Merge "Convert file delete to use OOUI"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Wed, 1 Aug 2018 17:23:24 +0000 (17:23 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Wed, 1 Aug 2018 17:23:24 +0000 (17:23 +0000)
1725 files changed:
.editorconfig [new file with mode: 0644]
.eslintrc.json
.phpcs.xml
.travis.yml
Gruntfile.js
HISTORY
INSTALL
README [new file with mode: 0644]
README.md [deleted file]
README.mediawiki [new symlink]
RELEASE-NOTES-1.31 [deleted file]
RELEASE-NOTES-1.32
autoload.php
composer.json
docs/extension.schema.v1.json
docs/extension.schema.v2.json
docs/globals.txt
docs/hooks.txt
docs/memcached.txt
docs/pageupdater.txt [new file with mode: 0644]
docs/skin.txt
docs/uidesign/table-layout.html [deleted file]
img_auth.php
includes/AjaxDispatcher.php
includes/AjaxResponse.php
includes/AuthPlugin.php
includes/AutoLoader.php
includes/Block.php
includes/Category.php
includes/CategoryViewer.php
includes/CommentStore.php
includes/ContentSecurityPolicy.php
includes/DefaultSettings.php
includes/Defines.php
includes/DevelopmentSettings.php
includes/DummyLinker.php
includes/EditPage.php
includes/FauxRequest.php
includes/FileDeleteForm.php
includes/FormOptions.php
includes/GitInfo.php
includes/GlobalFunctions.php
includes/Hooks.php
includes/Html.php
includes/LinkFilter.php
includes/Linker.php
includes/MWGrants.php
includes/MWNamespace.php
includes/MWTimestamp.php
includes/MagicWord.php
includes/MagicWordArray.php
includes/MagicWordFactory.php [new file with mode: 0644]
includes/MediaWiki.php
includes/MediaWikiServices.php
includes/MergeHistory.php
includes/Message.php
includes/MovePage.php
includes/NoLocalSettings.php
includes/OutputPage.php
includes/PHPVersionCheck.php
includes/PageProps.php
includes/PathRouter.php
includes/Pingback.php
includes/Preferences.php
includes/PrefixSearch.php
includes/ProtectionForm.php
includes/Revision.php
includes/ServiceWiring.php
includes/Setup.php
includes/SiteConfiguration.php
includes/Status.php
includes/Storage/DerivedPageDataUpdater.php [new file with mode: 0644]
includes/Storage/MutableRevisionRecord.php
includes/Storage/MutableRevisionSlots.php
includes/Storage/NameTableStore.php
includes/Storage/PageUpdateException.php [new file with mode: 0644]
includes/Storage/PageUpdater.php [new file with mode: 0644]
includes/Storage/RevisionFactory.php
includes/Storage/RevisionLookup.php
includes/Storage/RevisionRecord.php
includes/Storage/RevisionSlots.php
includes/Storage/RevisionSlotsUpdate.php
includes/Storage/RevisionStore.php
includes/Storage/SlotRecord.php
includes/Storage/SqlBlobStore.php
includes/StubObject.php
includes/TemplateParser.php
includes/Title.php
includes/WebRequest.php
includes/WebResponse.php
includes/WikiMap.php
includes/WikiReference.php
includes/Xml.php
includes/XmlSelect.php
includes/actions/Action.php
includes/actions/FormAction.php
includes/actions/HistoryAction.php
includes/actions/InfoAction.php
includes/actions/WatchAction.php
includes/api/ApiAuthManagerHelper.php
includes/api/ApiBase.php
includes/api/ApiCSPReport.php
includes/api/ApiDelete.php
includes/api/ApiErrorFormatter.php
includes/api/ApiExpandTemplates.php
includes/api/ApiFeedContributions.php
includes/api/ApiFeedWatchlist.php
includes/api/ApiFormatXml.php
includes/api/ApiHelp.php
includes/api/ApiMain.php
includes/api/ApiMessage.php
includes/api/ApiMessageTrait.php [new file with mode: 0644]
includes/api/ApiModuleManager.php
includes/api/ApiOptions.php
includes/api/ApiPageSet.php
includes/api/ApiParamInfo.php
includes/api/ApiParse.php
includes/api/ApiPatrol.php
includes/api/ApiQuery.php
includes/api/ApiQueryAllDeletedRevisions.php
includes/api/ApiQueryAllImages.php
includes/api/ApiQueryAllLinks.php
includes/api/ApiQueryAllRevisions.php
includes/api/ApiQueryBacklinksprop.php
includes/api/ApiQueryBase.php
includes/api/ApiQueryContributors.php
includes/api/ApiQueryDeletedRevisions.php
includes/api/ApiQueryExternalLinks.php
includes/api/ApiQueryFileRepoInfo.php
includes/api/ApiQueryFilearchive.php
includes/api/ApiQueryIWBacklinks.php
includes/api/ApiQueryImageInfo.php
includes/api/ApiQueryLangBacklinks.php
includes/api/ApiQueryLinks.php
includes/api/ApiQueryLogEvents.php
includes/api/ApiQueryPrefixSearch.php
includes/api/ApiQueryQueryPage.php
includes/api/ApiQueryRecentChanges.php
includes/api/ApiQueryRevisions.php
includes/api/ApiQueryRevisionsBase.php
includes/api/ApiQuerySearch.php
includes/api/ApiQuerySiteinfo.php
includes/api/ApiQueryTokens.php
includes/api/ApiQueryUserContribs.php [new file with mode: 0644]
includes/api/ApiQueryUserContributions.php [deleted file]
includes/api/ApiQueryWatchlist.php
includes/api/ApiRawMessage.php [new file with mode: 0644]
includes/api/ApiResult.php
includes/api/ApiRevisionDelete.php
includes/api/ApiRsd.php
includes/api/ApiSetNotificationTimestamp.php
includes/api/ApiSetPageLanguage.php
includes/api/ApiTag.php
includes/api/ApiUndelete.php
includes/api/ApiUpload.php
includes/api/ApiUsageException.php
includes/api/ApiUserrights.php
includes/api/IApiMessage.php [new file with mode: 0644]
includes/api/SearchApi.php
includes/api/UsageException.php [new file with mode: 0644]
includes/api/i18n/ar.json
includes/api/i18n/cs.json
includes/api/i18n/de.json
includes/api/i18n/en.json
includes/api/i18n/es.json
includes/api/i18n/fr.json
includes/api/i18n/gl.json
includes/api/i18n/he.json
includes/api/i18n/it.json
includes/api/i18n/ja.json
includes/api/i18n/ko.json
includes/api/i18n/ksh.json
includes/api/i18n/lt.json
includes/api/i18n/mk.json
includes/api/i18n/nb.json
includes/api/i18n/nl.json
includes/api/i18n/pl.json
includes/api/i18n/pt-br.json
includes/api/i18n/pt.json
includes/api/i18n/qqq.json
includes/api/i18n/ru.json
includes/api/i18n/sv.json
includes/api/i18n/uk.json
includes/api/i18n/zh-hans.json
includes/api/i18n/zh-hant.json
includes/auth/AbstractPasswordPrimaryAuthenticationProvider.php
includes/auth/AuthManager.php
includes/auth/AuthenticationResponse.php
includes/auth/ButtonAuthenticationRequest.php
includes/auth/ConfirmLinkSecondaryAuthenticationProvider.php
includes/auth/LegacyHookPreAuthenticationProvider.php
includes/auth/ResetPasswordSecondaryAuthenticationProvider.php
includes/auth/ThrottlePreAuthenticationProvider.php
includes/auth/Throttler.php
includes/cache/CacheDependency.php
includes/cache/CacheHelper.php
includes/cache/GenderCache.php
includes/cache/HTMLFileCache.php
includes/cache/LinkCache.php
includes/cache/MessageBlobStore.php
includes/cache/MessageCache.php
includes/cache/UserCache.php
includes/cache/localisation/LCStoreStaticArray.php
includes/cache/localisation/LocalisationCache.php
includes/changes/CategoryMembershipChange.php
includes/changes/ChangesList.php
includes/changes/ChangesListBooleanFilter.php
includes/changes/ChangesListFilterGroup.php
includes/changes/ChangesListStringOptionsFilterGroup.php
includes/changes/EnhancedChangesList.php
includes/changes/OldChangesList.php
includes/changes/RecentChange.php
includes/changetags/ChangeTags.php
includes/clientpool/SquidPurgeClient.php
includes/collation/IcuCollation.php
includes/compat/ScopedCallback.php [deleted file]
includes/compat/Timestamp.php [deleted file]
includes/compat/XMPReader.php [new file with mode: 0644]
includes/compat/normal/UtfNormal.php
includes/compat/normal/UtfNormalDefines.php [deleted file]
includes/compat/normal/UtfNormalUtil.php [deleted file]
includes/composer/ComposerHookHandler.php
includes/composer/ComposerPackageModifier.php
includes/composer/ComposerVersionNormalizer.php
includes/config/ConfigRepository.php [new file with mode: 0644]
includes/content/AbstractContent.php
includes/content/CodeContentHandler.php
includes/content/Content.php
includes/content/ContentHandler.php
includes/content/MessageContent.php
includes/content/TextContent.php
includes/content/TextContentHandler.php
includes/content/WikitextContent.php
includes/content/WikitextContentHandler.php
includes/context/ContextSource.php
includes/context/DerivativeContext.php
includes/context/RequestContext.php
includes/dao/DBAccessBase.php
includes/dao/IDBAccessObject.php
includes/db/CloneDatabase.php
includes/db/DatabaseOracle.php
includes/db/MWLBFactory.php
includes/db/PatchFileLocation.php [new file with mode: 0644]
includes/debug/DeprecationHelper.php [new file with mode: 0644]
includes/debug/logger/MonologSpi.php
includes/debug/logger/monolog/LineFormatter.php
includes/deferred/AutoCommitUpdate.php
includes/deferred/LinksDeletionUpdate.php
includes/deferred/LinksUpdate.php
includes/deferred/SearchUpdate.php
includes/diff/DairikiDiff.php
includes/diff/DiffEngine.php
includes/diff/DifferenceEngine.php
includes/diff/TableDiffFormatter.php
includes/diff/WordAccumulator.php
includes/edit/PreparedEdit.php
includes/exception/LocalizedException.php
includes/exception/MWExceptionHandler.php
includes/exception/MWExceptionRenderer.php
includes/export/DumpPipeOutput.php
includes/externalstore/ExternalStoreDB.php
includes/externalstore/ExternalStoreMwstore.php
includes/filebackend/FileBackendGroup.php
includes/filerepo/FileBackendDBRepoWrapper.php
includes/filerepo/FileRepo.php
includes/filerepo/ForeignAPIRepo.php
includes/filerepo/ForeignDBRepo.php
includes/filerepo/LocalRepo.php
includes/filerepo/RepoGroup.php
includes/filerepo/file/ArchivedFile.php
includes/filerepo/file/File.php
includes/filerepo/file/ForeignAPIFile.php
includes/filerepo/file/ForeignDBFile.php
includes/filerepo/file/LocalFile.php
includes/filerepo/file/OldLocalFile.php
includes/gallery/TraditionalImageGallery.php
includes/htmlform/HTMLForm.php
includes/htmlform/HTMLFormElement.php
includes/htmlform/HTMLFormField.php
includes/htmlform/fields/HTMLButtonField.php
includes/htmlform/fields/HTMLCheckField.php
includes/htmlform/fields/HTMLCheckMatrix.php
includes/htmlform/fields/HTMLExpiryField.php
includes/htmlform/fields/HTMLFloatField.php
includes/htmlform/fields/HTMLFormFieldCloner.php
includes/htmlform/fields/HTMLFormFieldWithButton.php
includes/htmlform/fields/HTMLMultiSelectField.php
includes/htmlform/fields/HTMLRadioField.php
includes/htmlform/fields/HTMLSelectAndOtherField.php
includes/htmlform/fields/HTMLSelectNamespace.php
includes/htmlform/fields/HTMLSelectOrOtherField.php
includes/htmlform/fields/HTMLSizeFilterField.php
includes/htmlform/fields/HTMLTextAreaField.php
includes/htmlform/fields/HTMLTextField.php
includes/htmlform/fields/HTMLTitleTextField.php
includes/htmlform/fields/HTMLUserTextField.php
includes/htmlform/fields/HTMLUsersMultiselectField.php
includes/http/CurlHttpRequest.php
includes/http/MWHttpRequest.php
includes/http/PhpHttpRequest.php
includes/import/WikiImporter.php
includes/installer/CliInstaller.php
includes/installer/DatabaseUpdater.php
includes/installer/Installer.php
includes/installer/MssqlUpdater.php
includes/installer/MysqlInstaller.php
includes/installer/MysqlUpdater.php
includes/installer/OracleUpdater.php
includes/installer/PostgresUpdater.php
includes/installer/SqliteUpdater.php
includes/installer/WebInstaller.php
includes/installer/WebInstallerExistingWiki.php
includes/installer/WebInstallerLanguage.php
includes/installer/WebInstallerName.php
includes/installer/WebInstallerOptions.php
includes/installer/WebInstallerPage.php
includes/installer/i18n/af.json
includes/installer/i18n/ar.json
includes/installer/i18n/ast.json
includes/installer/i18n/ba.json
includes/installer/i18n/be-tarask.json
includes/installer/i18n/bg.json
includes/installer/i18n/bn.json
includes/installer/i18n/br.json
includes/installer/i18n/bs.json
includes/installer/i18n/bto.json
includes/installer/i18n/ca.json
includes/installer/i18n/ce.json
includes/installer/i18n/cs.json
includes/installer/i18n/csb.json
includes/installer/i18n/de.json
includes/installer/i18n/diq.json
includes/installer/i18n/el.json
includes/installer/i18n/en.json
includes/installer/i18n/eo.json
includes/installer/i18n/es.json
includes/installer/i18n/eu.json
includes/installer/i18n/fa.json
includes/installer/i18n/fi.json
includes/installer/i18n/fr.json
includes/installer/i18n/frc.json
includes/installer/i18n/frp.json
includes/installer/i18n/gl.json
includes/installer/i18n/haw.json
includes/installer/i18n/he.json
includes/installer/i18n/hi.json
includes/installer/i18n/hrx.json
includes/installer/i18n/hsb.json
includes/installer/i18n/hu.json
includes/installer/i18n/ia.json
includes/installer/i18n/id.json
includes/installer/i18n/is.json
includes/installer/i18n/it.json
includes/installer/i18n/ja.json
includes/installer/i18n/ka.json
includes/installer/i18n/ko.json
includes/installer/i18n/ksh.json
includes/installer/i18n/ku-latn.json
includes/installer/i18n/lb.json
includes/installer/i18n/lij.json
includes/installer/i18n/lt.json
includes/installer/i18n/lv.json
includes/installer/i18n/mk.json
includes/installer/i18n/ml.json
includes/installer/i18n/ms.json
includes/installer/i18n/mt.json
includes/installer/i18n/mzn.json
includes/installer/i18n/nan.json
includes/installer/i18n/nap.json
includes/installer/i18n/nb.json
includes/installer/i18n/ne.json
includes/installer/i18n/nl-informal.json
includes/installer/i18n/nl.json
includes/installer/i18n/oc.json
includes/installer/i18n/olo.json
includes/installer/i18n/pl.json
includes/installer/i18n/pms.json
includes/installer/i18n/ps.json
includes/installer/i18n/pt-br.json
includes/installer/i18n/pt.json
includes/installer/i18n/qqq.json
includes/installer/i18n/ro.json
includes/installer/i18n/roa-tara.json
includes/installer/i18n/ru.json
includes/installer/i18n/sco.json
includes/installer/i18n/si.json
includes/installer/i18n/sl.json
includes/installer/i18n/sr-ec.json
includes/installer/i18n/sv.json
includes/installer/i18n/ta.json
includes/installer/i18n/te.json
includes/installer/i18n/th.json
includes/installer/i18n/tl.json
includes/installer/i18n/tr.json
includes/installer/i18n/tt-cyrl.json
includes/installer/i18n/uk.json
includes/installer/i18n/vi.json
includes/installer/i18n/war.json
includes/installer/i18n/yi.json
includes/installer/i18n/zh-hans.json
includes/installer/i18n/zh-hant.json
includes/interwiki/ClassicInterwikiLookup.php
includes/interwiki/Interwiki.php
includes/interwiki/InterwikiLookupAdapter.php
includes/interwiki/NullInterwikiLookup.php [new file with mode: 0644]
includes/jobqueue/Job.php
includes/jobqueue/JobQueue.php
includes/jobqueue/JobQueueDB.php
includes/jobqueue/JobQueueFederated.php
includes/jobqueue/JobQueueGroup.php
includes/jobqueue/JobQueueRedis.php
includes/jobqueue/JobQueueSecondTestQueue.php [deleted file]
includes/jobqueue/JobRunner.php
includes/jobqueue/JobSpecification.php
includes/jobqueue/aggregator/JobQueueAggregatorRedis.php
includes/jobqueue/jobs/CategoryMembershipChangeJob.php
includes/jobqueue/jobs/DeleteLinksJob.php
includes/jobqueue/jobs/DoubleRedirectJob.php
includes/jobqueue/jobs/HTMLCacheUpdateJob.php
includes/jobqueue/jobs/PublishStashedFileJob.php
includes/jobqueue/utils/BacklinkJobUtils.php
includes/json/FormatJson.php
includes/libs/ArrayUtils.php
includes/libs/CSSMin.php
includes/libs/Cookie.php
includes/libs/CryptHKDF.php
includes/libs/CryptRand.php
includes/libs/EasyDeflate.php [new file with mode: 0644]
includes/libs/GenericArrayObject.php
includes/libs/HashRing.php
includes/libs/HttpStatus.php
includes/libs/IP.php
includes/libs/JavaScriptMinifier.php
includes/libs/MapCacheLRU.php
includes/libs/MappedIterator.php
includes/libs/MemoizedCallable.php
includes/libs/MultiHttpClient.php
includes/libs/ProcessCacheLRU.php
includes/libs/StatusValue.php
includes/libs/StringUtils.php
includes/libs/Timing.php
includes/libs/UDPTransport.php
includes/libs/Xhprof.php
includes/libs/XhprofData.php
includes/libs/composer/ComposerInstalled.php
includes/libs/composer/ComposerLock.php
includes/libs/filebackend/FSFileBackend.php
includes/libs/filebackend/FileBackend.php
includes/libs/filebackend/FileBackendMultiWrite.php
includes/libs/filebackend/FileBackendStore.php
includes/libs/filebackend/FileOpBatch.php
includes/libs/filebackend/HTTPFileStreamer.php
includes/libs/filebackend/SwiftFileBackend.php
includes/libs/filebackend/filejournal/FileJournal.php
includes/libs/filebackend/fileop/FileOp.php
includes/libs/http/HttpAcceptParser.php
includes/libs/jsminplus.php
includes/libs/lockmanager/DBLockManager.php
includes/libs/lockmanager/LockManager.php
includes/libs/lockmanager/MemcLockManager.php
includes/libs/lockmanager/RedisLockManager.php
includes/libs/lockmanager/ScopedLock.php
includes/libs/mime/IEContentAnalyzer.php
includes/libs/mime/MimeAnalyzer.php
includes/libs/mime/XmlTypeCheck.php
includes/libs/objectcache/BagOStuff.php
includes/libs/objectcache/CachedBagOStuff.php
includes/libs/objectcache/HashBagOStuff.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/WANObjectCacheReaper.php
includes/libs/rdbms/ChronologyProtector.php
includes/libs/rdbms/database/DBConnRef.php
includes/libs/rdbms/database/Database.php
includes/libs/rdbms/database/DatabaseDomain.php
includes/libs/rdbms/database/DatabaseMssql.php
includes/libs/rdbms/database/DatabaseMysqlBase.php
includes/libs/rdbms/database/DatabaseMysqli.php
includes/libs/rdbms/database/DatabasePostgres.php
includes/libs/rdbms/database/DatabaseSqlite.php
includes/libs/rdbms/database/IDatabase.php
includes/libs/rdbms/database/IMaintainableDatabase.php
includes/libs/rdbms/database/resultwrapper/FakeResultWrapper.php
includes/libs/rdbms/database/resultwrapper/ResultWrapper.php
includes/libs/rdbms/encasing/Blob.php
includes/libs/rdbms/exception/DBAccessError.php
includes/libs/rdbms/exception/DBConnectionError.php
includes/libs/rdbms/exception/DBError.php
includes/libs/rdbms/exception/DBExpectedError.php
includes/libs/rdbms/exception/DBQueryError.php
includes/libs/rdbms/exception/DBReadOnlyError.php
includes/libs/rdbms/exception/DBReplicationWaitError.php
includes/libs/rdbms/exception/DBTransactionError.php
includes/libs/rdbms/exception/DBTransactionSizeError.php
includes/libs/rdbms/exception/DBUnexpectedError.php
includes/libs/rdbms/field/Field.php
includes/libs/rdbms/field/MySQLField.php
includes/libs/rdbms/lbfactory/ILBFactory.php
includes/libs/rdbms/lbfactory/LBFactory.php
includes/libs/rdbms/lbfactory/LBFactoryMulti.php
includes/libs/rdbms/lbfactory/LBFactorySimple.php
includes/libs/rdbms/lbfactory/LBFactorySingle.php
includes/libs/rdbms/loadbalancer/ILoadBalancer.php
includes/libs/rdbms/loadbalancer/LoadBalancer.php
includes/libs/rdbms/loadbalancer/LoadBalancerSingle.php
includes/libs/rdbms/loadmonitor/LoadMonitor.php
includes/libs/rdbms/loadmonitor/LoadMonitorMySQL.php
includes/libs/redis/RedisConnRef.php
includes/libs/redis/RedisConnectionPool.php
includes/libs/replacers/DoubleReplacer.php
includes/libs/replacers/HashtableReplacer.php
includes/libs/replacers/RegexlikeReplacer.php
includes/libs/replacers/Replacer.php
includes/libs/stats/BufferingStatsdDataFactory.php
includes/libs/virtualrest/ParsoidVirtualRESTService.php
includes/libs/virtualrest/RestbaseVirtualRESTService.php
includes/libs/virtualrest/VirtualRESTService.php
includes/libs/virtualrest/VirtualRESTServiceClient.php
includes/libs/xmp/XMP.php [deleted file]
includes/libs/xmp/XMPInfo.php [deleted file]
includes/libs/xmp/XMPValidate.php [deleted file]
includes/linkeddata/PageDataRequestHandler.php
includes/linker/LinkRenderer.php
includes/logging/BlockLogFormatter.php
includes/logging/DeleteLogFormatter.php
includes/logging/ImportLogFormatter.php
includes/logging/LogEntry.php
includes/logging/LogEventsList.php
includes/logging/LogFormatter.php
includes/logging/LogPage.php
includes/logging/LogPager.php
includes/logging/MergeLogFormatter.php
includes/logging/MoveLogFormatter.php
includes/logging/NewUsersLogFormatter.php
includes/logging/PageLangLogFormatter.php
includes/logging/PatrolLog.php
includes/logging/PatrolLogFormatter.php
includes/logging/ProtectLogFormatter.php
includes/logging/RightsLogFormatter.php
includes/logging/TagLogFormatter.php
includes/logging/UploadLogFormatter.php
includes/logging/WikitextLogFormatter.php
includes/mail/MailAddress.php
includes/mail/UserMailer.php
includes/media/BitmapHandler.php
includes/media/BitmapMetadataHandler.php
includes/media/BmpHandler.php
includes/media/DjVuHandler.php
includes/media/Exif.php
includes/media/FormatMetadata.php
includes/media/GIFMetadataExtractor.php
includes/media/JpegMetadataExtractor.php
includes/media/MediaHandler.php
includes/media/MediaTransformOutput.php
includes/media/SVGMetadataExtractor.php
includes/media/SvgHandler.php
includes/media/TiffHandler.php
includes/media/TransformationalImageHandler.php
includes/media/XCF.php
includes/objectcache/ObjectCache.php
includes/objectcache/SqlBagOStuff.php
includes/page/Article.php
includes/page/ImagePage.php
includes/page/PageArchive.php
includes/page/WikiPage.php
includes/pager/IndexPager.php
includes/pager/ReverseChronologicalPager.php
includes/pager/TablePager.php
includes/parser/BlockLevelPass.php
includes/parser/CoreParserFunctions.php
includes/parser/CoreTagHooks.php
includes/parser/LinkHolderArray.php
includes/parser/Parser.php
includes/parser/ParserDiffTest.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/Sanitizer.php
includes/password/BcryptPassword.php
includes/password/EncryptedPassword.php
includes/password/Pbkdf2Password.php
includes/poolcounter/PoolCounterRedis.php
includes/poolcounter/PoolCounterWork.php
includes/poolcounter/PoolCounterWorkViaCallback.php
includes/poolcounter/PoolWorkArticleView.php
includes/preferences/DefaultPreferencesFactory.php
includes/preferences/Filter.php [new file with mode: 0644]
includes/preferences/IntvalFilter.php [new file with mode: 0644]
includes/preferences/MultiUsernameFilter.php [new file with mode: 0644]
includes/preferences/PreferencesFactory.php
includes/preferences/TimezoneFilter.php [new file with mode: 0644]
includes/profiler/Profiler.php
includes/profiler/ProfilerSectionOnly.php
includes/profiler/ProfilerXhprof.php
includes/profiler/output/ProfilerOutputStats.php
includes/profiler/output/ProfilerOutputText.php
includes/registration/ExtensionJsonValidator.php
includes/registration/ExtensionProcessor.php
includes/registration/ExtensionRegistry.php
includes/registration/Processor.php
includes/registration/VersionChecker.php
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/ResourceLoaderLanguageDataModule.php
includes/resourceloader/ResourceLoaderLanguageNamesModule.php
includes/resourceloader/ResourceLoaderLessVarFileModule.php
includes/resourceloader/ResourceLoaderModule.php
includes/resourceloader/ResourceLoaderOOUIImageModule.php
includes/resourceloader/ResourceLoaderRawFileModule.php [deleted file]
includes/resourceloader/ResourceLoaderSpecialCharacterDataModule.php
includes/resourceloader/ResourceLoaderStartUpModule.php
includes/resourceloader/ResourceLoaderUserOptionsModule.php
includes/resourceloader/ResourceLoaderWikiModule.php
includes/revisiondelete/RevDelList.php
includes/search/PaginatingSearchEngine.php [new file with mode: 0644]
includes/search/SearchDatabase.php
includes/search/SearchEngine.php
includes/search/SearchEngineFactory.php
includes/search/SearchHighlighter.php
includes/search/SearchMssql.php
includes/search/SearchMySQL.php
includes/search/SearchNearMatchResultSet.php
includes/search/SearchOracle.php
includes/search/SearchPostgres.php
includes/search/SearchResult.php
includes/search/SearchResultSet.php
includes/search/SearchSqlite.php
includes/search/SearchSuggestionSet.php
includes/search/SqlSearchResultSet.php
includes/services/ServiceContainer.php
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/SessionProviderInterface.php
includes/shell/Command.php
includes/shell/FirejailCommand.php
includes/shell/Shell.php
includes/site/CachingSiteStore.php
includes/site/DBSiteStore.php
includes/site/FileBasedSiteLookup.php
includes/site/MediaWikiPageNameNormalizer.php
includes/site/MediaWikiSite.php
includes/site/Site.php
includes/site/SiteExporter.php
includes/site/SiteImporter.php
includes/site/SiteList.php
includes/site/SiteLookup.php
includes/site/SiteSQLStore.php
includes/site/SiteStore.php
includes/site/SitesCacheFileBuilder.php
includes/skins/BaseTemplate.php
includes/skins/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/LoginSignupSpecialPage.php
includes/specialpage/QueryPage.php
includes/specialpage/SpecialPage.php
includes/specialpage/SpecialPageFactory.php
includes/specials/SpecialAutoblockList.php
includes/specials/SpecialBlock.php
includes/specials/SpecialBotPasswords.php
includes/specials/SpecialChangeEmail.php
includes/specials/SpecialComparePages.php
includes/specials/SpecialContributions.php
includes/specials/SpecialCreateAccount.php
includes/specials/SpecialEditTags.php
includes/specials/SpecialEditWatchlist.php
includes/specials/SpecialEmailuser.php
includes/specials/SpecialFileDuplicateSearch.php
includes/specials/SpecialImport.php
includes/specials/SpecialListgrouprights.php
includes/specials/SpecialLog.php
includes/specials/SpecialMIMEsearch.php
includes/specials/SpecialMediaStatistics.php
includes/specials/SpecialMergeHistory.php
includes/specials/SpecialNewpages.php
includes/specials/SpecialPageLanguage.php
includes/specials/SpecialPasswordPolicies.php
includes/specials/SpecialPasswordReset.php
includes/specials/SpecialPreferences.php
includes/specials/SpecialPrefixindex.php
includes/specials/SpecialProtectedpages.php
includes/specials/SpecialProtectedtitles.php
includes/specials/SpecialRecentchanges.php
includes/specials/SpecialSearch.php
includes/specials/SpecialUndelete.php
includes/specials/SpecialUpload.php
includes/specials/SpecialUserrights.php
includes/specials/SpecialVersion.php
includes/specials/SpecialWantedcategories.php
includes/specials/SpecialWatchlist.php
includes/specials/SpecialWhatlinkshere.php
includes/specials/formfields/Licenses.php
includes/specials/formfields/UploadSourceField.php
includes/specials/forms/EditWatchlistNormalHTMLForm.php
includes/specials/forms/PreferencesForm.php [deleted file]
includes/specials/forms/PreferencesFormLegacy.php
includes/specials/forms/PreferencesFormOOUI.php
includes/specials/forms/UploadForm.php
includes/specials/helpers/License.php
includes/specials/pagers/ActiveUsersPager.php
includes/specials/pagers/AllMessagesTablePager.php
includes/specials/pagers/ContribsPager.php
includes/specials/pagers/DeletedContribsPager.php
includes/specials/pagers/ImageListPager.php
includes/specials/pagers/ProtectedPagesPager.php
includes/specials/pagers/ProtectedTitlesPager.php
includes/specials/pagers/UsersPager.php
includes/templates/EnhancedChangesListGroup.mustache
includes/tidy/RaggettBase.php
includes/tidy/RaggettExternal.php
includes/tidy/RaggettInternalHHVM.php
includes/tidy/RaggettInternalPHP.php
includes/tidy/RemexCompatFormatter.php
includes/tidy/RemexCompatMunger.php
includes/title/MalformedTitleException.php
includes/title/MediaWikiTitleCodec.php
includes/upload/UploadBase.php
includes/upload/UploadFromChunks.php
includes/upload/UploadStash.php
includes/user/BotPassword.php
includes/user/ExternalUserNames.php
includes/user/PasswordReset.php
includes/user/User.php
includes/user/UserGroupMembership.php
includes/utils/AutoloadGenerator.php
includes/utils/MWCryptRand.php
includes/utils/MWRestrictions.php
includes/utils/UIDGenerator.php
includes/utils/ZipDirectoryReader.php
includes/watcheditem/WatchedItemQueryService.php
includes/watcheditem/WatchedItemQueryServiceExtension.php
includes/watcheditem/WatchedItemStoreInterface.php
includes/widget/ComplexTitleInputWidget.php
includes/widget/ExpiryInputWidget.php
includes/widget/NamespaceInputWidget.php
includes/widget/SelectWithInputWidget.php
includes/widget/SizeFilterWidget.php
includes/widget/UsersMultiselectWidget.php
includes/widget/search/BasicSearchResultSetWidget.php
includes/widget/search/SearchFormWidget.php
includes/widget/search/SimpleSearchResultSetWidget.php
jsduck.json
languages/ConverterRule.php
languages/Language.php
languages/LanguageConverter.php
languages/classes/LanguageAr.php
languages/classes/LanguageBe_tarask.php
languages/classes/LanguageEn.php
languages/classes/LanguageFi.php
languages/classes/LanguageMl.php
languages/data/CrhExceptions.php
languages/data/Names.php
languages/data/README.md [new file with mode: 0644]
languages/data/normalize-ar.php [new file with mode: 0644]
languages/data/normalize-ml.php [new file with mode: 0644]
languages/i18n/ace.json
languages/i18n/ady-cyrl.json
languages/i18n/aeb-arab.json
languages/i18n/af.json
languages/i18n/ais.json
languages/i18n/aln.json
languages/i18n/am.json
languages/i18n/ami.json [new file with mode: 0644]
languages/i18n/an.json
languages/i18n/ang.json
languages/i18n/anp.json
languages/i18n/ar.json
languages/i18n/arc.json
languages/i18n/arn.json
languages/i18n/arq.json
languages/i18n/ary.json
languages/i18n/arz.json
languages/i18n/as.json
languages/i18n/ase.json
languages/i18n/ast.json
languages/i18n/atj.json
languages/i18n/avk.json
languages/i18n/awa.json
languages/i18n/az.json
languages/i18n/azb.json
languages/i18n/ba.json
languages/i18n/bar.json
languages/i18n/bcc.json
languages/i18n/bcl.json
languages/i18n/be-tarask.json
languages/i18n/be.json
languages/i18n/bg.json
languages/i18n/bgn.json
languages/i18n/bho.json
languages/i18n/bjn.json
languages/i18n/bn.json
languages/i18n/bo.json
languages/i18n/bpy.json
languages/i18n/bqi.json
languages/i18n/br.json
languages/i18n/bs.json
languages/i18n/btm.json [new file with mode: 0644]
languages/i18n/ca.json
languages/i18n/cdo.json
languages/i18n/ce.json
languages/i18n/ceb.json
languages/i18n/ch.json
languages/i18n/ckb.json
languages/i18n/co.json
languages/i18n/cps.json
languages/i18n/crh-cyrl.json
languages/i18n/crh-latn.json
languages/i18n/cs.json
languages/i18n/csb.json
languages/i18n/cu.json
languages/i18n/cv.json
languages/i18n/cy.json
languages/i18n/da.json
languages/i18n/de-ch.json
languages/i18n/de-formal.json
languages/i18n/de.json
languages/i18n/diq.json
languages/i18n/dsb.json
languages/i18n/dtp.json
languages/i18n/dty.json
languages/i18n/egl.json
languages/i18n/el.json
languages/i18n/en-gb.json
languages/i18n/en.json
languages/i18n/eo.json
languages/i18n/es-formal.json
languages/i18n/es.json
languages/i18n/et.json
languages/i18n/eu.json
languages/i18n/ext.json
languages/i18n/fa.json
languages/i18n/fi.json
languages/i18n/fo.json
languages/i18n/fr.json
languages/i18n/frp.json
languages/i18n/frr.json
languages/i18n/fur.json
languages/i18n/fy.json
languages/i18n/ga.json
languages/i18n/gag.json
languages/i18n/gan-hans.json
languages/i18n/gan-hant.json
languages/i18n/gcr.json
languages/i18n/gd.json
languages/i18n/gl.json
languages/i18n/glk.json
languages/i18n/gom-deva.json
languages/i18n/gom-latn.json
languages/i18n/gor.json
languages/i18n/got.json
languages/i18n/grc.json
languages/i18n/gsw.json
languages/i18n/gu.json
languages/i18n/gv.json
languages/i18n/ha.json
languages/i18n/hak.json
languages/i18n/haw.json
languages/i18n/he.json
languages/i18n/hi.json
languages/i18n/hif-latn.json
languages/i18n/hil.json
languages/i18n/hr.json
languages/i18n/hrx.json
languages/i18n/hsb.json
languages/i18n/ht.json
languages/i18n/hu.json
languages/i18n/hy.json
languages/i18n/hyw.json [new file with mode: 0644]
languages/i18n/ia.json
languages/i18n/id.json
languages/i18n/ie.json
languages/i18n/ig.json
languages/i18n/ilo.json
languages/i18n/inh.json
languages/i18n/io.json
languages/i18n/is.json
languages/i18n/it.json
languages/i18n/ja.json
languages/i18n/jam.json
languages/i18n/jut.json
languages/i18n/jv.json
languages/i18n/ka.json
languages/i18n/kaa.json
languages/i18n/kab.json
languages/i18n/kbd-cyrl.json
languages/i18n/kbp.json
languages/i18n/khw.json
languages/i18n/kiu.json
languages/i18n/kk-arab.json
languages/i18n/kk-cyrl.json
languages/i18n/kk-latn.json
languages/i18n/km.json
languages/i18n/kn.json
languages/i18n/ko.json
languages/i18n/krc.json
languages/i18n/krl.json
languages/i18n/ksh.json
languages/i18n/ku-latn.json
languages/i18n/kum.json
languages/i18n/kw.json
languages/i18n/ky.json
languages/i18n/la.json
languages/i18n/lad.json
languages/i18n/lb.json
languages/i18n/lez.json
languages/i18n/lfn.json
languages/i18n/lg.json
languages/i18n/li.json
languages/i18n/lij.json
languages/i18n/lki.json
languages/i18n/lmo.json
languages/i18n/lo.json
languages/i18n/loz.json
languages/i18n/lrc.json
languages/i18n/lt.json
languages/i18n/lus.json
languages/i18n/luz.json
languages/i18n/lv.json
languages/i18n/lzh.json
languages/i18n/lzz.json
languages/i18n/mai.json
languages/i18n/map-bms.json
languages/i18n/mdf.json
languages/i18n/mg.json
languages/i18n/mhr.json
languages/i18n/min.json
languages/i18n/mk.json
languages/i18n/ml.json
languages/i18n/mn.json
languages/i18n/mni.json [new file with mode: 0644]
languages/i18n/mr.json
languages/i18n/ms.json
languages/i18n/mt.json
languages/i18n/mwl.json
languages/i18n/my.json
languages/i18n/myv.json
languages/i18n/mzn.json
languages/i18n/nah.json
languages/i18n/nan.json
languages/i18n/nap.json
languages/i18n/nb.json
languages/i18n/nds-nl.json
languages/i18n/nds.json
languages/i18n/ne.json
languages/i18n/nl.json
languages/i18n/nn.json
languages/i18n/nso.json
languages/i18n/nys.json
languages/i18n/oc.json
languages/i18n/olo.json
languages/i18n/or.json
languages/i18n/os.json
languages/i18n/pa.json
languages/i18n/pam.json
languages/i18n/pcd.json
languages/i18n/pfl.json
languages/i18n/pl.json
languages/i18n/pms.json
languages/i18n/pnb.json
languages/i18n/pnt.json
languages/i18n/prg.json
languages/i18n/ps.json
languages/i18n/pt-br.json
languages/i18n/pt.json
languages/i18n/qqq.json
languages/i18n/qu.json
languages/i18n/qug.json
languages/i18n/rif.json
languages/i18n/rm.json
languages/i18n/ro.json
languages/i18n/roa-tara.json
languages/i18n/ru.json
languages/i18n/rue.json
languages/i18n/sa.json
languages/i18n/sah.json
languages/i18n/sat.json
languages/i18n/sc.json
languages/i18n/scn.json
languages/i18n/sco.json
languages/i18n/sd.json
languages/i18n/sdc.json
languages/i18n/sdh.json
languages/i18n/se.json
languages/i18n/ses.json
languages/i18n/sgs.json
languages/i18n/sh.json
languages/i18n/shi.json
languages/i18n/shn.json
languages/i18n/shy-latn.json
languages/i18n/si.json
languages/i18n/sk.json
languages/i18n/skr-arab.json
languages/i18n/sl.json
languages/i18n/sli.json
languages/i18n/so.json
languages/i18n/sq.json
languages/i18n/sr-ec.json
languages/i18n/sr-el.json
languages/i18n/srn.json
languages/i18n/stq.json
languages/i18n/sty.json
languages/i18n/su.json
languages/i18n/sv.json
languages/i18n/sw.json
languages/i18n/szl.json
languages/i18n/ta.json
languages/i18n/tay.json
languages/i18n/tcy.json
languages/i18n/te.json
languages/i18n/tet.json
languages/i18n/tg-cyrl.json
languages/i18n/tg-latn.json
languages/i18n/th.json
languages/i18n/tk.json
languages/i18n/tl.json
languages/i18n/tly.json
languages/i18n/to.json
languages/i18n/tr.json
languages/i18n/tru.json
languages/i18n/ts.json
languages/i18n/tt-cyrl.json
languages/i18n/tt-latn.json
languages/i18n/tyv.json
languages/i18n/udm.json
languages/i18n/ug-arab.json
languages/i18n/uk.json
languages/i18n/ur.json
languages/i18n/uz.json
languages/i18n/vec.json
languages/i18n/vep.json
languages/i18n/vi.json
languages/i18n/vmf.json
languages/i18n/vo.json
languages/i18n/vot.json
languages/i18n/vro.json
languages/i18n/wa.json
languages/i18n/war.json
languages/i18n/wo.json
languages/i18n/wuu.json
languages/i18n/xal.json
languages/i18n/xmf.json
languages/i18n/yi.json
languages/i18n/yo.json
languages/i18n/yue.json
languages/i18n/zea.json
languages/i18n/zgh.json
languages/i18n/zh-hans.json
languages/i18n/zh-hant.json
languages/i18n/zh-hk.json
languages/messages/MessagesAb.php
languages/messages/MessagesAf.php
languages/messages/MessagesBe.php
languages/messages/MessagesBe_tarask.php
languages/messages/MessagesBg.php
languages/messages/MessagesBr.php
languages/messages/MessagesBtm.php [new file with mode: 0644]
languages/messages/MessagesCs.php
languages/messages/MessagesEo.php
languages/messages/MessagesEs.php
languages/messages/MessagesEt.php
languages/messages/MessagesFi.php
languages/messages/MessagesFr.php
languages/messages/MessagesFrp.php
languages/messages/MessagesFur.php
languages/messages/MessagesHu.php
languages/messages/MessagesHy.php
languages/messages/MessagesIa.php
languages/messages/MessagesIt.php
languages/messages/MessagesKaa.php
languages/messages/MessagesKk_cyrl.php
languages/messages/MessagesKk_latn.php
languages/messages/MessagesKo.php
languages/messages/MessagesKsh.php
languages/messages/MessagesLa.php
languages/messages/MessagesLbe.php
languages/messages/MessagesLn.php
languages/messages/MessagesLt.php
languages/messages/MessagesLv.php
languages/messages/MessagesMni.php [new file with mode: 0644]
languages/messages/MessagesMr.php
languages/messages/MessagesNb.php
languages/messages/MessagesNn.php
languages/messages/MessagesOc.php
languages/messages/MessagesPl.php
languages/messages/MessagesPt.php
languages/messages/MessagesPt_br.php
languages/messages/MessagesRu.php
languages/messages/MessagesSa.php
languages/messages/MessagesSat.php [new file with mode: 0644]
languages/messages/MessagesSe.php
languages/messages/MessagesSk.php
languages/messages/MessagesSv.php
languages/messages/MessagesTa.php
languages/messages/MessagesTe.php
languages/messages/MessagesUdm.php
languages/messages/MessagesUk.php
languages/messages/MessagesUr.php
languages/messages/MessagesUz.php
languages/messages/MessagesWa.php
languages/messages/MessagesZgh.php [new file with mode: 0644]
maintenance/Maintenance.php
maintenance/addRFCandPMIDInterwiki.php
maintenance/addSite.php
maintenance/archives/patch-archive-ar_rev_id-unique.sql [new file with mode: 0644]
maintenance/archives/patch-interwiki-fix-pk.sql [new file with mode: 0644]
maintenance/archives/patch-logging-drop-type-action-index.sql [new file with mode: 0644]
maintenance/archives/patch-logging-log-type-action-index.sql [new file with mode: 0644]
maintenance/archives/patch-logging-type-action-index.sql [deleted file]
maintenance/archives/patch-page_props-fix-pk.sql [new file with mode: 0644]
maintenance/archives/patch-protected_titles-fix-pk.sql [new file with mode: 0644]
maintenance/archives/patch-site_identifiers-fix-pk.sql [new file with mode: 0644]
maintenance/backup.inc
maintenance/categoryChangesAsRdf.php
maintenance/cleanupCaps.php
maintenance/cleanupImages.php
maintenance/cleanupInvalidDbKeys.php
maintenance/cleanupSpam.php
maintenance/cleanupTitles.php
maintenance/cleanupUploadStash.php
maintenance/cleanupWatchlist.php
maintenance/copyFileBackend.php
maintenance/createAndPromote.php
maintenance/createCommonPasswordCdb.php
maintenance/deleteAutoPatrolLogs.php
maintenance/doMaintenance.php
maintenance/dumpTextPass.php
maintenance/dumpUploads.php
maintenance/exportSites.php
maintenance/fileOpPerfTest.php
maintenance/findDeprecated.php
maintenance/formatInstallDoc.php
maintenance/generateSitemap.php
maintenance/getReplicaServer.php
maintenance/importSites.php
maintenance/interwiki.list
maintenance/interwiki.sql
maintenance/jsduck/eg-iframe.html
maintenance/language/generateCollationData.php
maintenance/language/generateNormalizerDataAr.php
maintenance/language/generateNormalizerDataMl.php
maintenance/language/languages.inc
maintenance/language/listVariants.php
maintenance/mcc.php
maintenance/mssql/archives/patch-actor-table.sql
maintenance/mssql/archives/patch-comment-table.sql
maintenance/mssql/archives/patch-content.sql
maintenance/mssql/archives/patch-interwiki-pk.sql [new file with mode: 0644]
maintenance/mssql/archives/patch-page_props-pk.sql [new file with mode: 0644]
maintenance/mssql/archives/patch-protected_titles-pk.sql [new file with mode: 0644]
maintenance/mssql/archives/patch-site_identifiers-pk.sql [new file with mode: 0644]
maintenance/mssql/archives/patch-slots.sql
maintenance/mssql/tables.sql
maintenance/mysql.php [new file with mode: 0644]
maintenance/namespaceDupes.php
maintenance/oracle/archives/patch-actor-table.sql
maintenance/oracle/archives/patch-archive-ar_rev_id-unique.sql [new file with mode: 0644]
maintenance/oracle/archives/patch-comment-table.sql
maintenance/oracle/tables.sql
maintenance/orphans.php
maintenance/parse.php
maintenance/populateChangeTagDef.php [new file with mode: 0644]
maintenance/populateContentTables.php [new file with mode: 0644]
maintenance/populateInterwiki.php
maintenance/postgres/archives/patch-interwiki-pk.sql [new file with mode: 0644]
maintenance/postgres/archives/patch-protected_titles-pk.sql [new file with mode: 0644]
maintenance/postgres/archives/patch-site_identifiers-pk.sql [new file with mode: 0644]
maintenance/postgres/tables.sql
maintenance/purgePage.php
maintenance/reassignEdits.php
maintenance/rebuildrecentchanges.php
maintenance/refreshLinks.php
maintenance/removeUnusedAccounts.php
maintenance/renameDbPrefix.php
maintenance/resetAuthenticationThrottle.php [new file with mode: 0644]
maintenance/resources/update-oojs.sh
maintenance/runBatchedQuery.php
maintenance/shell.php
maintenance/showSiteStats.php
maintenance/sqlite/archives/patch-actor-table.sql
maintenance/sqlite/archives/patch-archive-ar_rev_id-unique.sql [new file with mode: 0644]
maintenance/sqlite/archives/patch-interwiki-fix-pk.sql [new file with mode: 0644]
maintenance/sqlite/archives/patch-page_props-fix-pk.sql [new file with mode: 0644]
maintenance/sqlite/archives/patch-protected_titles-fix-pk.sql [new file with mode: 0644]
maintenance/sqlite/archives/patch-site_identifiers-fix-pk.sql [new file with mode: 0644]
maintenance/storage/checkStorage.php
maintenance/storage/moveToExternal.php
maintenance/storage/recompressTracked.php
maintenance/storage/storageTypeStats.php
maintenance/storage/testCompression.php
maintenance/storage/trackBlobs.php
maintenance/tables.sql
maintenance/updateCollation.php
maintenance/updateSpecialPages.php
package.json
profileinfo.php
resources/Resources.php
resources/lib/easy-deflate/README.md [new file with mode: 0644]
resources/lib/easy-deflate/deflate.js [new file with mode: 0644]
resources/lib/easy-deflate/easydeflate.js [new file with mode: 0644]
resources/lib/easy-deflate/inflate.js [new file with mode: 0644]
resources/lib/oojs-ui/History.md
resources/lib/oojs-ui/i18n/af.json
resources/lib/oojs-ui/i18n/ar.json
resources/lib/oojs-ui/i18n/ast.json
resources/lib/oojs-ui/i18n/be-tarask.json
resources/lib/oojs-ui/i18n/bg.json
resources/lib/oojs-ui/i18n/bn.json
resources/lib/oojs-ui/i18n/br.json
resources/lib/oojs-ui/i18n/ca.json
resources/lib/oojs-ui/i18n/cs.json
resources/lib/oojs-ui/i18n/de.json
resources/lib/oojs-ui/i18n/el.json
resources/lib/oojs-ui/i18n/eo.json
resources/lib/oojs-ui/i18n/es.json
resources/lib/oojs-ui/i18n/eu.json
resources/lib/oojs-ui/i18n/fa.json
resources/lib/oojs-ui/i18n/fi.json
resources/lib/oojs-ui/i18n/fr.json
resources/lib/oojs-ui/i18n/gl.json
resources/lib/oojs-ui/i18n/gor.json
resources/lib/oojs-ui/i18n/he.json
resources/lib/oojs-ui/i18n/hr.json
resources/lib/oojs-ui/i18n/is.json
resources/lib/oojs-ui/i18n/it.json
resources/lib/oojs-ui/i18n/ja.json
resources/lib/oojs-ui/i18n/km.json
resources/lib/oojs-ui/i18n/ko.json
resources/lib/oojs-ui/i18n/la.json
resources/lib/oojs-ui/i18n/lb.json
resources/lib/oojs-ui/i18n/lv.json
resources/lib/oojs-ui/i18n/mg.json
resources/lib/oojs-ui/i18n/mk.json
resources/lib/oojs-ui/i18n/ml.json
resources/lib/oojs-ui/i18n/nb.json
resources/lib/oojs-ui/i18n/nl.json
resources/lib/oojs-ui/i18n/pl.json
resources/lib/oojs-ui/i18n/pt-br.json
resources/lib/oojs-ui/i18n/pt.json
resources/lib/oojs-ui/i18n/qqq.json
resources/lib/oojs-ui/i18n/qu.json
resources/lib/oojs-ui/i18n/roa-tara.json
resources/lib/oojs-ui/i18n/ru.json
resources/lib/oojs-ui/i18n/sk.json
resources/lib/oojs-ui/i18n/sl.json
resources/lib/oojs-ui/i18n/sr-ec.json
resources/lib/oojs-ui/i18n/sv.json
resources/lib/oojs-ui/i18n/te.json
resources/lib/oojs-ui/i18n/tr.json
resources/lib/oojs-ui/i18n/uk.json
resources/lib/oojs-ui/i18n/vec.json
resources/lib/oojs-ui/i18n/vi.json
resources/lib/oojs-ui/i18n/zh-hans.json
resources/lib/oojs-ui/i18n/zh-hant.json
resources/lib/oojs-ui/oojs-ui-apex.js
resources/lib/oojs-ui/oojs-ui-apex.js.map [deleted file]
resources/lib/oojs-ui/oojs-ui-apex.js.map.json [new file with mode: 0644]
resources/lib/oojs-ui/oojs-ui-core-apex.css
resources/lib/oojs-ui/oojs-ui-core-wikimediaui.css
resources/lib/oojs-ui/oojs-ui-core.js
resources/lib/oojs-ui/oojs-ui-core.js.map [deleted file]
resources/lib/oojs-ui/oojs-ui-core.js.map.json [new file with mode: 0644]
resources/lib/oojs-ui/oojs-ui-toolbars-apex.css
resources/lib/oojs-ui/oojs-ui-toolbars-wikimediaui.css
resources/lib/oojs-ui/oojs-ui-toolbars.js
resources/lib/oojs-ui/oojs-ui-toolbars.js.map [deleted file]
resources/lib/oojs-ui/oojs-ui-toolbars.js.map.json [new file with mode: 0644]
resources/lib/oojs-ui/oojs-ui-widgets-apex.css
resources/lib/oojs-ui/oojs-ui-widgets-wikimediaui.css
resources/lib/oojs-ui/oojs-ui-widgets.js
resources/lib/oojs-ui/oojs-ui-widgets.js.map [deleted file]
resources/lib/oojs-ui/oojs-ui-widgets.js.map.json [new file with mode: 0644]
resources/lib/oojs-ui/oojs-ui-wikimediaui.js
resources/lib/oojs-ui/oojs-ui-wikimediaui.js.map [deleted file]
resources/lib/oojs-ui/oojs-ui-wikimediaui.js.map.json [new file with mode: 0644]
resources/lib/oojs-ui/oojs-ui-windows-apex.css
resources/lib/oojs-ui/oojs-ui-windows-wikimediaui.css
resources/lib/oojs-ui/oojs-ui-windows.js
resources/lib/oojs-ui/oojs-ui-windows.js.map [deleted file]
resources/lib/oojs-ui/oojs-ui-windows.js.map.json [new file with mode: 0644]
resources/lib/oojs-ui/themes/apex/icons-editing-styling.json
resources/lib/oojs-ui/themes/wikimediaui/icons-editing-styling.json
resources/lib/oojs-ui/themes/wikimediaui/icons-interactions.json
resources/lib/oojs-ui/themes/wikimediaui/images/icons/bold-cyrl-palochka-invert.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/wikimediaui/images/icons/bold-cyrl-palochka-invert.svg [new file with mode: 0644]
resources/lib/oojs-ui/themes/wikimediaui/images/icons/bold-cyrl-palochka-progressive.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/wikimediaui/images/icons/bold-cyrl-palochka-progressive.svg [new file with mode: 0644]
resources/lib/oojs-ui/themes/wikimediaui/images/icons/bold-cyrl-palochka.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/wikimediaui/images/icons/bold-cyrl-palochka.svg [new file with mode: 0644]
resources/lib/oojs-ui/themes/wikimediaui/images/icons/subtract-destructive.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/wikimediaui/images/icons/subtract-destructive.svg [new file with mode: 0644]
resources/lib/oojs/README.md
resources/lib/oojs/oojs.jquery.js
resources/src/jquery.tablesorter/jquery.tablesorter.js
resources/src/jquery.tablesorter/jquery.tablesorter.less
resources/src/jquery/jquery.lengthLimit.js
resources/src/jquery/jquery.makeCollapsible.js
resources/src/jquery/jquery.tablesorter.styles.less [deleted file]
resources/src/mediawiki.ForeignStructuredUpload.BookletLayout/BookletLayout.js
resources/src/mediawiki.Title/Title.js
resources/src/mediawiki.Upload.BookletLayout/BookletLayout.css
resources/src/mediawiki.Uri/Uri.js
resources/src/mediawiki.action/mediawiki.action.edit.stash.js
resources/src/mediawiki.action/mediawiki.action.edit.styles.less
resources/src/mediawiki.api/index.js
resources/src/mediawiki.api/upload.js
resources/src/mediawiki.base/mediawiki.base.js [new file with mode: 0644]
resources/src/mediawiki.base/mediawiki.errorLogger.js [new file with mode: 0644]
resources/src/mediawiki.debug/debug.js
resources/src/mediawiki.hidpi/hidpi.js [deleted file]
resources/src/mediawiki.hidpi/skip.js [deleted file]
resources/src/mediawiki.htmlform.ooui.styles.less
resources/src/mediawiki.inspect.js
resources/src/mediawiki.jqueryMsg/mediawiki.jqueryMsg.js
resources/src/mediawiki.language/mediawiki.language.init.js
resources/src/mediawiki.language/mediawiki.language.numbers.js
resources/src/mediawiki.legacy/commonPrint.css
resources/src/mediawiki.legacy/oldshared.css
resources/src/mediawiki.legacy/shared.css
resources/src/mediawiki.less/mediawiki.mixins.less
resources/src/mediawiki.page.gallery.js
resources/src/mediawiki.page.image.pagination.js
resources/src/mediawiki.page.watch.ajax.js
resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.ItemModel.js
resources/src/mediawiki.rcfilters/mw.rcfilters.Controller.js
resources/src/mediawiki.rcfilters/mw.rcfilters.init.js
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.less
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.mixins.less
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.ChangesListWrapperWidget.highlightCircles.seenunseen.less
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.ChangesListWrapperWidget.less
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.FilterTagMultiselectWidget.less
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.ItemMenuOptionWidget.less
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.LiveUpdateButtonWidget.less
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.SavedLinksListWidget.less
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.WatchlistTopSectionWidget.less
resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.ChangesListWrapperWidget.js
resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterItemHighlightButton.js
resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterMenuOptionWidget.js
resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterTagMultiselectWidget.js
resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterWrapperWidget.js
resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.HighlightColorPickerWidget.js
resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.HighlightPopupWidget.js [new file with mode: 0644]
resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.ItemMenuOptionWidget.js
resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.MainWrapperWidget.js
resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.MenuSelectWidget.js
resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.SavedLinksListItemWidget.js
resources/src/mediawiki.skinning/interface.css
resources/src/mediawiki.special.apisandbox/apisandbox.js
resources/src/mediawiki.special.changeslist.css
resources/src/mediawiki.special.contributions.js
resources/src/mediawiki.special.preferences.ooui/tabs.js
resources/src/mediawiki.special.preferences.styles.css
resources/src/mediawiki.special.preferences.styles.ooui.css [deleted file]
resources/src/mediawiki.special.preferences.styles.ooui.less [new file with mode: 0644]
resources/src/mediawiki.special.preferences/tabs.legacy.js
resources/src/mediawiki.special.upload/upload.js
resources/src/mediawiki.special/newpages.less [new file with mode: 0644]
resources/src/mediawiki.toc.styles/common.css [new file with mode: 0644]
resources/src/mediawiki.toc.styles/print.css [new file with mode: 0644]
resources/src/mediawiki.toc.styles/screen.less [new file with mode: 0644]
resources/src/mediawiki.toc/toc.js
resources/src/mediawiki.ui/components/checkbox.less
resources/src/mediawiki.ui/components/inputs.less
resources/src/mediawiki.visibleTimeout.js
resources/src/mediawiki.widgets.datetime/mediawiki.widgets.datetime.definitions.less
resources/src/mediawiki.widgets/mw.widgets.CategoryCapsuleItemWidget.js [deleted file]
resources/src/mediawiki.widgets/mw.widgets.CategoryMultiselectWidget.js
resources/src/mediawiki.widgets/mw.widgets.CategoryTagItemWidget.js [new file with mode: 0644]
resources/src/mediawiki.widgets/mw.widgets.TitleWidget.js
resources/src/mediawiki/mediawiki.errorLogger.js [deleted file]
resources/src/mediawiki/mediawiki.js [deleted file]
resources/src/mediawiki/mediawiki.log.js [deleted file]
resources/src/mediawiki/mediawiki.requestIdleCallback.js [deleted file]
resources/src/startup.js [deleted file]
resources/src/startup/mediawiki.js [new file with mode: 0644]
resources/src/startup/mediawiki.log.js [new file with mode: 0644]
resources/src/startup/mediawiki.requestIdleCallback.js [new file with mode: 0644]
resources/src/startup/startup.js [new file with mode: 0644]
serialized/.gitignore
serialized/Makefile
serialized/normalize-ar.ser [deleted file]
serialized/normalize-ml.ser [deleted file]
tests/common/TestsAutoLoader.php
tests/integration/includes/shell/FirejailCommandTest.php
tests/parser/DbTestRecorder.php
tests/parser/DjVuSupport.php
tests/parser/ParserTestRunner.php
tests/parser/parserTests.php
tests/parser/parserTests.txt
tests/phan/config.php
tests/phpunit/MediaWikiTestCase.php
tests/phpunit/ResourceLoaderTestCase.php
tests/phpunit/data/autoloader/psr4/TestFooBar.php [new file with mode: 0644]
tests/phpunit/data/registration/autoload_namespaces.json [new file with mode: 0644]
tests/phpunit/data/registration/duplicate_keys.json [new file with mode: 0644]
tests/phpunit/data/registration/good.json
tests/phpunit/data/xmp/1.result.php [deleted file]
tests/phpunit/data/xmp/1.xmp [deleted file]
tests/phpunit/data/xmp/2.result.php [deleted file]
tests/phpunit/data/xmp/2.xmp [deleted file]
tests/phpunit/data/xmp/3-invalid.result.php [deleted file]
tests/phpunit/data/xmp/3-invalid.xmp [deleted file]
tests/phpunit/data/xmp/3.result.php [deleted file]
tests/phpunit/data/xmp/3.xmp [deleted file]
tests/phpunit/data/xmp/4.result.php [deleted file]
tests/phpunit/data/xmp/4.xmp [deleted file]
tests/phpunit/data/xmp/5.result.php [deleted file]
tests/phpunit/data/xmp/5.xmp [deleted file]
tests/phpunit/data/xmp/6.result.php [deleted file]
tests/phpunit/data/xmp/6.xmp [deleted file]
tests/phpunit/data/xmp/7.result.php [deleted file]
tests/phpunit/data/xmp/7.xmp [deleted file]
tests/phpunit/data/xmp/README [deleted file]
tests/phpunit/data/xmp/bag-for-seq.result.php [deleted file]
tests/phpunit/data/xmp/bag-for-seq.xmp [deleted file]
tests/phpunit/data/xmp/doctype-included.result.php [deleted file]
tests/phpunit/data/xmp/doctype-included.xmp [deleted file]
tests/phpunit/data/xmp/doctype-not-included.xmp [deleted file]
tests/phpunit/data/xmp/flash.result.php [deleted file]
tests/phpunit/data/xmp/flash.xmp [deleted file]
tests/phpunit/data/xmp/gps.result.php [deleted file]
tests/phpunit/data/xmp/gps.xmp [deleted file]
tests/phpunit/data/xmp/invalid-child-not-struct.result.php [deleted file]
tests/phpunit/data/xmp/invalid-child-not-struct.xmp [deleted file]
tests/phpunit/data/xmp/no-namespace.result.php [deleted file]
tests/phpunit/data/xmp/no-namespace.xmp [deleted file]
tests/phpunit/data/xmp/no-recognized-props.result.php [deleted file]
tests/phpunit/data/xmp/no-recognized-props.xmp [deleted file]
tests/phpunit/data/xmp/utf16BE.result.php [deleted file]
tests/phpunit/data/xmp/utf16BE.xmp [deleted file]
tests/phpunit/data/xmp/utf16LE.result.php [deleted file]
tests/phpunit/data/xmp/utf16LE.xmp [deleted file]
tests/phpunit/data/xmp/utf32BE.result.php [deleted file]
tests/phpunit/data/xmp/utf32BE.xmp [deleted file]
tests/phpunit/data/xmp/utf32LE.result.php [deleted file]
tests/phpunit/data/xmp/utf32LE.xmp [deleted file]
tests/phpunit/data/xmp/xmpExt.result.php [deleted file]
tests/phpunit/data/xmp/xmpExt.xmp [deleted file]
tests/phpunit/data/xmp/xmpExt2.xmp [deleted file]
tests/phpunit/documentation/ReleaseNotesTest.php [new file with mode: 0644]
tests/phpunit/includes/ActorMigrationTest.php
tests/phpunit/includes/AutoLoaderTest.php [new file with mode: 0644]
tests/phpunit/includes/CommentStoreTest.php
tests/phpunit/includes/ContentSecurityPolicyTest.php
tests/phpunit/includes/EditPageTest.php
tests/phpunit/includes/ExtraParserTest.php
tests/phpunit/includes/GlobalFunctions/WfExpandUrlTest.php [new file with mode: 0644]
tests/phpunit/includes/GlobalFunctions/wfArrayFilterTest.php
tests/phpunit/includes/GlobalFunctions/wfExpandUrlTest.php [deleted file]
tests/phpunit/includes/GlobalFunctions/wfUrlencodeTest.php
tests/phpunit/includes/HooksTest.php
tests/phpunit/includes/HtmlTest.php
tests/phpunit/includes/LinkerTest.php
tests/phpunit/includes/MWNamespaceTest.php
tests/phpunit/includes/MediaWikiServicesTest.php
tests/phpunit/includes/MediaWikiTest.php
tests/phpunit/includes/MultiHttpClientTest.php [new file with mode: 0644]
tests/phpunit/includes/OutputPageTest.php
tests/phpunit/includes/PageArchiveTest.php [deleted file]
tests/phpunit/includes/PathRouterTest.php
tests/phpunit/includes/PrefixSearchTest.php
tests/phpunit/includes/RevisionContentHandlerDbTest.php [deleted file]
tests/phpunit/includes/RevisionDbTestBase.php
tests/phpunit/includes/RevisionMcrDbTest.php [new file with mode: 0644]
tests/phpunit/includes/RevisionMcrReadNewDbTest.php [new file with mode: 0644]
tests/phpunit/includes/RevisionMcrWriteBothDbTest.php [new file with mode: 0644]
tests/phpunit/includes/RevisionNoContentHandlerDbTest.php [deleted file]
tests/phpunit/includes/RevisionNoContentModelDbTest.php [new file with mode: 0644]
tests/phpunit/includes/RevisionPreMcrDbTest.php [new file with mode: 0644]
tests/phpunit/includes/RevisionTest.php
tests/phpunit/includes/SampleTest.php
tests/phpunit/includes/Storage/DerivedPageDataUpdaterTest.php [new file with mode: 0644]
tests/phpunit/includes/Storage/McrReadNewRevisionStoreDbTest.php [new file with mode: 0644]
tests/phpunit/includes/Storage/McrReadNewSchemaOverride.php [new file with mode: 0644]
tests/phpunit/includes/Storage/McrRevisionStoreDbTest.php [new file with mode: 0644]
tests/phpunit/includes/Storage/McrSchemaDetection.php [new file with mode: 0644]
tests/phpunit/includes/Storage/McrSchemaOverride.php [new file with mode: 0644]
tests/phpunit/includes/Storage/McrWriteBothRevisionStoreDbTest.php [new file with mode: 0644]
tests/phpunit/includes/Storage/McrWriteBothSchemaOverride.php [new file with mode: 0644]
tests/phpunit/includes/Storage/MutableRevisionRecordTest.php
tests/phpunit/includes/Storage/MutableRevisionSlotsTest.php
tests/phpunit/includes/Storage/NameTableStoreTest.php
tests/phpunit/includes/Storage/NoContentModelRevisionStoreDbTest.php [new file with mode: 0644]
tests/phpunit/includes/Storage/PageUpdaterTest.php [new file with mode: 0644]
tests/phpunit/includes/Storage/PreMcrRevisionStoreDbTest.php [new file with mode: 0644]
tests/phpunit/includes/Storage/PreMcrSchemaOverride.php [new file with mode: 0644]
tests/phpunit/includes/Storage/RevisionSlotsTest.php
tests/phpunit/includes/Storage/RevisionSlotsUpdateTest.php
tests/phpunit/includes/Storage/RevisionStoreDbTest.php [deleted file]
tests/phpunit/includes/Storage/RevisionStoreDbTestBase.php [new file with mode: 0644]
tests/phpunit/includes/Storage/RevisionStoreRecordTest.php
tests/phpunit/includes/Storage/RevisionStoreTest.php
tests/phpunit/includes/Storage/SlotRecordTest.php
tests/phpunit/includes/Storage/SqlBlobStoreTest.php
tests/phpunit/includes/Storage/create-pre-mcr-fields.sql [new file with mode: 0644]
tests/phpunit/includes/Storage/drop-mcr-tables.sql [new file with mode: 0644]
tests/phpunit/includes/Storage/drop-pre-mcr-fields.sql [new file with mode: 0644]
tests/phpunit/includes/Storage/drop-pre-mcr-fields.sqlite.sql [new file with mode: 0644]
tests/phpunit/includes/TestLogger.php
tests/phpunit/includes/TestUserRegistry.php
tests/phpunit/includes/TitleMethodsTest.php
tests/phpunit/includes/TitlePermissionTest.php
tests/phpunit/includes/TitleTest.php
tests/phpunit/includes/WebRequestTest.php
tests/phpunit/includes/XmlTest.php
tests/phpunit/includes/actions/ActionTest.php
tests/phpunit/includes/actions/WatchActionTest.php [new file with mode: 0644]
tests/phpunit/includes/api/ApiBaseTest.php
tests/phpunit/includes/api/ApiComparePagesTest.php
tests/phpunit/includes/api/ApiEditPageTest.php
tests/phpunit/includes/api/ApiMainTest.php
tests/phpunit/includes/api/ApiOptionsTest.php
tests/phpunit/includes/api/ApiQueryPrefixSearchTest.php [new file with mode: 0644]
tests/phpunit/includes/api/ApiQueryRecentChangesIntegrationTest.php
tests/phpunit/includes/api/ApiQuerySearchTest.php [new file with mode: 0644]
tests/phpunit/includes/api/ApiQueryWatchlistIntegrationTest.php
tests/phpunit/includes/api/ApiTestCase.php
tests/phpunit/includes/api/RandomImageGenerator.php
tests/phpunit/includes/api/format/ApiFormatBaseTest.php
tests/phpunit/includes/api/format/ApiFormatTestBase.php
tests/phpunit/includes/api/format/ApiFormatXmlTest.php
tests/phpunit/includes/api/generateRandomImages.php
tests/phpunit/includes/api/query/ApiQueryRevisionsTest.php
tests/phpunit/includes/api/query/ApiQueryTestBase.php
tests/phpunit/includes/api/query/ApiQueryUserContribsTest.php [new file with mode: 0644]
tests/phpunit/includes/api/query/ApiQueryUserContributionsTest.php [deleted file]
tests/phpunit/includes/auth/AuthManagerTest.php
tests/phpunit/includes/auth/ThrottlerTest.php
tests/phpunit/includes/cache/GenderCacheTest.php
tests/phpunit/includes/changetags/ChangeTagsTest.php
tests/phpunit/includes/collation/CustomUppercaseCollationTest.php
tests/phpunit/includes/content/ContentHandlerTest.php
tests/phpunit/includes/content/JavaScriptContentTest.php
tests/phpunit/includes/content/WikitextContentHandlerTest.php
tests/phpunit/includes/content/WikitextContentTest.php
tests/phpunit/includes/db/DatabaseTestHelper.php
tests/phpunit/includes/db/LBFactoryTest.php
tests/phpunit/includes/db/LoadBalancerTest.php
tests/phpunit/includes/debug/DeprecationHelperTest.php [new file with mode: 0644]
tests/phpunit/includes/debug/TestDeprecatedClass.php [new file with mode: 0644]
tests/phpunit/includes/debug/TestDeprecatedSubclass.php [new file with mode: 0644]
tests/phpunit/includes/filebackend/FileBackendTest.php
tests/phpunit/includes/htmlform/HTMLFormTest.php
tests/phpunit/includes/interwiki/InterwikiTest.php
tests/phpunit/includes/jobqueue/JobQueueMemoryTest.php
tests/phpunit/includes/jobqueue/jobs/CategoryMembershipChangeJobTest.php
tests/phpunit/includes/jobqueue/jobs/ClearUserWatchlistJobTest.php
tests/phpunit/includes/libs/CSSMinTest.php
tests/phpunit/includes/libs/EasyDeflateTest.php [new file with mode: 0644]
tests/phpunit/includes/libs/HashRingTest.php
tests/phpunit/includes/libs/IEUrlExtensionTest.php
tests/phpunit/includes/libs/IPTest.php
tests/phpunit/includes/libs/MapCacheLRUTest.php
tests/phpunit/includes/libs/ProcessCacheLRUTest.php
tests/phpunit/includes/libs/XhprofTest.php
tests/phpunit/includes/libs/objectcache/BagOStuffTest.php
tests/phpunit/includes/libs/objectcache/MultiWriteBagOStuffTest.php
tests/phpunit/includes/libs/objectcache/WANObjectCacheTest.php
tests/phpunit/includes/libs/rdbms/database/DBConnRefTest.php
tests/phpunit/includes/libs/rdbms/database/DatabaseMysqlBaseTest.php
tests/phpunit/includes/libs/rdbms/database/DatabaseSQLTest.php
tests/phpunit/includes/libs/rdbms/database/DatabaseTest.php
tests/phpunit/includes/libs/xmp/XMPTest.php [deleted file]
tests/phpunit/includes/libs/xmp/XMPValidateTest.php [deleted file]
tests/phpunit/includes/linker/LinkRendererTest.php
tests/phpunit/includes/logging/LogFormatterTestCase.php
tests/phpunit/includes/media/IPTCTest.php
tests/phpunit/includes/media/MediaWikiMediaTestCase.php
tests/phpunit/includes/page/PageArchiveMcrTest.php [new file with mode: 0644]
tests/phpunit/includes/page/PageArchivePreMcrTest.php [new file with mode: 0644]
tests/phpunit/includes/page/PageArchiveTestBase.php [new file with mode: 0644]
tests/phpunit/includes/page/WikiPageContentHandlerDbTest.php [deleted file]
tests/phpunit/includes/page/WikiPageDbTestBase.php
tests/phpunit/includes/page/WikiPageMcrDbTest.php [new file with mode: 0644]
tests/phpunit/includes/page/WikiPageMcrReadNewDbTest.php [new file with mode: 0644]
tests/phpunit/includes/page/WikiPageMcrWriteBothDbTest.php [new file with mode: 0644]
tests/phpunit/includes/page/WikiPageNoContentHandlerDbTest.php [deleted file]
tests/phpunit/includes/page/WikiPageNoContentModelDbTest.php [new file with mode: 0644]
tests/phpunit/includes/page/WikiPagePreMcrDbTest.php [new file with mode: 0644]
tests/phpunit/includes/parser/MagicVariableTest.php
tests/phpunit/includes/parser/ParserOptionsTest.php
tests/phpunit/includes/preferences/DefaultPreferencesFactoryTest.php
tests/phpunit/includes/preferences/FiltersTest.php [new file with mode: 0644]
tests/phpunit/includes/registration/ExtensionJsonValidatorTest.php
tests/phpunit/includes/registration/ExtensionRegistryTest.php
tests/phpunit/includes/registration/VersionCheckerTest.php
tests/phpunit/includes/resourceloader/MessageBlobStoreTest.php
tests/phpunit/includes/resourceloader/ResourceLoaderClientHtmlTest.php
tests/phpunit/includes/resourceloader/ResourceLoaderFileModuleTest.php
tests/phpunit/includes/resourceloader/ResourceLoaderModuleTest.php
tests/phpunit/includes/resourceloader/ResourceLoaderStartUpModuleTest.php
tests/phpunit/includes/resourceloader/ResourceLoaderTest.php
tests/phpunit/includes/search/SearchEnginePrefixTest.php
tests/phpunit/includes/search/SearchEngineTest.php
tests/phpunit/includes/search/SearchNearMatchResultSetTest.php [new file with mode: 0644]
tests/phpunit/includes/search/SearchResultSetTest.php [new file with mode: 0644]
tests/phpunit/includes/search/SearchResultTest.php [new file with mode: 0644]
tests/phpunit/includes/services/ServiceContainerTest.php
tests/phpunit/includes/session/CookieSessionProviderTest.php
tests/phpunit/includes/session/PHPSessionHandlerTest.php
tests/phpunit/includes/session/SessionTest.php
tests/phpunit/includes/session/TestUtils.php
tests/phpunit/includes/specialpage/AbstractChangesListSpecialPageTestCase.php
tests/phpunit/includes/specialpage/SpecialPageFactoryTest.php
tests/phpunit/includes/specialpage/SpecialPageTest.php
tests/phpunit/includes/specials/SpecialBlankPageTest.php
tests/phpunit/includes/specials/SpecialPageExecutor.php
tests/phpunit/includes/specials/SpecialPageTestBase.php
tests/phpunit/includes/specials/SpecialPreferencesTest.php
tests/phpunit/includes/specials/SpecialSearchTest.php
tests/phpunit/includes/specials/SpecialShortpagesTest.php
tests/phpunit/includes/title/MediaWikiTitleCodecTest.php
tests/phpunit/includes/title/NaiveImportTitleFactoryTest.php
tests/phpunit/includes/title/NamespaceImportTitleFactoryTest.php
tests/phpunit/includes/title/SubpageImportTitleFactoryTest.php
tests/phpunit/includes/upload/UploadBaseTest.php
tests/phpunit/includes/user/PasswordResetTest.php
tests/phpunit/includes/user/UserTest.php
tests/phpunit/languages/LanguageConverterTest.php
tests/phpunit/languages/LanguageTest.php
tests/phpunit/languages/SpecialPageAliasTest.php
tests/phpunit/languages/classes/LanguageCrhTest.php
tests/phpunit/maintenance/backup_PageTest.php
tests/phpunit/maintenance/deleteAutoPatrolLogsTest.php
tests/phpunit/maintenance/populateChangeTagDefTest.php [new file with mode: 0644]
tests/phpunit/mocks/MockMessageLocalizer.php
tests/phpunit/mocks/content/DummyContentForTesting.php
tests/phpunit/mocks/content/DummyContentHandlerForTesting.php
tests/phpunit/mocks/content/DummyNonTextContent.php
tests/phpunit/mocks/content/DummyNonTextContentHandler.php
tests/phpunit/mocks/content/DummySerializeErrorContentHandler.php
tests/phpunit/mocks/search/MockCompletionSearchEngine.php [new file with mode: 0644]
tests/phpunit/mocks/search/MockSearchEngine.php [new file with mode: 0644]
tests/phpunit/mocks/search/MockSearchResult.php [new file with mode: 0644]
tests/phpunit/mocks/search/MockSearchResultSet.php [new file with mode: 0644]
tests/phpunit/structure/AutoLoaderStructureTest.php [new file with mode: 0644]
tests/phpunit/structure/AutoLoaderTest.php [deleted file]
tests/phpunit/structure/AvailableRightsTest.php
tests/phpunit/structure/ContentHandlerSanityTest.php
tests/phpunit/structure/ExtensionJsonValidationTest.php
tests/phpunit/structure/ResourcesTest.php
tests/phpunit/structure/SpecialPageFatalTest.php [new file with mode: 0644]
tests/phpunit/structure/StructureTest.php
tests/phpunit/suite.xml
tests/phpunit/suites/ExtensionsTestSuite.php
tests/phpunit/suites/ParserTestTopLevelSuite.php
tests/phpunit/tests/MediaWikiTestCaseSchema1Test.php
tests/phpunit/tests/MediaWikiTestCaseSchema2Test.php
tests/qunit/.eslintrc.json
tests/qunit/QUnitTestResources.php
tests/qunit/data/generateJqueryMsgData.php
tests/qunit/data/styleTest.css.php
tests/qunit/data/testrunner.js
tests/qunit/suites/resources/jquery/jquery.accessKeyLabel.test.js
tests/qunit/suites/resources/jquery/jquery.colorUtil.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
tests/qunit/suites/resources/jquery/jquery.tablesorter.test.js
tests/qunit/suites/resources/jquery/jquery.textSelection.test.js
tests/qunit/suites/resources/mediawiki.api/mediawiki.api.category.test.js
tests/qunit/suites/resources/mediawiki.api/mediawiki.api.edit.test.js
tests/qunit/suites/resources/mediawiki.api/mediawiki.api.parse.test.js
tests/qunit/suites/resources/mediawiki.api/mediawiki.api.test.js
tests/qunit/suites/resources/mediawiki.api/mediawiki.api.watch.test.js
tests/qunit/suites/resources/mediawiki.rcfilters/UriProcessor.test.js
tests/qunit/suites/resources/mediawiki.rcfilters/dm.FilterItem.test.js
tests/qunit/suites/resources/mediawiki.rcfilters/dm.FiltersViewModel.test.js
tests/qunit/suites/resources/mediawiki.rcfilters/dm.SavedQueriesModel.test.js
tests/qunit/suites/resources/mediawiki.rcfilters/dm.SavedQueryItemModel.test.js
tests/qunit/suites/resources/mediawiki.widgets/MediaSearch/mediawiki.widgets.APIResultsQueue.test.js [new file with mode: 0644]
tests/qunit/suites/resources/mediawiki/mediawiki.RegExp.test.js
tests/qunit/suites/resources/mediawiki/mediawiki.String.byteLength.test.js
tests/qunit/suites/resources/mediawiki/mediawiki.String.trimByteLength.test.js
tests/qunit/suites/resources/mediawiki/mediawiki.Title.test.js
tests/qunit/suites/resources/mediawiki/mediawiki.Uri.test.js
tests/qunit/suites/resources/mediawiki/mediawiki.base.test.js [new file with mode: 0644]
tests/qunit/suites/resources/mediawiki/mediawiki.cldr.test.js
tests/qunit/suites/resources/mediawiki/mediawiki.experiments.test.js
tests/qunit/suites/resources/mediawiki/mediawiki.html.test.js
tests/qunit/suites/resources/mediawiki/mediawiki.inspect.test.js
tests/qunit/suites/resources/mediawiki/mediawiki.jqueryMsg.test.js
tests/qunit/suites/resources/mediawiki/mediawiki.jscompat.test.js
tests/qunit/suites/resources/mediawiki/mediawiki.language.test.js
tests/qunit/suites/resources/mediawiki/mediawiki.loader.test.js
tests/qunit/suites/resources/mediawiki/mediawiki.template.mustache.test.js
tests/qunit/suites/resources/mediawiki/mediawiki.template.test.js
tests/qunit/suites/resources/mediawiki/mediawiki.test.js
tests/qunit/suites/resources/mediawiki/mediawiki.user.test.js
tests/qunit/suites/resources/mediawiki/mediawiki.util.test.js
tests/selenium/pageobjects/recentchanges.page.js [new file with mode: 0644]
tests/selenium/pageobjects/watchable.page.js [new file with mode: 0644]
tests/selenium/pageobjects/watchlist.page.js [new file with mode: 0644]
tests/selenium/selenium.sh
tests/selenium/specs/page.js
tests/selenium/specs/specialrecentchanges.js [new file with mode: 0644]
tests/selenium/specs/specialwatchlist.js [new file with mode: 0644]
tests/selenium/specs/user.js
tests/selenium/wdio-mediawiki/CHANGELOG.md
tests/selenium/wdio-mediawiki/Util.js [new file with mode: 0644]
tests/selenium/wdio-mediawiki/package.json
tests/selenium/wdio-mediawiki/specs/BlankPage.js
tests/selenium/wdio.conf.js
thumb.php

diff --git a/.editorconfig b/.editorconfig
new file mode 100644 (file)
index 0000000..9231818
--- /dev/null
@@ -0,0 +1,11 @@
+root = true
+
+[*]
+indent_style = tab
+end_of_line = lf
+charset = utf-8
+trim_trailing_whitespace = true
+insert_final_newline = true
+
+[*.md]
+trim_trailing_whitespace = false
index 64b5ea7..844895d 100644 (file)
@@ -11,6 +11,7 @@
                "OO": false
        },
        "rules": {
-               "dot-notation": 0
+               "dot-notation": 0,
+               "max-len": 0
        }
 }
index 440adaf..2a34154 100644 (file)
@@ -2,27 +2,27 @@
 <ruleset name="MediaWiki">
        <rule ref="./vendor/mediawiki/mediawiki-codesniffer/MediaWiki">
                <exclude name="Generic.ControlStructures.InlineControlStructure" />
+               <exclude name="MediaWiki.Commenting.FunctionAnnotations.UnrecognizedAnnotation" />
                <exclude name="MediaWiki.Commenting.FunctionComment.MissingDocumentationProtected" />
                <exclude name="MediaWiki.Commenting.FunctionComment.MissingDocumentationPublic" />
                <exclude name="MediaWiki.Commenting.FunctionComment.MissingParamTag" />
                <exclude name="MediaWiki.Commenting.FunctionComment.MissingReturn" />
                <exclude name="MediaWiki.Commenting.FunctionComment.ExtraParamComment" />
                <exclude name="MediaWiki.Commenting.FunctionComment.WrongStyle" />
+               <exclude name="MediaWiki.Commenting.PhpunitAnnotations.NotClassTrait" />
                <exclude name="MediaWiki.Commenting.IllegalSingleLineComment.IllegalSingleLineCommentStart" />
                <exclude name="MediaWiki.Commenting.IllegalSingleLineComment.IllegalSingleLineCommentEnd" />
-               <exclude name="MediaWiki.Commenting.LicenseComment.InvalidLicenseTag" />
                <exclude name="MediaWiki.ControlStructures.AssignmentInControlStructures.AssignmentInControlStructures" />
+               <exclude name="MediaWiki.Commenting.MissingCovers.MissingCovers" />
                <exclude name="MediaWiki.NamingConventions.LowerCamelFunctionsName.FunctionName" />
-               <exclude name="MediaWiki.WhiteSpace.SpaceBeforeSingleLineComment.NewLineComment" />
-               <exclude name="MediaWiki.WhiteSpace.SpaceBeforeSingleLineComment.SingleSpaceBeforeSingleLineComment" />
                <exclude name="MediaWiki.Usage.DbrQueryUsage.DbrQueryFound" />
                <exclude name="MediaWiki.Usage.ExtendClassUsage.FunctionVarUsage" />
-               <exclude name="MediaWiki.Files.ClassMatchesFilename.WrongCase" />
-               <exclude name="MediaWiki.Files.ClassMatchesFilename.NotMatch" />
+               <exclude name="MediaWiki.Usage.ForbiddenFunctions.passthru" />
                <exclude name="MediaWiki.VariableAnalysis.ForbiddenGlobalVariables.ForbiddenGlobal$wgTitle" />
+               <exclude name="MediaWiki.WhiteSpace.SpaceBeforeSingleLineComment.NewLineComment" />
+               <exclude name="MediaWiki.WhiteSpace.SpaceBeforeSingleLineComment.SingleSpaceBeforeSingleLineComment" />
                <exclude name="Squiz.Scope.MethodScope.Missing" />
                <exclude name="Squiz.Scope.MemberVarScope.Missing" />
-               <exclude name="MediaWiki.Commenting.MissingCovers.MissingCovers" />
        </rule>
        <rule ref="MediaWiki.NamingConventions.PrefixedGlobalFunctions">
                <properties>
        </rule>
        <rule ref="MediaWiki.NamingConventions.ValidGlobalName">
                <properties>
-                       <property name="ignoreList" type="array" value="$IP,$messageMemc,$parserMemc" />
+                       <property name="ignoreList" type="array" value="$IP,$messageMemc" />
                </properties>
        </rule>
+       <rule ref="MediaWiki.NamingConventions.ValidGlobalName.allowedPrefix">
+               <exclude-pattern>profileinfo\.php</exclude-pattern>
+               <exclude-pattern>maintenance/language/checkLanguage\.inc</exclude-pattern>
+               <exclude-pattern>maintenance/doMaintenance\.php</exclude-pattern>
+               <exclude-pattern>maintenance/mergeMessageFileList\.php</exclude-pattern>
+               <exclude-pattern>maintenance/commandLine\.inc</exclude-pattern>
+       </rule>
        <rule ref="Generic.Files.LineLength">
                <exclude-pattern>*/languages/messages/Messages*\.php</exclude-pattern>
        </rule>
+       <rule ref="MediaWiki.Files.ClassMatchesFilename.NotMatch">
+               <!--
+                       Whitelist existing violations, but enable the sniff to prevent
+                       any new occurrences.
+               -->
+               <exclude-pattern>*/includes/media/XCF\.php</exclude-pattern>
+               <exclude-pattern>*/includes/Feed\.php</exclude-pattern>
+               <exclude-pattern>*/includes/libs/xmp/XMP\.php</exclude-pattern>
+               <exclude-pattern>*/includes/jobqueue/JobSpecification\.php</exclude-pattern>
+               <exclude-pattern>*/includes/RevisionList\.php</exclude-pattern>
+               <exclude-pattern>*/includes/installer/PhpBugTests\.php</exclude-pattern>
+               <exclude-pattern>*/includes/exception/LocalizedException\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialMostinterwikis\.php</exclude-pattern>
+               <exclude-pattern>*/includes/cache/CacheDependency\.php</exclude-pattern>
+               <exclude-pattern>*/includes/cache/CacheHelper\.php</exclude-pattern>
+               <exclude-pattern>*/includes/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/SpecialBrokenRedirects\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialConfirmemail\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialDeadendpages\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialDeletedContributions\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialDoubleRedirects\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialEmailInvalidate\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialFewestrevisions\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialFileDuplicateSearch\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialLinkSearch\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialListDuplicatedFiles\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialListredirects\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialLonelypages\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialLongpages\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialMIMEsearch\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialMediaStatistics\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialMostcategories\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialMostimages\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialMostlinked\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialMostlinkedcategories\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialMostlinkedtemplates\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialMostrevisions\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialMovepage\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialMyRedirectPages\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialNewimages\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialRandompage\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialShortpages\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialUncategorizedcategories\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialUncategorizedimages\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialUncategorizedpages\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialUncategorizedtemplates\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialUnusedcategories\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialUnusedimages\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialUnusedtemplates\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialUnwatchedpages\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialUserrights\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialWantedcategories\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialWantedfiles\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialWantedpages\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialWantedtemplates\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialWithoutinterwiki\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/7zip.inc</exclude-pattern>
+               <exclude-pattern>*/maintenance/CodeCleanerGlobalsPass.inc</exclude-pattern>
+               <exclude-pattern>*/maintenance/archives/upgradeLogging\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/backup.inc</exclude-pattern>
+               <exclude-pattern>*/maintenance/benchmarks/bench_HTTP_HTTPS\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/benchmarks/bench_Wikimedia_base_convert\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/benchmarks/bench_delete_truncate\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/benchmarks/bench_if_switch\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/benchmarks/bench_strtr_str_replace\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/benchmarks/bench_utf8_title_check\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/benchmarks/bench_wfIsWindows\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/cleanupTable.inc</exclude-pattern>
+               <exclude-pattern>*/maintenance/cleanupTitles\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/commandLine.inc</exclude-pattern>
+               <exclude-pattern>*/maintenance/dumpTextPass\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/edit\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/findDeprecated\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/getText\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/hhvm/makeRepo\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/importDump\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/install\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/invalidateUserSessions\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/jsparse\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/lag\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/language/StatOutputs\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/language/checkLanguage.inc</exclude-pattern>
+               <exclude-pattern>*/maintenance/language/date-formats\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/language/languages.inc</exclude-pattern>
+               <exclude-pattern>*/maintenance/minify\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/mysql\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/parse\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/preprocessorFuzzTest\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/rebuildImages\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/renderDump\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/shell\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/sql\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/sqlite.inc</exclude-pattern>
+               <exclude-pattern>*/maintenance/sqlite\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/term/MWTerm\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/update\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/userDupes.inc</exclude-pattern>
+               <exclude-pattern>*/maintenance/userOptions\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/view\.php</exclude-pattern>
+               <exclude-pattern>*/profileinfo\.php</exclude-pattern>
+               <!-- Language converters use the pattern of 2 classes in one file -->
+               <exclude-pattern>*/languages/*\.php</exclude-pattern>
+               <!-- We don't care that much about violations in tests -->
+               <exclude-pattern>*/tests/*\.php</exclude-pattern>
+       </rule>
+       <rule ref="MediaWiki.Files.ClassMatchesFilename.WrongCase">
+               <!--
+                       Whitelist existing violations, but enable the sniff to prevent
+                       any new occurrences.
+               -->
+               <exclude-pattern>*/includes/specials/SpecialActiveusers\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialBooksources\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialEmailuser\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialListfiles\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialListgrants\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialListgrouprights\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialListusers.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialRecentchanges\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialRecentchangeslinked\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialRevisiondelete\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/SpecialWhatlinkshere\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/language/alltrans\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/language/digit2html\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/language/langmemusage\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/mctest\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/mergeMessageFileList\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/mwdocgen\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/rebuildall\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/rebuildmessages\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/rebuildrecentchanges\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/rebuildtextindex\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/storage/checkStorage\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/storage/recompressTracked\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/storage/trackBlobs\.php</exclude-pattern>
+               <!-- We don't care that much about violations in tests -->
+               <exclude-pattern>*/tests/*\.php</exclude-pattern>
+       </rule>
+
        <rule ref="Generic.Files.OneObjectStructurePerFile.MultipleFound">
                <!--
                        Whitelist existing violations, but enable the sniff to prevent
                <exclude-pattern>*/includes/AuthPlugin\.php</exclude-pattern>
                <exclude-pattern>*/includes/cache/CacheDependency\.php</exclude-pattern>
                <exclude-pattern>*/includes/cache/CacheHelper\.php</exclude-pattern>
+               <exclude-pattern>*/includes/compat/XMPReader\.php</exclude-pattern>
                <exclude-pattern>*/includes/deferred/CdnCacheUpdate\.php</exclude-pattern>
                <exclude-pattern>*/includes/diff/DairikiDiff\.php</exclude-pattern>
                <exclude-pattern>*/includes/diff/DiffEngine\.php</exclude-pattern>
                <exclude-pattern>*/includes/search/SearchEngine\.php</exclude-pattern>
                <exclude-pattern>*/includes/specialpage/LoginSignupSpecialPage\.php</exclude-pattern>
                <exclude-pattern>*/includes/specialpage/RedirectSpecialPage\.php</exclude-pattern>
+               <exclude-pattern>*/includes/specials/forms/PreferencesFormLegacy\.php</exclude-pattern>
                <exclude-pattern>*/includes/specials/SpecialListusers\.php</exclude-pattern>
                <exclude-pattern>*/includes/specials/SpecialMyRedirectPages\.php</exclude-pattern>
                <exclude-pattern>*/includes/specials/SpecialUploadStash\.php</exclude-pattern>
        <rule ref="MediaWiki.Usage.AssignmentInReturn.AssignmentInReturn">
                <exclude-pattern>*/tests/phpunit/*\.php</exclude-pattern>
        </rule>
+       <rule ref="MediaWiki.Usage.ForbiddenFunctions.escapeshellarg">
+               <!--
+                       Whitelist existing violations, but enable the sniff to prevent
+                       any new occurrences.
+               -->
+               <exclude-pattern>*/includes/libs/filebackend/FSFileBackend\.php</exclude-pattern>
+               <exclude-pattern>*/includes/shell/Command\.php</exclude-pattern>
+               <exclude-pattern>*/includes/shell/Shell\.php</exclude-pattern>
+               <exclude-pattern>*/tests/phpunit/structure/StructureTest\.php</exclude-pattern>
+       </rule>
+       <rule ref="MediaWiki.Usage.ForbiddenFunctions.exec">
+               <!--
+                       Whitelist existing violations, but enable the sniff to prevent
+                       any new occurrences.
+               -->
+               <exclude-pattern>*/tests/phpunit/structure/StructureTest\.php</exclude-pattern>
+       </rule>
+       <rule ref="MediaWiki.Usage.ForbiddenFunctions.popen">
+               <!--
+                       Whitelist existing violations, but enable the sniff to prevent
+                       any new occurrences.
+               -->
+               <exclude-pattern>*/includes/GlobalFunctions\.php</exclude-pattern>
+               <exclude-pattern>*/includes/libs/filebackend/FSFileBackend\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/7zip\.inc</exclude-pattern>
+               <exclude-pattern>*/maintenance/populateImageSha1\.php</exclude-pattern>
+       </rule>
+       <rule ref="MediaWiki.Usage.ForbiddenFunctions.proc_open">
+               <!--
+                       Whitelist existing violations, but enable the sniff to prevent
+                       any new occurrences.
+               -->
+               <exclude-pattern>includes/export/DumpPipeOutput\.php</exclude-pattern>
+               <exclude-pattern>includes/resourceloader/ResourceLoaderImage\.php</exclude-pattern>
+               <exclude-pattern>includes/shell/Command\.php</exclude-pattern>
+               <exclude-pattern>includes/tidy/RaggettExternal\.php</exclude-pattern>
+               <exclude-pattern>maintenance/dumpTextPass\.php</exclude-pattern>
+               <exclude-pattern>maintenance/mysql\.php</exclude-pattern>
+               <exclude-pattern>maintenance/storage/recompressTracked\.php</exclude-pattern>
+               <exclude-pattern>tests/parser/editTests\.php</exclude-pattern>
+       </rule>
+       <rule ref="MediaWiki.Usage.ForbiddenFunctions.shell_exec">
+               <!--
+                       Whitelist existing violations, but enable the sniff to prevent
+                       any new occurrences.
+               -->
+               <exclude-pattern>*/maintenance/mwdocgen\.php</exclude-pattern>
+               <exclude-pattern>*/maintenance/updateCredits\.php</exclude-pattern>
+       </rule>
+       <rule ref="MediaWiki.Usage.ForbiddenFunctions.system">
+               <!--
+                       Whitelist existing violations, but enable the sniff to prevent
+                       any new occurrences.
+               -->
+               <exclude-pattern>*/maintenance/mwdocgen\.php</exclude-pattern>
+       </rule>
        <file>.</file>
        <arg name="encoding" value="UTF-8"/>
        <arg name="extensions" value="php,php5,inc,sample"/>
index 73e4af5..2fc6d64 100644 (file)
@@ -37,6 +37,12 @@ matrix:
       php: hhvm-3.21
     - env: dbtype=mysql dbuser=root
       php: hhvm-3.18
+  allow_failures:
+    - php: 7.2
+    - env: dbtype=postgres dbuser=travis
+    - php: hhvm-3.18
+    - php: hhvm-3.21
+    - php: hhvm-3.24
 
 services:
   - mysql
@@ -77,7 +83,8 @@ notifications:
   email: false
   irc:
     channels:
-      - "chat.freenode.net#mediawiki-feed"
+      - "chat.freenode.net#wikimedia-dev"
+    template:
+      - "%{repository}#%{build_number} (%{branch} - %{commit} %{author}): %{message} - %{build_url}"
     on_success: change
-    on_failure: change
-    skip_join: true
+    on_failure: always
index 8018212..6be908e 100644 (file)
@@ -33,9 +33,7 @@ module.exports = function ( grunt ) {
                                '!vendor/**',
                                // Explicitly say "**/*.js" here in case of symlinks
                                '!extensions/**/*.js',
-                               '!skins/**/*.js',
-                               // Skip functions aren't even parseable
-                               '!resources/src/mediawiki.hidpi/skip.js'
+                               '!skins/**/*.js'
                        ]
                },
                jsonlint: {
diff --git a/HISTORY b/HISTORY
index 0693b21..7540af3 100644 (file)
--- a/HISTORY
+++ b/HISTORY
@@ -1,4 +1,490 @@
-Change notes from older releases. For current info see RELEASE-NOTES-1.31.
+Change notes from older releases. For current info see RELEASE-NOTES-1.32.
+
+= MediaWiki 1.31 =
+
+== MediaWiki 1.31.0 ==
+
+=== Changes since MediaWiki 1.31.0-rc.2 ===
+* (T195783) Initialize PSR-4 namespaces at same stage as normal autoloader.
+* (T196092) Hide MySQL binary/utf-8 charset option in the installer.
+* (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.
+* (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.
+
+=== Changes since MediaWiki 1.31.0-rc.0 ===
+* (T33223) Drop archive.ar_text and ar_flags.
+* Add default edit rate limit of 90 edits/minute for all users.
+* (T187645) Use codepoint as tiebreaker when getting first-letters in
+  IcuCollation.
+* (T191947) Don't shell during the installer if shelling out is disabled.
+* (T194319) Improve duplicate config setting exception as part of extension
+  registration.
+* (T195211) Don't require trailing slash in PSR-4 autoloader directory.
+* (T186565) Fix PHP Notice from `ob_end_flush()` in `FileRepo::streamFile()`.
+* Do not incorrectly hide namespace input field in the installer.
+* (T186456) Refactor checks looking for PEAR maik libraries to be clearer.
+
+=== Important pre-upgrade notes for 1.31 ===
+* If you're using MySQL, SQLite, or MSSQL, are not using update.php to apply
+  schema changes, and cannot have downtime to run migrateArchiveText.php and
+  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.
+
+=== Configuration changes in 1.31 ===
+* $wgEnableAPI and $wgEnableWriteAPI are now deprecated and will be removed in
+  a future version. The API is now considered to be stable, secure and
+  essential.
+* $wgUsejQueryThree was removed, as it is now the default. This was documented
+  as a temporary variable during the migration period, deprecated since 1.29.
+* $wgLogoHD has been updated to support svg images and uses $wgLogo where
+  possible for fallback images such as png.
+* (T44246) $wgFilterLogTypes will no longer ignore 'patrol' when user does not
+  have the right to mark things patrolled.
+* Wikis that contain imported revisions or CentralAuth global blocks should run
+  maintenance/cleanupUsersWithNoId.php.
+* The configuration settings $wgResourceLoaderMinifierStatementsOnOwnLine and
+  $wgResourceLoaderMinifierMaxLineLength, deprecated since 1.27, were removed.
+* (T180921) $wgReferrerPolicy now supports having fallbacks for browsers that
+  are not using the latest version of the Referrer Policy specification.
+* $wgFragmentMode is now set to [ 'legacy', 'html5' ] by default. This is a
+  first step of migration to human-readable section IDs that will later result
+  in 'html5' being the default mode.
+* CACHE_ACCEL now only supports APC(u) or WinCache. XCache support was removed
+  as upstream is inactive and has no plans to move to PHP 7.
+* The old CategorizedRecentChanges feature, including its related configuration
+  option $wgAllowCategorizedRecentChanges, has been removed.
+* (T188472) The 'comma' value for $wgArticleCountMethod is no longer supported
+  for performance reasons, and installations with this setting will now work as
+  if it was configured with 'any'.
+* (T185753) MediaWiki now defaults to using RemexHtml to tidy up user input,
+  rather than being off by default. If you wish to disable HTML tidying
+  entirely, set $wgTidyConfig to null; if you wish to use the old, deprecated
+  Tidy external binary, both set $wgTidyConfig to null and $wgUseTidy to true.
+* $wgLogAutopatrol now defaults to false instead of true.
+* $wgValidateAllHtml was removed and will be ignored.
+* $wgScriptExtension, deprecated and ignored since 1.25, was removed. See the
+  1.25 release notes for more information.
+* $wgUseAjax is now marked as deprecated, just like the deprecated AJAX
+  framework that it enables. Some extensions mistakenly used this to check
+  whether any AJAX functionality at all should be enabled, further making this
+  problematic to retain.
+* $wgDBmysql5 is now deprecated, and will be removed in a future version. It
+  has been marked as experimental ever since it was introduced.
+
+=== New features in 1.31 ===
+* (T76554) User sub-pages named ….json are now protected in the same way that
+  ….js and ….css pages are, so that configuration options can safely be placed
+  there.
+* Wikimedia\Rdbms\IDatabase->select() and similar methods now support joins
+  with parentheses for grouping.
+* As a first pass in standardizing dialog boxes across the MediaWiki product,
+  Html class now provides helper methods for messageBox, successBox, errorBox
+  and warningBox generation.
+* (T9240) Imports will now record unknown (and, optionally, known) usernames in
+  a format like "iw>Example".
+* (T20209) Linker (used on history pages, log pages, and so on) will display
+  usernames formed like "iw>Example" as interwiki links, as if by wikitext like
+  [[iw:User:Example|iw>Example]].
+* (T111605) The 'ImportHandleUnknownUser' hook allows extensions to auto-create
+  users during an import.
+* Added a hook, ParserOutputPostCacheTransform, to allow extensions to affect
+  the ParserOutput::getText() post-cache transformations.
+* Added a hook, UploadForm:getInitialPageText, to allow extensions to alter the
+  initial page text for file uploads.
+* (T181651) The info page for File pages now displays the file's base-16 SHA1
+  hash value in the table of basic information.
+* Style tags with a 'data-mw-deduplicate' attribute will be deduplicated as a
+  ParserOutput::getText() post-cache transformation. This may be disabled by
+  passing 'deduplicateStyles' => false to that method.
+* The identity of the logged-in or IP "actor" for logged actions is being moved
+  into a new actor table, with the rows in tables such as revision and logging
+  referring to the actor ID instead of storing the user ID and name/IP in
+  every row.
+  * This is currently gated by $wgActorTableSchemaMigrationStage. Most wikis
+    can set this to MIGRATION_NEW and run maintenance/migrateActors.php as
+    soon as any necessary extensions are updated.
+  * Most code accessing rows for logged actions from the database should use
+    the relevant getQueryInfo() methods to get the information needed to build
+    the SQL query. The ActorMigration class may also be used to get feature
+    -flagged information needed to access actor-related fields during the
+    migration period.
+* Added Wikimedia\Rdbms\IDatabase::cancelAtomic(), to roll back an atomic
+  section without having to roll back the whole transaction.
+* Wikimedia\Rdbms\IDatabase::doAtomicSection(), non-native ::insertSelect(),
+  and non-MySQL ::replace() and ::upsert() no longer roll back the whole
+  transaction on failure.
+* (T189785) Added a monthly heartbeat ping to the pingback feature.
+* The CLI installer (maintenance/install.php) learned to detect and include
+  extensions. Pass --with-extensions to enable that feature.
+* (T184791) rc_patrolled now has three states: "0" for unpatrolled,
+  "1" for manually patrolled and "2" for autopatrolled actions.
+* Extensions can now set their type to "editor" if they provide an editor or
+  enhance the editing experience.
+* Extensions can use a PSR-4 autoloader by setting an "AutoloadNamespaces"
+  property in extension.json. See the documentation at
+  <https://mediawiki.org/wiki/Manual:Extension.json/Schema#AutoloadNamespaces>
+  for more details and an example.
+* (T19099) Tabs which link to pages that don't exist (like those to uncreated
+  discussion pages) now have a tooltip to indicate state, not just colour.
+
+=== External library changes in 1.31 ===
+* pear/mail, pear/mail_mime and pear/mail_mime-decode have been moved from
+  suggested to required. These packages now must be installed via composer
+  and not via PEAR itself.
+
+==== Upgraded external libraries ====
+* Updated jquery.chosen from v0.9.14 to v1.8.2.
+* Updated composer/spdx-licenses from 1.1.4 to 1.3.0 (development dependency).
+* Updated nikic/php-parser from 2.1.0 to 3.1.3 (development dependency).
+* Updated wikimedia/ip-set from 1.1.0 to 1.2.0.
+* Updated wikimedia/relpath from 2.0.0 to 2.1.1.
+* Updated wikimedia/running-stat from 1.1.0 to 1.2.0.
+* Updated wikimedia/wrappedstring from 2.2.0 to 2.3.0.
+* Updated mediawiki/at-ease from 1.1.0 to 1.2.0.
+* Updated wikimedia/php-session-serializer from 1.0.4 to 1.0.6.
+* Updated wikimedia/remex-html from 1.0.2 to 1.0.3.
+* Updated wikimedia/html-formatter from 1.0.1 to 1.0.2.
+
+==== New external libraries ====
+* Added wikimedia/object-factory 1.0.0
+
+==== Removed and replaced external libraries ====
+* (T17845) The deprecated 'jquery.badge' module was removed.
+* The deprecated 'jquery.autoEllipsis' module was removed. Use the CSS
+  text-overflow property instead.
+* The deprecated 'jquery.placeholder' module was removed.
+* The deprecated 'jquery.appear' module was removed. Use the
+  'mediawiki.viewport' module instead.
+* mediawiki/at-ease was replaced with wikimedia/at-ease.
+
+=== Bug fixes in 1.31 ===
+* (T90902) Non-breaking space in header ID breaks anchor.
+* (T189375) CSSMin now allows quoted urls in `url()` syntax to start with a
+  space.
+* (T2087, T10897, T87753, T174639) Whitespace created by category and language
+  links is now stripped rather than leaving blank lines in odd places.
+* (T3780) Uploads with UTF-8 names now work on PHP7.1+ on Windows servers.
+* (T182366) UploadBase::checkXMLEncodingMissmatch() now works on PHP 7.1+
+
+=== Action API changes in 1.31 ===
+* (T185058) The 'name' value to tgprop for action=query&list=tags has been
+  removed. It has never made a difference in the output, the name was always
+  returned regardless.
+* The 'watch' and 'unwatch' parameters for action=move have been removed. They
+  were deprecated and also accidentally nonfunctional since 1.17 in 2010. Use
+  'watchlist' instead.
+
+=== Action API internal changes in 1.31 ===
+* ApiBase::getProfileDBTime, deprecated since 1.25, was removed.
+* ApiBase::getModuleProfileName, deprecated since 1.25, was removed.
+* ApiBase::getProfileTime, deprecated since 1.25, was removed.
+
+=== Languages updated in 1.31 ===
+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.
+
+* (T180052) Mirandese (mwl) now supports gendered NS_USER/NS_USER_TALK.
+* (T182305) New language support: Nyungar (nys).
+* (T186359) New language support: Siberian Tatar [cебертатар] (sty).
+* (T186635) New language support: Guianan Creole (gcr).
+* (T186647) New language support: Kumyk [къумукъ] (kum).
+* (T187750) New language support: Spanish formal address (es-formal).
+* (T187824) New language support: Hungarian formal address (hu-formal).
+* (T189127) New language support: Gorontalo (gor).
+
+=== Breaking changes in 1.31 ===
+* MessageBlobStore::insertMessageBlob(), deprecated in 1.27, was removed.
+* The OutputPage class constructor now requires a context parameter.
+  Instantiating without context was deprecated in 1.18.
+* The mw.page JavaScript singleton, deprecated in 1.30, was removed.
+* Article::getLastPurgeTimestamp(), WikiPage::getLastPurgeTimestamp(), and the
+  related WikiPage::PURGE_* constants, deprecated in 1.29, were removed.
+* The Article::selectFields(), ::onArticleCreate(), ::onArticleDelete(), and
+  ::onArticleEdit() methods, deprecated in 1.24, were removed.
+* Installer::locateExecutable() and ::locateExecutableInDefaultPaths() were
+  removed. Use ExecutableFinder::findInDefaultPaths() instead.
+* The deprecated MW_DIFF_VERSION constant was removed.
+  DifferenceEngine::MW_DIFF_VERSION should be used instead.
+* Due to significant refactoring, method ContribsPager::getUserCond() that had
+  no access restriction has been removed.
+* The Block class will no longer accept usable-but-missing usernames for
+  'byText' or ->setBlocker(). Callers should either ensure the blocker exists
+  locally or use a new interwiki-format username like "iw>Example".
+* The following methods and constants from the WatchedItem class, which were
+  deprecated in 1.27, have been removed:
+  * WatchedItem::getTitle()
+  * WatchedItem::fromUserTitle()
+  * WatchedItem::addWatch()
+  * WatchedItem::removeWatch()
+  * WatchedItem::isWatched()
+  * WatchedItem::duplicateEntries()
+  * WatchedItem::IGNORE_USER_RIGHTS
+  * WatchedItem::CHECK_USER_RIGHTS
+  * WatchedItem::DEPRECATED_USAGE_TIMESTAMP
+* The $statementsOnOwnLine parameter of JavaScriptMinifier::minify was removed.
+  $wgResourceLoaderMinifierStatementsOnOwnLine, the corresponding configuration
+  variable, has been deprecated since 1.27 and was removed as well.
+* The $maxLineLength parameter of JavaScriptMinifier::minify was removed.
+  $wgResourceLoaderMinifierMaxLineLength, the corresponding configuration
+  variable, has been deprecated since 1.27 and was removed as well.
+* The HtmlFormatter class, deprecated in 1.27, was removed. The namespaced
+  HtmlFormatter\HtmlFormatter class should be used instead.
+* The driver 'mysql' for MySQL, deprecated in MediaWiki 1.30, has been removed.
+  The driver has been deprecated since PHP 5.5 and was removed in PHP 7.0. The
+  default driver for MySQL has been 'mysqli' since MediaWiki 1.22.
+* The following properties of PreparedEdit were deprecated in 1.21 and have
+  been removed:
+  * PreparedEdit->newText
+  * PreparedEdit->oldText
+  * PreparedEdit->pst
+* ParserOutput objects which are generated using a non-default value for
+  ParserOptions::setWrapOutputClass() can no longer be added to the parser
+  cache.
+* The following deprecated methods from the OutputPage class have been removed:
+  * OutputPage::addExtensionStyle(); deprecated in 1.27
+  * OutputPage::getExtStyle(); deprecated in 1.27
+  * OutputPage::setETag(); deprecated in 1.28 (obsolete no-op)
+  * OutputPage::setSquidMaxage(); deprecated in 1.27
+  * OutputPage::readOnlyPage(); deprecated in 1.25
+  * OutputPage::rateLimited(); deprecated in 1.25
+  * Additionally, the protected OutputPage::$mExtStyles array, only accessed
+    through the above and with no known uses, was removed.
+* The no-op method Skin::showIPinHeader(), deprecated in 1.27, was removed.
+* The following variables and methods in EditPage, deprecated in MediaWiki 1.30,
+  were removed:
+  * $isCssJsSubpage — use ::isUserConfigPage()
+  * $isCssSubpage — use ::isUserCssConfigPage()
+  * $isJsSubpage — use ::isUserJsConfigPage()
+  * $isWrongCaseCssJsPage – use ::isWrongCaseUserConfigPage()
+  * ::getSummaryInput() – use ::getSummaryInputWidget()
+  * ::getSummaryInputOOUI() – use ::getSummaryInputWidget()
+  * ::getCheckboxes() – use ::getCheckboxesWidget() or
+      ::getCheckboxesDefinition()
+  * ::getCheckboxesOOUI() – use ::getCheckboxesWidget() or
+      ::getCheckboxesDefinition()
+* ResourceLoaderModule::getPosition(), deprecated in 1.29, has been removed.
+* In User, the cookie-related methods which were wrappers for the functions on
+  the response object, and were deprecated in 1.27, have been removed:
+  * ::setCookie()
+  * ::clearCookie()
+  * ::setExtendedLoginCookie()
+  Note that User::setCookies() remains, and is not deprecated.
+* Also in User, some auth-related methods which were deprecated in 1.27 have
+  been removed:
+  * ::getEditTokenTimestamp() – use MediaWiki\Session\Token::getTimestamp()
+  * ::getPasswordFactory() – create a PasswordFactory directly
+  * ::passwordChangeInputAttribs()
+* The global functions wfProfileIn and wfProfileOut, deprecated in 1.25, have
+  been removed.
+* SpecialPageFactory::getList(), deprecated in 1.24, has been removed. You can
+  use ::getNames() instead.
+* OpenSearch::getOpenSearchTemplate(), deprecated in 1.25, has been removed. You
+  can use ApiOpenSearch::getOpenSearchTemplate() instead.
+* The global function wfBaseConvert, deprecated in 1.27, has been removed. Use
+  Wikimedia\base_convert() directly.
+* Calling Database::begin() explicitly during an implicit transaction or when
+  DBO_TRX is set results in an exception. Calling Database::commit() explicitly
+  for an implicit transaction also results in an exception. Previously these
+  were logged as errors. The startAtomic() and endAtomic() methods, or
+  AtomicSectionUpdate should be used instead.
+* The global function wfOutputHandler() was removed, use the its replacement
+  MediaWiki\OutputHandler::handle() instead. The global function was only
+  sometimes defined. Its replacement is always available via the autoloader.
+* ChangeTags::listExtensionActivatedTags and ::listExtensionDefinedTags,
+  deprecated in 1.28, have been removed. Use ::listSoftwareActivatedTags() and
+  ::listSoftwareDefinedTags() instead.
+* Title::getTitleInvalidRegex(), deprecated in 1.25, has been removed. You can
+  use MediaWikiTitleCodec::getTitleInvalidRegex() instead.
+* HTMLForm & VFormHTMLForm::isVForm(), deprecated in 1.25, have been removed.
+* The ProfileSection class, deprecated in 1.25 and unused, has been removed.
+* The ResourceLoaderGetLessVars hook, deprecated in 1.30, has been removed. Use
+  ResourceLoaderModule::getLessVars() to expose local variables instead of
+  global ones.
+* As part of work to modernise user-generated content clean-up, a config option
+  and some methods related to HTML validity were removed without deprecation.
+  The public methods MWTidy::checkErrors() and the path through which it was
+  called, TidyDriverBase::validate(), are removed, as are the testing methods
+  MediaWikiTestCase::assertValidHtmlSnippet() and ::assertValidHtmlDocument().
+  The $wgValidateAllHtml configuration option is removed and will be ignored.
+* Execution of external programs using MediaWiki\Shell\Command now applies
+  the RESTRICT_DEFAULT Firejail restriction by default.
+* The ResourceLoaderModule::getHashMtime() and ::getDefinitionMtime() methods,
+  deprecated in 1.26, were removed.
+* The deprecated 'mediawiki.widgets.CategorySelector' module alias was removed.
+  Use the 'mediawiki.widgets.CategoryMultiselectWidget' module directly.
+
+=== Deprecations in 1.31 ===
+* The Revision class was deprecated in favor of RevisionStore, BlobStore, and
+  RevisionRecord and its subclasses.
+* The global function wfBCP47 is deprecated in favour of LanguageCode::bcp47.
+* The global function wfCountDown is now deprecated in favor of
+  Maintenance::countDown.
+* Several methods for returning lists of fields to select from the database
+  have been deprecated in favor of similar methods that also return the tables
+  to select from and the join conditions for those tables.
+  * Block::selectFields() → Block::getQueryInfo()
+  * RecentChange::selectFields() → RecentChange::getQueryInfo()
+  * ArchivedFile::selectFields() → ArchivedFile::getQueryInfo()
+  * LocalFile::selectFields() → LocalFile::getQueryInfo()
+  * LocalFile::getCacheFields() with a prefix no longer works
+  * LocalFile::getLazyCacheFields() with a prefix no longer works
+  * OldLocalFile::selectFields() → OldLocalFile::getQueryInfo()
+  * RecentChange::selectFields() → RecentChange::getQueryInfo()
+  * Revision::userJoinCond() → Revision::getQueryInfo( [ 'user' ] )
+  * Revision::selectUserFields() → Revision::getQueryInfo( [ 'user' ] )
+  * Revision::pageJoinCond() → Revision::getQueryInfo( [ 'page' ] )
+  * Revision::selectPageFields() → Revision::getQueryInfo( [ 'page' ] )
+  * Revision::selectTextFields() → Revision::getQueryInfo( [ 'text' ] )
+  * Revision::selectFields() → Revision::getQueryInfo()
+  * Revision::selectArchiveFields() → Revision::getArchiveQueryInfo()
+  * User::selectFields() → User::getQueryInfo()
+  * WikiPage::selectFields() → WikiPage::getQueryInfo()
+* Revision::setUserIdAndName() was deprecated.
+* Access to TitleValue class properties was deprecated, the relevant getters
+  should be used instead.
+* DifferenceEngine::getDiffBodyCacheKey() is deprecated. Subclasses should
+  override DifferenceEngine::getDiffBodyCacheKeyParams() instead.
+* Use of Maintenance::error( $err, $die ) to exit script was deprecated. Use
+  Maintenance::fatalError() instead.
+* 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.
+* The following methods that get and set ParserOutput state are deprecated.
+  Callers should use the new stateless $options parameter to
+  ParserOutput::getText() instead.
+  * ParserOptions::getEditSection()
+  * ParserOptions::setEditSection()
+  * ParserOutput::getEditSectionTokens()
+  * ParserOutput::setEditSectionTokens()
+  * ParserOutput::getTOCEnabled()
+  * ParserOutput::setTOCEnabled()
+  * OutputPage::enableSectionEditLinks()
+  * OutputPage::sectionEditLinksEnabled()
+  * The public ParserOutput state fields $mTOCEnabled and $mEditSectionTokens
+    are also deprecated.
+* License::getLicenses has been deprecated; use License::getLines instead.
+* QuickTemplate::setRef() was deprecated in favour of QuickTemplate::set().
+  Setting template variables by reference allowed violating the principle of
+  data being immutable once added to the skin template. In practice, this method
+  was not being used for that. Rather, setRef() existed as memory optimisation
+  for PHP 4.
+* QuickTemplate::setTranslator() and MediaWikiI18N::set() were deprecated in
+  favour of Skin::msg() parameters.
+* MediaWikiI18N::translate() was deprecated in favour of Skin::msg() or
+  wfMessage().
+* Passing false to ParserOptions::setWrapOutputClass() is deprecated. Use the
+  'unwrap' transform to ParserOutput::getText() instead.
+* \ObjectFactory (no namespace) is deprecated, the namespaced class
+  \Wikimedia\ObjectFactory from the wikimedia/object-factory library should be
+  used instead.
+* CommentStore::newKey is deprecated. Instead, get an instance from
+  MediaWikiServices.
+* The following CommentStore methods have had their signatures changed to
+  introduce a $key parameter, usage of the methods on instances retrieved from
+  CommentStore::newKey will remain unchanged but deprecated:
+  * CommentStore::getFields
+  * CommentStore::getJoin
+  * CommentStore::getComment
+  * CommentStore::getCommentLegacy
+  * CommentStore::insert
+  * CommentStore::insertWithTemplate
+* The following methods in Title have been renamed, and the old ones are
+  deprecated:
+  * Title::getSkinFromCssJsSubpage – use ::getSkinFromConfigSubpage
+  * Title::isCssOrJsPage – use ::isSiteConfigPage
+  * Title::isCssJsSubpage – use ::isUserConfigPage
+  * Title::isCssSubpage – use ::isUserCssConfigPage
+  * Title::isJsSubpage – use ::isUserJsConfigPage
+* The following methods related to caching of half-parsed HTML were deprecated:
+  * Parser::serializeHalfParsedText()
+  * Parser::unserializeHalfParsedText()
+  * Parser::isValidHalfParsedText()
+  * StripState::getSubState()
+  * StripState::merge()
+* The DeferredStringifier class is deprecated, use Message::listParam() instead.
+* The type string for the parameter $lang of DateFormatter::getInstance is
+  deprecated.
+* Wikimedia\Rdbms\SavepointPostgres is deprecated.
+* The DO_MAINTENANCE constant is deprecated. RUN_MAINTENANCE_IF_MAIN should be
+  used instead.
+* The function wfShellWikiCmd() has been deprecated, use
+  MediaWiki\Shell::makeScriptCommand().
+* In the future, the hooks 'PreferencesFormPreSave' and 'PreferencesGetLegend'
+  will be allowed to provide any HTMLForm object rather than PreferencesForm.
+
+=== Other changes in 1.31 ===
+* Browser support for Internet Explorer 10 was lowered from Grade A to Grade C.
+* Browser support for Opera 12 and older was dropped entirely. Opera 15+
+  continues at Grade A.
+* Multi-content-revision capability was introduced into the storage layer. See
+  <https://mediawiki.org/wiki/Requests_for_comment/Multi-Content_Revisions>.
+* The "free" CSS class is now only applied to unbracketed URLs in wikitext.
+  Links written using square brackets will get the class "text" not "free".
+* RFC 157418: Whitespace is trimmed from wikitext headings, wikitext list items,
+  wikitext table captions, wikitext table headings, wikitext table cells. HTML
+  headings, HTML list items, HTML table captions, HTML table headings, HTML
+  table cells will not have this trimming behavior.
+
+== Compatibility ==
+MediaWiki 1.31 requires PHP 7.0.0 or later. Although HHVM 3.18.5 or later is
+supported, it is generally advised to use PHP 7.0.0 or later for long term
+support.
+
+MySQL/MariaDB is the recommended DBMS. PostgreSQL or SQLite can also be used,
+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.3.7 or later
+* Oracle 9.0.1 or later
+* Microsoft SQL Server 2005 (9.00.1399)
+
+== Upgrading ==
+1.31 has several database changes since 1.30, 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.30.x and older releases, see HISTORY.
+
+== Online documentation ==
+Documentation for both end-users and site administrators is available on
+MediaWiki.org, and is covered under the GNU Free Documentation License (except
+for pages that explicitly state that their contents are in the public domain):
+
+       https://www.mediawiki.org/wiki/Special:MyLanguage/Documentation
+
+== Mailing list ==
+A mailing list is available for MediaWiki user support and discussion:
+
+       https://lists.wikimedia.org/mailman/listinfo/mediawiki-l
+
+A low-traffic announcements-only list is also available:
+
+       https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce
+
+It's highly recommended that you sign up for one of these lists if you're
+going to run a public MediaWiki, so you can be notified of security fixes.
+
+== IRC help ==
+There's usually someone online in #mediawiki on irc.freenode.net.
+
 
 = MediaWiki 1.30 =
 
diff --git a/INSTALL b/INSTALL
index 3b93505..d68342c 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -6,7 +6,7 @@ Starting with MediaWiki 1.2.0, it's possible to install and configure the wiki
 "in-place", as long as you have the necessary prerequisites available.
 
 Required software:
-* Web server with PHP 5.5.9 or higher.
+* Web server with PHP 7.0.0 or HHVM 3.18.5 or higher.
 * A SQL server, the following types are supported
 ** MySQL 5.5.8 or higher
 ** PostgreSQL 9.2 or higher
@@ -17,9 +17,6 @@ Required software:
 MediaWiki is developed and tested mainly on Unix/Linux platforms, but should
 work on Windows as well.
 
-If your PHP is configured as a CGI plug-in rather than an Apache module you may
-experience problems, as this configuration is not well tested.
-
 Support for rendering mathematical formulas requires installing the Math extension,
 see https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:Math
 
@@ -56,7 +53,7 @@ ie. /wiki/index.php/Article.
   |  will appear. It is common in this case to use w as the folder name and  |
   |  /wiki/ as the virtual article path where your articles pretend to be.   |
   |                                                                          |
-  |    See: https://www.mediawiki.org/wiki/Manual:Short_URL                  |
+  |  See: https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Short_URL |
   +--------------------------------------------------------------------------+
 
 Hop into your browser and surf into the wiki directory. It'll direct you into
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..ad9b9d9
--- /dev/null
+++ b/README
@@ -0,0 +1,33 @@
+== MediaWiki ==
+
+MediaWiki is a free and open-source wiki software package written in PHP. It
+serves as the platform for Wikipedia and the other Wikimedia projects, used
+by hundreds of millions of people each month. MediaWiki is localised in over
+350 languages and its reliability and robust feature set have earned it a large
+and vibrant community of third-party users and developers.
+
+MediaWiki is:
+
+* feature-rich and extensible, both on-wiki and with hundreds of extensions;
+* scalable and suitable for both small and large sites;
+* simple to install, working on most hardware/software combinations; and
+* available in your language.
+
+For system requirements, installation, and upgrade details, see the files
+RELEASE-NOTES, INSTALL, and UPGRADE.
+
+* Ready to get started?
+** https://www.mediawiki.org/wiki/Special:MyLanguage/Download
+* Looking for the technical manual?
+** https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Contents
+* Seeking help from a person?
+** https://www.mediawiki.org/wiki/Special:MyLanguage/Communication
+* Looking to file a bug report or a feature request?
+** https://bugs.mediawiki.org/
+* Interested in helping out?
+** https://www.mediawiki.org/wiki/Special:MyLanguage/How_to_contribute
+
+MediaWiki is the result of global collaboration and cooperation. The CREDITS
+file lists technical contributors to the project. The COPYING file explains
+MediaWiki's copyright and license (GNU General Public License, version 2 or
+later). Many thanks to the Wikimedia community for testing and suggestions.
diff --git a/README.md b/README.md
deleted file mode 100644 (file)
index ca703db..0000000
--- a/README.md
+++ /dev/null
@@ -1,34 +0,0 @@
-MediaWiki
-===========
-
-MediaWiki is a free and open-source wiki software package written in PHP. It
-serves as the platform for Wikipedia and the other Wikimedia projects, used
-by hundreds of millions of people each month. MediaWiki is localised in over
-350 languages and its reliability and robust feature set have earned it a large
-and vibrant community of third-party users and developers.
-
-MediaWiki is:
-
-* feature-rich and extensible, both on-wiki and with hundreds of extensions;
-* scalable and suitable for both small and large sites;
-* simple to install, working on most hardware/software combinations; and
-* available in your language.
-
-For system requirements, installation, and upgrade details, see the files
-RELEASE-NOTES, INSTALL, and UPGRADE.
-
-* Ready to get started?
-** https://www.mediawiki.org/wiki/Special:MyLanguage/Download
-* Looking for the technical manual?
-** https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Contents
-* Seeking help from a person?
-** https://www.mediawiki.org/wiki/Special:MyLanguage/Communication
-* Looking to file a bug report or a feature request?
-** https://bugs.mediawiki.org/
-* Interested in helping out?
-** https://www.mediawiki.org/wiki/Special:MyLanguage/How_to_contribute
-
-MediaWiki is the result of global collaboration and cooperation. The CREDITS
-file lists technical contributors to the project. The COPYING file explains
-MediaWiki's copyright and license (GNU General Public License, version 2 or
-later). Many thanks to the Wikimedia community for testing and suggestions.
diff --git a/README.mediawiki b/README.mediawiki
new file mode 120000 (symlink)
index 0000000..100b938
--- /dev/null
@@ -0,0 +1 @@
+README
\ No newline at end of file
diff --git a/RELEASE-NOTES-1.31 b/RELEASE-NOTES-1.31
deleted file mode 100644 (file)
index 740535a..0000000
+++ /dev/null
@@ -1,449 +0,0 @@
-== MediaWiki 1.31 ==
-
-THIS IS NOT A RELEASE YET
-
-MediaWiki 1.31 is an alpha-quality branch and is not recommended for use in
-production.
-
-=== Configuration changes in 1.31 ===
-* $wgEnableAPI and $wgEnableWriteAPI are now deprecated and will be removed in
-  a future version. The API is now considered to be stable, secure and
-  essential.
-* $wgUsejQueryThree was removed, as it is now the default. This was documented
-  as a temporary variable during the migration period, deprecated since 1.29.
-* $wgLogoHD has been updated to support svg images and uses $wgLogo where
-  possible for fallback images such as png.
-* (T44246) $wgFilterLogTypes will no longer ignore 'patrol' when user does not
-  have the right to mark things patrolled.
-* Wikis that contain imported revisions or CentralAuth global blocks should run
-  maintenance/cleanupUsersWithNoId.php.
-* The configuration settings $wgResourceLoaderMinifierStatementsOnOwnLine and
-  $wgResourceLoaderMinifierMaxLineLength, deprecated since 1.27, were removed.
-* (T180921) $wgReferrerPolicy now supports having fallbacks for browsers that
-  are not using the latest version of the Referrer Policy specification.
-* $wgFragmentMode is now set to [ 'legacy', 'html5' ] by default. This is a
-  first step of migration to human-readable section IDs that will later result
-  in 'html5' being the default mode.
-* CACHE_ACCEL now only supports APC(u) or WinCache. XCache support was removed
-  as upstream is inactive and has no plans to move to PHP 7.
-* The old CategorizedRecentChanges feature, including its related configuration
-  option $wgAllowCategorizedRecentChanges, has been removed.
-* (T188472) The 'comma' value for $wgArticleCountMethod is no longer supported
-  for performance reasons, and installations with this setting will now work as
-  if it was configured with 'any'.
-* (T185753) MediaWiki now defaults to using RemexHtml to tidy up user input,
-  rather than being off by default. If you wish to disable HTML tidying
-  entirely, set $wgTidyConfig to null; if you wish to use the old, deprecated
-  Tidy external binary, both set $wgTidyConfig to null and $wgUseTidy to true.
-* $wgLogAutopatrol now defaults to false instead of true.
-* $wgValidateAllHtml was removed and will be ignored.
-* $wgScriptExtension, deprecated and ignored since 1.25, was removed. See the
-  1.25 release notes for more information.
-* $wgUseAjax is now marked as deprecated, just like the deprecated AJAX
-  framework that it enables. Some extensions mistakenly used this to check
-  whether any AJAX functionality at all should be enabled, further making this
-  problematic to retain.
-
-=== New features in 1.31 ===
-* (T76554) User sub-pages named ….json are now protected in the same way that
-  ….js and ….css pages are, so that configuration options can safely be placed
-  there.
-* Wikimedia\Rdbms\IDatabase->select() and similar methods now support joins
-  with parentheses for grouping.
-* As a first pass in standardizing dialog boxes across the MediaWiki product,
-  Html class now provides helper methods for messageBox, successBox, errorBox
-  and warningBox generation.
-* (T9240) Imports will now record unknown (and, optionally, known) usernames in
-  a format like "iw>Example".
-* (T20209) Linker (used on history pages, log pages, and so on) will display
-  usernames formed like "iw>Example" as interwiki links, as if by wikitext like
-  [[iw:User:Example|iw>Example]].
-* (T111605) The 'ImportHandleUnknownUser' hook allows extensions to auto-create
-  users during an import.
-* Added a hook, ParserOutputPostCacheTransform, to allow extensions to affect
-  the ParserOutput::getText() post-cache transformations.
-* Added a hook, UploadForm:getInitialPageText, to allow extensions to alter the
-  initial page text for file uploads.
-* (T181651) The info page for File pages now displays the file's base-16 SHA1
-  hash value in the table of basic information.
-* Style tags with a 'data-mw-deduplicate' attribute will be deduplicated as a
-  ParserOutput::getText() post-cache transformation. This may be disabled by
-  passing 'deduplicateStyles' => false to that method.
-* The identity of the logged-in or IP "actor" for logged actions is being moved
-  into a new actor table, with the rows in tables such as revision and logging
-  referring to the actor ID instead of storing the user ID and name/IP in
-  every row.
-  * This is currently gated by $wgActorTableSchemaMigrationStage. Most wikis
-    can set this to MIGRATION_NEW and run maintenance/migrateActors.php as
-    soon as any necessary extensions are updated.
-  * Most code accessing rows for logged actions from the database should use
-    the relevant getQueryInfo() methods to get the information needed to build
-    the SQL query. The ActorMigration class may also be used to get feature
-    -flagged information needed to access actor-related fields during the
-    migration period.
-* Added Wikimedia\Rdbms\IDatabase::cancelAtomic(), to roll back an atomic
-  section without having to roll back the whole transaction.
-* Wikimedia\Rdbms\IDatabase::doAtomicSection(), non-native ::insertSelect(),
-  and non-MySQL ::replace() and ::upsert() no longer roll back the whole
-  transaction on failure.
-* (T189785) Added a monthly heartbeat ping to the pingback feature.
-* The CLI installer (maintenance/install.php) learned to detect and include
-  extensions. Pass --with-extensions to enable that feature.
-* (T184791) rc_patrolled now has three states: "0" for unpatrolled,
-  "1" for manually patrolled and "2" for autopatrolled actions.
-* Extensions can now set their type to "editor" if they provide an editor or
-  enhance the editing experience.
-* Extensions can use a PSR-4 autoloader by setting an "AutoloadNamespaces"
-  property in extension.json. See the documentation at
-  <https://mediawiki.org/wiki/Manual:Extension.json/Schema#AutoloadNamespaces>
-  for more details and an example.
-* (T19099) Tabs which link to pages that don't exist (like those to uncreated
-  discussion pages) now have a tooltip to indicate state, not just colour.
-
-=== External library changes in 1.31 ===
-* pear/mail, pear/mail_mime and pear/mail_mime-decode have been moved from
-  suggested to required. These packages now must be installed via composer
-  and not via PEAR itself.
-
-==== Upgraded external libraries ====
-* Updated jquery.chosen from v0.9.14 to v1.8.2.
-* Updated composer/spdx-licenses from 1.1.4 to 1.3.0 (development dependency).
-* Updated nikic/php-parser from 2.1.0 to 3.1.3 (development dependency).
-* Updated wikimedia/ip-set from 1.1.0 to 1.2.0.
-* Updated wikimedia/relpath from 2.0.0 to 2.1.1.
-* Updated wikimedia/running-stat from 1.1.0 to 1.2.0.
-* Updated wikimedia/wrappedstring from 2.2.0 to 2.3.0.
-* Updated mediawiki/at-ease from 1.1.0 to 1.2.0.
-* Updated wikimedia/php-session-serializer from 1.0.4 to 1.0.6.
-* Updated wikimedia/remex-html from 1.0.2 to 1.0.3.
-* Updated wikimedia/html-formatter from 1.0.1 to 1.0.2.
-
-==== New external libraries ====
-* Added wikimedia/object-factory 1.0.0
-
-==== Removed and replaced external libraries ====
-* (T17845) The deprecated 'jquery.badge' module was removed.
-* The deprecated 'jquery.autoEllipsis' module was removed. Use the CSS
-  text-overflow property instead.
-* The deprecated 'jquery.placeholder' module was removed.
-* The deprecated 'jquery.appear' module was removed. Use the
-  'mediawiki.viewport' module instead.
-* mediawiki/at-ease was replaced with wikimedia/at-ease.
-
-=== Bug fixes in 1.31 ===
-* (T90902) Non-breaking space in header ID breaks anchor.
-* (T189375) CSSMin now allows quoted urls in `url()` syntax to start with a
-  space.
-* (T2087, T10897, T87753, T174639) Whitespace created by category and language
-  links is now stripped rather than leaving blank lines in odd places.
-* (T3780) Uploads with UTF-8 names now work on PHP7.1+ on Windows servers.
-
-=== Action API changes in 1.31 ===
-* (T185058) The 'name' value to tgprop for action=query&list=tags has been
-  removed. It has never made a difference in the output, the name was always
-  returned regardless.
-* The 'watch' and 'unwatch' parameters for action=move have been removed. They
-  were deprecated and also accidentally nonfunctional since 1.17 in 2010. Use
-  'watchlist' instead.
-
-=== Action API internal changes in 1.31 ===
-* ApiBase::getProfileDBTime, deprecated since 1.25, was removed.
-* ApiBase::getModuleProfileName, deprecated since 1.25, was removed.
-* ApiBase::getProfileTime, deprecated since 1.25, was removed.
-
-=== Languages updated in 1.31 ===
-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.
-
-* (T180052) Mirandese (mwl) now supports gendered NS_USER/NS_USER_TALK.
-* (T182305) New language support: Nyungar (nys).
-* (T186359) New language support: Siberian Tatar [cебертатар] (sty).
-* (T186635) New language support: Guianan Creole (gcr).
-* (T186647) New language support: Kumyk [къумукъ] (kum).
-* (T187750) New language support: Spanish formal address (es-formal).
-* (T187824) New language support: Hungarian formal address (hu-formal).
-* (T189127) New language support: Gorontalo (gor).
-
-=== Breaking changes in 1.31 ===
-* MessageBlobStore::insertMessageBlob(), deprecated in 1.27, was removed.
-* The OutputPage class constructor now requires a context parameter.
-  Instantiating without context was deprecated in 1.18.
-* The mw.page JavaScript singleton, deprecated in 1.30, was removed.
-* Article::getLastPurgeTimestamp(), WikiPage::getLastPurgeTimestamp(), and the
-  related WikiPage::PURGE_* constants, deprecated in 1.29, were removed.
-* The Article::selectFields(), ::onArticleCreate(), ::onArticleDelete(), and
-  ::onArticleEdit() methods, deprecated in 1.24, were removed.
-* Installer::locateExecutable() and ::locateExecutableInDefaultPaths() were
-  removed. Use ExecutableFinder::findInDefaultPaths() instead.
-* The deprecated MW_DIFF_VERSION constant was removed.
-  DifferenceEngine::MW_DIFF_VERSION should be used instead.
-* Due to significant refactoring, method ContribsPager::getUserCond() that had
-  no access restriction has been removed.
-* The Block class will no longer accept usable-but-missing usernames for
-  'byText' or ->setBlocker(). Callers should either ensure the blocker exists
-  locally or use a new interwiki-format username like "iw>Example".
-* The following methods and constants from the WatchedItem class, which were
-  deprecated in 1.27, have been removed:
-  * WatchedItem::getTitle()
-  * WatchedItem::fromUserTitle()
-  * WatchedItem::addWatch()
-  * WatchedItem::removeWatch()
-  * WatchedItem::isWatched()
-  * WatchedItem::duplicateEntries()
-  * WatchedItem::IGNORE_USER_RIGHTS
-  * WatchedItem::CHECK_USER_RIGHTS
-  * WatchedItem::DEPRECATED_USAGE_TIMESTAMP
-* The $statementsOnOwnLine parameter of JavaScriptMinifier::minify was removed.
-  $wgResourceLoaderMinifierStatementsOnOwnLine, the corresponding configuration
-  variable, has been deprecated since 1.27 and was removed as well.
-* The $maxLineLength parameter of JavaScriptMinifier::minify was removed.
-  $wgResourceLoaderMinifierMaxLineLength, the corresponding configuration
-  variable, has been deprecated since 1.27 and was removed as well.
-* The HtmlFormatter class, deprecated in 1.27, was removed. The namespaced
-  HtmlFormatter\HtmlFormatter class should be used instead.
-* The driver 'mysql' for MySQL, deprecated in MediaWiki 1.30, has been removed.
-  The driver has been deprecated since PHP 5.5 and was removed in PHP 7.0. The
-  default driver for MySQL has been 'mysqli' since MediaWiki 1.22.
-* The following properties of PreparedEdit were deprecated in 1.21 and have
-  been removed:
-  * PreparedEdit->newText
-  * PreparedEdit->oldText
-  * PreparedEdit->pst
-* ParserOutput objects which are generated using a non-default value for
-  ParserOptions::setWrapOutputClass() can no longer be added to the parser
-  cache.
-* The following deprecated methods from the OutputPage class have been removed:
-  * OutputPage::addExtensionStyle(); deprecated in 1.27
-  * OutputPage::getExtStyle(); deprecated in 1.27
-  * OutputPage::setETag(); deprecated in 1.28 (obsolete no-op)
-  * OutputPage::setSquidMaxage(); deprecated in 1.27
-  * OutputPage::readOnlyPage(); deprecated in 1.25
-  * OutputPage::rateLimited(); deprecated in 1.25
-  * Additionally, the protected OutputPage::$mExtStyles array, only accessed
-    through the above and with no known uses, was removed.
-* The no-op method Skin::showIPinHeader(), deprecated in 1.27, was removed.
-* The following variables and methods in EditPage, deprecated in MediaWiki 1.30,
-  were removed:
-  * $isCssJsSubpage — use ::isUserConfigPage()
-  * $isCssSubpage — use ::isUserCssConfigPage()
-  * $isJsSubpage — use ::isUserJsConfigPage()
-  * $isWrongCaseCssJsPage – use ::isWrongCaseUserConfigPage()
-  * ::getSummaryInput() – use ::getSummaryInputWidget()
-  * ::getSummaryInputOOUI() – use ::getSummaryInputWidget()
-  * ::getCheckboxes() – use ::getCheckboxesWidget() or
-      ::getCheckboxesDefinition()
-  * ::getCheckboxesOOUI() – use ::getCheckboxesWidget() or
-      ::getCheckboxesDefinition()
-* ResourceLoaderModule::getPosition(), deprecated in 1.29, has been removed.
-* In User, the cookie-related methods which were wrappers for the functions on
-  the response object, and were deprecated in 1.27, have been removed:
-  * ::setCookie()
-  * ::clearCookie()
-  * ::setExtendedLoginCookie()
-  Note that User::setCookies() remains, and is not deprecated.
-* Also in User, some auth-related methods which were deprecated in 1.27 have
-  been removed:
-  * ::getEditTokenTimestamp() – use MediaWiki\Session\Token::getTimestamp()
-  * ::getPasswordFactory() – create a PasswordFactory directly
-  * ::passwordChangeInputAttribs()
-* The global functions wfProfileIn and wfProfileOut, deprecated in 1.25, have
-  been removed.
-* SpecialPageFactory::getList(), deprecated in 1.24, has been removed. You can
-  use ::getNames() instead.
-* OpenSearch::getOpenSearchTemplate(), deprecated in 1.25, has been removed. You
-  can use ApiOpenSearch::getOpenSearchTemplate() instead.
-* The global function wfBaseConvert, deprecated in 1.27, has been removed. Use
-  Wikimedia\base_convert() directly.
-* Calling Database::begin() explicitly during an implicit transaction or when
-  DBO_TRX is set results in an exception. Calling Database::commit() explicitly
-  for an implicit transaction also results in an exception. Previously these
-  were logged as errors. The startAtomic() and endAtomic() methods, or
-  AtomicSectionUpdate should be used instead.
-* The global function wfOutputHandler() was removed, use the its replacement
-  MediaWiki\OutputHandler::handle() instead. The global function was only
-  sometimes defined. Its replacement is always available via the autoloader.
-* ChangeTags::listExtensionActivatedTags and ::listExtensionDefinedTags,
-  deprecated in 1.28, have been removed. Use ::listSoftwareActivatedTags() and
-  ::listSoftwareDefinedTags() instead.
-* Title::getTitleInvalidRegex(), deprecated in 1.25, has been removed. You can
-  use MediaWikiTitleCodec::getTitleInvalidRegex() instead.
-* HTMLForm & VFormHTMLForm::isVForm(), deprecated in 1.25, have been removed.
-* The ProfileSection class, deprecated in 1.25 and unused, has been removed.
-* The ResourceLoaderGetLessVars hook, deprecated in 1.30, has been removed. Use
-  ResourceLoaderModule::getLessVars() to expose local variables instead of
-  global ones.
-* As part of work to modernise user-generated content clean-up, a config option
-  and some methods related to HTML validity were removed without deprecation.
-  The public methods MWTidy::checkErrors() and the path through which it was
-  called, TidyDriverBase::validate(), are removed, as are the testing methods
-  MediaWikiTestCase::assertValidHtmlSnippet() and ::assertValidHtmlDocument().
-  The $wgValidateAllHtml configuration option is removed and will be ignored.
-* Execution of external programs using MediaWiki\Shell\Command now applies
-  the RESTRICT_DEFAULT Firejail restriction by default.
-* The ResourceLoaderModule::getHashMtime() and ::getDefinitionMtime() methods,
-  deprecated in 1.26, were removed.
-* The deprecated 'mediawiki.widgets.CategorySelector' module alias was removed.
-  Use the 'mediawiki.widgets.CategoryMultiselectWidget' module directly.
-
-=== Deprecations in 1.31 ===
-* The Revision class was deprecated in favor of RevisionStore, BlobStore, and
-  RevisionRecord and its subclasses.
-* The global function wfBCP47 is deprecated in favour of LanguageCode::bcp47.
-* The global function wfCountDown is now deprecated in favor of
-  Maintenance::countDown.
-* Several methods for returning lists of fields to select from the database
-  have been deprecated in favor of similar methods that also return the tables
-  to select from and the join conditions for those tables.
-  * Block::selectFields() → Block::getQueryInfo()
-  * RecentChange::selectFields() → RecentChange::getQueryInfo()
-  * ArchivedFile::selectFields() → ArchivedFile::getQueryInfo()
-  * LocalFile::selectFields() → LocalFile::getQueryInfo()
-  * LocalFile::getCacheFields() with a prefix no longer works
-  * LocalFile::getLazyCacheFields() with a prefix no longer works
-  * OldLocalFile::selectFields() → OldLocalFile::getQueryInfo()
-  * RecentChange::selectFields() → RecentChange::getQueryInfo()
-  * Revision::userJoinCond() → Revision::getQueryInfo( [ 'user' ] )
-  * Revision::selectUserFields() → Revision::getQueryInfo( [ 'user' ] )
-  * Revision::pageJoinCond() → Revision::getQueryInfo( [ 'page' ] )
-  * Revision::selectPageFields() → Revision::getQueryInfo( [ 'page' ] )
-  * Revision::selectTextFields() → Revision::getQueryInfo( [ 'text' ] )
-  * Revision::selectFields() → Revision::getQueryInfo()
-  * Revision::selectArchiveFields() → Revision::getArchiveQueryInfo()
-  * User::selectFields() → User::getQueryInfo()
-  * WikiPage::selectFields() → WikiPage::getQueryInfo()
-* Revision::setUserIdAndName() was deprecated.
-* Access to TitleValue class properties was deprecated, the relevant getters
-  should be used instead.
-* DifferenceEngine::getDiffBodyCacheKey() is deprecated. Subclasses should
-  override DifferenceEngine::getDiffBodyCacheKeyParams() instead.
-* Use of Maintenance::error( $err, $die ) to exit script was deprecated. Use
-  Maintenance::fatalError() instead.
-* 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.
-* The following methods that get and set ParserOutput state are deprecated.
-  Callers should use the new stateless $options parameter to
-  ParserOutput::getText() instead.
-  * ParserOptions::getEditSection()
-  * ParserOptions::setEditSection()
-  * ParserOutput::getEditSectionTokens()
-  * ParserOutput::setEditSectionTokens()
-  * ParserOutput::getTOCEnabled()
-  * ParserOutput::setTOCEnabled()
-  * OutputPage::enableSectionEditLinks()
-  * OutputPage::sectionEditLinksEnabled()
-  * The public ParserOutput state fields $mTOCEnabled and $mEditSectionTokens
-    are also deprecated.
-* License::getLicenses has been deprecated; use License::getLines instead.
-* QuickTemplate::setRef() was deprecated in favour of QuickTemplate::set().
-  Setting template variables by reference allowed violating the principle of
-  data being immutable once added to the skin template. In practice, this method
-  was not being used for that. Rather, setRef() existed as memory optimisation
-  for PHP 4.
-* QuickTemplate::setTranslator() and MediaWikiI18N::set() were deprecated in
-  favour of Skin::msg() parameters.
-* MediaWikiI18N::translate() was deprecated in favour of Skin::msg() or
-  wfMessage().
-* Passing false to ParserOptions::setWrapOutputClass() is deprecated. Use the
-  'unwrap' transform to ParserOutput::getText() instead.
-* \ObjectFactory (no namespace) is deprecated, the namespaced class
-  \Wikimedia\ObjectFactory from the wikimedia/object-factory library should be
-  used instead.
-* CommentStore::newKey is deprecated. Instead, get an instance from
-  MediaWikiServices.
-* The following CommentStore methods have had their signatures changed to
-  introduce a $key parameter, usage of the methods on instances retrieved from
-  CommentStore::newKey will remain unchanged but deprecated:
-  * CommentStore::getFields
-  * CommentStore::getJoin
-  * CommentStore::getComment
-  * CommentStore::getCommentLegacy
-  * CommentStore::insert
-  * CommentStore::insertWithTemplate
-* The following methods in Title have been renamed, and the old ones are
-  deprecated:
-  * Title::getSkinFromCssJsSubpage – use ::getSkinFromConfigSubpage
-  * Title::isCssOrJsPage – use ::isSiteConfigPage
-  * Title::isCssJsSubpage – use ::isUserConfigPage
-  * Title::isCssSubpage – use ::isUserCssConfigPage
-  * Title::isJsSubpage – use ::isUserJsConfigPage
-* The following methods related to caching of half-parsed HTML were deprecated:
-  * Parser::serializeHalfParsedText()
-  * Parser::unserializeHalfParsedText()
-  * Parser::isValidHalfParsedText()
-  * StripState::getSubState()
-  * StripState::merge()
-* The DeferredStringifier class is deprecated, use Message::listParam() instead.
-* The type string for the parameter $lang of DateFormatter::getInstance is
-  deprecated.
-* Wikimedia\Rdbms\SavepointPostgres is deprecated.
-* The DO_MAINTENANCE constant is deprecated. RUN_MAINTENANCE_IF_MAIN should be
-  used instead.
-* The function wfShellWikiCmd() has been deprecated, use
-  MediaWiki\Shell::makeScriptCommand().
-=== Other changes in 1.31 ===
-* Browser support for Internet Explorer 10 was lowered from Grade A to Grade C.
-* Browser support for Opera 12 and older was dropped entirely. Opera 15+
-  continues at Grade A.
-* Multi-content-revision capability was introduced into the storage layer. See
-  <https://mediawiki.org/wiki/Requests_for_comment/Multi-Content_Revisions>.
-* The "free" CSS class is now only applied to unbracketed URLs in wikitext.
-  Links written using square brackets will get the class "text" not "free".
-* RFC 157418: Whitespace is trimmed from wikitext headings, wikitext list items,
-  wikitext table captions, wikitext table headings, wikitext table cells. HTML
-  headings, HTML list items, HTML table captions, HTML table headings, HTML
-  table cells will not have this trimming behavior.
-
-== Compatibility ==
-MediaWiki 1.31 requires PHP 7.0.0 or later. Although HHVM 3.18.5 or later is
-supported, it is generally advised to use PHP 7.0.0 or later for long term
-support.
-
-MySQL/MariaDB is the recommended DBMS. PostgreSQL or SQLite can also be used,
-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.3.7 or later
-* Oracle 9.0.1 or later
-* Microsoft SQL Server 2005 (9.00.1399)
-
-== Upgrading ==
-1.31 has several database changes since 1.30, 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.30.x and older releases, see HISTORY.
-
-== Online documentation ==
-Documentation for both end-users and site administrators is available on
-MediaWiki.org, and is covered under the GNU Free Documentation License (except
-for pages that explicitly state that their contents are in the public domain):
-
-       https://www.mediawiki.org/wiki/Special:MyLanguage/Documentation
-
-== Mailing list ==
-A mailing list is available for MediaWiki user support and discussion:
-
-       https://lists.wikimedia.org/mailman/listinfo/mediawiki-l
-
-A low-traffic announcements-only list is also available:
-
-       https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce
-
-It's highly recommended that you sign up for one of these lists if you're
-going to run a public MediaWiki, so you can be notified of security fixes.
-
-== IRC help ==
-There's usually someone online in #mediawiki on irc.freenode.net.
index fa7c962..95459b2 100644 (file)
@@ -10,6 +10,7 @@ production.
   have been removed.
 * The $wgUseAjax setting, deprecated in 1.31, is now ignored.
 * The $wgSiteSupportPage setting, unused since 1.5, was removed.
+* The $wgBrowserBlacklist setting, deprecated in 1.30, was removed.
 * The default quality of JPEG thumbnails generated by GD was reduced from 95 to
   80. The quality of JPEG thumbnails is now configurable through the new setting
   $wgJpegQuality (default 80). This aligns the quality to what ImageMagick uses.
@@ -21,28 +22,74 @@ production.
   adds a defense-in-depth feature to stop an attacker who has found a bug in
   the parser allowing them to insert malicious attributes. Disabled by default,
   you can configure this via $wgCSPHeader and $wgCSPReportOnlyHeader.
+* New configuration variable has been added: $wgCookieSetOnIpBlock.
+  This determines whether to set a cookie when an IP user is blocked. Doing so
+  means that a blocked user, even after moving to a new IP address, will still
+  be blocked.
+* The archive table's ar_rev_id field is now unique.
+* Special:BotPasswords now requires reauthentication.
+* (T194414) The default watchlist view time has been increased from 3 to 7 days.
+* The right to edit sitewide Javascript (e.g. MediaWiki:Common.js), CSS or JSON
+  was separated from 'editinterface' and is available under
+  'editsitejs'/'editsitecss'/'editsitejson'. Having 'editinterface' is still
+  necessary to edit such pages.
+* A new user group, 'interface-admin', is added for controlling access to
+  sitewide CSS/JS (and editing other users' CSS/JS). No other group has
+  'editsitecss', 'editusercss', 'editsitejs' or 'edituserjs' by default.
+* A new grant group, 'editsiteconfig', is added for granting the above rights.
 
 === New features in 1.32 ===
 * (T112474) Generalized the ResourceLoader mechanism for overriding modules
   using a particular page during edit previews.
+* (T12331) You can now log page creation events by setting $wgPageCreationLog
+  to true.
 * Added 'ApiParseMakeOutputPage' hook.
-* (T174313) Added checkbox on Special:ListUsers to display only users in temporary
-  user groups.
+* (T174313) Added checkbox on Special:ListUsers to display only users in
+  temporary user groups.
+* (T152462) A cookie can now be set when an IP user is blocked to track that
+  user if they move to a new IP address. This is disabled by default.
+* (T194950) Added 'ApiMaxLagInfo' hook.
+* SpecialPage::checkLoginSecurityLevel() will now preserve POST data when
+  reauthenticating.
+* FormSpecialPage::execute() will now call checkLoginSecurityLevel() if
+  getLoginSecurityLevel() returns non-false.
+* The 'ImageBeforeProduceHTML' hook is now passed three new parameters, $parser,
+  &$query and &$widthOption, allowing extensions even finer control over the
+  resulting HTML code.
+* Added new 'ArticleShowPatrolFooter' hook, which allows extensions to determine
+  if the [mark as patrolled] link should be shown at the footer of patrollable
+  pages.
+* The array of hidden options ($opts) passed to the 'SpecialSearchPowerBox' hook
+  is now passed by reference, allowing extensions to modify or even unset it.
+* Added new 'OutputPageAfterGetHeadLinksArray' hook, allowing extensions to
+  modify the return value of OutputPage#getHeadLinksArray in order to add,
+  remove or otherwise alter the elements to be output in the page <head>.
+* (T28934) The 'HistoryPageToolLinks' hook allows extensions to append
+  additional links to the subtitle of a history page.
+* The 'GetLinkColours' hook now receives an additional $title parameter,
+  the Title object of the page being parsed, on which the links will be shown.
 
 === External library changes in 1.32 ===
 * …
 
 ==== Upgraded external libraries ====
 * Updated QUnit from 2.4.0 to 2.6.0.
+* Updated wikimedia/scoped-callback from 1.0.0 to 2.0.0.
+** ScopedCallback objects can no longer be serialized.
+* Updated wikimedia/wrappedstring from 2.3.0 to 3.0.1.
+* Updated mediawiki/mediawiki-codesniffer from v20.0.0 to v21.0.0.
+* Updated composer/spdx-licenses from 1.3.0 to 1.4.0.
 
 ==== New external libraries ====
+* Added wikimedia/xmp-reader 0.5.1
 * …
 
 ==== Removed and replaced external libraries ====
 * …
 
 === Bug fixes in 1.32 ===
-* …
+* SpecialPage::execute() will now only call checkLoginSecurityLevel() if
+  getLoginSecurityLevel() returns non-false.
 
 === Action API changes in 1.32 ===
 * Added templated parameters.
@@ -56,11 +103,41 @@ production.
     templated parameters.
 * It is now an error to submit too many values for a multi-valued parameter.
   This has generated a warning since MediaWiki 1.14.
+* Assertion failures from the 'assert' and 'assertuser' parameters will no
+  longer use the action module's custom response format, for the few modules
+  that use custom formatters that handle errors.
+* (T198935) User list preferences such as `email-blacklist` and similar
+  extension preferences are no longer represented as arrays when returned by
+  action=query&meta=userinfo&uiprop=options.
+* 'missingparam' errors will now use the prefixed parameter name in the code
+  and error text, e.g. "noxxfoo" and "The 'xxfoo' parameter must be set" rather
+  than "nofoo" and "The 'foo' parameter must be set".
+* action=query&prop=revisions now takes a 'rvslots' parameter to indicate the
+  multi-content revision slots for which content should be returned. It also
+  has a new rvprop, 'roles', to indicate which roles have slots. A deprecation
+  warning will be issued if rvprop=content or rvprop=contentmodel are used
+  without rvslots.
+* The rvcontentformat parameter to action=query&prop=revisions has been
+  deprecated. Clients should be prepared to deal with the default format for
+  relevant models.
+* Use of the deprecated parameters rvexpandtemplates, rvgeneratexml, rvparse,
+  rvdiffto, rvdifftotext, rvdifftotextpst, rvcontentformat, or the deprecated
+  rvprop=parsetree is forbidden with the new 'rvslots' parameter.
+* action=query&prop=deletedrevisions, action=query&list=allrevisions, and
+  action=query&list=alldeletedrevisions are changed similarly to
+  &prop=revisions (see the three previous items).
 
 === Action API internal changes in 1.32 ===
 * Added 'ApiParseMakeOutputPage' hook.
 * Parameter names may no longer contain '{' or '}', as these are now used for
   templated parameters.
+* (T194950) Added 'ApiMaxLagInfo' hook.
+* Added 'ApiParseMakeOutputPage' hook.
+* The following methods now take a RevisionRecord rather than a Revision. No
+  external callers are known.
+  * ApiFeedContributions::feedItemAuthor()
+  * ApiFeedContributions::feedItemDesc()
+  * ApiQueryRevisionsBase::extractRevisionInfo()
 
 === Languages updated in 1.32 ===
 MediaWiki supports over 350 languages. Many localisations are updated regularly.
@@ -69,6 +146,9 @@ because of Phabricator reports.
 
 * (T193566) Added language support for Ambonese Malay (abs).
 * (T194047) Added language support for Shawiya, Latin script (shy-latn).
+* (T195940) Added language support for Batak Mandailing (btm).
+* (T137491) Added language support for Standard Moroccan Amazigh (zgh).
+* (T198132) Added language support for Manipuri (mni).
 
 === Breaking changes in 1.32 ===
 * $wgRequestTime, deprecated in 1.25, was removed. Use
@@ -97,16 +177,68 @@ because of Phabricator reports.
 * mw.util.updateTooltipAccessKeys(), deprecated in 1.24, was removed. Use
   jquery.accessKeyLabel instead.
 * The SqlDataUpdate class, deprecated in 1.28, has been removed.
-* The Html5Internal and Html5Depurate tidy driver classes were removed, along with the
-  Balancer tidy implementation. Both implementations were experimental, and were replaced
-  by RemexHtml.
+* The Html5Internal and Html5Depurate tidy driver classes were removed, along
+  with the Balancer tidy implementation. Both implementations were experimental,
+  and were replaced by RemexHtml.
 * (T179624) Job::insert() and ::batchInsert(), deprecated in 1.21, were both
   removed. Use JobQueueGroup::singleton()->push() instead.
 * The jquery.footHovzer module, for mediawiki.debug, was removed.
 * The es5-shim module, empty and deprecated since 1.29, was removed.
-* The mediawiki.widgets.visibleByteLimit module, deprecated in 1.32, was removed.
-  Use mediawiki.widgets.visibleLengthLimit instead.
+* the dom-level2-shim module, empty and deprecated since 1.29, was removed.
+* the json module, empty and deprecated since 1.29, was removed.
+* The mediawiki.widgets.visibleByteLimit module alias, deprecated in 1.32, was
+  removed. Use mediawiki.widgets.visibleLengthLimit instead.
 * The jquery.farbtastic module, unused since 1.18, was removed.
+* (T181318) The $wgStyleVersion setting and its appendage to various script and
+  style URLs in OutputPage, deprecated in 1.31, was removed.
+* The hooks 'PreferencesFormPreSave' and 'PreferencesGetLegend' may provide
+  any HTMLForm object rather than PreferencesForm.
+* The non namespaced TimestampException class, deprecated in 1.29, was removed.
+  Use Wikimedia\Timestamp\TimestampException instead.
+* The global functions codepointToUtf8, hexSequenceToUtf8, utf8ToHexSequence,
+  utf8ToCodepoint, and escapeSingleString (deprecated in 1.25) were removed.
+  The UtfNormal\Utils class from the utfnormal library should be used instead.
+* The deprecated UTF8_ and UNICODE_ constants were removed. The class constants
+  from the UtfNormal\Constants class from the utfnormal library should be used
+* (T140807) The wgResourceLoaderLESSImportPaths configuration option was removed
+  from ResourceLoader. Instead, use `@import` statements in LESS to import
+  files directly from nearby directories within the same project.
+* The protected methods PHPSessionHandler::returnSuccess() and returnFailure(),
+  only needed for PHP5 compatibility, have been removed. It now uses the boolean
+  values `true` and `false` respectively.
+* The $parserMemc global and wfGetParserCacheStorage(), deprecated since 1.30,
+  were removed. Use the ParserCache class instead.
+* ScopedCallback (deprecated in 1.28) was removed. Use Wikimedia\ScopedCallback
+  instead.
+* Support for ResourceLoaderModule::getModifiedTime() and getModifiedHash(),
+  deprecated since 1.26, was removed. Use getDefinitionSummary() instead.
+* (T195256) Skins are recommended not to rely on JavaScript for the "mw-jump"
+  and "jump-to-nav" accessibility links. To this end, the "jquery.mw-jump"
+  is no longer loaded by default. The Vector and MonoBook skins have made a
+  minor change to implement the toggle feature with CSS instead. To restore
+  prior functionality, either explicitly load "jquery.mw-jump" in your skin
+  or refer to T195256 for details on how to make the same change.
+* Hook 'EditPageBeforeEditChecks' was removed;
+  use 'EditPageGetCheckboxesDefinition' instead.
+* Linker::getLinkColour() and DummyLinker::getLinkColour(), deprecated since
+  1.28, were removed. LinkRenderer::getLinkClasses() should be used instead.
+* Wikimedia\Rdbms\LoadBalancer::getLaggedSlaveMode(), deprecated in 1.28, has
+  been removed. Use Wikimedia\Rdbms\LoadBalancer::getLaggedReplicaMode()
+  instead.
+* mw.widgets.CategoryMultiselectWidget now uses TagMultiselectWidget instead of
+  CapsuleMultiselectWidget. The following methods may no longer be used:
+  * setItemsFromData: Use setValue instead
+  * getItemsData: Use getItems instead and get the data property
+* Two OutputPage methods, addMetadataLink() and getMetadataAttribute(), were
+  removed.  Use addLink() instead.
+* Another two OutputPage methods, setPageTitleActionText() and
+  getPageTitleActionText(), were removed.  They did nothing since 1.15 (almost
+  ten years).  Use setHTMLTitle() directly.
+* All MagicWord static member variables have been removed.  Use appropriate
+  hooks or MagicWordFactory methods instead.
+* MagicWord::clearCache() has been removed.  Instead, create a new
+  MagicWordFactory, such as by calling
+  resetServiceForTesting( 'MagicWordFactory' ) on a MediaWikiServices.
 
 === Deprecations in 1.32 ===
 * Use of a StartProfiler.php file is deprecated in favour of placing
@@ -129,17 +261,91 @@ because of Phabricator reports.
   mediawiki.api.messages, and mediawiki.api.rollback.
 * ApiBase::truncateArray() is deprecated. No replacement, as nothing is known
   to use it.
+* WatchAction::getUnwatchToken is deprecated. Use WatchAction::getWatchToken
+  with the 'unwatch' action parameter instead.
+* IcuCollation::getICUVersion() is deprecated, as you can just use the PHP
+  constant INTL_ICU_VERSION directly in all versions that MediaWiki supports.
+* Parser::fetchFile() is deprecated. Use ::fetchFileAndTitle() instead.
+* The ApiQueryContributions class has been renamed to ApiQueryUserContribs.
+* The XMPInfo, XMPReader, and XMPValidate classes have been deprecated in favor
+  of the namespaced classes provided by the wikimedia/xmp-reader library.
+* SearchResultSet::{next,rewind} are deprecated. Calling code should
+  use foreach on the SearchResultSet, or the extractResults method. Extending
+  code should override extractResults.
+* Instantiating SearchResultSet directly is deprecated. SearchEngine
+  implementations must subclass SearchResultSet for their purposes.
+* 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.
+* Parser::getConverterLanguage() is deprecated.  Use ::getTargetLanguage()
+  instead.
+* Language::markNoConversion() is deprecated.  It confused readers because
+  it had unexpected behavior (only marking text if it looked like a URL)
+  and was only used in a single place in the code.  Use
+  LanguageConverter::markNoConversion() instead.
+* (T197492) Language::truncate() was soft deprecated in 1.31 and is
+  hard deprecated in this release.  It has been split into two similar
+  methods, Language::truncateForVisual() and Language::truncateForDatabase(),
+  which measure length in characters and bytes, respectively.  Use
+  Language::truncateForVisual() when possible to provide equity to users
+  of multibyte scripts.
+* (T176526) EditPage::getContextTitle() falling back to $wgTitle when the
+  context title is unset is now deprecated; anything creating an EditPage
+  instance should set the context title via ::setContextTitle().
+* The 'jquery.hidpi' module (polyfill for IMG srcset) is deprecated.
+* ResourceLoaderStartUpModule::getStartupModules() and ::getLegacyModules()
+  are deprecated. These concepts are obsolete and have no replacement.
+* String type for $lang of DifferenceEngine::setTextLanguage is deprecated.
+* The following methods of OutputPage are now deprecated in favour
+  of using showFatalError directly: OutputPage::showFileDeleteError()
+  OutputPage::showFileNotFoundError(), OutputPage::showFileRenameError()
+  OutputPage::showFileCopyError() and OutputPage::showUnexpectedValueError().
+* The Replacer, DoubleReplacer, HashtableReplacer, and RegexlikeReplacer
+  classes are now deprecated. Use a Closure instead.
+* (T194263) ContentHandler::makeParserOptions() is deprecated. Use
+  WikiPage::makeParserOptions() or ParserOptions::newCanonical() instead.
+* (T100681) Use of the Parsoid v1 API with the VirtualRESTService, deprecated in
+  MediaWiki 1.26,  is now hard-deprecated. All known clients were converted to
+  the Parsoid v3 API in May 2015.
+* $input is deprecated in hook 'LogEventsListGetExtraInputs'. Use
+  $formDescriptor instead.
+* SearchEngine::transformSearchTerm( $term ) should no longer be called prior
+  to running searchText. This method was mainly implemented to support the
+  'prefix' URI param in SpecialSearch, but there are no reasons to expose this
+  logic as it should be handled internally by SearchEngine implementations
+  supporting this feature. SearchEngine implementations should no longer
+  override this methods.
+* SearchEngine::replacePrefixes( $query ) should no longer be called prior
+  to running searchText/searchTitle.
+* (T199657) Messages for $wgFilterLogTypes labels should be no longer be in the
+  'log-show-hide-[type]' format. Instead use 'logeventslist-[type]-log'.
+* Global functions  wfArrayFilter() and wfArrayFilterByKey() are deprecated.
+  use array_filter() directly.
+* The $wgShowSQLErrors global is deprecated and nonfunctional.
+  Set $wgShowExceptionDetails and/or $wgShowHostnames instead.
+* The $wgShowDBErrorBacktrace global is deprecated and nonfunctional.
+  Set $wgShowExceptionDetails instead.
+* Public access to the DifferenceEngine properties mOldid, mNewid, mOldPage,
+  mNewPage, mOldContent, mNewContent, mRevisionsLoaded, mTextLoaded and
+  mCacheHit is deprecated. Use getOldid() / getNewid() for the first two,
+  do your own lookup for page/content. mNewRev / mOldRev remains public.
+* The $wgExternalDiffEngine value 'wikidiff2' is deprecated. To use wikidiff2
+  just enable the PHP extension, and it will be autodetected.
+* The wfUseMW function, soft-deprecated in 1.26, is now hard deprecated.
+* All MagicWord static methods are now deprecated.  Use the MagicWordFactory
+  methods instead.
 
 === Other changes in 1.32 ===
-* Soft hyphens (U+00AD) are now automatically removed from titles; these
-  characters can accidentally end up in copy-and-pasted titles.
-* Strip Unicode 6.3.0 directional formatting characters (U+061C, U+2066,
-  U+2067, U+2068, U+2069) from the title.
+* (T198811) The following tables have had their UNIQUE indexes turned into
+  proper PRIMARY KEYs for increased maintainability: interwiki, page_props,
+  protected_titles and site_identifiers.
 * …
 
 == Compatibility ==
-MediaWiki 1.32 requires PHP 5.5.9 or later. Although HHVM 3.18.5 or later is
-supported, it is generally advised to use PHP 5.5.9 or later for long term
+MediaWiki 1.32 requires PHP 7.0.0 or later. Although HHVM 3.18.5 or later is
+supported, it is generally advised to use PHP 7.0.0 or later for long term
 support.
 
 MySQL/MariaDB is the recommended DBMS. PostgreSQL or SQLite can also be used,
index 40ded45..b5b5c52 100644 (file)
@@ -12,7 +12,7 @@ $wgAutoloadLocalClasses = [
        'ActiveUsersPager' => __DIR__ . '/includes/specials/pagers/ActiveUsersPager.php',
        'ActivityUpdateJob' => __DIR__ . '/includes/jobqueue/jobs/ActivityUpdateJob.php',
        'ActorMigration' => __DIR__ . '/includes/ActorMigration.php',
-       'AddRFCAndPMIDInterwiki' => __DIR__ . '/maintenance/addRFCandPMIDInterwiki.php',
+       'AddRFCandPMIDInterwiki' => __DIR__ . '/maintenance/addRFCandPMIDInterwiki.php',
        'AddSite' => __DIR__ . '/maintenance/addSite.php',
        'AjaxDispatcher' => __DIR__ . '/includes/AjaxDispatcher.php',
        'AjaxResponse' => __DIR__ . '/includes/AjaxResponse.php',
@@ -64,7 +64,7 @@ $wgAutoloadLocalClasses = [
        'ApiManageTags' => __DIR__ . '/includes/api/ApiManageTags.php',
        'ApiMergeHistory' => __DIR__ . '/includes/api/ApiMergeHistory.php',
        'ApiMessage' => __DIR__ . '/includes/api/ApiMessage.php',
-       'ApiMessageTrait' => __DIR__ . '/includes/api/ApiMessage.php',
+       'ApiMessageTrait' => __DIR__ . '/includes/api/ApiMessageTrait.php',
        'ApiModuleManager' => __DIR__ . '/includes/api/ApiModuleManager.php',
        'ApiMove' => __DIR__ . '/includes/api/ApiMove.php',
        'ApiOpenSearch' => __DIR__ . '/includes/api/ApiOpenSearch.php',
@@ -93,7 +93,7 @@ $wgAutoloadLocalClasses = [
        'ApiQueryCategories' => __DIR__ . '/includes/api/ApiQueryCategories.php',
        'ApiQueryCategoryInfo' => __DIR__ . '/includes/api/ApiQueryCategoryInfo.php',
        'ApiQueryCategoryMembers' => __DIR__ . '/includes/api/ApiQueryCategoryMembers.php',
-       'ApiQueryContributions' => __DIR__ . '/includes/api/ApiQueryUserContributions.php',
+       'ApiQueryContributions' => __DIR__ . '/includes/api/ApiQueryUserContribs.php',
        'ApiQueryContributors' => __DIR__ . '/includes/api/ApiQueryContributors.php',
        'ApiQueryDeletedRevisions' => __DIR__ . '/includes/api/ApiQueryDeletedRevisions.php',
        'ApiQueryDeletedrevs' => __DIR__ . '/includes/api/ApiQueryDeletedrevs.php',
@@ -129,11 +129,12 @@ $wgAutoloadLocalClasses = [
        'ApiQueryStashImageInfo' => __DIR__ . '/includes/api/ApiQueryStashImageInfo.php',
        'ApiQueryTags' => __DIR__ . '/includes/api/ApiQueryTags.php',
        'ApiQueryTokens' => __DIR__ . '/includes/api/ApiQueryTokens.php',
+       'ApiQueryUserContribs' => __DIR__ . '/includes/api/ApiQueryUserContribs.php',
        'ApiQueryUserInfo' => __DIR__ . '/includes/api/ApiQueryUserInfo.php',
        'ApiQueryUsers' => __DIR__ . '/includes/api/ApiQueryUsers.php',
        'ApiQueryWatchlist' => __DIR__ . '/includes/api/ApiQueryWatchlist.php',
        'ApiQueryWatchlistRaw' => __DIR__ . '/includes/api/ApiQueryWatchlistRaw.php',
-       'ApiRawMessage' => __DIR__ . '/includes/api/ApiMessage.php',
+       'ApiRawMessage' => __DIR__ . '/includes/api/ApiRawMessage.php',
        'ApiRemoveAuthenticationData' => __DIR__ . '/includes/api/ApiRemoveAuthenticationData.php',
        'ApiResetPassword' => __DIR__ . '/includes/api/ApiResetPassword.php',
        'ApiResult' => __DIR__ . '/includes/api/ApiResult.php',
@@ -183,7 +184,6 @@ $wgAutoloadLocalClasses = [
        'BatchRowIterator' => __DIR__ . '/includes/utils/BatchRowIterator.php',
        'BatchRowUpdate' => __DIR__ . '/includes/utils/BatchRowUpdate.php',
        'BatchRowWriter' => __DIR__ . '/includes/utils/BatchRowWriter.php',
-       'BatchedQueryRunner' => __DIR__ . '/maintenance/runBatchedQuery.php',
        'BcryptPassword' => __DIR__ . '/includes/password/BcryptPassword.php',
        'BenchHttpHttps' => __DIR__ . '/maintenance/benchmarks/bench_HTTP_HTTPS.php',
        'BenchIfSwitch' => __DIR__ . '/maintenance/benchmarks/bench_if_switch.php',
@@ -222,7 +222,6 @@ $wgAutoloadLocalClasses = [
        'CachedBagOStuff' => __DIR__ . '/includes/libs/objectcache/CachedBagOStuff.php',
        'CachingSiteStore' => __DIR__ . '/includes/site/CachingSiteStore.php',
        'CannotCreateActorException' => __DIR__ . '/includes/exception/CannotCreateActorException.php',
-       'CapsCleanup' => __DIR__ . '/maintenance/cleanupCaps.php',
        'CategoriesRdf' => __DIR__ . '/includes/CategoriesRdf.php',
        'Category' => __DIR__ . '/includes/Category.php',
        'CategoryChangesAsRdf' => __DIR__ . '/maintenance/categoryChangesAsRdf.php',
@@ -264,12 +263,16 @@ $wgAutoloadLocalClasses = [
        'ClassCollector' => __DIR__ . '/includes/utils/AutoloadGenerator.php',
        'CleanupAncientTables' => __DIR__ . '/maintenance/cleanupAncientTables.php',
        'CleanupBlocks' => __DIR__ . '/maintenance/cleanupBlocks.php',
+       'CleanupCaps' => __DIR__ . '/maintenance/cleanupCaps.php',
        'CleanupEmptyCategories' => __DIR__ . '/maintenance/cleanupEmptyCategories.php',
+       'CleanupImages' => __DIR__ . '/maintenance/cleanupImages.php',
        'CleanupInvalidDbKeys' => __DIR__ . '/maintenance/cleanupInvalidDbKeys.php',
        'CleanupPreferences' => __DIR__ . '/maintenance/cleanupPreferences.php',
        'CleanupRemovedModules' => __DIR__ . '/maintenance/cleanupRemovedModules.php',
        'CleanupSpam' => __DIR__ . '/maintenance/cleanupSpam.php',
+       'CleanupUploadStash' => __DIR__ . '/maintenance/cleanupUploadStash.php',
        'CleanupUsersWithNoId' => __DIR__ . '/maintenance/cleanupUsersWithNoId.php',
+       'CleanupWatchlist' => __DIR__ . '/maintenance/cleanupWatchlist.php',
        'ClearInterwikiCache' => __DIR__ . '/maintenance/clearInterwikiCache.php',
        'ClearUserWatchlistJob' => __DIR__ . '/includes/jobqueue/jobs/ClearUserWatchlistJob.php',
        'ClearWatchlistNotificationsJob' => __DIR__ . '/includes/jobqueue/jobs/ClearWatchlistNotificationsJob.php',
@@ -318,6 +321,7 @@ $wgAutoloadLocalClasses = [
        'CoreParserFunctions' => __DIR__ . '/includes/parser/CoreParserFunctions.php',
        'CoreTagHooks' => __DIR__ . '/includes/parser/CoreTagHooks.php',
        'CreateAndPromote' => __DIR__ . '/maintenance/createAndPromote.php',
+       'CreateCommonPasswordCdb' => __DIR__ . '/maintenance/createCommonPasswordCdb.php',
        'CreateFileOp' => __DIR__ . '/includes/libs/filebackend/fileop/CreateFileOp.php',
        'CreditsAction' => __DIR__ . '/includes/actions/CreditsAction.php',
        'CrhConverter' => __DIR__ . '/languages/classes/LanguageCrh.php',
@@ -383,6 +387,7 @@ $wgAutoloadLocalClasses = [
        'DependencyWrapper' => __DIR__ . '/includes/cache/CacheDependency.php',
        'DeprecatedGlobal' => __DIR__ . '/includes/DeprecatedGlobal.php',
        'DeprecatedInterfaceFinder' => __DIR__ . '/maintenance/findDeprecated.php',
+       'DeprecationHelper' => __DIR__ . '/includes/debug/DeprecationHelper.php',
        'DerivativeContext' => __DIR__ . '/includes/context/DerivativeContext.php',
        'DerivativeRequest' => __DIR__ . '/includes/DerivativeRequest.php',
        'DerivativeResourceLoaderContext' => __DIR__ . '/includes/resourceloader/DerivativeResourceLoaderContext.php',
@@ -427,7 +432,9 @@ $wgAutoloadLocalClasses = [
        'DumpRenderer' => __DIR__ . '/maintenance/renderDump.php',
        'DumpRev' => __DIR__ . '/maintenance/storage/dumpRev.php',
        'DumpStringOutput' => __DIR__ . '/includes/export/DumpStringOutput.php',
+       'DumpUploads' => __DIR__ . '/maintenance/dumpUploads.php',
        'DuplicateJob' => __DIR__ . '/includes/jobqueue/jobs/DuplicateJob.php',
+       'EasyDeflate' => __DIR__ . '/includes/libs/EasyDeflate.php',
        'EditAction' => __DIR__ . '/includes/actions/EditAction.php',
        'EditCLI' => __DIR__ . '/maintenance/edit.php',
        'EditPage' => __DIR__ . '/includes/EditPage.php',
@@ -512,6 +519,7 @@ $wgAutoloadLocalClasses = [
        'FileJournal' => __DIR__ . '/includes/libs/filebackend/filejournal/FileJournal.php',
        'FileOp' => __DIR__ . '/includes/libs/filebackend/fileop/FileOp.php',
        'FileOpBatch' => __DIR__ . '/includes/libs/filebackend/FileOpBatch.php',
+       'FileOpPerfTest' => __DIR__ . '/maintenance/fileOpPerfTest.php',
        'FileRepo' => __DIR__ . '/includes/filerepo/FileRepo.php',
        'FileRepoStatus' => __DIR__ . '/includes/filerepo/FileRepoStatus.php',
        'FindDeprecated' => __DIR__ . '/maintenance/findDeprecated.php',
@@ -535,6 +543,7 @@ $wgAutoloadLocalClasses = [
        'FormAction' => __DIR__ . '/includes/actions/FormAction.php',
        'FormOptions' => __DIR__ . '/includes/FormOptions.php',
        'FormSpecialPage' => __DIR__ . '/includes/specialpage/FormSpecialPage.php',
+       'FormatInstallDoc' => __DIR__ . '/maintenance/formatInstallDoc.php',
        'FormatJson' => __DIR__ . '/includes/json/FormatJson.php',
        'FormatMetadata' => __DIR__ . '/includes/media/FormatMetadata.php',
        'FormattedRCFeed' => __DIR__ . '/includes/rcfeed/FormattedRCFeed.php',
@@ -544,7 +553,6 @@ $wgAutoloadLocalClasses = [
        'GanConverter' => __DIR__ . '/languages/classes/LanguageGan.php',
        'GenderCache' => __DIR__ . '/includes/cache/GenderCache.php',
        'GenerateCollationData' => __DIR__ . '/maintenance/language/generateCollationData.php',
-       'GenerateCommonPassword' => __DIR__ . '/maintenance/createCommonPasswordCdb.php',
        'GenerateJsonI18n' => __DIR__ . '/maintenance/generateJsonI18n.php',
        'GenerateNormalizerDataAr' => __DIR__ . '/maintenance/language/generateNormalizerDataAr.php',
        'GenerateNormalizerDataMl' => __DIR__ . '/maintenance/language/generateNormalizerDataMl.php',
@@ -552,7 +560,7 @@ $wgAutoloadLocalClasses = [
        'GenericArrayObject' => __DIR__ . '/includes/libs/GenericArrayObject.php',
        'GetConfiguration' => __DIR__ . '/maintenance/getConfiguration.php',
        'GetLagTimes' => __DIR__ . '/maintenance/getLagTimes.php',
-       'GetSlaveServer' => __DIR__ . '/maintenance/getReplicaServer.php',
+       'GetReplicaServer' => __DIR__ . '/maintenance/getReplicaServer.php',
        'GetTextMaint' => __DIR__ . '/maintenance/getText.php',
        'GitInfo' => __DIR__ . '/includes/GitInfo.php',
        'GlobalDependency' => __DIR__ . '/includes/cache/CacheDependency.php',
@@ -619,7 +627,7 @@ $wgAutoloadLocalClasses = [
        'Http' => __DIR__ . '/includes/http/Http.php',
        'HttpError' => __DIR__ . '/includes/exception/HttpError.php',
        'HttpStatus' => __DIR__ . '/includes/libs/HttpStatus.php',
-       'IApiMessage' => __DIR__ . '/includes/api/ApiMessage.php',
+       'IApiMessage' => __DIR__ . '/includes/api/IApiMessage.php',
        'IBufferingStatsdDataFactory' => __DIR__ . '/includes/libs/stats/IBufferingStatsdDataFactory.php',
        'ICacheHelper' => __DIR__ . '/includes/cache/CacheHelper.php',
        'IContextSource' => __DIR__ . '/includes/context/IContextSource.php',
@@ -637,7 +645,6 @@ $wgAutoloadLocalClasses = [
        'IcuCollation' => __DIR__ . '/includes/collation/IcuCollation.php',
        'IdentityCollation' => __DIR__ . '/includes/collation/IdentityCollation.php',
        'ImageBuilder' => __DIR__ . '/maintenance/rebuildImages.php',
-       'ImageCleanup' => __DIR__ . '/maintenance/cleanupImages.php',
        'ImageGalleryBase' => __DIR__ . '/includes/gallery/ImageGalleryBase.php',
        'ImageHandler' => __DIR__ . '/includes/media/ImageHandler.php',
        'ImageHistoryList' => __DIR__ . '/includes/page/ImageHistoryList.php',
@@ -698,7 +705,6 @@ $wgAutoloadLocalClasses = [
        'JobQueueMemory' => __DIR__ . '/includes/jobqueue/JobQueueMemory.php',
        'JobQueueReadOnlyError' => __DIR__ . '/includes/jobqueue/JobQueue.php',
        'JobQueueRedis' => __DIR__ . '/includes/jobqueue/JobQueueRedis.php',
-       'JobQueueSecondTestQueue' => __DIR__ . '/includes/jobqueue/JobQueueSecondTestQueue.php',
        'JobRunner' => __DIR__ . '/includes/jobqueue/JobRunner.php',
        'JobSpecification' => __DIR__ . '/includes/jobqueue/JobSpecification.php',
        'JpegHandler' => __DIR__ . '/includes/media/JpegHandler.php',
@@ -826,11 +832,11 @@ $wgAutoloadLocalClasses = [
        'MachineReadableRCFeedFormatter' => __DIR__ . '/includes/rcfeed/MachineReadableRCFeedFormatter.php',
        'MagicWord' => __DIR__ . '/includes/MagicWord.php',
        'MagicWordArray' => __DIR__ . '/includes/MagicWordArray.php',
+       'MagicWordFactory' => __DIR__ . '/includes/MagicWordFactory.php',
        'MailAddress' => __DIR__ . '/includes/mail/MailAddress.php',
        'MainConfigDependency' => __DIR__ . '/includes/cache/CacheDependency.php',
        'MaintainableDBConnRef' => __DIR__ . '/includes/libs/rdbms/database/MaintainableDBConnRef.php',
        'Maintenance' => __DIR__ . '/maintenance/Maintenance.php',
-       'MaintenanceFormatInstallDoc' => __DIR__ . '/maintenance/formatInstallDoc.php',
        'MakeTestEdits' => __DIR__ . '/maintenance/makeTestEdits.php',
        'MalformedTitleException' => __DIR__ . '/includes/title/MalformedTitleException.php',
        'ManageJobs' => __DIR__ . '/maintenance/manageJobs.php',
@@ -885,16 +891,16 @@ $wgAutoloadLocalClasses = [
        'MediaWiki\\Auth\\Throttler' => __DIR__ . '/includes/auth/Throttler.php',
        'MediaWiki\\Auth\\UserDataAuthenticationRequest' => __DIR__ . '/includes/auth/UserDataAuthenticationRequest.php',
        'MediaWiki\\Auth\\UsernameAuthenticationRequest' => __DIR__ . '/includes/auth/UsernameAuthenticationRequest.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',
        'MediaWiki\\Diff\\WordAccumulator' => __DIR__ . '/includes/diff/WordAccumulator.php',
-       'MediaWiki\\EditPage\\TextConflictHelper' => __DIR__ . '/includes/editpage/TextConflictHelper.php',
-       'MediaWiki\\EditPage\\TextboxBuilder' => __DIR__ . '/includes/editpage/TextboxBuilder.php',
-       'MediaWiki\\Edit\\PreparedEdit' => __DIR__ . '/includes/edit/PreparedEdit.php',
        'MediaWiki\\HeaderCallback' => __DIR__ . '/includes/HeaderCallback.php',
        'MediaWiki\\Http\\HttpRequestFactory' => __DIR__ . '/includes/http/HttpRequestFactory.php',
        'MediaWiki\\Interwiki\\ClassicInterwikiLookup' => __DIR__ . '/includes/interwiki/ClassicInterwikiLookup.php',
        'MediaWiki\\Interwiki\\InterwikiLookup' => __DIR__ . '/includes/interwiki/InterwikiLookup.php',
        'MediaWiki\\Interwiki\\InterwikiLookupAdapter' => __DIR__ . '/includes/interwiki/InterwikiLookupAdapter.php',
+       'MediaWiki\\Interwiki\\NullInterwikiLookup' => __DIR__ . '/includes/interwiki/NullInterwikiLookup.php',
        'MediaWiki\\Languages\\Data\\CrhExceptions' => __DIR__ . '/languages/data/CrhExceptions.php',
        'MediaWiki\\Languages\\Data\\Names' => __DIR__ . '/languages/data/Names.php',
        'MediaWiki\\Languages\\Data\\ZhConversion' => __DIR__ . '/languages/data/ZhConversion.php',
@@ -917,72 +923,10 @@ $wgAutoloadLocalClasses = [
        'MediaWiki\\Logger\\Spi' => __DIR__ . '/includes/debug/logger/Spi.php',
        'MediaWiki\\MediaWikiServices' => __DIR__ . '/includes/MediaWikiServices.php',
        'MediaWiki\\OutputHandler' => __DIR__ . '/includes/OutputHandler.php',
-       'MediaWiki\\Preferences\\DefaultPreferencesFactory' => __DIR__ . '/includes/preferences/DefaultPreferencesFactory.php',
-       'MediaWiki\\Preferences\\PreferencesFactory' => __DIR__ . '/includes/preferences/PreferencesFactory.php',
        'MediaWiki\\ProcOpenError' => __DIR__ . '/includes/exception/ProcOpenError.php',
        'MediaWiki\\Search\\ParserOutputSearchDataExtractor' => __DIR__ . '/includes/search/ParserOutputSearchDataExtractor.php',
-       'MediaWiki\\Services\\CannotReplaceActiveServiceException' => __DIR__ . '/includes/services/CannotReplaceActiveServiceException.php',
-       'MediaWiki\\Services\\ContainerDisabledException' => __DIR__ . '/includes/services/ContainerDisabledException.php',
-       'MediaWiki\\Services\\DestructibleService' => __DIR__ . '/includes/services/DestructibleService.php',
-       'MediaWiki\\Services\\NoSuchServiceException' => __DIR__ . '/includes/services/NoSuchServiceException.php',
-       'MediaWiki\\Services\\SalvageableService' => __DIR__ . '/includes/services/SalvageableService.php',
-       'MediaWiki\\Services\\ServiceAlreadyDefinedException' => __DIR__ . '/includes/services/ServiceAlreadyDefinedException.php',
-       'MediaWiki\\Services\\ServiceContainer' => __DIR__ . '/includes/services/ServiceContainer.php',
-       'MediaWiki\\Services\\ServiceDisabledException' => __DIR__ . '/includes/services/ServiceDisabledException.php',
-       'MediaWiki\\Session\\BotPasswordSessionProvider' => __DIR__ . '/includes/session/BotPasswordSessionProvider.php',
-       'MediaWiki\\Session\\CookieSessionProvider' => __DIR__ . '/includes/session/CookieSessionProvider.php',
-       'MediaWiki\\Session\\ImmutableSessionProviderWithCookie' => __DIR__ . '/includes/session/ImmutableSessionProviderWithCookie.php',
-       'MediaWiki\\Session\\MetadataMergeException' => __DIR__ . '/includes/session/MetadataMergeException.php',
-       'MediaWiki\\Session\\PHPSessionHandler' => __DIR__ . '/includes/session/PHPSessionHandler.php',
-       'MediaWiki\\Session\\Session' => __DIR__ . '/includes/session/Session.php',
-       'MediaWiki\\Session\\SessionBackend' => __DIR__ . '/includes/session/SessionBackend.php',
-       'MediaWiki\\Session\\SessionId' => __DIR__ . '/includes/session/SessionId.php',
-       'MediaWiki\\Session\\SessionInfo' => __DIR__ . '/includes/session/SessionInfo.php',
-       'MediaWiki\\Session\\SessionManager' => __DIR__ . '/includes/session/SessionManager.php',
-       'MediaWiki\\Session\\SessionManagerInterface' => __DIR__ . '/includes/session/SessionManagerInterface.php',
-       'MediaWiki\\Session\\SessionProvider' => __DIR__ . '/includes/session/SessionProvider.php',
-       'MediaWiki\\Session\\SessionProviderInterface' => __DIR__ . '/includes/session/SessionProviderInterface.php',
-       'MediaWiki\\Session\\Token' => __DIR__ . '/includes/session/Token.php',
-       'MediaWiki\\Session\\UserInfo' => __DIR__ . '/includes/session/UserInfo.php',
        'MediaWiki\\ShellDisabledError' => __DIR__ . '/includes/exception/ShellDisabledError.php',
-       'MediaWiki\\Shell\\Command' => __DIR__ . '/includes/shell/Command.php',
-       'MediaWiki\\Shell\\CommandFactory' => __DIR__ . '/includes/shell/CommandFactory.php',
-       'MediaWiki\\Shell\\FirejailCommand' => __DIR__ . '/includes/shell/FirejailCommand.php',
-       'MediaWiki\\Shell\\Result' => __DIR__ . '/includes/shell/Result.php',
-       'MediaWiki\\Shell\\Shell' => __DIR__ . '/includes/shell/Shell.php',
        'MediaWiki\\Site\\MediaWikiPageNameNormalizer' => __DIR__ . '/includes/site/MediaWikiPageNameNormalizer.php',
-       'MediaWiki\\Sparql\\SparqlClient' => __DIR__ . '/includes/sparql/SparqlClient.php',
-       'MediaWiki\\Sparql\\SparqlException' => __DIR__ . '/includes/sparql/SparqlException.php',
-       'MediaWiki\\Storage\\BlobAccessException' => __DIR__ . '/includes/Storage/BlobAccessException.php',
-       'MediaWiki\\Storage\\BlobStore' => __DIR__ . '/includes/Storage/BlobStore.php',
-       'MediaWiki\\Storage\\BlobStoreFactory' => __DIR__ . '/includes/Storage/BlobStoreFactory.php',
-       'MediaWiki\\Storage\\IncompleteRevisionException' => __DIR__ . '/includes/Storage/IncompleteRevisionException.php',
-       'MediaWiki\\Storage\\MutableRevisionRecord' => __DIR__ . '/includes/Storage/MutableRevisionRecord.php',
-       'MediaWiki\\Storage\\MutableRevisionSlots' => __DIR__ . '/includes/Storage/MutableRevisionSlots.php',
-       'MediaWiki\\Storage\\NameTableAccessException' => __DIR__ . '/includes/Storage/NameTableAccessException.php',
-       'MediaWiki\\Storage\\NameTableStore' => __DIR__ . '/includes/Storage/NameTableStore.php',
-       'MediaWiki\\Storage\\RevisionAccessException' => __DIR__ . '/includes/Storage/RevisionAccessException.php',
-       'MediaWiki\\Storage\\RevisionArchiveRecord' => __DIR__ . '/includes/Storage/RevisionArchiveRecord.php',
-       'MediaWiki\\Storage\\RevisionFactory' => __DIR__ . '/includes/Storage/RevisionFactory.php',
-       'MediaWiki\\Storage\\RevisionLookup' => __DIR__ . '/includes/Storage/RevisionLookup.php',
-       'MediaWiki\\Storage\\RevisionRecord' => __DIR__ . '/includes/Storage/RevisionRecord.php',
-       'MediaWiki\\Storage\\RevisionSlots' => __DIR__ . '/includes/Storage/RevisionSlots.php',
-       'MediaWiki\\Storage\\RevisionSlotsUpdate' => __DIR__ . '/includes/Storage/RevisionSlotsUpdate.php',
-       'MediaWiki\\Storage\\RevisionStore' => __DIR__ . '/includes/Storage/RevisionStore.php',
-       'MediaWiki\\Storage\\RevisionStoreRecord' => __DIR__ . '/includes/Storage/RevisionStoreRecord.php',
-       'MediaWiki\\Storage\\SlotRecord' => __DIR__ . '/includes/Storage/SlotRecord.php',
-       'MediaWiki\\Storage\\SqlBlobStore' => __DIR__ . '/includes/Storage/SqlBlobStore.php',
-       'MediaWiki\\Storage\\SuppressedDataException' => __DIR__ . '/includes/Storage/SuppressedDataException.php',
-       'MediaWiki\\Tidy\\RaggettBase' => __DIR__ . '/includes/tidy/RaggettBase.php',
-       'MediaWiki\\Tidy\\RaggettExternal' => __DIR__ . '/includes/tidy/RaggettExternal.php',
-       'MediaWiki\\Tidy\\RaggettInternalHHVM' => __DIR__ . '/includes/tidy/RaggettInternalHHVM.php',
-       'MediaWiki\\Tidy\\RaggettInternalPHP' => __DIR__ . '/includes/tidy/RaggettInternalPHP.php',
-       'MediaWiki\\Tidy\\RaggettWrapper' => __DIR__ . '/includes/tidy/RaggettWrapper.php',
-       'MediaWiki\\Tidy\\RemexCompatFormatter' => __DIR__ . '/includes/tidy/RemexCompatFormatter.php',
-       'MediaWiki\\Tidy\\RemexCompatMunger' => __DIR__ . '/includes/tidy/RemexCompatMunger.php',
-       'MediaWiki\\Tidy\\RemexDriver' => __DIR__ . '/includes/tidy/RemexDriver.php',
-       'MediaWiki\\Tidy\\RemexMungerData' => __DIR__ . '/includes/tidy/RemexMungerData.php',
-       'MediaWiki\\Tidy\\TidyDriverBase' => __DIR__ . '/includes/tidy/TidyDriverBase.php',
        'MediaWiki\\User\\UserIdentity' => __DIR__ . '/includes/user/UserIdentity.php',
        'MediaWiki\\User\\UserIdentityValue' => __DIR__ . '/includes/user/UserIdentityValue.php',
        'MediaWiki\\Widget\\ComplexNamespaceInputWidget' => __DIR__ . '/includes/widget/ComplexNamespaceInputWidget.php',
@@ -1055,11 +999,12 @@ $wgAutoloadLocalClasses = [
        'MwSql' => __DIR__ . '/maintenance/sql.php',
        'MySqlLockManager' => __DIR__ . '/includes/filebackend/lockmanager/MySqlLockManager.php',
        'MysqlInstaller' => __DIR__ . '/includes/installer/MysqlInstaller.php',
+       'MysqlMaintenance' => __DIR__ . '/maintenance/mysql.php',
        'MysqlUpdater' => __DIR__ . '/includes/installer/MysqlUpdater.php',
        'NaiveForeignTitleFactory' => __DIR__ . '/includes/title/NaiveForeignTitleFactory.php',
        'NaiveImportTitleFactory' => __DIR__ . '/includes/title/NaiveImportTitleFactory.php',
        'NamespaceAwareForeignTitleFactory' => __DIR__ . '/includes/title/NamespaceAwareForeignTitleFactory.php',
-       'NamespaceConflictChecker' => __DIR__ . '/maintenance/namespaceDupes.php',
+       'NamespaceDupes' => __DIR__ . '/maintenance/namespaceDupes.php',
        'NamespaceImportTitleFactory' => __DIR__ . '/includes/title/NamespaceImportTitleFactory.php',
        'NewFilesPager' => __DIR__ . '/includes/specials/pagers/NewFilesPager.php',
        'NewPagesPager' => __DIR__ . '/includes/specials/pagers/NewPagesPager.php',
@@ -1128,6 +1073,7 @@ $wgAutoloadLocalClasses = [
        'PageProps' => __DIR__ . '/includes/PageProps.php',
        'PageQueryPage' => __DIR__ . '/includes/specialpage/PageQueryPage.php',
        'Pager' => __DIR__ . '/includes/pager/Pager.php',
+       'PaginatingSearchEngine' => __DIR__ . '/includes/search/PaginatingSearchEngine.php',
        'ParameterizedPassword' => __DIR__ . '/includes/password/ParameterizedPassword.php',
        'Parser' => __DIR__ . '/includes/parser/Parser.php',
        'ParserCache' => __DIR__ . '/includes/parser/ParserCache.php',
@@ -1142,7 +1088,6 @@ $wgAutoloadLocalClasses = [
        'PasswordReset' => __DIR__ . '/includes/user/PasswordReset.php',
        'PatchSql' => __DIR__ . '/maintenance/patchSql.php',
        'PathRouter' => __DIR__ . '/includes/PathRouter.php',
-       'PathRouterPatternReplacer' => __DIR__ . '/includes/PathRouter.php',
        'PatrolLog' => __DIR__ . '/includes/logging/PatrolLog.php',
        'PatrolLogFormatter' => __DIR__ . '/includes/logging/PatrolLogFormatter.php',
        'Pbkdf2Password' => __DIR__ . '/includes/password/Pbkdf2Password.php',
@@ -1160,7 +1105,9 @@ $wgAutoloadLocalClasses = [
        'PopulateArchiveRevId' => __DIR__ . '/maintenance/populateArchiveRevId.php',
        'PopulateBacklinkNamespace' => __DIR__ . '/maintenance/populateBacklinkNamespace.php',
        'PopulateCategory' => __DIR__ . '/maintenance/populateCategory.php',
+       'PopulateChangeTagDef' => __DIR__ . '/maintenance/populateChangeTagDef.php',
        'PopulateContentModel' => __DIR__ . '/maintenance/populateContentModel.php',
+       'PopulateContentTables' => __DIR__ . '/maintenance/populateContentTables.php',
        'PopulateExternallinksIndex60' => __DIR__ . '/maintenance/populateExternallinksIndex60.php',
        'PopulateFilearchiveSha1' => __DIR__ . '/maintenance/populateFilearchiveSha1.php',
        'PopulateImageSha1' => __DIR__ . '/maintenance/populateImageSha1.php',
@@ -1177,7 +1124,7 @@ $wgAutoloadLocalClasses = [
        'PostgresInstaller' => __DIR__ . '/includes/installer/PostgresInstaller.php',
        'PostgresUpdater' => __DIR__ . '/includes/installer/PostgresUpdater.php',
        'Preferences' => __DIR__ . '/includes/Preferences.php',
-       'PreferencesForm' => __DIR__ . '/includes/specials/forms/PreferencesForm.php',
+       'PreferencesForm' => __DIR__ . '/includes/specials/forms/PreferencesFormLegacy.php',
        'PreferencesFormLegacy' => __DIR__ . '/includes/specials/forms/PreferencesFormLegacy.php',
        'PreferencesFormOOUI' => __DIR__ . '/includes/specials/forms/PreferencesFormOOUI.php',
        'PrefixSearch' => __DIR__ . '/includes/PrefixSearch.php',
@@ -1267,6 +1214,7 @@ $wgAutoloadLocalClasses = [
        'ReplicatedBagOStuff' => __DIR__ . '/includes/libs/objectcache/ReplicatedBagOStuff.php',
        'RepoGroup' => __DIR__ . '/includes/filerepo/RepoGroup.php',
        'RequestContext' => __DIR__ . '/includes/context/RequestContext.php',
+       'ResetAuthenticationThrottle' => __DIR__ . '/maintenance/resetAuthenticationThrottle.php',
        'ResetUserEmail' => __DIR__ . '/maintenance/resetUserEmail.php',
        'ResetUserTokens' => __DIR__ . '/maintenance/resetUserTokens.php',
        'ResourceFileCache' => __DIR__ . '/includes/cache/ResourceFileCache.php',
@@ -1288,7 +1236,6 @@ $wgAutoloadLocalClasses = [
        'ResourceLoaderOOUIFileModule' => __DIR__ . '/includes/resourceloader/ResourceLoaderOOUIFileModule.php',
        'ResourceLoaderOOUIImageModule' => __DIR__ . '/includes/resourceloader/ResourceLoaderOOUIImageModule.php',
        'ResourceLoaderOOUIModule' => __DIR__ . '/includes/resourceloader/ResourceLoaderOOUIModule.php',
-       'ResourceLoaderRawFileModule' => __DIR__ . '/includes/resourceloader/ResourceLoaderRawFileModule.php',
        'ResourceLoaderSiteModule' => __DIR__ . '/includes/resourceloader/ResourceLoaderSiteModule.php',
        'ResourceLoaderSiteStylesModule' => __DIR__ . '/includes/resourceloader/ResourceLoaderSiteStylesModule.php',
        'ResourceLoaderSkinModule' => __DIR__ . '/includes/resourceloader/ResourceLoaderSkinModule.php',
@@ -1333,12 +1280,12 @@ $wgAutoloadLocalClasses = [
        'RollbackAction' => __DIR__ . '/includes/actions/RollbackAction.php',
        'RollbackEdits' => __DIR__ . '/maintenance/rollbackEdits.php',
        'RowUpdateGenerator' => __DIR__ . '/includes/utils/RowUpdateGenerator.php',
+       'RunBatchedQuery' => __DIR__ . '/maintenance/runBatchedQuery.php',
        'RunJobs' => __DIR__ . '/maintenance/runJobs.php',
        'SVGMetadataExtractor' => __DIR__ . '/includes/media/SVGMetadataExtractor.php',
        'SVGReader' => __DIR__ . '/includes/media/SVGMetadataExtractor.php',
        'SamplingStatsdClient' => __DIR__ . '/includes/libs/stats/SamplingStatsdClient.php',
        'Sanitizer' => __DIR__ . '/includes/parser/Sanitizer.php',
-       'ScopedCallback' => __DIR__ . '/includes/compat/ScopedCallback.php',
        'ScopedLock' => __DIR__ . '/includes/libs/lockmanager/ScopedLock.php',
        'SearchApi' => __DIR__ . '/includes/api/SearchApi.php',
        'SearchDatabase' => __DIR__ . '/includes/search/SearchDatabase.php',
@@ -1520,7 +1467,6 @@ $wgAutoloadLocalClasses = [
        'TempFileRepo' => __DIR__ . '/includes/filerepo/TempFileRepo.php',
        'TemplateParser' => __DIR__ . '/includes/TemplateParser.php',
        'TemplatesOnThisPageFormatter' => __DIR__ . '/includes/TemplatesOnThisPageFormatter.php',
-       'TestFileOpPerformance' => __DIR__ . '/maintenance/fileOpPerfTest.php',
        'TextContent' => __DIR__ . '/includes/content/TextContent.php',
        'TextContentHandler' => __DIR__ . '/includes/content/TextContentHandler.php',
        'TextPassDumper' => __DIR__ . '/maintenance/dumpTextPass.php',
@@ -1578,7 +1524,6 @@ $wgAutoloadLocalClasses = [
        'UploadChunkFileException' => __DIR__ . '/includes/upload/UploadFromChunks.php',
        'UploadChunkVerificationException' => __DIR__ . '/includes/upload/UploadFromChunks.php',
        'UploadChunkZeroLengthFileException' => __DIR__ . '/includes/upload/UploadFromChunks.php',
-       'UploadDumper' => __DIR__ . '/maintenance/dumpUploads.php',
        'UploadForm' => __DIR__ . '/includes/specials/forms/UploadForm.php',
        'UploadFromChunks' => __DIR__ . '/includes/upload/UploadFromChunks.php',
        'UploadFromFile' => __DIR__ . '/includes/upload/UploadFromFile.php',
@@ -1590,7 +1535,6 @@ $wgAutoloadLocalClasses = [
        'UploadSourceField' => __DIR__ . '/includes/specials/formfields/UploadSourceField.php',
        'UploadStash' => __DIR__ . '/includes/upload/UploadStash.php',
        'UploadStashBadPathException' => __DIR__ . '/includes/upload/UploadStash.php',
-       'UploadStashCleanup' => __DIR__ . '/maintenance/cleanupUploadStash.php',
        'UploadStashException' => __DIR__ . '/includes/upload/UploadStash.php',
        'UploadStashFile' => __DIR__ . '/includes/upload/UploadStash.php',
        'UploadStashFileException' => __DIR__ . '/includes/upload/UploadStash.php',
@@ -1600,7 +1544,7 @@ $wgAutoloadLocalClasses = [
        'UploadStashWrongOwnerException' => __DIR__ . '/includes/upload/UploadStash.php',
        'UploadStashZeroLengthFileException' => __DIR__ . '/includes/upload/UploadStash.php',
        'UppercaseCollation' => __DIR__ . '/includes/collation/UppercaseCollation.php',
-       'UsageException' => __DIR__ . '/includes/api/ApiUsageException.php',
+       'UsageException' => __DIR__ . '/includes/api/UsageException.php',
        'User' => __DIR__ . '/includes/user/User.php',
        'UserArray' => __DIR__ . '/includes/user/UserArray.php',
        'UserArrayFromResult' => __DIR__ . '/includes/user/UserArrayFromResult.php',
@@ -1640,7 +1584,6 @@ $wgAutoloadLocalClasses = [
        'WatchedItemQueryServiceExtension' => __DIR__ . '/includes/watcheditem/WatchedItemQueryServiceExtension.php',
        'WatchedItemStore' => __DIR__ . '/includes/watcheditem/WatchedItemStore.php',
        'WatchedItemStoreInterface' => __DIR__ . '/includes/watcheditem/WatchedItemStoreInterface.php',
-       'WatchlistCleanup' => __DIR__ . '/maintenance/cleanupWatchlist.php',
        'WebInstaller' => __DIR__ . '/includes/installer/WebInstaller.php',
        'WebInstallerComplete' => __DIR__ . '/includes/installer/WebInstallerComplete.php',
        'WebInstallerCopying' => __DIR__ . '/includes/installer/WebInstallerCopying.php',
@@ -1744,9 +1687,9 @@ $wgAutoloadLocalClasses = [
        'WrapOldPasswords' => __DIR__ . '/maintenance/wrapOldPasswords.php',
        'XCFHandler' => __DIR__ . '/includes/media/XCF.php',
        'XMLRCFeedFormatter' => __DIR__ . '/includes/rcfeed/XMLRCFeedFormatter.php',
-       'XMPInfo' => __DIR__ . '/includes/libs/xmp/XMPInfo.php',
-       'XMPReader' => __DIR__ . '/includes/libs/xmp/XMP.php',
-       'XMPValidate' => __DIR__ . '/includes/libs/xmp/XMPValidate.php',
+       'XMPInfo' => __DIR__ . '/includes/compat/XMPReader.php',
+       'XMPReader' => __DIR__ . '/includes/compat/XMPReader.php',
+       'XMPValidate' => __DIR__ . '/includes/compat/XMPReader.php',
        'Xhprof' => __DIR__ . '/includes/libs/Xhprof.php',
        'XhprofData' => __DIR__ . '/includes/libs/XhprofData.php',
        'Xml' => __DIR__ . '/includes/Xml.php',
index 90972d6..dbc59a2 100644 (file)
                "ext-mbstring": "*",
                "ext-xml": "*",
                "liuggio/statsd-php-client": "1.0.18",
-               "oojs/oojs-ui": "0.27.0",
+               "oojs/oojs-ui": "0.27.5",
                "oyejorge/less.php": "1.7.0.14",
                "pear/mail": "1.4.1",
                "pear/mail_mime": "1.10.2",
                "pear/mail_mime-decode": "1.5.5.2",
-               "php": ">=5.5.9",
+               "php": ">=5.6.99",
                "psr/log": "1.0.2",
                "wikimedia/assert": "0.2.2",
                "wikimedia/at-ease": "1.2.0",
                "wikimedia/relpath": "2.1.1",
                "wikimedia/remex-html": "1.0.3",
                "wikimedia/running-stat": "1.2.1",
-               "wikimedia/scoped-callback": "1.0.0",
+               "wikimedia/scoped-callback": "2.0.0",
                "wikimedia/utfnormal": "2.0.0",
                "wikimedia/timestamp": "1.0.0",
                "wikimedia/wait-condition-loop": "1.0.1",
-               "wikimedia/wrappedstring": "2.3.0",
+               "wikimedia/wrappedstring": "3.0.1",
+               "wikimedia/xmp-reader": "0.5.1",
                "zordius/lightncandy": "0.23"
        },
        "require-dev": {
-               "composer/spdx-licenses": "1.3.0",
+               "cache/integration-tests": "0.16.0",
+               "composer/spdx-licenses": "1.4.0",
                "hamcrest/hamcrest-php": "^2.0",
                "jakub-onderka/php-parallel-lint": "0.9.2",
-               "jetbrains/phpstorm-stubs": "dev-master#1b9906084d6635456fcf3f3a01f0d7d5b99a578a",
+               "jetbrains/phpstorm-stubs": "dev-master#38ff1a581b297f7901e961b8c923862ea80c3b96",
                "justinrainbow/json-schema": "~5.2",
-               "mediawiki/mediawiki-codesniffer": "17.0.0",
+               "mediawiki/mediawiki-codesniffer": "21.0.0",
                "monolog/monolog": "~1.22.1",
                "nikic/php-parser": "3.1.3",
+               "seld/jsonlint": "1.7.1",
                "nmred/kafka-php": "0.1.5",
                "phpunit/phpunit": "4.8.36 || ^6.5",
-               "psy/psysh": "0.8.11",
+               "psy/psysh": "0.9.6",
                "wikimedia/avro": "1.8.0",
                "wikimedia/testing-access-wrapper": "~1.0",
                "wmde/hamcrest-html-matchers": "^0.1.0"
                "psr-0": {
                        "ComposerHookHandler": "includes/composer",
                        "ComposerVendorHtaccessCreator": "includes/composer"
-               },
-               "files": [
-                       "includes/compat/Timestamp.php"
-               ]
+               }
        },
        "autoload-dev": {
                "files": [
index bcfd2aa..a8f66c9 100644 (file)
                                                                "class": {
                                                                        "enum": ["ResourceLoaderImageModule"]
                                                                },
+                                                               "defaultColor": {
+                                                                       "type": "string"
+                                                               },
                                                                "data": {
                                                                        "type": "string"
                                                                },
                                                                "selectorWithVariant": {
                                                                        "type": "string"
                                                                },
+                                                               "useDataURI": {
+                                                                       "type": "boolean"
+                                                               },
                                                                "variants": {
                                                                        "type": "object"
                                                                },
index 31edbd0..c9d33e1 100644 (file)
                                                                "class": {
                                                                        "enum": ["ResourceLoaderImageModule"]
                                                                },
+                                                               "defaultColor": {
+                                                                       "type": "string"
+                                                               },
                                                                "data": {
                                                                        "type": "string"
                                                                },
                                                                "selectorWithVariant": {
                                                                        "type": "string"
                                                                },
+                                                               "useDataURI": {
+                                                                       "type": "boolean"
+                                                               },
                                                                "variants": {
                                                                        "type": "object"
                                                                },
index 5bdb31c..be887a6 100644 (file)
@@ -63,5 +63,5 @@ $wgParser
 $wgRequest
        WebRequest object, to get request data
 
-$wgMemc, $messageMemc, $parserMemc
+$wgMemc, $messageMemc
        Object caches
index 9404e14..219c51f 100644 (file)
@@ -74,10 +74,10 @@ Using a hook-running strategy, we can avoid having all this option-specific
 stuff in our mainline code. Using hooks, the function becomes:
 
        function showAnArticle( $article ) {
-               if ( Hooks::run( 'ArticleShow', array( &$article ) ) ) {
+               if ( Hooks::run( 'ArticleShow', [ &$article ] ) ) {
                        # code to actually show the article goes here
 
-                       Hooks::run( 'ArticleShowComplete', array( &$article ) );
+                       Hooks::run( 'ArticleShowComplete', [ &$article ] );
                }
        }
 
@@ -137,13 +137,13 @@ Hooks are registered by adding them to the global $wgHooks array for a given
 event. All the following are valid ways to define hooks:
 
        $wgHooks['EventName'][] = 'someFunction'; # function, no data
-       $wgHooks['EventName'][] = array( 'someFunction', $someData );
-       $wgHooks['EventName'][] = array( 'someFunction' ); # weird, but OK
+       $wgHooks['EventName'][] = [ 'someFunction', $someData ];
+       $wgHooks['EventName'][] = [ 'someFunction' ]; # weird, but OK
 
        $wgHooks['EventName'][] = $object; # object only
-       $wgHooks['EventName'][] = array( $object, 'someMethod' );
-       $wgHooks['EventName'][] = array( $object, 'someMethod', $someData );
-       $wgHooks['EventName'][] = array( $object ); # weird but OK
+       $wgHooks['EventName'][] = [ $object, 'someMethod' ];
+       $wgHooks['EventName'][] = [ $object, 'someMethod', $someData ];
+       $wgHooks['EventName'][] = [ $object ]; # weird but OK
 
 When an event occurs, the function (or object method) will be called with the
 optional data provided as well as event-specific parameters. The above examples
@@ -168,8 +168,8 @@ different: 'onArticleSave', 'onUserLogin', etc.
 The extra data is useful if we want to use the same function or object for
 different purposes. For example:
 
-       $wgHooks['PageContentSaveComplete'][] = array( 'ircNotify', 'TimStarling' );
-       $wgHooks['PageContentSaveComplete'][] = array( 'ircNotify', 'brion' );
+       $wgHooks['PageContentSaveComplete'][] = [ 'ircNotify', 'TimStarling' ];
+       $wgHooks['PageContentSaveComplete'][] = [ 'ircNotify', 'brion' ];
 
 This code would result in ircNotify being run twice when an article is saved:
 once for 'TimStarling', and once for 'brion'.
@@ -187,7 +187,7 @@ The last result would be for cases where the hook function replaces the main
 functionality. For example, if you wanted to authenticate users to a custom
 system (LDAP, another PHP program, whatever), you could do:
 
-       $wgHooks['UserLogin'][] = array( 'ldapLogin', $ldapServer );
+       $wgHooks['UserLogin'][] = [ 'ldapLogin', $ldapServer ];
 
        function ldapLogin( $username, $password ) {
                # log user into LDAP
@@ -232,7 +232,7 @@ wfRunHooks must be used, which was deprecated in MediaWiki 1.25.
 Note that hook parameters are passed in an array; this is a necessary
 inconvenience to make it possible to pass reference values (that can be changed)
 into the hook code. Also note that earlier versions of wfRunHooks took a
-variable number of arguments; the array() calling protocol came about after
+variable number of arguments; the array calling protocol came about after
 MediaWiki 1.4rc1.
 
 ==Events and parameters==
@@ -240,8 +240,8 @@ MediaWiki 1.4rc1.
 This is a list of known events and parameters; please add to it if you're going
 to add events to the MediaWiki code.
 
-'AbortAutoAccount': DEPRECATED! Create a PreAuthenticationProvider instead.
-Return false to cancel automated local account creation, where normally
+'AbortAutoAccount': DEPRECATED since 1.27! Create a PreAuthenticationProvider
+instead. Return false to cancel automated local account creation, where normally
 authentication against an external auth plugin would be creating a local
 account.
 $user: the User object about to be created (read-only, incomplete)
@@ -259,7 +259,7 @@ $editor: The User who made the change.
 $title: The Title of the page that was edited.
 $rc: The current RecentChange object.
 
-'AbortLogin': DEPRECATED! Create a PreAuthenticationProvider instead.
+'AbortLogin': DEPRECATED since 1.27! Create a PreAuthenticationProvider instead.
 Return false to cancel account login.
 $user: the User object being authenticated against
 $password: the password being submitted, not yet checked for validity
@@ -269,8 +269,8 @@ $password: the password being submitted, not yet checked for validity
 &$msg: the message identifier for abort reason (new in 1.18, not available
   before 1.18)
 
-'AbortNewAccount': DEPRECATED! Create a PreAuthenticationProvider instead.
-Return false to cancel explicit account creation.
+'AbortNewAccount': DEPRECATED since 1.27! Create a PreAuthenticationProvider
+instead. Return false to cancel explicit account creation.
 $user: the User object about to be created (read-only, incomplete)
 &$msg: out parameter: HTML to display on abort
 &$status: out parameter: Status object to return, replaces the older $msg param
@@ -294,14 +294,14 @@ $name: name of the action
 &$fields: HTMLForm descriptor array
 $article: Article object
 
-'AddNewAccount': DEPRECATED! Use LocalUserCreated.
+'AddNewAccount': DEPRECATED since 1.27! Use LocalUserCreated.
 After a user account is created.
 $user: the User object that was created. (Parameter added in 1.7)
 $byEmail: true when account was created "by email" (added in 1.12)
 
-'AfterBuildFeedLinks': Executed in OutputPage.php after all feed links (atom, rss,...)
-are created. Can be used to omit specific feeds from being outputted. You must not use
-this hook to add feeds, use OutputPage::addFeedLink() instead.
+'AfterBuildFeedLinks': Executed in OutputPage.php after all feed links (atom,
+rss,...) are created. Can be used to omit specific feeds from being outputted.
+You must not use this hook to add feeds, use OutputPage::addFeedLink() instead.
 &$feedLinks: Array of created feed links
 
 'AfterFinalPageOutput': Nearly at the end of OutputPage::output() but
@@ -372,7 +372,7 @@ from ApiBase::addDeprecation().
 &$msgs: Message[] Messages to include in the help. Multiple messages will be
   joined with spaces.
 
-'APIEditBeforeSave': DEPRECATED! Use EditFilterMergedContent instead.
+'APIEditBeforeSave': DEPRECATED since 1.28! Use EditFilterMergedContent instead.
 Before saving a page with api.php?action=edit, after
 processing request parameters. Return false to let the request fail, returning
 an error message or an <edit result="Failure"> tag if $resultArr was filled.
@@ -409,8 +409,8 @@ $format: API format code for $text.
 &$params: Array of parameters
 $flags: int zero or OR-ed flags like ApiBase::GET_VALUES_FOR_HELP
 
-'APIGetDescription': DEPRECATED! Use APIGetDescriptionMessages instead.
-Use this hook to modify a module's description.
+'APIGetDescription': DEPRECATED since 1.25! Use APIGetDescriptionMessages
+instead. Use this hook to modify a module's description.
 &$module: ApiBase Module object
 &$desc: String description, or array of description strings
 
@@ -418,8 +418,8 @@ Use this hook to modify a module's description.
 $module: ApiBase Module object
 &$msg: Array of Message objects
 
-'APIGetParamDescription': DEPRECATED! Use APIGetParamDescriptionMessages
-instead.
+'APIGetParamDescription': DEPRECATED since 1.25! Use
+APIGetParamDescriptionMessages instead.
 Use this hook to modify a module's parameter descriptions.
 &$module: ApiBase Module object
 &$desc: Array of parameter descriptions
@@ -488,8 +488,8 @@ documentation.
 $module: ApiQueryBase module in question
 $result: ResultWrapper|bool returned from the IDatabase::select()
 &$hookData: array that was passed to the 'ApiQueryBaseBeforeQuery' hook and
- will be passed to the 'ApiQueryBaseProcessRow' hook, intended for inter-hook
- communication.
 will be passed to the 'ApiQueryBaseProcessRow' hook, intended for inter-hook
 communication.
 
 'ApiQueryBaseBeforeQuery': Called for (some) API query modules before a
 database query is made. WARNING: It would be very easy to misuse this hook and
@@ -504,7 +504,7 @@ $module: ApiQueryBase module in question
 &$query_options: array of options for the database request
 &$join_conds: join conditions for the tables
 &$hookData: array that will be passed to the 'ApiQueryBaseAfterQuery' and
- 'ApiQueryBaseProcessRow' hooks, intended for inter-hook communication.
 'ApiQueryBaseProcessRow' hooks, intended for inter-hook communication.
 
 'ApiQueryBaseProcessRow': Called for (some) API query modules as each row of
 the database result is processed. Return false to stop processing the result
@@ -514,26 +514,26 @@ $module: ApiQueryBase module in question
 $row: stdClass Database result row
 &$data: array to be included in the ApiResult.
 &$hookData: array that was be passed to the 'ApiQueryBaseBeforeQuery' and
- 'ApiQueryBaseAfterQuery' hooks, intended for inter-hook communication.
 'ApiQueryBaseAfterQuery' hooks, intended for inter-hook communication.
 
 'APIQueryGeneratorAfterExecute': After calling the executeGenerator() method of
 an action=query submodule. Use this to extend core API modules.
 &$module: Module object
 &$resultPageSet: ApiPageSet object
 
-'APIQueryInfoTokens': DEPRECATED! Use ApiQueryTokensRegisterTypes instead.
-Use this hook to add custom tokens to prop=info. Every token has an action,
-which will be used in the intoken parameter and in the output
+'APIQueryInfoTokens': DEPRECATED since 1.24! Use ApiQueryTokensRegisterTypes
+instead. Use this hook to add custom tokens to prop=info. Every token has an
+action, which will be used in the intoken parameter and in the output
 (actiontoken="..."), and a callback function which should return the token, or
 false if the user isn't allowed to obtain it. The prototype of the callback
 function is func($pageid, $title), where $pageid is the page ID of the page the
 token is requested for and $title is the associated Title object. In the hook,
 just add your callback to the $tokenFunctions array and return true (returning
 false makes no sense).
-&$tokenFunctions: array(action => callback)
+&$tokenFunctions: [ action => callback ]
 
-'APIQueryRecentChangesTokens': DEPRECATED! Use ApiQueryTokensRegisterTypes
-instead.
+'APIQueryRecentChangesTokens': DEPRECATED since 1.24! Use
+ApiQueryTokensRegisterTypes instead.
 Use this hook to add custom tokens to list=recentchanges. Every token has an
 action, which will be used in the rctoken parameter and in the output
 (actiontoken="..."), and a callback function which should return the token, or
@@ -543,9 +543,10 @@ page associated to the revision the token is requested for, $title the
 associated Title object and $rc the associated RecentChange object. In the
 hook, just add your callback to the $tokenFunctions array and return true
 (returning false makes no sense).
-&$tokenFunctions: array(action => callback)
+&$tokenFunctions: [ action => callback ]
 
-'APIQueryRevisionsTokens': DEPRECATED! Use ApiQueryTokensRegisterTypes instead.
+'APIQueryRevisionsTokens': DEPRECATED since 1.24! Use
+ApiQueryTokensRegisterTypes instead.
 Use this hook to add custom tokens to prop=revisions. Every token has an
 action, which will be used in the rvtoken parameter and in the output
 (actiontoken="..."), and a callback function which should return the token, or
@@ -555,7 +556,7 @@ page associated to the revision the token is requested for, $title the
 associated Title object and $rev the associated Revision object. In the hook,
 just add your callback to the $tokenFunctions array and return true (returning
 false makes no sense).
-&$tokenFunctions: array(action => callback)
+&$tokenFunctions: [ action => callback ]
 
 'APIQuerySiteInfoGeneralInfo': Use this hook to add extra information to the
 sites general information.
@@ -569,10 +570,11 @@ sites statistics information.
 'ApiQueryTokensRegisterTypes': Use this hook to add additional token types to
 action=query&meta=tokens. Note that most modules will probably be able to use
 the 'csrf' token instead of creating their own token types.
-&$salts: array( type => salt to pass to User::getEditToken() or array of salt
-  and key to pass to Session::getToken() )
+&$salts: [ type => salt to pass to User::getEditToken(), or array of salt
+  and key to pass to Session::getToken() ]
 
-'APIQueryUsersTokens': DEPRECATED! Use ApiQueryTokensRegisterTypes instead.
+'APIQueryUsersTokens': DEPRECATED since 1.24! Use ApiQueryTokensRegisterTypes
+instead.
 Use this hook to add custom token to list=users. Every token has an action,
 which will be used in the ustoken parameter and in the output
 (actiontoken="..."), and a callback function which should return the token, or
@@ -580,7 +582,7 @@ false if the user isn't allowed to obtain it. The prototype of the callback
 function is func($user) where $user is the User object. In the hook, just add
 your callback to the $tokenFunctions array and return true (returning false
 makes no sense).
-&$tokenFunctions: array(action => callback)
+&$tokenFunctions: [ action => callback ]
 
 'ApiQueryWatchlistExtractOutputData': Extract row data for ApiQueryWatchlist.
 $module: ApiQueryWatchlist instance
@@ -600,7 +602,7 @@ key for the array that represents the service data. In this data array, the
 key-value-pair identified by the apiLink key is required.
 &$apis: array of services
 
-'ApiTokensGetTokenTypes': DEPRECATED! Use ApiQueryTokensRegisterTypes instead.
+'ApiTokensGetTokenTypes': DEPRECATED since 1.24! Use ApiQueryTokensRegisterTypes instead.
 Use this hook to extend action=tokens with new token types.
 &$tokenTypes: supported token types in format 'type' => callback function
   used to retrieve this type of tokens.
@@ -737,6 +739,11 @@ $user: the user who did the rollback
 $revision: the revision the page was reverted back to
 $current: the reverted revision
 
+'ArticleShowPatrolFooter': Called at the beginning of Article#showPatrolFooter.
+Extensions can use this to not show the [mark as patrolled] link in certain
+circumstances.
+$article: the Article object
+
 'ArticleUndelete': When one or more revisions of an article are restored.
 &$title: Title corresponding to the article restored
 $create: Whether or not the restoration caused the page to be created (i.e. it
@@ -778,7 +785,8 @@ redirect was followed.
 from a set of AuthenticationRequest classes into a form descriptor; hooks
 can tweak the array to change how login etc. forms should look.
 $requests: array of AuthenticationRequests the fields are created from
-$fieldInfo: field information array (union of all AuthenticationRequest::getFieldInfo() responses).
+$fieldInfo: field information array (union of all
+  AuthenticationRequest::getFieldInfo() responses).
 &$formDescriptor: HTMLForm descriptor. The special key 'weight' can be set
   to change the order of the fields.
 $action: one of the AuthManager::ACTION_* constants.
@@ -786,20 +794,21 @@ $action: one of the AuthManager::ACTION_* constants.
 'AuthManagerLoginAuthenticateAudit': A login attempt either succeeded or failed
 for a reason other than misconfiguration or session loss. No return data is
 accepted; this hook is for auditing only.
-$response: The MediaWiki\Auth\AuthenticationResponse in either a PASS or FAIL state.
+$response: The MediaWiki\Auth\AuthenticationResponse in either a PASS or FAIL
+  state.
 $user: The User object being authenticated against, or null if authentication
   failed before getting that far.
 $username: A guess at the user name being authenticated, or null if we can't
   even determine that.
 
-'AuthPluginAutoCreate': DEPRECATED! Use the 'LocalUserCreated' hook instead.
-Called when creating a local account for an user logged in from an external
-authentication method.
+'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! 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.
+'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.
@@ -972,9 +981,9 @@ No return data is accepted; this hook is for auditing only.
 $req: AuthenticationRequest object describing the change (and target user)
 $status: StatusValue with the result of the action
 
-'ChangePasswordForm': DEPRECATED! Use AuthChangeFormFields or security levels.
-For extensions that need to add a field to the ChangePassword form via the
-Preferences form.
+'ChangePasswordForm': DEPRECATED since 1.27! Use AuthChangeFormFields or
+security levels. For extensions that need to add a field to the ChangePassword
+form via the Preferences form.
 &$extraFields: An array of arrays that hold fields like would be passed to the
   pretty function.
 
@@ -991,8 +1000,8 @@ $rows: The data that will be rendered. May be a ResultWrapper instance or
 $unpatrolled: Whether or not we are showing unpatrolled changes.
 $watched: Whether or not the change is watched by the user.
 
-'ChangesListSpecialPageFilters': DEPRECATED! Use 'ChangesListSpecialPageStructuredFilters'
-instead.
+'ChangesListSpecialPageFilters': DEPRECATED since 1.29! Use
+'ChangesListSpecialPageStructuredFilters' instead.
 Called after building form options on pages
 inheriting from ChangesListSpecialPage (in core: RecentChanges,
 RecentChangesLinked and Watchlist).
@@ -1075,8 +1084,9 @@ $rc_id: recentchanges table id
 $rev_id: revision table id
 $log_id: logging table id
 $params: tag params
-$rc: RecentChange being tagged when the tagging accompanies the action or null
-$user: User who performed the tagging when the tagging is subsequent to the action or null
+$rc: RecentChange being tagged when the tagging accompanies the action, or null
+$user: User who performed the tagging when the tagging is subsequent to the
+  action, or null
 
 'ChangeTagsAllowedAdd': Called when checking if a user can add tags to a change.
 &$allowedTags: List of all the tags the user is allowed to add. Any tags the
@@ -1186,16 +1196,16 @@ $lossy:   boolean indicating whether lossy conversion is allowed.
   converted Content object. Note that $result->getContentModel() must return
   $toModel.
 
-'ContentSecurityPolicyDefaultSource': Modify the allowed CSP load sources. This affects all
-directives except for the script directive. If you want to add a script
-source, see ContentSecurityPolicyScriptSource hook.
+'ContentSecurityPolicyDefaultSource': Modify the allowed CSP load sources. This
+affects all directives except for the script directive. If you want to add a
+script source, see ContentSecurityPolicyScriptSource hook.
 &$defaultSrc: Array of Content-Security-Policy allowed sources
 $policyConfig: Current configuration for the Content-Security-Policy header
-$mode: ContentSecurityPolicy::REPORT_ONLY_MODE or ContentSecurityPolicy::FULL_MODE
-  depending on type of header
+$mode: ContentSecurityPolicy::REPORT_ONLY_MODE or
+  ContentSecurityPolicy::FULL_MODE depending on type of header
 
-'ContentSecurityPolicyDirectives': Modify the content security policy directives.
-Use this only if ContentSecurityPolicyDefaultSource and
+'ContentSecurityPolicyDirectives': Modify the content security policy
+directives. Use this only if ContentSecurityPolicyDefaultSource and
 ContentSecurityPolicyScriptSource do not meet your needs.
 &$directives: Array of CSP directives
 $policyConfig: Current configuration for the CSP header
@@ -1208,8 +1218,8 @@ want non-script sources to be loaded from
 whatever you add.
 &$scriptSrc: Array of CSP directives
 $policyConfig: Current configuration for the CSP header
-$mode: ContentSecurityPolicy::REPORT_ONLY_MODE or ContentSecurityPolicy::FULL_MODE
-  depending on type of header
+$mode: ContentSecurityPolicy::REPORT_ONLY_MODE or
+  ContentSecurityPolicy::FULL_MODE depending on type of header
 
 'CustomEditor': When invoking the page editor
 Return true to allow the normal editor to be used, or false if implementing
@@ -1240,12 +1250,15 @@ $row: the DB row for this line
   Currently only data attributes reserved to MediaWiki are allowed
   (see Sanitizer::isReservedDataAttribute).
 
-'DeleteUnknownPreferences': Called by the cleanupPreferences.php maintenance script to build a WHERE clause with which
-to delete preferences that are not known about. This hook is used by extensions that have dynamically-named preferences
-that should not be deleted in the usual cleanup process. For example, the Gadgets extension creates preferences prefixed
-with 'gadget-', and so anything with that prefix is excluded from the deletion.
-&where: An array that will be passed as the $cond parameter to IDatabase::select() to determine what will be deleted
-  from the user_properties table.
+'DeleteUnknownPreferences': Called by the cleanupPreferences.php maintenance
+script to build a WHERE clause with which to delete preferences that are not
+known about. This hook is used by extensions that have dynamically-named
+preferences that should not be deleted in the usual cleanup process. For
+example, the Gadgets extension creates preferences prefixed with 'gadget-', and
+so anything with that prefix is excluded from the deletion.
+&where: An array that will be passed as the $cond parameter to
+  IDatabase::select() to determine what will be deleted from the user_properties
+  table.
 $db: The IDatabase object, useful for accessing $db->buildLike() etc.
 
 'DifferenceEngineAfterLoadNewText': called in DifferenceEngine::loadNewText()
@@ -1260,82 +1273,88 @@ checking if the variable's value is null.
 This hook can be used to inject content into said class member variable.
 $differenceEngine: DifferenceEngine object
 
-'DifferenceEngineMarkPatrolledLink': Allows extensions to change the "mark as patrolled" link
-which is shown both on the diff header as well as on the bottom of a page, usually
-wrapped in a span element which has class="patrollink".
+'DifferenceEngineMarkPatrolledLink': Allows extensions to change the "mark as
+patrolled" link which is shown both on the diff header as well as on the bottom
+of a page, usually wrapped in a span element which has class="patrollink".
 $differenceEngine: DifferenceEngine object
 &$markAsPatrolledLink: The "mark as patrolled" link HTML (string)
 $rcid: Recent change ID (rc_id) for this change (int)
 
-'DifferenceEngineMarkPatrolledRCID': Allows extensions to possibly change the rcid parameter.
-For example the rcid might be set to zero due to the user being the same as the
-performer of the change but an extension might still want to show it under certain
-conditions.
+'DifferenceEngineMarkPatrolledRCID': Allows extensions to possibly change the
+rcid parameter. For example the rcid might be set to zero due to the user being
+the same as the performer of the change but an extension might still want to
+show it under certain conditions.
 &$rcid: rc_id (int) of the change or 0
 $differenceEngine: DifferenceEngine object
 $change: RecentChange object
 $user: User object representing the current user
 
-'DifferenceEngineNewHeader': Allows extensions to change the $newHeader variable, which
-contains information about the new revision, such as the revision's author, whether
-the revision was marked as a minor edit or not, etc.
+'DifferenceEngineNewHeader': Allows extensions to change the $newHeader
+variable, which contains information about the new revision, such as the
+revision's author, whether the revision was marked as a minor edit or not, etc.
 $differenceEngine: DifferenceEngine object
 &$newHeader: The string containing the various #mw-diff-otitle[1-5] divs, which
-include things like revision author info, revision comment, RevisionDelete link and more
+  include things like revision author info, revision comment, RevisionDelete
+  link and more
 $formattedRevisionTools: Array containing revision tools, some of which may have
-been injected with the DiffRevisionTools hook
-$nextlink: String containing the link to the next revision (if any); also included in $newHeader
-$rollback: Rollback link (string) to roll this revision back to the previous one, if any
+  been injected with the DiffRevisionTools hook
+$nextlink: String containing the link to the next revision (if any); also
+  included in $newHeader
+$rollback: Rollback link (string) to roll this revision back to the previous
+  one, if any
 $newminor: String indicating if the new revision was marked as a minor edit
 $diffOnly: Boolean parameter passed to DifferenceEngine#showDiffPage, indicating
-whether we should show just the diff; passed in as a query string parameter to the
-various URLs constructed here (i.e. $nextlink)
+  whether we should show just the diff; passed in as a query string parameter to
+  the various URLs constructed here (i.e. $nextlink)
 $rdel: RevisionDelete link for the new revision, if the current user is allowed
-to use the RevisionDelete feature
+  to use the RevisionDelete feature
 $unhide: Boolean parameter indicating whether to show RevisionDeleted revisions
 
-'DifferenceEngineOldHeader': Allows extensions to change the $oldHeader variable, which
-contains information about the old revision, such as the revision's author, whether
-the revision was marked as a minor edit or not, etc.
+'DifferenceEngineOldHeader': Allows extensions to change the $oldHeader
+variable, which contains information about the old revision, such as the
+revision's author, whether the revision was marked as a minor edit or not, etc.
 $differenceEngine: DifferenceEngine object
 &$oldHeader: The string containing the various #mw-diff-otitle[1-5] divs, which
-include things like revision author info, revision comment, RevisionDelete link and more
-$prevlink: String containing the link to the previous revision (if any); also included in $oldHeader
+  include things like revision author info, revision comment, RevisionDelete
+  link and more
+$prevlink: String containing the link to the previous revision (if any); also
+  included in $oldHeader
 $oldminor: String indicating if the old revision was marked as a minor edit
 $diffOnly: Boolean parameter passed to DifferenceEngine#showDiffPage, indicating
-whether we should show just the diff; passed in as a query string parameter to the
-various URLs constructed here (i.e. $prevlink)
+  whether we should show just the diff; passed in as a query string parameter to
+  the various URLs constructed here (i.e. $prevlink)
 $ldel: RevisionDelete link for the old revision, if the current user is allowed
-to use the RevisionDelete feature
+  to use the RevisionDelete feature
 $unhide: Boolean parameter indicating whether to show RevisionDeleted revisions
 
-'DifferenceEngineOldHeaderNoOldRev': Change the $oldHeader variable in cases when
-there is no old revision
+'DifferenceEngineOldHeaderNoOldRev': Change the $oldHeader variable in cases
+when there is no old revision
 &$oldHeader: empty string by default
 
-'DifferenceEngineRenderRevisionAddParserOutput': Allows extensions to change the parser output.
-Return false to not add parser output via OutputPage's addParserOutput method.
+'DifferenceEngineRenderRevisionAddParserOutput': Allows extensions to change the
+parser output. Return false to not add parser output via OutputPage's
+addParserOutput method.
 $differenceEngine: DifferenceEngine object
 $out: OutputPage object
 $parserOutput: ParserOutput object
 $wikiPage: WikiPage object
 
-'DifferenceEngineRenderRevisionShowFinalPatrolLink': An extension can hook into this hook
-point and return false to not show the final "mark as patrolled" link on the bottom
-of a page.
+'DifferenceEngineRenderRevisionShowFinalPatrolLink': An extension can hook into
+this hook point and return false to not show the final "mark as patrolled" link
+on the bottom of a page.
 This hook has no arguments.
 
 'DifferenceEngineShowDiff': Allows extensions to affect the diff text which
 eventually gets sent to the OutputPage object.
 $differenceEngine: DifferenceEngine object
 
-'DifferenceEngineShowEmptyOldContent': Allows extensions to change the diff table
-body (without header) in cases when there is no old revision or the old and new
-revisions are identical.
+'DifferenceEngineShowEmptyOldContent': Allows extensions to change the diff
+table body (without header) in cases when there is no old revision or the old
+and new revisions are identical.
 $differenceEngine: DifferenceEngine object
 
-'DifferenceEngineShowDiffPage': Add additional output via the available OutputPage
-object into the diff view
+'DifferenceEngineShowDiffPage': Add additional output via the available
+OutputPage object into the diff view
 $out: OutputPage object
 
 'DifferenceEngineShowDiffPageMaybeShowMissingRevision': called in
@@ -1361,7 +1380,7 @@ an article
 &$article: article (object) being viewed
 &$oldid: oldid (int) being viewed
 
-'DoEditSectionLink': DEPRECATED! Use SkinEditSectionLinks instead.
+'DoEditSectionLink': DEPRECATED since 1.25! Use SkinEditSectionLinks instead.
 Override the HTML generated for section edit links
 $skin: Skin object rendering the UI
 $title: Title object for the title being linked to (may not be the same as
@@ -1381,7 +1400,6 @@ $section: Section being edited
 &$error: Error message to return
 $summary: Edit summary for page
 
-
 'EditFilterMergedContent': Post-section-merge edit filter.
 This may be triggered by the EditPage or any other facility that modifies page
 content. Use the $status object to indicate whether the edit should be allowed,
@@ -1389,7 +1407,7 @@ and to provide a reason for disallowing it. Return false to abort the edit, and
 true to continue. Returning true if $status->isOK() returns false means "don't
 save but continue user interaction", e.g. show the edit form.
 $status->apiHookResult can be set to an array to be returned by api.php
-action=edit. This is used to deliver captchas.
+  action=edit. This is used to deliver captchas.
 $context: object implementing the IContextSource interface.
 $content: content of the edit box, as a Content object.
 $status: Status object to represent errors, etc.
@@ -1417,9 +1435,9 @@ $resultDetails: Result details array
 
 'EditPage::importFormData': allow extensions to read additional data
 posted in the form
+Return value is ignored (should always return true)
 $editpage: EditPage instance
 $request: Webrequest
-return value is ignored (should always return true)
 
 'EditPage::showEditForm:fields': allows injection of form field into edit form
 Return value is ignored (should always return true)
@@ -1461,18 +1479,11 @@ textarea in the edit form.
 &$buttons: Array of edit buttons "Save", "Preview", "Live", and "Diff"
 &$tabindex: HTML tabindex of the last edit check/button
 
-'EditPageBeforeEditChecks': DEPRECATED! Use 'EditPageGetCheckboxesDefinition' instead,
-or 'EditPage::showStandardInputs:options' if you don't actually care about checkboxes
-and just want to add some HTML to the page.
-Allows modifying the edit checks below the textarea in the edit form.
-&$editpage: The current EditPage object
-&$checks: Array of the HTML for edit checks like "watch this page"/"minor edit"
-&$tabindex: HTML tabindex of the last edit check/button
-
 'EditPageBeforeEditToolbar': Allows modifying the edit toolbar above the
 textarea in the edit form.
+Hook subscribers can return false to avoid the default toolbar code being
+loaded.
 &$toolbar: The toolbar HTML
-Hook subscribers can return false to avoid the default toolbar code being loaded.
 
 'EditPageCopyrightWarning': Allow for site and per-namespace customization of
 contribution/copyright notice.
@@ -1483,8 +1494,8 @@ $title: title of page being edited
 'EditPageGetCheckboxesDefinition': Allows modifying the edit checkboxes
 below the textarea in the edit form.
 $editpage: The current EditPage object
-&$checkboxes: Array of checkbox definitions. See EditPage::getCheckboxesDefinition()
-for the format.
+&$checkboxes: Array of checkbox definitions. See
+  EditPage::getCheckboxesDefinition() for the format.
 
 'EditPageGetDiffContent': Allow modifying the wikitext that will be used in
 "Show changes". Note that it is preferable to implement diff handling for
@@ -1520,7 +1531,8 @@ true to allow those checks to occur, and false if checking is done.
 &$from: MailAddress object of sending user
 &$subject: subject of the mail
 &$text: text of the mail
-&$error: Out-param for an error. Should be set to a Status object or boolean false.
+&$error: Out-param for an error. Should be set to a Status object or boolean
+  false.
 
 'EmailUserCC': Before sending the copy of the email to the author.
 &$to: MailAddress object of receiving user
@@ -1555,7 +1567,8 @@ $block: The RecentChanges objects in that block
 a grouped recent change inner line in EnhancedChangesList.
 Hook subscribers can return false to omit this line from recentchanges.
 $changesList: EnhancedChangesList object
-&$data: An array with all the components that will be joined in order to create the line
+&$data: An array with all the components that will be joined in order to create
+  the line
 $block: An array of RecentChange objects in that block
 $rc: The RecentChange object for this line
 &$classes: An array of classes to change
@@ -1566,7 +1579,8 @@ $rc: The RecentChange object for this line
 'EnhancedChangesListModifyBlockLineData': to alter data used to build
 a non-grouped recent change line in EnhancedChangesList.
 $changesList: EnhancedChangesList object
-&$data: An array with all the components that will be joined in order to create the line
+&$data: An array with all the components that will be joined in order to create
+  the line
 $rc: The RecentChange object for this line
 
 'ExemptFromAccountCreationThrottle': Exemption from the account creation
@@ -1672,10 +1686,10 @@ underscore) magic words. Called by MagicWord.
 
 'GetExtendedMetadata': Get extended file metadata for the API
 &$combinedMeta: Array of the form:
-       'MetadataPropName' => array(
+       'MetadataPropName' => [
                value' => prop value,
                'source' => 'name of hook'
-       ).
+        ].
 $file: File object of file in question
 $context: RequestContext (including language to use)
 $single: Only extract the current language; if false, the prop value should
@@ -1716,6 +1730,7 @@ $query: query options passed to Title::getInternalURL()
 $linkcolour_ids: array of prefixed DB keys of the pages linked to,
   indexed by page_id.
 &$colours: (output) array of CSS classes, indexed by prefixed DB keys
+$title: Title object of the page being parsed, on which the links will be shown
 
 'GetLocalURL': Modify local URLs as output into page links. Note that if you are
 working with internal urls (non-interwiki) then it may be preferable to work
@@ -1773,7 +1788,7 @@ $lang: Language that will be used to render the timestamp
 'getUserPermissionsErrors': Add a permissions error when permissions errors are
 checked for. Use instead of userCan for most cases. Return false if the user
 can't do it, and populate $result with the reason in the form of
-array( messagename, param1, param2, ... ) or a MessageSpecifier instance (you
+[ messagename, param1, param2, ... ] or a MessageSpecifier instance (you
 might want to use ApiMessage to provide machine-readable details for the API).
 For consistency, error messages
 should be plain text with no special coloring, bolding, etc. to show that
@@ -1787,12 +1802,12 @@ $action: Action being checked
 'getUserPermissionsErrorsExpensive': Equal to getUserPermissionsErrors, but is
 called only if expensive checks are enabled. Add a permissions error when
 permissions errors are checked for. Return false if the user can't do it, and
-populate $result with the reason in the form of array( messagename, param1,
-param2, ... ) or a MessageSpecifier instance (you might want to use ApiMessage
-to provide machine-readable details for the API). For consistency, error
-messages should be plain text with no
-special coloring, bolding, etc. to show that they're errors; presenting them
-properly to the user as errors is done by the caller.
+populate $result with the reason in the form of [ messagename, param1, param2,
+... ] or a MessageSpecifier instance (you might want to use ApiMessage to
+provide machine-readable details for the API). For consistency, error messages
+should be plain text with no special coloring, bolding, etc. to show that
+they're errors; presenting them properly to the user as errors is done by the
+caller.
 &$title: Title object being checked against
 &$user: Current user object
 $action: Action being checked
@@ -1809,6 +1824,11 @@ $rev: Revision object
 $prevRev: Revision object, next in line in page history, or null
 $user: Current user object
 
+'HistoryPageToolLinks': Add one or more links to revision history page subtitle.
+$context: IContextSource (object)
+$linkRenderer: LinkRenderer instance
+&$links: Array of HTML strings
+
 'HTMLFileCache::useFileCache': Override whether a page should be cached in file
 cache.
 $context: An IContextSource object with information about the request being
@@ -1826,6 +1846,9 @@ just modify a few things using call-by-reference.
   includes/Linker.php for Linker::makeImageLink
 &$time: Timestamp of file in 'YYYYMMDDHHIISS' string form, or false for current
 &$res: Final HTML output, used if you return false
+$parser: Parser instance
+&$query: Query params for desc URL
+&$widthOption: Used by the parser to remember the user preference thumbnailsize
 
 'ImageOpenShowImageInlineBefore': Call potential extension just before showing
 the image on an image page.
@@ -1886,9 +1909,9 @@ $revisionInfo: Array of revision information
 Return false to stop further processing of the tag
 $reader: XMLReader object
 
-'ImportHandleUnknownUser': When a user doesn't exist locally, this hook is called
-to give extensions an opportunity to auto-create it. If the auto-creation is
-successful, return false.
+'ImportHandleUnknownUser': When a user doesn't exist locally, this hook is
+called to give extensions an opportunity to auto-create it. If the auto-creation
+is successful, return false.
 $name: User name
 
 'ImportHandleUploadXMLTag': When parsing a XML tag in a file upload.
@@ -1972,7 +1995,7 @@ $user: User the password is being validated for
 $code: The language code or the language we're looking for a messages file for
 &$file: The messages file path, you can override this to change the location.
 
-'LanguageGetMagic': DEPRECATED! Use $magicWords in a file listed in
+'LanguageGetMagic': DEPRECATED since 1.16! Use $magicWords in a file listed in
 $wgExtensionMessagesFiles instead.
 Use this to define synonyms of magic words depending of the language
 &$magicExtensions: associative array of magic words synonyms
@@ -2007,11 +2030,11 @@ $title: The page's Title.
 $out: The output page.
 $cssClassName: CSS class name of the language selector.
 
-'LinkBegin': DEPRECATED! Use HtmlPageLinkRendererBegin instead.
-Used when generating internal and interwiki links in
-Linker::link(), before processing starts.  Return false to skip default
-processing and return $ret. See documentation for Linker::link() for details on
-the expected meanings of parameters.
+'LinkBegin': DEPRECATED since 1.28! Use HtmlPageLinkRendererBegin instead.
+Used when generating internal and interwiki links in Linker::link(), before
+processing starts.  Return false to skip default processing and return $ret. See
+documentation for Linker::link() for details on the expected meanings of
+parameters.
 $skin: the Skin object
 $target: the Title that the link is pointing to
 &$html: the contents that the <a> tag should have (raw HTML); null means
@@ -2025,7 +2048,7 @@ $target: the Title that the link is pointing to
 &$options: array of options.  Can include 'known', 'broken', 'noclasses'.
 &$ret: the value to return if your hook returns false.
 
-'LinkEnd': DEPRECATED! Use HtmlPageLinkRendererEnd hook instead
+'LinkEnd': DEPRECATED since 1.28! Use HtmlPageLinkRendererEnd hook instead
 Used when generating internal and interwiki links in Linker::link(),
 just before the function returns a value.  If you return true, an <a> element
 with HTML attributes $attribs and contents $html will be returned.  If you
@@ -2170,7 +2193,8 @@ $autocreated: Boolean, whether this was an auto-creation
 Special:Log for a specific log type
 $type: String of log type being displayed
 $logEventsList: LogEventsList object for context and access to the WebRequest
-&$input: string HTML of an input element
+&$input: string HTML of an input element (deprecated, use $formDescriptor instead)
+&$formDescriptor: array HTMLForm's form descriptor
 
 'LogEventsListShowLogExtract': Called before the string is added to OutputPage.
 Returning false will prevent the string from being added to the OutputPage.
@@ -2207,11 +2231,11 @@ in LoginForm::$validErrorMessages).
 &$messages: Already added messages (inclusive messages from
   LoginForm::$validErrorMessages)
 
-'LoginUserMigrated': DEPRECATED! Create a PreAuthenticationProvider instead.
-Called during login to allow extensions the opportunity to inform a user that
-their username doesn't exist for a specific reason, instead of letting the
-login form give the generic error message that the account does not exist. For
-example, when the account has been renamed or deleted.
+'LoginUserMigrated': DEPRECATED since 1.27! Create a PreAuthenticationProvider
+instead. Called during login to allow extensions the opportunity to inform a
+user that their username doesn't exist for a specific reason, instead of letting
+the login form give the generic error message that the account does not exist.
+For example, when the account has been renamed or deleted.
 $user: the User object being authenticated against.
 &$msg: the message identifier for abort reason, or an array to pass a message
   key and parameters.
@@ -2265,6 +2289,18 @@ $wcOnlySysopsCanPatrol: config setting indicating whether the user must be a
   sysop to patrol the edit.
 $auto: true if the edit is being marked as patrolled automatically
 
+'ApiMaxLagInfo': When lag information is being requested via API. Use this to
+override lag information. Generally a hook function should only replace
+$lagInfo if the new $lagInfo['lag'] is greater than the current $lagInfo['lag'].
+&$lagInfo: Maximum lag information array. Fields in the array are:
+  'lag' is the number of seconds of lag.
+  'host' is the host name on which the lag exists.
+  'type' is an indication of the type of lag,
+    e.g. "db" for database replication lag or "jobqueue" for job queue size
+    converted to pseudo-seconds.
+  It is possible to add more fields and they will be returned to the user in
+  the API response.
+
 'MediaWikiPerformAction': Override MediaWiki::performAction(). Use this to do
 something completely different, after the basic globals have been set up, but
 before ordinary actions take place.
@@ -2359,8 +2395,8 @@ $new: the ?new= param value from the url
 'NewPagesLineEnding': Called before a NewPages line is finished.
 $page: the SpecialNewPages object
 &$ret: the HTML line
-$row: the database row for this page (the recentchanges record and a few extras - see
-  NewPagesPager::getQueryInfo)
+$row: the database row for this page (the recentchanges record and a few extras
+  - see NewPagesPager::getQueryInfo)
 &$classes: the classes to add to the surrounding <li>
 &$attribs: associative array of other HTML attributes for the <li> element.
   Currently only data attributes reserved to MediaWiki are allowed
@@ -2370,7 +2406,9 @@ $row: the database row for this page (the recentchanges record and a few extras
 edit.
 $wikiPage: the WikiPage edited
 $rev: the new revision
-$baseID: the revision ID this was based off, if any
+$originalRevId: if the edit restores or repeats an earlier revision (such as a
+  rollback or a null revision), the ID of that earlier revision. False otherwise.
+  (Used to be called $baseID.)
 $user: the editing user
 &$tags: tags to apply to the edit and recent change
 
@@ -2408,6 +2446,12 @@ users and/or IP addresses too.
 &$otherBlockLink: An array with links to other block logs
 $ip: The requested IP address or username
 
+'OutputPageAfterGetHeadLinksArray': Called in OutputPage#getHeadLinksArray right
+before returning the result.
+&$tags: array containing all <head> links generated so far. The array format is
+"link name or number => 'link HTML'".
+$out: the OutputPage object
+
 'OutputPageBeforeHTML': A page has been processed by the parser and the
 resulting HTML is about to be displayed.
 &$parserOutput: the parserOutput (object) that corresponds to the page
@@ -2478,7 +2522,9 @@ $flags: Flags passed to WikiPage::doEditContent()
 $revision: New Revision of the article (can be null for edits that change
   nothing)
 $status: Status object about to be returned by doEditContent()
-$baseRevId: the rev ID (or false) this edit was based on
+$originalRevId: if the edit restores or repeats an earlier revision (such as a
+  rollback or a null revision), the ID of that earlier revision. False otherwise.
+  (Used to be called $baseRevId.)
 $undidRevId: the rev ID (or 0) this edit undid
 
 'PageHistoryBeforeList': When a history page list is about to be constructed.
@@ -2599,7 +2645,7 @@ cache or return false to not use it.
 &$parser: Parser object
 &$varCache: variable cache (array)
 
-'ParserLimitReport': DEPRECATED! Use ParserLimitReportPrepare and
+'ParserLimitReport': DEPRECATED since 1.22! Use ParserLimitReportPrepare and
 ParserLimitReportFormat instead.
 Called at the end of Parser:parse() when the parser will
 include comments about size of the text parsed.
@@ -2636,7 +2682,8 @@ change the default value for an option, all existing parser cache entries will
 be invalid. To avoid bugs, you'll need to handle that somehow (e.g. with the
 RejectParserCacheValue hook) because MediaWiki won't do it for you.
 &$defaults: Set the default value for your option here.
-&$inCacheKey: To fragment the parser cache on your option, set a truthy value here.
+&$inCacheKey: To fragment the parser cache on your option, set a truthy value
+  here.
 &$lazyLoad: To lazy-initialize your option, set it null in $defaults and set a
   callable here. The callable is passed the ParserOptions object and the option
   name.
@@ -2666,7 +2713,8 @@ run. Use when page save hooks require the presence of custom tables to ensure
 that tests continue to run properly.
 &$tables: array of table names
 
-'ParserOutputStashForEdit': Called when an edit stash parse finishes, before the output is cached.
+'ParserOutputStashForEdit': Called when an edit stash parse finishes, before the
+output is cached.
 $page: the WikiPage of the candidate edit
 $content: the Content object of the candidate edit
 $output: the ParserOutput result of the candidate edit
@@ -2716,19 +2764,20 @@ Occurs after signing up or logging in, allows for interception of redirect.
 
 'PreferencesFormPreSave': Override preferences being saved
 $formData: array of user submitted data
-$form: PreferencesForm object, also a ContextSource
+$form: HTMLForm object, also a ContextSource
 $user: User object with preferences to be saved set
 &$result: boolean indicating success
 $oldUserOptions: array with user old options (before save)
 
 'PreferencesGetLegend': Override the text used for the <legend> of a
 preferences section.
-$form: the PreferencesForm object. This is a ContextSource as well
+$form: the HTMLForm object. This is a ContextSource as well
 $key: the section name
 &$legend: the legend text. Defaults to wfMessage( "prefs-$key" )->text() but may
   be overridden
 
-'PrefixSearchBackend': DEPRECATED! Override SearchEngine::completionSearchBackend instead.
+'PrefixSearchBackend': DEPRECATED since 1.27! Override
+SearchEngine::completionSearchBackend instead.
 Override the title prefix search used for OpenSearch and
 AJAX search suggestions. Put results into &$results outparam and return false.
 $ns: array of int namespace keys to search in
@@ -2824,7 +2873,7 @@ $context: ResourceLoaderContext|null
 ResourceLoaderStartUpModule::getConfigSettings(). Use this to export static
 configuration variables to JavaScript. Things that depend on the current page
 or request state must be added through MakeGlobalVariablesScript instead.
-&$vars: array( variable name => value )
+&$vars: [ variable name => value ]
 
 'ResourceLoaderJqueryMsgModuleMagicWords': Called in
 ResourceLoaderJqueryMsgModule to allow adding magic words for jQueryMsg.
@@ -2843,10 +2892,10 @@ called after the addition of 'qunit' and MediaWiki testing resources.
 &$testModules: array of JavaScript testing modules. The 'qunit' framework,
   included in core, is fed using tests/qunit/QUnitTestResources.php.
   To add a new qunit module named 'myext.tests':
-       $testModules['qunit']['myext.tests'] = array(
+       $testModules['qunit']['myext.tests'] = [
                'script' => 'extension/myext/tests.js',
                'dependencies' => <any module dependency you might have>
-       );
+        ];
   For QUnit framework, the mediawiki.tests.qunit.testrunner dependency will be
   added to any module.
 &$ResourceLoader: object
@@ -2854,8 +2903,8 @@ called after the addition of 'qunit' and MediaWiki testing resources.
 'RevisionRecordInserted': Called after a revision is inserted into the database.
 $revisionRecord: the RevisionRecord that has just been inserted.
 
-'RevisionInsertComplete': DEPRECATED! Use RevisionRecordInserted hook instead.
-Called after a revision is inserted into the database.
+'RevisionInsertComplete': DEPRECATED since 1.31! Use RevisionRecordInserted hook
+instead. Called after a revision is inserted into the database.
 $revision: the Revision
 $data: DEPRECATED! Always null!
 $flags: DEPRECATED! Always null!
@@ -2903,10 +2952,12 @@ $engine: SearchEngine for which the indexing is intended
 
 'SearchResultsAugment': Allows extension to add its code to the list of search
 result augmentors.
-&$setAugmentors: List of whole-set augmentor objects, must implement ResultSetAugmentor
-&$rowAugmentors: List of per-row augmentor objects, must implement ResultAugmentor.
-Note that lists should be in the format name => object and the names in both lists should
-be distinct.
+&$setAugmentors: List of whole-set augmentor objects, must implement
+  ResultSetAugmentor.
+&$rowAugmentors: List of per-row augmentor objects, must implement
+  ResultAugmentor.
+Note that lists should be in the format name => object and the names in both
+  lists should be distinct.
 
 'SecondaryDataUpdates': Allows modification of the list of DataUpdates to
 perform when page content is modified. Currently called by
@@ -2989,11 +3040,13 @@ $terms: Search terms, for highlighting
 
 'ShowSearchHitTitle': Customise display of search hit title/link.
 &$title: Title to link to
-&$titleSnippet: Label for the link representing the search result. Typically the article title.
+&$titleSnippet: Label for the link representing the search result. Typically the
+  article title.
 $result: The SearchResult object
 $terms: String of the search terms entered
 $specialSearch: The SpecialSearch object
-&$query: Array of query string parameters for the link representing the search result.
+&$query: Array of query string parameters for the link representing the search
+  result.
 &$attributes: Array of title link attributes, can be modified by extension.
 
 'SidebarBeforeOutput': Allows to edit sidebar just before it is output by skins.
@@ -3171,7 +3224,7 @@ $pager: The UsersPager instance
 
 'SpecialListusersFormatRow': Called right before the end of
 UsersPager::formatRow().
-&$item: HTML to be returned. Will be wrapped in <li></li> after the hook finishes
+&$item: HTML to be returned. Will be wrapped in an <li> after the hook finishes
 $row: Database row object
 
 'SpecialListusersHeader': Called after adding the submit button in
@@ -3248,8 +3301,8 @@ use this to change some selection criteria or substitute a different title.
 &$title: If the hook returns false, a Title object to use instead of the
   result from the normal query
 
-'SpecialRecentChangesFilters': DEPRECATED! Use ChangesListSpecialPageStructuredFilters
-instead.
+'SpecialRecentChangesFilters': DEPRECATED since 1.23! Use
+ChangesListSpecialPageStructuredFilters instead.
 Called after building form options at RecentChanges.
 $special: the special page object
 &$filters: associative array of filter definitions. The keys are the HTML
@@ -3261,8 +3314,8 @@ SpecialRecentChanges.
 &$extraOpts: array of added items, to which can be added
 $opts: FormOptions for this request
 
-'SpecialRecentChangesQuery': DEPRECATED! Use ChangesListSpecialPageStructuredFilters
-or ChangesListSpecialPageQuery instead.
+'SpecialRecentChangesQuery': DEPRECATED since 1.23! Use
+ChangesListSpecialPageStructuredFilters or ChangesListSpecialPageQuery instead.
 Called when building SQL query for SpecialRecentChanges and
 SpecialRecentChangesLinked.
 &$conds: array of WHERE conditionals for query
@@ -3275,10 +3328,10 @@ $opts: FormOptions for this request
 'SpecialResetTokensTokens': Called when building token list for
 SpecialResetTokens.
 &$tokens: array of token information arrays in the format of
-       array(
+       [
                'preference' => '<preference-name>',
                'label-message' => '<message-key>',
-       )
+        ]
 
 'SpecialSearchCreateLink': Called when making the message to create a page or
 go to the existing page.
@@ -3291,7 +3344,8 @@ $url does a standard redirect to $title. Setting $url redirects to the
 specified URL.
 $term: The string the user searched for
 $title: The title the 'go' feature has decided to forward the user to
-&$url: Initially null, hook subscribers can set this to specify the final url to redirect to
+&$url: Initially null, hook subscribers can set this to specify the final url to
+  redirect to
 
 'SpecialSearchNogomatch': Called when the 'Go' feature is triggered (generally
 from autocomplete search other than the main bar on Special:Search) and the
@@ -3303,7 +3357,7 @@ called.
 the advanced form, a.k.a. power search box.
 &$showSections: an array to add values with more options to
 $term: the search term (not a title object)
-$opts: an array of hidden options (containing 'redirs' and 'profile')
+&$opts: an array of hidden options (containing 'redirs' and 'profile')
 
 'SpecialSearchProfileForm': Allows modification of search profile forms.
 $search: special page object
@@ -3349,11 +3403,14 @@ $engine: the search engine
   message key to use in the name column,
 $context: IContextSource object
 
-'SpecialTrackingCategories::preprocess': Called after LinkBatch on Special:TrackingCategories
+'SpecialTrackingCategories::preprocess': Called after LinkBatch on
+Special:TrackingCategories
 $specialPage: The SpecialTrackingCategories object
-$trackingCategories: Array of data from Special:TrackingCategories with msg and cats
+$trackingCategories: Array of data from Special:TrackingCategories with msg and
+  cats
 
-'SpecialTrackingCategories::generateCatLink': Called for each cat link on Special:TrackingCategories
+'SpecialTrackingCategories::generateCatLink': Called for each cat link on
+Special:TrackingCategories
 $specialPage: The SpecialTrackingCategories object
 $catTitle: The Title object of the linked category
 &$html: The Result html
@@ -3366,8 +3423,8 @@ Special:Upload.
 $wgVersion: Current $wgVersion for you to use
 &$versionUrl: Raw url to link to (eg: release notes)
 
-'SpecialWatchlistFilters': DEPRECATED! Use ChangesListSpecialPageStructuredFilters
-instead.
+'SpecialWatchlistFilters': DEPRECATED since 1.23! Use
+ChangesListSpecialPageStructuredFilters instead.
 Called after building form options at Watchlist.
 $special: the special page object
 &$filters: associative array of filter definitions. The keys are the HTML
@@ -3379,8 +3436,8 @@ SpecialWatchlist. Allows extensions to register custom values they have
 inserted to rc_type so they can be returned as part of the watchlist.
 &$nonRevisionTypes: array of values in the rc_type field of recentchanges table
 
-'SpecialWatchlistQuery': DEPRECATED! Use ChangesListSpecialPageStructuredFilters
-or ChangesListSpecialPageQuery instead.
+'SpecialWatchlistQuery': DEPRECATED since 1.23! Use
+ChangesListSpecialPageStructuredFilters or ChangesListSpecialPageQuery instead.
 Called when building sql query for SpecialWatchlist.
 &$conds: array of WHERE conditionals for query
 &$tables: array of tables to be queried
@@ -3443,7 +3500,8 @@ $old: old title
 $nt: new title
 $user: user who does the move
 
-'TitleMoveStarting': Before moving an article (title), but just after the atomic DB section starts.
+'TitleMoveStarting': Before moving an article (title), but just after the atomic
+DB section starts.
 $old: old title
 $nt: new title
 $user: user who does the move
@@ -3516,8 +3574,8 @@ $title: Title object of the page that we're about to undelete
 $title: title object related to the revision
 $rev: revision (object) that will be viewed
 
-'UnitTestsAfterDatabaseSetup': Called right after MediaWiki's test infrastructure
-has finished creating/duplicating core tables for unit tests.
+'UnitTestsAfterDatabaseSetup': Called right after MediaWiki's test
+infrastructure has finished creating/duplicating core tables for unit tests.
 $database: Database in question
 $prefix: Table prefix to be used in unit tests
 
@@ -3529,7 +3587,7 @@ Since 1.24: Paths pointing to a directory will be recursively scanned for
 test case files matching the suffix "Test.php".
 &$paths: list of test cases and directories to search.
 
-'UnknownAction': DEPRECATED! To add an action in an extension,
+'UnknownAction': DEPRECATED since 1.19! To add an action in an extension,
 create a subclass of Action, and add a new key to $wgActions.
 An unknown "action" has occurred (useful for defining your own actions).
 $action: action name
@@ -3556,11 +3614,11 @@ $type: (string) the requested upload type
 &$className: the class name of the Upload instance to be created
 
 'UploadForm:BeforeProcessing': At the beginning of processUpload(). Lets you
-poke at member variables like $mUploadDescription before the file is saved. Do
-not use this hook to break upload processing. This will return the user to a
-blank form with no error message; use UploadVerification and UploadVerifyFile
-instead.
-&$form: UploadForm object
+poke at member variables like $mUploadDescription before the file is saved.
+Do not use this hook to break upload processing.
+This will return the user to a blank form with no error message;
+use UploadVerifyUpload or UploadVerifyFile instead.
+&$upload: SpecialUpload object
 
 'UploadForm:getInitialPageText': After the initial page text for file uploads
 is generated, to allow it to be altered.
@@ -3571,7 +3629,7 @@ $config: Config object
 'UploadForm:initial': Before the upload form is generated. You might set the
 member-variables $uploadFormTextTop and $uploadFormTextAfterSummary to inject
 text (HTML) either before or after the editform.
-&$form: UploadForm object
+&$upload: SpecialUpload object
 
 'UploadFormInitDescriptor': After the descriptor for the upload form as been
 assembled.
@@ -3590,12 +3648,12 @@ being uploaded, use UploadVerifyFile or UploadVerifyUpload.
 $upload: (object) An instance of UploadBase, with all info about the upload
 $user: (object) An instance of User, the user uploading this file
 $props: (array) File properties, as returned by FSFile::getPropsFromPath()
-&$error: output: If the file stashing should be prevented, set this to the reason
-  in the form of array( messagename, param1, param2, ... ) or a MessageSpecifier
-  instance (you might want to use ApiMessage to provide machine-readable details
-  for the API).
+&$error: output: If the file stashing should be prevented, set this to the
+  reason in the form of [ messagename, param1, param2, ... ] or a
+  MessageSpecifier instance (you might want to use ApiMessage to provide machine
+  -readable details for the API).
 
-'UploadVerification': DEPRECATED! Use UploadVerifyFile instead.
+'UploadVerification': DEPRECATED since 1.28! Use UploadVerifyFile instead.
 Additional chances to reject an uploaded file.
 $saveName: (string) destination file name
 $tempName: (string) filesystem path to the temporary file for checks
@@ -3608,10 +3666,10 @@ in most cases over UploadVerification.
 $upload: (object) an instance of UploadBase, with all info about the upload
 $mime: (string) The uploaded file's MIME type, as detected by MediaWiki.
   Handlers will typically only apply for specific MIME types.
-&$error: (object) output: true if the file is valid. Otherwise, set this to the reason
-  in the form of array( messagename, param1, param2, ... ) or a MessageSpecifier
-  instance (you might want to use ApiMessage to provide machine-readable details
-  for the API).
+&$error: (object) output: true if the file is valid. Otherwise, set this to the
+  reason in the form of [ messagename, param1, param2, ... ] or a
+  MessageSpecifier instance (you might want to use ApiMessage to provide machine
+  -readable details for the API).
 
 'UploadVerifyUpload': Upload verification, based on both file properties like
 MIME type (same as UploadVerifyFile) and the information entered by the user
@@ -3622,7 +3680,7 @@ $props: (array) File properties, as returned by FSFile::getPropsFromPath()
 $comment: (string) Upload log comment (also used as edit summary)
 $pageText: (string) File description page text (only used for new uploads)
 &$error: output: If the file upload should be prevented, set this to the reason
-  in the form of array( messagename, param1, param2, ... ) or a MessageSpecifier
+  in the form of [ messagename, param1, param2, ... ] or a MessageSpecifier
   instance (you might want to use ApiMessage to provide machine-readable details
   for the API).
 
@@ -3665,8 +3723,8 @@ messages!" message, return false to not delete it.
 &$user: User (object) that will clear the message
 $oldid: ID of the talk page revision being viewed (0 means the most recent one)
 
-'UserCreateForm': DEPRECATED! Create an AuthenticationProvider instead.
-Manipulate the login form.
+'UserCreateForm': DEPRECATED since 1.27! Create an AuthenticationProvider
+instead. Manipulate the login form.
 &$template: SimpleTemplate instance for the form
 
 'UserEffectiveGroups': Called in User::getEffectiveGroups().
@@ -3693,7 +3751,7 @@ $user: User object
 &$timestamp: timestamp, change this to override local email authentication
   timestamp
 
-'UserGetImplicitGroups': DEPRECATED!
+'UserGetImplicitGroups': DEPRECATED since 1.25!
 Called in User::getImplicitGroups().
 &$groups: List of implicit (automatically-assigned) groups
 
@@ -3759,7 +3817,8 @@ $name: user name
 $user: user object
 &$s: database query object
 
-'UserLoadFromSession': DEPRECATED! Create a MediaWiki\Session\SessionProvider instead.
+'UserLoadFromSession': DEPRECATED since 1.27! Create a
+MediaWiki\Session\SessionProvider instead.
 Called to authenticate users on external/environmental means; occurs before
 session is loaded.
 $user: user object being loaded
@@ -3774,16 +3833,17 @@ $user: User object
 'UserLoggedIn': Called after a user is logged in
 $user: User object for the logged-in user
 
-'UserLoginComplete': Show custom content after a user has logged in via the web interface.
-For functionality that needs to run after any login (API or web) use UserLoggedIn.
+'UserLoginComplete': Show custom content after a user has logged in via the Web
+interface. For functionality that needs to run after any login (API or web) use
+UserLoggedIn.
 &$user: the user object that was created on login
 &$inject_html: Any HTML to inject after the "logged in" message.
-$direct: (bool) The hook is called directly after a successful login. This will only happen once
-  per login. A UserLoginComplete call with direct=false can happen when the user visits the login
-  page while already logged in.
+$direct: (bool) The hook is called directly after a successful login. This will
+  only happen once per login. A UserLoginComplete call with direct=false can
+  happen when the user visits the login page while already logged in.
 
-'UserLoginForm': DEPRECATED! Create an AuthenticationProvider instead.
-Manipulate the login form.
+'UserLoginForm': DEPRECATED since 1.27! Create an AuthenticationProvider
+instead. Manipulate the login form.
 &$template: QuickTemplate instance for the form
 
 'UserLogout': Before a user logs out.
@@ -3801,21 +3861,26 @@ $to: Array of MailAddress objects for the recipients
 
 'UserMailerSplitTo': Called in UserMailer::send() to give extensions a chance
 to split up an email with multiple the To: field into separate emails.
-&$to: array of MailAddress objects; unset the ones which should be mailed separately
+&$to: array of MailAddress objects; unset the ones which should be mailed
+separately
 
-'UserMailerTransformContent': Called in UserMailer::send() to change email contents.
-Extensions can block sending the email by returning false and setting $error.
+'UserMailerTransformContent': Called in UserMailer::send() to change email
+contents. Extensions can block sending the email by returning false and setting
+$error.
 $to: array of MailAdresses of the targets
 $from: MailAddress of the sender
-&$body: email body, either a string (for plaintext emails) or an array with 'text' and 'html' keys
+&$body: email body, either a string (for plaintext emails) or an array with
+  'text' and 'html' keys
 &$error: should be set to an error message string
 
-'UserMailerTransformMessage': Called in UserMailer::send() to change email after it has gone through
-the MIME transform. Extensions can block sending the email by returning false and setting $error.
+'UserMailerTransformMessage': Called in UserMailer::send() to change email after
+it has gone through the MIME transform. Extensions can block sending the email
+by returning false and setting $error.
 $to: array of MailAdresses of the targets
 $from: MailAddress of the sender
 &$subject: email subject (not MIME encoded)
-&$headers: email headers (except To: and Subject:) as an array of header name => value pairs
+&$headers: email headers (except To: and Subject:) as an array of header
+name => value pairs
 &$body: email body (in MIME format) as a string
 &$error: should be set to an error message string
 
@@ -3844,27 +3909,29 @@ message(s).
 &$user: user retrieving new talks messages
 &$talks: array of new talks page(s)
 
-'UserRights': DEPRECATED! Use UserGroupsChanged instead.
+'UserRights': DEPRECATED since 1.26! Use UserGroupsChanged instead.
 After a user's group memberships are changed.
 &$user: User object that was changed
 $add: Array of strings corresponding to groups added
 $remove: Array of strings corresponding to groups removed
 
-'UserSaveOptions': Called just before saving user preferences. Hook handlers can either add or
-manipulate options, or reset one back to it's default to block changing it. Hook handlers are also
-allowed to abort the process by returning false, e.g. to save to a global profile instead. Compare
-to the UserSaveSettings hook, which is called after the preferences have been saved.
+'UserSaveOptions': Called just before saving user preferences. Hook handlers can
+either add or manipulate options, or reset one back to it's default to block
+changing it. Hook handlers are also allowed to abort the process by returning
+false, e.g. to save to a global profile instead. Compare to the UserSaveSettings
+hook, which is called after the preferences have been saved.
 $user: The User for which the options are going to be saved
 &$options: The users options as an associative array, modifiable
 
-'UserSaveSettings': Called directly after user preferences (user_properties in the database) have
-been saved. Compare to the UserSaveOptions hook, which is called before.
+'UserSaveSettings': Called directly after user preferences (user_properties in
+the database) have been saved. Compare to the UserSaveOptions hook, which is
+called before.
 $user: The User for which the options have been saved
 
-'UserSetCookies': DEPRECATED! 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 count on user data being saved to cookies
-versus some other mechanism.
+'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
+count on user data being saved to cookies versus some other mechanism.
 Called when setting user cookies.
 $user: User object
 &$session: session array, will be added to the session
@@ -3893,7 +3960,7 @@ displayed correctly in Special:ListUsers.
 $dbr: Read-only database handle
 $userIds: Array of user IDs whose groups we should look up
 &$cache: Array of user ID -> (array of internal group name (e.g. 'sysop') ->
-UserGroupMembership object)
+  UserGroupMembership object)
 &$groups: Array of group name -> bool true mappings for members of a given user
 group
 
@@ -3968,15 +4035,15 @@ dumps. One, and only one hook should set this, and return false.
 &$opts: Options to use for the query
 &$join: Join conditions
 
-'WikiPageDeletionUpdates': manipulate the list of DeferrableUpdates to be applied when
-a page is deleted. Called in WikiPage::getDeletionUpdates(). Note that updates
-specific to a content model should be provided by the respective Content's
-getDeletionUpdates() method.
+'WikiPageDeletionUpdates': manipulate the list of DeferrableUpdates to be
+applied when a page is deleted. Called in WikiPage::getDeletionUpdates(). Note
+that updates specific to a content model should be provided by the respective
+Content's getDeletionUpdates() method.
 $page: the WikiPage
-$content: the Content to generate updates for, or null in case the page revision could not be
-  loaded. The delete will succeed despite this.
-&$updates: the array of objects that implement DeferrableUpdate. Hook function may want to add to
-  it.
+$content: the Content to generate updates for, or null in case the page revision
+  could not be loaded. The delete will succeed despite this.
+&$updates: the array of objects that implement DeferrableUpdate. Hook function
+  may want to add to it.
 
 'WikiPageFactory': Override WikiPage class used for a title
 $title: Title of the page
index 8c59e72..1e68fb7 100644 (file)
@@ -80,18 +80,15 @@ usage evenly), make its entry a subarray:
 MediaWiki uses a fork of Ryan T. Dean's pure-PHP memcached client.
 It also supports the PECL PHP extension for memcached.
 
-MediaWiki uses three object for object caching:
-* $wgMemc, controlled by $wgMainCacheType
-* $parserMemc, controlled by $wgParserCacheType
-* $messageMemc, controlled by $wgMessageCacheType
-If you set CACHE_NONE to one of the three control variable, (default
-value for $wgMainCacheType), MediaWiki still create a MemCacheClient,
-but requests to it are no-ops and we always fall through to the
-database. If the cache daemon can't be contacted, it should also
-disable itself fairly smoothly.
-
-By default, $wgMemc is used but when it is $parserMemc or $messageMemc
-this is mentioned below.
+MediaWiki uses the ObjectCache class to retrieve instances of
+BagOStuff by purpose, controlled by the following variables:
+* $wgMainCacheType
+* $wgParserCacheType
+* $wgMessageCacheType
+
+If you set one of these to CACHE_NONE, MediaWiki still creates a
+BagOStuff object, but calls it to it are no-ops. If the cache daemon
+can't be contacted, it should also disable itself fairly smoothly.
 
 == Keys used ==
 
@@ -134,7 +131,7 @@ Localisation:
        cleared by: Language::loadLocalisation()
 
 Message Cache:
-       stored in: $messageMemc
+       backend: $wgMessageCacheType
        key: $wgDBname:messages, $wgDBname:messages-hash, $wgDBname:messages-status
        ex: wikidb:messages, wikidb:messages-hash, wikidb:messages-status
        stores: an array where the keys are DB keys and the values are messages
@@ -151,7 +148,8 @@ Newtalk:
        expiry: 30 minutes
 
 Parser Cache:
-       stored in: $parserMemc
+       access: ParserCache
+       backend: $wgParserCacheType
        key: $wgDBname:pcache:idhash:$pageid-$renderkey!$hash
                $pageid: id of the page
                $renderkey: 1 if action=render, 0 otherwise
@@ -205,7 +203,7 @@ Sessions:
        cleared by: session_destroy()
 
 Sidebar:
-       stored in: $parserMemc
+       access: WANObjectCache
        controlled by: $wgEnableSidebarCache
        key: $wgDBname:sidebar
        ex: wikidb:sidebar
@@ -221,7 +219,7 @@ Special:Allpages:
        cleared by: nothing
 
 Special:Recentchanges (feed):
-       stored in: $messageMemc
+       backend: $wgMessageCacheType
        key: $wgDBname:rcfeed:$format:$limit:$hideminor:$target and
                rcfeed:$format:timestamp
        ex: wikidb:rcfeed:rss:50:: and rcfeed:rss:timestamp
diff --git a/docs/pageupdater.txt b/docs/pageupdater.txt
new file mode 100644 (file)
index 0000000..4980c92
--- /dev/null
@@ -0,0 +1,191 @@
+This document provides an overview of the usage of PageUpdater and DerivedPageDataUpdater.
+
+== PageUpdater ==
+PageUpdater is the canonical way to create page revisions, that is, to perform edits.
+
+PageUpdater is a stateful, handle-like object that allows new revisions to be created
+on a given wiki page using the saveRevision() method. PageUpdater provides setters for
+defining the new revision's content as well as meta-data such as change tags. saveRevision()
+stores the new revision's primary content and metadata, and triggers the necessary
+updates to derived secondary data and cached artifacts e.g. in the ParserCache and the
+CDN layer, using a DerivedPageDataUpdater.
+
+PageUpdater instances follow the below life cycle, defined by a number of
+methods:
+
+                          +----------------------------+
+                          |                            |
+                          |             new            |
+                          |                            |
+                          +------|--------------|------+
+                                 |              |
+            grabParentRevision()-|              |
+            or hasEditConflict()-|              |
+                                 |              |
+                        +--------v-------+      |
+                        |                |      |
+                        |  parent known  |      |
+                        |                |      |
+  Enables---------------+--------|-------+      |
+    safe operations based on     |              |-saveRevision()
+    the parent revision, e.g.    |              |
+    section replacement or       |              |
+    edit conflict resolution.    |              |
+                                 |              |
+                  saveRevision()-|              |
+                                 |              |
+                          +------v--------------v------+
+                          |                            |
+                          |      creation committed    |
+                          |                            |
+  Enables-----------------+----------------------------+
+    wasSuccess()
+    isUnchanged()
+    isNew()
+    getState()
+    getNewRevision()
+    etc.
+
+The stateful nature of PageUpdater allows it to be used to safely perform
+transformations that depend on the new revision's parent revision, such as replacing
+sections or applying 3-way conflict resolution, while protecting against race
+conditions using a compare-and-swap (CAS) mechanism: after calling code used the
+grabParentRevision() method to access the edit's logical parent, PageUpdater
+remembers that revision, and ensure that that revision is still the page's current
+revision when performing the atomic database update for the revision's primary
+meta-data when saveRevision() is called. If another revision was created concurrently,
+saveRevision() will fail, indicating the problem with the "edit-conflict" code in the status
+object.
+
+Typical usage for programmatic revision creation (with $page being a WikiPage as of 1.32, to be
+replaced by a repository service later):
+
+  $updater = $page->newPageUpdater( $user );
+  $updater->setContent( 'main', $content );
+  $updater->setRcPatrolStatus( RecentChange::PRC_PATROLLED );
+  $newRev = $updater->saveRevision( $comment );
+
+Usage with content depending on the parent revision
+
+  $updater = $page->newPageUpdater( $user );
+  $parent = $updater->grabParentRevision();
+  $content = $parent->getContent( 'main' )->replaceSection( $section, $sectionContent );
+  $updater->setContent( 'main', $content );
+  $newRev = $updater->saveRevision( $comment, EDIT_UPDATE );
+
+In both cases, all secondary updates will be triggered automatically.
+
+== DerivedPageDataUpdater ==
+DerivedPageDataUpdater is a stateful, handle-like object that caches derived data representing
+a revision, and can trigger updates of cached copies of that data, e.g. in the links tables,
+page_props, the ParserCache, and the CDN layer.
+
+DerivedPageDataUpdater is used by PageUpdater when creating new revisions, but can also
+be used independently when performing meta data updates during undeletion, import, or
+when puring a page. It's a stepping stone on the way to a more complete refactoring of WikiPage.
+
+NOTE: Avoid direct usage of DerivedPageDataUpdater. In the future, we want to define interfaces
+for the different use cases of DerivedPageDataUpdater, particularly providing access to post-PST
+content and ParserOutput to callbacks during revision creation, which currently use
+WikiPage::prepareContentForEdit, and allowing updates to be triggered on purge, import, and
+undeletion, which currently use WikiPage::doEditUpdates() and Content::getSecondaryDataUpdates().
+
+The primary reason for DerivedPageDataUpdater to be stateful is internal caching of state
+that avoids the re-generation of ParserOutput and re-application of pre-save-
+transformations (PST).
+
+DerivedPageDataUpdater instances follow the below life cycle, defined by a number of
+methods:
+
+                       +---------------------------------------------------------------------+
+                       |                                                                     |
+                       |                                 new                                 |
+                       |                                                                     |
+                       +---------------|------------------|------------------|---------------+
+                                       |                  |                  |
+                 grabCurrentRevision()-|                  |                  |
+                                       |                  |                  |
+                           +-----------v----------+       |                  |
+                           |                      |       |-prepareContent() |
+                           |    knows current     |       |                  |
+                           |                      |       |                  |
+  Enables------------------+-----|-----|----------+       |                  |
+    pageExisted()                |     |                  |                  |
+    wasRedirect()                |     |-prepareContent() |                  |-prepareUpdate()
+                                 |     |                  |                  |
+                                 |     |    +-------------v------------+     |
+                                 |     |    |                          |     |
+                                 |     +---->        has content       |     |
+                                 |          |                          |     |
+  Enables------------------------|----------+--------------------------+     |
+    isChange()                   |                              |            |
+    isCreation()                 |-prepareUpdate()              |            |
+    getSlots()                   |              prepareUpdate()-|            |
+    getTouchedSlotRoles()        |                              |            |
+    getCanonicalParserOutput()   |                  +-----------v------------v-----------------+
+                                 |                  |                                          |
+                                 +------------------>                 has revision             |
+                                                    |                                          |
+  Enables-------------------------------------------+------------------------|-----------------+
+    updateParserCache()                                                      |
+    runSecondaryDataUpdates()                                                |-doUpdates()
+                                                                             |
+                                                                 +-----------v---------+
+                                                                 |                     |
+                                                                 |     updates done    |
+                                                                 |                     |
+                                                                 +---------------------+
+
+
+- grabCurrentRevision() returns the logical parent revision of the target revision. It is
+guaranteed to always return the same revision for a given DerivedPageDataUpdater instance.
+If called before prepareUpdate(), this fixates the logical parent to be the page's current
+revision. If called for the first time after prepareUpdate(), it returns the revision
+passed as the 'oldrevision' option to prepareUpdate(), or, if that wasn't given, the
+parent of $revision parameter passed to prepareUpdate().
+
+- prepareContent() is called before the new revision is created, to apply pre-save-
+transformation (PST) and allow subsequent access to the canonical ParserOutput of the
+revision. getSlots() and getCanonicalParserOutput() as well as getSecondaryDataUpdates()
+may be used after prepareContent() was called. Calling prepareContent() with the same
+parameters again has no effect. Calling it again with mismatching paramters, or calling
+it after prepareUpdate() was called, triggers a LogicException.
+
+- prepareUpdate() is called after the new revision has been created. This may happen
+right after the revision was created, on the same instance on which prepareContent() was
+called, or later (possibly much later), on a fresh instance in a different process,
+due to deferred or asynchronous updates, or during import, undeletion, purging, etc.
+prepareUpdate() is required before a call to doUpdates(), and it also enables calls to
+getSlots() and getCanonicalParserOutput() as well as getSecondaryDataUpdates().
+Calling prepareUpdate() with the same parameters again has no effect.
+Calling it again with mismatching parameters, or calling it with parameters mismatching
+the ones prepareContent() was called with, triggers a LogicException.
+
+- getSecondaryDataUpdtes() returns DataUpdates that represent derived data for the revision.
+These may be used to update such data, e.g. in ApiPurge, RefreshLinksJob, and the refreshLinks
+script.
+
+- doUpdates() triggers the updates defined by getSecondaryDataUpdtes(), and also causes
+updates to cached artifacts in the ParserCache, the CDN layer, etc. This is primarily
+used by PageUpdater, but also by PageArchive during undeletion, and when importing
+revisions from XML. doUpdates() can only be called after prepareUpdate() was used to
+initialize the DerivedPageDataUpdater instance for a specific revision. Calling it before
+prepareUpdate() is called raises a LogicException.
+
+A DerivedPageDataUpdater instance is intended to be re-used during different stages
+of complex update operations that often involve callbacks to extension code via
+MediaWiki's hook mechanism, or deferred or even asynchronous execution of Jobs and
+DeferredUpdates. Since these mechanisms typically do not provide a way to pass a
+DerivedPageDataUpdater directly, WikiPage::getDerivedPageDataUpdater() has to be used to
+obtain a DerivedPageDataUpdater for the update currently in progress - re-using the
+same DerivedPageDataUpdater if possible avoids re-generation of ParserOutput objects
+and other expensively derived artifacts.
+
+This mechanism for re-using a DerivedPageDataUpdater instance without passing it directly
+requires a way to ensure that a given DerivedPageDataUpdater instance can actually be used
+in the calling code's context. For this purpose, WikiPage::getDerivedPageDataUpdater()
+calls the isReusableFor() method on DerivedPageDataUpdater, which ensures that the given
+instance is applicable to the given parameters. In other words, isReusableFor() predicts
+whether calling prepareContent() or prepareUpdate() with a given set of parameters will
+trigger a LogicException. In that case, WikiPage::getDerivedPageDataUpdater() creates a
+fresh DerivedPageDataUpdater instance.
index 0b4e0bd..8dff602 100644 (file)
@@ -58,7 +58,7 @@ These can also be customised on a per-user basis, by editing
 
 Several custom skins are available as of 2014.
 
-https://www.mediawiki.org/wiki/Category:All_skins
+https://www.mediawiki.org/wiki/Special:MyLanguage/Category:All_skins
 
 Installing a skin requires adding its files in a subdirectory under skins/ and
 adding an appropriate require_once line to LocalSettings.php, similarly to how
diff --git a/docs/uidesign/table-layout.html b/docs/uidesign/table-layout.html
deleted file mode 100644 (file)
index 2c26819..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-       <style>
-               /** This is just for coloring: */
-               table { border: 1px solid #CC0; }
-               td { border: 1px solid  #CCC; }
-
-               table {
-                       width: 100%;
-                       table-layout: fixed;
-               }
-
-               #first {
-                       width: 300px;
-               }
-       </style>
-</head>
-<body>
-
-<p>
-This play with table-layout:fixed; and applying the width to colgroup or col element. Firefox only recongize the width if it is applied on col element!</p>
-<p>
-On a perfect browser, both tables should look the same</p>
-
-<dl>
-       <dt>colgroup</dt>
-       <dd>300 px width is applied to the first colgroup element</dd>
-</dl>
-<div style="width: 400px;">
-<table>
-       <colgroup id="first" /></colgroup>
-       <colgroup id="second"/></colgroup>
-       <colgroup id="third" /></colgroup>
-       <tr>
-               <td>Very long?</td>
-               <td>#</td>
-               <td>$</td>
-       </tr>
-</table>
-</div>
-
-<dl>
-       <dt>col</dt>
-       <dd>Each colgroup has an additional col element. The first col element is applied the 300 px width</dd>
-</dl>
-
-<div style="width: 400px;">
-<table>
-       <colgroup><col id="first" /></colgroup>
-       <colgroup><col id="second"/></colgroup>
-       <colgroup><col id="third" /></colgroup>
-       <tr>
-               <td>Very long?</td>
-               <td>#</td>
-               <td>$</td>
-       </tr>
-</table>
-</div>
index 2052809..ca69d31 100644 (file)
@@ -17,7 +17,8 @@
  *  just that it was. If you want to change this, you can set $wgImgAuthDetails to 'true'
  *  in localsettings.php and it will give the user the reason why access was denied.
  *
- * Your server needs to support PATH_INFO; CGI-based configurations usually don't.
+ * Your server needs to support REQUEST_URI or PATH_INFO; CGI-based
+ * configurations sometimes don't.
  *
  * 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
index 35b556d..5f825c8 100644 (file)
@@ -76,7 +76,7 @@ class AjaxDispatcher {
 
                switch ( $this->mode ) {
                        case 'get':
-                               $this->func_name = isset( $_GET["rs"] ) ? $_GET["rs"] : '';
+                               $this->func_name = $_GET["rs"] ?? '';
                                if ( !empty( $_GET["rsargs"] ) ) {
                                        $this->args = $_GET["rsargs"];
                                } else {
@@ -84,7 +84,7 @@ class AjaxDispatcher {
                                }
                                break;
                        case 'post':
-                               $this->func_name = isset( $_POST["rs"] ) ? $_POST["rs"] : '';
+                               $this->func_name = $_POST["rs"] ?? '';
                                if ( !empty( $_POST["rsargs"] ) ) {
                                        $this->args = $_POST["rsargs"];
                                } else {
index 3e42c08..0c11505 100644 (file)
@@ -242,7 +242,7 @@ class AjaxResponse {
                        # this breaks strtotime().
                        $modsince = preg_replace( '/;.*$/', '', $_SERVER["HTTP_IF_MODIFIED_SINCE"] );
                        $modsinceTime = strtotime( $modsince );
-                       $ismodsince = wfTimestamp( TS_MW, $modsinceTime ? $modsinceTime : 1 );
+                       $ismodsince = wfTimestamp( TS_MW, $modsinceTime ?: 1 );
                        wfDebug( "$fname: -- client send If-Modified-Since: $modsince", 'private' );
                        wfDebug( "$fname: --  we might send Last-Modified : $lastmod", 'private' );
 
index b73ecbd..e12db24 100644 (file)
@@ -96,11 +96,7 @@ class AuthPlugin {
         * @return string
         */
        public function getDomain() {
-               if ( isset( $this->domain ) ) {
-                       return $this->domain;
-               } else {
-                       return 'invaliddomain';
-               }
+               return $this->domain ?? 'invaliddomain';
        }
 
        /**
index 6e77056..9fc063a 100644 (file)
@@ -123,12 +123,22 @@ class AutoLoader {
         *
         * @see <http://www.php-fig.org/psr/psr-4/>
         * @private Only public for usage in AutoloadGenerator
+        * @codeCoverageIgnore
         * @since 1.31
         * @return string[]
         */
        public static function getAutoloadNamespaces() {
                return [
-                       'MediaWiki\\Linker\\' => __DIR__ .'/linker/'
+                       'MediaWiki\\Edit\\' => __DIR__ . '/edit/',
+                       'MediaWiki\\EditPage\\' => __DIR__ . '/editpage/',
+                       'MediaWiki\\Linker\\' => __DIR__ .'/linker/',
+                       'MediaWiki\\Preferences\\' => __DIR__ .'/preferences/',
+                       'MediaWiki\\Services\\' => __DIR__ .'/services/',
+                       'MediaWiki\\Session\\' => __DIR__ .'/session/',
+                       'MediaWiki\\Shell\\' => __DIR__ .'/shell/',
+                       'MediaWiki\\Sparql\\' => __DIR__ .'/sparql/',
+                       'MediaWiki\\Storage\\' => __DIR__ .'/Storage/',
+                       'MediaWiki\\Tidy\\' => __DIR__ .'/tidy/',
                ];
        }
 }
index 2ce1f3e..a7d89e2 100644 (file)
@@ -224,7 +224,7 @@ class Block {
                        'ipb_address',
                        'ipb_by',
                        'ipb_by_text',
-                       'ipb_by_actor' => $wgActorTableSchemaMigrationStage > MIGRATION_OLD ? 'ipb_by_actor' : null,
+                       'ipb_by_actor' => $wgActorTableSchemaMigrationStage > MIGRATION_OLD ? 'ipb_by_actor' : 'NULL',
                        'ipb_timestamp',
                        'ipb_auto',
                        'ipb_anon_only',
@@ -299,7 +299,7 @@ class Block {
         *     1) A block directly on the given user or IP
         *     2) A rangeblock encompassing the given IP (smallest first)
         *     3) An autoblock on the given IP
-        * @param User|string $vagueTarget Also search for blocks affecting this target.  Doesn't
+        * @param User|string|null $vagueTarget Also search for blocks affecting this target.  Doesn't
         *     make any sense to use TYPE_AUTO / TYPE_ID here. Leave blank to skip IP lookups.
         * @throws MWException
         * @return bool Whether a relevant block was found
@@ -405,7 +405,7 @@ class Block {
        /**
         * Get a set of SQL conditions which will select rangeblocks encompassing a given range
         * @param string $start Hexadecimal IP representation
-        * @param string $end Hexadecimal IP representation, or null to use $start = $end
+        * @param string|null $end Hexadecimal IP representation, or null to use $start = $end
         * @return string
         */
        public static function getRangeCond( $start, $end = null ) {
@@ -458,7 +458,7 @@ class Block {
        protected function initFromRow( $row ) {
                $this->setTarget( $row->ipb_address );
                $this->setBlocker( User::newFromAnyId(
-                       $row->ipb_by, $row->ipb_by_text, isset( $row->ipb_by_actor ) ? $row->ipb_by_actor : null
+                       $row->ipb_by, $row->ipb_by_text, $row->ipb_by_actor ?? null
                ) );
 
                $this->mTimestamp = wfTimestamp( TS_MW, $row->ipb_timestamp );
@@ -519,7 +519,7 @@ class Block {
         * Insert a block into the block table. Will fail if there is a conflicting
         * block (same name and options) already in the database.
         *
-        * @param IDatabase $dbw If you have one available
+        * @param IDatabase|null $dbw If you have one available
         * @return bool|array False on failure, assoc array on success:
         *      ('id' => block ID, 'autoIds' => array of autoblock IDs)
         */
@@ -1162,7 +1162,7 @@ class Block {
         *     Calling this with a user, IP address or range will not select autoblocks, and will
         *     only select a block where the targets match exactly (so looking for blocks on
         *     1.2.3.4 will not select 1.2.0.0/16 or even 1.2.3.4/32)
-        * @param string|User|int $vagueTarget As above, but we will search for *any* block which
+        * @param string|User|int|null $vagueTarget As above, but we will search for *any* block which
         *     affects that target (so for an IP address, get ranges containing that IP; and also
         *     get any relevant autoblocks). Leave empty or blank to skip IP-based lookups.
         * @param bool $fromMaster Whether to use the DB_MASTER database
@@ -1641,7 +1641,7 @@ class Block {
                        $reason,
                        $context->getRequest()->getIP(),
                        $this->getByName(),
-                       $systemBlockType !== null ? $systemBlockType : $this->getId(),
+                       $systemBlockType ?? $this->getId(),
                        $lang->formatExpiry( $this->mExpiry ),
                        (string)$intended,
                        $lang->userTimeAndDate( $this->mTimestamp, $context->getUser() ),
index 46b86d8..3352c2c 100644 (file)
@@ -48,7 +48,7 @@ class Category {
 
        /**
         * Set up all member variables using a database query.
-        * @param int $mode
+        * @param int $mode One of (Category::LOAD_ONLY, Category::LAZY_INIT_ROW)
         * @throws MWException
         * @return bool True on success, false on failure.
         */
@@ -171,7 +171,7 @@ class Category {
         *   fields are null, the resulting Category object will represent an empty
         *   category if a title object was given. If the fields are null and no
         *   title was given, this method fails and returns false.
-        * @param Title $title Optional title object for the category represented by
+        * @param Title|null $title Optional title object for the category represented by
         *   the given row. May be provided if it is already known, to avoid having
         *   to re-create a title object later.
         * @return Category|false
@@ -335,6 +335,10 @@ class Category {
 
                $dbw->startAtomic( __METHOD__ );
 
+               // Lock the `category` row before locking `categorylinks` rows to try
+               // to avoid deadlocks with LinksDeletionUpdate (T195397)
+               $dbw->lockForUpdate( 'category', [ 'cat_title' => $this->mName ], __METHOD__ );
+
                // Lock all the `categorylinks` records and gaps for this category;
                // this is a separate query due to postgres/oracle limitations
                $dbw->selectRowCount(
@@ -416,4 +420,45 @@ class Category {
 
                return true;
        }
+
+       /**
+        * Call refreshCounts() if there are no entries in the categorylinks table
+        * or if the category table has a row that states that there are no entries
+        *
+        * Due to lock errors or other failures, the precomputed counts can get out of sync,
+        * making it hard to know when to delete the category row without checking the
+        * categorylinks table.
+        *
+        * @return bool Whether links were refreshed
+        * @since 1.32
+        */
+       public function refreshCountsIfEmpty() {
+               $dbw = wfGetDB( DB_MASTER );
+
+               $hasLink = $dbw->selectField(
+                       'categorylinks',
+                       '1',
+                       [ 'cl_to' => $this->getName() ],
+                       __METHOD__
+               );
+               if ( !$hasLink ) {
+                       $this->refreshCounts(); // delete any category table entry
+
+                       return true;
+               }
+
+               $hasBadRow = $dbw->selectField(
+                       'category',
+                       '1',
+                       [ 'cat_title' => $this->getName(), 'cat_pages <= 0' ],
+                       __METHOD__
+               );
+               if ( $hasBadRow ) {
+                       $this->refreshCounts(); // clean up this row
+
+                       return true;
+               }
+
+               return false;
+       }
 }
index 4202249..79ab8b4 100644 (file)
@@ -581,7 +581,7 @@ class CategoryViewer extends ContextSource {
 
                foreach ( $colContents as $char => $articles ) {
                        # Change space to non-breaking space to keep headers aligned
-                       $h3char = $char === ' ' ? '&#160;' : htmlspecialchars( $char );
+                       $h3char = $char === ' ' ? "\u{00A0}" : htmlspecialchars( $char );
 
                        $ret .= '<div class="mw-category-group"><h3>' . $h3char;
                        $ret .= "</h3>\n";
index e9b08e8..d03a00e 100644 (file)
@@ -138,7 +138,7 @@ class CommentStore {
         * @return string
         */
        private function getKey( $methodKey = null ) {
-               $key = $this->key !== null ? $this->key : $methodKey;
+               $key = $this->key ?? $methodKey;
                if ( $key === null ) {
                        // @codeCoverageIgnoreStart
                        throw new InvalidArgumentException( '$key should not be null' );
@@ -158,7 +158,7 @@ class CommentStore {
         *
         * @since 1.30
         * @since 1.31 Method signature changed, $key parameter added (with deprecated back compat)
-        * @param string $key A key such as "rev_comment" identifying the comment
+        * @param string|null $key A key such as "rev_comment" identifying the comment
         *  field being fetched.
         * @return string[] to include in the `$vars` to `IDatabase->select()`. All
         *  fields are aliased, so `+` is safe to use.
@@ -191,7 +191,7 @@ class CommentStore {
         *
         * @since 1.30
         * @since 1.31 Method signature changed, $key parameter added (with deprecated back compat)
-        * @param string $key A key such as "rev_comment" identifying the comment
+        * @param string|null $key A key such as "rev_comment" identifying the comment
         *  field being fetched.
         * @return array With three keys:
         *   - tables: (string[]) to include in the `$table` to `IDatabase->select()`
@@ -261,7 +261,7 @@ class CommentStore {
        private function getCommentInternal( IDatabase $db = null, $key, $row, $fallback = false ) {
                $row = (array)$row;
                if ( array_key_exists( "{$key}_text", $row ) && array_key_exists( "{$key}_data", $row ) ) {
-                       $cid = isset( $row["{$key}_cid"] ) ? $row["{$key}_cid"] : null;
+                       $cid = $row["{$key}_cid"] ?? null;
                        $text = $row["{$key}_text"];
                        $data = $row["{$key}_data"];
                } elseif ( $this->stage === MIGRATION_OLD ) {
@@ -381,7 +381,7 @@ class CommentStore {
         * @since 1.31 Method signature changed, $key parameter added (with deprecated back compat)
         * @param string $key A key such as "rev_comment" identifying the comment
         *  field being fetched.
-        * @param object|array $row Result row.
+        * @param object|array|null $row Result row.
         * @param bool $fallback If true, fall back as well as possible instead of throwing an exception.
         * @return CommentStoreComment
         */
@@ -415,7 +415,7 @@ class CommentStore {
         * @param IDatabase $db Database handle to use for lookup
         * @param string $key A key such as "rev_comment" identifying the comment
         *  field being fetched.
-        * @param object|array $row Result row.
+        * @param object|array|null $row Result row.
         * @param bool $fallback If true, fall back as well as possible instead of throwing an exception.
         * @return CommentStoreComment
         */
@@ -458,16 +458,7 @@ class CommentStore {
                $comment = CommentStoreComment::newUnsavedComment( $comment, $data );
 
                # Truncate comment in a Unicode-sensitive manner
-               $comment->text = $this->lang->truncate( $comment->text, self::MAX_COMMENT_LENGTH );
-               if ( mb_strlen( $comment->text, 'UTF-8' ) > self::COMMENT_CHARACTER_LIMIT ) {
-                       $ellipsis = wfMessage( 'ellipsis' )->inLanguage( $this->lang )->escaped();
-                       if ( mb_strlen( $ellipsis ) >= self::COMMENT_CHARACTER_LIMIT ) {
-                               // WTF?
-                               $ellipsis = '...';
-                       }
-                       $maxLength = self::COMMENT_CHARACTER_LIMIT - mb_strlen( $ellipsis, 'UTF-8' );
-                       $comment->text = mb_substr( $comment->text, 0, $maxLength, 'UTF-8' ) . $ellipsis;
-               }
+               $comment->text = $this->lang->truncateForVisual( $comment->text, self::COMMENT_CHARACTER_LIMIT );
 
                if ( $this->stage > MIGRATION_OLD && !$comment->id ) {
                        $dbData = $comment->data;
@@ -530,7 +521,7 @@ class CommentStore {
                $comment = $this->createComment( $dbw, $comment, $data );
 
                if ( $this->stage <= MIGRATION_WRITE_BOTH ) {
-                       $fields[$key] = $this->lang->truncate( $comment->text, 255 );
+                       $fields[$key] = $this->lang->truncateForDatabase( $comment->text, 255 );
                }
 
                if ( $this->stage >= MIGRATION_WRITE_BOTH ) {
@@ -567,7 +558,7 @@ class CommentStore {
         * @param IDatabase $dbw Database handle to insert on
         * @param string $key A key such as "rev_comment" identifying the comment
         *  field being fetched.
-        * @param string|Message|CommentStoreComment $comment As for `self::createComment()`
+        * @param string|Message|CommentStoreComment|null $comment As for `self::createComment()`
         * @param array|null $data As for `self::createComment()`
         * @return array Fields for the insert or update
         */
@@ -606,7 +597,7 @@ class CommentStore {
         * @param IDatabase $dbw Database handle to insert on
         * @param string $key A key such as "rev_comment" identifying the comment
         *  field being fetched.
-        * @param string|Message|CommentStoreComment $comment As for `self::createComment()`
+        * @param string|Message|CommentStoreComment|null $comment As for `self::createComment()`
         * @param array|null $data As for `self::createComment()`
         * @return array Two values:
         *  - array Fields for the insert or update
index 66a3535..91117f4 100644 (file)
@@ -171,7 +171,6 @@ class ContentSecurityPolicy {
 
                $additionalSelfUrls = $this->getAdditionalSelfUrls();
                $additionalSelfUrlsScript = $this->getAdditionalSelfUrlsScript();
-               $nonceSrc = "'nonce-" . $this->nonce . "'";
 
                // If no default-src is sent at all, it
                // seems browsers (or at least some), interpret
@@ -183,7 +182,11 @@ class ContentSecurityPolicy {
                $cssSrc = false;
                $imgSrc = false;
                $scriptSrc = [ "'unsafe-eval'", "'self'" ];
-               if ( $mode !== self::FULL_MODE_RESTRICTED ) {
+               if (
+                       $mode !== self::FULL_MODE_RESTRICTED &&
+                       ( !isset( $policyConfig['useNonces'] ) || $policyConfig['useNonces'] )
+               ) {
+                       $nonceSrc = "'nonce-" . $this->nonce . "'";
                        $scriptSrc[] = $nonceSrc;
                }
                $scriptSrc = array_merge( $scriptSrc, $additionalSelfUrlsScript );
@@ -518,13 +521,28 @@ class ContentSecurityPolicy {
        }
 
        /**
-        * Is CSP currently enabled (i.e. Should we set nonce attribute)
+        * Should we set nonce attribute
         *
         * @param Config $config Configuration object
         * @return bool
         */
-       public static function isEnabled( Config $config ) {
-               return $config->get( 'CSPHeader' ) !== false
-                       || $config->get( 'CSPReportOnlyHeader' ) !== false;
+       public static function isNonceRequired( Config $config ) {
+               $configs = [
+                       $config->get( 'CSPHeader' ),
+                       $config->get( 'CSPReportOnlyHeader' )
+               ];
+               foreach ( $configs as $headerConfig ) {
+                       if (
+                               $headerConfig === true ||
+                               ( is_array( $headerConfig ) &&
+                               !isset( $headerConfig['useNonces'] ) ) ||
+                               ( is_array( $headerConfig ) &&
+                               isset( $headerConfig['useNonces'] ) &&
+                               $headerConfig['useNonces'] )
+                       ) {
+                               return true;
+                       }
+               }
+               return false;
        }
 }
index 87ca016..27769f9 100644 (file)
@@ -377,7 +377,13 @@ $wgActionPaths = [];
  */
 
 /**
- * Uploads have to be specially set up to be secure
+ * Allow users to upload files.
+ *
+ * Use $wgLocalFileRepo to control how and where uploads are stored.
+ * Disabled by default as for security reasons.
+ * See <https://www.mediawiki.org/wiki/Manual:Configuring_file_uploads>.
+ *
+ * @since 1.5
  */
 $wgEnableUploads = false;
 
@@ -491,8 +497,8 @@ $wgImgAuthUrlPathMap = [];
  *   - scriptDirUrl      URL of the MediaWiki installation, equivalent to $wgScriptPath, e.g.
  *                       https://en.wikipedia.org/w
  *   - articleUrl        Equivalent to $wgArticlePath, e.g. https://en.wikipedia.org/wiki/$1
- *   - fetchDescription  Fetch the text of the remote file description page. Equivalent to
- *                       $wgFetchCommonsDescriptions.
+ *   - fetchDescription  Fetch the text of the remote file description page and display them
+ *                       on the local wiki.
  *   - abbrvThreshold    File names over this size will use the short form of thumbnail names.
  *                       Short thumbnail names only have the width, parameters, and the extension.
  *
@@ -500,7 +506,8 @@ $wgImgAuthUrlPathMap = [];
  *   - dbType, dbServer, dbUser, dbPassword, dbName, dbFlags
  *                       equivalent to the corresponding member of $wgDBservers
  *   - tablePrefix       Table prefix, the foreign wiki's $wgDBprefix
- *   - hasSharedCache    True if the wiki's shared cache is accessible via the local $wgMemc
+ *   - hasSharedCache    Set to true if the foreign wiki's $wgMainCacheType is identical to,
+ *                       and accesible from, this wiki.
  *
  * ForeignAPIRepo:
  *   - apibase              Use for the foreign API's URL
@@ -518,17 +525,133 @@ $wgImgAuthUrlPathMap = [];
 $wgLocalFileRepo = false;
 
 /**
+ * Enable the use of files from one or more other wikis.
+ *
+ * If you operate multiple wikis, you can declare a shared upload path here.
+ * Uploads to the local wiki will NOT be stored here - See $wgLocalFileRepo
+ * and $wgUploadDirectory for that.
+ *
+ * The wiki will only consider the foreign repository if no file of the given name
+ * is found in the local repository (e.g. via `[[File:..]]` syntax).
+ *
+ * @since 1.11
  * @see $wgLocalFileRepo
  */
 $wgForeignFileRepos = [];
 
 /**
- * Use Commons as a remote file repository. Essentially a wrapper, when this
- * is enabled $wgForeignFileRepos will point at Commons with a set of default
- * settings
+ * Use Wikimedia Commons as a foreign file repository.
+ *
+ * This is a shortcut for adding an entry to to $wgForeignFileRepos
+ * for https://commons.wikimedia.org, using ForeignAPIRepo with the
+ * default settings.
+ *
+ * @since 1.16
  */
 $wgUseInstantCommons = false;
 
+/**
+ * Shortcut for adding an entry to $wgForeignFileRepos.
+ *
+ * Uses the folowing variables:
+ *
+ * - directory: $wgSharedUploadDirectory.
+ * - url: $wgSharedUploadPath.
+ * - hashLevels: Based on $wgHashedSharedUploadDirectory.
+ * - thumbScriptUrl: $wgSharedThumbnailScriptPath.
+ * - transformVia404: Based on $wgGenerateThumbnailOnParse.
+ * - descBaseUrl: $wgRepositoryBaseUrl.
+ * - fetchDescription: $wgFetchCommonsDescriptions.
+ *
+ * If $wgSharedUploadDBname is set, it uses the ForeignDBRepo
+ * class, with also the following variables:
+ *
+ * - dbName: $wgSharedUploadDBname.
+ * - dbType: $wgDBtype.
+ * - dbServer: $wgDBserver.
+ * - dbUser: $wgDBuser.
+ * - dbPassword: $wgDBpassword.
+ * - dbFlags: Based on $wgDebugDumpSql.
+ * - tablePrefix: $wgSharedUploadDBprefix,
+ * - hasSharedCache: $wgCacheSharedUploads.
+ *
+ * @var bool
+ * @since 1.3
+ */
+$wgUseSharedUploads = false;
+
+/**
+ * Shortcut for the 'directory' setting of $wgForeignFileRepos.
+ * Only used if $wgUseSharedUploads is enabled.
+ *
+ * @var string
+ * @since 1.3
+ */
+$wgSharedUploadDirectory = null;
+
+/**
+ * Shortcut for the 'url' setting of $wgForeignFileRepos.
+ * Only used if $wgUseSharedUploads is enabled.
+ *
+ * @var string
+ * @since 1.3
+ */
+$wgSharedUploadPath = null;
+
+/**
+ * Shortcut for the 'hashLevels' setting of $wgForeignFileRepos.
+ * Only used if $wgUseSharedUploads is enabled.
+ *
+ * @var bool
+ * @since 1.3
+ */
+$wgHashedSharedUploadDirectory = true;
+
+/**
+ * Shortcut for the 'descBaseUrl' setting of $wgForeignFileRepos.
+ * Only used if $wgUseSharedUploads is enabled.
+ *
+ * @since 1.5
+ */
+$wgRepositoryBaseUrl = 'https://commons.wikimedia.org/wiki/File:';
+
+/**
+ * Shortcut for the 'fetchDescription' setting of $wgForeignFileRepos.
+ * Only used if $wgUseSharedUploads is enabled.
+ *
+ * @var bool
+ * @since 1.5
+ */
+$wgFetchCommonsDescriptions = false;
+
+/**
+ * Shortcut for the ForeignDBRepo 'dbName' setting in $wgForeignFileRepos.
+ * Set this to false if the uploads do not come from a wiki.
+ * Only used if $wgUseSharedUploads is enabled.
+ *
+ * @var bool|string
+ * @since 1.4
+ */
+$wgSharedUploadDBname = false;
+
+/**
+ * Shortcut for the ForeignDBRepo 'tablePrefix' setting in $wgForeignFileRepos.
+ * Only used if $wgUseSharedUploads is enabled.
+ *
+ * @var string
+ * @since 1.5
+ */
+$wgSharedUploadDBprefix = '';
+
+/**
+ * Shortcut for the ForeignDBRepo 'hasSharedCache' setting in $wgForeignFileRepos.
+ * Only used if $wgUseSharedUploads is enabled.
+ *
+ * @var bool
+ * @since 1.5
+ */
+$wgCacheSharedUploads = true;
+
 /**
  * Array of foreign file repo names (set in $wgForeignFileRepos above) that
  * are allowable upload targets. These wikis must have some method of
@@ -676,53 +799,6 @@ $wgShowEXIF = function_exists( 'exif_read_data' );
  */
 $wgUpdateCompatibleMetadata = false;
 
-/**
- * If you operate multiple wikis, you can define a shared upload path here.
- * Uploads to this wiki will NOT be put there - they will be put into
- * $wgUploadDirectory.
- * If $wgUseSharedUploads is set, the wiki will look in the shared repository if
- * no file of the given name is found in the local repository (for [[File:..]],
- * [[Media:..]] links). Thumbnails will also be looked for and generated in this
- * directory.
- *
- * Note that these configuration settings can now be defined on a per-
- * repository basis for an arbitrary number of file repositories, using the
- * $wgForeignFileRepos variable.
- */
-$wgUseSharedUploads = false;
-
-/**
- * Full path on the web server where shared uploads can be found
- */
-$wgSharedUploadPath = null;
-
-/**
- * Fetch commons image description pages and display them on the local wiki?
- */
-$wgFetchCommonsDescriptions = false;
-
-/**
- * Path on the file system where shared uploads can be found.
- */
-$wgSharedUploadDirectory = null;
-
-/**
- * DB name with metadata about shared directory.
- * Set this to false if the uploads do not come from a wiki.
- */
-$wgSharedUploadDBname = false;
-
-/**
- * Optional table prefix used in database.
- */
-$wgSharedUploadDBprefix = '';
-
-/**
- * Cache shared metadata in memcached.
- * Don't do this if the commons wiki is in a different memcached domain
- */
-$wgCacheSharedUploads = true;
-
 /**
  * Allow for upload to be copied from an URL.
  * The timeout for copy uploads is set by $wgCopyUploadTimeout.
@@ -821,7 +897,11 @@ $wgUploadMissingFileUrl = false;
 $wgThumbnailScriptPath = false;
 
 /**
- * @see $wgThumbnailScriptPath
+ * Shortcut for the 'thumbScriptUrl' setting of $wgForeignFileRepos.
+ * Only used if $wgUseSharedUploads is enabled.
+ *
+ * @var string
+ * @since 1.3
  */
 $wgSharedThumbnailScriptPath = false;
 
@@ -840,23 +920,6 @@ $wgSharedThumbnailScriptPath = false;
  */
 $wgHashedUploadDirectory = true;
 
-/**
- * Set the following to false especially if you have a set of files that need to
- * be accessible by all wikis, and you do not want to use the hash (path/a/aa/)
- * directory layout.
- */
-$wgHashedSharedUploadDirectory = true;
-
-/**
- * Base URL for a repository wiki. Leave this blank if uploads are just stored
- * in a shared directory and not meant to be accessible through a separate wiki.
- * Otherwise the image description pages on the local wiki will link to the
- * image description page on this wiki.
- *
- * Please specify the namespace, as in the example below.
- */
-$wgRepositoryBaseUrl = "https://commons.wikimedia.org/wiki/File:";
-
 /**
  * This is the list of preferred extensions for uploading files. Uploading files
  * with extensions not in this list will trigger a warning.
@@ -1500,10 +1563,6 @@ $wgDirectoryMode = 0777;
  *
  * This means a 320x240 use of an image on the wiki will also generate 480x360 and 640x480
  * thumbnails, output via the srcset attribute.
- *
- * On older browsers, a JavaScript polyfill switches the appropriate images in after loading
- * the original low-resolution versions depending on the reported window.devicePixelRatio.
- * The polyfill can be found in the jquery.hidpi module.
  */
 $wgResponsiveImages = true;
 
@@ -1894,6 +1953,13 @@ $wgSQLMode = '';
  */
 $wgDBmwschema = null;
 
+/**
+ * Default group to use when getting database connections.
+ * Will be used as default query group in ILoadBalancer::getConnection.
+ * @since 1.32
+ */
+$wgDBDefaultGroup = null;
+
 /**
  * To override default SQLite data directory ($docroot/../data)
  */
@@ -2059,6 +2125,8 @@ $wgDBerrorLogTZ = false;
  * 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;
 
@@ -2565,17 +2633,6 @@ $wgCacheEpoch = '20030516000000';
  */
 $wgGitInfoCacheDirectory = false;
 
-/**
- * Bump this number when changing the global style sheets and JavaScript.
- *
- * It should be appended in the query string of static CSS and JS includes,
- * to ensure that client-side caches do not keep obsolete copies of global
- * styles.
- *
- * @deprecated since 1.31
- */
-$wgStyleVersion = '303';
-
 /**
  * This will cache static pages for non-logged-in users to reduce
  * database traffic on public sites. ResourceLoader requests to default
@@ -3009,11 +3066,6 @@ $wgAllUnicodeFixes = false;
  */
 $wgLegacyEncoding = false;
 
-/**
- * @deprecated since 1.30, does nothing
- */
-$wgBrowserBlackList = [];
-
 /**
  * If set to true, the MediaWiki 1.4 to 1.5 schema conversion will
  * create stub reference rows in the text table instead of copying
@@ -3238,8 +3290,8 @@ $wgHTMLFormAllowTableFormat = true;
 $wgUseMediaWikiUIEverywhere = false;
 
 /**
- * Temporary variable that determines whether the EditPage class should use OOjs UI or not.
- * This will be removed later and OOjs UI will become the only option.
+ * Temporary variable that determines whether Special:Preferences should use OOUI or not.
+ * This will be removed later and OOUI will become the only option.
  *
  * @since 1.32
  */
@@ -3789,23 +3841,6 @@ $wgResourceLoaderLESSVars = [
        'deviceWidthTablet' => '720px',
 ];
 
-/**
- * Default import paths for LESS modules. LESS files referenced in @import
- * statements will be looked up here first, and relative to the importing file
- * second. To avoid collisions, it's important for the LESS files in these
- * directories to have a common, predictable file name prefix.
- *
- * Extensions need not (and should not) register paths in
- * $wgResourceLoaderLESSImportPaths. The import path includes the path of the
- * currently compiling LESS file, which allows each extension to freely import
- * files from its own tree.
- *
- * @since 1.22
- */
-$wgResourceLoaderLESSImportPaths = [
-       "$IP/resources/src/mediawiki.less/",
-];
-
 /**
  * Whether ResourceLoader should attempt to persist modules in localStorage on
  * browsers that support the Web Storage API.
@@ -4513,6 +4548,12 @@ $wgPasswordPolicy = [
                        'PasswordCannotMatchUsername' => true,
                        'PasswordCannotBePopular' => 25,
                ],
+               'interface-admin' => [
+                       'MinimalPasswordLength' => 8,
+                       'MinimumPasswordLengthToLogin' => 1,
+                       'PasswordCannotMatchUsername' => true,
+                       'PasswordCannotBePopular' => 25,
+               ],
                'bot' => [
                        'MinimalPasswordLength' => 8,
                        'MinimumPasswordLengthToLogin' => 1,
@@ -4757,10 +4798,10 @@ $wgPasswordDefault = 'pbkdf2';
  * $wgPasswordConfig['bcrypt-peppered'] = [
  *     'class' => EncryptedPassword::class,
  *     'underlying' => 'bcrypt',
- *     'secrets' => [],
- *     'cipher' => MCRYPT_RIJNDAEL_256,
- *     'mode' => MCRYPT_MODE_CBC,
- *     'cost' => 5,
+ *     'secrets' => [
+ *         hash( 'sha256', 'secret', true ),
+ *     ],
+ *     'cipher' => 'aes-256-cbc',
  * ];
  * @endcode
  *
@@ -4893,7 +4934,7 @@ $wgDefaultUserOptions = [
        'watchdefault' => 1,
        'watchdeletion' => 0,
        'watchuploads' => 1,
-       'watchlistdays' => 3.0,
+       'watchlistdays' => 7.0,
        'watchlisthideanons' => 0,
        'watchlisthidebots' => 0,
        'watchlisthideliu' => 0,
@@ -4905,6 +4946,7 @@ $wgDefaultUserOptions = [
        'watchlistunwatchlinks' => 0,
        'watchmoves' => 0,
        'watchrollback' => 0,
+       'wlenhancedfilters-disable' => 0,
        'wllimit' => 250,
        'useeditwarning' => 1,
        'prefershttps' => 1,
@@ -5181,9 +5223,8 @@ $wgGroupPermissions['sysop']['deletedhistory'] = true;
 $wgGroupPermissions['sysop']['deletedtext'] = true;
 $wgGroupPermissions['sysop']['undelete'] = true;
 $wgGroupPermissions['sysop']['editinterface'] = true;
-$wgGroupPermissions['sysop']['editusercss'] = true;
+$wgGroupPermissions['sysop']['editsitejson'] = true;
 $wgGroupPermissions['sysop']['edituserjson'] = true;
-$wgGroupPermissions['sysop']['edituserjs'] = true;
 $wgGroupPermissions['sysop']['import'] = true;
 $wgGroupPermissions['sysop']['importupload'] = true;
 $wgGroupPermissions['sysop']['move'] = true;
@@ -5216,6 +5257,14 @@ $wgGroupPermissions['sysop']['mergehistory'] = true;
 $wgGroupPermissions['sysop']['managechangetags'] = true;
 $wgGroupPermissions['sysop']['deletechangetags'] = true;
 
+$wgGroupPermissions['interface-admin']['editinterface'] = true;
+$wgGroupPermissions['interface-admin']['editsitecss'] = true;
+$wgGroupPermissions['interface-admin']['editsitejson'] = true;
+$wgGroupPermissions['interface-admin']['editsitejs'] = true;
+$wgGroupPermissions['interface-admin']['editusercss'] = true;
+$wgGroupPermissions['interface-admin']['edituserjson'] = true;
+$wgGroupPermissions['interface-admin']['edituserjs'] = true;
+
 // Permission to change users' group assignments
 $wgGroupPermissions['bureaucrat']['userrights'] = true;
 $wgGroupPermissions['bureaucrat']['noratelimit'] = true;
@@ -5822,9 +5871,14 @@ $wgGrantPermissions['editmyoptions']['editmyoptions'] = true;
 
 $wgGrantPermissions['editinterface'] = $wgGrantPermissions['editpage'];
 $wgGrantPermissions['editinterface']['editinterface'] = true;
-$wgGrantPermissions['editinterface']['editusercss'] = true;
 $wgGrantPermissions['editinterface']['edituserjson'] = true;
-$wgGrantPermissions['editinterface']['edituserjs'] = true;
+$wgGrantPermissions['editinterface']['editsitejson'] = true;
+
+$wgGrantPermissions['editsiteconfig'] = $wgGrantPermissions['editinterface'];
+$wgGrantPermissions['editsiteconfig']['editusercss'] = true;
+$wgGrantPermissions['editsiteconfig']['edituserjs'] = true;
+$wgGrantPermissions['editsiteconfig']['editsitecss'] = true;
+$wgGrantPermissions['editsiteconfig']['editsitejs'] = true;
 
 $wgGrantPermissions['createeditmovepage'] = $wgGrantPermissions['editpage'];
 $wgGrantPermissions['createeditmovepage']['createpage'] = true;
@@ -5903,6 +5957,7 @@ $wgGrantPermissionGroups = [
        'editmyoptions'       => 'customization',
 
        'editinterface'       => 'administration',
+       'editsiteconfig'      => 'administration',
        'rollback'            => 'administration',
        'blockusers'          => 'administration',
        'delete'              => 'administration',
@@ -6043,6 +6098,15 @@ $wgSessionName = false;
  */
 $wgCookieSetOnAutoblock = false;
 
+/**
+ * Whether to set a cookie when a logged-out user is blocked. Doing so means that a blocked user,
+ * even after moving to a new IP address, will still be blocked. This cookie will contain an
+ * authentication code if $wgSecretKey is set, or otherwise will just be the block ID (in which
+ * case there is a possibility of an attacker discovering the names of revdeleted users, so it
+ * is best to use this in conjunction with $wgSecretKey being set).
+ */
+$wgCookieSetOnIpBlock = false;
+
 /** @} */ # end of cookie settings }
 
 /************************************************************************//**
@@ -6251,14 +6315,17 @@ $wgSpecialVersionShowHooks = false;
  * Whether to show "we're sorry, but there has been a database error" pages.
  * Displaying errors aids in debugging, but may display information useful
  * to an attacker.
+ *
+ * @deprecated and nonfunctional since 1.32: set $wgShowExceptionDetails and/or
+ * $wgShowHostnames instead.
  */
 $wgShowSQLErrors = false;
 
 /**
- * If set to true, uncaught exceptions will print a complete stack trace
- * to output. This should only be used for debugging, as it may reveal
- * private information in function parameters due to PHP's backtrace
- * formatting.
+ * If set to true, uncaught exceptions will print the exception message and a
+ * complete stack trace to output. This should only be used for debugging, as it
+ * may reveal private information in function parameters due to PHP's backtrace
+ * formatting.  If set to false, only the exception's class will be shown.
  */
 $wgShowExceptionDetails = false;
 
@@ -6269,6 +6336,8 @@ $wgShowExceptionDetails = false;
  * reported in the normal manner. $wgShowExceptionDetails applies in other cases,
  * including those in which an uncaught exception is thrown from within the
  * exception handler.
+ *
+ * @deprecated and nonfunctional since 1.32: set $wgShowExceptionDetails instead.
  */
 $wgShowDBErrorBacktrace = false;
 
@@ -6890,6 +6959,15 @@ $wgUseRCPatrol = true;
  */
 $wgStructuredChangeFiltersShowPreference = false;
 
+/**
+ * Whether a preference is displayed for structured change filters on watchlist.
+ * Works just like $wgStructuredChangeFiltersShowPreference.
+ *
+ * Temporary variable during development and will be removed
+ * @since 1.32
+ */
+$wgStructuredChangeFiltersShowWatchlistPreference = false;
+
 /**
  * Whether to enable RCFilters app on Special:Watchlist
  *
@@ -7128,7 +7206,7 @@ $wgRightsUrl = null;
 
 /**
  * If either $wgRightsUrl or $wgRightsPage is specified then this variable gives the text for the
- * link.
+ * link. Otherwise, it will be treated as raw HTML.
  * If using $wgRightsUrl then this value must be specified. If using $wgRightsPage then the name
  * of the page will also be used as the link if this variable is not set.
  */
@@ -7667,6 +7745,9 @@ $wgCategoryCollation = 'uppercase';
  * general category and can be viewed as a named subset of all logs; and
  * an action, which is a specific kind of event that can exist in that
  * log type.
+ *
+ * Note that code should call LogPage::validTypes() to get a list of valid
+ * log types instead of checking the global variable.
  */
 $wgLogTypes = [
        '',
@@ -7712,8 +7793,8 @@ $wgLogRestrictions = [
  * hidden by default unless the link is clicked. Import logs will be shown by
  * default, and hidden when the link is clicked.
  *
- * A message of the form log-show-hide-[type] should be added, and will be used
- * for the link text.
+ * A message of the form logeventslist-[type]-log should be added, and will be
+ * used for the link text.
  */
 $wgFilterLogTypes = [
        'patrol' => true,
@@ -7888,10 +7969,16 @@ $wgActionFilteredLogs = [
 ];
 
 /**
- * Maintain a log of newusers at Log/newusers?
+ * Maintain a log of newusers at Special:Log/newusers?
  */
 $wgNewUserLog = true;
 
+/**
+ * Maintain a log of page creations at Special:Log/create?
+ * @since 1.32
+ */
+$wgPageCreationLog = true;
+
 /** @} */ # end logging }
 
 /*************************************************************************//**
@@ -8609,9 +8696,14 @@ $wgSiteTypes = [
 $wgPagePropsHaveSortkey = true;
 
 /**
- * Port where you have HTTPS running
- * Supports HTTPS on non-standard ports
- * @see T67184
+ * For installations where the canonical server is HTTP but HTTPS is optionally
+ * supported, you can specify a non-standard HTTPS port here. $wgServer should
+ * be a protocol-relative URL.
+ *
+ * If HTTPS is always used, just specify the port number in $wgServer.
+ *
+ * @see https://phabricator.wikimedia.org/T67184
+ *
  * @since 1.24
  */
 $wgHttpsPort = 443;
@@ -8762,6 +8854,8 @@ $wgMaxJobDBWriteDuration = false;
  *    $wgCrossSiteAJAXdomains as an allowed load sources.
  *  'unsafeFallback' Add unsafe-inline as a script source, as a fallback for
  *    browsers that do not understand nonce-sources [default on].
+ *  'useNonces' Require nonces on all inline scripts. If disabled and 'unsafeFallback'
+ *    is on, then all inline scripts will be allowed [default true].
  *  'script-src' Array of additional places that are allowed to have JS be loaded from.
  *  'report-uri' true to use MW api [default], false to disable, string for alternate uri
  * @warning May cause slowness on windows due to slow random number generator.
@@ -8894,6 +8988,27 @@ $wgInterwikiPrefixDisplayTypes = [];
  */
 $wgCommentTableSchemaMigrationStage = MIGRATION_OLD;
 
+/**
+ * RevisionStore table schema migration stage (content, slots, content_models & slot_roles tables).
+ * Use the SCHEMA_COMPAT_XXX flags. Supported values:
+ *
+ * - SCHEMA_COMPAT_OLD
+ * - SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD
+ * - SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW
+ * - SCHEMA_COMPAT_OLD
+ *
+ * Note that reading the old and new schema at the same time is not supported.
+ * Attempting to set both read bits in $wgMultiContentRevisionSchemaMigrationStage
+ * will result in an InvalidArgumentException.
+ *
+ * @see Task: https://phabricator.wikimedia.org/T174028
+ * @see Commit: https://gerrit.wikimedia.org/r/#/c/378724/
+ *
+ * @since 1.32
+ * @var int An appropriate combination of SCHEMA_COMPAT_XXX flags.
+ */
+$wgMultiContentRevisionSchemaMigrationStage = SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD;
+
 /**
  * Actor table schema migration stage.
  * @since 1.31
@@ -8910,6 +9025,32 @@ $wgActorTableSchemaMigrationStage = MIGRATION_OLD;
  */
 $wgExpiryWidgetNoDatePicker = false;
 
+/**
+ * change_tag table schema migration stage.
+ *
+ * - MIGRATION_OLD: Do not use change_tag_def table or ct_tag_id.
+ * - MIGRATION_WRITE_BOTH: Write to the change_tag_def table and ct_tag_id, but read from
+ *   the old schema. This is different from the formal definition of the constants
+ * - MIGRATION_WRITE_NEW: Behaves the same as MIGRATION_WRITE_BOTH
+ * - MIGRATION_NEW: Use the change_tag_def table and ct_tag_id, do not read/write ct_tag
+ *
+ * @since 1.32
+ * @var int One of the MIGRATION_* constants
+ */
+$wgChangeTagsSchemaMigrationStage = MIGRATION_OLD;
+
+/**
+ * Temporarily flag to use change_tag_def table as backend of change tag statistics.
+ * For example in case of Special:Tags. If set to false, it will use change_tag table.
+ * Before setting it to true set $wgChangeTagsSchemaMigrationStage to MIGRATION_WRITE_BOTH and run
+ * PopulateChangeTagDef maintaince script.
+ * It's redundant when $wgChangeTagsSchemaMigrationStage is set to MIGRATION_NEW
+ *
+ * @since 1.32
+ * @var bool
+ */
+$wgTagStatisticsNewTable = false;
+
 /**
  * For really cool vim folding this needs to be at the end:
  * vim: foldmarker=@{,@} foldmethod=marker
index 087af39..72cddd2 100644 (file)
@@ -22,7 +22,6 @@
 
 require_once __DIR__ . '/libs/mime/defines.php';
 require_once __DIR__ . '/libs/rdbms/defines.php';
-require_once __DIR__ . '/compat/normal/UtfNormalDefines.php';
 
 use Wikimedia\Rdbms\IDatabase;
 
@@ -271,11 +270,34 @@ define( 'CONTENT_FORMAT_XML', 'application/xml' );
 define( 'SHELL_MAX_ARG_STRLEN', '100000' );
 /**@}*/
 
+/**@{
+ * Schema compatibility flags.
+ *
+ * Used as flags in a bit field that indicates whether the old or new schema (or both)
+ * are read or written.
+ *
+ * - SCHEMA_COMPAT_WRITE_OLD: Whether information is written to the old schema.
+ * - SCHEMA_COMPAT_READ_OLD: Whether information stored in the old schema is read.
+ * - SCHEMA_COMPAT_WRITE_NEW: Whether information is written to the new schema.
+ * - SCHEMA_COMPAT_READ_NEW: Whether information stored in the new schema is read.
+ */
+define( 'SCHEMA_COMPAT_WRITE_OLD', 0x01 );
+define( 'SCHEMA_COMPAT_READ_OLD', 0x02 );
+define( 'SCHEMA_COMPAT_WRITE_NEW', 0x10 );
+define( 'SCHEMA_COMPAT_READ_NEW', 0x20 );
+define( 'SCHEMA_COMPAT_WRITE_BOTH', SCHEMA_COMPAT_WRITE_OLD | SCHEMA_COMPAT_WRITE_NEW );
+define( 'SCHEMA_COMPAT_READ_BOTH', SCHEMA_COMPAT_READ_OLD | SCHEMA_COMPAT_READ_NEW );
+define( 'SCHEMA_COMPAT_OLD', SCHEMA_COMPAT_WRITE_OLD | SCHEMA_COMPAT_READ_OLD );
+define( 'SCHEMA_COMPAT_NEW', SCHEMA_COMPAT_WRITE_NEW | SCHEMA_COMPAT_READ_NEW );
+/**@}*/
+
 /**@{
  * Schema change migration flags.
  *
  * Used as values of a feature flag for an orderly transition from an old
- * schema to a new schema.
+ * schema to a new schema. The numeric values of these constants are compatible with the
+ * SCHEMA_COMPAT_XXX bitfield semantics. High bits are used to ensure that the numeric
+ * ordering follows the order in which the migration stages should be used.
  *
  * - MIGRATION_OLD: Only read and write the old schema. The new schema need not
  *   even exist. This is used from when the patch is merged until the schema
@@ -290,8 +312,8 @@ define( 'SHELL_MAX_ARG_STRLEN', '100000' );
  * - MIGRATION_NEW: Only read and write the new schema. The old schema (and the
  *   feature flag) may now be removed.
  */
-define( 'MIGRATION_OLD', 0 );
-define( 'MIGRATION_WRITE_BOTH', 1 );
-define( 'MIGRATION_WRITE_NEW', 2 );
-define( 'MIGRATION_NEW', 3 );
+define( 'MIGRATION_OLD', 0x00000000 | SCHEMA_COMPAT_OLD );
+define( 'MIGRATION_WRITE_BOTH', 0x10000000 | SCHEMA_COMPAT_READ_BOTH | SCHEMA_COMPAT_WRITE_BOTH );
+define( 'MIGRATION_WRITE_NEW', 0x20000000 | SCHEMA_COMPAT_READ_BOTH | SCHEMA_COMPAT_WRITE_NEW );
+define( 'MIGRATION_NEW', 0x30000000 | SCHEMA_COMPAT_NEW );
 /**@}*/
index 96ed56b..8b32de4 100644 (file)
@@ -24,18 +24,16 @@ ini_set( 'display_errors', 1 );
 /**
  * Debugging: MediaWiki
  */
-global $wgDevelopmentWarnings, $wgShowDBErrorBacktrace, $wgShowExceptionDetails,
-       $wgShowSQLErrors, $wgDebugRawPage,
-       $wgDebugComments, $wgDebugDumpSql, $wgDebugTimestamps,
+global $wgDevelopmentWarnings, $wgShowExceptionDetails, $wgShowHostnames,
+       $wgDebugRawPage, $wgDebugComments, $wgDebugDumpSql, $wgDebugTimestamps,
        $wgCommandLineMode, $wgDebugLogFile, $wgDBerrorLog, $wgDebugLogGroups;
 
 // Use of wfWarn() should cause tests to fail
 $wgDevelopmentWarnings = true;
 
 // Enable showing of errors
-$wgShowDBErrorBacktrace = true;
 $wgShowExceptionDetails = true;
-$wgShowSQLErrors = true;
+$wgShowHostnames = true;
 $wgDebugRawPage = true; // T49960
 
 // Enable log files
index 9aa6aeb..2f5455e 100644 (file)
@@ -5,14 +5,6 @@
  */
 class DummyLinker {
 
-       /**
-        * @deprecated since 1.28, use LinkRenderer::getLinkClasses() instead
-        */
-       public function getLinkColour( $t, $threshold ) {
-               wfDeprecated( __METHOD__, '1.28' );
-               return Linker::getLinkColour( $t, $threshold );
-       }
-
        public function link(
                $target,
                $html = null,
@@ -107,7 +99,7 @@ class DummyLinker {
                Title $title,
                $file,
                $label = '',
-               $alt,
+               $alt = '',
                $align = 'right',
                $params = [],
                $framed = false,
index 67ce1f3..16f1c5a 100644 (file)
@@ -235,7 +235,10 @@ class EditPage {
        /** @var string */
        public $action = 'submit';
 
-       /** @var bool */
+       /** @var bool Whether an edit conflict needs to be resolved. Detected based on whether
+        * $editRevId is different from the current revision. When a conflict has successfully
+        * been resolved by a 3-way-merge, this field is set to false.
+        */
        public $isConflict = false;
 
        /** @var bool New page or new section */
@@ -301,7 +304,7 @@ class EditPage {
        /** @var bool Has a summary been preset using GET parameter &summary= ? */
        public $hasPresetSummary = false;
 
-       /** @var Revision|bool|null */
+       /** @var Revision|bool|null A revision object corresponding to $this->editRevId. */
        public $mBaseRevision = false;
 
        /** @var bool */
@@ -342,7 +345,16 @@ class EditPage {
        /** @var string */
        public $edittime = '';
 
-       /** @var int */
+       /** @var int ID of the current revision at the time editing was initiated on the client.
+        * This is used to detect and resolve edit conflicts.
+        *
+        * @note 0 if the page did not exist at that time.
+        * @note When starting an edit from an old revision, this still records the current
+        * revision at the time , not the one the edit is based on.
+        *
+        * @see $oldid
+        * @see getBaseRevision()
+        */
        private $editRevId = null;
 
        /** @var string */
@@ -354,10 +366,16 @@ class EditPage {
        /** @var string */
        public $starttime = '';
 
-       /** @var int */
+       /** @var int Revision ID the edit is based on, or 0 if it's the current revision.
+        * @see $editRevId
+        */
        public $oldid = 0;
 
-       /** @var int */
+       /** @var int Revision ID the edit is based on, adjusted when an edit conflict is resolved.
+        * @see $editRevId
+        * @see $oldid
+        * @see getparentRevId()
+        */
        public $parentRevId = 0;
 
        /** @var string */
@@ -486,17 +504,15 @@ class EditPage {
 
        /**
         * Get the context title object.
-        * If not set, $wgTitle will be returned. This behavior might change in
-        * the future to return $this->mTitle instead.
+        *
+        * If not set, $wgTitle will be returned, but this is deprecated. This will
+        * throw an exception.
         *
         * @return Title
         */
        public function getContextTitle() {
                if ( is_null( $this->mContextTitle ) ) {
-                       wfDebugLog(
-                               'GlobalTitleFail',
-                               __METHOD__ . ' called by ' . wfGetAllCallers( 5 ) . ' with no title set.'
-                       );
+                       wfDeprecated( __METHOD__ . ' called with no title set', '1.32' );
                        global $wgTitle;
                        return $wgTitle;
                } else {
@@ -587,6 +603,10 @@ class EditPage {
                $permErrors = $this->getEditPermissionErrors( $this->save ? 'secure' : 'full' );
                if ( $permErrors ) {
                        wfDebug( __METHOD__ . ": User can't edit\n" );
+
+                       // track block with a cookie if it doesn't exists already
+                       $this->context->getUser()->trackBlockWithCookie();
+
                        // Auto-block user's IP if the account was "hard" blocked
                        if ( !wfReadOnly() ) {
                                DeferredUpdates::addCallableUpdate( function () {
@@ -928,12 +948,7 @@ class EditPage {
                        } else {
                                // If we receive the last parameter of the request, we can fairly
                                // claim the POST request has not been truncated.
-
-                               // TODO: softened the check for cutover.  Once we determine
-                               // that it is safe, we should complete the transition by
-                               // removing the "edittime" clause.
-                               $this->incompleteForm = ( !$request->getVal( 'wpUltimateParam' )
-                                       && is_null( $this->edittime ) );
+                               $this->incompleteForm = !$request->getVal( 'wpUltimateParam' );
                        }
                        if ( $this->incompleteForm ) {
                                # If the form is incomplete, force to preview.
@@ -1182,6 +1197,7 @@ class EditPage {
                                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.
@@ -1190,12 +1206,19 @@ class EditPage {
                                                !$undorev->isDeleted( Revision::DELETED_TEXT ) &&
                                                !$oldrev->isDeleted( Revision::DELETED_TEXT )
                                        ) {
-                                               $content = $this->page->getUndoContent( $undorev, $oldrev );
-
-                                               if ( $content === false ) {
-                                                       # Warn the user that something went wrong
-                                                       $undoMsg = 'failure';
+                                               if ( WikiPage::hasDifferencesOutsideMainSlot( $undorev, $oldrev ) ) {
+                                                       // Cannot yet undo edits that involve anything other the main slot.
+                                                       $undoMsg = 'main-slot-only';
                                                } else {
+                                                       $content = $this->page->getUndoContent( $undorev, $oldrev );
+
+                                                       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, $wgContLang );
                                                        $newContent = $content->preSaveTransform( $this->mTitle, $user, $popts );
@@ -1252,7 +1275,8 @@ class EditPage {
                                        }
 
                                        $out = $this->context->getOutput();
-                                       // Messages: undo-success, undo-failure, undo-norev, undo-nochange
+                                       // Messages: undo-success, undo-failure, undo-main-slot-only, undo-norev,
+                                       // undo-nochange.
                                        $class = ( $undoMsg == 'success' ? '' : 'error ' ) . "mw-undo-{$undoMsg}";
                                        $this->editFormPageTop .= $out->parse( "<div class=\"{$class}\">" .
                                                $this->context->msg( 'undo-' . $undoMsg )->plain() . '</div>', true, /* interface */true );
@@ -1491,7 +1515,11 @@ class EditPage {
         * @return Status The resulting status object.
         */
        public function attemptSave( &$resultDetails = false ) {
-               # Allow bots to exempt some edits from bot flagging
+               // TODO: MCR: treat $this->minoredit like $this->bot and check isAllowed( 'minoredit' )!
+               // Also, add $this->autopatrol like $this->bot and check isAllowed( 'autopatrol' )!
+               // This is needed since PageUpdater no longer checks these rights!
+
+               // Allow bots to exempt some edits from bot flagging
                $bot = $this->context->getUser()->isAllowed( 'bot' ) && $this->bot;
                $status = $this->internalAttemptSave( $resultDetails, $bot );
 
@@ -1574,7 +1602,7 @@ class EditPage {
                                                $query = $query . '&' . $extraQueryRedirect;
                                        }
                                }
-                               $anchor = isset( $resultDetails['sectionanchor'] ) ? $resultDetails['sectionanchor'] : '';
+                               $anchor = $resultDetails['sectionanchor'] ?? '';
                                $out->redirect( $this->mTitle->getFullURL( $query ) . $anchor );
                                return false;
 
@@ -2015,7 +2043,10 @@ ERROR;
 
                        wfDebug( "timestamp: {$timestamp}, edittime: {$this->edittime}\n" );
 
-                       // Check editRevId if set, which handles same-second timestamp collisions
+                       // An edit conflict is detected if the current revision is different from the
+                       // revision that was current when editing was initiated on the client.
+                       // This is checked based on the timestamp and revision ID.
+                       // TODO: the timestamp based check can probably go away now.
                        if ( $timestamp != $this->edittime
                                || ( $this->editRevId !== null && $this->editRevId != $latest )
                        ) {
@@ -2295,7 +2326,8 @@ ERROR;
        private function mergeChangesIntoContent( &$editContent ) {
                $db = wfGetDB( DB_MASTER );
 
-               // This is the revision the editor started from
+               // This is the revision that was current at the time editing was initiated on the client,
+               // even if the edit was based on an old revision.
                $baseRevision = $this->getBaseRevision();
                $baseContent = $baseRevision ? $baseRevision->getContent() : null;
 
@@ -2326,9 +2358,16 @@ ERROR;
        }
 
        /**
-        * @note: this method is very poorly named. If the user opened the form with ?oldid=X,
-        *        one might think of X as the "base revision", which is NOT what this returns.
-        * @return Revision|null Current version when the edit was started
+        * Returns the revision that was current at the time editing was initiated on the client,
+        * even if the edit was based on an old revision.
+        *
+        * @warning this method is very poorly named. If the user opened the form with ?oldid=X,
+        *        one might think of X as the "base revision", which is NOT what this returns,
+        *        see oldid for that. One might further assume that this corresponds to the $baseRevId
+        *        parameter of WikiPage::doEditContent, which is not the case either.
+        *        getExpectedParentRevision() would perhaps be a better name.
+        *
+        * @return Revision|null Current version when editing was initiated on the client
         */
        public function getBaseRevision() {
                if ( !$this->mBaseRevision ) {
@@ -2808,7 +2847,7 @@ ERROR;
                        $this->autoSumm = md5( '' );
                }
 
-               $autosumm = $this->autoSumm ? $this->autoSumm : md5( $this->summary );
+               $autosumm = $this->autoSumm ?: md5( $this->summary );
                $out->addHTML( Html::hidden( 'wpAutoSummary', $autosumm ) );
 
                $out->addHTML( Html::hidden( 'oldid', $this->oldid ) );
@@ -3154,8 +3193,8 @@ ERROR;
         * Builds a standard summary input with a label.
         *
         * @param string $summary The value of the summary input
-        * @param string $labelText The html to place inside the label
-        * @param array $inputAttrs Array of attrs to use on the input
+        * @param string|null $labelText The html to place inside the label
+        * @param array|null $inputAttrs Array of attrs to use on the input
         *
         * @return OOUI\FieldLayout OOUI FieldLayout with Label and Input
         */
@@ -3288,8 +3327,8 @@ ERROR;
         * The $textoverride method can be used by subclasses overriding showContentForm
         * to pass back to this method.
         *
-        * @param array $customAttribs Array of html attributes to use in the textarea
-        * @param string $textoverride Optional text to override $this->textarea1 with
+        * @param array|null $customAttribs Array of html attributes to use in the textarea
+        * @param string|null $textoverride Optional text to override $this->textarea1 with
         */
        protected function showTextbox1( $customAttribs = null, $textoverride = null ) {
                if ( $this->wasDeletedSinceLastEdit() && $this->formtype == 'save' ) {
@@ -3313,7 +3352,7 @@ ERROR;
                }
 
                $this->showTextbox(
-                       $textoverride !== null ? $textoverride : $this->textbox1,
+                       $textoverride ?? $this->textbox1,
                        'wpTextbox1',
                        $attribs
                );
@@ -3537,7 +3576,7 @@ ERROR;
                // Allow for site and per-namespace customization of contribution/copyright notice.
                Hooks::run( 'EditPageCopyrightWarning', [ $title, &$copywarnMsg ] );
 
-               $msg = call_user_func_array( 'wfMessage', $copywarnMsg )->title( $title );
+               $msg = wfMessage( ...$copywarnMsg )->title( $title );
                if ( $langcode ) {
                        $msg->inLanguage( $langcode );
                }
@@ -3987,7 +4026,7 @@ ERROR;
         * Shows a bulletin board style toolbar for common editing functions.
         * It can be disabled in the user preferences.
         *
-        * @param Title $title Title object for the page being edited (optional)
+        * @param Title|null $title Title object for the page being edited (optional)
         * @return string
         */
        public static function getEditToolbar( $title = null ) {
@@ -4111,14 +4150,12 @@ ERROR;
 
                $script .= '});';
 
-               $nonce = $wgOut->getCSPNonce();
-               $wgOut->addScript( ResourceLoader::makeInlineScript( $script, $nonce ) );
-
                $toolbar = '<div id="toolbar"></div>';
 
                if ( Hooks::run( 'EditPageBeforeEditToolbar', [ &$toolbar ] ) ) {
                        // Only add the old toolbar cruft to the page payload if the toolbar has not
                        // been over-written by a hook caller
+                       $nonce = $wgOut->getCSPNonce();
                        $wgOut->addScript( ResourceLoader::makeInlineScript( $script, $nonce ) );
                };
 
@@ -4193,7 +4230,7 @@ ERROR;
                $checkboxesDef = $this->getCheckboxesDefinition( $checked );
 
                foreach ( $checkboxesDef as $name => $options ) {
-                       $legacyName = isset( $options['legacy-name'] ) ? $options['legacy-name'] : $name;
+                       $legacyName = $options['legacy-name'] ?? $name;
 
                        $title = null;
                        $accesskey = null;
@@ -4219,33 +4256,11 @@ ERROR;
                                        'align' => 'inline',
                                        'label' => new OOUI\HtmlSnippet( $this->context->msg( $options['label-message'] )->parse() ),
                                        'title' => $title,
-                                       'id' => isset( $options['label-id'] ) ? $options['label-id'] : null,
+                                       'id' => $options['label-id'] ?? null,
                                ]
                        );
                }
 
-               // Backwards-compatibility hack to run the EditPageBeforeEditChecks hook. It's important,
-               // people have used it for the weirdest things completely unrelated to checkboxes...
-               // And if we're gonna run it, might as well allow its legacy checkboxes to be shown.
-               $legacyCheckboxes = [];
-               if ( !$this->isNew ) {
-                       $legacyCheckboxes['minor'] = '';
-               }
-               $legacyCheckboxes['watch'] = '';
-               // Copy new-style checkboxes into an old-style structure
-               foreach ( $checkboxes as $name => $oouiLayout ) {
-                       $legacyCheckboxes[$name] = (string)$oouiLayout;
-               }
-               // Avoid PHP 7.1 warning of passing $this by reference
-               $ep = $this;
-               Hooks::run( 'EditPageBeforeEditChecks', [ &$ep, &$legacyCheckboxes, &$tabindex ], '1.29' );
-               // Copy back any additional old-style checkboxes into the new-style structure
-               foreach ( $legacyCheckboxes as $name => $html ) {
-                       if ( $html && !isset( $checkboxes[$name] ) ) {
-                               $checkboxes[$name] = new OOUI\Widget( [ 'content' => new OOUI\HtmlSnippet( $html ) ] );
-                       }
-               }
-
                return $checkboxes;
        }
 
index 2f7f75b..ecbc6e3 100644 (file)
@@ -121,7 +121,7 @@ class FauxRequest extends WebRequest {
                        $prefix = $wgCookiePrefix;
                }
                $name = $prefix . $key;
-               return isset( $this->cookies[$name] ) ? $this->cookies[$name] : $default;
+               return $this->cookies[$name] ?? $default;
        }
 
        /**
index eb0052c..c362ec0 100644 (file)
@@ -148,7 +148,7 @@ class FileDeleteForm {
         * @param string &$oldimage Archive name
         * @param string $reason Reason of the deletion
         * @param bool $suppress Whether to mark all deleted versions as restricted
-        * @param User $user User object performing the request
+        * @param User|null $user User object performing the request
         * @param array $tags Tags to apply to the deletion action
         * @throws MWException
         * @return Status
index 53c8d3b..53ddac9 100644 (file)
@@ -336,7 +336,7 @@ class FormOptions implements ArrayAccess {
         * available for accessing with getValue() or consumeValue() etc.
         *
         * @param WebRequest $r The request to fetch values from
-        * @param array $optionKeys Which options to fetch the values for (default:
+        * @param array|null $optionKeys Which options to fetch the values for (default:
         *     all of them). Note that passing an empty array will also result in
         *     values for all keys being fetched.
         * @throws MWException If the type of any option is invalid
index 6270b27..363d7b8 100644 (file)
@@ -227,6 +227,7 @@ class GitInfo {
                        $date = false;
                        if ( is_file( $wgGitBin ) &&
                                is_executable( $wgGitBin ) &&
+                               !Shell::isDisabled() &&
                                $this->getHead() !== false
                        ) {
                                $cmd = [
index 659ac9d..4a09b9c 100644 (file)
@@ -31,75 +31,7 @@ use MediaWiki\MediaWikiServices;
 use MediaWiki\Shell\Shell;
 use Wikimedia\ScopedCallback;
 use Wikimedia\Rdbms\DBReplicationWaitError;
-
-// Hide compatibility functions from Doxygen
-/// @cond
-/**
- * Compatibility functions
- *
- * We support PHP 5.5.9 and up.
- * Re-implementations of newer functions or functions in non-standard
- * PHP extensions may be included here.
- */
-
-// hash_equals function only exists in PHP >= 5.6.0
-// https://secure.php.net/hash_equals
-if ( !function_exists( 'hash_equals' ) ) {
-       /**
-        * Check whether a user-provided string is equal to a fixed-length secret string
-        * without revealing bytes of the secret string through timing differences.
-        *
-        * The usual way to compare strings (PHP's === operator or the underlying memcmp()
-        * function in C) is to compare corresponding bytes and stop at the first difference,
-        * which would take longer for a partial match than for a complete mismatch. This
-        * is not secure when one of the strings (e.g. an HMAC or token) must remain secret
-        * and the other may come from an attacker. Statistical analysis of timing measurements
-        * over many requests may allow the attacker to guess the string's bytes one at a time
-        * (and check his guesses) even if the timing differences are extremely small.
-        *
-        * When making such a security-sensitive comparison, it is essential that the sequence
-        * in which instructions are executed and memory locations are accessed not depend on
-        * the secret string's value. HOWEVER, for simplicity, we do not attempt to minimize
-        * the inevitable leakage of the string's length. That is generally known anyway as
-        * a chararacteristic of the hash function used to compute the secret value.
-        *
-        * Longer explanation: http://www.emerose.com/timing-attacks-explained
-        *
-        * @codeCoverageIgnore
-        * @param string $known_string Fixed-length secret string to compare against
-        * @param string $user_string User-provided string
-        * @return bool True if the strings are the same, false otherwise
-        */
-       function hash_equals( $known_string, $user_string ) {
-               // Strict type checking as in PHP's native implementation
-               if ( !is_string( $known_string ) ) {
-                       trigger_error( 'hash_equals(): Expected known_string to be a string, ' .
-                               gettype( $known_string ) . ' given', E_USER_WARNING );
-
-                       return false;
-               }
-
-               if ( !is_string( $user_string ) ) {
-                       trigger_error( 'hash_equals(): Expected user_string to be a string, ' .
-                               gettype( $user_string ) . ' given', E_USER_WARNING );
-
-                       return false;
-               }
-
-               $known_string_len = strlen( $known_string );
-               if ( $known_string_len !== strlen( $user_string ) ) {
-                       return false;
-               }
-
-               $result = 0;
-               for ( $i = 0; $i < $known_string_len; $i++ ) {
-                       $result |= ord( $known_string[$i] ) ^ ord( $user_string[$i] );
-               }
-
-               return ( $result === 0 );
-       }
-}
-/// @endcond
+use Wikimedia\WrappedString;
 
 /**
  * Load an extension
@@ -190,7 +122,7 @@ function wfArrayDiff2_cmp( $a, $b ) {
        if ( is_string( $a ) && is_string( $b ) ) {
                return strcmp( $a, $b );
        } elseif ( count( $a ) !== count( $b ) ) {
-               return count( $a ) < count( $b ) ? -1 : 1;
+               return count( $a ) <=> count( $b );
        } else {
                reset( $a );
                reset( $b );
@@ -209,7 +141,7 @@ function wfArrayDiff2_cmp( $a, $b ) {
 }
 
 /**
- * Like array_filter with ARRAY_FILTER_USE_BOTH, but works pre-5.6.
+ * @deprecated since 1.32, use array_filter() with ARRAY_FILTER_USE_BOTH directly
  *
  * @param array $arr
  * @param callable $callback Will be called with the array value and key (in that order) and
@@ -217,17 +149,11 @@ function wfArrayDiff2_cmp( $a, $b ) {
  * @return array
  */
 function wfArrayFilter( array $arr, callable $callback ) {
-       if ( defined( 'ARRAY_FILTER_USE_BOTH' ) ) {
-               return array_filter( $arr, $callback, ARRAY_FILTER_USE_BOTH );
-       }
-       $filteredKeys = array_filter( array_keys( $arr ), function ( $key ) use ( $arr, $callback ) {
-               return call_user_func( $callback, $arr[$key], $key );
-       } );
-       return array_intersect_key( $arr, array_fill_keys( $filteredKeys, true ) );
+       return array_filter( $arr, $callback, ARRAY_FILTER_USE_BOTH );
 }
 
 /**
- * Like array_filter with ARRAY_FILTER_USE_KEY, but works pre-5.6.
+ * @deprecated since 1.32, use array_filter() with ARRAY_FILTER_USE_KEY directly
  *
  * @param array $arr
  * @param callable $callback Will be called with the array key and should return a bool which
@@ -235,9 +161,7 @@ function wfArrayFilter( array $arr, callable $callback ) {
  * @return array
  */
 function wfArrayFilterByKey( array $arr, callable $callback ) {
-       return wfArrayFilter( $arr, function ( $val, $key ) use ( $callback ) {
-               return call_user_func( $callback, $key );
-       } );
+       return array_filter( $arr, $callback, ARRAY_FILTER_USE_KEY );
 }
 
 /**
@@ -624,17 +548,24 @@ function wfExpandUrl( $url, $defaultProto = PROTO_CURRENT ) {
        } elseif ( substr( $url, 0, 1 ) == '/' ) {
                // If $serverUrl is protocol-relative, prepend $defaultProtoWithoutSlashes,
                // otherwise leave it alone.
-               $url = ( $serverHasProto ? '' : $defaultProtoWithoutSlashes ) . $serverUrl . $url;
+               if ( $serverHasProto ) {
+                       $url = $serverUrl . $url;
+               } else {
+                       // If an HTTPS URL is synthesized from a protocol-relative $wgServer, allow the
+                       // user to override the port number (T67184)
+                       if ( $defaultProto === PROTO_HTTPS && $wgHttpsPort != 443 ) {
+                               if ( isset( $bits['port'] ) ) {
+                                       throw new Exception( 'A protocol-relative $wgServer may not contain a port number' );
+                               }
+                               $url = $defaultProtoWithoutSlashes . $serverUrl . ':' . $wgHttpsPort . $url;
+                       } else {
+                               $url = $defaultProtoWithoutSlashes . $serverUrl . $url;
+                       }
+               }
        }
 
        $bits = wfParseUrl( $url );
 
-       // ensure proper port for HTTPS arrives in URL
-       // https://phabricator.wikimedia.org/T67184
-       if ( $defaultProto === PROTO_HTTPS && $wgHttpsPort != 443 ) {
-               $bits['port'] = $wgHttpsPort;
-       }
-
        if ( $bits && isset( $bits['path'] ) ) {
                $bits['path'] = wfRemoveDotSegments( $bits['path'] );
                return wfAssembleUrl( $bits );
@@ -650,6 +581,19 @@ function wfExpandUrl( $url, $defaultProto = PROTO_CURRENT ) {
        return false;
 }
 
+/**
+ * Get the wiki's "server", i.e. the protocol and host part of the URL, with a
+ * protocol specified using a PROTO_* constant as in wfExpandUrl()
+ *
+ * @since 1.32
+ * @param string|int|null $proto One of the PROTO_* constants.
+ * @return string The URL
+ */
+function wfGetServerUrl( $proto ) {
+       $url = wfExpandUrl( '/', $proto );
+       return substr( $url, 0, -1 );
+}
+
 /**
  * This function will reassemble a URL parsed with wfParseURL.  This is useful
  * if you need to edit part of a URL and put it back together.
@@ -942,20 +886,13 @@ function wfParseUrl( $url ) {
 function wfExpandIRI( $url ) {
        return preg_replace_callback(
                '/((?:%[89A-F][0-9A-F])+)/i',
-               'wfExpandIRI_callback',
+               function ( array $matches ) {
+                       return urldecode( $matches[1] );
+               },
                wfExpandUrl( $url )
        );
 }
 
-/**
- * Private callback for wfExpandIRI
- * @param array $matches
- * @return string
- */
-function wfExpandIRI_callback( $matches ) {
-       return urldecode( $matches[1] );
-}
-
 /**
  * Make URL indexes, appropriate for the el_index field of externallinks.
  *
@@ -1405,21 +1342,19 @@ function wfGetLangObj( $langcode = false ) {
  * This function replaces all old wfMsg* functions.
  *
  * @param string|string[]|MessageSpecifier $key Message key, or array of keys, or a MessageSpecifier
- * @param mixed $params,... Normal message parameters
+ * @param string|string[] ...$params Normal message parameters
  * @return Message
  *
  * @since 1.17
  *
  * @see Message::__construct
  */
-function wfMessage( $key /*...*/ ) {
+function wfMessage( $key, ...$params ) {
        $message = new Message( $key );
 
        // We call Message::params() to reduce code duplication
-       $params = func_get_args();
-       array_shift( $params );
        if ( $params ) {
-               call_user_func_array( [ $message, 'params' ], $params );
+               $message->params( ...$params );
        }
 
        return $message;
@@ -1430,16 +1365,15 @@ function wfMessage( $key /*...*/ ) {
  * for the first message which is non-empty. If all messages are empty then an
  * instance of the first message key is returned.
  *
- * @param string|string[] $keys,... Message keys
+ * @param string ...$keys Message keys
  * @return Message
  *
  * @since 1.18
  *
  * @see Message::newFallbackSequence
  */
-function wfMessageFallback( /*...*/ ) {
-       $args = func_get_args();
-       return call_user_func_array( 'Message::newFallbackSequence', $args );
+function wfMessageFallback( ...$keys ) {
+       return Message::newFallbackSequence( ...$keys );
 }
 
 /**
@@ -1514,8 +1448,8 @@ function wfHostname() {
  * If $wgShowHostnames is true, the script will also set 'wgHostname' to the
  * hostname of the server handling the request.
  *
- * @param string $nonce Value from OutputPage::getCSPNonce
- * @return string
+ * @param string|null $nonce Value from OutputPage::getCSPNonce
+ * @return string|WrappedString HTML
  */
 function wfReportTime( $nonce = null ) {
        global $wgShowHostnames;
@@ -1585,7 +1519,7 @@ function wfBacktrace( $raw = null ) {
 
        $frames = array_map( function ( $frame ) use ( $frameFormat ) {
                $file = !empty( $frame['file'] ) ? basename( $frame['file'] ) : '-';
-               $line = isset( $frame['line'] ) ? $frame['line'] : '-';
+               $line = $frame['line'] ?? '-';
                $call = $frame['function'];
                if ( !empty( $frame['class'] ) ) {
                        $call = $frame['class'] . $frame['type'] . $call;
@@ -1699,6 +1633,7 @@ function wfClientAcceptsGzip( $force = false ) {
  * As required by the callers, "<nowiki>" is not used.
  *
  * @param string $text Text to be escaped
+ * @param-taint $text escapes_html
  * @return string
  */
 function wfEscapeWikiText( $text ) {
@@ -2051,7 +1986,7 @@ function wfTimestamp( $outputtype = TS_UNIX, $ts = 0 ) {
  * For dealing with nullable timestamp columns in the database.
  *
  * @param int $outputtype
- * @param string $ts
+ * @param string|null $ts
  * @return string
  */
 function wfTimestampOrNull( $outputtype = TS_UNIX, $ts = null ) {
@@ -2129,8 +2064,8 @@ function wfTempDir() {
  * Make directory, and make all parent directories if they don't exist
  *
  * @param string $dir Full path to directory to create
- * @param int $mode Chmod value to use, default is $wgDirectoryMode
- * @param string $caller Optional caller param for debugging.
+ * @param int|null $mode Chmod value to use, default is $wgDirectoryMode
+ * @param string|null $caller Optional caller param for debugging.
  * @throws MWException
  * @return bool
  */
@@ -2268,9 +2203,7 @@ function wfStringToBool( $val ) {
  * @deprecated since 1.30 use MediaWiki\Shell::escape()
  */
 function wfEscapeShellArg( /*...*/ ) {
-       $args = func_get_args();
-
-       return call_user_func_array( Shell::class . '::escape', $args );
+       return Shell::escape( ...func_get_args() );
 }
 
 /**
@@ -2310,7 +2243,7 @@ function wfShellExec( $cmd, &$retval = null, $environ = [],
        }
 
        $includeStderr = isset( $options['duplicateStderr'] ) && $options['duplicateStderr'];
-       $profileMethod = isset( $options['profileMethod'] ) ? $options['profileMethod'] : wfGetCaller();
+       $profileMethod = $options['profileMethod'] ?? wfGetCaller();
 
        try {
                $result = Shell::command( [] )
@@ -2373,7 +2306,7 @@ function wfShellWikiCmd( $script, array $parameters = [], array $options = [] )
        // Give site config file a chance to run the script in a wrapper.
        // The caller may likely want to call wfBasename() on $script.
        Hooks::run( 'wfShellWikiCmd', [ &$script, &$parameters, &$options ] );
-       $cmd = isset( $options['php'] ) ? [ $options['php'] ] : [ $wgPhpCli ];
+       $cmd = [ $options['php'] ?? $wgPhpCli ];
        if ( isset( $options['wrapper'] ) ) {
                $cmd[] = $options['wrapper'];
        }
@@ -2390,7 +2323,7 @@ function wfShellWikiCmd( $script, array $parameters = [], array $options = [] )
  * @param string $mine
  * @param string $yours
  * @param string &$result
- * @param string &$mergeAttemptResult
+ * @param string|null &$mergeAttemptResult
  * @return bool
  */
 function wfMerge( $old, $mine, $yours, &$result, &$mergeAttemptResult = null ) {
@@ -2596,6 +2529,8 @@ function wfUsePHP( $req_ver ) {
 function wfUseMW( $req_ver ) {
        global $wgVersion;
 
+       wfDeprecated( __FUNCTION__, '1.26' );
+
        if ( version_compare( $wgVersion, (string)$req_ver, '<' ) ) {
                throw new MWException( "MediaWiki $req_ver required--this is only $wgVersion" );
        }
@@ -2739,6 +2674,28 @@ function wfGetPrecompiledData( $name ) {
        return false;
 }
 
+/**
+ * @since 1.32
+ * @param string[] $data Array with string keys/values to export
+ * @param string $header
+ * @return string PHP code
+ */
+function wfMakeStaticArrayFile( array $data, $header = 'Automatically generated' ) {
+       $format = "\t%s => %s,\n";
+       $code = "<?php\n"
+               . "// " . implode( "\n// ", explode( "\n", $header ) ) . "\n"
+               . "return [\n";
+       foreach ( $data as $key => $value ) {
+               $code .= sprintf(
+                       $format,
+                       var_export( $key, true ),
+                       var_export( $value, true )
+               );
+       }
+       $code .= "];\n";
+       return $code;
+}
+
 /**
  * Make a cache key for the local wiki.
  *
@@ -2747,10 +2704,7 @@ function wfGetPrecompiledData( $name ) {
  * @return string
  */
 function wfMemcKey( /*...*/ ) {
-       return call_user_func_array(
-               [ ObjectCache::getLocalClusterInstance(), 'makeKey' ],
-               func_get_args()
-       );
+       return ObjectCache::getLocalClusterInstance()->makeKey( ...func_get_args() );
 }
 
 /**
@@ -2766,10 +2720,7 @@ function wfMemcKey( /*...*/ ) {
 function wfForeignMemcKey( $db, $prefix /*...*/ ) {
        $args = array_slice( func_get_args(), 2 );
        $keyspace = $prefix ? "$db-$prefix" : $db;
-       return call_user_func_array(
-               [ ObjectCache::getLocalClusterInstance(), 'makeKeyInternal' ],
-               [ $keyspace, $args ]
-       );
+       return ObjectCache::getLocalClusterInstance()->makeKeyInternal( $keyspace, $args );
 }
 
 /**
@@ -2785,10 +2736,7 @@ function wfForeignMemcKey( $db, $prefix /*...*/ ) {
  * @return string
  */
 function wfGlobalCacheKey( /*...*/ ) {
-       return call_user_func_array(
-               [ ObjectCache::getLocalClusterInstance(), 'makeGlobalKey' ],
-               func_get_args()
-       );
+       return ObjectCache::getLocalClusterInstance()->makeGlobalKey( ...func_get_args() );
 }
 
 /**
@@ -3164,6 +3112,7 @@ function wfShorthandToInteger( $string = '', $default = -1 ) {
  * @return string The language code which complying with BCP 47 standards.
  */
 function wfBCP47( $code ) {
+       wfDeprecated( __METHOD__, '1.31' );
        return LanguageCode::bcp47( $code );
 }
 
@@ -3197,17 +3146,6 @@ function wfGetMessageCacheStorage() {
        return ObjectCache::getInstance( $wgMessageCacheType );
 }
 
-/**
- * Get the cache object used by the parser cache
- *
- * @deprecated since 1.30, use MediaWikiServices::getParserCache()->getCacheStorage()
- * @return BagOStuff
- */
-function wfGetParserCacheStorage() {
-       global $wgParserCacheType;
-       return ObjectCache::getInstance( $wgParserCacheType );
-}
-
 /**
  * Call hook functions defined in $wgHooks
  *
@@ -3270,7 +3208,7 @@ function wfUnpack( $format, $data, $length = false ) {
  *
  * @param string $name The image name to check
  * @param Title|bool $contextTitle The page on which the image occurs, if known
- * @param string $blacklist Wikitext of a file blacklist
+ * @param string|null $blacklist Wikitext of a file blacklist
  * @return bool
  */
 function wfIsBadImage( $name, $contextTitle = false, $blacklist = null ) {
index c22dc97..d434120 100644 (file)
@@ -47,10 +47,6 @@ class Hooks {
         * @since 1.18
         */
        public static function register( $name, $callback ) {
-               if ( !isset( self::$handlers[$name] ) ) {
-                       self::$handlers[$name] = [];
-               }
-
                self::$handlers[$name][] = $callback;
        }
 
@@ -62,6 +58,7 @@ class Hooks {
         *
         * @since 1.21
         * @throws MWException If not in testing mode.
+        * @codeCoverageIgnore
         */
        public static function clear( $name ) {
                if ( !defined( 'MW_PHPUNIT_TEST' ) && !defined( 'MW_PARSER_TEST' ) ) {
index 019e078..ad0130b 100644 (file)
@@ -391,8 +391,8 @@ class Html {
                        unset( $attribs['type'] );
                }
                if ( $element === 'input' ) {
-                       $type = isset( $attribs['type'] ) ? $attribs['type'] : null;
-                       $value = isset( $attribs['value'] ) ? $attribs['value'] : null;
+                       $type = $attribs['type'] ?? null;
+                       $value = $attribs['value'] ?? null;
                        if ( $type === 'checkbox' || $type === 'radio' ) {
                                // The default value for checkboxes and radio buttons is 'on'
                                // not ''. By stripping value="" we break radio boxes that
@@ -557,7 +557,7 @@ class Html {
         * literal "</script>" or (for XML) literal "]]>".
         *
         * @param string $contents JavaScript
-        * @param string $nonce Nonce for CSP header, from OutputPage::getCSPNonce()
+        * @param string|null $nonce Nonce for CSP header, from OutputPage::getCSPNonce()
         * @return string Raw HTML
         */
        public static function inlineScript( $contents, $nonce = null ) {
@@ -565,7 +565,7 @@ class Html {
                if ( $nonce !== null ) {
                        $attrs['nonce'] = $nonce;
                } else {
-                       if ( ContentSecurityPolicy::isEnabled( RequestContext::getMain()->getConfig() ) ) {
+                       if ( ContentSecurityPolicy::isNonceRequired( RequestContext::getMain()->getConfig() ) ) {
                                wfWarn( "no nonce set on script. CSP will break it" );
                        }
                }
@@ -582,7 +582,7 @@ class Html {
         * "<script src=foo.js></script>".
         *
         * @param string $url
-        * @param string $nonce Nonce for CSP header, from OutputPage::getCSPNonce()
+        * @param string|null $nonce Nonce for CSP header, from OutputPage::getCSPNonce()
         * @return string Raw HTML
         */
        public static function linkedScript( $url, $nonce = null ) {
@@ -590,7 +590,7 @@ class Html {
                if ( $nonce !== null ) {
                        $attrs['nonce'] = $nonce;
                } else {
-                       if ( ContentSecurityPolicy::isEnabled( RequestContext::getMain()->getConfig() ) ) {
+                       if ( ContentSecurityPolicy::isNonceRequired( RequestContext::getMain()->getConfig() ) ) {
                                wfWarn( "no nonce set on script. CSP will break it" );
                        }
                }
@@ -925,9 +925,9 @@ class Html {
                if ( isset( $params['label'] ) ) {
                        $ret .= self::element(
                                'label', [
-                                       'for' => isset( $selectAttribs['id'] ) ? $selectAttribs['id'] : null,
+                                       'for' => $selectAttribs['id'] ?? null,
                                ], $params['label']
-                       ) . '&#160;';
+                       ) . "\u{00A0}";
                }
 
                // Wrap options in a <select>
index 790e2be..17b4d56 100644 (file)
@@ -38,9 +38,10 @@ class LinkFilter {
         *
         * @param Content $content Content to check
         * @param string $filterEntry Domainparts, see makeRegex() for more details
+        * @param string $protocol 'http://' or 'https://'
         * @return int 0 if no match or 1 if there's at least one match
         */
-       static function matchEntry( Content $content, $filterEntry ) {
+       public static function matchEntry( Content $content, $filterEntry, $protocol = 'http://' ) {
                if ( !( $content instanceof TextContent ) ) {
                        // TODO: handle other types of content too.
                        //      Maybe create ContentHandler::matchFilter( LinkFilter ).
@@ -50,7 +51,7 @@ class LinkFilter {
 
                $text = $content->getNativeData();
 
-               $regex = self::makeRegex( $filterEntry );
+               $regex = self::makeRegex( $filterEntry, $protocol );
                return preg_match( $regex, $text );
        }
 
@@ -59,10 +60,12 @@ class LinkFilter {
         *
         * @param string $filterEntry URL, if it begins with "*.", it'll be
         *        replaced to match any subdomain
+        * @param string $protocol 'http://' or 'https://'
+        *
         * @return string Regex pattern, for preg_match()
         */
-       private static function makeRegex( $filterEntry ) {
-               $regex = '!http://';
+       private static function makeRegex( $filterEntry, $protocol ) {
+               $regex = '!' . preg_quote( $protocol );
                if ( substr( $filterEntry, 0, 2 ) == '*.' ) {
                        $regex .= '(?:[A-Za-z0-9.-]+\.|)';
                        $filterEntry = substr( $filterEntry, 2 );
index 5cdbfee..f160fd6 100644 (file)
@@ -38,29 +38,6 @@ class Linker {
        const TOOL_LINKS_NOBLOCK = 1;
        const TOOL_LINKS_EMAIL = 2;
 
-       /**
-        * Return the CSS colour of a known link
-        *
-        * @deprecated since 1.28, use LinkRenderer::getLinkClasses() instead
-        *
-        * @since 1.16.3
-        * @param LinkTarget $t
-        * @param int $threshold User defined threshold
-        * @return string CSS class
-        */
-       public static function getLinkColour( LinkTarget $t, $threshold ) {
-               wfDeprecated( __METHOD__, '1.28' );
-               $services = MediaWikiServices::getInstance();
-               $linkRenderer = $services->getLinkRenderer();
-               if ( $threshold !== $linkRenderer->getStubThreshold() ) {
-                       // Need to create a new instance with the right stub threshold...
-                       $linkRenderer = $services->getLinkRendererFactory()->create();
-                       $linkRenderer->setStubThreshold( $threshold );
-               }
-
-               return $linkRenderer->getLinkClasses( $t );
-       }
-
        /**
         * This function returns an HTML link to the given target.  It serves a few
         * purposes:
@@ -328,7 +305,9 @@ class Linker {
                $res = null;
                $dummy = new DummyLinker;
                if ( !Hooks::run( 'ImageBeforeProduceHTML', [ &$dummy, &$title,
-                       &$file, &$frameParams, &$handlerParams, &$time, &$res ] ) ) {
+                       &$file, &$frameParams, &$handlerParams, &$time, &$res,
+                       $parser, &$query, &$widthOption
+               ] ) ) {
                        return $res;
                }
 
@@ -338,7 +317,7 @@ class Linker {
                }
 
                // Clean up parameters
-               $page = isset( $handlerParams['page'] ) ? $handlerParams['page'] : false;
+               $page = $handlerParams['page'] ?? false;
                if ( !isset( $frameParams['align'] ) ) {
                        $frameParams['align'] = '';
                }
@@ -442,7 +421,7 @@ class Linker {
                        $params = [
                                'alt' => $frameParams['alt'],
                                'title' => $frameParams['title'],
-                               'valign' => isset( $frameParams['valign'] ) ? $frameParams['valign'] : false,
+                               'valign' => $frameParams['valign'] ?? false,
                                'img-class' => $frameParams['class'] ];
                        if ( isset( $frameParams['border'] ) ) {
                                $params['img-class'] .= ( $params['img-class'] !== '' ? ' ' : '' ) . 'thumbborder';
@@ -504,7 +483,7 @@ class Linker {
         * @param string $manualthumb
         * @return string
         */
-       public static function makeThumbLinkObj( Title $title, $file, $label = '', $alt,
+       public static function makeThumbLinkObj( Title $title, $file, $label = '', $alt = '',
                $align = 'right', $params = [], $framed = false, $manualthumb = ""
        ) {
                $frameParams = [
@@ -535,7 +514,7 @@ class Linker {
        ) {
                $exists = $file && $file->exists();
 
-               $page = isset( $handlerParams['page'] ) ? $handlerParams['page'] : false;
+               $page = $handlerParams['page'] ?? false;
                if ( !isset( $frameParams['align'] ) ) {
                        $frameParams['align'] = 'right';
                }
@@ -826,7 +805,7 @@ class Linker {
                        $key = strtolower( $name );
                }
 
-               return self::linkKnown( SpecialPage::getTitleFor( $name ), wfMessage( $key )->text() );
+               return self::linkKnown( SpecialPage::getTitleFor( $name ), wfMessage( $key )->escaped() );
        }
 
        /**
@@ -925,7 +904,7 @@ class Linker {
         *   red if the user has no edits?
         * @param int $flags Customisation flags (e.g. Linker::TOOL_LINKS_NOBLOCK
         *   and Linker::TOOL_LINKS_EMAIL).
-        * @param int $edits User edit count (optional, for performance)
+        * @param int|null $edits User edit count (optional, for performance)
         * @return string HTML fragment
         */
        public static function userToolLinks(
@@ -987,7 +966,7 @@ class Linker {
         * @since 1.16.3
         * @param int $userId User identifier
         * @param string $userText User name or IP address
-        * @param int $edits User edit count (optional, for performance)
+        * @param int|null $edits User edit count (optional, for performance)
         * @return string
         */
        public static function userToolLinksRedContribs( $userId, $userText, $edits = null ) {
@@ -1517,7 +1496,7 @@ class Linker {
         * @return string
         */
        public static function tocIndent() {
-               return "\n<ul>";
+               return "\n<ul>\n";
        }
 
        /**
@@ -1548,9 +1527,9 @@ class Linker {
                        $classes .= " tocsection-$sectionIndex";
                }
 
-               // \n<li class="$classes"><a href="#$anchor"><span class="tocnumber">
+               // <li class="$classes"><a href="#$anchor"><span class="tocnumber">
                // $tocnumber</span> <span class="toctext">$tocline</span></a>
-               return "\n" . Html::openElement( 'li', [ 'class' => $classes ] )
+               return Html::openElement( 'li', [ 'class' => $classes ] )
                        . Html::rawElement( 'a',
                                [ 'href' => "#$anchor" ],
                                Html::element( 'span', [ 'class' => 'tocnumber' ], $tocnumber )
@@ -1583,12 +1562,25 @@ class Linker {
                $title = wfMessage( 'toc' )->inLanguage( $lang )->escaped();
 
                return '<div id="toc" class="toc">'
+                       . Html::element( 'input', [
+                               'type' => 'checkbox',
+                               'role' => 'button',
+                               'id' => 'toctogglecheckbox',
+                               'class' => 'toctogglecheckbox',
+                               'style' => 'display:none',
+                       ] )
                        . Html::openElement( 'div', [
                                'class' => 'toctitle',
                                'lang' => $lang->getHtmlCode(),
                                'dir' => $lang->getDir(),
                        ] )
-                       . '<h2>' . $title . "</h2></div>\n"
+                       . "<h2>$title</h2>"
+                       . '<span class="toctogglespan">'
+                       . Html::label( '', 'toctogglecheckbox', [
+                               'class' => 'toctogglelabel',
+                       ] )
+                       . '</span>'
+                       . "</div>\n"
                        . $toc
                        . "</ul>\n</div>\n";
        }
@@ -1699,7 +1691,7 @@ class Linker {
         * @since 1.16.3. $context added in 1.20. $options added in 1.21
         *
         * @param Revision $rev
-        * @param IContextSource $context Context to use or null for the main context.
+        * @param IContextSource|null $context Context to use or null for the main context.
         * @param array $options
         * @return string
         */
index ba22590..769e5b4 100644 (file)
@@ -58,11 +58,11 @@ class MWGrants {
                // Give grep a chance to find the usages:
                // grant-blockusers, grant-createeditmovepage, grant-delete,
                // grant-editinterface, grant-editmycssjs, grant-editmywatchlist,
-               // grant-editpage, grant-editprotected, grant-highvolume,
-               // grant-oversight, grant-patrol, grant-protect, grant-rollback,
-               // grant-sendemail, grant-uploadeditmovefile, grant-uploadfile,
-               // grant-basic, grant-viewdeleted, grant-viewmywatchlist,
-               // grant-createaccount
+               // grant-editsiteconfig, grant-editpage, grant-editprotected,
+               // grant-highvolume, grant-oversight, grant-patrol, grant-protect,
+               // grant-rollback, grant-sendemail, grant-uploadeditmovefile,
+               // grant-uploadfile, grant-basic, grant-viewdeleted,
+               // grant-viewmywatchlist, grant-createaccount
                $msg = wfMessage( "grant-$grant" );
                if ( $lang !== null ) {
                        if ( is_string( $lang ) ) {
index f2f98ba..e03a29b 100644 (file)
@@ -254,11 +254,7 @@ class MWNamespace {
         */
        public static function getCanonicalName( $index ) {
                $nslist = self::getCanonicalNamespaces();
-               if ( isset( $nslist[$index] ) ) {
-                       return $nslist[$index];
-               } else {
-                       return false;
-               }
+               return $nslist[$index] ?? false;
        }
 
        /**
@@ -472,9 +468,7 @@ class MWNamespace {
         */
        public static function getNamespaceContentModel( $index ) {
                global $wgNamespaceContentModels;
-               return isset( $wgNamespaceContentModels[$index] )
-                       ? $wgNamespaceContentModels[$index]
-                       : null;
+               return $wgNamespaceContentModels[$index] ?? null;
        }
 
        /**
@@ -483,7 +477,7 @@ class MWNamespace {
         *
         * @since 1.23
         * @param int $index Index to check
-        * @param User $user User to check
+        * @param User|null $user User to check
         * @return array
         */
        public static function getRestrictionLevels( $index, User $user = null ) {
@@ -546,4 +540,26 @@ class MWNamespace {
 
                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.
+        *
+        * @since 1.32
+        * @param int $index Namespace index
+        * @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';
+               }
+       }
 }
index 7f3649e..d28169f 100644 (file)
@@ -138,9 +138,9 @@ class MWTimestamp extends ConvertibleTimestamp {
         * Generate a purely relative timestamp, i.e., represent the time elapsed between
         * the given base timestamp and this object.
         *
-        * @param MWTimestamp $relativeTo Relative base timestamp (defaults to now)
-        * @param User $user Use to use offset for
-        * @param Language $lang Language to use
+        * @param MWTimestamp|null $relativeTo Relative base timestamp (defaults to now)
+        * @param User|null $user Use to use offset for
+        * @param Language|null $lang Language to use
         * @param array $chosenIntervals Intervals to use to represent it
         * @return string Relative timestamp
         */
index 93c8a71..a193c9f 100644 (file)
  * @ingroup Parser
  */
 
+use MediaWiki\MediaWikiServices;
+
 /**
  * This class encapsulates "magic words" such as "#redirect", __NOTOC__, etc.
  *
  * @par Usage:
  * @code
- *     if (MagicWord::get( 'redirect' )->match( $text ) ) {
+ *     if ( $magicWordFactory->get( 'redirect' )->match( $text ) ) {
  *       // some code
  *     }
  * @endcode
  *
- * Possible future improvements:
- *   * Simultaneous searching for a number of magic words
- *   * MagicWord::$mObjects in shared memory
- *
  * Please avoid reading the data out of one of these objects and then writing
  * special case code. If possible, add another match()-like function here.
  *
@@ -92,172 +90,14 @@ class MagicWord {
        /** @var bool */
        private $mFound = false;
 
-       /** @var bool */
-       public static $mVariableIDsInitialised = false;
-
-       /** @var string[] */
-       public static $mVariableIDs = [
-               '!',
-               'currentmonth',
-               'currentmonth1',
-               'currentmonthname',
-               'currentmonthnamegen',
-               'currentmonthabbrev',
-               'currentday',
-               'currentday2',
-               'currentdayname',
-               'currentyear',
-               'currenttime',
-               'currenthour',
-               'localmonth',
-               'localmonth1',
-               'localmonthname',
-               'localmonthnamegen',
-               'localmonthabbrev',
-               'localday',
-               'localday2',
-               'localdayname',
-               'localyear',
-               'localtime',
-               'localhour',
-               'numberofarticles',
-               'numberoffiles',
-               'numberofedits',
-               'articlepath',
-               'pageid',
-               'sitename',
-               'server',
-               'servername',
-               'scriptpath',
-               'stylepath',
-               'pagename',
-               'pagenamee',
-               'fullpagename',
-               'fullpagenamee',
-               'namespace',
-               'namespacee',
-               'namespacenumber',
-               'currentweek',
-               'currentdow',
-               'localweek',
-               'localdow',
-               'revisionid',
-               'revisionday',
-               'revisionday2',
-               'revisionmonth',
-               'revisionmonth1',
-               'revisionyear',
-               'revisiontimestamp',
-               'revisionuser',
-               'revisionsize',
-               'subpagename',
-               'subpagenamee',
-               'talkspace',
-               'talkspacee',
-               'subjectspace',
-               'subjectspacee',
-               'talkpagename',
-               'talkpagenamee',
-               'subjectpagename',
-               'subjectpagenamee',
-               'numberofusers',
-               'numberofactiveusers',
-               'numberofpages',
-               'currentversion',
-               'rootpagename',
-               'rootpagenamee',
-               'basepagename',
-               'basepagenamee',
-               'currenttimestamp',
-               'localtimestamp',
-               'directionmark',
-               'contentlanguage',
-               'pagelanguage',
-               'numberofadmins',
-               'cascadingsources',
-       ];
-
-       /** Array of caching hints for ParserCache
-        * @var array [ string => int ]
-        */
-       public static $mCacheTTLs = [
-               'currentmonth' => 86400,
-               'currentmonth1' => 86400,
-               'currentmonthname' => 86400,
-               'currentmonthnamegen' => 86400,
-               'currentmonthabbrev' => 86400,
-               'currentday' => 3600,
-               'currentday2' => 3600,
-               'currentdayname' => 3600,
-               'currentyear' => 86400,
-               'currenttime' => 3600,
-               'currenthour' => 3600,
-               'localmonth' => 86400,
-               'localmonth1' => 86400,
-               'localmonthname' => 86400,
-               'localmonthnamegen' => 86400,
-               'localmonthabbrev' => 86400,
-               'localday' => 3600,
-               'localday2' => 3600,
-               'localdayname' => 3600,
-               'localyear' => 86400,
-               'localtime' => 3600,
-               'localhour' => 3600,
-               'numberofarticles' => 3600,
-               'numberoffiles' => 3600,
-               'numberofedits' => 3600,
-               'currentweek' => 3600,
-               'currentdow' => 3600,
-               'localweek' => 3600,
-               'localdow' => 3600,
-               'numberofusers' => 3600,
-               'numberofactiveusers' => 3600,
-               'numberofpages' => 3600,
-               'currentversion' => 86400,
-               'currenttimestamp' => 3600,
-               'localtimestamp' => 3600,
-               'pagesinnamespace' => 3600,
-               'numberofadmins' => 3600,
-               'numberingroup' => 3600,
-       ];
-
-       /** @var string[] */
-       public static $mDoubleUnderscoreIDs = [
-               'notoc',
-               'nogallery',
-               'forcetoc',
-               'toc',
-               'noeditsection',
-               'newsectionlink',
-               'nonewsectionlink',
-               'hiddencat',
-               'index',
-               'noindex',
-               'staticredirect',
-               'notitleconvert',
-               'nocontentconvert',
-       ];
-
-       /** @var string[] */
-       public static $mSubstIDs = [
-               'subst',
-               'safesubst',
-       ];
-
-       /** @var array [ string => MagicWord ] */
-       public static $mObjects = [];
-
-       /** @var MagicWordArray */
-       public static $mDoubleUnderscoreArray = null;
-
        /**#@-*/
 
        /**
         * Create a new MagicWord object
         *
-        * Use factory instead: MagicWord::get
+        * Use factory instead: MagicWordFactory::get
         *
-        * @param string $id The internal name of the magic word
+        * @param string|null $id The internal name of the magic word
         * @param string[]|string $syn synonyms for the magic word
         * @param bool $cs If magic word is case sensitive
         */
@@ -273,36 +113,29 @@ class MagicWord {
         * @param string $id The internal name of the magic word
         *
         * @return MagicWord
+        * @deprecated since 1.32, use MagicWordFactory::get
         */
-       public static function &get( $id ) {
-               if ( !isset( self::$mObjects[$id] ) ) {
-                       $mw = new MagicWord();
-                       $mw->load( $id );
-                       self::$mObjects[$id] = $mw;
-               }
-               return self::$mObjects[$id];
+       public static function get( $id ) {
+               return MediaWikiServices::getInstance()->getMagicWordFactory()->get( $id );
        }
 
        /**
         * Get an array of parser variable IDs
         *
         * @return string[]
+        * @deprecated since 1.32, use MagicWordFactory::getVariableIDs
         */
        public static function getVariableIDs() {
-               if ( !self::$mVariableIDsInitialised ) {
-                       # Get variable IDs
-                       Hooks::run( 'MagicWordwgVariableIDs', [ &self::$mVariableIDs ] );
-                       self::$mVariableIDsInitialised = true;
-               }
-               return self::$mVariableIDs;
+               return MediaWikiServices::getInstance()->getMagicWordFactory()->getVariableIDs();
        }
 
        /**
         * Get an array of parser substitution modifier IDs
         * @return string[]
+        * @deprecated since 1.32, use MagicWordFactory::getSubstIDs
         */
        public static function getSubstIDs() {
-               return self::$mSubstIDs;
+               return MediaWikiServices::getInstance()->getMagicWordFactory()->getSubstIDs();
        }
 
        /**
@@ -310,34 +143,20 @@ class MagicWord {
         *
         * @param string $id
         * @return int
+        * @deprecated since 1.32, use MagicWordFactory::getCacheTTL
         */
        public static function getCacheTTL( $id ) {
-               if ( array_key_exists( $id, self::$mCacheTTLs ) ) {
-                       return self::$mCacheTTLs[$id];
-               } else {
-                       return -1;
-               }
+               return MediaWikiServices::getInstance()->getMagicWordFactory()->getCacheTTL( $id );
        }
 
        /**
         * Get a MagicWordArray of double-underscore entities
         *
         * @return MagicWordArray
+        * @deprecated since 1.32, use MagicWordFactory::getDoubleUnderscoreArray
         */
        public static function getDoubleUnderscoreArray() {
-               if ( is_null( self::$mDoubleUnderscoreArray ) ) {
-                       Hooks::run( 'GetDoubleUnderscoreIDs', [ &self::$mDoubleUnderscoreIDs ] );
-                       self::$mDoubleUnderscoreArray = new MagicWordArray( self::$mDoubleUnderscoreIDs );
-               }
-               return self::$mDoubleUnderscoreArray;
-       }
-
-       /**
-        * Clear the self::$mObjects variable
-        * For use in parser tests
-        */
-       public static function clearCache() {
-               self::$mObjects = [];
+               return MediaWikiServices::getInstance()->getMagicWordFactory()->getDoubleUnderscoreArray();
        }
 
        /**
@@ -395,13 +214,7 @@ class MagicWord {
        public function compareStringLength( $s1, $s2 ) {
                $l1 = strlen( $s1 );
                $l2 = strlen( $s2 );
-               if ( $l1 < $l2 ) {
-                       return 1;
-               } elseif ( $l1 > $l2 ) {
-                       return -1;
-               } else {
-                       return 0;
-               }
+               return $l2 <=> $l1; // descending
        }
 
        /**
index 4010ec7..20ac680 100644 (file)
@@ -23,6 +23,7 @@
  */
 
 use MediaWiki\Logger\LoggerFactory;
+use MediaWiki\MediaWikiServices;
 
 /**
  * Class for handling an array of magic words
@@ -32,6 +33,9 @@ class MagicWordArray {
        /** @var array */
        public $names = [];
 
+       /** @var MagicWordFactory */
+       private $factory;
+
        /** @var array */
        private $hash;
 
@@ -41,9 +45,14 @@ class MagicWordArray {
 
        /**
         * @param array $names
+        * @param MagicWordFactory|null $factory
         */
-       public function __construct( $names = [] ) {
+       public function __construct( $names = [], MagicWordFactory $factory = null ) {
                $this->names = $names;
+               $this->factory = $factory;
+               if ( !$factory ) {
+                       $this->factory = MediaWikiServices::getInstance()->getMagicWordFactory();
+               }
        }
 
        /**
@@ -75,7 +84,7 @@ class MagicWordArray {
                        global $wgContLang;
                        $this->hash = [ 0 => [], 1 => [] ];
                        foreach ( $this->names as $name ) {
-                               $magic = MagicWord::get( $name );
+                               $magic = $this->factory->get( $name );
                                $case = intval( $magic->isCaseSensitive() );
                                foreach ( $magic->getSynonyms() as $syn ) {
                                        if ( !$case ) {
@@ -97,7 +106,7 @@ class MagicWordArray {
                        $this->baseRegex = [ 0 => '', 1 => '' ];
                        $allGroups = [];
                        foreach ( $this->names as $name ) {
-                               $magic = MagicWord::get( $name );
+                               $magic = $this->factory->get( $name );
                                $case = intval( $magic->isCaseSensitive() );
                                foreach ( $magic->getSynonyms() as $i => $syn ) {
                                        // Group name must start with a non-digit in PCRE 8.34+
diff --git a/includes/MagicWordFactory.php b/includes/MagicWordFactory.php
new file mode 100644 (file)
index 0000000..15a7678
--- /dev/null
@@ -0,0 +1,271 @@
+<?php
+/**
+ * See docs/magicword.txt.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup Parser
+ */
+
+/**
+ * A factory that stores information about MagicWords, and creates them on demand with caching.
+ *
+ * Possible future improvements:
+ *   * Simultaneous searching for a number of magic words
+ *   * $mObjects in shared memory
+ *
+ * @since 1.32
+ * @ingroup Parser
+ */
+class MagicWordFactory {
+       /**#@-*/
+
+       /** @var bool */
+       private $mVariableIDsInitialised = false;
+
+       /** @var string[] */
+       private $mVariableIDs = [
+               '!',
+               'currentmonth',
+               'currentmonth1',
+               'currentmonthname',
+               'currentmonthnamegen',
+               'currentmonthabbrev',
+               'currentday',
+               'currentday2',
+               'currentdayname',
+               'currentyear',
+               'currenttime',
+               'currenthour',
+               'localmonth',
+               'localmonth1',
+               'localmonthname',
+               'localmonthnamegen',
+               'localmonthabbrev',
+               'localday',
+               'localday2',
+               'localdayname',
+               'localyear',
+               'localtime',
+               'localhour',
+               'numberofarticles',
+               'numberoffiles',
+               'numberofedits',
+               'articlepath',
+               'pageid',
+               'sitename',
+               'server',
+               'servername',
+               'scriptpath',
+               'stylepath',
+               'pagename',
+               'pagenamee',
+               'fullpagename',
+               'fullpagenamee',
+               'namespace',
+               'namespacee',
+               'namespacenumber',
+               'currentweek',
+               'currentdow',
+               'localweek',
+               'localdow',
+               'revisionid',
+               'revisionday',
+               'revisionday2',
+               'revisionmonth',
+               'revisionmonth1',
+               'revisionyear',
+               'revisiontimestamp',
+               'revisionuser',
+               'revisionsize',
+               'subpagename',
+               'subpagenamee',
+               'talkspace',
+               'talkspacee',
+               'subjectspace',
+               'subjectspacee',
+               'talkpagename',
+               'talkpagenamee',
+               'subjectpagename',
+               'subjectpagenamee',
+               'numberofusers',
+               'numberofactiveusers',
+               'numberofpages',
+               'currentversion',
+               'rootpagename',
+               'rootpagenamee',
+               'basepagename',
+               'basepagenamee',
+               'currenttimestamp',
+               'localtimestamp',
+               'directionmark',
+               'contentlanguage',
+               'pagelanguage',
+               'numberofadmins',
+               'cascadingsources',
+       ];
+
+       /** Array of caching hints for ParserCache
+        * @var array [ string => int ]
+        */
+       private $mCacheTTLs = [
+               'currentmonth' => 86400,
+               'currentmonth1' => 86400,
+               'currentmonthname' => 86400,
+               'currentmonthnamegen' => 86400,
+               'currentmonthabbrev' => 86400,
+               'currentday' => 3600,
+               'currentday2' => 3600,
+               'currentdayname' => 3600,
+               'currentyear' => 86400,
+               'currenttime' => 3600,
+               'currenthour' => 3600,
+               'localmonth' => 86400,
+               'localmonth1' => 86400,
+               'localmonthname' => 86400,
+               'localmonthnamegen' => 86400,
+               'localmonthabbrev' => 86400,
+               'localday' => 3600,
+               'localday2' => 3600,
+               'localdayname' => 3600,
+               'localyear' => 86400,
+               'localtime' => 3600,
+               'localhour' => 3600,
+               'numberofarticles' => 3600,
+               'numberoffiles' => 3600,
+               'numberofedits' => 3600,
+               'currentweek' => 3600,
+               'currentdow' => 3600,
+               'localweek' => 3600,
+               'localdow' => 3600,
+               'numberofusers' => 3600,
+               'numberofactiveusers' => 3600,
+               'numberofpages' => 3600,
+               'currentversion' => 86400,
+               'currenttimestamp' => 3600,
+               'localtimestamp' => 3600,
+               'pagesinnamespace' => 3600,
+               'numberofadmins' => 3600,
+               'numberingroup' => 3600,
+       ];
+
+       /** @var string[] */
+       private $mDoubleUnderscoreIDs = [
+               'notoc',
+               'nogallery',
+               'forcetoc',
+               'toc',
+               'noeditsection',
+               'newsectionlink',
+               'nonewsectionlink',
+               'hiddencat',
+               'index',
+               'noindex',
+               'staticredirect',
+               'notitleconvert',
+               'nocontentconvert',
+       ];
+
+       /** @var string[] */
+       private $mSubstIDs = [
+               'subst',
+               'safesubst',
+       ];
+
+       /** @var array [ string => MagicWord ] */
+       private $mObjects = [];
+
+       /** @var MagicWordArray */
+       private $mDoubleUnderscoreArray = null;
+
+       /**#@-*/
+
+       /**
+        * Factory: creates an object representing an ID
+        *
+        * @param string $id The internal name of the magic word
+        *
+        * @return MagicWord
+        */
+       public function get( $id ) {
+               if ( !isset( $this->mObjects[$id] ) ) {
+                       $mw = new MagicWord();
+                       $mw->load( $id );
+                       $this->mObjects[$id] = $mw;
+               }
+               return $this->mObjects[$id];
+       }
+
+       /**
+        * Get an array of parser variable IDs
+        *
+        * @return string[]
+        */
+       public function getVariableIDs() {
+               if ( !$this->mVariableIDsInitialised ) {
+                       # Get variable IDs
+                       Hooks::run( 'MagicWordwgVariableIDs', [ &$this->mVariableIDs ] );
+                       $this->mVariableIDsInitialised = true;
+               }
+               return $this->mVariableIDs;
+       }
+
+       /**
+        * Get an array of parser substitution modifier IDs
+        * @return string[]
+        */
+       public function getSubstIDs() {
+               return $this->mSubstIDs;
+       }
+
+       /**
+        * Allow external reads of TTL array
+        *
+        * @param string $id
+        * @return int
+        */
+       public function getCacheTTL( $id ) {
+               if ( array_key_exists( $id, $this->mCacheTTLs ) ) {
+                       return $this->mCacheTTLs[$id];
+               } else {
+                       return -1;
+               }
+       }
+
+       /**
+        * Get a MagicWordArray of double-underscore entities
+        *
+        * @return MagicWordArray
+        */
+       public function getDoubleUnderscoreArray() {
+               if ( is_null( $this->mDoubleUnderscoreArray ) ) {
+                       Hooks::run( 'GetDoubleUnderscoreIDs', [ &$this->mDoubleUnderscoreIDs ] );
+                       $this->mDoubleUnderscoreArray = $this->newArray( $this->mDoubleUnderscoreIDs );
+               }
+               return $this->mDoubleUnderscoreArray;
+       }
+
+       /**
+        * Get a new MagicWordArray with provided $names
+        *
+        * @param array $names
+        * @return MagicWordArray
+        */
+       public function newArray( array $names = [] ) : MagicWordArray {
+               return new MagicWordArray( $names, $this );
+       }
+}
index 459a7e1..a67cb9b 100644 (file)
@@ -90,7 +90,7 @@ class MediaWiki {
                        }
                        // Check variant links so that interwiki links don't have to worry
                        // about the possible different language variants
-                       if ( count( $wgContLang->getVariants() ) > 1
+                       if ( $wgContLang->hasVariants()
                                && !is_null( $ret ) && $ret->getArticleID() == 0
                        ) {
                                $wgContLang->findVariantLink( $title, $ret );
@@ -104,7 +104,7 @@ class MediaWiki {
                if ( $ret === null || !$ret->isSpecialPage() ) {
                        // We can have urls with just ?diff=,?oldid= or even just ?diff=
                        $oldid = $request->getInt( 'oldid' );
-                       $oldid = $oldid ? $oldid : $request->getInt( 'diff' );
+                       $oldid = $oldid ?: $request->getInt( 'diff' );
                        // Allow oldid to override a changed or missing title
                        if ( $oldid ) {
                                $rev = Revision::newFromId( $oldid );
@@ -426,7 +426,7 @@ class MediaWiki {
                        // If $target is set, then a hook wanted to redirect.
                        if ( !$ignoreRedirect && ( $target || $page->isRedirect() ) ) {
                                // Is the target already set by an extension?
-                               $target = $target ? $target : $page->followRedirect();
+                               $target = $target ?: $page->followRedirect();
                                if ( is_string( $target ) ) {
                                        if ( !$this->config->get( 'DisableHardRedirects' ) ) {
                                                // we'll need to redirect
@@ -568,7 +568,7 @@ class MediaWiki {
 
        /**
         * @see MediaWiki::preOutputCommit()
-        * @param callable $postCommitWork [default: null]
+        * @param callable|null $postCommitWork [default: null]
         * @since 1.26
         */
        public function doPreOutputCommit( callable $postCommitWork = null ) {
@@ -580,7 +580,7 @@ class MediaWiki {
         * the user can receive a response (in case commit fails)
         *
         * @param IContextSource $context
-        * @param callable $postCommitWork [default: null]
+        * @param callable|null $postCommitWork [default: null]
         * @since 1.27
         */
        public static function preOutputCommit(
@@ -631,7 +631,8 @@ class MediaWiki {
 
                // Record ChronologyProtector positions for DBs affected in this request at this point
                $cpIndex = null;
-               $lbFactory->shutdown( $flags, $postCommitWork, $cpIndex );
+               $cpClientId = null;
+               $lbFactory->shutdown( $flags, $postCommitWork, $cpIndex, $cpClientId );
                wfDebug( __METHOD__ . ': LBFactory shutdown completed' );
 
                if ( $cpIndex > 0 ) {
@@ -639,7 +640,7 @@ class MediaWiki {
                                $now = time();
                                $expires = $now + ChronologyProtector::POSITION_COOKIE_TTL;
                                $options = [ 'prefix' => '' ];
-                               $value = LBFactory::makeCookieValueFromCPIndex( $cpIndex, $now ); // T190082
+                               $value = LBFactory::makeCookieValueFromCPIndex( $cpIndex, $now, $cpClientId );
                                $request->response()->setCookie( 'cpPosIndex', $value, $expires, $options );
                        }
 
@@ -722,6 +723,9 @@ class MediaWiki {
                        MWExceptionHandler::rollbackMasterChangesAndLog( $e );
                }
 
+               // Disable WebResponse setters for post-send processing (T191537).
+               WebResponse::disableForPostSend();
+
                $blocksHttpClient = true;
                // Defer everything else if possible...
                $callback = function () use ( $mode, &$blocksHttpClient ) {
@@ -939,7 +943,7 @@ class MediaWiki {
                        try {
                                $statsdServer = explode( ':', $config->get( 'StatsdServer' ) );
                                $statsdHost = $statsdServer[0];
-                               $statsdPort = isset( $statsdServer[1] ) ? $statsdServer[1] : 8125;
+                               $statsdPort = $statsdServer[1] ?? 8125;
                                $statsdSender = new SocketSender( $statsdHost, $statsdPort );
                                $statsdClient = new SamplingStatsdClient( $statsdSender, true, false );
                                $statsdClient->setSamplingRates( $config->get( 'StatsdSamplingRates' ) );
index ac98683..f891042 100644 (file)
@@ -21,10 +21,13 @@ use MediaWiki\Storage\NameTableStore;
 use MediaWiki\Storage\RevisionFactory;
 use MediaWiki\Storage\RevisionLookup;
 use MediaWiki\Storage\RevisionStore;
+use OldRevisionImporter;
+use UploadRevisionImporter;
 use Wikimedia\Rdbms\LBFactory;
 use LinkCache;
 use Wikimedia\Rdbms\LoadBalancer;
 use MediaHandlerFactory;
+use MediaWiki\Config\ConfigRepository;
 use MediaWiki\Linker\LinkRenderer;
 use MediaWiki\Linker\LinkRendererFactory;
 use MediaWiki\Services\SalvageableService;
@@ -48,6 +51,7 @@ use TitleFormatter;
 use TitleParser;
 use VirtualRESTServiceClient;
 use MediaWiki\Interwiki\InterwikiLookup;
+use MagicWordFactory;
 
 /**
  * Service locator for MediaWiki core services.
@@ -464,6 +468,14 @@ class MediaWikiServices extends ServiceContainer {
                return $this->getService( 'StatsdDataFactory' );
        }
 
+       /**
+        * @since 1.32
+        * @return IBufferingStatsdDataFactory
+        */
+       public function getPerDbNameStatsdDataFactory() {
+               return $this->getService( 'PerDbNameStatsdDataFactory' );
+       }
+
        /**
         * @since 1.27
         * @return EventRelayerGroup
@@ -539,6 +551,7 @@ class MediaWikiServices extends ServiceContainer {
 
        /**
         * @since 1.28
+        * @deprecated since 1.32, use random_bytes()/random_int()
         * @return CryptRand
         */
        public function getCryptRand() {
@@ -788,6 +801,14 @@ class MediaWikiServices extends ServiceContainer {
                return $this->getService( 'SlotRoleStore' );
        }
 
+       /**
+        * @since 1.32
+        * @return NameTableStore
+        */
+       public function getChangeTagDefStore() {
+               return $this->getService( 'ChangeTagDefStore' );
+       }
+
        /**
         * @since 1.31
         * @return PreferencesFactory
@@ -820,6 +841,38 @@ class MediaWikiServices extends ServiceContainer {
                return $this->getService( 'ActorMigration' );
        }
 
+       /**
+        * @since 1.32
+        * @return UploadRevisionImporter
+        */
+       public function getUploadRevisionImporter() {
+               return $this->getService( 'UploadRevisionImporter' );
+       }
+
+       /**
+        * @since 1.32
+        * @return OldRevisionImporter
+        */
+       public function getOldRevisionImporter() {
+               return $this->getService( 'OldRevisionImporter' );
+       }
+
+       /**
+        * @since 1.32
+        * @return ConfigRepository
+        */
+       public function getConfigRepository() {
+               return $this->getService( 'ConfigRepository' );
+       }
+
+       /**
+        * @since 1.32
+        * @return MagicWordFactory
+        */
+       public function getMagicWordFactory() {
+               return $this->getService( 'MagicWordFactory' );
+       }
+
        ///////////////////////////////////////////////////////////////////////////
        // NOTE: When adding a service getter here, don't forget to add a test
        // case for it in MediaWikiServicesTest::provideGetters() and in
index 0e9bb46..0914a9b 100644 (file)
@@ -167,7 +167,7 @@ class MergeHistory {
                // Convert into a Status object
                if ( $errors ) {
                        foreach ( $errors as $error ) {
-                               call_user_func_array( [ $status, 'fatal' ], $error );
+                               $status->fatal( ...$error );
                        }
                }
 
@@ -254,6 +254,8 @@ class MergeHistory {
                        return $permCheck;
                }
 
+               $this->dbw->startAtomic( __METHOD__ );
+
                $this->dbw->update(
                        'revision',
                        [ 'rev_page' => $this->dest->getArticleID() ],
@@ -264,17 +266,17 @@ class MergeHistory {
                // Check if this did anything
                $this->revisionsMerged = $this->dbw->affectedRows();
                if ( $this->revisionsMerged < 1 ) {
+                       $this->dbw->endAtomic( __METHOD__ );
                        $status->fatal( 'mergehistory-fail-no-change' );
+
                        return $status;
                }
 
                // Make the source page a redirect if no revisions are left
-               $haveRevisions = $this->dbw->selectField(
+               $haveRevisions = $this->dbw->lockForUpdate(
                        'revision',
-                       'rev_timestamp',
                        [ 'rev_page' => $this->source->getArticleID() ],
-                       __METHOD__,
-                       [ 'FOR UPDATE' ]
+                       __METHOD__
                );
                if ( !$haveRevisions ) {
                        if ( $reason ) {
@@ -350,6 +352,8 @@ class MergeHistory {
 
                Hooks::run( 'ArticleMergeComplete', [ $this->source, $this->dest ] );
 
+               $this->dbw->endAtomic( __METHOD__ );
+
                return $status;
        }
 }
index 7d05f41..5ca0942 100644 (file)
@@ -242,7 +242,7 @@ class Message implements MessageSpecifier, Serializable {
         * message keys to try and use the first non-empty message for, or a
         * MessageSpecifier to copy from.
         * @param array $params Message parameters.
-        * @param Language $language [optional] Language to use (defaults to current user language).
+        * @param Language|null $language [optional] Language to use (defaults to current user language).
         * @throws InvalidArgumentException
         */
        public function __construct( $key, $params = [], Language $language = null ) {
@@ -726,6 +726,8 @@ class Message implements MessageSpecifier, Serializable {
         * @throws MWException
         */
        public function inLanguage( $lang ) {
+               $previousLanguage = $this->language;
+
                if ( $lang instanceof Language ) {
                        $this->language = $lang;
                } elseif ( is_string( $lang ) ) {
@@ -740,7 +742,11 @@ class Message implements MessageSpecifier, Serializable {
                                . "passed a String or Language object; $type given"
                        );
                }
-               $this->message = null;
+
+               if ( $this->language !== $previousLanguage ) {
+                       // The language has changed. Clear the message cache.
+                       $this->message = null;
+               }
                $this->interface = false;
                return $this;
        }
@@ -831,6 +837,7 @@ class Message implements MessageSpecifier, Serializable {
         *   the last time (this is for B/C and should be avoided).
         *
         * @return string HTML
+        * @suppress SecurityCheck-DoubleEscaped phan false positive
         */
        public function toString( $format = null ) {
                if ( $format === null ) {
@@ -1122,7 +1129,7 @@ class Message implements MessageSpecifier, Serializable {
         *
         * @return string
         */
-       protected function replaceParameters( $message, $type = 'before', $format ) {
+       protected function replaceParameters( $message, $type, $format ) {
                // A temporary marker for $1 parameters that is only valid
                // in non-attribute contexts. However if the entire message is escaped
                // then we don't want to use it because it will be mangled in all contexts
index fc9f6a6..ec44b6e 100644 (file)
@@ -57,7 +57,7 @@ class MovePage {
                // Convert into a Status object
                if ( $errors ) {
                        foreach ( $errors as $error ) {
-                               call_user_func_array( [ $status, 'fatal' ], $error );
+                               $status->fatal( ...$error );
                        }
                }
 
@@ -280,13 +280,7 @@ class MovePage {
                        [ 'cl_from' => $pageid ],
                        __METHOD__
                );
-               if ( $this->newTitle->getNamespace() == NS_CATEGORY ) {
-                       $type = 'subcat';
-               } elseif ( $this->newTitle->getNamespace() == NS_FILE ) {
-                       $type = 'file';
-               } else {
-                       $type = 'page';
-               }
+               $type = MWNamespace::getCategoryLinkType( $this->newTitle->getNamespace() );
                foreach ( $prefixes as $prefixRow ) {
                        $prefix = $prefixRow->cl_sortkey_prefix;
                        $catTo = $prefixRow->cl_to;
@@ -415,7 +409,9 @@ class MovePage {
                        new AtomicSectionUpdate(
                                $dbw,
                                __METHOD__,
-                               function () use ( $params ) {
+                               // Hold onto $user to avoid HHVM bug where it no longer
+                               // becomes a reference (T118683)
+                               function () use ( $params, &$user ) {
                                        Hooks::run( 'TitleMoveComplete', $params );
                                }
                        )
index 46e9630..f6f4cd3 100644 (file)
@@ -52,7 +52,7 @@ try {
        echo $templateParser->processTemplate(
                'NoLocalSettings',
                [
-                       'wgVersion' => ( isset( $wgVersion ) ? $wgVersion : 'VERSION' ),
+                       'wgVersion' => ( $wgVersion ?? 'VERSION' ),
                        'path' => $path,
                        'localSettingsExists' => file_exists( MW_CONFIG_FILE ),
                        'installerStarted' => $installerStarted
index 6c45d9c..aa517e7 100644 (file)
@@ -24,6 +24,7 @@ use MediaWiki\Linker\LinkTarget;
 use MediaWiki\Logger\LoggerFactory;
 use MediaWiki\MediaWikiServices;
 use MediaWiki\Session\SessionManager;
+use Wikimedia\Rdbms\IResultWrapper;
 use Wikimedia\RelPath;
 use Wikimedia\WrappedString;
 use Wikimedia\WrappedStringList;
@@ -54,9 +55,8 @@ class OutputPage extends ContextSource {
        protected $mCanonicalUrl = false;
 
        /**
-        * @var string Should be private - has getter and setter. Contains
-        *   the HTML title */
-       public $mPagetitle = '';
+        * @var string The contents of <h1> */
+       private $mPageTitle = '';
 
        /**
         * @var string Contains all of the "<body>" content. Should be private we
@@ -222,9 +222,6 @@ class OutputPage extends ContextSource {
         */
        public $mNoGallery = false;
 
-       /** @var string */
-       private $mPageTitleActionText = '';
-
        /** @var int Cache stuff. Looks like mEnableClientCache */
        protected $mCdnMaxage = 0;
        /** @var int Upper limit on mCdnMaxage */
@@ -403,18 +400,6 @@ class OutputPage extends ContextSource {
                return $this->mLinktags;
        }
 
-       /**
-        * Add a new \<link\> with "rel" attribute set to "meta"
-        *
-        * @param array $linkarr Associative array mapping attribute names to their
-        *                 values, both keys and values will be escaped, and the
-        *                 "rel" attribute will be automatically added
-        */
-       function addMetadataLink( array $linkarr ) {
-               $linkarr['rel'] = $this->getMetadataAttribute();
-               $this->addLink( $linkarr );
-       }
-
        /**
         * Set the URL to be used for the <link rel=canonical>. This should be used
         * in preference to addLink(), to avoid duplicate link tags.
@@ -435,22 +420,6 @@ class OutputPage extends ContextSource {
                return $this->mCanonicalUrl;
        }
 
-       /**
-        * Get the value of the "rel" attribute for metadata links
-        *
-        * @return string
-        */
-       public function getMetadataAttribute() {
-               # note: buggy CC software only reads first "meta" link
-               static $haveMeta = false;
-               if ( $haveMeta ) {
-                       return 'alternate meta';
-               } else {
-                       $haveMeta = true;
-                       return 'meta';
-               }
-       }
-
        /**
         * Add raw HTML to the list of scripts (including \<script\> tag, etc.)
         * Internal use only. Use OutputPage::addModules() or OutputPage::addJsConfigVars()
@@ -468,9 +437,9 @@ class OutputPage extends ContextSource {
         * Internal use only. Use OutputPage::addModules() if possible.
         *
         * @param string $file URL to file (absolute path, protocol-relative, or full url)
-        * @param string $version Style version of the file. Defaults to $wgStyleVersion
+        * @param string|null $unused Previously used to change the cache-busting query parameter
         */
-       public function addScriptFile( $file, $version = null ) {
+       public function addScriptFile( $file, $unused = null ) {
                if ( substr( $file, 0, 1 ) !== '/' && !preg_match( '#^[a-z]*://#i', $file ) ) {
                        // This is not an absolute path, protocol-relative url, or full scheme url,
                        // presumed to be an old call intended to include a file from /w/skins/common,
@@ -478,11 +447,7 @@ class OutputPage extends ContextSource {
                        wfDeprecated( __METHOD__, '1.24' );
                        return;
                }
-               $path = $file;
-               if ( is_null( $version ) ) {
-                       $version = $this->getConfig()->get( 'StyleVersion' );
-               }
-               $this->addScript( Html::linkedScript( wfAppendQuery( $path, $version ), $this->getCSPNonce() ) );
+               $this->addScript( Html::linkedScript( $file, $this->getCSPNonce() ) );
        }
 
        /**
@@ -646,9 +611,7 @@ class OutputPage extends ContextSource {
                        // Register a callback for $this->contentOverrides on the first call
                        $this->addContentOverrideCallback( function ( LinkTarget $target ) {
                                $key = $target->getNamespace() . ':' . $target->getDBkey();
-                               return isset( $this->contentOverrides[$key] )
-                                       ? $this->contentOverrides[$key]
-                                       : null;
+                               return $this->contentOverrides[$key] ?? null;
                        } );
                }
 
@@ -761,11 +724,7 @@ class OutputPage extends ContextSource {
         * @return mixed Property value or null if not found
         */
        public function getProperty( $name ) {
-               if ( isset( $this->mProperties[$name] ) ) {
-                       return $this->mProperties[$name];
-               } else {
-                       return null;
-               }
+               return $this->mProperties[$name] ?? null;
        }
 
        /**
@@ -818,7 +777,7 @@ class OutputPage extends ContextSource {
                # this breaks strtotime().
                $clientHeader = preg_replace( '/;.*$/', '', $clientHeader );
 
-               Wikimedia\suppressWarnings(); // E_STRICT system time bitching
+               Wikimedia\suppressWarnings(); // E_STRICT system time warnings
                $clientHeaderTime = strtotime( $clientHeader );
                Wikimedia\restoreWarnings();
                if ( !$clientHeaderTime ) {
@@ -932,25 +891,6 @@ class OutputPage extends ContextSource {
                }
        }
 
-       /**
-        * Set the new value of the "action text", this will be added to the
-        * "HTML title", separated from it with " - ".
-        *
-        * @param string $text New value of the "action text"
-        */
-       public function setPageTitleActionText( $text ) {
-               $this->mPageTitleActionText = $text;
-       }
-
-       /**
-        * Get the value of the "action text"
-        *
-        * @return string
-        */
-       public function getPageTitleActionText() {
-               return $this->mPageTitleActionText;
-       }
-
        /**
         * "HTML title" means the contents of "<title>".
         * It is stored as plain, unescaped text and will be run through htmlspecialchars in the skin file.
@@ -1001,7 +941,7 @@ class OutputPage extends ContextSource {
                # change "<script>foo&bar</script>" to "&lt;script&gt;foo&amp;bar&lt;/script&gt;"
                # but leave "<i>foobar</i>" alone
                $nameWithTags = Sanitizer::normalizeCharReferences( Sanitizer::removeHTMLtags( $name ) );
-               $this->mPagetitle = $nameWithTags;
+               $this->mPageTitle = $nameWithTags;
 
                # change "<i>foo&amp;bar</i>" to "foo&bar"
                $this->setHTMLTitle(
@@ -1016,7 +956,7 @@ class OutputPage extends ContextSource {
         * @return string
         */
        public function getPageTitle() {
-               return $this->mPagetitle;
+               return $this->mPageTitle;
        }
 
        /**
@@ -1272,7 +1212,7 @@ class OutputPage extends ContextSource {
         *                               (e.g. 'fr:Test page')
         */
        public function addLanguageLinks( array $newLinkArray ) {
-               $this->mLanguageLinks += $newLinkArray;
+               $this->mLanguageLinks = array_merge( $this->mLanguageLinks, $newLinkArray );
        }
 
        /**
@@ -1347,7 +1287,7 @@ class OutputPage extends ContextSource {
 
        /**
         * @param array $categories
-        * @return bool|ResultWrapper
+        * @return bool|IResultWrapper
         */
        protected function addCategoryLinksToLBAndGetResult( array $categories ) {
                # Add the links to a LinkBatch
@@ -1374,7 +1314,8 @@ class OutputPage extends ContextSource {
                );
 
                # Add the results to the link cache
-               $lb->addResultToCache( LinkCache::singleton(), $res );
+               $linkCache = MediaWikiServices::getInstance()->getLinkCache();
+               $lb->addResultToCache( $linkCache, $res );
 
                return $res;
        }
@@ -1520,9 +1461,7 @@ class OutputPage extends ContextSource {
                if ( $type == ResourceLoaderModule::TYPE_COMBINED ) {
                        return min( array_values( $this->mAllowedModules ) );
                } else {
-                       return isset( $this->mAllowedModules[$type] )
-                               ? $this->mAllowedModules[$type]
-                               : ResourceLoaderModule::ORIGIN_ALL;
+                       return $this->mAllowedModules[$type] ?? ResourceLoaderModule::ORIGIN_ALL;
                }
        }
 
@@ -1811,7 +1750,8 @@ class OutputPage extends ContextSource {
         * @param ParserOutput $parserOutput
         */
        public function addParserOutputMetadata( $parserOutput ) {
-               $this->mLanguageLinks += $parserOutput->getLanguageLinks();
+               $this->mLanguageLinks =
+                       array_merge( $this->mLanguageLinks, $parserOutput->getLanguageLinks() );
                $this->addCategoryLinks( $parserOutput->getCategories() );
                $this->setIndicators( $parserOutput->getIndicators() );
                $this->mNewSectionLink = $parserOutput->getNewSection();
@@ -1939,7 +1879,7 @@ class OutputPage extends ContextSource {
         * @param bool $interface Use interface language ($wgLang instead of
         *   $wgContLang) while parsing language sensitive magic words like GRAMMAR and PLURAL.
         *   This also disables LanguageConverter.
-        * @param Language $language Target language object, will override $interface
+        * @param Language|null $language Target language object, will override $interface
         * @throws MWException
         * @return string HTML
         */
@@ -2417,10 +2357,6 @@ class OutputPage extends ContextSource {
                $response->header( 'Content-type: ' . $config->get( 'MimeType' ) . '; charset=UTF-8' );
                $response->header( 'Content-language: ' . $wgContLang->getHtmlCode() );
 
-               // Avoid Internet Explorer "compatibility view" in IE 8-10, so that
-               // jQuery etc. can work correctly.
-               $response->header( 'X-UA-Compatible: IE=Edge' );
-
                if ( !$this->mArticleBodyOnly ) {
                        $sk = $this->getSkin();
 
@@ -2547,7 +2483,7 @@ class OutputPage extends ContextSource {
         * Output a standard permission error page
         *
         * @param array $errors Error message keys or [key, param...] arrays
-        * @param string $action Action that was denied or null if unknown
+        * @param string|null $action Action that was denied or null if unknown
         */
        public function showPermissionsErrorPage( array $errors, $action = null ) {
                foreach ( $errors as $key => $error ) {
@@ -2637,7 +2573,7 @@ class OutputPage extends ContextSource {
         * Format a list of error messages
         *
         * @param array $errors Array of arrays returned by Title::getUserPermissionsErrors
-        * @param string $action Action that was denied or null if unknown
+        * @param string|null $action Action that was denied or null if unknown
         * @return string The wikitext error-messages, formatted into a list.
         */
        public function formatPermissionsErrorMessage( array $errors, $action = null ) {
@@ -2657,13 +2593,13 @@ class OutputPage extends ContextSource {
 
                        foreach ( $errors as $error ) {
                                $text .= '<li>';
-                               $text .= call_user_func_array( [ $this, 'msg' ], $error )->plain();
+                               $text .= $this->msg( ...$error )->plain();
                                $text .= "</li>\n";
                        }
                        $text .= '</ul>';
                } else {
                        $text .= "<div class=\"permissions-errors\">\n" .
-                                       call_user_func_array( [ $this, 'msg' ], reset( $errors ) )->plain() .
+                                       $this->msg( ...reset( $errors ) )->plain() .
                                        "\n</div>";
                }
 
@@ -2691,30 +2627,56 @@ class OutputPage extends ContextSource {
                }
        }
 
+       /**
+        * Output an error page
+        *
+        * @note FatalError exception class provides an alternative.
+        * @param string $message Error to output. Must be escaped for HTML.
+        */
        public function showFatalError( $message ) {
                $this->prepareErrorPage( $this->msg( 'internalerror' ) );
 
                $this->addHTML( $message );
        }
 
+       /**
+        * @deprecated 1.32 Use OutputPage::showFatalError or throw FatalError instead.
+        */
        public function showUnexpectedValueError( $name, $val ) {
-               $this->showFatalError( $this->msg( 'unexpected', $name, $val )->text() );
+               wfDeprecated( __METHOD__, '1.32' );
+               $this->showFatalError( $this->msg( 'unexpected', $name, $val )->escaped() );
        }
 
+       /**
+        * @deprecated 1.32 Use OutputPage::showFatalError or throw FatalError instead.
+        */
        public function showFileCopyError( $old, $new ) {
-               $this->showFatalError( $this->msg( 'filecopyerror', $old, $new )->text() );
+               wfDeprecated( __METHOD__, '1.32' );
+               $this->showFatalError( $this->msg( 'filecopyerror', $old, $new )->escaped() );
        }
 
+       /**
+        * @deprecated 1.32 Use OutputPage::showFatalError or throw FatalError instead.
+        */
        public function showFileRenameError( $old, $new ) {
-               $this->showFatalError( $this->msg( 'filerenameerror', $old, $new )->text() );
+               wfDeprecated( __METHOD__, '1.32' );
+               $this->showFatalError( $this->msg( 'filerenameerror', $old, $new )->escpaed() );
        }
 
+       /**
+        * @deprecated 1.32 Use OutputPage::showFatalError or throw FatalError instead.
+        */
        public function showFileDeleteError( $name ) {
-               $this->showFatalError( $this->msg( 'filedeleteerror', $name )->text() );
+               wfDeprecated( __METHOD__, '1.32' );
+               $this->showFatalError( $this->msg( 'filedeleteerror', $name )->escaped() );
        }
 
+       /**
+        * @deprecated 1.32 Use OutputPage::showFatalError or throw FatalError instead.
+        */
        public function showFileNotFoundError( $name ) {
-               $this->showFatalError( $this->msg( 'filenotfound', $name )->text() );
+               wfDeprecated( __METHOD__, '1.32' );
+               $this->showFatalError( $this->msg( 'filenotfound', $name )->escaped() );
        }
 
        /**
@@ -2722,7 +2684,7 @@ class OutputPage extends ContextSource {
         *
         * @param Title $title Title to link
         * @param array $query Query string parameters
-        * @param string $text Text of the link (input is not escaped)
+        * @param string|null $text Text of the link (input is not escaped)
         * @param array $options Options array to pass to Linker
         */
        public function addReturnTo( $title, array $query = [], $text = null, $options = [] ) {
@@ -2737,9 +2699,9 @@ class OutputPage extends ContextSource {
         * Add a "return to" link pointing to a specified title,
         * or the title indicated in the request, or else the main page
         *
-        * @param mixed $unused
-        * @param Title|string $returnto Title or String to return to
-        * @param string $returntoquery Query string for the return to link
+        * @param mixed|null $unused
+        * @param Title|string|null $returnto Title or String to return to
+        * @param string|null $returntoquery Query string for the return to link
         */
        public function returnToMain( $unused = null, $returnto = null, $returntoquery = null ) {
                if ( $returnto == null ) {
@@ -3069,7 +3031,7 @@ class OutputPage extends ContextSource {
         * Add one or more variables to be set in mw.config in JavaScript
         *
         * @param string|array $keys Key or array of key/value pairs
-        * @param mixed $value [optional] Value of the configuration variable
+        * @param mixed|null $value [optional] Value of the configuration variable
         */
        public function addJsConfigVars( $keys, $value = null ) {
                if ( is_array( $keys ) ) {
@@ -3123,13 +3085,13 @@ class OutputPage extends ContextSource {
 
                // Pre-process information
                $separatorTransTable = $lang->separatorTransformTable();
-               $separatorTransTable = $separatorTransTable ? $separatorTransTable : [];
+               $separatorTransTable = $separatorTransTable ?: [];
                $compactSeparatorTransTable = [
                        implode( "\t", array_keys( $separatorTransTable ) ),
                        implode( "\t", $separatorTransTable ),
                ];
                $digitTransTable = $lang->digitTransformTable();
-               $digitTransTable = $digitTransTable ? $digitTransTable : [];
+               $digitTransTable = $digitTransTable ?: [];
                $compactDigitTransTable = [
                        implode( "\t", array_keys( $digitTransTable ) ),
                        implode( "\t", $digitTransTable ),
@@ -3518,6 +3480,13 @@ class OutputPage extends ContextSource {
                        ] );
                }
 
+               // Allow extensions to add, remove and/or otherwise manipulate these links
+               // If you want only to *add* <head> links, please use the addHeadItem()
+               // (or addHeadItems() for multiple items) method instead.
+               // This hook is provided as a last resort for extensions to modify these
+               // links before the output is sent to client.
+               Hooks::run( 'OutputPageAfterGetHeadLinksArray', [ &$tags, $this ] );
+
                return $tags;
        }
 
@@ -3666,8 +3635,11 @@ class OutputPage extends ContextSource {
                        $url = $style;
                } else {
                        $config = $this->getConfig();
-                       $url = $config->get( 'StylePath' ) . '/' . $style . '?' .
-                               $config->get( 'StyleVersion' );
+                       // Append file hash as query parameter
+                       $url = self::transformResourcePath(
+                               $config,
+                               $config->get( 'StylePath' ) . '/' . $style
+                       );
                }
 
                $link = Html::linkedStyle( $url, $media );
@@ -3909,7 +3881,7 @@ class OutputPage extends ContextSource {
         */
        public static function setupOOUI( $skinName = 'default', $dir = 'ltr' ) {
                $themes = ResourceLoaderOOUIModule::getSkinThemeMap();
-               $theme = isset( $themes[$skinName] ) ? $themes[$skinName] : $themes['default'];
+               $theme = $themes[$skinName] ?? $themes['default'];
                // For example, 'OOUI\WikimediaUITheme'.
                $themeClass = "OOUI\\{$theme}Theme";
                OOUI\Theme::setSingleton( new $themeClass() );
@@ -3973,12 +3945,8 @@ class OutputPage extends ContextSource {
                uksort( $logosPerDppx, function ( $a , $b ) {
                        $a = floatval( $a );
                        $b = floatval( $b );
-
-                       if ( $a == $b ) {
-                               return 0;
-                       }
                        // Sort from smallest to largest (e.g. 1x, 1.5x, 2x)
-                       return ( $a < $b ) ? -1 : 1;
+                       return $a <=> $b;
                } );
 
                foreach ( $logosPerDppx as $dppx => $src ) {
@@ -4026,13 +3994,13 @@ class OutputPage extends ContextSource {
         * @since 1.32
         */
        public function getCSPNonce() {
-               if ( !ContentSecurityPolicy::isEnabled( $this->getConfig() ) ) {
+               if ( !ContentSecurityPolicy::isNonceRequired( $this->getConfig() ) ) {
                        return false;
                }
                if ( $this->CSPNonce === null ) {
                        // XXX It might be expensive to generate randomness
-                       // on every request, on windows.
-                       $rand = MWCryptRand::generate( 15 );
+                       // on every request, on Windows.
+                       $rand = random_bytes( 15 );
                        $this->CSPNonce = base64_encode( $rand );
                }
                return $this->CSPNonce;
index cfe889f..8eda14a 100644 (file)
@@ -94,7 +94,7 @@ class PHPVersionCheck {
                        'version' => PHP_VERSION,
                        'vendor' => 'the PHP Group',
                        'upstreamSupported' => '5.6.0',
-                       'minSupported' => '5.5.9',
+                       'minSupported' => '7.0.0',
                        'upgradeURL' => 'https://secure.php.net/downloads.php',
                );
        }
@@ -120,7 +120,7 @@ class PHPVersionCheck {
                                . "MediaWiki $this->mwVersion needs {$phpInfo['implementation']}"
                                . " $minimumVersion or higher or {$otherInfo['implementation']} version "
                                . "{$otherInfo['minSupported']}.\n\nCheck if you have a"
-                               . " newer php executable with a different name, such as php5.\n\n";
+                               . " newer php executable with a different name.\n\n";
 
                        // phpcs:disable Generic.Files.LineLength
                        $longHtml = <<<HTML
@@ -134,7 +134,7 @@ class PHPVersionCheck {
                        If for some reason you are unable to upgrade your {$phpInfo['implementation']} version,
                        you will need to <a href="https://www.mediawiki.org/wiki/Download">download</a> an
                        older version of MediaWiki from our website.
-                       See our<a href="https://www.mediawiki.org/wiki/Compatibility#PHP">compatibility page</a>
+                       See our <a href="https://www.mediawiki.org/wiki/Compatibility#PHP">compatibility page</a>
                        for details of which versions are compatible with prior versions of {$phpInfo['implementation']}.
 HTML;
                        // phpcs:enable Generic.Files.LineLength
index ff8deee..df2451c 100644 (file)
@@ -81,7 +81,7 @@ class PageProps {
         * Create a PageProps object
         */
        private function __construct() {
-               $this->cache = new ProcessCacheLRU( self::CACHE_SIZE );
+               $this->cache = new MapCacheLRU( self::CACHE_SIZE );
        }
 
        /**
@@ -89,8 +89,8 @@ class PageProps {
         * @param int $size
         */
        public function ensureCacheSize( $size ) {
-               if ( $this->cache->getSize() < $size ) {
-                       $this->cache->resize( $size );
+               if ( $this->cache->getMaxSize() < $size ) {
+                       $this->cache->setMaxSize( $size );
                }
        }
 
@@ -267,11 +267,11 @@ class PageProps {
         * @return string|bool property value array or false if not found
         */
        private function getCachedProperty( $pageID, $propertyName ) {
-               if ( $this->cache->has( $pageID, $propertyName, self::CACHE_TTL ) ) {
-                       return $this->cache->get( $pageID, $propertyName );
+               if ( $this->cache->hasField( $pageID, $propertyName, self::CACHE_TTL ) ) {
+                       return $this->cache->getField( $pageID, $propertyName );
                }
-               if ( $this->cache->has( 0, $pageID, self::CACHE_TTL ) ) {
-                       $pageProperties = $this->cache->get( 0, $pageID );
+               if ( $this->cache->hasField( 0, $pageID, self::CACHE_TTL ) ) {
+                       $pageProperties = $this->cache->getField( 0, $pageID );
                        if ( isset( $pageProperties[$propertyName] ) ) {
                                return $pageProperties[$propertyName];
                        }
@@ -286,8 +286,8 @@ class PageProps {
         * @return string|bool property value array or false if not found
         */
        private function getCachedProperties( $pageID ) {
-               if ( $this->cache->has( 0, $pageID, self::CACHE_TTL ) ) {
-                       return $this->cache->get( 0, $pageID );
+               if ( $this->cache->hasField( 0, $pageID, self::CACHE_TTL ) ) {
+                       return $this->cache->getField( 0, $pageID );
                }
                return false;
        }
@@ -300,7 +300,7 @@ class PageProps {
         * @param mixed $propertyValue value of property
         */
        private function cacheProperty( $pageID, $propertyName, $propertyValue ) {
-               $this->cache->set( $pageID, $propertyName, $propertyValue );
+               $this->cache->setField( $pageID, $propertyName, $propertyValue );
        }
 
        /**
@@ -311,6 +311,6 @@ class PageProps {
         */
        private function cacheProperties( $pageID, $pageProperties ) {
                $this->cache->clear( $pageID );
-               $this->cache->set( 0, $pageID, $pageProperties );
+               $this->cache->setField( 0, $pageID, $pageProperties );
        }
 }
index cc6fc4a..faf4db4 100644 (file)
@@ -240,6 +240,28 @@ class PathRouter {
                // matches are tested first
                $this->sortByWeight();
 
+               $matches = $this->internalParse( $path );
+               if ( is_null( $matches ) ) {
+                       // Try with the normalized path (T100782)
+                       $path = wfRemoveDotSegments( $path );
+                       $path = preg_replace( '#/+#', '/', $path );
+                       $matches = $this->internalParse( $path );
+               }
+
+               // We know the difference between null (no matches) and
+               // 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;
+       }
+
+       /**
+        * Match a path against each defined pattern
+        *
+        * @param string $path
+        * @return array|null
+        */
+       protected function internalParse( $path ) {
                $matches = null;
 
                foreach ( $this->patterns as $pattern ) {
@@ -248,17 +270,12 @@ class PathRouter {
                                break;
                        }
                }
-
-               // We know the difference between null (no matches) and
-               // 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;
        }
 
        /**
         * @param string $path
-        * @param string $pattern
+        * @param object $pattern
         * @return array|null
         */
        protected static function extractTitle( $path, $pattern ) {
@@ -319,13 +336,8 @@ class PathRouter {
                                        $value = $paramData['value'];
                                } elseif ( isset( $paramData['pattern'] ) ) {
                                        // For patterns we have to make value replacements on the string
-                                       $value = $paramData['pattern'];
-                                       $replacer = new PathRouterPatternReplacer;
-                                       $replacer->params = $m;
-                                       if ( isset( $pattern->key ) ) {
-                                               $replacer->key = $pattern->key;
-                                       }
-                                       $value = $replacer->replace( $value );
+                                       $value = self::expandParamValue( $m, $pattern->key ?? null,
+                                               $paramData['pattern'] );
                                        if ( $value === false ) {
                                                // Pattern required data that wasn't available, abort
                                                return null;
@@ -352,48 +364,43 @@ class PathRouter {
                return $matches;
        }
 
-}
-
-class PathRouterPatternReplacer {
-
-       public $key, $params, $error;
-
        /**
-        * Replace keys inside path router patterns with text.
-        * We do this inside of a replacement callback because after replacement we can't tell the
-        * difference between a $1 that was not replaced and a $1 that was part of
-        * the content a $1 was replaced with.
-        * @param string $value
+        * Replace $key etc. in param values with the matched strings from the path.
+        *
+        * @param array $pathMatches The match results from the path
+        * @param string|null $key The key of the matching pattern
+        * @param string $value The param value to be expanded
         * @return string|false
         */
-       public function replace( $value ) {
-               $this->error = false;
-               $value = preg_replace_callback( '/\$(\d+|key)/u', [ $this, 'callback' ], $value );
-               if ( $this->error ) {
-                       return false;
-               }
-               return $value;
-       }
+       protected static function expandParamValue( $pathMatches, $key, $value ) {
+               $error = false;
 
-       /**
-        * @param array $m
-        * @return string
-        */
-       protected function callback( $m ) {
-               if ( $m[1] == "key" ) {
-                       if ( is_null( $this->key ) ) {
-                               $this->error = true;
-                               return '';
-                       }
-                       return $this->key;
-               } else {
-                       $d = $m[1];
-                       if ( !isset( $this->params["par$d"] ) ) {
-                               $this->error = true;
-                               return '';
+               $replacer = function ( $m ) use ( $pathMatches, $key, &$error ) {
+                       if ( $m[1] == "key" ) {
+                               if ( is_null( $key ) ) {
+                                       $error = true;
+
+                                       return '';
+                               }
+
+                               return $key;
+                       } else {
+                               $d = $m[1];
+                               if ( !isset( $pathMatches["par$d"] ) ) {
+                                       $error = true;
+
+                                       return '';
+                               }
+
+                               return rawurldecode( $pathMatches["par$d"] );
                        }
-                       return rawurldecode( $this->params["par$d"] );
+               };
+
+               $value = preg_replace_callback( '/\$(\d+|key)/u', $replacer, $value );
+               if ( $error ) {
+                       return false;
                }
-       }
 
+               return $value;
+       }
 }
index 64b54f1..ee608c2 100644 (file)
@@ -50,8 +50,8 @@ class Pingback {
        protected $id;
 
        /**
-        * @param Config $config
-        * @param LoggerInterface $logger
+        * @param Config|null $config
+        * @param LoggerInterface|null $logger
         */
        public function __construct( Config $config = null, LoggerInterface $logger = null ) {
                $this->config = $config ?: RequestContext::getMain()->getConfig();
index 26e28ba..a8a312c 100644 (file)
@@ -262,12 +262,12 @@ class Preferences {
         * @param IContextSource $context
         * @param string $formClass
         * @param array $remove Array of items to remove
-        * @return PreferencesForm|HTMLForm
+        * @return PreferencesFormLegacy|HTMLForm
         */
        public static function getFormObject(
                $user,
                IContextSource $context,
-               $formClass = PreferencesForm::class,
+               $formClass = PreferencesFormLegacy::class,
                array $remove = []
        ) {
                $preferencesFactory = self::getDefaultPreferencesFactory();
@@ -300,30 +300,6 @@ class Preferences {
                throw new Exception( __METHOD__ . '() is deprecated and does nothing' );
        }
 
-       /**
-        * Handle the form submission if everything validated properly
-        *
-        * @deprecated since 1.31, use PreferencesFactory
-        *
-        * @param array $formData
-        * @param PreferencesForm $form
-        * @return bool|Status|string
-        */
-       public static function tryFormSubmit( $formData, $form ) {
-               $preferencesFactory = self::getDefaultPreferencesFactory();
-               return $preferencesFactory->legacySaveFormData( $formData, $form );
-       }
-
-       /**
-        * @param array $formData
-        * @param PreferencesForm $form
-        * @return Status
-        */
-       public static function tryUISubmit( $formData, $form ) {
-               $preferencesFactory = self::getDefaultPreferencesFactory();
-               return $preferencesFactory->legacySubmitForm( $formData, $form );
-       }
-
        /**
         * Get a list of all time zones
         * @param Language $language Language used for the localized names
index 62ee5c6..63a4d9c 100644 (file)
@@ -58,54 +58,14 @@ abstract class PrefixSearch {
                        return []; // Return empty result
                }
 
-               $hasNamespace = $this->extractNamespace( $search );
-               if ( $hasNamespace ) {
-                       list( $namespace, $search ) = $hasNamespace;
-                       $namespaces = [ $namespace ];
-               } else {
-                       $namespaces = $this->validateNamespaces( $namespaces );
-                       Hooks::run( 'PrefixSearchExtractNamespace', [ &$namespaces, &$search ] );
+               $hasNamespace = SearchEngine::parseNamespacePrefixes( $search, false, true );
+               if ( $hasNamespace !== false ) {
+                       list( $search, $namespaces ) = $hasNamespace;
                }
 
                return $this->searchBackend( $namespaces, $search, $limit, $offset );
        }
 
-       /**
-        * Figure out if given input contains an explicit namespace.
-        *
-        * @param string $input
-        * @return false|array Array of namespace and remaining text, or false if no namespace given.
-        */
-       protected function extractNamespace( $input ) {
-               if ( strpos( $input, ':' ) === false ) {
-                       return false;
-               }
-
-               // Namespace prefix only
-               $title = Title::newFromText( $input . 'Dummy' );
-               if (
-                       $title &&
-                       $title->getText() === 'Dummy' &&
-                       !$title->inNamespace( NS_MAIN ) &&
-                       !$title->isExternal()
-               ) {
-                       return [ $title->getNamespace(), '' ];
-               }
-
-               // Namespace prefix with additional input
-               $title = Title::newFromText( $input );
-               if (
-                       $title &&
-                       !$title->inNamespace( NS_MAIN ) &&
-                       !$title->isExternal()
-               ) {
-                       // getText provides correct capitalization
-                       return [ $title->getNamespace(), $title->getText() ];
-               }
-
-               return false;
-       }
-
        /**
         * Do a prefix search for all possible variants of the prefix
         * @param string $search
@@ -211,7 +171,7 @@ abstract class PrefixSearch {
 
                $searchParts = explode( '/', $search, 2 );
                $searchKey = $searchParts[0];
-               $subpageSearch = isset( $searchParts[1] ) ? $searchParts[1] : null;
+               $subpageSearch = $searchParts[1] ?? null;
 
                // Handle subpage search separately.
                if ( $subpageSearch !== null ) {
index 51c2923..1f3de50 100644 (file)
@@ -196,7 +196,7 @@ class ProtectionForm {
        /**
         * Show the input form with optional error message
         *
-        * @param string $err Error message or null if there's no error
+        * @param string|null $err Error message or null if there's no error
         */
        function show( $err = null ) {
                $out = $this->mContext->getOutput();
index 548ef8d..7ff73dd 100644 (file)
@@ -581,11 +581,11 @@ class Revision implements IDBAccessObject {
                                return $row['title'];
                        }
 
-                       $pageId = isset( $row['page'] ) ? $row['page'] : 0;
-                       $revId = isset( $row['id'] ) ? $row['id'] : 0;
+                       $pageId = $row['page'] ?? 0;
+                       $revId = $row['id'] ?? 0;
                } else {
-                       $pageId = isset( $row->rev_page ) ? $row->rev_page : 0;
-                       $revId = isset( $row->rev_id ) ? $row->rev_id : 0;
+                       $pageId = $row->rev_page ?? 0;
+                       $revId = $row->rev_id ?? 0;
                }
 
                try {
@@ -739,7 +739,7 @@ class Revision implements IDBAccessObject {
        /**
         * Set the title of the revision
         *
-        * @deprecated: since 1.31, this is now a noop. Pass the Title to the constructor instead.
+        * @deprecated since 1.31, this is now a noop. Pass the Title to the constructor instead.
         *
         * @param Title $title
         */
@@ -887,7 +887,7 @@ class Revision implements IDBAccessObject {
         *   Revision::FOR_PUBLIC       to be displayed to all users
         *   Revision::FOR_THIS_USER    to be displayed to $user
         *   Revision::RAW              get the text regardless of permissions
-        * @param User $user User object to check for, only if FOR_THIS_USER is passed
+        * @param User|null $user User object to check for, only if FOR_THIS_USER is passed
         *   to the $audience parameter
         * @since 1.21
         * @return Content|null
@@ -927,7 +927,7 @@ class Revision implements IDBAccessObject {
         * used to determine the content model to use. If no title is know, CONTENT_MODEL_WIKITEXT
         * is used as a last resort.
         *
-        * @todo: drop this, with MCR, there no longer is a single model associated with a revision.
+        * @todo drop this, with MCR, there no longer is a single model associated with a revision.
         *
         * @return string The content model id associated with this revision,
         *     see the CONTENT_MODEL_XXX constants.
@@ -942,7 +942,7 @@ class Revision implements IDBAccessObject {
         * If no content format was stored in the database, the default format for this
         * revision's content model is returned.
         *
-        * @todo: drop this, the format is irrelevant to the revision!
+        * @todo drop this, the format is irrelevant to the revision!
         *
         * @return string The content format id associated with this revision,
         *     see the CONTENT_FORMAT_XXX constants.
@@ -1038,7 +1038,18 @@ class Revision implements IDBAccessObject {
                        ? SqlBlobStore::makeAddressFromTextId( $row->old_id )
                        : null;
 
-               return self::getBlobStore( $wiki )->expandBlob( $text, $flags, $cacheKey );
+               $revisionText = self::getBlobStore( $wiki )->expandBlob( $text, $flags, $cacheKey );
+
+               if ( $revisionText === false ) {
+                       if ( isset( $row->old_id ) ) {
+                               wfLogWarning( __METHOD__ . ": Bad data in text row {$row->old_id}! " );
+                       } else {
+                               wfLogWarning( __METHOD__ . ": Bad data in text row! " );
+                       }
+                       return false;
+               }
+
+               return $revisionText;
        }
 
        /**
@@ -1063,6 +1074,11 @@ class Revision implements IDBAccessObject {
         * @return string|bool Decompressed text, or false on failure
         */
        public static function decompressRevisionText( $text, $flags ) {
+               if ( $text === false ) {
+                       // Text failed to be fetched; nothing to do
+                       return false;
+               }
+
                return self::getBlobStore()->decompressData( $text, $flags );
        }
 
@@ -1094,8 +1110,6 @@ class Revision implements IDBAccessObject {
 
                // Avoid PHP 7.1 warning of passing $this by reference
                $revision = $this;
-               // TODO: hard-deprecate in 1.32 (or even 1.31?)
-               Hooks::run( 'RevisionInsertComplete', [ &$revision, null, null ] );
 
                return $rec->getId();
        }
index ee92cbf..66b4c0c 100644 (file)
@@ -38,6 +38,7 @@
  */
 
 use MediaWiki\Auth\AuthManager;
+use MediaWiki\Config\ConfigRepository;
 use MediaWiki\Interwiki\ClassicInterwikiLookup;
 use MediaWiki\Linker\LinkRendererFactory;
 use MediaWiki\Logger\LoggerFactory;
@@ -104,6 +105,10 @@ return [
                return $factory;
        },
 
+       'ConfigRepository' => function ( MediaWikiServices $services ) {
+               return new ConfigRepository( $services->getConfigFactory() );
+       },
+
        'MainConfig' => function ( MediaWikiServices $services ) {
                // Use the 'main' config from the ConfigFactory service.
                return $services->getConfigFactory()->makeConfig( 'main' );
@@ -128,6 +133,14 @@ return [
                );
        },
 
+       'PerDbNameStatsdDataFactory' => function ( MediaWikiServices $services ) {
+               $config = $services->getMainConfig();
+               $wiki = $config->get( 'DBname' );
+               return new BufferingStatsdDataFactory(
+                       rtrim( $services->getMainConfig()->get( 'StatsdMetricPrefix' ) ) . '.' . $wiki
+               );
+       },
+
        'EventRelayerGroup' => function ( MediaWikiServices $services ) {
                return new EventRelayerGroup( $services->getMainConfig()->get( 'EventRelayerConfig' ) );
        },
@@ -188,29 +201,8 @@ return [
                );
        },
 
-       'CryptRand' => function ( MediaWikiServices $services ) {
-               $secretKey = $services->getMainConfig()->get( 'SecretKey' );
-               return new CryptRand(
-                       [
-                               // To try vary the system information of the state a bit more
-                               // by including the system's hostname into the state
-                               'wfHostname',
-                               // It's mostly worthless but throw the wiki's id into the data
-                               // for a little more variance
-                               'wfWikiID',
-                               // If we have a secret key set then throw it into the state as well
-                               function () use ( $secretKey ) {
-                                       return $secretKey ?: '';
-                               }
-                       ],
-                       // The config file is likely the most often edited file we know should
-                       // be around so include its stat info into the state.
-                       // The constant with its location will almost always be defined, as
-                       // WebStart.php defines MW_CONFIG_FILE to $IP/LocalSettings.php unless
-                       // being configured with MW_CONFIG_CALLBACK (e.g. the installer).
-                       defined( 'MW_CONFIG_FILE' ) ? [ MW_CONFIG_FILE ] : [],
-                       LoggerFactory::getInstance( 'CryptRand' )
-               );
+       'CryptRand' => function () {
+               return new CryptRand();
        },
 
        'CryptHKDF' => function ( MediaWikiServices $services ) {
@@ -231,9 +223,7 @@ return [
                        $cache = ObjectCache::getLocalClusterInstance();
                }
 
-               return new CryptHKDF( $secret, $config->get( 'HKDFAlgorithm' ),
-                       $cache, $context, $services->getCryptRand()
-               );
+               return new CryptHKDF( $secret, $config->get( 'HKDFAlgorithm' ), $cache, $context );
        },
 
        'MediaHandlerFactory' => function ( MediaWikiServices $services ) {
@@ -311,7 +301,8 @@ return [
 
        'Parser' => function ( MediaWikiServices $services ) {
                $conf = $services->getMainConfig()->get( 'ParserConf' );
-               return ObjectFactory::constructClassInstance( $conf['class'], [ $conf ] );
+               return ObjectFactory::constructClassInstance( $conf['class'],
+                       [ $conf, $services->getMagicWordFactory() ] );
        },
 
        'ParserCache' => function ( MediaWikiServices $services ) {
@@ -415,9 +406,7 @@ return [
                foreach ( $config['paths'] as $prefix => $serviceConfig ) {
                        $class = $serviceConfig['class'];
                        // Merge in the global defaults
-                       $constructArg = isset( $serviceConfig['options'] )
-                               ? $serviceConfig['options']
-                               : [];
+                       $constructArg = $serviceConfig['options'] ?? [];
                        $constructArg += $config['global'];
                        // Make the VRS service available at the mount point
                        $vrsClient->mount( $prefix, [ 'class' => $class, 'config' => $constructArg ] );
@@ -496,6 +485,9 @@ return [
                        $blobStore,
                        $services->getMainWANObjectCache(),
                        $services->getCommentStore(),
+                       $services->getContentModelStore(),
+                       $services->getSlotRoleStore(),
+                       $services->getMainConfig()->get( 'MultiContentRevisionSchemaMigrationStage' ),
                        $services->getActorMigration()
                );
 
@@ -562,6 +554,24 @@ return [
                );
        },
 
+       'ChangeTagDefStore' => function ( MediaWikiServices $services ) {
+               return new NameTableStore(
+                       $services->getDBLoadBalancer(),
+                       $services->getMainWANObjectCache(),
+                       LoggerFactory::getInstance( 'NameTableSqlStore' ),
+                       'change_tag_def',
+                       'ctd_id',
+                       'ctd_name',
+                       null,
+                       false,
+                       function ( $insertFields ) {
+                               $insertFields['ctd_user_defined'] = 0;
+                               $insertFields['ctd_count'] = 0;
+                               return $insertFields;
+                       }
+               );
+       },
+
        'PreferencesFactory' => function ( MediaWikiServices $services ) {
                global $wgContLang;
                $authManager = AuthManager::singleton();
@@ -591,6 +601,11 @@ return [
                );
        },
 
+       'MagicWordFactory' => function ( MediaWikiServices $services ) {
+               global $wgContLang;
+               return new MagicWordFactory( $wgContLang );
+       },
+
        ///////////////////////////////////////////////////////////////////////////
        // NOTE: When adding a service here, don't forget to add a getter function
        // in the MediaWikiServices class. The convenience getter should just call
index 2c315a3..4d9c495 100644 (file)
@@ -278,7 +278,7 @@ $wgGalleryOptions += [
 ];
 
 /**
- * Initialise $wgLocalFileRepo from backwards-compatible settings
+ * Shortcuts for $wgLocalFileRepo
  */
 if ( !$wgLocalFileRepo ) {
        $wgLocalFileRepo = [
@@ -294,8 +294,15 @@ if ( !$wgLocalFileRepo ) {
                'deletedHashLevels' => $wgHashedUploadDirectory ? 3 : 0
        ];
 }
+
+if ( !isset( $wgLocalFileRepo['backend'] ) ) {
+       // Create a default FileBackend name.
+       // FileBackendGroup will register a default, if absent from $wgFileBackends.
+       $wgLocalFileRepo['backend'] = $wgLocalFileRepo['name'] . '-backend';
+}
+
 /**
- * Initialise shared repo from backwards-compatible settings
+ * Shortcuts for $wgForeignFileRepos
  */
 if ( $wgUseSharedUploads ) {
        if ( $wgSharedUploadDBname ) {
@@ -346,13 +353,6 @@ if ( $wgUseInstantCommons ) {
                'apiThumbCacheExpiry' => 0,
        ];
 }
-/*
- * Add on default file backend config for file repos.
- * FileBackendGroup will handle initializing the backends.
- */
-if ( !isset( $wgLocalFileRepo['backend'] ) ) {
-       $wgLocalFileRepo['backend'] = $wgLocalFileRepo['name'] . '-backend';
-}
 foreach ( $wgForeignFileRepos as &$repo ) {
        if ( !isset( $repo['directory'] ) && $repo['class'] === ForeignAPIRepo::class ) {
                $repo['directory'] = $wgUploadDirectory; // b/c
@@ -533,7 +533,7 @@ if ( $wgInvalidateCacheOnLocalSettingsChange ) {
 }
 
 if ( $wgNewUserLog ) {
-       // Add a new log type
+       // Add new user log type
        $wgLogTypes[] = 'newusers';
        $wgLogNames['newusers'] = 'newuserlogpage';
        $wgLogHeaders['newusers'] = 'newuserlogpagetext';
@@ -544,6 +544,12 @@ if ( $wgNewUserLog ) {
        $wgLogActionsHandlers['newusers/autocreate'] = NewUsersLogFormatter::class;
 }
 
+if ( $wgPageCreationLog ) {
+       // Add page creation log type
+       $wgLogTypes[] = 'create';
+       $wgLogActionsHandlers['create/create'] = LogFormatter::class;
+}
+
 if ( $wgPageLanguageUseDB ) {
        $wgLogTypes[] = 'pagelang';
        $wgLogActionsHandlers['pagelang/pagelang'] = PageLangLogFormatter::class;
@@ -627,10 +633,6 @@ define( 'MW_SERVICE_BOOTSTRAP_COMPLETE', 1 );
 
 MWExceptionHandler::installHandler();
 
-require_once "$IP/includes/compat/normal/UtfNormalUtil.php";
-
-$ps_validation = Profiler::instance()->scopedProfileIn( $fname . '-validation' );
-
 // T48998: Bail out early if $wgArticlePath is non-absolute
 foreach ( [ 'wgArticlePath', 'wgVariantArticlePath' ] as $varName ) {
        if ( $$varName && !preg_match( '/^(https?:\/\/|\/)/', $$varName ) ) {
@@ -643,8 +645,6 @@ foreach ( [ 'wgArticlePath', 'wgVariantArticlePath' ] as $varName ) {
        }
 }
 
-Profiler::instance()->scopedProfileOut( $ps_validation );
-
 $ps_default2 = Profiler::instance()->scopedProfileIn( $fname . '-defaults2' );
 
 if ( $wgCanonicalServer === false ) {
@@ -705,7 +705,7 @@ if ( $wgMainWANCache === false ) {
 
 Profiler::instance()->scopedProfileOut( $ps_default2 );
 
-$ps_misc = Profiler::instance()->scopedProfileIn( $fname . '-misc1' );
+$ps_misc = Profiler::instance()->scopedProfileIn( $fname . '-misc' );
 
 // Raise the memory limit if it's too low
 wfMemoryLimit();
@@ -736,20 +736,20 @@ if ( !$wgDBerrorLogTZ ) {
 // Initialize the request object in $wgRequest
 $wgRequest = RequestContext::getMain()->getRequest(); // BackCompat
 // Set user IP/agent information for agent session consistency purposes
+$cpPosInfo = LBFactory::getCPInfoFromCookieValue(
+       // The cookie has no prefix and is set by MediaWiki::preOutputCommit()
+       $wgRequest->getCookie( 'cpPosIndex', '' ),
+       // Mitigate broken client-side cookie expiration handling (T190082)
+       time() - ChronologyProtector::POSITION_COOKIE_TTL
+);
 MediaWikiServices::getInstance()->getDBLoadBalancerFactory()->setRequestInfo( [
        'IPAddress' => $wgRequest->getIP(),
        'UserAgent' => $wgRequest->getHeader( 'User-Agent' ),
        'ChronologyProtection' => $wgRequest->getHeader( 'ChronologyProtection' ),
-       'ChronologyPositionIndex' => $wgRequest->getInt(
-               'cpPosIndex',
-               LBFactory::getCPIndexFromCookieValue(
-                       // The cookie has no prefix and is set by MediaWiki::preOutputCommit()
-                       $wgRequest->getCookie( 'cpPosIndex', '' ),
-                       // Mitigate broken client-side cookie expiration handling (T190082)
-                       time() - ChronologyProtector::POSITION_COOKIE_TTL
-               )
-       )
+       'ChronologyPositionIndex' => $wgRequest->getInt( 'cpPosIndex', $cpPosInfo['index'] ),
+       'ChronologyClientId' => $cpPosInfo['clientId']
 ] );
+unset( $cpPosInfo );
 // Make sure that object caching does not undermine the ChronologyProtector improvements
 if ( $wgRequest->getCookie( 'UseDC', '' ) === 'master' ) {
        // The user is pinned to the primary DC, meaning that they made recent changes which should
@@ -774,19 +774,9 @@ if ( $wgCommandLineMode ) {
        wfDebug( $debug );
 }
 
-Profiler::instance()->scopedProfileOut( $ps_misc );
-$ps_memcached = Profiler::instance()->scopedProfileIn( $fname . '-memcached' );
-
 $wgMemc = wfGetMainCache();
 $messageMemc = wfGetMessageCacheStorage();
 
-/**
- * @deprecated since 1.30
- */
-$parserMemc = new DeprecatedGlobal( 'parserMemc', function () {
-       return MediaWikiServices::getInstance()->getParserCache()->getCacheStorage();
-}, '1.30' );
-
 wfDebugLog( 'caches',
        'cluster: ' . get_class( $wgMemc ) .
        ', WAN: ' . ( $wgMainWANCache === CACHE_NONE ? 'CACHE_NONE' : $wgMainWANCache ) .
@@ -795,7 +785,7 @@ wfDebugLog( 'caches',
        ', session: ' . get_class( ObjectCache::getInstance( $wgSessionCacheType ) )
 );
 
-Profiler::instance()->scopedProfileOut( $ps_memcached );
+Profiler::instance()->scopedProfileOut( $ps_misc );
 
 // Most of the config is out, some might want to run hooks here.
 Hooks::run( 'SetupAfterCache' );
@@ -827,8 +817,6 @@ if ( $wgAuth && !$wgAuth instanceof MediaWiki\Auth\AuthManagerAuthPlugin ) {
        ], '$wgAuth is ' . get_class( $wgAuth ) );
 }
 
-// Set up the session
-$ps_session = Profiler::instance()->scopedProfileIn( $fname . '-session' );
 /**
  * @var MediaWiki\Session\SessionId|null $wgInitialSessionId The persistent
  * session ID (if any) loaded at startup
@@ -837,7 +825,7 @@ $wgInitialSessionId = null;
 if ( !defined( 'MW_NO_SESSION' ) && !$wgCommandLineMode ) {
        // If session.auto_start is there, we can't touch session name
        if ( $wgPHPSessionHandling !== 'disable' && !wfIniGetBool( 'session.auto_start' ) ) {
-               session_name( $wgSessionName ? $wgSessionName : $wgCookiePrefix . '_session' );
+               session_name( $wgSessionName ?: $wgCookiePrefix . '_session' );
        }
 
        // Create the SessionManager singleton and set up our session handler,
@@ -892,7 +880,6 @@ if ( !defined( 'MW_NO_SESSION' ) && !$wgCommandLineMode ) {
                );
        }
 }
-Profiler::instance()->scopedProfileOut( $ps_session );
 
 /**
  * @var User $wgUser
@@ -929,22 +916,7 @@ $ps_extensions = Profiler::instance()->scopedProfileIn( $fname . '-extensions' )
 // of the extension file. This allows the extension to perform
 // any necessary initialisation in the fully initialised environment
 foreach ( $wgExtensionFunctions as $func ) {
-       // Allow closures in PHP 5.3+
-       if ( is_object( $func ) && $func instanceof Closure ) {
-               $profName = $fname . '-extensions-closure';
-       } elseif ( is_array( $func ) ) {
-               if ( is_object( $func[0] ) ) {
-                       $profName = $fname . '-extensions-' . get_class( $func[0] ) . '::' . $func[1];
-               } else {
-                       $profName = $fname . '-extensions-' . implode( '::', $func );
-               }
-       } else {
-               $profName = $fname . '-extensions-' . strval( $func );
-       }
-
-       $ps_ext_func = Profiler::instance()->scopedProfileIn( $profName );
        call_user_func( $func );
-       Profiler::instance()->scopedProfileOut( $ps_ext_func );
 }
 
 // If the session user has a 0 id but a valid name, that means we need to
@@ -952,13 +924,11 @@ foreach ( $wgExtensionFunctions as $func ) {
 if ( !defined( 'MW_NO_SESSION' ) && !$wgCommandLineMode ) {
        $sessionUser = MediaWiki\Session\SessionManager::getGlobalSession()->getUser();
        if ( $sessionUser->getId() === 0 && User::isValidUserName( $sessionUser->getName() ) ) {
-               $ps_autocreate = Profiler::instance()->scopedProfileIn( $fname . '-autocreate' );
                $res = MediaWiki\Auth\AuthManager::singleton()->autoCreateUser(
                        $sessionUser,
                        MediaWiki\Auth\AuthManager::AUTOCREATE_SOURCE_SESSION,
                        true
                );
-               Profiler::instance()->scopedProfileOut( $ps_autocreate );
                \MediaWiki\Logger\LoggerFactory::getInstance( 'authevents' )->info( 'Autocreation attempt', [
                        'event' => 'autocreate',
                        'status' => $res,
index 6bd179a..1eaedc2 100644 (file)
@@ -180,7 +180,7 @@ class SiteConfiguration {
         * Retrieves a configuration setting for a given wiki.
         * @param string $settingName ID of the setting name to retrieve
         * @param string $wiki Wiki ID of the wiki in question.
-        * @param string $suffix The suffix of the wiki in question.
+        * @param string|null $suffix The suffix of the wiki in question.
         * @param array $params List of parameters. $.'key' is replaced by $value in all returned data.
         * @param array $wikiTags The tags assigned to the wiki.
         * @return mixed The value of the setting requested.
@@ -294,7 +294,7 @@ class SiteConfiguration {
        /**
         * Gets all settings for a wiki
         * @param string $wiki Wiki ID of the wiki in question.
-        * @param string $suffix The suffix of the wiki in question.
+        * @param string|null $suffix The suffix of the wiki in question.
         * @param array $params List of parameters. $.'key' is replaced by $value in all returned data.
         * @param array $wikiTags The tags assigned to the wiki.
         * @return array Array of settings requested.
@@ -325,7 +325,7 @@ class SiteConfiguration {
         * Retrieves a configuration setting for a given wiki, forced to a boolean.
         * @param string $setting ID of the setting name to retrieve
         * @param string $wiki Wiki ID of the wiki in question.
-        * @param string $suffix The suffix of the wiki in question.
+        * @param string|null $suffix The suffix of the wiki in question.
         * @param array $wikiTags The tags assigned to the wiki.
         * @return bool The value of the setting requested.
         */
@@ -364,7 +364,7 @@ class SiteConfiguration {
         * Retrieves the value of a given setting, and places it in its corresponding global variable.
         * @param string $setting ID of the setting name to retrieve
         * @param string $wiki Wiki ID of the wiki in question.
-        * @param string $suffix The suffix of the wiki in question.
+        * @param string|null $suffix The suffix of the wiki in question.
         * @param array $params List of parameters. $.'key' is replaced by $value in all returned data.
         * @param array $wikiTags The tags assigned to the wiki.
         */
@@ -399,7 +399,7 @@ class SiteConfiguration {
        /**
         * Retrieves the values of all settings, and places them in their corresponding global variables.
         * @param string $wiki Wiki ID of the wiki in question.
-        * @param string $suffix The suffix of the wiki in question.
+        * @param string|null $suffix The suffix of the wiki in question.
         * @param array $params List of parameters. $.'key' is replaced by $value in all returned data.
         * @param array $wikiTags The tags assigned to the wiki.
         */
@@ -432,7 +432,7 @@ class SiteConfiguration {
                        return $default;
                }
 
-               $ret = call_user_func_array( $this->siteParamsCallback, [ $this, $wiki ] );
+               $ret = ( $this->siteParamsCallback )( $this, $wiki );
                # Validate the returned value
                if ( !is_array( $ret ) ) {
                        return $default;
@@ -606,7 +606,7 @@ class SiteConfiguration {
 
        public function loadFullData() {
                if ( $this->fullLoadCallback && !$this->fullLoadDone ) {
-                       call_user_func( $this->fullLoadCallback, $this );
+                       ( $this->fullLoadCallback )( $this );
                        $this->fullLoadDone = true;
                }
        }
index f17f173..877d221 100644 (file)
@@ -171,7 +171,7 @@ 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 $lang Language to use for processing messages
+        * @param string|Language|null $lang Language to use for processing messages
         * @return string
         */
        public function getWikiText( $shortContext = false, $longContext = false, $lang = null ) {
@@ -227,7 +227,7 @@ class Status extends StatusValue {
         *
         * @param string|string[]|bool $shortContext A message name or an array of message names.
         * @param string|string[]|bool $longContext A message name or an array of message names.
-        * @param string|Language $lang Language to use for processing messages
+        * @param string|Language|null $lang Language to use for processing messages
         * @return Message
         */
        public function getMessage( $shortContext = false, $longContext = false, $lang = null ) {
@@ -279,7 +279,7 @@ class Status extends StatusValue {
         * If $error is an array, the "params" field is a list of parameters for the message.
         *
         * @param array|string $error Code string or (key: code string, params: string[]) map
-        * @param string|Language $lang Language to use for processing messages
+        * @param string|Language|null $lang Language to use for processing messages
         * @return Message
         */
        protected function getErrorMessage( $error, $lang = null ) {
@@ -324,7 +324,7 @@ class Status extends StatusValue {
        /**
         * Return an array with a Message object for each error.
         * @param array $errors
-        * @param string|Language $lang Language to use for processing messages
+        * @param string|Language|null $lang Language to use for processing messages
         * @return Message[]
         */
        protected function getErrorMessageArray( $errors, $lang = null ) {
@@ -359,7 +359,7 @@ class Status extends StatusValue {
        /**
         * Returns a list of status messages of the given type (or all if false)
         *
-        * @note: this handles RawMessage poorly
+        * @note this handles RawMessage poorly
         *
         * @param string|bool $type
         * @return array
diff --git a/includes/Storage/DerivedPageDataUpdater.php b/includes/Storage/DerivedPageDataUpdater.php
new file mode 100644 (file)
index 0000000..6f241ba
--- /dev/null
@@ -0,0 +1,1542 @@
+<?php
+/**
+ * A handle for managing updates for derived page data on edit, import, purge, etc.
+ *
+ * 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\Storage;
+
+use ApiStashEdit;
+use CategoryMembershipChangeJob;
+use Content;
+use ContentHandler;
+use DataUpdate;
+use DeferredUpdates;
+use Hooks;
+use IDBAccessObject;
+use InvalidArgumentException;
+use JobQueueGroup;
+use Language;
+use LinksUpdate;
+use LogicException;
+use MediaWiki\Edit\PreparedEdit;
+use MediaWiki\MediaWikiServices;
+use MediaWiki\User\UserIdentity;
+use MessageCache;
+use ParserCache;
+use ParserOptions;
+use ParserOutput;
+use Psr\Log\LoggerInterface;
+use Psr\Log\NullLogger;
+use RecentChangesUpdateJob;
+use ResourceLoaderWikiModule;
+use Revision;
+use SearchUpdate;
+use SiteStatsUpdate;
+use Title;
+use User;
+use Wikimedia\Assert\Assert;
+use WikiPage;
+
+/**
+ * A handle for managing updates for derived page data on edit, import, purge, etc.
+ *
+ * @note Avoid direct usage of DerivedPageDataUpdater.
+ *
+ * @todo Define interfaces for the different use cases of DerivedPageDataUpdater, particularly
+ * providing access to post-PST content and ParserOutput to callbacks during revision creation,
+ * which currently use WikiPage::prepareContentForEdit, and allowing updates to be triggered on
+ * purge, import, and undeletion, which currently use WikiPage::doEditUpdates() and
+ * Content::getSecondaryDataUpdates().
+ *
+ * DerivedPageDataUpdater instances are designed to be cached inside a WikiPage instance,
+ * and re-used by callback code over the course of an update operation. It's a stepping stone
+ * one the way to a more complete refactoring of WikiPage.
+ *
+ * When using a DerivedPageDataUpdater, the following life cycle must be observed:
+ * grabCurrentRevision (optional), prepareContent (optional), prepareUpdate (required
+ * for doUpdates). getCanonicalParserOutput, getSlots, and getSecondaryDataUpdates
+ * require prepareContent or prepareUpdate to have been called first, to initialize the
+ * DerivedPageDataUpdater.
+ *
+ * @see docs/pageupdater.txt for more information.
+ *
+ * MCR migration note: this replaces the relevant methods in WikiPage, and covers the use cases
+ * of PreparedEdit.
+ *
+ * @internal
+ *
+ * @since 1.32
+ * @ingroup Page
+ */
+class DerivedPageDataUpdater implements IDBAccessObject {
+
+       /**
+        * @var UserIdentity|null
+        */
+       private $user = null;
+
+       /**
+        * @var WikiPage
+        */
+       private $wikiPage;
+
+       /**
+        * @var ParserCache
+        */
+       private $parserCache;
+
+       /**
+        * @var RevisionStore
+        */
+       private $revisionStore;
+
+       /**
+        * @var Language
+        */
+       private $contentLanguage;
+
+       /**
+        * @var LoggerInterface
+        */
+       private $saveParseLogger;
+
+       /**
+        * @var JobQueueGroup
+        */
+       private $jobQueueGroup;
+
+       /**
+        * @var MessageCache
+        */
+       private $messageCache;
+
+       /**
+        * @var string see $wgArticleCountMethod
+        */
+       private $articleCountMethod;
+
+       /**
+        * @var boolean see $wgRCWatchCategoryMembership
+        */
+       private $rcWatchCategoryMembership = false;
+
+       /**
+        * See $options on prepareUpdate.
+        */
+       private $options = [
+               'changed' => true,
+               'created' => false,
+               'moved' => false,
+               'restored' => false,
+               'oldcountable' => null,
+               'oldredirect' => null,
+       ];
+
+       /**
+        * The state of the relevant row in page table before the edit.
+        * This is determined by the first call to grabCurrentRevision, prepareContent,
+        * or prepareUpdate.
+        * If pageState was not initialized when prepareUpdate() is called, prepareUpdate() will
+        * attempt to emulate the state of the page table before the edit.
+        *
+        * @var array
+        */
+       private $pageState = null;
+
+       /**
+        * @var RevisionSlotsUpdate|null
+        */
+       private $slotsUpdate = null;
+
+       /**
+        * @var MutableRevisionSlots|null
+        */
+       private $pstContentSlots = null;
+
+       /**
+        * @var object[] anonymous objects with two fields, using slot roles as keys:
+        *  - hasHtml: whether the output contains HTML
+        *  - ParserOutput: the slot's parser output
+        */
+       private $slotsOutput = [];
+
+       /**
+        * @var ParserOutput|null
+        */
+       private $canonicalParserOutput = null;
+
+       /**
+        * @var ParserOptions|null
+        */
+       private $canonicalParserOptions = null;
+
+       /**
+        * @var RevisionRecord
+        */
+       private $revision = null;
+
+       /**
+        * A stage identifier for managing the life cycle of this instance.
+        * Possible stages are 'new', 'knows-current', 'has-content', 'has-revision', and 'done'.
+        *
+        * @see docs/pageupdater.txt for documentation of the life cycle.
+        *
+        * @var string
+        */
+       private $stage = 'new';
+
+       /**
+        * Transition table for managing the life cycle of DerivedPageDateUpdater instances.
+        *
+        * XXX: Overkill. This is a linear order, we could just count. Names are nice though,
+        * and constants are also overkill...
+        *
+        * @see docs/pageupdater.txt for documentation of the life cycle.
+        *
+        * @var array[]
+        */
+       private static $transitions = [
+               'new' => [
+                       'new' => true,
+                       'knows-current' => true,
+                       'has-content' => true,
+                       'has-revision' => true,
+               ],
+               'knows-current' => [
+                       'knows-current' => true,
+                       'has-content' => true,
+                       'has-revision' => true,
+               ],
+               'has-content' => [
+                       'has-content' => true,
+                       'has-revision' => true,
+               ],
+               'has-revision' => [
+                       'has-revision' => true,
+                       'done' => true,
+               ],
+       ];
+
+       /**
+        * @param WikiPage $wikiPage ,
+        * @param RevisionStore $revisionStore
+        * @param ParserCache $parserCache
+        * @param JobQueueGroup $jobQueueGroup
+        * @param MessageCache $messageCache
+        * @param Language $contentLanguage
+        * @param LoggerInterface|null $saveParseLogger
+        */
+       public function __construct(
+               WikiPage $wikiPage,
+               RevisionStore $revisionStore,
+               ParserCache $parserCache,
+               JobQueueGroup $jobQueueGroup,
+               MessageCache $messageCache,
+               Language $contentLanguage,
+               LoggerInterface $saveParseLogger = null
+       ) {
+               $this->wikiPage = $wikiPage;
+
+               $this->parserCache = $parserCache;
+               $this->revisionStore = $revisionStore;
+               $this->jobQueueGroup = $jobQueueGroup;
+               $this->messageCache = $messageCache;
+               $this->contentLanguage = $contentLanguage;
+
+               // XXX: replace all wfDebug calls with a Logger. Do we nede more than one logger here?
+               $this->saveParseLogger = $saveParseLogger ?: new NullLogger();
+       }
+
+       /**
+        * Transition function for managing the life cycle of this instances.
+        *
+        * @see docs/pageupdater.txt for documentation of the life cycle.
+        *
+        * @param string $newStage the new stage
+        * @return string the previous stage
+        *
+        * @throws LogicException If a transition to the given stage is not possible in the current
+        *         stage.
+        */
+       private function doTransition( $newStage ) {
+               $this->assertTransition( $newStage );
+
+               $oldStage = $this->stage;
+               $this->stage = $newStage;
+
+               return $oldStage;
+       }
+
+       /**
+        * Asserts that a transition to the given stage is possible, without performing it.
+        *
+        * @see docs/pageupdater.txt for documentation of the life cycle.
+        *
+        * @param string $newStage the new stage
+        *
+        * @throws LogicException If this instance is not in the expected stage
+        */
+       private function assertTransition( $newStage ) {
+               if ( empty( self::$transitions[$this->stage][$newStage] ) ) {
+                       throw new LogicException( "Cannot transition from {$this->stage} to $newStage" );
+               }
+       }
+
+       /**
+        * @return bool|string
+        */
+       private function getWikiId() {
+               // TODO: get from RevisionStore
+               return false;
+       }
+
+       /**
+        * Checks whether this DerivedPageDataUpdater can be re-used for running updates targeting
+        * the the given revision.
+        *
+        * @param UserIdentity|null $user The user creating the revision in question
+        * @param RevisionRecord|null $revision New revision (after save, if already saved)
+        * @param RevisionSlotsUpdate|null $slotsUpdate New content (before PST)
+        * @param null|int $parentId Parent revision of the edit (use 0 for page creation)
+        *
+        * @return bool
+        */
+       public function isReusableFor(
+               UserIdentity $user = null,
+               RevisionRecord $revision = null,
+               RevisionSlotsUpdate $slotsUpdate = null,
+               $parentId = null
+       ) {
+               if ( $revision
+                       && $parentId
+                       && $revision->getParentId() !== $parentId
+               ) {
+                       throw new InvalidArgumentException( '$parentId should match the parent of $revision' );
+               }
+
+               if ( $revision
+                       && $user
+                       && $revision->getUser( RevisionRecord::RAW )->getName() !== $user->getName()
+               ) {
+                       throw new InvalidArgumentException( '$user should match the author of $revision' );
+               }
+
+               if ( $user && $this->user && $user->getName() !== $this->user->getName() ) {
+                       return false;
+               }
+
+               if ( $revision && $this->revision && $this->revision->getId() !== $revision->getId() ) {
+                       return false;
+               }
+
+               if ( $revision && !$user ) {
+                       $user = $revision->getUser( RevisionRecord::RAW );
+               }
+
+               if ( $this->pageState
+                       && $revision
+                       && $revision->getParentId() !== null
+                       && $this->pageState['oldId'] !== $revision->getParentId()
+               ) {
+                       return false;
+               }
+
+               if ( $this->pageState
+                       && $parentId !== null
+                       && $this->pageState['oldId'] !== $parentId
+               ) {
+                       return false;
+               }
+
+               if ( $this->revision
+                       && $user
+                       && $this->revision->getUser( RevisionRecord::RAW )->getName() !== $user->getName()
+               ) {
+                       return false;
+               }
+
+               if ( $revision
+                       && $this->user
+                       && $revision->getUser( RevisionRecord::RAW )->getName() !== $this->user->getName()
+               ) {
+                       return false;
+               }
+
+               // NOTE: this check is the primary reason for having the $this->slotsUpdate field!
+               if ( $this->slotsUpdate
+                       && $slotsUpdate
+                       && !$this->slotsUpdate->hasSameUpdates( $slotsUpdate )
+               ) {
+                       return false;
+               }
+
+               if ( $this->pstContentSlots
+                       && $revision
+                       && !$this->pstContentSlots->hasSameContent( $revision->getSlots() )
+               ) {
+                       return false;
+               }
+
+               return true;
+       }
+
+       /**
+        * @param string $articleCountMethod "any" or "link".
+        * @see $wgArticleCountMethod
+        */
+       public function setArticleCountMethod( $articleCountMethod ) {
+               $this->articleCountMethod = $articleCountMethod;
+       }
+
+       /**
+        * @param bool $rcWatchCategoryMembership
+        * @see $wgRCWatchCategoryMembership
+        */
+       public function setRcWatchCategoryMembership( $rcWatchCategoryMembership ) {
+               $this->rcWatchCategoryMembership = $rcWatchCategoryMembership;
+       }
+
+       /**
+        * @return Title
+        */
+       private function getTitle() {
+               // NOTE: eventually, we won't get a WikiPage passed into the constructor any more
+               return $this->wikiPage->getTitle();
+       }
+
+       /**
+        * @return WikiPage
+        */
+       private function getWikiPage() {
+               // NOTE: eventually, we won't get a WikiPage passed into the constructor any more
+               return $this->wikiPage;
+       }
+
+       /**
+        * Determines whether the page being edited already existed.
+        * Only defined after calling grabCurrentRevision() or prepareContent() or prepareUpdate()!
+        *
+        * @return bool
+        * @throws LogicException if called before grabCurrentRevision
+        */
+       public function pageExisted() {
+               $this->assertHasPageState( __METHOD__ );
+
+               return $this->pageState['oldId'] > 0;
+       }
+
+       /**
+        * Returns the revision that was current before the edit. This would be null if the edit
+        * created the page, or the revision's parent for a regular edit, or the revision itself
+        * for a null-edit.
+        * Only defined after calling grabCurrentRevision() or prepareContent() or prepareUpdate()!
+        *
+        * @return RevisionRecord|null the revision that was current before the edit, or null if
+        *         the edit created the page.
+        */
+       private function getOldRevision() {
+               $this->assertHasPageState( __METHOD__ );
+
+               // If 'oldRevision' is not set, load it!
+               // Useful if $this->oldPageState is initialized by prepareUpdate.
+               if ( !array_key_exists( 'oldRevision', $this->pageState ) ) {
+                       /** @var int $oldId */
+                       $oldId = $this->pageState['oldId'];
+                       $flags = $this->useMaster() ? RevisionStore::READ_LATEST : 0;
+                       $this->pageState['oldRevision'] = $oldId
+                               ? $this->revisionStore->getRevisionById( $oldId, $flags )
+                               : null;
+               }
+
+               return $this->pageState['oldRevision'];
+       }
+
+       /**
+        * Returns the revision that was the page's current revision when grabCurrentRevision()
+        * was first called.
+        *
+        * During an edit, that revision will act as the logical parent of the new revision.
+        *
+        * Some updates are performed based on the difference between the database state at the
+        * moment this method is first called, and the state after the edit.
+        *
+        * @see docs/pageupdater.txt for more information on when thie method can and should be called.
+        *
+        * @note After prepareUpdate() was called, grabCurrentRevision() will throw an exception
+        * to avoid confusion, since the page's current revision is then the new revision after
+        * the edit, which was presumably passed to prepareUpdate() as the $revision parameter.
+        * Use getOldRevision() instead to access the revision that used to be current before the
+        * edit.
+        *
+        * @return RevisionRecord|null the page's current revision, or null if the page does not
+        * yet exist.
+        */
+       public function grabCurrentRevision() {
+               if ( $this->pageState ) {
+                       return $this->pageState['oldRevision'];
+               }
+
+               $this->assertTransition( 'knows-current' );
+
+               // NOTE: eventually, we won't get a WikiPage passed into the constructor any more
+               $wikiPage = $this->getWikiPage();
+
+               // Do not call WikiPage::clear(), since the caller may already have caused page data
+               // to be loaded with SELECT FOR UPDATE. Just assert it's loaded now.
+               $wikiPage->loadPageData( self::READ_LATEST );
+               $rev = $wikiPage->getRevision();
+               $current = $rev ? $rev->getRevisionRecord() : null;
+
+               $this->pageState = [
+                       'oldRevision' => $current,
+                       'oldId' => $rev ? $rev->getId() : 0,
+                       'oldIsRedirect' => $wikiPage->isRedirect(), // NOTE: uses page table
+                       'oldCountable' => $wikiPage->isCountable(), // NOTE: uses pagelinks table
+               ];
+
+               $this->doTransition( 'knows-current' );
+
+               return $this->pageState['oldRevision'];
+       }
+
+       /**
+        * Whether prepareUpdate() or prepareContent() have been called on this instance.
+        *
+        * @return bool
+        */
+       public function isContentPrepared() {
+               return $this->pstContentSlots !== null;
+       }
+
+       /**
+        * Whether prepareUpdate() has been called on this instance.
+        *
+        * @return bool
+        */
+       public function isUpdatePrepared() {
+               return $this->revision !== null;
+       }
+
+       /**
+        * @return int
+        */
+       private function getPageId() {
+               // NOTE: eventually, we won't get a WikiPage passed into the constructor any more
+               return $this->wikiPage->getId();
+       }
+
+       /**
+        * @return string
+        */
+       private function getTimestampNow() {
+               // TODO: allow an override to be injected for testing
+               return wfTimestampNow();
+       }
+
+       /**
+        * Whether the content of the target revision is publicly visible.
+        *
+        * @return bool
+        */
+       public function isContentPublic() {
+               if ( $this->revision ) {
+                       // XXX: if that revision is the current revision, this can be skipped
+                       return !$this->revision->isDeleted( RevisionRecord::DELETED_TEXT );
+               } else {
+                       // If the content has not been saved yet, it cannot have been suppressed yet.
+                       return true;
+               }
+       }
+
+       /**
+        * Returns the slot, modified or inherited, after PST, with no audience checks applied.
+        *
+        * @param string $role slot role name
+        *
+        * @throws PageUpdateException If the slot is neither set for update nor inherited from the
+        *        parent revision.
+        * @return SlotRecord
+        */
+       public function getRawSlot( $role ) {
+               return $this->getSlots()->getSlot( $role );
+       }
+
+       /**
+        * Returns the content of the given slot, with no audience checks.
+        *
+        * @throws PageUpdateException If the slot is neither set for update nor inherited from the
+        *        parent revision.
+        * @param string $role slot role name
+        * @return Content
+        */
+       public function getRawContent( $role ) {
+               return $this->getRawSlot( $role )->getContent();
+       }
+
+       /**
+        * Returns the content model of the given slot
+        *
+        * @param string $role slot role name
+        * @return string
+        */
+       private function getContentModel( $role ) {
+               return $this->getRawSlot( $role )->getModel();
+       }
+
+       /**
+        * @param string $role slot role name
+        * @return ContentHandler
+        */
+       private function getContentHandler( $role ) {
+               // TODO: inject something like a ContentHandlerRegistry
+               return ContentHandler::getForModelID( $this->getContentModel( $role ) );
+       }
+
+       private function useMaster() {
+               // TODO: can we just set a flag to true in prepareContent()?
+               return $this->wikiPage->wasLoadedFrom( self::READ_LATEST );
+       }
+
+       /**
+        * @return bool
+        */
+       public function isCountable() {
+               // NOTE: Keep in sync with WikiPage::isCountable.
+
+               if ( !$this->getTitle()->isContentPage() ) {
+                       return false;
+               }
+
+               if ( !$this->isContentPublic() ) {
+                       // This should be irrelevant: countability only applies to the current revision,
+                       // and the current revision is never suppressed.
+                       return false;
+               }
+
+               if ( $this->isRedirect() ) {
+                       return false;
+               }
+
+               $hasLinks = null;
+
+               if ( $this->articleCountMethod === 'link' ) {
+                       $hasLinks = (bool)count( $this->getCanonicalParserOutput()->getLinks() );
+               }
+
+               // TODO: MCR: ask all slots if they have links [SlotHandler/PageTypeHandler]
+               $mainContent = $this->getRawContent( 'main' );
+               return $mainContent->isCountable( $hasLinks );
+       }
+
+       /**
+        * @return bool
+        */
+       public function isRedirect() {
+               // NOTE: main slot determines redirect status
+               $mainContent = $this->getRawContent( 'main' );
+
+               return $mainContent->isRedirect();
+       }
+
+       /**
+        * @param RevisionRecord $rev
+        *
+        * @return bool
+        */
+       private function revisionIsRedirect( RevisionRecord $rev ) {
+               // NOTE: main slot determines redirect status
+               $mainContent = $rev->getContent( 'main', RevisionRecord::RAW );
+
+               return $mainContent->isRedirect();
+       }
+
+       /**
+        * Prepare updates based on an update which has not yet been saved.
+        *
+        * This may be used to create derived data that is needed when creating a new revision;
+        * particularly, this makes available the slots of the new revision via the getSlots()
+        * method, after applying PST and slot inheritance.
+        *
+        * The derived data prepared for revision creation may then later be re-used by doUpdates(),
+        * without the need to re-calculate.
+        *
+        * @see docs/pageupdater.txt for more information on when thie method can and should be called.
+        *
+        * @note Calling this method more than once with the same $slotsUpdate
+        * has no effect. Calling this method multiple times with different content will cause
+        * an exception.
+        *
+        * @note Calling this method after prepareUpdate() has been called will cause an exception.
+        *
+        * @param User $user The user to act as context for pre-save transformation (PST).
+        *        Type hint should be reduced to UserIdentity at some point.
+        * @param RevisionSlotsUpdate $slotsUpdate The new content of the slots to be updated
+        *        by this edit, before PST.
+        * @param bool $useStash Whether to use stashed ParserOutput
+        */
+       public function prepareContent(
+               User $user,
+               RevisionSlotsUpdate $slotsUpdate,
+               $useStash = true
+       ) {
+               if ( $this->slotsUpdate ) {
+                       if ( !$this->user ) {
+                               throw new LogicException(
+                                       'Unexpected state: $this->slotsUpdate was initialized, '
+                                       . 'but $this->user was not.'
+                               );
+                       }
+
+                       if ( $this->user->getName() !== $user->getName() ) {
+                               throw new LogicException( 'Can\'t call prepareContent() again for different user! '
+                                       . 'Expected ' . $this->user->getName() . ', got ' . $user->getName()
+                               );
+                       }
+
+                       if ( !$this->slotsUpdate->hasSameUpdates( $slotsUpdate ) ) {
+                               throw new LogicException(
+                                       'Can\'t call prepareContent() again with different slot content!'
+                               );
+                       }
+
+                       return; // prepareContent() already done, nothing to do
+               }
+
+               $this->assertTransition( 'has-content' );
+
+               $wikiPage = $this->getWikiPage(); // TODO: use only for legacy hooks!
+               $title = $this->getTitle();
+
+               $parentRevision = $this->grabCurrentRevision();
+
+               $this->slotsOutput = [];
+               $this->canonicalParserOutput = null;
+               $this->canonicalParserOptions = null;
+
+               // The edit may have already been prepared via api.php?action=stashedit
+               $stashedEdit = false;
+
+               // TODO: MCR: allow output for all slots to be stashed.
+               if ( $useStash && $slotsUpdate->isModifiedSlot( 'main' ) ) {
+                       $mainContent = $slotsUpdate->getModifiedSlot( 'main' )->getContent();
+                       $legacyUser = User::newFromIdentity( $user );
+                       $stashedEdit = ApiStashEdit::checkCache( $title, $mainContent, $legacyUser );
+               }
+
+               if ( $stashedEdit ) {
+                       /** @var ParserOutput $output */
+                       $output = $stashedEdit->output;
+
+                       // TODO: this should happen when stashing the ParserOutput, not now!
+                       $output->setCacheTime( $stashedEdit->timestamp );
+
+                       // TODO: MCR: allow output for all slots to be stashed.
+                       $this->canonicalParserOutput = $output;
+               }
+
+               $userPopts = ParserOptions::newFromUserAndLang( $user, $this->contentLanguage );
+               Hooks::run( 'ArticlePrepareTextForEdit', [ $wikiPage, $userPopts ] );
+
+               $this->user = $user;
+               $this->slotsUpdate = $slotsUpdate;
+
+               if ( $parentRevision ) {
+                       // start out by inheriting all parent slots
+                       $this->pstContentSlots = MutableRevisionSlots::newFromParentRevisionSlots(
+                               $parentRevision->getSlots()->getSlots()
+                       );
+               } else {
+                       $this->pstContentSlots = new MutableRevisionSlots();
+               }
+
+               foreach ( $slotsUpdate->getModifiedRoles() as $role ) {
+                       $slot = $slotsUpdate->getModifiedSlot( $role );
+
+                       if ( $slot->isInherited() ) {
+                               // No PST for inherited slots! Note that "modified" slots may still be inherited
+                               // from an earlier version, e.g. for rollbacks.
+                               $pstSlot = $slot;
+                       } elseif ( $role === 'main' && $stashedEdit ) {
+                               // TODO: MCR: allow PST content for all slots to be stashed.
+                               $pstSlot = SlotRecord::newUnsaved( $role, $stashedEdit->pstContent );
+                       } else {
+                               $content = $slot->getContent();
+                               $pstContent = $content->preSaveTransform( $title, $this->user, $userPopts );
+                               $pstSlot = SlotRecord::newUnsaved( $role, $pstContent );
+                       }
+
+                       $this->pstContentSlots->setSlot( $pstSlot );
+               }
+
+               foreach ( $slotsUpdate->getRemovedRoles() as $role ) {
+                       $this->pstContentSlots->removeSlot( $role );
+               }
+
+               $this->options['created'] = ( $parentRevision === null );
+               $this->options['changed'] = ( $parentRevision === null
+                       || !$this->pstContentSlots->hasSameContent( $parentRevision->getSlots() ) );
+
+               $this->doTransition( 'has-content' );
+       }
+
+       private function assertHasPageState( $method ) {
+               if ( !$this->pageState ) {
+                       throw new LogicException(
+                               'Must call grabCurrentRevision() or prepareContent() '
+                               . 'or prepareUpdate() before calling ' . $method
+                       );
+               }
+       }
+
+       private function assertPrepared( $method ) {
+               if ( !$this->pstContentSlots ) {
+                       throw new LogicException(
+                               'Must call prepareContent() or prepareUpdate() before calling ' . $method
+                       );
+               }
+       }
+
+       /**
+        * Whether the edit creates the page.
+        *
+        * @return bool
+        */
+       public function isCreation() {
+               $this->assertPrepared( __METHOD__ );
+               return $this->options['created'];
+       }
+
+       /**
+        * Whether the edit created, or should create, a new revision (that is, it's not a null-edit).
+        *
+        * @warning at present, "null-revisions" that do not change content but do have a revision
+        * record would return false after prepareContent(), but true after prepareUpdate()!
+        * This should probably be fixed.
+        *
+        * @return bool
+        */
+       public function isChange() {
+               $this->assertPrepared( __METHOD__ );
+               return $this->options['changed'];
+       }
+
+       /**
+        * Whether the page was a redirect before the edit.
+        *
+        * @return bool
+        */
+       public function wasRedirect() {
+               $this->assertHasPageState( __METHOD__ );
+
+               if ( $this->pageState['oldIsRedirect'] === null ) {
+                       /** @var RevisionRecord $rev */
+                       $rev = $this->pageState['oldRevision'];
+                       if ( $rev ) {
+                               $this->pageState['oldIsRedirect'] = $this->revisionIsRedirect( $rev );
+                       } else {
+                               $this->pageState['oldIsRedirect'] = false;
+                       }
+               }
+
+               return $this->pageState['oldIsRedirect'];
+       }
+
+       /**
+        * Returns the slots of the target revision, after PST.
+        *
+        * @return RevisionSlots
+        */
+       public function getSlots() {
+               $this->assertPrepared( __METHOD__ );
+               return $this->pstContentSlots;
+       }
+
+       /**
+        * Returns the RevisionSlotsUpdate for this updater.
+        *
+        * @return RevisionSlotsUpdate
+        */
+       private function getRevisionSlotsUpdate() {
+               $this->assertPrepared( __METHOD__ );
+
+               if ( !$this->slotsUpdate ) {
+                       if ( !$this->revision ) {
+                               // This should not be possible: if assertPrepared() returns true,
+                               // at least one of $this->slotsUpdate or $this->revision should be set.
+                               throw new LogicException( 'No revision nor a slots update is known!' );
+                       }
+
+                       $old = $this->getOldRevision();
+                       $this->slotsUpdate = RevisionSlotsUpdate::newFromRevisionSlots(
+                               $this->revision->getSlots(),
+                               $old ? $old->getSlots() : null
+                       );
+               }
+               return $this->slotsUpdate;
+       }
+
+       /**
+        * Returns the role names of the slots touched by the new revision,
+        * including removed roles.
+        *
+        * @return string[]
+        */
+       public function getTouchedSlotRoles() {
+               return $this->getRevisionSlotsUpdate()->getTouchedRoles();
+       }
+
+       /**
+        * Returns the role names of the slots modified by the new revision,
+        * not including removed roles.
+        *
+        * @return string[]
+        */
+       public function getModifiedSlotRoles() {
+               return $this->getRevisionSlotsUpdate()->getModifiedRoles();
+       }
+
+       /**
+        * Returns the role names of the slots removed by the new revision.
+        *
+        * @return string[]
+        */
+       public function getRemovedSlotRoles() {
+               return $this->getRevisionSlotsUpdate()->getRemovedRoles();
+       }
+
+       /**
+        * Prepare derived data updates targeting the given Revision.
+        *
+        * Calling this method requires the given revision to be present in the database.
+        * This may be right after a new revision has been created, or when re-generating
+        * derived data e.g. in ApiPurge, RefreshLinksJob, and the refreshLinks
+        * script.
+        *
+        * @see docs/pageupdater.txt for more information on when thie method can and should be called.
+        *
+        * @note Calling this method more than once with the same revision has no effect.
+        * $options are only used for the first call. Calling this method multiple times with
+        * different revisions will cause an exception.
+        *
+        * @note If grabCurrentRevision() (or prepareContent()) has been called before
+        * calling this method, $revision->getParentRevision() has to refer to the revision that
+        * was the current revision at the time grabCurrentRevision() was called.
+        *
+        * @param RevisionRecord $revision
+        * @param array $options Array of options, following indexes are used:
+        * - changed: bool, whether the revision changed the content (default true)
+        * - created: bool, whether the revision created the page (default false)
+        * - moved: bool, whether the page was moved (default false)
+        * - restored: bool, whether the page was undeleted (default false)
+        * - oldrevision: Revision object for the pre-update revision (default null)
+        * - parseroutput: The canonical ParserOutput of $revision (default null)
+        * - triggeringuser: The user triggering the update (UserIdentity, default null)
+        * - oldredirect: bool, null, or string 'no-change' (default null):
+        *    - bool: whether the page was counted as a redirect before that
+        *      revision, only used in changed is true and created is false
+        *    - null or 'no-change': don't update the redirect status.
+        * - oldcountable: bool, null, or string 'no-change' (default null):
+        *    - bool: whether the page was counted as an article before that
+        *      revision, only used in changed is true and created is false
+        *    - null: if created is false, don't update the article count; if created
+        *      is true, do update the article count
+        *    - 'no-change': don't update the article count, ever
+        *
+        */
+       public function prepareUpdate( RevisionRecord $revision, array $options = [] ) {
+               Assert::parameter(
+                       !isset( $options['oldrevision'] )
+                       || $options['oldrevision'] instanceof Revision
+                       || $options['oldrevision'] instanceof RevisionRecord,
+                       '$options["oldrevision"]',
+                       'must be a RevisionRecord (or Revision)'
+               );
+               Assert::parameter(
+                       !isset( $options['parseroutput'] )
+                       || $options['parseroutput'] instanceof ParserOutput,
+                       '$options["parseroutput"]',
+                       'must be a ParserOutput'
+               );
+               Assert::parameter(
+                       !isset( $options['triggeringuser'] )
+                       || $options['triggeringuser'] instanceof UserIdentity,
+                       '$options["triggeringuser"]',
+                       'must be a UserIdentity'
+               );
+
+               if ( !$revision->getId() ) {
+                       throw new InvalidArgumentException(
+                               'Revision must have an ID set for it to be used with prepareUpdate()!'
+                       );
+               }
+
+               if ( $this->revision ) {
+                       if ( $this->revision->getId() === $revision->getId() ) {
+                               return; // nothing to do!
+                       } else {
+                               throw new LogicException(
+                                       'Trying to re-use DerivedPageDataUpdater with revision '
+                                       .$revision->getId()
+                                       . ', but it\'s already bound to revision '
+                                       . $this->revision->getId()
+                               );
+                       }
+               }
+
+               if ( $this->pstContentSlots
+                       && !$this->pstContentSlots->hasSameContent( $revision->getSlots() )
+               ) {
+                       throw new LogicException(
+                               'The Revision provided has mismatching content!'
+                       );
+               }
+
+               // Override fields defined in $this->options with values from $options.
+               $this->options = array_intersect_key( $options, $this->options ) + $this->options;
+
+               if ( isset( $this->pageState['oldId'] ) ) {
+                       $oldId = $this->pageState['oldId'];
+               } elseif ( isset( $this->options['oldrevision'] ) ) {
+                       /** @var Revision|RevisionRecord $oldRev */
+                       $oldRev = $this->options['oldrevision'];
+                       $oldId = $oldRev->getId();
+               } else {
+                       $oldId = $revision->getParentId();
+               }
+
+               if ( $oldId !== null ) {
+                       // XXX: what if $options['changed'] disagrees?
+                       // MovePage creates a dummy revision with changed = false!
+                       // We may want to explicitly distinguish between "no new revision" (null-edit)
+                       // and "new revision without new content" (dummy revision).
+
+                       if ( $oldId === $revision->getParentId() ) {
+                               // NOTE: this may still be a NullRevision!
+                               // New revision!
+                               $this->options['changed'] = true;
+                       } elseif ( $oldId === $revision->getId() ) {
+                               // Null-edit!
+                               $this->options['changed'] = false;
+                       } else {
+                               // This indicates that calling code has given us the wrong Revision object
+                               throw new LogicException(
+                                       'The Revision mismatches old revision ID: '
+                                       . 'Old ID is ' . $oldId
+                                       . ', parent ID is ' . $revision->getParentId()
+                                       . ', revision ID is ' . $revision->getId()
+                               );
+                       }
+               }
+
+               // If prepareContent() was used to generate the PST content (which is indicated by
+               // $this->slotsUpdate being set), and this is not a null-edit, then the given
+               // revision must have the acting user as the revision author. Otherwise, user
+               // signatures generated by PST would mismatch the user in the revision record.
+               if ( $this->user !== null && $this->options['changed'] && $this->slotsUpdate ) {
+                       $user = $revision->getUser();
+                       if ( !$this->user->equals( $user ) ) {
+                               throw new LogicException(
+                                       'The Revision provided has a mismatching actor: expected '
+                                       .$this->user->getName()
+                                       . ', got '
+                                       . $user->getName()
+                               );
+                       }
+               }
+
+               // If $this->pageState was not yet initialized by grabCurrentRevision or prepareContent,
+               // emulate the state of the page table before the edit, as good as we can.
+               if ( !$this->pageState ) {
+                       $this->pageState = [
+                               'oldIsRedirect' => isset( $this->options['oldredirect'] )
+                                       && is_bool( $this->options['oldredirect'] )
+                                               ? $this->options['oldredirect']
+                                               : null,
+                               'oldCountable' => isset( $this->options['oldcountable'] )
+                                       && is_bool( $this->options['oldcountable'] )
+                                               ? $this->options['oldcountable']
+                                               : null,
+                       ];
+
+                       if ( $this->options['changed'] ) {
+                               // The edit created a new revision
+                               $this->pageState['oldId'] = $revision->getParentId();
+
+                               if ( isset( $this->options['oldrevision'] ) ) {
+                                       $rev = $this->options['oldrevision'];
+                                       $this->pageState['oldRevision'] = $rev instanceof Revision
+                                               ? $rev->getRevisionRecord()
+                                               : $rev;
+                               }
+                       } else {
+                               // This is a null-edit, so the old revision IS the new revision!
+                               $this->pageState['oldId'] = $revision->getId();
+                               $this->pageState['oldRevision'] = $revision;
+                       }
+               }
+
+               // "created" is forced here
+               $this->options['created'] = ( $this->pageState['oldId'] === 0 );
+
+               $this->revision = $revision;
+               $this->pstContentSlots = $revision->getSlots();
+
+               $this->doTransition( 'has-revision' );
+
+               // NOTE: in case we have a User object, don't override with a UserIdentity.
+               // We already checked that $revision->getUser() mathces $this->user;
+               if ( !$this->user ) {
+                       $this->user = $revision->getUser( RevisionRecord::RAW );
+               }
+
+               // Prune any output that depends on the revision ID.
+               if ( $this->canonicalParserOutput ) {
+                       if ( $this->outputVariesOnRevisionMetaData( $this->canonicalParserOutput, __METHOD__ ) ) {
+                               $this->canonicalParserOutput = null;
+                       }
+               } else {
+                       $this->saveParseLogger->debug( __METHOD__ . ": No prepared canonical output...\n" );
+               }
+
+               if ( $this->slotsOutput ) {
+                       foreach ( $this->slotsOutput as $role => $prep ) {
+                               if ( $this->outputVariesOnRevisionMetaData( $prep->output, __METHOD__ ) ) {
+                                       unset( $this->slotsOutput[$role] );
+                               }
+                       }
+               } else {
+                       $this->saveParseLogger->debug( __METHOD__ . ": No prepared output...\n" );
+               }
+
+               // reset ParserOptions, so the actual revision ID is used in future ParserOutput generation
+               $this->canonicalParserOptions = null;
+
+               // Avoid re-generating the canonical ParserOutput if it's known.
+               // We just trust that the caller is passing the correct ParserOutput!
+               if ( isset( $options['parseroutput'] ) ) {
+                       $this->canonicalParserOutput = $options['parseroutput'];
+               }
+
+               // TODO: optionally get ParserOutput from the ParserCache here.
+               // Move the logic used by RefreshLinksJob here!
+       }
+
+       /**
+        * @param ParserOutput $out
+        * @param string $method
+        * @return bool
+        */
+       private function outputVariesOnRevisionMetaData( ParserOutput $out, $method = __METHOD__ ) {
+               if ( $out->getFlag( 'vary-revision' ) ) {
+                       // XXX: Just keep the output if the speculative revision ID was correct, like below?
+                       $this->saveParseLogger->info(
+                               "$method: Prepared output has vary-revision...\n"
+                       );
+                       return true;
+               } elseif ( $out->getFlag( 'vary-revision-id' )
+                       && $out->getSpeculativeRevIdUsed() !== $this->revision->getId()
+               ) {
+                       $this->saveParseLogger->info(
+                               "$method: Prepared output has vary-revision-id with wrong ID...\n"
+                       );
+                       return true;
+               } elseif ( $out->getFlag( 'vary-user' )
+                       && !$this->options['changed']
+               ) {
+                       // When Alice makes a null-edit on top of Bob's edit,
+                       // {{REVISIONUSER}} must resolve to "Bob", not "Alice", see T135261.
+                       // TODO: to avoid this, we should check for null-edits in makeCanonicalparserOptions,
+                       // and set setCurrentRevisionCallback to return the existing revision when appropriate.
+                       // See also the comment there [dk 2018-05]
+                       $this->saveParseLogger->info(
+                               "$method: Prepared output has vary-user and is null-edit...\n"
+                       );
+                       return true;
+               } else {
+                       wfDebug( "$method: Keeping prepared output...\n" );
+                       return false;
+               }
+       }
+
+       /**
+        * @deprecated This only exists for B/C, use the getters on DerivedPageDataUpdater directly!
+        * @return PreparedEdit
+        */
+       public function getPreparedEdit() {
+               $this->assertPrepared( __METHOD__ );
+
+               $slotsUpdate = $this->getRevisionSlotsUpdate();
+               $preparedEdit = new PreparedEdit();
+
+               $preparedEdit->popts = $this->getCanonicalParserOptions();
+               $preparedEdit->output = $this->getCanonicalParserOutput();
+               $preparedEdit->pstContent = $this->pstContentSlots->getContent( 'main' );
+               $preparedEdit->newContent =
+                       $slotsUpdate->isModifiedSlot( 'main' )
+                       ? $slotsUpdate->getModifiedSlot( 'main' )->getContent()
+                       : $this->pstContentSlots->getContent( 'main' ); // XXX: can we just remove this?
+               $preparedEdit->oldContent = null; // unused. // XXX: could get this from the parent revision
+               $preparedEdit->revid = $this->revision ? $this->revision->getId() : null;
+               $preparedEdit->timestamp = $preparedEdit->output->getCacheTime();
+               $preparedEdit->format = $preparedEdit->pstContent->getDefaultFormat();
+
+               return $preparedEdit;
+       }
+
+       /**
+        * @return bool
+        */
+       private function isContentAccessible() {
+               // XXX: when we move this to a RevisionHtmlProvider, the audience may be configurable!
+               return $this->isContentPublic();
+       }
+
+       /**
+        * @param string $role
+        * @param bool $generateHtml
+        * @return ParserOutput
+        */
+       public function getSlotParserOutput( $role, $generateHtml = true ) {
+               // TODO: factor this out into a RevisionHtmlProvider that can also be used for viewing.
+
+               $this->assertPrepared( __METHOD__ );
+
+               if ( isset( $this->slotsOutput[$role] ) ) {
+                       $entry = $this->slotsOutput[$role];
+
+                       if ( $entry->hasHtml || !$generateHtml ) {
+                               return $entry->output;
+                       }
+               }
+
+               if ( !$this->isContentAccessible() ) {
+                       // empty output
+                       $output = new ParserOutput();
+               } else {
+                       $content = $this->getRawContent( $role );
+
+                       $output = $content->getParserOutput(
+                               $this->getTitle(),
+                               $this->revision ? $this->revision->getId() : null,
+                               $this->getCanonicalParserOptions(),
+                               $generateHtml
+                       );
+               }
+
+               $this->slotsOutput[$role] = (object)[
+                       'output' => $output,
+                       'hasHtml' => $generateHtml,
+               ];
+
+               $output->setCacheTime( $this->getTimestampNow() );
+
+               return $output;
+       }
+
+       /**
+        * @return ParserOutput
+        */
+       public function getCanonicalParserOutput() {
+               if ( $this->canonicalParserOutput ) {
+                       return $this->canonicalParserOutput;
+               }
+
+               // TODO: MCR: logic for combining the output of multiple slot goes here!
+               // TODO: factor this out into a RevisionHtmlProvider that can also be used for viewing.
+               $this->canonicalParserOutput = $this->getSlotParserOutput( 'main' );
+
+               return $this->canonicalParserOutput;
+       }
+
+       /**
+        * @return ParserOptions
+        */
+       public function getCanonicalParserOptions() {
+               if ( $this->canonicalParserOptions ) {
+                       return $this->canonicalParserOptions;
+               }
+
+               // TODO: ParserOptions should *not* be controlled by the ContentHandler!
+               // See T190712 for how to fix this for Wikibase.
+               $this->canonicalParserOptions = $this->wikiPage->makeParserOptions( 'canonical' );
+
+               //TODO: if $this->revision is not set but we already know that we pending update is a
+               // null-edit, we should probably use the page's current revision here.
+               // That would avoid the need for the !$this->options['changed'] branch in
+               // outputVariesOnRevisionMetaData [dk 2018-05]
+
+               if ( $this->revision ) {
+                       // Make sure we use the appropriate revision ID when generating output
+                       $title = $this->getTitle();
+                       $oldCallback = $this->canonicalParserOptions->getCurrentRevisionCallback();
+                       $this->canonicalParserOptions->setCurrentRevisionCallback(
+                               function ( Title $parserTitle, $parser = false ) use ( $title, &$oldCallback ) {
+                                       if ( $parserTitle->equals( $title ) ) {
+                                               $legacyRevision = new Revision( $this->revision );
+                                               return $legacyRevision;
+                                       } else {
+                                               return call_user_func( $oldCallback, $parserTitle, $parser );
+                                       }
+                               }
+                       );
+               } else {
+                       // NOTE: we only get here without READ_LATEST if called directly by application logic
+                       $dbIndex = $this->useMaster()
+                               ? DB_MASTER // use the best possible guess
+                               : DB_REPLICA; // T154554
+
+                       $this->canonicalParserOptions->setSpeculativeRevIdCallback(
+                               function () use ( $dbIndex ) {
+                                       // TODO: inject LoadBalancer!
+                                       $lb = MediaWikiServices::getInstance()->getDBLoadBalancer();
+                                       // Use a fresh connection in order to see the latest data, by avoiding
+                                       // stale data from REPEATABLE-READ snapshots.
+                                       // HACK: But don't use a fresh connection in unit tests, since it would not have
+                                       // the fake tables. This should be handled by the LoadBalancer!
+                                       $flags = defined( 'MW_PHPUNIT_TEST' ) ? 0 : $lb::CONN_TRX_AUTOCOMMIT;
+                                       $db = $lb->getConnectionRef( $dbIndex, [], $this->getWikiId(), $flags );
+
+                                       return 1 + (int)$db->selectField(
+                                               'revision',
+                                               'MAX(rev_id)',
+                                               [],
+                                               __METHOD__
+                                       );
+                               }
+                       );
+               }
+
+               return $this->canonicalParserOptions;
+       }
+
+       /**
+        * @param bool $recursive
+        *
+        * @return DataUpdate[]
+        */
+       public function getSecondaryDataUpdates( $recursive = false ) {
+               // TODO: MCR: getSecondaryDataUpdates() needs a complete overhaul to avoid DataUpdates
+               // from different slots overwriting each other in the database. Plan:
+               // * replace direct calls to Content::getSecondaryDataUpdates() with calls to this method
+               // * Construct LinksUpdate here, on the combined ParserOutput, instead of in AbstractContent
+               //   for each slot.
+               // * Pass $slot into getSecondaryDataUpdates() - probably be introducing a new duplicate
+               //   version of this function in ContentHandler.
+               // * The new method gets the PreparedEdit, but no $recursive flag (that's for LinksUpdate)
+               // * Hack: call both the old and the new getSecondaryDataUpdates method here; Pass
+               //   the per-slot ParserOutput to the old method, for B/C.
+               // * Hack: If there is more than one slot, filter LinksUpdate from the DataUpdates
+               //   returned by getSecondaryDataUpdates, and use a LinksUpdated for the combined output
+               //   instead.
+               // * Call the SecondaryDataUpdates hook here (or kill it - its signature doesn't make sense)
+
+               $content = $this->getSlots()->getContent( 'main' );
+
+               // NOTE: $output is the combined output, to be shown in the default view.
+               $output = $this->getCanonicalParserOutput();
+
+               $updates = $content->getSecondaryDataUpdates(
+                       $this->getTitle(), null, $recursive, $output
+               );
+
+               return $updates;
+       }
+
+       /**
+        * Do standard updates after page edit, purge, or import.
+        * Update links tables, site stats, search index, title cache, message cache, etc.
+        * Purges pages that depend on this page when appropriate.
+        * With a 10% chance, triggers pruning the recent changes table.
+        *
+        * @note prepareUpdate() must be called before calling this method!
+        *
+        * MCR migration note: this replaces WikiPage::doEditUpdates.
+        */
+       public function doUpdates() {
+               $this->assertTransition( 'done' );
+
+               // TODO: move logic into a PageEventEmitter service
+
+               $wikiPage = $this->getWikiPage(); // TODO: use only for legacy hooks!
+
+               // NOTE: this may trigger the first parsing of the new content after an edit (when not
+               // using pre-generated stashed output).
+               // XXX: we may want to use the PoolCounter here. This would perhaps allow the initial parse
+               // to be perform post-send. The client could already follow a HTTP redirect to the
+               // page view, but would then have to wait for a response until rendering is complete.
+               $output = $this->getCanonicalParserOutput();
+
+               // Save it to the parser cache.
+               // Make sure the cache time matches page_touched to avoid double parsing.
+               $this->parserCache->save(
+                       $output, $wikiPage, $this->getCanonicalParserOptions(),
+                       $this->revision->getTimestamp(),  $this->revision->getId()
+               );
+
+               $legacyUser = User::newFromIdentity( $this->user );
+               $legacyRevision = new Revision( $this->revision );
+
+               // Update the links tables and other secondary data
+               $recursive = $this->options['changed']; // T52785
+               $updates = $this->getSecondaryDataUpdates( $recursive );
+
+               foreach ( $updates as $update ) {
+                       // TODO: make an $option field for the cause
+                       $update->setCause( 'edit-page', $this->user->getName() );
+                       if ( $update instanceof LinksUpdate ) {
+                               $update->setRevision( $legacyRevision );
+
+                               if ( !empty( $this->options['triggeringuser'] ) ) {
+                                       /** @var UserIdentity|User $triggeringUser */
+                                       $triggeringUser = $this->options['triggeringuser'];
+                                       if ( !$triggeringUser instanceof User ) {
+                                               $triggeringUser = User::newFromIdentity( $triggeringUser );
+                                       }
+
+                                       $update->setTriggeringUser( $triggeringUser );
+                               }
+                       }
+                       DeferredUpdates::addUpdate( $update );
+               }
+
+               // TODO: MCR: check if *any* changed slot supports categories!
+               if ( $this->rcWatchCategoryMembership
+                       && $this->getContentHandler( 'main' )->supportsCategories() === true
+                       && ( $this->options['changed'] || $this->options['created'] )
+                       && !$this->options['restored']
+               ) {
+                       // Note: jobs are pushed after deferred updates, so the job should be able to see
+                       // the recent change entry (also done via deferred updates) and carry over any
+                       // bot/deletion/IP flags, ect.
+                       $this->jobQueueGroup->lazyPush(
+                               new CategoryMembershipChangeJob(
+                                       $this->getTitle(),
+                                       [
+                                               'pageId' => $this->getPageId(),
+                                               'revTimestamp' => $this->revision->getTimestamp(),
+                                       ]
+                               )
+                       );
+               }
+
+               // TODO: replace legacy hook! Use a listener on PageEventEmitter instead!
+               $editInfo = $this->getPreparedEdit();
+               Hooks::run( 'ArticleEditUpdates', [ &$wikiPage, &$editInfo, $this->options['changed'] ] );
+
+               // TODO: replace legacy hook! Use a listener on PageEventEmitter instead!
+               if ( Hooks::run( 'ArticleEditUpdatesDeleteFromRecentchanges', [ &$wikiPage ] ) ) {
+                       // Flush old entries from the `recentchanges` table
+                       if ( mt_rand( 0, 9 ) == 0 ) {
+                               $this->jobQueueGroup->lazyPush( RecentChangesUpdateJob::newPurgeJob() );
+                       }
+               }
+
+               $id = $this->getPageId();
+               $title = $this->getTitle();
+               $dbKey = $title->getPrefixedDBkey();
+               $shortTitle = $title->getDBkey();
+
+               if ( !$title->exists() ) {
+                       wfDebug( __METHOD__ . ": Page doesn't exist any more, bailing out\n" );
+
+                       $this->doTransition( 'done' );
+                       return;
+               }
+
+               if ( $this->options['oldcountable'] === 'no-change' ||
+                       ( !$this->options['changed'] && !$this->options['moved'] )
+               ) {
+                       $good = 0;
+               } elseif ( $this->options['created'] ) {
+                       $good = (int)$this->isCountable();
+               } elseif ( $this->options['oldcountable'] !== null ) {
+                       $good = (int)$this->isCountable()
+                               - (int)$this->options['oldcountable'];
+               } else {
+                       $good = 0;
+               }
+               $edits = $this->options['changed'] ? 1 : 0;
+               $pages = $this->options['created'] ? 1 : 0;
+
+               DeferredUpdates::addUpdate( SiteStatsUpdate::factory(
+                       [ 'edits' => $edits, 'articles' => $good, 'pages' => $pages ]
+               ) );
+
+               // TODO: make search infrastructure aware of slots!
+               $mainSlot = $this->revision->getSlot( 'main' );
+               if ( !$mainSlot->isInherited() && $this->isContentPublic() ) {
+                       DeferredUpdates::addUpdate( new SearchUpdate( $id, $dbKey, $mainSlot->getContent() ) );
+               }
+
+               // If this is another user's talk page, update newtalk.
+               // Don't do this if $options['changed'] = false (null-edits) nor if
+               // it's a minor edit and the user making the edit doesn't generate notifications for those.
+               if ( $this->options['changed']
+                       && $title->getNamespace() == NS_USER_TALK
+                       && $shortTitle != $legacyUser->getTitleKey()
+                       && !( $this->revision->isMinor() && $legacyUser->isAllowed( 'nominornewtalk' ) )
+               ) {
+                       $recipient = User::newFromName( $shortTitle, false );
+                       if ( !$recipient ) {
+                               wfDebug( __METHOD__ . ": invalid username\n" );
+                       } else {
+                               // Allow extensions to prevent user notification
+                               // when a new message is added to their talk page
+                               // TODO: replace legacy hook!  Use a listener on PageEventEmitter instead!
+                               if ( Hooks::run( 'ArticleEditUpdateNewTalk', [ &$wikiPage, $recipient ] ) ) {
+                                       if ( User::isIP( $shortTitle ) ) {
+                                               // An anonymous user
+                                               $recipient->setNewtalk( true, $legacyRevision );
+                                       } elseif ( $recipient->isLoggedIn() ) {
+                                               $recipient->setNewtalk( true, $legacyRevision );
+                                       } else {
+                                               wfDebug( __METHOD__ . ": don't need to notify a nonexistent user\n" );
+                                       }
+                               }
+                       }
+               }
+
+               if ( $title->getNamespace() == NS_MEDIAWIKI
+                       && $this->getRevisionSlotsUpdate()->isModifiedSlot( 'main' )
+               ) {
+                       $mainContent = $this->isContentPublic() ? $this->getRawContent( 'main' ) : null;
+
+                       $this->messageCache->updateMessageOverride( $title, $mainContent );
+               }
+
+               // TODO: move onArticleCreate and onArticle into a PageEventEmitter service
+               if ( $this->options['created'] ) {
+                       WikiPage::onArticleCreate( $title );
+               } elseif ( $this->options['changed'] ) { // T52785
+                       WikiPage::onArticleEdit( $title, $legacyRevision, $this->getTouchedSlotRoles() );
+               }
+
+               $oldRevision = $this->getOldRevision();
+               $oldLegacyRevision = $oldRevision ? new Revision( $oldRevision ) : null;
+
+               // TODO: In the wiring, register a listener for this on the new PageEventEmitter
+               ResourceLoaderWikiModule::invalidateModuleCache(
+                       $title, $oldLegacyRevision, $legacyRevision, $this->getWikiId()
+               );
+
+               $this->doTransition( 'done' );
+       }
+
+}
index a259ae0..1aa1165 100644 (file)
@@ -44,26 +44,14 @@ class MutableRevisionRecord extends RevisionRecord {
         * the new revision will act as a null-revision.
         *
         * @param RevisionRecord $parent
-        * @param CommentStoreComment $comment
-        * @param UserIdentity $user
-        * @param string $timestamp
         *
         * @return MutableRevisionRecord
         */
-       public static function newFromParentRevision(
-               RevisionRecord $parent,
-               CommentStoreComment $comment,
-               UserIdentity $user,
-               $timestamp
-       ) {
+       public static function newFromParentRevision( RevisionRecord $parent ) {
                // TODO: ideally, we wouldn't need a Title here
                $title = Title::newFromLinkTarget( $parent->getPageAsLinkTarget() );
                $rev = new MutableRevisionRecord( $title, $parent->getWikiId() );
 
-               $rev->setComment( $comment );
-               $rev->setUser( $user );
-               $rev->setTimestamp( $timestamp );
-
                foreach ( $parent->getSlotRoles() as $role ) {
                        $slot = $parent->getSlot( $role, self::RAW );
                        $rev->inheritSlot( $slot );
@@ -140,8 +128,8 @@ class MutableRevisionRecord extends RevisionRecord {
         * @param SlotRecord $parentSlot
         */
        public function inheritSlot( SlotRecord $parentSlot ) {
-               $slot = SlotRecord::newInherited( $parentSlot );
-               $this->setSlot( $slot );
+               $this->mSlots->inheritSlot( $parentSlot );
+               $this->resetAggregateValues();
        }
 
        /**
@@ -180,6 +168,15 @@ class MutableRevisionRecord extends RevisionRecord {
                $this->resetAggregateValues();
        }
 
+       /**
+        * Applies the given update to the slots of this revision.
+        *
+        * @param RevisionSlotsUpdate $update
+        */
+       public function applyUpdate( RevisionSlotsUpdate $update ) {
+               $update->apply( $this->mSlots );
+       }
+
        /**
         * @param CommentStoreComment $comment
         */
index 4cc3730..df94964 100644 (file)
@@ -60,8 +60,6 @@ class MutableRevisionSlots extends RevisionSlots {
         * Sets the given slot.
         * If a slot with the same role is already present, it is replaced.
         *
-        * @note This may cause the slot meta-data for the revision to be lazy-loaded.
-        *
         * @param SlotRecord $slot
         */
        public function setSlot( SlotRecord $slot ) {
@@ -74,10 +72,18 @@ class MutableRevisionSlots extends RevisionSlots {
        }
 
        /**
-        * Sets the content for the slot with the given role.
+        * Sets the given slot to an inherited version of $slot.
         * If a slot with the same role is already present, it is replaced.
         *
-        * @note This may cause the slot meta-data for the revision to be lazy-loaded.
+        * @param SlotRecord $slot
+        */
+       public function inheritSlot( SlotRecord $slot ) {
+               $this->setSlot( SlotRecord::newInherited( $slot ) );
+       }
+
+       /**
+        * Sets the content for the slot with the given role.
+        * If a slot with the same role is already present, it is replaced.
         *
         * @param string $role
         * @param Content $content
@@ -90,8 +96,6 @@ class MutableRevisionSlots extends RevisionSlots {
        /**
         * Remove the slot for the given role, discontinue the corresponding stream.
         *
-        * @note This may cause the slot meta-data for the revision to be lazy-loaded.
-        *
         * @param string $role
         */
        public function removeSlot( $role ) {
index ebce3da..3516ffe 100644 (file)
@@ -60,6 +60,8 @@ class NameTableStore {
        private $nameField;
        /** @var null|callable */
        private $normalizationCallback = null;
+       /** @var null|callable */
+       private $insertCallback = null;
 
        /**
         * @param LoadBalancer $dbLoadBalancer A load balancer for acquiring database connections
@@ -68,9 +70,11 @@ class NameTableStore {
         * @param string $table
         * @param string $idField
         * @param string $nameField
-        * @param callable $normalizationCallback Normalization to be applied to names before being
+        * @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 callable|null $insertCallback Callback to change insert fields accordingly.
+        * This parameter was introduced in 1.32
         */
        public function __construct(
                LoadBalancer $dbLoadBalancer,
@@ -80,7 +84,8 @@ class NameTableStore {
                $idField,
                $nameField,
                callable $normalizationCallback = null,
-               $wikiId = false
+               $wikiId = false,
+               callable $insertCallback = null
        ) {
                $this->loadBalancer = $dbLoadBalancer;
                $this->cache = $cache;
@@ -91,6 +96,7 @@ class NameTableStore {
                $this->normalizationCallback = $normalizationCallback;
                $this->wikiId = $wikiId;
                $this->cacheTTL = IExpiringStore::TTL_MONTH;
+               $this->insertCallback = $insertCallback;
        }
 
        /**
@@ -103,8 +109,20 @@ class NameTableStore {
                return $this->loadBalancer->getConnection( $index, [], $this->wikiId, $flags );
        }
 
+       /**
+        * Gets the cache key for names.
+        *
+        * The cache key is constructed based on the wiki ID passed to the constructor, and allows
+        * sharing of name tables cached for a specific database between wikis.
+        *
+        * @return string
+        */
        private function getCacheKey() {
-               return $this->cache->makeKey( 'NameTableSqlStore', $this->table, $this->wikiId );
+               return $this->cache->makeGlobalKey(
+                       'NameTableSqlStore',
+                       $this->table,
+                       $this->loadBalancer->resolveDomainID( $this->wikiId )
+               );
        }
 
        /**
@@ -348,7 +366,7 @@ class NameTableStore {
 
                $dbw->insert(
                        $this->table,
-                       [ $this->nameField => $name ],
+                       $this->getFieldsToStore( $name ),
                        __METHOD__,
                        [ 'IGNORE' ]
                );
@@ -363,4 +381,16 @@ class NameTableStore {
                return $dbw->insertId();
        }
 
+       /**
+        * @param string $name
+        * @return array
+        */
+       private function getFieldsToStore( $name ) {
+               $fields = [ $this->nameField => $name ];
+               if ( $this->insertCallback !== null ) {
+                       $fields = call_user_func( $this->insertCallback, $fields );
+               }
+               return $fields;
+       }
+
 }
diff --git a/includes/Storage/PageUpdateException.php b/includes/Storage/PageUpdateException.php
new file mode 100644 (file)
index 0000000..d87374a
--- /dev/null
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Exception representing a failure to update a page entry.
+ *
+ * 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\Storage;
+
+use RuntimeException;
+
+/**
+ * Exception representing a failure to update a page entry.
+ *
+ * @since 1.32
+ */
+class PageUpdateException extends RuntimeException {
+
+}
diff --git a/includes/Storage/PageUpdater.php b/includes/Storage/PageUpdater.php
new file mode 100644 (file)
index 0000000..c6795ea
--- /dev/null
@@ -0,0 +1,1211 @@
+<?php
+/**
+ * Controller-like object for creating and updating pages by creating new revisions.
+ *
+ * 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 Daniel Kinzler
+ */
+
+namespace MediaWiki\Storage;
+
+use AtomicSectionUpdate;
+use ChangeTags;
+use CommentStoreComment;
+use Content;
+use ContentHandler;
+use DeferredUpdates;
+use Hooks;
+use InvalidArgumentException;
+use LogicException;
+use ManualLogEntry;
+use MediaWiki\Linker\LinkTarget;
+use MWException;
+use RecentChange;
+use Revision;
+use RuntimeException;
+use Status;
+use Title;
+use User;
+use Wikimedia\Assert\Assert;
+use Wikimedia\Rdbms\DBConnRef;
+use Wikimedia\Rdbms\DBUnexpectedError;
+use Wikimedia\Rdbms\IDatabase;
+use Wikimedia\Rdbms\LoadBalancer;
+use WikiPage;
+
+/**
+ * Controller-like object for creating and updating pages by creating new revisions.
+ *
+ * PageUpdater instances provide compare-and-swap (CAS) protection against concurrent updates
+ * between the time grabParentRevision() is called and saveRevision() inserts a new revision.
+ * This allows application logic to safely perform edit conflict resolution using the parent
+ * revision's content.
+ *
+ * @see docs/pageupdater.txt for more information.
+ *
+ * MCR migration note: this replaces the relevant methods in WikiPage.
+ *
+ * @since 1.32
+ * @ingroup Page
+ */
+class PageUpdater {
+
+       /**
+        * @var User
+        */
+       private $user;
+
+       /**
+        * @var WikiPage
+        */
+       private $wikiPage;
+
+       /**
+        * @var DerivedPageDataUpdater
+        */
+       private $derivedDataUpdater;
+
+       /**
+        * @var LoadBalancer
+        */
+       private $loadBalancer;
+
+       /**
+        * @var RevisionStore
+        */
+       private $revisionStore;
+
+       /**
+        * @var boolean see $wgUseAutomaticEditSummaries
+        * @see $wgUseAutomaticEditSummaries
+        */
+       private $useAutomaticEditSummaries = true;
+
+       /**
+        * @var int the RC patrol status the new revision should be marked with.
+        */
+       private $rcPatrolStatus = RecentChange::PRC_UNPATROLLED;
+
+       /**
+        * @var bool whether to create a log entry for new page creations.
+        */
+       private $usePageCreationLog = true;
+
+       /**
+        * @var boolean see $wgAjaxEditStash
+        */
+       private $ajaxEditStash = true;
+
+       /**
+        * @var bool|int
+        */
+       private $originalRevId = false;
+
+       /**
+        * @var array
+        */
+       private $tags = [];
+
+       /**
+        * @var int
+        */
+       private $undidRevId = 0;
+
+       /**
+        * @var RevisionSlotsUpdate
+        */
+       private $slotsUpdate;
+
+       /**
+        * @var Status|null
+        */
+       private $status = null;
+
+       /**
+        * @param User $user
+        * @param WikiPage $wikiPage
+        * @param DerivedPageDataUpdater $derivedDataUpdater
+        * @param LoadBalancer $loadBalancer
+        * @param RevisionStore $revisionStore
+        */
+       public function __construct(
+               User $user,
+               WikiPage $wikiPage,
+               DerivedPageDataUpdater $derivedDataUpdater,
+               LoadBalancer $loadBalancer,
+               RevisionStore $revisionStore
+       ) {
+               $this->user = $user;
+               $this->wikiPage = $wikiPage;
+               $this->derivedDataUpdater = $derivedDataUpdater;
+
+               $this->loadBalancer = $loadBalancer;
+               $this->revisionStore = $revisionStore;
+
+               $this->slotsUpdate = new RevisionSlotsUpdate();
+       }
+
+       /**
+        * Can be used to enable or disable automatic summaries that are applied to certain kinds of
+        * changes, like completely blanking a page.
+        *
+        * @param bool $useAutomaticEditSummaries
+        * @see $wgUseAutomaticEditSummaries
+        */
+       public function setUseAutomaticEditSummaries( $useAutomaticEditSummaries ) {
+               $this->useAutomaticEditSummaries = $useAutomaticEditSummaries;
+       }
+
+       /**
+        * Sets the "patrolled" status of the edit.
+        * Callers should check the "patrol" and "autopatrol" permissions as appropriate.
+        *
+        * @see $wgUseRCPatrol
+        * @see $wgUseNPPatrol
+        *
+        * @param int $status RC patrol status, e.g. RecentChange::PRC_AUTOPATROLLED.
+        */
+       public function setRcPatrolStatus( $status ) {
+               $this->rcPatrolStatus = $status;
+       }
+
+       /**
+        * Whether to create a log entry for new page creations.
+        *
+        * @see $wgPageCreationLog
+        *
+        * @param bool $use
+        */
+       public function setUsePageCreationLog( $use ) {
+               $this->usePageCreationLog = $use;
+       }
+
+       /**
+        * @param bool $ajaxEditStash
+        * @see $wgAjaxEditStash
+        */
+       public function setAjaxEditStash( $ajaxEditStash ) {
+               $this->ajaxEditStash = $ajaxEditStash;
+       }
+
+       private function getWikiId() {
+               return false; // TODO: get from RevisionStore!
+       }
+
+       /**
+        * @param int $mode DB_MASTER or DB_REPLICA
+        *
+        * @return DBConnRef
+        */
+       private function getDBConnectionRef( $mode ) {
+               return $this->loadBalancer->getConnectionRef( $mode, [], $this->getWikiId() );
+       }
+
+       /**
+        * @return LinkTarget
+        */
+       private function getLinkTarget() {
+               // NOTE: eventually, we won't get a WikiPage passed into the constructor any more
+               return $this->wikiPage->getTitle();
+       }
+
+       /**
+        * @return Title
+        */
+       private function getTitle() {
+               // NOTE: eventually, we won't get a WikiPage passed into the constructor any more
+               return $this->wikiPage->getTitle();
+       }
+
+       /**
+        * @return WikiPage
+        */
+       private function getWikiPage() {
+               // NOTE: eventually, we won't get a WikiPage passed into the constructor any more
+               return $this->wikiPage;
+       }
+
+       /**
+        * Checks whether this update conflicts with another update performed between the client
+        * loading data to prepare an edit, and the client committing the edit. This is intended to
+        * detect user level "edit conflict" when the latest revision known to the client
+        * is no longer the current revision when processing the update.
+        *
+        * An update expected to create a new page can be checked by setting $expectedParentRevision = 0.
+        * Such an update is considered to have a conflict if a current revision exists (that is,
+        * the page was created since the edit was initiated on the client).
+        *
+        * This method returning true indicates to calling code that edit conflict resolution should
+        * be applied before saving any data. It does not prevent the update from being performed, and
+        * it should not be confused with a "late" conflict indicated by the "edit-conflict" status.
+        * A "late" conflict is a CAS failure caused by an update being performed concurrently between
+        * the time grabParentRevision() was called and the time saveRevision() trying to insert the
+        * new revision.
+        *
+        * @note A user level edit conflict is not the same as the "edit-conflict" status triggered by
+        * a CAS failure. Calling this method establishes the CAS token, it does not check against it:
+        * This method calls grabParentRevision(), and thus causes the expected parent revision
+        * for the update to be fixed to the page's current revision at this point in time.
+        * It acts as a compare-and-swap (CAS) token in that it is guaranteed that saveRevision()
+        * will fail with the "edit-conflict" status if the current revision of the page changes after
+        * hasEditConflict() (or grabParentRevision()) was called and before saveRevision() could insert
+        * a new revision.
+        *
+        * @see grabParentRevision()
+        *
+        * @param int $expectedParentRevision The ID of the revision the client expects to be the
+        *        current one. Use 0 to indicate that the page is expected to not yet exist.
+        *
+        * @return bool
+        */
+       public function hasEditConflict( $expectedParentRevision ) {
+               $parent = $this->grabParentRevision();
+               $parentId = $parent ? $parent->getId() : 0;
+
+               return $parentId !== $expectedParentRevision;
+       }
+
+       /**
+        * Returns the revision that was the page's current revision when grabParentRevision()
+        * was first called. This revision is the expected parent revision of the update, and will be
+        * recorded as the new revision's parent revision (unless no new revision is created because
+        * the content was not changed).
+        *
+        * This method MUST not be called after saveRevision() was called!
+        *
+        * The current revision determined by the first call to this methods effectively acts a
+        * compare-and-swap (CAS) token which is checked by saveRevision(), which fails if any
+        * concurrent updates created a new revision.
+        *
+        * Application code should call this method before applying transformations to the new
+        * content that depend on the parent revision, e.g. adding/replacing sections, or resolving
+        * conflicts via a 3-way merge. This protects against race conditions triggered by concurrent
+        * updates.
+        *
+        * @see DerivedPageDataUpdater::grabCurrentRevision()
+        *
+        * @note The expected parent revision is not to be confused with the logical base revision.
+        * The base revision is specified by the client, the parent revision is determined from the
+        * database. If base revision and parent revision are not the same, the updates is considered
+        * to require edit conflict resolution.
+        *
+        * @throws LogicException if called after saveRevision().
+        * @return RevisionRecord|null the parent revision, or null of the page does not yet exist.
+        */
+       public function grabParentRevision() {
+               return $this->derivedDataUpdater->grabCurrentRevision();
+       }
+
+       /**
+        * @return string
+        */
+       private function getTimestampNow() {
+               // TODO: allow an override to be injected for testing
+               return wfTimestampNow();
+       }
+
+       /**
+        * Check flags and add EDIT_NEW or EDIT_UPDATE to them as needed.
+        *
+        * @param int $flags
+        * @return int Updated $flags
+        */
+       private function checkFlags( $flags ) {
+               if ( !( $flags & EDIT_NEW ) && !( $flags & EDIT_UPDATE ) ) {
+                       $flags |= ( $this->derivedDataUpdater->pageExisted() ) ? EDIT_UPDATE : EDIT_NEW;
+               }
+
+               return $flags;
+       }
+
+       /**
+        * Set the new content for the given slot role
+        *
+        * @param string $role A slot role name (such as "main")
+        * @param Content $content
+        */
+       public function setContent( $role, Content $content ) {
+               // TODO: MCR: check the role and the content's model against the list of supported
+               // roles, see T194046.
+
+               if ( $role !== 'main' ) {
+                       throw new InvalidArgumentException( 'Only the main slot is presently supported' );
+               }
+
+               $this->slotsUpdate->modifyContent( $role, $content );
+       }
+
+       /**
+        * Explicitly inherit a slot from some earlier revision.
+        *
+        * The primary use case for this is rollbacks, when slots are to be inherited from
+        * the rollback target, overriding the content from the parent revision (which is the
+        * revision being rolled back).
+        *
+        * This should typically not be used to inherit slots from the parent revision, which
+        * happens implicitly. Using this method causes the given slot to be treated as "modified"
+        * during revision creation, even if it has the same content as in the parent revision.
+        *
+        * @param SlotRecord $originalSlot A slot already existing in the database, to be inherited
+        *        by the new revision.
+        */
+       public function inheritSlot( SlotRecord $originalSlot ) {
+               // NOTE: this slot is inherited from some other revision, but it's
+               // a "modified" slot for the RevisionSlotsUpdate and DerivedPageDataUpdater,
+               // since it's not implicitly inherited from the parent revision.
+               $inheritedSlot = SlotRecord::newInherited( $originalSlot );
+               $this->slotsUpdate->modifySlot( $inheritedSlot );
+       }
+
+       /**
+        * Removes the slot with the given role.
+        *
+        * This discontinues the "stream" of slots with this role on the page,
+        * preventing the new revision, and any subsequent revisions, from
+        * inheriting the slot with this role.
+        *
+        * @param string $role A slot role name (but not "main")
+        */
+       public function removeSlot( $role ) {
+               if ( $role === 'main' ) {
+                       throw new InvalidArgumentException( 'Cannot remove the main slot!' );
+               }
+
+               $this->slotsUpdate->removeSlot( $role );
+       }
+
+       /**
+        * Returns the ID of an earlier revision that is being repeated or restored by this update.
+        *
+        * @return bool|int The original revision id, or false if no earlier revision is known to be
+        * repeated or restored by this update.
+        */
+       public function getOriginalRevisionId() {
+               return $this->originalRevId;
+       }
+
+       /**
+        * Sets the ID of an earlier revision that is being repeated or restored by this update.
+        * The new revision is expected to have the exact same content as the given original revision.
+        * This is used with rollbacks and with dummy "null" revisions which are created to record
+        * things like page moves.
+        *
+        * This value is passed to the PageContentSaveComplete and NewRevisionFromEditComplete hooks.
+        *
+        * @param int|bool $originalRevId The original revision id, or false if no earlier revision
+        * is known to be repeated or restored by this update.
+        */
+       public function setOriginalRevisionId( $originalRevId ) {
+               Assert::parameterType( 'integer|boolean', $originalRevId, '$originalRevId' );
+               $this->originalRevId = $originalRevId;
+       }
+
+       /**
+        * Returns the revision ID set by setUndidRevisionId(), indicating what revision is being
+        * undone by this edit.
+        *
+        * @return int
+        */
+       public function getUndidRevisionId() {
+               return $this->undidRevId;
+       }
+
+       /**
+        * Sets the ID of revision that was undone by the present update.
+        * This is used with the "undo" action, and is expected to hold the oldest revision ID
+        * in case more then one revision is being undone.
+        *
+        * @param int $undidRevId
+        */
+       public function setUndidRevisionId( $undidRevId ) {
+               Assert::parameterType( 'integer', $undidRevId, '$undidRevId' );
+               $this->undidRevId = $undidRevId;
+       }
+
+       /**
+        * Sets a tag to apply to this update.
+        * Callers are responsible for permission checks,
+        * using ChangeTags::canAddTagsAccompanyingChange.
+        * @param string $tag
+        */
+       public function addTag( $tag ) {
+               Assert::parameterType( 'string', $tag, '$tag' );
+               $this->tags[] = trim( $tag );
+       }
+
+       /**
+        * Sets tags to apply to this update.
+        * Callers are responsible for permission checks,
+        * using ChangeTags::canAddTagsAccompanyingChange.
+        * @param string[] $tags
+        */
+       public function addTags( array $tags ) {
+               Assert::parameterElementType( 'string', $tags, '$tags' );
+               foreach ( $tags as $tag ) {
+                       $this->addTag( $tag );
+               }
+       }
+
+       /**
+        * Returns the list of tags set using the addTag() method.
+        *
+        * @return string[]
+        */
+       public function getExplicitTags() {
+               return $this->tags;
+       }
+
+       /**
+        * @param int $flags Bit mask: a bit mask of EDIT_XXX flags.
+        * @return string[]
+        */
+       private function computeEffectiveTags( $flags ) {
+               $tags = $this->tags;
+
+               foreach ( $this->slotsUpdate->getModifiedRoles() as $role ) {
+                       $old_content = $this->getParentContent( $role );
+
+                       $handler = $this->getContentHandler( $role );
+                       $content = $this->slotsUpdate->getModifiedSlot( $role )->getContent();
+
+                       // TODO: MCR: Do this for all slots. Also add tags for removing roles!
+                       $tag = $handler->getChangeTag( $old_content, $content, $flags );
+                       // If there is no applicable tag, null is returned, so we need to check
+                       if ( $tag ) {
+                               $tags[] = $tag;
+                       }
+               }
+
+               // Check for undo tag
+               if ( $this->undidRevId !== 0 && in_array( 'mw-undo', ChangeTags::getSoftwareTags() ) ) {
+                       $tags[] = 'mw-undo';
+               }
+
+               return array_unique( $tags );
+       }
+
+       /**
+        * Returns the content of the given slot of the parent revision, with no audience checks applied.
+        * If there is no parent revision or the slot is not defined, this returns null.
+        *
+        * @param string $role slot role name
+        * @return Content|null
+        */
+       private function getParentContent( $role ) {
+               $parent = $this->grabParentRevision();
+
+               if ( $parent && $parent->hasSlot( $role ) ) {
+                       return $parent->getContent( $role, RevisionRecord::RAW );
+               }
+
+               return null;
+       }
+
+       /**
+        * @param string $role slot role name
+        * @return ContentHandler
+        */
+       private function getContentHandler( $role ) {
+               // TODO: inject something like a ContentHandlerRegistry
+               if ( $this->slotsUpdate->isModifiedSlot( $role ) ) {
+                       $slot = $this->slotsUpdate->getModifiedSlot( $role );
+               } else {
+                       $parent = $this->grabParentRevision();
+
+                       if ( $parent ) {
+                               $slot = $parent->getSlot( $role, RevisionRecord::RAW );
+                       } else {
+                               throw new RevisionAccessException( 'No such slot: ' . $role );
+                       }
+               }
+
+               return ContentHandler::getForModelID( $slot->getModel() );
+       }
+
+       /**
+        * @param int $flags Bit mask: a bit mask of EDIT_XXX flags.
+        *
+        * @return CommentStoreComment
+        */
+       private function makeAutoSummary( $flags ) {
+               if ( !$this->useAutomaticEditSummaries || ( $flags & EDIT_AUTOSUMMARY ) === 0 ) {
+                       return CommentStoreComment::newUnsavedComment( '' );
+               }
+
+               // NOTE: this generates an auto-summary for SOME RANDOM changed slot!
+               // TODO: combine auto-summaries for multiple slots!
+               // XXX: this logic should not be in the storage layer!
+               $roles = $this->slotsUpdate->getModifiedRoles();
+               $role = reset( $roles );
+
+               if ( $role === false ) {
+                       return CommentStoreComment::newUnsavedComment( '' );
+               }
+
+               $handler = $this->getContentHandler( $role );
+               $content = $this->slotsUpdate->getModifiedSlot( $role )->getContent();
+               $old_content = $this->getParentContent( $role );
+               $summary = $handler->getAutosummary( $old_content, $content, $flags );
+
+               return CommentStoreComment::newUnsavedComment( $summary );
+       }
+
+       /**
+        * Change an existing article or create a new article. Updates RC and all necessary caches,
+        * optionally via the deferred update array. This does not check user permissions.
+        *
+        * It is guaranteed that saveRevision() will fail if the current revision of the page
+        * changes after grabParentRevision() was called and before saveRevision() can insert
+        * a new revision, as per the CAS mechanism described above.
+        *
+        * The caller is however responsible for calling hasEditConflict() to detect a
+        * user-level edit conflict, and to adjust the content of the new revision accordingly,
+        * e.g. by using a 3-way-merge.
+        *
+        * MCR migration note: this replaces WikiPage::doEditContent. Callers that change to using
+        * saveRevision() now need to check the "minoredit" themselves before using EDIT_MINOR.
+        *
+        * @param CommentStoreComment $summary Edit summary
+        * @param int $flags Bitfield:
+        *      EDIT_NEW
+        *          Create a new page, or fail with "edit-already-exists" if the page exists.
+        *      EDIT_UPDATE
+        *          Create a new revision, or fail with "edit-gone-missing" if the page does not exist.
+        *      EDIT_MINOR
+        *          Mark this revision as minor
+        *      EDIT_SUPPRESS_RC
+        *          Do not log the change in recentchanges
+        *      EDIT_FORCE_BOT
+        *          Mark the revision as automated ("bot edit")
+        *      EDIT_AUTOSUMMARY
+        *          Fill in blank summaries with generated text where possible
+        *      EDIT_INTERNAL
+        *          Signal that the page retrieve/save cycle happened entirely in this request.
+        *
+        * If neither EDIT_NEW nor EDIT_UPDATE is specified, the expected state is detected
+        * automatically via grabParentRevision(). In this case, the "edit-already-exists" or
+        * "edit-gone-missing" errors may still be triggered due to race conditions, if the page
+        * was unexpectedly created or deleted while revision creation is in progress. This can be
+        * viewed as part of the CAS mechanism described above.
+        *
+        * @return RevisionRecord|null The new revision, or null if no new revision was created due
+        *         to a failure or a null-edit. Use isUnchanged(), wasSuccessful() and getStatus()
+        *         to determine the outcome of the revision creation.
+        *
+        * @throws MWException
+        * @throws RuntimeException
+        */
+       public function saveRevision( CommentStoreComment $summary, $flags = 0 ) {
+               // Defend against mistakes caused by differences with the
+               // signature of WikiPage::doEditContent.
+               Assert::parameterType( 'integer', $flags, '$flags' );
+
+               if ( $this->wasCommitted() ) {
+                       throw new RuntimeException( 'saveRevision() has already been called on this PageUpdater!' );
+               }
+
+               // Low-level sanity check
+               if ( $this->getLinkTarget()->getText() === '' ) {
+                       throw new RuntimeException( 'Something is trying to edit an article with an empty title' );
+               }
+
+               // TODO: MCR: check the role and the content's model against the list of supported
+               // and required roles, see T194046.
+
+               // Make sure the given content type is allowed for this page
+               // TODO: decide: Extend check to other slots? Consider the role in check? [PageType]
+               $mainContentHandler = $this->getContentHandler( 'main' );
+               if ( !$mainContentHandler->canBeUsedOn( $this->getTitle() ) ) {
+                       $this->status = Status::newFatal( 'content-not-allowed-here',
+                               ContentHandler::getLocalizedName( $mainContentHandler->getModelID() ),
+                               $this->getTitle()->getPrefixedText()
+                       );
+                       return null;
+               }
+
+               // Load the data from the master database if needed. Needed to check flags.
+               // NOTE: This grabs the parent revision as the CAS token, if grabParentRevision
+               // wasn't called yet. If the page is modified by another process before we are done with
+               // it, this method must fail (with status 'edit-conflict')!
+               // NOTE: The parent revision may be different from $this->originalRevisionId.
+               $this->grabParentRevision();
+               $flags = $this->checkFlags( $flags );
+
+               // Avoid statsd noise and wasted cycles check the edit stash (T136678)
+               if ( ( $flags & EDIT_INTERNAL ) || ( $flags & EDIT_FORCE_BOT ) ) {
+                       $useStashed = false;
+               } else {
+                       $useStashed = $this->ajaxEditStash;
+               }
+
+               // TODO: use this only for the legacy hook, and only if something uses the legacy hook
+               $wikiPage = $this->getWikiPage();
+
+               $user = $this->user;
+
+               // Prepare the update. This performs PST and generates the canonical ParserOutput.
+               $this->derivedDataUpdater->prepareContent(
+                       $this->user,
+                       $this->slotsUpdate,
+                       $useStashed
+               );
+
+               // TODO: don't force initialization here!
+               // This is a hack to work around the fact that late initialization of the ParserOutput
+               // causes ApiFlowEditHeaderTest::testCache to fail. Whether that failure indicates an
+               // actual problem, or is just an issue with the test setup, remains to be determined
+               // [dk, 2018-03].
+               // Anomie said in 2018-03:
+               /*
+                       I suspect that what's breaking is this:
+
+                       The old version of WikiPage::doEditContent() called prepareContentForEdit() which
+                       generated the ParserOutput right then, so when doEditUpdates() gets called from the
+                       DeferredUpdate scheduled by WikiPage::doCreate() there's no need to parse. I note
+                       there's a comment there that says "Get the pre-save transform content and final
+                       parser output".
+                       The new version of WikiPage::doEditContent() makes a PageUpdater and calls its
+                       saveRevision(), which calls DerivedPageDataUpdater::prepareContent() and
+                       PageUpdater::doCreate() without ever having to actually generate a ParserOutput.
+                       Thus, when DerivedPageDataUpdater::doUpdates() is called from the DeferredUpdate
+                       scheduled by PageUpdater::doCreate(), it does find that it needs to parse at that point.
+
+                       And the order of operations in that Flow test is presumably:
+
+                       - Create a page with a call to WikiPage::doEditContent(), in a way that somehow avoids
+                       processing the DeferredUpdate.
+                       - Set up the "no set!" mock cache in Flow\Tests\Api\ApiTestCase::expectCacheInvalidate()
+                       - Then, during the course of doing that test, a $db->commit() results in the
+                       DeferredUpdates being run.
+                */
+               $this->derivedDataUpdater->getCanonicalParserOutput();
+
+               $mainContent = $this->derivedDataUpdater->getSlots()->getContent( 'main' );
+
+               // Trigger pre-save hook (using provided edit summary)
+               $hookStatus = Status::newGood( [] );
+               // TODO: replace legacy hook!
+               // TODO: avoid pass-by-reference, see T193950
+               $hook_args = [ &$wikiPage, &$user, &$mainContent, &$summary,
+                       $flags & EDIT_MINOR, null, null, &$flags, &$hookStatus ];
+               // Check if the hook rejected the attempted save
+               if ( !Hooks::run( 'PageContentSave', $hook_args ) ) {
+                       if ( $hookStatus->isOK() ) {
+                               // Hook returned false but didn't call fatal(); use generic message
+                               $hookStatus->fatal( 'edit-hook-aborted' );
+                       }
+
+                       $this->status = $hookStatus;
+                       return null;
+               }
+
+               // Provide autosummaries if one is not provided and autosummaries are enabled
+               // XXX: $summary == null seems logical, but the empty string may actually come from the user
+               // XXX: Move this logic out of the storage layer! It does not belong here! Use a callback?
+               if ( $summary->text === '' && $summary->data === null ) {
+                       $summary = $this->makeAutoSummary( $flags );
+               }
+
+               // Actually create the revision and create/update the page.
+               // Do NOT yet set $this->status!
+               if ( $flags & EDIT_UPDATE ) {
+                       $status = $this->doModify( $summary, $this->user, $flags );
+               } else {
+                       $status = $this->doCreate( $summary, $this->user, $flags );
+               }
+
+               // Promote user to any groups they meet the criteria for
+               DeferredUpdates::addCallableUpdate( function () use ( $user ) {
+                       $user->addAutopromoteOnceGroups( 'onEdit' );
+                       $user->addAutopromoteOnceGroups( 'onView' ); // b/c
+               } );
+
+               // NOTE: set $this->status only after all hooks have been called,
+               // so wasCommitted doesn't return true wehn called indirectly from a hook handler!
+               $this->status = $status;
+
+               // TODO: replace bad status with Exceptions!
+               return ( $this->status && $this->status->isOK() )
+                       ? $this->status->value['revision-record']
+                       : null;
+       }
+
+       /**
+        * Whether saveRevision() has been called on this instance
+        *
+        * @return bool
+        */
+       public function wasCommitted() {
+               return $this->status !== null;
+       }
+
+       /**
+        * The Status object indicating whether saveRevision() was successful, or null if
+        * saveRevision() was not yet called on this instance.
+        *
+        * @note This is here for compatibility with WikiPage::doEditContent. It may be deprecated
+        * soon.
+        *
+        * Possible status errors:
+        *     edit-hook-aborted: The ArticleSave hook aborted the update but didn't
+        *       set the fatal flag of $status.
+        *     edit-gone-missing: In update mode, but the article didn't exist.
+        *     edit-conflict: In update mode, the article changed unexpectedly.
+        *     edit-no-change: Warning that the text was the same as before.
+        *     edit-already-exists: In creation mode, but the article already exists.
+        *
+        *  Extensions may define additional errors.
+        *
+        *  $return->value will contain an associative array with members as follows:
+        *     new: Boolean indicating if the function attempted to create a new article.
+        *     revision: The revision object for the inserted revision, or null.
+        *
+        * @return null|Status
+        */
+       public function getStatus() {
+               return $this->status;
+       }
+
+       /**
+        * Whether saveRevision() completed successfully
+        *
+        * @return bool
+        */
+       public function wasSuccessful() {
+               return $this->status && $this->status->isOK();
+       }
+
+       /**
+        * Whether saveRevision() was called and created a new page.
+        *
+        * @return bool
+        */
+       public function isNew() {
+               return $this->status && $this->status->isOK() && $this->status->value['new'];
+       }
+
+       /**
+        * Whether saveRevision() did not create a revision because the content didn't change
+        * (null-edit). Whether the content changed or not is determined by
+        * DerivedPageDataUpdater::isChange().
+        *
+        * @return bool
+        */
+       public function isUnchanged() {
+               return $this->status
+                       && $this->status->isOK()
+                       && $this->status->value['revision-record'] === null;
+       }
+
+       /**
+        * The new revision created by saveRevision(), or null if saveRevision() has not yet been
+        * called, failed, or did not create a new revision because the content did not change.
+        *
+        * @return RevisionRecord|null
+        */
+       public function getNewRevision() {
+               return ( $this->status && $this->status->isOK() )
+                       ? $this->status->value['revision-record']
+                       : null;
+       }
+
+       /**
+        * Constructs a MutableRevisionRecord based on the Content prepared by the
+        * DerivedPageDataUpdater. This takes care of inheriting slots, updating slots
+        * with PST applied, and removing discontinued slots.
+        *
+        * This calls Content::prepareSave() to verify that the slot content can be saved.
+        * The $status parameter is updated with any errors or warnings found by Content::prepareSave().
+        *
+        * @param CommentStoreComment $comment
+        * @param User $user
+        * @param string $timestamp
+        * @param int $flags
+        * @param Status $status
+        *
+        * @return MutableRevisionRecord
+        */
+       private function makeNewRevision(
+               CommentStoreComment $comment,
+               User $user,
+               $timestamp,
+               $flags,
+               Status $status
+       ) {
+               $wikiPage = $this->getWikiPage();
+               $title = $this->getTitle();
+               $parent = $this->grabParentRevision();
+
+               $rev = new MutableRevisionRecord( $title, $this->getWikiId() );
+               $rev->setPageId( $title->getArticleID() );
+
+               if ( $parent ) {
+                       $oldid = $parent->getId();
+                       $rev->setParentId( $oldid );
+               } else {
+                       $oldid = 0;
+               }
+
+               $rev->setComment( $comment );
+               $rev->setUser( $user );
+               $rev->setTimestamp( $timestamp );
+               $rev->setMinorEdit( ( $flags & EDIT_MINOR ) > 0 );
+
+               foreach ( $this->derivedDataUpdater->getSlots()->getSlots() as $slot ) {
+                       $content = $slot->getContent();
+
+                       // XXX: We may push this up to the "edit controller" level, see T192777.
+                       // TODO: change the signature of PrepareSave to not take a WikiPage!
+                       $prepStatus = $content->prepareSave( $wikiPage, $flags, $oldid, $user );
+
+                       if ( $prepStatus->isOK() ) {
+                               $rev->setSlot( $slot );
+                       }
+
+                       // TODO: MCR: record which problem arose in which slot.
+                       $status->merge( $prepStatus );
+               }
+
+               return $rev;
+       }
+
+       /**
+        * @param CommentStoreComment $summary The edit summary
+        * @param User $user The revision's author
+        * @param int $flags EXIT_XXX constants
+        *
+        * @throws MWException
+        * @return Status
+        */
+       private function doModify( CommentStoreComment $summary, User $user, $flags ) {
+               $wikiPage = $this->getWikiPage(); // TODO: use for legacy hooks only!
+
+               // Update article, but only if changed.
+               $status = Status::newGood( [ 'new' => false, 'revision' => null, 'revision-record' => null ] );
+
+               // Convenience variables
+               $now = $this->getTimestampNow();
+
+               $oldRev = $this->grabParentRevision();
+               $oldid = $oldRev ? $oldRev->getId() : 0;
+
+               if ( !$oldRev ) {
+                       // Article gone missing
+                       $status->fatal( 'edit-gone-missing' );
+
+                       return $status;
+               }
+
+               $newRevisionRecord = $this->makeNewRevision(
+                       $summary,
+                       $user,
+                       $now,
+                       $flags,
+                       $status
+               );
+
+               if ( !$status->isOK() ) {
+                       return $status;
+               }
+
+               // XXX: we may want a flag that allows a null revision to be forced!
+               $changed = $this->derivedDataUpdater->isChange();
+
+               $dbw = $this->getDBConnectionRef( DB_MASTER );
+
+               if ( $changed ) {
+                       $dbw->startAtomic( __METHOD__ );
+
+                       // Get the latest page_latest value while locking it.
+                       // Do a CAS style check to see if it's the same as when this method
+                       // started. If it changed then bail out before touching the DB.
+                       $latestNow = $wikiPage->lockAndGetLatest(); // TODO: move to storage service, pass DB
+                       if ( $latestNow != $oldid ) {
+                               // We don't need to roll back, since we did not modify the database yet.
+                               // XXX: Or do we want to rollback, any transaction started by calling
+                               // code will fail? If we want that, we should probably throw an exception.
+                               $dbw->endAtomic( __METHOD__ );
+                               // Page updated or deleted in the mean time
+                               $status->fatal( 'edit-conflict' );
+
+                               return $status;
+                       }
+
+                       // At this point we are now comitted to returning an OK
+                       // status unless some DB query error or other exception comes up.
+                       // This way callers don't have to call rollback() if $status is bad
+                       // unless they actually try to catch exceptions (which is rare).
+
+                       // Save revision content and meta-data
+                       $newRevisionRecord = $this->revisionStore->insertRevisionOn( $newRevisionRecord, $dbw );
+                       $newLegacyRevision = new Revision( $newRevisionRecord );
+
+                       // Update page_latest and friends to reflect the new revision
+                       // TODO: move to storage service
+                       $wasRedirect = $this->derivedDataUpdater->wasRedirect();
+                       if ( !$wikiPage->updateRevisionOn( $dbw, $newLegacyRevision, null, $wasRedirect ) ) {
+                               throw new PageUpdateException( "Failed to update page row to use new revision." );
+                       }
+
+                       // TODO: replace legacy hook!
+                       $tags = $this->computeEffectiveTags( $flags );
+                       Hooks::run(
+                               'NewRevisionFromEditComplete',
+                               [ $wikiPage, $newLegacyRevision, $this->getOriginalRevisionId(), $user, &$tags ]
+                       );
+
+                       // Update recentchanges
+                       if ( !( $flags & EDIT_SUPPRESS_RC ) ) {
+                               // Add RC row to the DB
+                               RecentChange::notifyEdit(
+                                       $now,
+                                       $this->getTitle(),
+                                       $newRevisionRecord->isMinor(),
+                                       $user,
+                                       $summary->text, // TODO: pass object when that becomes possible
+                                       $oldid,
+                                       $newRevisionRecord->getTimestamp(),
+                                       ( $flags & EDIT_FORCE_BOT ) > 0,
+                                       '',
+                                       $oldRev->getSize(),
+                                       $newRevisionRecord->getSize(),
+                                       $newRevisionRecord->getId(),
+                                       $this->rcPatrolStatus,
+                                       $tags
+                               );
+                       }
+
+                       $user->incEditCount();
+
+                       $dbw->endAtomic( __METHOD__ );
+
+                       // Return the new revision to the caller
+                       $status->value['revision-record'] = $newRevisionRecord;
+
+                       // TODO: globally replace usages of 'revision' with getNewRevision()
+                       $status->value['revision'] = $newLegacyRevision;
+               } else {
+                       // T34948: revision ID must be set to page {{REVISIONID}} and
+                       // related variables correctly. Likewise for {{REVISIONUSER}} (T135261).
+                       // Since we don't insert a new revision into the database, the least
+                       // error-prone way is to reuse given old revision.
+                       $newRevisionRecord = $oldRev;
+
+                       $status->warning( 'edit-no-change' );
+                       // Update page_touched as updateRevisionOn() was not called.
+                       // Other cache updates are managed in WikiPage::onArticleEdit()
+                       // via WikiPage::doEditUpdates().
+                       $this->getTitle()->invalidateCache( $now );
+               }
+
+               // Do secondary updates once the main changes have been committed...
+               // NOTE: the updates have to be processed before sending the response to the client
+               // (DeferredUpdates::PRESEND), otherwise the client may already be following the
+               // HTTP redirect to the standard view before dervide data has been created - most
+               // importantly, before the parser cache has been updated. This would cause the
+               // content to be parsed a second time, or may cause stale content to be shown.
+               DeferredUpdates::addUpdate(
+                       $this->getAtomicSectionUpdate(
+                               $dbw,
+                               $wikiPage,
+                               $newRevisionRecord,
+                               $user,
+                               $summary,
+                               $flags,
+                               $status,
+                               [ 'changed' => $changed, ]
+                       ),
+                       DeferredUpdates::PRESEND
+               );
+
+               return $status;
+       }
+
+       /**
+        * @param CommentStoreComment $summary The edit summary
+        * @param User $user The revision's author
+        * @param int $flags EXIT_XXX constants
+        *
+        * @throws DBUnexpectedError
+        * @throws MWException
+        * @return Status
+        */
+       private function doCreate( CommentStoreComment $summary, User $user, $flags ) {
+               $wikiPage = $this->getWikiPage(); // TODO: use for legacy hooks only!
+
+               if ( !$this->derivedDataUpdater->getSlots()->hasSlot( 'main' ) ) {
+                       throw new PageUpdateException( 'Must provide a main slot when creating a page!' );
+               }
+
+               $status = Status::newGood( [ 'new' => true, 'revision' => null, 'revision-record' => null ] );
+
+               $now = $this->getTimestampNow();
+
+               $newRevisionRecord = $this->makeNewRevision(
+                       $summary,
+                       $user,
+                       $now,
+                       $flags,
+                       $status
+               );
+
+               if ( !$status->isOK() ) {
+                       return $status;
+               }
+
+               $dbw = $this->getDBConnectionRef( DB_MASTER );
+               $dbw->startAtomic( __METHOD__ );
+
+               // Add the page record unless one already exists for the title
+               // TODO: move to storage service
+               $newid = $wikiPage->insertOn( $dbw );
+               if ( $newid === false ) {
+                       $dbw->endAtomic( __METHOD__ ); // nothing inserted
+                       $status->fatal( 'edit-already-exists' );
+
+                       return $status; // nothing done
+               }
+
+               // At this point we are now comitted to returning an OK
+               // status unless some DB query error or other exception comes up.
+               // This way callers don't have to call rollback() if $status is bad
+               // unless they actually try to catch exceptions (which is rare).
+               $newRevisionRecord->setPageId( $newid );
+
+               // Save the revision text...
+               $newRevisionRecord = $this->revisionStore->insertRevisionOn( $newRevisionRecord, $dbw );
+               $newLegacyRevision = new Revision( $newRevisionRecord );
+
+               // Update the page record with revision data
+               // TODO: move to storage service
+               if ( !$wikiPage->updateRevisionOn( $dbw, $newLegacyRevision, 0 ) ) {
+                       throw new PageUpdateException( "Failed to update page row to use new revision." );
+               }
+
+               // TODO: replace legacy hook!
+               $tags = $this->computeEffectiveTags( $flags );
+               Hooks::run(
+                       'NewRevisionFromEditComplete',
+                       [ $wikiPage, $newLegacyRevision, false, $user, &$tags ]
+               );
+
+               // Update recentchanges
+               if ( !( $flags & EDIT_SUPPRESS_RC ) ) {
+                       // Add RC row to the DB
+                       RecentChange::notifyNew(
+                               $now,
+                               $this->getTitle(),
+                               $newRevisionRecord->isMinor(),
+                               $user,
+                               $summary->text, // TODO: pass object when that becomes possible
+                               ( $flags & EDIT_FORCE_BOT ) > 0,
+                               '',
+                               $newRevisionRecord->getSize(),
+                               $newRevisionRecord->getId(),
+                               $this->rcPatrolStatus,
+                               $tags
+                       );
+               }
+
+               $user->incEditCount();
+
+               if ( $this->usePageCreationLog ) {
+                       // Log the page creation
+                       // @TODO: Do we want a 'recreate' action?
+                       $logEntry = new ManualLogEntry( 'create', 'create' );
+                       $logEntry->setPerformer( $user );
+                       $logEntry->setTarget( $this->getTitle() );
+                       $logEntry->setComment( $summary->text );
+                       $logEntry->setTimestamp( $now );
+                       $logEntry->setAssociatedRevId( $newRevisionRecord->getId() );
+                       $logEntry->insert();
+                       // Note that we don't publish page creation events to recentchanges
+                       // (i.e. $logEntry->publish()) since this would create duplicate entries,
+                       // one for the edit and one for the page creation.
+               }
+
+               $dbw->endAtomic( __METHOD__ );
+
+               // Return the new revision to the caller
+               // TODO: globally replace usages of 'revision' with getNewRevision()
+               $status->value['revision'] = $newLegacyRevision;
+               $status->value['revision-record'] = $newRevisionRecord;
+
+               // Do secondary updates once the main changes have been committed...
+               DeferredUpdates::addUpdate(
+                       $this->getAtomicSectionUpdate(
+                               $dbw,
+                               $wikiPage,
+                               $newRevisionRecord,
+                               $user,
+                               $summary,
+                               $flags,
+                               $status,
+                               [ 'created' => true ]
+                       ),
+                       DeferredUpdates::PRESEND
+               );
+
+               return $status;
+       }
+
+       private function getAtomicSectionUpdate(
+               IDatabase $dbw,
+               WikiPage $wikiPage,
+               RevisionRecord $newRevisionRecord,
+               User $user,
+               CommentStoreComment $summary,
+               $flags,
+               Status $status,
+               $hints = []
+       ) {
+               return new AtomicSectionUpdate(
+                       $dbw,
+                       __METHOD__,
+                       function () use (
+                               $wikiPage, $newRevisionRecord, $user,
+                               $summary, $flags, $status, $hints
+                       ) {
+                               $newLegacyRevision = new Revision( $newRevisionRecord );
+                               $mainContent = $newRevisionRecord->getContent( 'main', RevisionRecord::RAW );
+
+                               // Update links tables, site stats, etc.
+                               $this->derivedDataUpdater->prepareUpdate( $newRevisionRecord, $hints );
+                               $this->derivedDataUpdater->doUpdates();
+
+                               // TODO: replace legacy hook!
+                               // TODO: avoid pass-by-reference, see T193950
+
+                               if ( $hints['created'] ?? false ) {
+                                       // Trigger post-create hook
+                                       $params = [ &$wikiPage, &$user, $mainContent, $summary->text,
+                                               $flags & EDIT_MINOR, null, null, &$flags, $newLegacyRevision ];
+                                       Hooks::run( 'PageContentInsertComplete', $params );
+                               }
+
+                               // Trigger post-save hook
+                               $params = [ &$wikiPage, &$user, $mainContent, $summary->text,
+                                               $flags & EDIT_MINOR, null, null, &$flags, $newLegacyRevision,
+                                               &$status, $this->getOriginalRevisionId(), $this->undidRevId ];
+                               Hooks::run( 'PageContentSaveComplete', $params );
+                       }
+               );
+       }
+
+}
index 86e8c06..2c45468 100644 (file)
@@ -77,7 +77,7 @@ interface RevisionFactory {
         *        Use RevisionStore::getArchiveQueryInfo() to build a query that yields the
         *        required fields.
         * @param int $queryFlags Flags for lazy loading behavior, see IDBAccessObject::READ_XXX.
-        * @param Title $title
+        * @param Title|null $title
         * @param array $overrides An associative array that allows fields in $row to be overwritten.
         *        Keys in this array correspond to field names in $row without the "ar_" prefix, so
         *        $overrides['user'] will override $row->ar_user, etc.
index 45cd184..a6e2930 100644 (file)
@@ -84,7 +84,7 @@ interface RevisionLookup extends IDBAccessObject {
         * MCR migration note: this replaces Revision::getPrevious
         *
         * @param RevisionRecord $rev
-        * @param Title $title if known (optional)
+        * @param Title|null $title if known (optional)
         *
         * @return RevisionRecord|null
         */
@@ -96,7 +96,7 @@ interface RevisionLookup extends IDBAccessObject {
         * MCR migration note: this replaces Revision::getNext
         *
         * @param RevisionRecord $rev
-        * @param Title $title if known (optional)
+        * @param Title|null $title if known (optional)
         *
         * @return RevisionRecord|null
         */
index 6d83e1c..17c56ea 100644 (file)
@@ -48,8 +48,9 @@ abstract class RevisionRecord {
        const DELETED_COMMENT = 2;
        const DELETED_USER = 4;
        const DELETED_RESTRICTED = 8;
-       const SUPPRESSED_USER = 12; // convenience
-       const SUPPRESSED_ALL = 15; // convenience
+       const SUPPRESSED_USER = self::DELETED_USER | self::DELETED_RESTRICTED; // convenience
+       const SUPPRESSED_ALL = self::DELETED_TEXT | self::DELETED_COMMENT | self::DELETED_USER |
+               self::DELETED_RESTRICTED; // convenience
 
        // Audience options for accessors
        const FOR_PUBLIC = 1;
@@ -217,6 +218,48 @@ abstract class RevisionRecord {
                return $this->mSlots->getSlotRoles();
        }
 
+       /**
+        * Returns the slots defined for this revision.
+        *
+        * @return RevisionSlots
+        */
+       public function getSlots() {
+               return $this->mSlots;
+       }
+
+       /**
+        * Returns the slots that originate in this revision.
+        *
+        * Note that this does not include any slots inherited from some earlier revision,
+        * even if they are different from the slots in the immediate parent revision.
+        * This is the case for rollbacks: slots of a rollback revision are inherited from
+        * the rollback target, and are different from the slots in the parent revision,
+        * which was rolled back.
+        *
+        * To find all slots modified by this revision against its immediate parent
+        * revision, use RevisionSlotsUpdate::newFromRevisionSlots().
+        *
+        * @return RevisionSlots
+        */
+       public function getOriginalSlots() {
+               return new RevisionSlots( $this->mSlots->getOriginalSlots() );
+       }
+
+       /**
+        * Returns slots inherited from some previous revision.
+        *
+        * "Inherited" slots are all slots that do not originate in this revision.
+        * Note that these slots may still differ from the one in the parent revision.
+        * This is the case for rollbacks: slots of a rollback revision are inherited from
+        * the rollback target, and are different from the slots in the parent revision,
+        * which was rolled back.
+        *
+        * @return RevisionSlots
+        */
+       public function getInheritedSlots() {
+               return new RevisionSlots( $this->mSlots->getInheritedSlots() );
+       }
+
        /**
         * Get revision ID. Depending on the concrete subclass, this may return null if
         * the revision ID is not known (e.g. because the revision does not yet exist
@@ -410,7 +453,7 @@ abstract class RevisionRecord {
         *
         * @return bool
         */
-       protected function audienceCan( $field, $audience, User $user = null ) {
+       public function audienceCan( $field, $audience, User $user = null ) {
                if ( $audience == self::FOR_PUBLIC && $this->isDeleted( $field ) ) {
                        return false;
                } elseif ( $audience == self::FOR_THIS_USER ) {
@@ -473,7 +516,7 @@ abstract class RevisionRecord {
                        $permissionlist = implode( ', ', $permissions );
                        if ( $title === null ) {
                                wfDebug( "Checking for $permissionlist due to $field match on $bitfield\n" );
-                               return call_user_func_array( [ $user, 'isAllowedAny' ], $permissions );
+                               return $user->isAllowedAny( ...$permissions );
                        } else {
                                $text = $title->getPrefixedText();
                                wfDebug( "Checking for $permissionlist on $text due to $field match on $bitfield\n" );
index c7dcd13..91969fc 100644 (file)
@@ -139,7 +139,7 @@ class RevisionSlots {
        /**
         * Computes the total nominal size of the revision's slots, in bogo-bytes.
         *
-        * @warn This is potentially expensive! It may cause all slot's content to be loaded
+        * @warning This is potentially expensive! It may cause all slot's content to be loaded
         * and deserialized.
         *
         * @return int
@@ -181,7 +181,7 @@ class RevisionSlots {
         * is that slot's hash. For consistency, the combined hash of an empty set of slots
         * is the hash of the empty string.
         *
-        * @warn This is potentially expensive! It may cause all slot's content to be loaded
+        * @warning This is potentially expensive! It may cause all slot's content to be loaded
         * and deserialized, then re-serialized and hashed.
         *
         * @return string
@@ -202,13 +202,14 @@ class RevisionSlots {
        }
 
        /**
-        * Return all slots that are not inherited.
+        * Return all slots that belong to the revision they originate from (that is,
+        * they are not inherited from some other revision).
         *
         * @note This may cause the slot meta-data for the revision to be lazy-loaded.
         *
         * @return SlotRecord[]
         */
-       public function getTouchedSlots() {
+       public function getOriginalSlots() {
                return array_filter(
                        $this->getSlots(),
                        function ( SlotRecord $slot ) {
@@ -218,7 +219,8 @@ class RevisionSlots {
        }
 
        /**
-        * Return all slots that are inherited.
+        * Return all slots that are not not originate in the revision they belong to (that is,
+        * they are inherited from some other revision).
         *
         * @note This may cause the slot meta-data for the revision to be lazy-loaded.
         *
@@ -268,4 +270,43 @@ class RevisionSlots {
                return true;
        }
 
+       /**
+        * Find roles for which the $other RevisionSlots object has different content
+        * as this RevisionSlots object, including any roles that are present in one
+        * but not the other.
+        *
+        * @param RevisionSlots $other
+        *
+        * @return string[] a list of slot roles that are different.
+        */
+       public function getRolesWithDifferentContent( RevisionSlots $other ) {
+               if ( $other === $this ) {
+                       return [];
+               }
+
+               $aSlots = $this->getSlots();
+               $bSlots = $other->getSlots();
+
+               ksort( $aSlots );
+               ksort( $bSlots );
+
+               $different = array_keys( array_merge(
+                       array_diff_key( $aSlots, $bSlots ),
+                       array_diff_key( $bSlots, $aSlots )
+               ) );
+
+               /** @var SlotRecord[] $common */
+               $common = array_intersect_key( $aSlots, $bSlots );
+
+               foreach ( $common as $role => $s ) {
+                       $t = $bSlots[$role];
+
+                       if ( !$s->hasSameContent( $t ) ) {
+                               $different[] = $role;
+                       }
+               }
+
+               return $different;
+       }
+
 }
index 0eef90f..d173a3c 100644 (file)
@@ -72,6 +72,39 @@ class RevisionSlotsUpdate {
                return new RevisionSlotsUpdate( $modified, $removed );
        }
 
+       /**
+        * Constructs a RevisionSlotsUpdate representing the update of $parentSlots
+        * when changing $newContent. If a slot has the same content in $newContent
+        * as in $parentSlots, that slot is considered inherited and thus omitted from
+        * the resulting RevisionSlotsUpdate.
+        *
+        * In contrast to newFromRevisionSlots(), slots in $parentSlots that are not present
+        * in $newContent are not considered removed. They are instead assumed to be inherited.
+        *
+        * @param Content[] $newContent The new content, using slot roles as array keys.
+        *
+        * @return RevisionSlotsUpdate
+        */
+       public static function newFromContent( array $newContent, RevisionSlots $parentSlots = null ) {
+               $modified = [];
+
+               foreach ( $newContent as $role => $content ) {
+                       $slot = SlotRecord::newUnsaved( $role, $content );
+
+                       if ( $parentSlots
+                               && $parentSlots->hasSlot( $role )
+                               && $slot->hasSameContent( $parentSlots->getSlot( $role ) )
+                       ) {
+                               // Skip slots that had the same content in the parent revision from $modified.
+                               continue;
+                       }
+
+                       $modified[$role] = $slot;
+               }
+
+               return new RevisionSlotsUpdate( $modified );
+       }
+
        /**
         * @param SlotRecord[] $modifiedSlots
         * @param string[] $removedRoles
@@ -90,6 +123,11 @@ class RevisionSlotsUpdate {
         * Returns a list of modified slot roles, that is, roles modified by calling modifySlot(),
         * and not later removed by calling removeSlot().
         *
+        * Note that slots in modified roles may still be inherited slots. This is for instance
+        * the case when the RevisionSlotsUpdate objects represents some kind of rollback
+        * operation, in which slots that existed in an earlier revision are restored in
+        * a new revision.
+        *
         * @return string[]
         */
        public function getModifiedRoles() {
@@ -239,4 +277,20 @@ class RevisionSlotsUpdate {
                return true;
        }
 
+       /**
+        * Applies this update to the given MutableRevisionSlots, setting all modified slots,
+        * and removing all removed roles.
+        *
+        * @param MutableRevisionSlots $slots
+        */
+       public function apply( MutableRevisionSlots $slots ) {
+               foreach ( $this->getModifiedRoles() as $role ) {
+                       $slots->setSlot( $this->getModifiedSlot( $role ) );
+               }
+
+               foreach ( $this->getRemovedRoles() as $role ) {
+                       $slots->removeSlot( $role );
+               }
+       }
+
 }
index 5b3daf4..d090d8b 100644 (file)
@@ -47,6 +47,7 @@ use Psr\Log\LoggerAwareInterface;
 use Psr\Log\LoggerInterface;
 use Psr\Log\NullLogger;
 use RecentChange;
+use Revision;
 use stdClass;
 use Title;
 use User;
@@ -68,6 +69,8 @@ use Wikimedia\Rdbms\LoadBalancer;
 class RevisionStore
        implements IDBAccessObject, RevisionFactory, RevisionLookup, LoggerAwareInterface {
 
+       const ROW_CACHE_KEY = 'revision-row-1.29';
+
        /**
         * @var SqlBlobStore
         */
@@ -80,6 +83,7 @@ class RevisionStore
 
        /**
         * @var boolean
+        * @see $wgContentHandlerUseDB
         */
        private $contentHandlerUseDB = true;
 
@@ -108,6 +112,19 @@ class RevisionStore
         */
        private $logger;
 
+       /**
+        * @var NameTableStore
+        */
+       private $contentModelStore;
+
+       /**
+        * @var NameTableStore
+        */
+       private $slotRoleStore;
+
+       /** @var int An appropriate combination of SCHEMA_COMPAT_XXX flags. */
+       private $mcrMigrationStage;
+
        /**
         * @todo $blobStore should be allowed to be any BlobStore!
         *
@@ -115,28 +132,76 @@ class RevisionStore
         * @param SqlBlobStore $blobStore
         * @param WANObjectCache $cache
         * @param CommentStore $commentStore
+        * @param NameTableStore $contentModelStore
+        * @param NameTableStore $slotRoleStore
+        * @param int $mcrMigrationStage An appropriate combination of SCHEMA_COMPAT_XXX flags
         * @param ActorMigration $actorMigration
         * @param bool|string $wikiId
+        *
+        * @throws MWException if $mcrMigrationStage or $wikiId is invalid.
         */
        public function __construct(
                LoadBalancer $loadBalancer,
                SqlBlobStore $blobStore,
                WANObjectCache $cache,
                CommentStore $commentStore,
+               NameTableStore $contentModelStore,
+               NameTableStore $slotRoleStore,
+               $mcrMigrationStage,
                ActorMigration $actorMigration,
                $wikiId = false
        ) {
                Assert::parameterType( 'string|boolean', $wikiId, '$wikiId' );
+               Assert::parameterType( 'integer', $mcrMigrationStage, '$mcrMigrationStage' );
+               Assert::parameter(
+                       ( $mcrMigrationStage & SCHEMA_COMPAT_READ_BOTH ) !== SCHEMA_COMPAT_READ_BOTH,
+                       '$mcrMigrationStage',
+                       'Reading from the old and the new schema at the same time is not supported.'
+               );
+               Assert::parameter(
+                       ( $mcrMigrationStage & SCHEMA_COMPAT_READ_BOTH ) !== 0,
+                       '$mcrMigrationStage',
+                       'Reading needs to be enabled for the old or the new schema.'
+               );
+               Assert::parameter(
+                       ( $mcrMigrationStage & SCHEMA_COMPAT_WRITE_BOTH ) !== 0,
+                       '$mcrMigrationStage',
+                       'Writing needs to be enabled for the old or the new schema.'
+               );
+               Assert::parameter(
+                       ( $mcrMigrationStage & SCHEMA_COMPAT_READ_OLD ) === 0
+                       || ( $mcrMigrationStage & SCHEMA_COMPAT_WRITE_OLD ) !== 0,
+                       '$mcrMigrationStage',
+                       'Cannot read the old schema when not also writing it.'
+               );
+               Assert::parameter(
+                       ( $mcrMigrationStage & SCHEMA_COMPAT_READ_NEW ) === 0
+                       || ( $mcrMigrationStage & SCHEMA_COMPAT_WRITE_NEW ) !== 0,
+                       '$mcrMigrationStage',
+                       'Cannot read the new schema when not also writing it.'
+               );
 
                $this->loadBalancer = $loadBalancer;
                $this->blobStore = $blobStore;
                $this->cache = $cache;
                $this->commentStore = $commentStore;
+               $this->contentModelStore = $contentModelStore;
+               $this->slotRoleStore = $slotRoleStore;
+               $this->mcrMigrationStage = $mcrMigrationStage;
                $this->actorMigration = $actorMigration;
                $this->wikiId = $wikiId;
                $this->logger = new NullLogger();
        }
 
+       /**
+        * @param int $flags A combination of SCHEMA_COMPAT_XXX flags.
+        * @return bool True if all the given flags were set in the $mcrMigrationStage
+        *         parameter passed to the constructor.
+        */
+       private function hasMcrSchemaFlags( $flags ) {
+               return ( $this->mcrMigrationStage & $flags ) === $flags;
+       }
+
        public function setLogger( LoggerInterface $logger ) {
                $this->logger = $logger;
        }
@@ -156,9 +221,20 @@ class RevisionStore
        }
 
        /**
+        * @see $wgContentHandlerUseDB
         * @param bool $contentHandlerUseDB
+        * @throws MWException
         */
        public function setContentHandlerUseDB( $contentHandlerUseDB ) {
+               if ( $this->hasMcrSchemaFlags( SCHEMA_COMPAT_WRITE_NEW )
+                       || $this->hasMcrSchemaFlags( SCHEMA_COMPAT_READ_NEW )
+               ) {
+                       if ( !$contentHandlerUseDB ) {
+                               throw new MWException(
+                                       'Content model must be stored in the database for multi content revision migration.'
+                               );
+                       }
+               }
                $this->contentHandlerUseDB = $contentHandlerUseDB;
        }
 
@@ -179,6 +255,16 @@ class RevisionStore
                return $lb->getConnection( $mode, [], $this->wikiId );
        }
 
+       /**
+        * @param int $queryFlags a bit field composed of READ_XXX flags
+        *
+        * @return DBConnRef
+        */
+       private function getDBConnectionRefForQueryFlags( $queryFlags ) {
+               list( $mode, ) = DBAccessObjectUtils::getDBOptions( $queryFlags );
+               return $this->getDBConnectionRef( $mode );
+       }
+
        /**
         * @param IDatabase $connection
         */
@@ -329,14 +415,38 @@ class RevisionStore
                // TODO: pass in a DBTransactionContext instead of a database connection.
                $this->checkDatabaseWikiId( $dbw );
 
-               if ( !$rev->getSlotRoles() ) {
-                       throw new InvalidArgumentException( 'At least one slot needs to be defined!' );
+               $slotRoles = $rev->getSlotRoles();
+
+               // Make sure the main slot is always provided throughout migration
+               if ( !in_array( 'main', $slotRoles ) ) {
+                       throw new InvalidArgumentException(
+                               'main slot must be provided'
+                       );
                }
 
-               if ( $rev->getSlotRoles() !== [ 'main' ] ) {
-                       throw new InvalidArgumentException( 'Only the main slot is supported for now!' );
+               // If we are not writing into the new schema, we can't support extra slots.
+               if ( !$this->hasMcrSchemaFlags( SCHEMA_COMPAT_WRITE_NEW ) && $slotRoles !== [ 'main' ] ) {
+                       throw new InvalidArgumentException(
+                               'Only the main slot is supported when not writing to the MCR enabled schema!'
+                       );
                }
 
+               // As long as we are not reading from the new schema, we don't want to write extra slots.
+               if ( !$this->hasMcrSchemaFlags( SCHEMA_COMPAT_READ_NEW ) && $slotRoles !== [ 'main' ] ) {
+                       throw new InvalidArgumentException(
+                               'Only the main slot is supported when not reading from the MCR enabled schema!'
+                       );
+               }
+
+               // Checks
+               $this->failOnNull( $rev->getSize(), 'size field' );
+               $this->failOnEmpty( $rev->getSha1(), 'sha1 field' );
+               $this->failOnEmpty( $rev->getTimestamp(), 'timestamp field' );
+               $comment = $this->failOnNull( $rev->getComment( RevisionRecord::RAW ), 'comment' );
+               $user = $this->failOnNull( $rev->getUser( RevisionRecord::RAW ), 'user' );
+               $this->failOnNull( $user->getId(), 'user field' );
+               $this->failOnEmpty( $user->getName(), 'user_text field' );
+
                // TODO: we shouldn't need an actual Title here.
                $title = Title::newFromLinkTarget( $rev->getPageAsLinkTarget() );
                $pageId = $this->failOnEmpty( $rev->getPageId(), 'rev_page field' ); // check this early
@@ -345,44 +455,147 @@ class RevisionStore
                        ? $this->getPreviousRevisionId( $dbw, $rev )
                        : $rev->getParentId();
 
-               // Record the text (or external storage URL) to the blob store
-               $slot = $rev->getSlot( 'main', RevisionRecord::RAW );
-
-               $size = $this->failOnNull( $rev->getSize(), 'size field' );
-               $sha1 = $this->failOnEmpty( $rev->getSha1(), 'sha1 field' );
-
-               if ( !$slot->hasAddress() ) {
-                       $content = $slot->getContent();
-                       $format = $content->getDefaultFormat();
-                       $model = $content->getModel();
-
-                       $this->checkContentModel( $content, $title );
-
-                       $data = $content->serialize( $format );
-
-                       // Hints allow the blob store to optimize by "leaking" application level information to it.
-                       // TODO: with the new MCR storage schema, we rev_id have this before storing the blobs.
-                       // When we have it, add rev_id as a hint. Can be used with rev_parent_id for
-                       // differential storage or compression of subsequent revisions.
-                       $blobHints = [
-                               BlobStore::DESIGNATION_HINT => 'page-content', // BlobStore may be used for other things too.
-                               BlobStore::PAGE_HINT => $pageId,
-                               BlobStore::ROLE_HINT => $slot->getRole(),
-                               BlobStore::PARENT_HINT => $parentId,
-                               BlobStore::SHA1_HINT => $slot->getSha1(),
-                               BlobStore::MODEL_HINT => $model,
-                               BlobStore::FORMAT_HINT => $format,
-                       ];
+               /** @var RevisionRecord $rev */
+               $rev = $dbw->doAtomicSection(
+                       __METHOD__,
+                       function ( IDatabase $dbw, $fname ) use (
+                               $rev,
+                               $user,
+                               $comment,
+                               $title,
+                               $pageId,
+                               $parentId
+                       ) {
+                               return $this->insertRevisionInternal(
+                                       $rev,
+                                       $dbw,
+                                       $user,
+                                       $comment,
+                                       $title,
+                                       $pageId,
+                                       $parentId
+                               );
+                       }
+               );
 
-                       $blobAddress = $this->blobStore->storeBlob( $data, $blobHints );
-               } else {
-                       $blobAddress = $slot->getAddress();
-                       $model = $slot->getModel();
-                       $format = $slot->getFormat();
+               // sanity checks
+               Assert::postcondition( $rev->getId() > 0, 'revision must have an ID' );
+               Assert::postcondition( $rev->getPageId() > 0, 'revision must have a page ID' );
+               Assert::postcondition(
+                       $rev->getComment( RevisionRecord::RAW ) !== null,
+                       'revision must have a comment'
+               );
+               Assert::postcondition(
+                       $rev->getUser( RevisionRecord::RAW ) !== null,
+                       'revision must have a user'
+               );
+
+               // Trigger exception if the main slot is missing.
+               // Technically, this could go away after MCR migration: while
+               // calling code may require a main slot to exist, RevisionStore
+               // really should not know or care about that requirement.
+               $rev->getSlot( 'main', RevisionRecord::RAW );
+
+               foreach ( $slotRoles as $role ) {
+                       $slot = $rev->getSlot( $role, RevisionRecord::RAW );
+                       Assert::postcondition(
+                               $slot->getContent() !== null,
+                               $role .  ' slot must have content'
+                       );
+                       Assert::postcondition(
+                               $slot->hasRevision(),
+                               $role .  ' slot must have a revision associated'
+                       );
                }
 
-               $textId = $this->blobStore->getTextIdFromAddress( $blobAddress );
+               Hooks::run( 'RevisionRecordInserted', [ $rev ] );
+
+               // TODO: deprecate in 1.32!
+               $legacyRevision = new Revision( $rev );
+               Hooks::run( 'RevisionInsertComplete', [ &$legacyRevision, null, null ] );
 
+               return $rev;
+       }
+
+       private function insertRevisionInternal(
+               RevisionRecord $rev,
+               IDatabase $dbw,
+               User $user,
+               CommentStoreComment $comment,
+               Title $title,
+               $pageId,
+               $parentId
+       ) {
+               $slotRoles = $rev->getSlotRoles();
+
+               $revisionRow = $this->insertRevisionRowOn(
+                       $dbw,
+                       $rev,
+                       $title,
+                       $parentId
+               );
+
+               $revisionId = $revisionRow['rev_id'];
+
+               $blobHints = [
+                       BlobStore::PAGE_HINT => $pageId,
+                       BlobStore::REVISION_HINT => $revisionId,
+                       BlobStore::PARENT_HINT => $parentId,
+               ];
+
+               $newSlots = [];
+               foreach ( $slotRoles as $role ) {
+                       $slot = $rev->getSlot( $role, RevisionRecord::RAW );
+
+                       if ( $slot->hasRevision() ) {
+                               // If the SlotRecord already has a revision ID set, this means it already exists
+                               // in the database, and should already belong to the current revision.
+                               // TODO: properly abort transaction if the assertion fails!
+                               Assert::parameter(
+                                       $slot->getRevision() === $revisionId,
+                                       'slot role ' . $slot->getRole(),
+                                       'Existing slot should belong to revision '
+                                       . $revisionId . ', but belongs to revision ' . $slot->getRevision() . '!'
+                               );
+
+                               // Slot exists, nothing to do, move along.
+                               // This happens when restoring archived revisions.
+
+                               $newSlots[$role] = $slot;
+
+                               // Write the main slot's text ID to the revision table for backwards compatibility
+                               if ( $slot->getRole() === 'main'
+                                       && $this->hasMcrSchemaFlags( SCHEMA_COMPAT_WRITE_OLD )
+                               ) {
+                                       $blobAddress = $slot->getAddress();
+                                       $this->updateRevisionTextId( $dbw, $revisionId, $blobAddress );
+                               }
+                       } else {
+                               $newSlots[$role] = $this->insertSlotOn( $dbw, $revisionId, $slot, $title, $blobHints );
+                       }
+               }
+
+               $this->insertIpChangesRow( $dbw, $user, $rev, $revisionId );
+
+               $rev = new RevisionStoreRecord(
+                       $title,
+                       $user,
+                       $comment,
+                       (object)$revisionRow,
+                       new RevisionSlots( $newSlots ),
+                       $this->wikiId
+               );
+
+               return $rev;
+       }
+
+       /**
+        * @param IDatabase $dbw
+        * @param int $revisionId
+        * @param string &$blobAddress (may change!)
+        */
+       private function updateRevisionTextId( IDatabase $dbw, $revisionId, &$blobAddress ) {
+               $textId = $this->blobStore->getTextIdFromAddress( $blobAddress );
                if ( !$textId ) {
                        throw new LogicException(
                                'Blob address not supported in 1.29 database schema: ' . $blobAddress
@@ -393,103 +606,255 @@ class RevisionStore
                // may be a new value, not anything already contained in $blobAddress.
                $blobAddress = SqlBlobStore::makeAddressFromTextId( $textId );
 
-               $comment = $this->failOnNull( $rev->getComment( RevisionRecord::RAW ), 'comment' );
-               $user = $this->failOnNull( $rev->getUser( RevisionRecord::RAW ), 'user' );
-               $timestamp = $this->failOnEmpty( $rev->getTimestamp(), 'timestamp field' );
-
-               // Checks.
-               $this->failOnNull( $user->getId(), 'user field' );
-               $this->failOnEmpty( $user->getName(), 'user_text field' );
-
-               # Record the edit in revisions
-               $row = [
-                       'rev_page'       => $pageId,
-                       'rev_parent_id'  => $parentId,
-                       'rev_text_id'    => $textId,
-                       'rev_minor_edit' => $rev->isMinor() ? 1 : 0,
-                       'rev_timestamp'  => $dbw->timestamp( $timestamp ),
-                       'rev_deleted'    => $rev->getVisibility(),
-                       'rev_len'        => $size,
-                       'rev_sha1'       => $sha1,
-               ];
+               $dbw->update(
+                       'revision',
+                       [ 'rev_text_id' => $textId ],
+                       [ 'rev_id' => $revisionId ],
+                       __METHOD__
+               );
+       }
 
-               if ( $rev->getId() !== null ) {
-                       // Needed to restore revisions with their original ID
-                       $row['rev_id'] = $rev->getId();
+       /**
+        * @param IDatabase $dbw
+        * @param int $revisionId
+        * @param SlotRecord $protoSlot
+        * @param Title $title
+        * @param array $blobHints See the BlobStore::XXX_HINT constants
+        * @return SlotRecord
+        */
+       private function insertSlotOn(
+               IDatabase $dbw,
+               $revisionId,
+               SlotRecord $protoSlot,
+               Title $title,
+               array $blobHints = []
+       ) {
+               if ( $protoSlot->hasAddress() ) {
+                       $blobAddress = $protoSlot->getAddress();
+               } else {
+                       $blobAddress = $this->storeContentBlob( $protoSlot, $title, $blobHints );
                }
 
-               list( $commentFields, $commentCallback ) =
-                       $this->commentStore->insertWithTempTable( $dbw, 'rev_comment', $comment );
-               $row += $commentFields;
-
-               list( $actorFields, $actorCallback ) =
-                       $this->actorMigration->getInsertValuesWithTempTable( $dbw, 'rev_user', $user );
-               $row += $actorFields;
-
-               if ( $this->contentHandlerUseDB ) {
-                       // MCR migration note: rev_content_model and rev_content_format will go away
+               // Write the main slot's text ID to the revision table for backwards compatibility
+               if ( $protoSlot->getRole() === 'main'
+                       && $this->hasMcrSchemaFlags( SCHEMA_COMPAT_WRITE_OLD )
+               ) {
+                       $this->updateRevisionTextId( $dbw, $revisionId, $blobAddress );
+               }
 
-                       $defaultModel = ContentHandler::getDefaultModelFor( $title );
-                       $defaultFormat = ContentHandler::getForModelID( $defaultModel )->getDefaultFormat();
+               if ( $this->hasMcrSchemaFlags( SCHEMA_COMPAT_WRITE_NEW ) ) {
+                       if ( $protoSlot->hasContentId() ) {
+                               $contentId = $protoSlot->getContentId();
+                       } else {
+                               $contentId = $this->insertContentRowOn( $protoSlot, $dbw, $blobAddress );
+                       }
 
-                       $row['rev_content_model'] = ( $model === $defaultModel ) ? null : $model;
-                       $row['rev_content_format'] = ( $format === $defaultFormat ) ? null : $format;
+                       $this->insertSlotRowOn( $protoSlot, $dbw, $revisionId, $contentId );
+               } else {
+                       $contentId = null;
                }
 
-               $dbw->insert( 'revision', $row, __METHOD__ );
+               $savedSlot = SlotRecord::newSaved(
+                       $revisionId,
+                       $contentId,
+                       $blobAddress,
+                       $protoSlot
+               );
 
-               if ( !isset( $row['rev_id'] ) ) {
-                       // only if auto-increment was used
-                       $row['rev_id'] = intval( $dbw->insertId() );
-               }
-               $commentCallback( $row['rev_id'] );
-               $actorCallback( $row['rev_id'], $row );
+               return $savedSlot;
+       }
 
-               // Insert IP revision into ip_changes for use when querying for a range.
+       /**
+        * Insert IP revision into ip_changes for use when querying for a range.
+        * @param IDatabase $dbw
+        * @param User $user
+        * @param RevisionRecord $rev
+        * @param int $revisionId
+        */
+       private function insertIpChangesRow(
+               IDatabase $dbw,
+               User $user,
+               RevisionRecord $rev,
+               $revisionId
+       ) {
                if ( $user->getId() === 0 && IP::isValid( $user->getName() ) ) {
                        $ipcRow = [
-                               'ipc_rev_id'        => $row['rev_id'],
-                               'ipc_rev_timestamp' => $row['rev_timestamp'],
+                               'ipc_rev_id'        => $revisionId,
+                               'ipc_rev_timestamp' => $dbw->timestamp( $rev->getTimestamp() ),
                                'ipc_hex'           => IP::toHex( $user->getName() ),
                        ];
                        $dbw->insert( 'ip_changes', $ipcRow, __METHOD__ );
                }
+       }
+
+       /**
+        * @param IDatabase $dbw
+        * @param RevisionRecord $rev
+        * @param Title $title
+        * @param int $parentId
+        *
+        * @return array a revision table row
+        *
+        * @throws MWException
+        * @throws MWUnknownContentModelException
+        */
+       private function insertRevisionRowOn(
+               IDatabase $dbw,
+               RevisionRecord $rev,
+               Title $title,
+               $parentId
+       ) {
+               $revisionRow = $this->getBaseRevisionRow( $dbw, $rev, $title, $parentId );
 
-               $newSlot = SlotRecord::newSaved( $row['rev_id'], $textId, $blobAddress, $slot );
-               $slots = new RevisionSlots( [ 'main' => $newSlot ] );
+               list( $commentFields, $commentCallback ) =
+                       $this->commentStore->insertWithTempTable(
+                               $dbw,
+                               'rev_comment',
+                               $rev->getComment( RevisionRecord::RAW )
+                       );
+               $revisionRow += $commentFields;
 
-               $rev = new RevisionStoreRecord(
-                       $title,
-                       $user,
-                       $comment,
-                       (object)$row,
-                       $slots,
-                       $this->wikiId
-               );
+               list( $actorFields, $actorCallback ) =
+                       $this->actorMigration->getInsertValuesWithTempTable(
+                               $dbw,
+                               'rev_user',
+                               $rev->getUser( RevisionRecord::RAW )
+                       );
+               $revisionRow += $actorFields;
 
-               $newSlot = $rev->getSlot( 'main', RevisionRecord::RAW );
+               $dbw->insert( 'revision', $revisionRow, __METHOD__ );
 
-               // sanity checks
-               Assert::postcondition( $rev->getId() > 0, 'revision must have an ID' );
-               Assert::postcondition( $rev->getPageId() > 0, 'revision must have a page ID' );
-               Assert::postcondition(
-                       $rev->getComment( RevisionRecord::RAW ) !== null,
-                       'revision must have a comment'
-               );
-               Assert::postcondition(
-                       $rev->getUser( RevisionRecord::RAW ) !== null,
-                       'revision must have a user'
-               );
+               if ( !isset( $revisionRow['rev_id'] ) ) {
+                       // only if auto-increment was used
+                       $revisionRow['rev_id'] = intval( $dbw->insertId() );
+               }
 
-               Assert::postcondition( $newSlot !== null, 'revision must have a main slot' );
-               Assert::postcondition(
-                       $newSlot->getAddress() !== null,
-                       'main slot must have an addess'
+               $commentCallback( $revisionRow['rev_id'] );
+               $actorCallback( $revisionRow['rev_id'], $revisionRow );
+
+               return $revisionRow;
+       }
+
+       /**
+        * @param IDatabase $dbw
+        * @param RevisionRecord $rev
+        * @param Title $title
+        * @param int $parentId
+        *
+        * @return array [ 0 => array $revisionRow, 1 => callable  ]
+        * @throws MWException
+        * @throws MWUnknownContentModelException
+        */
+       private function getBaseRevisionRow(
+               IDatabase $dbw,
+               RevisionRecord $rev,
+               Title $title,
+               $parentId
+       ) {
+               // Record the edit in revisions
+               $revisionRow = [
+                       'rev_page'       => $rev->getPageId(),
+                       'rev_parent_id'  => $parentId,
+                       'rev_minor_edit' => $rev->isMinor() ? 1 : 0,
+                       'rev_timestamp'  => $dbw->timestamp( $rev->getTimestamp() ),
+                       'rev_deleted'    => $rev->getVisibility(),
+                       'rev_len'        => $rev->getSize(),
+                       'rev_sha1'       => $rev->getSha1(),
+               ];
+
+               if ( $rev->getId() !== null ) {
+                       // Needed to restore revisions with their original ID
+                       $revisionRow['rev_id'] = $rev->getId();
+               }
+
+               if ( $this->hasMcrSchemaFlags( SCHEMA_COMPAT_WRITE_OLD ) ) {
+                       // In non MCR mode this IF section will relate to the main slot
+                       $mainSlot = $rev->getSlot( 'main' );
+                       $model = $mainSlot->getModel();
+                       $format = $mainSlot->getFormat();
+
+                       // MCR migration note: rev_content_model and rev_content_format will go away
+                       if ( $this->contentHandlerUseDB ) {
+                               $defaultModel = ContentHandler::getDefaultModelFor( $title );
+                               $defaultFormat = ContentHandler::getForModelID( $defaultModel )->getDefaultFormat();
+
+                               $revisionRow['rev_content_model'] = ( $model === $defaultModel ) ? null : $model;
+                               $revisionRow['rev_content_format'] = ( $format === $defaultFormat ) ? null : $format;
+                       }
+               }
+
+               return $revisionRow;
+       }
+
+       /**
+        * @param SlotRecord $slot
+        * @param Title $title
+        * @param array $blobHints See the BlobStore::XXX_HINT constants
+        *
+        * @throws MWException
+        * @return string the blob address
+        */
+       private function storeContentBlob(
+               SlotRecord $slot,
+               Title $title,
+               array $blobHints = []
+       ) {
+               $content = $slot->getContent();
+               $format = $content->getDefaultFormat();
+               $model = $content->getModel();
+
+               $this->checkContent( $content, $title );
+
+               return $this->blobStore->storeBlob(
+                       $content->serialize( $format ),
+                       // These hints "leak" some information from the higher abstraction layer to
+                       // low level storage to allow for optimization.
+                       array_merge(
+                               $blobHints,
+                               [
+                                       BlobStore::DESIGNATION_HINT => 'page-content',
+                                       BlobStore::ROLE_HINT => $slot->getRole(),
+                                       BlobStore::SHA1_HINT => $slot->getSha1(),
+                                       BlobStore::MODEL_HINT => $model,
+                                       BlobStore::FORMAT_HINT => $format,
+                               ]
+                       )
                );
+       }
 
-               Hooks::run( 'RevisionRecordInserted', [ $rev ] );
+       /**
+        * @param SlotRecord $slot
+        * @param IDatabase $dbw
+        * @param int $revisionId
+        * @param int $contentId
+        */
+       private function insertSlotRowOn( SlotRecord $slot, IDatabase $dbw, $revisionId, $contentId ) {
+               $slotRow = [
+                       'slot_revision_id' => $revisionId,
+                       'slot_role_id' => $this->slotRoleStore->acquireId( $slot->getRole() ),
+                       'slot_content_id' => $contentId,
+                       // If the slot has a specific origin use that ID, otherwise use the ID of the revision
+                       // that we just inserted.
+                       'slot_origin' => $slot->hasOrigin() ? $slot->getOrigin() : $revisionId,
+               ];
+               $dbw->insert( 'slots', $slotRow, __METHOD__ );
+       }
 
-               return $rev;
+       /**
+        * @param SlotRecord $slot
+        * @param IDatabase $dbw
+        * @param string $blobAddress
+        * @return int content row ID
+        */
+       private function insertContentRowOn( SlotRecord $slot, IDatabase $dbw, $blobAddress ) {
+               $contentRow = [
+                       'content_size' => $slot->getSize(),
+                       'content_sha1' => $slot->getSha1(),
+                       'content_model' => $this->contentModelStore->acquireId( $slot->getModel() ),
+                       'content_address' => $blobAddress,
+               ];
+               $dbw->insert( 'content', $contentRow, __METHOD__ );
+               return intval( $dbw->insertId() );
        }
 
        /**
@@ -501,7 +866,7 @@ class RevisionStore
         * @throws MWException
         * @throws MWUnknownContentModelException
         */
-       private function checkContentModel( Content $content, Title $title ) {
+       private function checkContent( Content $content, Title $title ) {
                // Note: may return null for revisions that have not yet been inserted
 
                $model = $content->getModel();
@@ -552,16 +917,21 @@ class RevisionStore
         * Such revisions can for instance identify page rename
         * operations and other such meta-modifications.
         *
+        * @note This method grabs a FOR UPDATE lock on the relevant row of the page table,
+        * to prevent a new revision from being inserted before the null revision has been written
+        * to the database.
+        *
         * MCR migration note: this replaces Revision::newNullRevision
         *
         * @todo Introduce newFromParentRevision(). newNullRevision can then be based on that
         * (or go away).
         *
-        * @param IDatabase $dbw
+        * @param IDatabase $dbw used for obtaining the lock on the page table row
         * @param Title $title Title of the page to read from
         * @param CommentStoreComment $comment RevisionRecord's summary
         * @param bool $minor Whether the revision should be considered as minor
         * @param User $user The user to attribute the revision to
+        *
         * @return RevisionRecord|null RevisionRecord or null on error
         */
        public function newNullRevision(
@@ -573,56 +943,39 @@ class RevisionStore
        ) {
                $this->checkDatabaseWikiId( $dbw );
 
-               $fields = [ 'page_latest', 'page_namespace', 'page_title',
-                       'rev_id', 'rev_text_id', 'rev_len', 'rev_sha1' ];
-
-               if ( $this->contentHandlerUseDB ) {
-                       $fields[] = 'rev_content_model';
-                       $fields[] = 'rev_content_format';
-               }
-
-               $current = $dbw->selectRow(
-                       [ 'page', 'revision' ],
-                       $fields,
-                       [
-                               'page_id' => $title->getArticleID(),
-                               'page_latest=rev_id',
-                       ],
+               // T51581: Lock the page table row to ensure no other process
+               // is adding a revision to the page at the same time.
+               // Avoid locking extra tables, compare T191892.
+               $pageLatest = $dbw->selectField(
+                       'page',
+                       'page_latest',
+                       [ 'page_id' => $title->getArticleID() ],
                        __METHOD__,
-                       [ 'FOR UPDATE' ] // T51581
+                       [ 'FOR UPDATE' ]
                );
 
-               if ( $current ) {
-                       $fields = [
-                               'page'        => $title->getArticleID(),
-                               'user_text'   => $user->getName(),
-                               'user'        => $user->getId(),
-                               'actor'       => $user->getActorId(),
-                               'comment'     => $comment,
-                               'minor_edit'  => $minor,
-                               'text_id'     => $current->rev_text_id,
-                               'parent_id'   => $current->page_latest,
-                               'slot_origin' => $current->page_latest,
-                               'len'         => $current->rev_len,
-                               'sha1'        => $current->rev_sha1
-                       ];
+               if ( !$pageLatest ) {
+                       return null;
+               }
 
-                       if ( $this->contentHandlerUseDB ) {
-                               $fields['content_model'] = $current->rev_content_model;
-                               $fields['content_format'] = $current->rev_content_format;
-                       }
+               // Fetch the actual revision row from master, without locking all extra tables.
+               $oldRevision = $this->loadRevisionFromConds(
+                       $dbw,
+                       [ 'rev_id' => intval( $pageLatest ) ],
+                       self::READ_LATEST,
+                       $title
+               );
 
-                       $fields['title'] = Title::makeTitle( $current->page_namespace, $current->page_title );
+               // Construct the new revision
+               $timestamp = wfTimestampNow(); // TODO: use a callback, so we can override it for testing.
+               $newRevision = MutableRevisionRecord::newFromParentRevision( $oldRevision );
 
-                       $mainSlot = $this->emulateMainSlot_1_29( $fields, self::READ_LATEST, $title );
-                       $revision = new MutableRevisionRecord( $title, $this->wikiId );
-                       $this->initializeMutableRevisionFromArray( $revision, $fields );
-                       $revision->setSlot( $mainSlot );
-               } else {
-                       $revision = null;
-               }
+               $newRevision->setComment( $comment );
+               $newRevision->setUser( $user );
+               $newRevision->setTimestamp( $timestamp );
+               $newRevision->setMinorEdit( $minor );
 
-               return $revision;
+               return $newRevision;
        }
 
        /**
@@ -657,9 +1010,8 @@ class RevisionStore
         * @return null|RecentChange
         */
        public function getRecentChange( RevisionRecord $rev, $flags = 0 ) {
-               $dbr = $this->getDBConnection( DB_REPLICA );
-
                list( $dbType, ) = DBAccessObjectUtils::getDBOptions( $flags );
+               $db = $this->getDBConnection( $dbType );
 
                $userIdentity = $rev->getUser( RevisionRecord::RAW );
 
@@ -670,18 +1022,18 @@ class RevisionStore
                }
 
                // TODO: Select by rc_this_oldid alone - but as of Nov 2017, there is no index on that!
-               $actorWhere = $this->actorMigration->getWhere( $dbr, 'rc_user', $rev->getUser(), false );
+               $actorWhere = $this->actorMigration->getWhere( $db, 'rc_user', $rev->getUser(), false );
                $rc = RecentChange::newFromConds(
                        [
                                $actorWhere['conds'],
-                               'rc_timestamp' => $dbr->timestamp( $rev->getTimestamp() ),
+                               'rc_timestamp' => $db->timestamp( $rev->getTimestamp() ),
                                'rc_this_oldid' => $rev->getId()
                        ],
                        __METHOD__,
                        $dbType
                );
 
-               $this->releaseDBConnection( $dbr );
+               $this->releaseDBConnection( $db );
 
                // XXX: cache this locally? Glue it to the RevisionRecord?
                return $rc;
@@ -750,20 +1102,24 @@ class RevisionStore
                $mainSlotRow->model_name = null;
                $mainSlotRow->slot_revision_id = null;
                $mainSlotRow->content_address = null;
-               $mainSlotRow->slot_content_id = null;
 
                $content = null;
                $blobData = null;
                $blobFlags = null;
 
                if ( is_object( $row ) ) {
+                       if ( $this->hasMcrSchemaFlags( SCHEMA_COMPAT_READ_NEW ) ) {
+                               // Don't emulate from a row when using the new schema.
+                               // Emulating from an array is still OK.
+                               throw new LogicException( 'Can\'t emulate the main slot when using MCR schema.' );
+                       }
+
                        // archive row
                        if ( !isset( $row->rev_id ) && ( isset( $row->ar_user ) || isset( $row->ar_actor ) ) ) {
                                $row = $this->mapArchiveFields( $row );
                        }
 
                        if ( isset( $row->rev_text_id ) && $row->rev_text_id > 0 ) {
-                               $mainSlotRow->slot_content_id = $row->rev_text_id;
                                $mainSlotRow->content_address = SqlBlobStore::makeAddressFromTextId(
                                        $row->rev_text_id
                                );
@@ -781,7 +1137,7 @@ class RevisionStore
                                if ( !property_exists( $row, 'old_flags' ) ) {
                                        throw new InvalidArgumentException( 'old_flags was not set in $row' );
                                }
-                               $blobFlags = ( $row->old_flags === null ) ? '' : $row->old_flags;
+                               $blobFlags = $row->old_flags ?? '';
                        }
 
                        $mainSlotRow->slot_revision_id = intval( $row->rev_id );
@@ -798,9 +1154,6 @@ class RevisionStore
                } elseif ( is_array( $row ) ) {
                        $mainSlotRow->slot_revision_id = isset( $row['id'] ) ? intval( $row['id'] ) : null;
 
-                       $mainSlotRow->slot_content_id = isset( $row['text_id'] )
-                               ? intval( $row['text_id'] )
-                               : null;
                        $mainSlotRow->slot_origin = isset( $row['slot_origin'] )
                                ? intval( $row['slot_origin'] )
                                : null;
@@ -856,6 +1209,9 @@ class RevisionStore
                }
 
                if ( !$content ) {
+                       // XXX: We should perhaps fail if $blobData is null and $mainSlotRow->content_address
+                       // is missing, but "empty revisions" with no content are used in some edge cases.
+
                        $content = function ( SlotRecord $slot )
                                use ( $blobData, $blobFlags, $queryFlags, $mainSlotRow )
                        {
@@ -869,7 +1225,15 @@ class RevisionStore
                        };
                }
 
-               $mainSlotRow->slot_id = $mainSlotRow->slot_revision_id;
+               // NOTE: this callback will be looped through RevisionSlot::newInherited(), allowing
+               // the inherited slot to have the same content_id as the original slot. In that case,
+               // $slot will be the inherited slot, while $mainSlotRow still refers to the original slot.
+               $mainSlotRow->slot_content_id =
+                       function ( SlotRecord $slot ) use ( $queryFlags, $mainSlotRow ) {
+                               $db = $this->getDBConnectionRefForQueryFlags( $queryFlags );
+                               return $this->findSlotContentId( $db, $mainSlotRow->slot_revision_id, 'main' );
+                       };
+
                return new SlotRecord( $mainSlotRow, $content );
        }
 
@@ -988,12 +1352,11 @@ class RevisionStore
                        // and fall back to master. The assumption is that we only want to force the fallback
                        // if we are quite sure the revision exists because the caller supplied a revision ID.
                        // If the page isn't found at all on a replica, it probably simply does not exist.
-                       $db = $this->getDBConnection( ( $flags & self::READ_LATEST ) ? DB_MASTER : DB_REPLICA );
+                       $db = $this->getDBConnectionRefForQueryFlags( $flags );
 
                        $conds[] = 'rev_id=page_latest';
                        $rev = $this->loadRevisionFromConds( $db, $conds, $flags );
 
-                       $this->releaseDBConnection( $db );
                        return $rev;
                }
        }
@@ -1030,12 +1393,11 @@ class RevisionStore
                        // and fall back to master. The assumption is that we only want to force the fallback
                        // if we are quite sure the revision exists because the caller supplied a revision ID.
                        // If the page isn't found at all on a replica, it probably simply does not exist.
-                       $db = $this->getDBConnection( ( $flags & self::READ_LATEST ) ? DB_MASTER : DB_REPLICA );
+                       $db = $this->getDBConnectionRefForQueryFlags( $flags );
 
                        $conds[] = 'rev_id=page_latest';
                        $rev = $this->loadRevisionFromConds( $db, $conds, $flags );
 
-                       $this->releaseDBConnection( $db );
                        return $rev;
                }
        }
@@ -1064,6 +1426,83 @@ class RevisionStore
                );
        }
 
+       /**
+        * @param int $revId The revision to load slots for.
+        * @param int $queryFlags
+        *
+        * @return SlotRecord[]
+        */
+       private function loadSlotRecords( $revId, $queryFlags ) {
+               $revQuery = self::getSlotsQueryInfo( [ 'content' ] );
+
+               list( $dbMode, $dbOptions ) = DBAccessObjectUtils::getDBOptions( $queryFlags );
+               $db = $this->getDBConnectionRef( $dbMode );
+
+               $res = $db->select(
+                       $revQuery['tables'],
+                       $revQuery['fields'],
+                       [
+                               'slot_revision_id' => $revId,
+                       ],
+                       __METHOD__,
+                       $dbOptions,
+                       $revQuery['joins']
+               );
+
+               $slots = [];
+
+               foreach ( $res as $row ) {
+                       $contentCallback = function ( SlotRecord $slot ) use ( $queryFlags, $row ) {
+                               return $this->loadSlotContent( $slot, null, null, null, $queryFlags );
+                       };
+
+                       $slots[$row->role_name] = new SlotRecord( $row, $contentCallback );
+               }
+
+               if ( !isset( $slots['main'] ) ) {
+                       throw new RevisionAccessException(
+                               'Main slot of revision ' . $revId . ' not found in database!'
+                       );
+               };
+
+               return $slots;
+       }
+
+       /**
+        * Factory method for RevisionSlots.
+        *
+        * @note If other code has a need to construct RevisionSlots objects, this should be made
+        * public, since RevisionSlots instances should not be constructed directly.
+        *
+        * @param int $revId
+        * @param object $revisionRow
+        * @param int $queryFlags
+        * @param Title $title
+        *
+        * @return RevisionSlots
+        * @throws MWException
+        */
+       private function newRevisionSlots(
+               $revId,
+               $revisionRow,
+               $queryFlags,
+               Title $title
+       ) {
+               if ( !$this->hasMcrSchemaFlags( SCHEMA_COMPAT_READ_NEW ) ) {
+                       $mainSlot = $this->emulateMainSlot_1_29( $revisionRow, $queryFlags, $title );
+                       $slots = new RevisionSlots( [ 'main' => $mainSlot ] );
+               } else {
+                       // XXX: do we need the same kind of caching here
+                       // that getKnownCurrentRevision uses (if $revId == page_latest?)
+
+                       $slots = new RevisionSlots( function () use( $revId, $queryFlags ) {
+                               return $this->loadSlotRecords( $revId, $queryFlags );
+                       } );
+               }
+
+               return $slots;
+       }
+
        /**
         * Make a fake revision object from an archive table row. This is queried
         * for permissions or even inserted (as in Special:Undelete)
@@ -1117,27 +1556,26 @@ class RevisionStore
 
                try {
                        $user = User::newFromAnyId(
-                               isset( $row->ar_user ) ? $row->ar_user : null,
-                               isset( $row->ar_user_text ) ? $row->ar_user_text : null,
-                               isset( $row->ar_actor ) ? $row->ar_actor : null
+                               $row->ar_user ?? null,
+                               $row->ar_user_text ?? null,
+                               $row->ar_actor ?? null
                        );
                } catch ( InvalidArgumentException $ex ) {
                        wfWarn( __METHOD__ . ': ' . $ex->getMessage() );
                        $user = new UserIdentityValue( 0, '', 0 );
                }
 
-               $comment = $this->commentStore
-                       // Legacy because $row may have come from self::selectFields()
-                       ->getCommentLegacy( $this->getDBConnection( DB_REPLICA ), 'ar_comment', $row, true );
+               $db = $this->getDBConnectionRefForQueryFlags( $queryFlags );
+               // Legacy because $row may have come from self::selectFields()
+               $comment = $this->commentStore->getCommentLegacy( $db, 'ar_comment', $row, true );
 
-               $mainSlot = $this->emulateMainSlot_1_29( $row, $queryFlags, $title );
-               $slots = new RevisionSlots( [ 'main' => $mainSlot ] );
+               $slots = $this->newRevisionSlots( $row->ar_rev_id, $row, $queryFlags, $title );
 
                return new RevisionArchiveRecord( $title, $user, $comment, $row, $slots, $this->wikiId );
        }
 
        /**
-        * @see RevisionFactory::newRevisionFromRow_1_29
+        * @see RevisionFactory::newRevisionFromRow
         *
         * MCR migration note: this replaces Revision::newFromRow
         *
@@ -1146,15 +1584,13 @@ class RevisionStore
         * @param Title|null $title
         *
         * @return RevisionRecord
-        * @throws MWException
-        * @throws RevisionAccessException
         */
-       private function newRevisionFromRow_1_29( $row, $queryFlags = 0, Title $title = null ) {
+       public function newRevisionFromRow( $row, $queryFlags = 0, Title $title = null ) {
                Assert::parameterType( 'object', $row, '$row' );
 
                if ( !$title ) {
-                       $pageId = isset( $row->rev_page ) ? $row->rev_page : 0; // XXX: also check page_id?
-                       $revId = isset( $row->rev_id ) ? $row->rev_id : 0;
+                       $pageId = $row->rev_page ?? 0; // XXX: also check page_id?
+                       $revId = $row->rev_id ?? 0;
 
                        $title = $this->getTitle( $pageId, $revId, $queryFlags );
                }
@@ -1168,40 +1604,24 @@ class RevisionStore
 
                try {
                        $user = User::newFromAnyId(
-                               isset( $row->rev_user ) ? $row->rev_user : null,
-                               isset( $row->rev_user_text ) ? $row->rev_user_text : null,
-                               isset( $row->rev_actor ) ? $row->rev_actor : null
+                               $row->rev_user ?? null,
+                               $row->rev_user_text ?? null,
+                               $row->rev_actor ?? null
                        );
                } catch ( InvalidArgumentException $ex ) {
                        wfWarn( __METHOD__ . ': ' . $ex->getMessage() );
                        $user = new UserIdentityValue( 0, '', 0 );
                }
 
-               $comment = $this->commentStore
-                       // Legacy because $row may have come from self::selectFields()
-                       ->getCommentLegacy( $this->getDBConnection( DB_REPLICA ), 'rev_comment', $row, true );
+               $db = $this->getDBConnectionRefForQueryFlags( $queryFlags );
+               // Legacy because $row may have come from self::selectFields()
+               $comment = $this->commentStore->getCommentLegacy( $db, 'rev_comment', $row, true );
 
-               $mainSlot = $this->emulateMainSlot_1_29( $row, $queryFlags, $title );
-               $slots = new RevisionSlots( [ 'main' => $mainSlot ] );
+               $slots = $this->newRevisionSlots( $row->rev_id, $row, $queryFlags, $title );
 
                return new RevisionStoreRecord( $title, $user, $comment, $row, $slots, $this->wikiId );
        }
 
-       /**
-        * @see RevisionFactory::newRevisionFromRow
-        *
-        * MCR migration note: this replaces Revision::newFromRow
-        *
-        * @param object $row
-        * @param int $queryFlags
-        * @param Title|null $title
-        *
-        * @return RevisionRecord
-        */
-       public function newRevisionFromRow( $row, $queryFlags = 0, Title $title = null ) {
-               return $this->newRevisionFromRow_1_29( $row, $queryFlags, $title );
-       }
-
        /**
         * Constructs a new MutableRevisionRecord based on the given associative array following
         * the MW1.29 convention for the Revision constructor.
@@ -1230,8 +1650,8 @@ class RevisionStore
                }
 
                if ( !$title ) {
-                       $pageId = isset( $fields['page'] ) ? $fields['page'] : 0;
-                       $revId = isset( $fields['id'] ) ? $fields['id'] : 0;
+                       $pageId = $fields['page'] ?? 0;
+                       $revId = $fields['id'] ?? 0;
 
                        $title = $this->getTitle( $pageId, $revId, $queryFlags );
                }
@@ -1242,14 +1662,22 @@ 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 ) ) {
-                               throw new MWException( 'content field must contain a Content object.' );
+                       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['text_id'] ) ) {
+               if ( !empty( $fields['text_id'] ) ) {
+                       if ( !$this->hasMcrSchemaFlags( SCHEMA_COMPAT_READ_OLD ) ) {
+                               throw new MWException( "The text_id field is only available in the pre-MCR schema" );
+                       }
+
+                       if ( !empty( $fields['content'] ) ) {
                                throw new MWException(
                                        "Text already stored in external store (id {$fields['text_id']}), " .
-                                       "can't serialize content object"
+                                       "can't specify content object"
                                );
                        }
                }
@@ -1258,7 +1686,7 @@ class RevisionStore
                        isset( $fields['comment'] )
                        && !( $fields['comment'] instanceof CommentStoreComment )
                ) {
-                       $commentData = isset( $fields['comment_data'] ) ? $fields['comment_data'] : null;
+                       $commentData = $fields['comment_data'] ?? null;
 
                        if ( $fields['comment'] instanceof Message ) {
                                $fields['comment'] = CommentStoreComment::newUnsavedComment(
@@ -1274,11 +1702,17 @@ class RevisionStore
                        }
                }
 
-               $mainSlot = $this->emulateMainSlot_1_29( $fields, $queryFlags, $title );
-
                $revision = new MutableRevisionRecord( $title, $this->wikiId );
                $this->initializeMutableRevisionFromArray( $revision, $fields );
-               $revision->setSlot( $mainSlot );
+
+               if ( isset( $fields['content'] ) && is_array( $fields['content'] ) ) {
+                       foreach ( $fields['content'] as $role => $content ) {
+                               $revision->setContent( $role, $content );
+                       }
+               } else {
+                       $mainSlot = $this->emulateMainSlot_1_29( $fields, $queryFlags, $title );
+                       $revision->setSlot( $mainSlot );
+               }
 
                return $revision;
        }
@@ -1299,9 +1733,9 @@ class RevisionStore
                } else {
                        try {
                                $user = User::newFromAnyId(
-                                       isset( $fields['user'] ) ? $fields['user'] : null,
-                                       isset( $fields['user_text'] ) ? $fields['user_text'] : null,
-                                       isset( $fields['actor'] ) ? $fields['actor'] : null
+                                       $fields['user'] ?? null,
+                                       $fields['user_text'] ?? null,
+                                       $fields['actor'] ?? null
                                );
                        } catch ( InvalidArgumentException $ex ) {
                                $user = null;
@@ -1469,14 +1903,13 @@ class RevisionStore
         *
         * @param array $conditions
         * @param int $flags (optional)
-        * @param Title $title
+        * @param Title|null $title
         *
         * @return RevisionRecord|null
         */
        private function newRevisionFromConds( $conditions, $flags = 0, Title $title = null ) {
-               $db = $this->getDBConnection( ( $flags & self::READ_LATEST ) ? DB_MASTER : DB_REPLICA );
+               $db = $this->getDBConnectionRefForQueryFlags( $flags );
                $rev = $this->loadRevisionFromConds( $db, $conditions, $flags, $title );
-               $this->releaseDBConnection( $db );
 
                $lb = $this->getDBLoadBalancer();
 
@@ -1488,9 +1921,9 @@ class RevisionStore
                        && $lb->hasOrMadeRecentMasterChanges()
                ) {
                        $flags = self::READ_LATEST;
-                       $db = $this->getDBConnection( DB_MASTER );
-                       $rev = $this->loadRevisionFromConds( $db, $conditions, $flags, $title );
-                       $this->releaseDBConnection( $db );
+                       $dbw = $this->getDBConnection( DB_MASTER );
+                       $rev = $this->loadRevisionFromConds( $dbw, $conditions, $flags, $title );
+                       $this->releaseDBConnection( $dbw );
                }
 
                return $rev;
@@ -1505,7 +1938,7 @@ class RevisionStore
         * @param IDatabase $db
         * @param array $conditions
         * @param int $flags (optional)
-        * @param Title $title
+        * @param Title|null $title
         *
         * @return RevisionRecord|null
         */
@@ -1575,7 +2008,7 @@ class RevisionStore
        private function fetchRevisionRowFromConds( IDatabase $db, $conditions, $flags = 0 ) {
                $this->checkDatabaseWikiId( $db );
 
-               $revQuery = self::getQueryInfo( [ 'page', 'user' ] );
+               $revQuery = $this->getQueryInfo( [ 'page', 'user' ] );
                $options = [];
                if ( ( $flags & self::READ_LOCKING ) == self::READ_LOCKING ) {
                        $options[] = 'FOR UPDATE';
@@ -1590,18 +2023,59 @@ class RevisionStore
                );
        }
 
+       /**
+        * Finds the ID of a content row for a given revision and slot role.
+        * This can be used to re-use content rows even while the content ID
+        * is still missing from SlotRecords, when writing to both the old and
+        * the new schema during MCR schema migration.
+        *
+        * @todo remove after MCR schema migration is complete.
+        *
+        * @param IDatabase $db
+        * @param int $revId
+        * @param string $role
+        *
+        * @return int|null
+        */
+       private function findSlotContentId( IDatabase $db, $revId, $role ) {
+               if ( !$this->hasMcrSchemaFlags( SCHEMA_COMPAT_WRITE_NEW ) ) {
+                       return null;
+               }
+
+               try {
+                       $roleId = $this->slotRoleStore->getId( $role );
+                       $conditions = [
+                               'slot_revision_id' => $revId,
+                               'slot_role_id' => $roleId,
+                       ];
+
+                       $contentId = $db->selectField( 'slots', 'slot_content_id', $conditions, __METHOD__ );
+
+                       return $contentId ?: null;
+               } catch ( NameTableAccessException $ex ) {
+                       // If the role is missing from the slot_roles table,
+                       // the corresponding row in slots cannot exist.
+                       return null;
+               }
+       }
+
        /**
         * Return the tables, fields, and join conditions to be selected to create
-        * a new revision object.
+        * a new RevisionStoreRecord object.
         *
         * MCR migration note: this replaces Revision::getQueryInfo
         *
+        * If the format of fields returned changes in any way then the cache key provided by
+        * self::getRevisionRowCacheKey should be updated.
+        *
         * @since 1.31
         *
         * @param array $options Any combination of the following strings
         *  - 'page': Join with the page table, and select fields to identify the page
         *  - 'user': Join with the user table, and select the user name
-        *  - 'text': Join with the text table, and select fields to load page text
+        *  - 'text': Join with the text table, and select fields to load page text. This
+        *    option is deprecated in MW 1.32 when the MCR migration flag SCHEMA_COMPAT_WRITE_NEW
+        *    is set, and disallowed when SCHEMA_COMPAT_READ_OLD is not set.
         *
         * @return array With three keys:
         *  - tables: (string[]) to include in the `$table` to `IDatabase->select()`
@@ -1619,7 +2093,6 @@ class RevisionStore
                $ret['fields'] = array_merge( $ret['fields'], [
                        'rev_id',
                        'rev_page',
-                       'rev_text_id',
                        'rev_timestamp',
                        'rev_minor_edit',
                        'rev_deleted',
@@ -1638,9 +2111,13 @@ class RevisionStore
                $ret['fields'] = array_merge( $ret['fields'], $actorQuery['fields'] );
                $ret['joins'] = array_merge( $ret['joins'], $actorQuery['joins'] );
 
-               if ( $this->contentHandlerUseDB ) {
-                       $ret['fields'][] = 'rev_content_format';
-                       $ret['fields'][] = 'rev_content_model';
+               if ( $this->hasMcrSchemaFlags( SCHEMA_COMPAT_READ_OLD ) ) {
+                       $ret['fields'][] = 'rev_text_id';
+
+                       if ( $this->contentHandlerUseDB ) {
+                               $ret['fields'][] = 'rev_content_format';
+                               $ret['fields'][] = 'rev_content_model';
+                       }
                }
 
                if ( in_array( 'page', $options, true ) ) {
@@ -1666,6 +2143,15 @@ class RevisionStore
                }
 
                if ( in_array( 'text', $options, true ) ) {
+                       if ( !$this->hasMcrSchemaFlags( SCHEMA_COMPAT_WRITE_OLD ) ) {
+                               throw new InvalidArgumentException( 'text table can no longer be joined directly' );
+                       } elseif ( !$this->hasMcrSchemaFlags( SCHEMA_COMPAT_READ_OLD ) ) {
+                               // NOTE: even when this class is set to not read from the old schema, callers
+                               // should still be able to join against the text table, as long as we are still
+                               // writing the old schema for compatibility.
+                               wfDeprecated( __METHOD__ . ' with `text` option', '1.32' );
+                       }
+
                        $ret['tables'][] = 'text';
                        $ret['fields'] = array_merge( $ret['fields'], [
                                'old_text',
@@ -1679,7 +2165,77 @@ class RevisionStore
 
        /**
         * Return the tables, fields, and join conditions to be selected to create
-        * a new archived revision object.
+        * a new SlotRecord.
+        *
+        * @since 1.32
+        *
+        * @param array $options Any combination of the following strings
+        *  - 'content': Join with the content table, and select content meta-data fields
+        *
+        * @return array With three keys:
+        *  - tables: (string[]) to include in the `$table` to `IDatabase->select()`
+        *  - fields: (string[]) to include in the `$vars` to `IDatabase->select()`
+        *  - joins: (array) to include in the `$join_conds` to `IDatabase->select()`
+        */
+       public function getSlotsQueryInfo( $options = [] ) {
+               $ret = [
+                       'tables' => [],
+                       'fields' => [],
+                       'joins'  => [],
+               ];
+
+               if ( $this->hasMcrSchemaFlags( SCHEMA_COMPAT_READ_OLD ) ) {
+                       $db = $this->getDBConnectionRef( DB_REPLICA );
+                       $ret['tables']['slots'] = 'revision';
+
+                       $ret['fields']['slot_revision_id'] = 'slots.rev_id';
+                       $ret['fields']['slot_content_id'] = 'NULL';
+                       $ret['fields']['slot_origin'] = 'slots.rev_id';
+                       $ret['fields']['role_name'] = $db->addQuotes( 'main' );
+
+                       if ( in_array( 'content', $options, true ) ) {
+                               $ret['fields']['content_size'] = 'slots.rev_len';
+                               $ret['fields']['content_sha1'] = 'slots.rev_sha1';
+                               $ret['fields']['content_address']
+                                       = $db->buildConcat( [ $db->addQuotes( 'tt:' ), 'slots.rev_text_id' ] );
+
+                               if ( $this->contentHandlerUseDB ) {
+                                       $ret['fields']['model_name'] = 'slots.rev_content_model';
+                               } else {
+                                       $ret['fields']['model_name'] = 'NULL';
+                               }
+                       }
+               } else {
+                       $ret['tables'][] = 'slots';
+                       $ret['tables'][] = 'slot_roles';
+                       $ret['fields'] = array_merge( $ret['fields'], [
+                               'slot_revision_id',
+                               'slot_content_id',
+                               'slot_origin',
+                               'role_name'
+                       ] );
+                       $ret['joins']['slot_roles'] = [ 'INNER JOIN', [ 'slot_role_id = role_id' ] ];
+
+                       if ( in_array( 'content', $options, true ) ) {
+                               $ret['tables'][] = 'content';
+                               $ret['tables'][] = 'content_models';
+                               $ret['fields'] = array_merge( $ret['fields'], [
+                                       'content_size',
+                                       'content_sha1',
+                                       'content_address',
+                                       'model_name'
+                               ] );
+                               $ret['joins']['content'] = [ 'INNER JOIN', [ 'slot_content_id = content_id' ] ];
+                               $ret['joins']['content_models'] = [ 'INNER JOIN', [ 'content_model = model_id' ] ];
+                       }
+               }
+
+               return $ret;
+       }
+
+       /**
+        * Return the tables, fields, and join conditions to be selected to create
+        * a new RevisionArchiveRecord object.
         *
         * MCR migration note: this replaces Revision::getArchiveQueryInfo
         *
@@ -1701,7 +2257,6 @@ class RevisionStore
                                        'ar_namespace',
                                        'ar_title',
                                        'ar_rev_id',
-                                       'ar_text_id',
                                        'ar_timestamp',
                                        'ar_minor_edit',
                                        'ar_deleted',
@@ -1712,9 +2267,13 @@ class RevisionStore
                        'joins' => $commentQuery['joins'] + $actorQuery['joins'],
                ];
 
-               if ( $this->contentHandlerUseDB ) {
-                       $ret['fields'][] = 'ar_content_format';
-                       $ret['fields'][] = 'ar_content_model';
+               if ( $this->hasMcrSchemaFlags( SCHEMA_COMPAT_READ_OLD ) ) {
+                       $ret['fields'][] = 'ar_text_id';
+
+                       if ( $this->contentHandlerUseDB ) {
+                               $ret['fields'][] = 'ar_content_format';
+                               $ret['fields'][] = 'ar_content_model';
+                       }
                }
 
                return $ret;
@@ -1773,7 +2332,7 @@ class RevisionStore
         * MCR migration note: this replaces Revision::getPrevious
         *
         * @param RevisionRecord $rev
-        * @param Title $title if known (optional)
+        * @param Title|null $title if known (optional)
         *
         * @return RevisionRecord|null
         */
@@ -1794,7 +2353,7 @@ class RevisionStore
         * MCR migration note: this replaces Revision::getNext
         *
         * @param RevisionRecord $rev
-        * @param Title $title if known (optional)
+        * @param Title|null $title if known (optional)
         *
         * @return RevisionRecord|null
         */
@@ -1855,15 +2414,12 @@ class RevisionStore
         * @return string|bool False if not found
         */
        public function getTimestampFromId( $title, $id, $flags = 0 ) {
-               $db = $this->getDBConnection(
-                       ( $flags & IDBAccessObject::READ_LATEST ) ? DB_MASTER : DB_REPLICA
-               );
+               $db = $this->getDBConnectionRefForQueryFlags( $flags );
 
                $conds = [ 'rev_id' => $id ];
                $conds['rev_page'] = $title->getArticleID();
                $timestamp = $db->selectField( 'revision', 'rev_timestamp', $conds, __METHOD__ );
 
-               $this->releaseDBConnection( $db );
                return ( $timestamp !== false ) ? wfTimestamp( TS_MW, $timestamp ) : false;
        }
 
@@ -1932,7 +2488,7 @@ class RevisionStore
                        return false;
                }
 
-               $revQuery = self::getQueryInfo();
+               $revQuery = $this->getQueryInfo();
                $res = $db->select(
                        $revQuery['tables'],
                        [
@@ -1990,7 +2546,7 @@ class RevisionStore
 
                $row = $this->cache->getWithSetCallback(
                        // Page/rev IDs passed in from DB to reflect history merges
-                       $this->cache->makeGlobalKey( 'revision-row-1.29', $db->getDomainID(), $pageId, $revId ),
+                       $this->getRevisionRowCacheKey( $db, $pageId, $revId ),
                        WANObjectCache::TTL_WEEK,
                        function ( $curValue, &$ttl, array &$setOpts ) use ( $db, $pageId, $revId ) {
                                $setOpts += Database::getCacheSetOptions( $db );
@@ -2014,6 +2570,26 @@ class RevisionStore
                }
        }
 
+       /**
+        * Get a cache key for use with a row as selected with getQueryInfo( [ 'page', 'user' ] )
+        * Caching rows without 'page' or 'user' could lead to issues.
+        * If the format of the rows returned by the query provided by getQueryInfo changes the
+        * cache key should be updated to avoid conflicts.
+        *
+        * @param IDatabase $db
+        * @param int $pageId
+        * @param int $revId
+        * @return string
+        */
+       private function getRevisionRowCacheKey( IDatabase $db, $pageId, $revId ) {
+               return $this->cache->makeGlobalKey(
+                       self::ROW_CACHE_KEY,
+                       $db->getDomainID(),
+                       $pageId,
+                       $revId
+               );
+       }
+
        // TODO: move relevant methods from Title here, e.g. getFirstRevision, isBigDeletion, etc.
 
 }
index 9462518..dff4b03 100644 (file)
@@ -38,7 +38,9 @@ use Wikimedia\Assert\Assert;
 class SlotRecord {
 
        /**
-        * @var object database result row, as a raw object
+        * @var object database result row, as a raw object. Callbacks are supported for field values,
+        *      to enable on-demand emulation of these values. This is primarily intended for use
+        *      during schema migration.
         */
        private $row;
 
@@ -142,11 +144,11 @@ class SlotRecord {
        /**
         * Constructs a complete SlotRecord for a newly saved revision, based on the incomplete
         * proto-slot. This adds information that has only become available during saving,
-        * particularly the revision ID and content address.
+        * particularly the revision ID, content ID and content address.
         *
         * @param int $revisionId the revision the slot is to be associated with (field slot_revision_id).
         *        If $protoSlot already has a revision, it must be the same.
-        * @param int $contentId the ID of the row in the content table describing the content
+        * @param int|null $contentId the ID of the row in the content table describing the content
         *        referenced by $contentAddress (field slot_content_id).
         *        If $protoSlot already has a content ID, it must be the same.
         * @param string $contentAddress the slot's content address (field content_address).
@@ -163,7 +165,8 @@ class SlotRecord {
                SlotRecord $protoSlot
        ) {
                Assert::parameterType( 'integer', $revisionId, '$revisionId' );
-               Assert::parameterType( 'integer', $contentId, '$contentId' );
+               // TODO once migration is over $contentId must be an integer
+               Assert::parameterType( 'integer|null', $contentId, '$contentId' );
                Assert::parameterType( 'string', $contentAddress, '$contentAddress' );
 
                if ( $protoSlot->hasRevision() && $protoSlot->getRevision() !== $revisionId ) {
@@ -181,7 +184,7 @@ class SlotRecord {
                        );
                }
 
-               if ( $protoSlot->hasAddress() && $protoSlot->getContentId() !== $contentId ) {
+               if ( $protoSlot->hasContentId() && $protoSlot->getContentId() !== $contentId ) {
                        throw new LogicException(
                                "Mismatching content ID $contentId: "
                                . "The slot already has content row {$protoSlot->getContentId()} associated."
@@ -231,11 +234,6 @@ class SlotRecord {
                Assert::parameterType( 'object', $row, '$row' );
                Assert::parameterType( 'Content|callable', $content, '$content' );
 
-               Assert::parameter(
-                       property_exists( $row, 'slot_id' ),
-                       '$row->slot_id',
-                       'must exist'
-               );
                Assert::parameter(
                        property_exists( $row, 'slot_revision_id' ),
                        '$row->slot_revision_id',
@@ -379,6 +377,13 @@ class SlotRecord {
         * @return bool whether this record contains the given field
         */
        private function hasField( $name ) {
+               if ( isset( $this->row->$name ) ) {
+                       // if the field is a callback, resolve first, then re-check
+                       if ( !is_string( $this->row->$name ) && is_callable( $this->row->$name ) ) {
+                               $this->getField( $name );
+                       }
+               }
+
                return isset( $this->row->$name );
        }
 
@@ -430,6 +435,30 @@ class SlotRecord {
                return $this->hasField( 'content_address' );
        }
 
+       /**
+        * Whether this slot has an origin (revision ID that originated the slot's content.
+        *
+        * @since 1.32
+        *
+        * @return bool
+        */
+       public function hasOrigin() {
+               return $this->hasField( 'slot_origin' );
+       }
+
+       /**
+        * Whether this slot has a content ID. Slots will have a content ID if their
+        * content has been stored in the content table. While building a new revision,
+        * SlotRecords will not have an ID associated.
+        *
+        * @since 1.32
+        *
+        * @return bool
+        */
+       public function hasContentId() {
+               return $this->hasField( 'slot_content_id' );
+       }
+
        /**
         * Whether this slot has revision ID associated. Slots will have a revision ID associated
         * only if they were loaded as part of an existing revision. While building a new revision,
index 72de2c9..48ffe2c 100644 (file)
@@ -267,8 +267,7 @@ class SqlBlobStore implements IDBAccessObject, BlobStore {
 
                // No negative caching; negative hits on text rows may be due to corrupted replica DBs
                $blob = $this->cache->getWithSetCallback(
-                       // TODO: change key, since this is not necessarily revision text!
-                       $this->cache->makeKey( 'revisiontext', 'textid', $blobAddress ),
+                       $this->getCacheKey( $blobAddress ),
                        $this->getCacheTTL(),
                        function ( $unused, &$ttl, &$setOpts ) use ( $blobAddress, $queryFlags ) {
                                list( $index ) = DBAccessObjectUtils::getDBOptions( $queryFlags );
@@ -349,13 +348,32 @@ class SqlBlobStore implements IDBAccessObject, BlobStore {
                $blob = $this->expandBlob( $row->old_text, $row->old_flags, $blobAddress );
 
                if ( $blob === false ) {
-                       wfWarn( __METHOD__ . ": Bad data in text row $textId." );
+                       wfLogWarning( __METHOD__ . ": Bad data in text row $textId." );
                        return false;
                }
 
                return $blob;
        }
 
+       /**
+        * Get a cache key for a given Blob address.
+        *
+        * The cache key is constructed in a way that allows cached blobs from the same database
+        * to be re-used between wikis. For example, enwiki and frwiki will use the same cache keys
+        * for blobs from the wikidatawiki database.
+        *
+        * @param string $blobAddress
+        * @return string
+        */
+       private function getCacheKey( $blobAddress ) {
+               return $this->cache->makeGlobalKey(
+                       'BlobStore',
+                       'address',
+                       $this->dbLoadBalancer->resolveDomainID( $this->wikiId ),
+                       $blobAddress
+               );
+       }
+
        /**
         * Expand a raw data blob according to the flags given.
         *
@@ -370,7 +388,8 @@ class SqlBlobStore implements IDBAccessObject, BlobStore {
         * @param string|string[] $flags Blob flags, such as 'external' or 'gzip'.
         *   Note that not including 'utf-8' in $flags will cause the data to be decoded
         *   according to the legacy encoding specified via setLegacyEncoding.
-        * @param string|null $cacheKey May be used for caching if given
+        * @param string|null $cacheKey A blob address for use in the cache key. If not given,
+        *   caching is disabled.
         *
         * @return false|string The expanded blob or false on failure
         */
@@ -387,25 +406,22 @@ class SqlBlobStore implements IDBAccessObject, BlobStore {
                                return false;
                        }
 
-                       if ( $cacheKey && $this->wikiId === false ) {
-                               // Make use of the wiki-local revision text cache.
+                       if ( $cacheKey ) {
                                // The cached value should be decompressed, so handle that and return here.
-                               // NOTE: we rely on $this->cache being the right cache for $this->wikiId!
                                return $this->cache->getWithSetCallback(
-                                       // TODO: change key, since this is not necessarily revision text!
-                                       $this->cache->makeKey( 'revisiontext', 'textid', $cacheKey ),
+                                       $this->getCacheKey( $cacheKey ),
                                        $this->getCacheTTL(),
                                        function () use ( $url, $flags ) {
                                                // No negative caching per BlobStore::getBlob()
                                                $blob = ExternalStore::fetchFromURL( $url, [ 'wiki' => $this->wikiId ] );
 
-                                               return $this->decompressData( $blob, $flags );
+                                               return $blob === false ? false : $this->decompressData( $blob, $flags );
                                        },
                                        [ 'pcGroup' => self::TEXT_CACHE_GROUP, 'pcTTL' => WANObjectCache::TTL_PROC_LONG ]
                                );
                        } else {
                                $blob = ExternalStore::fetchFromURL( $url, [ 'wiki' => $this->wikiId ] );
-                               return $this->decompressData( $blob, $flags );
+                               return $blob === false ? false : $this->decompressData( $blob, $flags );
                        }
                } else {
                        return $this->decompressData( $raw, $flags );
@@ -461,7 +477,7 @@ class SqlBlobStore implements IDBAccessObject, BlobStore {
         * @note direct use is deprecated, use getBlob() or SlotRecord::getContent() instead.
         * @todo make this private, there should be no need to use this method outside this class.
         *
-        * @param mixed $blob Reference to a text
+        * @param string $blob Blob in compressed/encoded form.
         * @param array $blobFlags Compression flags, such as 'gzip'.
         *   Note that not including 'utf-8' in $blobFlags will cause the data to be decoded
         *   according to the legacy encoding specified via setLegacyEncoding.
@@ -469,10 +485,8 @@ class SqlBlobStore implements IDBAccessObject, BlobStore {
         * @return string|bool Decompressed text, or false on failure
         */
        public function decompressData( $blob, array $blobFlags ) {
-               if ( $blob === false ) {
-                       // Text failed to be fetched; nothing to do
-                       return false;
-               }
+               // Revision::decompressRevisionText accepted false here, so defend against that
+               Assert::parameterType( 'string', $blob, '$blob' );
 
                if ( in_array( 'error', $blobFlags ) ) {
                        // Error row, return false
@@ -486,7 +500,7 @@ class SqlBlobStore implements IDBAccessObject, BlobStore {
                        $blob = gzinflate( $blob );
 
                        if ( $blob === false ) {
-                               wfLogWarning( __METHOD__ . ': gzinflate() failed' );
+                               wfWarn( __METHOD__ . ': gzinflate() failed' );
                                return false;
                        }
                }
index 067f11f..9213076 100644 (file)
@@ -56,8 +56,8 @@ class StubObject {
        protected $params;
 
        /**
-        * @param string $global Name of the global variable.
-        * @param string|callable $class Name of the class of the real object
+        * @param string|null $global Name of the global variable.
+        * @param string|callable|null $class Name of the class of the real object
         *                               or a factory function to call
         * @param array $params Parameters to pass to constructor of the real object.
         */
index 2293dab..dc7d31e 100644 (file)
@@ -46,7 +46,7 @@ class TemplateParser {
        protected $compileFlags = LightnCandy::FLAG_ERROR_EXCEPTION;
 
        /**
-        * @param string $templateDir
+        * @param string|null $templateDir
         * @param bool $forceRecompile
         */
        public function __construct( $templateDir = null, $forceRecompile = false ) {
@@ -209,8 +209,11 @@ class TemplateParser {
         *     );
         * @endcode
         * @param string $templateName The name of the template
+        * @param-taint $templateName exec_misc
         * @param mixed $args
+        * @param-taint $args none
         * @param array $scopes
+        * @param-taint $scopes none
         * @return string
         */
        public function processTemplate( $templateName, $args, array $scopes = [] ) {
index fd7451c..cc7d722 100644 (file)
@@ -37,7 +37,7 @@ use MediaWiki\MediaWikiServices;
  *       and does not rely on global state or the database.
  */
 class Title implements LinkTarget {
-       /** @var HashBagOStuff */
+       /** @var MapCacheLRU */
        static private $titleCache = null;
 
        /**
@@ -306,6 +306,10 @@ class Title implements LinkTarget {
        public static function newFromTextThrow( $text, $defaultNamespace = NS_MAIN ) {
                if ( is_object( $text ) ) {
                        throw new MWException( '$text must be a string, given an object' );
+               } elseif ( $text === null ) {
+                       // Legacy code relies on MalformedTitleException being thrown in this case
+                       // (happens when URL with no title in it is parsed). TODO fix
+                       throw new MalformedTitleException( 'title-invalid-empty' );
                }
 
                $titleCache = self::getTitleCache();
@@ -371,11 +375,11 @@ class Title implements LinkTarget {
        }
 
        /**
-        * @return HashBagOStuff
+        * @return MapCacheLRU
         */
        private static function getTitleCache() {
                if ( self::$titleCache == null ) {
-                       self::$titleCache = new HashBagOStuff( [ 'maxKeys' => self::CACHE_MAX ] );
+                       self::$titleCache = new MapCacheLRU( self::CACHE_MAX );
                }
                return self::$titleCache;
        }
@@ -784,11 +788,8 @@ class Title implements LinkTarget {
         * @return int Result of string comparison, or namespace comparison
         */
        public static function compare( LinkTarget $a, LinkTarget $b ) {
-               if ( $a->getNamespace() == $b->getNamespace() ) {
-                       return strcmp( $a->getText(), $b->getText() );
-               } else {
-                       return $a->getNamespace() - $b->getNamespace();
-               }
+               return $a->getNamespace() <=> $b->getNamespace()
+                       ?: strcmp( $a->getText(), $b->getText() );
        }
 
        /**
@@ -982,7 +983,7 @@ class Title implements LinkTarget {
                        && ( !$this->mContentModel || $flags === self::GAID_FOR_UPDATE )
                        && $this->getArticleID( $flags )
                ) {
-                       $linkCache = LinkCache::singleton();
+                       $linkCache = MediaWikiServices::getInstance()->getLinkCache();
                        $linkCache->addLinkObj( $this ); # in case we already had an article ID
                        $this->mContentModel = $linkCache->getGoodLinkFieldObj( $this, 'model' );
                }
@@ -1292,12 +1293,9 @@ class Title implements LinkTarget {
         */
        public function isSiteConfigPage() {
                return (
-                       NS_MEDIAWIKI == $this->mNamespace
-                       && (
-                               $this->hasContentModel( CONTENT_MODEL_CSS )
-                               || $this->hasContentModel( CONTENT_MODEL_JSON )
-                               || $this->hasContentModel( CONTENT_MODEL_JAVASCRIPT )
-                       )
+                       $this->isSiteCssConfigPage()
+                       || $this->isSiteJsonConfigPage()
+                       || $this->isSiteJsConfigPage()
                );
        }
 
@@ -1320,13 +1318,9 @@ class Title implements LinkTarget {
         */
        public function isUserConfigPage() {
                return (
-                       NS_USER == $this->mNamespace
-                       && $this->isSubpage()
-                       && (
-                               $this->hasContentModel( CONTENT_MODEL_CSS )
-                               || $this->hasContentModel( CONTENT_MODEL_JSON )
-                               || $this->hasContentModel( CONTENT_MODEL_JAVASCRIPT )
-                       )
+                       $this->isUserCssConfigPage()
+                       || $this->isUserJsonConfigPage()
+                       || $this->isUserJsConfigPage()
                );
        }
 
@@ -1426,6 +1420,60 @@ class Title implements LinkTarget {
                return $this->isUserJsConfigPage();
        }
 
+       /**
+        * Is this a sitewide CSS "config" page?
+        *
+        * @return bool
+        * @since 1.32
+        */
+       public function isSiteCssConfigPage() {
+               return (
+                       NS_MEDIAWIKI == $this->mNamespace
+                       && (
+                               $this->hasContentModel( CONTENT_MODEL_CSS )
+                               // paranoia - a MediaWiki: namespace page with mismatching extension and content
+                               // model is probably by mistake and might get handled incorrectly (see e.g. T112937)
+                               || substr( $this->getDBkey(), -4 ) === '.css'
+                       )
+               );
+       }
+
+       /**
+        * Is this a sitewide JSON "config" page?
+        *
+        * @return bool
+        * @since 1.32
+        */
+       public function isSiteJsonConfigPage() {
+               return (
+                       NS_MEDIAWIKI == $this->mNamespace
+                       && (
+                               $this->hasContentModel( CONTENT_MODEL_JSON )
+                               // paranoia - a MediaWiki: namespace page with mismatching extension and content
+                               // model is probably by mistake and might get handled incorrectly (see e.g. T112937)
+                               || substr( $this->getDBkey(), -5 ) === '.json'
+                       )
+               );
+       }
+
+       /**
+        * Is this a sitewide JS "config" page?
+        *
+        * @return bool
+        * @since 1.31
+        */
+       public function isSiteJsConfigPage() {
+               return (
+                       NS_MEDIAWIKI == $this->mNamespace
+                       && (
+                               $this->hasContentModel( CONTENT_MODEL_JAVASCRIPT )
+                               // paranoia - a MediaWiki: namespace page with mismatching extension and content
+                               // model is probably by mistake and might get handled incorrectly (see e.g. T112937)
+                               || substr( $this->getDBkey(), -3 ) === '.js'
+                       )
+               );
+       }
+
        /**
         * Is this a talk page of some sort?
         *
@@ -2089,7 +2137,7 @@ class Title implements LinkTarget {
         * May provide false positives, but should never provide a false negative.
         *
         * @param string $action Action that permission needs to be checked for
-        * @param User $user User to check (since 1.19); $wgUser will be used if not provided.
+        * @param User|null $user User to check (since 1.19); $wgUser will be used if not provided.
         * @return bool
         */
        public function quickUserCan( $action, $user = null ) {
@@ -2100,7 +2148,7 @@ class Title implements LinkTarget {
         * Can $user perform $action on this page?
         *
         * @param string $action Action that permission needs to be checked for
-        * @param User $user User to check (since 1.19); $wgUser will be used if not
+        * @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
@@ -2316,6 +2364,44 @@ class Title implements LinkTarget {
                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 ];
+                       }
+
+                       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
         *
@@ -2556,7 +2642,10 @@ class Title implements LinkTarget {
                        return $errors;
                }
 
-               if ( $wgEmailConfirmToEdit && !$user->isEmailConfirmed() ) {
+               if ( $wgEmailConfirmToEdit
+                       && !$user->isEmailConfirmed()
+                       && $action === 'edit'
+               ) {
                        $errors[] = [ 'confirmedittext' ];
                }
 
@@ -2701,10 +2790,10 @@ class Title implements LinkTarget {
                                'checkReadPermissions',
                                'checkUserBlock', // for wgBlockDisablesLogin
                        ];
-               # Don't call checkSpecialsAndNSPermissions 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.
+               # 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',
@@ -2719,6 +2808,7 @@ class Title implements LinkTarget {
                                'checkQuickPermissions',
                                'checkPermissionHooks',
                                'checkSpecialsAndNSPermissions',
+                               'checkSiteConfigPermissions',
                                'checkUserConfigPermissions',
                                'checkPageRestrictions',
                                'checkCascadingSourcesRestrictions',
@@ -3089,9 +3179,7 @@ class Title implements LinkTarget {
                if ( !$this->mRestrictionsLoaded ) {
                        $this->loadRestrictions();
                }
-               return isset( $this->mRestrictions[$action] )
-                               ? $this->mRestrictions[$action]
-                               : [];
+               return $this->mRestrictions[$action] ?? [];
        }
 
        /**
@@ -3119,7 +3207,7 @@ class Title implements LinkTarget {
                if ( !$this->mRestrictionsLoaded ) {
                        $this->loadRestrictions();
                }
-               return isset( $this->mRestrictionsExpiry[$action] ) ? $this->mRestrictionsExpiry[$action] : false;
+               return $this->mRestrictionsExpiry[$action] ?? false;
        }
 
        /**
@@ -3141,7 +3229,7 @@ class Title implements LinkTarget {
         * Public for usage by LiquidThreads.
         *
         * @param array $rows Array of db result objects
-        * @param string $oldFashionedRestrictions Comma-separated set of permission keys
+        * @param string|null $oldFashionedRestrictions Comma-separated set of permission keys
         * indicating who can move or edit the page from the page table, (pre 1.10) rows.
         * Edit and move sections are separated by a colon
         * Example: "edit=autoconfirmed,sysop:move=sysop"
@@ -3213,7 +3301,7 @@ class Title implements LinkTarget {
        /**
         * Load restrictions from the page_restrictions table
         *
-        * @param string $oldFashionedRestrictions Comma-separated set of permission keys
+        * @param string|null $oldFashionedRestrictions Comma-separated set of permission keys
         * indicating who can move or edit the page from the page table, (pre 1.10) rows.
         * Edit and move sections are separated by a colon
         * Example: "edit=autoconfirmed,sysop:move=sysop"
@@ -3435,7 +3523,7 @@ class Title implements LinkTarget {
                        $this->mArticleID = 0;
                        return $this->mArticleID;
                }
-               $linkCache = LinkCache::singleton();
+               $linkCache = MediaWikiServices::getInstance()->getLinkCache();
                if ( $flags & self::GAID_FOR_UPDATE ) {
                        $oldUpdate = $linkCache->forUpdate( true );
                        $linkCache->clearLink( $this );
@@ -3465,7 +3553,7 @@ class Title implements LinkTarget {
                        return $this->mRedirect;
                }
 
-               $linkCache = LinkCache::singleton();
+               $linkCache = MediaWikiServices::getInstance()->getLinkCache();
                $linkCache->addLinkObj( $this ); # in case we already had an article ID
                $cached = $linkCache->getGoodLinkFieldObj( $this, 'redirect' );
                if ( $cached === null ) {
@@ -3499,7 +3587,7 @@ class Title implements LinkTarget {
                        $this->mLength = 0;
                        return $this->mLength;
                }
-               $linkCache = LinkCache::singleton();
+               $linkCache = MediaWikiServices::getInstance()->getLinkCache();
                $linkCache->addLinkObj( $this ); # in case we already had an article ID
                $cached = $linkCache->getGoodLinkFieldObj( $this, 'length' );
                if ( $cached === null ) {
@@ -3527,7 +3615,7 @@ class Title implements LinkTarget {
                        $this->mLatestID = 0;
                        return $this->mLatestID;
                }
-               $linkCache = LinkCache::singleton();
+               $linkCache = MediaWikiServices::getInstance()->getLinkCache();
                $linkCache->addLinkObj( $this ); # in case we already had an article ID
                $cached = $linkCache->getGoodLinkFieldObj( $this, 'revision' );
                if ( $cached === null ) {
@@ -3552,7 +3640,7 @@ class Title implements LinkTarget {
         * @param int $newid The new Article ID
         */
        public function resetArticleID( $newid ) {
-               $linkCache = LinkCache::singleton();
+               $linkCache = MediaWikiServices::getInstance()->getLinkCache();
                $linkCache->clearLink( $this );
 
                if ( $newid === false ) {
@@ -3574,7 +3662,7 @@ class Title implements LinkTarget {
        }
 
        public static function clearCaches() {
-               $linkCache = LinkCache::singleton();
+               $linkCache = MediaWikiServices::getInstance()->getLinkCache();
                $linkCache->clear();
 
                $titleCache = self::getTitleCache();
@@ -3678,7 +3766,7 @@ class Title implements LinkTarget {
 
                $retVal = [];
                if ( $res->numRows() ) {
-                       $linkCache = LinkCache::singleton();
+                       $linkCache = MediaWikiServices::getInstance()->getLinkCache();
                        foreach ( $res as $row ) {
                                $titleObj = self::makeTitle( $row->page_namespace, $row->page_title );
                                if ( $titleObj ) {
@@ -3746,7 +3834,7 @@ class Title implements LinkTarget {
                );
 
                $retVal = [];
-               $linkCache = LinkCache::singleton();
+               $linkCache = MediaWikiServices::getInstance()->getLinkCache();
                foreach ( $res as $row ) {
                        if ( $row->page_id ) {
                                $titleObj = self::newFromRow( $row );
@@ -4683,7 +4771,7 @@ class Title implements LinkTarget {
        /**
         * Updates page_touched for this page; called from LinksUpdate.php
         *
-        * @param string $purgeTime [optional] TS_MW timestamp
+        * @param string|null $purgeTime [optional] TS_MW timestamp
         * @return bool True if the update succeeded
         */
        public function invalidateCache( $purgeTime = null ) {
@@ -4754,7 +4842,7 @@ class Title implements LinkTarget {
        /**
         * Get the timestamp when this page was updated since the user last saw it.
         *
-        * @param User $user
+        * @param User|null $user
         * @return string|null
         */
        public function getNotificationTimestamp( $user = null ) {
@@ -4945,7 +5033,7 @@ class Title implements LinkTarget {
                // check, if the page language could be saved in the database, and if so and
                // the value is not requested already, lookup the page language using LinkCache
                if ( $wgPageLanguageUseDB && $this->mDbPageLanguage === false ) {
-                       $linkCache = LinkCache::singleton();
+                       $linkCache = MediaWikiServices::getInstance()->getLinkCache();
                        $linkCache->addLinkObj( $this );
                        $this->mDbPageLanguage = $linkCache->getGoodLinkFieldObj( $this, 'lang' );
                }
@@ -4985,7 +5073,7 @@ class Title implements LinkTarget {
                        $langObj = $contentHandler->getPageLanguage( $this );
                        $this->mPageLanguage = [ $langObj->getCode(), $wgLanguageCode ];
                } else {
-                       $langObj = wfGetLangObj( $this->mPageLanguage[0] );
+                       $langObj = Language::factory( $this->mPageLanguage[0] );
                }
 
                return $langObj;
index e0b8de7..e31d3f9 100644 (file)
@@ -129,7 +129,7 @@ class WebRequest {
                        $a = parse_url( $url );
                        Wikimedia\restoreWarnings();
                        if ( $a ) {
-                               $path = isset( $a['path'] ) ? $a['path'] : '';
+                               $path = $a['path'] ?? '';
 
                                global $wgScript;
                                if ( $path == $wgScript && $want !== 'all' ) {
@@ -275,8 +275,7 @@ class WebRequest {
                // This method is called from various error handlers and should be kept simple.
 
                if ( !self::$reqId ) {
-                       self::$reqId = isset( $_SERVER['UNIQUE_ID'] )
-                               ? $_SERVER['UNIQUE_ID'] : wfRandomString( 24 );
+                       self::$reqId = $_SERVER['UNIQUE_ID'] ?? wfRandomString( 24 );
                }
 
                return self::$reqId;
@@ -458,7 +457,7 @@ class WebRequest {
         * @return mixed Old value if one was present, null otherwise
         */
        public function setVal( $key, $value ) {
-               $ret = isset( $this->data[$key] ) ? $this->data[$key] : null;
+               $ret = $this->data[$key] ?? null;
                $this->data[$key] = $value;
                return $ret;
        }
@@ -485,7 +484,7 @@ class WebRequest {
         * If no source and no default, returns null.
         *
         * @param string $name
-        * @param array $default Optional default (or null)
+        * @param array|null $default Optional default (or null)
         * @return array|null
         */
        public function getArray( $name, $default = null ) {
@@ -504,7 +503,7 @@ class WebRequest {
         * If an array is returned, contents are guaranteed to be integers.
         *
         * @param string $name
-        * @param array $default Option default (or null)
+        * @param array|null $default Option default (or null)
         * @return array Array of ints
         */
        public function getIntArray( $name, $default = null ) {
@@ -714,7 +713,7 @@ class WebRequest {
         * @return string
         */
        public function getMethod() {
-               return isset( $_SERVER['REQUEST_METHOD'] ) ? $_SERVER['REQUEST_METHOD'] : 'GET';
+               return $_SERVER['REQUEST_METHOD'] ?? 'GET';
        }
 
        /**
@@ -777,8 +776,8 @@ class WebRequest {
         * Get a cookie from the $_COOKIE jar
         *
         * @param string $key The name of the cookie
-        * @param string $prefix A prefix to use for the cookie name, if not $wgCookiePrefix
-        * @param mixed $default What to return if the value isn't found
+        * @param string|null $prefix A prefix to use for the cookie name, if not $wgCookiePrefix
+        * @param mixed|null $default What to return if the value isn't found
         * @return mixed Cookie value or $default if the cookie not set
         */
        public function getCookie( $key, $prefix = null, $default = null ) {
@@ -857,7 +856,7 @@ class WebRequest {
         * @return string
         */
        public function getFullRequestURL() {
-               return wfExpandUrl( $this->getRequestURL(), PROTO_CURRENT );
+               return wfGetServerUrl( PROTO_CURRENT ) .  $this->getRequestURL();
        }
 
        /**
index 0208a72..3a4faf0 100644 (file)
@@ -32,6 +32,22 @@ class WebResponse {
         */
        protected static $setCookies = [];
 
+       /** @var bool Used to disable setters before running jobs post-request (T191537) */
+       protected static $disableForPostSend = false;
+
+       /**
+        * Disable setters for post-send processing
+        *
+        * After this call, self::setCookie(), self::header(), and
+        * self::statusHeader() will log a warning and return without
+        * setting cookies or headers.
+        *
+        * @since 1.32
+        */
+       public static function disableForPostSend() {
+               self::$disableForPostSend = true;
+       }
+
        /**
         * Output an HTTP header, wrapper for PHP's header()
         * @param string $string Header to output
@@ -39,6 +55,16 @@ class WebResponse {
         * @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 ( self::$disableForPostSend ) {
+                       wfDebugLog( 'header', 'ignored post-send header {header}', 'all', [
+                               'header' => $string,
+                               'replace' => $replace,
+                               'http_response_code' => $http_response_code,
+                               'exception' => new RuntimeException( 'Ignored post-send header' ),
+                       ] );
+                       return;
+               }
+
                \MediaWiki\HeaderCallback::warnIfHeadersSent();
                if ( $http_response_code ) {
                        header( $string, $replace, $http_response_code );
@@ -69,6 +95,14 @@ class WebResponse {
         * @param int $code Status code
         */
        public function statusHeader( $code ) {
+               if ( self::$disableForPostSend ) {
+                       wfDebugLog( 'header', 'ignored post-send status header {code}', 'all', [
+                               'code' => $code,
+                               'exception' => new RuntimeException( 'Ignored post-send status header' ),
+                       ] );
+                       return;
+               }
+
                HttpStatus::header( $code );
        }
 
@@ -117,9 +151,29 @@ class WebResponse {
                        $expire = time() + $wgCookieExpiration;
                }
 
+               if ( self::$disableForPostSend ) {
+                       $cookie = $options['prefix'] . $name;
+                       wfDebugLog( 'cookie', 'ignored post-send cookie {cookie}', 'all', [
+                               'cookie' => $cookie,
+                               'data' => [
+                                       'name' => (string)$cookie,
+                                       'value' => (string)$value,
+                                       'expire' => (int)$expire,
+                                       'path' => (string)$options['path'],
+                                       'domain' => (string)$options['domain'],
+                                       'secure' => (bool)$options['secure'],
+                                       'httpOnly' => (bool)$options['httpOnly'],
+                               ],
+                               'exception' => new RuntimeException( 'Ignored post-send cookie' ),
+                       ] );
+                       return;
+               }
+
                $func = $options['raw'] ? 'setrawcookie' : 'setcookie';
 
                if ( Hooks::run( 'WebResponseSetCookie', [ &$name, &$value, &$expire, &$options ] ) ) {
+                       // Note: Don't try to move this earlier to reuse it for self::$disableForPostSend,
+                       // we need to use the altered values from the hook here. (T198525)
                        $cookie = $options['prefix'] . $name;
                        $data = [
                                'name' => (string)$cookie,
@@ -234,10 +288,7 @@ class FauxResponse extends WebResponse {
        public function getHeader( $key ) {
                $key = strtoupper( $key );
 
-               if ( isset( $this->headers[$key] ) ) {
-                       return $this->headers[$key];
-               }
-               return null;
+               return $this->headers[$key] ?? null;
        }
 
        /**
@@ -303,10 +354,7 @@ class FauxResponse extends WebResponse {
         * @return array|null
         */
        public function getCookieData( $name ) {
-               if ( isset( $this->cookies[$name] ) ) {
-                       return $this->cookies[$name];
-               }
-               return null;
+               return $this->cookies[$name] ?? null;
        }
 
        /**
index 8bb37b5..9dc3bfe 100644 (file)
@@ -104,7 +104,7 @@ class WikiMap {
                        $path .= '?' . $urlParts['query'];
                }
 
-               $canonicalServer = isset( $urlParts['scheme'] ) ? $urlParts['scheme'] : 'http';
+               $canonicalServer = $urlParts['scheme'] ?? 'http';
                $canonicalServer .= '://' . $urlParts['host'];
 
                return new WikiReference( $canonicalServer, $path );
@@ -131,7 +131,7 @@ class WikiMap {
         *
         * @param string $wikiID Wiki'd id (generally database name)
         * @param string $user User name (must be normalised before calling this function!)
-        * @param string $text Link's text; optional, default to "User:$user"
+        * @param string|null $text Link's text; optional, default to "User:$user"
         * @return string HTML link or false if the wiki was not found
         */
        public static function foreignUserLink( $wikiID, $user, $text = null ) {
@@ -143,7 +143,7 @@ class WikiMap {
         *
         * @param string $wikiID Wiki'd id (generally database name)
         * @param string $page Page name (must be normalised before calling this function!)
-        * @param string $text Link's text; optional, default to $page
+        * @param string|null $text Link's text; optional, default to $page
         * @return string|false HTML link or false if the wiki was not found
         */
        public static function makeForeignLink( $wikiID, $page, $text = null ) {
index 724ba98..d3688c8 100644 (file)
@@ -36,7 +36,7 @@ class WikiReference {
        public function __construct( $canonicalServer, $path, $server = null ) {
                $this->mCanonicalServer = $canonicalServer;
                $this->mPath = $path;
-               $this->mServer = $server === null ? $canonicalServer : $server;
+               $this->mServer = $server ?? $canonicalServer;
        }
 
        /**
index 10d0d8b..8c65461 100644 (file)
@@ -31,7 +31,7 @@ class Xml {
         * characters (<, >, &) are escaped but illegals are not touched.
         *
         * @param string $element Element name
-        * @param array $attribs Name=>value pairs. Values will be escaped.
+        * @param array|null $attribs Name=>value pairs. Values will be escaped.
         * @param string $contents Null to make an open tag only; '' for a contentless closed tag (default)
         * @param bool $allowShortTag Whether '' in $contents will result in a contentless closed tag
         * @return string
@@ -49,7 +49,7 @@ class Xml {
                        if ( $allowShortTag && $contents === '' ) {
                                $out .= ' />';
                        } else {
-                               $out .= '>' . htmlspecialchars( $contents ) . "</$element>";
+                               $out .= '>' . htmlspecialchars( $contents, ENT_NOQUOTES ) . "</$element>";
                        }
                }
                return $out;
@@ -103,7 +103,7 @@ class Xml {
         * This opens an XML element
         *
         * @param string $element Name of the element
-        * @param array $attribs Array of attributes, see Xml::expandAttributes()
+        * @param array|null $attribs Array of attributes, see Xml::expandAttributes()
         * @return string
         */
        public static function openElement( $element, $attribs = null ) {
@@ -124,11 +124,11 @@ class Xml {
         * content you have is already valid xml.
         *
         * @param string $element Element name
-        * @param array $attribs Array of attributes
+        * @param array|null $attribs Array of attributes
         * @param string $contents Content of the element
         * @return string
         */
-       public static function tags( $element, $attribs = null, $contents ) {
+       public static function tags( $element, $attribs, $contents ) {
                return self::openElement( $element, $attribs ) . $contents . "</$element>";
        }
 
@@ -136,7 +136,7 @@ class Xml {
         * Create a date selector
         *
         * @param string $selected The month which should be selected, default ''.
-        * @param string $allmonths Value of a special item denoting all month.
+        * @param string|null $allmonths Value of a special item denoting all month.
         *   Null to not include (default).
         * @param string $id Element identifier
         * @return string Html string containing the month selector
@@ -197,7 +197,7 @@ class Xml {
         *
         * @param string $selected The language code of the selected language
         * @param bool $customisedOnly If true only languages which have some content are listed
-        * @param string $inLanguage The ISO code of the language to display the select list in (optional)
+        * @param string|null $inLanguage The ISO code of the language to display the select list in
         * @param array $overrideAttrs Override the attributes of the select tag (since 1.20)
         * @param Message|null $msg Label message key (since 1.20)
         * @return array Array containing 2 items: label HTML and select list HTML
@@ -382,7 +382,7 @@ class Xml {
                $value = false, $attribs = []
        ) {
                list( $label, $input ) = self::inputLabelSep( $label, $name, $id, $size, $value, $attribs );
-               return $label . '&#160;' . $input;
+               return $label . "\u{00A0}" . $input;
        }
 
        /**
@@ -420,7 +420,7 @@ class Xml {
        public static function checkLabel( $label, $name, $id, $checked = false, $attribs = [] ) {
                global $wgUseMediaWikiUIEverywhere;
                $chkLabel = self::check( $name, $checked, [ 'id' => $id ] + $attribs ) .
-                       '&#160;' .
+                       "\u{00A0}" .
                        self::label( $label, $id, $attribs );
 
                if ( $wgUseMediaWikiUIEverywhere ) {
@@ -446,7 +446,7 @@ class Xml {
                $checked = false, $attribs = []
        ) {
                return self::radio( $name, $value, $checked, [ 'id' => $id ] + $attribs ) .
-                       '&#160;' .
+                       "\u{00A0}" .
                        self::label( $label, $id, $attribs );
        }
 
@@ -477,7 +477,7 @@ class Xml {
        /**
         * Convenience function to build an HTML drop-down list item.
         * @param string $text Text for this item. Will be HTML escaped
-        * @param string $value Form submission value; if empty, use text
+        * @param string|null $value Form submission value; if empty, use text
         * @param bool $selected If true, will be the default selected item
         * @param array $attribs Optional additional HTML attributes
         * @return string HTML
@@ -503,7 +503,7 @@ class Xml {
         * @param string $other Text for the "Other reasons" option
         * @param string $selected Option which should be pre-selected
         * @param string $class CSS classes for the drop-down
-        * @param int $tabindex Value of the tabindex attribute
+        * @param int|null $tabindex Value of the tabindex attribute
         * @return string
         */
        public static function listDropDown( $name = '', $list = '', $other = '',
@@ -758,7 +758,7 @@ class Xml {
         * @param array $fields Associative array, key is the name of a message that
         *   contains a description for the field, value is an HTML string
         *   containing the appropriate input.
-        * @param string $submitLabel The name of a message containing a label for
+        * @param string|null $submitLabel The name of a message containing a label for
         *   the submit button.
         * @param array $submitAttribs The attributes to add to the submit button
         * @return string HTML form.
@@ -799,7 +799,7 @@ class Xml {
         * Build a table of data
         * @param array $rows An array of arrays of strings, each to be a row in a table
         * @param array $attribs An array of attributes to apply to the table tag [optional]
-        * @param array $headers An array of strings to use as table headers [optional]
+        * @param array|null $headers An array of strings to use as table headers [optional]
         * @return string
         */
        public static function buildTable( $rows, $attribs = [], $headers = null ) {
index 89f2f41..5d7406c 100644 (file)
@@ -70,11 +70,7 @@ class XmlSelect {
         * @return string|null
         */
        public function getAttribute( $name ) {
-               if ( isset( $this->attributes[$name] ) ) {
-                       return $this->attributes[$name];
-               } else {
-                       return null;
-               }
+               return $this->attributes[$name] ?? null;
        }
 
        /**
index e8d9a3e..fb22445 100644 (file)
@@ -104,7 +104,7 @@ abstract class Action implements MessageLocalizer {
                }
 
                if ( is_callable( $classOrCallable ) ) {
-                       return call_user_func_array( $classOrCallable, [ $page, $context ] );
+                       return $classOrCallable( $page, $context );
                }
 
                return $classOrCallable;
@@ -255,7 +255,7 @@ abstract class Action implements MessageLocalizer {
         */
        final public function msg( $key ) {
                $params = func_get_args();
-               return call_user_func_array( [ $this->getContext(), 'msg' ], $params );
+               return $this->getContext()->msg( ...$params );
        }
 
        /**
index 0141b9e..ec63910 100644 (file)
@@ -109,8 +109,13 @@ abstract class FormAction extends Action {
         *
         * If you don't want to do anything with the form, just return false here.
         *
+        * This method will be passed to the HTMLForm as a submit callback (see
+        * HTMLForm::setSubmitCallback) and must return as documented for HTMLForm::trySubmit.
+        *
+        * @see HTMLForm::setSubmitCallback()
+        * @see HTMLForm::trySubmit()
         * @param array $data
-        * @return bool|array True for success, false for didn't-try, array of errors on failure
+        * @return bool|string|array|Status Must return as documented for HTMLForm::trySubmit
         */
        abstract public function onSubmit( $data );
 
index f7ac21b..1a15fc0 100644 (file)
@@ -62,12 +62,25 @@ class HistoryAction extends FormlessAction {
 
        protected function getDescription() {
                // Creation of a subtitle link pointing to [[Special:Log]]
-               return MediaWikiServices::getInstance()->getLinkRenderer()->makeKnownLink(
+               $linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer();
+               $subtitle = $linkRenderer->makeKnownLink(
                        SpecialPage::getTitleFor( 'Log' ),
                        $this->msg( 'viewpagelogs' )->text(),
                        [],
                        [ 'page' => $this->getTitle()->getPrefixedText() ]
                );
+
+               $links = [];
+               // Allow extensions to add more links
+               Hooks::run( 'HistoryPageToolLinks', [ $this->getContext(), $linkRenderer, &$links ] );
+               if ( $links ) {
+                       $subtitle .= ''
+                               . $this->msg( 'word-separator' )->escaped()
+                               . $this->msg( 'parentheses' )
+                                       ->rawParams( $this->getLanguage()->pipeList( $links ) )
+                                       ->escaped();
+               }
+               return $subtitle;
        }
 
        /**
@@ -197,8 +210,8 @@ class HistoryAction extends FormlessAction {
                $content .= Xml::dateMenu(
                        ( $year == null ? MWTimestamp::getLocalInstance()->format( 'Y' ) : $year ),
                        $month
-               ) . '&#160;';
-               $content .= $tagSelector ? ( implode( '&#160;', $tagSelector ) . '&#160;' ) : '';
+               ) . "\u{00A0}";
+               $content .= $tagSelector ? ( implode( "\u{00A0}", $tagSelector ) . "\u{00A0}" ) : '';
                $content .= $checkDeleted . Html::submitButton(
                        $this->msg( 'historyaction-submit' )->text(),
                        [],
@@ -711,9 +724,7 @@ class HistoryPager extends ReverseChronologicalPager {
                # Sometimes rev_len isn't populated
                if ( $rev->getSize() !== null ) {
                        # Size is always public data
-                       $prevSize = isset( $this->parentLens[$row->rev_parent_id] )
-                               ? $this->parentLens[$row->rev_parent_id]
-                               : 0;
+                       $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";
@@ -790,7 +801,10 @@ class HistoryPager extends ReverseChronologicalPager {
                $attribs = [ 'data-mw-revid' => $rev->getId() ];
 
                Hooks::run( 'PageHistoryLineEnding', [ $this, &$row, &$s, &$classes, &$attribs ] );
-               $attribs = wfArrayFilterByKey( $attribs, [ Sanitizer::class, 'isReservedDataAttribute' ] );
+               $attribs = array_filter( $attribs,
+                       [ Sanitizer::class, 'isReservedDataAttribute' ],
+                       ARRAY_FILTER_USE_KEY
+               );
 
                if ( $classes ) {
                        $attribs['class'] = implode( ' ', $classes );
@@ -838,7 +852,7 @@ class HistoryPager extends ReverseChronologicalPager {
                } else {
                        return MediaWikiServices::getInstance()->getLinkRenderer()->makeKnownLink(
                                $this->getTitle(),
-                               $cur,
+                               new HtmlArmor( $cur ),
                                [],
                                [
                                        'diff' => $this->getWikiPage()->getLatest(),
@@ -870,7 +884,7 @@ class HistoryPager extends ReverseChronologicalPager {
                        # Next row probably exists but is unknown, use an oldid=prev link
                        return $linkRenderer->makeKnownLink(
                                $this->getTitle(),
-                               $last,
+                               new HtmlArmor( $last ),
                                [],
                                [
                                        'diff' => $prevRev->getId(),
@@ -889,7 +903,7 @@ class HistoryPager extends ReverseChronologicalPager {
 
                return $linkRenderer->makeKnownLink(
                        $this->getTitle(),
-                       $last,
+                       new HtmlArmor( $last ),
                        [],
                        [
                                'diff' => $prevRev->getId(),
index 0a4eae8..e77cdf7 100644 (file)
@@ -209,30 +209,26 @@ class InfoAction extends FormlessAction {
        protected function pageInfo() {
                global $wgContLang;
 
+               $services = MediaWikiServices::getInstance();
+
                $user = $this->getUser();
                $lang = $this->getLanguage();
                $title = $this->getTitle();
                $id = $title->getArticleID();
                $config = $this->context->getConfig();
-               $linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer();
+               $linkRenderer = $services->getLinkRenderer();
 
                $pageCounts = $this->pageCounts( $this->page );
 
-               $pageProperties = [];
                $props = PageProps::getInstance()->getAllProperties( $title );
-               if ( isset( $props[$id] ) ) {
-                       $pageProperties = $props[$id];
-               }
+               $pageProperties = $props[$id] ?? [];
 
                // Basic information
                $pageInfo = [];
                $pageInfo['header-basic'] = [];
 
                // Display title
-               $displayTitle = $title->getPrefixedText();
-               if ( isset( $pageProperties['displaytitle'] ) ) {
-                       $displayTitle = $pageProperties['displaytitle'];
-               }
+               $displayTitle = $pageProperties['displaytitle'] ?? $title->getPrefixedText();
 
                $pageInfo['header-basic'][] = [
                        $this->msg( 'pageinfo-display-title' ), $displayTitle
@@ -254,10 +250,7 @@ class InfoAction extends FormlessAction {
                }
 
                // Default sort key
-               $sortKey = $title->getCategorySortkey();
-               if ( isset( $pageProperties['defaultsort'] ) ) {
-                       $sortKey = $pageProperties['defaultsort'];
-               }
+               $sortKey = $pageProperties['defaultsort'] ?? $title->getCategorySortkey();
 
                $sortKey = htmlspecialchars( $sortKey );
                $pageInfo['header-basic'][] = [ $this->msg( 'pageinfo-default-sort' ), $sortKey ];
@@ -608,7 +601,7 @@ class InfoAction extends FormlessAction {
                ];
 
                // Array of MagicWord objects
-               $magicWords = MagicWord::getDoubleUnderscoreArray();
+               $magicWords = $services->getMagicWordFactory()->getDoubleUnderscoreArray();
 
                // Array of magic word IDs
                $wordIDs = $magicWords->names;
index 528e0e2..aaccc0c 100644 (file)
@@ -40,9 +40,7 @@ class WatchAction extends FormAction {
        }
 
        public function onSubmit( $data ) {
-               self::doWatch( $this->getTitle(), $this->getUser() );
-
-               return true;
+               return self::doWatch( $this->getTitle(), $this->getUser() );
        }
 
        protected function checkCanExecute( User $user ) {
@@ -183,8 +181,10 @@ class WatchAction extends FormAction {
         * @param string $action Optionally override the action to 'watch'
         * @return string Token
         * @since 1.18
+        * @deprecated since 1.32 Use WatchAction::getWatchToken() with action 'unwatch' directly.
         */
        public static function getUnwatchToken( Title $title, User $user, $action = 'unwatch' ) {
+               wfDeprecated( __METHOD__, '1.32' );
                return self::getWatchToken( $title, $user, $action );
        }
 
index d6b9f76..e37b4d4 100644 (file)
@@ -48,7 +48,7 @@ class ApiAuthManagerHelper {
                $this->module = $module;
 
                $params = $module->extractRequestParams();
-               $this->messageFormat = isset( $params['messageformat'] ) ? $params['messageformat'] : 'wikitext';
+               $this->messageFormat = $params['messageformat'] ?? 'wikitext';
        }
 
        /**
index b18bf58..e546c4a 100644 (file)
@@ -761,10 +761,23 @@ abstract class ApiBase extends ContextSource {
         * value - validated value from user or default. limits will not be
         * parsed if $parseLimit is set to false; use this when the max
         * limit is not definitive yet, e.g. when getting revisions.
-        * @param bool $parseLimit True by default
+        * @param bool|array $options If a boolean, uses that as the value for 'parseLimit'
+        *  - parseLimit: (bool, default true) Whether to parse the 'max' value for limit types
+        *  - safeMode: (bool, default false) If true, avoid throwing for parameter validation errors.
+        *    Returned parameter values might be ApiUsageException instances.
         * @return array
         */
-       public function extractRequestParams( $parseLimit = true ) {
+       public function extractRequestParams( $options = [] ) {
+               if ( is_bool( $options ) ) {
+                       $options = [ 'parseLimit' => $options ];
+               }
+               $options += [
+                       'parseLimit' => true,
+                       'safeMode' => false,
+               ];
+
+               $parseLimit = (bool)$options['parseLimit'];
+
                // Cache parameters, for performance and to avoid T26564.
                if ( !isset( $this->mParamCache[$parseLimit] ) ) {
                        $params = $this->getFinalParams() ?: [];
@@ -778,9 +791,13 @@ abstract class ApiBase extends ContextSource {
                                if ( isset( $paramSettings[self::PARAM_TEMPLATE_VARS] ) ) {
                                        $toProcess[] = [ $paramName, $paramSettings[self::PARAM_TEMPLATE_VARS], $paramSettings ];
                                } else {
-                                       $results[$paramName] = $this->getParameterFromSettings(
-                                               $paramName, $paramSettings, $parseLimit
-                                       );
+                                       try {
+                                               $results[$paramName] = $this->getParameterFromSettings(
+                                                       $paramName, $paramSettings, $parseLimit
+                                               );
+                                       } catch ( ApiUsageException $ex ) {
+                                               $results[$paramName] = $ex;
+                                       }
                                }
                        }
 
@@ -826,7 +843,11 @@ abstract class ApiBase extends ContextSource {
 
                                                $newName = str_replace( $placeholder, $value, $name );
                                                if ( !$targets ) {
-                                                       $results[$newName] = $this->getParameterFromSettings( $newName, $settings, $parseLimit );
+                                                       try {
+                                                               $results[$newName] = $this->getParameterFromSettings( $newName, $settings, $parseLimit );
+                                                       } catch ( ApiUsageException $ex ) {
+                                                               $results[$newName] = $ex;
+                                                       }
                                                } else {
                                                        $newTargets = [];
                                                        foreach ( $targets as $k => $v ) {
@@ -842,6 +863,15 @@ abstract class ApiBase extends ContextSource {
                        $this->mParamCache[$parseLimit] = $results;
                }
 
+               $ret = $this->mParamCache[$parseLimit];
+               if ( !$options['safeMode'] ) {
+                       foreach ( $ret as $v ) {
+                               if ( $v instanceof ApiUsageException ) {
+                                       throw $v;
+                               }
+                       }
+               }
+
                return $this->mParamCache[$parseLimit];
        }
 
@@ -852,7 +882,14 @@ abstract class ApiBase extends ContextSource {
         * @return mixed Parameter value
         */
        protected function getParameter( $paramName, $parseLimit = true ) {
-               return $this->extractRequestParams( $parseLimit )[$paramName];
+               $ret = $this->extractRequestParams( [
+                       'parseLimit' => $parseLimit,
+                       'safeMode' => true,
+               ] )[$paramName];
+               if ( $ret instanceof ApiUsageException ) {
+                       throw $ret;
+               }
+               return $ret;
        }
 
        /**
@@ -1063,7 +1100,7 @@ abstract class ApiBase extends ContextSource {
         * Return true if we're to watch the page, false if not, null if no change.
         * @param string $watchlist Valid values: 'watch', 'unwatch', 'preferences', 'nochange'
         * @param Title $titleObj The page under consideration
-        * @param string $userOption The user option to consider when $watchlist=preferences.
+        * @param string|null $userOption The user option to consider when $watchlist=preferences.
         *    If not set will use watchdefault always and watchcreations if $titleObj doesn't exist.
         * @return bool
         */
@@ -1119,36 +1156,16 @@ abstract class ApiBase extends ContextSource {
                        ];
                }
 
-               $default = isset( $paramSettings[self::PARAM_DFLT] )
-                       ? $paramSettings[self::PARAM_DFLT]
-                       : null;
-               $multi = isset( $paramSettings[self::PARAM_ISMULTI] )
-                       ? $paramSettings[self::PARAM_ISMULTI]
-                       : false;
-               $multiLimit1 = isset( $paramSettings[self::PARAM_ISMULTI_LIMIT1] )
-                       ? $paramSettings[self::PARAM_ISMULTI_LIMIT1]
-                       : null;
-               $multiLimit2 = isset( $paramSettings[self::PARAM_ISMULTI_LIMIT2] )
-                       ? $paramSettings[self::PARAM_ISMULTI_LIMIT2]
-                       : null;
-               $type = isset( $paramSettings[self::PARAM_TYPE] )
-                       ? $paramSettings[self::PARAM_TYPE]
-                       : null;
-               $dupes = isset( $paramSettings[self::PARAM_ALLOW_DUPLICATES] )
-                       ? $paramSettings[self::PARAM_ALLOW_DUPLICATES]
-                       : false;
-               $deprecated = isset( $paramSettings[self::PARAM_DEPRECATED] )
-                       ? $paramSettings[self::PARAM_DEPRECATED]
-                       : false;
-               $deprecatedValues = isset( $paramSettings[self::PARAM_DEPRECATED_VALUES] )
-                       ? $paramSettings[self::PARAM_DEPRECATED_VALUES]
-                       : [];
-               $required = isset( $paramSettings[self::PARAM_REQUIRED] )
-                       ? $paramSettings[self::PARAM_REQUIRED]
-                       : false;
-               $allowAll = isset( $paramSettings[self::PARAM_ALL] )
-                       ? $paramSettings[self::PARAM_ALL]
-                       : false;
+               $default = $paramSettings[self::PARAM_DFLT] ?? null;
+               $multi = $paramSettings[self::PARAM_ISMULTI] ?? false;
+               $multiLimit1 = $paramSettings[self::PARAM_ISMULTI_LIMIT1] ?? null;
+               $multiLimit2 = $paramSettings[self::PARAM_ISMULTI_LIMIT2] ?? null;
+               $type = $paramSettings[self::PARAM_TYPE] ?? null;
+               $dupes = $paramSettings[self::PARAM_ALLOW_DUPLICATES] ?? false;
+               $deprecated = $paramSettings[self::PARAM_DEPRECATED] ?? false;
+               $deprecatedValues = $paramSettings[self::PARAM_DEPRECATED_VALUES] ?? [];
+               $required = $paramSettings[self::PARAM_REQUIRED] ?? false;
+               $allowAll = $paramSettings[self::PARAM_ALL] ?? false;
 
                // When type is not given, and no choices, the type is the same as $default
                if ( !isset( $type ) ) {
@@ -1272,14 +1289,13 @@ abstract class ApiBase extends ContextSource {
                                        case 'text':
                                        case 'password':
                                                if ( $required && $value === '' ) {
-                                                       $this->dieWithError( [ 'apierror-missingparam', $paramName ] );
+                                                       $this->dieWithError( [ 'apierror-missingparam', $encParamName ] );
                                                }
                                                break;
                                        case 'integer': // Force everything using intval() and optionally validate limits
-                                               $min = isset( $paramSettings[self::PARAM_MIN] ) ? $paramSettings[self::PARAM_MIN] : null;
-                                               $max = isset( $paramSettings[self::PARAM_MAX] ) ? $paramSettings[self::PARAM_MAX] : null;
-                                               $enforceLimits = isset( $paramSettings[self::PARAM_RANGE_ENFORCE] )
-                                                       ? $paramSettings[self::PARAM_RANGE_ENFORCE] : false;
+                                               $min = $paramSettings[self::PARAM_MIN] ?? null;
+                                               $max = $paramSettings[self::PARAM_MAX] ?? null;
+                                               $enforceLimits = $paramSettings[self::PARAM_RANGE_ENFORCE] ?? false;
 
                                                if ( is_array( $value ) ) {
                                                        $value = array_map( 'intval', $value );
@@ -1311,7 +1327,7 @@ abstract class ApiBase extends ContextSource {
                                                if ( $multi ) {
                                                        self::dieDebug( __METHOD__, "Multi-values not supported for $encParamName" );
                                                }
-                                               $min = isset( $paramSettings[self::PARAM_MIN] ) ? $paramSettings[self::PARAM_MIN] : 0;
+                                               $min = $paramSettings[self::PARAM_MIN] ?? 0;
                                                if ( $value == 'max' ) {
                                                        $value = $this->getMain()->canApiHighLimits()
                                                                ? $paramSettings[self::PARAM_MAX2]
@@ -1427,7 +1443,7 @@ abstract class ApiBase extends ContextSource {
                                }
                        }
                } elseif ( $required ) {
-                       $this->dieWithError( [ 'apierror-missingparam', $paramName ] );
+                       $this->dieWithError( [ 'apierror-missingparam', $encParamName ] );
                }
 
                return $value;
@@ -1558,7 +1574,7 @@ abstract class ApiBase extends ContextSource {
         * @param int &$value Parameter value
         * @param int|null $min Minimum value
         * @param int|null $max Maximum value for users
-        * @param int $botMax Maximum value for sysops/bots
+        * @param int|null $botMax Maximum value for sysops/bots
         * @param bool $enforceLimits Whether to enforce (die) if value is outside limits
         */
        protected function validateLimit( $paramName, &$value, $min, $max, $botMax = null,
@@ -1728,7 +1744,7 @@ abstract class ApiBase extends ContextSource {
         * Set a watch (or unwatch) based the based on a watchlist parameter.
         * @param string $watch Valid values: 'watch', 'unwatch', 'preferences', 'nochange'
         * @param Title $titleObj The article's title to change
-        * @param string $userOption The user option to consider when $watch=preferences
+        * @param string|null $userOption The user option to consider when $watch=preferences
         */
        protected function setWatch( $watch, $titleObj, $userOption = null ) {
                $value = $this->getWatchlistValue( $watch, $titleObj, $userOption );
@@ -1796,14 +1812,14 @@ abstract class ApiBase extends ContextSource {
         * @since 1.25
         * @param string|array|Message $msg
         * @param IContextSource $context
-        * @param array $params
+        * @param array|null $params
         * @return Message|null
         */
        public static function makeMessage( $msg, IContextSource $context, array $params = null ) {
                if ( is_string( $msg ) ) {
                        $msg = wfMessage( $msg );
                } elseif ( is_array( $msg ) ) {
-                       $msg = call_user_func_array( 'wfMessage', $msg );
+                       $msg = wfMessage( ...$msg );
                }
                if ( !$msg instanceof Message ) {
                        return null;
@@ -1850,7 +1866,7 @@ abstract class ApiBase extends ContextSource {
                                        [ 'blockinfo' => ApiQueryUserInfo::getBlockInfo( $user->getBlock() ) ]
                                ) );
                        } else {
-                               call_user_func_array( [ $status, 'fatal' ], (array)$error );
+                               $status->fatal( ...(array)$error );
                        }
                }
                return $status;
@@ -2029,10 +2045,7 @@ abstract class ApiBase extends ContextSource {
                if ( !$status->getErrorsByType( 'error' ) ) {
                        $newStatus = Status::newGood();
                        foreach ( $status->getErrorsByType( 'warning' ) as $err ) {
-                               call_user_func_array(
-                                       [ $newStatus, 'fatal' ],
-                                       array_merge( [ $err['message'] ], $err['params'] )
-                               );
+                               $newStatus->fatal( $err['message'], ...$err['params'] );
                        }
                        if ( !$newStatus->getErrorsByType( 'error' ) ) {
                                $newStatus->fatal( 'unknownerror-nocode' );
@@ -2069,7 +2082,7 @@ abstract class ApiBase extends ContextSource {
                        $user = $this->getUser();
                }
                $rights = (array)$rights;
-               if ( !call_user_func_array( [ $user, 'isAllowedAny' ], $rights ) ) {
+               if ( !$user->isAllowedAny( ...$rights ) ) {
                        $this->dieWithError( [ 'apierror-permissiondenied', $this->msg( "action-{$rights[0]}" ) ] );
                }
        }
@@ -2298,7 +2311,7 @@ abstract class ApiBase extends ContextSource {
                                        'api-help-param-token',
                                        $this->needsToken(),
                                ],
-                       ] + ( isset( $params['token'] ) ? $params['token'] : [] );
+                       ] + ( $params['token'] ?? [] );
                }
 
                // Avoid PHP 7.1 warning of passing $this by reference
@@ -2338,7 +2351,7 @@ abstract class ApiBase extends ContextSource {
                                $settings = [];
                        }
 
-                       $d = isset( $desc[$param] ) ? $desc[$param] : '';
+                       $d = $desc[$param] ?? '';
                        if ( is_array( $d ) ) {
                                // Special handling for prop parameters
                                $d = array_map( function ( $line ) {
@@ -2420,9 +2433,7 @@ abstract class ApiBase extends ContextSource {
                                }
 
                                $valueMsgs = $settings[self::PARAM_HELP_MSG_PER_VALUE];
-                               $deprecatedValues = isset( $settings[self::PARAM_DEPRECATED_VALUES] )
-                                       ? $settings[self::PARAM_DEPRECATED_VALUES]
-                                       : [];
+                               $deprecatedValues = $settings[self::PARAM_DEPRECATED_VALUES] ?? [];
 
                                foreach ( $settings[self::PARAM_TYPE] as $value ) {
                                        if ( isset( $valueMsgs[$value] ) ) {
@@ -2664,16 +2675,14 @@ abstract class ApiBase extends ContextSource {
         * @deprecated since 1.25
         */
        public function profileIn() {
-               // No wfDeprecated() yet because extensions call this and might need to
-               // keep doing so for BC.
+               wfDeprecated( __METHOD__, '1.25' );
        }
 
        /**
         * @deprecated since 1.25
         */
        public function profileOut() {
-               // No wfDeprecated() yet because extensions call this and might need to
-               // keep doing so for BC.
+               wfDeprecated( __METHOD__, '1.25' );
        }
 
        /**
@@ -2774,7 +2783,7 @@ abstract class ApiBase extends ContextSource {
                if ( !$msg instanceof IApiMessage ) {
                        $key = $msg->getKey();
                        $params = $msg->getParams();
-                       array_unshift( $params, isset( self::$messageMap[$key] ) ? self::$messageMap[$key] : $key );
+                       array_unshift( $params, self::$messageMap[$key] ?? $key );
                        $msg = ApiMessage::create( $params );
                }
 
index 82a7cce..6271128 100644 (file)
@@ -176,8 +176,8 @@ class ApiCSPReport extends ApiBase {
                        $flagText = '[' . implode( ', ', $flags ) . ']';
                }
 
-               $blockedFile = isset( $report['blocked-uri'] ) ? $report['blocked-uri'] : 'n/a';
-               $page = isset( $report['document-uri'] ) ? $report['document-uri'] : 'n/a';
+               $blockedFile = $report['blocked-uri'] ?? 'n/a';
+               $page = $report['document-uri'] ?? 'n/a';
                $line = isset( $report['line-number'] ) ? ':' . $report['line-number'] : '';
                $warningText = $flagText .
                        ' Received CSP report: <' . $blockedFile .
index a63dee6..ec857b7 100644 (file)
@@ -139,7 +139,7 @@ class ApiDelete extends ApiBase {
         * @param Page $page Object to work on
         * @param User $user User doing the action
         * @param string $oldimage Archive name
-        * @param string &$reason Reason for the deletion. Autogenerated if null.
+        * @param string|null &$reason Reason for the deletion. Autogenerated if null.
         * @param bool $suppress Whether to mark all deleted versions as restricted
         * @param array $tags Tags to tag the deletion with
         * @return Status
index c637752..af23f95 100644 (file)
@@ -203,7 +203,7 @@ class ApiErrorFormatter {
        public function formatException( $exception, array $options = [] ) {
                return $this->formatMessage(
                        $this->getMessageFromException( $exception, $options ),
-                       isset( $options['format'] ) ? $options['format'] : null
+                       $options['format'] ?? null
                );
        }
 
index fe49b25..562bcdf 100644 (file)
@@ -20,6 +20,8 @@
  * @file
  */
 
+use MediaWiki\MediaWikiServices;
+
 /**
  * API module that functions as a shortcut to the wikitext preprocessor. Expands
  * any templates in a provided string, and returns the result of this expansion
@@ -48,7 +50,7 @@ class ApiExpandTemplates extends ApiBase {
 
                if ( $params['prop'] === null ) {
                        $this->addDeprecation(
-                               'apiwarn-deprecation-expandtemplates-prop', 'action=expandtemplates&!prop'
+                               [ 'apiwarn-deprecation-missingparam', 'prop' ], 'action=expandtemplates&!prop'
                        );
                        $prop = [];
                } else {
@@ -63,12 +65,12 @@ class ApiExpandTemplates extends ApiBase {
                // Get title and revision ID for parser
                $revid = $params['revid'];
                if ( $revid !== null ) {
-                       $rev = Revision::newFromId( $revid );
+                       $rev = MediaWikiServices::getInstance()->getRevisionStore()->getRevisionById( $revid );
                        if ( !$rev ) {
                                $this->dieWithError( [ 'apierror-nosuchrevid', $revid ] );
                        }
                        $pTitleObj = $titleObj;
-                       $titleObj = $rev->getTitle();
+                       $titleObj = Title::newFromLinkTarget( $rev->getPageAsLinkTarget() );
                        if ( $titleProvided ) {
                                if ( !$titleObj->equals( $pTitleObj ) ) {
                                        $this->addWarning( [ 'apierror-revwrongpage', $rev->getId(),
index 61a9035..92d504e 100644 (file)
  * @file
  */
 
+use MediaWiki\MediaWikiServices;
+use MediaWiki\Storage\RevisionAccessException;
+use MediaWiki\Storage\RevisionRecord;
+use MediaWiki\Storage\RevisionStore;
+
 /**
  * @ingroup API
  */
 class ApiFeedContributions extends ApiBase {
 
+       /** @var RevisionStore */
+       private $revisionStore;
+
        /**
         * This module uses a custom feed wrapper printer.
         *
@@ -35,6 +43,8 @@ class ApiFeedContributions extends ApiBase {
        }
 
        public function execute() {
+               $this->revisionStore = MediaWikiServices::getInstance()->getRevisionStore();
+
                $params = $this->extractRequestParams();
 
                $config = $this->getConfig();
@@ -130,7 +140,7 @@ class ApiFeedContributions extends ApiBase {
                if ( $title && $title->userCan( 'read', $this->getUser() ) ) {
                        $date = $row->rev_timestamp;
                        $comments = $title->getTalkPage()->getFullURL();
-                       $revision = Revision::newFromRow( $row );
+                       $revision = $this->revisionStore->newRevisionFromRow( $row );
 
                        return new FeedItem(
                                $title->getPrefixedText(),
@@ -146,21 +156,28 @@ class ApiFeedContributions extends ApiBase {
        }
 
        /**
-        * @param Revision $revision
+        * @since 1.32, takes a RevisionRecord instead of a Revision
+        * @param RevisionRecord $revision
         * @return string
         */
-       protected function feedItemAuthor( $revision ) {
-               return $revision->getUserText();
+       protected function feedItemAuthor( RevisionRecord $revision ) {
+               $user = $revision->getUser();
+               return $user ? $user->getName() : '';
        }
 
        /**
-        * @param Revision $revision
+        * @since 1.32, takes a RevisionRecord instead of a Revision
+        * @param RevisionRecord $revision
         * @return string
         */
-       protected function feedItemDesc( $revision ) {
+       protected function feedItemDesc( RevisionRecord $revision ) {
                if ( $revision ) {
                        $msg = wfMessage( 'colon-separator' )->inContentLanguage()->text();
-                       $content = $revision->getContent();
+                       try {
+                               $content = $revision->getContent( 'main' );
+                       } catch ( RevisionAccessException $e ) {
+                               $content = null;
+                       }
 
                        if ( $content instanceof TextContent ) {
                                // only textual content has a "source view".
@@ -173,8 +190,10 @@ class ApiFeedContributions extends ApiBase {
                                $html = '';
                        }
 
-                       return '<p>' . htmlspecialchars( $revision->getUserText() ) . $msg .
-                               htmlspecialchars( FeedItem::stripComment( $revision->getComment() ) ) .
+                       $comment = $revision->getComment();
+
+                       return '<p>' . htmlspecialchars( $this->feedItemAuthor( $revision ) ) . $msg .
+                               htmlspecialchars( FeedItem::stripComment( $comment ? $comment->text : '' ) ) .
                                "</p>\n<hr />\n<div>" . $html . '</div>';
                }
 
index 393e536..c21ac12 100644 (file)
@@ -144,7 +144,7 @@ class ApiFeedWatchlist extends ApiBase {
                                ' [' . $this->getConfig()->get( 'LanguageCode' ) . ']';
                        $feedUrl = SpecialPage::getTitleFor( 'Watchlist' )->getFullURL();
 
-                       $feedFormat = isset( $params['feedformat'] ) ? $params['feedformat'] : 'rss';
+                       $feedFormat = $params['feedformat'] ?? 'rss';
                        $msg = wfMessage( 'watchlist' )->inContentLanguage()->escaped();
                        $feed = new $feedClasses[$feedFormat] ( $feedTitle, $msg, $feedUrl );
 
@@ -201,7 +201,7 @@ class ApiFeedWatchlist extends ApiBase {
                } else {
                        $titleUrl = $title->getFullURL( $curidParam );
                }
-               $comment = isset( $info['comment'] ) ? $info['comment'] : null;
+               $comment = $info['comment'] ?? null;
 
                // Create an anchor to section.
                // The anchor won't work for sections that have dupes on page
index cc1bd82..73e9e58 100644 (file)
@@ -104,26 +104,18 @@ class ApiFormatXml extends ApiFormatBase {
                        $value = (array)$value;
                }
                if ( is_array( $value ) ) {
-                       $contentKey = isset( $value[ApiResult::META_CONTENT] )
-                               ? $value[ApiResult::META_CONTENT]
-                               : '*';
-                       $subelementKeys = isset( $value[ApiResult::META_SUBELEMENTS] )
-                               ? $value[ApiResult::META_SUBELEMENTS]
-                               : [];
+                       $contentKey = $value[ApiResult::META_CONTENT] ?? '*';
+                       $subelementKeys = $value[ApiResult::META_SUBELEMENTS] ?? [];
                        if ( isset( $value[ApiResult::META_BC_SUBELEMENTS] ) ) {
                                $subelementKeys = array_merge(
                                        $subelementKeys, $value[ApiResult::META_BC_SUBELEMENTS]
                                );
                        }
-                       $preserveKeys = isset( $value[ApiResult::META_PRESERVE_KEYS] )
-                               ? $value[ApiResult::META_PRESERVE_KEYS]
-                               : [];
+                       $preserveKeys = $value[ApiResult::META_PRESERVE_KEYS] ?? [];
                        $indexedTagName = isset( $value[ApiResult::META_INDEXED_TAG_NAME] )
                                ? self::mangleName( $value[ApiResult::META_INDEXED_TAG_NAME], $preserveKeys )
                                : '_v';
-                       $bcBools = isset( $value[ApiResult::META_BC_BOOLS] )
-                               ? $value[ApiResult::META_BC_BOOLS]
-                               : [];
+                       $bcBools = $value[ApiResult::META_BC_BOOLS] ?? [];
                        $indexSubelements = isset( $value[ApiResult::META_TYPE] )
                                ? $value[ApiResult::META_TYPE] !== 'array'
                                : false;
index bccb338..041b024 100644 (file)
@@ -104,6 +104,7 @@ class ApiHelp extends ApiBase {
                ] );
                if ( !empty( $options['toc'] ) ) {
                        $out->addModules( 'mediawiki.toc' );
+                       $out->addModuleStyles( 'mediawiki.toc.styles' );
                }
                $out->setPageTitle( $context->msg( 'api-help-title' ) );
 
@@ -149,7 +150,7 @@ class ApiHelp extends ApiBase {
                }
                $out->addHTML( $html );
 
-               $helptitle = isset( $options['helptitle'] ) ? $options['helptitle'] : null;
+               $helptitle = $options['helptitle'] ?? null;
                $html = self::fixHelpLinks( $out->getHTML(), $helptitle, $haveModules );
                $out->clearHTML();
                $out->addHTML( $html );
@@ -482,9 +483,7 @@ class ApiHelp extends ApiBase {
 
                                        // Type documentation
                                        if ( !isset( $settings[ApiBase::PARAM_TYPE] ) ) {
-                                               $dflt = isset( $settings[ApiBase::PARAM_DFLT] )
-                                                       ? $settings[ApiBase::PARAM_DFLT]
-                                                       : null;
+                                               $dflt = $settings[ApiBase::PARAM_DFLT] ?? null;
                                                if ( is_bool( $dflt ) ) {
                                                        $settings[ApiBase::PARAM_TYPE] = 'boolean';
                                                } elseif ( is_string( $dflt ) || is_null( $dflt ) ) {
@@ -503,12 +502,8 @@ class ApiHelp extends ApiBase {
 
                                                if ( is_array( $type ) ) {
                                                        $count = count( $type );
-                                                       $deprecatedValues = isset( $settings[ApiBase::PARAM_DEPRECATED_VALUES] )
-                                                               ? $settings[ApiBase::PARAM_DEPRECATED_VALUES]
-                                                               : [];
-                                                       $links = isset( $settings[ApiBase::PARAM_VALUE_LINKS] )
-                                                               ? $settings[ApiBase::PARAM_VALUE_LINKS]
-                                                               : [];
+                                                       $deprecatedValues = $settings[ApiBase::PARAM_DEPRECATED_VALUES] ?? [];
+                                                       $links = $settings[ApiBase::PARAM_VALUE_LINKS] ?? [];
                                                        $values = array_map( function ( $v ) use ( $links, $deprecatedValues ) {
                                                                $attr = [];
                                                                if ( $v !== '' ) {
@@ -707,9 +702,7 @@ class ApiHelp extends ApiBase {
                                                                $info[] = implode( ' ', $extra );
                                                        }
 
-                                                       $allowAll = isset( $settings[ApiBase::PARAM_ALL] )
-                                                               ? $settings[ApiBase::PARAM_ALL]
-                                                               : false;
+                                                       $allowAll = $settings[ApiBase::PARAM_ALL] ?? false;
                                                        if ( $allowAll || $settings[ApiBase::PARAM_TYPE] === 'namespace' ) {
                                                                if ( $settings[ApiBase::PARAM_TYPE] === 'namespace' ) {
                                                                        $allSpecifier = ApiBase::ALL_DEFAULT_STRING;
@@ -733,9 +726,7 @@ class ApiHelp extends ApiBase {
                                        }
 
                                        // Add default
-                                       $default = isset( $settings[ApiBase::PARAM_DFLT] )
-                                               ? $settings[ApiBase::PARAM_DFLT]
-                                               : null;
+                                       $default = $settings[ApiBase::PARAM_DFLT] ?? null;
                                        if ( $default === '' ) {
                                                $info[] = $context->msg( 'api-help-param-default-empty' )
                                                        ->parse();
index 914d8e9..e5e384c 100644 (file)
@@ -24,8 +24,6 @@
 use MediaWiki\Logger\LoggerFactory;
 use MediaWiki\MediaWikiServices;
 use Wikimedia\Timestamp\TimestampException;
-use Wikimedia\Rdbms\DBQueryError;
-use Wikimedia\Rdbms\DBError;
 
 /**
  * This is the main API class, used for both external and internal processing.
@@ -165,7 +163,7 @@ class ApiMain extends ApiBase {
        /**
         * Constructs an instance of ApiMain that utilizes the module and format specified by $request.
         *
-        * @param IContextSource|WebRequest $context If this is an instance of
+        * @param IContextSource|WebRequest|null $context If this is an instance of
         *    FauxRequest, errors are thrown and no printing occurs
         * @param bool $enableWrite Should be set to true if the api may modify data
         */
@@ -486,7 +484,7 @@ class ApiMain extends ApiBase {
         * @return ApiFormatBase
         */
        public function createPrinterByName( $format ) {
-               $printer = $this->mModuleMgr->getModule( $format, 'format' );
+               $printer = $this->mModuleMgr->getModule( $format, 'format', /* $ignoreCache */ true );
                if ( $printer === null ) {
                        $this->dieWithError(
                                [ 'apierror-unknownformat', wfEscapeWikiText( $format ) ], 'unknown_format'
@@ -535,11 +533,9 @@ class ApiMain extends ApiBase {
                        $this->executeAction();
                        $runTime = microtime( true ) - $t;
                        $this->logRequest( $runTime );
-                       if ( $this->mModule->isWriteMode() && $this->getRequest()->wasPosted() ) {
-                               MediaWikiServices::getInstance()->getStatsdDataFactory()->timing(
-                                       'api.' . $this->mModule->getModuleName() . '.executeTiming', 1000 * $runTime
-                               );
-                       }
+                       MediaWikiServices::getInstance()->getStatsdDataFactory()->timing(
+                               'api.' . $this->mModule->getModuleName() . '.executeTiming', 1000 * $runTime
+                       );
                } catch ( Exception $e ) {
                        $this->handleException( $e );
                        $this->logRequest( microtime( true ) - $t, $e );
@@ -1040,9 +1036,7 @@ class ApiMain extends ApiBase {
                        $config = $this->getConfig();
                        $class = preg_replace( '#^Wikimedia\\\Rdbms\\\#', '', get_class( $e ) );
                        $code = 'internal_api_error_' . $class;
-                       if ( ( $e instanceof DBQueryError ) && !$config->get( 'ShowSQLErrors' ) ) {
-                               $params = [ 'apierror-databaseerror', WebRequest::getRequestId() ];
-                       } else {
+                       if ( $config->get( 'ShowExceptionDetails' ) ) {
                                if ( $e instanceof ILocalizedException ) {
                                        $msg = $e->getMessageObject();
                                } elseif ( $e instanceof MessageSpecifier ) {
@@ -1051,7 +1045,10 @@ class ApiMain extends ApiBase {
                                        $msg = wfEscapeWikiText( $e->getMessage() );
                                }
                                $params = [ 'apierror-exceptioncaught', WebRequest::getRequestId(), $msg ];
+                       } else {
+                               $params = [ 'apierror-exceptioncaughttype', WebRequest::getRequestId(), get_class( $e ) ];
                        }
+
                        $messages[] = ApiMessage::create( $params, $code );
                }
                return $messages;
@@ -1115,9 +1112,7 @@ class ApiMain extends ApiBase {
                                )
                        );
                } else {
-                       if ( $config->get( 'ShowExceptionDetails' ) &&
-                               ( !$e instanceof DBError || $config->get( 'ShowDBErrorBacktrace' ) )
-                       ) {
+                       if ( $config->get( 'ShowExceptionDetails' ) ) {
                                $result->addContentValue(
                                        $path,
                                        'trace',
@@ -1258,6 +1253,8 @@ class ApiMain extends ApiBase {
                        }
                }
 
+               Hooks::runWithoutAbort( 'ApiMaxLagInfo', [ &$lagInfo ] );
+
                return $lagInfo;
        }
 
@@ -1552,6 +1549,11 @@ class ApiMain extends ApiBase {
         */
        protected function executeAction() {
                $params = $this->setupExecuteAction();
+
+               // Check asserts early so e.g. errors in parsing a module's parameters due to being
+               // logged out don't override the client's intended "am I logged in?" check.
+               $this->checkAsserts( $params );
+
                $module = $this->setupModule();
                $this->mModule = $module;
 
@@ -1573,8 +1575,6 @@ class ApiMain extends ApiBase {
                        $this->setupExternalResponse( $module, $params );
                }
 
-               $this->checkAsserts( $params );
-
                // Execute
                $module->execute();
                Hooks::run( 'APIAfterExecute', [ &$module ] );
@@ -1611,7 +1611,7 @@ class ApiMain extends ApiBase {
        /**
         * Log the preceding request
         * @param float $time Time in seconds
-        * @param Exception $e Exception caught while processing the request
+        * @param Exception|null $e Exception caught while processing the request
         */
        protected function logRequest( $time, $e = null ) {
                $request = $this->getRequest();
index 3347128..6a8b7d0 100644 (file)
@@ -1,8 +1,5 @@
 <?php
 /**
- * Defines an interface for messages with additional machine-readable data for
- * use by the API, and provides concrete implementations of that interface.
- *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * @file
  */
 
-/**
- * Interface for messages with machine-readable data for use by the API
- *
- * The idea is that it's a Message that has some extra data for the API to use when interpreting it
- * as an error (or, in the future, as a warning). Internals of MediaWiki often use messages (or
- * message keys, or Status objects containing messages) to pass information about errors to the user
- * (see e.g. Title::getUserPermissionsErrors()) and the API has to make do with that.
- *
- * @since 1.25
- * @note This interface exists to work around PHP's inheritance, so ApiMessage
- *  can extend Message and ApiRawMessage can extend RawMessage while still
- *  allowing an instanceof check for a Message object including this
- *  functionality. If for some reason you feel the need to implement this
- *  interface on some other class, that class must also implement all the
- *  public methods the Message class provides (not just those from
- *  MessageSpecifier, which as written is fairly useless).
- * @ingroup API
- */
-interface IApiMessage extends MessageSpecifier {
-       /**
-        * Returns a machine-readable code for use by the API
-        *
-        * If no code was specifically set, the message key is used as the code
-        * after removing "apiwarn-" or "apierror-" prefixes and applying
-        * backwards-compatibility mappings.
-        *
-        * @return string
-        */
-       public function getApiCode();
-
-       /**
-        * Returns additional machine-readable data about the error condition
-        * @return array
-        */
-       public function getApiData();
-
-       /**
-        * Sets the machine-readable code for use by the API
-        * @param string|null $code If null, uses the default (see self::getApiCode())
-        * @param array|null $data If non-null, passed to self::setApiData()
-        */
-       public function setApiCode( $code, array $data = null );
-
-       /**
-        * Sets additional machine-readable data about the error condition
-        * @param array $data
-        */
-       public function setApiData( array $data );
-}
-
-/**
- * Trait to implement the IApiMessage interface for Message subclasses
- * @since 1.27
- * @ingroup API
- */
-trait ApiMessageTrait {
-
-       /**
-        * Compatibility code mappings for various MW messages.
-        * @todo Ideally anything relying on this should be changed to use ApiMessage.
-        */
-       protected static $messageMap = [
-               'actionthrottledtext' => 'ratelimited',
-               'autoblockedtext' => 'autoblocked',
-               'badaccess-group0' => 'permissiondenied',
-               'badaccess-groups' => 'permissiondenied',
-               'badipaddress' => 'invalidip',
-               'blankpage' => 'emptypage',
-               'blockedtext' => 'blocked',
-               'cannotdelete' => 'cantdelete',
-               'cannotundelete' => 'cantundelete',
-               'cantmove-titleprotected' => 'protectedtitle',
-               'cantrollback' => 'onlyauthor',
-               'confirmedittext' => 'confirmemail',
-               'content-not-allowed-here' => 'contentnotallowedhere',
-               'deleteprotected' => 'cantedit',
-               'delete-toobig' => 'bigdelete',
-               'edit-conflict' => 'editconflict',
-               'imagenocrossnamespace' => 'nonfilenamespace',
-               'imagetypemismatch' => 'filetypemismatch',
-               'importbadinterwiki' => 'badinterwiki',
-               'importcantopen' => 'cantopenfile',
-               'import-noarticle' => 'badinterwiki',
-               'importnofile' => 'nofile',
-               'importuploaderrorpartial' => 'partialupload',
-               'importuploaderrorsize' => 'filetoobig',
-               'importuploaderrortemp' => 'notempdir',
-               'ipb_already_blocked' => 'alreadyblocked',
-               'ipb_blocked_as_range' => 'blockedasrange',
-               'ipb_cant_unblock' => 'cantunblock',
-               'ipb_expiry_invalid' => 'invalidexpiry',
-               'ip_range_invalid' => 'invalidrange',
-               'mailnologin' => 'cantsend',
-               'markedaspatrollederror-noautopatrol' => 'noautopatrol',
-               'movenologintext' => 'cantmove-anon',
-               'movenotallowed' => 'cantmove',
-               'movenotallowedfile' => 'cantmovefile',
-               'namespaceprotected' => 'protectednamespace',
-               'nocreate-loggedin' => 'cantcreate',
-               'nocreatetext' => 'cantcreate-anon',
-               'noname' => 'invaliduser',
-               'nosuchusershort' => 'nosuchuser',
-               'notanarticle' => 'missingtitle',
-               'nouserspecified' => 'invaliduser',
-               'ns-specialprotected' => 'unsupportednamespace',
-               'protect-cantedit' => 'cantedit',
-               'protectedinterface' => 'protectednamespace-interface',
-               'protectedpagetext' => 'protectedpage',
-               'range_block_disabled' => 'rangedisabled',
-               'rcpatroldisabled' => 'patroldisabled',
-               'readonlytext' => 'readonly',
-               'sessionfailure' => 'badtoken',
-               'systemblockedtext' => 'blocked',
-               'titleprotected' => 'protectedtitle',
-               'undo-failure' => 'undofailure',
-               'userrights-nodatabase' => 'nosuchdatabase',
-               'userrights-no-interwiki' => 'nointerwikiuserrights',
-       ];
-
-       protected $apiCode = null;
-       protected $apiData = [];
-
-       public function getApiCode() {
-               if ( $this->apiCode === null ) {
-                       $key = $this->getKey();
-                       if ( isset( self::$messageMap[$key] ) ) {
-                               $this->apiCode = self::$messageMap[$key];
-                       } elseif ( $key === 'apierror-missingparam' ) {
-                               /// @todo: Kill this case along with ApiBase::$messageMap
-                               $this->apiCode = 'no' . $this->getParams()[0];
-                       } elseif ( substr( $key, 0, 8 ) === 'apiwarn-' ) {
-                               $this->apiCode = substr( $key, 8 );
-                       } elseif ( substr( $key, 0, 9 ) === 'apierror-' ) {
-                               $this->apiCode = substr( $key, 9 );
-                       } else {
-                               $this->apiCode = $key;
-                       }
-               }
-               return $this->apiCode;
-       }
-
-       public function setApiCode( $code, array $data = null ) {
-               if ( $code !== null && !( is_string( $code ) && $code !== '' ) ) {
-                       throw new InvalidArgumentException( "Invalid code \"$code\"" );
-               }
-
-               $this->apiCode = $code;
-               if ( $data !== null ) {
-                       $this->setApiData( $data );
-               }
-       }
-
-       public function getApiData() {
-               return $this->apiData;
-       }
-
-       public function setApiData( array $data ) {
-               $this->apiData = $data;
-       }
-
-       public function serialize() {
-               return serialize( [
-                       'parent' => parent::serialize(),
-                       'apiCode' => $this->apiCode,
-                       'apiData' => $this->apiData,
-               ] );
-       }
-
-       public function unserialize( $serialized ) {
-               $data = unserialize( $serialized );
-               parent::unserialize( $data['parent'] );
-               $this->apiCode = $data['apiCode'];
-               $this->apiData = $data['apiData'];
-       }
-}
-
 /**
  * Extension of Message implementing IApiMessage
  * @since 1.25
@@ -266,36 +87,3 @@ class ApiMessage extends Message implements IApiMessage {
                $this->setApiCode( $code, $data );
        }
 }
-
-/**
- * Extension of RawMessage implementing IApiMessage
- * @since 1.25
- * @ingroup API
- */
-class ApiRawMessage extends RawMessage implements IApiMessage {
-       use ApiMessageTrait;
-
-       /**
-        * @param RawMessage|string|array $msg
-        *  - RawMessage: is cloned
-        *  - array: first element is $key, rest are $params to RawMessage::__construct
-        *  - string: passed to RawMessage::__construct
-        * @param string|null $code
-        * @param array|null $data
-        */
-       public function __construct( $msg, $code = null, array $data = null ) {
-               if ( $msg instanceof RawMessage ) {
-                       foreach ( get_class_vars( get_class( $this ) ) as $key => $value ) {
-                               if ( isset( $msg->$key ) ) {
-                                       $this->$key = $msg->$key;
-                               }
-                       }
-               } elseif ( is_array( $msg ) ) {
-                       $key = array_shift( $msg );
-                       parent::__construct( $key, $msg );
-               } else {
-                       parent::__construct( $msg );
-               }
-               $this->setApiCode( $code, $data );
-       }
-}
diff --git a/includes/api/ApiMessageTrait.php b/includes/api/ApiMessageTrait.php
new file mode 100644 (file)
index 0000000..18b6bc4
--- /dev/null
@@ -0,0 +1,145 @@
+<?php
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+/**
+ * Trait to implement the IApiMessage interface for Message subclasses
+ * @since 1.27
+ * @ingroup API
+ */
+trait ApiMessageTrait {
+
+       /**
+        * Compatibility code mappings for various MW messages.
+        * @todo Ideally anything relying on this should be changed to use ApiMessage.
+        */
+       protected static $messageMap = [
+               'actionthrottledtext' => 'ratelimited',
+               'autoblockedtext' => 'autoblocked',
+               'badaccess-group0' => 'permissiondenied',
+               'badaccess-groups' => 'permissiondenied',
+               'badipaddress' => 'invalidip',
+               'blankpage' => 'emptypage',
+               'blockedtext' => 'blocked',
+               'cannotdelete' => 'cantdelete',
+               'cannotundelete' => 'cantundelete',
+               'cantmove-titleprotected' => 'protectedtitle',
+               'cantrollback' => 'onlyauthor',
+               'confirmedittext' => 'confirmemail',
+               'content-not-allowed-here' => 'contentnotallowedhere',
+               'deleteprotected' => 'cantedit',
+               'delete-toobig' => 'bigdelete',
+               'edit-conflict' => 'editconflict',
+               'imagenocrossnamespace' => 'nonfilenamespace',
+               'imagetypemismatch' => 'filetypemismatch',
+               'importbadinterwiki' => 'badinterwiki',
+               'importcantopen' => 'cantopenfile',
+               'import-noarticle' => 'badinterwiki',
+               'importnofile' => 'nofile',
+               'importuploaderrorpartial' => 'partialupload',
+               'importuploaderrorsize' => 'filetoobig',
+               'importuploaderrortemp' => 'notempdir',
+               'ipb_already_blocked' => 'alreadyblocked',
+               'ipb_blocked_as_range' => 'blockedasrange',
+               'ipb_cant_unblock' => 'cantunblock',
+               'ipb_expiry_invalid' => 'invalidexpiry',
+               'ip_range_invalid' => 'invalidrange',
+               'mailnologin' => 'cantsend',
+               'markedaspatrollederror-noautopatrol' => 'noautopatrol',
+               'movenologintext' => 'cantmove-anon',
+               'movenotallowed' => 'cantmove',
+               'movenotallowedfile' => 'cantmovefile',
+               'namespaceprotected' => 'protectednamespace',
+               'nocreate-loggedin' => 'cantcreate',
+               'nocreatetext' => 'cantcreate-anon',
+               'noname' => 'invaliduser',
+               'nosuchusershort' => 'nosuchuser',
+               'notanarticle' => 'missingtitle',
+               'nouserspecified' => 'invaliduser',
+               'ns-specialprotected' => 'unsupportednamespace',
+               'protect-cantedit' => 'cantedit',
+               'protectedinterface' => 'protectednamespace-interface',
+               'protectedpagetext' => 'protectedpage',
+               'range_block_disabled' => 'rangedisabled',
+               'rcpatroldisabled' => 'patroldisabled',
+               'readonlytext' => 'readonly',
+               'sessionfailure' => 'badtoken',
+               'systemblockedtext' => 'blocked',
+               'titleprotected' => 'protectedtitle',
+               'undo-failure' => 'undofailure',
+               'userrights-nodatabase' => 'nosuchdatabase',
+               'userrights-no-interwiki' => 'nointerwikiuserrights',
+       ];
+
+       protected $apiCode = null;
+       protected $apiData = [];
+
+       public function getApiCode() {
+               if ( $this->apiCode === null ) {
+                       $key = $this->getKey();
+                       if ( isset( self::$messageMap[$key] ) ) {
+                               $this->apiCode = self::$messageMap[$key];
+                       } elseif ( $key === 'apierror-missingparam' ) {
+                               /// @todo: Kill this case along with ApiBase::$messageMap
+                               $this->apiCode = 'no' . $this->getParams()[0];
+                       } elseif ( substr( $key, 0, 8 ) === 'apiwarn-' ) {
+                               $this->apiCode = substr( $key, 8 );
+                       } elseif ( substr( $key, 0, 9 ) === 'apierror-' ) {
+                               $this->apiCode = substr( $key, 9 );
+                       } else {
+                               $this->apiCode = $key;
+                       }
+               }
+               return $this->apiCode;
+       }
+
+       public function setApiCode( $code, array $data = null ) {
+               if ( $code !== null && !( is_string( $code ) && $code !== '' ) ) {
+                       throw new InvalidArgumentException( "Invalid code \"$code\"" );
+               }
+
+               $this->apiCode = $code;
+               if ( $data !== null ) {
+                       $this->setApiData( $data );
+               }
+       }
+
+       public function getApiData() {
+               return $this->apiData;
+       }
+
+       public function setApiData( array $data ) {
+               $this->apiData = $data;
+       }
+
+       public function serialize() {
+               return serialize( [
+                       'parent' => parent::serialize(),
+                       'apiCode' => $this->apiCode,
+                       'apiData' => $this->apiData,
+               ] );
+       }
+
+       public function unserialize( $serialized ) {
+               $data = unserialize( $serialized );
+               parent::unserialize( $data['parent'] );
+               $this->apiCode = $data['apiCode'];
+               $this->apiData = $data['apiData'];
+       }
+}
index e02c862..d2df013 100644 (file)
@@ -96,7 +96,7 @@ class ApiModuleManager extends ContextSource {
                foreach ( $modules as $name => $moduleSpec ) {
                        if ( is_array( $moduleSpec ) ) {
                                $class = $moduleSpec['class'];
-                               $factory = ( isset( $moduleSpec['factory'] ) ? $moduleSpec['factory'] : null );
+                               $factory = ( $moduleSpec['factory'] ?? null );
                        } else {
                                $class = $moduleSpec;
                                $factory = null;
@@ -143,7 +143,7 @@ class ApiModuleManager extends ContextSource {
         * Get module instance by name, or instantiate it if it does not exist
         *
         * @param string $moduleName Module name
-        * @param string $group Optionally validate that the module is in a specific group
+        * @param string|null $group Optionally validate that the module is in a specific group
         * @param bool $ignoreCache If true, force-creates a new instance and does not cache it
         *
         * @return ApiBase|null The new module instance, or null if failed
@@ -205,7 +205,7 @@ class ApiModuleManager extends ContextSource {
 
        /**
         * Get an array of modules in a specific group or all if no group is set.
-        * @param string $group Optional group filter
+        * @param string|null $group Optional group filter
         * @return array List of module names
         */
        public function getNames( $group = null ) {
@@ -224,7 +224,7 @@ class ApiModuleManager extends ContextSource {
 
        /**
         * Create an array of (moduleName => moduleClass) for a specific group or for all.
-        * @param string $group Name of the group to get or null for all
+        * @param string|null $group Name of the group to get or null for all
         * @return array Name=>class map
         */
        public function getNamesWithClasses( $group = null ) {
@@ -256,7 +256,7 @@ class ApiModuleManager extends ContextSource {
        /**
         * Returns true if the specific module is defined at all or in a specific group.
         * @param string $moduleName Module name
-        * @param string $group Group name to check against, or null to check all groups,
+        * @param string|null $group Group name to check against, or null to check all groups,
         * @return bool True if defined
         */
        public function isDefined( $moduleName, $group = null ) {
index 4b76906..fe7d10d 100644 (file)
@@ -29,11 +29,15 @@ use MediaWiki\MediaWikiServices;
  * @ingroup API
  */
 class ApiOptions extends ApiBase {
+       /** @var User User account to modify */
+       private $userForUpdates;
+
        /**
         * Changes preferences of the current user.
         */
        public function execute() {
-               if ( $this->getUser()->isAnon() ) {
+               $user = $this->getUserForUpdates();
+               if ( !$user || $user->isAnon() ) {
                        $this->dieWithError(
                                [ 'apierror-mustbeloggedin', $this->msg( 'action-editmyoptions' ) ], 'notloggedin'
                        );
@@ -48,16 +52,8 @@ class ApiOptions extends ApiBase {
                        $this->dieWithError( [ 'apierror-missingparam', 'optionname' ] );
                }
 
-               // Load the user from the master to reduce CAS errors on double post (T95839)
-               $user = $this->getUser()->getInstanceForUpdate();
-               if ( !$user ) {
-                       $this->dieWithError(
-                               [ 'apierror-mustbeloggedin', $this->msg( 'action-editmyoptions' ) ], 'notloggedin'
-                       );
-               }
-
                if ( $params['reset'] ) {
-                       $user->resetOptions( $params['resetkinds'], $this->getContext() );
+                       $this->resetPreferences( $params['resetkinds'] );
                        $changed = true;
                }
 
@@ -65,19 +61,18 @@ class ApiOptions extends ApiBase {
                if ( $params['change'] ) {
                        foreach ( $params['change'] as $entry ) {
                                $array = explode( '=', $entry, 2 );
-                               $changes[$array[0]] = isset( $array[1] ) ? $array[1] : null;
+                               $changes[$array[0]] = $array[1] ?? null;
                        }
                }
                if ( isset( $params['optionname'] ) ) {
-                       $newValue = isset( $params['optionvalue'] ) ? $params['optionvalue'] : null;
+                       $newValue = $params['optionvalue'] ?? null;
                        $changes[$params['optionname']] = $newValue;
                }
                if ( !$changed && !count( $changes ) ) {
                        $this->dieWithError( 'apierror-nochanges' );
                }
 
-               $preferencesFactory = MediaWikiServices::getInstance()->getPreferencesFactory();
-               $prefs = $preferencesFactory->getFormDescriptor( $user, $this->getContext() );
+               $prefs = $this->getPreferences();
                $prefsKinds = $user->getOptionKinds( $this->getContext(), $changes );
 
                $htmlForm = null;
@@ -117,7 +112,7 @@ class ApiOptions extends ApiBase {
                                        break;
                        }
                        if ( $validation === true ) {
-                               $user->setOption( $key, $value );
+                               $this->setPreference( $key, $value );
                                $changed = true;
                        } else {
                                $this->addWarning( [ 'apiwarn-validationfailed', wfEscapeWikiText( $key ), $validation ] );
@@ -125,13 +120,59 @@ class ApiOptions extends ApiBase {
                }
 
                if ( $changed ) {
-                       // Commit changes
-                       $user->saveSettings();
+                       $this->commitChanges();
                }
 
                $this->getResult()->addValue( null, $this->getModuleName(), 'success' );
        }
 
+       /**
+        * Load the user from the master to reduce CAS errors on double post (T95839)
+        *
+        * @return null|User
+        */
+       protected function getUserForUpdates() {
+               if ( !$this->userForUpdates ) {
+                       $this->userForUpdates = $this->getUser()->getInstanceForUpdate();
+               }
+
+               return $this->userForUpdates;
+       }
+
+       /**
+        * Returns preferences form descriptor
+        * @return mixed[][]
+        */
+       protected function getPreferences() {
+               $preferencesFactory = MediaWikiServices::getInstance()->getPreferencesFactory();
+               return $preferencesFactory->getFormDescriptor( $this->getUserForUpdates(),
+                       $this->getContext() );
+       }
+
+       /**
+        * @param string[] $kinds One or more types returned by User::listOptionKinds() or 'all'
+        */
+       protected function resetPreferences( array $kinds ) {
+               $this->getUserForUpdates()->resetOptions( $kinds, $this->getContext() );
+       }
+
+       /**
+        * Sets one user preference to be applied by commitChanges()
+        *
+        * @param string $preference
+        * @param mixed $value
+        */
+       protected function setPreference( $preference, $value ) {
+               $this->getUserForUpdates()->setOption( $preference, $value );
+       }
+
+       /**
+        * Applies changes to user preferences
+        */
+       protected function commitChanges() {
+               $this->getUserForUpdates()->saveSettings();
+       }
+
        public function mustBePosted() {
                return true;
        }
index 48303a5..ea2a85f 100644 (file)
@@ -460,7 +460,7 @@ class ApiPageSet extends ApiBase {
        /**
         * Get a list of redirect resolutions - maps a title to its redirect
         * target. Includes generator data for redirect source when available.
-        * @param ApiResult $result
+        * @param ApiResult|null $result
         * @return array Array of prefixed_title (string) => Title object
         * @since 1.21
         */
@@ -507,7 +507,7 @@ class ApiPageSet extends ApiBase {
        /**
         * Get a list of title normalizations - maps a title to its normalized
         * version in the form of result array.
-        * @param ApiResult $result
+        * @param ApiResult|null $result
         * @return array Array of raw_prefixed_title (string) => prefixed_title (string)
         * @since 1.21
         */
@@ -542,7 +542,7 @@ class ApiPageSet extends ApiBase {
        /**
         * Get a list of title conversions - maps a title to its converted
         * version as a result array.
-        * @param ApiResult $result
+        * @param ApiResult|null $result
         * @return array Array of (from, to) strings
         * @since 1.21
         */
@@ -573,7 +573,7 @@ class ApiPageSet extends ApiBase {
        /**
         * Get a list of interwiki titles - maps a title to its interwiki
         * prefix as result.
-        * @param ApiResult $result
+        * @param ApiResult|null $result
         * @param bool $iwUrl
         * @return array Array of raw_prefixed_title (string) => interwiki_prefix (string)
         * @since 1.21
@@ -692,7 +692,7 @@ class ApiPageSet extends ApiBase {
 
        /**
         * Revision IDs that were not found in the database as result array.
-        * @param ApiResult $result
+        * @param ApiResult|null $result
         * @return array Array of revision IDs
         * @since 1.21
         */
@@ -771,7 +771,8 @@ class ApiPageSet extends ApiBase {
                // Store Title object in various data structures
                $title = Title::newFromRow( $row );
 
-               LinkCache::singleton()->addGoodLinkObjFromRow( $title, $row );
+               $linkCache = MediaWikiServices::getInstance()->getLinkCache();
+               $linkCache->addGoodLinkObjFromRow( $title, $row );
 
                $pageId = intval( $row->page_id );
                $this->mAllPages[$row->page_namespace][$row->page_title] = $pageId;
@@ -904,7 +905,7 @@ class ApiPageSet extends ApiBase {
                        // Any items left in the $remaining list are added as missing
                        if ( $processTitles ) {
                                // The remaining titles in $remaining are non-existent pages
-                               $linkCache = LinkCache::singleton();
+                               $linkCache = MediaWikiServices::getInstance()->getLinkCache();
                                foreach ( $remaining as $ns => $dbkeys ) {
                                        foreach ( array_keys( $dbkeys ) as $dbkey ) {
                                                $title = Title::makeTitle( $ns, $dbkey );
@@ -1199,7 +1200,7 @@ class ApiPageSet extends ApiBase {
                                // Variants checking
                                global $wgContLang;
                                if ( $this->mConvertTitles &&
-                                       count( $wgContLang->getVariants() ) > 1 &&
+                                       $wgContLang->hasVariants() &&
                                        !$titleObj->exists()
                                ) {
                                        // Language::findVariantLink will modify titleText and titleObj into
index b8a32ae..c81cf7e 100644 (file)
@@ -339,9 +339,7 @@ class ApiParamInfo extends ApiBase {
                        }
 
                        if ( !isset( $settings[ApiBase::PARAM_TYPE] ) ) {
-                               $dflt = isset( $settings[ApiBase::PARAM_DFLT] )
-                                       ? $settings[ApiBase::PARAM_DFLT]
-                                       : null;
+                               $dflt = $settings[ApiBase::PARAM_DFLT] ?? null;
                                if ( is_bool( $dflt ) ) {
                                        $settings[ApiBase::PARAM_TYPE] = 'boolean';
                                } elseif ( is_string( $dflt ) || is_null( $dflt ) ) {
@@ -445,9 +443,7 @@ class ApiParamInfo extends ApiBase {
                                        $allowAll = true;
                                        $allSpecifier = ApiBase::ALL_DEFAULT_STRING;
                                } else {
-                                       $allowAll = isset( $settings[ApiBase::PARAM_ALL] )
-                                               ? $settings[ApiBase::PARAM_ALL]
-                                               : false;
+                                       $allowAll = $settings[ApiBase::PARAM_ALL] ?? false;
                                        $allSpecifier = ( is_string( $allowAll ) ? $allowAll : ApiBase::ALL_DEFAULT_STRING );
                                }
                                if ( $allowAll && $item['multi'] &&
index 096122d..3a60471 100644 (file)
@@ -697,7 +697,7 @@ class ApiParse extends ApiBase {
                        $hiddencats[$row->page_title] = isset( $row->pp_propname );
                }
 
-               $linkCache = LinkCache::singleton();
+               $linkCache = MediaWikiServices::getInstance()->getLinkCache();
 
                foreach ( $links as $link => $sortkey ) {
                        $entry = [];
index a20aca4..2b65f95 100644 (file)
@@ -22,6 +22,8 @@
  * @file
  */
 
+use MediaWiki\MediaWikiServices;
+
 /**
  * Allows user to patrol pages
  * @ingroup API
@@ -41,11 +43,12 @@ class ApiPatrol extends ApiBase {
                                $this->dieWithError( [ 'apierror-nosuchrcid', $params['rcid'] ] );
                        }
                } else {
-                       $rev = Revision::newFromId( $params['revid'] );
+                       $store = MediaWikiServices::getInstance()->getRevisionStore();
+                       $rev = $store->getRevisionById( $params['revid'] );
                        if ( !$rev ) {
                                $this->dieWithError( [ 'apierror-nosuchrevid', $params['revid'] ] );
                        }
-                       $rc = $rev->getRecentChange();
+                       $rc = $store->getRecentChange( $rev );
                        if ( !$rc ) {
                                $this->dieWithError( [ 'apierror-notpatrollable', $params['revid'] ] );
                        }
index e49024d..c68ec2b 100644 (file)
@@ -98,7 +98,7 @@ class ApiQuery extends ApiBase {
                'recentchanges' => ApiQueryRecentChanges::class,
                'search' => ApiQuerySearch::class,
                'tags' => ApiQueryTags::class,
-               'usercontribs' => ApiQueryContributions::class,
+               'usercontribs' => ApiQueryUserContribs::class,
                'users' => ApiQueryUsers::class,
                'watchlist' => ApiQueryWatchlist::class,
                'watchlistraw' => ApiQueryWatchlistRaw::class,
index be12977..50afc7d 100644 (file)
@@ -23,6 +23,9 @@
  * @file
  */
 
+use MediaWiki\MediaWikiServices;
+use MediaWiki\Storage\RevisionRecord;
+
 /**
  * Query module to enumerate all deleted revisions.
  *
@@ -35,7 +38,7 @@ class ApiQueryAllDeletedRevisions extends ApiQueryRevisionsBase {
        }
 
        /**
-        * @param ApiPageSet $resultPageSet
+        * @param ApiPageSet|null $resultPageSet
         * @return void
         */
        protected function run( ApiPageSet $resultPageSet = null ) {
@@ -45,6 +48,7 @@ class ApiQueryAllDeletedRevisions extends ApiQueryRevisionsBase {
                $user = $this->getUser();
                $db = $this->getDB();
                $params = $this->extractRequestParams( false );
+               $revisionStore = MediaWikiServices::getInstance()->getRevisionStore();
 
                $result = $this->getResult();
 
@@ -103,7 +107,7 @@ class ApiQueryAllDeletedRevisions extends ApiQueryRevisionsBase {
 
                if ( $resultPageSet === null ) {
                        $this->parseParameters( $params );
-                       $arQuery = Revision::getArchiveQueryInfo();
+                       $arQuery = $revisionStore->getArchiveQueryInfo();
                        $this->addTables( $arQuery['tables'] );
                        $this->addJoinConds( $arQuery['joins'] );
                        $this->addFields( $arQuery['fields'] );
@@ -149,11 +153,7 @@ class ApiQueryAllDeletedRevisions extends ApiQueryRevisionsBase {
                $miser_ns = null;
 
                if ( $mode == 'all' ) {
-                       if ( $params['namespace'] !== null ) {
-                               $namespaces = $params['namespace'];
-                       } else {
-                               $namespaces = MWNamespace::getValidNamespaces();
-                       }
+                       $namespaces = $params['namespace'] ?? MWNamespace::getValidNamespaces();
                        $this->addWhereFld( 'ar_namespace', $namespaces );
 
                        // For from/to/prefix, we have to consider the potential
@@ -239,9 +239,9 @@ class ApiQueryAllDeletedRevisions extends ApiQueryRevisionsBase {
                        // (shouldn't be able to get here without 'deletedhistory', but
                        // check it again just in case)
                        if ( !$user->isAllowed( 'deletedhistory' ) ) {
-                               $bitmask = Revision::DELETED_USER;
+                               $bitmask = RevisionRecord::DELETED_USER;
                        } elseif ( !$user->isAllowedAny( 'suppressrevision', 'viewsuppressed' ) ) {
-                               $bitmask = Revision::DELETED_USER | Revision::DELETED_RESTRICTED;
+                               $bitmask = RevisionRecord::DELETED_USER | RevisionRecord::DELETED_RESTRICTED;
                        } else {
                                $bitmask = 0;
                        }
@@ -347,13 +347,13 @@ class ApiQueryAllDeletedRevisions extends ApiQueryRevisionsBase {
                                        $generated[] = $row->ar_rev_id;
                                }
                        } else {
-                               $revision = Revision::newFromArchiveRow( $row );
+                               $revision = $revisionStore->newRevisionFromArchiveRow( $row );
                                $rev = $this->extractRevisionInfo( $revision, $row );
 
                                if ( !isset( $pageMap[$row->ar_namespace][$row->ar_title] ) ) {
                                        $index = $nextIndex++;
                                        $pageMap[$row->ar_namespace][$row->ar_title] = $index;
-                                       $title = $revision->getTitle();
+                                       $title = Title::newFromLinkTarget( $revision->getPageAsLinkTarget() );
                                        $a = [
                                                'pageid' => $title->getArticleID(),
                                                'revisions' => [ $rev ],
index 14f1cc4..c7a0cbc 100644 (file)
@@ -129,15 +129,15 @@ class ApiQueryAllImages extends ApiQueryGeneratorBase {
                        if ( !is_null( $params['continue'] ) ) {
                                $cont = explode( '|', $params['continue'] );
                                $this->dieContinueUsageIf( count( $cont ) != 1 );
-                               $op = ( $ascendingOrder ? '>' : '<' );
+                               $op = $ascendingOrder ? '>' : '<';
                                $continueFrom = $db->addQuotes( $cont[0] );
                                $this->addWhere( "img_name $op= $continueFrom" );
                        }
 
                        // Image filters
-                       $from = ( $params['from'] === null ? null : $this->titlePartToKey( $params['from'], NS_FILE ) );
-                       $to = ( $params['to'] === null ? null : $this->titlePartToKey( $params['to'], NS_FILE ) );
-                       $this->addWhereRange( 'img_name', ( $ascendingOrder ? 'newer' : 'older' ), $from, $to );
+                       $from = $params['from'] === null ? null : $this->titlePartToKey( $params['from'], NS_FILE );
+                       $to = $params['to'] === null ? null : $this->titlePartToKey( $params['to'], NS_FILE );
+                       $this->addWhereRange( 'img_name', $ascendingOrder ? 'newer' : 'older', $from, $to );
 
                        if ( isset( $params['prefix'] ) ) {
                                $this->addWhere( 'img_name' . $db->buildLike(
@@ -210,7 +210,7 @@ class ApiQueryAllImages extends ApiQueryGeneratorBase {
                                                'ug_expiry IS NULL OR ug_expiry >= ' . $db->addQuotes( $db->timestamp() )
                                        ]
                                ] ] );
-                               $groupCond = ( $params['filterbots'] == 'nobots' ? 'NULL' : 'NOT NULL' );
+                               $groupCond = $params['filterbots'] == 'nobots' ? 'NULL' : 'NOT NULL';
                                $this->addWhere( "ug_group IS $groupCond" );
                        }
                }
index 057dbb2..8377e74 100644 (file)
@@ -150,10 +150,10 @@ class ApiQueryAllLinks extends ApiQueryGeneratorBase {
                }
 
                // 'continue' always overrides 'from'
-               $from = $continue || $params['from'] === null ? null :
-                       $this->titlePartToKey( $params['from'], $namespace ) );
-               $to = $params['to'] === null ? null :
-                       $this->titlePartToKey( $params['to'], $namespace ) );
+               $from = $continue || $params['from'] === null ? null :
+                       $this->titlePartToKey( $params['from'], $namespace );
+               $to = $params['to'] === null ? null :
+                       $this->titlePartToKey( $params['to'], $namespace );
                $this->addWhereRange( $pfx . $fieldTitle, 'newer', $from, $to );
 
                if ( isset( $params['prefix'] ) ) {
index 3af2459..833e2e4 100644 (file)
@@ -20,6 +20,9 @@
  * @file
  */
 
+use MediaWiki\MediaWikiServices;
+use MediaWiki\Storage\RevisionRecord;
+
 /**
  * Query module to enumerate all revisions.
  *
@@ -33,12 +36,13 @@ class ApiQueryAllRevisions extends ApiQueryRevisionsBase {
        }
 
        /**
-        * @param ApiPageSet $resultPageSet
+        * @param ApiPageSet|null $resultPageSet
         * @return void
         */
        protected function run( ApiPageSet $resultPageSet = null ) {
                $db = $this->getDB();
                $params = $this->extractRequestParams( false );
+               $revisionStore = MediaWikiServices::getInstance()->getRevisionStore();
 
                $result = $this->getResult();
 
@@ -63,7 +67,7 @@ class ApiQueryAllRevisions extends ApiQueryRevisionsBase {
 
                if ( $resultPageSet === null ) {
                        $this->parseParameters( $params );
-                       $revQuery = Revision::getQueryInfo(
+                       $revQuery = $revisionStore->getQueryInfo(
                                $this->fetchContent ? [ 'page', 'text' ] : [ 'page' ]
                        );
                        $this->addTables( $revQuery['tables'] );
@@ -120,9 +124,9 @@ class ApiQueryAllRevisions extends ApiQueryRevisionsBase {
                if ( $params['user'] !== null || $params['excludeuser'] !== null ) {
                        // Paranoia: avoid brute force searches (T19342)
                        if ( !$this->getUser()->isAllowed( 'deletedhistory' ) ) {
-                               $bitmask = Revision::DELETED_USER;
+                               $bitmask = RevisionRecord::DELETED_USER;
                        } elseif ( !$this->getUser()->isAllowedAny( 'suppressrevision', 'viewsuppressed' ) ) {
-                               $bitmask = Revision::DELETED_USER | Revision::DELETED_RESTRICTED;
+                               $bitmask = RevisionRecord::DELETED_USER | RevisionRecord::DELETED_RESTRICTED;
                        } else {
                                $bitmask = 0;
                        }
@@ -185,13 +189,13 @@ class ApiQueryAllRevisions extends ApiQueryRevisionsBase {
                                        $generated[] = $row->rev_id;
                                }
                        } else {
-                               $revision = Revision::newFromRow( $row );
+                               $revision = $revisionStore->newRevisionFromRow( $row );
                                $rev = $this->extractRevisionInfo( $revision, $row );
 
                                if ( !isset( $pageMap[$row->rev_page] ) ) {
                                        $index = $nextIndex++;
                                        $pageMap[$row->rev_page] = $index;
-                                       $title = $revision->getTitle();
+                                       $title = Title::newFromLinkTarget( $revision->getPageAsLinkTarget() );
                                        $a = [
                                                'pageid' => $title->getArticleID(),
                                                'revisions' => [ $rev ],
index fb90e25..bfacc51 100644 (file)
@@ -88,7 +88,7 @@ class ApiQueryBacklinksprop extends ApiQueryGeneratorBase {
        }
 
        /**
-        * @param ApiPageSet $resultPageSet
+        * @param ApiPageSet|null $resultPageSet
         */
        private function run( ApiPageSet $resultPageSet = null ) {
                $settings = self::$settings[$this->getModuleName()];
@@ -419,7 +419,7 @@ class ApiQueryBacklinksprop extends ApiQueryGeneratorBase {
                $settings = self::$settings[$this->getModuleName()];
                $name = $this->getModuleName();
                $path = $this->getModulePath();
-               $title = isset( $settings['exampletitle'] ) ? $settings['exampletitle'] : 'Main Page';
+               $title = $settings['exampletitle'] ?? 'Main Page';
                $etitle = rawurlencode( $title );
 
                return [
index 3ad45bb..b9ed9f2 100644 (file)
@@ -320,7 +320,7 @@ abstract class ApiQueryBase extends ApiBase {
         * Add an option such as LIMIT or USE INDEX. If an option was set
         * before, the old value will be overwritten
         * @param string $name Option name
-        * @param string|string[] $value Option value
+        * @param string|string[]|null $value Option value
         */
        protected function addOption( $name, $value = null ) {
                if ( is_null( $value ) ) {
@@ -402,8 +402,8 @@ abstract class ApiQueryBase extends ApiBase {
        }
 
        /**
-        * @param string $query
-        * @param string $protocol
+        * @param string|null $query
+        * @param string|null $protocol
         * @return null|string
         */
        public function prepareUrlQuerySearchString( $query = null, $protocol = null ) {
@@ -503,7 +503,7 @@ abstract class ApiQueryBase extends ApiBase {
         * Same as addPageSubItems(), but one element of $data at a time
         * @param int $pageId Page ID
         * @param array $item Data array à la ApiResult
-        * @param string $elemname XML element name. If null, getModuleName()
+        * @param string|null $elemname XML element name. If null, getModuleName()
         *  is used
         * @return bool Whether the element fit in the result
         */
index d07df5a..e39afac 100644 (file)
@@ -23,6 +23,9 @@
  * @since 1.23
  */
 
+use MediaWiki\MediaWikiServices;
+use MediaWiki\Storage\RevisionRecord;
+
 /**
  * A query module to show contributors to a page
  *
@@ -75,7 +78,7 @@ class ApiQueryContributors extends ApiQueryBase {
                }
 
                $result = $this->getResult();
-               $revQuery = Revision::getQueryInfo();
+               $revQuery = MediaWikiServices::getInstance()->getRevisionStore()->getQueryInfo();
 
                // For MIGRATION_NEW, target indexes on the revision_actor_temp table.
                // Otherwise, revision is fine because it'll have to check all revision rows anyway.
@@ -94,7 +97,7 @@ class ApiQueryContributors extends ApiQueryBase {
                ] );
                $this->addWhereFld( $pageField, $pages );
                $this->addWhere( ActorMigration::newMigration()->isAnon( $revQuery['fields']['rev_user'] ) );
-               $this->addWhere( $db->bitAnd( 'rev_deleted', Revision::DELETED_USER ) . ' = 0' );
+               $this->addWhere( $db->bitAnd( 'rev_deleted', RevisionRecord::DELETED_USER ) . ' = 0' );
                $this->addOption( 'GROUP BY', $pageField );
                $res = $this->select( __METHOD__ );
                foreach ( $res as $row ) {
@@ -106,7 +109,7 @@ class ApiQueryContributors extends ApiQueryBase {
                                // some other module used up all the space. Just set a dummy
                                // continue and hope it works next time.
                                $this->setContinueEnumParameter( 'continue',
-                                       $params['continue'] !== null ? $params['continue'] : '0|0'
+                                       $params['continue'] ?? '0|0'
                                );
 
                                return;
@@ -126,7 +129,7 @@ class ApiQueryContributors extends ApiQueryBase {
                ] );
                $this->addWhereFld( $pageField, $pages );
                $this->addWhere( ActorMigration::newMigration()->isNotAnon( $revQuery['fields']['rev_user'] ) );
-               $this->addWhere( $db->bitAnd( 'rev_deleted', Revision::DELETED_USER ) . ' = 0' );
+               $this->addWhere( $db->bitAnd( 'rev_deleted', RevisionRecord::DELETED_USER ) . ' = 0' );
                $this->addOption( 'GROUP BY', [ $pageField, $idField ] );
                $this->addOption( 'LIMIT', $params['limit'] + 1 );
 
index 1a1e8f7..c3af71b 100644 (file)
@@ -23,6 +23,9 @@
  * @file
  */
 
+use MediaWiki\MediaWikiServices;
+use MediaWiki\Storage\RevisionRecord;
+
 /**
  * Query module to enumerate deleted revisions for pages.
  *
@@ -55,12 +58,13 @@ class ApiQueryDeletedRevisions extends ApiQueryRevisionsBase {
                $params = $this->extractRequestParams( false );
 
                $db = $this->getDB();
+               $revisionStore = MediaWikiServices::getInstance()->getRevisionStore();
 
                $this->requireMaxOneParameter( $params, 'user', 'excludeuser' );
 
                if ( $resultPageSet === null ) {
                        $this->parseParameters( $params );
-                       $arQuery = Revision::getArchiveQueryInfo();
+                       $arQuery = $revisionStore->getArchiveQueryInfo();
                        $this->addTables( $arQuery['tables'] );
                        $this->addFields( $arQuery['fields'] );
                        $this->addJoinConds( $arQuery['joins'] );
@@ -132,9 +136,9 @@ class ApiQueryDeletedRevisions extends ApiQueryRevisionsBase {
                        // (shouldn't be able to get here without 'deletedhistory', but
                        // check it again just in case)
                        if ( !$user->isAllowed( 'deletedhistory' ) ) {
-                               $bitmask = Revision::DELETED_USER;
+                               $bitmask = RevisionRecord::DELETED_USER;
                        } elseif ( !$user->isAllowedAny( 'suppressrevision', 'viewsuppressed' ) ) {
-                               $bitmask = Revision::DELETED_USER | Revision::DELETED_RESTRICTED;
+                               $bitmask = RevisionRecord::DELETED_USER | RevisionRecord::DELETED_RESTRICTED;
                        } else {
                                $bitmask = 0;
                        }
@@ -234,7 +238,7 @@ class ApiQueryDeletedRevisions extends ApiQueryRevisionsBase {
 
                                $fit = $this->addPageSubItem(
                                        $pageMap[$row->ar_namespace][$row->ar_title],
-                                       $this->extractRevisionInfo( Revision::newFromArchiveRow( $row ), $row ),
+                                       $this->extractRevisionInfo( $revisionStore->newRevisionFromArchiveRow( $row ), $row ),
                                        'rev'
                                );
                                if ( !$fit ) {
index fd196aa..6c219d4 100644 (file)
@@ -66,7 +66,7 @@ class ApiQueryExternalLinks extends ApiQueryBase {
                }
 
                $this->addOption( 'LIMIT', $params['limit'] + 1 );
-               $offset = isset( $params['offset'] ) ? $params['offset'] : 0;
+               $offset = $params['offset'] ?? 0;
                if ( $offset ) {
                        $this->addOption( 'OFFSET', $params['offset'] );
                }
index 4589991..279bc0a 100644 (file)
@@ -81,6 +81,7 @@ class ApiQueryFileRepoInfo extends ApiQueryBase {
                                ApiBase::PARAM_DFLT => implode( '|', $props ),
                                ApiBase::PARAM_ISMULTI => true,
                                ApiBase::PARAM_TYPE => $props,
+                               ApiBase::PARAM_HELP_MSG_PER_VALUE => [],
                        ],
                ];
        }
@@ -100,14 +101,20 @@ class ApiQueryFileRepoInfo extends ApiQueryBase {
 
                $propValues[] = 'canUpload';
 
+               sort( $propValues );
                return $propValues;
        }
 
        protected function getExamplesMessages() {
-               return [
-                       'action=query&meta=filerepoinfo&friprop=apiurl|name|displayname'
-                               => 'apihelp-query+filerepoinfo-example-simple',
-               ];
+               $examples = [];
+
+               $props = array_intersect( [ 'apiurl', 'name', 'displayname' ], $this->getProps() );
+               if ( $props ) {
+                       $examples['action=query&meta=filerepoinfo&friprop=' . implode( '|', $props )] =
+                               'apihelp-query+filerepoinfo-example-simple';
+               }
+
+               return $examples;
        }
 
        public function getHelpUrls() {
index ebffb15..a6a3251 100644 (file)
@@ -24,6 +24,8 @@
  * @file
  */
 
+use MediaWiki\Storage\RevisionRecord;
+
 /**
  * Query module to enumerate all deleted files.
  *
@@ -153,7 +155,7 @@ class ApiQueryFilearchive extends ApiQueryBase {
                        self::addTitleInfo( $file, $title );
 
                        if ( $fld_description &&
-                               Revision::userCanBitfield( $row->fa_deleted, File::DELETED_COMMENT, $user )
+                               RevisionRecord::userCanBitfield( $row->fa_deleted, File::DELETED_COMMENT, $user )
                        ) {
                                $file['description'] = $commentStore->getComment( 'fa_description', $row )->text;
                                if ( isset( $prop['parseddescription'] ) ) {
@@ -162,7 +164,7 @@ class ApiQueryFilearchive extends ApiQueryBase {
                                }
                        }
                        if ( $fld_user &&
-                               Revision::userCanBitfield( $row->fa_deleted, File::DELETED_USER, $user )
+                               RevisionRecord::userCanBitfield( $row->fa_deleted, File::DELETED_USER, $user )
                        ) {
                                $file['userid'] = (int)$row->fa_user;
                                $file['user'] = $row->fa_user_text;
index 90aed6e..7193eeb 100644 (file)
@@ -42,7 +42,7 @@ class ApiQueryIWBacklinks extends ApiQueryGeneratorBase {
        }
 
        /**
-        * @param ApiPageSet $resultPageSet
+        * @param ApiPageSet|null $resultPageSet
         * @return void
         */
        public function run( $resultPageSet = null ) {
index e447f4f..8994e06 100644 (file)
@@ -127,7 +127,7 @@ class ApiQueryImageInfo extends ApiQueryBase {
                                        if ( count( $pageIds[NS_FILE] ) == 1 ) {
                                                // See the 'the user is screwed' comment below
                                                $this->setContinueEnumParameter( 'start',
-                                                       $start !== null ? $start : wfTimestamp( TS_ISO_8601, $img->getTimestamp() )
+                                                       $start ?? wfTimestamp( TS_ISO_8601, $img->getTimestamp() )
                                                );
                                        } else {
                                                $this->setContinueEnumParameter( 'continue',
@@ -152,7 +152,7 @@ class ApiQueryImageInfo extends ApiQueryBase {
                                                // thing again. When the violating queries have been
                                                // out-continued, the result will get through
                                                $this->setContinueEnumParameter( 'start',
-                                                       $start !== null ? $start : wfTimestamp( TS_ISO_8601, $img->getTimestamp() )
+                                                       $start ?? wfTimestamp( TS_ISO_8601, $img->getTimestamp() )
                                                );
                                        } else {
                                                $this->setContinueEnumParameter( 'continue',
@@ -359,7 +359,7 @@ class ApiQueryImageInfo extends ApiQueryBase {
         * @param File $file
         * @param array $prop Array of properties to get (in the keys)
         * @param ApiResult $result
-        * @param array $thumbParams Containing 'width' and 'height' items, or null
+        * @param array|null $thumbParams Containing 'width' and 'height' items, or null
         * @param array|bool|string $opts Options for data fetching.
         *   This is an array consisting of the keys:
         *    'version': The metadata version for the metadata option
index 9b99312..7145d4d 100644 (file)
@@ -42,7 +42,7 @@ class ApiQueryLangBacklinks extends ApiQueryGeneratorBase {
        }
 
        /**
-        * @param ApiPageSet $resultPageSet
+        * @param ApiPageSet|null $resultPageSet
         * @return void
         */
        public function run( $resultPageSet = null ) {
index 67bf619..144c758 100644 (file)
@@ -103,7 +103,7 @@ class ApiQueryLinks extends ApiQueryGeneratorBase {
                        if ( $cond ) {
                                $this->addWhere( $cond );
                                $multiNS = count( $lb->data ) !== 1;
-                               $multiTitle = count( call_user_func_array( 'array_merge', $lb->data ) ) !== 1;
+                               $multiTitle = count( array_merge( ...$lb->data ) ) !== 1;
                        } else {
                                // No titles so no results
                                return;
index 84e12d7..a6b97dd 100644 (file)
@@ -321,7 +321,7 @@ class ApiQueryLogEvents extends ApiQueryBase {
                        }
                        if ( LogEventsList::userCan( $row, LogPage::DELETED_USER, $user ) ) {
                                if ( $this->fld_user ) {
-                                       $vals['user'] = $row->user_name === null ? $row->log_user_text : $row->user_name;
+                                       $vals['user'] = $row->user_name ?? $row->log_user_text;
                                }
                                if ( $this->fld_userid ) {
                                        $vals['userid'] = intval( $row->log_user );
@@ -418,7 +418,7 @@ class ApiQueryLogEvents extends ApiQueryBase {
                                ApiBase::PARAM_HELP_MSG_PER_VALUE => [],
                        ],
                        'type' => [
-                               ApiBase::PARAM_TYPE => $config->get( 'LogTypes' )
+                               ApiBase::PARAM_TYPE => LogPage::validTypes(),
                        ],
                        'action' => [
                                // validation on request is done in execute()
index 2fbc518..04d3f2c 100644 (file)
@@ -51,7 +51,12 @@ class ApiQueryPrefixSearch extends ApiQueryGeneratorBase {
                $offset = $params['offset'];
 
                $searchEngine = $this->buildSearchEngine( $params );
-               $titles = $searchEngine->extractTitles( $searchEngine->completionSearchWithVariants( $search ) );
+               $suggestions = $searchEngine->completionSearchWithVariants( $search );
+               $titles = $searchEngine->extractTitles( $suggestions );
+
+               if ( $suggestions->hasMoreResults() ) {
+                       $this->setContinueEnumParameter( 'offset', $offset + $limit );
+               }
 
                if ( $resultPageSet ) {
                        $resultPageSet->setRedirectMergePolicy( function ( array $current, array $new ) {
@@ -60,10 +65,6 @@ class ApiQueryPrefixSearch extends ApiQueryGeneratorBase {
                                }
                                return $current;
                        } );
-                       if ( count( $titles ) > $limit ) {
-                               $this->setContinueEnumParameter( 'offset', $offset + $limit );
-                               array_pop( $titles );
-                       }
                        $resultPageSet->populateFromTitles( $titles );
                        foreach ( $titles as $index => $title ) {
                                $resultPageSet->setGeneratorData( $title, [ 'index' => $index + $offset + 1 ] );
@@ -72,10 +73,6 @@ class ApiQueryPrefixSearch extends ApiQueryGeneratorBase {
                        $result = $this->getResult();
                        $count = 0;
                        foreach ( $titles as $title ) {
-                               if ( ++$count > $limit ) {
-                                       $this->setContinueEnumParameter( 'offset', $offset + $limit );
-                                       break;
-                               }
                                $vals = [
                                        'ns' => intval( $title->getNamespace() ),
                                        'title' => $title->getPrefixedText(),
@@ -86,8 +83,9 @@ class ApiQueryPrefixSearch extends ApiQueryGeneratorBase {
                                        $vals['pageid'] = intval( $title->getArticleID() );
                                }
                                $fit = $result->addValue( [ 'query', $this->getModuleName() ], null, $vals );
+                               ++$count;
                                if ( !$fit ) {
-                                       $this->setContinueEnumParameter( 'offset', $offset + $count - 1 );
+                                       $this->setContinueEnumParameter( 'offset', $offset + $count );
                                        break;
                                }
                        }
index a828e11..8758d9c 100644 (file)
@@ -49,7 +49,7 @@ class ApiQueryQueryPage extends ApiQueryGeneratorBase {
        }
 
        /**
-        * @param ApiPageSet $resultPageSet
+        * @param ApiPageSet|null $resultPageSet
         */
        public function run( $resultPageSet = null ) {
                $params = $this->extractRequestParams();
index 326debc..a5be58b 100644 (file)
@@ -20,6 +20,8 @@
  * @file
  */
 
+use MediaWiki\Storage\RevisionRecord;
+
 /**
  * A query action to enumerate the recent changes that were done to the wiki.
  * Various filters are supported.
@@ -136,7 +138,7 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
        /**
         * Generates and outputs the result of this query based upon the provided parameters.
         *
-        * @param ApiPageSet $resultPageSet
+        * @param ApiPageSet|null $resultPageSet
         */
        public function run( $resultPageSet = null ) {
                $user = $this->getUser();
@@ -181,6 +183,16 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
                        }
                }
 
+               $title = $params['title'];
+               if ( !is_null( $title ) ) {
+                       $titleObj = Title::newFromText( $title );
+                       if ( is_null( $titleObj ) ) {
+                               $this->dieWithError( [ 'apierror-invalidtitle', wfEscapeWikiText( $title ) ] );
+                       }
+                       $this->addWhereFld( 'rc_namespace', $titleObj->getNamespace() );
+                       $this->addWhereFld( 'rc_title', $titleObj->getDBkey() );
+               }
+
                if ( !is_null( $params['show'] ) ) {
                        $show = array_flip( $params['show'] );
 
@@ -355,9 +367,9 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
                // Paranoia: avoid brute force searches (T19342)
                if ( !is_null( $params['user'] ) || !is_null( $params['excludeuser'] ) ) {
                        if ( !$user->isAllowed( 'deletedhistory' ) ) {
-                               $bitmask = Revision::DELETED_USER;
+                               $bitmask = RevisionRecord::DELETED_USER;
                        } elseif ( !$user->isAllowedAny( 'suppressrevision', 'viewsuppressed' ) ) {
-                               $bitmask = Revision::DELETED_USER | Revision::DELETED_RESTRICTED;
+                               $bitmask = RevisionRecord::DELETED_USER | RevisionRecord::DELETED_RESTRICTED;
                        } else {
                                $bitmask = 0;
                        }
@@ -497,11 +509,11 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
 
                /* Add user data and 'anon' flag, if user is anonymous. */
                if ( $this->fld_user || $this->fld_userid ) {
-                       if ( $row->rc_deleted & Revision::DELETED_USER ) {
+                       if ( $row->rc_deleted & RevisionRecord::DELETED_USER ) {
                                $vals['userhidden'] = true;
                                $anyHidden = true;
                        }
-                       if ( Revision::userCanBitfield( $row->rc_deleted, Revision::DELETED_USER, $user ) ) {
+                       if ( RevisionRecord::userCanBitfield( $row->rc_deleted, RevisionRecord::DELETED_USER, $user ) ) {
                                if ( $this->fld_user ) {
                                        $vals['user'] = $row->rc_user_text;
                                }
@@ -536,11 +548,13 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
 
                /* Add edit summary / log summary. */
                if ( $this->fld_comment || $this->fld_parsedcomment ) {
-                       if ( $row->rc_deleted & Revision::DELETED_COMMENT ) {
+                       if ( $row->rc_deleted & RevisionRecord::DELETED_COMMENT ) {
                                $vals['commenthidden'] = true;
                                $anyHidden = true;
                        }
-                       if ( Revision::userCanBitfield( $row->rc_deleted, Revision::DELETED_COMMENT, $user ) ) {
+                       if ( RevisionRecord::userCanBitfield(
+                               $row->rc_deleted, RevisionRecord::DELETED_COMMENT, $user
+                       ) ) {
                                $comment = $this->commentStore->getComment( 'rc_comment', $row )->text;
                                if ( $this->fld_comment ) {
                                        $vals['comment'] = $comment;
@@ -587,11 +601,13 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
                }
 
                if ( $this->fld_sha1 && $row->rev_sha1 !== null ) {
-                       if ( $row->rev_deleted & Revision::DELETED_TEXT ) {
+                       if ( $row->rev_deleted & RevisionRecord::DELETED_TEXT ) {
                                $vals['sha1hidden'] = true;
                                $anyHidden = true;
                        }
-                       if ( Revision::userCanBitfield( $row->rev_deleted, Revision::DELETED_TEXT, $user ) ) {
+                       if ( RevisionRecord::userCanBitfield(
+                               $row->rev_deleted, RevisionRecord::DELETED_TEXT, $user
+                       ) ) {
                                if ( $row->rev_sha1 !== '' ) {
                                        $vals['sha1'] = Wikimedia\base_convert( $row->rev_sha1, 36, 16, 40 );
                                } else {
@@ -613,7 +629,7 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
                        }
                }
 
-               if ( $anyHidden && ( $row->rc_deleted & Revision::DELETED_RESTRICTED ) ) {
+               if ( $anyHidden && ( $row->rc_deleted & RevisionRecord::DELETED_RESTRICTED ) ) {
                        $vals['suppressed'] = true;
                }
 
@@ -727,6 +743,7 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
                                ApiBase::PARAM_TYPE => RecentChange::getChangeTypes()
                        ],
                        'toponly' => false,
+                       'title' => null,
                        'continue' => [
                                ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
                        ],
index 5858bc7..5e7b864 100644 (file)
@@ -20,6 +20,9 @@
  * @file
  */
 
+use MediaWiki\MediaWikiServices;
+use MediaWiki\Storage\RevisionRecord;
+
 /**
  * A query action to enumerate revisions of a given page, or show top revisions
  * of multiple pages. Various pieces of information may be shown - flags,
@@ -81,6 +84,7 @@ class ApiQueryRevisions extends ApiQueryRevisionsBase {
 
        protected function run( ApiPageSet $resultPageSet = null ) {
                $params = $this->extractRequestParams( false );
+               $revisionStore = MediaWikiServices::getInstance()->getRevisionStore();
 
                // If any of those parameters are used, work in 'enumeration' mode.
                // Enum mode can only be used when exactly one page is provided.
@@ -139,7 +143,7 @@ class ApiQueryRevisions extends ApiQueryRevisionsBase {
                        if ( $this->fld_user ) {
                                $opts[] = 'user';
                        }
-                       $revQuery = Revision::getQueryInfo( $opts );
+                       $revQuery = $revisionStore->getQueryInfo( $opts );
                        $this->addTables( $revQuery['tables'] );
                        $this->addFields( $revQuery['fields'] );
                        $this->addJoinConds( $revQuery['joins'] );
@@ -301,9 +305,9 @@ class ApiQueryRevisions extends ApiQueryRevisionsBase {
                        if ( $params['user'] !== null || $params['excludeuser'] !== null ) {
                                // Paranoia: avoid brute force searches (T19342)
                                if ( !$this->getUser()->isAllowed( 'deletedhistory' ) ) {
-                                       $bitmask = Revision::DELETED_USER;
+                                       $bitmask = RevisionRecord::DELETED_USER;
                                } elseif ( !$this->getUser()->isAllowedAny( 'suppressrevision', 'viewsuppressed' ) ) {
-                                       $bitmask = Revision::DELETED_USER | Revision::DELETED_RESTRICTED;
+                                       $bitmask = RevisionRecord::DELETED_USER | RevisionRecord::DELETED_RESTRICTED;
                                } else {
                                        $bitmask = 0;
                                }
@@ -382,14 +386,15 @@ class ApiQueryRevisions extends ApiQueryRevisionsBase {
                        if ( $resultPageSet !== null ) {
                                $generated[] = $row->rev_id;
                        } else {
-                               $revision = new Revision( $row );
+                               $revision = $revisionStore->newRevisionFromRow( $row );
                                $rev = $this->extractRevisionInfo( $revision, $row );
 
                                if ( $this->token !== null ) {
-                                       $title = $revision->getTitle();
+                                       $title = Title::newFromLinkTarget( $revision->getPageAsLinkTarget() );
+                                       $revisionCompat = new Revision( $revision );
                                        $tokenFunctions = $this->getTokenFunctions();
                                        foreach ( $this->token as $t ) {
-                                               $val = call_user_func( $tokenFunctions[$t], $title->getArticleID(), $title, $revision );
+                                               $val = call_user_func( $tokenFunctions[$t], $title->getArticleID(), $title, $revisionCompat );
                                                if ( $val === false ) {
                                                        $this->addWarning( [ 'apiwarn-tokennotallowed', $t ] );
                                                } else {
index f888434..600c89e 100644 (file)
  * @file
  */
 
+use MediaWiki\Storage\RevisionAccessException;
+use MediaWiki\Storage\RevisionRecord;
+use MediaWiki\Storage\SlotRecord;
+use MediaWiki\MediaWikiServices;
+
 /**
  * A base class for functions common to producing a list of revisions.
  *
  */
 abstract class ApiQueryRevisionsBase extends ApiQueryGeneratorBase {
 
+       /**
+        * @name Constants for internal use. Don't use externally.
+        * @{
+        */
+
+       // Bits to indicate the results of the revdel permission check on a revision,
+       // see self::checkRevDel()
+       const IS_DELETED = 1; // Whether the field is revision-deleted
+       const CANNOT_VIEW = 2; // Whether the user cannot view the field due to revdel
+
+       /**@}*/
+
        protected $limit, $diffto, $difftotext, $difftotextpst, $expandTemplates, $generateXML,
-               $section, $parseContent, $fetchContent, $contentFormat, $setParsedLimit = true;
+               $section, $parseContent, $fetchContent, $contentFormat, $setParsedLimit = true,
+               $slotRoles = null, $needSlots;
 
        protected $fld_ids = false, $fld_flags = false, $fld_timestamp = false,
-               $fld_size = false, $fld_sha1 = false, $fld_comment = false,
-               $fld_parsedcomment = false, $fld_user = false, $fld_userid = false,
-               $fld_content = false, $fld_tags = false, $fld_contentmodel = false, $fld_parsetree = false;
+               $fld_size = false, $fld_slotsize = false, $fld_sha1 = false, $fld_slotsha1 = false,
+               $fld_comment = false, $fld_parsedcomment = false, $fld_user = false, $fld_userid = false,
+               $fld_content = false, $fld_tags = false, $fld_contentmodel = false, $fld_roles = false,
+               $fld_parsetree = false;
 
        public function execute() {
                $this->run();
@@ -44,7 +63,7 @@ abstract class ApiQueryRevisionsBase extends ApiQueryGeneratorBase {
        }
 
        /**
-        * @param ApiPageSet $resultPageSet
+        * @param ApiPageSet|null $resultPageSet
         * @return void
         */
        abstract protected function run( ApiPageSet $resultPageSet = null );
@@ -55,6 +74,55 @@ abstract class ApiQueryRevisionsBase extends ApiQueryGeneratorBase {
         * @param array $params
         */
        protected function parseParameters( $params ) {
+               $prop = array_flip( $params['prop'] );
+
+               $this->fld_ids = isset( $prop['ids'] );
+               $this->fld_flags = isset( $prop['flags'] );
+               $this->fld_timestamp = isset( $prop['timestamp'] );
+               $this->fld_comment = isset( $prop['comment'] );
+               $this->fld_parsedcomment = isset( $prop['parsedcomment'] );
+               $this->fld_size = isset( $prop['size'] );
+               $this->fld_slotsize = isset( $prop['slotsize'] );
+               $this->fld_sha1 = isset( $prop['sha1'] );
+               $this->fld_slotsha1 = isset( $prop['slotsha1'] );
+               $this->fld_content = isset( $prop['content'] );
+               $this->fld_contentmodel = isset( $prop['contentmodel'] );
+               $this->fld_userid = isset( $prop['userid'] );
+               $this->fld_user = isset( $prop['user'] );
+               $this->fld_tags = isset( $prop['tags'] );
+               $this->fld_roles = isset( $prop['roles'] );
+               $this->fld_parsetree = isset( $prop['parsetree'] );
+
+               $this->slotRoles = $params['slots'];
+
+               if ( $this->slotRoles !== null ) {
+                       if ( $this->fld_parsetree ) {
+                               $this->dieWithError( [
+                                       'apierror-invalidparammix-cannotusewith',
+                                       $this->encodeParamName( 'prop=parsetree' ),
+                                       $this->encodeParamName( 'slots' ),
+                               ], 'invalidparammix' );
+                       }
+                       foreach ( [
+                               'expandtemplates', 'generatexml', 'parse', 'diffto', 'difftotext', 'difftotextpst',
+                               'contentformat'
+                       ] as $p ) {
+                               if ( $params[$p] !== null && $params[$p] !== false ) {
+                                       $this->dieWithError( [
+                                               'apierror-invalidparammix-cannotusewith',
+                                               $this->encodeParamName( $p ),
+                                               $this->encodeParamName( 'slots' ),
+                                       ], 'invalidparammix' );
+                               }
+                       }
+               }
+
+               if ( !empty( $params['contentformat'] ) ) {
+                       $this->contentFormat = $params['contentformat'];
+               }
+
+               $this->limit = $params['limit'];
+
                if ( !is_null( $params['difftotext'] ) ) {
                        $this->difftotext = $params['difftotext'];
                        $this->difftotextpst = $params['difftotextpst'];
@@ -72,11 +140,13 @@ abstract class ApiQueryRevisionsBase extends ApiQueryGeneratorBase {
                        // DifferenceEngine returns a rather ambiguous empty
                        // string if that's not the case
                        if ( $params['diffto'] != 0 ) {
-                               $difftoRev = Revision::newFromId( $params['diffto'] );
+                               $difftoRev = MediaWikiServices::getInstance()->getRevisionStore()
+                                       ->getRevisionById( $params['diffto'] );
                                if ( !$difftoRev ) {
                                        $this->dieWithError( [ 'apierror-nosuchrevid', $params['diffto'] ] );
                                }
-                               if ( !$difftoRev->userCan( Revision::DELETED_TEXT, $this->getUser() ) ) {
+                               $revDel = $this->checkRevDel( $difftoRev, RevisionRecord::DELETED_TEXT );
+                               if ( $revDel & self::CANNOT_VIEW ) {
                                        $this->addWarning( [ 'apiwarn-difftohidden', $difftoRev->getId() ] );
                                        $params['diffto'] = null;
                                }
@@ -84,39 +154,6 @@ abstract class ApiQueryRevisionsBase extends ApiQueryGeneratorBase {
                        $this->diffto = $params['diffto'];
                }
 
-               $prop = array_flip( $params['prop'] );
-
-               $this->fld_ids = isset( $prop['ids'] );
-               $this->fld_flags = isset( $prop['flags'] );
-               $this->fld_timestamp = isset( $prop['timestamp'] );
-               $this->fld_comment = isset( $prop['comment'] );
-               $this->fld_parsedcomment = isset( $prop['parsedcomment'] );
-               $this->fld_size = isset( $prop['size'] );
-               $this->fld_sha1 = isset( $prop['sha1'] );
-               $this->fld_content = isset( $prop['content'] );
-               $this->fld_contentmodel = isset( $prop['contentmodel'] );
-               $this->fld_userid = isset( $prop['userid'] );
-               $this->fld_user = isset( $prop['user'] );
-               $this->fld_tags = isset( $prop['tags'] );
-               $this->fld_parsetree = isset( $prop['parsetree'] );
-
-               if ( $this->fld_parsetree ) {
-                       $encParam = $this->encodeParamName( 'prop' );
-                       $name = $this->getModuleName();
-                       $parent = $this->getParent();
-                       $parentParam = $parent->encodeParamName( $parent->getModuleManager()->getModuleGroup( $name ) );
-                       $this->addDeprecation(
-                               [ 'apiwarn-deprecation-parameter', "{$encParam}=parsetree" ],
-                               "action=query&{$parentParam}={$name}&{$encParam}=parsetree"
-                       );
-               }
-
-               if ( !empty( $params['contentformat'] ) ) {
-                       $this->contentFormat = $params['contentformat'];
-               }
-
-               $this->limit = $params['limit'];
-
                $this->fetchContent = $this->fld_content || !is_null( $this->diffto )
                        || !is_null( $this->difftotext ) || $this->fld_parsetree;
 
@@ -152,18 +189,46 @@ abstract class ApiQueryRevisionsBase extends ApiQueryGeneratorBase {
                        $this->limit = 10;
                }
                $this->validateLimit( 'limit', $this->limit, 1, $userMax, $botMax );
+
+               $this->needSlots = $this->fetchContent || $this->fld_contentmodel ||
+                       $this->fld_slotsize || $this->fld_slotsha1;
+               if ( $this->needSlots && $this->slotRoles === null ) {
+                       $encParam = $this->encodeParamName( 'slots' );
+                       $name = $this->getModuleName();
+                       $parent = $this->getParent();
+                       $parentParam = $parent->encodeParamName( $parent->getModuleManager()->getModuleGroup( $name ) );
+                       $this->addDeprecation(
+                               [ 'apiwarn-deprecation-missingparam', $encParam ],
+                               "action=query&{$parentParam}={$name}&!{$encParam}"
+                       );
+               }
        }
 
        /**
-        * Extract information from the Revision
+        * Test revision deletion status
+        * @param RevisionRecord $revision Revision to check
+        * @param int $field One of the RevisionRecord::DELETED_* constants
+        * @return int Revision deletion status flags. Bitwise OR of
+        *  self::IS_DELETED and self::CANNOT_VIEW, as appropriate.
+        */
+       private function checkRevDel( RevisionRecord $revision, $field ) {
+               $ret = $revision->isDeleted( $field ) ? self::IS_DELETED : 0;
+               if ( $ret ) {
+                       $canSee = $revision->audienceCan( $field, RevisionRecord::FOR_THIS_USER, $this->getUser() );
+                       $ret = $ret | ( $canSee ? 0 : self::CANNOT_VIEW );
+               }
+               return $ret;
+       }
+
+       /**
+        * Extract information from the RevisionRecord
         *
-        * @param Revision $revision
+        * @since 1.32, takes a RevisionRecord instead of a Revision
+        * @param RevisionRecord $revision Revision
         * @param object $row Should have a field 'ts_tags' if $this->fld_tags is set
         * @return array
         */
-       protected function extractRevisionInfo( Revision $revision, $row ) {
-               $title = $revision->getTitle();
-               $user = $this->getUser();
+       protected function extractRevisionInfo( RevisionRecord $revision, $row ) {
                $vals = [];
                $anyHidden = false;
 
@@ -179,15 +244,17 @@ abstract class ApiQueryRevisionsBase extends ApiQueryGeneratorBase {
                }
 
                if ( $this->fld_user || $this->fld_userid ) {
-                       if ( $revision->isDeleted( Revision::DELETED_USER ) ) {
+                       $revDel = $this->checkRevDel( $revision, RevisionRecord::DELETED_USER );
+                       if ( ( $revDel & self::IS_DELETED ) ) {
                                $vals['userhidden'] = true;
                                $anyHidden = true;
                        }
-                       if ( $revision->userCan( Revision::DELETED_USER, $user ) ) {
+                       if ( !( $revDel & self::CANNOT_VIEW ) ) {
+                               $u = $revision->getUser( RevisionRecord::RAW );
                                if ( $this->fld_user ) {
-                                       $vals['user'] = $revision->getUserText( Revision::RAW );
+                                       $vals['user'] = $u->getName();
                                }
-                               $userid = $revision->getUser( Revision::RAW );
+                               $userid = $u->getId();
                                if ( !$userid ) {
                                        $vals['anon'] = true;
                                }
@@ -203,45 +270,115 @@ abstract class ApiQueryRevisionsBase extends ApiQueryGeneratorBase {
                }
 
                if ( $this->fld_size ) {
-                       if ( !is_null( $revision->getSize() ) ) {
+                       try {
                                $vals['size'] = intval( $revision->getSize() );
-                       } else {
+                       } catch ( RevisionAccessException $e ) {
+                               // Back compat: If there's no size, return 0.
+                               // @todo: Gergő says to mention T198099 as a "todo" here.
                                $vals['size'] = 0;
                        }
                }
 
                if ( $this->fld_sha1 ) {
-                       if ( $revision->isDeleted( Revision::DELETED_TEXT ) ) {
+                       $revDel = $this->checkRevDel( $revision, RevisionRecord::DELETED_TEXT );
+                       if ( ( $revDel & self::IS_DELETED ) ) {
                                $vals['sha1hidden'] = true;
                                $anyHidden = true;
                        }
-                       if ( $revision->userCan( Revision::DELETED_TEXT, $user ) ) {
-                               if ( $revision->getSha1() != '' ) {
+                       if ( !( $revDel & self::CANNOT_VIEW ) ) {
+                               try {
                                        $vals['sha1'] = Wikimedia\base_convert( $revision->getSha1(), 36, 16, 40 );
-                               } else {
+                               } catch ( RevisionAccessException $e ) {
+                                       // Back compat: If there's no sha1, return emtpy string.
+                                       // @todo: Gergő says to mention T198099 as a "todo" here.
                                        $vals['sha1'] = '';
                                }
                        }
                }
 
-               if ( $this->fld_contentmodel ) {
-                       $vals['contentmodel'] = $revision->getContentModel();
+               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;
+                       }
+                       if ( $this->slotRoles === null ) {
+                               try {
+                                       $slot = $revision->getSlot( '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' );
+                       }
                }
 
                if ( $this->fld_comment || $this->fld_parsedcomment ) {
-                       if ( $revision->isDeleted( Revision::DELETED_COMMENT ) ) {
+                       $revDel = $this->checkRevDel( $revision, RevisionRecord::DELETED_COMMENT );
+                       if ( ( $revDel & self::IS_DELETED ) ) {
                                $vals['commenthidden'] = true;
                                $anyHidden = true;
                        }
-                       if ( $revision->userCan( Revision::DELETED_COMMENT, $user ) ) {
-                               $comment = $revision->getComment( Revision::RAW );
+                       if ( !( $revDel & self::CANNOT_VIEW ) ) {
+                               $comment = $revision->getComment( RevisionRecord::RAW );
+                               $comment = $comment ? $comment->text : '';
 
                                if ( $this->fld_comment ) {
                                        $vals['comment'] = $comment;
                                }
 
                                if ( $this->fld_parsedcomment ) {
-                                       $vals['parsedcomment'] = Linker::formatComment( $comment, $title );
+                                       $vals['parsedcomment'] = Linker::formatComment(
+                                               $comment, Title::newFromLinkTarget( $revision->getPageAsLinkTarget() )
+                                       );
                                }
                        }
                }
@@ -256,69 +393,119 @@ abstract class ApiQueryRevisionsBase extends ApiQueryGeneratorBase {
                        }
                }
 
-               $content = null;
-               global $wgParser;
-               if ( $this->fetchContent ) {
-                       $content = $revision->getContent( Revision::FOR_THIS_USER, $this->getUser() );
-                       // Expand templates after getting section content because
-                       // template-added sections don't count and Parser::preprocess()
-                       // will have less input
-                       if ( $content && $this->section !== false ) {
-                               $content = $content->getSection( $this->section, false );
-                               if ( !$content ) {
-                                       $this->dieWithError(
-                                               [
-                                                       'apierror-nosuchsection-what',
-                                                       wfEscapeWikiText( $this->section ),
-                                                       $this->msg( 'revid', $revision->getId() )
-                                               ],
-                                               'nosuchsection'
-                                       );
+               if ( $anyHidden && $revision->isDeleted( RevisionRecord::DELETED_RESTRICTED ) ) {
+                       $vals['suppressed'] = true;
+               }
+
+               return $vals;
+       }
+
+       /**
+        * Extract information from the SlotRecord
+        *
+        * @param SlotRecord $slot
+        * @param int $revDel Revdel status flags, from self::checkRevDel()
+        * @param Content|null &$content Set to the slot's content, if available
+        *  and $this->fetchContent is true
+        * @return array
+        */
+       private function extractSlotInfo( SlotRecord $slot, $revDel, &$content = null ) {
+               $vals = [];
+               ApiResult::setArrayType( $vals, 'assoc' );
+
+               if ( $this->fld_slotsize ) {
+                       $vals['size'] = intval( $slot->getSize() );
+               }
+
+               if ( $this->fld_slotsha1 ) {
+                       if ( ( $revDel & self::IS_DELETED ) ) {
+                               $vals['sha1hidden'] = true;
+                       }
+                       if ( !( $revDel & self::CANNOT_VIEW ) ) {
+                               if ( $slot->getSha1() != '' ) {
+                                       $vals['sha1'] = Wikimedia\base_convert( $slot->getSha1(), 36, 16, 40 );
+                               } else {
+                                       $vals['sha1'] = '';
                                }
                        }
-                       if ( $revision->isDeleted( Revision::DELETED_TEXT ) ) {
+               }
+
+               if ( $this->fld_contentmodel ) {
+                       $vals['contentmodel'] = $slot->getModel();
+               }
+
+               $content = null;
+               if ( $this->fetchContent ) {
+                       if ( ( $revDel & self::IS_DELETED ) ) {
                                $vals['texthidden'] = true;
-                               $anyHidden = true;
-                       } elseif ( !$content ) {
-                               $vals['textmissing'] = true;
+                       }
+                       if ( !( $revDel & self::CANNOT_VIEW ) ) {
+                               try {
+                                       $content = $slot->getContent();
+                               } catch ( RevisionAccessException $e ) {
+                                       // @todo: Gergő says to mention T198099 as a "todo" here.
+                                       $vals['textmissing'] = true;
+                               }
+                               // Expand templates after getting section content because
+                               // template-added sections don't count and Parser::preprocess()
+                               // will have less input
+                               if ( $content && $this->section !== false ) {
+                                       $content = $content->getSection( $this->section, false );
+                                       if ( !$content ) {
+                                               $vals['nosuchsection'] = true;
+                                       }
+                               }
                        }
                }
+
+               return $vals;
+       }
+
+       /**
+        * Format a Content using deprecated options
+        * @param Content $content Content to format
+        * @param RevisionRecord $revision Revision being processed
+        * @return array
+        */
+       private function extractDeprecatedContent( Content $content, RevisionRecord $revision ) {
+               global $wgParser;
+
+               $vals = [];
+               $title = Title::newFromLinkTarget( $revision->getPageAsLinkTarget() );
+
                if ( $this->fld_parsetree || ( $this->fld_content && $this->generateXML ) ) {
-                       if ( $content ) {
-                               if ( $content->getModel() === CONTENT_MODEL_WIKITEXT ) {
-                                       $t = $content->getNativeData(); # note: don't set $text
+                       if ( $content->getModel() === CONTENT_MODEL_WIKITEXT ) {
+                               $t = $content->getNativeData(); # note: don't set $text
 
-                                       $wgParser->startExternalParse(
-                                               $title,
-                                               ParserOptions::newFromContext( $this->getContext() ),
-                                               Parser::OT_PREPROCESS
-                                       );
-                                       $dom = $wgParser->preprocessToDom( $t );
-                                       if ( is_callable( [ $dom, 'saveXML' ] ) ) {
-                                               $xml = $dom->saveXML();
-                                       } else {
-                                               $xml = $dom->__toString();
-                                       }
-                                       $vals['parsetree'] = $xml;
+                               $wgParser->startExternalParse(
+                                       $title,
+                                       ParserOptions::newFromContext( $this->getContext() ),
+                                       Parser::OT_PREPROCESS
+                               );
+                               $dom = $wgParser->preprocessToDom( $t );
+                               if ( is_callable( [ $dom, 'saveXML' ] ) ) {
+                                       $xml = $dom->saveXML();
                                } else {
-                                       $vals['badcontentformatforparsetree'] = true;
-                                       $this->addWarning(
-                                               [
-                                                       'apierror-parsetree-notwikitext-title',
-                                                       wfEscapeWikiText( $title->getPrefixedText() ),
-                                                       $content->getModel()
-                                               ],
-                                               'parsetree-notwikitext'
-                                       );
+                                       $xml = $dom->__toString();
                                }
+                               $vals['parsetree'] = $xml;
+                       } else {
+                               $vals['badcontentformatforparsetree'] = true;
+                               $this->addWarning(
+                                       [
+                                               'apierror-parsetree-notwikitext-title',
+                                               wfEscapeWikiText( $title->getPrefixedText() ),
+                                               $content->getModel()
+                                       ],
+                                       'parsetree-notwikitext'
+                               );
                        }
                }
 
-               if ( $this->fld_content && $content ) {
+               if ( $this->fld_content ) {
                        $text = null;
 
                        if ( $this->expandTemplates && !$this->parseContent ) {
-                               # XXX: implement template expansion for all content types in ContentHandler?
                                if ( $content->getModel() === CONTENT_MODEL_WIKITEXT ) {
                                        $text = $content->getNativeData();
 
@@ -376,7 +563,7 @@ abstract class ApiQueryRevisionsBase extends ApiQueryGeneratorBase {
                                $vals['diff'] = [];
                                $context = new DerivativeContext( $this->getContext() );
                                $context->setTitle( $title );
-                               $handler = $revision->getContentHandler();
+                               $handler = $content->getContentHandler();
 
                                if ( !is_null( $this->difftotext ) ) {
                                        $model = $title->getContentModel();
@@ -398,7 +585,7 @@ abstract class ApiQueryRevisionsBase extends ApiQueryGeneratorBase {
 
                                                if ( $this->difftotextpst ) {
                                                        $popts = ParserOptions::newFromContext( $this->getContext() );
-                                                       $difftocontent = $difftocontent->preSaveTransform( $title, $user, $popts );
+                                                       $difftocontent = $difftocontent->preSaveTransform( $title, $this->getUser(), $popts );
                                                }
 
                                                $engine = $handler->createDifferenceEngine( $context );
@@ -421,10 +608,6 @@ abstract class ApiQueryRevisionsBase extends ApiQueryGeneratorBase {
                        }
                }
 
-               if ( $anyHidden && $revision->isDeleted( Revision::DELETED_RESTRICTED ) ) {
-                       $vals['suppressed'] = true;
-               }
-
                return $vals;
        }
 
@@ -437,6 +620,12 @@ abstract class ApiQueryRevisionsBase extends ApiQueryGeneratorBase {
        }
 
        public function getAllowedParams() {
+               $slotRoles = MediaWikiServices::getInstance()->getSlotRoleStore()->getMap();
+               if ( !in_array( 'main', $slotRoles, true ) ) {
+                       $slotRoles[] = 'main';
+               }
+               sort( $slotRoles, SORT_STRING );
+
                return [
                        'prop' => [
                                ApiBase::PARAM_ISMULTI => true,
@@ -448,12 +637,15 @@ abstract class ApiQueryRevisionsBase extends ApiQueryGeneratorBase {
                                        'user',
                                        'userid',
                                        'size',
+                                       'slotsize',
                                        'sha1',
+                                       'slotsha1',
                                        'contentmodel',
                                        'comment',
                                        'parsedcomment',
                                        'content',
                                        'tags',
+                                       'roles',
                                        'parsetree',
                                ],
                                ApiBase::PARAM_HELP_MSG => 'apihelp-query+revisions+base-param-prop',
@@ -464,15 +656,27 @@ abstract class ApiQueryRevisionsBase extends ApiQueryGeneratorBase {
                                        'user' => 'apihelp-query+revisions+base-paramvalue-prop-user',
                                        'userid' => 'apihelp-query+revisions+base-paramvalue-prop-userid',
                                        'size' => 'apihelp-query+revisions+base-paramvalue-prop-size',
+                                       'slotsize' => 'apihelp-query+revisions+base-paramvalue-prop-slotsize',
                                        'sha1' => 'apihelp-query+revisions+base-paramvalue-prop-sha1',
+                                       'slotsha1' => 'apihelp-query+revisions+base-paramvalue-prop-slotsha1',
                                        'contentmodel' => 'apihelp-query+revisions+base-paramvalue-prop-contentmodel',
                                        'comment' => 'apihelp-query+revisions+base-paramvalue-prop-comment',
                                        'parsedcomment' => 'apihelp-query+revisions+base-paramvalue-prop-parsedcomment',
                                        'content' => 'apihelp-query+revisions+base-paramvalue-prop-content',
                                        'tags' => 'apihelp-query+revisions+base-paramvalue-prop-tags',
+                                       'roles' => 'apihelp-query+revisions+base-paramvalue-prop-roles',
                                        'parsetree' => [ 'apihelp-query+revisions+base-paramvalue-prop-parsetree',
                                                CONTENT_MODEL_WIKITEXT ],
                                ],
+                               ApiBase::PARAM_DEPRECATED_VALUES => [
+                                       'parsetree' => true,
+                               ],
+                       ],
+                       'slots' => [
+                               ApiBase::PARAM_TYPE => $slotRoles,
+                               ApiBase::PARAM_HELP_MSG => 'apihelp-query+revisions+base-param-slots',
+                               ApiBase::PARAM_ISMULTI => true,
+                               ApiBase::PARAM_ALL => true,
                        ],
                        'limit' => [
                                ApiBase::PARAM_TYPE => 'limit',
@@ -515,6 +719,7 @@ abstract class ApiQueryRevisionsBase extends ApiQueryGeneratorBase {
                        'contentformat' => [
                                ApiBase::PARAM_TYPE => ContentHandler::getAllContentFormats(),
                                ApiBase::PARAM_HELP_MSG => 'apihelp-query+revisions+base-param-contentformat',
+                               ApiBase::PARAM_DEPRECATED => true,
                        ],
                ];
        }
index 7d46a5f..f5461e0 100644 (file)
@@ -60,12 +60,25 @@ class ApiQuerySearch extends ApiQueryGeneratorBase {
 
                // Create search engine instance and set options
                $search = $this->buildSearchEngine( $params );
+               if ( isset( $params['sort'] ) ) {
+                       $search->setSort( $params['sort'] );
+               }
                $search->setFeatureData( 'rewrite', (bool)$params['enablerewrites'] );
                $search->setFeatureData( 'interwiki', (bool)$interwiki );
 
-               $query = $search->transformSearchTerm( $query );
-               $query = $search->replacePrefixes( $query );
+               $nquery = $search->transformSearchTerm( $query );
+               if ( $nquery !== $query ) {
+                       $query = $nquery;
+                       wfDeprecated( 'SearchEngine::transformSearchTerm() (overridden by ' .
+                               get_class( $search ) . ')', '1.32' );
+               }
 
+               $nquery = $search->replacePrefixes( $query );
+               if ( $nquery !== $query ) {
+                       $query = $nquery;
+                       wfDeprecated( 'SearchEngine::replacePrefixes() (overridden by ' .
+                                                 get_class( $search ) . ')', '1.32' );
+               }
                // Perform the actual search
                if ( $what == 'text' ) {
                        $matches = $search->searchText( $query );
@@ -142,20 +155,16 @@ class ApiQuerySearch extends ApiQueryGeneratorBase {
                $terms = $wgContLang->convertForSearchResult( $matches->termMatches() );
                $titles = [];
                $count = 0;
-               $result = $matches->next();
                $limit = $params['limit'];
 
-               while ( $result ) {
-                       if ( ++$count > $limit ) {
-                               // We've reached the one extra which shows that there are
-                               // additional items to be had. Stop here...
-                               $this->setContinueEnumParameter( 'offset', $params['offset'] + $params['limit'] );
-                               break;
-                       }
+               if ( $matches->hasMoreResults() ) {
+                       $this->setContinueEnumParameter( 'offset', $params['offset'] + $params['limit'] );
+               }
 
+               foreach ( $matches as $result ) {
+                       $count++;
                        // Silently skip broken and missing titles
                        if ( $result->isBrokenTitle() || $result->isMissingRevision() ) {
-                               $result = $matches->next();
                                continue;
                        }
 
@@ -172,8 +181,6 @@ class ApiQuerySearch extends ApiQueryGeneratorBase {
                        } else {
                                $titles[] = $result->getTitle();
                        }
-
-                       $result = $matches->next();
                }
 
                // Here we assume interwiki results do not count with
@@ -301,8 +308,7 @@ class ApiQuerySearch extends ApiQueryGeneratorBase {
                                // Include number of results if requested
                                $totalhits += $interwikiMatches->getTotalHits();
 
-                               $result = $interwikiMatches->next();
-                               while ( $result ) {
+                               foreach ( $interwikiMatches as $result ) {
                                        $title = $result->getTitle();
                                        $vals = $this->getSearchResultData( $result, $prop, $terms );
 
@@ -322,8 +328,6 @@ class ApiQuerySearch extends ApiQueryGeneratorBase {
                                                // pagination info so just bail out
                                                break;
                                        }
-
-                                       $result = $interwikiMatches->next();
                                }
                        }
                        if ( $totalhits !== null ) {
@@ -391,6 +395,20 @@ class ApiQuerySearch extends ApiQueryGeneratorBase {
                        'enablerewrites' => false,
                ];
 
+               // If we have more than one engine the list of available sorts is
+               // difficult to represent. For now don't expose it.
+               $alternatives = MediaWiki\MediaWikiServices::getInstance()
+                       ->getSearchEngineConfig()
+                       ->getSearchTypes();
+               if ( count( $alternatives ) == 1 ) {
+                       $this->allowedParams['sort'] = [
+                               ApiBase::PARAM_DFLT => 'relevance',
+                               ApiBase::PARAM_TYPE => MediaWiki\MediaWikiServices::getInstance()
+                                       ->newSearchEngine()
+                                       ->getValidSorts(),
+                       ];
+               }
+
                return $this->allowedParams;
        }
 
index 3f2d510..7d4b55f 100644 (file)
@@ -54,7 +54,7 @@ class ApiQuerySiteinfo extends ApiQueryBase {
                                        $fit = $this->appendMagicWords( $p );
                                        break;
                                case 'interwikimap':
-                                       $filteriw = isset( $params['filteriw'] ) ? $params['filteriw'] : false;
+                                       $filteriw = $params['filteriw'] ?? false;
                                        $fit = $this->appendInterwikiMap( $p, $filteriw );
                                        break;
                                case 'dbrepllag':
@@ -387,7 +387,7 @@ class ApiQuerySiteinfo extends ApiQueryBase {
                }
 
                $params = $this->extractRequestParams();
-               $langCode = isset( $params['inlanguagecode'] ) ? $params['inlanguagecode'] : '';
+               $langCode = $params['inlanguagecode'] ?? '';
                $langNames = Language::fetchLanguageNames( $langCode );
 
                $getPrefixes = MediaWikiServices::getInstance()->getInterwikiLookup()->getAllPrefixes( $local );
@@ -629,7 +629,7 @@ class ApiQuerySiteinfo extends ApiQueryBase {
                                        }
 
                                        if ( SpecialVersion::getExtLicenseFileName( $extensionPath ) ) {
-                                               $ret['license-name'] = isset( $ext['license-name'] ) ? $ext['license-name'] : '';
+                                               $ret['license-name'] = $ext['license-name'] ?? '';
                                                $ret['license'] = SpecialPage::getTitleFor(
                                                        'Version',
                                                        "License/{$ext['name']}"
@@ -699,7 +699,7 @@ class ApiQuerySiteinfo extends ApiQueryBase {
 
        public function appendLanguages( $property ) {
                $params = $this->extractRequestParams();
-               $langCode = isset( $params['inlanguagecode'] ) ? $params['inlanguagecode'] : '';
+               $langCode = $params['inlanguagecode'] ?? '';
                $langNames = Language::fetchLanguageNames( $langCode );
 
                $data = [];
@@ -808,7 +808,7 @@ class ApiQuerySiteinfo extends ApiQueryBase {
        }
 
        public function appendVariables( $property ) {
-               $variables = MagicWord::getVariableIDs();
+               $variables = MediaWikiServices::getInstance()->getMagicWordFactory()->getVariableIDs();
                ApiResult::setArrayType( $variables, 'BCarray' );
                ApiResult::setIndexedTagName( $variables, 'v' );
 
index e86fdf3..8854aac 100644 (file)
@@ -94,7 +94,7 @@ class ApiQueryTokens extends ApiQueryBase {
        public static function getToken( User $user, MediaWiki\Session\Session $session, $salt ) {
                if ( is_array( $salt ) ) {
                        $session->persist();
-                       return call_user_func_array( [ $session, 'getToken' ], $salt );
+                       return $session->getToken( ...$salt );
                } else {
                        return $user->getEditTokenObject( $salt, $session->getRequest() );
                }
diff --git a/includes/api/ApiQueryUserContribs.php b/includes/api/ApiQueryUserContribs.php
new file mode 100644 (file)
index 0000000..3aa6183
--- /dev/null
@@ -0,0 +1,843 @@
+<?php
+/**
+ * Copyright © 2006 Yuri Astrakhan "<Firstname><Lastname>@gmail.com"
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+use MediaWiki\MediaWikiServices;
+use MediaWiki\Storage\RevisionRecord;
+
+/**
+ * This query action adds a list of a specified user's contributions to the output.
+ *
+ * @ingroup API
+ */
+class ApiQueryUserContribs extends ApiQueryBase {
+
+       public function __construct( ApiQuery $query, $moduleName ) {
+               parent::__construct( $query, $moduleName, 'uc' );
+       }
+
+       private $params, $multiUserMode, $orderBy, $parentLens, $commentStore;
+
+       private $fld_ids = false, $fld_title = false, $fld_timestamp = false,
+               $fld_comment = false, $fld_parsedcomment = false, $fld_flags = false,
+               $fld_patrolled = false, $fld_tags = false, $fld_size = false, $fld_sizediff = false;
+
+       public function execute() {
+               global $wgActorTableSchemaMigrationStage;
+
+               // Parse some parameters
+               $this->params = $this->extractRequestParams();
+
+               $this->commentStore = CommentStore::getStore();
+
+               $prop = array_flip( $this->params['prop'] );
+               $this->fld_ids = isset( $prop['ids'] );
+               $this->fld_title = isset( $prop['title'] );
+               $this->fld_comment = isset( $prop['comment'] );
+               $this->fld_parsedcomment = isset( $prop['parsedcomment'] );
+               $this->fld_size = isset( $prop['size'] );
+               $this->fld_sizediff = isset( $prop['sizediff'] );
+               $this->fld_flags = isset( $prop['flags'] );
+               $this->fld_timestamp = isset( $prop['timestamp'] );
+               $this->fld_patrolled = isset( $prop['patrolled'] );
+               $this->fld_tags = isset( $prop['tags'] );
+
+               // Most of this code will use the 'contributions' group DB, which can map to replica DBs
+               // with extra user based indexes or partioning by user. The additional metadata
+               // queries should use a regular replica DB since the lookup pattern is not all by user.
+               $dbSecondary = $this->getDB(); // any random replica DB
+
+               // TODO: if the query is going only against the revision table, should this be done?
+               $this->selectNamedDB( 'contributions', DB_REPLICA, 'contributions' );
+
+               $sort = ( $this->params['dir'] == 'newer' ? '' : ' DESC' );
+               $op = ( $this->params['dir'] == 'older' ? '<' : '>' );
+
+               // Create an Iterator that produces the UserIdentity objects we need, depending
+               // on which of the 'userprefix', 'userids', or 'user' params was
+               // specified.
+               $this->requireOnlyOneParameter( $this->params, 'userprefix', 'userids', 'user' );
+               if ( isset( $this->params['userprefix'] ) ) {
+                       $this->multiUserMode = true;
+                       $this->orderBy = 'name';
+                       $fname = __METHOD__;
+
+                       // Because 'userprefix' might produce a huge number of users (e.g.
+                       // a wiki with users "Test00000001" to "Test99999999"), use a
+                       // generator with batched lookup and continuation.
+                       $userIter = call_user_func( function () use ( $dbSecondary, $sort, $op, $fname ) {
+                               global $wgActorTableSchemaMigrationStage;
+
+                               $fromName = false;
+                               if ( !is_null( $this->params['continue'] ) ) {
+                                       $continue = explode( '|', $this->params['continue'] );
+                                       $this->dieContinueUsageIf( count( $continue ) != 4 );
+                                       $this->dieContinueUsageIf( $continue[0] !== 'name' );
+                                       $fromName = $continue[1];
+                               }
+                               $like = $dbSecondary->buildLike( $this->params['userprefix'], $dbSecondary->anyString() );
+
+                               $limit = 501;
+
+                               do {
+                                       $from = $fromName ? "$op= " . $dbSecondary->addQuotes( $fromName ) : false;
+
+                                       // For the new schema, pull from the actor table. For the
+                                       // old, pull from rev_user. For migration a FULL [OUTER]
+                                       // JOIN would be what we want, except MySQL doesn't support
+                                       // that so we have to UNION instead.
+                                       if ( $wgActorTableSchemaMigrationStage === MIGRATION_NEW ) {
+                                               $res = $dbSecondary->select(
+                                                       'actor',
+                                                       [ 'actor_id', 'user_id' => 'COALESCE(actor_user,0)', 'user_name' => 'actor_name' ],
+                                                       array_merge( [ "actor_name$like" ], $from ? [ "actor_name $from" ] : [] ),
+                                                       $fname,
+                                                       [ 'ORDER BY' => [ "user_name $sort" ], 'LIMIT' => $limit ]
+                                               );
+                                       } elseif ( $wgActorTableSchemaMigrationStage === MIGRATION_OLD ) {
+                                               $res = $dbSecondary->select(
+                                                       'revision',
+                                                       [ 'actor_id' => 'NULL', 'user_id' => 'rev_user', 'user_name' => 'rev_user_text' ],
+                                                       array_merge( [ "rev_user_text$like" ], $from ? [ "rev_user_text $from" ] : [] ),
+                                                       $fname,
+                                                       [ 'DISTINCT', 'ORDER BY' => [ "rev_user_text $sort" ], 'LIMIT' => $limit ]
+                                               );
+                                       } else {
+                                               // There are three queries we have to combine to be sure of getting all results:
+                                               //  - actor table (any rows that have been migrated will have empty rev_user_text)
+                                               //  - revision+actor by user id
+                                               //  - revision+actor by name for anons
+                                               $options = $dbSecondary->unionSupportsOrderAndLimit()
+                                                       ? [ 'ORDER BY' => [ "user_name $sort" ], 'LIMIT' => $limit ] : [];
+                                               $subsql = [];
+                                               $subsql[] = $dbSecondary->selectSQLText(
+                                                       'actor',
+                                                       [ 'actor_id', 'user_id' => 'COALESCE(actor_user,0)', 'user_name' => 'actor_name' ],
+                                                       array_merge( [ "actor_name$like" ], $from ? [ "actor_name $from" ] : [] ),
+                                                       $fname,
+                                                       $options
+                                               );
+                                               $subsql[] = $dbSecondary->selectSQLText(
+                                                       [ 'revision', 'actor' ],
+                                                       [ 'actor_id', 'user_id' => 'rev_user', 'user_name' => 'rev_user_text' ],
+                                                       array_merge(
+                                                               [ "rev_user_text$like", 'rev_user != 0' ],
+                                                               $from ? [ "rev_user_text $from" ] : []
+                                                       ),
+                                                       $fname,
+                                                       array_merge( [ 'DISTINCT' ], $options ),
+                                                       [ 'actor' => [ 'LEFT JOIN', 'rev_user = actor_user' ] ]
+                                               );
+                                               $subsql[] = $dbSecondary->selectSQLText(
+                                                       [ 'revision', 'actor' ],
+                                                       [ 'actor_id', 'user_id' => 'rev_user', 'user_name' => 'rev_user_text' ],
+                                                       array_merge(
+                                                               [ "rev_user_text$like", 'rev_user = 0' ],
+                                                               $from ? [ "rev_user_text $from" ] : []
+                                                       ),
+                                                       $fname,
+                                                       array_merge( [ 'DISTINCT' ], $options ),
+                                                       [ 'actor' => [ 'LEFT JOIN', 'rev_user_text = actor_name' ] ]
+                                               );
+                                               $sql = $dbSecondary->unionQueries( $subsql, false ) . " ORDER BY user_name $sort";
+                                               $sql = $dbSecondary->limitResult( $sql, $limit );
+                                               $res = $dbSecondary->query( $sql, $fname );
+                                       }
+
+                                       $count = 0;
+                                       $fromName = false;
+                                       foreach ( $res as $row ) {
+                                               if ( ++$count >= $limit ) {
+                                                       $fromName = $row->user_name;
+                                                       break;
+                                               }
+                                               yield User::newFromRow( $row );
+                                       }
+                               } while ( $fromName !== false );
+                       } );
+                       // Do the actual sorting client-side, because otherwise
+                       // prepareQuery might try to sort by actor and confuse everything.
+                       $batchSize = 1;
+               } elseif ( isset( $this->params['userids'] ) ) {
+                       if ( !count( $this->params['userids'] ) ) {
+                               $encParamName = $this->encodeParamName( 'userids' );
+                               $this->dieWithError( [ 'apierror-paramempty', $encParamName ], "paramempty_$encParamName" );
+                       }
+
+                       $ids = [];
+                       foreach ( $this->params['userids'] as $uid ) {
+                               if ( $uid <= 0 ) {
+                                       $this->dieWithError( [ 'apierror-invaliduserid', $uid ], 'invaliduserid' );
+                               }
+                               $ids[] = $uid;
+                       }
+
+                       $this->orderBy = 'id';
+                       $this->multiUserMode = count( $ids ) > 1;
+
+                       $from = $fromId = false;
+                       if ( $this->multiUserMode && !is_null( $this->params['continue'] ) ) {
+                               $continue = explode( '|', $this->params['continue'] );
+                               $this->dieContinueUsageIf( count( $continue ) != 4 );
+                               $this->dieContinueUsageIf( $continue[0] !== 'id' && $continue[0] !== 'actor' );
+                               $fromId = (int)$continue[1];
+                               $this->dieContinueUsageIf( $continue[1] !== (string)$fromId );
+                               $from = "$op= $fromId";
+                       }
+
+                       // For the new schema, just select from the actor table. For the
+                       // old and transitional schemas, select from user and left join
+                       // actor if it exists.
+                       if ( $wgActorTableSchemaMigrationStage === MIGRATION_NEW ) {
+                               $res = $dbSecondary->select(
+                                       'actor',
+                                       [ 'actor_id', 'user_id' => 'actor_user', 'user_name' => 'actor_name' ],
+                                       array_merge( [ 'actor_user' => $ids ], $from ? [ "actor_id $from" ] : [] ),
+                                       __METHOD__,
+                                       [ 'ORDER BY' => "user_id $sort" ]
+                               );
+                       } elseif ( $wgActorTableSchemaMigrationStage === MIGRATION_OLD ) {
+                               $res = $dbSecondary->select(
+                                       'user',
+                                       [ 'actor_id' => 'NULL', 'user_id' => 'user_id', 'user_name' => 'user_name' ],
+                                       array_merge( [ 'user_id' => $ids ], $from ? [ "user_id $from" ] : [] ),
+                                       __METHOD__,
+                                       [ 'ORDER BY' => "user_id $sort" ]
+                               );
+                       } else {
+                               $res = $dbSecondary->select(
+                                       [ 'user', 'actor' ],
+                                       [ 'actor_id', 'user_id', 'user_name' ],
+                                       array_merge( [ 'user_id' => $ids ], $from ? [ "user_id $from" ] : [] ),
+                                       __METHOD__,
+                                       [ 'ORDER BY' => "user_id $sort" ],
+                                       [ 'actor' => [ 'LEFT JOIN', 'actor_user = user_id' ] ]
+                               );
+                       }
+                       $userIter = UserArray::newFromResult( $res );
+                       $batchSize = count( $ids );
+               } else {
+                       $names = [];
+                       if ( !count( $this->params['user'] ) ) {
+                               $encParamName = $this->encodeParamName( 'user' );
+                               $this->dieWithError(
+                                       [ 'apierror-paramempty', $encParamName ], "paramempty_$encParamName"
+                               );
+                       }
+                       foreach ( $this->params['user'] as $u ) {
+                               if ( $u === '' ) {
+                                       $encParamName = $this->encodeParamName( 'user' );
+                                       $this->dieWithError(
+                                               [ 'apierror-paramempty', $encParamName ], "paramempty_$encParamName"
+                                       );
+                               }
+
+                               if ( User::isIP( $u ) || ExternalUserNames::isExternal( $u ) ) {
+                                       $names[$u] = null;
+                               } else {
+                                       $name = User::getCanonicalName( $u, 'valid' );
+                                       if ( $name === false ) {
+                                               $encParamName = $this->encodeParamName( 'user' );
+                                               $this->dieWithError(
+                                                       [ 'apierror-baduser', $encParamName, wfEscapeWikiText( $u ) ], "baduser_$encParamName"
+                                               );
+                                       }
+                                       $names[$name] = null;
+                               }
+                       }
+
+                       $this->orderBy = 'name';
+                       $this->multiUserMode = count( $names ) > 1;
+
+                       $from = $fromName = false;
+                       if ( $this->multiUserMode && !is_null( $this->params['continue'] ) ) {
+                               $continue = explode( '|', $this->params['continue'] );
+                               $this->dieContinueUsageIf( count( $continue ) != 4 );
+                               $this->dieContinueUsageIf( $continue[0] !== 'name' && $continue[0] !== 'actor' );
+                               $fromName = $continue[1];
+                               $from = "$op= " . $dbSecondary->addQuotes( $fromName );
+                       }
+
+                       // For the new schema, just select from the actor table. For the
+                       // old and transitional schemas, select from user and left join
+                       // actor if it exists then merge in any unknown users (IPs and imports).
+                       if ( $wgActorTableSchemaMigrationStage === MIGRATION_NEW ) {
+                               $res = $dbSecondary->select(
+                                       'actor',
+                                       [ 'actor_id', 'user_id' => 'actor_user', 'user_name' => 'actor_name' ],
+                                       array_merge( [ 'actor_name' => array_keys( $names ) ], $from ? [ "actor_id $from" ] : [] ),
+                                       __METHOD__,
+                                       [ 'ORDER BY' => "actor_name $sort" ]
+                               );
+                               $userIter = UserArray::newFromResult( $res );
+                       } else {
+                               if ( $wgActorTableSchemaMigrationStage === MIGRATION_OLD ) {
+                                       $res = $dbSecondary->select(
+                                               'user',
+                                               [ 'actor_id' => 'NULL', 'user_id', 'user_name' ],
+                                               array_merge( [ 'user_name' => array_keys( $names ) ], $from ? [ "user_name $from" ] : [] ),
+                                               __METHOD__
+                                       );
+                               } else {
+                                       $res = $dbSecondary->select(
+                                               [ 'user', 'actor' ],
+                                               [ 'actor_id', 'user_id', 'user_name' ],
+                                               array_merge( [ 'user_name' => array_keys( $names ) ], $from ? [ "user_name $from" ] : [] ),
+                                               __METHOD__,
+                                               [],
+                                               [ 'actor' => [ 'LEFT JOIN', 'actor_user = user_id' ] ]
+                                       );
+                               }
+                               foreach ( $res as $row ) {
+                                       $names[$row->user_name] = $row;
+                               }
+                               if ( $this->params['dir'] == 'newer' ) {
+                                       ksort( $names, SORT_STRING );
+                               } else {
+                                       krsort( $names, SORT_STRING );
+                               }
+                               $neg = $op === '>' ? -1 : 1;
+                               $userIter = call_user_func( function () use ( $names, $fromName, $neg ) {
+                                       foreach ( $names as $name => $row ) {
+                                               if ( $fromName === false || $neg * strcmp( $name, $fromName ) <= 0 ) {
+                                                       $user = $row ? User::newFromRow( $row ) : User::newFromName( $name, false );
+                                                       yield $user;
+                                               }
+                                       }
+                               } );
+                       }
+                       $batchSize = count( $names );
+               }
+
+               // During migration, force ordering on the client side because we're
+               // having to combine multiple queries that would otherwise have
+               // different sort orders.
+               if ( $wgActorTableSchemaMigrationStage === MIGRATION_WRITE_BOTH ||
+                       $wgActorTableSchemaMigrationStage === MIGRATION_WRITE_NEW
+               ) {
+                       $batchSize = 1;
+               }
+
+               // With the new schema, the DB query will order by actor so update $this->orderBy to match.
+               if ( $batchSize > 1 && $wgActorTableSchemaMigrationStage === MIGRATION_NEW ) {
+                       $this->orderBy = 'actor';
+               }
+
+               $count = 0;
+               $limit = $this->params['limit'];
+               $userIter->rewind();
+               while ( $userIter->valid() ) {
+                       $users = [];
+                       while ( count( $users ) < $batchSize && $userIter->valid() ) {
+                               $users[] = $userIter->current();
+                               $userIter->next();
+                       }
+
+                       // Ugh. We have to run the query three times, once for each
+                       // possible 'orcond' from ActorMigration, and then merge them all
+                       // together in the proper order. And preserving the correct
+                       // $hookData for each one.
+                       // @todo When ActorMigration is removed, this can go back to a
+                       //  single prepare and select.
+                       $merged = [];
+                       foreach ( [ 'actor', 'userid', 'username' ] as $which ) {
+                               if ( $this->prepareQuery( $users, $limit - $count, $which ) ) {
+                                       $hookData = [];
+                                       $res = $this->select( __METHOD__, [], $hookData );
+                                       foreach ( $res as $row ) {
+                                               $merged[] = [ $row, &$hookData ];
+                                       }
+                               }
+                       }
+                       $neg = $this->params['dir'] == 'newer' ? 1 : -1;
+                       usort( $merged, function ( $a, $b ) use ( $neg, $batchSize ) {
+                               if ( $batchSize === 1 ) { // One user, can't be different
+                                       $ret = 0;
+                               } elseif ( $this->orderBy === 'id' ) {
+                                       $ret = $a[0]->rev_user <=> $b[0]->rev_user;
+                               } elseif ( $this->orderBy === 'name' ) {
+                                       $ret = strcmp( $a[0]->rev_user_text, $b[0]->rev_user_text );
+                               } else {
+                                       $ret = $a[0]->rev_actor <=> $b[0]->rev_actor;
+                               }
+
+                               if ( !$ret ) {
+                                       $ret = strcmp(
+                                               wfTimestamp( TS_MW, $a[0]->rev_timestamp ),
+                                               wfTimestamp( TS_MW, $b[0]->rev_timestamp )
+                                       );
+                               }
+
+                               if ( !$ret ) {
+                                       $ret = $a[0]->rev_id <=> $b[0]->rev_id;
+                               }
+
+                               return $neg * $ret;
+                       } );
+                       $merged = array_slice( $merged, 0, $limit - $count + 1 );
+                       // (end "Ugh")
+
+                       if ( $this->fld_sizediff ) {
+                               $revIds = [];
+                               foreach ( $merged as $data ) {
+                                       if ( $data[0]->rev_parent_id ) {
+                                               $revIds[] = $data[0]->rev_parent_id;
+                                       }
+                               }
+                               $this->parentLens = MediaWikiServices::getInstance()->getRevisionStore()
+                                       ->listRevisionSizes( $dbSecondary, $revIds );
+                       }
+
+                       foreach ( $merged as $data ) {
+                               $row = $data[0];
+                               $hookData = &$data[1];
+                               if ( ++$count > $limit ) {
+                                       // We've reached the one extra which shows that there are
+                                       // additional pages to be had. Stop here...
+                                       $this->setContinueEnumParameter( 'continue', $this->continueStr( $row ) );
+                                       break 2;
+                               }
+
+                               $vals = $this->extractRowInfo( $row );
+                               $fit = $this->processRow( $row, $vals, $hookData ) &&
+                                       $this->getResult()->addValue( [ 'query', $this->getModuleName() ], null, $vals );
+                               if ( !$fit ) {
+                                       $this->setContinueEnumParameter( 'continue', $this->continueStr( $row ) );
+                                       break 2;
+                               }
+                       }
+               }
+
+               $this->getResult()->addIndexedTagName( [ 'query', $this->getModuleName() ], 'item' );
+       }
+
+       /**
+        * Prepares the query and returns the limit of rows requested
+        * @param User[] $users
+        * @param int $limit
+        * @param string $which 'actor', 'userid', or 'username'
+        * @return bool
+        */
+       private function prepareQuery( array $users, $limit, $which ) {
+               global $wgActorTableSchemaMigrationStage;
+
+               $this->resetQueryParams();
+               $db = $this->getDB();
+
+               $revQuery = MediaWikiServices::getInstance()->getRevisionStore()->getQueryInfo( [ 'page' ] );
+               $this->addTables( $revQuery['tables'] );
+               $this->addJoinConds( $revQuery['joins'] );
+               $this->addFields( $revQuery['fields'] );
+
+               $revWhere = ActorMigration::newMigration()->getWhere( $db, 'rev_user', $users );
+               if ( !isset( $revWhere['orconds'][$which] ) ) {
+                       return false;
+               }
+               $this->addWhere( $revWhere['orconds'][$which] );
+
+               if ( $wgActorTableSchemaMigrationStage === MIGRATION_NEW ) {
+                       $orderUserField = 'rev_actor';
+                       $userField = $this->orderBy === 'actor' ? 'revactor_actor' : 'actor_name';
+               } else {
+                       $orderUserField = $this->orderBy === 'id' ? 'rev_user' : 'rev_user_text';
+                       $userField = $revQuery['fields'][$orderUserField];
+               }
+               if ( $which === 'actor' ) {
+                       $tsField = 'revactor_timestamp';
+                       $idField = 'revactor_rev';
+               } else {
+                       $tsField = 'rev_timestamp';
+                       $idField = 'rev_id';
+               }
+
+               // Handle continue parameter
+               if ( !is_null( $this->params['continue'] ) ) {
+                       $continue = explode( '|', $this->params['continue'] );
+                       if ( $this->multiUserMode ) {
+                               $this->dieContinueUsageIf( count( $continue ) != 4 );
+                               $modeFlag = array_shift( $continue );
+                               $this->dieContinueUsageIf( $modeFlag !== $this->orderBy );
+                               $encUser = $db->addQuotes( array_shift( $continue ) );
+                       } else {
+                               $this->dieContinueUsageIf( count( $continue ) != 2 );
+                       }
+                       $encTS = $db->addQuotes( $db->timestamp( $continue[0] ) );
+                       $encId = (int)$continue[1];
+                       $this->dieContinueUsageIf( $encId != $continue[1] );
+                       $op = ( $this->params['dir'] == 'older' ? '<' : '>' );
+                       if ( $this->multiUserMode ) {
+                               $this->addWhere(
+                                       "$userField $op $encUser OR " .
+                                       "($userField = $encUser AND " .
+                                       "($tsField $op $encTS OR " .
+                                       "($tsField = $encTS AND " .
+                                       "$idField $op= $encId)))"
+                               );
+                       } else {
+                               $this->addWhere(
+                                       "$tsField $op $encTS OR " .
+                                       "($tsField = $encTS AND " .
+                                       "$idField $op= $encId)"
+                               );
+                       }
+               }
+
+               // Don't include any revisions where we're not supposed to be able to
+               // see the username.
+               $user = $this->getUser();
+               if ( !$user->isAllowed( 'deletedhistory' ) ) {
+                       $bitmask = RevisionRecord::DELETED_USER;
+               } elseif ( !$user->isAllowedAny( 'suppressrevision', 'viewsuppressed' ) ) {
+                       $bitmask = RevisionRecord::DELETED_USER | RevisionRecord::DELETED_RESTRICTED;
+               } else {
+                       $bitmask = 0;
+               }
+               if ( $bitmask ) {
+                       $this->addWhere( $db->bitAnd( 'rev_deleted', $bitmask ) . " != $bitmask" );
+               }
+
+               // Add the user field to ORDER BY if there are multiple users
+               if ( count( $users ) > 1 ) {
+                       $this->addWhereRange( $orderUserField, $this->params['dir'], null, null );
+               }
+
+               // Then timestamp
+               $this->addTimestampWhereRange( $tsField,
+                       $this->params['dir'], $this->params['start'], $this->params['end'] );
+
+               // Then rev_id for a total ordering
+               $this->addWhereRange( $idField, $this->params['dir'], null, null );
+
+               $this->addWhereFld( 'page_namespace', $this->params['namespace'] );
+
+               $show = $this->params['show'];
+               if ( $this->params['toponly'] ) { // deprecated/old param
+                       $show[] = 'top';
+               }
+               if ( !is_null( $show ) ) {
+                       $show = array_flip( $show );
+
+                       if ( ( isset( $show['minor'] ) && isset( $show['!minor'] ) )
+                               || ( isset( $show['patrolled'] ) && isset( $show['!patrolled'] ) )
+                               || ( isset( $show['autopatrolled'] ) && isset( $show['!autopatrolled'] ) )
+                               || ( isset( $show['autopatrolled'] ) && isset( $show['!patrolled'] ) )
+                               || ( isset( $show['top'] ) && isset( $show['!top'] ) )
+                               || ( isset( $show['new'] ) && isset( $show['!new'] ) )
+                       ) {
+                               $this->dieWithError( 'apierror-show' );
+                       }
+
+                       $this->addWhereIf( 'rev_minor_edit = 0', isset( $show['!minor'] ) );
+                       $this->addWhereIf( 'rev_minor_edit != 0', isset( $show['minor'] ) );
+                       $this->addWhereIf(
+                               'rc_patrolled = ' . RecentChange::PRC_UNPATROLLED,
+                               isset( $show['!patrolled'] )
+                       );
+                       $this->addWhereIf(
+                               'rc_patrolled != ' . RecentChange::PRC_UNPATROLLED,
+                               isset( $show['patrolled'] )
+                       );
+                       $this->addWhereIf(
+                               'rc_patrolled != ' . RecentChange::PRC_AUTOPATROLLED,
+                               isset( $show['!autopatrolled'] )
+                       );
+                       $this->addWhereIf(
+                               'rc_patrolled = ' . RecentChange::PRC_AUTOPATROLLED,
+                               isset( $show['autopatrolled'] )
+                       );
+                       $this->addWhereIf( $idField . ' != page_latest', isset( $show['!top'] ) );
+                       $this->addWhereIf( $idField . ' = page_latest', isset( $show['top'] ) );
+                       $this->addWhereIf( 'rev_parent_id != 0', isset( $show['!new'] ) );
+                       $this->addWhereIf( 'rev_parent_id = 0', isset( $show['new'] ) );
+               }
+               $this->addOption( 'LIMIT', $limit + 1 );
+
+               if ( isset( $show['patrolled'] ) || isset( $show['!patrolled'] ) ||
+                       isset( $show['autopatrolled'] ) || isset( $show['!autopatrolled'] ) || $this->fld_patrolled
+               ) {
+                       if ( !$user->useRCPatrol() && !$user->useNPPatrol() ) {
+                               $this->dieWithError( 'apierror-permissiondenied-patrolflag', 'permissiondenied' );
+                       }
+
+                       $isFilterset = isset( $show['patrolled'] ) || isset( $show['!patrolled'] ) ||
+                               isset( $show['autopatrolled'] ) || isset( $show['!autopatrolled'] );
+                       $this->addTables( 'recentchanges' );
+                       $this->addJoinConds( [ 'recentchanges' => [
+                               $isFilterset ? 'JOIN' : 'LEFT JOIN',
+                               [
+                                       // This is a crazy hack. recentchanges has no index on rc_this_oldid, so instead of adding
+                                       // one T19237 did a join using rc_user_text and rc_timestamp instead. Now rc_user_text is
+                                       // probably unavailable, so just do rc_timestamp.
+                                       'rc_timestamp = ' . $tsField,
+                                       'rc_this_oldid = ' . $idField,
+                               ]
+                       ] ] );
+               }
+
+               $this->addFieldsIf( 'rc_patrolled', $this->fld_patrolled );
+
+               if ( $this->fld_tags ) {
+                       $this->addTables( 'tag_summary' );
+                       $this->addJoinConds(
+                               [ 'tag_summary' => [ 'LEFT JOIN', [ $idField . ' = ts_rev_id' ] ] ]
+                       );
+                       $this->addFields( 'ts_tags' );
+               }
+
+               if ( isset( $this->params['tag'] ) ) {
+                       $this->addTables( 'change_tag' );
+                       $this->addJoinConds(
+                               [ 'change_tag' => [ 'INNER JOIN', [ $idField . ' = ct_rev_id' ] ] ]
+                       );
+                       $this->addWhereFld( 'ct_tag', $this->params['tag'] );
+               }
+
+               return true;
+       }
+
+       /**
+        * Extract fields from the database row and append them to a result array
+        *
+        * @param stdClass $row
+        * @return array
+        */
+       private function extractRowInfo( $row ) {
+               $vals = [];
+               $anyHidden = false;
+
+               if ( $row->rev_deleted & RevisionRecord::DELETED_TEXT ) {
+                       $vals['texthidden'] = true;
+                       $anyHidden = true;
+               }
+
+               // Any rows where we can't view the user were filtered out in the query.
+               $vals['userid'] = (int)$row->rev_user;
+               $vals['user'] = $row->rev_user_text;
+               if ( $row->rev_deleted & RevisionRecord::DELETED_USER ) {
+                       $vals['userhidden'] = true;
+                       $anyHidden = true;
+               }
+               if ( $this->fld_ids ) {
+                       $vals['pageid'] = intval( $row->rev_page );
+                       $vals['revid'] = intval( $row->rev_id );
+                       // $vals['textid'] = intval( $row->rev_text_id ); // todo: Should this field be exposed?
+
+                       if ( !is_null( $row->rev_parent_id ) ) {
+                               $vals['parentid'] = intval( $row->rev_parent_id );
+                       }
+               }
+
+               $title = Title::makeTitle( $row->page_namespace, $row->page_title );
+
+               if ( $this->fld_title ) {
+                       ApiQueryBase::addTitleInfo( $vals, $title );
+               }
+
+               if ( $this->fld_timestamp ) {
+                       $vals['timestamp'] = wfTimestamp( TS_ISO_8601, $row->rev_timestamp );
+               }
+
+               if ( $this->fld_flags ) {
+                       $vals['new'] = $row->rev_parent_id == 0 && !is_null( $row->rev_parent_id );
+                       $vals['minor'] = (bool)$row->rev_minor_edit;
+                       $vals['top'] = $row->page_latest == $row->rev_id;
+               }
+
+               if ( $this->fld_comment || $this->fld_parsedcomment ) {
+                       if ( $row->rev_deleted & RevisionRecord::DELETED_COMMENT ) {
+                               $vals['commenthidden'] = true;
+                               $anyHidden = true;
+                       }
+
+                       $userCanView = RevisionRecord::userCanBitfield(
+                               $row->rev_deleted,
+                               RevisionRecord::DELETED_COMMENT, $this->getUser()
+                       );
+
+                       if ( $userCanView ) {
+                               $comment = $this->commentStore->getComment( 'rev_comment', $row )->text;
+                               if ( $this->fld_comment ) {
+                                       $vals['comment'] = $comment;
+                               }
+
+                               if ( $this->fld_parsedcomment ) {
+                                       $vals['parsedcomment'] = Linker::formatComment( $comment, $title );
+                               }
+                       }
+               }
+
+               if ( $this->fld_patrolled ) {
+                       $vals['patrolled'] = $row->rc_patrolled != RecentChange::PRC_UNPATROLLED;
+                       $vals['autopatrolled'] = $row->rc_patrolled == RecentChange::PRC_AUTOPATROLLED;
+               }
+
+               if ( $this->fld_size && !is_null( $row->rev_len ) ) {
+                       $vals['size'] = intval( $row->rev_len );
+               }
+
+               if ( $this->fld_sizediff
+                       && !is_null( $row->rev_len )
+                       && !is_null( $row->rev_parent_id )
+               ) {
+                       $parentLen = $this->parentLens[$row->rev_parent_id] ?? 0;
+                       $vals['sizediff'] = intval( $row->rev_len - $parentLen );
+               }
+
+               if ( $this->fld_tags ) {
+                       if ( $row->ts_tags ) {
+                               $tags = explode( ',', $row->ts_tags );
+                               ApiResult::setIndexedTagName( $tags, 'tag' );
+                               $vals['tags'] = $tags;
+                       } else {
+                               $vals['tags'] = [];
+                       }
+               }
+
+               if ( $anyHidden && ( $row->rev_deleted & RevisionRecord::DELETED_RESTRICTED ) ) {
+                       $vals['suppressed'] = true;
+               }
+
+               return $vals;
+       }
+
+       private function continueStr( $row ) {
+               if ( $this->multiUserMode ) {
+                       switch ( $this->orderBy ) {
+                               case 'id':
+                                       return "id|$row->rev_user|$row->rev_timestamp|$row->rev_id";
+                               case 'name':
+                                       return "name|$row->rev_user_text|$row->rev_timestamp|$row->rev_id";
+                               case 'actor':
+                                       return "actor|$row->rev_actor|$row->rev_timestamp|$row->rev_id";
+                       }
+               } else {
+                       return "$row->rev_timestamp|$row->rev_id";
+               }
+       }
+
+       public function getCacheMode( $params ) {
+               // This module provides access to deleted revisions and patrol flags if
+               // the requester is logged in
+               return 'anon-public-user-private';
+       }
+
+       public function getAllowedParams() {
+               return [
+                       'limit' => [
+                               ApiBase::PARAM_DFLT => 10,
+                               ApiBase::PARAM_TYPE => 'limit',
+                               ApiBase::PARAM_MIN => 1,
+                               ApiBase::PARAM_MAX => ApiBase::LIMIT_BIG1,
+                               ApiBase::PARAM_MAX2 => ApiBase::LIMIT_BIG2
+                       ],
+                       'start' => [
+                               ApiBase::PARAM_TYPE => 'timestamp'
+                       ],
+                       'end' => [
+                               ApiBase::PARAM_TYPE => 'timestamp'
+                       ],
+                       'continue' => [
+                               ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
+                       ],
+                       'user' => [
+                               ApiBase::PARAM_TYPE => 'user',
+                               ApiBase::PARAM_ISMULTI => true
+                       ],
+                       'userids' => [
+                               ApiBase::PARAM_TYPE => 'integer',
+                               ApiBase::PARAM_ISMULTI => true
+                       ],
+                       'userprefix' => null,
+                       'dir' => [
+                               ApiBase::PARAM_DFLT => 'older',
+                               ApiBase::PARAM_TYPE => [
+                                       'newer',
+                                       'older'
+                               ],
+                               ApiBase::PARAM_HELP_MSG => 'api-help-param-direction',
+                       ],
+                       'namespace' => [
+                               ApiBase::PARAM_ISMULTI => true,
+                               ApiBase::PARAM_TYPE => 'namespace'
+                       ],
+                       'prop' => [
+                               ApiBase::PARAM_ISMULTI => true,
+                               ApiBase::PARAM_DFLT => 'ids|title|timestamp|comment|size|flags',
+                               ApiBase::PARAM_TYPE => [
+                                       'ids',
+                                       'title',
+                                       'timestamp',
+                                       'comment',
+                                       'parsedcomment',
+                                       'size',
+                                       'sizediff',
+                                       'flags',
+                                       'patrolled',
+                                       'tags'
+                               ],
+                               ApiBase::PARAM_HELP_MSG_PER_VALUE => [],
+                       ],
+                       'show' => [
+                               ApiBase::PARAM_ISMULTI => true,
+                               ApiBase::PARAM_TYPE => [
+                                       'minor',
+                                       '!minor',
+                                       'patrolled',
+                                       '!patrolled',
+                                       'autopatrolled',
+                                       '!autopatrolled',
+                                       'top',
+                                       '!top',
+                                       'new',
+                                       '!new',
+                               ],
+                               ApiBase::PARAM_HELP_MSG => [
+                                       'apihelp-query+usercontribs-param-show',
+                                       $this->getConfig()->get( 'RCMaxAge' )
+                               ],
+                       ],
+                       'tag' => null,
+                       'toponly' => [
+                               ApiBase::PARAM_DFLT => false,
+                               ApiBase::PARAM_DEPRECATED => true,
+                       ],
+               ];
+       }
+
+       protected function getExamplesMessages() {
+               return [
+                       'action=query&list=usercontribs&ucuser=Example'
+                               => 'apihelp-query+usercontribs-example-user',
+                       'action=query&list=usercontribs&ucuserprefix=192.0.2.'
+                               => 'apihelp-query+usercontribs-example-ipprefix',
+               ];
+       }
+
+       public function getHelpUrls() {
+               return 'https://www.mediawiki.org/wiki/Special:MyLanguage/API:Usercontribs';
+       }
+}
+
+/**
+ * @since 1.9
+ * @deprecated since 1.32
+ */
+class_alias( ApiQueryUserContribs::class, 'ApiQueryContributions' );
diff --git a/includes/api/ApiQueryUserContributions.php b/includes/api/ApiQueryUserContributions.php
deleted file mode 100644 (file)
index 12f42ed..0000000
+++ /dev/null
@@ -1,832 +0,0 @@
-<?php
-/**
- * Copyright © 2006 Yuri Astrakhan "<Firstname><Lastname>@gmail.com"
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- */
-
-/**
- * This query action adds a list of a specified user's contributions to the output.
- *
- * @ingroup API
- */
-class ApiQueryContributions extends ApiQueryBase {
-
-       public function __construct( ApiQuery $query, $moduleName ) {
-               parent::__construct( $query, $moduleName, 'uc' );
-       }
-
-       private $params, $multiUserMode, $orderBy, $parentLens;
-       private $fld_ids = false, $fld_title = false, $fld_timestamp = false,
-               $fld_comment = false, $fld_parsedcomment = false, $fld_flags = false,
-               $fld_patrolled = false, $fld_tags = false, $fld_size = false, $fld_sizediff = false;
-
-       public function execute() {
-               global $wgActorTableSchemaMigrationStage;
-
-               // Parse some parameters
-               $this->params = $this->extractRequestParams();
-
-               $this->commentStore = CommentStore::getStore();
-
-               $prop = array_flip( $this->params['prop'] );
-               $this->fld_ids = isset( $prop['ids'] );
-               $this->fld_title = isset( $prop['title'] );
-               $this->fld_comment = isset( $prop['comment'] );
-               $this->fld_parsedcomment = isset( $prop['parsedcomment'] );
-               $this->fld_size = isset( $prop['size'] );
-               $this->fld_sizediff = isset( $prop['sizediff'] );
-               $this->fld_flags = isset( $prop['flags'] );
-               $this->fld_timestamp = isset( $prop['timestamp'] );
-               $this->fld_patrolled = isset( $prop['patrolled'] );
-               $this->fld_tags = isset( $prop['tags'] );
-
-               // Most of this code will use the 'contributions' group DB, which can map to replica DBs
-               // with extra user based indexes or partioning by user. The additional metadata
-               // queries should use a regular replica DB since the lookup pattern is not all by user.
-               $dbSecondary = $this->getDB(); // any random replica DB
-
-               // TODO: if the query is going only against the revision table, should this be done?
-               $this->selectNamedDB( 'contributions', DB_REPLICA, 'contributions' );
-
-               $sort = ( $this->params['dir'] == 'newer' ? '' : ' DESC' );
-               $op = ( $this->params['dir'] == 'older' ? '<' : '>' );
-
-               // Create an Iterator that produces the UserIdentity objects we need, depending
-               // on which of the 'userprefix', 'userids', or 'user' params was
-               // specified.
-               $this->requireOnlyOneParameter( $this->params, 'userprefix', 'userids', 'user' );
-               if ( isset( $this->params['userprefix'] ) ) {
-                       $this->multiUserMode = true;
-                       $this->orderBy = 'name';
-                       $fname = __METHOD__;
-
-                       // Because 'userprefix' might produce a huge number of users (e.g.
-                       // a wiki with users "Test00000001" to "Test99999999"), use a
-                       // generator with batched lookup and continuation.
-                       $userIter = call_user_func( function () use ( $dbSecondary, $sort, $op, $fname ) {
-                               global $wgActorTableSchemaMigrationStage;
-
-                               $fromName = false;
-                               if ( !is_null( $this->params['continue'] ) ) {
-                                       $continue = explode( '|', $this->params['continue'] );
-                                       $this->dieContinueUsageIf( count( $continue ) != 4 );
-                                       $this->dieContinueUsageIf( $continue[0] !== 'name' );
-                                       $fromName = $continue[1];
-                               }
-                               $like = $dbSecondary->buildLike( $this->params['userprefix'], $dbSecondary->anyString() );
-
-                               $limit = 501;
-
-                               do {
-                                       $from = $fromName ? "$op= " . $dbSecondary->addQuotes( $fromName ) : false;
-
-                                       // For the new schema, pull from the actor table. For the
-                                       // old, pull from rev_user. For migration a FULL [OUTER]
-                                       // JOIN would be what we want, except MySQL doesn't support
-                                       // that so we have to UNION instead.
-                                       if ( $wgActorTableSchemaMigrationStage === MIGRATION_NEW ) {
-                                               $res = $dbSecondary->select(
-                                                       'actor',
-                                                       [ 'actor_id', 'user_id' => 'COALESCE(actor_user,0)', 'user_name' => 'actor_name' ],
-                                                       array_merge( [ "actor_name$like" ], $from ? [ "actor_name $from" ] : [] ),
-                                                       $fname,
-                                                       [ 'ORDER BY' => [ "user_name $sort" ], 'LIMIT' => $limit ]
-                                               );
-                                       } elseif ( $wgActorTableSchemaMigrationStage === MIGRATION_OLD ) {
-                                               $res = $dbSecondary->select(
-                                                       'revision',
-                                                       [ 'actor_id' => 'NULL', 'user_id' => 'rev_user', 'user_name' => 'rev_user_text' ],
-                                                       array_merge( [ "rev_user_text$like" ], $from ? [ "rev_user_text $from" ] : [] ),
-                                                       $fname,
-                                                       [ 'DISTINCT', 'ORDER BY' => [ "rev_user_text $sort" ], 'LIMIT' => $limit ]
-                                               );
-                                       } else {
-                                               // There are three queries we have to combine to be sure of getting all results:
-                                               //  - actor table (any rows that have been migrated will have empty rev_user_text)
-                                               //  - revision+actor by user id
-                                               //  - revision+actor by name for anons
-                                               $options = $dbSecondary->unionSupportsOrderAndLimit()
-                                                       ? [ 'ORDER BY' => [ "user_name $sort" ], 'LIMIT' => $limit ] : [];
-                                               $subsql = [];
-                                               $subsql[] = $dbSecondary->selectSQLText(
-                                                       'actor',
-                                                       [ 'actor_id', 'user_id' => 'COALESCE(actor_user,0)', 'user_name' => 'actor_name' ],
-                                                       array_merge( [ "actor_name$like" ], $from ? [ "actor_name $from" ] : [] ),
-                                                       $fname,
-                                                       $options
-                                               );
-                                               $subsql[] = $dbSecondary->selectSQLText(
-                                                       [ 'revision', 'actor' ],
-                                                       [ 'actor_id', 'user_id' => 'rev_user', 'user_name' => 'rev_user_text' ],
-                                                       array_merge(
-                                                               [ "rev_user_text$like", 'rev_user != 0' ],
-                                                               $from ? [ "rev_user_text $from" ] : []
-                                                       ),
-                                                       $fname,
-                                                       array_merge( [ 'DISTINCT' ], $options ),
-                                                       [ 'actor' => [ 'LEFT JOIN', 'rev_user = actor_user' ] ]
-                                               );
-                                               $subsql[] = $dbSecondary->selectSQLText(
-                                                       [ 'revision', 'actor' ],
-                                                       [ 'actor_id', 'user_id' => 'rev_user', 'user_name' => 'rev_user_text' ],
-                                                       array_merge(
-                                                               [ "rev_user_text$like", 'rev_user = 0' ],
-                                                               $from ? [ "rev_user_text $from" ] : []
-                                                       ),
-                                                       $fname,
-                                                       array_merge( [ 'DISTINCT' ], $options ),
-                                                       [ 'actor' => [ 'LEFT JOIN', 'rev_user_text = actor_name' ] ]
-                                               );
-                                               $sql = $dbSecondary->unionQueries( $subsql, false ) . " ORDER BY user_name $sort";
-                                               $sql = $dbSecondary->limitResult( $sql, $limit );
-                                               $res = $dbSecondary->query( $sql, $fname );
-                                       }
-
-                                       $count = 0;
-                                       $fromName = false;
-                                       foreach ( $res as $row ) {
-                                               if ( ++$count >= $limit ) {
-                                                       $fromName = $row->user_name;
-                                                       break;
-                                               }
-                                               yield User::newFromRow( $row );
-                                       }
-                               } while ( $fromName !== false );
-                       } );
-                       // Do the actual sorting client-side, because otherwise
-                       // prepareQuery might try to sort by actor and confuse everything.
-                       $batchSize = 1;
-               } elseif ( isset( $this->params['userids'] ) ) {
-                       if ( !count( $this->params['userids'] ) ) {
-                               $encParamName = $this->encodeParamName( 'userids' );
-                               $this->dieWithError( [ 'apierror-paramempty', $encParamName ], "paramempty_$encParamName" );
-                       }
-
-                       $ids = [];
-                       foreach ( $this->params['userids'] as $uid ) {
-                               if ( $uid <= 0 ) {
-                                       $this->dieWithError( [ 'apierror-invaliduserid', $uid ], 'invaliduserid' );
-                               }
-                               $ids[] = $uid;
-                       }
-
-                       $this->orderBy = 'id';
-                       $this->multiUserMode = count( $ids ) > 1;
-
-                       $from = $fromId = false;
-                       if ( $this->multiUserMode && !is_null( $this->params['continue'] ) ) {
-                               $continue = explode( '|', $this->params['continue'] );
-                               $this->dieContinueUsageIf( count( $continue ) != 4 );
-                               $this->dieContinueUsageIf( $continue[0] !== 'id' && $continue[0] !== 'actor' );
-                               $fromId = (int)$continue[1];
-                               $this->dieContinueUsageIf( $continue[1] !== (string)$fromId );
-                               $from = "$op= $fromId";
-                       }
-
-                       // For the new schema, just select from the actor table. For the
-                       // old and transitional schemas, select from user and left join
-                       // actor if it exists.
-                       if ( $wgActorTableSchemaMigrationStage === MIGRATION_NEW ) {
-                               $res = $dbSecondary->select(
-                                       'actor',
-                                       [ 'actor_id', 'user_id' => 'actor_user', 'user_name' => 'actor_name' ],
-                                       array_merge( [ 'actor_user' => $ids ], $from ? [ "actor_id $from" ] : [] ),
-                                       __METHOD__,
-                                       [ 'ORDER BY' => "user_id $sort" ]
-                               );
-                       } elseif ( $wgActorTableSchemaMigrationStage === MIGRATION_OLD ) {
-                               $res = $dbSecondary->select(
-                                       'user',
-                                       [ 'actor_id' => 'NULL', 'user_id' => 'user_id', 'user_name' => 'user_name' ],
-                                       array_merge( [ 'user_id' => $ids ], $from ? [ "user_id $from" ] : [] ),
-                                       __METHOD__,
-                                       [ 'ORDER BY' => "user_id $sort" ]
-                               );
-                       } else {
-                               $res = $dbSecondary->select(
-                                       [ 'user', 'actor' ],
-                                       [ 'actor_id', 'user_id', 'user_name' ],
-                                       array_merge( [ 'user_id' => $ids ], $from ? [ "user_id $from" ] : [] ),
-                                       __METHOD__,
-                                       [ 'ORDER BY' => "user_id $sort" ],
-                                       [ 'actor' => [ 'LEFT JOIN', 'actor_user = user_id' ] ]
-                               );
-                       }
-                       $userIter = UserArray::newFromResult( $res );
-                       $batchSize = count( $ids );
-               } else {
-                       $names = [];
-                       if ( !count( $this->params['user'] ) ) {
-                               $encParamName = $this->encodeParamName( 'user' );
-                               $this->dieWithError(
-                                       [ 'apierror-paramempty', $encParamName ], "paramempty_$encParamName"
-                               );
-                       }
-                       foreach ( $this->params['user'] as $u ) {
-                               if ( $u === '' ) {
-                                       $encParamName = $this->encodeParamName( 'user' );
-                                       $this->dieWithError(
-                                               [ 'apierror-paramempty', $encParamName ], "paramempty_$encParamName"
-                                       );
-                               }
-
-                               if ( User::isIP( $u ) || ExternalUserNames::isExternal( $u ) ) {
-                                       $names[$u] = null;
-                               } else {
-                                       $name = User::getCanonicalName( $u, 'valid' );
-                                       if ( $name === false ) {
-                                               $encParamName = $this->encodeParamName( 'user' );
-                                               $this->dieWithError(
-                                                       [ 'apierror-baduser', $encParamName, wfEscapeWikiText( $u ) ], "baduser_$encParamName"
-                                               );
-                                       }
-                                       $names[$name] = null;
-                               }
-                       }
-
-                       $this->orderBy = 'name';
-                       $this->multiUserMode = count( $names ) > 1;
-
-                       $from = $fromName = false;
-                       if ( $this->multiUserMode && !is_null( $this->params['continue'] ) ) {
-                               $continue = explode( '|', $this->params['continue'] );
-                               $this->dieContinueUsageIf( count( $continue ) != 4 );
-                               $this->dieContinueUsageIf( $continue[0] !== 'name' && $continue[0] !== 'actor' );
-                               $fromName = $continue[1];
-                               $from = "$op= " . $dbSecondary->addQuotes( $fromName );
-                       }
-
-                       // For the new schema, just select from the actor table. For the
-                       // old and transitional schemas, select from user and left join
-                       // actor if it exists then merge in any unknown users (IPs and imports).
-                       if ( $wgActorTableSchemaMigrationStage === MIGRATION_NEW ) {
-                               $res = $dbSecondary->select(
-                                       'actor',
-                                       [ 'actor_id', 'user_id' => 'actor_user', 'user_name' => 'actor_name' ],
-                                       array_merge( [ 'actor_name' => array_keys( $names ) ], $from ? [ "actor_id $from" ] : [] ),
-                                       __METHOD__,
-                                       [ 'ORDER BY' => "actor_name $sort" ]
-                               );
-                               $userIter = UserArray::newFromResult( $res );
-                       } else {
-                               if ( $wgActorTableSchemaMigrationStage === MIGRATION_OLD ) {
-                                       $res = $dbSecondary->select(
-                                               'user',
-                                               [ 'actor_id' => 'NULL', 'user_id', 'user_name' ],
-                                               array_merge( [ 'user_name' => array_keys( $names ) ], $from ? [ "user_name $from" ] : [] ),
-                                               __METHOD__
-                                       );
-                               } else {
-                                       $res = $dbSecondary->select(
-                                               [ 'user', 'actor' ],
-                                               [ 'actor_id', 'user_id', 'user_name' ],
-                                               array_merge( [ 'user_name' => array_keys( $names ) ], $from ? [ "user_name $from" ] : [] ),
-                                               __METHOD__,
-                                               [],
-                                               [ 'actor' => [ 'LEFT JOIN', 'actor_user = user_id' ] ]
-                                       );
-                               }
-                               foreach ( $res as $row ) {
-                                       $names[$row->user_name] = $row;
-                               }
-                               call_user_func_array(
-                                       $this->params['dir'] == 'newer' ? 'ksort' : 'krsort', [ &$names, SORT_STRING ]
-                               );
-                               $neg = $op === '>' ? -1 : 1;
-                               $userIter = call_user_func( function () use ( $names, $fromName, $neg ) {
-                                       foreach ( $names as $name => $row ) {
-                                               if ( $fromName === false || $neg * strcmp( $name, $fromName ) <= 0 ) {
-                                                       $user = $row ? User::newFromRow( $row ) : User::newFromName( $name, false );
-                                                       yield $user;
-                                               }
-                                       }
-                               } );
-                       }
-                       $batchSize = count( $names );
-               }
-
-               // During migration, force ordering on the client side because we're
-               // having to combine multiple queries that would otherwise have
-               // different sort orders.
-               if ( $wgActorTableSchemaMigrationStage === MIGRATION_WRITE_BOTH ||
-                       $wgActorTableSchemaMigrationStage === MIGRATION_WRITE_NEW
-               ) {
-                       $batchSize = 1;
-               }
-
-               // With the new schema, the DB query will order by actor so update $this->orderBy to match.
-               if ( $batchSize > 1 && $wgActorTableSchemaMigrationStage === MIGRATION_NEW ) {
-                       $this->orderBy = 'actor';
-               }
-
-               $count = 0;
-               $limit = $this->params['limit'];
-               $userIter->rewind();
-               while ( $userIter->valid() ) {
-                       $users = [];
-                       while ( count( $users ) < $batchSize && $userIter->valid() ) {
-                               $users[] = $userIter->current();
-                               $userIter->next();
-                       }
-
-                       // Ugh. We have to run the query three times, once for each
-                       // possible 'orcond' from ActorMigration, and then merge them all
-                       // together in the proper order. And preserving the correct
-                       // $hookData for each one.
-                       // @todo When ActorMigration is removed, this can go back to a
-                       //  single prepare and select.
-                       $merged = [];
-                       foreach ( [ 'actor', 'userid', 'username' ] as $which ) {
-                               if ( $this->prepareQuery( $users, $limit - $count, $which ) ) {
-                                       $hookData = [];
-                                       $res = $this->select( __METHOD__, [], $hookData );
-                                       foreach ( $res as $row ) {
-                                               $merged[] = [ $row, &$hookData ];
-                                       }
-                               }
-                       }
-                       $neg = $this->params['dir'] == 'newer' ? 1 : -1;
-                       usort( $merged, function ( $a, $b ) use ( $neg, $batchSize ) {
-                               if ( $batchSize === 1 ) { // One user, can't be different
-                                       $ret = 0;
-                               } elseif ( $this->orderBy === 'id' ) {
-                                       $ret = $a[0]->rev_user - $b[0]->rev_user;
-                               } elseif ( $this->orderBy === 'name' ) {
-                                       $ret = strcmp( $a[0]->rev_user_text, $b[0]->rev_user_text );
-                               } else {
-                                       $ret = $a[0]->rev_actor - $b[0]->rev_actor;
-                               }
-
-                               if ( !$ret ) {
-                                       $ret = strcmp(
-                                               wfTimestamp( TS_MW, $a[0]->rev_timestamp ),
-                                               wfTimestamp( TS_MW, $b[0]->rev_timestamp )
-                                       );
-                               }
-
-                               if ( !$ret ) {
-                                       $ret = $a[0]->rev_id - $b[0]->rev_id;
-                               }
-
-                               return $neg * $ret;
-                       } );
-                       $merged = array_slice( $merged, 0, $limit - $count + 1 );
-                       // (end "Ugh")
-
-                       if ( $this->fld_sizediff ) {
-                               $revIds = [];
-                               foreach ( $merged as $data ) {
-                                       if ( $data[0]->rev_parent_id ) {
-                                               $revIds[] = $data[0]->rev_parent_id;
-                                       }
-                               }
-                               $this->parentLens = Revision::getParentLengths( $dbSecondary, $revIds );
-                       }
-
-                       foreach ( $merged as $data ) {
-                               $row = $data[0];
-                               $hookData = &$data[1];
-                               if ( ++$count > $limit ) {
-                                       // We've reached the one extra which shows that there are
-                                       // additional pages to be had. Stop here...
-                                       $this->setContinueEnumParameter( 'continue', $this->continueStr( $row ) );
-                                       break 2;
-                               }
-
-                               $vals = $this->extractRowInfo( $row );
-                               $fit = $this->processRow( $row, $vals, $hookData ) &&
-                                       $this->getResult()->addValue( [ 'query', $this->getModuleName() ], null, $vals );
-                               if ( !$fit ) {
-                                       $this->setContinueEnumParameter( 'continue', $this->continueStr( $row ) );
-                                       break 2;
-                               }
-                       }
-               }
-
-               $this->getResult()->addIndexedTagName( [ 'query', $this->getModuleName() ], 'item' );
-       }
-
-       /**
-        * Prepares the query and returns the limit of rows requested
-        * @param User[] $users
-        * @param int $limit
-        * @param string $which 'actor', 'userid', or 'username'
-        * @return bool
-        */
-       private function prepareQuery( array $users, $limit, $which ) {
-               global $wgActorTableSchemaMigrationStage;
-
-               $this->resetQueryParams();
-               $db = $this->getDB();
-
-               $revQuery = Revision::getQueryInfo( [ 'page' ] );
-               $this->addTables( $revQuery['tables'] );
-               $this->addJoinConds( $revQuery['joins'] );
-               $this->addFields( $revQuery['fields'] );
-
-               $revWhere = ActorMigration::newMigration()->getWhere( $db, 'rev_user', $users );
-               if ( !isset( $revWhere['orconds'][$which] ) ) {
-                       return false;
-               }
-               $this->addWhere( $revWhere['orconds'][$which] );
-
-               if ( $wgActorTableSchemaMigrationStage === MIGRATION_NEW ) {
-                       $orderUserField = 'rev_actor';
-                       $userField = $this->orderBy === 'actor' ? 'revactor_actor' : 'actor_name';
-               } else {
-                       $orderUserField = $this->orderBy === 'id' ? 'rev_user' : 'rev_user_text';
-                       $userField = $revQuery['fields'][$orderUserField];
-               }
-               if ( $which === 'actor' ) {
-                       $tsField = 'revactor_timestamp';
-                       $idField = 'revactor_rev';
-               } else {
-                       $tsField = 'rev_timestamp';
-                       $idField = 'rev_id';
-               }
-
-               // Handle continue parameter
-               if ( !is_null( $this->params['continue'] ) ) {
-                       $continue = explode( '|', $this->params['continue'] );
-                       if ( $this->multiUserMode ) {
-                               $this->dieContinueUsageIf( count( $continue ) != 4 );
-                               $modeFlag = array_shift( $continue );
-                               $this->dieContinueUsageIf( $modeFlag !== $this->orderBy );
-                               $encUser = $db->addQuotes( array_shift( $continue ) );
-                       } else {
-                               $this->dieContinueUsageIf( count( $continue ) != 2 );
-                       }
-                       $encTS = $db->addQuotes( $db->timestamp( $continue[0] ) );
-                       $encId = (int)$continue[1];
-                       $this->dieContinueUsageIf( $encId != $continue[1] );
-                       $op = ( $this->params['dir'] == 'older' ? '<' : '>' );
-                       if ( $this->multiUserMode ) {
-                               $this->addWhere(
-                                       "$userField $op $encUser OR " .
-                                       "($userField = $encUser AND " .
-                                       "($tsField $op $encTS OR " .
-                                       "($tsField = $encTS AND " .
-                                       "$idField $op= $encId)))"
-                               );
-                       } else {
-                               $this->addWhere(
-                                       "$tsField $op $encTS OR " .
-                                       "($tsField = $encTS AND " .
-                                       "$idField $op= $encId)"
-                               );
-                       }
-               }
-
-               // Don't include any revisions where we're not supposed to be able to
-               // see the username.
-               $user = $this->getUser();
-               if ( !$user->isAllowed( 'deletedhistory' ) ) {
-                       $bitmask = Revision::DELETED_USER;
-               } elseif ( !$user->isAllowedAny( 'suppressrevision', 'viewsuppressed' ) ) {
-                       $bitmask = Revision::DELETED_USER | Revision::DELETED_RESTRICTED;
-               } else {
-                       $bitmask = 0;
-               }
-               if ( $bitmask ) {
-                       $this->addWhere( $db->bitAnd( 'rev_deleted', $bitmask ) . " != $bitmask" );
-               }
-
-               // Add the user field to ORDER BY if there are multiple users
-               if ( count( $users ) > 1 ) {
-                       $this->addWhereRange( $orderUserField, $this->params['dir'], null, null );
-               }
-
-               // Then timestamp
-               $this->addTimestampWhereRange( $tsField,
-                       $this->params['dir'], $this->params['start'], $this->params['end'] );
-
-               // Then rev_id for a total ordering
-               $this->addWhereRange( $idField, $this->params['dir'], null, null );
-
-               $this->addWhereFld( 'page_namespace', $this->params['namespace'] );
-
-               $show = $this->params['show'];
-               if ( $this->params['toponly'] ) { // deprecated/old param
-                       $show[] = 'top';
-               }
-               if ( !is_null( $show ) ) {
-                       $show = array_flip( $show );
-
-                       if ( ( isset( $show['minor'] ) && isset( $show['!minor'] ) )
-                               || ( isset( $show['patrolled'] ) && isset( $show['!patrolled'] ) )
-                               || ( isset( $show['autopatrolled'] ) && isset( $show['!autopatrolled'] ) )
-                               || ( isset( $show['autopatrolled'] ) && isset( $show['!patrolled'] ) )
-                               || ( isset( $show['top'] ) && isset( $show['!top'] ) )
-                               || ( isset( $show['new'] ) && isset( $show['!new'] ) )
-                       ) {
-                               $this->dieWithError( 'apierror-show' );
-                       }
-
-                       $this->addWhereIf( 'rev_minor_edit = 0', isset( $show['!minor'] ) );
-                       $this->addWhereIf( 'rev_minor_edit != 0', isset( $show['minor'] ) );
-                       $this->addWhereIf(
-                               'rc_patrolled = ' . RecentChange::PRC_UNPATROLLED,
-                               isset( $show['!patrolled'] )
-                       );
-                       $this->addWhereIf(
-                               'rc_patrolled != ' . RecentChange::PRC_UNPATROLLED,
-                               isset( $show['patrolled'] )
-                       );
-                       $this->addWhereIf(
-                               'rc_patrolled != ' . RecentChange::PRC_AUTOPATROLLED,
-                               isset( $show['!autopatrolled'] )
-                       );
-                       $this->addWhereIf(
-                               'rc_patrolled = ' . RecentChange::PRC_AUTOPATROLLED,
-                               isset( $show['autopatrolled'] )
-                       );
-                       $this->addWhereIf( $idField . ' != page_latest', isset( $show['!top'] ) );
-                       $this->addWhereIf( $idField . ' = page_latest', isset( $show['top'] ) );
-                       $this->addWhereIf( 'rev_parent_id != 0', isset( $show['!new'] ) );
-                       $this->addWhereIf( 'rev_parent_id = 0', isset( $show['new'] ) );
-               }
-               $this->addOption( 'LIMIT', $limit + 1 );
-
-               if ( isset( $show['patrolled'] ) || isset( $show['!patrolled'] ) ||
-                       isset( $show['autopatrolled'] ) || isset( $show['!autopatrolled'] ) || $this->fld_patrolled
-               ) {
-                       if ( !$user->useRCPatrol() && !$user->useNPPatrol() ) {
-                               $this->dieWithError( 'apierror-permissiondenied-patrolflag', 'permissiondenied' );
-                       }
-
-                       $isFilterset = isset( $show['patrolled'] ) || isset( $show['!patrolled'] ) ||
-                               isset( $show['autopatrolled'] ) || isset( $show['!autopatrolled'] );
-                       $this->addTables( 'recentchanges' );
-                       $this->addJoinConds( [ 'recentchanges' => [
-                               $isFilterset ? 'JOIN' : 'LEFT JOIN',
-                               [
-                                       // This is a crazy hack. recentchanges has no index on rc_this_oldid, so instead of adding
-                                       // one T19237 did a join using rc_user_text and rc_timestamp instead. Now rc_user_text is
-                                       // probably unavailable, so just do rc_timestamp.
-                                       'rc_timestamp = ' . $tsField,
-                                       'rc_this_oldid = ' . $idField,
-                               ]
-                       ] ] );
-               }
-
-               $this->addFieldsIf( 'rc_patrolled', $this->fld_patrolled );
-
-               if ( $this->fld_tags ) {
-                       $this->addTables( 'tag_summary' );
-                       $this->addJoinConds(
-                               [ 'tag_summary' => [ 'LEFT JOIN', [ $idField . ' = ts_rev_id' ] ] ]
-                       );
-                       $this->addFields( 'ts_tags' );
-               }
-
-               if ( isset( $this->params['tag'] ) ) {
-                       $this->addTables( 'change_tag' );
-                       $this->addJoinConds(
-                               [ 'change_tag' => [ 'INNER JOIN', [ $idField . ' = ct_rev_id' ] ] ]
-                       );
-                       $this->addWhereFld( 'ct_tag', $this->params['tag'] );
-               }
-
-               return true;
-       }
-
-       /**
-        * Extract fields from the database row and append them to a result array
-        *
-        * @param stdClass $row
-        * @return array
-        */
-       private function extractRowInfo( $row ) {
-               $vals = [];
-               $anyHidden = false;
-
-               if ( $row->rev_deleted & Revision::DELETED_TEXT ) {
-                       $vals['texthidden'] = true;
-                       $anyHidden = true;
-               }
-
-               // Any rows where we can't view the user were filtered out in the query.
-               $vals['userid'] = (int)$row->rev_user;
-               $vals['user'] = $row->rev_user_text;
-               if ( $row->rev_deleted & Revision::DELETED_USER ) {
-                       $vals['userhidden'] = true;
-                       $anyHidden = true;
-               }
-               if ( $this->fld_ids ) {
-                       $vals['pageid'] = intval( $row->rev_page );
-                       $vals['revid'] = intval( $row->rev_id );
-                       // $vals['textid'] = intval( $row->rev_text_id ); // todo: Should this field be exposed?
-
-                       if ( !is_null( $row->rev_parent_id ) ) {
-                               $vals['parentid'] = intval( $row->rev_parent_id );
-                       }
-               }
-
-               $title = Title::makeTitle( $row->page_namespace, $row->page_title );
-
-               if ( $this->fld_title ) {
-                       ApiQueryBase::addTitleInfo( $vals, $title );
-               }
-
-               if ( $this->fld_timestamp ) {
-                       $vals['timestamp'] = wfTimestamp( TS_ISO_8601, $row->rev_timestamp );
-               }
-
-               if ( $this->fld_flags ) {
-                       $vals['new'] = $row->rev_parent_id == 0 && !is_null( $row->rev_parent_id );
-                       $vals['minor'] = (bool)$row->rev_minor_edit;
-                       $vals['top'] = $row->page_latest == $row->rev_id;
-               }
-
-               if ( $this->fld_comment || $this->fld_parsedcomment ) {
-                       if ( $row->rev_deleted & Revision::DELETED_COMMENT ) {
-                               $vals['commenthidden'] = true;
-                               $anyHidden = true;
-                       }
-
-                       $userCanView = Revision::userCanBitfield(
-                               $row->rev_deleted,
-                               Revision::DELETED_COMMENT, $this->getUser()
-                       );
-
-                       if ( $userCanView ) {
-                               $comment = $this->commentStore->getComment( 'rev_comment', $row )->text;
-                               if ( $this->fld_comment ) {
-                                       $vals['comment'] = $comment;
-                               }
-
-                               if ( $this->fld_parsedcomment ) {
-                                       $vals['parsedcomment'] = Linker::formatComment( $comment, $title );
-                               }
-                       }
-               }
-
-               if ( $this->fld_patrolled ) {
-                       $vals['patrolled'] = $row->rc_patrolled != RecentChange::PRC_UNPATROLLED;
-                       $vals['autopatrolled'] = $row->rc_patrolled == RecentChange::PRC_AUTOPATROLLED;
-               }
-
-               if ( $this->fld_size && !is_null( $row->rev_len ) ) {
-                       $vals['size'] = intval( $row->rev_len );
-               }
-
-               if ( $this->fld_sizediff
-                       && !is_null( $row->rev_len )
-                       && !is_null( $row->rev_parent_id )
-               ) {
-                       $parentLen = isset( $this->parentLens[$row->rev_parent_id] )
-                               ? $this->parentLens[$row->rev_parent_id]
-                               : 0;
-                       $vals['sizediff'] = intval( $row->rev_len - $parentLen );
-               }
-
-               if ( $this->fld_tags ) {
-                       if ( $row->ts_tags ) {
-                               $tags = explode( ',', $row->ts_tags );
-                               ApiResult::setIndexedTagName( $tags, 'tag' );
-                               $vals['tags'] = $tags;
-                       } else {
-                               $vals['tags'] = [];
-                       }
-               }
-
-               if ( $anyHidden && $row->rev_deleted & Revision::DELETED_RESTRICTED ) {
-                       $vals['suppressed'] = true;
-               }
-
-               return $vals;
-       }
-
-       private function continueStr( $row ) {
-               if ( $this->multiUserMode ) {
-                       switch ( $this->orderBy ) {
-                               case 'id':
-                                       return "id|$row->rev_user|$row->rev_timestamp|$row->rev_id";
-                               case 'name':
-                                       return "name|$row->rev_user_text|$row->rev_timestamp|$row->rev_id";
-                               case 'actor':
-                                       return "actor|$row->rev_actor|$row->rev_timestamp|$row->rev_id";
-                       }
-               } else {
-                       return "$row->rev_timestamp|$row->rev_id";
-               }
-       }
-
-       public function getCacheMode( $params ) {
-               // This module provides access to deleted revisions and patrol flags if
-               // the requester is logged in
-               return 'anon-public-user-private';
-       }
-
-       public function getAllowedParams() {
-               return [
-                       'limit' => [
-                               ApiBase::PARAM_DFLT => 10,
-                               ApiBase::PARAM_TYPE => 'limit',
-                               ApiBase::PARAM_MIN => 1,
-                               ApiBase::PARAM_MAX => ApiBase::LIMIT_BIG1,
-                               ApiBase::PARAM_MAX2 => ApiBase::LIMIT_BIG2
-                       ],
-                       'start' => [
-                               ApiBase::PARAM_TYPE => 'timestamp'
-                       ],
-                       'end' => [
-                               ApiBase::PARAM_TYPE => 'timestamp'
-                       ],
-                       'continue' => [
-                               ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
-                       ],
-                       'user' => [
-                               ApiBase::PARAM_TYPE => 'user',
-                               ApiBase::PARAM_ISMULTI => true
-                       ],
-                       'userids' => [
-                               ApiBase::PARAM_TYPE => 'integer',
-                               ApiBase::PARAM_ISMULTI => true
-                       ],
-                       'userprefix' => null,
-                       'dir' => [
-                               ApiBase::PARAM_DFLT => 'older',
-                               ApiBase::PARAM_TYPE => [
-                                       'newer',
-                                       'older'
-                               ],
-                               ApiBase::PARAM_HELP_MSG => 'api-help-param-direction',
-                       ],
-                       'namespace' => [
-                               ApiBase::PARAM_ISMULTI => true,
-                               ApiBase::PARAM_TYPE => 'namespace'
-                       ],
-                       'prop' => [
-                               ApiBase::PARAM_ISMULTI => true,
-                               ApiBase::PARAM_DFLT => 'ids|title|timestamp|comment|size|flags',
-                               ApiBase::PARAM_TYPE => [
-                                       'ids',
-                                       'title',
-                                       'timestamp',
-                                       'comment',
-                                       'parsedcomment',
-                                       'size',
-                                       'sizediff',
-                                       'flags',
-                                       'patrolled',
-                                       'tags'
-                               ],
-                               ApiBase::PARAM_HELP_MSG_PER_VALUE => [],
-                       ],
-                       'show' => [
-                               ApiBase::PARAM_ISMULTI => true,
-                               ApiBase::PARAM_TYPE => [
-                                       'minor',
-                                       '!minor',
-                                       'patrolled',
-                                       '!patrolled',
-                                       'autopatrolled',
-                                       '!autopatrolled',
-                                       'top',
-                                       '!top',
-                                       'new',
-                                       '!new',
-                               ],
-                               ApiBase::PARAM_HELP_MSG => [
-                                       'apihelp-query+usercontribs-param-show',
-                                       $this->getConfig()->get( 'RCMaxAge' )
-                               ],
-                       ],
-                       'tag' => null,
-                       'toponly' => [
-                               ApiBase::PARAM_DFLT => false,
-                               ApiBase::PARAM_DEPRECATED => true,
-                       ],
-               ];
-       }
-
-       protected function getExamplesMessages() {
-               return [
-                       'action=query&list=usercontribs&ucuser=Example'
-                               => 'apihelp-query+usercontribs-example-user',
-                       'action=query&list=usercontribs&ucuserprefix=192.0.2.'
-                               => 'apihelp-query+usercontribs-example-ipprefix',
-               ];
-       }
-
-       public function getHelpUrls() {
-               return 'https://www.mediawiki.org/wiki/Special:MyLanguage/API:Usercontribs';
-       }
-}
index bb09838..5dd247a 100644 (file)
@@ -21,6 +21,7 @@
  */
 
 use MediaWiki\MediaWikiServices;
+use MediaWiki\Storage\RevisionRecord;
 
 /**
  * This query action allows clients to retrieve a list of recently modified pages
@@ -302,13 +303,13 @@ class ApiQueryWatchlist extends ApiQueryGeneratorBase {
 
                /* Add user data and 'anon' flag, if user is anonymous. */
                if ( $this->fld_user || $this->fld_userid ) {
-                       if ( $recentChangeInfo['rc_deleted'] & Revision::DELETED_USER ) {
+                       if ( $recentChangeInfo['rc_deleted'] & RevisionRecord::DELETED_USER ) {
                                $vals['userhidden'] = true;
                                $anyHidden = true;
                        }
-                       if ( Revision::userCanBitfield(
+                       if ( RevisionRecord::userCanBitfield(
                                $recentChangeInfo['rc_deleted'],
-                               Revision::DELETED_USER,
+                               RevisionRecord::DELETED_USER,
                                $user
                        ) ) {
                                if ( $this->fld_userid ) {
@@ -353,13 +354,13 @@ class ApiQueryWatchlist extends ApiQueryGeneratorBase {
 
                /* Add edit summary / log summary. */
                if ( $this->fld_comment || $this->fld_parsedcomment ) {
-                       if ( $recentChangeInfo['rc_deleted'] & Revision::DELETED_COMMENT ) {
+                       if ( $recentChangeInfo['rc_deleted'] & RevisionRecord::DELETED_COMMENT ) {
                                $vals['commenthidden'] = true;
                                $anyHidden = true;
                        }
-                       if ( Revision::userCanBitfield(
+                       if ( RevisionRecord::userCanBitfield(
                                $recentChangeInfo['rc_deleted'],
-                               Revision::DELETED_COMMENT,
+                               RevisionRecord::DELETED_COMMENT,
                                $user
                        ) ) {
                                $comment = $this->commentStore->getComment( 'rc_comment', $recentChangeInfo )->text;
@@ -407,7 +408,7 @@ class ApiQueryWatchlist extends ApiQueryGeneratorBase {
                        }
                }
 
-               if ( $anyHidden && ( $recentChangeInfo['rc_deleted'] & Revision::DELETED_RESTRICTED ) ) {
+               if ( $anyHidden && ( $recentChangeInfo['rc_deleted'] & RevisionRecord::DELETED_RESTRICTED ) ) {
                        $vals['suppressed'] = true;
                }
 
diff --git a/includes/api/ApiRawMessage.php b/includes/api/ApiRawMessage.php
new file mode 100644 (file)
index 0000000..ed3537a
--- /dev/null
@@ -0,0 +1,52 @@
+<?php
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+/**
+ * Extension of RawMessage implementing IApiMessage
+ * @since 1.25
+ * @ingroup API
+ */
+class ApiRawMessage extends RawMessage implements IApiMessage {
+       use ApiMessageTrait;
+
+       /**
+        * @param RawMessage|string|array $msg
+        *  - RawMessage: is cloned
+        *  - array: first element is $key, rest are $params to RawMessage::__construct
+        *  - string: passed to RawMessage::__construct
+        * @param string|null $code
+        * @param array|null $data
+        */
+       public function __construct( $msg, $code = null, array $data = null ) {
+               if ( $msg instanceof RawMessage ) {
+                       foreach ( get_class_vars( get_class( $this ) ) as $key => $value ) {
+                               if ( isset( $msg->$key ) ) {
+                                       $this->$key = $msg->$key;
+                               }
+                       }
+               } elseif ( is_array( $msg ) ) {
+                       $key = array_shift( $msg );
+                       parent::__construct( $key, $msg );
+               } else {
+                       parent::__construct( $msg );
+               }
+               $this->setApiCode( $code, $data );
+       }
+}
index 468d878..3b7c181 100644 (file)
@@ -61,7 +61,7 @@ class ApiResult implements ApiSerializable {
         * probably wrong.
         * @since 1.25
         */
-       const NO_VALIDATE = 12;
+       const NO_VALIDATE = self::NO_SIZE_CHECK | 8;
 
        /**
         * Key for the 'indexed tag name' metadata item. Value is string.
@@ -723,7 +723,7 @@ class ApiResult implements ApiSerializable {
         * @since 1.25
         * @param array &$arr
         * @param string $type See ApiResult::META_TYPE
-        * @param string $kvpKeyName See ApiResult::META_KVP_KEY_NAME
+        * @param string|null $kvpKeyName See ApiResult::META_KVP_KEY_NAME
         */
        public static function setArrayType( array &$arr, $type, $kvpKeyName = null ) {
                if ( !in_array( $type, [
@@ -742,7 +742,7 @@ class ApiResult implements ApiSerializable {
         * @since 1.25
         * @param array|string|null $path See ApiResult::addValue()
         * @param string $tag See ApiResult::META_TYPE
-        * @param string $kvpKeyName See ApiResult::META_KVP_KEY_NAME
+        * @param string|null $kvpKeyName See ApiResult::META_KVP_KEY_NAME
         */
        public function addArrayType( $path, $tag, $kvpKeyName = null ) {
                $arr = &$this->path( $path );
@@ -754,7 +754,7 @@ class ApiResult implements ApiSerializable {
         * @since 1.25
         * @param array &$arr
         * @param string $type See ApiResult::META_TYPE
-        * @param string $kvpKeyName See ApiResult::META_KVP_KEY_NAME
+        * @param string|null $kvpKeyName See ApiResult::META_KVP_KEY_NAME
         */
        public static function setArrayTypeRecursive( array &$arr, $type, $kvpKeyName = null ) {
                self::setArrayType( $arr, $type, $kvpKeyName );
@@ -770,7 +770,7 @@ class ApiResult implements ApiSerializable {
         * @since 1.25
         * @param array|string|null $path See ApiResult::addValue()
         * @param string $tag See ApiResult::META_TYPE
-        * @param string $kvpKeyName See ApiResult::META_KVP_KEY_NAME
+        * @param string|null $kvpKeyName See ApiResult::META_KVP_KEY_NAME
         */
        public function addArrayTypeRecursive( $path, $tag, $kvpKeyName = null ) {
                $arr = &$this->path( $path );
@@ -804,11 +804,11 @@ class ApiResult implements ApiSerializable {
         * @return array|object
         */
        protected static function applyTransformations( array $dataIn, array $transforms ) {
-               $strip = isset( $transforms['Strip'] ) ? $transforms['Strip'] : 'none';
+               $strip = $transforms['Strip'] ?? 'none';
                if ( $strip === 'base' ) {
                        $transforms['Strip'] = 'none';
                }
-               $transformTypes = isset( $transforms['Types'] ) ? $transforms['Types'] : null;
+               $transformTypes = $transforms['Types'] ?? null;
                if ( $transformTypes !== null && !is_array( $transformTypes ) ) {
                        throw new InvalidArgumentException( __METHOD__ . ':Value for "Types" must be an array' );
                }
@@ -954,9 +954,7 @@ class ApiResult implements ApiSerializable {
 
                                case 'kvp':
                                case 'BCkvp':
-                                       $key = isset( $metadata[self::META_KVP_KEY_NAME] )
-                                               ? $metadata[self::META_KVP_KEY_NAME]
-                                               : $transformTypes['ArmorKVP'];
+                                       $key = $metadata[self::META_KVP_KEY_NAME] ?? $transformTypes['ArmorKVP'];
                                        $valKey = isset( $transforms['BC'] ) ? '*' : 'value';
                                        $assocAsObject = !empty( $transformTypes['AssocAsObject'] );
                                        $merge = !empty( $metadata[self::META_KVP_MERGE] );
@@ -1052,7 +1050,7 @@ class ApiResult implements ApiSerializable {
         *
         * @since 1.25
         * @param array|object $data
-        * @param array &$metadata Store metadata here, if provided
+        * @param array|null &$metadata Store metadata here, if provided
         * @return array|object
         */
        public static function stripMetadataNonRecursive( $data, &$metadata = null ) {
index 9a793e2..6121c3d 100644 (file)
@@ -21,6 +21,8 @@
  * @since 1.23
  */
 
+use MediaWiki\Storage\RevisionRecord;
+
 /**
  * API interface to RevDel. The API equivalent of Special:RevisionDelete.
  * Requires API write mode to be enabled.
@@ -61,8 +63,8 @@ class ApiRevisionDelete extends ApiBase {
                }
                $bits = [
                        'content' => RevisionDeleter::getRevdelConstant( $params['type'] ),
-                       'comment' => Revision::DELETED_COMMENT,
-                       'user' => Revision::DELETED_USER,
+                       'comment' => RevisionRecord::DELETED_COMMENT,
+                       'user' => RevisionRecord::DELETED_USER,
                ];
                $bitfield = [];
                foreach ( $bits as $key => $bit ) {
@@ -77,11 +79,11 @@ class ApiRevisionDelete extends ApiBase {
 
                if ( $params['suppress'] === 'yes' ) {
                        $this->checkUserRightsAny( 'suppressrevision' );
-                       $bitfield[Revision::DELETED_RESTRICTED] = 1;
+                       $bitfield[RevisionRecord::DELETED_RESTRICTED] = 1;
                } elseif ( $params['suppress'] === 'no' ) {
-                       $bitfield[Revision::DELETED_RESTRICTED] = 0;
+                       $bitfield[RevisionRecord::DELETED_RESTRICTED] = 0;
                } else {
-                       $bitfield[Revision::DELETED_RESTRICTED] = -1;
+                       $bitfield[RevisionRecord::DELETED_RESTRICTED] = -1;
                }
 
                $targetObj = null;
index f20d1c6..71bab36 100644 (file)
@@ -120,7 +120,7 @@ class ApiRsd extends ApiBase {
                                'name' => $name,
                                'preferred' => wfBoolToStr( $name == 'MediaWiki' ),
                                'apiLink' => $info['apiLink'],
-                               'blogID' => isset( $info['blogID'] ) ? $info['blogID'] : '',
+                               'blogID' => $info['blogID'] ?? '',
                        ];
                        $settings = [];
                        if ( isset( $info['docs'] ) ) {
index f7dc4a7..b81c5bf 100644 (file)
@@ -22,6 +22,7 @@
  *
  * @file
  */
+
 use MediaWiki\MediaWikiServices;
 
 /**
@@ -73,10 +74,11 @@ class ApiSetNotificationTimestamp extends ApiBase {
                        if ( $params['entirewatchlist'] || $pageSet->getGoodTitleCount() > 1 ) {
                                $this->dieWithError( [ 'apierror-multpages', $this->encodeParamName( 'torevid' ) ] );
                        }
-                       $title = reset( $pageSet->getGoodTitles() );
+                       $titles = $pageSet->getGoodTitles();
+                       $title = reset( $titles );
                        if ( $title ) {
-                               $timestamp = Revision::getTimestampFromId(
-                                       $title, $params['torevid'], Revision::READ_LATEST );
+                               $timestamp = MediaWikiServices::getInstance()->getRevisionStore()
+                                       ->getTimestampFromId( $title, $params['torevid'], IDBAccessObject::READ_LATEST );
                                if ( $timestamp ) {
                                        $timestamp = $dbw->timestamp( $timestamp );
                                } else {
@@ -87,12 +89,14 @@ class ApiSetNotificationTimestamp extends ApiBase {
                        if ( $params['entirewatchlist'] || $pageSet->getGoodTitleCount() > 1 ) {
                                $this->dieWithError( [ 'apierror-multpages', $this->encodeParamName( 'newerthanrevid' ) ] );
                        }
-                       $title = reset( $pageSet->getGoodTitles() );
+                       $titles = $pageSet->getGoodTitles();
+                       $title = reset( $titles );
                        if ( $title ) {
-                               $revid = $title->getNextRevisionID(
-                                       $params['newerthanrevid'], Title::GAID_FOR_UPDATE );
+                               $revid = $title->getNextRevisionID( $params['newerthanrevid'], Title::GAID_FOR_UPDATE );
                                if ( $revid ) {
-                                       $timestamp = $dbw->timestamp( Revision::getTimestampFromId( $title, $revid ) );
+                                       $timestamp = $dbw->timestamp(
+                                               MediaWikiServices::getInstance()->getRevisionStore()->getTimestampFromId( $title, $revid )
+                                       );
                                } else {
                                        $timestamp = null;
                                }
index 40826ae..84ab3ea 100644 (file)
@@ -80,7 +80,7 @@ class ApiSetPageLanguage extends ApiBase {
                        $this,
                        $titleObj,
                        $params['lang'],
-                       $params['reason'] === null ? '' : $params['reason'],
+                       $params['reason'] ?? '',
                        $params['tags'] ?: []
                );
 
index c9f6db3..e0c7a28 100644 (file)
  * @file
  */
 
+use MediaWiki\MediaWikiServices;
+use MediaWiki\Storage\RevisionStore;
+
 /**
  * @ingroup API
  * @since 1.25
  */
 class ApiTag extends ApiBase {
 
+       /** @var RevisionStore */
+       private $revisionStore;
+
        public function execute() {
+               $this->revisionStore = MediaWikiServices::getInstance()->getRevisionStore();
+
                $params = $this->extractRequestParams();
                $user = $this->getUser();
 
@@ -84,7 +92,7 @@ class ApiTag extends ApiBase {
                                $valid = RecentChange::newFromId( $id );
                                break;
                        case 'revid':
-                               $valid = Revision::newFromId( $id );
+                               $valid = $this->revisionStore->getRevisionById( $id );
                                break;
                        case 'logid':
                                $valid = self::validateLogId( $id );
index ee5c3a2..840ef1b 100644 (file)
@@ -65,7 +65,7 @@ class ApiUndelete extends ApiBase {
 
                $pa = new PageArchive( $titleObj, $this->getConfig() );
                $retval = $pa->undelete(
-                       ( isset( $params['timestamps'] ) ? $params['timestamps'] : [] ),
+                       ( $params['timestamps'] ?? [] ),
                        $params['reason'],
                        $params['fileids'],
                        false,
index 93e432b..2c5b583 100644 (file)
@@ -682,9 +682,7 @@ class ApiUpload extends ApiBase {
                                $warning = $warnings['exists'];
                                unset( $warnings['exists'] );
                                /** @var LocalFile $localFile */
-                               $localFile = isset( $warning['normalizedFile'] )
-                                       ? $warning['normalizedFile']
-                                       : $warning['file'];
+                               $localFile = $warning['normalizedFile'] ?? $warning['file'];
                                $warnings[$warning['warning']] = $localFile->getName();
                        }
 
index c200dcb..7f8a26b 100644 (file)
  * @file
  */
 
-/**
- * This exception will be thrown when dieUsage is called to stop module execution.
- *
- * @ingroup API
- * @deprecated since 1.29, use ApiUsageException instead
- */
-class UsageException extends MWException {
-
-       private $mCodestr;
-
-       /**
-        * @var null|array
-        */
-       private $mExtraData;
-
-       /**
-        * @param string $message
-        * @param string $codestr
-        * @param int $code
-        * @param array|null $extradata
-        */
-       public function __construct( $message, $codestr, $code = 0, $extradata = null ) {
-               parent::__construct( $message, $code );
-               $this->mCodestr = $codestr;
-               $this->mExtraData = $extradata;
-
-               if ( !$this instanceof ApiUsageException ) {
-                       wfDeprecated( __METHOD__, '1.29' );
-               }
-
-               // This should never happen, so throw an exception about it that will
-               // hopefully get logged with a backtrace (T138585)
-               if ( !is_string( $codestr ) || $codestr === '' ) {
-                       throw new InvalidArgumentException( 'Invalid $codestr, was ' .
-                               ( $codestr === '' ? 'empty string' : gettype( $codestr ) )
-                       );
-               }
-       }
-
-       /**
-        * @return string
-        */
-       public function getCodeString() {
-               wfDeprecated( __METHOD__, '1.29' );
-               return $this->mCodestr;
-       }
-
-       /**
-        * @return array
-        */
-       public function getMessageArray() {
-               wfDeprecated( __METHOD__, '1.29' );
-               $result = [
-                       'code' => $this->mCodestr,
-                       'info' => $this->getMessage()
-               ];
-               if ( is_array( $this->mExtraData ) ) {
-                       $result = array_merge( $result, $this->mExtraData );
-               }
-
-               return $result;
-       }
-
-       /**
-        * @return string
-        */
-       public function __toString() {
-               return "{$this->getCodeString()}: {$this->getMessage()}";
-       }
-}
-
 /**
  * Exception used to abort API execution with an error
  *
index 47f3bc5..e251fe6 100644 (file)
@@ -134,7 +134,7 @@ class ApiUserrights extends ApiBase {
 
                $this->requireOnlyOneParameter( $params, 'user', 'userid' );
 
-               $user = isset( $params['user'] ) ? $params['user'] : '#' . $params['userid'];
+               $user = $params['user'] ?? '#' . $params['userid'];
 
                $form = $this->getUserRightsPage();
                $form->setContext( $this->getContext() );
diff --git a/includes/api/IApiMessage.php b/includes/api/IApiMessage.php
new file mode 100644 (file)
index 0000000..fee62c5
--- /dev/null
@@ -0,0 +1,69 @@
+<?php
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+/**
+ * Interface for messages with machine-readable data for use by the API
+ *
+ * The idea is that it's a Message that has some extra data for the API to use when interpreting it
+ * as an error (or, in the future, as a warning). Internals of MediaWiki often use messages (or
+ * message keys, or Status objects containing messages) to pass information about errors to the user
+ * (see e.g. Title::getUserPermissionsErrors()) and the API has to make do with that.
+ *
+ * @since 1.25
+ * @note This interface exists to work around PHP's inheritance, so ApiMessage
+ *  can extend Message and ApiRawMessage can extend RawMessage while still
+ *  allowing an instanceof check for a Message object including this
+ *  functionality. If for some reason you feel the need to implement this
+ *  interface on some other class, that class must also implement all the
+ *  public methods the Message class provides (not just those from
+ *  MessageSpecifier, which as written is fairly useless).
+ * @ingroup API
+ */
+interface IApiMessage extends MessageSpecifier {
+       /**
+        * Returns a machine-readable code for use by the API
+        *
+        * If no code was specifically set, the message key is used as the code
+        * after removing "apiwarn-" or "apierror-" prefixes and applying
+        * backwards-compatibility mappings.
+        *
+        * @return string
+        */
+       public function getApiCode();
+
+       /**
+        * Returns additional machine-readable data about the error condition
+        * @return array
+        */
+       public function getApiData();
+
+       /**
+        * Sets the machine-readable code for use by the API
+        * @param string|null $code If null, uses the default (see self::getApiCode())
+        * @param array|null $data If non-null, passed to self::setApiData()
+        */
+       public function setApiCode( $code, array $data = null );
+
+       /**
+        * Sets additional machine-readable data about the error condition
+        * @param array $data
+        */
+       public function setApiData( array $data );
+}
index f7c6471..fc6eddf 100644 (file)
@@ -76,7 +76,7 @@ trait SearchApi {
                        if ( $alternatives[0] === null ) {
                                $alternatives[0] = self::$BACKEND_NULL_PARAM;
                        }
-                       $this->allowedParams['backend'] = [
+                       $params['backend'] = [
                                ApiBase::PARAM_DFLT => $searchConfig->getSearchType(),
                                ApiBase::PARAM_TYPE => $alternatives,
                        ];
@@ -140,8 +140,7 @@ trait SearchApi {
         * will be set:
         *  - backend: which search backend to use
         *  - limit: mandatory
-        *  - offset: optional, if set limit will be incremented by
-        *    one ( to support the continue parameter )
+        *  - offset: optional
         *  - namespace: mandatory
         *  - search engine profiles defined by SearchApi::getSearchProfileParams()
         * @param string[]|null $params API request params (must be sanitized by
@@ -150,22 +149,14 @@ trait SearchApi {
         */
        public function buildSearchEngine( array $params = null ) {
                if ( $params != null ) {
-                       $type = isset( $params['backend'] ) ? $params['backend'] : null;
+                       $type = $params['backend'] ?? null;
                        if ( $type === self::$BACKEND_NULL_PARAM ) {
                                $type = null;
                        }
                        $searchEngine = MediaWikiServices::getInstance()->getSearchEngineFactory()->create( $type );
                        $limit = $params['limit'];
                        $searchEngine->setNamespaces( $params['namespace'] );
-                       $offset = null;
-                       if ( isset( $params['offset'] ) ) {
-                               // If the API supports offset then it probably
-                               // wants to fetch limit+1 so it can check if
-                               // more results are available to properly set
-                               // the continue param
-                               $offset = $params['offset'];
-                               $limit += 1;
-                       }
+                       $offset = isset( $params['offset'] ) ? $params['offset'] : null;
                        $searchEngine->setLimitOffset( $limit, $offset );
 
                        // Initialize requested search profiles.
diff --git a/includes/api/UsageException.php b/includes/api/UsageException.php
new file mode 100644 (file)
index 0000000..426ce91
--- /dev/null
@@ -0,0 +1,90 @@
+<?php
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+/**
+ * This exception will be thrown when dieUsage is called to stop module execution.
+ *
+ * @ingroup API
+ * @deprecated since 1.29, use ApiUsageException instead
+ */
+class UsageException extends MWException {
+
+       private $mCodestr;
+
+       /**
+        * @var null|array
+        */
+       private $mExtraData;
+
+       /**
+        * @param string $message
+        * @param string $codestr
+        * @param int $code
+        * @param array|null $extradata
+        */
+       public function __construct( $message, $codestr, $code = 0, $extradata = null ) {
+               parent::__construct( $message, $code );
+               $this->mCodestr = $codestr;
+               $this->mExtraData = $extradata;
+
+               if ( !$this instanceof ApiUsageException ) {
+                       wfDeprecated( __METHOD__, '1.29' );
+               }
+
+               // This should never happen, so throw an exception about it that will
+               // hopefully get logged with a backtrace (T138585)
+               if ( !is_string( $codestr ) || $codestr === '' ) {
+                       throw new InvalidArgumentException( 'Invalid $codestr, was ' .
+                               ( $codestr === '' ? 'empty string' : gettype( $codestr ) )
+                       );
+               }
+       }
+
+       /**
+        * @return string
+        */
+       public function getCodeString() {
+               wfDeprecated( __METHOD__, '1.29' );
+               return $this->mCodestr;
+       }
+
+       /**
+        * @return array
+        */
+       public function getMessageArray() {
+               wfDeprecated( __METHOD__, '1.29' );
+               $result = [
+                       'code' => $this->mCodestr,
+                       'info' => $this->getMessage()
+               ];
+               if ( is_array( $this->mExtraData ) ) {
+                       $result = array_merge( $result, $this->mExtraData );
+               }
+
+               return $result;
+       }
+
+       /**
+        * @return string
+        */
+       public function __toString() {
+               return "{$this->getCodeString()}: {$this->getMessage()}";
+       }
+}
index 574c94b..8c69b9d 100644 (file)
@@ -14,7 +14,7 @@
                        "Azouz.anis"
                ]
        },
-       "apihelp-main-extended-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:Special:MyLanguage/API:Main_page|Documentation]]\n* [[mw:Special:MyLanguage/API:FAQ|FAQ]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Mailing list]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce API Announcements]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Bugs & requests]\n</div>\n<strong>Status:</strong> يجب أن تعمل جميع الميزات المعروضة في هذه الصفحة، إلا أن واجهة برمجة التطبيقات لا تزال قيد التطوير النشط، وقد تتغير في أي وقت. الاشتراك في\n<strong>Erroneous requests:</strong>عند إرسال طلبات خاطئة إلى api, فالـHTTP سيتم إرسال رأس مع المفتاح \"MediaWiki-API-Error\" ومن ثم سيتم تعيين قيمة رأس ورمز الخطأ المرسل مرة أخرى إلى نفس القيمة. لمزيد من المعلومات، راجع  [[mw:Special:MyLanguage/API:Errors_and_warnings|API: Errors and warnings]].\n<p class=\"mw-apisandbox-link\"><strong>Testing:</strong> لسهولة إختبار طلبات API، انظر [[Special:ApiSandbox]].</p>",
+       "apihelp-main-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> API ميدياويكي هي واجهة ناضجة ومستقرة يتم دعمها وتحسينها بشكل نشط، في حين أننا نحاول تجنب ذلك، قد نحتاج في بعض الأحيان إلى إجراء تغييرات في التكسير، اشترك في [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ القائمة البريدية لإعلان API ميدياويكي] لإشعارات التحديثات.\n\n<strong>الطلبات الخاطئة:</strong>عندما يتم إرسال طلبات خاطئة إلى API، سيتم إرسال رأس HTTP مع مفتاح \"خطأ-API-ميدياويكي\"، وبعد ذلك سترجع قيمة الرأس ورمز الخطأ المرتجع إلى يتم تعيينه على نفس القيمة، لمزيد من المعلومات; راجع [[mw:Special:MyLanguage/API:Errors_and_warnings|API: Errors and warnings]].\n\n<p class=\"mw-apisandbox-link\"><strong>الاختبار:</strong>لسهولة اختبار طلبات API ; انظر [[Special:ApiSandbox]].</p>",
        "apihelp-main-param-action": "أي فعل للعمل.",
        "apihelp-main-param-format": "صيغة الخرج.",
        "apihelp-main-param-maxlag": "يمكن استخدام التأخر الأقصى عند تثبيت ميدياويكي على قاعدة بيانات مكررة، لحفظ الإجراءات التي تتسبب في أي تأخير أكثر في النسخ المتماثل للموقع; يمكن أن يجعل هذا الوسيط العميل ينتظر حتى يكون تأخر النسخ المتماثل أقل من القيمة المحددة، في حالة التأخير المفرط، يتم إرجاع رمز الخطأ <samp>maxlag</samp> برسالة مثل <samp>Waiting for $host: $lag seconds lagged</samp>،<br />انظر [[mw:Special:MyLanguage/Manual:Maxlag_parameter|دليل: الوسيط maxlag]] لمزيد من المعلومات.",
@@ -28,6 +28,7 @@
        "apihelp-main-param-responselanginfo": "تشمل اللغات المستخدمة لأجل <var>uselang</var> and <var>errorlang</var> في النتيجة.",
        "apihelp-main-param-origin": "عند الوصول إلى API باستخدام طلب AJAX عبر النطاقات (CORS)، اضبطها على النطاق الأصلي، يجب تضمين هذا في أي طلب ما قبل الطيران، وبالتالي يجب أن يكون جزءا من طلب URI (وليس جسم POST). \n\nبالنسبة للطلبات المصادقة، يجب أن يتطابق هذا مع أحد المصادر الموجودة في الرأس<code>Origin</code> بالضبط; لذا يجب تعيينه على شيء مثل<kbd>https://en.wikipedia.org</kbd> أو <kbd>https://meta.wikimedia.org</kbd>، إذا لم يتطابق هذا الوسيط مع الرأس<code>Origin</code>، فسيتم إرجاع استجابة 403، إذا كان هذا الوسيط مطابقا للرأس <code>Origin</code>، ستتم إضافة الأصل إلى القائمة البيضاء، سيتم تعيين الرؤوس <code>Access-Control-Allow-Origin</code> و<code>Access-Control-Allow-Credentials</code>.\n\nبالنسبة للطلبات غير المصادقة، حدد القيمة <kbd>*</kbd>، سيؤدي ذلك إلى تعيين الرأس <code>Access-Control-Allow-Origin</code>، ولكن <code>Access-Control-Allow-Credentials</code> سيكون <code>false</code> وسيتم تقييد كل البيانات الخاصة بالمستخدم.",
        "apihelp-main-param-uselang": "اللغة المستخدمة لترجمة الرسائل. <kbd>[[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo]]</kbd> بـ<kbd>siprop=languages</kbd> يقوم بإرجاع قائمة أكواد اللغة، أو تحديد <kbd>user</kbd> لاستخدام تفضيل اللغة للمستخدم الحالي، أو تحديد <kbd>content</kbd> لاستخدام لغة محتوى الويكي هذا.",
+       "apihelp-main-param-errorformat": "تنسيق لاستخدامه في التحذير وإخراج نص الخطأ. \n; نص عادي: إزالة نص الويكي ذي وسوم HTML واستبدال الكيانات.\n; نص الويكي: نص ويكي غير مقتبس.\n; html: HTML.\n; خام: مفتاح ووسائط الرسالة.\n; لا شيء: لا يوجد إخراج نص، فقط رموز الخطأ.\n; bc: التنسيق المستخدم قبل ميدياويكي 1.29، يتم تجاهل <var>errorlang</var> و<var>errorsuselocal</var>.",
        "apihelp-main-param-errorlang": "لغة لاستخدامها في التحذيرات والأخطاء. <kbd>[[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo]]</kbd> بـ<kbd>siprop=languages</kbd> يقوم بإرجاع قائمة أكواد اللغة، أو تحديد <kbd>content</kbd> لاستخدام لغة محتوى الويكي هذا، أو تحديد <kbd>uselang</kbd> لاستخدام نفس القيمة كوسيط <var>uselang</var>.",
        "apihelp-main-param-errorsuselocal": "إذا ما أعطيت، النصوص الخطأ ستستخدم الرسائل المخصصة محليا من نطاق {{ns:MediaWiki}}.",
        "apihelp-block-summary": "منع مستخدم.",
        "apihelp-expandtemplates-paramvalue-prop-properties": "خصائص الصفحة التي تحددها الكلمات السحرية الموسعة في نص الويكي.",
        "apihelp-expandtemplates-paramvalue-prop-volatile": "إذا كان الإخراج سريع التأثر، ينبغي عدم استخدامه في أي مكان آخر داخل الصفحة.",
        "apihelp-expandtemplates-paramvalue-prop-ttl": "الحد الأقصى للوقت الذي يجب بعده إبطال ذاكرة التخزين المؤقت للنتيجة.",
+       "apihelp-expandtemplates-paramvalue-prop-modules": "تتم إضافة أية وحدات ResourceLoader التي طلبت تعيين دالات المحلل اللغوي إلى الإخراج، يجب طلب <kbd>jsconfigvars</kbd> أو <kbd>encodedjsconfigvars</kbd> بشكل مشترك مع <kbd>modules</kbd>.",
        "apihelp-expandtemplates-paramvalue-prop-jsconfigvars": "يعطي متغيرات تكوين جافا سكريبت الخاصة بهذه الصفحة.",
        "apihelp-expandtemplates-paramvalue-prop-encodedjsconfigvars": "يعطي متغيرات تكوين جافا سكريبت الخاصة بهذه الصفحة كسلسلة JSON.",
        "apihelp-expandtemplates-paramvalue-prop-parsetree": "شجرة تحليل XML للمدخلات.",
        "apihelp-imagerotate-example-simple": "تدوير <kbd>File:Example.png</kbd> بمقدار <kbd>90</kbd> درجة.",
        "apihelp-imagerotate-example-generator": "تدوير جميع الصور في <kbd>Category:Flip</kbd> بمقدار <kbd>180</kbd> درجة.",
        "apihelp-import-summary": "استيراد صفحة من موقع ويكي آخر أو من ملف XML.",
+       "apihelp-import-extended-description": "لاحظ أنه يجب أن يتم إجراء POST HTTP كرفع ملف (أي باستخدام بيانات متعددة الأجزاء/النماذج) عند إرسال ملف للوسيط <var>xml</var>.",
        "apihelp-import-param-summary": "ملخص إدخال سجل الاستيراد.",
        "apihelp-import-param-xml": "ملف XML مرفوع.",
        "apihelp-import-param-interwikiprefix": "بالنسبة للواردات المرفوعة: بادئة إنترويكي لتطبيقها على أسماء مستخدمين غير معروفة (والمستخدمين المعروفين إذا تم تعيين <var>$1assignknownusers</var>).",
        "apihelp-logout-example-logout": "تسجيل خروج المستخدم الحالي.",
        "apihelp-managetags-summary": "أداء المهام الإدارية المتعلقة بتغيير الوسوم.",
        "apihelp-managetags-param-operation": "أي الإجراءات ستنفذ:\n؛ إنشاء: إنشاء وسم التغيير جديدة للاستخدام اليدوي.\n؛ حذف: إزالة وسم التغيير من قاعدة البيانات، بما في ذلك إزالة الوسم من كافة المراجعات، وإدخالات التغيير الأخيرة، وإدخالات السجل المستخدم.\n؛ تنشيط: تنشيط وسم التغيير، مما يسمح للمستخدمين بتطبيقه يدويا.\n; إلغاء: إلغاء تنشيط وسم التغيير، ومنع المستخدمين من تطبيقه يدويا.",
+       "apihelp-managetags-param-tag": "وسم لإنشاء أو حذف أو تنشيط أو إلغاء تنشيط. لإنشاء وسم; يجب ألا يكون الوسم موجودا، لحذف وسم; يجب أن يكون الوسم موجودا، لتنشيط وسم; يجب أن يكون الوسم موجودا وغير مستخدم بواسطة إضافة، لإلغاء تنشيط وسم; يجب أن يكون الوسم نشطا في الوقت الحالي ويتم تحديدها يدويا.",
        "apihelp-managetags-param-reason": "سبب اختياري لإنشاء، وحذف، وتفعيل أو تعطيل الوسم.",
        "apihelp-managetags-param-ignorewarnings": "إذا كان سيتم تجاهل أي تحذيرات تصدر خلال العملية.",
+       "apihelp-managetags-param-tags": "تغيير الوسوم لتطبيق الإدخال في سجل الحذف إدارة الوسوم.",
        "apihelp-managetags-example-create": "إنشاء وسم مسمى <kbd>spam</kbd> بسبب <kbd>For use in edit patrolling</kbd>",
        "apihelp-managetags-example-delete": "حذف <kbd>vandlaism</kbd> وسم بسبب <kbd>Misspelt</kbd>",
        "apihelp-managetags-example-activate": "تنشيط الوسم المسمى <kbd>spam</kbd> بسبب <kbd>For use in edit patrolling</kbd>",
        "apihelp-move-param-noredirect": "لا تنشئ تحويلة.",
        "apihelp-move-param-watch": "إضافة الصفحة والتحويلة إلى قائمة مراقبة المستخدم الحالي.",
        "apihelp-move-param-unwatch": "إزالة الصفحة والتحويلة إلى قائمة مراقبة المستخدم الحالي.",
+       "apihelp-move-param-watchlist": "إضافة أو إزالة الصفحة من قائمة مراقبة المستخدم الحالي أو استخدام التفضيلات أو عدم تغيير المراقبة دون قيد أو شرط.",
        "apihelp-move-param-ignorewarnings": "تجاهل أي تحذيرات.",
+       "apihelp-move-param-tags": "غير الوسوم لتطبيقها على الإدخال في سجل النقل وعلى النسخة الفارغة في الصفحة الوجهة.",
        "apihelp-move-example-move": "انقل <kbd>Badtitle</kbd> إلى <kbd>Goodtitle</kbd> دون ترك تحويلة.",
        "apihelp-opensearch-summary": "بحث الويكي باستخدام بروتوكول أوبن سيرش OpenSearch.",
        "apihelp-opensearch-param-search": "سطر البحث",
        "apihelp-opensearch-param-limit": "الحد الأقصى للنتائج المُرجعة",
-       "apihelp-opensearch-param-namespace": "النطاقات للبحث.",
+       "apihelp-opensearch-param-namespace": "النطاقات للبحث، يتم التجاهل إذا بدأ <var>$1search</var> ببادئة نطاق صالحة.",
        "apihelp-opensearch-param-suggest": "لا تفعل شيئا إذا كان <var>[[mw:Special:MyLanguage/Manual:$wgEnableOpenSearchSuggest|$wgEnableOpenSearchSuggest]]</var> خاطئا.",
+       "apihelp-opensearch-param-redirects": "كيفية التعامل مع التحويلات:\n;إرجاع: إرجاع التحويلة نفسها.\n;حل: إرجاع الصفحة الهدف، قد ترجع نتائج أقل من $1limit.\nلأسباب تاريخية; يكون الإعداد الافتراضي هو \"إرجاع\" لـ$1format=json و\"حل\" للتنسيقات الأخرى.",
        "apihelp-opensearch-param-format": "شكل الإخراج.",
        "apihelp-opensearch-param-warningsaserror": "إذا تم رفع التحذيرات ب<kbd>format=json</kbd>, أعد أخطاء API بدلا من تجاهلها.",
        "apihelp-opensearch-example-te": "العثور على صفحات تبدأ ب<kbd>Te</kbd>.",
+       "apihelp-options-summary": "تغيير تفضيلات المستخدم الحالي.",
+       "apihelp-options-extended-description": "لا يمكن تعيين سوى الخيارات المسجلة في النواة أو في أحد الملحقات المثبتة، أو الخيارات مع المفاتيح المسبوقة بـ<code>userjs-</code> (التي يُراد استخدامها من قبل سكريبتات المستخدم).",
        "apihelp-options-param-reset": "إعادة تعيين التفضيلات إلى إعدادات الموقع الإفتراضية.",
        "apihelp-options-param-resetkinds": "قائمة أنواع الخيارات لإعادة ضبطها عندما يتم تعيين خيار <var>$1reset</var>.",
+       "apihelp-options-param-change": "قائمة بالتغييرات، الاسم المنسق=value (مثل skin=vector)، إذا لم يتم تحديد أية قيمة (ولا حتى علامة المساواة)، على سبيل المثال، optionname|otheroption|..., ستتم إعادة تعيين الخيار إلى قيمته الافتراضية، إذا كانت أية قيمة تم تمريرها تحتوي على حرف الأنبوب(<kbd>|</kbd>)، فاستخدم [[Special:ApiHelp/main#main/datatypes| فاصل بديل متعدد القيم]] للعملية الصحيحة.",
        "apihelp-options-param-optionname": "اسم الخيار الذي ينبغي ضبطه إلى القيمة التي قدمها <var>$1optionvalue</var>.",
        "apihelp-options-param-optionvalue": "قيمة للخيار المحدد من قبل <var>$1optionname</var>.",
        "apihelp-options-example-reset": "إعادة تعيين كل التفضيلات.",
        "apihelp-options-example-change": "غير تفضيلات <kbd>skin</kbd> و<kbd>hideminor</kbd>.",
        "apihelp-options-example-complex": "إعادة تعيين جميع تفضيلات، ثم تعيين <kbd>skin</kbd> و<kbd>nickname</kbd>.",
        "apihelp-paraminfo-summary": "الحصول على معلومات حول وحدات API.",
+       "apihelp-paraminfo-param-modules": "قائمة بأسماء الوحدات (قيم الوسائط <var>action</var> أو <var>format</var> أو <kbd>main</kbd>)، يمكن تحديد الوحدات الفرعية التي تحتوي على <kbd>+</kbd>، أو كل الوحدات الفرعية التي تحتوي على <kbd>+*</kbd>، أو جميع الوحدات الفرعية بشكل متكرر بـ<kbd>+**</kbd>.",
        "apihelp-paraminfo-param-helpformat": "شكل سلاسل المساعدة.",
+       "apihelp-paraminfo-param-querymodules": "قائمة بأسماء وحدات الاستعلام (قيمة وسيط <var>prop</var> أو <var>meta</var> أو <var>list</var>)، استخدم <kbd>$1modules=query+foo</kbd> بدلا من <kbd>$1querymodules=foo</kbd>.",
        "apihelp-paraminfo-param-mainmodule": "الحصول على معلومات عن وحدة (المستوى الأعلى) الرئيسية أيضا. استخدم <kbd>$1modules=main</kbd> بدلا من ذلك.",
+       "apihelp-paraminfo-param-pagesetmodule": "الحصول على معلومات حول وحدة مجموعة الصفحة (يتم توفير titles= والأصدقاء) كذلك.",
        "apihelp-paraminfo-param-formatmodules": "قائمة بأسماء أشكال الوحدات (قيم الوسيط <var>format</var>). استخدم <var>$1modules</var> بدلا من ذلك.",
        "apihelp-paraminfo-example-1": "عرض معلومات عن <kbd>[[Special:ApiHelp/parse|action=parse]]</kbd> و<kbd>[[Special:ApiHelp/jsonfm|format=jsonfm]]</kbd> و<kbd>[[Special:ApiHelp/query+allpages|action=query&list=allpages]]</kbd> و<kbd>[[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo]]</kbd>.",
        "apihelp-paraminfo-example-2": "أظهر المعلومات لجميع الوحدات الفرعية ل<kbd>[[Special:ApiHelp/query|action=query]]</kbd>.",
+       "apihelp-parse-summary": "يوزع المحتوى ويرجع مخرجات المحلل.",
+       "apihelp-parse-extended-description": "راجع مختلف وحدات prop لـ<kbd>[[Special:ApiHelp/query|action=query]]</kbd>  للحصول على معلومات من الإصدار الحالي للصفحة.\n\nهناك عدة طرق لتحديد النص المراد تحليله: \n# حدد صفحة أو مراجعة، باستخدام <var>$1page</var> أو <var>$1pageid</var> أو <var>$1oldid</var>.\n# حدد المحتوى بشكل صريح، باستخدام <var>$1text</var> و<var>$1title</var> و<var>$1revid</var> و<var>$1contentmodel</var>.\n# تحديد ملخص للتحليل فقط، يجب إعطاء قيمة فارغة لـ<var>$1prop</var>.",
        "apihelp-parse-param-title": "عنوان الصفحة التي ينتمي النص إليها.إذا تم حذفها، <var>$1contentmodel</var> يجب أن تكون محددة، و[[API]] سيتم استخدامه كعنوان.",
        "apihelp-parse-param-text": "نص للتحليل. استخدم <var>$1title</var> أو <var>$1contentmodel</var> للتحكم في نموذج المحتوى.",
+       "apihelp-parse-param-revid": "معرف المراجعة، لـ<code><nowiki>{{REVISIONID}}</nowiki></code> ومتغيرات مشابهة.",
        "apihelp-parse-param-summary": "ملخص للتحليل.",
        "apihelp-parse-param-page": "تحليل محتوى هذه الصفحة. لا يمكن أن تُستخدَم بجانب <var>$1text</var> and <var>$1title</var>.",
        "apihelp-parse-param-pageid": "حلل محتوى هذه الصفحة. تجاوز <var>$1page</var>.",
        "apihelp-parse-param-redirects": "لو <var>$1page</var> أو <var>$1pageid</var> is تم تعيينها للتحويل، حلها.",
        "apihelp-parse-param-oldid": "تحليل مضمون هذا التعديل. تجاوز <var>$1page</var> و<var>$1pageid</var>.",
        "apihelp-parse-param-prop": "أي قطعة من المعلومات تريد الحصول عليها:",
+       "apihelp-parse-paramvalue-prop-text": "يعطي النص المعالج لنص الويكي.",
        "apihelp-parse-paramvalue-prop-langlinks": "يعطي وصلات اللغات في تحليل نصوص الويكي.",
        "apihelp-parse-paramvalue-prop-categories": "يعطي التصنيفات في تحليل نصوص الويكي.",
        "apihelp-parse-paramvalue-prop-categorieshtml": "يعطي إصدار HTML للتصنيفات.",
        "apihelp-parse-paramvalue-prop-images": "يعطي الصور في تحليل نصوص الويكي.",
        "apihelp-parse-paramvalue-prop-externallinks": "يعطي الوصلات الخارجية في تحليل نصوص الويكي.",
        "apihelp-parse-paramvalue-prop-sections": "يعطي الأقسام في تحليل نصوص الويكي.",
+       "apihelp-parse-paramvalue-prop-revid": "يضيف معرِف المراجعة للصفحة التي تم تحليلها.",
        "apihelp-parse-paramvalue-prop-displaytitle": "يضيف العنوان في تحليل نصوص الويكي.",
        "apihelp-parse-paramvalue-prop-headitems": "يعطي عناصر لوضعها في <code>&lt;head&gt;</code> الصفحة.",
        "apihelp-parse-paramvalue-prop-headhtml": "يعطي تحليل <code>&lt;head&gt;</code> الصفحة.",
+       "apihelp-parse-paramvalue-prop-modules": "يعطي وحدات ResourceLoader المستخدمة في الصفحة، للتحميل; استخدم <code>mw.loader.using()</code>، يجب طلب <kbd>jsconfigvars</kbd> أو <kbd>encodedjsconfigvars</kbd> بشكل مشترك مع <kbd>modules</kbd>.",
        "apihelp-parse-paramvalue-prop-jsconfigvars": "يعطي متغيرات تكوين جافا سكريبت الخاصة بهذه الصفحة. للتطبيق; استخدم <code>mw.config.set()</code>.",
        "apihelp-parse-paramvalue-prop-encodedjsconfigvars": "يعطي متغيرات تكوين جافا سكريبت الخاصة بهذه الصفحة كسلسلة JSON.",
        "apihelp-parse-paramvalue-prop-indicators": "يعطي HTML مؤشرات حالة الصفحة المستخدمة في الصفحة.",
        "apihelp-parse-paramvalue-prop-limitreportdata": "يعطي تقرير الحد بطريقة منظمة. لا يعطي أية بيانات، عندما يتم تعيين <var>$1disablelimitreport</var>.",
        "apihelp-parse-paramvalue-prop-limitreporthtml": "يعطي إصدار HTML لتقرير الحد. لا يعطي أية بيانات، عندما يتم تعيين<var>$1disablelimitreport</var>.",
        "apihelp-parse-paramvalue-prop-parsetree": "شجرة تحليل XML لمحتويات المراجعة (يتطلب نموذج محتوى <code>$1</code>)",
+       "apihelp-parse-paramvalue-prop-parsewarnings": "يعطي التحذيرات التي حدثت أثناء تحليل المحتوى.",
+       "apihelp-parse-param-wrapoutputclass": "فئة CSS لاستخدام التفاف إخراج المحلل.",
        "apihelp-parse-param-pst": "قم بتحويل قبل الحفظ على المدخلات قبل تحليل ذلك. صالح فقط عند استخدامه مع النص.",
+       "apihelp-parse-param-onlypst": "قم بإجراء تحويل ما قبل الحفظ (PST) على الإدخال، ولكن لا تقم بتحليله; لعرض نفس نص الويكي، بعد تطبيق PST، صالح فقط عند استخدامه مع <var>$1text</var>.",
        "apihelp-parse-param-effectivelanglinks": "يشمل وصلات لغة المقدمة بواسطة ملحقات (للاستخدام مع <kbd>$1prop=langlinks</kbd>).",
+       "apihelp-parse-param-section": "فقط تحليل محتوى رقم هذا القسم. \nعندما <kbd>new</kbd>، تحليل <var>$1text</var> و<var>$1sectiontitle</var> كما لو كانت إضافة قسم جديد إلى الصفحة.",
+       "apihelp-parse-param-sectiontitle": "عنوان قسم جديد عندما يكون <var>section</var> <kbd>new</kbd>.\n\nعلى عكس تحرير الصفحة، لا يرجع هذا إلى <var>summary</var> عند حذفه أو تفريغه.",
        "apihelp-parse-param-disablelimitreport": "تجاهل تقرير الحد (\"NewPP limit report\") من مخرجات المحلل.",
        "apihelp-parse-param-disablepp": "استخدم <var>$1disablelimitreport</var> بدلا من ذلك.",
        "apihelp-parse-param-disableeditsection": "تجاهل روابط تحرير الأقسام من مخرجات المحلل.",
        "apihelp-parse-param-disabletidy": "لا تشغل تنظيف HTML (على سبيل المثال مرتبة) على مخرجات المحلل.",
+       "apihelp-parse-param-disablestylededuplication": "لا تكرر أوراق الأنماط المضمنة في إخراج المحلل.",
        "apihelp-parse-param-generatexml": "توليد شجرة تحليل XML (يتطلب نموذج المحتوى <code>$1</code>; حل محلها <kbd>$2prop=parsetree</kbd>).",
        "apihelp-parse-param-preview": "تحليل في وضع المعاينة.",
        "apihelp-parse-param-sectionpreview": "تحليل في وضع معاينة القسم (يمكن وضع المعاينة أيضا).",
        "apihelp-parse-param-disabletoc": "تجاهل جدول المحتويات في المخرجات.",
+       "apihelp-parse-param-useskin": "تطبيق المظهر المحدد لإخراج المحلل اللغوي، قد يؤثر على الخصائص التالية: <kbd>langlinks</kbd> ،<kbd>headitems</kbd> ،<kbd>modules</kbd> ،<kbd>jsconfigvars</kbd> ،<kbd>indicators</kbd>.",
        "apihelp-parse-param-contentformat": "نموذج المحتوى المسلسل يُستخدَم للنص المدخل. صالح فقط عند استخدامه مع $1text.",
+       "apihelp-parse-param-contentmodel": "نموذج المحتوى لنص الإدخال، إذا تم تجاهله، فيجب تحديد $1title، وسيكون الإعداد الافتراضي هو نموذج العنوان المحدد، صالح فقط عند استخدامه مع $1text.",
        "apihelp-parse-example-page": "تحليل صفحة.",
        "apihelp-parse-example-text": "تحليل نصوص ويكي",
        "apihelp-parse-example-texttitle": "تحليل نصوص ويكي، تحديد عنوان الصفحة.",
        "apihelp-protect-summary": "غير مستوى الحماية لصفحة.",
        "apihelp-protect-param-title": "عنوان الصفحة ل (إزالة) الحماية. لا يمكن أن تُستخدَم بجانب $1pageid.",
        "apihelp-protect-param-pageid": "معرف الصفحة ل (إزالة) الحماية. لا يمكن أن تُستخدَم بجانب $1pageid.",
+       "apihelp-protect-param-protections": "قائمة بمستويات الحماية، منسقة <kbd>action=level</kbd> (على سبيل المثال <kbd>edit=sysop</kbd>)، يعني مستوى <kbd>all</kbd> أن أي شخص مسموح له باتخاذ الإجراء: أي أنه لا توجد قيود.\n\n<strong>ملاحظة:</strong> أية إجراءات غير مدرجة ستتم إزالة قيودها.",
+       "apihelp-protect-param-expiry": "انتهاء الطوابع الزمنية، إذا تم تعيين طابع زمني واحد فقط، فسيتم استخدامه لكل أشكال الحماية، استخدم <kbd>infinite</kbd> أو <kbd>indefinite</kbd> أو <kbd>infinity</kbd> أو <kbd>never</kbd> للحماية التي لا تنتهي أبدا.",
        "apihelp-protect-param-reason": "سبب (إزالة) الحماية.",
        "apihelp-protect-param-tags": "تغيير وسوم لتطبيق الإدخال في سجل الحماية.",
+       "apihelp-protect-param-cascade": "تمكين الحماية المتتالية (أي حماية القوالب المضمنة والصور المستخدمة في هذه الصفحة)، يتم التجاهل إذا كان أي من مستويات الحماية المعطاة لا يدعم التتالي.",
        "apihelp-protect-param-watch": "إذا تم الضبط، أضف الصفحة (غير) المحمية لقائمة مراقبة المستخدم الحالي.",
+       "apihelp-protect-param-watchlist": "بدون إضافة أو إزالة الصفحة من قائمة مراقبة المستخدم الحالي أو استخدام التفضيلات أو عدم تغيير المراقبة.",
        "apihelp-protect-example-protect": "حماية صفحة.",
        "apihelp-protect-example-unprotect": "إلغاء حماية الصفحة من خلال وضع قيود ل<kbd>all</kbd> (أي يُسمَح أي شخص باتخاذ الإجراءات).",
        "apihelp-protect-example-unprotect2": "إلغاء حماية الصفحة عن طريق عدم وضع أية قيود.",
        "apihelp-query-param-prop": "أي الخصائص تريد الحصول على صفحات استعلام عنها.",
        "apihelp-query-param-list": "أي القوائم تريد الحصول عليها.",
        "apihelp-query-param-meta": "أي البيانات الوصفية تريد الحصول عليها.",
+       "apihelp-query-param-indexpageids": "تضمين قسم إضافي لمعرفات الصفحات يسرد جميع معرفات الصفحات التي تم إرجاعها.",
        "apihelp-query-param-export": "تصدير المراجعات الحالية لجميع الصفحات المعينة أو المولدة.",
        "apihelp-query-param-exportnowrap": "إعادة تصدير XML دون التفاف عليه في نتيجة XML (نفس شكل [[Special:Export|خاص:تصدير]]). يمكن استخدامها فقط مع $1export.",
+       "apihelp-query-param-iwurl": "ما إذا كنت تريد الحصول على المسار الكامل إذا كان العنوان رابط إنترويكي.",
        "apihelp-query-param-rawcontinue": "إرجاع <samp>query-continue</samp> بيانات خام للاستمرار.",
        "apihelp-query-example-revisions": "جلب [[Special:ApiHelp/query+siteinfo|معلومات الموقع]] و[[Special:ApiHelp/query+revisions|مراجعات]] <kbd>Main Page</kbd>.",
        "apihelp-query-example-allpages": "جلب مراجعات الصفحات التي تبدأ ب<kbd>API/</kbd>.",
        "apihelp-query+allcategories-param-to": "التصنيف الذي يقف التعداد عنده.",
        "apihelp-query+allcategories-param-prefix": "ابحث عن جميع التصنيفات التي تبدأ أسماؤها بهذه القيمة.",
        "apihelp-query+allcategories-param-dir": "اتجاه الفرز.",
-       "apihelp-query+allcategories-param-limit": "كم عدد الفئات في الإرجاع.",
+       "apihelp-query+allcategories-param-min": "فقط إرجاع التصنيفات بهذا العدد الكبير من الأعضاء على الأقل.",
+       "apihelp-query+allcategories-param-max": "فقط إرجاع التصنيفات بهذا العدد الكبير من الأعضاء على الأقل.",
+       "apihelp-query+allcategories-param-limit": "كم عدد التصنيات للعودة.",
        "apihelp-query+allcategories-param-prop": "أي الخصائص تريد الحصول عليها:",
        "apihelp-query+allcategories-paramvalue-prop-size": "أضف عدد الصفحات في هذا التصنيف.",
+       "apihelp-query+allcategories-paramvalue-prop-hidden": "يوسم التصنيفات المخفية بـ<code>_&#95;HIDDENCAT_&#95;</code>.",
+       "apihelp-query+allcategories-example-size": "إدراج التصنيفات مع معلومات حول عدد الصفحات في كل منها.",
        "apihelp-query+allcategories-example-generator": "استرداد المعلومات حول صفحة التصنيف نفسها للتصنيفات التي تبدأ ب<kbd>List</kbd>.",
        "apihelp-query+alldeletedrevisions-summary": "قائمة جميع المراجعات المحذوفة بواسطة المستخدم أو في نطاق.",
        "apihelp-query+alldeletedrevisions-paraminfo-useronly": "يمكن أن تُستخدَم فقط مع <var>$3user</var>.",
        "apihelp-query+alldeletedrevisions-paraminfo-nonuseronly": "لا يمكن أن تُستخدَم مع <var>$3user</var>.",
+       "apihelp-query+alldeletedrevisions-param-start": "الطابع الزمني لبدء العد منه.",
        "apihelp-query+alldeletedrevisions-param-end": "الطابع الزمني الذي يقف التعداد منه.",
        "apihelp-query+alldeletedrevisions-param-from": "بدء الإدراج في القائمة من هذا العنوان.",
        "apihelp-query+alldeletedrevisions-param-to": "وقف الإدراج في القائمة من هذا العنوان.",
        "apihelp-query+alldeletedrevisions-param-prefix": "ابحث عن جميع عناوين الصفحات التي تبدأ أسماؤها بهذه القيمة.",
-       "apihelp-query+alldeletedrevisions-param-tag": "مراجعات القائمة فقط تم وسمها بهذ الوسم.",
-       "apihelp-query+alldeletedrevisions-param-user": "أدرج Ø§Ù\84Ù\85راجعات Ø§Ù\84تÙ\8a Ù\83تبÙ\87ا هذا المستخدم فقط.",
-       "apihelp-query+alldeletedrevisions-param-excludeuser": "Ù\84ا ØªØ¯Ø±Ø¬ Ø§Ù\84Ù\85راجعات Ø§Ù\84تÙ\8a Ù\83تبÙ\87ا هذا المستخدم.",
+       "apihelp-query+alldeletedrevisions-param-tag": "إدراج المراجعات الموسومة بهذ الوسم فقط.",
+       "apihelp-query+alldeletedrevisions-param-user": "إددراج Ø§Ù\84Ù\85راجعات Ø¨Ù\88اسطة هذا المستخدم فقط.",
+       "apihelp-query+alldeletedrevisions-param-excludeuser": "Ù\84ا ØªØ³Ø±Ø¯ Ø§Ù\84Ù\85راجعات Ø¨Ù\88اسطة هذا المستخدم.",
        "apihelp-query+alldeletedrevisions-param-namespace": "أدرج الصفحات  في هذا النطاق فقط.",
+       "apihelp-query+alldeletedrevisions-param-miser-user-namespace": "<strong>ملاحظة:</strong> بسبب [[mw:Special:MyLanguage/Manual:$wgMiserMode|وضع miser]]; استخدام <var>$1user</var> و<var>$1namespace</var> معا قد يؤدي إلى نتائج أقل من <var>$1limit</var> نتائج التي يتم عرضها قبل المتابعة، في الحالات القصوى، قد يتم إرجاع صفر نتائج.",
        "apihelp-query+alldeletedrevisions-param-generatetitles": "عندما يُستخدَم كمولد، ولد عناوين بدلا من معرفات المراجعات.",
+       "apihelp-query+alldeletedrevisions-example-user": "اذكر آخر 50 مشاركة محذوفة بواسطة المستخدم <kbd>Example</kbd.",
+       "apihelp-query+alldeletedrevisions-example-ns-main": "سرد أول 50 مراجعات محذوفة في النطاق الرئيسي.",
        "apihelp-query+allfileusages-summary": "قائمة جميع استخدامات الملفات، بما في ذلك غير الموجودة.",
        "apihelp-query+allfileusages-param-from": "عنوان الملف لبدء التعداد منه.",
        "apihelp-query+allfileusages-param-to": "عنوان الملف لوقف التعداد منه.",
        "apihelp-query+allfileusages-param-prefix": "البحث عن كل عناوين الملفات التي تبدأ بهذه القيمة.",
-       "apihelp-query+allfileusages-param-prop": "أي قطعة من المعلومات تريد تضمينها:",
+       "apihelp-query+allfileusages-param-unique": "عرض عناوين ملفات متميزة فقط، لا يمكن استخدامها مع $1prop=ids، عند استخدامها كمولد،\nيتم إنتاج الصفحات المستهدفة بدلا من صفحات المصدر.",
+       "apihelp-query+allfileusages-param-prop": "أية قطعة من المعلومات لتضمينها:",
        "apihelp-query+allfileusages-paramvalue-prop-ids": "تضيف معرفات استخدام الصفحات (لا يمكن استخدامها مع $1unique).",
        "apihelp-query+allfileusages-paramvalue-prop-title": "تضيف عنوان الملف.",
        "apihelp-query+allfileusages-param-limit": "كم عدد مجموع البنود للعودة.",
+       "apihelp-query+allfileusages-param-dir": "الاتجاه للإدراج فيه.",
+       "apihelp-query+allfileusages-example-B": "سرد عناوين الملفات، بما في ذلك العناوين المفقودة، مع معرفات الصفحات التي تنتمي إليها، بدءا من <kbd>B</kbd.",
+       "apihelp-query+allfileusages-example-unique": "سرد عناوين الملفات الفريدة.",
+       "apihelp-query+allfileusages-example-unique-generator": "الحصول على جميع عناوين الملفات، والتعليم على المفقودة.",
+       "apihelp-query+allfileusages-example-generator": "الحصول على الصفحات التي تحتوي على الملفات.",
        "apihelp-query+allimages-summary": "تعداد كافة الصور بشكل متتالي.",
        "apihelp-query+allimages-param-sort": "خاصية للفرز وفقًا لها.",
+       "apihelp-query+allimages-param-dir": "الاتجاه للإدراج فيه.",
        "apihelp-query+allimages-param-from": "عنوان الصورة لبدء التعداد منه. يمكن استخدامها مع $1sort=name فقط.",
        "apihelp-query+allimages-param-to": "عنوان الصورة لوقف التعداد منه. يمكن استخدامها مع $1sort=name فقط.",
        "apihelp-query+allimages-param-start": "طابع زمني لبدء التعداد منه. يمكن استخدامه مع $1sort فقط.",
        "apihelp-query+allimages-param-end": "طابع زمني لإنهاء التعداد منه. يمكن استخدامه مع $1sort فقط.",
        "apihelp-query+allimages-param-prefix": "البحث عن كل عناوين الصور التي تبدأ بهذه القيمة. يمكن استخدامها مع $1sort فقط.",
+       "apihelp-query+allimages-param-minsize": "الحد من الصور بهذا العدد الكبير من البايتات على الأقل.",
+       "apihelp-query+allimages-param-maxsize": "الحد من الصور بهذه البايتات على الأكثر.",
        "apihelp-query+allimages-param-sha1": "SHA1 تجزئة الصورة. تجاوز $1sha1base36.",
        "apihelp-query+allimages-param-sha1base36": "SHA1 تجزئة الصورة في قاعدة 36 (تُستخدَم في ميدياويكي).",
+       "apihelp-query+allimages-param-user": "فقط إرجاع الملفات التي تم رفعها من قبل هذا المستخدم، يمكن استخدامها فقط مع\n$1sort=timestamp، لا يمكن استخدامها مع $1filterbots.",
        "apihelp-query+allimages-param-filterbots": "كيفية تصفية الملفات التي تم تحميلها بواسطة بوتات. يمكن استخدامها مع $1sort=timestamp فقط. لا يمكن أن تُستخدَم بجانب $1user.",
        "apihelp-query+allimages-param-mime": "عن أي أنواع MIME تبحث، على سبيل المثال <kbd>image/jpeg</kbd>.",
+       "apihelp-query+allimages-param-limit": "كم عدد الصور الإجمالي للعودة.",
        "apihelp-query+allimages-example-B": "أظهر قائمة الملفات التي تبدأ ب<kbd>B</kbd>.",
        "apihelp-query+allimages-example-recent": "أظهر قائمة الملفات التي تم تحميلها مؤخرا، على غرار [[Special:NewFiles|خاص:ملفات جديدة]].",
        "apihelp-query+allimages-example-mimetypes": "أظهر قائمة الملفات من نوع MIME <kbd>image/png</kbd> أو <kbd>image/gif</kbd>",
        "apihelp-query+alllinks-param-from": "عنوان الرابط لبدء التعداد منه.",
        "apihelp-query+alllinks-param-to": "عنوان الرابط لوقف التعداد منه.",
        "apihelp-query+alllinks-param-prefix": "البحث عن كل العناوين المرتبطة التي تبدأ بهذه القيمة.",
-       "apihelp-query+alllinks-param-prop": "أي قطعة من المعلومات تريد تضمينها:",
+       "apihelp-query+alllinks-param-unique": "عرض فقط العناوين المتميزة المرتبطة، لا يمكن استخدامها مع <kbd>$1prop=ids</kbd>،\nعند استخدامها كمولد، يتم إنتاج الصفحات المستهدفة بدلا من صفحات المصدر.",
+       "apihelp-query+alllinks-param-prop": "أية قطعة من المعلومات لتضمينها:",
        "apihelp-query+alllinks-paramvalue-prop-ids": "تضيف معرف الصفحة للصفحة المرتبطة (لا يمكن استخدامها مع $1unique).",
        "apihelp-query+alllinks-paramvalue-prop-title": "تضيف عنوان الرابط.",
        "apihelp-query+alllinks-param-namespace": "نطاق للتعداد.",
        "apihelp-query+alllinks-param-limit": "كم عدد مجموع البنود للعودة.",
+       "apihelp-query+alllinks-param-dir": "الاتجاه للإدراج فيه.",
+       "apihelp-query+alllinks-example-B": "سرد العناوين المرتبطة، بما في ذلك المفقودة، مع معرفات الصفحات التي تنتمي إليها، بدءا من <kbd>B</kbd.",
+       "apihelp-query+alllinks-example-unique": "سرد العناوين المرتبطة الفريدة.",
+       "apihelp-query+alllinks-example-unique-generator": "الحصول على جميع العناوين المرتبطة، والتعليم على المفقودة.",
        "apihelp-query+alllinks-example-generator": "يحصل على الصفحات التي تحتوي على وصلات.",
+       "apihelp-query+allmessages-summary": "إرجاع الرسائل من هذا الموقع.",
+       "apihelp-query+allmessages-param-messages": "أية رسائل للإخراج، <kbd>*</kbd> (افتراضي) تعني جميع الرسائل.",
        "apihelp-query+allmessages-param-prop": "أي الخصائص تريد الحصول عليها:",
+       "apihelp-query+allmessages-param-enableparser": "تعيين إلى تمكين المحلل، ستتم معالجة مسبقة لنص الويكي الخاص بالرسالة (كلمات سحرية بديلة، قوالب معالجة، إلخ.).",
+       "apihelp-query+allmessages-param-nocontent": "في حالة التعيين، لا تقم بتضمين محتوى الرسائل في الإخراج.",
+       "apihelp-query+allmessages-param-includelocal": "تضمين الرسائل المحلية أيضا: أي الرسائل غير الموجودة في البرنامج ولكنها موجودة كما هو الحال في نطاق {{ns:MediaWiki}}،\nيسرد هذا جميع صفحات نطاق {{ns:MediaWiki}}، بحيث يسرد أيضا تلك الصفحات التي ليست رسائل فعلية مثل [[MediaWiki:Common.js|Common.js]].",
+       "apihelp-query+allmessages-param-args": "الوسائط ليتم نسخها في الرسالة.",
        "apihelp-query+allmessages-param-filter": "إرجاع الرسائل بالأسماء التي تحتوي على هذه السلسلة فقط.",
+       "apihelp-query+allmessages-param-customised": "إرجاع الرسائل فقط في حالة التخصيص هذه.",
        "apihelp-query+allmessages-param-lang": "إرجاع الرسائل بهذه اللغة.",
        "apihelp-query+allmessages-param-from": "إرجاع الرسائل ابتداء من هذه الرسالة.",
        "apihelp-query+allmessages-param-to": "إرجاع الرسائل التي تنتهي بهذه الرسالة.",
+       "apihelp-query+allmessages-param-title": "اسم الصفحة لاستخدامه كسياق عند توزيع الرسالة (لخيار $1enableparser).",
        "apihelp-query+allmessages-param-prefix": "إرجاء الرسائل بهذه البادئة.",
        "apihelp-query+allmessages-example-ipb": "عرض رسائل تبدأ ب<kbd>ipb-</kbd>.",
        "apihelp-query+allmessages-example-de": "عرض رسائل <kbd>august</kbd> and <kbd>mainpage</kbd> باللغة الألمانية.",
        "apihelp-query+allpages-summary": "تعداد كافة الصفحات بشكل متتالي في نطاق معين.",
+       "apihelp-query+allpages-param-from": "عنوان الصفحة لبدء التعداد منه.",
        "apihelp-query+allpages-param-to": "عنوان الصفحة لإيقاف التعداد منه.",
        "apihelp-query+allpages-param-prefix": "البحث عن كل عناوين الصفحات التي تبدأ بهذه القيمة.",
        "apihelp-query+allpages-param-namespace": "نطاق للتعداد.",
        "apihelp-query+allpages-param-filterredir": "أي الصفحات للعرض.",
+       "apihelp-query+allpages-param-minsize": "الحد من الصفحات بهذا العدد الكبير من البايتات على الأقل.",
+       "apihelp-query+allpages-param-maxsize": "الحد من صفحات مع هذا العدد الكبير من البايتات.",
+       "apihelp-query+allpages-param-prtype": "الحد من الصفحات المحمية فقط.",
+       "apihelp-query+allpages-param-prlevel": "تصفية الحماية على أساس مستوى الحماية (يجب استخدامه مع $1prtype= وسيط).",
+       "apihelp-query+allpages-param-prfiltercascade": "تصفية الحماية على أساس مستوى الحماية (يتم تجاهلها عند عدم تعيين $1prtype).",
        "apihelp-query+allpages-param-limit": "كم عدد مجموع الصفحات للعودة.",
+       "apihelp-query+allpages-param-dir": "الاتجاه للإدراج فيه.",
+       "apihelp-query+allpages-param-filterlanglinks": "التصفية استنادا إلى ما إذا كانت الصفحة تحتوي على روابط لغات، لاحظ أن هذا قد لا يفكر في  روابط اللغات المضافة بواسطة الإضافات.",
+       "apihelp-query+allpages-param-prexpiry": "مدة انتهاء الحماية لتصفية الصفحة فيها: \n; غير محددة: احصل على الصفحات التي لها تاريخ انتهاء غير محدود للحماية. \n; واضح: احصل على صفحات ذات مدة حماية محددة فقط.\n; الكل: الحصول على صفحات بأي انتهاء صلاحية للحماية.",
        "apihelp-query+allpages-example-B": "عرض  قائمة من الصفحات التي تبدأ بالحرف <kbd>B</kbd>.",
        "apihelp-query+allpages-example-generator": "عرض معلومات حول 4 صفحات تبدأ بالحرف <kbd>T</kbd>.",
+       "apihelp-query+allpages-example-generator-revisions": "عرض محتوى أول صفحتين غير تحويلتين  التي تبدأ من <kbd>Re</kbd.",
+       "apihelp-query+allredirects-summary": "أدرج جميع التحويلات إلى نطاق.",
        "apihelp-query+allredirects-param-from": "عنوان التحويلة لبدء التعداد منه.",
        "apihelp-query+allredirects-param-to": "عنوان التحويلة لإيقاف التعداد منه.",
        "apihelp-query+allredirects-param-prefix": "ابحث عن جميع عناوين الصفحات المستهدفة التي تبدأ بهذه القيمة.",
-       "apihelp-query+allredirects-param-prop": "أي قطعة من المعلومات تريد تضمينها:",
+       "apihelp-query+allredirects-param-unique": "عرض صفحات الهدف متميزة فقط، لا يمكن استخدامها مع $1prop=ids|fragment|interwiki،\nعند استخدامها كمولد، يتم إنتاج الصفحات المستهدفة بدلا من صفحات المصدر.",
+       "apihelp-query+allredirects-param-prop": "أية قطعة من المعلومات لتضمينها:",
        "apihelp-query+allredirects-paramvalue-prop-ids": "تضيف معرف الصفحة لصفحة التحويل (لا يمكن استخدامها مع $1unique).",
        "apihelp-query+allredirects-paramvalue-prop-title": "تضيف عنوان التحويلة.",
+       "apihelp-query+allredirects-paramvalue-prop-fragment": "يضيف الجزء من التحويلة، إن وُجِد (لا يمكن استخدامه مع <var>$1unique</var>).",
+       "apihelp-query+allredirects-paramvalue-prop-interwiki": "يضيف بادئة إنترويكي من التحويلة، إن وُجِدت (لا يمكن استخدامها مع <var>$1unique</var>).",
        "apihelp-query+allredirects-param-namespace": "نطاق للتعداد.",
        "apihelp-query+allredirects-param-limit": "كم عدد مجموع البنود للعودة.",
+       "apihelp-query+allredirects-param-dir": "الاتجاه للإدراج فيه.",
+       "apihelp-query+allredirects-example-B": "سرد الصفحات الهدف، بما في ذلك المفقودة، مع معرفات الصفحات التي تنتمي إليها، بدءا من <kbd>B</kbd.",
+       "apihelp-query+allredirects-example-unique": "سرد الصفحات الهدف الفريدة.",
+       "apihelp-query+allredirects-example-unique-generator": "الحصول على جميع الصفحات المستهدفة، والتعليم على المفقودة.",
        "apihelp-query+allredirects-example-generator": "يحصل على الصفحات التي تحتوي على تحويلات.",
        "apihelp-query+allrevisions-summary": "اعرض كل المراجعات.",
        "apihelp-query+allrevisions-param-start": "التصنيف الذي يبدأ التعداد منه.",
        "apihelp-query+allrevisions-param-end": "الطابع الزمني الذي يقف التعداد منه.",
+       "apihelp-query+allrevisions-param-user": "إددراج المراجعات بواسطة هذا المستخدم فقط.",
+       "apihelp-query+allrevisions-param-excludeuser": "لا تسرد المراجعات بواسطة هذا المستخدم.",
+       "apihelp-query+allrevisions-param-namespace": "أدرج الصفحات في هذا النطاق فقط.",
        "apihelp-query+allrevisions-param-generatetitles": "عندما يُستخدَم كمولد، ولد عناوين بدلا من معرفات المراجعات.",
+       "apihelp-query+allrevisions-example-user": "أدرج آخر 50 مساهمة بواسطة المستخدم <kbd>Example</kbd>.",
+       "apihelp-query+allrevisions-example-ns-main": "سرد أول 50 مراجعة في النطاق الرئيسي.",
+       "apihelp-query+mystashedfiles-summary": "احصل على قائمة بالملفات في ذاكرة التخزين المؤقت الخاص برفع المستخدم الحالي.",
        "apihelp-query+mystashedfiles-param-prop": "أي الخصائص تريد لجلب للملفات.",
        "apihelp-query+mystashedfiles-paramvalue-prop-size": "جلب حجم الملف وأبعاد الصورة.",
+       "apihelp-query+mystashedfiles-paramvalue-prop-type": "جلب نوع MIME للملف ونوع الوسائط.",
+       "apihelp-query+mystashedfiles-param-limit": "كم عدد الملفات للحصول عليها.",
+       "apihelp-query+mystashedfiles-example-simple": "احصل على مفتاح الملف وحجم الملف وحجم البكسل للملفات في  ذاكرة التخزين المؤقت الخاص برفع المستخدم الحالي.",
+       "apihelp-query+alltransclusions-summary": "أدرج كل التضمينات (الصفحات المضمنة باستخدام &#123;&#123;x&#125;&#125;)، بما في ذلك غير الموجودة.",
+       "apihelp-query+alltransclusions-param-from": "عنوان التضمين لبدء التعداد منه.",
+       "apihelp-query+alltransclusions-param-to": "عنوان التضمين لوقف التعداد فيه.",
+       "apihelp-query+alltransclusions-param-prefix": "ابحث عن جميع العناوين المضمنة التي تبدأ بهذه القيمة.",
+       "apihelp-query+alltransclusions-param-unique": "عرض العناوين المضمنة المتميزة فقط، لا يمكن استخدامها مع <kbd>$1prop=ids</kbd>،\nعند استخدامها كمولد، يتم إنتاج الصفحات المستهدفة بدلا من صفحات المصدر.",
+       "apihelp-query+alltransclusions-param-prop": "أي جزء من المعلومات لتضمينه:",
+       "apihelp-query+alltransclusions-paramvalue-prop-ids": "يضيف معرف الصفحة لتضين الصفحة (لا يمكن استخدامه مع $1unique).",
+       "apihelp-query+alltransclusions-paramvalue-prop-title": "يضيف عنوان التضمين.",
+       "apihelp-query+alltransclusions-param-namespace": "النطاق للتعداد.",
+       "apihelp-query+alltransclusions-param-limit": "كم عدد العناصر لإرجاعها.",
+       "apihelp-query+alltransclusions-param-dir": "الاتجاه للإدراج فيه.",
+       "apihelp-query+alltransclusions-example-B": "سرد العناوين المعطلة، بما في ذلك المفقودة، مع معرفات الصفحات التي تنتمي إليها، بدءا من <kbd>B</ kbd>.",
+       "apihelp-query+alltransclusions-example-unique": "إدراج عناوين مضمنة فريدة.",
+       "apihelp-query+alltransclusions-example-unique-generator": "الحصول على جميع العناوين المضمنة، والتعليم على المفقودة.",
+       "apihelp-query+alltransclusions-example-generator": "يحصل على الصفحات التي تحتوي على تضمينات.",
+       "apihelp-query+allusers-summary": "تعداد جميع المستخدمين المسجلين.",
+       "apihelp-query+allusers-param-from": "اسم المستخدم لبدء التعداد منه.",
+       "apihelp-query+allusers-param-to": "اسم المستخدم لإيقاف التعداد فيه.",
+       "apihelp-query+allusers-param-prefix": "ابحث عن جميع المستخدمين الذين يبدأون بهذه القيمة.",
+       "apihelp-query+allusers-param-dir": "اتجاه للفرز فيه.",
+       "apihelp-query+allusers-param-group": "تضمين المستخدمين في المجموعات المحددة فقط.",
+       "apihelp-query+allusers-param-excludegroup": "استبعاد المستخدمين في المجموعات المحددة.",
+       "apihelp-query+allusers-param-rights": "قم بتضمين المستخدمين بالصلاحيات المحددة فقط، لا تشمل الصلاحيات الممنوحة بواسطة المجموعات الضمنية أو الترقية التلقائية مثل * المستخدمين أو المستخدمين المؤكدين.",
+       "apihelp-query+allusers-param-prop": "أية قطعة من المعلومات لتضمينها:",
+       "apihelp-query+allusers-paramvalue-prop-blockinfo": "يضيف المعلومات حول المنع الحالي للمستخدم.",
+       "apihelp-query+allusers-paramvalue-prop-groups": "يسرد المجموعات التي يوجد بها المستخدم، يستخدم هذا المزيد من موارد الخادم وقد يعرض نتائج أقل من الحد المسموح به.",
+       "apihelp-query+allusers-paramvalue-prop-implicitgroups": "يسرد كل المجموعات التي يوجد فيها المستخدم تلقائيا.",
+       "apihelp-query+allusers-paramvalue-prop-rights": "يسرد الصلاحيات التي يمتلكها المستخدم.",
+       "apihelp-query+allusers-paramvalue-prop-editcount": "يضيف عدد تحريرات المستخدم.",
+       "apihelp-query+allusers-paramvalue-prop-registration": "يإضيف الطابع الزمني عند تسجيل المستخدم إذا كان متاحا (قد يكون فارغا).",
+       "apihelp-query+allusers-paramvalue-prop-centralids": "يضيف معرفات مركزية وحالة المرفقات للمستخدم.",
+       "apihelp-query+allusers-param-limit": "كم عدد أسماء المستخدمين لإرجاعها.",
+       "apihelp-query+allusers-param-witheditsonly": "سرد المستخدمين الذين قاموا بتحريرات فقط.",
+       "apihelp-query+allusers-param-activeusers": "سرد المستخدمين النشطين في آخر $1 {{PLURAL:$1|يوم|أيام}} فقط.",
+       "apihelp-query+allusers-param-attachedwiki": "باستخدام <kbd>$1prop=centralids</kbd>، أشر أيضا إلى ما إذا كان المستخدم مرتبطا بالويكي المحدد بواسطة هذا المعرف.",
+       "apihelp-query+allusers-example-Y": "سرد المستخدمين ابتداء من <kbd>Y</kbd>.",
+       "apihelp-query+authmanagerinfo-summary": "استرداد معلومات حول حالة المصادقة الحالية.",
+       "apihelp-query+authmanagerinfo-param-securitysensitiveoperation": "اختبار ما إذا كانت حالة المصادقة الحالية للمستخدم كافية للعملية الحساسة للأمان المحددة أم لا.",
+       "apihelp-query+authmanagerinfo-param-requestsfor": "إحضار معلومات حول طلبات المصادقة المطلوبة لإجراء المصادقة المحدد.",
+       "apihelp-query+authmanagerinfo-example-login": "جلب الطلبات التي يمكن استخدامها عند بدء تسجيل دخول.",
+       "apihelp-query+authmanagerinfo-example-login-merged": "جلب الطلبات التي يمكن استخدامها عند بدء تسجيل دخول، مع دمج حقول النماذج.",
+       "apihelp-query+authmanagerinfo-example-securitysensitiveoperation": "اختبار ما إذا كانت المصادقة كافية لعمل <kbd>foo</kbd>.",
+       "apihelp-query+backlinks-summary": "ابحث عن جميع الصفحات الموصولة للصفحة المحددة.",
+       "apihelp-query+backlinks-param-title": "عنوان للبحث، لا يمكن استخدامه مع <var>$1pageid</var",
+       "apihelp-query+backlinks-param-pageid": "معرف صفحة للبحث، لا يمكن استخدامه مع <var>$1title</var>.",
+       "apihelp-query+backlinks-param-namespace": "النطاق للتعداد.",
+       "apihelp-query+backlinks-param-dir": "الاتجاه للإدراج فيه.",
+       "apihelp-query+backlinks-param-filterredir": "كيفية التصفية للتحويلات، إذا تم ضبطه على <kbd>nonredirects</kbd> عند تمكين <var>$1redirect</var>، فسيتم تطبيق هذا على المستوى الثاني فقط.",
+       "apihelp-query+backlinks-param-limit": "كم عدد الصفحات التي سيتم إرجاعها، إذا تم تمكين <var>$1redirect</var> ، فسيتم تطبيق الحد الأقصى على كل مستوى بشكل منفصل (مما يعني أنه قد يتم إرجاع ما يصل إلى * <var>$1limit</var> نتائج).",
+       "apihelp-query+backlinks-param-redirect": "إذا كان ربط الصفحة تحويلة، فابحث عن جميع الصفحات التي تصل لتلك التحويلة أيضا، الحد الأقصى هو النصف.",
+       "apihelp-query+backlinks-example-simple": "عرض الوصلات إلى <kbd>Main page</kbd>.",
+       "apihelp-query+backlinks-example-generator": "احصل على معلومات حول الصفحات التي تصل إلى <kbd>Main page</kbd>.",
+       "apihelp-query+blocks-summary": "إدراج جميع المستخدمين وعناوين الآيبي الممنوعة.",
+       "apihelp-query+blocks-param-start": "الطابع الزمني لبدء العد منه.",
+       "apihelp-query+blocks-param-end": "الطابع الزمني لوقف التعداد فيه.",
+       "apihelp-query+blocks-param-ids": "قائمة معرفات المنع للإدراج (اختياري).",
+       "apihelp-query+blocks-param-users": "قائمة المستخدمين للبحث عنهم (اختياري).",
+       "apihelp-query+blocks-param-ip": "احصل على كل عمليات المنع التي تنطبق على عنوان الآيبي أو نطاق CIDR عذا، بما في ذلك عمليات منع النطاق،\nلا يمكن استخدامه مع <var>$3users</var>، لا يتم قبول نطاقات CIDR الأوسع من IPv4/$1 أو IPv6/$2.",
+       "apihelp-query+blocks-param-limit": "الحد الأقصى لعدد عمليات المنع لإدراجها.",
+       "apihelp-query+blocks-param-prop": "أي الخصائص للحصول عليها.",
+       "apihelp-query+blocks-paramvalue-prop-id": "يضيف معرف المنع.",
+       "apihelp-query+blocks-paramvalue-prop-user": "يضيف اسم المستخدم للمستخدم الممنوع.",
+       "apihelp-query+blocks-paramvalue-prop-userid": "يضيف اسم المستخدم للمستخدم الممنوع.",
+       "apihelp-query+blocks-paramvalue-prop-by": "يضيف اسم المستخدم للمستخدم المانع.",
+       "apihelp-query+blocks-paramvalue-prop-byid": "يضيف اسم المستخدم للمستخدم المانع.",
+       "apihelp-query+blocks-paramvalue-prop-timestamp": "يضيف الطابع الزمني عندما تم منح المنع.",
+       "apihelp-query+blocks-paramvalue-prop-expiry": "يضيف الطابع الزمني عندما تنتهي صلاحية المنع.",
+       "apihelp-query+blocks-paramvalue-prop-reason": "يضيف السبب المعطى للمنع.",
+       "apihelp-query+blocks-paramvalue-prop-range": "يضيف نطاق عناوين الآيبي المتأثرة بالمنع.",
+       "apihelp-query+blocks-paramvalue-prop-flags": "يوسم المنع بـ(المنع التلقائي والمجهولون فقط وما إلى ذلك).",
+       "apihelp-query+blocks-param-show": "إظهار العناصر التي تستوفي هذه المعايير فقط،\nعلى سبيل المثال، لمشاهدة عمليات المنع غير المحددة فقط على عناوين آيبي; اضبط <kbd>$1show=ip|!temp</kbd>.",
        "apihelp-query+blocks-example-simple": "قائمة المنع.",
+       "apihelp-query+blocks-example-users": "إدراج عمليات منع المستخدمين <kbd>Alice</kbd> و<kbd>Bob</kbd>.",
+       "apihelp-query+categories-summary": "أدرج جميع التصنيفات التي تنتمي إليها الصفحات.",
+       "apihelp-query+categories-param-prop": "أي الخصائص الإضافية التي يمكنك الحصول عليها لكل تصنيف:",
+       "apihelp-query+categories-paramvalue-prop-sortkey": "يضيف مفتاح الفرز (سلسلة سداسية عشرية) وبادئة مفتاح الفرز (جزء يمكن قراءته بواسطة البشر) للتصنيف.",
+       "apihelp-query+categories-paramvalue-prop-timestamp": "يضيف الطابع الزمني عند إضافة التصنيف.",
+       "apihelp-query+categories-paramvalue-prop-hidden": "يوسم التصنيفات المخفية بـ<code>_&#95;HIDDENCAT_&#95;</code>.",
+       "apihelp-query+categories-param-show": "أي نوع من التصنيفات لإظهاره.",
+       "apihelp-query+categories-param-limit": "كم عدد التصنيات للعودة.",
+       "apihelp-query+categories-param-categories": "إدراج هذه التصنيفات فقط، مفيد للتحقق ما إذا كانت صفحة معينة في تصنيف معين.",
+       "apihelp-query+categories-param-dir": "الاتجاه للإدراج فيه.",
+       "apihelp-query+categories-example-simple": "احصل على قائمة بالتصنيفات التي تنتمي إليها صفحة <kbd>Albert Einstein</kbd>.",
+       "apihelp-query+categories-example-generator": "الحصول على معلومات حول جميع التصنيفات المستخدمة في صفحة <kbd>Albert Einstein</kbd>.",
+       "apihelp-query+categoryinfo-summary": "يرجع المعلومات حول التصنيفات المحددة.",
+       "apihelp-query+categoryinfo-example-simple": "الحصول على معلومات عن <kbd>Category:Foo</kbd> و<kbd>Category:Bar</kbd>.",
+       "apihelp-query+categorymembers-summary": "إدراج جميع الصفحات في تصنيف معين.",
+       "apihelp-query+categorymembers-param-title": "أي تصنيف لتعداد (مطلوب)، يجب تضمين البادئة <kbd>{{ns:category}}:</kbd>، لا يمكن استخدامه مع <var>$1pageid</var>.",
+       "apihelp-query+categorymembers-param-pageid": "معرف صفحة التصنيف للتعداد، لا يمكن استخدامه مع <var>$1title</var>.",
+       "apihelp-query+categorymembers-param-prop": "أية قطعة من المعلومات لتضمينها:",
+       "apihelp-query+categorymembers-paramvalue-prop-ids": "يضيف معرف الصفحة.",
+       "apihelp-query+categorymembers-paramvalue-prop-title": "يضيف معرف عنوان ونطاق الصفحة.",
+       "apihelp-query+categorymembers-paramvalue-prop-sortkey": "يضيف مفتاح الفرز المستخدم للفرز في التصنيف (سلسلة سداسية عشرية).",
+       "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-type": "أي نوع من أعضاء التصنيفات لتضمينه، تم التجاهل عند تعيين <kbd>$1sort=timestamp</kbd>.",
+       "apihelp-query+categorymembers-param-limit": "الحد الأقصى لعدد الصفحات المطلوب عرضها.",
+       "apihelp-query+categorymembers-param-sort": "خاصية للفرز وفقا لها.",
+       "apihelp-query+categorymembers-param-dir": "في أي اتجاه للفرز.",
+       "apihelp-query+categorymembers-param-start": "الطابع الزمني لبدء الإدراج منه، يمكن استخدامه فقط مع <kbd>$1sort=timestamp</kbd>.",
+       "apihelp-query+categorymembers-param-end": "الطابع الزمني لإنهاء الإدراج فيه، يمكن استخدامه فقط مع <kbd>$1sort=timestamp</kbd>.",
+       "apihelp-query+categorymembers-param-starthexsortkey": "منتاح فرز لبدء الإدراج منه، كما يتم إرجاعه بواسطة <kbd>$1prop=sortkey</kbd>، يمكن استخدامه فقط مع <kbd>$1sort=sortkey</kbd>.",
+       "apihelp-query+categorymembers-param-endhexsortkey": "منتاح فرز لإنهاء الإدراج فيه، كما يتم إرجاعه بواسطة <kbd>$1prop=sortkey</kbd>، يمكن استخدامه فقط مع <kbd>$1sort=sortkey</kbd>.",
+       "apihelp-query+categorymembers-param-startsortkeyprefix": "بادئة منتاح فرز لبدء الإدراج منها، كما يتم إرجاعها بواسطة <kbd>$1prop=sortkey</kbd>، يمكن استخدامها فقط مع <kbd>$1sort=sortkey</kbd>.",
+       "apihelp-query+categorymembers-param-endsortkeyprefix": "بادئة منتاح فرز لإنهاء الإدراج فيها، كما يتم إرجاعها بواسطة <kbd>$1prop=sortkey</kbd>، يمكن استخدامها فقط مع <kbd>$1sort=sortkey</kbd>.",
+       "apihelp-query+categorymembers-param-startsortkey": "استخدم $1arthexsortkey بدلا من ذلك.",
+       "apihelp-query+categorymembers-param-endsortkey": "استخدم $1endhexsortkey بدلا من ذلك.",
+       "apihelp-query+categorymembers-example-simple": "الحصول على أول 10 صفحات في <kbd>Category:Physics</kbd>.",
+       "apihelp-query+categorymembers-example-generator": "الحصول على معلومات الصفحة حول  أول 10 صفحات في <kbd>Category:Physics</kbd>.",
+       "apihelp-query+contributors-summary": "احصل على قائمة بالمساهمين الذين سجلوا الدخول وعدد المشتركين المجهولين في الصفحة.",
+       "apihelp-query+contributors-param-group": "قم بتضمين المستخدمين بالصلاحيات المحددة فقط، لا تقم بتضمين الصلاحيات الممنوحة بواسطة المجموعات الضمنية أو الترقية التلقائية مثل * المستخدمين أو المستخدمين المؤكدين.",
+       "apihelp-query+contributors-param-excludegroup": "استبعاد المستخدمين بالصلاحيات المحددة، لا تقم بتضمين الصلاحيات الممنوحة بواسطة المجموعات الضمنية أو الترقية التلقائية مثل * المستخدمين أو المستخدمين المؤكدين.",
+       "apihelp-query+contributors-param-rights": "قم بتضمين المستخدمين بالصلاحيات المحددة فقط، لا تشمل الصلاحيات الممنوحة بواسطة المجموعات الضمنية أو الترقية التلقائية مثل * المستخدمين أو المستخدمين المؤكدين.",
+       "apihelp-query+contributors-param-excluderights": "استبعاد المستخدمين بالصلاحيات المحددة، لا تقم بتضمين الصلاحيات الممنوحة بواسطة المجموعات الضمنية أو الترقية التلقائية مثل * المستخدمين أو المستخدمين المؤكدين.",
+       "apihelp-query+contributors-param-limit": "كم عدد المساهمين للعودة.",
+       "apihelp-query+contributors-example-simple": "عرض المساهمين في الصفحة <kbd>Main Page</kbd>.",
+       "apihelp-query+deletedrevisions-summary": "الحصول على معلومات المراجعة المحذوفة.",
+       "apihelp-query+deletedrevisions-extended-description": "يمكن استخدامه بعدة طرق: \n# الحصول على مراجعات محذوفة لمجموعة من الصفحات، عن طريق تعيين عناوين أو صفحات، مرتبة حسب العنوان والطابع الزمني. \n# الحصول على بيانات حول مجموعة من المراجعات المحذوفة عن طريق تعيين معرفاتها مع معرفات المراجعات، مرتبة حسب معرف المراجعة.",
+       "apihelp-query+deletedrevisions-param-start": "الطابع الزمني لبدء العد منه، تم التجاهل عند معالجة قائمة بمعرفات المراجعة.",
+       "apihelp-query+deletedrevisions-param-end": "الطابع الزمني لإيقاف التعداد فيه، تم التجاهل عند معالجة قائمة بمعرفات المراجعة.",
+       "apihelp-query+deletedrevisions-param-tag": "إدراج المراجعات الموسومة بهذ الوسم فقط.",
+       "apihelp-query+deletedrevisions-param-user": "إددراج المراجعات بواسطة هذا المستخدم فقط.",
+       "apihelp-query+deletedrevisions-param-excludeuser": "لا تسرد المراجعات بواسطة هذا المستخدم.",
+       "apihelp-query+deletedrevisions-example-titles": "إدراج المراجعات المحذوفة من الصفحات <kbd>Main Page</kbd> و<kbd>Talk:Main Page</kbd>، بمحتوى.",
+       "apihelp-query+deletedrevisions-example-revids": "إدراج المعلومات الخاصة بالمراجعة المحذوفة <kbd>123456</kbd>.",
+       "apihelp-query+deletedrevs-summary": "إدراج المراجعات المحذوفة.",
+       "apihelp-query+deletedrevs-extended-description": "يعمل في ثلاثة أوضاع: \n# إدراج المراجعات المحذوفات للعناوين المحددة، مرتبة حسب الطابع الزمني. \n# إدراج المساهمات المحذوفة لمستخدم معين، مرتبة حسب الطابع الزمني (لم يتم تحديد عناوين). \n# سرد جميع المراجعات المحذوفة في النطاق المحدد، مرتبة حسب العنوان والطابع الزمني (لم يتم تحديد عناوين، ولم يتم تعيين $1user). \n\nتنطبق بعض الوسائط فقط على بعض الأوضاع ويتم تجاهلها في أوضاع أخرى.",
+       "apihelp-query+deletedrevs-paraminfo-modes": "{{PLURAL:$1|وضع|أوضاع}}: $2",
+       "apihelp-query+deletedrevs-param-start": "الطابع الزمني لبدء العد منه.",
+       "apihelp-query+deletedrevs-param-end": "الطابع الزمني لوقف التعداد فيه.",
+       "apihelp-query+deletedrevs-param-from": "بدء الإدراج من هذا العنوان.",
+       "apihelp-query+deletedrevs-param-to": "وقف الإدراج من هذا العنوان.",
+       "apihelp-query+deletedrevs-param-prefix": "البحث عن كل عناوين الصفحات التي تبدأ بهذه القيمة.",
+       "apihelp-query+deletedrevs-param-unique": "إدراج مراجعة واحدة فقط لكل صفحة.",
+       "apihelp-query+deletedrevs-param-tag": "إدراج المراجعات الموسومة بهذ الوسم فقط.",
+       "apihelp-query+deletedrevs-param-user": "إددراج المراجعات بواسطة هذا المستخدم فقط.",
+       "apihelp-query+deletedrevs-param-excludeuser": "لا تسرد المراجعات بواسطة هذا المستخدم.",
+       "apihelp-query+deletedrevs-param-namespace": "إدراج الصفحات في هذا النطاق فقط.",
+       "apihelp-query+deletedrevs-param-limit": "الحد الأقصى لكمية المراجعات للإدراج.",
+       "apihelp-query+deletedrevs-param-prop": "أي الخصائص للحصول عليها: \n;revid:يضيف معرف المراجعة معرف المراجعة للمراجعة المحذوفة.\n;parentid: يضيف معرف المراجعة للنسخة السابقة السابقة إلى الصفحة.\n;user:يضيف  المستخدم الذي قام بإجراء المراجعة.\n;userid:يضيف معرف المستخدم الذي قام بإجراء المراجعة.\n;comment:يضيف تعليق المراجعة.\n;parsedcomment:يضيف التعليق المحسن للمراجعة.\n;minor:يوسم إذا كانت المراجعة طفيفة.\n;len:يضيف طول (بالبايت) المراجعة.\n;sha1:يضيف SHA-1 (الأساس 16) للمراجعة.\n;content:يضيف محتوى المراجعة.\n;token:<span class=\"apihelp-deprecated\">موقوف.</span>  يعطي رمز التعديل.\n;tags:يوسم للمراجعة.",
+       "apihelp-query+deletedrevs-example-mode1": "إدراج المراجعات المحذوفة من الصفحات <kbd>Main Page</kbd> و<kbd>Talk:Main Page</kbd>، بمحتوى (الوضع 1).",
+       "apihelp-query+deletedrevs-example-mode2": "إدراج آخر 50 مساهمة محذوفة بواسطة <kbd>Bob</kbd> (الوضع 2).",
+       "apihelp-query+deletedrevs-example-mode3-main": "إدراج آخر 50 مراجعة محذوفة في النطاق الرئيسي (الوضع 3).",
+       "apihelp-query+deletedrevs-example-mode3-talk": "إدراج أول 50 صفحة محذوفة في النطاق {{ns:talk}} (الوضع 3).",
+       "apihelp-query+disabled-summary": "تم تعطيل وحدة الاستعلام هذه.",
+       "apihelp-query+duplicatefiles-summary": "سرد كافة الملفات التي تكون مكررة عن الملفات المحددة استنادا إلى قيم رمز الرقم.",
+       "apihelp-query+duplicatefiles-param-limit": "كم عدد الملفات المكررة للعودة.",
+       "apihelp-query+duplicatefiles-param-dir": "الاتجاه للإدراج فيه.",
+       "apihelp-query+duplicatefiles-param-localonly": "ابحث فقط عن الملفات في المستودع المحلي.",
+       "apihelp-query+duplicatefiles-example-simple": "ابحث عن تكرارات [[:File:Albert Einstein Head.jpg]].",
+       "apihelp-query+duplicatefiles-example-generated": "ابحث عن تكرارات كل الملفات.",
+       "apihelp-query+embeddedin-summary": "العثور على جميع الصفحات التي تتضمن (نسخ) العنوان المعطى.",
+       "apihelp-query+embeddedin-param-title": "عنوان للبحث، لا يمكن استخدامه مع <var>$1pageid</var",
+       "apihelp-query+embeddedin-param-pageid": "معرف صفحة للبحث، لا يمكن استخدامه مع <var>$1title</var>.",
+       "apihelp-query+embeddedin-param-namespace": "النطاق للتعداد.",
+       "apihelp-query+embeddedin-param-dir": "الاتجاه للإدراج فيه.",
+       "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+extlinks-summary": "يرجع جميع المسارات الخارجية (وليس الإنترويكي) من الصفحات المعينة.",
+       "apihelp-query+extlinks-param-limit": "كم عدد الوصلات للعودة.",
+       "apihelp-query+extlinks-param-protocol": "بروتوكول المسار، إذا تم تعيين <var>$1query</var> وفارغ، يكون البروتوكول <kbd>http</kbd>اترك كلا من هذا و<var>$1query</var> فارغين لسرد جميع الروابط الخارجية.",
+       "apihelp-query+extlinks-param-query": "بحث سلسلة دون بروتوكول، مفيد للتحقق مما إذا كانت صفحة معينة تحتوي على مسار خارجي معين.",
+       "apihelp-query+extlinks-param-expandurl": "توسيع المسارات المتعلقة بالبروتوكول مع البروتوكول الأساسي.",
+       "apihelp-query+extlinks-example-simple": "احصل على قائمة بالوصلات الخارجية في <kbd>Main Page</kbd>.",
+       "apihelp-query+exturlusage-summary": "تعداد الصفحات التي تحتوي على مسار محدد.",
+       "apihelp-query+exturlusage-param-prop": "أية قطعة من المعلومات لتضمينها:",
+       "apihelp-query+exturlusage-paramvalue-prop-ids": "يضيف معرف الصفحة.",
+       "apihelp-query+exturlusage-paramvalue-prop-title": "يضيف معرف عنوان ونطاق الصفحة.",
+       "apihelp-query+exturlusage-paramvalue-prop-url": "يضيف المسار المستخدم في الصفحة.",
+       "apihelp-query+exturlusage-param-protocol": "بروتوكول المسار، إذا تم تعيين <var>$1query</var> وفارغ، يكون البروتوكول <kbd>http</kbd>اترك كلا من هذا و<var>$1query</var> فارغين لسرد جميع الروابط الخارجية.",
+       "apihelp-query+exturlusage-param-query": "بحث سلسلة دون بروتوكول، انظر [[Special:LinkSearch]]، اتركه فارغًا لسرد كل الروابط الخارجية.",
+       "apihelp-query+exturlusage-param-namespace": "النطاق للتعداد.",
+       "apihelp-query+exturlusage-param-limit": "كم عدد الصفحات للعودة.",
+       "apihelp-query+exturlusage-param-expandurl": "توسيع المسارات المتعلقة بالبروتوكول مع البروتوكول الأساسي.",
+       "apihelp-query+exturlusage-example-simple": "عرض الصفحات التي تربط بـ<kbd>https://www.mediawiki.org</kbd>.",
+       "apihelp-query+filearchive-summary": "تعداد كافة الملفات المحذوفة بالتسلسل.",
+       "apihelp-query+filearchive-param-from": "عنوان الصورة لبدء التعداد منه.",
+       "apihelp-query+filearchive-param-to": "عنوان الصورة لإيقاف التعداد فيه.",
+       "apihelp-query+filearchive-param-prefix": "ابحث عن جميع عناوين الصور التي تبدأ بهذه القيمة.",
+       "apihelp-query+filearchive-param-limit": "كم عدد الصور الإجمالي للعودة.",
+       "apihelp-query+filearchive-param-dir": "الاتجاه للإدراج فيه.",
+       "apihelp-query+filearchive-param-sha1": "SHA1 تجزئة الصورة، يتجاوز $1sha1base36.",
+       "apihelp-query+filearchive-param-sha1base36": "SHA1 تجزئة الصورة في القاعدة 36 (المستخدمة في ميدياويكي).",
+       "apihelp-query+filearchive-param-prop": "أي المعلومات عن الصورة للحصول عليها",
+       "apihelp-query+filearchive-paramvalue-prop-sha1": "يضيف تجزئة SHA-1 للصورة.",
+       "apihelp-query+filearchive-paramvalue-prop-timestamp": "يضيف الطابع الزمني للنسخة المرفوعة.",
+       "apihelp-query+filearchive-paramvalue-prop-user": "يضيف المستخدم الذي رفع نسخة الصورة.",
+       "apihelp-query+filearchive-paramvalue-prop-size": "يضيف حجم الصورة بالبايت والطول والعرض وعدد الصفحات (عند قابلية التطبيق).",
+       "apihelp-query+filearchive-paramvalue-prop-dimensions": "الاسم المستعار للحجم.",
+       "apihelp-query+filearchive-paramvalue-prop-description": "يضيف وصفا لنسخة الصورة.",
+       "apihelp-query+filearchive-paramvalue-prop-parseddescription": "تحليل وصف الإصدار.",
+       "apihelp-query+filearchive-paramvalue-prop-mime": "يضيف MIME الصورة.",
+       "apihelp-query+filearchive-paramvalue-prop-mediatype": "يضيف نوع وسائط الصورة.",
+       "apihelp-query+filearchive-paramvalue-prop-metadata": "يسرد بيانات تعريف Exif لإصدار الصورة.",
+       "apihelp-query+filearchive-paramvalue-prop-bitdepth": "يضيف عمق البت للإصدار.",
+       "apihelp-query+filearchive-paramvalue-prop-archivename": "يضيف اسم ملف إصدار الأرشيف للإصدارات غير الأحدث.",
+       "apihelp-query+filearchive-example-simple": "عرض قائمة بجميع الملفات المحذوفة.",
+       "apihelp-query+filerepoinfo-summary": "إرجاع معلومات التعريف حول مستودعات الصور المكونة في الويكي.",
+       "apihelp-query+filerepoinfo-param-prop": "أي خصائص المستودع للحصول عليها (قد يكون هناك المزيد متاح في بعض الويكيات).",
+       "apihelp-query+filerepoinfo-paramvalue-prop-apiurl": "مسار إلى API تطبيقات المستودع، مفيد في الحصول على معلومات الصورة من المضيف.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-articlepath": "مستودع الويكي <var>[[mw:Special:MyLanguage/Manual:$wgArticlePath|$wgArticlePath]]</var> أو ما يعادله.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-canUpload": "ما إذا كان يمكن رفع ملفات إلى هذا المستودع، على سبيل المثال عبر CORS والمصادقة المشتركة.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-displayname": "اسم قابل للقراءة من قبل الإنسان في مستودع الويكي.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-favicon": "مسار أيقونة المفضلة الخاصة بمستودع الويكي <var>[[mw:Special:MyLanguage/Manual:$wgFavicon|$wgFavicon]]</var>.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-fetchDescription": "ما إذا تم جلب صفحات وصف الملفات من هذا المستودع عند عرض صفحات وصف الملف المحلية.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-initialCapital": "ما إذا كانت أسماء الملفات تبدأ ضمنياً بحرف كبير.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-local": "سواء كان هذا المستودع محليا أم لا.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-name": "مفتاح المستودع، المستخدم على سبيل المثال في <var>[[mw:Special:MyLanguage/Manual:$wgForeignFileRepos|$wgForeignFileRepos]]</var> and [[Special:ApiHelp/query+imageinfo|imageinfo]] يعيد القيم.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-rootUrl": "مسار مسار الجذر لمسارات الصورة.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-scriptDirUrl": "مسار مسار الجذر لتثبيت ميدياويكي الخاص بمستودع الويكي.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-server": "مستودع الويكي <var>[[mw:Special:MyLanguage/Manual:$wgServer|$wgServer]]</var> أو ما يعادله.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-thumbUrl": "مسار مسار الجذر لمسارات الصورة المصغرة.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-url": "مسار مسار المنطقة العامة.",
+       "apihelp-query+filerepoinfo-example-simple": "الحصول على معلومات حول مستودعات الملفات.",
+       "apihelp-query+fileusage-summary": "ابحث عن كل الصفحات التي تستخدم الملفات المعطاة.",
+       "apihelp-query+fileusage-param-prop": "أي الخصائص للحصول عليها.",
+       "apihelp-query+fileusage-paramvalue-prop-pageid": "معرف الصفحة لكل صفحة.",
+       "apihelp-query+fileusage-paramvalue-prop-title": "عنوان كل صفحة.",
+       "apihelp-query+fileusage-paramvalue-prop-redirect": "علم إذا كانت الصفحة تحويلة.",
+       "apihelp-query+fileusage-param-namespace": "إدراج الصفحات في هذه النطاقات فقط.",
+       "apihelp-query+fileusage-param-limit": "كم العدد للعودة.",
+       "apihelp-query+fileusage-param-show": "إظهار العناصر التي تستوفي هذه المعايير فقط:\n;تحويلة: عرض التحويلات فقط.\n;غير تحويلة:إظهار غير التحويلات فقط.",
+       "apihelp-query+fileusage-example-simple": "احصل على قائمة الصفحات التي تستخدم [[:File:Example.jpg]].",
+       "apihelp-query+fileusage-example-generator": "احصل على معلومات حول الصفحات التي تستخدم [[:File:Example.jpg]].",
+       "apihelp-query+imageinfo-summary": "يعرض معلومات الملف وسجل الرفع.",
+       "apihelp-query+imageinfo-param-prop": "أي المعلومات عن الصورة للحصول عليها",
+       "apihelp-query+imageinfo-paramvalue-prop-timestamp": "يضيف الطابع الزمني للنسخة المرفوعة.",
+       "apihelp-query+imageinfo-paramvalue-prop-user": "يضيف المستخدم الذي رفع كل إصدار من الملف.",
        "apihelp-query+imageinfo-paramvalue-prop-userid": "إضافة هوية المستخدم الذي قام بتحميل كل إصدار ملف.",
+       "apihelp-query+imageinfo-paramvalue-prop-comment": "تعليق على الإصدار.",
+       "apihelp-query+imageinfo-paramvalue-prop-parsedcomment": "تحليل التعليق على النسخة.",
+       "apihelp-query+imageinfo-paramvalue-prop-canonicaltitle": "يضيف العنوان الأساسي للملف.",
+       "apihelp-query+imageinfo-paramvalue-prop-url": "يعطي مسارا للملف وصفحة الوصف.",
+       "apihelp-query+imageinfo-paramvalue-prop-size": "يضيف حجم الملف بالبايت والطول والعرض وعدد الصفحات (عند قابلية التطبيق).",
+       "apihelp-query+imageinfo-paramvalue-prop-dimensions": "الاسم المستعار للحجم.",
+       "apihelp-query+imageinfo-paramvalue-prop-sha1": "يضيف تجزئة SHA-1 للملف.",
+       "apihelp-query+imageinfo-paramvalue-prop-mime": "يضيف نوع MIME للملف.",
+       "apihelp-query+imageinfo-paramvalue-prop-thumbmime": "يضيف نوع MIME للصورة المصغرة (يتطلب مسار ووسيط $1urlwidth).",
+       "apihelp-query+imageinfo-paramvalue-prop-mediatype": "يضيف نوع الوسائط للملف.",
+       "apihelp-query+imageinfo-paramvalue-prop-metadata": "يسرد بيانات تعريف Exif لإصدار الملف.",
+       "apihelp-query+imageinfo-paramvalue-prop-commonmetadata": "يسرد بيانات التعريف العامة لصيغة الملف لإصدار الملف.",
+       "apihelp-query+imageinfo-paramvalue-prop-extmetadata": "يسرد البيانات الوصفية المنسقة من مصادر متعددة، النتائج بتنسيق HTML.",
+       "apihelp-query+imageinfo-paramvalue-prop-archivename": "يضيف اسم ملف إصدار الأرشيف للإصدارات غير الأحدث.",
+       "apihelp-query+imageinfo-paramvalue-prop-bitdepth": "يضيف عمق البت للإصدار.",
+       "apihelp-query+imageinfo-paramvalue-prop-uploadwarning": "تُستخدَم من قبل صفحة Special:Upload للحصول على معلومات حول ملف موجود، غير مخصص للاستخدام خارج نواة ميدياويكي.",
+       "apihelp-query+imageinfo-paramvalue-prop-badfile": "يضيف ما إذا كان الملف موجودا في [[MediaWiki:Bad image list]]",
+       "apihelp-query+imageinfo-param-limit": "عدد مراجعات الملفات ليتم إرجاعها لكل ملف.",
+       "apihelp-query+imageinfo-param-start": "الطابع الزمني لبدء الإدراج منه.",
+       "apihelp-query+imageinfo-param-end": "الطابع الزمني لإيقاف الإدراج فيه.",
+       "apihelp-query+imageinfo-param-urlwidth": "إذا تم تعيين $2prop=url، فسيتم إرجاع مسار صورة مقسمة إلى هذا العرض،\nلأسباب تتعلق بالأداء في حالة استخدام هذا الخيار; لن يتم عرض أكثر من $1 من الصور المقاسة.",
+       "apihelp-query+imageinfo-param-urlheight": "على غرار $1urlwidth.",
+       "apihelp-query+imageinfo-param-metadataversion": "إصدار البيانات الوصفية لاستخدامه، إذا تم تحديد <kbd>latest</kbd>، استخدم أحدث إصدار، الافتراضي <kbd>1</kbd> للتوافق مع الإصدارات السابقة.",
+       "apihelp-query+imageinfo-param-extmetadatalanguage": "أية لغة لجلب extmetadata بها، هذا يؤثر على كل الترجمة التي يتم جلبها، إذا كانت متعددة متاحة، وكذلك كيفية تنسيق أشياء مثل الأرقام والقيم المختلفة.",
+       "apihelp-query+imageinfo-param-extmetadatamultilang": "إذا كانت ترجمات خاصية extmetadata متاحة، فاجلبها كلها.",
+       "apihelp-query+imageinfo-param-extmetadatafilter": "إذا كان محددا وغير فارغ، فسيتم إرجاع هذه المفاتيح فقط لـ$1prop=extmetadata.",
+       "apihelp-query+imageinfo-param-urlparam": "سلسلة وسيط خاصة بالمعالج، على سبيل المثال، قد تستخدم ملفات PDF <kbd>page15-100px</kbd>، يجب استخدام <var>$1urlwidth</var> وأن يكون متسقا مع <var>$1urlparam</var>.",
+       "apihelp-query+imageinfo-param-badfilecontexttitle": "إذا تم تعيين<kbd>$2prop=badfile</kbd> ، فهذا هو عنوان الصفحة المستخدم عند تقييم [[MediaWiki:Bad image list]]",
+       "apihelp-query+imageinfo-param-localonly": "ابحث فقط عن الملفات في المستودع المحلي.",
+       "apihelp-query+imageinfo-example-simple": "إحضار معلومات حول الإصدار الحالي من [[:File:Albert Einstein Head.jpg]].",
+       "apihelp-query+imageinfo-example-dated": "إحضار معلومات حول إصدارات [[:File:Test.jpg]] من عام 2008 وما بعده.",
+       "apihelp-query+images-summary": "يعرض جميع الملفات المضمنة في الصفحات المعينة.",
+       "apihelp-query+images-param-limit": "كم عدد الملفات للعودة.",
+       "apihelp-query+images-param-images": "إدراج هذه الملفات فقط، مفيد للتحقق ما إذا كانت صفحة معينة تحتوي على ملف معين.",
+       "apihelp-query+images-param-dir": "الاتجاه للإدراج فيه.",
+       "apihelp-query+images-example-simple": "احصل على قائمة بالملفات المستخدمة في [[Main Page]].",
+       "apihelp-query+images-example-generator": "الحصول على معلومات حول جميع الملفات المستخدمة في [[Main Page]].",
+       "apihelp-query+imageusage-summary": "ابحث عن كل الصفحات التي تستخدم عنوان الصورة المعين.",
+       "apihelp-query+imageusage-param-title": "عنوان للبحث، لا يمكن استخدامه مع <var>$1pageid</var",
+       "apihelp-query+imageusage-param-pageid": "معرف صفحة للبحث، لا يمكن استخدامه مع <var>$1title</var>.",
+       "apihelp-query+imageusage-param-namespace": "النطاق للتعداد.",
+       "apihelp-query+imageusage-param-dir": "الاتجاه للإدراج فيه.",
+       "apihelp-query+imageusage-param-filterredir": "كيفية التصفية للتحويلات، إذا تم ضبطه على <kbd>nonredirects</kbd> عند تمكين <var>$1redirect</var>، فسيتم تطبيق هذا على المستوى الثاني فقط.",
+       "apihelp-query+imageusage-param-limit": "كم عدد الصفحات التي سيتم إرجاعها، إذا تم تمكين <var>$1redirect</var> ، فسيتم تطبيق الحد الأقصى على كل مستوى بشكل منفصل (مما يعني أنه قد يتم إرجاع ما يصل إلى * <var>$1limit</var> نتائج).",
+       "apihelp-query+imageusage-param-redirect": "إذا كان ربط الصفحة تحويلة، فابحث عن جميع الصفحات التي تصل لتلك التحويلة أيضا، الحد الأقصى هو النصف.",
+       "apihelp-query+imageusage-example-simple": "عرض الصفحات التي تستخدم [[:File:Albert Einstein Head.jpg]].",
+       "apihelp-query+imageusage-example-generator": "احصل على معلومات حول الصفحات التي تستخدم [[:File:Albert Einstein Head.jpg]].",
+       "apihelp-query+info-summary": "الحصول على معلومات الصفحة الأساسية.",
+       "apihelp-query+info-param-prop": "أي الخصائص الإضافية للحصول عليها:",
+       "apihelp-query+info-paramvalue-prop-protection": "إدراج مستوى الحماية لكل صفحة.",
+       "apihelp-query+info-paramvalue-prop-talkid": "معرف الصفحة لصفحة النقاش لكل صفحة غير النقاش.",
+       "apihelp-query+info-paramvalue-prop-watched": "أدرج حالة المراقبة لكل صفحة.",
+       "apihelp-query+info-paramvalue-prop-watchers": "عدد المراقبين، إذا كان مسموحا.",
+       "apihelp-query+info-paramvalue-prop-visitingwatchers": "عدد مراقبي كل صفحة الذين زاروا التحريرات الأخيرة لتلك الصفحة، إذا كان مسموحا بذلك.",
+       "apihelp-query+info-paramvalue-prop-notificationtimestamp": "الطابع الزمني لإشعار قائمة المراقبة لكل صفحة.",
+       "apihelp-query+info-paramvalue-prop-subjectid": "معرف الصفحة للصفحة الرئيسية لكل صفحة نقاش.",
+       "apihelp-query+info-paramvalue-prop-url": "يعطي مسارا كاملا، ومسارا للتعديل، ومسار الأساسي لكل صفحة.",
+       "apihelp-query+info-paramvalue-prop-readable": "ما إذا كان يمكن للمستخدم قراءة هذه الصفحة.",
+       "apihelp-query+info-paramvalue-prop-preload": "يعطي النص الذي تم إرجاعه بواسطة EditFormPreloadText.",
+       "apihelp-query+info-paramvalue-prop-displaytitle": "يعطي الطريقة التي يتم بها عرض عنوان الصفحة بالفعل.",
+       "apihelp-query+info-paramvalue-prop-varianttitles": "يعطي عنوان العرض بجميع الصيغ الخاصة بلغة محتوى الموقع.",
+       "apihelp-query+info-param-testactions": "اختبر ما إذا كان المستخدم الحالي يمكنه تنفيذ إجراءات معينة على الصفحة.",
+       "apihelp-query+info-param-token": "استخدم [[Special:ApiHelp/query+tokens|action=query&meta=tokens]] بدلا من ذلك.",
+       "apihelp-query+info-example-simple": "الحصول على معلومات حول الصفحة <kbd>Main Page</kbd>.",
+       "apihelp-query+info-example-protection": "احصل على معلومات عامة وحماية حول الصفحة <kbd>Main Page</kbd>.",
+       "apihelp-query+iwbacklinks-summary": "العثور على جميع الصفحات التي تصل إلى وصلة الإنترويكي المعطاه.",
+       "apihelp-query+iwbacklinks-extended-description": "يمكن استخدامها للعثور على جميع الروابط ببادئة، أو كل الروابط إلى عنوان (ببادئة معينة)، استخدام أي من الوسيطين \"جميع روابط الإنترويكي\" على نحو فعال.",
+       "apihelp-query+iwbacklinks-param-prefix": "بادئة للإنترويكي.",
+       "apihelp-query+iwbacklinks-param-title": "رابط إنترويكي للبحث عنه، يجب استخدامه مع <var>$1blprefix</var.",
+       "apihelp-query+iwbacklinks-param-limit": "كم عدد مجموع الصفحات للعودة.",
+       "apihelp-query+iwbacklinks-param-prop": "أي الخصائص للحصول عليها.",
+       "apihelp-query+iwbacklinks-paramvalue-prop-iwprefix": "يضيف بادئة الإنترويكي.",
+       "apihelp-query+iwbacklinks-paramvalue-prop-iwtitle": "يضيف عنوان الإنترويكي.",
+       "apihelp-query+iwbacklinks-param-dir": "الاتجاه للإدراج فيه.",
+       "apihelp-query+iwlinks-summary": "يعرض جميع روابط الإنترويكي من الصفحات المحددة.",
+       "apihelp-query+iwlinks-param-url": "ما إذا كنت تريد الحصول على المسار الكامل (لا يمكن استخدامه مع $1prop).",
+       "apihelp-query+iwlinks-param-prop": "الخصائص الإضافية التي يمكنك الحصول عليها لكل رابط بين اللغات:",
+       "apihelp-query+iwlinks-paramvalue-prop-url": "يضيف المسار الكامل.",
+       "apihelp-query+iwlinks-param-limit": "كم عدد وصلات الإنترويكي للعودة.",
+       "apihelp-query+iwlinks-param-prefix": "عودة روابط الإنترويكي بهذه البادئة فقط.",
+       "apihelp-query+iwlinks-param-title": "رابط إنترويكي للبحث عنه، يجب استخدامه مع <var>$1prefix</var.",
+       "apihelp-query+iwlinks-param-dir": "الاتجاه للإدراج فيه.",
+       "apihelp-query+iwlinks-example-simple": "الحصول على روابط إنترويكي من الصفحة <kbd>Main Page</kbd>.",
+       "apihelp-query+langbacklinks-summary": "ابحث عن جميع الصفحات التي تصل لرابط اللغة المحدد.",
+       "apihelp-query+langbacklinks-extended-description": "يمكن استخدامها للعثور على جميع الروابط برمز لغة، أو كل الروابط إلى عنوان (بلغة معينة)، استخدام أي من الوسيطين \"كل روابط اللغات\" بشكل فعال،\nلاحظ أن هذا قد لا يفكر في روابط اللغة التي تتم إضافتها بواسطة الإضافات.",
+       "apihelp-query+langbacklinks-param-lang": "لغة لرابط اللغة.",
+       "apihelp-query+langbacklinks-param-title": "رابط اللغة للبحث عنه، يجب استخدامه مع $1lang.",
+       "apihelp-query+langbacklinks-param-limit": "كم عدد مجموع الصفحات للعودة.",
+       "apihelp-query+langbacklinks-param-prop": "أي الخصائص للحصول عليها.",
+       "apihelp-query+langbacklinks-paramvalue-prop-lllang": "يضيف رمز لغة رابط اللغة.",
+       "apihelp-query+langbacklinks-paramvalue-prop-lltitle": "يضيف عنوان رابط اللغة.",
+       "apihelp-query+langbacklinks-param-dir": "الاتجاه للإدراج فيه.",
+       "apihelp-query+langbacklinks-example-simple": "الحصول على الصفحات التي تصل إلى [[:fr:Test]].",
+       "apihelp-query+langbacklinks-example-generator": "الحصول على معلومات حول الصفحات التي تصل إلى [[:fr:Test]].",
+       "apihelp-query+langlinks-summary": "يعرض جميع روابط الإنترويكي التي تربط من الصفحات المحددة.",
+       "apihelp-query+langlinks-param-limit": "كم عدد الروابط المحلية التي ستعود.",
+       "apihelp-query+langlinks-param-url": "ما إذا كنت ستحصل على المسار الكامل (لا يمكن استخدامه مع <var>$1prop</var>).",
+       "apihelp-query+langlinks-param-prop": "الخصائص الإضافية التي يمكنك الحصول عليها لكل رابط بين اللغات:",
+       "apihelp-query+langlinks-paramvalue-prop-url": "يضيف المسار الكامل.",
+       "apihelp-query+langlinks-paramvalue-prop-langname": "يضيف اسم اللغة المترجمة (أفضل جهد)، استخدم <var>$1inlanguagecode</var> للتحكم في اللغة.",
+       "apihelp-query+langlinks-paramvalue-prop-autonym": "يضيف اسم اللغة الأم.",
+       "apihelp-query+langlinks-param-lang": "إرجاع روابط اللغة برمز اللغة هذا فقط.",
+       "apihelp-query+langlinks-param-title": "رابط للبحث عنه، يجب استخدامه مع <var>$1prefix</var.",
+       "apihelp-query+langlinks-param-dir": "الاتجاه للإدراج فيه.",
+       "apihelp-query+langlinks-param-inlanguagecode": "رمز اللغة لأسماء اللغة المترجمة.",
+       "apihelp-query+langlinks-example-simple": "الحصول على روابط بين اللغات تربط من الصفحة <kbd>Main Page</kbd>.",
+       "apihelp-query+links-summary": "يعرض جميع الروابط من الصفحات المحددة.",
+       "apihelp-query+links-param-namespace": "إظهار الروابط في هذه النطاقات فقط.",
+       "apihelp-query+links-param-limit": "كم عدد الوصلات للعودة.",
+       "apihelp-query+links-param-titles": "إدراج الروابط لهذه العناوين فقط، مفيد للتحقق مما إذا كانت صفحة معينة ترتبط بعنوان معين.",
+       "apihelp-query+links-param-dir": "الاتجاه للإدراج فيه.",
+       "apihelp-query+links-example-simple": "الحصول على روابط من الصفحة <kbd>Main Page</kbd>.",
+       "apihelp-query+links-example-generator": "الحصول على معلومات حول صفحات الارتباط في الصفحة <kbd>Main Page</kbd>.",
+       "apihelp-query+links-example-namespaces": "احصل على روابط من الصفحة <kbd>Main Page</kbd> في النطاقات {{ns:user}} و{{ns:template}}.",
+       "apihelp-query+linkshere-summary": "ابحث عن جميع الصفحات الموصولة للصفحة المحددة.",
+       "apihelp-query+linkshere-param-prop": "أي الخصائص للحصول عليها.",
+       "apihelp-query+linkshere-paramvalue-prop-pageid": "معرف الصفحة لكل صفحة.",
+       "apihelp-query+linkshere-paramvalue-prop-title": "عنوان كل صفحة.",
+       "apihelp-query+linkshere-paramvalue-prop-redirect": "علم إذا كانت الصفحة تحويلة.",
+       "apihelp-query+linkshere-param-namespace": "إدراج الصفحات في هذه النطاقات فقط.",
+       "apihelp-query+linkshere-param-limit": "كم العدد للعودة.",
+       "apihelp-query+linkshere-param-show": "إظهار العناصر التي تستوفي هذه المعايير فقط:\n;تحويلة: عرض التحويلات فقط.\n;غير تحويلة:إظهار غير التحويلات فقط.",
+       "apihelp-query+linkshere-example-simple": "احصل على قائمة الصفحات التي تربط بـ[[Main Page]].",
+       "apihelp-query+linkshere-example-generator": "احصل على معلومات حول الصفحات التي تصل إلى [[Main Page]].",
+       "apihelp-query+logevents-summary": "الحصول على الأحداث من السجلات.",
+       "apihelp-query+logevents-param-prop": "أي الخصائص للحصول عليها.",
+       "apihelp-query+logevents-paramvalue-prop-ids": "يضيف معرف حدث السجل.",
+       "apihelp-query+logevents-paramvalue-prop-title": "يضيف عنوان الصفحة لحدث السجل.",
+       "apihelp-query+logevents-paramvalue-prop-type": "يضيف نوع حدث السجل.",
+       "apihelp-query+logevents-paramvalue-prop-user": "يضيف المستخدم المسؤول عن حدث السجل.",
+       "apihelp-query+logevents-paramvalue-prop-userid": "يضيف معرف المستخدم الذي كان مسؤولا عن حدث السجل.",
+       "apihelp-query+logevents-paramvalue-prop-timestamp": "يضيف الطابع الزمني لحدث السجل.",
+       "apihelp-query+logevents-paramvalue-prop-comment": "يضيف تعليق حدث السجل.",
+       "apihelp-query+logevents-paramvalue-prop-parsedcomment": "يضيف التعليق المحلل لحدث السجل.",
+       "apihelp-query+logevents-paramvalue-prop-details": "يسرد تفاصيل إضافية حول حدث السجل.",
+       "apihelp-query+logevents-paramvalue-prop-tags": "يسرد وسوما لحدث السجل.",
+       "apihelp-query+logevents-param-type": "تصفية إدخالات السجل لهذا النوع فقط.",
+       "apihelp-query+logevents-param-action": "تصفية إجراءات السجل لهذا الإجراء فقط، يتجاوز <var>$1type</var>، في قائمة القيم المحتملة، يمكن أن تحتوي القيم بحرف بدل العلامة النجمية مثل <kbd>action/*</kbd> على سلاسل مختلفة بعد الخط المائل (/).",
+       "apihelp-query+logevents-param-start": "الطابع الزمني لبدء العد منه.",
+       "apihelp-query+logevents-param-end": "الطابع الزمني لإنهاء التعداد.",
+       "apihelp-query+logevents-param-user": "تصفية الإلدخالات تلك المدخلات من قبل المستخدم المعطى.",
+       "apihelp-query+logevents-param-title": "تصفية الإدخالات إلى تلك المتعلقة بصفحة.",
+       "apihelp-query+logevents-param-namespace": "تصفية الإدخالات إلى تلك الموجودة في النطاق المحدد.",
+       "apihelp-query+logevents-param-prefix": "تصفية الإدخالات التي تبدأ بهذه البادئة.",
+       "apihelp-query+logevents-param-tag": "إدراج إدخالات الحدث الموسومة بهذ الوسم فقط.",
+       "apihelp-query+logevents-param-limit": "كم العدد الكلي لإدخالات الحدث للعودة.",
+       "apihelp-query+logevents-example-simple": "إدراج أحداث السجل الأخيرة.",
+       "apihelp-query+pagepropnames-summary": "إدراج جميع أسماء خواص الصفحة قيد الاستخدام في الويكي.",
+       "apihelp-query+pagepropnames-param-limit": "الحد الأقصى لعدد الأسماء للعودة.",
+       "apihelp-query+pagepropnames-example-simple": "الحصول على أول 10 أسماء خواص.",
+       "apihelp-query+pageprops-summary": "الحصول على خصائص صفحة مختلفة محددة في محتوى الصفحة.",
+       "apihelp-query+pageprops-param-prop": "سرد خصائص الصفحة هذه فقط (<kbd>[[Special:ApiHelp/query+pagepropnames|action=query&list=pagepropnames]]</kbd> تقوم بإرجاع أسماء خصائص الصفحة قيد الاستخدام)، مفيد للتحقق مما إذا كانت الصفحات تستخدم خاصية صفحة معينة.",
+       "apihelp-query+pageprops-example-simple": "احصل على خصائص للصفحات <kbd>Main Page</kbd> و<kbd>MediaWiki</kbd>.",
+       "apihelp-query+pageswithprop-summary": "سرد جميع الصفحات التي تستخدم خاصية صفحة معينة.",
+       "apihelp-query+pageswithprop-param-propname": "خاصية الصفحة التي تريد تعداد الصفحات (<kbd>[[Special:ApiHelp/query+pagepropnames|action=query&list=pagepropnames]]</kbd> تقوم بإرجاع أسماء خصائص الصفحة قيد الاستخدام).",
+       "apihelp-query+pageswithprop-param-prop": "أية قطعة من المعلومات لتضمينها:",
+       "apihelp-query+pageswithprop-paramvalue-prop-ids": "يضيف معرف الصفحة.",
+       "apihelp-query+pageswithprop-paramvalue-prop-title": "يضيف معرف عنوان ونطاق الصفحة.",
+       "apihelp-query+pageswithprop-paramvalue-prop-value": "يضيف قيمة خاصية الصفحة.",
+       "apihelp-query+pageswithprop-param-limit": "الحد الأقصى لعدد الصفحات المطلوب عرضها.",
+       "apihelp-query+pageswithprop-param-dir": "في أي اتجاه للفرز.",
+       "apihelp-query+pageswithprop-example-simple": "أدرج أول 10 صفحات تستخدم <code>&#123;&#123;DISPLAYTITLE:&#125;&#125;</code>.",
+       "apihelp-query+pageswithprop-example-generator": "احصل على معلومات إضافية حول أول 10 صفحات تستخدم <code>_&#95;NOTOC_&#95;</code>.",
+       "apihelp-query+prefixsearch-summary": "قم بإجراء بحث بالبادئة عن عناوين الصفحات.",
+       "apihelp-query+prefixsearch-extended-description": "على الرغم من التشابه في الأسماء، لا يُقصَد بهذه الوحدة أن تكون مكافئة لـ [[Special:PrefixIndex]]، لذلك; راجع <kbd>[[Special:ApiHelp/query+allpages|action=query&list=allpages]]</kbd> مع الوسيط <kbd>apprefix</kbd>، يشبه الغرض من هذه الوحدة <kbd>[[Special:ApiHelp/opensearch|action=opensearch]]</kbd>: لأخذ مدخلات المستخدم وتقديم أفضل العناوين المطابقة، استنادا إلى الواجهة الخلفية لمحرك البحث، قد يتضمن هذا تصحيحا مطبعيا أو تجنبا للتحويل أو استدلالا آخر.",
+       "apihelp-query+prefixsearch-param-search": "سلسلة البحث.",
+       "apihelp-query+prefixsearch-param-namespace": "النطاقات للبحث، يتم التجاهل إذا بدأ <var>$1search</var> ببادئة نطاق صالحة.",
+       "apihelp-query+prefixsearch-param-limit": "الحد الأقصى لعدد النتائج للعودة.",
        "apihelp-query+prefixsearch-param-offset": "عدد النتائج المراد تخطيها.",
+       "apihelp-query+prefixsearch-example-simple": "ابحث عن عناوين الصفحات التي تبدأ بـ<kbd>meaning</kbd>.",
+       "apihelp-query+prefixsearch-param-profile": "ابحث عن ملف شخصي لاستخدامه.",
+       "apihelp-query+protectedtitles-summary": "سرد جميع العناوين المحمية من الإنشاء.",
+       "apihelp-query+protectedtitles-param-namespace": "إدراج عناوين في هذه النطاقات فقط.",
+       "apihelp-query+protectedtitles-param-level": "إدراج العناوين بمستويات الحماية هذه فقط.",
+       "apihelp-query+protectedtitles-param-limit": "كم عدد مجموع الصفحات للعودة.",
+       "apihelp-query+protectedtitles-param-start": "بدء الإدراج في هذا الطابع الزمني للحماية.",
+       "apihelp-query+protectedtitles-param-end": "وقف الإدراج في هذا الطابع الزمني للحماية.",
+       "apihelp-query+protectedtitles-param-prop": "أي الخصائص للحصول عليها.",
+       "apihelp-query+protectedtitles-paramvalue-prop-timestamp": "يإضيف الطابع الزمني عند إضافة الحماية.",
+       "apihelp-query+protectedtitles-paramvalue-prop-user": "يضيف المستخدم الذي أضاف الحماية.",
+       "apihelp-query+protectedtitles-paramvalue-prop-userid": "يضيف معرف المستخدم الذي أضاف الحماية.",
+       "apihelp-query+protectedtitles-paramvalue-prop-comment": "يضيف التعليق للحماية.",
+       "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-generator": "ابحث عن روابط للعناوين المحمية في النطاق الرئيسي.",
+       "apihelp-query+querypage-summary": "الحصول على قائمة يتم توفيرها من خلال صفحة خاصة تستند إلى صفحة استعلام.",
+       "apihelp-query+querypage-param-page": "اسم الصفحة الخاصة، ملاحظة: هذا حساس لحالة الأحرف.",
+       "apihelp-query+querypage-param-limit": "عدد النتائج للعودة.",
+       "apihelp-query+querypage-example-ancientpages": "إرجاع النتائج من [[Special:Ancientpages]].",
+       "apihelp-query+random-summary": "الحصول على مجموعة من الصفحات العشوائية.",
+       "apihelp-query+random-extended-description": "يتم سرد الصفحات بتسلسل ثابت، نقطة البداية فقط عشوائية: هذا يعني أنه إذا، على سبيل المثال، كانت <samp>Main Page</samp>  أول صفحة عشوائية في القائمة، <samp>List of fictional monkeys</samp> سوف تكون الثانية <em>always</em>، <samp>List of people on stamps of Vanuatu</samp> الثالثة، إلخ.",
+       "apihelp-query+random-param-namespace": "إرجاع الصفحات في هذه النطاقات فقط.",
+       "apihelp-query+random-param-limit": "تحديد عدد الصفحات العشوائية التي سيتم إرجاعها.",
+       "apihelp-query+random-param-redirect": "استخدم <kbd>$1filterredir=redirects</kbd> بدلا من ذلك.",
+       "apihelp-query+random-param-filterredir": "كيفية التصفية للتحويلات.",
+       "apihelp-query+random-example-simple": "قم بإرجاع صفحتين عشوائيتين من النطاق الرئيسي.",
+       "apihelp-query+random-example-generator": "إرجاع معلومات الصفحة حول صفحتين عشوائيتين من النطاق الرئيسي.",
+       "apihelp-query+recentchanges-summary": "تعداد أحدث التغييرات.",
+       "apihelp-query+recentchanges-param-start": "الطابع الزمني لبدء العد منه.",
+       "apihelp-query+recentchanges-param-end": "الطابع الزمني لإنهاء التعداد.",
+       "apihelp-query+recentchanges-param-namespace": "تصفية التغييرات على هذه النطاقات فقط.",
+       "apihelp-query+recentchanges-param-user": "إددراج التغييرات بواسطة هذا المستخدم فقط.",
+       "apihelp-query+recentchanges-param-excludeuser": "لا تسرد التغييرات بواسطة هذا المستخدم.",
+       "apihelp-query+recentchanges-param-tag": "إدراج التغييرات الموسومة بهذ الوسم فقط.",
+       "apihelp-query+recentchanges-param-prop": "تضمين أجزاء إضافية من المعلومات:",
+       "apihelp-query+recentchanges-paramvalue-prop-user": "يضيف المستخدم المسؤول عن التحرير والوسوم إذا كان يوجد آيبي.",
+       "apihelp-query+recentchanges-paramvalue-prop-userid": "يضيف المستخدم المسؤول عن التعديل.",
+       "apihelp-query+recentchanges-paramvalue-prop-comment": "يضيف التعليق للتحرير.",
+       "apihelp-query+recentchanges-paramvalue-prop-parsedcomment": "يضيف التعليق المحلل للتحرير.",
+       "apihelp-query+recentchanges-paramvalue-prop-flags": "يضيف علامات للتحرير.",
+       "apihelp-query+recentchanges-paramvalue-prop-timestamp": "يضيف الطابع الزمني للتحرير.",
+       "apihelp-query+recentchanges-paramvalue-prop-title": "يضيف عنوان صفحة التحرير.",
+       "apihelp-query+recentchanges-paramvalue-prop-ids": "يضيف معرف الصفحة ومعرف أحدث التغييرات ومعرف النسخة الجديدة والقديمة.",
+       "apihelp-query+recentchanges-paramvalue-prop-sizes": "يضيف طول الصفحة الجديد والقديم بالبايت.",
+       "apihelp-query+recentchanges-paramvalue-prop-redirect": "يوسم التحرير إذا كانت الصفحة تحويلة",
+       "apihelp-query+recentchanges-paramvalue-prop-patrolled": "يوسم التعديلات التي يمكن مراجعتها باعتبارها مراجعة أو غير مراجعة.",
+       "apihelp-query+recentchanges-paramvalue-prop-autopatrolled": "يوسم التعديلات التي يمكن مراجعتها باعتبارها مراجعة تلقائيا أم لا.",
+       "apihelp-query+recentchanges-paramvalue-prop-loginfo": "يضيف معلومات السجل (معرف السجل، نوع السجل، إلخ) لإدخالات السجل.",
+       "apihelp-query+recentchanges-paramvalue-prop-tags": "يسرد الوسوم للدخول.",
+       "apihelp-query+recentchanges-paramvalue-prop-sha1": "يضيف المجموع الاختباري للمحتوى للإدخالات المرتبطة بمراجعة.",
+       "apihelp-query+recentchanges-param-token": "استخدم [[Special:ApiHelp/query+tokens|action=query&meta=tokens]] بدلا من ذلك.",
+       "apihelp-query+recentchanges-param-show": "إظهار العناصر التي تستوفي هذه المعايير فقط، على سبيل المثال، مشاهدة التعديلات الطفيفة فقط التي قام بها المستخدمون مسجلو الدخول، قم بتعيين $1show=minor|!anon.",
+       "apihelp-query+recentchanges-param-limit": "كم عدد التغييرات الإجمالي للعودة.",
+       "apihelp-query+recentchanges-param-type": "أي أنواع التغييرات لعرضها.",
+       "apihelp-query+recentchanges-param-toponly": "سرد التغييرات التي هي أحدث مراجعة فقط.",
+       "apihelp-query+recentchanges-param-title": "تصفية الإدخالات إلى تلك المتعلقة بصفحة.",
+       "apihelp-query+recentchanges-param-generaterevisions": "عند استخدامه كمولد، قم بإنشاء معرفات المراجعة بدلا من العناوين، ولن تؤدي إدخالات التغيير الأخيرة التي لا تحتوي على معرفات المراجعة المرتبطة (مثل معظم إدخالات السجلات) إلى توليد أي شيء.",
+       "apihelp-query+recentchanges-example-simple": "سرد أحدث التغييرات.",
+       "apihelp-query+recentchanges-example-generator": "الحصول على معلومات الصفحة حول أحدث التغييرات غير المراجعة.",
+       "apihelp-query+redirects-summary": "يعرض جميعالتحويلات إلى الصفحات المحددة.",
+       "apihelp-query+redirects-param-prop": "أي الخصائص للحصول عليها.",
+       "apihelp-query+redirects-paramvalue-prop-pageid": "معرف الصفحة لكل تحويلة.",
+       "apihelp-query+redirects-paramvalue-prop-title": "عنوان كل تحويلة.",
+       "apihelp-query+redirects-paramvalue-prop-fragment": "جزء من كل تحويلة، إن وُجِدت.",
+       "apihelp-query+redirects-param-namespace": "إدراج الصفحات في هذه النطاقات فقط.",
+       "apihelp-query+redirects-param-limit": "كم عدد التحويلات لإرجاعها.",
+       "apihelp-query+redirects-param-show": "إظهار العناصر التي تستوفي هذه المعايير فقط:\n;fragment:إظهار التحويلات بجزء فقط.\n;!fragment:إظهار التحويلات بدون جزء فقط.",
+       "apihelp-query+redirects-example-simple": "احصل على قائمة بالتحويلات إلى [[Main Page]].",
+       "apihelp-query+redirects-example-generator": "احصل على معلومات حول جميع التحويلات إلى [[Main Page]].",
+       "apihelp-query+revisions-summary": "الحصول على معلومات المراجعة.",
+       "apihelp-query+revisions-extended-description": "يمكن استخدامه بعدة طرق: \n# الحصول على بيانات حول مجموعة من الصفحات (المراجعة الأخيرة)، عن طريق تعيين عناوين أو معرفات صفحات. \n# احصل على مراجعات لصفحة معينة، باستخدام العناوين أو معرفات الصفحات ذات البداية، أو النهاية، أو الحد. \n# الحصول على بيانات حول مجموعة من المراجعات من خلال تعيين معرفاتها مع معرفات المراجعات.",
+       "apihelp-query+revisions-paraminfo-singlepageonly": "لا يجوز استخدامها إلا مع صفحة واحدة (الوضع #2).",
+       "apihelp-query+revisions-param-startid": "بدء التعداد من الطابع الزمني لهذه المراجعة، يجب أن تكون النسخة موجودة، لكن لا يجب أن تنتمي إلى هذه الصفحة.",
+       "apihelp-query+revisions-param-endid": "إيقاف التعداد في الطابع الزمني لهذه المراجعة، يجب أن تكون النسخة موجودة، لكن لا يجب أن تنتمي إلى هذه الصفحة.",
+       "apihelp-query+revisions-param-start": "من أي طابع زمني للمراجعة لبدء التعداد.",
+       "apihelp-query+revisions-param-end": "تعداد يصل إلى هذا الطابع الزمني.",
+       "apihelp-query+revisions-param-user": "عدم تضمين سوى المراجعات التي أجراها المستخدم.",
+       "apihelp-query+revisions-param-excludeuser": "استبعاد المراجعات التي أجراها المستخدم.",
+       "apihelp-query+revisions-param-tag": "إدراج المراجعات الموسومة بهذ الوسم فقط.",
+       "apihelp-query+revisions-param-token": "أي الرموز المميزة للحصول عليها لكل مراجعة.",
+       "apihelp-query+revisions-example-content": "احصل على بيانات تتضمن محتوى آخر مراجعة لـ<kbd>API</kbd> العناوين و<kbd>Main Page</kbd>.",
+       "apihelp-query+revisions-example-last5": "احصل على آخر 5 مراجعات لـ<kbd>Main Page</kbd>.",
+       "apihelp-query+revisions-example-first5": "احصل على أول 5 مراجعات من <kbd>Main Page</kbd>.",
+       "apihelp-query+revisions-example-first5-after": "احصل على أول 5 مراجعات للصفحة <kbd>Main Page</kbd> بعد 2006-05-01.",
+       "apihelp-query+revisions-example-first5-not-localhost": "احصل على أول 5 مراجعات للصفحة <kbd>Main Page</kbd> التي لم يجرها المستخدم المجهول <kbd>127.0.0.1</kbd>.",
+       "apihelp-query+revisions-example-first5-user": "احصل على أول 5 مراجعات للصفحة <kbd>Main Page</kbd> التي تم إجراؤها بواسطة المستخدم <kbd>MediaWiki default</kbd>.",
+       "apihelp-query+revisions+base-param-prop": "أي الخصائص للحصول عليها لكل مراجعة:",
+       "apihelp-query+revisions+base-paramvalue-prop-ids": "معرف المراجعة.",
+       "apihelp-query+revisions+base-paramvalue-prop-flags": "أعلام المراجعة (طفيفة).",
+       "apihelp-query+revisions+base-paramvalue-prop-timestamp": "الطابع الزمني للمراجعة.",
+       "apihelp-query+revisions+base-paramvalue-prop-user": "المستخدم الذي أجرى المراجعة.",
+       "apihelp-query+revisions+base-paramvalue-prop-userid": "معرف المستخدم لمنشئ المراجعة.",
+       "apihelp-query+revisions+base-paramvalue-prop-size": "طول (بايت) المراجعة.",
+       "apihelp-query+revisions+base-paramvalue-prop-sha1": "SHA-1 (القاعدة 16) المراجعة.",
+       "apihelp-query+revisions+base-paramvalue-prop-contentmodel": "معرف نموذج المحتوى للمراجعة.",
+       "apihelp-query+revisions+base-paramvalue-prop-comment": "تعليق من قبل المستخدم للمراجعة.",
+       "apihelp-query+revisions+base-paramvalue-prop-parsedcomment": "تعليق محلل من قبل المستخدم للمراجعة.",
+       "apihelp-query+revisions+base-paramvalue-prop-content": "نص المراجعة.",
+       "apihelp-query+revisions+base-paramvalue-prop-tags": "وسوم للمراجعة.",
+       "apihelp-query+revisions+base-paramvalue-prop-parsetree": "<span class=\"apihelp-deprecated\">موقوف.</span> استخدم <kbd>[[Special:ApiHelp/expandtemplates|action=expandtemplates]]</kbd> أو <kbd>[[Special:ApiHelp/parse|action=parse]]</kbd> بدلا من ذلك، شجرة تحليل XML لمحتوى المراجعة (تتطلب نموذج المحتوى <code>$1</code>).",
+       "apihelp-query+revisions+base-param-limit": "الحد من عدد المراجعات التي سيتم إرجاعها.",
+       "apihelp-query+revisions+base-param-expandtemplates": "استخدم <kbd>[[Special:ApiHelp/expandtemplates|action=expandtemplates]]</kbd> بدلا من ذلك، قم بتوسيع القوالب في محتوى المراجعة (يتطلب $1prop=content).",
+       "apihelp-query+revisions+base-param-generatexml": "استخدم <kbd>[[Special:ApiHelp/expandtemplates|action=expandtemplates]]</kbd> أو <kbd>[[Special:ApiHelp/parse|action=parse]]</kbd> بدلا من ذلك، قم بتوليد شجرة تحليل XML لمحتوى المراجعة (تتطلب $1prop=content).",
+       "apihelp-query+revisions+base-param-parse": "استخدم <kbd>[[Special:ApiHelp/parse|action=parse]]</kbd> بدلا من ذلك، تحليل محتوى المراجعة (يتطلب $1prop=content)، لأسباب تتعلق بالأداء; إذا تم استخدام هذا الخيار، يتم فرض $1limit إلى 1.",
+       "apihelp-query+revisions+base-param-section": "استرجع محتويات رقم هذا القسم فقط.",
+       "apihelp-query+revisions+base-param-diffto": "استخدم <kbd>[[Special:ApiHelp/compare|action=compare]]</kbd> بدلا من ذلك، معرف المراجعة للتفريق بين كل مراجعة، استخدم <kbd>prev</kbd> و<kbd>next</kbd> و<kbd>cur</kbd> للمراجعة السابقة واللاحقة والحالية على التوالي.",
+       "apihelp-query+revisions+base-param-difftotext": "استخدم <kbd>[[Special:ApiHelp/compare|action=compare]]</kbd> بدلا من ذلك، النص للتفريق بين كل مراجعة، يختلف عدد محدود فقط من المراجعات، يتجاوز <var>$1diffto</var>، إذا تم تعيين <var>$1section</var>، فسيتم تمييز هذا القسم فقط مقابل هذا النص.",
+       "apihelp-query+revisions+base-param-difftotextpst": "استخدم <kbd>[[Special:ApiHelp/compare|action=compare]]</kbd> بدلا من ذلك، قم بإجراء تحويل ما قبل الحفظ على النص قبل نشره، صالح فقط عند استخدامه مع <var>$1difftotext</var>.",
+       "apihelp-query+revisions+base-param-contentformat": "تنسيق التسلسل المستخدم لـ<var>$1difftotext</var> والمتوقع لإخراج المحتوى.",
+       "apihelp-query+search-summary": "إجراء بحث نص كامل.",
+       "apihelp-query+search-param-search": "ابحث عن عناوين الصفحات أو المحتوى الذي يطابق هذه القيمة، يمكنك استخدام سلسلة البحث لاستدعاء ميزات بحث خاصة، اعتمادا على ما تنفذه الواجهة الخلفية للبحث في موقع الويكي.",
+       "apihelp-query+search-param-namespace": "ابحث داخل هذه النطاقات فقط.",
+       "apihelp-query+search-param-what": "أي نوع من البحث لأدائه.",
+       "apihelp-query+search-param-info": "أية بيانات وصفية لعرضها.",
+       "apihelp-query+search-param-prop": "أي الخصائص للعودة.",
+       "apihelp-query+search-param-qiprofile": "الاستعلام عن ملف شخصي مستقل للاستخدام (يؤثر على خوارزمية الترتيب).",
+       "apihelp-query+search-paramvalue-prop-size": "يضيف حجم الصفحة بالبايت.",
+       "apihelp-query+search-paramvalue-prop-wordcount": "يضيف عدد كلمات الصفحة.",
+       "apihelp-query+search-paramvalue-prop-timestamp": "يضيف الطابع الزمني لوقت آخر تعديل للصفحة.",
+       "apihelp-query+search-paramvalue-prop-snippet": "يضيف مقتطفا محللا للصفحة.",
+       "apihelp-query+search-paramvalue-prop-titlesnippet": "يضيف مقتطفا محللا لعنوان الصفحة.",
+       "apihelp-query+search-paramvalue-prop-redirectsnippet": "يضيف مقتطفا محللا لعنوان التحويلة.",
+       "apihelp-query+search-paramvalue-prop-redirecttitle": "يضيف عنوان التحويلة المطابقة.",
+       "apihelp-query+search-paramvalue-prop-sectionsnippet": "يضيف مقتطفا محللا لعنوان القسم المطابق.",
+       "apihelp-query+search-paramvalue-prop-sectiontitle": "يضيف عنوان القسم المطابق.",
+       "apihelp-query+search-paramvalue-prop-categorysnippet": "يضيف مقتطفا محللا للتصنيف المطابق.",
+       "apihelp-query+search-paramvalue-prop-isfilematch": "يضيف قيمة منطقية تشير إلى ما إذا كان محتوى البحث مطابقا للمحتوى.",
+       "apihelp-query+search-paramvalue-prop-extensiondata": "يضيف بيانات إضافية منشأة بواسطة الإضافات.",
+       "apihelp-query+search-paramvalue-prop-score": "تم تجاهله.",
+       "apihelp-query+search-paramvalue-prop-hasrelated": "تم تجاهله.",
+       "apihelp-query+search-param-limit": "كم عدد مجموع الصفحات للعودة.",
+       "apihelp-query+search-param-interwiki": "تضمين نتائج الإنترويكي في البحث، إذا كان ذلك متاحا.",
+       "apihelp-query+search-param-backend": "أية واجهة خلفية للبحث مستخدمة، إن لم تكن الافتراضية.",
+       "apihelp-query+search-param-enablerewrites": "تمكين إعادة كتابة الاستعلام الداخلية، يمكن لبعض الواجهات الخلفية البحث إعادة كتابة الاستعلام إلى آخر يُعتَقد أنه يوفر نتائج أفضل، على سبيل المثال عن طريق تصحيح الأخطاء الإملائية.",
+       "apihelp-query+search-param-sort": "تعيين ترتيب الفرز للنتائج التي تم إرجاعها.",
+       "apihelp-query+search-example-simple": "البحث عن <kbd>meaning</kbd>.",
+       "apihelp-query+search-example-text": "البحث في النصوص عن <kbd>meaning</kbd>.",
+       "apihelp-query+search-example-generator": "احصل على معلومات الصفحة حول الصفحات التي تم إرجاعها للبحث عن <kbd>meaning</kbd>.",
+       "apihelp-query+siteinfo-summary": "إرجاع معلومات عامة حول الموقع.",
+       "apihelp-query+siteinfo-param-prop": "أي المعلومات للحصول عليها:",
+       "apihelp-query+siteinfo-paramvalue-prop-general": "معلومات النظام الشاملة.",
+       "apihelp-query+siteinfo-paramvalue-prop-namespaces": "قائمة النطاقات المسجلة وأسمائها الأساسية.",
+       "apihelp-query+siteinfo-paramvalue-prop-namespacealiases": "قائمة الاسماء المستعارة المسجلة للنطاقات.",
+       "apihelp-query+siteinfo-paramvalue-prop-specialpagealiases": "قائمة الأسماء المستعارة للصفحات الخاصة.",
+       "apihelp-query+siteinfo-paramvalue-prop-magicwords": "قائمة الكلمات السحرية وأسمائها المستعارة.",
+       "apihelp-query+siteinfo-paramvalue-prop-statistics": "يعيد إحصائيات الموقع.",
+       "apihelp-query+siteinfo-paramvalue-prop-interwikimap": "يرجع خريطة الإنترويكي (يتم ترشيحها اختياريا، ويتم اختيارها اختياريا باستخدام <var>$1inlanguagecode</var>).",
+       "apihelp-query+siteinfo-paramvalue-prop-dbrepllag": "يرجع خادم قاعدة البيانات مع تأخر النسخ المتماثل الأعلى.",
+       "apihelp-query+siteinfo-paramvalue-prop-usergroups": "يرجع مجموعات المستخدمين والصلاحيات المرتبطة.",
+       "apihelp-query+siteinfo-paramvalue-prop-libraries": "يرجع المكتبات المثبتة على الويكي.",
+       "apihelp-query+siteinfo-paramvalue-prop-extensions": "يرجع الإضافات المثبتة على الويكي.",
+       "apihelp-query+siteinfo-paramvalue-prop-fileextensions": "يرجع قائمة امتدادات الملفات (أنواع الملفات) المسموح برفعها.",
+       "apihelp-query+siteinfo-paramvalue-prop-rightsinfo": "يرجع معلومات حقوق (ترخيص) الويكي إن كانت متاحة.",
+       "apihelp-query+siteinfo-paramvalue-prop-restrictions": "يرجع المعلومات حول أنواع القيود (الحماية) المتاحة.",
+       "apihelp-query+siteinfo-paramvalue-prop-languages": "يعرض قائمة اللغات التي يدعمها ميدياويكي (مترجمة اختياريا باستخدام <var>$1inlanguagecode</var>).",
+       "apihelp-query+siteinfo-paramvalue-prop-languagevariants": "يعرض قائمة بأكواد اللغات التي يتم تمكين [[mw:Special:MyLanguage/LanguageConverter|LanguageConverter]] بها، والمتغيرات المدعومة المختلفة لكل منها.",
+       "apihelp-query+siteinfo-paramvalue-prop-skins": "يعرض قائمة بجميع المظاهر الممكَّنة (مترجمة اختياريا باستخدام <var>$1inlanguagecode</var>، بخلاف لغة المحتوى).",
+       "apihelp-query+siteinfo-paramvalue-prop-extensiontags": "يعرض قائمة وسوم امتداد المحلل.",
+       "apihelp-query+siteinfo-paramvalue-prop-functionhooks": "يرجع قائمة خطاطيف دالة المحلل.",
+       "apihelp-query+siteinfo-paramvalue-prop-showhooks": "يعرض قائمة بكل الخطاطيف المشتركة (محتويات <var>[[mw:Special:MyLanguage/Manual:$wgHooks|$wgHooks]]</var>).",
+       "apihelp-query+siteinfo-paramvalue-prop-variables": "يعرض قائمة بمعرفات المتغيرات.",
+       "apihelp-query+siteinfo-paramvalue-prop-protocols": "يعرض قائمة بالبروتوكولات المسموح بها في الروابط الخارجية.",
+       "apihelp-query+siteinfo-paramvalue-prop-defaultoptions": "يعرض القيم الافتراضية لتفضيلات المستخدم.",
+       "apihelp-query+siteinfo-paramvalue-prop-uploaddialog": "يعرض تكوين مربع حوار الرفع.",
+       "apihelp-query+siteinfo-param-filteriw": "إرجاع الإدخالات المحلية أو غير المحلية فقط بخريطة الإنترويكي.",
+       "apihelp-query+siteinfo-param-showalldb": "سرد جميع خوادم قواعد البيانات، وليست فقط واحدة تخلفت أكثر.",
+       "apihelp-query+siteinfo-param-numberingroup": "يسرد عدد المستخدمين في مجموعات المستخدمين.",
+       "apihelp-query+siteinfo-param-inlanguagecode": "رمز اللغة لأسماء اللغة المترجمة (أفضل جهد) وأسماء المظاهر.",
+       "apihelp-query+siteinfo-example-simple": "إحضار معلومات الموقع.",
+       "apihelp-query+siteinfo-example-interwiki": "إحضار قائمة ببادئات الإنترويكي المحلية.",
+       "apihelp-query+siteinfo-example-replag": "تحقق من تأخر النسخ المتماثل الحالي.",
+       "apihelp-query+stashimageinfo-summary": "يرجع معلومات الملف للملفات المملوءة.",
+       "apihelp-query+stashimageinfo-param-filekey": "المفتاح الذي يحدد التحميل السابق المخزن مؤقتا.",
+       "apihelp-query+stashimageinfo-param-sessionkey": "الاسم المستعار لـ$1filekey; للتوافق مع الإصدارات السابقة.",
+       "apihelp-query+stashimageinfo-example-simple": "يرجع معلومات لملف مملوء.",
+       "apihelp-query+stashimageinfo-example-params": "يرجع الصور المصغرة لملفين مخزنين.",
+       "apihelp-query+tags-summary": "سرد وسوم التغيير.",
+       "apihelp-query+tags-param-limit": "الحد الأقصى لعدد الوسوم لإدراجها.",
+       "apihelp-query+tags-param-prop": "أي الخصائص للحصول عليها.",
+       "apihelp-query+tags-paramvalue-prop-name": "يضيف اسم الوسم.",
+       "apihelp-query+tags-paramvalue-prop-displayname": "يضيف رسالة نظام للوسم.",
+       "apihelp-query+tags-paramvalue-prop-description": "يضيف وصف الوسم.",
+       "apihelp-query+tags-paramvalue-prop-hitcount": "يضيف عدد المراجعات وإدخالات السجلات التي تحتوي على هذا الوسم.",
+       "apihelp-query+tags-paramvalue-prop-defined": "حدد ما إذا كانت الوسم محددا.",
+       "apihelp-query+tags-paramvalue-prop-source": "الحصول على مصادر الوسم، والتي قد تتضمن <samp>extension</samp>  للوسوم المعرفة بالامتداد و<samp>manual</samp> للوسوم التي قد يتم تطبيقها يدويا من قبل المستخدمين.",
+       "apihelp-query+tags-paramvalue-prop-active": "ما إذا كان الوسم لا يزال قيد التطبيق.",
+       "apihelp-query+tags-example-simple": "سرد الوسوم المتاحة.",
+       "apihelp-query+templates-summary": "يعرض جميع الملفات المضمنة في الصفحات المعينة.",
+       "apihelp-query+templates-param-namespace": "إظهار القوالب في هذه النطاقات فقط.",
+       "apihelp-query+templates-param-limit": "كم عدد القوالب للعودة.",
+       "apihelp-query+templates-param-templates": "إدراج هذه القوالب فقط، مفيد للتحقق ما إذا كانت صفحة معينة تستخدم قالبا معينا.",
+       "apihelp-query+templates-param-dir": "الاتجاه للإدراج فيه.",
+       "apihelp-query+templates-example-simple": "احصل على القوالب المستخدمة في الصفحة <kbd>Main Page</kbd>.",
+       "apihelp-query+templates-example-generator": "احصل على معلومات حول صفحات القوالب المستخدمة في <kbd>Main Page</kbd>.",
+       "apihelp-query+templates-example-namespaces": "احصل على صفحات في نطاقي {{ns:user}} و{{ns:template}} المضمنة في الصفحة <kbd>Main Page</kbd>.",
+       "apihelp-query+tokens-summary": "الحصول على الرموز المميزة لإجراءات تعديل البيانات.",
+       "apihelp-query+tokens-param-type": "أنواع الرمز المميز للطلب.",
+       "apihelp-query+tokens-example-simple": "استرداد رمز csrf (الافتراضي).",
+       "apihelp-query+tokens-example-types": "استرجع رمز مراقبة ورمز مراجعة.",
+       "apihelp-query+transcludedin-summary": "ابحث عن جميع الصفحات التي تتضمن الصفحات المعينة.",
+       "apihelp-query+transcludedin-param-prop": "أي الخصائص للحصول عليها.",
+       "apihelp-query+transcludedin-paramvalue-prop-pageid": "معرف الصفحة لكل صفحة.",
+       "apihelp-query+transcludedin-paramvalue-prop-title": "عنوان كل صفحة.",
+       "apihelp-query+transcludedin-paramvalue-prop-redirect": "علم إذا كانت الصفحة تحويلة.",
+       "apihelp-query+transcludedin-param-namespace": "إدراج الصفحات في هذه النطاقات فقط.",
+       "apihelp-query+transcludedin-param-limit": "كم العدد للعودة.",
+       "apihelp-query+transcludedin-param-show": "إظهار العناصر التي تستوفي هذه المعايير فقط:\n;تحويلة: عرض التحويلات فقط.\n;!تحويلة:إظهار غير التحويلات فقط.",
+       "apihelp-query+transcludedin-example-simple": "احصل على قائمة بالصفحات التي تتضمن <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-start": "الطابع الزمني للبدء للعودة منه.",
+       "apihelp-query+usercontribs-param-end": "الطابع الزمني للانتهاء للعودة إليه.",
+       "apihelp-query+usercontribs-param-user": "المستخدمون لاسترداد مساهمات لهم، لا يمكن استخدامه مع <var>$1userids</var> أو <var>$1userprefix</var>.",
+       "apihelp-query+usercontribs-param-userprefix": "استرداد المساهمات لجميع المستخدمين الذين تبدأ أسماؤهم بهذه القيمة، لا يمكن استخدامه مع <var>$1user</var> أو <var>$1userids</var>.",
+       "apihelp-query+usercontribs-param-userids": "معرفات المستخدم لاسترداد المساهمات لهم، لا يمكن استخدامه مع <var>$1user</var> أو <var>$1userprefix</var>.",
+       "apihelp-query+usercontribs-param-namespace": "إدراج المساهمات في هذه النطاقات فقط.",
+       "apihelp-query+usercontribs-param-prop": "تضمين أجزاء إضافية من المعلومات:",
+       "apihelp-query+usercontribs-paramvalue-prop-ids": "يضيف معرف الصفحة ومعرف المراجعة.",
+       "apihelp-query+usercontribs-paramvalue-prop-title": "يضيف معرف عنوان ونطاق الصفحة.",
+       "apihelp-query+usercontribs-paramvalue-prop-timestamp": "يضيف الطابع الزمني للتحرير.",
+       "apihelp-query+usercontribs-paramvalue-prop-comment": "يضيف تعليق التعديل.",
+       "apihelp-query+usercontribs-paramvalue-prop-parsedcomment": "يضيف التعليق المحلل للتحرير.",
+       "apihelp-query+usercontribs-paramvalue-prop-size": "يضيف الحجم الجديد للتحرير.",
+       "apihelp-query+usercontribs-paramvalue-prop-sizediff": "يضيف حجم دلتا التعديل ضد الأصل.",
+       "apihelp-query+usercontribs-paramvalue-prop-flags": "يضيف علامات التحرير.",
+       "apihelp-query+usercontribs-paramvalue-prop-patrolled": "يوسم التعديلات المراجعة.",
+       "apihelp-query+usercontribs-paramvalue-prop-autopatrolled": "يوسم التعديلات المراجعة تلقائيا.",
+       "apihelp-query+usercontribs-paramvalue-prop-tags": "يسرد وسوما للتحرير.",
+       "apihelp-query+usercontribs-param-show": "عرض العناصر التي تستوفي هذه المعايير فقط، مثل التعديلات الطفيفة فقط: <kbd>$2show=!minor</kbd>.\n\nإذا تم تعيين <kbd>$2show=patrolled</kbd> or <kbd>$2show=!patrolled</kbd>، فإن المراجعات أقدم من <var>[[mw:Special:MyLanguage/Manual:$wgRCMaxAge|$wgRCMaxAge]]</var> ($1 {{PLURAL:$1|ثانية|ثوانٍ}}) لن يتم عرضها.",
+       "apihelp-query+usercontribs-param-tag": "إدراج المراجعات الموسومة بهذ الوسم فقط.",
+       "apihelp-query+usercontribs-param-toponly": "سرد التغييرات التي هي أحدث مراجعة فقط.",
+       "apihelp-query+usercontribs-example-user": "عرض مساهمات المستخدم <kbd>Example</kbd>.",
+       "apihelp-query+usercontribs-example-ipprefix": "عرض المساهمات من جميع عناوين الآيبي بالبادئة <kbd>192.0.2.</kbd>.",
+       "apihelp-query+userinfo-summary": "الحصول على معلومات حول المستخدم الحالي.",
+       "apihelp-query+userinfo-param-prop": "أية قطعة من المعلومات لتضمينها:",
+       "apihelp-query+userinfo-paramvalue-prop-blockinfo": "يوسم إذا تم منع المستخدم الحالي، من قبل أي شخص، ولأي سبب.",
+       "apihelp-query+userinfo-paramvalue-prop-hasmsg": "يضيف وسم <samp>messages</samp> إذا كان المستخدم الحالي لديه رسائل معلقة.",
+       "apihelp-query+userinfo-paramvalue-prop-groups": "يسرد كل المجموعات التي ينتمي إليها المستخدم الحالي.",
+       "apihelp-query+userinfo-paramvalue-prop-groupmemberships": "يسرد المجموعات التي تم تعيينها للمستخدم بشكل صريح، بما في ذلك تاريخ انتهاء عضوية كل مجموعة.",
+       "apihelp-query+userinfo-paramvalue-prop-implicitgroups": "يسرد جميع المجموعات التي يكون المستخدم الحالي عضوا فيها تلقائيا.",
+       "apihelp-query+userinfo-paramvalue-prop-rights": "يسرد جميع الصلاحيات التي يمتلكها المستخدم الحالي.",
+       "apihelp-query+userinfo-paramvalue-prop-changeablegroups": "يسرد المجموعات التي يمكن للمستخدم الحالي الإضافتة والإزالة منها.",
+       "apihelp-query+userinfo-paramvalue-prop-options": "يسرد جميع التفضيلات التي قام المستخدم الحالي بتعيينها.",
+       "apihelp-query+userinfo-paramvalue-prop-preferencestoken": "الحصول على رمز لتغيير تفضيلات المستخدم الحالي.",
+       "apihelp-query+userinfo-paramvalue-prop-editcount": "يضيف عدد تحرير المستخدم الحالي.",
+       "apihelp-query+userinfo-paramvalue-prop-ratelimits": "يسرد جميع حدود المعدل المطبقة على المستخدم الحالي.",
+       "apihelp-query+userinfo-paramvalue-prop-realname": "يضيف اسم المستخدم الحقيقي.",
+       "apihelp-query+userinfo-paramvalue-prop-email": "يضيف عنوان البريد الإلكتروني للمستخدم وتاريخ مصادقة البريد الإلكتروني.",
+       "apihelp-query+userinfo-paramvalue-prop-acceptlang": "يكرر الرأس <code>Accept-Language</code> الذي يرسله العميل بتنسيق منظم.",
+       "apihelp-query+userinfo-paramvalue-prop-registrationdate": "يضيف تاريخ تسجيل المستخدم.",
+       "apihelp-query+userinfo-paramvalue-prop-unreadcount": "يضيف عدد الصفحات غير المقروءة في قائمة مراقبة المستخدم (بحد أقصى $1; ترجع <samp>$2</samp> إذا كان أكثر).",
+       "apihelp-query+userinfo-paramvalue-prop-centralids": "يضيف المعرفات المركزية وحالة المرفقات للمستخدم.",
+       "apihelp-query+userinfo-param-attachedwiki": "باستخدام <kbd>$1prop=centralids</kbd>، حدد ما إذا كان المستخدم مرتبطا بالويكي المحدد بواسطة هذا المعرف.",
+       "apihelp-query+userinfo-example-simple": "الحصول على معلومات حول المستخدم الحالي.",
+       "apihelp-query+userinfo-example-data": "الحصول على معلومات حول المستخدم الحالي.",
+       "apihelp-query+users-summary": "الحصول على معلومات حول قائمة المستخدمين.",
+       "apihelp-query+users-param-prop": "أية قطعة من المعلومات لتضمينها:",
+       "apihelp-query+users-paramvalue-prop-blockinfo": "يوسم إذا تم منع المستخدم الحالي، من قبل أي شخص، ولأي سبب.",
+       "apihelp-query+users-paramvalue-prop-groups": "يسرد كل المجموعات التي ينتمي إليها كل مستخدم.",
+       "apihelp-query+users-paramvalue-prop-groupmemberships": "يسرد المجموعات التي تم تعيينها للمستخدم بشكل صريح، بما في ذلك تاريخ انتهاء عضوية كل مجموعة.",
+       "apihelp-query+users-paramvalue-prop-implicitgroups": "يسرد كل المجموعات التي يوجد فيها المستخدم تلقائيا.",
+       "apihelp-query+users-paramvalue-prop-rights": "يسرد جميع الصلاحيات التي يمتلكها كل مستخدم.",
+       "apihelp-query+users-paramvalue-prop-editcount": "يضيف عدد تحرير المستخدم.",
+       "apihelp-query+users-paramvalue-prop-registration": "يضيف الطابع الزمني للتسجيل للمستخدم.",
+       "apihelp-query+users-paramvalue-prop-emailable": "يوسم إذا كان المستخدم يستطيع ويرغب في تلقي البريد الإلكتروني من خلال [[Special:Emailuser]].",
+       "apihelp-query+users-paramvalue-prop-gender": "يوسم الجنس من المستخدم: يرجع \"ذكر\" أو \"أنثى\" أو \"غير معروف\".",
+       "apihelp-query+users-paramvalue-prop-centralids": "يضيف المعرفات المركزية وحالة المرفقات للمستخدم.",
+       "apihelp-query+users-paramvalue-prop-cancreate": "يشير إلى ما إذا كان يمكن إنشاء حساب لأسماء مستخدمين صالحة ولكن غير مسجلة.",
+       "apihelp-query+users-param-attachedwiki": "باستخدام <kbd>$1prop=centralids</kbd>، حدد ما إذا كان المستخدم مرتبطا بالويكي المحدد بواسطة هذا المعرف.",
+       "apihelp-query+users-param-users": "قائمة من المستخدمين للحصول على معلومات عنهم.",
+       "apihelp-query+users-param-userids": "قائمة معرفات المستخدمين للحصول على معلومات عنهم.",
+       "apihelp-query+users-param-token": "استخدم [[Special:ApiHelp/query+tokens|action=query&meta=tokens]] بدلا من ذلك.",
+       "apihelp-query+users-example-simple": "عودة المعلومات للمستخدم <kbd>Example</kbd>.",
+       "apihelp-query+watchlist-summary": "احصل على أحدث التغييرات على الصفحات في قائمة مراقبة المستخدم الحالي.",
+       "apihelp-query+watchlist-param-allrev": "تضمين مراجعات متعددة لنفس الصفحة في إطار زمني محدد.",
+       "apihelp-query+watchlist-param-start": "الطابع الزمني لبدء العد منه.",
+       "apihelp-query+watchlist-param-end": "الطابع الزمني لإنهاء التعداد.",
+       "apihelp-query+watchlist-param-namespace": "تصفية التغييرات على النطاقات المعطاة فقط.",
+       "apihelp-query+watchlist-param-user": "إددراج التغييرات بواسطة هذا المستخدم فقط.",
+       "apihelp-query+watchlist-param-excludeuser": "لا تسرد التغييرات بواسطة هذا المستخدم.",
+       "apihelp-query+watchlist-param-limit": "إجمالي عدد النتائج لإرجاعها لكل طلب.",
+       "apihelp-query+watchlist-param-prop": "أي الخصائص الإضافية للحصول عليها:",
+       "apihelp-query+watchlist-paramvalue-prop-ids": "يضيف معرفات المراجعات ومعرفات الصفحات.",
+       "apihelp-query+watchlist-paramvalue-prop-title": "يضيف عنوان الصفحة.",
+       "apihelp-query+watchlist-paramvalue-prop-flags": "يضيف علامات للتحرير.",
+       "apihelp-query+watchlist-paramvalue-prop-user": "يضيف المستخدم الذي قام بالتعديل.",
+       "apihelp-query+watchlist-paramvalue-prop-userid": "يضيف معرف المستخدم الذي أجرى التعديل.",
+       "apihelp-query+watchlist-paramvalue-prop-comment": "يضيف تعليق التعديل.",
+       "apihelp-query+watchlist-paramvalue-prop-parsedcomment": "يضيف التعليق المحلل للتحرير.",
+       "apihelp-query+watchlist-paramvalue-prop-timestamp": "يضيف الطابع الزمني للتحرير.",
+       "apihelp-query+watchlist-paramvalue-prop-patrol": "يوسم التعديلات المراجعة.",
+       "apihelp-query+watchlist-paramvalue-prop-autopatrol": "يوسم التعديلات المراجعة تلقائيا.",
+       "apihelp-query+watchlist-paramvalue-prop-sizes": "يضيف الأطوال القديمة والجديدة للصفحة.",
+       "apihelp-query+watchlist-paramvalue-prop-notificationtimestamp": "يإضيف الطابع الزمني عندما تم إبلاغ المستخدم آخر مرة عن التعديل.",
+       "apihelp-query+watchlist-paramvalue-prop-loginfo": "يضيف معلومات السجل عند الاقتضاء.",
+       "apihelp-query+watchlist-paramvalue-prop-tags": "يسرد الوسوم للدخول.",
+       "apihelp-query+watchlist-param-show": "إظهار العناصر التي تستوفي هذه المعايير فقط، على سبيل المثال، مشاهدة التعديلات الطفيفة فقط التي قام بها المستخدمون مسجلو الدخول، قم بتعيين $1show=minor|!anon.",
+       "apihelp-query+watchlist-param-type": "أي أنواع التغييرات لعرضها.",
+       "apihelp-query+watchlist-paramvalue-type-edit": "تعديلات الصفحة العادية.",
+       "apihelp-query+watchlist-paramvalue-type-external": "التغييرات الخارجية.",
+       "apihelp-query+watchlist-paramvalue-type-new": "إنشاء الصفحات.",
+       "apihelp-query+watchlist-paramvalue-type-log": "ادخالات السجلات.",
+       "apihelp-query+watchlist-paramvalue-type-categorize": "تغييرات عضوية التصنيف.",
+       "apihelp-query+watchlist-param-owner": "يًستخدَم مع $1token للوصول إلى قائمة مراقبة مستخدم مختلف.",
+       "apihelp-query+watchlist-param-token": "رمز أمان (متوفر في [[Special:Preferences#mw-prefsection-watchlist|التفضيلات]]) للسماح بالوصول إلى قائمة مراقبة مستخدم آخر.",
+       "apihelp-query+watchlist-example-simple": "أدرج أعلى مراجعة للصفحات التي تم تغييرها مؤخرا في قائمة مراقبة المستخدم الحالية.",
+       "apihelp-query+watchlist-example-props": "احصل على معلومات إضافية حول المراجعة العليا للصفحات التي تم تغييرها مؤخرا في قائمة مراقبة المستخدم الحالية.",
+       "apihelp-query+watchlist-example-allrev": "يمكنك جلب معلومات حول جميع التغييرات الأخيرة على الصفحات في قائمة مراقبة المستخدم الحالي.",
+       "apihelp-query+watchlist-example-generator": "جلب معلومات الصفحة للصفحات التي تم تغييرها مؤخرا في قائمة مراقبة المستخدم الحالية.",
+       "apihelp-query+watchlist-example-generator-rev": "جلب معلومات المراجعة للتغييرات الأخيرة على الصفحات في قائمة مراقبة المستخدم الحالي.",
+       "apihelp-query+watchlist-example-wlowner": "أدرج أعلى مراجعة للصفحات التي تم تغييرها مؤخرا في قائمة مراقبة المستخدم <kbd>Example</kbd>.",
+       "apihelp-query+watchlistraw-summary": "الحصول على جميع صفحات قائمة مراقبة المستخدم الحالي.",
+       "apihelp-query+watchlistraw-param-namespace": "إدراج عناوين في النطاقات المعطاة فقط.",
+       "apihelp-query+watchlistraw-param-limit": "كم الإجمالي العدد للنتائج لإرجاعها لكل طلب.",
+       "apihelp-query+watchlistraw-param-prop": "أي الخصائص الإضافية للحصول عليها:",
+       "apihelp-query+watchlistraw-paramvalue-prop-changed": "يإضيف الطابع الزمني عندما تم إبلاغ المستخدم آخر مرة عن التعديل.",
+       "apihelp-query+watchlistraw-param-show": "إدراج العناصر التي تفي بهذه المعايير فقط.",
+       "apihelp-query+watchlistraw-param-owner": "يًستخدَم مع $1token للوصول إلى قائمة مراقبة مستخدم مختلف.",
+       "apihelp-query+watchlistraw-param-token": "رمز أمان (متوفر في [[Special:Preferences#mw-prefsection-watchlist|التفضيلات]]) للسماح بالوصول إلى قائمة مراقبة مستخدم آخر.",
+       "apihelp-query+watchlistraw-param-dir": "الاتجاه للإدراج فيه.",
+       "apihelp-query+watchlistraw-param-fromtitle": "العنوان (مع بادئة النطاق) لبدء العد منه.",
+       "apihelp-query+watchlistraw-param-totitle": "العنوان (مع بادئة النطاق) لإيقاف العد عنده.",
+       "apihelp-query+watchlistraw-example-simple": "سرد الصفحات في قائمة مراقبة المستخدم الحالي.",
+       "apihelp-query+watchlistraw-example-generator": "جلب معلومات الصفحة للصفحات في قائمة مراقبة المستخدم الحالية.",
+       "apihelp-removeauthenticationdata-summary": "إزالة بيانات المصادقة للمستخدم الحالي.",
+       "apihelp-removeauthenticationdata-example-simple": "محاولة إزالة بيانات المستخدم الحالي لـ<kbd>FooAuthenticationRequest</kbd>.",
+       "apihelp-resetpassword-summary": "إرسال بريد إلكتروني لإعادة تعيين كلمة المرور إلى مستخدم.",
+       "apihelp-resetpassword-extended-description-noroutes": "لا تتوفر طرق إعادة تعيين كلمة المرور.\n\nتمكين المسارات في <var>[[mw:Special:MyLanguage/Manual:$wgPasswordResetRoutes|$wgPasswordResetRoutes]]</var> لاستخدام هذه الوحدة.",
+       "apihelp-resetpassword-param-user": "تجري إعادة تعيين المستخدم.",
+       "apihelp-resetpassword-param-email": "تجري إعادة ضبط عنوان البريد الإلكتروني للمستخدم.",
+       "apihelp-resetpassword-example-user": "إرسال بريد إلكتروني لإعادة تعيين كلمة المرور إلى المستخدم <kbd>Example</kbd>.",
+       "apihelp-resetpassword-example-email": "رسال بريد إلكتروني لإعادة تعيين كلمة المرور لجميع المستخدمين الذين لديهم عنوان البريد الإلكتروني <kbd>user@example.com</kbd>.",
+       "apihelp-revisiondelete-summary": "حذف واسترجاع المراجعات.",
+       "apihelp-revisiondelete-param-type": "نوع حذف المراجعة الذي يتم تنفيذه.",
+       "apihelp-revisiondelete-param-target": "عنوان الصفحة لحذف المراجعة، إذا كان مطلوبا للنوع.",
+       "apihelp-revisiondelete-param-ids": "المعرفات للمراجعات لحذفها.",
+       "apihelp-revisiondelete-param-hide": "ماذا نختبئ لكل مراجعة.",
+       "apihelp-revisiondelete-param-show": "ما الذي يجب إظهاره لكل مراجعة.",
+       "apihelp-revisiondelete-param-suppress": "سواء إخفاء البيانات من الإداريين وكذلك الآخرين.",
+       "apihelp-revisiondelete-param-reason": "سبب للحذف أو الاسترجاع.",
+       "apihelp-revisiondelete-param-tags": "وسوم لتطبيقها على الإدخال في سجل الحذف.",
+       "apihelp-revisiondelete-example-revision": "إخفاء محتوى المراجعة <kbd>12345</kbd> في الصفحة <kbd>Main Page</kbd>.",
+       "apihelp-revisiondelete-example-log": "إخفاء كافة البيانات الموجودة في إدخال السجل <kbd>67890</kbd> بسبب <kbd>BLP violation</kbd>.",
+       "apihelp-rollback-summary": "التراجع عن آخر تعديل على الصفحة.",
+       "apihelp-rollback-extended-description": "إذا قام المستخدم الأخير الذي قام بتحرير الصفحة بإجراء تعديلات متعددة في صف، فسوف يتم استرجاعها مرة أخرى.",
+       "apihelp-rollback-param-title": "عنوان الصفحة للتراجع، لا يمكن استخدامه مع <var>$1project</var>.",
+       "apihelp-rollback-param-pageid": "معرف الصفحة للصفحة للتراجع، لا يمكن استخدامه مع <var>$1project</var>.",
+       "apihelp-rollback-param-tags": "وسوم للتطبيق على التراجع.",
+       "apihelp-rollback-param-user": "اسم المستخدم الذي سيتم إرجاع تعديلاته.",
+       "apihelp-rollback-param-summary": "ملخص تعديل مخصص، إذا كان فارغا، سيتم استخدام الملخص الافتراضي.",
+       "apihelp-rollback-param-markbot": "تعليم التعديلات المسترجعة كتعديلات بوت.",
+       "apihelp-rollback-param-watchlist": "إضافة أو إزالة الصفحة من قائمة مراقبة المستخدم الحالي أو استخدام التفضيلات أو عدم تغيير المراقبة بدون شروط.",
+       "apihelp-rollback-example-simple": "استرجاع التعديلات الأخيرة على الصفحة<kbd>Main Page</kbd> بواسطة المستخدم <kbd>Example</kbd>.",
+       "apihelp-rollback-example-summary": "استرجاع التعديلات الأخيرة على صفحة <kbd>Main Page</kbd>بواسطة مستخدم الآيبي <kbd>192.0.2.5</kbd> بالملخص <kbd>Reverting vandalism</kbd>، وتعليم تلك التعديلات والاسترجاع كتعديلات بوت.",
+       "apihelp-rsd-summary": "تصدير مخطط RSD (اكتشاف بسيط حقا).",
+       "apihelp-rsd-example-simple": "تصدير مخطط RSD.",
+       "apihelp-setnotificationtimestamp-summary": "تحديث الطابع الزمني للإخطار للصفحات المراقبة.",
+       "apihelp-setnotificationtimestamp-extended-description": "يؤثر هذا على إبراز الصفحات التي تم تغييرها في قائمة المراقبة والتاريخ، وإرسال البريد الإلكتروني عند تمكين التفضيل  \"{{int:tog-enotifwatchlistpages}}\".",
+       "apihelp-setnotificationtimestamp-param-entirewatchlist": "العمل على جميع الصفحات المراقبة.",
+       "apihelp-setnotificationtimestamp-param-timestamp": "الطابع الزمني الذي لتعيين الطابع الزمني للإشعار.",
+       "apihelp-setnotificationtimestamp-param-torevid": "مراجعة لضبط الطابع الزمني للإشعار عليها (صفحة واحدة فقط).",
+       "apihelp-setnotificationtimestamp-param-newerthanrevid": "مراجعة لضبط الطابع الزمني للإشعار الأحدث منها (صفحة واحدة فقط).",
+       "apihelp-setnotificationtimestamp-example-all": "إعادة تعيين حالة الإشعار لقائمة المراقبة بأكملها.",
+       "apihelp-setnotificationtimestamp-example-page": "إعادة ضبط حالة الإخطار لـ<kbd>Main page</kbd>.",
+       "apihelp-setnotificationtimestamp-example-pagetimestamp": "تعيين الطابع الزمني للإشعار للصفحة <kbd>Main page</kbd> حتى لا يتم عرض جميع التعديلات منذ 1 يناير 2012.",
+       "apihelp-setnotificationtimestamp-example-allpages": "إعادة تعيين حالة الإشعار للصفحات في نطاق <kbd>{{ns:user}}</kbd>.",
+       "apihelp-setpagelanguage-summary": "تغيير لغة صفحة.",
+       "apihelp-setpagelanguage-extended-description-disabled": "لا يُسمَح بتغيير لغة صفحة في هذا الويكي.\n\nتمكين <var>[[mw:Special:MyLanguage/Manual:$wgPageLanguageUseDB|$wgPageLanguageUseDB]] لاستخدام هذا الإجراء.",
+       "apihelp-setpagelanguage-param-title": "عنوان الصفحة التي ترغب في تغيير لغتها، لا يمكن استخدامه مع <var>$1pageid</var>.",
+       "apihelp-setpagelanguage-param-pageid": "معرف الصفحة للصفحة التي ترغب في تغيير لغتها، لا يمكن استخدامه مع <var>$1title</var>.",
+       "apihelp-setpagelanguage-param-lang": "كود اللغة للغة لتغيير الصفحة إليها، استخدم <kbd>default</kbd> لإعادة تعيين الصفحة إلى لغة محتوى الويكي.",
+       "apihelp-setpagelanguage-param-reason": "سبب للتغيير.",
+       "apihelp-setpagelanguage-param-tags": "تغيير الوسوم لتطبيقها على إدخال السجل الناتج عن هذا الإجراء.",
+       "apihelp-setpagelanguage-example-language": "تغيير لغة <kbd>Main Page</kbd> إلى لغة الباسك.",
+       "apihelp-setpagelanguage-example-default": "تغيير لغة الصفحة بمعرف 123 إلى لغة محتوى الويكي الافتراضية.",
+       "apihelp-stashedit-summary": "إعداد تحرير في ذاكرة التخزين المؤقت المشتركة.",
+       "apihelp-stashedit-extended-description": "يهدف هذا إلى الاستخدام عبر AJAX من نموذج التحرير لتحسين أداء حفظ الصفحة.",
+       "apihelp-stashedit-param-title": "عنوان الصفحة التي يتم تحريرها.",
+       "apihelp-stashedit-param-section": "رقم القسم. <kbd>0</kbd> للقسم العلوي، <kbd>new</kbd> لقسم جديد.",
+       "apihelp-stashedit-param-sectiontitle": "العنوان لقسم جديد.",
+       "apihelp-stashedit-param-text": "محتوى الصفحة.",
+       "apihelp-stashedit-param-stashedtexthash": "رمز رقم محتوى الصفحة من وحدة تخزين سابقة لاستخدامها بدلا من ذلك.",
+       "apihelp-stashedit-param-contentmodel": "نموذج المحتوى للمحتوى الجديد.",
+       "apihelp-stashedit-param-contentformat": "نسق المحتوى التسلسلي المستخدم لنص المدخلات.",
+       "apihelp-stashedit-param-baserevid": "معرف المراجعة للمراجعة الأساسية.",
+       "apihelp-stashedit-param-summary": "تغيير الملخص.",
+       "apihelp-tag-summary": "إضافة أو إزالة وسوم التغيير من المراجعات الفردية أو إدخالات السجلات.",
+       "apihelp-tag-param-rcid": "واحد أو أكثر من التغييرات الحديثة للمعرفات التي يمكن من خلالها إضافة أو إزالة الوسم.",
+       "apihelp-tag-param-revid": "معرف تعديل واحد أو أكثر يمكن من خلاله إضافة أو إزالة الوسم.",
+       "apihelp-tag-param-logid": "واحد أو أكثر من معرفات إدخال السجل يمكن من خلاله إضافة أو إزالة الوسم.",
+       "apihelp-tag-param-add": "وسوم للإضافة، يمكن فقط إضافة وسوم محددة يدويا.",
+       "apihelp-tag-param-remove": "وسوم لإزالتها، لا يمكن إزالة سوى الوسوم المعرفة يدويا أو غير المعرفة تماما.",
+       "apihelp-tag-param-reason": "سبب للتغيير.",
+       "apihelp-tag-param-tags": "وسوم لتطبيقها على إدخال السجل الذي سيتم إنشاؤه كنتيجة لهذا الإجراء.",
+       "apihelp-tag-example-rev": "أضف الوسم <kbd>vandalism</kbd> إلى معرّف المراجعة 123 بدون تحديد سبب",
+       "apihelp-tag-example-log": "إزالة الوسم <kbd>spam</kbd> من معرف إدخال السجل 123 بالسبب <kbd>Wrongly applied</kbd>",
+       "apihelp-tokens-summary": "الحصول على الرموز المميزة لإجراءات تعديل البيانات.",
+       "apihelp-tokens-extended-description": "تم إهمال هذه الوحدة لصالح [[Special:ApiHelp/query+tokens|action=query&meta=tokens]].",
+       "apihelp-tokens-param-type": "أنواع الرمز المميز للطلب.",
+       "apihelp-tokens-example-edit": "استرداد رمز تحرير (الافتراضي).",
+       "apihelp-tokens-example-emailmove": "استرداد رمز بريد إلكتروني ورمز نقل.",
+       "apihelp-unblock-summary": "إلغاء منع المستخدم.",
+       "apihelp-unblock-param-id": "معرف المنع لرفع المنع (تم الحصول عليه من خلال <kbd>list=blocks</kbd>)، لا يمكن استخدامه مع <var>$1user</var> أو <var>$1userid</var>.",
+       "apihelp-unblock-param-user": "اسم المستخدم، أو عنوان آيبي أو نطاق عنوان آيبي لمنعه، لا يمكن أن يُستخدَم جنبا إلى جنب مع <var>$1id</var> أو <var>$1userid</var>.",
+       "apihelp-unblock-param-userid": "معرف الآيبي لرفع منعه، لا يمكن أن يُستخدَم جنبا إلى جنب مع <var>$1id</var> أو <var>$1user</var>.",
+       "apihelp-unblock-param-reason": "سبب لرفع للمنع.",
+       "apihelp-unblock-param-tags": "تغيير الوسوم للتطبيق على الإدخال في سجل المنع.",
+       "apihelp-unblock-example-id": "رفع منع المعرف #<kbd>105</kbd>.",
+       "apihelp-unblock-example-user": "رفع منع المستخدم <kbd>Bob</kbd> بالسبب <kbd>Sorry Bob</kbd>.",
+       "apihelp-undelete-summary": "استعادة مراجعات صفحة محذوفة.",
+       "apihelp-undelete-extended-description": "يمكن استرداد قائمة المراجعات المحذوفة (بما في ذلك الطوابع الزمنية) من خلال [[Special:ApiHelp/query+deletedrevisions|prop=deletedrevisions]]، ويمكن استرداد قائمة معرفات الملفات المحذوفة من خلال [[Special:ApiHelp/query+filearchive|list=filearchive]].",
+       "apihelp-undelete-param-title": "عنوان الصفحة للاسترجاع.",
+       "apihelp-undelete-param-reason": "سبب للاسترجاع.",
+       "apihelp-undelete-param-tags": "تغيير وسوم لتطبيقها على الإدخال في سجل الحذف.",
+       "apihelp-undelete-param-timestamps": "الطوابع الزمنية للمراجعات للاسترجاع، إذا كانت كل من <var>$1timestamps</var> فارغة، فستتم استعادتها كلها.",
+       "apihelp-undelete-param-fileids": "الطوابع الزمنية لمراجعات الملف للاسترجاع، إذا كانت كل من <var>$1timestamps</var> فارغة، فستتم استعادتها كلها.",
+       "apihelp-undelete-param-watchlist": "إضافة أو إزالة الصفحة من قائمة مراقبة المستخدم الحالي أو استخدام التفضيلات أو عدم تغيير المراقبة بدون شروط.",
+       "apihelp-undelete-example-page": "استرجاع صفحة <kbd>Main Page</kbd>.",
+       "apihelp-undelete-example-revisions": "استرجاع مراجعتين لصفحة <kbd>Main Page</kbd>.",
+       "apihelp-unlinkaccount-summary": "إزالة حساب جهة خارجية مرتبط من المستخدم الحالي.",
+       "apihelp-unlinkaccount-example-simple": "محاولة إزالة رابط المستخدم الحالي للموفر المقترن بـ<kbd>FooAuthenticationRequest</kbd>.",
+       "apihelp-upload-summary": "رفع ملف أو الحصول على حالة المرفوعات المعلقة.",
+       "apihelp-upload-extended-description": "تتوفر عدة طرق: \n* ارفع محتويات الملف مباشرة، باستخدام الوسيط <var>$1file</var>.\n* ارفع الملف على أجزاء باستخدام الوسائط <var>$1filesize</var> و<var>$1chunk</var> و<var>$1offset</var>.\n*  اجعل خادم ميدياويكي يقوم بجلب ملف من مسار، باستخدام الوسيط <var>$1url</var>.\n*  أكمل عملية رفع سابقة فشلت بسبب التحذيرات، باستخدام الوسيط <var>$1filekey</var>.\nلاحظ أنه يجب إجراء HTTP POST كرفع ملف (أي استخدام <code>multipart/form-data</code>) عند إرسال <var>$1file</var>.",
+       "apihelp-upload-param-filename": "اسم الملف المستهدف.",
+       "apihelp-upload-param-comment": "تحميل تعليق الرفع، يُستخدَم أيضا كنص الصفحة الأولي للملفات الجديدة إذا لم يتم تحديد <var>$1text</var>.",
+       "apihelp-upload-param-tags": "غتيير الوسوم لتطبيقها على إدخال سجل الرفع ومراجعة صفحة الملف.",
+       "apihelp-upload-param-text": "النص الأولي للصفحة للملفات الجديدة.",
+       "apihelp-upload-param-watch": "راقب الصفحة.",
+       "apihelp-upload-param-watchlist": "إضافة أو إزالة الصفحة من قائمة مراقبة المستخدم الحالي أو استخدام التفضيلات أو عدم تغيير المراقبة بدون شروط.",
+       "apihelp-upload-param-ignorewarnings": "تجاهل أية تحذيرات.",
+       "apihelp-upload-param-file": "محتويات الملف.",
+       "apihelp-upload-param-url": "مسار لجلب الملف منه.",
+       "apihelp-upload-param-filekey": "المفتاح الذي يحدد التحميل السابق المخزن مؤقتا.",
+       "apihelp-upload-param-sessionkey": "نفس $1filekey، تتم صيانته للتوافق مع الإصدارات السابقة.",
+       "apihelp-upload-param-stash": "في حالة التعيين، سيخزن الخادم الملف مؤقتا بدلا من إضافته إلى المستودع.",
+       "apihelp-upload-param-filesize": "حجم ملف الرفع الكامل.",
+       "apihelp-upload-param-offset": "إزاحة القطعة بالبايت.",
+       "apihelp-upload-param-chunk": "محتويات القطعة.",
+       "apihelp-upload-param-async": "إجراء عمليات ملف كبيرة محتملة غير متزامنة عند الإمكان.",
+       "apihelp-upload-param-checkstatus": "فقط جلب حالة الرفع لمفتاح الملف المحدد.",
+       "apihelp-upload-example-url": "رفع من مسار.",
+       "apihelp-upload-example-filekey": "أكمل الرفع الذي أخفق بسبب التحذيرات.",
+       "apihelp-userrights-summary": "تغيير عضوية مجموعة المستخدم.",
+       "apihelp-userrights-param-user": "اسم المستخدم.",
+       "apihelp-userrights-param-userid": "معرف المستخدم.",
+       "apihelp-userrights-param-add": "أضف المستخدم إلى هذه المجموعات، أو إذا كان بالفعل عضوا، قم بتحديث صلاحية عضويته في تلك المجموعة.",
+       "apihelp-userrights-param-expiry": "الطوابع الزمنية لانتهاء الصلاحية، قد تكون نسبية (على سبيل المثال <kbd>5 months</kbd> or <kbd>2 weeks</kbd>) أو مطلقة (على سبيل المثال <kbd>2014-09-18T12:34:56Z</kbd>). إذا تم تعيين طابع زمني واحد فقط، فسيتم استخدامه لكافة المجموعات التي تم تمريرها إلى الوسيط <var>$1add</var>، استخدم <kbd>infinite</kbd> أو <kbd>indefinite</kbd> أو <kbd>infinity</kbd> أو <kbd>never</kbd> لمجموعة مستخدمين لا تنتهي صلاحيتها أبدا.",
+       "apihelp-userrights-param-remove": "أزل المستخدم من هذه المجموعات.",
+       "apihelp-userrights-param-reason": "سبب للتغيير.",
+       "apihelp-userrights-param-tags": "تغيير وسوم لتطبيقها على الإدخال في سجل صلاحيات المستخدم.",
+       "apihelp-userrights-example-user": "إضافة المستخدم <kbd>FooBot</kbd> إلى مجموعة <kbd>bot</kbd> وإزالته من المجموعات <kbd>sysop</kbd> و<kbd>bureaucrat</kbd>.",
+       "apihelp-userrights-example-userid": "إضافة المستخدم بالمعرف <kbd>123</kbd> إلى مجموعة <kbd>bot</kbd> وإزالته من المجموعات <kbd>sysop</kbd> و<kbd>bureaucrat</kbd>.",
+       "apihelp-userrights-example-expiry": "إضافة المستخدم <kbd>SometimeSysop</kbd> إلى مجموعة <kbd>sysop</kbd> لمدة شهر واحد.",
+       "apihelp-validatepassword-summary": "التحقق من صحة كلمة المرور ضد سياسات كلمة مرور الويكي.",
+       "apihelp-validatepassword-extended-description": "يتم الإبلاغ عن الصلاحية كـ<samp>Good</samp> إذا كانت كلمة المرور مقبولة، أو <samp>Change</samp> إذا كان قد يتم استخدام كلمة المرور لتسجيل الدخول ولكن يجب تغييرها، أو <samp>Invalid</samp> إذا كان كلمة المرور غير قابلة للاستخدام.",
+       "apihelp-validatepassword-param-password": "كلمة المرور للتحقق.",
+       "apihelp-validatepassword-param-user": "اسم المستخدم; للاستخدام عند اختبار إنشاء الحساب، يجب ألا يكون المستخدم المحدد موجودا.",
+       "apihelp-validatepassword-param-email": "عنوان البريد الإلكتروني; للاستخدام عند اختبار إنشاء الحساب.",
+       "apihelp-validatepassword-param-realname": "الاسم الحقيقي; للاستخدام عند اختبار إنشاء الحساب.",
+       "apihelp-validatepassword-example-1": "تحقق من كلمة المرور <kbd>foobar</kbd> للمستخدم الحالي.",
+       "apihelp-validatepassword-example-2": "تحقق من كلمة المرور <kbd>qwerty</kbd> لإنشاء المستخدم <kbd>Example</kbd>.",
+       "apihelp-watch-summary": "إضافة أو إزالة صفحات من قائمة مراقبة المستخدم الحالي.",
+       "apihelp-watch-param-title": "الصفحة ل(عدم)مراقبتها، استخدم <var>$1titles</var> بدلا من ذلك.",
+       "apihelp-watch-param-unwatch": "إذا تم التعيين فستتم إزالة الصفحة من قائمة المراقبة بدلا من مراقبتها.",
+       "apihelp-watch-example-watch": "راقب الصفحة <kbd>Main Page</kbd>.",
+       "apihelp-watch-example-unwatch": "ألغِ مراقبة الصفحة <kbd>Main Page</kbd>.",
+       "apihelp-watch-example-generator": "راقب الصفحات القليلة الأولى في النطاق الرئيسي.",
+       "apihelp-format-example-generic": "إرجاع نتيجة الاستعلام بتنسيق $1.",
+       "apihelp-format-param-wrappedhtml": "إرجاع HTML المطبوع بشكل جيد ووحدات ResourceLoader المرتبطة به ككائن JSON.",
+       "apihelp-json-summary": "بيانات الإخراج بتنسيق JSON.",
+       "apihelp-json-param-callback": "إذا تم تحديده، فسيقوم بإخراج الإخراج في استدعاء دالة معينة، للسلامة; سيتم تقييد جميع البيانات الخاصة بالمستخدم.",
+       "apihelp-json-param-utf8": "إذا تم تحديده، يقوم بترميز معظم (وليس كل) الأحرف غير ASCII كـUTF-8 بدلا من استبدالها بتسلسلات الهروب السداسية العشرية، افتراضي عندما لا يكون <var>formatversion</var>  <kbd>1</kbd>.",
+       "apihelp-json-param-ascii": "إذا تم تحديده، يشفر كل غير ASCII باستخدام تسلسلات الهروب السداسية العشرية، افتراضي عندما يكون <var>formatversion</var> <kbd>1</kbd>.",
+       "apihelp-jsonfm-summary": "بيانات الإخراج بتنسيق JSON (الطباعة بـHTML).",
+       "apihelp-none-summary": "عدم إخراج أي شيء.",
+       "apihelp-php-summary": "بيانات الإخراج بتنسيق PHP المتسلسل.",
+       "apihelp-phpfm-summary": "بيانات الإخراج بتنسيق JSON (الطباعة بـHTML).",
+       "apihelp-rawfm-summary": "بيانات الإخراج، بما في ذلك عناصر تصحيح الأخطاء، بتنسيق JSON (الطباعة بـHTML).",
+       "apihelp-xml-summary": "بيانات الإخراج بتنسيق XML.",
+       "apihelp-xml-param-xslt": "إذا تم تحديده، سيضيف الصفحة المسماة كورقة أنماط XSL، يجب أن تكون القيمة عنوانا في نطاق {{ns:MediaWiki}} ينتهي بـ<code>.xsl</code>.",
+       "apihelp-xml-param-includexmlnamespace": "If specified, adds an XML namespace.\nإذا تم تحديدها، سيضيف نطاق XML.",
+       "apihelp-xmlfm-summary": "بيانات الإخراج بتنسيق XML (الطباعة بـHTML).",
+       "api-format-title": "ناتج API ميدياويكي",
+       "api-format-prettyprint-header": "هذا هو تمثيل HTML لتنسيق $1، HTML مفيد في تصحيح الأخطاء، ولكنه غير مناسب لاستخدام التطبيق. \n\nحدد الوسيط <var>format</var> لتغيير نسق المخرجات، لمشاهدة تمثيل غير HTML لتنسيق $1; اضبط <kbd>format=$2</kbd>.\n\nراجع [[mw:Special:MyLanguage/API|التوثيق كاملا]]، أو [[Special:ApiHelp/main|مساعدة API]] لمزيد من المعلومات.",
+       "api-format-prettyprint-header-only-html": "هذا تمثيل HTML مخصص للتصحيح، وغير مناسب لاستخدام تطبيق HTML. \n\nراجع [[mw:Special:MyLanguage/API|التوثيق كاملا]]، أو [[Special:ApiHelp/main|مساعدة API]] لمزيد من المعلومات.",
+       "api-format-prettyprint-header-hyperlinked": "هذا هو تمثيل HTML لتنسيق $1، HTML مفيد في تصحيح الأخطاء، ولكنه غير مناسب لاستخدام التطبيق. \n\nحدد الوسيط <var>format</var> لتغيير نسق المخرجات، لمشاهدة تمثيل غير HTML لتنسيق $1; اضبط [$3 <kbd>format=$2</kbd>].\n\nراجع [[mw:API|التوثيق كاملا]]، أو [[Special:ApiHelp/main|مساعدة API]] لمزيد من المعلومات.",
+       "api-format-prettyprint-status": "سيتم إرجاع هذه الاستجابة بحالة HTTP $1 $2.",
+       "api-login-fail-aborted": "تتطلب المصادقة تفاعل المستخدم، والذي لا يدعمه <kbd>action=login</kbd>، لتتمكن من تسجيل الدخول باستخدام <kbd>action=login</kbd>; راجع [[Special:BotPasswords]]، لمتابعة استخدام تسجيل الدخول إلى الحساب الرئيسي; راجع <kbd>[[Special:ApiHelp/clientlogin|action=clientlogin]]</kbd>.",
+       "api-login-fail-aborted-nobotpw": "تتطلب المصادقة تفاعل المستخدم، والذي لا يدعمه <kbd>action=login</kbd>، لتسجيل الدخول; راجع <kbd>[[Special:ApiHelp/clientlogin|action=clientlogin]]</kbd>.",
+       "api-login-fail-badsessionprovider": "لا يمكن تسجيل الدخول باستخدام $1.",
+       "api-login-fail-sameorigin": "لا يمكن تسجيل الدخول عندما لا يتم تطبيق السياسة الأصلية.",
+       "api-pageset-param-titles": "قائمة عناوين للعمل عليها.",
+       "api-pageset-param-pageids": "قائمة بمعرفات الصفحات للعمل عليها.",
+       "api-pageset-param-revids": "قائمة بمعرفات المراجعات للعمل عليها.",
+       "api-pageset-param-generator": "احصل على قائمة الصفحات للعمل عليها من خلال تنفيذ وحدة الاستعلام المحددة.\n\n<strong>ملاحظة:</strong> يجب أن تبدأ أسماء وسطائط المولد بـ\"g\"، انظر الأمثلة.",
+       "api-pageset-param-redirects-generator": "حل التحويلات تلقائيا في <var>$1titles</var> و<var>$1pageids</var> و<var>$1revids</var> وفي الصفحات التي يتم إرجاعها بواسطة <var>$1generator</var>.",
+       "api-pageset-param-redirects-nogenerator": "حل التحويلات تلقائيا في <var>$1titles</var> و<var>$1pageids</var> و<var>$1revids</var>.",
+       "api-pageset-param-converttitles": "تحويل العناوين إلى المتغيرات الأخرى إذا لزم الأمر، يعمل فقط إذا كانت لغة محتوى الويكي تدعم تحويل المتغير، تتضمن اللغات التي تدعم تحويل المتغير $1.",
+       "api-help-title": "مساعدة API ميدياويكي",
+       "api-help-lead": "\nهذه صفحة توثيق ميدياويكي API التي تم إنشاؤها تلقائيا.\n\nوثائق وأمثلة: https://www.mediawiki.org/wiki/API",
+       "api-help-main-header": "الوحدة الرئيسية",
+       "api-help-undocumented-module": "لا توجد وثائق للوحدة $1.",
+       "api-help-flag-deprecated": "هذه الوحدة مهملة.",
+       "api-help-flag-internal": "<strong> هذه الوحدة داخلية أو غير مستقرة.</strong> قد تتغير عمليتها دون إشعار.",
+       "api-help-flag-readrights": "هذه الوحدة تتطلب صلاحيات القراءة.",
+       "api-help-flag-writerights": "هذه الوحدة تتطلب صلاحيات الكتابة.",
+       "api-help-flag-mustbeposted": "هذه الوحدة تقبل طلبات POST فقط.",
+       "api-help-flag-generator": "هذه الوحدة يمكن أن تُستخدَم كمولد.",
+       "api-help-source": "المصدر:$1",
+       "api-help-source-unknown": "المصدر: <span class=\"apihelp-unknown\">غير معروف</span>",
+       "api-help-license": "الترخيص: [[$1|$2]]",
+       "api-help-license-noname": "الترخيص: [[$1|انظر الوصلة]]",
+       "api-help-license-unknown": "الترخيص: <span class=\"apihelp-unknown\">غير معروف</span>",
+       "api-help-parameters": "{{PLURAL:$1|وسيط|وسائط}}:",
+       "api-help-param-deprecated": "مهمل.",
+       "api-help-param-required": "هذا الوسيط مطلوب.",
+       "api-help-param-templated": "هذا [[Special:ApiHelp/main#main/templatedparams|وسيط قالب]]، عند تقديم الطلب، $2.",
+       "api-help-param-templated-var-first": "يجب استبدال <var>&#x7B;$1&#x7D;</var> في اسم الوسيط بقيم <var>$2</var>",
+       "api-help-param-templated-var": "<var>&#x7B;$1&#x7D;</var> بقيم <var>$2</var>",
+       "api-help-datatypes-header": "أنواع البيانات",
+       "api-help-datatypes": "يجب أن يكون الإدخال إلى ميدياويكي هو UTF-8 المعيَّن لـNFC، قد يحاول ميدياويكي تحويل مدخلات أخرى، ولكن قد يتسبب ذلك في فشل بعض العمليات (مثل [[Special:ApiHelp/edit|التعديلات]] مع عمليات فحص MD5).\n\nتحتاج بعض أنواع الوسائط في طلبات API إلى مزيد من الشرح:\n;منطقية\n:تعمل الوسائط المنطقية مثل صناديق اختيار HTML: إذا تم تحديد الوسيط، بغض النظر عن القيمة، فيتم اعتباره صحيحا، للحصول على قيمة خاطئة; احذف الوسيط تماما.\n;الطابع الزمني\n:قد يتم تحديد الطوابع الزمنية بتنسيقات متعددة، يُوصَى بـISO 8601 التاريخ والوقت، جميع الأوقات بالتوقيت العالمي المنسق، يتم تجاهل أية منطقة زمنية مضمنة.\n:* تاريخ ووقت ISO 8601، <kbd><var>2001</var>-<var>01</var>-<var>15</var>T<var>14</var>:<var>56</var>:<var>00</var>Z</kbd> (علامات الترقيم و<kbd>Z</kbd> اختيارية)\n:* تاريخ ووقت ISO 8601مع الثواني المجزأة (متجاهلة)، <kbd><var>2001</var>-<var>01</var>-<var>15</var>T<var>14</var>:<var>56</var>:<var>00</var>.<var>00001</var>Z</kbd>  (الشرطات، والنقطتان الرأسيتان اختيارية و<kbd>Z</kbd>)\n:* تنسيق ميدياويكي، <kbd><var>2001</var><var>01</var><var>15</var><var>14</var><var>56</var><var>00</var></kbd>\n:* تنسيق رقمي عام، (توقيت اختياري، أو يتم تجاهل) <kbd><var>2001</var>-<var>01</var>-<var>15</var> <var>14</var>:<var>56</var>:<var>00</var></kbd> (منطقة زمنية اختيارية لـ<kbd>GMT</kbd>، <kbd>+<var>##</var></kbd>، أو يتم تجاهل <kbd>-<var>##</var></kbd>)\n:* تنسيق EXIF، <kbd><var>2001</var>:<var>01</var>:<var>15</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:*تنسيق RFC 2822 (قد يتم حذف المنطقة الزمنية)، <kbd><var>Mon</var>, <var>15</var> <var>Jan</var> <var>2001</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:*تنسيق RFC 850 format (قد يتم حذف المنطقة الزمنية)، <kbd><var>Monday</var>, <var>15</var>-<var>Jan</var>-<var>2001</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:* تنسيق C ctime format, <kbd><var>Mon</var> <var>Jan</var> <var>15</var> <var>14</var>:<var>56</var>:<var>00</var> <var>2001</var></kbd>\n:* الثواني منذ 1970-01-01T00:00:00Z كعدد صحيح يتراوح بين 1 و13 (باستثناء <kbd>0</kbd>)\n:* السلسلة <kbd>now</kbd>\n;فاصل بديل متعدد القيم\n:يتم عادةً إرسال الوسائط التي تأخذ قيم متعددة مع القيم المفصولة باستخدام حرف الأنبوب، على سبيل المثال <kbd>param=value1|value2</kbd> or <kbd>param=value1%7Cvalue2</kbd> إذا كانت القيمة يجب أن تحتوي على حرف الأنبوب، فاستخدم U+001F (فاصل الوحدة) مثل الفاصل ''و'' بادئة القيمة بـU+001F، على سبيل المثال <kbd>param=%1Fvalue1%1Fvalue2</kbd>.",
+       "api-help-templatedparams-header": "وسائط القالب",
+       "api-help-templatedparams": "تدعم وسائط القوالب الحالات التي تحتاج فيها API إلى قيمة لكل قيمة من وسيط آخر، على سبيل المثال، إذا كانت هناك وحدة API لطلب الفاكهة، فإنه قد يكون لديك وسيط <var>fruits</var>  لتحديد أي الفواكه تم طلبها ووسيط قالب <var>{fruit}-quantity</var>لتحديد عدد الفواكه لكل طلب، يمكن لعميل API الذي يريد 1 تفاحة، 5 موز، 20 فراولة ثم تقديم طلب مثل <kbd>fruits=apples|bananas|strawberries&apples-quantity=1&bananas-quantity=5&strawberries-quantity=20</kbd>.",
+       "api-help-param-type-limit": "النوع: عدد صحيح أو <kbd>max</kbd>",
+       "api-help-param-type-integer": "النوع: {{PLURAL:$1|1=عدد صحيح|2=قائمة الأعداد الصحيحة}}",
+       "api-help-param-type-boolean": "النوع: منطقية ([[Special:ApiHelp/main#main/datatypes|التفاصيل]])",
+       "api-help-param-type-timestamp": "النوع: {{PLURAL:$1|1=طابع زمني|2=قائمة الطوابع الزمنية}} ([[Special:ApiHelp/main#main/datatypes|الصيغ المسموح بها]])",
+       "api-help-param-type-user": "النوع: {{PLURAL:$1|1=اسم مستخدم|2=قائمة أسماء المستخدمين}}",
+       "api-help-param-list": "{{PLURAL:$1|1=إحدى القيم التالية|2=القيم (منفصلة مع <kbd>{{!}}</kbd> أو [[Special:ApiHelp/main#main/datatypes|البديل]])}}: $2",
+       "api-help-param-list-can-be-empty": "{{PLURAL:$1|0=يجب أن تكون فارغة|يمكن أن تكون فارغة، أو $2}}",
+       "api-help-param-limit": "لا يُسمَح بأكثر من $1.",
+       "api-help-param-limit2": "لا يُسمَح بأكثر من $1 ($2 للبوتات).",
+       "api-help-param-integer-min": "يجب ألا تقل {{PLURAL:$1|1=القيمة|2=القيم}} عن $2.",
+       "api-help-param-integer-max": "يجب ألا تزيد {{PLURAL:$1|1=القيمة|2=القيم}} عن $3.",
+       "api-help-param-integer-minmax": "يجب أن تتراوح {{PLURAL:$1|1=القيمة|2=القيم}} بين $2 و$3.",
+       "api-help-param-upload": "يجب أن يتم نشره كرفع ملف باستخدام بيانات متعددة الأجزاء/النماذج.",
+       "api-help-param-multi-separate": "قيم منفصلة بـ<kbd>|</kbd> أو [[Special:ApiHelp/main#main/datatypes|بديل]].",
+       "api-help-param-multi-max": "الحد الأقصى لعدد القيم هو {{PLURAL:$1|$1}} ({{PLURAL:$2|$2}} للبوتات).",
+       "api-help-param-multi-max-simple": "الحد الأقصى لعدد القيم هو {{PLURAL:$1|$1}}.",
+       "api-help-param-multi-all": "لتحديد كل القيم; استخدم <kbd>$1</kbd>.",
+       "api-help-param-default": "الافتراضي: $1",
+       "api-help-param-default-empty": "الافتراضي: <span class=\"apihelp-empty\">(فارغ)</span>",
+       "api-help-param-token": "تم استرداد رمز مميز \"$1\" من [[Special:ApiHelp/query+tokens|action=query&meta=tokens]]",
+       "api-help-param-token-webui": "للتوافق; يتم أيضا قبول الرمز المميز المستخدم في واجهة المستخدم على الويب.",
+       "api-help-param-disabled-in-miser-mode": "تم التعطيل بسبب [[mw:Special:MyLanguage/Manual:$wgMiserMode|وضع miser]].",
+       "api-help-param-limited-in-miser-mode": "<strong>ملاحظة:</strong> بسبب [[mw:Special:MyLanguage/Manual:$wgMiserMode|وضع miser]]; استخدام هذا قد يؤدي إلى نتائج أقل من <var>$1limit</var> نتائج التي يتم عرضها قبل المتابعة، في الحالات القصوى، قد يتم إرجاع صفر نتائج.",
+       "api-help-param-direction": "في أي اتجاه للتعداد:\n;الأحدث: سرد الأقدم أولا، ملاحظة: يجب أن يكون $1start قبل $1end.\n;older:List newest first (default). Note: $1start has to be later than $1end.\n;الأقدم: سرد الأحدث أولا (افتراضي)، ملاحظة: يجب أن يكون $1start بعد $1end.",
+       "api-help-param-continue": "عندما تتوفر المزيد من النتائج، استخدم هذا للمتابعة",
+       "api-help-param-no-description": "<span class=\"apihelp-empty\">(لا يوجد وصف)</span>",
+       "api-help-param-maxbytes": "Cلا يمكن أن يكون أطول من $1 {{PLURAL:$1|بايت}}.",
+       "api-help-param-maxchars": "Cلا يمكن أن يكون أطول من $1 {{PLURAL:$1|حرف|أحرف}}.",
+       "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-open-in-apisandbox": "<small>[فتح في ملعب]</small>",
+       "api-help-authmanager-general-usage": "الإجراء العام لاستخدام هذه الوحدة هو:\n# جلب الحقول المتاحة من <kbd>[[Special:ApiHelp/query+authmanagerinfo|action=query&meta=authmanagerinfo]]</kbd> مع amirequestsfor=$4، $<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> with <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": "تنسيق لاستخدامه في إرسال الرسائل.",
+       "api-help-authmanagerhelper-mergerequestfields": "دمج معلومات الحقل لجميع طلبات التوثيق في مصفوفة واحدة.",
+       "api-help-authmanagerhelper-preservestate": "الحفاظ على الحالة من محاولة تسجيل دخول فاشلة سابقة، إن أمكن.",
+       "api-help-authmanagerhelper-returnurl": "يجب أن يكون العودة لتدفقات المصادقة من الجهات الخارجية مطلقا، مطلوب إما هذا أو  <var>$1continue</var>.\n\nعند استلام استجابة <samp>REDIRECT</samp>، ستفتح عادةً متصفح أو عرض ويب للمسار <samp>redirecttarget</samp>المحدد لتدفق مصادقة طرف ثالث، عند اكتمال ذلك، سيرسل الطرف الثالث المتصفح أو عرض الويب إلى هذا المسار، يجب عليك استخلاص أي استعلام أو وسائط POST من المسار وتمريرها كطلب <var>$1continue</var> إلى وحدة API هذه.",
+       "api-help-authmanagerhelper-continue": "هذا الطلب استمرار بعد استجابة <samp>UI</samp> أو <samp>REDIRECT</samp> سابقة، مطلوب إما هذا أو <var>$1returnurl</var>.",
+       "api-help-authmanagerhelper-additional-params": "تقبل هذه الوحدة معايير إضافية بناءً على طلبات المصادقة المتاحة، استخدم <kbd>[[Special:ApiHelp/query+authmanagerinfo|action=query&meta=authmanagerinfo]]</kbd> مع <kbd>amirequestsfor=$1</kbd> (أو استجابة سابقة من هذه الوحدة، إن وُجِدت) لتحديد الطلبات المتاحة والحقول التي يستخدمونها.",
+       "apierror-allimages-redirect": "استخدم <kbd>gaifilterredir=nonredirects</kbd> بدلا من <var>redirects</var> عند استخدام <kbd>allimages</kbd> كمولد.",
+       "apierror-allpages-generator-redirects": "استخدم <kbd>gaifilterredir=nonredirects</kbd> بدلا من <var>redirects</var> عند استخدام <kbd>allimages</kbd> كمولد.",
+       "apierror-appendnotsupported": "لا يمكن إلحاق الصفحات باستخدام نموذج المحتوى $1.",
+       "apierror-articleexists": "تم بالفعل إنشاء المقالة التي حاولت إنشاءها.",
+       "apierror-assertbotfailed": "التأكيد على فشل المستخدم في صلاحية <code>bot</code>.",
+       "apierror-assertnameduserfailed": "تأكيد أن المستخدم \"$1\" فشل.",
+       "apierror-assertuserfailed": "التأكيد على فشل تسجيل الدخول للمستخدم.",
+       "apierror-autoblocked": "عنوان الآيبي الخاص بك تم منعه تلقائيا; لأنه تم استخدامه بواسطة مستخدم ممنوع.",
+       "apierror-badconfig-resulttoosmall": "إن قيمة <code>$wgAPIMaxResultSize</code> في هذا الويكي صغيرة جدا لا تحتوي على معلومات النتائج الأساسية.",
+       "apierror-badcontinue": "متابعة غير صحيحة; يجب عليك تمرير القيمة الأصلية التي تم إرجاعها بواسطة الاستعلام السابق.",
+       "apierror-baddiff": "لا يمكن استرجاع الفرقك; إحدى أو كلا المراجعتين غير موجودة أو ليست لديك صلاحية لعرضها.",
+       "apierror-baddiffto": "يجب تعيين <var>$1diffto</var> على عدد غير سالب، <kbd>prev</kbd>, <kbd>next</kbd> أو <kbd>cur</kbd>.",
+       "apierror-badformat-generic": "التنسيق المطلوب $1 غير مدعوم لنموذج المحتوى $2.",
+       "apierror-badformat": "التنسيق المطلوب $1 غير مدعوم لنموذج المحتوى $2 المستخدم بواسطة $3.",
+       "apierror-badgenerator-notgenerator": "لا يمكن استخدام الوحدة <kbd>$1</kbd> كمولد.",
+       "apierror-badgenerator-unknown": "<kbd>generator=$1</kbd> مجهول.",
+       "apierror-badip": "وسيط الآيبي غير صالح.",
+       "apierror-badmd5": "رمز الرقم MD5 المتوفر غير صحيح.",
+       "apierror-badmodule-badsubmodule": "لا تحتوي الوحدة <kbd>$1</kbd> على وحدة فرعية \"$2\".",
+       "apierror-badmodule-nosubmodules": "لا تحتوي الوحدة <kbd>$1</kbd> على وحدات فرعية.",
+       "apierror-badparameter": "قيمة غير صالحة للوسيط <var>$1</var>.",
+       "apierror-badquery": "استعلام غير صالح.",
+       "apierror-badtimestamp": "قيمة غير صالحة \"$2\" لوسيط الطابع الزمني <var>$1</var>.",
+       "apierror-badtoken": "رمز CSRF غير صالح.",
+       "apierror-badupload": "وسيط رفع الملف <var>$1</var> ليس رفع ملف; تأكد من استخدام <code>multipart/form-data</code> لـPOST الخاص بك وقم بتضمين اسم ملف في الرأس <code>Content-Disposition</code>.",
+       "apierror-badurl": "قيمة غير صالحة \"$2\" لوسيط العنوان <var>$1</var>.",
+       "apierror-baduser": "قيمة غير صالحة \"$2\" لوسيط المستخدم <var>$1</var>.",
+       "apierror-badvalue-notmultivalue": "لا يمكن استخدام فصل U+001F متعدد القيم إلا لوسائط متعددة القيم.",
+       "apierror-bad-watchlist-token": "رمز قائمة مراقبة غير صحيح مقدم; يُرجَى تعيين رمز مميز في [[Special:Preferences]].",
+       "apierror-blockedfrommail": "لقد تم منعك من إرسال البريد الإلكتروني.",
+       "apierror-blocked": "لقد تم منعك من التحرير.",
+       "apierror-botsnotsupported": "هذه الواجهة غير مدعومة للبوتات.",
+       "apierror-cannot-async-upload-file": "لا يمكن الجمع بين الوسيطين <var>async</var> و<var>file</var>، إذا كنت تريد معالجة غير متزامنة لملفك المرفوع، فارفعه أولاً إلى المخبأ (باستخدام الوسيط <var>stash</var>) ثم انشر الملف المتقطع بشكل غير متزامن (باستخدام <var>filekey</var> و<var>async</var>).",
+       "apierror-cannotreauthenticate": "هذا الإجراء غير متاح لأن هويتك لا يمكن التحقق منها.",
+       "apierror-cannotviewtitle": "لا يُسمَح لك بعرض $1.",
+       "apierror-cantblock-email": "ليست لديك صلاحية لمنع المستخدمين من إرسال البريد الإلكتروني من خلال الويكي.",
+       "apierror-cantblock": "ليست لديك صلاحية لمنع المستخدمين.",
+       "apierror-cantchangecontentmodel": "ليست لديك صلاحية لمنع المستخدمين لتغيير نموذج محتوى صفحة.",
+       "apierror-canthide": "ليست لديك صلاحية إخفاء أسماء المستخدمين من سجل المنع.",
+       "apierror-cantimport-upload": "ليست لديك صلاحية استيراد الصفحات المرفوعة.",
+       "apierror-cantimport": "ليست لديك صلاحية لاستيراد الصفحات.",
+       "apierror-cantoverwrite-sharedfile": "الملف الهدف موجود في مستودع مشترك وليست لديك صلاحية لتجاوزه.",
+       "apierror-cantsend": "لم تقم بتسجيل الدخول أو ليس لديك عنوان بريد إلكتروني مؤكد أو غير مسموح لك بإرسال بريد إلكتروني إلى مستخدمين آخرين; لذلك لا يمكنك إرسال بريد إلكتروني.",
+       "apierror-cantundelete": "تعذر الاسترجاع: قد لا تكون المراجعات المطلوبة موجودة، أو ربما تم الاسترجاع بالفعل.",
+       "apierror-changeauth-norequest": "فشل في إنشاء طلب التغيير.",
+       "apierror-chunk-too-small": "الحد الأدنى لحجم القطعة هو $1 {{PLURAL:$1|بايت}} للقطع غير النهائية.",
+       "apierror-cidrtoobroad": "لا يُقبَل مدى $1 CIDR أكبر من /$2.",
+       "apierror-compare-no-title": "لا يمكن الحفظ المسبق للحفظ بدون عنوان; حاول تحديد <var>fromtitle</var> أو <var>totitle</var>.",
+       "apierror-compare-nosuchfromsection": "لا يوجد قسم $1 في المحتوى 'من'.",
+       "apierror-compare-nosuchtosection": "لا يوجد قسم $1 في المحتوى 'إلى'.",
+       "apierror-compare-relative-to-nothing": "لا توجد مراجعة 'من' لـ<var>torelative</var> لتكون نسبة.",
+       "apierror-contentserializationexception": "فشل تسلسل المحتوى: $1",
+       "apierror-contenttoobig": "يتجاوز المحتوى الذي أدخلته حد حجم المقالة البالغ $1 {{PLURAL:$1|كيلوبايت}}.",
+       "apierror-copyuploadbaddomain": "لا يُسمَح بالمرفوعات بواسطة مسار من هذا النطاق.",
+       "apierror-copyuploadbadurl": "لا يُسمَح بالرفع من هذا المسار.",
+       "apierror-create-titleexists": "لا يمكن حماية العناوين الموجودة باستخدام <kbd>create</kbd>.",
+       "apierror-csp-report": "خطأ في معالجة تقرير CSP: $1.",
+       "apierror-deletedrevs-param-not-1-2": "لا يمكن استخدام الوسيط <var>$1</var> في الأوضاع 1 أو 2.",
+       "apierror-deletedrevs-param-not-3": "لا يمكن استخدام الوسيط <var>$1</var> في الوضع 3.",
+       "apierror-emptynewsection": "إنشاء أقسام جديدة فارغة غير ممكن.",
+       "apierror-emptypage": "لا يُسمَح بإنشاء صفحات جديدة فارغة.",
+       "apierror-exceptioncaught": "[$1] تم اكتشاف الاستثناء: $2",
+       "apierror-filedoesnotexist": "الملف غير موجود.",
+       "apierror-fileexists-sharedrepo-perm": "الملف الهدف موجود في مستودع مشترك; استخدم الوسيط <var>ignorewarnings</var> لتجاوزه.",
+       "apierror-filenopath": "لا يمكن الحصول على مسار الملف المحلي.",
+       "apierror-filetypecannotberotated": "لا يمكن تدوير نوع الملف.",
+       "apierror-formatphp": "لا يمكن تمثيل هذه الاستجابة باستخدام <kbd>format=php</kbd>; انظر https://phabricator.wikimedia.org/T68776.",
+       "apierror-imageusage-badtitle": "يجب أن يكون عنوان <<kbd>$1</kbd> ملفا.",
+       "apierror-import-unknownerror": "خطأ غير معروف في الاستيراد: $1.",
+       "apierror-integeroutofrange-abovebotmax": "لا يجوز أن يكون <var>$1</var> أكثر من $2 (معين إلى $3) للبوتات أو الإداريين.",
+       "apierror-integeroutofrange-abovemax": "لا يجوز أن يكون <var>$1</var> أكثر من $2 (معين إلى $3) للمستخدمين.",
+       "apierror-integeroutofrange-belowminimum": "لا يجوز أن يكون <var>$1</var> أقل من $2 (معين إلى $3)",
+       "apierror-invalidcategory": "اسم التصنيفف الذي أدخلته غير صالح.",
+       "apierror-invalid-chunk": "الإزاحة بالإضافة إلى الجزء الحالي أكبر من حجم الملف المطالب به.",
+       "apierror-invalidexpiry": "وقت انتهاء الصلاحية غير صالح \"$1\".",
+       "apierror-invalid-file-key": "ليس مفتاح ملف صالح.",
+       "apierror-invalidlang": "رمز لغة غير صالح للوسيط <var>$1</var>.",
+       "apierror-invalidoldimage": "يحتوي الوسيط <var>oldimage</var> على تنسيق غير صالح.",
+       "apierror-invalidparammix-cannotusewith": "لا يمكن استخدام الوسيط <kbd>$1</kbd> مع <kbd>$2</kbd>.",
+       "apierror-invalidparammix-mustusewith": "يمكن استخدام الوسيط <kbd>$1</kbd> مع <kbd>$2</kbd> فقط.",
+       "apierror-invalidparammix-parse-new-section": "لا يمكن دمج <kbd>section=new</kbd> مع الوسائط <var>oldid</var> أو <var>pageid</var> أو <var>page</var>; الرجاء استخدام <var>title</var> و<var>text</var>.",
+       "apierror-invalidparammix": "لا يمكن استخدام {{PLURAL:$2|الوسائط}} $1 معا.",
+       "apierror-invalidsection": "يجب أن يكون الوسيط <var>section</var> معرف قسم صالحا أو <kbd>new</kbd>.",
+       "apierror-invalidsha1base36hash": "رمز رقم SHA1Base36 المقدم غير صالح.",
+       "apierror-invalidsha1hash": "رمز رقم SHA1 المقدم غير صالح.",
+       "apierror-invalidtitle": "عنوان سيء \"$1\".",
+       "apierror-invalidurlparam": "قيمة غير صالحة لـ<var>$1urlparam</var> (<kbd>$2=$3</kbd>).",
+       "apierror-invaliduser": "اسم المستخدم غير صالح \"$1\".",
+       "apierror-invaliduserid": "معرف المستخدم <var>$1</var> غير صالح.",
+       "apierror-maxbytes": "لا يمكن أن يكون الوسيط <var>$1</var> أطول من $2 {{PLURAL:$2|بايت}}",
+       "apierror-maxchars": "لا يمكن أن يكون الوسيط <var>$1</var> أطول من $2 {{PLURAL:$2|حرف|أحرف}}",
+       "apierror-maxlag-generic": "في انتظار خادم قاعدة البيانات: تأخر $1 {{PLURAL:$1|ثانية|ثوانٍ}}.",
+       "apierror-maxlag": "في انتظار $2: تأخر $1 {{PLURAL:$1|ثانية|ثوانٍ}}.",
+       "apierror-mimesearchdisabled": "تم تعطيل بحث MIME في وضع Miser.",
+       "apierror-missingcontent-pageid": "محتوى مفقود لمعرف الصفحة $1.",
+       "apierror-missingcontent-revid": "محتوى مفقود لمعرف المراجعة $1.",
+       "apierror-missingparam-at-least-one-of": "مطلوب {{PLURAL:$2|الوسيط|واحد على الأقل من الوسائط}} $1.",
+       "apierror-missingparam-one-of": "مطلوب {{PLURAL:$2|الوسيط|واحد على الأقل من الوسائط}} $1.",
+       "apierror-missingparam": "يجب تعيين الوسيط <var>$1</var>.",
+       "apierror-missingrev-pageid": "لا توجد مراجعة حالية لمعرف الصفحة $1.",
+       "apierror-missingrev-title": "لا توجد مراجعة حالية للعنوان $1.",
+       "apierror-missingtitle-createonly": "يمكن حماية العناوين المفقودة فقط باستخدام <kbd>create</kbd>.",
+       "apierror-missingtitle": "الصفحة التي حددتها غير موجودة.",
+       "apierror-missingtitle-byname": "الصفحة $1 غير موجودة.",
+       "apierror-moduledisabled": "تم تعطيل الوحدة <kbd>$1</kbd>.",
+       "apierror-multival-only-one-of": "{{PLURAL:$3|فقط|واحد فقط من}} $2 مسموح به للوسيط <var>$1</var>.",
+       "apierror-multpages": "لا يجوز استخدام <var>$1</var> إلا مع صفحة واحدة.",
+       "apierror-mustbeloggedin-changeauth": "يجب عليك تسجيل الدخول لتغيير بيانات المصادقة.",
+       "apierror-mustbeloggedin-generic": "يجب أن تكون مسجلا.",
+       "apierror-mustbeloggedin-linkaccounts": "يجب عليك تسجيل الدخول لربط الحسابات.",
+       "apierror-mustbeloggedin-removeauth": "يجب عليك تسجيل الدخول لإزالة بيانات المصادقة.",
+       "apierror-mustbeloggedin-uploadstash": "لا يتوفر الرفع المخبأ إلا للمستخدمين المسجلين.",
+       "apierror-mustbeloggedin": "يجب تسجيل الدخول إلى $1.",
+       "apierror-mustbeposted": "تتطلب الوحدة <kbd>$1</kbd> طلب POST.",
+       "apierror-mustpostparams": "تم العثور على {{PLURAL:$2|الوسيط|الوسائط}} في سلسلة الاستعلام، ولكن يجب أن يكون في نص POST: $1.",
+       "apierror-noapiwrite": "تم تعطيل تحرير هذا الويكي من خلال  API; تأكد من تضمين العبارة <code>$wgEnableWriteAPI=true;</code> في ملف <code>LocalSettings.php</code> الخاص بالويكي.",
+       "apierror-nochanges": "لم يتم طلب أية تغييرات.",
+       "apierror-nodeleteablefile": "لا يوجد مثل هذا الإصدار القديم من الملف.",
+       "apierror-no-direct-editing": "التعديل المباشر عبر API غير مدعوم لنموذج المحتوى $1 المستخدم في $2.",
+       "apierror-noedit-anon": "لا يمكن للمستخدمين المجهولين تحرير الصفحات.",
+       "apierror-noedit": "ليست لديك صلاحية تعديل الصفحات.",
+       "apierror-noimageredirect-anon": "لا يمكن للمستخدمين المجهولين إنشاء تحويلات صور.",
+       "apierror-noimageredirect": "ليست لديك صلاحية تعديل الصفحات إنشاء تحويلات الصور.",
+       "apierror-nosuchlogid": "لا توجد مدخلة سجل بالمعرف $1.",
+       "apierror-nosuchpageid": "لا توجد صفحة بالمعرف $1.",
+       "apierror-nosuchrcid": "لا يوجد تغيير حديث بالمعرف $1.",
+       "apierror-nosuchrevid": "لا توجد مراجعة بالمعرف $1.",
+       "apierror-nosuchsection": "لا يوجد قسم $1.",
+       "apierror-nosuchsection-what": "لا يوجد قسم $1 في $2.",
+       "apierror-nosuchuserid": "لا يوجد مستخدم بالمعرف $1.",
+       "apierror-notarget": "لم تحدد هدفا صالحا لهذا الإجراء.",
+       "apierror-notpatrollable": "لا يمكن إجراء مراجعة للمراجعة $1 لأنها قديمة جدا.",
+       "apierror-nouploadmodule": "لا توجد وحدة رفع محددة.",
        "apierror-offline": "لم يمكن المتابعة بسبب مشاكل في الاتصال بالشبكة; تأكد من أنه لديك اتصال بالإنترنت وحاول مرة أخرى.",
+       "apierror-opensearch-json-warnings": "لا يمكن تمثيل التحذيرات بتنسيق OpenSearch JSON.",
+       "apierror-pagecannotexist": "النطاق لا يسمح بالصفحات الفعلية.",
+       "apierror-pagedeleted": "لقد تم حذف الصفحة منذ أن جلبت طابعها الزمني.",
+       "apierror-pagelang-disabled": "لا يُسمَح بتغيير لغة صفحة في هذا الويكي.",
+       "apierror-paramempty": "قد لا يكون الوسيط <var>$1</var> فارغا.",
+       "apierror-parsetree-notwikitext": "<kbd>prop=parsetree</kbd> مدعوم لمحتوى نص الويكي فقط.",
+       "apierror-parsetree-notwikitext-title": "<kbd>prop=parsetree</kbd> مدعوم لمحتوى نص الويكي فقط، يستخدم $1 نموذج المحتوى $2.",
+       "apierror-pastexpiry": "وقت انتهاء الصلاحية \"$1\" في الماضي.",
+       "apierror-permissiondenied": "ليست لديك صلاحية لـ$1.",
+       "apierror-permissiondenied-generic": "الإذن مرفوض.",
+       "apierror-permissiondenied-patrolflag": "تحتاج إلى صلاحية<code>patrol</code> أو <code>patrolmarks</code> لطلب علم مراجع.",
+       "apierror-permissiondenied-unblock": "ليست لديك صلاحية لرفع منع المستخدمين.",
+       "apierror-prefixsearchdisabled": "تم تعطيل البحث عن بادئة MIME في وضع Miser.",
+       "apierror-promised-nonwrite-api": "لا يمكن إرسال رأس HTTP <code>Promise-Non-Write-API-Action</code> إلى وحدات API الخاصة بوضع الكتابة.",
+       "apierror-protect-invalidaction": "نوع حماية غير صالح \"$1\".",
+       "apierror-protect-invalidlevel": "مستوى حماية غير صالح \"$1\".",
+       "apierror-ratelimited": "لقد تجاوزت حد المعدل الخاص بك; يُرجَى الانتظار بعض الوقت والمحاولة مرة أخرى.",
+       "apierror-readapidenied": "أنت بحاجة لصلاحية القراءة لاستخدام هذه الوحدة.",
+       "apierror-readonly": "الويكي حاليا في وضع القراءة فقط.",
+       "apierror-reauthenticate": "لم تقم بالمصادقة مؤخرًا في هذه الجلسة; الرجاء إعادة التصديق.",
+       "apierror-redirect-appendonly": "لقد حاولت إجراء التعديل باستخدام وضع تحويل التالي، والذي يجب استخدامه في الاقتران مع <kbd>section=new</kbd> أو <var>prependtext</var> أو <var>appendtext</var>.",
+       "apierror-revdel-mutuallyexclusive": "لا يمكن استخدام نفس الحقل في كل من <var>hide</var> و<var>show</var>.",
+       "apierror-revdel-needtarget": "مطلوب عنوان مستهدف لنوع RevDel هذا.",
+       "apierror-revdel-paramneeded": "هناك قيمة واحدة على الأقل مطلوبة لـ<var>hide</var> و/أو <var>show</var>.",
+       "apierror-revisions-badid": "لم يتم العثور على مراجعة للوسيط <var>$1</var>.",
+       "apierror-revisions-norevids": "لا يجوز استخدام الوسيط <var>revids</var> مع خيارات القائمة (<var>$1limit</var> و<var>$1startid</var> و<var>$1endid</var و<kbd>$1dir=newer</kbd> و<var>$1user</var> و<var>$1excludeuser</var> و<var>$1start</var> و<var>$1end</var>).",
+       "apierror-revisions-singlepage": "تم استخدام <var>titles</var> أو <var>pageids</var> أو مولد لتزويد صفحات متعددة، لكن يمكن استخدام وسائط <var>$1limit</var> و<var>$1startid</var> و<var>$1endid</var> و<kbd>$1dir=newer</kbd> و<var>$1user</var> و<var>$1excludeuser</var> و<var>$1start</var> و<var>$1end</var> في صفحة واحدة فقط.",
+       "apierror-revwrongpage": "r$1 ليست مراجعة $2.",
+       "apierror-searchdisabled": "تم تعطيل بحث <var>$1</var>.",
+       "apierror-sectionreplacefailed": "لا يمكن دمج القسم المحدث.",
+       "apierror-sectionsnotsupported": "الأقسام غير مدعومة لنموذج المحتوى $1.",
+       "apierror-sectionsnotsupported-what": "الأقسام غير مدعومة بواسطة $1.",
+       "apierror-show": "وسيط غير صحيحة; قد لا يتم تقديم قيم خاصة متبادلة.",
+       "apierror-siteinfo-includealldenied": "يمكن عرض جميع معلومات الخوادم ما لم يكن <var>$wgShowHostnames</var> صحيحا.",
+       "apierror-sizediffdisabled": "تم تعطيل فرق الحجم في وضع Miser.",
+       "apierror-spamdetected": "تم رفض تعديلك لأنه يحتوي على جزء من الرسائل غير المرغوب فيها: <code>$1</code>.",
+       "apierror-specialpage-cantexecute": "ليست لديك صلاحية لعرض نتائج هذه الصفحة الخاصة.",
+       "apierror-stashedfilenotfound": "تعذر العثور على الملف في المخبأ: $1.",
+       "apierror-stashedit-missingtext": "لم يتم العثور على نص متقطع مع رمز الرقم المحدد.",
+       "apierror-stashfailed-complete": "تم اكتمال الرفع المقسم بالفعل، تحقق من الحالة للتفاصيل.",
+       "apierror-stashfailed-nosession": "لا توجد جلسة رفع مقسمة بهذا المفتاح.",
+       "apierror-stashfilestorage": "تعذر تخزين الرفع في المخبأ: $1",
+       "apierror-stashinvalidfile": "ملف مخفي غير صالح.",
+       "apierror-stashnosuchfilekey": "لا يوجد مفتاح ملف كهذا: $1.",
+       "apierror-stashpathinvalid": "مفتاح الملف بتنسيق غير لائق أو غير صالح بأي شكل آخر: $1.",
+       "apierror-stashwrongowner": "مالك غير صحيح: $1",
+       "apierror-stashzerolength": "الملف ذو طول صفري، ولا يمكن تخزينه في المخبأ: $1.",
+       "apierror-systemblocked": "لقد تم منعك تلقائيا بواسطة ميدياويكي.",
+       "apierror-templateexpansion-notwikitext": "توسيع القالب مدعوم لمحتوى نص الويكي فقط، يستخدم $1 نموذج المحتوى $2.",
        "apierror-timeout": "لم يستجب الخادم ضمن الوقت المتوقع.",
-       "api-feed-error-title": "خطأ ($1)"
+       "apierror-toofewexpiries": "$1 انتهت صلاحية {{PLURAL:$1|الطابع الزمني المقدم|الطوابع الزمنية المقدمة}} حيث كان يلزم توفر $2 {{PLURAL:$2|ه|ها}}.",
+       "apierror-toomanyvalues": "تم توفير قيم كثيرة جدا للوسيط <var>$1</var>، الحد هو $2.",
+       "apierror-unknownaction": "لم يتم التعرف على الإجراء المحدد <kbd>$1</kbd>.",
+       "apierror-unknownerror-editpage": "خطأ غير معروف في صفحة التعديل: $1.",
+       "apierror-unknownerror-nocode": "خطأ غير معروف.",
+       "apierror-unknownerror": "خطأ غير معروف: \"$1\".",
+       "apierror-unknownformat": "تنسيق غير معروف \"$1\".",
+       "apierror-unrecognizedparams": "{{PLURAL:$2|وسيط غير معترف به|وسائط غير معترف بها}}: $1.",
+       "apierror-unrecognizedvalue": "قيمة غير معروفة للوسيط <var>$1</var>: $2.",
+       "apierror-unsupportedrepo": "مستودع الملفات المحلي لا يدعم الاستعلام عن كل الصور.",
+       "apierror-upload-filekeyneeded": "يجب توفير Must supply a <var>filekey</var> عندما يكون <var>offset</var> غير صفري.",
+       "apierror-upload-filekeynotallowed": "لا يمكن توفير <var>filekey</var> عندما يكون <var>offset</var> 0.",
+       "apierror-upload-inprogress": "الرفع من المخبأ قيد التقدم بالفعل.",
+       "apierror-upload-missingresult": "لا توجد نتيجة في بيانات الحالة.",
+       "apierror-urlparamnormal": "تعذر تطبيع وسائط الصور لـ$1.",
+       "apierror-writeapidenied": "لا يُسمَح لك بتعديل هذا الويكي من خلال API.",
+       "apiwarn-alldeletedrevisions-performance": "للحصول على أداء أفضل عند إنشاء العناوين; اضبط <kbd>$1dir=newer</kbd>.",
+       "apiwarn-badurlparam": "تعذر تحليل <var>$1urlparam</var> لـ$2، باستخدام العرض والطول فقط.",
+       "apiwarn-badutf8": "تحتوي القيمة التي تم تمريرها لـ<var>$1</var> على بيانات غير صالحة أو غير طبيعية، يجب أن تكون البيانات النصية صالحة، NFC-normalized Unicode بدون أحرف تحكم C0 غير HT (\\t) وLF (\\n) وCR (\\r).",
+       "apiwarn-checktoken-percentencoding": "تحقق من أن الرموز مثل \"+\" في الرمز المميز يتم ترميزها بشكل صحيح في المسار.",
+       "apiwarn-compare-nocontentmodel": "لا يمكن تحديد نموذج محتوى، على افتراض $1.",
+       "apiwarn-deprecation-deletedrevs": "تم إيقاف <kbd>list=deletedrevs</kbd>; الرجاء استخدام <kbd>prop=deletedrevisions</kbd> or <kbd>list=alldeletedrevisions</kbd> بدلا من ذلك.",
+       "apiwarn-deprecation-httpsexpected": "HTTP المستخدمة عند توقع HTTPS.",
+       "apiwarn-deprecation-login-botpw": "تم إيقاف تسجيل الدخول إلى الحساب الرئيسي عبر <kbd>action=login</kbd> وقد يتوقف عن العمل دون سابق إنذار، لمتابعة تسجيل الدخول باستخدام <kbd>action=login</kbd>; راجع [[Special:BotPasswords]]، لمتابعة استخدام تسجيل الدخول إلى الحساب الرئيسي بأمان; راجع <kbd>action=clientlogin</kbd>.",
+       "apiwarn-deprecation-login-nobotpw": "تم إيقاف تسجيل الدخول إلى الحساب الرئيسي عبر <kbd>action=login</kbd>، وقد يتوقف عن العمل دون سابق إنذار، لتسجيل الدخول بأمان; راجع <kbd>action=clientlogin</kbd>.",
+       "apiwarn-deprecation-login-token": "تم إيقاف عمل رمز مميز عبر <kbd>action=login</kbd> ;استخدم <kbd>action=query&meta=tokens&type=login</kbd> بدلا من ذلك.",
+       "apiwarn-deprecation-parameter": "تم إيقاف الوسيط <var>$1</var>.",
+       "apiwarn-deprecation-parse-headitems": "تم إيقاف <kbd>prop=headitems</kbd> منذ ميدياويكي 1.28; استخدم <kbd>prop=headhtml</kbd> عند إنشاء مستندات HTML جديدة، أو <kbd>prop=modules|jsconfigvars</kbd> عند تحديث مستند من جانب العميل.",
+       "apiwarn-deprecation-purge-get": "تم إيقاف استخدام <kbd>action=purge</kbd> عبر GET; استخدم POST بدلا من ذلك.",
+       "apiwarn-deprecation-withreplacement": "تم إيقاف <kbd>$1</kbd>; الرجاء استخدام <kbd>$2</kbd> بدلا من ذلك.",
+       "apiwarn-difftohidden": "لا يمكنك إجراء مقارنة مع r$1: المحتوى مخفي.",
+       "apiwarn-errorprinterfailed": "فشل خطأ الطباعة; سوف يعيد دون وسائط.",
+       "apiwarn-errorprinterfailed-ex": "فشل خطأ الطباعة (سوف يعيد دون وسائط): $1.",
+       "apiwarn-ignoring-invalid-templated-value": "تجاهل القيمة <kbd>$2</kbd> في <var>$1</var> عند معالجة وسائط القوالب.",
+       "apiwarn-invalidcategory": "\"$1\" ليس تصنيفا.",
+       "apiwarn-invalidtitle": "\"$1\" ليس عنوانا صالحا.",
+       "apiwarn-invalidxmlstylesheetext": "يجب أن تحتوي ورقة الأنماط على الملحق <code>.xsl</code> extension.",
+       "apiwarn-invalidxmlstylesheet": "ورقة أنماط غير صالحة أو غير موجودة محددة.",
+       "apiwarn-invalidxmlstylesheetns": "يجب أن تكون ورقة الأنماط في نطاق {{ns:MediaWiki}}.",
+       "apiwarn-moduleswithoutvars": "تم تعيين الخاصية <kbd>modules</kbd> ولكن ليست <kbd>jsconfigvars</kbd> أو <kbd>encodedjsconfigvars</kbd>، متغيرات التكوين ضرورية للاستخدام السليم للوحدة.",
+       "apiwarn-notfile": "\"$1\" ليس ملفا.",
+       "apiwarn-nothumb-noimagehandler": "تعذر إنشاء الصورة المصغرة نظرا لعدم احتواء $1 على معالج صورة مقترن.",
+       "apiwarn-parse-nocontentmodel": "لم يتم إعطاء <var>title</var> أو <var>contentmodel</var>، على افتراض $1.",
+       "apiwarn-parse-revidwithouttext": "تم استخدام <var>revid</var> بدون <var>text</var>، وتم طلب خصائص الصفحة المحللة، هل تقصد استخدام <var>oldid</var> بدلا من <var>revid</var>؟",
+       "apiwarn-parse-titlewithouttext": "تم استخدام <var>title</var> بدون <var>text</var>، وتم طلب خصائص الصفحة المحللة، هل تقصد استخدام <var>page</var> بدلا من <var>title</var>؟",
+       "apiwarn-tokennotallowed": "الإجراء \"$1\" غير مسموح به للمستخدم الحالي.",
+       "apiwarn-tokens-origin": "قد لا يتم الحصول على الرموز عند عدم تطبيق السياسة الأصلية.",
+       "apiwarn-truncatedresult": "تم اقتطاع هذه النتيجة لأنها قد تكون أكبر من حد الـ$1 بايت.",
+       "apiwarn-unclearnowtimestamp": "تم إيقاف تمرير \"$2\" لوسيط الطابع الزمني <var>$1</var>; إذا احتجت لسبب ما إلى تحديد الوقت الحالي دون حسابه من جانب العميل، فاستخدم <kbd>now</kbd>.",
+       "apiwarn-unrecognizedvalues": "{{PLURAL:$3|قيمة|قيم}} غير معروفة للوسيط <var>$1</var>: $2.",
+       "apiwarn-unsupportedarray": "يستخدم الوسيط <var>$1</var> بنية مصفوفة PHP غير مدعومة.",
+       "apiwarn-urlparamwidth": "تجاهل قيمة العرض المحددة في <var>$1urlparam</var> ($2) لصالح قيمة العرض المشتقة من <var>$1urlwidth</var>/<var>$1urlheight</var> ($3).",
+       "apiwarn-validationfailed-badchars": "أحرف غير صالحة في المفتاح (مسموح فقط بـ<code>a-z</code> و<code>A-Z</code> و<code>0-9</code> و<code>_</code> و<code>-</code>).",
+       "apiwarn-validationfailed-badpref": "ليس تفضيلا صالحا.",
+       "apiwarn-validationfailed-cannotset": "لا يمكن ضبطها بواسطة هذه الوحدة.",
+       "apiwarn-validationfailed-keytoolong": "المفتاح طويل جدًا (لا يُسمَح بأكثر من $1 بايت).",
+       "apiwarn-validationfailed": "خطأ في التحقق من <kbd>$1</kbd>: $2",
+       "apiwarn-wgDebugAPI": "<strong>تحذير الأمان</strong>: تم تمكين <var>$wgDebugAPI</var>.",
+       "api-feed-error-title": "خطأ ($1)",
+       "api-usage-docref": "راجع $1 لاستخدام API.",
+       "api-usage-mailinglist-ref": "اشترك في القائمة البريدية لإعلان api ميدياويكي في &lt;https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce&gt ; للحصول على إشعار بإيقاف API وإيقاف التغييرات.",
+       "api-exception-trace": "$1 في $2($3)\n$4",
+       "api-credits-header": "الإحالات",
+       "api-credits": "مطورو API:\n* يوري أستراخان (مبتكر، المطور الرئيسي سبتمبر 2006 - سبتمبر 2007) \n* روان كاتو (المطور الرئيسي سبتمبر 2007-2009) \n* فيكتور فاسيليف \n* برايان تونغ مينه \n* سام ريد \n* براد يورش (المطور الرئيسي 2013 - الآن) \n\nيُرجَى إرسال تعليقاتك واقتراحاتك وأسئلتك لـmediawiki-api@lists.wikimedia.org\nأو إرسال تقريرا عن خطأ في https://phabricator.wikimedia.org/."
 }
index c69f267..09e4106 100644 (file)
@@ -15,7 +15,7 @@
                        "Ilimanaq29"
                ]
        },
-       "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<strong>Testování:</strong> Pro jednoduché testování požadavků na API zkuste [[Special:ApiSandbox]].",
+       "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>",
        "apihelp-main-param-action": "Která akce se má provést.",
        "apihelp-main-param-format": "Formát výstupu.",
        "apihelp-main-param-maxlag": "Maximální zpoždění lze použít, když je MediaWiki nainstalováno na cluster s replikovanou databází. Abyste se vyhnuli zhoršování už tak špatného replikačního zpoždění, můžete tímto parametrem nechat klienta čekat, dokud replikační zpoždění neklesne pod uvedenou hodnotu. V případě příliš vysokého zpoždění se vrátí chybový kód „<samp>maxlag</samp>“ s hlášením typu „<samp>Waiting for $host: $lag seconds lagged</samp>“.<br />Více informací najdete v [[mw:Special:MyLanguage/Manual:Maxlag_parameter|příručce]].",
index 86a22e6..5bdc3c9 100644 (file)
        "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-rootUrl": "Wurzel-URL-Pfad für Bildpfade.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-scriptDirUrl": "Wurzel-URL-Pfad für die MediaWiki-Installation des Repositoriumwikis.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-thumbUrl": "Wurzel-URL-Pfad für Vorschaubildpfade.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-url": "URL-Pfad der öffentlichen Zone.",
        "apihelp-query+filerepoinfo-example-simple": "Ruft Informationen über Dateirepositorien ab.",
        "apihelp-query+fileusage-summary": "Alle Seiten finden, die die angegebenen Dateien verwenden.",
        "apihelp-query+fileusage-param-prop": "Zurückzugebende Eigenschaften:",
        "apihelp-query+iwlinks-param-limit": "Wie viele Interwiki-Links zurückgegeben werden sollen.",
        "apihelp-query+iwlinks-param-prefix": "Gibt nur Interwiki-Links mit diesem Präfix zurück.",
        "apihelp-query+iwlinks-param-dir": "Die Auflistungsrichtung.",
+       "apihelp-query+langbacklinks-param-lang": "Sprache für den Sprachlink.",
        "apihelp-query+langbacklinks-param-limit": "Wie viele Gesamtseiten zurückgegeben werden sollen.",
        "apihelp-query+langbacklinks-param-prop": "Zurückzugebende Eigenschaften:",
        "apihelp-query+langbacklinks-paramvalue-prop-lltitle": "Ergänzt den Titel des Sprachlinks.",
        "apihelp-query+revisions+base-paramvalue-prop-user": "Benutzer, der die Version erstellt hat.",
        "apihelp-query+revisions+base-paramvalue-prop-userid": "Benutzerkennung des Versionserstellers.",
        "apihelp-query+revisions+base-paramvalue-prop-size": "Länge in Bytes der Version.",
+       "apihelp-query+revisions+base-paramvalue-prop-slotsize": "Länge (Bytes) eines jeden Versionsschlitzes.",
        "apihelp-query+revisions+base-paramvalue-prop-sha1": "SHA-1-Prüfsumme (Basis 16) der Version.",
-       "apihelp-query+revisions+base-paramvalue-prop-contentmodel": "Inhaltsmodell-Kennung der Version.",
-       "apihelp-query+revisions+base-paramvalue-prop-content": "Text 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-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-what": "Welcher Suchtyp ausgeführt werden soll.",
        "apihelp-query+search-param-info": "Welche Metadaten zurückgegeben werden sollen.",
        "apihelp-query+search-param-prop": "Eigenschaften zur Rückgabe:",
        "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-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+search-example-simple": "Nach <kbd>meaning</kbd> suchen.",
        "apihelp-query+search-example-text": "Texte nach <kbd>meaning</kbd> durchsuchen.",
        "apihelp-query+siteinfo-paramvalue-prop-specialpagealiases": "Liste von Spezialseiten-Aliasse.",
        "apierror-stashwrongowner": "Falscher Besitzer: $1",
        "apierror-systemblocked": "Du wurdest von MediaWiki automatisch gesperrt.",
        "apierror-timeout": "Der Server hat nicht innerhalb der erwarteten Zeit reagiert.",
+       "apierror-toomanyvalues": "Es wurden zu viele Werte für den Parameter <var>$1</var> angegeben. Die Obergrenze liegt bei $2.",
        "apierror-unknownerror-nocode": "Unbekannter Fehler.",
        "apierror-unknownerror": "Unbekannter Fehler: „$1“.",
        "apierror-unknownformat": "Nicht erkanntes Format „$1“.",
+       "apiwarn-deprecation-missingparam": "Da <var>$1</var> nicht angegeben wurde, wurde ein veraltetes Format für die Ausgabe verwendet. Dieses Format ist veraltet und in Zukunft wird immer das neue Format benutzt.",
        "apiwarn-ignoring-invalid-templated-value": "Ignorieren des Wertes <kbd>$2</kbd> in <var>$1</var> bei der Verarbeitung von Vorlagenparametern.",
        "apiwarn-invalidcategory": "„$1“ ist keine Kategorie.",
        "apiwarn-invalidtitle": "„$1“ ist kein gültiger Titel.",
        "apiwarn-notfile": "„$1“ ist keine Datei.",
        "apiwarn-parse-revidwithouttext": "<var>revid</var>, ohne <var>text</var> verwendet, und geparste Seiteneigenschaften wurden angefordert. Wolltest du <var>oldid</var> anstatt <var>revid</var> verwenden?",
-       "apiwarn-toomanyvalues": "Es wurden zu viele Werte für den Parameter <var>$1</var> angegeben. Die Obergrenze liegt bei $2.",
        "apiwarn-validationfailed-badpref": "Keine gültige Einstellung.",
        "apiwarn-validationfailed-cannotset": "Kann nicht von diesem Modul festgelegt werden.",
        "apiwarn-validationfailed-keytoolong": "Der Schlüssel ist zu lang. Es sind nicht mehr als $1 Bytes erlaubt.",
index 68bf603..3c74f25 100644 (file)
        "apihelp-query+filearchive-example-simple": "Show a list of all deleted files.",
 
        "apihelp-query+filerepoinfo-summary": "Return meta information about image repositories configured on the wiki.",
-       "apihelp-query+filerepoinfo-param-prop": "Which repository properties to get (there may be more available on some wikis):\n;apiurl:URL to the repository API - helpful for getting image info from the host.\n;name:The key of the repository - used in e.g. <var>[[mw:Special:MyLanguage/Manual:$wgForeignFileRepos|$wgForeignFileRepos]]</var> and [[Special:ApiHelp/query+imageinfo|imageinfo]] return values.\n;displayname:The human-readable name of the repository wiki.\n;rooturl:Root URL for image paths.\n;local:Whether that repository is the local one or not.",
+       "apihelp-query+filerepoinfo-param-prop": "Which repository properties to get (properties available may vary on other wikis).",
+       "apihelp-query+filerepoinfo-paramvalue-prop-apiurl": "URL to the repository API - helpful for getting image info from the host.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-articlepath": "Repository wiki's <var>[[mw:Special:MyLanguage/Manual:$wgArticlePath|$wgArticlePath]]</var> or equivalent.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-canUpload": "Whether files can be uploaded to this repository, e.g. via CORS and shared authentication.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-displayname": "The human-readable name of the repository wiki.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-favicon": "Repository wiki's favicon URL, from <var>[[mw:Special:MyLanguage/Manual:$wgFavicon|$wgFavicon]]</var>.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-fetchDescription": "Whether file description pages are fetched from this repository when viewing local file description pages.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-initialCapital": "Whether file names implicitly start with a capital letter.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-local": "Whether that repository is the local one or not.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-name": "The key of the repository - used in e.g. <var>[[mw:Special:MyLanguage/Manual:$wgForeignFileRepos|$wgForeignFileRepos]]</var> and [[Special:ApiHelp/query+imageinfo|imageinfo]] return values.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-rootUrl": "Root URL path for image paths.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-scriptDirUrl": "Root URL path for the repository wiki's MediaWiki installation.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-server": "Repository wiki's <var>[[mw:Special:MyLanguage/Manual:$wgServer|$wgServer]]</var> or equivalent.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-thumbUrl": "Root URL path for thumbnail paths.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-url": "Public zone URL path.",
        "apihelp-query+filerepoinfo-example-simple": "Get information about file repositories.",
 
        "apihelp-query+fileusage-summary": "Find all pages that use the given files.",
        "apihelp-query+recentchanges-param-limit": "How many total changes to return.",
        "apihelp-query+recentchanges-param-type": "Which types of changes to show.",
        "apihelp-query+recentchanges-param-toponly": "Only list changes which are the latest revision.",
+       "apihelp-query+recentchanges-param-title": "Filter entries to those related to a page.",
        "apihelp-query+recentchanges-param-generaterevisions": "When being used as a generator, generate revision IDs rather than titles. Recent change entries without associated revision IDs (e.g. most log entries) will generate nothing.",
        "apihelp-query+recentchanges-example-simple": "List recent changes.",
        "apihelp-query+recentchanges-example-generator": "Get page info about recent unpatrolled changes.",
        "apihelp-query+revisions+base-paramvalue-prop-user": "User that made the revision.",
        "apihelp-query+revisions+base-paramvalue-prop-userid": "User ID of the revision creator.",
        "apihelp-query+revisions+base-paramvalue-prop-size": "Length (bytes) of the revision.",
+       "apihelp-query+revisions+base-paramvalue-prop-slotsize": "Length (bytes) of each revision slot.",
        "apihelp-query+revisions+base-paramvalue-prop-sha1": "SHA-1 (base 16) of the revision.",
-       "apihelp-query+revisions+base-paramvalue-prop-contentmodel": "Content model ID of the revision.",
+       "apihelp-query+revisions+base-paramvalue-prop-slotsha1": "SHA-1 (base 16) of each revision slot.",
+       "apihelp-query+revisions+base-paramvalue-prop-contentmodel": "Content model ID of each revision slot.",
        "apihelp-query+revisions+base-paramvalue-prop-comment": "Comment by the user for the revision.",
        "apihelp-query+revisions+base-paramvalue-prop-parsedcomment": "Parsed comment by the user for the revision.",
-       "apihelp-query+revisions+base-paramvalue-prop-content": "Text of the revision.",
+       "apihelp-query+revisions+base-paramvalue-prop-content": "Content of each revision slot.",
        "apihelp-query+revisions+base-paramvalue-prop-tags": "Tags for the revision.",
-       "apihelp-query+revisions+base-paramvalue-prop-parsetree": "<span class=\"apihelp-deprecated\">Deprecated.</span> Use <kbd>[[Special:ApiHelp/expandtemplates|action=expandtemplates]]</kbd> or <kbd>[[Special:ApiHelp/parse|action=parse]]</kbd> instead. The XML parse tree of revision content (requires content model <code>$1</code>).",
+       "apihelp-query+revisions+base-paramvalue-prop-roles": "List content slot roles that exist in the revision.",
+       "apihelp-query+revisions+base-paramvalue-prop-parsetree": "Use <kbd>[[Special:ApiHelp/expandtemplates|action=expandtemplates]]</kbd> or <kbd>[[Special:ApiHelp/parse|action=parse]]</kbd> instead. The XML parse tree of revision content (requires content model <code>$1</code>).",
+       "apihelp-query+revisions+base-param-slots": "Which revision slots to return data for, when slot-related properties are included in <var>$1props</var>. If omitted, data from the <kbd>main</kbd> slot will be returned in a backwards-compatible format.",
        "apihelp-query+revisions+base-param-limit": "Limit how many revisions will be returned.",
        "apihelp-query+revisions+base-param-expandtemplates": "Use <kbd>[[Special:ApiHelp/expandtemplates|action=expandtemplates]]</kbd> instead. Expand templates in revision content (requires $1prop=content).",
        "apihelp-query+revisions+base-param-generatexml": "Use <kbd>[[Special:ApiHelp/expandtemplates|action=expandtemplates]]</kbd> or <kbd>[[Special:ApiHelp/parse|action=parse]]</kbd> instead. Generate XML parse tree for revision content (requires $1prop=content).",
        "apihelp-query+search-param-interwiki": "Include interwiki results in the search, if available.",
        "apihelp-query+search-param-backend": "Which search backend to use, if not the default.",
        "apihelp-query+search-param-enablerewrites": "Enable internal query rewriting. Some search backends can rewrite the query into another which is thought to provide better results, for instance by correcting spelling errors.",
+       "apihelp-query+search-param-sort": "Set the sort order of returned results.",
        "apihelp-query+search-example-simple": "Search for <kbd>meaning</kbd>.",
        "apihelp-query+search-example-text": "Search texts for <kbd>meaning</kbd>.",
        "apihelp-query+search-example-generator": "Get page info about the pages returned for a search for <kbd>meaning</kbd>.",
        "apierror-copyuploadbadurl": "Upload not allowed from this URL.",
        "apierror-create-titleexists": "Existing titles can't be protected with <kbd>create</kbd>.",
        "apierror-csp-report": "Error processing CSP report: $1.",
-       "apierror-databaseerror": "[$1] Database query error.",
        "apierror-deletedrevs-param-not-1-2": "The <var>$1</var> parameter cannot be used in modes 1 or 2.",
        "apierror-deletedrevs-param-not-3": "The <var>$1</var> parameter cannot be used in mode 3.",
        "apierror-emptynewsection": "Creating empty new sections is not possible.",
        "apierror-emptypage": "Creating new, empty pages is not allowed.",
        "apierror-exceptioncaught": "[$1] Exception caught: $2",
+       "apierror-exceptioncaughttype": "[$1] Caught exception of type $2",
        "apierror-filedoesnotexist": "File does not exist.",
        "apierror-fileexists-sharedrepo-perm": "The target file exists on a shared repository. Use the <var>ignorewarnings</var> parameter to override it.",
        "apierror-filenopath": "Cannot get local file path.",
        "apierror-sectionsnotsupported": "Sections are not supported for content model $1.",
        "apierror-sectionsnotsupported-what": "Sections are not supported by $1.",
        "apierror-show": "Incorrect parameter - mutually exclusive values may not be supplied.",
-       "apierror-siteinfo-includealldenied": "Cannot view all servers' info unless <var>$wgShowHostNames</var> is true.",
+       "apierror-siteinfo-includealldenied": "Cannot view all servers' info unless <var>$wgShowHostnames</var> is true.",
        "apierror-sizediffdisabled": "Size difference is disabled in Miser Mode.",
        "apierror-spamdetected": "Your edit was refused because it contained a spam fragment: <code>$1</code>.",
        "apierror-specialpage-cantexecute": "You don't have permission to view the results of this special page.",
        "apiwarn-checktoken-percentencoding": "Check that symbols such as \"+\" in the token are properly percent-encoded in the URL.",
        "apiwarn-compare-nocontentmodel": "No content model could be determined, assuming $1.",
        "apiwarn-deprecation-deletedrevs": "<kbd>list=deletedrevs</kbd> has been deprecated. Please use <kbd>prop=deletedrevisions</kbd> or <kbd>list=alldeletedrevisions</kbd> instead.",
-       "apiwarn-deprecation-expandtemplates-prop": "Because no values have been specified for the <var>prop</var> parameter, a legacy format has been used for the output. This format is deprecated, and in the future, a default value will be set for the <var>prop</var> parameter, causing the new format to always be used.",
        "apiwarn-deprecation-httpsexpected": "HTTP used when HTTPS was expected.",
        "apiwarn-deprecation-login-botpw": "Main-account login via <kbd>action=login</kbd> is deprecated and may stop working without warning. To continue login with <kbd>action=login</kbd>, see [[Special:BotPasswords]]. To safely continue using main-account login, see <kbd>action=clientlogin</kbd>.",
        "apiwarn-deprecation-login-nobotpw": "Main-account login via <kbd>action=login</kbd> is deprecated and may stop working without warning. To safely log in, see <kbd>action=clientlogin</kbd>.",
        "apiwarn-deprecation-login-token": "Fetching a token via <kbd>action=login</kbd> is deprecated. Use <kbd>action=query&meta=tokens&type=login</kbd> instead.",
+       "apiwarn-deprecation-missingparam": "Because <var>$1</var> was not specified, a legacy format has been used for the output. This format is deprecated, and in the future the new format will always be used.",
        "apiwarn-deprecation-parameter": "The parameter <var>$1</var> has been deprecated.",
        "apiwarn-deprecation-parse-headitems": "<kbd>prop=headitems</kbd> is deprecated since MediaWiki 1.28. Use <kbd>prop=headhtml</kbd> when creating new HTML documents, or <kbd>prop=modules|jsconfigvars</kbd> when updating a document client-side.",
        "apiwarn-deprecation-purge-get": "Use of <kbd>action=purge</kbd> via GET is deprecated. Use POST instead.",
index 5d0c27a..f807411 100644 (file)
@@ -30,7 +30,8 @@
                        "Fortega",
                        "Luzcaru",
                        "Javiersanp",
-                       "KATRINE1992"
+                       "KATRINE1992",
+                       "Adjen"
                ]
        },
        "apihelp-main-extended-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:Special:MyLanguage/API:Main_page|Documentation]]\n* [[mw:Special:MyLanguage/API:FAQ|FAQ]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Mailing list]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce API Announcements]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Bugs & requests]\n</div>\n<strong>Status:</strong> Todas las funciones mostradas en esta página deberían estar funcionando, pero la API aún está en desarrollo activo, y puede cambiar en cualquier momento. Suscribase a [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ the mediawiki-api-announce mailing list] para aviso de actualizaciones.\n\n<strong>Erroneous requests:</strong> Cuando se envían solicitudes erróneas a la API, se enviará un encabezado HTTP con la clave \"MediaWiki-API-Error\" y, luego, el valor del encabezado y el código de error devuelto se establecerán en el mismo valor. Para más información ver [[mw:Special:MyLanguage/API:Errors_and_warnings|API: Errors and warnings]].\n\n<strong>Testing:</strong> Para facilitar la comprobación de las solicitudes de API, consulte [[Special:ApiSandbox]].",
        "apihelp-query+recentchanges-param-limit": "Cuántos cambios en total se devolverán.",
        "apihelp-query+recentchanges-param-type": "Cuántos tipos de cambios se mostrarán.",
        "apihelp-query+recentchanges-param-toponly": "Enumerar solo las modificaciones que sean las últimas revisiones.",
+       "apihelp-query+recentchanges-param-title": "Filtrar entradas mostrando solo aquellas relacionadas con una página.",
        "apihelp-query+recentchanges-param-generaterevisions": "Cuando se utilice como generador, genera identificadores de revisión en lugar de títulos. Las entradas en la lista de cambios recientes que no tengan identificador de revisión asociado (por ejemplo, la mayoría de las entradas de registro) no generarán nada.",
        "apihelp-query+recentchanges-example-simple": "Lista de cambios recientes.",
        "apihelp-query+recentchanges-example-generator": "Obtener información de página de cambios recientes no patrullados.",
        "apierror-copyuploadbadurl": "No se permite realizar cargas a partir de este URL.",
        "apierror-create-titleexists": "Los títulos existentes no se pueden proteger con <kbd>create</kbd>.",
        "apierror-csp-report": "Error de procesamiento del informe CSP: $1.",
-       "apierror-databaseerror": "[$1] Error en la consulta de la base de datos.",
        "apierror-deletedrevs-param-not-1-2": "El parámetro <var>$1</var> no se puede utilizar en los modos 1 o 2.",
        "apierror-deletedrevs-param-not-3": "El parámetro <var>$1</var> no se puede usar en modo 3.",
        "apierror-emptynewsection": "Crear secciones vacías no es posible.",
        "apierror-sectionsnotsupported": "Las secciones no son compatibles con el modelo de contenido $1.",
        "apierror-sectionsnotsupported-what": "Las secciones no son compatibles con $1.",
        "apierror-show": "Parámetro incorrecto: no se pueden proporcionar valores mutuamente excluyentes.",
-       "apierror-siteinfo-includealldenied": "No se puede ver la información de todos los servidores a menos que <var>$wgShowHostNames</var> tenga valor verdadero.",
+       "apierror-siteinfo-includealldenied": "No se puede ver la información de todos los servidores a menos que <var>$wgShowHostnames</var> tenga valor verdadero.",
        "apierror-sizediffdisabled": "La diferencia de tamaño está deshabilitada en el modo avaro.",
        "apierror-spamdetected": "Tu edición fue rechazada por contener un fragmento de spam: <code>$1</code>.",
        "apierror-specialpage-cantexecute": "No tienes permiso para ver los resultados de esta página especial.",
        "apierror-systemblocked": "Has sido bloqueado automáticamente por el software MediaWiki.",
        "apierror-templateexpansion-notwikitext": "La expansión de plantillas solo es compatible con el contenido en wikitexto. $1 usa el modelo de contenido $2.",
        "apierror-timeout": "El servidor no respondió en el plazo previsto.",
+       "apierror-toomanyvalues": "Se proporcionaron demasiados valores al parámetro <var>$1</var>. El límite es de $2.",
        "apierror-unknownaction": "La acción especificada, <kbd>$1</kbd>, no está reconocida.",
        "apierror-unknownerror-editpage": "Error de EditPage desconocido: $1.",
        "apierror-unknownerror-nocode": "Error desconocido.",
        "apiwarn-badurlparam": "No se pudo analizar <var>$1urlparam</var> para $2. Se utilizarán solamente la anchura y altura.",
        "apiwarn-badutf8": "El valor pasado para <var>$1</var> contiene datos no válidos o no normalizados. Los datos textuales deberían estar en Unicode válido, normalizado en NFC y sin caracteres de control C0 excepto HT (\\t), LF (\\n) y CR (\\r).",
        "apiwarn-deprecation-deletedrevs": "<kbd>list=deletedrevs</kbd> ha quedado obsoleto. En su lugar, utiliza <kbd>prop=deletedrevisions</kbd> o <kbd>list=alldeletedrevisions</kbd>.",
-       "apiwarn-deprecation-expandtemplates-prop": "Como no se ha especificado ningún valor para el parámetro <var>prop</var>, se ha utilizado un formato heredado para la salida. Este formato está en desuso y, en el futuro, el parámetro <var>prop</var> tendrá un valor predeterminado, de forma que siempre se utilizará el formato nuevo.",
        "apiwarn-deprecation-httpsexpected": "Se ha utilizado HTTP cuando se esperaba HTTPS.",
        "apiwarn-deprecation-login-botpw": "El inicio de sesión con la cuenta principal mediante <kbd>action=login</kbd> está en desuso y puede dejar de funcionar sin aviso previo. Para proseguir el inicio de sesión mediante <kbd>action=login</kbd>, véase [[Special:BotPasswords]]. Para proseguir el inicio de sesión con la cuenta principal de forma segura, véase <kbd>action=clientlogin</kbd>.",
        "apiwarn-deprecation-login-nobotpw": "El inicio de sesión con la cuenta principal mediante <kbd>action=login</kbd> está en desuso y puede dejar de funcionar sin aviso previo. Para iniciar sesión de forma segura, véase <kbd>action=clientlogin</kbd>.",
        "apiwarn-invalidxmlstylesheetns": "La hoja de estilos debería estar en el espacio de nombres {{ns:MediaWiki}}.",
        "apiwarn-moduleswithoutvars": "La propiedad <kbd>modules</kbd> está definida, pero no lo está <kbd>jsconfigvars</kbd> ni <kbd>encodedjsconfigvars</kbd>. Las variables de configuración son necesarias para el correcto uso del módulo.",
        "apiwarn-notfile": "\"$1\" no es un archivo.",
+       "apiwarn-nothumb-noimagehandler": "No se pudo crear la miniatura porque «$1» no tiene ningún manipulador de imágenes asociado.",
        "apiwarn-parse-nocontentmodel": "No se proporcionó <var>title</var> ni <var>contentmodel</var>. Se asume $1.",
        "apiwarn-tokennotallowed": "La acción «$1» no está permitida para el usuario actual.",
        "apiwarn-truncatedresult": "Se ha truncado este resultado porque de otra manera sobrepasaría el límite de $1 bytes.",
index ab3f430..5652404 100644 (file)
        "apihelp-query+filearchive-paramvalue-prop-archivename": "Ajoute le nom de fichier de la version d’archive pour les versions autres que la dernière.",
        "apihelp-query+filearchive-example-simple": "Afficher une liste de tous les fichiers supprimés",
        "apihelp-query+filerepoinfo-summary": "Renvoyer les méta-informations sur les référentiels d’images configurés dans le wiki.",
-       "apihelp-query+filerepoinfo-param-prop": "Quelles propriétés du référentiel récupérer (il peut y en avoir plus de disponibles sur certains wikis) :\n;apiurl:URL de l’API du référentiel - utile pour obtenir les infos de l’image depuis l’hôte.\n;name:La clé du référentiel - utilisé par ex. dans les valeurs de retour de <var>[[mw:Special:MyLanguage/Manual:$wgForeignFileRepos|$wgForeignFileRepos]]</var> et [[Special:ApiHelp/query+imageinfo|imageinfo]].\n;displayname:Le nom lisible du wiki référentiel.\n;rooturl:URL racine des chemins d’image.\n;local:Si ce référentiel est le référentiel local ou non.",
+       "apihelp-query+filerepoinfo-param-prop": "Quelles propriétés récupérer du référentiel (les propriétés disponibles peuvent varier sur les autres wikis).",
+       "apihelp-query+filerepoinfo-paramvalue-prop-apiurl": "URL vers l’API du dépôt — utile pour obtenir des informations sur l’image depuis l’hôte.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-articlepath": "<var>[[mw:Special:MyLanguage/Manual:$wgArticlePath|$wgArticlePath]]</var> du wiki du dépôt, ou équivalent.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-canUpload": "Si les fichiers peuvent être téléversés sur ce dépôt, par exemple via CORS et l’authentification partagée.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-displayname": "Le nom lisible du wiki du dépôt.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-favicon": "URL de l'icône favorite du dépôt du wiki, depuis <var>[[mw:Special:MyLanguage/Manual:$wgFavicon|$wgFavicon]]</var>.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-fetchDescription": "Si les pages de description de fichier sont récupérées de ce dépôt lors de l’affichage des pages de description de fichier locales.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-initialCapital": "Si les noms de fichier commencent implicitement par une majuscule.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-local": "Si ce dépôt est local ou non.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-name": "La clé du dépôt — utilisée dans les valeurs de retour, par ex. <var>[[mw:Special:MyLanguage/Manual:$wgForeignFileRepos|$wgForeignFileRepos]]</var> et [[Special:ApiHelp/query+imageinfo|imageinfo]] return values.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-rootUrl": "Chemin de l’URL racine pour les chemins d’image.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-scriptDirUrl": "Chemin de l’URL racine pour l’installation de MédiaWiki du wiki du dépôt.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-server": "<var>[[mw:Special:MyLanguage/Manual:$wgServer|$wgServer]]</var> du wiki du dépôt, ou équivalent.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-thumbUrl": "Chemin de l’URL racine pour les chemins des vignettes.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-url": "Chemin de l’URL de la zone publique.",
        "apihelp-query+filerepoinfo-example-simple": "Obtenir des informations sur les référentiels de fichier.",
        "apihelp-query+fileusage-summary": "Trouver toutes les pages qui utilisent les fichiers donnés.",
        "apihelp-query+fileusage-param-prop": "Quelles propriétés obtenir :",
        "apihelp-query+recentchanges-param-limit": "Combien de modifications renvoyer au total.",
        "apihelp-query+recentchanges-param-type": "Quels types de modification afficher.",
        "apihelp-query+recentchanges-param-toponly": "Lister uniquement les modifications qui sont de la dernière révision.",
+       "apihelp-query+recentchanges-param-title": "Filtrer les entrées vers celles relatives à une page.",
        "apihelp-query+recentchanges-param-generaterevisions": "Utilisé comme générateur, générer des IDs de révision plutôt que des titres.\nLes entrées de modification récentes sans IDs de révision associé (par ex. la plupart des entrées de journaux) ne généreront rien.",
        "apihelp-query+recentchanges-example-simple": "Lister les modifications récentes",
        "apihelp-query+recentchanges-example-generator": "Obtenir l’information de page sur les modifications récentes non relues.",
        "apihelp-query+revisions+base-paramvalue-prop-user": "L’utilisateur qui a fait la révision.",
        "apihelp-query+revisions+base-paramvalue-prop-userid": "L’ID de l’utilisateur créateur de la révision.",
        "apihelp-query+revisions+base-paramvalue-prop-size": "Longueur (en octets) de la révision.",
+       "apihelp-query+revisions+base-paramvalue-prop-slotsize": "Longueur (en octets) de chaque emplacement de révision.",
        "apihelp-query+revisions+base-paramvalue-prop-sha1": "Hachage SHA-1 (base 16) de la révision.",
-       "apihelp-query+revisions+base-paramvalue-prop-contentmodel": "ID du modèle de contenu de la révision.",
+       "apihelp-query+revisions+base-paramvalue-prop-slotsha1": "SHA-1 (base 16) de chaque emplacement de révision.",
+       "apihelp-query+revisions+base-paramvalue-prop-contentmodel": "ID du modèle de contenu de chaque emplacement de révision.",
        "apihelp-query+revisions+base-paramvalue-prop-comment": "Commentaire de l’utilisateur sur la révision.",
        "apihelp-query+revisions+base-paramvalue-prop-parsedcomment": "Commentaire analysé de l’utilisateur sur la révision.",
-       "apihelp-query+revisions+base-paramvalue-prop-content": "Texte de la révision.",
+       "apihelp-query+revisions+base-paramvalue-prop-content": "Contenu de chaque emplacement de révision.",
        "apihelp-query+revisions+base-paramvalue-prop-tags": "Balises de la révision.",
-       "apihelp-query+revisions+base-paramvalue-prop-parsetree": "<span class=\"apihelp-deprecated\">Deprecated.</span> Utiliser  <kbd>[[Special:ApiHelp/expandtemplates|action=expandtemplates]]</kbd> ou <kbd>[[Special:ApiHelp/parse|action=parse]]</kbd> à la place. L’arbre d’analyse XML du contenu de la révision (nécessite le modèle de contenu <code>$1</code>).",
+       "apihelp-query+revisions+base-paramvalue-prop-roles": "Lister les rôles d’emplacement de contenu qui existent dans la révision.",
+       "apihelp-query+revisions+base-paramvalue-prop-parsetree": "Utiliser  <kbd>[[Special:ApiHelp/expandtemplates|action=expandtemplates]]</kbd> ou <kbd>[[Special:ApiHelp/parse|action=parse]]</kbd> à la place. L’arbre d’analyse XML du contenu de la révision (nécessite le modèle de contenu <code>$1</code>).",
+       "apihelp-query+revisions+base-param-slots": "Pour quels emplacements de révision renvoyer des données, quand les propriétés relatives aux emplacements sont incluses dans <var>$1props</var>. Si omis, les données de l’emplacement <kbd>main</kbd> seront renvoyées dans un format rétro-compatible.",
        "apihelp-query+revisions+base-param-limit": "Limiter le nombre de révisions retournées.",
        "apihelp-query+revisions+base-param-expandtemplates": "Utiliser <kbd>[[Special:ApiHelp/expandtemplates|action=expandtemplates]]</kbd> à la place. Développer les modèles dans le contenu de la révision (nécessite $1prop=content).",
        "apihelp-query+revisions+base-param-generatexml": "Utiliser <kbd>[[Special:ApiHelp/expandtemplates|action=expandtemplates]]</kbd> ou <kbd>[[Special:ApiHelp/parse|action=parse]]</kbd> à la place. Générer l’arbre d’analyse XML pour le contenu de la révision (nécessite $1prop=content).",
        "apihelp-query+search-param-interwiki": "Inclure les résultats interwiki dans la recherche, s’ils sont disponibles.",
        "apihelp-query+search-param-backend": "Quel serveur de recherche utiliser, si ce n’est pas celui par défaut.",
        "apihelp-query+search-param-enablerewrites": "Activer la réécriture interne de la requête. Les serveurs de recherche peuvent réécrire la requête en une autre qui est censée donner de meilleurs résultats, par exemple en corrigeant les erreurs d’orthographe.",
+       "apihelp-query+search-param-sort": "Fixe l’ordre de tri des résultats renvoyés.",
        "apihelp-query+search-example-simple": "Rechercher <kbd>meaning</kbd>.",
        "apihelp-query+search-example-text": "Rechercher des textes pour <kbd>meaning</kbd>.",
        "apihelp-query+search-example-generator": "Obtenir les informations sur les pages renvoyées par une recherche de <kbd>meaning</kbd>.",
        "api-help-datatypes-header": "Type de données",
        "api-help-datatypes": "Les entrées dans MédiaWiki doivent être en UTF-8 à la norme NFC. MédiaWiki peut tenter de convertir d’autres types d’entrée, mais cela peut faire échouer certaines opérations (comme les [[Special:ApiHelp/edit|modifications]] avec contrôles MD5) to fail.\n\nCertains types de paramètre dans les requêtes de l’API nécessitent plus d’explication :\n;boolean\n:Les paramètres booléens fonctionnent comme des cases à cocher HTML : si le paramètre est spécifié, quelle que soit sa valeur, il est considéré comme vrai. Pour une valeur fausse, enlever complètement le paramètre.\n;timestamp\n:Les horodatages peuvent être spécifiés sous différentes formes. Date et heure ISO 8601 est recommandé. Toutes les heures sont en UTC, tout fuseau horaire inclus est ignoré.\n:* Date et heure ISO 8601, <kbd><var>2001</var>-<var>01</var>-<var>15</var>T<var>14</var>:<var>56</var>:<var>00</var>Z</kbd> (la ponctuation et <kbd>Z</kbd> sont facultatifs)\n:* Date et heure ISO 8601 avec fractions de seconde (ignorées), <kbd><var>2001</var>-<var>01</var>-<var>15</var>T<var>14</var>:<var>56</var>:<var>00</var>.<var>00001</var>Z</kbd> (tirets, deux-points et <kbd>Z</kbd> sont facultatifs)\n:* Format MédiaWiki, <kbd><var>2001</var><var>01</var><var>15</var><var>14</var><var>56</var><var>00</var></kbd>\n:* Format numérique générique, <kbd><var>2001</var>-<var>01</var>-<var>15</var> <var>14</var>:<var>56</var>:<var>00</var></kbd> (fuseau horaire facultatif en <kbd>GMT</kbd>, <kbd>+<var>##</var></kbd>, ou <kbd>-<var>##</var></kbd> sont ignorés)\n:* Format EXIF, <kbd><var>2001</var>:<var>01</var>:<var>15</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:*Format RFC 2822 (le fuseau horaire est facultatif), <kbd><var>Mon</var>, <var>15</var> <var>Jan</var> <var>2001</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:* Format RFC 850 (le fuseau horaire est facultatif), <kbd><var>Monday</var>, <var>15</var>-<var>Jan</var>-<var>2001</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:* Format ctime C, <kbd><var>Mon</var> <var>Jan</var> <var>15</var> <var>14</var>:<var>56</var>:<var>00</var> <var>2001</var></kbd>\n:* Secondes depuis 1970-01-01T00:00:00Z sous forme d’entier de 1 à 13 chiffres (sans <kbd>0</kbd>)\n:* La chaîne <kbd>now</kbd>",
        "api-help-templatedparams-header": "Paramètres de modèle",
-       "api-help-templatedparams": "Les paramètres de modèle supportent les cas où un module d’API a besoin d’une valeur pour chaque valeur d’un autre paramètre quelconque. Par exemple, s’il y avait un module d’API pour demander un fruit, il pourrait avoir un paramètre <var>fruits</var> pour spécifier quels fruits sont demandés et un paramètre de modèle <var>{fruit}-quantité</var> pour spécifier combien de chaque fruit demander. Un client de l’API qui voudrait une pomme, cinq bananes et vingt fraises pourrait alors faire une requête comme <kbd>fruits=pommes|bananes|fraises&pommes-quantité=1&bananes-quantité=5&fraises-quantité=20</kbd>.",
+       "api-help-templatedparams": "Les paramètres de modèle supportent les cas où un module d’API a besoin d’une valeur pour chaque valeur d’un autre paramètre quelconque. Par exemple, s’il y avait un module d’API pour demander un fruit, il pourrait avoir un paramètre <var>fruits</var> pour spécifier quels fruits sont demandés et un paramètre de modèle <var>{fruit}-quantité</var> pour spécifier la quantité demandée de chaque fruit. Un client de l’API qui voudrait une pomme, cinq bananes et vingt fraises pourrait alors faire une requête comme <kbd>fruits=pommes|bananes|fraises&pommes-quantité=1&bananes-quantité=5&fraises-quantité=20</kbd>.",
        "api-help-param-type-limit": "Type : entier ou <kbd>max</kbd>",
        "api-help-param-type-integer": "Type : {{PLURAL:$1|1=entier|2=liste d’entiers}}",
        "api-help-param-type-boolean": "Type : booléen ([[Special:ApiHelp/main#main/datatypes|détails]])",
        "apierror-copyuploadbadurl": "Les téléversements ne sont pas autorisés depuis cette URL.",
        "apierror-create-titleexists": "Les titres existants ne peuvent pas être protégés avec <kbd>create</kbd>.",
        "apierror-csp-report": "Erreur lors du traitement du rapport CSP: $1.",
-       "apierror-databaseerror": "[$1] erreur de requête de base de données.",
        "apierror-deletedrevs-param-not-1-2": "Le paramètre <var>$1</var> ne peut pas être utilisé dans les modes 1 ou 2.",
        "apierror-deletedrevs-param-not-3": "Le paramètre <var>$1</var> ne peut pas être utilisé dans le mode 3.",
        "apierror-emptynewsection": "Il n'est pas possible de créer de nouvelles sections vides.",
        "apierror-emptypage": "Il n'est pas possible de créer de nouvelles pages vides.",
        "apierror-exceptioncaught": "[$1] Exception interceptée: $2",
+       "apierror-exceptioncaughttype": "[$1] Exception interceptée de type $2",
        "apierror-filedoesnotexist": "Le fichier n’existe pas.",
        "apierror-fileexists-sharedrepo-perm": "Le fichier cible existe dans un dépôt partagé. Utilisr le paramètre <var>ignorewarnings</var> pour l’écraser.",
        "apierror-filenopath": "Il n'est pas possible de récupérer le chemin du fichier local.",
        "apierror-sectionsnotsupported": "Les sections ne sont pas prises en charge pour le modèle de contenu $1.",
        "apierror-sectionsnotsupported-what": "Les sections ne sont pas prises en charge par $1.",
        "apierror-show": "Paramètre incorrect - des valeurs mutuellement exclusives ne peuvent pas être fournies.",
-       "apierror-siteinfo-includealldenied": "Impossible d’afficher toutes les informatiosn du serveur, sauf si <var>$wgShowHostNames</var> vaut vrai.",
+       "apierror-siteinfo-includealldenied": "Impossible d’afficher toutes les informatiosn du serveur, sauf si <var>$wgShowHostnames</var> vaut vrai.",
        "apierror-sizediffdisabled": "La différence de taille est désactivée dans le mode Miser.",
        "apierror-spamdetected": "Votre modification a été refusée parce qu’elle contenait un fragment de pourriel : <code>$1</code>.",
        "apierror-specialpage-cantexecute": "Vous n'avez pas l'autorisation d'afficher les résultats de cette page spéciale.",
        "apierror-templateexpansion-notwikitext": "Le développement du modèle n'est effectif que sur un contenu wikitext. $1 utilise le modèle de contenu $2.",
        "apierror-timeout": "Le serveur n’a pas répondu dans le délai imparti.",
        "apierror-toofewexpiries": "$1 {{PLURAL:$1|horodatage d’expiration a été fourni|horodatages d’expiration ont été fournis}} alors que $2 {{PLURAL:$2|était attendu|étaient attendus}}.",
+       "apierror-toomanyvalues": "Trop de valeurs fournies pour le paramètre <var>$1</var>. La  limite est $2.",
        "apierror-unknownaction": "L'action spécifiée, <kbd>$1</kbd>, n'est pas reconnue.",
        "apierror-unknownerror-editpage": "Erreur inconnue EditPage: $1.",
        "apierror-unknownerror-nocode": "Erreur inconnue.",
        "apiwarn-checktoken-percentencoding": "Vérifier que les symboles tels que \"+\" dans le jeton sont correctement  codés avec des pourcents dans l'URL.",
        "apiwarn-compare-nocontentmodel": "Aucun modèle de contenu n’a pu être déterminé, $1 est supposé.",
        "apiwarn-deprecation-deletedrevs": "<kbd>list=deletedrevs</kbd> est devenu désuet. Veuillez utiliser <kbd>prop=deletedrevisions</kbd> ou <kbd>list=alldeletedrevisions</kbd> à la place.",
-       "apiwarn-deprecation-expandtemplates-prop": "Comme aucune valeur n’a été spécifiée pour le paramètre <var>prop</var>, un format patrimonial a été utilisé pour la sortie. Ce format est désuet et, dans le futur, une valeur par défaut sera fixée pour le paramètre <var>prop</var>, provoquant ainsi l’utilisation systématique du nouveau format.",
        "apiwarn-deprecation-httpsexpected": "HTTP est utilisé alors que HTTPS est attendu.",
        "apiwarn-deprecation-login-botpw": "La connexion au compte principal via <kbd>action=login</kbd> est désuète et peut cesser de fonctionner sans avertissement. Pour continuer à vous connecter avec <kbd>action=login</kbd>, voyez [[Special:BotPasswords]]. Pour continuer à utiliser la connexion au compte principal en toute sécurité, voyez <kbd>action=clientlogin</kbd>.",
        "apiwarn-deprecation-login-nobotpw": "La connexion au compte principal via <kbd>action=login</kbd> est désuète et peut cesser de fonctionner sans avertissement. Pour vous connecter en toute sécurité, voyez <kbd>action=clientlogin</kbd>.",
        "apiwarn-deprecation-login-token": "La récupération d’un jeton via <kbd>action=login</kbd> est désuète. Utilisez <kbd>action=query&meta=tokens&type=login</kbd> à la place.",
+       "apiwarn-deprecation-missingparam": "Comme <var>$1</var> n’a pas été spécifié, un format ancien a été utilisé pour la sortie. Ce format est obsolète, et dans le futur, le nouveau format sera toujours utilisé.",
        "apiwarn-deprecation-parameter": "Le paramètre <var>$1</var> est désuet.",
        "apiwarn-deprecation-parse-headitems": "<kbd>prop=headitems</kbd> est désuet depuis MédiaWiki 1.28. Utilisez <kbd>prop=headhtml</kbd> lors de la création de nouveaux documents HTML, ou <kbd>prop=modules|jsconfigvars</kbd> lors de la mise à jour d’un document côté client.",
        "apiwarn-deprecation-purge-get": "L’utilisation de <kbd>action=purge</kbd> via un GET est désuète. Utiliser POST à la place.",
        "apiwarn-redirectsandrevids": "La résolution de la redirection ne peut pas être utilisée avec le paramètre <var>revids</var>. Toutes les redirections vers lesquelles pointent <var>revids</var> n’ont pas été résolues.",
        "apiwarn-tokennotallowed": "L'action « $1 » n'est pas autorisée pour l'utilisateur actuel.",
        "apiwarn-tokens-origin": "Les jetons ne peuvent pas être obtenus quand la politique de même origine n’est pas appliquée.",
-       "apiwarn-toomanyvalues": "Trop de valeurs fournies pour le paramètre <var>$1</var>. La  limite est $2.",
        "apiwarn-truncatedresult": "Ce résultat a été tronqué parce que sinon, il dépasserait la limite de $1 octets.",
        "apiwarn-unclearnowtimestamp": "Passer « $2 » comme paramètre d’horodatage <var>$1</var> a été rendu désuet. Si, pour une raison quelconque, vous avez besoin de spécifier explicitement l’heure courante sans la recalculer du côté client, utilisez <kbd>now</kbd>.",
        "apiwarn-unrecognizedvalues": "{{PLURAL:$3|Valeur non reconnue|Valeurs non reconnues}} pour le paramètre <var>$1</var> : $2.",
index 1f2b028..5103bd3 100644 (file)
        "apierror-copyuploadbadurl": "As subas non están permitidas para esta URL.",
        "apierror-create-titleexists": "Os títulos existentes non poden ser protexidos con <kbd>create</kbd>.",
        "apierror-csp-report": "Erro procesando o informe CSPː $1.",
-       "apierror-databaseerror": "[$1] erro de consulta da base de datos.",
        "apierror-deletedrevs-param-not-1-2": "O parámetro <var>$1</var> non pode usarse nos modos 1 e 2.",
        "apierror-deletedrevs-param-not-3": "O parámetro <var>$1</var> non pode usarse no modo 3.",
        "apierror-emptynewsection": "Non é posible crear novas seccións baleiras.",
        "apierror-sectionsnotsupported": "As seccións non son compatibles co modelo de contido $1.",
        "apierror-sectionsnotsupported-what": "As seccións non son compatibles con $1.",
        "apierror-show": "Parámetro incorrecto - non se poden proporcionar valores mutuamente excluíntes.",
-       "apierror-siteinfo-includealldenied": "Non se pode ver a información de tódolos servidores a menos que <var>$wgShowHostNames</var> teña valor verdadeiro.",
+       "apierror-siteinfo-includealldenied": "Non se pode ver a información de tódolos servidores a menos que <var>$wgShowHostnames</var> teña valor verdadeiro.",
        "apierror-sizediffdisabled": "A diferenza de tamaño está deshabilitada no modo Miser.",
        "apierror-spamdetected": "A súa edición foi rexeitada por conter un fragmento de publicidade: <code>$1</code>.",
        "apierror-specialpage-cantexecute": "Non ten permiso para ver os resultados desta páxina especial.",
        "apierror-systemblocked": "Foi bloqueado automaticamente polo software MediaWiki.",
        "apierror-templateexpansion-notwikitext": "A expansión de modelos só é compatible co contido en wikitexto. $1 usa o modelo de contido $2.",
        "apierror-timeout": "O servidor non respondeu no tempo esperado.",
+       "apierror-toomanyvalues": "Demasiados valores para o parámetro <var>$1</var>. O límite é $2.",
        "apierror-unknownaction": "A acción especificada, <kbd>$1</kbd>, non está recoñecida.",
        "apierror-unknownerror-editpage": "Erro descoñecido EditPageː $1.",
        "apierror-unknownerror-nocode": "Erro descoñecido.",
        "apiwarn-badurlparam": "Non se puido analizar <var>$1urlparam</var> para $2. Só se usará a anchura e a altura.",
        "apiwarn-badutf8": "O valor pasado para <var>$1</var> contén datos non válidos ou non normalizados. Os datos de texto deberían estar en formato Unicode válido, normalizado en NFC e sen caracteres de control C0 distintos de HT (\\t), LF (\\n) e CR (\\r).",
        "apiwarn-deprecation-deletedrevs": "<kbd>list=deletedrevs</kbd> quedou obsoleto. No seu lugar, utilice <kbd>prop=deletedrevisions</kbd> ou <kbd>list=alldeletedrevisions</kbd>.",
-       "apiwarn-deprecation-expandtemplates-prop": "Como non se especificou ningún valor para o parámetro <var>prop</var>, utilizouse un formato herdado para a saída. Este formato está en desuso e, no futuro, o parámetro <var>prop</var> terá un valor predeterminado, de forma que sempre se utilizará o formato novo.",
        "apiwarn-deprecation-httpsexpected": "Utilizouse HTTP cando esperábase HTTPS.",
        "apiwarn-deprecation-login-botpw": "O inicio de sesión coa conta principal mediante <kbd>action=login</kbd> está en desuso e pode deixar de funcionar sen aviso previo. Para proseguir o inicio de sesión mediante <kbd>action=login</kbd>, consulte [[Special:BotPasswords]]. Para proseguir o inicio de sesión coa conta principal de forma segura, consulte <kbd>action=clientlogin</kbd>.",
        "apiwarn-deprecation-login-nobotpw": "O inicio de sesión coa conta principal mediante <kbd>action=login</kbd> está en desuso e pode deixar de funcionar sen aviso previo. Para iniciar sesión de forma segura, consulte <kbd>action=clientlogin</kbd>.",
        "apiwarn-notfile": "\"$1\" non é un ficheiro.",
        "apiwarn-parse-nocontentmodel": "Non se proporcionou <var>title</var> nin <var>contentmodel</var>, asúmese $1.",
        "apiwarn-tokennotallowed": "A acción \"$1\" non está permitida para o usuario actual.",
-       "apiwarn-toomanyvalues": "Demasiados valores para o parámetro <var>$1</var>. O límite é $2.",
        "apiwarn-truncatedresult": "Truncouse este resultado porque doutra maneira sobrepasaría o límite de $1 bytes.",
        "apiwarn-unrecognizedvalues": "{{PLURAL:$3|Valor non recoñecido|Valores non recoñecidos}} para o parámetro <var>$1</var>: $2.",
        "apiwarn-unsupportedarray": "O parámetro <var>$1</var> usa unha sintaxe PHP de matriz que non está soportada.",
index 911ac2f..e2c73c2 100644 (file)
        "apihelp-query+filearchive-paramvalue-prop-archivename": "הוספת שם הקובץ של גרסה מאורכבת עבור גרסאות שאינן האחרונה.",
        "apihelp-query+filearchive-example-simple": "הצגת רשימת כל הקבצים המחוקים.",
        "apihelp-query+filerepoinfo-summary": "החזרת מידע מטא על מאגרי תמונות שמוגדרים בוויקי.",
-       "apihelp-query+filerepoinfo-param-prop": "אילו מאפייני מאגר לקבל (יכולים להיות יותר מזה באתרי ויקי אחדים):\n;apiurl:URL ל־API של המאגר – מועיל לקבלת מידע על התמונה מהמארח.\n;name:המפתח של המאגר – משמש למשל בערכים המוחזרים מ־<var>[[mw:Special:MyLanguage/Manual:$wgForeignFileRepos|$wgForeignFileRepos]]</var> ומ־[[Special:ApiHelp/query+imageinfo|imageinfo]].\n;displayname:שם קריא של אתר הוויקי של המאגר.\n;rooturl:URL שורש לנתיבי תמונות.\n;local:האם המאגר הוא מקומי או לא.",
+       "apihelp-query+filerepoinfo-param-prop": "אילו מאפייני מאגר לקבל (המאפיינים הזמינים עשויים להשתנות באתרי ויקי אחרים).",
+       "apihelp-query+filerepoinfo-paramvalue-prop-apiurl": "כתובת URL ל־API של המאגר – שימושי לקבלת מידע על תמונות מהשרת המארח.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-articlepath": "ההגדרה <var dir=\"ltr\">[[mw:Special:MyLanguage/Manual:$wgArticlePath|$wgArticlePath]]</var> של אתר הוויקי של המאגר או ערך השווה לה.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-canUpload": "האם ניתן להעלות קבצים למאגר הזה, למשל באמצעות CORS ובאמצעות אימות משותף.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-displayname": "שם אתר הוויקי של המאגר (בפורמט שמתאים לקריאה על־ידי אדם).",
+       "apihelp-query+filerepoinfo-paramvalue-prop-favicon": "כתובת הצלמית של אתר הוויקי של המאגר, מתוך ההגדרה <var dir=\"ltr\">[[mw:Special:MyLanguage/Manual:$wgFavicon|$wgFavicon]]</var>.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-fetchDescription": "האם דפי תיאור של קבצים מאוחזרים מהמאגר הזה בעת צפייה בדפי תיאור של קבצים מקומיים.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-initialCapital": "האם שמות של קבצים מתחילים באות גדולה.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-local": "האם המאגר הזה הוא המאגר המקומי או לא.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-name": "מפתח המאגר, שנמצא בשימוש למשל בערכים המוחזרים של <var dir=\"ltr\">[[mw:Special:MyLanguage/Manual:$wgForeignFileRepos|$wgForeignFileRepos]]</var> ושל [[Special:ApiHelp/query+imageinfo|imageinfo]].",
+       "apihelp-query+filerepoinfo-paramvalue-prop-rootUrl": "נתיב כתובת הבסיס עבור נתיבים של תמונות.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-scriptDirUrl": "נתיב כתובת הבסיס של התקנת מדיה־ויקי באתר הוויקי של המאגר.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-server": "ההגדרה <var dir=\"ltr\">[[mw:Special:MyLanguage/Manual:$wgServer|$wgServer]]</var> של אתר הוויקי של המאגר או ערך השווה לה.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-thumbUrl": "נתיב כתובת הבסיס עבור נתיבים של תמונות ממוזערות.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-url": "נתיב הכתובת של התחום הציבורי.",
        "apihelp-query+filerepoinfo-example-simple": "קבלת מידע על מאגרי קבצים.",
        "apihelp-query+fileusage-summary": "מציאת כל הדפים שמשתמשים בקבצים הנתונים.",
        "apihelp-query+fileusage-param-prop": "אילו מאפיינים לקבל:",
        "apihelp-query+recentchanges-param-limit": "כמה שינויים להחזיר בסך הכול.",
        "apihelp-query+recentchanges-param-type": "אילו סוגים של שינויים להציג.",
        "apihelp-query+recentchanges-param-toponly": "לרשום רק שינויים שהם הגרסה האחרונה.",
+       "apihelp-query+recentchanges-param-title": "סינון הרשומות לאלו הקשורות לדף.",
        "apihelp-query+recentchanges-param-generaterevisions": "בעת שימוש בתור מחולל, לחולל מזהי גרסה במקום כותרות. עיולי שינויים אחרונים ללא מזהה גרסה משויך (למשל רוב עיולי היומן) לא יחוללו דבר.",
        "apihelp-query+recentchanges-example-simple": "הצגת השינויים האחרונים.",
        "apihelp-query+recentchanges-example-generator": "קבלת מידע על הדף על שינויים אחרונים שלא נבדקו.",
        "apihelp-query+search-param-interwiki": "לכלול תוצאות בינוויקי בחיפוש, אם זמין.",
        "apihelp-query+search-param-backend": "באיזה שרת חיפוש להשתמש אם לא בבררת המחדל.",
        "apihelp-query+search-param-enablerewrites": "הפעלת שכתוב שאילתות פנימי. שרתי חיפוש אחדים יכולים לשכתב את השאילתה לצורה אחרת שנחשבת לכזאת שמספקת תוצאות טובות יותר, למשל באמצעות תיקון שגיאות כתיב.",
+       "apihelp-query+search-param-sort": "קביעת סדר המיון של התוצאות המוחזרות.",
        "apihelp-query+search-example-simple": "חיפוש <kbd>meaning</kbd>.",
        "apihelp-query+search-example-text": "חיפוש טקסטים עבור <kbd>meaning</kbd>.",
        "apihelp-query+search-example-generator": "קבלת מידע על הדף עבור שמוחזרים מחיפוש אחרי <kbd>meaning</kbd>.",
        "apierror-copyuploadbadurl": "העלאה אינה מותרת מה־URL הזה.",
        "apierror-create-titleexists": "כותרות קיימות אינם יכולות מוגנות עם <kbd>create</kbd>.",
        "apierror-csp-report": "בעיבוד דו\"ח CSP אירעה שגיאה: $1",
-       "apierror-databaseerror": "[$1] שגיאת שאילתת מסד נתונים.",
        "apierror-deletedrevs-param-not-1-2": "הפרמטר <var>$1</var> אינו יכול לשמש במצבים 1 או 2.",
        "apierror-deletedrevs-param-not-3": "הפרמטר <var>$1</var> אינו יכול במצב 3.",
        "apierror-emptynewsection": "יצירת פסקאות חדשות ריקות בלתי־אפשרי.",
        "apierror-sectionsnotsupported": "מקטעים אינם נתמכים במודל התוכן $1.",
        "apierror-sectionsnotsupported-what": "מקטעים אינם נתמכים ב־$1.",
        "apierror-show": "פרמטר לא נכון – אי־אפשר לספק ערכים שמבטלים זה את זה.",
-       "apierror-siteinfo-includealldenied": "לא ניתן להציג את המידע של כל השרתים אלא אם <var dir=\"ltr\">$wgShowHostNames</var> מוגדר להיות true.",
+       "apierror-siteinfo-includealldenied": "לא ניתן להציג את המידע של כל השרתים אלא אם <var dir=\"ltr\">$wgShowHostnames</var> מוגדר להיות true.",
        "apierror-sizediffdisabled": "ההבדל בגודל כבוי במצב קמצן.",
        "apierror-spamdetected": "העריכה שלך סורבה כי הכילה חלק ספאם: <code>$1</code>.",
        "apierror-specialpage-cantexecute": "אין לך הרשאה להציג את התוצאות של הדף המיוחד הזה.",
        "apierror-templateexpansion-notwikitext": "הרחבת תבניות נתמכת רק בתוכן קוד ויקי (wikitext). $1 משתמש במודל התוכן $2.",
        "apierror-timeout": "השרת לא השיב בזמן המצופה.",
        "apierror-toofewexpiries": "{{PLURAL:$1|ניתן חותם זמן תפוגה אחד|ניתנו $1 חותמי זמן תפוגה}} כאשר {{PLURAL:$2|היה נחוץ אחד|היו נחוצים $1}}.",
+       "apierror-toomanyvalues": "יותר מדי ערכים סופקו לפרמטר <var>$1</var>. המגבלה היא $2.",
        "apierror-unknownaction": "הפעולה שניתנה, <kbd>$1</kbd>, אינה מוכרת.",
        "apierror-unknownerror-editpage": "שגיאת EditPage בלתי־ידועה: $1.",
        "apierror-unknownerror-nocode": "שגיאה בלתי־ידועה.",
        "apiwarn-checktoken-percentencoding": "נא לבדוק שסימנים כמו \"+\" באסימון מקודדים עם אחוזים בצורה נכונה ב־URL.",
        "apiwarn-compare-nocontentmodel": "לא היה אפשר לקבוע את מודל התוכן, נניח שזה $1.",
        "apiwarn-deprecation-deletedrevs": "<kbd>list=deletedrevs</kbd> הוצהר בתור מיושן. נא להשתמש ב־ <kbd>prop=deletedrevisions</kbd> או ב־<kbd>list=alldeletedrevisions</kbd> במקום זה.",
-       "apiwarn-deprecation-expandtemplates-prop": "מכיוון שלא ניתנו ערכים לפרמטר <var>prop</var>, תסדיר מיושן ישמש לפלט. התסדיר הזה מיושן, ובעתיד יינתן ערך בררת מחדל לפרמטר <var>prop</var>, כך שתמיד ישמש התסדיר החדש.",
        "apiwarn-deprecation-httpsexpected": "משמש HTTP כשהיה צפוי HTTPS.",
        "apiwarn-deprecation-login-botpw": "כניסה לחשבון עיקרי (main-account) דרך <kbd>action=login</kbd> מיושנת ועלולה להפסיק לעבוד ללא אזהרה נוספת. כדי להמשיך להיכנס עם <kbd>action=login</kbd>, ר' [[Special:BotPasswords]]. כדי להמשיך באופן מאובטח באמצעות חשבון עיקרי, ר' <kbd>action=clientlogin</kbd>.",
        "apiwarn-deprecation-login-nobotpw": "כניסה בחשבון ראשי עם <kbd>action=login</kbd> מיושנת ויכולה להפסיק לעבוד ללא אזהרה. כדי להיכנס באופן מאובטח, ר' <kbd>action=clientlogin</kbd>.",
        "apiwarn-redirectsandrevids": "פתרון הפניות לא יכול לשמש יחד עם הפרמטר <var>revids</var>. הפניות ש־<var>revids</var> מצביע אליהן לא נפתרו.",
        "apiwarn-tokennotallowed": "הפעולה \"$1\" אינה מותרת למשתמש הנוכחי.",
        "apiwarn-tokens-origin": "לא ניתן לקבל אסימונים כשמדיניות המקור הזהה אינה חלה.",
-       "apiwarn-toomanyvalues": "יותר מדי ערכים סופקו לפרמטר <var>$1</var>. המגבלה היא $2.",
        "apiwarn-truncatedresult": "התוצאה נחתכה כי אחרת היא הייתה ארוכה מהמגבלה של $1 בתים.",
        "apiwarn-unclearnowtimestamp": "העברת \"$2\" בתור פרמטר חותם־זמן <var>$1</var> הוצהרה בתור מיושנת. אם מסיבה כלשהי אתם צריכים להגדיר במפורש את הזמן הנוכחי ללא חישובו בצד הלקוח, יש להשתמש ב־<kbd>now</kbd>.",
        "apiwarn-unrecognizedvalues": "לפרמטר <var>$1</var> {{PLURAL:$3|ניתן ערך בלתי־ידוע|ניתנו ערכים בלתי־ידועים}}: $2.",
index 8811177..ceb2d42 100644 (file)
        "apihelp-query+revisions+base-paramvalue-prop-timestamp": "Il timestamp della versione.",
        "apihelp-query+revisions+base-paramvalue-prop-user": "Utente che ha effettuato la versione.",
        "apihelp-query+revisions+base-paramvalue-prop-userid": "ID utente dell'autore della versione.",
-       "apihelp-query+revisions+base-paramvalue-prop-content": "Testo della versione.",
+       "apihelp-query+revisions+base-paramvalue-prop-content": "Contenuto di ogni slot di versione.",
        "apihelp-query+revisions+base-paramvalue-prop-tags": "Etichette della versione.",
        "apihelp-query+search-summary": "Eseguire una ricerca di testo completa.",
        "apihelp-query+search-param-what": "Quale tipo di ricerca effettuare.",
        "apihelp-query+search-paramvalue-prop-score": "Ignorato.",
        "apihelp-query+search-paramvalue-prop-hasrelated": "Ignorato.",
        "apihelp-query+search-param-limit": "Quante pagine totali restituire.",
+       "apihelp-query+search-param-sort": "Imposta l'ordinamento dei risultati restituiti.",
        "apihelp-query+siteinfo-param-prop": "Quali informazioni ottenere:",
        "apihelp-query+siteinfo-paramvalue-prop-statistics": "Restituisce le statistiche del sito.",
        "apihelp-query+siteinfo-paramvalue-prop-libraries": "Restituisci librerie installate sul wiki.",
        "apierror-maxchars": "Il parametro <var>$1</var> non può essere più lungo di $2 {{PLURAL:$2|carattere|caratteri}}",
        "apierror-nosuchuserid": "Non c'è alcun utente con ID $1.",
        "apierror-timeout": "Il server non ha risposto entro il tempo previsto.",
+       "apierror-toomanyvalues": "Troppi valori forniti per il parametro <var>$1</ var>. Il limite è $2.",
        "api-credits-header": "Crediti"
 }
index 84e1046..399fc1f 100644 (file)
        "apihelp-compare-param-fromtitle": "比較する1つ目のページ名。",
        "apihelp-compare-param-fromid": "比較する1つ目のページID。",
        "apihelp-compare-param-fromrev": "比較する1つ目の版。",
+       "apihelp-compare-param-fromtext": "<var>fromtitle</var>, <var>fromid</var> or <var>fromrev</var> で指定された版の内容の代わりに、このテキストを使用します。",
+       "apihelp-compare-param-fromsection": "'from' の内容のうち指定された節のみを使用します。",
        "apihelp-compare-param-frompst": "<var>fromtext</var>に保存前変換を行います。",
        "apihelp-compare-param-fromcontentmodel": "<var>fromtext</var>のコンテンツモデル。指定されていない場合は、他のパラメータに基づいて推測されます。",
        "apihelp-compare-param-totitle": "比較する2つ目のページ名。",
        "apihelp-compare-param-toid": "比較する2つ目のページID。",
        "apihelp-compare-param-torev": "比較する2つ目の版。",
+       "apihelp-compare-param-tosection": "'to' の内容のうち指定された節のみを使用します。",
        "apihelp-compare-param-topst": "<var>totext</var>に保存前変換を行います。",
+       "apihelp-compare-param-tocontentmodel": "<var>totext</var> のコンテンツモデル。指定されていない場合は、他のパラメータに基づいて推測されます。",
        "apihelp-compare-param-prop": "どの情報を取得するか:",
        "apihelp-compare-paramvalue-prop-diff": "差分HTML。",
        "apihelp-compare-paramvalue-prop-diffsize": "差分HTMLのサイズ (バイト数)。",
        "apihelp-undelete-param-timestamps": "復元する版のタイムスタンプ。<var>$1timestamps</var> と <var>$1fileids</var> の両方が空の場合、すべての版が復元されます。",
        "apihelp-undelete-example-page": "<kbd>Main Page</kbd> を復元する。",
        "apihelp-undelete-example-revisions": "<kbd>Main Page</kbd> の2つの版を復元する。",
+       "apihelp-upload-param-filename": "対象のファイル名。",
+       "apihelp-upload-param-comment": "アップロードのコメント。新規ファイルのアップロードで <var>$1text</var> が指定されていない場合、初期ページテキストとしても使用されます。",
+       "apihelp-upload-param-text": "新しいファイルの初期ページテキスト。",
        "apihelp-upload-param-watch": "このページをウォッチする。",
        "apihelp-upload-param-ignorewarnings": "あらゆる警告を無視する。",
        "apihelp-upload-param-url": "ファイル取得元のURL.",
index d5ac9e0..56a6507 100644 (file)
        "apihelp-edit-param-watch": "문서를 현재 사용자의 주시문서 목록에 추가합니다.",
        "apihelp-edit-param-unwatch": "문서를 현재 사용자의 주시문서 목록에서 제거합니다.",
        "apihelp-edit-param-watchlist": "현재 사용자의 주시목록에서 문서를 무조건적으로 추가하거나 제거하거나, 환경 설정을 사용하거나 주시를 변경하지 않습니다.",
-       "apihelp-edit-param-redirect": "자동으로 넘겨주기 처리하기.",
+       "apihelp-edit-param-prependtext": "이 텍스를 문서의 처음에 추가합니다. $1text를 무효로 합니다.",
+       "apihelp-edit-param-appendtext": "이 텍스트를 문서의 끝에 추가합니다. $1text를 무효로 합니다.\n\n새 문단을 추가하려면 이 변수 대신 $1section=new를 사용하십시오.",
+       "apihelp-edit-param-undo": "이 판의 편집을 취소합니다. $1text, $1prependtext, $1appendtext를 무효로 합니다.",
+       "apihelp-edit-param-undoafter": "$1undo에서부터 이 판까지의 모든 판의 편집을 취소합니다. 설정하지 않으면 하나의 판만 편집을 취소합니다.",
+       "apihelp-edit-param-redirect": "자동으로 넘겨주기를 처리합니다.",
+       "apihelp-edit-param-contentformat": "입력 텍스트에 사용할 내용 직렬화 포맷입니다.",
        "apihelp-edit-param-contentmodel": "새 콘텐츠의 콘텐츠 모델.",
+       "apihelp-edit-param-token": "토큰은 무조건 마지막 변수로 보내거나 적어도 $1text 변수 뒤에 보내는 것이 좋습니다.",
        "apihelp-edit-example-edit": "문서 편집",
+       "apihelp-edit-example-prepend": "문서의 맨 앞에 <kbd>_&#95;NOTOC_&#95;</kbd>를 추가합니다.",
        "apihelp-edit-example-undo": "자동 편집요약으로 13579판에서 13585판까지 되돌리기.",
        "apihelp-emailuser-summary": "사용자에게 이메일을 보냅니다.",
        "apihelp-emailuser-param-target": "이메일을 받을 사용자.",
        "apihelp-parse-param-sectionpreview": "문단 미리 보기 모드에서 구문 분석을 합니다. (미리 보기 모드도 활성화함)",
        "apihelp-parse-param-disabletoc": "출력에서 목차를 제외합니다.",
        "apihelp-parse-param-useskin": "선택한 스킨을 파서 출력에 적용합니다. 다음의 속성에 영향을 줄 수 있습니다: <kbd>langlinks</kbd>, <kbd>headitems</kbd>, <kbd>modules</kbd>, <kbd>jsconfigvars</kbd>, <kbd>indicators</kbd>.",
+       "apihelp-parse-param-contentformat": "입력 텍스트에 사용할 내용 직렬화 포맷입니다. $1text와 함께 사용할 때에만 유효합니다.",
        "apihelp-parse-example-page": "페이지의 구문을 분석합니다.",
        "apihelp-parse-example-text": "위키텍스트의 구문을 분석합니다.",
        "apihelp-parse-example-summary": "요약을 구문 분석합니다.",
        "apihelp-query+filearchive-paramvalue-prop-metadata": "그림의 버전에 대한 Exif 메타데이터를 나열합니다.",
        "apihelp-query+filearchive-example-simple": "삭제된 모든 파일의 목록을 표시합니다.",
        "apihelp-query+filerepoinfo-summary": "위키에 구성된 그림 저장소에 대한 메타 정보를 반환합니다.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-apiurl": "저장소 API의 URL - 호스트로부터 이미지 정보를 가져오는데 유용합니다.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-canUpload": "파일을 이 저장소에 올릴 수 있는지의 여부. (예: CORS를 통해, 공유 인증을 통해)",
+       "apihelp-query+filerepoinfo-paramvalue-prop-displayname": "사람이 식별할 수 있는 저장소 위키의 이름입니다.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-local": "해당 저장소가 로컬인지 아닌지의 여부입니다.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-rootUrl": "이미지 경로의 루트 URL 경로입니다.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-thumbUrl": "섬네일 경로의 루트 URL 경로입니다.",
        "apihelp-query+filerepoinfo-example-simple": "파일 저장소의 정보를 가져옵니다.",
        "apihelp-query+fileusage-summary": "제시된 파일을 사용하는 모든 문서를 찾습니다.",
        "apihelp-query+fileusage-param-prop": "얻고자 하는 속성:",
        "apihelp-query+search-paramvalue-prop-timestamp": "문서가 마지막으로 편집된 시기의 타임스탬프를 추가합니다.",
        "apihelp-query+search-paramvalue-prop-score": "무시됨.",
        "apihelp-query+search-paramvalue-prop-hasrelated": "무시됨.",
+       "apihelp-query+search-param-sort": "반환된 결과의 정렬 순서를 설정합니다.",
        "apihelp-query+search-example-simple": "<kbd>meaning</kbd>을 검색합니다.",
        "apihelp-query+search-example-text": "<kbd>meaning</kbd>의 텍스트를 검색합니다.",
        "apihelp-query+siteinfo-summary": "사이트의 전반적인 정보를 반환합니다.",
        "apihelp-stashedit-param-sectiontitle": "새 문단을 위한 제목.",
        "apihelp-stashedit-param-text": "문서 내용.",
        "apihelp-stashedit-param-contentmodel": "새 콘텐츠의 콘텐츠 모델.",
+       "apihelp-stashedit-param-contentformat": "입력 텍스트에 사용할 내용 직렬화 포맷입니다.",
        "apihelp-tag-summary": "개별 판이나 기록 항목에서 변경 태그를 추가하거나 제거합니다.",
        "apihelp-tag-param-rcid": "태그를 변경하거나 추가할 하나 이상의 최근 바뀜 ID입니다.",
        "apihelp-tag-param-revid": "태그를 추가하거나 제거할 하나 이상의 판 ID입니다.",
        "api-help-datatypes-header": "데이터 유형",
        "api-help-datatypes": "API 요청 내 몇몇 매개변수형에 대해 더 자세히 설명해보겠습니다:\n;boolean\n:Boolean 매개변수들은 HTML 체크박스처럼 동작합니다: 만약 매개변수가 지정되었다면, 값에 상관없이 참의 값으로 여겨집니다. 거짓값은 매개변수 전체를 생략하세요.\n;timestamp\n:타임스탬프들은 여러 형식으로 표현될 수 있으나 ISO 8601 날짜와 시간이 추천됩니다. 모든 시간은 UTC이어야 하며, 포함된 시간대는 모두 무시됩니다.\n:* ISO 8601 날짜와 시간, <kbd><var>2001</var>-<var>01</var>-<var>15</var>T<var>14</var>:<var>56</var>:<var>00</var>Z</kbd> (구두점과 <kbd>Z</kbd>는 선택입니다.)\n:* ISO 8601 날짜와 시간과 (무시되는) 소수 초, <kbd><var>2001</var>-<var>01</var>-<var>15</var>T<var>14</var>:<var>56</var>:<var>00</var>.<var>00001</var>Z</kbd> (대시, 콜론과 <kbd>Z</kbd>는 선택입니다.)\n:* 미디어위키 형식, <kbd><var>2001</var><var>01</var><var>15</var><var>14</var><var>56</var><var>00</var></kbd>\n:* 일반적인 수 형식 <kbd><var>2001</var>-<var>01</var>-<var>15</var> <var>14</var>:<var>56</var>:<var>00</var></kbd> (<kbd>GMT</kbd>, <kbd>+<var>##</var></kbd>, 또는 <kbd>-<var>##</var></kbd>와 같은 선택적 시간대는 무시됩니다)\n:*RFC 2822 형식 (시간대는 생략될 수 있음), <kbd><var>Mon</var>, <var>15</var> <var>Jan</var> <var>2001</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:* RFC 850 형식 (시간대는 생략될 수 있음), <kbd><var>Monday</var>, <var>15</var>-<var>Jan</var>-<var>2001</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:* C ctime 형식, <kbd><var>Mon</var> <var>Jan</var> <var>15</var> <var>14</var>:<var>56</var>:<var>00</var> <var>2001</var></kbd>\n:* 1부터 13자리까지의 숫자로 표현된 1970-01-01T00:00:00Z부터 흐른 시간(초) (<kbd>0</kbd>을 제외)\n:* 문자열 <kbd>now</kbd>",
        "api-help-templatedparams-header": "틀 변수",
+       "api-help-templatedparams": "틀 변수는 다른 일부 변수의 개별 값에 대한 API 모듈에 값이 필요한 경우를 지원합니다. 이를테면 과일을 요청하는 API 모듈이 있다면 <var>fruits</var> 변수를 사용하여 요청할 과일을 지정할 수 있으며 틀 변수 <var>{fruit}-quantity</var>를 사용하여 요청할 과일의 수를 지정할 수 있습니다. 사과 1개, 바나나 5개, 딸기 20개를 원하는 API 클라이언트는 <kbd>fruits=apples|bananas|strawberries&apples-quantity=1&bananas-quantity=5&strawberries-quantity=20</kbd>와 같은 요청을 수행할 수 있습니다.",
        "api-help-param-type-limit": "유형: 정수 또는 <kbd>max</kbd>",
        "api-help-param-type-integer": "유형: {{PLURAL:$1|1=정수|2=정수 목록}}",
        "api-help-param-type-boolean": "유형: 불리언 ([[Special:ApiHelp/main#main/datatypes|자세한 정보]])",
        "api-help-param-type-timestamp": "유형: {{PLURAL:$1|1=타임스탬프|2=타임스탬프 목록}} ([[Special:ApiHelp/main#main/datatypes|허용되는 포맷]])",
        "api-help-param-type-user": "유형: {{PLURAL:$1|1=사용자 이름|2=사용자 이름 목록}}",
-       "api-help-param-list": "{{PLURAL:$1|1=다음 값 중 하나|2=값 (<kbd>{{!}}</kbd>로 구분)}}: $2 또는 [[Special:ApiHelp/main#main/datatypes|alternative]]: $2",
+       "api-help-param-list": "{{PLURAL:$1|1=다음 값 중 하나|2=값 (<kbd>{{!}}</kbd>로 구분)}}: $2 또는 [[Special:ApiHelp/main#main/datatypes|다른 문자열]]: $2",
        "api-help-param-list-can-be-empty": "{{PLURAL:$1|0=비어 있어야 함|비어 있을 수 있거나 $2}}",
        "api-help-param-limit": "$1 초과는 허용되지 않습니다.",
        "api-help-param-limit2": "$1 초과는 허용되지 않습니다. (봇의 경우 $2)",
        "apierror-articleexists": "작성하려는 문서가 이미 만들어져 있습니다.",
        "apierror-assertbotfailed": "사용자의 <code>bot</code> 권한 보유 표명이 실패했습니다.",
        "apierror-assertnameduserfailed": "사용자의 \"$1\" 지정 표명이 실패했습니다.",
-       "apierror-assertuserfailed": "사용자의 로그인 표명이 실패했습니다.",
+       "apierror-assertuserfailed": "사용자의 로그인 실패 표명이 발생했습니다.",
        "apierror-autoblocked": "사용자의 IP 주소는 차단된 사용자에 의해 사용되었으므로 자동으로 차단된 상태입니다.",
        "apierror-badgenerator-unknown": "알 수 없는 <kbd>generator=$1</kbd>.",
        "apierror-badip": "IP 변수가 유효하지 않습니다.",
        "apierror-cantimport-upload": "업로드된 페이지를 가져올 권한이 없습니다.",
        "apierror-cantimport": "페이지를 가져올 권한이 없습니다.",
        "apierror-cantsend": "로그인하지 않았거나 인증된 이메일 주소가 없거나 다른 사용자로 이메일을 보낼 권한이 없기 때문에 이메일을 보낼 수 없습니다.",
-       "apierror-databaseerror": "[$1] 데이터베이스 쿼리 오류.",
        "apierror-emptynewsection": "비어있는 새 문단을 만들 수 없습니다.",
        "apierror-emptypage": "새 문서로 빈 문서를 만들 수 없습니다.",
        "apierror-exceptioncaught": "[$1] 예외가 발생했습니다: $2",
        "apierror-stashwrongowner": "잘못된 소유자: $1",
        "apierror-systemblocked": "당신은 미디어위키에 의해서 자동으로 차단되었습니다.",
        "apierror-timeout": "서버가 예측된 시간 내에 응답하지 않았습니다.",
+       "apierror-toomanyvalues": "<var>$1</var> 변수에 너무 많은 값이 지정되었습니다. 제한은 $2입니다.",
        "apierror-unknownerror-editpage": "알 수 없는 EditPage 오류: $1.",
        "apierror-unknownerror-nocode": "알 수 없는 오류.",
        "apierror-unknownerror": "알 수 없는 오류: \"$1\"",
index b0231df..4ba4062 100644 (file)
        "apihelp-query+filearchive-param-sha1base36": "Däm Beld singe <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"secure hash algorithm\">SHA-1</i>-Pröhvsomm em 36-jer Zahlesüßtehm. Weed em Mehdiajwikki jebruch.",
        "apihelp-query+filearchive-param-prop": "Wat för en Aanjahbe zom Beld holle:",
        "apihelp-query+filearchive-paramvalue-prop-sha1": "Deiht dä <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"secure hash algorithm\">SHA-1 (base 16)</i> vun dä Väsjohn vn däm Beld derbei.",
-       "apihelp-query+filearchive-paramvalue-prop-timestamp": "Adds timestamp for the uploaded version.",
        "apihelp-query+filearchive-paramvalue-prop-user": "Deiht dä Metmaacher derbei, dä di Väsjohn huhjelahde hät.",
        "apihelp-query+filearchive-paramvalue-prop-size": "Deiht de Aanzahl <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\">Bytes</i> vun dä Dattei derbei, un, wann bikannt, de Hühde, de Wiggde, un de Aanzahl Sigge.",
        "apihelp-query+filearchive-paramvalue-prop-dimensions": "Et sällve, wi <code lang=\"en\" xml:lang=\"en\" dir=\"ltr\">size</code>.",
        "apihelp-query+links-example-simple": "Holl de Lengks vun dä Sigg <kbd>Main Page</kbd>",
        "apihelp-query+linkshere-summary": "Fengk alle Sigge, di op de aanjejovve Sigge lengke.",
        "apihelp-query+linkshere-param-prop": "Wat för en Eijeschaffte holle:",
-       "apihelp-query+linkshere-paramvalue-prop-pageid": "Page ID of each page.",
-       "apihelp-query+linkshere-paramvalue-prop-title": "Title of each page.",
-       "apihelp-query+linkshere-paramvalue-prop-redirect": "Flag if the page is a redirect.",
        "apihelp-query+linkshere-param-namespace": "Donn blohß Sigge en heh dä Appachtemangs metnämme.",
        "apihelp-query+linkshere-param-limit": "Wi vill holle?",
        "apihelp-query+linkshere-example-simple": "Holl en Leß vun Sigge, di op de Sigg „<code lang=\"en\" xml:lang=\"en\" dir=\"ltr\">[[Main Page]]</code>“ lengke donn.",
index f470a72..09b6671 100644 (file)
        "apierror-cantimport-upload": "Neturite teisės importuoti įkeltų puslapių.",
        "apierror-cantimport": "Neturite teisės importuoti puslapių.",
        "apierror-copyuploadbadurl": "Įkėlimas neleidžiamas iš šio URL.",
-       "apierror-databaseerror": "[$1] Duomenų bazės užklausos klaida.",
        "apierror-emptynewsection": "Neįmanoma kurti naujų tuščių skyrių.",
        "apierror-filedoesnotexist": "Failas neegzistuoja.",
        "apierror-filetypecannotberotated": "Failo tipas negali būti pasuktas.",
index 3cec5d4..47ab23f 100644 (file)
        "apihelp-options-summary": "Смени ги нагодувањата на тековниот корисник.",
        "apihelp-options-extended-description": "Можат да се зададат само можностите заведени во јадрото или во едно од воспоставените додатоци, или пак можности со клуч кој ја има претставката <code>userjs-</code> (предвиден за употреба од кориснички скрипти).",
        "apihelp-options-param-reset": "Ги враќа поставките по основно.",
-       "apihelp-options-param-resetkinds": "Ð\9fисок на типови можности за повраток кога е зададена можноста <var>$1reset</var>.",
+       "apihelp-options-param-resetkinds": "Сисок на типови можности за повраток кога е зададена можноста <var>$1reset</var>.",
        "apihelp-options-param-change": "Список на промени во форматот name=value (на пр. skin=vector). Вредностите не треба да содржат исправени црти. Ако не зададете вредност (дури ни знак за равенство), на пр., можност|другаможност|..., ќе биде зададена вредноста на можноста по основно.",
        "apihelp-options-param-optionname": "Назив на можноста што треба да ѝ се зададе на вредноста дадена од <var>$1optionvalue</var>.",
        "apihelp-options-param-optionvalue": "Вредноста на можноста укажана од <var>$1optionname</var>. Може да содржи исправени црти.",
index a1c9238..be6e798 100644 (file)
        "apierror-copyuploadbadurl": "Opplasting tillates ikke fra denne URL-en.",
        "apierror-create-titleexists": "Eksisterende titler kan ikke beskyttes med <kbd>create</kbd>.",
        "apierror-csp-report": "Feil under prosessering av CSP-rapport: $1.",
-       "apierror-databaseerror": "[$1] Databasespørringsfeil.",
        "apierror-deletedrevs-param-not-1-2": "Parameteren <var>$1</var> kan ikke brukes i modus 1 eller 2.",
        "apierror-deletedrevs-param-not-3": "Parameteren <var>$1</var> kan ikke brukes i modus 3.",
        "apierror-emptynewsection": "Oppretting av tomme nye seksjoner er ikke mulig.",
        "apierror-sectionreplacefailed": "Kunne ikke flette oppdatert seksjon.",
        "apierror-sectionsnotsupported": "Seksjoner støttes ikke for innholdsmodellen $1.",
        "apierror-sectionsnotsupported-what": "Seksjoner støttes ikke av $1.",
-       "apierror-siteinfo-includealldenied": "Kan ikke vise alle tjenernes info med mindre </var>$wgShowHostNames</var> er sann.",
+       "apierror-siteinfo-includealldenied": "Kan ikke vise alle tjenernes info med mindre </var>$wgShowHostnames</var> er sann.",
        "apierror-sizediffdisabled": "Størrelsesforskjell er slått av i Miser-modus.",
        "apierror-timeout": "Tjeneren svarte ikke innenfor forventet tid.",
        "apiwarn-validationfailed": "Bekreftelsesfeil <kbd>$1</kbd>: $2"
index d0148fe..d7735f6 100644 (file)
@@ -31,6 +31,7 @@
        "apihelp-main-param-servedby": "De hostnaam van de server die de aanvraag heeft afgehandeld aan de resultaten toevoegen.",
        "apihelp-main-param-curtimestamp": "Huidige tijd aan de resultaten toevoegen.",
        "apihelp-main-param-responselanginfo": "De voor <var>uselang</var> en <var>errorlang</var> gebruikte talen aan de resultaten toevoegen.",
+       "apihelp-main-param-uselang": "Taal om te gebruiken voor berichtvertalingen. <kbd>[[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo]]</kbd> gecombineerd met <kbd>siprop=languages</kbd> toont een lijst met taalcodes. De waarde <kbd>user</kbd> gebruikt de taal die door de huidige gebruiker als voorkeur is ingesteld. De waarde <kbd>content</kbd> gebruikt de taal die de inhoud op de wiki heeft.",
        "apihelp-main-param-errorlang": "De voor waarschuwingen en fouten te gebruiken taal. <kbd>[[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo]]</kbd> met <kbd>siprop=languages</kbd> geeft een lijst van taalcodes, of stel <kbd>content</kbd> in om de taal van de inhoud van deze wiki te gebruiken, of stel <kbd>uselang</kbd> in om dezelfde waarde als de parameter <var>uselang</var> te gebruiken.",
        "apihelp-main-param-errorsuselocal": "Indien ingesteld maken foutmeldingen gebruik van lokaal-aangepaste berichten in de {{ns:MediaWiki}}-naamruimte.",
        "apihelp-block-summary": "Gebruiker blokkeren.",
        "apihelp-move-param-to": "Nieuwe paginanaam.",
        "apihelp-move-param-reason": "Reden voor de naamswijziging.",
        "apihelp-move-param-movetalk": "Hernoem de overlegpagina, indien deze bestaat.",
+       "apihelp-move-param-movesubpages": "Hernoem ook deelpagina's, indien van toepassing.",
        "apihelp-move-param-noredirect": "Geen doorverwijzing achterlaten.",
        "apihelp-move-param-watch": "Voeg de pagina en de doorverwijzing toe aan de volglijst van de huidige gebruiker.",
        "apihelp-move-param-unwatch": "Verwijder de pagina en de doorverwijzing van de volglijst van de huidige gebruiker.",
        "apihelp-opensearch-summary": "In de wiki zoeken met behulp het OpenSearchprotocol.",
        "apihelp-opensearch-param-search": "Zoektekst.",
        "apihelp-opensearch-param-limit": "Het maximale aantal weer te geven resultaten.",
-       "apihelp-opensearch-param-namespace": "Te doorzoeken naamruimten.",
+       "apihelp-opensearch-param-namespace": "Te doorzoeken naamruimten. Wordt genegeerd indien <var>$1search</var> met een geldige naamruimte voorvoegsel begint.",
        "apihelp-opensearch-param-suggest": "Niets doen als <var>[[mw:Special:MyLanguage/Manual:$wgEnableOpenSearchSuggest|$wgEnableOpenSearchSuggest]]</var> onwaar is.",
        "apihelp-opensearch-param-redirects": "Hoe om te gaan met doorverwijzingen:\n;return:Retourneer de doorverwijzing.\n;resolve:Retourneer de doelpagina. Retourneert mogelijk minder dan $1limit resultaten.\nOm historische redenen is \"return\" de standaardinstelling voor <code>$1format=json</code>, en \"resolve\" voor andere formaten.",
        "apihelp-opensearch-param-format": "Het uitvoerformaat.",
        "apihelp-protect-example-protect": "Een pagina beveiligen.",
        "apihelp-purge-param-forcelinkupdate": "Werk de koppelingstabellen bij.",
        "apihelp-purge-param-forcerecursivelinkupdate": "Werk de koppelingentabel bij, en werk de koppelingstabellen bij voor alle pagina's die deze pagina als sjabloon gebruiken.",
+       "apihelp-query+allcategories-summary": "Alle categorieën doorlopen.",
        "apihelp-query+allcategories-param-dir": "Richting om in te sorteren.",
        "apihelp-query+allcategories-param-limit": "Hoeveel categorieën te tonen.",
        "apihelp-query+allcategories-paramvalue-prop-size": "Voegt het aantal pagina's in de categorie toe.",
        "apihelp-query+alldeletedrevisions-param-tag": "Alleen versies met dit label weergeven.",
        "apihelp-query+alldeletedrevisions-param-excludeuser": "Geen revisies door deze gebruiker weergeven.",
        "apihelp-query+alldeletedrevisions-param-namespace": "Alleen pagina's in deze naamruimte weergeven.",
+       "apihelp-query+alldeletedrevisions-example-user": "Toon de laatste 50 verwijderde bijdragen van gebruiker <kbd>Example</kbd>.",
+       "apihelp-query+alldeletedrevisions-example-ns-main": "Toon de eerse 50 verwijderde versies in de hoofdnaamruimte.",
        "apihelp-query+allfileusages-paramvalue-prop-title": "Voegt de titel van het bestand toe.",
        "apihelp-query+allfileusages-param-limit": "Hoeveel items er in totaal moeten worden getoond.",
        "apihelp-query+allimages-example-recent": "Toon een lijst van recentelijk geüploade bestanden, vergelijkbaar met [[Special:NewFiles]].",
        "apihelp-query+alllinks-param-namespace": "De door te lopen naamruimte.",
        "apihelp-query+alllinks-param-limit": "Hoeveel items er in totaal moeten worden getoond.",
+       "apihelp-query+allmessages-param-prop": "Welke eigenschappen op te vragen.",
        "apihelp-query+allmessages-param-enableparser": "Stel in om de parser in te schakelen, zorgt voor het voorverwerken van de wikitekst van een bericht (vervangen van magische woorden, afhandelen van sjablonen, enz.).",
        "apihelp-query+allmessages-param-lang": "Toon berichten in deze taal.",
        "apihelp-query+allmessages-param-from": "Toon berichten vanaf dit bericht.",
        "apihelp-query+allmessages-param-to": "Toon berichten tot aan dit bericht.",
+       "apihelp-query+allmessages-param-prefix": "Toon berichten met dit voorvoegsel.",
+       "apihelp-query+allpages-param-limit": "Het totaal aantal pagina's dat getoont moeten worden.",
        "apihelp-query+allredirects-summary": "Toon alle doorverwijzingen naar een naamruimte.",
+       "apihelp-query+allredirects-paramvalue-prop-title": "Voegt de titel van de doorverwijzing toe.",
+       "apihelp-query+allredirects-param-limit": "Hoeveel items er in totaal moeten worden getoond.",
+       "apihelp-query+allrevisions-summary": "Toon alle versies.",
+       "apihelp-query+allrevisions-param-namespace": "Alleen pagina's in deze naamruimte weergeven.",
        "apihelp-query+allrevisions-example-user": "Toon de laatste 50 bijdragen van gebruiker <kbd>Example</kbd>.",
        "apihelp-query+mystashedfiles-paramvalue-prop-type": "Vraag het MIME- en mediatype van het bestand op.",
        "apihelp-query+mystashedfiles-param-limit": "Hoeveel bestanden te tonen.",
+       "apihelp-query+alltransclusions-param-namespace": "De door te lopen naamruimte.",
+       "apihelp-query+alltransclusions-param-limit": "Hoeveel items er in totaal moeten worden getoond.",
+       "apihelp-query+allusers-param-dir": "Richting om in te sorteren.",
        "apihelp-query+allusers-param-excludegroup": "Sluit gebruikers in de gegeven groepen uit.",
        "apihelp-query+allusers-paramvalue-prop-blockinfo": "Voegt informatie over een actuele blokkade van de gebruiker toe.",
        "apihelp-query+allusers-paramvalue-prop-groups": "Toont de groepen waar de gebruiker in zit. Dit gebruikt meer serverbronnen en retourneert mogelijk minder resultaten dan de opgegeven limiet.",
        "apihelp-query+allusers-paramvalue-prop-rights": "Toont de rechten die de gebruiker heeft.",
        "apihelp-query+allusers-paramvalue-prop-editcount": "Voegt het aantal bewerkingen van de gebruiker toe.",
        "apihelp-query+allusers-paramvalue-prop-registration": "Voegt de registratiedatum van de gebruiker toe, indien beschikbaar (kan leeg zijn).",
+       "apihelp-query+allusers-param-limit": "Het totaal aantal aan gebruikersnamen dat getoont moet worden.",
        "apihelp-query+allusers-param-witheditsonly": "Toon alleen gebruikers die bewerkingen hebben gemaakt.",
        "apihelp-query+allusers-param-activeusers": "Toon alleen gebruikers die actief zijn geweest in de laatste {{PLURAL:$1|dag|$1 dagen}}.",
        "apihelp-query+allusers-example-Y": "Toon gebruikers vanaf <kbd>Y</kbd>.",
        "apihelp-query+categories-paramvalue-prop-hidden": "Markeert categorieën die verborgen zijn met <code>_&#95;HIDDENCAT_&#95;</code>",
        "apihelp-query+categories-param-show": "Welke soort categorieën te tonen.",
        "apihelp-query+categories-param-limit": "Hoeveel categorieën te tonen.",
+       "apihelp-query+categories-example-simple": "Toon de lijst waarin de pagina <kbd>Albert Einstein</kbd> zich bevind.",
+       "apihelp-query+categorymembers-summary": "Toon alle pagina's in de opgegeven categorie.",
        "apihelp-query+categorymembers-paramvalue-prop-ids": "Voegt de pagina-ID toe.",
        "apihelp-query+categorymembers-paramvalue-prop-title": "Voegt de titel en de naamruimte-ID van de pagina toe.",
+       "apihelp-query+categorymembers-param-limit": "Het maximale aantal weer te geven pagina's.",
        "apihelp-query+categorymembers-param-dir": "Richting om in te sorteren.",
+       "apihelp-query+categorymembers-example-simple": "Toon de eerste 10 pagina's in <kbd>Category:Physics</kbd>.",
        "apihelp-query+deletedrevisions-param-tag": "Alleen revisies met dit label weergeven.",
+       "apihelp-query+deletedrevs-paraminfo-modes": "{{PLURAL:$1|Modus|Modi}}: $2",
        "apihelp-query+deletedrevs-param-tag": "Alleen revisies met dit label weergeven.",
        "apihelp-query+embeddedin-param-namespace": "De door te lopen naamruimte.",
+       "apihelp-query+filearchive-example-simple": "Toon een lijst met alle verwijderde bestanden.",
        "apihelp-query+fileusage-paramvalue-prop-pageid": "Pagina-ID van elke pagina.",
        "apihelp-query+fileusage-paramvalue-prop-title": "Titel van elke pagina.",
+       "apihelp-query+imageinfo-paramvalue-prop-mediatype": "Voegt het mediatype van het bestand toe.",
        "apihelp-query+imageusage-param-namespace": "De door te lopen naamruimte.",
        "apihelp-query+imageusage-example-simple": "Toon pagina's die [[:File:Albert Einstein Head.jpg]] gebruiken.",
        "apihelp-query+imageusage-example-generator": "Toon informatie over pagina's die [[:File:Albert Einstein Head.jpg]] gebruiken.",
        "apihelp-query+iwbacklinks-param-prefix": "Voorvoegsel voor de interwiki.",
+       "apihelp-query+iwlinks-paramvalue-prop-url": "Voegt de volledige URL toe.",
+       "apihelp-query+langbacklinks-example-simple": "Toon de pagina's die verwijzen naar [[:fr:Test]].",
+       "apihelp-query+langlinks-paramvalue-prop-url": "Voegt de volledige URL toe.",
+       "apihelp-query+linkshere-paramvalue-prop-pageid": "Pagina-ID van elke pagina.",
+       "apihelp-query+linkshere-paramvalue-prop-title": "Titel van elke pagina.",
+       "apihelp-query+linkshere-param-namespace": "Toon alleen pagina's in deze naamruimten.",
+       "apihelp-query+linkshere-example-simple": "Toon een lijst van pagina's die naar [[Main Page]] verwijzen.",
        "apihelp-query+logevents-param-type": "Logboekregels alleen voor dit type filteren.",
        "apihelp-query+logevents-param-tag": "Alleen logboekregels met dit label weergeven.",
        "apihelp-query+logevents-example-simple": "Recente logboekregels weergeven.",
+       "apihelp-query+pageswithprop-paramvalue-prop-ids": "Voegt de pagina-ID toe.",
+       "apihelp-query+prefixsearch-param-offset": "Aantal resultaten dat overgeslagen moeten worden.",
        "apihelp-query+protectedtitles-paramvalue-prop-level": "Voegt het beveiligingsniveau toe.",
        "apihelp-query+protectedtitles-example-simple": "Toon beveiligde titels.",
        "apihelp-query+querypage-param-limit": "Aantal te tonen resultaten.",
        "apihelp-query+querypage-example-ancientpages": "Toon resultaten van [[Special:Ancientpages]].",
        "apihelp-query+random-param-namespace": "Toon alleen pagina's in deze naamruimten.",
        "apihelp-query+random-param-limit": "Beperk hoeveel willekeurige pagina's worden getoond.",
+       "apihelp-query+random-param-redirect": "Gebruik in plaats daarvan <kbd>$1filterredir=redirects</kbd>.",
        "apihelp-query+random-example-simple": "Toon twee willekeurige pagina's uit de hoofdnaamruimte.",
        "apihelp-query+random-example-generator": "Toon pagina-informatie over twee willekeurige pagina's uit de hoofdnaamruimte.",
        "apihelp-query+recentchanges-param-user": "Toon alleen wijzigingen door deze gebruiker.",
        "apihelp-query+revisions+base-paramvalue-prop-tags": "Labels voor de versie.",
        "apihelp-query+revisions+base-param-difftotextpst": "Gebruik in plaats hiervan [[Special:ApiHelp/compare|action=compare]]. Een \"pre-save\"-transformatie uitvoeren op de tekst alvorens de verschillen te bepalen. Alleen geldig indien gebruikt met <var>$1difftotext</var>.",
        "apihelp-query+search-summary": "Voer een zoekopdracht in de volledige tekst uit.",
+       "apihelp-query+search-paramvalue-prop-score": "Genegeerd.",
+       "apihelp-query+search-paramvalue-prop-hasrelated": "Genegeerd.",
        "apihelp-query+search-param-limit": "Hoeveel pagina's te tonen.",
        "apihelp-query+search-example-simple": "Zoeken naar <kbd>meaning</kbd>.",
        "apihelp-query+siteinfo-paramvalue-prop-namespacealiases": "Lijst van geregistreerde naamruimte-aliassen.",
        "apihelp-query+usercontribs-example-ipprefix": "Bijdragen van alle IP-adressen met het voorvoegsel <kbd>192.0.2.</kbd> weergeven.",
        "apihelp-query+userinfo-summary": "Informatie over de huidige gebruiker opvragen.",
        "apihelp-query+userinfo-paramvalue-prop-realname": "Voegt de echte naam van de gebruiker toe.",
+       "apihelp-query+watchlist-paramvalue-prop-title": "Voegt de titel van de pagina toe.",
        "apihelp-query+watchlist-paramvalue-prop-loginfo": "Voegt logboekgegevens toe waar van toepassing.",
        "apihelp-query+watchlist-param-type": "Welke typen wijzigingen weer te geven:",
        "apihelp-query+watchlist-paramvalue-type-edit": "Gewone paginabewerkingen.",
        "apihelp-query+watchlist-paramvalue-type-new": "Nieuwe pagina's.",
        "apihelp-query+watchlist-paramvalue-type-log": "Logboekregels.",
        "apihelp-query+watchlist-paramvalue-type-categorize": "Wijzigingen in categorielidmaatschap.",
+       "apihelp-setpagelanguage-summary": "Wijzig de taal van een pagina.",
+       "apihelp-stashedit-param-sectiontitle": "De titel van een nieuw kopje.",
        "apihelp-stashedit-param-text": "Pagina-inhoud.",
+       "apihelp-unblock-summary": "Gebruikers deblokkeren.",
        "apihelp-unblock-param-user": "Te deblokkeren gebruikersnaam, IP-adres of IP-range. Kan niet in combinatie met <var>$1id</var> of <var>$1userid</var> gebruikt worden.",
        "apihelp-unblock-param-userid": "Te deblokkeren gebruikers-ID. Kan niet in combinatie met <var>$1id</var> of <var>$1user</var> gebruikt worden.",
+       "apihelp-unblock-param-reason": "Reden voor de deblokkade.",
+       "apihelp-upload-param-watch": "De pagina volgen.",
+       "apihelp-upload-param-ignorewarnings": "Eventuele waarschuwingen negeren.",
+       "apihelp-upload-param-file": "Bestandsinhoud.",
+       "apihelp-upload-param-filesize": "Bestandsgroote van de hele upload.",
+       "apihelp-userrights-param-user": "Gebruikersnaam.",
+       "apihelp-userrights-param-userid": "Gebruikers-ID.",
+       "apihelp-userrights-param-remove": "Verwijder de gebruiker uit deze groepen.",
+       "apihelp-userrights-param-reason": "Reden voor de wijziging.",
        "apihelp-json-param-formatversion": "Uitvoeropmaak:\n;1:Achterwaarts-compatibele opmaak (booleans in XML-stijl, <samp>*</samp>-sleutels voor contentnodes, enz.).\n;2:Experimentele moderne opmaak. Details kunnen wijzigen!\n;latest:Gebruik de meest recente opmaak (op het moment <kbd>2</kbd>), kan zonder waarschuwing wijzigen.",
+       "apihelp-jsonfm-summary": "Toon de data in het JSON formaat (opgemaakt in HTML).",
+       "apihelp-none-summary": "Toon niets.",
+       "apihelp-php-summary": "Toon de data in geserialiseerde PHP.",
        "apihelp-php-param-formatversion": "Uitvoeropmaak:\n;1:Achterwaarts-compatibele opmaak (booleans in XML-stijl, <samp>*</samp>-sleutels voor contentnodes, enz.).\n;2:Experimentele moderne opmaak. Details kunnen wijzigen!\n;latest:Gebruik de meest recente opmaak (op het moment <kbd>2</kbd>), kan zonder waarschuwing wijzigen.",
+       "apihelp-phpfm-summary": "Toon de data in geserialiseerde PHP (opgemaakt in HTML).",
        "apihelp-rawfm-summary": "Gegevens, inclusief debugelementen, in JSON-formaat (nette opmaak in HTML) uitvoeren.",
+       "apihelp-xml-summary": "Toon de data in het XML formaat.",
+       "apihelp-xmlfm-summary": "Toon de data in het XML formaat (opgemaakt in HTML).",
+       "api-format-title": "MediaWiki API resultaat.",
+       "api-format-prettyprint-header-hyperlinked": "Dit is de HTML uitvoer van het $1 formaat. HTML is geschikt voor het debuggen, maar ongeschikt voor applicatiegebruik.\n\nGeef de parameter <var>format</var> mee om het uitvoerformaat te wijzigen. Geef [$3 <kbd>format=$2</kbd>] mee om de niet-HTML uitvoer van het $1 formaat te zien.\n\nBekijk de [[mw:API|volledige documentatie]], of de [[Special:ApiHelp/main|API hulp]] voor meer informatie.",
+       "api-help-title": "MediaWiki API hulp",
+       "api-help-undocumented-module": "Er is geen documentatie voor de module $1.",
+       "api-help-flag-internal": "<strong>Deze module is voor intern gebruik of nog niet stabiel.</strong> De functionaliteit kan zonder enige voorafgaande melding wijzigen.",
        "api-help-flag-readrights": "Voor deze module zijn leesrechten nodig.",
        "api-help-flag-writerights": "Voor deze module zijn schrijfrechten nodig.",
+       "api-help-source": "Bron: $1",
+       "api-help-source-unknown": "Bron: <span class=\"apihelp-unknown\">onbekend</span>",
+       "api-help-license": "Licentie: [[$1|$2]]",
+       "api-help-license-noname": "Licentie: [[$1|Zie koppeling]]",
+       "api-help-license-unknown": "Licentie: <span class=\"apihelp-unknown\">onbekend</span>",
        "api-help-parameters": "{{PLURAL:$1|Parameter|Parameters}}:",
        "api-help-param-deprecated": "Verouderd.",
+       "api-help-param-required": "Deze parameter is verplicht.",
        "api-help-datatypes-header": "Gegevenstypen",
+       "api-help-param-type-limit": "Type: geheel getal of <kbd>max</kbd>",
+       "api-help-param-type-integer": "Type: {{PLURAL:$1|1=geheel getal|2=lijst met gehele getallen}}",
+       "api-help-param-type-user": "Type: {{PLURAL:$1|1=gebruikersnaam|2=lijst met gebruikersnamen}}",
+       "api-help-param-list": "{{PLURAL:$1|1=Een van de volgende waarden|2=Waarden (gescheiden met <kbd>{{!}}</kbd> of [[Special:ApiHelp/main#main/datatypes|alternatief]])}}: $2",
+       "api-help-param-list-can-be-empty": "{{PLURAL:$1|0=Moet leeg zijn|Moet leeg of $2 zijn}}",
+       "api-help-param-limit": "Niet meer dan $1 toegestaan.",
+       "api-help-param-limit2": "Niet meer dan $1 ($2 voor bots) toegestaan.",
+       "api-help-param-integer-min": "De {{PLURAL:$1|1=waarde|2=waardes}} mogen niet minder dan $2 zijn.",
+       "api-help-param-integer-max": "De {{PLURAL:$1|1=waarde|2=waardes}} mogen niet meer dan $3 zijn.",
+       "api-help-param-integer-minmax": "De {{PLURAL:$1|1=waarde|2=waardes}} moeten zich tussen $2 en $3 bevinden.",
+       "api-help-param-multi-max": "Het maximaal aantal waarden is {{PLURAL:$1|$1}} ({{PLURAL:$2|$2}} voor bots).",
+       "api-help-param-multi-max-simple": "Het maximaal aantal waarden is {{PLURAL:$1|$1}}.",
+       "api-help-param-multi-all": "Gebruik <kbd>$1</kbd> om alle waarden op te geven.",
        "api-help-param-default": "Standaard: $1",
+       "api-help-param-maxbytes": "Mag niet langer zijn dan $1 {{PLURAL:$1|byte|bytes}}.",
+       "api-help-param-maxchars": "Mag niet langer zijn dan $1 {{PLURAL:$1|teken|tekens}}.",
        "api-help-examples": "{{PLURAL:$1|Voorbeeld|Voorbeelden}}:",
+       "api-help-open-in-apisandbox": "<small>[open in de zandbak]</small>",
        "apierror-autoblocked": "Uw IP-adres is automatisch geblokkeerd, omdat het gebruikt werd door een geblokkeerde gebruiker.",
+       "apierror-badmd5": "De opgegeven MD5 hash is onjuist.",
+       "apierror-badmodule-badsubmodule": "De module <kbd>$1</kbd> heeft geen deelmodule \"$2\".",
        "apierror-badmodule-nosubmodules": "De module <kbd>$1</kbd> heeft geen submodules.",
+       "apierror-badparameter": "Ongeldige waarde voor parameter <var>$1</var>.",
        "apierror-blockedfrommail": "Het versturen van e-mail is voor u geblokkeerd.",
        "apierror-blocked": "Het bewerken is voor u geblokkeerd.",
+       "apierror-cannotviewtitle": "U hebt geen toestemming om $1 te bekijken.",
+       "apierror-cantblock": "U hebt geen rechten om gebruikers te blokkeren.",
+       "apierror-cantchangecontentmodel": "U hebt geen rechten om het inhoudsmodel van een pagina te wijzigen.",
+       "apierror-canthide": "U hebt geen rechten om gebruikersnamen van het blokkeerlogboek te verbergen.",
+       "apierror-cantimport-upload": "U hebt geen rechten om geuploade pagina's te importeren.",
+       "apierror-cantimport": "U hebt geen rechten om pagina's te importeren.",
        "apierror-filedoesnotexist": "Bestand bestaat niet.",
+       "apierror-filetypecannotberotated": "Dit bestandstype kan niet geroteerd worden.",
+       "apierror-import-unknownerror": "Onbekende fout trad op tijdens het importeren: $1.",
        "apierror-integeroutofrange-belowminimum": "<var>$1</var> mag niet minder zijn dan $2 (ingesteld op $3).",
        "apierror-invalidcategory": "De opgegeven categorienaam is niet geldig.",
+       "apierror-invalidtitle": "Ongeldige titel \"$1\".",
        "apierror-invaliduser": "Ongeldige gebruikersnaam \"$1\".",
+       "apierror-invaliduserid": "Gebruikers-ID <var>$1</var> is ongeldig.",
+       "apierror-maxbytes": "Parameter <var>$1</var> mag niet langer dan $2 {{PLURAL:$2|byte|bytes}} zijn",
+       "apierror-maxchars": "Parameter <var>$1</var> mag niet langer dan $2 {{PLURAL:$2|teken|tekens}} zijn",
        "apierror-maxlag-generic": "Wachten op een databaseserver: $1 {{PLURAL:$1|seconde|seconden}} vertraging.",
        "apierror-maxlag": "Wachten op $2: $1 {{PLURAL:$1|seconde|seconden}} vertraging.",
+       "apierror-missingparam-one-of": "{{PLURAL:$2|De parameter|Een van de parameters}} $1 is verplicht.",
+       "apierror-missingparam": "De parameter <var>$1</var> moet opgegeven zijn.",
+       "apierror-missingtitle-createonly": "Ontbrekende titels kunnen alleen beveiligd worden met <kbd>create</kbd>.",
        "apierror-missingtitle": "De opgegeven pagina bestaat niet.",
        "apierror-missingtitle-byname": "De pagina $1 bestaat niet.",
+       "apierror-moduledisabled": "De module <kbd>$1</kbd> is uitgeschakeld.",
+       "apierror-multival-only-one-of": "{{PLURAL:$3|Alleen|Alleen een uit}} $2 is toegestaan voor de parameter <var>$1</var>.",
        "apierror-mustbeloggedin-generic": "U moet ingelogd zijn.",
+       "apierror-mustbeloggedin": "U moet ingelogd zijn om $1.",
+       "apierror-noedit": "U hebt geen rechten om pagina's te bewerken.",
+       "apierror-noimageredirect-anon": "Anonieme gebruikers kunnen geen afbeeldingdoorverwijzingen aanmaken.",
+       "apierror-noimageredirect": "U hebt geen rechten om afbeeldingdoorverwijzingen aan te maken.",
+       "apierror-nosuchlogid": "Er is geen logboekregel met de ID $1.",
+       "apierror-nosuchpageid": "Er is geen pagina met de ID $1.",
+       "apierror-nosuchrcid": "Er is geen recente wijziging met de ID $1.",
+       "apierror-nosuchrevid": "Er is geen versie met de ID $1.",
+       "apierror-nosuchsection": "Er is geen kopje $1.",
+       "apierror-nosuchsection-what": "Er is geen kopje $1 in $2.",
        "apierror-nosuchuserid": "Er is geen gebruiker met ID $1.",
+       "apierror-notarget": "U hebt geen geldig doel opgegeven voor deze handeling.",
+       "apierror-notpatrollable": "De versie r$1 kan niet gemarkeerd worden omdat deze te oud is.",
+       "apierror-opensearch-json-warnings": "Waarschuwingen kunnen niet worden getoond in het OpenSearch JSON formaat.",
+       "apierror-pagelang-disabled": "Het wijzigen van de taal van een pagina is niet toegestaan op deze pagina.",
+       "apierror-paramempty": "De parameter <var>$1</var> mag niet leeg zijn.",
+       "apierror-pastexpiry": "Vervaldatum  \"$1\" is in het verleden.",
        "apierror-permissiondenied": "U hebt geen toestemming om $1.",
        "apierror-permissiondenied-generic": "Toegang geweigerd.",
+       "apierror-protect-invalidaction": "Ongeldig beveiligingstype \"$1\".",
+       "apierror-readapidenied": "U hebt leesrechten nodig om deze module te kunnen gebruiken.",
        "apierror-readonly": "De wiki is momenteel in alleen-lezen modus.",
+       "apierror-searchdisabled": "<var>$1</var> zoeken is uitgeschakeld.",
+       "apierror-sectionsnotsupported": "Kopjes worden niet ondersteund door inhoudsmodel $1.",
+       "apierror-sectionsnotsupported-what": "Kopjes worden niet ondersteund door $1.",
+       "apierror-stashwrongowner": "Onjuiste eigenaar: $1",
        "apierror-systemblocked": "U bent automatisch geblokkeerd door MediaWiki.",
        "apierror-timeout": "De server heeft niet binnen de verwachte tijd geantwoord.",
        "apierror-unknownerror-nocode": "Onbekende fout.",
        "apierror-unknownerror": "Onbekende fout: \"$1\".",
        "apierror-unrecognizedparams": "Niet-herkende {{PLURAL:$2|parameter|parameters}}: $1.",
+       "apiwarn-compare-nocontentmodel": "Het inhoudsmodel kon niet worden bepaald. $1 wordt aangenomen.",
        "apiwarn-invalidcategory": "\"$1\" is geen categorie.",
        "apiwarn-invalidtitle": "\"$1\" is geen geldige titel.",
+       "apiwarn-invalidxmlstylesheetext": "Stijlblad moet de bestandsextensie <code>.xsl</code> hebben.",
+       "apiwarn-invalidxmlstylesheet": "Ongeldig of niet-bestaand stijlblad opgegeven.",
+       "apiwarn-invalidxmlstylesheetns": "Het stijlblad moet zich in de {{ns:MediaWiki}} naamruimte bevinden.",
        "apiwarn-notfile": "\"$1\" is geen bestand.",
+       "apiwarn-parse-nocontentmodel": "Er is geen <var>title</var> of <var>contentmodel</var> opgegeven, $1 wordt aangenomen.",
+       "apiwarn-unrecognizedvalues": "Onbekende {{PLURAL:$3|waarde|waardes}} voor parameter <var>$1</var>: $2.",
        "apiwarn-validationfailed-badpref": "geen geldige voorkeur.",
        "api-feed-error-title": "Fout ($1)",
        "api-usage-docref": "Zie $1 voor API-gebruik.",
+       "api-exception-trace": "$1 in $2($3)\n$4",
        "api-credits-header": "Vermeldingen",
        "api-credits": "API-ontwikkelaars:\n* Yuri Astrakhan (oorspronkelijke ontwikkelaar, hoofdontwikkelaar september 2006 – september 2007)\n* Roan Kattouw (hoofdontwikkelaar september 2007–2009)\n* Victor Vasiliev\n* Bryan Tong Minh\n* Sam Reed\n* Brad Jorsch (hoofdontwikkelaar 2013–heden)\n\nStuur uw opmerkingen, suggesties en vragen naar mediawiki-api@lists.wikimedia.org\nof maak een bugrapport aan op https://phabricator.wikimedia.org/."
 }
index 8591eba..1ded789 100644 (file)
        "apihelp-query+search-paramvalue-prop-hasrelated": "Zignorowano",
        "apihelp-query+search-param-limit": "Łączna liczba stron do zwrócenia.",
        "apihelp-query+search-param-interwiki": "Dołączaj wyniki wyszukiwań interwiki w wyszukiwarce, jeśli możliwe.",
+       "apihelp-query+search-param-sort": "Ustaw porządek sortowania zwracanych wyników.",
        "apihelp-query+search-example-simple": "Szukaj <kbd>meaning</kbd>.",
        "apihelp-query+siteinfo-paramvalue-prop-general": "Ogólne informacje o systemie.",
        "apihelp-query+siteinfo-paramvalue-prop-namespaces": "Lista zarejestrowanych przestrzeni nazw i ich nazwy kanoniczne.",
        "apierror-cantimport": "Nie masz uprawnień do importowania stron.",
        "apierror-cantsend": "Nie jesteś zalogowany, nie masz potwierdzonego adresu e-mail, albo nie masz prawa wysyłać e-maili do innych użytkowników, więc nie możesz wysłać wiadomości e-mail.",
        "apierror-cantundelete": "Nie można przywrócić: dana wersja nie istnieje albo została już przywrócona.",
-       "apierror-databaseerror": "[$1] Błąd zapytania do bazy danych.",
        "apierror-exceptioncaught": "[$1] Stwierdzono wyjątek: $2",
        "apierror-filedoesnotexist": "Plik nie istnieje.",
        "apierror-import-unknownerror": "Nieznany błąd podczas importowania: $1.",
        "apierror-specialpage-cantexecute": "Nie masz uprawnień, aby zobaczyć wyniki tej strony specjalnej.",
        "apierror-stashwrongowner": "Nieprawidłowy właściciel: $1",
        "apierror-timeout": "Serwer nie odpowiedział w spodziewanym czasie.",
+       "apierror-toomanyvalues": "Podano zbyt wiele wartości dla parametru <var>$1</var>. Ograniczenie do $2.",
        "apierror-unknownerror-nocode": "Nieznany błąd.",
        "apierror-unknownerror": "Nieznany błąd: „$1”.",
        "apierror-unknownformat": "Nierozpoznany format „$1”.",
        "apiwarn-invalidtitle": "„$1” nie jest poprawnym tytułem.",
        "apiwarn-notfile": "„$1” nie jest plikiem.",
        "apiwarn-tokennotallowed": "Działanie „$1” jest niedozwolone dla bieżącego użytkownika.",
-       "apiwarn-toomanyvalues": "Podano zbyt wiele wartości dla parametru <var>$1</var>. Ograniczenie do $2.",
        "apiwarn-validationfailed-keytoolong": "klucz zbyt długi (dozwolone nie więcej niż $1 bajtów).",
        "apiwarn-validationfailed": "Błąd walidacji dla <kbd>$1</kbd>: $2",
        "apiwarn-wgDebugAPI": "<strong>Ostrzeżenie o zabezpieczeniach</strong>: włączone jest <var>$wgDebugAPI</var>.",
index df7ea51..3d2ac3e 100644 (file)
        "apihelp-query+filearchive-paramvalue-prop-archivename": "Adiciona o nome do arquivo da versão arquivada para as versões não-mais recentes.",
        "apihelp-query+filearchive-example-simple": "Mostrar uma lista de todos os arquivos excluídos.",
        "apihelp-query+filerepoinfo-summary": "Retorna informações meta sobre repositórios de imagens configurados na wiki.",
-       "apihelp-query+filerepoinfo-param-prop": "Quais propriedades do repositório obter (pode haver mais disponível em algumas wikis):\n;apiurl: URL para a API do repositório - útil para obter informações de imagem do host.\n;name: A chave do repositório - usado em por exemplo, <var>[[mw:Special:MyLanguage/Manual:$wgForeignFileRepos|$wgForeignFileRepos]]</var> e [[Special:ApiHelp/query+imageinfo|imageinfo]] valores de retorno.\n;displayname: O legível para humanos do repositório wiki.\n;rooturl: URL raiz para caminhos de imagem.\n; local: Se esse repositório é o local ou não.",
+       "apihelp-query+filerepoinfo-param-prop": "As propriedades do repositório que devem ser obtidas (as propriedades disponíveis podem variar noutras wikis).",
+       "apihelp-query+filerepoinfo-paramvalue-prop-apiurl": "URL para a API do repositório - útil para obter informação sobre imagens, do repositório.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-articlepath": "<var>[[mw:Special:MyLanguage/Manual:$wgArticlePath|$wgArticlePath]]</var> da wiki do repositório ou equivalente.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-canUpload": "Indica se podem ser carregados ficheiros neste repositório, por exemplo, via CORS e autenticação partilhada.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-displayname": "O nome legível da wiki do repositório.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-favicon": "O URL da favicon da wiki do repositório, de <var>[[mw:Special:MyLanguage/Manual:$wgFavicon|$wgFavicon]]</var>.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-fetchDescription": "Indica se as páginas de descrição de ficheiro devem ser obtidas deste repositório ao ver as páginas de descrição de ficheiros locais.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-initialCapital": "Indica se os nomes de arquivos começam implicitamente com letra maiúscula.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-local": "Indica se o repositório em questão é o local ou não.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-name": "A chave do repositório - usada, por exemplo, nos valores devolvidos em <var>[[mw:Special:MyLanguage/Manual:$wgForeignFileRepos|$wgForeignFileRepos]]</var> e [[Special:ApiHelp/query+imageinfo|imageinfo]].",
+       "apihelp-query+filerepoinfo-paramvalue-prop-rootUrl": "Caminho do URL de raiz para os caminhos de imagens.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-scriptDirUrl": "Caminho do URL de raiz para a instalação MediaWiki da wiki do repositório.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-server": "<var>[[mw:Special:MyLanguage/Manual:$wgServer|$wgServer]]</var> da wiki do repositório ou equivalente.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-thumbUrl": "Caminho do URL de raiz para os caminhos das miniaturas.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-url": "Caminho do URL da zona pública.",
        "apihelp-query+filerepoinfo-example-simple": "Obter informações sobre repositórios de arquivos.",
        "apihelp-query+fileusage-summary": "Encontre todas as páginas que usam os arquivos dados.",
        "apihelp-query+fileusage-param-prop": "Quais propriedades obter:",
        "apihelp-query+recentchanges-param-limit": "Quantas alterações a serem retornadas.",
        "apihelp-query+recentchanges-param-type": "Quais tipos de mudanças mostrar.",
        "apihelp-query+recentchanges-param-toponly": "Somente lista as alterações que são as últimas revisões.",
+       "apihelp-query+recentchanges-param-title": "Filtre as entradas para aquelas relacionadas a uma página.",
        "apihelp-query+recentchanges-param-generaterevisions": "Quando usado como gerador, gere IDs de revisão em vez de títulos. As entradas de alterações recentes sem IDs de revisão associadas (por exemplo, a maioria das entradas de log) não gerarão nada.",
        "apihelp-query+recentchanges-example-simple": "Listar mudanças recentes.",
        "apihelp-query+recentchanges-example-generator": "Obter informações da página sobre as mudanças recentes não patrulhadas.",
        "apihelp-query+revisions+base-paramvalue-prop-user": "Usuário que fez a revisão.",
        "apihelp-query+revisions+base-paramvalue-prop-userid": "ID de usuário do criador da revisão.",
        "apihelp-query+revisions+base-paramvalue-prop-size": "Comprimento (bytes) da revisão.",
+       "apihelp-query+revisions+base-paramvalue-prop-slotsize": "O comprimento (em bytes) de cada segmento de revisão.",
        "apihelp-query+revisions+base-paramvalue-prop-sha1": "SHA-1 (base 16) da revisão.",
-       "apihelp-query+revisions+base-paramvalue-prop-contentmodel": "ID do modelo de conteúdo da revisão.",
+       "apihelp-query+revisions+base-paramvalue-prop-slotsha1": "O resumo criptográfico SHA-1 (base 16) de cada segmento de revisão.",
+       "apihelp-query+revisions+base-paramvalue-prop-contentmodel": "O identificador do modelo de conteúdo de cada segmento de revisão.",
        "apihelp-query+revisions+base-paramvalue-prop-comment": "Comentário do usuário para a revisão.",
        "apihelp-query+revisions+base-paramvalue-prop-parsedcomment": "Analisar comentário do usuário para a revisão.",
-       "apihelp-query+revisions+base-paramvalue-prop-content": "Texto da revisão.",
+       "apihelp-query+revisions+base-paramvalue-prop-content": "Conteúdo de cada segmento de revisão.",
        "apihelp-query+revisions+base-paramvalue-prop-tags": "Etiquetas para a revisão.",
+       "apihelp-query+revisions+base-paramvalue-prop-roles": "Listar as funções dos segmentos de conteúdo que existem na revisão.",
        "apihelp-query+revisions+base-paramvalue-prop-parsetree": "<span class=\"apihelp-deprecated\">Obsoleto.</span> Use <kbd>[[Special:ApiHelp/expandtemplates|action=expandtemplates]]</kbd> ou <kbd>[[Special:ApiHelp/parse|action=parse]]</kbd> em vez. A árvore de análise XML de conteúdo da revisão (requer o modelo de conteúdo <code>$1</code>).",
+       "apihelp-query+revisions+base-param-slots": "Quais os segmentos de revisão cujos dados devem ser devolvidos quando propriedades relacionadas com segmentos são incluídas em <var>$1props</var>. Se for omitido, serão devolvidos dados do segmento principal (<kbd>main</kbd>) num formato compatível com versões anteriores.",
        "apihelp-query+revisions+base-param-limit": "Limita quantas revisões serão retornadas.",
        "apihelp-query+revisions+base-param-expandtemplates": "Use <kbd>[[Special:ApiHelp/expandtemplates|action=expandtemplates]]</kbd> em vez disso. Expande predefinições no conteúdo de revisão (requer $1prop=content).",
        "apihelp-query+revisions+base-param-generatexml": "Use <kbd>[[Special:ApiHelp/expandtemplates|action=expandtemplates]]</kbd> ou <kbd>[[Special:ApiHelp/parse|action=parse]]</kbd> em vez disso. Gerar árvore de analise XML para o conteúdo de revisão (requer $1prop=content).",
        "apihelp-query+search-param-interwiki": "Inclua resultados de interwiki na pesquisa, se disponível.",
        "apihelp-query+search-param-backend": "Qual o backend de pesquisa a ser usado, se não for o padrão.",
        "apihelp-query+search-param-enablerewrites": "Habilita a reescrita de consulta interna. Alguns backends de pesquisa podem reescrever a consulta em outro que é pensado para fornecer melhores resultados, por exemplo, corrigindo erros de ortografia.",
+       "apihelp-query+search-param-sort": "Definir o ordenamento dos resultados devolvidos.",
        "apihelp-query+search-example-simple": "Procurar por <kbd>meaning</kbd>.",
        "apihelp-query+search-example-text": "Procurar textos para <kbd>meaning</kbd>.",
        "apihelp-query+search-example-generator": "Obter informações da página sobre as páginas retornadas para uma pesquisa por <kbd>meaning</kbd>.",
        "apierror-copyuploadbadurl": "Envio não permitido a partir deste URL.",
        "apierror-create-titleexists": "Os títulos existentes não podem ser protegidos com <kbd>create</kbd>.",
        "apierror-csp-report": "Erro ao processar o relatório CSP: $1.",
-       "apierror-databaseerror": "[$1] Houve um erro na consulta ao banco de dados.",
        "apierror-deletedrevs-param-not-1-2": "O parâmetro <var>$1</var> não pode ser usado nos modos 1 ou 2.",
        "apierror-deletedrevs-param-not-3": "O parâmetro <var>$1</var> não pode ser usado no modo 3.",
        "apierror-emptynewsection": "A criação de novas seções vazias não é possível.",
        "apierror-sectionsnotsupported": "As seções não são suportadas para o modelo de conteúdo $1.",
        "apierror-sectionsnotsupported-what": "As seções não são suportadas por $1.",
        "apierror-show": "Parâmetro incorreto - valores mutuamente exclusivos podem não ser fornecidos.",
-       "apierror-siteinfo-includealldenied": "Não é possível visualizar a informação de todos os servidores, a menos que <var>$wgShowHostNames</var> seja true.",
+       "apierror-siteinfo-includealldenied": "Não é possível visualizar a informação de todos os servidores, a menos que <var>$wgShowHostnames</var> seja true.",
        "apierror-sizediffdisabled": "A diferença de tamanho está desativada no Miser Mode.",
        "apierror-spamdetected": "Sua edição foi bloqueada porque contem um fragmento de spam: <code>$1</code>.",
        "apierror-specialpage-cantexecute": "Você não tem permissão para ver os resultados desta página especial.",
        "apierror-templateexpansion-notwikitext": "A expansão da predefinição só é suportada pelo conteúdo do texto wiki. $1 usa o modelo de conteúdo $2.",
        "apierror-timeout": "O servidor não respondeu dentro do tempo esperado.",
        "apierror-toofewexpiries": "{{PLURAL:$1|Foi fornecida $1 data e hora|Foram fornecidas $1 datas e horas}} de expiração quando {{PLURAL:$2|era necessária|eram necessárias}} $2.",
+       "apierror-toomanyvalues": "Muitos valores são fornecidos para o parâmetro <var>$1</var>. O limite é de $2.",
        "apierror-unknownaction": "A ação especificada, <kbd>$1</kbd>, não é reconhecida.",
        "apierror-unknownerror-editpage": "Erro EditPage desconhecido: $1.",
        "apierror-unknownerror-nocode": "Erro desconhecido.",
        "apiwarn-checktoken-percentencoding": "Verificar se os símbolos, como \"+\" no token, estão codificados corretamente na URL.",
        "apiwarn-compare-nocontentmodel": "Nenhum modelo de conteúdo pode ser determinado, assumindo $1.",
        "apiwarn-deprecation-deletedrevs": "<kbd>list=deletedrevs</kbd> foi depreciado. Por favor, use <kbd>prop=deletedrevisions</kbd> ou <kbd>list=alldeletedrevisions</kbd> em vez.",
-       "apiwarn-deprecation-expandtemplates-prop": "Como nenhum valor foi especificado para o parâmetro <var>prop</var>, um formato herdado foi usado para a saída. Este formato está obsoleto e no futuro um valor padrão será definido para o parâmetro <var>prop</var>, fazendo com que o novo formato sempre seja usado.",
        "apiwarn-deprecation-httpsexpected": "HTTP usado quando o HTTPS era esperado.",
        "apiwarn-deprecation-login-botpw": "O login da conta principal via <kbd>action=login</kbd> está obsoleto e pode parar de funcionar sem aviso prévio. Para continuar com o login com <kbd>action=login</ kbd>, consulte [[Special:BotPasswords]]. Para continuar com segurança usando o login da conta principal, veja <kbd>action=clientlogin</kbd>.",
        "apiwarn-deprecation-login-nobotpw": "O login da conta principal via <kbd>action=login</kbd> está obsoleto e pode parar de funcionar sem aviso prévio. Para fazer login com segurança, veja <kbd>action=clientlogin</kbd>.",
        "apiwarn-deprecation-login-token": "Obter um token via <kbd>action=login</kbd> está obsoleto. Use <kbd>action=query&meta=tokens&type=login</kbd> em vez.",
+       "apiwarn-deprecation-missingparam": "Foi usado um formato antigo para a saída, porque <var>$1</var> não foi especificado. Este formato foi descontinuado e de futuro será sempre usado o formato novo.",
        "apiwarn-deprecation-parameter": "O parâmetro <var>$1</var> é obsoleto.",
        "apiwarn-deprecation-parse-headitems": "<kbd>prop=headitems</kbd> está depreciado desde o MediaWiki 1.28. Use <kbd>prop=headhtml</kbd> quando for criar novos documentos HTML, ou <kbd>prop=modules|jsconfigvars</kbd> quando for atualizar um documento no lado do cliente.",
        "apiwarn-deprecation-purge-get": "O uso de <kbd>action=purge</kbd> via GET está obsoleto. Use o POST em vez disso.",
        "apiwarn-redirectsandrevids": "A resolução de redirecionamento não pode ser usada em conjunto com o parâmetro <var>revids</var>. Qualquer redirecionamento <var>revids</var> apontando para não foi resolvido.",
        "apiwarn-tokennotallowed": "A ação \"$1\" não é permitida para o usuário atual.",
        "apiwarn-tokens-origin": "Os tokens não podem ser obtidos quando a política de origem não é aplicada.",
-       "apiwarn-toomanyvalues": "Muitos valores são fornecidos para o parâmetro <var>$1</var>. O limite é de $2.",
        "apiwarn-truncatedresult": "Esse resultado foi truncado porque, de outra forma, seria maior do que o limite de $1 bytes.",
        "apiwarn-unclearnowtimestamp": "Passar \"$2\" para o parâmetro timestamp <var>$1</var> está obsoleto. Se, por algum motivo, você precisa especificar explicitamente o tempo atual sem calcular o lado do cliente, use <kbd>now</kbd>.",
        "apiwarn-unrecognizedvalues": "{{PLURAL:$3|Valor não reconhecido para o parâmetro|Valores não reconhecidos para o parâmetro}} <var>$1</var>: $2.",
index 9adb8b9..0cc3238 100644 (file)
        "apihelp-query+filearchive-paramvalue-prop-archivename": "Adiciona o nome de ficheiro da versão arquivada das versões anteriores à última.",
        "apihelp-query+filearchive-example-simple": "Mostrar uma lista de todos os ficheiros eliminados.",
        "apihelp-query+filerepoinfo-summary": "Devolver meta informação sobre os repositórios de imagens configurados na wiki.",
-       "apihelp-query+filerepoinfo-param-prop": "As propriedades do repositório que devem ser obtidas (em algumas wikis poderão haver mais disponíveis):\n;apiurl:URL para a API do repositório - útil para obter informação de imagens do servidor.\n;name:A chave para o repositório - usada, por exemplo, em <var>[[mw:Special:MyLanguage/Manual:$wgForeignFileRepos|$wgForeignFileRepos]]</var> e nos valores de retorno de [[Special:ApiHelp/query+imageinfo|imageinfo]].\n;displayname:O nome legível da wiki repositório.\n;rooturl:URL de raiz para endereços de imagens.\n;local:Se o repositório é o local ou não.",
+       "apihelp-query+filerepoinfo-param-prop": "As propriedades do repositório que devem ser obtidas (as propriedades disponíveis podem variar noutras wikis).",
+       "apihelp-query+filerepoinfo-paramvalue-prop-apiurl": "URL para a API do repositório - útil para obter informação sobre imagens, do repositório.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-articlepath": "<var>[[mw:Special:MyLanguage/Manual:$wgArticlePath|$wgArticlePath]]</var> da wiki do repositório ou equivalente.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-canUpload": "Indica se podem ser carregados ficheiros neste repositório, por exemplo, via CORS e autenticação partilhada.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-displayname": "O nome legível da wiki do repositório.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-favicon": "O URL da favicon da wiki do repositório, de <var>[[mw:Special:MyLanguage/Manual:$wgFavicon|$wgFavicon]]</var>.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-fetchDescription": "Indica se as páginas de descrição de ficheiro devem ser obtidas deste repositório ao ver as páginas de descrição de ficheiros locais.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-initialCapital": "Indica se os nomes de ficheiros começam implicitamente com letra maiúscula.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-local": "Indica se o repositório em questão é o local ou não.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-name": "A chave do repositório - usada, por exemplo, nos valores devolvidos em <var>[[mw:Special:MyLanguage/Manual:$wgForeignFileRepos|$wgForeignFileRepos]]</var> e [[Special:ApiHelp/query+imageinfo|imageinfo]].",
+       "apihelp-query+filerepoinfo-paramvalue-prop-rootUrl": "Caminho do URL de raiz para os caminhos de imagens.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-scriptDirUrl": "Caminho do URL de raiz para a instalação MediaWiki da wiki do repositório.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-server": "<var>[[mw:Special:MyLanguage/Manual:$wgServer|$wgServer]]</var> da wiki do repositório ou equivalente.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-thumbUrl": "Caminho do URL de raiz para os caminhos das miniaturas.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-url": "Caminho do URL da zona pública.",
        "apihelp-query+filerepoinfo-example-simple": "Obter informações sobre os repositórios de ficheiros.",
        "apihelp-query+fileusage-summary": "Encontrar todas as páginas que usam os ficheiros indicados.",
        "apihelp-query+fileusage-param-prop": "As propriedades a serem obtidas:",
        "apihelp-query+recentchanges-param-limit": "O número total de mudanças a serem devolvidas.",
        "apihelp-query+recentchanges-param-type": "Os tipos de mudanças a serem mostradas.",
        "apihelp-query+recentchanges-param-toponly": "Listar só as alterações que são a revisão mais recente.",
+       "apihelp-query+recentchanges-param-title": "Filtrar as entradas para produzir só as relacionadas com uma página.",
        "apihelp-query+recentchanges-param-generaterevisions": "Ao ser usado como gerador, gerar identificadores de revisões em vez de títulos. As entradas das mudanças recentes que não tenham identificadores de revisão associados (por exemplo, a maioria das entradas do registo) não geram nada.",
        "apihelp-query+recentchanges-example-simple": "Listar as mudanças recentes.",
        "apihelp-query+recentchanges-example-generator": "Obter informação de página acerca das mudanças recentes não patrulhadas.",
        "apihelp-query+revisions+base-paramvalue-prop-timestamp": "A data e hora da revisão.",
        "apihelp-query+revisions+base-paramvalue-prop-user": "O utilizador que fez a revisão.",
        "apihelp-query+revisions+base-paramvalue-prop-userid": "O identificador de utilizador do criador da revisão.",
-       "apihelp-query+revisions+base-paramvalue-prop-size": "O tamanho (em bytes) da revisão.",
+       "apihelp-query+revisions+base-paramvalue-prop-size": "O comprimento (em bytes) da revisão.",
+       "apihelp-query+revisions+base-paramvalue-prop-slotsize": "O comprimento (em bytes) de cada segmento de revisão.",
        "apihelp-query+revisions+base-paramvalue-prop-sha1": "O resumo criptográfico SHA-1 (na base 16) da revisão.",
-       "apihelp-query+revisions+base-paramvalue-prop-contentmodel": "O identificador do modelo de conteúdo da revisão.",
+       "apihelp-query+revisions+base-paramvalue-prop-slotsha1": "O resumo criptográfico SHA-1 (base 16) de cada segmento de revisão.",
+       "apihelp-query+revisions+base-paramvalue-prop-contentmodel": "O identificador do modelo de conteúdo de cada segmento de revisão.",
        "apihelp-query+revisions+base-paramvalue-prop-comment": "O comentário do utilizador para a revisão.",
        "apihelp-query+revisions+base-paramvalue-prop-parsedcomment": "O comentário do utilizador para a revisão, após a análise sintática.",
-       "apihelp-query+revisions+base-paramvalue-prop-content": "O texto da revisão.",
+       "apihelp-query+revisions+base-paramvalue-prop-content": "Conteúdo de cada segmento de revisão.",
        "apihelp-query+revisions+base-paramvalue-prop-tags": "As etiquetas para a revisão.",
-       "apihelp-query+revisions+base-paramvalue-prop-parsetree": "<span class=\"apihelp-deprecated\">Descontinuado.</span> Em substituição, use <kbd>[[Special:ApiHelp/expandtemplates|action=expandtemplates]]</kbd> ou <kbd>[[Special:ApiHelp/parse|action=parse]]</kbd>. A árvore de análise XML do conteúdo da revisão (requer o modelo de conteúdo <code>$1</code>).",
+       "apihelp-query+revisions+base-paramvalue-prop-roles": "Listar as funções dos segmentos de conteúdo que existem na revisão.",
+       "apihelp-query+revisions+base-paramvalue-prop-parsetree": "Usar antes <kbd>[[Special:ApiHelp/expandtemplates|action=expandtemplates]]</kbd> ou <kbd>[[Special:ApiHelp/parse|action=parse]]</kbd>. A árvore XML da análise sintática do conteúdo da revisão <code>$1</code>).",
+       "apihelp-query+revisions+base-param-slots": "Quais os segmentos de revisão cujos dados devem ser devolvidos quando propriedades relacionadas com segmentos são incluídas em <var>$1props</var>. Se for omitido, serão devolvidos dados do segmento principal (<kbd>main</kbd>) num formato compatível com versões anteriores.",
        "apihelp-query+revisions+base-param-limit": "Limitar o número de revisões que serão devolvidas.",
        "apihelp-query+revisions+base-param-expandtemplates": "Em substituição, use <kbd>[[Special:ApiHelp/expandtemplates|action=expandtemplates]]</kbd>. Expandir predefinições no conteúdo da revisão (requer $1prop=content).",
        "apihelp-query+revisions+base-param-generatexml": "Em substituição, use <kbd>[[Special:ApiHelp/expandtemplates|action=expandtemplates]]</kbd> ou <kbd>[[Special:ApiHelp/parse|action=parse]]</kbd>. Gerar a árvore de análise sintática em XML do conteúdo da revisão (requer $1prop=content).",
        "apihelp-query+search-param-interwiki": "Incluir resultados interwikis na pesquisa, se disponíveis.",
        "apihelp-query+search-param-backend": "O servidor de pesquisas a ser usado, se diferente do servidor padrão.",
        "apihelp-query+search-param-enablerewrites": "Ativar a reescrita da pesquisa interna. Alguns motores de pesquisa podem reescrever a pesquisa substituindo-a por outra que consideram que dará melhores resultados, por exemplo, por corrigir erros de ortografia.",
+       "apihelp-query+search-param-sort": "Definir o ordenamento dos resultados devolvidos.",
        "apihelp-query+search-example-simple": "Pesquisar <kbd>meaning</kbd>.",
        "apihelp-query+search-example-text": "Pesquisar <kbd>meaning</kbd> nos textos.",
        "apihelp-query+search-example-generator": "Obter informação sobre as páginas devolvidas por uma pesquisa do termo <kbd>meaning</kbd>.",
        "apihelp-query+watchlist-param-prop": "As propriedades adicionais que devem ser obtidas:",
        "apihelp-query+watchlist-paramvalue-prop-ids": "Adiciona identificadores de revisões e de páginas.",
        "apihelp-query+watchlist-paramvalue-prop-title": "Adiciona o título da página.",
-       "apihelp-query+watchlist-paramvalue-prop-flags": "Adiciona etiquetas para a edição.",
+       "apihelp-query+watchlist-paramvalue-prop-flags": "Adiciona as etiquetas da edição.",
        "apihelp-query+watchlist-paramvalue-prop-user": "Adiciona o utilizador que fez a edição.",
        "apihelp-query+watchlist-paramvalue-prop-userid": "Adiciona o identificador do utilizador que realizou a edição.",
        "apihelp-query+watchlist-paramvalue-prop-comment": "Adiciona o comentário da edição.",
        "api-help-param-default": "Valor por omissão: $1",
        "api-help-param-default-empty": "Padrão: <span class=\"apihelp-empty\">(vazio)</span>",
        "api-help-param-token": "Uma chave \"$1\" obtida de [[Special:ApiHelp/query+tokens|action=query&meta=tokens]]",
-       "api-help-param-token-webui": "Para efeitos de compatibilidade, a chave usada na interface ''web'' também é aceite.",
+       "api-help-param-token-webui": "Para efeitos de compatibilidade, a chave usada na interface da Internet também é aceite.",
        "api-help-param-disabled-in-miser-mode": "Desativado devido ao [[mw:Special:MyLanguage/Manual:$wgMiserMode|modo avarento]] (''miser mode'').",
        "api-help-param-limited-in-miser-mode": "<strong>Nota:</strong> devido ao [[mw:Special:MyLanguage/Manual:$wgMiserMode|modo avarento]] (''miser mode''), usar isto pode resultar na devolução de menos de <var>$1limit</var> resultados antes de continuar; em casos extremos pode não ser devolvido qualquer resultado.",
        "api-help-param-direction": "A direção da enumeração:\n;newer:Listar o mais antigo primeiro. Nota: $1start tem de estar antes de $1end.\n;older:Listar o mais recente primeiro (padrão). Nota: $1start tem de estar depois de $1end.",
        "api-help-authmanagerhelper-messageformat": "Formato a usar nas mensagens de saída.",
        "api-help-authmanagerhelper-mergerequestfields": "Combinar a informação de todos os pedidos de autenticação numa única matriz.",
        "api-help-authmanagerhelper-preservestate": "Preservar o estado de uma tentativa de autenticação anterior falhada, se possível.",
-       "api-help-authmanagerhelper-returnurl": "O URL de retorno para processos de autenticação por terceiros tem de ser absoluto. É obrigatório fornecer este URL ou <var>$1continue</var>.\n\nTipicamente, após receber uma resposta <samp>REDIRECT</samp>, abrirá um ''browser'' ou uma ''web view'' para o URL <samp>redirecttarget</samp> especificado, para dar lugar ao processo de autenticação por terceiros. Quando esse processo terminar, a terceira entidade encaminhará o ''browser'' ou a ''web view'' para este URL. Deve extrair do URL quaisquer parâmetros de consulta ou de POST, e passá-los como um pedido <var>$1continue</var> a este módulo da API.",
+       "api-help-authmanagerhelper-returnurl": "O URL de retorno para processos de autenticação por terceiros tem de ser absoluto. É obrigatório fornecer este URL ou <var>$1continue</var>.\n\nTipicamente, após receber uma resposta <samp>REDIRECT</samp>, abrirá um ''browser'' ou uma vista da Internet para o URL <samp>redirecttarget</samp> especificado, para dar lugar ao processo de autenticação por terceiros. Quando esse processo terminar, a terceira entidade encaminhará o ''browser'' ou a vista da Internet para este URL. Deve extrair do URL quaisquer parâmetros de consulta ou de POST, e passá-los como um pedido <var>$1continue</var> a este módulo da API.",
        "api-help-authmanagerhelper-continue": "Este pedido é uma continuação após uma resposta anterior com o valor <samp>UI</samp> ou <samp>REDIRECT</samp>. É obrigatório fornecer este parâmetro ou o parâmetro <var>$1returnurl</var>.",
        "api-help-authmanagerhelper-additional-params": "Este módulo aceita parâmetros adicionais, dependendo dos pedidos de autenticação disponíveis. Use <kbd>[[Special:ApiHelp/query+authmanagerinfo|action=query&meta=authmanagerinfo]]</kbd> com <kbd>amirequestsfor=$1</kbd> (ou uma resposta anterior deste módulo, se aplicável) para determinar os pedidos disponíveis e os campos que estes utilizam.",
        "apierror-allimages-redirect": "Usar <kbd>gaifilterredir=nonredirects</kbd> em vez de <var>redirects</var> ao utilizar <kbd>allimages</kbd> como gerador.",
        "apierror-copyuploadbadurl": "Não são permitidos carregamentos a partir deste URL.",
        "apierror-create-titleexists": "Os títulos existentes não podem ser protegidos com  <kbd>create</kbd>.",
        "apierror-csp-report": "Ocorreu um erro no processamento do relatório CSP: $1.",
-       "apierror-databaseerror": "[$1] Erro na consulta da base de dados.",
        "apierror-deletedrevs-param-not-1-2": "O parâmetro <var>$1</var> não pode ser usado nos modos 1 e 2.",
        "apierror-deletedrevs-param-not-3": "O parâmetro <var>$1</var> não pode ser usado no modo 3.",
        "apierror-emptynewsection": "Não é possível criar secções novas vazias.",
        "apierror-emptypage": "Não é permitido criar páginas novas vazias.",
-       "apierror-exceptioncaught": "[$1] Exceção intercetada: $2",
+       "apierror-exceptioncaught": "[$1] Exceção capturada: $2",
+       "apierror-exceptioncaughttype": "[$1] Foi capturada uma exceção do tipo $2",
        "apierror-filedoesnotexist": "O ficheiro não existe.",
        "apierror-fileexists-sharedrepo-perm": "O ficheiro de destino já existe num repositório partilhado. Use o parâmetro <var>ignorewarnings</var> para substituí-lo.",
        "apierror-filenopath": "Não é possível obter o caminho local do ficheiro.",
        "apierror-sectionsnotsupported": "Secções não são suportadas pelo modelo de conteúdo $1.",
        "apierror-sectionsnotsupported-what": "Secções não são suportadas por $1.",
        "apierror-show": "Parâmetro incorreto - não podem ser fornecidos valores mutuamente exclusivos.",
-       "apierror-siteinfo-includealldenied": "Não é possível ver a informação de todos os servidores, a menos que <var>$wgShowHostNames</var> tenha o valor \"true\".",
+       "apierror-siteinfo-includealldenied": "Não é possível ver a informação de todos os servidores, a menos que <var>$wgShowHostnames</var> tenha o valor \"true\".",
        "apierror-sizediffdisabled": "A diferença de tamanho está desativada no modo avarento.",
        "apierror-spamdetected": "A sua edição foi recusada porque continha um fragmento de spam: <code>$1</code>.",
        "apierror-specialpage-cantexecute": "Não tem permissão para ver os resultados desta página especial.",
        "apierror-templateexpansion-notwikitext": "A expansão de predefinições só é suportada para conteúdo em texto wiki. A página $1 usa o modelo de conteúdo $2.",
        "apierror-timeout": "O servidor não respondeu no prazo esperado.",
        "apierror-toofewexpiries": "{{PLURAL:$1|Foi fornecida $1 data e hora|Foram fornecidas $1 datas e horas}} de expiração quando {{PLURAL:$2|era necessária|eram necessárias}} $2.",
+       "apierror-toomanyvalues": "Foram fornecidos demasiados valores para o parâmetro <var>$1</var>. O limite é $2.",
        "apierror-unknownaction": "A operação especificada, <kbd>$1</kbd>, não é reconhecida.",
        "apierror-unknownerror-editpage": "Erro EditPage desconhecido: $1.",
        "apierror-unknownerror-nocode": "Erro desconhecido.",
        "apiwarn-checktoken-percentencoding": "Verifique que símbolos como \"+\" na chave estão devidamente codificados com percentagem no URL.",
        "apiwarn-compare-nocontentmodel": "Não foi possível determinar nenhum modelo de conteúdo; será assumido $1.",
        "apiwarn-deprecation-deletedrevs": "<kbd>list=deletedrevs</kbd> foi descontinuado. Em substituição, use <kbd>prop=deletedrevisions</kbd> ou <kbd>list=alldeletedrevisions</kbd>, por favor.",
-       "apiwarn-deprecation-expandtemplates-prop": "Dado que não foi especificado nenhum valor para o parâmetro <var>prop</var> foi usado um formato antigo para o resultado. Esse formato está descontinuado e, de futuro, será definido um valor por omissão para o parâmetro <var>prop</var>, de forma que seja sempre usado um formato novo.",
        "apiwarn-deprecation-httpsexpected": "Foi usado HTTP quando era esperado HTTPS.",
        "apiwarn-deprecation-login-botpw": "O início de sessões com uma conta principal através de <kbd>action=login</kbd> foi descontinuado e poderá deixar de funcionar sem aviso prévio. Para continuar a iniciar sessões com <kbd>action=login</kbd>, consulte [[Special:BotPasswords]]. Para continuar a iniciar sessões com a conta principal de forma segura, consulte <kbd>action=clientlogin</kbd>.",
        "apiwarn-deprecation-login-nobotpw": "O início de sessões com uma conta principal através de <kbd>action=login</kbd> foi descontinuado e poderá deixar de funcionar sem aviso prévio. Para iniciar uma sessão de forma segura, consulte <kbd>action=clientlogin</kbd>.",
        "apiwarn-deprecation-login-token": "A obtenção de uma chave através de <kbd>action=login</kbd> foi descontinuada. Em substituição, use <kbd>action=query&meta=tokens&type=login</kbd>.",
+       "apiwarn-deprecation-missingparam": "Foi usado um formato antigo para a saída, porque <var>$1</var> não foi especificado. Este formato foi descontinuado e de futuro será sempre usado o formato novo.",
        "apiwarn-deprecation-parameter": "O parâmetro <var>$1</var> foi descontinuado.",
        "apiwarn-deprecation-parse-headitems": "<kbd>prop=headitems</kbd> está obsoleto desde o MediaWiki 1.28. Use <kbd>prop=headhtml</kbd> ao criar novos documentos de HTML, ou <kbd>prop=modules|jsconfigvars</kbd> ao atualizar um documento no lado do cliente.",
        "apiwarn-deprecation-purge-get": "O uso de <kbd>action=purge</kbd> através de um GET foi descontinuado. Em substituição, use um POST.",
        "apiwarn-redirectsandrevids": "Resolução de redirecionamentos não pode ser usada em conjunto com o parâmetro <var>revids</var>. Quaisquer redirecionamentos para os quais <var>revids</var> aponta não foram resolvidos.",
        "apiwarn-tokennotallowed": "A operação \"$1\" não é permitida para o utilizador atual.",
        "apiwarn-tokens-origin": "Não é possível obter chaves quando a norma da mesma origem não é aplicada.",
-       "apiwarn-toomanyvalues": "Foram fornecidos demasiados valores para o parâmetro <var>$1</var>. O limite é $2.",
        "apiwarn-truncatedresult": "Este resultado foi truncado porque ultrapassaria o limite de $1 bytes.",
        "apiwarn-unclearnowtimestamp": "A passagem de \"$2\" no parâmetro de data e hora <var>$1</var> foi tornada obsoleta. Se, por qualquer razão, precisa de especificar de forma explícita a hora atual sem a calcular no lado do cliente, use <kbd>now</kbd>.",
        "apiwarn-unrecognizedvalues": "{{PLURAL:$3|Valor não reconhecido|Valores não reconhecidos}} para o parâmetro <var>$1</var>: $2.",
index 1ecb077..f158f27 100644 (file)
        "apihelp-query+filearchive-example-simple": "{{doc-apihelp-example|query+filearchive}}",
        "apihelp-query+filerepoinfo-summary": "{{doc-apihelp-summary|query+filerepoinfo}}",
        "apihelp-query+filerepoinfo-param-prop": "{{doc-apihelp-param|query+filerepoinfo|prop}}",
+       "apihelp-query+filerepoinfo-paramvalue-prop-apiurl": "{{doc-apihelp-paramvalue|query+filerepoinfo|prop|apiurl}}",
+       "apihelp-query+filerepoinfo-paramvalue-prop-articlepath": "{{doc-apihelp-paramvalue|query+filerepoinfo|prop|articlepath}}",
+       "apihelp-query+filerepoinfo-paramvalue-prop-canUpload": "{{doc-apihelp-paramvalue|query+filerepoinfo|prop|canUpload}}",
+       "apihelp-query+filerepoinfo-paramvalue-prop-displayname": "{{doc-apihelp-paramvalue|query+filerepoinfo|prop|displayname}}",
+       "apihelp-query+filerepoinfo-paramvalue-prop-favicon": "{{doc-apihelp-paramvalue|query+filerepoinfo|prop|favicon}}",
+       "apihelp-query+filerepoinfo-paramvalue-prop-fetchDescription": "{{doc-apihelp-paramvalue|query+filerepoinfo|prop|fetchDescription}}",
+       "apihelp-query+filerepoinfo-paramvalue-prop-initialCapital": "{{doc-apihelp-paramvalue|query+filerepoinfo|prop|initialCapital}}",
+       "apihelp-query+filerepoinfo-paramvalue-prop-local": "{{doc-apihelp-paramvalue|query+filerepoinfo|prop|local}}",
+       "apihelp-query+filerepoinfo-paramvalue-prop-name": "{{doc-apihelp-paramvalue|query+filerepoinfo|prop|name}}",
+       "apihelp-query+filerepoinfo-paramvalue-prop-rootUrl": "{{doc-apihelp-paramvalue|query+filerepoinfo|prop|rootUrl}}",
+       "apihelp-query+filerepoinfo-paramvalue-prop-scriptDirUrl": "{{doc-apihelp-paramvalue|query+filerepoinfo|prop|scriptDirUrl}}",
+       "apihelp-query+filerepoinfo-paramvalue-prop-server": "{{doc-apihelp-paramvalue|query+filerepoinfo|prop|server}}",
+       "apihelp-query+filerepoinfo-paramvalue-prop-thumbUrl": "{{doc-apihelp-paramvalue|query+filerepoinfo|prop|thumbUrl}}",
+       "apihelp-query+filerepoinfo-paramvalue-prop-url": "{{doc-apihelp-paramvalue|query+filerepoinfo|prop|url}}",
        "apihelp-query+filerepoinfo-example-simple": "{{doc-apihelp-example|query+filerepoinfo}}",
        "apihelp-query+fileusage-summary": "{{doc-apihelp-summary|query+fileusage}}",
        "apihelp-query+fileusage-param-prop": "{{doc-apihelp-param|query+fileusage|prop|paramvalues=1}}",
        "apihelp-query+recentchanges-param-limit": "{{doc-apihelp-param|query+recentchanges|limit}}",
        "apihelp-query+recentchanges-param-type": "{{doc-apihelp-param|query+recentchanges|type}}",
        "apihelp-query+recentchanges-param-toponly": "{{doc-apihelp-param|query+recentchanges|toponly}}",
+       "apihelp-query+recentchanges-param-title": "{{doc-apihelp-param|query+recentchanges|title}}",
        "apihelp-query+recentchanges-param-generaterevisions": "{{doc-apihelp-param|query+recentchanges|generaterevisions}}",
        "apihelp-query+recentchanges-example-simple": "{{doc-apihelp-example|query+recentchanges}}",
        "apihelp-query+recentchanges-example-generator": "{{doc-apihelp-example|query+recentchanges}}",
        "apihelp-query+revisions+base-paramvalue-prop-user": "{{doc-apihelp-paramvalue|query+revisions+base|prop|user}}",
        "apihelp-query+revisions+base-paramvalue-prop-userid": "{{doc-apihelp-paramvalue|query+revisions+base|prop|userid}}",
        "apihelp-query+revisions+base-paramvalue-prop-size": "{{doc-apihelp-paramvalue|query+revisions+base|prop|size}}",
+       "apihelp-query+revisions+base-paramvalue-prop-slotsize": "{{doc-apihelp-paramvalue|query+revisions+base|prop|slotsize}}",
        "apihelp-query+revisions+base-paramvalue-prop-sha1": "{{doc-apihelp-paramvalue|query+revisions+base|prop|sha1}}",
+       "apihelp-query+revisions+base-paramvalue-prop-slotsha1": "{{doc-apihelp-paramvalue|query+revisions+base|prop|slotsha1}}",
        "apihelp-query+revisions+base-paramvalue-prop-contentmodel": "{{doc-apihelp-paramvalue|query+revisions+base|prop|contentmodel}}",
        "apihelp-query+revisions+base-paramvalue-prop-comment": "{{doc-apihelp-paramvalue|query+revisions+base|prop|comment}}",
        "apihelp-query+revisions+base-paramvalue-prop-parsedcomment": "{{doc-apihelp-paramvalue|query+revisions+base|prop|parsedcomment}}",
        "apihelp-query+revisions+base-paramvalue-prop-content": "{{doc-apihelp-paramvalue|query+revisions+base|prop|content}}",
        "apihelp-query+revisions+base-paramvalue-prop-tags": "{{doc-apihelp-paramvalue|query+revisions+base|prop|tags}}",
+       "apihelp-query+revisions+base-paramvalue-prop-roles": "{{doc-apihelp-paramvalue|query+revisions+base|prop|roles}}",
        "apihelp-query+revisions+base-paramvalue-prop-parsetree": "{{doc-apihelp-paramvalue|query+revisions+base|prop|parsetree|params=* $1 - Value of the constant CONTENT_MODEL_WIKITEXT|paramstart=2}}",
+       "apihelp-query+revisions+base-param-slots": "{{doc-apihelp-param|query+revisions+base|slots|description=the \"slots\" parameter to revision querying modules|noseealso=1}}",
        "apihelp-query+revisions+base-param-limit": "{{doc-apihelp-param|query+revisions+base|limit|description=the \"limit\" parameter to revision querying modules|noseealso=1}}",
        "apihelp-query+revisions+base-param-expandtemplates": "{{doc-apihelp-param|query+revisions+base|expandtemplates|description=the \"expandtemplates\" parameter to revision querying modules|noseealso=1}}",
        "apihelp-query+revisions+base-param-generatexml": "{{doc-apihelp-param|query+revisions+base|generatexml|description=the \"generatexml\" parameter to revision querying modules|noseealso=1}}",
        "apihelp-query+search-param-interwiki": "{{doc-apihelp-param|query+search|interwiki}}",
        "apihelp-query+search-param-backend": "{{doc-apihelp-param|query+search|backend}}",
        "apihelp-query+search-param-enablerewrites": "{{doc-apihelp-param|query+search|enablerewrites}}",
+       "apihelp-query+search-param-sort": "{{doc-apihelp-param|query+search|sort}}",
        "apihelp-query+search-example-simple": "{{doc-apihelp-example|query+search}}",
        "apihelp-query+search-example-text": "{{doc-apihelp-example|query+search}}",
        "apihelp-query+search-example-generator": "{{doc-apihelp-example|query+search}}",
        "apierror-copyuploadbadurl": "{{doc-apierror}}",
        "apierror-create-titleexists": "{{doc-apierror}}",
        "apierror-csp-report": "{{doc-apierror}}\n\nParameters:\n* $1 - Error code, e.g. \"toobig\".",
-       "apierror-databaseerror": "{{doc-apierror}}\n\nParameters:\n* $1 - Exception log ID code. This is meaningless to the end user, but can be used by people with access to the logs to easily find the logged error.",
        "apierror-deletedrevs-param-not-1-2": "{{doc-apierror}}\n\nParameters:\n* $1 - Parameter name.\n\nSee also:\n* {{msg-mw|apihelp-query+deletedrevs-extended-description}}",
        "apierror-deletedrevs-param-not-3": "{{doc-apierror}}\n\nParameters:\n* $1 - Parameter name.\n\nSee also:\n* {{msg-mw|apihelp-query+deletedrevs-extended-description}}",
        "apierror-emptynewsection": "{{doc-apierror}}",
        "apierror-emptypage": "{{doc-apierror}}",
        "apierror-exceptioncaught": "{{doc-apierror}}\n\nParameters:\n* $1 - Exception log ID code. This is meaningless to the end user, but can be used by people with access to the logs to easily find the logged error.\n* $2 - Exception message, which may end with punctuation. Probably in English.",
+       "apierror-exceptioncaughttype": "{{doc-apierror}}\n\nParameters:\n* $1 - Exception log ID code. This is meaningless to the end user, but can be used by people with access to the logs to easily find the logged error.\n* $2 - Exception type (for example, DBError).",
        "apierror-filedoesnotexist": "{{doc-apierror}}",
        "apierror-fileexists-sharedrepo-perm": "{{doc-apierror}}",
        "apierror-filenopath": "{{doc-apierror}}",
        "apiwarn-checktoken-percentencoding": "{{doc-apierror}}",
        "apiwarn-compare-nocontentmodel": "{{doc-apierror}}\n\nParameters:\n* $1 - Content model being assumed.",
        "apiwarn-deprecation-deletedrevs": "{{doc-apierror}}",
-       "apiwarn-deprecation-expandtemplates-prop": "{{doc-apierror}}",
        "apiwarn-deprecation-httpsexpected": "{{doc-apierror}}",
        "apiwarn-deprecation-login-botpw": "{{doc-apierror}}",
        "apiwarn-deprecation-login-nobotpw": "{{doc-apierror}}",
        "apiwarn-deprecation-login-token": "{{doc-apierror}}",
+       "apiwarn-deprecation-missingparam": "{{doc-apierror}}\n\nParameters:\n* $1 - Parameter name.",
        "apiwarn-deprecation-parameter": "{{doc-apierror}}\n\nParameters:\n* $1 - Parameter name.",
        "apiwarn-deprecation-parse-headitems": "{{doc-apierror}}",
        "apiwarn-deprecation-purge-get": "{{doc-apierror}}",
index 48d3643..bae0948 100644 (file)
                        "Mouse21",
                        "Happy13241",
                        "Ole Yves",
-                       "AttemptToCallNil"
+                       "AttemptToCallNil",
+                       "Movses",
+                       "Stjn",
+                       "Edward Chernenko",
+                       "Vlad5250"
                ]
        },
        "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-parse-paramvalue-prop-headitems": "Возвращает элементы, которые следует поместить в <code>&lt;head&gt;</code> страницы.",
        "apihelp-parse-paramvalue-prop-headhtml": "Возвращает распарсенный <code>&lt;head&gt;</code> страницы.",
        "apihelp-parse-paramvalue-prop-modules": "Возвращает использованные на странице модули ResourceLoader. Для загрузки, используйте <code>mw.loader.using()</code>. Одновременно с <kbd>modules</kbd> должно быть запрошено либо <kbd>jsconfigvars</kbd>, либо <kbd>encodedjsconfigvars</kbd>.",
-       "apihelp-parse-paramvalue-prop-jsconfigvars": "Возвращает переменные JavaScript с данными настроек для этой страницы. Для их применения используйте <code>mw.condig.set()</code>.",
+       "apihelp-parse-paramvalue-prop-jsconfigvars": "Возвращает переменные JavaScript с данными настроек для этой страницы. Для их применения используйте <code>mw.config.set()</code>.",
        "apihelp-parse-paramvalue-prop-encodedjsconfigvars": "Возвращает переменные JavaScript с данными настроек для этой страницы в виде JSON-строки.",
        "apihelp-parse-paramvalue-prop-indicators": "Возвращает HTML-код индикаторов, использованных на данной странице.",
        "apihelp-parse-paramvalue-prop-iwlinks": "Возвращает интервики-ссылки из распарсенного вики-текста.",
        "apihelp-query+filearchive-paramvalue-prop-archivename": "Добавляет имя архивной версии файла.",
        "apihelp-query+filearchive-example-simple": "Список всех удалённых файлов.",
        "apihelp-query+filerepoinfo-summary": "Возвращает мета-информацию о файловых репозиториях, настроенных в вики.",
-       "apihelp-query+filerepoinfo-param-prop": "Какие свойства хранилища получить (на некоторых вики может быть доступно больше):\n;apiutl: Ссылка на API хранилища — полезно для получения информации об изображении с хоста.\n;name: Ключ хранилища — используется, например, <var>[[mw:Special:MyLanguage/Manual:$wgForeignFileRepos|$wgForeignFileRepos]]</var> и возвращаемых [[Special:ApiHelp/query+imageinfo|imageinfo]].\n;displayname: Человеко-читаемое название хранилища.\n;rooturl: Корневая ссылка для путей к файлам.\n;local: Определяет, является ли хранилище локальным, или нет.",
+       "apihelp-query+filerepoinfo-param-prop": "Какие свойства хранилища получить (доступность свойств может отличаться в разных вики).",
+       "apihelp-query+filerepoinfo-paramvalue-prop-rootUrl": "Корневой URL для изображений.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-url": "URL путь публичной зоны.",
        "apihelp-query+filerepoinfo-example-simple": "Получить информацию о файловых репозиториях.",
        "apihelp-query+fileusage-summary": "Поиск всех страниц, использующих данный файл.",
        "apihelp-query+fileusage-param-prop": "Какие свойства получить:",
        "apihelp-query+recentchanges-param-limit": "Сколько правок вернуть.",
        "apihelp-query+recentchanges-param-type": "Какие типы правок показать.",
        "apihelp-query+recentchanges-param-toponly": "Перечислять только последние правки страниц.",
+       "apihelp-query+recentchanges-param-title": "Вернуть записи, связанные со страницей.",
        "apihelp-query+recentchanges-param-generaterevisions": "При использовании в качестве генератора, генерировать идентификаторы версий вместо их названий. Записи последних изменений без привязанного идентификатора версии (например, большинство записей журналов) не сгенерируют ничего.",
        "apihelp-query+recentchanges-example-simple": "Список последних изменений.",
        "apihelp-query+recentchanges-example-generator": "Получить информацию о последних страницах с неотпатрулированными изменениями.",
        "apihelp-query+search-param-interwiki": "Включить результаты из других вики, если доступны.",
        "apihelp-query+search-param-backend": "Какой поисковый движок использовать, если не стандартный.",
        "apihelp-query+search-param-enablerewrites": "Разрешить редактирование запроса. Некоторые поисковые движки могут отредактировать запрос, например, исправив опечатку, если посчитают, что это приведёт к лучшим результатам.",
+       "apihelp-query+search-param-sort": "Задаёт порядок сортировки возвращаемых результатов.",
        "apihelp-query+search-example-simple": "Найти <kbd>meaning</kbd>.",
        "apihelp-query+search-example-text": "Найти тексты, содержащие <kbd>meaning</kbd>.",
        "apihelp-query+search-example-generator": "Получить информацию о страницах, возвращённых по поисковому запросу <kbd>meaning</kbd>.",
        "apierror-copyuploadbadurl": "Загрузка по этой ссылке недоступна.",
        "apierror-create-titleexists": "Существующие названия не могут быть защищены с помощью <kbd>create</kbd>.",
        "apierror-csp-report": "Ошибка при обработке отчёта CSP: $1.",
-       "apierror-databaseerror": "[$1] Ошибка запроса к базе данных.",
        "apierror-deletedrevs-param-not-1-2": "Параметр <var>$1</var> не может быть использован в режимах 1 и 2.",
        "apierror-deletedrevs-param-not-3": "Параметр <var>$1</var> не может быть использован в третьем режиме.",
        "apierror-emptynewsection": "Создание пустых секций невозможно.",
        "apierror-sectionsnotsupported": "Разбиение на секции не поддерживается моделью содержимого $1.",
        "apierror-sectionsnotsupported-what": "Разбиение на секции не поддерживается $1.",
        "apierror-show": "Некорректный параметр — вручную исключённые значения не могут быть обработаны.",
-       "apierror-siteinfo-includealldenied": "Невозможно отобразить информацию о всех серверах, если <var>$wgShowHostNames</var> не истинно.",
+       "apierror-siteinfo-includealldenied": "Невозможно отобразить информацию о всех серверах, если <var>$wgShowHostnames</var> не истинно.",
        "apierror-sizediffdisabled": "Подсчёт разницы размеров отключён в жадном режиме.",
        "apierror-spamdetected": "Ваша правка была отклонена, так как содержит спам: <code>$1</code>.",
        "apierror-specialpage-cantexecute": "У вас нет прав, чтобы просматривать результаты этой служебной страницы.",
        "apierror-templateexpansion-notwikitext": "Раскрытие шаблонов разрешено только для вики-текстового содержимого. $1 использует модель содержимого $2.",
        "apierror-timeout": "Сервер не ответил за ожидаемое время.",
        "apierror-toofewexpiries": "Задано $1 {{PLURAL:$1|временная метка|временные метки|временных меток}} истечения, необходимо $2.",
+       "apierror-toomanyvalues": "Слишком много значений передано параметру <var>$1</var>. Максимальное число — $2.",
        "apierror-unknownaction": "Заданное действие, <kbd>$1</kbd>, не распознано.",
        "apierror-unknownerror-editpage": "Неизвестная ошибка EditPage: $1.",
        "apierror-unknownerror-nocode": "Неизвестная ошибка.",
        "apiwarn-checktoken-percentencoding": "Проверьте, что символы вроде «+» в токене корректно закодированы %-последовательностями в ссылке.",
        "apiwarn-compare-nocontentmodel": "Модель содержимого не может быть определена, предполагается $1.",
        "apiwarn-deprecation-deletedrevs": "<kbd>list=deletedrevs</kbd> устарел. Пожалуйста, вместо него используйте <kbd>prop=deletedrevisions</kbd> или <kbd>list=alldeletedrevisions</kbd>.",
-       "apiwarn-deprecation-expandtemplates-prop": "Поскольку никакие значения не были указаны в параметре <var>prop</var>, был использован наследованный формат. Этот формат является устаревшим, и в будущем параметру <var>prop</var> будет присвоено значение по умолчанию, что приведёт к повсеместному использованию нового формата.",
        "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-redirectsandrevids": "Раскрытие перенаправлений не может быть использовано вместе с параметром <var>revids</var>. Все перенаправления на точку <var>revids</var> не должны быть раскрыты.",
        "apiwarn-tokennotallowed": "Действие «$1» не разрешено для текущего участника.",
        "apiwarn-tokens-origin": "Токены не могут быть получены, пока не применено правило ограничения домена.",
-       "apiwarn-toomanyvalues": "Слишком много значений передано параметру <var>$1</var>. Максимальное число — $2.",
        "apiwarn-truncatedresult": "Результат был усечён, поскольку в противном случае он был бы больше лимита в $1 {{PLURAL:$1|байт|байта|байт}}.",
        "apiwarn-unclearnowtimestamp": "Передача «$2» в качестве параметра временной метки <var>$1</var> устарело. Если по какой-то причине вы хотите прямо указать текущее время без вычисления его на стороне клиента, используйте <kbd>now</kbd>.",
        "apiwarn-unrecognizedvalues": "{{PLURAL:$3|Нераспознанное значение|Нераспознанные значения}} параметра <var>$1</var>: $2.",
index 5c0a12e..20dc919 100644 (file)
        "api-help-param-maxchars": "Kan inte vara längre än $1 {{PLURAL:$1|tecken}}.",
        "apierror-articleexists": "Artikeln du försökte skapa har redan skapats.",
        "apierror-baddiff": "Diff kan inte hämtas. En eller båda sidversioner finns inte eller du har inte behörighet för att visa dem.",
+       "apierror-exceptioncaughttype": "[$1] Fångade undantag av typen $2",
        "apierror-invalidoldimage": "Parametern <var>oldimage</var> har ett ogiltigt format.",
        "apierror-invalidsection": "Parametern <var>section</var> måste vara ett giltigt avsnitts-ID eller <kbd>new</kbd>.",
        "apierror-maxbytes": "Parametern <var>$1</var> kan inte var längre än $2 {{PLURAL:$2|byte}}",
index bc0b365..e9078e0 100644 (file)
@@ -16,7 +16,7 @@
                        "Choomaq"
                ]
        },
-       "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> Усі функції, вказані на цій сторінці, мають працювати, але 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: Errors and warnings]].\n\n<strong>Тестування:</strong> Для зручності тестування запитів API, див. [[Special:ApiSandbox]].",
+       "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> Усі функції, вказані на цій сторінці, мають працювати, але 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-main-param-action": "Яку дію виконати.",
        "apihelp-main-param-format": "Формат виводу.",
        "apihelp-main-param-maxlag": "Максимальна затримка може використовуватися, коли MediaWiki інстальовано на реплікований кластер бази даних. Щоб зберегти дії, які спричиняють більшу затримку реплікації, цей параметр може змусити клієнт почекати, поки затримка реплікації не буде меншою за вказане значення. У випадку непомірної затримки, видається код помилки <samp>maxlag</samp> з повідомленням на зразок <samp>Очікування на $host: $lag секунд(и) затримки</samp>.<br />Див. [[mw:Special:MyLanguage/Manual:Maxlag_parameter|Manual: Maxlag parameter]] для детальнішої інформації.",
@@ -67,6 +67,7 @@
        "apihelp-compare-param-fromid": "Перший ID сторінки для порівняння.",
        "apihelp-compare-param-fromrev": "Перша версія для порівняння.",
        "apihelp-compare-param-fromtext": "Використати цей текст замість контенту версії, вказаної через <var>fromtitle</var>, <var>fromid</var> або <var>fromrev</var>.",
+       "apihelp-compare-param-fromsection": "Використовувати лише вказану секцію із заданого вмісту «from».",
        "apihelp-compare-param-frompst": "Зробити трансформацію перед збереженням на <var>fromtext</var>.",
        "apihelp-compare-param-fromcontentmodel": "Контентна модель <var>fromtext</var>. Якщо не вказано, буде використано припущення на основі інших параметрів.",
        "apihelp-compare-param-fromcontentformat": "Формат серіалізації контенту <var>fromtext</var>.",
@@ -75,6 +76,7 @@
        "apihelp-compare-param-torev": "Друга версія для порівняння.",
        "apihelp-compare-param-torelative": "Використати версію, яка стосується версії, визначеної через <var>fromtitle</var>, <var>fromid</var> або <var>fromrev</var>. Усі інші опції 'to' буде проігноровано.",
        "apihelp-compare-param-totext": "Використати цей текст замість контенту версії, вказаної через <var>totitle</var>, <var>toid</var> або <var>torev</var>.",
+       "apihelp-compare-param-tosection": "Використовувати лише вказану секцію із заданого вмісту «to».",
        "apihelp-compare-param-topst": "Виконати трансформацію перед збереженням на <var>totext</var>.",
        "apihelp-compare-param-tocontentmodel": "Контентна модель <var>totext</var>. Якщо не вказано, буде використано припущення на основі інших параметрів.",
        "apihelp-compare-param-tocontentformat": "Формат серіалізації контенту <var>totext</var>.",
        "apihelp-import-extended-description": "Зважте, що HTTP POST має бути виконано як завантаження файлу (тобто з використанням даних різних частин/форм) під час надсилання файлу для параметра <var>xml</var>.",
        "apihelp-import-param-summary": "Підсумок імпорту записів журналу.",
        "apihelp-import-param-xml": "Завантажено XML-файл.",
+       "apihelp-import-param-interwikiprefix": "Для завантажених імпортів: префікс інтервікі, який слід додавати до невідомих імен користувачів (а також відомих користувачів, якщо задано <var>$1assignknownusers</var>).",
+       "apihelp-import-param-assignknownusers": "Прив'язувати редагування до локальних користувачів, якщо користувач із таким іменем існує локально.",
        "apihelp-import-param-interwikisource": "Для інтервікі-імпорту: вікі, з якої імпортувати.",
        "apihelp-import-param-interwikipage": "Для інтервікі-імпорту: сторінки для імпорту.",
        "apihelp-import-param-fullhistory": "Для інтервікі-імпорту: імпортувати повну історію, не лише поточну версію.",
        "apihelp-opensearch-summary": "Шукати у вікі з використанням протоколу OpenSearch.",
        "apihelp-opensearch-param-search": "Рядок пошуку.",
        "apihelp-opensearch-param-limit": "Максимальна кількість результатів для виведення.",
-       "apihelp-opensearch-param-namespace": "Простори назв, у яких шукати.",
+       "apihelp-opensearch-param-namespace": "Простори назв, у яких шукати. Ігнорується, якщо <var>$1search</var> починається з валідного префікса простору назв.",
        "apihelp-opensearch-param-suggest": "Нічого не робити, якщо <var>[[mw:Special:MyLanguage/Manual:$wgEnableOpenSearchSuggest|$wgEnableOpenSearchSuggest]]</var> хибний.",
        "apihelp-opensearch-param-redirects": "Як обробляти перенаправлення:\n;return:Видати саме перенаправлення.\n;resolve:Видати цільову сторінку. Може видати менше, ніж $1limit результат{{PLURAL:$1limit||и|ів}}.\nЗ історичних причин, за замовчуванням стоїть «return» для $1format=json і «resolve» — для інших форматів.",
        "apihelp-opensearch-param-format": "Формат виводу.",
        "apihelp-parse-param-disablepp": "Використати натомість <var>$1disablelimitreport</var>.",
        "apihelp-parse-param-disableeditsection": "Пропустити посилання на редагування розділів на виході аналізу.",
        "apihelp-parse-param-disabletidy": "Не запускайте очищення HTML (e.g. tidy) на виході аналізу.",
+       "apihelp-parse-param-disablestylededuplication": "Не усувайте дублікати вбудованих таблиць стилів на виході парсера.",
        "apihelp-parse-param-generatexml": "Генерувати синтаксичне дерево XML (передбачає модель вмісту <code>$1</code>; замінено на <kbd>$2prop=parsetree</kbd>).",
        "apihelp-parse-param-preview": "Аналізувати у режимі попереднього перегляду.",
        "apihelp-parse-param-sectionpreview": "Аналізувати у режимі попереднього перегляду розділу (також вмикає попередній перегляд).",
        "apihelp-query+filearchive-param-dir": "Напрямок, у якому перелічити.",
        "apihelp-query+filearchive-param-sha1": "SHA1-хеш зображення. Перевизначає $1sha1base36.",
        "apihelp-query+filearchive-param-sha1base36": "SHA1-хеш зображення у base 36 (використано в MediaWiki).",
-       "apihelp-query+filearchive-param-prop": "Which image information to get:",
+       "apihelp-query+filearchive-param-prop": "Інформацію про яке зображення слід отримати:",
        "apihelp-query+filearchive-paramvalue-prop-sha1": "Додає хеш SHA-1 до зображення.",
        "apihelp-query+filearchive-paramvalue-prop-timestamp": "Додає часову мітку завантаженої версії.",
        "apihelp-query+filearchive-paramvalue-prop-user": "Додає користувача, який завантажив версію зображення.",
        "apihelp-query+filearchive-paramvalue-prop-archivename": "Додає до імені версію архіву для неостаточного варіанту файлу.",
        "apihelp-query+filearchive-example-simple": "Показати список усіх вилучених файлів.",
        "apihelp-query+filerepoinfo-summary": "Видати мета-інформацію про репозиторії зображень, налаштовані на вікі.",
-       "apihelp-query+filerepoinfo-param-prop": "Які властивості репозиторію отримати (на деяких вікі може бути більше):\n;apiurl:URL до репозиторію API — корисне для отримання інформації про зображення з хосту.\n;name:Ключ репозиторію — використано в e.g. <var>[[mw:Special:MyLanguage/Manual:$wgForeignFileRepos|$wgForeignFileRepos]]</var> і значення [[Special:ApiHelp/query+imageinfo|imageinfo]].\n;displayname:Людиночита назва репозиторію вікі.\n;rooturl:Корінний URL для шляху зображення.\n;local:Чи репозиторій локальний, чи ні.",
+       "apihelp-query+filerepoinfo-param-prop": "Які властивості репозиторію отримати (доступні властивості можуть варіюватися в інших вікі).",
+       "apihelp-query+filerepoinfo-paramvalue-prop-apiurl": "URL-адреса API репозиторію — корисно для отримання інформації про зображення від хоста.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-articlepath": "<var>[[mw:Special:MyLanguage/Manual:$wgArticlePath|$wgArticlePath]]</var> вікі-сайту репозиторію, або еквівалент.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-canUpload": "Чи можна завантажувати файли в цей репозиторій, напр., через CORS та спільну автентифікацію.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-displayname": "Назва вікі-сайту репозиторію, читабельна для людини.",
        "apihelp-query+filerepoinfo-example-simple": "Отримати інформацію про репозиторії файлів.",
        "apihelp-query+fileusage-summary": "Знайти всі сторінки, що використовують дані файли.",
        "apihelp-query+fileusage-param-prop": "Які властивості отримати:",
        "apierror-copyuploadbadurl": "Завантаження з цієї URL-адреси недозволені.",
        "apierror-create-titleexists": "Наявні назви не можна захистити за допомогою <kbd>create</kbd>.",
        "apierror-csp-report": "Помилка при опрацюванні CSP-звіту: $1.",
-       "apierror-databaseerror": "[$1] Помилка запиту до бази даних.",
        "apierror-deletedrevs-param-not-1-2": "Параметр <var>$1</var> не може використовуватись у режимах 1 або 2.",
        "apierror-deletedrevs-param-not-3": "Параметр <var>$1</var> не може використовуватись у режимі 3.",
        "apierror-emptynewsection": "Створення нових порожніх розділів неможливе.",
        "apierror-sectionsnotsupported": "Розділи не підтримуються для контентної моделі $1.",
        "apierror-sectionsnotsupported-what": "Розділи не підтримуються $1.",
        "apierror-show": "Неправильний параметр — не можна надавати взаємовиключні значення.",
-       "apierror-siteinfo-includealldenied": "Не можна переглядати інформацію щодо всіх серверів, якщо тільки <var>$wgShowHostNames</var> не вказано як «true».",
+       "apierror-siteinfo-includealldenied": "Не можна переглядати інформацію щодо всіх серверів, якщо тільки <var>$wgShowHostnames</var> не вказано як «true».",
        "apierror-sizediffdisabled": "Різниця у розмірах вимкнена в скупому режимі.",
        "apierror-spamdetected": "Ваше редагування було відхилено, оскільки воно містило фрагмент спаму: <code>$1</code>.",
        "apierror-specialpage-cantexecute": "Ви не маєте прав на перегляд результатів цієї спеціальної сторінки.",
        "apierror-templateexpansion-notwikitext": "Розширення шаблонів підтримується лише для вмісту у форматі вікірозмітки. $1 використовує контентну модель $2.",
        "apierror-timeout": "Сервер не відповів протягом відведеного на це часу.",
        "apierror-toofewexpiries": "$1 {{PLURAL:$1|мітка часу завершення була надана|мітки часу завершення були надані|міток часу завершення було надано}}, тоді як {{PLURAL:$2|потрібна була $2 така мітка|потрібні були $2 таких мітки|потрібно було $2 таких міток}}.",
+       "apierror-toomanyvalues": "Надто багато значень задано для параметра <var>$1</var>. Ліміт становить $2.",
        "apierror-unknownaction": "Вказана дія, <kbd>$1</kbd>, нерозпізнана.",
        "apierror-unknownerror-editpage": "Невідома помилка EditPage: $1.",
        "apierror-unknownerror-nocode": "Невідома помилка.",
        "apiwarn-checktoken-percentencoding": "Перевірте, чи символи, такі як «+» у токені, пройшли правильне процентне кодування в URL.",
        "apiwarn-compare-nocontentmodel": "Не вдалося визначити контентну модель, припускаємо $1.",
        "apiwarn-deprecation-deletedrevs": "<kbd>list=deletedrevs</kbd> є застарілим. Будь ласка, використовуйте замість нього <kbd>prop=deletedrevisions</kbd> або <kbd>list=alldeletedrevisions</kbd>.",
-       "apiwarn-deprecation-expandtemplates-prop": "Оскільки не задано жодних значень для параметра <var>prop</var>, як вихідні дані було використано старий формат. Цей формат є застарілим, і в майбутньому параметру <var>prop</var> буде задано стандартне значення, наслідком чого стане те, що завжди використовуватиметься новий формат.",
        "apiwarn-deprecation-httpsexpected": "Використано HTTP, тоді як очікувалося використання HTTPS.",
        "apiwarn-deprecation-login-botpw": "Вхід в основний обліковий запис через <kbd>action=login</kbd> є застарілим, і може припинити працювати, без попередження. Щоб продовжити вхід у систему через <kbd>action=login</kbd>, див. [[Special:BotPasswords]]. Щоб безпечно продовжити, використовуючи вхід в основний обліковий запис, див. <kbd>action=clientlogin</kbd>.",
        "apiwarn-deprecation-login-nobotpw": "Вхід в основний обліковий запис через <kbd>action=login</kbd> є застарілим, і може припинити працювати, без попередження. Щоб безпечно увійти в систему, див. <kbd>action=clientlogin</kbd>.",
        "apiwarn-redirectsandrevids": "Вирішення перенаправлень не може використовуватись разом з параметром <var>revids</var>. Усі перенаправлення, на які вказує <var>revids</var>, не було вирішено.",
        "apiwarn-tokennotallowed": "Дія «$1» недозволена для поточного користувача.",
        "apiwarn-tokens-origin": "Токени не можна отримати, поки не застосована політика одного походження.",
-       "apiwarn-toomanyvalues": "Надто багато значень задано для параметра <var>$1</var>. Ліміт становить $2.",
        "apiwarn-truncatedresult": "Цей результат було скорочено, оскільки інакше він перевищив би ліміт у $1 байтів.",
        "apiwarn-unclearnowtimestamp": "Вказування «$2» для параметра мітки часу <var>$1</var> є застарілим. Якщо з якоїсь причини Вам треба чітко вказати поточний час без вираховування його з боку клієнта, використайте <kbd>now</kbd>.",
        "apiwarn-unrecognizedvalues": "{{PLURAL:$3|Нерозпізнане|Нерозпізнані}} значення для параметра <var>$1</var>: $2.",
index f335890..088b730 100644 (file)
@@ -24,7 +24,8 @@
                        "D41D8CD98F",
                        "Umherirrender",
                        "NeverBehave",
-                       "Wbxshiori"
+                       "Wbxshiori",
+                       "Wxyveronica"
                ]
        },
        "apihelp-main-extended-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:Special:MyLanguage/API:Main_page|文档]]\n* [[mw:Special:MyLanguage/API:FAQ|常见问题]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api 邮件列表]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce API公告]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R 程序错误与功能请求]\n</div>\n<strong>状态信息:</strong>MediaWiki API是一个成熟稳定的,不断受到支持和改进的界面。尽管我们尽力避免,但偶尔也需要作出重大更新;请订阅[https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ mediawiki-api-announce 邮件列表]以便获得更新通知。\n\n<strong>错误请求:</strong>当API收到错误请求时,HTTP header将会返回一个包含\"MediaWiki-API-Error\"的值,随后header的值与error code将会送回并设置为相同的值。详细信息请参阅[[mw:Special:MyLanguage/API:Errors_and_warnings|API:错误与警告]]。\n\n<p class=\"mw-apisandbox-link\"><strong>测试中:</strong>测试API请求的易用性,请参见[[Special:ApiSandbox]]。</p>",
        "apihelp-purge-example-simple": "刷新<kbd>Main Page</kbd>和<kbd>API</kbd>页面。",
        "apihelp-purge-example-generator": "刷新主名字空间的前10个页面。",
        "apihelp-query-summary": "取得来自并有关MediaWiki的数据。",
-       "apihelp-query-extended-description": "所有数据修改将首先不得不使用查询来获得令牌,以阻止来自恶意网站的滥用行为。",
+       "apihelp-query-extended-description": "所有数据修改须首先使用查询来获得令牌,以阻止来自恶意网站的滥用行为。",
        "apihelp-query-param-prop": "要为已查询页面获取的属性。",
        "apihelp-query-param-list": "要获取的列表。",
        "apihelp-query-param-meta": "要获取的元数据。",
        "apihelp-query+filearchive-paramvalue-prop-archivename": "添加用于非最新版本的存档版本的文件名。",
        "apihelp-query+filearchive-example-simple": "显示已删除文件列表。",
        "apihelp-query+filerepoinfo-summary": "返回有关wiki配置的图片存储库的元信息。",
-       "apihelp-query+filerepoinfo-param-prop": "要获取的存储库属性(这在一些wiki上可能有更多可用选项):\n;apiurl:链接至API的URL - 对从主机获取图片信息有用。\n;name:存储库关键词 - 用于例如<var>[[mw:Special:MyLanguage/Manual:$wgForeignFileRepos|$wgForeignFileRepos]]</var>,并且[[Special:ApiHelp/query+imageinfo|imageinfo]]会返回值。\n;displayname:人类可读的存储库wiki名称。\n;rooturl:图片路径的根URL。\n;local:存储库是否在本地。",
+       "apihelp-query+filerepoinfo-param-prop": "要获取的存储库属性(可用属性在其他wiki上可能不同)。",
+       "apihelp-query+filerepoinfo-paramvalue-prop-apiurl": "至存储库API的URL - 对从主机获取图片信息有用。",
+       "apihelp-query+filerepoinfo-paramvalue-prop-articlepath": "存储库wiki的<var>[[mw:Special:MyLanguage/Manual:$wgArticlePath|$wgArticlePath]]</var>或等价物。",
+       "apihelp-query+filerepoinfo-paramvalue-prop-canUpload": "文件是否可以上传至此存储库,例如通过CORS和共享身份验证。",
+       "apihelp-query+filerepoinfo-paramvalue-prop-displayname": "人类可读的存储库wiki名称。",
+       "apihelp-query+filerepoinfo-paramvalue-prop-favicon": "存储库wiki的网站图标URL,来自<var>[[mw:Special:MyLanguage/Manual:$wgFavicon|$wgFavicon]]</var>。",
+       "apihelp-query+filerepoinfo-paramvalue-prop-fetchDescription": "当查看本地文件说明页面时,文件描述页面是否检索自此存储库。",
+       "apihelp-query+filerepoinfo-paramvalue-prop-initialCapital": "文件名是否隐式地以大写字母开头。",
+       "apihelp-query+filerepoinfo-paramvalue-prop-local": "存储库是否为本地的。",
+       "apihelp-query+filerepoinfo-paramvalue-prop-name": "存储库的关键词 - 用于例如<var>[[mw:Special:MyLanguage/Manual:$wgForeignFileRepos|$wgForeignFileRepos]]</var>和[[Special:ApiHelp/query+imageinfo|imageinfo]]返回的值。",
+       "apihelp-query+filerepoinfo-paramvalue-prop-rootUrl": "用于图片路径的根URL路径。",
+       "apihelp-query+filerepoinfo-paramvalue-prop-scriptDirUrl": "用于存储库wiki的MediaWiki安装副本的根URL路径。",
+       "apihelp-query+filerepoinfo-paramvalue-prop-server": "存储库wiki的<var>[[mw:Special:MyLanguage/Manual:$wgServer|$wgServer]]</var>或等价物。",
+       "apihelp-query+filerepoinfo-paramvalue-prop-thumbUrl": "用于缩略图路径的根URL路径。",
+       "apihelp-query+filerepoinfo-paramvalue-prop-url": "公开区域URL路径。",
        "apihelp-query+filerepoinfo-example-simple": "获得有关文件存储库的信息。",
        "apihelp-query+fileusage-summary": "查找所有使用指定文件的页面。",
        "apihelp-query+fileusage-param-prop": "要获取的属性:",
        "apihelp-query+recentchanges-param-limit": "返回总计更新数。",
        "apihelp-query+recentchanges-param-type": "显示的更改类型。",
        "apihelp-query+recentchanges-param-toponly": "只列举作为最新修订的更改。",
+       "apihelp-query+recentchanges-param-title": "过滤记录至这些与页面相关的。",
        "apihelp-query+recentchanges-param-generaterevisions": "当作为生成器使用时,生成修订ID而不是标题。不带关联修订ID的最近更改记录(例如大多数日志记录)将不会生成任何东西。",
        "apihelp-query+recentchanges-example-simple": "最近更改列表。",
        "apihelp-query+recentchanges-example-generator": "获取有关最近未巡查更改的页面信息。",
        "apihelp-query+search-param-interwiki": "搜索结果中包含跨wiki结果,如果可用。",
        "apihelp-query+search-param-backend": "要使用的搜索后端,如果没有则为默认。",
        "apihelp-query+search-param-enablerewrites": "启用内部查询重写。一些搜索后端可以重写查询到另一个被认为能提供更好结果的位置,例如纠正拼写错误。",
+       "apihelp-query+search-param-sort": "设置返回结果的排序。",
        "apihelp-query+search-example-simple": "搜索<kbd>meaning</kbd>。",
        "apihelp-query+search-example-text": "搜索文本<kbd>meaning</kbd>。",
        "apihelp-query+search-example-generator": "获取有关搜索<kbd>meaning</kbd>返回页面的页面信息。",
        "apierror-copyuploadbadurl": "不允许从此URL上传。",
        "apierror-create-titleexists": "现有标题不能通过<kbd>create</kbd>保护。",
        "apierror-csp-report": "处理CSP报告时出错:$1。",
-       "apierror-databaseerror": "[$1]数据库查询错误。",
        "apierror-deletedrevs-param-not-1-2": "<var>$1</var>参数不能用于模式1或2。",
        "apierror-deletedrevs-param-not-3": "<var>$1</var>参数不能用于模式3。",
        "apierror-emptynewsection": "无法创建空白新章节。",
        "apierror-emptypage": "不允许创建新的,空白的页面。",
        "apierror-exceptioncaught": "[$1]捕获异常:$2",
+       "apierror-exceptioncaughttype": "[$1]发现$2类型异常",
        "apierror-filedoesnotexist": "文件不存在。",
        "apierror-fileexists-sharedrepo-perm": "目标文件存在于共享存储库。使用<var>ignorewarnings</var>参数覆盖它。",
        "apierror-filenopath": "不能获取本地文件路径。",
        "apierror-sectionsnotsupported": "内容模型$1不支持章节。",
        "apierror-sectionsnotsupported-what": "章节不被$1所支持。",
        "apierror-show": "不正确的参数——不可提供互斥值。",
-       "apierror-siteinfo-includealldenied": "除非<var>$wgShowHostNames</var>为真,否则不能查看所有服务器的信息。",
+       "apierror-siteinfo-includealldenied": "除非<var>$wgShowHostnames</var>为真,否则不能查看所有服务器的信息。",
        "apierror-sizediffdisabled": "大小差异在Miser模式中被禁用。",
        "apierror-spamdetected": "您的编辑被拒绝,因为它包含垃圾部分:<code>$1</code>。",
        "apierror-specialpage-cantexecute": "您没有权限查看此特殊页面的结果。",
        "apierror-templateexpansion-notwikitext": "模板展开只支持wiki文本内容。$1使用内容模型$2。",
        "apierror-timeout": "服务器没有在预期时间内响应。",
        "apierror-toofewexpiries": "提供了$1个逾期{{PLURAL:$1|时间戳}},实际则需要$2个。",
+       "apierror-toomanyvalues": "为参数<var>$1</var>提供了太多值。限制为$2。",
        "apierror-unknownaction": "指定的操作<kbd>$1</kbd>不被承认。",
        "apierror-unknownerror-editpage": "未知的编辑页面错误:$1。",
        "apierror-unknownerror-nocode": "未知错误。",
        "apiwarn-checktoken-percentencoding": "在令牌中检查例如“+”的符号会在URL中适当进行百分号编码。",
        "apiwarn-compare-nocontentmodel": "没有可以定义的模型,假定为$1。",
        "apiwarn-deprecation-deletedrevs": "<kbd>list=deletedrevs</kbd>已弃用。请改用<kbd>prop=deletedrevisions</kbd>或<kbd>list=alldeletedrevisions</kbd>。",
-       "apiwarn-deprecation-expandtemplates-prop": "因为没有为<var>prop</var>参数指定值,所以在输出上使用了遗留格式。这种格式已弃用,并且将来会为<var>prop</var>参数设置默认值,这会导致新格式总会被使用。",
        "apiwarn-deprecation-httpsexpected": "当应为HTTPS时,HTTP被使用。",
        "apiwarn-deprecation-login-botpw": "通过<kbd>action=login</kbd>的主账户登录已被弃用,并可能在未事先警告的情况下停止工作。要继续通过<kbd>action=login</kbd>登录,请参见[[Special:BotPasswords]]。要安全继续使用主账户登录,请参见<kbd>action=clientlogin</kbd>。",
        "apiwarn-deprecation-login-nobotpw": "通过<kbd>action=login</kbd>的主账户登录已被弃用,并可能在未事先警告的情况下停止工作。要安全登录,请参见<kbd>action=clientlogin</kbd>。",
        "apiwarn-redirectsandrevids": "重定向解决方案不能与<var>revids</var>参数一起使用。任何<var>revids</var>所指向的重定向都未被解决。",
        "apiwarn-tokennotallowed": "操作“$1”不允许当前用户使用。",
        "apiwarn-tokens-origin": "在未应用同来源方针时,令牌可能无法获得。",
-       "apiwarn-toomanyvalues": "参数<var>$1</var>指定了太多的值。上限为$2。",
        "apiwarn-truncatedresult": "此结果被缩短,否则其将大于$1字节的限制。",
        "apiwarn-unclearnowtimestamp": "为时间戳参数<var>$1</var>传递“$2”已被弃用。如因某些原因您需要明确指定当前时间而不计算客户端,请使用<kbd>now</kbd>。",
        "apiwarn-unrecognizedvalues": "参数<var>$1</var>有无法识别的{{PLURAL:$3|值}}:$2。",
index 2f9b693..9f101b6 100644 (file)
@@ -18,7 +18,7 @@
                        "Sanmosa"
                ]
        },
-       "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>本頁所展示的所有功能都應正常運作,但API仍在開發,會隨時變化。請訂閱[https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ mediawiki-api-announce 郵遞清單]以便獲得更新通知。\n\n<strong>錯誤的請求:</strong>當API收到錯誤的請求,會發出以「MediaWiki-API-Error」為鍵的HTTP標頭欄位,隨後標頭欄位的值,以及傳回的錯誤碼會設為相同值。詳細資訊請參閱[[mw:Special:MyLanguage/API:Errors_and_warnings|API: 錯誤與警告]]。\n\n<strong>測試:</strong>要簡化API請求的測試過程,請見[[Special:ApiSandbox]]。",
+       "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>本頁所展示的所有功能都應正常運作,但API仍在開發,會隨時變化。請訂閱[https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ mediawiki-api-announce 郵寄清單]以便獲得更新通知。\n\n<strong>錯誤的請求:</strong>當API收到錯誤的請求,會發出以「MediaWiki-API-Error」為鍵的HTTP標頭欄位,隨後標頭欄位的值,以及傳回的錯誤碼會設為相同值。詳細資訊請參閱[[mw:Special:MyLanguage/API:Errors_and_warnings|API: 錯誤與警告]]。\n\n<strong>測試:</strong>要簡化API請求的測試過程,請見[[Special:ApiSandbox]]。",
        "apihelp-main-param-action": "要執行的動作。",
        "apihelp-main-param-format": "輸出的格式。",
        "apihelp-main-param-smaxage": "將HTTP緩存控制頭欄位設為<code>s-maxage</code>秒。錯誤不會做緩存。",
@@ -29,7 +29,7 @@
        "apihelp-main-param-servedby": "在結果中包括提出請求的主機名。",
        "apihelp-main-param-curtimestamp": "在結果中包括目前的時間戳。",
        "apihelp-main-param-responselanginfo": "在結果中包括<var>uselang</var>和<var>errorlang</var>所用的語言。",
-       "apihelp-block-summary": "封鎖用戶。",
+       "apihelp-block-summary": "封鎖使用者。",
        "apihelp-block-param-user": "要封鎖的使用者名稱、IP 位址或 IP 範圍。不能與 <var>$1userid</var> 一起使用",
        "apihelp-block-param-reason": "封鎖原因。",
        "apihelp-block-param-anononly": "僅封鎖匿名使用者 (禁止這個 IP 位址的匿名使用者編輯)。",
@@ -60,7 +60,7 @@
        "apihelp-compare-param-torev": "要比對的第二個修訂。",
        "apihelp-compare-example-1": "建立修訂 1 與 1 的差異檔",
        "apihelp-createaccount-summary": "建立新使用者帳號。",
-       "apihelp-createaccount-param-name": "用戶名。",
+       "apihelp-createaccount-param-name": "使用者名稱。",
        "apihelp-createaccount-param-password": "密碼 (若有設定 <var>$1mailpassword</var> 則可略過)。",
        "apihelp-createaccount-param-domain": "外部身分核對使用的網域 (可有可無)。",
        "apihelp-createaccount-param-token": "在第一次請求時已取得的帳號建立金鑰。",
        "apihelp-import-param-namespace": "匯入至此命名空間。無法與 <var>$1rootpage</var> 一起使用。",
        "apihelp-import-param-rootpage": "匯入作為此頁面的子頁面。無法與 <var>$1namespace</var> 一起使用。",
        "apihelp-login-summary": "登入並取得身分核對 cookies",
-       "apihelp-login-param-name": "用戶名。",
+       "apihelp-login-param-name": "使用者名稱。",
        "apihelp-login-param-password": "密碼。",
        "apihelp-login-param-domain": "網域名稱(可有可無)。",
        "apihelp-login-example-login": "登入",
        "apihelp-query+allredirects-param-limit": "要回傳的項目總數。",
        "apihelp-query+allrevisions-summary": "列出所有修訂版本。",
        "apihelp-query+alltransclusions-param-limit": "要回傳的項目總數。",
+       "apihelp-query+allusers-param-from": "起始列舉的使用者名稱。",
+       "apihelp-query+allusers-example-Y": "列出以<kbd>Y</kbd>開頭的使用者。",
        "apihelp-query+authmanagerinfo-summary": "取得目前身分核對狀態的資訊。",
        "apihelp-query+categories-param-limit": "要回傳的分類數量。",
        "apihelp-query+categoryinfo-summary": "回傳有關指定分類的資訊。",
        "apihelp-unblock-example-id": "解除封銷 ID #<kbd>105</kbd>。",
        "apihelp-undelete-param-reason": "還原的原因。",
        "apihelp-userrights-summary": "變更一位使用者的群組成員。",
-       "apihelp-userrights-param-user": "用戶名。",
-       "apihelp-userrights-param-userid": "用戶ID。",
+       "apihelp-userrights-param-user": "使用者名稱。",
+       "apihelp-userrights-param-userid": "使用者ID。",
        "apihelp-userrights-param-add": "加入使用者至這些群組;若已是成員,則更新失效時間。",
        "apihelp-userrights-param-remove": "從這些群組移除使用者。",
        "apihelp-userrights-param-reason": "變更的原因。",
        "api-format-title": "MediaWiki API 結果",
        "api-format-prettyprint-header": "這是$1格式的HTML呈現。HTML適合用於除錯,但不適合應用程式使用。\n\n指定<var>format</var>參數以更改輸出格式。要檢視$1格式的非HTML呈現,設定<kbd>format=$2</kbd>。\n\n參考 [[mw:Special:MyLanguage/API|完整說明文件]] 或 [[Special:ApiHelp/main|API說明]] 以取得更多資訊。",
        "api-format-prettyprint-header-only-html": "這是用來除錯的HTML呈現,不適合實際應用。\n\n參見[[mw:Special:MyLanguage/API|完整文件]]或[[Special:ApiHelp/main|API幫助]]以取得更多資訊。",
+       "api-format-prettyprint-header-hyperlinked": "這是$1格式的HTML實現。HTML對除錯很有用,但不適合應用程式使用。\n\n指定<var>format</var>參數以更改輸出格式。要查看$1格式的非HTML實現,設置[$3 <kbd>format=$2</kbd>]。\n\n參見[[mw:API|完整文件]],或[[Special:ApiHelp/main|API幫助]]以獲取更多信息。",
        "api-format-prettyprint-status": "此回應將會傳回HTTP狀態$1 $2。",
        "api-pageset-param-titles": "要使用的標題清單。",
        "api-pageset-param-pageids": "要使用的頁面 ID 清單。",
index f5bfc2a..3d26767 100644 (file)
@@ -113,7 +113,7 @@ abstract class AbstractPasswordPrimaryAuthenticationProvider
         *
         * @param string $username
         * @param Status $status From $this->checkPasswordValidity()
-        * @param mixed $data Passed through to $this->getPasswordResetData()
+        * @param mixed|null $data Passed through to $this->getPasswordResetData()
         */
        protected function setPasswordResetFlag( $username, Status $status, $data = null ) {
                $reset = $this->getPasswordResetData( $username, $data );
index 9ed6d13..d3fd5fc 100644 (file)
@@ -240,7 +240,7 @@ class AuthManager implements LoggerAwareInterface {
                global $wgAuth;
 
                if ( $wgAuth && !$wgAuth instanceof AuthManagerAuthPlugin ) {
-                       return call_user_func_array( [ $wgAuth, $method ], $params );
+                       return $wgAuth->$method( ...$params );
                } else {
                        return $return;
                }
@@ -771,7 +771,12 @@ class AuthManager implements LoggerAwareInterface {
                        $status = self::SEC_FAIL;
                }
 
-               $this->logger->info( __METHOD__ . ": $operation is $status" );
+               $this->logger->info( __METHOD__ . ": $operation is $status for '{user}'",
+                       [
+                               'user' => $session->getUser()->getName(),
+                               'clientip' => $this->getRequest()->getIP(),
+                       ]
+               );
 
                return $status;
        }
@@ -881,8 +886,11 @@ class AuthManager implements LoggerAwareInterface {
         * returned success.
         *
         * @param AuthenticationRequest $req
+        * @param bool $isAddition Set true if this represents an addition of
+        *  credentials rather than a change. The main difference is that additions
+        *  should not invalidate BotPasswords. If you're not sure, leave it false.
         */
-       public function changeAuthenticationData( AuthenticationRequest $req ) {
+       public function changeAuthenticationData( AuthenticationRequest $req, $isAddition = false ) {
                $this->logger->info( 'Changing authentication data for {user} class {what}', [
                        'user' => is_string( $req->username ) ? $req->username : '<no name>',
                        'what' => get_class( $req ),
@@ -892,7 +900,9 @@ class AuthManager implements LoggerAwareInterface {
 
                // When the main account's authentication data is changed, invalidate
                // all BotPasswords too.
-               \BotPassword::invalidateAllPasswordsForUser( $req->username );
+               if ( !$isAddition ) {
+                       \BotPassword::invalidateAllPasswordsForUser( $req->username );
+               }
        }
 
        /**@}*/
@@ -985,7 +995,7 @@ class AuthManager implements LoggerAwareInterface {
                if ( $permErrors ) {
                        $status = Status::newGood();
                        foreach ( $permErrors as $args ) {
-                               call_user_func_array( [ $status, 'fatal' ], $args );
+                               $status->fatal( ...$args );
                        }
                        return $status;
                }
@@ -1675,7 +1685,7 @@ class AuthManager implements LoggerAwareInterface {
                }
 
                // Checks passed, create the user...
-               $from = isset( $_SERVER['REQUEST_URI'] ) ? $_SERVER['REQUEST_URI'] : 'CLI';
+               $from = $_SERVER['REQUEST_URI'] ?? 'CLI';
                $this->logger->info( __METHOD__ . ': creating new user ({username}) - from: {from}', [
                        'username' => $username,
                        'from' => $from,
@@ -2244,7 +2254,7 @@ class AuthManager implements LoggerAwareInterface {
         * Fetch authentication data from the current session
         * @protected For use by AuthenticationProviders
         * @param string $key
-        * @param mixed $default
+        * @param mixed|null $default
         * @return mixed
         */
        public function getAuthenticationSessionData( $key, $default = null ) {
@@ -2286,9 +2296,10 @@ class AuthManager implements LoggerAwareInterface {
                        $spec = [ 'sort2' => $i++ ] + $spec + [ 'sort' => 0 ];
                }
                unset( $spec );
+               // Sort according to the 'sort' field, and if they are equal, according to 'sort2'
                usort( $specs, function ( $a, $b ) {
-                       return ( (int)$a['sort'] ) - ( (int)$b['sort'] )
-                               ?: $a['sort2'] - $b['sort2'];
+                       return $a['sort'] <=> $b['sort']
+                               ?: $a['sort2'] <=> $b['sort2'];
                } );
 
                $ret = [];
@@ -2426,7 +2437,7 @@ class AuthManager implements LoggerAwareInterface {
                        $providers += $this->getSecondaryAuthenticationProviders();
                }
                foreach ( $providers as $provider ) {
-                       call_user_func_array( [ $provider, $method ], $args );
+                       $provider->$method( ...$args );
                }
        }
 
index 956c985..8cb33aa 100644 (file)
@@ -199,7 +199,7 @@ class AuthenticationResponse {
        /**
         * @param AuthenticationRequest[] $reqs AuthenticationRequests needed to continue
         * @param string $redirectTarget URL
-        * @param mixed $redirectApiData Data suitable for adding to an ApiResult
+        * @param mixed|null $redirectApiData Data suitable for adding to an ApiResult
         * @return AuthenticationResponse
         * @see AuthenticationResponse::REDIRECT
         */
index d274e18..1268e68 100644 (file)
@@ -90,14 +90,14 @@ class ButtonAuthenticationRequest extends AuthenticationRequest {
                } elseif ( is_string( $data['label'] ) ) {
                        $data['label'] = new \Message( $data['label'] );
                } elseif ( is_array( $data['label'] ) ) {
-                       $data['label'] = call_user_func_array( 'Message::newFromKey', $data['label'] );
+                       $data['label'] = Message::newFromKey( ...$data['label'] );
                }
                if ( !isset( $data['help'] ) ) {
                        $data['help'] = new \RawMessage( '$1', $data['name'] );
                } elseif ( is_string( $data['help'] ) ) {
                        $data['help'] = new \Message( $data['help'] );
                } elseif ( is_array( $data['help'] ) ) {
-                       $data['help'] = call_user_func_array( 'Message::newFromKey', $data['help'] );
+                       $data['help'] = Message::newFromKey( ...$data['help'] );
                }
                $ret = new static( $data['name'], $data['label'], $data['help'] );
                foreach ( $data as $k => $v ) {
index 7f121cd..c2d730c 100644 (file)
@@ -119,7 +119,9 @@ class ConfirmLinkSecondaryAuthenticationProvider extends AbstractSecondaryAuthen
                                $status = $this->manager->allowsAuthenticationDataChange( $req );
                                $statuses[] = [ $req, $status ];
                                if ( $status->isGood() ) {
-                                       $this->manager->changeAuthenticationData( $req );
+                                       // We're not changing credentials, just adding a new link
+                                       // to an already-known user.
+                                       $this->manager->changeAuthenticationData( $req, /* $isAddition */ true );
                                } else {
                                        $anyFailed = true;
                                }
index 95fe3ab..e8a276c 100644 (file)
@@ -168,7 +168,7 @@ class LegacyHookPreAuthenticationProvider extends AbstractPreAuthenticationProvi
 
                        case LoginForm::USER_MIGRATED:
                                $error = $msg ?: 'login-migrated-generic';
-                               return call_user_func_array( 'StatusValue::newFatal', (array)$error );
+                               return StatusValue::newFatal( ...(array)$error );
 
                        // @codeCoverageIgnoreStart
                        case LoginForm::CREATE_BLOCKED: // Can never happen
index 45ac3aa..c831fc8 100644 (file)
@@ -96,7 +96,7 @@ class ResetPasswordSecondaryAuthenticationProvider extends AbstractSecondaryAuth
                        }
                }
 
-               $needReq = isset( $data->req ) ? $data->req : new PasswordAuthenticationRequest();
+               $needReq = $data->req ?? new PasswordAuthenticationRequest();
                if ( !$needReq->action ) {
                        $needReq->action = AuthManager::ACTION_CHANGE;
                }
index ae0bc6b..83d67ea 100644 (file)
@@ -58,8 +58,7 @@ class ThrottlePreAuthenticationProvider extends AbstractPreAuthenticationProvide
        public function __construct( $params = [] ) {
                $this->throttleSettings = array_intersect_key( $params,
                        [ 'accountCreationThrottle' => true, 'passwordAttemptThrottle' => true ] );
-               $this->cache = isset( $params['cache'] ) ? $params['cache'] :
-                       \ObjectCache::getLocalClusterInstance();
+               $this->cache = $params['cache'] ?? \ObjectCache::getLocalClusterInstance();
        }
 
        public function setConfig( Config $config ) {
index 3125bd3..e6d9bd8 100644 (file)
@@ -52,7 +52,7 @@ class Throttler implements LoggerAwareInterface {
        protected $warningLimit;
 
        /**
-        * @param array $conditions An array of arrays describing throttling conditions.
+        * @param array|null $conditions An array of arrays describing throttling conditions.
         *     Defaults to $wgPasswordAttemptThrottle. See documentation of that variable for format.
         * @param array $params Parameters (all optional):
         *   - type: throttle type, used as a namespace for counters,
@@ -138,7 +138,7 @@ class Throttler implements LoggerAwareInterface {
                                $this->logRejection( [
                                        'throttle' => $this->type,
                                        'index' => $index,
-                                       'ip' => $ipKey,
+                                       'ipKey' => $ipKey,
                                        'username' => $username,
                                        'count' => $count,
                                        'expiry' => $expiry,
@@ -193,7 +193,7 @@ class Throttler implements LoggerAwareInterface {
 
        protected function logRejection( array $context ) {
                $logMsg = 'Throttle {throttle} hit, throttled for {expiry} seconds due to {count} attempts '
-                       . 'from username {username} and IP {ip}';
+                       . 'from username {username} and IP {ipKey}';
 
                // If we are hitting a throttle for >= warningLimit attempts, it is much more likely to be
                // an attack than someone simply forgetting their password, so log it at a higher level.
index 4ff1004..11df5bc 100644 (file)
@@ -118,7 +118,7 @@ class DependencyWrapper {
                if ( is_object( $obj ) && $obj instanceof DependencyWrapper && !$obj->isExpired() ) {
                        $value = $obj->value;
                } elseif ( $callback ) {
-                       $value = call_user_func_array( $callback, $callbackParams );
+                       $value = $callback( ...$callbackParams );
                        # Cache the newly-generated value
                        $wrapper = new DependencyWrapper( $value, $deps );
                        $wrapper->storeToCache( $cache, $key, $expiry );
index e77e251..6c6b184 100644 (file)
@@ -18,7 +18,7 @@
  * http://www.gnu.org/copyleft/gpl.html
  *
  * @file
- * @license GNU GPL v2 or later
+ * @license GPL-2.0-or-later
  * @author Jeroen De Dauw < jeroendedauw@gmail.com >
  */
 
@@ -294,7 +294,7 @@ class CacheHelper implements ICacheHelper {
                                $args = [ $args ];
                        }
 
-                       $value = call_user_func_array( $computeFunction, $args );
+                       $value = $computeFunction( ...$args );
 
                        if ( $this->cacheEnabled ) {
                                if ( is_null( $key ) ) {
@@ -350,7 +350,7 @@ class CacheHelper implements ICacheHelper {
                        throw new MWException( 'No cache key set, so cannot obtain or save the CacheHelper values.' );
                }
 
-               return call_user_func_array( 'wfMemcKey', $this->cacheKey );
+               return wfMemcKey( ...array_values( $this->cacheKey ) );
        }
 
        /**
index 099a986..7228814 100644 (file)
@@ -85,7 +85,7 @@ class GenderCache {
                /* Undefined if there is a valid username which for some reason doesn't
                 * exist in the database.
                 */
-               return isset( $this->cache[$username] ) ? $this->cache[$username] : $this->getDefault();
+               return $this->cache[$username] ?? $this->getDefault();
        }
 
        /**
@@ -171,7 +171,7 @@ class GenderCache {
                $res = $dbr->select( $table, $fields, $conds, $comment, [], $joins );
 
                foreach ( $res as $row ) {
-                       $this->cache[$row->user_name] = $row->up_value ? $row->up_value : $default;
+                       $this->cache[$row->user_name] = $row->up_value ?: $default;
                }
        }
 
index 7ae2ee0..f8cd754 100644 (file)
@@ -91,6 +91,7 @@ class HTMLFileCache extends FileCacheBase {
         * @return bool
         */
        public static function useFileCache( IContextSource $context, $mode = self::MODE_NORMAL ) {
+               global $wgContLang;
                $config = MediaWikiServices::getInstance()->getMainConfig();
 
                if ( !$config->get( 'UseFileCache' ) && $mode !== self::MODE_REBUILD ) {
@@ -123,7 +124,7 @@ class HTMLFileCache extends FileCacheBase {
                $ulang = $context->getLanguage();
 
                // Check that there are no other sources of variation
-               if ( $user->getId() || $ulang->getCode() !== $config->get( 'LanguageCode' ) ) {
+               if ( $user->getId() || !$ulang->equals( $wgContLang ) ) {
                        return false;
                }
 
index 2d08895..260038a 100644 (file)
@@ -32,10 +32,10 @@ use MediaWiki\MediaWikiServices;
  * @ingroup Cache
  */
 class LinkCache {
-       /** @var HashBagOStuff */
-       private $mGoodLinks;
-       /** @var HashBagOStuff */
-       private $mBadLinks;
+       /** @var MapCacheLRU */
+       private $goodLinks;
+       /** @var MapCacheLRU */
+       private $badLinks;
        /** @var WANObjectCache */
        private $wanCache;
 
@@ -52,8 +52,8 @@ class LinkCache {
        const MAX_SIZE = 10000;
 
        public function __construct( TitleFormatter $titleFormatter, WANObjectCache $cache ) {
-               $this->mGoodLinks = new HashBagOStuff( [ 'maxKeys' => self::MAX_SIZE ] );
-               $this->mBadLinks = new HashBagOStuff( [ 'maxKeys' => self::MAX_SIZE ] );
+               $this->goodLinks = new MapCacheLRU( self::MAX_SIZE );
+               $this->badLinks = new MapCacheLRU( self::MAX_SIZE );
                $this->wanCache = $cache;
                $this->titleFormatter = $titleFormatter;
        }
@@ -75,7 +75,7 @@ class LinkCache {
         * in order to avoid link table inconsistency), which was later removed
         * for performance on wikis with a high edit rate.
         *
-        * @param bool $update
+        * @param bool|null $update
         * @return bool
         */
        public function forUpdate( $update = null ) {
@@ -87,7 +87,7 @@ class LinkCache {
         * @return int Page ID or zero
         */
        public function getGoodLinkID( $title ) {
-               $info = $this->mGoodLinks->get( $title );
+               $info = $this->goodLinks->get( $title );
                if ( !$info ) {
                        return 0;
                }
@@ -103,7 +103,7 @@ class LinkCache {
         */
        public function getGoodLinkFieldObj( LinkTarget $target, $field ) {
                $dbkey = $this->titleFormatter->getPrefixedDBkey( $target );
-               $info = $this->mGoodLinks->get( $dbkey );
+               $info = $this->goodLinks->get( $dbkey );
                if ( !$info ) {
                        return null;
                }
@@ -116,7 +116,7 @@ class LinkCache {
         */
        public function isBadLink( $title ) {
                // Use get() to ensure it records as used for LRU.
-               return $this->mBadLinks->get( $title ) !== false;
+               return $this->badLinks->has( $title );
        }
 
        /**
@@ -125,7 +125,7 @@ class LinkCache {
         * @param int $id Page's ID
         * @param LinkTarget $target
         * @param int $len Text's length
-        * @param int $redir Whether the page is a redirect
+        * @param int|null $redir Whether the page is a redirect
         * @param int $revision Latest revision's ID
         * @param string|null $model Latest revision's content model ID
         * @param string|null $lang Language code of the page, if not the content language
@@ -134,7 +134,7 @@ class LinkCache {
                $revision = 0, $model = null, $lang = null
        ) {
                $dbkey = $this->titleFormatter->getPrefixedDBkey( $target );
-               $this->mGoodLinks->set( $dbkey, [
+               $this->goodLinks->set( $dbkey, [
                        'id' => (int)$id,
                        'length' => (int)$len,
                        'redirect' => (int)$redir,
@@ -153,7 +153,7 @@ class LinkCache {
         */
        public function addGoodLinkObjFromRow( LinkTarget $target, $row ) {
                $dbkey = $this->titleFormatter->getPrefixedDBkey( $target );
-               $this->mGoodLinks->set( $dbkey, [
+               $this->goodLinks->set( $dbkey, [
                        'id' => intval( $row->page_id ),
                        'length' => intval( $row->page_len ),
                        'redirect' => intval( $row->page_is_redirect ),
@@ -169,7 +169,7 @@ class LinkCache {
        public function addBadLinkObj( LinkTarget $target ) {
                $dbkey = $this->titleFormatter->getPrefixedDBkey( $target );
                if ( !$this->isBadLink( $dbkey ) ) {
-                       $this->mBadLinks->set( $dbkey, 1 );
+                       $this->badLinks->set( $dbkey, 1 );
                }
        }
 
@@ -177,7 +177,7 @@ class LinkCache {
         * @param string $title Prefixed DB key
         */
        public function clearBadLink( $title ) {
-               $this->mBadLinks->delete( $title );
+               $this->badLinks->clear( $title );
        }
 
        /**
@@ -185,8 +185,8 @@ class LinkCache {
         */
        public function clearLink( LinkTarget $target ) {
                $dbkey = $this->titleFormatter->getPrefixedDBkey( $target );
-               $this->mBadLinks->delete( $dbkey );
-               $this->mGoodLinks->delete( $dbkey );
+               $this->badLinks->clear( $dbkey );
+               $this->goodLinks->clear( $dbkey );
        }
 
        /**
@@ -321,7 +321,7 @@ class LinkCache {
         */
        public function invalidateTitle( LinkTarget $title ) {
                if ( $this->isCacheable( $title ) ) {
-                       $cache = ObjectCache::getMainWANInstance();
+                       $cache = $this->wanCache;
                        $cache->delete(
                                $cache->makeKey( 'page', $title->getNamespace(), sha1( $title->getDBkey() ) )
                        );
@@ -332,7 +332,7 @@ class LinkCache {
         * Clears cache
         */
        public function clear() {
-               $this->mGoodLinks->clear();
-               $this->mBadLinks->clear();
+               $this->goodLinks->clear();
+               $this->badLinks->clear();
        }
 }
index b262eab..65e659d 100644 (file)
@@ -50,8 +50,8 @@ class MessageBlobStore implements LoggerAwareInterface {
        protected $wanCache;
 
        /**
-        * @param ResourceLoader $rl
-        * @param LoggerInterface $logger
+        * @param ResourceLoader|null $rl
+        * @param LoggerInterface|null $logger
         */
        public function __construct( ResourceLoader $rl = null, LoggerInterface $logger = null ) {
                $this->resourceloader = $rl;
index 71fcd8b..7a172be 100644 (file)
@@ -32,7 +32,8 @@ use Wikimedia\Rdbms\Database;
 define( 'MSG_CACHE_VERSION', 2 );
 
 /**
- * Message cache
+ * Cache of messages that are defined by MediaWiki namespace pages or by hooks
+ *
  * Performs various MediaWiki namespace-related functions
  * @ingroup Cache
  */
@@ -45,19 +46,16 @@ class MessageCache {
        const LOCK_TTL = 30;
 
        /**
-        * Process local cache of loaded messages that are defined in
-        * MediaWiki namespace. First array level is a language code,
-        * second level is message key and the values are either message
-        * content prefixed with space, or !NONEXISTENT for negative
-        * caching.
-        * @var array $mCache
+        * Process cache of loaded messages that are defined in MediaWiki namespace
+        *
+        * @var MapCacheLRU Map of (language code => key => " <MESSAGE>" or "!TOO BIG")
         */
-       protected $mCache;
+       protected $cache;
 
        /**
         * @var bool[] Map of (language code => boolean)
         */
-       protected $mCacheVolatile = [];
+       protected $cacheVolatile = [];
 
        /**
         * Should mean that database cannot be used, but check
@@ -79,12 +77,6 @@ class MessageCache {
        /** @var Parser */
        protected $mParser;
 
-       /**
-        * Variable for tracking which variables are already loaded
-        * @var array $mLoadedLanguages
-        */
-       protected $mLoadedLanguages = [];
-
        /**
         * @var bool $mInParser
         */
@@ -173,6 +165,8 @@ class MessageCache {
                $this->clusterCache = $clusterCache;
                $this->srvCache = $serverCache;
 
+               $this->cache = new MapCacheLRU( 5 ); // limit size for sanity
+
                $this->mDisable = !$useDB;
                $this->mExpiry = $expiry;
        }
@@ -245,8 +239,8 @@ class MessageCache {
         * is disabled.
         *
         * @param string $code Language to which load messages
-        * @param int $mode Use MessageCache::FOR_UPDATE to skip process cache [optional]
-        * @throws MWException
+        * @param int|null $mode Use MessageCache::FOR_UPDATE to skip process cache [optional]
+        * @throws InvalidArgumentException
         * @return bool
         */
        protected function load( $code, $mode = null ) {
@@ -255,7 +249,7 @@ class MessageCache {
                }
 
                # Don't do double loading...
-               if ( isset( $this->mLoadedLanguages[$code] ) && $mode != self::FOR_UPDATE ) {
+               if ( $this->cache->has( $code ) && $mode != self::FOR_UPDATE ) {
                        return true;
                }
 
@@ -278,7 +272,7 @@ class MessageCache {
                # Hash of the contents is stored in memcache, to detect if data-center cache
                # or local cache goes out of date (e.g. due to replace() on some other server)
                list( $hash, $hashVolatile ) = $this->getValidationHash( $code );
-               $this->mCacheVolatile[$code] = $hashVolatile;
+               $this->cacheVolatile[$code] = $hashVolatile;
 
                # Try the local cache and check against the cluster hash key...
                $cache = $this->getLocalCache( $code );
@@ -295,8 +289,8 @@ class MessageCache {
                        $staleCache = $cache;
                } else {
                        $where[] = 'got from local cache';
+                       $this->cache->set( $code, $cache );
                        $success = true;
-                       $this->mCache[$code] = $cache;
                }
 
                if ( !$success ) {
@@ -325,7 +319,7 @@ class MessageCache {
                                                $staleCache = $cache;
                                        } else {
                                                $where[] = 'got from global cache';
-                                               $this->mCache[$code] = $cache;
+                                               $this->cache->set( $code, $cache );
                                                $this->saveToCaches( $cache, 'local-only', $code );
                                                $success = true;
                                        }
@@ -346,7 +340,7 @@ class MessageCache {
                                } elseif ( $staleCache ) {
                                        # Use the stale cache while some other thread constructs the new one
                                        $where[] = 'using stale cache';
-                                       $this->mCache[$code] = $staleCache;
+                                       $this->cache->set( $code, $staleCache );
                                        $success = true;
                                        break;
                                } elseif ( $failedAttempts > 0 ) {
@@ -370,13 +364,14 @@ class MessageCache {
                if ( !$success ) {
                        $where[] = 'loading FAILED - cache is disabled';
                        $this->mDisable = true;
-                       $this->mCache = false;
+                       $this->cache->set( $code, null );
                        wfDebugLog( 'MessageCacheError', __METHOD__ . ": Failed to load $code\n" );
                        # This used to throw an exception, but that led to nasty side effects like
                        # the whole wiki being instantly down if the memcached server died
-               } else {
-                       # All good, just record the success
-                       $this->mLoadedLanguages[$code] = true;
+               }
+
+               if ( !$this->cache->has( $code ) ) { // sanity
+                       throw new LogicException( "Process cache for '$code' should be set by now." );
                }
 
                $info = implode( ', ', $where );
@@ -388,7 +383,7 @@ class MessageCache {
        /**
         * @param string $code
         * @param array &$where List of wfDebug() comments
-        * @param int $mode Use MessageCache::FOR_UPDATE to use DB_MASTER
+        * @param int|null $mode Use MessageCache::FOR_UPDATE to use DB_MASTER
         * @return bool|string True on success or one of ("cantacquire", "disabled")
         */
        protected function loadFromDBWithLock( $code, array &$where, $mode = null ) {
@@ -416,7 +411,7 @@ class MessageCache {
                }
 
                $cache = $this->loadFromDB( $code, $mode );
-               $this->mCache[$code] = $cache;
+               $this->cache->set( $code, $cache );
                $saveSuccess = $this->saveToCaches( $cache, 'all', $code );
 
                if ( !$saveSuccess ) {
@@ -450,7 +445,7 @@ class MessageCache {
         * on-demand from the database later.
         *
         * @param string $code Language code
-        * @param int $mode Use MessageCache::FOR_UPDATE to skip process cache
+        * @param int|null $mode Use MessageCache::FOR_UPDATE to skip process cache
         * @return array Loaded messages for storing in caches
         */
        protected function loadFromDB( $code, $mode = null ) {
@@ -472,10 +467,10 @@ class MessageCache {
 
                $mostused = [];
                if ( $wgAdaptiveMessageCache && $code !== $wgLanguageCode ) {
-                       if ( !isset( $this->mCache[$wgLanguageCode] ) ) {
+                       if ( !$this->cache->has( $wgLanguageCode ) ) {
                                $this->load( $wgLanguageCode );
                        }
-                       $mostused = array_keys( $this->mCache[$wgLanguageCode] );
+                       $mostused = array_keys( $this->cache->get( $wgLanguageCode ) );
                        foreach ( $mostused as $key => $value ) {
                                $mostused[$key] = "$value/$code";
                        }
@@ -577,10 +572,10 @@ class MessageCache {
                // (a) Update the process cache with the new message text
                if ( $text === false ) {
                        // Page deleted
-                       $this->mCache[$code][$title] = '!NONEXISTENT';
+                       $this->cache->setField( $code, $title, '!NONEXISTENT' );
                } else {
                        // Ignore $wgMaxMsgCacheEntrySize so the process cache is up to date
-                       $this->mCache[$code][$title] = ' ' . $text;
+                       $this->cache->setField( $code, $title, ' ' . $text );
                }
 
                // (b) Update the shared caches in a deferred update with a fresh DB snapshot
@@ -597,26 +592,31 @@ class MessageCache {
                                                [ 'title' => $title, 'code' => $code ] );
                                        return;
                                }
-                               // Load the messages from the master DB to avoid race conditions
+                               // Reload messages from the database and pre-populate dc-local caches
+                               // as optimisation. Use the master DB to avoid race conditions.
                                $cache = $this->loadFromDB( $code, self::FOR_UPDATE );
-                               $this->mCache[$code] = $cache;
-                               // Load the process cache values and set the per-title cache keys
+                               // Check if an individual cache key should exist and update cache accordingly
                                $page = WikiPage::factory( Title::makeTitle( NS_MEDIAWIKI, $title ) );
                                $page->loadPageData( $page::READ_LATEST );
                                $text = $this->getMessageTextFromContent( $page->getContent() );
-                               // Check if an individual cache key should exist and update cache accordingly
                                if ( is_string( $text ) && strlen( $text ) > $wgMaxMsgCacheEntrySize ) {
-                                       $titleKey = $this->bigMessageCacheKey( $this->mCache[$code]['HASH'], $title );
-                                       $this->wanCache->set( $titleKey, ' ' . $text, $this->mExpiry );
+                                       // Match logic of loadCachedMessagePageEntry()
+                                       $this->wanCache->set(
+                                               $this->bigMessageCacheKey( $cache['HASH'], $title ),
+                                               ' ' . $text,
+                                               $this->mExpiry
+                                       );
                                }
                                // Mark this cache as definitely being "latest" (non-volatile) so
-                               // load() calls do try to refresh the cache with replica DB data
-                               $this->mCache[$code]['LATEST'] = time();
+                               // load() calls do not try to refresh the cache with replica DB data
+                               $cache['LATEST'] = time();
+                               // Update the process cache
+                               $this->cache->set( $code, $cache );
                                // Pre-emptively update the local datacenter cache so things like edit filter and
                                // blacklist changes are reflected immediately; these often use MediaWiki: pages.
                                // The datacenter handling replace() calls should be the same one handling edits
                                // as they require HTTP POST.
-                               $this->saveToCaches( $this->mCache[$code], 'all', $code );
+                               $this->saveToCaches( $cache, 'all', $code );
                                // Release the lock now that the cache is saved
                                ScopedCallback::consume( $scopedLock );
 
@@ -727,7 +727,7 @@ class MessageCache {
                        $this->wanCache->makeKey( 'messages', $code, 'hash', 'v1' ),
                        [
                                'hash' => $cache['HASH'],
-                               'latest' => isset( $cache['LATEST'] ) ? $cache['LATEST'] : 0
+                               'latest' => $cache['LATEST'] ?? 0
                        ],
                        WANObjectCache::TTL_INDEFINITE
                );
@@ -836,9 +836,9 @@ class MessageCache {
                                ],
                                [
                                        ' ',
-                                       "\xc2\xa0",
-                                       "\xc2\xa0",
-                                       "\xc2\xad"
+                                       "\u{00A0}",
+                                       "\u{00A0}",
+                                       "\u{00AD}"
                                ],
                                $message
                        );
@@ -968,10 +968,13 @@ class MessageCache {
         * @return string|bool The message, or false if it does not exist or on error
         */
        public function getMsgFromNamespace( $title, $code ) {
+               // Load all MediaWiki page definitions into cache. Note that individual keys
+               // already loaded into cache during this request remain in the cache, which
+               // includes the value of hook-defined messages.
                $this->load( $code );
 
-               if ( isset( $this->mCache[$code][$title] ) ) {
-                       $entry = $this->mCache[$code][$title];
+               $entry = $this->cache->getField( $code, $title );
+               if ( $entry !== null ) {
                        if ( substr( $entry, 0, 1 ) === ' ' ) {
                                // The message exists and is not '!TOO BIG'
                                return (string)substr( $entry, 1 );
@@ -980,92 +983,101 @@ class MessageCache {
                        }
                        // Fall through and try invididual message cache below
                } else {
-                       // XXX: This is not cached in process cache, should it?
+                       // Message does not have a MediaWiki page definition
                        $message = false;
                        Hooks::run( 'MessagesPreLoad', [ $title, &$message, $code ] );
                        if ( $message !== false ) {
-                               return $message;
+                               $this->cache->setField( $code, $title, ' ' . $message );
+                       } else {
+                               $this->cache->setField( $code, $title, '!NONEXISTENT' );
                        }
 
-                       return false;
+                       return $message;
                }
 
-               // Individual message cache key
-               $titleKey = $this->bigMessageCacheKey( $this->mCache[$code]['HASH'], $title );
-
-               if ( $this->mCacheVolatile[$code] ) {
+               if ( $this->cacheVolatile[$code] ) {
                        $entry = false;
                        // Make sure that individual keys respect the WAN cache holdoff period too
                        LoggerFactory::getInstance( 'MessageCache' )->debug(
                                __METHOD__ . ': loading volatile key \'{titleKey}\'',
-                               [ 'titleKey' => $titleKey, 'code' => $code ] );
+                               [ 'titleKey' => $title, 'code' => $code ] );
                } else {
                        // Try the individual message cache
-                       $entry = $this->wanCache->get( $titleKey );
-               }
-
-               if ( $entry !== false ) {
-                       if ( substr( $entry, 0, 1 ) === ' ' ) {
-                               $this->mCache[$code][$title] = $entry;
-                               // The message exists, so make sure a string is returned
-                               return (string)substr( $entry, 1 );
-                       } elseif ( $entry === '!NONEXISTENT' ) {
-                               $this->mCache[$code][$title] = '!NONEXISTENT';
-
-                               return false;
-                       } else {
-                               // Corrupt/obsolete entry, delete it
-                               $this->wanCache->delete( $titleKey );
-                       }
-               }
-
-               // Try loading the message from the database
-               $dbr = wfGetDB( DB_REPLICA );
-               $cacheOpts = Database::getCacheSetOptions( $dbr );
-               // Use newKnownCurrent() to avoid querying revision/user tables
-               $titleObj = Title::makeTitle( NS_MEDIAWIKI, $title );
-               if ( $titleObj->getLatestRevID() ) {
-                       $revision = Revision::newKnownCurrent(
-                               $dbr,
-                               $titleObj
+                       $entry = $this->loadCachedMessagePageEntry(
+                               $title,
+                               $code,
+                               $this->cache->getField( $code, 'HASH' )
                        );
-               } else {
-                       $revision = false;
                }
 
-               if ( $revision ) {
-                       $content = $revision->getContent();
-                       if ( $content ) {
-                               $message = $this->getMessageTextFromContent( $content );
-                               if ( is_string( $message ) ) {
-                                       $this->mCache[$code][$title] = ' ' . $message;
-                                       $this->wanCache->set( $titleKey, ' ' . $message, $this->mExpiry, $cacheOpts );
-                               }
-                       } else {
-                               // A possibly temporary loading failure
-                               LoggerFactory::getInstance( 'MessageCache' )->warning(
-                                       __METHOD__ . ': failed to load message page text for \'{titleKey}\'',
-                                       [ 'titleKey' => $titleKey, 'code' => $code ] );
-                               $message = null; // no negative caching
-                       }
-               } else {
-                       $message = false; // negative caching
+               if ( $entry !== false && substr( $entry, 0, 1 ) === ' ' ) {
+                       $this->cache->setField( $code, $title, $entry );
+                       // The message exists, so make sure a string is returned
+                       return (string)substr( $entry, 1 );
                }
 
-               if ( $message === false ) {
-                       // Negative caching in case a "too big" message is no longer available (deleted)
-                       $this->mCache[$code][$title] = '!NONEXISTENT';
-                       $this->wanCache->set( $titleKey, '!NONEXISTENT', $this->mExpiry, $cacheOpts );
-               }
+               $this->cache->setField( $code, $title, '!NONEXISTENT' );
 
-               return $message;
+               return false;
+       }
+
+       /**
+        * @param string $dbKey
+        * @param string $code
+        * @param string $hash
+        * @return string Either " <MESSAGE>" or "!NONEXISTANT"
+        */
+       private function loadCachedMessagePageEntry( $dbKey, $code, $hash ) {
+               return $this->srvCache->getWithSetCallback(
+                       $this->srvCache->makeKey( 'messages-big', $hash, $dbKey ),
+                       IExpiringStore::TTL_MINUTE,
+                       function () use ( $code, $dbKey, $hash ) {
+                               return $this->wanCache->getWithSetCallback(
+                                       $this->bigMessageCacheKey( $hash, $dbKey ),
+                                       $this->mExpiry,
+                                       function ( $oldValue, &$ttl, &$setOpts ) use ( $dbKey, $code ) {
+                                               // Try loading the message from the database
+                                               $dbr = wfGetDB( DB_REPLICA );
+                                               $setOpts += Database::getCacheSetOptions( $dbr );
+                                               // Use newKnownCurrent() to avoid querying revision/user tables
+                                               $title = Title::makeTitle( NS_MEDIAWIKI, $dbKey );
+                                               $revision = Revision::newKnownCurrent( $dbr, $title );
+                                               if ( !$revision ) {
+                                                       // The wiki doesn't have a local override page. Cache absence with normal TTL.
+                                                       // When overrides are created, self::replace() takes care of the cache.
+                                                       return '!NONEXISTENT';
+                                               }
+                                               $content = $revision->getContent();
+                                               if ( $content ) {
+                                                       $message = $this->getMessageTextFromContent( $content );
+                                               } else {
+                                                       LoggerFactory::getInstance( 'MessageCache' )->warning(
+                                                               __METHOD__ . ': failed to load page text for \'{titleKey}\'',
+                                                               [ 'titleKey' => $dbKey, 'code' => $code ]
+                                                       );
+                                                       $message = null;
+                                               }
+
+                                               if ( !is_string( $message ) ) {
+                                                       // Revision failed to load Content, or Content is incompatible with wikitext.
+                                                       // Possibly a temporary loading failure.
+                                                       $ttl = 5;
+
+                                                       return '!NONEXISTENT';
+                                               }
+
+                                               return ' ' . $message;
+                                       }
+                               );
+                       }
+               );
        }
 
        /**
         * @param string $message
         * @param bool $interface
-        * @param Language $language
-        * @param Title $title
+        * @param Language|null $language
+        * @param Title|null $title
         * @return string
         */
        public function transform( $message, $interface = false, $language = null, $title = null ) {
@@ -1118,10 +1130,10 @@ class MessageCache {
 
        /**
         * @param string $text
-        * @param Title $title
+        * @param Title|null $title
         * @param bool $linestart Whether or not this is at the start of a line
         * @param bool $interface Whether this is an interface message
-        * @param Language|string $language Language code
+        * @param Language|string|null $language Language code
         * @return ParserOutput|string
         */
        public function parse( $text, $title = null, $linestart = true,
@@ -1190,13 +1202,12 @@ class MessageCache {
         *
         * Mainly used after a mass rebuild
         */
-       function clear() {
+       public function clear() {
                $langs = Language::fetchLanguageNames( null, 'mw' );
                foreach ( array_keys( $langs ) as $code ) {
                        $this->wanCache->touchCheckKey( $this->getCheckKey( $code ) );
                }
-
-               $this->mLoadedLanguages = [];
+               $this->cache->clear();
        }
 
        /**
@@ -1233,12 +1244,12 @@ class MessageCache {
                global $wgContLang;
 
                $this->load( $code );
-               if ( !isset( $this->mCache[$code] ) ) {
+               if ( !$this->cache->has( $code ) ) {
                        // Apparently load() failed
                        return null;
                }
                // Remove administrative keys
-               $cache = $this->mCache[$code];
+               $cache = $this->cache->get( $code );
                unset( $cache['VERSION'] );
                unset( $cache['EXPIRY'] );
                unset( $cache['EXCESSIVE'] );
index cb68571..2828b9a 100644 (file)
@@ -56,9 +56,7 @@ class UserCache {
                        $this->doQuery( [ $userId ] ); // cache miss
                }
 
-               return isset( $this->cache[$userId][$prop] )
-                       ? $this->cache[$userId][$prop]
-                       : false; // user does not exist?
+               return $this->cache[$userId][$prop] ?? false; // user does not exist?
        }
 
        /**
index 602c0ac..38700b8 100644 (file)
@@ -47,6 +47,13 @@ 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}\"" );
+                       }
+               }
+
                $this->currentLang = $code;
                $this->fname = $this->directory . '/' . $code . '.l10n.php';
                $this->data[$code] = [];
index dd9e8e1..9e2a2fd 100644 (file)
@@ -292,11 +292,7 @@ class LocalisationCache {
                        $this->loadSubitem( $code, $key, $subkey );
                }
 
-               if ( isset( $this->data[$code][$key][$subkey] ) ) {
-                       return $this->data[$code][$key][$subkey];
-               } else {
-                       return null;
-               }
+               return $this->data[$code][$key][$subkey] ?? null;
        }
 
        /**
@@ -528,7 +524,12 @@ class LocalisationCache {
                Wikimedia\restoreWarnings();
 
                if ( $_fileType == 'core' || $_fileType == 'extension' ) {
+
+                       // Lnguage files aren't required to contain all the possible variables, so suppress warnings
+                       // when variables don't exist in tests
+                       Wikimedia\suppressWarnings();
                        $data = compact( self::$allKeys );
+                       Wikimedia\restoreWarnings();
                } elseif ( $_fileType == 'aliases' ) {
                        $data = compact( 'aliases' );
                } else {
@@ -603,11 +604,7 @@ class LocalisationCache {
                if ( $this->pluralRules === null ) {
                        $this->loadPluralFiles();
                }
-               if ( !isset( $this->pluralRules[$code] ) ) {
-                       return null;
-               } else {
-                       return $this->pluralRules[$code];
-               }
+               return $this->pluralRules[$code] ?? null;
        }
 
        /**
@@ -621,11 +618,7 @@ class LocalisationCache {
                if ( $this->pluralRuleTypes === null ) {
                        $this->loadPluralFiles();
                }
-               if ( !isset( $this->pluralRuleTypes[$code] ) ) {
-                       return null;
-               } else {
-                       return $this->pluralRuleTypes[$code];
-               }
+               return $this->pluralRuleTypes[$code] ?? null;
        }
 
        /**
@@ -1047,11 +1040,7 @@ class LocalisationCache {
                }
 
                foreach ( $data['preloadedMessages'] as $subkey ) {
-                       if ( isset( $data['messages'][$subkey] ) ) {
-                               $subitem = $data['messages'][$subkey];
-                       } else {
-                               $subitem = null;
-                       }
+                       $subitem = $data['messages'][$subkey] ?? null;
                        $preload['messages'][$subkey] = $subitem;
                }
 
index f095b64..f1e61bb 100644 (file)
@@ -23,8 +23,6 @@
  * @since 1.27
  */
 
-use Wikimedia\Assert\Assert;
-
 class CategoryMembershipChange {
 
        const CATEGORY_ADDITION = 1;
@@ -59,7 +57,7 @@ class CategoryMembershipChange {
 
        /**
         * @param Title $pageTitle Title instance of the categorized page
-        * @param Revision $revision Latest Revision instance of the categorized page
+        * @param Revision|null $revision Latest Revision instance of the categorized page
         *
         * @throws MWException
         */
@@ -83,11 +81,10 @@ class CategoryMembershipChange {
         *
         * @throws MWException
         */
-       public function overrideNewForCategorizationCallback( $callback ) {
+       public function overrideNewForCategorizationCallback( callable $callback ) {
                if ( !defined( 'MW_PHPUNIT_TEST' ) ) {
                        throw new MWException( 'Cannot override newForCategorization callback in operation.' );
                }
-               Assert::parameterType( 'callable', $callback, '$callback' );
                $this->newForCategorizationCallback = $callback;
        }
 
@@ -142,7 +139,7 @@ class CategoryMembershipChange {
        /**
         * @param string $timestamp Timestamp of the recent change to occur in TS_MW format
         * @param Title $categoryTitle Title of the category a page is being added to or removed from
-        * @param User $user User object of the user that made the change
+        * @param User|null $user User object of the user that made the change
         * @param string $comment Change summary
         * @param Title $pageTitle Title of the page that is being added or removed
         * @param string $lastTimestamp Parent revision timestamp of this change in TS_MW format
@@ -187,22 +184,19 @@ class CategoryMembershipChange {
                }
 
                /** @var RecentChange $rc */
-               $rc = call_user_func_array(
-                       $this->newForCategorizationCallback,
-                       [
-                               $timestamp,
-                               $categoryTitle,
-                               $user,
-                               $comment,
-                               $pageTitle,
-                               $lastRevId,
-                               $newRevId,
-                               $lastTimestamp,
-                               $bot,
-                               $ip,
-                               $deleted,
-                               $added
-                       ]
+               $rc = ( $this->newForCategorizationCallback )(
+                       $timestamp,
+                       $categoryTitle,
+                       $user,
+                       $comment,
+                       $pageTitle,
+                       $lastRevId,
+                       $newRevId,
+                       $lastTimestamp,
+                       $bot,
+                       $ip,
+                       $deleted,
+                       $added
                );
                $rc->save();
        }
index ac029a2..eb9febe 100644 (file)
@@ -44,7 +44,7 @@ class ChangesList extends ContextSource {
        /** @var callable */
        protected $changeLinePrefixer;
 
-       /** @var BagOStuff */
+       /** @var MapCacheLRU */
        protected $watchMsgCache;
 
        /**
@@ -72,7 +72,7 @@ class ChangesList extends ContextSource {
                        $this->skin = $obj;
                }
                $this->preCacheMessages();
-               $this->watchMsgCache = new HashBagOStuff( [ 'maxKeys' => 50 ] );
+               $this->watchMsgCache = new MapCacheLRU( 50 );
                $this->linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer();
                $this->filterGroups = $filterGroups;
        }
@@ -107,7 +107,7 @@ class ChangesList extends ContextSource {
         *
         * @param RecentChange &$rc Passed by reference
         * @param bool $watched (default false)
-        * @param int $linenumber (default null)
+        * @param int|null $linenumber (default null)
         *
         * @return string|bool
         */
@@ -115,6 +115,31 @@ class ChangesList extends ContextSource {
                throw new RuntimeException( 'recentChangesLine should be implemented' );
        }
 
+       /**
+        * Get the container for highlights that are used in the new StructuredFilters
+        * system
+        *
+        * @return string HTML structure of the highlight container div
+        */
+       protected function getHighlightsContainerDiv() {
+               $highlightColorDivs = '';
+               foreach ( [ 'none', 'c1', 'c2', 'c3', 'c4', 'c5' ] as $color ) {
+                       $highlightColorDivs .= Html::rawElement(
+                               'div',
+                               [
+                                       'class' => 'mw-rcfilters-ui-highlights-color-' . $color,
+                                       'data-color' => $color
+                               ]
+                       );
+               }
+
+               return Html::rawElement(
+                       'div',
+                       [ 'class' => 'mw-rcfilters-ui-highlights' ],
+                       $highlightColorDivs
+               );
+       }
+
        /**
         * Sets the list to use a "<li class='watchlist-(namespace)-(page)'>" tag
         * @param bool $value
@@ -152,7 +177,7 @@ class ChangesList extends ContextSource {
         * @param string $nothing To use for empty space
         * @return string
         */
-       public function recentChangesFlags( $flags, $nothing = '&#160;' ) {
+       public function recentChangesFlags( $flags, $nothing = "\u{00A0}" ) {
                $f = '';
                foreach ( array_keys( $this->getConfig()->get( 'RecentChangesFlags' ) ) as $flag ) {
                        $f .= isset( $flags[$flag] ) && $flags[$flag]
@@ -183,8 +208,6 @@ class ChangesList extends ContextSource {
                        $classes[] = Sanitizer::escapeClass( self::CSS_CLASS_PREFIX . 'ns' .
                                $rc->mAttribs['rc_namespace'] . '-' . $rc->mAttribs['rc_title'] );
                }
-               $classes[] = Sanitizer::escapeClass( self::CSS_CLASS_PREFIX . 'ns-' .
-                       $rc->mAttribs['rc_namespace'] );
 
                // Indicate watched status on the line to allow for more
                // comprehensive styling.
@@ -198,7 +221,8 @@ class ChangesList extends ContextSource {
        }
 
        /**
-        * Get an array of CSS classes attributed to filters for this row
+        * Get an array of CSS classes attributed to filters for this row. Used for highlighting
+        * in the front-end.
         *
         * @param RecentChange $rc
         * @return array Array of CSS classes
@@ -206,6 +230,9 @@ class ChangesList extends ContextSource {
        protected function getHTMLClassesForFilters( $rc ) {
                $classes = [];
 
+               $classes[] = Sanitizer::escapeClass( self::CSS_CLASS_PREFIX . 'ns-' .
+                       $rc->mAttribs['rc_namespace'] );
+
                if ( $this->filterGroups !== null ) {
                        foreach ( $this->filterGroups as $filterGroup ) {
                                foreach ( $filterGroup->getFilters() as $filter ) {
@@ -222,7 +249,7 @@ class ChangesList extends ContextSource {
         * bot edit, or unpatrolled edit. In English it typically contains "N", "m", "b", or "!".
         *
         * @param string $flag One key of $wgRecentChangesFlags
-        * @param IContextSource $context
+        * @param IContextSource|null $context
         * @return string HTML
         */
        public static function flag( $flag, IContextSource $context = null ) {
@@ -236,7 +263,7 @@ class ChangesList extends ContextSource {
                                $flagInfos[$key]['letter'] = $value['letter'];
                                $flagInfos[$key]['title'] = $value['title'];
                                // Allow customized class name, fall back to flag name
-                               $flagInfos[$key]['class'] = isset( $value['class'] ) ? $value['class'] : $key;
+                               $flagInfos[$key]['class'] = $value['class'] ?? $key;
                        }
                }
 
@@ -283,7 +310,7 @@ class ChangesList extends ContextSource {
         *
         * @param int $old Number of bytes
         * @param int $new Number of bytes
-        * @param IContextSource $context
+        * @param IContextSource|null $context
         * @return string
         */
        public static function showCharacterDifference( $old, $new, IContextSource $context = null ) {
@@ -336,7 +363,7 @@ class ChangesList extends ContextSource {
         * Format the character difference of one or several changes.
         *
         * @param RecentChange $old
-        * @param RecentChange $new Last change to use, if not provided, $old will be used
+        * @param RecentChange|null $new Last change to use, if not provided, $old will be used
         * @return string HTML fragment
         */
        public function formatCharacterDifference( RecentChange $old, RecentChange $new = null ) {
@@ -575,10 +602,9 @@ class ChangesList extends ContextSource {
                if ( $count <= 0 ) {
                        return '';
                }
-               $cache = $this->watchMsgCache;
-               return $cache->getWithSetCallback(
-                       $cache->makeKey( 'watching-users-msg', $count ),
-                       $cache::TTL_INDEFINITE,
+
+               return $this->watchMsgCache->getWithSetCallback(
+                       "watching-users-msg:$count",
                        function () use ( $count ) {
                                return $this->msg( 'number_of_watching_users_RCview' )
                                        ->numParams( $count )->escaped();
@@ -601,7 +627,7 @@ class ChangesList extends ContextSource {
         * field of this revision, if it's marked as deleted.
         * @param RCCacheEntry|RecentChange $rc
         * @param int $field
-        * @param User $user User object to check, or null to use $wgUser
+        * @param User|null $user User object to check, or null to use $wgUser
         * @return bool
         */
        public static function userCan( $rc, $field, User $user = null ) {
@@ -625,7 +651,8 @@ class ChangesList extends ContextSource {
                }
        }
 
-       /** Inserts a rollback link
+       /**
+        * Insert a rollback link
         *
         * @param string &$s
         * @param RecentChange &$rc
@@ -634,19 +661,18 @@ class ChangesList extends ContextSource {
                if ( $rc->mAttribs['rc_type'] == RC_EDIT
                        && $rc->mAttribs['rc_this_oldid']
                        && $rc->mAttribs['rc_cur_id']
+                       && $rc->getAttribute( 'page_latest' ) == $rc->mAttribs['rc_this_oldid']
                ) {
-                       $page = $rc->getTitle();
-                       /** Check for rollback and edit permissions, disallow special pages, and only
+                       $title = $rc->getTitle();
+                       /** Check for rollback permissions, disallow special pages, and only
                         * show a link on the top-most revision */
-                       if ( $this->getUser()->isAllowed( 'rollback' )
-                               && $rc->mAttribs['page_latest'] == $rc->mAttribs['rc_this_oldid']
-                       ) {
+                       if ( $title->quickUserCan( 'rollback', $this->getUser() ) ) {
                                $rev = new Revision( [
-                                       'title' => $page,
+                                       'title' => $title,
                                        'id' => $rc->mAttribs['rc_this_oldid'],
                                        'user' => $rc->mAttribs['rc_user'],
                                        'user_text' => $rc->mAttribs['rc_user_text'],
-                                       'actor' => isset( $rc->mAttribs['rc_actor'] ) ? $rc->mAttribs['rc_actor'] : null,
+                                       'actor' => $rc->mAttribs['rc_actor'] ?? null,
                                        'deleted' => $rc->mAttribs['rc_deleted']
                                ] );
                                $s .= ' ' . Linker::generateRollback( $rev, $this->getContext() );
index f37ed2d..fc37882 100644 (file)
@@ -206,18 +206,15 @@ class ChangesListBooleanFilter extends ChangesListFilter {
                        return;
                }
 
-               call_user_func_array(
-                       $this->queryCallable,
-                       [
-                               get_class( $specialPage ),
-                               $specialPage->getContext(),
-                               $dbr,
-                               &$tables,
-                               &$fields,
-                               &$conds,
-                               &$query_options,
-                               &$join_conds
-                       ]
+               ( $this->queryCallable )(
+                       get_class( $specialPage ),
+                       $specialPage->getContext(),
+                       $dbr,
+                       $tables,
+                       $fields,
+                       $conds,
+                       $query_options,
+                       $join_conds
                );
        }
 
index 3e2c464..9d30537 100644 (file)
@@ -322,7 +322,7 @@ abstract class ChangesListFilterGroup {
         * @return ChangesListFilter|null Specified filter, or null if it is not registered
         */
        public function getFilter( $name ) {
-               return isset( $this->filters[$name] ) ? $this->filters[$name] : null;
+               return $this->filters[$name] ?? null;
        }
 
        /**
@@ -358,7 +358,7 @@ abstract class ChangesListFilterGroup {
                }
 
                usort( $this->filters, function ( $a, $b ) {
-                       return $b->getPriority() - $a->getPriority();
+                       return $b->getPriority() <=> $a->getPriority();
                } );
 
                foreach ( $this->filters as $filterName => $filter ) {
index 8cd7ba8..e06f081 100644 (file)
@@ -200,19 +200,16 @@ class ChangesListStringOptionsFilterGroup extends ChangesListFilterGroup {
 
                sort( $selectedValues );
 
-               call_user_func_array(
-                       $this->queryCallable,
-                       [
-                               get_class( $specialPage ),
-                               $specialPage->getContext(),
-                               $dbr,
-                               &$tables,
-                               &$fields,
-                               &$conds,
-                               &$query_options,
-                               &$join_conds,
-                               $selectedValues
-                       ]
+               ( $this->queryCallable )(
+                       get_class( $specialPage ),
+                       $specialPage->getContext(),
+                       $dbr,
+                       $tables,
+                       $fields,
+                       $conds,
+                       $query_options,
+                       $join_conds,
+                       $selectedValues
                );
        }
 
index 6c7666f..28b30d8 100644 (file)
@@ -93,7 +93,7 @@ class EnhancedChangesList extends ChangesList {
         *
         * @param RecentChange &$rc
         * @param bool $watched
-        * @param int $linenumber (default null)
+        * @param int|null $linenumber (default null)
         *
         * @return string
         */
@@ -203,8 +203,7 @@ class EnhancedChangesList extends ChangesList {
                # Default values for RC flags
                $collectedRcFlags = [];
                foreach ( $recentChangesFlags as $key => $value ) {
-                       $flagGrouping = ( isset( $recentChangesFlags[$key]['grouping'] ) ?
-                                       $recentChangesFlags[$key]['grouping'] : 'any' );
+                       $flagGrouping = ( $recentChangesFlags[$key]['grouping'] ?? 'any' );
                        switch ( $flagGrouping ) {
                                case 'all':
                                        $collectedRcFlags[$key] = true;
@@ -267,6 +266,7 @@ class EnhancedChangesList extends ChangesList {
 
                # Sub-entries
                $lines = [];
+               $filterClasses = [];
                foreach ( $block as $i => $rcObj ) {
                        $line = $this->getLineData( $block, $rcObj, $queryParams );
                        if ( !$line ) {
@@ -277,8 +277,7 @@ class EnhancedChangesList extends ChangesList {
 
                        // Roll up flags
                        foreach ( $line['recentChangesFlagsRaw'] as $key => $value ) {
-                               $flagGrouping = ( isset( $recentChangesFlags[$key]['grouping'] ) ?
-                                       $recentChangesFlags[$key]['grouping'] : 'any' );
+                               $flagGrouping = ( $recentChangesFlags[$key]['grouping'] ?? 'any' );
                                switch ( $flagGrouping ) {
                                        case 'all':
                                                if ( !$value ) {
@@ -295,12 +294,19 @@ class EnhancedChangesList extends ChangesList {
                                }
                        }
 
+                       // Roll up filter-based CSS classes
+                       $filterClasses = array_merge( $filterClasses, $this->getHTMLClassesForFilters( $rcObj ) );
+                       // Add classes for change tags separately, getHTMLClassesForFilters() doesn't add them
+                       $this->getTags( $rcObj, $filterClasses );
+                       $filterClasses = array_unique( $filterClasses );
+
                        $lines[] = $line;
                }
 
                // Further down are some assumptions that $block is a 0-indexed array
                // with (count-1) as last key. Let's make sure it is.
                $block = array_values( $block );
+               $filterClasses = array_values( $filterClasses );
 
                if ( empty( $block ) || !$lines ) {
                        // if we can't show anything, don't display this block altogether
@@ -341,6 +347,7 @@ class EnhancedChangesList extends ChangesList {
                        'articleLink' => $articleLink,
                        'charDifference' => $charDifference,
                        'collectedRcFlags' => $this->recentChangesFlags( $collectedRcFlags ),
+                       'filterClasses' => $filterClasses,
                        'languageDirMark' => $this->getLanguage()->getDirMark(),
                        'lines' => $lines,
                        'logText' => $logText,
@@ -402,14 +409,14 @@ class EnhancedChangesList extends ChangesList {
 
                # Log timestamp
                if ( $type == RC_LOG ) {
-                       $link = $rcObj->timestamp;
+                       $link = htmlspecialchars( $rcObj->timestamp );
                        # Revision link
                } elseif ( !ChangesList::userCan( $rcObj, Revision::DELETED_TEXT, $this->getUser() ) ) {
-                       $link = '<span class="history-deleted">' . $rcObj->timestamp . '</span> ';
+                       $link = Html::element( 'span', [ 'class' => 'history-deleted' ], $rcObj->timestamp );
                } else {
                        $link = $this->linkRenderer->makeKnownLink(
                                $rcObj->getTitle(),
-                               new HtmlArmor( $rcObj->timestamp ),
+                               $rcObj->timestamp,
                                [],
                                $params
                        );
@@ -465,7 +472,10 @@ class EnhancedChangesList extends ChangesList {
                        // skip entry if hook aborted it
                        return [];
                }
-               $attribs = wfArrayFilterByKey( $attribs, [ Sanitizer::class, 'isReservedDataAttribute' ] );
+               $attribs = array_filter( $attribs,
+                       [ Sanitizer::class, 'isReservedDataAttribute' ],
+                       ARRAY_FILTER_USE_KEY
+               );
 
                $lineParams['recentChangesFlagsRaw'] = [];
                if ( isset( $data['recentChangesFlags'] ) ) {
@@ -635,7 +645,7 @@ class EnhancedChangesList extends ChangesList {
                ];
                // timestamp is not really a link here, but is called timestampLink
                // for consistency with EnhancedChangesListModifyLineData
-               $data['timestampLink'] = $rcObj->timestamp;
+               $data['timestampLink'] = htmlspecialchars( $rcObj->timestamp );
 
                # Article or log link
                if ( $logType ) {
@@ -697,9 +707,9 @@ class EnhancedChangesList extends ChangesList {
                }
                $attribs = $data['attribs'];
                unset( $data['attribs'] );
-               $attribs = wfArrayFilterByKey( $attribs, function ( $key ) {
+               $attribs = array_filter( $attribs, function ( $key ) {
                        return $key === 'class' || Sanitizer::isReservedDataAttribute( $key );
-               } );
+               }, ARRAY_FILTER_USE_KEY );
 
                $prefix = '';
                if ( is_callable( $this->changeLinePrefixer ) ) {
@@ -707,9 +717,14 @@ class EnhancedChangesList extends ChangesList {
                }
 
                $line = Html::openElement( 'table', $attribs ) . Html::openElement( 'tr' );
+               // Highlight block
+               $line .= Html::rawElement( 'td', [],
+                       $this->getHighlightsContainerDiv()
+               );
+
                $line .= Html::rawElement( 'td', [], '<span class="mw-enhancedchanges-arrow-space"></span>' );
                $line .= Html::rawElement( 'td', [ 'class' => 'mw-changeslist-line-prefix' ], $prefix );
-               $line .= '<td class="mw-enhanced-rc">';
+               $line .= '<td class="mw-enhanced-rc" colspan="2">';
 
                if ( isset( $data['recentChangesFlags'] ) ) {
                        $line .= $this->recentChangesFlags( $data['recentChangesFlags'] );
@@ -717,10 +732,10 @@ class EnhancedChangesList extends ChangesList {
                }
 
                if ( isset( $data['timestampLink'] ) ) {
-                       $line .= '&#160;' . $data['timestampLink'];
+                       $line .= "\u{00A0}" . $data['timestampLink'];
                        unset( $data['timestampLink'] );
                }
-               $line .= '&#160;</td>';
+               $line .= "\u{00A0}</td>";
                $line .= Html::openElement( 'td', [
                        'class' => 'mw-changeslist-line-inner',
                        // Used for reliable determination of the affiliated page
index 88c3c22..7ba12fb 100644 (file)
@@ -27,7 +27,7 @@ class OldChangesList extends ChangesList {
         *
         * @param RecentChange &$rc Passed by reference
         * @param bool $watched (default false)
-        * @param int $linenumber (default null)
+        * @param int|null $linenumber (default null)
         *
         * @return string|bool
         */
@@ -63,6 +63,7 @@ class OldChangesList extends ChangesList {
                $dateheader = ''; // $html now contains only <li>...</li>, for hooks' convenience.
                $this->insertDateHeader( $dateheader, $rc->mAttribs['rc_timestamp'] );
 
+               $html = $this->getHighlightsContainerDiv() . $html;
                $attribs['class'] = implode( ' ', $classes );
 
                return $dateheader . Html::rawElement( 'li', $attribs,  $html ) . "\n";
index cc9532e..819f170 100644 (file)
@@ -420,9 +420,9 @@ class RecentChange {
 
                # Convert mAttribs['rc_user'] etc for ActorMigration
                $user = User::newFromAnyId(
-                       isset( $row['rc_user'] ) ? $row['rc_user'] : null,
-                       isset( $row['rc_user_text'] ) ? $row['rc_user_text'] : null,
-                       isset( $row['rc_actor'] ) ? $row['rc_actor'] : null
+                       $row['rc_user'] ?? null,
+                       $row['rc_user_text'] ?? null,
+                       $row['rc_actor'] ?? null
                );
                unset( $row['rc_user'], $row['rc_user_text'], $row['rc_actor'] );
                $row += ActorMigration::newMigration()->getInsertValues( $dbw, 'rc_user', $user );
@@ -490,7 +490,7 @@ class RecentChange {
 
        /**
         * Notify all the feeds about the change.
-        * @param array $feeds Optional feeds to send to, defaults to $wgRCFeeds
+        * @param array|null $feeds Optional feeds to send to, defaults to $wgRCFeeds
         */
        public function notifyRCFeeds( array $feeds = null ) {
                global $wgRCFeeds;
@@ -520,11 +520,7 @@ class RecentChange {
                                continue;
                        }
 
-                       if ( isset( $this->mExtra['actionCommentIRC'] ) ) {
-                               $actionComment = $this->mExtra['actionCommentIRC'];
-                       } else {
-                               $actionComment = null;
-                       }
+                       $actionComment = $this->mExtra['actionCommentIRC'] ?? null;
 
                        $feed = RCFeed::factory( $params );
                        $feed->notify( $this, $actionComment );
@@ -560,7 +556,7 @@ class RecentChange {
         *
         * @param RecentChange|int $change RecentChange or corresponding rc_id
         * @param bool $auto For automatic patrol
-        * @param string|string[] $tags Change tags to add to the patrol log entry
+        * @param string|string[]|null $tags Change tags to add to the patrol log entry
         *   ($user should be able to add the specified tags before this is called)
         * @return array See doMarkPatrolled(), or null if $change is not an existing rc_id
         */
@@ -585,7 +581,7 @@ class RecentChange {
         * 'markedaspatrollederror-noautopatrol' as errors
         * @param User $user User object doing the action
         * @param bool $auto For automatic patrol
-        * @param string|string[] $tags Change tags to add to the patrol log entry
+        * @param string|string[]|null $tags Change tags to add to the patrol log entry
         *   ($user should be able to add the specified tags before this is called)
         * @return array Array of permissions errors, see Title::getUserPermissionsErrors()
         */
@@ -662,9 +658,9 @@ class RecentChange {
         * Makes an entry in the database corresponding to an edit
         *
         * @param string $timestamp
-        * @param Title &$title
+        * @param Title $title
         * @param bool $minor
-        * @param User &$user
+        * @param User $user
         * @param string $comment
         * @param int $oldId
         * @param string $lastTimestamp
@@ -678,7 +674,7 @@ class RecentChange {
         * @return RecentChange
         */
        public static function notifyEdit(
-               $timestamp, &$title, $minor, &$user, $comment, $oldId, $lastTimestamp,
+               $timestamp, $title, $minor, $user, $comment, $oldId, $lastTimestamp,
                $bot, $ip = '', $oldSize = 0, $newSize = 0, $newId = 0, $patrol = 0,
                $tags = []
        ) {
@@ -739,9 +735,9 @@ class RecentChange {
         * Note: the title object must be loaded with the new id using resetArticleID()
         *
         * @param string $timestamp
-        * @param Title &$title
+        * @param Title $title
         * @param bool $minor
-        * @param User &$user
+        * @param User $user
         * @param string $comment
         * @param bool $bot
         * @param string $ip
@@ -752,7 +748,7 @@ class RecentChange {
         * @return RecentChange
         */
        public static function notifyNew(
-               $timestamp, &$title, $minor, &$user, $comment, $bot,
+               $timestamp, $title, $minor, $user, $comment, $bot,
                $ip = '', $size = 0, $newId = 0, $patrol = 0, $tags = []
        ) {
                $rc = new RecentChange;
@@ -809,8 +805,8 @@ class RecentChange {
 
        /**
         * @param string $timestamp
-        * @param Title &$title
-        * @param User &$user
+        * @param Title $title
+        * @param User $user
         * @param string $actionComment
         * @param string $ip
         * @param string $type
@@ -822,7 +818,7 @@ class RecentChange {
         * @param string $actionCommentIRC
         * @return bool
         */
-       public static function notifyLog( $timestamp, &$title, &$user, $actionComment, $ip, $type,
+       public static function notifyLog( $timestamp, $title, $user, $actionComment, $ip, $type,
                $action, $target, $logComment, $params, $newId = 0, $actionCommentIRC = ''
        ) {
                global $wgLogRestrictions;
@@ -840,8 +836,8 @@ class RecentChange {
 
        /**
         * @param string $timestamp
-        * @param Title &$title
-        * @param User &$user
+        * @param Title $title
+        * @param User $user
         * @param string $actionComment
         * @param string $ip
         * @param string $type
@@ -855,7 +851,7 @@ class RecentChange {
         * @param bool $isPatrollable Whether this log entry is patrollable
         * @return RecentChange
         */
-       public static function newLogEntry( $timestamp, &$title, &$user, $actionComment, $ip,
+       public static function newLogEntry( $timestamp, $title, $user, $actionComment, $ip,
                $type, $action, $target, $logComment, $params, $newId = 0, $actionCommentIRC = '',
                $revId = 0, $isPatrollable = false ) {
                global $wgRequest;
@@ -936,7 +932,7 @@ class RecentChange {
         *
         * @param string $timestamp Timestamp of the recent change to occur
         * @param Title $categoryTitle Title of the category a page is being added to or removed from
-        * @param User $user User object of the user that made the change
+        * @param User|null $user User object of the user that made the change
         * @param string $comment Change summary
         * @param Title $pageTitle Title of the page that is being added or removed
         * @param int $oldRevId Parent revision ID of this change
@@ -945,7 +941,7 @@ class RecentChange {
         * @param bool $bot true, if the change was made by a bot
         * @param string $ip IP address of the user, if the change was made anonymously
         * @param int $deleted Indicates whether the change has been deleted
-        * @param bool $added true, if the category was added, false for removed
+        * @param bool|null $added true, if the category was added, false for removed
         *
         * @return RecentChange
         */
@@ -1024,7 +1020,7 @@ class RecentChange {
         */
        public function getParam( $name ) {
                $params = $this->parseParams();
-               return isset( $params[$name] ) ? $params[$name] : null;
+               return $params[$name] ?? null;
        }
 
        /**
@@ -1055,9 +1051,9 @@ class RecentChange {
                $this->mAttribs['rc_comment_data'] = null;
 
                $user = User::newFromAnyId(
-                       isset( $this->mAttribs['rc_user'] ) ? $this->mAttribs['rc_user'] : null,
-                       isset( $this->mAttribs['rc_user_text'] ) ? $this->mAttribs['rc_user_text'] : null,
-                       isset( $this->mAttribs['rc_actor'] ) ? $this->mAttribs['rc_actor'] : null
+                       $this->mAttribs['rc_user'] ?? null,
+                       $this->mAttribs['rc_user_text'] ?? null,
+                       $this->mAttribs['rc_actor'] ?? null
                );
                $this->mAttribs['rc_user'] = $user->getId();
                $this->mAttribs['rc_user_text'] = $user->getName();
@@ -1078,9 +1074,9 @@ class RecentChange {
 
                if ( $name === 'rc_user' || $name === 'rc_user_text' || $name === 'rc_actor' ) {
                        $user = User::newFromAnyId(
-                               isset( $this->mAttribs['rc_user'] ) ? $this->mAttribs['rc_user'] : null,
-                               isset( $this->mAttribs['rc_user_text'] ) ? $this->mAttribs['rc_user_text'] : null,
-                               isset( $this->mAttribs['rc_actor'] ) ? $this->mAttribs['rc_actor'] : null
+                               $this->mAttribs['rc_user'] ?? null,
+                               $this->mAttribs['rc_user_text'] ?? null,
+                               $this->mAttribs['rc_actor'] ?? null
                        );
                        if ( $name === 'rc_user' ) {
                                return $user->getId();
@@ -1093,7 +1089,7 @@ class RecentChange {
                        }
                }
 
-               return isset( $this->mAttribs[$name] ) ? $this->mAttribs[$name] : null;
+               return $this->mAttribs[$name] ?? null;
        }
 
        /**
index b64f85a..3bb777e 100644 (file)
@@ -213,7 +213,7 @@ class ChangeTags {
         * @param int|null $rc_id The rc_id of the change to add the tags to
         * @param int|null $rev_id The rev_id of the change to add the tags to
         * @param int|null $log_id The log_id of the change to add the tags to
-        * @param string $params Params to put in the ct_params field of table 'change_tag'
+        * @param string|null $params Params to put in the ct_params field of table 'change_tag'
         * @param RecentChange|null $rc Recent change, in case the tagging accompanies the action
         * (this should normally be the case)
         *
@@ -244,7 +244,7 @@ class ChangeTags {
         * Pass a variable whose value is null if the rev_id is not relevant or unknown.
         * @param int|null &$log_id The log_id of the change to add the tags to.
         * Pass a variable whose value is null if the log_id is not relevant or unknown.
-        * @param string $params Params to put in the ct_params field of table
+        * @param string|null $params Params to put in the ct_params field of table
         * 'change_tag' when adding tags
         * @param RecentChange|null $rc Recent change being tagged, in case the tagging accompanies
         * the action
@@ -261,6 +261,8 @@ class ChangeTags {
                &$rev_id = null, &$log_id = null, $params = null, RecentChange $rc = null,
                User $user = null
        ) {
+               global $wgChangeTagsSchemaMigrationStage;
+
                $tagsToAdd = array_filter( (array)$tagsToAdd ); // Make sure we're submitting all tags...
                $tagsToRemove = array_filter( (array)$tagsToRemove );
 
@@ -342,6 +344,22 @@ class ChangeTags {
 
                // insert a row into change_tag for each new tag
                if ( count( $tagsToAdd ) ) {
+                       $changeTagMapping = [];
+                       if ( $wgChangeTagsSchemaMigrationStage > MIGRATION_OLD ) {
+                               $changeTagDefStore = MediaWikiServices::getInstance()->getChangeTagDefStore();
+
+                               foreach ( $tagsToAdd as $tag ) {
+                                       $changeTagMapping[$tag] = $changeTagDefStore->acquireId( $tag );
+                               }
+
+                               $dbw->update(
+                                       'change_tag_def',
+                                       [ 'ctd_count = ctd_count + 1' ],
+                                       [ 'ctd_name' => $tagsToAdd ],
+                                       __METHOD__
+                               );
+                       }
+
                        $tagsRows = [];
                        foreach ( $tagsToAdd as $tag ) {
                                // Filter so we don't insert NULLs as zero accidentally.
@@ -354,9 +372,11 @@ class ChangeTags {
                                                'ct_rc_id' => $rc_id,
                                                'ct_log_id' => $log_id,
                                                'ct_rev_id' => $rev_id,
-                                               'ct_params' => $params
+                                               'ct_params' => $params,
+                                               'ct_tag_id' => $changeTagMapping[$tag] ?? null,
                                        ]
                                );
+
                        }
 
                        $dbw->insert( 'change_tag', $tagsRows, __METHOD__, [ 'IGNORE' ] );
@@ -374,6 +394,20 @@ class ChangeTags {
                                        ]
                                );
                                $dbw->delete( 'change_tag', $conds, __METHOD__ );
+                               if ( $dbw->affectedRows() && $wgChangeTagsSchemaMigrationStage > MIGRATION_OLD ) {
+                                       $dbw->update(
+                                               'change_tag_def',
+                                               [ 'ctd_count = ctd_count - 1' ],
+                                               [ 'ctd_name' => $tag ],
+                                               __METHOD__
+                                       );
+
+                                       $dbw->delete(
+                                               'change_tag_def',
+                                               [ 'ctd_name' => $tag, 'ctd_count' => 0, 'ctd_user_defined' => 0 ],
+                                               __METHOD__
+                                       );
+                               }
                        }
                }
 
@@ -419,7 +453,7 @@ class ChangeTags {
                // $prevTags can be out of date on replica DBs, especially when addTags is called consecutively,
                // causing loss of tags added recently in tag_summary table.
                $prevTags = $dbw->selectField( 'tag_summary', 'ts_tags', $tsConds, __METHOD__ );
-               $prevTags = $prevTags ? $prevTags : '';
+               $prevTags = $prevTags ?: '';
                $prevTags = array_filter( explode( ',', $prevTags ) );
 
                // add tags
@@ -828,8 +862,8 @@ class ChangeTags {
        }
 
        /**
-        * Defines a tag in the valid_tag table, without checking that the tag name
-        * is valid.
+        * Defines a tag in the valid_tag table and/or update ctd_user_defined field in change_tag_def,
+        * without checking that the tag name is valid.
         * Extensions should NOT use this function; they can use the ListDefinedTags
         * hook instead.
         *
@@ -837,26 +871,63 @@ class ChangeTags {
         * @since 1.25
         */
        public static function defineTag( $tag ) {
+               global $wgChangeTagsSchemaMigrationStage;
+
                $dbw = wfGetDB( DB_MASTER );
-               $dbw->replace( 'valid_tag',
+               if ( $wgChangeTagsSchemaMigrationStage > MIGRATION_OLD ) {
+                       $tagDef = [
+                               'ctd_name' => $tag,
+                               'ctd_user_defined' => 1,
+                               'ctd_count' => 0
+                       ];
+                       $dbw->upsert(
+                               'change_tag_def',
+                               $tagDef,
+                               [ 'ctd_name' ],
+                               [ 'ctd_user_defined' => 1 ],
+                               __METHOD__
+                       );
+               }
+
+               $dbw->replace(
+                       'valid_tag',
                        [ 'vt_tag' ],
                        [ 'vt_tag' => $tag ],
-                       __METHOD__ );
+                       __METHOD__
+               );
 
                // clear the memcache of defined tags
                self::purgeTagCacheAll();
        }
 
        /**
-        * Removes a tag from the valid_tag table. The tag may remain in use by
-        * extensions, and may still show up as 'defined' if an extension is setting
-        * it from the ListDefinedTags hook.
+        * Removes a tag from the valid_tag table and/or update ctd_user_defined field in change_tag_def.
+        * The tag may remain in use by extensions, and may still show up as 'defined'
+        * if an extension is setting it from the ListDefinedTags hook.
         *
         * @param string $tag Tag to remove
         * @since 1.25
         */
        public static function undefineTag( $tag ) {
+               global $wgChangeTagsSchemaMigrationStage;
+
                $dbw = wfGetDB( DB_MASTER );
+
+               if ( $wgChangeTagsSchemaMigrationStage > MIGRATION_OLD ) {
+                       $dbw->update(
+                               'change_tag_def',
+                               [ 'ctd_name' => $tag ],
+                               [ 'ctd_user_defined' => 0 ],
+                               __METHOD__
+                       );
+
+                       $dbw->delete(
+                               'change_tag_def',
+                               [ 'ctd_name' => $tag, 'ctd_count' => 0 ],
+                               __METHOD__
+                       );
+               }
+
                $dbw->delete( 'valid_tag', [ 'vt_tag' => $tag ], __METHOD__ );
 
                // clear the memcache of defined tags
@@ -870,7 +941,7 @@ class ChangeTags {
         * @param string $tag
         * @param string $reason
         * @param User $user Who to attribute the action to
-        * @param int $tagCount For deletion only, how many usages the tag had before
+        * @param int|null $tagCount For deletion only, how many usages the tag had before
         * it was deleted.
         * @param array $logEntryTags Change tags to apply to the entry
         * that will be created in the tag management log
@@ -1108,6 +1179,7 @@ class ChangeTags {
 
        /**
         * Creates a tag by adding a row to the `valid_tag` table.
+        * and/or add it to `change_tag_def` table.
         *
         * Extensions should NOT use this function; they can use the ListDefinedTags
         * hook instead.
@@ -1158,10 +1230,11 @@ class ChangeTags {
         * @since 1.25
         */
        public static function deleteTagEverywhere( $tag ) {
+               global $wgChangeTagsSchemaMigrationStage;
                $dbw = wfGetDB( DB_MASTER );
                $dbw->startAtomic( __METHOD__ );
 
-               // delete from valid_tag
+               // delete from valid_tag and/or set ctd_user_defined = 0
                self::undefineTag( $tag );
 
                // find out which revisions use this tag, so we can delete from tag_summary
@@ -1180,6 +1253,10 @@ class ChangeTags {
                // delete from change_tag
                $dbw->delete( 'change_tag', [ 'ct_tag' => $tag ], __METHOD__ );
 
+               if ( $wgChangeTagsSchemaMigrationStage > MIGRATION_OLD ) {
+                       $dbw->delete( 'change_tag_def', [ 'ctd_name' => $tag ], __METHOD__ );
+               }
+
                $dbw->endAtomic( __METHOD__ );
 
                // give extensions a chance
@@ -1268,7 +1345,7 @@ class ChangeTags {
 
                // store the tag usage statistics
                $tagUsage = self::tagUsageStatistics();
-               $hitcount = isset( $tagUsage[$tag] ) ? $tagUsage[$tag] : 0;
+               $hitcount = $tagUsage[$tag] ?? 0;
 
                // do it!
                $deleteResult = self::deleteTagEverywhere( $tag );
@@ -1430,6 +1507,13 @@ class ChangeTags {
         * @return array Array of string => int
         */
        public static function tagUsageStatistics() {
+               global $wgChangeTagsSchemaMigrationStage, $wgTagStatisticsNewTable;
+               if ( $wgChangeTagsSchemaMigrationStage > MIGRATION_WRITE_BOTH ||
+                       ( $wgTagStatisticsNewTable && $wgChangeTagsSchemaMigrationStage > MIGRATION_OLD )
+               ) {
+                       return self::newTagUsageStatistics();
+               }
+
                $fname = __METHOD__;
                $cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
                return $cache->getWithSetCallback(
@@ -1463,6 +1547,29 @@ class ChangeTags {
                );
        }
 
+       /**
+        * Same self::tagUsageStatistics() but uses change_tag_def.
+        *
+        * @return array Array of string => int
+        */
+       private static function newTagUsageStatistics() {
+               $dbr = wfGetDB( DB_REPLICA );
+               $res = $dbr->select(
+                       'change_tag_def',
+                       [ 'ctd_name', 'ctd_count' ],
+                       [],
+                       __METHOD__,
+                       [ 'ORDER BY' => 'ctd_count DESC' ]
+               );
+
+               $out = [];
+               foreach ( $res as $row ) {
+                       $out[$row->ctd_name] = $row->ctd_count;
+               }
+
+               return $out;
+       }
+
        /**
         * Indicate whether change tag editing UI is relevant
         *
index 3388860..a531cd1 100644 (file)
@@ -73,7 +73,7 @@ class SquidPurgeClient {
        public function __construct( $server, $options = [] ) {
                $parts = explode( ':', $server, 2 );
                $this->host = $parts[0];
-               $this->port = isset( $parts[1] ) ? $parts[1] : 80;
+               $this->port = $parts[1] ?? 80;
        }
 
        /**
index 9ac81ae..5f401a5 100644 (file)
@@ -94,7 +94,7 @@ class IcuCollation extends Collation {
                'af' => [],
                'am' => [],
                'ar' => [],
-               'as' => [ "\xe0\xa6\x82", "\xe0\xa6\x81", "\xe0\xa6\x83", "\xe0\xa7\x8e", "ক্ষ " ],
+               'as' => [ "\u{0982}", "\u{0981}", "\u{0983}", "\u{09CE}", "ক্ষ " ],
                'ast' => [ "Ch", "Ll", "Ñ" ], // not in libicu
                'az' => [ "Ç", "Ə", "Ğ", "İ", "Ö", "Ş", "Ü" ],
                'be' => [ "Ё" ],
@@ -144,11 +144,11 @@ class IcuCollation extends Collation {
                'ga' => [],
                'gd' => [], // not in libicu
                'gl' => [ "Ch", "Ll", "Ñ" ],
-               'gu' => [ "\xe0\xaa\x82", "\xe0\xaa\x83", "\xe0\xaa\x81", "\xe0\xaa\xb3" ],
+               'gu' => [ "\u{0A82}", "\u{0A83}", "\u{0A81}", "\u{0AB3}" ],
                'ha' => [ 'Ɓ', 'Ɗ', 'Ƙ', 'Sh', 'Ts', 'Ƴ' ],
                'haw' => [ 'ʻ' ],
                'he' => [],
-               'hi' => [ "\xe0\xa4\x82", "\xe0\xa4\x83" ],
+               'hi' => [ "\u{0902}", "\u{0903}" ],
                'hr' => [ "Č", "Ć", "Dž", "Đ", "Lj", "Nj", "Š", "Ž" ],
                'hsb' => [ "Č", "Dź", "Ě", "Ch", "Ł", "Ń", "Ř", "Š", "Ć", "Ž" ],
                'hu' => [ "Cs", "Dz", "Dzs", "Gy", "Ly", "Ny", "Ö", "Sz", "Ty", "Ü", "Zs" ],
@@ -161,13 +161,13 @@ class IcuCollation extends Collation {
                'kk' => [ "Ү", "І" ],
                'kl' => [ "Æ", "Ø", "Å" ],
                'km' => [
-                       "រ", "ឫ", "ឬ", "ល", "ឭ", "ឮ", "\xe1\x9e\xbb\xe1\x9f\x86",
-                       "\xe1\x9f\x86", "\xe1\x9e\xb6\xe1\x9f\x86", "\xe1\x9f\x87",
-                       "\xe1\x9e\xb7\xe1\x9f\x87", "\xe1\x9e\xbb\xe1\x9f\x87",
-                       "\xe1\x9f\x81\xe1\x9f\x87", "\xe1\x9f\x84\xe1\x9f\x87",
+                       "រ", "ឫ", "ឬ", "ល", "ឭ", "ឮ", "\u{17BB}\u{17C6}",
+                       "\u{17C6}", "\u{17B6}\u{17C6}", "\u{17C7}",
+                       "\u{17B7}\u{17C7}", "\u{17BB}\u{17C7}",
+                       "\u{17C1}\u{17C7}", "\u{17C4}\u{17C7}",
                ],
-               'kn' => [ "\xe0\xb2\x81", "\xe0\xb2\x83", "\xe0\xb3\xb1", "\xe0\xb3\xb2" ],
-               'kok' => [ "\xe0\xa4\x82", "\xe0\xa4\x83", "ळ", "क्ष" ],
+               'kn' => [ "\u{0C81}", "\u{0C83}", "\u{0CF1}", "\u{0CF2}" ],
+               'kok' => [ "\u{0902}", "\u{0903}", "ळ", "क्ष" ],
                'ku' => [ "Ç", "Ê", "Î", "Ş", "Û" ], // not in libicu
                'ky' => [ "Ё" ],
                'la' => [], // not in libicu
@@ -181,7 +181,7 @@ class IcuCollation extends Collation {
                'ml' => [],
                'mn' => [],
                'mo' => [ "Ă", "Â", "Î", "Ș", "Ț" ], // not in libicu
-               'mr' => [ "\xe0\xa4\x82", "\xe0\xa4\x83", "ळ", "क्ष", "ज्ञ" ],
+               'mr' => [ "\u{0902}", "\u{0903}", "ळ", "क्ष", "ज्ञ" ],
                'ms' => [],
                'mt' => [ "Ċ", "Ġ", "Għ", "Ħ", "Ż" ],
                'nb' => [ "Æ", "Ø", "Å" ],
@@ -191,8 +191,8 @@ class IcuCollation extends Collation {
                'no' => [ "Æ", "Ø", "Å" ], // not in libicu. You should probably use nb or nn instead.
                'oc' => [], // not in libicu
                'om' => [ 'Ch', 'Dh', 'Kh', 'Ny', 'Ph', 'Sh' ],
-               'or' => [ "\xe0\xac\x81", "\xe0\xac\x82", "\xe0\xac\x83", "କ୍ଷ" ],
-               'pa' => [ "\xe0\xa9\x8d" ],
+               'or' => [ "\u{0B01}", "\u{0B02}", "\u{0B03}", "କ୍ଷ" ],
+               'pa' => [ "\u{0A4D}" ],
                'pl' => [ "Ą", "Ć", "Ę", "Ł", "Ń", "Ó", "Ś", "Ź", "Ż" ],
                'pt' => [],
                'rm' => [], // not in libicu
@@ -204,7 +204,7 @@ class IcuCollation extends Collation {
                        'Á', 'Č', 'Ʒ', 'Ǯ', 'Đ', 'Ǧ', 'Ǥ', 'Ǩ', 'Ŋ',
                        'Š', 'Ŧ', 'Ž', 'Ø', 'Æ', 'Ȧ', 'Ä', 'Ö'
                ],
-               'si' => [ "\xe0\xb6\x82", "\xe0\xb6\x83", "\xe0\xb6\xa4" ],
+               'si' => [ "\u{0D82}", "\u{0D83}", "\u{0DA4}" ],
                'sk' => [ "Ä", "Č", "Ch", "Ô", "Š", "Ž" ],
                'sl' => [ "Č", "Š", "Ž" ],
                'smn' => [ "Á", "Č", "Đ", "Ŋ", "Š", "Ŧ", "Ž", "Æ", "Ø", "Å", "Ä", "Ö" ],
@@ -215,12 +215,12 @@ class IcuCollation extends Collation {
                'sv@collation=standard' => [ "Å", "Ä", "Ö" ],
                'sw' => [],
                'ta' => [
-                       "\xE0\xAE\x82", "ஃ", "க்ஷ", "க்", "ங்", "ச்", "ஞ்", "ட்", "ண்", "த்", "ந்",
+                       "\u{0B82}", "ஃ", "க்ஷ", "க்", "ங்", "ச்", "ஞ்", "ட்", "ண்", "த்", "ந்",
                        "ப்", "ம்", "ய்", "ர்", "ல்", "வ்", "ழ்", "ள்", "ற்", "ன்", "ஜ்", "ஶ்", "ஷ்",
                        "ஸ்", "ஹ்", "க்ஷ்"
                ],
-               'te' => [ "\xe0\xb0\x81", "\xe0\xb0\x82", "\xe0\xb0\x83" ],
-               'th' => [ "ฯ", "\xe0\xb9\x86", "\xe0\xb9\x8d", "\xe0\xb8\xba" ],
+               'te' => [ "\u{0C01}", "\u{0C02}", "\u{0C03}" ],
+               'th' => [ "ฯ", "\u{0E46}", "\u{0E4D}", "\u{0E3A}" ],
                'tk' => [ "Ç", "Ä", "Ž", "Ň", "Ö", "Ş", "Ü", "Ý" ],
                'tl' => [ "Ñ", "Ng" ], // not in libicu
                'to' => [ "Ng", "ʻ" ],
@@ -231,8 +231,8 @@ class IcuCollation extends Collation {
                'vi' => [ "Ă", "Â", "Đ", "Ê", "Ô", "Ơ", "Ư" ],
                'vo' => [ "Ä", "Ö", "Ü" ],
                'yi' => [
-                       "\xd7\x91\xd6\xbf", "\xd7\x9b\xd6\xbc", "\xd7\xa4\xd6\xbc",
-                       "\xd7\xa9\xd7\x82", "\xd7\xaa\xd6\xbc"
+                       "\u{05D1}\u{05BF}", "\u{05DB}\u{05BC}", "\u{05E4}\u{05BC}",
+                       "\u{05E9}\u{05C2}", "\u{05EA}\u{05BC}"
                ],
                'yo' => [ "Ẹ", "Gb", "Ọ", "Ṣ" ],
                'zu' => [],
@@ -333,7 +333,7 @@ class IcuCollation extends Collation {
                                static::class,
                                $this->locale,
                                $this->digitTransformLanguage->getCode(),
-                               self::getICUVersion(),
+                               INTL_ICU_VERSION,
                                self::FIRST_LETTER_VERSION
                        );
                        $this->firstLetterData = $cache->getWithSetCallback( $cacheKey, $cache::TTL_WEEK, function () {
@@ -390,8 +390,7 @@ class IcuCollation extends Collation {
                                wfDebug( "Primary collision '$letter' '{$letterMap[$key]}' (comparison: $comp)\n" );
                                // If that also has a collision, use codepoint as a tiebreaker.
                                if ( $comp === 0 ) {
-                                       // TODO Use <=> operator when PHP 7 is allowed.
-                                       $comp = UtfNormal\Utils::utf8ToCodepoint( $letter ) -
+                                       $comp = UtfNormal\Utils::utf8ToCodepoint( $letter ) <=>
                                                UtfNormal\Utils::utf8ToCodepoint( $letterMap[$key] );
                                }
                                if ( $comp < 0 ) {
@@ -528,18 +527,15 @@ class IcuCollation extends Collation {
         * can't be determined.
         *
         * The constant INTL_ICU_VERSION this function refers to isn't really
-        * documented. It is available since PHP 5.3.7 (see PHP 54561
-        * https://bugs.php.net/bug.php?id=54561). This function will return
-        * false on older PHPs.
-        *
-        * TODO: Remove the backwards-compatibility as MediaWiki now requires
-        * higher levels of PHP.
+        * documented, but see https://bugs.php.net/bug.php?id=54561.
         *
         * @since 1.21
-        * @return string|bool
+        * @deprecated since 1.32, use INTL_ICU_VERSION directly
+        * @return string
         */
        static function getICUVersion() {
-               return defined( 'INTL_ICU_VERSION' ) ? INTL_ICU_VERSION : false;
+               wfDeprecated( __METHOD__, '1.32' );
+               return INTL_ICU_VERSION;
        }
 
        /**
@@ -550,7 +546,7 @@ class IcuCollation extends Collation {
         * @return string|bool
         */
        static function getUnicodeVersionForICU() {
-               $icuVersion = self::getICUVersion();
+               $icuVersion = INTL_ICU_VERSION;
                if ( !$icuVersion ) {
                        return false;
                }
@@ -558,6 +554,8 @@ class IcuCollation extends Collation {
                $versionPrefix = substr( $icuVersion, 0, 3 );
                // Source: http://site.icu-project.org/download
                $map = [
+                       '61.' => '10.0',
+                       '60.' => '10.0',
                        '59.' => '9.0',
                        '58.' => '9.0',
                        '57.' => '8.0',
@@ -579,10 +577,6 @@ class IcuCollation extends Collation {
                        '3.4' => '4.1',
                ];
 
-               if ( isset( $map[$versionPrefix] ) ) {
-                       return $map[$versionPrefix];
-               } else {
-                       return false;
-               }
+               return $map[$versionPrefix] ?? false;
        }
 }
diff --git a/includes/compat/ScopedCallback.php b/includes/compat/ScopedCallback.php
deleted file mode 100644 (file)
index 4fd4bc7..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-<?php
-/**
- * Compatibility class for pre-namespace, pre-library class name
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- */
-
-/**
- * @deprecated since 1.28 use Wikimedia\ScopedCallback
- *
- * @since 1.21
- */
-class ScopedCallback extends Wikimedia\ScopedCallback {
-}
diff --git a/includes/compat/Timestamp.php b/includes/compat/Timestamp.php
deleted file mode 100644 (file)
index 63b87ae..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-<?php
-// This file is loaded by composer.json#autoload.files instead of autoload.php,
-// because PHP's class loader does not support autoloading an alias for a class that
-// isn't already loaded. See also AutoLoaderTest and ClassCollector.
-
-// By using an autoload file, this will trigger directly at runtime outside any class
-// loading context. This file will then register the alias and, as class_alias() does
-// by default, it will trigger a plain autoload for the destination class.
-
-// The below uses a namespaced class reference, to to avoid being seen by ClassCollector,
-// which would otherwise add it to autoload.php, after which AutoLoaderTest will
-// complain about class_alias() not being in the target class file.
-
-/**
- * @deprecated since 1.29
- * @since 1.20
- */
-class_alias( Wikimedia\Timestamp\TimestampException::class, 'TimestampException' );
diff --git a/includes/compat/XMPReader.php b/includes/compat/XMPReader.php
new file mode 100644 (file)
index 0000000..5854842
--- /dev/null
@@ -0,0 +1,40 @@
+<?php
+/**
+ * Back-compat for pre-librarized XMP classes
+ *
+ * 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.
+ */
+
+use Wikimedia\XMPReader\Info;
+use Wikimedia\XMPReader\Reader;
+use Wikimedia\XMPReader\Validate;
+
+/**
+ * @deprecated since 1.32
+ */
+class XMPInfo extends Info {
+}
+
+/**
+ * @deprecated since 1.32
+ */
+class XMPReader extends Reader {
+}
+
+/**
+ * @deprecated since 1.32
+ */
+class XMPValidate extends Validate {
+}
index 308bef6..bce1ea6 100644 (file)
@@ -57,6 +57,7 @@ class UtfNormal {
         * @return string a clean, shiny, normalized UTF-8 string
         */
        static function cleanUp( $string ) {
+               wfDeprecated( __METHOD__, '1.25' );
                return Validator::cleanUp( $string );
        }
 
@@ -69,6 +70,7 @@ class UtfNormal {
         * @return string a UTF-8 string in normal form C
         */
        static function toNFC( $string ) {
+               wfDeprecated( __METHOD__, '1.25' );
                return Validator::toNFC( $string );
        }
 
@@ -80,6 +82,7 @@ class UtfNormal {
         * @return string a UTF-8 string in normal form D
         */
        static function toNFD( $string ) {
+               wfDeprecated( __METHOD__, '1.25' );
                return Validator::toNFD( $string );
        }
 
@@ -92,6 +95,7 @@ class UtfNormal {
         * @return string a UTF-8 string in normal form KC
         */
        static function toNFKC( $string ) {
+               wfDeprecated( __METHOD__, '1.25' );
                return Validator::toNFKC( $string );
        }
 
@@ -104,6 +108,7 @@ class UtfNormal {
         * @return string a UTF-8 string in normal form KD
         */
        static function toNFKD( $string ) {
+               wfDeprecated( __METHOD__, '1.25' );
                return Validator::toNFKD( $string );
        }
 
@@ -114,6 +119,7 @@ class UtfNormal {
         * @return bool
         */
        static function quickIsNFC( $string ) {
+               wfDeprecated( __METHOD__, '1.25' );
                return Validator::quickIsNFC( $string );
        }
 
@@ -124,6 +130,7 @@ class UtfNormal {
         * @return bool
         */
        static function quickIsNFCVerify( &$string ) {
+               wfDeprecated( __METHOD__, '1.25' );
                return Validator::quickIsNFCVerify( $string );
        }
 }
diff --git a/includes/compat/normal/UtfNormalDefines.php b/includes/compat/normal/UtfNormalDefines.php
deleted file mode 100644 (file)
index 38ce855..0000000
+++ /dev/null
@@ -1,186 +0,0 @@
-<?php
-/**
- * Backwards-compatability constants which are now provided by the
- * UtfNormal library. They are hardcoded here since they are needed
- * before the composer autoloader is initialized.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- * @ingroup UtfNormal
- */
-
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UNICODE_HANGUL_FIRST', 0xac00 );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UNICODE_HANGUL_LAST', 0xd7a3 );
-
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UNICODE_HANGUL_LBASE', 0x1100 );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UNICODE_HANGUL_VBASE', 0x1161 );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UNICODE_HANGUL_TBASE', 0x11a7 );
-
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UNICODE_HANGUL_LCOUNT', 19 );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UNICODE_HANGUL_VCOUNT', 21 );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UNICODE_HANGUL_TCOUNT', 28 );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UNICODE_HANGUL_NCOUNT', UNICODE_HANGUL_VCOUNT * UNICODE_HANGUL_TCOUNT );
-
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UNICODE_HANGUL_LEND', UNICODE_HANGUL_LBASE + UNICODE_HANGUL_LCOUNT - 1 );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UNICODE_HANGUL_VEND', UNICODE_HANGUL_VBASE + UNICODE_HANGUL_VCOUNT - 1 );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UNICODE_HANGUL_TEND', UNICODE_HANGUL_TBASE + UNICODE_HANGUL_TCOUNT - 1 );
-
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UNICODE_SURROGATE_FIRST', 0xd800 );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UNICODE_SURROGATE_LAST', 0xdfff );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UNICODE_MAX', 0x10ffff );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UNICODE_REPLACEMENT', 0xfffd );
-
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UTF8_HANGUL_FIRST', "\xea\xb0\x80" /*codepointToUtf8( UNICODE_HANGUL_FIRST )*/ );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UTF8_HANGUL_LAST', "\xed\x9e\xa3" /*codepointToUtf8( UNICODE_HANGUL_LAST )*/ );
-
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UTF8_HANGUL_LBASE', "\xe1\x84\x80" /*codepointToUtf8( UNICODE_HANGUL_LBASE )*/ );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UTF8_HANGUL_VBASE', "\xe1\x85\xa1" /*codepointToUtf8( UNICODE_HANGUL_VBASE )*/ );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UTF8_HANGUL_TBASE', "\xe1\x86\xa7" /*codepointToUtf8( UNICODE_HANGUL_TBASE )*/ );
-
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UTF8_HANGUL_LEND', "\xe1\x84\x92" /*codepointToUtf8( UNICODE_HANGUL_LEND )*/ );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UTF8_HANGUL_VEND', "\xe1\x85\xb5" /*codepointToUtf8( UNICODE_HANGUL_VEND )*/ );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UTF8_HANGUL_TEND', "\xe1\x87\x82" /*codepointToUtf8( UNICODE_HANGUL_TEND )*/ );
-
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UTF8_SURROGATE_FIRST', "\xed\xa0\x80" /*codepointToUtf8( UNICODE_SURROGATE_FIRST )*/ );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UTF8_SURROGATE_LAST', "\xed\xbf\xbf" /*codepointToUtf8( UNICODE_SURROGATE_LAST )*/ );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UTF8_MAX', "\xf4\x8f\xbf\xbf" /*codepointToUtf8( UNICODE_MAX )*/ );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UTF8_REPLACEMENT', "\xef\xbf\xbd" /*codepointToUtf8( UNICODE_REPLACEMENT )*/ );
-# define( 'UTF8_REPLACEMENT', '!' );
-
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UTF8_OVERLONG_A', "\xc1\xbf" );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UTF8_OVERLONG_B', "\xe0\x9f\xbf" );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UTF8_OVERLONG_C', "\xf0\x8f\xbf\xbf" );
-
-# These two ranges are illegal
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UTF8_FDD0', "\xef\xb7\x90" /*codepointToUtf8( 0xfdd0 )*/ );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UTF8_FDEF', "\xef\xb7\xaf" /*codepointToUtf8( 0xfdef )*/ );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UTF8_FFFE', "\xef\xbf\xbe" /*codepointToUtf8( 0xfffe )*/ );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UTF8_FFFF', "\xef\xbf\xbf" /*codepointToUtf8( 0xffff )*/ );
-
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UTF8_HEAD', false );
-/**
- * @deprecated since 1.25, use UtfNormal\Constants instead
- */
-define( 'UTF8_TAIL', true );
diff --git a/includes/compat/normal/UtfNormalUtil.php b/includes/compat/normal/UtfNormalUtil.php
deleted file mode 100644 (file)
index 0e29dd0..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-<?php
-/**
- * Some of these functions are adapted from places in MediaWiki.
- * Should probably merge them for consistency.
- *
- * Copyright © 2004 Brion Vibber <brion@pobox.com>
- * https://www.mediawiki.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- * @ingroup UtfNormal
- */
-
-use UtfNormal\Utils;
-
-/**
- * Return UTF-8 sequence for a given Unicode code point.
- *
- * @param int $codepoint
- * @return string
- * @throws InvalidArgumentException if fed out of range data.
- * @public
- * @deprecated since 1.25, use UtfNormal\Utils directly
- */
-function codepointToUtf8( $codepoint ) {
-       wfDeprecated( __FUNCTION__, '1.25' );
-       return Utils::codepointToUtf8( $codepoint );
-}
-
-/**
- * Take a series of space-separated hexadecimal numbers representing
- * Unicode code points and return a UTF-8 string composed of those
- * characters. Used by UTF-8 data generation and testing routines.
- *
- * @param string $sequence
- * @return string
- * @throws InvalidArgumentException if fed out of range data.
- * @private
- * @deprecated since 1.25, use UtfNormal\Utils directly
- */
-function hexSequenceToUtf8( $sequence ) {
-       wfDeprecated( __FUNCTION__, '1.25' );
-       return Utils::hexSequenceToUtf8( $sequence );
-}
-
-/**
- * Take a UTF-8 string and return a space-separated series of hex
- * numbers representing Unicode code points. For debugging.
- *
- * @fixme this is private but extensions + maint scripts are using it
- * @param string $str UTF-8 string.
- * @return string
- * @private
- */
-function utf8ToHexSequence( $str ) {
-       wfDeprecated( __FUNCTION__, '1.25' );
-       $buf = '';
-       foreach ( preg_split( '//u', $str, -1, PREG_SPLIT_NO_EMPTY ) as $cp ) {
-               $buf .= sprintf( '%04x ', UtfNormal\Utils::utf8ToCodepoint( $cp ) );
-       }
-
-       return rtrim( $buf );
-}
-
-/**
- * Determine the Unicode codepoint of a single-character UTF-8 sequence.
- * Does not check for invalid input data.
- *
- * @param string $char
- * @return int
- * @public
- * @deprecated since 1.25, use UtfNormal\Utils directly
- */
-function utf8ToCodepoint( $char ) {
-       wfDeprecated( __FUNCTION__, '1.25' );
-       return Utils::utf8ToCodepoint( $char );
-}
-
-/**
- * Escape a string for inclusion in a PHP single-quoted string literal.
- *
- * @param string $string string to be escaped.
- * @return string escaped string.
- * @public
- * @deprecated since 1.25, use UtfNormal\Utils directly
- */
-function escapeSingleString( $string ) {
-       wfDeprecated( __FUNCTION__, '1.25' );
-       return Utils::escapeSingleString( $string );
-}
index a1943be..b26a479 100644 (file)
@@ -7,7 +7,7 @@ $GLOBALS['IP'] = __DIR__ . '/../../';
 require_once __DIR__ . '/../AutoLoader.php';
 
 /**
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
  * @author Jeroen De Dauw < jeroendedauw@gmail.com >
  */
 class ComposerHookHandler {
index 168336b..6aa0b5b 100644 (file)
@@ -5,7 +5,7 @@ use Composer\Package\Package;
 use Composer\Semver\Constraint\Constraint;
 
 /**
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
  * @author Jeroen De Dauw < jeroendedauw@gmail.com >
  */
 class ComposerPackageModifier {
index 2194bed..52bc0cd 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
 /**
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
  * @author Jeroen De Dauw < jeroendedauw@gmail.com >
  */
 class ComposerVersionNormalizer {
diff --git a/includes/config/ConfigRepository.php b/includes/config/ConfigRepository.php
new file mode 100644 (file)
index 0000000..c87a344
--- /dev/null
@@ -0,0 +1,224 @@
+<?php
+/**
+ * Copyright 2016
+ *
+ * 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\Config;
+
+use MediaWiki\Services\SalvageableService;
+use Wikimedia\Assert\Assert;
+
+/**
+ * Object which holds currently registered configuration options.
+ *
+ * @since 1.32
+ */
+class ConfigRepository implements SalvageableService {
+       /** @var \ConfigFactory */
+       private $configFactory;
+
+       /** @var array */
+       private $configItems = [
+               'private' => [],
+               'public' => [],
+       ];
+
+       /**
+        * @param \ConfigFactory $configFactory
+        */
+       public function __construct( \ConfigFactory $configFactory ) {
+               $this->configFactory = $configFactory;
+       }
+
+       /**
+        * Returns true, if this repository contains a configuration with a specific name.
+        *
+        * @param string $name The name of the config to check the existence of
+        * @param bool $alsoPrivate If set to true, will check the private config options, too
+        * @return bool
+        */
+       public function has( $name, $alsoPrivate = false ) {
+               return isset( $this->configItems['public'][$name] ) ||
+                       ( $alsoPrivate && isset( $this->configItems['private'][$name] ) );
+       }
+
+       /**
+        * Returns the ConfigItem with the given name, if there's one. Throws a ConfigException
+        * otherwise.
+        *
+        * @param string $name The name of the configuration option to get
+        * @return array
+        * @throws \ConfigException
+        */
+       public function get( $name ) {
+               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];
+       }
+
+       /**
+        * Returns an array of all configuration items saved in this ConfigRepository. This includes
+        * all configuration options, including the ones marked as private and public.
+        *
+        * Note: This function does not do any permission checks or something similar. You should not
+        * use this function, if the output will be available to the public audience! Use
+        * ConfigRepository::getPublic() instead.
+        *
+        * @return array
+        */
+       public function getAll() {
+               return array_merge( $this->configItems['private'], $this->configItems['public'] );
+       }
+
+       /**
+        * Returns an array of all public configuration options saved in this ConfigRepository.
+        *
+        * @return array
+        */
+       public function getPublic() {
+               return $this->configItems['public'];
+       }
+
+       /**
+        * Returns the current value of the configuration option. If no ConfigRegistry was provided
+        * when the config was added to the repository, the default value will be returned.
+        *
+        * @param string $name The name of the configuration option to get the value of
+        * @return mixed
+        * @throws \ConfigException
+        */
+       public function getValueOf( $name ) {
+               $config = $this->get( $name );
+               if ( !isset( $config['configregistry'] ) ) {
+                       return $config['value'];
+               }
+
+               return $this->configFactory->makeConfig( $config['configregistry'] )->get( $name );
+       }
+
+       /**
+        * Returns the description of the given config option, This can be either a localized
+        * description, if one such, or the (maybe english only) description provided in the
+        * definition of the configuration. If both is not provided an empty string is returned.
+        *
+        * @param string $name The name of the configuration option to get the description of
+        * @return string HTML-escaped string
+        */
+       public function getDescriptionOf( $name ) {
+               $config = $this->get( $name );
+               if ( isset( $config['descriptionmsg'] ) ) {
+                       return wfMessage( $config['descriptionmsg'] )->escaped();
+               }
+               if ( isset( $config['description'] ) ) {
+                       return htmlspecialchars( $config['description'] );
+               }
+               return '';
+       }
+
+       /**
+        * Adds the definition of a configuration to this repository.
+        *
+        * @param string $name the name of the config
+        * @param array $config Options of this config. Values are:
+        *  - value: The default value of this configuration, required
+        *  - providedby: The name of the provider of this config (an extension, core, ...), required
+        *  - configregistry: The name of the config to retrieve the value with, required
+        *  - public: whether this option is public or not, if not set, the option is considered as
+        *    "private", optional
+        *  - description: the not localized description of this config option, optional
+        *  - descriptionmsg: The message key of the localized description of this configuration
+        *    option, optional
+        * @throws \ConfigException
+        */
+       public function add( $name, array $config ) {
+               if ( $this->has( $name ) ) {
+                       throw new \ConfigException( 'A configuration with the name ' . $name .
+                               'does already exist. It is provided by: ' .
+                               $this->get( $name )['providedby'] );
+               }
+               if ( isset( $config['public'] ) && $config['public'] ) {
+                       $this->configItems['public'][$name] = $config;
+               } else {
+                       $this->configItems['private'][$name] = $config;
+               }
+       }
+
+       /**
+        * Returns true, if there're no elements in this instance, otherwise false.
+        *
+        * @param bool $includePrivate Whether configuration options, that are marked as private
+        * should be included in this check.
+        * @return bool
+        */
+       public function isEmpty( $includePrivate = false ) {
+               if ( $includePrivate ) {
+                       return empty( $this->configItems['private'] ) &&
+                               empty( $this->configItems[ 'public'] );
+               }
+               return empty( $this->configItems['public'] );
+       }
+
+       /**
+        * Re-uses existing Cache objects from $other. Cache objects are only re-used if the
+        * registered factory function for both is the same.
+        *
+        * @see SalvageableService::salvage()
+        *
+        * @param SalvageableService $other The object to salvage state from. $other must have the
+        * exact same type as $this.
+        */
+       public function salvage( SalvageableService $other ) {
+               Assert::parameterType( self::class, $other, '$other' );
+
+               /** @var ConfigRepository $other */
+               $otherCurrentObj = $other->current();
+               foreach ( $other->configItems['public'] as $name => $otherConfig ) {
+                       if ( isset( $this->configItems['public'][$name] ) ) {
+                               continue;
+                       }
+
+                       $this->add( $name, $otherConfig );
+
+                       // recover the pointer of the other config repository
+                       if ( $otherCurrentObj === $otherConfig ) {
+                               end( $this->configItems['public'] );
+                       }
+               }
+               foreach ( $other->configItems['private'] as $name => $otherConfig ) {
+                       if ( isset( $this->configItems['private'][$name] ) ) {
+                               continue;
+                       }
+
+                       $this->add( $name, $otherConfig );
+
+                       // recover the pointer of the other config repository
+                       if ( $otherCurrentObj === $otherConfig ) {
+                               end( $this->configItems['private'] );
+                       }
+               }
+
+               // disable $other
+               $other->configItems = [];
+       }
+}
index b21eadc..b6211b0 100644 (file)
@@ -43,7 +43,7 @@ abstract class AbstractContent implements Content {
        protected $model_id;
 
        /**
-        * @param string $modelId
+        * @param string|null $modelId
         *
         * @since 1.21
         */
@@ -145,7 +145,7 @@ abstract class AbstractContent implements Content {
        /**
         * @since 1.21
         *
-        * @param string $format
+        * @param string|null $format
         *
         * @return string
         *
@@ -182,7 +182,7 @@ abstract class AbstractContent implements Content {
        /**
         * @since 1.21
         *
-        * @param Content $that
+        * @param Content|null $that
         *
         * @return bool
         *
@@ -219,9 +219,9 @@ abstract class AbstractContent implements Content {
         * @since 1.21
         *
         * @param Title $title
-        * @param Content $old
+        * @param Content|null $old
         * @param bool $recursive
-        * @param ParserOutput $parserOutput
+        * @param ParserOutput|null $parserOutput
         *
         * @return DataUpdate[]
         *
@@ -501,7 +501,7 @@ abstract class AbstractContent implements Content {
                ParserOptions $options = null, $generateHtml = true
        ) {
                if ( $options === null ) {
-                       $options = $this->getContentHandler()->makeParserOptions( 'canonical' );
+                       $options = ParserOptions::newCanonical( 'canonical' );
                }
 
                $po = new ParserOutput();
index dfd46c8..e350fb3 100644 (file)
@@ -32,7 +32,7 @@ abstract class CodeContentHandler extends TextContentHandler {
         * Returns the English language, because code is English, and should be handled as such.
         *
         * @param Title $title
-        * @param Content $content
+        * @param Content|null $content
         *
         * @return Language
         *
@@ -46,7 +46,7 @@ abstract class CodeContentHandler extends TextContentHandler {
         * Returns the English language, because code is English, and should be handled as such.
         *
         * @param Title $title
-        * @param Content $content
+        * @param Content|null $content
         *
         * @return Language
         *
index 3e58782..000bff2 100644 (file)
@@ -162,7 +162,7 @@ interface Content {
         *
         * @since 1.21
         *
-        * @param string $format The desired serialization format, or null for the default format.
+        * @param string|null $format The desired serialization format, or null for the default format.
         *
         * @return string Serialized form of this Content object.
         */
@@ -210,7 +210,7 @@ interface Content {
         *
         * @since 1.21
         *
-        * @param Content $that The Content object to compare to.
+        * @param Content|null $that The Content object to compare to.
         *
         * @return bool True if this Content object is equal to $that, false otherwise.
         */
@@ -262,8 +262,8 @@ interface Content {
         *       may call ParserOutput::recordOption() on the output object.
         *
         * @param Title $title The page title to use as a context for rendering.
-        * @param int $revId Optional revision ID being rendered.
-        * @param ParserOptions $options Any parser options.
+        * @param int|null $revId Optional revision ID being rendered.
+        * @param ParserOptions|null $options Any parser options.
         * @param bool $generateHtml Whether to generate HTML (default: true). If false,
         *        the result of calling getText() on the ParserOutput object returned by
         *        this method is undefined.
@@ -296,12 +296,12 @@ interface Content {
         *   AbstractContent does.
         *
         * @param Title $title The context for determining the necessary updates
-        * @param Content $old An optional Content object representing the
+        * @param Content|null $old An optional Content object representing the
         *    previous content, i.e. the content being replaced by this Content
         *    object.
         * @param bool $recursive Whether to include recursive updates (default:
         *    false).
-        * @param ParserOutput $parserOutput Optional ParserOutput object.
+        * @param ParserOutput|null $parserOutput Optional ParserOutput object.
         *    Provide if you have one handy, to avoid re-parsing of the content.
         *
         * @return DataUpdate[] A list of DataUpdate objects for putting information
index 3cfac8f..79bbba8 100644 (file)
@@ -70,7 +70,7 @@ abstract class ContentHandler {
         *
         * @since 1.21
         *
-        * @param Content $content
+        * @param Content|null $content
         *
         * @throws MWException If the content is not an instance of TextContent and
         * wgContentHandlerTextFallback was set to 'fail'.
@@ -115,11 +115,11 @@ abstract class ContentHandler {
         *
         * @param string $text The textual representation, will be
         *    unserialized to create the Content object
-        * @param Title $title The title of the page this text belongs to.
+        * @param Title|null $title The title of the page this text belongs to.
         *    Required if $modelId is not provided.
-        * @param string $modelId The model to deserialize to. If not provided,
+        * @param string|null $modelId The model to deserialize to. If not provided,
         *    $title->getContentModel() is used.
-        * @param string $format The format to use for deserialization. If not
+        * @param string|null $format The format to use for deserialization. If not
         *    given, the model's default format is used.
         *
         * @throws MWException If model ID or format is not supported or if the text can not be
@@ -420,7 +420,7 @@ abstract class ContentHandler {
         * @since 1.21
         *
         * @param Content $content The Content object to serialize
-        * @param string $format The desired serialization format
+        * @param string|null $format The desired serialization format
         *
         * @return string Serialized form of the content
         */
@@ -446,7 +446,7 @@ abstract class ContentHandler {
         * @since 1.21
         *
         * @param string $blob Serialized form of the content
-        * @param string $format The format used for serialization
+        * @param string|null $format The format used for serialization
         *
         * @return Content The Content object created by deserializing $blob
         */
@@ -654,7 +654,7 @@ abstract class ContentHandler {
         * @since 1.21
         *
         * @param Title $title The page to determine the language for.
-        * @param Content $content The page's content, if you have it handy, to avoid reloading it.
+        * @param Content|null $content The page's content, if you have it handy, to avoid reloading it.
         *
         * @return Language The page's language
         */
@@ -689,7 +689,7 @@ abstract class ContentHandler {
         * @since 1.21
         *
         * @param Title $title The page to determine the language for.
-        * @param Content $content The page's content, if you have it handy, to avoid reloading it.
+        * @param Content|null $content The page's content, if you have it handy, to avoid reloading it.
         *
         * @return Language The page's language for viewing
         */
@@ -1069,7 +1069,7 @@ abstract class ContentHandler {
         * @param Revision $undo The revision to undo
         * @param Revision $undoafter Must be an earlier revision than $undo
         *
-        * @return mixed String on success, false on failure
+        * @return mixed Content on success, false on failure
         */
        public function getUndoContent( Revision $current, Revision $undo, Revision $undoafter ) {
                $cur_content = $current->getContent();
@@ -1114,6 +1114,8 @@ abstract class ContentHandler {
        /**
         * Get parser options suitable for rendering and caching the article
         *
+        * @deprecated since 1.32, use WikiPage::makeParserOptions() or
+        *  ParserOptions::newCanonical() instead.
         * @param IContextSource|User|string $context One of the following:
         *        - IContextSource: Use the User and the Language of the provided
         *                                            context
@@ -1126,22 +1128,8 @@ abstract class ContentHandler {
         * @return ParserOptions
         */
        public function makeParserOptions( $context ) {
-               global $wgContLang;
-
-               if ( $context instanceof IContextSource ) {
-                       $user = $context->getUser();
-                       $lang = $context->getLanguage();
-               } elseif ( $context instanceof User ) { // settings per user (even anons)
-                       $user = $context;
-                       $lang = null;
-               } elseif ( $context === 'canonical' ) { // canonical settings
-                       $user = new User;
-                       $lang = $wgContLang;
-               } else {
-                       throw new MWException( "Bad context for parser options: $context" );
-               }
-
-               return ParserOptions::newCanonical( $user, $lang );
+               wfDeprecated( __METHOD__, '1.32' );
+               return ParserOptions::newCanonical( $context );
        }
 
        /**
@@ -1310,7 +1298,7 @@ abstract class ContentHandler {
         * Specific content handlers may override it if they need different content handling.
         *
         * @param WikiPage $page
-        * @param ParserCache $cache
+        * @param ParserCache|null $cache
         * @return ParserOutput
         */
        public function getParserOutputForIndexing( WikiPage $page, ParserCache $cache = null ) {
index 4b58989..b21c6f4 100644 (file)
@@ -42,7 +42,7 @@ class MessageContent extends AbstractContent {
 
        /**
         * @param Message|string $msg A Message object, or a message key.
-        * @param string[] $params An optional array of message parameters.
+        * @param string[]|null $params An optional array of message parameters.
         */
        public function __construct( $msg, $params = null ) {
                # XXX: messages may be wikitext, html or plain text! and maybe even something else entirely.
@@ -148,8 +148,8 @@ class MessageContent extends AbstractContent {
 
        /**
         * @param Title $title Unused.
-        * @param int $revId Unused.
-        * @param ParserOptions $options Unused.
+        * @param int|null $revId Unused.
+        * @param ParserOptions|null $options Unused.
         * @param bool $generateHtml Whether to generate HTML (default: true).
         *
         * @return ParserOutput
index 71f65b3..c058296 100644 (file)
@@ -75,7 +75,7 @@ class TextContent extends AbstractContent {
 
                $text = $this->getNativeData();
 
-               $truncatedtext = $wgContLang->truncate(
+               $truncatedtext = $wgContLang->truncateForDatabase(
                        preg_replace( "/[\n\r]/", ' ', $text ),
                        max( 0, $maxlength ) );
 
@@ -194,7 +194,7 @@ class TextContent extends AbstractContent {
         * @since 1.21
         *
         * @param Content $that The other content object to compare this content object to.
-        * @param Language $lang The language object to use for text segmentation.
+        * @param Language|null $lang The language object to use for text segmentation.
         *    If not given, $wgContentLang is used.
         *
         * @return Diff A diff representing the changes that would have to be
index 4a7944c..0978ffc 100644 (file)
@@ -38,7 +38,7 @@ class TextContentHandler extends ContentHandler {
         * Returns the content's text as-is.
         *
         * @param Content $content
-        * @param string $format The serialization format to check
+        * @param string|null $format The serialization format to check
         *
         * @return mixed
         */
@@ -108,7 +108,7 @@ class TextContentHandler extends ContentHandler {
         * @since 1.21
         *
         * @param string $text Serialized form of the content
-        * @param string $format The format used for serialization
+        * @param string|null $format The format used for serialization
         *
         * @return Content The TextContent object wrapping $text
         */
index 5beef31..21947d2 100644 (file)
@@ -25,6 +25,8 @@
  * @author Daniel Kinzler
  */
 
+use MediaWiki\MediaWikiServices;
+
 /**
  * Content object for wiki text pages.
  *
@@ -182,7 +184,7 @@ class WikitextContent extends TextContent {
                        return $this->redirectTargetAndText;
                }
 
-               $redir = MagicWord::get( 'redirect' );
+               $redir = MediaWikiServices::getInstance()->getMagicWordFactory()->get( 'redirect' );
                $text = ltrim( $this->getNativeData() );
                if ( $redir->matchStartAndRemove( $text ) ) {
                        // Extract the first link and see if it's usable
index 9c26ae1..ab157f5 100644 (file)
@@ -23,6 +23,8 @@
  * @ingroup Content
  */
 
+use MediaWiki\MediaWikiServices;
+
 /**
  * Content handler for wiki text pages.
  *
@@ -60,7 +62,7 @@ class WikitextContentHandler extends TextContentHandler {
                        }
                }
 
-               $mwRedir = MagicWord::get( 'redirect' );
+               $mwRedir = MediaWikiServices::getInstance()->getMagicWordFactory()->get( 'redirect' );
                $redirectText = $mwRedir->getSynonym( 0 ) .
                        ' [[' . $optionalColon . $destination->getFullText() . ']]';
 
index 03fb9e2..6182538 100644 (file)
@@ -168,7 +168,7 @@ abstract class ContextSource implements IContextSource {
        public function msg( $key /* $args */ ) {
                $args = func_get_args();
 
-               return call_user_func_array( [ $this->getContext(), 'msg' ], $args );
+               return $this->getContext()->msg( ...$args );
        }
 
        /**
index f7a1815..acf6fcb 100644 (file)
@@ -296,6 +296,6 @@ class DerivativeContext extends ContextSource implements MutableContext {
        public function msg( $key ) {
                $args = func_get_args();
 
-               return call_user_func_array( 'wfMessage', $args )->setContext( $this );
+               return wfMessage( ...$args )->setContext( $this );
        }
 }
index db3a7a9..7563330 100644 (file)
@@ -423,7 +423,7 @@ class RequestContext implements IContextSource, MutableContext {
        public function msg( $key ) {
                $args = func_get_args();
 
-               return call_user_func_array( 'wfMessage', $args )->setContext( $this );
+               return wfMessage( ...$args )->setContext( $this );
        }
 
        /**
index beac91e..b6ccb53 100644 (file)
@@ -28,7 +28,7 @@ use Wikimedia\Rdbms\LoadBalancer;
  * @file
  * @ingroup Database
  *
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
  * @author Daniel Kinzler
  */
 abstract class DBAccessBase implements IDBAccessObject {
index e18a090..a555c55 100644 (file)
@@ -59,9 +59,9 @@ interface IDBAccessObject {
        /** @var int Read from the master/quorum */
        const READ_LATEST = 1;
        /* @var int Read from the master/quorum and lock out other writers */
-       const READ_LOCKING = 3; // READ_LATEST (1) and "LOCK IN SHARE MODE" (2)
+       const READ_LOCKING = self::READ_LATEST | 2; // READ_LATEST (1) and "LOCK IN SHARE MODE" (2)
        /** @var int Read from the master/quorum and lock out other writers and locking readers */
-       const READ_EXCLUSIVE = 7; // READ_LOCKING (3) and "FOR UPDATE" (4)
+       const READ_EXCLUSIVE = self::READ_LOCKING | 4; // READ_LOCKING (3) and "FOR UPDATE" (4)
 
        /** @var int Read from a replica DB or without a quorum, using the master/quorum on miss */
        const READ_LATEST_IMMUTABLE = 8;
index edb54ae..1564fab 100644 (file)
@@ -46,7 +46,7 @@ class CloneDatabase {
         * @param IMaintainableDatabase $db A database subclass
         * @param array $tablesToClone An array of tables to clone, unprefixed
         * @param string $newTablePrefix Prefix to assign to the tables
-        * @param string $oldTablePrefix Prefix on current tables, if not $wgDBprefix
+        * @param string|null $oldTablePrefix Prefix on current tables, if not $wgDBprefix
         * @param bool $dropCurrentTables
         */
        public function __construct( IMaintainableDatabase $db, array $tablesToClone,
@@ -55,7 +55,7 @@ class CloneDatabase {
                $this->db = $db;
                $this->tablesToClone = $tablesToClone;
                $this->newTablePrefix = $newTablePrefix;
-               $this->oldTablePrefix = $oldTablePrefix !== null ? $oldTablePrefix : $this->db->tablePrefix();
+               $this->oldTablePrefix = $oldTablePrefix ?? $this->db->tablePrefix();
                $this->dropCurrentTables = $dropCurrentTables;
        }
 
@@ -82,10 +82,10 @@ class CloneDatabase {
                        # works correctly across DB engines, we need to change the pre-
                        # fix back and forth so tableName() works right.
 
-                       self::changePrefix( $this->oldTablePrefix );
+                       $this->db->tablePrefix( $this->oldTablePrefix );
                        $oldTableName = $this->db->tableName( $tbl, 'raw' );
 
-                       self::changePrefix( $this->newTablePrefix );
+                       $this->db->tablePrefix( $this->newTablePrefix );
                        $newTableName = $this->db->tableName( $tbl, 'raw' );
 
                        // Postgres: Temp tables are automatically deleted upon end of session
@@ -116,12 +116,12 @@ class CloneDatabase {
         */
        public function destroy( $dropTables = false ) {
                if ( $dropTables ) {
-                       self::changePrefix( $this->newTablePrefix );
+                       $this->db->tablePrefix( $this->newTablePrefix );
                        foreach ( $this->tablesToClone as $tbl ) {
                                $this->db->dropTable( $tbl );
                        }
                }
-               self::changePrefix( $this->oldTablePrefix );
+               $this->db->tablePrefix( $this->oldTablePrefix );
        }
 
        /**
index 3362f0f..f4f04f1 100644 (file)
@@ -675,7 +675,7 @@ class DatabaseOracle extends Database {
                }
                $table = strtolower( $this->removeIdentifierQuotes( $this->tableName( $table ) ) );
 
-               return ( isset( $this->sequenceData[$table] ) ) ? $this->sequenceData[$table] : false;
+               return $this->sequenceData[$table] ?? false;
        }
 
        /**
index 79f787d..e50f855 100644 (file)
@@ -65,6 +65,7 @@ abstract class MWLBFactory {
                        'cliMode' => $wgCommandLineMode,
                        'hostname' => wfHostname(),
                        'readOnlyReason' => $readOnlyMode->getReason(),
+                       'defaultGroup' => $mainConfig->get( 'DBDefaultGroup' ),
                ];
 
                // When making changes here, remember to also specify MediaWiki-specific options
diff --git a/includes/db/PatchFileLocation.php b/includes/db/PatchFileLocation.php
new file mode 100644 (file)
index 0000000..d2787fa
--- /dev/null
@@ -0,0 +1,90 @@
+<?php
+/**
+ * Trait for finding SQL patch files.
+ *
+ * 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\DB;
+
+use RuntimeException;
+use Wikimedia\Rdbms\IDatabase;
+
+/**
+ * Trait for finding SQL patch files.
+ *
+ * @since 1.32
+ */
+trait PatchFileLocation {
+
+       /**
+        * Utility function for finding the appropriate SQL patch file for the currently
+        * used database type.
+        *
+        * The file will be searched for in the following locations, in order of preference:
+        *   "$patchDir/$name.$dbType.sql",
+        *   "$patchDir/$dbType/$name.sql",
+        *   "$patchDir/$dbType/archives/$name.sql",
+        *   "$patchDir/$name.sql",
+        *   "$patchDir/archives/$name.sql"
+        *
+        * @param IDatabase $db
+        * @param string $name The script name (relative to $patchDir, without the '.sql' suffix)
+        * @param string|null $patchDir The directory to find the script in. Use __DIR__ to search in the
+        *        directory the calling code is located in. If omitted, the "maintenance"
+        *        directory will be used, where the scripts used by the updater are located.
+        *
+        * @return string
+        * @throws RuntimeException if no matching patch file could be found.
+        */
+       protected function getSqlPatchPath( IDatabase $db, $name, $patchDir = null ) {
+               $dbType = $db->getType();
+
+               if ( $patchDir === null ) {
+                       $patchDir = $GLOBALS['IP'] . '/maintenance';
+               }
+
+               $paths = [
+
+                       // For a small number of patch files, closely associated with code,
+                       // e.g. for unit tests:
+                       "$patchDir/$name.$dbType.sql",
+
+                       // For a large number of patch files, e.g. for schema updates of extensions:
+                       "$patchDir/$dbType/$name.sql",
+
+                       // For MediaWiki core schema update patches:
+                       "$patchDir/$dbType/archives/$name.sql",
+
+                       // Database-agnostic fallback:
+                       "$patchDir/$name.sql",
+
+                       // Database-agnostic fallback for MediaWiki core schema update patches:
+                       "$patchDir/archives/$name.sql"
+               ];
+
+               foreach ( $paths as $p ) {
+                       if ( file_exists( $p ) ) {
+                               return $p;
+                       }
+               }
+
+               throw new RuntimeException( "No SQL script matching $name could be found in $patchDir" );
+       }
+
+}
diff --git a/includes/debug/DeprecationHelper.php b/includes/debug/DeprecationHelper.php
new file mode 100644 (file)
index 0000000..cd78005
--- /dev/null
@@ -0,0 +1,148 @@
+<?php
+/**
+ * Trait for issuing warnings on deprecated access.
+ *
+ * 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 this trait in classes which have properties for which public access
+ * is deprecated. Set the list of properties in $deprecatedPublicProperties
+ * and make the properties non-public. The trait will preserve public access
+ * but issue deprecation warnings when it is needed.
+ *
+ * Example usage:
+ *     class Foo {
+ *         use DeprecationHelper;
+ *         protected $bar;
+ *         public function __construct() {
+ *             $this->deprecatePublicProperty( 'bar', '1.21', __CLASS__ );
+ *         }
+ *     }
+ *
+ *     $foo = new Foo;
+ *     $foo->bar; // works but logs a warning
+ *
+ * Cannot be used with classes that have their own __get/__set methods.
+ *
+ * @since 1.32
+ */
+trait DeprecationHelper {
+
+       /**
+        * List of deprecated properties, in <property name> => [<version>, <class>, <component>] format
+        * where <version> is the MediaWiki version where the property got deprecated, <class> is the
+        * 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[]
+        */
+       protected $deprecatedPublicProperties = [];
+
+       /**
+        * Mark a property as deprecated. Only use this for properties that used to be public and only
+        *   call it in the constructor.
+        * @param string $property The name of the property.
+        * @param string $version MediaWiki version where the property became deprecated.
+        * @param string|null $class The class which has the deprecated property. This can usually be
+        *   guessed, but PHP can get confused when both the parent class and the subclass use the
+        *   trait, so it should be specified in classes meant for subclassing.
+        * @param string|null $component
+        * @see wfDeprecated()
+        */
+       protected function deprecatePublicProperty(
+               $property, $version, $class = null, $component = null
+       ) {
+               $this->deprecatedPublicProperties[$property] = [ $version, $class ?: get_class(), $component ];
+       }
+
+       public function __get( $name ) {
+               if ( isset( $this->deprecatedPublicProperties[$name] ) ) {
+                       list( $version, $class, $component ) = $this->deprecatedPublicProperties[$name];
+                       $qualifiedName = $class . '::$' . $name;
+                       wfDeprecated( $qualifiedName, $version, $component, 3 );
+                       return $this->$name;
+               }
+
+               $qualifiedName = get_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 );
+               } else {
+                       // Non-existing property. Try to behave like PHP would.
+                       trigger_error( "Undefined property: $qualifiedName", E_USER_NOTICE );
+               }
+               return null;
+       }
+
+       public function __set( $name, $value ) {
+               if ( isset( $this->deprecatedPublicProperties[$name] ) ) {
+                       list( $version, $class, $component ) = $this->deprecatedPublicProperties[$name];
+                       $qualifiedName = $class . '::$' . $name;
+                       wfDeprecated( $qualifiedName, $version, $component, 3 );
+                       $this->$name = $value;
+                       return;
+               }
+
+               $qualifiedName = get_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 );
+               } else {
+                       // Non-existing property. Try to behave like PHP would.
+                       $this->$name = $value;
+               }
+       }
+
+       /**
+        * Like property_exists but also check for non-visible private properties and returns which
+        * class in the inheritance chain declared the property.
+        * @param string $property
+        * @return string|bool Best guess for the class in which the property is defined.
+        */
+       private function deprecationHelperGetPropertyOwner( $property ) {
+               // Easy branch: check for protected property / private property of the current class.
+               if ( property_exists( $this, $property ) ) {
+                       // The class name is not necessarily correct here but getting the correct class
+                       // name would be expensive, this will work most of the time and getting it
+                       // wrong is not a big deal.
+                       return __CLASS__;
+               }
+               // property_exists() returns false when the property does exist but is private (and not
+               // defined by the current class, for some value of "current" that differs slightly
+               // between engines).
+               // Since PHP triggers an error on public access of non-public properties but happily
+               // allows public access to undefined properties, we need to detect this case as well.
+               // Reflection is slow so use array cast hack to check for that:
+               $obfuscatedProps = array_keys( (array)$this );
+               $obfuscatedPropTail = "\0$property";
+               foreach ( $obfuscatedProps as $obfuscatedProp ) {
+                       // private props are in the form \0<classname>\0<propname>
+                       if ( strpos( $obfuscatedProp, $obfuscatedPropTail, 1 ) !== false ) {
+                               $classname = substr( $obfuscatedProp, 1, -strlen( $obfuscatedPropTail ) );
+                               if ( $classname === '*' ) {
+                                       // sanity; this shouldn't be possible as protected properties were handled earlier
+                                       $classname = __CLASS__;
+                               }
+                               return $classname;
+                       }
+               }
+               return false;
+       }
+
+}
index ec27ad1..ff653ab 100644 (file)
@@ -179,9 +179,7 @@ class MonologSpi implements Spi {
                if ( !isset( $this->singletons['loggers'][$channel] ) ) {
                        // Fallback to using the '@default' configuration if an explict
                        // configuration for the requested channel isn't found.
-                       $spec = isset( $this->config['loggers'][$channel] ) ?
-                               $this->config['loggers'][$channel] :
-                               $this->config['loggers']['@default'];
+                       $spec = $this->config['loggers'][$channel] ?? $this->config['loggers']['@default'];
 
                        $monolog = $this->createLogger( $channel, $spec );
                        $this->singletons['loggers'][$channel] = $monolog;
@@ -201,7 +199,7 @@ class MonologSpi implements Spi {
 
                if ( isset( $spec['calls'] ) ) {
                        foreach ( $spec['calls'] as $method => $margs ) {
-                               call_user_func_array( [ $obj, $method ], $margs );
+                               $obj->$method( ...$margs );
                        }
                }
 
index cdc4da3..8537d71 100644 (file)
@@ -42,8 +42,8 @@ use MWExceptionHandler;
 class LineFormatter extends MonologLineFormatter {
 
        /**
-        * @param string $format The format of the message
-        * @param string $dateFormat The format of the timestamp: one supported by DateTime::format
+        * @param string|null $format The format of the message
+        * @param string|null $dateFormat The format of the timestamp: one supported by DateTime::format
         * @param bool $allowInlineLineBreaks Whether to allow inline line breaks in log entries
         * @param bool $ignoreEmptyContextAndExtra
         * @param bool $includeStacktraces
@@ -164,7 +164,7 @@ class LineFormatter extends MonologLineFormatter {
                                                );
                                }
 
-                               $prev = isset( $prev['previous'] ) ? $prev['previous'] : null;
+                               $prev = $prev['previous'] ?? null;
                        }
                }
                return $str;
index f9297af..8507157 100644 (file)
@@ -39,7 +39,7 @@ class AutoCommitUpdate implements DeferrableUpdate, DeferrableCallback {
                try {
                        /** @var Exception $e */
                        $e = null;
-                       call_user_func_array( $this->callback, [ $this->dbw, $this->fname ] );
+                       ( $this->callback )( $this->dbw, $this->fname );
                } catch ( Exception $e ) {
                }
                if ( $autoTrx ) {
index 3c86d11..f370e43 100644 (file)
@@ -90,6 +90,7 @@ class LinksDeletionUpdate extends DataUpdate implements EnqueueableDataUpdate {
                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() ]
                                );
@@ -98,19 +99,11 @@ class LinksDeletionUpdate extends DataUpdate implements EnqueueableDataUpdate {
 
                // Refresh counts on categories that should be empty now
                if ( $title->getNamespace() === NS_CATEGORY ) {
-                       $row = $dbw->selectRow(
-                               'category',
-                               [ 'cat_id', 'cat_title', 'cat_pages', 'cat_subcats', 'cat_files' ],
-                               [ 'cat_title' => $title->getDBkey(), 'cat_pages <= 100' ],
-                               __METHOD__
-                       );
-                       if ( $row ) {
-                               $cat = Category::newFromRow( $row, $title );
-                               // T166757: do the update after the main job DB commit
-                               DeferredUpdates::addCallableUpdate( function () use ( $cat ) {
-                                       $cat->refreshCounts();
-                               } );
-                       }
+                       // T166757: do the update after the main job DB commit
+                       DeferredUpdates::addCallableUpdate( function () use ( $title ) {
+                               $cat = Category::newFromName( $title->getDBkey() );
+                               $cat->refreshCountsIfEmpty();
+                       } );
                }
 
                $this->batchDeleteByPK(
index 398df01..141888c 100644 (file)
@@ -141,14 +141,9 @@ class LinksUpdate extends DataUpdate implements EnqueueableDataUpdate {
                }
 
                foreach ( $this->mCategories as &$sortkey ) {
-                       # If the sortkey is longer then 255 bytes,
-                       # it truncated by DB, and then doesn't get
-                       # matched when comparing existing vs current
-                       # categories, causing T27254.
-                       # Also. substr behaves weird when given "".
-                       if ( $sortkey !== '' ) {
-                               $sortkey = substr( $sortkey, 0, 255 );
-                       }
+                       # If the sortkey is longer then 255 bytes, it is truncated by DB, and then doesn't match
+                       # when comparing existing vs current categories, causing T27254.
+                       $sortkey = mb_strcut( $sortkey, 0, 255 );
                }
 
                $this->mRecursive = $recursive;
@@ -161,7 +156,7 @@ class LinksUpdate extends DataUpdate implements EnqueueableDataUpdate {
        /**
         * Update link tables with outgoing links from an updated article
         *
-        * @note: this is managed by DeferredUpdates::execute(). Do not run this in a transaction.
+        * @note this is managed by DeferredUpdates::execute(). Do not run this in a transaction.
         */
        public function doUpdate() {
                if ( $this->ticket ) {
@@ -593,13 +588,7 @@ class LinksUpdate extends DataUpdate implements EnqueueableDataUpdate {
                        $nt = Title::makeTitleSafe( NS_CATEGORY, $name );
                        $wgContLang->findVariantLink( $name, $nt, true );
 
-                       if ( $this->mTitle->getNamespace() == NS_CATEGORY ) {
-                               $type = 'subcat';
-                       } elseif ( $this->mTitle->getNamespace() == NS_FILE ) {
-                               $type = 'file';
-                       } else {
-                               $type = 'page';
-                       }
+                       $type = MWNamespace::getCategoryLinkType( $this->mTitle->getNamespace() );
 
                        # Treat custom sortkeys as a prefix, so that if multiple
                        # things are forced to sort as '*' or something, they'll
index 2766bcb..0d1de1a 100644 (file)
@@ -113,7 +113,7 @@ class SearchUpdate implements DeferrableUpdate {
         * If you're using a real search engine, you'll probably want to override
         * this behavior and do something nicer with the original wikitext.
         * @param string $text
-        * @param SearchEngine $se Search engine
+        * @param SearchEngine|null $se Search engine
         * @return string
         */
        public function updateText( $text, SearchEngine $se = null ) {
index d76af31..063f826 100644 (file)
@@ -66,7 +66,7 @@ abstract class DiffOp {
        }
 
        /**
-        * @param int $i
+        * @param int|null $i
         * @return string[]|string|null
         */
        public function getClosing( $i = null ) {
index 273d1d6..142c51d 100644 (file)
@@ -351,7 +351,7 @@ class DiffEngine {
                        $this->maxDifferences = ceil( ( $this->m + $this->n ) / 2.0 );
                        if ( $this->m * $this->n > $this->tooLong ) {
                                // limit complexity to D^POW_LIMIT for long sequences
-                               $this->maxDifferences = floor( pow( $this->maxDifferences, $this->powLimit - 1.0 ) );
+                               $this->maxDifferences = floor( $this->maxDifferences ** ( $this->powLimit - 1.0 ) );
                                wfDebug( "Limiting max number of differences to $this->maxDifferences\n" );
                        }
 
index b1ca435..aa0a1f7 100644 (file)
@@ -28,6 +28,9 @@ use MediaWiki\Shell\Shell;
  * @ingroup DifferenceEngine
  */
 class DifferenceEngine extends ContextSource {
+
+       use DeprecationHelper;
+
        /**
         * Constant to indicate diff cache compatibility.
         * Bump this when changing the diff formatting in a way that
@@ -36,47 +39,54 @@ class DifferenceEngine extends ContextSource {
         */
        const DIFF_VERSION = '1.12';
 
-       /** @var int */
-       public $mOldid;
+       /** @var int Revision ID or 0 for current */
+       protected $mOldid;
 
-       /** @var int */
-       public $mNewid;
+       /** @var int|string Revision ID or null for current or an alias such as 'next' */
+       protected $mNewid;
 
        private $mOldTags;
        private $mNewTags;
 
-       /** @var Content */
-       public $mOldContent;
+       /** @var Content|null */
+       protected $mOldContent;
 
-       /** @var Content */
-       public $mNewContent;
+       /** @var Content|null */
+       protected $mNewContent;
 
        /** @var Language */
        protected $mDiffLang;
 
        /** @var Title */
-       public $mOldPage;
+       protected $mOldPage;
 
        /** @var Title */
-       public $mNewPage;
+       protected $mNewPage;
 
-       /** @var Revision */
+       /** @var Revision|null */
        public $mOldRev;
 
-       /** @var Revision */
+       /** @var Revision|null */
        public $mNewRev;
 
        /** @var bool Have the revisions IDs been loaded */
        private $mRevisionsIdsLoaded = false;
 
        /** @var bool Have the revisions been loaded */
-       public $mRevisionsLoaded = false;
+       protected $mRevisionsLoaded = false;
 
        /** @var int How many text blobs have been loaded, 0, 1 or 2? */
-       public $mTextLoaded = 0;
+       protected $mTextLoaded = 0;
+
+       /**
+        * Was the content overridden via setContent()?
+        * If the content was overridden, most internal state (e.g. mOldid or mOldRev) should be ignored.
+        * @var bool
+        */
+       protected $isContentOverridden = false;
 
        /** @var bool Was the diff fetched from cache? */
-       public $mCacheHit = false;
+       protected $mCacheHit = false;
 
        /**
         * Set this to true to add debug info to the HTML output.
@@ -102,7 +112,7 @@ class DifferenceEngine extends ContextSource {
        /**#@-*/
 
        /**
-        * @param IContextSource $context Context to use, anything else will be ignored
+        * @param IContextSource|null $context Context to use, anything else will be ignored
         * @param int $old Old ID we want to show and diff with.
         * @param string|int $new Either revision ID or 'prev' or 'next'. Default: 0.
         * @param int $rcid Deprecated, no longer used!
@@ -112,6 +122,16 @@ class DifferenceEngine extends ContextSource {
        public function __construct( $context = null, $old = 0, $new = 0, $rcid = 0,
                $refreshCache = false, $unhide = false
        ) {
+               $this->deprecatePublicProperty( 'mOldid', '1.32', __CLASS__ );
+               $this->deprecatePublicProperty( 'mNewid', '1.32', __CLASS__ );
+               $this->deprecatePublicProperty( 'mOldPage', '1.32', __CLASS__ );
+               $this->deprecatePublicProperty( 'mNewPage', '1.32', __CLASS__ );
+               $this->deprecatePublicProperty( 'mOldContent', '1.32', __CLASS__ );
+               $this->deprecatePublicProperty( 'mNewContent', '1.32', __CLASS__ );
+               $this->deprecatePublicProperty( 'mRevisionsLoaded', '1.32', __CLASS__ );
+               $this->deprecatePublicProperty( 'mTextLoaded', '1.32', __CLASS__ );
+               $this->deprecatePublicProperty( 'mCacheHit', '1.32', __CLASS__ );
+
                if ( $context instanceof IContextSource ) {
                        $this->setContext( $context );
                }
@@ -132,6 +152,8 @@ class DifferenceEngine extends ContextSource {
        }
 
        /**
+        * Get the language of the difference engine, defaults to page content language
+        *
         * @return Language
         */
        public function getDiffLang() {
@@ -312,7 +334,7 @@ class DifferenceEngine extends ContextSource {
                                        $rollbackLink = Linker::generateRollback( $this->mNewRev, $this->getContext() );
                                        if ( $rollbackLink ) {
                                                $out->preventClickjacking();
-                                               $rollback = '&#160;&#160;&#160;' . $rollbackLink;
+                                               $rollback = "\u{00A0}\u{00A0}\u{00A0}" . $rollbackLink;
                                        }
                                }
 
@@ -342,7 +364,7 @@ class DifferenceEngine extends ContextSource {
                                        [ 'diff' => 'prev', 'oldid' => $this->mOldid ] + $query
                                );
                        } else {
-                               $prevlink = '&#160;';
+                               $prevlink = "\u{00A0}";
                        }
 
                        if ( $this->mOldRev->isMinor() ) {
@@ -395,7 +417,7 @@ class DifferenceEngine extends ContextSource {
                                [ 'diff' => 'next', 'oldid' => $this->mNewid ] + $query
                        );
                } else {
-                       $nextlink = '&#160;';
+                       $nextlink = "\u{00A0}";
                }
 
                if ( $this->mNewRev->isMinor() ) {
@@ -586,7 +608,7 @@ class DifferenceEngine extends ContextSource {
        protected function revisionDeleteLink( $rev ) {
                $link = Linker::getRevDeleteLink( $this->getUser(), $rev, $rev->getTitle() );
                if ( $link !== '' ) {
-                       $link = '&#160;&#160;&#160;' . $link . ' ';
+                       $link = "\u{00A0}\u{00A0}\u{00A0}" . $link . ' ';
                }
 
                return $link;
@@ -756,10 +778,7 @@ class DifferenceEngine extends ContextSource {
                        // for backwards-compatibility
                        $key = $this->getDiffBodyCacheKey();
                        if ( $key === null ) {
-                               $key = call_user_func_array(
-                                       [ $cache, 'makeKey' ],
-                                       $this->getDiffBodyCacheKeyParams()
-                               );
+                               $key = $cache->makeKey( ...$this->getDiffBodyCacheKeyParams() );
                        }
 
                        // Try cache
@@ -947,7 +966,7 @@ class DifferenceEngine extends ContextSource {
                        wfDeprecated( "\$wgExternalDiffEngine = '{$wgExternalDiffEngine}'", '1.27' );
                        $wgExternalDiffEngine = false;
                } elseif ( $wgExternalDiffEngine == 'wikidiff2' ) {
-                       // Same as above, but with no deprecation warnings
+                       wfDeprecated( "\$wgExternalDiffEngine = '{$wgExternalDiffEngine}'", '1.32' );
                        $wgExternalDiffEngine = false;
                } elseif ( !is_string( $wgExternalDiffEngine ) && $wgExternalDiffEngine !== false ) {
                        // And prevent people from shooting themselves in the foot...
@@ -1342,15 +1361,19 @@ class DifferenceEngine extends ContextSource {
 
                $this->mTextLoaded = 2;
                $this->mRevisionsLoaded = true;
+               $this->isContentOverridden = true;
        }
 
        /**
         * Set the language in which the diff text is written
-        * (Defaults to page content language).
-        * @param Language|string $lang
+        *
+        * @param Language $lang
         * @since 1.19
         */
        public function setTextLanguage( $lang ) {
+               if ( !$lang instanceof Language ) {
+                       wfDeprecated( __METHOD__ . ' with other type than Language for $lang', '1.32' );
+               }
                $this->mDiffLang = wfGetLangObj( $lang );
        }
 
@@ -1418,11 +1441,11 @@ class DifferenceEngine extends ContextSource {
         * to false. This is impossible via ordinary user input, and is provided for
         * API convenience.
         *
-        * @return bool
+        * @return bool Whether both revisions were loaded successfully.
         */
        public function loadRevisionData() {
                if ( $this->mRevisionsLoaded ) {
-                       return true;
+                       return $this->isContentOverridden || $this->mNewRev && $this->mOldRev;
                }
 
                // Whether it succeeds or fails, we don't want to try again
@@ -1498,11 +1521,11 @@ class DifferenceEngine extends ContextSource {
        /**
         * Load the text of the revisions, as well as revision data.
         *
-        * @return bool
+        * @return bool Whether the content of both revisions could be loaded successfully.
         */
        public function loadText() {
                if ( $this->mTextLoaded == 2 ) {
-                       return true;
+                       return $this->loadRevisionData() && $this->mOldContent && $this->mNewContent;
                }
 
                // Whether it succeeds or fails, we don't want to try again
@@ -1533,11 +1556,11 @@ class DifferenceEngine extends ContextSource {
        /**
         * Load the text of the new revision, not the old one
         *
-        * @return bool
+        * @return bool Whether the content of the new revision could be loaded successfully.
         */
        public function loadNewText() {
                if ( $this->mTextLoaded >= 1 ) {
-                       return true;
+                       return $this->loadRevisionData();
                }
 
                $this->mTextLoaded = 1;
index 67f9a79..845c2bc 100644 (file)
@@ -43,9 +43,9 @@ class TableDiffFormatter extends DiffFormatter {
         * @return mixed
         */
        public static function escapeWhiteSpace( $msg ) {
-               $msg = preg_replace( '/^ /m', '&#160; ', $msg );
-               $msg = preg_replace( '/ $/m', ' &#160;', $msg );
-               $msg = preg_replace( '/  /', '&#160; ', $msg );
+               $msg = preg_replace( '/^ /m', "\u{00A0} ", $msg );
+               $msg = preg_replace( '/ $/m', " \u{00A0}", $msg );
+               $msg = preg_replace( '/  /', "\u{00A0} ", $msg );
 
                return $msg;
        }
@@ -123,7 +123,7 @@ class TableDiffFormatter extends DiffFormatter {
         * @return string
         */
        protected function contextLine( $line ) {
-               return $this->wrapLine( '&#160;', 'diff-context', $line );
+               return $this->wrapLine( "\u{00A0}", 'diff-context', $line );
        }
 
        /**
@@ -146,7 +146,7 @@ class TableDiffFormatter extends DiffFormatter {
         * @return string
         */
        protected function emptyLine() {
-               return '<td colspan="2">&#160;</td>';
+               return "<td colspan=\"2\">\u{00A0}</td>";
        }
 
        /**
index 88631ed..aefcfb7 100644 (file)
@@ -66,7 +66,7 @@ class WordAccumulator {
                        array_push( $this->lines, $this->line );
                } else {
                        # make empty lines visible by inserting an NBSP
-                       array_push( $this->lines, '&#160;' );
+                       array_push( $this->lines, "\u{00A0}" );
                }
                $this->line = '';
        }
index 910d221..7007316 100644 (file)
@@ -27,6 +27,8 @@ use ParserOutput;
 /**
  * Represents information returned by WikiPage::prepareContentForEdit()
  *
+ * @deprecated since 1.32, use DerivedPageDataUpdater instead.
+ *
  * @since 1.30
  */
 class PreparedEdit {
index f5f8c84..c0182d5 100644 (file)
@@ -46,7 +46,8 @@ class LocalizedException extends Exception implements ILocalizedException {
        /**
         * @param string|array|MessageSpecifier $messageSpec See Message::newFromSpecifier
         * @param int $code
-        * @param Exception|Throwable $previous The previous exception used for the exception chaining.
+        * @param Exception|Throwable|null $previous The previous exception used for the exception
+        *  chaining.
         */
        public function __construct( $messageSpec, $code = 0, $previous = null ) {
                $this->messageSpec = $messageSpec;
index 79f0a23..00dca9d 100644 (file)
@@ -161,8 +161,8 @@ class MWExceptionHandler {
         *
         * @param int $level Error level raised
         * @param string $message
-        * @param string $file
-        * @param int $line
+        * @param string|null $file
+        * @param int|null $line
         * @return bool
         *
         * @see logError()
@@ -173,9 +173,7 @@ class MWExceptionHandler {
                global $wgPropagateErrors;
 
                if ( in_array( $level, self::$fatalErrorTypes ) ) {
-                       return call_user_func_array(
-                               'MWExceptionHandler::handleFatalError', func_get_args()
-                       );
+                       return self::handleFatalError( ...func_get_args() );
                }
 
                // Map error constant to error name (reverse-engineer PHP error
@@ -233,12 +231,12 @@ class MWExceptionHandler {
         *
         * @since 1.25
         *
-        * @param int $level Error level raised
-        * @param string $message Error message
-        * @param string $file File that error was raised in
-        * @param int $line Line number error was raised at
-        * @param array $context Active symbol table point of error
-        * @param array $trace Backtrace at point of error (undocumented HHVM
+        * @param int|null $level Error level raised
+        * @param string|null $message Error message
+        * @param string|null $file File that error was raised in
+        * @param int|null $line Line number error was raised at
+        * @param array|null $context Active symbol table point of error
+        * @param array|null $trace Backtrace at point of error (undocumented HHVM
         *     feature)
         * @return bool Always returns false
         */
index dc8dfd0..49cf71e 100644 (file)
@@ -19,7 +19,6 @@
  */
 
 use Wikimedia\Rdbms\DBConnectionError;
-use Wikimedia\Rdbms\DBError;
 use Wikimedia\Rdbms\DBReadOnlyError;
 use Wikimedia\Rdbms\DBExpectedError;
 
@@ -37,7 +36,7 @@ class MWExceptionRenderer {
         * @param Exception|Throwable|null $eNew New exception from attempting to show the first
         */
        public static function output( $e, $mode, $eNew = null ) {
-               global $wgMimeType;
+               global $wgMimeType, $wgShowExceptionDetails;
 
                if ( defined( 'MW_API' ) ) {
                        // Unhandled API exception, we can't be sure that format printer is alive
@@ -47,16 +46,18 @@ class MWExceptionRenderer {
                        self::printError( self::getText( $e ) );
                } elseif ( $mode === self::AS_PRETTY ) {
                        self::statusHeader( 500 );
+                       self::header( "Content-Type: $wgMimeType; charset=utf-8" );
                        if ( $e instanceof DBConnectionError ) {
                                self::reportOutageHTML( $e );
                        } else {
-                               self::header( "Content-Type: $wgMimeType; charset=utf-8" );
                                self::reportHTML( $e );
                        }
                } else {
+                       self::statusHeader( 500 );
+                       self::header( "Content-Type: $wgMimeType; charset=utf-8" );
                        if ( $eNew ) {
                                $message = "MediaWiki internal error.\n\n";
-                               if ( self::showBackTrace( $e ) ) {
+                               if ( $wgShowExceptionDetails ) {
                                        $message .= 'Original exception: ' .
                                                MWExceptionHandler::getLogMessage( $e ) .
                                                "\nBacktrace:\n" . MWExceptionHandler::getRedactedTraceAsString( $e ) .
@@ -71,7 +72,7 @@ class MWExceptionRenderer {
                                }
                                $message .= "\n";
                        } else {
-                               if ( self::showBackTrace( $e ) ) {
+                               if ( $wgShowExceptionDetails ) {
                                        $message = MWExceptionHandler::getLogMessage( $e ) .
                                                "\nBacktrace:\n" .
                                                MWExceptionHandler::getRedactedTraceAsString( $e ) . "\n";
@@ -160,7 +161,9 @@ class MWExceptionRenderer {
         * @return string Html to output
         */
        public static function getHTML( $e ) {
-               if ( self::showBackTrace( $e ) ) {
+               global $wgShowExceptionDetails;
+
+               if ( $wgShowExceptionDetails ) {
                        $html = "<div class=\"errorbox mw-content-ltr\"><p>" .
                                nl2br( htmlspecialchars( MWExceptionHandler::getLogMessage( $e ) ) ) .
                                '</p><p>Backtrace:</p><p>' .
@@ -207,7 +210,9 @@ class MWExceptionRenderer {
         * @return string
         */
        private static function getText( $e ) {
-               if ( self::showBackTrace( $e ) ) {
+               global $wgShowExceptionDetails;
+
+               if ( $wgShowExceptionDetails ) {
                        return MWExceptionHandler::getLogMessage( $e ) .
                                "\nBacktrace:\n" .
                                MWExceptionHandler::getRedactedTraceAsString( $e ) . "\n";
@@ -216,34 +221,13 @@ class MWExceptionRenderer {
                }
        }
 
-       /**
-        * @param Exception|Throwable $e
-        * @return bool
-        */
-       private static function showBackTrace( $e ) {
-               global $wgShowExceptionDetails, $wgShowDBErrorBacktrace;
-
-               return (
-                       $wgShowExceptionDetails &&
-                       ( !( $e instanceof DBError ) || $wgShowDBErrorBacktrace )
-               );
-       }
-
        /**
         * @param Exception|Throwable $e
         * @return string
         */
        private static function getShowBacktraceError( $e ) {
-               global $wgShowExceptionDetails, $wgShowDBErrorBacktrace;
-               $vars = [];
-               if ( !$wgShowExceptionDetails ) {
-                       $vars[] = '$wgShowExceptionDetails = true;';
-               }
-               if ( $e instanceof DBError && !$wgShowDBErrorBacktrace ) {
-                       $vars[] = '$wgShowDBErrorBacktrace = true;';
-               }
-               $vars = implode( ' and ', $vars );
-               return "Set $vars at the bottom of LocalSettings.php to show detailed debugging information.";
+               $var = '$wgShowExceptionDetails = true;';
+               return "Set $var at the bottom of LocalSettings.php to show detailed debugging information.";
        }
 
        /**
@@ -292,7 +276,7 @@ class MWExceptionRenderer {
         * @param Exception|Throwable $e
         */
        private static function reportOutageHTML( $e ) {
-               global $wgShowDBErrorBacktrace, $wgShowHostnames, $wgShowSQLErrors;
+               global $wgShowExceptionDetails, $wgShowHostnames, $wgSitename;
 
                $sorry = htmlspecialchars( self::msg(
                        'dberr-problems',
@@ -303,7 +287,7 @@ class MWExceptionRenderer {
                        'Try waiting a few minutes and reloading.'
                ) );
 
-               if ( $wgShowHostnames || $wgShowSQLErrors ) {
+               if ( $wgShowHostnames ) {
                        $info = str_replace(
                                '$1',
                                Html::element( 'span', [ 'dir' => 'ltr' ], $e->getMessage() ),
@@ -317,17 +301,22 @@ class MWExceptionRenderer {
                }
 
                MessageCache::singleton()->disable(); // no DB access
+               $html = "<!DOCTYPE html>\n" .
+                               '<html><head>' .
+                               '<title>' .
+                               htmlspecialchars( $wgSitename ) .
+                               '</title>' .
+                               '<style>body { font-family: sans-serif; margin: 0; padding: 0.5em 2em; }</style>' .
+                               "</head><body><h1>$sorry</h1><p>$again</p><p><small>$info</small></p>";
 
-               $html = "<h1>$sorry</h1><p>$again</p><p><small>$info</small></p>";
-
-               if ( $wgShowDBErrorBacktrace ) {
+               if ( $wgShowExceptionDetails ) {
                        $html .= '<p>Backtrace:</p><pre>' .
                                htmlspecialchars( $e->getTraceAsString() ) . '</pre>';
                }
 
                $html .= '<hr />';
                $html .= self::googleSearchForm();
-
+               $html .= '</body></html>';
                echo $html;
        }
 
index ce899ed..26010da 100644 (file)
@@ -34,7 +34,7 @@ class DumpPipeOutput extends DumpFileOutput {
 
        /**
         * @param string $command
-        * @param string $file
+        * @param string|null $file
         */
        function __construct( $command, $file = null ) {
                if ( !is_null( $file ) ) {
index 5edb4b2..422e1fb 100644 (file)
@@ -128,7 +128,7 @@ class ExternalStoreDB extends ExternalStoreMedium {
        public function getSlave( $cluster ) {
                global $wgDefaultExternalStore;
 
-               $wiki = isset( $this->params['wiki'] ) ? $this->params['wiki'] : false;
+               $wiki = $this->params['wiki'] ?? false;
                $lb = $this->getLoadBalancer( $cluster );
 
                if ( !in_array( "DB://" . $cluster, (array)$wgDefaultExternalStore ) ) {
@@ -151,7 +151,7 @@ class ExternalStoreDB extends ExternalStoreMedium {
         * @return MaintainableDBConnRef
         */
        public function getMaster( $cluster ) {
-               $wiki = isset( $this->params['wiki'] ) ? $this->params['wiki'] : false;
+               $wiki = $this->params['wiki'] ?? false;
                $lb = $this->getLoadBalancer( $cluster );
 
                $db = $lb->getMaintenanceConnectionRef( DB_MASTER, [], $wiki );
@@ -194,6 +194,10 @@ class ExternalStoreDB extends ExternalStoreMedium {
                static $externalBlobCache = [];
 
                $cacheID = ( $itemID === false ) ? "$cluster/$id" : "$cluster/$id/";
+
+               $wiki = $this->params['wiki'] ?? false;
+               $cacheID = ( $wiki === false ) ? $cacheID : "$cacheID@$wiki";
+
                if ( isset( $externalBlobCache[$cacheID] ) ) {
                        wfDebugLog( 'ExternalStoreDB-cache',
                                "ExternalStoreDB::fetchBlob cache hit on $cacheID" );
@@ -301,7 +305,7 @@ class ExternalStoreDB extends ExternalStoreMedium {
                return [
                        $path[2], // cluster
                        $path[3], // id
-                       isset( $path[4] ) ? $path[4] : false // itemID
+                       $path[4] ?? false // itemID
                ];
        }
 }
index 5d7155e..c5893be 100644 (file)
@@ -81,7 +81,7 @@ class ExternalStoreMwstore extends ExternalStoreMedium {
                        // Make sure ID is roughly lexicographically increasing for performance
                        $id = str_pad( UIDGenerator::newTimestampedUID128( 32 ), 26, '0', STR_PAD_LEFT );
                        // Segregate items by wiki ID for the sake of bookkeeping
-                       $wiki = isset( $this->params['wiki'] ) ? $this->params['wiki'] : wfWikiID();
+                       $wiki = $this->params['wiki'] ?? wfWikiID();
 
                        $url = $be->getContainerStoragePath( 'data' ) . '/' . rawurlencode( $wiki );
                        $url .= ( $be instanceof FSFileBackend )
index 454b633..503acdc 100644 (file)
@@ -79,15 +79,9 @@ class FileBackendGroup {
                        $repoName = $info['name'];
                        // Local vars that used to be FSRepo members...
                        $directory = $info['directory'];
-                       $deletedDir = isset( $info['deletedDir'] )
-                               ? $info['deletedDir']
-                               : false; // deletion disabled
-                       $thumbDir = isset( $info['thumbDir'] )
-                               ? $info['thumbDir']
-                               : "{$directory}/thumb";
-                       $transcodedDir = isset( $info['transcodedDir'] )
-                               ? $info['transcodedDir']
-                               : "{$directory}/transcoded";
+                       $deletedDir = $info['deletedDir'] ?? false; // deletion disabled
+                       $thumbDir = $info['thumbDir'] ?? "{$directory}/thumb";
+                       $transcodedDir = $info['transcodedDir'] ?? "{$directory}/transcoded";
                        // Get the FS backend configuration
                        $autoBackends[] = [
                                'name' => $backendName,
@@ -100,7 +94,7 @@ class FileBackendGroup {
                                        "{$repoName}-deleted" => $deletedDir,
                                        "{$repoName}-temp" => "{$directory}/temp"
                                ],
-                               'fileMode' => isset( $info['fileMode'] ) ? $info['fileMode'] : 0644,
+                               'fileMode' => $info['fileMode'] ?? 0644,
                                'directoryMode' => $wgDirectoryMode,
                        ];
                }
@@ -129,9 +123,7 @@ class FileBackendGroup {
                        }
                        $class = $config['class'];
 
-                       $config['readOnly'] = !empty( $config['readOnly'] )
-                               ? $config['readOnly']
-                               : $readOnlyReason;
+                       $config['readOnly'] = $config['readOnly'] ?? $readOnlyReason;
 
                        unset( $config['class'] ); // backend won't need this
                        $this->backends[$name] = [
index dbb5421..b445487 100644 (file)
@@ -45,7 +45,7 @@ class FileBackendDBRepoWrapper extends FileBackend {
        protected $repoName;
        /** @var Closure */
        protected $dbHandleFunc;
-       /** @var ProcessCacheLRU */
+       /** @var MapCacheLRU */
        protected $resolvedPathCache;
        /** @var DBConnRef[] */
        protected $dbs;
@@ -59,7 +59,7 @@ class FileBackendDBRepoWrapper extends FileBackend {
                $this->backend = $config['backend'];
                $this->repoName = $config['repoName'];
                $this->dbHandleFunc = $config['dbHandleFactory'];
-               $this->resolvedPathCache = new ProcessCacheLRU( 100 );
+               $this->resolvedPathCache = new MapCacheLRU( 100 );
        }
 
        /**
@@ -102,8 +102,8 @@ class FileBackendDBRepoWrapper extends FileBackend {
                // @TODO: batching
                $resolved = [];
                foreach ( $paths as $i => $path ) {
-                       if ( !$latest && $this->resolvedPathCache->has( $path, 'target', 10 ) ) {
-                               $resolved[$i] = $this->resolvedPathCache->get( $path, 'target' );
+                       if ( !$latest && $this->resolvedPathCache->hasField( $path, 'target', 10 ) ) {
+                               $resolved[$i] = $this->resolvedPathCache->getField( $path, 'target' );
                                continue;
                        }
 
@@ -127,12 +127,12 @@ class FileBackendDBRepoWrapper extends FileBackend {
                                        continue;
                                }
                                $resolved[$i] = $this->getPathForSHA1( $sha1 );
-                               $this->resolvedPathCache->set( $path, 'target', $resolved[$i] );
+                               $this->resolvedPathCache->setField( $path, 'target', $resolved[$i] );
                        } elseif ( $container === "{$this->repoName}-deleted" ) {
                                $name = basename( $path ); // <hash>.<ext>
                                $sha1 = substr( $name, 0, strpos( $name, '.' ) ); // ignore extension
                                $resolved[$i] = $this->getPathForSHA1( $sha1 );
-                               $this->resolvedPathCache->set( $path, 'target', $resolved[$i] );
+                               $this->resolvedPathCache->setField( $path, 'target', $resolved[$i] );
                        } else {
                                $resolved[$i] = $path;
                        }
index b15f81f..3d9a904 100644 (file)
@@ -171,30 +171,20 @@ class FileRepo {
                }
 
                // Optional settings that have a default
-               $this->initialCapital = isset( $info['initialCapital'] )
-                       ? $info['initialCapital']
-                       : MWNamespace::isCapitalized( NS_FILE );
-               $this->url = isset( $info['url'] )
-                       ? $info['url']
-                       : false; // a subclass may set the URL (e.g. ForeignAPIRepo)
+               $this->initialCapital = $info['initialCapital'] ?? MWNamespace::isCapitalized( NS_FILE );
+               $this->url = $info['url'] ?? false; // a subclass may set the URL (e.g. ForeignAPIRepo)
                if ( isset( $info['thumbUrl'] ) ) {
                        $this->thumbUrl = $info['thumbUrl'];
                } else {
                        $this->thumbUrl = $this->url ? "{$this->url}/thumb" : false;
                }
-               $this->hashLevels = isset( $info['hashLevels'] )
-                       ? $info['hashLevels']
-                       : 2;
-               $this->deletedHashLevels = isset( $info['deletedHashLevels'] )
-                       ? $info['deletedHashLevels']
-                       : $this->hashLevels;
+               $this->hashLevels = $info['hashLevels'] ?? 2;
+               $this->deletedHashLevels = $info['deletedHashLevels'] ?? $this->hashLevels;
                $this->transformVia404 = !empty( $info['transformVia404'] );
-               $this->abbrvThreshold = isset( $info['abbrvThreshold'] )
-                       ? $info['abbrvThreshold']
-                       : 255;
+               $this->abbrvThreshold = $info['abbrvThreshold'] ?? 255;
                $this->isPrivate = !empty( $info['isPrivate'] );
                // Give defaults for the basic zones...
-               $this->zones = isset( $info['zones'] ) ? $info['zones'] : [];
+               $this->zones = $info['zones'] ?? [];
                foreach ( [ 'public', 'thumb', 'transcoded', 'temp', 'deleted' ] as $zone ) {
                        if ( !isset( $this->zones[$zone]['container'] ) ) {
                                $this->zones[$zone]['container'] = "{$this->name}-{$zone}";
@@ -428,7 +418,7 @@ class FileRepo {
                if ( isset( $options['bypassCache'] ) ) {
                        $options['latest'] = $options['bypassCache']; // b/c
                }
-               $time = isset( $options['time'] ) ? $options['time'] : false;
+               $time = $options['time'] ?? false;
                $flags = !empty( $options['latest'] ) ? File::READ_LATEST : 0;
                # First try the current version of the file to see if it precedes the timestamp
                $img = $this->newFile( $title );
@@ -534,7 +524,7 @@ class FileRepo {
         * @return File|bool False on failure
         */
        public function findFileFromKey( $sha1, $options = [] ) {
-               $time = isset( $options['time'] ) ? $options['time'] : false;
+               $time = $options['time'] ?? false;
                # First try to find a matching current version of a file...
                if ( !$this->fileFactoryKey ) {
                        return false; // find-by-sha1 not supported
@@ -690,7 +680,7 @@ class FileRepo {
         */
        public function getTempHashPath( $suffix ) {
                $parts = explode( '!', $suffix, 2 ); // format is <timestamp>!<name> or just <name>
-               $name = isset( $parts[1] ) ? $parts[1] : $suffix; // hash path is not based on timestamp
+               $name = $parts[1] ?? $suffix; // hash path is not based on timestamp
                return self::getHashPathForLevel( $name, $this->hashLevels );
        }
 
@@ -1187,11 +1177,7 @@ class FileRepo {
                if ( $status->successCount == 0 ) {
                        $status->setOK( false );
                }
-               if ( isset( $status->value[0] ) ) {
-                       $status->value = $status->value[0];
-               } else {
-                       $status->value = false;
-               }
+               $status->value = $status->value[0] ?? false;
 
                return $status;
        }
@@ -1225,7 +1211,7 @@ class FileRepo {
                        list( $src, $dstRel, $archiveRel ) = $ntuple;
                        $srcPath = ( $src instanceof FSFile ) ? $src->getPath() : $src;
 
-                       $options = isset( $ntuple[3] ) ? $ntuple[3] : [];
+                       $options = $ntuple[3] ?? [];
                        // Resolve source to a storage path if virtual
                        $srcPath = $this->resolveToStoragePath( $srcPath );
                        if ( !$this->validateFilename( $dstRel ) ) {
@@ -1250,7 +1236,7 @@ class FileRepo {
                        }
 
                        // Set any desired headers to be use in GET/HEAD responses
-                       $headers = isset( $options['headers'] ) ? $options['headers'] : [];
+                       $headers = $options['headers'] ?? [];
 
                        // Archive destination file if it exists.
                        // This will check if the archive file also exists and fail if does.
@@ -1745,7 +1731,7 @@ class FileRepo {
         * @return Status
         */
        public function newFatal( $message /*, parameters...*/ ) {
-               $status = call_user_func_array( [ Status::class, 'newFatal' ], func_get_args() );
+               $status = Status::newFatal( ...func_get_args() );
                $status->cleanCallback = $this->getErrorCleanupFunction();
 
                return $status;
@@ -1850,7 +1836,7 @@ class FileRepo {
                $args = func_get_args();
                array_unshift( $args, 'filerepo', $this->getName() );
 
-               return call_user_func_array( 'wfMemcKey', $args );
+               return wfMemcKey( ...$args );
        }
 
        /**
index cba21c8..c20df76 100644 (file)
@@ -75,7 +75,7 @@ class ForeignAPIRepo extends FileRepo {
                parent::__construct( $info );
 
                // https://commons.wikimedia.org/w/api.php
-               $this->mApiBase = isset( $info['apibase'] ) ? $info['apibase'] : null;
+               $this->mApiBase = $info['apibase'] ?? null;
 
                if ( isset( $info['apiThumbCacheExpiry'] ) ) {
                        $this->apiThumbCacheExpiry = $info['apiThumbCacheExpiry'];
index 7879448..4b33138 100644 (file)
@@ -132,9 +132,8 @@ class ForeignDBRepo extends LocalRepo {
        function getSharedCacheKey( /*...*/ ) {
                if ( $this->hasSharedCache() ) {
                        $args = func_get_args();
-                       array_unshift( $args, $this->dbName, $this->tablePrefix );
 
-                       return call_user_func_array( 'wfForeignMemcKey', $args );
+                       return wfForeignMemcKey( $this->dbName, $this->tablePrefix, ...$args );
                } else {
                        return false;
                }
index 03a9d44..9a6ef22 100644 (file)
@@ -507,7 +507,7 @@ class LocalRepo extends FileRepo {
        function getSharedCacheKey( /*...*/ ) {
                $args = func_get_args();
 
-               return call_user_func_array( 'wfMemcKey', $args );
+               return wfMemcKey( ...$args );
        }
 
        /**
@@ -590,7 +590,7 @@ class LocalRepo extends FileRepo {
                        wfDebug( __METHOD__ . ": skipped because storage uses sha1 paths\n" );
                        return Status::newGood();
                } else {
-                       return call_user_func_array( 'parent::' . $function, $args );
+                       return parent::$function( ...$args );
                }
        }
 }
index b797790..f3fed57 100644 (file)
@@ -98,7 +98,7 @@ class RepoGroup {
        function __construct( $localInfo, $foreignInfo ) {
                $this->localInfo = $localInfo;
                $this->foreignInfo = $foreignInfo;
-               $this->cache = new ProcessCacheLRU( self::MAX_CACHE_SIZE );
+               $this->cache = new MapCacheLRU( self::MAX_CACHE_SIZE );
        }
 
        /**
@@ -125,10 +125,12 @@ class RepoGroup {
                if ( isset( $options['bypassCache'] ) ) {
                        $options['latest'] = $options['bypassCache']; // b/c
                }
+               $options += [ 'time' => false ];
 
                if ( !$this->reposInitialised ) {
                        $this->initialiseRepos();
                }
+
                $title = File::normalizeTitle( $title );
                if ( !$title ) {
                        return false;
@@ -136,17 +138,16 @@ class RepoGroup {
 
                # Check the cache
                $dbkey = $title->getDBkey();
+               $timeKey = is_string( $options['time'] ) ? $options['time'] : '';
                if ( empty( $options['ignoreRedirect'] )
                        && empty( $options['private'] )
                        && empty( $options['latest'] )
                ) {
-                       $time = isset( $options['time'] ) ? $options['time'] : '';
-                       if ( $this->cache->has( $dbkey, $time, 60 ) ) {
-                               return $this->cache->get( $dbkey, $time );
+                       if ( $this->cache->hasField( $dbkey, $timeKey, 60 ) ) {
+                               return $this->cache->getField( $dbkey, $timeKey );
                        }
                        $useCache = true;
                } else {
-                       $time = false;
                        $useCache = false;
                }
 
@@ -163,10 +164,10 @@ class RepoGroup {
                        }
                }
 
-               $image = $image ? $image : false; // type sanity
+               $image = $image ?: false; // type sanity
                # Cache file existence or non-existence
                if ( $useCache && ( !$image || $image->isCacheable() ) ) {
-                       $this->cache->set( $dbkey, $time, $image );
+                       $this->cache->setField( $dbkey, $timeKey, $image );
                }
 
                return $image;
@@ -324,11 +325,8 @@ class RepoGroup {
                }
                if ( $index === 'local' ) {
                        return $this->localRepo;
-               } elseif ( isset( $this->foreignRepos[$index] ) ) {
-                       return $this->foreignRepos[$index];
-               } else {
-                       return false;
                }
+               return $this->foreignRepos[$index] ?? false;
        }
 
        /**
@@ -372,8 +370,7 @@ class RepoGroup {
                        $this->initialiseRepos();
                }
                foreach ( $this->foreignRepos as $repo ) {
-                       $args = array_merge( [ $repo ], $params );
-                       if ( call_user_func_array( $callback, $args ) ) {
+                       if ( $callback( $repo, ...$params ) ) {
                                return true;
                        }
                }
index 65e4345..5589c68 100644 (file)
@@ -248,7 +248,7 @@ class ArchivedFile {
                        'fa_minor_mime',
                        'fa_user',
                        'fa_user_text',
-                       'fa_actor' => $wgActorTableSchemaMigrationStage > MIGRATION_OLD ? 'fa_actor' : null,
+                       'fa_actor' => $wgActorTableSchemaMigrationStage > MIGRATION_OLD ? 'fa_actor' : 'NULL',
                        'fa_timestamp',
                        'fa_deleted',
                        'fa_deleted_timestamp', /* Used by LocalFileRestoreBatch */
index 7c87af3..370ebb4 100644 (file)
@@ -933,7 +933,7 @@ abstract class File implements IDBAccessObject {
         */
        function getUnscaledThumb( $handlerParams = [] ) {
                $hp =& $handlerParams;
-               $page = isset( $hp['page'] ) ? $hp['page'] : false;
+               $page = $hp['page'] ?? false;
                $width = $this->getWidth( $page );
                if ( !$width ) {
                        return $this->iconThumb();
@@ -2068,9 +2068,8 @@ abstract class File implements IDBAccessObject {
                        $cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
                        $key = $this->repo->getLocalCacheKey(
                                'RemoteFileDescription',
-                               'url',
                                $lang->getCode(),
-                               $this->getName()
+                               md5( $this->getName() )
                        );
 
                        return $cache->getWithSetCallback(
index 1002b82..0e48195 100644 (file)
@@ -128,8 +128,8 @@ class ForeignAPIFile extends File {
                // Note, the this->canRender() check above implies
                // that we have a handler, and it can do makeParamString.
                $otherParams = $this->handler->makeParamString( $params );
-               $width = isset( $params['width'] ) ? $params['width'] : -1;
-               $height = isset( $params['height'] ) ? $params['height'] : -1;
+               $width = $params['width'] ?? -1;
+               $height = $params['height'] ?? -1;
 
                $thumbUrl = $this->repo->getThumbUrlFromCache(
                        $this->getName(),
@@ -311,9 +311,7 @@ class ForeignAPIFile extends File {
         * @return bool|string
         */
        function getDescriptionUrl() {
-               return isset( $this->mInfo['descriptionurl'] )
-                       ? $this->mInfo['descriptionurl']
-                       : false;
+               return $this->mInfo['descriptionurl'] ?? false;
        }
 
        /**
index 05df45b..7a982bd 100644 (file)
@@ -155,10 +155,9 @@ class ForeignDBFile extends LocalFile {
 
                return $cache->getWithSetCallback(
                        $this->repo->getLocalCacheKey(
-                               'RemoteFileDescription',
-                               'url',
+                               'ForeignFileDescription',
                                $lang->getCode(),
-                               $this->getName(),
+                               md5( $this->getName() ),
                                $touched
                        ),
                        $this->repo->descriptionCacheExpiry ?: $cache::TTL_UNCACHEABLE,
index 1702264..742d78d 100644 (file)
@@ -223,7 +223,7 @@ class LocalFile extends File {
                        'img_minor_mime',
                        'img_user',
                        'img_user_text',
-                       'img_actor' => $wgActorTableSchemaMigrationStage > MIGRATION_OLD ? 'img_actor' : null,
+                       'img_actor' => $wgActorTableSchemaMigrationStage > MIGRATION_OLD ? 'img_actor' : 'NULL',
                        'img_timestamp',
                        'img_sha1',
                ] + MediaWikiServices::getInstance()->getCommentStore()->getFields( 'img_description' );
@@ -583,9 +583,9 @@ class LocalFile extends File {
                        ->getComment( 'description', (object)$decoded )->text;
 
                $decoded['user'] = User::newFromAnyId(
-                       isset( $decoded['user'] ) ? $decoded['user'] : null,
-                       isset( $decoded['user_text'] ) ? $decoded['user_text'] : null,
-                       isset( $decoded['actor'] ) ? $decoded['actor'] : null
+                       $decoded['user'] ?? null,
+                       $decoded['user_text'] ?? null,
+                       $decoded['actor'] ?? null
                );
                unset( $decoded['user_text'], $decoded['actor'] );
 
@@ -772,9 +772,9 @@ class LocalFile extends File {
 
                if ( isset( $info['user'] ) || isset( $info['user_text'] ) || isset( $info['actor'] ) ) {
                        $this->user = User::newFromAnyId(
-                               isset( $info['user'] ) ? $info['user'] : null,
-                               isset( $info['user_text'] ) ? $info['user_text'] : null,
-                               isset( $info['actor'] ) ? $info['actor'] : null
+                               $info['user'] ?? null,
+                               $info['user_text'] ?? null,
+                               $info['actor'] ?? null
                        );
                }
 
@@ -2208,7 +2208,7 @@ class LocalFile extends File {
 
                // If extra data (metadata) was not loaded then it must have been large
                return $this->extraDataLoaded
-               && strlen( serialize( $this->metadata ) ) <= self::CACHE_FIELD_MAX_LEN;
+                       && strlen( serialize( $this->metadata ) ) <= self::CACHE_FIELD_MAX_LEN;
        }
 
        /**
@@ -2216,9 +2216,9 @@ class LocalFile extends File {
         * @since 1.28
         */
        public function acquireFileLock() {
-               return $this->getRepo()->getBackend()->lockFiles(
+               return Status::wrap( $this->getRepo()->getBackend()->lockFiles(
                        [ $this->getPath() ], LockManager::LOCK_EX, 10
-               );
+               ) );
        }
 
        /**
@@ -2226,9 +2226,9 @@ class LocalFile extends File {
         * @since 1.28
         */
        public function releaseFileLock() {
-               return $this->getRepo()->getBackend()->unlockFiles(
+               return Status::wrap( $this->getRepo()->getBackend()->unlockFiles(
                        [ $this->getPath() ], LockManager::LOCK_EX
-               );
+               ) );
        }
 
        /**
@@ -3344,19 +3344,15 @@ class LocalFileMoveBatch {
                $status = $repo->newGood();
                $dbw = $this->db;
 
-               $hasCurrent = $dbw->selectField(
+               $hasCurrent = $dbw->lockForUpdate(
                        'image',
-                       '1',
                        [ 'img_name' => $this->oldName ],
-                       __METHOD__,
-                       [ 'FOR UPDATE' ]
+                       __METHOD__
                );
-               $oldRowCount = $dbw->selectRowCount(
+               $oldRowCount = $dbw->lockForUpdate(
                        'oldimage',
-                       '*',
                        [ 'oi_name' => $this->oldName ],
-                       __METHOD__,
-                       [ 'FOR UPDATE' ]
+                       __METHOD__
                );
 
                if ( $hasCurrent ) {
index aa434d0..9759b79 100644 (file)
@@ -41,7 +41,7 @@ class OldLocalFile extends LocalFile {
        /**
         * @param Title $title
         * @param FileRepo $repo
-        * @param string|int $time
+        * @param string|int|null $time
         * @return self
         * @throws MWException
         */
@@ -138,7 +138,7 @@ class OldLocalFile extends LocalFile {
                        'oi_minor_mime',
                        'oi_user',
                        'oi_user_text',
-                       'oi_actor' => $wgActorTableSchemaMigrationStage > MIGRATION_OLD ? 'oi_actor' : null,
+                       'oi_actor' => $wgActorTableSchemaMigrationStage > MIGRATION_OLD ? 'oi_actor' : 'NULL',
                        'oi_timestamp',
                        'oi_deleted',
                        'oi_sha1',
index cd6aab0..479ca5d 100644 (file)
@@ -35,7 +35,7 @@ class TraditionalImageGallery extends ImageGalleryBase {
        function toHTML() {
                if ( $this->mPerRow > 0 ) {
                        $maxwidth = $this->mPerRow * ( $this->mWidths + $this->getAllPadding() );
-                       $oldStyle = isset( $this->mAttribs['style'] ) ? $this->mAttribs['style'] : '';
+                       $oldStyle = $this->mAttribs['style'] ?? '';
                        # _width is ignored by any sane browser. IE6 doesn't know max-width
                        # so it uses _width instead
                        $this->mAttribs['style'] = "max-width: {$maxwidth}px;_width: {$maxwidth}px;" .
@@ -226,7 +226,7 @@ class TraditionalImageGallery extends ImageGalleryBase {
                        $nt,
                        htmlspecialchars(
                                is_int( $this->getCaptionLength() ) ?
-                                       $lang->truncate( $nt->getText(), $this->getCaptionLength() ) :
+                                       $lang->truncateForVisual( $nt->getText(), $this->getCaptionLength() ) :
                                        $nt->getText()
                        ),
                        [
@@ -286,7 +286,7 @@ class TraditionalImageGallery extends ImageGalleryBase {
        }
 
        /**
-        * Length to truncate filename to in caption when using "showfilename" (if int).
+        * Length (in characters) to truncate filename to in caption when using "showfilename" (if int).
         * A value of 'true' will truncate the filename to one line using CSS, while
         * 'false' will disable truncating.
         *
index 043e0f6..442a7cf 100644 (file)
@@ -301,7 +301,7 @@ class HTMLForm extends ContextSource {
         * Build a new HTMLForm from an array of field attributes
         *
         * @param array $descriptor Array of Field constructs, as described above
-        * @param IContextSource $context Available since 1.18, will become compulsory in 1.18.
+        * @param IContextSource|null $context Available since 1.18, will become compulsory in 1.18.
         *     Obviates the need to call $form->setTitle()
         * @param string $messagePrefix A prefix to go in front of default messages
         */
@@ -333,9 +333,7 @@ class HTMLForm extends ContextSource {
                $this->mFlatFields = [];
 
                foreach ( $descriptor as $fieldname => $info ) {
-                       $section = isset( $info['section'] )
-                               ? $info['section']
-                               : '';
+                       $section = $info['section'] ?? '';
 
                        if ( isset( $info['type'] ) && $info['type'] === 'file' ) {
                                $this->mUseMultipart = true;
@@ -609,7 +607,7 @@ class HTMLForm extends ContextSource {
                $hoistedErrors = Status::newGood();
                if ( $this->mValidationErrorMessage ) {
                        foreach ( (array)$this->mValidationErrorMessage as $error ) {
-                               call_user_func_array( [ $hoistedErrors, 'fatal' ], $error );
+                               $hoistedErrors->fatal( ...$error );
                        }
                } else {
                        $hoistedErrors->fatal( 'htmlform-invalid-input' );
@@ -754,6 +752,17 @@ class HTMLForm extends ContextSource {
                return $this;
        }
 
+       /**
+        * Get the introductory message HTML.
+        *
+        * @since 1.32
+        *
+        * @return string
+        */
+       public function getPreText() {
+               return $this->mPre;
+       }
+
        /**
         * Add HTML to the header, inside the form.
         *
@@ -805,7 +814,7 @@ class HTMLForm extends ContextSource {
                if ( $section === null ) {
                        return $this->mHeader;
                } else {
-                       return isset( $this->mSectionHeaders[$section] ) ? $this->mSectionHeaders[$section] : '';
+                       return $this->mSectionHeaders[$section] ?? '';
                }
        }
 
@@ -860,7 +869,7 @@ class HTMLForm extends ContextSource {
                if ( $section === null ) {
                        return $this->mFooter;
                } else {
-                       return isset( $this->mSectionFooters[$section] ) ? $this->mSectionFooters[$section] : '';
+                       return $this->mSectionFooters[$section] ?? '';
                }
        }
 
@@ -959,8 +968,8 @@ class HTMLForm extends ContextSource {
                        $data = [
                                'name' => $args[0],
                                'value' => $args[1],
-                               'id' => isset( $args[2] ) ? $args[2] : null,
-                               'attribs' => isset( $args[3] ) ? $args[3] : null,
+                               'id' => $args[2] ?? null,
+                               'attribs' => $args[3] ?? null,
                        ];
                } else {
                        if ( !isset( $data['name'] ) ) {
@@ -1664,7 +1673,7 @@ class HTMLForm extends ContextSource {
                                        $html[] = $retval;
 
                                        $labelValue = trim( $value->getLabel() );
-                                       if ( $labelValue !== '&#160;' && $labelValue !== '' ) {
+                                       if ( $labelValue !== "\u{00A0}" && $labelValue !== '&#160;' && $labelValue !== '' ) {
                                                $hasLabel = true;
                                        }
 
index 2830b9c..fbef265 100644 (file)
@@ -13,8 +13,8 @@ trait HTMLFormElement {
 
        public function initializeHTMLFormElement( array $config = [] ) {
                // Properties
-               $this->hideIf = isset( $config['hideIf'] ) ? $config['hideIf'] : null;
-               $this->modules = isset( $config['modules'] ) ? $config['modules'] : [];
+               $this->hideIf = $config['hideIf'] ?? null;
+               $this->modules = $config['modules'] ?? [];
 
                // Initialization
                if ( $this->hideIf ) {
index 5066f28..97e4b50 100644 (file)
@@ -81,12 +81,9 @@ abstract class HTMLFormField {
                $args = func_get_args();
 
                if ( $this->mParent ) {
-                       $callback = [ $this->mParent, 'msg' ];
-               } else {
-                       $callback = 'wfMessage';
+                       return $this->mParent->msg( ...$args );
                }
-
-               return call_user_func_array( $callback, $args );
+               return wfMessage( ...$args );
        }
 
        /**
@@ -315,7 +312,7 @@ abstract class HTMLFormField {
                }
 
                if ( isset( $this->mValidationCallback ) ) {
-                       return call_user_func( $this->mValidationCallback, $value, $alldata, $this->mParent );
+                       return ( $this->mValidationCallback )( $value, $alldata, $this->mParent );
                }
 
                return true;
@@ -323,7 +320,7 @@ abstract class HTMLFormField {
 
        public function filter( $value, $alldata ) {
                if ( isset( $this->mFilterCallback ) ) {
-                       $value = call_user_func( $this->mFilterCallback, $value, $alldata, $this->mParent );
+                       $value = ( $this->mFilterCallback )( $value, $alldata, $this->mParent );
                }
 
                return $value;
@@ -400,9 +397,9 @@ abstract class HTMLFormField {
                if ( isset( $params['label-message'] ) ) {
                        $this->mLabel = $this->getMessage( $params['label-message'] )->parse();
                } elseif ( isset( $params['label'] ) ) {
-                       if ( $params['label'] === '&#160;' ) {
+                       if ( $params['label'] === '&#160;' || $params['label'] === "\u{00A0}" ) {
                                // Apparently some things set &nbsp directly and in an odd format
-                               $this->mLabel = '&#160;';
+                               $this->mLabel = "\u{00A0}";
                        } else {
                                $this->mLabel = htmlspecialchars( $params['label'] );
                        }
@@ -546,11 +543,10 @@ abstract class HTMLFormField {
                        'mw-htmlform-nolabel' => ( $label === '' )
                ];
 
-               $horizontalLabel = isset( $this->mParams['horizontal-label'] )
-                       ? $this->mParams['horizontal-label'] : false;
+               $horizontalLabel = $this->mParams['horizontal-label'] ?? false;
 
                if ( $horizontalLabel ) {
-                       $field = '&#160;' . $inputHtml . "\n$errors";
+                       $field = "\u{00A0}" . $inputHtml . "\n$errors";
                } else {
                        $field = Html::rawElement(
                                'div',
@@ -634,7 +630,7 @@ abstract class HTMLFormField {
 
                // the element could specify, that the label doesn't need to be added
                $label = $this->getLabel();
-               if ( $label && $label !== '&#160;' ) {
+               if ( $label && $label !== "\u{00A0}" && $label !== '&#160;' ) {
                        $config['label'] = new OOUI\HtmlSnippet( $label );
                }
 
@@ -749,7 +745,7 @@ abstract class HTMLFormField {
                $label = $this->getLabelHtml( $cellAttributes );
 
                $html = "\n" . $errors .
-                       $label . '&#160;' .
+                       $label . "\u{00A0}" .
                        $inputHtml .
                        $helptext;
 
@@ -930,7 +926,7 @@ abstract class HTMLFormField {
         * @return string HTML
         */
        public function getLabel() {
-               return is_null( $this->mLabel ) ? '' : $this->mLabel;
+               return $this->mLabel ?? '';
        }
 
        public function getLabelHtml( $cellAttributes = [] ) {
@@ -944,14 +940,13 @@ abstract class HTMLFormField {
 
                $labelValue = trim( $this->getLabel() );
                $hasLabel = false;
-               if ( $labelValue !== '&#160;' && $labelValue !== '' ) {
+               if ( $labelValue !== "\u{00A0}" && $labelValue !== '&#160;' && $labelValue !== '' ) {
                        $hasLabel = true;
                }
 
                $displayFormat = $this->mParent->getDisplayFormat();
                $html = '';
-               $horizontalLabel = isset( $this->mParams['horizontal-label'] )
-                       ? $this->mParams['horizontal-label'] : false;
+               $horizontalLabel = $this->mParams['horizontal-label'] ?? false;
 
                if ( $displayFormat === 'table' ) {
                        $html =
@@ -973,11 +968,7 @@ abstract class HTMLFormField {
        }
 
        public function getDefault() {
-               if ( isset( $this->mDefault ) ) {
-                       return $this->mDefault;
-               } else {
-                       return null;
-               }
+               return $this->mDefault ?? null;
        }
 
        /**
index a19bd5a..7f7f718 100644 (file)
@@ -46,9 +46,9 @@ class HTMLButtonField extends HTMLFormField {
                if ( isset( $info['buttonlabel-message'] ) ) {
                        $this->buttonLabel = $this->getMessage( $info['buttonlabel-message'] )->parse();
                } elseif ( isset( $info['buttonlabel'] ) ) {
-                       if ( $info['buttonlabel'] === '&#160;' ) {
+                       if ( $info['buttonlabel'] === '&#160;' || $info['buttonlabel'] === "\u{00A0}" ) {
                                // Apparently some things set &nbsp directly and in an odd format
-                               $this->buttonLabel = '&#160;';
+                               $this->buttonLabel = "\u{00A0}";
                        } else {
                                $this->buttonLabel = htmlspecialchars( $info['buttonlabel'] );
                        }
index 9a956fb..aad9f6e 100644 (file)
@@ -27,7 +27,7 @@ class HTMLCheckField extends HTMLFormField {
                }
 
                $chkLabel = Xml::check( $this->mName, $value, $attr ) .
-                       '&#160;' .
+                       "\u{00A0}" .
                        Html::rawElement( 'label', $attrLabel, $this->mLabel );
 
                if ( $wgUseMediaWikiUIEverywhere || $this->mParent instanceof VFormHTMLForm ) {
@@ -88,7 +88,7 @@ class HTMLCheckField extends HTMLFormField {
                ) {
                        return '';
                } else {
-                       return '&#160;';
+                       return "\u{00A0}";
                }
        }
 
@@ -116,10 +116,9 @@ class HTMLCheckField extends HTMLFormField {
        public function loadDataFromRequest( $request ) {
                $invert = isset( $this->mParams['invert'] ) && $this->mParams['invert'];
 
-               // GetCheck won't work like we want for checks.
                // Fetch the value in either one of the two following case:
-               // - we have a valid submit attempt (form was just submitted, or a GET URL forged by the user)
-               // - checkbox name has a value (false or true), ie is not null
+               // - 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 ) {
                        return $invert
                                ? !$request->getBool( $this->mName )
index df44626..da68a62 100644 (file)
@@ -88,7 +88,7 @@ class HTMLCheckMatrix extends HTMLFormField implements HTMLNestedFilterable {
                $attribs = $this->getAttributes( [ 'disabled', 'tabindex' ] );
 
                // Build the column headers
-               $headerContents = Html::rawElement( 'td', [], '&#160;' );
+               $headerContents = Html::rawElement( 'td', [], "\u{00A0}" );
                foreach ( $columns as $columnLabel => $columnTag ) {
                        $headerContents .= Html::rawElement( 'td', [], $columnLabel );
                }
@@ -239,11 +239,7 @@ class HTMLCheckMatrix extends HTMLFormField implements HTMLNestedFilterable {
        }
 
        public function getDefault() {
-               if ( isset( $this->mDefault ) ) {
-                       return $this->mDefault;
-               } else {
-                       return [];
-               }
+               return $this->mDefault ?? [];
        }
 
        public function filterDataForSubmit( $data ) {
index dfe6a8a..e7bdb44 100644 (file)
@@ -56,7 +56,7 @@ class HTMLExpiryField extends HTMLFormField {
                        $this->relativeField->getInputOOUI( $value ),
                        [
                                'id' => $this->mID,
-                               'required' => isset( $this->mParams['required'] ) ? $this->mParams['required'] : false,
+                               'required' => $this->mParams['required'] ?? false,
                        ]
                );
        }
index d2d54e2..72381f0 100644 (file)
@@ -5,7 +5,7 @@
  */
 class HTMLFloatField extends HTMLTextField {
        public function getSize() {
-               return isset( $this->mParams['size'] ) ? $this->mParams['size'] : 20;
+               return $this->mParams['size'] ?? 20;
        }
 
        public function validate( $value, $alldata ) {
index 53c6835..aae3af2 100644 (file)
@@ -273,9 +273,7 @@ class HTMLFormFieldCloner extends HTMLFormField {
         * @return string
         */
        protected function getInputHTMLForKey( $key, array $values ) {
-               $displayFormat = isset( $this->mParams['format'] )
-                       ? $this->mParams['format']
-                       : $this->mParent->getDisplayFormat();
+               $displayFormat = $this->mParams['format'] ?? $this->mParent->getDisplayFormat();
 
                // Conveniently, PHP method names are case-insensitive.
                $getFieldHtmlMethod = $displayFormat == 'table' ? 'getTableRow' : ( 'get' . $displayFormat );
@@ -298,7 +296,7 @@ class HTMLFormFieldCloner extends HTMLFormField {
                                $html .= $field->$getFieldHtmlMethod( $v );
 
                                $labelValue = trim( $field->getLabel() );
-                               if ( $labelValue != '&#160;' && $labelValue !== '' ) {
+                               if ( $labelValue !== "\u{00A0}" && $labelValue !== '&#160;' && $labelValue !== '' ) {
                                        $hasLabel = true;
                                }
                        }
@@ -306,9 +304,7 @@ class HTMLFormFieldCloner extends HTMLFormField {
 
                if ( !isset( $fields['delete'] ) ) {
                        $name = "{$this->mName}[$key][delete]";
-                       $label = isset( $this->mParams['delete-button-message'] )
-                               ? $this->mParams['delete-button-message']
-                               : 'htmlform-cloner-delete';
+                       $label = $this->mParams['delete-button-message'] ?? 'htmlform-cloner-delete';
                        $field = HTMLForm::loadInputFromParameters( $name, [
                                'type' => 'submit',
                                'formnovalidate' => true,
@@ -379,9 +375,7 @@ class HTMLFormFieldCloner extends HTMLFormField {
                ], $html );
 
                $name = "{$this->mName}[create]";
-               $label = isset( $this->mParams['create-button-message'] )
-                       ? $this->mParams['create-button-message']
-                       : 'htmlform-cloner-create';
+               $label = $this->mParams['create-button-message'] ?? 'htmlform-cloner-create';
                $field = HTMLForm::loadInputFromParameters( $name, [
                        'type' => 'submit',
                        'formnovalidate' => true,
index b2290ce..716a092 100644 (file)
@@ -70,6 +70,6 @@ class HTMLFormFieldWithButton extends HTMLFormField {
         * @return String
         */
        public function getElement( $element ) {
-               return $element . '&#160;' . $this->getInputHTML( '' );
+               return $element . "\u{00A0}" . $this->getInputHTML( '' );
        }
 }
index e8a7e99..2038606 100644 (file)
@@ -105,7 +105,7 @@ class HTMLMultiSelectField extends HTMLFormField implements HTMLNestedFilterable
                        $elementFunc = [ Html::class, $this->mOptionsLabelsNotFromMessage ? 'rawElement' : 'element' ];
                        $checkbox =
                                Xml::check( "{$this->mName}[]", $checked, $attribs ) .
-                               '&#160;' .
+                               "\u{00A0}" .
                                call_user_func( $elementFunc,
                                        'label',
                                        [ 'for' => $attribs['id'] ],
@@ -214,10 +214,14 @@ class HTMLMultiSelectField extends HTMLFormField implements HTMLNestedFilterable
         * @return string|array
         */
        public function loadDataFromRequest( $request ) {
-               if ( $this->isSubmitAttempt( $request ) ) {
+               $fromRequest = $request->getArray( $this->mName, [] );
+               // 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 ) || $fromRequest ) {
                        // Checkboxes are just not added to the request arrays if they're not checked,
                        // so it's perfectly possible for there not to be an entry at all
-                       return $request->getArray( $this->mName, [] );
+                       return $fromRequest;
                } else {
                        // That's ok, the user has not yet submitted the form, so show the defaults
                        return $this->getDefault();
index f3bcc0e..41c2c10 100644 (file)
@@ -92,7 +92,7 @@ class HTMLRadioField extends HTMLFormField {
                                        $classes[] = 'mw-ui-radio';
                                }
                                $radio = Xml::radio( $this->mName, $info, $info === $value, $attribs + [ 'id' => $id ] );
-                               $radio .= '&#160;' . call_user_func( $elementFunc, 'label', [ 'for' => $id ], $label );
+                               $radio .= "\u{00A0}" . call_user_func( $elementFunc, 'label', [ 'for' => $id ], $label );
 
                                $html .= ' ' . Html::rawElement(
                                        'div',
index 610b509..4e64e9d 100644 (file)
@@ -119,15 +119,20 @@ class HTMLSelectAndOtherField extends HTMLSelectField {
                        $dropdownInputAttribs['classes'] = [ $this->mClass ];
                }
 
+               $disabled = false;
+               if ( isset( $this->mParams[ 'disabled' ] ) && $this->mParams[ 'disabled' ] ) {
+                       $disabled = true;
+               }
+
                return $this->getInputWidget( [
                        'id' => $this->mID,
+                       'disabled' => $disabled,
                        'textinput' => $textAttribs,
                        'dropdowninput' => $dropdownInputAttribs,
                        'or' => false,
                        'classes' => [ 'mw-htmlform-select-and-other-field' ],
                        'data' => [
-                               'maxlengthUnit' => isset( $this->mParams['maxlength-unit'] )
-                                       ? $this->mParams['maxlength-unit'] : 'bytes'
+                               'maxlengthUnit' => $this->mParams['maxlength-unit'] ?? 'bytes'
                        ],
                ] );
        }
@@ -177,7 +182,7 @@ class HTMLSelectAndOtherField extends HTMLSelectField {
        }
 
        public function getSize() {
-               return isset( $this->mParams['size'] ) ? $this->mParams['size'] : 45;
+               return $this->mParams['size'] ?? 45;
        }
 
        public function validate( $value, $alldata ) {
index f13aa17..7f74b3b 100644 (file)
@@ -3,6 +3,10 @@
  * Wrapper for Html::namespaceSelector to use in HTMLForm
  */
 class HTMLSelectNamespace extends HTMLFormField {
+
+       /** @var string|null */
+       protected $mAllValue;
+
        public function __construct( $params ) {
                parent::__construct( $params );
 
index fb133f2..47c1f18 100644 (file)
@@ -12,9 +12,7 @@ class HTMLSelectOrOtherField extends HTMLTextField {
                $this->getOptions();
                if ( !in_array( 'other', $this->mOptions, true ) ) {
                        $msg =
-                               isset( $params['other'] )
-                                       ? $params['other']
-                                       : wfMessage( 'htmlform-selectorother-other' )->text();
+                               $params['other'] ?? wfMessage( 'htmlform-selectorother-other' )->text();
                        // Have 'other' always as first element
                        $this->mOptions = [ $msg => 'other' ] + $this->mOptions;
                }
@@ -127,8 +125,14 @@ class HTMLSelectOrOtherField extends HTMLTextField {
                        $textAttribs['placeholder'] = $this->mPlaceholder;
                }
 
+               $disabled = false;
+               if ( isset( $this->mParams[ 'disabled' ] ) && $this->mParams[ 'disabled' ] ) {
+                       $disabled = true;
+               }
+
                return $this->getInputWidget( [
                        'id' => $this->mID,
+                       'disabled' => $disabled,
                        'textinput' => $textAttribs,
                        'dropdowninput' => $dropdownAttribs,
                        'or' => true,
index 145a0ec..d1f628c 100644 (file)
@@ -10,7 +10,7 @@
  */
 class HTMLSizeFilterField extends HTMLIntField {
        public function getSize() {
-               return isset( $this->mParams['size'] ) ? $this->mParams['size'] : 9;
+               return $this->mParams['size'] ?? 9;
        }
 
        public function getInputHTML( $value ) {
@@ -27,7 +27,7 @@ class HTMLSizeFilterField extends HTMLIntField {
                        $value >= 0,
                        $attribs
                );
-               $html .= '&#160;' . Xml::radioLabel(
+               $html .= "\u{00A0}" . Xml::radioLabel(
                        $this->msg( 'maximum-size' )->text(),
                        $this->mName . '-mode',
                        'max',
@@ -35,8 +35,8 @@ class HTMLSizeFilterField extends HTMLIntField {
                        $value < 0,
                        $attribs
                );
-               $html .= '&#160;' . parent::getInputHTML( $value ? abs( $value ) : '' );
-               $html .= '&#160;' . $this->msg( 'pagesize' )->parse();
+               $html .= "\u{00A0}" . parent::getInputHTML( $value ? abs( $value ) : '' );
+               $html .= "\u{00A0}" . $this->msg( 'pagesize' )->parse();
 
                return $html;
        }
index 3370e4a..e9ed031 100644 (file)
@@ -29,15 +29,15 @@ class HTMLTextAreaField extends HTMLFormField {
        }
 
        public function getCols() {
-               return isset( $this->mParams['cols'] ) ? $this->mParams['cols'] : static::DEFAULT_COLS;
+               return $this->mParams['cols'] ?? static::DEFAULT_COLS;
        }
 
        public function getRows() {
-               return isset( $this->mParams['rows'] ) ? $this->mParams['rows'] : static::DEFAULT_ROWS;
+               return $this->mParams['rows'] ?? static::DEFAULT_ROWS;
        }
 
        public function getSpellCheck() {
-               $val = isset( $this->mParams['spellcheck'] ) ? $this->mParams['spellcheck'] : null;
+               $val = $this->mParams['spellcheck'] ?? null;
                if ( is_bool( $val ) ) {
                        // "spellcheck" attribute literally requires "true" or "false" to work.
                        return $val === true ? 'true' : 'false';
index b2e4f2a..b51182a 100644 (file)
@@ -38,11 +38,11 @@ class HTMLTextField extends HTMLFormField {
        }
 
        public function getSize() {
-               return isset( $this->mParams['size'] ) ? $this->mParams['size'] : 45;
+               return $this->mParams['size'] ?? 45;
        }
 
        public function getSpellCheck() {
-               $val = isset( $this->mParams['spellcheck'] ) ? $this->mParams['spellcheck'] : null;
+               $val = $this->mParams['spellcheck'] ?? null;
                if ( is_bool( $val ) ) {
                        // "spellcheck" attribute literally requires "true" or "false" to work.
                        return $val === true ? 'true' : 'false';
@@ -107,7 +107,7 @@ class HTMLTextField extends HTMLFormField {
        }
 
        protected function getType( &$attribs ) {
-               $type = isset( $attribs['type'] ) ? $attribs['type'] : 'text';
+               $type = $attribs['type'] ?? 'text';
                unset( $attribs['type'] );
 
                # Implement tiny differences between some field variants
index 602ddee..0ad41d4 100644 (file)
@@ -41,6 +41,11 @@ class HTMLTitleTextField extends HTMLTextField {
                        return parent::validate( $value, $alldata );
                }
 
+               // Default value (from getDefault()) is null, which breaks Title::newFromTextThrow() below
+               if ( $value === null ) {
+                       $value = '';
+               }
+
                if ( !$this->mParams['required'] && $value === '' ) {
                        // If this field is not required and the value is empty, that's okay, skip validation
                        return parent::validate( $value, $alldata );
index e193970..d672314 100644 (file)
@@ -34,6 +34,11 @@ class HTMLUserTextField extends HTMLTextField {
        }
 
        public function validate( $value, $alldata ) {
+               // Default value (from getDefault()) is null, User::newFromName() expects a string
+               if ( $value === null ) {
+                       $value = '';
+               }
+
                // check, if a user exists with the given username
                $user = User::newFromName( $value, false );
                $rangeError = null;
@@ -43,7 +48,7 @@ class HTMLUserTextField extends HTMLTextField {
                } elseif (
                        // check, if the user exists, if requested
                        ( $this->mParams['exists'] && $user->getId() === 0 ) &&
-                       // check, if the username is a valid IP address, otherweise save the error message
+                       // check, if the username is a valid IP address, otherwise save the error message
                        !( $this->mParams['ipallowed'] && IP::isValid( $value ) ) &&
                        // check, if the username is a valid IP range, otherwise save the error message
                        !( $this->mParams['iprange'] && ( $rangeError = $this->isValidIPRange( $value ) ) === true )
index 46cc6d3..cda69a8 100644 (file)
@@ -3,7 +3,7 @@
 use MediaWiki\Widget\UsersMultiselectWidget;
 
 /**
- * Implements a capsule multiselect input field for user names.
+ * Implements a tag multiselect input field for user names.
  *
  * Besides the parameters recognized by HTMLUserTextField, additional recognized
  * parameters are:
index 44bdddb..bab8521 100644 (file)
@@ -82,16 +82,7 @@ class CurlHttpRequest extends MWHttpRequest {
                        // Don't interpret POST parameters starting with '@' as file uploads, because this
                        // makes it impossible to POST plain values starting with '@' (and causes security
                        // issues potentially exposing the contents of local files).
-                       // The PHP manual says this option was introduced in PHP 5.5 defaults to true in PHP 5.6,
-                       // but we support lower versions, and the option doesn't exist in HHVM 5.6.99.
-                       if ( defined( 'CURLOPT_SAFE_UPLOAD' ) ) {
-                               $this->curlOptions[CURLOPT_SAFE_UPLOAD] = true;
-                       } elseif ( is_array( $postData ) ) {
-                               // In PHP 5.2 and later, '@' is interpreted as a file upload if POSTFIELDS
-                               // is an array, but not if it's a string. So convert $req['body'] to a string
-                               // for safety.
-                               $postData = wfArrayToCgi( $postData );
-                       }
+                       $this->curlOptions[CURLOPT_SAFE_UPLOAD] = true;
                        $this->curlOptions[CURLOPT_POSTFIELDS] = $postData;
 
                        // Suppress 'Expect: 100-continue' header, as some servers
@@ -107,6 +98,7 @@ class CurlHttpRequest extends MWHttpRequest {
                $curlHandle = curl_init( $this->url );
 
                if ( !curl_setopt_array( $curlHandle, $this->curlOptions ) ) {
+                       $this->status->fatal( 'http-internal-error' );
                        throw new InvalidArgumentException( "Error setting curl options." );
                }
 
@@ -158,13 +150,6 @@ class CurlHttpRequest extends MWHttpRequest {
                        return false;
                }
 
-               if ( version_compare( PHP_VERSION, '5.6.0', '<' ) ) {
-                       if ( strval( ini_get( 'open_basedir' ) ) !== '' ) {
-                               $this->logger->debug( "Cannot follow redirects when open_basedir is set\n" );
-                               return false;
-                       }
-               }
-
                return true;
        }
 }
index 70691b4..257955c 100644 (file)
@@ -87,7 +87,7 @@ abstract class MWHttpRequest implements LoggerAwareInterface {
         * @param string $url Url to use. If protocol-relative, will be expanded to an http:// URL
         * @param array $options (optional) extra params to pass (see Http::request())
         * @param string $caller The method making this request, for profiling
-        * @param Profiler $profiler An instance of the profiler for profiling, or null
+        * @param Profiler|null $profiler An instance of the profiler for profiling, or null
         */
        public function __construct(
                $url, array $options = [], $caller = __METHOD__, $profiler = null
@@ -332,6 +332,7 @@ abstract class MWHttpRequest implements LoggerAwareInterface {
                if ( is_null( $callback ) ) {
                        $callback = [ $this, 'read' ];
                } elseif ( !is_callable( $callback ) ) {
+                       $this->status->fatal( 'http-internal-error' );
                        throw new InvalidArgumentException( __METHOD__ . ': invalid callback' );
                }
                $this->callback = $callback;
@@ -387,6 +388,11 @@ abstract class MWHttpRequest implements LoggerAwareInterface {
        protected function parseHeader() {
                $lastname = "";
 
+               // Failure without (valid) headers gets a response status of zero
+               if ( !$this->status->isOK() ) {
+                       $this->respStatus = '0';
+               }
+
                foreach ( $this->headerList as $header ) {
                        if ( preg_match( "#^HTTP/([0-9.]+) (.*)#", $header, $match ) ) {
                                $this->respVersion = $match[1];
index 0636314..30ab181 100644 (file)
@@ -46,21 +46,6 @@ class PhpHttpRequest extends MWHttpRequest {
                $certLocations = [];
                if ( $this->caInfo ) {
                        $certLocations = [ 'manual' => $this->caInfo ];
-               } elseif ( version_compare( PHP_VERSION, '5.6.0', '<' ) ) {
-                       // Default locations, based on
-                       // https://www.happyassassin.net/2015/01/12/a-note-about-ssltls-trusted-certificate-stores-and-platforms/
-                       // PHP 5.5 and older doesn't have any defaults, so we try to guess ourselves.
-                       // PHP 5.6+ gets the CA location from OpenSSL as long as it is not set manually,
-                       // so we should leave capath/cafile empty there.
-                       $certLocations = array_filter( [
-                               getenv( 'SSL_CERT_DIR' ),
-                               getenv( 'SSL_CERT_PATH' ),
-                               '/etc/pki/tls/certs/ca-bundle.crt', # Fedora et al
-                               '/etc/ssl/certs',  # Debian et al
-                               '/etc/pki/tls/certs/ca-bundle.trust.crt',
-                               '/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem',
-                               '/System/Library/OpenSSL', # OSX
-                       ] );
                }
 
                foreach ( $certLocations as $key => $cert ) {
@@ -152,13 +137,7 @@ class PhpHttpRequest extends MWHttpRequest {
                }
 
                if ( $this->sslVerifyHost ) {
-                       // PHP 5.6.0 deprecates CN_match, in favour of peer_name which
-                       // actually checks SubjectAltName properly.
-                       if ( version_compare( PHP_VERSION, '5.6.0', '>=' ) ) {
-                               $options['ssl']['peer_name'] = $this->parsedUrl['host'];
-                       } else {
-                               $options['ssl']['CN_match'] = $this->parsedUrl['host'];
-                       }
+                       $options['ssl']['peer_name'] = $this->parsedUrl['host'];
                }
 
                $options['ssl'] += $this->getCertOptions();
@@ -184,19 +163,6 @@ class PhpHttpRequest extends MWHttpRequest {
                        restore_error_handler();
 
                        if ( !$fh ) {
-                               // HACK for instant commons.
-                               // If we are contacting (commons|upload).wikimedia.org
-                               // try again with CN_match for en.wikipedia.org
-                               // as php does not handle SubjectAltName properly
-                               // prior to "peer_name" option in php 5.6
-                               if ( isset( $options['ssl']['CN_match'] )
-                                       && ( $options['ssl']['CN_match'] === 'commons.wikimedia.org'
-                                               || $options['ssl']['CN_match'] === 'upload.wikimedia.org' )
-                               ) {
-                                       $options['ssl']['CN_match'] = 'en.wikipedia.org';
-                                       $context = stream_context_create( $options );
-                                       continue;
-                               }
                                break;
                        }
 
index 8991f5e..e5dacd7 100644 (file)
@@ -784,7 +784,7 @@ class WikiImporter {
                        } elseif ( $tag == 'revision' || $tag == 'upload' ) {
                                if ( !isset( $title ) ) {
                                        $title = $this->processTitle( $pageInfo['title'],
-                                               isset( $pageInfo['ns'] ) ? $pageInfo['ns'] : null );
+                                               $pageInfo['ns'] ?? null );
 
                                        // $title is either an array of two titles or false.
                                        if ( is_array( $title ) ) {
@@ -1015,7 +1015,7 @@ class WikiImporter {
         */
        private function processUpload( $pageInfo, $uploadInfo ) {
                $revision = new WikiRevision( $this->config );
-               $text = isset( $uploadInfo['text'] ) ? $uploadInfo['text'] : '';
+               $text = $uploadInfo['text'] ?? '';
 
                $revision->setTitle( $pageInfo['_title'] );
                $revision->setID( $pageInfo['id'] );
index 715f5df..4f531da 100644 (file)
@@ -38,7 +38,6 @@ class CliInstaller extends Installer {
                'dbpass' => 'wgDBpassword',
                'dbprefix' => 'wgDBprefix',
                'dbtableoptions' => 'wgDBTableOptions',
-               'dbmysql5' => 'wgDBmysql5',
                'dbport' => 'wgDBport',
                'dbschema' => 'wgDBmwschema',
                'dbpath' => 'wgSQLiteDataDir',
@@ -48,7 +47,7 @@ class CliInstaller extends Installer {
 
        /**
         * @param string $siteName
-        * @param string $admin
+        * @param string|null $admin
         * @param array $option
         */
        function __construct( $siteName, $admin = null, array $option = [] ) {
@@ -97,7 +96,7 @@ class CliInstaller extends Installer {
                        $this->setVar( '_InstallUser',
                                $option['installdbuser'] );
                        $this->setVar( '_InstallPassword',
-                               isset( $option['installdbpass'] ) ? $option['installdbpass'] : "" );
+                               $option['installdbpass'] ?? "" );
 
                        // Assume that if we're given the installer user, we'll create the account.
                        $this->setVar( '_CreateDBAccount', true );
@@ -198,7 +197,7 @@ class CliInstaller extends Installer {
 
                if ( count( $warnings ) !== 0 ) {
                        foreach ( $warnings as $w ) {
-                               call_user_func_array( [ $this, 'showMessage' ], $w );
+                               $this->showMessage( ...$w );
                        }
                }
 
index ba10278..e49a846 100644 (file)
@@ -82,7 +82,7 @@ abstract class DatabaseUpdater {
                PopulateBacklinkNamespace::class,
                FixDefaultJsonContentPages::class,
                CleanupEmptyCategories::class,
-               AddRFCAndPMIDInterwiki::class,
+               AddRFCandPMIDInterwiki::class,
                PopulatePPSortKey::class,
                PopulateIpChanges::class,
        ];
@@ -109,7 +109,7 @@ abstract class DatabaseUpdater {
        /**
         * @param Database &$db To perform updates on
         * @param bool $shared Whether to perform updates on shared tables
-        * @param Maintenance $maintenance Maintenance object which created us
+        * @param Maintenance|null $maintenance Maintenance object which created us
         */
        protected function __construct( Database &$db, $shared, Maintenance $maintenance = null ) {
                $this->db = $db;
@@ -208,6 +208,7 @@ abstract class DatabaseUpdater {
         * Output some text. If we're running from web, escape the text first.
         *
         * @param string $str Text to output
+        * @param-taint $str escapes_html
         */
        public function output( $str ) {
                if ( $this->maintenance->isQuiet() ) {
@@ -410,9 +411,9 @@ abstract class DatabaseUpdater {
 
                foreach ( $updates as $funcList ) {
                        $func = $funcList[0];
-                       $arg = $funcList[1];
+                       $args = $funcList[1];
                        $origParams = $funcList[2];
-                       call_user_func_array( $func, $arg );
+                       $func( ...$args );
                        flush();
                        $this->updatesSkipped[] = $origParams;
                }
@@ -479,7 +480,7 @@ abstract class DatabaseUpdater {
                        } elseif ( $passSelf ) {
                                array_unshift( $params, $this );
                        }
-                       $ret = call_user_func_array( $func, $params );
+                       $ret = $func( ...$params );
                        flush();
                        if ( $ret !== false ) {
                                $updatesDone[] = $origParams;
@@ -516,7 +517,7 @@ abstract class DatabaseUpdater {
         * Obviously, only use this for updates that occur after the updatelog table was
         * created!
         * @param string $key Name of key to insert
-        * @param string $val [optional] Value to insert along with the key
+        * @param string|null $val [optional] Value to insert along with the key
         */
        public function insertUpdateRow( $key, $val = null ) {
                $this->db->clearFlag( DBO_DDLMODE );
@@ -659,7 +660,7 @@ abstract class DatabaseUpdater {
         *
         * @param string $path Path to the patch file
         * @param bool $isFullPath Whether to treat $path as a relative or not
-        * @param string $msg Description of the patch
+        * @param string|null $msg Description of the patch
         * @return bool False if patch is skipped.
         */
        protected function applyPatch( $path, $isFullPath = false, $msg = null ) {
@@ -779,6 +780,39 @@ abstract class DatabaseUpdater {
                return true;
        }
 
+       /**
+        * Add a new index to an existing table if none of the given indexes exist
+        *
+        * @param string $table Name of the table to modify
+        * @param string[] $indexes Name of the indexes to check. $indexes[0] should
+        *  be the one actually being added.
+        * @param string $patch Path to the patch file
+        * @param bool $fullpath Whether to treat $patch path as a relative or not
+        * @return bool False if this was skipped because schema changes are skipped
+        */
+       protected function addIndexIfNoneExist( $table, $indexes, $patch, $fullpath = false ) {
+               if ( !$this->doTable( $table ) ) {
+                       return true;
+               }
+
+               if ( !$this->db->tableExists( $table, __METHOD__ ) ) {
+                       $this->output( "...skipping: '$table' table doesn't exist yet.\n" );
+                       return true;
+               }
+
+               $newIndex = $indexes[0];
+               foreach ( $indexes as $index ) {
+                       if ( $this->db->indexExists( $table, $index, __METHOD__ ) ) {
+                               $this->output(
+                                       "...skipping index $newIndex because index $index already set on $table table.\n"
+                               );
+                               return true;
+                       }
+               }
+
+               return $this->applyPatch( $patch, $fullpath, "Adding index $index to table $table" );
+       }
+
        /**
         * Drop a field from an existing table
         *
@@ -1329,4 +1363,29 @@ abstract class DatabaseUpdater {
                        $this->output( "done.\n" );
                }
        }
+
+       /**
+        * Populates the MCR content tables
+        * @since 1.32
+        */
+       protected function populateContentTables() {
+               global $wgMultiContentRevisionSchemaMigrationStage;
+               if ( ( $wgMultiContentRevisionSchemaMigrationStage & SCHEMA_COMPAT_WRITE_NEW ) &&
+                       !$this->updateRowExists( 'PopulateContentTables' )
+               ) {
+                       $this->output(
+                               "Migrating revision data to the MCR 'slot' and 'content' tables, printing progress markers.\n" .
+                               "For large databases, you may want to hit Ctrl-C and do this manually with\n" .
+                               "maintenance/populateContentTables.php.\n"
+                       );
+                       $task = $this->maintenance->runChild(
+                               PopulateContentTables::class, 'populateContentTables.php'
+                       );
+                       $ok = $task->execute();
+                       $this->output( $ok ? "done.\n" : "errors were encountered.\n" );
+                       if ( $ok ) {
+                               $this->insertUpdateRow( 'PopulateContentTables' );
+                       }
+               }
+       }
 }
index 93da2c3..367149d 100644 (file)
@@ -23,6 +23,8 @@
  * @file
  * @ingroup Deployment
  */
+
+use MediaWiki\Interwiki\NullInterwikiLookup;
 use MediaWiki\MediaWikiServices;
 use MediaWiki\Shell\Shell;
 
@@ -404,7 +406,7 @@ abstract class Installer {
                $installerConfig = self::getInstallerConfig( $defaultConfig );
 
                // Reset all services and inject config overrides
-               MediaWiki\MediaWikiServices::resetGlobalInstance( $installerConfig );
+               MediaWikiServices::resetGlobalInstance( $installerConfig );
 
                // Don't attempt to load user language options (T126177)
                // This will be overridden in the web installer with the user-specified language
@@ -415,13 +417,19 @@ abstract class Installer {
                Language::getLocalisationCache()->disableBackend();
 
                // Disable all global services, since we don't have any configuration yet!
-               MediaWiki\MediaWikiServices::disableStorageBackend();
+               MediaWikiServices::disableStorageBackend();
 
+               $mwServices = MediaWikiServices::getInstance();
                // Disable object cache (otherwise CACHE_ANYTHING will try CACHE_DB and
                // SqlBagOStuff will then throw since we just disabled wfGetDB)
-               $wgObjectCaches = MediaWikiServices::getInstance()->getMainConfig()->get( 'ObjectCaches' );
+               $wgObjectCaches = $mwServices->getMainConfig()->get( 'ObjectCaches' );
                $wgMemc = ObjectCache::getInstance( CACHE_NONE );
 
+               // Disable interwiki lookup, to avoid database access during parses
+               $mwServices->redefineService( 'InterwikiLookup', function () {
+                       return new NullInterwikiLookup();
+               } );
+
                // Having a user with id = 0 safeguards us from DB access via User::loadOptions().
                $wgUser = User::newFromId( 0 );
                RequestContext::getMain()->setUser( $wgUser );
@@ -523,7 +531,7 @@ abstract class Installer {
         * Installer variables are typically prefixed by an underscore.
         *
         * @param string $name
-        * @param mixed $default
+        * @param mixed|null $default
         *
         * @return mixed
         */
@@ -811,7 +819,7 @@ abstract class Installer {
                // with utf8 support, but not unicode property support.
                // check that \p{Zs} (space separators) matches
                // U+3000 (Ideographic space)
-               $regexprop = preg_replace( '/\p{Zs}/u', '', "-\xE3\x80\x80-" );
+               $regexprop = preg_replace( '/\p{Zs}/u', '', "-\u{3000}-" );
                Wikimedia\restoreWarnings();
                if ( $regexd != '--' || $regexprop != '--' ) {
                        $this->showError( 'config-pcre-no-utf8' );
@@ -1107,29 +1115,6 @@ abstract class Installer {
                return true;
        }
 
-       /**
-        * Convert a hex string representing a Unicode code point to that code point.
-        * @param string $c
-        * @return string|false
-        */
-       protected function unicodeChar( $c ) {
-               $c = hexdec( $c );
-               if ( $c <= 0x7F ) {
-                       return chr( $c );
-               } elseif ( $c <= 0x7FF ) {
-                       return chr( 0xC0 | $c >> 6 ) . chr( 0x80 | $c & 0x3F );
-               } elseif ( $c <= 0xFFFF ) {
-                       return chr( 0xE0 | $c >> 12 ) . chr( 0x80 | $c >> 6 & 0x3F ) .
-                               chr( 0x80 | $c & 0x3F );
-               } elseif ( $c <= 0x10FFFF ) {
-                       return chr( 0xF0 | $c >> 18 ) . chr( 0x80 | $c >> 12 & 0x3F ) .
-                               chr( 0x80 | $c >> 6 & 0x3F ) .
-                               chr( 0x80 | $c & 0x3F );
-               } else {
-                       return false;
-               }
-       }
-
        /**
         * Check the libicu version
         */
@@ -1141,8 +1126,8 @@ abstract class Installer {
                 * Note that we use the hex representation to create the code
                 * points in order to avoid any Unicode-destroying during transit.
                 */
-               $not_normal_c = $this->unicodeChar( "FA6C" );
-               $normal_c = $this->unicodeChar( "242EE" );
+               $not_normal_c = "\u{FA6C}";
+               $normal_c = "\u{242EE}";
 
                $useNormalizer = 'php';
                $needsUpdate = false;
@@ -1203,7 +1188,7 @@ abstract class Installer {
                $scriptTypes = [
                        'php' => [
                                "<?php echo 'ex' . 'ec';",
-                               "#!/var/env php5\n<?php echo 'ex' . 'ec';",
+                               "#!/var/env php\n<?php echo 'ex' . 'ec';",
                        ],
                ];
 
@@ -1612,28 +1597,16 @@ abstract class Installer {
        protected function doGenerateKeys( $keys ) {
                $status = Status::newGood();
 
-               $strong = true;
                foreach ( $keys as $name => $length ) {
-                       $secretKey = MWCryptRand::generateHex( $length, true );
-                       if ( !MWCryptRand::wasStrong() ) {
-                               $strong = false;
-                       }
-
+                       $secretKey = MWCryptRand::generateHex( $length );
                        $this->setVar( $name, $secretKey );
                }
 
-               if ( !$strong ) {
-                       $names = array_keys( $keys );
-                       $names = preg_replace( '/^(.*)$/', '\$$1', $names );
-                       global $wgLang;
-                       $status->warning( 'config-insecure-keys', $wgLang->listToText( $names ), count( $names ) );
-               }
-
                return $status;
        }
 
        /**
-        * Create the first user account, grant it sysop and bureaucrat rights
+        * Create the first user account, grant it sysop, bureaucrat and interface-admin rights
         *
         * @return Status
         */
@@ -1657,6 +1630,7 @@ abstract class Installer {
 
                        $user->addGroup( 'sysop' );
                        $user->addGroup( 'bureaucrat' );
+                       $user->addGroup( 'interface-admin' );
                        if ( $this->getVar( '_AdminEmail' ) ) {
                                $user->setEmail( $this->getVar( '_AdminEmail' ) );
                        }
@@ -1752,13 +1726,10 @@ abstract class Installer {
                $GLOBALS['wgLanguageConverterCacheType'] = CACHE_NONE;
                // Debug-friendly
                $GLOBALS['wgShowExceptionDetails'] = true;
+               $GLOBALS['wgShowHostnames'] = true;
                // Don't break forms
                $GLOBALS['wgExternalLinkTarget'] = '_blank';
 
-               // Extended debugging
-               $GLOBALS['wgShowSQLErrors'] = true;
-               $GLOBALS['wgShowDBErrorBacktrace'] = true;
-
                // Allow multiple ob_flush() calls
                $GLOBALS['wgDisableOutputCompression'] = true;
 
index 44b4e30..50c4517 100644 (file)
@@ -114,11 +114,11 @@ class MssqlUpdater extends DatabaseUpdater {
                        [ 'migrateComments' ],
 
                        // 1.31
-                       [ 'addTable', 'slots', 'patch-slots.sql' ],
-                       [ 'addField', 'slots', 'slot_origin', 'patch-slot-origin.sql' ],
-                       [ 'addTable', 'content', 'patch-content.sql' ],
                        [ 'addTable', 'slot_roles', 'patch-slot_roles.sql' ],
                        [ 'addTable', 'content_models', 'patch-content_models.sql' ],
+                       [ 'addTable', 'content', 'patch-content.sql' ],
+                       [ 'addTable', 'slots', 'patch-slots.sql' ],
+                       [ 'addField', 'slots', 'slot_origin', 'patch-slot-origin.sql' ],
                        [ 'migrateArchiveText' ],
                        [ 'addTable', 'actor', 'patch-actor-table.sql' ],
                        [ 'migrateActors' ],
@@ -136,6 +136,14 @@ class MssqlUpdater extends DatabaseUpdater {
                                'patch-externallinks-el_index_60-drop-default.sql' ],
                        [ 'runMaintenance', DeduplicateArchiveRevId::class, 'maintenance/deduplicateArchiveRevId.php' ],
                        [ 'addField', 'change_tag', 'ct_tag_id', 'patch-change_tag-tag_id.sql' ],
+                       [ 'addIndex', 'archive', 'ar_revid_uniq', 'patch-archive-ar_rev_id-unique.sql' ],
+                       [ 'populateContentTables' ],
+                       [ 'addIndex', 'logging', 'log_type_action', 'patch-logging-log-type-action-index.sql' ],
+                       [ 'dropIndex', 'logging', 'type_action', 'patch-logging-drop-type-action-index.sql' ],
+                       [ 'addIndex', 'interwiki', 'PRIMARY', 'patch-interwiki-pk.sql' ],
+                       [ 'addIndex', 'protected_titles', 'PRIMARY', 'patch-protected_titles-pk.sql' ],
+                       [ 'addIndex', 'page_props', 'PRIMARY', 'patch-page_props-pk.sql' ],
+                       [ 'addIndex', 'site_identifiers', 'PRIMARY', 'patch-site_identifiers-pk.sql' ],
                ];
        }
 
index 6256204..45f932a 100644 (file)
@@ -40,7 +40,6 @@ class MysqlInstaller extends DatabaseInstaller {
                'wgDBpassword',
                'wgDBprefix',
                'wgDBTableOptions',
-               'wgDBmysql5',
        ];
 
        protected $internalDefaults = [
@@ -414,20 +413,6 @@ class MysqlInstaller extends DatabaseInstaller {
                        $this->setVar( '_MysqlCharset', reset( $charsets ) );
                }
 
-               // Do charset selector
-               if ( count( $charsets ) >= 2 ) {
-                       // getRadioSet() builds a set of labeled radio buttons.
-                       // For grep: The following messages are used as the item labels:
-                       // config-mysql-binary, config-mysql-utf8
-                       $s .= $this->getRadioSet( [
-                               'var' => '_MysqlCharset',
-                               'label' => 'config-mysql-charset',
-                               'itemLabelPrefix' => 'config-mysql-',
-                               'values' => $charsets
-                       ] );
-                       $s .= $this->parent->getHelpBox( 'config-mysql-charset-help' );
-               }
-
                return $s;
        }
 
@@ -671,7 +656,6 @@ class MysqlInstaller extends DatabaseInstaller {
        }
 
        public function getLocalSettings() {
-               $dbmysql5 = wfBoolToStr( $this->getVar( 'wgDBmysql5', true ) );
                $prefix = LocalSettingsGenerator::escapePhpString( $this->getVar( 'wgDBprefix' ) );
                $tblOpts = LocalSettingsGenerator::escapePhpString( $this->getTableOptions() );
 
@@ -679,9 +663,6 @@ class MysqlInstaller extends DatabaseInstaller {
 \$wgDBprefix = \"{$prefix}\";
 
 # MySQL table options to use during installation or update
-\$wgDBTableOptions = \"{$tblOpts}\";
-
-# Experimental charset support for MySQL 5.0.
-\$wgDBmysql5 = {$dbmysql5};";
+\$wgDBTableOptions = \"{$tblOpts}\";";
        }
 }
index d70edea..99d6b35 100644 (file)
@@ -185,7 +185,8 @@ class MysqlUpdater extends DatabaseUpdater {
                        [ 'doClFieldsUpdate' ],
                        [ 'addTable', 'module_deps', 'patch-module_deps.sql' ],
                        [ 'dropIndex', 'archive', 'ar_page_revid', 'patch-archive_kill_ar_page_revid.sql' ],
-                       [ 'addIndex', 'archive', 'ar_revid', 'patch-archive_ar_revid.sql' ],
+                       [ 'addIndexIfNoneExist',
+                               'archive', [ 'ar_revid', 'ar_revid_uniq' ], 'patch-archive_ar_revid.sql' ],
                        [ 'doLangLinksLengthUpdate' ],
 
                        // 1.18
@@ -196,7 +197,6 @@ class MysqlUpdater extends DatabaseUpdater {
                        [ 'addTable', 'user_former_groups', 'patch-user_former_groups.sql' ],
 
                        // 1.19
-                       [ 'addIndex', 'logging', 'type_action', 'patch-logging-type-action-index.sql' ],
                        [ 'addField', 'revision', 'rev_sha1', 'patch-rev_sha1.sql' ],
                        [ 'doMigrateUserOptions' ],
                        [ 'dropField', 'user', 'user_options', 'patch-drop-user_options.sql' ],
@@ -356,6 +356,17 @@ class MysqlUpdater extends DatabaseUpdater {
                                'patch-externallinks-el_index_60-drop-default.sql' ],
                        [ 'runMaintenance', DeduplicateArchiveRevId::class, 'maintenance/deduplicateArchiveRevId.php' ],
                        [ 'addField', 'change_tag', 'ct_tag_id', 'patch-change_tag-tag_id.sql' ],
+                       [ 'addIndex', 'archive', 'ar_revid_uniq', 'patch-archive-ar_rev_id-unique.sql' ],
+                       [ 'populateContentTables' ],
+                       [ 'addIndex', 'logging', 'log_type_action', 'patch-logging-log-type-action-index.sql' ],
+                       [ 'dropIndex', 'logging', 'type_action', 'patch-logging-drop-type-action-index.sql' ],
+                       [ 'renameIndex', 'interwiki', 'iw_prefix', 'PRIMARY', false, 'patch-interwiki-fix-pk.sql' ],
+                       [ 'renameIndex', 'page_props', 'pp_page_propname', 'PRIMARY', false,
+                               'patch-page_props-fix-pk.sql' ],
+                       [ 'renameIndex', 'protected_titles', 'pt_namespace_title', 'PRIMARY', false,
+                               'patch-protected_titles-fix-pk.sql' ],
+                       [ 'renameIndex', 'site_identifiers', 'site_ids_type', 'PRIMARY', false,
+                               'patch-site_identifiers-fix-pk.sql' ],
                ];
        }
 
@@ -1220,7 +1231,7 @@ class MysqlUpdater extends DatabaseUpdater {
                                'Extending edit summary lengths (and setting defaults)'
                        );
                } else {
-                       $this->output( '...comment fields are up to date' );
+                       $this->output( "...comment fields are up to date.\n" );
                }
        }
 
index 965187a..c9ed53f 100644 (file)
@@ -153,6 +153,8 @@ class OracleUpdater extends DatabaseUpdater {
                        [ 'populateExternallinksIndex60' ],
                        [ 'runMaintenance', DeduplicateArchiveRevId::class, 'maintenance/deduplicateArchiveRevId.php' ],
                        [ 'addField', 'change_tag', 'ct_tag_id', 'patch-change_tag-tag_id.sql' ],
+                       [ 'addIndex', 'archive', 'ar_revid_uniq', 'patch-archive-ar_rev_id-unique.sql' ],
+                       [ 'populateContentTables' ],
 
                        // KEEP THIS AT THE BOTTOM!!
                        [ 'doRebuildDuplicateFunction' ],
index 49419ea..932c941 100644 (file)
@@ -582,6 +582,14 @@ class PostgresUpdater extends DatabaseUpdater {
                                'change_tag_tag_id_id',
                                '( ct_tag_id, ct_rc_id, ct_rev_id, ct_log_id )'
                        ],
+                       [ 'addPgIndex', 'archive', 'ar_revid_uniq', '(ar_rev_id)', 'unique' ],
+                       [ 'dropPgIndex', 'archive', 'ar_revid' ], // Probably doesn't exist, but do it anyway.
+                       [ 'populateContentTables' ],
+                       [ 'addPgIndex', 'logging', 'log_type_action', '( log_type, log_action, log_timestamp )' ],
+                       [ 'dropPgIndex', 'page_props', 'page_props_propname' ],
+                       [ 'addIndex', 'interwiki', 'interwiki_pkey', 'patch-interwiki-pk.sql' ],
+                       [ 'addIndex', 'protected_titles', 'protected_titles_pkey', 'patch-protected_titles-pk.sql' ],
+                       [ 'addIndex', 'site_identifiers', 'site_identifiers_pkey', 'patch-site_identifiers-pk.sql' ],
                ];
        }
 
@@ -959,12 +967,13 @@ END;
                }
        }
 
-       public function addPgIndex( $table, $index, $type ) {
+       public function addPgIndex( $table, $index, $type, $unique = false ) {
                if ( $this->db->indexExists( $table, $index ) ) {
                        $this->output( "...index '$index' on table '$table' already exists\n" );
                } else {
                        $this->output( "Creating index '$index' on table '$table' $type\n" );
-                       $this->db->query( "CREATE INDEX $index ON $table $type" );
+                       $unique = $unique ? 'UNIQUE' : '';
+                       $this->db->query( "CREATE $unique INDEX $index ON $table $type" );
                }
        }
 
index 2b27d37..80eb843 100644 (file)
@@ -68,7 +68,8 @@ class SqliteUpdater extends DatabaseUpdater {
                        [ 'addField', 'categorylinks', 'cl_collation', 'patch-categorylinks-better-collation.sql' ],
                        [ 'addTable', 'module_deps', 'patch-module_deps.sql' ],
                        [ 'dropIndex', 'archive', 'ar_page_revid', 'patch-archive_kill_ar_page_revid.sql' ],
-                       [ 'addIndex', 'archive', 'ar_revid', 'patch-archive_ar_revid.sql' ],
+                       [ 'addIndexIfNoneExist',
+                               'archive', [ 'ar_revid', 'ar_revid_uniq' ], 'patch-archive_ar_revid.sql' ],
 
                        // 1.18
                        [ 'addIndex', 'user', 'user_email', 'patch-user_email_index.sql' ],
@@ -76,7 +77,6 @@ class SqliteUpdater extends DatabaseUpdater {
                        [ 'addTable', 'user_former_groups', 'patch-user_former_groups.sql' ],
 
                        // 1.19
-                       [ 'addIndex', 'logging', 'type_action', 'patch-logging-type-action-index.sql' ],
                        [ 'doMigrateUserOptions' ],
                        [ 'dropField', 'user', 'user_options', 'patch-drop-user_options.sql' ],
                        [ 'addField', 'revision', 'rev_sha1', 'patch-rev_sha1.sql' ],
@@ -220,6 +220,17 @@ class SqliteUpdater extends DatabaseUpdater {
                                'patch-externallinks-el_index_60-drop-default.sql' ],
                        [ 'runMaintenance', DeduplicateArchiveRevId::class, 'maintenance/deduplicateArchiveRevId.php' ],
                        [ 'addField', 'change_tag', 'ct_tag_id', 'patch-change_tag-tag_id.sql' ],
+                       [ 'addIndex', 'archive', 'ar_revid_uniq', 'patch-archive-ar_rev_id-unique.sql' ],
+                       [ 'populateContentTables' ],
+                       [ 'addIndex', 'logging', 'log_type_action', 'patch-logging-log-type-action-index.sql' ],
+                       [ 'dropIndex', 'logging', 'type_action', 'patch-logging-drop-type-action-index.sql' ],
+                       [ 'renameIndex', 'interwiki', 'iw_prefix', 'PRIMARY', false, 'patch-interwiki-fix-pk.sql' ],
+                                               [ 'renameIndex', 'page_props', 'pp_page_propname', 'PRIMARY', false,
+                               'patch-page_props-fix-pk.sql' ],
+                       [ 'renameIndex', 'protected_titles', 'pt_namespace_title', 'PRIMARY', false,
+                               'patch-protected_titles-fix-pk.sql' ],
+                       [ 'renameIndex', 'site_identifiers', 'site_ids_type', 'PRIMARY', false,
+                               'patch-site_identifiers-fix-pk.sql' ],
                ];
        }
 
index 8fb9807..739d9f2 100644 (file)
@@ -166,18 +166,7 @@ class WebInstaller extends Installer {
                if ( ( $this->getVar( '_InstallDone' ) || $this->getVar( '_UpgradeDone' ) )
                        && $this->request->getVal( 'localsettings' )
                ) {
-                       $this->request->response()->header( 'Content-type: application/x-httpd-php' );
-                       $this->request->response()->header(
-                               'Content-Disposition: attachment; filename="LocalSettings.php"'
-                       );
-
-                       $ls = InstallerOverrides::getLocalSettingsGenerator( $this );
-                       $rightsProfile = $this->rightsProfiles[$this->getVar( '_RightsProfile' )];
-                       foreach ( $rightsProfile as $group => $rightsArr ) {
-                               $ls->setGroupRights( $group, $rightsArr );
-                       }
-                       echo $ls->getText();
-
+                       $this->outputLS();
                        return $this->session;
                }
 
@@ -472,7 +461,7 @@ class WebInstaller extends Installer {
         * Get a session variable.
         *
         * @param string $name
-        * @param array $default
+        * @param array|null $default
         *
         * @return array
         */
@@ -529,7 +518,7 @@ class WebInstaller extends Installer {
        public function getAcceptLanguage() {
                global $wgLanguageCode, $wgRequest;
 
-               $mwLanguages = Language::fetchLanguageNames();
+               $mwLanguages = Language::fetchLanguageNames( null, 'mwfile' );
                $headerLanguages = array_keys( $wgRequest->getAcceptLang() );
 
                foreach ( $headerLanguages as $lang ) {
@@ -717,7 +706,7 @@ class WebInstaller extends Installer {
         */
        public function showHelpBox( $msg /*, ... */ ) {
                $args = func_get_args();
-               $html = call_user_func_array( [ $this, 'getHelpBox' ], $args );
+               $html = $this->getHelpBox( ...$args );
                $this->output->addHTML( $html );
        }
 
@@ -742,7 +731,7 @@ class WebInstaller extends Installer {
        public function showStatusMessage( Status $status ) {
                $errors = array_merge( $status->getErrorsArray(), $status->getWarningsArray() );
                foreach ( $errors as $error ) {
-                       call_user_func_array( [ $this, 'showMessage' ], $error );
+                       $this->showMessage( ...$error );
                }
        }
 
@@ -758,7 +747,7 @@ class WebInstaller extends Installer {
         */
        public function label( $msg, $forId, $contents, $helpData = "" ) {
                if ( strval( $msg ) == '' ) {
-                       $labelText = '&#160;';
+                       $labelText = "\u{00A0}";
                } else {
                        $labelText = wfMessage( $msg )->escaped();
                }
@@ -1047,7 +1036,7 @@ class WebInstaller extends Installer {
 
                        $items[$value] =
                                Xml::radio( $params['controlName'], $value, $checked, $itemAttribs ) .
-                               '&#160;' .
+                               "\u{00A0}" .
                                Xml::tags( 'label', [ 'for' => $id ], $this->parse(
                                        isset( $params['itemLabels'] ) ?
                                                wfMessage( $params['itemLabels'][$value] )->plain() :
@@ -1121,13 +1110,13 @@ class WebInstaller extends Installer {
         * @return string
         */
        protected function getDocUrl( $page ) {
-               $url = "{$_SERVER['PHP_SELF']}?page=" . urlencode( $page );
+               $query = [ 'page' => $page ];
 
                if ( in_array( $this->currentPageName, $this->pageSequence ) ) {
-                       $url .= '&lastPage=' . urlencode( $this->currentPageName );
+                       $query['lastPage'] = $this->currentPageName;
                }
 
-               return $url;
+               return $this->getUrl( $query );
        }
 
        /**
@@ -1142,9 +1131,7 @@ class WebInstaller extends Installer {
        public function docLink( $linkText, $attribs, $parser ) {
                $url = $this->getDocUrl( $attribs['href'] );
 
-               return '<a href="' . htmlspecialchars( $url ) . '">' .
-                       htmlspecialchars( $linkText ) .
-                       '</a>';
+               return Html::element( 'a', [ 'href' => $url ], $linkText );
        }
 
        /**
@@ -1233,6 +1220,25 @@ class WebInstaller extends Installer {
                return WebRequest::detectServer();
        }
 
+       /**
+        * Actually output LocalSettings.php for download
+        *
+        * @suppress SecurityCheck-XSS
+        */
+       private function outputLS() {
+               $this->request->response()->header( 'Content-type: application/x-httpd-php' );
+               $this->request->response()->header(
+                       'Content-Disposition: attachment; filename="LocalSettings.php"'
+               );
+
+               $ls = InstallerOverrides::getLocalSettingsGenerator( $this );
+               $rightsProfile = $this->rightsProfiles[$this->getVar( '_RightsProfile' )];
+               foreach ( $rightsProfile as $group => $rightsArr ) {
+                       $ls->setGroupRights( $group, $rightsArr );
+               }
+               echo $ls->getText();
+       }
+
        /**
         * Output stylesheet for web installer pages
         */
index df68be8..0c7428f 100644 (file)
@@ -180,9 +180,7 @@ class WebInstallerExistingWiki extends WebInstallerPage {
 
                // Copy $wgAuthenticationTokenVersion too, if it exists
                $this->setVar( 'wgAuthenticationTokenVersion',
-                       isset( $vars['wgAuthenticationTokenVersion'] )
-                               ? $vars['wgAuthenticationTokenVersion']
-                               : null
+                       $vars['wgAuthenticationTokenVersion'] ?? null
                );
 
                return $status;
index 846be6c..85d1a2d 100644 (file)
@@ -30,7 +30,7 @@ class WebInstallerLanguage extends WebInstallerPage {
                $userLang = $r->getVal( 'uselang' );
                $contLang = $r->getVal( 'ContLang' );
 
-               $languages = Language::fetchLanguageNames();
+               $languages = Language::fetchLanguageNames( null, 'mwfile' );
                $lifetime = intval( ini_get( 'session.gc_maxlifetime' ) );
                if ( !$lifetime ) {
                        $lifetime = 1440; // PHP default
@@ -98,20 +98,13 @@ class WebInstallerLanguage extends WebInstallerPage {
         * @return string
         */
        public function getLanguageSelector( $name, $label, $selectedCode, $helpHtml = '' ) {
-               global $wgExtraLanguageCodes;
-
                $output = $helpHtml;
 
                $select = new XmlSelect( $name, $name, $selectedCode );
                $select->setAttribute( 'tabindex', $this->parent->nextTabIndex() );
 
-               $unwantedLanguageCodes = $wgExtraLanguageCodes +
-                       LanguageCode::getDeprecatedCodeMapping();
-               $languages = Language::fetchLanguageNames();
+               $languages = Language::fetchLanguageNames( null, 'mwfile' );
                foreach ( $languages as $code => $lang ) {
-                       if ( isset( $unwantedLanguageCodes[$code] ) ) {
-                               continue;
-                       }
                        $select->addOption( "$code - $lang", $code );
                }
 
index 50c88ae..09fc0f3 100644 (file)
@@ -223,7 +223,7 @@ class WebInstallerName extends WebInstallerPage {
                        $status = $upp->checkUserPasswordForGroups(
                                $user,
                                $pwd,
-                               [ 'bureaucrat', 'sysop' ]  // per Installer::createSysop()
+                               [ 'bureaucrat', 'sysop', 'interface-admin' ]  // per Installer::createSysop()
                        );
                        $valid = $status->isGood() ? true : $status->getMessage();
                } else {
index d798ea1..382ed3b 100644 (file)
@@ -412,7 +412,7 @@ class WebInstallerOptions extends WebInstallerPage {
 
                return '<p>' .
                        Html::element( 'img', [ 'src' => $this->getVar( 'wgRightsIcon' ) ] ) .
-                       '&#160;&#160;' .
+                       "\u{00A0}\u{00A0}" .
                        htmlspecialchars( $this->getVar( 'wgRightsText' ) ) .
                        "</p>\n" .
                        "<p style=\"text-align: center;\">" .
index 3aad6f8..1c5fa0e 100644 (file)
@@ -145,7 +145,7 @@ abstract class WebInstallerPage {
 
        /**
         * @param string $var
-        * @param mixed $default
+        * @param mixed|null $default
         *
         * @return mixed
         */
index 58c6b72..c74f637 100644 (file)
@@ -75,9 +75,6 @@
        "config-mysql-engine": "Stoor-enjin:",
        "config-mysql-innodb": "InnoDB",
        "config-mysql-myisam": "MyISAM",
-       "config-mysql-charset": "Karakterstelsel vir databasis:",
-       "config-mysql-binary": "Binêr",
-       "config-mysql-utf8": "UTF-8",
        "config-site-name": "Naam van die wiki:",
        "config-site-name-blank": "Verskaf 'n naam vir u webwerf.",
        "config-project-namespace": "Projeknaamruimte:",
index dfac82e..dcccd22 100644 (file)
        "config-env-php": "بي إتش بي $1 مثبت.",
        "config-env-hhvm": "نصبت HHVM $1.",
        "config-unicode-using-intl": "باستخدام [https://pecl.php.net/intl امتداد intl PECL] لتسوية يونيكود.",
+       "config-unicode-pure-php-warning": "<strong>تحذير:</strong> لا يتوفر [https://pecl.php.net/intl امتداد intl PECL] للتعامل مع تطبيع يونيكود; حيث يتراجع لإبطاء تنفيذ Pure-Pure;\nإذا كنت تدير موقعا عالي الزيارات، فتجب عليك القراءة قليلا في [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations تطبيع يونيكود].",
+       "config-unicode-update-warning": "<strong>تحذير:</strong> يستخدم الإصدار المثبت من برنامج تطبيع نظام يونيكود إصدارًا قديما من مكتبة [http://site.icu-project.org/ مشروع ICU];\nتجب عليك [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations الترقية] إذا كنت مهتما باستخدام يونيكود.",
+       "config-no-db": "لا يمكن العثور على مشغل قاعدة بيانات مناسب! تحتاج إلى تثبيت مشغل قاعدة بيانات PHP، \n{{PLURAL:$2|نوع قاعدة البيانات التالي مدعوم|أنواع قاعدة البيانات التالية مدعومة}} البيانات التالية مدعومة: $1.\n\nإذا قمت بتجميع PHP بنفسك، فقم بتكوينها مع تمكين عميل قاعدة البيانات، على سبيل المثال، باستخدام <code>./configure --with-mysqli</code>.\nإذا قمت بتثبيت PHP من حزمة Debian أو Ubuntu، فستحتاج أيضا إلى تثبيت، على سبيل المثال، حزمة <code>php-mysql</code>.",
        "config-outdated-sqlite": "<strong>تحذير:</strong> لديك SQLite $1, which وهو أقل من الحد الأدنى المطلوب للنسخة $2. SQLite سوف يكون غير متوفر.",
+       "config-no-fts3": "<strong>تحذير:</strong> يتم تجميع SQLite بدون [//sqlite.org/fts3.html FTS3 module]; ستكون ميزات البحث غير متوفرة في هذه الواجهة الخلفية.",
+       "config-pcre-old": "<strong>فادح:</strong> مطلوب PCRE $1 أو أحدث،\nترتبط ثنائية PHP الخاصة بك بـPCRE $2.\n[https://www.mediawiki.org/wiki/Manual:Errors_and_symptoms/PCRE مزيد من المعلومات].",
+       "config-pcre-no-utf8": "<strong>فادح:</strong> يبدو أن وحدة PCRE في PHP يتم تجميعها بدون دعم PCRE_UTF8، \nيتطلب ميدياويكي دعم UTF-8 ليعمل بشكل صحيح.",
+       "config-memory-raised": "<code>memory_limit</code> في PHP $1 ومرتفعة إلى $2.",
+       "config-memory-bad": "<strong>تحذير:</strong> في PHP <code>memory_limit</code> $1،\nهذا على الارجح منخفض جدا;\nقد يفشل التثبيت!",
        "config-apc": "تثبيت [https://secure.php.net/apc APC]",
-       "config-apcu": "تثبيت [https://secure.php.net/apcu APCu]",
+       "config-apcu": "[https://secure.php.net/apcu APCu] مثبت",
        "config-wincache": "تثبيت [https://www.iis.net/downloads/microsoft/wincache-extension WinCache]",
+       "config-no-cache-apcu": "<strong>تحذير:</strong> تعذر العثور على [https://secure.php.net/apcu APCu] أو [https://www.iis.net/downloads/microsoft/wincache-extension WinCache];\nكائن التخزين المؤقت غير ممكّّن.",
+       "config-mod-security": "<strong>تحذير:</strong> تم تمكين خادم الويب الخاص بك [https://modsecurity.org/ mod_security]/mod_security2، العديد من التكوينات الشائعة له سوف تتسبب في مشاكل لميدياويكي والبرامج الأخرى التي تسمح للمستخدمين بنشر محتوى عشوائي; \nإذا كان ذلك ممكنا، يجب تعطيل هذا، أو يمكنك الرجوع إلى [https://modsecurity.org/documentation/ توثيق mod_security] أو الاتصال بدعم مضيفك إذا واجهتك أخطاء عشوائية.",
        "config-diff3-bad": "جنو diff3 غير موجود.",
        "config-git": "العثور على برنامج التحكم في إصدار جت <code>$1</code>.",
        "config-git-bad": "برنامج التحكم في إصدار جت غير موجود.",
        "config-no-cli-uri": "<strong>تحذير:</strong> لم يتم تحديد <code>--scriptpath</code>، باستخدام الافتراضي: <code>$1</code>.",
        "config-using-server": "باستخدام اسم الخادم \"<nowiki>$1</nowiki\".",
        "config-using-uri": "باستخدام URL الخادم \"<nowiki>$1$2</nowiki>\".",
+       "config-uploads-not-safe": "<strong>تحذير:</strong>  الدليل الافتراضي للمرفوعات <code>$1</code> عرضة لتنفيذ سكريبتات عشوائية،\nعلى الرغم من أن ميدياويكي يتحقق من كل الملفات المرفوعة للتهديدات الأمنية، فمن المستحسن بشدة [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Security#Upload_security إغلاق هذه الثغرة الأمنية] قبل تمكين المرفوعات.",
+       "config-no-cli-uploads-check": "<strong>تحذير:</strong> لم يتم تحديد الدليل الافتراضي للمرفوعات (<code>$1</code>) للقابلية للتأثر\nلتنفيذ برنامج تعسفي أثناء تثبيت CLI.",
+       "config-brokenlibxml": "يحتوي نظامك على مجموعة من إصدارات PHP وlibxml2 ويمكن أن تسبب فسادا للبيانات في ميدياويكي وتطبيقات الويب الأخرى;\nقم بالترقية إلى libxml2 2.7.3 أو أحدث ([https://bugs.php.net/bug.php؟id=45996 تم تدقيم العلة مع PHP]); \nتم إحباط التثبيت.",
+       "config-suhosin-max-value-length": "تم تثبيت Suhosin وتقييد وسيط GET <code>length</code> إلى $1 بايت،\nسيعمل مكون ResourceLoader في ميدياويكي حول هذا الحد، لكن ذلك سيؤدي إلى انخفاض مستوى الأداء، \nإذا كان ذلك ممكنا، فيجب تعيين <code>suhosin.get.max_value_length</code> على 1024 أو أعلى في <code>php.ini</code>، وتعيين <code>$wgResourceLoaderMaxQueryLength</code> لنفس القيمة في <code>LocalSettings.php</code>.",
        "config-using-32bit": "<strong>تحذير:</strong> يبدو أن نظامك يعمل مع الأعداد الصحيحة 32 بت، هذا [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:32-bit لا يُنصَح به].",
        "config-db-type": "نوع قاعدة البيانات:",
        "config-db-host": "مضيف قاعدة البيانات:",
+       "config-db-host-help": "إذا كان خادم قاعدة البيانات موجودا في خادم مختلف، فأدخل اسم المضيف أو عنوان الآيبي هنا. \n\nإذا كنت تستخدم استضافة ويب مشتركة، فيجب أن يمنحك موفر الاستضافة اسم المضيف الصحيح في وثائقه. \n\nإذا كنت تقوم بالتثبيت على خادم ويندوز واستخدام MySQL، فإن استخدام \"localhost\" قد لا يعمل لاسم الخادم، إذا لم يتم ذلك، فجرب \"127.0.0.1\" لعنوان الآيبي المحلي. \n\nإذا كنت تستخدم PostgreSQL، فاترك هذا الحقل فارغا للاتصال عبر مقبس Unix.",
        "config-db-host-oracle": "قاعدة بيانات TNS:",
+       "config-db-host-oracle-help": "أدخل [http://download.oracle.com/docs/cd/B28359_01/network.111/b28317/tnsnames.htm اسم اتصال محلي] صالحا، يجب أن يكون ملف tnsnames.ora مرئيا لهذا التثبيت.<br />إذا كنت تستخدم مكتبات العملاء 10g أو أحدث، فيمكنك أيضا استخدام طريقة التسمية [http://download.oracle.com/docs/cd/E11882_01/network.112/e10836/naming.اتصال htm السهل].",
        "config-db-wiki-settings": "حدِّد هذا الويكي",
        "config-db-name": "اسم قاعدة البيانات",
        "config-db-name-help": "اختر الاسم الذي يعرف الويكي الخاص بك. لا يجب أن يحتوي على مسافات. إذا كنت تستخدم استضافة المواقع المشتركة، مزود الاستضافة إما سيعطيك اسم قاعدة بيانات محددة لاستخدامها أو سيتيح لك إنشاء قواعد بيانات عن طريق لوحة التحكم.",
        "config-db-name-oracle": "سكيما قاعدة البيانات:",
+       "config-db-account-oracle-warn": "هناك ثلاثة سيناريوهات مدعومة لتثبيت Oracle كقاعدة بيانات خلفية: \n\nإذا كنت ترغب في إنشاء حساب قاعدة بيانات كجزء من عملية التثبيت، فيُرجَى تقديم حساب بدور SYSDBA كحساب قاعدة بيانات للتثبيت وتحديد بيانات الاعتماد المطلوبة لحساب الوصول إلى الإنترنت، وإلا يمكنك إما إنشاء حساب الوصول إلى الويب يدويا وتزويد الحساب فقط (إذا كان يتطلب صلاحيات لإنشاء كائنات المخطط) أو توفير حسابين مختلفين، أحدهما له امتيازات إنشاء وامتياز مقيد للدخول إلى الويب. \n\nيمكن العثور على البرنامج النصي لإنشاء حساب له امتيازات مطلوبة في دليل \"maintenance/oracle/\" لهذا التثبيت، ضع في اعتبارك أن استخدام حساب مقيد سيؤدي إلى تعطيل جميع إمكانات الصيانة باستخدام الحساب الافتراضي.",
        "config-db-install-account": "حساب المستخدم للتنصيب",
        "config-db-username": "اسم مستخدم قاعدة البيانات:",
        "config-db-password": "كلمة سر قاعدة البيانات:",
        "config-db-schema-help": "هذا المخطط عادة يكون على ما يرام. غيره إذا كنت تعرف أنك في حاجة إلى هذا فقط.",
        "config-pg-test-error": "لا يمكن الاتصال بقاعدة البيانات <strong>$1</strong>: $2",
        "config-sqlite-dir": "دليل بيانات SQLite:",
+       "config-sqlite-dir-help": "يخزن SQLite جميع البيانات في ملف واحد. \n\nيجب أن يكون الدليل الذي توفره قابلا للكتابة بواسطة خادم الويب أثناء التثبيت. \n\nيجب أن يكون <strong>غير</strong> متاحا عبر الويب؛ هذا هو سبب عدم وضعه في مكان ملفات PHP الخاصة بك. \n\nسيقوم المثبت بكتابة ملف <code>.htaccess</code> معه، ولكن إذا فشل ذلك، يمكن لشخص ما الوصول إلى قاعدة بياناتك الأولية، \nيتضمن ذلك بيانات المستخدم الأولية (عناوين البريد الإلكتروني وكلمات المرور المجزأة) بالإضافة إلى المراجعات المحذوفة والبيانات المحظورة الأخرى على الويكي. \n\nفكر في وضع قاعدة البيانات في مكان آخر تماما، على سبيل المثال في <code>/var/lib/mediawiki/yourwiki</code.",
        "config-oracle-def-ts": "جدولية افتراضية:",
        "config-oracle-temp-ts": "جدولية مؤقتة:",
-       "config-type-mysql": "MySQL (أو متوافق)",
+       "config-type-mysql": "MariaDB أو MySQL أو متوافق",
        "config-type-postgres": "بوستجر إس كيو إل",
        "config-type-sqlite": "إس كيو لايت",
        "config-type-oracle": "أوراكل",
        "config-type-mssql": "خادم SQL لميكروسوفت",
        "config-support-info": "ميدياويكي يدعم نظم قواعد البيانات التالية: $1 إذا كنت لا ترى نظام قاعدة البيانات الذي تحاول استخدامه مدرجًا أدناه، اتبع الإرشادات المرتبطة فوق لتمكين الدعم.",
-       "config-header-mysql": "إعدادات MySQL",
+       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] هو الهدف الأساسي لميدياويكي وأفضل دعم له، يعمل ميدياويكي أيضا مع [{{int:version-db-mariadb-url}} MariaDB] و[{{int:version-db-percona-url}} Percona Server]، وهما متوافقان مع MySQL، ([https://secure.php.net/manual/en/mysqli.installation.php كيفية تجميع PHP مع دعم MySQL])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] هو نظام قاعدة بيانات مفتوح المصدر مشهور كبديل لـMySQL ([https://secure.php.net/manual/en/pgsql.installation.php كيفية تجميع PHP مع دعم PostgreSQL])",
+       "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] هو نظام قاعدة بيانات خفيف مدعوم بشكل جيد. ([https://secure.php.net/manual/en/pdo.installation.php كيفية ترجمة PHP باستخدام دعم SQLite]، يستخدم PDO)",
+       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] هي قاعدة بيانات مؤسسة تجارية. ([https://secure.php.net/manual/en/oci8.installation.php كيفية تجميع PHP مع دعم OCI8])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] هي قاعدة بيانات مؤسسة تجارية لويندوز. ([https://secure.php.net/manual/en/sqlsrv.installation.php كيفية تجميع PHP مع دعم SQLSRV])",
+       "config-header-mysql": "إعدادات MariaDB/MySQL",
        "config-header-postgres": "إعدادات PostgreSQL",
        "config-header-sqlite": "إعدادات SQLite",
        "config-header-oracle": "إعدادات أوراكل",
        "config-missing-db-name": "يجب عليك إدخال قيمة ل\"{{int:config-db-name}}\".",
        "config-missing-db-host": "يجب إدخال قيمة لـ\"{{int:config-db-host}}\".",
        "config-missing-db-server-oracle": "يجب عليك إدخال قيمة ل\"{{int:config-db-host-oracle}}\".",
+       "config-invalid-db-server-oracle": "TNS قاعدة بيانات غير صالحة \"$1\";\nاستخدم إما \"اسم TNS\" أو سلسلة \"الاتصال السهل\" \"Easy Connect\" ([http://docs.oracle.com/cd/E11882_01/network.112/e10836/naming.htm طرقلتسمية في أوراكل]).",
+       "config-invalid-db-name": "اسم قاعدة بيانات غير صالح \"$1\". \nاستخدم فقط أحرف أسكي (az، AZ) وأرقاما (0-9) وشرطات سفلية (_).",
+       "config-invalid-db-prefix": "بادئة قاعدة بيانات غير صالحة \"$1\". \nاستخدم فقط أحرف أسكي (az، AZ) وأرقاما (0-9) وشرطات سفلية (_).",
        "config-connection-error": "$1.\nتحقق من المضيف، واسم المستخدم وكلمة المرور وحاول مرة أخرى.",
+       "config-invalid-schema": "مخطط غير صالح لميدياويكي \"$1\". \nاستخدم فقط أحرف أسكي (az، AZ) وأرقاما (0-9) وشرطات سفلية (_).",
        "config-db-sys-create-oracle": "المثبت يعتمد باستخدام حساب SYSDBA فقط لإنشاء حساب جديد.",
        "config-db-sys-user-exists-oracle": "حساب المستخدم \"$1\" موجود بالفعل; يمكن استخدام SYSDBA لإنشاء حساب جديد فقط!",
        "config-postgres-old": "PostgreSQL $1 أو لاحق مطلوب. لديك $2.",
        "config-mssql-old": "خادم Microsoft SQL $1 أو لاحق مطلوب. لديك $2.",
+       "config-sqlite-name-help": "اختر اسمًا يعرف الويكي الخاص بك، \nلا تستخدم مسافات أو شرطات، \nسيتم استخدام هذا لاسم ملف البيانات SQLite.",
+       "config-sqlite-parent-unwritable-group": "لا يمكن إنشاء دليل البيانات <code><nowiki>$1</nowiki></code>; لأن الدليل الأصلي <code><nowiki>$2</nowiki></code> غير قابل للكتابة بواسطة خادم الويب، \nحدد المثبت المستخدم الذي يعمل عليه خادم الويب الخاص بك،\nاجعل الدليل <code><nowiki>$3</nowiki></code> قابلا للكتابة بواسطته للمتابعة، \nفي نظام يونكس/لينوكس قم بـ: \n<pre>cd $2\nmkdir $3\nchgrp $4 $3\nchmod g+w $3</pre>",
+       "config-sqlite-parent-unwritable-nogroup": "لا يمكن إنشاء دليل البيانات <code><nowiki>$1</nowiki></code>; لأن الدليل الأصلي <code><nowiki>$2</nowiki></code> غير قابل للكتابة بواسطة خادم الويب، \nتعذر على المثبت تحديد المستخدم الذي يعمل عليه خادم الويب الخاص بك،\nاجعل الدليل <code><nowiki>$3</nowiki></code> قابلا للكتابة بواسطته للمتابعة، \nفي نظام يونكس/لينوكس قم بـ: \n\n<pre>cd $2\nmkdir $3\nchmod a+w $3</pre>",
        "config-sqlite-mkdir-error": "خطأ في إنشاء دليل البيانات \"$1\". تحقق من الموقع وحاول مرة أخرى.",
        "config-sqlite-dir-unwritable": "غير قادر على الكتابة إلى الدليل \"$1\";\nغيِّر أذوناته حتى يتمكن خادم الويب من الكتابة إليه، وحاول مرة أخرى.",
        "config-sqlite-connection-error": "$1.\nتحقق من اسم دليل البيانات وقواعد البيانات أدناه وحاول مرة أخرى.",
        "config-sqlite-cant-create-db": "لا يمكن إنشاء ملف قاعدة البيانات <code>$1</code>.",
        "config-sqlite-fts3-downgrade": "PHP يفتقد دعم FTS3، تخفيض الجداول.",
        "config-can-upgrade": "هناك جداول ميدياويكي في قاعدة البيانات هذه. للارتقاء بها إلى ميدياويكي $1; انقر على <strong>متابعة</strong>.",
+       "config-upgrade-done": "اكتملت الترقية; \n\nيمكنك الآن [$1 بدء استخدام الويكي الخاص بك]. \n\nإذا كنت ترغب في إعادة إنشاء ملف <code>LocalSettings.php</code>، فانقر فوق الزر أدناه،\n<strong>غير مستحسن</strong> في ما لم تكن تواجه مشاكل مع الويكي الخاص بك.",
        "config-upgrade-done-no-regenerate": "اكتملت الترقية;\n\nيمكنك الآن [$1 بدء استخدام الويكي الخاص بك].",
        "config-regenerate": "إعادة تكوين LocalSettings.php ←",
        "config-show-table-status": "<code> إظهار جدول الحالة </code> فشل الاستعلام!",
        "config-db-web-create": "إنشئ حساب إذا لم يكن موجودا بالفعل",
        "config-db-web-no-create-privs": "الحساب الذي حددته لتركيب ليس لديه امتيازات كافية لإنشاء حساب.\nالحساب الذي حددته هنا موجود بالفعل.",
        "config-mysql-engine": "محرك التخزين",
-       "config-mysql-innodb": "إنو دي بي",
+       "config-mysql-innodb": "InnoDB (مستحسن)",
        "config-mysql-myisam": "ماي إسام",
-       "config-mysql-charset": "مجموعة محارف قاعدة البيانات",
-       "config-mysql-binary": "ثنائي",
-       "config-mysql-utf8": "يو تي إف-8",
+       "config-mysql-myisam-dep": "<strong>تحذير:</strong> لقد اخترت MyISAM كمحرك تخزين لـMySQL، والذي لا يُنصَح باستخدامه مع ميدياويكي; لأنه:\n* بالكاد يدعم التزامن بسبب قفل الجدول \n* أكثر عرضة للفساد من المحركات الأخرى\n* لا يقوم الكود الأساسي لميدياويكي بمعالجة MyISAM دائما كما يجب\n\nإذا كان تثبيت MySQL يدعم InnoDB، فمن المستحسن جدا أن تختاره بدلا منه، \nإذا كان تثبيت MySQL لا يدعم InnoDB، فربما حان الوقت للترقية.",
+       "config-mysql-only-myisam-dep": "<strong>تحذير:</strong> MyISAMهو محرك التخزين الوحيد المتاح لـMySQL على هذا الجهاز، ولا يُنصَح باستخدامه مع ميدياويكي; لأنه:\n* بالكاد يدعم التزامن بسبب قفل الجدول \n* أكثر عرضة للفساد من المحركات الأخرى\n* لا يقوم الكود الأساسي لميدياويكي بمعالجة MyISAM دائما كما يجب\n\nتثبيت MySQL لا يدعم InnoDB; ربما حان الوقت للترقية.",
+       "config-mysql-engine-help": "<strong>InnoDB</strong> هو دائما الخيار الأفضل; لأنه يحتوي على دعم تزامن جيد.\n\nقد يكون <strong>MyISAM</strong> أسرع في تثبيت المستخدم الفردي أو للقراءة فقط،\nتميل قواعد بيانات MyISAM للتلف أكثر من قواعد بيانات InnoDB.",
        "config-mssql-auth": "نوع الاستيثاق:",
+       "config-mssql-install-auth": "حدد نوع المصادقة الذي سيتم استخدامه للاتصال بقاعدة البيانات أثناء عملية التثبيت. \nإذا حددت \"{{int:config-mssql-windowsauth}}\"، فسيتم استخدام بيانات اعتماد أي مستخدم يعمل عليه خادم الويب.",
+       "config-mssql-web-auth": "حدد نوع المصادقة الذي سيستخدمه خادم الويب للاتصال بخادم قاعدة البيانات، أثناء التشغيل العادي للويكي. \nإذا حددت \"{{int:config-mssql-windowsauth}}\"، فسيتم استخدام بيانات اعتماد أي مستخدم يعمل عليه خادم الويب.",
        "config-mssql-sqlauth": "مصادقة خادم SQL",
        "config-mssql-windowsauth": "مصادقة ويندوز",
        "config-site-name": "اسم الويكي:",
        "config-ns-site-name": "مثل اسم الويكي: $1",
        "config-ns-other": "أخرى (حدد)",
        "config-ns-other-default": "ماي ويكي",
+       "config-project-namespace-help": "مثال ويكيبيديا التالي، يبقي العديد من الويكيات صفحات سياساتها منفصلة عن صفحات محتواها، في '''نطاق المشروع'''، \nتبدأ جميع عناوين الصفحات في هذا النطاق ببادئة معينة، والتي يمكنك تحديدها هنا، \nعادة، يتم اشتقاق هذه البادئة من اسم الويكي، ولكنها لا يمكن أن تحتوي على أحرف ترقيم مثل \"#\" أو \":\".",
        "config-ns-invalid": "النطاق المحدد \"<nowiki>$1</nowiki>\" غير صالح.\nحدد نطاق مشروع مختلف.",
        "config-ns-conflict": "النطاق المحدد \"<nowiki>$1</ nowiki>\" يتعارض مع نطاق ميدياويكي الافتراضي. حدد نطاق مشروع مختلف.",
        "config-admin-box": "حساب إداري",
        "config-admin-error-password": "خطأ داخلي عند عند وضع كلمة مرور للإداري \"<nowiki>$1</nowiki>\": <pre>$2</pre>.",
        "config-admin-error-bademail": "لقد قمت بإدخال عنوان البريد الإلكتروني غير صالح.",
        "config-subscribe": "اشترك في [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce نشر إعلانات القائمة البريدية].",
+       "config-subscribe-help": "هذه قائمة بريدية ذات حجم منخفض تُستخدَم لإعلانات الإصدار، بما في ذلك إعلانات الأمان المهمة، \nيجب عليك الاشتراك فيها وتحديث تثبيت ميدياويكي الخاص بك عندما تظهر إصدارات جديدة.",
        "config-subscribe-noemail": "حاولت الاشتراك في القائمة البريدية الخاصة بإصدار إعلانات دون تقديم عنوان بريد إلكتروني. يُرجَى إدخال عنوان بريد إلكتروني إذا كنت ترغب في الاشتراك في القائمة البريدية.",
        "config-pingback": "تبادل البيانات حول هذا التثبيت مع مطوري ميدياويكي.",
+       "config-pingback-help": "إذا قمت بتحديد هذا الخيار، سيقوم ميدياويكي بشكل دوري باختبار https://www.mediawiki.org مع بيانات أساسية حول نسخة ميدياويكي، تتضمن هذه البيانات، على سبيل المثال، نوع النظام وإصدار PHP والواجهة الخلفية لقاعدة البيانات، تشارك مؤسسة ويكيميديا ​​هذه البيانات مع مطوري ميدياويكي للمساعدة في توجيه جهود التطوير المستقبلية، سيتم إرسال البيانات التالية لنظامك:\n<pre>$1</pre>",
        "config-almost-done": "لقد شارفت على الانتهاء! يمكنك الآن تخطي التكوين المتبقي وتثبيت الويكي الآن.",
        "config-optional-continue": "اسألني المزيد من الأسئلة",
        "config-optional-skip": "إنني أشعر بالملل بالفعل، فقط قم بتثبيت الويكي",
        "config-profile-no-anon": "إنشاء الحساب مطلوب",
        "config-profile-fishbowl": "المحررون المخولون فقط",
        "config-profile-private": "ويكي خاص",
+       "config-profile-help": "تعمل الويكيات بشكل أفضل عندما تسمح لأكبر عدد ممكن من الأشخاص بتحريرها قدر الإمكان، \nفي ميدياويكي، من السهل مراجعة التغييرات الأخيرة، وإعادة أي ضرر يحدث من قبل مستخدمين سذج أو ضارين، \n\nومع ذلك، وجد الكثيرون أن ميدياويكي مفيد في مجموعة متنوعة من الأدوار، وفي بعض الأحيان ليس من السهل إقناع الجميع بمزايا طريقة الويكي; \nلذلك لديك الخيار. \n\nيسمح النموذج <strong>{{int:config-profile-wiki}}</strong> لأي شخص بالتحرير، دون تسجيل الدخول. \nويكي بـ<strong>{{int:config-profile-no-anon}}</strong> يوفر مساءلة إضافية، ولكنه قد يمنع المساهمين العاديين. \n\nيسمح السيناريو <strong>{{int:config-profile-fishbowl}}</strong> للمستخدمين المعتمدين بالتحرير، ولكن يمكن للجمهور عرض الصفحات، بما في ذلك التاريخ.\nيتيح <strong>{{int:config-profile-private}}</strong> للمستخدمين المعتمدين فقط عرض الصفحات، مع السماح لنفس المجموعة بالتعديل. \n\nتتوفر تكوينات صلاحيات مستخدم أكثر تعقيدًا بعد التثبيت، راجع [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:User_rights إدخال الدليل ذي الصلة].",
        "config-license": "حقوق النسخ والترخيص:",
        "config-license-none": "لا تذييل ترخيص",
        "config-license-cc-by-sa": "المشاع الإبداعي النسبة للمؤلف المشاركة بالمثل",
        "config-license-gfdl": "رخصة جنو للوثائق الحرة 1.3 أو لاحقة",
        "config-license-pd": "ملكية عامة",
        "config-license-cc-choose": "اختر ترخيص مشاع إبداعي مخصص",
+       "config-license-help": "يضع العديد من الويكيات العامة جميع المساهمات تحت [https://freedomdefined.org/Definition خصة حرة]، \nوهذا يساعد على خلق شعور بالملكية المجتمعية ويشجع على المساهمة طويلة الأجل، \nليس من الضروري عموما استخدام ويكي خاص أو شركة. \n\nإذا كنت تريد أن تكون قادرا على استخدام النص من ويكيبيديا، وتريد أن تكون ويكيبيديا قادرة على قبول النص الذي تم نسخه من الويكي الخاص بك، فيجب عليك اختيار <strong>{{int:config-license-cc-by-sa}}</strong>. \n\nاستخدمت ويكيبيديا في السابق رخصة جنو للوثائق الحرة، \nGFDL هو ترخيص صالح، ولكن من الصعب فهمه، \nمن الصعب أيضا إعادة استخدام المحتوى المرخص بموجب GFDL.",
        "config-email-settings": "إعدادات البريد الإلكتروني",
        "config-enable-email": "تمكين البريد الإلكتروني الصادرة",
        "config-enable-email-help": "إذا كنت تريد إرسال بريد إلكتروني إلى العمل، [Config-dbsupport-oracle/manual/en/mail.configuration.php إعدات بريد PHP's] تحتاج لأن يتم تكوينها بشكل صحيح. إذا كنت لا تريد أيا من ميزات البريد الإلكتروني، يمكنك تعطيلها هنا.",
        "config-email-watchlist": "تمكين إشعارات قائمة المراقبة",
        "config-email-watchlist-help": "السماح للمستخدمين بالحصول على إشعارات حول صفحاتهم المراقبة إذا كانوا قد مكنوها في تفضيلاتهم.",
        "config-email-auth": "تمكين مصادقة البريد الإلكتروني",
+       "config-email-auth-help": "إذا تم تمكين هذا الخيار، يتعين على المستخدمين تأكيد عنوان بريدهم الإلكتروني باستخدام رابط يتم إرساله إليهم عند تعيينهم أو تغييره. \nيمكن لعناوين البريد الإلكتروني الموثوقة فقط تلقي رسائل البريد الإلكتروني من المستخدمين الآخرين أو تغيير رسائل الإشعارات الإلكترونية. \nيعد تعيين هذا الخيار <strong> موصى به</strong> لمواقع الويكي العامة بسبب احتمال إساءة استخدام ميزات البريد الإلكتروني.",
        "config-email-sender": "عنوان البريد الإلكتروني المُرسِل:",
+       "config-email-sender-help": "أدخل عنوان البريد الإلكتروني لاستخدامه كعنوان المرسل في البريد الإلكتروني الصادر، \nهذا هو المكان الذي سيتم إرساله إلى المستبعد،\nتتطلب العديد من خوادم البريد أن يكون جزء اسم النطاق صالحا على الأقل.",
        "config-upload-settings": "الصور وتحميل الملفات",
        "config-upload-enable": "تمكين تحميل الملفات",
+       "config-upload-help": "من المحتمل أن تؤدي عمليات رفع الملفات إلى تعريض الخادم لمخاطر أمنية. \nلمزيد من المعلومات; اقرأ [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Security قسم الأمن] في الدليل. \n\nلتمكين رفع الملفات; قم بتغيير الوضع في الدليل الفرعي <code>الصور</code> تحت الدليل الرئيسي لميدياويكي كي يتمكن خادم الويب من الكتابة إليه، \nثم قم بتمكين هذا الخيار.",
        "config-upload-deleted": "المجلد للملفات المحذوفة:",
        "config-upload-deleted-help": "اختر دليلا لأرشفة الملفات المحذوفة،\nمن الناحية المثالية، لا يمكن الوصول إلى هذا من الويب.",
        "config-logo": "مسار الشعار:",
+       "config-logo-help": "يحتوي المظهر الافتراضي لميدياويكي على مساحة لشعار 135x160 بكسل فوق قائمة الشريط الجانبي، \nارفع صورة بالحجم المناسب، وأدخل المسار هنا. \n\nيمكنك استخدام <code>$wgStylePath</code> أو <code>$wgScriptPath</code> إذا كان شعارك مرتبطا بتلك المسارات. \n\nإذا كنت لا تريد شعارا، فاترك هذا الصندوق فارغا.",
        "config-instantcommons": "تمكين الاستخدام الفوري لويكيميديا كومنز InstantCommons",
+       "config-instantcommons-help": "[https://www.mediawiki.org/wiki/InstantCommons كومنز الفوري] هي ميزة تسمح للويكي باستخدام الصور والأصوات والوسائط الأخرى الموجودة على موقع [https://commons.wikimedia.org/ ويكيميديا كومنز]،\nمن أجل القيام بذلك; يتطلب ميدياويكي الوصول إلى الإنترنت. \n\nلمزيد من المعلومات حول هذه الميزة، بما في ذلك تعليمات حول كيفية إعدادها لمواقع ويكي بخلاف ويكيميديا كومنز; يُرجَى الرجوع إلى [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgForeignFileRepos الدليل].",
        "config-cc-error": "لم يعطِ منتقي رخصة المشاع الإبداعي أية نتيجة; أدخل اسم الترخيص يدويا.",
        "config-cc-again": "اختر مجددًا",
        "config-cc-not-chosen": "اختر أي ترخيص تريده ثم اضغط على \"متابعة\".",
        "config-advanced-settings": "ضبط متقدم",
        "config-cache-options": "إعدادات التخزين المؤقت الكائن:",
+       "config-cache-help": "يُستخدَم التخزين المؤقت للأداة لتحسين سرعة ميدياويكي عن طريق تخزين البيانات المستخدمة بشكل متكرر، \nيتم تشجيع المواقع المتوسطة والكبيرة إلى حد كبير على تمكينه، وستشاهد المواقع الصغيرة الفوائد أيضا.",
        "config-cache-none": "لا يوجد تخزين مؤقت (هذا لا يزيل أية وظيفة، لكن قد تتأثر السرعة على مواقع الويكي الكبيرة)",
        "config-cache-accel": "كائن التخزين المؤقت PHP (APC أو APCu أو  XCache أو XCache أو WinCache)",
        "config-cache-memcached": "استخدم Memcached (يتطلب إعدادت إضافية)",
        "config-install-pg-plpgsql": "التحقق من لغة PL/pgSQL",
        "config-pg-no-plpgsql": "تحتاج إلى تثبيت لغة PL/pgSQL في قاعدة البيانات $1",
        "config-pg-no-create-privs": "الحساب الذي حددته للتنزيل ليست لديه امتيازات كافية لإنشاء حساب.",
+       "config-pg-not-in-role": "الحساب الذي حددته لمستخدم الويب موجود بالفعل، \nالحساب الذي حددته للتثبيت ليس مستخدما متميزا وليس عضوا في دور مستخدم الويب; لذلك لا يمكنه إنشاء كائنات يملكها مستخدم الويب. \n\nميدياويكي حاليا يتطلب أن تكون الجداول مملوكة من قبل مستخدم الويب; يُرجَى تحديد اسم حساب ويب آخر، أو النقر فوق \"رجوع\" وتحديد مستخدم تثبيت متميز مناسب.",
        "config-install-user": "إنشاء مستخدم قاعدة البيانات",
        "config-install-user-alreadyexists": "المستخدم \"$1\" موجود بالفعل",
        "config-install-user-create-failed": "إنشاء مستخدم \"$1\" فشل:$2",
        "config-install-interwiki-exists": "<strong>تحذير:</strong> يبدو أن جدول الإنترويكي به إدخالات بالفعل. تخطي القائمة الافتراضي.",
        "config-install-stats": "بدء الإحصاءات",
        "config-install-keys": "توليد المفاتيح السرية",
-       "config-insecure-keys": "<strong>تحذير:</strong> {{PLURAL:$2|مفتاح الأمان|مفاتيح الأمان}} ($1) التي تم إنشاؤها أثناء التثبيت ليست آمنة تماما; جرب تغيير{{PLURAL:$2|ه|هم}} يدويا.",
        "config-install-updates": "منع تشغيل التحديثات غير الضرورية",
        "config-install-updates-failed": "<strong>خطأ:</strong> إدخال مفاتيح التحديث إلى الجداول فشلت بسبب الخطأ التالي: $1",
        "config-install-sysop": "إنشاء حساب مستخدم إداري",
        "config-install-mainpage-failed": "لم يتمكن من إدراج الصفحة الرئيسية: $1",
        "config-install-done": "<strong>مبروك!</strong>\nلقد قمت بتثبيت ميدياوكي.\n\nقام المثبت بتوليد ملف <code>LocalSettings.php</code>.\nيحتوي هذا الملف على كل تضبيطاتك.\n\nسيتطلب تشغيل الويكي منك تنزيل هذا الملف ووضعه في مجلد التثبيت الخاص بالويكي (نفس المجلد المحتوي على <code>index.php</code>). سيبدأ التنزيل تلقائيا.\n\nلو لم يُعرض عليك التنزيل أو قمت أنت بالغائه، يمكنك تنزيله بالضغط على الوصلة أدناه:\n\n$3\n\n<strong>تنبيه:</strong> لو لم تقم بهذا الآن، لن يكن ملف الضبط متاحا لك لاحقا إذا غادرت التثبيت بدون تنزيله.\n\nعندما تنتهي من وضع الملف بمكانه، يمكنك <strong>[$2 دخول الويكي]</strong>.",
        "config-install-done-path": "<strong>مبروك!</strong>\nلقد قمت بتثبيت ميدياوكي.\n\nقام المثبت بتوليد ملف <code>LocalSettings.php</code>.\nيحتوي هذا الملف على كل تضبيطاتك.\n\nسيتطلب تشغيل الويكي منك تنزيل هذا الملف ووضعه في <code>$4</code> (نفس المجلد المحتوي على index.php). سيبدأ التنزيل تلقائيا.\n\nلو لم يُعرض عليك التنزيل أو قمت أنت بالغائه، يمكنك تنزيله بالضغط على الوصلة أدناه:\n\n$3\n\n<strong>تنبيه:</strong> لو لم تقم بهذا الآن، لن يكن ملف الضبط متاحا لك لاحقا إذا غادرت التثبيت بدون تنزيله.\n\nعندما تنتهي من وضع الملف بمكانه، يمكنك <code>[$2 دخول الويكي]</strong>.",
+       "config-install-success": "لقد تم تثبيت ميدياويكي بنجاح; يمكنك الآن \nزيارة <$1$2> لعرض الويكي الخاص بك. \nإذا كانت لديك أسئلة، فاطلع على قائمة الأسئلة الشائعة: \n<https://www.mediawiki.org/wiki/Manual:FAQ> أو استخدم أحد \nمنتديات الدعم المرتبطة بهذه الصفحة.",
        "config-download-localsettings": "تنزيل <code>LocalSettings.php</code>",
        "config-help": "مساعدة",
        "config-help-tooltip": "اضغط للتوسيع",
index 3e11263..e0afeff 100644 (file)
@@ -53,7 +53,7 @@
        "config-unicode-using-intl": "Usando la [https://pecl.php.net/intl estensión intl PECL] pa la normalización Unicode.",
        "config-unicode-pure-php-warning": "'''Avisu:''' La [https://pecl.php.net/intl estensión intl PECL] nun ta disponible pa xestionar la normalización Unicode; volviendo a la implementación lenta en PHP puru.\nSi xestiona un sitiu con un tráficu altu, tendría de lleer una migaya sobro la [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations normalización Unicode].",
        "config-unicode-update-warning": "'''Avisu:''' La versión instalada del envoltoriu de normalización Unicode usa una versión antigua de la biblioteca [http://site.icu-project.org/ de los proyeutos ICU].\nTendría [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations d'anovala] si ye importante pa vusté usar Unicode.",
-       "config-no-db": "¡Nun pudo alcontrase un controlador de base de datos afayadizu! Necesites instalar un controlador de base de datos pa PHP.\n{{PLURAL:$2|Tien sofitu el tipu de base de datos siguiente|Tienen sofitu los tipos de base de datos siguientes}}: $1.\n\nSi compilasti PHP tu mesmu, reconfigúralu con un cliente de base de datos activáu, por exemplu, usando <code>./configure --with-mysqli</code>.\nSi instalasti PHP dende un paquete de Debian o Ubuntu, necesites instalar tamién,por exemplu, el paquete <code>php5-mysql</code>.",
+       "config-no-db": "¡Nun pudo alcontrase un controlador de base de datos afayadizu! Necesites instalar un controlador de base de datos pa PHP.\n{{PLURAL:$2|Tien sofitu el tipu de base de datos siguiente|Tienen sofitu los tipos de base de datos siguientes}}: $1.\n\nSi compilasti PHP tu mesmu, reconfigúralu con un cliente de base de datos activáu, por exemplu, usando <code>./configure --with-mysqli</code>.\nSi instalasti PHP dende un paquete de Debian o Ubuntu, necesites instalar tamién,por exemplu, el paquete <code>php-mysql</code>.",
        "config-outdated-sqlite": "'''Avisu:''' tien SQLite $1, que ye inferior a la versión mínima necesaria $2. SQLite nun tará disponible.",
        "config-no-fts3": "'''Avisu:''' SQLite ta compiláu ensin el [//sqlite.org/fts3.html módulu FTS3]; les funciones de gueta nun tarán disponibles nesti sistema.",
        "config-pcre-old": "<strong>Fatal:</strong> Ríquese PCRE $1 o posterior.\nEl binariu de PHP ta enllazáu con PCRE $2.\n[https://www.mediawiki.org/wiki/Manual:Errors_and_symptoms/PCRE Más información].",
        "config-type-mysql": "MySQL (o compatible)",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki ye compatible colos siguientes sistemes de bases de datos:\n\n$1\n\nSi nun atopes na llista el sistema de base de datos que tas intentando utilizar, sigue les instrucciones enllazaes enriba p'activar la compatibilidá.",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] ye un sistema comercial de base de datos empresariales pa Windows. ([Config-dbsupport-oracle/manual/en/sqlsrv.installation.php Cómo compilar PHP con compatibilidá pa SQLSRV])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] ye un sistema comercial de base de datos empresariales pa Windows. ([https://secure.php.net/manual/en/sqlsrv.installation.php Cómo compilar PHP con compatibilidá pa SQLSRV])",
        "config-header-mysql": "Configuración de MySQL",
        "config-header-postgres": "Configuración de PostgreSQL",
        "config-header-sqlite": "Configuración de SQLite",
        "config-mysql-engine": "Motor d'almacenamientu:",
        "config-mysql-innodb": "InnoDB",
        "config-mysql-myisam": "MyISAM",
-       "config-mysql-binary": "Binariu",
-       "config-mysql-utf8": "UTF-8",
        "config-mssql-auth": "Triba d'autenticación:",
        "config-site-name": "Nome de la wiki:",
        "config-site-name-help": "Esto apaecerá na barra de títulos del navegador y en dellos sitios más.",
        "config-license-cc-choose": "Escoyer una llicencia Creative Commons  personalizada",
        "config-email-settings": "Configuración de corréu electrónicu",
        "config-enable-email": "Activar el corréu electrónicu de salida",
-       "config-enable-email-help": "Si quies que'l corréu electrónicu funcione, les [Config-dbsupport-oracle/manual/en/mail.configuration.php preferencies de corréu de PHP] tienen de tar configuraes correutamente.\nSi nun quies les funciones de corréu electrónicu, puedes desactivales equí.",
+       "config-enable-email-help": "Si quies que'l corréu electrónicu funcione, les [https://secure.php.net/manual/en/mail.configuration.php preferencies de corréu de PHP] tienen de tar configuraes correutamente.\nSi nun quies les funciones de corréu electrónicu, puedes desactivales equí.",
        "config-email-user": "Activar el corréu electrónicu ente usuarios",
        "config-logo": "URL del logo:",
        "config-instantcommons": "Activar Instant Commons",
index 79c40ab..bfe2ca4 100644 (file)
@@ -60,7 +60,7 @@
        "config-unicode-using-intl": " [https://pecl.php.net/intl ҡушылмаһы файҙаланасаҡ, «intl» для PECL]  Юникод нормаль эшләһен өсөн.",
        "config-unicode-pure-php-warning": "'''Иғтибар!''': [https://pecl.php.net/intl ҡушылмаһы intl из PECL] Юникод өсөн рөхсәт ителмәгән PHP менән бик әкрен эшләйәсәк.\nҺеҙҙең сайт бик көсөргәнешле эшләһә [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations нормализации Юникодты нормалләштереү] өсөн уҡығыҙ.",
        "config-unicode-update-warning": "\"Иҫкәртеү\". Ҡуйылған тышлыҡ Юникодты нормаға килтереүҙең иҫке китапхана версияһын ҡуллана[http://site.icu-project.org/ проекта ICU].Әгәр Юникодты тулы мәғәнәһендә ҡулланырға теләһәгеҙ, һеҙ [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations версияны яңыртырға] тейешһегеҙ.",
-       "config-no-db": "Мәғлүмәттәр базаһына тура килгән драйверҙарҙы табып булманы!Һеҙгә  PHP өсөн мәғлүмәттәр базаһының  драйверҙарын ҡуйырға кәрәк.{{PLURAL:$2|сираттағы төр ҡулланыла|сираттағы төрҙәр ҡулланыла}}мәғлүмәттәр базалары:$1.\nӘгәр һеҙ үҙегеҙ PHP -ға компиляция яһаған булһағыҙ,  мәғлүмәттәр базаһына клиентты индереп уны яңынан, мәҫәлән, <code>./configure --with-mysqli</code> ярҙамы менән көйләгеҙ. Әгәр ҙә һеҙ PHP -ны Debian йәки Ubuntu пакеттарынан ҡуйһағыҙ, һеҙгә, мәҫәлән,  <code>php5-mysql</code> пакетын да ҡуйырға кәрәк булыр.",
+       "config-no-db": "Мәғлүмәттәр базаһына тура килгән драйверҙарҙы табып булманы!Һеҙгә  PHP өсөн мәғлүмәттәр базаһының  драйверҙарын ҡуйырға кәрәк.{{PLURAL:$2|сираттағы төр ҡулланыла|сираттағы төрҙәр ҡулланыла}}мәғлүмәттәр базалары:$1.\nӘгәр һеҙ үҙегеҙ PHP -ға компиляция яһаған булһағыҙ,  мәғлүмәттәр базаһына клиентты индереп уны яңынан, мәҫәлән, <code>./configure --with-mysqli</code> ярҙамы менән көйләгеҙ. Әгәр ҙә һеҙ PHP -ны Debian йәки Ubuntu пакеттарынан ҡуйһағыҙ, һеҙгә, мәҫәлән,  <code>php-mysql</code> пакетын да ҡуйырға кәрәк булыр.",
        "config-outdated-sqlite": "'''Киҫәтеү''': Һеҙҙә SQLite  $1 ҡуйылған, $2 тейешле өлгөнән түбән . SQLite асылмаясаҡ.",
        "config-no-fts3": "'''Иғтибар''': SQLite модулһыҙ йыйлған [//sqlite.org/fts3.html FTS3] — был мәғлүмәт базаһы өсөн эҙләү мөмкин булмаясаҡ.",
        "config-pcre-old": "'''Фаталь хата:'''  PCRE версияһы йәки яңырағы талап ителә $1.\nБашҡарылыусы файл PHP менән бәйләнгән PCRE  $2версияһы.\n[https://www.mediawiki.org/wiki/Manual:Errors_and_symptoms/PCRE Ентекләберәк].",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki -ла түбәндәге СУБД бар:\n\n$1\n\nӘгәр мәғлүмәт һаҡлау системаһын исемлектә күрмәһәгеҙ, рөхсәт алыу өсөн өҫтәге һылтанмалағы инструкция буйынса эш итегеҙ.",
        "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] — MediaWiki-ҙың иҫ яҡшы эшләгән төп мәғлүмәттәр базаһы.  MediaWiki шулай уҡ MySQL-тап килгән [{{int:version-db-mariadb-url}} MariaDB] һәм [{{int:version-db-percona-url}} Percona Server] менән эшләй. ([https://secure.php.net/manual/ru/mysql.installation.php MySQL-ярҙамында PHP туплау инструкцияһы])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] —  СУБД-ның популяр открыткаһы, MySQL өсөн альтернатива.\nТөҙәтелмәгән хаталар булыуы мөмкин, эш схемаһында ҡулланыу тәҡдим ителмәй. ([Config-dbsupport-oracle/manual/ru/pgsql.installation.php  PostgreSQL рөхсәт ителгән РНР йыйыу инструкцияһы]).",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] —  СУБД-ның популяр открыткаһы, MySQL өсөн альтернатива.\nТөҙәтелмәгән хаталар булыуы мөмкин, эш схемаһында ҡулланыу тәҡдим ителмәй. ([https://secure.php.net/manual/en/pgsql.installation.php  PostgreSQL рөхсәт ителгән РНР йыйыу инструкцияһы]).",
        "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] — яҡшы һәм еңел мәғлүмәт базаһы системаһы. ([http://www.php.net/manual/ru/pdo.installation.php  собрать PHP  SQLite]  PDO менән эшләй торған инструкция)",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] — предприятие масштабындаға коммерция базыһы. ([http://www.php.net/manual/ru/oci8.installation.php OCI8 ярҙамындағы РНР нисек йыйырға])",
-       "config-dbsupport-mssql": "* [{{int:version-db-oracle-url}} Oracle] — предприятие масштабындаға Windows өсөн коммерция базыһы. ([Config-dbsupport-oracle/manual/ru/oci8.installation.php OCI8 ярҙамындағы РНР нисек йыйырға])",
+       "config-dbsupport-mssql": "* [{{int:version-db-oracle-url}} Oracle] — предприятие масштабындаға Windows өсөн коммерция базыһы. ([https://secure.php.net/manual/en/sqlsrv.installation.php OCI8 ярҙамындағы РНР нисек йыйырға])",
        "config-header-mysql": "MySQL көйләү",
        "config-header-postgres": "PostgreSQL көйләү",
        "config-header-sqlite": "SQLite көйләү",
        "config-mysql-myisam-dep": "\"Иғтибар\" Һеҙ MySQL мәғлүмәтен һаҡлау өсөн MyISAM механизмын һайланығыҙ. Түбәндәге сәбәптәр арҡаһында уны ҡулланыу тәҡдим ителмәй:\n* параллелизмда эшләп булмай;\n* башҡа механизмдар менән сағыштырғанда мәғлүмәттәр юғала;\n* MediaWiki коды  MyISAM үҙенсәләген иҫәпкә алмай.\n\nҺеҙҙең MySQL InnoDB менән яраҡлы эшләһә ошо механизмды һайларға тәҡдим итебеҙ.\n\nҺеҙҙең MySQL InnoDB менән яраҡһыҙ эшләһә  механизмды яңыртырға тәҡдим итебеҙ.",
        "config-mysql-only-myisam-dep": "<strong>Иҫкәртеү:</strong> MyISAM — был компьютерҙә MySQL өсөн берҙән-бер асыҡ мәғлүмәттәр һаҡлау системаһы, һәм  MediaWiki менән берлектә ҡулланырға рөхсәт ителмәй,сөнки:\n* таблицаларҙы блокировкалау һөҙөмтәһендә параллелизмды көсһөҙ тота;\n* башҡа системаларға ҡарағанда, ватылыуға күберәк дусар ителгән;\n* MediaWiki код базаһы MyISAM -ды ғәҙәттәгесә эшкәртеп бөтә алмай\nҺеҙҙең MySQL  InnoDB -ды тотмай, бәлки, яңыртыу ваҡыты еткәндер.",
        "config-mysql-engine-help": "Параллель рәүештә яҡшыраҡ эшләгәне өсөн '''InnoDB''' өҫтөнлөрәк.\n\nБер ҡулланыусы йәки төҙәтеүҙәр әҙ булғанда вики өсөн '''MyISAM'''тың тиҙлеге  шәберәк, әммә унда мәғлүмәт базаһы InnoDB-ҡа ҡарағанда йышыраҡ сафтан сыға.",
-       "config-mysql-charset": "Мәғлүмәт базаһын кодлау",
-       "config-mysql-binary": "Икеле",
-       "config-mysql-utf8": "UTF-8",
-       "config-mysql-charset-help": "'''Ике режим'''да MediaWiki  UTF-8 тексын мәғлүмәт базаһының бинарныхҡырында һаҡлай.\nБыл MySQL-дың''UTF-8 режим''ына ҡарағанда һөҙөмтәлерәк һәм Unicode символдарының тулы тупланмаһын ҡулланыу мөмкинлеген бирә. \n\n'''UTF-8 режимы'''нда MySQL мәғлүмәттәрегеҙҙең ниндәй кодировкала ятҡанын беләсәк һәм уларҙы тейешенсә сағылдырасаҡ, үҙгәртәсәк, әммә был символдарҙы юғарыраҡ [https://en.wikipedia.org/wiki/Mapping_of_Unicode_character_planes База күптеллелек киңлегендә] һаәлау мөмкинлеген бирәсәк.",
        "config-mssql-auth": "Аутентификация төрө :",
        "config-mssql-install-auth": "Ҡуйыу процесында мәғлүмәт базаһына инеү өсөн файҙаланылған төп нөсхәне тикшереү тибын һайлағыҙ. \n\nӘгәр «{{int:config-mssql-windowsauth}}» һайлаһығыҙ, ҡулланыусының веб-сервер эшләгән иҫәп яҙмаһы файҙаланыласаҡ.",
        "config-mssql-web-auth": "Викиҙың ғәҙәттәге эше ваҡытында мәғлүмәттәр базаһы серверына инеү өсөн веб-сервер файҙаланған  төп нөсхәне тикшереү тибын һайлағыҙ. \n\nӘгәр «{{int:config-mssql-windowsauth}}» һайлаһығыҙ, ҡулланыусының веб-сервер эшләгән иҫәп яҙмаһы файҙаланыласаҡ.",
        "config-install-interwiki-exists": "'''Киҫәтеү''': интервики-таблицала яҙма бар.\nСтандарт исемлек төҙөү төшөп ҡалды.",
        "config-install-stats": "Инициализация статистикаһы",
        "config-install-keys": "Серле асҡыстар төҙөү",
-       "config-insecure-keys": "'''Киҫәтеү''' {{PLURAL:$2|1=Ҡатнашыусы булдырған хәүефһеҙлек асҡысы  $1 ышаныслы түгел}}. Асҡысты үҙгәртеү мөмкинлеген {{PLURAL:$2|1=}} ҡарағыҙ.",
        "config-install-updates": "Кәрәкмәген яңыртыуҙар туҡтатылды",
        "config-install-updates-failed": "<strong>Хата:</strong> Яңыртыуға асҡыс ҡуйыу түбәндәге хата менән тамамланды: $1",
        "config-install-sysop": "Администратор иҫәп яҙмаһын булдырыу",
index 1f26359..46d0aed 100644 (file)
@@ -56,7 +56,7 @@
        "config-unicode-using-intl": "Выкарыстоўваецца [https://pecl.php.net/intl intl пашырэньне з PECL] для Unicode-нармалізацыі",
        "config-unicode-pure-php-warning": "'''Папярэджаньне''': [https://pecl.php.net/intl Пашырэньне intl з PECL] — ня слушнае для Unicode-нармалізацыі, цяпер выкарыстоўваецца марудная PHP-рэалізацыя.\nКалі ў Вас сайт з высокай наведвальнасьцю, раім пачытаць пра [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations Unicode-нармалізацыю].",
        "config-unicode-update-warning": "'''Папярэджаньне''': усталяваная вэрсія бібліятэкі для Unicode-нармалізацыі выкарыстоўвае састарэлую вэрсію бібліятэкі з [http://site.icu-project.org/ праекту ICU].\nРаім [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations абнавіць], калі ваш сайт будзе працаваць з Unicode.",
-       "config-no-db": "Немагчыма знайсьці адпаведны драйвэр базы зьвестак. Вам неабходна ўсталяваць драйвэр базы зьвестак для PHP.\n{{PLURAL:$2|Падтрымліваецца наступны тып базы|Падтрымліваюцца наступныя тыпы базаў}} зьвестак: $1.\n\nКалі вы скампілявалі PHP самастойна, зьмяніце канфігурацыю, каб уключыць кліента базы зьвестак, напрыклад, з дапамогай <code>./configure --with-mysqli</code>.\nКалі вы ўсталявалі PHP з пакунку Debian або Ubuntu, тады вам трэба дадаткова ўсталяваць, напрыклад, пакунак <code>php5-mysql</code>.",
+       "config-no-db": "Немагчыма знайсьці адпаведны драйвэр базы зьвестак. Вам неабходна ўсталяваць драйвэр базы зьвестак для PHP.\n{{PLURAL:$2|Падтрымліваецца наступны тып базы|Падтрымліваюцца наступныя тыпы базаў}} зьвестак: $1.\n\nКалі вы скампілявалі PHP самастойна, зьмяніце канфігурацыю, каб уключыць кліента базы зьвестак, напрыклад, з дапамогай <code>./configure --with-mysqli</code>.\nКалі вы ўсталявалі PHP з пакунку Debian або Ubuntu, тады вам трэба дадаткова ўсталяваць, напрыклад, пакунак <code>php-mysql</code>.",
        "config-outdated-sqlite": "'''Папярэджаньне''': усталяваны SQLite $1, у той час, калі мінімальная сумяшчальная вэрсія — $2. SQLite ня будзе даступны.",
        "config-no-fts3": "'''Папярэджаньне''': SQLite створаны без модуля [//sqlite.org/fts3.html FTS3], для гэтага ўнутранага інтэрфэйсу ня будзе даступная магчымасьць пошуку.",
        "config-pcre-old": "<strong>Крытычная памылка:</strong> патрэбны PCRE вэрсіі $1 або пазьнейшай.\nPHP-файл, які выконваецца, зьвязаны з PCRE вэрсіі $2.\n[https://www.mediawiki.org/wiki/Manual:Errors_and_symptoms/PCRE Больш інфармацыі].",
        "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": "MySQL (або сумяшчальная)",
+       "config-type-mysql": "MariaDB, MySQL, або сумяшчальная",
        "config-type-postgres": "PostgreSQL",
        "config-type-sqlite": "SQLite",
        "config-type-oracle": "Oracle",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki падтрымлівае наступныя сыстэмы базаў зьвестак:\n\n$1\n\nКалі Вы ня бачыце сыстэму базаў зьвестак, якую Вы спрабуеце выкарыстоўваць ў сьпісе ніжэй, перайдзіце па спасылцы інструкцыі, якая знаходзіцца ніжэй, каб уключыць падтрымку.",
-       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] зьяўляецца галоўнай мэтай MediaWiki і падтрымліваецца лепей за ўсё. MediaWiki таксама працуе з [{{int:version-db-mariadb-url}} MariaDB] і [{{int:version-db-percona-url}} Percona Server], якія сумяшчальныя з MySQL. ([https://secure.php.net/manual/en/mysqli.installation.php Як скампіляваць PHP з падтрымкай MySQL])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] — папулярная сыстэма базы зьвестак з адкрытым кодам, якая зьяўляецца альтэрнатывай MySQL. ([Config-dbsupport-oracle/manual/en/pgsql.installation.php Як кампіляваць PHP з падтрымкай PostgreSQL])",
-       "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] — невялікая сыстэма базы зьвестак, якая мае вельмі добрую падтрымку. ([http://www.php.net/manual/en/pdo.installation.php Як кампіляваць PHP з падтрымкай SQLite], выкарыстоўвае PDO)",
-       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] зьяўляецца камэрцыйнай прафэсійнай базай зьвестак. ([http://www.php.net/manual/en/oci8.installation.php Як скампіляваць PHP з падтрымкай OCI8])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] — камэрцыйная база зьвестак для Windows. ([Config-dbsupport-oracle/manual/en/sqlsrv.installation.php Як скампіляваць PHP з падтрымкай SQLSRV])",
-       "config-header-mysql": "Налады MySQL",
+       "config-dbsupport-mysql": "* [{{int:version-db-mariadb-url}} MariaDB] зьяўляецца галоўнай мэтай MediaWiki і падтрымліваецца найлепш. MediaWiki таксама працуе з [{{int:version-db-mysql-url}} MySQL] і [{{int:version-db-percona-url}} Percona Server], якія сумяшчальныя з MariaDB. ([https://secure.php.net/manual/en/mysqli.installation.php Як скампіляваць PHP з падтрымкай MySQL])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] — папулярная сыстэма базы зьвестак з адкрытым кодам, якая зьяўляецца альтэрнатывай MySQL. ([https://secure.php.net/manual/en/pgsql.installation.php Як кампіляваць PHP з падтрымкай PostgreSQL])",
+       "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] — невялікая сыстэма базы зьвестак, якая мае вельмі добрую падтрымку. ([https://secure.php.net/manual/en/pdo.installation.php Як кампіляваць PHP з падтрымкай SQLite], выкарыстоўвае PDO)",
+       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] зьяўляецца камэрцыйнай прафэсійнай базай зьвестак. ([https://secure.php.net/manual/en/oci8.installation.php Як скампіляваць PHP з падтрымкай OCI8])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] — камэрцыйная база зьвестак для Windows. ([https://secure.php.net/manual/en/sqlsrv.installation.php Як скампіляваць PHP з падтрымкай SQLSRV])",
+       "config-header-mysql": "Налады MariaDB/MySQL",
        "config-header-postgres": "Налады PostgreSQL",
        "config-header-sqlite": "Налады SQLite",
        "config-header-oracle": "Налады Oracle",
        "config-db-web-create": "Стварыць рахунак, калі ён яшчэ не існуе",
        "config-db-web-no-create-privs": "Рахунак, які Вы пазначылі для ўсталяваньня ня мае правоў для стварэньня рахунку.\nРахунак, які Вы пазначылі тут, мусіць ужо існаваць.",
        "config-mysql-engine": "Рухавік сховішча:",
-       "config-mysql-innodb": "InnoDB",
+       "config-mysql-innodb": "InnoDB (рэкамэндавана)",
        "config-mysql-myisam": "MyISAM",
        "config-mysql-myisam-dep": "'''Папярэджаньне''': Вы выбралі MyISAM у якасьці рухавіка для захоўваньня зьвестак у MySQL, які не рэкамэндуецца да выкарыстаньня з MediaWiki па прычынах:\n* кепская падтрымка паралельнай апрацоўкі з-за таблічных блякаваньняў;\n* большая імавернасьць пашкоджаньня зьвестак у параўнаньні зь іншымі рухавікамі;\n* код MediaWiki не ва ўсіх выпадках улічвае асаблівасьці MyISAM.\n\nКалі Ваш MySQL-сэрвэр падтрымлівае InnoDB, вельмі рэкамэндуецца выкарыстаньне менавіта гэтага рухавіка.\nКалі MySQL-сэрвэр не падтрымлівае InnoDB, пэўна, настаў час абнавіць яго.",
        "config-mysql-only-myisam-dep": "<strong>Папярэджаньне:</strong> MyISAM — адзіная даступная сыстэма захоўваньня зьвестак для MySQL на гэтым кампутары, яна не рэкамэндуецца для ўжываньня з MediaWiki, таму што:\n* слаба падтрымлівае паралельнасьць праз блякаваньне табліцаў\n* больш за іншыя сыстэмы схільная да пашкоджаньняў\n* кодавая база MediaWiki не заўсёды належна апрацоўвае MyISAM\n\nВашае ўсталяваньне MySQL не падтрымлівае InnoDB, магчыма, час для абнаўленьня.",
        "config-mysql-engine-help": "'''InnoDB''' — звычайна найбольш слушны варыянт, таму што добра падтрымлівае паралелізм.\n\n'''MyISAM''' можа быць хутчэйшай у вікі з адным удзельнікам, ці толькі для чытаньня.\nБазы зьвестак на MyISAM вядомыя тым, што ў іх зьвесткі шкодзяцца нашмат часьцей за InnoDB.",
-       "config-mysql-charset": "Кадаваньне базы зьвестак:",
-       "config-mysql-binary": "Двайковае",
-       "config-mysql-utf8": "UTF-8",
-       "config-mysql-charset-help": "У '''двайковым рэжыме''', MediaWiki захоўвае тэкст у кадаваньні UTF-8 у базе зьвестак у двайковых палях.\nГэта болей эфэктыўна за рэжым MySQL UTF-8, і дазваляе Вам выкарыстоўваць увесь дыяпазон сымбаляў Unicode.\n\nУ '''рэжыме UTF-8''', MySQL ведае, якая табліцы сымбаляў выкарыстоўваецца ў Вашых зьвестках, і можа адпаведна прадстаўляць і канвэртаваць іх, але гэта не дазволіць Вам захоўваць сымбалі па-за межамі [https://en.wikipedia.org/wiki/Mapping_of_Unicode_character_planes Базавага шматмоўнага дыяпазону].",
        "config-mssql-auth": "Тып аўтэнтыфікацыі:",
        "config-mssql-install-auth": "Абярыце тып аўтэнтыфікацыі, які будзе выкарыстаны для злучэньня з базай зьвестак падчас працэсу ўсталяваньня.\nКалі вы абярэце «{{int:config-mssql-windowsauth}}», будуць выкарыстаныя ўліковыя зьвесткі карыстальніка, пад якім працуе вэб-сэрвэр.",
        "config-mssql-web-auth": "Абярыце тып аўтэнтыфікацыі, які вэб-сэрвэр будзе выкарыстоўваць для злучэньня з базай зьвестак падчас звычайнага функцыянаваньня вікі.\nКалі вы абярэце «{{int:config-mssql-windowsauth}}», будуць выкарыстаныя ўліковыя зьвесткі карыстальніка, пад якім працуе вэб-сэрвэр.",
        "config-license-help": "Шматлікія адкрытыя вікі публікуюць увесь унёсак у праект на ўмовах [https://freedomdefined.org/Definition вольнай ліцэнзіі].\nГэта дазваляе ствараць эфэкт супольнай уласнасьці і садзейнічае доўгатэрміноваму ўнёску.\nДля прыватных і карпаратыўных вікі гэта не зьяўляецца неабходнасьцю.\n\nКалі Вы жадаеце выкарыстоўваць тэкст зь Вікіпэдыі, і жадаеце, каб Вікіпэдыя магла прымаць тэксты, скапіяваныя з Вашай вікі, Вам неабходна выбраць ліцэнзію <strong>{{int:config-license-cc-by-sa}}</strong>.\n\nРаней Вікіпэдыя выкарыстоўвала ліцэнзію GNU Free Documentation.\nЯна ўсё яшчэ дзейнічае, але яна ўтрымлівае некаторыя моманты, якія ўскладняюць паўторнае выкарыстаньне і інтэрпрэтацыю матэрыялаў.",
        "config-email-settings": "Налады электроннай пошты",
        "config-enable-email": "Дазволіць выходзячыя электронныя лісты",
-       "config-enable-email-help": "Ð\9aалÑ\96 Ð\92Ñ\8b Ð¶Ð°Ð´Ð°ÐµÑ\86е, ÐºÐ°Ð± Ð¿Ñ\80аÑ\86авала Ñ\8dлекÑ\82Ñ\80оннаÑ\8f Ð¿Ð¾Ñ\88Ñ\82а, Ð½ÐµÐ°Ð±Ñ\85одна Ñ\81канÑ\84Ñ\96гÑ\83Ñ\80аваÑ\86Ñ\8c PHP [Config-dbsupport-oracle/manual/en/mail.configuration.php Ð°Ð´Ð¿Ð°Ð²ÐµÐ´Ð½Ñ\8bм Ñ\87Ñ\8bнам].\nÐ\9aалÑ\96 Ð\92Ñ\8b Ð½Ðµ Ð¶Ð°Ð´Ð°ÐµÑ\86е Ð²Ñ\8bкаÑ\80Ñ\8bÑ\81Ñ\82оÑ\9eваÑ\86Ñ\8c Ð¼Ð°Ð³Ñ\87Ñ\8bмаÑ\81Ñ\8cÑ\86Ñ\96 Ñ\8dлекÑ\82Ñ\80оннай Ð¿Ð¾Ñ\88Ñ\82Ñ\8b, Ð\92Ñ\8b Ð¼Ð¾Ð¶Ð°Ñ\86е Ñ\8fе Ð°Ð´ÐºÐ»Ñ\8eÑ\87Ñ\8bÑ\86Ñ\8c.",
+       "config-enable-email-help": "Ð\9aалÑ\96 Ð²Ñ\8b Ð¶Ð°Ð´Ð°ÐµÑ\86е, ÐºÐ°Ð± Ð¿Ñ\80аÑ\86авала Ñ\8dлекÑ\82Ñ\80оннаÑ\8f Ð¿Ð¾Ñ\88Ñ\82а, Ð½ÐµÐ°Ð±Ñ\85одна Ñ\81канÑ\84Ñ\96гÑ\83Ñ\80аваÑ\86Ñ\8c PHP [https://secure.php.net/manual/en/mail.configuration.php Ð°Ð´Ð¿Ð°Ð²ÐµÐ´Ð½Ñ\8bм Ñ\87Ñ\8bнам].\nÐ\9aалÑ\96 Ð²Ñ\8b Ð½Ðµ Ð¶Ð°Ð´Ð°ÐµÑ\86е Ð²Ñ\8bкаÑ\80Ñ\8bÑ\81Ñ\82оÑ\9eваÑ\86Ñ\8c Ð¼Ð°Ð³Ñ\87Ñ\8bмаÑ\81Ñ\8cÑ\86Ñ\96 Ñ\8dлекÑ\82Ñ\80оннай Ð¿Ð¾Ñ\88Ñ\82Ñ\8b, Ð²Ñ\8b Ð¼Ð¾Ð¶Ð°Ñ\86е Ñ\96Ñ\85 Ð°Ð´ÐºÐ»Ñ\8eÑ\87Ñ\8bÑ\86Ñ\8c Ñ\82Ñ\83Ñ\82.",
        "config-email-user": "Дазволіць электронную пошту для сувязі паміж удзельнікамі",
        "config-email-user-help": "Дазволіць усім удзельнікам дасылаць адзін аднаму электронныя лісты, калі ўключаная адпаведная магчымасьць ў іх наладах.",
        "config-email-usertalk": "Уключыць абвяшчэньні пра паведамленьні на старонцы абмеркаваньня",
        "config-install-interwiki-exists": "'''Папярэджаньне''': выглядае, што табліца інтэрвікі ўжо запоўненая.\nСьпіс па змоўчваньні прапушчаны.",
        "config-install-stats": "Ініцыялізацыі статыстыкі",
        "config-install-keys": "Стварэньне сакрэтных ключоў",
-       "config-insecure-keys": "<strong>Папярэджаньне:</strong> {{PLURAL:$2|1=Ключ бясьпекі $1 створаны|Ключы бясьпекі $1 створаныя}} падчас усталяваньня, {{PLURAL:$2|1=не зьяўляецца паўнасьцю бясьпечным|не зьяўляюцца поўнасьцю бясьпечнымі}}. Рэкамэндуецца зьмяніць {{PLURAL:$2|1=яго ўручную|іх уручную}}.",
        "config-install-updates": "Прадухіленьне запуску непатрэбных абнаўленьняў",
        "config-install-updates-failed": "<strong>Памылка</strong>: устаўка ключоў абнаўленьня ў табліцы завершылася наступнай памылкай: $1",
        "config-install-sysop": "Стварэньне рахунку адміністратара",
index 5c9bfd7..6b2f33f 100644 (file)
@@ -55,7 +55,7 @@
        "config-unicode-using-intl": "Използване на разширението [https://pecl.php.net/intl intl PECL] за нормализация на Уникод.",
        "config-unicode-pure-php-warning": "<strong>Внимание:</strong> [https://pecl.php.net/intl Разширението intl PECL] не е налично за справяне с нормализацията на Уникод, превключване към по-бавното изпълнение на чист PHP.\nАко сайтът е с голям трафик, препоръчително е да се запознаете с [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations нормализацията на Уникод].",
        "config-unicode-update-warning": "<strong>Предупреждение</strong>: Инсталираната версия на Обвивката за нормализация на Unicode използва по-старата версия на библиотеката на [http://site.icu-project.org/ проекта ICU].\nНеобходимо е да [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations инсталирате по-нова версия], в случай че сте загрижени за използването на Unicode.",
-       "config-no-db": "Не може да бъде открит подходящ драйвер за база данни! Необходимо е да инсталирате драйвер за база данни за PHP.\n{{PLURAL:$2|Поддържа се следния тип|Поддържат се следните типове}} бази от данни: $1.\n\nАко сами сте компилирали PHP, преконфигурирайте го с включен клиент за база данни, например чрез използване на <code>./configure --with-mysqli</code>.\nАко сте инсталирали PHP от пакет за Debian или Ubuntu, необходимо е също така да инсталирате и модула <code>php5-mysql</code>.",
+       "config-no-db": "Не може да бъде открит подходящ драйвер за база данни! Необходимо е да инсталирате драйвер за база данни за PHP.\n{{PLURAL:$2|Поддържа се следния тип|Поддържат се следните типове}} бази от данни: $1.\n\nАко сами сте компилирали PHP, преконфигурирайте го с включен клиент за база данни, например чрез използване на <code>./configure --with-mysqli</code>.\nАко сте инсталирали PHP от пакет за Debian или Ubuntu, необходимо е също така да инсталирате и модула <code>php-mysql</code>.",
        "config-outdated-sqlite": "<strong>Внимание:</strong> имате инсталиран SQLite  $1, а минималната допустима версия е $2. SQLite ще бъде недостъпна за ползване.",
        "config-no-fts3": "'''Предупреждение''': SQLite е компилирана без [//sqlite.org/fts3.html модула FTS3], затова възможностите за търсене няма да са достъпни.",
        "config-pcre-old": "<strong>Фатална грешка:</strong> Изисква се PCRE версия $1 или по-нова.\nИзпълнимият файл на PHP е свързан с PCRE версия $2.\n[https://www.mediawiki.org/wiki/Manual:Errors_and_symptoms/Повече информация за PCRE].",
        "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] е популярна система за управление на бази от данни, алтернатива на MySQL. ([https://secure.php.net/manual/bg/pgsql.installation.php Как се компилира PHP с поддръжка на PostgreSQL])",
        "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] е олекотена система за бази от данни, която е много добре поддържана. ([http://www.php.net/manual/bg/pdo.installation.php Как се компилира PHP с поддръжка на SQLite], използва PDO)",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] е комерсиална корпоративна база от данни. ([http://www.php.net/manual/en/oci8.installation.php Как се компилира PHP с поддръжка на OCI8])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] е комерсиална корпоративна база от данни за Windows. ([Config-dbsupport-oracle/manual/bg/sqlsrv.installation.php Как да се компилира PHP с поддръжка на SQLSRV])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] е комерсиална корпоративна база от данни за Windows. ([https://secure.php.net/manual/en/sqlsrv.installation.php Как да се компилира PHP с поддръжка на SQLSRV])",
        "config-header-mysql": "Настройки за MySQL",
        "config-header-postgres": "Настройки за PostgreSQL",
        "config-header-sqlite": "Настройки за SQLite",
        "config-mysql-myisam-dep": "<strong>Внимание:</strong> Избрана е MyISAM като система за складиране в MySQL, която не се препоръчва за използване с МедияУики, защото:\n* почти не поддържа паралелност заради заключване на таблиците\n* е по-податлива на повреди в сравнение с други системи\n* кодът на МедияУики не винаги поддържа MyISAM коректно\n\nАко инсталацията на MySQL поддържа InnoDB, силно е препоръчително да се използва тя.\nАко инсталацията на MySQL не поддържа InnoDB, вероятно е време за обновяване.",
        "config-mysql-only-myisam-dep": "<strong>Внимание:</strong> MyISAM e единственият наличен на тази машина тип на таблиците за MySQL и не е препоръчителен за употреба при МедияУики защото:\n* има слаба поддръжка на конкурентност на заявките, поради закючването на таблиците\n* е много по-податлив на грешки в базите от данни от другите типове таблици\n* кодът на МедияУики не винаги работи с MyISAM както трябва\n\nВашият MySQL не поддържа InnoDB, така че може би е дошло време за актуализиране.",
        "config-mysql-engine-help": "<strong>InnoDB</strong> почти винаги е най-добрата възможност заради навременната си поддръжка.\n\n<strong>MyISAM</strong> може да е по-бърза при инсталации с един потребител или само за четене.\nБазите от данни MyISAM се повреждат по-често от InnoDB.",
-       "config-mysql-charset": "Набор от знаци на базата от данни:",
-       "config-mysql-binary": "Двоичен",
-       "config-mysql-utf8": "UTF-8",
-       "config-mysql-charset-help": "В <strong>двоичен режим</strong> МедияУики съхранява текстовете в UTF-8 в бинарни полета в базата от данни.\nТова е по-ефективно от UTF-8 режима на MySQL и позволява използването на пълния набор от знаци в Уникод.\n\nВ <strong>UTF-8 режим</strong> MySQL ще знае в кой набор от знаци са данните от уикито и ще може да ги показва и променя по подходящ начин, но няма да позволява складиране на знаци извън [https://en.wikipedia.org/wiki/Mapping_of_Unicode_character_planes Основния многоезичен набор].",
        "config-mssql-auth": "Тип на удостоверяването:",
        "config-mssql-install-auth": "Изберете начин за удостоверяване, който ще бъде използван за връзка с базата от данни по време на инсталацията.\nАко изберете \"{{int:config-mssql-windowsauth}}\", ще се използват идентификационните данни на потребителя под който работи уеб сървъра.",
        "config-mssql-web-auth": "Изберете начина за удостоверяване, който ще се използва от уеб сървъра за връзка със сървъра за бази от данни по време на нормалните операции на уикито.\nАко изберете \"{{int:config-mssql-windowsauth}}\", ще се използват идентификационните данни на потребителя под който работи уеб сървъра.",
        "config-install-interwiki-exists": "<strong>Внимание:</strong> Таблицата с междууикита изглежда вече съдържа данни.\nПропускане на списъка по подразбиране.",
        "config-install-stats": "Инициализиране на статистиките",
        "config-install-keys": "Генериране на тайни ключове",
-       "config-insecure-keys": "<strong>Внимание:</strong> {{PLURAL:$2|Сигурният ключ, създаден по време на инсталацията, не е напълно надежден|Сигурните ключове, създадени по време на инсталацията, не са напълно надеждни}} $1 . Обмислете да {{PLURAL:$2|го|ги}} смените ръчно.",
        "config-install-updates": "Предотвратяване стартирането на ненужни актуализации",
        "config-install-updates-failed": "<strong>Грешка:</strong> Вмъкването на обновяващи ключове в таблиците се провали по следната причина: $1",
        "config-install-sysop": "Създаване на администраторска сметка",
index b6bbebb..a98e013 100644 (file)
@@ -8,7 +8,8 @@
                        "Aftabuzzaman",
                        "Hasive",
                        "আজিজ",
-                       "Elias Ahmmad"
+                       "Elias Ahmmad",
+                       "আফতাবুজ্জামান"
                ]
        },
        "config-desc": "মিডিয়াউইকির জন্য ইন্সটলার",
        "config-sqlite-dir": "এসকিউলাইট ডেটা ডিরেক্টরি:",
        "config-oracle-def-ts": "পূর্বনির্ধারিত টেবিলস্পেস",
        "config-oracle-temp-ts": "সাময়কি টেবিলস্পেস:",
+       "config-type-mysql": "MariaDB, MySQL, বা উপযুক্তগুলি",
        "config-type-mssql": "মাইক্রোসফট এসকিউএল সার্ভার",
-       "config-dbsupport-postgres": "* MySQL-এর বিকল্প হিসেবে [{{int:version-db-postgres-url}} PostgreSQL] হচ্ছে একটি জনপ্রিয় ওপেন সোর্স ডাটাবেস ব্যবস্থা। ([Config-dbsupport-oracle/manual/en/pgsql.installation.php PostgreSQL সমর্থনসহ কিভাবে PHP সঙ্কলন করবেন])",
-       "config-header-mysql": "মাইএসকিউএল সেটিংস",
+       "config-dbsupport-postgres": "* MySQL-এর বিকল্প হিসেবে [{{int:version-db-postgres-url}} PostgreSQL] হচ্ছে একটি জনপ্রিয় ওপেন সোর্স ডাটাবেস ব্যবস্থা। ([https://secure.php.net/manual/en/pgsql.installation.php PostgreSQL সমর্থনসহ কিভাবে PHP সঙ্কলন করবেন])",
+       "config-header-mysql": "MariaDB/MySQL সেটিং",
        "config-header-postgres": "পোস্টগ্রেএসকিউএল সেটিংস",
        "config-header-sqlite": "এসকিউলাইট সেটিংস",
        "config-header-oracle": "ওরাকল সেটিংস",
        "config-sqlite-cant-create-db": "ডাটাবেজ ফাইল <code>$1</code> তৈরি করা যায়নি।",
        "config-regenerate": "LocalSettings.php পুনরূত্পাদিত করুন →",
        "config-mysql-engine": "সংরক্ষণ ইঞ্জিন:",
-       "config-mysql-innodb": "ইনোডিবি",
+       "config-mysql-innodb": "InnoDB (সুপারিশকৃত)",
        "config-mysql-myisam": "মাইআইএসএএম",
-       "config-mysql-charset": "ডেটাবেজের অক্ষর সেট",
-       "config-mysql-binary": "বাইনারি",
-       "config-mysql-utf8": "ইউটিএফ-৮",
        "config-mssql-windowsauth": "উইন্ডোজ প্রমাণীকরণ",
        "config-site-name": "উইকির নাম:",
        "config-site-name-blank": "একটি সাইটের নাম প্রবেশ করান।",
index 58c4e1c..6ee9263 100644 (file)
@@ -55,7 +55,7 @@
        "config-unicode-using-intl": "Oc'h implijout [https://pecl.php.net/intl an astenn PECL intl] evit ar reolata Unicode.",
        "config-unicode-pure-php-warning": "<strong>Diwallit</strong> : N'haller ket ober gant an [https://pecl.php.net/intl intl astenn PECL] evit merañ reoladur Unicode; distreiñ d'ar stumm gorrek emplementet e PHP-rik.\nMa rit war-dro ul lec'hienn darempredet-stank e vo mat deoc'h lenn un tammig bihan diwar-benn se war [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations reolennadur Unicode].",
        "config-unicode-update-warning": "'''Diwallit''': ober a ra stumm staliet endalc'her skoueriekaat Unicode gant ur stumm kozh eus [http://site.icu-project.org/ levraoueg meziantoù ar raktres ICU].\nDleout a rafec'h [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations hizivaat] ma seblant deoc'h bezañ pouezus ober gant Unicode.",
-       "config-no-db": "N'eus ket bet gallet kavout ur sturier diazoù roadennoù a zere ! Ret eo deoc'h staliañ ur sturier diazoù roadennoù evit PHP.\nSkoret eo {{PLURAL:$2|ar seurt|ar seurtoù}} diazoù roadennoù da-heul : $1.\n\nMard eo bet kempunet PHP ganeoc'h-c'hwi hoc'h-unan, adkeflugnit-eñ en ur weredekaat un arval diaz roadennoù, da skouer en ur ober gant <code>/configure --with-mysqli</code>.\nM'hoc'h eus staliet PHP adalek ur pakad Debian pe Ubuntu, eo ret deoc'h staliañ, da skouer, ar pakad <code>php5-mysql</code> ivez.",
+       "config-no-db": "N'eus ket bet gallet kavout ur sturier diazoù roadennoù a zere ! Ret eo deoc'h staliañ ur sturier diazoù roadennoù evit PHP.\nSkoret eo {{PLURAL:$2|ar seurt|ar seurtoù}} diazoù roadennoù da-heul : $1.\n\nMard eo bet kempunet PHP ganeoc'h-c'hwi hoc'h-unan, adkeflugnit-eñ en ur weredekaat un arval diaz roadennoù, da skouer en ur ober gant <code>/configure --with-mysqli</code>.\nM'hoc'h eus staliet PHP adalek ur pakad Debian pe Ubuntu, eo ret deoc'h staliañ, da skouer, ar pakad <code>php-mysql</code> ivez.",
        "config-outdated-sqlite": "<strong>Taolit pled :</strong> ober a rit gant SQLite $1, hag a zo izeloc'h eget ar stumm $2 ret bihanañ. Ne vo ket posupl ober gant SQLite.",
        "config-no-fts3": "'''Diwallit ''': Kempunet eo SQLite hep ar [//sqlite.org/fts3.html vodulenn FTS3]; ne vo ket posupl ober gant an arc'hwelioù klask er staliadur-mañ",
        "config-pcre-old": "<strong>Fazo groñs :</strong> rekis eo ober gant PCRE $1 pe nevesoc'h.\nLiammet eo ho PHP binarel gant PCRE $2.\n[https://www.mediawiki.org/wiki/Manual:Errors_and_symptoms/PCRE Gouzout hiroc'h].",
        "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] zo anezhi ur reizhiad diaz roadennoù frank a wirioù brudet-mat a c'haller ober gantañ e plas MySQL. ([https://secure.php.net/manual/en/pgsql.installation.php Penaos kempunañ PHP gant skor PostgreSQL])",
        "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] zo anezhi ur reizhiad diaz roadennoù skañv skoret eus ar c'hentañ. ([http://www.php.net/manual/en/pdo.installation.php Penaos kempunañ PHP gant skor SQLite], implijout a ra PDO)",
        "config-dbsupport-oracle": "* Un embregerezh kenwerzhel diaz roadennoù eo [{{int:version-db-oracle-url}} Oracle]. ([http://www.php.net/manual/en/oci8.installation.php Penaos kempunañ PHP gant skor OCI8])",
-       "config-dbsupport-mssql": "* Un embregerezh kenwerzhel diaz roadennoù evit Windows eo [{{int:version-db-mssql-url}} Microsoft SQL Server]. ([Config-dbsupport-oracle/manual/en/sqlsrv.installation.php Penaos kempunañ PHP gant skor SQLSRV])",
+       "config-dbsupport-mssql": "* Un embregerezh kenwerzhel diaz roadennoù evit Windows eo [{{int:version-db-mssql-url}} Microsoft SQL Server]. ([https://secure.php.net/manual/en/sqlsrv.installation.php Penaos kempunañ PHP gant skor SQLSRV])",
        "config-header-mysql": "Arventennoù MySQL",
        "config-header-postgres": "Arventennoù PostgreSQL",
        "config-header-sqlite": "Arventennoù SQLite",
        "config-mysql-myisam-dep": "<strong>Diwallit :</strong> Diuzet eo bet ganeoc'h MyISAM evel keflusker stokañ evit MySQL, ar pezh n'eo ket erbedet evit implijout gant MediaWiki, rak :\n* a-boan m'eo skoret gantañ ober meur a dra war un dro peogwir eo prennet an taolennoù\n* techetoc'h eo d'ar gwastoù eget kefluskerioù all\n* kod diazez MediaWiki n'eo ket atav embreget MyISAM gantañ evel m'eo dleet\n\nM'eo skoret InnoDB gant ho staliadur MySQL, ez eo kuzuliet c'hwek deoc'h dibab hennezh kentoc'h.\nMa n'eo ket skoret InnoDB gant ho staliadur MySQL, e c'hallfe bezañ poent deoc'h ober un hizivadenn.",
        "config-mysql-only-myisam-dep": "<strong>Taolit evezh :</strong> MyISAM eo ar c'heflusker stokañ nemetañ a c'haller ober gantañ war ar mekanik-mañ evit MySQL, padal n'eo ket erbedet e implij gant MediaWiki, rak :\n* a-boan ma skor ar c'hevezerezh abalamour m'eo prennet an taolennoù\n* aesoc'h eo e wastañ eget kefluskerioù all\n* n'eo ket atav embreget MyIsam evel ma tlefe bezañ gant kod diazez MediaWiki\n\nN'eo ket skoret InnoDB gant ho staliadur MySQL. Poent eo hizivaat anezhañ marteze.",
        "config-mysql-engine-help": "<strong>InnoDB</strong> eo an dibab gwellañ koulz lavaret atav, kemer a ra e kont ar monedoù kevezus.\n\n<strong>MyISAM</strong> a c'hall bezañ fonnusoc'h evit ar staliadurioù unpost pe ar re lenn hepken.\nDiazoù roadennoù MyISAM zo techet da vezañ gwastet aliesoc'h eget re InnoDB.",
-       "config-mysql-charset": "Strobad arouezennoù an diaz roadennoù :",
-       "config-mysql-binary": "Binarel",
-       "config-mysql-utf8": "UTF-8",
-       "config-mysql-charset-help": "Er <strong>mod binarel</strong> eo stoket an destenn UTF-8 gant MediaWiki en diaz roadennoù e maeziennoù binarel.\nEfedusoc'h eo an dra-se eget mod UTF-8 MySQL; leuskel a ra ac'hanoc'h da implijout skalfad klok arouezennoù Unicode.\n\nEr <strong>mod UTF-8</strong>, MySQL a ouio anavezout ar rikoù arouezennoù emañ ho roadennoù ennañ hag e c'hallo o c'hinnig hag o amdreiñ en doare a zere met ne aotreo ket ac'hanoc'h da stokañ arouezennoù a-us d'ar [https://en.wikipedia.org/wiki/Mapping_of_Unicode_character_planes Steuñv liesyezhek diazez] (e saozneg).",
        "config-mssql-auth": "Seut anaoudadur :",
        "config-mssql-install-auth": "Diuzañ ar seurt dilesa a vo implijet evit kevreañ ouzh an diaz roadennoù e-pad ar staliañ.\nMa tibabit \"{{int:config-mssql-windowsauth}}\", e vo implijet titouroù anaout an implijer a laka ar servijer da dreiñ.",
        "config-mssql-web-auth": "Diuzañ ar seurt dilesa a vo implijet gant ar servijer web evit kevreañ ouzh diaz roadennoù ar servijer e-pad oberiadennoù boas ar wiki.\nMa tibabit \"{{int:config-mssql-windowsauth}}\", e vo implijet titouroù anaout an implijer a laka ar servijer da dreiñ.",
index a70c981..58931b8 100644 (file)
@@ -47,7 +47,7 @@
        "config-env-bad": "Okruženje je provjereno.\nNe možete instalirati MediaWiki.",
        "config-env-php": "PHP $1 je instaliran.",
        "config-env-hhvm": "HHVM $1 je instaliran.",
-       "config-no-db": "Ne mogu pronaći pogodan upravljački program za bazu podataka! Morate ga instalirati za PHP-bazu.\n{{PLURAL:$2|Podržana je sljedeća vrsta|Podržane su sljedeće vrste}} baze podataka: $1.\n\nAko se sami kompajlirali PHP, omogućite klijent baze podataka u postavkama koristeći, naprimjer, <code>./configure --with-mysqli</code>.\nAko ste instalirali PHP iz paketa za Debian ili Ubuntu, onda također morate instalirati, naprimjer, paket <code>php5-mysql</code>.",
+       "config-no-db": "Ne mogu pronaći pogodan upravljački program za bazu podataka! Morate ga instalirati za PHP-bazu.\n{{PLURAL:$2|Podržana je sljedeća vrsta|Podržane su sljedeće vrste}} baze podataka: $1.\n\nAko se sami kompajlirali PHP, omogućite klijent baze podataka u postavkama koristeći, naprimjer, <code>./configure --with-mysqli</code>.\nAko ste instalirali PHP iz paketa za Debian ili Ubuntu, onda također morate instalirati, naprimjer, paket <code>php-mysql</code>.",
        "config-memory-raised": "<code>memory_limit</code> za PHP iznosi $1, povišen na $2.",
        "config-memory-bad": "<strong>Upozorenje:</strong> <code>memory_limit</code> za PHP iznosi $1.\nOvo je vjerovatno premalo.\nInstalacija možda neće uspjeti!",
        "config-apc": "[https://secure.php.net/apc APC] je instaliran",
        "config-mysql-engine": "Skladišni pogon:",
        "config-mysql-innodb": "InnoDB",
        "config-mysql-myisam": "MyISAM",
-       "config-mysql-binary": "Binarni",
-       "config-mysql-utf8": "UTF-8",
        "config-mssql-auth": "Vrsta autentifikacije:",
        "config-site-name": "Ime wikija:",
        "config-site-name-blank": "Upišite ime sajta.",
index 2252568..6fb1bbe 100644 (file)
@@ -39,8 +39,6 @@
        "config-header-mssql": "Microsoft SQL Server settings",
        "config-mysql-innodb": "InnoDB",
        "config-mysql-myisam": "MyISAM",
-       "config-mysql-binary": "Binary",
-       "config-mysql-utf8": "UTF-8",
        "config-site-name": "Ngaran ka wiki",
        "config-site-name-blank": "Ibutang a ngaran ka site.",
        "config-project-namespace": "Bibutangan ka proyekto:",
index e03a737..a1f7248 100644 (file)
        "config-mysql-engine": "Motor d'emmagatzemament:",
        "config-mysql-innodb": "InnoDB",
        "config-mysql-myisam": "MyISAM",
-       "config-mysql-charset": "Joc de caràcters de la base de dades:",
-       "config-mysql-binary": "Binari",
-       "config-mysql-utf8": "UTF-8",
        "config-mssql-auth": "Tipus d'autenticació:",
        "config-mssql-sqlauth": "Autenticació de l’SQL Server",
        "config-mssql-windowsauth": "Autenticació del Windows",
index b58ff41..be482e9 100644 (file)
@@ -39,7 +39,6 @@
        "config-missing-db-server-oracle": "Ахьа тӀеюза езаш ю «{{int:config-db-host-oracle}}»",
        "config-invalid-db-server-oracle": "Хаамийн базан «$1» нийса йоцу TNS.\nЛелае «TNS Name», я могӀа «Easy Connect» ([http://docs.oracle.com/cd/E11882_01/network.112/e10836/naming.htm ЦӀерш техкаран кеп Oracle])",
        "config-sqlite-fts3-downgrade": "PHPн  гӀо до FTS3 яц — кхуссу таблицаш",
-       "config-mysql-utf8": "UTF-8",
        "config-mssql-auth": "Аутентификацин тайп:",
        "config-site-name": "Викин цӀе:",
        "config-site-name-blank": "Язъе сайтан цӀе.",
index fc61940..8e3b89c 100644 (file)
@@ -10,7 +10,8 @@
                        "Matěj Suchánek",
                        "LordMsz",
                        "Seb35",
-                       "Ilimanaq29"
+                       "Ilimanaq29",
+                       "Dvorapa"
                ]
        },
        "config-desc": "Instalační program pro MediaWiki",
@@ -59,7 +60,7 @@
        "config-unicode-using-intl": "Pro normalizaci Unicode se používá [https://pecl.php.net/intl PECL rozšíření intl].",
        "config-unicode-pure-php-warning": "<strong>Upozornění:</strong> Není dostupné [https://pecl.php.net/intl PECL rozšíření intl] pro normalizaci Unicode, bude se využívat pomalá implementace v čistém PHP.\nPokud provozujete wiki s velkou návštěvností, měli byste si přečíst něco o [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations normalizaci Unicode].",
        "config-unicode-update-warning": "<strong>Upozornění:</strong> Nainstalovaná verze vrstvy pro normalizaci Unicode používá starší verzi knihovny [http://site.icu-project.org/ projektu ICU].\nPokud vám aspoň trochu záleží na používání Unicode, měli byste [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations ji aktualizovat].",
-       "config-no-db": "Nepodařilo se nalézt vhodný databázový ovladač! Musíte nainstalovat databázový ovladač pro PHP.\n{{PLURAL:$2|Je podporován následující typ databáze|Jsou podporovány následující typy databází}}: $1.\n\nPokud jste si PHP přeložili sami, překonfigurujte ho se zapnutým databázovým klientem, například pomocí <code>./configure --with-mysqli</code>.\nPokud jste PHP nainstalovali z balíčku Debian či Ubuntu, potřebujete nainstalovat také modul <code>php5-mysql</code>.",
+       "config-no-db": "Nepodařilo se nalézt vhodný databázový ovladač! Musíte nainstalovat databázový ovladač pro PHP.\n{{PLURAL:$2|Je podporován následující typ databáze|Jsou podporovány následující typy databází}}: $1.\n\nPokud jste si PHP přeložili sami, překonfigurujte ho se zapnutým databázovým klientem, například pomocí <code>./configure --with-mysqli</code>.\nPokud jste PHP nainstalovali z balíčku Debian či Ubuntu, potřebujete nainstalovat také modul <code>php-mysql</code>.",
        "config-outdated-sqlite": "<strong>Upozornění:</strong> Máte SQLite $1, které je starší než minimálně vyžadovaná verze $2. SQLite nebude dostupné.",
        "config-no-fts3": "<strong>Upozornění:</strong> SQLite bylo přeloženo bez [//sqlite.org/fts3.html modulu FTS3], funkce pro vyhledávání zde nebudou dostupné.",
        "config-pcre-old": "<strong>Kritická chyba:</strong> Je vyžadováno PCRE verze $1 nebo novější.\nVaše binárka PHP obsahuje PCRE $2.\n[https://www.mediawiki.org/wiki/Manual:Errors_and_symptoms/PCRE Více informací.]",
        "config-type-oracle": "Oracle",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki podporuje následující databázové systémy:\n\n$1\n\nPokud v nabídce níže nevidíte databázový systém, který chcete použít, musíte pro zapnutí podpory následovat instrukce odkázané výše.",
-       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] je pro MediaWiki hlavní platformou a je podporováno nejlépe. MediaWiki pracuje také s [{{int:version-db-mariadb-url}} MariaDB] a [{{int:version-db-percona-url}} Percona Server], které jsou s MySQL kompatibilní. ([https://secure.php.net/manual/en/mysql.installation.php Jak zkompilovat PHP s podporou MySQL])",
+       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] je pro MediaWiki hlavní platformou a je podporováno nejlépe. MediaWiki pracuje také s [{{int:version-db-mariadb-url}} MariaDB] a [{{int:version-db-percona-url}} Percona Server], které jsou s MySQL kompatibilní. ([https://secure.php.net/manual/en/mysqli.installation.php Jak zkompilovat PHP s podporou MySQL])",
        "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] je populární otevřený databázový systém používaný jako alternativa k MySQL. ([https://secure.php.net/manual/en/pgsql.installation.php Jak přeložit PHP s podporou PostgreSQL])",
-       "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] je velmi dobře podporovaný odlehčený databázový systém. ([http://www.php.net/manual/en/pdo.installation.php Jak přeložit PHP s podporou SQLite], používá PDO)",
-       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] je komerční podniková databáze. ([http://www.php.net/manual/en/oci8.installation.php Jak přeložit PHP s podporou OCI8])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] je komerční podniková databáze pro Windows. ([Config-dbsupport-oracle/manual/en/sqlsrv.installation.php Jak přeložit PHP s podporou SQLSRV])",
+       "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] je velmi dobře podporovaný odlehčený databázový systém. ([https://secure.php.net/manual/en/pdo.installation.php Jak přeložit PHP s podporou SQLite], používá PDO)",
+       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] je komerční podniková databáze. ([https://secure.php.net/manual/en/oci8.installation.php Jak přeložit PHP s podporou OCI8])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] je komerční podniková databáze pro Windows. ([https://secure.php.net/manual/en/sqlsrv.installation.php Jak přeložit PHP s podporou SQLSRV])",
        "config-header-mysql": "Nastavení MySQL",
        "config-header-postgres": "Nastavení PostgreSQL",
        "config-header-sqlite": "Nastavení SQLite",
        "config-db-web-create": "Založit účet, pokud zatím neexistuje",
        "config-db-web-no-create-privs": "Účet uvedený pro instalaci nemá oprávnění dostatečná pro založení nového účtu.\nÚčet, který zde uvedete, již musí existovat.",
        "config-mysql-engine": "Typ úložiště:",
-       "config-mysql-innodb": "InnoDB",
+       "config-mysql-innodb": "InnoDB (doporučeno)",
        "config-mysql-myisam": "MyISAM",
        "config-mysql-myisam-dep": "<strong>Upozornění:</strong> Jako typ úložiště pro MySQL jste zvolili MyISAM, které není pro použití v MediaWiki doporučeno, neboť:\n* stěží podporuje současný přístup kvůli zamykání tabulek,\n* je náchylnější na poškození dat než jiná úložiště,\n* kód MediaWiki nepodporuje MyISAM vždy tak dobře, jak by měl.\n\nPokud vaše instalace MySQL podporuje InnoDB, důrazně doporučujeme použít spíše to.\nPokud vaše instalace MySQL InnoDB nepodporuje, možná je čas na aktualizaci.",
        "config-mysql-only-myisam-dep": "<strong>Upozornění:</strong> Jediným dostupným úložištěm dat pro MySQL je MyISAM, který se k užití s MediaWiki nedoporučuje, neboť:\n* téměř nepodporuje paralelní přístup kvůli zamykání tabulek,\n* oproti jiným formátům je náchylnější k poškození,\n* MediaWiki nepodporuje MyISAM tak dobře, jak by bylo třeba.\n\nVaše instalace MySQL nepodporuje InnoDB, možná je na čase upgradovat.",
        "config-mysql-engine-help": "'''InnoDB''' je téměř vždy nejlepší volba, neboť má dobrou podporu současného přístupu.\n\n'''MyISAM''' může být rychlejší u instalací pro jednoho uživatele nebo jen pro čtení.\nDatabáze MyISAM bývají poškozeny častěji než databáze InnoDB.",
-       "config-mysql-charset": "Znaková sada databáze:",
-       "config-mysql-binary": "Binární",
-       "config-mysql-utf8": "UTF-8",
-       "config-mysql-charset-help": "V '''binárním režimu''' ukládá MediaWiki text v UTF-8 do databáze v binárních sloupcích.\nTo je výkonnější než UTF-8 režim MySQL a umožňuje využít plný rozsah znaků Unicode.\n\nV '''režimu UTF-8''' bude MySQL znát znakovou sadu vašich dat a může je příslušně zobrazovat a převádět, ale neumožní vám uložit znaky mimo [https://en.wikipedia.org/wiki/Mapping_of_Unicode_character_planes Basic Multilingual Plane].",
        "config-mssql-auth": "Typ autentizace:",
        "config-mssql-install-auth": "Zvolte si typ autentizace, který se bude používat pro připojení k databázi v průběhu instalace.\nPokud zvolíte možnost „{{int:config-mssql-windowsauth}}“, použijí se přihlašovací údaje uživatele, pod kterým běží webový server.",
        "config-mssql-web-auth": "Zvolte si typ autentizace, který se bude používat pro připojení k databázi za běžného provozu wiki.\nPokud zvolíte možnost „{{int:config-mssql-windowsauth}}“, použijí se přihlašovací údaje uživatele, pod kterým běží webový server.",
        "config-license-help": "Mnoho veřejných wiki všechny příspěvky zveřejňuje pod některou [https://freedomdefined.org/Definition/Cs svobodnou licencí].\nTo pomáhá vytvořit duch komunitního vlastnictví a povzbuzuje dlouhodobé přispívání.\nTo obecně není potřeba u soukromé nebo firemní wiki.\n\nPokud chcete být schopni používat text z Wikipedie a chcete, aby Wikipedie byla schopna přijímat text okopírovaný z vaší wiki, měli byste zvolit <strong>{{int:config-license-cc-by-sa}}</strong>.\n\nDříve Wikipedie používala GNU Free Documentation License.\nGFDL je platná licence, ale složité jí porozumět.\nTaké je komplikované používat obsah licencovaný pod GFDL.",
        "config-email-settings": "Nastavení e-mailu",
        "config-enable-email": "Zapnout odchozí e-mail",
-       "config-enable-email-help": "Pokud chcete, aby e-mail fungoval, je potřeba správně nakonfigurovat [Config-dbsupport-oracle/manual/en/mail.configuration.php e-mailová nastavení PHP].\nPokud nechcete žádné e-mailové funkce, můžete je zde vypnout.",
+       "config-enable-email-help": "Pokud chcete, aby e-mail fungoval, je potřeba správně nakonfigurovat [https://secure.php.net/manual/en/mail.configuration.php e-mailová nastavení PHP].\nPokud nechcete žádné e-mailové funkce, můžete je zde vypnout.",
        "config-email-user": "Umožnit vzájemné e-maily mezi uživateli",
        "config-email-user-help": "Umožní všem uživatelům posílat si navzájem e-maily, pokud si to zapnout v uživatelském nastavení.",
        "config-email-usertalk": "Umožnit notifikace k uživatelským diskusím",
        "config-install-interwiki-exists": "'''Upozornění''': Vypadá to, že tabulka interwiki již obsahuje nějaké záznamy.\nPřeskakuje se implicitní seznam.",
        "config-install-stats": "Inicializují se statistiky",
        "config-install-keys": "Vytvářejí se tajné klíče",
-       "config-insecure-keys": "'''Upozornění:''' {{PLURAL:$2|Tajný klíč|Tajné klíče}} ($1) vytvořené v průběhu instalace {{PLURAL:$2|není|nejsou}} zcela {{PLURAL:$2|bezpečný|bezpečné}}. Zvažte {{PLURAL:$2|jeho|jejich}} ruční změnu.",
        "config-install-updates": "Ruší se spuštění nepotřebných aktualizací",
        "config-install-updates-failed": "<strong>Chyba:</strong> Vložení aktualizačních klíčů do tabulek selhalo s následující chybou: $1",
        "config-install-sysop": "Zakládá se uživatelský účet správce",
index ff52ec6..6c8e9b8 100644 (file)
@@ -40,8 +40,6 @@
        "config-diff3-bad": "Felënk GNU diff3.",
        "config-mysql-innodb": "InnoDB",
        "config-mysql-myisam": "MyISAM",
-       "config-mysql-binary": "binarny",
-       "config-mysql-utf8": "UTF‐8",
        "config-site-name": "Miono wiki:",
        "config-site-name-blank": "Wpiszë miono starnów.",
        "config-ns-other-default": "MòjôWiki",
index 4c39ac0..8433b33 100644 (file)
@@ -65,7 +65,7 @@
        "config-unicode-using-intl": "Zur  Unicode-Normalisierung wird die [https://pecl.php.net/intl PECL-Erweiterung intl] eingesetzt.",
        "config-unicode-pure-php-warning": "'''Warnung:''' Die [https://pecl.php.net/intl PECL-Erweiterung intl] ist für die Unicode-Normalisierung nicht verfügbar, so dass stattdessen die langsame pure-PHP-Implementierung genutzt wird.\nSofern eine Website mit großer Benutzeranzahl betrieben wird, sollten weitere Informationen auf der Webseite [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations Unicode-Normalisierung (en)] gelesen werden.",
        "config-unicode-update-warning": "'''Warnung:''' Die installierte Version des Unicode-Normalisierungswrappers nutzt einer ältere Version der Bibliothek des [http://site.icu-project.org/ ICU-Projekts].\nDiese sollte [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations aktualisiert] werden, sofern auf die Verwendung von Unicode Wert gelegt wird.",
-       "config-no-db": "Es konnte kein adäquater Datenbanktreiber gefunden werden. Es muss daher ein Datenbanktreiber für PHP installiert werden.\n{{PLURAL:$2|Das folgende Datenbanksystem wird|Die folgenden Datenbanksysteme werden}} unterstützt: $1\n\nWenn du PHP selbst kompiliert hast, konfiguriere es erneut mit einem aktivierten Datenbankclient, zum Beispiel durch Verwendung von <code>./configure --with-mysqli</code>.\nWenn du PHP von einem Debian- oder Ubuntu-Paket installiert hast, dann musst du auch beispielsweise das <code>php5-mysql</code>-Paket installieren.",
+       "config-no-db": "Es konnte kein adäquater Datenbanktreiber gefunden werden. Es muss daher ein Datenbanktreiber für PHP installiert werden.\n{{PLURAL:$2|Das folgende Datenbanksystem wird|Die folgenden Datenbanksysteme werden}} unterstützt: $1\n\nWenn du PHP selbst kompiliert hast, konfiguriere es erneut mit einem aktivierten Datenbankclient, zum Beispiel durch Verwendung von <code>./configure --with-mysqli</code>.\nWenn du PHP von einem Debian- oder Ubuntu-Paket installiert hast, dann musst du auch beispielsweise das <code>php-mysql</code>-Paket installieren.",
        "config-outdated-sqlite": "'''Warnung:''' SQLite $1 ist installiert. Allerdings benötigt MediaWiki SQLite $2 oder höher. SQLite wird daher nicht verfügbar sein.",
        "config-no-fts3": "'''Warnung:''' SQLite wurde ohne das [//sqlite.org/fts3.html FTS3-Modul] kompiliert, sodass keine Suchfunktionen für dieses Datenbanksystem zur Verfügung stehen werden.",
        "config-pcre-old": "<strong>Fataler Fehler:</strong> PCRE $1 oder neuer ist erforderlich!\nDie vorhandene PHP-Binärdatei ist mit PCRE $2 verknüpft.\n[https://www.mediawiki.org/wiki/Manual:Errors_and_symptoms/PCRE Weitere Informationen].",
        "config-sqlite-dir-help": "SQLite speichert alle Daten in einer einzigen Datei.\n\nDas für sie vorgesehene Verzeichnis muss während des Installationsvorgangs beschreibbar sein.\n\nEs sollte '''nicht''' über das Web zugänglich sein, was der Grund ist, warum die Datei nicht dort abgelegt wird, wo sich die PHP-Dateien befinden.\n\nDas Installationsprogramm wird mit der Datei zusammen eine zusätzliche <code>.htaccess</code>-Datei erstellen. Sofern dies scheitert, können Dritte auf die Datendatei zugreifen.\nDies umfasst die Nutzerdaten (E-Mail-Adressen, Passwörter, etc.) wie auch gelöschte Seitenversionen und andere vertrauliche Daten, die im Wiki gespeichert sind.\n\nEs ist daher zu erwägen, die Datendatei an gänzlich anderer Stelle abzulegen, beispielsweise im Verzeichnis <code>./var/lib/mediawiki/yourwiki</code>.",
        "config-oracle-def-ts": "Standardtabellenraum:",
        "config-oracle-temp-ts": "Temporärer Tabellenraum:",
-       "config-type-mysql": "MySQL (oder kompatible Datenbanksysteme)",
+       "config-type-mysql": "MariaDB, MySQL (oder kompatible Datenbanksysteme)",
        "config-type-postgres": "PostgreSQL",
        "config-type-sqlite": "SQLite",
        "config-type-oracle": "Oracle",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki unterstützt die folgenden Datenbanksysteme:\n\n$1\n\nSofern unterhalb nicht das Datenbanksystem angezeigt wird, das verwendet werden soll, muss dieses noch verfügbar gemacht werden. Oben ist zu jedem unterstützten Datenbanksystem ein Link zur entsprechenden Anleitung vorhanden.",
-       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] ist das von MediaWiki primär unterstützte Datenbanksystem. MediaWiki funktioniert auch mit [{{int:version-db-mariadb-url}} MariaDB] und [{{int:version-db-percona-url}} Percona Server], die MySQL-kompatibel sind. ([https://secure.php.net/manual/en/mysqli.installation.php Anleitung zur Kompilierung von PHP mit MySQL-Unterstützung])",
+       "config-dbsupport-mysql": "* [{{int:version-db-mariadb-url}} MariaDB] ist das von MediaWiki primär unterstützte Datenbanksystem. MediaWiki funktioniert auch mit [{{int:version-db-mysql-url}} MySQL] und [{{int:version-db-percona-url}} Percona Server], die MariaDB-kompatibel sind. ([https://secure.php.net/manual/en/mysqli.installation.php Anleitung zur Kompilierung von PHP mit MySQL-Unterstützung])",
        "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] ist ein beliebtes Open-Source-Datenbanksystem und eine Alternative zu MySQL. ([https://secure.php.net/manual/en/pgsql.installation.php Anleitung zur Kompilierung von PHP mit PostgreSQL-Unterstützung])",
        "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] ist ein verschlanktes Datenbanksystem, das auch gut unterstützt wird ([https://www.php.net/manual/de/pdo.installation.php Anleitung zur Kompilierung von PHP mit SQLite-Unterstützung], verwendet PHP Data Objects (PDO))",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] ist eine kommerzielle Unternehmensdatenbank ([https://www.php.net/manual/en/oci8.installation.php Anleitung zur Kompilierung von PHP mit OCI8-Unterstützung])",
        "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] ist eine gewerbliche Unternehmensdatenbank für Windows. ([https://www.php.net/manual/de/sqlsrv.installation.php Anleitung zur Kompilierung von PHP mit SQLSRV-Unterstützung])",
-       "config-header-mysql": "MySQL-Einstellungen",
+       "config-header-mysql": "MariaDB/MySQL-Einstellungen",
        "config-header-postgres": "PostgreSQL-Einstellungen",
        "config-header-sqlite": "SQLite-Einstellungen",
        "config-header-oracle": "Oracle-Einstellungen",
        "config-db-web-create": "Sofern nicht bereits vorhanden, muss nun das Konto erstellt werden",
        "config-db-web-no-create-privs": "Das angegebene und für den Installationsvorgang vorgesehene Datenbankkonto verfügt nicht über ausreichend Berechtigungen, um ein weiteres Datenbankkonto zu erstellen.\nDas hier angegebene Datenbankkonto muss daher bereits vorhanden sein.",
        "config-mysql-engine": "Datenbanksystem:",
-       "config-mysql-innodb": "InnoDB",
+       "config-mysql-innodb": "InnoDB (empfohlen)",
        "config-mysql-myisam": "MyISAM",
        "config-mysql-myisam-dep": "<strong>Warnung:</strong> Es wurde MyISAM als Speichersubsystem für das Datenbanksystem MySQL ausgewählt. Aus folgenden Gründen wird es nicht für den Einsatz mit MediaWiki empfohlen:\n* Es unterstützt aufgrund von Tabellensperrungen kaum die nebenläufige Ausführung von Aktionen.\n* Es ist anfälliger für Datenprobleme.\n* Es wird von MediaWiki nicht immer adäquat unterstützt.\n\nSofern die vorhandene MySQL-Installation das Speichersubsystem InnoDB unterstützt, wird deren Verwendung eindringlich empfohlen.\nSofern sie es nicht unterstützt, sollte nunmehr eine entsprechende Aktualisierung in Erwägung gezogen werden.",
        "config-mysql-only-myisam-dep": "<strong>Warnung:</strong> MyISAM ist das einzige verfügbare Speichersubsystem für das Datenbanksystem MySQL auf diesem Server. Es wird nicht für die Verwendung mit MediaWiki empfohlen, da es\n* aufgrund von Tabellensperrungen kaum die nebenläufige Ausführung von Aktionen unterstützt,\n* anfälliger für Datenprobleme ist und\n* von MediaWiki nicht immer adäquat unterstützt wird.\n\nDeine MySQL-Installation unterstützt nicht das Speichersubsystem InnoDB. Eine Aktualisierung wird nunmehr empfohlen.",
        "config-mysql-engine-help": "<strong>InnoDB</strong> als Speichersubsystem für das Datenbanksystem MySQL ist fast immer die bessere Wahl, da es gleichzeitige Zugriffe gut unterstützt.\n\n<strong>MyISAM</strong> als Speichersubsystem für das Datenbanksystem MySQL ist hingegen in Einzelnutzerumgebungen oder bei schreibgeschützten Wikis schneller.\nDatenbanken, die MyISAM verwenden, sind indes tendenziell fehleranfälliger als solche, die InnoDB verwenden.",
-       "config-mysql-charset": "Datenbankzeichensatz:",
-       "config-mysql-binary": "binär",
-       "config-mysql-utf8": "UTF-8",
-       "config-mysql-charset-help": "Im '''binären Modus''' speichert MediaWiki UTF-8 Texte in der Datenbank in binär kodierte Datenfelder.\nDies ist effizienter als der UTF-8-Modus von MySQL und ermöglicht so die Verwendung jeglicher Unicode-Zeichen.\n\nIm '''UTF-8-Modus''' wird MySQL den Zeichensatz der Daten erkennen und sie richtig anzeigen und konvertieren,\nallerdings können keine Zeichen außerhalb des [https://de.wikipedia.org/wiki/Basic_Multilingual_Plane#Gliederung_in_Ebenen_und_Bl.C3.B6cke ''Basic Multilingual Plane'' (BMP)] gespeichert werden.",
        "config-mssql-auth": "Authentifikationstyp:",
        "config-mssql-install-auth": "Wähle den Authentifikationstyp aus, der zur Verbindung mit der Datenbank während des Installationsprozesses verwendet wird.\nFalls du „{{int:config-mssql-windowsauth}}“ auswählst, werden die Anmeldeinformationen eines beliebigen Benutzers verwendet, der den Webserver ausführt.",
        "config-mssql-web-auth": "Wähle den Authentifikationstyp aus, der vom Webserver zur Verbindung mit dem Datenbankserver während des gewöhnlichen Betriebs des Wikis verwendet wird.\nFalls du „{{int:config-mssql-windowsauth}}“ auswählst, werden die Anmeldeinformationen eines beliebigen Benutzers verwendet, der den Webserver ausführt.",
        "config-install-interwiki-exists": "'''Warnung:'''  Es wurden Interwikitabellen mit Daten gefunden.\nDie Standardliste wird übersprungen.",
        "config-install-stats": "Statistiken werden initialisiert",
        "config-install-keys": "Geheimschlüssel werden erstellt",
-       "config-insecure-keys": "'''Warnung:''' {{PLURAL:$2|Der Geheimschlüssel|Die Geheimschlüssel}} $1, {{PLURAL:$2|der|die}} während des Installationsvorgangs generiert {{PLURAL:$2|wurde, ist|wurden, sind}} nicht sehr sicher. {{PLURAL:$2|Er sollte|Sie sollten}} manuell geändert werden.",
        "config-install-updates": "Unnötige Aktualisierungen nicht ausführen",
        "config-install-updates-failed": "<strong>Fehler:</strong> Das Einfügen von Aktualisierungsschlüssel in die Tabellen ist mit dem folgenden Fehler fehlgeschlagen: $1",
        "config-install-sysop": "Administratorkonto wird erstellt",
        "config-nofile": "Die Datei „$1“ konnte nicht gefunden werden. Wurde sie gelöscht?",
        "config-extension-link": "Wusstest du, dass dein Wiki die Nutzung von [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Extensions Erweiterungen] unterstützt?\n\nDu kannst die [https://www.mediawiki.org/wiki/Special:MyLanguage/Category:Extensions_by_category Erweiterungen nach Kategorie] anzeigen oder die [https://www.mediawiki.org/wiki/Extension_Matrix Erweiterungs-Matrix] aufrufen, um eine vollständige Liste der Erweiterungen zu sehen.",
        "config-skins-screenshots": "$1 (Bildschirmfotos: $2)",
+       "config-skins-screenshot": "$1 ($2)",
        "config-extensions-requires": "$1 (erfordert $2)",
        "config-screenshot": "Bildschirmfoto",
        "mainpagetext": "<strong>MediaWiki wurde installiert.</strong>",
index 26cdb59..159b66e 100644 (file)
@@ -59,8 +59,6 @@
        "config-mysql-engine": "Motorë depok kerdışi",
        "config-mysql-innodb": "InnoDB",
        "config-mysql-myisam": "MyISAM",
-       "config-mysql-binary": "Dılet",
-       "config-mysql-utf8": "UTF-8",
        "config-mssql-sqlauth": "SQL Server araştnayış",
        "config-mssql-windowsauth": "Windows kamiye araştnayış",
        "config-site-name": "Namey wiki:",
index acea1ea..34df619 100644 (file)
@@ -59,7 +59,7 @@
        "config-env-hhvm": "Το HHVM $1 είναι εγκατεστημένο.",
        "config-unicode-using-intl": "Χρησιμοποιείται η [https://pecl.php.net/intl επέκταση intl PECL] για κανονικοποίηση Unicode.",
        "config-unicode-pure-php-warning": "<strong>Προειδοποίηση:</strong> Η [https://pecl.php.net/intl επέκταση intl PECL] δεν είναι διαθέσιμη για να χειριστεί την κανονικοποίηση Unicode, επιστρέφουμε στην αργή αμιγώς PHP εφαρμογή.\nΕάν λειτουργείτε έναν ιστότοπο υψηλής επισκεψιμότητας, θα πρέπει να ρίξετε μια ματιά στην [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations κανονικοποίηση Unicode].",
-       "config-no-db": "Δεν βρέθηκε κάποιο κατάλληλο πρόγραμμα οδήγησης βάσης δεδομένων! Θα πρέπει να εγκαταστήσετε ένα πρόγραμμα οδήγησης βάσης δεδομένων για  PHP.\nΟ παρακάτω {{PLURAL:$2|τύπος βάσης δεδομένων|τύποι βάσεων δεδομένων}} υποστηρίζονται: $1.\n\nΑν κάνετε compile την PHP μόνοι σας, ρυθμίστε ξανά τις παραμέτρους με κάποιον ενεργοποιημένο εξυπηρετητή βάσεων  δεδομένων, για παράδειγμα, χρησιμοποιώντας την εντολή <code>./configure --with-mysqli</code>.\nΕάν έχετε εγκαταστήσει την PHP από κάποιο πακέτο στο Debian ή στο Ubuntu, τότε θα πρέπει να εγκαταστήσετε επίσης, για παράδειγμα, το πακέτο <code>php5-mysql</code>.",
+       "config-no-db": "Δεν βρέθηκε κάποιο κατάλληλο πρόγραμμα οδήγησης βάσης δεδομένων! Θα πρέπει να εγκαταστήσετε ένα πρόγραμμα οδήγησης βάσης δεδομένων για  PHP.\nΟ παρακάτω {{PLURAL:$2|τύπος βάσης δεδομένων|τύποι βάσεων δεδομένων}} υποστηρίζονται: $1.\n\nΑν κάνετε compile την PHP μόνοι σας, ρυθμίστε ξανά τις παραμέτρους με κάποιον ενεργοποιημένο εξυπηρετητή βάσεων  δεδομένων, για παράδειγμα, χρησιμοποιώντας την εντολή <code>./configure --with-mysqli</code>.\nΕάν έχετε εγκαταστήσει την PHP από κάποιο πακέτο στο Debian ή στο Ubuntu, τότε θα πρέπει να εγκαταστήσετε επίσης, για παράδειγμα, το πακέτο <code>php-mysql</code>.",
        "config-outdated-sqlite": "<strong>Προειδοποίηση:</strong> έχετε την SQLite έκδοση $1, που είναι χαμηλότερη από την ελάχιστη απαιτούμενη έκδοση $2. Η SQLite δεν θα είναι διαθέσιμη.",
        "config-pcre-no-utf8": "<strong>Κρίσιμο:</strong> Το PCRE module της PHP  φαίνεται να έχει μεταγλωττιστεί χωρίς υποστήριξη  PCRE_UTF8.\nΓια τη σωστή λειτουργία του MediaWiki απαιτείται υποστήριξη UTF-8.",
        "config-memory-raised": "Το  <code>memory_limit</code> της PHP είναι  $1 και αυξήθηκε σε  $2.",
        "config-dbsupport-postgres": "* Η [{{int:version-db-postgres-url}} PostgreSQL] είναι δημοφιλές σύστημα βάσης δεδομένων ανοικτού κώδικα ως εναλλακτική της MySQL. ([https://secure.php.net/manual/en/pgsql.installation.php Πώς να μεταγλωττίσετε την PHP με υποστήριξη PostgreSQL])",
        "config-dbsupport-sqlite": "* Η [{{int:version-db-sqlite-url}} SQLite] είναι ένα ελαφρύ σύστημα βάσης δεδομένων που υποστηρίζεται πολύ καλά. ([http://www.php.net/manual/en/pdo.installation.php Πώς να μεταγλωττίσετε την PHP με υποστήριξη SQLite], χρησιμοποιεί PDO)",
        "config-dbsupport-oracle": "* Η [{{int:version-db-oracle-url}} Oracle] είναι εμπορική βάση δεδομένων για επιχειρήσεις. ([http://www.php.net/manual/en/oci8.installation.php Πώς να μεταγλωττίσετε την PHP με υποστήριξη OCI8])",
-       "config-dbsupport-mssql": "* Ο [{{int:version-db-mssql-url}} Microsoft SQL Server] είναι εμπορική βάση δεδομένων για επιχειρήσεις που λειτουργεί σε Windows. ([Config-dbsupport-oracle/manual/en/sqlsrv.installation.php Πώς να μεταγλωττίσετε την PHP με υποστήριξη SQLSRV])",
+       "config-dbsupport-mssql": "* Ο [{{int:version-db-mssql-url}} Microsoft SQL Server] είναι εμπορική βάση δεδομένων για επιχειρήσεις που λειτουργεί σε Windows. ([https://secure.php.net/manual/en/sqlsrv.installation.php Πώς να μεταγλωττίσετε την PHP με υποστήριξη SQLSRV])",
        "config-header-mysql": "Ρυθμίσεις MySQL",
        "config-header-postgres": "Ρυθμίσεις PostgreSQL",
        "config-header-sqlite": "Ρυθμίσεις SQLite",
        "config-mysql-innodb": "InnoDB",
        "config-mysql-myisam": "MyISAM",
        "config-mysql-engine-help": "Το <strong>InnoDB</strong> είναι σχεδόν πάντα η καλύτερη επιλογή, αφού έχει καλή υποστήριξη ταυτόχρονης λειτουργίας.\n\nΤο <strong>MyISAM</strong> μπορεί να είναι ταχύτερο σε εγκαταστάσεις του ενός χρήστη ή μόνο ανάγνωσης. \nΟι βάσεις δεδομένων MyISAM τείνουν να φθείρονται συχνότερα από τις βάσεις δεδομένων InnoDB.",
-       "config-mysql-charset": "Σύνολο χαρακτήρων βάσης δεδομένων:",
-       "config-mysql-binary": "Δυαδικό",
-       "config-mysql-utf8": "UTF-8",
-       "config-mysql-charset-help": "Σε <strong>λειτουργία δυαδικού</strong>, το MediaWiki αποθηκεύει κείμενο UTF-8 στη βάση δεδομένων σε δυαδικά πεδία.\nΑυτό είναι πιο αποτελεσματικό από τη λειτουργία UTF-8 της MySQL και σας επιτρέπει να χρησιμοποιείτε ολόκληρο το φάσμα των χαρακτήρων Unicode.\n\nΣε <strong>λειτουργία UTF-8</strong>, η MySQL θα γνωρίζει σε ποιο σύνολο χαρακτήρων ανήκουν τα δεδομένα σας και θα μπορεί να τα παρουσιάζει και να τα μετατρέπει κατάλληλα, αλλά δεν θα σας επιτρέπει να αποθηκεύετε χαρακτήρες πάνω από το [https://en.wikipedia.org/wiki/Mapping_of_Unicode_character_planes βασικό πολύγλωσσο επίπεδο].",
        "config-mssql-auth": "Τύπος ελέγχου ταυτότητας:",
        "config-mssql-sqlauth": "Έλεγχος ταυτότητας του SQL Server",
        "config-mssql-windowsauth": "Έλεγχος ταυτότητας των Windows",
index 412b405..87bf792 100644 (file)
@@ -48,7 +48,7 @@
        "config-unicode-using-intl": "Using the [https://pecl.php.net/intl intl PECL extension] for Unicode normalization.",
        "config-unicode-pure-php-warning": "<strong>Warning:</strong> The [https://pecl.php.net/intl intl PECL extension] is not available to handle Unicode normalization, falling back to slow pure-PHP implementation.\nIf you run a high-traffic site, you should read a little on [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations Unicode normalization].",
        "config-unicode-update-warning": "<strong>Warning:</strong> The installed version of the Unicode normalization wrapper uses an older version of [http://site.icu-project.org/ the ICU project's] library.\nYou should [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations upgrade] if you are at all concerned about using Unicode.",
-       "config-no-db": "Could not find a suitable database driver! You need to install a database driver for PHP.\nThe following database {{PLURAL:$2|type is|types are}} supported: $1.\n\nIf you compiled PHP yourself, reconfigure it with a database client enabled, for example, using <code>./configure --with-mysqli</code>.\nIf you installed PHP from a Debian or Ubuntu package, then you also need to install, for example, the <code>php5-mysql</code> package.",
+       "config-no-db": "Could not find a suitable database driver! You need to install a database driver for PHP.\nThe following database {{PLURAL:$2|type is|types are}} supported: $1.\n\nIf you compiled PHP yourself, reconfigure it with a database client enabled, for example, using <code>./configure --with-mysqli</code>.\nIf you installed PHP from a Debian or Ubuntu package, then you also need to install, for example, the <code>php-mysql</code> package.",
        "config-outdated-sqlite": "<strong>Warning:</strong> you have SQLite $1, which is lower than minimum required version $2. SQLite will be unavailable.",
        "config-no-fts3": "<strong>Warning:</strong> SQLite is compiled without the [//sqlite.org/fts3.html FTS3 module], search features will be unavailable on this backend.",
        "config-pcre-old": "<strong>Fatal:</strong> PCRE $1 or later is required.\nYour PHP binary is linked with PCRE $2.\n[https://www.mediawiki.org/wiki/Manual:Errors_and_symptoms/PCRE More information].",
        "config-sqlite-dir-help": "SQLite stores all data in a single file.\n\nThe directory you provide must be writable by the webserver during installation.\n\nIt should <strong>not</strong> be accessible via the web; this is why we're not putting it where your PHP files are.\n\nThe installer will write a <code>.htaccess</code> file along with it, but if that fails someone can gain access to your raw database.\nThat includes raw user data (email addresses, hashed passwords) as well as deleted revisions and other restricted data on the wiki.\n\nConsider putting the database somewhere else altogether, for example in <code>/var/lib/mediawiki/yourwiki</code>.",
        "config-oracle-def-ts": "Default tablespace:",
        "config-oracle-temp-ts": "Temporary tablespace:",
-       "config-type-mysql": "MySQL (or compatible)",
+       "config-type-mysql": "MariaDB, MySQL, or compatible",
        "config-type-postgres": "PostgreSQL",
        "config-type-sqlite": "SQLite",
        "config-type-oracle": "Oracle",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki supports the following database systems:\n\n$1\n\nIf you do not see the database system you are trying to use listed below, then follow the instructions linked above to enable support.",
-       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] is the primary target for MediaWiki and is best supported. MediaWiki also works with [{{int:version-db-mariadb-url}} MariaDB] and [{{int:version-db-percona-url}} Percona Server], which are MySQL compatible. ([https://secure.php.net/manual/en/mysqli.installation.php How to compile PHP with MySQL 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-header-mysql": "MySQL settings",
+       "config-header-mysql": "MariaDB/MySQL settings",
        "config-header-postgres": "PostgreSQL settings",
        "config-header-sqlite": "SQLite settings",
        "config-header-oracle": "Oracle settings",
        "config-db-web-create": "Create the account if it does not already exist",
        "config-db-web-no-create-privs": "The account you specified for installation does not have enough privileges to create an account.\nThe account you specify here must already exist.",
        "config-mysql-engine": "Storage engine:",
-       "config-mysql-innodb": "InnoDB",
+       "config-mysql-innodb": "InnoDB (recommended)",
        "config-mysql-myisam": "MyISAM",
        "config-mysql-myisam-dep": "<strong>Warning:</strong> You have selected MyISAM as storage engine for MySQL, which is not recommended for use with MediaWiki, because:\n* it barely supports concurrency due to table locking\n* it is more prone to corruption than other engines\n* the MediaWiki codebase does not always handle MyISAM as it should\n\nIf your MySQL installation supports InnoDB, it is highly recommended that you choose that instead.\nIf your MySQL installation does not support InnoDB, maybe it's time for an upgrade.",
        "config-mysql-only-myisam-dep": "<strong>Warning:</strong> MyISAM is the only available storage engine for MySQL on this machine, and this is not recommended for use with MediaWiki, because:\n* it barely supports concurrency due to table locking\n* it is more prone to corruption than other engines\n* the MediaWiki codebase does not always handle MyISAM as it should\n\nYour MySQL installation does not support InnoDB, maybe it's time for an upgrade.",
        "config-mysql-engine-help": "<strong>InnoDB</strong> is almost always the best option, since it has good concurrency support.\n\n<strong>MyISAM</strong> may be faster in single-user or read-only installations.\nMyISAM databases tend to get corrupted more often than InnoDB databases.",
-       "config-mysql-charset": "Database character set:",
-       "config-mysql-binary": "Binary",
-       "config-mysql-utf8": "UTF-8",
-       "config-mysql-charset-help": "In <strong>binary mode</strong>, MediaWiki stores UTF-8 text to the database in binary fields.\nThis is more efficient than MySQL's UTF-8 mode, and allows you to use the full range of Unicode characters.\n\nIn <strong>UTF-8 mode</strong>, MySQL will know what character set your data is in, and can present and convert it appropriately, but it will not let you store characters above the [https://en.wikipedia.org/wiki/Mapping_of_Unicode_character_planes Basic Multilingual Plane].",
        "config-mssql-auth": "Authentication type:",
        "config-mssql-install-auth": "Select the authentication type that will be used to connect to the database during the installation process.\nIf you select \"{{int:config-mssql-windowsauth}}\", the credentials of whatever user the webserver is running as will be used.",
        "config-mssql-web-auth": "Select the authentication type that the web server will use to connect to the database server, during ordinary operation of the wiki.\nIf you select \"{{int:config-mssql-windowsauth}}\", the credentials of whatever user the webserver is running as will be used.",
        "config-install-interwiki-exists": "<strong>Warning:</strong> The interwiki table seems to already have entries.\nSkipping default list.",
        "config-install-stats": "Initializing statistics",
        "config-install-keys": "Generating secret keys",
-       "config-insecure-keys": "<strong>Warning:</strong> {{PLURAL:$2|A secure key|Secure keys}} ($1) generated during installation {{PLURAL:$2|is|are}} not completely safe. Consider changing {{PLURAL:$2|it|them}} manually.",
        "config-install-updates": "Prevent running unneeded updates",
        "config-install-updates-failed": "<strong>Error:</strong> Inserting update keys into tables failed with the following error: $1",
        "config-install-sysop": "Creating administrator user account",
index bf791f3..3adafe8 100644 (file)
@@ -49,8 +49,6 @@
        "config-header-sqlite": "SQLite-agordoj",
        "config-header-oracle": "Oracle-agordoj",
        "config-header-mssql": "Microsoft SQL Server-agordoj",
-       "config-mysql-binary": "Duuma",
-       "config-mysql-utf8": "UTF-8",
        "config-site-name": "Nomo de vikio:",
        "config-ns-generic": "Projekto",
        "config-admin-name": "Via uzantonomo:",
index 1eb460a..9c24b34 100644 (file)
@@ -35,7 +35,8 @@
                        "Irus",
                        "Tinss",
                        "KATRINE1992",
-                       "MarcoAurelio"
+                       "MarcoAurelio",
+                       "Adjen"
                ]
        },
        "config-desc": "El instalador de MediaWiki",
@@ -84,7 +85,7 @@
        "config-unicode-using-intl": "Se utiliza la [https://pecl.php.net/intl extensión «intl» de PECL] para la normalización Unicode.",
        "config-unicode-pure-php-warning": "<strong>Advertencia:</strong> la [https://pecl.php.net/intl extensión intl] no está disponible para efectuar la normalización Unicode. Se utilizará la implementación más lenta en PHP puro.\nSi tu web tiene mucho tráfico, te recomendamos leer acerca de la [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations normalización Unicode].",
        "config-unicode-update-warning": "<strong>Atención:</strong> la versión instalada del contenedor de normalización de Unicode utiliza una versión anticuada de la biblioteca del [http://site.icu-project.org/ proyecto ICU].\nDeberías [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations modernizarla] si te interesa utilizar Unicode.",
-       "config-no-db": "No se encontró un controlador adecuado para la base de datos. Necesitas instalar un controlador de base de datos para PHP.\n{{PLURAL:$2|Se admite el siguiente gestor de bases de datos|Se admiten los siguientes gestores de bases de datos}}: $1.\n\nSi compilaste PHP por tu cuenta, debes reconfigurarlo activando un cliente de base de datos, por ejemplo, mediante <code>./configure --with-mysqli</code>.\nSi instalaste PHP desde un paquete de Debian o Ubuntu, también debes instalar, por ejemplo, el paquete <code>php5-mysql</code>.",
+       "config-no-db": "No se encontró un controlador adecuado para la base de datos. Necesitas instalar un controlador de base de datos para PHP.\n{{PLURAL:$2|Se admite el siguiente gestor de bases de datos|Se admiten los siguientes gestores de bases de datos}}: $1.\n\nSi compilaste PHP por tu cuenta, debes reconfigurarlo activando un cliente de base de datos, por ejemplo, mediante <code>./configure --with-mysqli</code>.\nSi instalaste PHP desde un paquete de Debian o Ubuntu, también debes instalar, por ejemplo, el paquete <code>php-mysql</code>.",
        "config-outdated-sqlite": "<strong>Advertencia:</strong> tienes SQLite $1, que es inferior a la mínima versión requerida: $2. SQLite no estará disponible.",
        "config-no-fts3": "<strong>Advertencia:</strong> SQLite está compilado sin el [//sqlite.org/fts3.html módulo FTS3]. Las funcionalidades de búsqueda no estarán disponibles en esta instalación.",
        "config-pcre-old": "'''Fatal:''' Se requiere PCRE $1 o posterior.\nSu PHP binario está enlazado con PCRE $2.\n[https://www.mediawiki.org/wiki/Manual:Errors_and_symptoms/PCRE Más información].",
        "config-sqlite-dir-help": "SQLite almacena todos los datos en un único archivo.\n\nEl directorio que proporciones debe poder escribirse por el servidor web durante la instalación.\n\n'''No''' debería ser accesible a través de Internet. Por eso no vamos a ponerlo en el sitio donde están los archivos PHP.\n\nEl instalador escribirá un archivo <code>.htaccess</code> junto con él, pero si falla alguien podría tener acceso a la base de datos en bloque.\nEso incluye los datos de usuario en bloque (direcciones de correo electrónico, las contraseñas con hash) así como revisiones eliminadas y otros datos restringidos del wiki.\n\nConsidera poner la base de datos en algún otro sitio, por ejemplo en <code>/var/lib/mediawiki/tuwiki</code> .",
        "config-oracle-def-ts": "Espacio de tablas predeterminado:",
        "config-oracle-temp-ts": "Espacio de tablas temporal:",
-       "config-type-mysql": "MySQL (o compatible)",
+       "config-type-mysql": "MariaDB, MySQL o un sistema compatible",
        "config-type-postgres": "PostgreSQL",
        "config-type-sqlite": "SQLite",
        "config-type-oracle": "Oracle",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki es compatible con los siguientes sistemas de bases de datos:\n\n$1\n\nSi no encuentras en el listado el sistema de base de datos que estás intentando utilizar, sigue las instrucciones enlazadas arriba para activar la compatibilidad.",
-       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] es la base de datos mayoritaria para MediaWiki y la que goza de mayor compatibilidad. MediaWiki también funciona con [{{int:version-db-mariadb-url}} MariaDB] y [{{int:version-db-percona-url}} Percona Server], que son compatibles con MySQL. ([https://secure.php.net/manual/es/mysql.installation.php Cómo compilar PHP con compatibilidad MySQL])",
-       "config-dbsupport-postgres": "[{{int:version-db-postgres-url}} PostgreSQL] es un sistema de base de datos popular de código abierto, alternativa a MySQL. ([https://secure.php.net/manual/es/pgsql.installation.php Cómo compilar PHP con compatibilidad PostgreSQL]).",
-       "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] es un sistema de base de datos ligero con gran compatibilidad con MediaWiki. ([http://www.php.net/manual/es/pdo.installation.php Cómo compilar PHP con compatibilidad SQLite], usando PDO)",
-       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] es una base de datos comercial a nivel empresarial. ([http://www.php.net/manual/es/oci8.installation.php Cómo compilar PHP con compatibilidad con OCI8])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] es un sistema comercial de base de datos empresariales para Windows. ([Config-dbsupport-oracle/manual/en/sqlsrv.installation.php Cómo compilar PHP con compatibilidad con SQLSRV])",
-       "config-header-mysql": "Configuración de MySQL",
+       "config-dbsupport-mysql": "* [{{int:version-db-mariadb-url}} MariaDB] es la base de datos mayoritaria para MediaWiki y la que goza de mayor compatibilidad. MediaWiki también funciona con [{{int:version-db-myslql-url}} MySQL] y [{{int:version-db-percona-url}} Percona Server], que son compatibles con MariaDB. ([https://secure.php.net/manual/es/mysql.installation.php Cómo compilar PHP con compatibilidad MySQL])",
+       "config-dbsupport-postgres": "[{{int:version-db-postgres-url}} PostgreSQL] es un sistema de base de datos popular de código abierto, alternativa a MySQL. ([https://secure.php.net/manual/es/pgsql.installation.php Cómo compilar PHP con compatibilidad PostgreSQL]).",
+       "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] es un sistema de base de datos ligero con gran compatibilidad con MediaWiki. ([https://secure.php.net/manual/en/pdo.installation.php Cómo compilar PHP con compatibilidad SQLite], usando PDO)",
+       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] es una base de datos comercial a nivel empresarial. ([https://secure.php.net/manual/en/oci8.installation.php Cómo compilar PHP con compatibilidad con OCI8])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] es un sistema comercial de base de datos empresariales para Windows. ([https://secure.php.net/manual/en/sqlsrv.installation.php Cómo compilar PHP con compatibilidad con SQLSRV])",
+       "config-header-mysql": "Configuración de MariaDB/MySQL",
        "config-header-postgres": "Configuración de PostgreSQL",
        "config-header-sqlite": "Configuración de SQLite",
        "config-header-oracle": "Configuración de Oracle",
        "config-mysql-myisam-dep": "<strong>Atención:</strong> has seleccionado MyISAM como motor de almacenamiento de MySQL, el cual no está recomendado para usarse con MediaWiki, porque:\n* apenas admite la concurrencia debido al bloqueo de tablas\n* es más propenso a daños que otros motores\n* el código MediaWiki no siempre controla MyISAM como debería\n\nSi tu instalación de MySQL admite InnoDB, es muy recomendable que lo elijas en su lugar.\nSi tu instalación de MySQL no admite InnoDB, quizás es el momento de una modernización.",
        "config-mysql-only-myisam-dep": "<strong>Advertencia:</strong> solo se ha encontrado el motor de almacenamiento MyISAM para MySQL en esta máquina, y no se recomienda su uso con MediaWiki, porque:\n* apenas admite la concurrencia debido al bloqueo de tablas\n* es más propenso a daños que otros motores\n* el código de MediaWiki no siempre controla MyISAM como debería\n\nTu instalación de MySQL no admite InnoDB; quizás es el momento de una actualización.",
        "config-mysql-engine-help": "<strong>InnoDB</strong> es casi siempre la mejor opción, dado que soporta bien los accesos simultáneos.\n\n<strong>MyISAM</strong> puede ser más rápido en instalaciones con usuario único o de sólo lectura.\nLas bases de datos MyISAM tienden a corromperse más a menudo que las bases de datos InnoDB.",
-       "config-mysql-charset": "Conjunto de caracteres de la base de datos:",
-       "config-mysql-binary": "Binario",
-       "config-mysql-utf8": "UTF-8",
-       "config-mysql-charset-help": "En <strong>modo binario</strong>, MediaWiki almacena texto UTF-8 para la base de datos en campos binarios.\nEsto es más eficiente que el modo UTF-8 de MySQL y permite utilizar la gama completa de caracteres Unicode.\n\nEn <strong>modo UTF-8</strong>, MySQL sabrá qué conjunto de caracteres emplean sus datos y puede presentarlos y convertirlos adecuadamente, pero no permitirá almacenar caracteres por encima del [https://en.wikipedia.org/wiki/Mapping_of_Unicode_character_planes plano multilingüe básico].",
        "config-mssql-auth": "Tipo de autenticación:",
        "config-mssql-install-auth": "Selecciona el tipo de autenticación que se utilizará para conectarse a la base de datos durante el proceso de instalación.\nSi seleccionas \"{{int:config-mssql-windowsauth}}\", se usarán las credenciales del usuario con el que se ejecuta el servidor web.",
        "config-mssql-web-auth": "Selecciona el tipo de autenticación que utilizará el servidor web para conectarse al servidor de base de datos, durante el funcionamiento normal de la wiki.\nSi seleccionas \"{{int:config-mssql-windowsauth}}\", se usarán las credenciales del usuario con el cual se ejecuta el servidor web.",
        "config-license-help": "Muchos wikis públicos ponen todas las contribuciones bajo una [https://freedomdefined.org/Definition licencia libre].\nEsto ayuda a crear un sentido de propiedad comunitaria y alienta la contribución a largo plazo.\nEsto no es generalmente necesario para un wiki privado o corporativo.\n\nSi deseas poder utilizar texto de Wikipedia, y deseas que Wikipedia pueda aceptar el texto copiado de tu wiki, debes elegir <strong>{{int:config-license-cc-by-sa}}</strong>.\n\nWikipedia utilizaba anteriormente la licencia de documentación libre de GNU (GFDL).\nLa GFDL es una licencia válida, pero es difícil de entender.\nTambién es difícil reutilizar el contenido licenciado bajo la GFDL.",
        "config-email-settings": "Configuración de correo electrónico",
        "config-enable-email": "Activar el envío de correos electrónicos",
-       "config-enable-email-help": "Si quieres que el correo electrónico funcione, la [Config-dbsupport-oracle/manual/en/mail.configuration.php configuración PHP de correo electrónico] debe ser la correcta.\nSi no quieres la funcionalidad de correo electrónico, puedes desactivarla aquí.",
+       "config-enable-email-help": "Si quieres que el correo electrónico funcione, la [https://secure.php.net/manual/en/mail.configuration.php configuración PHP de correo electrónico] debe ser la correcta.\nSi no quieres ninguna funcionalidad de correo electrónico, puedes desactivarlas aquí.",
        "config-email-user": "Activar correo electrónico entre usuarios",
        "config-email-user-help": "Permitir que todos los usuarios intercambien correos electrónicos si lo han activado en sus preferencias.",
        "config-email-usertalk": "Activar notificaciones de páginas de discusión de usuarios",
        "config-install-interwiki-exists": "<strong>Advertencia:</strong> la tabla de interwikis parece ya contener entradas.\nSe omitirá la lista predeterminada.",
        "config-install-stats": "Iniciando las estadísticas",
        "config-install-keys": "Generando claves secretas",
-       "config-insecure-keys": "<strong>Advertencia:</strong> {{PLURAL:$2|una clave de seguridad generada|las claves de seguridad generadas}} ($1) durante la instalación no {{PLURAL:$2|es totalmente segura|son totalmente seguras}}. Considera {{PLURAL:$2|cambiarla|cambiarlas}} manualmente.",
        "config-install-updates": "Evitar ejecutar actualizaciones innecesarias",
        "config-install-updates-failed": "<strong>Error:</strong> falló la inserción de claves de actualización en las tablas con el siguiente error: $1",
        "config-install-sysop": "Creando la cuenta de usuario del administrador",
index 2831396..6928530 100644 (file)
@@ -5,7 +5,8 @@
                        "පසිඳු කාවින්ද",
                        "Subi",
                        "Sator",
-                       "Mikel Ibaiba"
+                       "Mikel Ibaiba",
+                       "Fitoschido"
                ]
        },
        "config-desc": "MediaWiki instalatzailea",
@@ -54,7 +55,7 @@
        "config-unicode-using-intl": "[https://pecl.php.net/intl intl PECL extension] erabiltzen Unicode-ren normalizaziorako.",
        "config-unicode-pure-php-warning": "<strong>Oharra:</strong> [https://pecl.php.net/intl intl PECL extension] ez dago prest Unicode-ren normalizazioa jasatzeko,PHP hutsaren ezarpena motelara itzultzen.\n\nTrafiko handiko gune bat exekutatzen baduzu, apur bat irakurri beharko zenuke [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations Unicode normalization]-ri buruz.",
        "config-unicode-update-warning": "<strong>Oharra:</strong> Unicode-ren normalizazioaren bilgarriaren bertsio instalatua [http://site.icu-project.org/ ICU proiektuaren] liburutegia bertsio zaharrago bat erabiltzen du.\n[Https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations upgrade] behar duzu Unicode erabiltzeagatik kezkatuta bazaude.",
-       "config-no-db": "Ezin izan da aurkitu datu-basearen driver egoki bat! Instalatu behar duzu PHP-ko datu-basearen driver bat. Hurrengo datu {{PLURAL:$2|basea|baseak}} onartzen {{PLURAL:$2|da|dira}}:$1\n\n\nPHP-k zuk konpilatu baduzu, berkonfiguratu datu-basearen bezeroarekin gaituta, adibidez, <code>./configure --with-mysqli</code>. erabiliz.\nDebian edo Ubuntu pakete batetik PHPa instalatu baduzu, orduan instalatu behar duzu ere bai hurrengo adibide bezalako bat <code>php5-mysql</code>",
+       "config-no-db": "Ezin izan da aurkitu datu-basearen driver egoki bat! Instalatu behar duzu PHP-ko datu-basearen driver bat. Hurrengo datu {{PLURAL:$2|basea|baseak}} onartzen {{PLURAL:$2|da|dira}}:$1\n\n\nPHP-k zuk konpilatu baduzu, berkonfiguratu datu-basearen bezeroarekin gaituta, adibidez, <code>./configure --with-mysqli</code>. erabiliz.\nDebian edo Ubuntu pakete batetik PHPa instalatu baduzu, orduan instalatu behar duzu ere bai hurrengo adibide bezalako bat <code>php-mysql</code>",
        "config-outdated-sqlite": "<strong>Warning:</strong> SQLite $1 daukazu, hau da, gutxieneko bertsioa $2 baino atzeratutagoa da. SQLite ez dago erabilgarri.",
        "config-no-fts3": "<strong>Warning:</strong> SQLite konpilatu egin da  [//sqlite.org/fts3.html FTS3 module] barik, \nbilaketa funtzioak ez dira erabilgarri izango \"backend\" honetan.",
        "config-pcre-old": "<strong>Fatal:</strong> PCRE $1 edo berriagoa behar da.\nZure PHP bitarra PCRE $2 rekin lotzen da.\n[https://www.mediawiki.org/wiki/Manual:Errors_and_symptoms/PCRE Informazio gehiago].",
        "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] iturburu irekiko datu basea sistema famatua da MySQL-rako alternatiba bezala. ([https://secure.php.net/manual/en/pgsql.installation.php How to compile PHP with PostgreSQL support])",
        "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] oso ondo onartzen duen datu-basearen sistema arina da.\n ([http://www.php.net/manual/en/pdo.installation.php How to compile PHP with SQLite support], uses PDO)",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] enpresa komertzial baten datu-basea da. ([http://www.php.net/manual/en/oci8.installation.php How to compile PHP with OCI8 support])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] Windows-entzako enpresa komertzial baten datu-basea da.  ([Config-dbsupport-oracle/manual/en/sqlsrv.installation.php How to compile PHP with SQLSRV support])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] Windows-entzako enpresa komertzial baten datu-basea da.  ([https://secure.php.net/manual/en/sqlsrv.installation.php How to compile PHP with SQLSRV support])",
        "config-header-mysql": "MySQL hobespenak",
        "config-header-postgres": "PostgreSQL hobespenak",
        "config-header-sqlite": "SQLite hobespenak",
        "config-mysql-myisam-dep": "<strong>Oharra:</strong> MyISAM MySQL biltegiratze-motor gisa aukeratu duzu, MediaWikirekin erabiltzeko gomendagarria ez dena honengatik:\n*taula blokeoak direla-eta gauza gutxi onartu ohi du\n*beste motore batzuek baino ustelkeria gehiago izateko aukerak ditu\n*MediaWiki-ren kode baseak ez du beti kudeatzen MyISAM behar bezala\n\nZure MySQL instalazioa InnoDB onartzen badu, hori aukeratzeko gomendatzen da.\nZure MySQL instalazioa InnoDB ez badu onartzen, baliteke bertsioa berritzeko ordua izatea.",
        "config-mysql-only-myisam-dep": "<strong> Oharra: </strong> MyISAM makinaren MySQL biltegiratze motarako bakarra da, eta hau ez da MediaWiki-rekin erabiltzeko gomendatzen, honengatik:\n* maiztasunez taula blokeoek konkurrentzia ez dute onartzen \n* Beste motore batzuek baino ustelkeria gehiago izaten dute\n* MediaWiki-ren kodekak ez du beti kudeatzen MyISAM behar bezala\n\nZure MySQL instalazioak ez du InnoDB onartzen, agian bertsio berritzeko ordua da.",
        "config-mysql-engine-help": "<strong>InnoDB</strong> ia beti aukerarik onena da, konkurrentzia-laguntza ona duelako.\n\n<strong>MyISAM</strong> erabiltzaile bakarreko edo irakurketa bakarreko instalazioetan azkarragoa izan daiteke.\nMyISAM datu-basea gehiagokotan hondatuta ageri da InnoDB datu-baseareakin baino.",
-       "config-mysql-charset": "Datu-basearen karaktere multzoa:",
-       "config-mysql-binary": "Bitarra",
-       "config-mysql-utf8": "UTF-8",
-       "config-mysql-charset-help": "<strong>Modu bitarrean</strong>, MediaWiki-k UTF-8 testua datu-baseko eremu bitarretan gordetzen du.\nHau MySQL-en UTF-8 modua baino eraginkorragoa da eta Unicode karaktereen barruti osoa erabiltzea ahalbidetzen du.\n\n<Strong>UTF-8 moduan</strong>, MySQL-k jakingo du zer karakterean zure datuak konfiguratzen dituen, aurkeztu eta behar bezala bihurtzeko, baina ez dizkizu karaktereak [https://en.wikipedia.org/wiki/Mapping_of_Unicode_character_planes Oinarrizko Eleaniztasun Plana]-ren gainetik gordetzen utziko.",
        "config-mssql-auth": "Autentifikazio mota:",
        "config-mssql-install-auth": "Aukeratu instalazio prozesuan zehar datu-basera konektatzeko erabiliko den autentifikazio mota.\n\"{{Int: config-mssql-windowsauth}}\" hautatzen baduzu, web zerbitzariak duen edozein erabiltzailek erabiliko duen kredentziala erabiliko da.",
        "config-mssql-web-auth": "Aukeratu instalazio prozesuan zehar datu-base zerbitzariari konektatzeko erabiliko den autentifikazio mota.\n\"{{Int: config-mssql-windowsauth}}\" hautatzen baduzu, web zerbitzariak duen edozein erabiltzailek erabiliko duen kredentziala erabiliko da.",
        "config-install-interwiki-exists": "<strong>Oharra:</strong> Interwikiko taula badirudi sarrerak dituela. \nTaula estandarra saltatzen.",
        "config-install-stats": "Estatistikak hasten",
        "config-install-keys": "Gako sekretuak sortzen",
-       "config-insecure-keys": "<strong>Oharra:</strong> ($1) instalazioan zehar sortu {{PLURAL:$2|den|diren}} {{PLURAL:$2|gako segurua|gako seguruak}}ez d(ir)a guztiz segurua(k). Kontuan hartu {{PLURAL:$2|hau|hauek}} eskuz aldatzeko aukera.",
        "config-install-updates": "Saihestu egikaratzen behar ez diren aktualizazioak",
        "config-install-updates-failed": "<strong>Errore</strong> Sartzea eguneratze-gakoak taulen barruan huts egin du hurrengo errorearekin: $1",
        "config-install-sysop": "Administratzaile kontua sortzen",
        "config-install-done-path": "<strong>Zorionak!</strong>\nMediaWiki instalatu duzu.\n\nInstalatzaileak sortu egin du <code>LocalSettings.php</code>\nZure konfigurazio guztia dauka.\n\nDeskargatu egin behar duzu eta jarri <code>$4</code> -ean . Deskarga automakikoki hasiko da.\n\nEz badizu deskargatzeko aukerarik eman, edo kantzalatu egin baduzu, hurrengo linkean klikatu berrabiatzeko:\n\n$3\n\n<strong>Oharra:</strong> Instalazio prozesuatik ateratzen bazara konfigurazio artxikoa deskargatu barik, gero ez da egongo eskuragarri.\n\nBehin hori eginda, <strong>[$2 enter your wiki]</strong> ahal duzu.",
        "config-install-success": "MediaWiki arrakastaz instalatu da. Orain <$1$2> bisitatu dezakezu zure wikia ikusteko.\nGalderarik izanez gero, begiratu gure maiztasunez egiten diren galderen zerrenda:\n<https://www.mediawiki.org/wiki/Manual:FAQ> edo erabili orrialde honi lotuta dauden laguntza foroetako bat.",
        "config-download-localsettings": "Jaitsi <code>LocalSettings.php</code>",
-       "config-help": "Laguntza",
+       "config-help": "laguntza",
        "config-help-tooltip": "sakatu zabaltzeko",
        "config-nofile": "Ezin da \"$1\" fitxategia aurkitu. Ezabatua izan da?",
        "config-extension-link": "Ba al zenekien wikiak [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Extensions extensions] onartzen dituela?\n\nArakatu [https://www.mediawiki.org/wiki/Special:MyLanguage/Category:Extensions_by_category extensions by category] edo [https://www.mediawiki.org/wiki/Extension_Matrix Extension Matrix] ikusi ahal izateko luzapenen zerrenda.",
index 15bb39c..3102bfb 100644 (file)
        "config-sqlite-dir-help": "اس‌کیولایت همهٔ اطلاعات را در یک پوشهٔ جداگانه ذخیره می‌کند.\nفهرستی را که به وجود‌ آوردید باید در طی نصب به‌ وسیلهٔ وب‌سرور قابل نوشتن باشد.\n<strong>نباید</strong> از طریق وب در دسترس باشد، به همین دلیل ما آن را در جایی که پوشه‌های پی‌اچ‌پی شما هست، قرار نمی‌دهیم.\nنصب کننده یک پوشهٔ <code>.htaccess</code> همراه آن خواهدآورد،اما اگر این کار را انجام ندهد،کسی می‌تواند به پایگاه اطلاعاتی شما دسترسی پیدا کند.\nاطلاعات خام کاربر شامل (آدرس‌های ایمیل، علامت‌‌ها با شماره‌های رمز عبور) به خوبی پاک کردن تغییرات و دیگر اطلاعات محرمانه در ویکی.\nقرار دادن پایگاه اطلاعاتی باهم را در جایی دیگر در نظر بگیرید، برای مثال در <code>/var/lib/mediawiki/yourwiki</code>.",
        "config-oracle-def-ts": "جدول پیش فرض:",
        "config-oracle-temp-ts": "جدول موقت:",
-       "config-type-mysql": "مای‌اس‌کیو‌ال (یا سازگار)",
+       "config-type-mysql": "MariaDB، مای‌اس‌کیو‌ال (یا سازگار)",
        "config-type-mssql": "سرور مایکروسافت اس‌کیو‌ال",
        "config-support-info": "مدیاویکی سامانه‌های پایگاه اطلاعاتی زیر را حمایت می‌کند:\n$1\nاگر متوجه سامانه پایگاه اطلاعاتی که سعی دارید از فهرست زیر استفاده کنید، نمی‌شوید، بنابراین دستورالعمل‌های مرتبط در بالا را برای فعال کردن پشتیبانی دنبال کنید.",
-       "config-dbsupport-mysql": "*[{{int:version-db-mysql-url}} MySQL] مهم‌ترین هدف برای مدیاویکی است و بهترین پشتیبانی. مدیاویکی همچنین کار می‌کند با [{{int:version-db-mariadb-url}} MariaDB] و [{{int:version-db-percona-url}} Percona Server] که با MySQL سازگار هستند.([https://secure.php.net/manual/en/mysqli.installation.php چگونه php را با MySQL کامپایل کنیم])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} پستگرس‌کیوال] یک سامانه پایگاه اطلاعات متن‌باز پر‌طرفدار است که جایگزینی برای مای‌اس‌کیوال است. ([Config-dbsupport-oracle/manual/en/pgsql.installation.php راهنمای تنظیم کردن پی‌اچ‌پی به همراه پستگرس‌کیوال])",
-       "config-dbsupport-sqlite": "*[{{int:version-db-sqlite-url}} اس‌کیولایت] یک سامانه پایگاه اطلاعاتی کم حجمی است که بسیار خوب پشتیبانی شده‌است.\n([http://www.php.net/manual/en/pdo.installation.php چگونگی کامپایل پی‌اچ‌پی با اس‌کیولایت]، از PDO استفاده می‌کند)",
-       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] یک پایگاه اطلاعاتی کار تبلیغاتی است.\n([http://www.php.net/manual/en/oci8.installation.php How to compile PHP with OCI8 support])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] یک پایگاه اطلاعاتی موسسهٔ تبلیغاتی برای وینذوز است. ([Config-dbsupport-oracle/manual/en/sqlsrv.installation.php How to compile PHP with SQLSRV support])",
-       "config-header-mysql": "تنظیمات مای‌اس‌کیو‌ال",
+       "config-dbsupport-mysql": "*[{{int:version-db-mariadb-url}} MariaDB] مهم‌ترین هدف برای مدیاویکی است و بهترین پشتیبانی. مدیاویکی همچنین کار می‌کند با [{{int:version-db-mysql-url}} MariaDB] و [{{int:version-db-percona-url}} Percona Server] که با MariaDB سازگار هستند.([https://secure.php.net/manual/en/mysqli.installation.php چگونه php را با MariaDB کامپایل کنیم])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} پستگرس‌کیوال] یک سامانه پایگاه اطلاعات متن‌باز پر‌طرفدار است که جایگزینی برای مای‌اس‌کیوال است. ([https://secure.php.net/manual/en/pgsql.installation.php راهنمای تنظیم کردن پی‌اچ‌پی به همراه پستگرس‌کیوال])",
+       "config-dbsupport-sqlite": "*[{{int:version-db-sqlite-url}} اس‌کیولایت] یک سامانه پایگاه اطلاعاتی کم حجمی است که بسیار خوب پشتیبانی شده‌است.\n([https://secure.php.net/manual/en/pdo.installation.php چگونگی کامپایل پی‌اچ‌پی با اس‌کیولایت]، از PDO استفاده می‌کند)",
+       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] یک پایگاه اطلاعاتی کار تبلیغاتی است.\n([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] یک پایگاه اطلاعاتی موسسهٔ تبلیغاتی برای وینذوز است. ([https://secure.php.net/manual/en/sqlsrv.installation.php How to compile PHP with SQLSRV support])",
+       "config-header-mysql": "تنظیمات MariaDB/مای‌اس‌کیو‌ال",
        "config-header-postgres": "تنظیمات پست‌گر‌اس‌کیو‌ال",
        "config-header-sqlite": "تنظیمات اس‌کیو‌لایت",
        "config-header-oracle": "تنظیمات اوراکل",
        "config-db-web-create": "اگر در حال‌حاضر وجود ندارد،حساب ایجاد کنید",
        "config-db-web-no-create-privs": "حسابی که شما برای نصب تعیین کردید،مزایای کافی برای ایجاد یک حساب را ندارد.\nحسابی که شما اینجا تعیین کرده‌اید باید در حال حاضر وجود داشته باشد.",
        "config-mysql-engine": "موتور ذخیره سازی:",
-       "config-mysql-innodb": "اینودی‌بی",
+       "config-mysql-innodb": "اینودی‌بی (پیشنهاد می‌شود)",
        "config-mysql-myisam": "می‌ای‌سم",
        "config-mysql-myisam-dep": "'''هشدار:''' شما مای‌آی‌اس‌ای‌ام را به عنوان موتور ذخیره برای مای‌آی‌اس‌ای‌ام انتخاب کرده‌اید، که برای استفاده با مدیاویکی توصیه نمی‌شود زیرا:\n* به‌علت قفل شدن جدول اجمالاً به طور همزمان پشتیبانی می کند\n* بیشتر از دیگر موتورها برای از بین‌ رفتن مستعد است.\n* مبنای رمز مدیاویکی همیشه مای‌آی‌اس‌ای‌ام را همان طور که باید باشد،کنترل نمی‌کند\nاگر نصب مای‌اس‌کیو‌ال شما اینودی‌بی را پشتیبانی می‌کند،بسیار توصیه می‌شود  که در عوض ،آن را انتخاب کنید.\nاگر نصب مای‌اس‌کیو‌ال شما، اینودی‌بی را پشتیبانی نمی‌کند، ممکن است زمان ارتقاء رسیده باشد.",
        "config-mysql-only-myisam-dep": "'''هشدار:''' مای‌آی‌اس‌ای‌ام تنها موتور ذخیره‌سازی اطلاعات برای مای‌اس‌کیو‌ال در این دستگاه است، و برای استفاده با مدیاویکی توصیه نمی‌شود، زیرا:\n* به‌علت قفل شدن جدول اجمالاً به طور همزمان پشتیبانی می کند\n* بیشتر از دیگر موتورها برای از بین‌ رفتن مستعد است.\n* مبنای رمز مدیاویکی همیشه مای‌آی‌اس‌ای‌ام را همان طور که باید باشد،کنترل نمی‌کند\nنصب مای‌اس‌کیو‌ال شما اینودی‌بی را پشتیبانی نمی‌کند،ممکن است زمان یک ارتقاء رسیده باشد.",
        "config-mysql-engine-help": "'''اینودی‌بی''' تقریباً همیشه بهترین گزینه است،زیرا پشتیبانی همزمان خوبی دارد.\n'''مای‌آی‌اس‌ای‌ام''' ممکن است در نصب‌های کاربر جداگانه یا فقط خواندنی سریع‌تر باشد.\nپایگاه‌های اطلاعاتی مای‌آی‌اس‌ای‌ام اغلب بیشتر از پایگاه‌های اطلاعاتی اینودی‌بی مستعد ازبین رفتن هستند.",
-       "config-mysql-charset": "مجموعه‌ٔ خصوصیات پایگاه اطلاعاتی:",
-       "config-mysql-binary": "دودویی",
-       "config-mysql-utf8": "UTF-8",
-       "config-mysql-charset-help": "در حالت باینری مدیاویکی متن را به صورت  UTF-8 در پایگاه داده باینری ذخیره می‌کند.\nاین روش بسیار به صرفه‌تر از حالت  UTF-8 برای MySQL هست و به شما اجازهٔ استفاده از همه بازهٔ نویسه‌های یونیکد را می دهد.\n\nدر حالت UTF-8 برنامه MySQL به شما اجازه می‌دهد که کدام نویسه‌ها در داده‌های شما باشند و اجازهٔ تبدیل و حضور آنها را به صورت مطلوبی می‌دهد ولی به شما اجازهٔ ذخیرهٔ نویسه‌های بالای [https://en.wikipedia.org/wiki/Mapping_of_Unicode_character_planes نقشه ابتدائی چندزبانی] را می‌دهد.",
        "config-mssql-auth": "نوع تأیید:",
        "config-mssql-install-auth": "نوع تأییدی را که برای اتصال به پایگاه اطلاعاتی حین فرآیند نصب مورد استفاده قرار گیرد را انتخاب کنید.\nاگر \"{{int:config-mssql-windowsauth}}\" را انتخاب می‌کنید، اعتبارات هرآنچه کاربر وب سرور به عنوان آن  مورد استفاده قرار می‌دهد مورد استفاده قرار خواهد گرفت.",
        "config-mssql-web-auth": "نوع تأییدی را که کارساز وب به‌وسیلهٔ آن برای کارهای معمولی به پایگاه اطلاعاتی متصل خواهد شد را انتخاب کنید.\nاگر «{{int:config-mssql-windowsauth}}» را انتخاب می‌کنید، اعتبارات هرآنچه کاربر وب سرور به عنوان آن  مورد استفاده قرار می‌دهد مورد استفاده قرار خواهد گرفت.",
        "config-license-help": "بسیاری از وبگاه‌ها ویرایش‌های ها را با  [https://freedomdefined.org/Definition اجازه‌نامهٔ آزاد] منتشر می‌کنند.\nاین کار به داشتن حس مالکیت جمعی کمک می‌کند و ویرایش‌های طولانی مدت را اشاعه می‌دهد.\nاین برای ویکی‌های خصوصی یا سازمانی الزامی نیست.\n\nاگر شما می‌خواهید از متون ویکی‌پدیا استفاده کنید، یا اینکه به ویکی‌پدیا اجازه دهید از متون شما استفاده کند باید متون خود را با <strong>{{int:config-license-cc-by-sa}}</strong> منتشر کنید.\n\nویکی‌پدیا در گذشته از اجازه‌نامهٔ داده‌های آزاد گنو استفاده می‌کرد.\nاین اجازه‌نامه مورد قبول است، ولی فهم آن آسان نیست.\nهمچنین استفادهٔ دوباره از متون تحت اجازه‌نامهٔ داده‌های آزاد گنو به سختی انجام می‌گیرد.",
        "config-email-settings": "تنظیمات ایمیل",
        "config-enable-email": "فعال‌سازی ایمیل خروجی",
-       "config-enable-email-help": "اگر می‌خواهید ارسال ایمیل کار کند، [Config-dbsupport-oracle/manual/en/mail.configuration.php PHP's mail settings] نیازمند پیکربندی صحیح است.\nاگر هیچ قابلیت ایمیلی نمی‌خواهید، می‌توانید آنها را اینجا غیر‌فعال کنید.",
+       "config-enable-email-help": "اگر می‌خواهید ارسال ایمیل کار کند، [https://secure.php.net/manual/en/mail.configuration.php PHP's mail settings] نیازمند پیکربندی صحیح است.\nاگر هیچ قابلیت ایمیلی نمی‌خواهید، می‌توانید آنها را اینجا غیر‌فعال کنید.",
        "config-email-user": "فعال کردن ایمیل کاربر به کاربر",
        "config-email-user-help": "به همهٔ کاربرانی که ارسال ایمیل را در ترجیحات خود فعال کرده‌اند، اجازه داده خواهد شد که به یکدیگر ایمیل ارسال کنند.",
        "config-email-usertalk": "فعال کردن اطلاع‌رسانی صفحهٔ بحث کاربر",
        "config-install-interwiki-exists": "'''هشدار:''' به نظر می‌رسد جدول ویکی داخلی در حال حاضر دارای مقداری اطلاعات است.\nنادیده گرفتن فهرست پیش‌فرض.",
        "config-install-stats": "شروع آمار",
        "config-install-keys": "تولید کلیدهای مخفی",
-       "config-insecure-keys": "'''هشدار:''' {{PLURAL:$2|کلید امن|کلیدهای امن}} ($1) در طی نصب  کاملاً ایمن {{PLURAL:$2|نیست|نیستند}}. تغییر دستی {{PLURAL:$2|آن|آنها}} را در نظر بگیرید.",
        "config-install-updates": "جلوگیری از به روز رسانی‌های غیر ضروری در حال اجرا",
        "config-install-updates-failed": "<strong>خطا:</strong> قراردادن کلیدهای به روز رسانی به داخل جداول با خطای روبرو مواجه شد: $1",
        "config-install-sysop": "ایجاد حساب کاربری مدیر",
        "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-skins-screenshots": "$1 (تصاویر: $2)",
+       "config-extensions-requires": "$1 (نیازمند $2)",
        "config-screenshot": "تصویر",
        "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 2a9bc33..cec1647 100644 (file)
@@ -68,7 +68,7 @@
        "config-env-php": "PHP $1 on asennettu.",
        "config-env-hhvm": "HHVM $1 on asennettu.",
        "config-unicode-using-intl": "Käyttää [https://pecl.php.net/intl intl PECL-laajennusta] Unicode-normalisaatioon.",
-       "config-no-db": "Sopivaa tietokanta-ajuria ei löytynyt! Sinun täytyy asentaa tietokanta-ajuri PHP:lle.\n{{PLURAL:$2|Seuraava tietokantatyyppi on tuettu|Seuraavat tietokantatyypit ovat tuettuja}}: $1.\n\nJos koostit PHP:n itse, määritä se uudelleen tietokanta-asiakkaan ollessa käytössä, esimerkiksi koodilla <code>./configure --with-mysqli</code>.\nJos asensit PHP:n Debian- tai Ubuntu-pakkauksesta, sinun on myös asennettava esimerkiksi <code>php5-mysql</code>-pakkaus.",
+       "config-no-db": "Sopivaa tietokanta-ajuria ei löytynyt! Sinun täytyy asentaa tietokanta-ajuri PHP:lle.\n{{PLURAL:$2|Seuraava tietokantatyyppi on tuettu|Seuraavat tietokantatyypit ovat tuettuja}}: $1.\n\nJos koostit PHP:n itse, määritä se uudelleen tietokanta-asiakkaan ollessa käytössä, esimerkiksi koodilla <code>./configure --with-mysqli</code>.\nJos asensit PHP:n Debian- tai Ubuntu-pakkauksesta, sinun on myös asennettava esimerkiksi <code>php-mysql</code>-pakkaus.",
        "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-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki tukee seuraavia tietokantajärjestelmiä:\n\n$1\n\nJos et näe tietokantajärjestelmää, jota yrität käyttää, listattuna alhaalla, seuraa yläpuolella olevia ohjeita tuen aktivoimiseksi.",
        "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] on MediaWikin ensisijainen kohde ja se on myös parhaiten tuettu. MediaWiki voi myös käyttää [{{int:version-db-mariadb-url}} MariaDB]- sekä [{{int:version-db-percona-url}} Percona Server]-järjestelmiä, jotka ovat MySQL-yhteensopivia. ([https://secure.php.net/manual/en/mysqli.installation.php Miten käännetään PHP MySQL-tuella])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] on suosittu avoimen lähdekoodin tietokantajärjestelmä vaihtoehtona MySQL:lle. ([Config-dbsupport-oracle/manual/en/pgsql.installation.php Kuinka käännetään PHP PostgreSQL-tuella])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] on suosittu avoimen lähdekoodin tietokantajärjestelmä vaihtoehtona MySQL:lle. ([https://secure.php.net/manual/en/pgsql.installation.php Kuinka käännetään PHP PostgreSQL-tuella])",
        "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] on kevyt tietokantajärjestelmä, jota tuetaan hyvin. ([http://www.php.net/manual/en/pdo.installation.php Miten käännetään PHP SQLite-tuella], käyttää PDO:ta)",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] on kaupallinen yritystietokanta. ([http://www.php.net/manual/en/oci8.installation.php Kuinka käännetään PHP OCI8-tuella])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] on kaupallinen yritystietokanta Windowsille. ([Config-dbsupport-oracle/manual/en/sqlsrv.installation.php Miten käännetään PHP SQLSRV-tuella])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] on kaupallinen yritystietokanta Windowsille. ([https://secure.php.net/manual/en/sqlsrv.installation.php Miten käännetään PHP SQLSRV-tuella])",
        "config-header-mysql": "MySQL-asetukset",
        "config-header-postgres": "PostgreSQL-asetukset",
        "config-header-sqlite": "SQLite-asetukset",
        "config-mysql-engine": "Tallennusmoottori",
        "config-mysql-innodb": "InnoDB",
        "config-mysql-myisam": "MyISAM",
-       "config-mysql-charset": "Tietokannan merkistökoodaus:",
-       "config-mysql-binary": "Binääri",
-       "config-mysql-utf8": "UTF-8",
        "config-mssql-auth": "Varmennuksen tyyppi:",
        "config-mssql-install-auth": "Valitse varmennuksen tyyppi, jota käytetään yhdistäessä tietokantaan asennuksen aikana.\nJos valitset \"{{int:config-mssql-windowsauth}}\", käytetään verkkopalvelimen käyttäjän kirjautumistietoja.",
        "config-mssql-web-auth": "Valitse varmennuksen tyyppi, jota verkkopalvelin käyttää yhdistäessään tietokantapalvelimeen wikin tavallisen toiminnan aikana.\nJos valitset \"{{int:config-mssql-windowsauth}}\", käytetään verkkopalvelimen käyttäjän kirjautumistietoja.",
        "config-install-interwiki-exists": "<strong>Varoitus:</strong> interwiki-taulussa on jo tietueita, ohitetaan oletuslista.",
        "config-install-stats": "Alustetaan tilastoja",
        "config-install-keys": "Muodostetaan salausavaimia",
-       "config-insecure-keys": "<strong>Varoitus:</strong> Asennuksen aikana {{PLURAL:$2|luotu turva-avain|luodut turva-avaimet}} ($1) {{PLURAL:$2|ei|eivät}} ole täysin {{PLURAL:$2|turvallinen|turvallisia}}. Harkitse {{PLURAL:$2|sen|niiden}} muuttamista manuaalisesti.",
        "config-install-updates": "Estä tarpeettomien päivitysten asennus",
        "config-install-updates-failed": "<strong>Virhe:</strong> Päivitysavainten lisääminen taulukoihin epäonnistui seuraavalla virheellä: $1",
        "config-install-sysop": "Luodaan ylläpitäjän tiliä",
index 39a1868..d8693d7 100644 (file)
@@ -78,7 +78,7 @@
        "config-unicode-using-intl": "Utilisation de [https://pecl.php.net/intl l’extension PECL intl] pour la normalisation Unicode.",
        "config-unicode-pure-php-warning": "<strong>Attention :</strong> L’[https://pecl.php.net/intl extension PECL intl] n’est pas disponible pour la normalisation d’Unicode, retour à la version lente implémentée en PHP seulement.\nSi votre site web sera très fréquenté, vous devriez lire ceci : [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations ''Unicode normalization''] (en anglais).",
        "config-unicode-update-warning": "<strong>Attention :</strong> la version installée du normalisateur Unicode utilise une ancienne version de la bibliothèque logicielle du [http://site.icu-project.org/ ''Projet ICU''].\nVous devriez faire une [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations mise à jour] si vous êtes concerné par l’usage d’Unicode.",
-       "config-no-db": "Impossible de trouver un pilote de base de données approprié ! Vous devez installer un pilote de base de données pour PHP. {{PLURAL:$2|Le type suivant|Les types suivants}} de bases de données {{PLURAL:$2|est reconnu|sont reconnus}} : $1.\n\nSi vous avez compilé PHP vous-même, reconfigurez-le avec un client de base de données actif, par exemple en utilisant <code>./configure --with-mysqli</code>. Si vous avez installé PHP depuis un paquet Debian ou Ubuntu, alors vous devrez aussi installer, par exemple, le paquet <code>php5-mysql</code>.",
+       "config-no-db": "Impossible de trouver un pilote de base de données approprié ! Vous devez installer un pilote de base de données pour PHP. {{PLURAL:$2|Le type suivant|Les types suivants}} de bases de données {{PLURAL:$2|est reconnu|sont reconnus}} : $1.\n\nSi vous avez compilé PHP vous-même, reconfigurez-le avec un client de base de données activé, par exemple en utilisant <code>./configure --with-mysqli</code>.  \nSi vous avez installé PHP depuis un paquet Debian ou Ubuntu, alors vous devrez aussi installer, par exemple, le paquet <code>php-mysql</code>.",
        "config-outdated-sqlite": "<strong>Attention :</strong> vous avez SQLite $1, qui est inférieur à la version minimale requise $2. SQLite sera indisponible.",
        "config-no-fts3": "<strong>Attention :</strong> SQLite est compilé sans le [//sqlite.org/fts3.html module FTS3] ; les fonctions de recherche ne seront pas disponibles sur ce moteur.",
        "config-pcre-old": "<strong>Erreur fatale :</strong> PCRE $1 ou ultérieur est nécessaire.\nVotre binaire PHP est lié avec PCRE $2.\n[https://www.mediawiki.org/wiki/Manual:Errors_and_symptoms/Plus d’information sur PCRE].",
        "config-sqlite-dir-help": "SQLite stocke toutes les données dans un fichier unique.\n\nLe répertoire que vous fournissez doit être accessible en écriture par le serveur lors de l'installation.\n\nIl '''ne faut pas''' qu'il soit accessible via le web, c'est pourquoi il n'est pas à l'endroit où sont vos fichiers PHP.\n\nL'installateur écrira un fichier <code>.htaccess</code> en même temps, mais s'il y a échec, quelqu'un peut accéder à votre base de données.\nCela comprend les données des utilisateurs (adresses de courriel, mots de passe hachés) ainsi que des révisions supprimées et d'autres données confidentielles du wiki.\n\nEnvisagez de placer la base de données ailleurs, par exemple dans <code>/var/lib/mediawiki/yourwiki</code>.",
        "config-oracle-def-ts": "Espace de stockage (''tablespace'') par défaut :",
        "config-oracle-temp-ts": "Espace de stockage (''tablespace'') temporaire :",
-       "config-type-mysql": "MySQL (ou compatible)",
+       "config-type-mysql": "MariaDB, MySQL , ou compatible",
        "config-type-postgres": "PostgreSQL",
        "config-type-sqlite": "SQLite",
        "config-type-oracle": "Oracle",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki prend en charge ces systèmes de bases de données :\n\n$1\n\nSi vous ne voyez pas le système de base de données que vous essayez d’utiliser ci-dessous, alors suivez les instructions ci-dessus (voir liens) pour activer la prise en charge.",
-       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] est le premier choix pour MediaWiki et est le mieux pris en charge. MediaWiki fonctionne aussi avec [{{int:version-db-mariadb-url}} MariaDB] et [{{int:version-db-percona-url}} Percona Server], qui sont compatibles avec MySQL. ([https://secure.php.net/manual/en/mysqli.installation.php Comment compiler PHP avec la prise en charge de MySQL])",
+       "config-dbsupport-mysql": "* [{{int:version-db-mariadb-url}} MariaDB] est le premier choix pour MediaWiki et est le mieux pris en charge. MediaWiki fonctionne aussi avec [{{int:version-db-mysql-url}} MySQL] et [{{int:version-db-percona-url}} Percona Server], qui sont compatibles avec MariaDB. ([https://secure.php.net/manual/en/mysqli.installation.php Comment compiler PHP avec la prise en charge de MySQL])",
        "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] est un système de base de données populaire en ''source ouverte'' qui peut être une alternative à MySQL ([https://secure.php.net/manual/en/pgsql.installation.php Comment compiler PHP avec la prise en charge de PostgreSQL]).",
        "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] est un système de base de données léger bien pris en charge ([https://secure.php.net/manual/en/pdo.installation.php Comment compiler PHP avec la prise en charge de SQLite], en utilisant PDO).",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] est un système commercial de gestion de base de données d’entreprise. ([https://secure.php.net/manual/en/oci8.installation.php Comment compiler PHP avec la prise en charge d’OCI8])",
        "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] est une base de données commerciale d’entreprise pour Windows. ([https://secure.php.net/manual/en/sqlsrv.installation.php Comment compiler PHP avec la prise en charge de SQLSRV])",
-       "config-header-mysql": "Paramètres de MySQL",
+       "config-header-mysql": "Paramètres de MariaDB/MySQL",
        "config-header-postgres": "Paramètres de PostgreSQL",
        "config-header-sqlite": "Paramètres de SQLite",
        "config-header-oracle": "Paramètres d’Oracle",
        "config-db-web-create": "Créez le compte s'il n'existe pas déjà",
        "config-db-web-no-create-privs": "Le compte que vous avez spécifié pour l'installation n'a pas de privilèges suffisants pour créer un compte.\nLe compte que vous spécifiez ici doit déjà exister.",
        "config-mysql-engine": "Moteur de stockage :",
-       "config-mysql-innodb": "InnoDB",
+       "config-mysql-innodb": "InnoDB (recommandé)",
        "config-mysql-myisam": "MyISAM",
        "config-mysql-myisam-dep": "<strong> Avertissement </strong>: vous avez sélectionné MyISAM comme moteur de stockage pour MySQL, ce qui n’est pas recommandé pour une utilisation avec MediaWiki, parce que :\n * il prend à peine en charge la simultanéité en raison de verrouillage de table\n * il est plus sujet à la corruption que les autres moteurs\n * le code de base MediaWiki ne gère pas toujours MyISAM comme il se doit\n\nSi votre installation MySQL prenden charge InnoDB, il est fortement recommandé que vous le choisissiez plutôt. \nSi votre installation MySQL ne prend pas en charge les tables InnoDB, il est peut-être temps de faire une mise à niveau.",
        "config-mysql-only-myisam-dep": "<strong>Attention :</strong> MyISAM est le seul moteur de stockage disponible pour MySQL sur cette machine, et cela n’est pas recommandé pour une utilisation avec MédiaWiki, car :\n* il prend très peu en charge les accès concurrents à cause du verrouillage des tables\n* il est plus sujet à corruption que les autres moteurs\n* le code de base de MédiaWiki ne gère pas toujours MyISAM comme il faudrait\n\nVotre installation MySQL ne prend pas en charge InnoDB ; il est peut-être temps de la mettre à jour.",
        "config-mysql-engine-help": "<strong>InnoDB</strong> est presque toujours la meilleure option, car il prend bien en charge les accès concurrents.\n\n<strong>MyISAM</strong> peut être plus rapide dans les installations monoposte ou en lecture seule.\nLes bases de données MyISAM ont tendance à se corrompre plus souvent que les bases d’InnoDB.",
-       "config-mysql-charset": "Jeu de caractères de la base de données :",
-       "config-mysql-binary": "Binaire",
-       "config-mysql-utf8": "UTF-8",
-       "config-mysql-charset-help": "En <strong>mode binaire</strong>, MediaWiki stocke le texte au format UTF-8 dans la base de données dans des champs binaires.\nC'est plus efficace que le ''UTF-8 mode'' de MySQL, et vous permet d'utiliser toute la gamme des caractères Unicode.\n\nEn <strong>mode UTF-8</strong>, MySQL reconnaîtra le jeu de caractères dans lequel sont vos données et pourra les présenter et les convertir de manière appropriée, mais il ne vous laissera pas stocker les caractères au-dessus du [https://en.wikipedia.org/wiki/Mapping_of_Unicode_character_planes plan multilingue de base] (en anglais).",
        "config-mssql-auth": "Type d’authentification :",
        "config-mssql-install-auth": "Sélectionner le type d’authentification qui sera utilisé pour se connecter à la base de données pendant le processus d’installation.\nSi vous sélectionnez « {{int:config-mssql-windowsauth}} », les informations d’identification de l’utilisateur faisant tourner le serveur seront utilisées.",
        "config-mssql-web-auth": "Sélectionner le type d’authentification que le serveur web utilisera pour se connecter au serveur de base de données lors des opérations habituelles du wiki.\nSi vous sélectionnez « {{int:config-mssql-windowsauth}} », les informations d’identification de l’utilisateur sous lequel tourne le serveur web seront utilisées.",
        "config-install-interwiki-exists": "'''Attention:''' La table des interwikis semble déjà contenir des entrées.\nLa liste par défaut ne sera pas inscrite.",
        "config-install-stats": "Initialisation des statistiques",
        "config-install-keys": "Génération de la clé secrète",
-       "config-insecure-keys": "'''Avertissement''' : {{PLURAL:$2|Une clé de sécurité générée ($1) pendant l'installation n'est pas complètement sécuritaire. Envisagez de la modifier manuellement.|Des clés de sécurité générées ($1) pendant l'installation ne sont pas complètement sécuritaires. Envisagez de les modifier manuellement.}}",
        "config-install-updates": "Empêcher l’exécution des mises à jour inutiles",
        "config-install-updates-failed": "<strong>Erreur :</strong> L’insertion de clés modifiées dans les tables a échoué avec l’erreur suivante : $1",
        "config-install-sysop": "Création du compte administrateur",
index 5eac7d3..c0e86f7 100644 (file)
@@ -50,8 +50,6 @@
        "config-sqlite-name-help": "Choisir un nom qui identifie ton wiki.\nFait user pas ni d'espaces ni des traits d'union\nIl va user pour fichier de données SQLite.",
        "config-mysql-innodb": "InnoDB",
        "config-mysql-myisam": "MyISAM",
-       "config-mysql-binary": "Binaire",
-       "config-mysql-utf8": "UTF-8",
        "config-site-name": "Nom du wiki:",
        "config-ns-generic": "Projet",
        "config-ns-other-default": "MonWiki",
index 6f6210e..fa84d5f 100644 (file)
@@ -68,9 +68,6 @@
        "config-mysql-engine": "Motor de stocâjo :",
        "config-mysql-innodb": "InnoDB",
        "config-mysql-myisam": "MyISAM",
-       "config-mysql-charset": "Juè de caractèros de la bâsa de balyês :",
-       "config-mysql-binary": "Binèro",
-       "config-mysql-utf8": "UTF-8",
        "config-site-name": "Nom du vouiqui :",
        "config-site-name-blank": "Buchiéd un nom de seto.",
        "config-project-namespace": "Èspâço de noms du projèt :",
index f30914b..67c1543 100644 (file)
@@ -56,7 +56,7 @@
        "config-unicode-using-intl": "Usando a [https://pecl.php.net/intl extensión intl PECL] para a normalización Unicode.",
        "config-unicode-pure-php-warning": "<strong>Atención:</strong> A [https://pecl.php.net/intl extensión intl PECL] non está dispoñible para manexar a normalización Unicode; volvendo á execución lenta de PHP puro.\nSe o seu sitio posúe un alto tráfico de visitantes, debería ler un chisco sobre a [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations normalización Unicode].",
        "config-unicode-update-warning": "<strong>Atención:</strong> A versión instalada da envoltura de normalización Unicode emprega unha versión vella da biblioteca [http://site.icu-project.org/ do proxecto ICU].\nDebería [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations actualizar] se o uso de Unicode é importante para vostede.",
-       "config-no-db": "Non se puido atopar un controlador axeitado para a base de datos! Necesita instalar un controlador de base de datos para PHP.\n{{PLURAL:$2|Acéptase o seguinte tipo|Acéptanse os seguintes tipos}} de base de datos: $1.\n\nSe compilou o PHP vostede mesmo, reconfigúreo activando un cliente de base de datos, por exemplo, usando <code>./configure --with-mysqli</code>.\nSe instalou o PHP desde un paquete Debian ou Ubuntu, entón tamén necesita instalar, por exemplo, o módulo <code>php5-mysql</code>.",
+       "config-no-db": "Non se puido atopar un controlador axeitado para a base de datos! Necesita instalar un controlador de base de datos para PHP.\n{{PLURAL:$2|Acéptase o seguinte tipo|Acéptanse os seguintes tipos}} de base de datos: $1.\n\nSe compilou o PHP vostede mesmo, reconfigúreo activando un cliente de base de datos, por exemplo, usando <code>./configure --with-mysqli</code>.\nSe instalou o PHP desde un paquete Debian ou Ubuntu, entón tamén necesita instalar, por exemplo, o módulo <code>php-mysql</code>.",
        "config-outdated-sqlite": "<strong>Atención:</strong> Ten o SQLite $1, que é inferior á versión mínima necesaria: $2. O SQLite non estará dispoñible.",
        "config-no-fts3": "<strong>Atención:</strong> O SQLite está compilado sen o [//sqlite.org/fts3.html módulo FTS3]; as características de procura non estarán dispoñibles nesta instalación.",
        "config-pcre-old": "<strong>Erro fatal:</strong> Necesítase PCRE $1 ou posterior.\nO seu PHP binario está ligado con PCRE $2.\n[https://www.mediawiki.org/wiki/Manual:Errors_and_symptoms/PCRE Máis información].",
        "config-sqlite-dir-help": "SQLite recolle todos os datos nun ficheiro único.\n\nO servidor web debe ter permisos sobre o directorio para que poida escribir nel durante a instalación.\n\nAdemais, o servidor <strong>non</strong> debe ser accesible a través da web, motivo polo que non está no mesmo lugar ca os ficheiros PHP.\n\nAsemade, o programa de instalación escribirá un ficheiro <code>.htaccess</code>, pero se erra alguén pode obter acceso á súa base de datos.\nIsto inclúe datos de usuario (enderezos de correo electrónico, contrasinais codificados), así como revisións borradas e outros datos restrinxidos no wiki.\n\nConsidere poñer a base de datos nun só lugar, por exemplo en <code>/var/lib/mediawiki/oseuwiki</code>.",
        "config-oracle-def-ts": "Espazo de táboas por defecto:",
        "config-oracle-temp-ts": "Espazo de táboas temporal:",
-       "config-type-mysql": "MySQL (ou compatible)",
+       "config-type-mysql": "MariaDB, MySQL ou compatíbel",
        "config-type-postgres": "PostgreSQL",
        "config-type-sqlite": "SQLite",
        "config-type-oracle": "Oracle",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki soporta os seguintes sistemas de bases de datos:\n\n$1\n\nSe non ve listado a continuación o sistema de base de datos que intenta usar, siga as instrucións ligadas enriba para activar o soporte.",
-       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] é o obxectivo principal para MediaWiki e está mellor soportado. MediaWiki tamén funciona con [{{int:version-db-mariadb-url}} MariaDB] e [{{int:version-db-percona-url}} Percona Server], que son compatibles con MySQL. ([https://secure.php.net/manual/en/mysqli.installation.php  Como compilar PHP con compatibilidade MySQL])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] é un sistema de base de datos popular e de código aberto como alternativa a MySQL. ([Config-dbsupport-oracle/manual/en/pgsql.installation.php Como compilar PHP con compatibilidade PostgreSQL])",
-       "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] é un sistema de base de datos lixeiro moi ben soportado. ([http://www.php.net/manual/en/pdo.installation.php Como compilar o PHP con soporte SQLite], emprega PDO)",
-       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] é un sistema comercial de xestión de base de datos de nivel empresarial. ([http://www.php.net/manual/en/oci8.installation.php Como compilar o PHP con compatibilidade OCI8])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] é un sistema comercial de xestión de base de datos de nivel empresarial para Windows. ([Config-dbsupport-oracle/manual/en/sqlsrv.installation.php Como compilar o PHP con compatibilidade SQLSRV])",
-       "config-header-mysql": "Configuración do MySQL",
+       "config-dbsupport-mysql": "* [{{int:version-db-mariadb-url}} MariaDB] é o obxectivo principal para MediaWiki e é o que mellor soportado está. MediaWiki tamén funciona con [{{int:version-db-mysql-url}} MySQL] e [{{int:version-db-percona-url}} Percona Server], que son compatibles con MariaDB. ([https://secure.php.net/manual/en/mysqli.installation.php Como compilar PHP con compatibilidade MySQL])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] é un sistema de base de datos popular e de código aberto como alternativa a MySQL. ([https://secure.php.net/manual/en/pgsql.installation.php Como compilar PHP con compatibilidade PostgreSQL])",
+       "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] é un sistema de base de datos lixeiro moi ben soportado. ([https://secure.php.net/manual/en/pdo.installation.php Como compilar o PHP con soporte SQLite], emprega PDO)",
+       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] é un sistema comercial de xestión de base de datos a nivel empresarial. ([https://secure.php.net/manual/en/oci8.installation.php Como compilar PHP con soporte OCI8])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] é un sistema comercial de xestión de base de datos de nivel empresarial para Windows. ([https://secure.php.net/manual/en/sqlsrv.installation.php Como compilar o PHP con compatibilidade SQLSRV])",
+       "config-header-mysql": "Configuración MariaDB/MySQL",
        "config-header-postgres": "Configuración do PostgreSQL",
        "config-header-sqlite": "Configuración do SQLite",
        "config-header-oracle": "Configuración do Oracle",
        "config-db-web-create": "Crear a conta se aínda non existe",
        "config-db-web-no-create-privs": "A conta que especificou para a instalación non ten os privilexios suficientes para crear unha conta.\nA conta que se especifique aquí xa debe existir.",
        "config-mysql-engine": "Motor de almacenamento:",
-       "config-mysql-innodb": "InnoDB",
+       "config-mysql-innodb": "InnoDB (recomendado)",
        "config-mysql-myisam": "MyISAM",
        "config-mysql-myisam-dep": "<strong>Atención:</strong> Seleccionou MyISAM como o motor de almacenamento para MySQL, unha combinación non recomendada para MediaWiki, porque:\n* practicamente non soporta os accesos simultáneos debido ao bloqueo de táboas\n* é máis propenso a corromperse ca outros motores\n* o código base de MediaWiki non sempre manexa o MyISAM como debera\n\nSe a súa instalación MySQL soporta InnoDB, recoméndase elixilo no canto de MyISAM.\nSe a súa instalación MySQL non soporta InnoDB, quizais sexa boa idea realizar unha actualización.",
        "config-mysql-only-myisam-dep": "<strong>Atención:</strong> MyISAM é o único motor de almacenamento para MySQL nesta máquina, unha combinación non recomendada para MediaWiki, porque:\n* practicamente non soporta os accesos simultáneos debido ao bloqueo de táboas\n* é máis propenso a corromperse ca outros motores\n* o código base de MediaWiki non sempre manexa o MyISAM como debera\n\nA súa instalación MySQL non soporta InnoDB, quizais sexa boa idea realizar unha actualización.",
        "config-mysql-engine-help": "<strong>InnoDB</strong> é case sempre a mellor opción, dado que soporta ben os accesos simultáneos.\n\n<strong>MyISAM</strong> é máis rápido en instalacións de usuario único e de só lectura.\nAs bases de datos MyISAM tenden a se corromper máis a miúdo ca as bases de datos InnoDB.",
-       "config-mysql-charset": "Conxunto de caracteres da base de datos:",
-       "config-mysql-binary": "Binario",
-       "config-mysql-utf8": "UTF-8",
-       "config-mysql-charset-help": "No <strong>modo binario</strong>, MediaWiki almacena texto UTF-8 na base de datos en campos binarios.\nIsto é máis eficaz ca o modo UTF-8 de MySQL e permítelle usar o rango completo de caracteres Unicode.\n\nNo <strong>modo UTF-8</strong>, MySQL saberá o xogo de caracteres dos seus datos e pode presentar e converter os datos de maneira axeitada,\npero non lle deixará gardar caracteres por riba do [https://en.wikipedia.org/wiki/Mapping_of_Unicode_character_planes plan multilingüe básico].",
        "config-mssql-auth": "Tipo de autenticación:",
        "config-mssql-install-auth": "Seleccione o tipo de autenticación que se utilizará para conectarse á base de datos durante o proceso de instalación.\nSe selecciona \"{{int:config-mssql-windowsauth}}\", usaranse as credenciais do usuario co que se está a executar o servidor web.",
        "config-mssql-web-auth": "Seleccione o tipo de autenticación que utilizará o servidor web para conectarse ao servidor da base de datos durante o funcionamiento normal do wiki.\nSe selecciona \"{{int:config-mssql-windowsauth}}\", usaranse as credenciais do usuario co que se está a executar o servidor web.",
        "config-license-help": "Moitos wikis públicos liberan todas as súas contribucións baixo unha [https://freedomdefined.org/Definition/Gl licenza libre].\nIsto axuda a crear un sentido de propiedade comunitaria e anima a seguir contribuíndo durante moito tempo.\nXeralmente, non é necesario nos wikis privados ou de empresas.\n\nSe quere poder empregar textos da Wikipedia, así como que a Wikipedia poida aceptar textos copiados do seu wiki, escolla a licenza <strong>{{int:config-license-cc-by-sa}}</strong>.\n\nA licenza de documentación libre de GNU era a licenza anterior da Wikipedia.\nMalia aínda ser unha licenza válida, é difícil de entender.\nTamén é difícil reusar contidos baixo esta licenza.",
        "config-email-settings": "Configuración do correo electrónico",
        "config-enable-email": "Activar os correos electrónicos de saída",
-       "config-enable-email-help": "Se quere que o correo electrónico funcione, cómpre configurar os [Config-dbsupport-oracle/manual/en/mail.configuration.php parámetros PHP] correctamente.\nSe non quere ningunha característica no correo, pode desactivalas aquí.",
+       "config-enable-email-help": "Se quere que o correo electrónico funcione, cómpre configurar os [https://secure.php.net/manual/en/mail.configuration.php parámetros PHP de correo] correctamente.\nSe non quere ningunha característica de correo electrónico, pode desactivalas aquí.",
        "config-email-user": "Activar o intercambio de correos electrónicos entre usuarios",
        "config-email-user-help": "Permitir que todos os usuarios intercambien correos electrónicos, se o teñen activado nas súas preferencias.",
        "config-email-usertalk": "Activar a notificación da páxina de conversa de usuario",
        "config-cache-options": "Configuración da caché de obxectos:",
        "config-cache-help": "A caché de obxectos emprégase para mellorar a velocidade de MediaWiki mediante a memorización de datos usados con frecuencia.\nÉ amplamente recomendable a súa activación nos sitios de tamaño medio e grande; os sitios pequenos obterán tamén beneficios.",
        "config-cache-none": "Sen caché (non se elimina ningunha funcionalidade, pero pode afectar á velocidade en wikis grandes)",
-       "config-cache-accel": "Caché de obxectos do PHP (APC, APCu, XCache ou WinCache)",
+       "config-cache-accel": "Caché de obxectos PHP (APC, APCu ou WinCache)",
        "config-cache-memcached": "Empregar o Memcached (necesita unha instalación e configuración adicional)",
        "config-memcached-servers": "Servidores da memoria caché:",
        "config-memcached-help": "Lista de enderezos IP para Memcached.\nDebe especificarse un por liña, así como o porto a usar. Por exemplo:\n 127.0.0.1:11211\n 192.168.1.25:1234",
        "config-install-interwiki-exists": "<strong>Atención:</strong> Semella que a táboa de interwiki xa contén entradas.\nSaltando a lista por defecto.",
        "config-install-stats": "Iniciando as estatísticas",
        "config-install-keys": "Xerando as claves secretas",
-       "config-insecure-keys": "<strong>Atención:</strong> {{PLURAL:$2|A clave de seguridade|As claves de seguridade}} ($1) {{PLURAL:$2|xerada|xeradas}} durante a instalación non {{PLURAL:$2|é|son}} completamente {{PLURAL:$2|segura|seguras}}. Considere a posibilidade de {{PLURAL:$2|cambiala|cambialas}} manualmente.",
        "config-install-updates": "Evitar executar actualizacións innecesarias",
        "config-install-updates-failed": "<strong>Error:</strong> a inserción de claves de actualización nas táboas fallou co seguinte erro: $1",
        "config-install-sysop": "Creando a conta de usuario de administrador",
        "config-nofile": "Non se puido atopar o ficheiro \"$1\". Se cadra, foi borrado.",
        "config-extension-link": "Sabía que o seu wiki soporta [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Extensions extensións]?\n\nPode explorar as [https://www.mediawiki.org/wiki/Special:MyLanguage/Category:Extensions_by_category extensións por categoría] ou a [https://www.mediawiki.org/wiki/Extension_Matrix matriz de extensións] para ollar a lista completa de extensións.",
        "config-skins-screenshots": "$1 (capturas de pantalla: $2)",
+       "config-extensions-requires": "$1 (require $2)",
        "config-screenshot": "captura de pantalla",
        "mainpagetext": "<strong>Instalouse MediaWiki.</strong>",
        "mainpagedocfooter": "Consulte a [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents guía de usuario] para obter máis información sobre como usar o software wiki.\n\n== Primeiros pasos ==\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Lista das opcións de configuración]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ Preguntas máis frecuentes sobre MediaWiki]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Lista de correo dos lanzamentos de MediaWiki]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Localice MediaWiki á súa lingua]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Aprenda como combater a publicidade na súa wiki]"
index afa7d72..08672c4 100644 (file)
@@ -44,8 +44,6 @@
        "config-db-name": "Inoa hōkeo ʻikepili",
        "config-db-username": "Inoa hōkeo ʻikepili:",
        "config-db-password": "ʻŌlelo hūnā hōkeo ʻikepili",
-       "config-mysql-binary": "Baineli",
-       "config-mysql-utf8": "UTF-8",
        "config-site-name": "Inoa wiki:",
        "config-project-namespace": "Lewainoa papahana:",
        "config-ns-generic": "Papahana",
index ea28b58..6d1b894 100644 (file)
@@ -59,7 +59,7 @@
        "config-unicode-using-intl": "משתמש ב[https://pecl.php.net/intl הרחבת intl PECL] לנרמול יוניקוד.",
        "config-unicode-pure-php-warning": "<strong>אזהרה:</strong> [https://pecl.php.net/intl הרחבת intl PECL] אינה זמינה לטיפול בנרמול יוניקוד. משתמש ביישום PHP טהור ואטי יותר.\nאם זהו אתר בעל תעבורה גבוהה, כדאי לקרוא את המסמך הבא: [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations Unicode normalization].",
        "config-unicode-update-warning": "'''אזהרה''': הגרסה המותקנת של מעטפת נרמול יוניקוד משתמשת בגרסה ישנה של הספרייה של [http://site.icu-project.org/ פרויקט ICU].\nכדאי [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations לעדכן] אם הטיפול ביוניקוד חשוב לך.",
-       "config-no-db": "לא נמצא דרייבר מסד נתונים מתאים. יש להתקין דרייבר מסד נתונים ל־PHP.\n{{PLURAL:$2|נתמך הסוג הבא של מסד נתונים|נתמכים הסוגים הבאים של מסדי נתונים}}: $1.\n\nאם קִמפלת את PHP בעצמך, יש להגדיר אותו מחדש ולהפעיל את לקוח מסד נתונים, למשל באמצעות <code dir=\"ltr\">./configure --with-mysqli</code>.\nאם התקנת את PHP מחבילה של דביאן או של אובונטו, יש להתקין, למשל, גם את המודול <code dir=\"ltr\">php5-mysql</code>.",
+       "config-no-db": "לא נמצא דרייבר מסד נתונים מתאים. יש להתקין דרייבר מסד נתונים ל־PHP.\n{{PLURAL:$2|נתמך הסוג הבא של מסד נתונים|נתמכים הסוגים הבאים של מסדי נתונים}}: $1.\n\nאם קִמפלת את PHP בעצמך, יש להגדיר אותו מחדש ולהפעיל את לקוח מסד נתונים, למשל באמצעות <code dir=\"ltr\">./configure --with-mysqli</code>.\nאם התקנת את PHP מחבילה של דביאן או של אובונטו, יש להתקין, למשל, גם את המודול <code dir=\"ltr\">php-mysql</code>.",
        "config-outdated-sqlite": "'''אזהרה''': במערכת מתוקן SQLite $1. גרסה זו לא נתמכת ולשימוש ב־SQLite נדרשת גרסה $2 לפחות. SQLlite לא יהיה זמין.",
        "config-no-fts3": "'''אזהרה''': SQLite מהודר ללא [//sqlite.org/fts3.html מודול FTS]. יכולות חיפוש לא יהיו זמינות בהתקנה הזאת.",
        "config-pcre-old": "<strong>שגיאה סופנית:</strong> חובה להתקין PCRE מגרסה $1 או גרסה חדשה יותר.\nקובץ הרצת ה־PHP שלך מקושר עם PCRE מגרסה $2.\n[https://www.mediawiki.org/wiki/Manual:Errors_and_symptoms/PCRE מידע נוסף].",
        "config-sqlite-dir-help": "SQLite שומר את כל הנתונים בקובץ אחד.\n\nלשרת הווב צריכה להיות הרשאה לכתוב לתיקייה שמוגדרת כאן.\n\nהיא לא צריכה נגישה לכולם דרך האינטרנט – בגלל זה איננו שמים אותה באותו מקום עם קובצי ה־PHP.\n\nתוכנת ההתקנה תכתוב קובץ <code dir=\"ltr\">.htaccess</code> יחד אִתו, אבל אם זה ייכשל, מישהו יוכל להשיג גישה למסד הנתונים שלכם.\nשם נמצא מידע מפורש של משתמשים (כתובות דוא״ל, ססמאות מגובבות) וגם גרסאות מחוקות של דפים ומידע מוגבל אחר.\n\nכדאי לשקול לשים את מסד הנתונים במקום אחר לגמרי, למשל ב־<code dir=\"ltr\">/var/lib/mediawiki/yourwik</code>.",
        "config-oracle-def-ts": "מרחב טבלאות לפי בררת מחדל (default tablespace):",
        "config-oracle-temp-ts": "מרחב טבלאות זמני (temporary tablespace):",
-       "config-type-mysql": "MySQL (או תואם)",
+       "config-type-mysql": "MariaDB‏, MySQL, או תואם",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "מדיה־ויקי תומכת במערכות מסדי הנתונים הבאות:\n\n$1\n\nאם אינך רואה את מסד הנתונים שלך ברשימה, יש לעקוב אחר ההוראות המקושרות לעיל כדי להפעיל את התמיכה.",
-       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] הוא היעד העיקרי עבור מדיה־ויקי ולו התמיכה הטובה ביותר. מדיה־ויקי עובדת גם עם [{{int:version-db-mariadb-url}} MariaDB] ועם [{{int:version-db-percona-url}} Percona Server], שתואמים ל־MySQL. (ר׳ [https://secure.php.net/manual/en/mysql.installation.php how to compile PHP with MySQL support])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] הוא מסד נתונים נפוץ בקוד פתוח והוא נפוץ בתור חלופה ל־MySQL. (ר׳ [Config-dbsupport-oracle/manual/en/pgsql.installation.php how to compile PHP with PostgreSQL support]).",
-       "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] הוא מסד נתונים קליל עם תמיכה טובה מאוד. (ר׳ [http://www.php.net/manual/en/pdo.installation.php How to compile PHP with SQLite support], משתמש ב־PDO)",
-       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] הוא מסד נתונים עסקי מסחרי. (ר׳ [http://www.php.net/manual/en/oci8.installation.php How to compile PHP with OCI8 support])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] הוא מסד נתונים עסקי מסחרי לחלונות. ([Config-dbsupport-oracle/manual/en/sqlsrv.installation.php How to compile PHP with SQLSRV support])",
-       "config-header-mysql": "הגדרות MySQL",
+       "config-dbsupport-mysql": "* [{{int:version-db-mariadb-url}} MariaDB] הוא היעד העיקרי עבור מדיה־ויקי ולו התמיכה הטובה ביותר. מדיה־ויקי עובדת גם עם [{{int:version-db-mysql-url}} MySQL] ועם [{{int:version-db-percona-url}} Percona Server], שתואמים ל־MariaDB. (ר׳ [https://secure.php.net/manual/en/mysql.installation.php how to compile PHP with MySQL support])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] הוא מסד נתונים נפוץ בקוד פתוח והוא נפוץ בתור חלופה ל־MySQL. (ר׳ [https://secure.php.net/manual/en/pgsql.installation.php how to compile PHP with PostgreSQL support]).",
+       "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] הוא מסד נתונים קליל עם תמיכה טובה מאוד. (ר׳ [https://secure.php.net/manual/en/pdo.installation.php How to compile PHP with SQLite support], משתמש ב־PDO)",
+       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] הוא מסד נתונים עסקי מסחרי. (ר׳ [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] הוא מסד נתונים עסקי מסחרי לחלונות. ([https://secure.php.net/manual/en/sqlsrv.installation.php How to compile PHP with SQLSRV support])",
+       "config-header-mysql": "הגדרות MariaDB/MySQL",
        "config-header-postgres": "הגדרות PostgreSQL",
        "config-header-sqlite": "הגדרות SQLite",
        "config-header-oracle": "הגדרות Oracle",
        "config-db-web-create": "ליצור חשבון אם הוא אינו קיים כבר.",
        "config-db-web-no-create-privs": "לחשבון שהקלדת להתקנה אין מספיק הרשאות ליצירת חשבון.\nהחשבון שאתם מקלידים כאן צריך להיות קיים.",
        "config-mysql-engine": "מנוע האחסון:",
-       "config-mysql-innodb": "InnoDB",
+       "config-mysql-innodb": "InnoDB (מומלץ)",
        "config-mysql-myisam": "MyISAM",
        "config-mysql-myisam-dep": "'''אזהרה''': בחרתם ב־MyISAM בתור מנוע אחסון של MySQL, וזה לא מומלץ מהסיבות הבאות:\n* המנוע הזה בקושי תומך בעיבוד מקבילי בגלל נעילת טבלאות\n* הוא פחות עמיד בפני אובדן מידע ממנועים אחרים\n* הקוד של מדיה־ויקי לא תמיד מטפל ב־MyISAM כפי שצריך\n\nאם התקנת MySQL שלכם תומכת ב־InnoDB, מומלץ מאוד שתבחרו באפשרות הזאת.\nאם התקנת MySQL שלכם אינה תומכת ב־InnoDB, אולי זה הזמן לשקול לשדרג אותה.",
        "config-mysql-only-myisam-dep": "'''אזהרה:''' MyISAM הוא מנוע האחסון היחיד שזמין ל־MySQL במכונה הזאת, וזה לא מומלץ לשימוש עם מדיה־ויקי, כי:\n* הוא כמעט שאינו תומך בחיבורים מרובים בגלל נעילת טבלאות\n* הוא פגיע יותר לקלקול ממנועים אחרים\n* הקוד של מדיה־ויקי לא תמיד מטפל ב־MyISAM כפי שצריך\n\nהתקנת MySQL אינה תומכת ב־InnoDB, ואולי הגיע הזמן לשדרג אותה.",
        "config-mysql-engine-help": "'''InnoDB''' היא כמעט תמיד האפשרות הטובה ביותר, כי במנוע הזה יש תמיכה טובה ביותר בעיבוד מקבילי.\n\n'''MyISAM''' עשוי להיות בהתקנות שמיועדות למשתמש אחד ולהתקנות לקריאה בלבד.\nמסדי נתונים עם MyISAM נוטים להיהרס לעתים קרובות יותר מאשר מסדי נתונים עם InnoDB.",
-       "config-mysql-charset": "קידוד התווים של מסד הנתונים:",
-       "config-mysql-binary": "בינרי",
-       "config-mysql-utf8": "UTF-8",
-       "config-mysql-charset-help": "ב'''מצב בינרי''' (binary mode) מדיה־ויקי שומרת טקסט UTF-8 במסד הנתונים בשדות בינריים.\nזה יעיל יותר ממצב UTF-8 של MySQL ומאפשר לכם להשתמש בכל הטווח של תווי יוניקוד.\n\nב'''מצב UTF-8'''&rlm; (UTF-8 mode)&rlm; MySQL יֵדַע מה קידוד התווים (character set) של הטקסט שלכם ויציג וימיר אותו בהתאם, אבל לא יאפשר לכם לשמור תווים שאינם נמצאים בטווח הרב־לשוני הבסיסי ([https://en.wikipedia.org/wiki/Mapping_of_Unicode_character_planes Basic Multilingual Plane]).",
        "config-mssql-auth": "סוג אימות:",
        "config-mssql-install-auth": "נא לבחור את סוג האימות שישמש להתחברות למסד הנתונים בזמן תהליך ההתקנה. בחירה ב־\"{{int:config-mssql-windowsauth}}\" תשתמש בהרשאות של החשבון שמריץ את השרת הנוכחי.",
        "config-mssql-web-auth": "נא לבחור את סוג האימות שישמש את השרת להתחברות למסד הנתונים בזמן הריצה הרגילה של הוויקי.\nבחירה ב־\"{{int:config-mssql-windowsauth}}\" תשתמש בהרשאות של החשבון שמריץ את השרת הנוכחי.",
        "config-license-help": "אתרי ויקי ציבוריים רבים מפרסמים את כל התרומות [https://freedomdefined.org/Definition ברישיון חופשי].\nזה עוזר ליצור תחושה של בעלות קהילתית ומעודד תרומה לאורך זמן.\nזה בדרך כלל לא נחוץ לאתר ויקי פרטי או אתר של חברה מסחרית.\n\nאם האפשרות להשתמש בטקסט מוויקיפדיה והאפשרות שוויקיפדיה תוכל תקבל עותקים של טקסטים מהוויקי שלך חשובות לך, כדאי לבחור ב<strong>{{int:config-license-cc-by-sa}}</strong>.\n\nויקיפדיה השתמשה בעבר ברישיון החופשי למסמכים של גנו (GNU FDL או GFDL).\nהוא עדיין רישיון תקין, אבל קשה להבנה.\nכמו־כן, קשה לעשות שימוש חוזר ביצירות שפורסמו לפי GFDL.",
        "config-email-settings": "הגדרות דוא״ל",
        "config-enable-email": "להפעיל דוא״ל יוצא",
-       "config-enable-email-help": "אם אתם רוצים שדוא״ל יעבוד, [Config-dbsupport-oracle/manual/en/mail.configuration.php אפשרויות הדוא״ל של PHP] צריכות להיות מוגדרות נכון.\nאם אינכם רוצים להפעיל שום אפשרויות דוא״ל, כבו אותן כאן ועכשיו.",
+       "config-enable-email-help": "אם אתם רוצים שדוא״ל יעבוד, [https://secure.php.net/manual/en/mail.configuration.php אפשרויות הדוא״ל של PHP] צריכות להיות מוגדרות נכון.\nאם אינכם רוצים להפעיל שום אפשרויות דוא״ל, כבו אותן כאן ועכשיו.",
        "config-email-user": "להפעיל שליחת דוא״ל ממשתמש למשתמש",
        "config-email-user-help": "לאפשר לכל המשתמשים לשלוח אחד לשני דוא״ל אם הם הפעילו את זה בהעדפות שלהם.",
        "config-email-usertalk": "להפעיל הודעות על דף שיחת משתמש",
        "config-install-interwiki-exists": "'''אזהרה:''' נראה שבטבלת הבינוויקי כבר יש רשומות.\nמדלג על הרשומה ההתחלתית.",
        "config-install-stats": "אתחול סטטיסטיקות",
        "config-install-keys": "יצירת מפתחות סודיים",
-       "config-insecure-keys": "'''אזהרה''': {{PLURAL:$2|מפתח|מפתחות}} אבטחה ($1) {{PLURAL:$2|שנוצר|שנוצרו}} במהלך ההתקנה {{PLURAL:$2|אינו בטוח|אינם בטוחים}} מספיק. מומלץ לשקול לשנות {{PLURAL:$2|אותו|אותם}} ידנית.",
        "config-install-updates": "למנוע הרצת עדכונים מיותרים",
        "config-install-updates-failed": "<strong>שגיאה:</strong> הוספת מפתחות עדכון לטבלאות נכשל עם השגיאה הבאה: $1",
        "config-install-sysop": "יצירת חשבון מפעיל",
index 992ba29..ca3d1df 100644 (file)
@@ -65,8 +65,6 @@
        "config-regenerate": "LocalSettings.php फिर से निर्मित करें →",
        "config-db-web-account": "वेब पहुँच हेतु डेटाबेस खाता",
        "config-mysql-innodb": "इनोडीबी",
-       "config-mysql-binary": "बाइनरी",
-       "config-mysql-utf8": "UTF-8",
        "config-mssql-auth": "प्रमाणन प्रकार:",
        "config-mssql-sqlauth": "SQL सर्वर प्रमाणन",
        "config-site-name": "विकि का नाम:",
index 39c5353..b358c4d 100644 (file)
@@ -50,7 +50,7 @@
        "config-unicode-using-intl": "Zur  Unicode-Normalisierung weard die [https://pecl.php.net/intl PECL-Erweiterung intl] ingesetzt.",
        "config-unicode-pure-php-warning": "'''Warnung:''' Die [https://pecl.php.net/intl PECL-Erweiterung intl] ist für die Unicode-Normalisierung net verfüchbar, so dass stattdessen die langsame pure-PHP-Implementierung genutzt weard.\nSofern en Webseit mit grosser Benutzeranzoohl betrieb weard, sollte weitre Informatione uff der Webseite [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations Unicode-Normalisierung (en)] geles sin.",
        "config-unicode-update-warning": "'''Warnung:''' Die installierte Version von der Unicode-Normalisierungswrappers nutzt en ältre Version von der [http://site.icu-project.org/ ICU-Projekts] sein Bibliothek.\nDie sollte [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations aktualisiert] sin, sofern uff die Verwennung von Unicode Wert geleht weard.",
-       "config-no-db": "Es konnt ken adäquater Datenbanktreiwer gefund sin. Es muss doher en Datenbanktreiwer für PHP installiert sin.\nDie folchende Datebanksysteme werre unnerstützt: $1\n\nWenn du PHP sellebst kompiliert host, konfigurier es erneit mit en aktiviert Datebankclient, zum Beispiel dorrich Verwennung von <code>./configure --with-mysqli</code>.\nWenn du PHP von en Debian- orrer Ubuntu-Paket installiert host, dann musst du ooch beispielsweis das <code>php5-mysql</code>-Paket installiere.",
+       "config-no-db": "Es konnt ken adäquater Datenbanktreiwer gefund sin. Es muss doher en Datenbanktreiwer für PHP installiert sin.\nDie folchende Datebanksysteme werre unnerstützt: $1\n\nWenn du PHP sellebst kompiliert host, konfigurier es erneit mit en aktiviert Datebankclient, zum Beispiel dorrich Verwennung von <code>./configure --with-mysqli</code>.\nWenn du PHP von en Debian- orrer Ubuntu-Paket installiert host, dann musst du ooch beispielsweis das <code>php-mysql</code>-Paket installiere.",
        "config-outdated-sqlite": "'''Warnung:''' SQLite $1 ist installiert. Allerdings benöticht MediaWiki SQLite $2 orrer höcher. SQLite weard doher net verfüchbar sin.",
        "config-no-fts3": "'''Warnung:''' SQLite woard ohne das [//sqlite.org/fts3.html FTS3-Modul] kompiliert, so dass ken Suchfunktione für das Datenbanksystem zur Verfüchung stehn werre.",
        "config-pcre-old": "<strong>Fataler Fehler:</strong> PCRE $1 orrer neier ist notwendich!\nDie vorhandne PHP-Binärdatei ist mit PCRE $2 verknüpft.\n[https://www.mediawiki.org/wiki/Manual:Errors_and_symptoms/PCRE Weitre Informatione].",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki unnerstützt die follichenne Datebanksysteme:\n\n$1\n\nSoweit net das Datebanksystem oongezeicht weard, das verwennt werre soll, gebt das uwe en Link zu der Oonleitung mit Informatione, wie das aktiviert sin kann.",
        "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] ist das von MediaWiki primär unterstützte Datebanksystem. MediaWiki funktioniert ooch mit [{{int:version-db-mariadb-url}} MariaDB] und [{{int:version-db-percona-url}} Percona Server], die MySQL-kompatibel sind. ([https://secure.php.net/manual/en/mysqli.installation.php Oonleitung zur Kompilierung von PHP mit MySQL-Unnerstützung] [englisch Sproch])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] ist en beliebtes Open-Source-Datebanksystem und ein Alternativ zu MySQL. Es gibt awer enche klenre Implementierungsfehler, so dass von der Nutzung in ener Produktivumgebung abgerat weard. ([Config-dbsupport-oracle/manual/de/pgsql.installation.php Oonnleitung zur Kompilierung von PHP mit PostgreSQL-Unterstützung])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] ist en beliebtes Open-Source-Datebanksystem und ein Alternativ zu MySQL. Es gibt awer enche klenre Implementierungsfehler, so dass von der Nutzung in ener Produktivumgebung abgerat weard. ([https://secure.php.net/manual/en/pgsql.installation.php Oonnleitung zur Kompilierung von PHP mit PostgreSQL-Unterstützung])",
        "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] ist en verschlanktes Datebanksystem, das ooch gut unnerstützt weard ([http://www.php.net/manual/de/pdo.installation.php Oonleitung zur Kompilierung von PHP mit SQLite-Unterstützung], verwennt PHP Data Objects (PDO))",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] ist en kommerzielle Unnernehmensdatebank ([http://www.php.net/manual/en/oci8.installation.php Oonleitung zur Kompilierung von PHP mit OCI8-Unnerstützung (en)])",
        "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] ist en gewerbliche Unnernehmensdatebank für Windows. ([Config-dbsupport-oracle/manual/de/sqlsrv.installation.php Oonleitung zur Kompilierung von PHP mithilfe SQLSRV-Unnerstützung])",
        "config-mysql-myisam-dep": "'''Warnung:''' Es woard MyISAM als Speicher-Engine für MySQL ausgewählt, die aus follichend Gründe net für den Insatz mit MediaWiki rekommendiert ist:\n* Sie unnerstützt uffgrund von Tabellesperrunge koom die neweloofiche Ausführung von Aktione.\n* Sie ist oonfällicher für Dateprobleme.\n* Sie weard von MediaWiki net immer adäquat unnerstützt.\n\nSoweit die voarhandne MySQL-Installation die Speicher-Engine InnoDB unnerstützt, weard sei Verwennung eindringlich rekommendiert.\nSoweit sie sie net unnerstützt, sollt en entsprechend Aktualisierung nunmeahr Erwächung gezoh sin.",
        "config-mysql-only-myisam-dep": "'''Warnung:''' MyISAM ist die einziche verfüchbare Speicher-Engine für MySQL uff dem Rechner, und das weard net für die Verwennung mit MediaWiki rekommendiert, weil sie\n* uffgrund von Tabellesperrunge koom die neweloofiche Ausführung von Aktione unnerstützt,\n* oonfällicher für Dateprobleme ist und\n* von MediaWiki net immer adäquat unnerstützt weard.\n\nDein MySQL-Installation unnerstützt net InnoDB. Eventuell muss en Aktualisierung dorrichgeführt werre.",
        "config-mysql-engine-help": "'''InnoDB''' ist nächst immer die bessre Wähl, weil es gleichzeitiche Zugriffe gut unnerstützt.\n\n'''MyISAM''' ist in Enzelnutzerumgebunge sowie bei schreibgeschützte Wikis schneller.\nBei MyISAM-Datebanke treten tendenziell häuficher Fehler uff als bei InnoDB-Datebanke.",
-       "config-mysql-charset": "Datebankzeichesatz",
-       "config-mysql-binary": "binär",
-       "config-mysql-utf8": "UTF-8",
-       "config-mysql-charset-help": "Im '''binäre Modus''' speichert MediaWiki UTF-8 Texte in der Datebank in binär kodierte Datefelder.\nDas ist effizienter als der UTF-8-Modus von MySQL und ermöglicht so die Verwennung jeder Unicode-Zeiche.\n\nIm '''UTF-8-Modus''' weard MySQL den Zeichesatz der Date erkenne und sie richtich oonzeiche und konvertiere,\nawer könne ken Zeiche ausserhalb von der [https://de.wikipedia.org/wiki/Basic_Multilingual_Plane#Gliederung_in_Ebenen_und_Bl.C3.B6cke ''Basic Multilingual Plane'' (BMP)] gespeichert sin.",
        "config-mssql-auth": "Authentifikationstyp:",
        "config-mssql-install-auth": "Wähl den Authentifikationstyp aus, der zur Verbinnung mit der Datebank während von der Installationsprozesses verwennt weard.\nFalls du „{{int:config-mssql-windowsauth}}“ auswählst, werre die Oonmeldeinformatione von en beliebiche Benutzer verwennt, wo den Webserver ausführt.",
        "config-mssql-web-auth": "Wähl den Authentifikationstyp aus, der vom Webserver zur Verbinnung mit dem Datebankserver während / im Verloof von der gewöhnliche Betrieb von der Wiki verwennt weard.\nFalls du „{{int:config-mssql-windowsauth}}“ auswählst, werre die Oonmeldeinformatione von en beliebiche Benutzer verwennt, wo den Webserver ausführt.",
        "config-install-interwiki-exists": "'''Warnung:'''  Es woare Interwikitabelle mit Date gefund.\nDie Standardliste weard üwersprung.",
        "config-install-stats": "Statistike werre initialisiert",
        "config-install-keys": "Geheimschlüssel werre erstellt",
-       "config-insecure-keys": "'''Warnung:''' {{PLURAL:$2|Der Geheimschlüssel|Die Geheimschlüssel}} $1, {{PLURAL:$2|der|die}} (während) im Verloof von der Installationsvoargang generiert {{PLURAL:$2|woard, ist|woare, sind}} net seahr sicher. {{PLURAL:$2|Er sollt|Sie sollte}} manuell geännert sin.",
        "config-install-sysop": "Administratorkonto weard erstellt",
        "config-install-subscribe-fail": "Abonniere von „mediawiki-announce“ ist gescheitert: $1",
        "config-install-subscribe-notpossible": "cURL ist net installiert und <code>allow_url_fopen</code> ist niet verfüchbar.",
index 8b7a124..10c6159 100644 (file)
@@ -47,7 +47,7 @@
        "config-env-bad": "Wokolina je so skontrolowała.\nNjemóžeš MediaWiki instalować.",
        "config-env-php": "PHP $1 je instalowany.",
        "config-unicode-using-intl": "Za normalizaciju Unicode so [https://pecl.php.net/intl PECL-rozšěrjenje intl] wužiwa.",
-       "config-no-db": "Njeda so přihódny ćěrjak datoweje banki namakać! Dyrbiš ćěrjak datoweje banki za PHP instalować.\nSlědowace typy datoweje banki so podpěruja: $1.\n\nJeli sy PHP sam kompilował, konfiguruj jón znowa z aktiwizowanym programom datoweje banki, na přikład z pomocu <code>./configure --with-mysqli</code>.\nJeli sy PHP z Debianoweho abo Ubuntuoweho paketa instalował, dyrbiš tež paket <code>php5-mysql</code> instalować.",
+       "config-no-db": "Njeda so přihódny ćěrjak datoweje banki namakać! Dyrbiš ćěrjak datoweje banki za PHP instalować.\nSlědowace typy datoweje banki so podpěruja: $1.\n\nJeli sy PHP sam kompilował, konfiguruj jón znowa z aktiwizowanym programom datoweje banki, na přikład z pomocu <code>./configure --with-mysqli</code>.\nJeli sy PHP z Debianoweho abo Ubuntuoweho paketa instalował, dyrbiš tež paket <code>php-mysql</code> instalować.",
        "config-outdated-sqlite": "'''Warnowanje''': maš SQLite $1, kotryž je starši hač minimalna trěbna wersija $2. SQLite njebudźe k dispoziciji stać.",
        "config-no-fts3": "'''Warnowanje''': SQLite je so bjez [//sqlite.org/fts3.html FTS3-modula] kompilował, pytanske funkcije njebudu k dispoziciji stać.",
        "config-pcre-no-utf8": "'''Ćežki zmylk''': Zda so, zo PCRE-modul za PHP ma so bjez PCRE_UTF8-podpěry kompilować.\nMediaWiki trjeba UTF-8-podpěru, zo by korektnje fungował.",
@@ -88,7 +88,7 @@
        "config-type-sqlite": "SQLite",
        "config-type-oracle": "Oracle",
        "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] je primarny cil za MediaWiki a podpěruje so najlěpje. MediaWiki funguje tež z [{{int:version-db-mariadb-url}} MariaDB] a [{{int:version-db-percona-url}} Percona Server], kotrejž stej kompatibelnej z MySQL. ([https://secure.php.net/manual/en/mysqli.installation.php Nawod ke kompilowanju  PHP z  MySQL-podpěru])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] je popularny system datoweje banki zjawneho žórła jako alternatiwa k MySQL. Móhło hišće někotre zmylki eksistować, a njeporuča so jón w produktiwnej wokolinje wužiwać. ([Config-dbsupport-oracle/manual/en/pgsql.installation.php Nawod za kompilowanje PHP z podpěru PostgreSQL])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] je popularny system datoweje banki zjawneho žórła jako alternatiwa k MySQL. Móhło hišće někotre zmylki eksistować, a njeporuča so jón w produktiwnej wokolinje wužiwać. ([https://secure.php.net/manual/en/pgsql.installation.php Nawod za kompilowanje PHP z podpěru PostgreSQL])",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] je komercielna předewzaćelska datowa banka. ([http://www.php.net/manual/en/oci8.installation.php Nawod za kompilowanje PHP z OCI8-podpěru])",
        "config-header-mysql": "Nastajenja MySQL",
        "config-header-postgres": "Nastajenja PostgreSQL",
        "config-mysql-engine": "Składowanska mašina:",
        "config-mysql-innodb": "InnoDB",
        "config-mysql-myisam": "MyISAM",
-       "config-mysql-charset": "Znamješkowa sadźba datoweje banki:",
-       "config-mysql-binary": "Binarny",
-       "config-mysql-utf8": "UTF-8",
        "config-site-name": "Mjeno wikija:",
        "config-site-name-help": "To zjewi so w titulowej lejstwje wobhladaka kaž tež na wšelakich druhich městnach.",
        "config-site-name-blank": "Zapodaj sydłowe mjeno.",
index 3f8a00f..25c6cae 100644 (file)
@@ -62,7 +62,7 @@
        "config-unicode-using-intl": "A rendszer Unicode normalizálására az [https://pecl.php.net/intl intl PECL kiterjesztést] használja.",
        "config-unicode-pure-php-warning": "<strong>Figyelmeztetés:</strong> A Unicode-normalizáláshoz szükséges [https://pecl.php.net/intl intl PECL kiterjesztés] nem érhető el, helyette a lassú, PHP-alapú implementáció lesz használatban.\nHa nagy látogatottságú oldalt üzemeltetsz, [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations itt] találhatsz további információkat a témáról.",
        "config-unicode-update-warning": "<strong>Figyelmeztetés:</strong> A Unicode normalizáláshoz szükséges burkolókönyvtár [http://site.icu-project.org/ az ICU projekt] függvénykönyvtárának régebbi változatát használja.\nHa ügyelni kívánsz a Unicode használatára, fontold meg a [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations frissítését].",
-       "config-no-db": "Nem sikerült egyetlen használható adatbázis-illesztőprogramot sem találni. Telepítened kell egyet a PHP-hez.\nA következő {{PLURAL:$2|adatbázistípus támogatott|adatbázistípusok támogatottak}}: $1.\n\nHa a PHP-t magad fordítottad, konfiguráld újra úgy, hogy engedélyezve legyen egy adatbáziskliens, pl. a <code>./configure --with-mysqli</code> parancs használatával.\nHa a PHP-t Debian vagy Ubuntu csomaggal telepítetted, akkor szükséged lesz például a <code>php5-mysql</code> csomagra is.",
+       "config-no-db": "Nem sikerült egyetlen használható adatbázis-illesztőprogramot sem találni. Telepítened kell egyet a PHP-hez.\nA következő {{PLURAL:$2|adatbázistípus támogatott|adatbázistípusok támogatottak}}: $1.\n\nHa a PHP-t magad fordítottad, konfiguráld újra úgy, hogy engedélyezve legyen egy adatbáziskliens, pl. a <code>./configure --with-mysqli</code> parancs használatával.\nHa a PHP-t Debian vagy Ubuntu csomaggal telepítetted, akkor szükséged lesz például a <code>php-mysql</code> csomagra is.",
        "config-outdated-sqlite": "<strong>Figyelmeztetés:</strong> SQLite $1 verziód van, ami alacsonyabb a legalább szükséges $2 verziónál. Az SQLite nem lesz elérhető.",
        "config-no-fts3": "<strong>Figyelmeztetés:</strong> Az SQLite [//sqlite.org/fts3.html FTS3 modul] nélkül lett fordítva, a keresési funkciók nem fognak működni ezen a rendszeren.",
        "config-pcre-old": "<strong>Kritikus hiba:</strong> PCRE $1 vagy későbbi szükséges.\nA te PHP binárisod a PCRE $2 verziójával van linkelve.\n[https://www.mediawiki.org/wiki/Manual:Errors_and_symptoms/PCRE További információ].",
        "config-type-mssql": "Microsoft SQL Szerver",
        "config-support-info": "A MediaWiki a következő adatbázisrendszereket támogatja:\n\n$1\n\nHa az alábbi listán nem találod azt a rendszert, melyet használni szeretnél, a fenti linken található instrukciókat követve engedélyezheted a támogatását.",
        "config-dbsupport-mysql": "* A [{{int:version-db-mysql-url}} MySQL] a MediaWiki elsődleges célpontja, így a legjobban támogatott. A MediaWiki elfut [{{int:version-db-mariadb-url}} MariaDB-n] és [{{int:version-db-percona-url}} Percona Serveren] is, mivel ezek MySQL-kompatibilisek. ([https://secure.php.net/manual/en/mysql.installation.php Hogyan fordítható a PHP MySQL-támogatással])",
-       "config-dbsupport-postgres": "* A [{{int:version-db-postgres-url}} PostgreSQL] népszerű, nyílt forráskódú adatbázisrendszer, a MySQL alternatívája. ([Config-dbsupport-oracle/manual/en/pgsql.installation.php Hogyan fordítható a PHP PostgreSQL-támogatással])",
+       "config-dbsupport-postgres": "* A [{{int:version-db-postgres-url}} PostgreSQL] népszerű, nyílt forráskódú adatbázisrendszer, a MySQL alternatívája. ([https://secure.php.net/manual/en/pgsql.installation.php Hogyan fordítható a PHP PostgreSQL-támogatással])",
        "config-dbsupport-sqlite": "* Az [{{int:version-db-sqlite-url}} SQLite] egy könnyű, nagyon jól támogatott adatbázisrendszer. ([http://www.php.net/manual/en/pdo.installation.php Hogyan fordítható a PHP SQLite-támogatással], PDO-t használ)",
        "config-dbsupport-oracle": "* Az [{{int:version-db-oracle-url}} Oracle] kereskedelmi, vállalati adatbázisrendszer. ([http://www.php.net/manual/en/oci8.installation.php Hogyan fordítható a PHP OCI8-támogatással])",
-       "config-dbsupport-mssql": "* A [{{int:version-db-mssql-url}} Microsoft SQL Server] kereskedelmi, vállalati adatbázisrendszer. ([Config-dbsupport-oracle/manual/en/sqlsrv.installation.php Hogyan fordítható a PHP SQLSRV-támogatással])",
+       "config-dbsupport-mssql": "* A [{{int:version-db-mssql-url}} Microsoft SQL Server] kereskedelmi, vállalati adatbázisrendszer. ([https://secure.php.net/manual/en/sqlsrv.installation.php Hogyan fordítható a PHP SQLSRV-támogatással])",
        "config-header-mysql": "MySQL-beállítások",
        "config-header-postgres": "PostgreSQL-beállítások",
        "config-header-sqlite": "SQLite-beállítások",
        "config-mysql-myisam": "MyISAM",
        "config-mysql-myisam-dep": "'''Figyelmeztetés''': A MyISAM tárolómotort választottad, ami nem ajánlott a MediaWiki használatánál, mert:\n* nagyon rosszul kezeli a párhuzamos lekéréseket a táblák zárolása miatt\n* sokkal nagyobb az esélye az adatkorrupció kialakulásának\n* a MediaWiki kódbázisa nem mindig úgy kezeli a MyISAM-ot, ahogyan kellene\n\nHa a feltelepített MySQL támogatja az InnoDB-t, erősen ajánlott, hogy inkább azt válaszd.\nHa nem, akkor lehet, hogy itt az ideje a frissítésnek.",
        "config-mysql-engine-help": "A legtöbb esetben az '''InnoDB''' a legjobb választás, mivel megfelelően támogatja a párhuzamosságot.\n\nA '''MyISAM''' gyorsabb megoldás lehet egyfelhasználós vagy csak olvasható környezetekben, azonban a MyISAM-adatbázisok sokkal gyakrabban sérülnek meg, mint az InnoDB-adatbázisok.",
-       "config-mysql-charset": "Adatbázis karakterkészlete:",
-       "config-mysql-binary": "Bináris",
-       "config-mysql-utf8": "UTF-8",
-       "config-mysql-charset-help": "'''Bináris módban''' a MediaWiki az UTF-8-as szövegeket bináris mezőkben tárolja az adatbázisban.\nEz sokkal hatékonyabb a MySQL UTF-8-as módjánál, és lehetővé teszi a teljes Unicode-karakterkészlet használatát.\n\n'''UTF-8-as módban''' a MySQL tudni fogja,hogy az adatok milyen karakterkészlettel rendelkeznek, és megfelelően átalakítja őket, azonban nem tárolhatóak olyan karakterek, melyek a [https://en.wikipedia.org/wiki/Mapping_of_Unicode_character_planes Basic Multilingual Plane] felett vannak.",
        "config-mssql-auth": "Hitelesítés típusa:",
        "config-mssql-sqlauth": "SQL Server hitelesítés",
        "config-mssql-windowsauth": "Windows hitelesítés",
        "config-install-interwiki-exists": "'''Figyelmeztetés''': Úgy tűnik, hogy az interwiki táblában már vannak bejegyzések.\nAlapértelmezett lista kihagyása.",
        "config-install-stats": "Statisztika inicializálása",
        "config-install-keys": "Titkos kulcsok generálása",
-       "config-insecure-keys": "'''Figyelmeztetés:''' A telepítés során generált $1 {{PLURAL:$2|biztonsági kulcs|biztonsági kulcsok}} nem teljesen $1 {{PLURAL:$2|biztonságos|biztonságosak}}. Érdemes {{PLURAL:$2||őket}} manuálisan megváltoztatni.",
        "config-install-updates": "Nem szükséges frissítések futtatásának megakadályozása",
        "config-install-sysop": "Az adminisztrátor felhasználói fiókjának létrehozása",
        "config-install-subscribe-fail": "Nem sikerült feliratkozni a mediawiki-announce levelezőlistára: $1",
        "config-nofile": "\"$1\" fájl nem található. Törölve lett?",
        "config-extension-link": "Tudtad, hogy a wikid támogat [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Extensions kiterjesztéseket]?\n\nBöngészhetsz [https://www.mediawiki.org/wiki/Special:MyLanguage/Category:Extensions_by_category kiterjesztéseket kategóriánként] vagy válogathatsz a [https://www.mediawiki.org/wiki/Extension_Matrix kiterjesztésmátrixból] az összes kiterjesztés áttekintéséhez.",
        "config-skins-screenshots": "$1 (képernyőképek: $2)",
+       "config-extensions-requires": "$1 ($2 szükséges hozzá)",
        "config-screenshot": "képernyőkép",
        "mainpagetext": "<strong>A MediaWiki telepítése sikeresen befejeződött.</strong>",
        "mainpagedocfooter": "Ha segítségre van szükséged a wikiszoftver használatához, akkor keresd fel a [https://meta.wikimedia.org/wiki/Help:Contents User's Guide] oldalt.\n\n== Alapok (angol nyelven) ==\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Beállítások listája]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ MediaWiki GyIK]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki-kiadások levelezőlistája]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources A MediaWiki fordítása a saját nyelvedre]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Tudd meg többet, hogyan küzdhetsz a kéretlen levelek ellen a wikiden]"
index d9e2ad1..fe382ac 100644 (file)
@@ -53,7 +53,7 @@
        "config-unicode-using-intl": "Le [https://pecl.php.net/intl extension PECL intl] es usate pro le normalisation Unicode.",
        "config-unicode-pure-php-warning": "'''Aviso''': Le [https://pecl.php.net/intl extension PECL intl] non es disponibile pro exequer le normalisation Unicode; le systema recurre al implementation lente in PHP pur.\nSi tu sito ha un alte volumine de traffico, tu deberea informar te un poco super le [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations normalisation Unicode].",
        "config-unicode-update-warning": "'''Aviso''': Le version installate del bibliotheca inveloppante pro normalisation Unicode usa un version ancian del bibliotheca del [http://site.icu-project.org/ projecto ICU].\nTu deberea [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations actualisar lo] si le uso de Unicode importa a te.",
-       "config-no-db": "Non poteva trovar un driver appropriate pro le base de datos! Es necessari installar un driver de base de datos pro PHP.\nLe sequente {{PLURAL:$2|typo|typos}} de base de datos es supportate: $1.\n\nSi tu compilava PHP tu mesme, reconfigura lo con un cliente de base de datos activate, per exemplo, usante <code>./configure --with-mysqli</code>.\nSi tu installava PHP ex un pacchetto Debian o Ubuntu, tu debe etiam installar, per exemplo, le modulo <code>php5-mysql</code>.",
+       "config-no-db": "Non poteva trovar un driver appropriate pro le base de datos! Es necessari installar un driver de base de datos pro PHP.\nLe sequente {{PLURAL:$2|typo|typos}} de base de datos es supportate: $1.\n\nSi tu compilava PHP tu mesme, reconfigura lo con un cliente de base de datos activate, per exemplo, usante <code>./configure --with-mysqli</code>.\nSi tu installava PHP ex un pacchetto Debian o Ubuntu, tu debe etiam installar, per exemplo, le modulo <code>php-mysql</code>.",
        "config-outdated-sqlite": "'''Attention''': tu ha SQLite $1, que es inferior al version minimal requirite, $2. SQLite essera indisponibile.",
        "config-no-fts3": "'''Attention''': SQLite es compilate sin [//sqlite.org/fts3.html modulo FTS3]; functionalitate de recerca non essera disponibile in iste back-end.",
        "config-pcre-old": "<strong>Fatal:</strong> PCRE $1 o plus tarde es necessari.\nTu binario de PHP binary es ligate con PCRE $2.\n[https://www.mediawiki.org/wiki/Manual:Errors_and_symptoms/PCRE Plus information].",
        "config-support-info": "MediaWiki supporta le sequente systemas de base de datos:\n\n$1\n\nSi tu non vide hic infra le systema de base de datos que tu tenta usar, alora seque le instructiones ligate hic supra pro activar le supporto.",
        "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] es le systema primari pro MediaWiki e le melio supportate. MediaWiki functiona anque con [{{int:version-db-mariadb-url}} MariaDB] e con [{{int:version-db-percona-url}} Percona Server], le quales es compatibile con MySQL. ([https://secure.php.net/manual/en/mysqli.installation.php Como compilar PHP con supporto de MySQL])",
        "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] es un systema de base de datos popular e open source, alternativa a MySQL. ([https://secure.php.net/manual/en/pgsql.installation.php Como compilar PHP con supporto de PostgreSQL])",
-       "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] es un systema de base de datos legier que es multo ben supportate. ([http://www.php.net/manual/en/pdo.installation.php Como compilar PHP con supporto de SQLite], usa PDO)",
-       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] es un banca de datos commercial pro interprisas. ([http://www.php.net/manual/en/oci8.installation.php Como compilar PHP con supporto de OCI8])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] es un base de datos de interprisa commercial pro Windows. ([Config-dbsupport-oracle/manual/en/sqlsrv.installation.php Como compilar PHP con supporto de SQLSRV])",
+       "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] es un systema de base de datos legier que es multo ben supportate. ([https://secure.php.net/manual/en/pdo.installation.php Como compilar PHP con supporto de SQLite], usa PDO)",
+       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] es un banca de datos commercial pro interprisas. ([https://secure.php.net/manual/en/oci8.installation.php Como compilar PHP con supporto de OCI8])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] es un base de datos de interprisa commercial pro Windows. ([https://secure.php.net/manual/en/sqlsrv.installation.php Como compilar PHP con supporto de SQLSRV])",
        "config-header-mysql": "Configuration de MySQL",
        "config-header-postgres": "Configuration de PostgreSQL",
        "config-header-sqlite": "Configuration de SQLite",
        "config-db-web-create": "Crear le conto si illo non jam existe",
        "config-db-web-no-create-privs": "Le conto que tu specificava pro installation non ha sufficiente privilegios pro crear un conto.\nLe conto que tu specifica hic debe jam exister.",
        "config-mysql-engine": "Motor de immagazinage:",
-       "config-mysql-innodb": "InnoDB",
+       "config-mysql-innodb": "InnoDB (recommendate)",
        "config-mysql-myisam": "MyISAM",
        "config-mysql-myisam-dep": "* '''Attention:''' Tu ha seligite MyISAM como motor de immagazinage pro MySQL, lo que non es recommendate pro uso con MediaWiki, perque:\n* illo a pena supporta le processamento simultanee a causa del blocada le tabulas\n* illo es plus susceptibile al corruption que altere motores\n* le base de codice de MediaWiki non sempre manea MyISAM como illo deberea\n\nSi tu installation de MySQL supporta InnoDB, es multo recommendate que tu selige iste in su loco.\nSi tu installation de MySQL non supporta InnoDB, forsan isto es un bon occasion pro actualisar lo.",
        "config-mysql-only-myisam-dep": "'''Attention:''' MyISAM es le unic motor de immagazinage disponibile pro MySQL in iste machina, ma isto non es recommendate pro le uso con MediaWiki, perque:\n* a pena supporto le accesso simultanee a causa del blocage de tabellas\n* es plus propense a corrumper se que altere motores\n* le codice base de MediaWiki non sempre gere MyISAM como deberea\n\nTu installation de MySQL non supporta InnoDB; forsan il es tempore de actualisar lo.",
        "config-mysql-engine-help": "'''InnoDB''' es quasi sempre le melior option, post que illo ha bon supporto pro simultaneitate.\n\n'''MyISAM''' pote esser plus rapide in installationes a usator singule o a lectura solmente.\nLe bases de datos MyISAM tende a esser corrumpite plus frequentemente que le base de datos InnoDB.",
-       "config-mysql-charset": "Codification de characteres in le base de datos:",
-       "config-mysql-binary": "Binari",
-       "config-mysql-utf8": "UTF-8",
-       "config-mysql-charset-help": "In '''modo binari''', MediaWiki immagazina le texto UTF-8 in le base de datos in campos binari.\nIsto es plus efficiente que le modo UTF-8 de MySQL, e permitte usar le rango complete de characteres Unicode.\n\nIn '''modo UTF-8''', MySQL cognoscera le codification de characteres usate pro tu dats, e pote presentar e converter lo appropriatemente, ma illo non permittera immagazinar characteres supra le [https://en.wikipedia.org/wiki/Mapping_of_Unicode_character_planes Plano Multilingue Basic].",
        "config-mssql-auth": "Typo de authentication:",
        "config-mssql-install-auth": "Selige le typo de authentication a usar pro connecter al base de datos durante le processo de installation.\nSi tu selige \"{{int:config-mssql-windowsauth}}\", le credentiales del usator que executa le servitor web essera usate.",
        "config-mssql-web-auth": "Selige le typo de authentication que le servitor web usara pro connecter al base de datos durante le operation ordinari del wiki.\nSi tu selige \"{{int:config-mssql-windowsauth}}\", le credentiales del usator que executa le servitor web essera usate.",
        "config-install-interwiki-exists": "'''Aviso''': Le tabella interwiki pare jam haber entratas.\nLe lista predefinite es saltate.",
        "config-install-stats": "Initialisation del statisticas",
        "config-install-keys": "Generation de claves secrete",
-       "config-insecure-keys": "'''Attention:''' {{PLURAL:$2|Un clave|Alcun claves}} secur ($1) generate durante le installation non es completemente secur. Considera cambiar {{PLURAL:$2|lo|los}} manualmente.",
        "config-install-updates": "Impedir le execution de actualisationes innecessari",
        "config-install-updates-failed": "<strong>Error:</strong> Le insertion de claves de actualisation in le tabellas ha fallite con le error sequente: $1",
        "config-install-sysop": "Crea conto de usator pro administrator",
        "config-nofile": "Le file \"$1\" non poteva esser trovate. Ha illo essite delite?",
        "config-extension-link": "Sapeva tu que tu wiki supporta [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Extensions extensiones]?\n\nTu pote explorar le [https://www.mediawiki.org/wiki/Special:MyLanguage/Category:Extensions_by_category extensiones per category] o le [https://www.mediawiki.org/wiki/Extension_Matrix matrice de extensiones] pro vider le lista complete de extensiones.",
        "config-skins-screenshots": "$1 (capturas de schermo: $2)",
+       "config-extensions-requires": "$1 (require $2)",
        "config-screenshot": "captura de schermo",
        "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 786bdeb..87fc27b 100644 (file)
@@ -64,7 +64,7 @@
        "config-unicode-using-intl": "Menggunakan [https://pecl.php.net/intl ekstensi PECL intl] untuk normalisasi Unicode.",
        "config-unicode-pure-php-warning": "<strong>Peringatan:</strong> [https://pecl.php.net/intl intl Ekstensi PECL] tidak tersedia untuk menangani normalisasi Unicode, dikembalikan untuk melambatkan implementasi PHP asli.\nApabila Anda menjalankan situs dengan lalu-lintas tinggi, Anda harus membaca [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations normalisasi Unicode].",
        "config-unicode-update-warning": "<strong>Peringatan:</strong> Versi terinstal dari pembungkus normalisasi Unicode menggunakan versi lama pustaka [http://site.icu-project.org/ proyek ICU].\nAnda harus [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations meningkatkan versinya] jika ingin menggunakan Unicode.",
-       "config-no-db": "Pengandar basis data yang sesuai tidak ditemukan! Anda perlu menginstal pengandar basis data untuk PHP.\n{{PLURAL:$2|Jenis|Jenis}} basis data yang didukung: $1.\n\nJika Anda mengompilasi PHP sendiri, ubahlah konfigurasinya dengan mengaktifkan klien basis data, misalnya menggunakan <code>./configure --with-mysqli</code>.\nJika Anda menginstal PHP dari paket Debian atau Ubuntu, maka Anda juga perlu menginstal seperti paket <code>php5-mysql</code>.",
+       "config-no-db": "Pengandar basis data yang sesuai tidak ditemukan! Anda perlu menginstal pengandar basis data untuk PHP.\n{{PLURAL:$2|Jenis|Jenis}} basis data yang didukung: $1.\n\nJika Anda mengompilasi PHP sendiri, ubahlah konfigurasinya dengan mengaktifkan klien basis data, misalnya menggunakan <code>./configure --with-mysqli</code>.\nJika Anda menginstal PHP dari paket Debian atau Ubuntu, maka Anda juga perlu menginstal seperti paket <code>php-mysql</code>.",
        "config-outdated-sqlite": "<strong>Peringatan:</strong> Anda menggunakan SQLite $1, yang lebih rendah dari versi minimum yang diperlukan $2. SQLite akan tidak tersedia.",
        "config-no-fts3": "'''Peringatan''': SQLite dikompilasi tanpa [//sqlite.org/fts3.html modul FTS3], fitur pencarian tidak akan tersedia pada konfigurasi ini.",
        "config-pcre-old": "<strong>Fatal:</strong> PCRE $1 atau kemudian diperlukan.\nBiner PHP Anda dihubungkan dengan PCRE $2. [https://www.mediawiki.org/wiki/Manual:Errors_and_symptoms/PCRE Selengkapnya].",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki mendukung sistem basis data berikut:\n\n$1\n\nJika Anda tidak melihat sistem basis data yang Anda gunakan tercantum di bawah ini, ikuti petunjuk terkait di atas untuk mengaktifkan dukungan.",
        "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] adalah target utama MediaWiki dan memiliki dukungan terbaik. MediaWiki juga berjalan dengan [{{int:version-db-mariadb-url}} MariaDB] dan [{{int:version-db-percona-url}} Server Percona], yang kompatibel dengan MySQL. ([https://secure.php.net/manual/en/mysql.installation.php Cara mengompilasi PHP dengan dukungan MySQL])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] adalah sistem basis data sumber terbuka populer sebagai alternatif MySQL.([Config-dbsupport-oracle/manual/en/pgsql.installation.php Bagaimana mengompilasikan PHP dengan dukungan PostgreSQL])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] adalah sistem basis data sumber terbuka populer sebagai alternatif MySQL.([https://secure.php.net/manual/en/pgsql.installation.php Bagaimana mengompilasikan PHP dengan dukungan PostgreSQL])",
        "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] adalah sistem basis data yang ringan yang sangat baik dukungannya. ([http://www.php.net/manual/en/pdo.installation.php cara mengompilasi PHP dengan dukungan SQLite], menggunakan PDO)",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] adalah basis data komersial untuk perusahaan. ([http://www.php.net/manual/en/oci8.installation.php cara mengompilasi PHP dengan dukungan OCI8])",
-       "config-dbsupport-mssql": "[{{int:version-db-mssql-url}} Microsoft SQL Server] adalah database perusahaan komersial untuk Windows. ([Config-dbsupport-oracle/manual/en/sqlsrv.installation.php Bagaimana cara mengkompilasi PHP dengan dukungan SQLSRV])",
+       "config-dbsupport-mssql": "[{{int:version-db-mssql-url}} Microsoft SQL Server] adalah database perusahaan komersial untuk Windows. ([https://secure.php.net/manual/en/sqlsrv.installation.php Bagaimana cara mengkompilasi PHP dengan dukungan SQLSRV])",
        "config-header-mysql": "Pengaturan MySQL",
        "config-header-postgres": "Pengaturan PostgreSQL",
        "config-header-sqlite": "Pengaturan SQLite",
        "config-mysql-myisam-dep": "<strong>Peringatan:</strong> Anda telah memilih MyISAM sebagai mesin penyimpanan MySQL, yang tidak dianjurkan untuk digunakan dengan MediaWiki, karena:\n * nyaris tidak mendukung operasi bersamaan karena penguncian tabel\n * lebih rentan terhadap korupsi daripada mesin lain\n * basis kode MediaWiki tidak selalu menangani MyISAM sebagaimana mestinya\n\nJika instalasi MySQL Anda mendukung InnoDB, sangat disarankan bagi Anda memilih itu.\nJika instalasi MySQL tidak mendukung InnoDB, mungkin sudah waktunya untuk pemutakhiran.",
        "config-mysql-only-myisam-dep": "<strong>Peringatan:</strong> MyISAM adalah satu-satunya mesin penyimpanan yang tersedia untuk MySQL pada mesin ini, dan hal ini tidak dianjurkan untuk digunakan dengan MediaWiki, karena:\n* hampir tidak mendukung konkurensi karena penguncian tabel\n* basis kode MediaWiki tidak selalu menangani MyISAM sebagaimana mestinya\n\nInstalasi MySQL Anda tidak mendukung InnoDB, mungkin sudah waktunya untuk peningkatan.",
        "config-mysql-engine-help": "'''InnoDB''' hampir selalu merupakan pilihan terbaik karena memiliki dukungan konkurensi yang baik.\n\n'''MyISAM''' mungkin lebih cepat dalam instalasi pengguna-tunggal atau hanya-baca.\nBasis data MyISAM cenderung lebih sering rusak daripada basis data InnoDB.",
-       "config-mysql-charset": "Set karakter basis data:",
-       "config-mysql-binary": "Biner",
-       "config-mysql-utf8": "UTF-8",
-       "config-mysql-charset-help": "Dalam '''modus biner''', MediaWiki menyimpan teks UTF-8 untuk basis data dalam bidang biner.\nIni lebih efisien daripada modus UTF-8 MySQL dan memungkinkan Anda untuk menggunakan ragam penuh karakter Unicode.\n\nDalam '''modus UTF-8''', MySQL akan tahu apa set karakter data dan dapat menampilkan dan mengubahnya sesuai keperluan, tetapi tidak akan mengizinkan Anda menyimpan karakter di atas [https://en.wikipedia.org/wiki/Mapping_of_Unicode_character_planes Basic Multilingual Plane].",
        "config-mssql-auth": "Jenis otentikasi:",
        "config-mssql-install-auth": "Pilih jenis otentikasi yang akan digunakan untuk menyambung ke database selama proses instalasi.\nJika Anda memilih \"{{int:config-mssql-windowsauth}}\", kredensial dari pengguna apapun pada server web yang berjalan akan digunakan.",
        "config-mssql-web-auth": "Pilih jenis otentikasi yang akan digunakan oleh server web untuk menyambung ke server basis data, selama operasi biasa dari wiki.\nJika Anda memilih \"{{int:config-mssql-windowsauth}}\", kredensial dari pengguna apapun pada server web yang berjalan akan digunakan.",
        "config-install-interwiki-exists": "'''Peringatan''': Tabel antarwiki tampaknya sudah memiliki entri.\nMengabaikan daftar bawaan.",
        "config-install-stats": "Inisialisasi statistik",
        "config-install-keys": "Membuat kunci rahasia",
-       "config-insecure-keys": "'''Peringatan:''' {{PLURAL:$2|Suatu|Beberapa}} kunci aman ($1) yang dibuat selama instalasi {{PLURAL:$2|tidak|tidak}} benar-benar aman. Pertimbangkan untuk mengubah {{PLURAL:$2|kunci|kunci-kunci}} tersebut secara manual.",
        "config-install-updates": "Cegah jalannya pembaruan yang tidak dibutuhkan",
        "config-install-updates-failed": "<strong>Kesalahan:</strong> Memasukkan kunci pembaruan ke dalam tabel gagal dengan kode kesalahan: $1",
        "config-install-sysop": "Membuat akun pengguna pengurus",
index 2f5826f..93039ff 100644 (file)
@@ -63,9 +63,6 @@
        "config-mysql-engine": "Gagnagrunnshýsing:",
        "config-mysql-innodb": "InnoDB",
        "config-mysql-myisam": "MyISAM",
-       "config-mysql-charset": "Stafatafla gagnagrunns:",
-       "config-mysql-binary": "Tvíundakerfis",
-       "config-mysql-utf8": "UTF-8",
        "config-mssql-auth": "Tegund auðkenningar:",
        "config-mssql-sqlauth": "SQL Server auðkenning",
        "config-mssql-windowsauth": "Windows auðkenning",
index 48e96c5..b8db489 100644 (file)
@@ -70,7 +70,7 @@
        "config-unicode-using-intl": "Usa [https://pecl.php.net/intl l'estensione PECL intl] per la normalizzazione Unicode.",
        "config-unicode-pure-php-warning": "'''Attenzione:''' [https://pecl.php.net/intl l'estensione PECL intl] non è disponibile per gestire la normalizzazione Unicode, quindi si torna alla lenta implementazione in PHP puro.\nSe esegui un sito ad alto traffico, dovresti leggere alcune considerazioni sulla [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations normalizzazione Unicode].",
        "config-unicode-update-warning": "'''Attenzione:''' la versione installata del gestore per la normalizzazione Unicode usa una vecchia versione della libreria [http://site.icu-project.org/ del progetto ICU].\nDovresti [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations aggiornare] se vuoi usare l'Unicode.",
-       "config-no-db": "Impossibile trovare un driver adatto per il database! È necessario installare un driver per PHP.\n{{PLURAL:$2|Il seguente formato di database è supportato|I seguenti formati di database sono supportati}}: $1.\n\nSe compili PHP autonomamente, riconfiguralo attivando un client database, per esempio utilizzando <code>./configure --with-mysqli</code>.\nQualora avessi installato PHP per mezzo di un pacchetto Debian o Ubuntu, allora devi installare anche il pacchetto <code>php5-mysql</code>.",
+       "config-no-db": "Impossibile trovare un driver adatto per il database! È necessario installare un driver per PHP.\n{{PLURAL:$2|Il seguente formato di database è supportato|I seguenti formati di database sono supportati}}: $1.\n\nSe compili PHP autonomamente, riconfiguralo attivando un client database, per esempio utilizzando <code>./configure --with-mysqli</code>.\nQualora avessi installato PHP per mezzo di un pacchetto Debian o Ubuntu, allora devi installare anche il pacchetto <code>php-mysql</code>.",
        "config-outdated-sqlite": "'''Attenzione''': è presente SQLite $1 mentre è richiesta la versione $2, SQLite non sarà disponibile.",
        "config-no-fts3": "'''Attenzione''': SQLite è compilato senza il [//sqlite.org/fts3.html modulo FTS3], le funzionalità di ricerca non saranno disponibili su questo backend.",
        "config-pcre-old": "<strong>Errore fatale:</strong> si richiede PCRE  $1 o successivo.\nIl tuo file binario PHP è collegato con PCRE $2.\n[https://www.mediawiki.org/wiki/Manual:Errors_and_symptoms/Maggiori informazioni su PCRE].",
@@ -78,7 +78,7 @@
        "config-memory-raised": "Il valore <code>memory_limit</code> di PHP è $1, aumentato a $2.",
        "config-memory-bad": "''Attenzione:''' Il valore di <code>memory_limit</code> di PHP è $1.\nProbabilmente è troppo basso.\nL'installazione potrebbe non riuscire!",
        "config-apc": "[https://secure.php.net/apc APC] è installato",
-       "config-apcu": "[https://secure.php.net/apc APC] è installato",
+       "config-apcu": "[https://secure.php.net/apcu APCu] è installato",
        "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] è installato",
        "config-no-cache-apcu": "'''Attenzione:''' [https://secure.php.net/apcu APCu], [http://xcache.lighttpd.net/ XCache] o [https://www.iis.net/downloads/microsoft/wincache-extension WinCache] non sono stati trovati.\nLa caching degli oggetti non è attivata.",
        "config-mod-security": "<strong>Attenzione:</strong> Il tuo server web ha il [https://modsecurity.org/ mod_security] abilitato. Se non correttamente configurato, può creare problemi a MediaWiki o ad altro software che permette agli utenti di pubblicare contenuto.\nFai riferimento alla [https://modsecurity.org/documentation/ documentazione sul mod_security] o contatta il supporto tecnico del tuo provider di hosting se si verificano errori.",
        "config-sqlite-dir-help": "SQLite memorizza tutti i dati in un unico file.\n\nLa directory che indicherai deve essere scrivibile dal server web durante l'installazione.\n\nDovrebbe essere <strong>non accessibile via web</strong>, è per questo che non la stiamo mettendo dove ci sono i file PHP.\n\nL'installatore scriverà insieme ad essa un file <code>.htaccess</code>, ma se il tentativo fallisse qualcuno potrebbe avere accesso al database grezzo.\nQuesto include dati utente grezzi (indirizzi, password cifrate) così come versioni eliminate e altri dati ad accesso limitato del wiki.\n\nConsidera l'opportunità di sistemare allo stesso tempo il database da qualche altra parte, per esempio in <code>/var/lib/mediawiki/tuowiki</code>.",
        "config-oracle-def-ts": "Tablespace di default:",
        "config-oracle-temp-ts": "Tablespace temporaneo:",
-       "config-type-mysql": "MySQL (o compatibile)",
+       "config-type-mysql": "MariaDB, MySQL o compatibile",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki supporta i seguenti sistemi di database:\n\n$1\n\nSe fra quelli elencati qui sotto non vedi il sistema di database che vorresti utilizzare, seguire le istruzioni linkate sopra per abilitare il supporto.",
-       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] è la configurazione preferibile per MediaWiki ed è quella meglio supportata. MediaWiki funziona anche con [{{int:version-db-mariadb-url}} MariaDB] e [{{int:version-db-percona-url}} Percona Server], che sono compatibili con MySQL.([https://secure.php.net/manual/en/mysqli.installation.php Come compilare PHP con supporto MySQL])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] è un popolare sistema di database open source come alternativa a MySQL. ([Config-dbsupport-oracle/manual/en/pgsql.installation.php Come compilare PHP con supporto PostgreSQL])",
-       "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite]  è un sistema di database leggero, che è supportato molto bene. ([http://www.php.net/manual/en/pdo.installation.php Come compilare PHP con supporto SQLite], utilizza PDO)",
-       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] è un database di un'impresa commerciale. ([http://www.php.net/manual/en/oci8.installation.php Come compilare PHP con supporto OCI8])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] è un database di un'impresa commerciale per Windows. ([Config-dbsupport-oracle/manual/en/sqlsrv.installation.php Come compilare PHP con supporto SQLSRV])",
+       "config-dbsupport-mysql": "* [{{int:version-db-mariadb-url}} MariaDB] è la configurazione preferibile per MediaWiki ed è quella meglio supportata. MediaWiki funziona anche con [{{int:version-db-mysql-url}} MySQL] e [{{int:version-db-percona-url}} Percona Server], che sono compatibili con MariaDB.([https://secure.php.net/manual/en/mysqli.installation.php Come compilare PHP con supporto MySQL])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] è un popolare sistema di database open source come alternativa a MySQL. ([https://secure.php.net/manual/en/pgsql.installation.php Come compilare PHP con supporto PostgreSQL])",
+       "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite]  è un sistema di database leggero, che è supportato molto bene. ([https://secure.php.net/manual/en/pdo.installation.php Come compilare PHP con supporto SQLite], utilizza PDO)",
+       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] è un database di un'impresa commerciale. ([https://secure.php.net/manual/en/oci8.installation.php Come compilare PHP con supporto OCI8])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] è un database di un'impresa commerciale per Windows. ([https://secure.php.net/manual/en/sqlsrv.installation.php Come compilare PHP con supporto SQLSRV])",
        "config-header-mysql": "Impostazioni MySQL",
        "config-header-postgres": "Impostazioni PostgreSQL",
        "config-header-sqlite": "Impostazioni SQLite",
        "config-db-web-create": "Crea l'account se non esiste già",
        "config-db-web-no-create-privs": "L'account usato per l'installazione non dispone dei privilegi necessari per creare un altro account.\nL'account indicato qui deve già esistere.",
        "config-mysql-engine": "Storage engine:",
-       "config-mysql-innodb": "InnoDB",
+       "config-mysql-innodb": "InnoDB (consigliato)",
        "config-mysql-myisam": "MyISAM",
        "config-mysql-myisam-dep": "<strong>Attenzione:</strong> hai selezionato MyISAM come motore di archiviazione per MySQL, che non è raccomandato per l'uso con  MediaWiki, perché:\n* supporta debolmente la concorrenza per il blocco della tabella\n* è più incline alla corruzione di altri motori\n* il codice di base MediaWiki non gestisce sempre MyISAM come dovrebbe\n\nSe la tua installazione MySQL supporta InnoDB, è altamente raccomandato che lo si scelga al suo posto.\nSe la tua installazione MySQL non supporta InnoDB, forse è il momento per un aggiornamento.",
        "config-mysql-only-myisam-dep": "<strong>Attenzione:</strong> MyISAM è l'unico motore di archiviazione disponibile per MySQL su questa macchina, e questo non è consigliato per l'uso con MediaWiki, perché:\n* supporta debolmente la concorrenza per il blocco della tabella\n* è più incline alla corruzione di altri motori\n* il codice di base MediaWiki non gestisce sempre MyISAM come dovrebbe\n\nSe la tua installazione MySQL non supporta InnoDB, forse è il momento per un aggiornamento.",
        "config-mysql-engine-help": "<strong>InnoDB</strong> è quasi sempre l'opzione migliore, in quanto ha un buon supporto della concorrenza.\n\n<strong>MyISAM</strong> potrebbe essere più veloce nelle installazioni monoutente o in sola lettura.\nI database MyISAM tendono a danneggiarsi più spesso dei database InnoDB.",
-       "config-mysql-charset": "Set di caratteri del database:",
-       "config-mysql-binary": "Binario",
-       "config-mysql-utf8": "UTF-8",
-       "config-mysql-charset-help": "In <strong>modalità binaria</strong>, MediaWiki archivia il testo UTF-8 nel database in campi binari.\nCiò è più efficiente rispetto alla modalità UTF-8 di MySQL, e consente di utilizzare la gamma completa di caratteri Unicode.\n\nIn <strong>modalità UTF-8</strong>, MySQL saprà in quale set di caratteri sono i tuoi dati, e potrà presentarli e convertirli in modo appropriato, ma non ti permetterà di memorizzare i caratteri al di sopra del [https://en.wikipedia.org/wiki/Mapping_of_Unicode_character_planes Piano di base multilinguistico].",
        "config-mssql-auth": "Tipo di autenticazione:",
        "config-mssql-install-auth": "Seleziona il tipo di autenticazione che verrà utilizzato per connettersi al database durante il processo di installazione.\nSe si seleziona \"{{int:config-mssql-windowsauth}}\", saranno utilizzate le credenziali dell'utente con cui viene eseguito il server web, qualunque esso sia.",
        "config-mssql-web-auth": "Seleziona il tipo di autenticazione che il server web utilizzerà per connettersi al database, durante il normale funzionamento del wiki.\nSe si seleziona \"{{int:config-mssql-windowsauth}}\", saranno utilizzate le credenziali dell'utente con cui viene eseguito il server web, qualunque esso sia.",
        "config-license-help": "Molti wiki pubblici rilasciano i loro contributi con una [https://freedomdefined.org/Definition licenza libera]. Questo aiuta a creare un senso di proprietà condivisa nella comunità e incoraggia a contribuire a lungo termine. Non è generalmente necessario per un wiki privato o aziendale.\n\nSe vuoi usare testi da Wikipedia, o desideri che Wikipedia possa essere in grado di accettare testi copiati dal tuo wiki, dovresti scegliere <strong>{{int:config-license-cc-by-sa}}</strong>.\n\nIn precedenza Wikipedia ha utilizzato la GNU Free Documentation License. La GFDL è una licenza valida, ma è di difficile comprensione e complica il riutilizzo dei contenuti.",
        "config-email-settings": "Impostazioni email",
        "config-enable-email": "Abilita la posta elettronica in uscita",
-       "config-enable-email-help": "Se vuoi che funzionino le email, le [Config-dbsupport-oracle/manual/en/mail.configuration.php PHP's impostazioni della posta] devono essere configurate correttamente.\nSe non si desidera alcuna funzionalità di posta elettronica, puoi disabilitarla qui.",
+       "config-enable-email-help": "Se vuoi che funzionino le email, le [https://secure.php.net/manual/en/mail.configuration.php impostazioni della posta] devono essere configurate correttamente.\nSe non si desidera alcuna funzionalità di posta elettronica, puoi disabilitarla qui.",
        "config-email-user": "Abilita invio email fra utenti",
        "config-email-user-help": "Consente a tutti gli utenti di inviarsi a vicenda email, se lo hanno abilitato nelle loro preferenze.",
        "config-email-usertalk": "Abilita le notifiche per le pagine di discussione utente",
        "config-install-interwiki-exists": "'''Attenzione:''' la tabella interwiki sembra che contiene già elementi.\nSalto l'elenco predefinito.",
        "config-install-stats": "Inizializzazione delle statistiche",
        "config-install-keys": "Generazione delle chiavi segrete",
-       "config-insecure-keys": "'''Attenzione:''' {{PLURAL:$2|Una chiave sicura|Delle chiavi sicure}} ($1) {{PLURAL:$2|generata|generate}} durante l'installazione non {{PLURAL:$2|è|sono}} completamente {{PLURAL:$2|sicura|sicure}}. Considera di {{PLURAL:$2|cambiarla|cambiarle}} manualmente.",
        "config-install-updates": "Impedire l'esecuzione di aggiornamenti non necessari",
        "config-install-updates-failed": "<strong>Errore:</strong> l'inserimento delle chiavi di aggiornamento nelle tabelle non è riuscito con il seguente errore: $1",
        "config-install-sysop": "Creazione dell'account utente per l'amministratore",
index 44fac37..0346dc7 100644 (file)
@@ -72,7 +72,7 @@
        "config-unicode-using-intl": "Unicode正規化に[https://pecl.php.net/intl intl PECL 拡張機能]を使用。",
        "config-unicode-pure-php-warning": "<strong>警告:</strong> Unicode 正規化の処理に [https://pecl.php.net/intl intl PECL 拡張機能]を利用できないため、処理が遅いピュア PHP の実装を代わりに使用しています。\n高トラフィックのサイトを運営する場合は、[https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations Unicode 正規化]をお読みください。",
        "config-unicode-update-warning": "<strong>警告:</strong> インストールされているバージョンの Unicode 正規化ラッパーは、[http://site.icu-project.org/ ICU プロジェクト]のライブラリの古いバージョンを使用しています。\nUnicode を少しでも利用する可能性がある場合は、[https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations アップグレード]してください。",
-       "config-no-db": "適切なデータベース ドライバーが見つかりませんでした! PHP にデータベース ドライバーをインストールする必要があります。\n以下の種類のデータベース{{PLURAL:$2|のタイプ}}に対応しています: $1\n\nPHP を自分でコンパイルした場合は、例えば <code>./configure --with-mysqli</code> を実行して、データベース クライアントを使用できるように再設定してください。\nDebian または Ubuntu のパッケージから PHP をインストールした場合は、モジュール (例: <code>php5-mysql</code>) もインストールする必要があります。",
+       "config-no-db": "適切なデータベース ドライバーが見つかりませんでした! PHP にデータベース ドライバーをインストールする必要があります。\n以下の種類のデータベース{{PLURAL:$2|のタイプ}}に対応しています: $1\n\nPHP を自分でコンパイルした場合は、例えば <code>./configure --with-mysqli</code> を実行して、データベース クライアントを使用できるように再設定してください。\nDebian または Ubuntu のパッケージから PHP をインストールした場合は、モジュール (例: <code>php-mysql</code>) もインストールする必要があります。",
        "config-outdated-sqlite": "<strong>警告:</strong> あなたは SQLite $1 を使用していますが、最低限必要なバージョン $2 より古いバージョンです。SQLite は利用できません。",
        "config-no-fts3": "<strong>警告:</strong> SQLite は [//sqlite.org/fts3.html FTS3] モジュールなしでコンパイルされており、このバックエンドでは検索機能は利用できなくなります。",
        "config-pcre-old": "<strong>致命的エラー:</strong> PCRE $1 以降が必要です。\nご使用中の PHP のバイナリは PCRE $2 とリンクされています。\n[https://www.mediawiki.org/wiki/Manual:Errors_and_symptoms/PCRE 詳細情報]",
        "config-type-mssql": "マイクロソフト SQL Server",
        "config-support-info": "MediaWiki は以下のデータベース システムに対応しています:\n\n$1\n\n使用しようとしているデータベース システムが下記の一覧にない場合は、上記リンク先の手順に従ってインストールしてください。",
        "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL]はMediaWikiの主要な対象であり、最もよくサポートされています。MediaWikiはMySQLと互換性のある[{{int:version-db-mariadb-url}} MariaDB]、[{{int:version-db-percona-url}} Percona Server]でも動きます。 ([https://secure.php.net/manual/ja/mysqli.installation.php PHPをMySQLサポート付きでコンパイルする方法])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] は、MySQLの代替として人気がある公開のデータベースシステムです。([Config-dbsupport-oracle/manual/en/pgsql.installation.php PHPをPostgreSQLサポート付きでコンパイルする方法])",
-       "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite]は、良くサポートされている、軽量データベースシステムです。([http://www.php.net/manual/ja/pdo.installation.php SQLiteに対応したPHPをコンパイルする方法]、PDOを使用)",
-       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle]は商業企業のデータベースです。([http://www.php.net/manual/en/oci8.installation.php OCI8サポートなPHPをコンパイルする方法])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server]は商業企業のWindows用データベースです。([Config-dbsupport-oracle/manual/en/sqlsrv.installation.php SQLSRVサポートなPHPをコンパイルする方法])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] は、MySQLの代替として人気がある公開のデータベースシステムです。([https://secure.php.net/manual/en/pgsql.installation.php PHPをPostgreSQLサポート付きでコンパイルする方法])",
+       "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite]は、良くサポートされている、軽量データベースシステムです。([https://secure.php.net/manual/ja/pdo.installation.php SQLiteに対応したPHPをコンパイルする方法]、PDOを使用)",
+       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle]は商業企業のデータベースです。([https://secure.php.net/manual/en/oci8.installation.php OCI8サポートなPHPをコンパイルする方法])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server]は商業企業のWindows用データベースです。([https://secure.php.net/manual/en/sqlsrv.installation.php SQLSRVサポートなPHPをコンパイルする方法])",
        "config-header-mysql": "MySQL の設定",
        "config-header-postgres": "PostgreSQL の設定",
        "config-header-sqlite": "SQLite の設定",
        "config-mysql-myisam-dep": "<strong>警告:</strong> MySQLのストレージエンジンとして MyISAM を選択していますが、これをMediaWikiで利用するのは推奨されていません。その理由は: \n* テーブルロックによる並列性をほとんどサポートしていない\n* 他のエンジンに比べて壊れやすい\n* MediaWiki のコードベースは必ずしも MyISAM を本来あるべきほどには扱っていない\n\nあなたがインストールした MySQL が InnoDB をサポートしている場合、代わりにそちらをお使いになることを強くお勧めします。\nあなたがインストールした MySQL が InnoDB をサポートしていない場合、アップグレードした方がいいでしょう。",
        "config-mysql-only-myisam-dep": "<strong>警告:</strong> MyISAM がこのマシンの MySQL の唯一のストレージエンジンですが、これをMediaWikiで利用するのは推奨されていません。その理由は: \n* テーブルロックによる並列性をほとんどサポートしていない\n* 他のエンジンに比べて壊れやすい\n* MediaWiki のコードベースは必ずしも MyISAM を本来あるべきほどには扱っていない\n\nあなたがインストールした MySQL が InnoDB をサポートしていない場合、アップグレードした方がいいでしょう。",
        "config-mysql-engine-help": "<strong>InnoDB</strong>は、並行処理のサポートに優れているので、ほとんどの場合において最良の選択肢です。\n\n<strong>MyISAM</strong>は、利用者が1人の場合、あるいは読み込み専用でインストールする場合に、より処理が早くなるでしょう。\nただし、MyISAMのデータベースは、InnoDBより高頻度で破損する傾向があります。",
-       "config-mysql-charset": "データベースの文字セット:",
-       "config-mysql-binary": "バイナリ",
-       "config-mysql-utf8": "UTF-8",
-       "config-mysql-charset-help": "<strong>バイナリ モード</strong>では、MediaWiki は、UTF-8 テキストをデータベースのバイナリ フィールドに格納します。\nこれは、MySQL の UTF-8 モードより効率的で、Unicode 文字の全範囲を利用できるようになります。\n\n<strong>UTF-8 モード</strong>では、MySQL は、データ内で使用している文字集合を知っているため、適切に表現や変換ができますが、\n[https://ja.wikipedia.org/wiki/%E5%9F%BA%E6%9C%AC%E5%A4%9A%E8%A8%80%E8%AA%9E%E9%9D%A2 基本多言語面]の外にある文字を格納できません。",
        "config-mssql-auth": "認証の種類:",
        "config-mssql-install-auth": "インストール過程でデータベースに接続するために使用する認証の種類を選択してください。\n「{{int:config-mssql-windowsauth}}」を選択した場合、ウェブサーバーを実行しているユーザーの認証情報が使用されます。",
        "config-mssql-web-auth": "ウィキの通常の操作の際にウェブサーバーがデータベースサーバーに接続するために使用する認証の種類を選択してください。\n「{{int:config-mssql-windowsauth}}」を選択した場合、ウェブサーバーを実行しているユーザーの認証情報が使用されます。",
        "config-install-interwiki-exists": "<strong>警告:</strong> ウィキ間テーブルは既に登録されているようです。\n既定のテーブルを無視します。",
        "config-install-stats": "統計情報の初期化",
        "config-install-keys": "秘密鍵の生成",
-       "config-insecure-keys": "<strong>警告:</strong> インストール中に生成されたセキュアキー ($1) は完璧に安全ではありません。手動で変更することを検討してください。",
        "config-install-updates": "不要な更新を実行するのを防ぐ",
        "config-install-updates-failed": "<strong>エラー:</strong> 更新キーをテーブルに挿入する際に失敗しました。以下のエラーが起こっています: $1",
        "config-install-sysop": "管理者アカウントの作成",
index 2d12f47..90967d1 100644 (file)
@@ -47,8 +47,6 @@
        "config-sqlite-readonly": "ფაილი <code>$1</code> ჩასაწერად მიუწვდომელია.",
        "config-mysql-innodb": "InnoDB",
        "config-mysql-myisam": "MyISAM",
-       "config-mysql-binary": "ორობითი",
-       "config-mysql-utf8": "UTF-8",
        "config-site-name": "ვიკის სახელი:",
        "config-site-name-blank": "შეიყვანეთ ვებ-გვერდის სახელი.",
        "config-project-namespace": "პროექტის სახელთა სივრცე:",
index a376b61..bd4bd7f 100644 (file)
@@ -61,7 +61,7 @@
        "config-unicode-using-intl": "유니코드 정규화에 [https://pecl.php.net/intl intl PECL 확장 기능]을 사용합니다.",
        "config-unicode-pure-php-warning": "<strong>경고:</strong> 유니코드 정규화를 처리할 [https://pecl.php.net/intl intl PECL 확장 기능]을 사용할 수 없기 때문에 느린 pure-PHP 구현을 대신 사용합니다.\n트래픽이 높은 사이트에서 실행하시려면 [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations 유니코드 정규화]를 읽어보셔야 합니다.",
        "config-unicode-update-warning": "<strong>경고:</strong> 유니코드 정규화 래퍼의 설치된 버전은 [http://site.icu-project.org/ ICU 프로젝트]의 라이브러리의 이전 버전을 사용합니다.\n만약 유니코드를 사용하는 것에 대해 우려가 된다면 [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations 업그레이드]해야합니다.",
-       "config-no-db": "적절한 데이터베이스 드라이버를 찾을 수 없습니다! PHP용 데이터베이스 드라이버를 설치해야 합니다.\n다음 데이터베이스 {{PLURAL:$2|유형을}} 지원합니다: $1.\n\nPHP를 직접 컴파일했다면, 예를 들어 <code>./configure --with-mysqli</code>을 사용하여, 데이터베이스 클라이언트를 활성화하도록 다시 설정하세요.\n데비안이나 우분투 패키지에서 PHP를 설치했다면 <code>php5-mysql</code> 패키지도 설치해야 합니다.",
+       "config-no-db": "적절한 데이터베이스 드라이버를 찾을 수 없습니다! PHP용 데이터베이스 드라이버를 설치해야 합니다.\n다음 데이터베이스 {{PLURAL:$2|유형을}} 지원합니다: $1.\n\nPHP를 직접 컴파일했다면, 예를 들어 <code>./configure --with-mysqli</code>을 사용하여, 데이터베이스 클라이언트를 활성화하도록 다시 설정하세요.\n데비안이나 우분투 패키지에서 PHP를 설치했다면 <code>php-mysql</code> 패키지도 설치해야 합니다.",
        "config-outdated-sqlite": "<strong>경고:</strong> 최소 요구 버전 $2 보다 낮은 SQLite $1이(가) 있습니다. SQLite를 사용할 수 없습니다.",
        "config-no-fts3": "<strong>경고:</strong> SQLite를 [//sqlite.org/fts3.html FTS3 모듈] 없이 컴파일하며, 검색 기능은 백엔드에 사용할 수 없습니다.",
        "config-pcre-old": "<strong>치명:</strong> PCRE $1 또는 그 이상이 필요합니다.\nPHP 바이너리는 PCRE $2에 연결되어 있습니다. [https://www.mediawiki.org/wiki/Manual:Errors_and_symptoms/PCRE 자세한 정보].",
        "config-sqlite-dir-help": "SQLite는 하나의 파일에 모든 데이터를 저장합니다.\n\n입력한 디렉토리는 설치하는 동안 웹 서버가 쓸 수 있어야 합니다.\n\n이 디렉토리는 웹을 통해 접근할 수 <strong>없어야</strong> 합니다. PHP 파일이 있는 곳에 넣을 수 없는 것은 이 때문입니다.\n\n설치 관리자는 <code>.htaccess</code> 파일을 작성하지만, 이것이 실패하면 누군가가 원본 데이터베이스에 접근할 수 있습니다.\n데이터베이스는 원본 사용자 데이터(이메일 주소, 해시한 비밀번호)뿐만 아니라 삭제된 판과 위키의 다른 제한된 데이터를 포함합니다.\n\n예를 들어 <code>/var/lib/mediawiki/yourwiki</code>와 같이 다른 곳에 데이터베이스를 넣는 것이 좋습니다.",
        "config-oracle-def-ts": "기본 테이블공간:",
        "config-oracle-temp-ts": "임시 테이블공간:",
-       "config-type-mysql": "MySQL (또는 호환되는 데이터베이스 시스템)",
+       "config-type-mysql": "MariaDB, MySQL 및 호환",
        "config-type-oracle": "Oracle",
        "config-type-mssql": "Microsoft SQL 서버",
        "config-support-info": "미디어위키는 다음의 데이터베이스 시스템을 지원합니다:\n\n$1\n\n데이터베이스 시스템이 표시되지 않을 때 아래에 나열된 다음 지원을 활성화하려면 위의 링크된 지시에 따라 설치해볼 수 있습니다.",
-       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL]은 미디어위키의 기본 대상이며 가장 잘 지원됩니다. 미디어위키는 또한 MySQL와 호환되는 [{{int:version-db-mariadb-url}} MariaDB]와 [{{int:version-db-percona-url}} Percona 서버]에서도 작동합니다. ([https://secure.php.net/manual/en/mysql.installation.php MySQL 지원으로 PHP를 컴파일하는 방법])",
+       "config-dbsupport-mysql": "* [{{int:version-db-mariadb-url}} MariaDB]는 미디어위키의 기본 대상이며 가장 잘 지원됩니다. 미디어위키는 또한 MariaDB와 호환되는 [{{int:version-db-mysql-url}} MySQL]과 [{{int:version-db-percona-url}} Percona 서버]에서도 작동합니다. ([https://secure.php.net/manual/en/mysql.installation.php MySQL 지원으로 PHP를 컴파일하는 방법])",
        "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL]은 MySQL의 대안으로서 인기 있는 오픈 소스 데이터베이스 시스템입니다. ([https://secure.php.net/manual/en/pgsql.installation.php PostgreSQL 지원으로 PHP를 컴파일하는 방법])",
-       "config-dbsupport-sqlite": "*  [{{int:version-db-sqlite-url}} SQLite]는 매우 잘 지원되고 가벼운 데이터베이스 시스템입니다. ([http://www.php.net/manual/en/pdo.installation.php SQLite 지원으로 PHP를 컴파일하는 방법], PDO 사용)",
-       "config-dbsupport-oracle": "*  [{{int:version-db-oracle-url}} Oracle]은 상용 기업 데이터베이스입니다. ([http://www.php.net/manual/en/oci8.installation.php OCI8 지원으로 PHP를 컴파일하는 방법])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL 서버]는 Windows용 상용 기업 데이터베이스입니다. ([Config-dbsupport-oracle/manual/en/sqlsrv.installation.php SQLSRV 지원으로 PHP를 컴파일하는 방법])",
-       "config-header-mysql": "MySQL 설정",
+       "config-dbsupport-sqlite": "*  [{{int:version-db-sqlite-url}} SQLite]는 매우 잘 지원되고 가벼운 데이터베이스 시스템입니다. ([https://secure.php.net/manual/en/pdo.installation.php SQLite 지원으로 PHP를 컴파일하는 방법], PDO 사용)",
+       "config-dbsupport-oracle": "*  [{{int:version-db-oracle-url}} Oracle]은 상용 기업 데이터베이스입니다. ([https://secure.php.net/manual/en/oci8.installation.php OCI8 지원으로 PHP를 컴파일하는 방법])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL 서버]는 Windows용 상용 기업 데이터베이스입니다. ([https://secure.php.net/manual/en/sqlsrv.installation.php SQLSRV 지원으로 PHP를 컴파일하는 방법])",
+       "config-header-mysql": "MariaDB/MySQL 설정",
        "config-header-postgres": "PostgreSQL 설정",
        "config-header-sqlite": "SQLite 설정",
        "config-header-oracle": "Oracle 설정",
        "config-db-web-create": "이 계정이 아직 존재하지 않을 경우 계정 만들기",
        "config-db-web-no-create-privs": "설치를 위해 지정한 계정이 계정을 만들 수 있는 충분한 권한이 없습니다.\n여기서 지정한 계정은 이미 존재해야 합니다.",
        "config-mysql-engine": "저장소 엔진:",
-       "config-mysql-innodb": "InnoDB",
+       "config-mysql-innodb": "InnoDB (권장)",
        "config-mysql-myisam": "MyISAM",
        "config-mysql-myisam-dep": "<strong>경고:</strong> MySQL을 위한 저장소 엔진으로 MyISAM을 선택하였습니다. MyISAM을 미디어위키에 사용하는 것은 좋지 않습니다.  이유는:\n* 테이블 잠금 때문에 동시 실행을 지원하지 않습니다\n* 다른 엔진보다 더 손상되는 경향이 있습니다\n* 미디어위키 코드베이스가 항상 정상적으로 MyISAM을 처리하지 않습니다\n\nMySQL이 InnoDB를 지원한다면, InnoDB를 선택할 것을 매우 권장합니다.\nMySQL이 InnoDB를 지원하지 않는다면, 업그레이드를 하시는 편이 좋습니다.",
        "config-mysql-only-myisam-dep": "<strong>경고:</strong> MyISAM은 이 기계에  유일하게 사용할 수 있는 MySQL용 저장소 엔진이며, 미디어위키에 사용하는 것은 좋지 않습니다. 이유는:\n* 테이블 잠금 때문에 동시 실행을 지원하지 않습니다\n* 다른 엔진보다 더 손상시키는 경향이 있습니다\n* 미디어위키 코드베이스가 항상 정상적으로 MyISAM을 처리하지 않습니다\n\n당신의 MySQL은 InnoDB를 지원하지 않으며, 업그레이드를 하는 것이 좋습니다.",
        "config-mysql-engine-help": "<strong>InnoDB</strong>는 동시 실행 지원이 우수하기 때문에 대부분의 경우 최고의 옵션입니다.\n\n<strong>MyISAM</strong>은 단일 사용자나 읽기 전용 설치에서 더 빠를 수 있습니다.\nMyISAM 데이터베이스는 InnoDB 데이터베이스보다 더 자주 손실될 수 있습니다.",
-       "config-mysql-charset": "데이터베이스 문자 집합:",
-       "config-mysql-binary": "바이너리",
-       "config-mysql-utf8": "UTF-8",
-       "config-mysql-charset-help": "<strong>바이너리 모드</strong>에서 미디어위키는 바이너리 필드의 데이터베이스에 UTF-8 텍스트를 저장합니다.\nMySQL의 UTF-8 모드보다 더 효율적이고, 유니코드 문자의 전체 범위를 사용할 수 있습니다.\n<strong>UTF-8 모드</strong>에서는 MySQL이 데이터를 사용하는 문자 집합을 알고 있기 때문에 적절하게 표현하고 변환할 수 있지만\n[https://ko.wikipedia.org/wiki/%EC%9C%A0%EB%8B%88%EC%BD%94%EB%93%9C_%ED%8F%89%EB%A9%B4#.EA.B8.B0.EB.B3.B8_.EB.8B.A4.EA.B5.AD.EC.96.B4_.ED.8F.89.EB.A9.B4 기본 다국어 평면] 밖에 있는 문자를 저장할 수 없습니다.",
        "config-mssql-auth": "인증 형식:",
        "config-mssql-install-auth": "설치 과정 중 데이터베이스에 연결하는 데 사용할 인증 형식을 선택하세요.\n\"{{int:config-mssql-windowsauth}}\"을 선택하시면 웹서버를 실행 중인 아무 사용자의 자격 증명이 사용됩니다.",
        "config-mssql-web-auth": "위키가 일반적인 작업을 수행하는 동안 데이터베이스 서버에 연결하는 데 사용할 인증 형식을 선택하세요.\n\n\"{{int:config-mssql-windowsauth}}\"을 선택하시면 웹서버를 실행 중인 아무 사용자의 자격 증명이 사용됩니다.",
        "config-install-interwiki-exists": "<strong>경고:</strong> 인터위키 테이블이 이미 항목을 갖고 있는 것 같습니다.\n기본 목록을 건너뜁니다.",
        "config-install-stats": "통계를 초기화하는 중",
        "config-install-keys": "보안 키를 만드는 중",
-       "config-insecure-keys": "<strong>경고:</strong> 설치 중에 생성한 {{PLURAL:$2|보안 키}} ($1)는 완전히 안전하지 {{PLURAL:$2|않습니다}}. 직접 바꾸는 것을 고려하세요.",
        "config-install-updates": "불필요한 업데이트 실행 방지",
        "config-install-updates-failed": "<strong>오류:</strong> 다음 오류로 테이블 안에 업데이트 키를 넣기에 실패했습니다: $1",
        "config-install-sysop": "관리자 사용자 계정을 만드는 중",
index 030cecf..5ac7ec6 100644 (file)
        "config-dbsupport-postgres": "* <i lang=\"en\">[{{int:version-db-postgres-url}} PostgreSQL]</i> es e bikannt Daatebangksüßtehm met offe Quälltäxde, un ed es och en Wahl nävve <i lang=\"en\">MySQL</i>. Et sinn_er ävver paa klein Fählersche bekannt, um mer künne et em Momang för et reschtijje Werke nit ämfähle. ([https://secure.php.net/manual/de/pgsql.installation.php Aanleidung för et Övversäze un Enreeschte von PHP met <i lang=\"en\">PostgreSQL</i> dobei, op Deutsch])",
        "config-dbsupport-sqlite": "* <i lang=\"en\">[{{int:version-db-sqlite-url}} SQLite]</i> es e eijfach Daatebangksüßtehm, wat joot en Schoß jehallde weed. ([http://www.php.net/manual/de/pdo.installation.php Aanleidong för et Övversäze un Enreeschte von PHP met <i lang=\"en\">SQLite</i> dobei, op Deutsch])",
        "config-dbsupport-oracle": "* <i lang=\"en\">[{{int:version-db-oracle-url}} Oracle]</i> es e jeschäfflesch Daatebangksüßtehm för Ferme. ([http://www.php.net/manual/de/oci8.installation.php Aanleidong för et Övversäze un Enreeschte von PHP met <i lang=\"en\" xml:lang=\"en\">OCI8</i> dobei, op Deutsch])",
-       "config-dbsupport-mssql": "* Dä <i lang=\"en\" xml:lang=\"en\">[{{int:version-db-mssql-url}} Microsoft SQL Server]</i> es e jeschäfflesch Dahtebangksüßtehm för Rääschner met <i lang=\"en\" xml:lang=\"en\">Windows</i>. ([Config-dbsupport-oracle/manual/de/sqlsrv.installation.php Aanleidong för et Övversäze un Enreeschte von <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"PHP Hypertext Preprocessor\">PHP</i> met <i lang=\"en\" xml:lang=\"en\">SQLSRV </i> dobei, op Deutsch])",
+       "config-dbsupport-mssql": "* Dä <i lang=\"en\" xml:lang=\"en\">[{{int:version-db-mssql-url}} Microsoft SQL Server]</i> es e jeschäfflesch Dahtebangksüßtehm för Rääschner met <i lang=\"en\" xml:lang=\"en\">Windows</i>. ([https://secure.php.net/manual/en/sqlsrv.installation.php Aanleidong för et Övversäze un Enreeschte von <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"PHP Hypertext Preprocessor\">PHP</i> met <i lang=\"en\" xml:lang=\"en\">SQLSRV </i> dobei, op Deutsch])",
        "config-header-mysql": "De Enshtällunge för de <i lang=\"en\">MySQL</i> Daatebangk",
        "config-header-postgres": "De Enshtällunge för de <i lang=\"en\">PostgreSQL</i> Daatebangk",
        "config-header-sqlite": "De Enshtällunge för de <i lang=\"en\">SQLite</i> Daatebangk",
        "config-mysql-myisam-dep": "'''Opjepaß:''' <i lang=\"en\">MyISAM</i> es als Speicher för <i lang=\"en\">MySQL</i> nit besönders joot för et Zosammeschpell met MediaWiki zo bruche:\n* Dorj_et kumplätte Sperre vun Tabälle, künne koum ens Saache parrallel en dä Daatebangk jedonn wääde.\n* Dat Fomaat es anfällesch för Probleme met de Daate.\n* Et weed vun MediaWiki nit ėmmer zopaß ongerschtöz.\n\nWann Ding <i lang=\"en\">MySQL</i> et Schpeischere en <i lang=\"en\">InnoDB</i>-Datteije ongerschtöze deiht, dom_mer dat nohdröcklesch ämfähle.\nKann dä ẞööver dat nit, künnd et joode jelääjeheit sin, dä ens op der neuste Schtand ze bränge.",
        "config-mysql-only-myisam-dep": "'''Opjepaß:''' <i lang=\"en\" xml:lang=\"en\">MyISAM</i> es de einzeje Zoot Schpeischerprojramm för <i lang=\"en\" xml:lang=\"en\">MySQL</i> op dä Maschiin. Di es nit för MediaWiki ze ämfähle es, weil:\n* wääje dem Schpärre vun jannze Tabälle sin koum paralleele Axjuhne en dä Daatebangk möjjelesch,\n* ed es aanfällesch för Probleeme met de Daate es, un\n* et weed vun MediaWiki nit emmer jood ongerschtöz.\n\nDing Enschtallazjuhn vum <i lang=\"en\" xml:lang=\"en\">MySQL</i> kann nit met <i lang=\"en\" xml:lang=\"en\">InnoDB</i> ömjonn.\nWi wöhr et med ene neuere Väsjohn vum <i lang=\"en\" xml:lang=\"en\">MySQL</i>?",
        "config-mysql-engine-help": "<strong>InnoDB</strong> es fö jewöhnlesch et beß, weil vill Zohjreffe op eijmohl joot ongershtöz wääde.\n\n<strong>MyISAM</strong> es flöcker op Rääschnere met bloß einem Minsch draan, un bei Wikis, di mer bloß lässe un nit schrieeve kann.\nMyISAM-Daatebangke han em Schnett mih Fähler un jon flöcker kappott, wi InnoDB-Daatebangke.",
-       "config-mysql-charset": "Dä Daatebangk iere Zeischesaz:",
-       "config-mysql-binary": "binär",
-       "config-mysql-utf8": "UTF-8",
-       "config-mysql-charset-help": "Beim Schpeischere em <strong>binähre Fomaht</strong> deiht MehdijaWikki Täx, dä em <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"Däm Unicode singe Universal Coded Character Set + Transformation Format—8-Bit\">UTF-8</i>-Fommaht kütt, en singer Dahtebangk en binähr kodehrte Dahtefälder faßhallde.\nDad_es flöcker un spahsamer wi et <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"Däm Unicode singe Universal Coded Character Set + Transformation Format—8-Bit\">UTF-8</i>-Fommaht vum <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\">MySQL</i> un määd_et müjjelesch, jehdes <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"a standard for the consistent encoding, representation, and handling of text expressed in most of the world's writing systems\">UNICODE</i>-Zeische met faßzehallde.\n\nBeim Schpeischere em <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"Däm Unicode singe Universal Coded Character Set + Transformation Format—8-Bit\">UTF-8</i> deihd_et <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\">MySQL</i> der Zeijschesaz un de Kodehrung vun dä Dahte känne, un kann se akeraht aanzeije un ömwandelle,\nallerdengs künne kein Zeische ußerhalv vum [https://de.wikipedia.org/wiki/Basic_Multilingual_Plane#Gliederung_in_Ebenen_und_Bl.C3.B6cke jrundlähje Knubbel för vill Schprohche (<i lang=\"en\" xml:lang=\"en\" dir=\"ltr\">Basic Multilingual Plane — BMP</i>)] afjeschpeischert wähde.",
        "config-mssql-auth": "De Zoot Aanmäldong:",
        "config-mssql-install-auth": "Söhk us, wi dat Aanmälde aan dä Daatebangk vor sesch jonn sull för de Enschtallazjuhn.\nWann De <em>{{int:Config-mssql-windowsauth}}</em> nemms, weed jenumme, met wat emmer dä Wäbßööver aam loufe es.",
        "config-mssql-web-auth": "Söhk us, wi dat Aanmälde aan dä Daatebangk vör sesch jonn sull för de nommaale Ärbeid vum Wiki.\nWann De <em>{{int:Config-mssql-windowsauth}}</em> nemms, weed dat jenumme, wohmet dä Wäbßööver aam loufe es.",
        "config-install-interwiki-exists": "'''Opjepaß''': En der Engewiki-Tabäll schingk alt jät dren ze shtonn.\nDoh dom_mer nix dobei.",
        "config-install-stats": "De Shtatestek-Zahle wääde op Aanfang jeshtallt.",
        "config-install-keys": "Jeheime Schlößel wääde opjebout.",
-       "config-insecure-keys": "'''Opjepaß:''' {{PLURAL:$2|Ene jeheime Schlößel|Jeheim Schlößele|Keine jeheime Schlößel}} ($1) {{PLURAL:$2|es|sin|es}} automattesch aanjelaat woode. {{PLURAL:$2|Dä es|Di sin|Hä es}} ävver nit onbedengk janz sescher. Övverlääsch Der, {{PLURAL:$2|dä|di|en}} norr_ens vun Hand ze ändere.",
        "config-install-updates": "Donn kein onnühdeje Änderonge maache.",
        "config-install-updates-failed": "<strong>Dä:</strong> Schlößßelle för et Ändere en Tabälle  bränge es donävve jajange. Jemäldt wood: $1",
        "config-install-sysop": "Dä Zohjang för der Wiki-Köbes weed aanjelaat.",
index ea8c6a6..a6d5fda 100644 (file)
@@ -41,7 +41,6 @@
        "config-db-web-account": "Hesabê danegehê bô têgihiştina tora înternetê",
        "config-mysql-innodb": "InnoDB",
        "config-mysql-myisam": "MyISAM",
-       "config-mysql-utf8": "UTF-8",
        "config-site-name": "Navê wîkiyê:",
        "config-site-name-blank": "Navê malperek têkeve.",
        "config-ns-generic": "Proje",
index a5f9ddd..7980ca7 100644 (file)
        "config-sqlite-dir": "Repertoire vun den SQLite-Donnéeën",
        "config-oracle-def-ts": "Standard 'tablespace':",
        "config-oracle-temp-ts": "Temporären 'tablespace':",
-       "config-type-mysql": "MySQL (oder kompatibel)",
+       "config-type-mysql": "MariaDB, MySQL, oder kompatibel",
        "config-type-postgres": "PostgreSQL",
        "config-type-sqlite": "SQLite",
        "config-type-oracle": "Oracle",
        "config-type-mssql": "Microsoft SQL Server",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] ass e beléiften Open-Source-Datebanksystem an eng Alternativ zu MySQL. ([Config-dbsupport-oracle/manual/de/pgsql.installation.php Uleedung fir d'Kompilatoun vu PHP mat PostgreSQL-Ënnerstëtzung])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] ass e beléiften Open-Source-Datebanksystem an eng Alternativ zu MySQL. ([https://secure.php.net/manual/en/pgsql.installation.php Uleedung fir d'Kompilatoun vu PHP mat PostgreSQL-Ënnerstëtzung])",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] ass eng kommerziell Datebank-Software. ([http://www.php.net/manual/en/oci8.installation.php How to compile PHP mat OCI8 Ënnerstëtzung])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] ass eng kommerziell Datebank-Software fir Windows. ([Config-dbsupport-oracle/manual/en/sqlsrv.installation.php Wéi PHP mat SQLSRV Ënnerstëtzung kompiléieren])",
-       "config-header-mysql": "MySQL-Astellungen",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] ass eng kommerziell Datebank-Software fir Windows. ([https://secure.php.net/manual/en/sqlsrv.installation.php Wéi PHP mat SQLSRV Ënnerstëtzung kompiléieren])",
+       "config-header-mysql": "MariaDB/MySQL-Astellungen",
        "config-header-postgres": "PostgreSQL-Astellungen",
        "config-header-sqlite": "SQLite-Astellungen",
        "config-header-oracle": "Oracle-Astellungen",
        "config-db-web-account": "Datebankkont fir den Accès iwwer de Web",
        "config-db-web-account-same": "Dee selwechte Kont wéi bei der Installatioun benotzen",
        "config-db-web-create": "De Kont uleeë wann et e net scho gëtt",
-       "config-mysql-innodb": "InnoDB",
+       "config-mysql-innodb": "InnoDB (recommandéiert)",
        "config-mysql-myisam": "MyISAM",
-       "config-mysql-binary": "binär",
-       "config-mysql-utf8": "UTF-8",
        "config-mssql-auth": "Typ vun der Authentifikatioun:",
        "config-mssql-sqlauth": "SOL-Server-Authentifikatioun",
        "config-mssql-windowsauth": "Windows-Authentifikatioun",
index 01884d9..421279c 100644 (file)
@@ -50,7 +50,7 @@
        "config-unicode-using-intl": "Adoeuvia [https://pecl.php.net/intl l'estenscion PECL intl] pe-a normalizzaçion Unicode.",
        "config-unicode-pure-php-warning": "'''Attençion:''' [https://pecl.php.net/intl l'estenscion PECL intl] a no l'è disponibile pe gestî a normalizzaçion Unicode, quindi se torna a-a lenta implementaçion in PHP puo.\nSe ti esegui un scito a ato traffego, ti doviesci leze arcun-e conscidiaçioin in sciâ [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations normalizzaçion Unicode].",
        "config-unicode-update-warning": "'''Attençion:''' a verscion installaa do gestô pe-a normalizzaçion Unicode a l'adoeuvia una vegia verscion da libraia [http://site.icu-project.org/ do progetto ICU].\nTi doviesci [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations aggiornâ] se ti voeu doeuviâ l'Unicode.",
-       "config-no-db": "Imposcibile trovâ un driver adatto pe-o database! L'è necessaio installâ un driver pe PHP.\n{{PLURAL:$2|O seguente formato de database o l'è supportou|I seguenti formati de database son supportæ}}: $1.\n\nSe ti compilli PHP aotonomamente, riconfiguilo attivando un client database, presempio utilizzando <code>./configure --with-mysqli</code>.\nQualoa t'avesci installou PHP pe mezo de 'n pacchetto Debian ò Ubuntu, alloa ti devi installâ o pacchetto <code>php5-mysql</code> ascì.",
+       "config-no-db": "Imposcibile trovâ un driver adatto pe-o database! L'è necessaio installâ un driver pe PHP.\n{{PLURAL:$2|O seguente formato de database o l'è supportou|I seguenti formati de database son supportæ}}: $1.\n\nSe ti compilli PHP aotonomamente, riconfiguilo attivando un client database, presempio utilizzando <code>./configure --with-mysqli</code>.\nQualoa t'avesci installou PHP pe mezo de 'n pacchetto Debian ò Ubuntu, alloa ti devi installâ o pacchetto <code>php-mysql</code> ascì.",
        "config-outdated-sqlite": "'''Atençion''': ti g'hæ SQLite $1, ma te ghe voeu comme minnimo a verscion $2. SQLite o no saiâ disponibile.",
        "config-no-fts3": "'''Atençion''': SQLite o l'è compilou sença o [//sqlite.org/fts3.html modulo FTS3], e fonçioin de çerchia no saian disponibile insce sto motô.",
        "config-pcre-old": "<strong>Fatale:</strong> se richiede PCRE  $1 o succescivo.\nO to PHP binaio o l'è conligou con PCRE $2.\n[https://www.mediawiki.org/wiki/Manual:Errors_and_symptoms/Ciu informaçioin insce PCRE].",
        "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] o l'è un popolare scistema de database open source comme alternativa a MySQL. ([https://secure.php.net/manual/en/pgsql.installation.php Comme compilâ PHP con suporto PostgreSQL])",
        "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] o l'è un scistema de database leggio, ch'o l'è suportou molto ben. ([http://www.php.net/manual/en/pdo.installation.php Comme compilâ PHP con suporto SQLite], o l'utilizza PDO)",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] o l'è un database de un'impreiza comerciâ. ([http://www.php.net/manual/en/oci8.installation.php Comme compilâ PHP con suporto OCI8])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] o l'è un database de un'impreiza commerciâ per Windows. ([Config-dbsupport-oracle/manual/en/sqlsrv.installation.php Comme compilâ PHP con supporto SQLSRV])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] o l'è un database de un'impreiza commerciâ per Windows. ([https://secure.php.net/manual/en/sqlsrv.installation.php Comme compilâ PHP con supporto SQLSRV])",
        "config-header-mysql": "Impostaçioin MySQL",
        "config-header-postgres": "Impostaçioin PostgreSQL",
        "config-header-sqlite": "Impostaçioin SQLite",
        "config-mysql-myisam-dep": "<strong>Atençion:</strong> t'hæ seleçionou MyISAM comme motô d'archiviaçion pe MySQL, ch'o no l'è racomandou pe l'uso con  MediaWiki, percose:\n* o supporta debolmente a concorença pe-o blocco da tabella\n* o l'è ciu inclinou a-a corruçion di atri motoî\n* o codiçe de base MediaWiki o no gestisce sempre MyISAM comm'o doviæ\n\nSe a to instalaçion MySQL a supporta InnoDB, l'è atamente racomandou che ti o çerni a-o so posto.\nSe a to installaçion MySQL a no supporta InnoDB, foscia l'è o momento pe 'n agiornamento.",
        "config-mysql-only-myisam-dep": "<strong>Atençion:</strong> MyISAM o l'è l'unnico motô d'archiviaçion disponibbile pe MySQL insce sta macchina, e questo no l'è consegiou pe doeuviâlo con MediaWiki, percose:\n* o supporta debolmente a concorenza pe-o blocco da tabella\n* o l''è ciu inclinou a-a corruçion di atri motoî\n* o coddiçe de base MediaWiki MyISAM  o no-o gestisce sempre comm'o doviæ\n\nS'a to installaçion MySQL a no supporta InnoDB, foscia l'è o momento pe 'n agiornamento.",
        "config-mysql-engine-help": "<strong>InnoDB</strong> o l'è quæxi sempre a megio opçion, in quante o g'ha 'n bon supporto da concorença.\n\n<strong>MyISAM</strong> o poriæ vese ciu veloçe inte installaçioin mono-utente ò in sola-lettua.\nI database MyISAM tendan a dannezâse ciu soventi di database InnoDB.",
-       "config-mysql-charset": "Set di caratteri do database:",
-       "config-mysql-binary": "Binaio",
-       "config-mysql-utf8": "UTF-8",
-       "config-mysql-charset-help": "In <strong>modalitæ binaia</strong>, MediaWiki a l'archivvia o testo UTF-8 into database in campi binai.\nQuest'o l'è ciu efficaçe che a modalitæ UTF-8 do MySQL, e o consente de doeuviâ a gamma completa de caratteri Unicode.\n\nIn <strong>modalitæ UTF-8</strong>, MySQL o saviâ inte quæ set de caratteri l'è che son i to dæti, e o poriâ presentâli e convertîli in moddo apropiou, ma o no te permetiâ de memorizâ i caratteri de d'ato a-o [https://en.wikipedia.org/wiki/Mapping_of_Unicode_character_planes Cian de base murtilenguistego].",
        "config-mssql-auth": "Tipo d'aotenticaçion:",
        "config-mssql-install-auth": "Seleçion-a o tipo d'aotenticaçion ch'o saiâ doeuviou pe conettise a-o database durante o processo de instalaçion.\nSe ti seleçion-i \"{{int:config-mssql-windowsauth}}\", saiâ doeuviou e credençiæ de quæ se segge utente segge aproeuv'a fâ giâ o serviou web.",
        "config-mssql-web-auth": "Seleçion-a o tipo d'aotenticaçion che o serviou web o doeuviâ pe conettise a-o database. \nSe ti seleçion-i \"{{int:config-mssql-windowsauth}}\", saiâ doeuviou e credençiæ de quæ se segge utente segge aproeuv'a fâ giâ o serviou web.",
        "config-install-interwiki-exists": "'''Atençion:''' pâ che inta tabella interwiki ghe segge za di elementi.\nA lista predefinia a se sata.",
        "config-install-stats": "Iniçializaçion de statisteghe",
        "config-install-keys": "Generaçion de ciave segrette",
-       "config-insecure-keys": "'''Atençion:''' {{PLURAL:$2|Una ciave segûa|De ciave segûe}} ($1) {{PLURAL:$2|generâ|generæ}} durante l'instalaçion {{PLURAL:$2|a|}} no {{PLURAL:$2|l'è|son}} completamente {{PLURAL:$2|segûa|segûe}}. Consciddera de cangiâ{{PLURAL:$2|la|le}} manoalmente.",
        "config-install-updates": "Impedî l'esecuçion di agiornamenti non necessai",
        "config-install-updates-failed": "<strong>Erô:</strong> l'inseimento de ciave de agiornamento inte tabelle o no l'è ariescio pe-o seguente erô: $1",
        "config-install-sysop": "Creaçion de l'utença pe l'aministratô",
index 3d9830b..fe1888d 100644 (file)
@@ -5,7 +5,8 @@
                        "Mantak111",
                        "Zygimantus",
                        "Hugo.arg",
-                       "Homo"
+                       "Homo",
+                       "Manvydasz"
                ]
        },
        "config-desc": "MediaWiki diegimas",
@@ -55,7 +56,7 @@
        "config-apc": "[https://secure.php.net/apc APC] yra įdiegtas",
        "config-apcu": "[https://secure.php.net/apcu APCu] yra įdiegtas",
        "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] yra įdiegtas",
-       "config-no-cache-apcu": "<strong>Įspėjimas:</strong> Nepavyko rasti [https://secure.php.net/apcu APCu], [http://xcache.lighttpd.net/ XCache] or [https://www.iis.net/downloads/microsoft/wincache-extension WinCache].\nObjekto spartinimas neįjungtas.",
+       "config-no-cache-apcu": "<strong>Įspėjimas:</strong> Nepavyko rasti [https://secure.php.net/apcu APCu], [http://xcache.lighttpd.net/ XCache] ar [https://www.iis.net/downloads/microsoft/wincache-extension WinCache].\nObjekto spartinimas neįjungtas.",
        "config-diff3-bad": "GNU diff3 nerastas.",
        "config-git": "Rasta Git versijų kontrolės sistema: <code>$1</code>.",
        "config-imagemagick": "Rastas „ImageMagick“: <code>$1</code>.\nPaveikslėlių miniatiūrizavimas bus įjungtas, jeigu įgalinsite vaizdų įkėlimą.",
        "config-mysql-engine": "Saugojimo variklis:",
        "config-mysql-innodb": "InnoDB",
        "config-mysql-myisam": "MyISAM",
-       "config-mysql-charset": "Duomenų bazės simbolių rinkinys:",
-       "config-mysql-binary": "Dvejetainis",
-       "config-mysql-utf8": "UTF-8",
        "config-mssql-auth": "Autentifikavimo tipas:",
        "config-mssql-sqlauth": "SQL Serverio autentifikavimas",
        "config-mssql-windowsauth": "Windows autentifikavimas",
index ccf733e..baa6e49 100644 (file)
@@ -44,7 +44,6 @@
        "config-header-mssql": "Microsoft SQL servera iestatījumi",
        "config-mysql-innodb": "InnoDB",
        "config-mysql-myisam": "MyISAM",
-       "config-mysql-utf8": "UTF-8",
        "config-mssql-windowsauth": "Windows Autentifikācija",
        "config-ns-generic": "Projekts",
        "config-ns-site-name": "Tāds pats kā viki nosaukums: $1",
index 1331d84..1554f40 100644 (file)
@@ -53,7 +53,7 @@
        "config-unicode-using-intl": "Со додатокот [https://pecl.php.net/intl intl PECL] за уникодна нормализација.",
        "config-unicode-pure-php-warning": "'''Предупредување''': Додатокот [https://pecl.php.net/intl intl PECL] не е достапен за врши уникодна нормализација, враќајќи се на бавна примена на чист PHP.\n\nАко имате високопрометно мрежно место, тогаш ќе треба да прочитате повеќе за [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations уникодната нормализација].",
        "config-unicode-update-warning": "'''Предупредување:''' Воспоставената верзија на обвивката за уникодна нормализација користи постара верзија на библиотеката на [http://site.icu-project.org/ проектот ICU].\nЗа да користите Уникод, ќе треба да направите [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations надградба].",
-       "config-no-db": "Не можев да најдам соодветен двигател за базата на податоци! Ќе треба да воспоставите двигател за PHP-база.\n{{PLURAL:$2|Поддржан се следниов вид|Поддржани се следниве видови}} бази: $1.\n\nДоколку самите го срочивте овој PHP, овозможете го базниот клиент во поставките — на пр. со <code>./configure --with-mysqli</code>.\nАко овој PHP го воспоставите од пакет на Debian или Ubuntu, тогаш ќе треба исто така да го воспоставите, на пр., пакетот <code>php5-mysql</code>.",
+       "config-no-db": "Не можев да најдам соодветен двигател за базата на податоци! Ќе треба да воспоставите двигател за PHP-база.\n{{PLURAL:$2|Поддржан се следниов вид|Поддржани се следниве видови}} бази: $1.\n\nДоколку самите го срочивте овој PHP, овозможете го базниот клиент во поставките — на пр. со <code>./configure --with-mysqli</code>.\nАко овој PHP го воспоставите од пакет на Debian или Ubuntu, тогаш ќе треба исто така да го воспоставите, на пр., пакетот <code>php-mysql</code>.",
        "config-outdated-sqlite": "'''Предупредување''': имате SQLite $1. Најстарата допуштена верзија е $2. Затоа, SQLite ќе биде недостапен.",
        "config-no-fts3": "'''Предупредување''': SQLite iе составен без модулот [//sqlite.org/fts3.html FTS3] - за оваа база нема да има можност за пребарување.",
        "config-pcre-old": "'''Кобно:''' Се бара PCRE $1 или понова верзија.\nВашиот PHP-бинарен е сврзан со PCRE $2.\n[https://www.mediawiki.org/wiki/Manual:Errors_and_symptoms/PCRE Повеќе информации].",
        "config-sqlite-dir-help": "SQLite ги складира сите податоци во една податотека.\n\nПапката што ќе ја наведете мора да е запислива од мрежниот опслужувач во текот на воспоставката.\n\nТаа '''не''' смее да биде достапна преку семрежјето, и затоа не ја ставаме кајшто ви се наоѓаат PHP-податотеките.\n\nВоспоставувачот воедно ќе создаде податотека <code>.htaccess</code>, но ако таа не функционира како што треба, тогаш некој ќе може да ви влезе во вашата необработена (сирова) база на податоци.\nТука спаѓаат необработени кориснички податоци (е-поштенски адреси, хеширани лозинки) како и избришани преработки и други податоци за викито до кои се има ограничен пристап.\n\nСе препорачува целата база да ја сместите некаде, како на пр. <code>/var/lib/mediawiki/вашетовики</code>.",
        "config-oracle-def-ts": "Стандарден таблеарен простор:",
        "config-oracle-temp-ts": "Привремен табеларен простор:",
-       "config-type-mysql": "MySQL (или складно)",
+       "config-type-mysql": "MariaDB, MySQL или складно",
        "config-type-postgres": "PostgreSQL",
        "config-type-sqlite": "SQLite",
        "config-type-oracle": "Oracle",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "МедијаВики ги поддржува следниве системи на бази на податоци:\n\n$1\n\nАко системот што сакате да го користите не е наведен подолу, тогаш проследете ја горенаведената врска со инструкции за да овозможите поддршка за тој систем.",
-       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] е главната цел на МедијаВики и најдобро е поддржан. МедијаВики работи и со [{{int:version-db-mariadb-url}} MariaDB] и [{{int:version-db-percona-url}} Percona], кои се складни со MySQL. ([https://secure.php.net/manual/en/mysqli.installation.php Како да срочите PHP со поддршка за MySQL])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] е популарен систем на бази на податоци со отворен код кој претставува алтернатива на MySQL ([Config-dbsupport-oracle/manual/en/pgsql.installation.php како да составите PHP со поддршка за PostgreSQL]). ([Config-dbsupport-oracle/manual/en/pgsql.installation.php Како да срочите PHP со поддршка за PostgreSQL])",
-       "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] е лесен систем за бази на податоци кој е многу добро поддржан. ([http://www.php.net/manual/en/pdo.installation.php Како да составите PHP со поддршка за SQLite], користи PDO)",
-       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] е база на податоци на комерцијално претпријатие. ([http://www.php.net/manual/en/oci8.installation.php Како да составите PHP со поддршка за OCI8])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server]  е база на податоци на комерцијално претпријатиe за Windows ([Config-dbsupport-oracle/manual/en/sqlsrv.installation.php How to compile PHP with SQLSRV поддршка])",
-       "config-header-mysql": "Нагодувања на MySQL",
+       "config-dbsupport-mysql": "* [{{int:version-db-mariadb-url}} MariaDB] е главната цел на МедијаВики и најдобро е поддржан. МедијаВики работи и со  [{{int:version-db-mysql-url}} MySQL] и [{{int:version-db-percona-url}} Percona], кои се складни со MariaDB. ([https://secure.php.net/manual/en/mysqli.installation.php Како да срочите PHP со поддршка за MySQL])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] е популарен систем на бази на податоци со отворен код кој претставува алтернатива на MySQL ([https://secure.php.net/manual/en/pgsql.installation.php како да составите PHP со поддршка за PostgreSQL]). ([https://secure.php.net/manual/en/pgsql.installation.php Како да срочите PHP со поддршка за PostgreSQL])",
+       "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] е лесен систем за бази на податоци кој е многу добро поддржан. ([https://secure.php.net/manual/en/pdo.installation.php Како да составите PHP со поддршка за SQLite], користи PDO)",
+       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] е база на податоци на комерцијално претпријатие. ([https://secure.php.net/manual/en/oci8.installation.php Како да составите PHP со поддршка за OCI8])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server]  е база на податоци на комерцијално претпријатиe за Windows ([https://secure.php.net/manual/en/sqlsrv.installation.php How to compile PHP with SQLSRV поддршка])",
+       "config-header-mysql": "Нагодувања на MariaDB/MySQL",
        "config-header-postgres": "Нагодувања на PostgreSQL",
        "config-header-sqlite": "Нагодувања на SQLite",
        "config-header-oracle": "Нагодувања на Oracle",
        "config-db-web-create": "Создај ја сметката ако веќе не постои",
        "config-db-web-no-create-privs": "Сметката што ја назначивте за воспоставка нема доволно привилегии за да може да создаде сметка.\nТука мора да назначите постоечка сметка.",
        "config-mysql-engine": "Складишен погон:",
-       "config-mysql-innodb": "InnoDB",
+       "config-mysql-innodb": "InnoDB (препорачано)",
        "config-mysql-myisam": "MyISAM",
        "config-mysql-myisam-dep": "'''Предупредување:''' Го одбравте MyISAM како складишен погон за MySQL. Но тој не се препорачува за МедијаВики бидејќи:\n* одвај поддржува едновременост поради заклучување на табелите\n* поподложен на расипување од другите погони\n* кодната база на МедијаВики не секогаш може да работи со MyISAM како што треба\n\nАко вашата воспоставка на MySQL поддржува InnoDB, тогаш сериозно препорачуваме да го користите него наместо MyISAM.\nАко вашата воспоставка на MySQL не поддржува InnoDB, веројатно дошло време за надградба.",
        "config-mysql-only-myisam-dep": "'''Предупредување:''' MyISAM е единствениот достапен складишен погон за MySQL на оваа машина, а ова не се препорачува за употреба со МедијаВики, бидејќи:\n* речиси не поддржува истовремено извршување на задачите поради заклучувањето на табелите\n* поподложен е на расипувања од другите погони\n* кодната база на МедијаВИки не секогаш работи исправно со MyISAM\nВашата воспоставка на MySQL не поддржува InnoDB. Можеби е време да ја надградите.",
        "config-mysql-engine-help": "'''InnoDB''' речиси секогаш е најдобар избор, бидејќи има добра поддршка за едновременост.\n\n'''MyISAM''' може да е побрз кај воспоставките наменети за само еден корисник или незаписни воспоставки (само читање).\nБазите на податоци од MyISAM почесто се расипуваат од базите на InnoDB.",
-       "config-mysql-charset": "Збир знаци за базата:",
-       "config-mysql-binary": "Бинарен",
-       "config-mysql-utf8": "UTF-8",
-       "config-mysql-charset-help": "Во '''бинарен режим''', во базата на податоци МедијаВики складира UTF-8 текст во бинарни полиња.\nОва е поефикасно отколку  TF-8 режимот на MySQL, и ви овозможува да ја користите целата палета на уникодни знаци.\n\nВо '''UTF-8 режим''', MySQL ќе знае на кој збир знаци припаѓаат вашите податоци, и може соодветно да ги претстави и претвори, но нема да ви дозволи да складиратезнаци над [https://en.wikipedia.org/wiki/Mapping_of_Unicode_character_planes Основната повеќејазична рамнина].",
        "config-mssql-auth": "Тип на заверка:",
        "config-mssql-install-auth": "Изберете го типот на заверка што ќе се користи за поврзување со базата на податоци во текот на воспоставката.\nАко изберете „{{int:config-mssql-windowsauth}}“, ќе се користат најавните податоци или корисникот како кој работи мрежниот опслужувач.",
        "config-mssql-web-auth": "Изберете го типот на заверка што мрежниот послужувач ќе го користи за поврзување со опслужувачот на базата во текот на редовната работа на викито.\nАко изберете „{{int:config-mssql-windowsauth}}“, ќе се користат најавните податоци или корисникот како кој работи мрежниот опслужувач.",
        "config-install-interwiki-exists": "'''Предупредување''': Табелата со интервикија веќе содржи ставки.\nГо прескокнувам основно-зададениот список.",
        "config-install-stats": "Ги подготвувам статистиките",
        "config-install-keys": "Создавање на тајни клучеви",
-       "config-insecure-keys": "'''Предупредување:''' {{PLURAL:$2|Безбедносниот клуч $1 создаден во текот на воспоставката не е сосем безбеден|Безбедносните клучеви $1 создадени во текот на воспоставката не се сосем безбедни}}. Ви препорачуваме да {{PLURAL:$2|го|ги}} смените рачно.",
        "config-install-updates": "Спречи вршење на непотребни поднови",
        "config-install-updates-failed": "<strong>Грешка:</strong> Вметнувањето на подновни клучеви во табелите не успеа, со следнава грешка: $1",
        "config-install-sysop": "Создавање на администраторска корисничка сметка",
index 79fd490..c1bbec0 100644 (file)
@@ -56,7 +56,6 @@
        "config-connection-error": "$1.\n\nതാഴെ നൽകിയിരിക്കുന്ന ഹോസ്റ്റ്, ഉപയോക്തൃനാമം, രഹസ്യവാക്ക് എന്നിവ പരിശോധിച്ച് വീണ്ടും ശ്രമിക്കുക.",
        "config-regenerate": "LocalSettings.php പുനഃസൃഷ്ടിക്കുക →",
        "config-mysql-engine": "സ്റ്റോറേജ് എൻജിൻ:",
-       "config-mysql-utf8": "യു.ടി.എഫ്.-8",
        "config-site-name": "വിക്കിയുടെ പേര്:",
        "config-site-name-help": "ഇത് ബ്രൗസറിന്റെ ടൈറ്റിൽ ബാറിലും മറ്റനേകം ഇടങ്ങളിലും പ്രദർശിപ്പിക്കപ്പെടും.",
        "config-site-name-blank": "സൈറ്റിന്റെ പേര് നൽകുക.",
index 41e678c..334d3a0 100644 (file)
@@ -98,9 +98,6 @@
        "config-mysql-innodb": "InnoDB",
        "config-mysql-myisam": "MyISAM",
        "config-mysql-only-myisam-dep": "<strong>Amaran:</strong> MyISAM ialah satu-satunya enjin storan yang terdapat untuk MySQL di mesin ini, dan penggunaannya dengan MediaWiki tidak digalakkan kerana:\n* ia tidak menyokong keserempakan (''concurrency'') disebabkan penguncian jadual\n* ia lebih terdedah kepada korupsi daripada enjin-enjin lain\n* pangkalan kod MediaWiki tidak sentiasa mengendalikan MyISAM seperti yang diharapkan\n\nPemasangan MySQL anda tidak menyokong InnoDB. Mungkin tiba masanya untuk naik taraf.",
-       "config-mysql-charset": "Peranggu aksara pangkalan data:",
-       "config-mysql-binary": "Perduaan",
-       "config-mysql-utf8": "UTF-8",
        "config-mssql-auth": "Jenis pengesahan:",
        "config-site-name": "Nama wiki:",
        "config-site-name-help": "Ini akan dipaparkan pada bar tajuk perisian pelayar dan tempat-tempat lain yang berkenaan.",
        "config-install-interwiki-list": "Fail <code>interwiki.list</code> tidak dapat dibaca.",
        "config-install-interwiki-exists": "<strong>Amaran:</strong> Jadual antara wiki nampaknya sudah ada entri. Senarai asali dilangkau.",
        "config-install-keys": "Menjana kunci-kunci rahsia",
-       "config-insecure-keys": "<strong>Amaran:</strong> {{PLURAL:$2|Kunci keselamatan|Kunci-kunci keselamatan}} ($1) yang dihasilkan sewaktu pemasangan itu {{PLURAL:$2|adalah}} tidak selamat sepenuhnya. Oleh itu, {{PLURAL:$2|ia}} wajar ditukar secara manual.",
        "config-install-sysop": "Membuka akaun pengguna pentadbir",
        "config-install-mainpage": "Mewujudkan laman utama dengan kandungan lalai",
        "config-help": "bantuan",
index ad1da47..c4cd28b 100644 (file)
@@ -42,9 +42,6 @@
        "config-db-web-create": "Oħloq il-kont jekk għadu ma jeżistix",
        "config-mysql-innodb": "InnoDB",
        "config-mysql-myisam": "MyISAM",
-       "config-mysql-charset": "Sett ta' karattri tad-databażi:",
-       "config-mysql-binary": "Binarju",
-       "config-mysql-utf8": "UTF-8",
        "config-site-name": "Isem tal-wiki:",
        "config-site-name-help": "Dan se jidher fil-barra tat-titlu tal-browżer u f'diversi postijiet oħra.",
        "config-site-name-blank": "Daħħal isem tas-sit.",
index f7cc024..c64a2cd 100644 (file)
@@ -35,8 +35,6 @@
        "config-apcu": "[https://secure.php.net/apcu APCu] نصب بیه.",
        "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] نصب بیه.",
        "config-diff3-bad": "GNU diff3 پیدا نیه.",
-       "config-mysql-binary": "باینری",
-       "config-mysql-utf8": "UTF-8",
        "config-mssql-auth": "نوع تأیید:",
        "config-ns-generic": "پروژه",
        "config-ns-other": "دیگه ( تعیین هاکنین)",
index 953b672..67c20e0 100644 (file)
@@ -51,7 +51,7 @@
        "config-unicode-using-intl": "用 [https://pecl.php.net/intl intl PECL 擴充套件] 做 Unicode 正規化。",
        "config-unicode-pure-php-warning": "<strong>Kéng-kò:</strong> Bô-hoat-tō͘ iōng [https://pecl.php.net/intl intl PECL extension] chhú-lí Unicode chèng-kui-hoà, só͘-í thè kàu iōng sûn PHP si̍t-chok--ê chèng-kui-hoà têng-sek, chit khoán hong-sek chhú-lí sok-tō͘ khah bān. Nā lí--ê bāng-chām liú-lám--ê lâng chiâⁿ chē, lí èng-kai ài khoàⁿ [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations/zh Unicode chèng-kui-hoà].",
        "config-unicode-update-warning": "<strong>警告</strong>:這馬安裝的 Unicode 正規化包裝程式用舊版 [http://site.icu-project.org/ ICU 計劃] 的程式庫。\n若你需要用 Unicode,你應該先進行 [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations 升級]。",
-       "config-no-db": "揣無適合的資料庫驅動程式!你需要安裝 PHP 資料庫驅動程式。\n這馬支援下跤類型的資料庫: $1 。\n\n若你是家己編譯 PHP,你需要重新設定並且開資料庫客戶端,譬如:用 <code>./configure --with-mysqli</code> 指令參數。\n如你是用 Debian 或 Ubuntu 的套件安裝,你著需要閣另外安裝,例:<code>php5-mysql</code> 套件。",
+       "config-no-db": "揣無適合的資料庫驅動程式!你需要安裝 PHP 資料庫驅動程式。\n這馬支援下跤類型的資料庫: $1 。\n\n若你是家己編譯 PHP,你需要重新設定並且開資料庫客戶端,譬如:用 <code>./configure --with-mysqli</code> 指令參數。\n如你是用 Debian 或 Ubuntu 的套件安裝,你著需要閣另外安裝,例:<code>php-mysql</code> 套件。",
        "config-outdated-sqlite": "<strong>Kéng-kò:</strong> Lí í-keng an-chng SQLite $1, m̄-koh i--ê pán-pún pí thang-chng--ê pán-pún $2 khah kū. Só͘-í lí bô-hoat-tō͘ ēng SQLite.",
        "config-no-fts3": "<strong>Kéng-kò: </strong> SQLite tī pian-e̍k--ê sî-chūn bô pau-koat  [//sqlite.org/fts3.html FTS3 module], āu-tâi chhiau-chhoē kong-lêng tiō ē bô-hoat-tō͘ iōng.",
        "mainpagetext": "'''MediaWiki已經裝好矣。'''",
index 377056f..6ba2375 100644 (file)
@@ -52,7 +52,7 @@
        "config-unicode-using-intl": "Aúsa [https://pecl.php.net/intl l'estensione PECL intl] pe' ne fà 'a normalizzazione Unicode.",
        "config-unicode-pure-php-warning": "<strong>Attenziò:</strong> L' [https://pecl.php.net/intl estensione intl PECL] nun è a disposizione pe' gestire 'a normalizzazione Unicode, accussì se ausasse n'imprementazziona llenta 'n puro PHP.\nSi state a gestire nu pizzo ad alto traffico, avisseve a lieggere cocche considerazione ncopp' 'a [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations normalizzaziona Unicode].",
        "config-unicode-update-warning": "<strong>Attenziò:</strong> 'A verziona installata 'e normalizzazione Unicode aùsa 'a verziona viecchia d' 'o [http://site.icu-project.org/ pruggetto ICU].\nV'avite 'a [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations agghiurnà] si state a penzà ncopp' 'o fatto d'ausà Unicode.",
-       "config-no-db": "Nun se può truvà nu driver adatto p' 'o database! È necessario installare nu driver p' 'o PHP.\n{{PLURAL:$2|'O furmato suppurtato|'E furmate suppurtate}} 'e database ccà annanze: $1.\n\nSi cumpilate PHP autonomamente, riaccunciatevello attivando nu client database, p'esempio ausannoo <code>./configure --with-mysqli</code>.\nQuanno fosse installato PHP pe' bbìa 'e nu pacchetto Debian o Ubuntu, allora avite 'a installà pure 'o pacchetto <code>php5-mysql</code>.",
+       "config-no-db": "Nun se può truvà nu driver adatto p' 'o database! È necessario installare nu driver p' 'o PHP.\n{{PLURAL:$2|'O furmato suppurtato|'E furmate suppurtate}} 'e database ccà annanze: $1.\n\nSi cumpilate PHP autonomamente, riaccunciatevello attivando nu client database, p'esempio ausannoo <code>./configure --with-mysqli</code>.\nQuanno fosse installato PHP pe' bbìa 'e nu pacchetto Debian o Ubuntu, allora avite 'a installà pure 'o pacchetto <code>php-mysql</code>.",
        "config-outdated-sqlite": "'''Attenziò''': tenite 'o SQLite $1 pe' tramente ca ce vulesse 'a verziona $2, SQLite nun sarrà a disposizione.",
        "config-no-fts3": "'''Attenziò''': SQLite è cumpilato senza 'o [//sqlite.org/fts3.html modulo FTS3], 'e funziune 'e p'ascià dinto nun sarranno a disposizione ncopp'a stu backend.",
        "config-pcre-old": "<strong>Errore fatale:</strong> s'addimanna PCRE  $1 o succiessivo.\n'O file vuosto binario PHP è acucchiato c' 'o PCRE $2.\n[https://www.mediawiki.org/wiki/Manual:Errors_and_symptoms/PCRE Cchiù nfurmaziune].",
        "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] è nu sistema canusciuto 'e database open source ca fosse n'alternativa a MySQL. Putess'avé cocch'errore p'arricettà, e nun è cunzigliato 'e ll'ausà dint'a n'ambiente 'e produziona. ([https://secure.php.net/manual/en/pgsql.installation.php Comme s'avess'a cumpilà PHP cu suppuorto PostgreSQL])",
        "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite]  è nu sistema 'e database leggero, ca fosse assaje buono suppurtato. ([http://www.php.net/manual/en/pdo.installation.php Comme cumpilà PHP cu suppuorto SQLite], aùsa PDO)",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] è nu database 'e na fraveca commerciale. ([http://www.php.net/manual/en/oci8.installation.php Comme cumpilà PHP cu suppuorto OCI8])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] è nu database 'e na fraveca commerciale p' 'o Windows. ([Config-dbsupport-oracle/manual/en/sqlsrv.installation.php Comme cumpilà PHP cu suppuorto SQLSRV])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] è nu database 'e na fraveca commerciale p' 'o Windows. ([https://secure.php.net/manual/en/sqlsrv.installation.php Comme cumpilà PHP cu suppuorto SQLSRV])",
        "config-header-mysql": "Mpustaziune MySQL",
        "config-header-postgres": "Mpustaziune PostgreSQL",
        "config-header-sqlite": "Mpustaziune SQLite",
        "config-mysql-myisam-dep": "<strong>Attenziò:</strong> avite scigliuto MyISAM comm' 'o mutore 'archiviaziona MySQL, ca nun è raccummannato pe' l'ausà cu MediaWiki, pecché:\n* supporta debolmente 'a concorrenza p' 'o blocco d' 'a tabbella\n* è cchiù inchine 'a corruzione 'e l'ati mutore\n* 'o codece 'e base 'e MediaWiki nun gestisce sempe MyISAM comme l'avess'a gistiunà\n\nSi ll'installazione vosta MySQL suppuorta InnoDB, è autamente raccummandato ca si scigliesse a 'o posto suo.\nSi 'a installazione MySQL nun suppurtasse InnoDB, forse è 'o mumento 'e ll'agghiurnà.",
        "config-mysql-only-myisam-dep": "<strong>Attenziò:</strong> MyISAM è l'uneco mutore p'astipà date ca se trova mo' a disposizione p' 'o MySQL dint'a sta macchina, e nun fosse raccumandato 'e s'ausà cu MediaWiki, pecché:\n* suppurtasse minimamente concorrenza pe' bbìa 'e bluccà tabbelle\n* è cchiù facile ca jesse a se scassà cchiù 'e l'ati mutore\n* 'o codece MediaWiki nun maniasse sempe MyISAM comme l'avesse 'e manià\n\nL'installazione MySQL nun suppurtasse InnoDB, può darse ca chist'è 'o mumento pe' ve ll'agghiurnà.",
        "config-mysql-engine-help": "<strong>InnoDB</strong> è quase sempe 'a meglia opzione, pecché ave nu buono suppuorto concorrente.\n\n<strong>MyISAM</strong> putesse ghì cchiù ampressa int'a na installazione mono-utente e liegge-surtanto.\n'E database MyISAM se scassano cchiù spisso d' 'e database InnoDB.",
-       "config-mysql-charset": "Nzieme 'e carattere d' 'o database:",
-       "config-mysql-binary": "Binario",
-       "config-mysql-utf8": "UTF-8",
-       "config-mysql-charset-help": "Int'a <strong>modalità binaria</strong>, MediaWiki archiviasse 'o testo UTF-8 dint' 'o database a campe binarie.\nChest'è cchiù efficiente rispetto 'a modalità UTF-8 'e MySQL, e ve cunzente d'ausà 'a gamma cumpreta 'e carattere Unicode.\n\nInt'a <strong>modalità UTF-8</strong>, MySQL canoscesse dint'a quale set 'e carattere ce stanno 'e date vuoste, e putesse presentà e scagnà sti date int'a nu modo appropriato, ma nun ve premmettesse 'e dà memoria a 'e carattere ncopp' 'o [https://en.wikipedia.org/wiki/Mapping_of_Unicode_character_planes Piano base Multilengua].",
        "config-mssql-auth": "Tipo d'autenticazione:",
        "config-mssql-install-auth": "Sceglie 'o tipo d'autenticazziona ca s'ausarrà pe cunnettà â database, durante ll'operazziona d'istallazziona. Si piglie \"{{int:config-mssql-windowsauth}}\", 'e credenziale 'e qualunque fosse ll'utenza ca 'o webserver sta pruciessanno sarranno ausate.",
        "config-mssql-web-auth": "Sceglie 'o tipo d'autenticazziona ca 'o web server pigliarrà pe se cunnettà a 'o server 'e bbase 'e dati, durante ll'operazziona nurmale d' 'a wiki.\nSi piglie \"{{int:config-mssql-windowsauth}}\", 'e credenziale 'e qualunque fosse ll'utenza ca 'o webserver sta pruciessanno sarranno ausate.",
        "config-install-interwiki-exists": "'''Attenziò:''' 'a tabbella interwiki pare ca cuntenesse già elemente.\nZumpann' 'a lista predefinita.",
        "config-install-stats": "Inizializzaziona d' 'e statistiche",
        "config-install-keys": "Generaziona d' 'e chiave segrete",
-       "config-insecure-keys": "'''Attenziò:''' {{PLURAL:$2|Na chiave sicura|'E chiave sicure}} ($1) {{PLURAL:$2|generata|generate}} pe' tramente ca se fà l'installazione nun {{PLURAL:$2|è|songo}} completamente {{PLURAL:$2|sicura|sicure}}. Cunziderate d' {{PLURAL:$2|'a|'e}} cagnà manualmente.",
        "config-install-updates": "Mpiccià ll'agghiurnamiente ca nun fossero necessarie",
        "config-install-updates-failed": "<strong>Errore:</strong> l'inserimento d' 'e chiave 'agghiurnamiento dint' 'e tabbelle nun è asciuto pecché se cunfermaje l'errore ccà annanze: $1",
        "config-install-sysop": "Crianno nu cunto utente ammenistratore",
index e4e837d..1e88f7b 100644 (file)
@@ -58,7 +58,7 @@
        "config-unicode-using-intl": "Bruker [https://pecl.php.net/intl intl PECL-utvidelsen] for Unicode-normalisering.",
        "config-unicode-pure-php-warning": "'''Advarsel''': [https://pecl.php.net/intl intl PECL-utvidelsen] er ikke tilgjengelig for å håndtere Unicode-normaliseringen, faller tilbake til en langsommere ren-PHP-implementasjon.\nOm du kjører et nettsted med høy trafikk bør du lese litt om [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations Unicode-normalisering].",
        "config-unicode-update-warning": "<strong>Advarsel:</strong> Den installerte versjonen av Unicode-normalisereren bruker en eldre versjon av [http://site.icu-project.org/ ICU-prosjektets] bibliotek.\nDu bør [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations oppgradere] om du er bekymret for å bruke Unicode.",
-       "config-no-db": "Fant ingen passende databasedriver! Du må installere en databasedriver for PHP.\nFølgende {{PLURAL:$2|databasetype|databasetyper}} støttes: $1\n\nOm du kompilerte PHP selv, rekonfigurer den med en aktivert databaseklient, for eksempel ved å bruke <code>./configure --with-mysqli</code>.\nOm du installerte PHP fra en Debian- eller Ubuntu-pakke, må du også installere for eksempel <code>php5-mysql</code>-pakken.",
+       "config-no-db": "Fant ingen passende databasedriver! Du må installere en databasedriver for PHP.\nFølgende {{PLURAL:$2|databasetype|databasetyper}} støttes: $1\n\nOm du kompilerte PHP selv, rekonfigurer den med en aktivert databaseklient, for eksempel ved å bruke <code>./configure --with-mysqli</code>.\nOm du installerte PHP fra en Debian- eller Ubuntu-pakke, må du også installere for eksempel <code>php-mysql</code>-pakken.",
        "config-outdated-sqlite": "'''Advarsel''': Du har SQLite $1, som er en eldre versjon enn minimumskravet SQLite $2. SQLite vil ikke være tilgjengelig.",
        "config-no-fts3": "'''Advarsel''': SQLite er kompilert uten [//sqlite.org/fts3.html FTS3-modulen], søkefunksjoner vil ikke være tilgjengelig på dette bakstykket.",
        "config-pcre-old": "'''Alvorlig:''' PCRE $1 eller senere kreves.\nDin PHP-kode er lenket med PCRE $2.\n[https://www.mediawiki.org/wiki/Manual:Errors_and_symptoms/PCRE Nærmere informasjon].",
        "config-sqlite-dir-help": "SQLite lagrer alle data i en enkelt fil.\n\nMappen du oppgir må være skrivbar for nettjeneren under installasjonen.\n\nDen bør '''ikke''' være tilgjengelig fra nettet, dette er grunnen til at vi ikke legger det der PHP-filene dine er.\n\nInstallasjonsprogrammet vil skrive en <code>.htaccess</code>-fil sammen med det, men om det mislykkes kan noen få tilgang til din råe database. Dette inkluderer rå brukerdata (e-postadresser, hashede passord) samt slettede revisjoner og andre begrensede data på wikien.\n\nVurder å plassere databasen et helt annet sted, for eksempel i <code>/var/lib/mediawiki/yourwiki</code>.",
        "config-oracle-def-ts": "Standard tabellrom:",
        "config-oracle-temp-ts": "Midlertidig tabellrom:",
-       "config-type-mysql": "MySQL (eller kompatibelt)",
+       "config-type-mysql": "MariaDB, MySQL eller kompatibel",
        "config-type-postgres": "PostgreSQL",
        "config-type-sqlite": "SQLite",
        "config-type-oracle": "Oracle",
        "config-type-mssql": "Microsoft SQLServer",
        "config-support-info": "MediaWiki støtter følgende databasesystem:\n\n$1\n\nHvis du ikke ser databasesystemet du prøver å bruke i listen nedenfor, følg instruksjonene det er lenket til over for å aktivere støtte.",
-       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] er den prefererte databasen for MediaWiki og er derfor best støttet.  MediaWiki fungerer også med [{{int:version-db-mariadb-url}} MariaDB] og [{{int:version-db-percona-url}} Percona Server], som begge er MySQL-kompatible. ([https://secure.php.net/manual/en/mysqli.installation.php Hvordan kompilere med PHP med MySQL-støtte])",
+       "config-dbsupport-mysql": "* [{{int:version-db-mariadb-url}} MariaDB] er den foretrukne databasetypen for MediaWiki og har best støtte.  MediaWiki fungerer også med [{{int:version-db-mysql-url}} MySQL] og [{{int:version-db-percona-url}} Percona Server], som begge er MariaDB-kompatible. ([https://secure.php.net/manual/en/mysqli.installation.php Hvordan kompilere PHP med MySQL-støtte])",
        "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] er et populært åpen kildekode-databasesystem og et alternativ til MySQL.  ([https://secure.php.net/manual/en/pgsql.installation.php Hvordan kompilere PHP med PostgreSQL-støtte])",
        "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] er et lettvekts-databasesystem som har veldig god støtte. ([http://www.php.net/manual/en/pdo.installation.php Hvordan kompilere PHP med SQLite-støtte], bruker PDO)",
-       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] er en kommersiell database for bedrifter. ([http://www.php.net/manual/en/oci8.installation.php Hvordan kompilere PHP med OCI8-støtte])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQLServer] er en kommersiell enterprise-database for Windows. ([Config-dbsupport-oracle/manual/en/sqlsrv.installation.php Hvordan kompilere PHP med SQLSRV-støtte])",
-       "config-header-mysql": "MySQL-innstillinger",
+       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] er en kommersiell database for bedrifter. ([https://secure.php.net/manual/en/oci8.installation.php Hvordan kompilere PHP med OCI8-støtte])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] er et kommersielt databasesystem under Windows for bedrifter. ([https://secure.php.net/manual/en/sqlsrv.installation.php Hvordan kompilere PHP med SQLSRV-støtte])",
+       "config-header-mysql": "MariadB/MySQL-innstillinger",
        "config-header-postgres": "PostgreSQL-innstillinger",
        "config-header-sqlite": "SQLite-innstillinger",
        "config-header-oracle": "Oracle-innstillinger",
        "config-db-web-create": "Opprett kontoen om den ikke finnes allerede",
        "config-db-web-no-create-privs": "Kontoen du oppga for installasjonen har ikke nok privilegier til å opprette en konto.\nKontoen du oppgir her må finnes allerede.",
        "config-mysql-engine": "Lagringsmotor:",
-       "config-mysql-innodb": "InnoDB",
+       "config-mysql-innodb": "InnoDB (anbefalt)",
        "config-mysql-myisam": "MyISAM",
        "config-mysql-myisam-dep": "'''Advarsel:''' Du har valgt MyISAM som lagringsmotor for MySQL, noe som ikke er anbefalt for bruk med MediaWiki, fordi:\n* den knapt støtter samtidighet pga. tabell-låsing\n* den har større tilbøyelighet for å bli korrupt enn andre motorer\n* MediaWiki-koden håndterer ikke alltid MyISAM som den burde\n\nHvis din MySQL-installasjon støtter InnoDB, er det sterkt å anbefale at du i stedet velger den.\nHvis din MySQL-installasjon ikke støtter InnoDB, kan det være på tide med en oppgradering.",
        "config-mysql-only-myisam-dep": "'''Advarsel:''' MyISAM er den eneste tilgjengelig lagringsmotoren for MySQL på denne maskinen, og det er ikke anbefalt brukt for MediaWiki, fordi:\n* den knapt støtter samtidighet pga. tabell-låsing\n* den har større tilbøyelighet for å bli korrupt enn andre motorer\n* MediaWiki-koden håndterer ikke alltid MyISAM som den burde\n\nHvis din MySQL-installasjon ikke støtter InnoDB, kan det være på tide med en oppgradering.",
        "config-mysql-engine-help": "'''InnoDB''' er nesten alltid det beste alternativet siden den har god støtte for samtidighet («concurrency»).\n\n'''MyISAM''' kan være raskere i enbruker- eller les-bare-installasjoner.\nMyISAM-databaser har en tendens til å bli ødelagt oftere enn InnoDB-databaser.",
-       "config-mysql-charset": "Databasetegnsett:",
-       "config-mysql-binary": "Binær",
-       "config-mysql-utf8": "UTF-8",
-       "config-mysql-charset-help": "I '''binary mode''' lagrer MediaWiki UTF-8 tekst til databasen i binærfelt.\nDette er mer effektivt enn MySQLs UTF-8 modus og tillater deg å bruke hele spekteret av Unicode-tegn.\n\nI '''UTF-8 mode''' vil MySQL vite hvilket tegnsett dataene dine er i og kan presentere og konvertere det på en riktig måte,\nmen det vil ikke la deg lagre tegn over «[https://en.wikipedia.org/wiki/Mapping_of_Unicode_character_planes the Basic Multilingual Plane]».",
        "config-mssql-auth": "Autentiseringstype:",
        "config-mssql-install-auth": "Valg autentiseringstypen som skal brukes for å koble til databasen under installeringsprosessen. Hvis du velger «{{int:config-mssql-windowsauth}}», vil påloggingsinformasjonen for brukeren som kjører webtjeneren blir brukt.",
        "config-mssql-web-auth": "Velg autentiseringstype som webtjeneren vil bruke for å koble til databasetjeneren under normal kjøring av wikien.\nHvis du velger «{{int:config-mssql-windowsauth}}», vil påloggingsinformasjonen til brukeren som kjører webtjeneren blir brukt.",
        "config-license-help": "Mange åpne wikier legger alle bidrag under en [https://freedomdefined.org/Definition gratislisens].\nDette gir en følelse av felleseie og stimulerer til langvarige bidrag.\nDette er normalt unødvendig for en privat eller virksomhetsbegrenset wiki.\n\nHvis du ønsker å kunne bruke tekst fra Wikipedia, og at Wikipedia skal kunne ta i mot tekst kopiert fra din wiki, bør du velge <strong>{{int:config-license-cc-by-sa}}</strong>.\n\nWikipedia brukte tidligere GNU Free Documentation License.\nGFDL er en grei lisens, med vanskelig å forstå.\nDet er også vanskelig å gjenbruke innhold lisensiert under GFDL.",
        "config-email-settings": "E-postinnstillinger",
        "config-enable-email": "Aktiver utgående e-post",
-       "config-enable-email-help": "Hvis du vil at e-post skal virke må [Config-dbsupport-oracle/manual/en/mail.configuration.php PHPs e-postinnstillinger] bli konfigurert riktig.\nHvis du ikke ønsker noen e-postfunksjoner kan du deaktivere dem her.",
+       "config-enable-email-help": "Hvis du vil at e-post skal virke, må [https://secure.php.net/manual/en/mail.configuration.php PHPs epostinnstillinger] konfigureres riktig.\nHvis du ikke ønsker noen epostfunksjoner, kan du deaktivere dem her.",
        "config-email-user": "Aktiver e-post mellom brukere",
        "config-email-user-help": "Tillat alle brukere å sende hverandre e-post hvis de har aktivert det i deres innstillinger.",
        "config-email-usertalk": "Aktiver brukerdiskusjonssidevarsler",
        "config-install-interwiki-exists": "<strong>Advarsel:</strong> Interwiki-tabellen ser allerede ut til å ha innhold.\nLegger derfor ikke inn standardlisten.",
        "config-install-stats": "Initialiserer statisikk",
        "config-install-keys": "Genererer hemmelige nøkler",
-       "config-insecure-keys": "<strong>Advarsel:</strong> {{PLURAL:$2|En sikker nøkkel|Sikre nøkler}} ($1) generert under installeringen er ikke helt {{PLURAL:$2|trygg|trygge}}. Vurder å endre {{PLURAL:$2|den|dem}} manuelt.",
        "config-install-updates": "Forhindre unødvendige oppdateringer",
        "config-install-updates-failed": "<strong>Feil:</strong> Innsetting av oppdateringsnøkler i tabellene mislyktes med følgende feilmelding: $1",
        "config-install-sysop": "Oppretter brukerkonto for administrator",
index 3ee33c1..2677d47 100644 (file)
@@ -48,8 +48,6 @@
        "config-header-postgres": "PostgreSQL सेटिङहरू",
        "config-header-sqlite": "SQLite सेटिङ्हरू",
        "config-header-oracle": "ओरेकल सेटिङहरू",
-       "config-mysql-binary": "बाइनरी",
-       "config-mysql-utf8": "UTF-8",
        "config-site-name": "विकीको नाम:",
        "config-site-name-blank": "साइटको नाम लेख्नुहोस।",
        "config-project-namespace": "आयोजना नेमस्पेस:",
index dcee489..49e0e58 100644 (file)
@@ -45,7 +45,6 @@
        "config-upgrade-done-no-regenerate": "Het bijwerken is afgerond.\n\nJe kunt nu [$1 je wiki gebruiken].",
        "config-db-web-no-create-privs": "Het account dat je voor installatie hebt opgegeven, heeft niet voldoende rechten om een account aan te maken.\nHet account dat je hier opgeeft, moet al bestaan.",
        "config-mysql-myisam-dep": "'''Waarschuwing''': je hebt MyISAM geselecteerd als opslagengine voor MySQL. Dit is niet aan te raden voor MediaWiki omdat:\n* het nauwelijks ondersteuning biedt voor gebruik door meerdere gebruikers tegelijkertijd door het locken van tabellen;\n* het meer vatbaar is voor corruptie dan andere engines;\n* de code van MediaWiki niet alstijd omgaat met MyISAM zoals dat zou moeten.\n\nAls je installatie van MySQL InnoDB ondersteunt, gebruik dat dan vooral.\nAls je installatie van MySQL geen ondersteuning heeft voor InnoDB, denk dan na over upgraden.",
-       "config-mysql-charset-help": "In '''binaire modus''' slaat MediaWiki tekst in UTF-8 op in binaire databasevelden.\nDit is efficiënter dan de UTF-8-modus van MySQL en stelt je in staat de volledige reeks Unicodetekens te gebruiken.\n\nIn '''UTF-8-modus''' kent MySQL de tekenset van je gegevens en kan de databaseserver ze juist weergeven en converteren.\nHet is dat niet mogelijk tekens op te slaan die de \"[https://nl.wikipedia.org/wiki/Lijst_van_Unicode-subbereiken#Basic_Multilingual_Plane Basic Multilingual Plane]\" te boven gaan.",
        "config-project-namespace-help": "In het kielzog van Wikipedia beheren veel wiki's hun beleidspagina's apart van hun inhoudelijke pagina's in een \"'''projectnaamruimte'''\".\nAlle paginanamen in deze naamruimte beginnen met een bepaald voorvoegsel dat je hier kunt opgeven.\nDit voorvoegsel wordt meestal afgeleid van de naam van de wiki, maar het kan geen bijzondere tekens bevatten als \"#\" of \":\".",
        "config-admin-name": "Je naam:",
        "config-admin-password-mismatch": "De twee door jou ingevoerde wachtwoorden komen niet overeen.",
index c5ebb88..ca4bcc2 100644 (file)
@@ -70,7 +70,7 @@
        "config-unicode-using-intl": "Voor Unicode-normalisatie wordt de [https://pecl.php.net/intl PECL-extensie intl] gebruikt.",
        "config-unicode-pure-php-warning": "<strong>Waarschuwing:</strong> de [https://pecl.php.net/intl PECL-extensie intl] is niet beschikbaar om de Unicodenormalisatie af te handelen en daarom wordt de langzamere PHP-implementatie gebruikt.\nAls u MediaWiki voor een website met veel verkeer installeert, lees u dan in over [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations Unicodenormalisatie].",
        "config-unicode-update-warning": "<strong>Waarschuwing:</strong> de geïnstalleerde versie van de Unicodenormalisatiewrapper maakt gebruik van een oudere versie van [http://site.icu-project.org/ de bibliotheek van het ICU-project].\nU moet [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations bijwerken] als Unicode voor u van belang is.",
-       "config-no-db": "Het was niet mogelijk een geschikte databasedriver te vinden voor PHP! U moet een databasedriver installeren voor PHP.\n{{PLURAL:$2|Het volgende databasetype wordt|De volgende databasetypes worden}} ondersteund: $1.\n\nAls u PHP zelf hebt gecompileerd, wijzig dan uw instellingen zodat een databasedriver wordt geactiveerd, bijvoorbeeld via <code>./configure --with-mysqli</code>.\nAls u PHP hebt geïnstalleerd via een Debian- of Ubuntu-package, installeer dan ook bijvoorbeeld de module <code>php5-mysql</code>.",
+       "config-no-db": "Het was niet mogelijk een geschikte databasedriver te vinden voor PHP! U moet een databasedriver installeren voor PHP.\n{{PLURAL:$2|Het volgende databasetype wordt|De volgende databasetypes worden}} ondersteund: $1.\n\nAls u PHP zelf hebt gecompileerd, wijzig dan uw instellingen zodat een databasedriver wordt geactiveerd, bijvoorbeeld via <code>./configure --with-mysqli</code>.\nAls u PHP hebt geïnstalleerd via een Debian- of Ubuntu-package, installeer dan ook bijvoorbeeld de module <code>php-mysql</code>.",
        "config-outdated-sqlite": "''' Waarschuwing:''' u gebruikt SQLite $1. SQLite is niet beschikbaar omdat de minimaal vereiste versie $2 is.",
        "config-no-fts3": "<strong>Waarschuwing:</strong> SQLite is gecompileerd zonder de module [//sqlite.org/fts3.html FTS3]; zoekfuncties zijn niet beschikbaar.",
        "config-pcre-old": "'''Onherstelbare fout:''' PCRE $1 of een latere versie is vereist.\nUw uitvoerbare versie van PHP is gekoppeld met PCRE $2.\n[https://www.mediawiki.org/wiki/Manual:Errors_and_symptoms/PCRE Meer informatie].",
        "config-sqlite-dir-help": "SQLite slaat alle gegevens op in een enkel bestand.\n\nDe map die u opgeeft moet beschrijfbaar zijn voor de webserver tijdens de installatie.\n\nDeze mag '''niet toegankelijk''' zijn via het web en het bestand mag dus niet tussen de PHP-bestanden staan.\n\nHet installatieprogramma schrijft het bestand <code>.htaccess</code> weg met het databasebestand, maar als dat niet werkt kan iemand zich toegang tot het ruwe databasebestand verschaffen.\nOok de gebruikersgegevens (e-mailadressen, wachtwoordhashes) en verwijderde versies en overige gegevens met beperkte toegang via MediaWiki zijn dan onbeschermd.\n\nOverweeg om de database op een totaal andere plaats neer te zetten, bijvoorbeeld in <code>/var/lib/mediawiki/yourwiki</code>.",
        "config-oracle-def-ts": "Standaard tablespace:",
        "config-oracle-temp-ts": "Tijdelijke tablespace:",
-       "config-type-mysql": "MySQL (of compatibel)",
+       "config-type-mysql": "MariaDB, MySQL of compatibele systemen",
        "config-type-postgres": "PostgreSQL",
        "config-type-sqlite": "SQLite",
        "config-type-oracle": "Oracle",
        "config-support-info": "MediaWiki ondersteunt de volgende databasesystemen:\n\n$1\n\nAls u het databasesysteem dat u wilt gebruiken niet in de lijst terugvindt, volg dan de handleiding waarnaar hierboven wordt verwezen om ondersteuning toe te voegen.",
        "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] is de primaire database voor MediaWiki en wordt het best ondersteund. MediaWiki werkt ook met [{{int:version-db-mariadb-url}} MariaDB] en [{{int:version-db-percona-url}} Percona Server], die MySQL compatibel zijn ([https://secure.php.net/manual/en/mysqli.installation.php hoe PHP te compileren met MySQL-ondersteuning]).",
        "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] is een populair open source databasesysteem als alternatief voor MySQL.([https://secure.php.net/manual/en/pgsql.installation.php Hoe u PHP kunt compileren met ondersteuning voor PostgreSQL])",
-       "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] is een zeer goed ondersteund lichtgewicht databasesysteem ([http://www.php.net/manual/en/pdo.installation.php hoe PHP gecompileerd moet zijn met ondersteuning voor SQLite]; gebruikt PDO).",
-       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] is een commerciële database voor grote bedrijven ([http://www.php.net/manual/en/oci8.installation.php PHP compileren met ondersteuning voor OCI8]).",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] is een commerciële enterprisedatabase voor Windows ([Config-dbsupport-oracle/manual/en/sqlsrv.installation.php PHP compileren met ondersteuning voor SQLSRV]).",
-       "config-header-mysql": "MySQL-instellingen",
+       "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] is een zeer goed ondersteund lichtgewicht databasesysteem ([https://secure.php.net/manual/en/pdo.installation.php hoe PHP gecompileerd moet zijn met ondersteuning voor SQLite]; gebruikt PDO).",
+       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] is een commerciële database voor grote bedrijven ([https://secure.php.net/manual/en/oci8.installation.php PHP compileren met ondersteuning voor OCI8]).",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] is een commerciële enterprisedatabase voor Windows ([https://secure.php.net/manual/en/sqlsrv.installation.php PHP compileren met ondersteuning voor SQLSRV]).",
+       "config-header-mysql": "MariaDB/MySQL-instellingen",
        "config-header-postgres": "PostgreSQL-instellingen",
        "config-header-sqlite": "SQLite-instellingen",
        "config-header-oracle": "Oracle-instellingen",
        "config-db-web-create": "Maak de gebruiker aan als deze nog niet bestaat",
        "config-db-web-no-create-privs": "Het account dat u voor de installatie hebt opgegeven, heeft niet voldoende rechten om een account aan te maken.\nHet account dat u hier opgeeft, moet al bestaan.",
        "config-mysql-engine": "Opslagmethode:",
-       "config-mysql-innodb": "InnoDB",
+       "config-mysql-innodb": "InnoDB (aanbevolen)",
        "config-mysql-myisam": "MyISAM",
        "config-mysql-myisam-dep": "'''Waarschuwing''': u hebt MyISAM geselecteerd als opslagengine voor MySQL. Dit is niet aan te raden voor MediaWiki omdat:\n* het nauwelijks ondersteuning biedt voor gebruik door meerdere gebruikers tegelijkertijd door het locken van tabellen;\n* het meer vatbaar is voor corruptie dan andere engines;\n* de code van MediaWiki niet alstijd omgaat met MyISAM zoals dat zou moeten.\n\nAls uw installatie van MySQL InnoDB ondersteunt, gebruik dat dan vooral.\nAls uw installatie van MySQL geen ondersteuning heeft voor InnoDB, denk dan na over upgraden.",
        "config-mysql-only-myisam-dep": "'''Waarschuwing:''' MyISAM is enige beschikbare opslagmethode voor MySQL in deze omgeving, en deze wordt niet aangeraden voor gebruik met MediaWiki, omdat:\n* er nauwelijks ondersteuning is voor meerdere gelijktijdige transacties omdat tabellen op slot gezet worden;\n* tabellen makkelijker stuk kunnen gaan;\n* de code van MediaWiki niet altijd op de juiste wijze omgaat met MyISAM.\n\nUw installatie van MySQL heeft geen ondersteuning voor InnoDB. We raden u aan om een meer recente versie te gebruiken.",
        "config-mysql-engine-help": "'''InnoDB''' is vrijwel altijd de beste instelling, omdat deze goed omgaat met meerdere verzoeken tegelijkertijd.\n\n'''MyISAM''' is bij een zeer beperkt aantal gebruikers mogelijk sneller, of als de wiki alleen-lezen is.\nMyISAM-databases raken vaker beschadigd dan InnoDB-databases.",
-       "config-mysql-charset": "Tekenset voor de database:",
-       "config-mysql-binary": "Binair",
-       "config-mysql-utf8": "UTF-8",
-       "config-mysql-charset-help": "In <strong>binaire modus</strong> slaat MediaWiki tekst in UTF-8 op in binaire databasevelden.\nDit is efficiënter dan de UTF-8-modus van MySQL en stelt u in staat de volledige reeks Unicodetekens te gebruiken.\n\nIn <strong>UTF-8-modus</strong> kent MySQL de tekenset van uw gegevens en kan de databaseserver ze juist weergeven en converteren.\nHet is dan niet mogelijk tekens op te slaan die de \"[https://nl.wikipedia.org/wiki/Lijst_van_Unicode-subbereiken#Basic_Multilingual_Plane Basic Multilingual Plane]\" te boven gaan.",
        "config-mssql-auth": "Authenticatietype:",
        "config-mssql-install-auth": "Selecteer de authenticatiemethode die wordt gebruikt om met de database te verbinden tijdens het installatieproces.\nAls u \"{{int:config-mssql-windowsauth}}\" selecteert, dan worden de aanmeldgegevens van de gebruiker waaronder de webserver draait voor authenticatie gebruikt.",
        "config-mssql-web-auth": "Selecteer de authenticatiemethode die de webserver gebruikt om met de database te verbinden tijdens het installatieproces.\nAls u \"{{int:config-mssql-windowsauth}}\" selecteert, dan worden de aanmeldgegevens van de gebruiker waaronder de webserver draait voor authenticatie gebruikt.",
        "config-license-help": "In veel openbare wiki's zijn alle bijdragen beschikbaar onder een [https://freedomdefined.org/Definition vrije licentie].\nDit helpt bij het creëren van een gevoel van gemeenschappelijk eigendom en stimuleert bijdragen op lange termijn.\nDit is over het algemeen niet nodig is voor een particuliere of zakelijke wiki.\n\nAls u teksten uit Wikipedia wilt kunnen gebruiken en u wilt het mogelijk maken teksten uit uw wiki naar Wikipedia te kopiëren, kies dan de licentie <strong>{{int:config-license-cc-by-sa}}</strong>.\n\nDe GNU Free Documentation License is de oude licentie voor inhoud uit Wikipedia.\nDit is nog steeds een geldige licentie, maar deze licentie is lastig te begrijpen.\nHet is ook lastig inhoud te hergebruiken onder de GFDL.",
        "config-email-settings": "E-mailinstellingen",
        "config-enable-email": "Uitgaande e-mail inschakelen",
-       "config-enable-email-help": "Als u wilt dat e-mailen mogelijk is, dan moeten de [Config-dbsupport-oracle/manual/en/mail.configuration.php e-mailinstellingen van PHP] correct zijn.\nAls u niet wilt dat e-mailen mogelijk is, dan kunt u de instellingen hier uitschakelen.",
+       "config-enable-email-help": "Als u wilt dat e-mailen mogelijk is, dan moeten de [https://secure.php.net/manual/en/mail.configuration.php e-mailinstellingen van PHP] correct zijn.\nAls u niet wilt dat e-mailen mogelijk is, dan kunt u de instellingen hier uitschakelen.",
        "config-email-user": "E-mail tussen gebruikers inschakelen",
        "config-email-user-help": "Gebruikers toestaan e-mail aan elkaar te verzenden als dit in de voorkeuren is ingesteld.",
        "config-email-usertalk": "Gebruikersoverlegmeldingen inschakelen",
        "config-cache-options": "Instellingen voor het cachen van objecten:",
        "config-cache-help": "Het cachen van objecten wordt gebruikt om de snelheid van MediaWiki te verbeteren door vaak gebruikte gegevens te bewaren.\nMiddelgrote tot grote websites wordt geadviseerd dit in te schakelen en ook kleine sites merken de voordelen.",
        "config-cache-none": "Niets cachen.\nEr gaat geen functionaliteit verloren, maar dit kan invloed hebben op de prestaties.",
-       "config-cache-accel": "Cachen van objecten via PHP (APC, APCu, XCache of WinCache)",
+       "config-cache-accel": "Cachen van objecten via PHP (APC, APCu of WinCache)",
        "config-cache-memcached": "Memcached gebruiken (dit vereist aanvullende instellingen)",
        "config-memcached-servers": "Memcachedservers:",
        "config-memcached-help": "Lijst met IP-adressen te gebruiken voor Memcached.\nEén IP-adres per regel met een poortnummer.\nBijvoorbeeld:\n 127.0.0.1:11211\n 192.168.1.25:1234",
        "config-install-interwiki-exists": "'''Waarschuwing''': de interwikitabel heeft al inhoud.\nDe standaardlijst wordt overgeslagen.",
        "config-install-stats": "Statistieken initialiseren",
        "config-install-keys": "Bezig met aanmaken van geheime sleutels",
-       "config-insecure-keys": "'''Waarschuwing:''' De {{PLURAL:$2|sleutel die is aangemaakt|sleutels die zijn aangemaakt}} ($1) tijdens de installatie {{PLURAL:$2|is|zijn}} niet volledig veilig. Overweeg deze handmatig te wijzigen.",
        "config-install-updates": "Voorkomen dat updates onnodig worden uitgevoerd",
        "config-install-updates-failed": "<strong>Fout:</strong> het toevoegen van updatesleutels aan tabellen is mislukt met de volgende fout: $1",
        "config-install-sysop": "Account voor beheerder aanmaken",
        "config-nofile": "Het bestand \"$1\" is niet gevonden. Is het verwijderd?",
        "config-extension-link": "Weet u dat u [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Extensions uitbreidingen] kunt gebruiken voor uw wiki?\n\nU kunt [https://www.mediawiki.org/wiki/Special:MyLanguage/Category:Extensions_by_category uitbreidingen op categorie] bekijken of ga naar de [https://www.mediawiki.org/wiki/Extension_Matrix uitbreidingenmatrix] om de volledige lijst met uitbreidingen te bekijken.",
        "config-skins-screenshots": "$1 (schermafbeeldingen: $2)",
+       "config-extensions-requires": "$1 (vereist $2)",
        "config-screenshot": "schermafbeelding",
        "mainpagetext": "<strong>De installatie van MediaWiki is geslaagd.</strong>",
        "mainpagedocfooter": "Raadpleeg de [https://meta.wikimedia.org/wiki/Special:MyLanguage/Help:Contents handleiding] voor informatie over het gebruik van de wikisoftware.\n\n== Meer hulp over MediaWiki ==\n\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Lijst met instellingen]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ Veelgestelde vragen (FAQ)]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Mailinglijst voor aankondigingen van nieuwe versies]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Maak MediaWiki beschikbaar in uw taal]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Leer hoe u spam kunt voorkomen op uw wiki]"
index c099895..7198522 100644 (file)
@@ -91,9 +91,6 @@
        "config-mysql-engine": "Motor d'emmagazinatge :",
        "config-mysql-innodb": "InnoDB",
        "config-mysql-myisam": "MyISAM",
-       "config-mysql-charset": "Jòc de caractèrs de la basa de donadas :",
-       "config-mysql-binary": "Binari",
-       "config-mysql-utf8": "UTF-8",
        "config-mssql-auth": "Tipe d’autentificacion :",
        "config-mssql-sqlauth": "Autentificacion de SQL Server",
        "config-mssql-windowsauth": "Autentificacion Windows",
index 6894534..dd24138 100644 (file)
@@ -35,7 +35,6 @@
        "config-header-mssql": "Microsoft SQL Server azetukset",
        "config-mysql-innodb": "InnoDB",
        "config-mysql-myisam": "MyISAM",
-       "config-mysql-utf8": "UTF-8",
        "config-site-name": "Wikin nimi:",
        "config-site-name-blank": "Kirjuta sivun nimi.",
        "config-project-namespace": "Projektan nimitila:",
index 427558f..1d4d515 100644 (file)
        "config-unicode-using-intl": "Korzystanie z [https://pecl.php.net/intl rozszerzenia intl PECL] do normalizacji Unicode.",
        "config-unicode-pure-php-warning": "<strong>Uwaga:<strong> [https://pecl.php.net/intl Rozszerzenie intl PECL] do obsługi normalizacji Unicode nie jest dostępne. Użyta zostanie mało wydajna zwykła implementacja w PHP.\nJeśli prowadzisz stronę o dużym natężeniu ruchu, powinieneś zapoznać się z informacjami o [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations normalizacji Unicode].",
        "config-unicode-update-warning": "<strong>Uwaga:</strong> zainstalowana wersja normalizacji Unicode korzysta z nieaktualnej biblioteki [http://site.icu-project.org/ projektu ICU].\nPowinieneś [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations wykonać aktualizację], jeśli chcesz korzystać w pełni z Unicode.",
-       "config-no-db": "Nie można odnaleźć właściwego sterownika bazy danych! Musisz zainstalować sterownik bazy danych dla PHP.\nMożna użyć {{PLURAL:$2|następującego typu bazy|następujących typów baz}} danych: $1.\n\nJeśli skompilowałeś PHP samodzielnie, skonfiguruj go ponownie z włączonym klientem bazy danych, na przykład za pomocą polecenia <code>./configure --with-mysqli</code>.\nJeśli zainstalowałeś PHP jako pakiet Debiana lub Ubuntu, musisz również zainstalować np. moduł <code>php5-mysql</code>.",
+       "config-no-db": "Nie można odnaleźć właściwego sterownika bazy danych! Musisz zainstalować sterownik bazy danych dla PHP.\nMożna użyć {{PLURAL:$2|następującego typu bazy|następujących typów baz}} danych: $1.\n\nJeśli skompilowałeś PHP samodzielnie, skonfiguruj go ponownie z włączonym klientem bazy danych, na przykład za pomocą polecenia <code>./configure --with-mysqli</code>.\nJeśli zainstalowałeś PHP jako pakiet Debiana lub Ubuntu, musisz również zainstalować np. moduł <code>php-mysql</code>.",
        "config-outdated-sqlite": "'''Ostrzeżenie''': masz SQLite  $1, która jest niższa od minimalnej wymaganej wersji  $2 . SQLite będzie niedostępne.",
        "config-no-fts3": "'''Uwaga''' – SQLite został skompilowany bez [//sqlite.org/fts3.html modułu FTS3] – funkcje wyszukiwania nie będą dostępne.",
        "config-pcre-old": "<strong>Błąd krytyczny:</strong> Wymagany jest PCRE w wersji $1 lub nowszej.\nTwój plik wykonywalny PHP jest powiązany z wersją PCRE $2.\n[https://www.mediawiki.org/wiki/Manual:Errors_and_symptoms/PCRE Więcej informacji].",
        "config-pcre-no-utf8": "'''Błąd krytyczny''' – wydaje się, że moduł PCRE w PHP został skompilowany bez wsparcia dla UTF‐8.\nMediaWiki wymaga wsparcia dla UTF‐8 do prawidłowego działania.",
        "config-memory-raised": "PHP <code>memory_limit</code> było ustawione na $1, zostanie zwiększone do $2.",
        "config-memory-bad": "'''Uwaga:''' PHP <code>memory_limit</code> jest ustawione na $1.\nTo jest prawdopodobnie zbyt mało.\nInstalacja może się nie udać!",
-       "config-apc": "[Http://www.php.net/apc APC] jest zainstalowany",
+       "config-apc": "[https://secure.php.net/apc APC] jest zainstalowany",
        "config-apcu": "[https://secure.php.net/apcu APCu] jest zainstalowany",
        "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] jest zainstalowany",
        "config-no-cache-apcu": "<strong>Ostrzeżenie:</strong> Nie można było znaleźć [https://secure.php.net/apcu APCu] ani [https://www.iis.net/downloads/microsoft/wincache-extension WinCache].\nPamięć podręczna obiektów nie została włączona.",
        "config-sqlite-dir-help": "SQLite przechowuje wszystkie dane w pojedynczym pliku.\n\nWskazany katalog musi być dostępny do zapisu przez webserver podczas instalacji.\n\nPowinien '''nie''' być dostępny za z sieci web, dlatego nie umieszczamy ich tam, gdzie znajdują się pliki PHP.\n\nInstalator zapisze plik <code>.htaccess</code> obokniego, ale jeśli to zawiedzie, ktoś może uzyskać dostęp do nieprzetworzonej bazy danych.\nZawiera ona nieopracowane dane użytkownika (adresy e-mail, zahaszowane hasła) jak również usunięte wersje oraz inne dane o ograniczonym dostępie na wiki.\n\nWarto rozważyć umieszczenie w bazie danych zupełnie gdzie indziej, na przykład w <code>/var/lib/mediawiki/yourwiki</code> .",
        "config-oracle-def-ts": "Domyślna przestrzeń tabel:",
        "config-oracle-temp-ts": "Przestrzeń tabel tymczasowych:",
-       "config-type-mysql": "MySQL (lub kompatybilna)",
+       "config-type-mysql": "MariaDB, MySQL lub kompatybilna",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki może współpracować z następującymi systemami baz danych:\n\n$1\n\nPoniżej wyświetlone są systemy baz danych gotowe do użycia. Jeżeli poniżej brakuje bazy danych, z której chcesz skorzystać, oznacza to, że brakuje odpowiedniego oprogramowania lub zostało ono niepoprawnie skonfigurowane. Powyżej znajdziesz odnośniki do dokumentacji, która pomoże w konfiguracji odpowiednich komponentów.",
-       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] jest bazą danych, na której rozwijane jest oprogramowanie MediaWiki. MediaWiki działa również z [{{int:version-db-mariadb-url}} MariaDB] i [{{int:version-db-percona-url}} Percona Server], które są zgodne z MySQL. ([https://secure.php.net/manual/en/mysqli.installation.php Zobacz, jak skompilować PHP ze wsparciem dla MySQL])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] jest popularnym systemem baz danych, często stosowanym zamiast MySQL. ([https://secure.php.net/manual/pl/pgsql.installation.php Zobacz, jak skompilować PHP z obsługą PostgreSQL])",
-       "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] jest niewielkim systemem bazy danych, z którym MediaWiki bardzo dobrze współpracuje. ([http://www.php.net/manual/en/pdo.installation.php Zobacz, jak skompilować PHP ze wsparciem dla SQLite], korzystając z PDO)",
-       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] jest komercyjną profesjonalną bazą danych. ([http://www.php.net/manual/en/oci8.installation.php Jak skompilować PHP ze wsparciem dla OCI8])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] jest komercyjną profesjonalną bazą danych. ([Config-dbsupport-oracle/manual/pl/sqlsrv.installation.php Jak skompilować PHP ze wsparciem dla SQLSRV])",
-       "config-header-mysql": "Ustawienia MySQL",
+       "config-dbsupport-mysql": "* [{{int:version-db-mariadb-url}} MariaDB] jest bazą danych, na której rozwijane jest oprogramowanie MediaWiki. MediaWiki działa również z [{{int:version-db-mysql-url}} MySQL] i [{{int:version-db-percona-url}} Percona Server], które są zgodne z MariaDB. ([https://secure.php.net/manual/en/mysqli.installation.php Zobacz, jak skompilować PHP ze wsparciem dla MySQL])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] jest popularnym, otawrtym systemem baz danych, często stosowanym jako alternatywa dla MySQL. ([https://secure.php.net/manual/en/pgsql.installation.php Zobacz, jak skompilować PHP z obsługą PostgreSQL])",
+       "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] jest niewielkim systemem bazy danych, z którym MediaWiki bardzo dobrze współpracuje. ([https://secure.php.net/manual/pl/pdo.installation.php Zobacz, jak skompilować PHP ze wsparciem dla SQLite], korzystając z PDO)",
+       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] jest komercyjną profesjonalną bazą danych. ([https://secure.php.net/manual/pl/oci8.installation.php Jak skompilować PHP ze wsparciem dla OCI8])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] jest komercyjną profesjonalną bazą danych. ([https://secure.php.net/manual/pl/sqlsrv.installation.php Jak skompilować PHP ze wsparciem dla SQLSRV])",
+       "config-header-mysql": "Ustawienia MariaDB/MySQL",
        "config-header-postgres": "Ustawienia PostgreSQL",
        "config-header-sqlite": "Ustawienia SQLite",
        "config-header-oracle": "Ustawienia Oracle",
        "config-db-web-create": "Utwórz konto, jeśli jeszcze nie istnieje",
        "config-db-web-no-create-privs": "Konto podane do wykonania instalacji nie ma wystarczających uprawnień, aby utworzyć nowe konto.\nKonto, które wskazałeś tutaj musi już istnieć.",
        "config-mysql-engine": "Silnik przechowywania",
-       "config-mysql-innodb": "InnoDB",
+       "config-mysql-innodb": "InnoDB (zalecane)",
        "config-mysql-myisam": "MyISAM",
        "config-mysql-myisam-dep": "'''Ostrzeżenie''': wybrano MyISIAM jako silnik  składowania danych MySQL, co nie jest zalecane do użytku w MediaWiki, ponieważ:\n * ledwo obsługuje współbieżnośći ze względu na blokowanie tabel\n * jest bardziej podatna na uszkodzenie niż inne silniki\n * kod źródłowy MediaWiki nie zawsze obsługuje MyISAM tak, jak powinien\n\nJeśli instalacja MySQL obsługuje InnoDB, jest wysoce zalecane, by to je wybrać.\nJeśli instalacja MySQL nie obsługuje InnoDB, być może nadszedł czas na jej uaktualnienie.",
        "config-mysql-only-myisam-dep": "'''Ostrzeżenie:''' MyISAM jest jedynym dostępnym na tym komputerze mechanizmem składowania dla MySQL, który jednak nie jest zalecany do używania z MediaWiki, ponieważ:\n* słabo obsługuje współbieżność z powodu blokowania tabel\n* jest bardziej skłonny do uszkodzeń niż inne silniki\n* kod MediaWiki nie zawsze traktuje MyISAM jak powinien\n\nTwoja instalacja MySQL nie obsługuje InnoDB, być może jest to czas na aktualizację.",
        "config-mysql-engine-help": "'''InnoDB''' jest prawie zawsze najlepszą opcją, ponieważ posiada dobrą obsługę współbieżności.\n\n'''MyISAM''' może być szybsze w instalacjach pojedynczego użytkownika lub tylko do odczytu.\nBazy danych MyISAM mają tendencję do ulegania uszkodzeniom częściej niż bazy InnoDB.",
-       "config-mysql-charset": "Zestaw znaków bazy danych:",
-       "config-mysql-binary": "binarny",
-       "config-mysql-utf8": "UTF‐8",
-       "config-mysql-charset-help": "W <strong>trybie binarnym</strong>, MediaWiki zapisuje tekst UTF-8 do bazy danych w polach binarnych.\nJest on bardziej wydajny niż tryb UTF-8 w MySQL i pozwala na używanie znaków z pełnego zakresu Unicode.\n\nW <strong>trybie UTF-8</strong> MySQL będzie znać zestaw znaków w jakim zakodowano dane, możne też je wyświetlić i odpowiednio przekonwertować, ale nie pozwoli Ci przechowywać znaków spoza [https://en.wikipedia.org/wiki/Mapping_of_Unicode_character_planes podstawowej płaszczyzny wielojęzyczności].",
        "config-mssql-auth": "Typ uwierzytelniania:",
        "config-mssql-install-auth": "Wybierz typ uwierzytelniania, który będzie używany do łączenia się z bazą danych w trakcie procesu instalacji.\nJeśli wybierzesz „{{int:config-mssql-windowsauth}}”, będą wykorzystywane dane konta użytkownika, pod którym działa serwer www.",
        "config-mssql-web-auth": "Wybierz typ uwierzytelniania, który będzie używany przez serwer www do łączenia się z bazą danych podczas normalnego funkcjonowania wiki.\nJeśli wybierzesz „{{int:config-mssql-windowsauth}}”, użyte zostaną dane konta użytkownika, pod którym działa serwer www.",
        "config-license-help": "Wiele publicznych wiki umieszcza wszystkie dopisane treści na [https://freedomdefined.org/Definition wolnej licencji].\nPomaga to tworzyć poczucie wspólnoty i zachęca do długoterminowego wkładu.\nNie jest to zazwyczaj konieczne w prywatnych lub firmowych wiki.\n\nJeśli chcesz móc użyć tekstu z Wikipedii i chcesz Wikipedia mogła zaakceptować tekst skopiowany z twojej wiki, należy wybrać <strong>{{int:config-license-cc-by-sa}}</strong>.\n\nWikipedia używała poprzednio GNU Free Documentation License.\nGFDL jest poprawną licencję, ale trudno ją zrozumieć.\nTrudno także ponowne użyć zawartości na licencji GFDL.",
        "config-email-settings": "Ustawienia e-maili",
        "config-enable-email": "Włącz wychodzące wiadomości e–mail",
-       "config-enable-email-help": "Jeśli chcesz, aby działał e-mail, [Config-dbsupport-oracle/manual/en/mail.configuration.php Ustawienia poczty PHP] muszą być poprawnie wprowadzone.\nJeśli nie chcesz jakichś funkcji poczty e-mail, można je wyłączyć tutaj.",
+       "config-enable-email-help": "Jeśli chcesz, aby działał e-mail, [https://secure.php.net/manual/pl/mail.configuration.php Ustawienia poczty PHP] muszą być poprawnie wprowadzone.\nJeśli nie chcesz jakichś funkcji poczty e-mail, można je wyłączyć tutaj.",
        "config-email-user": "Włącz możliwość przesyłania e‐maili pomiędzy użytkownikami",
        "config-email-user-help": "Zezwalaj użytkownikom na wysyłanie wzajemnie e‐maili, jeśli będą mieć włączoną tę funkcję w swoich preferencjach.",
        "config-email-usertalk": "Włącz powiadamianie o zmianach na stronie dyskusji użytkownika",
        "config-install-interwiki-exists": "'''Uwaga''' – wygląda na to, że tabela interwiki ma już jakieś wpisy.\nTworzenie domyślnej listy pominięto.",
        "config-install-stats": "Inicjowanie statystyki",
        "config-install-keys": "Generowanie tajnych kluczy",
-       "config-insecure-keys": "'''Ostrzeżenie:''' {{PLURAL:$2|Klucz bezpieczeństwa|Klucze bezpieczeństwa|Klucze bezpieczeństwa}} ($1) utworzone podczas instalacji {{PLURAL:$2|utworzony podczas instalacji nie jest|utworzone podczas instalacji nie są|utworzone podczas instalacji nie są}} w pełni bezpieczne. Być może warto wygenerować {{PLURAL:$2|własny klucz|własne klucze|własne klucze}}.",
        "config-install-updates": "Zapobieganie uruchamianiu niepotrzebnych aktualizacji",
        "config-install-updates-failed": "<strong>Błąd:</strong> Wstawianie kluczy aktualizacji d0 tabeli nie powiodło się z powodu następującego błędu: $1",
        "config-install-sysop": "Tworzenie konta administratora",
        "config-nofile": "Nie udało się odnaleźć pliku \"$1\". Czy nie został usunięty?",
        "config-extension-link": "Czy wiesz, że twoja wiki obsługuje [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Extensions rozszerzenia]?\n\nMożesz przejrzeć [https://www.mediawiki.org/wiki/Category:Extensions_by_category rozszerzenia według kategorii] lub [https://www.mediawiki.org/wiki/Extension_Matrix Extension Matrix], aby zobaczyć pełną listę rozszerzeń.",
        "config-skins-screenshots": "$1 (zrzut ekranu: $2)",
+       "config-extensions-requires": "$1 (wymaga $2)",
        "config-screenshot": "zrzut ekranu",
        "mainpagetext": "<strong>Instalacja MediaWiki powiodła się.</strong>",
        "mainpagedocfooter": "Zapoznaj się z [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents Podręcznikiem użytkownika] zawierającym informacje o tym jak korzystać z oprogramowania wiki.\n\n== Na początek ==\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Lista ustawień konfiguracyjnych]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ MediaWiki FAQ]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Komunikaty o nowych wersjach MediaWiki (lista dyskusyjna)]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Przetłumacz MediaWiki na swój język]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Dowiedz się, jak walczyć ze spamem na swojej wiki]"
index f397942..131e06f 100644 (file)
@@ -56,7 +56,7 @@
        "config-unicode-using-intl": "As deuvra l'[https://pecl.php.net/intl estension intl PECL] për la normalisassion Unicode.",
        "config-unicode-pure-php-warning": "'''Avis:''' L'[https://pecl.php.net/intl estension intl PECL] a l'é pa disponìbil për gestì la normalisassion Unicode, da già che l'implementassion an PHP pur a faliss për lentëssa.\nS'a gestiss un sit a àut tràfich, a dovrìa lese cheicòs an sla [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations normalisassion Unicode].",
        "config-unicode-update-warning": "'''Avis:''' La version instalà dlë spassiador ëd normalisassion Unicode a deuvra na version veja ëd la librarìa dël [http://site.icu-project.org/ proget ICU].\nA dovrìa fé n'[https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations agiornament] s'a l'é anteressà a dovré Unicode.",
-       "config-no-db": "Impossìbil trové un pilòta ëd base ëd dàit bon! A dev instalé un pilòta ëd base ëd dàit për PHP.\n{{PLURAL:$2|La sòrt ëd base ëd dàit mantnùa a l'é costa|Le sòrt ëd base ëd dàit mantùe a son coste}} sì-dapress: $1.\n\nS'a l'é compilasse PHP chiel-midem, ch'a lo configura torna con un client ëd base ëd dàit abilità, për esempi an dovrand <code>./configure --with-mysqli</code>.\nS'a l'ha instalà PHP dai pachèt Debian o Ubuntu, antlora a dev ëdcò anstalé, për esempi, ël mòdul <code>php5-mysql</code>.",
+       "config-no-db": "Impossìbil trové un pilòta ëd base ëd dàit bon! A dev instalé un pilòta ëd base ëd dàit për PHP.\n{{PLURAL:$2|La sòrt ëd base ëd dàit mantnùa a l'é costa|Le sòrt ëd base ëd dàit mantùe a son coste}} sì-dapress: $1.\n\nS'a l'é compilasse PHP chiel-midem, ch'a lo configura torna con un client ëd base ëd dàit abilità, për esempi an dovrand <code>./configure --with-mysqli</code>.\nS'a l'ha instalà PHP dai pachèt Debian o Ubuntu, antlora a dev ëdcò anstalé, për esempi, ël mòdul <code>php-mysql</code>.",
        "config-outdated-sqlite": "'''Avis''': chiel a l'ha SQLite $1, che a l'é pi vej che la version mìnima dont a-i é damanca $2. SQLite a sarà pa disponìbil.",
        "config-no-fts3": "'''Avis''': SQLite a l'é compilà sensa ël mòdul [//sqlite.org/fts3.html FTS3], le funsion d'arserca a saran pa disponìbij su cost motor.",
        "config-pcre-no-utf8": "'''Fatal''': ël mòdul PCRE ëd PHP a smija esse compilà sensa l'apògg PCRE_UTF8.\nMediaWiki a ciama l'apògg d'UTF8 për marcé për da bin.",
        "config-mysql-myisam": "MyISAM",
        "config-mysql-myisam-dep": "'''Avis''': A l'ha selessionà MyISAM com motor ëd memorisassion për MySQL, che a l'é pa arcomandà da dovré con MediaWiki, përchè:\n* a sopòrta a pen-a la contemporanità për via ëd saradure ëd tàula\n* a l'é pi soget a la corussion che j'àutri motor\n* ël còdes bas ëd MediaWiki pa sempe a gestiss MyISAM com a dovrìa\n\nSe soa istalassion MySQL a manten InnoDB, a l'é fortement arcomandà ch'a serna pitòst col-lì.\nSe soa istalassion MySQL a manten nen InnoDB, a peul esse ch'a sia ël moment ëd n'agiornament.",
        "config-mysql-engine-help": "'''InnoDB''' a l'é scasi sempe la mej opsion, da già ch'a l'ha un bon manteniment dla concorensa.\n\n'''MyISAM''' a peul esse pi lest an instalassion për n'utent sol o mach an letura.\nLa base ëd dàit MyISAM a tira a corompse pi 'd soens che la base ëd dàit InnoDB.",
-       "config-mysql-charset": "Ansem ëd caràter dla base ëd dàit:",
-       "config-mysql-binary": "Binari",
-       "config-mysql-utf8": "UTF-8",
-       "config-mysql-charset-help": "An '''manera binaria''', MediaWiki a memorisa ël test UTF-8 ant la base ëd dàit an camp binari.\nSòn a l'é pi eficient che la manera UTF-8 ëd MySQL, e a-j përmët ëd dovré l'ansema antregh ëd caràter Unicode.\n\nAn '''manera UTF-8''', MySQL a conossrà an che ansem ëd caràter a son ij sò dat, e a peul presenteje e convertije apropriatament, ma a-j lassa pa memorisé ij caràter ëdzora al [https://en.wikipedia.org/wiki/Mapping_of_Unicode_character_planes pian multilenghìstich ëd base].",
        "config-site-name": "Nòm ëd la wiki:",
        "config-site-name-help": "Sòn a comparirà ant la bara dël tìtol dël navigador e an vàire d'àutri pòst.",
        "config-site-name-blank": "Ch'a buta un nòm ëd sit.",
        "config-install-interwiki-exists": "'''Avis''': La tàula interwiki a smija ch'a l'abia già dj'element.\nPër stàndard, la lista a sarà sautà.",
        "config-install-stats": "Inissialisassion dle statìstiche",
        "config-install-keys": "Generassion ëd le ciav segrete",
-       "config-insecure-keys": "'''Avis:''' {{PLURAL:$2|Na ciav sigura|Dle ciav sigure}} ($1) generà durant l'istalassion {{PLURAL:$2|a l'é|a son}} pa completament sigure. Ch'a consìdera ëd modifiche{{PLURAL:$2|la|je}} manualment.",
        "config-install-sysop": "Creassion dël cont ëd l'utent aministrator",
        "config-install-subscribe-fail": "As peul pa sot-scrivse mediawiki-announce: $1",
        "config-install-subscribe-notpossible": "cURL a l'é pa istalà e <code>allow_url_fopen</code> a l'é pa disponìbil.",
index cad2822..840c449 100644 (file)
@@ -53,8 +53,6 @@
        "config-header-mssql": "د مايکروسافټ SQL پالنگر امستنې",
        "config-sqlite-readonly": "د <code>$1</code> دوتنه د ليکلو وړ نه ده.",
        "config-sqlite-cant-create-db": "د توکبنسټ دوتنه <code>$1</code> جوړه نه شوه.",
-       "config-mysql-binary": "دوه ايز",
-       "config-mysql-utf8": "UTF-8",
        "config-site-name": "د ويکي نوم:",
        "config-site-name-blank": "د وېبځي نوم وليکۍ.",
        "config-project-namespace": "د پروژې نوم-تشيال:",
index 03bcf64..5dfb8d8 100644 (file)
@@ -71,7 +71,7 @@
        "config-unicode-using-intl": "Usando a [https://pecl.php.net/intl extensão intl PECL] para a normalização Unicode.",
        "config-unicode-pure-php-warning": "<strong>Aviso</strong>: A [https://pecl.php.net/intl extensão intl PECL] não está disponível para efetuar a normalização Unicode, abortando e passando para a lenta implementação de PHP puro.\nSe o seu site tem um alto volume de tráfego, informe-se sobre a [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations normalização Unicode].",
        "config-unicode-update-warning": "<strong>Aviso:</strong> A versão instalada do wrapper de normalização Unicode usa uma versão mais antiga da biblioteca do [http://www.site.icu-project.org/projeto ICU].\nVocê deve [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations atualizar] se você tem quaisquer preocupações com o uso do Unicode.",
-       "config-no-db": "Não foi possível encontrar um driver apropriado para a banco de dados! Você precisa instalar um driver de banco de dados para PHP. {{PLURAL:$2|É aceito o seguinte tipo|São aceitos os seguintes tipos}} de banco de dados: $1.\n\nSe você compilou o PHP, reconfigure-o com um cliente de banco de dados ativado, por exemplo, usando <code>./configure --with-mysqli</code>.\nSe instalou o PHP a partir de um pacote Debian ou Ubuntu, então também precisa instalar, por exemplo, o pacote <code>php5-mysql</code>.",
+       "config-no-db": "Não foi possível encontrar um driver apropriado para a banco de dados! Você precisa instalar um driver de banco de dados para PHP. {{PLURAL:$2|É aceito o seguinte tipo|São aceitos os seguintes tipos}} de banco de dados: $1.\n\nSe você compilou o PHP, reconfigure-o com um cliente de banco de dados ativado, por exemplo, usando <code>./configure --with-mysqli</code>.\nSe instalou o PHP a partir de um pacote Debian ou Ubuntu, então também precisa instalar, por exemplo, o pacote <code>php-mysql</code>.",
        "config-outdated-sqlite": "<strong>Aviso:</strong> você tem o SQLite versão $1, que é menor do que a versão mínima necessária $2. O SQLite não estará disponível.",
        "config-no-fts3": "<strong>Aviso</strong> O SQLite foi compilado sem o [//sqlite.org/fts3.html módulo FTS3], as funcionalidades de pesquisa não estarão disponíveis nesta instalação.",
        "config-pcre-old": "<strong>Erro fatal:</strong> É necessário o PCRE $1 ou versão posterior.\nO binário do seu PHP foi vinculado com o PCRE $2.\n[https://www.mediawiki.org/wiki/Manual:Errors_and_symptoms/PCRE Mais informações].",
        "config-sqlite-dir-help": "O SQLite armazena todos os dados em um único arquivo.\n\nO diretório que você fornecer deve permitir a sua escrita pelo servidor web durante a instalação.\n\nO diretório <strong>não</strong> deve ser acessível pela web, por isso não estamos colocando onde estão os seus arquivos PHP.\n\nO instalador escreverá um arquivo <code>.htaccess</code>, mas se isso falhar alguém poderá ganhar acesso a toda sua base de dados.\nIsso inclui dados brutos dos usuários (endereços de e-mail, senhas criptografadas) assim como todas revisões deletadas e outros dados restritos na wiki.\n\nConsidere colocar a banco de dados em algum outro lugar, por exemplo <code>/var/lib/mediawiki/yourwiki</code>.",
        "config-oracle-def-ts": "Espaço de tabela padrão:",
        "config-oracle-temp-ts": "Tablespace temporário:",
-       "config-type-mysql": "MySQL (ou compatível)",
+       "config-type-mysql": "MariaDB, MySQL (ou compatível)",
        "config-type-postgres": "PostgreSQL",
        "config-type-sqlite": "SQLite",
        "config-type-oracle": "Oracle",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "O MediaWiki suporta os sistemas de banco de dados a seguir:\n\n$1\n\nSe você não vê o sistema de banco de dados que você está tentando usar listados abaixo, siga as instruções relacionadas acima, para ativar o suporte.",
-       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] é o principal alvo para o MediaWiki e é melhor suportado. O MediaWiki também funciona com [{{int:version-db-mariadb-url}} MariaDB] e [{{int:version-db-percona-url}} Percona Server], que são compatíveis com MySQL. ([Http://www.php.net/manual/en/mysqli.installation.php Como compilar PHP com suporte a MySQL])",
+       "config-dbsupport-mysql": "* [{{int:version-db-mariadb-url}} MariaDB] é a base de dados preferida para o MediaWiki e a melhor suportada. O MediaWiki também trabalha com [{{int:version-db-mysql-url}} MySQL] e [{{int:version-db-percona-url}} Percona Server], que são compatíveis com MariaDB. ([https://secure.php.net/manual/pt_BR/mysqli.installation.php Como compilar PHP com suporte para MySQL].)",
        "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] é um popular sistema de banco de dados de código aberto como uma alternativa para o MySQL. ([https://secure.php.net/manual/en/pgsql.installation.php Como compilar o PHP com suporte PostgreSQL])",
-       "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] é um sistema de banco de dados leve que é muito bem suportado. ([http://www.php.net/manual/en/pdo.installation.php como compilar o PHP com suporte a SQLite], usa DOP)",
-       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] é um banco de dados comercial de empresas. ([http://www.php.net/manual/en/oci8.installation.php Como compilar o PHP com suporte OCI8])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] é uma banco de dados comercial do Windows para empresas. ([Config-dbsupport-oracle/manual/en/sqlsrv.installation.php Como compilar o PHP com suporte SQLSRV])",
-       "config-header-mysql": "Configurações MySQL",
+       "config-dbsupport-sqlite": "* O [{{int:version-db-sqlite-url}} SQLite] é uma plataforma de base de dados ligeira muito bem suportada. ([https://secure.php.net/manual/en/pdo.installation.php Como compilar PHP com suporte para SQLite], usa PDO.)",
+       "config-dbsupport-oracle": "* A [{{int:version-db-oracle-url}} Oracle] é uma base de dados comercial para empresas. ([https://secure.php.net/manual/en/oci8.installation.php Como compilar PHP com suporte para OCI8].)",
+       "config-dbsupport-mssql": "* O [{{int:version-db-mssql-url}} Microsoft SQL Server] é uma base de dados comercial do Windows para empresas. ([https://secure.php.net/manual/en/sqlsrv.installation.php Como compilar PHP com suporte para SQLSRV].)",
+       "config-header-mysql": "Definições MariaDB/MySQL",
        "config-header-postgres": "Configurações PostgreSQL",
        "config-header-sqlite": "Configurações SQLite",
        "config-header-oracle": "Configurações Oracle",
        "config-db-web-create": "Crie a conta se esta ainda não existir",
        "config-db-web-no-create-privs": "A conta que você especificou para a instalação não possui privilégios suficientes para criar uma conta.\nA conta que for especificada aqui já deve existir.",
        "config-mysql-engine": "Mecanismo de armazenamento:",
-       "config-mysql-innodb": "InnoDB",
+       "config-mysql-innodb": "InnoDB (recomendado)",
        "config-mysql-myisam": "MyISAM",
        "config-mysql-myisam-dep": "<strong>Aviso:</strong> Você selecionou MyISAM como mecanismo de armazenamento para o MySQL, o que não é recomendado para uso com o MediaWiki, porque:\n* dificilmente suporta concorrência devido ao bloqueio da tabela\n* é mais propenso à corrupção do que outros motores\n*a base de código MediaWiki nem sempre lida com o MyISAM como deveria\n\nSe sua instalação MySQL suportar o InnoDB, é altamente recomendável que você escolha ele.\nSe sua instalação MySQL não suportar o InnoDB, talvez seja hora de uma atualização.",
        "config-mysql-only-myisam-dep": "<strong>Aviso:</strong> O MyISAM é o único mecanismo de armazenamento disponível para o MySQL nesta máquina e isso não é recomendado para uso com o MediaWiki, porque:\n* dificilmente suporta concorrência devido ao bloqueio da tabela\n* é mais propenso à corrupção do que outros motores\n*a base de código MediaWiki nem sempre lida com o MyISAM como deveria\n\nA sua instalação no MySQL não suporta InnoDB, talvez seja hora de uma atualização.",
        "config-mysql-engine-help": "<strong>InnoDB</strong> é quase sempre a melhor opção, uma vez que possui um bom suporte de concorrência.\n\n<strong>MyISAM</strong> pode ser mais rápido em instalações de usuário único ou somente leitura.\\O banco de dados MyISAM tendem a ficar corrompidos mais frequentemente do que os bancos de dados InnoDB.",
-       "config-mysql-charset": "Conjunto de caracteres do banco de dados:",
-       "config-mysql-binary": "Binário",
-       "config-mysql-utf8": "UTF-8",
-       "config-mysql-charset-help": "Em <strong>modo binário</strong>, o MediaWiki armazena texto UTF-8 no banco de dados em campos binários.\nEsto é mais eficiente que o modo UTF-8 do MySQL e permite que você use a gama completa de caracteres Unicode.\n\nNo <strong>modo UTF-8</strong>, o MySQL saberá o caracterer em que seus dados estão inseridos e pode apresentá-lo e convertê-lo adequadamente, mas não permitirá que você armazene caracteres acima do [https://en.wikipedia.org/wiki/Mapping_of_Unicode_character_planes Multilingue Básico].",
        "config-mssql-auth": "Tipo de autenticação:",
        "config-mssql-install-auth": "Selecione o tipo de autenticação que será usado para se conectar ao banco de dados durante o processo de instalação.\nSe você selecionar \"{{int:config-mssql-windowsauth}}\", as credenciais de qualquer usuário que o servidor web esteja executando serão usadas.",
        "config-mssql-web-auth": "Selecione o tipo de autenticação que o servidor web usará para se conectar ao servidor do banco de dados, durante a operação normal da wiki.\nSe você selecionar \"{{int:config-mssql-windowsauth}}\", as credenciais de qualquer usuário no qual o servidor web está rodando serão usadas.",
        "config-install-interwiki-exists": "<strong>Aviso:</strong> A tabela de interwiki parece já ter entradas.\\NPulando lista padrão.",
        "config-install-stats": "Inicializando estatísticas",
        "config-install-keys": "Gerando senhas secretas",
-       "config-insecure-keys": "<strong>Aviso:</strong> {{PLURAL:$2|Uma chave segura gerada|Algumas chaves seguras geradas}} ($1) durante a instalação {{PLURAL:$2|não é completamente segura|não são completamente seguras}}. Considere mudar {{PLURAL:$2|ela|elas}} manualmente.",
        "config-install-updates": "Impedir a execução de atualizações desnecessárias",
        "config-install-updates-failed": "<strong>Error:</strong> A inserção de chaves de atualização em tabelas falhou com o seguinte erro: $1",
        "config-install-sysop": "Criando conta de usuário administrador",
index dcf39b0..cdcac45 100644 (file)
@@ -69,7 +69,7 @@
        "config-unicode-using-intl": "A usar a [https://pecl.php.net/intl extensão intl PECL] para a normalização Unicode.",
        "config-unicode-pure-php-warning": "<strong>Aviso:</strong> A [https://pecl.php.net/intl extensão intl PECL] não está disponível para efetuar a normalização Unicode. Irá recorrer-se à implementação em PHP puro, que é mais lenta.\nSe o seu sítio tem alto volume de tráfego, devia informar-se um pouco sobre a [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations/pt normalização Unicode].",
        "config-unicode-update-warning": "<strong>Aviso:</strong> A versão instalada do wrapper de normalização Unicode usa uma versão mais antiga da biblioteca do [http://site.icu-project.org/ projeto ICU].\nDevia [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations atualizá-la] se tem quaisquer preocupações sobre o uso do Unicode.",
-       "config-no-db": "Não foi possível encontrar um controlador apropriado da base de dados! Precisa de instalar um controlador da base de dados para o PHP. {{PLURAL:$2|É aceite o seguinte tipo|São aceites os seguintes tipos}} de base de dados: $1.\n\nSe fez a compilação do PHP, reconfigure-o com um cliente de base de dados ativado; por exemplo, usando <code>./configure --with-mysqli</code>.\nSe instalou o PHP a partir de um pacote Debian ou Ubuntu, então precisa de instalar também, por exemplo, o pacote <code>php5-mysql</code>.",
+       "config-no-db": "Não foi possível encontrar um controlador apropriado da base de dados! Precisa de instalar um controlador da base de dados para o PHP. {{PLURAL:$2|É aceite o seguinte tipo|São aceites os seguintes tipos}} de base de dados: $1.\n\nSe fez a compilação do PHP, reconfigure-o com um cliente de base de dados ativado; por exemplo, usando <code>./configure --with-mysqli</code>.\nSe instalou o PHP a partir de um pacote Debian ou Ubuntu, então precisa de instalar também, por exemplo, o pacote <code>php-mysql</code>.",
        "config-outdated-sqlite": "<strong>Aviso:</strong> Tem a versão $1 do SQLite, que é anterior à versão mínima necessária, a $2. O SQLite não estará disponível.",
        "config-no-fts3": "<strong>Aviso:</strong> O SQLite foi compilado sem o módulo [//sqlite.org/fts3.html FTS3]; as funcionalidades de pesquisa não estarão disponíveis nesta instalação.",
        "config-pcre-old": "<strong>Erro fatal:</strong> É necessário o PCRE $1 ou versão posterior.\nO seu binário PHP foi linkado com o PCRE $2.\n[https://www.mediawiki.org/wiki/Manual:Errors_and_symptoms/PCRE Mais informações].",
        "config-sqlite-dir-help": "O SQLite armazena todos os dados num único ficheiro.\n\nDurante a instalação, o servidor de Internet precisa de ter permissão de escrita no diretório que especificar.\n\nEste diretório <strong>não</strong> deve poder ser acedido diretamente da Internet, por isso está a ser colocado onde estão os seus ficheiros PHP.\n\nJuntamente com o diretório, o instalador irá criar um ficheiro <code>.htaccess</code>, mas se esta operação falhar é possível que alguém venha a ter acesso direto à base de dados.\nIsto inclui acesso aos dados dos utilizadores (endereços de correio eletrónico, palavras-passe encriptadas), às revisões eliminadas e a outros dados de acesso restrito na wiki.\n\nConsidere colocar a base de dados num local completamente diferente, como, por exemplo, em <code>/var/lib/mediawiki/asuawiki</code>.",
        "config-oracle-def-ts": "Tablespace padrão:",
        "config-oracle-temp-ts": "Tablespace temporário:",
-       "config-type-mysql": "MySQL (ou compatível)",
+       "config-type-mysql": "MariaDB, MySQL (ou compatível)",
        "config-type-postgres": "PostgreSQL",
        "config-type-sqlite": "SQLite",
        "config-type-oracle": "Oracle",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "O MediaWiki suporta as seguintes plataformas de base de dados:\n\n$1\n\nSe a plataforma que pretende usar não está listada abaixo, siga as instruções nas hiperligações acima para ativar o suporte.",
-       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] é a plataforma primária do MediaWiki e é a melhor suportada. O MediaWiki também trabalha com [{{int:version-db-mariadb-url}} MariaDB] e [{{int:version-db-percona-url}} Percona Server], que são compatíveis com MySQL. ([https://secure.php.net/manual/en/mysql.installation.php Como compilar PHP com suporte a MySQL])",
-       "config-dbsupport-postgres": "* O [{{int:version-db-postgres-url}} PostgreSQL] é uma plataforma popular de base de dados de código aberto, alternativa ao MySQL. ([https://secure.php.net/manual/en/pgsql.installation.php Como compilar o PHP com suporte PostgreSQL])",
-       "config-dbsupport-sqlite": "* O [{{int:version-db-sqlite-url}} SQLite] é uma plataforma de base de dados ligeira muito bem suportada. ([http://www.php.net/manual/en/pdo.installation.php Como compilar o PHP com suporte SQLite], usa PDO)",
-       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] é uma base de dados comercial para empresas. ([http://www.php.net/manual/en/oci8.installation.php Como compilar o PHP com suporte OCI8])",
-       "config-dbsupport-mssql": "* O [{{int:version-db-mssql-url}} Microsoft SQL Server] é uma base de dados comercial do Windows para empresas. ([Config-dbsupport-oracle/manual/en/sqlsrv.installation.php Como compilar o PHP com suporte SQLSRV])",
-       "config-header-mysql": "Definições MySQL",
+       "config-dbsupport-mysql": "* [{{int:version-db-mariadb-url}} MariaDB] é a base de dados preferida para o MediaWiki e a melhor suportada. O MediaWiki também trabalha com [{{int:version-db-mysql-url}} MySQL] e [{{int:version-db-percona-url}} Percona Server], que são compatíveis com MariaDB. ([https://secure.php.net/manual/pt_BR/mysqli.installation.php Como compilar PHP com suporte para MySQL].)",
+       "config-dbsupport-postgres": "* O [{{int:version-db-postgres-url}} PostgreSQL] é uma plataforma popular de base de dados de código aberto, alternativa ao MySQL. ([https://secure.php.net/manual/en/pgsql.installation.php Como compilar PHP com suporte para PostgreSQL].)",
+       "config-dbsupport-sqlite": "* O [{{int:version-db-sqlite-url}} SQLite] é uma plataforma de base de dados ligeira muito bem suportada. ([https://secure.php.net/manual/en/pdo.installation.php Como compilar PHP com suporte para SQLite], usa PDO.)",
+       "config-dbsupport-oracle": "* A [{{int:version-db-oracle-url}} Oracle] é uma base de dados comercial para empresas. ([https://secure.php.net/manual/en/oci8.installation.php Como compilar PHP com suporte para OCI8].)",
+       "config-dbsupport-mssql": "* O [{{int:version-db-mssql-url}} Microsoft SQL Server] é uma base de dados comercial do Windows para empresas. ([https://secure.php.net/manual/en/sqlsrv.installation.php Como compilar PHP com suporte para SQLSRV].)",
+       "config-header-mysql": "Definições MariaDB/MySQL",
        "config-header-postgres": "Definições PostgreSQL",
        "config-header-sqlite": "Definições SQLite",
        "config-header-oracle": "Definições Oracle",
        "config-db-web-create": "Criar a conta se ainda não existir",
        "config-db-web-no-create-privs": "A conta que especificou para a instalação não tem privilégios suficientes para criar uma conta.\nA conta que especificar aqui já tem de existir.",
        "config-mysql-engine": "Motor de armazenamento:",
-       "config-mysql-innodb": "InnoDB",
+       "config-mysql-innodb": "InnoDB (recomendado)",
        "config-mysql-myisam": "MyISAM",
        "config-mysql-myisam-dep": "<strong>Aviso:</strong>  Selecionou o MyISAM para motor de armazenamento do MySQL, uma combinação desaconselhada para usar com o MediaWiki porque:\n* praticamente não permite acessos simultâneos, porque bloqueia tabelas\n* o MyISAM é mais suscetível a perdas da integridade dos dados do que outros motores\n* o código do MediaWiki não trabalha devidamente com o MyISAM\n\nSe a sua instalação do MySQL suporta InnoDB, é altamente recomendado que o escolha em vez do MyISAM.\nSe não suporta o InnoDB, talvez seja uma boa altura para atualizá-la para a versão mais recente.",
        "config-mysql-only-myisam-dep": "<strong>Aviso:</strong> O único motor de armazenamento para MySQL nesta máquina é o MyISAM e o seu uso com o MediaWiki não é recomendado porque:\n* praticamente não suporta acessos simultâneos, porque bloqueia tabelas\n* o MyISAM é mais suscetível a perdas da integridade dos dados do que outros motores\n* o código do MediaWiki não trabalha devidamente com o MyISAM\n\nA sua instalação MySQL não suporta InnoDB, talvez seja uma boa altura para atualizá-la para a versão mais recente.",
        "config-mysql-engine-help": "<strong>InnoDB</strong> é quase sempre a melhor opção, porque suporta bem acessos simultâneos <i>(concurrency)</i>.\n\n<strong>MyISAM</strong> pode ser mais rápido no modo de utilizador único ou em instalações somente para leitura.\nAs bases de dados MyISAM tendem a perder integridade de dados com mais frequência do que as bases de dados InnoDB.",
-       "config-mysql-charset": "Conjunto de caracteres da base de dados:",
-       "config-mysql-binary": "Binário",
-       "config-mysql-utf8": "UTF-8",
-       "config-mysql-charset-help": "No modo '''binary''' (\"binário\"), o MediaWiki armazena o texto UTF-8 na base de dados em campos binários.\nIsto é mais eficiente do que o modo UTF-8 do MySQL e permite que sejam usados todos os caracteres Unicode.\n\nNo modo '''UTF-8''', o MySQL saberá em que conjunto de caracteres os seus dados estão e pode apresentá-los e convertê-los da forma mais adequada,\nmas não lhe permitirá armazenar caracteres acima do [https://en.wikipedia.org/wiki/Mapping_of_Unicode_character_planes Plano Multilingue Básico].",
        "config-mssql-auth": "Tipo de autenticação:",
        "config-mssql-install-auth": "Selecione o tipo de autenticação a usar para ligar à base de dados durante o processo de instalação.\nSe selecionar \"{{int:config-mssql-windowsauth}}\", serão usadas as credenciais do utilizador com que o servidor de Internet está a ser executado.",
        "config-mssql-web-auth": "Selecione o tipo de autenticação que o servidor de Internet irá usar para se ligar ao servidor da base de dados durante a operação normal da wiki.\nSe selecionar \"{{int:config-mssql-windowsauth}}\", serão usadas as credenciais do utilizador com que o servidor de Internet está a ser executado.",
        "config-license-help": "Muitas wikis de acesso público licenciam todas as colaborações com uma [https://freedomdefined.org/Definition licença livre].\nIsto ajuda a criar um sentido de propriedade da comunidade e encoraja as colaborações a longo prazo.\nTal não é geralmente necessário nas wikis privadas ou corporativas.\n\nSe pretende que seja possível usar textos da Wikipédia na sua wiki e que seja possível a Wikipédia aceitar textos copiados da sua wiki, deve escolher a licença <strong>{{int:config-license-cc-by-sa}}</strong>..\n\nA licença anterior da Wikipédia era a licença GNU Free Documentation License.\nA GFDL é uma licença válida, mas de difícil compreensão.\nTambém é difícil reutilizar conteúdos licenciados com a GFDL.",
        "config-email-settings": "Definições do correio eletrónico",
        "config-enable-email": "Ativar mensagens eletrónicas de saída",
-       "config-enable-email-help": "Se quer que o correio eletrónico funcione, as [Config-dbsupport-oracle/manual/en/mail.configuration.php definições de correio eletrónico do PHP] têm de estar configuradas corretamente.\nSe não pretende viabilizar qualquer funcionalidade de correio eletrónico, pode desativá-lo aqui.",
+       "config-enable-email-help": "Se quer que o correio eletrónico funcione, as [https://secure.php.net/manual/en/mail.configuration.php definições de correio eletrónico do PHP] têm de estar configuradas corretamente.\nSe não pretende viabilizar qualquer funcionalidade de correio eletrónico, pode desativá-lo aqui.",
        "config-email-user": "Ativar mensagens eletrónicas entre utilizadores",
        "config-email-user-help": "Permitir que todos os utilizadores troquem entre si mensagens de correio eletrónico, se tiverem ativado esta funcionalidade nas suas preferências.",
        "config-email-usertalk": "Ativar notificações de alterações à página de discussão dos utilizadores",
        "config-install-interwiki-exists": "<strong>Aviso:</strong> A tabela de interwikis parece já conter entradas.\nO preenchimento padrão desta tabela será saltado.",
        "config-install-stats": "A inicializar as estatísticas",
        "config-install-keys": "A gerar as chaves secretas",
-       "config-insecure-keys": "<strong>Aviso:</strong> {{PLURAL:$2|Uma chave segura|Chaves seguras}} ($1) {{PLURAL:$2|gerada durante a instalação não é completamente segura|geradas durante a instalação não são completamente seguras}}. Considere a possibilidade de {{PLURAL:$2|alterá-la|alterá-las}} manualmente.",
        "config-install-updates": "Evitar executar atualizações desnecessárias",
        "config-install-updates-failed": "<strong>Erro:</strong> A inserção de chaves de atualização nas tabelas falhou com o seguinte erro: $1",
        "config-install-sysop": "A criar a conta de administrador",
index fb546ab..c868169 100644 (file)
@@ -69,7 +69,7 @@
        "config-unicode-using-intl": "Status message in the MediaWiki installer environment checks.",
        "config-unicode-pure-php-warning": "PECL is the name of a group producing standard pieces of software for PHP, and intl is the name of their library handling some aspects of internationalization.",
        "config-unicode-update-warning": "ICU is a body producing standard software tools for support of Unicode and other internationalization aspects. This message warns the system administrator installing MediaWiki that the server's software is not up-to-date and MediaWiki will have problems handling some characters.",
-       "config-no-db": "{{doc-important|Do not translate \"<code>./configure --with-mysqli</code>\" and \"<code>php5-mysql</code>\".}}\nParameters:\n* $1 is comma separated list of database types supported by MediaWiki.\n* $2 is the count of items in $1 - for use in plural.",
+       "config-no-db": "{{doc-important|Do not translate \"<code>./configure --with-mysqli</code>\" and \"<code>php-mysql</code>\".}}\nParameters:\n* $1 is comma separated list of database types supported by MediaWiki.\n* $2 is the count of items in $1 - for use in plural.",
        "config-outdated-sqlite": "Used as warning. Parameters:\n* $1 - the version of SQLite that has been installed\n* $2 - minimum version",
        "config-no-fts3": "A \"[[:wikipedia:Front and back ends|backend]]\" is a system or component that ordinary users don't interact with directly and don't need to know about, and that is responsible for a distinct task or service - for example, a storage back-end is a generic system for storing data which other applications can use. Possible alternatives for back-end are \"system\" or \"service\", or (depending on context and language) even leave it untranslated.",
        "config-pcre-old": "Parameters:\n* $1 - minimum PCRE version number\n* $2 - the installed version of [[wikipedia:PCRE|PCRE]]\n{{Related|Config-fatal}}",
        "config-mysql-myisam-dep": "Warning message in the MediaWiki installer when MyISAM is chosen as MySQL storage engine.",
        "config-mysql-only-myisam-dep": "Used as warning message when mysql does not support the minimum suggested feature set.",
        "config-mysql-engine-help": "Help text in MediaWiki installer with advice for picking a MySQL storage engine.",
-       "config-mysql-charset": "Field label for the MySQL character set in the MediaWiki installer.",
-       "config-mysql-binary": "{{Identical|Binary}}",
-       "config-mysql-utf8": "Option for the MySQL character set in the MediaWiki installer.",
-       "config-mysql-charset-help": "Help text for the MySQL character set setting in the MediaWiki installer.",
        "config-mssql-auth": "Radio button group label.\n\nFollowed by the following radio button labels:\n* {{msg-mw|Config-mssql-sqlauth}}\n* {{msg-mw|Config-mssql-windowsauth}}",
        "config-mssql-install-auth": "Used as the help text for the \"Authentication type\" radio button when typing in database settings for installation.\n\nRefers to {{msg-mw|Config-mssql-windowsauth}}.\n\nSee also:\n* {{msg-mw|Config-mssql-web-auth}}",
        "config-mssql-web-auth": "Used as the help text for the \"Authentication type\" radio button when typing in database settings for normal wiki usage.\n\nRefers to {{msg-mw|Config-mssql-windowsauth}}.\n\nSee also:\n* {{msg-mw|Config-mssql-install-auth}}",
        "config-install-interwiki-exists": "Error notice during the installation saying that one of the database tables is already set up, so it's continuing without taking that step.",
        "config-install-stats": "*{{msg-mw|Config-install-database}}\n*{{msg-mw|Config-install-tables}}\n*{{msg-mw|Config-install-schema}}\n*{{msg-mw|Config-install-user}}\n*{{msg-mw|Config-install-interwiki}}\n*{{msg-mw|Config-install-stats}}\n*{{msg-mw|Config-install-keys}}\n*{{msg-mw|Config-install-sysop}}\n*{{msg-mw|Config-install-mainpage}}",
        "config-install-keys": "*{{msg-mw|Config-install-database}}\n*{{msg-mw|Config-install-tables}}\n*{{msg-mw|Config-install-schema}}\n*{{msg-mw|Config-install-user}}\n*{{msg-mw|Config-install-interwiki}}\n*{{msg-mw|Config-install-stats}}\n*{{msg-mw|Config-install-keys}}\n*{{msg-mw|Config-install-sysop}}\n*{{msg-mw|Config-install-mainpage}}",
-       "config-insecure-keys": "Parameters:\n* $1 - A list of names of the secret keys that were generated.\n* $2 - the number of items in the list $1, to be used with PLURAL.",
        "config-install-updates": "Message indicating that the updatelog table is filled with keys of updates that won't be run when running database updates.\n\nSee also:\n*{{msg-mw|Config-install-database}}\n*{{msg-mw|Config-install-tables}}\n*{{msg-mw|Config-install-interwiki}}\n*{{msg-mw|Config-install-stats}}\n*{{msg-mw|Config-install-keys}}\n*{{msg-mw|Config-install-updates}}\n*{{msg-mw|Config-install-schema}}\n*{{msg-mw|Config-install-user}}\n*{{msg-mw|Config-install-sysop}}\n*{{msg-mw|Config-install-mainpage}}",
        "config-install-updates-failed": "Used as error message. Parameters:\n* $1 - detailed error message",
        "config-install-sysop": "Message indicates that the administrator user account is being created\n\nSee also:\n*{{msg-mw|Config-install-database}}\n*{{msg-mw|Config-install-tables}}\n*{{msg-mw|Config-install-schema}}\n*{{msg-mw|Config-install-user}}\n*{{msg-mw|Config-install-interwiki}}\n*{{msg-mw|Config-install-stats}}\n*{{msg-mw|Config-install-keys}}\n*{{msg-mw|Config-install-sysop}}\n*{{msg-mw|Config-install-mainpage}}",
index f5b2ced..048ac02 100644 (file)
@@ -91,9 +91,6 @@
        "config-mysql-engine": "Motor de stocare:",
        "config-mysql-innodb": "InnoDB",
        "config-mysql-myisam": "MyISAM",
-       "config-mysql-charset": "Setul de caractere al bazei de date:",
-       "config-mysql-binary": "Binar",
-       "config-mysql-utf8": "UTF-8",
        "config-mssql-auth": "Tip de autentificare:",
        "config-site-name": "Numele wikiului:",
        "config-site-name-blank": "Introduceți un nume pentru sit.",
index 11c13d7..fcdaf00 100644 (file)
@@ -53,8 +53,6 @@
        "config-invalid-db-type": "Tipe de database invalide.",
        "config-mysql-innodb": "InnoDB",
        "config-mysql-myisam": "MyISAM",
-       "config-mysql-binary": "Binarie",
-       "config-mysql-utf8": "UTF-8",
        "config-ns-generic": "Proggette",
        "config-admin-email": "Indirizze e-mail:",
        "config-install-step-done": "fatte",
index 494e499..9d9f677 100644 (file)
@@ -25,7 +25,8 @@
                        "Irus",
                        "Mailman",
                        "Facenapalm",
-                       "Movses"
+                       "Movses",
+                       "Vlad5250"
                ]
        },
        "config-desc": "Инсталлятор MediaWiki",
@@ -74,7 +75,7 @@
        "config-unicode-using-intl": "Будет использовано [https://pecl.php.net/intl расширение «intl» для PECL] для нормализации Юникода.",
        "config-unicode-pure-php-warning": "'''Внимание!''': [https://pecl.php.net/intl расширение intl из PECL] недоступно для нормализации Юникода, будет использоваться медленная реализация на чистом PHP.\nЕсли ваш сайт работает под высокой нагрузкой, вам следует больше узнать о [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations нормализации Юникода].",
        "config-unicode-update-warning": "'''Предупреждение''': установленная версия обёртки нормализации Юникода использует старую версию библиотеки [http://site.icu-project.org/ проекта ICU].\nВы должны [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations обновить версию], если хотите полноценно использовать Юникод.",
-       "config-no-db": "Не удалось найти подходящие драйвера баз данных! Вам необходимо установить драйвера базы данных для PHP.\n{{PLURAL:$2|Поддерживается следующий тип|Поддерживаются следующие типы}} баз данных: $1.\n\nЕсли вы скомпилировали PHP сами, перенастройте его с включением клиента баз данных, например, с помощью <code>./configure --with-mysqli</code>.\nЕсли вы установили PHP из пакетов Debian или Ubuntu, то вам также необходимо установить, например, пакет <code>php5-mysql</code>.",
+       "config-no-db": "Не удалось найти подходящие драйвера баз данных! Вам необходимо установить драйвера базы данных для PHP.\n{{PLURAL:$2|Поддерживается следующий тип|Поддерживаются следующие типы}} баз данных: $1.\n\nЕсли вы скомпилировали PHP сами, перенастройте его с включением клиента баз данных, например, с помощью <code>./configure --with-mysqli</code>.\nЕсли вы установили PHP из пакетов Debian или Ubuntu, то вам также необходимо установить, например, пакет <code>php-mysql</code>.",
        "config-outdated-sqlite": "'''Предупреждение''': у Вас установлен SQLite  $1, версия которого ниже требуемой $2 . SQLite будет недоступен.",
        "config-no-fts3": "'''Внимание''': SQLite собран без модуля [//sqlite.org/fts3.html FTS3] — поиск не будет работать для этой базы данных.",
        "config-pcre-old": "'''Фатальная ошибка:''' требуется PCRE версии $1 или более поздняя.\nВаш исполняемый файл PHP связан с PCRE версии $2.\n[https://www.mediawiki.org/wiki/Manual:Errors_and_symptoms/PCRE Подробнее].",
        "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": "MySQL (или совместимая)",
+       "config-type-mysql": "MariaDB, MySQL или совместимая",
        "config-type-postgres": "PostgreSQL",
        "config-type-sqlite": "SQLite",
        "config-type-oracle": "Oracle",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki поддерживает следующие СУБД:\n\n$1\n\nЕсли вы не видите своей системы хранения данных в этом списке, следуйте инструкциям, на которые есть ссылка выше, чтобы получить поддержку.",
-       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] — основная база данных для MediaWiki, которая поддерживается лучше всего. MediaWiki также работает с [{{int:version-db-mariadb-url}} MariaDB] и [{{int:version-db-percona-url}} Percona Server], которые являются MySQL-совместимым. ([https://secure.php.net/manual/ru/mysql.installation.php инструкция, как собрать PHP с поддержкой MySQL])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] â\80\94 Ð¿Ð¾Ð¿Ñ\83лÑ\8fÑ\80наÑ\8f Ð¾Ñ\82кÑ\80Ñ\8bÑ\82аÑ\8f Ð¡Ð£Ð\91Ð\94, Ð°Ð»Ñ\8cÑ\82еÑ\80наÑ\82ива MySQL. ([Config-dbsupport-oracle/manual/ru/pgsql.installation.php Ð¸Ð½Ñ\81Ñ\82Ñ\80Ñ\83кÑ\86иÑ\8f, Ðºак собрать PHP с поддержкой PostgreSQL]).",
-       "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] — это легковесная система баз данных, имеющая очень хорошую поддержку. ([http://www.php.net/manual/ru/pdo.installation.php инструкция, как собрать PHP с поддержкой SQLite], работающей посредством PDO)",
-       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] â\80\94 Ñ\8dÑ\82о ÐºÐ¾Ð¼Ð¼ÐµÑ\80Ñ\87еÑ\81каÑ\8f Ð±Ð°Ð·Ð° Ð´Ð°Ð½Ð½Ñ\8bÑ\85 Ð¼Ð°Ñ\81Ñ\88Ñ\82аба Ð¿Ñ\80едпÑ\80иÑ\8fÑ\82иÑ\8f. ([http://www.php.net/manual/ru/oci8.installation.php Как собрать PHP с поддержкой OCI8])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] â\80\94 Ñ\8dÑ\82о ÐºÐ¾Ð¼Ð¼ÐµÑ\80Ñ\87еÑ\81кое Ð±Ð°Ð·Ð° Ð´Ð°Ð½Ð½Ñ\8bÑ\85 Ð±Ð°Ð·Ð° Ð´Ð°Ð½Ð½Ñ\8bÑ\85 Ð´Ð»Ñ\8f Windows Ð¼Ð°Ñ\81Ñ\88Ñ\82аба Ð¿Ñ\80едпÑ\80иÑ\8fÑ\82иÑ\8f. ([Config-dbsupport-oracle/manual/ru/sqlsrv.installation.php Как собрать PHP с поддержкой SQLSRV])",
-       "config-header-mysql": "Настройки MySQL",
+       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] — основная база данных для MediaWiki, которая поддерживается лучше всего. MediaWiki также работает с [{{int:version-db-mariadb-url}} MariaDB] и [{{int:version-db-percona-url}} Percona Server], которые являются MariaDB-совместимыми. (См.[https://secure.php.net/manual/ru/mysql.installation.php Как собрать PHP с поддержкой MySQL])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] â\80\94 Ð¿Ð¾Ð¿Ñ\83лÑ\8fÑ\80наÑ\8f Ð¡Ð£Ð\91Ð\94 Ñ\81 Ð¾Ñ\82кÑ\80Ñ\8bÑ\82Ñ\8bм Ð¸Ñ\81Ñ\85однÑ\8bм ÐºÐ¾Ð´Ð¾Ð¼, Ð°Ð»Ñ\8cÑ\82еÑ\80наÑ\82ива MySQL. ([https://secure.php.net/manual/ru/pgsql.installation.php Ð\9aак собрать PHP с поддержкой PostgreSQL]).",
+       "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] — это легковесная система баз данных, имеющая очень хорошую поддержку. ([https://secure.php.net/manual/ru/pdo.installation.php Как собрать PHP с поддержкой SQLite], работающей посредством PDO)",
+       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] â\80\94 Ñ\8dÑ\82о ÐºÐ¾Ð¼Ð¼ÐµÑ\80Ñ\87еÑ\81каÑ\8f ÐºÐ¾Ñ\80поÑ\80аÑ\82ивнаÑ\8f Ð±Ð°Ð·Ð° Ð´Ð°Ð½Ð½Ñ\8bÑ\85. ([https://secure.php.net/manual/ru/oci8.installation.php Как собрать PHP с поддержкой OCI8])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] â\80\94 Ñ\8dÑ\82о ÐºÐ¾Ð¼Ð¼ÐµÑ\80Ñ\87еÑ\81каÑ\8f ÐºÐ¾Ñ\80поÑ\80аÑ\82ивнаÑ\8f Ð±Ð°Ð·Ð° Ð´Ð°Ð½Ð½Ñ\8bÑ\85 Ð´Ð»Ñ\8f Windows. ([https://secure.php.net/manual/ru/sqlsrv.installation.php Как собрать PHP с поддержкой SQLSRV])",
+       "config-header-mysql": "Настройки MariaDB/MySQL",
        "config-header-postgres": "Настройки PostgreSQL",
        "config-header-sqlite": "Настройки SQLite",
        "config-header-oracle": "Настройки Oracle",
        "config-db-web-create": "Создать учётную запись, если она ещё не существует",
        "config-db-web-no-create-privs": "Учётная запись, указанная вами для установки, не обладает достаточными правами для создания учётной записи.\nУказанная здесь учётная запись уже должна существовать.",
        "config-mysql-engine": "Движок базы данных:",
-       "config-mysql-innodb": "InnoDB",
+       "config-mysql-innodb": "InnoDB (рекомендуется)",
        "config-mysql-myisam": "MyISAM",
        "config-mysql-myisam-dep": "''' Внимание.''' Вы выбрали механизм MyISAM для хранения данных MySQL. Он не рекомендуется к использованию по следующим причинам:\n* он слабо поддерживает параллелизм из-за табличных блокировок;\n* более склонен к потере данных, по сравнению с другими механизмами;\n* код MediaWiki не всегда учитывает особенности MyISAM должным образом.\n\nЕсли ваша MySQL поддерживает InnoDB, настоятельно рекомендуется выбрать этот механизм.\nЕсли ваша MySQL не поддерживает InnoDB, возможно, настало время обновиться.",
        "config-mysql-only-myisam-dep": "<strong>Предупреждение:</strong> MyISAM — единственная доступная система хранения данных для MySQL на этом компьютере, и она не рекомендуется для использования совместно с MediaWiki, потому что:\n* слабо поддерживает параллелизм из-за блокировки таблиц\n* больше других систем подвержена повреждению\n* кодовая база MediaWiki не всегда обрабатывает MyISAM так, как следует\n\nВаша MySQL не поддерживает InnoDB, так что, возможно, настало время для обновления.",
        "config-mysql-engine-help": "'''InnoDB''' почти всегда предпочтительнее, так как он лучше справляется с параллельным доступом.\n\n'''MyISAM''' может оказаться быстрее для вики с одним пользователем или с минимальным количеством поступающих правок, однако базы данных на нём портятся чаще, чем на InnoDB.",
-       "config-mysql-charset": "Кодировка базы данных:",
-       "config-mysql-binary": "Двоичный",
-       "config-mysql-utf8": "UTF-8",
-       "config-mysql-charset-help": "В '''двоичном режиме''' MediaWiki хранит UTF-8 текст в бинарных полях базы данных.\nЭто более эффективно, чем ''UTF-8 режим'' MySQL, и позволяет использовать полный набор символов Unicode.\n\nВ '''режиме UTF-8''' MySQL будет знать в какой кодировке находятся Ваши данные и может отображать и преобразовывать их соответствующим образом, но это не позволит вам хранить символы выше [https://en.wikipedia.org/wiki/Mapping_of_Unicode_character_planes Базовой Многоязыковой Плоскости].",
        "config-mssql-auth": "Тип аутентификации:",
        "config-mssql-install-auth": "Выберите тип проверки подлинности, который будет использоваться для подключения к базе данных во время процесса установки.\nЕсли вы выберите «{{int:config-mssql-windowsauth}}», будут использоваться учётные данные пользователя, под которым работает веб-сервер.",
        "config-mssql-web-auth": "Выберите тип проверки подлинности, который веб-сервер будет использовать для подключения к серверу базы данных во время обычного функционирования вики.\nЕсли вы выберите «{{int:config-mssql-windowsauth}}», будут использоваться учётные данные пользователя, под которым работает веб-сервер.",
        "config-license-help": "Многие общедоступные вики разрешают использовать свои материалы на условиях [https://freedomdefined.org/Definition/Ru свободных лицензий].\nЭто помогает созданию чувства общности, стимулирует долгосрочное участие.\nНо в этом нет необходимости для частных или корпоративных вики.\n\nЕсли вы хотите использовать тексты из Википедии или хотите, что в Википедию можно было копировать тексты из вашей вики, вам следует выбрать <strong>{{int:config-license-cc-by-sa}}</strong>.\n\nВикипедия ранее использовала лицензию GNU Free Documentation License.\nGFDL может быть использована, но она сложна для понимания и осложняет повторное использование материалов.",
        "config-email-settings": "Настройки электронной почты",
        "config-enable-email": "Включить исходящие e-mail",
-       "config-enable-email-help": "Ð\95Ñ\81ли Ð²Ñ\8b Ñ\85оÑ\82иÑ\82е, Ñ\87Ñ\82обÑ\8b Ñ\8dлекÑ\82Ñ\80оннаÑ\8f Ð¿Ð¾Ñ\87Ñ\82а Ñ\80абоÑ\82ала, Ð½ÐµÐ¾Ð±Ñ\85одимо Ð²Ñ\8bполниÑ\82Ñ\8c [Config-dbsupport-oracle/manual/ru/mail.configuration.php Ñ\81ооÑ\82веÑ\82Ñ\81Ñ\82вÑ\83Ñ\8eÑ\89ие Ð½Ð°Ñ\81Ñ\82Ñ\80ойки PHP].\nÐ\95Ñ\81ли Ð²Ñ\8b Ð½Ðµ Ñ\85оÑ\82иÑ\82е Ð¸Ñ\81полÑ\8cзоваÑ\82Ñ\8c Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾Ñ\81Ñ\82и Ñ\8dлекÑ\82Ñ\80онной Ð¿Ð¾Ñ\87Ñ\82Ñ\8b Ð² Ð²Ð¸ÐºÐ¸, Ð²Ñ\8b Ð¼Ð¾Ð¶ÐµÑ\82е ÐµÑ\91 отключить.",
+       "config-enable-email-help": "Ð\95Ñ\81ли Ð²Ñ\8b Ñ\85оÑ\82иÑ\82е, Ñ\87Ñ\82обÑ\8b Ñ\8dлекÑ\82Ñ\80оннаÑ\8f Ð¿Ð¾Ñ\87Ñ\82а Ñ\80абоÑ\82ала, Ð½ÐµÐ¾Ð±Ñ\85одимо Ð¿Ñ\80авилÑ\8cно Ð½Ð°Ñ\81Ñ\82Ñ\80оиÑ\82Ñ\8c [https://secure.php.net/manual/ru/mail.configuration.php Ñ\80абоÑ\82Ñ\83 Ð¿Ð¾Ñ\87Ñ\82Ñ\8b Ð² PHP].\nÐ\95Ñ\81ли Ð²Ñ\8b Ð½Ðµ Ñ\85оÑ\82иÑ\82е Ð¸Ñ\81полÑ\8cзоваÑ\82Ñ\8c Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾Ñ\81Ñ\82и Ñ\8dлекÑ\82Ñ\80онной Ð¿Ð¾Ñ\87Ñ\82Ñ\8b, Ð²Ñ\8b Ð¼Ð¾Ð¶ÐµÑ\82е ÐµÑ\91 Ð·Ð´ÐµÑ\81Ñ\8c отключить.",
        "config-email-user": "Включить электронную почту от участника к участнику",
        "config-email-user-help": "Разрешить всем пользователям отправлять друг другу электронные письма, если выставлена соответствующая настройка в профиле.",
        "config-email-usertalk": "Включить уведомления пользователей о сообщениях на их странице обсуждения",
        "config-install-interwiki-exists": "'''Предупреждение''': в интервики-таблице, кажется, уже есть записи.\nСоздание стандартного списка пропущено.",
        "config-install-stats": "Статистика инициализации",
        "config-install-keys": "Создание секретных ключей",
-       "config-insecure-keys": "'''Предупреждение.''' {{PLURAL:$2|1=Ключ безопасности $1, созданный во время установки, недостаточно надёжен|Ключи безопасности $1, созданные во время установки, недостаточно надёжны}}. Рассмотрите возможность {{PLURAL:$2|1=его|их}} изменения вручную.",
        "config-install-updates": "Предотвращение запуска ненужных обновлений",
        "config-install-updates-failed": "<strong>Ошибка:</strong> Вставка ключей обновления в таблицы завершилась со следующей ошибкой: $1",
        "config-install-sysop": "Создание учётной записи администратора",
index 89a72d4..68d40d5 100644 (file)
@@ -54,7 +54,7 @@
        "config-unicode-using-intl": "Uising the [https://pecl.php.net/intl intl PECL extension] fer Unicode normalization.",
        "config-unicode-pure-php-warning": "<strong>Warnishment:</strong> The [https://pecl.php.net/intl intl PECL extension] is no available tae haunle Unicode normalisation, fawin back tae slaw pure-PHP implementation.\nGif ye rin ae hei-traffic steid, ye shid read ae wee bit oan [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations Unicode normalization].",
        "config-unicode-update-warning": "<strong>Wairnin:</strong> The installed version o the Unicode normalisation wrapper uises an aulder version o [http://site.icu-project.org/ the ICU project's] library.\nYe shoud [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations upgrade] if ye are at aw concerned aboot uisin Unicode.",
-       "config-no-db": "Could nae find a suitable database driver! Ye need tae install a database driver for PHP.\nThe follaein database {{PLURAL:$2|type is|types are}} supportit: $1.\n\nIf you compiled PHP yersel, reconfigur it wi a database client enabled, for example, uisin <code>./configure --with-mysqli</code>.\nIf ye installed PHP frae a Debian or Ubuntu package, then ye an aa need tae install, for example, the <code>php5-mysql</code> package.",
+       "config-no-db": "Could nae find a suitable database driver! Ye need tae install a database driver for PHP.\nThe follaein database {{PLURAL:$2|type is|types are}} supportit: $1.\n\nIf you compiled PHP yersel, reconfigur it wi a database client enabled, for example, uisin <code>./configure --with-mysqli</code>.\nIf ye installed PHP frae a Debian or Ubuntu package, then ye an aa need tae install, for example, the <code>php-mysql</code> package.",
        "config-outdated-sqlite": "<strong>Warnishment:</strong> ye have SQLite $1, this is lower than minimum required version $2. SQLite will be onavailable.",
        "config-no-fts3": "<strong>Warnishment:</strong> SQLite is compiled wioot the [//sqlite.org/fts3.html FTS3 module], rake features will be onavailable oan this backend.",
        "config-pcre-old": "<strong>Fatal:</strong> PCRE $1 or later is required.\nYer PHP binary is link't wi PCRE $2.\n[https://www.mediawiki.org/wiki/Manual:Errors_and_symptoms/PCRE Mair informâtion].",
        "config-type-mssql": "Micræsaff SQL Server",
        "config-support-info": "MediaWiki supports the follaein database systems:\n\n$1\n\nGif ye dinna see the database system ye'r tryin tae uise listed ablow, than follae the instructions linked abuin tae enable support.",
        "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] is the primarie tairget fer MediaWiki n is best supported. MediaWiki warks forby wi [{{int:version-db-mariadb-url}} MariaDB] n [{{int:version-db-percona-url}} Percona Server], thir ar MySQL compatible. ([https://secure.php.net/manual/en/mysqli.installation.php Hou tae compile PHP wi MySQL support])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] is ae popular apen soorce database system aes aen alternative til MySQL. Thaur micht be some wee bugs still hingin roond, n it's na recommendit fer uiss in ae production environment. ([Config-dbsupport-oracle/manual/en/pgsql.installation.php Hou tae compile PHP wi PostgreSQL support])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] is ae popular apen soorce database system aes aen alternative til MySQL. Thaur micht be some wee bugs still hingin roond, n it's na recommendit fer uiss in ae production environment. ([https://secure.php.net/manual/en/pgsql.installation.php Hou tae compile PHP wi PostgreSQL support])",
        "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] is ae lichtweicht database system that is ver weel supportit. ([http://www.php.net/manual/en/pdo.installation.php Hou tae compile PHP wi SQLite support], uises PDO)",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] is ae commercial enterprise database. ([http://www.php.net/manual/en/oci8.installation.php Hou tae compile PHP wi OCI8 support])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] is ae commercial enterprise database fer Windows. ([Config-dbsupport-oracle/manual/en/sqlsrv.installation.php Hou tae compile PHP wi SQLSRV support])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] is ae commercial enterprise database fer Windows. ([https://secure.php.net/manual/en/sqlsrv.installation.php Hou tae compile PHP wi SQLSRV support])",
        "config-header-mysql": "MaSQL settins",
        "config-header-postgres": "PostgreSQL settins",
        "config-header-sqlite": "SQLite settins",
        "config-mysql-myisam-dep": "<strong>Warnishment:</strong> Ye'v selected MyISAM aes storage engine fer MySQL, this isna recommended fer uiss wi MediaWiki, cause:\n* it barelie supports concurrencie cause o buird lockin\n* it's mair prone til rot than ither engines\n* the MediaWiki codebase disna aye haunnle MyISAM aes it shid\n\nGif yer MySQL installâtion supports InnoDB, it is heilie recommended that ye chuise that instead.\nGif yer MySQL installâtion disna support InnoDB, than perhaps it's time fer aen upgrade.",
        "config-mysql-only-myisam-dep": "<strong>Warnishment:</strong> MyISAM is the yinly available storage engine fer MySQL oan this machine, n this isna recommended fer uiss wi MediaWiki, cause:\n* it barelie supports concurrencie cause o buird lockin\n* it is mair prone til rot than ither engines\n* the MediaWiki codebase disna aye haunnle MyISAM aes it shid\n\nYer MySQL installâtion dina support InnoDB, perhaps it's time fer aen upgrade.",
        "config-mysql-engine-help": "<strong>InnoDB</strong> is awmaist aye the best optie, aes it haes guid concurrencie support.\n\n<strong>MyISAM</strong> micht be faster in single-uiser or read-yinly installâtions.\nMyISAM databases tend tae rot mair aften than InnoDB databases.",
-       "config-mysql-charset": "Database chairacter set:",
-       "config-mysql-binary": "Binarie",
-       "config-mysql-utf8": "UTF-8",
-       "config-mysql-charset-help": "In <strong>binarie mode</strong>, MediaWiki stores UTF-8 tex til the database in binarie fields.\nThis is mair effeecient than MySQL's UTF-8 mode, n permits ye tae uise the ful range o Unicode chairacters.\n\nIn <strong>UTF-8 mode</strong>, MySQL will ken whit chairacter set yer data is in, n can present n convert it appropreeatelie, but it'll naw lat ye store chairacters abuin the [https://en.wikipedia.org/wiki/Mapping_of_Unicode_character_planes Basic Multilingual Plane].",
        "config-mssql-auth": "Authentication type:",
        "config-mssql-install-auth": "Select the authentication type that's tae be uised tae connect wi the database durin the installation process.\nGif ye select \"{{int:config-mssql-windowsauth}}\", the credeentials o whitever uiser the wabserver is rinnin aes will be uised.",
        "config-mssql-web-auth": "Select the authentication type that the wab server will uise tae connect wi the database server, durin ordinair operation o the wiki.\nGif ye select \"{{int:config-mssql-winowsauth}}\", the credeentials o whitever uiser the wabserver is rinnin aes will be uised.",
        "config-install-interwiki-exists": "<strong>Warnishment:</strong> The interwiki buird awreadie seems tae hae entries.\nSkippin defaut let.",
        "config-install-stats": "Ineetializin stateestics",
        "config-install-keys": "Generatin hidlins keys",
-       "config-insecure-keys": "<strong>Warnishment:</strong> {{PLURAL:$2|Ae secure key|Secure keys}} ($1) generated durin instawation {{PLURAL:$2|is|ar}} naw compleatelie safe. Consider chyngin {{PLURAL:$2|it|theim}} manuallie.",
        "config-install-updates": "Hinder the runnin o onneedit updates.",
        "config-install-updates-failed": "<strong>Mistak:</strong> Insertin update keys intae the buirds failed wi the folleain mistak: $1",
        "config-install-sysop": "Makin admeenistrâter uiser accoont",
index 410f480..363014c 100644 (file)
@@ -63,8 +63,6 @@
        "config-mysql-engine": "ආචයන එන්ජිම:",
        "config-mysql-innodb": "InnoDB",
        "config-mysql-myisam": "MyISAM",
-       "config-mysql-binary": "ද්විමය",
-       "config-mysql-utf8": "UTF-8",
        "config-mssql-windowsauth": "windows සහතික කිරීම.",
        "config-site-name": "විකියෙහි නම:",
        "config-site-name-blank": "අඩවි නාමයක් යොදන්න.",
index 7e110c2..ce43339 100644 (file)
@@ -4,7 +4,8 @@
                        "Dbc334",
                        "Eleassar",
                        "Yerpo",
-                       "HairyFotr"
+                       "HairyFotr",
+                       "Janezdrilc"
                ]
        },
        "config-desc": "Namestitveni program za MediaWiki",
@@ -76,9 +77,9 @@
        "config-db-schema-help": "Ta shema je po navadi v redu.\nSpremenite jo samo, če veste, da jo morate.",
        "config-pg-test-error": "Ne morem se povezati z zbirko podatkov <strong>$1</strong>: $2",
        "config-sqlite-dir": "Mapa podatkov SQLite:",
-       "config-type-mysql": "MySQL (ali združljiv)",
+       "config-type-mysql": "MySQL, MySQL ali združljiv",
        "config-support-info": "MediaWiki podpira naslednje sisteme zbirk podatkov:\n\n$1\n\nČe zgoraj ne vidite navedenega sistema zbirk podatkov, ki ga poskušate uporabiti, sledite navodilom na spodnji povezavi, da omogočite podporo.",
-       "config-header-mysql": "Nastavitve MySQL",
+       "config-header-mysql": "Nastavitve MariaDB/MySQL",
        "config-header-postgres": "Nastavitve PostgreSQL",
        "config-header-sqlite": "Nastavitve SQLite",
        "config-header-oracle": "Nastavitve Oracle",
        "config-db-web-account-same": "Uporabi enak račun kot za namestitev",
        "config-db-web-create": "Ustvari račun, če že ne obstaja",
        "config-mysql-engine": "Pogon skladiščenja:",
-       "config-mysql-innodb": "InnoDB",
+       "config-mysql-innodb": "InnoDB (priporočeno)",
        "config-mysql-myisam": "MyISAM",
-       "config-mysql-charset": "Nabor znakov zbirke podatkov:",
-       "config-mysql-binary": "Dvojiško",
-       "config-mysql-utf8": "UTF-8",
        "config-mssql-auth": "Tip avtentikacije:",
        "config-site-name": "Ime wikija:",
        "config-site-name-help": "To bo prikazano v naslovni vrstici brskalnika in na drugih različnih mestih.",
index 015b6ff..62f2538 100644 (file)
@@ -8,7 +8,8 @@
                        "Сербијана",
                        "Zoranzoki21",
                        "Acamicamacaraca",
-                       "Obsuser"
+                       "Obsuser",
+                       "BadDog"
                ]
        },
        "config-desc": "Инсталација за Медијавики",
@@ -32,7 +33,7 @@
        "config-page-upgrade": "Надоградња постојеће инсталације",
        "config-page-dbsettings": "Подешавања базе података",
        "config-page-name": "Назив",
-       "config-page-options": "Ð\9fодеÑ\88аваÑ\9aа",
+       "config-page-options": "Ð\9eпÑ\86иÑ\98е",
        "config-page-install": "Инсталирај",
        "config-page-complete": "Завршено!",
        "config-page-restart": "Поновно покретање инсталације",
        "config-db-password": "Лозинка базе података:",
        "config-db-port": "Порт базе података:",
        "config-db-schema": "Шема за Медијавики:",
-       "config-type-mysql": "MySQL (или компактибилан)",
+       "config-type-mysql": "MariaDB, MySQL, или компактибилан",
        "config-type-postgres": "PostgreSQL",
        "config-type-sqlite": "SQLite",
        "config-type-oracle": "Oracle",
        "config-type-mssql": "Microsoft SQL Server",
-       "config-header-mysql": "MySQL подешавања",
+       "config-header-mysql": "MariaDB/MySQL подешавања",
        "config-header-mssql": "Подешавања Microsoft SQL Server-а",
        "config-invalid-db-type": "Неважећи тип базе података.",
        "config-mssql-old": "Потребан је Microsoft SQL Server $1 или новији. Ви имате $2.",
-       "config-mysql-innodb": "InnoDB",
+       "config-mysql-innodb": "InnoDB (препоручено)",
        "config-mysql-myisam": "MyISAM",
-       "config-mysql-utf8": "UTF-8",
        "config-mssql-auth": "Тип провере идентитета:",
        "config-mssql-sqlauth": "Провера идентитета SQL Server-а",
        "config-mssql-windowsauth": "Провера идентитета Виндоуса",
index 04e96d0..dd2e51f 100644 (file)
@@ -58,7 +58,7 @@
        "config-unicode-using-intl": "Använder [https://pecl.php.net/intl intl PECL-tillägget] för Unicode-normalisering.",
        "config-unicode-pure-php-warning": "'''Varning:''' [https://pecl.php.net/intl intl PECL-tillägget] är inte tillgängligt för att hantera Unicode-normalisering, faller tillbaka till en långsamt implementering i ren PHP.\nOm du driver en högtrafikerad webbplats bör du läsa lite om [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations Unicode-normalisering].",
        "config-unicode-update-warning": "<strong>Varning:</strong> Den installerade versionen av Unicode-normaliserings \"wrappern\" använder en äldre version av [http://site.icu-project.org/ ICU projektets] bibliotek.\nDu bör [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations uppgradera] om är intresserad av att använda Unicode.",
-       "config-no-db": "Kunde inte hitta en lämplig databasdrivrutin! Du måste installera en databasdrivrutin för PHP.\nFöljande databas{{PLURAL:$2|typ |typer}} stöds: $1.\n\nI du själv kompilerat din PHP, konfigurera den med en databasklient aktiverad genom att t.ex. använda <code>./configure --with-mysqli</code>.\nOm du installerade PHP från ett Debian- eller Ubuntupaket måste du även installera, t.ex. <code>php5-mysql</code>-paketet.",
+       "config-no-db": "Kunde inte hitta en lämplig databasdrivrutin! Du måste installera en databasdrivrutin för PHP.\nFöljande databas{{PLURAL:$2|typ |typer}} stöds: $1.\n\nI du själv kompilerat din PHP, konfigurera den med en databasklient aktiverad genom att t.ex. använda <code>./configure --with-mysqli</code>.\nOm du installerade PHP från ett Debian- eller Ubuntupaket måste du även installera, t.ex. <code>php-mysql</code>-paketet.",
        "config-outdated-sqlite": "'''Varning:''' du har SQLite $1, vilket är lägre än minimikravet version $2. SQLite kommer inte att vara tillgänglig.",
        "config-no-fts3": "'''Varning:''' SQLite kompileras utan [//sqlite.org/fts3.html FTS3-modulen], sökfunktioner kommer att vara otillgängliga på denna backend.",
        "config-pcre-old": "'''Kritiskt:''' PCRE $1 eller senare krävs.\nDin PHP-binär är länkad till PCRE $2.\n[https://www.mediawiki.org/wiki/Manual:Errors_and_symptoms/PCRE Mer information].",
        "config-sqlite-dir-help": "SQLite lagrar all data i en enda fil.\n\nDen katalog du anger måste vara skrivbar av webbservern under installationen.\n\nDet bör <strong>inte</strong> vara tillgänglig via webben; Det är därför vi inte lägger den där dina PHP-filer är.\n\nInstallationsprogrammet kommer att skriva en <code>.htaccess</code>-fil tillsammans med den, men om det misslyckas kan någon få tillgång till den råa databasen.\nVlken innehåller rå användardata (e-postadresser, hashade lösenord) samt borttagna revideringar och annan begränsad data på wiki.\n\nÖverväga att lägga databasen någon helt annanstans, till exempel i <code>/var/lib/mediawiki/yourwiki</code>.",
        "config-oracle-def-ts": "Standardtabellutrymme (tablespace):",
        "config-oracle-temp-ts": "Tillfälligt tabellutrymme (tablespace):",
-       "config-type-mysql": "MySQL (eller kompatibelt)",
+       "config-type-mysql": "MariaDB, MySQL eller kompatibelt",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki stöder följande databassystem:\n\n$1\n\nOm du inte ser det databassystem som du försöker använda nedanstående, följ då instruktionerna länkade ovan för aktivera stöd för det.",
-       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] är det primära målet för MediaWiki och det stöds bäst. MediaWiki fungerar även med [{{int:version-db-mariadb-url}} MariaDB] och [{{int:version-db-percona-url}} Percona Server], som är kompatibla med MySQL. ([https://secure.php.net/manual/en/mysqli.installation.php Hur man kompilerar PHP med stöd för MySQL])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] är ett populärt databassystem med öppen källkod som ett alternativ till MySQL. ([Config-dbsupport-oracle/manual/en/pgsql.installation.php Hur man kompilerar PHP med PostgreSQL stöd])",
-       "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] är en lättviktsdatabassystem med väldigt bra stöd. ([http://www.php.net/manual/en/pdo.installation.php Hur man kompilerar PHP med SQLite stöd], använder PDO)",
-       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] är en kommersiellt databas för företag. ([http://www.php.net/manual/en/oci8.installation.php Hur man kompilerar PHP med OCI8 stöd])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] är en kommersiellt databas för företag för Windows. ([Config-dbsupport-oracle/manual/en/sqlsrv.installation.php Hur man kompilerar PHP med SQLSRV stöd])",
-       "config-header-mysql": "MySQL-inställningar",
+       "config-dbsupport-mysql": "* [{{int:version-db-mariadb-url}} MariaDB] är det primära målet för MediaWiki och stöds bäst. MediaWiki fungerar även med [{{int:version-db-mysql-url}} MySQL] och [{{int:version-db-percona-url}} Percona Server], som är kompatibla med MariaDB. ([https://secure.php.net/manual/en/mysqli.installation.php Hur man kompilerar PHP med stöd för MySQL])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] är ett populärt databassystem med öppen källkod som ett alternativ till MySQL. ([https://secure.php.net/manual/en/pgsql.installation.php Hur man kompilerar PHP med PostgreSQL-stöd])",
+       "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] är en lättviktsdatabassystem med väldigt bra stöd. ([https://secure.php.net/manual/en/pdo.installation.php Hur man kompilerar PHP med SQLite stöd], använder PDO)",
+       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] är en kommersiellt databas för företag. ([https://secure.php.net/manual/en/oci8.installation.php Hur man kompilerar PHP med OCI8 stöd])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] är en kommersiellt databas för företag för Windows. ([https://secure.php.net/manual/en/sqlsrv.installation.php Hur man kompilerar PHP med SQLSRV stöd])",
+       "config-header-mysql": "MariaDB/MySQL-inställningar",
        "config-header-postgres": "PostgreSQL-inställningar",
        "config-header-sqlite": "SQLite-inställningar",
        "config-header-oracle": "Oracle-inställningar",
        "config-db-web-create": "Skapa kontot om det inte redan finns",
        "config-db-web-no-create-privs": "Det konto som du har angett för installation har inte tillräcklig behörighet för att skapa ett konto.\nDet konto du anger här måste redan finnas.",
        "config-mysql-engine": "Lagringsmotor:",
-       "config-mysql-innodb": "InnoDB",
+       "config-mysql-innodb": "InnoDB (rekommenderas)",
        "config-mysql-myisam": "MyISAM",
        "config-mysql-myisam-dep": "'''Varning:''' Du har valt MyISAM som lagringsmotor för MySQL, vilket inte rekommenderas för användning med MediaWiki eftersom:\n* den knappt stöder samtidigt exekvering på grund av låsning av tabeller\n* den är mer benägen att korrumpera data än andra motorer\n* MediaWiki-kodbasen hanterar inte alltid MyISAM som den ska\n\nOm din MySQL-installation stöder InnoDB, är det starkt rekommenderat att du väljer det istället.\nOm din MySQL-installation inte stöder InnoDB, kanske det är dags för en uppgradering.",
        "config-mysql-only-myisam-dep": "'''Varning:''' MyISAM är den enda tillgängliga lagringsmotorn för MySQL på denna maskin, och den är inte rekommenderad att använda med MediaWiki eftersom:\n* den knappt stöder samtidigt exekvering på grund av låsning av tabeller\n* den är mer benägen att korrumpera data än andra motorer\n* MediaWiki-kodbasen hanterar inte alltid MyISAM som den ska\n\nDin MySQL-installation stöder inte InnoDB, det kanske är dags för en uppgradering.",
        "config-mysql-engine-help": "'''InnoDB''' är nästan alltid det bästa valet eftersom den har ett bra system för samtidiga arbeten.\n\n'''MyISAM''' kan vara snabbare i enanvändarläge eller skrivskyddade installationer.\nMyISAM-databaser tenderar att bli korrupta oftare än InnoDB-databaser.",
-       "config-mysql-charset": "Databasteckensuppsättning:",
-       "config-mysql-binary": "Binär",
-       "config-mysql-utf8": "UTF-8",
-       "config-mysql-charset-help": "I '''binärt läge''' lagrar MediaWiki UTF-8 text till databasen i binära fält.\nDetta är mer effektivt än MySQLs UTF-8-läge, och den tillåter dig att använda den fulla uppsättningen av Unicode-tecken.\n\nI '''UTF-8-läge''' vet MySQL vilket teckenuppsättning din data är i och kan presentera och konvertera den på ett lämpligt sätt, men den tillåter dig inte att lagra tecken över [https://en.wikipedia.org/wiki/Mapping_of_Unicode_character_planes Basic Multilingual Plane].",
        "config-mssql-auth": "Autentiseringstyp:",
        "config-mssql-install-auth": "Välj autentiseringstypen som kommer att användas för att ansluta till databasen under installationsprocessen.\nOm du väljer \"{{int:config-mssql-windowsauth}}\", kommer autentiseringsuppgifterna för den användare webbservern körs som att användas.",
        "config-mssql-web-auth": "Välj autentiseringstypen som kommer att användas för att ansluta till databasen under ordinarie drift av wikin.\nOm du väljer \"{{int:config-mssql-windowsauth}}\", kommer autentiseringsuppgifterna för den användare webbservern körs som att användas.",
        "config-install-interwiki-exists": "<strong>Varning:</strong> Interwiki-tabellen verkar redan innehålla poster.\nHoppar över standardlistan.",
        "config-install-stats": "Initierar statistik",
        "config-install-keys": "Genererar hemliga nycklar",
-       "config-insecure-keys": "'''Varning:''' {{PLURAL:$2|En säkerhetsnyckel|Säkerhetsnycklar}} ($1) som generades under installationen är inte helt {{PLURAL:$2|säker|säkra}} . Överväg att ändra {{PLURAL:$2|den|dem}} manuellt.",
        "config-install-updates": "Förhindra att onödiga uppdateringar körs",
        "config-install-updates-failed": "<strong>Fel:</strong> Infogning av uppdateringsnycklar i tabeller misslyckades med följande fel:$1",
        "config-install-sysop": "Skapar administratörskonto",
index a531f4f..c2368da 100644 (file)
@@ -43,8 +43,6 @@
        "config-upgrade-done-no-regenerate": "தரமுயர்த்தல் முழுமையடைந்தது.\nநீங்கள் தற்போது [$1 உங்கள் விக்கியைப் பயன்படுத்தத் துவங்கலாம்].",
        "config-db-web-account": "வலை அணுகலுக்கான தரவுத் தளக் கணக்கு",
        "config-mysql-engine": "சேமிப்பு இயந்திரம்:",
-       "config-mysql-charset": "தரவுத் தள வரியுருத் தொகுதி:",
-       "config-mysql-utf8": "UTF-8",
        "config-site-name": "விக்கியின் பெயர்:",
        "config-site-name-blank": "ஒரு தளத்தின் பெயரை உள்ளிடுக.",
        "config-ns-generic": "திட்டம்",
index ce949d1..dd4bd0c 100644 (file)
        "config-mysql-engine": "స్టోరేజీ ఇంజను:",
        "config-mysql-innodb": "InnoDB",
        "config-mysql-myisam": "MyISAM",
-       "config-mysql-charset": "డేటాబేసు కారెక్టరు సెట్:",
-       "config-mysql-binary": "బైనరీ",
-       "config-mysql-utf8": "UTF-8",
        "config-mssql-auth": "ఆథెంటికేషన్ రకం:",
        "config-mssql-sqlauth": "SQL Server ఆథెంటికేషన్",
        "config-mssql-windowsauth": "విండోస్ ఆథెంటికేషన్",
index bdd1ff8..a21909e 100644 (file)
@@ -53,7 +53,7 @@
        "config-env-hhvm": "มี HHVM $1 ติดตั้งอยู่",
        "config-unicode-using-intl": "ใช้[https://pecl.php.net/intl ส่วนขยาย intl PECL] สำหรับการปรับ Unicode เข้าสู่รูปปกติ (Unicode normalization)",
        "config-unicode-pure-php-warning": "<strong>คำเตือน:</strong> [https://pecl.php.net/intl intl ส่วนขยาย PECL] ไม่พร้อมใช้งานสำหรับการจัดมาตรฐาน Unicode กำลังกลับไปใช้ PHP ที่แท้จริงแบบช้า\nถ้าคุณเปิดดำเนินการไซต์ที่มีปริมาณการใช้งานสูง คุณควรอ่านดูเกี่ยวกับ[https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations การจัดมาตรฐาน Unicode] สักเล็กน้อย",
-       "config-no-db": "ไม่พบไดรเวอร์ฐานข้อมูลที่เหมาะสม! คุณจำเป็นต้องติดตั้งไดรเวอร์ฐานข้อมูลสำหรับ PHP\nชนิดฐานข้อมูลต่อไปนี้ได้รับการสนับสนุน: $1\n\nถ้าคุณคอมไพล์ PHP ด้วยตนเอง ให้กำหนดค่าใหม่อีกครั้งโดยเปิดใช้งานไคลเอนต์ฐานข้อมูล ตัวอย่างเช่น ใช้ <code>./configure --with-mysqli</code>\nถ้าคุณติดตั้ง PHP จากแพกเกจ Debian หรือ Ubuntu คุณก็จำเป็นต้องติดตั้งแพกเกจต่อไปนี้ ตัวอย่างเช่น แพกเกจ <code>php5-mysql</code>",
+       "config-no-db": "ไม่พบไดรเวอร์ฐานข้อมูลที่เหมาะสม! คุณจำเป็นต้องติดตั้งไดรเวอร์ฐานข้อมูลสำหรับ PHP\nชนิดฐานข้อมูลต่อไปนี้ได้รับการสนับสนุน: $1\n\nถ้าคุณคอมไพล์ PHP ด้วยตนเอง ให้กำหนดค่าใหม่อีกครั้งโดยเปิดใช้งานไคลเอนต์ฐานข้อมูล ตัวอย่างเช่น ใช้ <code>./configure --with-mysqli</code>\nถ้าคุณติดตั้ง PHP จากแพกเกจ Debian หรือ Ubuntu คุณก็จำเป็นต้องติดตั้งแพกเกจต่อไปนี้ ตัวอย่างเช่น แพกเกจ <code>php-mysql</code>",
        "config-outdated-sqlite": "<strong>คำเตือน:</strong> คุณมี SQLite $1 ซึ่งต่ำกว่ารุ่นขั้นต่ำที่ต้องการ $2 ดังนั้น SQLite จะไม่พร้อมให้ใช้งาน",
        "config-no-fts3": "<strong>คำเตือน:</strong> SQLite ถูกคอมไพล์โดยไม่มี[//sqlite.org/fts3.html โมดูล FTS3] คุณลักษณะการค้นหาจะไม่พร้อมใช้งานบนแบ็กเอนด์นี้",
        "config-pcre-old": "<strong>ข้อผิดพลาดร้ายแรง:</strong> ต้องใช้ PCRE $1 หรือสูงกว่า\nไบนารี PHP ของคุณถูกเชื่อมโยงกับ PCRE $2\n[https://www.mediawiki.org/wiki/Manual:Errors_and_symptoms/PCRE ข้อมูลเพิ่มเติม]",
        "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] คือระบบฐานข้อมูลแบบโอเพนซอร์สที่ได้รับความนิยมสูงที่สามารถใช้แทน MySQL ได้ ([https://secure.php.net/manual/en/pgsql.installation.php วิธีการคอมไพล์ PHP ด้วยการสนับสนุน PostgreSQL])",
        "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] คือระบบฐานข้อมูลขนาดเล็กที่ได้รับการสนับสนุนดีมาก ([http://www.php.net/manual/en/pdo.installation.php วิธีการคอมไพล์ PHP ด้วยการสนับสนุน SQLite], ใช้ PDO)",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] คือฐานข้อมูลสำหรับองค์กรพาณิชย์ ([http://www.php.net/manual/en/oci8.installation.php วิธีการคอมไพล์ PHP ด้วยการสนับสนุน OCI8])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] คือฐานข้อมูลสำหรับองค์กรพาณิชย์สำหรับ Windows. ([Config-dbsupport-oracle/manual/en/sqlsrv.installation.php วิธีการคอมไพล์ PHP ด้วยการสนับสนุน SQLSRV])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] คือฐานข้อมูลสำหรับองค์กรพาณิชย์สำหรับ Windows. ([https://secure.php.net/manual/en/sqlsrv.installation.php วิธีการคอมไพล์ PHP ด้วยการสนับสนุน SQLSRV])",
        "config-header-mysql": "การตั้งค่า MySQL",
        "config-header-postgres": "การตั้งค่า PostgreSQL",
        "config-header-sqlite": "การตั้งค่า SQLite",
        "config-mysql-myisam-dep": "<strong>คำเตือน:</strong> คุณได้เลือก MyISAM เป็นกลไกที่จัดเก็บข้อมูลสำหรับ MySQL ซึ่่งไม่แนะนำให้ใช้กับ MediaWiki เนื่องจาก:\n* ไม่ค่อยสนับสนุนกระบวนการทำงานพร้อมกันเนื่องจากการล็อกตารางข้อมูล\n* มีแนวโน้มที่จะเสียหายมากกว่ากลไกอื่น\n* Codebase ของ MediaWiki ไม่สามารถจัดการ MyISAM ได้ดีเท่าที่ควร\n\nถ้าการติดตั้ง MySQL ของคุณสนับสนุน InnoDB แนะนำอย่างยิ่งว่าให้คุณเลือก InnoDB แทน\nถ้าการติดตั้ง MySQL ของคุณไม่สนับสนุน InnoDB อาจถึงเวลาที่คุณต้องอัปเกรดแล้ว",
        "config-mysql-only-myisam-dep": "<strong>คำเตือน:</strong> กลไกที่จัดเก็บข้อมูลสำหรับ MySQL ที่พร้อมใช้งานบนเครื่องนี้มีเพียง MyISAM ซึ่่งไม่แนะนำให้ใช้กับ MediaWiki เนื่องจาก:\n* ไม่ค่อยสนับสนุนกระบวนการทำงานพร้อมกันเนื่องจากการล็อกตารางข้อมูล\n* มีแนวโน้มที่จะเสียหายมากกว่ากลไกอื่น\n* Codebase ของ MediaWiki ไม่สามารถจัดการ MyISAM ได้ดีเท่าที่ควร\n\nการติดตั้ง MySQL ของคุณไม่สนับสนุน InnoDB อาจถึงเวลาที่คุณต้องอัปเกรดแล้ว",
        "config-mysql-engine-help": "<strong>InnoDB</strong> เป็นตัวเลือกที่เกือบดีที่สุดเสมอ เนื่องจากมีการสนับสนุนกระบวนการทำงานพร้อมกัน\n\n<strong>MyISAM</strong> อาจทำงานได้เร็วกว่าในการติดตั้งแบบผู้ใช้คนเดียวหรือแบบอ่านอย่างเดียว\nฐานข้อมูล MyISAM มักจะได้รับความเสียหายบ่อยมากกว่าฐานข้อมูล InnoDB",
-       "config-mysql-charset": "ชุดอักขระของฐานข้อมูล:",
-       "config-mysql-binary": "ไบนารี",
-       "config-mysql-utf8": "UTF-8",
-       "config-mysql-charset-help": "ใน<strong>โหมดไบนารี</strong> MediaWiki จะจัดเก็บข้อความ UTF-8 ไว้ในฐานข้อมูลในเขตข้อมูลไบนารี\nการใช้โหมดไบนารีจะมีประสิทธิภาพมากกว่าการใช้โหมด UTF-8 ของ MySQL และจะอนุญาตให้คุณสามารถใช้อักขระที่มีใน Unicode ได้หมดทุกช่วง\n\nใน<strong>โหมด UTF-8</strong> MySQL จะทราบว่าข้อมูลของคุณอยู่ในชุดอักขระได้ และจะสามารถเสนอและแปลงข้อมูลดังกล่าวได้อย่างเหมาะสม แต่จะไม่อนุญาตให้คุณจัดเก็บข้อมูลที่มีอักขระนอกเหนือจากในช่วง[https://en.wikipedia.org/wiki/Mapping_of_Unicode_character_planes เพลนหลายภาษาพื้นฐาน]",
        "config-mssql-auth": "ชนิดการยืนยันตัวตน:",
        "config-mssql-install-auth": "เลือกชนิดการยืนยันตัวตนที่จะใช้เชื่อมต่อไปยังฐานข้อมูลในระหว่างกระบวนการติดตั้ง\nถ้าคุณเลือก \"{{int:config-mssql-windowsauth}}\" ข้อมูลประจำตัวที่ระบุว่าเว็บเซิร์ฟเวอร์กำลังทำงานในฐานะผู้ใช้ใดจะถูกใช้",
        "config-mssql-web-auth": "เลือกชนิดการยืนยันตัวตนที่จะใช้เชื่อมต่อไปยังฐานข้อมูลในระหว่างการใช้งานวิกิตามปกติ\nถ้าคุณเลือก \"{{int:config-mssql-windowsauth}}\" ข้อมูลประจำตัวที่ระบุว่าเว็บเซิร์ฟเวอร์กำลังทำงานในฐานะผู้ใช้ใดจะถูกใช้",
index ab6632f..3614333 100644 (file)
@@ -57,7 +57,7 @@
        "config-unicode-using-intl": "Ginagamit ang [https://pecl.php.net/intl intl dugtong na PECL] para sa pagsasanormal ng Unikodigo.",
        "config-unicode-pure-php-warning": "'''Babala''': Ang [https://pecl.php.net/intl dugtong ng internasyunal na PECL] ay hindi makukuha upang makapanghawak ng pagpapanormal ng Unikodigo, na babagsak na pabalik sa mabagal na pagsasakatuparan ng dalisay na PHP.\nKapag nagpapatakbo ka ng isang pook na mataas ang trapiko, dapat kang bumasa ng kaunti hinggil sa [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations pagpapanormal ng Unikodigo].",
        "config-unicode-update-warning": "'''Babala''': Ang nakaluklok na bersiyon ng pambalot ng pagpapanormal ng Unikodigo ay gumagamit ng isang mas matandang bersiyon ng aklatan ng [http://site.icu-project.org/ proyekto ng ICU].\nDapat kang [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations magtaas ng uri] kung may pag-aalala ka hinggil sa paggamit ng Unikodigo.",
-       "config-no-db": "Hindi matagpuan ang isang angkop na tagapagmaneho ng kalipunan ng datos! Kailangan mong magluklok ng isang tagapagmaneho ng kalipunan ng dato para sa PHP.\nTinatangkilik ang {{PLURAL:$2|mga}} sumusunod na uri ng kalipunan ng dato: $1.\n\nKung ikaw mismo ang nangalap ng PHP, muling isaayos ito na pinagagana ang isang kliyente ng kalipunan ng dato, halimbawa na ang paggamit ng <code>./configure --with-mysqli</code>.\nKung iniluklok mo ang PHP mula sa isang pakete ng Debian o Ubuntu, kung gayon kailangan mo ring magluklok, halimbawa ay ang paketeng <code>php5-mysql</code>.",
+       "config-no-db": "Hindi matagpuan ang isang angkop na tagapagmaneho ng kalipunan ng datos! Kailangan mong magluklok ng isang tagapagmaneho ng kalipunan ng dato para sa PHP.\nTinatangkilik ang {{PLURAL:$2|mga}} sumusunod na uri ng kalipunan ng dato: $1.\n\nKung ikaw mismo ang nangalap ng PHP, muling isaayos ito na pinagagana ang isang kliyente ng kalipunan ng dato, halimbawa na ang paggamit ng <code>./configure --with-mysqli</code>.\nKung iniluklok mo ang PHP mula sa isang pakete ng Debian o Ubuntu, kung gayon kailangan mo ring magluklok, halimbawa ay ang paketeng <code>php-mysql</code>.",
        "config-outdated-sqlite": "'''Babala''': mayroong kang $1 ng SQLite, na mas mababa kaysa sa pinaka mababang kailangang bersiyon na $2. Magiging hindi makukuha ang SQLite.",
        "config-no-fts3": "'''Warning''': Ang SQLite ay hindi itinala at tinipon na wala ang [//sqlite.org/fts3.html modulong FTS3], ang mga tampok na panghanap ay magiging hindi makukuha sa ibabaw ng panlikod na dulong ito.",
        "config-pcre-no-utf8": "'''Malubha''': Tila tinipon ang modyul na PCRE ng PHP na wala ang suporta ng PCRE_UTF8.\nNangangailangan ang MediaWiki ng suporta ng UTF-8 upang maging tama ang pag-andar.",
        "config-sqlite-dir-help": "Iniimbak ng SQLite ang lahat ng dato sa loob ng isang nag-iisang file.\n\nAng ibibigay mong directory ay dapat na maging masusulatan ng tagapaghain ng kasaputan habang nag-i-install.\n\n'''Hindi''' ito dapat na mapuntahan sa pamamagitan ng web server, ito ang dahilan kung bakit hindi namin ito inilalagay sa kung nasaan ang iyong mga file ng PHP.\n\nAng installer ay magsusulat ng isang file na <code>.htaccess</code> na kasama ito, subalit kapag nabigo iyon mayroong isang tao na maaaring makakuha ng pagka nakakapunta sa iyong hilaw na database.\nKasama riyan ang hilaw na dato ng tagagamit (mga email address, pinaghalong mga password) pati na ang nabura nang mga pagbabago at iba pang may pagbabawal na dato ng wiki.\n\nIsaalang-alang ang paglalagay na magkakasama ang database sa ibang lugar, halimbawa na ang sa loob ng <code>/var/lib/mediawiki/yourwiki</code>.",
        "config-oracle-def-ts": "Likas na nakatakdang puwang ng talahanayan:",
        "config-oracle-temp-ts": "Pansamantalang puwang ng talahanayan:",
-       "config-type-mysql": "MySQL (o katugma)",
+       "config-type-mysql": "MariaDB, MySQL, o katugma",
        "config-type-postgres": "PostgreSQL",
        "config-type-sqlite": "SQLite",
        "config-type-oracle": "Oracle",
        "config-dbsupport-postgres": "* Ang [{{int:version-db-postgres-url}} PostgreSQL] ay isang bantog na sistema ng kalipunan ng dato na bukas ang pinagmulan na panghalili sa MySQL. ([https://secure.php.net/manual/en/pgsql.installation.php Paano magtipon ng PHP na mayroong suporta ng PostgreSQL]).",
        "config-dbsupport-sqlite": "* Ang [{{int:version-db-sqlite-url}} SQLite] ay isang magaan ang timbang na sistema ng kalipunan ng dato na sinusuportahan nang napaka mainam. ([http://www.php.net/manual/en/pdo.installation.php Paano magtipon ng PHP na mayroong suporta ng SQLite], gumagamit ng PDO)",
        "config-dbsupport-oracle": "* Ang [{{int:version-db-oracle-url}} Oracle] ay isang kalipunan ng dato ng kasigasigang pangkalakal. ([http://www.php.net/manual/en/oci8.installation.php Paano magtipunan ng PHP na mayroong suporta ng OCI8])",
-       "config-header-mysql": "Mga katakdaan ng MySQL",
+       "config-header-mysql": "Mga katakdaan ng MariaDB/MySQL",
        "config-header-postgres": "Mga katakdaan ng PostgreSQL",
        "config-header-sqlite": "Mga katakdaan ng SQLite",
        "config-header-oracle": "Mga katakdaan ng Oracle",
        "config-mysql-myisam": "MyISAM",
        "config-mysql-myisam-dep": "'''Babala''': Pinili mo ang MyISAM bilang makinang imbakan para sa MySQL, na hindi iminumungkahi para gamitin sa MediaWiki, sapagkat:\n* bahagya lamang itong sumusuporta ng pagkakasundu-sundo dahil sa pagkakandado ng talahanayan\n* mas malaki ang pagkakataon na kapitan ng sira kaysa sa ibang mga makina\n* ang himpilang kodigo ng MediaWiki ay hindi palaging humahawak ng MyISAM ayon sa nararapat\n\nKung ang iyong nakaluklok na MySQL ay sumusuporta ng InnoDB, higit na iminumungkahi na piliin mo iyon sa halip.\nKung ang iyong nakaluklok na MySQL ay hindi sumusuporta ng InnoDB, marahil ay panahon na para sa isang pagtataas ng uri.",
        "config-mysql-engine-help": "Ang '''InnoDB''' ay ang halos palaging pinaka mainam na mapipili, dahil mayroon itong mabuting suporta ng pagkakasundu-sundo.\n\nMaaaring mas mabilis ang '''MyISAM''' sa mga pagluluklok na pang-isahang tagagamit o mababasa lamang.\nMay gawi ang mga kalipunan ng dato ng MyISAM na masira nang mas madalas kaysa sa mga kalipunan ng dato ng InnoDB.",
-       "config-mysql-charset": "Pangkat ng panitik ng kalipunan ng dato:",
-       "config-mysql-binary": "Binaryo",
-       "config-mysql-utf8": "UTF-8",
-       "config-mysql-charset-help": "Sa '''gawi na binaryo''', iniimbak ng MediaWiki ang tekstong UTF-8 sa kalipunan ng dato sa loob ng mga hanay na binaryo.\nMas kapaki-pakinabang ito kaysa sa gawi na UTF-8 ng MySQL, at nagpapahintulot sa iyo upang magamit ang buong kasaklawan ng mga panitik ng Unikodigo.\n\nSa ''gawi na UTF-8''', malalaman ng MySQL kung sa anong pangkat ng panitik nakapaloob ang iyong dato, at angkop na makakapagharap at makapapagpalit nito, subalit hindi ka nito papayagan na mag-imbak ng mga panitik na nasa itaas ng [https://en.wikipedia.org/wiki/Mapping_of_Unicode_character_planes Basic Multilingual Plane] o Saligang Tapyas na Pangmaramihang Wika.",
        "config-site-name": "Pangalan ng wiki:",
        "config-site-name-help": "Lilitaw ito sa bareta ng pamagat ng pantingin-tingin at sa samu't saring ibang mga lugar.",
        "config-site-name-blank": "Magpasok ng isang pangalan ng sityo.",
        "config-install-interwiki-exists": "'''Babala''': Tila may mga laman na ang talahanayan ng interwiki.\nNilalaktawan ang likas na nakatakdang talaan.",
        "config-install-stats": "Sinisimulan ang estadistika",
        "config-install-keys": "Ginagawa ang lihim na mga susi",
-       "config-insecure-keys": "'''Babala:''' Nalikha ang {{PLURAL:$2|A secure key|ligtas na mga susi}} ($1) habang ang pagluluklok {{PLURAL:$2|ay|ay}} hindi pa lubos na ligtas. Isaalang-alang ang kinakamay na pagbago {{PLURAL:$2|nito|ng mga ito}}.",
        "config-install-sysop": "Nililikha ang account ng tagagamit na tagapangasiwa",
        "config-install-subscribe-fail": "Hindi nagawang magpasipi mula sa mediawiki-announce: $1",
        "config-install-subscribe-notpossible": "Hindi nakalagak ang cURL at hindi makukuha ang <code>allow_url_fopen</code>",
index 9f63ba8..93d44e4 100644 (file)
        "config-unicode-using-intl": "Unikod normalleştirmesi için [https://pecl.php.net/intl intl PECL uzantısı] kullanılıyor.",
        "config-unicode-pure-php-warning": "<strong>Uyarı:</strong> [https://pecl.php.net/intl intl PECL uzantısı] Unicode normalizasyonunu kaldırabilecek şekilde müsait değil; bu yüzden sayfa saf PHP uygulamasına dönüyor. Yüksek trafik alan bir sayfa çalıştırıyorsanız, [//www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations Unicode normalizasyonu] ile ilgili biraz bilgi almalısınız.",
        "config-unicode-update-warning": "<strong>Uyarı:</strong> Yüklü durumdaki Unicode normalleştirme sarıcı [http://site.icu-project.org/ ICU proje] kütüphanesinin eski bir sürümünü kullanır.\nUnicode kullanımı konusunda endişeleriniz varsa [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations yükseltme] yapmanız gerekmektedir.",
-       "config-no-db": "Uygun bir veri tabanı sürücüsü bulunamadı! PHP için bir veri tabanı sürücüsü kurmanız gerekir. Şu veri tabanı {{PLURAL:$2|türleri|türleri}} desteklenmektedir: $1\n\nEğer PHP'yi kendiniz derlediyseniz, bu durumda <code>./configure --with-mysqli</code> kullanarak etkinleştirilmiş veri tabanı istemcisi ile yeniden yapılandırmalısınız.\nPHP'yi bir Debian veya Ubuntu paketinden yüklediyseniz, bu durumda <code>php5-mysql</code> paketini de kurmanız gerekir.",
+       "config-no-db": "Uygun bir veri tabanı sürücüsü bulunamadı! PHP için bir veri tabanı sürücüsü kurmanız gerekir. Şu veri tabanı {{PLURAL:$2|türleri|türleri}} desteklenmektedir: $1\n\nEğer PHP'yi kendiniz derlediyseniz, bu durumda <code>./configure --with-mysqli</code> kullanarak etkinleştirilmiş veri tabanı istemcisi ile yeniden yapılandırmalısınız.\nPHP'yi bir Debian veya Ubuntu paketinden yüklediyseniz, bu durumda <code>php-mysql</code> paketini de kurmanız gerekir.",
        "config-outdated-sqlite": "<strong>Uyarı:</strong> Elinizde SQLite $1 var. Gerekli minimum sürüm: $2. SQLite kullanılamayacaktır.",
        "config-no-fts3": "<strong>Uyarı:</strong> SQLite [//sqlite.org/fts3.html FTS3 modülü] olmadan derlendi, bu arkayüzde arama özellikleri kullanılamayacaktır.",
        "config-pcre-old": "<strong>Ağır hata:</strong> PCRE $1 veya daha üst versiyon gerekli.\nSizin PHP kurulumunuz PCRE $2 ile bağlı.\n[https://www.mediawiki.org/wiki/Manual:Errors_and_symptoms/PCRE Daha fazla bilgi].",
        "config-pcre-no-utf8": "<strong>Önemli hata:</strong> PHP'nin PCRE modülü PCRE_UTF8 desteği olmadan derlenmiş gözüküyor.\nMediaWiki'nin doğru çalışabilmesi için UTF-8 desteği gereklidir.",
        "config-memory-raised": "PHP'nin <code>memory_limit</code> (hafıza sınırı) değeri $1, $2'ye yükseltildi.",
        "config-memory-bad": "<strong>Uyarı:</strong> PHP'nin <code>memory_limit</code> (hafıza sınırı) değeri $1.\nBu büyük ihtimalle çok düşük.\nKurulum başarısız olabilir!",
-       "config-apc": "[https://secure.php.net/apc APC] kurulu",
-       "config-apcu": "[https://secure.php.net/apcu APCu] yüklendi",
-       "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] kurulu",
+       "config-apc": "[https://secure.php.net/apc APC] kuruldu",
+       "config-apcu": "[https://secure.php.net/apcu APCu] kuruldu",
+       "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] kuruldu",
        "config-no-cache-apcu": "<strong>Uyarı:</strong> [https://secure.php.net/apcu APCu] ya da [https://www.iis.net/downloads/microsoft/wincache-extension WinCache] kurulumu bulunamadı.\nNesne önbellekleme etkin değil.",
        "config-mod-security": "<strong>'''Uyarı:'''</strong> Web sunucunuz [https://modsecurity.org/mod_security2 mod_security] etkin. Bunun birçok yaygın yapılandırması bulunur ve eğer yanlış yapılandırılmış ise, bu MediaWiki ve kullanıcılara isteğe bağlı içerik göndermesine izin veren diğer yazılımlar için sorun oluşturabilir.\nMümkünse bu devre dışı bırakılmalıdır. Aksi takdirde rastgele hatalar alırsanız [https://modsecurity.org/documentation/ mod_security belgelemesine] bakın ya da sunucunuzun desteğine başvurun.",
        "config-diff3-bad": "GNU diff3 bulunamadı.",
@@ -90,6 +90,8 @@
        "config-no-cli-uri": "<strong>Uyarı:</strong> Herhangi bir <code>--scriptpath</code> belirlenmemiş, varsayılan kullanılıyor: <code>$1</code>.",
        "config-using-server": "Sunucu adı olarak \"<nowiki>$1</nowiki>\" kullanılıyor.",
        "config-using-uri": "Sunucu URLsi olarak \"<nowiki>$1$2</nowiki>\" kullanılıyor.",
+       "config-uploads-not-safe": "<strong>Uyarı:</strong> Yüklemeler için varsayılan dizininiz <code>$1</code>, rastgele komut dosyalarının yürütülmesine karşı savunmasızdır.\nMediaWiki, karşıya yüklenen tüm dosyaları güvenlik tehditlerine karşı denetlese de, yüklemeleri etkinleştirmeden önce [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Security#Upload_security bu güvenlik açığını kapatmanız] önemle tavsiye edilir.",
+       "config-no-cli-uploads-check": "<strong>Uyarı:</strong> Yüklemeler için varsayılan dizininiz (<code>$1</code>), CLI yüklemesi sırasında rastgele kod yürütme güvenlik açığı açısından denetlenmez.",
        "config-db-type": "Veritabanı tipi:",
        "config-db-host": "Veritabanı sunucusu:",
        "config-db-host-help": "Veritabanı sunucunuz farklı bir sunucu üzerinde ise, ana bilgisayar adını veya IP adresini buraya girin.\n\nPaylaşılan ağ barındırma hizmeti kullanıyorsanız, barındırma sağlayıcınız size doğru bir ana bilgisayar adını kendi belgelerinde vermiştir.\n\nEğer MySQL kullanan bir Windows sunucusuna yükleme yapıyorsanız, sunucu adı olarak \"localhost\" kullanırsanız çalışmayabilir. Çalışmazsa, yerel IP adresi için \"127.0.0.1\" deneyin.\n\nPostgreSQL kullanıyorsanız, bu alanı bir Unix soketi ile bağlanmak için boş bırakın.",
        "config-db-web-create": "Eğer oluşturulmuş hesap yoksa yeni hesap oluştur",
        "config-db-web-no-create-privs": "Kurulum için belirlediğiniz hesap, hesap yaratımı için gerekli izinlere sahip değil.\nBurada belirttiğiniz hesap halihazırda var olmalı.",
        "config-mysql-engine": "Depolama motoru:",
-       "config-mysql-innodb": "InnoDB",
+       "config-mysql-innodb": "InnoDB (önerilen)",
        "config-mysql-myisam": "MyISAM",
-       "config-mysql-charset": "Veritabanı karakter seti",
-       "config-mysql-binary": "İkili",
-       "config-mysql-utf8": "UTF-8",
        "config-mssql-auth": "Kimlik doğrulama türü:",
        "config-mssql-install-auth": "Kurulum işlemi sırasında veritabanına bağlanmak için kullanılacak doğrulama türünü seçin.\n\"{{int:config-mssql-windowsauth}}\"'ı seçerseniz,ağ sunucusu olarak çalışan kullanıcının kimlik bilgileri kullanılacaktır.",
        "config-mssql-sqlauth": "SQL Server kimlik doğrulaması",
index 391e8ae..9ebbc27 100644 (file)
@@ -41,8 +41,6 @@
        "config-db-schema": "MediaWiki өчен төзелеш:",
        "config-mysql-innodb": "InnoDB",
        "config-mysql-myisam": "MyISAM",
-       "config-mysql-binary": "Икеле",
-       "config-mysql-utf8": "UTF-8",
        "config-ns-generic": "Проект",
        "config-ns-other": "Башка (күрсәтегез)",
        "config-ns-other-default": "MyWiki",
index 4caa2ff..3f31990 100644 (file)
@@ -62,7 +62,7 @@
        "config-unicode-using-intl": "Використовувати [https://pecl.php.net/intl міжнародне розширення PECL] для нормалізації Юнікоду.",
        "config-unicode-pure-php-warning": "'''Увага''': [https://pecl.php.net/intl міжнародне розширення PECL] не може провести нормалізацію Юнікоду.\nЯкщо ваш сайт має високий трафік, вам варто почитати про [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations нормалізацію Юнікоду].",
        "config-unicode-update-warning": "'''Увага''': Встановлена версія обгортки нормалізації Юнікоду використовує стару версію бібліотеки [http://site.icu-project.org/ проекту ICU].\nВи маєте [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations оновити версію], якщо плануєте повноцінно використовувати Юнікод.",
-       "config-no-db": "Не вдалося знайти потрібний драйвер бази даних! Вам необхідно встановити драйвер бази даних для PHP. Підтримуються {{PLURAL:$2|такий тип|такі типи}} баз даних: $1.\n\nЯкщо ви скомпілювали PHP самостійно, переналаштуйте його з увімкненим клієнтом бази даних, наприклад за допомогою <code>./configure --with-mysqli</code>.\n\nЯкщо установлено PHP з пакетів Debian або Ubuntu, тоді ви також повинні встановити, наприклад, пакунок <code>php5-mysql</code>.",
+       "config-no-db": "Не вдалося знайти потрібний драйвер бази даних! Вам необхідно встановити драйвер бази даних для PHP. Підтримуються {{PLURAL:$2|такий тип|такі типи}} баз даних: $1.\n\nЯкщо ви скомпілювали PHP самостійно, переналаштуйте його з увімкненим клієнтом бази даних, наприклад за допомогою <code>./configure --with-mysqli</code>.\n\nЯкщо установлено PHP з пакетів Debian або Ubuntu, тоді ви також повинні встановити, наприклад, пакунок <code>php-mysql</code>.",
        "config-outdated-sqlite": "'''Увага''': у Вас встановлена версія SQLite $1, а це нижче, ніж мінімально необхідна версія $2. SQLite буде недоступним.",
        "config-no-fts3": "'''Увага''': SQLite зібраний без [//sqlite.org/fts3.html модуля FTS3], функції пошуку не будуть працювати у цій системі.",
        "config-pcre-old": "'''Фатальна помилка:''' потрібно PCRE версії $1 або пізнішої.\nВаш виконуваний файл PHP пов'язаний з PCRE версії $2.\n[https://www.mediawiki.org/wiki/Manual:Errors_and_symptoms/PCRE Подробиці].",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki підтримує такі системи баз даних:\n\n$1\n\nЯкщо Ви не бачите серед перерахованих систему баз даних, яку використовуєте, виконайте вказівки, вказані вище, щоб увімкнути підтримку.",
        "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] є основною для MediaWiki і найкраще підтримується.  MediaWiki також працює із [{{int:version-db-mariadb-url}} MariaDB] та [{{int:version-db-percona-url}} Percona Server], які сумісні з MySQL.  ([https://secure.php.net/manual/en/mysqli.installation.php як зібрати PHP з допомогою MySQL])",
-       "config-dbsupport-postgres": "*  [{{int:version-db-postgres-url}} PostgreSQL] — популярна відкрита СУБД, альтернатива MySQL. ([Config-dbsupport-oracle/manual/en/pgsql.installation.php як зібрати PHP з допомогою PostgreSQL]).",
+       "config-dbsupport-postgres": "*  [{{int:version-db-postgres-url}} PostgreSQL] — популярна відкрита СУБД, альтернатива MySQL. ([https://secure.php.net/manual/en/pgsql.installation.php як зібрати PHP з допомогою PostgreSQL]).",
        "config-dbsupport-sqlite": "*  [{{int:version-db-sqlite-url}} SQLite] — легка система баз даних, яка дуже добре підтримується. ([http://www.php.net/manual/en/pdo.installation.php Як зібрати PHP з допомогою SQLite], що використовує PDO)",
        "config-dbsupport-oracle": "*  [{{int:version-db-oracle-url}} Oracle] — комерційна база даних масштабу підприємства. ([http://www.php.net/manual/en/oci8.installation.php Як зібрати PHP з підтримкою OCI8])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] — це комерційна база даних для Windows масштабу підприємства. ([Config-dbsupport-oracle/manual/ru/sqlsrv.installation.php Як зібрати PHP з підтримкою SQLSRV])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] — це комерційна база даних для Windows масштабу підприємства. ([https://secure.php.net/manual/en/sqlsrv.installation.php Як зібрати PHP з підтримкою SQLSRV])",
        "config-header-mysql": "Налаштування MySQL",
        "config-header-postgres": "Налаштування PostgreSQL",
        "config-header-sqlite": "Налаштування SQLite",
        "config-mysql-myisam-dep": "'''Увага''': Ви обрали MyISAM для зберігання даних MySQL, що не рекомендовано для роботи з MediaWiki, оскільки:\n* він слабко підтримує паралелізм через блокування таблиць\n* він більш схильний до ушкоджень, ніж інші двигуни\n* база коду MediaWiki не завжди працює з MyISAM так, як мала б.\n\nЯкщо Ваша інсталяція MySQL підтримує InnoDB, дуже рекомендується вибрати цей двигун.\nЯкщо Ваша інсталяція MySQL не підтримує InnoDB, можливо настав час її оновити.",
        "config-mysql-only-myisam-dep": "\"'Зауваження:\"' MyISAM є єдиним механізмом для зберігання MySQL на цій машині, який не рекомендується для використання з MediaWiki, оскільки:\n* слабо підтримує паралелізм через блокування таблиць\n* більш схильний до пошкоджень, ніж інші двигуни\n* код MediaWiki не завжди розглядає MyISAM, як повинен\n\nТвоє встановлення MySQL не підтримує InnoDB, можливо, потрібно оновити.",
        "config-mysql-engine-help": "'''InnoDB''' є завжди кращим вибором, оскільки краще підтримує паралельний доступ.\n\n'''MyISAM''' може бути швидшим для одного користувача або в інсталяціях read-only.\nБази даних MyISAM схильні псуватись частіше, ніж бази InnoDB.",
-       "config-mysql-charset": "Кодування бази даних:",
-       "config-mysql-binary": "Двійкове",
-       "config-mysql-utf8": "UTF-8",
-       "config-mysql-charset-help": "У '''бінарному режимі''' MediaWiki зберігає текст UTF-8 у базі даних з бінарними полями.\nЦе більш ефективно, ніж UTF-8 режим MySQL, і дозволяє використовувати увесь набір символів Юнікоду.\n\nУ '''режимі UTF-8''' MySQL буде знати, якого символу стосуються Ваші дані, і могтиме відображати та конвертувати їх належним чином, але не дозволятиме зберігати символи, що виходять за межі [https://en.wikipedia.org/wiki/Mapping_of_Unicode_character_planes Basic Multilingual Plane].",
        "config-mssql-auth": "Тип автентифікації:",
        "config-mssql-install-auth": "Виберіть тип перевірки автентичності, який буде використовуватися для підключення до бази даних під час процесу установки. \nЯкщо ви оберете \"{{int:config-mssql-windowsauth}}\", будуть використовуватися облікові дані користувача, під яким працює веб-сервер.",
        "config-mssql-web-auth": "Виберіть тип перевірки автентичності, який веб-сервер буде використовувати для підключення до сервера бази даних під час звичайного функціонування вікі. \nЯкщо ви оберете \"{{int:config-mssql-windowsauth}}\", будуть використовуватися облікові дані користувача, під яким працює веб-сервер.",
        "config-license-help": "Чимало загальнодоступних вікі публікують увесь свій вміст під [https://freedomdefined.org/Definition вільною ліцензією]. Це розвиває відчуття спільної власності і заохочує довготривалу участь. У загальному випадку для приватної чи корпоративної вікі у цьому немає необхідності.\n\nЯкщо Ви хочете мати змогу використовувати текст з Вікіпедії і дати Вікіпедії змогу використовувати текст, скопійований з Вашої вікі, вам необхідно обрати <strong>{{int:config-license-cc-by-sa}}</strong>.\n\nРаніше Вікіпедія використовувала GNU Free Documentation License.\nGFDL — допустима ліцензія, але у ній важко розібратися, а контент під GFDL важко використовувати повторно.",
        "config-email-settings": "Налаштування електронної пошти",
        "config-enable-email": "Увімкнути вихідну електронну пошту",
-       "config-enable-email-help": "Якщо Ви хочете, що електронна пошта працювала, необхідно виставити коректні [Config-dbsupport-oracle/manual/en/mail.configuration.php налаштування пошти у PHP].\nЯкщо Вам не потрібні жодні можливості електронної пошти у вікі, можете тут їх відключити.",
+       "config-enable-email-help": "Якщо Ви хочете, що електронна пошта працювала, необхідно виставити коректні [Config-dbsupport-oracle/manual/en/mail.configuration.php налаштування пошти у PHP].\nЯкщо Вам не потрібні жодні можливості електронної пошти у вікі, можете тут їх відімкнути.",
        "config-email-user": "Увімкнути електронну пошту користувач-користувачеві",
        "config-email-user-help": "Дозволити усім користувачам надсилати один одному електронну пошту, якщо вони увімкнули цю можливість у своїх налаштуваннях.",
        "config-email-usertalk": "Увімкнути сповіщення про повідомлення на сторінці обговорення користувача",
        "config-install-interwiki-exists": "'''Увага''': Таблиця інтервікі уже, здається, має записи.\nСтворення стандартного списку пропускається.",
        "config-install-stats": "Ініціалізація статистики",
        "config-install-keys": "Генерація секретних ключів",
-       "config-insecure-keys": "'''Увага:''' {{PLURAL:$2|1=Секретний ключ|Секретні ключі}} ($1), {{PLURAL:$2|1=згенерований в процесі встановлення, недостатньо надійний|згенеровані в процесі встановлення, недостатньо надійні}}. Розгляньте можливість {{PLURAL:$2|1=його|їх}} заміни вручну.",
        "config-install-updates": "Запобігти запуску непотрібних оновлень",
        "config-install-updates-failed": "<strong>Помилка:</strong> Вставка оновленних ключів в таблиці не вдалося через таку помилку:$1",
        "config-install-sysop": "Створення облікового запису адміністратора",
        "config-nofile": "Файл \"$1\" не знайдено. Його видалено?",
        "config-extension-link": "Чи знаєте ви, що ваше вікі підтримує [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Extensions розширення]?\n\nВи можете переглядати [https://www.mediawiki.org/wiki/Special:MyLanguage/Category:Extensions_by_category розширення по категорії] або в [https://www.mediawiki.org/wiki/Extension_Matrix матрицю розширень] щоб побачити повний список розширень.",
        "config-skins-screenshots": "$1 (скріншоти: $2)",
+       "config-extensions-requires": "$1 (вимагає $2)",
        "config-screenshot": "скріншот",
        "mainpagetext": "<strong>Програмне забезпечення «MediaWiki» встановлено.</strong>",
        "mainpagedocfooter": "Інформацію про роботу з цією вікі можна знайти на сторінці [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents Довідка:Вміст].\n\n== Деякі корисні ресурси ==\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Список налаштувань];\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ Часті питання з приводу MediaWiki];\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Розсилка повідомлень про появу нових версій MediaWiki];\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Локалізувати MediaWiki своєю мовою]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Дізнатися, як боротися зі спамом у своїй вікі]"
index 29ce143..ca87d60 100644 (file)
@@ -56,7 +56,7 @@
        "config-unicode-using-intl": "Sẽ sử dụng [https://pecl.php.net/intl phần mở rộng PECL intl] để chuẩn hóa Unicode.",
        "config-unicode-pure-php-warning": "<strong>Cảnh báo:</strong>  [https://pecl.php.net/intl intl PECL extension] không được phép xử lý Unicode chuẩn hóa, trả lại thực thi PHP-gốc chậm.\nNếu bạn chạy một site lưu lượng lớn, bạn phải để ý qua một chút trên  [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations Unicode normalization].",
        "config-unicode-update-warning": "<strong>Cảnh báo:</strong> Phiên bản cài đặt của gói Unicode chuẩn hóa sử dụng một phiên bản cũ của thư viện [http://site.icu-project.org/ the ICU project].\nBạn phải [https://www.mediawiki.org/wiki/Special:MyLanguage/nâng cấp Unicode_normalization_considerations] nếu bạn quan tâm đến việc sử dụng Unicode.",
-       "config-no-db": "Không tìm thấy một trình điều khiển cơ sở dữ liệu phù hợp! Bạn cần phải cài một trình điều khiển cơ sở dữ liệu cho PHP.\n{{PLURAL:$2|Loại|Các loại}} cơ sở dữ liệu sau đây được hỗ trợ: $1.\n\nNếu bạn đã biên dịch PHP lấy, cấu hình lại nó mà kích hoạt một trình khách cơ sở dữ liệu, ví dụ bằng lệnh <code>./configure --with-mysqli</code>.\nNếu bạn đã cài PHP từ một gói Debian hoặc Ubuntu, thì bạn cũng cần phải cài ví dụ gói <code>php5-mysql</code>.",
+       "config-no-db": "Không tìm thấy một trình điều khiển cơ sở dữ liệu phù hợp! Bạn cần phải cài một trình điều khiển cơ sở dữ liệu cho PHP.\n{{PLURAL:$2|Loại|Các loại}} cơ sở dữ liệu sau đây được hỗ trợ: $1.\n\nNếu bạn đã biên dịch PHP lấy, cấu hình lại nó mà kích hoạt một trình khách cơ sở dữ liệu, ví dụ bằng lệnh <code>./configure --with-mysqli</code>.\nNếu bạn đã cài PHP từ một gói Debian hoặc Ubuntu, thì bạn cũng cần phải cài ví dụ gói <code>php-mysql</code>.",
        "config-outdated-sqlite": "<strong>Chú ý:</strong> Bạn có SQLite $1, phiên bản này thấp hơn phiên bản yêu câu tối thiểu $2. SQLite sẽ không có tác dụng.",
        "config-no-fts3": "<strong>Chú ý:</strong> SQLite được biên dịch mà không có [//sqlite.org/fts3.html mô đun FTS3], nên các chức năng tìm kiếm sẽ bị vô hiệu trên hệ thống phía sau này.",
        "config-pcre-old": "<strong>Lỗi chí tử:</strong> PCRE $1 trở lên được yêu cầu phải có.\nBản nhị phân PHP của bạn dang được liên kết với PCRE $2.\n[https://www.mediawiki.org/wiki/Manual:Errors_and_symptoms/PCRE Thông tin bổ sung].",
        "config-sqlite-dir-help": "SQLite lưu tất cả các dữ liệu trong một tập tin duy nhất.\n\nThư mục mà bạn cung cấp phải cho phép máy chủ Web ghi vào khi cài đặt.\n\n<strong>Không</strong> nên làm cho nó truy cập được qua Web; đây là lý do chúng tôi không đặt nó vào cùng thư mục với các tập tin PHP của bạn.\n\nTrình cài đặt sẽ ghi một tập tin <code>.htaccess</code> đi kèm, nhưng nếu thất bại người nào đó có thể truy cập vào cơ sở dữ liệu thô của bạn.\nĐiều đó bao gồm dữ liệu người dùng thô (địa chỉ thư điện tử, mật khẩu được băm) cũng như các phiên bản bị xóa và dữ liệu bị hạn chế khác trên wiki.\n\nXem xét đặt cơ sở dữ liệu tại nơi nào khác hẳn, ví dụ trong <code>/var/lib/mediawiki/wiki_cua_ban</code>.",
        "config-oracle-def-ts": "Không gian bảng mặc định:",
        "config-oracle-temp-ts": "Không gian bảng tạm:",
-       "config-type-mysql": "MySQL (hoặc tương hợp)",
+       "config-type-mysql": "MariaDB, MySQL, hoặc tương hợp",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki hỗ trợ các hệ thống cơ sở dữ liệu sau đây:\n\n$1\n\nNếu bạn không thấy hệ thống cơ sở dữ liệu mà bạn đang muốn sử dụng được liệt kê dưới đây, thì hãy theo chỉ dẫn được liên kết ở trên để kích hoạt tính năng hỗ trợ.",
-       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] là mục tiêu chính cho MediaWiki và được hỗ trợ tốt nhất. MediaWiki cũng làm việc với [{{int:version-db-mariadb-url}} MariaDB] và [{{int:version-db-percona-url}} Percona Server], là những cơ sở dữ liệu tương thích với MySQL. ([https://secure.php.net/manual/en/mysqli.installation.php Làm thế nào để biên dịch PHP với sự hỗ trợ của MySQL])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] là một hệ thống cơ sở dữ liệu mã nguồn mở phổ biến như là một thay thế cho MySQL. ([Config-dbsupport-oracle/manual/en/pgsql.installation.php Làm thế nào để biên dịch PHP với sự hỗ trợ của PostgreSQL])",
-       "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] là một hệ thống cơ sở dữ liệu dung lượng nhẹ được hỗ trợ rất tốt. ([http://www.php.net/manual/en/pdo.installation.php Làm thế nào để biên dịch PHP với sự hỗ trợ của SQLite], sử dụng PDO)",
-       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] là một cơ sở dữ liệu doanh nghiệp thương mại. ([http://www.php.net/manual/en/oci8.installation.php Làm thế nào để biên dịch PHP với sự hỗ trợ của OCI8])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] là một cơ sở dữ liệu doanh nghiệp thương mại cho Windows. ([Config-dbsupport-oracle/manual/en/sqlsrv.installation.php Làm thế nào để biên dịch PHP với sự hỗ trợ của SQLSRV])",
-       "config-header-mysql": "Thiết lập MySQL",
+       "config-dbsupport-mysql": "* [{{int:version-db-mariadb-url}} MariaDB] là mục tiêu chính cho MediaWiki và được hỗ trợ tốt nhất. MediaWiki cũng làm việc với [{{int:version-db-mysql-url}} MySQL] và [{{int:version-db-percona-url}} Percona Server], là những cơ sở dữ liệu tương thích với MariaDB. ([https://secure.php.net/manual/en/mysqli.installation.php Làm thế nào để biên dịch PHP với sự hỗ trợ của MySQL])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] là một hệ thống cơ sở dữ liệu mã nguồn mở phổ biến như là một thay thế cho MySQL. ([https://secure.php.net/manual/en/pgsql.installation.php Làm thế nào để biên dịch PHP với sự hỗ trợ của PostgreSQL])",
+       "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] là một hệ thống cơ sở dữ liệu dung lượng nhẹ được hỗ trợ rất tốt. ([https://secure.php.net/manual/en/pdo.installation.php Làm thế nào để biên dịch PHP với sự hỗ trợ của SQLite], sử dụng PDO)",
+       "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] là một cơ sở dữ liệu doanh nghiệp thương mại. ([https://secure.php.net/manual/en/oci8.installation.php Làm thế nào để biên dịch PHP với sự hỗ trợ của OCI8])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] là một cơ sở dữ liệu doanh nghiệp thương mại cho Windows. ([https://secure.php.net/manual/en/sqlsrv.installation.php Làm thế nào để biên dịch PHP với sự hỗ trợ của SQLSRV])",
+       "config-header-mysql": "Thiết lập MariaDB/MySQL",
        "config-header-postgres": "Thiết lập PostgreSQL",
        "config-header-sqlite": "Thiết lập SQLite",
        "config-header-oracle": "Thiết lập Oracle",
        "config-db-web-create": "Mở tài khoản nếu chưa tồn tại",
        "config-db-web-no-create-privs": "Tài khoản mà bạn xác định để cài đặt không có đủ quyền để tạo một tài khoản. Tài khoản mà bạn chỉ ra ở đây phải thực sự tồn tại trước đó.",
        "config-mysql-engine": "Máy lưu trữ:",
-       "config-mysql-innodb": "InnoDB",
+       "config-mysql-innodb": "InnoDB (khuyến khích)",
        "config-mysql-myisam": "MyISAM",
        "config-mysql-myisam-dep": "<strong>Cảnh báo:</strong> Bạn đã chọn MyISAM làm động cơ lưu trữ cho MySQL, điều này không được khuyến khích sử dụng với MediaWiki, bởi vì:\n* Nó ít hỗ trợ đồng thời do việc khóa bảng\n* Nó dễ bị lỗi hơn so với các động cơ khác\n* Kho mã nguồn của MediaWiki không phải khi nào cũng xử lý MyISAM như mong muốn\n\nNếu cài đặt MySQL của bạn hỗ trợ InnoDB, đặc biệt khuyến cáo bạn nên chọn để thay thế.\nNếu cài đặt MySQL của bạn không hỗ trợ InnoDB, có lẽ đã đến lúc để nâng cấp.",
        "config-mysql-only-myisam-dep": "<strong>Cảnh báo:</strong> MyISAM chỉ là công cụ lưu trữ có sẵn cho MySQL trên máy tính này, và điều này không được khuyến khích sử dụng với MediaWiki, bởi vì:\n* Nó ít hỗ trợ đồng thời do việc khóa khóa\n* Nó là dễ bị hư hỏng hơn các engine khác\n* Codebase MediaWiki không phải khi nào cũng xử lý MyISAM như mong muốn\n\nCài đặt MySQL của bạn không hỗ trợ InnoDB, có lẽ đã đến lúc để nâng cấp.",
        "config-mysql-engine-help": "<strong>InnoDB</strong> hầu như luôn là tùy chọn tốt nhất, vì nó có hỗ trợ đồng thời rất tốt.\n\n<strong>MyISAM</strong> có thể nhanh hơn trong chế độ một người dùng hoặc các cài đặt chỉ-đọc (read-only).\nCơ sở dữ liệu MyISAM có xu hướng thường xuyên bị hỏng hóc hơn so với cơ sở dữ liệu InnoDB.",
-       "config-mysql-charset": "Bảng mã cơ sở dữ liệu:",
-       "config-mysql-binary": "Nhị phân",
-       "config-mysql-utf8": "UTF-8",
-       "config-mysql-charset-help": "Trong <strong>chế độ nhị phân</strong>, MediaWiki lưu văn bản UTF-8 vào cơ sở dữ liệu trong các trường nhị phân.\nĐiều này hiệu quả hơn so với chế độ UTF-8 của MySQL, và cho phép bạn sử dụng đầy đủ các ký tự Unicode.\n\nTrong <strong>chế độ UTF-8 </strong>, MySQL sẽ biết những ký tự nào thiết lập dữ liệu của bạn, và có thể trình bày và chuyển đổi nó một cách thích hợp, nhưng nó sẽ không cho phép bạn lưu trữ các ký tự nằm trên [https://en.wikipedia.org/wiki/Mapping_of_Unicode_character_planes Basic Multilingual Plane].",
        "config-mssql-auth": "Kiểu xác thực:",
        "config-mssql-install-auth": "Chọn loại xác thực sẽ được sử dụng để kết nối với cơ sở dữ liệu trong quá trình cài đặt.\nNếu bạn chọn “{{int:config-mssql-windowsauth}}”, thông tin của bất cứ người sử dụng nào mà máy chủ web đang chạy sẽ được sử dụng.",
        "config-mssql-web-auth": "Chọn kiểu xác thực mà máy chủ web sẽ sử dụng để kết nối đến máy chủ cơ sở dữ liệu, trong quá trình hoạt động bình thường của wiki.\nNếu bạn chọn “{{int:config-mssql-windowsauth}}”, thông tin của bất cứ người sử dụng nào mà máy chủ web đang hoạt động sẽ được sử dụng.",
        "config-license-help": "Nhiều wiki công khai phát hành tất cả các đóng góp theo một [https://freedomdefined.org/Definition/Vi?uselang=vi giấy phép tự do].\nĐiều này giúp tạo nên thái độ cộng đồng sở hữu và ủng hộ sự đóng góp lâu dài.\nNói chung, một wiki riêng tư hoặc của công ty không nhất thiết phải sử dụng một giấy phép tự do.\n\nNếu bạn muốn được phép sử dụng văn bản từ Wikipedia và muốn Wikipedia nhận được những văn bản được sao chép từ wiki của bạn, bạn nên chọn <strong>{{int:config-license-cc-by-sa}}</strong>.\n\nWikipedia từng sử dụng Giấy phép Tài liệu Tự do GNU.\nGFDL là một giấy phép hợp lệ nhưng khó hiểu trên thực tế.\nNội dung được phát hành theo GFDL cũng khó tái sử dụng.",
        "config-email-settings": "Thiết lập thư điện tử",
        "config-enable-email": "Cho phép gửi thư điện tử đi",
-       "config-enable-email-help": "Nếu bạn muốn khả năng gửi thư điện tử, [Config-dbsupport-oracle/manual/en/mail.configuration.php thiết lập mail của PHP] cần phải được cấu hình đúng.\nNếu bạn không muốn sử dụng bất kỳ tính năng thư điện tử nào, bạn có thể vô hiệu chúng ở đây.",
+       "config-enable-email-help": "Nếu bạn muốn khả năng gửi thư điện tử, [https://secure.php.net/manual/en/mail.configuration.php thiết lập mail của PHP] cần phải được cấu hình đúng.\nNếu bạn không muốn sử dụng bất kỳ tính năng thư điện tử nào, bạn có thể vô hiệu chúng ở đây.",
        "config-email-user": "Cho phép người dùng gửi thư điện tử cho người dùng khác",
        "config-email-user-help": "Cho phép tất cả người dùng gửi thư điện tử cho nhau, nếu họ đã kích hoạt nó trong cài đặt tùy chọn của họ.",
        "config-email-usertalk": "Gửi thư thông báo về tin nhắn mới",
        "config-cache-options": "Thiết lập bộ nhớ đệm đối tượng:",
        "config-cache-help": "Lưu vào bộ nhớ đệm đối tượng được sử dụng để cải thiện tốc độ của MediaWiki bằng cách lưu vào bộ nhớ đệm những dữ liệu thường xuyên sử dụng.\nCác trang web từ trung bình cho đến các trang web lớn rất được khuyến khích kích hoạt tính năng này, và các trang web nhỏ cũng sẽ nhìn thấy lợi ích tương tự.",
        "config-cache-none": "Không lưu vào bộ nhớ đệm (không có chức năng nhiệm vụ sẽ được loại bỏ, nhưng tốc độ có thể bị ảnh hưởng trên các trang web wiki lớn hơn)",
-       "config-cache-accel": "Bộ nhớ đệm đối tượng PHP (APC, APCu, XCache, hoặc WinCache)",
+       "config-cache-accel": "Bộ nhớ đệm đối tượng PHP (APC, APCu, hoặc WinCache)",
        "config-cache-memcached": "Sử dụng Memcached (cần thiết lập và cấu hình thêm)",
        "config-memcached-servers": "Máy chủ Memcached:",
        "config-memcached-help": "Danh sách các địa chỉ IP để sử dụng cho Memcached .\nNên xác định trên một dòng và chỉ định các cổng được sử dụng. Ví dụ:\n 127.0.0.1:11211\n 192.168.1.25:1234",
        "config-install-interwiki-exists": "'''Cảnh báo:''' Hình như đã có mục trong bảng liên wiki.\nĐã bỏ qua danh sách mặc định.",
        "config-install-stats": "Đang khởi tạo các thống kê",
        "config-install-keys": "Tạo ra các chìa khóa bí mật",
-       "config-insecure-keys": "<strong>Cảnh báo:</strong> {{PLURAL:$2|Một khóa an toàn|Khóa an toàn}} ($1) được tạo ra trong quá trình cài đặt {{PLURAL:$2}}không phải an toàn hẳn. Hãy cân nhắc việc thay đổi {{PLURAL:$2|nó|chúng}} thủ công.",
        "config-install-updates": "Tránh các cập nhật không cần thiết",
        "config-install-updates-failed": "<strong>Lỗi:</strong> Chèn phím cập nhật vào các bảng không thành công với các lỗi sau:1$",
        "config-install-sysop": "Đang mở tài khoản người dùng bảo quản viên",
        "config-install-mainpage-failed": "Không thể chèn trang đầu: $1",
        "config-install-done": "<strong>Xin chúc mừng!</strong>\nBạn đã cài đặt MediaWiki.\n\nBộ cài đặt đã tạo ra một tập tin <code>LocalSettings.php</code>.\nTập tin này chứa tất cả các cấu hình của bạn.\n\nBạn sẽ cần phải tải nó về và đặt nó trong thư mục cài đặt wiki của bạn (cùng thư mục với index.php). Việc tải về có lẽ sẽ được khởi động tự động.\n\nNếu bản tải về không được cung cấp, hoặc nếu bạn hủy bỏ nó, bạn có thể khởi động lại tải về bằng cách nhấn vào liên kết dưới đây:\n\n$3\n\n<strong>Lưu ý:</strong> Nếu bạn không làm điều này ngay bây giờ, điều này sẽ tạo ra tập tin cấu hình sẽ không có giá trị cho bạn sau này nếu bạn thoát khỏi trình cài đặt mà không tải nó về.\n\nKhi đã việc tải về đã hoàn thành, bạn có thể <strong>[$2 truy cập trang wiki của bạn]</strong>.",
        "config-install-done-path": "<strong>Xin chúc mừng!</strong>\nBạn đã cài đặt MediaWiki.\n\nBộ cài đặt đã tạo ra một tập tin <code>LocalSettings.php</code>.\nTập tin này chứa tất cả các cấu hình của bạn.\n\nBạn sẽ cần phải tải nó về và đặt nó tại <code>$4</code>. Việc tải về có lẽ sẽ được khởi động tự động.\n\nNếu bản tải về không được cung cấp, hoặc nếu bạn hủy bỏ nó, bạn có thể khởi động lại tải về bằng cách nhấn vào liên kết dưới đây:\n\n$3\n\n<strong>Lưu ý:</strong> Nếu bạn không làm điều này ngay bây giờ, điều này sẽ tạo ra tập tin cấu hình sẽ không có giá trị cho bạn sau này nếu bạn thoát khỏi trình cài đặt mà không tải nó về.\n\nKhi đã việc tải về đã hoàn thành, bạn có thể <strong>[$2 truy cập trang wiki của bạn]</strong>.",
+       "config-install-success": "MediaWiki đã được cài đặt thành công. Bây giờ bạn có thể mở <$1$2> để xem wiki của bạn.\nNếu bạn có thắc mắc, hãy đọc các câu thường hỏi:\n<https://www.mediawiki.org/wiki/Manual:FAQ?uselang=vi> hoặc ghé vào một diễn đàn hỗ trợ được liệt kê tại trang đó.",
        "config-download-localsettings": "Tải về <code>LocalSettings.php</code>",
        "config-help": "Trợ giúp",
        "config-help-tooltip": "nhấn chuột để mở rộng",
        "config-nofile": "Không tìm thấy tập tin “$1”. Nó có phải bị xóa không?",
        "config-extension-link": "Bạn có biết rằng wiki của bạn có hỗ trợ [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Extensions mở rộng]?\n\nBạn có thể truy cập [https://www.mediawiki.org/wiki/Special:MyLanguage/Category:Extensions_by_category phần mở rộng theo thể loại] hoặc [https://www.mediawiki.org/wiki/Extension_Matrix Ma trận Mở rộng] để xem danh sách đầy đủ các phần mở rộng.",
        "config-skins-screenshots": "$1 (ảnh chụp màn hình: $2)",
+       "config-extensions-requires": "$1 (cần $2)",
        "config-screenshot": "ảnh chụp màn hình",
        "mainpagetext": "'''MediaWiki đã được cài đặt.'''",
        "mainpagedocfooter": "Xin đọc [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents Hướng dẫn sử dụng] để biết thêm thông tin về cách sử dụng phần mềm wiki.\n\n== Để bắt đầu ==\n\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Danh sách các thiết lập cấu hình]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ Các câu hỏi thường gặp MediaWiki]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Danh sách gửi thư về việc phát hành MediaWiki]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Tìm hiểu cách chống spam tại wiki của bạn]"
index c598a0b..dca707f 100644 (file)
@@ -46,7 +46,7 @@
        "config-env-hhvm": "Gin-install an HHVM $1.",
        "config-unicode-using-intl": "Gamita an [https://pecl.php.net/intl intl PECL extension] para han normalisasyon han Unicode.",
        "config-unicode-pure-php-warning": "<strong>Pahimatngon:</strong> An [https://pecl.php.net/intl intl PECL extension] in waray akos kumapot hin Unicode normalization, tungod hini mabalik ha mahinay nga puro-PHP nga implementasyon.\nKun nagpapadalagan ka hin high-traffic site, alayon pagbasa hin guti han [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations Unicode normalization].",
-       "config-no-db": "Diri nakakabiling hin naaangay nga database driver! Kinahanglan mo magtaod hin uska database driver para han PHP. An masunod nga mga klase hin database in ginsusuporatahan: $1.\n\nKun ikaw mismo an nag-compile han PHP, kinahanglan ma-reconfigure iton nga para maapandar an database client, pananglitan, han paggamit han <code>./configure --with-mysqli</code>.\nKun gintaod mo an PHP tikang ha uska Debian o Ubuntu nga pakete, kinahanglan nimo magtaod liwat, pananglitan, hiton an <code>php5-mysql</code> nga pakete.",
+       "config-no-db": "Diri nakakabiling hin naaangay nga database driver! Kinahanglan mo magtaod hin uska database driver para han PHP. An masunod nga mga klase hin database in ginsusuporatahan: $1.\n\nKun ikaw mismo an nag-compile han PHP, kinahanglan ma-reconfigure iton nga para maapandar an database client, pananglitan, han paggamit han <code>./configure --with-mysqli</code>.\nKun gintaod mo an PHP tikang ha uska Debian o Ubuntu nga pakete, kinahanglan nimo magtaod liwat, pananglitan, hiton an <code>php-mysql</code> nga pakete.",
        "config-pcre-old": "<strong>Nangangarat-an:</strong> Nagkikinahanglan hin PCRE $1 o mas urhi pa.\nAn imo PHP nga binaryo in nakasumpay hin PCRE $2. [https://www.mediawiki.org/wiki/Manual:Errors_and_symptoms/PCRE More information].",
        "config-db-name": "Ngaran han database:",
        "config-db-name-help": "Pagpili hin ngaran nga natudlok ha imo wiki.\nDapat waray ini mga espasyo.\n\nKun ikaw in nagamit hin shared web hosting, an imo hosting provider in mahatag diri ngani an specific database name para paggamit, matugot ha imo paghimo hin mga database pinaagi han control panel.",
@@ -61,8 +61,6 @@
        "config-db-web-account": "Database account para han web access",
        "config-mysql-innodb": "InnoDB",
        "config-mysql-myisam": "MyISAM",
-       "config-mysql-binary": "Binary",
-       "config-mysql-utf8": "UTF-8",
        "config-site-name": "Ngaran han wiki:",
        "config-ns-generic": "Proyekto",
        "config-ns-site-name": "Kapareho han wiki nga ngaran: $1",
index f85ef6e..c4892e7 100644 (file)
@@ -39,8 +39,8 @@
        "config-env-bad": "מ'האט קאנטראלירט די סביבה.\nאיר קענט נישט אינסטאלירן מעדיעוויקי.",
        "config-env-php": "PHP $1 איז אינצטאלירט.",
        "config-env-hhvm": "HHVM $1 איז אינסטאלירט.",
-       "config-apc": "[https://secure.php.net/apc APC] איז אינסטאלירט",
-       "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] איז אינסטאלירט",
+       "config-apc": "[https://secure.php.net/apc APC] איז אינסטאַלירט",
+       "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] איז אינסטאַלירט",
        "config-diff3-bad": "GNU diff3 נישט געטראפן.",
        "config-using-server": "באניצן סארווער־נאמען \"<nowiki>$1</nowiki>\".",
        "config-using-uri": "באניצן סארווער־אדרעס \"<nowiki>$1$2</nowiki>\".",
index 01eeba1..37706fa 100644 (file)
@@ -71,7 +71,7 @@
        "config-unicode-using-intl": "使用[https://pecl.php.net/intl intl PECL扩展程序]标准化Unicode。",
        "config-unicode-pure-php-warning": "<strong>警告:</strong>因为尚未安装 [https://pecl.php.net/intl intl PECL 扩展]以处理 Unicode 正常化,故只能退而采用运行较慢的纯 PHP 实现的方法。如果您运行着一个高流量的网站,请参阅 [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations Unicode标准化]一文。",
        "config-unicode-update-warning": "<strong>警告:</strong>Unicode正常化封装器的已安装版本使用了旧版本的[http://site.icu-project.org/ ICU项目]库。如果您需要使用Unicode,请将其[https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations 升级]。",
-       "config-no-db": "无法找到合适的数据库驱动!您需要为PHP安装数据库驱动。目前支持以下数据库{{PLURAL:$2|类型}}:$1。\n\n如果您自己编译了PHP,请通过启用数据库客户端重新配置它,例如使用 <code>./configure --with-mysqli</code>。如果您从 Debian 或 Ubuntu 安装包安装了PHP,那么您也需要安装,例如 <code>php5-mysql</code> 安装包。",
+       "config-no-db": "无法找到合适的数据库驱动!您需要为PHP安装数据库驱动。目前支持以下数据库{{PLURAL:$2|类型}}:$1。\n\n如果您自己编译了PHP,请通过启用数据库客户端重新配置它,例如使用<code>./configure --with-mysqli</code>。如果您从Debian或Ubuntu安装包安装了PHP,那么您也需要安装一些组件包,例如<code>php-mysql</code>。",
        "config-outdated-sqlite": "<strong>警告:</strong>您已安装SQLite $1,但是它的版本低于最低要求版本$2。因此您无法选择SQLite。",
        "config-no-fts3": "<strong>警告:</strong>已编译的SQLite不包含[//sqlite.org/fts3.html FTS3模块],后台搜索功能将不可用。",
        "config-pcre-old": "<strong>致命错误:</strong>需要PCRE $1 或更高版本。\n您的 PHP 二进制文件与 PCRE $2 链接。\n[https://www.mediawiki.org/wiki/Manual:Errors_and_symptoms/PCRE 详细信息]。",
        "config-sqlite-dir-help": "SQLite会将所有的数据存储于单一文件中。\n\n您所提供的目录必须在安装过程中对网页服务器可写。\n\n该目录<strong>不应</strong>允许通过web访问,因此我们不会将数据文件和PHP文件放在一起。\n\n安装程序在创建数据文件时,亦会在相同目录下创建<code>.htaccess</code>以控制权限。假若此等控制失效,则可能会将您的数据文件暴露于公共空间,让他人可以获取用户数据(电子邮件地址、杂凑后的密码)、被删除的版本以及其他在wiki上被限制访问的数据。\n\n请考虑将数据库统一放置在某处,如<code>/var/lib/mediawiki/yourwiki</code>下。",
        "config-oracle-def-ts": "默认表空间:",
        "config-oracle-temp-ts": "临时表空间:",
-       "config-type-mysql": "MySQL(或兼容程序)",
+       "config-type-mysql": "MariaDB、MySQL或兼容程序",
        "config-type-mssql": "微软SQL服务器",
        "config-support-info": "MediaWiki支持以下数据库系统:\n\n$1\n\n如果您在下面列出的数据库系统中没有找到您希望使用的系统,请根据上方链向的指引启用支持。",
-       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL]是MediaWiki的首选数据库,对它的支持最为完备。MediaWiki也可以在[{{int:version-db-mariadb-url}} MariaDB]和[{{int:version-db-percona-url}} Percona Server]下工作,它们与MySQL兼容。([https://secure.php.net/manual/en/mysqli.installation.php 如何将对MySQL的支持编译进PHP中])",
+       "config-dbsupport-mysql": "* [{{int:version-db-mariadb-url}} MariaDB]是用于MediaWiki的主要数据库,对它的支持最为完备。MediaWiki也可以在[{{int:version-db-mysql-url}} MySQL]和[{{int:version-db-percona-url}} Percona Server]下工作,它们与MariaDB兼容。([https://secure.php.net/manual/en/mysqli.installation.php 如何将对MySQL的支持编译进PHP中])",
        "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL]是一种流行的开源数据库系统,可作为MySQL的替代。([https://secure.php.net/manual/en/pgsql.installation.php 如何将对PostgreSQL的支持编译进PHP中])",
        "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite]是一种轻量级的数据库系统,能被良好地支持。([https://secure.php.net/manual/en/pdo.installation.php 如何将对SQLite的支持编译进PHP中],须使用PDO)",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle]是一种商用企业级的数据库。([https://secure.php.net/manual/en/oci8.installation.php 如何将对OCI8的支持编译进PHP中])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server]是一个适用于Windows的商业性企业数据库。([Config-dbsupport-oracle/manual/en/sqlsrv.installation.php 如何编译带有SQLSRV支持的PHP])",
-       "config-header-mysql": "MySQL设置",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server]是一个适用于Windows的商业性企业数据库。([https://secure.php.net/manual/en/sqlsrv.installation.php 如何编译带有SQLSRV支持的PHP])",
+       "config-header-mysql": "MariaDB/MySQL设置",
        "config-header-postgres": "PostgreSQL设置",
        "config-header-sqlite": "SQLite设置",
        "config-header-oracle": "Oracle设置",
        "config-db-web-create": "如果帐号不存在,则自动创建",
        "config-db-web-no-create-privs": "您指定给安装程序的帐号缺少创建帐号的权限,因此您指定的帐号必须已经存在。",
        "config-mysql-engine": "存储引擎:",
-       "config-mysql-innodb": "InnoDB",
+       "config-mysql-innodb": "InnoDB(推荐)",
        "config-mysql-myisam": "MyISAM",
        "config-mysql-myisam-dep": "<strong>警告:</strong>您选择了MyISAM作为MySQL的存储引擎,MediaWiki并不推荐您这么做,因为:\n* 它仅能通过表锁定来勉强支持并发\n* 与其他引擎相比,它更容易被损坏\n* MediaWiki代码库并不总会去处理MyISAM\n\n如果您的MySQL程序支持InnoDB,我们高度推荐您使用该引擎替代MyISAM。\n如果您的MySQL程序不支持InnoDB,请考虑升级。",
        "config-mysql-only-myisam-dep": "<strong>警告:</strong>MyISAM是MySQL在此机器上唯一可用的存储引擎,但它不适合用于MediaWiki,因为:\n*因为表级锁定,它几乎不支持并发。\n*它相比其他引擎更容易损坏。\n*MediaWiki代码不能总是按照预期操作MyISAM。\n\n你的MySQL不支持InnoDB,是时候升级了。",
        "config-mysql-engine-help": "<strong>InnoDB</strong>通常是最佳选项,因为它对并发操作有着良好的支持。\n\n<strong>MyISAM</strong>在单用户或只读环境下可能会有更快的性能表现。但MyISAM数据库出错的概率一般要大于InnoDB数据库。",
-       "config-mysql-charset": "数据库字符集:",
-       "config-mysql-binary": "二进制",
-       "config-mysql-utf8": "UTF-8",
-       "config-mysql-charset-help": "在<strong>二进制模式</strong>下,MediaWiki会将UTF-8编码的文本存于数据库的二进制字段中。相对于MySQL的UTF-8模式,这种方法效率更高,并允许您使用全范围的Unicode字符。\n\n在<strong>UTF-8模式</strong>下,MySQL将知道您数据使用的字符集,并能适当地提供和转换内容。但这样做您将无法在数据库中存储[https://zh.wikipedia.org/wiki/基本多文种平面 基本多文种平面]以外的字符。",
        "config-mssql-auth": "身份验证类型:",
        "config-mssql-install-auth": "选择安装过程中链接数据库时将采用的身份验证方式。如果您选择“{{int:config-mssql-windowsauth}}”,将使用运行服务器的用户的身份凭据。",
        "config-mssql-web-auth": "选择Web服务器在通常wiki操作期间用来连接数据库服务器的身份验证方式。如果您选择“{{int:config-mssql-windowsauth}}”,将使用运行Web服务器的用户的凭据。",
        "config-install-interwiki-exists": "<strong>警告:</strong>跨wiki数据表似乎已有内容,跳过默认列表。",
        "config-install-stats": "初始化统计",
        "config-install-keys": "生成密钥中",
-       "config-insecure-keys": "<strong>警告:</strong>在安装过程中生成的{{PLURAL:$2|安全密钥}}($1){{PLURAL:$2|并}}不一定安全。请考虑手动更改{{PLURAL:$2|它|它们}}。",
        "config-install-updates": "防止运行不需要的更新",
        "config-install-updates-failed": "<strong>错误:</strong>表格中插入更新关键字失败并出现如下错误:$1",
        "config-install-sysop": "正在创建管理员用户帐号",
index 261db81..0ed6f6f 100644 (file)
@@ -70,7 +70,7 @@
        "config-unicode-using-intl": "使用 [https://pecl.php.net/intl intl PECL 擴充套件] 做 Unicode 正規化。",
        "config-unicode-pure-php-warning": "<strong>警告:</strong> 無法使用 [https://pecl.php.net/intl intl PECL 擴充套件] 處理 Unicode 正規化,故回退使用純 PHP 實作的正規化程式,此方式處理速度較緩慢。\n\n如果您的網站瀏覽人次很高,您應先閱讀 [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations/zh Unicode 正規化]。",
        "config-unicode-update-warning": "<strong>警告</strong>:目前安裝的 Unicode 正規化包裝程式使用了舊版 [http://site.icu-project.org/ ICU 計劃] 的程式庫。\n若您需要使用 Unicode,您應先進行 [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations 升級]。",
-       "config-no-db": "找不到合適的資料庫驅動程式!您需要安裝 PHP 資料庫驅動程式。\n目前支援以下{{PLURAL:$2|類型|類型}}的資料庫: $1 。\n\n如果您是自行編譯 PHP,您必須重新設定並開啟資料庫客戶端,例:使用 <code>./configure --with-mysqli</code> 指令參數。\n如果您是使用 Debian 或 Ubuntu 的套件安裝 PHP ,您則需要額外安裝,例:<code>php5-mysql</code> 套件。",
+       "config-no-db": "找不到合適的資料庫驅動程式!您需要安裝 PHP 資料庫驅動程式。\n目前支援以下{{PLURAL:$2|類型|類型}}的資料庫: $1 。\n\n如果您是自行編譯 PHP,您必須重新設定並開啟資料庫客戶端,例:使用 <code>./configure --with-mysqli</code> 指令參數。\n如果您是使用 Debian 或 Ubuntu 的套件安裝 PHP ,您則需要額外安裝,例:<code>php-mysql</code> 套件。",
        "config-outdated-sqlite": "<strong>警告:</strong>您已安裝 SQLite $1,但是它的版本低於最低需求版本 $2。 因此您無法使用 SQLite。",
        "config-no-fts3": "<strong>警告:</strong> SQLite 編譯時未包含 [//sqlite.org/fts3.html FTS3 模組],後台搜尋功能將無法使用。",
        "config-pcre-old": "<strong>嚴重:</strong> 需要使用 PCRE $1 或更新的版本。\n您的 PHP 執行檔使用的是 PCRE $2。\n[https://www.mediawiki.org/wiki/Manual:Errors_and_symptoms/PCRE 詳細資訊]。",
        "config-sqlite-dir-help": "SQLite 會將所有的資料存儲於單一檔案中。\n\n您所提供的目錄在安裝過程中必須開啟給網頁伺服器的寫入權限。\n\n該目錄 <strong>不應</strong> 可以被透過網頁所開啟,這也是為什麼我們不將資料與 PHP 檔案放在一起。\n\n安裝程式在建立資料庫檔案時,會同時在目錄下建立 <code>.htaccess</code> 以控制網頁伺服器權限。若此設定失效,則會導致任何人可以直接存取您的原始資料檔案,而資料庫的內容包含原始的使用者資料 (電子郵件地址、加密後的密碼)、刪除後的修訂及其他在 Wiki 上被限制存取的資料。\n\n請考慮將資料庫統一放置在某處,如 <code>/var/lib/mediawiki/yourwiki</code> 底下。",
        "config-oracle-def-ts": "預設資料表空間:",
        "config-oracle-temp-ts": "臨時資料表空間:",
-       "config-type-mysql": "MySQL (或與其相容的程式)",
+       "config-type-mysql": "MariaDB、MySQL、或與其相容的套件",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki 支援以下資料庫系統:\n\n$1\n\n如果您下方沒有看到您要使用的資料庫系統,請根據上方連結指示開啟資料庫的支援。",
-       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] 是 MediaWiki 主要支援的資料庫系統。MediaWiki 也同時可運作與於 [{{int:version-db-mariadb-url}} MariaDB] 和 [{{int:version-db-percona-url}} Percona 伺服器],上述這些與 MySQL 相容的資料庫系統。([https://secure.php.net/manual/en/mysqli.installation.php\n如何編譯支援 MySQL 的 PHP])",
+       "config-dbsupport-mysql": "* [{{int:version-db-mariadb-url}} MariaDB] 是 MediaWiki 主要支援的資料庫系統。MediaWiki 也同時可運作與於 [{{int:version-db-mysql-url}} MySQL] 和 [{{int:version-db-percona-url}} Percona 伺服器],上述這些與 MariaDB 相容的資料庫系統。([https://secure.php.net/manual/en/mysqli.installation.php 如何編譯支援 MySQL 的 PHP])",
        "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] 是一套受歡迎的開源資料庫系統,可用來替代 MySQL。([https://secure.php.net/manual/en/pgsql.installation.php 如何編譯支援 PostgreSQL 的 PHP])。",
        "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] 是一套輕量級的資料庫系統,MediaWiki 可在此資料庫系統上良好的運作。([https://secure.php.net/manual/en/pdo.installation.php 如何編譯支援 SQLite 的 PHP],須透過 PDO)",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] 是一套商用企業級的資料庫。([https://secure.php.net/manual/en/oci8.installation.php 如何編譯支援 OCI8 的 PHP])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] 是一套 Windows 專用的商用企業級的資料庫。 ([Config-dbsupport-oracle/manual/en/sqlsrv.installation.php 如何編譯支援 SQLSRV 的 PHP])",
-       "config-header-mysql": "MySQL 設定",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] 是一套 Windows 專用的商用企業級的資料庫。 ([https://secure.php.net/manual/en/sqlsrv.installation.php 如何編譯支援 SQLSRV 的 PHP])",
+       "config-header-mysql": "MariaDB/MySQL 設定",
        "config-header-postgres": "PostgreSQL 設定",
        "config-header-sqlite": "SQLite 設定",
        "config-header-oracle": "Oracle 設定",
        "config-db-web-create": "如果帳號不存在則建立新帳號",
        "config-db-web-no-create-privs": "您指定給安裝程序使用的帳號沒有足夠的權限建立新帳號。\n在此處必須指定已經存在的帳號。",
        "config-mysql-engine": "儲存引擎:",
-       "config-mysql-innodb": "InnoDB",
+       "config-mysql-innodb": "InnoDB(推薦)",
        "config-mysql-myisam": "MyISAM",
        "config-mysql-myisam-dep": "<strong>警告:</strong>您選擇用來做為 MySQL 的儲存引撆 MyISAM 並不建議使用在 MediaWiki,主要原因為:\n* MyISAM 使用的資料表鎖定較無法承受多人同時連線\n* 比起其他儲存引擎相,它較容易損壞\n* MediaWiki 程式碼並沒有針對 MyISAM 做特別的處理\n\n若您安裝的 MySQL 支援 InnoDB,我們強烈建議您改用 InnoDB。\n若您安裝的 MySQL 不支援 InnoDB,則應考慮升級 MySQL。",
        "config-mysql-only-myisam-dep": "<strong>警告:</strong>您的伺服器上的 MySQL 唯一可用的儲存引擎是 MyISAM,但並不建議使用,主要原因為:\n* MyISAM 使用的資料表鎖定較無法承受多人同時連線\n* 比起其他儲存引擎相,它較容易損壞\n* MediaWiki 程式碼並沒有針對 MyISAM 做特別的處理\n\n若您安裝的 MySQL 不支援 InnoDB,則應考慮升級 MySQL。",
        "config-mysql-engine-help": "由於對同時連線有較好的處理能力,<strong>InnoDB</strong> 通常是最佳的選項。\n\n<strong>MyISAM</strong> 只在單人使用或者唯讀作業的情況之下才可能有較快的處理能力。\n相較於 InnoDB,MyISAM 也較容易出現資料損毀的情況。",
-       "config-mysql-charset": "資料庫字元集:",
-       "config-mysql-binary": "二進制",
-       "config-mysql-utf8": "UTF-8",
-       "config-mysql-charset-help": "在 <strong>二進制模式</strong> 下,MediaWiki 將 UTF-8 的文字儲存在二進位型態的欄位。\n這個模式比 MySQL 的 UTF-8 模式還要更有效,並且可以讓您使用完整的 Unicode 字元集。\n\n在 <strong>UTF-8 模式</strong> 下,MySQL 可以知道您的資料使用何種編碼儲存,您可以正常的取得與轉換內容,但此個模式只支援到 Unicode 中的  [https://en.wikipedia.org/wiki/Mapping_of_Unicode_character_planes 基本多文種平面] 字元。",
        "config-mssql-auth": "身份驗證類型:",
        "config-mssql-install-auth": "請選擇安裝程序中要用來連線資料庫使用的身份驗證類型。\n若您選擇 \"{{int:config-mssql-windowsauth}}\",不論網頁伺服器是使用何種身份執行都會使用這組驗證資料。",
        "config-mssql-web-auth": "請選擇一般操作中要用來連線資料庫使用的身份驗證類型。\n若您選擇 \"{{int:config-mssql-windowsauth}}\",不論網頁伺服器是使用何種身份執行都會使用這組驗證資料。",
        "config-install-interwiki-exists": "<strong>警告:</strong> interwiki 資料表內已有資料,略過建立預設資料。",
        "config-install-stats": "初始化統計資訊",
        "config-install-keys": "產生秘密金鑰中",
-       "config-insecure-keys": "<strong>警告:</strong>在安裝過程中所產生的 $2 組安全金鑰($1)並不完全安全。請考慮手動更改。",
        "config-install-updates": "略過執行不需要的更新",
        "config-install-updates-failed": "<strong>錯誤:</strong> 插入更新鍵值至資料表失敗,並出現以下錯誤:$1",
        "config-install-sysop": "正在建立管理員使用者帳號",
index d5103da..eada9d4 100644 (file)
@@ -314,10 +314,10 @@ class ClassicInterwikiLookup implements InterwikiLookup {
        private function loadFromArray( $mc ) {
                if ( isset( $mc['iw_url'] ) ) {
                        $url = $mc['iw_url'];
-                       $local = isset( $mc['iw_local'] ) ? $mc['iw_local'] : 0;
-                       $trans = isset( $mc['iw_trans'] ) ? $mc['iw_trans'] : 0;
-                       $api = isset( $mc['iw_api'] ) ? $mc['iw_api'] : '';
-                       $wikiId = isset( $mc['iw_wikiid'] ) ? $mc['iw_wikiid'] : '';
+                       $local = $mc['iw_local'] ?? 0;
+                       $trans = $mc['iw_trans'] ?? 0;
+                       $api = $mc['iw_api'] ?? '';
+                       $wikiId = $mc['iw_wikiid'] ?? '';
 
                        return new Interwiki( null, $url, $api, $wikiId, $local, $trans );
                }
index 657849a..832883b 100644 (file)
@@ -66,6 +66,7 @@ class Interwiki {
         * @return bool Whether it exists
         */
        public static function isValidInterwiki( $prefix ) {
+               wfDeprecated( __METHOD__, '1.28' );
                return MediaWikiServices::getInstance()->getInterwikiLookup()->isValidInterwiki( $prefix );
        }
 
@@ -78,6 +79,7 @@ class Interwiki {
         * @return Interwiki|null|bool
         */
        public static function fetch( $prefix ) {
+               wfDeprecated( __METHOD__, '1.28' );
                return MediaWikiServices::getInstance()->getInterwikiLookup()->fetch( $prefix );
        }
 
@@ -88,6 +90,7 @@ class Interwiki {
         * @since 1.26
         */
        public static function invalidateCache( $prefix ) {
+               wfDeprecated( __METHOD__, '1.28' );
                MediaWikiServices::getInstance()->getInterwikiLookup()->invalidateCache( $prefix );
        }
 
@@ -101,13 +104,14 @@ class Interwiki {
         * @since 1.19
         */
        public static function getAllPrefixes( $local = null ) {
+               wfDeprecated( __METHOD__, '1.28' );
                return MediaWikiServices::getInstance()->getInterwikiLookup()->getAllPrefixes( $local );
        }
 
        /**
         * Get the URL for a particular title (or with $1 if no title given)
         *
-        * @param string $title What text to put for the article name
+        * @param string|null $title What text to put for the article name
         * @return string The URL
         * @note Prior to 1.19 The getURL with an argument was broken.
         *       If you if you use this arg in an extension that supports MW earlier
index 076c37f..d906498 100644 (file)
@@ -24,7 +24,7 @@ namespace MediaWiki\Interwiki;
  * @since 1.29
  * @ingroup InterwikiLookup
  *
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
  */
 
 use Interwiki;
diff --git a/includes/interwiki/NullInterwikiLookup.php b/includes/interwiki/NullInterwikiLookup.php
new file mode 100644 (file)
index 0000000..09fa1ec
--- /dev/null
@@ -0,0 +1,57 @@
+<?php
+/**
+ * Copyright (C) 2018 Kunal Mehta <legoktm@member.fsf.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.
+ *
+ */
+
+namespace MediaWiki\Interwiki;
+
+/**
+ * An interwiki lookup that has no data, intended
+ * for use in the installer.
+ *
+ * @since 1.31
+ */
+class NullInterwikiLookup implements InterwikiLookup {
+
+       /**
+        * @inheritDoc
+        */
+       public function isValidInterwiki( $prefix ) {
+               return false;
+       }
+
+       /**
+        * @inheritDoc
+        */
+       public function fetch( $prefix ) {
+               return false;
+       }
+
+       /**
+        * @inheritDoc
+        */
+       public function getAllPrefixes( $local = null ) {
+               return [];
+       }
+
+       /**
+        * @inheritDoc
+        */
+       public function invalidateCache( $prefix ) {
+       }
+}
index b16cfa3..45ab4d3 100644 (file)
@@ -170,9 +170,7 @@ abstract class Job implements IJobSpecification {
         * @since 1.27
         */
        public function getRequestId() {
-               return isset( $this->params['requestId'] )
-                       ? $this->params['requestId']
-                       : null;
+               return $this->params['requestId'] ?? null;
        }
 
        /**
@@ -280,12 +278,8 @@ abstract class Job implements IJobSpecification {
         */
        public function getRootJobParams() {
                return [
-                       'rootJobSignature' => isset( $this->params['rootJobSignature'] )
-                               ? $this->params['rootJobSignature']
-                               : null,
-                       'rootJobTimestamp' => isset( $this->params['rootJobTimestamp'] )
-                               ? $this->params['rootJobTimestamp']
-                               : null
+                       'rootJobSignature' => $this->params['rootJobSignature'] ?? null,
+                       'rootJobTimestamp' => $this->params['rootJobTimestamp'] ?? null
                ];
        }
 
index d2446ab..c4ce2ba 100644 (file)
@@ -58,8 +58,8 @@ abstract class JobQueue {
        protected function __construct( array $params ) {
                $this->wiki = $params['wiki'];
                $this->type = $params['type'];
-               $this->claimTTL = isset( $params['claimTTL'] ) ? $params['claimTTL'] : 0;
-               $this->maxTries = isset( $params['maxTries'] ) ? $params['maxTries'] : 3;
+               $this->claimTTL = $params['claimTTL'] ?? 0;
+               $this->maxTries = $params['maxTries'] ?? 3;
                if ( isset( $params['order'] ) && $params['order'] !== 'any' ) {
                        $this->order = $params['order'];
                } else {
@@ -69,12 +69,8 @@ abstract class JobQueue {
                        throw new MWException( __CLASS__ . " does not support '{$this->order}' order." );
                }
                $this->dupCache = wfGetCache( CACHE_ANYTHING );
-               $this->aggr = isset( $params['aggregator'] )
-                       ? $params['aggregator']
-                       : new JobQueueAggregatorNull( [] );
-               $this->readOnlyReason = isset( $params['readOnlyReason'] )
-                       ? $params['readOnlyReason']
-                       : false;
+               $this->aggr = $params['aggregator'] ?? new JobQueueAggregatorNull( [] );
+               $this->readOnlyReason = $params['readOnlyReason'] ?? false;
        }
 
        /**
index a082d64..bc73718 100644 (file)
@@ -55,7 +55,7 @@ class JobQueueDB extends JobQueue {
        protected function __construct( array $params ) {
                parent::__construct( $params );
 
-               $this->cluster = isset( $params['cluster'] ) ? $params['cluster'] : false;
+               $this->cluster = $params['cluster'] ?? false;
                $this->cache = ObjectCache::getMainWANInstance();
        }
 
index 7f3b2b1..0f8fcfb 100644 (file)
@@ -73,15 +73,11 @@ class JobQueueFederated extends JobQueue {
         */
        protected function __construct( array $params ) {
                parent::__construct( $params );
-               $section = isset( $params['sectionsByWiki'][$this->wiki] )
-                       ? $params['sectionsByWiki'][$this->wiki]
-                       : 'default';
+               $section = $params['sectionsByWiki'][$this->wiki] ?? 'default';
                if ( !isset( $params['partitionsBySection'][$section] ) ) {
                        throw new MWException( "No configuration for section '$section'." );
                }
-               $this->maxPartitionsTry = isset( $params['maxPartitionsTry'] )
-                       ? $params['maxPartitionsTry']
-                       : 2;
+               $this->maxPartitionsTry = $params['maxPartitionsTry'] ?? 2;
                // Get the full partition map
                $partitionMap = $params['partitionsBySection'][$section];
                arsort( $partitionMap, SORT_NUMERIC );
index addc7fc..820c492 100644 (file)
@@ -62,7 +62,7 @@ class JobQueueGroup {
        protected function __construct( $wiki, $readOnlyReason ) {
                $this->wiki = $wiki;
                $this->readOnlyReason = $readOnlyReason;
-               $this->cache = new ProcessCacheLRU( 10 );
+               $this->cache = new MapCacheLRU( 10 );
        }
 
        /**
@@ -111,7 +111,7 @@ class JobQueueGroup {
                        $conf = $conf + $wgJobTypeConf['default'];
                }
                $conf['aggregator'] = JobQueueAggregator::singleton();
-               if ( $this->readOnlyReason !== false ) {
+               if ( !isset( $conf['readOnlyReason'] ) ) {
                        $conf['readOnlyReason'] = $this->readOnlyReason;
                }
 
@@ -154,8 +154,8 @@ class JobQueueGroup {
                        $this->get( $type )->push( $jobs );
                }
 
-               if ( $this->cache->has( 'queues-ready', 'list' ) ) {
-                       $list = $this->cache->get( 'queues-ready', 'list' );
+               if ( $this->cache->hasField( 'queues-ready', 'list' ) ) {
+                       $list = $this->cache->getField( 'queues-ready', 'list' );
                        if ( count( array_diff( array_keys( $jobsByType ), $list ) ) ) {
                                $this->cache->clear( 'queues-ready' );
                        }
@@ -244,10 +244,10 @@ class JobQueueGroup {
                        }
                } else { // any job in the "default" jobs types
                        if ( $flags & self::USE_CACHE ) {
-                               if ( !$this->cache->has( 'queues-ready', 'list', self::PROC_CACHE_TTL ) ) {
-                                       $this->cache->set( 'queues-ready', 'list', $this->getQueuesWithJobs() );
+                               if ( !$this->cache->hasField( 'queues-ready', 'list', self::PROC_CACHE_TTL ) ) {
+                                       $this->cache->setField( 'queues-ready', 'list', $this->getQueuesWithJobs() );
                                }
-                               $types = $this->cache->get( 'queues-ready', 'list' );
+                               $types = $this->cache->getField( 'queues-ready', 'list' );
                        } else {
                                $types = $this->getQueuesWithJobs();
                        }
index 7dad014..e9505bc 100644 (file)
@@ -93,7 +93,7 @@ class JobQueueRedis extends JobQueue {
                parent::__construct( $params );
                $params['redisConfig']['serializer'] = 'none'; // make it easy to use Lua
                $this->server = $params['redisServer'];
-               $this->compression = isset( $params['compression'] ) ? $params['compression'] : 'none';
+               $this->compression = $params['compression'] ?? 'none';
                $this->redisPool = RedisConnectionPool::singleton( $params['redisConfig'] );
                if ( empty( $params['daemonized'] ) ) {
                        throw new InvalidArgumentException(
diff --git a/includes/jobqueue/JobQueueSecondTestQueue.php b/includes/jobqueue/JobQueueSecondTestQueue.php
deleted file mode 100644 (file)
index 01f467f..0000000
+++ /dev/null
@@ -1,290 +0,0 @@
-<?php
-
-/**
- * A wrapper for the JobQueue that delegates all the method calls to a single,
- * main queue, and also pushes all the jobs to a second job queue that's being
- * debugged.
- *
- * This class was temporary added to test transitioning to the JobQueueEventBus
- * and will removed after the transition is completed. This code is only needed
- * while we are testing the new infrastructure to be able to compare the results
- * between the queue implementations and make sure that they process the same jobs,
- * deduplicate correctly, compare the delays, backlogs and make sure no jobs are lost.
- * When the new infrastructure is well tested this will not be needed any more.
- *
- * @deprecated since 1.30
- * @since 1.30
- */
-class JobQueueSecondTestQueue extends JobQueue {
-
-       /**
-        * @var JobQueue
-        */
-       private $mainQueue;
-
-       /**
-        * @var JobQueue
-        */
-       private $debugQueue;
-
-       /**
-        * @var bool
-        */
-       private $onlyWriteToDebugQueue;
-
-       protected function __construct( array $params ) {
-               if ( !isset( $params['mainqueue'] ) ) {
-                       throw new MWException( "mainqueue parameter must be provided to the debug queue" );
-               }
-
-               if ( !isset( $params['debugqueue'] ) ) {
-                       throw new MWException( "debugqueue parameter must be provided to the debug queue" );
-               }
-
-               $conf = [ 'wiki' => $params['wiki'], 'type' => $params['type'] ];
-               $this->mainQueue = JobQueue::factory( $params['mainqueue'] + $conf );
-               $this->debugQueue = JobQueue::factory( $params['debugqueue'] + $conf );
-               $this->onlyWriteToDebugQueue = isset( $params['readonly'] ) ? $params['readonly'] : false;
-
-               // We need to construct parent after creating the main and debug queue
-               // because super constructor calls some methods we delegate to the main queue.
-               parent::__construct( $params );
-       }
-
-       /**
-        * Get the allowed queue orders for configuration validation
-        *
-        * @return array Subset of (random, timestamp, fifo, undefined)
-        */
-       protected function supportedOrders() {
-               return $this->mainQueue->supportedOrders();
-       }
-
-       /**
-        * Get the default queue order to use if configuration does not specify one
-        *
-        * @return string One of (random, timestamp, fifo, undefined)
-        */
-       protected function optimalOrder() {
-               return $this->mainQueue->optimalOrder();
-       }
-
-       /**
-        * Find out if delayed jobs are supported for configuration validation
-        *
-        * @return bool Whether delayed jobs are supported
-        */
-       protected function supportsDelayedJobs() {
-               return $this->mainQueue->supportsDelayedJobs();
-       }
-
-       /**
-        * @see JobQueue::isEmpty()
-        * @return bool
-        */
-       protected function doIsEmpty() {
-               return $this->mainQueue->doIsEmpty();
-       }
-
-       /**
-        * @see JobQueue::getSize()
-        * @return int
-        */
-       protected function doGetSize() {
-               return $this->mainQueue->doGetSize();
-       }
-
-       /**
-        * @see JobQueue::getAcquiredCount()
-        * @return int
-        */
-       protected function doGetAcquiredCount() {
-               return $this->mainQueue->doGetAcquiredCount();
-       }
-
-       /**
-        * @see JobQueue::getDelayedCount()
-        * @return int
-        */
-       protected function doGetDelayedCount() {
-               return $this->mainQueue->doGetDelayedCount();
-       }
-
-       /**
-        * @see JobQueue::getAbandonedCount()
-        * @return int
-        */
-       protected function doGetAbandonedCount() {
-               return $this->mainQueue->doGetAbandonedCount();
-       }
-
-       /**
-        * @see JobQueue::batchPush()
-        * @param IJobSpecification[] $jobs
-        * @param int $flags
-        */
-       protected function doBatchPush( array $jobs, $flags ) {
-               if ( !$this->onlyWriteToDebugQueue ) {
-                       $this->mainQueue->doBatchPush( $jobs, $flags );
-               }
-
-               try {
-                       $this->debugQueue->doBatchPush( $jobs, $flags );
-               } catch ( Exception $exception ) {
-                       MWExceptionHandler::logException( $exception );
-               }
-       }
-
-       /**
-        * @see JobQueue::pop()
-        * @return Job|bool
-        */
-       protected function doPop() {
-               return $this->mainQueue->doPop();
-       }
-
-       /**
-        * @see JobQueue::ack()
-        * @param Job $job
-        * @return Job|bool
-        */
-       protected function doAck( Job $job ) {
-               return $this->mainQueue->doAck( $job );
-       }
-
-       /**
-        * @see JobQueue::deduplicateRootJob()
-        * @param IJobSpecification $job
-        * @throws MWException
-        * @return bool
-        */
-       protected function doDeduplicateRootJob( IJobSpecification $job ) {
-               return $this->mainQueue->doDeduplicateRootJob( $job );
-       }
-
-       /**
-        * @see JobQueue::isRootJobOldDuplicate()
-        * @param Job $job
-        * @return bool
-        */
-       protected function doIsRootJobOldDuplicate( Job $job ) {
-               return $this->mainQueue->doIsRootJobOldDuplicate( $job );
-       }
-
-       /**
-        * @param string $signature Hash identifier of the root job
-        * @return string
-        */
-       protected function getRootJobCacheKey( $signature ) {
-               return $this->mainQueue->getRootJobCacheKey( $signature );
-       }
-
-       /**
-        * @see JobQueue::delete()
-        * @return bool
-        * @throws MWException
-        */
-       protected function doDelete() {
-               return $this->mainQueue->doDelete();
-       }
-
-       /**
-        * @see JobQueue::waitForBackups()
-        * @return void
-        */
-       protected function doWaitForBackups() {
-               $this->mainQueue->doWaitForBackups();
-       }
-
-       /**
-        * @see JobQueue::flushCaches()
-        * @return void
-        */
-       protected function doFlushCaches() {
-               $this->mainQueue->doFlushCaches();
-       }
-
-       /**
-        * Get an iterator to traverse over all available jobs in this queue.
-        * This does not include jobs that are currently acquired or delayed.
-        * Note: results may be stale if the queue is concurrently modified.
-        *
-        * @return Iterator
-        * @throws JobQueueError
-        */
-       public function getAllQueuedJobs() {
-               return $this->mainQueue->getAllQueuedJobs();
-       }
-
-       /**
-        * Get an iterator to traverse over all delayed jobs in this queue.
-        * Note: results may be stale if the queue is concurrently modified.
-        *
-        * @return Iterator
-        * @throws JobQueueError
-        * @since 1.22
-        */
-       public function getAllDelayedJobs() {
-               return $this->mainQueue->getAllDelayedJobs();
-       }
-
-       /**
-        * Get an iterator to traverse over all claimed jobs in this queue
-        *
-        * Callers should be quick to iterator over it or few results
-        * will be returned due to jobs being acknowledged and deleted
-        *
-        * @return Iterator
-        * @throws JobQueueError
-        * @since 1.26
-        */
-       public function getAllAcquiredJobs() {
-               return $this->mainQueue->getAllAcquiredJobs();
-       }
-
-       /**
-        * Get an iterator to traverse over all abandoned jobs in this queue
-        *
-        * @return Iterator
-        * @throws JobQueueError
-        * @since 1.25
-        */
-       public function getAllAbandonedJobs() {
-               return $this->mainQueue->getAllAbandonedJobs();
-       }
-
-       /**
-        * Do not use this function outside of JobQueue/JobQueueGroup
-        *
-        * @return string
-        * @since 1.22
-        */
-       public function getCoalesceLocationInternal() {
-               return $this->mainQueue->getCoalesceLocationInternal();
-       }
-
-       /**
-        * @see JobQueue::getSiblingQueuesWithJobs()
-        * @param array $types List of queues types
-        * @return array|null (list of queue types) or null if unsupported
-        */
-       protected function doGetSiblingQueuesWithJobs( array $types ) {
-               return $this->mainQueue->doGetSiblingQueuesWithJobs( $types );
-       }
-
-       /**
-        * @see JobQueue::getSiblingQueuesSize()
-        * @param array $types List of queues types
-        * @return array|null (list of queue types) or null if unsupported
-        */
-       protected function doGetSiblingQueueSizes( array $types ) {
-               return $this->mainQueue->doGetSiblingQueueSizes( $types );
-       }
-
-       /**
-        * @throws JobQueueReadOnlyError
-        */
-       protected function assertNotReadOnly() {
-               $this->mainQueue->assertNotReadOnly();
-       }
-}
index 977fbda..7c5d0ae 100644 (file)
@@ -69,7 +69,7 @@ class JobRunner implements LoggerAwareInterface {
        }
 
        /**
-        * @param LoggerInterface $logger
+        * @param LoggerInterface|null $logger
         */
        public function __construct( LoggerInterface $logger = null ) {
                if ( $logger === null ) {
@@ -109,9 +109,9 @@ class JobRunner implements LoggerAwareInterface {
 
                $response = [ 'jobs' => [], 'reached' => 'none-ready' ];
 
-               $type = isset( $options['type'] ) ? $options['type'] : false;
-               $maxJobs = isset( $options['maxJobs'] ) ? $options['maxJobs'] : false;
-               $maxTime = isset( $options['maxTime'] ) ? $options['maxTime'] : false;
+               $type = $options['type'] ?? false;
+               $maxJobs = $options['maxJobs'] ?? false;
+               $maxTime = $options['maxTime'] ?? false;
                $noThrottle = isset( $options['throttle'] ) && !$options['throttle'];
 
                // Bail if job type is invalid
index b62b83c..d060c1c 100644 (file)
@@ -117,7 +117,7 @@ class JobSpecification implements IJobSpecification {
         * @param string $type
         * @param array $params Map of key/values
         * @param array $opts Map of key/values; includes 'removeDuplicates'
-        * @param Title $title Optional descriptive title
+        * @param Title|null $title Optional descriptive title
         */
        public function __construct(
                $type, array $params, array $opts = [], Title $title = null
@@ -186,12 +186,8 @@ class JobSpecification implements IJobSpecification {
 
        public function getRootJobParams() {
                return [
-                       'rootJobSignature' => isset( $this->params['rootJobSignature'] )
-                               ? $this->params['rootJobSignature']
-                               : null,
-                       'rootJobTimestamp' => isset( $this->params['rootJobTimestamp'] )
-                               ? $this->params['rootJobTimestamp']
-                               : null
+                       'rootJobSignature' => $this->params['rootJobSignature'] ?? null,
+                       'rootJobTimestamp' => $this->params['rootJobTimestamp'] ?? null
                ];
        }
 
index db07086..7d0e1e6 100644 (file)
@@ -49,9 +49,7 @@ class JobQueueAggregatorRedis extends JobQueueAggregator {
         */
        public function __construct( array $params ) {
                parent::__construct( $params );
-               $this->servers = isset( $params['redisServers'] )
-                       ? $params['redisServers']
-                       : [ $params['redisServer'] ]; // b/c
+               $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' );
index 16640be..a0c70ab 100644 (file)
@@ -173,7 +173,7 @@ class CategoryMembershipChangeJob extends Job {
                }
 
                // Parse the new revision and get the categories
-               $categoryChanges = $this->getExplicitCategoriesChanges( $title, $newRev, $oldRev );
+               $categoryChanges = $this->getExplicitCategoriesChanges( $page, $newRev, $oldRev );
                list( $categoryInserts, $categoryDeletes ) = $categoryChanges;
                if ( !$categoryInserts && !$categoryDeletes ) {
                        return; // nothing to do
@@ -203,7 +203,7 @@ class CategoryMembershipChangeJob extends Job {
        }
 
        private function getExplicitCategoriesChanges(
-               Title $title, Revision $newRev, Revision $oldRev = null
+               WikiPage $page, Revision $newRev, Revision $oldRev = null
        ) {
                // Inject the same timestamp for both revision parses to avoid seeing category changes
                // due to time-based parser functions. Inject the same page title for the parses too.
@@ -213,10 +213,10 @@ class CategoryMembershipChangeJob extends Job {
                // assumes these updates are perfectly FIFO and that link tables are always
                // up to date, neither of which are true.
                $oldCategories = $oldRev
-                       ? $this->getCategoriesAtRev( $title, $oldRev, $parseTimestamp )
+                       ? $this->getCategoriesAtRev( $page, $oldRev, $parseTimestamp )
                        : [];
                // Parse the new revision and get the categories
-               $newCategories = $this->getCategoriesAtRev( $title, $newRev, $parseTimestamp );
+               $newCategories = $this->getCategoriesAtRev( $page, $newRev, $parseTimestamp );
 
                $categoryInserts = array_values( array_diff( $newCategories, $oldCategories ) );
                $categoryDeletes = array_values( array_diff( $oldCategories, $newCategories ) );
@@ -225,19 +225,19 @@ class CategoryMembershipChangeJob extends Job {
        }
 
        /**
-        * @param Title $title
+        * @param WikiPage $page
         * @param Revision $rev
         * @param string $parseTimestamp TS_MW
         *
         * @return string[] category names
         */
-       private function getCategoriesAtRev( Title $title, Revision $rev, $parseTimestamp ) {
+       private function getCategoriesAtRev( WikiPage $page, Revision $rev, $parseTimestamp ) {
                $content = $rev->getContent();
-               $options = $content->getContentHandler()->makeParserOptions( 'canonical' );
+               $options = $page->makeParserOptions( 'canonical' );
                $options->setTimestamp( $parseTimestamp );
                // This could possibly use the parser cache if it checked the revision ID,
                // but that's more complicated than it's worth.
-               $output = $content->getParserOutput( $title, $rev->getId(), $options );
+               $output = $content->getParserOutput( $page->getTitle(), $rev->getId(), $options );
 
                // array keys will cast numeric category names to ints
                // so we need to cast them back to strings to avoid breaking things!
index d0969e4..0a14192 100644 (file)
@@ -55,7 +55,7 @@ class DeleteLinksJob extends Job {
                }
 
                $factory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
-               $timestamp = isset( $this->params['timestamp'] ) ? $this->params['timestamp'] : null;
+               $timestamp = $this->params['timestamp'] ?? null;
                $page = WikiPage::factory( $this->title ); // title when deleted
 
                $update = new LinksDeletionUpdate( $page, $pageId, $timestamp );
index 74c446f..1bcbd30 100644 (file)
@@ -21,6 +21,8 @@
  * @ingroup JobQueue
  */
 
+use MediaWiki\MediaWikiServices;
+
 /**
  * Job to fix double redirects after moving a page
  *
@@ -116,7 +118,7 @@ class DoubleRedirectJob extends Job {
                }
 
                // Check for a suppression tag (used e.g. in periodically archived discussions)
-               $mw = MagicWord::get( 'staticredirect' );
+               $mw = MediaWikiServices::getInstance()->getMagicWordFactory()->get( 'staticredirect' );
                if ( $content->matchMagicWord( $mw ) ) {
                        wfDebug( __METHOD__ . ": skipping: suppressed with __STATICREDIRECT__\n" );
 
index 34028df..7d0ada5 100644 (file)
@@ -128,9 +128,7 @@ class HTMLCacheUpdateJob extends Job {
                // not expected to invalidate these cache entries too often.
                $touchTimestamp = wfTimestampNow();
                // If page_touched is higher than this, then something else already bumped it after enqueue
-               $condTimestamp = isset( $this->params['rootJobTimestamp'] )
-                       ? $this->params['rootJobTimestamp']
-                       : $touchTimestamp;
+               $condTimestamp = $this->params['rootJobTimestamp'] ?? $touchTimestamp;
 
                $dbw = wfGetDB( DB_MASTER );
                $factory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
index e89812b..d2b2107 100644 (file)
@@ -84,7 +84,7 @@ class PublishStashedFileJob extends Job {
                                $this->params['text'],
                                $this->params['watch'],
                                $user,
-                               isset( $this->params['tags'] ) ? $this->params['tags'] : []
+                               $this->params['tags'] ?? []
                        );
                        if ( !$status->isGood() ) {
                                UploadBase::setSessionStatus(
index 76f8d6d..bf27e9c 100644 (file)
@@ -103,7 +103,7 @@ class BacklinkJobUtils {
                        $realBSize = $bSize;
                }
 
-               $extraParams = isset( $opts['params'] ) ? $opts['params'] : [];
+               $extraParams = $opts['params'] ?? [];
 
                $jobs = [];
                // Combine the first range (of size $bSize) backlinks into leaf jobs
index 0c77a7b..1ab17a0 100644 (file)
@@ -38,7 +38,7 @@ class FormatJson {
         * HTML and XML.
         *
         * @warning Do not use this option for JSON that could end up in inline scripts.
-        * - HTML5, §4.3.1.2 Restrictions for contents of script elements
+        * - HTML 5.2, §4.12.1.3 Restrictions for contents of script elements
         * - XML 1.0 (5th Ed.), §2.4 Character Data and Markup
         *
         * @since 1.22
@@ -52,19 +52,18 @@ class FormatJson {
         *
         * @since 1.22
         */
-       const ALL_OK = 3;
+       const ALL_OK = self::UTF8_OK | self::XMLMETA_OK;
 
        /**
-        * If set, treat json objects '{...}' as associative arrays. Without this option,
-        * json objects will be converted to stdClass.
-        * The value is set to 1 to be backward compatible with 'true' that was used before.
+        * If set, treat JSON objects '{...}' as associative arrays. Without this option,
+        * JSON objects will be converted to stdClass.
         *
         * @since 1.24
         */
        const FORCE_ASSOC = 0x100;
 
        /**
-        * If set, attempts to fix invalid json.
+        * If set, attempt to fix invalid JSON.
         *
         * @since 1.24
         */
@@ -77,17 +76,6 @@ class FormatJson {
         */
        const STRIP_COMMENTS = 0x400;
 
-       /**
-        * Regex that matches whitespace inside empty arrays and objects.
-        *
-        * This doesn't affect regular strings inside the JSON because those can't
-        * have a real line break (\n) in them, at this point they are already escaped
-        * as the string "\n" which this doesn't match.
-        *
-        * @private
-        */
-       const WS_CLEANUP_REGEX = '/(?<=[\[{])\n\s*+(?=[\]}])/';
-
        /**
         * Characters problematic in JavaScript.
         *
@@ -95,8 +83,8 @@ class FormatJson {
         *       and U+000D (CR). However, PHP already escapes LF and CR according to RFC 4627.
         */
        private static $badChars = [
-               "\xe2\x80\xa8", // U+2028 LINE SEPARATOR
-               "\xe2\x80\xa9", // U+2029 PARAGRAPH SEPARATOR
+               "\u{2028}", // U+2028 LINE SEPARATOR
+               "\u{2029}", // U+2029 PARAGRAPH SEPARATOR
        ];
 
        /**
@@ -129,11 +117,6 @@ class FormatJson {
                        $pretty = $pretty ? '    ' : false;
                }
 
-               static $bug66021;
-               if ( $pretty !== false && $bug66021 === null ) {
-                       $bug66021 = json_encode( [], JSON_PRETTY_PRINT ) !== '[]';
-               }
-
                // PHP escapes '/' to prevent breaking out of inline script blocks using '</script>',
                // which is hardly useful when '<' and '>' are escaped (and inadequate), and such
                // escaping negatively impacts the human readability of URLs and similar strings.
@@ -146,22 +129,16 @@ class FormatJson {
                        return false;
                }
 
-               if ( $pretty !== false ) {
-                       // Workaround for <https://bugs.php.net/bug.php?id=66021>
-                       if ( $bug66021 ) {
-                               $json = preg_replace( self::WS_CLEANUP_REGEX, '', $json );
+               if ( $pretty !== false && $pretty !== '    ' ) {
+                       // Change the four-space indent to a tab indent
+                       $json = str_replace( "\n    ", "\n\t", $json );
+                       while ( strpos( $json, "\t    " ) !== false ) {
+                               $json = str_replace( "\t    ", "\t\t", $json );
                        }
-                       if ( $pretty !== '    ' ) {
-                               // Change the four-space indent to a tab indent
-                               $json = str_replace( "\n    ", "\n\t", $json );
-                               while ( strpos( $json, "\t    " ) !== false ) {
-                                       $json = str_replace( "\t    ", "\t\t", $json );
-                               }
 
-                               if ( $pretty !== "\t" ) {
-                                       // Change the tab indent to the provided indent
-                                       $json = str_replace( "\t", $pretty, $json );
-                               }
+                       if ( $pretty !== "\t" ) {
+                               // Change the tab indent to the provided indent
+                               $json = str_replace( "\t", $pretty, $json );
                        }
                }
                if ( $escaping & self::UTF8_OK ) {
@@ -263,7 +240,7 @@ class FormatJson {
 
        /**
         * Remove multiline and single line comments from an otherwise valid JSON
-        * input string. This can be used as a preprocessor for to allow JSON
+        * input string. This can be used as a preprocessor, to allow JSON
         * formatted configuration files to contain comments.
         *
         * @param string $json
index 0413ea0..e238887 100644 (file)
@@ -120,8 +120,8 @@ class ArrayUtils {
                $max = $valueCount;
                do {
                        $mid = $min + ( ( $max - $min ) >> 1 );
-                       $item = call_user_func( $valueCallback, $mid );
-                       $comparison = call_user_func( $comparisonCallback, $target, $item );
+                       $item = $valueCallback( $mid );
+                       $comparison = $comparisonCallback( $target, $item );
                        if ( $comparison > 0 ) {
                                $min = $mid;
                        } elseif ( $comparison == 0 ) {
@@ -133,8 +133,8 @@ class ArrayUtils {
                } while ( $min < $max - 1 );
 
                if ( $min == 0 ) {
-                       $item = call_user_func( $valueCallback, $min );
-                       $comparison = call_user_func( $comparisonCallback, $target, $item );
+                       $item = $valueCallback( $min );
+                       $comparison = $comparisonCallback( $target, $item );
                        if ( $comparison < 0 ) {
                                // Before the first item
                                return false;
@@ -168,7 +168,7 @@ class ArrayUtils {
                                                $args[] = $array[$key];
                                        }
                                }
-                               $valueret = call_user_func_array( __METHOD__, $args );
+                               $valueret = self::arrayDiffAssocRecursive( ...$args );
                                if ( count( $valueret ) ) {
                                        $ret[$key] = $valueret;
                                }
index 454fd41..92a4f9e 100644 (file)
@@ -19,7 +19,7 @@
  * @version 0.1.1 -- 2010-09-11
  * @author Trevor Parscal <tparscal@wikimedia.org>
  * @copyright Copyright 2010 Wikimedia Foundation
- * @license http://www.apache.org/licenses/LICENSE-2.0
+ * @license Apache-2.0
  */
 
 /**
@@ -72,15 +72,24 @@ class CSSMin {
                                $url = $match['file'][0];
 
                                // Skip fully-qualified and protocol-relative URLs and data URIs
-                               // Also skips the rare `behavior` property specifying application's default behavior
                                if (
                                        substr( $url, 0, 2 ) === '//' ||
-                                       parse_url( $url, PHP_URL_SCHEME ) ||
-                                       substr( $url, 0, 9 ) === '#default#'
+                                       parse_url( $url, PHP_URL_SCHEME )
                                ) {
                                        break;
                                }
 
+                               // Strip trailing anchors - T115436
+                               $anchor = strpos( $url, '#' );
+                               if ( $anchor !== false ) {
+                                       $url = substr( $url, 0, $anchor );
+
+                                       // '#some-anchors' is not a file
+                                       if ( $url === '' ) {
+                                               break;
+                                       }
+                               }
+
                                $files[] = $path . $url;
                        }
                }
@@ -179,7 +188,7 @@ class CSSMin {
         * @return string
         */
        public static function serializeStringValue( $value ) {
-               $value = strtr( $value, [ "\0" => "\xEF\xBF\xBD", '\\' => '\\\\', '"' => '\\"' ] );
+               $value = strtr( $value, [ "\0" => "\u{FFFD}", '\\' => '\\\\', '"' => '\\"' ] );
                $value = preg_replace_callback( '/[\x01-\x1f\x7f]/', function ( $match ) {
                        return '\\' . base_convert( ord( $match[0] ), 10, 16 ) . ' ';
                }, $value );
@@ -399,6 +408,7 @@ class CSSMin {
                        // Match these three variants separately to avoid broken urls when
                        // e.g. a double quoted url contains a parenthesis, or when a
                        // single quoted url contains a double quote, etc.
+                       // FIXME: Simplify now we only support PHP 7.0.0+
                        // Note: PCRE doesn't support multiple capture groups with the same name by default.
                        // - PCRE 6.7 introduced the "J" modifier (PCRE_INFO_JCHANGED for PCRE_DUPNAMES).
                        //   https://secure.php.net/manual/en/reference.pcre.pattern.modifiers.php
@@ -484,11 +494,11 @@ class CSSMin {
 
                // Pass thru fully-qualified and protocol-relative URLs and data URIs, as well as local URLs if
                // we can't expand them.
-               // Also skips the rare `behavior` property specifying application's default behavior
+               // Also skips anchors or the rare `behavior` property specifying application's default behavior
                if (
                        self::isRemoteUrl( $url ) ||
                        self::isLocalUrl( $url ) ||
-                       substr( $url, 0, 9 ) === '#default#'
+                       substr( $url, 0, 1 ) === '#'
                ) {
                        return $url;
                }
index a67b919..c0ab0a0 100644 (file)
@@ -86,7 +86,7 @@ class Cookie {
         * not a big problem in practice, but there are test cases)
         *
         * @param string $domain The domain to validate
-        * @param string $originDomain (optional) the domain the cookie originates from
+        * @param string|null $originDomain (optional) the domain the cookie originates from
         * @return bool
         */
        public static function validateCookieDomain( $domain, $originDomain = null ) {
index c41aab3..0478a33 100644 (file)
@@ -99,22 +99,14 @@ class CryptHKDF {
                'whirlpool' => 64,
        ];
 
-       /**
-        * @var CryptRand
-        */
-       private $cryptRand;
-
        /**
         * @param string $secretKeyMaterial
         * @param string $algorithm Name of hashing algorithm
         * @param BagOStuff $cache
         * @param string|array $context Context to mix into HKDF context
-        * @param CryptRand $cryptRand
         * @throws InvalidArgumentException if secret key material is too short
         */
-       public function __construct( $secretKeyMaterial, $algorithm, BagOStuff $cache, $context,
-               CryptRand $cryptRand
-       ) {
+       public function __construct( $secretKeyMaterial, $algorithm, BagOStuff $cache, $context ) {
                if ( strlen( $secretKeyMaterial ) < 16 ) {
                        throw new InvalidArgumentException( "secret was too short." );
                }
@@ -122,7 +114,6 @@ class CryptHKDF {
                $this->algorithm = $algorithm;
                $this->cache = $cache;
                $this->context = is_array( $context ) ? $context : [ $context ];
-               $this->cryptRand = $cryptRand;
 
                // To prevent every call from hitting the same memcache server, pick
                // from a set of keys to use. mt_rand is only use to pick a random
@@ -150,12 +141,12 @@ class CryptHKDF {
                        $lastSalt = $this->cache->get( $this->cacheKey );
                        if ( $lastSalt === false ) {
                                // If we don't have a previous value to use as our salt, we use
-                               // 16 bytes from CryptRand, which will use a small amount of
+                               // 16 bytes from random_bytes(), which will use a small amount of
                                // entropy from our pool. Note, "XTR may be deterministic or keyed
                                // via an optional “salt value”  (i.e., a non-secret random
                                // value)..." - http://eprint.iacr.org/2010/264.pdf. However, we
                                // use a strongly random value since we can.
-                               $lastSalt = $this->cryptRand->generate( 16 );
+                               $lastSalt = random_bytes( 16 );
                        }
                        // Get a binary string that is hashLen long
                        $this->salt = hash( $this->algorithm, $lastSalt, true );
index f7702dd..a1bbd09 100644 (file)
  * @author Daniel Friesen
  * @file
  */
-use Psr\Log\LoggerInterface;
 
+/**
+ * @deprecated since 1.32, use random_bytes()/random_int()
+ */
 class CryptRand {
        /**
-        * Minimum number of iterations we want to make in our drift calculations.
+        * @deprecated since 1.32, unused
         */
        const MIN_ITERATIONS = 1000;
 
        /**
-        * Number of milliseconds we want to spend generating each separate byte
-        * of the final generated bytes.
-        * This is used in combination with the hash length to determine the duration
-        * we should spend doing drift calculations.
+        * @deprecated since 1.32, unused
         */
        const MSEC_PER_BYTE = 0.5;
 
        /**
-        * A boolean indicating whether the previous random generation was done using
-        * cryptographically strong random number generator or not.
-        */
-       protected $strong = null;
-
-       /**
-        * List of functions to call to generate some random state
+        * Initialize an initial random state based off of whatever we can find
         *
-        * @var callable[]
-        */
-       protected $randomFuncs = [];
-
-       /**
-        * List of files to generate some random state from
+        * @deprecated since 1.32, unused and does nothing
         *
-        * @var string[]
-        */
-       protected $randomFiles = [];
-
-       /**
-        * @var LoggerInterface
-        */
-       protected $logger;
-
-       public function __construct( array $randomFuncs, array $randomFiles, LoggerInterface $logger ) {
-               $this->randomFuncs = $randomFuncs;
-               $this->randomFiles = $randomFiles;
-               $this->logger = $logger;
-       }
-
-       /**
-        * Initialize an initial random state based off of whatever we can find
         * @return string
         */
        protected function initialRandomState() {
-               // $_SERVER contains a variety of unstable user and system specific information
-               // It'll vary a little with each page, and vary even more with separate users
-               // It'll also vary slightly across different machines
-               $state = serialize( $_SERVER );
-
-               // Try to gather a little entropy from the different php rand sources
-               $state .= rand() . uniqid( mt_rand(), true );
-
-               // Include some information about the filesystem's current state in the random state
-               $files = $this->randomFiles;
-
-               // We know this file is here so grab some info about ourselves
-               $files[] = __FILE__;
-
-               // We must also have a parent folder, and with the usual file structure, a grandparent
-               $files[] = __DIR__;
-               $files[] = dirname( __DIR__ );
-
-               foreach ( $files as $file ) {
-                       Wikimedia\suppressWarnings();
-                       $stat = stat( $file );
-                       Wikimedia\restoreWarnings();
-                       if ( $stat ) {
-                               // stat() duplicates data into numeric and string keys so kill off all the numeric ones
-                               foreach ( $stat as $k => $v ) {
-                                       if ( is_numeric( $k ) ) {
-                                               unset( $k );
-                                       }
-                               }
-                               // The absolute filename itself will differ from install to install so don't leave it out
-                               $path = realpath( $file );
-                               if ( $path !== false ) {
-                                       $state .= $path;
-                               } else {
-                                       $state .= $file;
-                               }
-                               $state .= implode( '', $stat );
-                       } else {
-                               // The fact that the file isn't there is worth at least a
-                               // minuscule amount of entropy.
-                               $state .= '0';
-                       }
-               }
-
-               // Try and make this a little more unstable by including the varying process
-               // id of the php process we are running inside of if we are able to access it
-               if ( function_exists( 'getmypid' ) ) {
-                       $state .= getmypid();
-               }
-
-               // If available try to increase the instability of the data by throwing in
-               // the precise amount of memory that we happen to be using at the moment.
-               if ( function_exists( 'memory_get_usage' ) ) {
-                       $state .= memory_get_usage( true );
-               }
-
-               foreach ( $this->randomFuncs as $randomFunc ) {
-                       $state .= call_user_func( $randomFunc );
-               }
-
-               return $state;
+               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 ) {
-               // Minimum number of iterations (to avoid slow operations causing the
-               // loop to gather little entropy)
-               $minIterations = self::MIN_ITERATIONS;
-               // Duration of time to spend doing calculations (in seconds)
-               $duration = ( self::MSEC_PER_BYTE / 1000 ) * MWCryptHash::hashLength();
-               // Create a buffer to use to trigger memory operations
-               $bufLength = 10000000;
-               $buffer = str_repeat( ' ', $bufLength );
-               $bufPos = 0;
-
-               // Iterate for $duration seconds or at least $minIterations number of iterations
-               $iterations = 0;
-               $startTime = microtime( true );
-               $currentTime = $startTime;
-               while ( $iterations < $minIterations || $currentTime - $startTime < $duration ) {
-                       // Trigger some memory writing to trigger some bus activity
-                       // This may create variance in the time between iterations
-                       $bufPos = ( $bufPos + 13 ) % $bufLength;
-                       $buffer[$bufPos] = ' ';
-                       // Add the drift between this iteration and the last in as entropy
-                       $nextTime = microtime( true );
-                       $delta = (int)( ( $nextTime - $currentTime ) * 1000000 );
-                       $data .= $delta;
-                       // Every 100 iterations hash the data and entropy
-                       if ( $iterations % 100 === 0 ) {
-                               $data = sha1( $data );
-                       }
-                       $currentTime = $nextTime;
-                       $iterations++;
-               }
-               $timeTaken = $currentTime - $startTime;
-               $data = MWCryptHash::hash( $data );
-
-               $this->logger->debug( "Clock drift calculation " .
-                       "(time-taken=" . ( $timeTaken * 1000 ) . "ms, " .
-                       "iterations=$iterations, " .
-                       "time-per-iteration=" . ( $timeTaken / $iterations * 1e6 ) . "us)" );
-
-               return $data;
+               return '';
        }
 
        /**
         * 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() {
-               static $state = null;
-               if ( is_null( $state ) ) {
-                       // Initialize the state with whatever unstable data we can find
-                       // It's important that this data is hashed right afterwards to prevent
-                       // it from being leaked into the output stream
-                       $state = MWCryptHash::hash( $this->initialRandomState() );
-               }
-               // Generate a new random state based on the initial random state or previous
-               // random state by combining it with clock drift
-               $state = $this->driftHash( $state );
-
-               return $state;
+               return '';
        }
 
        /**
@@ -211,191 +78,36 @@ class CryptRand {
         * random bytes generation in the previously run generate* call
         * was cryptographically strong.
         *
-        * @return bool Returns true if the source was strong, false if not.
+        * @deprecated since 1.32, always returns true
+        *
+        * @return bool Always true
         */
        public function wasStrong() {
-               if ( is_null( $this->strong ) ) {
-                       throw new RuntimeException( __METHOD__ . ' called before generation of random data' );
-               }
-
-               return $this->strong;
+               return true;
        }
 
        /**
-        * Generate a run of (ideally) cryptographically random data and return
+        * 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
-        * @param bool $forceStrong Pass true if you want generate to prefer cryptographically
-        *                          strong sources of entropy even if reading from them may steal
-        *                          more entropy from the system than optimal.
         * @return string Raw binary random data
         */
-       public function generate( $bytes, $forceStrong = false ) {
+       public function generate( $bytes ) {
                $bytes = floor( $bytes );
-               static $buffer = '';
-               if ( is_null( $this->strong ) ) {
-                       // Set strength to false initially until we know what source data is coming from
-                       $this->strong = true;
-               }
-
-               if ( strlen( $buffer ) < $bytes ) {
-                       // If available make use of PHP 7's random_bytes
-                       // On Linux, getrandom syscall will be used if available.
-                       // On Windows CryptGenRandom will always be used
-                       // On other platforms, /dev/urandom will be used.
-                       // Avoids polyfills from before php 7.0
-                       // All error situations will throw Exceptions and or Errors
-                       if ( PHP_VERSION_ID >= 70000
-                               || ( defined( 'HHVM_VERSION_ID' ) && HHVM_VERSION_ID >= 31101 )
-                       ) {
-                               $rem = $bytes - strlen( $buffer );
-                               $buffer .= random_bytes( $rem );
-                       }
-                       if ( strlen( $buffer ) >= $bytes ) {
-                               $this->strong = true;
-                       }
-               }
-
-               if ( strlen( $buffer ) < $bytes && function_exists( 'mcrypt_create_iv' ) ) {
-                       // If available make use of mcrypt_create_iv URANDOM source to generate randomness
-                       // On unix-like systems this reads from /dev/urandom but does it without any buffering
-                       // and bypasses openbasedir restrictions, so it's preferable to reading directly
-                       // On Windows starting in PHP 5.3.0 Windows' native CryptGenRandom is used to generate
-                       // entropy so this is also preferable to just trying to read urandom because it may work
-                       // on Windows systems as well.
-                       $rem = $bytes - strlen( $buffer );
-                       $iv = mcrypt_create_iv( $rem, MCRYPT_DEV_URANDOM );
-                       if ( $iv === false ) {
-                               $this->logger->debug( "mcrypt_create_iv returned false." );
-                       } else {
-                               $buffer .= $iv;
-                               $this->logger->debug( "mcrypt_create_iv generated " . strlen( $iv ) .
-                                       " bytes of randomness." );
-                       }
-               }
-
-               if ( strlen( $buffer ) < $bytes && function_exists( 'openssl_random_pseudo_bytes' ) ) {
-                       $rem = $bytes - strlen( $buffer );
-                       $openssl_strong = false;
-                       $openssl_bytes = openssl_random_pseudo_bytes( $rem, $openssl_strong );
-                       if ( $openssl_bytes === false ) {
-                               $this->logger->debug( "openssl_random_pseudo_bytes returned false." );
-                       } else {
-                               $buffer .= $openssl_bytes;
-                               $this->logger->debug( "openssl_random_pseudo_bytes generated " .
-                                       strlen( $openssl_bytes ) . " bytes of " .
-                                       ( $openssl_strong ? "strong" : "weak" ) . " randomness." );
-                       }
-                       if ( strlen( $buffer ) >= $bytes ) {
-                               // openssl tells us if the random source was strong, if some of our data was generated
-                               // using it use it's say on whether the randomness is strong
-                               $this->strong = !!$openssl_strong;
-                       }
-               }
-
-               // Only read from urandom if we can control the buffer size or were passed forceStrong
-               if ( strlen( $buffer ) < $bytes &&
-                       ( function_exists( 'stream_set_read_buffer' ) || $forceStrong )
-               ) {
-                       $rem = $bytes - strlen( $buffer );
-                       if ( !function_exists( 'stream_set_read_buffer' ) && $forceStrong ) {
-                               $this->logger->debug( "Was forced to read from /dev/urandom " .
-                                       "without control over the buffer size." );
-                       }
-                       // /dev/urandom is generally considered the best possible commonly
-                       // available random source, and is available on most *nix systems.
-                       Wikimedia\suppressWarnings();
-                       $urandom = fopen( "/dev/urandom", "rb" );
-                       Wikimedia\restoreWarnings();
-
-                       // Attempt to read all our random data from urandom
-                       // php's fread always does buffered reads based on the stream's chunk_size
-                       // so in reality it will usually read more than the amount of data we're
-                       // asked for and not storing that risks depleting the system's random pool.
-                       // If stream_set_read_buffer is available set the chunk_size to the amount
-                       // of data we need. Otherwise read 8k, php's default chunk_size.
-                       if ( $urandom ) {
-                               // php's default chunk_size is 8k
-                               $chunk_size = 1024 * 8;
-                               if ( function_exists( 'stream_set_read_buffer' ) ) {
-                                       // If possible set the chunk_size to the amount of data we need
-                                       stream_set_read_buffer( $urandom, $rem );
-                                       $chunk_size = $rem;
-                               }
-                               $random_bytes = fread( $urandom, max( $chunk_size, $rem ) );
-                               $buffer .= $random_bytes;
-                               fclose( $urandom );
-                               $this->logger->debug( "/dev/urandom generated " . strlen( $random_bytes ) .
-                                       " bytes of randomness." );
-
-                               if ( strlen( $buffer ) >= $bytes ) {
-                                       // urandom is always strong, set to true if all our data was generated using it
-                                       $this->strong = true;
-                               }
-                       } else {
-                               $this->logger->debug( "/dev/urandom could not be opened." );
-                       }
-               }
-
-               // If we cannot use or generate enough data from a secure source
-               // use this loop to generate a good set of pseudo random data.
-               // This works by initializing a random state using a pile of unstable data
-               // and continually shoving it through a hash along with a variable salt.
-               // We hash the random state with more salt to avoid the state from leaking
-               // out and being used to predict the /randomness/ that follows.
-               if ( strlen( $buffer ) < $bytes ) {
-                       $this->logger->debug( __METHOD__ .
-                               ": Falling back to using a pseudo random state to generate randomness." );
-               }
-               while ( strlen( $buffer ) < $bytes ) {
-                       $buffer .= MWCryptHash::hmac( $this->randomState(), strval( mt_rand() ) );
-                       // This code is never really cryptographically strong, if we use it
-                       // at all, then set strong to false.
-                       $this->strong = false;
-               }
-
-               // Once the buffer has been filled up with enough random data to fulfill
-               // the request shift off enough data to handle the request and leave the
-               // unused portion left inside the buffer for the next request for random data
-               $generated = substr( $buffer, 0, $bytes );
-               $buffer = substr( $buffer, $bytes );
-
-               $this->logger->debug( strlen( $buffer ) .
-                       " bytes of randomness leftover in the buffer." );
-
-               return $generated;
+               return random_bytes( $bytes );
        }
 
        /**
-        * Generate a run of (ideally) cryptographically random data and return
+        * Generate a run of cryptographically random data and return
         * it in hexadecimal string format.
-        * You can use CryptRand::wasStrong() if you wish to know if the source used
-        * was cryptographically strong.
         *
         * @param int $chars The number of hex chars of random data to generate
-        * @param bool $forceStrong Pass true if you want generate to prefer cryptographically
-        *                          strong sources of entropy even if reading from them may steal
-        *                          more entropy from the system than optimal.
         * @return string Hexadecimal random data
         */
-       public function generateHex( $chars, $forceStrong = false ) {
-               // hex strings are 2x the length of raw binary so we divide the length in half
-               // odd numbers will result in a .5 that leads the generate() being 1 character
-               // short, so we use ceil() to ensure that we always have enough bytes
-               $bytes = ceil( $chars / 2 );
-               // Generate the data and then convert it to a hex string
-               $hex = bin2hex( $this->generate( $bytes, $forceStrong ) );
-
-               // A bit of paranoia here, the caller asked for a specific length of string
-               // here, and it's possible (eg when given an odd number) that we may actually
-               // have at least 1 char more than they asked for. Just in case they made this
-               // call intending to insert it into a database that does truncation we don't
-               // want to give them too much and end up with their database and their live
-               // code having two different values because part of what we gave them is truncated
-               // hence, we strip out any run of characters longer than what we were asked for.
-               return substr( $hex, 0, $chars );
+       public function generateHex( $chars ) {
+               return MWCryptRand::generateHex( $chars );
        }
 }
diff --git a/includes/libs/EasyDeflate.php b/includes/libs/EasyDeflate.php
new file mode 100644 (file)
index 0000000..6102746
--- /dev/null
@@ -0,0 +1,72 @@
+<?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.
+ *
+ */
+
+/**
+ * Server-side helper for the easy-deflate library
+ *
+ * @since 1.32
+ */
+class EasyDeflate {
+
+       /**
+        * Whether the content is deflated
+        *
+        * @param string $data
+        *
+        * @return bool
+        */
+       public static function isDeflated( $data ) {
+               return substr( $data, 0, 11 ) === 'rawdeflate,';
+       }
+
+       /**
+        * For content that has been compressed with deflate in the client,
+        * try to uncompress it with inflate.
+        *
+        * If data is not prefixed with 'rawdeflate,' it will be returned unmodified.
+        *
+        * Data can be compressed in the client using the 'easy-deflate.deflate'
+        * module:
+        *
+        * @code
+        *    mw.loader.using( 'easy-deflate.deflate' ).then( function () {
+        *        var deflated = EasyDeflate.deflate( myContent );
+        *    } );
+        * @endcode
+        *
+        * @param string $data Deflated data
+        * @return StatusValue Inflated data will be set as the value
+        * @throws InvalidArgumentException If the data wasn't deflated
+        */
+       public static function inflate( $data ) {
+               if ( !self::isDeflated( $data ) ) {
+                       throw new InvalidArgumentException( 'Data does not begin with deflated prefix' );
+               }
+               $deflated = base64_decode( substr( $data, 11 ), true );
+               if ( $deflated === false ) {
+                       return StatusValue::newFatal( 'easydeflate-invaliddeflate' );
+               }
+               Wikimedia\suppressWarnings();
+               $inflated = gzinflate( $deflated );
+               Wikimedia\restoreWarnings();
+               if ( $inflated === false ) {
+                       return StatusValue::newFatal( 'easydeflate-invaliddeflate' );
+               }
+               return StatusValue::newGood( $inflated );
+       }
+}
index 79d1374..a9b26ac 100644 (file)
@@ -29,7 +29,7 @@
  *
  * @file
  *
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
  * @author Jeroen De Dauw < jeroendedauw@gmail.com >
  */
 abstract class GenericArrayObject extends ArrayObject {
index 3b9c24d..251fa88 100644 (file)
 /**
  * Convenience class for weighted consistent hash rings
  *
+ * This deterministically maps "keys" to a set of "locations" while avoiding clumping
+ *
+ * Each location is represented by a number of nodes on a ring proportionate to the ratio
+ * of its weight compared to the total location weight. Note positions are deterministically
+ * derived from the hash of the location name. Nodes are responsible for the portion of the
+ * ring, counter-clockwise, up until the next node. Locations are responsible for all portions
+ * of the ring that the location's nodes are responsible for.
+ *
+ * A location that is temporarily "ejected" is said to be absent from the "live" ring.
+ * If no location ejections are active, then the base ring and live ring are identical.
+ *
  * @since 1.22
  */
-class HashRing {
-       /** @var array (location => weight) */
-       protected $sourceMap = [];
-       /** @var array (location => (start, end)) */
-       protected $ring = [];
+class HashRing implements Serializable {
+       /** @var string Hashing algorithm for hash() */
+       protected $algo;
+       /** @var int[] Non-empty (location => integer weight) */
+       protected $weightByLocation;
+       /** @var int[] Map of (location => UNIX timestamp) */
+       protected $ejectExpiryByLocation;
 
-       /** @var HashRing|null */
+       /** @var array[] Non-empty list of (float, node name, location name) */
+       protected $baseRing;
+       /** @var array[] Non-empty list of (float, node name, location name) */
        protected $liveRing;
-       /** @var array (location => UNIX timestamp) */
-       protected $ejectionExpiries = [];
-       /** @var int UNIX timestamp */
-       protected $ejectionNextExpiry = INF;
 
-       const RING_SIZE = 268435456; // 2^28
+       /** @var float Number of positions on the ring */
+       const RING_SIZE = 4294967296.0; // 2^32
+       /** @var integer Overall number of node groups per server */
+       const HASHES_PER_LOCATION = 40;
+       /** @var integer Number of nodes in a node group */
+       const SECTORS_PER_HASH = 4;
+
+       const KEY_POS = 0;
+       const KEY_LOCATION = 1;
+
+       /** @var int Consider all locations */
+       const RING_ALL = 0;
+       /** @var int Only consider "live" locations */
+       const RING_LIVE = 1;
 
        /**
-        * @param array $map (location => weight)
+        * Make a consistent hash ring given a set of locations and their weight values
+        *
+        * @param int[] $map Map of (location => weight)
+        * @param string $algo Hashing algorithm listed in hash_algos() [optional]
+        * @param int[] $ejections Map of (location => UNIX timestamp) for ejection expiries
+        * @since 1.31
         */
-       public function __construct( array $map ) {
-               $map = array_filter( $map, function ( $w ) {
-                       return $w > 0;
-               } );
-               if ( !count( $map ) ) {
-                       throw new UnexpectedValueException( "Ring is empty or all weights are zero." );
-               }
-               $this->sourceMap = $map;
-               // Sort the locations based on the hash of their names
-               $hashes = [];
-               foreach ( $map as $location => $weight ) {
-                       $hashes[$location] = sha1( $location );
-               }
-               uksort( $map, function ( $a, $b ) use ( $hashes ) {
-                       return strcmp( $hashes[$a], $hashes[$b] );
-               } );
-               // Fit the map to weight-proportionate one with a space of size RING_SIZE
-               $sum = array_sum( $map );
-               $standardMap = [];
-               foreach ( $map as $location => $weight ) {
-                       $standardMap[$location] = (int)floor( $weight / $sum * self::RING_SIZE );
+       public function __construct( array $map, $algo = 'sha1', array $ejections = [] ) {
+               $this->init( $map, $algo, $ejections );
+       }
+
+       /**
+        * @param int[] $map Map of (location => integer)
+        * @param string $algo Hashing algorithm
+        * @param int[] $ejections Map of (location => UNIX timestamp) for ejection expires
+        */
+       protected function init( array $map, $algo, array $ejections ) {
+               if ( !in_array( $algo, hash_algos(), true ) ) {
+                       throw new RuntimeException( __METHOD__ . ": unsupported '$algo' hash algorithm." );
                }
-               // Build a ring of RING_SIZE spots, with each location at a spot in location hash order
-               $index = 0;
-               foreach ( $standardMap as $location => $weight ) {
-                       // Location covers half-closed interval [$index,$index + $weight)
-                       $this->ring[$location] = [ $index, $index + $weight ];
-                       $index += $weight;
+
+               $weightByLocation = array_filter( $map );
+               if ( $weightByLocation === [] ) {
+                       throw new UnexpectedValueException( "No locations with non-zero weight." );
+               } elseif ( min( $map ) < 0 ) {
+                       throw new InvalidArgumentException( "Location weight cannot be negative." );
                }
-               // Make sure the last location covers what is left
-               end( $this->ring );
-               $this->ring[key( $this->ring )][1] = self::RING_SIZE;
+
+               $this->algo = $algo;
+               $this->weightByLocation = $weightByLocation;
+               $this->ejectExpiryByLocation = $ejections;
+               $this->baseRing = $this->buildLocationRing( $this->weightByLocation, $this->algo );
        }
 
        /**
@@ -82,11 +104,10 @@ class HashRing {
         *
         * @param string $item
         * @return string Location
+        * @throws UnexpectedValueException
         */
        final public function getLocation( $item ) {
-               $locations = $this->getLocations( $item, 1 );
-
-               return $locations[0];
+               return $this->getLocations( $item, 1 )[0];
        }
 
        /**
@@ -94,46 +115,83 @@ class HashRing {
         *
         * @param string $item
         * @param int $limit Maximum number of locations to return
-        * @return array List of locations
+        * @param int $from One of the RING_* class constants
+        * @return string[] List of locations
+        * @throws UnexpectedValueException
         */
-       public function getLocations( $item, $limit ) {
-               $locations = [];
-               $primaryLocation = null;
-               $spot = hexdec( substr( sha1( $item ), 0, 7 ) ); // first 28 bits
-               foreach ( $this->ring as $location => $range ) {
-                       if ( count( $locations ) >= $limit ) {
-                               break;
-                       }
-                       // The $primaryLocation is the location the item spot is in.
-                       // After that is reached, keep appending the next locations.
-                       if ( ( $range[0] <= $spot && $spot < $range[1] ) || $primaryLocation !== null ) {
-                               if ( $primaryLocation === null ) {
-                                       $primaryLocation = $location;
-                               }
-                               $locations[] = $location;
-                       }
+       public function getLocations( $item, $limit, $from = self::RING_ALL ) {
+               if ( $from === self::RING_ALL ) {
+                       $ring = $this->baseRing;
+               } elseif ( $from === self::RING_LIVE ) {
+                       $ring = $this->getLiveRing();
+               } else {
+                       throw new InvalidArgumentException( "Invalid ring source specified." );
                }
-               // If more locations are requested, wrap-around and keep adding them
-               reset( $this->ring );
+
+               // Locate this item's position on the hash ring
+               $position = $this->getItemPosition( $item );
+               $itemNodeIndex = $this->findNodeIndexForPosition( $position, $ring );
+
+               $locations = [];
+               $currentIndex = $itemNodeIndex;
                while ( count( $locations ) < $limit ) {
-                       $location = key( $this->ring );
-                       if ( $location === $primaryLocation ) {
-                               break; // don't go in circles
+                       $nodeLocation = $ring[$currentIndex][self::KEY_LOCATION];
+                       if ( !in_array( $nodeLocation, $locations, true ) ) {
+                               // Ignore other nodes for the same locations already added
+                               $locations[] = $nodeLocation;
+                       }
+                       $currentIndex = $this->getNextClockwiseNodeIndex( $currentIndex, $ring );
+                       if ( $currentIndex === $itemNodeIndex ) {
+                               break; // all nodes visited
                        }
-                       $locations[] = $location;
-                       next( $this->ring );
                }
 
                return $locations;
        }
 
        /**
-        * Get the map of locations to weight (ignores 0-weight items)
+        * @param float $position
+        * @param array[] $ring Either the base or live ring
+        * @return int|null
+        */
+       private function findNodeIndexForPosition( $position, $ring ) {
+               $count = count( $ring );
+               if ( $count === 0 ) {
+                       return null;
+               }
+               $lowPos = 0;
+               $highPos = $count;
+               while ( true ) {
+                       $midPos = intval( ( $lowPos + $highPos ) / 2 );
+                       if ( $midPos === $count ) {
+                               return 0;
+                       }
+                       $midVal = $ring[$midPos][self::KEY_POS];
+                       $midMinusOneVal = $midPos === 0 ? 0 : $ring[$midPos - 1][self::KEY_POS];
+
+                       if ( $position <= $midVal && $position > $midMinusOneVal ) {
+                               return $midPos;
+                       }
+
+                       if ( $midVal < $position ) {
+                               $lowPos = $midPos + 1;
+                       } else {
+                               $highPos = $midPos - 1;
+                       }
+
+                       if ( $lowPos > $highPos ) {
+                               return 0;
+                       }
+               }
+       }
+
+       /**
+        * Get the map of locations to weight (does not include zero weight items)
         *
-        * @return array
+        * @return int[]
         */
        public function getLocationWeights() {
-               return $this->sourceMap;
+               return $this->weightByLocation;
        }
 
        /**
@@ -142,53 +200,19 @@ class HashRing {
         * @param string $location
         * @param int $ttl Seconds
         * @return bool Whether some non-ejected locations are left
+        * @throws UnexpectedValueException
         */
        public function ejectFromLiveRing( $location, $ttl ) {
-               if ( !isset( $this->sourceMap[$location] ) ) {
+               if ( !isset( $this->weightByLocation[$location] ) ) {
                        throw new UnexpectedValueException( "No location '$location' in the ring." );
                }
-               $expiry = time() + $ttl;
-               $this->liveRing = null; // stale
-               $this->ejectionExpiries[$location] = $expiry;
-               $this->ejectionNextExpiry = min( $expiry, $this->ejectionNextExpiry );
 
-               return ( count( $this->ejectionExpiries ) < count( $this->sourceMap ) );
-       }
+               $expiry = $this->getCurrentTime() + $ttl;
+               $this->ejectExpiryByLocation[$location] = $expiry;
 
-       /**
-        * Get the "live" hash ring (which does not include ejected locations)
-        *
-        * @return HashRing
-        * @throws UnexpectedValueException
-        */
-       protected function getLiveRing() {
-               $now = time();
-               if ( $this->liveRing === null || $this->ejectionNextExpiry <= $now ) {
-                       $this->ejectionExpiries = array_filter(
-                               $this->ejectionExpiries,
-                               function ( $expiry ) use ( $now ) {
-                                       return ( $expiry > $now );
-                               }
-                       );
-                       if ( count( $this->ejectionExpiries ) ) {
-                               $map = array_diff_key( $this->sourceMap, $this->ejectionExpiries );
-                               $this->liveRing = count( $map ) ? new self( $map ) : false;
-
-                               $this->ejectionNextExpiry = min( $this->ejectionExpiries );
-                       } else { // common case; avoid recalculating ring
-                               $this->liveRing = clone $this;
-                               $this->liveRing->ejectionExpiries = [];
-                               $this->liveRing->ejectionNextExpiry = INF;
-                               $this->liveRing->liveRing = null;
-
-                               $this->ejectionNextExpiry = INF;
-                       }
-               }
-               if ( !$this->liveRing ) {
-                       throw new UnexpectedValueException( "The live ring is currently empty." );
-               }
+               $this->liveRing = null; // invalidate ring cache
 
-               return $this->liveRing;
+               return ( count( $this->ejectExpiryByLocation ) < count( $this->weightByLocation ) );
        }
 
        /**
@@ -198,8 +222,8 @@ class HashRing {
         * @return string Location
         * @throws UnexpectedValueException
         */
-       public function getLiveLocation( $item ) {
-               return $this->getLiveRing()->getLocation( $item );
+       final public function getLiveLocation( $item ) {
+               return $this->getLocations( $item, 1, self::RING_LIVE )[0];
        }
 
        /**
@@ -207,20 +231,200 @@ class HashRing {
         *
         * @param string $item
         * @param int $limit Maximum number of locations to return
-        * @return array List of locations
+        * @return string[] List of locations
         * @throws UnexpectedValueException
         */
-       public function getLiveLocations( $item, $limit ) {
-               return $this->getLiveRing()->getLocations( $item, $limit );
+       final public function getLiveLocations( $item, $limit ) {
+               return $this->getLocations( $item, $limit, self::RING_LIVE );
        }
 
        /**
-        * Get the map of "live" locations to weight (ignores 0-weight items)
+        * Get the map of "live" locations to weight (does not include zero weight items)
         *
-        * @return array
+        * @return int[]
         * @throws UnexpectedValueException
         */
        public function getLiveLocationWeights() {
-               return $this->getLiveRing()->getLocationWeights();
+               $now = $this->getCurrentTime();
+
+               return array_diff_key(
+                       $this->weightByLocation,
+                       array_filter(
+                               $this->ejectExpiryByLocation,
+                               function ( $expiry ) use ( $now ) {
+                                       return ( $expiry > $now );
+                               }
+                       )
+               );
+       }
+
+       /**
+        * @param int[] $weightByLocation
+        * @param string $algo Hashing algorithm
+        * @return array[]
+        */
+       private function buildLocationRing( array $weightByLocation, $algo ) {
+               $locationCount = count( $weightByLocation );
+               $totalWeight = array_sum( $weightByLocation );
+
+               $ring = [];
+               // Assign nodes to all locations based on location weight
+               $claimed = []; // (position as string => (node, index))
+               foreach ( $weightByLocation as $location => $weight ) {
+                       $ratio = $weight / $totalWeight;
+                       // There $locationCount * (HASHES_PER_LOCATION * 4) nodes available;
+                       // assign a few groups of nodes to this location based on its weight.
+                       $nodesQuartets = intval( $ratio * self::HASHES_PER_LOCATION * $locationCount );
+                       for ( $qi = 0; $qi < $nodesQuartets; ++$qi ) {
+                               // For efficiency, get 4 points per hash call and 4X node count.
+                               // If $algo is MD5, then this matches that of with libketama.
+                               // See https://github.com/RJ/ketama/blob/master/libketama/ketama.c
+                               $positions = $this->getNodePositionQuartet( "{$location}-{$qi}" );
+                               foreach ( $positions as $gi => $position ) {
+                                       $node = ( $qi * self::SECTORS_PER_HASH + $gi ) . "@$location";
+                                       $posKey = (string)$position; // large integer
+                                       if ( isset( $claimed[$posKey] ) ) {
+                                               // Disallow duplicates for sanity (name decides precedence)
+                                               if ( $claimed[$posKey]['node'] > $node ) {
+                                                       continue;
+                                               } else {
+                                                       unset( $ring[$claimed[$posKey]['index']] );
+                                               }
+                                       }
+                                       $ring[] = [
+                                               self::KEY_POS => $position,
+                                               self::KEY_LOCATION => $location
+                                       ];
+                                       $claimed[$posKey] = [ 'node' => $node, 'index' => count( $ring ) - 1 ];
+                               }
+                       }
+               }
+               // Sort the locations into clockwise order based on the hash ring position
+               usort( $ring, function ( $a, $b ) {
+                       if ( $a[self::KEY_POS] === $b[self::KEY_POS] ) {
+                               throw new UnexpectedValueException( 'Duplicate node positions.' );
+                       }
+
+                       return ( $a[self::KEY_POS] < $b[self::KEY_POS] ? -1 : 1 );
+               } );
+
+               return $ring;
+       }
+
+       /**
+        * @param string $item Key
+        * @return float Ring position; integral number in [0, self::RING_SIZE - 1]
+        */
+       private function getItemPosition( $item ) {
+               // If $algo is MD5, then this matches that of with libketama.
+               // See https://github.com/RJ/ketama/blob/master/libketama/ketama.c
+               $octets = substr( hash( $this->algo, (string)$item, true ), 0, 4 );
+               if ( strlen( $octets ) != 4 ) {
+                       throw new UnexpectedValueException( __METHOD__ . ": {$this->algo} is < 32 bits." );
+               }
+
+               return (float)sprintf( '%u', unpack( 'V', $octets )[1] );
+       }
+
+       /**
+        * @param string $nodeGroupName
+        * @return float[] Four ring positions on [0, self::RING_SIZE - 1]
+        */
+       private function getNodePositionQuartet( $nodeGroupName ) {
+               $octets = substr( hash( $this->algo, (string)$nodeGroupName, true ), 0, 16 );
+               if ( strlen( $octets ) != 16 ) {
+                       throw new UnexpectedValueException( __METHOD__ . ": {$this->algo} is < 128 bits." );
+               }
+
+               $positions = [];
+               foreach ( unpack( 'V4', $octets ) as $signed ) {
+                       $positions[] = (float)sprintf( '%u', $signed );
+               }
+
+               return $positions;
+       }
+
+       /**
+        * @param int $i Valid index for a node in the ring
+        * @param array[] $ring Either the base or live ring
+        * @return int Valid index for a node in the ring
+        */
+       private function getNextClockwiseNodeIndex( $i, $ring ) {
+               if ( !isset( $ring[$i] ) ) {
+                       throw new UnexpectedValueException( __METHOD__ . ": reference index is invalid." );
+               }
+
+               $next = $i + 1;
+
+               return ( $next < count( $ring ) ) ? $next : 0;
+       }
+
+       /**
+        * Get the "live" hash ring (which does not include ejected locations)
+        *
+        * @return array[]
+        * @throws UnexpectedValueException
+        */
+       protected function getLiveRing() {
+               if ( !$this->ejectExpiryByLocation ) {
+                       return $this->baseRing; // nothing ejected
+               }
+
+               $now = $this->getCurrentTime();
+
+               if ( $this->liveRing === null || min( $this->ejectExpiryByLocation ) <= $now ) {
+                       // Live ring needs to be regerenated...
+                       $this->ejectExpiryByLocation = array_filter(
+                               $this->ejectExpiryByLocation,
+                               function ( $expiry ) use ( $now ) {
+                                       return ( $expiry > $now );
+                               }
+                       );
+
+                       if ( count( $this->ejectExpiryByLocation ) ) {
+                               // Some locations are still ejected from the ring
+                               $liveRing = [];
+                               foreach ( $this->baseRing as $i => $nodeInfo ) {
+                                       $location = $nodeInfo[self::KEY_LOCATION];
+                                       if ( !isset( $this->ejectExpiryByLocation[$location] ) ) {
+                                               $liveRing[] = $nodeInfo;
+                                       }
+                               }
+                       } else {
+                               $liveRing = $this->baseRing;
+                       }
+
+                       $this->liveRing = $liveRing;
+               }
+
+               if ( !$this->liveRing ) {
+                       throw new UnexpectedValueException( "The live ring is currently empty." );
+               }
+
+               return $this->liveRing;
+       }
+
+       /**
+        * @return int UNIX timestamp
+        */
+       protected function getCurrentTime() {
+               return time();
+       }
+
+       public function serialize() {
+               return serialize( [
+                       'algorithm' => $this->algo,
+                       'locations' => $this->weightByLocation,
+                       'ejections' => $this->ejectExpiryByLocation
+               ] );
+       }
+
+       public function unserialize( $serialized ) {
+               $data = unserialize( $serialized );
+               if ( is_array( $data ) ) {
+                       $this->init( $data['locations'], $data['algorithm'], $data['ejections'] );
+               } else {
+                       throw new UnexpectedValueException( __METHOD__ . ": unable to decode JSON." );
+               }
        }
 }
index 7e65216..4b14160 100644 (file)
@@ -84,7 +84,7 @@ class HttpStatus {
                        507 => 'Insufficient Storage',
                        511 => 'Network Authentication Required',
                ];
-               return isset( $statusMessage[$code] ) ? $statusMessage[$code] : null;
+               return $statusMessage[$code] ?? null;
        }
 
        /**
index f95bb1e..8efcd15 100644 (file)
@@ -164,7 +164,7 @@ class IP {
                }
                if ( self::isIPv4( $ip ) ) {
                        // Remove leading 0's from octet representation of IPv4 address
-                       $ip = preg_replace( '/(?:^|(?<=\.))0+(?=[1-9]|0\.|0$)/', '', $ip );
+                       $ip = preg_replace( '!(?:^|(?<=\.))0+(?=[1-9]|0[./]|0$)!', '', $ip );
                        return $ip;
                }
                // Remove any whitespaces, convert to upper case
@@ -425,7 +425,7 @@ class IP {
                        $ip = self::sanitizeIP( $ip );
                        $n = ip2long( $ip );
                        if ( $n < 0 ) {
-                               $n += pow( 2, 32 );
+                               $n += 2 ** 32;
                                # On 32-bit platforms (and on Windows), 2^32 does not fit into an int,
                                # so $n becomes a float. We convert it to string instead.
                                if ( is_float( $n ) ) {
@@ -487,7 +487,7 @@ class IP {
                        }
                        # Convert to unsigned
                        if ( $network < 0 ) {
-                               $network += pow( 2, 32 );
+                               $network += 2 ** 32;
                        }
                } else {
                        $network = false;
@@ -523,7 +523,7 @@ class IP {
                                $start = $end = false;
                        } else {
                                $start = sprintf( '%08X', $network );
-                               $end = sprintf( '%08X', $network + pow( 2, ( 32 - $bits ) ) - 1 );
+                               $end = sprintf( '%08X', $network + 2 ** ( 32 - $bits ) - 1 );
                        }
                // Explicit range
                } elseif ( strpos( $range, '-' ) !== false ) {
index 5ecfc7c..2e8b591 100644 (file)
@@ -4,7 +4,10 @@
  *
  * @file
  * @author Paul Copperman <paul.copperman@gmail.com>
- * @license Choose any of Apache, MIT, GPL, LGPL
+ * @license Apache-2.0
+ * @license MIT
+ * @license GPL-2.0-or-later
+ * @license LGPL-2.1-or-later
  */
 
 /**
@@ -572,7 +575,7 @@ class JavaScriptMinifier {
 
                        // Now get the token type from our type array
                        $token = substr( $s, $pos, $end - $pos ); // so $end - $pos == strlen( $token )
-                       $type = isset( $tokenTypes[$token] ) ? $tokenTypes[$token] : self::TYPE_LITERAL;
+                       $type = $tokenTypes[$token] ?? self::TYPE_LITERAL;
 
                        if ( $newlineFound && isset( $semicolon[$state][$type] ) ) {
                                // This token triggers the semicolon insertion mechanism of javascript. While we
index 553315f..ad5e58d 100644 (file)
@@ -25,27 +25,47 @@ use Wikimedia\Assert\Assert;
 /**
  * Handles a simple LRU key/value map with a maximum number of entries
  *
- * Use ProcessCacheLRU if hierarchical purging is needed or objects can become stale
+ * The last-modification timestamp of entries is internally tracked so that callers can
+ * specify the maximum acceptable age of entries in calls to the has() method. As a convenience,
+ * the hasField(), getField(), and setField() methods can be used for entries that are field/value
+ * maps themselves; such fields will have their own internally tracked last-modification timestamp.
  *
  * @see ProcessCacheLRU
  * @ingroup Cache
  * @since 1.23
  */
-class MapCacheLRU {
-       /** @var array */
-       protected $cache = []; // (key => value)
+class MapCacheLRU implements IExpiringStore, Serializable {
+       /** @var array Map of (key => value) */
+       private $cache = [];
+       /** @var array Map of (key => (UNIX timestamp, (field => UNIX timestamp))) */
+       private $timestamps = [];
+       /** @var float Default entry timestamp if not specified */
+       private $epoch;
 
-       protected $maxCacheKeys; // integer; max entries
+       /** @var int Max number of entries */
+       private $maxCacheKeys;
+
+       /** @var float|null */
+       private $wallClockOverride;
+
+       const RANK_TOP = 1.0;
+
+       /** @var int Array key that holds the entry's main timestamp (flat key use) */
+       const SIMPLE = 0;
+       /** @var int Array key that holds the entry's field timestamps (nested key use) */
+       const FIELDS = 1;
 
        /**
-        * @param int $maxKeys Maximum number of entries allowed (min 1).
-        * @throws Exception When $maxCacheKeys is not an int or not above zero.
+        * @param int $maxKeys Maximum number of entries allowed (min 1)
+        * @throws Exception When $maxKeys is not an int or not above zero
         */
        public function __construct( $maxKeys ) {
                Assert::parameterType( 'integer', $maxKeys, '$maxKeys' );
                Assert::parameter( $maxKeys > 0, '$maxKeys', 'must be above zero' );
 
                $this->maxCacheKeys = $maxKeys;
+               // Use the current time as the default "as of" timesamp of entries
+               $this->epoch = $this->getCurrentTime();
        }
 
        /**
@@ -86,13 +106,14 @@ class MapCacheLRU {
         * @param float $rank Bottom fraction of the list where keys start off [Default: 1.0]
         * @return void
         */
-       public function set( $key, $value, $rank = 1.0 ) {
+       public function set( $key, $value, $rank = self::RANK_TOP ) {
                if ( $this->has( $key ) ) {
                        $this->ping( $key );
                } elseif ( count( $this->cache ) >= $this->maxCacheKeys ) {
                        reset( $this->cache );
                        $evictKey = key( $this->cache );
                        unset( $this->cache[$evictKey] );
+                       unset( $this->timestamps[$evictKey] );
                }
 
                if ( $rank < 1.0 && $rank > 0 ) {
@@ -103,20 +124,31 @@ class MapCacheLRU {
                } else {
                        $this->cache[$key] = $value;
                }
+
+               $this->timestamps[$key] = [
+                       self::SIMPLE => $this->getCurrentTime(),
+                       self::FIELDS => []
+               ];
        }
 
        /**
         * Check if a key exists
         *
         * @param string $key
+        * @param float $maxAge Ignore items older than this many seconds [optional] (since 1.32)
         * @return bool
         */
-       public function has( $key ) {
+       public function has( $key, $maxAge = 0.0 ) {
                if ( !is_int( $key ) && !is_string( $key ) ) {
                        throw new UnexpectedValueException(
                                __METHOD__ . ' called with invalid key. Must be string or integer.' );
                }
-               return array_key_exists( $key, $this->cache );
+
+               if ( !array_key_exists( $key, $this->cache ) ) {
+                       return false;
+               }
+
+               return ( $maxAge <= 0 || $this->getAge( $key ) <= $maxAge );
        }
 
        /**
@@ -125,10 +157,11 @@ class MapCacheLRU {
         * If the item is already set, it will be pushed to the top of the cache.
         *
         * @param string $key
-        * @return mixed Returns null if the key was not found
+        * @param float $maxAge Ignore items older than this many seconds [optional] (since 1.32)
+        * @return mixed Returns null if the key was not found or is older than $maxAge
         */
-       public function get( $key ) {
-               if ( !$this->has( $key ) ) {
+       public function get( $key, $maxAge = 0.0 ) {
+               if ( !$this->has( $key, $maxAge ) ) {
                        return null;
                }
 
@@ -137,6 +170,56 @@ class MapCacheLRU {
                return $this->cache[$key];
        }
 
+       /**
+        * @param string|int $key
+        * @param string|int $field
+        * @param mixed $value
+        * @param float $initRank
+        */
+       public function setField( $key, $field, $value, $initRank = self::RANK_TOP ) {
+               if ( $this->has( $key ) ) {
+                       $this->ping( $key );
+               } else {
+                       $this->set( $key, [], $initRank );
+               }
+
+               if ( !is_array( $this->cache[$key] ) ) {
+                       throw new UnexpectedValueException( "The value of '$key' is not an array." );
+               }
+
+               $this->cache[$key][$field] = $value;
+               $this->timestamps[$key][self::FIELDS][$field] = $this->getCurrentTime();
+       }
+
+       /**
+        * @param string|int $key
+        * @param string|int $field
+        * @param float $maxAge Ignore items older than this many seconds [optional] (since 1.32)
+        * @return bool
+        */
+       public function hasField( $key, $field, $maxAge = 0.0 ) {
+               $value = $this->get( $key );
+               if ( !is_array( $value ) || !array_key_exists( $field, $value ) ) {
+                       return false;
+               }
+
+               return ( $maxAge <= 0 || $this->getAge( $key, $field ) <= $maxAge );
+       }
+
+       /**
+        * @param string|int $key
+        * @param string|int $field
+        * @param float $maxAge Ignore items older than this many seconds [optional] (since 1.32)
+        * @return mixed Returns null if the key was not found or is older than $maxAge
+        */
+       public function getField( $key, $field, $maxAge = 0.0 ) {
+               if ( !$this->hasField( $key, $field, $maxAge ) ) {
+                       return null;
+               }
+
+               return $this->cache[$key][$field];
+       }
+
        /**
         * @return array
         * @since 1.25
@@ -154,10 +237,13 @@ class MapCacheLRU {
         * @param string $key
         * @param callable $callback Callback that will produce the value
         * @param float $rank Bottom fraction of the list where keys start off [Default: 1.0]
+        * @param float $maxAge Ignore items older than this many seconds [Default: 0.0] (since 1.32)
         * @return mixed The cached value if found or the result of $callback otherwise
         */
-       public function getWithSetCallback( $key, callable $callback, $rank = 1.0 ) {
-               if ( $this->has( $key ) ) {
+       public function getWithSetCallback(
+               $key, callable $callback, $rank = self::RANK_TOP, $maxAge = 0.0
+       ) {
+               if ( $this->has( $key, $maxAge ) ) {
                        $value = $this->get( $key );
                } else {
                        $value = call_user_func( $callback );
@@ -172,27 +258,105 @@ class MapCacheLRU {
        /**
         * Clear one or several cache entries, or all cache entries
         *
-        * @param string|array $keys
+        * @param string|array|null $keys
         * @return void
         */
        public function clear( $keys = null ) {
-               if ( $keys === null ) {
+               if ( func_num_args() == 0 ) {
                        $this->cache = [];
+                       $this->timestamps = [];
                } else {
                        foreach ( (array)$keys as $key ) {
                                unset( $this->cache[$key] );
+                               unset( $this->timestamps[$key] );
                        }
                }
        }
 
+       /**
+        * Get the maximum number of keys allowed
+        *
+        * @return int
+        * @since 1.32
+        */
+       public function getMaxSize() {
+               return $this->maxCacheKeys;
+       }
+
+       /**
+        * Resize the maximum number of cache entries, removing older entries as needed
+        *
+        * @param int $maxKeys Maximum number of entries allowed (min 1)
+        * @return void
+        * @throws Exception When $maxKeys is not an int or not above zero
+        * @since 1.32
+        */
+       public function setMaxSize( $maxKeys ) {
+               Assert::parameterType( 'integer', $maxKeys, '$maxKeys' );
+               Assert::parameter( $maxKeys > 0, '$maxKeys', 'must be above zero' );
+
+               $this->maxCacheKeys = $maxKeys;
+               while ( count( $this->cache ) > $this->maxCacheKeys ) {
+                       reset( $this->cache );
+                       $evictKey = key( $this->cache );
+                       unset( $this->cache[$evictKey] );
+                       unset( $this->timestamps[$evictKey] );
+               }
+       }
+
        /**
         * Push an entry to the top of the cache
         *
         * @param string $key
         */
-       protected function ping( $key ) {
+       private function ping( $key ) {
                $item = $this->cache[$key];
                unset( $this->cache[$key] );
                $this->cache[$key] = $item;
        }
+
+       /**
+        * @param string|int $key
+        * @param string|int|null $field [optional]
+        * @return float UNIX timestamp; the age of the given entry or entry field
+        */
+       private function getAge( $key, $field = null ) {
+               if ( $field !== null ) {
+                       $mtime = $this->timestamps[$key][self::FIELDS][$field] ?? $this->epoch;
+               } else {
+                       $mtime = $this->timestamps[$key][self::SIMPLE] ?? $this->epoch;
+               }
+
+               return ( $this->getCurrentTime() - $mtime );
+       }
+
+       public function serialize() {
+               return serialize( [
+                       'entries' => $this->cache,
+                       'timestamps' => $this->timestamps
+               ] );
+       }
+
+       public function unserialize( $serialized ) {
+               $data = unserialize( $serialized );
+               $this->cache = $data['entries'] ?? [];
+               $this->timestamps = $data['timestamps'] ?? [];
+               $this->epoch = $this->getCurrentTime();
+       }
+
+       /**
+        * @return float UNIX timestamp
+        * @codeCoverageIgnore
+        */
+       protected function getCurrentTime() {
+               return $this->wallClockOverride ?: microtime( true );
+       }
+
+       /**
+        * @param float|null &$time Mock UNIX timestamp for testing
+        * @codeCoverageIgnore
+        */
+       public function setMockTime( &$time ) {
+               $this->wallClockOverride =& $time;
+       }
 }
index d60af34..4a62e72 100644 (file)
@@ -60,7 +60,7 @@ class MappedIterator extends FilterIterator {
                }
                parent::__construct( $baseIterator );
                $this->vCallback = $vCallback;
-               $this->aCallback = isset( $options['accept'] ) ? $options['accept'] : null;
+               $this->aCallback = $options['accept'] ?? null;
        }
 
        public function next() {
index 14462f1..e9d1fc1 100644 (file)
@@ -123,7 +123,7 @@ class MemoizedCallable {
                $success = false;
                $result = $this->fetchResult( $key, $success );
                if ( !$success ) {
-                       $result = call_user_func_array( $this->callable, $args );
+                       $result = ( $this->callable )( ...$args );
                        $this->storeResult( $key, $result );
                }
 
index 654b189..36f49e0 100644 (file)
 use Psr\Log\LoggerAwareInterface;
 use Psr\Log\LoggerInterface;
 use Psr\Log\NullLogger;
+use MediaWiki\MediaWikiServices;
 
 /**
- * Class to handle concurrent HTTP requests
+ * Class to handle multiple HTTP requests
+ *
+ * If curl is available, requests will be made concurrently.
+ * Otherwise, they will be made serially.
  *
  * HTTP request maps are arrays that use the following format:
  *   - method   : GET/HEAD/PUT/POST/DELETE
@@ -50,9 +54,9 @@ class MultiHttpClient implements LoggerAwareInterface {
        protected $multiHandle = null; // curl_multi handle
        /** @var string|null SSL certificates path */
        protected $caBundlePath;
-       /** @var int */
+       /** @var float */
        protected $connTimeout = 10;
-       /** @var int */
+       /** @var float */
        protected $reqTimeout = 300;
        /** @var bool */
        protected $usePipelining = false;
@@ -65,6 +69,11 @@ class MultiHttpClient implements LoggerAwareInterface {
        /** @var LoggerInterface */
        protected $logger;
 
+       // In PHP 7 due to https://bugs.php.net/bug.php?id=76480 the request/connect
+       // timeouts are periodically polled instead of being accurately respected.
+       // The select timeout is set to the minimum timeout multiplied by this factor.
+       const TIMEOUT_ACCURACY_FACTOR = 0.1;
+
        /**
         * @param array $options
         *   - connTimeout     : default connection timeout (seconds)
@@ -73,6 +82,8 @@ class MultiHttpClient implements LoggerAwareInterface {
         *   - usePipelining   : whether to use HTTP pipelining if possible (for all hosts)
         *   - maxConnsPerHost : maximum number of concurrent connections (per host)
         *   - userAgent       : The User-Agent header value to send
+        *   - logger          : a \Psr\Log\LoggerInterface instance for debug logging
+        *   - caBundlePath    : path to specific Certificate Authority bundle (if any)
         * @throws Exception
         */
        public function __construct( array $options ) {
@@ -100,11 +111,11 @@ class MultiHttpClient implements LoggerAwareInterface {
         * Execute an HTTP(S) request
         *
         * This method returns a response map of:
-        *   - code    : HTTP response code or 0 if there was a serious cURL error
-        *   - reason  : HTTP response reason (empty if there was a serious cURL error)
+        *   - code    : HTTP response code or 0 if there was a serious error
+        *   - reason  : HTTP response reason (empty if there was a serious error)
         *   - headers : <header name/value associative array>
         *   - body    : HTTP response body or resource (if "stream" was set)
-        *   - error     : Any cURL error string
+        *   - error     : Any error string
         * The map also stores integer-indexed copies of these values. This lets callers do:
         * @code
         *              list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $http->run( $req );
@@ -120,14 +131,17 @@ class MultiHttpClient implements LoggerAwareInterface {
        }
 
        /**
-        * Execute a set of HTTP(S) requests concurrently
+        * Execute a set of HTTP(S) requests.
+        *
+        * If curl is available, requests will be made concurrently.
+        * Otherwise, they will be made serially.
         *
         * The maps are returned by this method with the 'response' field set to a map of:
-        *   - code    : HTTP response code or 0 if there was a serious cURL error
-        *   - reason  : HTTP response reason (empty if there was a serious cURL error)
+        *   - code    : HTTP response code or 0 if there was a serious error
+        *   - reason  : HTTP response reason (empty if there was a serious error)
         *   - headers : <header name/value associative array>
         *   - body    : HTTP response body or resource (if "stream" was set)
-        *   - error   : Any cURL error string
+        *   - error   : Any error string
         * The map also stores integer-indexed copies of these values. This lets callers do:
         * @code
         *        list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $req['response'];
@@ -146,45 +160,45 @@ class MultiHttpClient implements LoggerAwareInterface {
         * @throws Exception
         */
        public function runMulti( array $reqs, array $opts = [] ) {
+               $this->normalizeRequests( $reqs );
+               if ( $this->isCurlEnabled() ) {
+                       return $this->runMultiCurl( $reqs, $opts );
+               } else {
+                       return $this->runMultiHttp( $reqs, $opts );
+               }
+       }
+
+       /**
+        * Determines if the curl extension is available
+        *
+        * @return bool true if curl is available, false otherwise.
+        */
+       protected function isCurlEnabled() {
+               return extension_loaded( 'curl' );
+       }
+
+       /**
+        * Execute a set of HTTP(S) requests concurrently
+        *
+        * @see MultiHttpClient::runMulti()
+        *
+        * @param array $reqs Map of HTTP request arrays
+        * @param array $opts
+        *   - connTimeout     : connection timeout per request (seconds)
+        *   - reqTimeout      : post-connection timeout per request (seconds)
+        *   - usePipelining   : whether to use HTTP pipelining if possible
+        *   - maxConnsPerHost : maximum number of concurrent connections (per host)
+        * @return array $reqs With response array populated for each
+        * @throws Exception
+        */
+       private function runMultiCurl( array $reqs, array $opts = [] ) {
                $chm = $this->getCurlMulti();
 
-               // Normalize $reqs and add all of the required cURL handles...
+               $selectTimeout = $this->getSelectTimeout( $opts );
+
+               // Add all of the required cURL handles...
                $handles = [];
                foreach ( $reqs as $index => &$req ) {
-                       $req['response'] = [
-                               'code'     => 0,
-                               'reason'   => '',
-                               'headers'  => [],
-                               'body'     => '',
-                               'error'    => ''
-                       ];
-                       if ( isset( $req[0] ) ) {
-                               $req['method'] = $req[0]; // short-form
-                               unset( $req[0] );
-                       }
-                       if ( isset( $req[1] ) ) {
-                               $req['url'] = $req[1]; // short-form
-                               unset( $req[1] );
-                       }
-                       if ( !isset( $req['method'] ) ) {
-                               throw new Exception( "Request has no 'method' field set." );
-                       } elseif ( !isset( $req['url'] ) ) {
-                               throw new Exception( "Request has no 'url' field set." );
-                       }
-                       $this->logger->debug( "{$req['method']}: {$req['url']}" );
-                       $req['query'] = isset( $req['query'] ) ? $req['query'] : [];
-                       $headers = []; // normalized headers
-                       if ( isset( $req['headers'] ) ) {
-                               foreach ( $req['headers'] as $name => $value ) {
-                                       $headers[strtolower( $name )] = $value;
-                               }
-                       }
-                       $req['headers'] = $headers;
-                       if ( !isset( $req['body'] ) ) {
-                               $req['body'] = '';
-                               $req['headers']['content-length'] = 0;
-                       }
-                       $req['flags'] = isset( $req['flags'] ) ? $req['flags'] : [];
                        $handles[$index] = $this->getCurlHandle( $req, $opts );
                        if ( count( $reqs ) > 1 ) {
                                // https://github.com/guzzle/guzzle/issues/349
@@ -224,7 +238,7 @@ 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, 10 ) == -1 ) {
+                                       if ( curl_multi_select( $chm, $selectTimeout ) == -1 ) {
                                                // PHP bug 63411; https://curl.haxx.se/libcurl/c/curl_multi_fdset.html
                                                usleep( 5000 ); // 5ms
                                        }
@@ -285,11 +299,11 @@ class MultiHttpClient implements LoggerAwareInterface {
        protected function getCurlHandle( array &$req, array $opts = [] ) {
                $ch = curl_init();
 
-               curl_setopt( $ch, CURLOPT_CONNECTTIMEOUT,
-                       isset( $opts['connTimeout'] ) ? $opts['connTimeout'] : $this->connTimeout );
-               curl_setopt( $ch, CURLOPT_PROXY, isset( $req['proxy'] ) ? $req['proxy'] : $this->proxy );
-               curl_setopt( $ch, CURLOPT_TIMEOUT,
-                       isset( $opts['reqTimeout'] ) ? $opts['reqTimeout'] : $this->reqTimeout );
+               curl_setopt( $ch, CURLOPT_CONNECTTIMEOUT_MS,
+                       ( $opts['connTimeout'] ?? $this->connTimeout ) * 1000 );
+               curl_setopt( $ch, CURLOPT_PROXY, $req['proxy'] ?? $this->proxy );
+               curl_setopt( $ch, CURLOPT_TIMEOUT_MS,
+                       ( $opts['reqTimeout'] ?? $this->reqTimeout ) * 1000 );
                curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, 1 );
                curl_setopt( $ch, CURLOPT_MAXREDIRS, 4 );
                curl_setopt( $ch, CURLOPT_HEADER, 0 );
@@ -346,16 +360,7 @@ class MultiHttpClient implements LoggerAwareInterface {
                        // Don't interpret POST parameters starting with '@' as file uploads, because this
                        // makes it impossible to POST plain values starting with '@' (and causes security
                        // issues potentially exposing the contents of local files).
-                       // The PHP manual says this option was introduced in PHP 5.5 defaults to true in PHP 5.6,
-                       // but we support lower versions, and the option doesn't exist in HHVM 5.6.99.
-                       if ( defined( 'CURLOPT_SAFE_UPLOAD' ) ) {
-                               curl_setopt( $ch, CURLOPT_SAFE_UPLOAD, true );
-                       } elseif ( is_array( $req['body'] ) ) {
-                               // In PHP 5.2 and later, '@' is interpreted as a file upload if POSTFIELDS
-                               // is an array, but not if it's a string. So convert $req['body'] to a string
-                               // for safety.
-                               $req['body'] = http_build_query( $req['body'] );
-                       }
+                       curl_setopt( $ch, CURLOPT_SAFE_UPLOAD, true );
                        curl_setopt( $ch, CURLOPT_POSTFIELDS, $req['body'] );
                } else {
                        if ( is_resource( $req['body'] ) || $req['body'] !== '' ) {
@@ -393,7 +398,13 @@ class MultiHttpClient implements LoggerAwareInterface {
                                        return $length;
                                }
                                list( $name, $value ) = explode( ":", $header, 2 );
-                               $req['response']['headers'][strtolower( $name )] = trim( $value );
+                               $name = strtolower( $name );
+                               $value = trim( $value );
+                               if ( isset( $req['response']['headers'][$name] ) ) {
+                                       $req['response']['headers'][$name] .= ', ' . $value;
+                               } else {
+                                       $req['response']['headers'][$name] = $value;
+                               }
                                return $length;
                        }
                );
@@ -426,7 +437,7 @@ class MultiHttpClient implements LoggerAwareInterface {
        protected function getCurlMulti() {
                if ( !$this->multiHandle ) {
                        if ( !function_exists( 'curl_multi_init' ) ) {
-                               throw new Exception( "PHP cURL extension missing. " .
+                               throw new Exception( "PHP cURL function curl_multi_init missing. " .
                                                                         "Check https://www.mediawiki.org/wiki/Manual:CURL" );
                        }
                        $cmh = curl_multi_init();
@@ -437,6 +448,152 @@ class MultiHttpClient implements LoggerAwareInterface {
                return $this->multiHandle;
        }
 
+       /**
+        * Execute a set of HTTP(S) requests sequentially.
+        *
+        * @see MultiHttpClient::runMulti()
+        * @todo Remove dependency on MediaWikiServices: use a separate HTTP client
+        *  library or copy code from PhpHttpRequest
+        * @param array $reqs Map of HTTP request arrays
+        * @param array $opts
+        *   - connTimeout     : connection timeout per request (seconds)
+        *   - reqTimeout      : post-connection timeout per request (seconds)
+        * @return array $reqs With response array populated for each
+        * @throws Exception
+        */
+       private function runMultiHttp( array $reqs, array $opts = [] ) {
+               $httpOptions = [
+                       'timeout' => $opts['reqTimeout'] ?? $this->reqTimeout,
+                       'connectTimeout' => $opts['connTimeout'] ?? $this->connTimeout,
+                       'logger' => $this->logger,
+                       'caInfo' => $this->caBundlePath,
+               ];
+               foreach ( $reqs as &$req ) {
+                       $reqOptions = $httpOptions + [
+                               'method' => $req['method'],
+                               'proxy' => $req['proxy'] ?? $this->proxy,
+                               'userAgent' => $req['headers']['user-agent'] ?? $this->userAgent,
+                               'postData' => $req['body'],
+                       ];
+
+                       $url = $req['url'];
+                       $query = http_build_query( $req['query'], '', '&', PHP_QUERY_RFC3986 );
+                       if ( $query != '' ) {
+                               $url .= strpos( $req['url'], '?' ) === false ? "?$query" : "&$query";
+                       }
+
+                       $httpRequest = MediaWikiServices::getInstance()->getHttpRequestFactory()->create(
+                               $url, $reqOptions );
+                       $sv = $httpRequest->execute()->getStatusValue();
+
+                       $respHeaders = array_map(
+                               function ( $v ) {
+                                       return implode( ', ', $v );
+                               },
+                               $httpRequest->getResponseHeaders() );
+
+                       $req['response'] = [
+                               'code' => $httpRequest->getStatus(),
+                               'reason' => '',
+                               'headers' => $respHeaders,
+                               'body' => $httpRequest->getContent(),
+                               'error' => '',
+                       ];
+
+                       if ( !$sv->isOk() ) {
+                               $svErrors = $sv->getErrors();
+                               if ( isset( $svErrors[0] ) ) {
+                                       $req['response']['error'] = $svErrors[0]['message'];
+
+                                       // param values vary per failure type (ex. unknown host vs unknown page)
+                                       if ( isset( $svErrors[0]['params'][0] ) ) {
+                                               if ( is_numeric( $svErrors[0]['params'][0] ) ) {
+                                                       if ( isset( $svErrors[0]['params'][1] ) ) {
+                                                               $req['response']['reason'] = $svErrors[0]['params'][1];
+                                                       }
+                                               } else {
+                                                       $req['response']['reason'] = $svErrors[0]['params'][0];
+                                               }
+                                       }
+                               }
+                       }
+
+                       $req['response'][0] = $req['response']['code'];
+                       $req['response'][1] = $req['response']['reason'];
+                       $req['response'][2] = $req['response']['headers'];
+                       $req['response'][3] = $req['response']['body'];
+                       $req['response'][4] = $req['response']['error'];
+               }
+
+               return $reqs;
+       }
+
+       /**
+        * Normalize request information
+        *
+        * @param array $reqs the requests to normalize
+        */
+       private function normalizeRequests( array &$reqs ) {
+               foreach ( $reqs as &$req ) {
+                       $req['response'] = [
+                               'code'     => 0,
+                               'reason'   => '',
+                               'headers'  => [],
+                               'body'     => '',
+                               'error'    => ''
+                       ];
+                       if ( isset( $req[0] ) ) {
+                               $req['method'] = $req[0]; // short-form
+                               unset( $req[0] );
+                       }
+                       if ( isset( $req[1] ) ) {
+                               $req['url'] = $req[1]; // short-form
+                               unset( $req[1] );
+                       }
+                       if ( !isset( $req['method'] ) ) {
+                               throw new Exception( "Request has no 'method' field set." );
+                       } elseif ( !isset( $req['url'] ) ) {
+                               throw new Exception( "Request has no 'url' field set." );
+                       }
+                       $this->logger->debug( "{$req['method']}: {$req['url']}" );
+                       $req['query'] = $req['query'] ?? [];
+                       $headers = []; // normalized headers
+                       if ( isset( $req['headers'] ) ) {
+                               foreach ( $req['headers'] as $name => $value ) {
+                                       $headers[strtolower( $name )] = $value;
+                               }
+                       }
+                       $req['headers'] = $headers;
+                       if ( !isset( $req['body'] ) ) {
+                               $req['body'] = '';
+                               $req['headers']['content-length'] = 0;
+                       }
+                       $req['flags'] = $req['flags'] ?? [];
+               }
+       }
+
+       /**
+        * Get a suitable select timeout for the given options.
+        *
+        * @param array $opts
+        * @return float
+        */
+       private function getSelectTimeout( $opts ) {
+               $connTimeout = $opts['connTimeout'] ?? $this->connTimeout;
+               $reqTimeout = $opts['reqTimeout'] ?? $this->reqTimeout;
+               $timeouts = array_filter( [ $connTimeout, $reqTimeout ] );
+               if ( count( $timeouts ) === 0 ) {
+                       return 1;
+               }
+
+               $selectTimeout = min( $timeouts ) * self::TIMEOUT_ACCURACY_FACTOR;
+               // Minimum 10us for sanity
+               if ( $selectTimeout < 10e-6 ) {
+                       $selectTimeout = 10e-6;
+               }
+               return $selectTimeout;
+       }
+
        /**
         * Register a logger
         *
index b374259..f0cd83e 100644 (file)
@@ -20,7 +20,6 @@
  * @file
  * @ingroup Cache
  */
-use Wikimedia\Assert\Assert;
 
 /**
  * Class for process caching individual properties of expiring items
@@ -28,22 +27,18 @@ use Wikimedia\Assert\Assert;
  * When the key for an entire item is deleted, all properties for it are deleted
  *
  * @ingroup Cache
+ * @deprecated Since 1.32 Use MapCacheLRU instead
  */
 class ProcessCacheLRU {
-       /** @var array */
-       protected $cache = []; // (key => prop => value)
-
-       /** @var array */
-       protected $cacheTimes = []; // (key => prop => UNIX timestamp)
-
-       protected $maxCacheKeys; // integer; max entries
+       /** @var MapCacheLRU */
+       protected $cache;
 
        /**
         * @param int $maxKeys Maximum number of entries allowed (min 1).
         * @throws UnexpectedValueException When $maxCacheKeys is not an int or =< 0.
         */
        public function __construct( $maxKeys ) {
-               $this->resize( $maxKeys );
+               $this->cache = new MapCacheLRU( $maxKeys );
        }
 
        /**
@@ -57,16 +52,7 @@ class ProcessCacheLRU {
         * @return void
         */
        public function set( $key, $prop, $value ) {
-               if ( isset( $this->cache[$key] ) ) {
-                       $this->ping( $key );
-               } elseif ( count( $this->cache ) >= $this->maxCacheKeys ) {
-                       reset( $this->cache );
-                       $evictKey = key( $this->cache );
-                       unset( $this->cache[$evictKey] );
-                       unset( $this->cacheTimes[$evictKey] );
-               }
-               $this->cache[$key][$prop] = $value;
-               $this->cacheTimes[$key][$prop] = microtime( true );
+               $this->cache->setField( $key, $prop, $value );
        }
 
        /**
@@ -78,13 +64,7 @@ class ProcessCacheLRU {
         * @return bool
         */
        public function has( $key, $prop, $maxAge = 0.0 ) {
-               if ( isset( $this->cache[$key][$prop] ) ) {
-                       return ( $maxAge <= 0 ||
-                               ( microtime( true ) - $this->cacheTimes[$key][$prop] ) <= $maxAge
-                       );
-               }
-
-               return false;
+               return $this->cache->hasField( $key, $prop, $maxAge );
        }
 
        /**
@@ -97,29 +77,17 @@ class ProcessCacheLRU {
         * @return mixed
         */
        public function get( $key, $prop ) {
-               if ( !isset( $this->cache[$key][$prop] ) ) {
-                       return null;
-               }
-               $this->ping( $key );
-               return $this->cache[$key][$prop];
+               return $this->cache->getField( $key, $prop );
        }
 
        /**
         * Clear one or several cache entries, or all cache entries.
         *
-        * @param string|array $keys
+        * @param string|array|null $keys
         * @return void
         */
        public function clear( $keys = null ) {
-               if ( $keys === null ) {
-                       $this->cache = [];
-                       $this->cacheTimes = [];
-               } else {
-                       foreach ( (array)$keys as $key ) {
-                               unset( $this->cache[$key] );
-                               unset( $this->cacheTimes[$key] );
-                       }
-               }
+               $this->cache->clear( $keys );
        }
 
        /**
@@ -130,27 +98,7 @@ class ProcessCacheLRU {
         * @throws UnexpectedValueException
         */
        public function resize( $maxKeys ) {
-               Assert::parameterType( 'integer', $maxKeys, '$maxKeys' );
-               Assert::parameter( $maxKeys > 0, '$maxKeys', 'must be above zero' );
-
-               $this->maxCacheKeys = $maxKeys;
-               while ( count( $this->cache ) > $this->maxCacheKeys ) {
-                       reset( $this->cache );
-                       $evictKey = key( $this->cache );
-                       unset( $this->cache[$evictKey] );
-                       unset( $this->cacheTimes[$evictKey] );
-               }
-       }
-
-       /**
-        * Push an entry to the top of the cache
-        *
-        * @param string $key
-        */
-       protected function ping( $key ) {
-               $item = $this->cache[$key];
-               unset( $this->cache[$key] );
-               $this->cache[$key] = $item;
+               $this->cache->setMaxSize( $maxKeys );
        }
 
        /**
@@ -158,6 +106,6 @@ class ProcessCacheLRU {
         * @return int
         */
        public function getSize() {
-               return $this->maxCacheKeys;
+               return $this->cache->getMaxSize();
        }
 }
index 6f348c2..16cb1ed 100644 (file)
@@ -68,14 +68,14 @@ class StatusValue {
        public static function newFatal( $message /*, parameters...*/ ) {
                $params = func_get_args();
                $result = new static();
-               call_user_func_array( [ &$result, 'fatal' ], $params );
+               $result->fatal( ...$params );
                return $result;
        }
 
        /**
         * Factory function for good results
         *
-        * @param mixed $value
+        * @param mixed|null $value
         * @return static
         */
        public static function newGood( $value = null ) {
@@ -162,7 +162,7 @@ class StatusValue {
         * Change operation result
         *
         * @param bool $ok Whether the operation completed
-        * @param mixed $value
+        * @param mixed|null $value
         */
        public function setResult( $ok, $value = null ) {
                $this->ok = (bool)$ok;
index 7915ccf..51d1081 100644 (file)
@@ -206,7 +206,7 @@ class StringUtils {
                        } elseif ( $tokenType == 'end' ) {
                                if ( $foundStart ) {
                                        # Found match
-                                       $output .= call_user_func( $callback, [
+                                       $output .= $callback( [
                                                substr( $subject, $outputPos, $tokenOffset + $tokenLength - $outputPos ),
                                                substr( $subject, $contentPos, $tokenOffset - $contentPos )
                                        ] );
@@ -243,10 +243,13 @@ class StringUtils {
         * @return string The string with the matches replaced
         */
        static function delimiterReplace( $startDelim, $endDelim, $replace, $subject, $flags = '' ) {
-               $replacer = new RegexlikeReplacer( $replace );
-
-               return self::delimiterReplaceCallback( $startDelim, $endDelim,
-                       $replacer->cb(), $subject, $flags );
+               return self::delimiterReplaceCallback(
+                       $startDelim, $endDelim,
+                       function ( array $matches ) use ( $replace ) {
+                               return strtr( $replace, [ '$0' => $matches[0], '$1' => $matches[1] ] );
+                       },
+                       $subject, $flags
+               );
        }
 
        /**
@@ -263,8 +266,13 @@ class StringUtils {
                $text = str_replace( $placeholder, '', $text );
 
                // Replace instances of the separator inside HTML-like tags with the placeholder
-               $replacer = new DoubleReplacer( $separator, $placeholder );
-               $cleaned = self::delimiterReplaceCallback( '<', '>', $replacer->cb(), $text );
+               $cleaned = self::delimiterReplaceCallback(
+                       '<', '>',
+                       function ( array $matches ) use ( $separator, $placeholder ) {
+                               return str_replace( $separator, $placeholder, $matches[0] );
+                       },
+                       $text
+               );
 
                // Explode, then put the replaced separators back in
                $items = explode( $separator, $cleaned );
@@ -290,8 +298,13 @@ class StringUtils {
                $text = str_replace( $placeholder, '', $text );
 
                // Replace instances of the separator inside HTML-like tags with the placeholder
-               $replacer = new DoubleReplacer( $search, $placeholder );
-               $cleaned = self::delimiterReplaceCallback( '<', '>', $replacer->cb(), $text );
+               $cleaned = self::delimiterReplaceCallback(
+                       '<', '>',
+                       function ( array $matches ) use ( $search, $placeholder ) {
+                               return str_replace( $search, $placeholder, $matches[0] );
+                       },
+                       $text
+               );
 
                // Explode, then put the replaced separators back in
                $cleaned = str_replace( $search, $replace, $cleaned );
index 7b1a914..65a9247 100644 (file)
@@ -52,7 +52,7 @@ class Timing implements LoggerAwareInterface {
 
        public function __construct( array $params = [] ) {
                $this->clearMarks();
-               $this->setLogger( isset( $params['logger'] ) ? $params['logger'] : new NullLogger() );
+               $this->setLogger( $params['logger'] ?? new NullLogger() );
        }
 
        /**
@@ -83,7 +83,7 @@ class Timing implements LoggerAwareInterface {
        }
 
        /**
-        * @param string $markName The name of the mark that should
+        * @param string|null $markName The name of the mark that should
         *  be cleared. If not specified, all marks will be cleared.
         */
        public function clearMarks( $markName = null ) {
@@ -117,7 +117,7 @@ class Timing implements LoggerAwareInterface {
         *
         * @param string $measureName
         * @param string $startMark
-        * @param string $endMark
+        * @param string|null $endMark
         * @return array|bool The measure that has been created, or false if either
         *  the start mark or the end mark do not exist.
         */
@@ -155,7 +155,7 @@ class Timing implements LoggerAwareInterface {
         */
        private function sortEntries() {
                uasort( $this->entries, function ( $a, $b ) {
-                       return 10000 * ( $a['startTime'] - $b['startTime'] );
+                       return $a['startTime'] <=> $b['startTime'];
                } );
        }
 
@@ -188,6 +188,6 @@ class Timing implements LoggerAwareInterface {
         * @return array|null Entry named $name or null if it does not exist.
         */
        public function getEntryByName( $name ) {
-               return isset( $this->entries[$name] ) ? $this->entries[$name] : null;
+               return $this->entries[$name] ?? null;
        }
 }
index 7fad882..7532ce7 100644 (file)
@@ -54,7 +54,7 @@ class UDPTransport {
                        // IPv6 bracketed host
                        $host = $m[1];
                        $port = intval( $m[2] );
-                       $prefix = isset( $m[3] ) ? $m[3] : false;
+                       $prefix = $m[3] ?? false;
                        $domain = AF_INET6;
                } elseif ( preg_match( '!^udp:(?://)?([a-zA-Z0-9.-]+):(\d+)(?:/(.*))?$!', $info, $m ) ) {
                        $host = $m[1];
@@ -62,7 +62,7 @@ class UDPTransport {
                                $host = gethostbyname( $host );
                        }
                        $port = intval( $m[2] );
-                       $prefix = isset( $m[3] ) ? $m[3] : false;
+                       $prefix = $m[3] ?? false;
                        $domain = AF_INET;
                } else {
                        throw new InvalidArgumentException( __METHOD__ . ': Invalid UDP specification' );
index e58d98f..8175427 100644 (file)
@@ -54,13 +54,14 @@ class Xhprof {
                        throw new Exception( 'Profiling is already enabled.' );
                }
                self::$enabled = true;
-               if ( function_exists( 'xhprof_enable' ) ) {
-                       xhprof_enable( $flags, $options );
-               } elseif ( function_exists( 'tideways_enable' ) ) {
-                       tideways_enable( $flags, $options );
-               } else {
-                       throw new Exception( "Neither xhprof nor tideways are installed" );
-               }
+               self::callAny(
+                       [
+                               'xhprof_enable',
+                               'tideways_enable',
+                               'tideways_xhprof_enable'
+                       ],
+                       [ $flags, $options ]
+               );
        }
 
        /**
@@ -71,12 +72,27 @@ class Xhprof {
        public static function disable() {
                if ( self::isEnabled() ) {
                        self::$enabled = false;
-                       if ( function_exists( 'xhprof_disable' ) ) {
-                               return xhprof_disable();
-                       } else {
-                               // tideways
-                               return tideways_disable();
+                       return self::callAny( [
+                               'xhprof_disable',
+                               'tideways_disable',
+                               'tideways_xhprof_disable'
+                       ] );
+               }
+       }
+
+       /**
+        * Call the first available function from $functions.
+        * @param array $functions
+        * @param array $args
+        * @throws Exception
+        */
+       protected static function callAny( array $functions, array $args = [] ) {
+               foreach ( $functions as $func ) {
+                       if ( function_exists( $func ) ) {
+                               return $func( ...$args );
                        }
                }
+
+               throw new Exception( "Neither xhprof nor tideways are installed" );
        }
 }
index 5af22ed..90e52f0 100644 (file)
@@ -370,11 +370,10 @@ class XhprofData {
                return function ( $a, $b ) use ( $key, $sub ) {
                        if ( isset( $a[$key] ) && isset( $b[$key] ) ) {
                                // Descending sort: larger values will be first in result.
-                               // Assumes all values are numeric.
                                // Values for 'main()' will not have sub keys
                                $valA = is_array( $a[$key] ) ? $a[$key][$sub] : $a[$key];
                                $valB = is_array( $b[$key] ) ? $b[$key][$sub] : $b[$key];
-                               return $valB - $valA;
+                               return $valB <=> $valA;
                        } else {
                                // Sort datum with the key before those without
                                return isset( $a[$key] ) ? -1 : 1;
index ef2b768..54d43d3 100644 (file)
@@ -26,9 +26,9 @@ class ComposerInstalled {
                        $deps[$installed['name']] = [
                                'version' => ComposerJson::normalizeVersion( $installed['version'] ),
                                'type' => $installed['type'],
-                               'licenses' => isset( $installed['license'] ) ? $installed['license'] : [],
-                               'authors' => isset( $installed['authors'] ) ? $installed['authors'] : [],
-                               'description' => isset( $installed['description'] ) ? $installed['description'] : '',
+                               'licenses' => $installed['license'] ?? [],
+                               'authors' => $installed['authors'] ?? [],
+                               'description' => $installed['description'] ?? '',
                        ];
                }
 
index dc8bc03..c5b5f00 100644 (file)
@@ -26,9 +26,9 @@ class ComposerLock {
                        $deps[$installed['name']] = [
                                'version' => ComposerJson::normalizeVersion( $installed['version'] ),
                                'type' => $installed['type'],
-                               'licenses' => isset( $installed['license'] ) ? $installed['license'] : [],
-                               'authors' => isset( $installed['authors'] ) ? $installed['authors'] : [],
-                               'description' => isset( $installed['description'] ) ? $installed['description'] : '',
+                               'licenses' => $installed['license'] ?? [],
+                               'authors' => $installed['authors'] ?? [],
+                               'description' => $installed['description'] ?? '',
                        ];
                }
 
index d60e768..c2c3b47 100644 (file)
@@ -89,8 +89,8 @@ class FSFileBackend extends FileBackendStore {
                        }
                }
 
-               $this->fileMode = isset( $config['fileMode'] ) ? $config['fileMode'] : 0644;
-               $this->dirMode = isset( $config['directoryMode'] ) ? $config['directoryMode'] : 0777;
+               $this->fileMode = $config['fileMode'] ?? 0644;
+               $this->dirMode = $config['directoryMode'] ?? 0777;
                if ( isset( $config['fileOwner'] ) && function_exists( 'posix_getuid' ) ) {
                        $this->fileOwner = $config['fileOwner'];
                        // cache this, assuming it doesn't change
index 08f960a..6d5efa2 100644 (file)
@@ -170,12 +170,9 @@ abstract class FileBackend implements LoggerAwareInterface {
                        throw new InvalidArgumentException(
                                "Backend domain ID not provided for '{$this->name}'." );
                }
-               $this->lockManager = isset( $config['lockManager'] )
-                       ? $config['lockManager']
-                       : new NullLockManager( [] );
-               $this->fileJournal = isset( $config['fileJournal'] )
-                       ? $config['fileJournal']
-                       : FileJournal::factory( [ 'class' => NullFileJournal::class ], $this->name );
+               $this->lockManager = $config['lockManager'] ?? new NullLockManager( [] );
+               $this->fileJournal = $config['fileJournal']
+                       ?? FileJournal::factory( [ 'class' => NullFileJournal::class ], $this->name );
                $this->readOnly = isset( $config['readOnly'] )
                        ? (string)$config['readOnly']
                        : '';
@@ -185,18 +182,14 @@ abstract class FileBackend implements LoggerAwareInterface {
                $this->concurrency = isset( $config['concurrency'] )
                        ? (int)$config['concurrency']
                        : 50;
-               $this->obResetFunc = isset( $config['obResetFunc'] )
-                       ? $config['obResetFunc']
-                       : [ $this, 'resetOutputBuffer' ];
-               $this->streamMimeFunc = isset( $config['streamMimeFunc'] )
-                       ? $config['streamMimeFunc']
-                       : null;
-               $this->statusWrapper = isset( $config['statusWrapper'] ) ? $config['statusWrapper'] : null;
-
-               $this->profiler = isset( $config['profiler'] ) ? $config['profiler'] : null;
-               $this->logger = isset( $config['logger'] ) ? $config['logger'] : new \Psr\Log\NullLogger();
-               $this->statusWrapper = isset( $config['statusWrapper'] ) ? $config['statusWrapper'] : null;
-               $this->tmpDirectory = isset( $config['tmpDirectory'] ) ? $config['tmpDirectory'] : null;
+               $this->obResetFunc = $config['obResetFunc'] ?? [ $this, 'resetOutputBuffer' ];
+               $this->streamMimeFunc = $config['streamMimeFunc'] ?? null;
+               $this->statusWrapper = $config['statusWrapper'] ?? null;
+
+               $this->profiler = $config['profiler'] ?? null;
+               $this->logger = $config['logger'] ?? new \Psr\Log\NullLogger();
+               $this->statusWrapper = $config['statusWrapper'] ?? null;
+               $this->tmpDirectory = $config['tmpDirectory'] ?? null;
        }
 
        public function setLogger( LoggerInterface $logger ) {
@@ -1274,7 +1267,7 @@ abstract class FileBackend implements LoggerAwareInterface {
         *
         * @see FileBackend::getFileStat()
         *
-        * @param array $paths Storage paths (optional)
+        * @param array|null $paths Storage paths (optional)
         */
        abstract public function clearCache( array $paths = null );
 
@@ -1414,7 +1407,7 @@ abstract class FileBackend implements LoggerAwareInterface {
         */
        protected function resolveFSFileObjects( array $ops ) {
                foreach ( $ops as &$op ) {
-                       $src = isset( $op['src'] ) ? $op['src'] : null;
+                       $src = $op['src'] ?? null;
                        if ( $src instanceof FSFile ) {
                                $op['srcRef'] = $src;
                                $op['src'] = $src->getPath();
@@ -1597,7 +1590,7 @@ abstract class FileBackend implements LoggerAwareInterface {
        final protected function newStatus() {
                $args = func_get_args();
                if ( count( $args ) ) {
-                       $sv = call_user_func_array( [ StatusValue::class, 'newFatal' ], $args );
+                       $sv = StatusValue::newFatal( ...$args );
                } else {
                        $sv = StatusValue::newGood();
                }
index 9c367af..655a710 100644 (file)
@@ -95,12 +95,8 @@ class FileBackendMultiWrite extends FileBackend {
         */
        public function __construct( array $config ) {
                parent::__construct( $config );
-               $this->syncChecks = isset( $config['syncChecks'] )
-                       ? $config['syncChecks']
-                       : self::CHECK_SIZE;
-               $this->autoResync = isset( $config['autoResync'] )
-                       ? $config['autoResync']
-                       : false;
+               $this->syncChecks = $config['syncChecks'] ?? self::CHECK_SIZE;
+               $this->autoResync = $config['autoResync'] ?? false;
                $this->asyncWrites = isset( $config['replication'] ) && $config['replication'] === 'async';
                // Construct backends here rather than via registration
                // to keep these backends hidden from outside the proxy.
index 06b263a..e2d56b0 100644 (file)
@@ -40,9 +40,9 @@ abstract class FileBackendStore extends FileBackend {
        protected $memCache;
        /** @var BagOStuff */
        protected $srvCache;
-       /** @var ProcessCacheLRU Map of paths to small (RAM/disk) cache items */
+       /** @var MapCacheLRU Map of paths to small (RAM/disk) cache items */
        protected $cheapCache;
-       /** @var ProcessCacheLRU Map of paths to large (RAM/disk) cache items */
+       /** @var MapCacheLRU Map of paths to large (RAM/disk) cache items */
        protected $expensiveCache;
 
        /** @var array Map of container names to sharding config */
@@ -70,13 +70,11 @@ abstract class FileBackendStore extends FileBackend {
         */
        public function __construct( array $config ) {
                parent::__construct( $config );
-               $this->mimeCallback = isset( $config['mimeCallback'] )
-                       ? $config['mimeCallback']
-                       : null;
+               $this->mimeCallback = $config['mimeCallback'] ?? null;
                $this->srvCache = new EmptyBagOStuff(); // disabled by default
                $this->memCache = WANObjectCache::newEmpty(); // disabled by default
-               $this->cheapCache = new ProcessCacheLRU( self::CACHE_CHEAP_SIZE );
-               $this->expensiveCache = new ProcessCacheLRU( self::CACHE_EXPENSIVE_SIZE );
+               $this->cheapCache = new MapCacheLRU( self::CACHE_CHEAP_SIZE );
+               $this->expensiveCache = new MapCacheLRU( self::CACHE_EXPENSIVE_SIZE );
        }
 
        /**
@@ -629,11 +627,11 @@ abstract class FileBackendStore extends FileBackend {
                }
                $ps = $this->scopedProfileSection( __METHOD__ . "-{$this->name}" );
                $latest = !empty( $params['latest'] ); // use latest data?
-               if ( !$latest && !$this->cheapCache->has( $path, 'stat', self::CACHE_TTL ) ) {
+               if ( !$latest && !$this->cheapCache->hasField( $path, 'stat', self::CACHE_TTL ) ) {
                        $this->primeFileCache( [ $path ] ); // check persistent cache
                }
-               if ( $this->cheapCache->has( $path, 'stat', self::CACHE_TTL ) ) {
-                       $stat = $this->cheapCache->get( $path, 'stat' );
+               if ( $this->cheapCache->hasField( $path, 'stat', self::CACHE_TTL ) ) {
+                       $stat = $this->cheapCache->getField( $path, 'stat' );
                        // If we want the latest data, check that this cached
                        // value was in fact fetched with the latest available data.
                        if ( is_array( $stat ) ) {
@@ -649,22 +647,22 @@ abstract class FileBackendStore extends FileBackend {
                $stat = $this->doGetFileStat( $params );
                if ( is_array( $stat ) ) { // file exists
                        // Strongly consistent backends can automatically set "latest"
-                       $stat['latest'] = isset( $stat['latest'] ) ? $stat['latest'] : $latest;
-                       $this->cheapCache->set( $path, 'stat', $stat );
+                       $stat['latest'] = $stat['latest'] ?? $latest;
+                       $this->cheapCache->setField( $path, 'stat', $stat );
                        $this->setFileCache( $path, $stat ); // update persistent cache
                        if ( isset( $stat['sha1'] ) ) { // some backends store SHA-1 as metadata
-                               $this->cheapCache->set( $path, 'sha1',
+                               $this->cheapCache->setField( $path, 'sha1',
                                        [ 'hash' => $stat['sha1'], 'latest' => $latest ] );
                        }
                        if ( isset( $stat['xattr'] ) ) { // some backends store headers/metadata
                                $stat['xattr'] = self::normalizeXAttributes( $stat['xattr'] );
-                               $this->cheapCache->set( $path, 'xattr',
+                               $this->cheapCache->setField( $path, 'xattr',
                                        [ 'map' => $stat['xattr'], 'latest' => $latest ] );
                        }
                } elseif ( $stat === false ) { // file does not exist
-                       $this->cheapCache->set( $path, 'stat', $latest ? 'NOT_EXIST_LATEST' : 'NOT_EXIST' );
-                       $this->cheapCache->set( $path, 'xattr', [ 'map' => false, 'latest' => $latest ] );
-                       $this->cheapCache->set( $path, 'sha1', [ 'hash' => false, 'latest' => $latest ] );
+                       $this->cheapCache->setField( $path, 'stat', $latest ? 'NOT_EXIST_LATEST' : 'NOT_EXIST' );
+                       $this->cheapCache->setField( $path, 'xattr', [ 'map' => false, 'latest' => $latest ] );
+                       $this->cheapCache->setField( $path, 'sha1', [ 'hash' => false, 'latest' => $latest ] );
                        $this->logger->debug( __METHOD__ . ": File $path does not exist.\n" );
                } else { // an error occurred
                        $this->logger->warning( __METHOD__ . ": Could not stat file $path.\n" );
@@ -711,8 +709,8 @@ abstract class FileBackendStore extends FileBackend {
                }
                $ps = $this->scopedProfileSection( __METHOD__ . "-{$this->name}" );
                $latest = !empty( $params['latest'] ); // use latest data?
-               if ( $this->cheapCache->has( $path, 'xattr', self::CACHE_TTL ) ) {
-                       $stat = $this->cheapCache->get( $path, 'xattr' );
+               if ( $this->cheapCache->hasField( $path, 'xattr', self::CACHE_TTL ) ) {
+                       $stat = $this->cheapCache->getField( $path, 'xattr' );
                        // If we want the latest data, check that this cached
                        // value was in fact fetched with the latest available data.
                        if ( !$latest || $stat['latest'] ) {
@@ -721,7 +719,7 @@ abstract class FileBackendStore extends FileBackend {
                }
                $fields = $this->doGetFileXAttributes( $params );
                $fields = is_array( $fields ) ? self::normalizeXAttributes( $fields ) : false;
-               $this->cheapCache->set( $path, 'xattr', [ 'map' => $fields, 'latest' => $latest ] );
+               $this->cheapCache->setField( $path, 'xattr', [ 'map' => $fields, 'latest' => $latest ] );
 
                return $fields;
        }
@@ -742,8 +740,8 @@ abstract class FileBackendStore extends FileBackend {
                }
                $ps = $this->scopedProfileSection( __METHOD__ . "-{$this->name}" );
                $latest = !empty( $params['latest'] ); // use latest data?
-               if ( $this->cheapCache->has( $path, 'sha1', self::CACHE_TTL ) ) {
-                       $stat = $this->cheapCache->get( $path, 'sha1' );
+               if ( $this->cheapCache->hasField( $path, 'sha1', self::CACHE_TTL ) ) {
+                       $stat = $this->cheapCache->getField( $path, 'sha1' );
                        // If we want the latest data, check that this cached
                        // value was in fact fetched with the latest available data.
                        if ( !$latest || $stat['latest'] ) {
@@ -751,7 +749,7 @@ abstract class FileBackendStore extends FileBackend {
                        }
                }
                $hash = $this->doGetFileSha1Base36( $params );
-               $this->cheapCache->set( $path, 'sha1', [ 'hash' => $hash, 'latest' => $latest ] );
+               $this->cheapCache->setField( $path, 'sha1', [ 'hash' => $hash, 'latest' => $latest ] );
 
                return $hash;
        }
@@ -790,8 +788,8 @@ abstract class FileBackendStore extends FileBackend {
                        $path = self::normalizeStoragePath( $src );
                        if ( $path === null ) {
                                $fsFiles[$src] = null; // invalid storage path
-                       } elseif ( $this->expensiveCache->has( $path, 'localRef' ) ) {
-                               $val = $this->expensiveCache->get( $path, 'localRef' );
+                       } elseif ( $this->expensiveCache->hasField( $path, 'localRef' ) ) {
+                               $val = $this->expensiveCache->getField( $path, 'localRef' );
                                // If we want the latest data, check that this cached
                                // value was in fact fetched with the latest available data.
                                if ( !$latest || $val['latest'] ) {
@@ -804,7 +802,7 @@ abstract class FileBackendStore extends FileBackend {
                foreach ( $this->doGetLocalReferenceMulti( $params ) as $path => $fsFile ) {
                        $fsFiles[$path] = $fsFile;
                        if ( $fsFile ) { // update the process cache...
-                               $this->expensiveCache->set( $path, 'localRef',
+                               $this->expensiveCache->setField( $path, 'localRef',
                                        [ 'object' => $fsFile, 'latest' => $latest ] );
                        }
                }
@@ -851,8 +849,8 @@ abstract class FileBackendStore extends FileBackend {
                $status = $this->newStatus();
 
                // Always set some fields for subclass convenience
-               $params['options'] = isset( $params['options'] ) ? $params['options'] : [];
-               $params['headers'] = isset( $params['headers'] ) ? $params['headers'] : [];
+               $params['options'] = $params['options'] ?? [];
+               $params['headers'] = $params['headers'] ?? [];
 
                // Don't stream it out as text/html if there was a PHP error
                if ( ( empty( $params['headless'] ) || $params['headers'] ) && headers_sent() ) {
@@ -1104,7 +1102,7 @@ abstract class FileBackendStore extends FileBackend {
                }
 
                // Enlarge the cache to fit the stat entries of these files
-               $this->cheapCache->resize( max( 2 * count( $paths ), self::CACHE_CHEAP_SIZE ) );
+               $this->cheapCache->setMaxSize( max( 2 * count( $paths ), self::CACHE_CHEAP_SIZE ) );
 
                // Load from the persistent container caches
                $this->primeContainerCache( $paths );
@@ -1131,7 +1129,7 @@ abstract class FileBackendStore extends FileBackend {
                $status->success = $subStatus->success; // not done in merge()
 
                // Shrink the stat cache back to normal size
-               $this->cheapCache->resize( self::CACHE_CHEAP_SIZE );
+               $this->cheapCache->setMaxSize( self::CACHE_CHEAP_SIZE );
 
                return $status;
        }
@@ -1301,7 +1299,7 @@ abstract class FileBackendStore extends FileBackend {
         *
         * @see FileBackend::clearCache()
         *
-        * @param array $paths Storage paths (optional)
+        * @param array|null $paths Storage paths (optional)
         */
        protected function doClearCache( array $paths = null ) {
        }
@@ -1324,24 +1322,24 @@ abstract class FileBackendStore extends FileBackend {
                        }
                        if ( is_array( $stat ) ) { // file exists
                                // Strongly consistent backends can automatically set "latest"
-                               $stat['latest'] = isset( $stat['latest'] ) ? $stat['latest'] : $latest;
-                               $this->cheapCache->set( $path, 'stat', $stat );
+                               $stat['latest'] = $stat['latest'] ?? $latest;
+                               $this->cheapCache->setField( $path, 'stat', $stat );
                                $this->setFileCache( $path, $stat ); // update persistent cache
                                if ( isset( $stat['sha1'] ) ) { // some backends store SHA-1 as metadata
-                                       $this->cheapCache->set( $path, 'sha1',
+                                       $this->cheapCache->setField( $path, 'sha1',
                                                [ 'hash' => $stat['sha1'], 'latest' => $latest ] );
                                }
                                if ( isset( $stat['xattr'] ) ) { // some backends store headers/metadata
                                        $stat['xattr'] = self::normalizeXAttributes( $stat['xattr'] );
-                                       $this->cheapCache->set( $path, 'xattr',
+                                       $this->cheapCache->setField( $path, 'xattr',
                                                [ 'map' => $stat['xattr'], 'latest' => $latest ] );
                                }
                        } elseif ( $stat === false ) { // file does not exist
-                               $this->cheapCache->set( $path, 'stat',
+                               $this->cheapCache->setField( $path, 'stat',
                                        $latest ? 'NOT_EXIST_LATEST' : 'NOT_EXIST' );
-                               $this->cheapCache->set( $path, 'xattr',
+                               $this->cheapCache->setField( $path, 'xattr',
                                        [ 'map' => false, 'latest' => $latest ] );
-                               $this->cheapCache->set( $path, 'sha1',
+                               $this->cheapCache->setField( $path, 'sha1',
                                        [ 'hash' => false, 'latest' => $latest ] );
                                $this->logger->debug( __METHOD__ . ": File $path does not exist.\n" );
                        } else { // an error occurred
@@ -1560,7 +1558,7 @@ abstract class FileBackendStore extends FileBackend {
                $shards = [];
                list( $digits, $base ) = $this->getContainerHashLevels( $container );
                if ( $digits > 0 ) {
-                       $numShards = pow( $base, $digits );
+                       $numShards = $base ** $digits;
                        for ( $index = 0; $index < $numShards; $index++ ) {
                                $shards[] = '.' . Wikimedia\base_convert( $index, 10, $base, $digits );
                        }
@@ -1771,14 +1769,14 @@ abstract class FileBackendStore extends FileBackend {
                        $path = $pathNames[$cacheKey];
                        if ( is_array( $val ) ) {
                                $val['latest'] = false; // never completely trust cache
-                               $this->cheapCache->set( $path, 'stat', $val );
+                               $this->cheapCache->setField( $path, 'stat', $val );
                                if ( isset( $val['sha1'] ) ) { // some backends store SHA-1 as metadata
-                                       $this->cheapCache->set( $path, 'sha1',
+                                       $this->cheapCache->setField( $path, 'sha1',
                                                [ 'hash' => $val['sha1'], 'latest' => false ] );
                                }
                                if ( isset( $val['xattr'] ) ) { // some backends store headers/metadata
                                        $val['xattr'] = self::normalizeXAttributes( $val['xattr'] );
-                                       $this->cheapCache->set( $path, 'xattr',
+                                       $this->cheapCache->setField( $path, 'xattr',
                                                [ 'map' => $val['xattr'], 'latest' => false ] );
                                }
                        }
index 2324098..540961e 100644 (file)
@@ -66,7 +66,7 @@ class FileOpBatch {
                $batchId = $journal->getTimestampedUUID();
                $ignoreErrors = !empty( $opts['force'] );
                $journaled = empty( $opts['nonJournaled'] );
-               $maxConcurrency = isset( $opts['concurrency'] ) ? $opts['concurrency'] : 1;
+               $maxConcurrency = $opts['concurrency'] ?? 1;
 
                $entries = []; // file journal entry list
                $predicates = FileOp::newPredicates(); // account for previous ops in prechecks
index 46cd6be..e161254 100644 (file)
@@ -47,12 +47,8 @@ class HTTPFileStreamer {
         */
        public function __construct( $path, array $params = [] ) {
                $this->path = $path;
-               $this->obResetFunc = isset( $params['obResetFunc'] )
-                       ? $params['obResetFunc']
-                       : [ __CLASS__, 'resetOutputBuffers' ];
-               $this->streamMimeFunc = isset( $params['streamMimeFunc'] )
-                       ? $params['streamMimeFunc']
-                       : [ __CLASS__, 'contentTypeFromPath' ];
+               $this->obResetFunc = $params['obResetFunc'] ?? [ __CLASS__, 'resetOutputBuffers' ];
+               $this->streamMimeFunc = $params['streamMimeFunc'] ?? [ __CLASS__, 'contentTypeFromPath' ];
        }
 
        /**
index 997974e..31882de 100644 (file)
@@ -116,24 +116,12 @@ class SwiftFileBackend extends FileBackendStore {
                $this->swiftUser = $config['swiftUser'];
                $this->swiftKey = $config['swiftKey'];
                // Optional settings
-               $this->authTTL = isset( $config['swiftAuthTTL'] )
-                       ? $config['swiftAuthTTL']
-                       : 15 * 60; // some sane number
-               $this->swiftTempUrlKey = isset( $config['swiftTempUrlKey'] )
-                       ? $config['swiftTempUrlKey']
-                       : '';
-               $this->swiftStorageUrl = isset( $config['swiftStorageUrl'] )
-                       ? $config['swiftStorageUrl']
-                       : null;
-               $this->shardViaHashLevels = isset( $config['shardViaHashLevels'] )
-                       ? $config['shardViaHashLevels']
-                       : '';
-               $this->rgwS3AccessKey = isset( $config['rgwS3AccessKey'] )
-                       ? $config['rgwS3AccessKey']
-                       : '';
-               $this->rgwS3SecretKey = isset( $config['rgwS3SecretKey'] )
-                       ? $config['rgwS3SecretKey']
-                       : '';
+               $this->authTTL = $config['swiftAuthTTL'] ?? 15 * 60; // some sane number
+               $this->swiftTempUrlKey = $config['swiftTempUrlKey'] ?? '';
+               $this->swiftStorageUrl = $config['swiftStorageUrl'] ?? null;
+               $this->shardViaHashLevels = $config['shardViaHashLevels'] ?? '';
+               $this->rgwS3AccessKey = $config['rgwS3AccessKey'] ?? '';
+               $this->rgwS3SecretKey = $config['rgwS3SecretKey'] ?? '';
                // HTTP helper client
                $this->http = new MultiHttpClient( [] );
                // Cache container information to mask latency
@@ -141,25 +129,17 @@ class SwiftFileBackend extends FileBackendStore {
                        $this->memCache = $config['wanCache'];
                }
                // Process cache for container info
-               $this->containerStatCache = new ProcessCacheLRU( 300 );
+               $this->containerStatCache = new MapCacheLRU( 300 );
                // Cache auth token information to avoid RTTs
                if ( !empty( $config['cacheAuthInfo'] ) && isset( $config['srvCache'] ) ) {
                        $this->srvCache = $config['srvCache'];
                } else {
                        $this->srvCache = new EmptyBagOStuff();
                }
-               $this->readUsers = isset( $config['readUsers'] )
-                       ? $config['readUsers']
-                       : [];
-               $this->writeUsers = isset( $config['writeUsers'] )
-                       ? $config['writeUsers']
-                       : [];
-               $this->secureReadUsers = isset( $config['secureReadUsers'] )
-                       ? $config['secureReadUsers']
-                       : [];
-               $this->secureWriteUsers = isset( $config['secureWriteUsers'] )
-                       ? $config['secureWriteUsers']
-                       : [];
+               $this->readUsers = $config['readUsers'] ?? [];
+               $this->writeUsers = $config['writeUsers'] ?? [];
+               $this->secureReadUsers = $config['secureReadUsers'] ?? [];
+               $this->secureWriteUsers = $config['secureWriteUsers'] ?? [];
        }
 
        public function getFeatures() {
@@ -299,9 +279,8 @@ class SwiftFileBackend extends FileBackendStore {
                }
 
                $sha1Hash = Wikimedia\base_convert( sha1( $params['content'] ), 16, 36, 31 );
-               $contentType = isset( $params['headers']['content-type'] )
-                       ? $params['headers']['content-type']
-                       : $this->getContentType( $params['dst'], $params['content'], null );
+               $contentType = $params['headers']['content-type']
+                       ?? $this->getContentType( $params['dst'], $params['content'], null );
 
                $reqs = [ [
                        'method' => 'PUT',
@@ -356,9 +335,8 @@ class SwiftFileBackend extends FileBackendStore {
                        return $status;
                }
                $sha1Hash = Wikimedia\base_convert( $sha1Hash, 16, 36, 31 );
-               $contentType = isset( $params['headers']['content-type'] )
-                       ? $params['headers']['content-type']
-                       : $this->getContentType( $params['dst'], null, $params['src'] );
+               $contentType = $params['headers']['content-type']
+                       ?? $this->getContentType( $params['dst'], null, $params['src'] );
 
                $handle = fopen( $params['src'], 'rb' );
                if ( $handle === false ) { // source doesn't exist?
@@ -1055,7 +1033,7 @@ class SwiftFileBackend extends FileBackendStore {
         * @param array $val Stat value
         */
        public function loadListingStatInternal( $path, array $val ) {
-               $this->cheapCache->set( $path, 'stat', $val );
+               $this->cheapCache->setField( $path, 'stat', $val );
        }
 
        protected function doGetFileXAttributes( array $params ) {
@@ -1125,7 +1103,7 @@ class SwiftFileBackend extends FileBackendStore {
 
                if ( empty( $params['allowOB'] ) ) {
                        // Cancel output buffering and gzipping if set
-                       call_user_func( $this->obResetFunc );
+                       ( $this->obResetFunc )();
                }
 
                $handle = fopen( 'php://output', 'wb' );
@@ -1210,7 +1188,7 @@ class SwiftFileBackend extends FileBackendStore {
                                // Set the file stat process cache in passing
                                $stat = $this->getStatFromHeaders( $rhdrs );
                                $stat['latest'] = $isLatest;
-                               $this->cheapCache->set( $path, 'stat', $stat );
+                               $this->cheapCache->setField( $path, 'stat', $stat );
                        } elseif ( $rcode === 404 ) {
                                $tmpFiles[$path] = false;
                        } else {
@@ -1237,7 +1215,7 @@ class SwiftFileBackend extends FileBackendStore {
                                return null;
                        }
 
-                       $ttl = isset( $params['ttl'] ) ? $params['ttl'] : 86400;
+                       $ttl = $params['ttl'] ?? 86400;
                        $expires = time() + $ttl;
 
                        if ( $this->swiftTempUrlKey != '' ) {
@@ -1325,7 +1303,7 @@ class SwiftFileBackend extends FileBackendStore {
                        foreach ( $reqs as $stage => &$req ) {
                                list( $container, $relPath ) = $req['url'];
                                $req['url'] = $this->storageUrl( $auth, $container, $relPath );
-                               $req['headers'] = isset( $req['headers'] ) ? $req['headers'] : [];
+                               $req['headers'] = $req['headers'] ?? [];
                                $req['headers'] = $this->authTokenHeaders( $auth ) + $req['headers'];
                                $httpReqsByStage[$stage][$index] = $req;
                        }
@@ -1339,7 +1317,7 @@ class SwiftFileBackend extends FileBackendStore {
                        foreach ( $httpReqs as $index => $httpReq ) {
                                // Run the callback for each request of this operation
                                $callback = $fileOpHandles[$index]->callback;
-                               call_user_func_array( $callback, [ $httpReq, $statuses[$index] ] );
+                               $callback( $httpReq, $statuses[$index] );
                                // On failure, abort all remaining requests for this operation
                                // (e.g. abort the DELETE request if the COPY request fails for a move)
                                if ( !$statuses[$index]->isOK() ) {
@@ -1417,10 +1395,10 @@ class SwiftFileBackend extends FileBackendStore {
 
                if ( $bypassCache ) { // purge cache
                        $this->containerStatCache->clear( $container );
-               } elseif ( !$this->containerStatCache->has( $container, 'stat' ) ) {
+               } elseif ( !$this->containerStatCache->hasField( $container, 'stat' ) ) {
                        $this->primeContainerCache( [ $container ] ); // check persistent cache
                }
-               if ( !$this->containerStatCache->has( $container, 'stat' ) ) {
+               if ( !$this->containerStatCache->hasField( $container, 'stat' ) ) {
                        $auth = $this->getAuthentication();
                        if ( !$auth ) {
                                return null;
@@ -1440,7 +1418,7 @@ class SwiftFileBackend extends FileBackendStore {
                                if ( $bypassCache ) {
                                        return $stat;
                                } else {
-                                       $this->containerStatCache->set( $container, 'stat', $stat ); // cache it
+                                       $this->containerStatCache->setField( $container, 'stat', $stat ); // cache it
                                        $this->setContainerCache( $container, $stat ); // update persistent cache
                                }
                        } elseif ( $rcode === 404 ) {
@@ -1453,7 +1431,7 @@ class SwiftFileBackend extends FileBackendStore {
                        }
                }
 
-               return $this->containerStatCache->get( $container, 'stat' );
+               return $this->containerStatCache->getField( $container, 'stat' );
        }
 
        /**
@@ -1605,7 +1583,7 @@ class SwiftFileBackend extends FileBackendStore {
 
        protected function doPrimeContainerCache( array $containerInfo ) {
                foreach ( $containerInfo as $container => $info ) {
-                       $this->containerStatCache->set( $container, 'stat', $info );
+                       $this->containerStatCache->setField( $container, 'stat', $info );
                }
        }
 
@@ -1686,7 +1664,7 @@ class SwiftFileBackend extends FileBackendStore {
                        'mtime' => $this->convertSwiftDate( $rhdrs['last-modified'], TS_MW ),
                        // Empty objects actually return no content-length header in Ceph
                        'size'  => isset( $rhdrs['content-length'] ) ? (int)$rhdrs['content-length'] : 0,
-                       'sha1'  => isset( $metadata['sha1base36'] ) ? $metadata['sha1base36'] : null,
+                       'sha1'  => $metadata['sha1base36'] ?? null,
                        // Note: manifiest ETags are not an MD5 of the file
                        'md5'   => ctype_xdigit( $rhdrs['etag'] ) ? $rhdrs['etag'] : null,
                        'xattr' => [ 'metadata' => $metadata, 'headers' => $headers ]
@@ -1759,8 +1737,8 @@ class SwiftFileBackend extends FileBackendStore {
 
        /**
         * @param array $creds From getAuthentication()
-        * @param string $container
-        * @param string $object
+        * @param string|null $container
+        * @param string|null $object
         * @return string
         */
        protected function storageUrl( array $creds, $container = null, $object = null ) {
index 5ba59c5..47be4eb 100644 (file)
@@ -48,7 +48,7 @@ abstract class FileJournal {
         *     'ttlDays' : days to keep log entries around (false means "forever")
         */
        protected function __construct( array $config ) {
-               $this->ttlDays = isset( $config['ttlDays'] ) ? $config['ttlDays'] : false;
+               $this->ttlDays = $config['ttlDays'] ?? false;
        }
 
        /**
@@ -149,9 +149,9 @@ abstract class FileJournal {
         * Get an array of file change log entries.
         * A starting change ID and/or limit can be specified.
         *
-        * @param int $start Starting change ID or null
+        * @param int|null $start Starting change ID or null
         * @param int $limit Maximum number of items to return
-        * @param string &$next Updated to the ID of the next entry.
+        * @param string|null &$next Updated to the ID of the next entry.
         * @return array List of associative arrays, each having:
         *     id         : unique, monotonic, ID for this change
         *     batch_uuid : UUID for an operation batch
index 40af7ac..206048b 100644 (file)
@@ -115,7 +115,7 @@ abstract class FileOp {
                if ( FileBackend::isStoragePath( $path ) ) {
                        $res = FileBackend::normalizeStoragePath( $path );
 
-                       return ( $res !== null ) ? $res : $path;
+                       return $res ?? $path;
                }
 
                return $path;
@@ -137,7 +137,7 @@ abstract class FileOp {
         * @return mixed Returns null if the parameter is not set
         */
        final public function getParam( $name ) {
-               return isset( $this->params[$name] ) ? $this->params[$name] : null;
+               return $this->params[$name] ?? null;
        }
 
        /**
index df22b41..93f5b0b 100644 (file)
@@ -23,7 +23,7 @@ class HttpAcceptParser {
         * Note that type parameters and accept extension like the "level" parameter
         * are not supported, weights are derived from "q" values only.
         *
-        * @todo: If additional type parameters are present, ignore them cleanly.
+        * @todo If additional type parameters are present, ignore them cleanly.
         *        At present, they often confuse the result.
         *
         * See HTTP/1.1 section 14 for details.
index e3c2d75..08e9d69 100644 (file)
@@ -909,7 +909,7 @@ class JSParser
                                }
                                else
                                {
-                                       $n->setup = $n2 ? $n2 : null;
+                                       $n->setup = $n2 ?: null;
                                        $this->t->mustMatch(OP_SEMICOLON);
                                        $n->condition = $this->t->peek() == OP_SEMICOLON ? null : $this->Expression($x);
                                        $this->t->mustMatch(OP_SEMICOLON);
@@ -1656,7 +1656,7 @@ class JSNode
        {
                if ($token = $t->currentToken())
                {
-                       $this->type = $type ? $type : $token->type;
+                       $this->type = $type ?: $token->type;
                        $this->value = $token->value;
                        $this->lineno = $token->lineno;
                        $this->start = $token->start;
@@ -1752,7 +1752,7 @@ class JSTokenizer
        public function init($source, $filename = '', $lineno = 1)
        {
                $this->source = $source;
-               $this->filename = $filename ? $filename : '[inline]';
+               $this->filename = $filename ?: '[inline]';
                $this->lineno = $lineno;
 
                $this->cursor = 0;
index 26e25f9..5e8c22b 100644 (file)
@@ -82,7 +82,7 @@ abstract class DBLockManager extends QuorumLockManager {
                        $this->lockExpiry = $config['lockExpiry'];
                } else {
                        $met = ini_get( 'max_execution_time' );
-                       $this->lockExpiry = $met ? $met : 60; // use some sane amount if 0
+                       $this->lockExpiry = $met ?: 60; // use some sane amount if 0
                }
                $this->safeDelay = ( $this->lockExpiry <= 0 )
                        ? 60 // pick a safe-ish number to match DB timeout default
@@ -90,13 +90,11 @@ abstract class DBLockManager extends QuorumLockManager {
 
                // Tracks peers that couldn't be queried recently to avoid lengthy
                // connection timeouts. This is useless if each bucket has one peer.
-               $this->statusCache = isset( $config['srvCache'] )
-                       ? $config['srvCache']
-                       : new HashBagOStuff();
+               $this->statusCache = $config['srvCache'] ?? new HashBagOStuff();
        }
 
        /**
-        * @TODO change this code to work in one batch
+        * @todo change this code to work in one batch
         * @param string $lockSrv
         * @param array $pathsByType
         * @return StatusValue
index 6b3cfb4..d152c65 100644 (file)
@@ -80,7 +80,7 @@ abstract class LockManager {
         *               This only applies if locks are not tied to a connection/process.
         */
        public function __construct( array $config ) {
-               $this->domain = isset( $config['domain'] ) ? $config['domain'] : 'global';
+               $this->domain = $config['domain'] ?? 'global';
                if ( isset( $config['lockTTL'] ) ) {
                        $this->lockTTL = max( 5, $config['lockTTL'] );
                } elseif ( PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg' ) {
@@ -101,7 +101,7 @@ abstract class LockManager {
                }
                $this->session = md5( implode( '-', $random ) );
 
-               $this->logger = isset( $config['logger'] ) ? $config['logger'] : new \Psr\Log\NullLogger();
+               $this->logger = $config['logger'] ?? new \Psr\Log\NullLogger();
        }
 
        /**
@@ -201,6 +201,11 @@ abstract class LockManager {
        final protected function normalizePathsByType( array $pathsByType ) {
                $res = [];
                foreach ( $pathsByType as $type => $paths ) {
+                       foreach ( $paths as $path ) {
+                               if ( (string)$path === '' ) {
+                                       throw new InvalidArgumentException( __METHOD__ . ": got empty path." );
+                               }
+                       }
                        $res[$this->lockTypeMap[$type]] = array_unique( $paths );
                }
 
index 6274d60..7f5f003 100644 (file)
@@ -46,7 +46,7 @@ class MemcLockManager extends QuorumLockManager {
 
        /** @var MemcachedBagOStuff[] Map of (server name => MemcachedBagOStuff) */
        protected $cacheServers = [];
-       /** @var HashBagOStuff Server status cache */
+       /** @var MapCacheLRU Server status cache */
        protected $statusCache;
 
        /**
@@ -68,7 +68,7 @@ class MemcLockManager extends QuorumLockManager {
                $this->srvsByBucket = array_filter( $config['srvsByBucket'], 'is_array' );
                $this->srvsByBucket = array_values( $this->srvsByBucket ); // consecutive
 
-               $memcConfig = isset( $config['memcConfig'] ) ? $config['memcConfig'] : [];
+               $memcConfig = $config['memcConfig'] ?? [];
                $memcConfig += [ 'class' => MemcachedPhpBagOStuff::class ]; // default
 
                $class = $memcConfig['class'];
@@ -81,7 +81,7 @@ class MemcLockManager extends QuorumLockManager {
                        $this->cacheServers[$name] = new $class( $params );
                }
 
-               $this->statusCache = new HashBagOStuff();
+               $this->statusCache = new MapCacheLRU( 100 );
        }
 
        protected function getLocksOnServer( $lockSrv, array $pathsByType ) {
@@ -89,7 +89,7 @@ class MemcLockManager extends QuorumLockManager {
 
                $memc = $this->getCache( $lockSrv );
                // List of affected paths
-               $paths = call_user_func_array( 'array_merge', array_values( $pathsByType ) );
+               $paths = array_merge( ...array_values( $pathsByType ) );
                $paths = array_unique( $paths );
                // List of affected lock record keys
                $keys = array_map( [ $this, 'recordKeyForPath' ], $paths );
@@ -164,7 +164,7 @@ class MemcLockManager extends QuorumLockManager {
 
                $memc = $this->getCache( $lockSrv );
                // List of affected paths
-               $paths = call_user_func_array( 'array_merge', array_values( $pathsByType ) );
+               $paths = array_merge( ...array_values( $pathsByType ) );
                $paths = array_unique( $paths );
                // List of affected lock record keys
                $keys = array_map( [ $this, 'recordKeyForPath' ], $paths );
@@ -252,13 +252,13 @@ class MemcLockManager extends QuorumLockManager {
                        throw new InvalidArgumentException( "Invalid cache server '$lockSrv'." );
                }
 
-               $online = $this->statusCache->get( "online:$lockSrv" );
-               if ( $online === false ) {
+               $online = $this->statusCache->get( "online:$lockSrv", 30 );
+               if ( $online === null ) {
                        $online = $this->cacheServers[$lockSrv]->set( __CLASS__ . ':ping', 1, 1 );
                        if ( !$online ) { // server down?
                                $this->logger->warning( __METHOD__ . ": Could not contact $lockSrv." );
                        }
-                       $this->statusCache->set( "online:$lockSrv", (int)$online, 30 );
+                       $this->statusCache->set( "online:$lockSrv", (int)$online );
                }
 
                return $online ? $this->cacheServers[$lockSrv] : null;
index ea9dde7..a624f0a 100644 (file)
@@ -76,7 +76,7 @@ class RedisLockManager extends QuorumLockManager {
        protected function getLocksOnServer( $lockSrv, array $pathsByType ) {
                $status = StatusValue::newGood();
 
-               $pathList = call_user_func_array( 'array_merge', array_values( $pathsByType ) );
+               $pathList = array_merge( ...array_values( $pathsByType ) );
 
                $server = $this->lockServers[$lockSrv];
                $conn = $this->redisPool->getConnection( $server, $this->logger );
@@ -171,7 +171,7 @@ LUA;
        protected function freeLocksOnServer( $lockSrv, array $pathsByType ) {
                $status = StatusValue::newGood();
 
-               $pathList = call_user_func_array( 'array_merge', array_values( $pathsByType ) );
+               $pathList = array_merge( ...array_values( $pathsByType ) );
 
                $server = $this->lockServers[$lockSrv];
                $conn = $this->redisPool->getConnection( $server, $this->logger );
index 6261335..d877db0 100644 (file)
@@ -85,7 +85,7 @@ class ScopedLock {
         * This is useful for early release of locks before function scope is destroyed.
         * This is the same as setting the lock object to null.
         *
-        * @param ScopedLock &$lock
+        * @param ScopedLock|null &$lock
         * @since 1.21
         */
        public static function release( ScopedLock &$lock = null ) {
index e9fb11f..802ed2d 100644 (file)
@@ -500,13 +500,13 @@ class IEContentAnalyzer {
                        < ( $counters['ctrl'] + $counters['high'] ) * 16
                ) {
                        $kindOfBinary = true;
-                       $type = $binaryType ? $binaryType : $textType;
+                       $type = $binaryType ?: $textType;
                        if ( $type === false ) {
                                $type = 'application/octet-stream';
                        }
                } else {
                        $kindOfBinary = false;
-                       $type = $textType ? $textType : $binaryType;
+                       $type = $textType ?: $binaryType;
                        if ( $type === false ) {
                                $type = 'text/plain';
                        }
index 8d842cb..77c377b 100644 (file)
@@ -195,21 +195,11 @@ EOT;
                $this->typeFile = $params['typeFile'];
                $this->infoFile = $params['infoFile'];
                $this->xmlTypes = $params['xmlTypes'];
-               $this->initCallback = isset( $params['initCallback'] )
-                       ? $params['initCallback']
-                       : null;
-               $this->detectCallback = isset( $params['detectCallback'] )
-                       ? $params['detectCallback']
-                       : null;
-               $this->guessCallback = isset( $params['guessCallback'] )
-                       ? $params['guessCallback']
-                       : null;
-               $this->extCallback = isset( $params['extCallback'] )
-                       ? $params['extCallback']
-                       : null;
-               $this->logger = isset( $params['logger'] )
-                       ? $params['logger']
-                       : new \Psr\Log\NullLogger();
+               $this->initCallback = $params['initCallback'] ?? null;
+               $this->detectCallback = $params['detectCallback'] ?? null;
+               $this->guessCallback = $params['guessCallback'] ?? null;
+               $this->extCallback = $params['extCallback'] ?? null;
+               $this->logger = $params['logger'] ?? new \Psr\Log\NullLogger();
 
                $this->loadFiles();
        }
@@ -437,7 +427,7 @@ EOT;
        public function getTypesForExtension( $ext ) {
                $ext = strtolower( $ext );
 
-               $r = isset( $this->mExtToMime[$ext] ) ? $this->mExtToMime[$ext] : null;
+               $r = $this->mExtToMime[$ext] ?? null;
                return $r;
        }
 
@@ -1039,9 +1029,9 @@ EOT;
         * @todo analyse file if need be
         * @todo look at multiple extension, separately and together.
         *
-        * @param string $path Full path to the image file, in case we have to look at the contents
+        * @param string|null $path Full path to the image file, in case we have to look at the contents
         *        (if null, only the MIME type is used to determine the media type code).
-        * @param string $mime MIME type. If null it will be guessed using guessMimeType.
+        * @param string|null $mime MIME type. If null it will be guessed using guessMimeType.
         *
         * @return string A value to be used with the MEDIATYPE_xxx constants.
         */
index 9770515..9cfaf67 100644 (file)
@@ -91,7 +91,7 @@ class XmlTypeCheck {
         *  result stored in $this->filterMatchType.
         *
         * @param string $input a filename or string containing the XML element
-        * @param callable $filterCallback (optional)
+        * @param callable|null $filterCallback (optional)
         *        Function to call to do additional custom validity checks from the
         *        SAX element handler event. This gives you access to the element
         *        namespace, name, attributes, and text contents.
@@ -114,7 +114,7 @@ class XmlTypeCheck {
         * Alternative constructor: from filename
         *
         * @param string $fname the filename of an XML document
-        * @param callable $filterCallback (optional)
+        * @param callable|null $filterCallback (optional)
         *        Function to call to do additional custom validity checks from the
         *        SAX element handler event. This gives you access to the element
         *        namespace, name, and attributes, but not to text contents.
@@ -129,7 +129,7 @@ class XmlTypeCheck {
         * Alternative constructor: from string
         *
         * @param string $string a string containing an XML element
-        * @param callable $filterCallback (optional)
+        * @param callable|null $filterCallback (optional)
         *        Function to call to do additional custom validity checks from the
         *        SAX element handler event. This gives you access to the element
         *        namespace, name, and attributes, but not to text contents.
@@ -394,8 +394,8 @@ class XmlTypeCheck {
                        $callbackReturn = call_user_func(
                                $externalCallback,
                                $parsedDTD['type'],
-                               isset( $parsedDTD['publicid'] ) ? $parsedDTD['publicid'] : null,
-                               isset( $parsedDTD['systemid'] ) ? $parsedDTD['systemid'] : null
+                               $parsedDTD['publicid'] ?? null,
+                               $parsedDTD['systemid'] ?? null
                        );
                }
                if ( $callbackReturn ) {
index 8a88581..82ae5ae 100644 (file)
@@ -81,6 +81,9 @@ abstract class BagOStuff implements IExpiringStore, LoggerAwareInterface {
        /** @var callable[] */
        protected $busyCallbacks = [];
 
+       /** @var float|null */
+       private $wallClockOverride;
+
        /** @var int[] Map of (ATTR_* class constant => QOS_* class constant) */
        protected $attrMap = [];
 
@@ -119,20 +122,18 @@ abstract class BagOStuff implements IExpiringStore, LoggerAwareInterface {
                        $this->keyspace = $params['keyspace'];
                }
 
-               $this->asyncHandler = isset( $params['asyncHandler'] )
-                       ? $params['asyncHandler']
-                       : null;
+               $this->asyncHandler = $params['asyncHandler'] ?? null;
 
                if ( !empty( $params['reportDupes'] ) && is_callable( $this->asyncHandler ) ) {
                        $this->reportDupes = true;
                }
 
-               $this->syncTimeout = isset( $params['syncTimeout'] ) ? $params['syncTimeout'] : 3;
+               $this->syncTimeout = $params['syncTimeout'] ?? 3;
        }
 
        /**
         * @param LoggerInterface $logger
-        * @return null
+        * @return void
         */
        public function setLogger( LoggerInterface $logger ) {
                $this->logger = $logger;
@@ -184,7 +185,7 @@ abstract class BagOStuff implements IExpiringStore, LoggerAwareInterface {
         *
         * @param string $key
         * @param int $flags Bitfield of BagOStuff::READ_* constants [optional]
-        * @param int $oldFlags [unused]
+        * @param int|null $oldFlags [unused]
         * @return mixed Returns false on failure and if the item does not exist
         */
        public function get( $key, $flags = 0, $oldFlags = null ) {
@@ -237,7 +238,7 @@ abstract class BagOStuff implements IExpiringStore, LoggerAwareInterface {
        abstract protected function doGet( $key, $flags = 0 );
 
        /**
-        * @note: This method is only needed if merge() uses mergeViaCas()
+        * @note This method is only needed if merge() uses mergeViaCas()
         *
         * @param string $key
         * @param mixed &$casToken
@@ -307,6 +308,11 @@ abstract class BagOStuff implements IExpiringStore, LoggerAwareInterface {
                        $this->reportDupes = $reportDupes;
 
                        if ( $this->getLastError() ) {
+                               $this->logger->warning(
+                                       __METHOD__ . ' failed due to I/O error on get() for {key}.',
+                                       [ 'key' => $key ]
+                               );
+
                                return false; // don't spam retries (retry only on races)
                        }
 
@@ -324,6 +330,11 @@ abstract class BagOStuff implements IExpiringStore, LoggerAwareInterface {
                                $success = $this->cas( $casToken, $key, $value, $exptime );
                        }
                        if ( $this->getLastError() ) {
+                               $this->logger->warning(
+                                       __METHOD__ . ' failed due to I/O error for {key}.',
+                                       [ 'key' => $key ]
+                               );
+
                                return false; // IO error; don't spam retries
                        }
                } while ( !$success && --$attempts );
@@ -342,7 +353,26 @@ abstract class BagOStuff implements IExpiringStore, LoggerAwareInterface {
         * @throws Exception
         */
        protected function cas( $casToken, $key, $value, $exptime = 0 ) {
-               throw new Exception( "CAS is not implemented in " . __CLASS__ );
+               if ( !$this->lock( $key, 0 ) ) {
+                       return false; // non-blocking
+               }
+
+               $curCasToken = null; // passed by reference
+               $this->getWithToken( $key, $curCasToken, self::READ_LATEST );
+               if ( $casToken === $curCasToken ) {
+                       $success = $this->set( $key, $value, $exptime );
+               } else {
+                       $this->logger->info(
+                               __METHOD__ . ' failed due to race condition for {key}.',
+                               [ 'key' => $key ]
+                       );
+
+                       $success = false; // mismatched or failed
+               }
+
+               $this->unlock( $key );
+
+               return $success;
        }
 
        /**
@@ -356,7 +386,13 @@ abstract class BagOStuff implements IExpiringStore, LoggerAwareInterface {
         * @return bool Success
         */
        protected function mergeViaLock( $key, $callback, $exptime = 0, $attempts = 10, $flags = 0 ) {
-               if ( !$this->lock( $key, 6 ) ) {
+               if ( $attempts <= 1 ) {
+                       $timeout = 0; // clearly intended to be "non-blocking"
+               } else {
+                       $timeout = 3;
+               }
+
+               if ( !$this->lock( $key, $timeout ) ) {
                        return false;
                }
 
@@ -367,6 +403,11 @@ abstract class BagOStuff implements IExpiringStore, LoggerAwareInterface {
                $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
@@ -422,13 +463,19 @@ abstract class BagOStuff implements IExpiringStore, LoggerAwareInterface {
                        }
                }
 
+               $fname = __METHOD__;
                $expiry = min( $expiry ?: INF, self::TTL_DAY );
                $loop = new WaitConditionLoop(
-                       function () use ( $key, $timeout, $expiry ) {
+                       function () use ( $key, $timeout, $expiry, $fname ) {
                                $this->clearLastError();
                                if ( $this->add( "{$key}:lock", 1, $expiry ) ) {
                                        return true; // locked!
                                } elseif ( $this->getLastError() ) {
+                                       $this->logger->warning(
+                                               $fname . ' failed due to I/O error for {key}.',
+                                               [ 'key' => $key ]
+                                       );
+
                                        return WaitConditionLoop::CONDITION_ABORTED; // network partition?
                                }
 
@@ -437,9 +484,15 @@ abstract class BagOStuff implements IExpiringStore, LoggerAwareInterface {
                        $timeout
                );
 
-               $locked = ( $loop->invoke() === $loop::CONDITION_REACHED );
+               $code = $loop->invoke();
+               $locked = ( $code === $loop::CONDITION_REACHED );
                if ( $locked ) {
                        $this->locks[$key] = [ 'class' => $rclass, 'depth' => 1 ];
+               } elseif ( $code === $loop::CONDITION_TIMED_OUT ) {
+                       $this->logger->warning(
+                               "$fname failed due to timeout for {key}.",
+                               [ 'key' => $key, 'timeout' => $timeout ]
+                       );
                }
 
                return $locked;
@@ -455,7 +508,15 @@ abstract class BagOStuff implements IExpiringStore, LoggerAwareInterface {
                if ( isset( $this->locks[$key] ) && --$this->locks[$key]['depth'] <= 0 ) {
                        unset( $this->locks[$key] );
 
-                       return $this->delete( "{$key}:lock" );
+                       $ok = $this->delete( "{$key}:lock" );
+                       if ( !$ok ) {
+                               $this->logger->warning(
+                                       __METHOD__ . ' failed to release lock for {key}.',
+                                       [ 'key' => $key ]
+                               );
+                       }
+
+                       return $ok;
                }
 
                return true;
@@ -484,13 +545,16 @@ abstract class BagOStuff implements IExpiringStore, LoggerAwareInterface {
                        return null;
                }
 
-               $lSince = microtime( true ); // lock timestamp
+               $lSince = $this->getCurrentTime(); // lock timestamp
 
                return new ScopedCallback( function () use ( $key, $lSince, $expiry ) {
                        $latency = 0.050; // latency skew (err towards keeping lock present)
-                       $age = ( microtime( true ) - $lSince + $latency );
+                       $age = ( $this->getCurrentTime() - $lSince + $latency );
                        if ( ( $age + $latency ) >= $expiry ) {
-                               $this->logger->warning( "Lock for $key held too long ($age sec)." );
+                               $this->logger->warning(
+                                       "Lock for {key} held too long ({age} sec).",
+                                       [ 'key' => $key, 'age' => $age ]
+                               );
                                return; // expired; it's not "safe" to delete the key
                        }
                        $this->unlock( $key );
@@ -552,6 +616,7 @@ abstract class BagOStuff implements IExpiringStore, LoggerAwareInterface {
         * @return bool Success
         */
        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 );
                }
@@ -565,7 +630,7 @@ abstract class BagOStuff implements IExpiringStore, LoggerAwareInterface {
         * @return int|bool New value or false on failure
         */
        public function incr( $key, $value = 1 ) {
-               if ( !$this->lock( $key ) ) {
+               if ( !$this->lock( $key, 1 ) ) {
                        return false;
                }
                $n = $this->get( $key );
@@ -603,14 +668,15 @@ abstract class BagOStuff implements IExpiringStore, LoggerAwareInterface {
         * @since 1.24
         */
        public function incrWithInit( $key, $ttl, $value = 1, $init = 1 ) {
+               $this->clearLastError();
                $newValue = $this->incr( $key, $value );
-               if ( $newValue === false ) {
+               if ( $newValue === false && !$this->getLastError() ) {
                        // No key set; initialize
                        $newValue = $this->add( $key, (int)$init, $ttl ) ? $init : false;
-               }
-               if ( $newValue === false ) {
-                       // Raced out initializing; increment
-                       $newValue = $this->incr( $key, $value );
+                       if ( $newValue === false && !$this->getLastError() ) {
+                               // Raced out initializing; increment
+                               $newValue = $this->incr( $key, $value );
+                       }
                }
 
                return $newValue;
@@ -702,7 +768,7 @@ abstract class BagOStuff implements IExpiringStore, LoggerAwareInterface {
         */
        protected function convertExpiry( $exptime ) {
                if ( $exptime != 0 && $exptime < ( 10 * self::TTL_YEAR ) ) {
-                       return time() + $exptime;
+                       return (int)$this->getCurrentTime() + $exptime;
                } else {
                        return $exptime;
                }
@@ -717,7 +783,7 @@ abstract class BagOStuff implements IExpiringStore, LoggerAwareInterface {
         */
        protected function convertToRelative( $exptime ) {
                if ( $exptime >= ( 10 * self::TTL_YEAR ) ) {
-                       $exptime -= time();
+                       $exptime -= (int)$this->getCurrentTime();
                        if ( $exptime <= 0 ) {
                                $exptime = 1;
                        }
@@ -759,7 +825,7 @@ abstract class BagOStuff implements IExpiringStore, LoggerAwareInterface {
         *
         * @since 1.27
         * @param string $class Key class
-        * @param string $component [optional] Key component (starting with a key collection name)
+        * @param string|null $component [optional] Key component (starting with a key collection name)
         * @return string Colon-delimited list of $keyspace followed by escaped components of $args
         */
        public function makeGlobalKey( $class, $component = null ) {
@@ -771,7 +837,7 @@ abstract class BagOStuff implements IExpiringStore, LoggerAwareInterface {
         *
         * @since 1.27
         * @param string $class Key class
-        * @param string $component [optional] Key component (starting with a key collection name)
+        * @param string|null $component [optional] Key component (starting with a key collection name)
         * @return string Colon-delimited list of $keyspace followed by escaped components of $args
         */
        public function makeKey( $class, $component = null ) {
@@ -784,7 +850,7 @@ abstract class BagOStuff implements IExpiringStore, LoggerAwareInterface {
         * @since 1.28
         */
        public function getQoS( $flag ) {
-               return isset( $this->attrMap[$flag] ) ? $this->attrMap[$flag] : self::QOS_UNKNOWN;
+               return $this->attrMap[$flag] ?? self::QOS_UNKNOWN;
        }
 
        /**
@@ -807,4 +873,20 @@ abstract class BagOStuff implements IExpiringStore, LoggerAwareInterface {
 
                return $map;
        }
+
+       /**
+        * @return float UNIX timestamp
+        * @codeCoverageIgnore
+        */
+       protected function getCurrentTime() {
+               return $this->wallClockOverride ?: microtime( true );
+       }
+
+       /**
+        * @param float|null &$time Mock UNIX timestamp for testing
+        * @codeCoverageIgnore
+        */
+       public function setMockTime( &$time ) {
+               $this->wallClockOverride =& $time;
+       }
 }
index ae434c1..726836e 100644 (file)
@@ -68,7 +68,7 @@ class CachedBagOStuff extends HashBagOStuff {
        }
 
        public function delete( $key, $flags = 0 ) {
-               unset( $this->bag[$key] );
+               parent::delete( $key );
                if ( !( $flags & self::WRITE_CACHE_ONLY ) ) {
                        $this->backend->delete( $key );
                }
@@ -86,12 +86,16 @@ class CachedBagOStuff extends HashBagOStuff {
                return $this->backend->deleteObjectsExpiringBefore( $date, $progressCallback );
        }
 
+       public function makeKeyInternal( $keyspace, $args ) {
+               return $this->backend->makeKeyInternal( ...func_get_args() );
+       }
+
        public function makeKey( $class, $component = null ) {
-               return call_user_func_array( [ $this->backend, __FUNCTION__ ], func_get_args() );
+               return $this->backend->makeKey( ...func_get_args() );
        }
 
        public function makeGlobalKey( $class, $component = null ) {
-               return call_user_func_array( [ $this->backend, __FUNCTION__ ], func_get_args() );
+               return $this->backend->makeGlobalKey( ...func_get_args() );
        }
 
        // These just call the backend (tested elsewhere)
index f8e3b17..ec66492 100644 (file)
@@ -44,7 +44,7 @@ class HashBagOStuff extends BagOStuff {
        function __construct( $params = [] ) {
                parent::__construct( $params );
 
-               $this->maxCacheKeys = isset( $params['maxKeys'] ) ? $params['maxKeys'] : INF;
+               $this->maxCacheKeys = $params['maxKeys'] ?? INF;
                if ( $this->maxCacheKeys <= 0 ) {
                        throw new InvalidArgumentException( '$maxKeys parameter must be above zero' );
                }
@@ -115,8 +115,4 @@ class HashBagOStuff extends BagOStuff {
        public function clear() {
                $this->bag = [];
        }
-
-       protected function getCurrentTime() {
-               return time();
-       }
 }
index 59131b9..1cc07b7 100644 (file)
@@ -259,11 +259,11 @@ class MemcachedClient {
         * @return mixed
         */
        public function __construct( $args ) {
-               $this->set_servers( isset( $args['servers'] ) ? $args['servers'] : array() );
-               $this->_debug = isset( $args['debug'] ) ? $args['debug'] : false;
+               $this->set_servers( $args['servers'] ?? array() );
+               $this->_debug = $args['debug'] ?? false;
                $this->stats = array();
-               $this->_compress_threshold = isset( $args['compress_threshold'] ) ? $args['compress_threshold'] : 0;
-               $this->_persistent = isset( $args['persistent'] ) ? $args['persistent'] : false;
+               $this->_compress_threshold = $args['compress_threshold'] ?? 0;
+               $this->_persistent = $args['persistent'] ?? false;
                $this->_compress_enable = true;
                $this->_have_zlib = function_exists( 'gzcompress' );
 
@@ -271,12 +271,12 @@ class MemcachedClient {
                $this->_host_dead = array();
 
                $this->_timeout_seconds = 0;
-               $this->_timeout_microseconds = isset( $args['timeout'] ) ? $args['timeout'] : 500000;
+               $this->_timeout_microseconds = $args['timeout'] ?? 500000;
 
-               $this->_connect_timeout = isset( $args['connect_timeout'] ) ? $args['connect_timeout'] : 0.1;
+               $this->_connect_timeout = $args['connect_timeout'] ?? 0.1;
                $this->_connect_attempts = 2;
 
-               $this->_logger = isset( $args['logger'] ) ? $args['logger'] : new NullLogger();
+               $this->_logger = $args['logger'] ?? new NullLogger();
        }
 
        // }}}
index e3e66d5..fe31c25 100644 (file)
@@ -140,7 +140,19 @@ class MemcachedPeclBagOStuff extends MemcachedBagOStuff {
 
        protected function getWithToken( $key, &$casToken, $flags = 0 ) {
                $this->debugLog( "get($key)" );
-               $result = $this->client->get( $this->validateKeyEncoding( $key ), null, $casToken );
+               if ( defined( Memcached::class . '::GET_EXTENDED' ) ) { // v3.0.0
+                       $flags = Memcached::GET_EXTENDED;
+                       $res = $this->client->get( $this->validateKeyEncoding( $key ), null, $flags );
+                       if ( is_array( $res ) ) {
+                               $result = $res['value'];
+                               $casToken = $res['cas'];
+                       } else {
+                               $result = false;
+                               $casToken = null;
+                       }
+               } else {
+                       $result = $this->client->get( $this->validateKeyEncoding( $key ), null, $casToken );
+               }
                $result = $this->checkResult( $key, $result );
                return $result;
        }
index e2d9d93..3ff390b 100644 (file)
@@ -62,12 +62,12 @@ class MemcachedPhpBagOStuff extends MemcachedBagOStuff {
        public function incr( $key, $value = 1 ) {
                $this->validateKeyEncoding( $key );
 
-               return $this->client->incr( $key, $value );
+               return $this->client->incr( $key, $value ) ?? false;
        }
 
        public function decr( $key, $value = 1 ) {
                $this->validateKeyEncoding( $key );
 
-               return $this->client->decr( $key, $value );
+               return $this->client->decr( $key, $value ) ?? false;
        }
 }
index b030522..043f8cb 100644 (file)
@@ -34,9 +34,8 @@ class MultiWriteBagOStuff extends BagOStuff {
        protected $caches;
        /** @var bool Use async secondary writes */
        protected $asyncWrites = false;
-
-       /** Idiom for "write to all backends" */
-       const ALL = INF;
+       /** @var int[] List of all backing cache indexes */
+       protected $cacheIndexes = [];
 
        const UPGRADE_TTL = 3600; // TTL when a key is copied to a higher cache tier
 
@@ -91,6 +90,8 @@ class MultiWriteBagOStuff extends BagOStuff {
                        $params['replication'] === 'async' &&
                        is_callable( $this->asyncHandler )
                );
+
+               $this->cacheIndexes = array_keys( $this->caches );
        }
 
        public function setDebug( $debug ) {
@@ -107,21 +108,24 @@ class MultiWriteBagOStuff extends BagOStuff {
                        return $this->caches[0]->get( $key, $flags );
                }
 
-               $misses = 0; // number backends checked
                $value = false;
-               foreach ( $this->caches as $cache ) {
+               $missIndexes = []; // backends checked
+               foreach ( $this->caches as $i => $cache ) {
                        $value = $cache->get( $key, $flags );
                        if ( $value !== false ) {
                                break;
                        }
-                       ++$misses;
+                       $missIndexes[] = $i;
                }
 
                if ( $value !== false
-                       && $misses > 0
+                       && $missIndexes
                        && ( $flags & self::READ_VERIFIED ) == self::READ_VERIFIED
                ) {
-                       $this->doWrite( $misses, $this->asyncWrites, 'set', $key, $value, self::UPGRADE_TTL );
+                       // Backfill the value to the higher (and often faster/smaller) cache tiers
+                       $this->doWrite(
+                               $missIndexes, $this->asyncWrites, 'set', $key, $value, self::UPGRADE_TTL
+                       );
                }
 
                return $value;
@@ -132,23 +136,56 @@ class MultiWriteBagOStuff extends BagOStuff {
                        ? false
                        : $this->asyncWrites;
 
-               return $this->doWrite( self::ALL, $asyncWrites, 'set', $key, $value, $exptime );
+               return $this->doWrite( $this->cacheIndexes, $asyncWrites, 'set', $key, $value, $exptime );
        }
 
        public function delete( $key ) {
-               return $this->doWrite( self::ALL, $this->asyncWrites, 'delete', $key );
+               return $this->doWrite( $this->cacheIndexes, $this->asyncWrites, 'delete', $key );
        }
 
        public function add( $key, $value, $exptime = 0 ) {
-               return $this->doWrite( self::ALL, $this->asyncWrites, 'add', $key, $value, $exptime );
+               // Try the write to the top-tier cache
+               $ok = $this->doWrite( [ 0 ], $this->asyncWrites, 'add', $key, $value, $exptime );
+               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,
+                               'set',
+                               $key,
+                               $value,
+                               $exptime
+                       );
+               }
+
+               return false;
        }
 
        public function incr( $key, $value = 1 ) {
-               return $this->doWrite( self::ALL, $this->asyncWrites, 'incr', $key, $value );
+               return $this->doWrite( $this->cacheIndexes, $this->asyncWrites, 'incr', $key, $value );
        }
 
        public function decr( $key, $value = 1 ) {
-               return $this->doWrite( self::ALL, $this->asyncWrites, 'decr', $key, $value );
+               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,
+                       $asyncWrites,
+                       'merge',
+                       $key,
+                       $callback,
+                       $exptime,
+                       $attempts,
+                       $flags
+               );
        }
 
        public function lock( $key, $timeout = 6, $expiry = 6, $rclass = '' ) {
@@ -170,41 +207,37 @@ class MultiWriteBagOStuff extends BagOStuff {
        }
 
        /**
-        * Apply a write method to the first $count backing caches
+        * Apply a write method to the backing caches specified by $indexes (in order)
         *
-        * @param int $count
+        * @param int[] $indexes List of backing cache indexes
         * @param bool $asyncWrites
         * @param string $method
         * @param mixed $args,...
         * @return bool
         */
-       protected function doWrite( $count, $asyncWrites, $method /*, ... */ ) {
+       protected function doWrite( $indexes, $asyncWrites, $method /*, ... */ ) {
                $ret = true;
                $args = array_slice( func_get_args(), 3 );
 
-               if ( $count > 1 && $asyncWrites ) {
+               if ( array_diff( $indexes, [ 0 ] ) && $asyncWrites && $method !== 'merge' ) {
                        // Deep-clone $args to prevent misbehavior when something writes an
                        // object to the BagOStuff then modifies it afterwards, e.g. T168040.
                        $args = unserialize( serialize( $args ) );
                }
 
-               foreach ( $this->caches as $i => $cache ) {
-                       if ( $i >= $count ) {
-                               break; // ignore the lower tiers
-                       }
-
+               foreach ( $indexes as $i ) {
+                       $cache = $this->caches[$i];
                        if ( $i == 0 || !$asyncWrites ) {
                                // First store or in sync mode: write now and get result
-                               if ( !call_user_func_array( [ $cache, $method ], $args ) ) {
+                               if ( !$cache->$method( ...$args ) ) {
                                        $ret = false;
                                }
                        } else {
                                // Secondary write in async mode: do not block this HTTP request
                                $logger = $this->logger;
-                               call_user_func(
-                                       $this->asyncHandler,
+                               ( $this->asyncHandler )(
                                        function () use ( $cache, $method, $args, $logger ) {
-                                               if ( !call_user_func_array( [ $cache, $method ], $args ) ) {
+                                               if ( !$cache->$method( ...$args ) ) {
                                                        $logger->warning( "Async $method op failed" );
                                                }
                                        }
@@ -234,11 +267,15 @@ class MultiWriteBagOStuff extends BagOStuff {
                return $ret;
        }
 
+       public function makeKeyInternal( $keyspace, $args ) {
+               return $this->caches[0]->makeKeyInternal( ...func_get_args() );
+       }
+
        public function makeKey( $class, $component = null ) {
-               return call_user_func_array( [ $this->caches[0], __FUNCTION__ ], func_get_args() );
+               return $this->caches[0]->makeKey( ...func_get_args() );
        }
 
        public function makeGlobalKey( $class, $component = null ) {
-               return call_user_func_array( [ $this->caches[0], __FUNCTION__ ], func_get_args() );
+               return $this->caches[0]->makeGlobalKey( ...func_get_args() );
        }
 }
index d3aa9f5..fc3d575 100644 (file)
@@ -1,5 +1,7 @@
 <?php
 
+use Psr\Log\LoggerInterface;
+
 /**
  * Interface to key-value storage behind an HTTP server.
  *
  * @endcode
  */
 class RESTBagOStuff extends BagOStuff {
+       /**
+        * Default connection timeout in seconds. The kernel retransmits the SYN
+        * packet after 1 second, so 1.2 seconds allows for 1 retransmit without
+        * permanent failure.
+        */
+       const DEFAULT_CONN_TIMEOUT = 1.2;
+
+       /**
+        * Default request timeout
+        */
+       const DEFAULT_REQ_TIMEOUT = 3.0;
 
        /**
         * @var MultiHttpClient
@@ -43,18 +56,34 @@ class RESTBagOStuff extends BagOStuff {
                if ( empty( $params['url'] ) ) {
                        throw new InvalidArgumentException( 'URL parameter is required' );
                }
-               parent::__construct( $params );
                if ( empty( $params['client'] ) ) {
-                       $this->client = new MultiHttpClient( [] );
+                       // Pass through some params to the HTTP client.
+                       $clientParams = [
+                               'connTimeout' => $params['connTimeout'] ?? self::DEFAULT_CONN_TIMEOUT,
+                               'reqTimeout' => $params['reqTimeout'] ?? self::DEFAULT_REQ_TIMEOUT,
+                       ];
+                       foreach ( [ 'caBundlePath', 'proxy' ] as $key ) {
+                               if ( isset( $params[$key] ) ) {
+                                       $clientParams[$key] = $params[$key];
+                               }
+                       }
+                       $this->client = new MultiHttpClient( $clientParams );
                } else {
                        $this->client = $params['client'];
                }
+               // The parent constructor calls setLogger() which sets the logger in $this->client
+               parent::__construct( $params );
                // Make sure URL ends with /
                $this->url = rtrim( $params['url'], '/' ) . '/';
                // Default config, R+W > N; no locks on reads though; writes go straight to state-machine
                $this->attrMap[self::ATTR_SYNCWRITES] = self::QOS_SYNCWRITES_QC;
        }
 
+       public function setLogger( LoggerInterface $logger ) {
+               parent::setLogger( $logger );
+               $this->client->setLogger( $logger );
+       }
+
        /**
         * @param string $key
         * @param int $flags Bitfield of BagOStuff::READ_* constants [optional]
@@ -111,7 +140,7 @@ class RESTBagOStuff extends BagOStuff {
                        'body' => serialize( $value )
                ];
                list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $this->client->run( $req );
-               if ( $rcode === 200 || $rcode === 201 ) {
+               if ( $rcode === 200 || $rcode === 201 || $rcode === 204 ) {
                        return true;
                }
                return $this->handleError( "Failed to store $key", $rcode, $rerr );
@@ -129,7 +158,7 @@ class RESTBagOStuff extends BagOStuff {
                        'url' => $this->url . rawurlencode( $key ),
                ];
                list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $this->client->run( $req );
-               if ( $rcode === 200 || $rcode === 204 || $rcode === 205 ) {
+               if ( in_array( $rcode, [ 200, 204, 205, 404, 410 ] ) ) {
                        return true;
                }
                return $this->handleError( "Failed to delete $key", $rcode, $rerr );
index f720010..a8047b0 100644 (file)
@@ -91,12 +91,19 @@ class RedisBagOStuff extends BagOStuff {
        }
 
        protected function doGet( $key, $flags = 0 ) {
+               $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;
                }
                try {
                        $value = $conn->get( $key );
+                       $casToken = $value;
                        $result = $this->unserialize( $value );
                } catch ( RedisException $e ) {
                        $result = false;
@@ -260,6 +267,10 @@ 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().
         *
@@ -279,7 +290,7 @@ class RedisBagOStuff extends BagOStuff {
                }
                try {
                        if ( !$conn->exists( $key ) ) {
-                               return null;
+                               return false;
                        }
                        // @FIXME: on races, the key may have a 0 TTL
                        $result = $conn->incrBy( $key, $value );
@@ -396,9 +407,7 @@ class RedisBagOStuff extends BagOStuff {
         */
        protected function getMasterLinkStatus( RedisConnRef $conn ) {
                $info = $conn->info();
-               return isset( $info['master_link_status'] )
-                       ? $info['master_link_status']
-                       : null;
+               return $info['master_link_status'] ?? null;
        }
 
        /**
index 56b6e0e..f2c3732 100644 (file)
@@ -128,4 +128,16 @@ class ReplicatedBagOStuff extends BagOStuff {
                $this->writeStore->clearLastError();
                $this->readStore->clearLastError();
        }
+
+       public function makeKeyInternal( $keyspace, $args ) {
+               return $this->writeStore->makeKeyInternal( ...func_get_args() );
+       }
+
+       public function makeKey( $class, $component = null ) {
+               return $this->writeStore->makeKey( ...func_get_args() );
+       }
+
+       public function makeGlobalKey( $class, $component = null ) {
+               return $this->writeStore->makeGlobalKey( ...func_get_args() );
+       }
 }
index 17f596d..2989c81 100644 (file)
@@ -87,7 +87,7 @@ use Psr\Log\NullLogger;
 class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
        /** @var BagOStuff The local datacenter cache */
        protected $cache;
-       /** @var HashBagOStuff[] Map of group PHP instance caches */
+       /** @var MapCacheLRU[] Map of group PHP instance caches */
        protected $processCaches = [];
        /** @var string Purge channel name */
        protected $purgeChannel;
@@ -118,6 +118,9 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
        /** @var int Key fetched */
        private $warmupKeyMisses = 0;
 
+       /** @var float|null */
+       private $wallClockOverride;
+
        /** Max time expected to pass between delete() and DB commit finishing */
        const MAX_COMMIT_DELAY = 3;
        /** Max replication+snapshot lag before applying TTL_LAGGED or disallowing set() */
@@ -223,19 +226,15 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
         */
        public function __construct( array $params ) {
                $this->cache = $params['cache'];
-               $this->purgeChannel = isset( $params['channels']['purge'] )
-                       ? $params['channels']['purge']
-                       : self::DEFAULT_PURGE_CHANNEL;
-               $this->purgeRelayer = isset( $params['relayers']['purge'] )
-                       ? $params['relayers']['purge']
-                       : new EventRelayerNull( [] );
-               $this->region = isset( $params['region'] ) ? $params['region'] : 'main';
-               $this->cluster = isset( $params['cluster'] ) ? $params['cluster'] : 'wan-main';
+               $this->purgeChannel = $params['channels']['purge'] ?? self::DEFAULT_PURGE_CHANNEL;
+               $this->purgeRelayer = $params['relayers']['purge'] ?? new EventRelayerNull( [] );
+               $this->region = $params['region'] ?? 'main';
+               $this->cluster = $params['cluster'] ?? 'wan-main';
                $this->mcrouterAware = !empty( $params['mcrouterAware'] );
 
-               $this->setLogger( isset( $params['logger'] ) ? $params['logger'] : new NullLogger() );
-               $this->stats = isset( $params['stats'] ) ? $params['stats'] : new NullStatsdDataFactory();
-               $this->asyncHandler = isset( $params['asyncHandler'] ) ? $params['asyncHandler'] : null;
+               $this->setLogger( $params['logger'] ?? new NullLogger() );
+               $this->stats = $params['stats'] ?? new NullStatsdDataFactory();
+               $this->asyncHandler = $params['asyncHandler'] ?? null;
        }
 
        /**
@@ -260,9 +259,9 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
         * Fetch the value of a key from cache
         *
         * If supplied, $curTTL is set to the remaining TTL (current time left):
-        *   - a) INF; if $key exists, has no TTL, and is not expired by $checkKeys
-        *   - b) float (>=0); if $key exists, has a TTL, and is not expired by $checkKeys
-        *   - c) float (<0); if $key is tombstoned, stale, or existing but expired by $checkKeys
+        *   - a) INF; if $key exists, has no TTL, and is not invalidated by $checkKeys
+        *   - b) float (>=0); if $key exists, has a TTL, and is not invalidated by $checkKeys
+        *   - c) float (<0); if $key is tombstoned, stale, or existing but invalidated by $checkKeys
         *   - d) null; if $key does not exist and is not tombstoned
         *
         * If a key is tombstoned, $curTTL will reflect the time since delete().
@@ -292,19 +291,19 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
         * That method has cache slam avoiding features for hot/expensive keys.
         *
         * @param string $key Cache key made from makeKey() or makeGlobalKey()
-        * @param mixed &$curTTL Approximate TTL left on the key if present/tombstoned [returned]
+        * @param mixed|null &$curTTL Approximate TTL left on the key if present/tombstoned [returned]
         * @param array $checkKeys List of "check" keys
-        * @param float &$asOf UNIX timestamp of cached value; null on failure [returned]
+        * @param float|null &$asOf UNIX timestamp of cached value; null on failure [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 );
-               $curTTL = isset( $curTTLs[$key] ) ? $curTTLs[$key] : null;
-               $asOf = isset( $asOfs[$key] ) ? $asOfs[$key] : null;
+               $curTTL = $curTTLs[$key] ?? null;
+               $asOf = $asOfs[$key] ?? null;
 
-               return isset( $values[$key] ) ? $values[$key] : false;
+               return $values[$key] ?? false;
        }
 
        /**
@@ -379,8 +378,7 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
                        list( $value, $curTTL ) = $this->unwrap( $wrappedValues[$vKey], $now );
                        if ( $value !== false ) {
                                $result[$key] = $value;
-
-                               // Force dependant keys to be invalid for a while after purging
+                               // 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] ) ) {
@@ -389,9 +387,9 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
                                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 expired by *this* check key
+                                               // 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 expired by *any* known check key
+                                               // How long ago this value was invalidated by *any* known check key
                                                $curTTL = min( $curTTL, $ago );
                                        }
                                }
@@ -417,7 +415,7 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
                                ? $this->parsePurgeValue( $wrappedValues[$timeKey] )
                                : false;
                        if ( $purge === false ) {
-                               // Key is not set or invalid; regenerate
+                               // Key is not set or malformed; regenerate
                                $newVal = $this->makePurgeValue( $now, self::HOLDOFF_TTL );
                                $this->cache->add( $timeKey, $newVal, self::CHECK_KEY_TTL );
                                $purge = $this->parsePurgeValue( $newVal );
@@ -494,10 +492,10 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
         */
        final public function set( $key, $value, $ttl = 0, array $opts = [] ) {
                $now = $this->getCurrentTime();
-               $lockTSE = isset( $opts['lockTSE'] ) ? $opts['lockTSE'] : self::TSE_NONE;
-               $staleTTL = isset( $opts['staleTTL'] ) ? $opts['staleTTL'] : self::STALE_TTL_NONE;
+               $lockTSE = $opts['lockTSE'] ?? self::TSE_NONE;
+               $staleTTL = $opts['staleTTL'] ?? self::STALE_TTL_NONE;
                $age = isset( $opts['since'] ) ? max( 0, $now - $opts['since'] ) : 0;
-               $lag = isset( $opts['lag'] ) ? $opts['lag'] : 0;
+               $lag = $opts['lag'] ?? 0;
 
                // Do not cache potentially uncommitted data as it might get rolled back
                if ( !empty( $opts['pending'] ) ) {
@@ -782,7 +780,7 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
         * or getWithSetCallback() will be invalidated. The differences are:
         *   - a) The "check" key will be deleted from all caches and lazily
         *        re-initialized when accessed (rather than set everywhere)
-        *   - b) Thus, dependent keys will be known to be invalid, but not
+        *   - b) Thus, dependent keys will be known to be stale, but not
         *        for how long (they are treated as "just" purged), which
         *        effects any lockTSE logic in getWithSetCallback()
         *   - c) Since "check" keys are initialized only on the server the key hashes
@@ -981,23 +979,26 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
         *   - WANObjectCache::TTL_UNCACHEABLE: Do not cache (if the key exists, it is not deleted)
         * @param callable $callback Value generation function
         * @param array $opts Options map:
-        *   - checkKeys: List of "check" keys. The key at $key will be seen as invalid when either
+        *   - checkKeys: List of "check" keys. The key at $key will be seen as stale when either
         *      touchCheckKey() or resetCheckKey() is called on any of the keys in this list. This
         *      is useful if thousands or millions of keys depend on the same entity. The entity can
         *      simply have its "check" key updated whenever the entity is modified.
         *      Default: [].
-        *   - graceTTL: Consider reusing expired values instead of refreshing them if they expired
-        *      less than this many seconds ago. The odds of a refresh becomes more likely over time,
+        *   - graceTTL: If the key is invalidated (by "checkKeys") less than this many seconds ago,
+        *      consider reusing the stale value. The odds of a refresh becomes more likely over time,
         *      becoming certain once the grace period is reached. This can reduce traffic spikes
-        *      when millions of keys are compared to the same "check" key and touchCheckKey()
-        *      or resetCheckKey() is called on that "check" key.
+        *      when millions of keys are compared to the same "check" key and touchCheckKey() or
+        *      resetCheckKey() is called on that "check" key. This option is not useful for the
+        *      case of the key simply expiring on account of its TTL (use "lowTTL" instead).
         *      Default: WANObjectCache::GRACE_TTL_NONE.
-        *   - lockTSE: If the key is tombstoned or expired (by checkKeys) less than this many seconds
-        *      ago, then try to have a single thread handle cache regeneration at any given time.
+        *   - lockTSE: If the key is tombstoned or invalidated (by "checkKeys") less than this many
+        *      seconds ago, try to have a single thread handle cache regeneration at any given time.
         *      Other threads will try to use stale values if possible. If, on miss, the time since
         *      expiration is low, the assumption is that the key is hot and that a stampede is worth
         *      avoiding. Setting this above WANObjectCache::HOLDOFF_TTL makes no difference. The
-        *      higher this is set, the higher the worst-case staleness can be.
+        *      higher this is set, the higher the worst-case staleness can be. This option does not
+        *      by itself handle the case of the key simply expiring on account of its TTL, so make
+        *      sure that "lowTTL" is not disabled when using this option.
         *      Use WANObjectCache::TSE_NONE to disable this logic.
         *      Default: WANObjectCache::TSE_NONE.
         *   - busyValue: If no value exists and another thread is currently regenerating it, use this
@@ -1052,15 +1053,15 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
         * @note Callable type hints are not used to avoid class-autoloading
         */
        final public function getWithSetCallback( $key, $ttl, $callback, array $opts = [] ) {
-               $pcTTL = isset( $opts['pcTTL'] ) ? $opts['pcTTL'] : self::TTL_UNCACHEABLE;
+               $pcTTL = $opts['pcTTL'] ?? self::TTL_UNCACHEABLE;
 
                // Try the process cache if enabled and the cache callback is not within a cache callback.
                // Process cache use in nested callbacks is not lag-safe with regard to HOLDOFF_TTL since
                // the in-memory value is further lagged than the shared one since it uses a blind TTL.
                if ( $pcTTL >= 0 && $this->callbackDepth == 0 ) {
-                       $group = isset( $opts['pcGroup'] ) ? $opts['pcGroup'] : self::PC_PRIMARY;
+                       $group = $opts['pcGroup'] ?? self::PC_PRIMARY;
                        $procCache = $this->getProcessCache( $group );
-                       $value = $procCache->get( $key );
+                       $value = $procCache->has( $key, $pcTTL ) ? $procCache->get( $key ) : false;
                } else {
                        $procCache = false;
                        $value = false;
@@ -1116,7 +1117,7 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
 
                        // Update the process cache if enabled
                        if ( $procCache && $value !== false ) {
-                               $procCache->set( $key, $value, $pcTTL );
+                               $procCache->set( $key, $value );
                        }
                }
 
@@ -1132,20 +1133,20 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
         * @param int $ttl
         * @param callback $callback
         * @param array $opts Options map for getWithSetCallback()
-        * @param float &$asOf Cache generation timestamp of returned value [returned]
+        * @param float|null &$asOf Cache generation timestamp of returned value [returned]
         * @return mixed
         * @note Callable type hints are not used to avoid class-autoloading
         */
        protected function doGetWithSetCallback( $key, $ttl, $callback, array $opts, &$asOf = null ) {
-               $lowTTL = isset( $opts['lowTTL'] ) ? $opts['lowTTL'] : min( self::LOW_TTL, $ttl );
-               $lockTSE = isset( $opts['lockTSE'] ) ? $opts['lockTSE'] : self::TSE_NONE;
-               $staleTTL = isset( $opts['staleTTL'] ) ? $opts['staleTTL'] : self::STALE_TTL_NONE;
-               $graceTTL = isset( $opts['graceTTL'] ) ? $opts['graceTTL'] : self::GRACE_TTL_NONE;
-               $checkKeys = isset( $opts['checkKeys'] ) ? $opts['checkKeys'] : [];
-               $busyValue = isset( $opts['busyValue'] ) ? $opts['busyValue'] : null;
-               $popWindow = isset( $opts['hotTTR'] ) ? $opts['hotTTR'] : self::HOT_TTR;
-               $ageNew = isset( $opts['ageNew'] ) ? $opts['ageNew'] : self::AGE_NEW;
-               $minTime = isset( $opts['minAsOf'] ) ? $opts['minAsOf'] : self::MIN_TIMESTAMP_NONE;
+               $lowTTL = $opts['lowTTL'] ?? min( self::LOW_TTL, $ttl );
+               $lockTSE = $opts['lockTSE'] ?? self::TSE_NONE;
+               $staleTTL = $opts['staleTTL'] ?? self::STALE_TTL_NONE;
+               $graceTTL = $opts['graceTTL'] ?? self::GRACE_TTL_NONE;
+               $checkKeys = $opts['checkKeys'] ?? [];
+               $busyValue = $opts['busyValue'] ?? null;
+               $popWindow = $opts['hotTTR'] ?? self::HOT_TTR;
+               $ageNew = $opts['ageNew'] ?? self::AGE_NEW;
+               $minTime = $opts['minAsOf'] ?? self::MIN_TIMESTAMP_NONE;
                $versioned = isset( $opts['version'] );
 
                // Get a collection name to describe this class of key
@@ -1222,7 +1223,8 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
                                }
                                // Use the busy fallback value if nothing else
                                if ( $busyValue !== null ) {
-                                       $this->stats->increment( "wanobjectcache.$kClass.miss.busy" );
+                                       $miss = is_infinite( $minTime ) ? 'renew' : 'miss';
+                                       $this->stats->increment( "wanobjectcache.$kClass.$miss.busy" );
 
                                        return is_callable( $busyValue ) ? $busyValue() : $busyValue;
                                }
@@ -1267,7 +1269,8 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
                        $this->cache->changeTTL( self::MUTEX_KEY_PREFIX . $key, (int)$preCallbackTime - 60 );
                }
 
-               $this->stats->increment( "wanobjectcache.$kClass.miss.compute" );
+               $miss = is_infinite( $minTime ) ? 'renew' : 'miss';
+               $this->stats->increment( "wanobjectcache.$kClass.$miss.compute" );
 
                return $value;
        }
@@ -1381,11 +1384,12 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
                ArrayIterator $keyedIds, $ttl, callable $callback, array $opts = []
        ) {
                $valueKeys = array_keys( $keyedIds->getArrayCopy() );
-               $checkKeys = isset( $opts['checkKeys'] ) ? $opts['checkKeys'] : [];
+               $checkKeys = $opts['checkKeys'] ?? [];
+               $pcTTL = $opts['pcTTL'] ?? self::TTL_UNCACHEABLE;
 
                // Load required keys into process cache in one go
                $this->warmupCache = $this->getRawKeysForWarmup(
-                       $this->getNonProcessCachedKeys( $valueKeys, $opts ),
+                       $this->getNonProcessCachedKeys( $valueKeys, $opts, $pcTTL ),
                        $checkKeys
                );
                $this->warmupKeyMisses = 0;
@@ -1476,12 +1480,13 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
        ) {
                $idsByValueKey = $keyedIds->getArrayCopy();
                $valueKeys = array_keys( $idsByValueKey );
-               $checkKeys = isset( $opts['checkKeys'] ) ? $opts['checkKeys'] : [];
+               $checkKeys = $opts['checkKeys'] ?? [];
+               $pcTTL = $opts['pcTTL'] ?? self::TTL_UNCACHEABLE;
                unset( $opts['lockTSE'] ); // incompatible
                unset( $opts['busyValue'] ); // incompatible
 
                // Load required keys into process cache in one go
-               $keysGet = $this->getNonProcessCachedKeys( $valueKeys, $opts );
+               $keysGet = $this->getNonProcessCachedKeys( $valueKeys, $opts, $pcTTL );
                $this->warmupCache = $this->getRawKeysForWarmup( $keysGet, $checkKeys );
                $this->warmupKeyMisses = 0;
 
@@ -1597,23 +1602,23 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
        /**
         * @see BagOStuff::makeKey()
         * @param string $class Key class
-        * @param string $component [optional] Key component (starting with a key collection name)
+        * @param string|null $component [optional] Key component (starting with a key collection name)
         * @return string Colon-delimited list of $keyspace followed by escaped components of $args
         * @since 1.27
         */
        public function makeKey( $class, $component = null ) {
-               return call_user_func_array( [ $this->cache, __FUNCTION__ ], func_get_args() );
+               return $this->cache->makeKey( ...func_get_args() );
        }
 
        /**
         * @see BagOStuff::makeGlobalKey()
         * @param string $class Key class
-        * @param string $component [optional] Key component (starting with a key collection name)
+        * @param string|null $component [optional] Key component (starting with a key collection name)
         * @return string Colon-delimited list of $keyspace followed by escaped components of $args
         * @since 1.27
         */
        public function makeGlobalKey( $class, $component = null ) {
-               return call_user_func_array( [ $this->cache, __FUNCTION__ ], func_get_args() );
+               return $this->cache->makeGlobalKey( ...func_get_args() );
        }
 
        /**
@@ -2005,7 +2010,7 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
         *
         * @param array|string|bool $wrapped
         * @param float $now Unix Current timestamp (preferrably pre-query)
-        * @return array (mixed; false if absent/tombstoned/invalid, current time left)
+        * @return array (mixed; false if absent/tombstoned/malformed, current time left)
         */
        protected function unwrap( $wrapped, $now ) {
                // Check if the value is a tombstone
@@ -2023,7 +2028,7 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
                        return [ false, null ];
                }
 
-               $flags = isset( $wrapped[self::FLD_FLAGS] ) ? $wrapped[self::FLD_FLAGS] : 0;
+               $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];
@@ -2061,15 +2066,7 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
        protected function determineKeyClass( $key ) {
                $parts = explode( ':', $key );
 
-               return isset( $parts[1] ) ? $parts[1] : $parts[0]; // sanity
-       }
-
-       /**
-        * @return float UNIX timestamp
-        * @codeCoverageIgnore
-        */
-       protected function getCurrentTime() {
-               return microtime( true );
+               return $parts[1] ?? $parts[0]; // sanity
        }
 
        /**
@@ -2108,12 +2105,12 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
 
        /**
         * @param string $group
-        * @return HashBagOStuff
+        * @return MapCacheLRU
         */
        protected function getProcessCache( $group ) {
                if ( !isset( $this->processCaches[$group] ) ) {
                        list( , $n ) = explode( ':', $group );
-                       $this->processCaches[$group] = new HashBagOStuff( [ 'maxKeys' => (int)$n ] );
+                       $this->processCaches[$group] = new MapCacheLRU( (int)$n );
                }
 
                return $this->processCaches[$group];
@@ -2122,15 +2119,16 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
        /**
         * @param array $keys
         * @param array $opts
+        * @param int $pcTTL
         * @return array List of keys
         */
-       private function getNonProcessCachedKeys( array $keys, array $opts ) {
+       private function getNonProcessCachedKeys( array $keys, array $opts, $pcTTL ) {
                $keysFound = [];
                if ( isset( $opts['pcTTL'] ) && $opts['pcTTL'] > 0 && $this->callbackDepth == 0 ) {
-                       $pcGroup = isset( $opts['pcGroup'] ) ? $opts['pcGroup'] : self::PC_PRIMARY;
+                       $pcGroup = $opts['pcGroup'] ?? self::PC_PRIMARY;
                        $procCache = $this->getProcessCache( $pcGroup );
                        foreach ( $keys as $key ) {
-                               if ( $procCache->get( $key ) !== false ) {
+                               if ( $procCache->has( $key, $pcTTL ) ) {
                                        $keysFound[] = $key;
                                }
                        }
@@ -2173,4 +2171,21 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
 
                return $warmupCache;
        }
+
+       /**
+        * @return float UNIX timestamp
+        * @codeCoverageIgnore
+        */
+       protected function getCurrentTime() {
+               return $this->wallClockOverride ?: microtime( true );
+       }
+
+       /**
+        * @param float|null &$time Mock UNIX timestamp for testing
+        * @codeCoverageIgnore
+        */
+       public function setMockTime( &$time ) {
+               $this->wallClockOverride =& $time;
+               $this->cache->setMockTime( $time );
+       }
 }
index 14737b1..e4ab95c 100644 (file)
@@ -92,12 +92,8 @@ class WANObjectCacheReaper implements LoggerAwareInterface {
                        throw new UnexpectedValueException( "No channel specified." );
                }
 
-               $this->initialStartWindow = isset( $params['initialStartWindow'] )
-                       ? $params['initialStartWindow']
-                       : 3600;
-               $this->logger = isset( $params['logger'] )
-                       ? $params['logger']
-                       : new NullLogger();
+               $this->initialStartWindow = $params['initialStartWindow'] ?? 3600;
+               $this->logger = $params['logger'] ?? new NullLogger();
        }
 
        public function setLogger( LoggerInterface $logger ) {
index 8b21ede..45179cc 100644 (file)
@@ -43,6 +43,8 @@ class ChronologyProtector implements LoggerAwareInterface {
        protected $key;
        /** @var string Hash of client parameters */
        protected $clientId;
+       /** @var string[] Map of client information fields for logging */
+       protected $clientLogInfo;
        /** @var int|null Expected minimum index of the last write to the position store */
        protected $waitForPosIndex;
        /** @var int Max seconds to wait on positions to appear */
@@ -64,21 +66,30 @@ class ChronologyProtector implements LoggerAwareInterface {
        /** @var int Seconds to store positions */
        const POSITION_TTL = 60;
        /** @var int Seconds to store position write index cookies (safely less than POSITION_TTL) */
-       const POSITION_COOKIE_TTL = 60;
+       const POSITION_COOKIE_TTL = 10;
        /** @var int Max time to wait for positions to appear */
        const POS_STORE_WAIT_TIMEOUT = 5;
 
        /**
         * @param BagOStuff $store
-        * @param array[] $client Map of (ip: <IP>, agent: <user-agent>)
+        * @param array[] $client Map of (ip: <IP>, agent: <user-agent> [, clientId: <hash>] )
         * @param int|null $posIndex Write counter index [optional]
         * @since 1.27
         */
        public function __construct( BagOStuff $store, array $client, $posIndex = null ) {
                $this->store = $store;
-               $this->clientId = md5( $client['ip'] . "\n" . $client['agent'] );
+               $this->clientId = isset( $client['clientId'] )
+                       ? $client['clientId']
+                       : md5( $client['ip'] . "\n" . $client['agent'] );
                $this->key = $store->makeGlobalKey( __CLASS__, $this->clientId, 'v2' );
                $this->waitForPosIndex = $posIndex;
+
+               $this->clientLogInfo = [
+                       'clientIP' => $client['ip'],
+                       'clientAgent' => $client['agent'],
+                       'clientId' => $client['clientId'] ?? null
+               ];
+
                $this->logger = new NullLogger();
        }
 
@@ -86,6 +97,14 @@ class ChronologyProtector implements LoggerAwareInterface {
                $this->logger = $logger;
        }
 
+       /**
+        * @return string Client ID hash
+        * @since 1.32
+        */
+       public function getClientId() {
+               return $this->clientId;
+       }
+
        /**
         * @param bool $enabled Whether to no-op all method calls
         * @since 1.27
@@ -298,7 +317,7 @@ class ChronologyProtector implements LoggerAwareInterface {
                                                [
                                                        'cpPosIndex' => $this->waitForPosIndex,
                                                        'waitTimeMs' => $waitedMs
-                                               ]
+                                               ] + $this->clientLogInfo
                                        );
                                } else {
                                        $this->logger->warning(
@@ -307,7 +326,7 @@ class ChronologyProtector implements LoggerAwareInterface {
                                                        'cpPosIndex' => $this->waitForPosIndex,
                                                        'indexReached' => $indexReached,
                                                        'waitTimeMs' => $waitedMs
-                                               ]
+                                               ] + $this->clientLogInfo
                                        );
                                }
                        } else {
@@ -330,7 +349,7 @@ class ChronologyProtector implements LoggerAwareInterface {
         */
        protected function mergePositions( $curValue, array $shutdownPositions, &$cpIndex = null ) {
                /** @var DBMasterPos[] $curPositions */
-               $curPositions = isset( $curValue['positions'] ) ? $curValue['positions'] : [];
+               $curPositions = $curValue['positions'] ?? [];
                // Use the newest positions for each DB master
                foreach ( $shutdownPositions as $db => $pos ) {
                        if (
@@ -342,7 +361,7 @@ class ChronologyProtector implements LoggerAwareInterface {
                        }
                }
 
-               $cpIndex = isset( $curValue['writeIndex'] ) ? $curValue['writeIndex'] : 0;
+               $cpIndex = $curValue['writeIndex'] ?? 0;
 
                return [
                        'positions' => $curPositions,
index 9de16c4..7cb0604 100644 (file)
@@ -33,7 +33,7 @@ class DBConnRef implements IDatabase {
                $this->lb = $lb;
                if ( $conn instanceof Database ) {
                        $this->conn = $conn; // live handle
-               } elseif ( count( $conn ) >= 4 && $conn[self::FLD_DOMAIN] !== false ) {
+               } elseif ( is_array( $conn ) && count( $conn ) >= 4 && $conn[self::FLD_DOMAIN] !== false ) {
                        $this->params = $conn;
                } else {
                        throw new InvalidArgumentException( "Missing lazy connection arguments." );
@@ -46,7 +46,7 @@ class DBConnRef implements IDatabase {
                        $this->conn = $this->lb->getConnection( $db, $groups, $wiki, $flags );
                }
 
-               return call_user_func_array( [ $this->conn, $name ], $arguments );
+               return $this->conn->$name( ...$arguments );
        }
 
        public function getServerInfo() {
@@ -167,6 +167,9 @@ class DBConnRef implements IDatabase {
                return $this->__call( __FUNCTION__, func_get_args() );
        }
 
+       /**
+        * @codeCoverageIgnore
+        */
        public function getWikiID() {
                return $this->getDomainID();
        }
@@ -284,6 +287,12 @@ class DBConnRef implements IDatabase {
                return $this->__call( __FUNCTION__, func_get_args() );
        }
 
+       public function lockForUpdate(
+               $table, $conds = '', $fname = __METHOD__, $options = [], $join_conds = []
+       ) {
+               return $this->__call( __FUNCTION__, func_get_args() );
+       }
+
        public function fieldExists( $table, $field, $fname = __METHOD__ ) {
                return $this->__call( __FUNCTION__, func_get_args() );
        }
@@ -639,4 +648,8 @@ class DBConnRef implements IDatabase {
        }
 }
 
+/**
+ * @since 1.22
+ * @deprecated since 1.29
+ */
 class_alias( DBConnRef::class, 'DBConnRef' );
index aeda5b9..4070a02 100644 (file)
@@ -287,7 +287,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
        const STATUS_TRX_NONE = 3;
 
        /**
-        * @note: exceptions for missing libraries/drivers should be thrown in initConnection()
+        * @note exceptions for missing libraries/drivers should be thrown in initConnection()
         * @param array $params Parameters passed from Database::factory()
         */
        protected function __construct( array $params ) {
@@ -315,9 +315,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
 
                $this->sessionVars = $params['variables'];
 
-               $this->srvCache = isset( $params['srvCache'] )
-                       ? $params['srvCache']
-                       : new HashBagOStuff();
+               $this->srvCache = $params['srvCache'] ?? new HashBagOStuff();
 
                $this->profiler = $params['profiler'];
                $this->trxProfiler = $params['trxProfiler'];
@@ -420,29 +418,27 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
         * @since 1.18
         */
        final public static function factory( $dbType, $p = [], $connect = self::NEW_CONNECTED ) {
-               $class = self::getClass( $dbType, isset( $p['driver'] ) ? $p['driver'] : null );
+               $class = self::getClass( $dbType, $p['driver'] ?? null );
 
                if ( class_exists( $class ) && is_subclass_of( $class, IDatabase::class ) ) {
                        // Resolve some defaults for b/c
-                       $p['host'] = isset( $p['host'] ) ? $p['host'] : false;
-                       $p['user'] = isset( $p['user'] ) ? $p['user'] : false;
-                       $p['password'] = isset( $p['password'] ) ? $p['password'] : false;
-                       $p['dbname'] = isset( $p['dbname'] ) ? $p['dbname'] : false;
-                       $p['flags'] = isset( $p['flags'] ) ? $p['flags'] : 0;
-                       $p['variables'] = isset( $p['variables'] ) ? $p['variables'] : [];
-                       $p['tablePrefix'] = isset( $p['tablePrefix'] ) ? $p['tablePrefix'] : '';
-                       $p['schema'] = isset( $p['schema'] ) ? $p['schema'] : '';
-                       $p['cliMode'] = isset( $p['cliMode'] )
-                               ? $p['cliMode']
-                               : ( PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg' );
-                       $p['agent'] = isset( $p['agent'] ) ? $p['agent'] : '';
+                       $p['host'] = $p['host'] ?? false;
+                       $p['user'] = $p['user'] ?? false;
+                       $p['password'] = $p['password'] ?? false;
+                       $p['dbname'] = $p['dbname'] ?? false;
+                       $p['flags'] = $p['flags'] ?? 0;
+                       $p['variables'] = $p['variables'] ?? [];
+                       $p['tablePrefix'] = $p['tablePrefix'] ?? '';
+                       $p['schema'] = $p['schema'] ?? '';
+                       $p['cliMode'] = $p['cliMode'] ?? ( PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg' );
+                       $p['agent'] = $p['agent'] ?? '';
                        if ( !isset( $p['connLogger'] ) ) {
                                $p['connLogger'] = new NullLogger();
                        }
                        if ( !isset( $p['queryLogger'] ) ) {
                                $p['queryLogger'] = new NullLogger();
                        }
-                       $p['profiler'] = isset( $p['profiler'] ) ? $p['profiler'] : null;
+                       $p['profiler'] = $p['profiler'] ?? null;
                        if ( !isset( $p['trxProfiler'] ) ) {
                                $p['trxProfiler'] = new TransactionProfiler();
                        }
@@ -1169,27 +1165,21 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
 
                if ( $ret === false ) {
                        if ( $this->trxLevel ) {
-                               if ( !$this->wasKnownStatementRollbackError() ) {
-                                       # Either the query was aborted or all queries after BEGIN where aborted.
-                                       if ( $this->explicitTrxActive() || $priorWritesPending ) {
-                                               # 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
-                                       } else {
-                                               # Nothing prior was there to lose from the transaction,
-                                               # so just roll it back.
-                                               $this->rollback( __METHOD__ . " ($fname)", self::FLUSHING_INTERNAL );
-                                       }
-                                       $this->trxStatusIgnoredCause = null;
-                               } else {
+                               if ( $this->wasKnownStatementRollbackError() ) {
                                        # 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.
+                                       # But log the cause so we can log a deprecation notice if a caller actually
+                                       # does ignore it.
                                        $this->trxStatusIgnoredCause = [ $lastError, $lastErrno, $fname ];
+                               } else {
+                                       # 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->trxStatusIgnoredCause = null;
                                }
                        }
 
@@ -1224,13 +1214,13 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
 
                $startTime = microtime( true );
                if ( $this->profiler ) {
-                       call_user_func( [ $this->profiler, 'profileIn' ], $queryProf );
+                       $this->profiler->profileIn( $queryProf );
                }
                $this->affectedRowCount = null;
                $ret = $this->doQuery( $commentedSql );
                $this->affectedRowCount = $this->affectedRows();
                if ( $this->profiler ) {
-                       call_user_func( [ $this->profiler, 'profileOut' ], $queryProf );
+                       $this->profiler->profileOut( $queryProf );
                }
                $queryRuntime = max( microtime( true ) - $startTime, 0.0 );
 
@@ -1722,7 +1712,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
 
                if ( isset( $options['LIMIT'] ) ) {
                        $sql = $this->limitResult( $sql, $options['LIMIT'],
-                               isset( $options['OFFSET'] ) ? $options['OFFSET'] : false );
+                               $options['OFFSET'] ?? false );
                }
                $sql = "$sql $postLimitTail";
 
@@ -1875,7 +1865,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                        if ( !$var ) {
                                $column = null;
                        } elseif ( count( $var ) == 1 ) {
-                               $column = isset( $var[0] ) ? $var[0] : reset( $var );
+                               $column = $var[0] ?? reset( $var );
                        } else {
                                throw new DBUnexpectedError( $this, __METHOD__ . ': got multiple columns.' );
                        }
@@ -1886,6 +1876,22 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                return $column;
        }
 
+       public function lockForUpdate(
+               $table, $conds = '', $fname = __METHOD__, $options = [], $join_conds = []
+       ) {
+               if ( !$this->trxLevel && !$this->getFlag( self::DBO_TRX ) ) {
+                       throw new DBUnexpectedError(
+                               $this,
+                               __METHOD__ . ': no transaction is active nor is DBO_TRX set'
+                       );
+               }
+
+               $options = (array)$options;
+               $options[] = 'FOR UPDATE';
+
+               return $this->selectRowCount( $table, '*', $conds, $fname, $options, $join_conds );
+       }
+
        /**
         * Removes most variables from an SQL query and replaces them with X or N for numbers.
         * It's only slightly flawed. Don't use for anything important.
@@ -1935,18 +1941,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                }
        }
 
-       public function tableExists( $table, $fname = __METHOD__ ) {
-               $tableRaw = $this->tableName( $table, 'raw' );
-               if ( isset( $this->sessionTempTables[$tableRaw] ) ) {
-                       return true; // already known to exist
-               }
-
-               $table = $this->tableName( $table );
-               $ignoreErrors = true;
-               $res = $this->query( "SELECT 1 FROM $table LIMIT 1", $fname, $ignoreErrors );
-
-               return (bool)$res;
-       }
+       abstract public function tableExists( $table, $fname = __METHOD__ );
 
        public function indexUnique( $table, $index ) {
                $indexInfo = $this->indexInfo( $table, $index );
@@ -2583,9 +2578,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
         * @return string
         */
        protected function indexName( $index ) {
-               return isset( $this->indexAliases[$index] )
-                       ? $this->indexAliases[$index]
-                       : $index;
+               return $this->indexAliases[$index] ?? $index;
        }
 
        public function addQuotes( $s ) {
@@ -3138,8 +3131,8 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                // $conds. Then union them together (using UNION ALL, because the
                // product *should* already be distinct).
                $orderBy = $this->makeOrderBy( $options );
-               $limit = isset( $options['LIMIT'] ) ? $options['LIMIT'] : null;
-               $offset = isset( $options['OFFSET'] ) ? $options['OFFSET'] : false;
+               $limit = $options['LIMIT'] ?? null;
+               $offset = $options['OFFSET'] ?? false;
                $all = empty( $options['NOTALL'] ) && !in_array( 'NOTALL', $options );
                if ( !$this->unionSupportsOrderAndLimit() ) {
                        unset( $options['ORDER BY'], $options['LIMIT'], $options['OFFSET'] );
@@ -3242,7 +3235,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                $e = null;
                do {
                        try {
-                               $retVal = call_user_func_array( $function, $args );
+                               $retVal = $function( ...$args );
                                break;
                        } catch ( DBQueryError $e ) {
                                if ( $this->wasDeadlock() ) {
@@ -3322,7 +3315,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                        // No transaction is active nor will start implicitly, so make one for this callback
                        $this->startAtomic( __METHOD__, self::ATOMIC_CANCELABLE );
                        try {
-                               call_user_func( $callback, $this );
+                               $callback( $this );
                                $this->endAtomic( __METHOD__ );
                        } catch ( Exception $e ) {
                                $this->cancelAtomic( __METHOD__ );
@@ -3448,16 +3441,11 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                        $this->trxIdleCallbacks = []; // consumed (and recursion guard)
                        $this->trxEndCallbacks = []; // consumed (recursion guard)
                        foreach ( $callbacks as $callback ) {
+                               ++$count;
+                               list( $phpCallback ) = $callback;
+                               $this->clearFlag( self::DBO_TRX ); // make each query its own transaction
                                try {
-                                       ++$count;
-                                       list( $phpCallback ) = $callback;
-                                       $this->clearFlag( self::DBO_TRX ); // make each query its own transaction
                                        call_user_func( $phpCallback, $trigger, $this );
-                                       if ( $autoTrx ) {
-                                               $this->setFlag( self::DBO_TRX ); // restore automatic begin()
-                                       } else {
-                                               $this->clearFlag( self::DBO_TRX ); // restore auto-commit
-                                       }
                                } catch ( Exception $ex ) {
                                        call_user_func( $this->errorLogger, $ex );
                                        $e = $e ?: $ex;
@@ -3466,6 +3454,12 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                                        if ( $this->trxLevel() ) {
                                                $this->rollback( __METHOD__, self::FLUSHING_INTERNAL );
                                        }
+                               } finally {
+                                       if ( $autoTrx ) {
+                                               $this->setFlag( self::DBO_TRX ); // restore automatic begin()
+                                       } else {
+                                               $this->clearFlag( self::DBO_TRX ); // restore auto-commit
+                                       }
                                }
                        }
                } while ( count( $this->trxIdleCallbacks ) );
@@ -3497,9 +3491,9 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                                try {
                                        ++$count;
                                        list( $phpCallback ) = $callback;
-                                       call_user_func( $phpCallback, $this );
+                                       $phpCallback( $this );
                                } catch ( Exception $ex ) {
-                                       call_user_func( $this->errorLogger, $ex );
+                                       $this->errorLogger( $ex );
                                        $e = $e ?: $ex;
                                }
                        }
@@ -3533,7 +3527,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                        try {
                                $phpCallback( $trigger, $this );
                        } catch ( Exception $ex ) {
-                               call_user_func( $this->errorLogger, $ex );
+                               ( $this->errorLogger )( $ex );
                                $e = $e ?: $ex;
                        }
                }
@@ -3734,7 +3728,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
        ) {
                $sectionId = $this->startAtomic( $fname, $cancelable );
                try {
-                       $res = call_user_func_array( $callback, [ $this, $fname ] );
+                       $res = $callback( $this, $fname );
                } catch ( Exception $e ) {
                        $this->cancelAtomic( $fname, $sectionId );
 
@@ -3850,9 +3844,11 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                $this->assertOpen();
 
                $this->runOnTransactionPreCommitCallbacks();
+
                $writeTime = $this->pendingWriteQueryDuration( self::ESTIMATE_DB_APPLY );
                $this->doCommit( $fname );
                $this->trxStatus = self::STATUS_TRX_NONE;
+
                if ( $this->trxDoneWrites ) {
                        $this->lastWriteTime = microtime( true );
                        $this->trxProfiler->transactionWritingOut(
@@ -3900,14 +3896,18 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                        // Avoid fatals if close() was called
                        $this->assertOpen();
 
+                       $writeTime = $this->pendingWriteQueryDuration( self::ESTIMATE_DB_APPLY );
                        $this->doRollback( $fname );
                        $this->trxStatus = self::STATUS_TRX_NONE;
                        $this->trxAtomicLevels = [];
+
                        if ( $this->trxDoneWrites ) {
                                $this->trxProfiler->transactionWritingOut(
                                        $this->server,
                                        $this->dbName,
-                                       $this->trxShortId
+                                       $this->trxShortId,
+                                       $writeTime,
+                                       $this->trxWriteAffectedRows
                                );
                        }
                }
@@ -4135,7 +4135,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
         * @see WANObjectCache::getWithSetCallback()
         *
         * @param IDatabase $db1
-        * @param IDatabase $db2 [optional]
+        * @param IDatabase|null $db2 [optional]
         * @return array Map of values:
         *   - lag: highest lag of any of the DBs or false on error (e.g. replication stopped)
         *   - since: oldest UNIX timestamp of any of the DB lag estimates
@@ -4260,7 +4260,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                                $cmd = $this->replaceVars( $cmd );
 
                                if ( $inputCallback ) {
-                                       $callbackResult = call_user_func( $inputCallback, $cmd );
+                                       $callbackResult = $inputCallback( $cmd );
 
                                        if ( is_string( $callbackResult ) || !$callbackResult ) {
                                                $cmd = $callbackResult;
@@ -4271,7 +4271,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                                        $res = $this->query( $cmd, $fname );
 
                                        if ( $resultCallback ) {
-                                               call_user_func( $resultCallback, $res, $this );
+                                               $resultCallback( $res, $this );
                                        }
 
                                        if ( false === $res ) {
@@ -4638,5 +4638,12 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
        }
 }
 
-class_alias( Database::class, 'DatabaseBase' ); // b/c for old name
-class_alias( Database::class, 'Database' ); // b/c global alias
+/**
+ * @deprecated since 1.28
+ */
+class_alias( Database::class, 'DatabaseBase' );
+
+/**
+ * @deprecated since 1.29
+ */
+class_alias( Database::class, 'Database' );
index ef6600b..602b15c 100644 (file)
@@ -182,7 +182,7 @@ class DatabaseDomain {
                for ( $i = 0; $i < $length; ++$i ) {
                        $char = $encoded[$i];
                        if ( $char === '?' ) {
-                               $nextChar = isset( $encoded[$i + 1] ) ? $encoded[$i + 1] : null;
+                               $nextChar = $encoded[$i + 1] ?? null;
                                if ( $nextChar === 'h' ) {
                                        $decoded .= '-';
                                        ++$i;
index 4c187f2..fed6f14 100644 (file)
@@ -1294,9 +1294,7 @@ class DatabaseMssql extends Database {
                        $this->populateColumnCaches();
                }
 
-               return isset( $this->binaryColumnCache[$tableRaw] )
-                       ? $this->binaryColumnCache[$tableRaw]
-                       : [];
+               return $this->binaryColumnCache[$tableRaw] ?? [];
        }
 
        /**
@@ -1311,9 +1309,7 @@ class DatabaseMssql extends Database {
                        $this->populateColumnCaches();
                }
 
-               return isset( $this->bitColumnCache[$tableRaw] )
-                       ? $this->bitColumnCache[$tableRaw]
-                       : [];
+               return $this->bitColumnCache[$tableRaw] ?? [];
        }
 
        private function populateColumnCaches() {
@@ -1418,4 +1414,7 @@ class DatabaseMssql extends Database {
        }
 }
 
+/**
+ * @deprecated since 1.29
+ */
 class_alias( DatabaseMssql::class, 'DatabaseMssql' );
index 0472139..3ecfca9 100644 (file)
@@ -96,12 +96,8 @@ abstract class DatabaseMysqlBase extends Database {
         * @param array $params
         */
        function __construct( array $params ) {
-               $this->lagDetectionMethod = isset( $params['lagDetectionMethod'] )
-                       ? $params['lagDetectionMethod']
-                       : 'Seconds_Behind_Master';
-               $this->lagDetectionOptions = isset( $params['lagDetectionOptions'] )
-                       ? $params['lagDetectionOptions']
-                       : [];
+               $this->lagDetectionMethod = $params['lagDetectionMethod'] ?? 'Seconds_Behind_Master';
+               $this->lagDetectionOptions = $params['lagDetectionOptions'] ?? [];
                $this->useGTIDs = !empty( $params['useGTIDs' ] );
                foreach ( [ 'KeyPath', 'CertPath', 'CAFile', 'CAPath', 'Ciphers' ] as $name ) {
                        $var = "ssl{$name}";
@@ -109,7 +105,7 @@ abstract class DatabaseMysqlBase extends Database {
                                $this->$var = $params[$var];
                        }
                }
-               $this->sqlMode = isset( $params['sqlMode'] ) ? $params['sqlMode'] : '';
+               $this->sqlMode = $params['sqlMode'] ?? '';
                $this->utf8Mode = !empty( $params['utf8Mode'] );
                $this->insertSelectIsSafe = isset( $params['insertSelectIsSafe'] )
                        ? (bool)$params['insertSelectIsSafe'] : null;
@@ -376,7 +372,7 @@ abstract class DatabaseMysqlBase extends Database {
 
                // Unfortunately, mysql_num_rows does not reset the last errno.
                // We are not checking for any errors here, since
-               // these are no errors mysql_num_rows can cause.
+               // there are no errors mysql_num_rows can cause.
                // See https://dev.mysql.com/doc/refman/5.0/en/mysql-fetch-row.html.
                // See https://phabricator.wikimedia.org/T44430
                return $n;
@@ -502,7 +498,7 @@ abstract class DatabaseMysqlBase extends Database {
        /**
         * Returns the text of the error message from previous MySQL operation
         *
-        * @param resource $conn Raw connection
+        * @param resource|null $conn Raw connection
         * @return string
         */
        abstract protected function mysqlError( $conn = null );
@@ -1461,7 +1457,7 @@ abstract class DatabaseMysqlBase extends Database {
        /**
         * List all tables on the database
         *
-        * @param string $prefix Only show tables with this prefix, e.g. mw_
+        * @param string|null $prefix Only show tables with this prefix, e.g. mw_
         * @param string $fname Calling function name
         * @return array
         */
@@ -1515,7 +1511,7 @@ abstract class DatabaseMysqlBase extends Database {
        /**
         * Lists VIEWs in the database
         *
-        * @param string $prefix Only show VIEWs with this prefix, eg.
+        * @param string|null $prefix Only show VIEWs with this prefix, eg.
         * unit_test_, or $wgDBprefix. Default: null, would return all views.
         * @param string $fname Name of calling function
         * @return array
@@ -1551,7 +1547,7 @@ abstract class DatabaseMysqlBase extends Database {
         * Differentiates between a TABLE and a VIEW.
         *
         * @param string $name Name of the TABLE/VIEW to test
-        * @param string $prefix
+        * @param string|null $prefix
         * @return bool
         * @since 1.22
         */
@@ -1580,4 +1576,7 @@ abstract class DatabaseMysqlBase extends Database {
        }
 }
 
+/**
+ * @deprecated since 1.29
+ */
 class_alias( DatabaseMysqlBase::class, 'DatabaseMysqlBase' );
index 0a5450c..6d9dabd 100644 (file)
@@ -77,7 +77,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 );
+                       $hostAndSocket = explode( ':', $realServer, 2 );
                        $realServer = $hostAndSocket[0];
                        $socket = $hostAndSocket[1];
                }
@@ -296,7 +296,7 @@ class DatabaseMysqli extends DatabaseMysqlBase {
        }
 
        /**
-        * @param mysqli $conn Optional connection object
+        * @param mysqli|null $conn Optional connection object
         * @return string
         */
        protected function mysqlError( $conn = null ) {
@@ -341,4 +341,7 @@ class DatabaseMysqli extends DatabaseMysqlBase {
        }
 }
 
+/**
+ * @deprecated since 1.29
+ */
 class_alias( DatabaseMysqli::class, 'DatabaseMysqli' );
index 9610839..a043cd6 100644 (file)
@@ -54,10 +54,8 @@ class DatabasePostgres extends Database {
         *   - keywordTableMap : Map of reserved table names to alternative table names to use
         */
        public function __construct( array $params ) {
-               $this->port = isset( $params['port'] ) ? $params['port'] : false;
-               $this->keywordTableMap = isset( $params['keywordTableMap'] )
-                       ? $params['keywordTableMap']
-                       : [];
+               $this->port = $params['port'] ?? false;
+               $this->keywordTableMap = $params['keywordTableMap'] ?? [];
 
                parent::__construct( $params );
        }
@@ -710,7 +708,7 @@ __INDEXATTR__;
         * @return string Value of $name or remapped name if $name is a reserved keyword
         */
        public function remappedTableName( $name ) {
-               return isset( $this->keywordTableMap[$name] ) ? $this->keywordTableMap[$name] : $name;
+               return $this->keywordTableMap[$name] ?? $name;
        }
 
        /**
@@ -1444,4 +1442,7 @@ SQL;
        }
 }
 
+/**
+ * @deprecated since 1.29
+ */
 class_alias( DatabasePostgres::class, 'DatabasePostgres' );
index a6a153a..b0fd12a 100644 (file)
@@ -220,10 +220,6 @@ class DatabaseSqlite extends Database {
                return false;
        }
 
-       public function selectDB( $db ) {
-               return false; // doesn't make sense
-       }
-
        /**
         * @return string SQLite DB file path
         * @since 1.25
@@ -496,7 +492,7 @@ class DatabaseSqlite extends Database {
                }
                $e = $this->conn->errorInfo();
 
-               return isset( $e[2] ) ? $e[2] : '';
+               return $e[2] ?? '';
        }
 
        /**
@@ -519,6 +515,19 @@ class DatabaseSqlite extends Database {
                return $this->lastAffectedRowCount;
        }
 
+       function tableExists( $table, $fname = __METHOD__ ) {
+               $tableRaw = $this->tableName( $table, 'raw' );
+               if ( isset( $this->sessionTempTables[$tableRaw] ) ) {
+                       return true; // already known to exist
+               }
+
+               $encTable = $this->addQuotes( $tableRaw );
+               $res = $this->query(
+                       "SELECT 1 FROM sqlite_master WHERE type='table' AND name=$encTable" );
+
+               return $res->numRows() ? true : false;
+       }
+
        /**
         * Returns information about an index
         * Returns false if the index does not exist
@@ -865,7 +874,7 @@ class DatabaseSqlite extends Database {
                $args = func_get_args();
                $function = array_shift( $args );
 
-               return call_user_func_array( $function, $args );
+               return $function( ...$args );
        }
 
        /**
@@ -1023,7 +1032,7 @@ class DatabaseSqlite extends Database {
        /**
         * List all tables on the database
         *
-        * @param string $prefix Only show tables with this prefix, e.g. mw_
+        * @param string|null $prefix Only show tables with this prefix, e.g. mw_
         * @param string $fname Calling function name
         *
         * @return array
@@ -1106,4 +1115,7 @@ class DatabaseSqlite extends Database {
        }
 }
 
+/**
+ * @deprecated since 1.29
+ */
 class_alias( DatabaseSqlite::class, 'DatabaseSqlite' );
index ca3fd52..61788e1 100644 (file)
@@ -32,7 +32,7 @@ use stdClass;
 /**
  * Basic database interface for live and lazy-loaded relation database handles
  *
- * @note: IDatabase and DBConnRef should be updated to reflect any changes
+ * @note IDatabase and DBConnRef should be updated to reflect any changes
  * @ingroup Database
  */
 interface IDatabase {
@@ -166,14 +166,14 @@ interface IDatabase {
 
        /**
         * Get/set the table prefix.
-        * @param string $prefix The table prefix to set, or omitted to leave it unchanged.
+        * @param string|null $prefix The table prefix to set, or omitted to leave it unchanged.
         * @return string The previous table prefix.
         */
        public function tablePrefix( $prefix = null );
 
        /**
         * Get/set the db schema.
-        * @param string $schema The database schema to set, or omitted to leave it unchanged.
+        * @param string|null $schema The database schema to set, or omitted to leave it unchanged.
         * @return string The previous db schema.
         */
        public function dbSchema( $schema = null );
@@ -182,7 +182,7 @@ interface IDatabase {
         * Get properties passed down from the server info array of the load
         * balancer.
         *
-        * @param string $name The entry of the info array to get, or null to get the
+        * @param string|null $name The entry of the info array to get, or null to get the
         *   whole array
         *
         * @return array|mixed|null
@@ -195,7 +195,7 @@ interface IDatabase {
         * parameters, the member with the given name is set to the given value.
         *
         * @param string $name
-        * @param array $value
+        * @param array|null $value
         */
        public function setLBInfo( $name, $value = null );
 
@@ -848,6 +848,21 @@ interface IDatabase {
                $tables, $var = '*', $conds = '', $fname = __METHOD__, $options = [], $join_conds = []
        );
 
+       /**
+        * Lock all rows meeting the given conditions/options FOR UPDATE
+        *
+        * @param array|string $table Table names
+        * @param array|string $conds Filters on the table
+        * @param string $fname Function name for profiling
+        * @param array $options Options for select ("FOR UPDATE" is added automatically)
+        * @param array $join_conds Join conditions
+        * @return int Number of matching rows found (and locked)
+        * @since 1.32
+        */
+       public function lockForUpdate(
+               $table, $conds = '', $fname = __METHOD__, $options = [], $join_conds = []
+       );
+
        /**
         * Determines whether a field exists in a table
         *
@@ -1485,7 +1500,7 @@ interface IDatabase {
         *
         * This is useful for combining cooperative locks and DB transactions.
         *
-        * @note: do not assume that *other* IDatabase instances will be AUTOCOMMIT mode
+        * @note do not assume that *other* IDatabase instances will be AUTOCOMMIT mode
         *
         * The callback takes the following arguments:
         *   - How the transaction ended (IDatabase::TRIGGER_COMMIT or IDatabase::TRIGGER_ROLLBACK)
@@ -1520,7 +1535,7 @@ interface IDatabase {
         *
         * Updates will execute in the order they were enqueued.
         *
-        * @note: do not assume that *other* IDatabase instances will be AUTOCOMMIT mode
+        * @note do not assume that *other* IDatabase instances will be AUTOCOMMIT mode
         *
         * The callback takes the following arguments:
         *   - How the transaction ended (IDatabase::TRIGGER_COMMIT or IDatabase::TRIGGER_IDLE)
@@ -1608,7 +1623,7 @@ interface IDatabase {
         *   - The failures are from contention solvable via onTransactionPreCommitOrIdle()
         *   - The failures are deadlocks; the RDBMs usually discard the whole transaction
         *
-        * @note: callers must use additional measures for situations involving two or more
+        * @note callers must use additional measures for situations involving two or more
         *   (peer) transactions (e.g. updating two database servers at once). The transaction
         *   and savepoint logic of this method only applies to this specific IDatabase instance.
         *
@@ -1687,7 +1702,7 @@ interface IDatabase {
         * corresponding startAtomic() implicitly started a transaction, that
         * transaction is rolled back.
         *
-        * @note: callers must use additional measures for situations involving two or more
+        * @note callers must use additional measures for situations involving two or more
         *   (peer) transactions (e.g. updating two database servers at once). The transaction
         *   and savepoint logic of startAtomic() are bound to specific IDatabase instances.
         *
@@ -1698,7 +1713,7 @@ interface IDatabase {
         * @since 1.31
         * @see IDatabase::startAtomic
         * @param string $fname
-        * @param AtomicSectionIdentifier $sectionId Section ID from startAtomic();
+        * @param AtomicSectionIdentifier|null $sectionId Section ID from startAtomic();
         *   passing this enables cancellation of unclosed nested sections [optional]
         * @throws DBError
         */
@@ -1882,7 +1897,7 @@ interface IDatabase {
         * The result is unquoted, and needs to be passed through addQuotes()
         * before it can be included in raw SQL.
         *
-        * @param string|int $ts
+        * @param string|int|null $ts
         *
         * @return string
         */
@@ -2117,4 +2132,7 @@ interface IDatabase {
        public function setIndexAliases( array $aliases );
 }
 
+/**
+ * @deprecated since 1.29
+ */
 class_alias( IDatabase::class, 'IDatabase' );
index 18e3cbb..5706435 100644 (file)
@@ -183,7 +183,7 @@ interface IMaintainableDatabase extends IDatabase {
        /**
         * Lists all the VIEWs in the database
         *
-        * @param string $prefix Only show VIEWs with this prefix, eg. unit_test_
+        * @param string|null $prefix Only show VIEWs with this prefix, eg. unit_test_
         * @param string $fname Name of calling function
         * @throws RuntimeException
         * @return array
@@ -279,7 +279,7 @@ interface IMaintainableDatabase extends IDatabase {
        /**
         * List all tables on the database
         *
-        * @param string $prefix Only show tables with this prefix, e.g. mw_
+        * @param string|null $prefix Only show tables with this prefix, e.g. mw_
         * @param string $fname Calling function name
         * @throws DBError
         * @return array
index 12e59b5..aeb5d8d 100644 (file)
@@ -62,4 +62,7 @@ class FakeResultWrapper extends ResultWrapper {
        }
 }
 
+/**
+ * @deprecated since 1.29
+ */
 class_alias( FakeResultWrapper::class, 'FakeResultWrapper' );
index df354af..1355e22 100644 (file)
@@ -119,4 +119,7 @@ class ResultWrapper implements IResultWrapper {
        }
 }
 
+/**
+ * @deprecated since 1.29
+ */
 class_alias( ResultWrapper::class, 'ResultWrapper' );
index 7bc3eac..6a28e35 100644 (file)
@@ -18,4 +18,7 @@ class Blob implements IBlob {
        }
 }
 
+/**
+ * @deprecated since 1.29
+ */
 class_alias( Blob::class, 'Blob' );
index 97e03b2..aa545cd 100644 (file)
@@ -31,4 +31,7 @@ class DBAccessError extends DBUnexpectedError {
        }
 }
 
+/**
+ * @deprecated since 1.29
+ */
 class_alias( DBAccessError::class, 'DBAccessError' );
index 91d98dc..4ed2b31 100644 (file)
@@ -25,7 +25,7 @@ namespace Wikimedia\Rdbms;
  */
 class DBConnectionError extends DBExpectedError {
        /**
-        * @param IDatabase $db Object throwing the error
+        * @param IDatabase|null $db Object throwing the error
         * @param string $error Error text
         */
        public function __construct( IDatabase $db = null, $error = 'unknown error' ) {
@@ -38,4 +38,7 @@ class DBConnectionError extends DBExpectedError {
        }
 }
 
+/**
+ * @deprecated since 1.29
+ */
 class_alias( DBConnectionError::class, 'DBConnectionError' );
index aad219d..6b67b45 100644 (file)
@@ -33,7 +33,7 @@ class DBError extends RuntimeException {
 
        /**
         * Construct a database error
-        * @param IDatabase $db Object which threw the error
+        * @param IDatabase|null $db Object which threw the error
         * @param string $error A simple error message to be used for debugging
         * @param \Exception|\Throwable|null $prev Previous exception
         */
@@ -43,4 +43,7 @@ class DBError extends RuntimeException {
        }
 }
 
+/**
+ * @deprecated since 1.29
+ */
 class_alias( DBError::class, 'DBError' );
index 7e46420..73bc1f1 100644 (file)
@@ -55,4 +55,7 @@ class DBExpectedError extends DBError implements MessageSpecifier {
        }
 }
 
+/**
+ * @deprecated since 1.29
+ */
 class_alias( DBExpectedError::class, 'DBExpectedError' );
index e6870a7..4bdd8f6 100644 (file)
@@ -40,7 +40,7 @@ class DBQueryError extends DBExpectedError {
         * @param int|string $errno
         * @param string $sql
         * @param string $fname
-        * @param string $message Optional message, intended for subclases (optional)
+        * @param string|null $message Optional message, intended for subclases (optional)
         */
        public function __construct( IDatabase $db, $error, $errno, $sql, $fname, $message = null ) {
                if ( $message === null ) {
@@ -67,4 +67,7 @@ class DBQueryError extends DBExpectedError {
        }
 }
 
+/**
+ * @deprecated since 1.29
+ */
 class_alias( DBQueryError::class, 'DBQueryError' );
index 4393343..cdde1a7 100644 (file)
@@ -27,4 +27,7 @@ namespace Wikimedia\Rdbms;
 class DBReadOnlyError extends DBExpectedError {
 }
 
+/**
+ * @deprecated since 1.29
+ */
 class_alias( DBReadOnlyError::class, 'DBReadOnlyError' );
index 457431e..c5dd8ae 100644 (file)
@@ -28,4 +28,7 @@ namespace Wikimedia\Rdbms;
 class DBReplicationWaitError extends DBExpectedError {
 }
 
+/**
+ * @deprecated since 1.29
+ */
 class_alias( DBReplicationWaitError::class, 'DBReplicationWaitError' );
index 62a078c..34b4c91 100644 (file)
@@ -27,4 +27,7 @@ namespace Wikimedia\Rdbms;
 class DBTransactionError extends DBExpectedError {
 }
 
+/**
+ * @deprecated since 1.29
+ */
 class_alias( DBTransactionError::class, 'DBTransactionError' );
index d2622e1..b3f464b 100644 (file)
@@ -30,4 +30,7 @@ class DBTransactionSizeError extends DBTransactionError {
        }
 }
 
+/**
+ * @deprecated since 1.29
+ */
 class_alias( DBTransactionSizeError::class, 'DBTransactionSizeError' );
index 9c67eb5..2c506ca 100644 (file)
@@ -27,4 +27,7 @@ namespace Wikimedia\Rdbms;
 class DBUnexpectedError extends DBError {
 }
 
+/**
+ * @deprecated since 1.29
+ */
 class_alias( DBUnexpectedError::class, 'DBUnexpectedError' );
index 7918f36..48d5546 100644 (file)
@@ -32,4 +32,7 @@ interface Field {
        function isNullable();
 }
 
+/**
+ * @deprecated since 1.29
+ */
 class_alias( Field::class, 'Field' );
index 709c61e..ecaddab 100644 (file)
@@ -18,11 +18,11 @@ class MySQLField implements Field {
                $this->is_multiple = $info->multiple_key;
                $this->is_key = ( $this->is_pk || $this->is_unique || $this->is_multiple );
                $this->type = $info->type;
-               $this->binary = isset( $info->binary ) ? $info->binary : false;
-               $this->is_numeric = isset( $info->numeric ) ? $info->numeric : false;
-               $this->is_blob = isset( $info->blob ) ? $info->blob : false;
-               $this->is_unsigned = isset( $info->unsigned ) ? $info->unsigned : false;
-               $this->is_zerofill = isset( $info->zerofill ) ? $info->zerofill : false;
+               $this->binary = $info->binary ?? false;
+               $this->is_numeric = $info->numeric ?? false;
+               $this->is_blob = $info->blob ?? false;
+               $this->is_unsigned = $info->unsigned ?? false;
+               $this->is_zerofill = $info->zerofill ?? false;
        }
 
        /**
index 16d0e31..222d7d1 100644 (file)
@@ -67,6 +67,22 @@ interface ILBFactory {
         */
        public function destroy();
 
+       /**
+        * Get the local (and default) database domain ID of connection handles
+        *
+        * @see DatabaseDomain
+        * @return string Database domain ID; this specifies DB name, schema, and table prefix
+        * @since 1.32
+        */
+       public function getLocalDomainID();
+
+       /**
+        * @param DatabaseDomain|string|bool $domain Database domain
+        * @return string Value of $domain if provided or the local domain otherwise
+        * @since 1.32
+        */
+       public function resolveDomainID( $domain );
+
        /**
         * Create a new load balancer object. The resulting object will be untracked,
         * not chronology-protected, and the caller is responsible for cleaning it up.
@@ -142,9 +158,13 @@ interface ILBFactory {
         * @param int $mode One of the class SHUTDOWN_* constants
         * @param callable|null $workCallback Work to mask ChronologyProtector writes
         * @param int|null &$cpIndex Position key write counter for ChronologyProtector
+        * @param string|null &$cpClientId Client ID hash for ChronologyProtector
         */
        public function shutdown(
-               $mode = self::SHUTDOWN_CHRONPROT_SYNC, callable $workCallback = null, &$cpIndex = null
+               $mode = self::SHUTDOWN_CHRONPROT_SYNC,
+               callable $workCallback = null,
+               &$cpIndex = null,
+               &$cpClientId = null
        );
 
        /**
@@ -225,7 +245,7 @@ interface ILBFactory {
 
        /**
         * Determine if any master connection has pending/written changes from this request
-        * @param float $age How many seconds ago is "recent" [defaults to LB lag wait timeout]
+        * @param float|null $age How many seconds ago is "recent" [defaults to LB lag wait timeout]
         * @return bool
         */
        public function hasOrMadeRecentMasterChanges( $age = null );
index 7f5990d..e47e75e 100644 (file)
@@ -38,23 +38,24 @@ use LogicException;
  */
 abstract class LBFactory implements ILBFactory {
        /** @var ChronologyProtector */
-       protected $chronProt;
+       private $chronProt;
        /** @var object|string Class name or object With profileIn/profileOut methods */
-       protected $profiler;
+       private $profiler;
        /** @var TransactionProfiler */
-       protected $trxProfiler;
+       private $trxProfiler;
        /** @var LoggerInterface */
-       protected $replLogger;
+       private $replLogger;
        /** @var LoggerInterface */
-       protected $connLogger;
+       private $connLogger;
        /** @var LoggerInterface */
-       protected $queryLogger;
+       private $queryLogger;
        /** @var LoggerInterface */
-       protected $perfLogger;
+       private $perfLogger;
        /** @var callable Error logger */
-       protected $errorLogger;
+       private $errorLogger;
        /** @var callable Deprecation logger */
-       protected $deprecationLogger;
+       private $deprecationLogger;
+
        /** @var BagOStuff */
        protected $srvCache;
        /** @var BagOStuff */
@@ -64,33 +65,36 @@ abstract class LBFactory implements ILBFactory {
 
        /** @var DatabaseDomain Local domain */
        protected $localDomain;
+
        /** @var string Local hostname of the app server */
-       protected $hostname;
+       private $hostname;
        /** @var array Web request information about the client */
-       protected $requestInfo;
-
-       /** @var mixed */
-       protected $ticket;
-       /** @var string|bool String if a requested DBO_TRX transaction round is active */
-       protected $trxRoundId = false;
-       /** @var string|bool Reason all LBs are read-only or false if not */
-       protected $readOnlyReason = false;
-       /** @var callable[] */
-       protected $replicationWaitCallbacks = [];
+       private $requestInfo;
+       /** @var bool Whether this PHP instance is for a CLI script */
+       private $cliMode;
+       /** @var string Agent name for query profiling */
+       private $agent;
 
        /** @var array[] $aliases Map of (table => (dbname, schema, prefix) map) */
-       protected $tableAliases = [];
+       private $tableAliases = [];
        /** @var string[] Map of (index alias => index) */
-       protected $indexAliases = [];
-
-       /** @var bool Whether this PHP instance is for a CLI script */
-       protected $cliMode;
-       /** @var string Agent name for query profiling */
-       protected $agent;
+       private $indexAliases = [];
+       /** @var callable[] */
+       private $replicationWaitCallbacks = [];
 
+       /** @var mixed */
+       private $ticket;
+       /** @var string|bool String if a requested DBO_TRX transaction round is active */
+       private $trxRoundId = false;
        /** @var string One of the ROUND_* class constants */
        private $trxRoundStage = self::ROUND_CURSORY;
 
+       /** @var string|bool Reason all LBs are read-only or false if not */
+       protected $readOnlyReason = false;
+
+       /** @var string|null */
+       private $defaultGroup = null;
+
        const ROUND_CURSORY = 'cursory';
        const ROUND_BEGINNING = 'within-begin';
        const ROUND_COMMITTING = 'within-commit';
@@ -110,44 +114,35 @@ abstract class LBFactory implements ILBFactory {
                        $this->readOnlyReason = $conf['readOnlyReason'];
                }
 
-               $this->srvCache = isset( $conf['srvCache'] ) ? $conf['srvCache'] : new EmptyBagOStuff();
-               $this->memStash = isset( $conf['memStash'] ) ? $conf['memStash'] : new EmptyBagOStuff();
-               $this->wanCache = isset( $conf['wanCache'] )
-                       ? $conf['wanCache']
-                       : WANObjectCache::newEmpty();
+               $this->srvCache = $conf['srvCache'] ?? new EmptyBagOStuff();
+               $this->memStash = $conf['memStash'] ?? new EmptyBagOStuff();
+               $this->wanCache = $conf['wanCache'] ?? WANObjectCache::newEmpty();
 
                foreach ( self::$loggerFields as $key ) {
-                       $this->$key = isset( $conf[$key] ) ? $conf[$key] : new \Psr\Log\NullLogger();
+                       $this->$key = $conf[$key] ?? new \Psr\Log\NullLogger();
                }
-               $this->errorLogger = isset( $conf['errorLogger'] )
-                       ? $conf['errorLogger']
-                       : function ( Exception $e ) {
-                               trigger_error( get_class( $e ) . ': ' . $e->getMessage(), E_USER_WARNING );
-                       };
-               $this->deprecationLogger = isset( $conf['deprecationLogger'] )
-                       ? $conf['deprecationLogger']
-                       : function ( $msg ) {
-                               trigger_error( $msg, E_USER_DEPRECATED );
-                       };
-
-               $this->profiler = isset( $conf['profiler'] ) ? $conf['profiler'] : null;
-               $this->trxProfiler = isset( $conf['trxProfiler'] )
-                       ? $conf['trxProfiler']
-                       : new TransactionProfiler();
+               $this->errorLogger = $conf['errorLogger'] ?? function ( Exception $e ) {
+                       trigger_error( get_class( $e ) . ': ' . $e->getMessage(), E_USER_WARNING );
+               };
+               $this->deprecationLogger = $conf['deprecationLogger'] ?? function ( $msg ) {
+                       trigger_error( $msg, E_USER_DEPRECATED );
+               };
+
+               $this->profiler = $conf['profiler'] ?? null;
+               $this->trxProfiler = $conf['trxProfiler'] ?? new TransactionProfiler();
 
                $this->requestInfo = [
-                       'IPAddress' => isset( $_SERVER[ 'REMOTE_ADDR' ] ) ? $_SERVER[ 'REMOTE_ADDR' ] : '',
-                       'UserAgent' => isset( $_SERVER['HTTP_USER_AGENT'] ) ? $_SERVER['HTTP_USER_AGENT'] : '',
-                       'ChronologyProtection' => 'true',
-                       // phpcs:ignore MediaWiki.Usage.SuperGlobalsUsage.SuperGlobals -- library can't use $wgRequest
-                       'ChronologyPositionIndex' => isset( $_GET['cpPosIndex'] ) ? $_GET['cpPosIndex'] : null
+                       'IPAddress' => $_SERVER[ 'REMOTE_ADDR' ] ?? '',
+                       'UserAgent' => $_SERVER['HTTP_USER_AGENT'] ?? '',
+                       // Headers application can inject via LBFactory::setRequestInfo()
+                       'ChronologyClientId' => null, // prior $cpClientId value from LBFactory::shutdown()
+                       'ChronologyPositionIndex' => null // prior $cpIndex value from LBFactory::shutdown()
                ];
 
-               $this->cliMode = isset( $conf['cliMode'] )
-                       ? $conf['cliMode']
-                       : ( PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg' );
-               $this->hostname = isset( $conf['hostname'] ) ? $conf['hostname'] : gethostname();
-               $this->agent = isset( $conf['agent'] ) ? $conf['agent'] : '';
+               $this->cliMode = $conf['cliMode'] ?? ( PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg' );
+               $this->hostname = $conf['hostname'] ?? gethostname();
+               $this->agent = $conf['agent'] ?? '';
+               $this->defaultGroup = $conf['defaultGroup'] ?? null;
 
                $this->ticket = mt_rand();
        }
@@ -157,8 +152,19 @@ abstract class LBFactory implements ILBFactory {
                $this->forEachLBCallMethod( 'disable' );
        }
 
+       public function getLocalDomainID() {
+               return $this->localDomain->getId();
+       }
+
+       public function resolveDomainID( $domain ) {
+               return ( $domain !== false ) ? (string)$domain : $this->getLocalDomainID();
+       }
+
        public function shutdown(
-               $mode = self::SHUTDOWN_CHRONPROT_SYNC, callable $workCallback = null, &$cpIndex = null
+               $mode = self::SHUTDOWN_CHRONPROT_SYNC,
+               callable $workCallback = null,
+               &$cpIndex = null,
+               &$cpClientId = null
        ) {
                $chronProt = $this->getChronologyProtector();
                if ( $mode === self::SHUTDOWN_CHRONPROT_SYNC ) {
@@ -167,6 +173,8 @@ abstract class LBFactory implements ILBFactory {
                        $this->shutdownChronologyProtector( $chronProt, null, 'async', $cpIndex );
                }
 
+               $cpClientId = $chronProt->getClientId();
+
                $this->commitMasterChanges( __METHOD__ ); // sanity
        }
 
@@ -207,7 +215,7 @@ abstract class LBFactory implements ILBFactory {
        protected function forEachLBCallMethod( $methodName, array $args = [] ) {
                $this->forEachLB(
                        function ( ILoadBalancer $loadBalancer, $methodName, array $args ) {
-                               call_user_func_array( [ $loadBalancer, $methodName ], $args );
+                               $loadBalancer->$methodName( ...$args );
                        },
                        [ $methodName, $args ]
                );
@@ -498,6 +506,7 @@ abstract class LBFactory implements ILBFactory {
                        [
                                'ip' => $this->requestInfo['IPAddress'],
                                'agent' => $this->requestInfo['UserAgent'],
+                               'clientId' => $this->requestInfo['ChronologyClientId']
                        ],
                        $this->requestInfo['ChronologyPositionIndex']
                );
@@ -509,6 +518,10 @@ abstract class LBFactory implements ILBFactory {
                        // Request opted out of using position wait logic. This is useful for requests
                        // done by the job queue or background ETL that do not have a meaningful session.
                        $this->chronProt->setWaitEnabled( false );
+               } elseif ( $this->memStash instanceof EmptyBagOStuff ) {
+                       // No where to store any DB positions and wait for them to appear
+                       $this->chronProt->setEnabled( false );
+                       $this->replLogger->info( 'Cannot use ChronologyProtector with EmptyBagOStuff.' );
                }
 
                $this->replLogger->debug( __METHOD__ . ': using request info ' .
@@ -579,6 +592,7 @@ abstract class LBFactory implements ILBFactory {
                        'hostname' => $this->hostname,
                        'cliMode' => $this->cliMode,
                        'agent' => $this->agent,
+                       'defaultGroup' => $this->defaultGroup,
                        'chronologyCallback' => function ( ILoadBalancer $lb ) {
                                // Defer ChronologyProtector construction in case setRequestInfo() ends up
                                // being called later (but before the first connection attempt) (T192611)
@@ -643,32 +657,38 @@ abstract class LBFactory implements ILBFactory {
 
        /**
         * @param int $index Write index
-        * @param int $time UNIX timestamp
-        * @return string Timestamp-qualified write index of the form "<index>.<timestamp>"
+        * @param int $time UNIX timestamp; can be used to detect stale cookies (T190082)
+        * @param string $clientId Agent ID hash from ILBFactory::shutdown()
+        * @return string Timestamp-qualified write index of the form "<index>@<timestamp>#<hash>"
         * @since 1.32
         */
-       public static function makeCookieValueFromCPIndex( $index, $time ) {
-               return $index . '@' . $time;
+       public static function makeCookieValueFromCPIndex( $index, $time, $clientId ) {
+               return "$index@$time#$clientId";
        }
 
        /**
-        * @param string $value String possibly of the form "<index>" or "<index>@<timestamp>"
-        * @param int $minTimestamp Lowest UNIX timestamp of non-expired values (if present)
-        * @return int|null Write index or null if $value is empty or expired
+        * @param string $value Possible result of LBFactory::makeCookieValueFromCPIndex()
+        * @param int $minTimestamp Lowest UNIX timestamp that a non-expired value can have
+        * @return array (index: int or null, clientId: string or null)
         * @since 1.32
         */
-       public static function getCPIndexFromCookieValue( $value, $minTimestamp ) {
-               if ( !preg_match( '/^(\d+)(?:@(\d+))?$/', $value, $m ) ) {
-                       return null;
+       public static function getCPInfoFromCookieValue( $value, $minTimestamp ) {
+               static $placeholder = [ 'index' => null, 'clientId' => null ];
+
+               if ( !preg_match( '/^(\d+)@(\d+)#([0-9a-f]{32})$/', $value, $m ) ) {
+                       return $placeholder; // invalid
                }
 
                $index = (int)$m[1];
-
-               if ( isset( $m[2] ) && $m[2] !== '' && (int)$m[2] < $minTimestamp ) {
-                       return null; // expired
+               if ( $index <= 0 ) {
+                       return $placeholder; // invalid
+               } elseif ( isset( $m[2] ) && $m[2] !== '' && (int)$m[2] < $minTimestamp ) {
+                       return $placeholder; // expired
                }
 
-               return ( $index > 0 ) ? $index : null;
+               $clientId = ( isset( $m[3] ) && $m[3] !== '' ) ? $m[3] : null;
+
+               return [ 'index' => $index, 'clientId' => $clientId ];
        }
 
        public function setRequestInfo( array $info ) {
@@ -713,4 +733,7 @@ abstract class LBFactory implements ILBFactory {
        }
 }
 
+/**
+ * @deprecated since 1.29
+ */
 class_alias( LBFactory::class, 'LBFactory' );
index cfa2647..30074ec 100644 (file)
@@ -422,10 +422,10 @@ class LBFactoryMulti extends LBFactory {
         */
        public function forEachLB( $callback, array $params = [] ) {
                foreach ( $this->mainLBs as $lb ) {
-                       call_user_func_array( $callback, array_merge( [ $lb ], $params ) );
+                       $callback( $lb, ...$params );
                }
                foreach ( $this->extLBs as $lb ) {
-                       call_user_func_array( $callback, array_merge( [ $lb ], $params ) );
+                       $callback( $lb, ...$params );
                }
        }
 }
index 9a6aa3a..6a6bb8d 100644 (file)
@@ -62,7 +62,7 @@ class LBFactorySimple extends LBFactory {
        public function __construct( array $conf ) {
                parent::__construct( $conf );
 
-               $this->servers = isset( $conf['servers'] ) ? $conf['servers'] : [];
+               $this->servers = $conf['servers'] ?? [];
                foreach ( $this->servers as $i => $server ) {
                        if ( $i == 0 ) {
                                $this->servers[$i]['master'] = true;
@@ -71,13 +71,9 @@ class LBFactorySimple extends LBFactory {
                        }
                }
 
-               $this->externalClusters = isset( $conf['externalClusters'] )
-                       ? $conf['externalClusters']
-                       : [];
-               $this->loadMonitorClass = isset( $conf['loadMonitorClass'] )
-                       ? $conf['loadMonitorClass']
-                       : 'LoadMonitor';
-               $this->maxLag = isset( $conf['maxLag'] ) ? $conf['maxLag'] : self::MAX_LAG_DEFAULT;
+               $this->externalClusters = $conf['externalClusters'] ?? [];
+               $this->loadMonitorClass = $conf['loadMonitorClass'] ?? 'LoadMonitor';
+               $this->maxLag = $conf['maxLag'] ?? self::MAX_LAG_DEFAULT;
        }
 
        /**
@@ -153,10 +149,10 @@ class LBFactorySimple extends LBFactory {
         */
        public function forEachLB( $callback, array $params = [] ) {
                if ( isset( $this->mainLB ) ) {
-                       call_user_func_array( $callback, array_merge( [ $this->mainLB ], $params ) );
+                       $callback( $this->mainLB, ...$params );
                }
                foreach ( $this->extLBs as $lb ) {
-                       call_user_func_array( $callback, array_merge( [ $lb ], $params ) );
+                       $callback( $lb, ...$params );
                }
        }
 }
index 587ab23..2c1a782 100644 (file)
@@ -103,7 +103,7 @@ class LBFactorySingle extends LBFactory {
         */
        public function forEachLB( $callback, array $params = [] ) {
                if ( isset( $this->lb ) ) { // may not be set during _destruct()
-                       call_user_func_array( $callback, array_merge( [ $this->lb ], $params ) );
+                       $callback( $this->lb, ...$params );
                }
        }
 }
index 81ce4ba..0ff6a32 100644 (file)
@@ -86,8 +86,6 @@ interface ILoadBalancer {
 
        /** @var int DB handle should have DBO_TRX disabled and the caller will leave it as such */
        const CONN_TRX_AUTOCOMMIT = 1;
-       /** @var int Alias for CONN_TRX_AUTOCOMMIT for b/c; deprecated since 1.31 */
-       const CONN_TRX_AUTO = 1;
 
        /** @var string Manager of ILoadBalancer instances is running post-commit callbacks */
        const STAGE_POSTCOMMIT_CALLBACKS = 'stage-postcommit-callbacks';
@@ -122,6 +120,22 @@ interface ILoadBalancer {
         */
        public function __construct( array $params );
 
+       /**
+        * Get the local (and default) database domain ID of connection handles
+        *
+        * @see DatabaseDomain
+        * @return string Database domain ID; this specifies DB name, schema, and table prefix
+        * @since 1.31
+        */
+       public function getLocalDomainID();
+
+       /**
+        * @param DatabaseDomain|string|bool $domain Database domain
+        * @return string Value of $domain if provided or the local domain otherwise
+        * @since 1.32
+        */
+       public function resolveDomainID( $domain );
+
        /**
         * Get the index of the reader connection, which may be a replica DB
         *
@@ -156,7 +170,7 @@ interface ILoadBalancer {
         * This can be used a faster proxy for waitForAll()
         *
         * @param DBMasterPos|bool $pos Master position or false
-        * @param int $timeout Max seconds to wait; default is mWaitTimeout
+        * @param int|null $timeout Max seconds to wait; default is mWaitTimeout
         * @return bool Success (able to connect and no timeouts reached)
         */
        public function waitForOne( $pos, $timeout = null );
@@ -165,7 +179,7 @@ interface ILoadBalancer {
         * Set the master wait position and wait for ALL replica DBs to catch up to it
         *
         * @param DBMasterPos|bool $pos Master position or false
-        * @param int $timeout Max seconds to wait; default is mWaitTimeout
+        * @param int|null $timeout Max seconds to wait; default is mWaitTimeout
         * @return bool Success (able to connect and no timeouts reached)
         */
        public function waitForAll( $pos, $timeout = null );
@@ -332,6 +346,13 @@ interface ILoadBalancer {
         */
        public function getServerName( $i );
 
+       /**
+        * Return the server info structure for a given index, or false if the index is invalid.
+        * @param int $i
+        * @return array|bool
+        */
+       public function getServerInfo( $i );
+
        /**
         * Get DB type of the server with the specified index
         *
@@ -481,7 +502,7 @@ interface ILoadBalancer {
         * Check if this load balancer object had any recent or still
         * pending writes issued against it by this PHP thread
         *
-        * @param float $age How many seconds ago is "recent" [defaults to mWaitTimeout]
+        * @param float|null $age How many seconds ago is "recent" [defaults to mWaitTimeout]
         * @return bool
         */
        public function hasOrMadeRecentMasterChanges( $age = null );
index 360be42..f2f9eb0 100644 (file)
@@ -38,10 +38,39 @@ use Exception;
  * @ingroup Database
  */
 class LoadBalancer implements ILoadBalancer {
-       /** @var array[] Map of (server index => server config array) */
-       private $servers;
+       /** @var ILoadMonitor */
+       private $loadMonitor;
+       /** @var callable|null Callback to run before the first connection attempt */
+       private $chronologyCallback;
+       /** @var BagOStuff */
+       private $srvCache;
+       /** @var WANObjectCache */
+       private $wanCache;
+       /** @var object|string Class name or object With profileIn/profileOut methods */
+       private $profiler;
+       /** @var TransactionProfiler */
+       private $trxProfiler;
+       /** @var LoggerInterface */
+       private $replLogger;
+       /** @var LoggerInterface */
+       private $connLogger;
+       /** @var LoggerInterface */
+       private $queryLogger;
+       /** @var LoggerInterface */
+       private $perfLogger;
+       /** @var callable Exception logger */
+       private $errorLogger;
+       /** @var callable Deprecation logger */
+       private $deprecationLogger;
+
+       /** @var DatabaseDomain Local Domain ID and default for selectDB() calls */
+       private $localDomain;
+
        /** @var Database[][][] Map of (connection category => server index => IDatabase[]) */
        private $conns;
+
+       /** @var array[] Map of (server index => server config array) */
+       private $servers;
        /** @var float[] Map of (server index => weight) */
        private $loads;
        /** @var array[] Map of (group => server index => weight) */
@@ -52,31 +81,24 @@ class LoadBalancer implements ILoadBalancer {
        private $waitTimeout;
        /** @var array The LoadMonitor configuration */
        private $loadMonitorConfig;
+       /** @var string Alternate ID string for the domain instead of DatabaseDomain::getId() */
+       private $localDomainIdAlias;
+       /** @var int */
+       private $maxLag = self::MAX_LAG_DEFAULT;
+
+       /** @var string Current server name */
+       private $hostname;
+       /** @var bool Whether this PHP instance is for a CLI script */
+       private $cliMode;
+       /** @var string Agent name for query profiling */
+       private $agent;
+
        /** @var array[] $aliases Map of (table => (dbname, schema, prefix) map) */
        private $tableAliases = [];
        /** @var string[] Map of (index alias => index) */
        private $indexAliases = [];
-
-       /** @var ILoadMonitor */
-       private $loadMonitor;
-       /** @var callable|null Callback to run before the first connection attempt */
-       private $chronologyCallback;
-       /** @var BagOStuff */
-       private $srvCache;
-       /** @var WANObjectCache */
-       private $wanCache;
-       /** @var object|string Class name or object With profileIn/profileOut methods */
-       protected $profiler;
-       /** @var TransactionProfiler */
-       protected $trxProfiler;
-       /** @var LoggerInterface */
-       protected $replLogger;
-       /** @var LoggerInterface */
-       protected $connLogger;
-       /** @var LoggerInterface */
-       protected $queryLogger;
-       /** @var LoggerInterface */
-       protected $perfLogger;
+       /** @var array[] Map of (name => callable) */
+       private $trxRecurringCallbacks = [];
 
        /** @var Database DB connection object that caused a problem */
        private $errorConnection;
@@ -94,35 +116,19 @@ class LoadBalancer implements ILoadBalancer {
        private $readOnlyReason = false;
        /** @var int Total connections opened */
        private $connsOpened = 0;
-       /** @var string|bool String if a requested DBO_TRX transaction round is active */
-       private $trxRoundId = false;
-       /** @var array[] Map of (name => callable) */
-       private $trxRecurringCallbacks = [];
-       /** @var DatabaseDomain Local Domain ID and default for selectDB() calls */
-       private $localDomain;
-       /** @var string Alternate ID string for the domain instead of DatabaseDomain::getId() */
-       private $localDomainIdAlias;
-       /** @var string Current server name */
-       private $host;
-       /** @var bool Whether this PHP instance is for a CLI script */
-       protected $cliMode;
-       /** @var string Agent name for query profiling */
-       protected $agent;
-
-       /** @var callable Exception logger */
-       private $errorLogger;
-       /** @var callable Deprecation logger */
-       private $deprecationLogger;
-
        /** @var bool */
        private $disabled = false;
        /** @var bool Whether any connection has been attempted yet */
        private $connectionAttempted = false;
-       /** @var int */
-       private $maxLag = self::MAX_LAG_DEFAULT;
+
+       /** @var string|bool String if a requested DBO_TRX transaction round is active */
+       private $trxRoundId = false;
        /** @var string Stage of the current transaction round in the transaction round life-cycle */
        private $trxRoundStage = self::ROUND_CURSORY;
 
+       /** @var string|null */
+       private $defaultGroup = null;
+
        /** @var int Warn when this many connection are held */
        const CONN_HELD_WARN_THRESHOLD = 10;
 
@@ -172,9 +178,7 @@ class LoadBalancer implements ILoadBalancer {
                        : DatabaseDomain::newUnspecified();
                $this->setLocalDomain( $localDomain );
 
-               $this->waitTimeout = isset( $params['waitTimeout'] )
-                       ? $params['waitTimeout']
-                       : self::MAX_WAIT_DEFAULT;
+               $this->waitTimeout = $params['waitTimeout'] ?? self::MAX_WAIT_DEFAULT;
 
                $this->readIndex = -1;
                $this->conns = [
@@ -228,35 +232,27 @@ class LoadBalancer implements ILoadBalancer {
                } else {
                        $this->wanCache = WANObjectCache::newEmpty();
                }
-               $this->profiler = isset( $params['profiler'] ) ? $params['profiler'] : null;
+               $this->profiler = $params['profiler'] ?? null;
                if ( isset( $params['trxProfiler'] ) ) {
                        $this->trxProfiler = $params['trxProfiler'];
                } else {
                        $this->trxProfiler = new TransactionProfiler();
                }
 
-               $this->errorLogger = isset( $params['errorLogger'] )
-                       ? $params['errorLogger']
-                       : function ( Exception $e ) {
-                               trigger_error( get_class( $e ) . ': ' . $e->getMessage(), E_USER_WARNING );
-                       };
-               $this->deprecationLogger = isset( $params['deprecationLogger'] )
-                       ? $params['deprecationLogger']
-                       : function ( $msg ) {
-                               trigger_error( $msg, E_USER_DEPRECATED );
-                       };
+               $this->errorLogger = $params['errorLogger'] ?? function ( Exception $e ) {
+                       trigger_error( get_class( $e ) . ': ' . $e->getMessage(), E_USER_WARNING );
+               };
+               $this->deprecationLogger = $params['deprecationLogger'] ?? function ( $msg ) {
+                       trigger_error( $msg, E_USER_DEPRECATED );
+               };
 
                foreach ( [ 'replLogger', 'connLogger', 'queryLogger', 'perfLogger' ] as $key ) {
-                       $this->$key = isset( $params[$key] ) ? $params[$key] : new NullLogger();
+                       $this->$key = $params[$key] ?? new NullLogger();
                }
 
-               $this->host = isset( $params['hostname'] )
-                       ? $params['hostname']
-                       : ( gethostname() ?: 'unknown' );
-               $this->cliMode = isset( $params['cliMode'] )
-                       ? $params['cliMode']
-                       : ( PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg' );
-               $this->agent = isset( $params['agent'] ) ? $params['agent'] : '';
+               $this->hostname = $params['hostname'] ?? ( gethostname() ?: 'unknown' );
+               $this->cliMode = $params['cliMode'] ?? ( PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg' );
+               $this->agent = $params['agent'] ?? '';
 
                if ( isset( $params['chronologyCallback'] ) ) {
                        $this->chronologyCallback = $params['chronologyCallback'];
@@ -269,19 +265,18 @@ class LoadBalancer implements ILoadBalancer {
                                $this->trxRoundStage = self::ROUND_ROLLBACK_CALLBACKS;
                        }
                }
+
+               $this->defaultGroup = $params['defaultGroup'] ?? null;
        }
 
-       /**
-        * Get the local (and default) database domain ID of connection handles
-        *
-        * @see DatabaseDomain
-        * @return string Database domain ID; this specifies DB name, schema, and table prefix
-        * @since 1.31
-        */
        public function getLocalDomainID() {
                return $this->localDomain->getId();
        }
 
+       public function resolveDomainID( $domain ) {
+               return ( $domain !== false ) ? (string)$domain : $this->getLocalDomainID();
+       }
+
        /**
         * Get a LoadMonitor instance
         *
@@ -321,9 +316,7 @@ class LoadBalancer implements ILoadBalancer {
                foreach ( $lags as $i => $lag ) {
                        if ( $i != 0 ) {
                                # How much lag this server nominally is allowed to have
-                               $maxServerLag = isset( $this->servers[$i]['max lag'] )
-                                       ? $this->servers[$i]['max lag']
-                                       : $this->maxLag; // default
+                               $maxServerLag = $this->servers[$i]['max lag'] ?? $this->maxLag; // default
                                # Constrain that futher by $maxLag argument
                                $maxServerLag = min( $maxServerLag, $maxLag );
 
@@ -610,7 +603,7 @@ class LoadBalancer implements ILoadBalancer {
         * Wait for a given replica DB to catch up to the master pos stored in $this
         * @param int $index Server index
         * @param bool $open Check the server even if a new connection has to be made
-        * @param int $timeout Max seconds to wait; default is "waitTimeout" given to __construct()
+        * @param int|null $timeout Max seconds to wait; default is "waitTimeout" given to __construct()
         * @return bool
         */
        protected function doWait( $index, $open = false, $timeout = null ) {
@@ -729,8 +722,11 @@ class LoadBalancer implements ILoadBalancer {
                        }
                }
 
+               // Check one "group" per default: the generic pool
+               $defaultGroups = $this->defaultGroup ? [ $this->defaultGroup ] : [ false ];
+
                $groups = ( $groups === false || $groups === [] )
-                       ? [ false ] // check one "group": the generic pool
+                       ? $defaultGroups
                        : (array)$groups;
 
                $masterOnly = ( $i == self::DB_MASTER || $i == $this->getWriterIndex() );
@@ -849,19 +845,19 @@ class LoadBalancer implements ILoadBalancer {
        }
 
        public function getConnectionRef( $db, $groups = [], $domain = false, $flags = 0 ) {
-               $domain = ( $domain !== false ) ? $domain : $this->localDomain;
+               $domain = $this->resolveDomainID( $domain );
 
                return new DBConnRef( $this, $this->getConnection( $db, $groups, $domain, $flags ) );
        }
 
        public function getLazyConnectionRef( $db, $groups = [], $domain = false, $flags = 0 ) {
-               $domain = ( $domain !== false ) ? $domain : $this->localDomain;
+               $domain = $this->resolveDomainID( $domain );
 
                return new DBConnRef( $this, [ $db, $groups, $domain, $flags ] );
        }
 
        public function getMaintenanceConnectionRef( $db, $groups = [], $domain = false, $flags = 0 ) {
-               $domain = ( $domain !== false ) ? $domain : $this->localDomain;
+               $domain = $this->resolveDomainID( $domain );
 
                return new MaintainableDBConnRef(
                        $this, $this->getConnection( $db, $groups, $domain, $flags ) );
@@ -876,7 +872,7 @@ class LoadBalancer implements ILoadBalancer {
                        $this->connLogger->debug( __METHOD__ . ': calling initLB() before first connection.' );
                        // Load any "waitFor" positions before connecting so that doWait() is triggered
                        $this->connectionAttempted = true;
-                       call_user_func( $this->chronologyCallback, $this );
+                       ( $this->chronologyCallback )( $this );
                }
 
                // Check if an auto-commit connection is being requested. If so, it will not reuse the
@@ -987,7 +983,7 @@ class LoadBalancer implements ILoadBalancer {
                        $oldDomain = key( $this->conns[$connFreeKey][$i] );
                        if ( strlen( $dbName ) && !$conn->selectDB( $dbName ) ) {
                                $this->lastError = "Error selecting database '$dbName' on server " .
-                                       $conn->getServer() . " from client host {$this->host}";
+                                       $conn->getServer() . " from client host {$this->hostname}";
                                $this->errorConnection = $conn;
                                $conn = false;
                        } else {
@@ -1033,7 +1029,7 @@ class LoadBalancer implements ILoadBalancer {
        public function getServerAttributes( $i ) {
                return Database::attributesFromType(
                        $this->getServerType( $i ),
-                       isset( $this->servers[$i]['driver'] ) ? $this->servers[$i]['driver'] : null
+                       $this->servers[$i]['driver'] ?? null
                );
        }
 
@@ -1106,7 +1102,7 @@ class LoadBalancer implements ILoadBalancer {
                $server['agent'] = $this->agent;
                // Use DBO_DEFAULT flags by default for LoadBalancer managed databases. Assume that the
                // application calls LoadBalancer::commitMasterChanges() before the PHP script completes.
-               $server['flags'] = isset( $server['flags'] ) ? $server['flags'] : IDatabase::DBO_DEFAULT;
+               $server['flags'] = $server['flags'] ?? IDatabase::DBO_DEFAULT;
 
                // Create a live connection object
                try {
@@ -1195,8 +1191,16 @@ class LoadBalancer implements ILoadBalancer {
                return ( $name != '' ) ? $name : 'localhost';
        }
 
+       public function getServerInfo( $i ) {
+               if ( isset( $this->servers[$i] ) ) {
+                       return $this->servers[$i];
+               } else {
+                       return false;
+               }
+       }
+
        public function getServerType( $i ) {
-               return isset( $this->servers[$i]['type'] ) ? $this->servers[$i]['type'] : 'unknown';
+               return $this->servers[$i]['type'] ?? 'unknown';
        }
 
        public function getMasterPos() {
@@ -1297,7 +1301,7 @@ class LoadBalancer implements ILoadBalancer {
        public function approveMasterChanges( array $options ) {
                $this->assertTransactionRoundStage( self::ROUND_FINALIZED );
 
-               $limit = isset( $options['maxWriteDuration'] ) ? $options['maxWriteDuration'] : 0;
+               $limit = $options['maxWriteDuration'] ?? 0;
 
                $this->trxRoundStage = self::ROUND_ERROR; // "failed" until proven otherwise
                $this->forEachOpenMasterConnection( function ( IDatabase $conn ) use ( $limit ) {
@@ -1374,7 +1378,7 @@ class LoadBalancer implements ILoadBalancer {
                                try {
                                        $conn->commit( $fname, $conn::FLUSHING_ALL_PEERS );
                                } catch ( DBError $e ) {
-                                       call_user_func( $this->errorLogger, $e );
+                                       ( $this->errorLogger )( $e );
                                        $failures[] = "{$conn->getServer()}: {$e->getMessage()}";
                                }
                        }
@@ -1727,8 +1731,7 @@ class LoadBalancer implements ILoadBalancer {
                foreach ( $this->conns as $connsByServer ) {
                        foreach ( $connsByServer as $serverConns ) {
                                foreach ( $serverConns as $conn ) {
-                                       $mergedParams = array_merge( [ $conn ], $params );
-                                       call_user_func_array( $callback, $mergedParams );
+                                       $callback( $conn, ...$params );
                                }
                        }
                }
@@ -1740,8 +1743,7 @@ class LoadBalancer implements ILoadBalancer {
                        if ( isset( $connsByServer[$masterIndex] ) ) {
                                /** @var IDatabase $conn */
                                foreach ( $connsByServer[$masterIndex] as $conn ) {
-                                       $mergedParams = array_merge( [ $conn ], $params );
-                                       call_user_func_array( $callback, $mergedParams );
+                                       $callback( $conn, ...$params );
                                }
                        }
                }
@@ -1754,8 +1756,7 @@ class LoadBalancer implements ILoadBalancer {
                                        continue; // skip master
                                }
                                foreach ( $serverConns as $conn ) {
-                                       $mergedParams = array_merge( [ $conn ], $params );
-                                       call_user_func_array( $callback, $mergedParams );
+                                       $callback( $conn, ...$params );
                                }
                        }
                }
@@ -1952,4 +1953,7 @@ class LoadBalancer implements ILoadBalancer {
        }
 }
 
+/**
+ * @deprecated since 1.29
+ */
 class_alias( LoadBalancer::class, 'LoadBalancer' );
index be80cc5..1b72502 100644 (file)
@@ -52,9 +52,9 @@ class LoadBalancerSingle extends LoadBalancer {
                                        'load' => 1,
                                ]
                        ],
-                       'trxProfiler' => isset( $params['trxProfiler'] ) ? $params['trxProfiler'] : null,
-                       'srvCache' => isset( $params['srvCache'] ) ? $params['srvCache'] : null,
-                       'wanCache' => isset( $params['wanCache'] ) ? $params['wanCache'] : null
+                       'trxProfiler' => $params['trxProfiler'] ?? null,
+                       'srvCache' => $params['srvCache'] ?? null,
+                       'wanCache' => $params['wanCache'] ?? null
                ] );
 
                if ( isset( $params['readOnlyReason'] ) ) {
@@ -77,4 +77,7 @@ class LoadBalancerSingle extends LoadBalancer {
        }
 }
 
+/**
+ * @deprecated since 1.29
+ */
 class_alias( LoadBalancerSingle::class, 'LoadBalancerSingle' );
index c7f807a..01834ee 100644 (file)
@@ -69,12 +69,8 @@ class LoadMonitor implements ILoadMonitor {
                $this->wanCache = $wCache;
                $this->replLogger = new NullLogger();
 
-               $this->movingAveRatio = isset( $options['movingAveRatio'] )
-                       ? $options['movingAveRatio']
-                       : 0.1;
-               $this->lagWarnThreshold = isset( $options['lagWarnThreshold'] )
-                       ? $options['lagWarnThreshold']
-                       : self::LAG_WARN_THRESHOLD;
+               $this->movingAveRatio = $options['movingAveRatio'] ?? 0.1;
+               $this->lagWarnThreshold = $options['lagWarnThreshold'] ?? self::LAG_WARN_THRESHOLD;
        }
 
        public function setLogger( LoggerInterface $logger ) {
@@ -167,9 +163,7 @@ class LoadMonitor implements ILoadMonitor {
                                $close = true; // new connection
                        }
 
-                       $lastWeight = isset( $staleValue['weightScales'][$i] )
-                               ? $staleValue['weightScales'][$i]
-                               : 1.0;
+                       $lastWeight = $staleValue['weightScales'][$i] ?? 1.0;
                        $coefficient = $this->getWeightScale( $i, $conn ?: null );
                        $newWeight = $movAveRatio * $coefficient + ( 1 - $movAveRatio ) * $lastWeight;
 
index 1fbc117..dda980c 100644 (file)
@@ -39,9 +39,7 @@ class LoadMonitorMySQL extends LoadMonitor {
        ) {
                parent::__construct( $lb, $srvCache, $wCache, $options );
 
-               $this->warmCacheRatio = isset( $options['warmCacheRatio'] )
-                       ? $options['warmCacheRatio']
-                       : 0.0;
+               $this->warmCacheRatio = $options['warmCacheRatio'] ?? 0.0;
        }
 
        protected function getWeightScale( $index, IDatabase $conn = null ) {
index d330d3c..a73fac1 100644 (file)
@@ -42,6 +42,27 @@ class RedisConnRef implements LoggerAwareInterface {
         */
        protected $logger;
 
+       /**
+        * No authentication errors.
+        *
+        * @var constant
+        */
+       const AUTH_NO_ERROR = 200;
+
+       /**
+        * Temporary authentication error; recovered by reauthenticating.
+        *
+        * @var constant
+        */
+       const AUTH_ERROR_TEMPORARY = 201;
+
+       /**
+        * Authentication error was permanent and could not be recovered.
+        *
+        * @var constant
+        */
+       const AUTH_ERROR_PERMANENT = 202;
+
        /**
         * @param RedisConnectionPool $pool
         * @param string $server
@@ -77,41 +98,145 @@ class RedisConnRef implements LoggerAwareInterface {
                $this->lastError = null;
        }
 
+       /**
+        * Magic __call handler for most Redis functions.
+        *
+        * @param string $name
+        * @param array $arguments
+        * @return mixed $res
+        * @throws RedisException
+        */
        public function __call( $name, $arguments ) {
-               $conn = $this->conn; // convenience
-
                // Work around https://github.com/nicolasff/phpredis/issues/70
                $lname = strtolower( $name );
-               if ( ( $lname === 'blpop' || $lname == 'brpop' )
-                       && is_array( $arguments[0] ) && isset( $arguments[1] )
+               if (
+                       ( $lname === 'blpop' || $lname === 'brpop' || $lname === 'brpoplpush' )
+                       && count( $arguments ) > 1
                ) {
-                       $this->pool->resetTimeout( $conn, $arguments[1] + 1 );
-               } elseif ( $lname === 'brpoplpush' && isset( $arguments[2] ) ) {
-                       $this->pool->resetTimeout( $conn, $arguments[2] + 1 );
+                       // Get timeout off the end since it is always required and argument length can vary
+                       $timeout = end( $arguments );
+                       // Only give the additional one second buffer if not requesting an infinite timeout
+                       $this->pool->resetTimeout( $this->conn, ( $timeout > 0 ? $timeout + 1 : $timeout ) );
                }
 
-               $conn->clearLastError();
+               return $this->tryCall( $name, $arguments );
+       }
+
+       /**
+        * Do the method call in the common try catch handler.
+        *
+        * @param string $method
+        * @param array $arguments
+        * @return mixed $res
+        * @throws RedisException
+        */
+       private function tryCall( $method, $arguments ) {
+               $this->conn->clearLastError();
                try {
-                       $res = call_user_func_array( [ $conn, $name ], $arguments );
-                       if ( preg_match( '/^ERR operation not permitted\b/', $conn->getLastError() ) ) {
-                               $this->pool->reauthenticateConnection( $this->server, $conn );
-                               $conn->clearLastError();
-                               $res = call_user_func_array( [ $conn, $name ], $arguments );
-                               $this->logger->info(
-                                       "Used automatic re-authentication for method '$name'.",
-                                       [ 'redis_server' => $this->server ]
-                               );
+                       $res = $this->conn->$method( ...$arguments );
+                       $authError = $this->checkAuthentication();
+                       if ( $authError === self::AUTH_ERROR_TEMPORARY ) {
+                               $res = $this->conn->$method( ...$arguments );
                        }
-               } catch ( RedisException $e ) {
-                       $this->pool->resetTimeout( $conn ); // restore
-                       throw $e;
+                       if ( $authError === self::AUTH_ERROR_PERMANENT ) {
+                               throw new RedisException( "Failure reauthenticating to Redis." );
+                       }
+               } finally {
+                       $this->postCallCleanup();
                }
 
-               $this->lastError = $conn->getLastError() ?: $this->lastError;
+               return $res;
+       }
 
-               $this->pool->resetTimeout( $conn ); // restore
+       /**
+        * Key Scan
+        * Handle this explicity due to needing the iterator passed by reference.
+        * See: https://github.com/phpredis/phpredis#scan
+        *
+        * @param int &$iterator
+        * @param string|null $pattern
+        * @param int|null $count
+        * @return array $res
+        */
+       public function scan( &$iterator, $pattern = null, $count = null ) {
+               return $this->tryCall( 'scan', [ &$iterator, $pattern, $count ] );
+       }
 
-               return $res;
+       /**
+        * Set Scan
+        * Handle this explicity due to needing the iterator passed by reference.
+        * See: https://github.com/phpredis/phpredis#sScan
+        *
+        * @param string $key
+        * @param int &$iterator
+        * @param string|null $pattern
+        * @param int|null $count
+        * @return array $res
+        */
+       public function sScan( $key, &$iterator, $pattern = null, $count = null ) {
+               return $this->tryCall( 'sScan', [ $key, &$iterator, $pattern, $count ] );
+       }
+
+       /**
+        * Hash Scan
+        * Handle this explicity due to needing the iterator passed by reference.
+        * See: https://github.com/phpredis/phpredis#hScan
+        *
+        * @param string $key
+        * @param int &$iterator
+        * @param string|null $pattern
+        * @param int|null $count
+        * @return array $res
+        */
+       public function hScan( $key, &$iterator, $pattern = null, $count = null ) {
+               return $this->tryCall( 'hScan', [ $key, &$iterator, $pattern, $count ] );
+       }
+
+       /**
+        * Sorted Set Scan
+        * Handle this explicity due to needing the iterator passed by reference.
+        * See: https://github.com/phpredis/phpredis#hScan
+        *
+        * @param string $key
+        * @param int &$iterator
+        * @param string|null $pattern
+        * @param int|null $count
+        * @return array $res
+        */
+       public function zScan( $key, &$iterator, $pattern = null, $count = null ) {
+               return $this->tryCall( 'zScan', [ $key, &$iterator, $pattern, $count ] );
+       }
+
+       /**
+        * Handle authentication errors and automatically reauthenticate.
+        *
+        * @return constant self::AUTH_NO_ERROR, self::AUTH_ERROR_TEMPORARY, or self::AUTH_ERROR_PERMANENT
+        */
+       private function checkAuthentication() {
+               if ( preg_match( '/^ERR operation not permitted\b/', $this->conn->getLastError() ) ) {
+                       if ( !$this->pool->reauthenticateConnection( $this->server, $this->conn ) ) {
+                               return self::AUTH_ERROR_PERMANENT;
+                       }
+                       $this->conn->clearLastError();
+                       $this->logger->info(
+                               "Used automatic re-authentication for Redis.",
+                               [ 'redis_server' => $this->server ]
+                       );
+                       return self::AUTH_ERROR_TEMPORARY;
+               }
+               return self::AUTH_NO_ERROR;
+       }
+
+       /**
+        * Post Redis call cleanup.
+        *
+        * @return void
+        */
+       private function postCallCleanup() {
+               $this->lastError = $this->conn->getLastError() ?: $this->lastError;
+
+               // Restore original timeout in the case of blocking calls.
+               $this->pool->resetTimeout( $this->conn );
        }
 
        /**
index 509240f..aa60242 100644 (file)
@@ -81,9 +81,7 @@ class RedisConnectionPool implements LoggerAwareInterface {
                                __CLASS__ . ' requires a Redis client library. ' .
                                'See https://www.mediawiki.org/wiki/Redis#Setup' );
                }
-               $this->logger = isset( $options['logger'] )
-                       ? $options['logger']
-                       : new \Psr\Log\NullLogger();
+               $this->logger = $options['logger'] ?? new \Psr\Log\NullLogger();
                $this->connectTimeout = $options['connectTimeout'];
                $this->readTimeout = $options['readTimeout'];
                $this->persistent = $options['persistent'];
@@ -170,7 +168,7 @@ class RedisConnectionPool implements LoggerAwareInterface {
         *
         * @param string $server A hostname/port combination or the absolute path of a UNIX socket.
         *                       If a hostname is specified but no port, port 6379 will be used.
-        * @param LoggerInterface $logger PSR-3 logger intance. [optional]
+        * @param LoggerInterface|null $logger PSR-3 logger intance. [optional]
         * @return RedisConnRef|bool Returns false on failure
         * @throws MWException
         */
@@ -384,7 +382,7 @@ class RedisConnectionPool implements LoggerAwareInterface {
         * Adjust or reset the connection handle read timeout value
         *
         * @param Redis $conn
-        * @param int $timeout Optional
+        * @param int|null $timeout Optional
         */
        public function resetTimeout( Redis $conn, $timeout = null ) {
                $conn->setOption( Redis::OPT_READ_TIMEOUT, $timeout ?: $this->readTimeout );
index fed023b..9d05e06 100644 (file)
@@ -20,6 +20,8 @@
 
 /**
  * Class to perform secondary replacement within each replacement string
+ *
+ * @deprecated since 1.32, use a Closure instead
  */
 class DoubleReplacer extends Replacer {
        /**
@@ -28,6 +30,7 @@ class DoubleReplacer extends Replacer {
         * @param int $index
         */
        public function __construct( $from, $to, $index = 0 ) {
+               wfDeprecated( __METHOD__, '1.32' );
                $this->from = $from;
                $this->to = $to;
                $this->index = $index;
index 11637d0..8247694 100644 (file)
@@ -20,6 +20,8 @@
 
 /**
  * Class to perform replacement based on a simple hashtable lookup
+ *
+ * @deprecated since 1.32, use a Closure instead
  */
 class HashtableReplacer extends Replacer {
        private $table, $index;
@@ -29,6 +31,7 @@ class HashtableReplacer extends Replacer {
         * @param int $index
         */
        public function __construct( $table, $index = 0 ) {
+               wfDeprecated( __METHOD__, '1.32' );
                $this->table = $table;
                $this->index = $index;
        }
index 9874f52..bdc4dc0 100644 (file)
@@ -20,6 +20,8 @@
 
 /**
  * Class to replace regex matches with a string similar to that used in preg_replace()
+ *
+ * @deprecated since 1.32, use a Closure instead
  */
 class RegexlikeReplacer extends Replacer {
        private $r;
@@ -28,6 +30,7 @@ class RegexlikeReplacer extends Replacer {
         * @param string $r
         */
        public function __construct( $r ) {
+               wfDeprecated( __METHOD__, '1.32' );
                $this->r = $r;
        }
 
index 655e771..5425eed 100644 (file)
 /**
  * Base class for "replacers", objects used in preg_replace_callback() and
  * StringUtils::delimiterReplaceCallback()
+ *
+ * @deprecated since 1.32, use a Closure instead
  */
 abstract class Replacer {
        /**
         * @return array
         */
        public function cb() {
+               wfDeprecated( __METHOD__, '1.32' );
                return [ $this, 'replace' ];
        }
 
index 06915b2..5ef0135 100644 (file)
@@ -92,10 +92,11 @@ class BufferingStatsdDataFactory extends StatsdDataFactory implements IBuffering
        }
 
        /**
-        * @deprecated Use getData()
+        * @deprecated since 1.30 Use getData() instead
         * @return StatsdData[]
         */
        public function getBuffer() {
+               wfDeprecated( __METHOD__, '1.30' );
                return $this->buffer;
        }
 
@@ -103,6 +104,10 @@ class BufferingStatsdDataFactory extends StatsdDataFactory implements IBuffering
                return !empty( $this->buffer );
        }
 
+       /**
+        * @since 1.30
+        * @return StatsdData[]
+        */
        public function getData() {
                return $this->buffer;
        }
index 37a967f..73ecc9d 100644 (file)
@@ -150,8 +150,10 @@ class ParsoidVirtualRESTService extends VirtualRESTService {
         * @param Closure $idGeneratorFunc
         * @return array
         * @throws Exception
+        * @deprecated since 1.26, upgrade your client to issue v3 requests.
         */
        public function onParsoid1Request( array $req, Closure $idGeneratorFunc ) {
+               wfDeprecated( __METHOD__, '1.26' );
                $parts = explode( '/', $req['url'] );
                list(
                        $targetWiki, // 'local'
index 192b4bd..d31e735 100644 (file)
@@ -153,8 +153,10 @@ class RestbaseVirtualRESTService extends VirtualRESTService {
         * @param Closure $idGeneratorFunc
         * @return array
         * @throws Exception
+        * @deprecated since 1.26, upgrade your client to issue v3 requests.
         */
        public function onParsoid1Request( array $req, Closure $idGeneratorFunc ) {
+               wfDeprecated( __METHOD__, '1.26' );
                $parts = explode( '/', $req['url'] );
                list(
                        $targetWiki, // 'local'
index 2f16078..c7b76b6 100644 (file)
@@ -51,7 +51,7 @@ abstract class VirtualRESTService {
         * @return string The name of the service behind this VRS object.
         */
        public function getName() {
-               return isset( $this->params['name'] ) ? $this->params['name'] : static::class;
+               return $this->params['name'] ?? static::class;
        }
 
        /**
index e3b9376..96d7929 100644 (file)
@@ -105,10 +105,7 @@ class VirtualRESTServiceClient {
                $cmpFunc = function ( $a, $b ) {
                        $al = substr_count( $a, '/' );
                        $bl = substr_count( $b, '/' );
-                       if ( $al === $bl ) {
-                               return 0; // should not actually happen
-                       }
-                       return ( $al < $bl ) ? 1 : -1; // largest prefix first
+                       return $bl <=> $al; // largest prefix first
                };
 
                $matches = []; // matching prefixes (mount points)
diff --git a/includes/libs/xmp/XMP.php b/includes/libs/xmp/XMP.php
deleted file mode 100644 (file)
index 6a4d7c4..0000000
+++ /dev/null
@@ -1,1443 +0,0 @@
-<?php
-/**
- * Reader for XMP data containing properties relevant to images.
- *
- * 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
- */
-
-use Psr\Log\LoggerAwareInterface;
-use Psr\Log\LoggerInterface;
-use Psr\Log\NullLogger;
-use Wikimedia\ScopedCallback;
-
-/**
- * Class for reading xmp data containing properties relevant to
- * images, and spitting out an array that FormatMetadata accepts.
- *
- * Note, this is not meant to recognize every possible thing you can
- * encode in XMP. It should recognize all the properties we want.
- * For example it doesn't have support for structures with multiple
- * nesting levels, as none of the properties we're supporting use that
- * feature. If it comes across properties it doesn't recognize, it should
- * ignore them.
- *
- * The public methods one would call in this class are
- * - parse( $content )
- *    Reads in xmp content.
- *    Can potentially be called multiple times with partial data each time.
- * - parseExtended( $content )
- *    Reads XMPExtended blocks (jpeg files only).
- * - getResults
- *    Outputs a results array.
- *
- * Note XMP kind of looks like rdf. They are not the same thing - XMP is
- * encoded as a specific subset of rdf. This class can read XMP. It cannot
- * read rdf.
- */
-class XMPReader implements LoggerAwareInterface {
-       /** @var array XMP item configuration array */
-       protected $items;
-
-       /** @var array Array to hold the current element (and previous element, and so on) */
-       private $curItem = [];
-
-       /** @var bool|string The structure name when processing nested structures. */
-       private $ancestorStruct = false;
-
-       /** @var bool|string Temporary holder for character data that appears in xmp doc. */
-       private $charContent = false;
-
-       /** @var array Stores the state the xmpreader is in (see MODE_FOO constants) */
-       private $mode = [];
-
-       /** @var array Array to hold results */
-       private $results = [];
-
-       /** @var bool If we're doing a seq or bag. */
-       private $processingArray = false;
-
-       /** @var bool|string Used for lang alts only */
-       private $itemLang = false;
-
-       /** @var resource A resource handle for the XML parser */
-       private $xmlParser;
-
-       /** @var bool|string Character set like 'UTF-8' */
-       private $charset = false;
-
-       /** @var int */
-       private $extendedXMPOffset = 0;
-
-       /** @var int Flag determining if the XMP is safe to parse **/
-       private $parsable = 0;
-
-       /** @var string Buffer of XML to parse **/
-       private $xmlParsableBuffer = '';
-
-       /**
-        * These are various mode constants.
-        * they are used to figure out what to do
-        * with an element when its encountered.
-        *
-        * For example, MODE_IGNORE is used when processing
-        * a property we're not interested in. So if a new
-        * element pops up when we're in that mode, we ignore it.
-        */
-       const MODE_INITIAL = 0;
-       const MODE_IGNORE = 1;
-       const MODE_LI = 2;
-       const MODE_LI_LANG = 3;
-       const MODE_QDESC = 4;
-
-       // The following MODE constants are also used in the
-       // $items array to denote what type of property the item is.
-       const MODE_SIMPLE = 10;
-       const MODE_STRUCT = 11; // structure (associative array)
-       const MODE_SEQ = 12; // ordered list
-       const MODE_BAG = 13; // unordered list
-       const MODE_LANG = 14;
-       const MODE_ALT = 15; // non-language alt. Currently not implemented, and not needed atm.
-       const MODE_BAGSTRUCT = 16; // A BAG of Structs.
-
-       const NS_RDF = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#';
-       const NS_XML = 'http://www.w3.org/XML/1998/namespace';
-
-       // States used while determining if XML is safe to parse
-       const PARSABLE_UNKNOWN = 0;
-       const PARSABLE_OK = 1;
-       const PARSABLE_BUFFERING = 2;
-       const PARSABLE_NO = 3;
-
-       /**
-        * @var LoggerInterface
-        */
-       private $logger;
-
-       /**
-        * @var string
-        */
-       private $filename;
-
-       /**
-        * Primary job is to initialize the XMLParser
-        * @param LoggerInterface|null $logger
-        * @param string $filename
-        */
-       function __construct( LoggerInterface $logger = null, $filename = 'unknown' ) {
-               if ( !function_exists( 'xml_parser_create_ns' ) ) {
-                       // this should already be checked by this point
-                       throw new RuntimeException( 'XMP support requires XML Parser' );
-               }
-               if ( $logger ) {
-                       $this->setLogger( $logger );
-               } else {
-                       $this->setLogger( new NullLogger() );
-               }
-               $this->filename = $filename;
-
-               $this->items = XMPInfo::getItems();
-
-               $this->resetXMLParser();
-       }
-
-       public function setLogger( LoggerInterface $logger ) {
-               $this->logger = $logger;
-       }
-
-       /**
-        * free the XML parser.
-        *
-        * @note It is unclear to me if we really need to do this ourselves
-        *  or if php garbage collection will automatically free the xmlParser
-        *  when it is no longer needed.
-        */
-       private function destroyXMLParser() {
-               if ( $this->xmlParser ) {
-                       xml_parser_free( $this->xmlParser );
-                       $this->xmlParser = null;
-               }
-       }
-
-       /**
-        * Main use is if a single item has multiple xmp documents describing it.
-        * For example in jpeg's with extendedXMP
-        */
-       private function resetXMLParser() {
-               $this->destroyXMLParser();
-
-               $this->xmlParser = xml_parser_create_ns( 'UTF-8', ' ' );
-               xml_parser_set_option( $this->xmlParser, XML_OPTION_CASE_FOLDING, 0 );
-               xml_parser_set_option( $this->xmlParser, XML_OPTION_SKIP_WHITE, 1 );
-
-               xml_set_element_handler( $this->xmlParser,
-                       [ $this, 'startElement' ],
-                       [ $this, 'endElement' ] );
-
-               xml_set_character_data_handler( $this->xmlParser, [ $this, 'char' ] );
-
-               $this->parsable = self::PARSABLE_UNKNOWN;
-               $this->xmlParsableBuffer = '';
-       }
-
-       /**
-        * Check if this instance supports using this class
-        * @return bool
-        */
-       public static function isSupported() {
-               return function_exists( 'xml_parser_create_ns' ) && class_exists( 'XMLReader' );
-       }
-
-       /** Get the result array. Do some post-processing before returning
-        * the array, and transform any metadata that is special-cased.
-        *
-        * @return array Array of results as an array of arrays suitable for
-        *    FormatMetadata::getFormattedData().
-        */
-       public function getResults() {
-               // xmp-special is for metadata that affects how stuff
-               // is extracted. For example xmpNote:HasExtendedXMP.
-
-               // It is also used to handle photoshop:AuthorsPosition
-               // which is weird and really part of another property,
-               // see 2:85 in IPTC. See also pg 21 of IPTC4XMP standard.
-               // The location fields also use it.
-
-               $data = $this->results;
-
-               if ( isset( $data['xmp-special']['AuthorsPosition'] )
-                       && is_string( $data['xmp-special']['AuthorsPosition'] )
-                       && isset( $data['xmp-general']['Artist'][0] )
-               ) {
-                       // Note, if there is more than one creator,
-                       // this only applies to first. This also will
-                       // only apply to the dc:Creator prop, not the
-                       // exif:Artist prop.
-
-                       $data['xmp-general']['Artist'][0] =
-                               $data['xmp-special']['AuthorsPosition'] . ', '
-                               . $data['xmp-general']['Artist'][0];
-               }
-
-               // Go through the LocationShown and LocationCreated
-               // changing it to the non-hierarchal form used by
-               // the other location fields.
-
-               if ( isset( $data['xmp-special']['LocationShown'][0] )
-                       && is_array( $data['xmp-special']['LocationShown'][0] )
-               ) {
-                       // the is_array is just paranoia. It should always
-                       // be an array.
-                       foreach ( $data['xmp-special']['LocationShown'] as $loc ) {
-                               if ( !is_array( $loc ) ) {
-                                       // To avoid copying over the _type meta-fields.
-                                       continue;
-                               }
-                               foreach ( $loc as $field => $val ) {
-                                       $data['xmp-general'][$field . 'Dest'][] = $val;
-                               }
-                       }
-               }
-               if ( isset( $data['xmp-special']['LocationCreated'][0] )
-                       && is_array( $data['xmp-special']['LocationCreated'][0] )
-               ) {
-                       // the is_array is just paranoia. It should always
-                       // be an array.
-                       foreach ( $data['xmp-special']['LocationCreated'] as $loc ) {
-                               if ( !is_array( $loc ) ) {
-                                       // To avoid copying over the _type meta-fields.
-                                       continue;
-                               }
-                               foreach ( $loc as $field => $val ) {
-                                       $data['xmp-general'][$field . 'Created'][] = $val;
-                               }
-                       }
-               }
-
-               // We don't want to return the special values, since they're
-               // special and not info to be stored about the file.
-               unset( $data['xmp-special'] );
-
-               // Convert GPSAltitude to negative if below sea level.
-               if ( isset( $data['xmp-exif']['GPSAltitudeRef'] )
-                       && isset( $data['xmp-exif']['GPSAltitude'] )
-               ) {
-                       // Must convert to a real before multiplying by -1
-                       // XMPValidate guarantees there will always be a '/' in this value.
-                       list( $nom, $denom ) = explode( '/', $data['xmp-exif']['GPSAltitude'] );
-                       $data['xmp-exif']['GPSAltitude'] = $nom / $denom;
-
-                       if ( $data['xmp-exif']['GPSAltitudeRef'] == '1' ) {
-                               $data['xmp-exif']['GPSAltitude'] *= -1;
-                       }
-                       unset( $data['xmp-exif']['GPSAltitudeRef'] );
-               }
-
-               return $data;
-       }
-
-       /**
-        * Main function to call to parse XMP. Use getResults to
-        * get results.
-        *
-        * Also catches any errors during processing, writes them to
-        * debug log, blanks result array and returns false.
-        *
-        * @param string $content XMP data
-        * @param bool $allOfIt If this is all the data (true) or if its split up (false). Default true
-        * @throws RuntimeException
-        * @return bool Success.
-        */
-       public function parse( $content, $allOfIt = true ) {
-               if ( !$this->xmlParser ) {
-                       $this->resetXMLParser();
-               }
-               try {
-
-                       // detect encoding by looking for BOM which is supposed to be in processing instruction.
-                       // see page 12 of http://www.adobe.com/devnet/xmp/pdfs/XMPSpecificationPart3.pdf
-                       if ( !$this->charset ) {
-                               $bom = [];
-                               if ( preg_match( '/\xEF\xBB\xBF|\xFE\xFF|\x00\x00\xFE\xFF|\xFF\xFE\x00\x00|\xFF\xFE/',
-                                       $content, $bom )
-                               ) {
-                                       switch ( $bom[0] ) {
-                                               case "\xFE\xFF":
-                                                       $this->charset = 'UTF-16BE';
-                                                       break;
-                                               case "\xFF\xFE":
-                                                       $this->charset = 'UTF-16LE';
-                                                       break;
-                                               case "\x00\x00\xFE\xFF":
-                                                       $this->charset = 'UTF-32BE';
-                                                       break;
-                                               case "\xFF\xFE\x00\x00":
-                                                       $this->charset = 'UTF-32LE';
-                                                       break;
-                                               case "\xEF\xBB\xBF":
-                                                       $this->charset = 'UTF-8';
-                                                       break;
-                                               default:
-                                                       // this should be impossible to get to
-                                                       throw new RuntimeException( "Invalid BOM" );
-                                       }
-                               } else {
-                                       // standard specifically says, if no bom assume utf-8
-                                       $this->charset = 'UTF-8';
-                               }
-                       }
-                       if ( $this->charset !== 'UTF-8' ) {
-                               // don't convert if already utf-8
-                               Wikimedia\suppressWarnings();
-                               $content = iconv( $this->charset, 'UTF-8//IGNORE', $content );
-                               Wikimedia\restoreWarnings();
-                       }
-
-                       // Ensure the XMP block does not have an xml doctype declaration, which
-                       // could declare entities unsafe to parse with xml_parse (T85848/T71210).
-                       if ( $this->parsable !== self::PARSABLE_OK ) {
-                               if ( $this->parsable === self::PARSABLE_NO ) {
-                                       throw new RuntimeException( 'Unsafe doctype declaration in XML.' );
-                               }
-
-                               $content = $this->xmlParsableBuffer . $content;
-                               if ( !$this->checkParseSafety( $content ) ) {
-                                       if ( !$allOfIt && $this->parsable !== self::PARSABLE_NO ) {
-                                               // parse wasn't Unsuccessful yet, so return true
-                                               // in this case.
-                                               return true;
-                                       }
-                                       $msg = ( $this->parsable === self::PARSABLE_NO ) ?
-                                               'Unsafe doctype declaration in XML.' :
-                                               'No root element found in XML.';
-                                       throw new RuntimeException( $msg );
-                               }
-                       }
-
-                       $ok = xml_parse( $this->xmlParser, $content, $allOfIt );
-                       if ( !$ok ) {
-                               $code = xml_get_error_code( $this->xmlParser );
-                               $error = xml_error_string( $code );
-                               $line = xml_get_current_line_number( $this->xmlParser );
-                               $col = xml_get_current_column_number( $this->xmlParser );
-                               $offset = xml_get_current_byte_index( $this->xmlParser );
-
-                               $this->logger->info(
-                                       '{method} : Error reading XMP content: {error} ' .
-                                       '(file: {file}, line: {line} column: {column} ' .
-                                       'byte offset: {offset})',
-                                       [
-                                               'method' => __METHOD__,
-                                               'error_code' => $code,
-                                               'error' => $error,
-                                               'file' => $this->filename,
-                                               'line' => $line,
-                                               'column' => $col,
-                                               'offset' => $offset,
-                                               'content' => $content,
-                               ] );
-                               $this->results = []; // blank if error.
-                               $this->destroyXMLParser();
-                               return false;
-                       }
-               } catch ( Exception $e ) {
-                       $this->logger->warning(
-                               '{method} {exception}',
-                               [
-                                       'method' => __METHOD__,
-                                       'exception' => $e,
-                                       'file' => $this->filename,
-                                       'content' => $content,
-                               ]
-                       );
-                       $this->results = [];
-                       return false;
-               }
-               if ( $allOfIt ) {
-                       $this->destroyXMLParser();
-               }
-
-               return true;
-       }
-
-       /** Entry point for XMPExtended blocks in jpeg files
-        *
-        * @todo In serious need of testing
-        * @see http://www.adobe.ge/devnet/xmp/pdfs/XMPSpecificationPart3.pdf XMP spec part 3 page 20
-        * @param string $content XMPExtended block minus the namespace signature
-        * @return bool If it succeeded.
-        */
-       public function parseExtended( $content ) {
-               // @todo FIXME: This is untested. Hard to find example files
-               // or programs that make such files..
-               $guid = substr( $content, 0, 32 );
-               if ( !isset( $this->results['xmp-special']['HasExtendedXMP'] )
-                       || $this->results['xmp-special']['HasExtendedXMP'] !== $guid
-               ) {
-                       $this->logger->info( __METHOD__ .
-                               " Ignoring XMPExtended block due to wrong guid (guid= '{guid}')",
-                                       [
-                                               'guid' => $guid,
-                                               'file' => $this->filename,
-                                       ]
-                       );
-
-                       return false;
-               }
-               $len = unpack( 'Nlength/Noffset', substr( $content, 32, 8 ) );
-
-               if ( !$len ||
-                       $len['length'] < 4 ||
-                       $len['offset'] < 0 ||
-                       $len['offset'] > $len['length']
-               ) {
-                       $this->logger->info(
-                               __METHOD__ . 'Error reading extended XMP block, invalid length or offset.',
-                               [ 'file' => $this->filename ]
-                       );
-
-                       return false;
-               }
-
-               // we're not very robust here. we should accept it in the wrong order.
-               // To quote the XMP standard:
-               // "A JPEG writer should write the ExtendedXMP marker segments in order,
-               // immediately following the StandardXMP. However, the JPEG standard
-               // does not require preservation of marker segment order. A robust JPEG
-               // reader should tolerate the marker segments in any order."
-               // On the other hand, the probability that an image will have more than
-               // 128k of metadata is rather low... so the probability that it will have
-               // > 128k, and be in the wrong order is very low...
-
-               if ( $len['offset'] !== $this->extendedXMPOffset ) {
-                       $this->logger->info( __METHOD__ . 'Ignoring XMPExtended block due to wrong order. (Offset was '
-                               . $len['offset'] . ' but expected ' . $this->extendedXMPOffset . ')',
-                               [ 'file' => $this->filename ]
-                       );
-
-                       return false;
-               }
-
-               if ( $len['offset'] === 0 ) {
-                       // if we're starting the extended block, we've probably already
-                       // done the XMPStandard block, so reset.
-                       $this->resetXMLParser();
-               }
-
-               $this->extendedXMPOffset += $len['length'];
-
-               $actualContent = substr( $content, 40 );
-
-               if ( $this->extendedXMPOffset === strlen( $actualContent ) ) {
-                       $atEnd = true;
-               } else {
-                       $atEnd = false;
-               }
-
-               $this->logger->debug(
-                       __METHOD__ . 'Parsing a XMPExtended block',
-                       [ 'file' => $this->filename ]
-               );
-
-               return $this->parse( $actualContent, $atEnd );
-       }
-
-       /**
-        * Character data handler
-        * Called whenever character data is found in the xmp document.
-        *
-        * does nothing if we're in MODE_IGNORE or if the data is whitespace
-        * throws an error if we're not in MODE_SIMPLE (as we're not allowed to have character
-        * data in the other modes).
-        *
-        * As an example, this happens when we encounter XMP like:
-        * <exif:DigitalZoomRatio>0/10</exif:DigitalZoomRatio>
-        * and are processing the 0/10 bit.
-        *
-        * @param resource $parser XMLParser reference to the xml parser
-        * @param string $data Character data
-        * @throws RuntimeException On invalid data
-        */
-       function char( $parser, $data ) {
-               $data = trim( $data );
-               if ( trim( $data ) === "" ) {
-                       return;
-               }
-
-               if ( !isset( $this->mode[0] ) ) {
-                       throw new RuntimeException( 'Unexpected character data before first rdf:Description element' );
-               }
-
-               if ( $this->mode[0] === self::MODE_IGNORE ) {
-                       return;
-               }
-
-               if ( $this->mode[0] !== self::MODE_SIMPLE
-                       && $this->mode[0] !== self::MODE_QDESC
-               ) {
-                       throw new RuntimeException( 'character data where not expected. (mode ' . $this->mode[0] . ')' );
-               }
-
-               // to check, how does this handle w.s.
-               if ( $this->charContent === false ) {
-                       $this->charContent = $data;
-               } else {
-                       $this->charContent .= $data;
-               }
-       }
-
-       /**
-        * Check if a block of XML is safe to pass to xml_parse, i.e. doesn't
-        * contain a doctype declaration which could contain a dos attack if we
-        * parse it and expand internal entities (T85848).
-        *
-        * @param string $content xml string to check for parse safety
-        * @return bool true if the xml is safe to parse, false otherwise
-        */
-       private function checkParseSafety( $content ) {
-               $reader = new XMLReader();
-               $result = null;
-
-               // For XMLReader to parse incomplete/invalid XML, it has to be open()'ed
-               // instead of using XML().
-               $reader->open(
-                       'data://text/plain,' . urlencode( $content ),
-                       null,
-                       LIBXML_NOERROR | LIBXML_NOWARNING | LIBXML_NONET
-               );
-
-               $oldDisable = libxml_disable_entity_loader( true );
-               /** @noinspection PhpUnusedLocalVariableInspection */
-               $reset = new ScopedCallback(
-                       'libxml_disable_entity_loader',
-                       [ $oldDisable ]
-               );
-               $reader->setParserProperty( XMLReader::SUBST_ENTITIES, false );
-
-               // Even with LIBXML_NOWARNING set, XMLReader::read gives a warning
-               // when parsing truncated XML, which causes unit tests to fail.
-               Wikimedia\suppressWarnings();
-               while ( $reader->read() ) {
-                       if ( $reader->nodeType === XMLReader::ELEMENT ) {
-                               // Reached the first element without hitting a doctype declaration
-                               $this->parsable = self::PARSABLE_OK;
-                               $result = true;
-                               break;
-                       }
-                       if ( $reader->nodeType === XMLReader::DOC_TYPE ) {
-                               $this->parsable = self::PARSABLE_NO;
-                               $result = false;
-                               break;
-                       }
-               }
-               Wikimedia\restoreWarnings();
-
-               if ( !is_null( $result ) ) {
-                       return $result;
-               }
-
-               // Reached the end of the parsable xml without finding an element
-               // or doctype. Buffer and try again.
-               $this->parsable = self::PARSABLE_BUFFERING;
-               $this->xmlParsableBuffer = $content;
-               return false;
-       }
-
-       /** When we hit a closing element in MODE_IGNORE
-        * Check to see if this is the element we started to ignore,
-        * in which case we get out of MODE_IGNORE
-        *
-        * @param string $elm Namespace of element followed by a space and then tag name of element.
-        */
-       private function endElementModeIgnore( $elm ) {
-               if ( $this->curItem[0] === $elm ) {
-                       array_shift( $this->curItem );
-                       array_shift( $this->mode );
-               }
-       }
-
-       /**
-        * Hit a closing element when in MODE_SIMPLE.
-        * This generally means that we finished processing a
-        * property value, and now have to save the result to the
-        * results array
-        *
-        * For example, when processing:
-        * <exif:DigitalZoomRatio>0/10</exif:DigitalZoomRatio>
-        * this deals with when we hit </exif:DigitalZoomRatio>.
-        *
-        * Or it could be if we hit the end element of a property
-        * of a compound data structure (like a member of an array).
-        *
-        * @param string $elm Namespace, space, and tag name.
-        */
-       private function endElementModeSimple( $elm ) {
-               if ( $this->charContent !== false ) {
-                       if ( $this->processingArray ) {
-                               // if we're processing an array, use the original element
-                               // name instead of rdf:li.
-                               list( $ns, $tag ) = explode( ' ', $this->curItem[0], 2 );
-                       } else {
-                               list( $ns, $tag ) = explode( ' ', $elm, 2 );
-                       }
-                       $this->saveValue( $ns, $tag, $this->charContent );
-
-                       $this->charContent = false; // reset
-               }
-               array_shift( $this->curItem );
-               array_shift( $this->mode );
-       }
-
-       /**
-        * Hit a closing element in MODE_STRUCT, MODE_SEQ, MODE_BAG
-        * generally means we've finished processing a nested structure.
-        * resets some internal variables to indicate that.
-        *
-        * Note this means we hit the closing element not the "</rdf:Seq>".
-        *
-        * @par For example, when processing:
-        * @code{,xml}
-        * <exif:ISOSpeedRatings> <rdf:Seq> <rdf:li>64</rdf:li>
-        *   </rdf:Seq> </exif:ISOSpeedRatings>
-        * @endcode
-        *
-        * This method is called when we hit the "</exif:ISOSpeedRatings>" tag.
-        *
-        * @param string $elm Namespace . space . tag name.
-        * @throws RuntimeException
-        */
-       private function endElementNested( $elm ) {
-               /* cur item must be the same as $elm, unless if in MODE_STRUCT
-                * in which case it could also be rdf:Description */
-               if ( $this->curItem[0] !== $elm
-                       && !( $elm === self::NS_RDF . ' Description'
-                               && $this->mode[0] === self::MODE_STRUCT )
-               ) {
-                       throw new RuntimeException( "nesting mismatch. got a </$elm> but expected a </" .
-                               $this->curItem[0] . '>' );
-               }
-
-               // Validate structures.
-               list( $ns, $tag ) = explode( ' ', $elm, 2 );
-               if ( isset( $this->items[$ns][$tag]['validate'] ) ) {
-                       $info =& $this->items[$ns][$tag];
-                       $finalName = isset( $info['map_name'] )
-                               ? $info['map_name'] : $tag;
-
-                       if ( is_array( $info['validate'] ) ) {
-                               $validate = $info['validate'];
-                       } else {
-                               $validator = new XMPValidate( $this->logger );
-                               $validate = [ $validator, $info['validate'] ];
-                       }
-
-                       if ( !isset( $this->results['xmp-' . $info['map_group']][$finalName] ) ) {
-                               // This can happen if all the members of the struct failed validation.
-                               $this->logger->debug(
-                                       __METHOD__ . " <$ns:$tag> has no valid members.",
-                                       [ 'file' => $this->filename ]
-                               );
-                       } elseif ( is_callable( $validate ) ) {
-                               $val =& $this->results['xmp-' . $info['map_group']][$finalName];
-                               call_user_func_array( $validate, [ $info, &$val, false ] );
-                               if ( is_null( $val ) ) {
-                                       // the idea being the validation function will unset the variable if
-                                       // its invalid.
-                                       $this->logger->info(
-                                               __METHOD__ . " <$ns:$tag> failed validation.",
-                                               [ 'file' => $this->filename ]
-                                       );
-                                       unset( $this->results['xmp-' . $info['map_group']][$finalName] );
-                               }
-                       } else {
-                               $this->logger->warning(
-                                       __METHOD__ . " Validation function for $finalName (" .
-                                       $validate[0] . '::' . $validate[1] . '()) is not callable.',
-                                       [ 'file' => $this->filename ]
-                               );
-                       }
-               }
-
-               array_shift( $this->curItem );
-               array_shift( $this->mode );
-               $this->ancestorStruct = false;
-               $this->processingArray = false;
-               $this->itemLang = false;
-       }
-
-       /**
-        * Hit a closing element in MODE_LI (either rdf:Seq, or rdf:Bag )
-        * Add information about what type of element this is.
-        *
-        * Note we still have to hit the outer "</property>"
-        *
-        * @par For example, when processing:
-        * @code{,xml}
-        * <exif:ISOSpeedRatings> <rdf:Seq> <rdf:li>64</rdf:li>
-        *   </rdf:Seq> </exif:ISOSpeedRatings>
-        * @endcode
-        *
-        * This method is called when we hit the "</rdf:Seq>".
-        * (For comparison, we call endElementModeSimple when we
-        * hit the "</rdf:li>")
-        *
-        * @param string $elm Namespace . ' ' . element name
-        * @throws RuntimeException
-        */
-       private function endElementModeLi( $elm ) {
-               list( $ns, $tag ) = explode( ' ', $this->curItem[0], 2 );
-               $info = $this->items[$ns][$tag];
-               $finalName = isset( $info['map_name'] )
-                       ? $info['map_name'] : $tag;
-
-               array_shift( $this->mode );
-
-               if ( !isset( $this->results['xmp-' . $info['map_group']][$finalName] ) ) {
-                       $this->logger->debug(
-                               __METHOD__ . " Empty compund element $finalName.",
-                               [ 'file' => $this->filename ]
-                       );
-
-                       return;
-               }
-
-               if ( $elm === self::NS_RDF . ' Seq' ) {
-                       $this->results['xmp-' . $info['map_group']][$finalName]['_type'] = 'ol';
-               } elseif ( $elm === self::NS_RDF . ' Bag' ) {
-                       $this->results['xmp-' . $info['map_group']][$finalName]['_type'] = 'ul';
-               } elseif ( $elm === self::NS_RDF . ' Alt' ) {
-                       // extra if needed as you could theoretically have a non-language alt.
-                       if ( $info['mode'] === self::MODE_LANG ) {
-                               $this->results['xmp-' . $info['map_group']][$finalName]['_type'] = 'lang';
-                       }
-               } else {
-                       throw new RuntimeException(
-                               __METHOD__ . " expected </rdf:seq> or </rdf:bag> but instead got $elm."
-                       );
-               }
-       }
-
-       /**
-        * End element while in MODE_QDESC
-        * mostly when ending an element when we have a simple value
-        * that has qualifiers.
-        *
-        * Qualifiers aren't all that common, and we don't do anything
-        * with them.
-        *
-        * @param string $elm Namespace and element
-        */
-       private function endElementModeQDesc( $elm ) {
-               if ( $elm === self::NS_RDF . ' value' ) {
-                       list( $ns, $tag ) = explode( ' ', $this->curItem[0], 2 );
-                       $this->saveValue( $ns, $tag, $this->charContent );
-
-                       return;
-               } else {
-                       array_shift( $this->mode );
-                       array_shift( $this->curItem );
-               }
-       }
-
-       /**
-        * Handler for hitting a closing element.
-        *
-        * generally just calls a helper function depending on what
-        * mode we're in.
-        *
-        * Ignores the outer wrapping elements that are optional in
-        * xmp and have no meaning.
-        *
-        * @param resource $parser
-        * @param string $elm Namespace . ' ' . element name
-        * @throws RuntimeException
-        */
-       function endElement( $parser, $elm ) {
-               if ( $elm === ( self::NS_RDF . ' RDF' )
-                       || $elm === 'adobe:ns:meta/ xmpmeta'
-                       || $elm === 'adobe:ns:meta/ xapmeta'
-               ) {
-                       // ignore these.
-                       return;
-               }
-
-               if ( $elm === self::NS_RDF . ' type' ) {
-                       // these aren't really supported properly yet.
-                       // However, it appears they almost never used.
-                       $this->logger->info(
-                               __METHOD__ . ' encountered <rdf:type>',
-                               [ 'file' => $this->filename ]
-                       );
-               }
-
-               if ( strpos( $elm, ' ' ) === false ) {
-                       // This probably shouldn't happen.
-                       // However, there is a bug in an adobe product
-                       // that forgets the namespace on some things.
-                       // (Luckily they are unimportant things).
-                       $this->logger->info(
-                               __METHOD__ . " Encountered </$elm> which has no namespace. Skipping.",
-                               [ 'file' => $this->filename ]
-                       );
-
-                       return;
-               }
-
-               if ( count( $this->mode ) === 0 ) {
-                       // This should never ever happen and means
-                       // there is a pretty major bug in this class.
-                       throw new RuntimeException( 'Encountered end element with no mode' );
-               }
-
-               if ( count( $this->curItem ) == 0 && $this->mode[0] !== self::MODE_INITIAL ) {
-                       // just to be paranoid. Should always have a curItem, except for initially
-                       // (aka during MODE_INITAL).
-                       throw new RuntimeException( "Hit end element </$elm> but no curItem" );
-               }
-
-               switch ( $this->mode[0] ) {
-                       case self::MODE_IGNORE:
-                               $this->endElementModeIgnore( $elm );
-                               break;
-                       case self::MODE_SIMPLE:
-                               $this->endElementModeSimple( $elm );
-                               break;
-                       case self::MODE_STRUCT:
-                       case self::MODE_SEQ:
-                       case self::MODE_BAG:
-                       case self::MODE_LANG:
-                       case self::MODE_BAGSTRUCT:
-                               $this->endElementNested( $elm );
-                               break;
-                       case self::MODE_INITIAL:
-                               if ( $elm === self::NS_RDF . ' Description' ) {
-                                       array_shift( $this->mode );
-                               } else {
-                                       throw new RuntimeException( 'Element ended unexpectedly while in MODE_INITIAL' );
-                               }
-                               break;
-                       case self::MODE_LI:
-                       case self::MODE_LI_LANG:
-                               $this->endElementModeLi( $elm );
-                               break;
-                       case self::MODE_QDESC:
-                               $this->endElementModeQDesc( $elm );
-                               break;
-                       default:
-                               $this->logger->info(
-                                       __METHOD__ . " no mode (elm = $elm)",
-                                       [ 'file' => $this->filename ]
-                               );
-                               break;
-               }
-       }
-
-       /**
-        * Hit an opening element while in MODE_IGNORE
-        *
-        * XMP is extensible, so ignore any tag we don't understand.
-        *
-        * Mostly ignores, unless we encounter the element that we are ignoring.
-        * in which case we add it to the item stack, so we can ignore things
-        * that are nested, correctly.
-        *
-        * @param string $elm Namespace . ' ' . tag name
-        */
-       private function startElementModeIgnore( $elm ) {
-               if ( $elm === $this->curItem[0] ) {
-                       array_unshift( $this->curItem, $elm );
-                       array_unshift( $this->mode, self::MODE_IGNORE );
-               }
-       }
-
-       /**
-        *  Start element in MODE_BAG (unordered array)
-        * this should always be <rdf:Bag>
-        *
-        * @param string $elm Namespace . ' ' . tag
-        * @throws RuntimeException If we have an element that's not <rdf:Bag>
-        */
-       private function startElementModeBag( $elm ) {
-               if ( $elm === self::NS_RDF . ' Bag' ) {
-                       array_unshift( $this->mode, self::MODE_LI );
-               } else {
-                       throw new RuntimeException( "Expected <rdf:Bag> but got $elm." );
-               }
-       }
-
-       /**
-        * Start element in MODE_SEQ (ordered array)
-        * this should always be <rdf:Seq>
-        *
-        * @param string $elm Namespace . ' ' . tag
-        * @throws RuntimeException If we have an element that's not <rdf:Seq>
-        */
-       private function startElementModeSeq( $elm ) {
-               if ( $elm === self::NS_RDF . ' Seq' ) {
-                       array_unshift( $this->mode, self::MODE_LI );
-               } elseif ( $elm === self::NS_RDF . ' Bag' ) {
-                       # T29105
-                       $this->logger->info(
-                               __METHOD__ . ' Expected an rdf:Seq, but got an rdf:Bag. Pretending' .
-                               ' it is a Seq, since some buggy software is known to screw this up.',
-                               [ 'file' => $this->filename ]
-                       );
-                       array_unshift( $this->mode, self::MODE_LI );
-               } else {
-                       throw new RuntimeException( "Expected <rdf:Seq> but got $elm." );
-               }
-       }
-
-       /**
-        * Start element in MODE_LANG (language alternative)
-        * this should always be <rdf:Alt>
-        *
-        * This tag tends to be used for metadata like describe this
-        * picture, which can be translated into multiple languages.
-        *
-        * XMP supports non-linguistic alternative selections,
-        * which are really only used for thumbnails, which
-        * we don't care about.
-        *
-        * @param string $elm Namespace . ' ' . tag
-        * @throws RuntimeException If we have an element that's not <rdf:Alt>
-        */
-       private function startElementModeLang( $elm ) {
-               if ( $elm === self::NS_RDF . ' Alt' ) {
-                       array_unshift( $this->mode, self::MODE_LI_LANG );
-               } else {
-                       throw new RuntimeException( "Expected <rdf:Seq> but got $elm." );
-               }
-       }
-
-       /**
-        * Handle an opening element when in MODE_SIMPLE
-        *
-        * This should not happen often. This is for if a simple element
-        * already opened has a child element. Could happen for a
-        * qualified element.
-        *
-        * For example:
-        * <exif:DigitalZoomRatio><rdf:Description><rdf:value>0/10</rdf:value>
-        *   <foo:someQualifier>Bar</foo:someQualifier> </rdf:Description>
-        *   </exif:DigitalZoomRatio>
-        *
-        * This method is called when processing the <rdf:Description> element
-        *
-        * @param string $elm Namespace and tag names separated by space.
-        * @param array $attribs Attributes of the element.
-        * @throws RuntimeException
-        */
-       private function startElementModeSimple( $elm, $attribs ) {
-               if ( $elm === self::NS_RDF . ' Description' ) {
-                       // If this value has qualifiers
-                       array_unshift( $this->mode, self::MODE_QDESC );
-                       array_unshift( $this->curItem, $this->curItem[0] );
-
-                       if ( isset( $attribs[self::NS_RDF . ' value'] ) ) {
-                               list( $ns, $tag ) = explode( ' ', $this->curItem[0], 2 );
-                               $this->saveValue( $ns, $tag, $attribs[self::NS_RDF . ' value'] );
-                       }
-               } elseif ( $elm === self::NS_RDF . ' value' ) {
-                       // This should not be here.
-                       throw new RuntimeException( __METHOD__ . ' Encountered <rdf:value> where it was unexpected.' );
-               } else {
-                       // something else we don't recognize, like a qualifier maybe.
-                       $this->logger->info( __METHOD__ .
-                               " Encountered element <{element}> where only expecting character data as value of {curitem}",
-                               [
-                                       'element' => $elm,
-                                       'curitem' => $this->curItem[0],
-                                       'file' => $this->filename,
-                               ]
-                       );
-                       array_unshift( $this->mode, self::MODE_IGNORE );
-                       array_unshift( $this->curItem, $elm );
-               }
-       }
-
-       /**
-        * Start an element when in MODE_QDESC.
-        * This generally happens when a simple element has an inner
-        * rdf:Description to hold qualifier elements.
-        *
-        * For example in:
-        * <exif:DigitalZoomRatio><rdf:Description><rdf:value>0/10</rdf:value>
-        *   <foo:someQualifier>Bar</foo:someQualifier> </rdf:Description>
-        *   </exif:DigitalZoomRatio>
-        * Called when processing the <rdf:value> or <foo:someQualifier>.
-        *
-        * @param string $elm Namespace and tag name separated by a space.
-        */
-       private function startElementModeQDesc( $elm ) {
-               if ( $elm === self::NS_RDF . ' value' ) {
-                       return; // do nothing
-               } else {
-                       // otherwise its a qualifier, which we ignore
-                       array_unshift( $this->mode, self::MODE_IGNORE );
-                       array_unshift( $this->curItem, $elm );
-               }
-       }
-
-       /**
-        * Starting an element when in MODE_INITIAL
-        * This usually happens when we hit an element inside
-        * the outer rdf:Description
-        *
-        * This is generally where most properties start.
-        *
-        * @param string $ns Namespace
-        * @param string $tag Tag name (without namespace prefix)
-        * @param array $attribs Array of attributes
-        * @throws RuntimeException
-        */
-       private function startElementModeInitial( $ns, $tag, $attribs ) {
-               if ( $ns !== self::NS_RDF ) {
-                       if ( isset( $this->items[$ns][$tag] ) ) {
-                               if ( isset( $this->items[$ns][$tag]['structPart'] ) ) {
-                                       // If this element is supposed to appear only as
-                                       // a child of a structure, but appears here (not as
-                                       // a child of a struct), then something weird is
-                                       // happening, so ignore this element and its children.
-
-                                       $this->logger->info(
-                                               'Encountered <{element}> outside of its expected parent. Ignoring.',
-                                               [ 'element' => "$ns:$tag", 'file' => $this->filename ]
-                                       );
-
-                                       array_unshift( $this->mode, self::MODE_IGNORE );
-                                       array_unshift( $this->curItem, $ns . ' ' . $tag );
-
-                                       return;
-                               }
-                               $mode = $this->items[$ns][$tag]['mode'];
-                               array_unshift( $this->mode, $mode );
-                               array_unshift( $this->curItem, $ns . ' ' . $tag );
-                               if ( $mode === self::MODE_STRUCT ) {
-                                       $this->ancestorStruct = isset( $this->items[$ns][$tag]['map_name'] )
-                                               ? $this->items[$ns][$tag]['map_name'] : $tag;
-                               }
-                               if ( $this->charContent !== false ) {
-                                       // Something weird.
-                                       // Should not happen in valid XMP.
-                                       throw new RuntimeException( 'tag nested in non-whitespace characters.' );
-                               }
-                       } else {
-                               // This element is not on our list of allowed elements so ignore.
-                               $this->logger->debug( __METHOD__ . ' Ignoring unrecognized element <{element}>.',
-                                       [ 'element' => "$ns:$tag", 'file' => $this->filename ] );
-                               array_unshift( $this->mode, self::MODE_IGNORE );
-                               array_unshift( $this->curItem, $ns . ' ' . $tag );
-
-                               return;
-                       }
-               }
-               // process attributes
-               $this->doAttribs( $attribs );
-       }
-
-       /**
-        * Hit an opening element when in a Struct (MODE_STRUCT)
-        * This is generally for fields of a compound property.
-        *
-        * Example of a struct (abbreviated; flash has more properties):
-        *
-        * <exif:Flash> <rdf:Description> <exif:Fired>True</exif:Fired>
-        *  <exif:Mode>1</exif:Mode></rdf:Description></exif:Flash>
-        *
-        * or:
-        *
-        * <exif:Flash rdf:parseType='Resource'> <exif:Fired>True</exif:Fired>
-        *  <exif:Mode>1</exif:Mode></exif:Flash>
-        *
-        * @param string $ns Namespace
-        * @param string $tag Tag name (no ns)
-        * @param array $attribs Array of attribs w/ values.
-        * @throws RuntimeException
-        */
-       private function startElementModeStruct( $ns, $tag, $attribs ) {
-               if ( $ns !== self::NS_RDF ) {
-                       if ( isset( $this->items[$ns][$tag] ) ) {
-                               if ( isset( $this->items[$ns][$this->ancestorStruct]['children'] )
-                                       && !isset( $this->items[$ns][$this->ancestorStruct]['children'][$tag] )
-                               ) {
-                                       // This assumes that we don't have inter-namespace nesting
-                                       // which we don't in all the properties we're interested in.
-                                       throw new RuntimeException( " <$tag> appeared nested in <" . $this->ancestorStruct
-                                               . "> where it is not allowed." );
-                               }
-                               array_unshift( $this->mode, $this->items[$ns][$tag]['mode'] );
-                               array_unshift( $this->curItem, $ns . ' ' . $tag );
-                               if ( $this->charContent !== false ) {
-                                       // Something weird.
-                                       // Should not happen in valid XMP.
-                                       throw new RuntimeException( "tag <$tag> nested in non-whitespace characters (" .
-                                               $this->charContent . ")." );
-                               }
-                       } else {
-                               array_unshift( $this->mode, self::MODE_IGNORE );
-                               array_unshift( $this->curItem, $ns . ' ' . $tag );
-
-                               return;
-                       }
-               }
-
-               if ( $ns === self::NS_RDF && $tag === 'Description' ) {
-                       $this->doAttribs( $attribs );
-                       array_unshift( $this->mode, self::MODE_STRUCT );
-                       array_unshift( $this->curItem, $this->curItem[0] );
-               }
-       }
-
-       /**
-        * opening element in MODE_LI
-        * process elements of arrays.
-        *
-        * Example:
-        * <exif:ISOSpeedRatings> <rdf:Seq> <rdf:li>64</rdf:li>
-        *   </rdf:Seq> </exif:ISOSpeedRatings>
-        * This method is called when we hit the <rdf:li> element.
-        *
-        * @param string $elm Namespace . ' ' . tagname
-        * @param array $attribs Attributes. (needed for BAGSTRUCTS)
-        * @throws RuntimeException If gets a tag other than <rdf:li>
-        */
-       private function startElementModeLi( $elm, $attribs ) {
-               if ( ( $elm ) !== self::NS_RDF . ' li' ) {
-                       throw new RuntimeException( "<rdf:li> expected but got $elm." );
-               }
-
-               if ( !isset( $this->mode[1] ) ) {
-                       // This should never ever ever happen. Checking for it
-                       // to be paranoid.
-                       throw new RuntimeException( 'In mode Li, but no 2xPrevious mode!' );
-               }
-
-               if ( $this->mode[1] === self::MODE_BAGSTRUCT ) {
-                       // This list item contains a compound (STRUCT) value.
-                       array_unshift( $this->mode, self::MODE_STRUCT );
-                       array_unshift( $this->curItem, $elm );
-                       $this->processingArray = true;
-
-                       if ( !isset( $this->curItem[1] ) ) {
-                               // be paranoid.
-                               throw new RuntimeException( 'Can not find parent of BAGSTRUCT.' );
-                       }
-                       list( $curNS, $curTag ) = explode( ' ', $this->curItem[1] );
-                       $this->ancestorStruct = isset( $this->items[$curNS][$curTag]['map_name'] )
-                               ? $this->items[$curNS][$curTag]['map_name'] : $curTag;
-
-                       $this->doAttribs( $attribs );
-               } else {
-                       // Normal BAG or SEQ containing simple values.
-                       array_unshift( $this->mode, self::MODE_SIMPLE );
-                       // need to add curItem[0] on again since one is for the specific item
-                       // and one is for the entire group.
-                       array_unshift( $this->curItem, $this->curItem[0] );
-                       $this->processingArray = true;
-               }
-       }
-
-       /**
-        * Opening element in MODE_LI_LANG.
-        * process elements of language alternatives
-        *
-        * Example:
-        * <dc:title> <rdf:Alt> <rdf:li xml:lang="x-default">My house
-        *  </rdf:li> </rdf:Alt> </dc:title>
-        *
-        * This method is called when we hit the <rdf:li> element.
-        *
-        * @param string $elm Namespace . ' ' . tag
-        * @param array $attribs Array of elements (most importantly xml:lang)
-        * @throws RuntimeException If gets a tag other than <rdf:li> or if no xml:lang
-        */
-       private function startElementModeLiLang( $elm, $attribs ) {
-               if ( $elm !== self::NS_RDF . ' li' ) {
-                       throw new RuntimeException( __METHOD__ . " <rdf:li> expected but got $elm." );
-               }
-               if ( !isset( $attribs[self::NS_XML . ' lang'] )
-                       || !preg_match( '/^[-A-Za-z0-9]{2,}$/D', $attribs[self::NS_XML . ' lang'] )
-               ) {
-                       throw new RuntimeException( __METHOD__
-                               . " <rdf:li> did not contain, or has invalid xml:lang attribute in lang alternative" );
-               }
-
-               // Lang is case-insensitive.
-               $this->itemLang = strtolower( $attribs[self::NS_XML . ' lang'] );
-
-               // need to add curItem[0] on again since one is for the specific item
-               // and one is for the entire group.
-               array_unshift( $this->curItem, $this->curItem[0] );
-               array_unshift( $this->mode, self::MODE_SIMPLE );
-               $this->processingArray = true;
-       }
-
-       /**
-        * Hits an opening element.
-        * Generally just calls a helper based on what MODE we're in.
-        * Also does some initial set up for the wrapper element
-        *
-        * @param resource $parser
-        * @param string $elm Namespace "<space>" element
-        * @param array $attribs Attribute name => value
-        * @throws RuntimeException
-        */
-       function startElement( $parser, $elm, $attribs ) {
-               if ( $elm === self::NS_RDF . ' RDF'
-                       || $elm === 'adobe:ns:meta/ xmpmeta'
-                       || $elm === 'adobe:ns:meta/ xapmeta'
-               ) {
-                       /* ignore. */
-                       return;
-               } elseif ( $elm === self::NS_RDF . ' Description' ) {
-                       if ( count( $this->mode ) === 0 ) {
-                               // outer rdf:desc
-                               array_unshift( $this->mode, self::MODE_INITIAL );
-                       }
-               } elseif ( $elm === self::NS_RDF . ' type' ) {
-                       // This doesn't support rdf:type properly.
-                       // In practise I have yet to see a file that
-                       // uses this element, however it is mentioned
-                       // on page 25 of part 1 of the xmp standard.
-                       // Also it seems as if exiv2 and exiftool do not support
-                       // this either (That or I misunderstand the standard)
-                       $this->logger->info(
-                               __METHOD__ . ' Encountered <rdf:type> which isn\'t currently supported',
-                               [ 'file' => $this->filename ]
-                       );
-               }
-
-               if ( strpos( $elm, ' ' ) === false ) {
-                       // This probably shouldn't happen.
-                       $this->logger->info(
-                               __METHOD__ . " Encountered <$elm> which has no namespace. Skipping.",
-                               [ 'file' => $this->filename ]
-                       );
-
-                       return;
-               }
-
-               list( $ns, $tag ) = explode( ' ', $elm, 2 );
-
-               if ( count( $this->mode ) === 0 ) {
-                       // This should not happen.
-                       throw new RuntimeException( 'Error extracting XMP, '
-                               . "encountered <$elm> with no mode" );
-               }
-
-               switch ( $this->mode[0] ) {
-                       case self::MODE_IGNORE:
-                               $this->startElementModeIgnore( $elm );
-                               break;
-                       case self::MODE_SIMPLE:
-                               $this->startElementModeSimple( $elm, $attribs );
-                               break;
-                       case self::MODE_INITIAL:
-                               $this->startElementModeInitial( $ns, $tag, $attribs );
-                               break;
-                       case self::MODE_STRUCT:
-                               $this->startElementModeStruct( $ns, $tag, $attribs );
-                               break;
-                       case self::MODE_BAG:
-                       case self::MODE_BAGSTRUCT:
-                               $this->startElementModeBag( $elm );
-                               break;
-                       case self::MODE_SEQ:
-                               $this->startElementModeSeq( $elm );
-                               break;
-                       case self::MODE_LANG:
-                               $this->startElementModeLang( $elm );
-                               break;
-                       case self::MODE_LI_LANG:
-                               $this->startElementModeLiLang( $elm, $attribs );
-                               break;
-                       case self::MODE_LI:
-                               $this->startElementModeLi( $elm, $attribs );
-                               break;
-                       case self::MODE_QDESC:
-                               $this->startElementModeQDesc( $elm );
-                               break;
-                       default:
-                               throw new RuntimeException( 'StartElement in unknown mode: ' . $this->mode[0] );
-               }
-       }
-
-       // phpcs:disable Generic.Files.LineLength
-       /**
-        * Process attributes.
-        * Simple values can be stored as either a tag or attribute
-        *
-        * Often the initial "<rdf:Description>" tag just has all the simple
-        * properties as attributes.
-        *
-        * @par Example:
-        * @code
-        * <rdf:Description rdf:about="" xmlns:exif="http://ns.adobe.com/exif/1.0/" exif:DigitalZoomRatio="0/10">
-        * @endcode
-        *
-        * @param array $attribs Array attribute=>value
-        * @throws RuntimeException
-        */
-       // phpcs:enable
-       private function doAttribs( $attribs ) {
-               // first check for rdf:parseType attribute, as that can change
-               // how the attributes are interperted.
-
-               if ( isset( $attribs[self::NS_RDF . ' parseType'] )
-                       && $attribs[self::NS_RDF . ' parseType'] === 'Resource'
-                       && $this->mode[0] === self::MODE_SIMPLE
-               ) {
-                       // this is equivalent to having an inner rdf:Description
-                       $this->mode[0] = self::MODE_QDESC;
-               }
-               foreach ( $attribs as $name => $val ) {
-                       if ( strpos( $name, ' ' ) === false ) {
-                               // This shouldn't happen, but so far some old software forgets namespace
-                               // on rdf:about.
-                               $this->logger->info(
-                                       __METHOD__ . ' Encountered non-namespaced attribute: ' .
-                                       " $name=\"$val\". Skipping. ",
-                                       [ 'file' => $this->filename ]
-                               );
-                               continue;
-                       }
-                       list( $ns, $tag ) = explode( ' ', $name, 2 );
-                       if ( $ns === self::NS_RDF ) {
-                               if ( $tag === 'value' || $tag === 'resource' ) {
-                                       // resource is for url.
-                                       // value attribute is a weird way of just putting the contents.
-                                       $this->char( $this->xmlParser, $val );
-                               }
-                       } elseif ( isset( $this->items[$ns][$tag] ) ) {
-                               if ( $this->mode[0] === self::MODE_SIMPLE ) {
-                                       throw new RuntimeException( __METHOD__
-                                               . " $ns:$tag found as attribute where not allowed" );
-                               }
-                               $this->saveValue( $ns, $tag, $val );
-                       } else {
-                               $this->logger->debug(
-                                       __METHOD__ . " Ignoring unrecognized element <$ns:$tag>.",
-                                       [ 'file' => $this->filename ]
-                               );
-                       }
-               }
-       }
-
-       /**
-        * Given an extracted value, save it to results array
-        *
-        * note also uses $this->ancestorStruct and
-        * $this->processingArray to determine what name to
-        * save the value under. (in addition to $tag).
-        *
-        * @param string $ns Namespace of tag this is for
-        * @param string $tag Tag name
-        * @param string $val Value to save
-        */
-       private function saveValue( $ns, $tag, $val ) {
-               $info =& $this->items[$ns][$tag];
-               $finalName = isset( $info['map_name'] )
-                       ? $info['map_name'] : $tag;
-               if ( isset( $info['validate'] ) ) {
-                       if ( is_array( $info['validate'] ) ) {
-                               $validate = $info['validate'];
-                       } else {
-                               $validator = new XMPValidate( $this->logger );
-                               $validate = [ $validator, $info['validate'] ];
-                       }
-
-                       if ( is_callable( $validate ) ) {
-                               call_user_func_array( $validate, [ $info, &$val, true ] );
-                               // the reasoning behind using &$val instead of using the return value
-                               // is to be consistent between here and validating structures.
-                               if ( is_null( $val ) ) {
-                                       $this->logger->info(
-                                               __METHOD__ . " <$ns:$tag> failed validation.",
-                                               [ 'file' => $this->filename ]
-                                       );
-
-                                       return;
-                               }
-                       } else {
-                               $this->logger->warning(
-                                       __METHOD__ . " Validation function for $finalName (" .
-                                       $validate[0] . '::' . $validate[1] . '()) is not callable.',
-                                       [ 'file' => $this->filename ]
-                               );
-                       }
-               }
-
-               if ( $this->ancestorStruct && $this->processingArray ) {
-                       // Aka both an array and a struct. ( self::MODE_BAGSTRUCT )
-                       $this->results['xmp-' . $info['map_group']][$this->ancestorStruct][][$finalName] = $val;
-               } elseif ( $this->ancestorStruct ) {
-                       $this->results['xmp-' . $info['map_group']][$this->ancestorStruct][$finalName] = $val;
-               } elseif ( $this->processingArray ) {
-                       if ( $this->itemLang === false ) {
-                               // normal array
-                               $this->results['xmp-' . $info['map_group']][$finalName][] = $val;
-                       } else {
-                               // lang array.
-                               $this->results['xmp-' . $info['map_group']][$finalName][$this->itemLang] = $val;
-                       }
-               } else {
-                       $this->results['xmp-' . $info['map_group']][$finalName] = $val;
-               }
-       }
-}
diff --git a/includes/libs/xmp/XMPInfo.php b/includes/libs/xmp/XMPInfo.php
deleted file mode 100644 (file)
index 5211a2c..0000000
+++ /dev/null
@@ -1,1168 +0,0 @@
-<?php
-/**
- * Definitions for XMPReader class.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- * @ingroup Media
- */
-
-/**
- * This class is just a container for a big array
- * used by XMPReader to determine which XMP items to
- * extract.
- */
-class XMPInfo {
-       /** Get the items array
-        * @return array XMP item configuration array.
-        */
-       public static function getItems() {
-               return self::$items;
-       }
-
-       /**
-        * XMPInfo::$items keeps a list of all the items
-        * we are interested to extract, as well as
-        * information about the item like what type
-        * it is.
-        *
-        * Format is an array of namespaces,
-        * each containing an array of tags
-        * each tag is an array of information about the
-        * tag, including:
-        *   * map_group - What group (used for precedence during conflicts).
-        *   * mode - What type of item (self::MODE_SIMPLE usually, see above for
-        *     all values).
-        *   * validate - Method to validate input. Could also post-process the
-        *     input. A string value is assumed to be a method of
-        *     XMPValidate. Can also take a array( 'className', 'methodName' ).
-        *   * choices - Array of potential values (format of 'value' => true ).
-        *     Only used with validateClosed.
-        *   * rangeLow and rangeHigh - Alternative to choices for numeric ranges.
-        *     Again for validateClosed only.
-        *   * children - For MODE_STRUCT items, allowed children.
-        *   * structPart - Indicates that this element can only appear as a member
-        *     of a structure.
-        *
-        * Currently this just has a bunch of EXIF values as this class is only half-done.
-        */
-       static private $items = [
-               'http://ns.adobe.com/exif/1.0/' => [
-                       'ApertureValue' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateRational'
-                       ],
-                       'BrightnessValue' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateRational'
-                       ],
-                       'CompressedBitsPerPixel' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateRational'
-                       ],
-                       'DigitalZoomRatio' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateRational'
-                       ],
-                       'ExposureBiasValue' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateRational'
-                       ],
-                       'ExposureIndex' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateRational'
-                       ],
-                       'ExposureTime' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateRational'
-                       ],
-                       'FlashEnergy' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateRational',
-                       ],
-                       'FNumber' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateRational'
-                       ],
-                       'FocalLength' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateRational'
-                       ],
-                       'FocalPlaneXResolution' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateRational'
-                       ],
-                       'FocalPlaneYResolution' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateRational'
-                       ],
-                       'GPSAltitude' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateRational',
-                       ],
-                       'GPSDestBearing' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateRational'
-                       ],
-                       'GPSDestDistance' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateRational'
-                       ],
-                       'GPSDOP' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateRational'
-                       ],
-                       'GPSImgDirection' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateRational'
-                       ],
-                       'GPSSpeed' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateRational'
-                       ],
-                       'GPSTrack' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateRational'
-                       ],
-                       'MaxApertureValue' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateRational'
-                       ],
-                       'ShutterSpeedValue' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateRational'
-                       ],
-                       'SubjectDistance' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateRational'
-                       ],
-                       /* Flash */
-                       'Flash' => [
-                               'mode' => XMPReader::MODE_STRUCT,
-                               'children' => [
-                                       'Fired' => true,
-                                       'Function' => true,
-                                       'Mode' => true,
-                                       'RedEyeMode' => true,
-                                       'Return' => true,
-                               ],
-                               'validate' => 'validateFlash',
-                               'map_group' => 'exif',
-                       ],
-                       'Fired' => [
-                               'map_group' => 'exif',
-                               'validate' => 'validateBoolean',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'structPart' => true,
-                       ],
-                       'Function' => [
-                               'map_group' => 'exif',
-                               'validate' => 'validateBoolean',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'structPart' => true,
-                       ],
-                       'Mode' => [
-                               'map_group' => 'exif',
-                               'validate' => 'validateClosed',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'choices' => [ '0' => true, '1' => true,
-                                       '2' => true, '3' => true ],
-                               'structPart' => true,
-                       ],
-                       'Return' => [
-                               'map_group' => 'exif',
-                               'validate' => 'validateClosed',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'choices' => [ '0' => true,
-                                       '2' => true, '3' => true ],
-                               'structPart' => true,
-                       ],
-                       'RedEyeMode' => [
-                               'map_group' => 'exif',
-                               'validate' => 'validateBoolean',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'structPart' => true,
-                       ],
-                       /* End Flash */
-                       'ISOSpeedRatings' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SEQ,
-                               'validate' => 'validateInteger'
-                       ],
-                       /* end rational things */
-                       'ColorSpace' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateClosed',
-                               'choices' => [ '1' => true, '65535' => true ],
-                       ],
-                       'ComponentsConfiguration' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SEQ,
-                               'validate' => 'validateClosed',
-                               'choices' => [ '1' => true, '2' => true, '3' => true, '4' => true,
-                                       '5' => true, '6' => true ]
-                       ],
-                       'Contrast' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateClosed',
-                               'choices' => [ '0' => true, '1' => true, '2' => true ]
-                       ],
-                       'CustomRendered' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateClosed',
-                               'choices' => [ '0' => true, '1' => true ]
-                       ],
-                       'DateTimeOriginal' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateDate',
-                       ],
-                       'DateTimeDigitized' => [ /* xmp:CreateDate */
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateDate',
-                       ],
-                       /* todo: there might be interesting information in
-                        * exif:DeviceSettingDescription, but need to find an
-                        * example
-                        */
-                       'ExifVersion' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                       ],
-                       'ExposureMode' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateClosed',
-                               'rangeLow' => 0,
-                               'rangeHigh' => 2,
-                       ],
-                       'ExposureProgram' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateClosed',
-                               'rangeLow' => 0,
-                               'rangeHigh' => 8,
-                       ],
-                       'FileSource' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateClosed',
-                               'choices' => [ '3' => true ]
-                       ],
-                       'FlashpixVersion' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                       ],
-                       'FocalLengthIn35mmFilm' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateInteger',
-                       ],
-                       'FocalPlaneResolutionUnit' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateClosed',
-                               'choices' => [ '2' => true, '3' => true ],
-                       ],
-                       'GainControl' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateClosed',
-                               'rangeLow' => 0,
-                               'rangeHigh' => 4,
-                       ],
-                       /* this value is post-processed out later */
-                       'GPSAltitudeRef' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateClosed',
-                               'choices' => [ '0' => true, '1' => true ],
-                       ],
-                       'GPSAreaInformation' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                       ],
-                       'GPSDestBearingRef' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateClosed',
-                               'choices' => [ 'T' => true, 'M' => true ],
-                       ],
-                       'GPSDestDistanceRef' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateClosed',
-                               'choices' => [ 'K' => true, 'M' => true,
-                                       'N' => true ],
-                       ],
-                       'GPSDestLatitude' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateGPS',
-                       ],
-                       'GPSDestLongitude' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateGPS',
-                       ],
-                       'GPSDifferential' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateClosed',
-                               'choices' => [ '0' => true, '1' => true ],
-                       ],
-                       'GPSImgDirectionRef' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateClosed',
-                               'choices' => [ 'T' => true, 'M' => true ],
-                       ],
-                       'GPSLatitude' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateGPS',
-                       ],
-                       'GPSLongitude' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateGPS',
-                       ],
-                       'GPSMapDatum' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                       ],
-                       'GPSMeasureMode' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateClosed',
-                               'choices' => [ '2' => true, '3' => true ]
-                       ],
-                       'GPSProcessingMethod' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                       ],
-                       'GPSSatellites' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                       ],
-                       'GPSSpeedRef' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateClosed',
-                               'choices' => [ 'K' => true, 'M' => true,
-                                       'N' => true ],
-                       ],
-                       'GPSStatus' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateClosed',
-                               'choices' => [ 'A' => true, 'V' => true ]
-                       ],
-                       'GPSTimeStamp' => [
-                               'map_group' => 'exif',
-                               // Note: in exif, GPSDateStamp does not include
-                               // the time, where here it does.
-                               'map_name' => 'GPSDateStamp',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateDate',
-                       ],
-                       'GPSTrackRef' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateClosed',
-                               'choices' => [ 'T' => true, 'M' => true ]
-                       ],
-                       'GPSVersionID' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                       ],
-                       'ImageUniqueID' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                       ],
-                       'LightSource' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateClosed',
-                               /* can't use a range, as it skips... */
-                               'choices' => [ '0' => true, '1' => true,
-                                       '2' => true, '3' => true, '4' => true,
-                                       '9' => true, '10' => true, '11' => true,
-                                       '12' => true, '13' => true,
-                                       '14' => true, '15' => true,
-                                       '17' => true, '18' => true,
-                                       '19' => true, '20' => true,
-                                       '21' => true, '22' => true,
-                                       '23' => true, '24' => true,
-                                       '255' => true,
-                               ],
-                       ],
-                       'MeteringMode' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateClosed',
-                               'rangeLow' => 0,
-                               'rangeHigh' => 6,
-                               'choices' => [ '255' => true ],
-                       ],
-                       /* Pixel(X|Y)Dimension are rather useless, but for
-                        * completeness since we do it with exif.
-                        */
-                       'PixelXDimension' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateInteger',
-                       ],
-                       'PixelYDimension' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateInteger',
-                       ],
-                       'Saturation' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateClosed',
-                               'rangeLow' => 0,
-                               'rangeHigh' => 2,
-                       ],
-                       'SceneCaptureType' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateClosed',
-                               'rangeLow' => 0,
-                               'rangeHigh' => 3,
-                       ],
-                       'SceneType' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateClosed',
-                               'choices' => [ '1' => true ],
-                       ],
-                       // Note, 6 is not valid SensingMethod.
-                       'SensingMethod' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateClosed',
-                               'rangeLow' => 1,
-                               'rangeHigh' => 5,
-                               'choices' => [ '7' => true, 8 => true ],
-                       ],
-                       'Sharpness' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateClosed',
-                               'rangeLow' => 0,
-                               'rangeHigh' => 2,
-                       ],
-                       'SpectralSensitivity' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                       ],
-                       // This tag should perhaps be displayed to user better.
-                       'SubjectArea' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SEQ,
-                               'validate' => 'validateInteger',
-                       ],
-                       'SubjectDistanceRange' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateClosed',
-                               'rangeLow' => 0,
-                               'rangeHigh' => 3,
-                       ],
-                       'SubjectLocation' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SEQ,
-                               'validate' => 'validateInteger',
-                       ],
-                       'UserComment' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_LANG,
-                       ],
-                       'WhiteBalance' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateClosed',
-                               'choices' => [ '0' => true, '1' => true ]
-                       ],
-               ],
-               'http://ns.adobe.com/tiff/1.0/' => [
-                       'Artist' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                       ],
-                       'BitsPerSample' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SEQ,
-                               'validate' => 'validateInteger',
-                       ],
-                       'Compression' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateClosed',
-                               'choices' => [ '1' => true, '6' => true ],
-                       ],
-                       /* this prop should not be used in XMP. dc:rights is the correct prop */
-                       'Copyright' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_LANG,
-                       ],
-                       'DateTime' => [ /* proper prop is xmp:ModifyDate */
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateDate',
-                       ],
-                       'ImageDescription' => [ /* proper one is dc:description */
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_LANG,
-                       ],
-                       'ImageLength' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateInteger',
-                       ],
-                       'ImageWidth' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateInteger',
-                       ],
-                       'Make' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                       ],
-                       'Model' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                       ],
-                       /**** Do not extract this property
-                        * It interferes with auto exif rotation.
-                        * 'Orientation'       => array(
-                        *    'map_group' => 'exif',
-                        *    'mode'      => XMPReader::MODE_SIMPLE,
-                        *    'validate'  => 'validateClosed',
-                        *    'choices'   => array( '1' => true, '2' => true, '3' => true, '4' => true, 5 => true,
-                        *            '6' => true, '7' => true, '8' => true ),
-                        *),
-                        ******/
-                       'PhotometricInterpretation' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateClosed',
-                               'choices' => [ '2' => true, '6' => true ],
-                       ],
-                       'PlanerConfiguration' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateClosed',
-                               'choices' => [ '1' => true, '2' => true ],
-                       ],
-                       'PrimaryChromaticities' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SEQ,
-                               'validate' => 'validateRational',
-                       ],
-                       'ReferenceBlackWhite' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SEQ,
-                               'validate' => 'validateRational',
-                       ],
-                       'ResolutionUnit' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateClosed',
-                               'choices' => [ '2' => true, '3' => true ],
-                       ],
-                       'SamplesPerPixel' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateInteger',
-                       ],
-                       'Software' => [ /* see xmp:CreatorTool */
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                       ],
-                       /* ignore TransferFunction */
-                       'WhitePoint' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SEQ,
-                               'validate' => 'validateRational',
-                       ],
-                       'XResolution' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateRational',
-                       ],
-                       'YResolution' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateRational',
-                       ],
-                       'YCbCrCoefficients' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SEQ,
-                               'validate' => 'validateRational',
-                       ],
-                       'YCbCrPositioning' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateClosed',
-                               'choices' => [ '1' => true, '2' => true ],
-                       ],
-                       /********
-                        * Disable extracting this property (T33944)
-                        * Several files have a string instead of a Seq
-                        * for this property. XMPReader doesn't handle
-                        * mismatched types very gracefully (it marks
-                        * the entire file as invalid, instead of just
-                        * the relavent prop). Since this prop
-                        * doesn't communicate all that useful information
-                        * just disable this prop for now, until such
-                        * XMPReader is more graceful (T34172)
-                        * 'YCbCrSubSampling'  => array(
-                        *    'map_group' => 'exif',
-                        *    'mode'      => XMPReader::MODE_SEQ,
-                        *    'validate'  => 'validateClosed',
-                        *    'choices'   => array( '1' => true, '2' => true ),
-                        * ),
-                        */
-               ],
-               'http://ns.adobe.com/exif/1.0/aux/' => [
-                       'Lens' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                       ],
-                       'SerialNumber' => [
-                               'map_group' => 'exif',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                       ],
-                       'OwnerName' => [
-                               'map_group' => 'exif',
-                               'map_name' => 'CameraOwnerName',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                       ],
-               ],
-               'http://purl.org/dc/elements/1.1/' => [
-                       'title' => [
-                               'map_group' => 'general',
-                               'map_name' => 'ObjectName',
-                               'mode' => XMPReader::MODE_LANG
-                       ],
-                       'description' => [
-                               'map_group' => 'general',
-                               'map_name' => 'ImageDescription',
-                               'mode' => XMPReader::MODE_LANG
-                       ],
-                       'contributor' => [
-                               'map_group' => 'general',
-                               'map_name' => 'dc-contributor',
-                               'mode' => XMPReader::MODE_BAG
-                       ],
-                       'coverage' => [
-                               'map_group' => 'general',
-                               'map_name' => 'dc-coverage',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                       ],
-                       'creator' => [
-                               'map_group' => 'general',
-                               'map_name' => 'Artist', // map with exif Artist, iptc byline (2:80)
-                               'mode' => XMPReader::MODE_SEQ,
-                       ],
-                       'date' => [
-                               'map_group' => 'general',
-                               // Note, not mapped with other date properties, as this type of date is
-                               // non-specific: "A point or period of time associated with an event in
-                               //  the lifecycle of the resource"
-                               'map_name' => 'dc-date',
-                               'mode' => XMPReader::MODE_SEQ,
-                               'validate' => 'validateDate',
-                       ],
-                       /* Do not extract dc:format, as we've got better ways to determine MIME type */
-                       'identifier' => [
-                               'map_group' => 'deprecated',
-                               'map_name' => 'Identifier',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                       ],
-                       'language' => [
-                               'map_group' => 'general',
-                               'map_name' => 'LanguageCode', /* mapped with iptc 2:135 */
-                               'mode' => XMPReader::MODE_BAG,
-                               'validate' => 'validateLangCode',
-                       ],
-                       'publisher' => [
-                               'map_group' => 'general',
-                               'map_name' => 'dc-publisher',
-                               'mode' => XMPReader::MODE_BAG,
-                       ],
-                       // for related images/resources
-                       'relation' => [
-                               'map_group' => 'general',
-                               'map_name' => 'dc-relation',
-                               'mode' => XMPReader::MODE_BAG,
-                       ],
-                       'rights' => [
-                               'map_group' => 'general',
-                               'map_name' => 'Copyright',
-                               'mode' => XMPReader::MODE_LANG,
-                       ],
-                       // Note: source is not mapped with iptc source, since iptc
-                       // source describes the source of the image in terms of a person
-                       // who provided the image, where this is to describe an image that the
-                       // current one is based on.
-                       'source' => [
-                               'map_group' => 'general',
-                               'map_name' => 'dc-source',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                       ],
-                       'subject' => [
-                               'map_group' => 'general',
-                               'map_name' => 'Keywords', /* maps to iptc 2:25 */
-                               'mode' => XMPReader::MODE_BAG,
-                       ],
-                       'type' => [
-                               'map_group' => 'general',
-                               'map_name' => 'dc-type',
-                               'mode' => XMPReader::MODE_BAG,
-                       ],
-               ],
-               'http://ns.adobe.com/xap/1.0/' => [
-                       'CreateDate' => [
-                               'map_group' => 'general',
-                               'map_name' => 'DateTimeDigitized',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateDate',
-                       ],
-                       'CreatorTool' => [
-                               'map_group' => 'general',
-                               'map_name' => 'Software',
-                               'mode' => XMPReader::MODE_SIMPLE
-                       ],
-                       'Identifier' => [
-                               'map_group' => 'general',
-                               'mode' => XMPReader::MODE_BAG,
-                       ],
-                       'Label' => [
-                               'map_group' => 'general',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                       ],
-                       'ModifyDate' => [
-                               'map_group' => 'general',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'map_name' => 'DateTime',
-                               'validate' => 'validateDate',
-                       ],
-                       'MetadataDate' => [
-                               'map_group' => 'general',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               // map_name to be consistent with other date names.
-                               'map_name' => 'DateTimeMetadata',
-                               'validate' => 'validateDate',
-                       ],
-                       'Nickname' => [
-                               'map_group' => 'general',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                       ],
-                       'Rating' => [
-                               'map_group' => 'general',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateRating',
-                       ],
-               ],
-               'http://ns.adobe.com/xap/1.0/rights/' => [
-                       'Certificate' => [
-                               'map_group' => 'general',
-                               'map_name' => 'RightsCertificate',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                       ],
-                       'Marked' => [
-                               'map_group' => 'general',
-                               'map_name' => 'Copyrighted',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateBoolean',
-                       ],
-                       'Owner' => [
-                               'map_group' => 'general',
-                               'map_name' => 'CopyrightOwner',
-                               'mode' => XMPReader::MODE_BAG,
-                       ],
-                       // this seems similar to dc:rights.
-                       'UsageTerms' => [
-                               'map_group' => 'general',
-                               'mode' => XMPReader::MODE_LANG,
-                       ],
-                       'WebStatement' => [
-                               'map_group' => 'general',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                       ],
-               ],
-               // XMP media management.
-               'http://ns.adobe.com/xap/1.0/mm/' => [
-                       // if we extract the exif UniqueImageID, might
-                       // as well do this too.
-                       'OriginalDocumentID' => [
-                               'map_group' => 'general',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                       ],
-                       // It might also be useful to do xmpMM:LastURL
-                       // and xmpMM:DerivedFrom as you can potentially,
-                       // get the url of this document/source for this
-                       // document. However whats more likely is you'd
-                       // get a file:// url for the path of the doc,
-                       // which is somewhat of a privacy issue.
-               ],
-               'http://creativecommons.org/ns#' => [
-                       'license' => [
-                               'map_name' => 'LicenseUrl',
-                               'map_group' => 'general',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                       ],
-                       'morePermissions' => [
-                               'map_name' => 'MorePermissionsUrl',
-                               'map_group' => 'general',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                       ],
-                       'attributionURL' => [
-                               'map_group' => 'general',
-                               'map_name' => 'AttributionUrl',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                       ],
-                       'attributionName' => [
-                               'map_group' => 'general',
-                               'map_name' => 'PreferredAttributionName',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                       ],
-               ],
-               // Note, this property affects how jpeg metadata is extracted.
-               'http://ns.adobe.com/xmp/note/' => [
-                       'HasExtendedXMP' => [
-                               'map_group' => 'special',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                       ],
-               ],
-               /* Note, in iptc schemas, the legacy properties are denoted
-                * as deprecated, since other properties should used instead,
-                * and properties marked as deprecated in the standard are
-                * are marked as general here as they don't have replacements
-                */
-               'http://ns.adobe.com/photoshop/1.0/' => [
-                       'City' => [
-                               'map_group' => 'deprecated',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'map_name' => 'CityDest',
-                       ],
-                       'Country' => [
-                               'map_group' => 'deprecated',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'map_name' => 'CountryDest',
-                       ],
-                       'State' => [
-                               'map_group' => 'deprecated',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'map_name' => 'ProvinceOrStateDest',
-                       ],
-                       'DateCreated' => [
-                               'map_group' => 'deprecated',
-                               // marking as deprecated as the xmp prop preferred
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'map_name' => 'DateTimeOriginal',
-                               'validate' => 'validateDate',
-                               // note this prop is an XMP, not IPTC date
-                       ],
-                       'CaptionWriter' => [
-                               'map_group' => 'general',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'map_name' => 'Writer',
-                       ],
-                       'Instructions' => [
-                               'map_group' => 'general',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'map_name' => 'SpecialInstructions',
-                       ],
-                       'TransmissionReference' => [
-                               'map_group' => 'general',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'map_name' => 'OriginalTransmissionRef',
-                       ],
-                       'AuthorsPosition' => [
-                               /* This corresponds with 2:85
-                                * By-line Title, which needs to be
-                                * handled weirdly to correspond
-                                * with iptc/exif. */
-                               'map_group' => 'special',
-                               'mode' => XMPReader::MODE_SIMPLE
-                       ],
-                       'Credit' => [
-                               'map_group' => 'general',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                       ],
-                       'Source' => [
-                               'map_group' => 'general',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                       ],
-                       'Urgency' => [
-                               'map_group' => 'general',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                       ],
-                       'Category' => [
-                               // Note, this prop is deprecated, but in general
-                               // group since it doesn't have a replacement.
-                               'map_group' => 'general',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'map_name' => 'iimCategory',
-                       ],
-                       'SupplementalCategories' => [
-                               'map_group' => 'general',
-                               'mode' => XMPReader::MODE_BAG,
-                               'map_name' => 'iimSupplementalCategory',
-                       ],
-                       'Headline' => [
-                               'map_group' => 'general',
-                               'mode' => XMPReader::MODE_SIMPLE
-                       ],
-               ],
-               'http://iptc.org/std/Iptc4xmpCore/1.0/xmlns/' => [
-                       'CountryCode' => [
-                               'map_group' => 'deprecated',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'map_name' => 'CountryCodeDest',
-                       ],
-                       'IntellectualGenre' => [
-                               'map_group' => 'general',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                       ],
-                       // Note, this is a six digit code.
-                       // See: http://cv.iptc.org/newscodes/scene/
-                       // Since these aren't really all that common,
-                       // we just show the number.
-                       'Scene' => [
-                               'map_group' => 'general',
-                               'mode' => XMPReader::MODE_BAG,
-                               'validate' => 'validateInteger',
-                               'map_name' => 'SceneCode',
-                       ],
-                       /* Note: SubjectCode should be an 8 ascii digits.
-                        * it is not really an integer (has leading 0's,
-                        * cannot have a +/- sign), but validateInteger
-                        * will let it through.
-                        */
-                       'SubjectCode' => [
-                               'map_group' => 'general',
-                               'mode' => XMPReader::MODE_BAG,
-                               'map_name' => 'SubjectNewsCode',
-                               'validate' => 'validateInteger'
-                       ],
-                       'Location' => [
-                               'map_group' => 'deprecated',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'map_name' => 'SublocationDest',
-                       ],
-                       'CreatorContactInfo' => [
-                               /* Note this maps to 2:118 in iim
-                                * (Contact) field. However those field
-                                * types are slightly different - 2:118
-                                * is free form text field, where this
-                                * is more structured.
-                                */
-                               'map_group' => 'general',
-                               'mode' => XMPReader::MODE_STRUCT,
-                               'map_name' => 'Contact',
-                               'children' => [
-                                       'CiAdrExtadr' => true,
-                                       'CiAdrCity' => true,
-                                       'CiAdrCtry' => true,
-                                       'CiEmailWork' => true,
-                                       'CiTelWork' => true,
-                                       'CiAdrPcode' => true,
-                                       'CiAdrRegion' => true,
-                                       'CiUrlWork' => true,
-                               ],
-                       ],
-                       'CiAdrExtadr' => [ /* address */
-                               'map_group' => 'general',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'structPart' => true,
-                       ],
-                       'CiAdrCity' => [ /* city */
-                               'map_group' => 'general',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'structPart' => true,
-                       ],
-                       'CiAdrCtry' => [ /* country */
-                               'map_group' => 'general',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'structPart' => true,
-                       ],
-                       'CiEmailWork' => [ /* email (possibly separated by ',') */
-                               'map_group' => 'general',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'structPart' => true,
-                       ],
-                       'CiTelWork' => [ /* telephone */
-                               'map_group' => 'general',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'structPart' => true,
-                       ],
-                       'CiAdrPcode' => [ /* postal code */
-                               'map_group' => 'general',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'structPart' => true,
-                       ],
-                       'CiAdrRegion' => [ /* province/state */
-                               'map_group' => 'general',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'structPart' => true,
-                       ],
-                       'CiUrlWork' => [ /* url. Multiple may be separated by comma. */
-                               'map_group' => 'general',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'structPart' => true,
-                       ],
-                       /* End contact info struct properties */
-               ],
-               'http://iptc.org/std/Iptc4xmpExt/2008-02-29/' => [
-                       'Event' => [
-                               'map_group' => 'general',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                       ],
-                       'OrganisationInImageName' => [
-                               'map_group' => 'general',
-                               'mode' => XMPReader::MODE_BAG,
-                               'map_name' => 'OrganisationInImage'
-                       ],
-                       'PersonInImage' => [
-                               'map_group' => 'general',
-                               'mode' => XMPReader::MODE_BAG,
-                       ],
-                       'MaxAvailHeight' => [
-                               'map_group' => 'general',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateInteger',
-                               'map_name' => 'OriginalImageHeight',
-                       ],
-                       'MaxAvailWidth' => [
-                               'map_group' => 'general',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'validate' => 'validateInteger',
-                               'map_name' => 'OriginalImageWidth',
-                       ],
-                       // LocationShown and LocationCreated are handled
-                       // specially because they are hierarchical, but we
-                       // also want to merge with the old non-hierarchical.
-                       'LocationShown' => [
-                               'map_group' => 'special',
-                               'mode' => XMPReader::MODE_BAGSTRUCT,
-                               'children' => [
-                                       'WorldRegion' => true,
-                                       'CountryCode' => true, /* iso code */
-                                       'CountryName' => true,
-                                       'ProvinceState' => true,
-                                       'City' => true,
-                                       'Sublocation' => true,
-                               ],
-                       ],
-                       'LocationCreated' => [
-                               'map_group' => 'special',
-                               'mode' => XMPReader::MODE_BAGSTRUCT,
-                               'children' => [
-                                       'WorldRegion' => true,
-                                       'CountryCode' => true, /* iso code */
-                                       'CountryName' => true,
-                                       'ProvinceState' => true,
-                                       'City' => true,
-                                       'Sublocation' => true,
-                               ],
-                       ],
-                       'WorldRegion' => [
-                               'map_group' => 'special',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'structPart' => true,
-                       ],
-                       'CountryCode' => [
-                               'map_group' => 'special',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'structPart' => true,
-                       ],
-                       'CountryName' => [
-                               'map_group' => 'special',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'structPart' => true,
-                               'map_name' => 'Country',
-                       ],
-                       'ProvinceState' => [
-                               'map_group' => 'special',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'structPart' => true,
-                               'map_name' => 'ProvinceOrState',
-                       ],
-                       'City' => [
-                               'map_group' => 'special',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'structPart' => true,
-                       ],
-                       'Sublocation' => [
-                               'map_group' => 'special',
-                               'mode' => XMPReader::MODE_SIMPLE,
-                               'structPart' => true,
-                       ],
-
-                       /* Other props that might be interesting but
-                        * Not currently extracted:
-                        * ArtworkOrObject, (info about objects in picture)
-                        * DigitalSourceType
-                        * RegistryId
-                        */
-               ],
-
-               /* Plus props we might want to consider:
-                * (Note: some of these have unclear/incomplete definitions
-                * from the iptc4xmp standard).
-                * ImageSupplier (kind of like iptc source field)
-                * ImageSupplierId (id code for image from supplier)
-                * CopyrightOwner
-                * ImageCreator
-                * Licensor
-                * Various model release fields
-                * Property release fields.
-                */
-       ];
-}
diff --git a/includes/libs/xmp/XMPValidate.php b/includes/libs/xmp/XMPValidate.php
deleted file mode 100644 (file)
index 9fe3e33..0000000
+++ /dev/null
@@ -1,399 +0,0 @@
-<?php
-/**
- * Methods for validating XMP properties.
- *
- * 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
- */
-
-use Psr\Log\LoggerInterface;
-use Psr\Log\LoggerAwareInterface;
-use Wikimedia\Timestamp\ConvertibleTimestamp;
-
-/**
- * This contains some static methods for
- * validating XMP properties. See XMPInfo and XMPReader classes.
- *
- * Each of these functions take the same parameters
- * * an info array which is a subset of the XMPInfo::items array
- * * A value (passed as reference) to validate. This can be either a
- *    simple value or an array
- * * A boolean to determine if this is validating a simple or complex values
- *
- * It should be noted that when an array is being validated, typically the validation
- * function is called once for each value, and then once at the end for the entire array.
- *
- * These validation functions can also be used to modify the data. See the gps and flash one's
- * for example.
- *
- * @see http://www.adobe.com/devnet/xmp/pdfs/XMPSpecificationPart1.pdf starting at pg 28
- * @see http://www.adobe.com/devnet/xmp/pdfs/XMPSpecificationPart2.pdf starting at pg 11
- */
-class XMPValidate implements LoggerAwareInterface {
-
-       /**
-        * @var LoggerInterface
-        */
-       private $logger;
-
-       public function __construct( LoggerInterface $logger ) {
-               $this->setLogger( $logger );
-       }
-
-       public function setLogger( LoggerInterface $logger ) {
-               $this->logger = $logger;
-       }
-       /**
-        * Function to validate boolean properties ( True or False )
-        *
-        * @param array $info Information about current property
-        * @param mixed &$val Current value to validate
-        * @param bool $standalone If this is a simple property or array
-        */
-       public function validateBoolean( $info, &$val, $standalone ) {
-               if ( !$standalone ) {
-                       // this only validates standalone properties, not arrays, etc
-                       return;
-               }
-               if ( $val !== 'True' && $val !== 'False' ) {
-                       $this->logger->info( __METHOD__ . " Expected True or False but got $val" );
-                       $val = null;
-               }
-       }
-
-       /**
-        * function to validate rational properties ( 12/10 )
-        *
-        * @param array $info Information about current property
-        * @param mixed &$val Current value to validate
-        * @param bool $standalone If this is a simple property or array
-        */
-       public function validateRational( $info, &$val, $standalone ) {
-               if ( !$standalone ) {
-                       // this only validates standalone properties, not arrays, etc
-                       return;
-               }
-               if ( !preg_match( '/^(?:-?\d+)\/(?:\d+[1-9]|[1-9]\d*)$/D', $val ) ) {
-                       $this->logger->info( __METHOD__ . " Expected rational but got $val" );
-                       $val = null;
-               }
-       }
-
-       /**
-        * function to validate rating properties -1, 0-5
-        *
-        * if its outside of range put it into range.
-        *
-        * @see MWG spec
-        * @param array $info Information about current property
-        * @param mixed &$val Current value to validate
-        * @param bool $standalone If this is a simple property or array
-        */
-       public function validateRating( $info, &$val, $standalone ) {
-               if ( !$standalone ) {
-                       // this only validates standalone properties, not arrays, etc
-                       return;
-               }
-               if ( !preg_match( '/^[-+]?\d*(?:\.?\d*)$/D', $val )
-                       || !is_numeric( $val )
-               ) {
-                       $this->logger->info( __METHOD__ . " Expected rating but got $val" );
-                       $val = null;
-
-                       return;
-               } else {
-                       $nVal = (float)$val;
-                       if ( $nVal < 0 ) {
-                               // We do < 0 here instead of < -1 here, since
-                               // the values between 0 and -1 are also illegal
-                               // as -1 is meant as a special reject rating.
-                               $this->logger->info( __METHOD__ . " Rating too low, setting to -1 (Rejected)" );
-                               $val = '-1';
-
-                               return;
-                       }
-                       if ( $nVal > 5 ) {
-                               $this->logger->info( __METHOD__ . " Rating too high, setting to 5" );
-                               $val = '5';
-
-                               return;
-                       }
-               }
-       }
-
-       /**
-        * function to validate integers
-        *
-        * @param array $info Information about current property
-        * @param mixed &$val Current value to validate
-        * @param bool $standalone If this is a simple property or array
-        */
-       public function validateInteger( $info, &$val, $standalone ) {
-               if ( !$standalone ) {
-                       // this only validates standalone properties, not arrays, etc
-                       return;
-               }
-               if ( !preg_match( '/^[-+]?\d+$/D', $val ) ) {
-                       $this->logger->info( __METHOD__ . " Expected integer but got $val" );
-                       $val = null;
-               }
-       }
-
-       /**
-        * function to validate properties with a fixed number of allowed
-        * choices. (closed choice)
-        *
-        * @param array $info Information about current property
-        * @param mixed &$val Current value to validate
-        * @param bool $standalone If this is a simple property or array
-        */
-       public function validateClosed( $info, &$val, $standalone ) {
-               if ( !$standalone ) {
-                       // this only validates standalone properties, not arrays, etc
-                       return;
-               }
-
-               // check if its in a numeric range
-               $inRange = false;
-               if ( isset( $info['rangeLow'] )
-                       && isset( $info['rangeHigh'] )
-                       && is_numeric( $val )
-                       && ( intval( $val ) <= $info['rangeHigh'] )
-                       && ( intval( $val ) >= $info['rangeLow'] )
-               ) {
-                       $inRange = true;
-               }
-
-               if ( !isset( $info['choices'][$val] ) && !$inRange ) {
-                       $this->logger->info( __METHOD__ . " Expected closed choice, but got $val" );
-                       $val = null;
-               }
-       }
-
-       /**
-        * function to validate and modify flash structure
-        *
-        * @param array $info Information about current property
-        * @param mixed &$val Current value to validate
-        * @param bool $standalone If this is a simple property or array
-        */
-       public function validateFlash( $info, &$val, $standalone ) {
-               if ( $standalone ) {
-                       // this only validates flash structs, not individual properties
-                       return;
-               }
-               if ( !( isset( $val['Fired'] )
-                       && isset( $val['Function'] )
-                       && isset( $val['Mode'] )
-                       && isset( $val['RedEyeMode'] )
-                       && isset( $val['Return'] )
-               ) ) {
-                       $this->logger->info( __METHOD__ . " Flash structure did not have all the required components" );
-                       $val = null;
-               } else {
-                       $val = ( 0 | ( $val['Fired'] === 'True' )
-                               | ( intval( $val['Return'] ) << 1 )
-                               | ( intval( $val['Mode'] ) << 3 )
-                               | ( ( $val['Function'] === 'True' ) << 5 )
-                               | ( ( $val['RedEyeMode'] === 'True' ) << 6 ) );
-               }
-       }
-
-       /**
-        * function to validate LangCode properties ( en-GB, etc )
-        *
-        * This is just a naive check to make sure it somewhat looks like a lang code.
-        *
-        * @see BCP 47
-        * @see https://wwwimages2.adobe.com/content/dam/Adobe/en/devnet/xmp/pdfs/
-        *      XMP%20SDK%20Release%20cc-2014-12/XMPSpecificationPart1.pdf page 22 (section 8.2.2.4)
-        *
-        * @param array $info Information about current property
-        * @param mixed &$val Current value to validate
-        * @param bool $standalone If this is a simple property or array
-        */
-       public function validateLangCode( $info, &$val, $standalone ) {
-               if ( !$standalone ) {
-                       // this only validates standalone properties, not arrays, etc
-                       return;
-               }
-               if ( !preg_match( '/^[-A-Za-z0-9]{2,}$/D', $val ) ) {
-                       // this is a rather naive check.
-                       $this->logger->info( __METHOD__ . " Expected Lang code but got $val" );
-                       $val = null;
-               }
-       }
-
-       /**
-        * function to validate date properties, and convert to (partial) Exif format.
-        *
-        * Dates can be one of the following formats:
-        * YYYY
-        * YYYY-MM
-        * YYYY-MM-DD
-        * YYYY-MM-DDThh:mmTZD
-        * YYYY-MM-DDThh:mm:ssTZD
-        * YYYY-MM-DDThh:mm:ss.sTZD
-        *
-        * @param array $info Information about current property
-        * @param mixed &$val Current value to validate. Converts to TS_EXIF as a side-effect.
-        *    in cases where there's only a partial date, it will give things like
-        *    2011:04.
-        * @param bool $standalone If this is a simple property or array
-        */
-       public function validateDate( $info, &$val, $standalone ) {
-               if ( !$standalone ) {
-                       // this only validates standalone properties, not arrays, etc
-                       return;
-               }
-               $res = [];
-               if ( !preg_match(
-                       /* ahh! scary regex... */
-                       // phpcs:ignore Generic.Files.LineLength
-                       '/^([0-3]\d{3})(?:-([01]\d)(?:-([0-3]\d)(?:T([0-2]\d):([0-6]\d)(?::([0-6]\d)(?:\.\d+)?)?([-+]\d{2}:\d{2}|Z)?)?)?)?$/D',
-                       $val, $res )
-               ) {
-                       $this->logger->info( __METHOD__ . " Expected date but got $val" );
-                       $val = null;
-               } else {
-                       /*
-                        * $res is formatted as follows:
-                        * 0 -> full date.
-                        * 1 -> year, 2-> month, 3-> day, 4-> hour, 5-> minute, 6->second
-                        * 7-> Timezone specifier (Z or something like +12:30 )
-                        * many parts are optional, some aren't. For example if you specify
-                        * minute, you must specify hour, day, month, and year but not second or TZ.
-                        */
-
-                       /*
-                        * First of all, if year = 0000, Something is wrongish,
-                        * so don't extract. This seems to happen when
-                        * some programs convert between metadata formats.
-                        */
-                       if ( $res[1] === '0000' ) {
-                               $this->logger->info( __METHOD__ . " Invalid date (year 0): $val" );
-                               $val = null;
-
-                               return;
-                       }
-
-                       if ( !isset( $res[4] ) ) { // hour
-                               // just have the year month day (if that)
-                               $val = $res[1];
-                               if ( isset( $res[2] ) ) {
-                                       $val .= ':' . $res[2];
-                               }
-                               if ( isset( $res[3] ) ) {
-                                       $val .= ':' . $res[3];
-                               }
-
-                               return;
-                       }
-
-                       if ( !isset( $res[7] ) || $res[7] === 'Z' ) {
-                               // if hour is set, then minute must also be or regex above will fail.
-                               $val = $res[1] . ':' . $res[2] . ':' . $res[3]
-                                       . ' ' . $res[4] . ':' . $res[5];
-                               if ( isset( $res[6] ) && $res[6] !== '' ) {
-                                       $val .= ':' . $res[6];
-                               }
-
-                               return;
-                       }
-
-                       // Extra check for empty string necessary due to TZ but no second case.
-                       $stripSeconds = false;
-                       if ( !isset( $res[6] ) || $res[6] === '' ) {
-                               $res[6] = '00';
-                               $stripSeconds = true;
-                       }
-
-                       // Do timezone processing. We've already done the case that tz = Z.
-
-                       // We know that if we got to this step, year, month day hour and min must be set
-                       // by virtue of regex not failing.
-
-                       $unix = ConvertibleTimestamp::convert( TS_UNIX,
-                               $res[1] . $res[2] . $res[3] . $res[4] . $res[5] . $res[6]
-                       );
-                       $offset = intval( substr( $res[7], 1, 2 ) ) * 60 * 60;
-                       $offset += intval( substr( $res[7], 4, 2 ) ) * 60;
-                       if ( substr( $res[7], 0, 1 ) === '-' ) {
-                               $offset = -$offset;
-                       }
-                       $val = ConvertibleTimestamp::convert( TS_EXIF, $unix + $offset );
-
-                       if ( $stripSeconds ) {
-                               // If seconds weren't specified, remove the trailing ':00'.
-                               $val = substr( $val, 0, -3 );
-                       }
-               }
-       }
-
-       /** function to validate, and more importantly
-        * translate the XMP DMS form of gps coords to
-        * the decimal form we use.
-        *
-        * @see http://www.adobe.com/devnet/xmp/pdfs/XMPSpecificationPart2.pdf
-        *        section 1.2.7.4 on page 23
-        *
-        * @param array $info Unused (info about prop)
-        * @param string &$val GPS string in either DDD,MM,SSk or
-        *   or DDD,MM.mmk form
-        * @param bool $standalone If its a simple prop (should always be true)
-        */
-       public function validateGPS( $info, &$val, $standalone ) {
-               if ( !$standalone ) {
-                       return;
-               }
-
-               $m = [];
-               if ( preg_match(
-                       '/(\d{1,3}),(\d{1,2}),(\d{1,2})([NWSE])/D',
-                       $val, $m )
-               ) {
-                       $coord = intval( $m[1] );
-                       $coord += intval( $m[2] ) * ( 1 / 60 );
-                       $coord += intval( $m[3] ) * ( 1 / 3600 );
-                       if ( $m[4] === 'S' || $m[4] === 'W' ) {
-                               $coord = -$coord;
-                       }
-                       $val = $coord;
-
-                       return;
-               } elseif ( preg_match(
-                       '/(\d{1,3}),(\d{1,2}(?:.\d*)?)([NWSE])/D',
-                       $val, $m )
-               ) {
-                       $coord = intval( $m[1] );
-                       $coord += floatval( $m[2] ) * ( 1 / 60 );
-                       if ( $m[3] === 'S' || $m[3] === 'W' ) {
-                               $coord = -$coord;
-                       }
-                       $val = $coord;
-
-                       return;
-               } else {
-                       $this->logger->info( __METHOD__
-                               . " Expected GPSCoordinate, but got $val." );
-                       $val = null;
-
-                       return;
-               }
-       }
-}
index c8d111d..d70688f 100644 (file)
@@ -72,7 +72,7 @@ class PageDataRequestHandler {
         *        - oldid|revision: the revision ID
         * @param OutputPage $output
         *
-        * @note: Instead of an output page, a WebResponse could be sufficient, but
+        * @note Instead of an output page, a WebResponse could be sufficient, but
         *        redirect logic is currently implemented in OutputPage.
         *
         * @throws HttpError
index 160d2d1..d096b00 100644 (file)
@@ -204,7 +204,7 @@ class LinkRenderer {
                        $realHtml = $html = null;
                }
                if ( !Hooks::run( 'LinkBegin',
-                       [ $dummy, $title, &$html, &$extraAttribs, &$query, &$options, &$ret ] )
+                       [ $dummy, $title, &$html, &$extraAttribs, &$query, &$options, &$ret ], '1.28' )
                ) {
                        return $ret;
                }
@@ -245,7 +245,7 @@ class LinkRenderer {
         * @return string
         */
        public function makePreloadedLink(
-               LinkTarget $target, $text = null, $classes, array $extraAttribs = [], array $query = []
+               LinkTarget $target, $text = null, $classes = '', array $extraAttribs = [], array $query = []
        ) {
                // Run begin hook
                $ret = $this->runBeginHook( $target, $text, $extraAttribs, $query, true );
@@ -373,7 +373,7 @@ class LinkRenderer {
                        $title = Title::newFromLinkTarget( $target );
                        $options = $this->getLegacyOptions( $isKnown );
                        if ( !Hooks::run( 'LinkEnd',
-                               [ $dummy, $title, $options, &$html, &$attribs, &$ret ] )
+                               [ $dummy, $title, $options, &$html, &$attribs, &$ret ], '1.28' )
                        ) {
                                return $ret;
                        }
index a5af026..0d22382 100644 (file)
@@ -18,7 +18,7 @@
  * http://www.gnu.org/copyleft/gpl.html
  *
  * @file
- * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ * @license GPL-2.0-or-later
  * @since 1.25
  */
 
index ef00634..8078e2e 100644 (file)
@@ -19,7 +19,7 @@
  *
  * @file
  * @author Niklas Laxström
- * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ * @license GPL-2.0-or-later
  * @since 1.22
  */
 
index a2a899b..ee67618 100644 (file)
@@ -18,7 +18,7 @@
  * http://www.gnu.org/copyleft/gpl.html
  *
  * @file
- * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ * @license GPL-2.0-or-later
  * @since 1.27
  */
 
index 31c196a..b53a486 100644 (file)
@@ -24,7 +24,7 @@
  *
  * @file
  * @author Niklas Laxström
- * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ * @license GPL-2.0-or-later
  * @since 1.19
  */
 
@@ -625,7 +625,7 @@ class ManualLogEntry extends LogEntryBase {
        /**
         * Insert the entry into the `logging` table.
         *
-        * @param IDatabase $dbw
+        * @param IDatabase|null $dbw
         * @return int ID of the log entry
         * @throws MWException
         */
@@ -821,7 +821,7 @@ class ManualLogEntry extends LogEntryBase {
        }
 
        public function getTimestamp() {
-               $ts = $this->timestamp !== null ? $this->timestamp : wfTimestampNow();
+               $ts = $this->timestamp ?? wfTimestampNow();
 
                return wfTimestamp( TS_MW, $ts );
        }
index 9e4a630..f032efc 100644 (file)
@@ -101,99 +101,120 @@ class LogEventsList extends ContextSource {
         * @param int|string $year Use 0 to start with no year preselected.
         * @param int|string $month A month in the 1..12 range. Use 0 to start with no month
         *  preselected.
-        * @param array $filter
+        * @param int|string $day A day in the 1..31 range. Use 0 to start with no month
+        *  preselected.
+        * @param array|null $filter
         * @param string $tagFilter Tag to select by default
-        * @param string $action
+        * @param string|null $action
         */
        public function showOptions( $types = [], $user = '', $page = '', $pattern = false, $year = 0,
-               $month = 0, $filter = null, $tagFilter = '', $action = null
+               $month = 0, $day = 0, $filter = null, $tagFilter = '', $action = null
        ) {
-               global $wgScript, $wgMiserMode;
-
-               $title = SpecialPage::getTitleFor( 'Log' );
-
                // For B/C, we take strings, but make sure they are converted...
                $types = ( $types === '' ) ? [] : (array)$types;
 
-               $tagSelector = ChangeTags::buildTagFilterSelector( $tagFilter, false, $this->getContext() );
-
-               $html = Html::hidden( 'title', $title->getPrefixedDBkey() );
+               $formDescriptor = [];
 
                // Basic selectors
-               $html .= $this->getTypeMenu( $types ) . "\n";
-               $html .= $this->getUserInput( $user ) . "\n";
-               $html .= $this->getTitleInput( $page ) . "\n";
-               $html .= $this->getExtraInputs( $types ) . "\n";
+               $formDescriptor['type'] = $this->getTypeMenuDesc( $types );
+               $formDescriptor['user'] = $this->getUserInputDesc( $user );
+               $formDescriptor['page'] = $this->getTitleInputDesc( $page );
+
+               // Add extra inputs if any
+               // This could either be a form descriptor array or a string with raw HTML.
+               // We need it to work in both cases and show a deprecation warning if it
+               // is a string. See T199495.
+               $extraInputsDescriptor = $this->getExtraInputsDesc( $types );
+               if (
+                       is_array( $extraInputsDescriptor ) &&
+                       !empty( $extraInputsDescriptor )
+               ) {
+                       $formDescriptor[ 'extra' ] = $extraInputsDescriptor;
+               } elseif ( is_string( $extraInputsDescriptor ) ) {
+                       // We'll add this to the footer of the form later
+                       $extraInputsString = $extraInputsDescriptor;
+                       wfDeprecated( 'Using $input in LogEventsListGetExtraInputs hook', '1.32' );
+               }
 
                // Title pattern, if allowed
-               if ( !$wgMiserMode ) {
-                       $html .= $this->getTitlePattern( $pattern ) . "\n";
+               if ( !$this->getConfig()->get( 'MiserMode' ) ) {
+                       $formDescriptor['pattern'] = $this->getTitlePatternDesc( $pattern );
                }
 
-               // date menu
-               $html .= Xml::tags( 'p', null, Xml::dateMenu( (int)$year, (int)$month ) );
+               // Date menu
+               $formDescriptor['date'] = [
+                       'type' => 'date',
+                       'label-message' => 'date',
+                       'default' => sprintf( "%04d-%02d-%02d", $year, $month, $day ),
+               ];
 
                // Tag filter
-               if ( $tagSelector ) {
-                       $html .= Xml::tags( 'p', null, implode( '&#160;', $tagSelector ) );
-               }
+               $formDescriptor['tagfilter'] = [
+                       'type' => 'tagfilter',
+                       'name' => 'tagfilter',
+                       'label-raw' => $this->msg( 'tag-filter' )->parse(),
+               ];
 
                // Filter links
                if ( $filter ) {
-                       $html .= Xml::tags( 'p', null, $this->getFilterLinks( $filter ) );
+                       $formDescriptor['filters'] = $this->getFiltersDesc( $filter );
                }
 
                // Action filter
-               if ( $action !== null ) {
-                       $html .= Xml::tags( 'p', null, $this->getActionSelector( $types, $action ) );
-               }
-
-               // Submit button
-               $html .= Xml::submitButton( $this->msg( 'logeventslist-submit' )->text() );
-
-               // Fieldset
-               $html = Xml::fieldset( $this->msg( 'log' )->text(), $html );
-
-               // Form wrapping
-               $html = Xml::tags( 'form', [ 'action' => $wgScript, 'method' => 'get' ], $html );
-
-               $this->getOutput()->addHTML( $html );
+               if (
+                       $action !== null &&
+                       $this->allowedActions !== null &&
+                       count( $this->allowedActions ) > 0
+               ) {
+                       $formDescriptor['subtype'] = $this->getActionSelectorDesc( $types, $action );
+               }
+
+               $context = new DerivativeContext( $this->getContext() );
+               $context->setTitle( SpecialPage::getTitleFor( 'Log' ) ); // Remove subpage
+               $htmlForm = new HTMLForm( $formDescriptor, $context );
+               $htmlForm
+                       ->setSubmitText( $this->msg( 'logeventslist-submit' )->text() )
+                       ->setMethod( 'get' )
+                       ->setWrapperLegendMsg( 'log' );
+
+               // TODO This will should be removed at some point. See T199495.
+               if ( isset( $extraInputsString ) ) {
+                       $htmlForm->addFooterText( Html::rawElement(
+                               'div',
+                               null,
+                               $extraInputsString
+                       ) );
+               }
+
+               $htmlForm->prepareForm()->displayForm( false );
        }
 
        /**
         * @param array $filter
-        * @return string Formatted HTML
+        * @return array Form descriptor
         */
-       private function getFilterLinks( $filter ) {
-               // show/hide links
-               $messages = [ $this->msg( 'show' )->text(), $this->msg( 'hide' )->text() ];
-               // Option value -> message mapping
-               $links = [];
-               $hiddens = ''; // keep track for "go" button
-               $linkRenderer = $this->getLinkRenderer();
+       private function getFiltersDesc( $filter ) {
+               $options = [];
+               $default = [];
                foreach ( $filter as $type => $val ) {
-                       // Should the below assignment be outside the foreach?
-                       // Then it would have to be copied. Not certain what is more expensive.
-                       $query = $this->getDefaultQuery();
-                       $queryKey = "hide_{$type}_log";
-
-                       $hideVal = 1 - intval( $val );
-                       $query[$queryKey] = $hideVal;
-
-                       $link = $linkRenderer->makeKnownLink(
-                               $this->getTitle(),
-                               $messages[$hideVal],
-                               [],
-                               $query
-                       );
+                       $message = $this->msg( "logeventslist-{$type}-log" );
+                       // FIXME: Remove this check once T199657 is fully resolved.
+                       if ( !$message->exists() ) {
+                               $message = $this->msg( "log-show-hide-{$type}" )->params( $this->msg( 'show' )->text() );
+                       }
+                       $options[ $message->text() ] = $type;
 
-                       // Message: log-show-hide-patrol
-                       $links[$type] = $this->msg( "log-show-hide-{$type}" )->rawParams( $link )->escaped();
-                       $hiddens .= Html::hidden( "hide_{$type}_log", $val ) . "\n";
+                       if ( $val === false ) {
+                               $default[] = $type;
+                       }
                }
-
-               // Build links
-               return '<small>' . $this->getLanguage()->pipeList( $links ) . '</small>' . $hiddens;
+               return [
+                       'class' => 'HTMLMultiSelectField',
+                       'label-message' => 'logeventslist-more-filters',
+                       'flatlist' => true,
+                       'options' => $options,
+                       'default' => $default,
+               ];
        }
 
        private function getDefaultQuery() {
@@ -213,22 +234,11 @@ class LogEventsList extends ContextSource {
 
        /**
         * @param array $queryTypes
-        * @return string Formatted HTML
+        * @return array Form descriptor
         */
-       private function getTypeMenu( $queryTypes ) {
+       private function getTypeMenuDesc( $queryTypes ) {
                $queryType = count( $queryTypes ) == 1 ? $queryTypes[0] : '';
-               $selector = $this->getTypeSelector();
-               $selector->setDefault( $queryType );
-
-               return $selector->getHTML();
-       }
 
-       /**
-        * Returns log page selector.
-        * @return XmlSelect
-        * @since 1.19
-        */
-       public function getTypeSelector() {
                $typesByName = []; // Temporary array
                // First pass to load the log names
                foreach ( LogPage::validTypes() as $type ) {
@@ -247,105 +257,100 @@ class LogEventsList extends ContextSource {
                unset( $typesByName[''] );
                $typesByName = [ '' => $public ] + $typesByName;
 
-               $select = new XmlSelect( 'type' );
-               foreach ( $typesByName as $type => $name ) {
-                       $select->addOption( $name, $type );
-               }
-
-               return $select;
+               return [
+                       'class' => 'HTMLSelectField',
+                       'name' => 'type',
+                       'options' => array_flip( $typesByName ),
+                       'default' => $queryType,
+               ];
        }
 
        /**
         * @param string $user
-        * @return string Formatted HTML
+        * @return array Form descriptor
         */
-       private function getUserInput( $user ) {
-               $label = Xml::inputLabel(
-                       $this->msg( 'specialloguserlabel' )->text(),
-                       'user',
-                       'mw-log-user',
-                       15,
-                       $user,
-                       [ 'class' => 'mw-autocomplete-user' ]
-               );
-
-               return '<span class="mw-input-with-label">' . $label . '</span>';
+       private function getUserInputDesc( $user ) {
+               return [
+                       'class' => 'HTMLUserTextField',
+                       'label-message' => 'specialloguserlabel',
+                       'name' => 'user',
+                       'default' => $user,
+               ];
        }
 
        /**
         * @param string $title
-        * @return string Formatted HTML
+        * @return array Form descriptor
         */
-       private function getTitleInput( $title ) {
-               $label = Xml::inputLabel(
-                       $this->msg( 'speciallogtitlelabel' )->text(),
-                       'page',
-                       'mw-log-page',
-                       20,
-                       $title
-               );
-
-               return '<span class="mw-input-with-label">' . $label .  '</span>';
+       private function getTitleInputDesc( $title ) {
+               return [
+                       'class' => 'HTMLTitleTextField',
+                       'label-message' => 'speciallogtitlelabel',
+                       'name' => 'page',
+                       'required' => false
+               ];
        }
 
        /**
         * @param bool $pattern
-        * @return string Checkbox
+        * @return array Form descriptor
         */
-       private function getTitlePattern( $pattern ) {
-               return '<span class="mw-input-with-label">' .
-                       Xml::checkLabel( $this->msg( 'log-title-wildcard' )->text(), 'pattern', 'pattern', $pattern ) .
-                       '</span>';
+       private function getTitlePatternDesc( $pattern ) {
+               return [
+                       'type' => 'check',
+                       'label-message' => 'log-title-wildcard',
+                       'name' => 'pattern',
+               ];
        }
 
        /**
         * @param array $types
-        * @return string
+        * @return array|string Form descriptor or string with HTML
         */
-       private function getExtraInputs( $types ) {
+       private function getExtraInputsDesc( $types ) {
                if ( count( $types ) == 1 ) {
                        if ( $types[0] == 'suppress' ) {
-                               $offender = $this->getRequest()->getVal( 'offender' );
-                               $user = User::newFromName( $offender, false );
-                               if ( !$user || ( $user->getId() == 0 && !IP::isIPAddress( $offender ) ) ) {
-                                       $offender = ''; // Blank field if invalid
-                               }
-                               return Xml::inputLabel( $this->msg( 'revdelete-offender' )->text(), 'offender',
-                                       'mw-log-offender', 20, $offender );
+                               return [
+                                       'type' => 'text',
+                                       'label-message' => 'revdelete-offender',
+                                       'name' => 'offender',
+                               ];
                        } else {
                                // Allow extensions to add their own extra inputs
-                               $input = '';
-                               Hooks::run( 'LogEventsListGetExtraInputs', [ $types[0], $this, &$input ] );
-                               return $input;
+                               // This could be an array or string. See T199495.
+                               $input = ''; // Deprecated
+                               $formDescriptor = [];
+                               Hooks::run( 'LogEventsListGetExtraInputs', [ $types[0], $this, &$input, &$formDescriptor ] );
+
+                               return empty( $formDescriptor ) ? $input : $formDescriptor;
                        }
                }
 
-               return '';
+               return [];
        }
 
        /**
         * Drop down menu for selection of actions that can be used to filter the log
         * @param array $types
         * @param string $action
-        * @return string
-        * @since 1.27
+        * @return array Form descriptor
         */
-       private function getActionSelector( $types, $action ) {
-               if ( $this->allowedActions === null || !count( $this->allowedActions ) ) {
-                       return '';
-               }
-               $html = '';
-               $html .= Xml::label( wfMessage( 'log-action-filter-' . $types[0] )->text(),
-                       'action-filter-' .$types[0] ) . "\n";
-               $select = new XmlSelect( 'subtype' );
-               $select->addOption( wfMessage( 'log-action-filter-all' )->text(), '' );
+       private function getActionSelectorDesc( $types, $action ) {
+               $actionOptions = [];
+               $actionOptions[ 'log-action-filter-all' ] = '';
+
                foreach ( $this->allowedActions as $value ) {
                        $msgKey = 'log-action-filter-' . $types[0] . '-' . $value;
-                       $select->addOption( wfMessage( $msgKey )->text(), $value );
+                       $actionOptions[ $msgKey ] = $value;
                }
-               $select->setDefault( $action );
-               $html .= $select->getHTML();
-               return $html;
+
+               return [
+                       'class' => 'HTMLSelectField',
+                       'name' => 'subtype',
+                       'options-messages' => $actionOptions,
+                       'default' => $action,
+                       'label' => $this->msg( 'log-action-filter-' . $types[0] )->text(),
+               ];
        }
 
        /**
@@ -420,7 +425,10 @@ class LogEventsList extends ContextSource {
 
                // Let extensions add data
                Hooks::run( 'LogEventsListLineEnding', [ $this, &$ret, $entry, &$classes, &$attribs ] );
-               $attribs = wfArrayFilterByKey( $attribs, [ Sanitizer::class, 'isReservedDataAttribute' ] );
+               $attribs = array_filter( $attribs,
+                       [ Sanitizer::class, 'isReservedDataAttribute' ],
+                       ARRAY_FILTER_USE_KEY
+               );
                $attribs['class'] = implode( ' ', $classes );
 
                return Html::rawElement( 'li', $attribs, $ret ) . "\n";
@@ -524,7 +532,7 @@ class LogEventsList extends ContextSource {
         *
         * @param stdClass $row
         * @param int $field
-        * @param User $user User to check, or null to use $wgUser
+        * @param User|null $user User to check, or null to use $wgUser
         * @return bool
         */
        public static function userCan( $row, $field, User $user = null ) {
@@ -537,7 +545,7 @@ class LogEventsList extends ContextSource {
         *
         * @param int $bitfield Current field
         * @param int $field
-        * @param User $user User to check, or null to use $wgUser
+        * @param User|null $user User to check, or null to use $wgUser
         * @return bool
         */
        public static function userCanBitfield( $bitfield, $field, User $user = null ) {
@@ -553,7 +561,7 @@ class LogEventsList extends ContextSource {
                        }
                        $permissionlist = implode( ', ', $permissions );
                        wfDebug( "Checking for $permissionlist due to $field match on $bitfield\n" );
-                       return call_user_func_array( [ $user, 'isAllowedAny' ], $permissions );
+                       return $user->isAllowedAny( ...$permissions );
                }
                return true;
        }
@@ -745,7 +753,7 @@ class LogEventsList extends ContextSource {
         *
         * @param IDatabase $db
         * @param string $audience Public/user
-        * @param User $user User to check, or null to use $wgUser
+        * @param User|null $user User to check, or null to use $wgUser
         * @return string|bool String on success, false on failure.
         */
        public static function getExcludeClause( $db, $audience = 'public', User $user = null ) {
index 0ffe691..d59c6aa 100644 (file)
@@ -19,7 +19,7 @@
  *
  * @file
  * @author Niklas Laxström
- * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ * @license GPL-2.0-or-later
  * @since 1.19
  */
 use MediaWiki\Linker\LinkRenderer;
@@ -377,7 +377,7 @@ class LogFormatter {
                                                // new key (5::duration/6::flags) or old key (0/optional 1)
                                                if ( $entry->isLegacy() ) {
                                                        $rawDuration = $parameters[0];
-                                                       $rawFlags = isset( $parameters[1] ) ? $parameters[1] : '';
+                                                       $rawFlags = $parameters[1] ?? '';
                                                } else {
                                                        $rawDuration = $parameters['5::duration'];
                                                        $rawFlags = $parameters['6::flags'];
@@ -639,7 +639,7 @@ class LogFormatter {
        /**
         * Helper to make a link to the page, taking the plaintext
         * value in consideration.
-        * @param Title $title The page
+        * @param Title|null $title The page
         * @param array $parameters Query parameters
         * @param string|null $html Linktext of the link as raw html
         * @throws MWException
index 9f34264..265a41c 100644 (file)
@@ -37,8 +37,8 @@ class LogPage {
        const DELETED_RESTRICTED = 8;
 
        // Convenience fields
-       const SUPPRESSED_USER = 12;
-       const SUPPRESSED_ACTION = 9;
+       const SUPPRESSED_USER = self::DELETED_USER | self::DELETED_RESTRICTED;
+       const SUPPRESSED_ACTION = self::DELETED_ACTION | self::DELETED_RESTRICTED;
 
        /** @var bool */
        public $updateRecentChanges;
index 84653b1..e7096c4 100644 (file)
@@ -63,13 +63,14 @@ class LogPager extends ReverseChronologicalPager {
         * @param array $conds Extra conditions for the query
         * @param int|bool $year The year to start from. Default: false
         * @param int|bool $month The month to start from. Default: false
+        * @param int|bool $day The day to start from. Default: false
         * @param string $tagFilter Tag
         * @param string $action Specific action (subtype) requested
         * @param int $logId Log entry ID, to limit to a single log entry.
         */
        public function __construct( $list, $types = [], $performer = '', $title = '',
-               $pattern = false, $conds = [], $year = false, $month = false, $tagFilter = '',
-               $action = '', $logId = false
+               $pattern = false, $conds = [], $year = false, $month = false, $day = false,
+               $tagFilter = '', $action = '', $logId = false
        ) {
                parent::__construct( $list->getContext() );
                $this->mConds = $conds;
@@ -80,7 +81,7 @@ class LogPager extends ReverseChronologicalPager {
                $this->limitPerformer( $performer );
                $this->limitTitle( $title, $pattern );
                $this->limitAction( $action );
-               $this->getDateCond( $year, $month );
+               $this->getDateCond( $year, $month, $day );
                $this->mTagFilter = $tagFilter;
                $this->limitLogId( $logId );
 
@@ -91,6 +92,7 @@ class LogPager extends ReverseChronologicalPager {
                $query = parent::getDefaultQuery();
                $query['type'] = $this->typeCGI; // arrays won't work here
                $query['user'] = $this->performer;
+               $query['day'] = $this->mDay;
                $query['month'] = $this->mMonth;
                $query['year'] = $this->mYear;
 
@@ -104,8 +106,17 @@ class LogPager extends ReverseChronologicalPager {
                if ( count( $this->types ) ) {
                        return $filters;
                }
+
+               $wpfilters = $this->getRequest()->getArray( "wpfilters" );
+               $request_filters = $wpfilters === null ? [] : $wpfilters;
+
                foreach ( $wgFilterLogTypes as $type => $default ) {
-                       $hide = $this->getRequest()->getInt( "hide_{$type}_log", $default );
+                       $hide = !in_array( $type, $request_filters );
+
+                       // Back-compat: Check old URL params if the new param wasn't passed
+                       if ( $wpfilters === null ) {
+                               $hide = $this->getRequest()->getBool( "hide_{$type}_log", $default );
+                       }
 
                        $filters[$type] = $hide;
                        if ( $hide ) {
@@ -413,6 +424,10 @@ class LogPager extends ReverseChronologicalPager {
                return $this->mMonth;
        }
 
+       public function getDay() {
+               return $this->mDay;
+       }
+
        public function getTagFilter() {
                return $this->mTagFilter;
        }
index 8775097..7a6fb9d 100644 (file)
@@ -18,7 +18,7 @@
  * http://www.gnu.org/copyleft/gpl.html
  *
  * @file
- * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ * @license GPL-2.0-or-later
  * @since 1.25
  */
 
index 43ca0ea..637a8e7 100644 (file)
@@ -19,7 +19,7 @@
  *
  * @file
  * @author Niklas Laxström
- * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ * @license GPL-2.0-or-later
  * @since 1.22
  */
 
index 382e4ad..911ab95 100644 (file)
@@ -19,7 +19,7 @@
  *
  * @file
  * @author Niklas Laxström
- * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ * @license GPL-2.0-or-later
  * @since 1.22
  */
 
index 694fa7f..a08427a 100644 (file)
@@ -19,7 +19,7 @@
  *
  * @file
  * @author Kunal Grover
- * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ * @license GPL-2.0-or-later
  * @since 1.24
  */
 
index 9b2e098..d737a4b 100644 (file)
@@ -33,8 +33,8 @@ class PatrolLog {
         *
         * @param int|RecentChange $rc Change identifier or RecentChange object
         * @param bool $auto Was this patrol event automatic?
-        * @param User $user User performing the action or null to use $wgUser
-        * @param string|string[] $tags Change tags to add to the patrol log entry
+        * @param User|null $user User performing the action or null to use $wgUser
+        * @param string|string[]|null $tags Change tags to add to the patrol log entry
         *   ($user should be able to add the specified tags before this is called)
         *
         * @return bool
index 894f59b..e02a703 100644 (file)
@@ -19,7 +19,7 @@
  *
  * @file
  * @author Niklas Laxström
- * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ * @license GPL-2.0-or-later
  * @since 1.22
  */
 
index 64ec626..931829a 100644 (file)
@@ -18,7 +18,7 @@
  * http://www.gnu.org/copyleft/gpl.html
  *
  * @file
- * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ * @license GPL-2.0-or-later
  * @since 1.26
  */
 
index 4b4d19f..6e527e8 100644 (file)
@@ -19,7 +19,7 @@
  *
  * @file
  * @author Alexandre Emsenhuber
- * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ * @license GPL-2.0-or-later
  * @since 1.22
  */
 
@@ -95,7 +95,7 @@ class RightsLogFormatter extends LogFormatter {
 
                if ( count( $oldGroups ) ) {
                        $params[3] = [ 'raw' => $this->formatRightsList( $oldGroups,
-                               isset( $allParams['oldmetadata'] ) ? $allParams['oldmetadata'] : [] ) ];
+                               $allParams['oldmetadata'] ?? [] ) ];
                } else {
                        $params[3] = $this->msg( 'rightsnone' )->text();
                }
@@ -103,7 +103,7 @@ class RightsLogFormatter extends LogFormatter {
                        // Array_values is used here because of T44211
                        // see use of array_unique in UserrightsPage::doSaveUserGroups on $newGroups.
                        $params[4] = [ 'raw' => $this->formatRightsList( array_values( $newGroups ),
-                               isset( $allParams['newmetadata'] ) ? $allParams['newmetadata'] : [] ) ];
+                               $allParams['newmetadata'] ?? [] ) ];
                } else {
                        $params[4] = $this->msg( 'rightsnone' )->text();
                }
@@ -181,8 +181,7 @@ class RightsLogFormatter extends LogFormatter {
                                if ( isset( $oldmetadata[$index] ) ) {
                                        $result += $oldmetadata[$index];
                                }
-                               $result['expiry'] = ApiResult::formatExpiry( isset( $result['expiry'] ) ?
-                                       $result['expiry'] : null );
+                               $result['expiry'] = ApiResult::formatExpiry( $result['expiry'] ?? null );
 
                                return $result;
                        }, array_keys( $params['4:array:oldgroups'] ) );
@@ -199,8 +198,7 @@ class RightsLogFormatter extends LogFormatter {
                                if ( isset( $newmetadata[$index] ) ) {
                                        $result += $newmetadata[$index];
                                }
-                               $result['expiry'] = ApiResult::formatExpiry( isset( $result['expiry'] ) ?
-                                       $result['expiry'] : null );
+                               $result['expiry'] = ApiResult::formatExpiry( $result['expiry'] ?? null );
 
                                return $result;
                        }, array_keys( $params['5:array:newgroups'] ) );
index 230d13b..8458e0b 100644 (file)
  * @since 1.25
  */
 class TagLogFormatter extends LogFormatter {
+
+       protected function getMessageParameters() {
+               $params = parent::getMessageParameters();
+
+               $isRevLink = !empty( $params[3] );
+               if ( $isRevLink ) {
+                       $id = $params[3];
+                       $target = $this->entry->getTarget();
+                       $query = [
+                               'oldid' => $id,
+                               'diff' => 'prev'
+                       ];
+               } else {
+                       $id = $params[4];
+                       $target = SpecialPage::getTitleValueFor( 'Log' );
+                       $query = [
+                               'logid' => $id,
+                       ];
+               }
+
+               $formattedNumber = $this->context->getLanguage()->formatNum( $id, true );
+               if ( $this->plaintext ) {
+                       $link = $formattedNumber;
+               } elseif ( !$isRevLink || $target->exists() ) {
+                       $link = $this->getLinkRenderer()->makeKnownLink(
+                               $target, $formattedNumber, [], $query );
+               } else {
+                       $link = htmlspecialchars( $formattedNumber );
+               }
+
+               if ( $isRevLink ) {
+                       $params[3] = Message::rawParam( $link );
+               } else {
+                       $params[4] = Message::rawParam( $link );
+               }
+
+               return $params;
+       }
+
        protected function getMessageKey() {
                $key = parent::getMessageKey();
                $params = $this->getMessageParameters();
@@ -50,4 +89,5 @@ class TagLogFormatter extends LogFormatter {
 
                return $key;
        }
+
 }
index 6c53671..a73052d 100644 (file)
@@ -18,7 +18,7 @@
  * http://www.gnu.org/copyleft/gpl.html
  *
  * @file
- * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ * @license GPL-2.0-or-later
  * @since 1.25
  */
 
index 13b5559..19f5144 100644 (file)
@@ -18,7 +18,7 @@
  * http://www.gnu.org/copyleft/gpl.html
  *
  * @file
- * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ * @license GPL-2.0-or-later
  */
 
 /**
index b9d9414..1b66c38 100644 (file)
@@ -47,8 +47,8 @@ class MailAddress {
 
        /**
         * @param string $address String with an email address, or a User object
-        * @param string $name Human-readable name if a string address is given
-        * @param string $realName Human-readable real name if a string address is given
+        * @param string|null $name Human-readable name if a string address is given
+        * @param string|null $realName Human-readable real name if a string address is given
         */
        function __construct( $address, $name = null, $realName = null ) {
                if ( is_object( $address ) && $address instanceof User ) {
index bdd4f44..5d7afd3 100644 (file)
@@ -244,10 +244,9 @@ class UserMailer {
                global $wgSMTP, $wgEnotifMaxRecips, $wgAdditionalMailParams;
                $mime = null;
 
-               $replyto = isset( $options['replyTo'] ) ? $options['replyTo'] : null;
-               $contentType = isset( $options['contentType'] ) ?
-                       $options['contentType'] : 'text/plain; charset=UTF-8';
-               $headers = isset( $options['headers'] ) ? $options['headers'] : [];
+               $replyto = $options['replyTo'] ?? null;
+               $contentType = $options['contentType'] ?? 'text/plain; charset=UTF-8';
+               $headers = $options['headers'] ?? [];
 
                // Allow transformation of content, such as encrypting/signing
                $error = false;
index cda037c..e2d32cf 100644 (file)
@@ -228,7 +228,7 @@ class BitmapHandler extends TransformationalImageHandler {
                $rotation = isset( $params['disableRotation'] ) ? 0 : $this->getRotation( $image );
                list( $width, $height ) = $this->extractPreRotationDimensions( $params, $rotation );
 
-               $cmd = call_user_func_array( 'wfEscapeShellArg', array_merge(
+               $cmd = wfEscapeShellArg( ...array_merge(
                        [ $wgImageMagickConvertCommand ],
                        $quality,
                        // Specify white background color, will be used for transparent images
@@ -449,7 +449,7 @@ class BitmapHandler extends TransformationalImageHandler {
                        return $this->getMediaTransformError( $params, $errMsg );
                }
 
-               $src_image = call_user_func( $loader, $params['srcPath'] );
+               $src_image = $loader( $params['srcPath'] );
 
                $rotation = function_exists( 'imagerotate' ) && !isset( $params['disableRotation'] ) ?
                        $this->getRotation( $image ) :
@@ -489,7 +489,7 @@ class BitmapHandler extends TransformationalImageHandler {
                if ( $useQuality && isset( $params['quality'] ) ) {
                        $funcParams[] = $params['quality'];
                }
-               call_user_func_array( $saveType, $funcParams );
+               $saveType( ...$funcParams );
 
                imagedestroy( $dst_image );
                imagedestroy( $src_image );
index 9e0fc3d..c0dfa3a 100644 (file)
@@ -22,6 +22,7 @@
  */
 
 use MediaWiki\Logger\LoggerFactory;
+use Wikimedia\XMPReader\Reader as XMPReader;
 
 /**
  * Class to deal with reconciling and extracting metadata from bitmap images.
@@ -184,7 +185,7 @@ class BitmapMetadataHandler {
                        }
                }
 
-               $meta->getExif( $filename, isset( $seg['byteOrder'] ) ? $seg['byteOrder'] : 'BE' );
+               $meta->getExif( $filename, $seg['byteOrder'] ?? 'BE' );
 
                return $meta->getMetadataArray();
        }
index 0229ac1..ed6e76f 100644 (file)
@@ -41,7 +41,7 @@ class BmpHandler extends BitmapHandler {
         *
         * @param string $text
         * @param string $mime
-        * @param array $params
+        * @param array|null $params
         * @return array
         */
        function getThumbType( $text, $mime, $params = null ) {
index 2541e35..14074ef 100644 (file)
@@ -105,7 +105,7 @@ class DjVuHandler extends ImageHandler {
         * @return bool|string
         */
        public function makeParamString( $params ) {
-               $page = isset( $params['page'] ) ? $params['page'] : 1;
+               $page = $params['page'] ?? 1;
                if ( !isset( $params['width'] ) ) {
                        return false;
                }
index a38e79b..9977f45 100644 (file)
@@ -20,7 +20,7 @@
  * @ingroup Media
  * @author Ævar Arnfjörð Bjarmason <avarab@gmail.com>
  * @copyright Copyright © 2005, Ævar Arnfjörð Bjarmason, 2009 Brent Garber
- * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License
+ * @license GPL-2.0-or-later
  * @see http://exif.org/Exif2-2.PDF The Exif 2.2 specification
  * @file
  */
@@ -742,12 +742,16 @@ class Exif {
                                $ecount = 1; // checking individual elements
                        }
                }
-               $count = count( $val );
-               if ( $ecount != $count ) {
-                       $this->debug( $val, __FUNCTION__, "Expected $ecount elements for $tag but got $count" );
 
-                       return false;
+               $count = 1;
+               if ( is_array( $val ) ) {
+                       $count = count( $val );
+                       if ( $ecount != $count ) {
+                               $this->debug( $val, __FUNCTION__, "Expected $ecount elements for $tag but got $count" );
+                               return false;
+                       }
                }
+               // If there are multiple values, recursively validate each of them.
                if ( $count > 1 ) {
                        foreach ( $val as $v ) {
                                if ( !$this->validate( $section, $tag, $v, true ) ) {
index f683da2..f647a9d 100644 (file)
@@ -20,7 +20,7 @@
  * @ingroup Media
  * @author Ævar Arnfjörð Bjarmason <avarab@gmail.com>
  * @copyright Copyright © 2005, Ævar Arnfjörð Bjarmason, 2009 Brent Garber, 2010 Brian Wolff
- * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License
+ * @license GPL-2.0-or-later
  * @see http://exif.org/Exif2-2.PDF The Exif 2.2 specification
  * @file
  */
@@ -271,7 +271,7 @@ class FormatMetadata extends ContextSource {
                                        // TODO: YCbCrCoefficients  #p27 (see annex E)
                                        case 'ExifVersion':
                                        case 'FlashpixVersion':
-                                               $val = "$val" / 100;
+                                               $val = (int)$val / 100;
                                                break;
 
                                        case 'ColorSpace':
@@ -787,7 +787,7 @@ class FormatMetadata extends ContextSource {
                                                        }
                                                }
                                                if ( is_numeric( $val ) ) {
-                                                       $fNumber = pow( 2, $val / 2 );
+                                                       $fNumber = 2 ** ( $val / 2 );
                                                        if ( $fNumber !== false ) {
                                                                $val = $this->msg( 'exif-maxaperturevalue-value',
                                                                        $this->formatNum( $val ),
@@ -971,11 +971,7 @@ class FormatMetadata extends ContextSource {
 
                                        case 'LanguageCode':
                                                $lang = Language::fetchLanguageName( strtolower( $val ), $this->getLanguage()->getCode() );
-                                               if ( $lang ) {
-                                                       $val = htmlspecialchars( $lang );
-                                               } else {
-                                                       $val = htmlspecialchars( $val );
-                                               }
+                                               $val = htmlspecialchars( $lang ?: $val );
                                                break;
 
                                        default:
@@ -1859,9 +1855,9 @@ class FormatMetadata extends ContextSource {
                // drop all characters which are not valid in an XML tag name
                // a bunch of non-ASCII letters would be valid but probably won't
                // be used so we take the easy way
-               $key = preg_replace( '/[^a-zA-z0-9_:.-]/', '', $key );
+               $key = preg_replace( '/[^a-zA-z0-9_:.\-]/', '', $key );
                // drop characters which are invalid at the first position
-               $key = preg_replace( '/^[\d-.]+/', '', $key );
+               $key = preg_replace( '/^[\d\-.]+/', '', $key );
 
                if ( $key == '' ) {
                        $key = '_';
index a26539a..591ccf1 100644 (file)
@@ -264,7 +264,7 @@ class GIFMetadataExtractor {
         */
        static function readGCT( $fh, $bpp ) {
                if ( $bpp > 0 ) {
-                       $max = pow( 2, $bpp );
+                       $max = 2 ** $bpp;
                        for ( $i = 1; $i <= $max; ++$i ) {
                                fread( $fh, 3 );
                        }
index 3c778f3..8a26f60 100644 (file)
@@ -21,6 +21,8 @@
  * @ingroup Media
  */
 
+use Wikimedia\XMPReader\Reader as XMPReader;
+
 /**
  * Class for reading jpegs and extracting metadata.
  * see also BitmapMetadataHandler.
index c76930c..4583632 100644 (file)
@@ -284,7 +284,7 @@ abstract class MediaHandler {
         *
         * @param string $ext Extension of original file
         * @param string $mime MIME type of original file
-        * @param array $params Handler specific rendering parameters
+        * @param array|null $params Handler specific rendering parameters
         * @return array Thumbnail extension and MIME type
         */
        function getThumbType( $ext, $mime, $params = null ) {
index 3506684..010cf80 100644 (file)
@@ -236,7 +236,7 @@ abstract class MediaTransformOutput {
        }
 
        /**
-        * @param string $title
+        * @param string|null $title
         * @param string|array $params Query parameters to add
         * @return array
         */
@@ -360,9 +360,9 @@ class ThumbnailImage extends MediaTransformOutput {
                        throw new MWException( __METHOD__ . ' called in the old style' );
                }
 
-               $alt = isset( $options['alt'] ) ? $options['alt'] : '';
+               $alt = $options['alt'] ?? '';
 
-               $query = isset( $options['desc-query'] ) ? $options['desc-query'] : '';
+               $query = $options['desc-query'] ?? '';
 
                $attribs = [
                        'alt' => $alt,
@@ -487,8 +487,8 @@ class MediaTransformError extends MediaTransformOutput {
 class TransformParameterError extends MediaTransformError {
        function __construct( $params ) {
                parent::__construct( 'thumbnail_error',
-                       max( isset( $params['width'] ) ? $params['width'] : 0, 120 ),
-                       max( isset( $params['height'] ) ? $params['height'] : 0, 120 ),
+                       max( $params['width'] ?? 0, 120 ),
+                       max( $params['height'] ?? 0, 120 ),
                        wfMessage( 'thumbnail_invalid_params' )
                );
        }
@@ -507,13 +507,13 @@ class TransformParameterError extends MediaTransformError {
 class TransformTooBigImageAreaError extends MediaTransformError {
        function __construct( $params, $maxImageArea ) {
                $msg = wfMessage( 'thumbnail_toobigimagearea' );
-               $msg->rawParams(
+               $msg->params(
                        $msg->getLanguage()->formatComputingNumbers( $maxImageArea, 1000, "size-$1pixel" )
                );
 
                parent::__construct( 'thumbnail_error',
-                       max( isset( $params['width'] ) ? $params['width'] : 0, 120 ),
-                       max( isset( $params['height'] ) ? $params['height'] : 0, 120 ),
+                       max( $params['width'] ?? 0, 120 ),
+                       max( $params['height'] ?? 0, 120 ),
                        $msg
                );
        }
index fc93b23..e00a5b3 100644 (file)
@@ -22,7 +22,7 @@
  * @author "Derk-Jan Hartman <hartman _at_ videolan d0t org>"
  * @author Brion Vibber
  * @copyright Copyright © 2010-2010 Brion Vibber, Derk-Jan Hartman
- * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License
+ * @license GPL-2.0-or-later
  */
 
 /**
index 9085421..a9c7b4f 100644 (file)
@@ -201,7 +201,7 @@ class SvgHandler extends ImageHandler {
                $clientHeight = $params['height'];
                $physicalWidth = $params['physicalWidth'];
                $physicalHeight = $params['physicalHeight'];
-               $lang = isset( $params['lang'] ) ? $params['lang'] : $this->getDefaultRenderLanguage( $image );
+               $lang = $params['lang'] ?? $this->getDefaultRenderLanguage( $image );
 
                if ( $flags & self::TRANSFORM_LATER ) {
                        return new ThumbnailImage( $image, $dstUrl, $dstPath, $params );
@@ -291,12 +291,16 @@ class SvgHandler extends ImageHandler {
                        if ( is_array( $wgSVGConverters[$wgSVGConverter] ) ) {
                                // This is a PHP callable
                                $func = $wgSVGConverters[$wgSVGConverter][0];
-                               $args = array_merge( [ $srcPath, $dstPath, $width, $height, $lang ],
-                                       array_slice( $wgSVGConverters[$wgSVGConverter], 1 ) );
                                if ( !is_callable( $func ) ) {
                                        throw new MWException( "$func is not callable" );
                                }
-                               $err = call_user_func_array( $func, $args );
+                               $err = $func( $srcPath,
+                                       $dstPath,
+                                       $width,
+                                       $height,
+                                       $lang,
+                                       ...array_slice( $wgSVGConverters[$wgSVGConverter], 1 )
+                               );
                                $retval = (bool)$err;
                        } else {
                                // External command
index f0f4cda..441513e 100644 (file)
@@ -61,7 +61,7 @@ class TiffHandler extends ExifBitmapHandler {
        /**
         * @param string $ext
         * @param string $mime
-        * @param array $params
+        * @param array|null $params
         * @return bool
         */
        function getThumbType( $ext, $mime, $params = null ) {
index 85430d2..ea0d61b 100644 (file)
@@ -127,7 +127,7 @@ abstract class TransformationalImageHandler extends ImageHandler {
                        'mimeType' => $image->getMimeType(),
                        'dstPath' => $dstPath,
                        'dstUrl' => $dstUrl,
-                       'interlace' => isset( $params['interlace'] ) ? $params['interlace'] : false,
+                       'interlace' => $params['interlace'] ?? false,
                ];
 
                if ( isset( $params['quality'] ) && $params['quality'] === 'low' ) {
index 491fef2..0cb618f 100644 (file)
@@ -46,7 +46,7 @@ class XCFHandler extends BitmapHandler {
         *
         * @param string $ext
         * @param string $mime
-        * @param array $params
+        * @param array|null $params
         * @return array
         */
        function getThumbType( $ext, $mime, $params = null ) {
index c384032..6d76d5e 100644 (file)
@@ -182,13 +182,9 @@ class ObjectCache {
                } elseif ( isset( $params['class'] ) ) {
                        $class = $params['class'];
                        // Automatically set the 'async' update handler
-                       $params['asyncHandler'] = isset( $params['asyncHandler'] )
-                               ? $params['asyncHandler']
-                               : 'DeferredUpdates::addCallableUpdate';
+                       $params['asyncHandler'] = $params['asyncHandler'] ?? 'DeferredUpdates::addCallableUpdate';
                        // Enable reportDupes by default
-                       $params['reportDupes'] = isset( $params['reportDupes'] )
-                               ? $params['reportDupes']
-                               : true;
+                       $params['reportDupes'] = $params['reportDupes'] ?? true;
                        // Do b/c logic for SqlBagOStuff
                        if ( is_a( $class, SqlBagOStuff::class, true ) ) {
                                if ( isset( $params['server'] ) && !isset( $params['servers'] ) ) {
@@ -289,7 +285,7 @@ class ObjectCache {
                $cache = MediaWikiServices::getInstance()->getLocalServerObjectCache();
                if ( $cache instanceof EmptyBagOStuff ) {
                        if ( is_array( $fallback ) ) {
-                               $fallback = isset( $fallback['fallback'] ) ? $fallback['fallback'] : CACHE_NONE;
+                               $fallback = $fallback['fallback'] ?? CACHE_NONE;
                        }
                        $cache = self::getInstance( $fallback );
                }
index 8ff14ed..076f208 100644 (file)
@@ -117,7 +117,7 @@ class SqlBagOStuff extends BagOStuff {
                                if ( is_string( $tag ) ) {
                                        $this->serverTags[$index] = $tag;
                                } else {
-                                       $this->serverTags[$index] = isset( $info['host'] ) ? $info['host'] : "#$index";
+                                       $this->serverTags[$index] = $info['host'] ?? "#$index";
                                }
                                ++$index;
                        }
@@ -168,8 +168,8 @@ class SqlBagOStuff extends BagOStuff {
                        if ( $this->serverInfos ) {
                                // Use custom database defined by server connection info
                                $info = $this->serverInfos[$serverIndex];
-                               $type = isset( $info['type'] ) ? $info['type'] : 'mysql';
-                               $host = isset( $info['host'] ) ? $info['host'] : '[unknown]';
+                               $type = $info['type'] ?? 'mysql';
+                               $host = $info['host'] ?? '[unknown]';
                                $this->logger->debug( __CLASS__ . ": connecting to $host" );
                                // Use a blank trx profiler to ignore expections as this is a cache
                                $info['trxProfiler'] = new TransactionProfiler();
index c865d4e..49912c7 100644 (file)
@@ -85,7 +85,7 @@ class Article implements Page {
        /**
         * Constructor and clear the article
         * @param Title $title Reference to a Title object.
-        * @param int $oldId Revision ID, null to fetch from request, zero for current
+        * @param int|null $oldId Revision ID, null to fetch from request, zero for current
         */
        public function __construct( Title $title, $oldId = null ) {
                $this->mOldId = $oldId;
@@ -279,8 +279,8 @@ class Article implements Page {
                                if ( $this->mRevision !== null ) {
                                        // Revision title doesn't match the page title given?
                                        if ( $this->mPage->getId() != $this->mRevision->getPage() ) {
-                                               $function = [ get_class( $this->mPage ), 'newFromID' ];
-                                               $this->mPage = call_user_func( $function, $this->mRevision->getPage() );
+                                               $function = get_class( $this->mPage ). '::newFromID';
+                                               $this->mPage = $function( $this->mRevision->getPage() );
                                        }
                                }
                        }
@@ -733,7 +733,7 @@ class Article implements Page {
                );
 
                // DifferenceEngine directly fetched the revision:
-               $this->mRevIdFetched = $de->mNewid;
+               $this->mRevIdFetched = $de->getNewid();
                $de->showDiffPage( $diffOnly );
 
                // Run view updates for the newer revision being diffed (and shown
@@ -976,6 +976,11 @@ class Article implements Page {
        public function showPatrolFooter() {
                global $wgUseNPPatrol, $wgUseRCPatrol, $wgUseFilePatrol;
 
+               // Allow hooks to decide whether to not output this at all
+               if ( !Hooks::run( 'ArticleShowPatrolFooter', [ $this ] ) ) {
+                       return false;
+               }
+
                $outputPage = $this->getContext()->getOutput();
                $user = $this->getContext()->getUser();
                $title = $this->getTitle();
@@ -1962,7 +1967,7 @@ class Article implements Page {
         * @since 1.16 (r52326) for LiquidThreads
         *
         * @param int|null $oldid Revision ID or null
-        * @param User $user The relevant user
+        * @param User|null $user The relevant user
         * @return ParserOutput|bool ParserOutput or false if the given revision ID is not found
         */
        public function getParserOutput( $oldid = null, User $user = null ) {
@@ -2114,11 +2119,11 @@ class Article implements Page {
         * @deprecated since 1.29. Use WikiPage::doEditContent() directly instead
         * @see WikiPage::doEditContent
         */
-       public function doEditContent( Content $content, $summary, $flags = 0, $baseRevId = false,
+       public function doEditContent( Content $content, $summary, $flags = 0, $originalRevId = false,
                User $user = null, $serialFormat = null
        ) {
                wfDeprecated( __METHOD__, '1.29' );
-               return $this->mPage->doEditContent( $content, $summary, $flags, $baseRevId,
+               return $this->mPage->doEditContent( $content, $summary, $flags, $originalRevId,
                        $user, $serialFormat
                );
        }
@@ -2615,8 +2620,8 @@ class Article implements Page {
        /**
         * @param string $reason
         * @param bool $suppress
-        * @param int $u1 Unused
-        * @param bool $u2 Unused
+        * @param int|null $u1 Unused
+        * @param bool|null $u2 Unused
         * @param string &$error
         * @return bool
         */
index b5ff805..58f25d4 100644 (file)
@@ -440,7 +440,7 @@ class ImagePage extends Article {
                                                // in the mediawiki.page.image.pagination module
                                                $link = Linker::linkKnown(
                                                        $this->getTitle(),
-                                                       $label,
+                                                       htmlspecialchars( $label ),
                                                        [],
                                                        [ 'page' => $page - 1 ]
                                                );
@@ -460,7 +460,7 @@ class ImagePage extends Article {
                                                $label = $this->getContext()->msg( 'imgmultipagenext' )->text();
                                                $link = Linker::linkKnown(
                                                        $this->getTitle(),
-                                                       $label,
+                                                       htmlspecialchars( $label ),
                                                        [],
                                                        [ 'page' => $page + 1 ]
                                                );
@@ -1015,11 +1015,8 @@ EOT
         * @return int Result of string comparison, or namespace comparison
         */
        protected function compare( $a, $b ) {
-               if ( $a->page_namespace == $b->page_namespace ) {
-                       return strcmp( $a->page_title, $b->page_title );
-               } else {
-                       return $a->page_namespace - $b->page_namespace;
-               }
+               return $a->page_namespace <=> $b->page_namespace
+                       ?: strcmp( $a->page_title, $b->page_title );
        }
 
        /**
@@ -1045,9 +1042,8 @@ EOT
                        $option = 0;
                }
 
-               return isset( $wgImageLimits[$option] )
-                       ? $wgImageLimits[$option]
-                       : [ 800, 600 ]; // if nothing is set, fallback to a hardcoded default
+               // if nothing is set, fallback to a hardcoded default
+               return $wgImageLimits[$option] ?? [ 800, 600 ];
        }
 
        /**
index 8b42020..dfc7c02 100644 (file)
  */
 
 use MediaWiki\MediaWikiServices;
-use Wikimedia\Rdbms\ResultWrapper;
+use MediaWiki\Storage\RevisionRecord;
+use MediaWiki\Storage\RevisionStore;
+use MediaWiki\Storage\SqlBlobStore;
+use Wikimedia\Assert\Assert;
+use Wikimedia\Rdbms\IResultWrapper;
 use Wikimedia\Rdbms\IDatabase;
 
 /**
@@ -50,6 +54,17 @@ class PageArchive {
                $this->config = $config;
        }
 
+       /**
+        * @return RevisionStore
+        */
+       private function getRevisionStore() {
+               // TODO: Refactor: delete()/undelete() should live in a PageStore service;
+               //       Methods in PageArchive and RevisionStore that deal with archive revisions
+               //       should move into an ArchiveStore service (but could still be implemented
+               //       together with RevisionStore).
+               return MediaWikiServices::getInstance()->getRevisionStore();
+       }
+
        public function doesWrites() {
                return true;
        }
@@ -59,9 +74,13 @@ class PageArchive {
         * wrapper with (ar_namespace, ar_title, count) fields, ordered by page
         * namespace/title.
         *
-        * @return ResultWrapper
+        * @deprecated since 1.32.
+        *
+        * @return IResultWrapper
         */
        public static function listAllPages() {
+               wfDeprecated( __METHOD__, '1.32' );
+
                $dbr = wfGetDB( DB_REPLICA );
 
                return self::listPages( $dbr, '' );
@@ -73,7 +92,7 @@ class PageArchive {
         * Returns result wrapper with (ar_namespace, ar_title, count) fields.
         *
         * @param string $term Search term
-        * @return ResultWrapper
+        * @return IResultWrapper
         */
        public static function listPagesBySearch( $term ) {
                $title = Title::newFromText( $term );
@@ -123,7 +142,7 @@ class PageArchive {
         * Returns result wrapper with (ar_namespace, ar_title, count) fields.
         *
         * @param string $prefix Title prefix
-        * @return ResultWrapper
+        * @return IResultWrapper
         */
        public static function listPagesByPrefix( $prefix ) {
                $dbr = wfGetDB( DB_REPLICA );
@@ -149,7 +168,7 @@ class PageArchive {
        /**
         * @param IDatabase $dbr
         * @param string|array $condition
-        * @return bool|ResultWrapper
+        * @return bool|IResultWrapper
         */
        protected static function listPages( $dbr, $condition ) {
                return $dbr->select(
@@ -173,17 +192,21 @@ class PageArchive {
         * List the revisions of the given page. Returns result wrapper with
         * various archive table fields.
         *
-        * @return ResultWrapper
+        * @return IResultWrapper
         */
        public function listRevisions() {
-               $revisionStore = MediaWikiServices::getInstance()->getRevisionStore();
+               $revisionStore = $this->getRevisionStore();
                $queryInfo = $revisionStore->getArchiveQueryInfo();
 
                $conds = [
                        'ar_namespace' => $this->title->getNamespace(),
                        'ar_title' => $this->title->getDBkey(),
                ];
-               $options = [ 'ORDER BY' => 'ar_timestamp DESC' ];
+
+               // NOTE: ordering by ar_timestamp and ar_id, to remove ambiguity.
+               // XXX: Ideally, we would be ordering by ar_timestamp and ar_rev_id, but since we
+               // don't have an index on ar_rev_id, that causes a file sort.
+               $options = [ 'ORDER BY' => 'ar_timestamp DESC, ar_id DESC' ];
 
                ChangeTags::modifyDisplayQuery(
                        $queryInfo['tables'],
@@ -210,7 +233,7 @@ class PageArchive {
         * Returns a result wrapper with various filearchive fields, or null
         * if not a file page.
         *
-        * @return ResultWrapper
+        * @return IResultWrapper
         * @todo Does this belong in Image for fuller encapsulation?
         */
        public function listFiles() {
@@ -232,30 +255,60 @@ class PageArchive {
 
        /**
         * Return a Revision object containing data for the deleted revision.
-        * Note that the result *may* or *may not* have a null page ID.
+        *
+        * @deprecated since 1.32, use getArchivedRevision() instead.
         *
         * @param string $timestamp
         * @return Revision|null
         */
        public function getRevision( $timestamp ) {
                $dbr = wfGetDB( DB_REPLICA );
-               $arQuery = Revision::getArchiveQueryInfo();
+               $rec = $this->getRevisionByConditions(
+                       [ 'ar_timestamp' => $dbr->timestamp( $timestamp ) ]
+               );
+               return $rec ? new Revision( $rec ) : null;
+       }
+
+       /**
+        * Return the archived revision with the given ID.
+        *
+        * @param int $revId
+        * @return Revision|null
+        */
+       public function getArchivedRevision( $revId ) {
+               // Protect against code switching from getRevision() passing in a timestamp.
+               Assert::parameterType( 'integer', $revId, '$revId' );
+
+               $rec = $this->getRevisionByConditions( [ 'ar_rev_id' => $revId ] );
+               return $rec ? new Revision( $rec ) : null;
+       }
+
+       /**
+        * @param array $conditions
+        * @param array $options
+        *
+        * @return RevisionRecord|null
+        */
+       private function getRevisionByConditions( array $conditions, array $options = [] ) {
+               $dbr = wfGetDB( DB_REPLICA );
+               $arQuery = $this->getRevisionStore()->getArchiveQueryInfo();
+
+               $conditions = $conditions + [
+                       'ar_namespace' => $this->title->getNamespace(),
+                       'ar_title' => $this->title->getDBkey(),
+               ];
 
                $row = $dbr->selectRow(
                        $arQuery['tables'],
                        $arQuery['fields'],
-                       [
-                               'ar_namespace' => $this->title->getNamespace(),
-                               'ar_title' => $this->title->getDBkey(),
-                               'ar_timestamp' => $dbr->timestamp( $timestamp )
-                       ],
+                       $conditions,
                        __METHOD__,
-                       [],
+                       $options,
                        $arQuery['joins']
                );
 
                if ( $row ) {
-                       return Revision::newFromArchiveRow( $row, [ 'title' => $this->title ] );
+                       return $this->getRevisionStore()->newRevisionFromArchiveRow( $row, 0, $this->title );
                }
 
                return null;
@@ -276,7 +329,7 @@ class PageArchive {
 
                // Check the previous deleted revision...
                $row = $dbr->selectRow( 'archive',
-                       'ar_timestamp',
+                       [ 'ar_rev_id', 'ar_timestamp' ],
                        [ 'ar_namespace' => $this->title->getNamespace(),
                                'ar_title' => $this->title->getDBkey(),
                                'ar_timestamp < ' .
@@ -286,6 +339,7 @@ class PageArchive {
                                'ORDER BY' => 'ar_timestamp DESC',
                                'LIMIT' => 1 ] );
                $prevDeleted = $row ? wfTimestamp( TS_MW, $row->ar_timestamp ) : false;
+               $prevDeletedId = $row ? intval( $row->ar_rev_id ) : null;
 
                $row = $dbr->selectRow( [ 'page', 'revision' ],
                        [ 'rev_id', 'rev_timestamp' ],
@@ -304,31 +358,40 @@ class PageArchive {
 
                if ( $prevLive && $prevLive > $prevDeleted ) {
                        // Most prior revision was live
-                       return Revision::newFromId( $prevLiveId );
+                       $rec = $this->getRevisionStore()->getRevisionById( $prevLiveId );
+                       $rec = $rec ? new Revision( $rec ) : null;
                } elseif ( $prevDeleted ) {
                        // Most prior revision was deleted
-                       return $this->getRevision( $prevDeleted );
+                       $rec = $this->getArchivedRevision( $prevDeletedId );
+               } else {
+                       $rec = null;
                }
 
-               // No prior revision on this page.
-               return null;
+               return $rec;
        }
 
        /**
-        * Get the text from an archive row containing ar_text_id
+        * Get the text from an archive row containing ar_text_id.
+        *
+        * @deprecated since 1.32. In the MCR schema, ar_text_id no longer exists.
+        * Calling code should switch to getArchiveRevision().
+        *
+        * @todo remove in 1.33
         *
-        * @deprecated since 1.31
         * @param object $row Database row
         * @return string
         */
        public function getTextFromRow( $row ) {
-               $dbr = wfGetDB( DB_REPLICA );
-               $text = $dbr->selectRow( 'text',
-                       [ 'old_text', 'old_flags' ],
-                       [ 'old_id' => $row->ar_text_id ],
-                       __METHOD__ );
+               wfDeprecated( __METHOD__, '1.32' );
+
+               if ( empty( $row->ar_text_id ) ) {
+                       throw new InvalidArgumentException( '$row->ar_text_id must be set and not empty!' );
+               }
+
+               $address = SqlBlobStore::makeAddressFromTextId( $row->ar_text_id );
+               $blobStore = MediaWikiServices::getInstance()->getBlobStore();
 
-               return Revision::getRevisionText( $text );
+               return $blobStore->getBlob( $address );
        }
 
        /**
@@ -337,41 +400,65 @@ class PageArchive {
         *
         * If there are no archived revisions for the page, returns NULL.
         *
+        * @note this bypasses any audience checks.
+        *
+        * @deprecated since 1.32. For compatibility with the MCR schema,
+        * calling code should switch to getLastRevisionId() and getArchiveRevision().
+        *
+        * @todo remove in 1.33
+        *
         * @return string|null
         */
        public function getLastRevisionText() {
+               wfDeprecated( __METHOD__, '1.32' );
+
+               $revId = $this->getLastRevisionId();
+
+               if ( $revId ) {
+                       $rev = $this->getArchivedRevision( $revId );
+                       $content = $rev->getContent( RevisionRecord::RAW );
+                       return $content->serialize();
+               }
+
+               return null;
+       }
+
+       /**
+        * Returns the ID of the latest deleted revision.
+        *
+        * @return int|false The revision's ID, or false if there is no deleted revision.
+        */
+       public function getLastRevisionId() {
                $dbr = wfGetDB( DB_REPLICA );
-               $row = $dbr->selectRow(
-                       [ 'archive', 'text' ],
-                       [ 'old_text', 'old_flags' ],
+               $revId = $dbr->selectField(
+                       'archive',
+                       'ar_rev_id',
                        [ 'ar_namespace' => $this->title->getNamespace(),
                                'ar_title' => $this->title->getDBkey() ],
                        __METHOD__,
-                       [ 'ORDER BY' => 'ar_timestamp DESC, ar_id DESC' ],
-                       [ 'text' => [ 'JOIN', 'old_id = ar_text_id' ] ]
+                       [ 'ORDER BY' => 'ar_timestamp DESC, ar_id DESC' ]
                );
 
-               if ( $row ) {
-                       return Revision::getRevisionText( $row );
-               }
-
-               return null;
+               return $revId ? intval( $revId ) : false;
        }
 
        /**
         * Quick check if any archived revisions are present for the page.
+        * This says nothing about whether the page currently exists in the page table or not.
         *
         * @return bool
         */
        public function isDeleted() {
                $dbr = wfGetDB( DB_REPLICA );
-               $n = $dbr->selectField( 'archive', 'COUNT(ar_title)',
+               $row = $dbr->selectRow(
+                       [ 'archive' ],
+                       '1', // We don't care about the value. Allow the database to optimize.
                        [ 'ar_namespace' => $this->title->getNamespace(),
                                'ar_title' => $this->title->getDBkey() ],
                        __METHOD__
                );
 
-               return ( $n > 0 );
+               return (bool)$row;
        }
 
        /**
@@ -387,8 +474,8 @@ class PageArchive {
         * @param string $comment
         * @param array $fileVersions
         * @param bool $unsuppress
-        * @param User $user User performing the action, or null to use $wgUser
-        * @param string|string[] $tags Change tags to add to log entry
+        * @param User|null $user User performing the action, or null to use $wgUser
+        * @param string|string[]|null $tags Change tags to add to log entry
         *   ($user should be able to add the specified tags before this is called)
         * @return array|bool array(number of file revisions restored, number of image revisions
         *   restored, log message) on success, false on failure.
@@ -527,7 +614,7 @@ class PageArchive {
                        $oldWhere['ar_timestamp'] = array_map( [ &$dbw, 'timestamp' ], $timestamps );
                }
 
-               $revisionStore = MediaWikiServices::getInstance()->getRevisionStore();
+               $revisionStore = $this->getRevisionStore();
                $queryInfo = $revisionStore->getArchiveQueryInfo();
                $queryInfo['tables'][] = 'revision';
                $queryInfo['fields'][] = 'rev_id';
@@ -600,27 +687,35 @@ class PageArchive {
                if ( $latestRestorableRow !== null ) {
                        $oldPageId = (int)$latestRestorableRow->ar_page_id; // pass this to ArticleUndelete hook
 
-                       // grab the content to check consistency with global state before restoring the page.
-                       $revision = Revision::newFromArchiveRow( $latestRestorableRow,
-                               [
-                                       'title' => $article->getTitle(), // used to derive default content model
-                               ]
+                       // Grab the content to check consistency with global state before restoring the page.
+                       // XXX: The only current use case is Wikibase, which tries to enforce uniqueness of
+                       // certain things across all pages. There may be a better way to do that.
+                       $revision = $revisionStore->newRevisionFromArchiveRow(
+                               $latestRestorableRow,
+                               0,
+                               $this->title
                        );
-                       $user = User::newFromName( $revision->getUserText( Revision::RAW ), false );
-                       $content = $revision->getContent( Revision::RAW );
 
-                       // NOTE: article ID may not be known yet. prepareSave() should not modify the database.
-                       $status = $content->prepareSave( $article, 0, -1, $user );
-                       if ( !$status->isOK() ) {
-                               $dbw->endAtomic( __METHOD__ );
+                       // TODO: use User::newFromUserIdentity from If610c68f4912e
+                       // TODO: The User isn't used for anything in prepareSave()! We should drop it.
+                       $user = User::newFromName( $revision->getUser( RevisionRecord::RAW )->getName(), false );
 
-                               return $status;
+                       foreach ( $revision->getSlotRoles() as $role ) {
+                               $content = $revision->getContent( $role, RevisionRecord::RAW );
+
+                               // NOTE: article ID may not be known yet. prepareSave() should not modify the database.
+                               $status = $content->prepareSave( $article, 0, -1, $user );
+                               if ( !$status->isOK() ) {
+                                       $dbw->endAtomic( __METHOD__ );
+
+                                       return $status;
+                               }
                        }
                }
 
                $newid = false; // newly created page ID
                $restored = 0; // number of revisions restored
-               /** @var Revision $revision */
+               /** @var RevisionRecord|null $revision */
                $revision = null;
                $restoredPages = [];
                // If there are no restorable revisions, we can skip most of the steps.
@@ -630,7 +725,7 @@ class PageArchive {
                        if ( $makepage ) {
                                // Check the state of the newest to-be version...
                                if ( !$unsuppress
-                                       && ( $latestRestorableRow->ar_deleted & Revision::DELETED_TEXT )
+                                       && ( $latestRestorableRow->ar_deleted & RevisionRecord::DELETED_TEXT )
                                ) {
                                        $dbw->endAtomic( __METHOD__ );
 
@@ -648,7 +743,7 @@ class PageArchive {
                                if ( $latestRestorableRow->ar_timestamp > $previousTimestamp ) {
                                        // Check the state of the newest to-be version...
                                        if ( !$unsuppress
-                                               && ( $latestRestorableRow->ar_deleted & Revision::DELETED_TEXT )
+                                               && ( $latestRestorableRow->ar_deleted & RevisionRecord::DELETED_TEXT )
                                        ) {
                                                $dbw->endAtomic( __METHOD__ );
 
@@ -667,20 +762,24 @@ class PageArchive {
                                }
                                // Insert one revision at a time...maintaining deletion status
                                // unless we are specifically removing all restrictions...
-                               $revision = Revision::newFromArchiveRow( $row,
+                               $revision = $revisionStore->newRevisionFromArchiveRow(
+                                       $row,
+                                       0,
+                                       $this->title,
                                        [
-                                               'page' => $pageId,
-                                               'title' => $this->title,
+                                               'page_id' => $pageId,
                                                'deleted' => $unsuppress ? 0 : $row->ar_deleted
-                                       ] );
+                                       ]
+                               );
 
                                // This will also copy the revision to ip_changes if it was an IP edit.
-                               $revision->insertOn( $dbw );
+                               $revisionStore->insertRevisionOn( $revision, $dbw );
 
                                $restored++;
 
+                               $legacyRevision = new Revision( $revision );
                                Hooks::run( 'ArticleRevisionUndeleted',
-                                       [ &$this->title, $revision, $row->ar_page_id ] );
+                                       [ &$this->title, $legacyRevision, $row->ar_page_id ] );
                                $restoredPages[$row->ar_page_id] = true;
                        }
 
@@ -708,12 +807,14 @@ class PageArchive {
                if ( $restored ) {
                        $created = (bool)$newid;
                        // Attach the latest revision to the page...
-                       $wasnew = $article->updateIfNewerOn( $dbw, $revision );
+                       // XXX: updateRevisionOn should probably move into a PageStore service.
+                       $wasnew = $article->updateIfNewerOn( $dbw, $legacyRevision );
                        if ( $created || $wasnew ) {
                                // Update site stats, link tables, etc
+                               // TODO: use DerivedPageDataUpdater from If610c68f4912e!
                                $article->doEditUpdates(
-                                       $revision,
-                                       User::newFromName( $revision->getUserText( Revision::RAW ), false ),
+                                       $legacyRevision,
+                                       User::newFromName( $revision->getUser( RevisionRecord::RAW )->getName(), false ),
                                        [
                                                'created' => $created,
                                                'oldcountable' => $oldcountable,
index cbce884..a1b2e57 100644 (file)
 use MediaWiki\Edit\PreparedEdit;
 use MediaWiki\Logger\LoggerFactory;
 use MediaWiki\MediaWikiServices;
+use MediaWiki\Storage\DerivedPageDataUpdater;
+use MediaWiki\Storage\PageUpdater;
+use MediaWiki\Storage\RevisionRecord;
+use MediaWiki\Storage\RevisionSlotsUpdate;
+use MediaWiki\Storage\RevisionStore;
 use Wikimedia\Assert\Assert;
 use Wikimedia\Rdbms\FakeResultWrapper;
 use Wikimedia\Rdbms\IDatabase;
-use Wikimedia\Rdbms\DBUnexpectedError;
+use Wikimedia\Rdbms\LoadBalancer;
 
 /**
  * Class representing a MediaWiki article and history.
@@ -88,6 +93,11 @@ class WikiPage implements Page, IDBAccessObject {
         */
        protected $mLinksUpdated = '19700101000000';
 
+       /**
+        * @var DerivedPageDataUpdater|null
+        */
+       private $derivedDataUpdater = null;
+
        /**
         * Constructor and clear the article
         * @param Title $title Reference to a Title object.
@@ -192,7 +202,7 @@ class WikiPage implements Page, IDBAccessObject {
         * @param object|string|int $type
         * @return mixed
         */
-       private static function convertSelectType( $type ) {
+       protected static function convertSelectType( $type ) {
                switch ( $type ) {
                        case 'fromdb':
                                return self::READ_NORMAL;
@@ -206,6 +216,27 @@ class WikiPage implements Page, IDBAccessObject {
                }
        }
 
+       /**
+        * @return RevisionStore
+        */
+       private function getRevisionStore() {
+               return MediaWikiServices::getInstance()->getRevisionStore();
+       }
+
+       /**
+        * @return ParserCache
+        */
+       private function getParserCache() {
+               return MediaWikiServices::getInstance()->getParserCache();
+       }
+
+       /**
+        * @return LoadBalancer
+        */
+       private function getDBLoadBalancer() {
+               return MediaWikiServices::getInstance()->getDBLoadBalancer();
+       }
+
        /**
         * @todo Move this UI stuff somewhere else
         *
@@ -261,8 +292,8 @@ class WikiPage implements Page, IDBAccessObject {
                $this->mTimestamp = '';
                $this->mIsRedirect = false;
                $this->mLatest = false;
-               // T59026: do not clear mPreparedEdit since prepareTextForEdit() already checks
-               // the requested rev ID and content against the cached one for equality. For most
+               // T59026: do not clear $this->derivedDataUpdater since getDerivedDataUpdater() already
+               // checks the requested rev ID and content against the cached one. For most
                // content types, the output should not change during the lifetime of this cache.
                // Clearing it can cause extra parses on edit for no reason.
        }
@@ -433,7 +464,7 @@ class WikiPage implements Page, IDBAccessObject {
 
                if ( is_int( $from ) ) {
                        list( $index, $opts ) = DBAccessObjectUtils::getDBOptions( $from );
-                       $loadBalancer = MediaWikiServices::getInstance()->getDBLoadBalancer();
+                       $loadBalancer = $this->getDBLoadBalancer();
                        $db = $loadBalancer->getConnection( $index );
                        $data = $this->pageDataFromTitle( $db, $this->mTitle, $opts );
 
@@ -456,6 +487,34 @@ class WikiPage implements Page, IDBAccessObject {
                $this->loadFromRow( $data, $from );
        }
 
+       /**
+        * Checks whether the page data was loaded using the given database access mode (or better).
+        *
+        * @since 1.32
+        *
+        * @param string|int $from One of the following:
+        *   - "fromdb" or WikiPage::READ_NORMAL to get from a replica DB.
+        *   - "fromdbmaster" or WikiPage::READ_LATEST to get from the master DB.
+        *   - "forupdate"  or WikiPage::READ_LOCKING to get from the master DB
+        *     using SELECT FOR UPDATE.
+        *
+        * @return bool
+        */
+       public function wasLoadedFrom( $from ) {
+               $from = self::convertSelectType( $from );
+
+               if ( !is_int( $from ) ) {
+                       // No idea from where the caller got this data, assume replica DB.
+                       $from = self::READ_NORMAL;
+               }
+
+               if ( is_int( $from ) && $from <= $this->mDataLoadedFrom ) {
+                       return true;
+               }
+
+               return false;
+       }
+
        /**
         * Load the object from a database row
         *
@@ -468,7 +527,7 @@ class WikiPage implements Page, IDBAccessObject {
         *          the master DB using SELECT FOR UPDATE
         */
        public function loadFromRow( $data, $from ) {
-               $lc = LinkCache::singleton();
+               $lc = MediaWikiServices::getInstance()->getLinkCache();
                $lc->clearLink( $this->mTitle );
 
                if ( $data ) {
@@ -709,7 +768,7 @@ class WikiPage implements Page, IDBAccessObject {
         *   Revision::FOR_PUBLIC       to be displayed to all users
         *   Revision::FOR_THIS_USER    to be displayed to $wgUser
         *   Revision::RAW              get the text regardless of permissions
-        * @param User $user User object to check for, only if FOR_THIS_USER is passed
+        * @param User|null $user User object to check for, only if FOR_THIS_USER is passed
         *   to the $audience parameter
         * @return Content|null The content of the current revision
         *
@@ -749,7 +808,7 @@ class WikiPage implements Page, IDBAccessObject {
         *   Revision::FOR_PUBLIC       to be displayed to all users
         *   Revision::FOR_THIS_USER    to be displayed to the given user
         *   Revision::RAW              get the text regardless of permissions
-        * @param User $user User object to check for, only if FOR_THIS_USER is passed
+        * @param User|null $user User object to check for, only if FOR_THIS_USER is passed
         *   to the $audience parameter
         * @return int User ID for the user that made the last article revision
         */
@@ -768,7 +827,7 @@ class WikiPage implements Page, IDBAccessObject {
         *   Revision::FOR_PUBLIC       to be displayed to all users
         *   Revision::FOR_THIS_USER    to be displayed to the given user
         *   Revision::RAW              get the text regardless of permissions
-        * @param User $user User object to check for, only if FOR_THIS_USER is passed
+        * @param User|null $user User object to check for, only if FOR_THIS_USER is passed
         *   to the $audience parameter
         * @return User|null
         */
@@ -787,7 +846,7 @@ class WikiPage implements Page, IDBAccessObject {
         *   Revision::FOR_PUBLIC       to be displayed to all users
         *   Revision::FOR_THIS_USER    to be displayed to the given user
         *   Revision::RAW              get the text regardless of permissions
-        * @param User $user User object to check for, only if FOR_THIS_USER is passed
+        * @param User|null $user User object to check for, only if FOR_THIS_USER is passed
         *   to the $audience parameter
         * @return string Username of the user that made the last article revision
         */
@@ -805,7 +864,7 @@ class WikiPage implements Page, IDBAccessObject {
         *   Revision::FOR_PUBLIC       to be displayed to all users
         *   Revision::FOR_THIS_USER    to be displayed to the given user
         *   Revision::RAW              get the text regardless of permissions
-        * @param User $user User object to check for, only if FOR_THIS_USER is passed
+        * @param User|null $user User object to check for, only if FOR_THIS_USER is passed
         *   to the $audience parameter
         * @return string Comment stored for the last article revision
         */
@@ -843,11 +902,14 @@ class WikiPage implements Page, IDBAccessObject {
        public function isCountable( $editInfo = false ) {
                global $wgArticleCountMethod;
 
+               // NOTE: Keep in sync with DerivedPageDataUpdater::isCountable.
+
                if ( !$this->mTitle->isContentPage() ) {
                        return false;
                }
 
                if ( $editInfo ) {
+                       // NOTE: only the main slot can make a page a redirect
                        $content = $editInfo->pstContent;
                } else {
                        $content = $this->getContent();
@@ -1031,7 +1093,7 @@ class WikiPage implements Page, IDBAccessObject {
         * @return UserArrayFromResult
         */
        public function getContributors() {
-               // @todo FIXME: This is expensive; cache this info somewhere.
+               // @todo: This is expensive; cache this info somewhere.
 
                $dbr = wfGetDB( DB_REPLICA );
 
@@ -1119,7 +1181,7 @@ class WikiPage implements Page, IDBAccessObject {
                }
 
                if ( $useParserCache ) {
-                       $parserOutput = MediaWikiServices::getInstance()->getParserCache()
+                       $parserOutput = $this->getParserCache()
                                ->get( $this, $parserOptions );
                        if ( $parserOutput !== false ) {
                                return $parserOutput;
@@ -1197,6 +1259,8 @@ class WikiPage implements Page, IDBAccessObject {
         * or else the record will be left in a funky state.
         * Best if all done inside a transaction.
         *
+        * @todo Factor out into a PageStore service, to be used by PageUpdater.
+        *
         * @param IDatabase $dbw
         * @param int|null $pageId Custom page ID that will be used for the insert statement
         *
@@ -1237,13 +1301,15 @@ class WikiPage implements Page, IDBAccessObject {
        /**
         * Update the page record to point to a newly saved revision.
         *
+        * @todo Factor out into a PageStore service, or move into PageUpdater.
+        *
         * @param IDatabase $dbw
         * @param Revision $revision For ID number, and text used to set
         *   length and redirect status fields
-        * @param int $lastRevision If given, will not overwrite the page field
+        * @param int|null $lastRevision If given, will not overwrite the page field
         *   when different from the currently set value.
         *   Giving 0 indicates the new page flag should be set on.
-        * @param bool $lastRevIsRedirect If given, will optimize adding and
+        * @param bool|null $lastRevIsRedirect If given, will optimize adding and
         *   removing rows in redirect table.
         * @return bool Success; false if the page row was missing or page_latest changed
         */
@@ -1252,6 +1318,10 @@ class WikiPage implements Page, IDBAccessObject {
        ) {
                global $wgContentHandlerUseDB;
 
+               // TODO: move into PageUpdater or PageStore
+               // NOTE: when doing that, make sure cached fields get reset in doEditContent,
+               // and in the compat stub!
+
                // Assertion to try to catch T92046
                if ( (int)$revision->getId() === 0 ) {
                        throw new InvalidArgumentException(
@@ -1297,7 +1367,8 @@ class WikiPage implements Page, IDBAccessObject {
                        $this->mLatest = $revision->getId();
                        $this->mIsRedirect = (bool)$rt;
                        // Update the LinkCache.
-                       LinkCache::singleton()->addGoodLinkObj(
+                       $linkCache = MediaWikiServices::getInstance()->getLinkCache();
+                       $linkCache->addGoodLinkObj(
                                $this->getId(),
                                $this->mTitle,
                                $len,
@@ -1382,17 +1453,45 @@ class WikiPage implements Page, IDBAccessObject {
                return $ret;
        }
 
+       /**
+        * Helper method for checking whether two revisions have differences that go
+        * beyond the main slot.
+        *
+        * MCR migration note: this method should go away!
+        *
+        * @deprecated Use only as a stop-gap before refactoring to support MCR.
+        *
+        * @param Revision $a
+        * @param Revision $b
+        * @return bool
+        */
+       public static function hasDifferencesOutsideMainSlot( Revision $a, Revision $b ) {
+               $aSlots = $a->getRevisionRecord()->getSlots();
+               $bSlots = $b->getRevisionRecord()->getSlots();
+               $changedRoles = $aSlots->getRolesWithDifferentContent( $bSlots );
+
+               return ( $changedRoles !== [ 'main' ] && $changedRoles !== [] );
+       }
+
        /**
         * Get the content that needs to be saved in order to undo all revisions
         * between $undo and $undoafter. Revisions must belong to the same page,
         * must exist and must not be deleted
+        *
         * @param Revision $undo
         * @param Revision $undoafter Must be an earlier revision than $undo
         * @return Content|bool Content on success, false on failure
         * @since 1.21
         * Before we had the Content object, this was done in getUndoText
         */
-       public function getUndoContent( Revision $undo, Revision $undoafter = null ) {
+       public function getUndoContent( Revision $undo, Revision $undoafter ) {
+               // TODO: MCR: replace this with a method that returns a RevisionSlotsUpdate
+
+               if ( self::hasDifferencesOutsideMainSlot( $undo, $undoafter ) ) {
+                       // Cannot yet undo edits that involve anything other the main slot.
+                       return false;
+               }
+
                $handler = $undo->getContentHandler();
                return $handler->getUndoContent( $this->getRevision(), $undo, $undoafter );
        }
@@ -1430,7 +1529,7 @@ class WikiPage implements Page, IDBAccessObject {
        ) {
                $baseRevId = null;
                if ( $edittime && $sectionId !== 'new' ) {
-                       $lb = MediaWikiServices::getInstance()->getDBLoadBalancer();
+                       $lb = $this->getDBLoadBalancer();
                        $dbr = $lb->getConnection( DB_REPLICA );
                        $rev = Revision::loadFromTimestamp( $dbr, $this->mTitle, $edittime );
                        // Try the master if this thread may have just added it.
@@ -1503,6 +1602,10 @@ class WikiPage implements Page, IDBAccessObject {
 
        /**
         * Check flags and add EDIT_NEW or EDIT_UPDATE to them as needed.
+        *
+        * @deprecated since 1.32, use exists() instead, or simply omit the EDIT_UPDATE
+        * and EDIT_NEW flags. To protect against race conditions, use PageUpdater::grabParentRevision.
+        *
         * @param int $flags
         * @return int Updated $flags
         */
@@ -1518,12 +1621,139 @@ class WikiPage implements Page, IDBAccessObject {
                return $flags;
        }
 
+       /**
+        * @return DerivedPageDataUpdater
+        */
+       private function newDerivedDataUpdater() {
+               global $wgContLang, $wgRCWatchCategoryMembership, $wgArticleCountMethod;
+
+               $derivedDataUpdater = new DerivedPageDataUpdater(
+                       $this, // NOTE: eventually, PageUpdater should not know about WikiPage
+                       $this->getRevisionStore(),
+                       $this->getParserCache(),
+                       JobQueueGroup::singleton(),
+                       MessageCache::singleton(),
+                       $wgContLang,
+                       LoggerFactory::getInstance( 'SaveParse' )
+               );
+
+               $derivedDataUpdater->setRcWatchCategoryMembership( $wgRCWatchCategoryMembership );
+               $derivedDataUpdater->setArticleCountMethod( $wgArticleCountMethod );
+
+               return $derivedDataUpdater;
+       }
+
+       /**
+        * Returns a DerivedPageDataUpdater for use with the given target revision or new content.
+        * This method attempts to re-use the same DerivedPageDataUpdater instance for subsequent calls.
+        * The parameters passed to this method are used to ensure that the DerivedPageDataUpdater
+        * returned matches that caller's expectations, allowing an existing instance to be re-used
+        * if the given parameters match that instance's internal state according to
+        * DerivedPageDataUpdater::isReusableFor(), and creating a new instance of the parameters do not
+        * match the existign one.
+        *
+        * If neither $forRevision nor $forUpdate is given, a new DerivedPageDataUpdater is always
+        * created, replacing any DerivedPageDataUpdater currently cached.
+        *
+        * MCR migration note: this replaces WikiPage::prepareContentForEdit.
+        *
+        * @since 1.32
+        *
+        * @param User|null $forUser The user that will be used for, or was used for, PST.
+        * @param RevisionRecord|null $forRevision The revision created by the edit for which
+        *        to perform updates, if the edit was already saved.
+        * @param RevisionSlotsUpdate|null $forUpdate The new content to be saved by the edit (pre PST),
+        *        if the edit was not yet saved.
+        * @param bool $forEdit Only re-use if the cached DerivedPageDataUpdater has the current
+        *       revision as the edit's parent revision. This ensures that the same
+        *       DerivedPageDataUpdater cannot be re-used for two consecutive edits.
+        *
+        * @return DerivedPageDataUpdater
+        */
+       private function getDerivedDataUpdater(
+               User $forUser = null,
+               RevisionRecord $forRevision = null,
+               RevisionSlotsUpdate $forUpdate = null,
+               $forEdit = false
+       ) {
+               if ( !$forRevision && !$forUpdate ) {
+                       // NOTE: can't re-use an existing derivedDataUpdater if we don't know what the caller is
+                       // going to use it with.
+                       $this->derivedDataUpdater = null;
+               }
+
+               if ( $this->derivedDataUpdater && !$this->derivedDataUpdater->isContentPrepared() ) {
+                       // NOTE: can't re-use an existing derivedDataUpdater if other code that has a reference
+                       // to it did not yet initialize it, because we don't know what data it will be
+                       // initialized with.
+                       $this->derivedDataUpdater = null;
+               }
+
+               // XXX: It would be nice to have an LRU cache instead of trying to re-use a single instance.
+               // However, there is no good way to construct a cache key. We'd need to check against all
+               // cached instances.
+
+               if ( $this->derivedDataUpdater
+                       && !$this->derivedDataUpdater->isReusableFor(
+                               $forUser,
+                               $forRevision,
+                               $forUpdate,
+                               $forEdit ? $this->getLatest() : null
+                       )
+               ) {
+                       $this->derivedDataUpdater = null;
+               }
+
+               if ( !$this->derivedDataUpdater ) {
+                       $this->derivedDataUpdater = $this->newDerivedDataUpdater();
+               }
+
+               return $this->derivedDataUpdater;
+       }
+
+       /**
+        * Returns a PageUpdater for creating new revisions on this page (or creating the page).
+        *
+        * The PageUpdater can also be used to detect the need for edit conflict resolution,
+        * and to protected such conflict resolution from concurrent edits using a check-and-set
+        * mechanism.
+        *
+        * @since 1.32
+        *
+        * @param User $user
+        * @param RevisionSlotsUpdate|null $forUpdate If given, allows any cached ParserOutput
+        *        that may already have been returned via getDerivedDataUpdater to be re-used.
+        *
+        * @return PageUpdater
+        */
+       public function newPageUpdater( User $user, RevisionSlotsUpdate $forUpdate = null ) {
+               global $wgAjaxEditStash, $wgUseAutomaticEditSummaries, $wgPageCreationLog;
+
+               $pageUpdater = new PageUpdater(
+                       $user,
+                       $this, // NOTE: eventually, PageUpdater should not know about WikiPage
+                       $this->getDerivedDataUpdater( $user, null, $forUpdate, true ),
+                       $this->getDBLoadBalancer(),
+                       $this->getRevisionStore()
+               );
+
+               $pageUpdater->setUsePageCreationLog( $wgPageCreationLog );
+               $pageUpdater->setAjaxEditStash( $wgAjaxEditStash );
+               $pageUpdater->setUseAutomaticEditSummaries( $wgUseAutomaticEditSummaries );
+
+               return $pageUpdater;
+       }
+
        /**
         * Change an existing article or create a new article. Updates RC and all necessary caches,
         * optionally via the deferred update array.
         *
+        * @deprecated since 1.32, use PageUpdater::saveRevision instead. Note that the new method
+        * expects callers to take care of checking EDIT_MINOR against the minoredit right, and to
+        * apply the autopatrol right as appropriate.
+        *
         * @param Content $content New content
-        * @param string $summary Edit summary
+        * @param string|CommentStoreComment $summary Edit summary
         * @param int $flags Bitfield:
         *      EDIT_NEW
         *          Article is known or assumed to be non-existent, create a new one
@@ -1547,12 +1777,12 @@ class WikiPage implements Page, IDBAccessObject {
         * error will be returned. These two conditions are also possible with
         * auto-detection due to MediaWiki's performance-optimised locking strategy.
         *
-        * @param bool|int $baseRevId The revision ID this edit was based off, if any.
-        *   This is not the parent revision ID, rather the revision ID for older
-        *   content used as the source for a rollback, for example.
-        * @param User $user The user doing the edit
-        * @param string $serialFormat Format for storing the content in the
-        *   database.
+        * @param bool|int $originalRevId: The ID of an original revision that the edit
+        * restores or repeats. The new revision is expected to have the exact same content as
+        * the given original revision. This is used with rollbacks and with dummy "null" revisions
+        * which are created to record things like page moves.
+        * @param User|null $user The user doing the edit
+        * @param string|null $serialFormat IGNORED.
         * @param array|null $tags Change tags to apply to this edit
         * Callers are responsible for permission checks
         * (with ChangeTags::canAddTagsAccompanyingChange)
@@ -1577,416 +1807,70 @@ class WikiPage implements Page, IDBAccessObject {
         * @throws MWException
         */
        public function doEditContent(
-               Content $content, $summary, $flags = 0, $baseRevId = false,
+               Content $content, $summary, $flags = 0, $originalRevId = false,
                User $user = null, $serialFormat = null, $tags = [], $undidRevId = 0
        ) {
-               global $wgUser, $wgUseAutomaticEditSummaries;
-
-               // Old default parameter for $tags was null
-               if ( $tags === null ) {
-                       $tags = [];
-               }
+               global $wgUser, $wgUseNPPatrol, $wgUseRCPatrol;
 
-               // Low-level sanity check
-               if ( $this->mTitle->getText() === '' ) {
-                       throw new MWException( 'Something is trying to edit an article with an empty title' );
-               }
-               // Make sure the given content type is allowed for this page
-               if ( !$content->getContentHandler()->canBeUsedOn( $this->mTitle ) ) {
-                       return Status::newFatal( 'content-not-allowed-here',
-                               ContentHandler::getLocalizedName( $content->getModel() ),
-                               $this->mTitle->getPrefixedText()
-                       );
+               if ( !( $summary instanceof CommentStoreComment ) ) {
+                       $summary = CommentStoreComment::newUnsavedComment( trim( $summary ) );
                }
 
-               // Load the data from the master database if needed.
-               // The caller may already loaded it from the master or even loaded it using
-               // SELECT FOR UPDATE, so do not override that using clear().
-               $this->loadPageData( 'fromdbmaster' );
-
-               $user = $user ?: $wgUser;
-               $flags = $this->checkFlags( $flags );
-
-               // Avoid PHP 7.1 warning of passing $this by reference
-               $wikiPage = $this;
-
-               // Trigger pre-save hook (using provided edit summary)
-               $hookStatus = Status::newGood( [] );
-               $hook_args = [ &$wikiPage, &$user, &$content, &$summary,
-                                                       $flags & EDIT_MINOR, null, null, &$flags, &$hookStatus ];
-               // Check if the hook rejected the attempted save
-               if ( !Hooks::run( 'PageContentSave', $hook_args ) ) {
-                       if ( $hookStatus->isOK() ) {
-                               // Hook returned false but didn't call fatal(); use generic message
-                               $hookStatus->fatal( 'edit-hook-aborted' );
-                       }
-
-                       return $hookStatus;
+               if ( !$user ) {
+                       $user = $wgUser;
                }
 
-               $old_revision = $this->getRevision(); // current revision
-               $old_content = $this->getContent( Revision::RAW ); // current revision's content
-
-               $handler = $content->getContentHandler();
-               $tag = $handler->getChangeTag( $old_content, $content, $flags );
-               // If there is no applicable tag, null is returned, so we need to check
-               if ( $tag ) {
-                       $tags[] = $tag;
+               // TODO: this check is here for backwards-compatibility with 1.31 behavior.
+               // Checking the minoredit right should be done in the same place the 'bot' right is
+               // checked for the EDIT_FORCE_BOT flag, which is currently in EditPage::attemptSave.
+               if ( ( $flags & EDIT_MINOR ) && !$user->isAllowed( 'minoredit' ) ) {
+                       $flags = ( $flags & ~EDIT_MINOR );
                }
 
-               // Check for undo tag
-               if ( $undidRevId !== 0 && in_array( 'mw-undo', ChangeTags::getSoftwareTags() ) ) {
-                       $tags[] = 'mw-undo';
-               }
+               $slotsUpdate = new RevisionSlotsUpdate();
+               $slotsUpdate->modifyContent( 'main', $content );
 
-               // Provide autosummaries if summary is not provided and autosummaries are enabled
-               if ( $wgUseAutomaticEditSummaries && ( $flags & EDIT_AUTOSUMMARY ) && $summary == '' ) {
-                       $summary = $handler->getAutosummary( $old_content, $content, $flags );
-               }
+               // NOTE: while doEditContent() executes, callbacks to getDerivedDataUpdater and
+               // prepareContentForEdit will generally use the DerivedPageDataUpdater that is also
+               // used by this PageUpdater. However, there is no guarantee for this.
+               $updater = $this->newPageUpdater( $user, $slotsUpdate );
+               $updater->setContent( 'main', $content );
+               $updater->setOriginalRevisionId( $originalRevId );
+               $updater->setUndidRevisionId( $undidRevId );
 
-               // Avoid statsd noise and wasted cycles check the edit stash (T136678)
-               if ( ( $flags & EDIT_INTERNAL ) || ( $flags & EDIT_FORCE_BOT ) ) {
-                       $useCache = false;
-               } else {
-                       $useCache = true;
-               }
-
-               // Get the pre-save transform content and final parser output
-               $editInfo = $this->prepareContentForEdit( $content, null, $user, $serialFormat, $useCache );
-               $pstContent = $editInfo->pstContent; // Content object
-               $meta = [
-                       'bot' => ( $flags & EDIT_FORCE_BOT ),
-                       'minor' => ( $flags & EDIT_MINOR ) && $user->isAllowed( 'minoredit' ),
-                       'serialized' => $pstContent->serialize( $serialFormat ),
-                       'serialFormat' => $serialFormat,
-                       'baseRevId' => $baseRevId,
-                       'oldRevision' => $old_revision,
-                       'oldContent' => $old_content,
-                       'oldId' => $this->getLatest(),
-                       'oldIsRedirect' => $this->isRedirect(),
-                       'oldCountable' => $this->isCountable(),
-                       'tags' => ( $tags !== null ) ? (array)$tags : [],
-                       'undidRevId' => $undidRevId
-               ];
+               $needsPatrol = $wgUseRCPatrol || ( $wgUseNPPatrol && !$this->exists() );
 
-               // Actually create the revision and create/update the page
-               if ( $flags & EDIT_UPDATE ) {
-                       $status = $this->doModify( $pstContent, $flags, $user, $summary, $meta );
-               } else {
-                       $status = $this->doCreate( $pstContent, $flags, $user, $summary, $meta );
+               // TODO: this logic should not be in the storage layer, it's here for compatibility
+               // with 1.31 behavior. Applying the 'autopatrol' right should be done in the same
+               // place the 'bot' right is handled, which is currently in EditPage::attemptSave.
+               if ( $needsPatrol && $this->getTitle()->userCan( 'autopatrol', $user ) ) {
+                       $updater->setRcPatrolStatus( RecentChange::PRC_AUTOPATROLLED );
                }
 
-               // Promote user to any groups they meet the criteria for
-               DeferredUpdates::addCallableUpdate( function () use ( $user ) {
-                       $user->addAutopromoteOnceGroups( 'onEdit' );
-                       $user->addAutopromoteOnceGroups( 'onView' ); // b/c
-               } );
-
-               return $status;
-       }
-
-       /**
-        * @param Content $content Pre-save transform content
-        * @param int $flags
-        * @param User $user
-        * @param string $summary
-        * @param array $meta
-        * @return Status
-        * @throws DBUnexpectedError
-        * @throws Exception
-        * @throws FatalError
-        * @throws MWException
-        */
-       private function doModify(
-               Content $content, $flags, User $user, $summary, array $meta
-       ) {
-               global $wgUseRCPatrol;
-
-               // Update article, but only if changed.
-               $status = Status::newGood( [ 'new' => false, 'revision' => null ] );
+               $updater->addTags( $tags );
 
-               // Convenience variables
-               $now = wfTimestampNow();
-               $oldid = $meta['oldId'];
-               /** @var Content|null $oldContent */
-               $oldContent = $meta['oldContent'];
-               $newsize = $content->getSize();
-
-               if ( !$oldid ) {
-                       // Article gone missing
-                       $status->fatal( 'edit-gone-missing' );
-
-                       return $status;
-               } elseif ( !$oldContent ) {
-                       // Sanity check for T39225
-                       throw new MWException( "Could not find text for current revision {$oldid}." );
-               }
-
-               $changed = !$content->equals( $oldContent );
-
-               $dbw = wfGetDB( DB_MASTER );
-
-               if ( $changed ) {
-                       // @TODO: pass content object?!
-                       $revision = new Revision( [
-                               'page'       => $this->getId(),
-                               'title'      => $this->mTitle, // for determining the default content model
-                               'comment'    => $summary,
-                               'minor_edit' => $meta['minor'],
-                               'text'       => $meta['serialized'],
-                               'len'        => $newsize,
-                               'parent_id'  => $oldid,
-                               'user'       => $user->getId(),
-                               'user_text'  => $user->getName(),
-                               'timestamp'  => $now,
-                               'content_model' => $content->getModel(),
-                               'content_format' => $meta['serialFormat'],
-                       ] );
-
-                       $prepStatus = $content->prepareSave( $this, $flags, $oldid, $user );
-                       $status->merge( $prepStatus );
-                       if ( !$status->isOK() ) {
-                               return $status;
-                       }
-
-                       $dbw->startAtomic( __METHOD__ );
-                       // Get the latest page_latest value while locking it.
-                       // Do a CAS style check to see if it's the same as when this method
-                       // started. If it changed then bail out before touching the DB.
-                       $latestNow = $this->lockAndGetLatest();
-                       if ( $latestNow != $oldid ) {
-                               $dbw->endAtomic( __METHOD__ );
-                               // Page updated or deleted in the mean time
-                               $status->fatal( 'edit-conflict' );
-
-                               return $status;
-                       }
-
-                       // At this point we are now comitted to returning an OK
-                       // status unless some DB query error or other exception comes up.
-                       // This way callers don't have to call rollback() if $status is bad
-                       // unless they actually try to catch exceptions (which is rare).
-
-                       // Save the revision text
-                       $revisionId = $revision->insertOn( $dbw );
-                       // Update page_latest and friends to reflect the new revision
-                       if ( !$this->updateRevisionOn( $dbw, $revision, null, $meta['oldIsRedirect'] ) ) {
-                               throw new MWException( "Failed to update page row to use new revision." );
-                       }
-
-                       $tags = $meta['tags'];
-                       Hooks::run( 'NewRevisionFromEditComplete',
-                               [ $this, $revision, $meta['baseRevId'], $user, &$tags ] );
-
-                       // Update recentchanges
-                       if ( !( $flags & EDIT_SUPPRESS_RC ) ) {
-                               // Mark as patrolled if the user can do so
-                               $autopatrolled = $wgUseRCPatrol && !count(
-                                               $this->mTitle->getUserPermissionsErrors( 'autopatrol', $user ) );
-                               // Add RC row to the DB
-                               RecentChange::notifyEdit(
-                                       $now,
-                                       $this->mTitle,
-                                       $revision->isMinor(),
-                                       $user,
-                                       $summary,
-                                       $oldid,
-                                       $this->getTimestamp(),
-                                       $meta['bot'],
-                                       '',
-                                       $oldContent ? $oldContent->getSize() : 0,
-                                       $newsize,
-                                       $revisionId,
-                                       $autopatrolled ? RecentChange::PRC_AUTOPATROLLED :
-                                               RecentChange::PRC_UNPATROLLED,
-                                       $tags
-                               );
-                       }
-
-                       $user->incEditCount();
-
-                       $dbw->endAtomic( __METHOD__ );
-                       $this->mTimestamp = $now;
-               } else {
-                       // T34948: revision ID must be set to page {{REVISIONID}} and
-                       // related variables correctly. Likewise for {{REVISIONUSER}} (T135261).
-                       // Since we don't insert a new revision into the database, the least
-                       // error-prone way is to reuse given old revision.
-                       $revision = $meta['oldRevision'];
-               }
-
-               if ( $changed ) {
-                       // Return the new revision to the caller
-                       $status->value['revision'] = $revision;
-               } else {
-                       $status->warning( 'edit-no-change' );
-                       // Update page_touched as updateRevisionOn() was not called.
-                       // Other cache updates are managed in onArticleEdit() via doEditUpdates().
-                       $this->mTitle->invalidateCache( $now );
-               }
-
-               // Do secondary updates once the main changes have been committed...
-               DeferredUpdates::addUpdate(
-                       new AtomicSectionUpdate(
-                               $dbw,
-                               __METHOD__,
-                               function () use (
-                                       $revision, &$user, $content, $summary, &$flags,
-                                       $changed, $meta, &$status
-                               ) {
-                                       // Update links tables, site stats, etc.
-                                       $this->doEditUpdates(
-                                               $revision,
-                                               $user,
-                                               [
-                                                       'changed' => $changed,
-                                                       'oldcountable' => $meta['oldCountable'],
-                                                       'oldrevision' => $meta['oldRevision']
-                                               ]
-                                       );
-                                       // Avoid PHP 7.1 warning of passing $this by reference
-                                       $wikiPage = $this;
-                                       // Trigger post-save hook
-                                       $params = [ &$wikiPage, &$user, $content, $summary, $flags & EDIT_MINOR,
-                                               null, null, &$flags, $revision, &$status, $meta['baseRevId'],
-                                               $meta['undidRevId'] ];
-                                       Hooks::run( 'PageContentSaveComplete', $params );
-                               }
-                       ),
-                       DeferredUpdates::PRESEND
+               $revRec = $updater->saveRevision(
+                       $summary,
+                       $flags
                );
 
-               return $status;
-       }
-
-       /**
-        * @param Content $content Pre-save transform content
-        * @param int $flags
-        * @param User $user
-        * @param string $summary
-        * @param array $meta
-        * @return Status
-        * @throws DBUnexpectedError
-        * @throws Exception
-        * @throws FatalError
-        * @throws MWException
-        */
-       private function doCreate(
-               Content $content, $flags, User $user, $summary, array $meta
-       ) {
-               global $wgUseRCPatrol, $wgUseNPPatrol;
-
-               $status = Status::newGood( [ 'new' => true, 'revision' => null ] );
-
-               $now = wfTimestampNow();
-               $newsize = $content->getSize();
-               $prepStatus = $content->prepareSave( $this, $flags, $meta['oldId'], $user );
-               $status->merge( $prepStatus );
-               if ( !$status->isOK() ) {
-                       return $status;
-               }
-
-               $dbw = wfGetDB( DB_MASTER );
-               $dbw->startAtomic( __METHOD__ );
-
-               // Add the page record unless one already exists for the title
-               $newid = $this->insertOn( $dbw );
-               if ( $newid === false ) {
-                       $dbw->endAtomic( __METHOD__ ); // nothing inserted
-                       $status->fatal( 'edit-already-exists' );
-
-                       return $status; // nothing done
-               }
-
-               // At this point we are now comitted to returning an OK
-               // status unless some DB query error or other exception comes up.
-               // This way callers don't have to call rollback() if $status is bad
-               // unless they actually try to catch exceptions (which is rare).
-
-               // @TODO: pass content object?!
-               $revision = new Revision( [
-                       'page'       => $newid,
-                       'title'      => $this->mTitle, // for determining the default content model
-                       'comment'    => $summary,
-                       'minor_edit' => $meta['minor'],
-                       'text'       => $meta['serialized'],
-                       'len'        => $newsize,
-                       'user'       => $user->getId(),
-                       'user_text'  => $user->getName(),
-                       'timestamp'  => $now,
-                       'content_model' => $content->getModel(),
-                       'content_format' => $meta['serialFormat'],
-               ] );
-
-               // Save the revision text...
-               $revisionId = $revision->insertOn( $dbw );
-               // Update the page record with revision data
-               if ( !$this->updateRevisionOn( $dbw, $revision, 0 ) ) {
-                       throw new MWException( "Failed to update page row to use new revision." );
+               // $revRec will be null if the edit failed, or if no new revision was created because
+               // the content did not change.
+               if ( $revRec ) {
+                       // update cached fields
+                       // TODO: this is currently redundant to what is done in updateRevisionOn.
+                       // But updateRevisionOn() should move into PageStore, and then this will be needed.
+                       $this->setLastEdit( new Revision( $revRec ) ); // TODO: use RevisionRecord
+                       $this->mLatest = $revRec->getId();
                }
 
-               Hooks::run( 'NewRevisionFromEditComplete', [ $this, $revision, false, $user ] );
-
-               // Update recentchanges
-               if ( !( $flags & EDIT_SUPPRESS_RC ) ) {
-                       // Mark as patrolled if the user can do so
-                       $patrolled = ( $wgUseRCPatrol || $wgUseNPPatrol ) &&
-                               !count( $this->mTitle->getUserPermissionsErrors( 'autopatrol', $user ) );
-                       // Add RC row to the DB
-                       RecentChange::notifyNew(
-                               $now,
-                               $this->mTitle,
-                               $revision->isMinor(),
-                               $user,
-                               $summary,
-                               $meta['bot'],
-                               '',
-                               $newsize,
-                               $revisionId,
-                               $patrolled,
-                               $meta['tags']
-                       );
-               }
-
-               $user->incEditCount();
-
-               $dbw->endAtomic( __METHOD__ );
-               $this->mTimestamp = $now;
-
-               // Return the new revision to the caller
-               $status->value['revision'] = $revision;
-
-               // Do secondary updates once the main changes have been committed...
-               DeferredUpdates::addUpdate(
-                       new AtomicSectionUpdate(
-                               $dbw,
-                               __METHOD__,
-                               function () use (
-                                       $revision, &$user, $content, $summary, &$flags, $meta, &$status
-                               ) {
-                                       // Update links, etc.
-                                       $this->doEditUpdates( $revision, $user, [ 'created' => true ] );
-                                       // Avoid PHP 7.1 warning of passing $this by reference
-                                       $wikiPage = $this;
-                                       // Trigger post-create hook
-                                       $params = [ &$wikiPage, &$user, $content, $summary,
-                                                               $flags & EDIT_MINOR, null, null, &$flags, $revision ];
-                                       Hooks::run( 'PageContentInsertComplete', $params );
-                                       // Trigger post-save hook
-                                       $params = array_merge( $params, [ &$status, $meta['baseRevId'], 0 ] );
-                                       Hooks::run( 'PageContentSaveComplete', $params );
-                               }
-                       ),
-                       DeferredUpdates::PRESEND
-               );
-
-               return $status;
+               return $updater->getStatus();
        }
 
        /**
         * Get parser options suitable for rendering the primary article wikitext
         *
-        * @see ContentHandler::makeParserOptions
+        * @see ParserOptions::newCanonical
         *
         * @param IContextSource|User|string $context One of the following:
         *        - IContextSource: Use the User and the Language of the provided
@@ -1998,7 +1882,7 @@ class WikiPage implements Page, IDBAccessObject {
         * @return ParserOptions
         */
        public function makeParserOptions( $context ) {
-               $options = $this->getContentHandler()->makeParserOptions( $context );
+               $options = ParserOptions::newCanonical( $context );
 
                if ( $this->getTitle()->isConversionTable() ) {
                        // @todo ConversionTable should become a separate content model, so
@@ -2012,14 +1896,17 @@ class WikiPage implements Page, IDBAccessObject {
        /**
         * Prepare content which is about to be saved.
         *
-        * Prior to 1.30, this returned a stdClass object with the same class
-        * members.
+        * Prior to 1.30, this returned a stdClass.
+        *
+        * @deprecated since 1.32, use getDerivedDataUpdater instead.
         *
         * @param Content $content
-        * @param Revision|int|null $revision Revision object. For backwards compatibility, a
-        *        revision ID is also accepted, but this is deprecated.
+        * @param Revision|RevisionRecord|int|null $revision Revision object.
+        *        For backwards compatibility, a revision ID is also accepted,
+        *        but this is deprecated.
+        *        Used with vary-revision or vary-revision-id.
         * @param User|null $user
-        * @param string|null $serialFormat
+        * @param string|null $serialFormat IGNORED
         * @param bool $useCache Check shared prepared edit cache
         *
         * @return PreparedEdit
@@ -2027,125 +1914,45 @@ class WikiPage implements Page, IDBAccessObject {
         * @since 1.21
         */
        public function prepareContentForEdit(
-               Content $content, $revision = null, User $user = null,
-               $serialFormat = null, $useCache = true
+               Content $content,
+               $revision = null,
+               User $user = null,
+               $serialFormat = null,
+               $useCache = true
        ) {
-               global $wgContLang, $wgUser, $wgAjaxEditStash;
+               global $wgUser;
 
-               if ( is_object( $revision ) ) {
-                       $revid = $revision->getId();
-               } else {
+               if ( !$user ) {
+                       $user = $wgUser;
+               }
+
+               if ( !is_object( $revision ) ) {
                        $revid = $revision;
                        // This code path is deprecated, and nothing is known to
                        // use it, so performance here shouldn't be a worry.
                        if ( $revid !== null ) {
                                wfDeprecated( __METHOD__ . ' with $revision = revision ID', '1.25' );
-                               $revision = Revision::newFromId( $revid, Revision::READ_LATEST );
+                               $store = $this->getRevisionStore();
+                               $revision = $store->getRevisionById( $revid, Revision::READ_LATEST );
                        } else {
                                $revision = null;
                        }
+               } elseif ( $revision instanceof Revision ) {
+                       $revision = $revision->getRevisionRecord();
                }
 
-               $user = is_null( $user ) ? $wgUser : $user;
-               // XXX: check $user->getId() here???
-
-               // Use a sane default for $serialFormat, see T59026
-               if ( $serialFormat === null ) {
-                       $serialFormat = $content->getContentHandler()->getDefaultFormat();
-               }
+               $slots = RevisionSlotsUpdate::newFromContent( [ 'main' => $content ] );
+               $updater = $this->getDerivedDataUpdater( $user, $revision, $slots );
 
-               if ( $this->mPreparedEdit
-                       && isset( $this->mPreparedEdit->newContent )
-                       && $this->mPreparedEdit->newContent->equals( $content )
-                       && $this->mPreparedEdit->revid == $revid
-                       && $this->mPreparedEdit->format == $serialFormat
-                       // XXX: also check $user here?
-               ) {
-                       // Already prepared
-                       return $this->mPreparedEdit;
-               }
-
-               // The edit may have already been prepared via api.php?action=stashedit
-               $cachedEdit = $useCache && $wgAjaxEditStash
-                       ? ApiStashEdit::checkCache( $this->getTitle(), $content, $user )
-                       : false;
-
-               $popts = ParserOptions::newFromUserAndLang( $user, $wgContLang );
-               Hooks::run( 'ArticlePrepareTextForEdit', [ $this, $popts ] );
-
-               $edit = new PreparedEdit();
-               if ( $cachedEdit ) {
-                       $edit->timestamp = $cachedEdit->timestamp;
-               } else {
-                       $edit->timestamp = wfTimestampNow();
-               }
-               // @note: $cachedEdit is safely not used if the rev ID was referenced in the text
-               $edit->revid = $revid;
+               if ( !$updater->isUpdatePrepared() ) {
+                       $updater->prepareContent( $user, $slots, $useCache );
 
-               if ( $cachedEdit ) {
-                       $edit->pstContent = $cachedEdit->pstContent;
-               } else {
-                       $edit->pstContent = $content
-                               ? $content->preSaveTransform( $this->mTitle, $user, $popts )
-                               : null;
-               }
-
-               $edit->format = $serialFormat;
-               $edit->popts = $this->makeParserOptions( 'canonical' );
-               if ( $cachedEdit ) {
-                       $edit->output = $cachedEdit->output;
-               } else {
                        if ( $revision ) {
-                               // We get here if vary-revision is set. This means that this page references
-                               // itself (such as via self-transclusion). In this case, we need to make sure
-                               // that any such self-references refer to the newly-saved revision, and not
-                               // to the previous one, which could otherwise happen due to replica DB lag.
-                               $oldCallback = $edit->popts->getCurrentRevisionCallback();
-                               $edit->popts->setCurrentRevisionCallback(
-                                       function ( Title $title, $parser = false ) use ( $revision, &$oldCallback ) {
-                                               if ( $title->equals( $revision->getTitle() ) ) {
-                                                       return $revision;
-                                               } else {
-                                                       return call_user_func( $oldCallback, $title, $parser );
-                                               }
-                                       }
-                               );
-                       } else {
-                               // Try to avoid a second parse if {{REVISIONID}} is used
-                               $dbIndex = ( $this->mDataLoadedFrom & self::READ_LATEST ) === self::READ_LATEST
-                                       ? DB_MASTER // use the best possible guess
-                                       : DB_REPLICA; // T154554
-
-                               $edit->popts->setSpeculativeRevIdCallback( function () use ( $dbIndex ) {
-                                       $lb = MediaWikiServices::getInstance()->getDBLoadBalancer();
-                                       // Use a fresh connection in order to see the latest data, by avoiding
-                                       // stale data from REPEATABLE-READ snapshots.
-                                       $db = $lb->getConnectionRef( $dbIndex, [], false, $lb::CONN_TRX_AUTO );
-
-                                       return 1 + (int)$db->selectField(
-                                               'revision',
-                                               'MAX(rev_id)',
-                                               [],
-                                               __METHOD__
-                                       );
-                               } );
+                               $updater->prepareUpdate( $revision );
                        }
-                       $edit->output = $edit->pstContent
-                               ? $edit->pstContent->getParserOutput( $this->mTitle, $revid, $edit->popts )
-                               : null;
                }
 
-               $edit->newContent = $content;
-               $edit->oldContent = $this->getContent( Revision::RAW );
-
-               if ( $edit->output ) {
-                       $edit->output->setCacheTime( wfTimestampNow() );
-               }
-
-               // Process cache the result
-               $this->mPreparedEdit = $edit;
-
-               return $edit;
+               return $updater->getPreparedEdit();
        }
 
        /**
@@ -2154,6 +1961,8 @@ class WikiPage implements Page, IDBAccessObject {
         * Purges pages that include this page if the text was changed here.
         * Every 100th edit, prune the recent changes table.
         *
+        * @deprecated since 1.32, use PageUpdater::doEditUpdates instead.
+        *
         * @param Revision $revision
         * @param User $user User object that did the revision
         * @param array $options Array of options, following indexes are used:
@@ -2170,165 +1979,13 @@ class WikiPage implements Page, IDBAccessObject {
         *   - 'no-change': don't update the article count, ever
         */
        public function doEditUpdates( Revision $revision, User $user, array $options = [] ) {
-               global $wgRCWatchCategoryMembership;
-
-               $options += [
-                       'changed' => true,
-                       'created' => false,
-                       'moved' => false,
-                       'restored' => false,
-                       'oldrevision' => null,
-                       'oldcountable' => null
-               ];
-               $content = $revision->getContent();
-
-               $logger = LoggerFactory::getInstance( 'SaveParse' );
-
-               // See if the parser output before $revision was inserted is still valid
-               $editInfo = false;
-               if ( !$this->mPreparedEdit ) {
-                       $logger->debug( __METHOD__ . ": No prepared edit...\n" );
-               } elseif ( $this->mPreparedEdit->output->getFlag( 'vary-revision' ) ) {
-                       $logger->info( __METHOD__ . ": Prepared edit has vary-revision...\n" );
-               } elseif ( $this->mPreparedEdit->output->getFlag( 'vary-revision-id' )
-                       && $this->mPreparedEdit->output->getSpeculativeRevIdUsed() !== $revision->getId()
-               ) {
-                       $logger->info( __METHOD__ . ": Prepared edit has vary-revision-id with wrong ID...\n" );
-               } elseif ( $this->mPreparedEdit->output->getFlag( 'vary-user' ) && !$options['changed'] ) {
-                       $logger->info( __METHOD__ . ": Prepared edit has vary-user and is null...\n" );
-               } else {
-                       wfDebug( __METHOD__ . ": Using prepared edit...\n" );
-                       $editInfo = $this->mPreparedEdit;
-               }
-
-               if ( !$editInfo ) {
-                       // Parse the text again if needed. Be careful not to do pre-save transform twice:
-                       // $text is usually already pre-save transformed once. Avoid using the edit stash
-                       // as any prepared content from there or in doEditContent() was already rejected.
-                       $editInfo = $this->prepareContentForEdit( $content, $revision, $user, null, false );
-               }
-
-               // Save it to the parser cache.
-               // Make sure the cache time matches page_touched to avoid double parsing.
-               MediaWikiServices::getInstance()->getParserCache()->save(
-                       $editInfo->output, $this, $editInfo->popts,
-                       $revision->getTimestamp(), $editInfo->revid
-               );
-
-               // Update the links tables and other secondary data
-               if ( $content ) {
-                       $recursive = $options['changed']; // T52785
-                       $updates = $content->getSecondaryDataUpdates(
-                               $this->getTitle(), null, $recursive, $editInfo->output
-                       );
-                       foreach ( $updates as $update ) {
-                               $update->setCause( 'edit-page', $user->getName() );
-                               if ( $update instanceof LinksUpdate ) {
-                                       $update->setRevision( $revision );
-                                       $update->setTriggeringUser( $user );
-                               }
-                               DeferredUpdates::addUpdate( $update );
-                       }
-                       if ( $wgRCWatchCategoryMembership
-                               && $this->getContentHandler()->supportsCategories() === true
-                               && ( $options['changed'] || $options['created'] )
-                               && !$options['restored']
-                       ) {
-                               // Note: jobs are pushed after deferred updates, so the job should be able to see
-                               // the recent change entry (also done via deferred updates) and carry over any
-                               // bot/deletion/IP flags, ect.
-                               JobQueueGroup::singleton()->lazyPush( new CategoryMembershipChangeJob(
-                                       $this->getTitle(),
-                                       [
-                                               'pageId' => $this->getId(),
-                                               'revTimestamp' => $revision->getTimestamp()
-                                       ]
-                               ) );
-                       }
-               }
-
-               // Avoid PHP 7.1 warning of passing $this by reference
-               $wikiPage = $this;
-
-               Hooks::run( 'ArticleEditUpdates', [ &$wikiPage, &$editInfo, $options['changed'] ] );
-
-               if ( Hooks::run( 'ArticleEditUpdatesDeleteFromRecentchanges', [ &$wikiPage ] ) ) {
-                       // Flush old entries from the `recentchanges` table
-                       if ( mt_rand( 0, 9 ) == 0 ) {
-                               JobQueueGroup::singleton()->lazyPush( RecentChangesUpdateJob::newPurgeJob() );
-                       }
-               }
-
-               if ( !$this->exists() ) {
-                       return;
-               }
-
-               $id = $this->getId();
-               $title = $this->mTitle->getPrefixedDBkey();
-               $shortTitle = $this->mTitle->getDBkey();
-
-               if ( $options['oldcountable'] === 'no-change' ||
-                       ( !$options['changed'] && !$options['moved'] )
-               ) {
-                       $good = 0;
-               } elseif ( $options['created'] ) {
-                       $good = (int)$this->isCountable( $editInfo );
-               } elseif ( $options['oldcountable'] !== null ) {
-                       $good = (int)$this->isCountable( $editInfo ) - (int)$options['oldcountable'];
-               } else {
-                       $good = 0;
-               }
-               $edits = $options['changed'] ? 1 : 0;
-               $pages = $options['created'] ? 1 : 0;
-
-               DeferredUpdates::addUpdate( SiteStatsUpdate::factory(
-                       [ 'edits' => $edits, 'articles' => $good, 'pages' => $pages ]
-               ) );
-               DeferredUpdates::addUpdate( new SearchUpdate( $id, $title, $content ) );
-
-               // If this is another user's talk page, update newtalk.
-               // Don't do this if $options['changed'] = false (null-edits) nor if
-               // it's a minor edit and the user doesn't want notifications for those.
-               if ( $options['changed']
-                       && $this->mTitle->getNamespace() == NS_USER_TALK
-                       && $shortTitle != $user->getTitleKey()
-                       && !( $revision->isMinor() && $user->isAllowed( 'nominornewtalk' ) )
-               ) {
-                       $recipient = User::newFromName( $shortTitle, false );
-                       if ( !$recipient ) {
-                               wfDebug( __METHOD__ . ": invalid username\n" );
-                       } else {
-                               // Avoid PHP 7.1 warning of passing $this by reference
-                               $wikiPage = $this;
-
-                               // Allow extensions to prevent user notification
-                               // when a new message is added to their talk page
-                               if ( Hooks::run( 'ArticleEditUpdateNewTalk', [ &$wikiPage, $recipient ] ) ) {
-                                       if ( User::isIP( $shortTitle ) ) {
-                                               // An anonymous user
-                                               $recipient->setNewtalk( true, $revision );
-                                       } elseif ( $recipient->isLoggedIn() ) {
-                                               $recipient->setNewtalk( true, $revision );
-                                       } else {
-                                               wfDebug( __METHOD__ . ": don't need to notify a nonexistent user\n" );
-                                       }
-                               }
-                       }
-               }
+               $revision = $revision->getRevisionRecord();
 
-               if ( $this->mTitle->getNamespace() == NS_MEDIAWIKI ) {
-                       MessageCache::singleton()->updateMessageOverride( $this->mTitle, $content );
-               }
+               $updater = $this->getDerivedDataUpdater( $user, $revision );
 
-               if ( $options['created'] ) {
-                       self::onArticleCreate( $this->mTitle );
-               } elseif ( $options['changed'] ) { // T52785
-                       self::onArticleEdit( $this->mTitle, $revision );
-               }
+               $updater->prepareUpdate( $revision, $options );
 
-               ResourceLoaderWikiModule::invalidateModuleCache(
-                       $this->mTitle, $options['oldrevision'], $revision, wfWikiID()
-               );
+               $updater->doUpdates();
        }
 
        /**
@@ -2340,7 +1997,7 @@ class WikiPage implements Page, IDBAccessObject {
         * @param int &$cascade Set to false if cascading protection isn't allowed.
         * @param string $reason
         * @param User $user The user updating the restrictions
-        * @param string|string[] $tags Change tags to add to the pages and protection log entries
+        * @param string|string[]|null $tags Change tags to add to the pages and protection log entries
         *   ($user should be able to add the specified tags before this is called)
         * @return Status Status object; if action is taken, $status->value is the log_id of the
         *   protection log entry.
@@ -2365,7 +2022,7 @@ class WikiPage implements Page, IDBAccessObject {
                // Take this opportunity to purge out expired restrictions
                Title::purgeExpiredRestrictions();
 
-               // @todo FIXME: Same limitations as described in ProtectionForm.php (line 37);
+               // @todo: Same limitations as described in ProtectionForm.php (line 37);
                // we expect a single selection, but the schema allows otherwise.
                $isProtected = false;
                $protect = false;
@@ -2756,10 +2413,10 @@ class WikiPage implements Page, IDBAccessObject {
         * @param string $reason Delete reason for deletion log
         * @param bool $suppress Suppress all revisions and log the deletion in
         *        the suppression log instead of the deletion log
-        * @param int $u1 Unused
-        * @param bool $u2 Unused
+        * @param int|null $u1 Unused
+        * @param bool|null $u2 Unused
         * @param array|string &$error Array of errors to append to
-        * @param User $user The deleting user
+        * @param User|null $user The deleting user
         * @return bool True if successful
         */
        public function doDeleteArticle(
@@ -2778,10 +2435,10 @@ class WikiPage implements Page, IDBAccessObject {
         * @param string $reason Delete reason for deletion log
         * @param bool $suppress Suppress all revisions and log the deletion in
         *   the suppression log instead of the deletion log
-        * @param int $u1 Unused
-        * @param bool $u2 Unused
+        * @param int|null $u1 Unused
+        * @param bool|null $u2 Unused
         * @param array|string &$error Array of errors to append to
-        * @param User $deleter The deleting user
+        * @param User|null $deleter The deleting user
         * @param array $tags Tags to apply to the deletion action
         * @param string $logsubtype
         * @return Status Status object; if successful, $status->value is the log_id of the
@@ -2793,7 +2450,7 @@ class WikiPage implements Page, IDBAccessObject {
                $tags = [], $logsubtype = 'delete'
        ) {
                global $wgUser, $wgContentHandlerUseDB, $wgCommentTableSchemaMigrationStage,
-                       $wgActorTableSchemaMigrationStage;
+                       $wgActorTableSchemaMigrationStage, $wgMultiContentRevisionSchemaMigrationStage;
 
                wfDebug( __METHOD__ . "\n" );
 
@@ -2880,22 +2537,30 @@ class WikiPage implements Page, IDBAccessObject {
                // Note array_intersect() preserves keys from the first arg, and we're
                // assuming $revQuery has `revision` primary and isn't using subtables
                // for anything we care about.
-               $res = $dbw->select(
+               $dbw->lockForUpdate(
                        array_intersect(
                                $revQuery['tables'],
                                [ 'revision', 'revision_comment_temp', 'revision_actor_temp' ]
                        ),
-                       '1',
                        [ 'rev_page' => $id ],
                        __METHOD__,
-                       'FOR UPDATE',
+                       [],
                        $revQuery['joins']
                );
-               foreach ( $res as $row ) {
-                       // Fetch all rows in case the DB needs that to properly lock them.
+
+               // If SCHEMA_COMPAT_WRITE_OLD is set, also select all extra fields we still write,
+               // so we can copy it to the archive table.
+               // We know the fields exist, otherwise SCHEMA_COMPAT_WRITE_OLD could not function.
+               if ( $wgMultiContentRevisionSchemaMigrationStage & SCHEMA_COMPAT_WRITE_OLD ) {
+                       $revQuery['fields'][] = 'rev_text_id';
+
+                       if ( $wgContentHandlerUseDB ) {
+                               $revQuery['fields'][] = 'rev_content_model';
+                               $revQuery['fields'][] = 'rev_content_format';
+                       }
                }
 
-               // Get all of the page revisions
+                       // Get all of the page revisions
                $res = $dbw->select(
                        $revQuery['tables'],
                        $revQuery['fields'],
@@ -2922,17 +2587,30 @@ class WikiPage implements Page, IDBAccessObject {
                                'ar_minor_edit' => $row->rev_minor_edit,
                                'ar_rev_id'     => $row->rev_id,
                                'ar_parent_id'  => $row->rev_parent_id,
-                               'ar_text_id'    => $row->rev_text_id,
+                                       /**
+                                        * ar_text_id should probably not be written to when the multi content schema has
+                                        * been migrated to (wgMultiContentRevisionSchemaMigrationStage) however there is no
+                                        * default for the field in WMF production currently so we must keep writing
+                                        * writing until a default of 0 is set.
+                                        * Task: https://phabricator.wikimedia.org/T190148
+                                        * Copying the value from the revision table should not lead to any issues for now.
+                                        */
                                'ar_len'        => $row->rev_len,
                                'ar_page_id'    => $id,
                                'ar_deleted'    => $suppress ? $bitfield : $row->rev_deleted,
                                'ar_sha1'       => $row->rev_sha1,
                        ] + $commentStore->insert( $dbw, 'ar_comment', $comment )
                                + $actorMigration->getInsertValues( $dbw, 'ar_user', $user );
-                       if ( $wgContentHandlerUseDB ) {
-                               $rowInsert['ar_content_model'] = $row->rev_content_model;
-                               $rowInsert['ar_content_format'] = $row->rev_content_format;
+
+                       if ( $wgMultiContentRevisionSchemaMigrationStage & SCHEMA_COMPAT_WRITE_OLD ) {
+                               $rowInsert['ar_text_id'] = $row->rev_text_id;
+
+                               if ( $wgContentHandlerUseDB ) {
+                                       $rowInsert['ar_content_model'] = $row->rev_content_model;
+                                       $rowInsert['ar_content_format'] = $row->rev_content_format;
+                               }
                        }
+
                        $rowsInsert[] = $rowInsert;
                        $revids[] = $row->rev_id;
 
@@ -3158,7 +2836,7 @@ class WikiPage implements Page, IDBAccessObject {
         * Callers are responsible for permission checks
         * (with ChangeTags::canAddTagsAccompanyingChange)
         *
-        * @return array
+        * @return array An array of error messages, as returned by Status::getErrorsArray()
         */
        public function commitRollback( $fromP, $summary, $bot,
                &$resultDetails, User $guser, $tags = null
@@ -3171,43 +2849,44 @@ class WikiPage implements Page, IDBAccessObject {
                        return [ [ 'readonlytext' ] ];
                }
 
-               // Get the last editor
-               $current = $this->getRevision();
+               // Begin revision creation cycle by creating a PageUpdater.
+               // If the page is changed concurrently after grabParentRevision(), the rollback will fail.
+               $updater = $this->newPageUpdater( $guser );
+               $current = $updater->grabParentRevision();
+
                if ( is_null( $current ) ) {
                        // Something wrong... no page?
                        return [ [ 'notanarticle' ] ];
                }
 
+               $currentEditorForPublic = $current->getUser( RevisionRecord::FOR_PUBLIC );
+               $legacyCurrent = new Revision( $current );
                $from = str_replace( '_', ' ', $fromP );
+
                // User name given should match up with the top revision.
-               // If the user was deleted then $from should be empty.
-               if ( $from != $current->getUserText() ) {
-                       $resultDetails = [ 'current' => $current ];
+               // If the revision's user is not visible, then $from should be empty.
+               if ( $from !== ( $currentEditorForPublic ? $currentEditorForPublic->getName() : '' ) ) {
+                       $resultDetails = [ 'current' => $legacyCurrent ];
                        return [ [ 'alreadyrolled',
                                htmlspecialchars( $this->mTitle->getPrefixedText() ),
                                htmlspecialchars( $fromP ),
-                               htmlspecialchars( $current->getUserText() )
+                               htmlspecialchars( $currentEditorForPublic ? $currentEditorForPublic->getName() : '' )
                        ] ];
                }
 
                // Get the last edit not by this person...
                // Note: these may not be public values
-               $userId = intval( $current->getUser( Revision::RAW ) );
-               $userName = $current->getUserText( Revision::RAW );
-               if ( $userId ) {
-                       $user = User::newFromId( $userId );
-                       $user->setName( $userName );
-               } else {
-                       $user = User::newFromName( $current->getUserText( Revision::RAW ), false );
-               }
-
-               $actorWhere = ActorMigration::newMigration()->getWhere( $dbw, 'rev_user', $user );
+               $actorWhere = ActorMigration::newMigration()->getWhere(
+                       $dbw,
+                       'rev_user',
+                       $current->getUser( RevisionRecord::RAW )
+               );
 
                $s = $dbw->selectRow(
                        [ 'revision' ] + $actorWhere['tables'],
                        [ 'rev_id', 'rev_timestamp', 'rev_deleted' ],
                        [
-                               'rev_page' => $current->getPage(),
+                               'rev_page' => $current->getPageId(),
                                'NOT(' . $actorWhere['conds'] . ')',
                        ],
                        __METHOD__,
@@ -3220,28 +2899,36 @@ class WikiPage implements Page, IDBAccessObject {
                if ( $s === false ) {
                        // No one else ever edited this page
                        return [ [ 'cantrollback' ] ];
-               } elseif ( $s->rev_deleted & Revision::DELETED_TEXT
-                       || $s->rev_deleted & Revision::DELETED_USER
+               } elseif ( $s->rev_deleted & RevisionRecord::DELETED_TEXT
+                       || $s->rev_deleted & RevisionRecord::DELETED_USER
                ) {
                        // Only admins can see this text
                        return [ [ 'notvisiblerev' ] ];
                }
 
                // Generate the edit summary if necessary
-               $target = Revision::newFromId( $s->rev_id, Revision::READ_LATEST );
+               $target = $this->getRevisionStore()->getRevisionById(
+                       $s->rev_id,
+                       RevisionStore::READ_LATEST
+               );
                if ( empty( $summary ) ) {
-                       if ( $from == '' ) { // no public user name
+                       if ( !$currentEditorForPublic ) { // no public user name
                                $summary = wfMessage( 'revertpage-nouser' );
                        } else {
                                $summary = wfMessage( 'revertpage' );
                        }
                }
+               $legacyTarget = new Revision( $target );
+               $targetEditorForPublic = $target->getUser( RevisionRecord::FOR_PUBLIC );
 
                // Allow the custom summary to use the same args as the default message
                $args = [
-                       $target->getUserText(), $from, $s->rev_id,
+                       $targetEditorForPublic ? $targetEditorForPublic->getName() : null,
+                       $currentEditorForPublic ? $currentEditorForPublic->getName() : null,
+                       $s->rev_id,
                        $wgContLang->timeanddate( wfTimestamp( TS_MW, $s->rev_timestamp ) ),
-                       $current->getId(), $wgContLang->timeanddate( $current->getTimestamp() )
+                       $current->getId(),
+                       $wgContLang->timeanddate( $current->getTimestamp() )
                ];
                if ( $summary instanceof Message ) {
                        $summary = $summary->params( $args )->inContentLanguage()->text();
@@ -3263,22 +2950,45 @@ class WikiPage implements Page, IDBAccessObject {
                        $flags |= EDIT_FORCE_BOT;
                }
 
-               $targetContent = $target->getContent();
-               $changingContentModel = $targetContent->getModel() !== $current->getContentModel();
+               // TODO: MCR: also log model changes in other slots, in case that becomes possible!
+               $currentContent = $current->getContent( 'main' );
+               $targetContent = $target->getContent( 'main' );
+               $changingContentModel = $targetContent->getModel() !== $currentContent->getModel();
 
                if ( in_array( 'mw-rollback', ChangeTags::getSoftwareTags() ) ) {
                        $tags[] = 'mw-rollback';
                }
 
-               // Actually store the edit
-               $status = $this->doEditContent(
-                       $targetContent,
-                       $summary,
-                       $flags,
-                       $target->getId(),
-                       $guser,
-                       null,
-                       $tags
+               // Build rollback revision:
+               // Restore old content
+               // TODO: MCR: test this once we can store multiple slots
+               foreach ( $target->getSlots()->getSlots() as $slot ) {
+                       $updater->inheritSlot( $slot );
+               }
+
+               // Remove extra slots
+               // TODO: MCR: test this once we can store multiple slots
+               foreach ( $current->getSlotRoles() as $role ) {
+                       if ( !$target->hasSlot( $role ) ) {
+                               $updater->removeSlot( $role );
+                       }
+               }
+
+               $updater->setOriginalRevisionId( $target->getId() );
+               // Do not call setUndidRevisionId(), that causes an extra "mw-undo" tag to be added (T190374)
+               $updater->addTags( $tags );
+
+               // TODO: this logic should not be in the storage layer, it's here for compatibility
+               // with 1.31 behavior. Applying the 'autopatrol' right should be done in the same
+               // place the 'bot' right is handled, which is currently in EditPage::attemptSave.
+               if ( $wgUseRCPatrol && $this->getTitle()->userCan( 'autopatrol', $guser ) ) {
+                       $updater->setRcPatrolStatus( RecentChange::PRC_AUTOPATROLLED );
+               }
+
+               // Actually store the rollback
+               $rev = $updater->saveRevision(
+                       CommentStoreComment::newUnsavedComment( $summary ),
+                       $flags
                );
 
                // Set patrolling and bot flag on the edits, which gets rollbacked.
@@ -3295,10 +3005,15 @@ class WikiPage implements Page, IDBAccessObject {
                }
 
                if ( count( $set ) ) {
-                       $actorWhere = ActorMigration::newMigration()->getWhere( $dbw, 'rc_user', $user, false );
+                       $actorWhere = ActorMigration::newMigration()->getWhere(
+                               $dbw,
+                               'rc_user',
+                               $current->getUser( RevisionRecord::RAW ),
+                               false
+                       );
                        $dbw->update( 'recentchanges', $set,
                                [ /* WHERE */
-                                       'rc_cur_id' => $current->getPage(),
+                                       'rc_cur_id' => $current->getPageId(),
                                        'rc_timestamp > ' . $dbw->addQuotes( $s->rev_timestamp ),
                                        $actorWhere['conds'], // No tables/joins are needed for rc_user
                                ],
@@ -3306,20 +3021,17 @@ class WikiPage implements Page, IDBAccessObject {
                        );
                }
 
-               if ( !$status->isOK() ) {
-                       return $status->getErrorsArray();
+               if ( !$updater->wasSuccessful() ) {
+                       return $updater->getStatus()->getErrorsArray();
                }
 
-               // raise error, when the edit is an edit without a new version
-               $statusRev = isset( $status->value['revision'] )
-                       ? $status->value['revision']
-                       : null;
-               if ( !( $statusRev instanceof Revision ) ) {
-                       $resultDetails = [ 'current' => $current ];
+               // Report if the edit was not created because it did not change the content.
+               if ( $updater->isUnchanged() ) {
+                       $resultDetails = [ 'current' => $legacyCurrent ];
                        return [ [ 'alreadyrolled',
                                        htmlspecialchars( $this->mTitle->getPrefixedText() ),
                                        htmlspecialchars( $fromP ),
-                                       htmlspecialchars( $current->getUserText() )
+                                       htmlspecialchars( $targetEditorForPublic ? $targetEditorForPublic->getName() : '' )
                        ] ];
                }
 
@@ -3331,7 +3043,7 @@ class WikiPage implements Page, IDBAccessObject {
                        $log->setTarget( $this->mTitle );
                        $log->setComment( $summary );
                        $log->setParameters( [
-                               '4::oldmodel' => $current->getContentModel(),
+                               '4::oldmodel' => $currentContent->getModel(),
                                '5::newmodel' => $targetContent->getModel(),
                        ] );
 
@@ -3339,18 +3051,19 @@ class WikiPage implements Page, IDBAccessObject {
                        $log->publish( $logId );
                }
 
-               $revId = $statusRev->getId();
+               $revId = $rev->getId();
 
-               Hooks::run( 'ArticleRollbackComplete', [ $this, $guser, $target, $current ] );
+               Hooks::run( 'ArticleRollbackComplete', [ $this, $guser, $legacyTarget, $legacyCurrent ] );
 
                $resultDetails = [
                        'summary' => $summary,
-                       'current' => $current,
-                       'target' => $target,
+                       'current' => $legacyCurrent,
+                       'target' => $legacyTarget,
                        'newid' => $revId,
                        'tags' => $tags
                ];
 
+               // TODO: make this return a Status object and wrap $resultDetails in that.
                return [];
        }
 
@@ -3366,6 +3079,8 @@ class WikiPage implements Page, IDBAccessObject {
         * @param Title $title
         */
        public static function onArticleCreate( Title $title ) {
+               // TODO: move this into a PageEventEmitter service
+
                // Update existence markers on article/talk tabs...
                $other = $title->getOtherPage();
 
@@ -3397,6 +3112,8 @@ class WikiPage implements Page, IDBAccessObject {
         * @param Title $title
         */
        public static function onArticleDelete( Title $title ) {
+               // TODO: move this into a PageEventEmitter service
+
                // Update existence markers on article/talk tabs...
                // Clear Backlink cache first so that purge jobs use more up-to-date backlink information
                BacklinkCache::get( $title )->clear();
@@ -3442,12 +3159,24 @@ class WikiPage implements Page, IDBAccessObject {
         *
         * @param Title $title
         * @param Revision|null $revision Revision that was just saved, may be null
+        * @param string[]|null $slotsChanged The role names of the slots that were changed.
+        *        If not given, all slots are assumed to have changed.
         */
-       public static function onArticleEdit( Title $title, Revision $revision = null ) {
-               // Invalidate caches of articles which include this page
-               DeferredUpdates::addUpdate(
-                       new HTMLCacheUpdate( $title, 'templatelinks', 'page-edit' )
-               );
+       public static function onArticleEdit(
+               Title $title,
+               Revision $revision = null,
+               $slotsChanged = null
+       ) {
+               // TODO: move this into a PageEventEmitter service
+
+               if ( $slotsChanged === null || in_array( 'main',  $slotsChanged ) ) {
+                       // Invalidate caches of articles which include this page.
+                       // Only for the main slot, because only the main slot is transcluded.
+                       // TODO: MCR: not true for TemplateStyles! [SlotHandler]
+                       DeferredUpdates::addUpdate(
+                               new HTMLCacheUpdate( $title, 'templatelinks', 'page-edit' )
+                       );
+               }
 
                // Invalidate the caches of all pages which redirect here
                DeferredUpdates::addUpdate(
@@ -3545,16 +3274,13 @@ class WikiPage implements Page, IDBAccessObject {
         */
        public function updateCategoryCounts( array $added, array $deleted, $id = 0 ) {
                $id = $id ?: $this->getId();
-               $ns = $this->getTitle()->getNamespace();
+               $type = MWNamespace::getCategoryLinkType( $this->getTitle()->getNamespace() );
 
                $addFields = [ 'cat_pages = cat_pages + 1' ];
                $removeFields = [ 'cat_pages = cat_pages - 1' ];
-               if ( $ns == NS_CATEGORY ) {
-                       $addFields[] = 'cat_subcats = cat_subcats + 1';
-                       $removeFields[] = 'cat_subcats = cat_subcats - 1';
-               } elseif ( $ns == NS_FILE ) {
-                       $addFields[] = 'cat_files = cat_files + 1';
-                       $removeFields[] = 'cat_files = cat_files - 1';
+               if ( $type !== 'page' ) {
+                       $addFields[] = "cat_{$type}s = cat_{$type}s + 1";
+                       $removeFields[] = "cat_{$type}s = cat_{$type}s - 1";
                }
 
                $dbw = wfGetDB( DB_MASTER );
@@ -3586,8 +3312,8 @@ class WikiPage implements Page, IDBAccessObject {
                                        $insertRows[] = [
                                                'cat_title'   => $cat,
                                                'cat_pages'   => 1,
-                                               'cat_subcats' => ( $ns == NS_CATEGORY ) ? 1 : 0,
-                                               'cat_files'   => ( $ns == NS_FILE ) ? 1 : 0,
+                                               'cat_subcats' => ( $type === 'subcat' ) ? 1 : 0,
+                                               'cat_files'   => ( $type === 'file' ) ? 1 : 0,
                                        ];
                                }
                                $dbw->upsert(
@@ -3617,23 +3343,10 @@ class WikiPage implements Page, IDBAccessObject {
                foreach ( $deleted as $catName ) {
                        $cat = Category::newFromName( $catName );
                        Hooks::run( 'CategoryAfterPageRemoved', [ $cat, $this, $id ] );
-               }
-
-               // Refresh counts on categories that should be empty now
-               if ( count( $deleted ) ) {
-                       $rows = $dbw->select(
-                               'category',
-                               [ 'cat_id', 'cat_title', 'cat_pages', 'cat_subcats', 'cat_files' ],
-                               [ 'cat_title' => $deleted, 'cat_pages <= 100' ],
-                               __METHOD__
-                       );
-                       foreach ( $rows as $row ) {
-                               $cat = Category::newFromRow( $row );
-                               // T166757: do the update after this DB commit
-                               DeferredUpdates::addCallableUpdate( function () use ( $cat ) {
-                                       $cat->refreshCounts();
-                               } );
-                       }
+                       // Refresh counts on categories that should be empty now (after commit, T166757)
+                       DeferredUpdates::addCallableUpdate( function () use ( $cat ) {
+                               $cat->refreshCountsIfEmpty();
+                       } );
                }
        }
 
@@ -3768,4 +3481,5 @@ class WikiPage implements Page, IDBAccessObject {
 
                return $linkCache->getMutableCacheKeys( $cache, $this->getTitle()->getTitleValue() );
        }
+
 }
index 6880d58..b00ec3a 100644 (file)
@@ -381,9 +381,9 @@ abstract class IndexPager extends ContextSource implements Pager {
                $info = $this->getQueryInfo();
                $tables = $info['tables'];
                $fields = $info['fields'];
-               $conds = isset( $info['conds'] ) ? $info['conds'] : [];
-               $options = isset( $info['options'] ) ? $info['options'] : [];
-               $join_conds = isset( $info['join_conds'] ) ? $info['join_conds'] : [];
+               $conds = $info['conds'] ?? [];
+               $options = $info['options'] ?? [];
+               $join_conds = $info['join_conds'] ?? [];
                $sortColumns = array_merge( [ $this->mIndexField ], $this->mExtraSortFields );
                if ( $descending ) {
                        $options['ORDER BY'] = $sortColumns;
@@ -456,8 +456,8 @@ abstract class IndexPager extends ContextSource implements Pager {
         * Make a self-link
         *
         * @param string $text Text displayed on the link
-        * @param array $query Associative array of parameter to be in the query string
-        * @param string $type Link type used to create additional attributes, like "rel", "class" or
+        * @param array|null $query Associative array of parameter to be in the query string
+        * @param string|null $type Link type used to create additional attributes, like "rel", "class" or
         *  "title". Valid values (non-exhaustive list): 'first', 'last', 'prev', 'next', 'asc', 'desc'.
         * @return string HTML fragment
         */
index 9eef728..51824d2 100644 (file)
@@ -81,14 +81,16 @@ abstract class ReverseChronologicalPager extends IndexPager {
                        return null;
                }
 
-               // Treat the given time in the wiki timezone and get a UTC timestamp for the database lookup
                $timestamp = self::getOffsetDate( $year, $month, $day );
-               $timestamp->setTimezone( $this->getConfig()->get( 'Localtimezone' ) );
 
                try {
-                       $this->mYear = (int)$timestamp->format( 'Y' );
-                       $this->mMonth = (int)$timestamp->format( 'm' );
-                       $this->mDay = (int)$timestamp->format( 'd' );
+                       // The timestamp used for DB queries is at midnight of the *next* day after the selected date.
+                       $selectedDate = new DateTime( $timestamp->getTimestamp( TS_ISO_8601 ) );
+                       $selectedDate = $selectedDate->modify( '-1 day' );
+
+                       $this->mYear = (int)$selectedDate->format( 'Y' );
+                       $this->mMonth = (int)$selectedDate->format( 'm' );
+                       $this->mDay = (int)$selectedDate->format( 'd' );
                        $this->mOffset = $this->mDb->timestamp( $timestamp->getTimestamp() );
                } catch ( TimestampException $e ) {
                        // Invalid user provided timestamp (T149257)
index 70055da..f38ed27 100644 (file)
@@ -119,7 +119,7 @@ abstract class TablePager extends IndexPager {
                // Make table header
                foreach ( $fields as $field => $name ) {
                        if ( strval( $name ) == '' ) {
-                               $s .= Html::rawElement( 'th', [], '&#160;' ) . "\n";
+                               $s .= Html::rawElement( 'th', [], "\u{00A0}" ) . "\n";
                        } elseif ( $this->isFieldSortable( $field ) ) {
                                $query = [ 'sort' => $field, 'limit' => $this->mLimit ];
                                $linkType = null;
@@ -188,11 +188,11 @@ abstract class TablePager extends IndexPager {
                $fieldNames = $this->getFieldNames();
 
                foreach ( $fieldNames as $field => $name ) {
-                       $value = isset( $row->$field ) ? $row->$field : null;
+                       $value = $row->$field ?? null;
                        $formatted = strval( $this->formatValue( $field, $value ) );
 
                        if ( $formatted == '' ) {
-                               $formatted = '&#160;';
+                               $formatted = "\u{00A0}";
                        }
 
                        $s .= Html::rawElement( 'td', $this->getCellAttrs( $field, $value ), $formatted ) . "\n";
@@ -298,7 +298,6 @@ abstract class TablePager extends IndexPager {
                $types = [ 'first', 'prev', 'next', 'last' ];
 
                $queries = $this->getPagingQueries();
-               $links = [];
 
                $buttons = [];
 
index c366903..0553db9 100644 (file)
@@ -293,7 +293,7 @@ class BlockLevelPass {
                                # @todo consider using a stack for nestable elements like span, table and div
 
                                // P-wrapping and indent-pre are suppressed inside, not outside
-                               $blockElems = 'table|h1|h2|h3|h4|h5|h6|pre|p|ul|ol|dl|li';
+                               $blockElems = 'table|h1|h2|h3|h4|h5|h6|pre|p|ul|ol|dl';
                                // P-wrapping and indent-pre are suppressed outside, not inside
                                $antiBlockElems = 'td|th';
 
@@ -301,7 +301,7 @@ class BlockLevelPass {
                                        '/<('
                                                . "({$blockElems})|\\/({$antiBlockElems})|"
                                                // Always suppresses
-                                               . '\\/?(tr)'
+                                               . '\\/?(tr|dt|dd|li)'
                                                . ')\\b/iS',
                                        $t
                                );
index d408c7f..3c47de3 100644 (file)
@@ -112,7 +112,7 @@ class CoreParserFunctions {
        /**
         * @param Parser $parser
         * @param string $date
-        * @param string $defaultPref
+        * @param string|null $defaultPref
         *
         * @return string
         */
@@ -165,13 +165,14 @@ class CoreParserFunctions {
         *
         * @param Parser $parser
         * @param string $s The text to encode.
-        * @param string $arg (optional): The type of encoding.
+        * @param string|null $arg (optional): The type of encoding.
         * @return string
         */
        public static function urlencode( $parser, $s = '', $arg = null ) {
                static $magicWords = null;
                if ( is_null( $magicWords ) ) {
-                       $magicWords = new MagicWordArray( [ 'url_path', 'url_query', 'url_wiki' ] );
+                       $magicWords =
+                               $parser->getMagicWordFactory()->newArray( [ 'url_path', 'url_query', 'url_wiki' ] );
                }
                switch ( $magicWords->matchStartToEnd( $arg ) ) {
                        // Encode as though it's a wiki page, '_' for ' '.
@@ -292,13 +293,15 @@ class CoreParserFunctions {
        /**
         * @param Parser $parser
         * @param string $num
-        * @param string $arg
+        * @param string|null $arg
         * @return string
         */
        public static function formatnum( $parser, $num = '', $arg = null ) {
-               if ( self::matchAgainstMagicword( 'rawsuffix', $arg ) ) {
+               if ( self::matchAgainstMagicword( $parser->getMagicWordFactory(), 'rawsuffix', $arg ) ) {
                        $func = [ $parser->getFunctionLang(), 'parseFormattedNumber' ];
-               } elseif ( self::matchAgainstMagicword( 'nocommafysuffix', $arg ) ) {
+               } elseif (
+                       self::matchAgainstMagicword( $parser->getMagicWordFactory(), 'nocommafysuffix', $arg )
+               ) {
                        $func = [ $parser->getFunctionLang(), 'formatNumNoSeparators' ];
                } else {
                        $func = [ $parser->getFunctionLang(), 'formatNum' ];
@@ -391,7 +394,8 @@ class CoreParserFunctions {
 
                static $magicWords = null;
                if ( is_null( $magicWords ) ) {
-                       $magicWords = new MagicWordArray( [ 'displaytitle_noerror', 'displaytitle_noreplace' ] );
+                       $magicWords = $parser->getMagicWordFactory()->newArray(
+                               [ 'displaytitle_noerror', 'displaytitle_noreplace' ] );
                }
                $arg = $magicWords->matchStartToEnd( $uarg );
 
@@ -449,7 +453,7 @@ class CoreParserFunctions {
                                $parser->mOutput->setDisplayTitle( $text );
                        }
                        if ( $old !== false && $old !== $text && !$arg ) {
-                               $converter = $parser->getConverterLanguage()->getConverter();
+                               $converter = $parser->getTargetLanguage()->getConverter();
                                return '<span class="error">' .
                                        wfMessage( 'duplicate-displaytitle',
                                                // Message should be parsed, but these params should only be escaped.
@@ -461,7 +465,7 @@ class CoreParserFunctions {
                                return '';
                        }
                } else {
-                       $converter = $parser->getConverterLanguage()->getConverter();
+                       $converter = $parser->getTargetLanguage()->getConverter();
                        $parser->getOutput()->addWarning(
                                wfMessage( 'restricted-displaytitle',
                                        // Message should be parsed, but this param should only be escaped.
@@ -475,16 +479,20 @@ class CoreParserFunctions {
        /**
         * Matches the given value against the value of given magic word
         *
+        * @param MagicWordFactory $magicWordFactory A factory to get the word from, e.g., from
+        *   $parser->getMagicWordFactory()
         * @param string $magicword Magic word key
         * @param string $value Value to match
         * @return bool True on successful match
         */
-       private static function matchAgainstMagicword( $magicword, $value ) {
+       private static function matchAgainstMagicword(
+               MagicWordFactory $magicWordFactory, $magicword, $value
+       ) {
                $value = trim( strval( $value ) );
                if ( $value === '' ) {
                        return false;
                }
-               $mwObject = MagicWord::get( $magicword );
+               $mwObject = $magicWordFactory->get( $magicword );
                return $mwObject->matchStartToEnd( $value );
        }
 
@@ -494,10 +502,18 @@ class CoreParserFunctions {
         * @param int|float $num
         * @param string $raw
         * @param Language|StubUserLang $language
+        * @param MagicWordFactory|null $magicWordFactory To evaluate $raw
         * @return string
         */
-       public static function formatRaw( $num, $raw, $language ) {
-               if ( self::matchAgainstMagicword( 'rawsuffix', $raw ) ) {
+       public static function formatRaw(
+               $num, $raw, $language, MagicWordFactory $magicWordFactory = null
+       ) {
+               if ( $raw !== null && !$magicWordFactory ) {
+                       $magicWordFactory = MediaWikiServices::getInstance()->getMagicWordFactory();
+               }
+               if (
+                       $raw !== null && self::matchAgainstMagicword( $magicWordFactory, 'rawsuffix', $raw )
+               ) {
                        return $num;
                } else {
                        return $language->formatNum( $num );
@@ -556,7 +572,7 @@ class CoreParserFunctions {
         * Note: function name changed to "mwnamespace" rather than "namespace"
         * to not break PHP 5.3
         * @param Parser $parser
-        * @param string $title
+        * @param string|null $title
         * @return mixed|string
         */
        public static function mwnamespace( $parser, $title = null ) {
@@ -613,7 +629,7 @@ class CoreParserFunctions {
         * Functions to get and normalize pagenames, corresponding to the magic words
         * of the same names
         * @param Parser $parser
-        * @param string $title
+        * @param string|null $title
         * @return string
         */
        public static function pagename( $parser, $title = null ) {
@@ -721,15 +737,15 @@ class CoreParserFunctions {
         * can't be called too many times per page.
         * @param Parser $parser
         * @param string $name
-        * @param string $arg1
-        * @param string $arg2
+        * @param string|null $arg1
+        * @param string|null $arg2
         * @return string
         */
        public static function pagesincategory( $parser, $name = '', $arg1 = null, $arg2 = null ) {
                global $wgContLang;
                static $magicWords = null;
                if ( is_null( $magicWords ) ) {
-                       $magicWords = new MagicWordArray( [
+                       $magicWords = $parser->getMagicWordFactory()->newArray( [
                                'pagesincategory_all',
                                'pagesincategory_pages',
                                'pagesincategory_subcats',
@@ -739,7 +755,7 @@ class CoreParserFunctions {
                static $cache = [];
 
                // split the given option to its variable
-               if ( self::matchAgainstMagicword( 'rawsuffix', $arg1 ) ) {
+               if ( self::matchAgainstMagicword( $parser->getMagicWordFactory(), 'rawsuffix', $arg1 ) ) {
                        // {{pagesincategory:|raw[|type]}}
                        $raw = $arg1;
                        $type = $magicWords->matchStartToEnd( $arg2 );
@@ -789,7 +805,7 @@ class CoreParserFunctions {
         *
         * @param Parser $parser
         * @param string $page Name of page to check (Default: empty string)
-        * @param string $raw Should number be human readable with commas or just number
+        * @param string|null $raw Should number be human readable with commas or just number
         * @return string
         */
        public static function pagesize( $parser, $page = '', $raw = null ) {
@@ -882,7 +898,7 @@ class CoreParserFunctions {
         * Unicode-safe str_pad with the restriction that $length is forced to be <= 500
         * @param Parser $parser
         * @param string $string
-        * @param int $length
+        * @param string $length
         * @param string $padding
         * @param int $direction
         * @return string
@@ -897,7 +913,12 @@ class CoreParserFunctions {
                }
 
                # The remaining length to add counts down to 0 as padding is added
-               $length = min( $length, 500 ) - mb_strlen( $string );
+               $length = min( (int)$length, 500 ) - mb_strlen( $string );
+               if ( $length <= 0 ) {
+                       // Nothing to add
+                       return $string;
+               }
+
                # $finalPadding is just $padding repeated enough times so that
                # mb_strlen( $string ) + mb_strlen( $finalPadding ) == $length
                $finalPadding = '';
@@ -961,7 +982,8 @@ class CoreParserFunctions {
        public static function defaultsort( $parser, $text, $uarg = '' ) {
                static $magicWords = null;
                if ( is_null( $magicWords ) ) {
-                       $magicWords = new MagicWordArray( [ 'defaultsort_noerror', 'defaultsort_noreplace' ] );
+                       $magicWords = $parser->getMagicWordFactory()->newArray(
+                               [ 'defaultsort_noerror', 'defaultsort_noreplace' ] );
                }
                $arg = $magicWords->matchStartToEnd( $uarg );
 
@@ -977,7 +999,7 @@ class CoreParserFunctions {
                if ( $old === false || $old == $text || $arg ) {
                        return '';
                } else {
-                       $converter = $parser->getConverterLanguage()->getConverter();
+                       $converter = $parser->getTargetLanguage()->getConverter();
                        return '<span class="error">' .
                                wfMessage( 'duplicate-defaultsort',
                                        // Message should be parsed, but these params should only be escaped.
@@ -1059,7 +1081,7 @@ class CoreParserFunctions {
                                $name = trim( $frame->expand( $bits['name'], PPFrame::STRIP_COMMENTS ) );
                                $value = trim( $frame->expand( $bits['value'] ) );
                                if ( preg_match( '/^(?:["\'](.+)["\']|""|\'\')$/s', $value, $m ) ) {
-                                       $value = isset( $m[1] ) ? $m[1] : '';
+                                       $value = $m[1] ?? '';
                                }
                                $attributes[$name] = $value;
                        }
@@ -1136,7 +1158,7 @@ class CoreParserFunctions {
        /**
         * Get the pageid of a specified page
         * @param Parser $parser
-        * @param string $title Title to get the pageid from
+        * @param string|null $title Title to get the pageid from
         * @return int|null|string
         * @since 1.23
         */
@@ -1157,7 +1179,7 @@ class CoreParserFunctions {
                }
 
                // Check the link cache, maybe something already looked it up.
-               $linkCache = LinkCache::singleton();
+               $linkCache = MediaWikiServices::getInstance()->getLinkCache();
                $pdbk = $t->getPrefixedDBkey();
                $id = $linkCache->getGoodLinkID( $pdbk );
                if ( $id != 0 ) {
@@ -1181,7 +1203,7 @@ class CoreParserFunctions {
        /**
         * Get the id from the last revision of a specified page.
         * @param Parser $parser
-        * @param string $title Title to get the id from
+        * @param string|null $title Title to get the id from
         * @return int|null|string
         * @since 1.23
         */
@@ -1198,7 +1220,7 @@ class CoreParserFunctions {
        /**
         * Get the day from the last revision of a specified page.
         * @param Parser $parser
-        * @param string $title Title to get the day from
+        * @param string|null $title Title to get the day from
         * @return string
         * @since 1.23
         */
@@ -1215,7 +1237,7 @@ class CoreParserFunctions {
        /**
         * Get the day with leading zeros from the last revision of a specified page.
         * @param Parser $parser
-        * @param string $title Title to get the day from
+        * @param string|null $title Title to get the day from
         * @return string
         * @since 1.23
         */
@@ -1232,7 +1254,7 @@ class CoreParserFunctions {
        /**
         * Get the month with leading zeros from the last revision of a specified page.
         * @param Parser $parser
-        * @param string $title Title to get the month from
+        * @param string|null $title Title to get the month from
         * @return string
         * @since 1.23
         */
@@ -1249,7 +1271,7 @@ class CoreParserFunctions {
        /**
         * Get the month from the last revision of a specified page.
         * @param Parser $parser
-        * @param string $title Title to get the month from
+        * @param string|null $title Title to get the month from
         * @return string
         * @since 1.23
         */
@@ -1266,7 +1288,7 @@ class CoreParserFunctions {
        /**
         * Get the year from the last revision of a specified page.
         * @param Parser $parser
-        * @param string $title Title to get the year from
+        * @param string|null $title Title to get the year from
         * @return string
         * @since 1.23
         */
@@ -1283,7 +1305,7 @@ class CoreParserFunctions {
        /**
         * Get the timestamp from the last revision of a specified page.
         * @param Parser $parser
-        * @param string $title Title to get the timestamp from
+        * @param string|null $title Title to get the timestamp from
         * @return string
         * @since 1.23
         */
@@ -1300,7 +1322,7 @@ class CoreParserFunctions {
        /**
         * Get the user from the last revision of a specified page.
         * @param Parser $parser
-        * @param string $title Title to get the user from
+        * @param string|null $title Title to get the user from
         * @return string
         * @since 1.23
         */
index 438603a..d178600 100644 (file)
@@ -46,6 +46,10 @@ class CoreTagHooks {
         * Text is treated roughly as 'nowiki' wrapped in an HTML 'pre' tag;
         * valid HTML attributes are passed on.
         *
+        * Uses custom html escaping which phan-taint-check won't recognize
+        * hence we suppress the error.
+        * @suppress SecurityCheck-XSS
+        *
         * @param string $text
         * @param array $attribs
         * @param Parser $parser
@@ -75,6 +79,7 @@ class CoreTagHooks {
         *
         * Uses undocumented extended tag hook return values, introduced in r61913.
         *
+        * @suppress SecurityCheck-XSS
         * @param string $content
         * @param array $attributes
         * @param Parser $parser
@@ -110,6 +115,10 @@ class CoreTagHooks {
         *
         * Uses undocumented extended tag hook return values, introduced in r61913.
         *
+        * Uses custom html escaping which phan-taint-check won't recognize
+        * hence we suppress the error.
+        * @suppress SecurityCheck-XSS
+        *
         * @param string $content
         * @param array $attributes
         * @param Parser $parser
index 816f7f7..66fd723 100644 (file)
@@ -21,6 +21,8 @@
  * @ingroup Parser
  */
 
+use MediaWiki\MediaWikiServices;
+
 /**
  * @ingroup Parser
  */
@@ -283,7 +285,7 @@ class LinkHolderArray {
                global $wgContLang;
 
                $colours = [];
-               $linkCache = LinkCache::singleton();
+               $linkCache = MediaWikiServices::getInstance()->getLinkCache();
                $output = $this->parent->getOutput();
                $linkRenderer = $this->parent->getLinkRenderer();
 
@@ -358,7 +360,7 @@ class LinkHolderArray {
                }
                if ( count( $linkcolour_ids ) ) {
                        // pass an array of page_ids to an extension
-                       Hooks::run( 'GetLinkColours', [ $linkcolour_ids, &$colours ] );
+                       Hooks::run( 'GetLinkColours', [ $linkcolour_ids, &$colours, $this->parent->getTitle() ] );
                }
 
                # Do a second query for different language variants of links and categories
@@ -372,7 +374,7 @@ class LinkHolderArray {
                        foreach ( $entries as $index => $entry ) {
                                $pdbk = $entry['pdbk'];
                                $title = $entry['title'];
-                               $query = isset( $entry['query'] ) ? $entry['query'] : [];
+                               $query = $entry['query'] ?? [];
                                $key = "$ns:$index";
                                $searchkey = "<!--LINK'\" $key-->";
                                $displayText = $entry['text'];
@@ -404,12 +406,13 @@ class LinkHolderArray {
                                $replacePairs[$searchkey] = $link;
                        }
                }
-               $replacer = new HashtableReplacer( $replacePairs, 1 );
 
                # Do the thing
                $text = preg_replace_callback(
                        '/(<!--LINK\'" .*?-->)/',
-                       $replacer->cb(),
+                       function ( array $matches ) use ( $replacePairs ) {
+                               return $replacePairs[$matches[1]];
+                       },
                        $text
                );
        }
@@ -434,12 +437,14 @@ class LinkHolderArray {
                        );
                        $output->addInterwikiLink( $link['title'] );
                }
-               $replacer = new HashtableReplacer( $replacePairs, 1 );
 
                $text = preg_replace_callback(
                        '/<!--IWLINK\'" (.*?)-->/',
-                       $replacer->cb(),
-                       $text );
+                       function ( array $matches ) use ( $replacePairs ) {
+                               return $replacePairs[$matches[1]];
+                       },
+                       $text
+               );
        }
 
        /**
@@ -451,7 +456,7 @@ class LinkHolderArray {
                $linkBatch = new LinkBatch();
                $variantMap = []; // maps $pdbkey_Variant => $keys (of link holders)
                $output = $this->parent->getOutput();
-               $linkCache = LinkCache::singleton();
+               $linkCache = MediaWikiServices::getInstance()->getLinkCache();
                $titlesToBeConverted = '';
                $titlesAttrs = [];
 
@@ -584,7 +589,7 @@ class LinkHolderArray {
                                        }
                                }
                        }
-                       Hooks::run( 'GetLinkColours', [ $linkcolour_ids, &$colours ] );
+                       Hooks::run( 'GetLinkColours', [ $linkcolour_ids, &$colours, $this->parent->getTitle() ] );
 
                        // rebuild the categories in original order (if there are replacements)
                        if ( count( $varCategories ) > 0 ) {
index 4e39537..2778ea6 100644 (file)
@@ -260,10 +260,14 @@ class Parser {
         */
        protected $mLinkRenderer;
 
+       /** @var MagicWordFactory */
+       private $magicWordFactory;
+
        /**
         * @param array $conf
+        * @param MagicWordFactory|null $magicWordFactory
         */
-       public function __construct( $conf = [] ) {
+       public function __construct( $conf = [], MagicWordFactory $magicWordFactory = null ) {
                $this->mConf = $conf;
                $this->mUrlProtocols = wfUrlProtocols();
                $this->mExtLinkBracketedRegex = '/\[(((?i)' . $this->mUrlProtocols . ')' .
@@ -284,6 +288,11 @@ class Parser {
                        $this->mPreprocessorClass = Preprocessor_Hash::class;
                }
                wfDebug( __CLASS__ . ": using preprocessor: {$this->mPreprocessorClass}\n" );
+
+               $this->magicWordFactory = $magicWordFactory;
+               if ( !$magicWordFactory ) {
+                       $this->magicWordFactory = MediaWikiServices::getInstance()->getMagicWordFactory();
+               }
        }
 
        /**
@@ -401,7 +410,7 @@ class Parser {
         * @param ParserOptions $options
         * @param bool $linestart
         * @param bool $clearState
-        * @param int $revid Number to pass in {{REVISIONID}}
+        * @param int|null $revid Number to pass in {{REVISIONID}}
         * @return ParserOutput A ParserOutput
         */
        public function parse(
@@ -460,11 +469,11 @@ class Parser {
                        || isset( $this->mDoubleUnderscores['notitleconvert'] )
                        || $this->mOutput->getDisplayTitle() !== false )
                ) {
-                       $convruletitle = $this->getConverterLanguage()->getConvRuleTitle();
+                       $convruletitle = $this->getTargetLanguage()->getConvRuleTitle();
                        if ( $convruletitle ) {
                                $this->mOutput->setTitleText( $convruletitle );
                        } else {
-                               $titleText = $this->getConverterLanguage()->convertTitle( $title );
+                               $titleText = $this->getTargetLanguage()->convertTitle( $title );
                                $this->mOutput->setTitleText( $titleText );
                        }
                }
@@ -593,7 +602,7 @@ class Parser {
                // Add on template profiling data in human/machine readable way
                $dataByFunc = $this->mProfiler->getFunctionStats();
                uasort( $dataByFunc, function ( $a, $b ) {
-                       return $a['real'] < $b['real']; // descending order
+                       return $b['real'] <=> $a['real']; // descending order
                } );
                $profileReport = [];
                foreach ( array_slice( $dataByFunc, 0, 10 ) as $item ) {
@@ -683,7 +692,7 @@ class Parser {
         * Also removes comments.
         * Do not call this function recursively.
         * @param string $text
-        * @param Title $title
+        * @param Title|null $title
         * @param ParserOptions $options
         * @param int|null $revid
         * @param bool|PPFrame $frame
@@ -789,7 +798,7 @@ class Parser {
        /**
         * Accessor/mutator for the Title object
         *
-        * @param Title $x Title object or null to just get the current one
+        * @param Title|null $x Title object or null to just get the current one
         * @return Title
         */
        public function Title( $x = null ) {
@@ -843,7 +852,7 @@ class Parser {
        /**
         * Accessor/mutator for the ParserOptions object
         *
-        * @param ParserOptions $x New value or null to just get the current one
+        * @param ParserOptions|null $x New value or null to just get the current one
         * @return ParserOptions Current ParserOptions object
         */
        public function Options( $x = null ) {
@@ -897,6 +906,7 @@ class Parser {
 
        /**
         * Get the language object for language conversion
+        * @deprecated since 1.32, just use getTargetLanguage()
         * @return Language|null
         */
        public function getConverterLanguage() {
@@ -947,6 +957,16 @@ class Parser {
                return $this->mLinkRenderer;
        }
 
+       /**
+        * Get the MagicWordFactory that this Parser is using
+        *
+        * @since 1.32
+        * @return MagicWordFactory
+        */
+       public function getMagicWordFactory() {
+               return $this->magicWordFactory;
+       }
+
        /**
         * Replaces all occurrences of HTML-style comments and the given tags
         * in the text with a random marker and returns the next text. The output
@@ -1352,15 +1372,7 @@ class Parser {
                }
 
                # Clean up special characters, only run once, next-to-last before doBlockLevels
-               $fixtags = [
-                       # French spaces, last one Guillemet-left
-                       # only if there is something before the space
-                       '/(.) (?=\\?|:|;|!|%|\\302\\273)/' => '\\1&#160;',
-                       # french spaces, Guillemet-right
-                       '/(\\302\\253) /' => '\\1&#160;',
-                       '/&#160;(!\s*important)/' => ' \\1', # Beware of CSS magic word !important, T13874.
-               ];
-               $text = preg_replace( array_keys( $fixtags ), array_values( $fixtags ), $text );
+               $text = Sanitizer::armorFrenchSpaces( $text );
 
                $text = $this->doBlockLevels( $text, $linestart );
 
@@ -1380,7 +1392,7 @@ class Parser {
                                # 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->getConverterLanguage()->convert( $text );
+                               $text = $this->getTargetLanguage()->convert( $text );
                        }
                }
 
@@ -1605,7 +1617,7 @@ class Parser {
                if ( $text === false ) {
                        # Not an image, make a link
                        $text = Linker::makeExternalLink( $url,
-                               $this->getConverterLanguage()->markNoConversion( $url, true ),
+                               $this->getTargetLanguage()->getConverter()->markNoConversion( $url ),
                                true, 'free',
                                $this->getExternalLinkAttribs( $url ), $this->mTitle );
                        # Register it in the output object...
@@ -1894,7 +1906,10 @@ class Parser {
                                list( $dtrail, $trail ) = Linker::splitTrail( $trail );
                        }
 
-                       $text = $this->getConverterLanguage()->markNoConversion( $text );
+                       // Excluding protocol-relative URLs may avoid many false positives.
+                       if ( preg_match( '/^(?:' . wfUrlProtocolsWithoutProtRel() . ')/', $text ) ) {
+                               $text = $this->getTargetLanguage()->getConverter()->markNoConversion( $text );
+                       }
 
                        $url = Sanitizer::cleanUrl( $url );
 
@@ -1918,7 +1933,7 @@ class Parser {
         * @since 1.21
         * @param string|bool $url Optional URL, to extract the domain from for rel =>
         *   nofollow if appropriate
-        * @param Title $title Optional Title, for wgNoFollowNsExceptions lookups
+        * @param Title|null $title Optional Title, for wgNoFollowNsExceptions lookups
         * @return string|null Rel attribute for $url
         */
        public static function getExternalLinkRel( $url = false, $title = null ) {
@@ -2360,7 +2375,7 @@ class Parser {
                                        }
                                        $sortkey = Sanitizer::decodeCharReferences( $sortkey );
                                        $sortkey = str_replace( "\n", '', $sortkey );
-                                       $sortkey = $this->getConverterLanguage()->convertCategoryKey( $sortkey );
+                                       $sortkey = $this->getTargetLanguage()->convertCategoryKey( $sortkey );
                                        $this->mOutput->addCategory( $nt->getDBkey(), $sortkey );
 
                                        continue;
@@ -2486,7 +2501,7 @@ class Parser {
         *
         * @private
         *
-        * @param string $index Magic variable identifier as mapped in MagicWord::$mVariableIDs
+        * @param string $index Magic variable identifier as mapped in MagicWordFactory::$mVariableIDs
         * @param bool|PPFrame $frame
         *
         * @throws MWException
@@ -2641,7 +2656,7 @@ class Parser {
                                        $this->mOutput->setFlag( 'vary-revision' );
                                        wfDebug( __METHOD__ . ": {{PAGEID}} used in a new page, setting vary-revision...\n" );
                                }
-                               $value = $pageid ? $pageid : null;
+                               $value = $pageid ?: null;
                                break;
                        case 'revisionid':
                                # Let the edit saving system know we should parse the page
@@ -2863,11 +2878,11 @@ class Parser {
         * @private
         */
        public function initialiseVariables() {
-               $variableIDs = MagicWord::getVariableIDs();
-               $substIDs = MagicWord::getSubstIDs();
+               $variableIDs = $this->magicWordFactory->getVariableIDs();
+               $substIDs = $this->magicWordFactory->getSubstIDs();
 
-               $this->mVariables = new MagicWordArray( $variableIDs );
-               $this->mSubstWords = new MagicWordArray( $substIDs );
+               $this->mVariables = $this->magicWordFactory->newArray( $variableIDs );
+               $this->mSubstWords = $this->magicWordFactory->newArray( $substIDs );
        }
 
        /**
@@ -3102,8 +3117,9 @@ class Parser {
                        $id = $this->mVariables->matchStartToEnd( $part1 );
                        if ( $id !== false ) {
                                $text = $this->getVariableValue( $id, $frame );
-                               if ( MagicWord::getCacheTTL( $id ) > -1 ) {
-                                       $this->mOutput->updateCacheExpiry( MagicWord::getCacheTTL( $id ) );
+                               if ( $this->magicWordFactory->getCacheTTL( $id ) > -1 ) {
+                                       $this->mOutput->updateCacheExpiry(
+                                               $this->magicWordFactory->getCacheTTL( $id ) );
                                }
                                $found = true;
                        }
@@ -3112,17 +3128,17 @@ class Parser {
                # MSG, MSGNW and RAW
                if ( !$found ) {
                        # Check for MSGNW:
-                       $mwMsgnw = MagicWord::get( 'msgnw' );
+                       $mwMsgnw = $this->magicWordFactory->get( 'msgnw' );
                        if ( $mwMsgnw->matchStartAndRemove( $part1 ) ) {
                                $nowiki = true;
                        } else {
                                # Remove obsolete MSG:
-                               $mwMsg = MagicWord::get( 'msg' );
+                               $mwMsg = $this->magicWordFactory->get( 'msg' );
                                $mwMsg->matchStartAndRemove( $part1 );
                        }
 
                        # Check for RAW:
-                       $mwRaw = MagicWord::get( 'raw' );
+                       $mwRaw = $this->magicWordFactory->get( 'raw' );
                        if ( $mwRaw->matchStartAndRemove( $part1 ) ) {
                                $forceRawInterwiki = true;
                        }
@@ -3138,11 +3154,8 @@ class Parser {
                                for ( $i = 0; $i < $argsLength; $i++ ) {
                                        $funcArgs[] = $args->item( $i );
                                }
-                               try {
-                                       $result = $this->callParserFunction( $frame, $func, $funcArgs );
-                               } catch ( Exception $ex ) {
-                                       throw $ex;
-                               }
+
+                               $result = $this->callParserFunction( $frame, $func, $funcArgs );
 
                                // Extract any forwarded flags
                                if ( isset( $result['title'] ) ) {
@@ -3188,8 +3201,8 @@ class Parser {
                        if ( $title ) {
                                $titleText = $title->getPrefixedText();
                                # Check for language variants if the template is not found
-                               if ( $this->getConverterLanguage()->hasVariants() && $title->getArticleID() == 0 ) {
-                                       $this->getConverterLanguage()->findVariantLink( $part1, $title, true );
+                               if ( $this->getTargetLanguage()->hasVariants() && $title->getArticleID() == 0 ) {
+                                       $this->getTargetLanguage()->findVariantLink( $part1, $title, true );
                                }
                                # Do recursion depth check
                                $limit = $this->mOptions->getMaxTemplateDepth();
@@ -3438,7 +3451,7 @@ class Parser {
                        }
                }
 
-               $result = call_user_func_array( $callback, $allArgs );
+               $result = $callback( ...$allArgs );
 
                # The interface for function hooks allows them to return a wikitext
                # string or an array containing the string and any flags. This mungs
@@ -3569,7 +3582,7 @@ class Parser {
                if ( is_string( $stuff['text'] ) ) {
                        $text = strtr( $text, "\x7f", "?" );
                }
-               $finalTitle = isset( $stuff['finalTitle'] ) ? $stuff['finalTitle'] : $title;
+               $finalTitle = $stuff['finalTitle'] ?? $title;
                if ( isset( $stuff['deps'] ) ) {
                        foreach ( $stuff['deps'] as $dep ) {
                                $this->mOutput->addTemplate( $dep['title'], $dep['page_id'], $dep['rev_id'] );
@@ -3634,7 +3647,7 @@ class Parser {
                        $rev_id = $rev ? $rev->getId() : 0;
                        # If there is no current revision, there is no page
                        if ( $id === false && !$rev ) {
-                               $linkCache = LinkCache::singleton();
+                               $linkCache = MediaWikiServices::getInstance()->getLinkCache();
                                $linkCache->addBadLinkObj( $title );
                        }
 
@@ -3692,8 +3705,10 @@ class Parser {
         * @param Title $title
         * @param array $options Array of options to RepoGroup::findFile
         * @return File|bool
+        * @deprecated since 1.32, use fetchFileAndTitle instead
         */
        public function fetchFile( $title, $options = [] ) {
+               wfDeprecated( __METHOD__, '1.32' );
                return $this->fetchFileAndTitle( $title, $options )[0];
        }
 
@@ -3990,7 +4005,7 @@ class Parser {
         */
        public function doDoubleUnderscore( $text ) {
                # The position of __TOC__ needs to be recorded
-               $mw = MagicWord::get( 'toc' );
+               $mw = $this->magicWordFactory->get( 'toc' );
                if ( $mw->match( $text ) ) {
                        $this->mShowToc = true;
                        $this->mForceTocPosition = true;
@@ -4003,7 +4018,7 @@ class Parser {
                }
 
                # Now match and remove the rest of them
-               $mwa = MagicWord::getDoubleUnderscoreArray();
+               $mwa = $this->magicWordFactory->getDoubleUnderscoreArray();
                $this->mDoubleUnderscores = $mwa->matchAndRemove( $text );
 
                if ( isset( $this->mDoubleUnderscores['nogallery'] ) ) {
@@ -4221,6 +4236,13 @@ class Parser {
                        # Avoid insertion of weird stuff like <math> by expanding the relevant sections
                        $safeHeadline = $this->mStripState->unstripBoth( $safeHeadline );
 
+                       # Remove any <style> or <script> tags (T198618)
+                       $safeHeadline = preg_replace(
+                               '#<(style|script)(?: [^>]*[^>/])?>.*?</\1>#is',
+                               '',
+                               $safeHeadline
+                       );
+
                        # Strip out HTML (first regex removes any tag not allowed)
                        # Allowed tags are:
                        # * <sup> and <sub> (T10393)
@@ -4647,7 +4669,7 @@ class Parser {
 
                # @todo FIXME: Regex doesn't respect extension tags or nowiki
                #  => Move this logic to braceSubstitution()
-               $substWord = MagicWord::get( 'subst' );
+               $substWord = $this->magicWordFactory->get( 'subst' );
                $substRegex = '/\{\{(?!(?:' . $substWord->getBaseRegex() . '))/x' . $substWord->getRegexCase();
                $substText = '{{' . $substWord->getSynonym( 0 );
 
@@ -4764,7 +4786,7 @@ class Parser {
                if ( preg_match( '/[<>\r\n]/', $tag, $m ) ) {
                        throw new MWException( "Invalid character {$m[0]} in setHook('$tag', ...) call" );
                }
-               $oldVal = isset( $this->mTagHooks[$tag] ) ? $this->mTagHooks[$tag] : null;
+               $oldVal = $this->mTagHooks[$tag] ?? null;
                $this->mTagHooks[$tag] = $callback;
                if ( !in_array( $tag, $this->mStripList ) ) {
                        $this->mStripList[] = $tag;
@@ -4795,7 +4817,7 @@ class Parser {
                if ( preg_match( '/[<>\r\n]/', $tag, $m ) ) {
                        throw new MWException( "Invalid character {$m[0]} in setTransparentHook('$tag', ...) call" );
                }
-               $oldVal = isset( $this->mTransparentTagHooks[$tag] ) ? $this->mTransparentTagHooks[$tag] : null;
+               $oldVal = $this->mTransparentTagHooks[$tag] ?? null;
                $this->mTransparentTagHooks[$tag] = $callback;
 
                return $oldVal;
@@ -4860,7 +4882,7 @@ class Parser {
                $this->mFunctionHooks[$id] = [ $callback, $flags ];
 
                # Add to function cache
-               $mw = MagicWord::get( $id );
+               $mw = $this->magicWordFactory->get( $id );
                if ( !$mw ) {
                        throw new MWException( __METHOD__ . '() expecting a magic word identifier.' );
                }
@@ -4910,8 +4932,7 @@ class Parser {
                if ( preg_match( '/[<>\r\n]/', $tag, $m ) ) {
                        throw new MWException( "Invalid character {$m[0]} in setFunctionTagHook('$tag', ...) call" );
                }
-               $old = isset( $this->mFunctionTagHooks[$tag] ) ?
-                       $this->mFunctionTagHooks[$tag] : null;
+               $old = $this->mFunctionTagHooks[$tag] ?? null;
                $this->mFunctionTagHooks[$tag] = [ $callback, $flags ];
 
                if ( !in_array( $tag, $this->mStripList ) ) {
@@ -5045,7 +5066,7 @@ class Parser {
                                unset( $paramMap['img_width'] );
                        }
 
-                       $mwArray = new MagicWordArray( array_keys( $paramMap ) );
+                       $mwArray = $this->magicWordFactory->newArray( array_keys( $paramMap ) );
 
                        $label = '';
                        $alt = '';
@@ -5164,7 +5185,8 @@ class Parser {
                                }
                        }
                        $this->mImageParams[$handlerClass] = $paramMap;
-                       $this->mImageParamsMagicArray[$handlerClass] = new MagicWordArray( array_keys( $paramMap ) );
+                       $this->mImageParamsMagicArray[$handlerClass] =
+                               $this->magicWordFactory->newArray( array_keys( $paramMap ) );
                }
                return [ $this->mImageParams[$handlerClass], $this->mImageParamsMagicArray[$handlerClass] ];
        }
@@ -5378,7 +5400,7 @@ class Parser {
                Hooks::run( 'ParserMakeImageParams', [ $title, $file, &$params, $this ] );
 
                # Linker does the rest
-               $time = isset( $options['time'] ) ? $options['time'] : false;
+               $time = $options['time'] ?? false;
                $ret = Linker::makeImageLink( $this, $title, $file, $params['frame'], $params['handler'],
                        $time, $descQuery, $this->mOptions->getThumbSize() );
 
index 353825a..93f4246 100644 (file)
@@ -61,12 +61,9 @@ class ParserDiffTest {
                $results = [];
                $mismatch = false;
                $lastResult = null;
-               $first = true;
-               foreach ( $this->parsers as $i => $parser ) {
-                       $currentResult = call_user_func_array( [ &$this->parsers[$i], $name ], $args );
-                       if ( $first ) {
-                               $first = false;
-                       } else {
+               foreach ( $this->parsers as $parser ) {
+                       $currentResult = $parser->$name( ...$args );
+                       if ( count( $results ) > 0 ) {
                                if ( is_object( $lastResult ) ) {
                                        if ( $lastResult != $currentResult ) {
                                                $mismatch = true;
@@ -77,7 +74,7 @@ class ParserDiffTest {
                                        }
                                }
                        }
-                       $results[$i] = $currentResult;
+                       $results[] = $currentResult;
                        $lastResult = $currentResult;
                }
                if ( $mismatch ) {
index 20bd599..e4b064e 100644 (file)
@@ -20,6 +20,8 @@
  * @file
  * @ingroup Parser
  */
+
+use MediaWiki\MediaWikiServices;
 use Wikimedia\ScopedCallback;
 
 /**
@@ -39,6 +41,13 @@ use Wikimedia\ScopedCallback;
  */
 class ParserOptions {
 
+       /**
+        * Flag indicating that newCanonical() accepts an IContextSource or the string 'canonical', for
+        * back-compat checks from extensions.
+        * @since 1.32
+        */
+       const HAS_NEWCANONICAL_FROM_CONTEXT = 1;
+
        /**
         * Default values for all options that are relevant for caching.
         * @see self::getDefaults()
@@ -657,7 +666,7 @@ class ParserOptions {
        /**
         * Get the user language used by the parser for this page and split the parser cache.
         *
-        * @warning: Calling this causes the parser cache to be fragmented by user language!
+        * @warning Calling this causes the parser cache to be fragmented by user language!
         * To avoid cache fragmentation, output should not depend on the user language.
         * Use Parser::getFunctionLang() or Parser::getTargetLanguage() instead!
         *
@@ -678,7 +687,7 @@ class ParserOptions {
        /**
         * Same as getUserLangObj() but returns a string instead.
         *
-        * @warning: Calling this causes the parser cache to be fragmented by user language!
+        * @warning Calling this causes the parser cache to be fragmented by user language!
         * To avoid cache fragmentation, output should not depend on the user language.
         * Use Parser::getFunctionLang() or Parser::getTargetLanguage() instead!
         *
@@ -928,10 +937,9 @@ class ParserOptions {
 
        /**
         * @warning For interaction with the parser cache, use
-        *  WikiPage::makeParserOptions(), ContentHandler::makeParserOptions(), or
-        *  ParserOptions::newCanonical() instead.
-        * @param User $user
-        * @param Language $lang
+        *  WikiPage::makeParserOptions() or ParserOptions::newCanonical() instead.
+        * @param User|null $user
+        * @param Language|null $lang
         */
        public function __construct( $user = null, $lang = null ) {
                if ( $user === null ) {
@@ -955,8 +963,7 @@ class ParserOptions {
        /**
         * Get a ParserOptions object for an anonymous user
         * @warning For interaction with the parser cache, use
-        *  WikiPage::makeParserOptions(), ContentHandler::makeParserOptions(), or
-        *  ParserOptions::newCanonical() instead.
+        *  WikiPage::makeParserOptions() or ParserOptions::newCanonical() instead.
         * @since 1.27
         * @return ParserOptions
         */
@@ -970,8 +977,7 @@ class ParserOptions {
         * Language will be taken from $wgLang.
         *
         * @warning For interaction with the parser cache, use
-        *  WikiPage::makeParserOptions(), ContentHandler::makeParserOptions(), or
-        *  ParserOptions::newCanonical() instead.
+        *  WikiPage::makeParserOptions() or ParserOptions::newCanonical() instead.
         * @param User $user
         * @return ParserOptions
         */
@@ -983,8 +989,7 @@ class ParserOptions {
         * Get a ParserOptions object from a given user and language
         *
         * @warning For interaction with the parser cache, use
-        *  WikiPage::makeParserOptions(), ContentHandler::makeParserOptions(), or
-        *  ParserOptions::newCanonical() instead.
+        *  WikiPage::makeParserOptions() or ParserOptions::newCanonical() instead.
         * @param User $user
         * @param Language $lang
         * @return ParserOptions
@@ -997,8 +1002,7 @@ class ParserOptions {
         * Get a ParserOptions object from a IContextSource object
         *
         * @warning For interaction with the parser cache, use
-        *  WikiPage::makeParserOptions(), ContentHandler::makeParserOptions(), or
-        *  ParserOptions::newCanonical() instead.
+        *  WikiPage::makeParserOptions() or ParserOptions::newCanonical() instead.
         * @param IContextSource $context
         * @return ParserOptions
         */
@@ -1013,12 +1017,29 @@ class ParserOptions {
         * different from the canonical values used for caching.
         *
         * @since 1.30
-        * @param User|null $user
-        * @param Language|StubObject|null $lang
+        * @since 1.32 Added string and IContextSource as options for the first parameter
+        * @param IContextSource|string|User|null $context
+        *  - If an IContextSource, the options are initialized based on the source's User and Language.
+        *  - If the string 'canonical', the options are initialized with an anonymous user and
+        *    $wgContLang.
+        *  - If a User or null, the options are initialized for that User (or $wgUser if null).
+        *    'userlang' is taken from the $userLang parameter, defaulting to $wgLang if that is null.
+        * @param Language|StubObject|null $userLang (see above)
         * @return ParserOptions
         */
-       public static function newCanonical( User $user = null, $lang = null ) {
-               $ret = new ParserOptions( $user, $lang );
+       public static function newCanonical( $context = null, $userLang = null ) {
+               if ( $context instanceof IContextSource ) {
+                       $ret = self::newFromContext( $context );
+               } elseif ( $context === 'canonical' ) {
+                       $ret = self::newFromAnon();
+               } elseif ( $context instanceof User || $context === null ) {
+                       $ret = new self( $context, $userLang );
+               } else {
+                       throw new InvalidArgumentException(
+                               '$context must be an IContextSource, the string "canonical", a User, or null'
+                       );
+               }
+
                foreach ( self::getCanonicalOverrides() as $k => $v ) {
                        $ret->setOption( $k, $v );
                }
@@ -1269,7 +1290,7 @@ class ParserOptions {
         *
         * @since 1.17
         * @param string[] $forOptions
-        * @param Title $title Used to get the content language of the page (since r97636)
+        * @param Title|null $title Used to get the content language of the page (since r97636)
         * @return string Page rendering hash
         */
        public function optionsHash( $forOptions, $title = null ) {
@@ -1386,11 +1407,12 @@ class ParserOptions {
                        };
                end( $wgHooks['TitleExists'] );
                $key = key( $wgHooks['TitleExists'] );
-               LinkCache::singleton()->clearBadLink( $title->getPrefixedDBkey() );
-               return new ScopedCallback( function () use ( $title, $key ) {
+               $linkCache = MediaWikiServices::getInstance()->getLinkCache();
+               $linkCache->clearBadLink( $title->getPrefixedDBkey() );
+               return new ScopedCallback( function () use ( $title, $key, $linkCache ) {
                        global $wgHooks;
                        unset( $wgHooks['TitleExists'][$key] );
-                       LinkCache::singleton()->clearLink( $title );
+                       $linkCache->clearLink( $title );
                } );
        }
 }
index fc36659..182648a 100644 (file)
@@ -311,10 +311,10 @@ class ParserOutput extends CacheTime {
                                        }
 
                                        $skin = $wgOut->getSkin();
-                                       return call_user_func_array(
-                                               [ $skin, 'doEditSectionLink' ],
-                                               [ $editsectionPage, $editsectionSection,
-                                                       $editsectionContent, $wgLang->getCode() ]
+                                       return $skin->doEditSectionLink( $editsectionPage,
+                                               $editsectionSection,
+                                               $editsectionContent,
+                                               $wgLang->getCode()
                                        );
                                },
                                $text
@@ -770,7 +770,7 @@ class ParserOutput extends CacheTime {
         * Add one or more variables to be set in mw.config in JavaScript.
         *
         * @param string|array $keys Key or array of key/value pairs.
-        * @param mixed $value [optional] Value of the configuration variable.
+        * @param mixed|null $value [optional] Value of the configuration variable.
         * @since 1.23
         */
        public function addJsConfigVars( $keys, $value = null ) {
@@ -959,7 +959,7 @@ class ParserOutput extends CacheTime {
         * @note You need to use getProperties() to check for boolean and null properties.
         */
        public function getProperty( $name ) {
-               return isset( $this->mProperties[$name] ) ? $this->mProperties[$name] : false;
+               return $this->mProperties[$name] ?? false;
        }
 
        public function unsetProperty( $name ) {
index 49e961a..b6084d8 100644 (file)
@@ -171,7 +171,8 @@ interface PPFrame {
        const RECOVER_COMMENTS = 16;
        const NO_TAGS = 32;
 
-       const RECOVER_ORIG = 59; // = 1|2|8|16|32 no constant expression support in PHP yet
+       const RECOVER_ORIG = self::NO_ARGS | self::NO_TEMPLATES | self::NO_IGNORE |
+               self::RECOVER_COMMENTS | self::NO_TAGS;
 
        /** This constant exists when $indexOffset is supported in newChild() */
        const SUPPORTS_INDEX_OFFSET = 1;
index 104cd13..d00c40f 100644 (file)
@@ -1547,7 +1547,7 @@ class PPFrame_DOM implements PPFrame {
                if ( $level === false ) {
                        return $this->title->getPrefixedDBkey();
                } else {
-                       return isset( $this->titleCache[$level] ) ? $this->titleCache[$level] : false;
+                       return $this->titleCache[$level] ?? false;
                }
        }
 
index 8e74380..0326499 100644 (file)
@@ -1368,7 +1368,7 @@ class PPFrame_Hash implements PPFrame {
                if ( $level === false ) {
                        return $this->title->getPrefixedDBkey();
                } else {
-                       return isset( $this->titleCache[$level] ) ? $this->titleCache[$level] : false;
+                       return $this->titleCache[$level] ?? false;
                }
        }
 
index 118442d..4614402 100644 (file)
@@ -463,12 +463,12 @@ class Sanitizer {
         * Cleans up HTML, removes dangerous tags and attributes, and
         * removes HTML comments
         * @param string $text
-        * @param callable $processCallback Callback to do any variable or parameter
+        * @param callable|null $processCallback Callback to do any variable or parameter
         *   replacements in HTML attribute values
         * @param array|bool $args Arguments for the processing callback
         * @param array $extratags For any extra tags to include
         * @param array $removetags For any tags (default or extra) to exclude
-        * @param callable $warnCallback (Deprecated) Callback allowing the
+        * @param callable|null $warnCallback (Deprecated) Callback allowing the
         *   addition of a tracking category when bad input is encountered.
         *   DO NOT ADD NEW PARAMETERS AFTER $warnCallback, since it will be
         *   removed shortly.
@@ -1141,6 +1141,28 @@ class Sanitizer {
                return $encValue;
        }
 
+       /**
+        * Armor French spaces with a replacement character
+        *
+        * @since 1.32
+        * @param string $text Text to armor
+        * @param string $space Space character for the French spaces, defaults to '&#160;'
+        * @return string Armored text
+        */
+       public static function armorFrenchSpaces( $text, $space = '&#160;' ) {
+               // Replace $ with \$ and \ with \\
+               $space = preg_replace( '#(?<!\\\\)(\\$|\\\\)#', '\\\\$1', $space );
+               $fixtags = [
+                       # French spaces, last one Guillemet-left
+                       # only if there is something before the space
+                       # and a non-word character after the punctuation.
+                       '/(\S) (?=[?:;!%»›](?!\w))/u' => "\\1$space",
+                       # French spaces, Guillemet-right
+                       '/([«‹]) /u' => "\\1$space",
+               ];
+               return preg_replace( array_keys( $fixtags ), array_values( $fixtags ), $text );
+       }
+
        /**
         * Encode an attribute value for HTML tags, with extra armoring
         * against further wiki processing.
@@ -1168,6 +1190,9 @@ class Sanitizer {
                        '__'   => '&#95;_',
                ] );
 
+               # Armor against French spaces detection (T5158)
+               $encValue = self::armorFrenchSpaces( $encValue, '&#32;' );
+
                # Stupid hack
                $encValue = preg_replace_callback(
                        '/((?i)' . wfUrlProtocols() . ')/',
@@ -1706,9 +1731,7 @@ class Sanitizer {
         */
        static function attributeWhitelist( $element ) {
                $list = self::setupAttributeWhitelist();
-               return isset( $list[$element] )
-                       ? $list[$element]
-                       : [];
+               return $list[$element] ?? [];
        }
 
        /**
index f811e3f..4ba34ef 100644 (file)
@@ -65,7 +65,7 @@ class BcryptPassword extends ParameterizedPassword {
                                // Replace + with ., because bcrypt uses a non-MIME base64 format
                                strtr(
                                        // Random base64 encoded string
-                                       base64_encode( MWCryptRand::generate( 16, true ) ),
+                                       base64_encode( random_bytes( 16 ) ),
                                        '+', '.'
                                ),
                                0, 22
index 0ea3c63..d1774ba 100644 (file)
@@ -60,7 +60,7 @@ class EncryptedPassword extends ParameterizedPassword {
                if ( count( $this->args ) ) {
                        $iv = base64_decode( $this->args[0] );
                } else {
-                       $iv = MWCryptRand::generate( openssl_cipher_iv_length( $this->params['cipher'] ), true );
+                       $iv = random_bytes( openssl_cipher_iv_length( $this->params['cipher'] ) );
                }
 
                $this->hash = openssl_encrypt(
@@ -102,7 +102,7 @@ class EncryptedPassword extends ParameterizedPassword {
                $this->params = $this->getDefaultParams();
 
                // Check the key size with the new params
-               $iv = MWCryptRand::generate( openssl_cipher_iv_length( $this->params['cipher'] ), true );
+               $iv = random_bytes( openssl_cipher_iv_length( $this->params['cipher'] ) );
                $this->hash = openssl_encrypt(
                                $underlyingHash,
                                $this->params['cipher'],
index 4a8831e..6065045 100644 (file)
@@ -42,13 +42,12 @@ class Pbkdf2Password extends ParameterizedPassword {
        }
 
        protected function shouldUseHashExtension() {
-               return isset( $this->config['use-hash-extension'] ) ?
-                       $this->config['use-hash-extension'] : function_exists( 'hash_pbkdf2' );
+               return $this->config['use-hash-extension'] ?? function_exists( 'hash_pbkdf2' );
        }
 
        public function crypt( $password ) {
                if ( count( $this->args ) == 0 ) {
-                       $this->args[] = base64_encode( MWCryptRand::generate( 16, true ) );
+                       $this->args[] = base64_encode( random_bytes( 16 ) );
                }
 
                if ( $this->shouldUseHashExtension() ) {
index 9515f25..f5fa4c7 100644 (file)
@@ -85,7 +85,9 @@ class PoolCounterRedis extends PoolCounter {
                parent::__construct( $conf, $type, $key );
 
                $this->serversByLabel = $conf['servers'];
-               $this->ring = new HashRing( array_fill_keys( array_keys( $conf['servers'] ), 100 ) );
+
+               $serverLabels = array_keys( $conf['servers'] );
+               $this->ring = new HashRing( array_fill_keys( $serverLabels, 10 ) );
 
                $conf['redisConfig']['serializer'] = 'none'; // for use with Lua
                $this->pool = RedisConnectionPool::singleton( $conf['redisConfig'] );
index a570d78..16e4397 100644 (file)
@@ -150,9 +150,7 @@ abstract class PoolCounterWork {
                                        PoolCounter::QUEUE_FULL => 'pool-queuefull',
                                        PoolCounter::TIMEOUT => 'pool-timeout' ];
 
-                               $status = Status::newFatal( isset( $errors[$status->value] )
-                                       ? $errors[$status->value]
-                                       : 'pool-errorunknown' );
+                               $status = Status::newFatal( $errors[$status->value] ?? 'pool-errorunknown' );
                                $this->logError( $status );
                                return $this->error( $status );
                }
index 834b8b1..aed52d1 100644 (file)
@@ -66,26 +66,26 @@ class PoolCounterWorkViaCallback extends PoolCounterWork {
        }
 
        public function doWork() {
-               return call_user_func_array( $this->doWork, [] );
+               return ( $this->doWork )();
        }
 
        public function getCachedWork() {
                if ( $this->doCachedWork ) {
-                       return call_user_func_array( $this->doCachedWork, [] );
+                       return ( $this->doCachedWork )();
                }
                return false;
        }
 
        public function fallback() {
                if ( $this->fallback ) {
-                       return call_user_func_array( $this->fallback, [] );
+                       return ( $this->fallback )();
                }
                return false;
        }
 
        public function error( $status ) {
                if ( $this->error ) {
-                       return call_user_func_array( $this->error, [ $status ] );
+                       return ( $this->error )( $status );
                }
                return false;
        }
index 7b888ab..4af86ae 100644 (file)
@@ -53,7 +53,7 @@ class PoolWorkArticleView extends PoolCounterWork {
         * @param int $revid ID of the revision being parsed.
         * @param bool $useParserCache Whether to use the parser cache.
         *   operation.
-        * @param Content|string $content Content to parse or null to load it; may
+        * @param Content|string|null $content Content to parse or null to load it; may
         *   also be given as a wikitext string, for BC.
         */
        public function __construct( WikiPage $page, ParserOptions $parserOptions,
index d5a706a..830da06 100644 (file)
@@ -20,7 +20,6 @@
 
 namespace MediaWiki\Preferences;
 
-use CentralIdLookup;
 use Config;
 use DateTime;
 use DateTimeZone;
@@ -45,8 +44,7 @@ use MWTimestamp;
 use OutputPage;
 use Parser;
 use ParserOptions;
-use PreferencesForm;
-use PreferencesFormOOUI;
+use PreferencesFormLegacy;
 use Psr\Log\LoggerAwareTrait;
 use Psr\Log\NullLogger;
 use Skin;
@@ -54,6 +52,7 @@ use SpecialPage;
 use SpecialPreferences;
 use Status;
 use Title;
+use UnexpectedValueException;
 use User;
 use UserGroupMembership;
 use Xml;
@@ -95,22 +94,6 @@ class DefaultPreferencesFactory implements PreferencesFactory {
                $this->logger = new NullLogger();
        }
 
-       /**
-        * @return callable[]
-        */
-       protected function getSaveFilters() {
-               // Wrap intval() so that we can pass it multiple parameters and treat all filters the same.
-               $intvalFilter = function ( $value, $alldata ) {
-                       return intval( $value );
-               };
-               return [
-                       'timecorrection' => [ $this, 'filterTimezoneInput' ],
-                       'rclimit' => $intvalFilter,
-                       'wllimit' => $intvalFilter,
-                       'searchlimit' => $intvalFilter,
-               ];
-       }
-
        /**
         * @inheritDoc
         */
@@ -179,16 +162,16 @@ class DefaultPreferencesFactory implements PreferencesFactory {
                $disable = !$user->isAllowed( 'editmyoptions' );
 
                $defaultOptions = User::getDefaultOptions();
+               $userOptions = $user->getOptions();
+               $this->applyFilters( $userOptions, $defaultPreferences, 'filterForForm' );
                # # Prod in defaults from the user
                foreach ( $defaultPreferences as $name => &$info ) {
-                       $prefFromUser = $this->getOptionFromUser( $name, $info, $user );
+                       $prefFromUser = $this->getOptionFromUser( $name, $info, $userOptions );
                        if ( $disable && !in_array( $name, $this->getSaveBlacklist() ) ) {
                                $info['disabled'] = 'disabled';
                        }
                        $field = HTMLForm::loadInputFromParameters( $name, $info, $dummyForm ); // For validation
-                       $globalDefault = isset( $defaultOptions[$name] )
-                               ? $defaultOptions[$name]
-                               : null;
+                       $globalDefault = $defaultOptions[$name] ?? null;
 
                        // If it validates, set it as the default
                        if ( isset( $info['default'] ) ) {
@@ -212,21 +195,21 @@ class DefaultPreferencesFactory implements PreferencesFactory {
         *
         * @param string $name
         * @param array $info
-        * @param User $user
+        * @param array $userOptions
         * @return array|string
         */
-       protected function getOptionFromUser( $name, $info, User $user ) {
-               $val = $user->getOption( $name );
+       protected function getOptionFromUser( $name, $info, array $userOptions ) {
+               $val = $userOptions[$name] ?? null;
 
                // Handling for multiselect preferences
                if ( ( isset( $info['type'] ) && $info['type'] == 'multiselect' ) ||
                                ( isset( $info['class'] ) && $info['class'] == \HTMLMultiSelectField::class ) ) {
                        $options = HTMLFormField::flattenOptions( $info['options'] );
-                       $prefix = isset( $info['prefix'] ) ? $info['prefix'] : $name;
+                       $prefix = $info['prefix'] ?? $name;
                        $val = [];
 
                        foreach ( $options as $value ) {
-                               if ( $user->getOption( "$prefix$value" ) ) {
+                               if ( $userOptions["$prefix$value"] ?? false ) {
                                        $val[] = $value;
                                }
                        }
@@ -237,12 +220,12 @@ class DefaultPreferencesFactory implements PreferencesFactory {
                                ( isset( $info['class'] ) && $info['class'] == \HTMLCheckMatrix::class ) ) {
                        $columns = HTMLFormField::flattenOptions( $info['columns'] );
                        $rows = HTMLFormField::flattenOptions( $info['rows'] );
-                       $prefix = isset( $info['prefix'] ) ? $info['prefix'] : $name;
+                       $prefix = $info['prefix'] ?? $name;
                        $val = [];
 
                        foreach ( $columns as $column ) {
                                foreach ( $rows as $row ) {
-                                       if ( $user->getOption( "$prefix$column-$row" ) ) {
+                                       if ( $userOptions["$prefix$column-$row"] ?? false ) {
                                                $val[] = "$column-$row";
                                        }
                                }
@@ -409,7 +392,7 @@ class DefaultPreferencesFactory implements PreferencesFactory {
                }
 
                // Language
-               $languages = Language::fetchLanguageNames( null, 'mw' );
+               $languages = Language::fetchLanguageNames( null, 'mwfile' );
                $languageCode = $this->config->get( 'LanguageCode' );
                if ( !array_key_exists( $languageCode, $languages ) ) {
                        $languages[$languageCode] = $languageCode;
@@ -447,12 +430,11 @@ class DefaultPreferencesFactory implements PreferencesFactory {
                if ( !$this->config->get( 'DisableLangConversion' ) ) {
                        foreach ( LanguageConverter::$languagesWithVariants as $langCode ) {
                                if ( $langCode == $this->contLang->getCode() ) {
-                                       $variants = $this->contLang->getVariants();
-
-                                       if ( count( $variants ) <= 1 ) {
+                                       if ( !$this->contLang->hasVariants() ) {
                                                continue;
                                        }
 
+                                       $variants = $this->contLang->getVariants();
                                        $variantArray = [];
                                        foreach ( $variants as $v ) {
                                                $v = str_replace( '_', '-', strtolower( $v ) );
@@ -657,16 +639,12 @@ class DefaultPreferencesFactory implements PreferencesFactory {
                                ];
 
                                if ( $this->config->get( 'EnableUserEmailBlacklist' ) ) {
-                                       $lookup = CentralIdLookup::factory();
-                                       $ids = $user->getOption( 'email-blacklist', [] );
-                                       $names = $ids ? $lookup->namesFromCentralIds( $ids, $user ) : [];
-
                                        $defaultPreferences['email-blacklist'] = [
                                                'type' => 'usersmultiselect',
                                                'label-message' => 'email-blacklist-label',
                                                'section' => 'personal/email',
-                                               'default' => implode( "\n", $names ),
                                                'disabled' => $disableEmailPrefs,
+                                               'filter' => MultiUsernameFilter::class,
                                        ];
                                }
                        }
@@ -854,6 +832,7 @@ class DefaultPreferencesFactory implements PreferencesFactory {
                        'size' => 20,
                        'section' => 'rendering/timeoffset',
                        'id' => 'wpTimeCorrection',
+                       'filter' => TimezoneFilter::class,
                ];
        }
 
@@ -1014,6 +993,7 @@ class DefaultPreferencesFactory implements PreferencesFactory {
                        'label-message' => 'recentchangescount',
                        'help-message' => 'prefs-help-recentchangescount',
                        'section' => 'rc/displayrc',
+                       'filter' => IntvalFilter::class,
                ];
                $defaultPreferences['usenewrc'] = [
                        'type' => 'toggle',
@@ -1025,6 +1005,12 @@ class DefaultPreferencesFactory implements PreferencesFactory {
                        'label-message' => 'tog-hideminor',
                        'section' => 'rc/advancedrc',
                ];
+               $defaultPreferences['rcfilters-rc-collapsed'] = [
+                       'type' => 'api',
+               ];
+               $defaultPreferences['rcfilters-wl-collapsed'] = [
+                       'type' => 'api',
+               ];
                $defaultPreferences['rcfilters-saved-queries'] = [
                        'type' => 'api',
                ];
@@ -1077,7 +1063,7 @@ class DefaultPreferencesFactory implements PreferencesFactory {
                if ( $this->config->get( 'StructuredChangeFiltersShowPreference' ) ) {
                        $defaultPreferences['rcenhancedfilters-disable'] = [
                                'type' => 'toggle',
-                               'section' => 'rc/opt-out',
+                               'section' => 'rc/optoutrc',
                                'label-message' => 'rcfilters-preference-label',
                                'help-message' => 'rcfilters-preference-help',
                        ];
@@ -1151,6 +1137,7 @@ class DefaultPreferencesFactory implements PreferencesFactory {
                        'label-message' => 'prefs-watchlist-edits',
                        'help' => $context->msg( 'prefs-watchlist-edits-max' )->escaped(),
                        'section' => 'watchlist/displaywatchlist',
+                       'filter' => IntvalFilter::class,
                ];
                $defaultPreferences['extendwatchlist'] = [
                        'type' => 'toggle',
@@ -1276,6 +1263,15 @@ class DefaultPreferencesFactory implements PreferencesFactory {
                                'help-message' => 'prefs-help-watchlist-token2',
                        ];
                }
+
+               if ( $this->config->get( 'StructuredChangeFiltersShowWatchlistPreference' ) ) {
+                       $defaultPreferences['wlenhancedfilters-disable'] = [
+                               'type' => 'toggle',
+                               'section' => 'watchlist/optoutwatchlist',
+                               'label-message' => 'rcfilters-watchlist-preference-label',
+                               'help-message' => 'rcfilters-watchlist-preference-help',
+                       ];
+               }
        }
 
        /**
@@ -1412,8 +1408,8 @@ class DefaultPreferencesFactory implements PreferencesFactory {
                $pixels = $l10n->msg( 'unit-pixel' )->text();
 
                foreach ( $this->config->get( 'ImageLimits' ) as $index => $limits ) {
-                       // Note: A left-to-right marker (\u200e) is inserted, see T144386
-                       $display = "{$limits[0]}" . json_decode( '"\u200e"' ) . "×{$limits[1]}" . $pixels;
+                       // Note: A left-to-right marker (U+200E) is inserted, see T144386
+                       $display = "{$limits[0]}\u{200E}×{$limits[1]}$pixels";
                        $ret[$display] = $index;
                }
 
@@ -1484,12 +1480,12 @@ class DefaultPreferencesFactory implements PreferencesFactory {
         * @param IContextSource $context
         * @param string $formClass
         * @param array $remove Array of items to remove
-        * @return PreferencesForm
+        * @return HTMLForm
         */
        public function getForm(
                User $user,
                IContextSource $context,
-               $formClass = PreferencesFormOOUI::class,
+               $formClass = PreferencesFormLegacy::class,
                array $remove = []
        ) {
                if ( SpecialPreferences::isOouiEnabled( $context ) ) {
@@ -1511,7 +1507,7 @@ class DefaultPreferencesFactory implements PreferencesFactory {
                }
 
                /**
-                * @var $htmlForm PreferencesForm
+                * @var $htmlForm HTMLForm
                 */
                $htmlForm = new $formClass( $formDescriptor, $context, 'prefs' );
 
@@ -1522,9 +1518,11 @@ class DefaultPreferencesFactory implements PreferencesFactory {
                # Used message keys: 'accesskey-preferences-save', 'tooltip-preferences-save'
                $htmlForm->setSubmitTooltip( 'preferences-save' );
                $htmlForm->setSubmitID( 'prefcontrol' );
-               $htmlForm->setSubmitCallback( function ( array $formData, PreferencesForm $form ) {
-                       return $this->submitForm( $formData, $form );
-               } );
+               $htmlForm->setSubmitCallback(
+                       function ( array $formData, HTMLForm $form ) use ( $formDescriptor ) {
+                               return $this->submitForm( $formData, $form, $formDescriptor );
+                       }
+               );
 
                return $htmlForm;
        }
@@ -1573,64 +1571,16 @@ class DefaultPreferencesFactory implements PreferencesFactory {
                return $opt;
        }
 
-       /**
-        * @param string $tz
-        * @param array $alldata
-        * @return string
-        */
-       protected function filterTimezoneInput( $tz, array $alldata ) {
-               $data = explode( '|', $tz, 3 );
-               switch ( $data[0] ) {
-                       case 'ZoneInfo':
-                               $valid = false;
-
-                               if ( count( $data ) === 3 ) {
-                                       // Make sure this timezone exists
-                                       try {
-                                               new DateTimeZone( $data[2] );
-                                               // If the constructor didn't throw, we know it's valid
-                                               $valid = true;
-                                       } catch ( Exception $e ) {
-                                               // Not a valid timezone
-                                       }
-                               }
-
-                               if ( !$valid ) {
-                                       // If the supplied timezone doesn't exist, fall back to the encoded offset
-                                       return 'Offset|' . intval( $tz[1] );
-                               }
-                               return $tz;
-                       case 'System':
-                               return $tz;
-                       default:
-                               $data = explode( ':', $tz, 2 );
-                               if ( count( $data ) == 2 ) {
-                                       $data[0] = intval( $data[0] );
-                                       $data[1] = intval( $data[1] );
-                                       $minDiff = abs( $data[0] ) * 60 + $data[1];
-                                       if ( $data[0] < 0 ) {
-                                               $minDiff = - $minDiff;
-                                       }
-                               } else {
-                                       $minDiff = intval( $data[0] ) * 60;
-                               }
-
-                               # Max is +14:00 and min is -12:00, see:
-                               # https://en.wikipedia.org/wiki/Timezone
-                               $minDiff = min( $minDiff, 840 );  # 14:00
-                               $minDiff = max( $minDiff, -720 ); # -12:00
-                               return 'Offset|' . $minDiff;
-               }
-       }
-
        /**
         * Handle the form submission if everything validated properly
         *
         * @param array $formData
-        * @param PreferencesForm $form
+        * @param HTMLForm $form
+        * @param array[] $formDescriptor
         * @return bool|Status|string
         */
-       protected function saveFormData( $formData, PreferencesForm $form ) {
+       protected function saveFormData( $formData, HTMLForm $form, array $formDescriptor ) {
+               /** @var \User $user */
                $user = $form->getModifiedUser();
                $hiddenPrefs = $this->config->get( 'HiddenPrefs' );
                $result = true;
@@ -1640,12 +1590,7 @@ class DefaultPreferencesFactory implements PreferencesFactory {
                }
 
                // Filter input
-               foreach ( array_keys( $formData ) as $name ) {
-                       $filters = $this->getSaveFilters();
-                       if ( isset( $filters[$name] ) ) {
-                               $formData[$name] = call_user_func( $filters[$name], $formData[$name], $formData );
-                       }
-               }
+               $this->applyFilters( $formData, $formDescriptor, 'filterFromForm' );
 
                // Fortunately, the realname field is MUCH simpler
                // (not really "private", but still shouldn't be edited without permission)
@@ -1702,31 +1647,47 @@ class DefaultPreferencesFactory implements PreferencesFactory {
        }
 
        /**
-        * DO NOT USE. Temporary function to punch hole for the Preferences class.
-        *
-        * @deprecated since 1.31, its inception
+        * Applies filters to preferences either before or after form usage
         *
-        * @param array $formData
-        * @param PreferencesForm $form
-        * @return bool|Status|string
+        * @param array &$preferences
+        * @param array $formDescriptor
+        * @param string $verb Name of the filter method to call, either 'filterFromForm' or
+        *              'filterForForm'
         */
-       public function legacySaveFormData( $formData, PreferencesForm $form ) {
-               return $this->saveFormData( $formData, $form );
+       protected function applyFilters( array &$preferences, array $formDescriptor, $verb ) {
+               foreach ( $formDescriptor as $preference => $desc ) {
+                       if ( !isset( $desc['filter'] ) || !isset( $preferences[$preference] ) ) {
+                               continue;
+                       }
+                       $filterDesc = $desc['filter'];
+                       if ( $filterDesc instanceof Filter ) {
+                               $filter = $filterDesc;
+                       } elseif ( class_exists( $filterDesc ) ) {
+                               $filter = new $filterDesc();
+                       } elseif ( is_callable( $filterDesc ) ) {
+                               $filter = $filterDesc();
+                       } else {
+                               throw new UnexpectedValueException(
+                                       "Unrecognized filter type for preference '$preference'"
+                               );
+                       }
+                       $preferences[$preference] = $filter->$verb( $preferences[$preference] );
+               }
        }
 
        /**
         * Save the form data and reload the page
         *
         * @param array $formData
-        * @param PreferencesForm $form
+        * @param HTMLForm $form
+        * @param array $formDescriptor
         * @return Status
         */
-       protected function submitForm( array $formData, PreferencesForm $form ) {
-               $res = $this->saveFormData( $formData, $form );
+       protected function submitForm( array $formData, HTMLForm $form, array $formDescriptor ) {
+               $res = $this->saveFormData( $formData, $form, $formDescriptor );
 
-               if ( $res ) {
+               if ( $res === true ) {
                        $context = $form->getContext();
-
                        $urlOptions = [];
 
                        if ( $res === 'eauth' ) {
@@ -1750,20 +1711,7 @@ class DefaultPreferencesFactory implements PreferencesFactory {
                        $context->getOutput()->redirect( $url );
                }
 
-               return Status::newGood();
-       }
-
-       /**
-        * DO NOT USE. Temporary function to punch hole for the Preferences class.
-        *
-        * @deprecated since 1.31, its inception
-        *
-        * @param array $formData
-        * @param PreferencesForm $form
-        * @return Status
-        */
-       public function legacySubmitForm( array $formData, PreferencesForm $form ) {
-               return $this->submitForm( $formData, $form );
+               return ( $res === true ? Status::newGood() : $res );
        }
 
        /**
diff --git a/includes/preferences/Filter.php b/includes/preferences/Filter.php
new file mode 100644 (file)
index 0000000..670dd5b
--- /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
+ *
+ * @file
+ */
+
+namespace MediaWiki\Preferences;
+
+/**
+ * Base interface for user preference flters that work as a middleware between
+ * storage and interface.
+ */
+interface Filter {
+       /**
+        * @param mixed $value
+        * @return mixed
+        */
+       public function filterForForm( $value );
+
+       /**
+        * @param mixed $value
+        * @return mixed
+        */
+       public function filterFromForm( $value );
+}
diff --git a/includes/preferences/IntvalFilter.php b/includes/preferences/IntvalFilter.php
new file mode 100644 (file)
index 0000000..0dd3fc5
--- /dev/null
@@ -0,0 +1,38 @@
+<?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\Preferences;
+
+class IntvalFilter implements Filter {
+
+       /**
+        * @inheritDoc
+        */
+       public function filterForForm( $value ) {
+               return $value;
+       }
+
+       /**
+        * @inheritDoc
+        */
+       public function filterFromForm( $value ) {
+               return intval( $value );
+       }
+}
diff --git a/includes/preferences/MultiUsernameFilter.php b/includes/preferences/MultiUsernameFilter.php
new file mode 100644 (file)
index 0000000..2d8ae3c
--- /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
+ */
+
+namespace MediaWiki\Preferences;
+
+use CentralIdLookup;
+
+class MultiUsernameFilter implements Filter {
+       /**
+        * @var CentralIdLookup|null
+        */
+       private $lookup;
+       /** @var CentralIdLookup|int User querying central usernames or one of the audience constants */
+       private $userOrAudience;
+
+       /**
+        * @param CentralIdLookup|null $lookup
+        * @param int $userOrAudience
+        */
+       public function __construct( CentralIdLookup $lookup = null,
+               $userOrAudience = CentralIdLookup::AUDIENCE_PUBLIC
+       ) {
+               $this->lookup = $lookup;
+               $this->userOrAudience = $userOrAudience;
+       }
+
+       /**
+        * @inheritDoc
+        */
+       public function filterFromForm( $names ) {
+               $names = trim( $names );
+               if ( $names !== '' ) {
+                       $names = preg_split( '/\n/', $names, -1, PREG_SPLIT_NO_EMPTY );
+                       $ids = $this->getLookup()->centralIdsFromNames( $names, $this->userOrAudience );
+                       if ( $ids ) {
+                               return implode( "\n", $ids );
+                       }
+               }
+               // If the user list is empty, it should be null (don't save) rather than an empty string
+               return null;
+       }
+
+       /**
+        * @inheritDoc
+        */
+       public function filterForForm( $value ) {
+               $ids = self::splitIds( $value );
+               $names = $ids ? $this->getLookup()->namesFromCentralIds( $ids, $this->userOrAudience ) : [];
+               return implode( "\n", $names );
+       }
+
+       /**
+        * Splits a newline separated list of user ids into a
+        *
+        * @param string $str
+        * @return int[]
+        */
+       public static function splitIds( $str ) {
+               return array_map( 'intval', preg_split( '/\n/', $str, -1, PREG_SPLIT_NO_EMPTY ) );
+       }
+
+       /**
+        * @return CentralIdLookup
+        */
+       private function getLookup() {
+               $this->lookup = $this->lookup ?? CentralIdLookup::factory();
+               return $this->lookup;
+       }
+}
index 685f78c..478edce 100644 (file)
@@ -28,8 +28,8 @@ use User;
  * A PreferencesFactory is a MediaWiki service that provides the definitions of preferences for a
  * given user. These definitions are in the form of an HTMLForm descriptor.
  *
- * PreferencesForm (a subclass of HTMLForm) is used to generate the Preferences form, and handles
- * generic submission, CSRF protection, layout and other logic in a reusable manner.
+ * PreferencesFormLegacy (a subclass of HTMLForm) is used to generate the Preferences form, and
+ * handles generic submission, CSRF protection, layout and other logic in a reusable manner.
  *
  * In order to generate the form, the HTMLForm object needs an array structure detailing the
  * form fields available, and that's what this implementations of this interface provide. Each
@@ -62,7 +62,7 @@ interface PreferencesFactory {
        public function getForm(
                User $user,
                IContextSource $contextSource,
-               $formClass = \PreferencesForm::class,
+               $formClass = \PreferencesFormLegacy::class,
                array $remove = []
        );
 
diff --git a/includes/preferences/TimezoneFilter.php b/includes/preferences/TimezoneFilter.php
new file mode 100644 (file)
index 0000000..53f12de
--- /dev/null
@@ -0,0 +1,84 @@
+<?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\Preferences;
+
+use DateTimeZone;
+use Exception;
+
+class TimezoneFilter implements Filter {
+
+       /**
+        * @inheritDoc
+        */
+       public function filterForForm( $value ) {
+               return $value;
+       }
+
+       /**
+        * @inheritDoc
+        */
+       public function filterFromForm( $tz ) {
+               $data = explode( '|', $tz, 3 );
+               switch ( $data[0] ) {
+                       case 'ZoneInfo':
+                               $valid = false;
+
+                               if ( count( $data ) === 3 ) {
+                                       // Make sure this timezone exists
+                                       try {
+                                               new DateTimeZone( $data[2] );
+                                               // If the constructor didn't throw, we know it's valid
+                                               $valid = true;
+                                       } catch ( Exception $e ) {
+                                               // Not a valid timezone
+                                       }
+                               }
+
+                               if ( !$valid ) {
+                                       // If the supplied timezone doesn't exist, fall back to the encoded offset
+                                       return 'Offset|' . intval( $tz[1] );
+                               }
+                               return $tz;
+                       case 'System':
+                               return $tz;
+                       default:
+                               $data = explode( ':', $tz, 2 );
+                               if ( count( $data ) == 2 ) {
+                                       $data[0] = intval( $data[0] );
+                                       $data[1] = intval( $data[1] );
+                                       $minDiff = abs( $data[0] ) * 60 + $data[1];
+                                       if ( $data[0] < 0 ) {
+                                               $minDiff = - $minDiff;
+                                       }
+                               } else {
+                                       $minDiff = intval( $data[0] ) * 60;
+                               }
+
+                               # Max is +14:00 and min is -12:00, see:
+                               # https://en.wikipedia.org/wiki/Timezone
+                               # 14:00
+                               $minDiff = min( $minDiff, 840 );
+                               # -12:00
+                               $minDiff = max( $minDiff, -720 );
+                               return 'Offset|' . $minDiff;
+               }
+       }
+}
index d02011f..bf4ddc7 100644 (file)
@@ -165,7 +165,7 @@ abstract class Profiler {
        abstract public function scopedProfileIn( $section );
 
        /**
-        * @param SectionProfileCallback &$section
+        * @param SectionProfileCallback|null &$section
         */
        public function scopedProfileOut( SectionProfileCallback &$section = null ) {
                $section = null;
index a7bc137..504859d 100644 (file)
@@ -73,10 +73,7 @@ class ProfilerSectionOnly extends Profiler {
        protected function getFunctionReport() {
                $data = $this->getFunctionStats();
                usort( $data, function ( $a, $b ) {
-                       if ( $a['real'] === $b['real'] ) {
-                               return 0;
-                       }
-                       return ( $a['real'] > $b['real'] ) ? -1 : 1; // descending
+                       return $b['real'] <=> $a['real']; // descending
                } );
 
                $width = 140;
index ffa441e..55a5a1f 100644 (file)
  * ($wgProfiler['exclude']) containing an array of function names.
  * Shell-style patterns are also accepted.
  *
- * It is also possible to use the Tideways PHP extension, which is mostly
- * a drop-in replacement for Xhprof. Just change the XHPROF_FLAGS_* constants
- * to TIDEWAYS_FLAGS_*.
+ * This also supports Tideways-XHProf PHP extension, which is mostly a drop-in
+ * replacement for Xhprof (replace XHPROF_FLAGS_* with XHPROF_TIDEWAYS_FLAGS_*),
+ * as well as the older (discontinued) Tideways extension (TIDEWAYS_FLAGS_*).
  *
  * @copyright © 2014 Wikimedia Foundation and contributors
  * @ingroup Profiler
  * @see Xhprof
  * @see https://php.net/xhprof
  * @see https://github.com/facebook/hhvm/blob/master/hphp/doc/profiling.md
- * @see https://github.com/tideways/php-profiler-extension
+ * @see https://github.com/tideways/php-xhprof-extension
  */
 class ProfilerXhprof extends Profiler {
        /**
@@ -73,7 +73,7 @@ class ProfilerXhprof extends Profiler {
        public function __construct( array $params = [] ) {
                parent::__construct( $params );
 
-               $flags = isset( $params['flags'] ) ? $params['flags'] : 0;
+               $flags = $params['flags'] ?? 0;
                $options = isset( $params['exclude'] )
                        ? [ 'ignored_functions' => $params['exclude'] ] : [];
                Xhprof::enable( $flags, $options );
@@ -201,10 +201,7 @@ class ProfilerXhprof extends Profiler {
        protected function getFunctionReport() {
                $data = $this->getFunctionStats();
                usort( $data, function ( $a, $b ) {
-                       if ( $a['real'] === $b['real'] ) {
-                               return 0;
-                       }
-                       return ( $a['real'] > $b['real'] ) ? -1 : 1; // descending
+                       return $b['real'] <=> $a['real']; // descending
                } );
 
                $width = 140;
index bb86551..6041ba0 100644 (file)
@@ -38,7 +38,7 @@ class ProfilerOutputStats extends ProfilerOutput {
         * @param array $stats
         */
        public function log( array $stats ) {
-               $prefix = isset( $this->params['prefix'] ) ? $this->params['prefix'] : '';
+               $prefix = $this->params['prefix'] ?? '';
                $contextStats = MediaWikiServices::getInstance()->getStatsdDataFactory();
 
                foreach ( $stats as $stat ) {
index 100304f..e3184db 100644 (file)
@@ -33,9 +33,7 @@ class ProfilerOutputText extends ProfilerOutput {
 
        function __construct( Profiler $collector, array $params ) {
                parent::__construct( $collector, $params );
-               $this->thresholdMs = isset( $params['thresholdMs'] )
-                       ? $params['thresholdMs']
-                       : 1.0;
+               $this->thresholdMs = $params['thresholdMs'] ?? 1.0;
        }
        public function log( array $stats ) {
                if ( $this->collector->getTemplated() ) {
@@ -48,7 +46,7 @@ class ProfilerOutputText extends ProfilerOutput {
                        } );
                        // Sort descending by time elapsed
                        usort( $stats, function ( $a, $b ) {
-                               return $a['real'] < $b['real'];
+                               return $b['real'] <=> $a['real'];
                        } );
 
                        array_walk( $stats,
@@ -62,8 +60,7 @@ class ProfilerOutputText extends ProfilerOutput {
                        if ( wfIsCLI() ) {
                                print "<!--\n{$out}\n-->\n";
                        } elseif ( $contentType === 'text/html' ) {
-                               $visible = isset( $this->params['visible'] ) ?
-                                       $this->params['visible'] : false;
+                               $visible = $this->params['visible'] ?? false;
                                if ( $visible ) {
                                        print "<pre>{$out}</pre>";
                                } else {
index 564ea6b..9d6c1a5 100644 (file)
 
 use Composer\Spdx\SpdxLicenses;
 use JsonSchema\Validator;
+use Seld\JsonLint\JsonParser;
+use Seld\JsonLint\ParsingException;
 
 /**
+ * Validate extension.json files against their JSON schema.
+ *
+ * This is used for static validation from the command-line via
+ * validateRegistrationFile.php, and the PHPUnit structure test suite
+ * (ExtensionJsonValidationTest).
+ *
+ * The files are normally read by the ExtensionRegistry
+ * and ExtensionProcessor classes.
+ *
  * @since 1.29
  */
 class ExtensionJsonValidator {
@@ -54,6 +65,10 @@ class ExtensionJsonValidator {
                                'The spdx-licenses library cannot be found, please install it through composer.'
                        );
                        return false;
+               } elseif ( !class_exists( JsonParser::class ) ) {
+                       call_user_func( $this->missingDepCallback,
+                               'The JSON lint library cannot be found, please install it through composer.'
+                       );
                }
 
                return true;
@@ -65,8 +80,14 @@ class ExtensionJsonValidator {
         * @throws ExtensionJsonValidationError on any failure
         */
        public function validate( $path ) {
-               $data = json_decode( file_get_contents( $path ) );
-               if ( !is_object( $data ) ) {
+               $contents = file_get_contents( $path );
+               $jsonParser = new JsonParser();
+               try {
+                       $data = $jsonParser->parse( $contents, JsonParser::DETECT_KEY_CONFLICTS );
+               } catch ( ParsingException $e ) {
+                       if ( $e instanceof \Seld\JsonLint\DuplicateKeyException ) {
+                               throw new ExtensionJsonValidationError( $e->getMessage() );
+                       }
                        throw new ExtensionJsonValidationError( "$path is not valid JSON" );
                }
 
index 14d4a17..d0a9871 100644 (file)
@@ -162,6 +162,11 @@ class ExtensionProcessor implements Processor {
         */
        protected $credits = [];
 
+       /**
+        * @var array
+        */
+       protected $config = [];
+
        /**
         * Any thing else in the $info that hasn't
         * already been processed
@@ -290,6 +295,7 @@ class ExtensionProcessor implements Processor {
 
                return [
                        'globals' => $this->globals,
+                       'config' => $this->config,
                        'defines' => $this->defines,
                        'callbacks' => $this->callbacks,
                        'credits' => $this->credits,
@@ -298,7 +304,7 @@ class ExtensionProcessor implements Processor {
        }
 
        public function getRequirements( array $info ) {
-               return isset( $info['requires'] ) ? $info['requires'] : [];
+               return $info['requires'] ?? [];
        }
 
        protected function extractHooks( array $info ) {
@@ -359,9 +365,7 @@ class ExtensionProcessor implements Processor {
        }
 
        protected function extractResourceLoaderModules( $dir, array $info ) {
-               $defaultPaths = isset( $info['ResourceFileModulePaths'] )
-                       ? $info['ResourceFileModulePaths']
-                       : false;
+               $defaultPaths = $info['ResourceFileModulePaths'] ?? false;
                if ( isset( $defaultPaths['localBasePath'] ) ) {
                        if ( $defaultPaths['localBasePath'] === '' ) {
                                // Avoid double slashes (e.g. /extensions/Example//path)
@@ -426,7 +430,7 @@ class ExtensionProcessor implements Processor {
        protected function extractCredits( $path, array $info ) {
                $credits = [
                        'path' => $path,
-                       'type' => isset( $info['type'] ) ? $info['type'] : 'other',
+                       'type' => $info['type'] ?? 'other',
                ];
                foreach ( self::$creditsAttributes as $attr ) {
                        if ( isset( $info[$attr] ) ) {
@@ -495,6 +499,11 @@ class ExtensionProcessor implements Processor {
                                        $value = "$dir/$value";
                                }
                                $this->addConfigGlobal( "$prefix$key", $value, $info['name'] );
+                               $data['providedby'] = $info['name'];
+                               if ( isset( $info['ConfigRegistry'][0] ) ) {
+                                       $data['configregistry'] = array_keys( $info['ConfigRegistry'] )[0];
+                               }
+                               $this->config[$key] = $data;
                        }
                }
        }
index b34a123..d21ae41 100644 (file)
@@ -36,7 +36,7 @@ class ExtensionRegistry {
        /**
         * Bump whenever the registration cache needs resetting
         */
-       const CACHE_VERSION = 6;
+       const CACHE_VERSION = 7;
 
        /**
         * Special key that defines the merge strategy
@@ -105,7 +105,7 @@ class ExtensionRegistry {
                                throw new Exception( "$path does not exist!" );
                        }
                        // @codeCoverageIgnoreStart
-                       if ( !$mtime ) {
+                       if ( $mtime === false ) {
                                $err = error_get_last();
                                throw new Exception( "Couldn't stat $path: {$err['message']}" );
                                // @codeCoverageIgnoreEnd
@@ -144,7 +144,7 @@ class ExtensionRegistry {
                        // been loaded
                        $cacheId = ObjectCache::detectLocalServerCache();
                        $cache = ObjectCache::newFromId( $cacheId );
-               } catch ( MWException $e ) {
+               } catch ( InvalidArgumentException $e ) {
                        $cache = new EmptyBagOStuff();
                }
                // See if this queue is in APC
@@ -247,6 +247,7 @@ class ExtensionRegistry {
                        }
                        if ( isset( $info['AutoloadNamespaces'] ) ) {
                                $autoloadNamespaces += $this->processAutoLoader( $dir, $info['AutoloadNamespaces'] );
+                               AutoLoader::$psr4Namespaces += $autoloadNamespaces;
                        }
 
                        // get all requirements/dependencies for this extension
index 210deb1..636d3b3 100644 (file)
@@ -25,6 +25,7 @@ interface Processor {
         * @return array With following keys:
         *     'globals' - variables to be set to $GLOBALS
         *     'defines' - constants to define
+        *     'config' - configuration information
         *     'callbacks' - functions to be executed by the registry
         *     'credits' - metadata to be stored by registry
         *     'attributes' - registration info which isn't a global variable
index 9c673bc..59853b4 100644 (file)
@@ -117,7 +117,7 @@ class VersionChecker {
                                                }
                                                break;
                                        case 'extensions':
-                                       case 'skin':
+                                       case 'skins':
                                                foreach ( $values as $dependency => $constraint ) {
                                                        $extError = $this->handleExtensionDependency(
                                                                $dependency, $constraint, $extension, $dependencyType
@@ -169,7 +169,7 @@ class VersionChecker {
         * @param string $dependencyName The name of the dependency
         * @param string $constraint The required version constraint for this dependency
         * @param string $checkedExt The Extension, which depends on this dependency
-        * @param string $type Either 'extension' or 'skin'
+        * @param string $type Either 'extensions' or 'skins'
         * @return bool|array false for no errors, or an array of info
         */
        private function handleExtensionDependency( $dependencyName, $constraint, $checkedExt,
index 2274793..aa632c3 100644 (file)
@@ -238,8 +238,8 @@ class ResourceLoader implements LoggerAwareInterface {
 
        /**
         * Register core modules and runs registration hooks.
-        * @param Config $config [optional]
-        * @param LoggerInterface $logger [optional]
+        * @param Config|null $config [optional]
+        * @param LoggerInterface|null $logger [optional]
         */
        public function __construct( Config $config = null, LoggerInterface $logger = null ) {
                global $IP;
@@ -317,7 +317,7 @@ class ResourceLoader implements LoggerAwareInterface {
         * Register a module with the ResourceLoader system.
         *
         * @param mixed $name Name of module as a string or List of name/object pairs as an array
-        * @param array $info Module info array. For backwards compatibility with 1.17alpha,
+        * @param array|null $info Module info array. For backwards compatibility with 1.17alpha,
         *   this may also be a ResourceLoaderModule object. Optional when using
         *   multiple-registration calling style.
         * @throws MWException If a duplicate module registration is attempted
@@ -446,7 +446,7 @@ class ResourceLoader implements LoggerAwareInterface {
         * Source IDs are typically the same as the Wiki ID or database name (e.g. lowercase a-z).
         *
         * @param array|string $id Source ID (string), or [ id1 => loadUrl, id2 => loadUrl, ... ]
-        * @param string|array $loadUrl load.php url (string), or array with loadUrl key for
+        * @param string|array|null $loadUrl load.php url (string), or array with loadUrl key for
         *  backwards-compatibility.
         * @throws MWException
         */
@@ -570,8 +570,7 @@ class ResourceLoader implements LoggerAwareInterface {
        }
 
        /**
-        * Return whether the definition of a module corresponds to a simple ResourceLoaderFileModule
-        * or one of its subclasses.
+        * Whether the module is a ResourceLoaderFileModule (including subclasses).
         *
         * @param string $name Module name
         * @return bool
@@ -584,14 +583,13 @@ class ResourceLoader implements LoggerAwareInterface {
                if ( isset( $info['object'] ) ) {
                        return false;
                }
-               if (
-                       isset( $info['class'] ) &&
-                       $info['class'] !== ResourceLoaderFileModule::class &&
-                       !is_subclass_of( $info['class'], ResourceLoaderFileModule::class )
-               ) {
-                       return false;
-               }
-               return true;
+               return (
+                       // The implied default for 'class' is ResourceLoaderFileModule
+                       !isset( $info['class'] ) ||
+                       // Explicit default
+                       $info['class'] === ResourceLoaderFileModule::class ||
+                       is_subclass_of( $info['class'], ResourceLoaderFileModule::class )
+               );
        }
 
        /**
@@ -1103,7 +1101,7 @@ MESSAGE;
                                                $strContent = isset( $styles['css'] ) ? implode( '', $styles['css'] ) : '';
                                                break;
                                        default:
-                                               $scripts = isset( $content['scripts'] ) ? $content['scripts'] : '';
+                                               $scripts = $content['scripts'] ?? '';
                                                if ( is_string( $scripts ) ) {
                                                        if ( $name === 'site' || $name === 'user' ) {
                                                                // Legacy scripts that run in the global scope without a closure.
@@ -1120,9 +1118,9 @@ MESSAGE;
                                                $strContent = self::makeLoaderImplementScript(
                                                        $implementKey,
                                                        $scripts,
-                                                       isset( $content['styles'] ) ? $content['styles'] : [],
+                                                       $content['styles'] ?? [],
                                                        isset( $content['messagesBlob'] ) ? new XmlJsCode( $content['messagesBlob'] ) : [],
-                                                       isset( $content['templates'] ) ? $content['templates'] : []
+                                                       $content['templates'] ?? []
                                                );
                                                break;
                                }
@@ -1310,7 +1308,7 @@ MESSAGE;
         *         Set the state of modules with the given names to the given states
         *
         * @param string $name
-        * @param string $state
+        * @param string|null $state
         * @return string JavaScript code
         */
        public static function makeLoaderStateScript( $name, $state = null ) {
@@ -1408,11 +1406,11 @@ MESSAGE;
         *        Registers modules with the given names and parameters.
         *
         * @param string $name Module name
-        * @param string $version Module version hash
-        * @param array $dependencies List of module names on which this module depends
-        * @param string $group Group which the module is in
-        * @param string $source Source of the module, or 'local' if not foreign
-        * @param string $skip Script body of the skip function
+        * @param string|null $version Module version hash
+        * @param array|null $dependencies List of module names on which this module depends
+        * @param string|null $group Group which the module is in
+        * @param string|null $source Source of the module, or 'local' if not foreign
+        * @param string|null $skip Script body of the skip function
         * @return string JavaScript code
         */
        public static function makeLoaderRegisterScript( $name, $version = null,
@@ -1466,7 +1464,7 @@ MESSAGE;
         *       Register sources with the given IDs and properties.
         *
         * @param string $id Source ID
-        * @param string $loadUrl load.php url
+        * @param string|null $loadUrl load.php url
         * @return string JavaScript code
         */
        public static function makeLoaderSourcesScript( $id, $loadUrl = null ) {
@@ -1503,8 +1501,9 @@ MESSAGE;
         * startup module if the client has adequate support for MediaWiki JavaScript code.
         *
         * @param string $script JavaScript code
-        * @param string $nonce [optional] Content-Security-Policy nonce (from OutputPage::getCSPNonce)
-        * @return WrappedString HTML
+        * @param string|null $nonce [optional] Content-Security-Policy nonce
+        *  (from OutputPage::getCSPNonce)
+        * @return string|WrappedString HTML
         */
        public static function makeInlineScript( $script, $nonce = null ) {
                $js = self::makeLoaderConditionalScript( $script );
@@ -1645,10 +1644,10 @@ MESSAGE;
         * @param array $modules
         * @param string $lang
         * @param string $skin
-        * @param string $user
-        * @param string $version
+        * @param string|null $user
+        * @param string|null $version
         * @param bool $debug
-        * @param string $only
+        * @param string|null $only
         * @param bool $printable
         * @param bool $handheld
         * @param array $extraQuery
@@ -1704,12 +1703,14 @@ MESSAGE;
         * Returns LESS compiler set up for use with MediaWiki
         *
         * @since 1.27
-        * @param array $extraVars Associative array of extra (i.e., other than the
-        *   globally-configured ones) that should be used for compilation.
+        * @param array $vars Associative array of variables that should be used
+        *  for compilation. Since 1.32, this method no longer automatically includes
+        *  global LESS vars from ResourceLoader::getLessVars (T191937).
         * @throws MWException
         * @return Less_Parser
         */
-       public function getLessCompiler( $extraVars = [] ) {
+       public function getLessCompiler( $vars = [] ) {
+               global $IP;
                // When called from the installer, it is possible that a required PHP extension
                // is missing (at least for now; see T49564). If this is the case, throw an
                // exception (caught by the installer) to prevent a fatal error later on.
@@ -1718,10 +1719,10 @@ MESSAGE;
                }
 
                $parser = new Less_Parser;
-               $parser->ModifyVars( array_merge( $this->getLessVars(), $extraVars ) );
-               $parser->SetImportDirs(
-                       array_fill_keys( $this->config->get( 'ResourceLoaderLESSImportPaths' ), '' )
-               );
+               $parser->ModifyVars( $vars );
+               $parser->SetImportDirs( [
+                       "$IP/resources/src/mediawiki.less/" => '',
+               );
                $parser->SetOption( 'relativeUrls', false );
 
                return $parser;
index 3ba63cf..8d08366 100644 (file)
@@ -18,6 +18,7 @@
  * @file
  */
 
+use Wikimedia\WrappedString;
 use Wikimedia\WrappedStringList;
 
 /**
@@ -94,7 +95,6 @@ class ResourceLoaderClientHtml {
        /**
         * Ensure the styles of one or more modules are loaded.
         *
-        * @deprecated since 1.28
         * @param array $modules Array of module names
         */
        public function setModuleStyles( array $modules ) {
@@ -146,7 +146,7 @@ class ResourceLoaderClientHtml {
                                'general' => [],
                        ],
                        // Deprecations for style-only modules
-                       'styledeprecations' => [],
+                       'styleDeprecations' => [],
                ];
 
                foreach ( $this->modules as $name ) {
@@ -213,7 +213,7 @@ class ResourceLoaderClientHtml {
                        }
                        $deprecation = $module->getDeprecationInformation();
                        if ( $deprecation ) {
-                               $data['styledeprecations'][] = $deprecation;
+                               $data['styleDeprecations'][] = $deprecation;
                        }
                }
 
@@ -318,14 +318,6 @@ class ResourceLoaderClientHtml {
                        );
                }
 
-               // Deprecations for only=styles modules
-               if ( $data['styledeprecations'] ) {
-                       $chunks[] = ResourceLoader::makeInlineScript(
-                               implode( '', $data['styledeprecations'] ),
-                               $nonce
-                       );
-               }
-
                // External stylesheets (only=styles)
                if ( $data['styles'] ) {
                        $chunks[] = $this->getLoad(
@@ -359,14 +351,25 @@ class ResourceLoaderClientHtml {
                        $startupQuery
                );
 
-               return WrappedStringList::join( "\n", $chunks );
+               return WrappedString::join( "\n", $chunks );
        }
 
        /**
         * @return string|WrappedStringList HTML
         */
        public function getBodyHtml() {
-               return '';
+               $data = $this->getData();
+               $chunks = [];
+
+               // Deprecations for only=styles modules
+               if ( $data['styleDeprecations'] ) {
+                       $chunks[] = ResourceLoader::makeInlineScript(
+                               implode( '', $data['styleDeprecations'] ),
+                               $this->options['nonce']
+                       );
+               }
+
+               return WrappedString::join( "\n", $chunks );
        }
 
        private function getContext( $group, $type ) {
@@ -402,7 +405,8 @@ class ResourceLoaderClientHtml {
         * @param array $modules One or more module names
         * @param string $only ResourceLoaderModule TYPE_ class constant
         * @param array $extraQuery [optional] Array with extra query parameters for the request
-        * @param string $nonce [optional] Content-Security-Policy nonce (from OutputPage::getCSPNonce)
+        * @param string|null $nonce [optional] Content-Security-Policy nonce
+        *  (from OutputPage::getCSPNonce)
         * @return string|WrappedStringList HTML
         */
        public static function makeLoad( ResourceLoaderContext $mainContext, array $modules, $only,
index d41198a..3ceb915 100644 (file)
@@ -226,7 +226,7 @@ class ResourceLoaderContext implements MessageLocalizer {
         * @return Message
         */
        public function msg( $key ) {
-               return call_user_func_array( 'wfMessage', func_get_args() )
+               return wfMessage( ...func_get_args() )
                        ->inLanguage( $this->getLanguage() )
                        // Use a dummy title because there is no real title
                        // for this endpoint, and the cache won't vary on it
index f2f3383..b2ca291 100644 (file)
@@ -153,10 +153,10 @@ class ResourceLoaderFileModule extends ResourceLoaderModule {
         *
         * @param array $options List of options; if not given or empty, an empty module will be
         *     constructed
-        * @param string $localBasePath Base path to prepend to all local paths in $options. Defaults
-        *     to $IP
-        * @param string $remoteBasePath Base path to prepend to all remote paths in $options. Defaults
-        *     to $wgResourceBasePath
+        * @param string|null $localBasePath Base path to prepend to all local paths in $options.
+        *     Defaults to $IP
+        * @param string|null $remoteBasePath Base path to prepend to all remote paths in $options.
+        *     Defaults to $wgResourceBasePath
         *
         * Below is a description for the $options array:
         * @throws InvalidArgumentException
@@ -298,9 +298,9 @@ class ResourceLoaderFileModule extends ResourceLoaderModule {
         * Implementation note: the amount of global state used in this function is staggering.
         *
         * @param array $options Module definition
-        * @param string $localBasePath Path to use if not provided in module definition. Defaults
+        * @param string|null $localBasePath Path to use if not provided in module definition. Defaults
         *     to $IP
-        * @param string $remoteBasePath Path to use if not provided in module definition. Defaults
+        * @param string|null $remoteBasePath Path to use if not provided in module definition. Defaults
         *     to $wgResourceBasePath
         * @return array Array( localBasePath, remoteBasePath )
         */
@@ -486,16 +486,13 @@ class ResourceLoaderFileModule extends ResourceLoaderModule {
        }
 
        /**
-        * Helper method to gather file hashes for getDefinitionSummary.
-        *
-        * This function is context-sensitive, only computing hashes of files relevant to the
-        * given language, skin, etc.
+        * Helper method for getDefinitionSummary.
         *
         * @see ResourceLoaderModule::getFileDependencies
         * @param ResourceLoaderContext $context
         * @return array
         */
-       protected function getFileHashes( ResourceLoaderContext $context ) {
+       private function getFileHashes( ResourceLoaderContext $context ) {
                $files = [];
 
                // Flatten style files into $files
@@ -641,7 +638,7 @@ class ResourceLoaderFileModule extends ResourceLoaderModule {
                                $collatedFiles[$default][] = $value;
                        } elseif ( is_array( $value ) ) {
                                // File name as the key, options array as the value
-                               $optionValue = isset( $value[$option] ) ? $value[$option] : $default;
+                               $optionValue = $value[$option] ?? $default;
                                if ( !isset( $collatedFiles[$optionValue] ) ) {
                                        $collatedFiles[$optionValue] = [];
                                }
@@ -656,7 +653,7 @@ class ResourceLoaderFileModule extends ResourceLoaderModule {
         *
         * @param array $list List of lists to select from
         * @param string $key Key to look for in $map
-        * @param string $fallback Key to look for in $list if $key doesn't exist
+        * @param string|null $fallback Key to look for in $list if $key doesn't exist
         * @return array List of elements from $map which matched $key or $fallback,
         *  or an empty list in case of no match
         */
@@ -673,12 +670,12 @@ class ResourceLoaderFileModule extends ResourceLoaderModule {
        }
 
        /**
-        * Get a list of file paths for all scripts in this module, in order of proper execution.
+        * Get a list of script file paths for this module, in order of proper execution.
         *
         * @param ResourceLoaderContext $context
         * @return array List of file paths
         */
-       protected function getScriptFiles( ResourceLoaderContext $context ) {
+       private function getScriptFiles( ResourceLoaderContext $context ) {
                $files = array_merge(
                        $this->scripts,
                        $this->getLanguageScripts( $context->getLanguage() ),
@@ -717,6 +714,9 @@ class ResourceLoaderFileModule extends ResourceLoaderModule {
        /**
         * Get a list of file paths for all styles in this module, in order of proper inclusion.
         *
+        * This is considered a private method. Exposed for internal use by WebInstallerOutput.
+        *
+        * @private
         * @param ResourceLoaderContext $context
         * @return array List of file paths
         */
@@ -790,13 +790,13 @@ class ResourceLoaderFileModule extends ResourceLoaderModule {
        }
 
        /**
-        * Gets the contents of a list of JavaScript files.
+        * Get the contents of a list of JavaScript files. Helper for getScript().
         *
         * @param array $scripts List of file paths to scripts to read, remap and concetenate
-        * @throws MWException
         * @return string Concatenated and remapped JavaScript data from $scripts
+        * @throws MWException
         */
-       protected function readScriptFiles( array $scripts ) {
+       private function readScriptFiles( array $scripts ) {
                if ( empty( $scripts ) ) {
                        return '';
                }
@@ -819,17 +819,17 @@ class ResourceLoaderFileModule extends ResourceLoaderModule {
        }
 
        /**
-        * Gets the contents of a list of CSS files.
+        * Get the contents of a list of CSS files.
         *
-        * @param array $styles List of media type/list of file paths pairs, to read, remap and
-        * concetenate
-        * @param bool $flip
-        * @param ResourceLoaderContext $context
+        * This is considered a private method. Exposed for internal use by WebInstallerOutput.
         *
-        * @throws MWException
+        * @private
+        * @param array $styles Map of media type to file paths to read, remap, and concatenate
+        * @param bool $flip
+        * @param ResourceLoaderContext|null $context
         * @return array List of concatenated and remapped CSS data from $styles,
         *     keyed by media type
-        *
+        * @throws MWException
         * @since 1.27 Calling this method without a ResourceLoaderContext instance
         *   is deprecated.
         */
@@ -959,9 +959,12 @@ class ResourceLoaderFileModule extends ResourceLoaderModule {
                        $cache = ObjectCache::getLocalServerInstance( CACHE_ANYTHING );
                }
 
-               // Construct a cache key from the LESS file name and a hash digest
+               $vars = array_merge(
+                       $context->getResourceLoader()->getLessVars(),
+                       $this->getLessVars( $context )
+               );
+               // Construct a cache key from the LESS file name, and a hash digest
                // of the LESS variables used for compilation.
-               $vars = $this->getLessVars( $context );
                ksort( $vars );
                $varsHash = hash( 'md4', serialize( $vars ) );
                $cacheKey = $cache->makeGlobalKey( 'LESS', $fileName, $varsHash );
index d38a175..0adbd0c 100644 (file)
@@ -44,14 +44,18 @@ class ResourceLoaderImage {
         * @param string|array $descriptor Path to image file, or array structure containing paths
         * @param string $basePath Directory to which paths in descriptor refer
         * @param array $variants
+        * @param string|null $defaultColor of the base variant
         * @throws InvalidArgumentException
         */
-       public function __construct( $name, $module, $descriptor, $basePath, $variants ) {
+       public function __construct( $name, $module, $descriptor, $basePath, $variants,
+               $defaultColor = null
+       ) {
                $this->name = $name;
                $this->module = $module;
                $this->descriptor = $descriptor;
                $this->basePath = $basePath;
                $this->variants = $variants;
+               $this->defaultColor = $defaultColor;
 
                // Expand shorthands:
                // [ "en,de,fr" => "foo.svg" ]
@@ -250,7 +254,10 @@ class ResourceLoaderImage {
                if ( $variant && isset( $this->variants[$variant] ) ) {
                        $data = $this->variantize( $this->variants[$variant], $context );
                } else {
-                       $data = file_get_contents( $path );
+                       $defaultColor = $this->defaultColor;
+                       $data = $defaultColor ?
+                               $this->variantize( [ 'color' => $defaultColor ], $context ) :
+                               file_get_contents( $path );
                }
 
                if ( $format === 'rasterized' ) {
index 5e329e8..b711cbd 100644 (file)
@@ -39,6 +39,8 @@ class ResourceLoaderImageModule extends ResourceLoaderModule {
        protected $origin = self::ORIGIN_CORE_SITEWIDE;
 
        protected $images = [];
+       protected $defaultColor = null;
+       protected $useDataURI = true;
        protected $variants = [];
        protected $prefix = null;
        protected $selectorWithoutVariant = '.{prefix}-{name}';
@@ -50,7 +52,7 @@ class ResourceLoaderImageModule extends ResourceLoaderModule {
         *
         * @param array $options List of options; if not given or empty, an empty module will be
         *     constructed
-        * @param string $localBasePath Base path to prepend to all local paths in $options. Defaults
+        * @param string|null $localBasePath Base path to prepend to all local paths in $options. Defaults
         *     to $IP
         *
         * Below is a description for the $options array:
@@ -182,6 +184,10 @@ class ResourceLoaderImageModule extends ResourceLoaderModule {
                                        $this->{$member} = $option;
                                        break;
 
+                               case 'useDataURI':
+                                       $this->{$member} = (bool)$option;
+                                       break;
+                               case 'defaultColor':
                                case 'prefix':
                                case 'selectorWithoutVariant':
                                case 'selectorWithVariant':
@@ -224,7 +230,7 @@ class ResourceLoaderImageModule extends ResourceLoaderModule {
        public function getImage( $name, ResourceLoaderContext $context ) {
                $this->loadFromDefinition();
                $images = $this->getImages( $context );
-               return isset( $images[$name] ) ? $images[$name] : null;
+               return $images[$name] ?? null;
        }
 
        /**
@@ -241,9 +247,7 @@ class ResourceLoaderImageModule extends ResourceLoaderModule {
                if ( !isset( $this->imageObjects[$skin] ) ) {
                        $this->imageObjects[$skin] = [];
                        if ( !isset( $this->images[$skin] ) ) {
-                               $this->images[$skin] = isset( $this->images['default'] ) ?
-                                       $this->images['default'] :
-                                       [];
+                               $this->images[$skin] = $this->images['default'] ?? [];
                        }
                        foreach ( $this->images[$skin] as $name => $options ) {
                                $fileDescriptor = is_string( $options ) ? $options : $options['file'];
@@ -266,7 +270,8 @@ class ResourceLoaderImageModule extends ResourceLoaderModule {
                                        $this->getName(),
                                        $fileDescriptor,
                                        $this->localBasePath,
-                                       $variantConfig
+                                       $variantConfig,
+                                       $this->defaultColor
                                );
                                $this->imageObjects[$skin][$image->getName()] = $image;
                        }
@@ -290,9 +295,7 @@ class ResourceLoaderImageModule extends ResourceLoaderModule {
                if ( !isset( $this->globalVariants[$skin] ) ) {
                        $this->globalVariants[$skin] = [];
                        if ( !isset( $this->variants[$skin] ) ) {
-                               $this->variants[$skin] = isset( $this->variants['default'] ) ?
-                                       $this->variants['default'] :
-                                       [];
+                               $this->variants[$skin] = $this->variants['default'] ?? [];
                        }
                        foreach ( $this->variants[$skin] as $name => $config ) {
                                if ( isset( $config['global'] ) && $config['global'] ) {
@@ -359,7 +362,7 @@ class ResourceLoaderImageModule extends ResourceLoaderModule {
                $script,
                $variant = null
        ) {
-               $imageDataUri = $image->getDataUri( $context, $variant, 'original' );
+               $imageDataUri = $this->useDataURI ? $image->getDataUri( $context, $variant, 'original' ) : false;
                $primaryUrl = $imageDataUri ?: $image->getUrl( $context, $script, $variant, 'original' );
                $declarations = $this->getCssDeclarations(
                        $primaryUrl,
@@ -430,7 +433,7 @@ class ResourceLoaderImageModule extends ResourceLoaderModule {
         * @param ResourceLoaderContext $context
         * @return array
         */
-       protected function getFileHashes( ResourceLoaderContext $context ) {
+       private function getFileHashes( ResourceLoaderContext $context ) {
                $this->loadFromDefinition();
                $files = [];
                foreach ( $this->getImages( $context ) as $name => $image ) {
@@ -444,7 +447,7 @@ class ResourceLoaderImageModule extends ResourceLoaderModule {
         * Extract a local base path from module definition information.
         *
         * @param array $options Module definition
-        * @param string $localBasePath Path to use if not provided in module definition. Defaults
+        * @param string|null $localBasePath Path to use if not provided in module definition. Defaults
         *     to $IP
         * @return string Local base path
         */
index e78484a..4b24081 100644 (file)
@@ -23,9 +23,9 @@
  */
 
 /**
- * ResourceLoader module for populating language specific data.
+ * ResourceLoader module for populating language specific data, such as grammar forms.
  */
-class ResourceLoaderLanguageDataModule extends ResourceLoaderModule {
+class ResourceLoaderLanguageDataModule extends ResourceLoaderFileModule {
 
        protected $targets = [ 'desktop', 'mobile' ];
 
@@ -54,7 +54,8 @@ class ResourceLoaderLanguageDataModule extends ResourceLoaderModule {
         * @return string JavaScript code
         */
        public function getScript( ResourceLoaderContext $context ) {
-               return Xml::encodeJsCall(
+               $fileScript = parent::getScript( $context );
+               $langDataScript = Xml::encodeJsCall(
                        'mw.language.setData',
                        [
                                $context->getLanguage(),
@@ -62,6 +63,7 @@ class ResourceLoaderLanguageDataModule extends ResourceLoaderModule {
                        ],
                        ResourceLoader::inDebugMode()
                );
+               return $fileScript . $langDataScript;
        }
 
        /**
@@ -72,10 +74,9 @@ class ResourceLoaderLanguageDataModule extends ResourceLoaderModule {
        }
 
        /**
-        * @param ResourceLoaderContext $context
-        * @return array
+        * @return bool
         */
-       public function getDependencies( ResourceLoaderContext $context = null ) {
-               return [ 'mediawiki.language.init' ];
+       public function supportsURLLoading() {
+               return false;
        }
 }
index 57260ba..eb09664 100644 (file)
@@ -28,7 +28,7 @@
 /**
  * ResourceLoader module for populating language specific data.
  */
-class ResourceLoaderLanguageNamesModule extends ResourceLoaderModule {
+class ResourceLoaderLanguageNamesModule extends ResourceLoaderFileModule {
 
        protected $targets = [ 'desktop', 'mobile' ];
 
@@ -60,11 +60,11 @@ class ResourceLoaderLanguageNamesModule extends ResourceLoaderModule {
        }
 
        /**
-        * @param ResourceLoaderContext $context
+        * @param ResourceLoaderContext|null $context
         * @return array
         */
        public function getDependencies( ResourceLoaderContext $context = null ) {
-               return [ 'mediawiki.language.init' ];
+               return [ 'mediawiki.language' ];
        }
 
        /**
index 17d00e0..c4e517a 100644 (file)
@@ -4,10 +4,21 @@
  * Subclass with context specific LESS variables
  */
 class ResourceLoaderLessVarFileModule extends ResourceLoaderFileModule {
-       protected $lessVariables = [
-               'collapsible-collapse',
-               'collapsible-expand',
-       ];
+       protected $lessVariables = [];
+
+       /**
+        * @inheritDoc
+        */
+       public function __construct(
+               $options = [],
+               $localBasePath = null,
+               $remoteBasePath = null
+       ) {
+               if ( isset( $options['lessMessages'] ) ) {
+                       $this->lessVariables = $options['lessMessages'];
+               }
+               parent::__construct( $options, $localBasePath, $remoteBasePath );
+       }
 
        /**
         * @inheritDoc
@@ -19,6 +30,7 @@ class ResourceLoaderLessVarFileModule extends ResourceLoaderFileModule {
 
        /**
         * Exclude a set of messages from a JSON string representation
+        *
         * @param string $blob
         * @param array $exclusions
         * @return array $blob
@@ -29,7 +41,7 @@ class ResourceLoaderLessVarFileModule extends ResourceLoaderFileModule {
                foreach ( $exclusions as $key ) {
                        unset( $data[$key] );
                }
-               return $data;
+               return (object)$data;
        }
 
        /**
@@ -45,6 +57,7 @@ class ResourceLoaderLessVarFileModule extends ResourceLoaderFileModule {
         * (ModifyVars) method so that the variable can be loaded and made available to stylesheets.
         * Note this does not take care of CSS escaping. That will be taken care of as part
         * of CSS Janus.
+        *
         * @param string $msg
         * @return string wrapped LESS variable definition
         */
@@ -53,14 +66,16 @@ class ResourceLoaderLessVarFileModule extends ResourceLoaderFileModule {
        }
 
        /**
-        * @param \ResourceLoaderContext $context
+        * Get language-specific LESS variables for this module.
+        *
+        * @param ResourceLoaderContext $context
         * @return array LESS variables
         */
-       protected function getLessVars( \ResourceLoaderContext $context ) {
+       protected function getLessVars( ResourceLoaderContext $context ) {
                $blob = parent::getMessageBlob( $context );
                $lessMessages = $this->excludeMessagesFromBlob( $blob, $this->messages );
 
-               $vars = [];
+               $vars = parent::getLessVars( $context );
                foreach ( $lessMessages as $msgKey => $value ) {
                        $vars['msg-' . $msgKey] = self::wrapAndEscapeMessage( $value );
                }
index a0a4e58..7018f16 100644 (file)
@@ -347,7 +347,7 @@ abstract class ResourceLoaderModule implements LoggerAwareInterface {
         * Note: It is expected that $context will be made non-optional in the near
         * future.
         *
-        * @param ResourceLoaderContext $context
+        * @param ResourceLoaderContext|null $context
         * @return array List of module names as strings
         */
        public function getDependencies( ResourceLoaderContext $context = null ) {
@@ -799,11 +799,6 @@ abstract class ResourceLoaderModule implements LoggerAwareInterface {
         * This method should be quick because it is frequently run by ResourceLoaderStartUpModule to
         * propagate changes to the client and effectively invalidate cache.
         *
-        * For backward-compatibility, the following optional data providers are automatically included:
-        *
-        * - getModifiedTime()
-        * - getModifiedHash()
-        *
         * @since 1.26
         * @param ResourceLoaderContext $context
         * @return string Hash (should use ResourceLoader::makeHash)
@@ -833,18 +828,6 @@ abstract class ResourceLoaderModule implements LoggerAwareInterface {
                                        throw new LogicException( 'getDefinitionSummary must call parent method' );
                                }
                                $str = json_encode( $summary );
-
-                               $mtime = $this->getModifiedTime( $context );
-                               if ( $mtime !== null ) {
-                                       // Support: MediaWiki 1.25 and earlier
-                                       $str .= strval( $mtime );
-                               }
-
-                               $mhash = $this->getModifiedHash( $context );
-                               if ( $mhash !== null ) {
-                                       // Support: MediaWiki 1.25 and earlier
-                                       $str .= strval( $mhash );
-                               }
                        }
 
                        $this->versionHash[$contextHash] = ResourceLoader::makeHash( $str );
@@ -915,28 +898,6 @@ abstract class ResourceLoaderModule implements LoggerAwareInterface {
                ];
        }
 
-       /**
-        * Get this module's last modification timestamp for a given context.
-        *
-        * @deprecated since 1.26 Use getDefinitionSummary() instead
-        * @param ResourceLoaderContext $context
-        * @return int|null UNIX timestamp
-        */
-       public function getModifiedTime( ResourceLoaderContext $context ) {
-               return null;
-       }
-
-       /**
-        * Helper method for providing a version hash to getVersionHash().
-        *
-        * @deprecated since 1.26 Use getDefinitionSummary() instead
-        * @param ResourceLoaderContext $context
-        * @return string|null Hash
-        */
-       public function getModifiedHash( ResourceLoaderContext $context ) {
-               return null;
-       }
-
        /**
         * Check whether this module is known to be empty. If a child class
         * has an easy and cheap way to determine that this module is
index 5c9e1d9..313d789 100644 (file)
@@ -35,7 +35,7 @@ class ResourceLoaderOOUIImageModule extends ResourceLoaderImageModule {
                $themes = self::getSkinThemeMap();
 
                // For backwards-compatibility, allow missing 'themeImages'
-               $module = isset( $this->definition['themeImages'] ) ? $this->definition['themeImages'] : '';
+               $module = $this->definition['themeImages'] ?? '';
 
                $definition = [];
                foreach ( $themes as $skin => $theme ) {
diff --git a/includes/resourceloader/ResourceLoaderRawFileModule.php b/includes/resourceloader/ResourceLoaderRawFileModule.php
deleted file mode 100644 (file)
index beab53e..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-<?php
-/**
- * Module containing files that are loaded without ResourceLoader.
- *
- * Primary usecase being "base" modules loaded by the startup module,
- * such as jquery and the mw.loader client itself. These make use of
- * ResourceLoaderModule and load.php for convenience but aren't actually
- * registered in the startup module (as it would have to load itself).
- *
- * 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 Timo Tijhof
- */
-
-class ResourceLoaderRawFileModule extends ResourceLoaderFileModule {
-
-       /**
-        * Enable raw mode to omit mw.loader.state() call as mw.loader
-        * does not yet exist when these modules execute.
-        * @var bool
-        */
-       protected $raw = true;
-
-       /**
-        * Get all JavaScript code.
-        *
-        * @param ResourceLoaderContext $context
-        * @return string JavaScript code
-        */
-       public function getScript( ResourceLoaderContext $context ) {
-               $script = parent::getScript( $context );
-               // Add closure explicitly because raw modules can't be wrapped mw.loader.implement.
-               // Unlike with mw.loader.implement, this closure is immediately invoked.
-               // @see ResourceLoader::makeModuleResponse
-               // @see ResourceLoader::makeLoaderImplementScript
-               return "(function () {\n{$script}\n}());";
-       }
-}
index a0061e3..0ad7fe4 100644 (file)
@@ -61,7 +61,7 @@ class ResourceLoaderSpecialCharacterDataModule extends ResourceLoaderModule {
        }
 
        /**
-        * @param ResourceLoaderContext $context
+        * @param ResourceLoaderContext|null $context
         * @return array
         */
        public function getDependencies( ResourceLoaderContext $context = null ) {
index 0416c85..a4fd712 100644 (file)
@@ -324,48 +324,64 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule {
         * @return array
         */
        public function getPreloadLinks( ResourceLoaderContext $context ) {
-               $url = self::getStartupModulesUrl( $context );
+               $url = $this->getBaseModulesUrl( $context );
                return [
                        $url => [ 'as' => 'script' ]
                ];
        }
 
        /**
-        * Base modules required for the base environment of ResourceLoader
+        * Internal modules used by ResourceLoader that cannot be depended on.
         *
+        * These module(s) should have isRaw() return true, and are not
+        * legal dependencies (enforced by structure/ResourcesTest).
+        *
+        * @deprecated since 1.32 No longer used.
         * @return array
         */
        public static function getStartupModules() {
-               return [ 'jquery', 'mediawiki' ];
+               wfDeprecated( __METHOD__, '1.32' );
+               return [];
        }
 
+       /**
+        * @deprecated since 1.32 No longer used.
+        * @return array
+        */
        public static function getLegacyModules() {
+               wfDeprecated( __METHOD__, '1.32' );
+               return [];
+       }
+
+       /**
+        * Base modules implicitly available to all modules.
+        *
+        * @since 1.32
+        * @return array
+        */
+       private function getBaseModules() {
                global $wgIncludeLegacyJavaScript;
 
-               $legacyModules = [];
+               $baseModules = [ 'jquery', 'mediawiki.base' ];
                if ( $wgIncludeLegacyJavaScript ) {
-                       $legacyModules[] = 'mediawiki.legacy.wikibits';
+                       $baseModules[] = 'mediawiki.legacy.wikibits';
                }
 
-               return $legacyModules;
+               return $baseModules;
        }
 
        /**
         * Get the load URL of the startup modules.
         *
-        * This is a helper for getScript(), but can also be called standalone, such
-        * as when generating an AppCache manifest.
+        * This is a helper for getScript().
         *
         * @param ResourceLoaderContext $context
         * @return string
         */
-       public static function getStartupModulesUrl( ResourceLoaderContext $context ) {
+       private function getBaseModulesUrl( ResourceLoaderContext $context ) {
                $rl = $context->getResourceLoader();
                $derivative = new DerivativeResourceLoaderContext( $context );
-               $derivative->setModules( array_merge(
-                       self::getStartupModules(),
-                       self::getLegacyModules()
-               ) );
+               $derivative->setModules( $this->getBaseModules() );
                $derivative->setOnly( 'scripts' );
                // Must setModules() before makeVersionQuery()
                $derivative->setVersion( $rl->makeVersionQuery( $derivative ) );
@@ -383,7 +399,15 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule {
                        return '/* Requires only=script */';
                }
 
-               $out = file_get_contents( "$IP/resources/src/startup.js" );
+               $out = file_get_contents( "$IP/resources/src/startup/startup.js" );
+
+               // Keep in sync with maintenance/jsduck/eg-iframe.html and,
+               // keep in sync with 'fileHashes' in StartUpModule::getDefinitionSummary().
+               $mwLoaderCode = file_get_contents( "$IP/resources/src/startup/mediawiki.js" ) .
+                       file_get_contents( "$IP/resources/src/startup/mediawiki.requestIdleCallback.js" );
+               if ( $context->getDebug() ) {
+                       $mwLoaderCode .= file_get_contents( "$IP/resources/src/startup/mediawiki.log.js" );
+               }
 
                $pairs = array_map( function ( $value ) {
                        $value = FormatJson::encode( $value, ResourceLoader::inDebugMode(), FormatJson::ALL_OK );
@@ -394,13 +418,14 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule {
                        '$VARS.wgLegacyJavaScriptGlobals' => $this->getConfig()->get( 'LegacyJavaScriptGlobals' ),
                        '$VARS.configuration' => $this->getConfigSettings( $context ),
                        // This url may be preloaded. See getPreloadLinks().
-                       '$VARS.baseModulesUri' => self::getStartupModulesUrl( $context ),
+                       '$VARS.baseModulesUri' => $this->getBaseModulesUrl( $context ),
                ] );
-               $pairs['$CODE.registrations()'] = str_replace(
+               $pairs['$CODE.registrations();'] = str_replace(
                        "\n",
                        "\n\t",
                        trim( $this->getModuleRegistrations( $context ) )
                );
+               $pairs['$CODE.defineLoader();'] = $mwLoaderCode;
 
                return strtr( $out, $pairs );
        }
@@ -429,8 +454,10 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule {
                        // Detect changes to the module registrations
                        'moduleHashes' => $this->getAllModuleHashes( $context ),
 
-                       'fileMtimes' => [
-                               filemtime( "$IP/resources/src/startup.js" ),
+                       'fileHashes' => [
+                               $this->safeFileHash( "$IP/resources/src/startup/startup.js" ),
+                               $this->safeFileHash( "$IP/resources/src/startup/mediawiki.js" ),
+                               $this->safeFileHash( "$IP/resources/src/startup/mediawiki.requestIdleCallback.js" ),
                        ],
                ];
                return $summary;
index ffa55c0..0d40ad7 100644 (file)
@@ -32,7 +32,7 @@ class ResourceLoaderUserOptionsModule extends ResourceLoaderModule {
        protected $targets = [ 'desktop', 'mobile' ];
 
        /**
-        * @param ResourceLoaderContext $context
+        * @param ResourceLoaderContext|null $context
         * @return array List of module names as strings
         */
        public function getDependencies( ResourceLoaderContext $context = null ) {
index 085244a..b699b36 100644 (file)
@@ -76,7 +76,8 @@ class ResourceLoaderWikiModule extends ResourceLoaderModule {
        protected $group;
 
        /**
-        * @param array $options For back-compat, this can be omitted in favour of overwriting getPages.
+        * @param array|null $options For back-compat, this can be omitted in favour of overwriting
+        *  getPages.
         */
        public function __construct( array $options = null ) {
                if ( is_null( $options ) ) {
@@ -285,7 +286,7 @@ class ResourceLoaderWikiModule extends ResourceLoaderModule {
                        if ( $options['type'] !== 'style' ) {
                                continue;
                        }
-                       $media = isset( $options['media'] ) ? $options['media'] : 'all';
+                       $media = $options['media'] ?? 'all';
                        $style = $this->getContent( $titleText, $context );
                        if ( strval( $style ) === '' ) {
                                continue;
@@ -534,6 +535,8 @@ class ResourceLoaderWikiModule extends ResourceLoaderModule {
        ) {
                static $formats = [ CONTENT_FORMAT_CSS, CONTENT_FORMAT_JAVASCRIPT ];
 
+               // TODO: MCR: differentiate between page functionality and content model!
+               //       Not all pages containing CSS or JS have to be modules! [PageType]
                if ( $old && in_array( $old->getContentFormat(), $formats ) ) {
                        $purge = true;
                } elseif ( $new && in_array( $new->getContentFormat(), $formats ) ) {
index 89025bc..cf895ba 100644 (file)
@@ -112,7 +112,7 @@ abstract class RevDelList extends RevisionListBase {
 
                $bitPars = $params['value'];
                $comment = $params['comment'];
-               $perItemStatus = isset( $params['perItemStatus'] ) ? $params['perItemStatus'] : false;
+               $perItemStatus = $params['perItemStatus'] ?? false;
 
                // CAS-style checks are done on the _deleted fields so the select
                // does not need to use FOR UPDATE nor be in the atomic section
@@ -287,7 +287,7 @@ abstract class RevDelList extends RevisionListBase {
                                'oldBits' => $virtualOldBits,
                                'comment' => $comment,
                                'ids' => $idsForLog,
-                               'tags' => isset( $params['tags'] ) ? $params['tags'] : [],
+                               'tags' => $params['tags'] ?? [],
                        ] + $authorFields
                );
 
diff --git a/includes/search/PaginatingSearchEngine.php b/includes/search/PaginatingSearchEngine.php
new file mode 100644 (file)
index 0000000..97ef2d5
--- /dev/null
@@ -0,0 +1,12 @@
+<?php
+
+/**
+ * Marker class for search engines that can handle their own pagination, by
+ * reporting in their SearchResultSet when a next page is available. This
+ * only applies to search{Title,Text} and not to completion search.
+ *
+ * SearchEngine implementations not implementing this interface will have
+ * an over-fetch performed to determine next page availability.
+ */
+interface PaginatingSearchEngine {
+}
index 643c2c1..93f8d23 100644 (file)
@@ -28,14 +28,14 @@ use Wikimedia\Rdbms\IDatabase;
  * @ingroup Search
  * @since 1.23
  */
-class SearchDatabase extends SearchEngine {
+abstract class SearchDatabase extends SearchEngine {
        /**
         * @var IDatabase Slave database for reading from for results
         */
        protected $db;
 
        /**
-        * @param IDatabase $db The database to search from
+        * @param IDatabase|null $db The database to search from
         */
        public function __construct( IDatabase $db = null ) {
                if ( $db ) {
@@ -45,6 +45,38 @@ class SearchDatabase extends SearchEngine {
                }
        }
 
+       /**
+        * @param string $term
+        * @return SearchResultSet|Status|null
+        */
+       final public function doSearchText( $term ) {
+               return $this->doSearchTextInDB( $this->extractNamespacePrefix( $term ) );
+       }
+
+       /**
+        * Perform a full text search query and return a result set.
+        *
+        * @param string $term Raw search term
+        * @return SqlSearchResultSet
+        */
+       abstract protected function doSearchTextInDB( $term );
+
+       /**
+        * @param string $term
+        * @return SearchResultSet|null
+        */
+       final public function doSearchTitle( $term ) {
+               return $this->doSearchTitleInDB( $this->extractNamespacePrefix( $term ) );
+       }
+
+       /**
+        * Perform a title-only search query and return a result set.
+        *
+        * @param string $term Raw search term
+        * @return SqlSearchResultSet
+        */
+       abstract protected function doSearchTitleInDB( $term );
+
        /**
         * Return a 'cleaned up' search string
         *
@@ -58,4 +90,19 @@ class SearchDatabase extends SearchEngine {
                $lc = $this->legalSearchChars( self::CHARS_ALL );
                return trim( preg_replace( "/[^{$lc}]/", " ", $text ) );
        }
+
+       /**
+        * Extract the optional namespace prefix and set self::namespaces
+        * accordingly and return the query string
+        * @param string $term
+        * @return string the query string without any namespace prefix
+        */
+       final protected function extractNamespacePrefix( $term ) {
+               $queryAndNs = self::parseNamespacePrefixes( $term );
+               if ( $queryAndNs === false ) {
+                       return $term;
+               }
+               $this->namespaces = $queryAndNs[1];
+               return $queryAndNs[0];
+       }
 }
index bd48e21..30c2271 100644 (file)
@@ -77,7 +77,9 @@ abstract class SearchEngine {
         * @return SearchResultSet|Status|null
         */
        public function searchText( $term ) {
-               return $this->doSearchText( $term );
+               return $this->maybePaginate( function () use ( $term ) {
+                       return $this->doSearchText( $term );
+               } );
        }
 
        /**
@@ -132,7 +134,9 @@ abstract class SearchEngine {
         * @return SearchResultSet|null
         */
        public function searchTitle( $term ) {
-               return $this->doSearchTitle( $term );
+               return $this->maybePaginate( function () use ( $term ) {
+                       return $this->doSearchTitle( $term );
+               } );
        }
 
        /**
@@ -146,6 +150,40 @@ abstract class SearchEngine {
                return null;
        }
 
+       /**
+        * Performs an overfetch and shrink operation to determine if
+        * the next page is available for search engines that do not
+        * explicitly implement their own pagination.
+        *
+        * @param Closure $fn Takes no arguments
+        * @return SearchResultSet|Status<SearchResultSet>|null Result of calling $fn
+        */
+       private function maybePaginate( Closure $fn ) {
+               if ( $this instanceof PaginatingSearchEngine ) {
+                       return $fn();
+               }
+               $this->limit++;
+               try {
+                       $resultSetOrStatus = $fn();
+               } finally {
+                       $this->limit--;
+               }
+
+               $resultSet = null;
+               if ( $resultSetOrStatus instanceof SearchResultSet ) {
+                       $resultSet = $resultSetOrStatus;
+               } elseif ( $resultSetOrStatus instanceof Status &&
+                       $resultSetOrStatus->getValue() instanceof SearchResultSet
+               ) {
+                       $resultSet = $resultSetOrStatus->getValue();
+               }
+               if ( $resultSet ) {
+                       $resultSet->shrink( $this->limit );
+               }
+
+               return $resultSetOrStatus;
+       }
+
        /**
         * @since 1.18
         * @param string $feature
@@ -206,6 +244,8 @@ abstract class SearchEngine {
         * search=test&prefix=Main_Page/Archive -> test prefix:Main Page/Archive
         * @param string $term
         * @return string
+        * @deprecated since 1.32 this should now be handled internally by the
+        * search engine
         */
        public function transformSearchTerm( $term ) {
                return $term;
@@ -347,16 +387,12 @@ abstract class SearchEngine {
         * or namespace names and set the list of namespaces
         * of this class accordingly.
         *
+        * @deprecated since 1.32; should be handled internally by the search engine
         * @param string $query
         * @return string
         */
        function replacePrefixes( $query ) {
-               $queryAndNs = self::parseNamespacePrefixes( $query );
-               if ( $queryAndNs === false ) {
-                       return $query;
-               }
-               $this->namespaces = $queryAndNs[1];
-               return $queryAndNs[0];
+               return $query;
        }
 
        /**
@@ -364,11 +400,21 @@ abstract class SearchEngine {
         * or namespace names
         *
         * @param string $query
+        * @param bool $withAllKeyword activate support of the "all:" keyword and its
+        * translations to activate searching on all namespaces.
+        * @param bool $withPrefixSearchExtractNamespaceHook call the PrefixSearchExtractNamespace hook
+        *  if classic namespace identification did not match.
         * @return false|array false if no namespace was extracted, an array
         * with the parsed query at index 0 and an array of namespaces at index
         * 1 (or null for all namespaces).
-        */
-       public static function parseNamespacePrefixes( $query ) {
+        * @throws FatalError
+        * @throws MWException
+        */
+       public static function parseNamespacePrefixes(
+               $query,
+               $withAllKeyword = true,
+               $withPrefixSearchExtractNamespaceHook = false
+       ) {
                global $wgContLang;
 
                $parsed = $query;
@@ -376,40 +422,48 @@ abstract class SearchEngine {
                        return false;
                }
                $extractedNamespace = null;
-               $allkeywords = [];
-
-               $allkeywords[] = wfMessage( 'searchall' )->inContentLanguage()->text() . ":";
-               // force all: so that we have a common syntax for all the wikis
-               if ( !in_array( 'all:', $allkeywords ) ) {
-                       $allkeywords[] = 'all:';
-               }
 
                $allQuery = false;
-               foreach ( $allkeywords as $kw ) {
-                       if ( strncmp( $query, $kw, strlen( $kw ) ) == 0 ) {
-                               $extractedNamespace = null;
-                               $parsed = substr( $query, strlen( $kw ) );
-                               $allQuery = true;
-                               break;
+               if ( $withAllKeyword ) {
+                       $allkeywords = [];
+
+                       $allkeywords[] = wfMessage( 'searchall' )->inContentLanguage()->text() . ":";
+                       // force all: so that we have a common syntax for all the wikis
+                       if ( !in_array( 'all:', $allkeywords ) ) {
+                               $allkeywords[] = 'all:';
+                       }
+
+                       foreach ( $allkeywords as $kw ) {
+                               if ( strncmp( $query, $kw, strlen( $kw ) ) == 0 ) {
+                                       $extractedNamespace = null;
+                                       $parsed = substr( $query, strlen( $kw ) );
+                                       $allQuery = true;
+                                       break;
+                               }
                        }
                }
 
                if ( !$allQuery && strpos( $query, ':' ) !== false ) {
-                       // TODO: should we unify with PrefixSearch::extractNamespace ?
                        $prefix = str_replace( ' ', '_', substr( $query, 0, strpos( $query, ':' ) ) );
                        $index = $wgContLang->getNsIndex( $prefix );
                        if ( $index !== false ) {
                                $extractedNamespace = [ $index ];
                                $parsed = substr( $query, strlen( $prefix ) + 1 );
+                       } elseif ( $withPrefixSearchExtractNamespaceHook ) {
+                               $hookNamespaces = [ NS_MAIN ];
+                               $hookQuery = $query;
+                               Hooks::run( 'PrefixSearchExtractNamespace', [ &$hookNamespaces, &$hookQuery ] );
+                               if ( $hookQuery !== $query ) {
+                                       $parsed = $hookQuery;
+                                       $extractedNamespace = $hookNamespaces;
+                               } else {
+                                       return false;
+                               }
                        } else {
                                return false;
                        }
                }
 
-               if ( trim( $parsed ) == '' ) {
-                       $parsed = $query; // prefix was the whole query
-               }
-
                return [ $parsed, $extractedNamespace ];
        }
 
@@ -467,7 +521,7 @@ abstract class SearchEngine {
         *
         * @todo This isn't ideal, we'd really like to have content-specific handling here
         * @param Title $t Title we're indexing
-        * @param Content $c Content of the page to index
+        * @param Content|null $c Content of the page to index
         * @return string
         */
        public function getTextFromContent( Title $t, Content $c = null ) {
@@ -492,37 +546,30 @@ abstract class SearchEngine {
         * @return string Simplified search string
         */
        protected function normalizeNamespaces( $search ) {
-               // Find a Title which is not an interwiki and is in NS_MAIN
-               $title = Title::newFromText( $search );
-               $ns = $this->namespaces;
-               if ( $title && !$title->isExternal() ) {
-                       $ns = [ $title->getNamespace() ];
-                       $search = $title->getText();
-                       if ( $ns[0] == NS_MAIN ) {
-                               $ns = $this->namespaces; // no explicit prefix, use default namespaces
-                               Hooks::run( 'PrefixSearchExtractNamespace', [ &$ns, &$search ] );
-                       }
-               } else {
-                       $title = Title::newFromText( $search . 'Dummy' );
-                       if ( $title && $title->getText() == 'Dummy'
-                                       && $title->getNamespace() != NS_MAIN
-                                       && !$title->isExternal()
-                       ) {
-                               $ns = [ $title->getNamespace() ];
-                               $search = '';
-                       } else {
-                               Hooks::run( 'PrefixSearchExtractNamespace', [ &$ns, &$search ] );
-                       }
+               $queryAndNs = self::parseNamespacePrefixes( $search, false, true );
+               if ( $queryAndNs !== false ) {
+                       $this->setNamespaces( $queryAndNs[1] );
+                       return $queryAndNs[0];
                }
-
-               $ns = array_map( function ( $space ) {
-                       return $space == NS_MEDIA ? NS_FILE : $space;
-               }, $ns );
-
-               $this->setNamespaces( $ns );
                return $search;
        }
 
+       /**
+        * Perform an overfetch of completion search results. This allows
+        * determining if another page of results is available.
+        *
+        * @param string $search
+        * @return SearchSuggestionSet
+        */
+       protected function completionSearchBackendOverfetch( $search ) {
+               $this->limit++;
+               try {
+                       return $this->completionSearchBackend( $search );
+               } finally {
+                       $this->limit--;
+               }
+       }
+
        /**
         * Perform a completion search.
         * Does not resolve namespaces and does not check variants.
@@ -560,7 +607,8 @@ abstract class SearchEngine {
                        return SearchSuggestionSet::emptySuggestionSet(); // Return empty result
                }
                $search = $this->normalizeNamespaces( $search );
-               return $this->processCompletionResults( $search, $this->completionSearchBackend( $search ) );
+               $suggestions = $this->completionSearchBackendOverfetch( $search );
+               return $this->processCompletionResults( $search, $suggestions );
        }
 
        /**
@@ -574,8 +622,8 @@ abstract class SearchEngine {
                }
                $search = $this->normalizeNamespaces( $search );
 
-               $results = $this->completionSearchBackend( $search );
-               $fallbackLimit = $this->limit - $results->getSize();
+               $results = $this->completionSearchBackendOverfetch( $search );
+               $fallbackLimit = 1 + $this->limit - $results->getSize();
                if ( $fallbackLimit > 0 ) {
                        global $wgContLang;
 
@@ -614,15 +662,26 @@ abstract class SearchEngine {
         * @return SearchSuggestionSet
         */
        protected function processCompletionResults( $search, SearchSuggestionSet $suggestions ) {
+               // We over-fetched to determine pagination. Shrink back down if we have extra results
+               // and mark if pagination is possible
+               $suggestions->shrink( $this->limit );
+
                $search = trim( $search );
                // preload the titles with LinkBatch
-               $titles = $suggestions->map( function ( SearchSuggestion $sugg ) {
+               $lb = new LinkBatch( $suggestions->map( function ( SearchSuggestion $sugg ) {
                        return $sugg->getSuggestedTitle();
-               } );
-               $lb = new LinkBatch( $titles );
+               } ) );
                $lb->setCaller( __METHOD__ );
                $lb->execute();
 
+               $diff = $suggestions->filter( function ( SearchSuggestion $sugg ) {
+                       return $sugg->getSuggestedTitle()->isKnown();
+               } );
+               if ( $diff > 0 ) {
+                       MediaWikiServices::getInstance()->getStatsdDataFactory()
+                               ->updateCount( 'search.completion.missing', $diff );
+               }
+
                $results = $suggestions->map( function ( SearchSuggestion $sugg ) {
                        return $sugg->getSuggestedTitle()->getPrefixedText();
                } );
@@ -830,7 +889,6 @@ abstract class SearchEngine {
                $setAugmentors = [];
                $rowAugmentors = [];
                Hooks::run( "SearchResultsAugment", [ &$setAugmentors, &$rowAugmentors ] );
-
                if ( !$setAugmentors && !$rowAugmentors ) {
                        // We're done here
                        return;
index 8cdca57..ecb6f43 100644 (file)
@@ -19,7 +19,7 @@ class SearchEngineFactory {
 
        /**
         * Create SearchEngine of the given type.
-        * @param string $type
+        * @param string|null $type
         * @return SearchEngine
         */
        public function create( $type = null ) {
index 20462cf..2cec241 100644 (file)
@@ -327,8 +327,8 @@ class SearchHighlighter {
         * @param string $text
         * @param int $start
         * @param int $end
-        * @param int &$posStart (out) actual start position
-        * @param int &$posEnd (out) actual end position
+        * @param int|null &$posStart (out) actual start position
+        * @param int|null &$posEnd (out) actual end position
         * @return string
         */
        function extract( $text, $start, $end, &$posStart = null, &$posEnd = null ) {
@@ -525,12 +525,12 @@ class SearchHighlighter {
                        }
                        --$contextlines;
                        // truncate function changes ... to relevant i18n message.
-                       $pre = $wgContLang->truncate( $m[1], - $contextchars, '...', false );
+                       $pre = $wgContLang->truncateForVisual( $m[1], - $contextchars, '...', false );
 
                        if ( count( $m ) < 3 ) {
                                $post = '';
                        } else {
-                               $post = $wgContLang->truncate( $m[3], $contextchars, '...', false );
+                               $post = $wgContLang->truncateForVisual( $m[3], $contextchars, '...', false );
                        }
 
                        $found = $m[2];
index 43bd3be..289f925 100644 (file)
@@ -21,6 +21,8 @@
  * @ingroup Search
  */
 
+use Wikimedia\Rdbms\IResultWrapper;
+
 /**
  * Search engine hook base class for Mssql (ConText).
  * @ingroup Search
@@ -32,7 +34,7 @@ class SearchMssql extends SearchDatabase {
         * @param string $term Raw search term
         * @return SqlSearchResultSet
         */
-       protected function doSearchText( $term ) {
+       protected function doSearchTextInDB( $term ) {
                $resultSet = $this->db->query( $this->getQuery( $this->filter( $term ), true ) );
                return new SqlSearchResultSet( $resultSet, $this->searchTerms );
        }
@@ -43,7 +45,7 @@ class SearchMssql extends SearchDatabase {
         * @param string $term Raw search term
         * @return SqlSearchResultSet
         */
-       protected function doSearchTitle( $term ) {
+       protected function doSearchTitleInDB( $term ) {
                $resultSet = $this->db->query( $this->getQuery( $this->filter( $term ), false ) );
                return new SqlSearchResultSet( $resultSet, $this->searchTerms );
        }
@@ -168,7 +170,7 @@ class SearchMssql extends SearchDatabase {
         * @param int $id
         * @param string $title
         * @param string $text
-        * @return bool|ResultWrapper
+        * @return bool|IResultWrapper
         */
        function update( $id, $title, $text ) {
                // We store the column data as UTF-8 byte order marked binary stream
@@ -191,7 +193,7 @@ class SearchMssql extends SearchDatabase {
         *
         * @param int $id
         * @param string $title
-        * @return bool|ResultWrapper
+        * @return bool|IResultWrapper
         */
        function updateTitle( $id, $title ) {
                $table = $this->db->tableName( 'searchindex' );
index 9a03ebe..6253b55 100644 (file)
@@ -167,7 +167,7 @@ class SearchMySQL extends SearchDatabase {
         * @param string $term Raw search term
         * @return SqlSearchResultSet
         */
-       protected function doSearchText( $term ) {
+       protected function doSearchTextInDB( $term ) {
                return $this->searchInternal( $term, true );
        }
 
@@ -177,7 +177,7 @@ class SearchMySQL extends SearchDatabase {
         * @param string $term Raw search term
         * @return SqlSearchResultSet
         */
-       protected function doSearchTitle( $term ) {
+       protected function doSearchTitleInDB( $term ) {
                return $this->searchInternal( $term, false );
        }
 
index 3141797..42bc62d 100644 (file)
@@ -3,28 +3,18 @@
  * A SearchResultSet wrapper for SearchNearMatcher
  */
 class SearchNearMatchResultSet extends SearchResultSet {
-       private $fetched = false;
-
        /**
         * @param Title|null $match Title if matched, else null
         */
        public function __construct( $match ) {
-               $this->result = $match;
-       }
-
-       public function numRows() {
-               return $this->result ? 1 : 0;
-       }
-
-       public function next() {
-               if ( $this->fetched || !$this->result ) {
-                       return false;
+               if ( $match === null ) {
+                       $this->results = [];
+               } else {
+                       $this->results = [ SearchResult::newFromTitle( $match, $this ) ];
                }
-               $this->fetched = true;
-               return SearchResult::newFromTitle( $this->result, $this );
        }
 
-       public function rewind() {
-               $this->fetched = false;
+       public function numRows() {
+               return $this->results ? 1 : 0;
        }
 }
index 7fe5b53..6d7e988 100644 (file)
@@ -64,7 +64,7 @@ class SearchOracle extends SearchDatabase {
         * @param string $term Raw search term
         * @return SqlSearchResultSet
         */
-       protected function doSearchText( $term ) {
+       protected function doSearchTextInDB( $term ) {
                if ( $term == '' ) {
                        return new SqlSearchResultSet( false, '' );
                }
@@ -79,7 +79,7 @@ class SearchOracle extends SearchDatabase {
         * @param string $term Raw search term
         * @return SqlSearchResultSet
         */
-       protected function doSearchTitle( $term ) {
+       protected function doSearchTitleInDB( $term ) {
                if ( $term == '' ) {
                        return new SqlSearchResultSet( false, '' );
                }
index 729e528..6d5f117 100644 (file)
@@ -37,7 +37,7 @@ class SearchPostgres extends SearchDatabase {
         * @param string $term Raw search term
         * @return SqlSearchResultSet
         */
-       protected function doSearchTitle( $term ) {
+       protected function doSearchTitleInDB( $term ) {
                $q = $this->searchQuery( $term, 'titlevector', 'page_title' );
                $olderror = error_reporting( E_ERROR );
                $resultSet = $this->db->query( $q, 'SearchPostgres', true );
@@ -45,7 +45,7 @@ class SearchPostgres extends SearchDatabase {
                return new SqlSearchResultSet( $resultSet, $this->searchTerms );
        }
 
-       protected function doSearchText( $term ) {
+       protected function doSearchTextInDB( $term ) {
                $q = $this->searchQuery( $term, 'textvector', 'old_text' );
                $olderror = error_reporting( E_ERROR );
                $resultSet = $this->db->query( $q, 'SearchPostgres', true );
index dc294c3..bd19a84 100644 (file)
@@ -57,8 +57,8 @@ class SearchResult {
        protected $searchEngine;
 
        /**
-        * A set of extension data.
-        * @var array[]
+        * A function returning a set of extension data.
+        * @var Closure|null
         */
        protected $extensionData;
 
@@ -66,7 +66,7 @@ class SearchResult {
         * Return a new SearchResult and initializes it with a title.
         *
         * @param Title $title
-        * @param SearchResultSet $parentSet
+        * @param SearchResultSet|null $parentSet
         * @return SearchResult
         */
        public static function newFromTitle( $title, SearchResultSet $parentSet = null ) {
@@ -267,17 +267,34 @@ class SearchResult {
         * @return array[]
         */
        public function getExtensionData() {
-               return $this->extensionData;
+               if ( $this->extensionData ) {
+                       return call_user_func( $this->extensionData );
+               } else {
+                       return [];
+               }
        }
 
        /**
         * Set extension data for this result.
         * The data is:
         * augmentor name => data
-        * @param array[] $extensionData
+        * @param Closure|array $extensionData Takes no arguments, returns
+        *  either array of extension data or null.
         */
-       public function setExtensionData( array $extensionData ) {
-               $this->extensionData = $extensionData;
+       public function setExtensionData( $extensionData ) {
+               if ( $extensionData instanceof Closure ) {
+                       $this->extensionData = $extensionData;
+               } elseif ( is_array( $extensionData ) ) {
+                       wfDeprecated( __METHOD__ . ' with array argument', 1.32 );
+                       $this->extensionData = function () use ( $extensionData ) {
+                               return $extensionData;
+                       };
+               } else {
+                       $type = is_object( $extensionData )
+                               ? get_class( $extensionData )
+                               : gettype( $extensionData );
+                       throw new \InvalidArgumentException(
+                               __METHOD__ . " must be called with Closure|array, but received $type" );
+               }
        }
-
 }
index e3eb4c2..e82779a 100644 (file)
@@ -24,8 +24,7 @@
 /**
  * @ingroup Search
  */
-class SearchResultSet {
-
+class SearchResultSet implements Countable, IteratorAggregate {
        /**
         * Types of interwiki results
         */
@@ -54,7 +53,7 @@ class SearchResultSet {
         * as an array.
         * @var SearchResult[]
         */
-       private $results;
+       protected $results;
 
        /**
         * Set of result's extra data, indexed per result id
@@ -65,8 +64,31 @@ class SearchResultSet {
         */
        protected $extraData = [];
 
-       public function __construct( $containedSyntax = false ) {
+       /**
+        * @var boolean True when there are more pages of search results available.
+        */
+       private $hasMoreResults;
+
+       /**
+        * @var ArrayIterator|null Iterator supporting BC iteration methods
+        */
+       private $bcIterator;
+
+       /**
+        * @param bool $containedSyntax True when query is not requesting a simple
+        *  term match
+        * @param bool $hasMoreResults True when there are more pages of search
+        *  results available.
+        */
+       public function __construct( $containedSyntax = false, $hasMoreResults = false ) {
+               if ( static::class === __CLASS__ ) {
+                       // This class will eventually be abstract. SearchEngine implementations
+                       // already have to extend this class anyways to provide the actual
+                       // search results.
+                       wfDeprecated( __METHOD__, 1.32 );
+               }
                $this->containedSyntax = $containedSyntax;
+               $this->hasMoreResults = $hasMoreResults;
        }
 
        /**
@@ -81,7 +103,11 @@ class SearchResultSet {
        }
 
        function numRows() {
-               return 0;
+               return $this->count();
+       }
+
+       final public function count() {
+               return count( $this->extractResults() );
        }
 
        /**
@@ -171,20 +197,39 @@ class SearchResultSet {
 
        /**
         * Fetches next search result, or false.
-        * STUB
-        * FIXME: refactor as iterator, so we could use nicer interfaces.
-        * @deprecated since 1.32; Use self::extractResults()
+        * @deprecated since 1.32; Use self::extractResults() or foreach
         * @return SearchResult|false
         */
-       function next() {
-               return false;
+       public function next() {
+               wfDeprecated( __METHOD__, '1.32' );
+               $it = $this->bcIterator();
+               $searchResult = $it->current();
+               $it->next();
+               return $searchResult ?? false;
        }
 
        /**
         * Rewind result set back to beginning
-        * @deprecated since 1.32; Use self::extractResults()
+        * @deprecated since 1.32; Use self::extractResults() or foreach
         */
-       function rewind() {
+       public function rewind() {
+               wfDeprecated( __METHOD__, '1.32' );
+               $this->bcIterator()->rewind();
+       }
+
+       private function bcIterator() {
+               if ( $this->bcIterator === null ) {
+                       $this->bcIterator = 'RECURSION';
+                       $this->bcIterator = $this->getIterator();
+               } elseif ( $this->bcIterator === 'RECURSION' ) {
+                       // Either next/rewind or extractResults must be implemented.  This
+                       // class was potentially instantiated directly. It should be
+                       // abstract with abstract methods to enforce this but that's a
+                       // breaking change...
+                       wfDeprecated( static::class . ' without implementing extractResults', '1.32' );
+                       $this->bcIterator = new ArrayIterator( [] );
+               }
+               return $this->bcIterator;
        }
 
        /**
@@ -204,6 +249,34 @@ class SearchResultSet {
                return $this->containedSyntax;
        }
 
+       /**
+        * @return bool True when there are more pages of search results available.
+        */
+       public function hasMoreResults() {
+               return $this->hasMoreResults;
+       }
+
+       /**
+        * @param int $limit Shrink result set to $limit and flag
+        *  if more results are available.
+        */
+       public function shrink( $limit ) {
+               if ( $this->count() > $limit ) {
+                       $this->hasMoreResults = true;
+                       // shrinking result set for implementations that
+                       // have not implemented extractResults and use
+                       // the default cache location. Other implementations
+                       // must override this as well.
+                       if ( is_array( $this->results ) ) {
+                               $this->results = array_slice( $this->results, 0, $limit );
+                       } else {
+                               throw new \UnexpectedValueException(
+                                       "When overriding result store extending classes must "
+                                       . " also override " . __METHOD__ );
+                       }
+               }
+       }
+
        /**
         * Extract all the results in the result set as array.
         * @return SearchResult[]
@@ -258,15 +331,15 @@ class SearchResultSet {
        /**
         * Returns extra data for specific result and store it in SearchResult object.
         * @param SearchResult $result
-        * @return array|null List of data as name => value or null if none present.
         */
        public function augmentResult( SearchResult $result ) {
                $id = $result->getTitle()->getArticleID();
-               if ( !$id || !isset( $this->extraData[$id] ) ) {
-                       return null;
+               if ( $id === -1 ) {
+                       return;
                }
-               $result->setExtensionData( $this->extraData[$id] );
-               return $this->extraData[$id];
+               $result->setExtensionData( function () use ( $id ) {
+                       return $this->extraData[$id] ?? [];
+               } );
        }
 
        /**
@@ -278,4 +351,8 @@ class SearchResultSet {
        public function getOffset() {
                return null;
        }
+
+       final public function getIterator() {
+               return new ArrayIterator( $this->extractResults() );
+       }
 }
index 1dc37d2..0ed477a 100644 (file)
@@ -156,7 +156,7 @@ class SearchSqlite extends SearchDatabase {
         * @param string $term Raw search term
         * @return SqlSearchResultSet
         */
-       protected function doSearchText( $term ) {
+       protected function doSearchTextInDB( $term ) {
                return $this->searchInternal( $term, true );
        }
 
@@ -166,7 +166,7 @@ class SearchSqlite extends SearchDatabase {
         * @param string $term Raw search term
         * @return SqlSearchResultSet
         */
-       protected function doSearchTitle( $term ) {
+       protected function doSearchTitleInDB( $term ) {
                return $this->searchInternal( $term, false );
        }
 
index aced5e1..cb1f831 100644 (file)
@@ -35,6 +35,11 @@ class SearchSuggestionSet {
         */
        private $pageMap = [];
 
+       /**
+        * @var bool Are more results available?
+        */
+       private $hasMoreResults;
+
        /**
         * Builds a new set of suggestions.
         *
@@ -45,8 +50,10 @@ class SearchSuggestionSet {
         * unexpected behaviors.
         *
         * @param SearchSuggestion[] $suggestions (must be sorted by score)
+        * @param bool $hasMoreResults Are more results available?
         */
-       public function __construct( array $suggestions ) {
+       public function __construct( array $suggestions, $hasMoreResults = false ) {
+               $this->hasMoreResults = $hasMoreResults;
                foreach ( $suggestions as $suggestion ) {
                        $pageID = $suggestion->getSuggestedTitleID();
                        if ( $pageID && empty( $this->pageMap[$pageID] ) ) {
@@ -56,6 +63,13 @@ class SearchSuggestionSet {
                }
        }
 
+       /**
+        * @return bool Are more results available?
+        */
+       public function hasMoreResults() {
+               return $this->hasMoreResults;
+       }
+
        /**
         * Get the list of suggestions.
         * @return SearchSuggestion[]
@@ -73,6 +87,18 @@ class SearchSuggestionSet {
                return array_map( $callback, $this->suggestions );
        }
 
+       /**
+        * Filter the suggestions array
+        * @param callback $callback Callable accepting single SearchSuggestion
+        *  instance returning bool false to remove the item.
+        * @return int The number of suggestions removed
+        */
+       public function filter( $callback ) {
+               $before = count( $this->suggestions );
+               $this->suggestions = array_values( array_filter( $this->suggestions, $callback ) );
+               return $before - count( $this->suggestions );
+       }
+
        /**
         * Add a new suggestion at the end.
         * If the score of the new suggestion is greater than the worst one,
@@ -167,6 +193,7 @@ class SearchSuggestionSet {
        public function shrink( $limit ) {
                if ( count( $this->suggestions ) > $limit ) {
                        $this->suggestions = array_slice( $this->suggestions, 0, $limit );
+                       $this->hasMoreResults = true;
                }
        }
 
@@ -177,14 +204,15 @@ class SearchSuggestionSet {
         * NOTE: Suggestion scores will be generated.
         *
         * @param Title[] $titles
+        * @param bool $hasMoreResults Are more results available?
         * @return SearchSuggestionSet
         */
-       public static function fromTitles( array $titles ) {
+       public static function fromTitles( array $titles, $hasMoreResults = false ) {
                $score = count( $titles );
                $suggestions = array_map( function ( $title ) use ( &$score ) {
                        return SearchSuggestion::fromTitle( $score--, $title );
                }, $titles );
-               return new SearchSuggestionSet( $suggestions );
+               return new SearchSuggestionSet( $suggestions, $hasMoreResults );
        }
 
        /**
@@ -193,14 +221,15 @@ class SearchSuggestionSet {
         * NOTE: Suggestion scores will be generated.
         *
         * @param string[] $titles
+        * @param bool $hasMoreResults Are more results available?
         * @return SearchSuggestionSet
         */
-       public static function fromStrings( array $titles ) {
+       public static function fromStrings( array $titles, $hasMoreResults = false ) {
                $score = count( $titles );
                $suggestions = array_map( function ( $title ) use ( &$score ) {
                        return SearchSuggestion::fromText( $score--, $title );
                }, $titles );
-               return new SearchSuggestionSet( $suggestions );
+               return new SearchSuggestionSet( $suggestions, $hasMoreResults );
        }
 
        /**
index 53d09e8..022dc0a 100644 (file)
@@ -7,8 +7,11 @@ use Wikimedia\Rdbms\ResultWrapper;
  * @ingroup Search
  */
 class SqlSearchResultSet extends SearchResultSet {
+       /** @var ResultWrapper Result object from database */
        protected $resultSet;
+       /** @var string Requested search query */
        protected $terms;
+       /** @var int|null Total number of hits for $terms */
        protected $totalHits;
 
        function __construct( ResultWrapper $resultSet, $terms, $total = null ) {
@@ -29,25 +32,21 @@ class SqlSearchResultSet extends SearchResultSet {
                return $this->resultSet->numRows();
        }
 
-       function next() {
+       public function extractResults() {
                if ( $this->resultSet === false ) {
-                       return false;
-               }
-
-               $row = $this->resultSet->fetchObject();
-               if ( $row === false ) {
-                       return false;
+                       return [];
                }
 
-               return SearchResult::newFromTitle(
-                       Title::makeTitle( $row->page_namespace, $row->page_title ), $this
-               );
-       }
-
-       function rewind() {
-               if ( $this->resultSet ) {
+               if ( $this->results === null ) {
+                       $this->results = [];
                        $this->resultSet->rewind();
+                       while ( ( $row = $this->resultSet->fetchObject() ) !== false ) {
+                               $this->results[] = SearchResult::newFromTitle(
+                                       Title::makeTitle( $row->page_namespace, $row->page_title ), $this
+                               );
+                       }
                }
+               return $this->results;
        }
 
        function free() {
index 9f09e22..30f8295 100644 (file)
@@ -55,6 +55,11 @@ class ServiceContainer implements DestructibleService {
         */
        private $serviceInstantiators = [];
 
+       /**
+        * @var callable[][]
+        */
+       private $serviceManipulators = [];
+
        /**
         * @var bool[] disabled status, per service name
         */
@@ -151,6 +156,22 @@ class ServiceContainer implements DestructibleService {
                        $this->serviceInstantiators,
                        $newInstantiators
                );
+
+               $newManipulators = array_diff(
+                       array_keys( $container->serviceManipulators ),
+                       $skip
+               );
+
+               foreach ( $newManipulators as $name ) {
+                       if ( isset( $this->serviceManipulators[$name] ) ) {
+                               $this->serviceManipulators[$name] = array_merge(
+                                       $this->serviceManipulators[$name],
+                                       $container->serviceManipulators[$name]
+                               );
+                       } else {
+                               $this->serviceManipulators[$name] = $container->serviceManipulators[$name];
+                       }
+               }
        }
 
        /**
@@ -185,7 +206,7 @@ class ServiceContainer implements DestructibleService {
                        throw new NoSuchServiceException( $name );
                }
 
-               return isset( $this->services[$name] ) ? $this->services[$name] : null;
+               return $this->services[$name] ?? null;
        }
 
        /**
@@ -199,7 +220,7 @@ class ServiceContainer implements DestructibleService {
         * Define a new service. The service must not be known already.
         *
         * @see getService().
-        * @see replaceService().
+        * @see redefineService().
         *
         * @param string $name The name of the service to register, for use with getService().
         * @param callable $instantiator Callback that returns a service instance.
@@ -224,7 +245,9 @@ class ServiceContainer implements DestructibleService {
         *
         * @see defineService().
         *
-        * @note This causes any previously instantiated instance of the service to be discarded.
+        * @note This will fail if the service was already instantiated. If the service was previously
+        * disabled, it will be re-enabled by this call. Any manipulators registered for the service
+        * will remain in place.
         *
         * @param string $name The name of the service to register.
         * @param callable $instantiator Callback function that returns a service instance.
@@ -233,7 +256,8 @@ class ServiceContainer implements DestructibleService {
         *        Any extra instantiation parameters provided to the constructor will be
         *        passed as subsequent parameters when invoking the instantiator.
         *
-        * @throws RuntimeException if $name is not a known service.
+        * @throws NoSuchServiceException if $name is not a known service.
+        * @throws CannotReplaceActiveServiceException if the service was already instantiated.
         */
        public function redefineService( $name, callable $instantiator ) {
                Assert::parameterType( 'string', $name, '$name' );
@@ -250,6 +274,46 @@ class ServiceContainer implements DestructibleService {
                unset( $this->disabled[$name] );
        }
 
+       /**
+        * Add a service manipulator callback for the given service.
+        * This method may be used by extensions that need to wrap, replace, or re-configure a
+        * service. It would typically be called from a MediaWikiServices hook handler.
+        *
+        * The manipulator callback is called just after the service is instantiated.
+        * It can call methods on the service to change configuration, or wrap or otherwise
+        * replace it.
+        *
+        * @see defineService().
+        * @see redefineService().
+        *
+        * @note This will fail if the service was already instantiated.
+        *
+        * @since 1.32
+        *
+        * @param string $name The name of the service to manipulate.
+        * @param callable $manipulator Callback function that manipulates, wraps or replaces a
+        * service instance. The callback receives the new service instance and this the
+        * ServiceContainer as parameters, as well as any extra instantiation parameters specified
+        * when constructing this ServiceContainer. If the callback returns a value, that
+        * value replaces the original service instance.
+        *
+        * @throws NoSuchServiceException if $name is not a known service.
+        * @throws CannotReplaceActiveServiceException if the service was already instantiated.
+        */
+       public function addServiceManipulator( $name, callable $manipulator ) {
+               Assert::parameterType( 'string', $name, '$name' );
+
+               if ( !$this->hasService( $name ) ) {
+                       throw new NoSuchServiceException( $name );
+               }
+
+               if ( isset( $this->services[$name] ) ) {
+                       throw new CannotReplaceActiveServiceException( $name );
+               }
+
+               $this->serviceManipulators[$name][] = $manipulator;
+       }
+
        /**
         * Disables a service.
         *
@@ -355,11 +419,28 @@ class ServiceContainer implements DestructibleService {
         */
        private function createService( $name ) {
                if ( isset( $this->serviceInstantiators[$name] ) ) {
-                       $service = call_user_func_array(
-                               $this->serviceInstantiators[$name],
-                               array_merge( [ $this ], $this->extraInstantiationParams )
+                       $service = ( $this->serviceInstantiators[$name] )(
+                               $this,
+                               ...$this->extraInstantiationParams
                        );
-                       // NOTE: when adding more wiring logic here, make sure copyWiring() is kept in sync!
+
+                       if ( isset( $this->serviceManipulators[$name] ) ) {
+                               foreach ( $this->serviceManipulators[$name] as $callback ) {
+                                       $ret = call_user_func_array(
+                                               $callback,
+                                               array_merge( [ $service, $this ], $this->extraInstantiationParams )
+                                       );
+
+                                       // If the manipulator callback returns an object, that object replaces
+                                       // the original service instance. This allows the manipulator to wrap
+                                       // or fully replace the service.
+                                       if ( $ret !== null ) {
+                                               $service = $ret;
+                                       }
+                               }
+                       }
+
+                       // NOTE: when adding more wiring logic here, make sure importWiring() is kept in sync!
                } else {
                        throw new NoSuchServiceException( $name );
                }
index 74925bd..aaa522a 100644 (file)
@@ -339,7 +339,7 @@ class CookieSessionProvider extends SessionProvider {
         * @param \WebRequest $request
         * @param string $key
         * @param string $prefix
-        * @param mixed $default
+        * @param mixed|null $default
         * @return mixed
         */
        protected function getCookie( $request, $key, $prefix, $default = null ) {
index 1cab3d3..200b913 100644 (file)
@@ -84,9 +84,7 @@ abstract class ImmutableSessionProviderWithCookie extends SessionProvider {
                        );
                }
 
-               $prefix = isset( $this->sessionCookieOptions['prefix'] )
-                       ? $this->sessionCookieOptions['prefix']
-                       : $this->config->get( 'CookiePrefix' );
+               $prefix = $this->sessionCookieOptions['prefix'] ?? $this->config->get( 'CookiePrefix' );
                $id = $request->getCookie( $this->sessionCookieName, $prefix );
                return SessionManager::validateSessionId( $id ) ? $id : null;
        }
@@ -141,9 +139,7 @@ abstract class ImmutableSessionProviderWithCookie extends SessionProvider {
                        return [];
                }
 
-               $prefix = isset( $this->sessionCookieOptions['prefix'] )
-                       ? $this->sessionCookieOptions['prefix']
-                       : $this->config->get( 'CookiePrefix' );
+               $prefix = $this->sessionCookieOptions['prefix'] ?? $this->config->get( 'CookiePrefix' );
                return [ $prefix . $this->sessionCookieName ];
        }
 
index b76f0ff..157cc52 100644 (file)
@@ -122,22 +122,28 @@ class PHPSessionHandler implements \SessionHandlerInterface {
                // Close any auto-started session, before we replace it
                session_write_close();
 
-               // Tell PHP not to mess with cookies itself
-               ini_set( 'session.use_cookies', 0 );
-               ini_set( 'session.use_trans_sid', 0 );
-
-               // T124510: Disable automatic PHP session related cache headers.
-               // MediaWiki adds it's own headers and the default PHP behavior may
-               // set headers such as 'Pragma: no-cache' that cause problems with
-               // some user agents.
-               session_cache_limiter( '' );
-
-               // Also set a sane serialization handler
-               \Wikimedia\PhpSessionSerializer::setSerializeHandler();
-
-               // Register this as the save handler, and register an appropriate
-               // shutdown function.
-               session_set_save_handler( self::$instance, true );
+               try {
+                       \Wikimedia\suppressWarnings();
+
+                       // Tell PHP not to mess with cookies itself
+                       ini_set( 'session.use_cookies', 0 );
+                       ini_set( 'session.use_trans_sid', 0 );
+
+                       // T124510: Disable automatic PHP session related cache headers.
+                       // MediaWiki adds it's own headers and the default PHP behavior may
+                       // set headers such as 'Pragma: no-cache' that cause problems with
+                       // some user agents.
+                       session_cache_limiter( '' );
+
+                       // Also set a sane serialization handler
+                       \Wikimedia\PhpSessionSerializer::setSerializeHandler();
+
+                       // Register this as the save handler, and register an appropriate
+                       // shutdown function.
+                       session_set_save_handler( self::$instance, true );
+               } finally {
+                       \Wikimedia\restoreWarnings();
+               }
        }
 
        /**
@@ -162,39 +168,12 @@ class PHPSessionHandler implements \SessionHandlerInterface {
                }
        }
 
-       /**
-        * Workaround for PHP5 bug
-        *
-        * PHP5 has a bug in handling boolean return values for
-        * SessionHandlerInterface methods, it expects 0 or -1 instead of true or
-        * false. See <https://wiki.php.net/rfc/session.user.return-value>.
-        *
-        * PHP7 and HHVM are not affected.
-        *
-        * @todo When we drop support for Zend PHP 5, this can be removed.
-        * @return bool|int
-        * @codeCoverageIgnore
-        */
-       protected static function returnSuccess() {
-               return defined( 'HHVM_VERSION' ) || version_compare( PHP_VERSION, '7.0.0', '>=' ) ? true : 0;
-       }
-
-       /**
-        * Workaround for PHP5 bug
-        * @see self::returnSuccess()
-        * @return bool|int
-        * @codeCoverageIgnore
-        */
-       protected static function returnFailure() {
-               return defined( 'HHVM_VERSION' ) || version_compare( PHP_VERSION, '7.0.0', '>=' ) ? false : -1;
-       }
-
        /**
         * Initialize the session (handler)
         * @private For internal use only
         * @param string $save_path Path used to store session files (ignored)
         * @param string $session_name Session name (ignored)
-        * @return bool|int Success (see self::returnSuccess())
+        * @return true
         */
        public function open( $save_path, $session_name ) {
                if ( self::$instance !== $this ) {
@@ -203,20 +182,20 @@ class PHPSessionHandler implements \SessionHandlerInterface {
                if ( !$this->enable ) {
                        throw new \BadMethodCallException( 'Attempt to use PHP session management' );
                }
-               return self::returnSuccess();
+               return true;
        }
 
        /**
         * Close the session (handler)
         * @private For internal use only
-        * @return bool|int Success (see self::returnSuccess())
+        * @return true
         */
        public function close() {
                if ( self::$instance !== $this ) {
                        throw new \UnexpectedValueException( __METHOD__ . ': Wrong instance called!' );
                }
                $this->sessionFieldCache = [];
-               return self::returnSuccess();
+               return true;
        }
 
        /**
@@ -251,7 +230,7 @@ class PHPSessionHandler implements \SessionHandlerInterface {
         * @param string $dataStr Session data. Not that you should ever call this
         *   directly, but note that this has the same issues with code injection
         *   via user-controlled data as does PHP's unserialize function.
-        * @return bool|int Success (see self::returnSuccess())
+        * @return bool
         */
        public function write( $id, $dataStr ) {
                if ( self::$instance !== $this ) {
@@ -270,20 +249,20 @@ class PHPSessionHandler implements \SessionHandlerInterface {
                                [
                                        'session' => $id,
                        ] );
-                       return self::returnSuccess();
+                       return true;
                }
 
                // First, decode the string PHP handed us
                $data = \Wikimedia\PhpSessionSerializer::decode( $dataStr );
                if ( $data === null ) {
                        // @codeCoverageIgnoreStart
-                       return self::returnFailure();
+                       return false;
                        // @codeCoverageIgnoreEnd
                }
 
                // Now merge the data into the Session object.
                $changed = false;
-               $cache = isset( $this->sessionFieldCache[$id] ) ? $this->sessionFieldCache[$id] : [];
+               $cache = $this->sessionFieldCache[$id] ?? [];
                foreach ( $data as $key => $value ) {
                        if ( !array_key_exists( $key, $cache ) ) {
                                if ( $session->exists( $key ) ) {
@@ -350,14 +329,14 @@ class PHPSessionHandler implements \SessionHandlerInterface {
 
                $session->persist();
 
-               return self::returnSuccess();
+               return true;
        }
 
        /**
         * Destroy a session
         * @private For internal use only
         * @param string $id Session id
-        * @return bool|int Success (see self::returnSuccess())
+        * @return true
         */
        public function destroy( $id ) {
                if ( self::$instance !== $this ) {
@@ -370,14 +349,14 @@ class PHPSessionHandler implements \SessionHandlerInterface {
                if ( $session ) {
                        $session->clear();
                }
-               return self::returnSuccess();
+               return true;
        }
 
        /**
         * Execute garbage collection.
         * @private For internal use only
         * @param int $maxlifetime Maximum session life time (ignored)
-        * @return bool|int Success (see self::returnSuccess())
+        * @return true
         * @codeCoverageIgnore See T135576
         */
        public function gc( $maxlifetime ) {
@@ -386,6 +365,6 @@ class PHPSessionHandler implements \SessionHandlerInterface {
                }
                $before = date( 'YmdHis', time() );
                $this->store->deleteObjectsExpiringBefore( $before );
-               return self::returnSuccess();
+               return true;
        }
 }
index 024bf9a..3dc8299 100644 (file)
@@ -291,7 +291,7 @@ final class Session implements \Countable, \Iterator, \ArrayAccess {
        /**
         * Fetch a value from the session
         * @param string|int $key
-        * @param mixed $default Returned if $this->exists( $key ) would be false
+        * @param mixed|null $default Returned if $this->exists( $key ) would be false
         * @return mixed
         */
        public function get( $key, $default = null ) {
@@ -481,7 +481,7 @@ final class Session implements \Countable, \Iterator, \ArrayAccess {
 
                // Encrypt
                // @todo: import a pure-PHP library for AES instead of doing $wgSessionInsecureSecrets
-               $iv = \MWCryptRand::generate( 16, true );
+               $iv = random_bytes( 16 );
                $algorithm = self::getEncryptionAlgorithm();
                switch ( $algorithm[0] ) {
                        case 'openssl':
@@ -522,7 +522,7 @@ final class Session implements \Countable, \Iterator, \ArrayAccess {
        /**
         * Fetch a value from the session that was set with self::setSecret()
         * @param string|int $key
-        * @param mixed $default Returned if $this->exists( $key ) would be false or decryption fails
+        * @param mixed|null $default Returned if $this->exists( $key ) would be false or decryption fails
         * @return mixed
         */
        public function getSecret( $key, $default = null ) {
index a376037..58163c6 100644 (file)
@@ -457,7 +457,7 @@ final class SessionBackend {
 
        /**
         * Set the "logged out" timestamp
-        * @param int $ts
+        * @param int|null $ts
         */
        public function setLoggedOutTimestamp( $ts = null ) {
                $ts = (int)$ts;
index 287da9d..577e03a 100644 (file)
@@ -282,7 +282,7 @@ class SessionInfo {
         * @return int Negative if $a < $b, positive if $a > $b, zero if equal
         */
        public static function compare( $a, $b ) {
-               return $a->getPriority() - $b->getPriority();
+               return $a->getPriority() <=> $b->getPriority();
        }
 
 }
index 603985f..ceb9ceb 100644 (file)
@@ -455,7 +455,7 @@ final class SessionManager implements SessionManagerInterface {
         */
        public function getProvider( $name ) {
                $providers = $this->getProviders();
-               return isset( $providers[$name] ) ? $providers[$name] : null;
+               return $providers[$name] ?? null;
        }
 
        /**
index 02ae23d..896e62f 100644 (file)
@@ -24,6 +24,7 @@
 namespace MediaWiki\Session;
 
 use Language;
+use Message;
 
 /**
  * This exists to make IDEs happy, so they don't see the
index 8ae517e..1154e05 100644 (file)
@@ -437,12 +437,12 @@ class Command {
                        @trigger_error( '' );
                        restore_error_handler();
 
-                       $readPipes = wfArrayFilterByKey( $pipes, function ( $fd ) use ( $desc ) {
+                       $readPipes = array_filter( $pipes, function ( $fd ) use ( $desc ) {
                                return $desc[$fd][0] === 'pipe' && $desc[$fd][1] === 'r';
-                       } );
-                       $writePipes = wfArrayFilterByKey( $pipes, function ( $fd ) use ( $desc ) {
+                       }, ARRAY_FILTER_USE_KEY );
+                       $writePipes = array_filter( $pipes, function ( $fd ) use ( $desc ) {
                                return $desc[$fd][0] === 'pipe' && $desc[$fd][1] === 'w';
-                       } );
+                       }, ARRAY_FILTER_USE_KEY );
                        // stream_select parameter names are from the POV of us being able to do the operation;
                        // proc_open desriptor types are from the POV of the process doing it.
                        // So $writePipes is passed as the $read parameter and $readPipes as $write.
index d818930..7aed05f 100644 (file)
@@ -65,7 +65,7 @@ class FirejailCommand extends Command {
                        $splitCommand = explode( ' ', $command, 2 );
                        $this->logger->debug(
                                "firejail: Command {$splitCommand[0]} {params} has no restrictions",
-                               [ 'params' => isset( $splitCommand[1] ) ? $splitCommand[1] : '' ]
+                               [ 'params' => $splitCommand[1] ?? '' ]
                        );
                        return parent::buildFinalCommand( $command );
                }
index 742e142..0ddc443 100644 (file)
@@ -43,18 +43,6 @@ use MediaWiki\MediaWikiServices;
  */
 class Shell {
 
-       /**
-        * Apply a default set of restrictions for improved
-        * security out of the box.
-        *
-        * Equal to NO_ROOT | SECCOMP | PRIVATE_DEV | NO_LOCALSETTINGS
-        *
-        * @note This value will change over time to provide increased security
-        *       by default, and is not guaranteed to be backwards-compatible.
-        * @since 1.31
-        */
-       const RESTRICT_DEFAULT = 39;
-
        /**
         * Disallow any root access. Any setuid binaries
         * will be run without elevated access.
@@ -101,6 +89,17 @@ class Shell {
         */
        const NO_LOCALSETTINGS = 32;
 
+       /**
+        * Apply a default set of restrictions for improved
+        * security out of the box.
+        *
+        * @note This value will change over time to provide increased security
+        *       by default, and is not guaranteed to be backwards-compatible.
+        * @since 1.31
+        */
+       const RESTRICT_DEFAULT = self::NO_ROOT | self::SECCOMP | self::PRIVATE_DEV |
+                                                        self::NO_LOCALSETTINGS;
+
        /**
         * Don't apply any restrictions
         *
@@ -111,23 +110,23 @@ class Shell {
        /**
         * Returns a new instance of Command class
         *
-        * @param string|string[] $command String or array of strings representing the command to
+        * @note You should check Shell::isDisabled() before calling this
+        * @param string|string[] ...$commands String or array of strings representing the command to
         * be executed, each value will be escaped.
         *   Example:   [ 'convert', '-font', 'font name' ] would produce "'convert' '-font' 'font name'"
         * @return Command
         */
-       public static function command( $command ) {
-               $args = func_get_args();
-               if ( count( $args ) === 1 && is_array( reset( $args ) ) ) {
+       public static function command( ...$commands ) {
+               if ( count( $commands ) === 1 && is_array( reset( $commands ) ) ) {
                        // If only one argument has been passed, and that argument is an array,
                        // treat it as a list of arguments
-                       $args = reset( $args );
+                       $commands = reset( $commands );
                }
                $command = MediaWikiServices::getInstance()
                        ->getShellCommandFactory()
                        ->create();
 
-               return $command->params( $args );
+               return $command->params( $commands );
        }
 
        /**
@@ -157,12 +156,11 @@ class Shell {
         * (https://bugs.php.net/bug.php?id=26285) and the locale problems on Linux in
         * PHP 5.2.6+ (bug backported to earlier distro releases of PHP).
         *
-        * @param string $args,... strings to escape and glue together, or a single array of
-        *     strings parameter. Null values are ignored.
+        * @param string|string[] ...$args strings to escape and glue together, or a single
+        *     array of strings parameter. Null values are ignored.
         * @return string
         */
-       public static function escape( /* ... */ ) {
-               $args = func_get_args();
+       public static function escape( ...$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
@@ -226,6 +224,7 @@ class Shell {
         * Note that $parameters should be a flat array and an option with an argument
         * should consist of two consecutive items in the array (do not use "--option value").
         *
+        * @note You should check Shell::isDisabled() before calling this
         * @param string $script MediaWiki CLI script with full path
         * @param string[] $parameters Arguments and options to the script
         * @param array $options Associative array of options:
index f3cd1e8..625c899 100644 (file)
@@ -24,7 +24,7 @@
  * @file
  * @ingroup Site
  *
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
  * @author Jeroen De Dauw < jeroendedauw@gmail.com >
  * @author Katie Filbert < aude.wiki@gmail.com >
  */
index 7fcfbe5..b2403ce 100644 (file)
@@ -26,7 +26,7 @@ use Wikimedia\Rdbms\LoadBalancer;
  * @file
  * @ingroup Site
  *
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
  * @author Jeroen De Dauw < jeroendedauw@gmail.com >
  * @author Daniel Kinzler
  */
@@ -45,7 +45,7 @@ class DBSiteStore implements SiteStore {
        /**
         * @since 1.27
         *
-        * @todo: inject some kind of connection manager that is aware of the target wiki,
+        * @todo inject some kind of connection manager that is aware of the target wiki,
         * instead of injecting a LoadBalancer.
         *
         * @param LoadBalancer $dbLoadBalancer
@@ -198,7 +198,7 @@ class DBSiteStore implements SiteStore {
                                'site_type' => $site->getType(),
                                'site_group' => $site->getGroup(),
                                'site_source' => $site->getSource(),
-                               'site_language' => $site->getLanguageCode() === null ? '' : $site->getLanguageCode(),
+                               'site_language' => $site->getLanguageCode() ?? '',
                                'site_protocol' => $site->getProtocol(),
                                'site_domain' => strrev( $site->getDomain() ) . '.',
                                'site_data' => serialize( $site->getExtraData() ),
index 9654440..c168a47 100644 (file)
@@ -17,7 +17,7 @@
  *
  * @file
  *
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
  */
 
 /**
index 8a12c4f..a81ddca 100644 (file)
@@ -26,7 +26,7 @@ use UtfNormal\Validator;
  *
  * @since 1.27
  *
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
  * @author John Erling Blad < jeblad@gmail.com >
  * @author Daniel Kinzler
  * @author Jeroen De Dauw < jeroendedauw@gmail.com >
index e1e7ce6..14c9a73 100644 (file)
@@ -22,7 +22,7 @@ use MediaWiki\Site\MediaWikiPageNameNormalizer;
  *
  * @file
  * @ingroup Site
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
  * @author John Erling Blad < jeblad@gmail.com >
  * @author Daniel Kinzler
  * @author Jeroen De Dauw < jeroendedauw@gmail.com >
index f5e3f22..01b2a3c 100644 (file)
@@ -23,7 +23,7 @@
  * @file
  * @ingroup Site
  *
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
  * @author Jeroen De Dauw < jeroendedauw@gmail.com >
  */
 class Site implements Serializable {
index 01b838e..0c9f996 100644 (file)
@@ -24,7 +24,7 @@
  * @file
  * @ingroup Site
  *
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
  * @author Daniel Kinzler
  */
 class SiteExporter {
index 5e13d06..956bdab 100644 (file)
@@ -24,7 +24,7 @@
  * @file
  * @ingroup Site
  *
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
  * @author Daniel Kinzler
  */
 class SiteImporter {
index b942d6e..726ab46 100644 (file)
@@ -23,7 +23,7 @@
  * @file
  * @ingroup Site
  *
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
  * @author Jeroen De Dauw < jeroendedauw@gmail.com >
  */
 class SiteList extends GenericArrayObject {
index 610bf0b..70fc453 100644 (file)
@@ -23,7 +23,7 @@
  * @file
  * @ingroup Site
  *
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
  */
 interface SiteLookup {
 
index 2f8a113..91d9ef7 100644 (file)
@@ -23,7 +23,7 @@
  * @file
  * @ingroup Site
  *
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
  * @author Daniel Kinzler
  */
 class SiteSQLStore {
@@ -39,7 +39,7 @@ class SiteSQLStore {
         *             or MediaWikiServices::getSiteLookup() instead.
         *
         * @param null $sitesTable IGNORED
-        * @param null $cache IGNORED
+        * @param BagOStuff|null $cache IGNORED
         *
         * @return SiteStore
         */
index 10e0c1b..13800d0 100644 (file)
@@ -23,7 +23,7 @@
  * @file
  * @ingroup Site
  *
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
  * @author Jeroen De Dauw < jeroendedauw@gmail.com >
  */
 interface SiteStore extends SiteLookup {
index b4046e3..f0d6ce1 100644 (file)
@@ -20,7 +20,7 @@
  *
  * @file
  *
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
  */
 class SitesCacheFileBuilder {
 
index e1f2969..5c4d812 100644 (file)
@@ -18,6 +18,9 @@
  * @file
  */
 
+use Wikimedia\WrappedString;
+use Wikimedia\WrappedStringList;
+
 /**
  * New base template for a skin's template extended from QuickTemplate
  * this class features helper methods that provide common ways of interacting
@@ -33,7 +36,7 @@ abstract class BaseTemplate extends QuickTemplate {
         * @return Message
         */
        public function getMsg( $name /* ... */ ) {
-               return call_user_func_array( [ $this->getSkin(), 'msg' ], func_get_args() );
+               return $this->getSkin()->msg( ...func_get_args() );
        }
 
        function msg( $str ) {
@@ -363,7 +366,7 @@ abstract class BaseTemplate extends QuickTemplate {
                if ( isset( $item['text'] ) ) {
                        $text = $item['text'];
                } else {
-                       $text = wfMessage( isset( $item['msg'] ) ? $item['msg'] : $key )->text();
+                       $text = wfMessage( $item['msg'] ?? $key )->text();
                }
 
                $html = htmlspecialchars( $text );
@@ -375,9 +378,7 @@ abstract class BaseTemplate extends QuickTemplate {
                        }
                        while ( count( $wrapper ) > 0 ) {
                                $element = array_pop( $wrapper );
-                               $html = Html::rawElement( $element['tag'], isset( $element['attributes'] )
-                                       ? $element['attributes']
-                                       : null, $html );
+                               $html = Html::rawElement( $element['tag'], $element['attributes'] ?? null, $html );
                        }
                }
 
@@ -514,7 +515,7 @@ abstract class BaseTemplate extends QuickTemplate {
                if ( isset( $item['itemtitle'] ) ) {
                        $attrs['title'] = $item['itemtitle'];
                }
-               return Html::rawElement( isset( $options['tag'] ) ? $options['tag'] : 'li', $attrs, $html );
+               return Html::rawElement( $options['tag'] ?? 'li', $attrs, $html );
        }
 
        function makeSearchInput( $attrs = [] ) {
@@ -558,11 +559,9 @@ abstract class BaseTemplate extends QuickTemplate {
                                unset( $buttonAttrs['height'] );
                                $imgAttrs = [
                                        'src' => $attrs['src'],
-                                       'alt' => isset( $attrs['alt'] )
-                                               ? $attrs['alt']
-                                               : wfMessage( 'searchbutton' )->text(),
-                                       'width' => isset( $attrs['width'] ) ? $attrs['width'] : null,
-                                       'height' => isset( $attrs['height'] ) ? $attrs['height'] : null,
+                                       'alt' => $attrs['alt'] ?? wfMessage( 'searchbutton' )->text(),
+                                       'width' => $attrs['width'] ?? null,
+                                       'height' => $attrs['height'] ?? null,
                                ];
                                return Html::rawElement( 'button', $buttonAttrs, Html::element( 'img', $imgAttrs ) );
                        default:
@@ -576,7 +575,7 @@ abstract class BaseTemplate extends QuickTemplate {
         * If you pass "flat" as an option then the returned array will be a flat array
         * of footer icons instead of a key/value array of footerlinks arrays broken
         * up into categories.
-        * @param string $option
+        * @param string|null $option
         * @return array|mixed
         */
        function getFooterLinks( $option = null ) {
@@ -598,10 +597,7 @@ abstract class BaseTemplate extends QuickTemplate {
 
                if ( $option == 'flat' ) {
                        // fold footerlinks into a single array using a bit of trickery
-                       $validFooterLinks = call_user_func_array(
-                               'array_merge',
-                               array_values( $validFooterLinks )
-                       );
+                       $validFooterLinks = array_merge( ...array_values( $validFooterLinks ) );
                }
 
                return $validFooterLinks;
@@ -616,7 +612,7 @@ abstract class BaseTemplate extends QuickTemplate {
         * in the list of footer icons. This is mostly useful for skins which only
         * display the text from footericons instead of the images and don't want a
         * duplicate copyright statement because footerlinks already rendered one.
-        * @param string $option
+        * @param string|null $option
         * @return array
         */
        function getFooterIcons( $option = null ) {
@@ -754,14 +750,14 @@ abstract class BaseTemplate extends QuickTemplate {
         * debug stuff. This should be called right before outputting the closing
         * body and html tags.
         *
-        * @return string
+        * @return string|WrappedStringList HTML
         * @since 1.29
         */
-       function getTrail() {
-               $html = MWDebug::getDebugHTML( $this->getSkin()->getContext() );
-               $html .= $this->get( 'bottomscripts' );
-               $html .= $this->get( 'reporttime' );
-
-               return $html;
+       public function getTrail() {
+               return WrappedString::join( "\n", [
+                       MWDebug::getDebugHTML( $this->getSkin()->getContext() ),
+                       $this->get( 'bottomscripts' ),
+                       $this->get( 'reporttime' )
+               ] );
        }
 }
index aa20e20..969ac51 100644 (file)
@@ -35,7 +35,7 @@ abstract class QuickTemplate {
        protected $config;
 
        /**
-        * @param Config $config
+        * @param Config|null $config
         */
        function __construct( Config $config = null ) {
                $this->data = [];
@@ -73,15 +73,11 @@ abstract class QuickTemplate {
         * Gets the template data requested
         * @since 1.22
         * @param string $name Key for the data
-        * @param mixed $default Optional default (or null)
+        * @param mixed|null $default Optional default (or null)
         * @return mixed The value of the data requested or the deafult
         */
        public function get( $name, $default = null ) {
-               if ( isset( $this->data[$name] ) ) {
-                       return $this->data[$name];
-               } else {
-                       return $default;
-               }
+               return $this->data[$name] ?? $default;
        }
 
        /**
index 5dfa7e3..ff2a9ea 100644 (file)
@@ -21,6 +21,8 @@
  */
 
 use MediaWiki\MediaWikiServices;
+use Wikimedia\WrappedString;
+use Wikimedia\WrappedStringList;
 
 /**
  * @defgroup Skins Skins
@@ -210,15 +212,9 @@ abstract class Skin extends ContextSource {
                        'syndicate' => [],
                ];
 
-               // Support for high-density display images if enabled
-               if ( $config->get( 'ResponsiveImages' ) ) {
-                       $modules['core'][] = 'mediawiki.hidpi';
-               }
-
                // Preload jquery.tablesorter for mediawiki.page.ready
                if ( strpos( $out->getHTML(), 'sortable' ) !== false ) {
                        $modules['content'][] = 'jquery.tablesorter';
-                       $modules['styles']['content'][] = 'jquery.tablesorter.styles';
                }
 
                // Preload jquery.makeCollapsible for mediawiki.page.ready
@@ -235,6 +231,7 @@ abstract class Skin extends ContextSource {
 
                if ( $out->isTOCEnabled() ) {
                        $modules['content'][] = 'mediawiki.toc';
+                       $modules['styles']['content'][] = 'mediawiki.toc.styles';
                }
 
                // Add various resources if required
@@ -395,24 +392,23 @@ abstract class Skin extends ContextSource {
 
        /**
         * Outputs the HTML generated by other functions.
-        * @param OutputPage $out
+        * @param OutputPage|null $out
         */
        abstract function outputPage( OutputPage $out = null );
 
        /**
         * @param array $data
-        * @param string $nonce OutputPage::getCSPNonce()
-        * @return string
+        * @param string|null $nonce OutputPage::getCSPNonce()
+        * @return string|WrappedString HTML
         */
-       static function makeVariablesScript( $data, $nonce = null ) {
+       public static function makeVariablesScript( $data, $nonce = null ) {
                if ( $data ) {
                        return ResourceLoader::makeInlineScript(
                                ResourceLoader::makeConfigSetScript( $data ),
                                $nonce
                        );
-               } else {
-                       return '';
                }
+               return '';
        }
 
        /**
@@ -675,16 +671,22 @@ abstract class Skin extends ContextSource {
        /**
         * This gets called shortly before the "</body>" tag.
         *
-        * @return string HTML-wrapped JS code to be put before "</body>"
+        * @return string|WrappedStringList HTML containing scripts to put before `</body>`
         */
        function bottomScripts() {
                // TODO and the suckage continues. This function is really just a wrapper around
                // OutputPage::getBottomScripts() which takes a Skin param. This should be cleaned
                // up at some point
-               $bottomScriptText = $this->getOutput()->getBottomScripts();
-               Hooks::run( 'SkinAfterBottomScripts', [ $this, &$bottomScriptText ] );
-
-               return $bottomScriptText;
+               $chunks = [ $this->getOutput()->getBottomScripts() ];
+
+               // Keep the hook appendage separate to preserve WrappedString objects.
+               // This enables BaseTemplate::getTrail() to merge them where possible.
+               $extraHtml = '';
+               Hooks::run( 'SkinAfterBottomScripts', [ $this, &$extraHtml ] );
+               if ( $extraHtml !== '' ) {
+                       $chunks[] = $extraHtml;
+               }
+               return WrappedString::join( "\n", $chunks );
        }
 
        /**
@@ -737,7 +739,7 @@ abstract class Skin extends ContextSource {
        }
 
        /**
-        * @param OutputPage $out Defaults to $this->getOutput() if left as null
+        * @param OutputPage|null $out Defaults to $this->getOutput() if left as null
         * @return string
         */
        function subPageSubtitle( $out = null ) {
@@ -968,7 +970,7 @@ abstract class Skin extends ContextSource {
                if ( is_string( $icon ) ) {
                        $html = $icon;
                } else { // Assuming array
-                       $url = isset( $icon["url"] ) ? $icon["url"] : null;
+                       $url = $icon["url"] ?? null;
                        unset( $icon["url"] );
                        if ( isset( $icon["src"] ) && $withImage === 'withImage' ) {
                                // do this the lazy way, just pass icon data as an attribute array
@@ -1095,25 +1097,25 @@ abstract class Skin extends ContextSource {
        }
 
        /**
-        * Return a fully resolved style path url to images or styles stored in the current skins's folder.
-        * This method returns a url resolved using the configured skin style path
-        * and includes the style version inside of the url.
+        * Return a fully resolved style path URL to images or styles stored in the
+        * current skin's folder. This method returns a URL resolved using the
+        * configured skin style path.
         *
         * Requires $stylename to be set, otherwise throws MWException.
         *
         * @param string $name The name or path of a skin resource file
-        * @return string The fully resolved style path url including styleversion
+        * @return string The fully resolved style path URL
         * @throws MWException
         */
        function getSkinStylePath( $name ) {
-               global $wgStylePath, $wgStyleVersion;
+               global $wgStylePath;
 
                if ( $this->stylename === null ) {
                        $class = static::class;
                        throw new MWException( "$class::\$stylename must be set to use getSkinStylePath()" );
                }
 
-               return "$wgStylePath/{$this->stylename}/$name?$wgStyleVersion";
+               return "$wgStylePath/{$this->stylename}/$name";
        }
 
        /* these are used extensively in SkinTemplate, but also some other places */
@@ -1446,7 +1448,7 @@ abstract class Skin extends ContextSource {
 
                if ( count( $newtalks ) == 1 && $newtalks[0]['wiki'] === wfWikiID() ) {
                        $uTalkTitle = $user->getTalkPage();
-                       $lastSeenRev = isset( $newtalks[0]['rev'] ) ? $newtalks[0]['rev'] : null;
+                       $lastSeenRev = $newtalks[0]['rev'] ?? null;
                        $nofAuthors = 0;
                        if ( $lastSeenRev !== null ) {
                                $plural = true; // Default if we have a last seen revision: if unknown, use plural
@@ -1597,14 +1599,13 @@ abstract class Skin extends ContextSource {
        }
 
        /**
-        * Create a section edit link.  This supersedes editSectionLink() and
-        * editSectionLinkForOther().
+        * Create a section edit link.
         *
         * @param Title $nt The title being linked to (may not be the same as
         *   the current page, if the section is included from a template)
         * @param string $section The designation of the section being pointed to,
         *   to be included in the link, like "&section=$section"
-        * @param string $tooltip The tooltip to use for the link: will be escaped
+        * @param string|null $tooltip The tooltip to use for the link: will be escaped
         *   and wrapped in the 'editsectionhint' message
         * @param string $lang Language code
         * @return string HTML to use for edit link
index 507688d..7b2d79e 100644 (file)
@@ -206,7 +206,7 @@ class SkinTemplate extends Skin {
        /**
         * initialize various variables and generate the template
         *
-        * @param OutputPage $out
+        * @param OutputPage|null $out
         */
        function outputPage( OutputPage $out = null ) {
                Profiler::instance()->setTemplated( true );
@@ -508,7 +508,7 @@ class SkinTemplate extends Skin {
         *
         * @since 1.31
         *
-        * @param array $personalTools
+        * @param array|null $personalTools
         * @param array $options
         * @return string
         */
@@ -1116,11 +1116,11 @@ class SkinTemplate extends Skin {
 
                        if ( $userCanRead && !$wgDisableLangConversion ) {
                                $pageLang = $title->getPageLanguage();
-                               // Gets list of language variants
-                               $variants = $pageLang->getVariants();
                                // Checks that language conversion is enabled and variants exist
                                // And if it is not in the special namespace
-                               if ( count( $variants ) > 1 ) {
+                               if ( $pageLang->hasVariants() ) {
+                                       // Gets list of language variants
+                                       $variants = $pageLang->getVariants();
                                        // Gets preferred variant (note that user preference is
                                        // only possible for wiki content language variant)
                                        $preferred = $pageLang->getPreferredVariant();
index b9745de..1476e85 100644 (file)
@@ -70,7 +70,7 @@ abstract class AuthManagerSpecialPage extends SpecialPage {
         * Used to preserve POST data over a HTTP redirect.
         *
         * @param array $data
-        * @param bool $wasPosted
+        * @param bool|null $wasPosted
         */
        protected function setRequest( array $data, $wasPosted = null ) {
                $request = $this->getContext()->getRequest();
@@ -223,7 +223,7 @@ abstract class AuthManagerSpecialPage extends SpecialPage {
         * Load or initialize $authAction, $authRequests and $subPage.
         * Subclasses should call this from execute() or otherwise ensure the variables are initialized.
         * @param string $subPage Subpage of the special page.
-        * @param string $authAction Override auth action specified in request (this is useful
+        * @param string|null $authAction Override auth action specified in request (this is useful
         *    when the form needs to be changed from <action> to <action>_CONTINUE after a successful
         *    authentication step)
         * @param bool $reset Regenerate the requests even if a cached version is available
@@ -432,11 +432,11 @@ abstract class AuthManagerSpecialPage extends SpecialPage {
                                $status = Status::newFatal( new RawMessage( '$1', $status ) );
                        } elseif ( is_array( $status ) ) {
                                if ( is_string( reset( $status ) ) ) {
-                                       $status = call_user_func_array( 'Status::newFatal', $status );
+                                       $status = Status::newFatal( ...$status );
                                } elseif ( is_array( reset( $status ) ) ) {
                                        $status = Status::newGood();
                                        foreach ( $status as $message ) {
-                                               call_user_func_array( [ $status, 'fatal' ], $message );
+                                               $status->fatal( ...$message );
                                        }
                                } else {
                                        throw new UnexpectedValueException( 'invalid HTMLForm::trySubmit() return value: '
@@ -718,8 +718,8 @@ abstract class AuthManagerSpecialPage extends SpecialPage {
                        $field['__index'] = $i++;
                }
                uasort( $formDescriptor, function ( $first, $second ) {
-                       return self::getField( $first, 'weight', 0 ) - self::getField( $second, 'weight', 0 )
-                               ?: $first['__index'] - $second['__index'];
+                       return self::getField( $first, 'weight', 0 ) <=> self::getField( $second, 'weight', 0 )
+                               ?: $first['__index'] <=> $second['__index'];
                } );
                foreach ( $formDescriptor as &$field ) {
                        unset( $field['__index'] );
@@ -730,7 +730,7 @@ abstract class AuthManagerSpecialPage extends SpecialPage {
         * Get an array value, or a default if it does not exist.
         * @param array $array
         * @param string $fieldName
-        * @param mixed $default
+        * @param mixed|null $default
         * @return mixed
         */
        protected static function getField( array $array, $fieldName, $default = null ) {
index 9e61ef7..58944b4 100644 (file)
@@ -57,6 +57,12 @@ abstract class ChangesListSpecialPage extends SpecialPage {
         */
        protected static $limitPreferenceName;
 
+       /**
+        * Preference name for collapsing the active filter display. Subclasses should override this.
+        * @var string
+        */
+       protected static $collapsedPreferenceName;
+
        /** @var string */
        protected $rcSubpage;
 
@@ -704,9 +710,8 @@ abstract class ChangesListSpecialPage extends SpecialPage {
                        return;
                }
 
-               $knownParams = call_user_func_array(
-                       [ $this->getRequest(), 'getValues' ],
-                       array_keys( $this->getOptions()->getAllValues() )
+               $knownParams = $this->getRequest()->getValues(
+                       ...array_keys( $this->getOptions()->getAllValues() )
                );
 
                // HACK: Temporarily until we can properly define "sticky" filters and parameters,
@@ -780,9 +785,13 @@ abstract class ChangesListSpecialPage extends SpecialPage {
                        foreach ( $jsData['messageKeys'] as $key ) {
                                $messages[$key] = $this->msg( $key )->plain();
                        }
-
                        $out->addBodyClasses( 'mw-rcfilters-enabled' );
 
+                       $collapsed = $this->getUser()->getBoolOption( static::$collapsedPreferenceName );
+                       if ( $collapsed ) {
+                               $out->addBodyClasses( 'mw-rcfilters-collapsed' );
+                       }
+
                        $out->addHTML(
                                ResourceLoader::makeInlineScript(
                                        ResourceLoader::makeMessageSetScript( $messages ),
@@ -791,6 +800,7 @@ abstract class ChangesListSpecialPage extends SpecialPage {
                        );
 
                        $out->addJsConfigVars( 'wgStructuredChangeFilters', $jsData['groups'] );
+                       $out->addJsConfigVars( 'wgStructuredChangeFiltersCollapsedState', $collapsed );
 
                        $out->addJsConfigVars(
                                'wgRCFiltersChangeTags',
@@ -819,6 +829,10 @@ abstract class ChangesListSpecialPage extends SpecialPage {
                                'wgStructuredChangeFiltersDaysPreferenceName',
                                static::$daysPreferenceName
                        );
+                       $out->addJsConfigVars(
+                               'wgStructuredChangeFiltersCollapsedPreferenceName',
+                               static::$collapsedPreferenceName
+                       );
 
                        $out->addJsConfigVars(
                                'StructuredChangeFiltersLiveUpdatePollingRate',
@@ -1196,9 +1210,7 @@ abstract class ChangesListSpecialPage extends SpecialPage {
         * @return ChangesListFilterGroup|null Group, or null if not registered
         */
        public function getFilterGroup( $groupName ) {
-               return isset( $this->filterGroups[$groupName] ) ?
-                       $this->filterGroups[$groupName] :
-                       null;
+               return $this->filterGroups[$groupName] ?? null;
        }
 
        // Currently, this intentionally only includes filters that display
@@ -1220,7 +1232,7 @@ abstract class ChangesListSpecialPage extends SpecialPage {
                ];
 
                usort( $this->filterGroups, function ( $a, $b ) {
-                       return $b->getPriority() - $a->getPriority();
+                       return $b->getPriority() <=> $a->getPriority();
                } );
 
                foreach ( $this->filterGroups as $groupName => $group ) {
@@ -1682,9 +1694,9 @@ abstract class ChangesListSpecialPage extends SpecialPage {
                        unset( $legendItems['unpatrolled'] );
                }
                foreach ( $legendItems as $key => $item ) { # generate items of the legend
-                       $label = isset( $item['legend'] ) ? $item['legend'] : $item['title'];
+                       $label = $item['legend'] ?? $item['title'];
                        $letter = $item['letter'];
-                       $cssClass = isset( $item['class'] ) ? $item['class'] : $key;
+                       $cssClass = $item['class'] ?? $key;
 
                        $legend .= Html::element( 'dt',
                                [ 'class' => $cssClass ], $context->msg( $letter )->text()
index 66c7d47..81a0036 100644 (file)
@@ -35,6 +35,12 @@ abstract class FormSpecialPage extends SpecialPage {
         */
        protected $par = null;
 
+       /**
+        * @var array|null POST data preserved across re-authentication
+        * @since 1.32
+        */
+       protected $reauthPostData = null;
+
        /**
         * Get an HTMLForm descriptor array
         * @return array
@@ -89,13 +95,31 @@ abstract class FormSpecialPage extends SpecialPage {
         * @return HTMLForm|null
         */
        protected function getForm() {
+               $context = $this->getContext();
+               $onSubmit = [ $this, 'onSubmit' ];
+
+               if ( $this->reauthPostData ) {
+                       // Restore POST data
+                       $context = new DerivativeContext( $context );
+                       $oldRequest = $this->getRequest();
+                       $context->setRequest( new DerivativeRequest(
+                               $oldRequest, $this->reauthPostData + $oldRequest->getQueryValues(), true
+                       ) );
+
+                       // But don't treat it as a "real" submission just in case of some
+                       // crazy kind of CSRF.
+                       $onSubmit = function () {
+                               return false;
+                       };
+               }
+
                $form = HTMLForm::factory(
                        $this->getDisplayFormat(),
                        $this->getFormFields(),
-                       $this->getContext(),
+                       $context,
                        $this->getMessagePrefix()
                );
-               $form->setSubmitCallback( [ $this, 'onSubmit' ] );
+               $form->setSubmitCallback( $onSubmit );
                if ( $this->getDisplayFormat() !== 'ooui' ) {
                        // No legend and wrapper by default in OOUI forms, but can be set manually
                        // from alterForm()
@@ -151,6 +175,11 @@ abstract class FormSpecialPage extends SpecialPage {
                // This will throw exceptions if there's a problem
                $this->checkExecutePermissions( $this->getUser() );
 
+               $securityLevel = $this->getLoginSecurityLevel();
+               if ( $securityLevel !== false && !$this->checkLoginSecurityLevel( $securityLevel ) ) {
+                       return;
+               }
+
                $form = $this->getForm();
                if ( $form->show() ) {
                        $this->onSuccess();
@@ -199,4 +228,14 @@ abstract class FormSpecialPage extends SpecialPage {
        public function requiresUnblock() {
                return true;
        }
+
+       /**
+        * Preserve POST data across reauthentication
+        *
+        * @since 1.32
+        * @param array $data
+        */
+       protected function setReauthPostData( array $data ) {
+               $this->reauthPostData = $data;
+       }
 }
index 49aaffd..8df6493 100644 (file)
@@ -52,7 +52,7 @@ abstract class ImageQueryPage extends QueryPage {
                        $i = 0;
                        foreach ( $res as $row ) {
                                $i++;
-                               $namespace = isset( $row->namespace ) ? $row->namespace : NS_FILE;
+                               $namespace = $row->namespace ?? NS_FILE;
                                $title = Title::makeTitleSafe( $namespace, $row->title );
                                if ( $title instanceof Title && $title->getNamespace() == NS_FILE ) {
                                        $gallery->add( $title, $this->getCellHtml( $row ) );
index 1c54d13..e94f3db 100644 (file)
@@ -265,6 +265,7 @@ abstract class LoginSignupSpecialPage extends AuthManagerSpecialPage {
                         $this->getUser()->isLoggedIn()
                ) {
                        $this->successfulAction();
+                       return;
                }
 
                // If logging in and not on HTTPS, either redirect to it or offer a link.
@@ -846,8 +847,7 @@ abstract class LoginSignupSpecialPage extends AuthManagerSpecialPage {
 
                // keep the ordering from getCoreFieldDescriptors() where there is no explicit weight
                foreach ( $coreFieldDescriptors as $fieldName => $coreField ) {
-                       $requestField = isset( $formDescriptor[$fieldName] ) ?
-                               $formDescriptor[$fieldName] : [];
+                       $requestField = $formDescriptor[$fieldName] ?? [];
 
                        // remove everything that is not in the fieldinfo, is not marked as a supplemental field
                        // to something in the fieldinfo, is not B/C for the pre-AuthManager templates,
@@ -1063,7 +1063,7 @@ abstract class LoginSignupSpecialPage extends AuthManagerSpecialPage {
                                        // 'id' => 'mw-userlogin-help', // FIXME HTMLInfoField ignores this
                                        'raw' => true,
                                        'default' => Html::element( 'a', [
-                                               'href' => Skin::makeInternalOrExternalUrl( wfMessage( 'helplogin-url' )
+                                               'href' => Skin::makeInternalOrExternalUrl( $this->msg( 'helplogin-url' )
                                                        ->inContentLanguage()
                                                        ->text() ),
                                        ], $this->msg( 'userlogin-helplink2' )->text() ),
@@ -1492,7 +1492,7 @@ class LoginForm extends SpecialPage {
        ];
 
        /**
-        * @param WebRequest $request
+        * @param WebRequest|null $request
         */
        public function __construct( $request = null ) {
                wfDeprecated( 'LoginForm', '1.27' );
index f642106..96f50bf 100644 (file)
@@ -806,7 +806,7 @@ abstract class QueryPage extends SpecialPage {
                }
                $title = Title::makeTitle( intval( $row->namespace ), $row->title );
                if ( $title ) {
-                       $date = isset( $row->timestamp ) ? $row->timestamp : '';
+                       $date = $row->timestamp ?? '';
                        $comments = '';
                        if ( $title ) {
                                $talkpage = $title->getTalkPage();
@@ -830,7 +830,7 @@ abstract class QueryPage extends SpecialPage {
        }
 
        function feedItemAuthor( $row ) {
-               return isset( $row->user_text ) ? $row->user_text : '';
+               return $row->user_text ?? '';
        }
 
        function feedTitle() {
@@ -865,7 +865,7 @@ abstract class QueryPage extends SpecialPage {
 
                $batch = new LinkBatch;
                foreach ( $res as $row ) {
-                       $batch->add( $ns !== null ? $ns : $row->namespace, $row->title );
+                       $batch->add( $ns ?? $row->namespace, $row->title );
                }
                $batch->execute();
 
index 6828b4a..7a39b3c 100644 (file)
@@ -182,7 +182,7 @@ class SpecialPage implements MessageLocalizer {
        /**
         * Get or set whether this special page is listed in Special:SpecialPages
         * @since 1.6
-        * @param bool $x
+        * @param bool|null $x
         * @return bool
         */
        function listed( $x = null ) {
@@ -220,7 +220,7 @@ class SpecialPage implements MessageLocalizer {
 
        /**
         * Whether the special page is being evaluated via transclusion
-        * @param bool $x
+        * @param bool|null $x
         * @return bool
         */
        function including( $x = null ) {
@@ -352,6 +352,23 @@ class SpecialPage implements MessageLocalizer {
                return false;
        }
 
+       /**
+        * Record preserved POST data after a reauthentication.
+        *
+        * This is called from checkLoginSecurityLevel() when returning from the
+        * redirect for reauthentication, if the redirect had been served in
+        * response to a POST request.
+        *
+        * The base SpecialPage implementation does nothing. If your subclass uses
+        * getLoginSecurityLevel() or checkLoginSecurityLevel(), it should probably
+        * implement this to do something with the data.
+        *
+        * @since 1.32
+        * @param array $data
+        */
+       protected function setReauthPostData( array $data ) {
+       }
+
        /**
         * Verifies that the user meets the security level, possibly reauthenticating them in the process.
         *
@@ -371,23 +388,50 @@ class SpecialPage implements MessageLocalizer {
         * Note that this does not in any way check that the user is authorized to use this special page
         * (use checkPermissions() for that).
         *
-        * @param string $level A security level. Can be an arbitrary string, defaults to the page name.
+        * @param string|null $level A security level. Can be an arbitrary string, defaults to the page
+        *   name.
         * @return bool False means a redirect to the reauthentication page has been set and processing
         *   of the special page should be aborted.
         * @throws ErrorPageError If the security level cannot be met, even with reauthentication.
         */
        protected function checkLoginSecurityLevel( $level = null ) {
                $level = $level ?: $this->getName();
+               $key = 'SpecialPage:reauth:' . $this->getName();
+               $request = $this->getRequest();
+
                $securityStatus = AuthManager::singleton()->securitySensitiveOperationStatus( $level );
                if ( $securityStatus === AuthManager::SEC_OK ) {
+                       $uniqueId = $request->getVal( 'postUniqueId' );
+                       if ( $uniqueId ) {
+                               $key = $key . ':' . $uniqueId;
+                               $session = $request->getSession();
+                               $data = $session->getSecret( $key );
+                               if ( $data ) {
+                                       $session->remove( $key );
+                                       $this->setReauthPostData( $data );
+                               }
+                       }
                        return true;
                } elseif ( $securityStatus === AuthManager::SEC_REAUTH ) {
-                       $request = $this->getRequest();
                        $title = self::getTitleFor( 'Userlogin' );
+                       $queryParams = $request->getQueryValues();
+
+                       if ( $request->wasPosted() ) {
+                               $data = array_diff_assoc( $request->getValues(), $request->getQueryValues() );
+                               if ( $data ) {
+                                       // unique ID in case the same special page is open in multiple browser tabs
+                                       $uniqueId = MWCryptRand::generateHex( 6 );
+                                       $key = $key . ':' . $uniqueId;
+                                       $queryParams['postUniqueId'] = $uniqueId;
+                                       $session = $request->getSession();
+                                       $session->persist(); // Just in case
+                                       $session->setSecret( $key, $data );
+                               }
+                       }
+
                        $query = [
                                'returnto' => $this->getFullTitle()->getPrefixedDBkey(),
-                               'returntoquery' => wfArrayToCgi( array_diff_key( $request->getQueryValues(),
-                                       [ 'title' => true ] ) ),
+                               'returntoquery' => wfArrayToCgi( array_diff_key( $queryParams, [ 'title' => true ] ) ),
                                'force' => $level,
                        ];
                        $url = $title->getFullURL( $query, false, PROTO_HTTPS );
@@ -568,7 +612,10 @@ class SpecialPage implements MessageLocalizer {
        public function execute( $subPage ) {
                $this->setHeaders();
                $this->checkPermissions();
-               $this->checkLoginSecurityLevel( $this->getLoginSecurityLevel() );
+               $securityLevel = $this->getLoginSecurityLevel();
+               if ( $securityLevel !== false && !$this->checkLoginSecurityLevel( $securityLevel ) ) {
+                       return;
+               }
                $this->outputHeader();
        }
 
@@ -745,10 +792,7 @@ class SpecialPage implements MessageLocalizer {
         * @see wfMessage
         */
        public function msg( $key /* $args */ ) {
-               $message = call_user_func_array(
-                       [ $this->getContext(), 'msg' ],
-                       func_get_args()
-               );
+               $message = $this->getContext()->msg( ...func_get_args() );
                // RequestContext passes context to wfMessage, and the language is set from
                // the context, but setting the language for Message class removes the
                // interface message status, which breaks for example usernameless gender
index b3cb806..b3b63b0 100644 (file)
@@ -415,7 +415,7 @@ class SpecialPageFactory {
         * Return categorised listable special pages which are available
         * for the current user, and everyone.
         *
-        * @param User $user User object to check permissions, $wgUser will be used
+        * @param User|null $user User object to check permissions, $wgUser will be used
         *        if not provided
         * @return array ( string => Specialpage )
         */
index e1909f5..cab5a2e 100644 (file)
@@ -98,7 +98,7 @@ class SpecialAutoblockList extends SpecialPage {
        protected function showTotal( BlockListPager $pager ) {
                $out = $this->getOutput();
                $out->addHTML(
-                       Html::element( 'div', [ 'style' => 'font-weight: bold;' ],
+                       Html::rawElement( 'div', [ 'style' => 'font-weight: bold;' ],
                                $this->msg( 'autoblocklist-total-autoblocks', $pager->getTotalAutoblocks() )->parse() )
                        . "\n"
                );
@@ -119,7 +119,7 @@ class SpecialAutoblockList extends SpecialPage {
                # Not necessary in a standard installation without such extensions enabled
                if ( count( $otherAutoblockLink ) ) {
                        $out->addHTML(
-                               Html::element( 'h2', [], $this->msg( 'autoblocklist-localblocks',
+                               Html::rawElement( 'h2', [], $this->msg( 'autoblocklist-localblocks',
                                        $pager->getNumRows() )->parse() )
                                . "\n"
                        );
index efe354a..3b25c6c 100644 (file)
@@ -494,7 +494,7 @@ class SpecialBlock extends FormSpecialPage {
         * @todo Should be in Block.php?
         * @param string $par Subpage parameter passed to setup, or data value from
         *     the HTMLForm
-        * @param WebRequest $request Optionally try and get data from a request too
+        * @param WebRequest|null $request Optionally try and get data from a request too
         * @return array [ User|string|null, Block::TYPE_ constant|null ]
         */
        public static function getTargetAndType( $par, WebRequest $request = null ) {
@@ -553,7 +553,7 @@ class SpecialBlock extends FormSpecialPage {
                if ( !$status->isOK() ) {
                        $errors = $status->getErrorsArray();
 
-                       return call_user_func_array( [ $form, 'msg' ], $errors[0] );
+                       return $form->msg( ...$errors[0] );
                } else {
                        return true;
                }
@@ -854,9 +854,11 @@ class SpecialBlock extends FormSpecialPage {
         *     to the standard "**<duration>|<displayname>" format?
         * @param Language|null $lang The language to get the durations in, or null to use
         *     the wiki's content language
+        * @param bool $includeOther Whether to include the 'other' option in the list of
+        *     suggestions
         * @return array
         */
-       public static function getSuggestedDurations( $lang = null ) {
+       public static function getSuggestedDurations( $lang = null, $includeOther = true ) {
                $a = [];
                $msg = $lang === null
                        ? wfMessage( 'ipboptions' )->inContentLanguage()->text()
@@ -875,7 +877,7 @@ class SpecialBlock extends FormSpecialPage {
                        $a[$show] = $value;
                }
 
-               if ( $a ) {
+               if ( $a && $includeOther ) {
                        // if options exist, add other to the end instead of the begining (which
                        // is what happens by default).
                        $a[ wfMessage( 'ipbother' )->text() ] = 'other';
@@ -1005,7 +1007,7 @@ class SpecialBlock extends FormSpecialPage {
        /**
         * Process the form on POST submission.
         * @param array $data
-        * @param HTMLForm $form
+        * @param HTMLForm|null $form
         * @return bool|array True for success, false for didn't-try, array of errors on failure
         */
        public function onSubmit( array $data, HTMLForm $form = null ) {
index f03565a..2d3a0cc 100644 (file)
@@ -57,6 +57,10 @@ class SpecialBotPasswords extends FormSpecialPage {
                return $this->getConfig()->get( 'EnableBotPasswords' );
        }
 
+       protected function getLoginSecurityLevel() {
+               return $this->getName();
+       }
+
        /**
         * Main execution point
         * @param string|null $par
index c514300..8cf64b1 100644 (file)
@@ -22,6 +22,7 @@
  */
 
 use MediaWiki\Auth\AuthManager;
+use MediaWiki\Logger\LoggerFactory;
 
 /**
  * Let users change their email address.
@@ -151,8 +152,6 @@ class SpecialChangeEmail extends FormSpecialPage {
         * @return Status
         */
        private function attemptChange( User $user, $newaddr ) {
-               $authManager = AuthManager::singleton();
-
                if ( $newaddr != '' && !Sanitizer::validateEmail( $newaddr ) ) {
                        return Status::newFatal( 'invalidemailaddress' );
                }
@@ -167,6 +166,14 @@ class SpecialChangeEmail extends FormSpecialPage {
                        return $status;
                }
 
+               LoggerFactory::getInstance( 'authentication' )->info(
+                       'Changing email address for {user} from {oldemail} to {newemail}', [
+                               'user' => $user->getName(),
+                               'oldemail' => $oldaddr,
+                               'newemail' => $newaddr,
+                       ]
+               );
+
                Hooks::run( 'PrefsEmailAudit', [ $user, $oldaddr, $newaddr ] );
 
                $user->saveSettings();
index 28f04fa..d6fb10f 100644 (file)
@@ -59,6 +59,7 @@ class SpecialComparePages extends SpecialPage {
                                'size' => '40',
                                'section' => 'page1',
                                'validation-callback' => [ $this, 'checkExistingTitle' ],
+                               'required' => false,
                        ],
                        'Revision1' => [
                                'type' => 'int',
@@ -75,6 +76,7 @@ class SpecialComparePages extends SpecialPage {
                                'size' => '40',
                                'section' => 'page2',
                                'validation-callback' => [ $this, 'checkExistingTitle' ],
+                               'required' => false,
                        ],
                        'Revision2' => [
                                'type' => 'int',
index 6fc8306..f5e2b86 100644 (file)
@@ -50,11 +50,7 @@ class SpecialContributions extends IncludableSpecialPage {
                $this->opts = [];
                $request = $this->getRequest();
 
-               if ( $par !== null ) {
-                       $target = $par;
-               } else {
-                       $target = $request->getVal( 'target' );
-               }
+               $target = $par ?? $request->getVal( 'target' );
 
                if ( $request->getVal( 'contribs' ) == 'newbie' || $par === 'newbies' ) {
                        $target = 'newbies';
@@ -556,7 +552,7 @@ class SpecialContributions extends IncludableSpecialPage {
                        $filterSelection = Html::rawElement(
                                'div',
                                [],
-                               implode( '&#160;', $tagFilter )
+                               implode( "\u{00A0}", $tagFilter )
                        );
                } else {
                        $filterSelection = Html::rawElement( 'div', [], '' );
@@ -609,7 +605,7 @@ class SpecialContributions extends IncludableSpecialPage {
                                $this->msg( 'namespace' )->text(),
                                'namespace',
                                ''
-                       ) . '&#160;' .
+                       ) . "\u{00A0}" .
                        Html::namespaceSelector(
                                [ 'selected' => $this->opts['namespace'], 'all' => '' ],
                                [
@@ -617,7 +613,7 @@ class SpecialContributions extends IncludableSpecialPage {
                                        'id' => 'namespace',
                                        'class' => 'namespaceselector',
                                ]
-                       ) . '&#160;' .
+                       ) . "\u{00A0}" .
                                Html::rawElement(
                                        'span',
                                        [ 'class' => 'mw-input-with-label' ],
@@ -630,7 +626,7 @@ class SpecialContributions extends IncludableSpecialPage {
                                                        'title' => $this->msg( 'tooltip-invert' )->text(),
                                                        'class' => 'mw-input'
                                                ]
-                                       ) . '&#160;'
+                                       ) . "\u{00A0}"
                                ) .
                                Html::rawElement( 'span', [ 'class' => 'mw-input-with-label' ],
                                        Xml::checkLabel(
@@ -642,7 +638,7 @@ class SpecialContributions extends IncludableSpecialPage {
                                                        'title' => $this->msg( 'tooltip-namespace_association' )->text(),
                                                        'class' => 'mw-input'
                                                ]
-                                       ) . '&#160;'
+                                       ) . "\u{00A0}"
                                )
                );
 
index 73beafc..2f87c47 100644 (file)
@@ -63,6 +63,10 @@ class SpecialCreateAccount extends LoginSignupSpecialPage {
                $user = $this->getUser();
                $status = AuthManager::singleton()->checkAccountCreatePermissions( $user );
                if ( !$status->isGood() ) {
+                       // track block with a cookie if it doesn't exists already
+                       if ( $user->isBlockedFromCreateAccount() ) {
+                               $user->trackBlockWithCookie();
+                       }
                        throw new ErrorPageError( 'createacct-error', $status->getMessage() );
                }
        }
index 3db7eda..b657335 100644 (file)
@@ -166,7 +166,7 @@ class SpecialEditTags extends UnlistedSpecialPage {
                                [],
                                [
                                        'page' => $this->targetObj->getPrefixedText(),
-                                       'hide_tag_log' => '0',
+                                       'wpfilters' => [ 'tag' ],
                                ]
                        );
                        if ( !$this->targetObj->isSpecialPage() ) {
index 5e04d8d..17b3201 100644 (file)
@@ -160,6 +160,7 @@ class SpecialEditWatchlist extends UnlistedSpecialPage {
                } elseif ( $this->toc !== false ) {
                        $out->prependHTML( $this->toc );
                        $out->addModules( 'mediawiki.toc' );
+                       $out->addModuleStyles( 'mediawiki.toc.styles' );
                }
        }
 
index f322ac4..9248a40 100644 (file)
@@ -21,6 +21,7 @@
  * @ingroup SpecialPage
  */
 use MediaWiki\MediaWikiServices;
+use MediaWiki\Preferences\MultiUsernameFilter;
 
 /**
  * A special page that allows users to send e-mails to other users
@@ -204,7 +205,7 @@ class SpecialEmailUser extends UnlistedSpecialPage {
                $nu = User::newFromName( $target );
                $error = self::validateTarget( $nu, $sender );
 
-               return $error ? $error : $nu;
+               return $error ?: $nu;
        }
 
        /**
@@ -247,8 +248,9 @@ class SpecialEmailUser extends UnlistedSpecialPage {
                }
 
                if ( $sender !== null ) {
-                       $blacklist = $target->getOption( 'email-blacklist', [] );
+                       $blacklist = $target->getOption( 'email-blacklist', '' );
                        if ( $blacklist ) {
+                               $blacklist = MultiUsernameFilter::splitIds( $blacklist );
                                $lookup = CentralIdLookup::factory();
                                $senderId = $lookup->centralIdFromLocalUser( $sender );
                                if ( $senderId !== 0 && in_array( $senderId, $blacklist ) ) {
@@ -267,7 +269,7 @@ class SpecialEmailUser extends UnlistedSpecialPage {
         *
         * @param User $user
         * @param string $editToken Edit token
-        * @param Config $config optional for backwards compatibility
+        * @param Config|null $config optional for backwards compatibility
         * @return string|null Null on success or string on error
         */
        public static function getPermissionsError( $user, $editToken, Config $config = null ) {
@@ -332,7 +334,7 @@ class SpecialEmailUser extends UnlistedSpecialPage {
                        Html::label(
                                $this->msg( 'emailusername' )->text(),
                                'emailusertarget'
-                       ) . '&#160;' .
+                       ) . "\u{00A0}" .
                        Html::input(
                                'target',
                                $name,
index e6d81c9..83e18c2 100644 (file)
@@ -103,7 +103,7 @@ class FileDuplicateSearchPage extends QueryPage {
                $this->setHeaders();
                $this->outputHeader();
 
-               $this->filename = $par !== null ? $par : $this->getRequest()->getText( 'filename' );
+               $this->filename = $par ?? $this->getRequest()->getText( 'filename' );
                $this->file = null;
                $this->hash = '';
                $title = Title::newFromText( $this->filename, NS_FILE );
@@ -121,7 +121,7 @@ class FileDuplicateSearchPage extends QueryPage {
                                'label-message' => 'fileduplicatesearch-filename',
                                'id' => 'filename',
                                'size' => 50,
-                               'value' => $this->filename,
+                               'default' => $this->filename,
                        ],
                ];
                $hiddenFields = [
index ab5d4d7..5a6bbc4 100644 (file)
@@ -526,7 +526,7 @@ class SpecialImport extends SpecialPage {
                                        Xml::checkLabel(
                                                $this->msg( 'import-assign-known-users' )->text(),
                                                'assignKnownUsers',
-                                               'assignKnownUsers',
+                                               'interwikiAssignKnownUsers',
                                                $this->assignKnownUsers
                                        ) .
                                        "</td>
index cc62d61..6091a64 100644 (file)
@@ -74,9 +74,7 @@ class SpecialListGroupRights extends SpecialPage {
                $linkRenderer = $this->getLinkRenderer();
 
                foreach ( $allGroups as $group ) {
-                       $permissions = isset( $groupPermissions[$group] )
-                               ? $groupPermissions[$group]
-                               : [];
+                       $permissions = $groupPermissions[$group] ?? [];
                        $groupname = ( $group == '*' ) // Replace * with a more descriptive groupname
                                ? 'all'
                                : $group;
@@ -114,13 +112,11 @@ class SpecialListGroupRights extends SpecialPage {
                                $grouplink = '';
                        }
 
-                       $revoke = isset( $revokePermissions[$group] ) ? $revokePermissions[$group] : [];
-                       $addgroups = isset( $addGroups[$group] ) ? $addGroups[$group] : [];
-                       $removegroups = isset( $removeGroups[$group] ) ? $removeGroups[$group] : [];
-                       $addgroupsSelf = isset( $groupsAddToSelf[$group] ) ? $groupsAddToSelf[$group] : [];
-                       $removegroupsSelf = isset( $groupsRemoveFromSelf[$group] )
-                               ? $groupsRemoveFromSelf[$group]
-                               : [];
+                       $revoke = $revokePermissions[$group] ?? [];
+                       $addgroups = $addGroups[$group] ?? [];
+                       $removegroups = $removeGroups[$group] ?? [];
+                       $addgroupsSelf = $groupsAddToSelf[$group] ?? [];
+                       $removegroupsSelf = $groupsRemoveFromSelf[$group] ?? [];
 
                        $id = $group == '*' ? false : Sanitizer::escapeIdForAttribute( $group );
                        $out->addHTML( Html::rawElement( 'tr', [ 'id' => $id ], "
index bad1746..2160312 100644 (file)
@@ -46,6 +46,7 @@ class SpecialLog extends SpecialPage {
                $opts->add( 'pattern', false );
                $opts->add( 'year', null, FormOptions::INTNULL );
                $opts->add( 'month', null, FormOptions::INTNULL );
+               $opts->add( 'day', null, FormOptions::INTNULL );
                $opts->add( 'tagfilter', '' );
                $opts->add( 'offset', '' );
                $opts->add( 'dir', '' );
@@ -59,6 +60,17 @@ class SpecialLog extends SpecialPage {
                        $this->parseParams( $opts, (string)$par );
                }
 
+               // Set date values
+               $dateString = $this->getRequest()->getVal( 'wpdate' );
+               if ( !empty( $dateString ) ) {
+                       $dateStamp = MWTimestamp::getInstance( $dateString . ' 00:00:00' );
+                       $dateStamp->setTimezone( $this->getConfig()->get( 'Localtimezone' ) );
+
+                       $opts->setValue( 'year', (int)$dateStamp->format( 'Y' ) );
+                       $opts->setValue( 'month', (int)$dateStamp->format( 'm' ) );
+                       $opts->setValue( 'day', (int)$dateStamp->format( 'd' ) );
+               }
+
                # Don't let the user get stuck with a certain date
                if ( $opts->getValue( 'offset' ) || $opts->getValue( 'dir' ) == 'prev' ) {
                        $opts->setValue( 'year', '' );
@@ -164,7 +176,7 @@ class SpecialLog extends SpecialPage {
         * @return string[] subpages
         */
        public function getSubpagesForPrefixSearch() {
-               $subpages = $this->getConfig()->get( 'LogTypes' );
+               $subpages = LogPage::validTypes();
                $subpages[] = 'all';
                sort( $subpages );
                return $subpages;
@@ -186,7 +198,7 @@ class SpecialLog extends SpecialPage {
                $parms = explode( '/', $par );
                $symsForAll = [ '*', 'all' ];
                if ( $parms[0] != '' &&
-                       ( in_array( $par, $this->getConfig()->get( 'LogTypes' ) ) || in_array( $par, $symsForAll ) )
+                       ( in_array( $par, LogPage::validTypes() ) || in_array( $par, $symsForAll ) )
                ) {
                        $opts->setValue( 'type', $par );
                } elseif ( count( $parms ) == 2 ) {
@@ -214,6 +226,7 @@ class SpecialLog extends SpecialPage {
                        $extraConds,
                        $opts->getValue( 'year' ),
                        $opts->getValue( 'month' ),
+                       $opts->getValue( 'day' ),
                        $opts->getValue( 'tagfilter' ),
                        $opts->getValue( 'subtype' ),
                        $opts->getValue( 'logid' )
@@ -235,6 +248,7 @@ class SpecialLog extends SpecialPage {
                        $pager->getPattern(),
                        $pager->getYear(),
                        $pager->getMonth(),
+                       $pager->getDay(),
                        $pager->getFilterParams(),
                        $pager->getTagFilter(),
                        $pager->getAction()
index a54d72d..f43ed9b 100644 (file)
@@ -160,7 +160,7 @@ class MIMEsearchPage extends QueryPage {
        }
 
        public function execute( $par ) {
-               $this->mime = $par ? $par : $this->getRequest()->getText( 'mime' );
+               $this->mime = $par ?: $this->getRequest()->getText( 'mime' );
                $this->mime = trim( $this->mime );
                list( $this->major, $this->minor ) = File::splitMime( $this->mime );
 
index 943fa57..6dbc09b 100644 (file)
@@ -182,7 +182,7 @@ class MediaStatisticsPage extends QueryPage {
                        [],
                        $linkRenderer->makeLink( $mimeSearch, $mime )
                );
-               $row .= Html::element(
+               $row .= Html::rawElement(
                        'td',
                        [],
                        $this->getExtensionList( $mime )
@@ -245,7 +245,7 @@ class MediaStatisticsPage extends QueryPage {
                $extArray = explode( ' ', $exts );
                $extArray = array_unique( $extArray );
                foreach ( $extArray as &$ext ) {
-                       $ext = '.' . $ext;
+                       $ext = htmlspecialchars( '.' . $ext );
                }
 
                return $this->getLanguage()->commaList( $extArray );
@@ -363,8 +363,8 @@ class MediaStatisticsPage extends QueryPage {
                $this->totalCount = $this->totalBytes = 0;
                foreach ( $res as $row ) {
                        $mediaStats = $this->splitFakeTitle( $row->title );
-                       $this->totalCount += isset( $mediaStats[2] ) ? $mediaStats[2] : 0;
-                       $this->totalBytes += isset( $mediaStats[3] ) ? $mediaStats[3] : 0;
+                       $this->totalCount += $mediaStats[2] ?? 0;
+                       $this->totalBytes += $mediaStats[3] ?? 0;
                }
                $res->seek( 0 );
        }
index f122db8..89eb410 100644 (file)
@@ -224,11 +224,11 @@ class SpecialMergeHistory extends SpecialPage {
                                        '</td>
                                        <td class="mw-input">' .
                                        Xml::input( 'wpComment', 50, $this->mComment, [ 'id' => 'wpComment' ] ) .
-                                       '</td>
+                                       "</td>
                                        </tr>
                                        <tr>
-                                               <td>&#160;</td>
-                                               <td class="mw-submit">' .
+                                               <td>\u{00A0}</td>
+                                               <td class=\"mw-submit\">" .
                                        Xml::submitButton(
                                                $this->msg( 'mergehistory-submit' )->text(),
                                                [ 'name' => 'merge', 'id' => 'mw-merge-submit' ]
index cd3da4f..ddf52f1 100644 (file)
@@ -229,7 +229,7 @@ class SpecialNewpages extends IncludableSpecialPage {
                }
                $hidden = implode( "\n", $hidden );
 
-               $form = [
+               $formDescriptor = [
                        'namespace' => [
                                'type' => 'namespaceselect',
                                'name' => 'namespace',
@@ -264,25 +264,26 @@ class SpecialNewpages extends IncludableSpecialPage {
                        ],
                ];
 
-               $htmlForm = new HTMLForm( $form, $this->getContext() );
-
-               $htmlForm->setSubmitText( $this->msg( 'newpages-submit' )->text() );
-               // The form should be visible on each request (inclusive requests with submitted forms), so
-               // return always false here.
-               $htmlForm->setSubmitCallback(
-                       function () {
-                               return false;
-                       }
-               );
-               $htmlForm->setMethod( 'get' );
-               $htmlForm->setWrapperLegend( true );
-               $htmlForm->setWrapperLegendMsg( 'newpages' );
-               $htmlForm->addFooterText( Html::rawElement(
-                       'div',
-                       null,
-                       $this->filterLinks()
-               ) );
-               $htmlForm->show();
+               $htmlForm = HTMLForm::factory( 'ooui', $formDescriptor, $this->getContext() );
+               $htmlForm
+                       ->setMethod( 'get' )
+                       ->setFormIdentifier( 'newpagesform' )
+                       // The form should be visible on each request (inclusive requests with submitted forms), so
+                       // return always false here.
+                       ->setSubmitCallback(
+                               function () {
+                                       return false;
+                               }
+                       )
+                       ->setSubmitText( $this->msg( 'newpages-submit' )->text() )
+                       ->setWrapperLegend( $this->msg( 'newpages' )->text() )
+                       ->addFooterText( Html::rawElement(
+                               'div',
+                               null,
+                               $this->filterLinks()
+                       ) )
+                       ->show();
+               $out->addModuleStyles( 'mediawiki.special' );
        }
 
        /**
@@ -398,7 +399,10 @@ class SpecialNewpages extends IncludableSpecialPage {
 
                // Let extensions add data
                Hooks::run( 'NewPagesLineEnding', [ $this, &$ret, $result, &$classes, &$attribs ] );
-               $attribs = wfArrayFilterByKey( $attribs, [ Sanitizer::class, 'isReservedDataAttribute' ] );
+               $attribs = array_filter( $attribs,
+                       [ Sanitizer::class, 'isReservedDataAttribute' ],
+                       ARRAY_FILTER_USE_KEY
+               );
 
                if ( count( $classes ) ) {
                        $attribs['class'] = implode( ' ', $classes );
@@ -483,7 +487,7 @@ class SpecialNewpages extends IncludableSpecialPage {
        }
 
        protected function feedItemAuthor( $row ) {
-               return isset( $row->rc_user_text ) ? $row->rc_user_text : '';
+               return $row->rc_user_text ?? '';
        }
 
        protected function feedItemDesc( $row ) {
index e3485ff..52db060 100644 (file)
@@ -163,7 +163,7 @@ class SpecialPageLanguage extends FormSpecialPage {
                        $this->getContext(),
                        $title,
                        $newLanguage,
-                       $data['reason'] === null ? '' : $data['reason']
+                       $data['reason'] ?? ''
                );
        }
 
@@ -224,8 +224,8 @@ class SpecialPageLanguage extends FormSpecialPage {
                }
 
                // Hardcoded [def] if the language is set to null
-               $logOld = $oldLanguage ? $oldLanguage : $defLang . '[def]';
-               $logNew = $newLanguage ? $newLanguage : $defLang . '[def]';
+               $logOld = $oldLanguage ?: $defLang . '[def]';
+               $logNew = $newLanguage ?: $defLang . '[def]';
 
                // Writing new page language to database
                $dbw->update(
index 415f973..0a3a679 100644 (file)
@@ -44,7 +44,8 @@ class SpecialPasswordPolicies extends SpecialPage {
                $out = $this->getOutput();
                $out->addModuleStyles( 'mediawiki.special' );
 
-               $this->addHelpLink( 'Help:Password policies' );
+               // TODO: Have specific user documentation page for this feature
+               $this->addHelpLink( 'Manual:$wgPasswordPolicy' );
 
                $out->addHTML(
                        Xml::openElement( 'table', [ 'class' => 'wikitable mw-passwordpolicies-table' ] ) .
index 7539235..7ea9ba0 100644 (file)
@@ -79,7 +79,7 @@ class SpecialPasswordReset extends FormSpecialPage {
                $a = [];
                if ( isset( $resetRoutes['username'] ) && $resetRoutes['username'] ) {
                        $a['Username'] = [
-                               'type' => 'text',
+                               'type' => 'user',
                                'label-message' => 'passwordreset-username',
                        ];
 
@@ -133,8 +133,8 @@ class SpecialPasswordReset extends FormSpecialPage {
         * @return Status
         */
        public function onSubmit( array $data ) {
-               $username = isset( $data['Username'] ) ? $data['Username'] : null;
-               $email = isset( $data['Email'] ) ? $data['Email'] : null;
+               $username = $data['Username'] ?? null;
+               $email = $data['Email'] ?? null;
 
                $this->method = $username ? 'username' : 'email';
                $this->result = Status::wrap(
index 7a4cde9..0490cbb 100644 (file)
@@ -40,6 +40,8 @@ class SpecialPreferences extends SpecialPage {
 
        /**
         * Check if OOUI mode is enabled, by config or query string
+        *
+        * @since 1.32
         * @param IContextSource $context The context.
         * @return bool
         */
@@ -161,7 +163,7 @@ class SpecialPreferences extends SpecialPage {
         * Get the preferences form to use.
         * @param User $user The user.
         * @param IContextSource $context The context.
-        * @return PreferencesForm|HTMLForm
+        * @return PreferencesFormLegacy|HTMLForm
         */
        protected function getFormObject( $user, IContextSource $context ) {
                $preferencesFactory = MediaWikiServices::getInstance()->getPreferencesFactory();
@@ -182,9 +184,7 @@ class SpecialPreferences extends SpecialPage {
 
                $context = new DerivativeContext( $this->getContext() );
                $context->setTitle( $this->getPageTitle( 'reset' ) ); // Reset subpage
-               $htmlForm = HTMLForm::factory(
-                       $this->oouiEnabled ? 'ooui' : 'vform', [], $context, 'prefs-restore'
-               );
+               $htmlForm = HTMLForm::factory( 'ooui', [], $context, 'prefs-restore' );
 
                $htmlForm->setSubmitTextMsg( 'restoreprefs' );
                $htmlForm->setSubmitDestructive();
index 3ca3a85..2a8a09d 100644 (file)
@@ -138,11 +138,11 @@ class SpecialPrefixindex extends SpecialAllPages {
        }
 
        /**
-        * @param int $namespace Default NS_MAIN
+        * @param int $namespace
         * @param string $prefix
-        * @param string $from List all pages from this name (default false)
+        * @param string|null $from List all pages from this name (default false)
         */
-       protected function showPrefixChunk( $namespace = NS_MAIN, $prefix, $from = null ) {
+       protected function showPrefixChunk( $namespace, $prefix, $from = null ) {
                global $wgContLang;
 
                if ( $from === null ) {
index 26f4da5..4b1b344 100644 (file)
@@ -92,7 +92,7 @@ class SpecialProtectedpages extends SpecialPage {
         *   cascadeOnly, noRedirect
         * @return string Input form
         */
-       protected function showOptions( $namespace, $type = 'edit', $level, $sizetype,
+       protected function showOptions( $namespace, $type, $level, $sizetype,
                $size, $filters
        ) {
                $formDescriptor = [
index 2770bc5..00bfba9 100644 (file)
@@ -112,7 +112,7 @@ class SpecialProtectedtitles extends SpecialPage {
         * @return string
         * @private
         */
-       function showOptions( $namespace, $type = 'edit', $level ) {
+       function showOptions( $namespace, $type, $level ) {
                $formDescriptor = [
                        'namespace' => [
                                'class' => 'HTMLSelectNamespace',
index bfef5e0..2496192 100644 (file)
@@ -35,6 +35,7 @@ class SpecialRecentChanges extends ChangesListSpecialPage {
        protected static $savedQueriesPreferenceName = 'rcfilters-saved-queries';
        protected static $daysPreferenceName = 'rcdays'; // Use general RecentChanges preference
        protected static $limitPreferenceName = 'rcfilters-limit'; // Use RCFilters-specific preference
+       protected static $collapsedPreferenceName = 'rcfilters-rc-collapsed';
 
        private $watchlistFilterGroupDefinition;
 
index f826844..2cff90e 100644 (file)
@@ -194,6 +194,9 @@ class SpecialSearch extends SpecialPage {
                $request = $this->getRequest();
                list( $this->limit, $this->offset ) = $request->getLimitOffset( 20, '' );
                $this->mPrefix = $request->getVal( 'prefix', '' );
+               if ( $this->mPrefix !== '' ) {
+                       $this->setExtraParam( 'prefix', $this->mPrefix );
+               }
 
                $user = $this->getUser();
 
@@ -259,7 +262,7 @@ class SpecialSearch extends SpecialPage {
                        return null;
                }
 
-               return $url === null ? $title->getFullUrlForRedirect() : $url;
+               return $url ?? $title->getFullUrlForRedirect();
        }
 
        /**
@@ -300,7 +303,6 @@ class SpecialSearch extends SpecialPage {
                $search->setLimitOffset( $this->limit, $this->offset );
                $search->setNamespaces( $this->namespaces );
                $search->prefix = $this->mPrefix;
-               $term = $search->transformSearchTerm( $term );
 
                Hooks::run( 'SpecialSearchSetupEngine', [ $this, $this->profile, $search ] );
                if ( !Hooks::run( 'SpecialSearchResultsPrepend', [ $this, $out, $term ] ) ) {
@@ -312,9 +314,20 @@ class SpecialSearch extends SpecialPage {
                $showSuggestion = $title === null || !$title->isKnown();
                $search->setShowSuggestion( $showSuggestion );
 
-               // fetch search results
+               $rewritten = $search->transformSearchTerm( $term );
+               if ( $rewritten !== $term ) {
+                       $term = $rewritten;
+                       wfDeprecated( 'SearchEngine::transformSearchTerm() (overridden by ' .
+                               get_class( $search ) . ')', '1.32' );
+               }
+
                $rewritten = $search->replacePrefixes( $term );
+               if ( $rewritten !== $term ) {
+                       wfDeprecated( 'SearchEngine::replacePrefixes() (overridden by ' .
+                                                 get_class( $search ) . ')', '1.32' );
+               }
 
+               // fetch search results
                $titleMatches = $search->searchTitle( $rewritten );
                $textMatches = $search->searchText( $rewritten );
 
@@ -531,6 +544,28 @@ class SpecialSearch extends SpecialPage {
                        );
                }
 
+               if ( $this->mPrefix !== '' ) {
+                       $subtitle = $this->msg( 'search-filter-title-prefix' )->plaintextParams( $this->mPrefix );
+                       $params = $this->powerSearchOptions();
+                       unset( $params['prefix'] );
+                       $params += [
+                               'search' => $term,
+                               'fulltext' => 1,
+                       ];
+
+                       $subtitle .= ' (';
+                       $subtitle .= Xml::element(
+                               'a',
+                               [
+                                       'href' => $this->getPageTitle()->getLocalURL( $params ),
+                                       'title' => $this->msg( 'search-filter-title-prefix-reset' ),
+                               ],
+                               $this->msg( 'search-filter-title-prefix-reset' )
+                       );
+                       $subtitle .= ')';
+                       $out->setSubtitle( $subtitle );
+               }
+
                $out->addJsConfigVars( [ 'searchTerm' => $term ] );
                $out->addModules( 'mediawiki.special.search' );
                $out->addModuleStyles( [
@@ -712,6 +747,18 @@ class SpecialSearch extends SpecialPage {
                $this->extraParams[$key] = $value;
        }
 
+       /**
+        * The prefix value send to Special:Search using the 'prefix' URI param
+        * It means that the user is willing to search for pages whose titles start with
+        * this prefix value.
+        * (Used by the InputBox extension)
+        *
+        * @return string
+        */
+       public function getPrefix() {
+               return $this->mPrefix;
+       }
+
        protected function getGroupName() {
                return 'pages';
        }
index 540dbc6..3069bd8 100644 (file)
@@ -129,7 +129,7 @@ class SpecialUndelete extends SpecialPage {
         * specific title if one is set.
         *
         * @param string $permission
-        * @param User $user
+        * @param User|null $user
         * @return bool
         */
        protected function isAllowed( $permission, User $user = null ) {
index 2eeafe6..c832f2d 100644 (file)
@@ -33,7 +33,7 @@ use MediaWiki\MediaWikiServices;
 class SpecialUpload extends SpecialPage {
        /**
         * Get data POSTed through the form and assign them to the object
-        * @param WebRequest $request Data posted.
+        * @param WebRequest|null $request Data posted.
         */
        public function __construct( $request = null ) {
                parent::__construct( 'Upload', 'upload' );
@@ -587,7 +587,7 @@ class SpecialUpload extends SpecialPage {
         * @param string $license
         * @param string $copyStatus
         * @param string $source
-        * @param Config $config Configuration object to load data from
+        * @param Config|null $config Configuration object to load data from
         * @return string
         */
        public static function getInitialPageText( $comment = '', $license = '',
@@ -761,7 +761,11 @@ class SpecialUpload extends SpecialPage {
                }
                $success = $this->mUpload->unsaveUploadedFile();
                if ( !$success ) {
-                       $this->getOutput()->showFileDeleteError( $this->mUpload->getTempPath() );
+                       $this->getOutput()->showFatalError(
+                               $this->msg( 'filedeleteerror' )
+                                       ->params( $this->mUpload->getTempPath() )
+                                       ->escaped()
+                       );
 
                        return false;
                } else {
index a05452d..4205188 100644 (file)
@@ -87,11 +87,7 @@ class UserrightsPage extends SpecialPage {
 
                $out->addModules( [ 'mediawiki.special.userrights' ] );
 
-               if ( $par !== null ) {
-                       $this->mTarget = $par;
-               } else {
-                       $this->mTarget = $request->getVal( 'user' );
-               }
+               $this->mTarget = $par ?? $request->getVal( 'user' );
 
                if ( is_string( $this->mTarget ) ) {
                        $this->mTarget = trim( $this->mTarget );
@@ -373,7 +369,7 @@ class UserrightsPage extends SpecialPage {
                }
                if ( $add ) {
                        foreach ( $add as $index => $group ) {
-                               $expiry = isset( $groupExpiries[$group] ) ? $groupExpiries[$group] : null;
+                               $expiry = $groupExpiries[$group] ?? null;
                                if ( !$user->addGroup( $group, $expiry ) ) {
                                        unset( $add[$index] );
                                }
@@ -658,7 +654,7 @@ class UserrightsPage extends SpecialPage {
                        )->escaped();
 
                $grouplist = '';
-               $count = count( $list );
+               $count = count( $list ) + count( $tempList );
                if ( $count > 0 ) {
                        $grouplist = $this->msg( 'userrights-groupsmember' )
                                ->numParams( $count )
index 48728a3..35c5689 100644 (file)
@@ -233,8 +233,8 @@ class SpecialVersion extends SpecialPage {
                }
                $software[$dbr->getSoftwareLink()] = $dbr->getServerInfo();
 
-               if ( IcuCollation::getICUVersion() ) {
-                       $software['[http://site.icu-project.org/ ICU]'] = IcuCollation::getICUVersion();
+               if ( defined( 'INTL_ICU_VERSION' ) ) {
+                       $software['[http://site.icu-project.org/ ICU]'] = INTL_ICU_VERSION;
                }
 
                // Allow a hook to add/remove items.
@@ -396,7 +396,7 @@ class SpecialVersion extends SpecialPage {
        public static function getExtensionTypeName( $type ) {
                $types = self::getExtensionTypes();
 
-               return isset( $types[$type] ) ? $types[$type] : $types['other'];
+               return $types[$type] ?? $types['other'];
        }
 
        /**
@@ -658,13 +658,7 @@ class SpecialVersion extends SpecialPage {
         * @return int
         */
        public function compare( $a, $b ) {
-               if ( $a['name'] === $b['name'] ) {
-                       return 0;
-               } else {
-                       return $this->getLanguage()->lc( $a['name'] ) > $this->getLanguage()->lc( $b['name'] )
-                               ? 1
-                               : -1;
-               }
+               return $this->getLanguage()->lc( $a['name'] ) <=> $this->getLanguage()->lc( $b['name'] );
        }
 
        /**
@@ -838,7 +832,7 @@ class SpecialVersion extends SpecialPage {
                $description = $out->parseInline( $description );
 
                // ... now get the authors for this extension
-               $authors = isset( $extension['author'] ) ? $extension['author'] : [];
+               $authors = $extension['author'] ?? [];
                $authors = $this->listAuthors( $authors, $extension['name'], $extensionPath );
 
                // Finally! Create the table
@@ -1140,7 +1134,7 @@ class SpecialVersion extends SpecialPage {
         */
        public function getEntryPointInfo() {
                global $wgArticlePath, $wgScriptPath;
-               $scriptPath = $wgScriptPath ? $wgScriptPath : "/";
+               $scriptPath = $wgScriptPath ?: "/";
                $entryPoints = [
                        'version-entrypoints-articlepath' => $wgArticlePath,
                        'version-entrypoints-scriptpath' => $scriptPath,
index fc0c312..d323c9e 100644 (file)
@@ -103,9 +103,7 @@ class WantedCategoriesPage extends WantedQueryPage {
                } else {
                        $plink = $this->getLinkRenderer()->makeLink( $nt, $text );
 
-                       $currentValue = isset( $this->currentCategoryCounts[$result->title] )
-                               ? $this->currentCategoryCounts[$result->title]
-                               : 0;
+                       $currentValue = $this->currentCategoryCounts[$result->title] ?? 0;
                        $cachedValue = intval( $result->value ); // T76910
 
                        // If the category has been created or emptied since the list was refreshed, strike it
index ea73347..5b48f4e 100644 (file)
@@ -35,6 +35,7 @@ class SpecialWatchlist extends ChangesListSpecialPage {
        protected static $savedQueriesPreferenceName = 'rcfilters-wl-saved-queries';
        protected static $daysPreferenceName = 'watchlistdays';
        protected static $limitPreferenceName = 'wllimit';
+       protected static $collapsedPreferenceName = 'rcfilters-wl-collapsed';
 
        private $maxDays;
 
@@ -110,10 +111,15 @@ class SpecialWatchlist extends ChangesListSpecialPage {
        }
 
        public static function checkStructuredFilterUiEnabled( Config $config, User $user ) {
-               return (
-                       $config->get( 'StructuredChangeFiltersOnWatchlist' ) &&
-                       $user->getOption( 'rcenhancedfilters' )
-               );
+               if ( !$config->get( 'StructuredChangeFiltersOnWatchlist' ) ) {
+                       return false;
+               }
+
+               if ( $config->get( 'StructuredChangeFiltersShowWatchlistPreference' ) ) {
+                       return !$user->getOption( 'wlenhancedfilters-disable' );
+               } else {
+                       return $user->getOption( 'rcenhancedfilters' );
+               }
        }
 
        /**
@@ -520,7 +526,7 @@ class SpecialWatchlist extends ChangesListSpecialPage {
                                                                $this->msg( 'watchlist-unwatch' )->text(), [
                                                                        'class' => 'mw-unwatch-link',
                                                                        'title' => $this->msg( 'tooltip-ca-unwatch' )->text()
-                                                               ], [ 'action' => 'unwatch' ] ) . '&#160;';
+                                                               ], [ 'action' => 'unwatch' ] ) . "\u{00A0}";
                                }
                        } );
                }
@@ -750,45 +756,36 @@ class SpecialWatchlist extends ChangesListSpecialPage {
        }
 
        function cutoffselector( $options ) {
-               // Cast everything to strings immediately, so that we know all of the values have the same
-               // precision, and can be compared with '==='. 2/24 has a few more decimal places than its
-               // default string representation, for example, and would confuse comparisons.
-
-               // Misleadingly, the 'days' option supports hours too.
-               $days = array_map( 'strval', [ 1 / 24, 2 / 24, 6 / 24, 12 / 24, 1, 3, 7 ] );
-
-               $userWatchlistOption = (string)$this->getUser()->getOption( 'watchlistdays' );
-               // add the user preference, if it isn't available already
-               if ( !in_array( $userWatchlistOption, $days ) && $userWatchlistOption !== '0' ) {
-                       $days[] = $userWatchlistOption;
-               }
-
-               $maxDays = (string)$this->maxDays;
-               // add the maximum possible value, if it isn't available already
-               if ( !in_array( $maxDays, $days ) ) {
-                       $days[] = $maxDays;
-               }
-
-               $selected = (string)$options['days'];
+               $selected = (float)$options['days'];
                if ( $selected <= 0 ) {
-                       $selected = $maxDays;
-               }
-
-               // add the currently selected value, if it isn't available already
-               if ( !in_array( $selected, $days ) ) {
-                       $days[] = $selected;
-               }
+                       $selected = $this->maxDays;
+               }
+
+               $selectedHours = round( $selected * 24 );
+
+               $hours = array_unique( array_filter( [
+                       1,
+                       2,
+                       6,
+                       12,
+                       24,
+                       72,
+                       168,
+                       24 * (float)$this->getUser()->getOption( 'watchlistdays', 0 ),
+                       24 * $this->maxDays,
+                       $selectedHours
+               ] ) );
+               asort( $hours );
 
-               $select = new XmlSelect( 'days', 'days', $selected );
+               $select = new XmlSelect( 'days', 'days', (float)( $selectedHours / 24 ) );
 
-               asort( $days );
-               foreach ( $days as $value ) {
-                       if ( $value < 1 ) {
-                               $name = $this->msg( 'hours' )->numParams( $value * 24 )->text();
+               foreach ( $hours as $value ) {
+                       if ( $value < 24 ) {
+                               $name = $this->msg( 'hours' )->numParams( $value )->text();
                        } else {
-                               $name = $this->msg( 'days' )->numParams( $value )->text();
+                               $name = $this->msg( 'days' )->numParams( $value / 24 )->text();
                        }
-                       $select->addOption( $name, $value );
+                       $select->addOption( $name, (float)( $value / 24 ) );
                }
 
                return $select->getHTML() . "\n<br />\n";
index 5677ac8..1d3ffd7 100644 (file)
@@ -208,15 +208,18 @@ class SpecialWhatLinksHere extends IncludableSpecialPage {
                                        if ( $hidelinks || $hidetrans || $hideredirs || $hideimages ) {
                                                $out->addHTML( $this->getFilterPanel() );
                                        }
-                                       $msgKey = is_int( $namespace ) ? 'nolinkshere-ns-2' : 'nolinkshere-2';
-                                       $link = $this->getLinkRenderer()->makeKnownLink(
+                                       $msgKey = is_int( $namespace ) ? 'nolinkshere-ns' : 'nolinkshere';
+                                       $link = $this->getLinkRenderer()->makeLink(
                                                $this->target,
                                                null,
                                                [],
                                                $this->target->isRedirect() ? [ 'redirect' => 'no' ] : []
                                        );
 
-                                       $errMsg = $this->msg( $msgKey )->rawParams( $link )->parseAsBlock();
+                                       $errMsg = $this->msg( $msgKey )
+                                               ->params( $this->target->getPrefixedText() )
+                                               ->rawParams( $link )
+                                               ->parseAsBlock();
                                        $out->addHTML( $errMsg );
                                        $out->setStatusCode( 404 );
                                }
@@ -282,14 +285,17 @@ class SpecialWhatLinksHere extends IncludableSpecialPage {
                                $out->addHTML( $this->whatlinkshereForm() );
                                $out->addHTML( $this->getFilterPanel() );
 
-                               $link = $this->getLinkRenderer()->makeKnownLink(
+                               $link = $this->getLinkRenderer()->makeLink(
                                        $this->target,
                                        null,
                                        [],
                                        $this->target->isRedirect() ? [ 'redirect' => 'no' ] : []
                                );
 
-                               $msg = $this->msg( 'linkshere-2' )->rawParams( $link )->parseAsBlock();
+                               $msg = $this->msg( 'linkshere' )
+                                       ->params( $this->target->getPrefixedText() )
+                                       ->rawParams( $link )
+                                       ->parseAsBlock();
                                $out->addHTML( $msg );
 
                                $prevnext = $this->getPrevNext( $prevId, $nextId );
@@ -517,7 +523,7 @@ class SpecialWhatLinksHere extends IncludableSpecialPage {
                        ]
                );
 
-               $f .= '&#160;' .
+               $f .= "\u{00A0}" .
                        Xml::checkLabel(
                                $this->msg( 'invert' )->text(),
                                'invert',
index a2f3128..0b6c165 100644 (file)
@@ -186,7 +186,7 @@ class Licenses extends HTMLFormField {
                        $attribs['selected'] = 'selected';
                }
 
-               $val = str_repeat( /* &nbsp */ "\xc2\xa0", $depth * 2 ) . $text;
+               $val = str_repeat( /* &nbsp */ "\u{00A0}", $depth * 2 ) . $text;
                return str_repeat( "\t", $depth ) . Xml::element( 'option', $attribs, $val ) . "\n";
        }
 
index 251a286..6dc129c 100644 (file)
@@ -61,8 +61,6 @@ class UploadSourceField extends HTMLTextField {
         * @return int
         */
        function getSize() {
-               return isset( $this->mParams['size'] )
-                       ? $this->mParams['size']
-                       : 60;
+               return $this->mParams['size'] ?? 60;
        }
 }
index b60882a..5f07073 100644 (file)
@@ -29,4 +29,10 @@ class EditWatchlistNormalHTMLForm extends OOUIHTMLForm {
                        ? $this->msg( 'blanknamespace' )->escaped()
                        : htmlspecialchars( $this->getContext()->getLanguage()->getFormattedNsText( $namespace ) );
        }
+
+       public function displaySection(
+               $fields, $sectionName = '', $fieldsetIDPrefix = '', &$hasUserVisibleFields = false
+       ) {
+               return parent::displaySection( $fields, $sectionName, 'editwatchlist-', $hasUserVisibleFields );
+       }
 }
diff --git a/includes/specials/forms/PreferencesForm.php b/includes/specials/forms/PreferencesForm.php
deleted file mode 100644 (file)
index a124410..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-<?php
-/**
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- */
-
-/**
- * Temporarily define PreferencesForm as an interface, so PreferencesFormOOUI
- * and PreferencesFormLegacy can implement it.
- *
- * When PreferencesFormLegacy we can merge PreferencesFormOOUI with PreferencesForm.
- */
-interface PreferencesForm {
-}
index e6bc494..c1f1026 100644 (file)
@@ -22,8 +22,10 @@ use MediaWiki\MediaWikiServices;
 
 /**
  * Form to edit user preferences.
+ *
+ * @since 1.32
  */
-class PreferencesFormLegacy extends HTMLForm implements PreferencesForm {
+class PreferencesFormLegacy extends HTMLForm {
        // Override default value from HTMLForm
        protected $mSubSectionBeforeFields = false;
 
@@ -102,7 +104,7 @@ class PreferencesFormLegacy extends HTMLForm implements PreferencesForm {
                foreach ( $this->mFlatFields as $fieldname => $field ) {
                        if ( $field instanceof HTMLNestedFilterable ) {
                                $info = $field->mParams;
-                               $prefix = isset( $info['prefix'] ) ? $info['prefix'] : $fieldname;
+                               $prefix = $info['prefix'] ?? $fieldname;
                                foreach ( $field->filterDataForSubmit( $data[$fieldname] ) as $key => $value ) {
                                        $data["$prefix$key"] = $value;
                                }
@@ -128,7 +130,8 @@ class PreferencesFormLegacy extends HTMLForm implements PreferencesForm {
         * @return string
         */
        function getLegend( $key ) {
-               $legend = parent::getLegend( $key );
+               $aliasKey = ( $key === 'optoutwatchlist' || $key === 'optoutrc' ) ? 'opt-out' : $key;
+               $legend = parent::getLegend( $aliasKey );
                Hooks::run( 'PreferencesGetLegend', [ $this, $key, &$legend ] );
                return $legend;
        }
@@ -141,3 +144,11 @@ class PreferencesFormLegacy extends HTMLForm implements PreferencesForm {
                return array_keys( array_filter( $this->mFieldTree, 'is_array' ) );
        }
 }
+
+/**
+ * Retain the old class name for backwards compatibility.
+ * In the future, this alias will be changed to point to PreferencesFormOOUI.
+ *
+ * @deprecated since 1.32
+ */
+class_alias( PreferencesFormLegacy::class, 'PreferencesForm' );
index 3a5adbb..cfa8f8f 100644 (file)
 
 /**
  * Form to edit user preferences.
+ *
+ * @since 1.32
  */
-class PreferencesFormOOUI extends OOUIHTMLForm implements PreferencesForm {
+class PreferencesFormOOUI extends OOUIHTMLForm {
        // Override default value from HTMLForm
        protected $mSubSectionBeforeFields = false;
 
@@ -103,7 +105,7 @@ class PreferencesFormOOUI extends OOUIHTMLForm implements PreferencesForm {
                foreach ( $this->mFlatFields as $fieldname => $field ) {
                        if ( $field instanceof HTMLNestedFilterable ) {
                                $info = $field->mParams;
-                               $prefix = isset( $info['prefix'] ) ? $info['prefix'] : $fieldname;
+                               $prefix = $info['prefix'] ?? $fieldname;
                                foreach ( $field->filterDataForSubmit( $data[$fieldname] ) as $key => $value ) {
                                        $data["$prefix$key"] = $value;
                                }
@@ -225,7 +227,8 @@ class PreferencesFormOOUI extends OOUIHTMLForm implements PreferencesForm {
         * @return string
         */
        function getLegend( $key ) {
-               $legend = parent::getLegend( $key );
+               $aliasKey = ( $key === 'optoutwatchlist' || $key === 'optoutrc' ) ? 'opt-out' : $key;
+               $legend = parent::getLegend( $aliasKey );
                Hooks::run( 'PreferencesGetLegend', [ $this, $key, &$legend ] );
                return $legend;
        }
index 8ab6f29..e37200f 100644 (file)
@@ -55,19 +55,16 @@ class UploadForm extends HTMLForm {
 
                $this->mWatch = !empty( $options['watch'] );
                $this->mForReUpload = !empty( $options['forreupload'] );
-               $this->mSessionKey = isset( $options['sessionkey'] ) ? $options['sessionkey'] : '';
+               $this->mSessionKey = $options['sessionkey'] ?? '';
                $this->mHideIgnoreWarning = !empty( $options['hideignorewarning'] );
                $this->mDestWarningAck = !empty( $options['destwarningack'] );
-               $this->mDestFile = isset( $options['destfile'] ) ? $options['destfile'] : '';
+               $this->mDestFile = $options['destfile'] ?? '';
 
-               $this->mComment = isset( $options['description'] ) ?
-                       $options['description'] : '';
+               $this->mComment = $options['description'] ?? '';
 
-               $this->mTextTop = isset( $options['texttop'] )
-                       ? $options['texttop'] : '';
+               $this->mTextTop = $options['texttop'] ?? '';
 
-               $this->mTextAfterSummary = isset( $options['textaftersummary'] )
-                       ? $options['textaftersummary'] : '';
+               $this->mTextAfterSummary = $options['textaftersummary'] ?? '';
 
                $sourceDescriptor = $this->getSourceSection();
                $descriptor = $sourceDescriptor
index 940f69c..fbd801d 100644 (file)
@@ -21,7 +21,7 @@
  * @ingroup SpecialPage
  * @author Ævar Arnfjörð Bjarmason <avarab@gmail.com>
  * @copyright Copyright © 2005, Ævar Arnfjörð Bjarmason
- * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ * @license GPL-2.0-or-later
  */
 
 /**
index 26ed499..87c849a 100644 (file)
@@ -44,7 +44,7 @@ class ActiveUsersPager extends UsersPager {
        private $blockStatusByUid;
 
        /**
-        * @param IContextSource $context
+        * @param IContextSource|null $context
         * @param FormOptions $opts
         */
        function __construct( IContextSource $context = null, FormOptions $opts ) {
index e6a0f0b..5addd9c 100644 (file)
@@ -58,7 +58,7 @@ class AllMessagesTablePager extends TablePager {
 
                $this->talk = $this->msg( 'talkpagelinktext' )->escaped();
 
-               $this->lang = ( $langObj ? $langObj : $wgContLang );
+               $this->lang = $langObj ?: $wgContLang;
                $this->langcode = $this->lang->getCode();
                $this->foreign = !$this->lang->equals( $wgContLang );
 
@@ -357,7 +357,7 @@ class AllMessagesTablePager extends TablePager {
                        $formatted = strval( $this->formatValue( 'am_actual', $row->am_actual ) );
 
                        if ( $formatted === '' ) {
-                               $formatted = '&#160;';
+                               $formatted = "\u{00A0}";
                        }
 
                        $s .= Xml::tags( 'td', $this->getCellAttrs( 'am_actual', $row->am_actual ), $formatted )
index e31498a..59fa948 100644 (file)
@@ -64,12 +64,12 @@ class ContribsPager extends RangeChronologicalPager {
                        $this->messages[$msg] = $this->msg( $msg )->escaped();
                }
 
-               $this->target = isset( $options['target'] ) ? $options['target'] : '';
-               $this->contribs = isset( $options['contribs'] ) ? $options['contribs'] : 'users';
-               $this->namespace = isset( $options['namespace'] ) ? $options['namespace'] : '';
-               $this->tagFilter = isset( $options['tagfilter'] ) ? $options['tagfilter'] : false;
-               $this->nsInvert = isset( $options['nsInvert'] ) ? $options['nsInvert'] : false;
-               $this->associated = isset( $options['associated'] ) ? $options['associated'] : false;
+               $this->target = $options['target'] ?? '';
+               $this->contribs = $options['contribs'] ?? 'users';
+               $this->namespace = $options['namespace'] ?? '';
+               $this->tagFilter = $options['tagfilter'] ?? false;
+               $this->nsInvert = $options['nsInvert'] ?? false;
+               $this->associated = $options['associated'] ?? false;
 
                $this->deletedOnly = !empty( $options['deletedOnly'] );
                $this->topOnly = !empty( $options['topOnly'] );
@@ -593,7 +593,10 @@ class ContribsPager extends RangeChronologicalPager {
 
                // Let extensions add data
                Hooks::run( 'ContributionsLineEnding', [ $this, &$ret, $row, &$classes, &$attribs ] );
-               $attribs = wfArrayFilterByKey( $attribs, [ Sanitizer::class, 'isReservedDataAttribute' ] );
+               $attribs = array_filter( $attribs,
+                       [ Sanitizer::class, 'isReservedDataAttribute' ],
+                       ARRAY_FILTER_USE_KEY
+               );
 
                // TODO: Handle exceptions in the catch block above.  Do any extensions rely on
                // receiving empty rows?
@@ -640,10 +643,10 @@ class ContribsPager extends RangeChronologicalPager {
         * @return array Options array with processed start and end date filter options
         */
        public static function processDateFilter( array $opts ) {
-               $start = isset( $opts['start'] ) ? $opts['start'] : '';
-               $end = isset( $opts['end'] ) ? $opts['end'] : '';
-               $year = isset( $opts['year'] ) ? $opts['year'] : '';
-               $month = isset( $opts['month'] ) ? $opts['month'] : '';
+               $start = $opts['start'] ?? '';
+               $end = $opts['end'] ?? '';
+               $year = $opts['year'] ?? '';
+               $month = $opts['month'] ?? '';
 
                if ( $start !== '' && $end !== '' && $start > $end ) {
                        $temp = $start;
index f3de64d..ee7eb3e 100644 (file)
@@ -23,6 +23,7 @@
  * @ingroup Pager
  */
 use MediaWiki\MediaWikiServices;
+use Wikimedia\Rdbms\IDatabase;
 use Wikimedia\Rdbms\IResultWrapper;
 use Wikimedia\Rdbms\FakeResultWrapper;
 
@@ -220,7 +221,10 @@ class DeletedContribsPager extends IndexPager {
 
                // Let extensions add data
                Hooks::run( 'DeletedContributionsLineEnding', [ $this, &$ret, $row, &$classes, &$attribs ] );
-               $attribs = wfArrayFilterByKey( $attribs, [ Sanitizer::class, 'isReservedDataAttribute' ] );
+               $attribs = array_filter( $attribs,
+                       [ Sanitizer::class, 'isReservedDataAttribute' ],
+                       ARRAY_FILTER_USE_KEY
+               );
 
                if ( $classes === [] && $attribs === [] && $ret === '' ) {
                        wfDebug( "Dropping Special:DeletedContribution row that could not be formatted\n" );
@@ -256,7 +260,7 @@ class DeletedContribsPager extends IndexPager {
                        'comment' => CommentStore::getStore()->getComment( 'ar_comment', $row )->text,
                        'user' => $row->ar_user,
                        'user_text' => $row->ar_user_text,
-                       'actor' => isset( $row->ar_actor ) ? $row->ar_actor : null,
+                       'actor' => $row->ar_actor ?? null,
                        'timestamp' => $row->ar_timestamp,
                        'minor_edit' => $row->ar_minor_edit,
                        'deleted' => $row->ar_deleted,
index b2f1487..3d7148d 100644 (file)
@@ -159,6 +159,9 @@ class ImageListPager extends TablePager {
        }
 
        /**
+        * The array keys (but not the array values) are used in sql. Phan
+        * gets confused by this, so mark this method as being ok for sql in general.
+        * @return-taint onlysafefor_sql
         * @return array
         */
        function getFieldNames() {
index 3b69698..3e97923 100644 (file)
@@ -44,8 +44,8 @@ class ProtectedPagesPager extends TablePager {
         * @param bool $noredirect
         * @param LinkRenderer $linkRenderer
         */
-       function __construct( $form, $conds = [], $type, $level, $namespace,
-               $sizetype = '', $size = 0, $indefonly = false, $cascadeonly = false, $noredirect = false,
+       function __construct( $form, $conds, $type, $level, $namespace,
+               $sizetype, $size, $indefonly, $cascadeonly, $noredirect,
                LinkRenderer $linkRenderer
        ) {
                $this->mForm = $form;
@@ -235,7 +235,7 @@ class ProtectedPagesPager extends TablePager {
                                                $this->getUser()
                                        ) ) {
                                                $value = CommentStore::getStore()->getComment( 'log_comment', $row )->text;
-                                               $formatted = Linker::formatComment( $value !== null ? $value : '' );
+                                               $formatted = Linker::formatComment( $value ?? '' );
                                        } else {
                                                $formatted = $this->msg( 'rev-deleted-comment' )->escaped();
                                        }
index 8f172f8..ed437be 100644 (file)
@@ -26,7 +26,7 @@ class ProtectedTitlesPager extends AlphabeticPager {
 
        public $mForm, $mConds;
 
-       function __construct( $form, $conds = [], $type, $level, $namespace,
+       function __construct( $form, $conds, $type, $level, $namespace,
                $sizetype = '', $size = 0
        ) {
                $this->mForm = $form;
index d17332f..aa757e6 100644 (file)
@@ -38,9 +38,9 @@ class UsersPager extends AlphabeticPager {
        protected $userGroupCache;
 
        /**
-        * @param IContextSource $context
-        * @param array $par (Default null)
-        * @param bool $including Whether this page is being transcluded in
+        * @param IContextSource|null $context
+        * @param array|null $par (Default null)
+        * @param bool|null $including Whether this page is being transcluded in
         * another page
         */
        function __construct( IContextSource $context = null, $par = null, $including = null ) {
@@ -411,7 +411,7 @@ class UsersPager extends AlphabeticPager {
                        $user = User::newFromId( $uid );
                        return $user->getGroupMemberships();
                } else {
-                       return isset( $cache[$uid] ) ? $cache[$uid] : [];
+                       return $cache[$uid] ?? [];
                }
        }
 
index 6493df8..e41a98b 100644 (file)
@@ -1,10 +1,20 @@
 <table class="{{# tableClasses }}{{ . }} {{/ tableClasses }}" data-mw-ts="{{{ fullTimestamp }}}">
-       <tr>
+       <tr class="mw-rcfilters-ui-highlights-enhanced-toplevel {{# filterClasses }}{{ . }} {{/ filterClasses }}">
+               <td>
+                       <div class="mw-rcfilters-ui-highlights">
+                               <div class="mw-rcfilters-ui-highlights-color-none" data-color="none"></div>
+                               <div class="mw-rcfilters-ui-highlights-color-c1" data-color="c1"></div>
+                               <div class="mw-rcfilters-ui-highlights-color-c2" data-color="c2"></div>
+                               <div class="mw-rcfilters-ui-highlights-color-c3" data-color="c3"></div>
+                               <div class="mw-rcfilters-ui-highlights-color-c4" data-color="c4"></div>
+                               <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"></span>
                </td>
                <td class="mw-changeslist-line-prefix">{{{ prefix }}}</td>
-               <td class="mw-enhanced-rc">{{{ collectedRcFlags }}}&#160;{{ timestamp }}&#160;</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 }}}
                </td>
        </tr>
        {{# lines }}
-       <tr class="{{# classes }}{{ . }} {{/ classes }}"{{{ attribs }}}>
+       <tr class="mw-rcfilters-ui-highlights-enhanced-nested {{# classes }}{{ . }} {{/ classes }}"{{{ attribs }}}>
+               <td></td>
                <td></td>
                <td></td>
                <td class="mw-enhanced-rc">{{{ recentChangesFlags }}}&#160;</td>
+               <td>
+                       <div class="mw-rcfilters-ui-highlights mw-enhanced-rc-nested">
+                               <div class="mw-rcfilters-ui-highlights-color-none" data-color="none"></div>
+                               <div class="mw-rcfilters-ui-highlights-color-c1" data-color="c1"></div>
+                               <div class="mw-rcfilters-ui-highlights-color-c2" data-color="c2"></div>
+                               <div class="mw-rcfilters-ui-highlights-color-c3" data-color="c3"></div>
+                               <div class="mw-rcfilters-ui-highlights-color-c4" data-color="c4"></div>
+                               <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>
index 245982e..ccef56b 100644 (file)
@@ -41,7 +41,7 @@ abstract class RaggettBase extends TidyDriverBase {
         * Perform a clean/repair operation
         * @param string $text HTML to check
         * @param bool $stderr Whether to read result from STDERR rather than STDOUT
-        * @param int &$retval Exit code (-1 on internal error)
+        * @param int|null &$retval Exit code (-1 on internal error)
         * @return null|string
         * @throws MWException
         */
index b59423a..2809ea4 100644 (file)
@@ -9,7 +9,7 @@ class RaggettExternal extends RaggettBase {
         *
         * @param string $text HTML to check
         * @param bool $stderr Whether to read result from STDERR rather than STDOUT
-        * @param int &$retval Exit code (-1 on internal error)
+        * @param int|null &$retval Exit code (-1 on internal error)
         * @return string|null
         */
        protected function cleanWrapped( $text, $stderr = false, &$retval = null ) {
index bb83d6a..65d37f4 100644 (file)
@@ -9,7 +9,7 @@ class RaggettInternalHHVM extends RaggettBase {
         *
         * @param string $text HTML to check
         * @param bool $stderr Whether to read result from error status instead of output
-        * @param int &$retval Exit code (-1 on internal error)
+        * @param int|null &$retval Exit code (-1 on internal error)
         * @return string|null
         */
        protected function cleanWrapped( $text, $stderr = false, &$retval = null ) {
index e5642d9..e7724b0 100644 (file)
@@ -9,7 +9,7 @@ class RaggettInternalPHP extends RaggettBase {
         *
         * @param string $text HTML to check
         * @param bool $stderr Whether to read result from error status instead of output
-        * @param int &$retval Exit code (-1 on internal error)
+        * @param int|null &$retval Exit code (-1 on internal error)
         * @return string|null
         */
        protected function cleanWrapped( $text, $stderr = false, &$retval = null ) {
index c8a715b..4e93382 100644 (file)
@@ -18,9 +18,9 @@ class RemexCompatFormatter extends HtmlFormatter {
 
        public function __construct( $options = [] ) {
                parent::__construct( $options );
-               $this->attributeEscapes["\xc2\xa0"] = '&#160;';
+               $this->attributeEscapes["\u{00A0}"] = '&#160;';
                unset( $this->attributeEscapes["&"] );
-               $this->textEscapes["\xc2\xa0"] = '&#160;';
+               $this->textEscapes["\u{00A0}"] = '&#160;';
                unset( $this->textEscapes["&"] );
        }
 
index 7cf7bbe..ab2ba46 100644 (file)
@@ -28,6 +28,7 @@ class RemexCompatMunger implements TreeHandler {
                "button" => true,
                "cite" => true,
                "code" => true,
+               "del" => true,
                "dfn" => true,
                "em" => true,
                "font" => true,
@@ -35,6 +36,7 @@ class RemexCompatMunger implements TreeHandler {
                "iframe" => true,
                "img" => true,
                "input" => true,
+               "ins" => true,
                "kbd" => true,
                "label" => true,
                "legend" => true,
index 213343f..47660e3 100644 (file)
@@ -29,7 +29,7 @@ class MalformedTitleException extends Exception implements ILocalizedException {
 
        /**
         * @param string $errorMessage Localisation message describing the error (since MW 1.26)
-        * @param string $titleText The invalid title text (since MW 1.26)
+        * @param string|null $titleText The invalid title text (since MW 1.26)
         * @param string[] $errorMessageParameters Additional parameters for the error message.
         * $titleText will be appended if it's not null. (since MW 1.26)
         */
index 7c2d393..890a870 100644 (file)
@@ -275,15 +275,10 @@ class MediaWikiTitleCodec implements TitleFormatter, TitleParser {
                        'user_case_dbkey' => $dbkey,
                ];
 
-               # Strip soft hyphens (U+00AD) and Unicode directional formatting characters (U+061C, U+200E,
-               # U+200F, U+202A. U+202B, U+202C, U+202D, U+202E, U+2066, U+2067, U+2068, U+2069).
+               # Strip Unicode bidi override characters.
                # Sometimes they slip into cut-n-pasted page titles, where the
-               # soft hyphens or override chars get included in list displays.
-               $dbkey = preg_replace(
-                       '/\xC2\xAD|\xD8\x9C|\xE2\x80[\x8E\x8F\xAA-\xAE]|\xE2\x81[\xA6-\xA9]/S',
-                       '',
-                       $dbkey
-               );
+               # override chars get included in list displays.
+               $dbkey = preg_replace( '/\xE2\x80[\x8E\x8F\xAA-\xAE]/S', '', $dbkey );
 
                # Clean up whitespace
                # Note: use of the /u option on preg_replace here will cause
index 064ca67..dcebb60 100644 (file)
@@ -160,7 +160,7 @@ abstract class UploadBase {
         * @return null|UploadBase
         */
        public static function createFromRequest( &$request, $type = null ) {
-               $type = $type ? $type : $request->getVal( 'wpSourceType', 'File' );
+               $type = $type ?: $request->getVal( 'wpSourceType', 'File' );
 
                if ( !$type ) {
                        return null;
@@ -247,7 +247,7 @@ abstract class UploadBase {
 
        /**
         * @param string $tempPath File system path to temporary file containing the upload
-        * @param int $fileSize
+        * @param int|null $fileSize
         */
        protected function setTempFile( $tempPath, $fileSize = null ) {
                $this->mTempPath = $tempPath;
@@ -854,7 +854,7 @@ abstract class UploadBase {
                        if ( !is_array( $error ) ) {
                                $error = [ $error ];
                        }
-                       return call_user_func_array( 'Status::newFatal', $error );
+                       return Status::newFatal( ...$error );
                }
 
                $status = $this->getLocalFile()->upload(
@@ -1063,7 +1063,7 @@ abstract class UploadBase {
                if ( !$isPartial ) {
                        $error = $this->runUploadStashFileHook( $user );
                        if ( $error ) {
-                               return call_user_func_array( 'Status::newFatal', $error );
+                               return Status::newFatal( ...$error );
                        }
                }
                try {
@@ -1103,7 +1103,7 @@ abstract class UploadBase {
         * file again.
         *
         * @deprecated since 1.28 Use tryStashFile() instead
-        * @param User $user
+        * @param User|null $user
         * @return UploadStashFile Stashed file
         * @throws UploadStashBadPathException
         * @throws UploadStashFileException
@@ -1116,7 +1116,7 @@ abstract class UploadBase {
        /**
         * Implementation for stashFile() and tryStashFile().
         *
-        * @param User $user
+        * @param User|null $user
         * @return UploadStashFile Stashed file
         */
        protected function doStashFile( User $user = null ) {
@@ -1397,7 +1397,7 @@ abstract class UploadBase {
         */
        public static function checkXMLEncodingMissmatch( $file ) {
                global $wgSVGMetadataCutoff;
-               $contents = file_get_contents( $file, false, null, -1, $wgSVGMetadataCutoff );
+               $contents = file_get_contents( $file, false, null, 0, $wgSVGMetadataCutoff );
                $encodingRegex = '!encoding[ \t\n\r]*=[ \t\n\r]*[\'"](.*?)[\'"]!si';
 
                if ( preg_match( "!<\?xml\b(.*?)\?>!si", $contents, $matches ) ) {
@@ -1529,7 +1529,7 @@ abstract class UploadBase {
         * @todo Replace this with a whitelist filter!
         * @param string $element
         * @param array $attribs
-        * @param array $data
+        * @param array|null $data
         * @return bool
         */
        public function checkSvgScriptCallback( $element, $attribs, $data = null ) {
@@ -1864,8 +1864,7 @@ abstract class UploadBase {
                # look up scanner configuration
                $command = $wgAntivirusSetup[$wgAntivirus]['command'];
                $exitCodeMap = $wgAntivirusSetup[$wgAntivirus]['codemap'];
-               $msgPattern = isset( $wgAntivirusSetup[$wgAntivirus]['messagepattern'] ) ?
-                       $wgAntivirusSetup[$wgAntivirus]['messagepattern'] : null;
+               $msgPattern = $wgAntivirusSetup[$wgAntivirus]['messagepattern'] ?? null;
 
                if ( strpos( $command, "%f" ) === false ) {
                        # simple pattern: append file to scan
index 68bcb9d..ee6f250 100644 (file)
@@ -210,7 +210,7 @@ class UploadFromChunks extends UploadFromFile {
                // override doStashFile() with completely different functionality in this class...
                $error = $this->runUploadStashFileHook( $this->user );
                if ( $error ) {
-                       call_user_func_array( [ $status, 'fatal' ], $error );
+                       $status->fatal( ...$error );
                        return $status;
                }
                try {
@@ -422,9 +422,9 @@ class UploadChunkFileException extends MWException {
 
 class UploadChunkVerificationException extends MWException {
        public $msg;
-       public function __construct( $res ) {
-               $this->msg = call_user_func_array( 'wfMessage', $res );
-               parent::__construct( call_user_func_array( 'wfMessage', $res )
+       public function __construct( array $res ) {
+               $this->msg = wfMessage( ...$res );
+               parent::__construct( wfMessage( ...$res )
                        ->inLanguage( 'en' )->useDatabase( false )->text() );
        }
 }
index e25b11e..4e40dce 100644 (file)
@@ -52,7 +52,7 @@
  */
 class UploadStash {
        // Format of the key for files -- has to be suitable as a filename itself (e.g. ab12cd34ef.jpg)
-       const KEY_FORMAT_REGEX = '/^[\w-\.]+\.\w*$/';
+       const KEY_FORMAT_REGEX = '/^[\w\-\.]+\.\w*$/';
        const MAX_US_PROPS_SIZE = 65535;
 
        /**
@@ -81,7 +81,7 @@ class UploadStash {
         * (should replace it eventually).
         *
         * @param FileRepo $repo
-        * @param User $user (default null)
+        * @param User|null $user
         */
        public function __construct( FileRepo $repo, $user = null ) {
                // this might change based on wiki's configuration.
@@ -202,7 +202,7 @@ class UploadStash {
         * database, along with other metadata.
         *
         * @param string $path Path to file you want stashed
-        * @param string $sourceType The type of upload that generated this file
+        * @param string|null $sourceType The type of upload that generated this file
         *   (currently, I believe, 'file' or null)
         * @throws UploadStashBadPathException
         * @throws UploadStashFileException
@@ -777,7 +777,8 @@ class UploadStashException extends MWException implements ILocalizedException {
        /**
         * @param string|array|MessageSpecifier $messageSpec See Message::newFromSpecifier
         * @param int $code Exception code
-        * @param Exception|Throwable $previous The previous exception used for the exception chaining.
+        * @param Exception|Throwable|null $previous The previous exception used for the exception
+        *  chaining.
         */
        public function __construct( $messageSpec, $code = 0, $previous = null ) {
                $this->messageSpec = $messageSpec;
index 6b8153c..960a486 100644 (file)
@@ -139,10 +139,8 @@ class BotPassword implements IDBAccessObject {
                        'bp_user' => 0,
                        'bp_app_id' => isset( $data['appId'] ) ? trim( $data['appId'] ) : '',
                        'bp_token' => '**unsaved**',
-                       'bp_restrictions' => isset( $data['restrictions'] )
-                               ? $data['restrictions']
-                               : MWRestrictions::newDefault(),
-                       'bp_grants' => isset( $data['grants'] ) ? $data['grants'] : [],
+                       'bp_restrictions' => $data['restrictions'] ?? MWRestrictions::newDefault(),
+                       'bp_grants' => $data['grants'] ?? [],
                ];
 
                if (
index f953b14..66674dc 100644 (file)
@@ -27,8 +27,20 @@ use MediaWiki\MediaWikiServices;
  * @since 1.31
  */
 class ExternalUserNames {
+
+       /**
+        * @var string
+        */
        private $usernamePrefix = 'imported';
+
+       /**
+        * @var bool
+        */
        private $assignKnownUsers = false;
+
+       /**
+        * @var bool[]
+        */
        private $triedCreations = [];
 
        /**
@@ -69,8 +81,16 @@ class ExternalUserNames {
        /**
         * Add an interwiki prefix to the username, if appropriate
         *
-        * @param string $name Name being imported
-        * @return string Name, possibly with the prefix prepended.
+        * This method does have a side-effect on SUL (single user login) wikis: Calling this calls the
+        * ImportHandleUnknownUser hook from the CentralAuth extension, which assigns a local ID to the
+        * global user name, if possible. No prefix is applied if this is successful.
+        *
+        * @see https://meta.wikimedia.org/wiki/Help:Unified_login
+        * @see https://www.mediawiki.org/wiki/Manual:Hooks/ImportHandleUnknownUser
+        *
+        * @param string $name
+        * @return string Either the unchanged username if it's a known local user (or not a valid
+        *  username), otherwise the name with the prefix prepended.
         */
        public function applyPrefix( $name ) {
                if ( !User::isUsableName( $name ) ) {
@@ -99,8 +119,8 @@ class ExternalUserNames {
        /**
         * Add an interwiki prefix to the username regardless of circumstances
         *
-        * @param string $name Name being imported
-        * @return string Name
+        * @param string $name
+        * @return string Prefixed username, using ">" as separator
         */
        public function addPrefix( $name ) {
                return substr( $this->usernamePrefix . '>' . $name, 0, 255 );
index faf09ee..f65bae5 100644 (file)
@@ -46,14 +46,14 @@ class PasswordReset implements LoggerAwareInterface {
        /**
         * In-process cache for isAllowed lookups, by username.
         * Contains a StatusValue object
-        * @var HashBagOStuff
+        * @var MapCacheLRU
         */
        private $permissionCache;
 
        public function __construct( Config $config, AuthManager $authManager ) {
                $this->config = $config;
                $this->authManager = $authManager;
-               $this->permissionCache = new HashBagOStuff( [ 'maxKeys' => 1 ] );
+               $this->permissionCache = new MapCacheLRU( 1 );
                $this->logger = LoggerFactory::getInstance( 'authentication' );
        }
 
@@ -122,8 +122,8 @@ class PasswordReset implements LoggerAwareInterface {
         *
         * @since 1.29 Fourth argument for displayPassword removed.
         * @param User $performingUser The user that does the password reset
-        * @param string $username The user whose password is reset
-        * @param string $email Alternative way to specify the user
+        * @param string|null $username The user whose password is reset
+        * @param string|null $email Alternative way to specify the user
         * @return StatusValue Will contain the passwords as a username => password array if the
         *   $displayPassword flag was set
         * @throws LogicException When the user is not allowed to perform the action
@@ -240,7 +240,9 @@ class PasswordReset implements LoggerAwareInterface {
 
                $passwords = [];
                foreach ( $reqs as $req ) {
-                       $this->authManager->changeAuthenticationData( $req );
+                       // This is adding a new temporary password, not intentionally changing anything
+                       // (even though it might technically invalidate an old temporary password).
+                       $this->authManager->changeAuthenticationData( $req, /* $isAddition */ true );
                }
 
                $this->logger->info(
index 7189bea..5e57a18 100644 (file)
@@ -147,6 +147,9 @@ class User implements IDBAccessObject, UserIdentity {
                'editmyuserjs',
                'editmywatchlist',
                'editsemiprotected',
+               'editsitecss',
+               'editsitejson',
+               'editsitejs',
                'editusercss',
                'edituserjson',
                'edituserjs',
@@ -636,6 +639,27 @@ class User implements IDBAccessObject, UserIdentity {
                return $u;
        }
 
+       /**
+        * Returns a User object corresponding to the given UserIdentity.
+        *
+        * @since 1.32
+        *
+        * @param UserIdentity $identity
+        *
+        * @return User
+        */
+       public static function newFromIdentity( UserIdentity $identity ) {
+               if ( $identity instanceof User ) {
+                       return $identity;
+               }
+
+               return self::newFromAnyId(
+                       $identity->getId() === 0 ? null : $identity->getId(),
+                       $identity->getName() === '' ? null : $identity->getName(),
+                       $identity->getActorId() === 0 ? null : $identity->getActorId()
+               );
+       }
+
        /**
         * Static factory method for creation from an ID, name, and/or actor ID
         *
@@ -738,7 +762,8 @@ class User implements IDBAccessObject, UserIdentity {
         * will be loaded once more from the database when accessing them.
         *
         * @param stdClass $row A row from the user table
-        * @param array $data Further data to load into the object (see User::loadFromRow for valid keys)
+        * @param array|null $data Further data to load into the object
+        *  (see User::loadFromRow for valid keys)
         * @return User
         */
        public static function newFromRow( $row, $data = null ) {
@@ -1041,7 +1066,7 @@ class User implements IDBAccessObject, UserIdentity {
         * @param string|array $groups A single group name or an array of group names
         * @param int $limit Max number of users to return. The actual limit will never exceed 5000
         *   records; larger values are ignored.
-        * @param int $after ID the user to start after
+        * @param int|null $after ID the user to start after
         * @return UserArrayFromResult
         */
        public static function findUsersByGroup( $groups, $limit = 5000, $after = null ) {
@@ -1345,32 +1370,54 @@ class User implements IDBAccessObject, UserIdentity {
                $user = $session->getUser();
                if ( $user->isLoggedIn() ) {
                        $this->loadFromUserObject( $user );
-
-                       // If this user is autoblocked, set a cookie to track the Block. This has to be done on
-                       // every session load, because an autoblocked editor might not edit again from the same
-                       // IP address after being blocked.
-                       $config = RequestContext::getMain()->getConfig();
-                       if ( $config->get( 'CookieSetOnAutoblock' ) === true ) {
-                               $block = $this->getBlock();
-                               $shouldSetCookie = $this->getRequest()->getCookie( 'BlockID' ) === null
-                                       && $block
-                                       && $block->getType() === Block::TYPE_USER
-                                       && $block->isAutoblocking();
-                               if ( $shouldSetCookie ) {
-                                       wfDebug( __METHOD__ . ': User is autoblocked, setting cookie to track' );
-                                       $block->setCookie( $this->getRequest()->response() );
-                               }
+                       if ( $user->isBlocked() ) {
+                               // If this user is autoblocked, set a cookie to track the Block. This has to be done on
+                               // every session load, because an autoblocked editor might not edit again from the same
+                               // IP address after being blocked.
+                               $this->trackBlockWithCookie();
                        }
 
                        // Other code expects these to be set in the session, so set them.
                        $session->set( 'wsUserID', $this->getId() );
                        $session->set( 'wsUserName', $this->getName() );
                        $session->set( 'wsToken', $this->getToken() );
+
                        return true;
                }
+
                return false;
        }
 
+       /**
+        * Set the 'BlockID' cookie depending on block type and user authentication status.
+        */
+       public function trackBlockWithCookie() {
+               $block = $this->getBlock();
+               if ( $block && $this->getRequest()->getCookie( 'BlockID' ) === null ) {
+                       $config = RequestContext::getMain()->getConfig();
+                       $shouldSetCookie = false;
+
+                       if ( $this->isAnon() && $config->get( 'CookieSetOnIpBlock' ) ) {
+                               // If user is logged-out, set a cookie to track the Block
+                               $shouldSetCookie = in_array( $block->getType(), [
+                                       Block::TYPE_IP, Block::TYPE_RANGE
+                               ] );
+                               if ( $shouldSetCookie ) {
+                                       $block->setCookie( $this->getRequest()->response() );
+
+                                       // temporary measure the use of cookies on ip blocks
+                                       $stats = MediaWikiServices::getInstance()->getStatsdDataFactory();
+                                       $stats->increment( 'block.ipblock.setCookie.success' );
+                               }
+                       } elseif ( $this->isLoggedIn() && $config->get( 'CookieSetOnAutoblock' ) ) {
+                               $shouldSetCookie = $block->getType() === Block::TYPE_USER && $block->isAutoblocking();
+                               if ( $shouldSetCookie ) {
+                                       $block->setCookie( $this->getRequest()->response() );
+                               }
+                       }
+               }
+       }
+
        /**
         * Load user and user_group data from the database.
         * $this->mId must be set, this is how the user is identified.
@@ -1422,7 +1469,7 @@ class User implements IDBAccessObject, UserIdentity {
         * Initialize this object from a row from the user table.
         *
         * @param stdClass $row Row from the user table to load.
-        * @param array $data Further user data to load into the object
+        * @param array|null $data Further user data to load into the object
         *
         *  user_groups   Array of arrays or stdClass result rows out of the user_groups
         *                table. Previously you were supposed to pass an array of strings
@@ -1896,12 +1943,24 @@ class User implements IDBAccessObject, UserIdentity {
                        // An ID was found in the cookie.
                        $tmpBlock = Block::newFromID( $blockCookieId );
                        if ( $tmpBlock instanceof Block ) {
-                               // Check the validity of the block.
-                               $blockIsValid = $tmpBlock->getType() == Block::TYPE_USER
-                                       && !$tmpBlock->isExpired()
-                                       && $tmpBlock->isAutoblocking();
                                $config = RequestContext::getMain()->getConfig();
-                               $useBlockCookie = ( $config->get( 'CookieSetOnAutoblock' ) === true );
+
+                               switch ( $tmpBlock->getType() ) {
+                                       case Block::TYPE_USER:
+                                               $blockIsValid = !$tmpBlock->isExpired() && $tmpBlock->isAutoblocking();
+                                               $useBlockCookie = ( $config->get( 'CookieSetOnAutoblock' ) === true );
+                                               break;
+                                       case Block::TYPE_IP:
+                                       case Block::TYPE_RANGE:
+                                               // If block is type IP or IP range, load only if user is not logged in (T152462)
+                                               $blockIsValid = !$tmpBlock->isExpired() && !$this->isLoggedIn();
+                                               $useBlockCookie = ( $config->get( 'CookieSetOnIpBlock' ) === true );
+                                               break;
+                                       default:
+                                               $blockIsValid = false;
+                                               $useBlockCookie = false;
+                               }
+
                                if ( $blockIsValid && $useBlockCookie ) {
                                        // Use the block.
                                        return $tmpBlock;
@@ -2637,7 +2696,7 @@ class User implements IDBAccessObject, UserIdentity {
        /**
         * Update the 'You have new messages!' status.
         * @param bool $val Whether the user has new messages
-        * @param Revision $curRev New, as yet unseen revision of the user talk
+        * @param Revision|null $curRev New, as yet unseen revision of the user talk
         *   page. Ignored if null or !$val.
         */
        public function setNewtalk( $val, $curRev = null ) {
@@ -3078,7 +3137,7 @@ class User implements IDBAccessObject, UserIdentity {
         * Get the user's current setting for a given option.
         *
         * @param string $oname The option to check
-        * @param string|array $defaultOverride A default value returned if the option does not exist
+        * @param string|array|null $defaultOverride A default value returned if the option does not exist
         * @param bool $ignoreHidden Whether to ignore the effects of $wgHiddenPrefs
         * @return string|array|int|null User's current value for the option
         * @see getBoolOption()
@@ -3273,7 +3332,7 @@ class User implements IDBAccessObject, UserIdentity {
         *
         * @see User::listOptionKinds
         * @param IContextSource $context
-        * @param array $options Assoc. array with options keys to check as keys.
+        * @param array|null $options Assoc. array with options keys to check as keys.
         *   Defaults to $this->mOptions.
         * @return array The key => kind mapping data
         */
@@ -3301,7 +3360,7 @@ class User implements IDBAccessObject, UserIdentity {
                        if ( ( isset( $info['type'] ) && $info['type'] == 'multiselect' ) ||
                                        ( isset( $info['class'] ) && $info['class'] == HTMLMultiSelectField::class ) ) {
                                $opts = HTMLFormField::flattenOptions( $info['options'] );
-                               $prefix = isset( $info['prefix'] ) ? $info['prefix'] : $name;
+                               $prefix = $info['prefix'] ?? $name;
 
                                foreach ( $opts as $value ) {
                                        $multiselectOptions["$prefix$value"] = true;
@@ -3316,7 +3375,7 @@ class User implements IDBAccessObject, UserIdentity {
                                        ( isset( $info['class'] ) && $info['class'] == HTMLCheckMatrix::class ) ) {
                                $columns = HTMLFormField::flattenOptions( $info['columns'] );
                                $rows = HTMLFormField::flattenOptions( $info['rows'] );
-                               $prefix = isset( $info['prefix'] ) ? $info['prefix'] : $name;
+                               $prefix = $info['prefix'] ?? $name;
 
                                foreach ( $columns as $column ) {
                                        foreach ( $rows as $row ) {
@@ -3635,7 +3694,7 @@ class User implements IDBAccessObject, UserIdentity {
         * never expire.)
         *
         * @param string $group Name of the group to add
-        * @param string $expiry Optional expiry timestamp in any format acceptable to
+        * @param string|null $expiry Optional expiry timestamp in any format acceptable to
         *   wfTimestamp(), or null if the group assignment should not expire
         * @return bool
         */
@@ -4013,7 +4072,7 @@ class User implements IDBAccessObject, UserIdentity {
         *
         * @param WebRequest|null $request WebRequest object to use; $wgRequest will be used if null
         *        is passed.
-        * @param bool $secure Whether to force secure/insecure cookies or use default
+        * @param bool|null $secure Whether to force secure/insecure cookies or use default
         * @param bool $rememberMe Whether to add a Token cookie for elongated sessions
         */
        public function setCookies( $request = null, $secure = null, $rememberMe = false ) {
@@ -4562,7 +4621,7 @@ class User implements IDBAccessObject, UserIdentity {
         * @param string $val Input value to compare
         * @param string|array $salt Optional function-specific data for hashing
         * @param WebRequest|null $request Object to use or null to use $wgRequest
-        * @param int $maxage Fail tokens older than this, in seconds
+        * @param int|null $maxage Fail tokens older than this, in seconds
         * @return bool Whether the token matches
         */
        public function matchEditToken( $val, $salt = '', $request = null, $maxage = null ) {
@@ -4576,7 +4635,7 @@ class User implements IDBAccessObject, UserIdentity {
         * @param string $val Input value to compare
         * @param string|array $salt Optional function-specific data for hashing
         * @param WebRequest|null $request Object to use or null to use $wgRequest
-        * @param int $maxage Fail tokens older than this, in seconds
+        * @param int|null $maxage Fail tokens older than this, in seconds
         * @return bool Whether the token matches
         */
        public function matchEditTokenNoSuffix( $val, $salt = '', $request = null, $maxage = null ) {
@@ -4627,7 +4686,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 $replyto Reply-To address
+        * @param string|null $replyto Reply-To address
         * @return Status
         */
        public function sendMail( $subject, $body, $from = null, $replyto = null ) {
@@ -5014,10 +5073,10 @@ class User implements IDBAccessObject, UserIdentity {
         */
        public static function getAllGroups() {
                global $wgGroupPermissions, $wgRevokePermissions;
-               return array_diff(
+               return array_values( array_diff(
                        array_merge( array_keys( $wgGroupPermissions ), array_keys( $wgRevokePermissions ) ),
                        self::getImplicitGroups()
-               );
+               ) );
        }
 
        /**
@@ -5391,7 +5450,7 @@ class User implements IDBAccessObject, UserIdentity {
        /**
         * Load the user options either from cache, the database or an array
         *
-        * @param array $data Rows for the current user out of the user_properties table
+        * @param array|null $data Rows for the current user out of the user_properties table
         */
        protected function loadOptions( $data = null ) {
                global $wgContLang;
@@ -5451,18 +5510,17 @@ class User implements IDBAccessObject, UserIdentity {
                                }
                        }
 
-                       // Convert the email blacklist from a new line delimited string
-                       // to an array of ids.
-                       if ( isset( $data['email-blacklist'] ) && $data['email-blacklist'] ) {
-                               $data['email-blacklist'] = array_map( 'intval', explode( "\n", $data['email-blacklist'] ) );
-                       }
-
                        foreach ( $data as $property => $value ) {
                                $this->mOptionOverrides[$property] = $value;
                                $this->mOptions[$property] = $value;
                        }
                }
 
+               // Replace deprecated language codes
+               $this->mOptions['language'] = LanguageCode::replaceDeprecatedCodes(
+                       $this->mOptions['language']
+               );
+
                $this->mOptionsLoaded = true;
 
                Hooks::run( 'UserLoadOptions', [ $this, &$this->mOptions ] );
@@ -5479,26 +5537,6 @@ class User implements IDBAccessObject, UserIdentity {
                // Not using getOptions(), to keep hidden preferences in database
                $saveOptions = $this->mOptions;
 
-               // Convert usernames to ids.
-               if ( isset( $this->mOptions['email-blacklist'] ) ) {
-                       if ( $this->mOptions['email-blacklist'] ) {
-                               $value = $this->mOptions['email-blacklist'];
-                               // Email Blacklist may be an array of ids or a string of new line
-                               // delimnated user names.
-                               if ( is_array( $value ) ) {
-                                       $ids = array_filter( $value, 'is_numeric' );
-                               } else {
-                                       $lookup = CentralIdLookup::factory();
-                                       $ids = $lookup->centralIdsFromNames( explode( "\n", $value ), $this );
-                               }
-                               $this->mOptions['email-blacklist'] = $ids;
-                               $saveOptions['email-blacklist'] = implode( "\n", $this->mOptions['email-blacklist'] );
-                       } else {
-                               // If the blacklist is empty, set it to null rather than an empty string.
-                               $this->mOptions['email-blacklist'] = null;
-                       }
-               }
-
                // Allow hooks to abort, for instance to save to a global profile.
                // Reset options to default state before saving.
                if ( !Hooks::run( 'UserSaveOptions', [ $this, &$saveOptions ] ) ) {
index 89cdc5f..cf985cb 100644 (file)
@@ -46,7 +46,7 @@ class UserGroupMembership {
 
        /**
         * @param int $userId The ID of the user who belongs to the group
-        * @param string $group The internal group name
+        * @param string|null $group The internal group name
         * @param string|null $expiry Timestamp of expiry in TS_MW format, or null if no expiry
         */
        public function __construct( $userId = 0, $group = null, $expiry = null ) {
index 98d2c0e..b437653 100644 (file)
@@ -389,7 +389,7 @@ class ClassCollector {
                        return;
                }
                // Note: When changing class name discovery logic,
-               // AutoLoaderTest.php may also need to be updated.
+               // AutoLoaderStructureTest.php may also need to be updated.
                switch ( $token[0] ) {
                        case T_NAMESPACE:
                        case T_CLASS:
index 5818958..0fc45f7 100644 (file)
@@ -28,6 +28,7 @@ use MediaWiki\MediaWikiServices;
 
 class MWCryptRand {
        /**
+        * @deprecated since 1.32
         * @return CryptRand
         */
        protected static function singleton() {
@@ -39,41 +40,49 @@ class MWCryptRand {
         * random bytes generation in the previously run generate* call
         * was cryptographically strong.
         *
-        * @return bool Returns true if the source was strong, false if not.
+        * @deprecated since 1.32, always returns true
+        *
+        * @return bool Always true
         */
        public static function wasStrong() {
-               return self::singleton()->wasStrong();
+               return true;
        }
 
        /**
-        * Generate a run of (ideally) cryptographically random data and return
+        * Generate a run of cryptographically random data and return
         * it in raw binary form.
-        * You can use MWCryptRand::wasStrong() if you wish to know if the source used
-        * was cryptographically strong.
+        *
+        * @deprecated since 1.32, use random_bytes()
         *
         * @param int $bytes The number of bytes of random data to generate
-        * @param bool $forceStrong Pass true if you want generate to prefer cryptographically
-        *                          strong sources of entropy even if reading from them may steal
-        *                          more entropy from the system than optimal.
         * @return string Raw binary random data
         */
-       public static function generate( $bytes, $forceStrong = false ) {
-               return self::singleton()->generate( $bytes, $forceStrong );
+       public static function generate( $bytes ) {
+               return random_bytes( floor( $bytes ) );
        }
 
        /**
-        * Generate a run of (ideally) cryptographically random data and return
+        * Generate a run of cryptographically random data and return
         * it in hexadecimal string format.
-        * You can use MWCryptRand::wasStrong() if you wish to know if the source used
-        * was cryptographically strong.
         *
         * @param int $chars The number of hex chars of random data to generate
-        * @param bool $forceStrong Pass true if you want generate to prefer cryptographically
-        *                          strong sources of entropy even if reading from them may steal
-        *                          more entropy from the system than optimal.
         * @return string Hexadecimal random data
         */
-       public static function generateHex( $chars, $forceStrong = false ) {
-               return self::singleton()->generateHex( $chars, $forceStrong );
+       public static function generateHex( $chars ) {
+               // hex strings are 2x the length of raw binary so we divide the length in half
+               // odd numbers will result in a .5 that leads the generate() being 1 character
+               // short, so we use ceil() to ensure that we always have enough bytes
+               $bytes = ceil( $chars / 2 );
+               // Generate the data and then convert it to a hex string
+               $hex = bin2hex( random_bytes( $bytes ) );
+
+               // A bit of paranoia here, the caller asked for a specific length of string
+               // here, and it's possible (eg when given an odd number) that we may actually
+               // have at least 1 char more than they asked for. Just in case they made this
+               // call intending to insert it into a database that does truncation we don't
+               // want to give them too much and end up with their database and their live
+               // code having two different values because part of what we gave them is truncated
+               // hence, we strip out any run of characters longer than what we were asked for.
+               return substr( $hex, 0, $chars );
        }
 }
index caf88a1..d4f1a92 100644 (file)
@@ -26,7 +26,7 @@ class MWRestrictions {
        private $ipAddresses = [ '0.0.0.0/0', '::/0' ];
 
        /**
-        * @param array $restrictions
+        * @param array|null $restrictions
         * @throws InvalidArgumentException
         */
        protected function __construct( array $restrictions = null ) {
index 4d5c3af..d184e92 100644 (file)
@@ -84,7 +84,7 @@ class UIDGenerator {
        }
 
        /**
-        * @todo: move to MW-specific factory class and inject temp dir
+        * @todo move to MW-specific factory class and inject temp dir
         * @return UIDGenerator
         */
        protected static function singleton() {
@@ -400,14 +400,14 @@ class UIDGenerator {
                        // Write back the new counter value
                        ftruncate( $handle, 0 );
                        rewind( $handle );
-                       fwrite( $handle, fmod( $counter, pow( 2, 48 ) ) ); // warp-around as needed
+                       fwrite( $handle, fmod( $counter, 2 ** 48 ) ); // warp-around as needed
                        fflush( $handle );
                        // Release the UID lock file
                        flock( $handle, LOCK_UN );
                }
 
                $ids = [];
-               $divisor = pow( 2, $bits );
+               $divisor = 2 ** $bits;
                $currentId = floor( $counter - $count ); // pre-increment counter value
                for ( $i = 0; $i < $count; ++$i ) {
                        $ids[] = fmod( ++$currentId, $divisor );
@@ -532,7 +532,7 @@ class UIDGenerator {
        protected function millisecondsSinceEpochBinary( array $time ) {
                list( $sec, $msec ) = $time;
                $ts = 1000 * $sec + $msec;
-               if ( $ts > pow( 2, 52 ) ) {
+               if ( $ts > 2 ** 52 ) {
                        throw new RuntimeException( __METHOD__ .
                                ': sorry, this function doesn\'t work after the year 144680' );
                }
@@ -551,7 +551,7 @@ class UIDGenerator {
                $offset = '122192928000000000';
                if ( PHP_INT_SIZE >= 8 ) { // 64 bit integers
                        $ts = ( 1000 * $sec + $msec ) * 10000 + (int)$offset + $delta;
-                       $id_bin = str_pad( decbin( $ts % pow( 2, 60 ) ), 60, '0', STR_PAD_LEFT );
+                       $id_bin = str_pad( decbin( $ts % ( 2 ** 60 ) ), 60, '0', STR_PAD_LEFT );
                } elseif ( extension_loaded( 'gmp' ) ) {
                        $ts = gmp_add( gmp_mul( (string)$sec, '1000' ), (string)$msec ); // ms
                        $ts = gmp_add( gmp_mul( $ts, '10000' ), $offset ); // 100ns intervals
index f0ace2c..46f3bbc 100644 (file)
@@ -511,7 +511,7 @@ class ZipDirectoryReader {
         * in the file to satisfy the request, an exception will be thrown.
         *
         * @param int $start The byte offset of the start of the block.
-        * @param int $length The number of bytes to return. If omitted, the remainder
+        * @param int|null $length The number of bytes to return. If omitted, the remainder
         *    of the file will be returned.
         *
         * @return string
@@ -656,7 +656,7 @@ class ZipDirectoryReader {
                                }
 
                                // Throw an exception if there was loss of precision
-                               if ( $value > pow( 2, 52 ) ) {
+                               if ( $value > 2 ** 52 ) {
                                        $this->error( 'zip-unsupported', 'number too large to be stored in a double. ' .
                                                'This could happen if we tried to unpack a 64-bit structure ' .
                                                'at an invalid location.' );
index 506ee00..17d9b91 100644 (file)
@@ -13,7 +13,7 @@ use Wikimedia\Rdbms\LoadBalancer;
  * @file
  * @ingroup Watchlist
  *
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
  */
 class WatchedItemQueryService {
 
@@ -220,7 +220,7 @@ class WatchedItemQueryService {
                        $joinConds
                );
 
-               $limit = isset( $dbOptions['LIMIT'] ) ? $dbOptions['LIMIT'] : INF;
+               $limit = $dbOptions['LIMIT'] ?? INF;
                $items = [];
                $startFrom = null;
                foreach ( $res as $row ) {
@@ -320,8 +320,8 @@ class WatchedItemQueryService {
        }
 
        private function getRecentChangeFieldsFromRow( stdClass $row ) {
-               // This can be simplified to single array_filter call filtering by key value,
-               // once we stop supporting PHP 5.5
+               // FIXME: This can be simplified to single array_filter call filtering by key value,
+               // now we have stopped supporting PHP 5.5
                $allFields = get_object_vars( $row );
                $rcKeys = array_filter(
                        array_keys( $allFields ),
index 93d5033..873ae2d 100644 (file)
@@ -11,7 +11,7 @@ use Wikimedia\Rdbms\IDatabase;
  * @file
  * @ingroup Watchlist
  *
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
  */
 interface WatchedItemQueryServiceExtension {
 
index 30d1cbb..99a051d 100644 (file)
@@ -264,7 +264,7 @@ interface WatchedItemStoreInterface {
         * @since 1.31
         *
         * @param User $user
-        * @param int $unreadLimit
+        * @param int|null $unreadLimit
         *
         * @return int|bool The number of unread notifications
         *                  true if greater than or equal to $unreadLimit
index ca6c848..392e46d 100644 (file)
@@ -40,9 +40,7 @@ class ComplexTitleInputWidget extends \OOUI\Widget {
                        $config['title'],
                        [
                                'relative' => true,
-                               'namespace' => isset( $config['namespace']['value'] ) ?
-                                       $config['namespace']['value'] :
-                                       null,
+                               'namespace' => $config['namespace']['value'] ?? null,
                        ]
                ) );
 
index 7395df1..f9985eb 100644 (file)
@@ -42,7 +42,7 @@ class ExpiryInputWidget extends Widget {
                parent::__construct( $options );
 
                $this->noDatePicker = $options['noDatePicker'];
-               $this->required = isset( $options['required'] ) ? $options['required'] : false;
+               $this->required = $options['required'] ?? false;
 
                // Properties
                $this->relativeInput = $relativeInput;
index 0840886..7802a2a 100644 (file)
@@ -25,8 +25,8 @@ class NamespaceInputWidget extends \OOUI\DropdownInputWidget {
                parent::__construct( $config );
 
                // Properties
-               $this->includeAllValue = isset( $config['includeAllValue'] ) ? $config['includeAllValue'] : null;
-               $this->exclude = isset( $config['exclude'] ) ? $config['exclude'] : [];
+               $this->includeAllValue = $config['includeAllValue'] ?? null;
+               $this->exclude = $config['exclude'] ?? [];
 
                // Initialization
                $this->addClasses( [ 'mw-widget-namespaceInputWidget' ] );
@@ -34,8 +34,8 @@ class NamespaceInputWidget extends \OOUI\DropdownInputWidget {
 
        protected function getNamespaceDropdownOptions( array $config ) {
                $namespaceOptionsParams = [
-                       'all' => isset( $config['includeAllValue'] ) ? $config['includeAllValue'] : null,
-                       'exclude' => isset( $config['exclude'] ) ? $config['exclude'] : null
+                       'all' => $config['includeAllValue'] ?? null,
+                       'exclude' => $config['exclude'] ?? null
                ];
                $namespaceOptions = \Html::namespaceSelectorOptions( $namespaceOptionsParams );
 
index 5ceed4c..262903d 100644 (file)
@@ -36,6 +36,11 @@ class SelectWithInputWidget extends \OOUI\Widget {
                        $config
                );
 
+               if ( isset( $config['disabled'] ) && $config['disabled'] == true ) {
+                       $config['textinput']['disabled'] = true;
+                       $config['dropdowninput']['disabled'] = true;
+               }
+
                parent::__construct( $config );
 
                // Properties
index c4d1dfc..18c05bf 100644 (file)
@@ -10,7 +10,7 @@ use \OOUI\LabelWidget;
  * Select and input widget.
  *
  * @copyright 2011-2018 MediaWiki Widgets Team and others; see AUTHORS.txt
- * @license The MIT License (MIT); see LICENSE.txt
+ * @license MIT
  */
 class SizeFilterWidget extends \OOUI\Widget {
 
index 68cdad6..aaa46ae 100644 (file)
@@ -39,7 +39,7 @@ class UsersMultiselectWidget extends \OOUI\Widget {
                $textarea = new MultilineTextInputWidget( [
                        'name' => $this->inputName,
                        'value' => implode( "\n", $this->usersArray ),
-                       'rows' => 25,
+                       'rows' => 10,
                ] );
                $this->prependContent( $textarea );
        }
index e236640..8521e68 100644 (file)
@@ -123,10 +123,8 @@ class BasicSearchResultSetWidget {
                $terms = $wgContLang->convertForSearchResult( $resultSet->termMatches() );
 
                $hits = [];
-               $result = $resultSet->next();
-               while ( $result ) {
-                       $hits[] .= $this->resultWidget->render( $result, $terms, $offset++ );
-                       $result = $resultSet->next();
+               foreach ( $resultSet as $result ) {
+                       $hits[] = $this->resultWidget->render( $result, $terms, $offset++ );
                }
 
                return "<ul class='mw-search-results'>" . implode( '', $hits ) . "</ul>";
index 2c88563..2302177 100644 (file)
@@ -100,6 +100,10 @@ class SearchFormWidget {
 
                $html .= $layout;
 
+               if ( $this->specialSearch->getPrefix() !== '' ) {
+                       $html .= Html::hidden( 'prefix', $this->specialSearch->getPrefix() );
+               }
+
                if ( $totalResults > 0 && $offset < $totalResults ) {
                        $html .= Xml::tags(
                                'div',
@@ -270,7 +274,7 @@ class SearchFormWidget {
                $showSections = [
                        'namespaceTables' => "<table>" . implode( '</table><table>', $namespaceTables ) . '</table>',
                ];
-               Hooks::run( 'SpecialSearchPowerBox', [ &$showSections, $term, $opts ] );
+               Hooks::run( 'SpecialSearchPowerBox', [ &$showSections, $term, &$opts ] );
 
                $hidden = '';
                foreach ( $opts as $key => $value ) {
index d0c259f..248099a 100644 (file)
@@ -56,12 +56,10 @@ class SimpleSearchResultSetWidget implements SearchResultSetWidget {
 
                $iwResults = [];
                foreach ( $resultSets as $resultSet ) {
-                       $result = $resultSet->next();
-                       while ( $result ) {
+                       foreach ( $resultSet as $result ) {
                                if ( !$result->isBrokenTitle() ) {
                                        $iwResults[$result->getTitle()->getInterwiki()][] = $result;
                                }
-                               $result = $resultSet->next();
                        }
                }
 
index e61303d..28473aa 100644 (file)
@@ -19,7 +19,7 @@
                "resources/src/mediawiki.legacy",
                "resources/src/mediawiki.libs.jpegmeta/jpegmeta.js",
                "resources/src/mediawiki.skinning",
-               "resources/src/startup.js"
+               "resources/src/startup/startup.js"
        ],
        "--": [
                "maintenance/jsduck/external.js",
index 8dfe00f..dc61519 100644 (file)
@@ -330,7 +330,7 @@ class ConverterRule {
 
        /**
         * Parse rules and flags.
-        * @param string $variant Variant language code
+        * @param string|null $variant Variant language code
         */
        public function parse( $variant = null ) {
                if ( !$variant ) {
index be0c037..7f04a68 100644 (file)
@@ -154,9 +154,9 @@ class Language {
        /**
         * Unicode directional formatting characters, for embedBidi()
         */
-       static private $lre = "\xE2\x80\xAA"; // U+202A LEFT-TO-RIGHT EMBEDDING
-       static private $rle = "\xE2\x80\xAB"; // U+202B RIGHT-TO-LEFT EMBEDDING
-       static private $pdf = "\xE2\x80\xAC"; // U+202C POP DIRECTIONAL FORMATTING
+       static private $lre = "\u{202A}"; // U+202A LEFT-TO-RIGHT EMBEDDING
+       static private $rle = "\u{202B}"; // U+202B RIGHT-TO-LEFT EMBEDDING
+       static private $pdf = "\u{202C}"; // U+202C POP DIRECTIONAL FORMATTING
 
        /**
         * Directionality test regex for embedBidi(). Matches the first strong directionality codepoint:
@@ -188,9 +188,7 @@ class Language {
                }
 
                // get the language object to process
-               $langObj = isset( self::$mLangObjCache[$code] )
-                       ? self::$mLangObjCache[$code]
-                       : self::newFromCode( $code );
+               $langObj = self::$mLangObjCache[$code] ?? self::newFromCode( $code );
 
                // merge the language object in to get it up front in the cache
                self::$mLangObjCache = array_merge( [ $code => $langObj ], self::$mLangObjCache );
@@ -222,7 +220,8 @@ class Language {
 
                // Check if there is a language class for the code
                $class = self::classFromCode( $code, $fallback );
-               if ( class_exists( $class ) ) {
+               // LanguageCode does not inherit Language
+               if ( class_exists( $class ) && is_a( $class, 'Language', true ) ) {
                        $lang = new $class;
                        return $lang;
                }
@@ -542,7 +541,7 @@ class Language {
         */
        public function getNsText( $index ) {
                $ns = $this->getNamespaces();
-               return isset( $ns[$index] ) ? $ns[$index] : false;
+               return $ns[$index] ?? false;
        }
 
        /**
@@ -577,7 +576,7 @@ class Language {
                $ns = $wgExtraGenderNamespaces +
                        (array)self::$dataCache->getItem( $this->mCode, 'namespaceGenderAliases' );
 
-               return isset( $ns[$index][$gender] ) ? $ns[$index][$gender] : $this->getNsText( $index );
+               return $ns[$index][$gender] ?? $this->getNsText( $index );
        }
 
        /**
@@ -613,7 +612,7 @@ class Language {
        function getLocalNsIndex( $text ) {
                $lctext = $this->lc( $text );
                $ids = $this->getNamespaceIds();
-               return isset( $ids[$lctext] ) ? $ids[$lctext] : false;
+               return $ids[$lctext] ?? false;
        }
 
        /**
@@ -700,7 +699,7 @@ class Language {
                        return $ns;
                }
                $ids = $this->getNamespaceIds();
-               return isset( $ids[$lctext] ) ? $ids[$lctext] : false;
+               return $ids[$lctext] ?? false;
        }
 
        /**
@@ -1091,7 +1090,7 @@ class Language {
         * @param string $ts 14-character timestamp
         *      YYYYMMDDHHMMSS
         *      01234567890123
-        * @param DateTimeZone $zone Timezone of $ts
+        * @param DateTimeZone|null $zone Timezone of $ts
         * @param int &$ttl The amount of time (in seconds) the output may be cached for.
         * Only makes sense if $ts is the current time.
         * @todo handling of "o" format character for Iranian, Hebrew, Hijri & Thai?
@@ -1884,6 +1883,14 @@ class Language {
                        # Add 543 years to the Gregorian calendar
                        # Months and days are identical
                        $gy_offset = $gy + 543;
+                       # fix for dates between 1912 and 1941
+                       # https://en.wikipedia.org/?oldid=836596673#New_year
+                       if ( $gy >= 1912 && $gy <= 1940 ) {
+                               if ( $gm <= 3 ) {
+                                       $gy_offset--;
+                               }
+                               $gm = ( $gm - 3 ) % 12;
+                       }
                } elseif ( ( !strcmp( $cName, 'minguo' ) ) || !strcmp( $cName, 'juche' ) ) {
                        # Minguo dates
                        # Deduct 1911 years from the Gregorian calendar
@@ -2917,33 +2924,33 @@ class Language {
                        if ( $code < 0xac00 || 0xd7a4 <= $code ) {
                                return $matches[1];
                        } elseif ( $code < 0xb098 ) {
-                               return "\xe3\x84\xb1";
+                               return "\u{3131}";
                        } elseif ( $code < 0xb2e4 ) {
-                               return "\xe3\x84\xb4";
+                               return "\u{3134}";
                        } elseif ( $code < 0xb77c ) {
-                               return "\xe3\x84\xb7";
+                               return "\u{3137}";
                        } elseif ( $code < 0xb9c8 ) {
-                               return "\xe3\x84\xb9";
+                               return "\u{3139}";
                        } elseif ( $code < 0xbc14 ) {
-                               return "\xe3\x85\x81";
+                               return "\u{3141}";
                        } elseif ( $code < 0xc0ac ) {
-                               return "\xe3\x85\x82";
+                               return "\u{3142}";
                        } elseif ( $code < 0xc544 ) {
-                               return "\xe3\x85\x85";
+                               return "\u{3145}";
                        } elseif ( $code < 0xc790 ) {
-                               return "\xe3\x85\x87";
+                               return "\u{3147}";
                        } elseif ( $code < 0xcc28 ) {
-                               return "\xe3\x85\x88";
+                               return "\u{3148}";
                        } elseif ( $code < 0xce74 ) {
-                               return "\xe3\x85\x8a";
+                               return "\u{314A}";
                        } elseif ( $code < 0xd0c0 ) {
-                               return "\xe3\x85\x8b";
+                               return "\u{314B}";
                        } elseif ( $code < 0xd30c ) {
-                               return "\xe3\x85\x8c";
+                               return "\u{314C}";
                        } elseif ( $code < 0xd558 ) {
-                               return "\xe3\x85\x8d";
+                               return "\u{314D}";
                        } else {
-                               return "\xe3\x85\x8e";
+                               return "\u{314E}";
                        }
                } else {
                        return '';
@@ -2954,6 +2961,7 @@ class Language {
         * @deprecated No-op since 1.28
         */
        function initEncoding() {
+               wfDeprecated( __METHOD__, '1.28' );
                // No-op.
        }
 
@@ -2963,6 +2971,7 @@ class Language {
         * @deprecated No-op since 1.28
         */
        function recodeForEdit( $s ) {
+               wfDeprecated( __METHOD__, '1.28' );
                return $s;
        }
 
@@ -2972,6 +2981,7 @@ class Language {
         * @deprecated No-op since 1.28
         */
        function recodeInput( $s ) {
+               wfDeprecated( __METHOD__, '1.28' );
                return $s;
        }
 
@@ -2990,8 +3000,8 @@ class Language {
                global $wgAllUnicodeFixes;
                $s = UtfNormal\Validator::cleanUp( $s );
                if ( $wgAllUnicodeFixes ) {
-                       $s = $this->transformUsingPairFile( 'normalize-ar.ser', $s );
-                       $s = $this->transformUsingPairFile( 'normalize-ml.ser', $s );
+                       $s = $this->transformUsingPairFile( 'normalize-ar.php', $s );
+                       $s = $this->transformUsingPairFile( 'normalize-ml.php', $s );
                }
 
                return $s;
@@ -3011,12 +3021,10 @@ class Language {
         * @throws MWException
         * @return string
         */
-       function transformUsingPairFile( $file, $string ) {
+       protected function transformUsingPairFile( $file, $string ) {
                if ( !isset( $this->transformData[$file] ) ) {
-                       $data = wfGetPrecompiledData( $file );
-                       if ( $data === false ) {
-                               throw new MWException( __METHOD__ . ": The transformation file $file is missing" );
-                       }
+                       global $IP;
+                       $data = require "$IP/languages/data/{$file}";
                        $this->transformData[$file] = new ReplacementArray( $data );
                }
                return $this->transformData[$file]->replace( $string );
@@ -3092,8 +3100,8 @@ class Language {
         * @return string
         */
        function getDirMark( $opposite = false ) {
-               $lrm = "\xE2\x80\x8E"; # LEFT-TO-RIGHT MARK, commonly abbreviated LRM
-               $rlm = "\xE2\x80\x8F"; # RIGHT-TO-LEFT MARK, commonly abbreviated RLM
+               $lrm = "\u{200E}"; # LEFT-TO-RIGHT MARK, commonly abbreviated LRM
+               $rlm = "\u{200F}"; # RIGHT-TO-LEFT MARK, commonly abbreviated RLM
                if ( $opposite ) {
                        return $this->isRTL() ? $lrm : $rlm;
                }
@@ -3156,7 +3164,7 @@ class Language {
                        return;
                }
                $this->mMagicHookDone = true;
-               Hooks::run( 'LanguageGetMagic', [ &$this->mMagicExtensions, $this->getCode() ] );
+               Hooks::run( 'LanguageGetMagic', [ &$this->mMagicExtensions, $this->getCode() ], '1.16' );
        }
 
        /**
@@ -3212,7 +3220,7 @@ class Language {
                        $this->mExtendedSpecialPageAliases =
                                self::$dataCache->getItem( $this->mCode, 'specialPageAliases' );
                        Hooks::run( 'LanguageGetSpecialPageAliases',
-                               [ &$this->mExtendedSpecialPageAliases, $this->getCode() ] );
+                               [ &$this->mExtendedSpecialPageAliases, $this->getCode() ], '1.16' );
                }
 
                return $this->mExtendedSpecialPageAliases;
@@ -3405,32 +3413,26 @@ class Language {
         * Take a list of strings and build a locale-friendly comma-separated
         * list, using the local comma-separator message.
         * The last two strings are chained with an "and".
-        * NOTE: This function will only work with standard numeric array keys (0, 1, 2…)
         *
-        * @param string[] $l
+        * @param string[] $list
         * @return string
         */
-       function listToText( array $l ) {
-               $m = count( $l ) - 1;
-               if ( $m < 0 ) {
+       public function listToText( array $list ) {
+               $itemCount = count( $list );
+               if ( $itemCount < 1 ) {
                        return '';
                }
-               if ( $m > 0 ) {
+               $text = array_pop( $list );
+               if ( $itemCount > 1 ) {
                        $and = $this->msg( 'and' )->escaped();
                        $space = $this->msg( 'word-separator' )->escaped();
-                       if ( $m > 1 ) {
+                       $comma = '';
+                       if ( $itemCount > 2 ) {
                                $comma = $this->msg( 'comma-separator' )->escaped();
                        }
+                       $text = implode( $comma, $list ) . $and . $space . $text;
                }
-               $s = $l[$m];
-               for ( $i = $m - 1; $i >= 0; $i-- ) {
-                       if ( $i == $m - 1 ) {
-                               $s = $l[$i] . $and . $space . $s;
-                       } else {
-                               $s = $l[$i] . $comma . $s;
-                       }
-               }
-               return $s;
+               return $text;
        }
 
        /**
@@ -3489,6 +3491,7 @@ class Language {
         * @return string
         */
        function truncate( $string, $length, $ellipsis = '...', $adjustLength = true ) {
+               wfDeprecated( __METHOD__, '1.31' );
                return $this->truncateForDatabase( $string, $length, $ellipsis, $adjustLength );
        }
 
@@ -3558,7 +3561,7 @@ class Language {
         * @return string
         */
        private function truncateInternal(
-               $string, $length, $ellipsis = '...', $adjustLength = true, $measureLength, $getSubstring
+               $string, $length, $ellipsis, $adjustLength, $measureLength, $getSubstring
        ) {
                if ( !is_callable( $measureLength ) || !is_callable( $getSubstring ) ) {
                        throw new InvalidArgumentException( 'Invalid callback provided' );
@@ -3962,7 +3965,7 @@ class Language {
                if ( $gender === 'female' ) {
                        return $forms[1];
                }
-               return isset( $forms[2] ) ? $forms[2] : $forms[0];
+               return $forms[2] ?? $forms[0];
        }
 
        /**
@@ -4076,7 +4079,7 @@ class Language {
         * match up with it.
         *
         * @param string $str The validated block duration in English
-        * @param User $user User object to use timezone from or null for $wgUser
+        * @param User|null $user User object to use timezone from or null for $wgUser
         * @param int $now Current timestamp, for formatting relative block durations
         * @return string Somehow translated block duration
         * @see LanguageFi.php for example implementation
@@ -4325,13 +4328,18 @@ class Language {
         * the "raw" tag (-{R| }-) to prevent conversion.
         *
         * This function is called "markNoConversion" for historical
-        * reasons.
+        * 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 );
@@ -4395,7 +4403,7 @@ class Language {
         * @return bool
         */
        public function equals( Language $lang ) {
-               return $lang->getCode() === $this->mCode;
+               return $lang === $this || $lang->getCode() === $this->mCode;
        }
 
        /**
@@ -4475,7 +4483,7 @@ class Language {
         * @throws MWException
         * @return string $prefix . $mangledCode . $suffix
         */
-       public static function getFileName( $prefix = 'Language', $code, $suffix = '.php' ) {
+       public static function getFileName( $prefix, $code, $suffix = '.php' ) {
                if ( !self::isValidBuiltInCode( $code ) ) {
                        throw new MWException( "Invalid language code \"$code\"" );
                }
index d11838a..dcc2cf3 100644 (file)
@@ -211,7 +211,7 @@ class LanguageConverter {
 
        /**
         * Validate the variant
-        * @param string $variant The variant to validate
+        * @param string|null $variant The variant to validate
         * @return mixed Returns the variant if it is valid, null otherwise
         */
        public function validateVariant( $variant = null ) {
@@ -224,7 +224,7 @@ class LanguageConverter {
        /**
         * Get the variant specified in the URL
         *
-        * @return mixed Variant if one found, false otherwise.
+        * @return mixed Variant if one found, null otherwise
         */
        public function getURLVariant() {
                global $wgRequest;
@@ -247,7 +247,7 @@ class LanguageConverter {
        /**
         * Determine if the user has a variant set.
         *
-        * @return mixed Variant if one found, false otherwise.
+        * @return mixed Variant if one found, null otherwise
         */
        protected function getUserVariant() {
                global $wgUser, $wgContLang;
@@ -284,7 +284,7 @@ class LanguageConverter {
        /**
         * Determine the language variant from the Accept-Language header.
         *
-        * @return mixed Variant if one found, false otherwise.
+        * @return mixed Variant if one found, null otherwise
         */
        protected function getHeaderVariant() {
                global $wgRequest;
index 90e3751..efdf5a2 100644 (file)
@@ -44,7 +44,7 @@ class LanguageAr extends Language {
                global $wgFixArabicUnicode;
                $s = parent::normalize( $s );
                if ( $wgFixArabicUnicode ) {
-                       $s = $this->transformUsingPairFile( 'normalize-ar.ser', $s );
+                       $s = $this->transformUsingPairFile( 'normalize-ar.php', $s );
                }
                return $s;
        }
index 1f9b767..07005d4 100644 (file)
@@ -19,8 +19,8 @@
  *
  * @file
  * @author Ævar Arnfjörð Bjarmason <avarab@gmail.com>
- * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License
- * @license http://www.gnu.org/copyleft/fdl.html GNU Free Documentation License
+ * @license GPL-2.0-or-later
+ * @license GFDL-1.3-or-later
  * @ingroup Language
  */
 
index 6d603f5..b838d06 100644 (file)
@@ -43,28 +43,28 @@ class EnConverter extends LanguageConverter {
         * @return string
         */
        function translate( $text, $toVariant ) {
-               if ( $toVariant === 'en-x-piglatin' ) {
-                       // Only process words composed of standard English alphabet, leave the rest unchanged.
-                       // This skips some English words like 'naïve' or 'résumé', but we can live with that.
-                       // Ignore single letters and words which aren't lowercase or uppercase-first.
-                       return preg_replace_callback( '/[A-Za-z][a-z\']+/', function ( $matches ) {
-                               $word = $matches[0];
-                               if ( preg_match( '/^[aeiou]/i', $word ) ) {
-                                       return $word . 'way';
-                               } else {
-                                       return preg_replace_callback( '/^(s?qu|[^aeiou][^aeiouy]*)(.*)$/i', function ( $m ) {
-                                               $ucfirst = strtoupper( $m[1][0] ) === $m[1][0];
-                                               if ( $ucfirst ) {
-                                                       return ucfirst( $m[2] ) . lcfirst( $m[1] ) . 'ay';
-                                               } else {
-                                                       return $m[2] . $m[1] . 'ay';
-                                               }
-                                       }, $word );
-                               }
-                       }, $text );
-               } else {
+               if ( $toVariant !== 'en-x-piglatin' ) {
                        return $text;
                }
+
+               // Only process words composed of standard English alphabet, leave the rest unchanged.
+               // This skips some English words like 'naïve' or 'résumé', but we can live with that.
+               // Ignore single letters and words which aren't lowercase or uppercase-first.
+               return preg_replace_callback( '/[A-Za-z][a-z\']+/', function ( $matches ) {
+                       $word = $matches[0];
+                       if ( preg_match( '/^[aeiou]/i', $word ) ) {
+                               return $word . 'way';
+                       }
+
+                       return preg_replace_callback( '/^(s?qu|[^aeiou][^aeiouy]*)(.*)$/i', function ( $m ) {
+                               $ucfirst = strtoupper( $m[1][0] ) === $m[1][0];
+                               if ( $ucfirst ) {
+                                       return ucfirst( $m[2] ) . lcfirst( $m[1] ) . 'ay';
+                               }
+
+                               return $m[2] . $m[1] . 'ay';
+                       }, $word );
+               }, $text );
        }
 }
 
@@ -75,13 +75,12 @@ class EnConverter extends LanguageConverter {
  */
 class LanguageEn extends Language {
        function __construct() {
-               global $wgUsePigLatinVariant, $wgHooks;
+               global $wgUsePigLatinVariant;
 
                parent::__construct();
 
                if ( $wgUsePigLatinVariant ) {
                        $this->mConverter = new EnConverter( $this, 'en', [ 'en', 'en-x-piglatin' ] );
-                       $wgHooks['PageContentSaveComplete'][] = $this->mConverter;
                }
        }
 }
index 54ff421..b2bae18 100644 (file)
@@ -84,7 +84,7 @@ class LanguageFi extends Language {
 
        /**
         * @param string $str
-        * @param User $user User object to use timezone from or null for $wgUser
+        * @param User|null $user User object to use timezone from or null for $wgUser
         * @param int $now Current timestamp, for formatting relative block durations
         * @return string
         */
index df894a1..cf45762 100644 (file)
@@ -45,7 +45,7 @@ class LanguageMl extends Language {
                global $wgFixMalayalamUnicode;
                $s = parent::normalize( $s );
                if ( $wgFixMalayalamUnicode ) {
-                       $s = $this->transformUsingPairFile( 'normalize-ml.ser', $s );
+                       $s = $this->transformUsingPairFile( 'normalize-ml.php', $s );
                }
                return $s;
        }
index c759220..fcba6dc 100644 (file)
@@ -126,7 +126,6 @@ class CrhExceptions {
                'beyude' => 'бейуде', 'beyüde' => 'бейуде',
                'curat' => 'джурьат', 'cürat' => 'джурьат',
                'mesul' => 'месуль', 'mesül' => 'месуль',
-               'yetsin' => 'етсин', 'etsin' => 'етсин',
        ];
 
        # map Cyrillic to Latin and back, simple string match only (no regex)
@@ -367,7 +366,7 @@ class CrhExceptions {
                'козь' => 'köz', '-юнджи' => '-ünci', '-юнджиде' => '-üncide', '-юнджиден' => '-ünciden',
 
                # originally L2C, here swapped
-               'еÑ\82Ñ\81ин' => 'etsin', 'лÑ\8cнаÑ\8f' => 'lnaya', 'лÑ\8cное' => 'lnoye', 'лÑ\8cнÑ\8bй' => 'lnıy', 'лÑ\8cний' => 'lniy',
+               'льная' => 'lnaya', 'льное' => 'lnoye', 'льный' => 'lnıy', 'льний' => 'lniy',
                'льская' => 'lskaya', 'льский' => 'lskiy', 'льское' => 'lskoye', 'ополь' => 'opol',
                'щее' => 'şçeye', 'щий' => 'şçiy', 'щая' => 'şçaya', 'цепс' => 'tseps',
 
@@ -389,8 +388,8 @@ class CrhExceptions {
                'му([иэИЭ])' => 'mü$1',
 
                # originally L2C, here swapped
-               'роль$1' => 'rol([^ü])',
-               'усть$1' => 'üst([^ü])',
+               'роль$1' => 'rol([^ü]|'.self::WB.')',
+               'усть$1' => 'üst([^ü]|'.self::WB.')',
 
                # more prefixes
                'ком-кок' => 'köm-kök',
@@ -460,6 +459,10 @@ class CrhExceptions {
                        '/'.self::WB.'Джонкю'.self::WB.'/u' => 'Cönkü',
                        '/'.self::WB.'ДЖОНКЮ'.self::WB.'/u' => 'CÖNKÜ',
 
+                       '/'.self::WB.'куркчи/u' => 'kürkçi',
+                       '/'.self::WB.'Куркчи/u' => 'Kürkçi',
+                       '/'.self::WB.'КУРКЧИ/u' => 'KÜRKÇI',
+
                        '/'.self::WB.'устке'.self::WB.'/u' => 'üstke',
                        '/'.self::WB.'Устке'.self::WB.'/u' => 'Üstke',
                        '/'.self::WB.'УСТКЕ'.self::WB.'/u' => 'ÜSTKE',
@@ -615,13 +618,21 @@ class CrhExceptions {
                        '/'.self::WB.'Mer'.self::WB.'/u' => 'Мэр',
                        '/'.self::WB.'MER'.self::WB.'/u' => 'МЭР',
 
-                       '/'.self::WB.'джонк/u' => 'cönk',
-                       '/'.self::WB.'Джонк/u' => 'Cönk',
-                       '/'.self::WB.'ДЖОНК/u' => 'CÖNK',
+                       '/'.self::WB.'cönk/u' => 'джонк',
+                       '/'.self::WB.'Cönk/u' => 'Джонк',
+                       '/'.self::WB.'CÖNK/u' => 'ДЖОНК',
 
-                       '/'.self::WB.'куркчи/u' => 'kürkçi',
-                       '/'.self::WB.'Куркчи/u' => 'Kürkçi',
-                       '/'.self::WB.'КУРКЧИ/u' => 'KÜRKÇI',
+                       # (y)etsin -> етсин/этсин
+                       # note that target starts with CYRILLIC е/Е!
+                       '/yetsin/u' => 'етсин',
+                       '/Yetsin/u' => 'Етсин',
+                       '/YETSİN/u' => 'ЕТСИН',
+
+                       # note that target starts with LATIN e/E!
+                       # (other transformations will determine CYRILLIC е/э as needed)
+                       '/etsin/u' => 'eтсин',
+                       '/Etsin/u' => 'Eтсин',
+                       '/ETSİN/u' => 'EТСИН',
 
                        # буква Ё - первый заход
                        # расставляем Ь после согласных
@@ -666,10 +677,6 @@ class CrhExceptions {
                        '/(['.Crh::L_F.'])l(['.Crh::L_CONS_LC.']|'.self::WB.')/u' => '$1ль$2',
                        '/(['.Crh::L_F_UC.'])L(['.Crh::L_CONS.']|'.self::WB.')/u' => '$1ЛЬ$2',
 
-                       '/etsin'.self::WB.'/u' => 'етсин',
-                       '/Etsin'.self::WB.'/u' => 'Етсин',
-                       '/ETSİN'.self::WB.'/u' => 'ЕТСИН',
-
                        # относятся к началу слова
                        '/'.self::WB.'ts/u' => 'ц',
                        '/'.self::WB.'T[sS]/u' => 'Ц',
index 737c20f..277bd02 100644 (file)
@@ -29,8 +29,8 @@ namespace MediaWiki\Languages\Data;
  * These determine things like interwikis, language selectors, and so on.
  * Safe to change without running scripts on the respective sites.
  *
- * \xE2\x80\x8E is the left-to-right marker and
- * \xE2\x80\x8F is the right-to-left marker.
+ * \u{200E} is the left-to-right marker and
+ * \u{200F} is the right-to-left marker.
  * They are required for ensuring the correct display of brackets in
  * mixed rtl/ltr environment.
  *
@@ -88,8 +88,8 @@ class Names {
                'bcc' => 'جهلسری بلوچی', # Southern Balochi
                'bcl' => 'Bikol Central', # Bikol: Central Bicolano language
                'be' => 'беларуская', # Belarusian normative
-               'be-tarask' => "беларуская (тарашкевіца)\xE2\x80\x8E", # Belarusian in Taraskievica orthography
-               'be-x-old' => "беларуская (тарашкевіца)\xE2\x80\x8E", # (be-tarask compat)
+               'be-tarask' => "беларуская (тарашкевіца)\u{200E}", # Belarusian in Taraskievica orthography
+               'be-x-old' => "беларуская (тарашкевіца)\u{200E}", # (be-tarask compat)
                'bg' => 'български', # Bulgarian
                'bgn' => 'روچ کپتین بلوچی', # Western Balochi
                'bh' => 'भोजपुरी', # Bihari macro language. Falls back to Bhojpuri (bho)
@@ -104,6 +104,7 @@ class Names {
                'br' => 'brezhoneg', # Breton
                'brh' => 'Bráhuí', # Brahui
                'bs' => 'bosanski', # Bosnian
+               'btm' => 'Batak Mandailing', # Batak Mandailing
                'bto' => 'Iriga Bicolano', # Rinconada Bikol
                'bug' => 'ᨅᨔ ᨕᨘᨁᨗ', # Buginese
                'bxr' => 'буряад', # Buryat (Russia)
@@ -121,8 +122,8 @@ class Names {
                'cps' => 'Capiceño', # Capiznon
                'cr' => 'Nēhiyawēwin / ᓀᐦᐃᔭᐍᐏᐣ', # Cree
                'crh' => 'qırımtatarca', # Crimean Tatar (multiple scripts - defaults to Latin)
-               'crh-latn' => "qırımtatarca (Latin)\xE2\x80\x8E", # Crimean Tatar (Latin)
-               'crh-cyrl' => "къырымтатарджа (Кирилл)\xE2\x80\x8E", # Crimean Tatar (Cyrillic)
+               'crh-latn' => "qırımtatarca (Latin)\u{200E}", # Crimean Tatar (Latin)
+               'crh-cyrl' => "къырымтатарджа (Кирилл)\u{200E}", # Crimean Tatar (Cyrillic)
                'cs' => 'čeština', # Czech
                'csb' => 'kaszëbsczi', # Cassubian
                'cu' => 'словѣньскъ / ⰔⰎⰑⰂⰡⰐⰠⰔⰍⰟ', # Old Church Slavonic (ancient language)
@@ -132,7 +133,7 @@ class Names {
                'de' => 'Deutsch', # German ("Du")
                'de-at' => 'Österreichisches Deutsch', # Austrian German
                'de-ch' => 'Schweizer Hochdeutsch', # Swiss Standard German
-               'de-formal' => "Deutsch (Sie-Form)\xE2\x80\x8E", # German - formal address ("Sie")
+               'de-formal' => "Deutsch (Sie-Form)\u{200E}", # German - formal address ("Sie")
                'din' => 'Thuɔŋjäŋ', # Dinka
                'diq' => 'Zazaki', # Zazaki
                'dsb' => 'dolnoserbski', # Lower Sorbian
@@ -149,7 +150,8 @@ class Names {
                'en-gb' => 'British English', # British English
                'eo' => 'Esperanto', # Esperanto
                'es' => 'español', # Spanish
-               'es-formal' => "español (formal)\xE2\x80\x8E", # Spanish formal address
+               'es-419' => 'español de América Latina', # Spanish for the Latin America and Caribbean region
+               'es-formal' => "español (formal)\u{200E}", # Spanish formal address
                'et' => 'eesti', # Estonian
                'eu' => 'euskara', # Basque
                'ext' => 'estremeñu', # Extremaduran
@@ -169,8 +171,8 @@ class Names {
                'ga' => 'Gaeilge', # Irish
                'gag' => 'Gagauz', # Gagauz
                'gan' => '贛語', # Gan (multiple scripts - defaults to Traditional)
-               'gan-hans' => "赣语(简体)\xE2\x80\x8E", # Gan (Simplified Han)
-               'gan-hant' => "贛語(繁體)\xE2\x80\x8E", # Gan (Traditional Han)
+               'gan-hans' => "赣语(简体)\u{200E}", # Gan (Simplified Han)
+               'gan-hant' => "贛語(繁體)\u{200E}", # Gan (Traditional Han)
                'gcr' => 'kréyòl gwiyanè', # Guianan Creole
                'gd' => 'Gàidhlig', # Scots Gaelic
                'gl' => 'galego', # Galician
@@ -199,7 +201,7 @@ class Names {
                'hsb' => 'hornjoserbsce', # Upper Sorbian
                'ht' => 'Kreyòl ayisyen', # Haitian Creole French
                'hu' => 'magyar', # Hungarian
-               'hu-formal' => "magyar (formal)\xE2\x80\x8E", # Hungarian formal address
+               'hu-formal' => "magyar (formal)\u{200E}", # Hungarian formal address
                'hy' => 'Հայերեն', # Armenian
                'hz' => 'Otsiherero', # Herero
                'ia' => 'interlingua', # Interlingua (IALA)
@@ -233,12 +235,12 @@ class Names {
                'kiu' => 'Kırmancki', # Kirmanjki
                'kj' => 'Kwanyama', # Kwanyama
                'kk' => 'қазақша', # Kazakh (multiple scripts - defaults to Cyrillic)
-               'kk-arab' => "قازاقشا (تٴوتە)\xE2\x80\x8F", # Kazakh Arabic
-               'kk-cyrl' => "қазақша (кирил)\xE2\x80\x8E", # Kazakh Cyrillic
-               'kk-latn' => "qazaqşa (latın)\xE2\x80\x8E", # Kazakh Latin
-               'kk-cn' => "قازاقشا (جۇنگو)\xE2\x80\x8F", # Kazakh (China)
-               'kk-kz' => "қазақша (Қазақстан)\xE2\x80\x8E", # Kazakh (Kazakhstan)
-               'kk-tr' => "qazaqşa (Türkïya)\xE2\x80\x8E", # Kazakh (Turkey)
+               'kk-arab' => "قازاقشا (تٴوتە)\u{200F}", # Kazakh Arabic
+               'kk-cyrl' => "қазақша (кирил)\u{200E}", # Kazakh Cyrillic
+               'kk-latn' => "qazaqşa (latın)\u{200E}", # Kazakh Latin
+               'kk-cn' => "قازاقشا (جۇنگو)\u{200F}", # Kazakh (China)
+               'kk-kz' => "қазақша (Қазақстан)\u{200E}", # Kazakh (Kazakhstan)
+               'kk-tr' => "qazaqşa (Türkïya)\u{200E}", # Kazakh (Turkey)
                'kl' => 'kalaallisut', # Inuktitut, Greenlandic/Greenlandic/Kalaallisut (kal)
                'km' => 'ភាសាខ្មែរ', # Khmer, Central
                'kn' => 'ಕನ್ನಡ', # Kannada
@@ -255,8 +257,8 @@ class Names {
                'ks-deva' => 'कॉशुर', # Kashmiri (Devanagari script)
                'ksh' => 'Ripoarisch', # Ripuarian
                'ku' => 'kurdî', # Kurdish (multiple scripts - defaults to Latin)
-               'ku-latn' => "kurdî (latînî)\xE2\x80\x8E", # Northern Kurdish (Latin script)
-               'ku-arab' => "كوردي (عەرەبی)\xE2\x80\x8F", # Northern Kurdish (Arabic script) (falls back to ckb)
+               'ku-latn' => "kurdî (latînî)\u{200E}", # Northern Kurdish (Latin script)
+               'ku-arab' => "كوردي (عەرەبی)\u{200F}", # Northern Kurdish (Arabic script) (falls back to ckb)
                'kum' => 'къумукъ', # Kumyk (Cyrillic, 'kum-latn' for Latin script)
                'kv' => 'коми', # Komi-Zyrian (Cyrillic is common script but also written in Latin script)
                'kw' => 'kernowek', # Cornish
@@ -295,6 +297,7 @@ class Names {
                'mk' => 'македонски', # Macedonian
                'ml' => 'മലയാളം', # Malayalam
                'mn' => 'монгол', # Halh Mongolian (Cyrillic) (ISO 639-3: khk)
+               'mni' => 'মেইতেই লোন্', # Manipuri/Meitei
                'mo' => 'молдовеняскэ', # Moldovan, deprecated
                'mr' => 'मराठी', # Marathi
                'mrj' => 'кырык мары', # Hill Mari
@@ -317,7 +320,7 @@ class Names {
                'ng' => 'Oshiwambo', # Ndonga
                'niu' => 'Niuē', # Niuean
                'nl' => 'Nederlands', # Dutch
-               'nl-informal' => "Nederlands (informeel)\xE2\x80\x8E", # Dutch (informal address ("je"))
+               'nl-informal' => "Nederlands (informeel)\u{200E}", # Dutch (informal address ("je"))
                'nn' => 'norsk nynorsk', # Norwegian (Nynorsk)
                'no' => 'norsk', # Norwegian macro language (falls back to nb).
                'nov' => 'Novial', # Novial
@@ -400,8 +403,8 @@ class Names {
                'so' => 'Soomaaliga', # Somali
                'sq' => 'shqip', # Albanian
                'sr' => 'српски / srpski', # Serbian (multiple scripts - defaults to Cyrillic)
-               'sr-ec' => "српски (ћирилица)\xE2\x80\x8E", # Serbian Cyrillic ekavian
-               'sr-el' => "srpski (latinica)\xE2\x80\x8E", # Serbian Latin ekavian
+               'sr-ec' => "српски (ћирилица)\u{200E}", # Serbian Cyrillic ekavian
+               'sr-el' => "srpski (latinica)\u{200E}", # Serbian Latin ekavian
                'srn' => 'Sranantongo', # Sranan Tongo
                'ss' => 'SiSwati', # Swati
                'st' => 'Sesotho', # Southern Sotho
@@ -468,17 +471,18 @@ class Names {
                'yue' => '粵語', # Cantonese
                'za' => 'Vahcuengh', # Zhuang
                'zea' => 'Zeêuws', # Zeeuws/Zeaws
+               'zgh' => 'ⵜⴰⵎⴰⵣⵉⵖⵜ ⵜⴰⵏⴰⵡⴰⵢⵜ', # Moroccan Amazigh (multiple scripts - defaults to Neo-Tifinagh)
                'zh' => '中文', # (Zhōng Wén) - Chinese
                'zh-classical' => '文言', # Classical Chinese/Literary Chinese -- (see T10217)
-               'zh-cn' => "中文(中国大陆)\xE2\x80\x8E", # Chinese (PRC)
-               'zh-hans' => "中文(简体)\xE2\x80\x8E", # Mandarin Chinese (Simplified Chinese script) (cmn-hans)
-               'zh-hant' => "中文(繁體)\xE2\x80\x8E", # Mandarin Chinese (Traditional Chinese script) (cmn-hant)
-               'zh-hk' => "中文(香港)\xE2\x80\x8E", # Chinese (Hong Kong)
+               'zh-cn' => "中文(中国大陆)\u{200E}", # Chinese (PRC)
+               'zh-hans' => "中文(简体)\u{200E}", # Mandarin Chinese (Simplified Chinese script) (cmn-hans)
+               'zh-hant' => "中文(繁體)\u{200E}", # Mandarin Chinese (Traditional Chinese script) (cmn-hant)
+               'zh-hk' => "中文(香港)\u{200E}", # Chinese (Hong Kong)
                'zh-min-nan' => 'Bân-lâm-gú', # Min-nan -- (see T10217)
-               'zh-mo' => "中文(澳門)\xE2\x80\x8E", # Chinese (Macau)
-               'zh-my' => "中文(马来西亚)\xE2\x80\x8E", # Chinese (Malaysia)
-               'zh-sg' => "中文(新加坡)\xE2\x80\x8E", # Chinese (Singapore)
-               'zh-tw' => "中文(台灣)\xE2\x80\x8E", # Chinese (Taiwan)
+               'zh-mo' => "中文(澳門)\u{200E}", # Chinese (Macau)
+               'zh-my' => "中文(马来西亚)\u{200E}", # Chinese (Malaysia)
+               'zh-sg' => "中文(新加坡)\u{200E}", # Chinese (Singapore)
+               'zh-tw' => "中文(台灣)\u{200E}", # Chinese (Taiwan)
                'zh-yue' => '粵語', # Cantonese -- (see T10217)
                'zu' => 'isiZulu' # Zulu
        ];
diff --git a/languages/data/README.md b/languages/data/README.md
new file mode 100644 (file)
index 0000000..8a13fdc
--- /dev/null
@@ -0,0 +1,7 @@
+## normalize-ar.phpc
+
+Generated by `maintenance/language/generateNormalizerDataAr.php`.
+
+## normalize-ml.php
+
+Generated by `maintenance/language/generateNormalizerDataMl.php`.
diff --git a/languages/data/normalize-ar.php b/languages/data/normalize-ar.php
new file mode 100644 (file)
index 0000000..f54b231
--- /dev/null
@@ -0,0 +1,735 @@
+<?php
+// File created by generateNormalizerDataAr.php
+return [
+       'ﭐ' => 'ٱ',
+       'ﭑ' => 'ٱ',
+       'ﭒ' => 'ٻ',
+       'ﭓ' => 'ٻ',
+       'ﭔ' => 'ٻ',
+       'ﭕ' => 'ٻ',
+       'ﭖ' => 'پ',
+       'ﭗ' => 'پ',
+       'ﭘ' => 'پ',
+       'ﭙ' => 'پ',
+       'ﭚ' => 'ڀ',
+       'ﭛ' => 'ڀ',
+       'ﭜ' => 'ڀ',
+       'ﭝ' => 'ڀ',
+       'ﭞ' => 'ٺ',
+       'ﭟ' => 'ٺ',
+       'ﭠ' => 'ٺ',
+       'ﭡ' => 'ٺ',
+       'ﭢ' => 'ٿ',
+       'ﭣ' => 'ٿ',
+       'ﭤ' => 'ٿ',
+       'ﭥ' => 'ٿ',
+       'ﭦ' => 'ٹ',
+       'ﭧ' => 'ٹ',
+       'ﭨ' => 'ٹ',
+       'ﭩ' => 'ٹ',
+       'ﭪ' => 'ڤ',
+       'ﭫ' => 'ڤ',
+       'ﭬ' => 'ڤ',
+       'ﭭ' => 'ڤ',
+       'ﭮ' => 'ڦ',
+       'ﭯ' => 'ڦ',
+       'ﭰ' => 'ڦ',
+       'ﭱ' => 'ڦ',
+       'ﭲ' => 'ڄ',
+       'ﭳ' => 'ڄ',
+       'ﭴ' => 'ڄ',
+       'ﭵ' => 'ڄ',
+       'ﭶ' => 'ڃ',
+       'ﭷ' => 'ڃ',
+       'ﭸ' => 'ڃ',
+       'ﭹ' => 'ڃ',
+       'ﭺ' => 'چ',
+       'ﭻ' => 'چ',
+       'ﭼ' => 'چ',
+       'ﭽ' => 'چ',
+       'ﭾ' => 'ڇ',
+       'ﭿ' => 'ڇ',
+       'ﮀ' => 'ڇ',
+       'ﮁ' => 'ڇ',
+       'ﮂ' => 'ڍ',
+       'ﮃ' => 'ڍ',
+       'ﮄ' => 'ڌ',
+       'ﮅ' => 'ڌ',
+       'ﮆ' => 'ڎ',
+       'ﮇ' => 'ڎ',
+       'ﮈ' => 'ڈ',
+       'ﮉ' => 'ڈ',
+       'ﮊ' => 'ژ',
+       'ﮋ' => 'ژ',
+       'ﮌ' => 'ڑ',
+       'ﮍ' => 'ڑ',
+       'ﮎ' => 'ک',
+       'ﮏ' => 'ک',
+       'ﮐ' => 'ک',
+       'ﮑ' => 'ک',
+       'ﮒ' => 'گ',
+       'ﮓ' => 'گ',
+       'ﮔ' => 'گ',
+       'ﮕ' => 'گ',
+       'ﮖ' => 'ڳ',
+       'ﮗ' => 'ڳ',
+       'ﮘ' => 'ڳ',
+       'ﮙ' => 'ڳ',
+       'ﮚ' => 'ڱ',
+       'ﮛ' => 'ڱ',
+       'ﮜ' => 'ڱ',
+       'ﮝ' => 'ڱ',
+       'ﮞ' => 'ں',
+       'ﮟ' => 'ں',
+       'ﮠ' => 'ڻ',
+       'ﮡ' => 'ڻ',
+       'ﮢ' => 'ڻ',
+       'ﮣ' => 'ڻ',
+       'ﮤ' => 'ۀ',
+       'ﮥ' => 'ۀ',
+       'ﮦ' => 'ہ',
+       'ﮧ' => 'ہ',
+       'ﮨ' => 'ہ',
+       'ﮩ' => 'ہ',
+       'ﮪ' => 'ھ',
+       'ﮫ' => 'ھ',
+       'ﮬ' => 'ھ',
+       'ﮭ' => 'ھ',
+       'ﮮ' => 'ے',
+       'ﮯ' => 'ے',
+       'ﮰ' => 'ۓ',
+       'ﮱ' => 'ۓ',
+       'ﯓ' => 'ڭ',
+       'ﯔ' => 'ڭ',
+       'ﯕ' => 'ڭ',
+       'ﯖ' => 'ڭ',
+       'ﯗ' => 'ۇ',
+       'ﯘ' => 'ۇ',
+       'ﯙ' => 'ۆ',
+       'ﯚ' => 'ۆ',
+       'ﯛ' => 'ۈ',
+       'ﯜ' => 'ۈ',
+       'ﯝ' => 'ٷ',
+       'ﯞ' => 'ۋ',
+       'ﯟ' => 'ۋ',
+       'ﯠ' => 'ۅ',
+       'ﯡ' => 'ۅ',
+       'ﯢ' => 'ۉ',
+       'ﯣ' => 'ۉ',
+       'ﯤ' => 'ې',
+       'ﯥ' => 'ې',
+       'ﯦ' => 'ې',
+       'ﯧ' => 'ې',
+       'ﯨ' => 'ى',
+       'ﯩ' => 'ى',
+       'ﯪ' => 'ئا',
+       'ﯫ' => 'ئا',
+       'ﯬ' => 'ئە',
+       'ﯭ' => 'ئە',
+       'ﯮ' => 'ئو',
+       'ﯯ' => 'ئو',
+       'ﯰ' => 'ئۇ',
+       'ﯱ' => 'ئۇ',
+       'ﯲ' => 'ئۆ',
+       'ﯳ' => 'ئۆ',
+       'ﯴ' => 'ئۈ',
+       'ﯵ' => 'ئۈ',
+       'ﯶ' => 'ئې',
+       'ﯷ' => 'ئې',
+       'ﯸ' => 'ئې',
+       'ﯹ' => 'ئى',
+       'ﯺ' => 'ئى',
+       'ﯻ' => 'ئى',
+       'ﯼ' => 'ی',
+       'ﯽ' => 'ی',
+       'ﯾ' => 'ی',
+       'ﯿ' => 'ی',
+       'ﰀ' => 'ئج',
+       'ﰁ' => 'ئح',
+       'ﰂ' => 'ئم',
+       'ﰃ' => 'ئى',
+       'ﰄ' => 'ئي',
+       'ﰅ' => 'بج',
+       'ﰆ' => 'بح',
+       'ﰇ' => 'بخ',
+       'ﰈ' => 'بم',
+       'ﰉ' => 'بى',
+       'ﰊ' => 'بي',
+       'ﰋ' => 'تج',
+       'ﰌ' => 'تح',
+       'ﰍ' => 'تخ',
+       'ﰎ' => 'تم',
+       'ﰏ' => 'تى',
+       'ﰐ' => 'تي',
+       'ﰑ' => 'ثج',
+       'ﰒ' => 'ثم',
+       'ﰓ' => 'ثى',
+       'ﰔ' => 'ثي',
+       'ﰕ' => 'جح',
+       'ﰖ' => 'جم',
+       'ﰗ' => 'حج',
+       'ﰘ' => 'حم',
+       'ﰙ' => 'خج',
+       'ﰚ' => 'خح',
+       'ﰛ' => 'خم',
+       'ﰜ' => 'سج',
+       'ﰝ' => 'سح',
+       'ﰞ' => 'سخ',
+       'ﰟ' => 'سم',
+       'ﰠ' => 'صح',
+       'ﰡ' => 'صم',
+       'ﰢ' => 'ضج',
+       'ﰣ' => 'ضح',
+       'ﰤ' => 'ضخ',
+       'ﰥ' => 'ضم',
+       'ﰦ' => 'طح',
+       'ﰧ' => 'طم',
+       'ﰨ' => 'ظم',
+       'ﰩ' => 'عج',
+       'ﰪ' => 'عم',
+       'ﰫ' => 'غج',
+       'ﰬ' => 'غم',
+       'ﰭ' => 'فج',
+       'ﰮ' => 'فح',
+       'ﰯ' => 'فخ',
+       'ﰰ' => 'فم',
+       'ﰱ' => 'فى',
+       'ﰲ' => 'في',
+       'ﰳ' => 'قح',
+       'ﰴ' => 'قم',
+       'ﰵ' => 'قى',
+       'ﰶ' => 'قي',
+       'ﰷ' => 'كا',
+       'ﰸ' => 'كج',
+       'ﰹ' => 'كح',
+       'ﰺ' => 'كخ',
+       'ﰻ' => 'كل',
+       'ﰼ' => 'كم',
+       'ﰽ' => 'كى',
+       'ﰾ' => 'كي',
+       'ﰿ' => 'لج',
+       'ﱀ' => 'لح',
+       'ﱁ' => 'لخ',
+       'ﱂ' => 'لم',
+       'ﱃ' => 'لى',
+       'ﱄ' => 'لي',
+       'ﱅ' => 'مج',
+       'ﱆ' => 'مح',
+       'ﱇ' => 'مخ',
+       'ﱈ' => 'مم',
+       'ﱉ' => 'مى',
+       'ﱊ' => 'مي',
+       'ﱋ' => 'نج',
+       'ﱌ' => 'نح',
+       'ﱍ' => 'نخ',
+       'ﱎ' => 'نم',
+       'ﱏ' => 'نى',
+       'ﱐ' => 'ني',
+       'ﱑ' => 'هج',
+       'ﱒ' => 'هم',
+       'ﱓ' => 'هى',
+       'ﱔ' => 'هي',
+       'ﱕ' => 'يج',
+       'ﱖ' => 'يح',
+       'ﱗ' => 'يخ',
+       'ﱘ' => 'يم',
+       'ﱙ' => 'يى',
+       'ﱚ' => 'يي',
+       'ﱛ' => 'ذٰ',
+       'ﱜ' => 'رٰ',
+       'ﱝ' => 'ىٰ',
+       'ﱞ' => ' ٌّ',
+       'ﱟ' => ' ٍّ',
+       'ﱠ' => ' َّ',
+       'ﱡ' => ' ُّ',
+       'ﱢ' => ' ِّ',
+       'ﱣ' => ' ّٰ',
+       'ﱤ' => 'ئر',
+       'ﱥ' => 'ئز',
+       'ﱦ' => 'ئم',
+       'ﱧ' => 'ئن',
+       'ﱨ' => 'ئى',
+       'ﱩ' => 'ئي',
+       'ﱪ' => 'بر',
+       'ﱫ' => 'بز',
+       'ﱬ' => 'بم',
+       'ﱭ' => 'بن',
+       'ﱮ' => 'بى',
+       'ﱯ' => 'بي',
+       'ﱰ' => 'تر',
+       'ﱱ' => 'تز',
+       'ﱲ' => 'تم',
+       'ﱳ' => 'تن',
+       'ﱴ' => 'تى',
+       'ﱵ' => 'تي',
+       'ﱶ' => 'ثر',
+       'ﱷ' => 'ثز',
+       'ﱸ' => 'ثم',
+       'ﱹ' => 'ثن',
+       'ﱺ' => 'ثى',
+       'ﱻ' => 'ثي',
+       'ﱼ' => 'فى',
+       'ﱽ' => 'في',
+       'ﱾ' => 'قى',
+       'ﱿ' => 'قي',
+       'ﲀ' => 'كا',
+       'ﲁ' => 'كل',
+       'ﲂ' => 'كم',
+       'ﲃ' => 'كى',
+       'ﲄ' => 'كي',
+       'ﲅ' => 'لم',
+       'ﲆ' => 'لى',
+       'ﲇ' => 'لي',
+       'ﲈ' => 'ما',
+       'ﲉ' => 'مم',
+       'ﲊ' => 'نر',
+       'ﲋ' => 'نز',
+       'ﲌ' => 'نم',
+       'ﲍ' => 'نن',
+       'ﲎ' => 'نى',
+       'ﲏ' => 'ني',
+       'ﲐ' => 'ىٰ',
+       'ﲑ' => 'ير',
+       'ﲒ' => 'يز',
+       'ﲓ' => 'يم',
+       'ﲔ' => 'ين',
+       'ﲕ' => 'يى',
+       'ﲖ' => 'يي',
+       'ﲗ' => 'ئج',
+       'ﲘ' => 'ئح',
+       'ﲙ' => 'ئخ',
+       'ﲚ' => 'ئم',
+       'ﲛ' => 'ئه',
+       'ﲜ' => 'بج',
+       'ﲝ' => 'بح',
+       'ﲞ' => 'بخ',
+       'ﲟ' => 'بم',
+       'ﲠ' => 'به',
+       'ﲡ' => 'تج',
+       'ﲢ' => 'تح',
+       'ﲣ' => 'تخ',
+       'ﲤ' => 'تم',
+       'ﲥ' => 'ته',
+       'ﲦ' => 'ثم',
+       'ﲧ' => 'جح',
+       'ﲨ' => 'جم',
+       'ﲩ' => 'حج',
+       'ﲪ' => 'حم',
+       'ﲫ' => 'خج',
+       'ﲬ' => 'خم',
+       'ﲭ' => 'سج',
+       'ﲮ' => 'سح',
+       'ﲯ' => 'سخ',
+       'ﲰ' => 'سم',
+       'ﲱ' => 'صح',
+       'ﲲ' => 'صخ',
+       'ﲳ' => 'صم',
+       'ﲴ' => 'ضج',
+       'ﲵ' => 'ضح',
+       'ﲶ' => 'ضخ',
+       'ﲷ' => 'ضم',
+       'ﲸ' => 'طح',
+       'ﲹ' => 'ظم',
+       'ﲺ' => 'عج',
+       'ﲻ' => 'عم',
+       'ﲼ' => 'غج',
+       'ﲽ' => 'غم',
+       'ﲾ' => 'فج',
+       'ﲿ' => 'فح',
+       'ﳀ' => 'فخ',
+       'ﳁ' => 'فم',
+       'ﳂ' => 'قح',
+       'ﳃ' => 'قم',
+       'ﳄ' => 'كج',
+       'ﳅ' => 'كح',
+       'ﳆ' => 'كخ',
+       'ﳇ' => 'كل',
+       'ﳈ' => 'كم',
+       'ﳉ' => 'لج',
+       'ﳊ' => 'لح',
+       'ﳋ' => 'لخ',
+       'ﳌ' => 'لم',
+       'ﳍ' => 'له',
+       'ﳎ' => 'مج',
+       'ﳏ' => 'مح',
+       'ﳐ' => 'مخ',
+       'ﳑ' => 'مم',
+       'ﳒ' => 'نج',
+       'ﳓ' => 'نح',
+       'ﳔ' => 'نخ',
+       'ﳕ' => 'نم',
+       'ﳖ' => 'نه',
+       'ﳗ' => 'هج',
+       'ﳘ' => 'هم',
+       'ﳙ' => 'هٰ',
+       'ﳚ' => 'يج',
+       'ﳛ' => 'يح',
+       'ﳜ' => 'يخ',
+       'ﳝ' => 'يم',
+       'ﳞ' => 'يه',
+       'ﳟ' => 'ئم',
+       'ﳠ' => 'ئه',
+       'ﳡ' => 'بم',
+       'ﳢ' => 'به',
+       'ﳣ' => 'تم',
+       'ﳤ' => 'ته',
+       'ﳥ' => 'ثم',
+       'ﳦ' => 'ثه',
+       'ﳧ' => 'سم',
+       'ﳨ' => 'سه',
+       'ﳩ' => 'شم',
+       'ﳪ' => 'شه',
+       'ﳫ' => 'كل',
+       'ﳬ' => 'كم',
+       'ﳭ' => 'لم',
+       'ﳮ' => 'نم',
+       'ﳯ' => 'نه',
+       'ﳰ' => 'يم',
+       'ﳱ' => 'يه',
+       'ﳲ' => 'ـَّ',
+       'ﳳ' => 'ـُّ',
+       'ﳴ' => 'ـِّ',
+       'ﳵ' => 'طى',
+       'ﳶ' => 'طي',
+       'ﳷ' => 'عى',
+       'ﳸ' => 'عي',
+       'ﳹ' => 'غى',
+       'ﳺ' => 'غي',
+       'ﳻ' => 'سى',
+       'ﳼ' => 'سي',
+       'ﳽ' => 'شى',
+       'ﳾ' => 'شي',
+       'ﳿ' => 'حى',
+       'ﴀ' => 'حي',
+       'ﴁ' => 'جى',
+       'ﴂ' => 'جي',
+       'ﴃ' => 'خى',
+       'ﴄ' => 'خي',
+       'ﴅ' => 'صى',
+       'ﴆ' => 'صي',
+       'ﴇ' => 'ضى',
+       'ﴈ' => 'ضي',
+       'ﴉ' => 'شج',
+       'ﴊ' => 'شح',
+       'ﴋ' => 'شخ',
+       'ﴌ' => 'شم',
+       'ﴍ' => 'شر',
+       'ﴎ' => 'سر',
+       'ﴏ' => 'صر',
+       'ﴐ' => 'ضر',
+       'ﴑ' => 'طى',
+       'ﴒ' => 'طي',
+       'ﴓ' => 'عى',
+       'ﴔ' => 'عي',
+       'ﴕ' => 'غى',
+       'ﴖ' => 'غي',
+       'ﴗ' => 'سى',
+       'ﴘ' => 'سي',
+       'ﴙ' => 'شى',
+       'ﴚ' => 'شي',
+       'ﴛ' => 'حى',
+       'ﴜ' => 'حي',
+       'ﴝ' => 'جى',
+       'ﴞ' => 'جي',
+       'ﴟ' => 'خى',
+       'ﴠ' => 'خي',
+       'ﴡ' => 'صى',
+       'ﴢ' => 'صي',
+       'ﴣ' => 'ضى',
+       'ﴤ' => 'ضي',
+       'ﴥ' => 'شج',
+       'ﴦ' => 'شح',
+       'ﴧ' => 'شخ',
+       'ﴨ' => 'شم',
+       'ﴩ' => 'شر',
+       'ﴪ' => 'سر',
+       'ﴫ' => 'صر',
+       'ﴬ' => 'ضر',
+       'ﴭ' => 'شج',
+       'ﴮ' => 'شح',
+       'ﴯ' => 'شخ',
+       'ﴰ' => 'شم',
+       'ﴱ' => 'سه',
+       'ﴲ' => 'شه',
+       'ﴳ' => 'طم',
+       'ﴴ' => 'سج',
+       'ﴵ' => 'سح',
+       'ﴶ' => 'سخ',
+       'ﴷ' => 'شج',
+       'ﴸ' => 'شح',
+       'ﴹ' => 'شخ',
+       'ﴺ' => 'طم',
+       'ﴻ' => 'ظم',
+       'ﴼ' => 'اً',
+       'ﴽ' => 'اً',
+       'ﵐ' => 'تجم',
+       'ﵑ' => 'تحج',
+       'ﵒ' => 'تحج',
+       'ﵓ' => 'تحم',
+       'ﵔ' => 'تخم',
+       'ﵕ' => 'تمج',
+       'ﵖ' => 'تمح',
+       'ﵗ' => 'تمخ',
+       'ﵘ' => 'جمح',
+       'ﵙ' => 'جمح',
+       'ﵚ' => 'حمي',
+       'ﵛ' => 'حمى',
+       'ﵜ' => 'سحج',
+       'ﵝ' => 'سجح',
+       'ﵞ' => 'سجى',
+       'ﵟ' => 'سمح',
+       'ﵠ' => 'سمح',
+       'ﵡ' => 'سمج',
+       'ﵢ' => 'سمم',
+       'ﵣ' => 'سمم',
+       'ﵤ' => 'صحح',
+       'ﵥ' => 'صحح',
+       'ﵦ' => 'صمم',
+       'ﵧ' => 'شحم',
+       'ﵨ' => 'شحم',
+       'ﵩ' => 'شجي',
+       'ﵪ' => 'شمخ',
+       'ﵫ' => 'شمخ',
+       'ﵬ' => 'شمم',
+       'ﵭ' => 'شمم',
+       'ﵮ' => 'ضحى',
+       'ﵯ' => 'ضخم',
+       'ﵰ' => 'ضخم',
+       'ﵱ' => 'طمح',
+       'ﵲ' => 'طمح',
+       'ﵳ' => 'طمم',
+       'ﵴ' => 'طمي',
+       'ﵵ' => 'عجم',
+       'ﵶ' => 'عمم',
+       'ﵷ' => 'عمم',
+       'ﵸ' => 'عمى',
+       'ﵹ' => 'غمم',
+       'ﵺ' => 'غمي',
+       'ﵻ' => 'غمى',
+       'ﵼ' => 'فخم',
+       'ﵽ' => 'فخم',
+       'ﵾ' => 'قمح',
+       'ﵿ' => 'قمم',
+       'ﶀ' => 'لحم',
+       'ﶁ' => 'لحي',
+       'ﶂ' => 'لحى',
+       'ﶃ' => 'لجج',
+       'ﶄ' => 'لجج',
+       'ﶅ' => 'لخم',
+       'ﶆ' => 'لخم',
+       'ﶇ' => 'لمح',
+       'ﶈ' => 'لمح',
+       'ﶉ' => 'محج',
+       'ﶊ' => 'محم',
+       'ﶋ' => 'محي',
+       'ﶌ' => 'مجح',
+       'ﶍ' => 'مجم',
+       'ﶎ' => 'مخج',
+       'ﶏ' => 'مخم',
+       'ﶒ' => 'مجخ',
+       'ﶓ' => 'همج',
+       'ﶔ' => 'همم',
+       'ﶕ' => 'نحم',
+       'ﶖ' => 'نحى',
+       'ﶗ' => 'نجم',
+       'ﶘ' => 'نجم',
+       'ﶙ' => 'نجى',
+       'ﶚ' => 'نمي',
+       'ﶛ' => 'نمى',
+       'ﶜ' => 'يمم',
+       'ﶝ' => 'يمم',
+       'ﶞ' => 'بخي',
+       'ﶟ' => 'تجي',
+       'ﶠ' => 'تجى',
+       'ﶡ' => 'تخي',
+       'ﶢ' => 'تخى',
+       'ﶣ' => 'تمي',
+       'ﶤ' => 'تمى',
+       'ﶥ' => 'جمي',
+       'ﶦ' => 'جحى',
+       'ﶧ' => 'جمى',
+       'ﶨ' => 'سخى',
+       'ﶩ' => 'صحي',
+       'ﶪ' => 'شحي',
+       'ﶫ' => 'ضحي',
+       'ﶬ' => 'لجي',
+       'ﶭ' => 'لمي',
+       'ﶮ' => 'يحي',
+       'ﶯ' => 'يجي',
+       'ﶰ' => 'يمي',
+       'ﶱ' => 'ممي',
+       'ﶲ' => 'قمي',
+       'ﶳ' => 'نحي',
+       'ﶴ' => 'قمح',
+       'ﶵ' => 'لحم',
+       'ﶶ' => 'عمي',
+       'ﶷ' => 'كمي',
+       'ﶸ' => 'نجح',
+       'ﶹ' => 'مخي',
+       'ﶺ' => 'لجم',
+       'ﶻ' => 'كمم',
+       'ﶼ' => 'لجم',
+       'ﶽ' => 'نجح',
+       'ﶾ' => 'جحي',
+       'ﶿ' => 'حجي',
+       'ﷀ' => 'مجي',
+       'ﷁ' => 'فمي',
+       'ﷂ' => 'بحي',
+       'ﷃ' => 'كمم',
+       'ﷄ' => 'عجم',
+       'ﷅ' => 'صمم',
+       'ﷆ' => 'سخي',
+       'ﷇ' => 'نجي',
+       'ﷰ' => 'صلے',
+       'ﷱ' => 'قلے',
+       'ﷲ' => 'الله',
+       'ﷳ' => 'اكبر',
+       'ﷴ' => 'محمد',
+       'ﷵ' => 'صلعم',
+       'ﷶ' => 'رسول',
+       'ﷷ' => 'عليه',
+       'ﷸ' => 'وسلم',
+       'ﷹ' => 'صلى',
+       'ﷺ' => 'صلى الله عليه وسلم',
+       'ﷻ' => 'جل جلاله',
+       '﷼' => 'ریال',
+       'ﹰ' => ' ً',
+       'ﹱ' => 'ـً',
+       'ﹲ' => ' ٌ',
+       'ﹴ' => ' ٍ',
+       'ﹶ' => ' َ',
+       'ﹷ' => 'ـَ',
+       'ﹸ' => ' ُ',
+       'ﹹ' => 'ـُ',
+       'ﹺ' => ' ِ',
+       'ﹻ' => 'ـِ',
+       'ﹼ' => ' ّ',
+       'ﹽ' => 'ـّ',
+       'ﹾ' => ' ْ',
+       'ﹿ' => 'ـْ',
+       'ﺀ' => 'ء',
+       'ﺁ' => 'آ',
+       'ﺂ' => 'آ',
+       'ﺃ' => 'أ',
+       'ﺄ' => 'أ',
+       'ﺅ' => 'ؤ',
+       'ﺆ' => 'ؤ',
+       'ﺇ' => 'إ',
+       'ﺈ' => 'إ',
+       'ﺉ' => 'ئ',
+       'ﺊ' => 'ئ',
+       'ﺋ' => 'ئ',
+       'ﺌ' => 'ئ',
+       'ﺍ' => 'ا',
+       'ﺎ' => 'ا',
+       'ﺏ' => 'ب',
+       'ﺐ' => 'ب',
+       'ﺑ' => 'ب',
+       'ﺒ' => 'ب',
+       'ﺓ' => 'ة',
+       'ﺔ' => 'ة',
+       'ﺕ' => 'ت',
+       'ﺖ' => 'ت',
+       'ﺗ' => 'ت',
+       'ﺘ' => 'ت',
+       'ﺙ' => 'ث',
+       'ﺚ' => 'ث',
+       'ﺛ' => 'ث',
+       'ﺜ' => 'ث',
+       'ﺝ' => 'ج',
+       'ﺞ' => 'ج',
+       'ﺟ' => 'ج',
+       'ﺠ' => 'ج',
+       'ﺡ' => 'ح',
+       'ﺢ' => 'ح',
+       'ﺣ' => 'ح',
+       'ﺤ' => 'ح',
+       'ﺥ' => 'خ',
+       'ﺦ' => 'خ',
+       'ﺧ' => 'خ',
+       'ﺨ' => 'خ',
+       'ﺩ' => 'د',
+       'ﺪ' => 'د',
+       'ﺫ' => 'ذ',
+       'ﺬ' => 'ذ',
+       'ﺭ' => 'ر',
+       'ﺮ' => 'ر',
+       'ﺯ' => 'ز',
+       'ﺰ' => 'ز',
+       'ﺱ' => 'س',
+       'ﺲ' => 'س',
+       'ﺳ' => 'س',
+       'ﺴ' => 'س',
+       'ﺵ' => 'ش',
+       'ﺶ' => 'ش',
+       'ﺷ' => 'ش',
+       'ﺸ' => 'ش',
+       'ﺹ' => 'ص',
+       'ﺺ' => 'ص',
+       'ﺻ' => 'ص',
+       'ﺼ' => 'ص',
+       'ﺽ' => 'ض',
+       'ﺾ' => 'ض',
+       'ﺿ' => 'ض',
+       'ﻀ' => 'ض',
+       'ﻁ' => 'ط',
+       'ﻂ' => 'ط',
+       'ﻃ' => 'ط',
+       'ﻄ' => 'ط',
+       'ﻅ' => 'ظ',
+       'ﻆ' => 'ظ',
+       'ﻇ' => 'ظ',
+       'ﻈ' => 'ظ',
+       'ﻉ' => 'ع',
+       'ﻊ' => 'ع',
+       'ﻋ' => 'ع',
+       'ﻌ' => 'ع',
+       'ﻍ' => 'غ',
+       'ﻎ' => 'غ',
+       'ﻏ' => 'غ',
+       'ﻐ' => 'غ',
+       'ﻑ' => 'ف',
+       'ﻒ' => 'ف',
+       'ﻓ' => 'ف',
+       'ﻔ' => 'ف',
+       'ﻕ' => 'ق',
+       'ﻖ' => 'ق',
+       'ﻗ' => 'ق',
+       'ﻘ' => 'ق',
+       'ﻙ' => 'ك',
+       'ﻚ' => 'ك',
+       'ﻛ' => 'ك',
+       'ﻜ' => 'ك',
+       'ﻝ' => 'ل',
+       'ﻞ' => 'ل',
+       'ﻟ' => 'ل',
+       'ﻠ' => 'ل',
+       'ﻡ' => 'م',
+       'ﻢ' => 'م',
+       'ﻣ' => 'م',
+       'ﻤ' => 'م',
+       'ﻥ' => 'ن',
+       'ﻦ' => 'ن',
+       'ﻧ' => 'ن',
+       'ﻨ' => 'ن',
+       'ﻩ' => 'ه',
+       'ﻪ' => 'ه',
+       'ﻫ' => 'ه',
+       'ﻬ' => 'ه',
+       'ﻭ' => 'و',
+       'ﻮ' => 'و',
+       'ﻯ' => 'ى',
+       'ﻰ' => 'ى',
+       'ﻱ' => 'ي',
+       'ﻲ' => 'ي',
+       'ﻳ' => 'ي',
+       'ﻴ' => 'ي',
+       'ﻵ' => 'لآ',
+       'ﻶ' => 'لآ',
+       'ﻷ' => 'لأ',
+       'ﻸ' => 'لأ',
+       'ﻹ' => 'لإ',
+       'ﻺ' => 'لإ',
+       'ﻻ' => 'لا',
+       'ﻼ' => 'لا',
+];
diff --git a/languages/data/normalize-ml.php b/languages/data/normalize-ml.php
new file mode 100644 (file)
index 0000000..1cf8548
--- /dev/null
@@ -0,0 +1,10 @@
+<?php
+// File created by generateNormalizerDataMl.php
+return [
+       'ണ്‍' => 'ൺ',
+       'ന്‍' => 'ൻ',
+       'ര്‍' => 'ർ',
+       'ല്‍' => 'ൽ',
+       'ള്‍' => 'ൾ',
+       'ക്‍' => 'ൿ',
+];
index 52d4caf..5cdcfaf 100644 (file)
        "actionthrottled": "Buet geupeubataih",
        "actionthrottledtext": "Sibagoe saboh seunipat lawan-spam, droeneuh geupeubataih nibak neupeulaku buet nyoe le that gö lam watèë paneuk, ngön droeneuh ka leubèh nibak bataih.\nNeuci lom lam padum minèt.",
        "protectedpagetext": "Laman nyoe ka geupeulindông mangat bèk jeuet geuandam",
-       "viewsourcetext": "Droëneuh  jeuët neu’eu",
+       "viewsourcetext": "Droeneuh jeuet neueu ngön neusalén nè nibak mieng nyoe.",
        "viewyourtext": "Droëneuh meuidzin kalön ngön neucok nè andam droëneuh u laman nyoë",
        "protectedinterface": "Halaman nyoe na tèks muka keu muka keu peukakaih leumiëk ngön geupeulindông mangat bek jeuet jipeureuloh.\nKeu neuk tamah atawa ubah teujeumah keu ban dum wiki, neungui [https://translatewiki.net/ translatewiki.net], proyek lokalisasi MediaWiki.",
        "mycustomcssprotected": "Droëneuh hana hak neuandam halaman CSS nyoe.",
        "retypenew": "Pasoë lom lageuëm barô:",
        "resetpass_submit": "Atô lageuëm rahsia lheuëh nyan tamöng",
        "changepassword-success": "Lageuëm rahsia droëneuh meuhasé geugantoë!",
+       "botpasswords-label-create": "Peugöt",
+       "botpasswords-label-update": "Peubarô",
+       "botpasswords-label-cancel": "Pubateue",
+       "botpasswords-label-delete": "Sampôh",
+       "botpasswords-label-resetpassword": "Atô keulayi lageuem rahsia",
        "resetpass_forbidden": "Lageuëm rahsia h'an jeuët geugantoë",
        "resetpass_forbidden-reason": "Lageuëm rahsia h`an jeuët geugantoë: $1",
        "resetpass-no-info": "Droëneuh suwah neutamöng mangat jeuët neu'eu laman nyoë",
        "missingcommenttext": "Neupasoë beunalah di yup.",
        "summary-preview": "Eu neuringkaih neuandam:",
        "blockedtitle": "Ureueng ngui geutheun",
-       "blockedtext": "'''Nan ureuëng nguy atawa alamat IP Droëneuh  ka geutheun.'''\n\nGeutheun lé $1. Dalèh jih nakeuh ''$2''.\n\n* Geutheun yôh: $8\n* Neutheun maté tanggay bak: $6\n* Nyang geutheun: $7\n\nDroëneuh   jeuët neutanyong bak $1 atawa [[{{MediaWiki:Grouppage-sysop}}|nyang urôh nyang la’én]] keu peugah haba bhah nyoë.\n\nDroëneuh   h’an jeuët neunguy alat 'Kirém surat-e ureuëng nguy nyoë' keucuali ka neupasoë alamat surat-e nyang sah di [[Special:Preferences|Geunalak]] Droëneuh ngön Droëneuh ka geutheun keu nguy nyan.\n\nAlamat IP Droëneuh nakeuh $3, ngön ID neutheun nakeuh $5. Tulông peuseureuta salah saboh atawa ban duwa beurita nyoë bak tiëp teunanyöng nyang neupeugöt.",
+       "blockedtext": "<strong>Nan ureueng ngui atawa alamat IP Droeneuh ka geutheun.</strong>\n\nTeuneuheuen geupeugöt lé $1. \nAlasan nyang geubri nakeuh <em>$2</em>.\n\n* Phôn mula geutheun: $8\n* Maté tanggai teuneuheun: $6\n* Ureueng nyang geutheun: $7\n\nDroeneuh jeuet neutanyöng bak $1 atawa [[{{MediaWiki:Grouppage-sysop}}|ureueng urôih]] nyang la’én bhaih teuneuheun nyoe.\nDroeneuh h`an jeuet neungui alat \"{{int:emailuser}}\" keucuali meunyo alamat surat-e nyang sah na neupasoe bak [[Special:Preferences|Neuatô akun]] ngön Droeneuh hana geutheun keu neungui atra nyan.\nAlamat IP Droeneuh jinoe nakeuh $3, ngön ID teuneuheun nakeuh $5.\nNeutulông pasoe ban dum keutrangan di ateueh lam tiep teunanyöng nyang neupeugöt.",
        "autoblockedtext": "'''Nan ureuëng nguy atawa alamat IP Droëneuh  ka geutheun.'''\n\nGeutheun lé $1. Dalèh jih nakeuh ''$2''.\n\n* Geutheun yôh: $8\n* Neutheun maté tanggay bak: $6\n* Nyang geutheun: $7\n\nDroëneuh   jeuët neutanyong bak $1 atawa [[{{MediaWiki:Grouppage-sysop}}|nyang urôh nyang la’én]] keu peugah haba bhah nyoë.\n\nDroëneuh   h’an jeuët neunguy alat 'Kirém surat-e ureuëng nguy nyoë' keucuali ka neupasoë alamat surat-e nyang sah di [[Special:Preferences|Geunalak]] Droëneuh ngön Droëneuh ka geutheun keu nguy nyan.\n\nAlamat IP Droëneuh nakeuh $3, ngön ID neutheun nakeuh $5. Tulông peuseureuta salah saboh atawa ban duwa beurita nyoë bak tiëp teunanyöng nyang neupeugöt.",
        "blockednoreason": "hana dalèh nyang geubri",
        "whitelistedittext": "Droeneuh suwah $1 keu neuandam ôn.",
        "search-result-category-size": "{{PLURAL:$1|1 anggeeta|$1 anggeeta}} ({{PLURAL:$2|1 aneuk kawan|$2 aneuk kawan}}, {{PLURAL:$3|1 beureukaih|$3 beureukaih}})",
        "search-redirect": "(geupupinah nibak $1)",
        "search-section": "(bideuëng $1)",
+       "search-file-match": "(reumbang ngön asoe beureukaih)",
        "search-suggest": "Kadang meukeusud Droëneuh nakeuh: $1",
        "search-interwiki-caption": "Buët la’én",
        "search-interwiki-default": "Hasé nibak $1:",
        "group": "Kawan:",
        "group-user": "Ureueng-ureueng ngui",
        "group-autoconfirmed": "Ureueng ngui nyang meu-konfirmasi otomatis",
+       "group-bot": "Bot",
        "group-sysop": "Ureuëng urôh",
        "group-bureaucrat": "Birôkrat",
        "group-suppress": "Ureueng kalön",
        "action-read": "beuët laman nyoe",
        "action-edit": "andam laman nyoë",
        "action-createpage": "peugöt laman",
+       "action-createaccount": "peugöt akun ureueng ngui nyoe",
        "action-move": "Peupinah laman nyoë",
        "nchanges": "$1 {{PLURAL:$1|neuubah}}",
        "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|yôh seunaweuë seuneulheuëh kön}}",
        "recentchanges-label-plusminus": "Seunipat miëng geugantoë lé jeumeulah bita nyoë",
        "recentchanges-legend-heading": "<strong>Hareutoë:</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (eu cit [[Special:NewPages|dapeuta laman barô]])",
-       "rcnotefrom": "Di yup nyoë nakeuh neuubah yôh <strong>$2</strong> (geupeudeuh trôh ‘an <strong>$1</strong> neuubah).",
+       "rcnotefrom": "Di yup nyoe nakeuh {{PLURAL:$5|neuubah}} yôh <strong>$3, $4</strong> (trôk 'an <strong>$1</strong> geupeudeuih).",
        "rclistfrom": "Peudeuih neuubah barô yôh $3 $2 kön",
        "rcshowhideminor": "$1 andam bacut",
        "rcshowhideminor-show": "Peuleumah",
        "rcshowhidebots-show": "Peuleumah",
        "rcshowhidebots-hide": "Peusom",
        "rcshowhideliu": "$1 ureuëng ngui tamöng",
+       "rcshowhideliu-show": "Peudeuih",
        "rcshowhideliu-hide": "Peusom",
        "rcshowhideanons": "$1 ureuëng ngui hana nan",
        "rcshowhideanons-show": "Peuleumah",
        "recentchangeslinked-feed": "Neuubah meuhubông",
        "recentchangeslinked-toolbox": "Neuubah teukaw'èt",
        "recentchangeslinked-title": "Neuubah nyang meukaw'èt ngön $1",
-       "recentchangeslinked-summary": "Neupasoe saboh nan mieng keu neueu neuubah bak mieng nyang mupawôt u atawa nibak mieng nyan. (Keu neueu anggèeta nibak saboh kawan, neupasoe Kawan:Nan kawan). Neuubah bak mieng bak [[Special:Watchlist|dapeuta keunalön]] teutuléh <strong>teubai</strong>.",
+       "recentchangeslinked-summary": "Neupasoe saboh nan mieng keu neueu neuubah bak mieng nyang mupawôt u atawa nibak mieng nyan. (Keu neueu anggèeta nibak saboh kawan, neupasoe {{ns:category}}:Nan kawan). Neuubah bak mieng nyang na bak [[Special:Watchlist|dapeuta keunalön]] teutuléh <strong>teubai</strong>.",
        "recentchangeslinked-page": "Nan miëng:",
        "recentchangeslinked-to": "Peuleumah neuubah nibak laman-laman nyang mupawôt ngön laman nyang geubri",
        "upload": "Peutamöng beureukaih",
        "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",
        "restriction-type": "Lindông:",
        "restriction-level": "Tingkat:",
+       "restriction-edit": "Andam",
+       "restriction-move": "Pupinah",
        "undeletebtn": "Peuriwang!",
        "undeletelink": "eu/peuriwang",
        "undeleteviewlink": "eu",
        "sp-contributions-search": "Mita soë nyang tuléh",
        "sp-contributions-username": "Alamat IP atawa nan ureuëng ngui:",
        "sp-contributions-toponly": "Peuleumah geunantoe nyang baro mantong",
+       "sp-contributions-newonly": "Peudeuih pumeugöt mieng mantöng",
        "sp-contributions-submit": "Mita",
        "whatlinkshere": "Peunawôt balék",
        "whatlinkshere-title": "Laman nyang mupawôt u $1",
        "whatlinkshere-page": "Miëng:",
-       "linkshere-2": "Laman-laman nyoë meupawôt u '''$1''':",
-       "nolinkshere-2": "Hana halaman nyang teukaw'et u '''$1'''.",
+       "linkshere": "Laman-laman nyoë meupawôt u '''$2''':",
+       "nolinkshere": "Hana halaman nyang teukaw'et u '''$2'''.",
        "isredirect": "laman peuninah",
        "istemplate": "ngön seunaleuëk",
        "isimage": "peunawôt beureukaih",
        "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",
        "ipblocklist": "Ureuëng ngui teutheun",
        "ipblocklist-submit": "Mita",
+       "infiniteblock": "hana bataih",
        "blocklink": "theun",
        "unblocklink": "peugadöh theun",
        "change-blocklink": "gantoë theun",
        "blocklogentry": "theun [[$1]] ngön watèë maté tanggay $2 $3",
        "unblocklogentry": "peugadöh theun \"$1\"",
        "block-log-flags-nocreate": "pumeugöt akun geupumaté",
+       "proxyblocker": "Ngön theun proxy",
        "movepagetext": "Formulir di yup nyoë geunguy keu jak ubah nan saboh ôn ngön jak peupinah ban dum data riwayat u nan barô. Nan nyang trép euntreuk jeuët keu ôn peupinah u nan nyang barô. Hubông u nan trép hana meu’ubah. Neupeupaseuti keu neupréksa peuninah ôn nyang reulöh atawa meuganda lheuëh neupinah. Droëneuh nyang mat tanggông jaweuëb keu neupeupaseuti meunyo hubông laju teusambông u ôn nyang patôt.\n\nBeu neuingat that meunyo ôn '''h’an''' jan geupeupinah meunyo ka na ôn nyang geunguy nan barô, keucuali meunyo ôn nyan soh atawa nakeuh ôn peuninah ngön hana riwayat andam. Nyoë areutijih Droëneuh jeuët neu’ubah nan ôn keulayi lagèë söt meunyo Droëneuh neupeugöt seunalah, ngön Droëneuh h‘an jeuët neutimpa ôn nyang ka na.\n'''INGAT'''\nNyoë jeuët geupeuakébat neu’ubah nyang h’an neuduga ngön kreuëh ngön bacah keu ôn nyang meuceuhu. Neupeupaseuti Droëneuh meuphôm akébat nibak buët nyoë sigohlom neulanjut.",
        "movepagetalktext": "Ôn peugah haba nyang na hubôngan euntreuk teupinah keudroë '''keucuali meunyo:'''\n\n*Saboh ôn peugah haba nyang hana soh ka na di yup nan barô, atawa\n*Droëneuh hana neubôh tanda cunténg bak kutak di yup nyoë\n\nLam masalah nyoë, meunyo neuhawa, Droëneuh jeuët neupeupinah atawa neupeugabông ôn keudroë.",
        "newtitle": "Nan barô:",
        "tooltip-ca-nstab-special": "Nyoë nakeuh miëng kusuih, ngön h’an jeuët geuandam.",
        "tooltip-ca-nstab-project": "Eu laman buët",
        "tooltip-ca-nstab-image": "Eu miëng beureukaih",
+       "tooltip-ca-nstab-mediawiki": "Eu peusan sistem",
        "tooltip-ca-nstab-template": "Eu seunaleuëk",
        "tooltip-ca-nstab-help": "Eu laman beunantu",
        "tooltip-ca-nstab-category": "Eu miëng kawan",
        "tooltip-summary": "Pasoë éhtisa paneuk",
        "interlanguage-link-title": "$1 – $2",
        "simpleantispam-label": "Paréksa anti-spam.\n<strong>BÈK</strong> neupasoë!",
+       "pageinfo-title": "Keutrangan keu \"$1\"",
+       "pageinfo-header-basic": "Keutrangan peuneuphôn",
+       "pageinfo-header-restrictions": "Lindông mieng",
+       "pageinfo-display-title": "Judul tampilan",
+       "pageinfo-default-sort": "Gunci urôt baku",
+       "pageinfo-length": "Panyang mieng (lam bita)",
+       "pageinfo-article-id": "ID Mieng",
+       "pageinfo-language": "Bahsa asoe mieng",
+       "pageinfo-content-model": "Modèl asoe mieng",
+       "pageinfo-robot-policy": "Geuindèks lé robot",
+       "pageinfo-robot-index": "Geupeuidin",
+       "pageinfo-robot-noindex": "Hana geupeuidin",
+       "pageinfo-watchers": "Jumeulah ureueng kalön mieng",
+       "pageinfo-redirects-name": "Jumeulah peuninah u mieng nyoe",
+       "pageinfo-firstuser": "Ureueng peugot mieng",
+       "pageinfo-firsttime": "Uroe buleuen pumeugot mieng",
+       "pageinfo-edits": "Jumeulah neuandam ban dum",
+       "pageinfo-recent-edits": "Jumeulah neuandam ban-ban nyoe (lam $1 nyoe)",
        "pageinfo-toolboxlink": "Keutrangan miëng",
+       "pageinfo-contentpage-yes": "Nyo",
+       "patrol-log-page": "Log patroli",
        "previousdiff": "← Bida awai",
        "nextdiff": "Geunantoë lheuëh nyan →",
        "file-info-size": "$1 × $2 piksel, rayek beureukaih: $3, MIME jeunèh: $4",
+       "file-info-size-pages": "$1 × $2 piksel, seunipat beureukaih: $3, jeunèh MIME: $4, $5 {{PLURAL:$5|mieng}}",
        "file-nohires": "Hana resolusi nyang leubèh manyang.",
        "svg-long-desc": "Beureukah SVG, nominal $1 x $2 piksel, rayek beureukah: $3",
        "show-big-image": "Beureukaih aseuli",
        "confirm-unwatch-button": "Ka göt",
        "confirm-unwatch-top": "Sampôh laman nyoë nibak dapeuta keunalön droëneuh?",
        "imgmultipageprev": "← laman sigohlomjih",
+       "imgmultipagenext": "mieng lheueh nyoe →",
+       "imgmultigo": "Jak!",
+       "imgmultigoto": "Jak u mieng $1",
        "autosumm-new": "Geupeugöt laman ngön asoë '$1'",
        "watchlisttools-view": "Peudeuh neuubah meukaw'èt",
        "watchlisttools-edit": "Peudeuh ngön andam dapeuta keunalön",
        "tag-filter": "Saréng [[Special:Tags|tag]]:",
        "tag-filter-submit": "Saréng",
        "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|Tag}}]]: $2)",
+       "tags-active-yes": "Nyo",
+       "tags-active-no": "H`an",
+       "tags-hitcount": "$1 {{PLURAL:$1|neuubah}}",
        "logentry-delete-delete": "$1 {{GENDER:$2|geusampôh}} miëng $3",
        "logentry-move-move": "$1 {{GENDER:$2|geupinah}} mieng $3 u $4",
+       "logentry-move-move-noredirect": "$1 {{GENDER:$2|geupinah}} mieng $3 u $4 hana geubôh peuninah",
+       "logentry-move-move_redir": "$1 {{GENDER:$2|geupinah}} mieng $3 u $4 ateueh mieng peuninah",
+       "logentry-patrol-patrol-auto": "$1 otomatis {{GENDER:$2|geutanda}} revisi $4 nibak mieng $3 nyang geukawai",
        "logentry-newusers-create": "$1 {{GENDER:$2|geupeugöt}} akun ureuëng ngui",
        "logentry-upload-upload": "$1 {{GENDER:$2|geupasoe}} $3",
        "searchsuggest-search": "Mita {{SITENAME}}",
index 0cd04d9..44f8a03 100644 (file)
        "whatlinkshere": "Мы нэкӀубгъом къэзыщэрэ зэпыщэхэр",
        "whatlinkshere-title": "\"$1\"-м къэзыщэрэ нэкӀубгъохэр",
        "whatlinkshere-page": "НэкӀубгъо:",
-       "linkshere-2": "Мы нэкӀубгъомэ зэпыщэр мыщ къащэ <strong>$1</strong>:",
+       "linkshere": "Мы нэкӀубгъомэ зэпыщэр мыщ къащэ <strong>$2</strong>:",
        "isredirect": "езгъэкӀокӀырэ нэкӀубгъо",
        "istemplate": "хэлъхьаныгъэ",
        "isimage": "файл зэпыщэ",
index 2ab8104..2c68200 100644 (file)
        "sp-contributions-toponly": "أظهر أعلى المراجعات فقط",
        "whatlinkshere-title": "الصفحات التي تصل إلى \"$1\"",
        "whatlinkshere-page": "الپاج:",
-       "linkshere-2": "الصفحات التالية تصل إلى '''$1''':",
-       "nolinkshere-2": "لا توجد صفحات تصل إلى '''$1'''.",
+       "linkshere": "الصفحات التالية تصل إلى '''$2''':",
+       "nolinkshere": "لا توجد صفحات تصل إلى '''$2'''.",
        "isredirect": "صفحة تحويل",
        "istemplate": "مضمن",
        "isimage": "وصلة ملف",
index 0c3c6a7..dc6ed48 100644 (file)
        "mainpage": "Tuisblad",
        "mainpage-description": "Tuisblad",
        "policy-url": "Project:Beleid",
-       "portal": "Gemeenskapsportaal",
+       "portal": "Gebruikersportaal",
        "portal-url": "Project:Gebruikersportaal",
        "privacy": "Privaatheidsbeleid",
        "privacypage": "Project:Privaatheidsbeleid",
        "timezoneregion-indian": "Indiese Oseaan",
        "timezoneregion-pacific": "Stille Oseaan",
        "allowemail": "Laat e-pos van ander toe",
+       "email-blacklist-label": "Verbied hierdie gebruikers om my te e-pos:",
        "prefs-searchoptions": "Soek",
        "prefs-namespaces": "Naamruimtes",
        "default": "verstek",
        "rcfilters-view-tags-tooltip": "Filter resultate volgens wysigingsetikette",
        "rcfilters-liveupdates-button": "Monitor bywerkings",
        "rcfilters-liveupdates-button-title-off": "Wys nuwe wysigings soos hulle inrol.",
-       "rcfilters-preference-label": "Versteek die verbeter weergawe van 'Onlangse wysigings'",
+       "rcfilters-preference-label": "Versteek die verbeterde weergawe van 'Onlangse wysigings'",
+       "rcfilters-watchlist-preference-label": "Versteek die verbeterde weergawe van die dophoulys.",
        "rcnotefrom": "{{PLURAL:$5|Wysiging|Wysigings}} sedert <strong>$3 om $4</strong> (maksimum van <strong>$1</strong> word gewys).",
        "rclistfrom": "Vertoon wysigings vanaf $3 $2",
        "rcshowhideminor": "$1 klein wysigings",
        "whatlinkshere": "Skakels hierheen",
        "whatlinkshere-title": "Bladsye wat na \"$1\" skakel",
        "whatlinkshere-page": "Bladsy:",
-       "linkshere-2": "Die volgende bladsye skakel na '''$1''':",
-       "nolinkshere-2": "Geen bladsye skakel na '''$1'''.",
-       "nolinkshere-ns-2": "Geen bladsye skakel na '''$1''' in die verkose naamruimte nie.",
+       "linkshere": "Die volgende bladsye skakel na '''$2''':",
+       "nolinkshere": "Geen bladsye skakel na '''$2'''.",
+       "nolinkshere-ns": "Geen bladsye skakel na '''$2''' in die verkose naamruimte nie.",
        "isredirect": "aanstuurblad",
        "istemplate": "insluiting",
        "isimage": "lêerskakel",
        "markedaspatrollederrornotify": "Merk as gekontroleerd het misluk.",
        "patrol-log-page": "Kontroleringslogboek",
        "patrol-log-header": "Die logboek wys weergawes wat as gekontroleer gemerk is.",
-       "log-show-hide-patrol": "Nasienlogboek $1",
        "confirm-markpatrolled-button": "OK",
        "deletedrevision": "Ou weergawe $1 geskrap",
        "filedeleteerror-short": "Fout met verwydering van lêer: $1",
index 57fd482..b00e768 100644 (file)
        "whatlinkshere": "masasiket katukuh uyniyay a kasabelih",
        "whatlinkshere-title": "masasiket tayza \"$1\" a kasabelih",
        "whatlinkshere-page": "Kasabelih:",
-       "linkshere-2": "isasaay a kasabelih masasiket tazuma tu <strong>$1</strong>:",
-       "nolinkshere-2": "No pages link to <strong>$1</strong>.",
-       "nolinkshere-ns-2": "mapili’ay a pangangananay a salaedan inayi’ kasabelih  masasiket tu $1.",
+       "linkshere": "isasaay a kasabelih masasiket tazuma tu <strong>$2</strong>:",
+       "nolinkshere": "No pages link to <strong>$2</strong>.",
+       "nolinkshere-ns": "mapili’ay a pangangananay a salaedan inayi’ kasabelih  masasiket tu $2.",
        "isredirect": "miliyaw patatuzu’",
        "istemplate": "palaculen tu kasabelih",
        "isimage": "tangan-tangan misiket",
        "markedaspatrollederrornotify": "silusi tayza-mikibi mungangaw.",
        "patrol-log-page": "tayza mikibi nasulitan nazipa’an",
        "patrol-log-header": "uyniyan sa u tayza-mikibi masumaday baziyong a nasulitan-nazipa’an.",
-       "log-show-hide-patrol": "$1 tayza mikibi nasulitan nazipa’an",
-       "log-show-hide-tag": "$1 tazihan-paya nasulitan nazipa’an",
        "confirm-markpatrolled-button": "malucekay",
        "confirm-markpatrolled-top": "silusi $2 a sumad $3 ku tayza-mikibi?",
        "deletedrevision": "masipu malumanay misumad nu ayaway $1",
index 4989c5d..24a6f97 100644 (file)
        "whatlinkshere": "Vegzat me këtu",
        "whatlinkshere-title": "Faqe që lidhen me \"$1\"",
        "whatlinkshere-page": "Faqja:",
-       "linkshere-2": "Faqet e mâposhtme lidhen në '''$1''':",
+       "linkshere": "Faqet e mâposhtme lidhen në '''$2''':",
        "isredirect": "faqe përcjellëse",
        "istemplate": "përfshirë",
        "isimage": "vegëz në figurë",
index f9f475d..0612ee9 100644 (file)
        "whatlinkshere": "ወዲህ የሚያያዝ",
        "whatlinkshere-title": "ከ «$1» ጋር የሚያያዙ ገጾች",
        "whatlinkshere-page": "ለገጽ (አርዕስት)፦",
-       "linkshere-2": "የሚከተሉት ገጾች ወደ '''$1''' ተያይዘዋል።",
-       "nolinkshere-2": "ወደ '''$1''' የተያያዘ ገጽ የለም።",
-       "nolinkshere-ns-2": "ባመለከቱት ክፍለ-ዊኪ ወደ '''$1''' የተያያዘ ገጽ የለም።",
+       "linkshere": "የሚከተሉት ገጾች ወደ '''$2''' ተያይዘዋል።",
+       "nolinkshere": "ወደ '''$2''' የተያያዘ ገጽ የለም።",
+       "nolinkshere-ns": "ባመለከቱት ክፍለ-ዊኪ ወደ '''$2''' የተያያዘ ገጽ የለም።",
        "isredirect": "መምሪያ መንገድ",
        "istemplate": "የተሰካ",
        "isimage": "የምስል ማያያዣ",
        "markedaspatrollederrortext": "የተመለከተ ሆኖ ለማሳለፍ አንድን ዕትም መወሰን አለብዎት።",
        "markedaspatrollederror-noautopatrol": "የራስዎን ለውጥ የተመለከተ ሆኖ ለማሳለፍ አይችሉም።",
        "patrol-log-page": "የማሳለፊያ መዝገብ",
-       "log-show-hide-patrol": "ማሳለፊያ መዝገቦች",
        "deletedrevision": "የቆየው ዕትም $1 አጠፋ",
        "filedeleteerror-short": "የፋይል ማጥፋት ስኅተት፦ $1",
        "filedeleteerror-long": "ፋይሉን በማጥፋት ስህተቶች ተነስተዋል፦\n\n$1",
diff --git a/languages/i18n/ami.json b/languages/i18n/ami.json
new file mode 100644 (file)
index 0000000..0f91c77
--- /dev/null
@@ -0,0 +1,670 @@
+{
+       "@metadata": {
+               "authors": [
+                       "Vickylin77s"
+               ]
+       },
+       "sunday": "週日",
+       "monday": "tinocay",
+       "tuesday": "tinosa",
+       "wednesday": "tinolo",
+       "thursday": "週四",
+       "friday": "週五",
+       "saturday": "週六",
+       "sun": "週日",
+       "mon": "tinocay",
+       "tue": "tinosa",
+       "wed": "tinolo",
+       "thu": "週四",
+       "fri": "週五",
+       "sat": "週六",
+       "january": "Saka cecay folad",
+       "february": "Saka tosa^ folad",
+       "march": "Saka tolo^ folad",
+       "april": "Saka sepat a folad",
+       "may_long": "Saka lima^ a folad",
+       "june": "Saka enem a folad",
+       "july": "Saka pito^ folad",
+       "august": "Saka falo^ folad",
+       "september": "Saka sowa^ folad",
+       "october": "Saka ngetep folad",
+       "november": "Saka safaw cecay folad",
+       "december": "Saka safaw tosa^ folad",
+       "january-gen": " Saka cecay folad",
+       "february-gen": "Saka tosa^ folad",
+       "march-gen": "Saka tolo^ folad",
+       "april-gen": " Saka sepat a folad",
+       "may-gen": "Saka lima^ a folad",
+       "july-gen": "Saka pito^ folad",
+       "august-gen": "Saka falo^ folad",
+       "september-gen": "Saka sowa^ folad",
+       "october-gen": "Saka ngetep folad",
+       "november-gen": "Saka safaw cecay folad",
+       "december-gen": "Saka safaw tosa^ folad",
+       "jan": " Saka cecay folad",
+       "feb": "Saka tosa^ folad",
+       "mar": "Saka tolo^ folad",
+       "apr": " Saka sepat a folad",
+       "may": "Saka lima^ a folad",
+       "jun": " Saka enem a folad",
+       "jul": "Saka pito^ folad",
+       "aug": "Saka falo^ folad",
+       "sep": "Saka sowa^ folad",
+       "oct": "Saka ngetep folad",
+       "nov": "Saka safaw cecay folad",
+       "dec": "Saka safaw tosa^ folad",
+       "pagecategories": "{{PLURAL:$1|kasakilac|$1 pisakilac}}",
+       "category_header": " O felih i laloma’ no kasakilac \"$1\"",
+       "subcategories": "i reremay a silsil",
+       "category-media-header": " O mitiya i laloma’ no kasakilac \"$1\"",
+       "category-empty": "<em>onini kasakilac imatini caay ho ka paroko i laloma’ ko ’a’arawen a felih ano eca o mitiya。</em>",
+       "hidden-categories": "{{PLURAL:$1|masimeday pisakilac/kasakilac}}",
+       "category-subcat-count": "{{PLURAL:$2|onini kasakilac matafo ko cecay i kalaenoay/kaikoray a wawaay a silsil 。|onini kasakilac matafoay ko i kalaenoay/kaikoray $1 a wawaay a silsil, $2 mapo:long。}}",
+       "category-article-count": "{{PLURAL:$2|onini kasakilac maala halo i kalaenoay/kaikoray a felih。|onini a kasakilac matafo ko i kalaenoay/kaikoray  $1 a felih, $2 mapo:long.}}",
+       "category-file-count": "{{PLURAL:$2|onini kasakilac matafoay ko cecay i kalaenoay/kaikoray a tang^an。|onini kasakilac matafoay ko i kalaenoay/kaikoray  $1 a tang^an, $2 mapo:long.}}",
+       "listingcontinuesabbrev": "milingato",
+       "noindex-category": "Awaayay a masorit i pikiliman a felih i kaikor",
+       "broken-file-category": "o matastasay a felih to pipatatongodan",
+       "cancel": "Sawaden miforic",
+       "moredotdotdot": "matongal ko adihay",
+       "mypage": " o felih",
+       "mytalk": " kalalicay",
+       "navigation": " pakerid a mi’araw",
+       "and": "&#32;ato&#32;",
+       "namespaces": "O pipanganganan",
+       "variants": "namafalican",
+       "navigation-heading": " sapipili’ a tilid to pakerid a mi’araw",
+       "returnto": "Panokasen tayra i $1.",
+       "tagline": "nani… a masadak {{SITENAME}}",
+       "help": "o pakafana’",
+       "search": " saoo’",
+       "searchbutton": " saoo’",
+       "go": " pidemak",
+       "history": " o likisi no felih",
+       "history_short": " likisi",
+       "printableversion": "Manga’ayay a lyi-inen a rorong",
+       "permalink": "tomerepay tongod",
+       "view": "misongila’ a minengneng",
+       "view-foreign": "misongila’ a minengneng i $1",
+       "edit": "misinanot",
+       "create": " misanga’",
+       "create-local": " mitongal to sowal to itiniay",
+       "newpage": " faelohy a felih",
+       "talkpagelinktext": " kalalicay",
+       "specialpage": " micidekay a felih",
+       "personaltools": " no cecayay tamdaw sakatayal",
+       "talk": " malalicay",
+       "views": "misongila’ a minengneng",
+       "toolbox": "sakatayal",
+       "otherlanguages": "O no roma a sowal",
+       "redirectedfrom": "(masafaeloh to misiyor nani $1)",
+       "redirectpagesub": " misafaeloh misiyor i felih",
+       "redirectto": " misafaeloh misiyor i",
+       "lastmodifiedat": "Inian a felih i, o sarikoray a mikawitan i $1 $2。",
+       "jumpto": "tayra",
+       "jumptonavigation": " pakerid a mi’araw",
+       "jumptosearch": " saoo’",
+       "aboutsite": "ora {{SITENAME}}",
+       "aboutpage": "Project: oya pakayniay i",
+       "copyright": "ano awa sa ko roma a sowal i, o $1 sarocek a tilid ko sapipatorod tona maemin",
+       "copyrightpage": "{{ns:project}}:pan-cyin",
+       "currentevents": " o lihaf no sinpon",
+       "currentevents-url": "Project: Aniniay masadak a demak",
+       "disclaimers": "o king-li to sakacaaw ka toro’ i ka’ayaw no holic",
+       "disclaimerpage": "Project: caayay ka palit no holic a sapatangasa a sowal",
+       "edithelp": "  o pakafana’ no pisinanot",
+       "mainpage": "‎ sa’ayayaw pising no tyin-naw",
+       "mainpage-description": "‎ sa’ayayaw pising no tyin-naw",
+       "portal": "O pinaro no tamdaw i cecayay no kasaniyaro’",
+       "portal-url": "Project: o ’adawang no niyaro’",
+       "privacy": " o dapongan a nisahalakaan",
+       "privacypage": "Project: dadapongen a demak",
+       "retrievedfrom": "Nicaliwan niala nani \"$1\"",
+       "youhavenewmessages": "ira ko $1 ($2) no miso",
+       "youhavenewmessagesfromusers": "{{PLURAL:$4|Ira ko no miso}}nani---ay {{PLURAL:$3|roma a micokaymasay |$3 micokaymasay }}a $1 ($2)。",
+       "newmessagesdifflinkplural": "ngata {{PLURAL:$1| falic }}",
+       "editsection": "misinanot",
+       "editold": "misinanot",
+       "viewsourceold": "misongila’ a minengneng to yin-se-ma",
+       "editlink": "misinanot",
+       "viewsourcelink": "misongila’ a minengneng to yin-se-ma",
+       "editsectionhint": "   misinanot to rekad:$1",
+       "toc": "tanenengan",
+       "showtoc": "pahapinang",
+       "hidetoc": " himed",
+       "collapsible-expand": " misatapang",
+       "site-atom-feed": "kasadakan no Atom ko $1",
+       "page-atom-feed": "kasadakan no Atom ko $1",
+       "red-link-title": "$1 (awaayay a felih)",
+       "nstab-main": " o felih",
+       "nstab-user": "O ta’arawan a felih no micokaymasay",
+       "nstab-special": " micidekay a felih",
+       "nstab-project": " halaka felih",
+       "nstab-image": " tang’an",
+       "nstab-template": " sampolo",
+       "nstab-category": "pisakilac",
+       "mainpage-nstab": "‎ sa’ayayaw pising no tyin-naw",
+       "nospecialpagetext": "<strong> awaay ko epoc noya milongocan iso a feli. </strong> Ano mangalay kiso milongoc to ciepocay micidekay a felih i, manga’ay tayra i [[Special:SpecialPages|{{int:specialpages}}]]。",
+       "badtitle": "awa ko epoc a sakacipinang a sowal",
+       "badtitletext": "awaay kora nitolo’an a feli, anoca caay katatodong ko piliting \npiteked 的 o felih sakacipinang a sowal是 awa ko epoc、o ’orac,或未 materongay\nliting的跨 sowal或跨 Wiki 的 sakacipinang a sowal。\nsakacipinang a sowal中 alatekhalo- awa ko pinangmicokaymas在 sakacipinang a sowal的 sorit。",
+       "viewsource": "misongila’ a minengneng to yin-se-ma",
+       "viewsource-title": "misongila’ a manengneng to yin-se-m no $1",
+       "viewsourcetext": "manga’ay misongila’ kiso a minengneng ato mirorod to yin-se-ma nona felih",
+       "yourname": "o ngangan no micokaymasay",
+       "userlogin-yourname-ph": " pacomden ko ngangan no picokaymas no miso",
+       "yourpassword": " mima’",
+       "userlogin-yourpassword": " mima’",
+       "userlogin-yourpassword-ph": " pacomden ko mima’ no miso",
+       "createacct-yourpassword-ph": " pacomden ko mima’",
+       "createacct-yourpasswordagain": "pihayda to mima’",
+       "createacct-yourpasswordagain-ph": "Tiyolen mipacomd ko mima^",
+       "userlogin-remembermypassword": "haratengen ko picomod no mako",
+       "login": " micomod",
+       "logout": "  mahadak",
+       "userlogin-noaccount": "Awaay ko cang-haw hay?",
+       "userlogin-joinproject": "Mikapot a micomod {{SITENAME}}",
+       "createaccount": "misanga’ to cang-haw",
+       "userlogin-resetpassword-link": "mapawan/matawal mi-ma^?",
+       "userlogin-helplink2": " padama to picomod",
+       "createacct-emailoptional": "i-miyo kahaceraan no tikami (mipili’ ato misorit)",
+       "createacct-email-ph": " pacomden ko i-miyo kahaceraan no tikami no miso",
+       "createacct-submit": "misanga’ to cang-haw no miso",
+       "createacct-another-submit": "misanga’ to cang-haw",
+       "createacct-benefit-heading": "{{SITENAME}} o nisanga’an no malecaday kiso a nipaini / nipafeli a tamdaw.",
+       "createacct-benefit-body1": "{{PLURAL:$1|a mikawit}}",
+       "createacct-benefit-body2": "$1 a felih",
+       "createacct-benefit-body3": "O samangataay no {{PLURAL:$1|painiay palada’}}",
+       "mailmypassword": " misafaeloh patonek to mima’",
+       "loginlanguagelabel": " sowal:$1",
+       "pt-login": " micomod",
+       "pt-login-button": " micomod",
+       "pt-createaccount": "misanga’ to cang-haw",
+       "pt-userlogout": "  mahadak",
+       "botpasswords-label-create": " misanga’",
+       "botpasswords-label-cancel": "Sawaden miforic",
+       "resetpass-submit-cancel": "Sawaden miforic",
+       "passwordreset": " misafaeloh patonek to mima’",
+       "passwordreset-username": "o ngangan no micokaymasay",
+       "bold_sample": "kifetolay a tilid",
+       "bold_tip": "kifetolay a tilid",
+       "italic_sample": "matokenihay a tilid",
+       "italic_tip": "matokenihay a tilid",
+       "link_sample": "matongoday a sakacipinang a sowal",
+       "link_tip": "I laloma’ay a makakafit",
+       "extlink_sample": "http://www.example.com  mipakakafit to   sakacipinang a sowal",
+       "extlink_tip": "Makakafitay i papotal (aka kapawan a http:// a misatapang)",
+       "headline_sample": "o sakacipinang a sowal sorit i sakacecay a cakat",
+       "headline_tip": "o sakacipinang a sowal sorit i sakatosa a cakat",
+       "nowiki_sample": " co’eneken ko caay ko masalalekoay a sorit",
+       "nowiki_tip": "Kapawanan ko masalalekoay a sowal no Wiki",
+       "image_tip": "Sapakemel a tang^an",
+       "media_tip": " patatongod to tang’an",
+       "sig_tip": "o pisorit iso to ngangan ato romi’ad toki",
+       "hr_tip": "O rimadac no nanom\n(caay ka rarid a micokaymas)",
+       "summary": " o nisa’amotoan a pakimad",
+       "minoredit": "O sapado^do^ a mikawitan",
+       "watchthis": "mitapal to inian a felih",
+       "savearticle": "mina’ang to felih",
+       "savearticle-start": "mina’ang to felih",
+       "showpreview": "pahapinang to pa’ayaw a minengneng",
+       "showdiff": "pahapinang to nifalican",
+       "anoneditwarning": "<strong> ’arawen :</strong> caayay ho  picomod kiso. Ano mikawit kiso to maamaan i, o mamapahapinang ko IP no miso i ’alomanay. Ano <strong>[$1  micomod kiso]</strong> ano eca <strong>[$2  misanga’ kiso to cang-haw]</strong>,o mikawitan iso i, oya ngangan iso o micokaymasay ko mapasapinangay, matira i, aira ko roma o kanga’ayan a demak.",
+       "blockedtext": "<strong>o ngangan no miso o micokaymasay ano eca o kaitiraan no IP no miso macekeray ito. </strong> maceker no  $1 kiso, enaw han i <em>$2</em>。 *  o toki miteka to picikeran :$8 *  maherek to ko picikeran a toki:$6 *  pakayniay cacikeren a tamdaw:$7 manga’ay kiso a nipakakafit/patongod  $1 ano eca o roma a  [[{{MediaWiki:Grouppage-sysop}}|mikowanay]] maaini to pakayniay i piciker a montay. Ano ira to kiso itira i [[Special:Preferences| o kakaolahan a pipatonek]] mipatonek to cecay o ciepocay    kahaceraan no tikami a i-miyo, ato caay ho kaciker koya sakatayal a i-miyo i, manga’ay kiso a pakayni i \"Email a pakakafit/patongod tonini micokaymasay \" sanay a sakatayal a mitongod to mikowanay. O kaitiraan no IP no miso anini i  $3,anini o macikeray a ID i o #$5. Ano mangalay kiso a mipolita i, patoroden koya i faleday masongila’ay a lihaf.",
+       "loginreqlink": " micomod",
+       "newarticletext": "militingay kiso to cecay awaayay a felih\nano mamisanga’ to cecay a felih,itira i nisinanotan a ’apelad a pacomd to sowal ( nengnengen ko [ sakadademak a tilid no $1]) 。\nano o caay ko pina’on iso ko sakatayni i, mi^mien ko <strong> minokas</strong>   tami^mian no sakipinengnengan",
+       "anontalkpagetext": "----<em>onini ka ainian a felih, o sakitini caayay ho pisanga’ to cang-haw a tamdaw, ano eca, yo misakaniway ho ko pipangangan a micokaymasay</em> oarasaka pakayni i kaitiraan no IP ko pisapinang to tireng, nika oya kaitiraan no malecaday a IP, alatek ’aloman ko micokaymasay. Ano o misakaniway ho ko pipangangan iso, ato ano caay ko sakitini i tisowanan koya mipo’elacay a sowal i, ka o [[Special:CreateAccount|pisanga’ o faelohay a cang-haw]] ano eca [[Special:UserLogin|sacomod]] ta caay ka sasifod to no roma oya misakaniway ko pipangangan a tamdaw.",
+       "noarticletext": " Awaay ko sorit i laloma’ nonini a felih, manga’ay kiso a mikilim i roma a felih i [[Special:Search/{{PAGENAME}}| misolap to sakacipinang a sowal nonini a felih]]、<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}}  misolap to nikilokan a sorit to romi’ami’ad , ano eca [{{fullurl:{{FULLPAGENAME}}|action=edit}}  itini misanga’ tonini a felih]</span>。",
+       "noarticletext-nopermission": "Awaay ko sorit i laloma’ nonini a felih, manga’ay kiso a mikilim i roma a felih i [[Special:Search/{{PAGENAME}}| misolap to sakacipinang a sowal nonini a felih]],ano eca <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}}  misolap to nikilokan a sorit to romi’ami’ad]</span>, nika awaay ko kingli no miso a misanga’ tonini a felih.",
+       "userpage-userdoesnotexist-view": "Caay ho ka hayda ko pipangangan a cang-haw no micokaymasay \"$1\".",
+       "clearyourcache": "<strong>’arawen :</strong>i ikor no pi’anang iso i ’ariri, panengen koya mata sapinengneng to codad ta manga’ay maneneng ko faelohay a nikafalic. \n* <strong>Firefox / Safari:</strong>penecen <em>Shift</em> itiya ta mitoro’ mikilim <em> misafaeloh  misolimet </em>,ano eca penecen <em>Ctrl-F5</em> ano eca <em>Ctrl-R</em> (Mac matira ta  <em>⌘-R</em>) * <strong>Google Chrome:</strong>rekenen <em>Ctrl-Shift-R</em> (Mac matira ta  <em>⌘-Shift-R</em>) * <strong>Internet Explorer:</strong>penecen <em>Ctrl</em> itiya t rekenen a mipili’ <em> misafaeloh  misolimet </em>,ano eca rekenen <em>Ctrl-F5</em> * <strong>Opera:</strong> tayra  <em> sapipili’ a tilid  →  patonek </em> (itira i Mac a <em>Opera →   patonek to kakaolahan </em>) herek i, ta tayra i <em> caayay ka ’araw no tao a dapong  &  an-cyin-sin  → sisiten ko nanengnengan a lakaw → mapatayraay i ’ariri a conga ato tang^an </em>。",
+       "previewnote": "<strong>mineneng kiso to ’a’arawen imatini, caay ho ka ’aneng iso i ’ariri koya nifalican no miso!</strong>",
+       "editing": "O mamikawit to $1",
+       "creating": "O mamisanga’ to $1",
+       "editingsection": "O mamikawit to $1(cefang tosir)",
+       "templatesused": "Macokaymas to ninian a felih i kalaenoay/kaikoray {{PLURAL:$1| ko sampolo}}:",
+       "templatesusedpreview": "Mipa’ayaw a minengneng i, macokaymas i kalaenoay/kaikoray ko {{PLURAL:$1| dado^doan a sampolo }}:",
+       "template-protected": "(madipotay/ma’adipelay)",
+       "template-semiprotected": "(mapangkiway ko pi’adipel)",
+       "hiddencategories": "O no {{PLURAL:$1| a felih konini, cecay ko masimeday to nisilsilan a kasakilac |$cecay ko masimeday to nisilsilan a kasakilac }} i salaoma’ no no tamdaw.",
+       "permissionserrorstext-withaction": "Itini i kalaeno{{PLURAL:$1| o lalangatan}},awaay ko king-li no miso a midemak to  $2 a demak:",
+       "recreate-moveddeleted-warn": "<strong>pi’arawi:O misafaelohay kiso a misanga’ toya masopitay to a felih. </strong> O haharatengen iso ko pilingato haca a mikawit tonini a felih. Itini mapatorod kiso to sapisopit ato sapilinah to codad, o sakacaloway iso a mineneng to sapatinako to ’a’arawen.",
+       "moveddeleted-notice": "Masopitay to konini a felih.\ni kalaeno, o sapaneneng toya nisopitan ato ya nilinahan a kilok.",
+       "undo-failure": "Iraay ko nikafafelih no nisalofan ato nikawitan i laloma’, orasaka caay ka nga’ay a minokas a patiko",
+       "viewpagelogs": " misongila’ a minengneng to kilok ninian a felih",
+       "currentrev": "safaelohay a pisalof",
+       "currentrev-asof": "Nani tiniay i $1 safaelohay a nisalofan",
+       "revisionasof": "Nani tiniay i $1 a nisalofan",
+       "revision-info": "O po:long no nisalofan i $7 nani tiniay i {{GENDER:$6|$2}} ko $1",
+       "previousrevision": "←i ka’ayaway nisalofan",
+       "nextrevision": "Pado^do^ misalof→",
+       "currentrevisionlink": "safaelohay a pisalof",
+       "cur": " Aniniay/imatiniay",
+       "last": "ka’ayaway",
+       "histlegend": "O kasasiroma no pasirini’ to nipili’an: ano mipli’ i, pasasirini’en koya misalofan toya masa’apeladay ato pili’en koya i kalaenoay a pipenecan mifhat to dingki a pasasirini’.  <br />  misapinang paini to silosi:<strong>({{int:cur}})</strong> = pasasirini’ toya safaelohay a nisalofan a rorong<strong>({{int:last}})</strong> = pasasirini’ toya sa’ayaway misalofan <strong>{{int:minoreditletter}}</strong> =  sapado^do^ a misalof.",
+       "history-feed-description": "Pakayni tonini a Wiki a tayra i nisalofan to a kilok",
+       "history-feed-item-nocomment": "$1 i laloma’ no  $2",
+       "rev-delundel": "o nika’araw to nanofalicen",
+       "rev-showdeleted": "pahapinang",
+       "revdel-restore": "o nika’araw to nanofalicen",
+       "pagehist": " o likisi no felih",
+       "history-title": "Masalofay a caway no \"$1\"",
+       "difference-title": "O kasasiroma no nisalofan no \"$1\"",
+       "lineno": "$1 tosir",
+       "compareselectedversions": "masasirini’ to mipili’an a misalof",
+       "editundo": " patikor",
+       "diff-multi-sameuser": "(caay pasapinang to nidemakan noya micokaymasaya tamdaw a kina  $1 a misalof)",
+       "diff-multi-otherusers": "(caay pahapinang to $2 nidemakan no i laloma’ay noya micokaymasay  saka $1 a misalof )",
+       "searchresults": " nasaoo’an",
+       "searchresults-title": "Nisolapan a cepo’/heci no $1",
+       "prevn": "ya ka’ayaway to $1",
+       "nextn": "o rarikoray a {{PLURAL:$1|$1}}",
+       "prevn-title": "o nalahecian no ka’ayaway nira to cecay",
+       "nextn-title": "o nikalahecian no rarikoray a $1",
+       "shown-title": "Pahapinangen ko pinaay a $1 i kahacecay a felih",
+       "viewprevnext": " misongila’ a minengneng to ($1 {{int:pipe-separator}} $2) ($3)",
+       "searchmenu-exists": "<strong>onini a Wiki iraayto ko ngangan  \"[[:$1]]\" no felih 。</strong> {{PLURAL:$2|0=|ano eca ’araw hato i roma a misolapan a codad. }}",
+       "searchmenu-new": "<strong>itini i Wiki  misanga’ to pi’arawan a felih \"[[:$1]]\"!</strong>{{PLURAL:$2|0=|ano eca, ’araw hato ko makeraay toya nipacomdaniso a codad, |ano eca, ’araw hato ko roma a makeraay tona nisolapan.}}",
+       "searchprofile-articles": " Matiliday a sowal itenok no felih",
+       "searchprofile-images": "Macacamolay a mi-ti-ya",
+       "searchprofile-advanced": " cakat",
+       "searchprofile-articles-tooltip": "Misolap mikilim i  $1",
+       "searchprofile-images-tooltip": " saoo’an a tang’an",
+       "searchprofile-everything-tooltip": " saoo’en maemin ko sowal (halo- kalalicay a felih)",
+       "searchprofile-advanced-tooltip": " saoo’ to pipanganganan no piketon no tireng",
+       "search-result-size": "$1 ({{PLURAL:$2|1 ko sorit|$2 ko sorit}})",
+       "search-result-category-size": "$1 ko salaloma’ay a tamdaw ($2 ko laenoay kasakilac ,$3 ko tang-an )",
+       "search-redirect": "(misafaeloh misiyor nani $1)",
+       "search-section": "(saka $1 a rekad )",
+       "search-file-match": "( matatodongay a sowal i laloma’ no tang^an )",
+       "search-suggest": "o nini $1 ko nitoro’an iso haw",
+       "searchall": "Maemin/po:long",
+       "search-showingresults": "{{PLURAL:$4|saka <strong>$1</strong> codad, <strong>$3</strong> mapo:long|saka <strong>$1 - $2</strong> codad,<strong>$3</strong> mapo:long  koya codad}}",
+       "search-nonefound": "awaay ko matatodongay to sakarocek a nikaherek",
+       "powersearch-toggleall": " Maemin/po:long",
+       "preferences": "o kananaman a pinangan",
+       "mypreferences": "o kananaman a pinangan",
+       "prefs-rc": "I ngataay nipifalic",
+       "prefs-watchlist": " o pirorodan to tatapalen a tilid",
+       "prefs-editwatchlist-raw": " misinanot to satapangan no pirorodan to tatapalen a tilid",
+       "searchresultshead": " saoo’",
+       "prefs-searchoptions": " saoo’",
+       "prefs-namespaces": "O pipanganganan",
+       "prefs-files": " tang’an",
+       "prefs-diffs": " o kasasiroma",
+       "right-upload": " mipaefer to tang^an",
+       "right-writeapi": "Sakatayal a misorit to API",
+       "grant-createaccount": "misanga’ to cang-haw",
+       "newuserlogpage": " misanga’ to pikilokan to micokaymasay",
+       "rightslog": "O king-li no nikilokan no micokaymasay",
+       "action-edit": "misinanot to inian a felih",
+       "action-createaccount": " misanga’ tona cang-haw no micokaymasay",
+       "action-move": "linahen kona felih",
+       "enhancedrc-history": " likisi",
+       "recentchanges": "I ngataay nipifalic",
+       "recentchanges-legend": "I ngataay nipifalic a kamok.",
+       "recentchanges-summary": "dapdapen i Wiki ko nikafalic nonini a felih",
+       "recentchanges-noresult": "Awaay ko matatodongay a sapifalih i salaloma’ no nipatonekay a romi’ad",
+       "recentchanges-feed-description": "dapdapen i Wiki ko nikafalic nonini a  nisa’amotoan a kimad",
+       "recentchanges-label-newpage": " masanga’ay to nona misinanotay ko faelohay a felih",
+       "recentchanges-label-minor": "O sapado^do^ a mikawitan",
+       "recentchanges-label-bot": "palatamdawan a kikay ko mamidemak tona pisinanot",
+       "recentchanges-label-unpatrolled": "caayay ho misolap kona pisinanot",
+       "recentchanges-label-plusminus": "o kafalic nona felih ( makakafitay a wey-yin)",
+       "recentchanges-legend-heading": "<strong> sapatiri’ a coka^:</strong>",
+       "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (’araw hato[[Special:NewPages|faelohay a felih]])",
+       "recentchanges-submit": "pahapinang",
+       "rcfilters-activefilters-hide": " himed",
+       "rcfilters-activefilters-show": "pahapinang",
+       "rcfilters-days-show-days": "$1 romi’ad",
+       "rcfilters-savedqueries-cancel-label": "Sawaden miforic",
+       "rcfilters-filtergroup-lastRevision": "safaelohay a pisalof",
+       "rcnotefrom": " i kalaenoay{{PLURAL:$5|為}}nani  <strong>$3 $4</strong> nifalican tangasa anini (saadihayay mipahapinangan i<strong>$1</strong> ko nisadakan a codad).",
+       "rclistfrom": "pahapinang to faelohay a falic nano $3 $2",
+       "rcshowhideminor": "$1 sapado^do^ a mikawit",
+       "rcshowhideminor-show": "pahapinang",
+       "rcshowhideminor-hide": " himed",
+       "rcshowhidebots": "$1 palatamdawan a kikay",
+       "rcshowhidebots-show": "pahapinang",
+       "rcshowhidebots-hide": " himed",
+       "rcshowhideliu": "$1 mapanganganay to a micokaymasay",
+       "rcshowhideliu-show": "pahapinang",
+       "rcshowhideliu-hide": " himed",
+       "rcshowhideanons": "$1 misakaniway a ngangan",
+       "rcshowhideanons-show": "pahapinang",
+       "rcshowhideanons-hide": " himed",
+       "rcshowhidepatr": "$1 masolapay to a mikawitan",
+       "rcshowhidepatr-show": "pahapinang",
+       "rcshowhidepatr-hide": " himed",
+       "rcshowhidemine": "$1 no mako a mikawitan",
+       "rcshowhidemine-show": "pahapinang",
+       "rcshowhidemine-hide": " himed",
+       "rcshowhidecategorization-show": "pahapinang",
+       "rcshowhidecategorization-hide": " himed",
+       "rclinks": "pahapinang to ngata $2 a romi’adan to $1 a nifalican",
+       "diff": " o kasasiroma",
+       "hist": " likisi",
+       "hide": " himed",
+       "show": "pahapinang",
+       "minoreditletter": "mamangay",
+       "newpageletter": " faelohay",
+       "boteditletter": "palatamdawan a kikay",
+       "rc-change-size-new": "nanofalicen i, o $1 makakafitay a wey-yin",
+       "rc-old-title": "o sa’ayaway a nisanga’an a ngangan i, o \"$1\"",
+       "recentchangeslinked": " pakayniay i pifalic",
+       "recentchangeslinked-feed": " pakayniay i pifalic",
+       "recentchangeslinked-toolbox": " pakayniay i pifalic",
+       "recentchangeslinked-title": "o kafafalic no pakayniay i \"$1\"",
+       "recentchangeslinked-page": " o ngangan no felih:",
+       "recentchangeslinked-to": "Pahapinangen ko nifalican a felih a itira toya nipatonekan nifalic a felih.",
+       "upload": " mipaefer to tang^an",
+       "filedesc": " o nisa’amotoan a pakimad",
+       "filesource": "lalengatan",
+       "upload-dialog-title": " mipaefer to tang^an",
+       "upload-dialog-button-cancel": "Sawaden miforic",
+       "upload-form-label-infoform-description": " kimad",
+       "upload-form-label-infoform-categories": " pisakilac",
+       "upload-form-label-infoform-date": "O romi’ad",
+       "license": "o sakipatorod a tilid",
+       "license-header": "o sakipatorod a tilid",
+       "listfiles-userdoesnotexist": "Caay ho ka hayda ko pipangangan a cang-haw no micokaymasay \"$1\".",
+       "imgfile": " tang’an",
+       "listfiles_thumb": " nisamamangan a conga",
+       "listfiles_date": "O romi’ad",
+       "listfiles_user": "micokaymasay",
+       "listfiles_description": " kimad",
+       "file-anchor-link": " tang’an",
+       "filehist": "o likisi no tang’an",
+       "filehist-help": " pili’en a mimi^mi ko romi’ad/ tok, ta misongila’ a minengneng to tang’an rorong nora tatokian",
+       "filehist-current": "Aniniay/imatinaay",
+       "filehist-datetime": "O romi’ad/ toki",
+       "filehist-thumb": " nisamamangan a conga",
+       "filehist-thumbtext": "Nani tiniay i $1 a rorong no nisamamangan a coka",
+       "filehist-user": "micokaymasay",
+       "filehist-dimensions": "o tata’ak ato karaya’",
+       "filehist-comment": "pipatongalan to sowal",
+       "imagelinks": " sakatayal no tang’an",
+       "linkstoimage": "Onini laenoay {{PLURAL:$1| makakafit ko felih  |$1 ko felih makakafit}}tayi tonini a tang^an:",
+       "linkstoimage-more": "mata’elifay ko $1 o {{PLURAL:$1| o felih  tongod| o felih  tongod}} a tayni tona tang’an. ona kamok deng o  {{PLURAL:$1|1 ko pitongod to |$1 tongod}} tayni tona tang’an a feli. Manga’ay misongila’ kiso a manengneng to [[Special:WhatLinksHere/$2| masongila’ay a kamok ]]。",
+       "nolinkstoimage": "Awaay ko felih to sapakakafit tonini a tang^an.",
+       "linkstoimage-redirect": "$1 (misafaeloh misiyor to tang^an ) $2",
+       "sharedupload-desc-here": "Nani tiniay i $1konini a tang^an, alatek macokaymas no roma a masatataday a tang^an. Ikalaeno i [ masongila’ay a sowal toya felih ] a mapahapinang ko i tenokay a sowal.",
+       "filepage-nofile": "Awaayay ko ngangan a tang^an.",
+       "upload-disallowed-here": "cowa ko mamatahepo iso kona tang’an。",
+       "randompage": "away ko pitooran a felih",
+       "randomincategory-submit": " pidemak",
+       "statistics-articles": " Matiliday a sowal itenok no felih",
+       "statistics-pages": " o felih",
+       "pageswithprop-submit": " pidemak",
+       "double-redirect-fixer": " misafaeloh misiyor i nisalofay",
+       "brokenredirects-edit": "misinanot",
+       "withoutinterwiki-submit": "pahapinang",
+       "nbytes": "$1 ko makakafitay a wey-yin",
+       "nmembers": "$1 ko salaloma’ay no …a tamdaw",
+       "prefixindex": "do^doen ko tatapangan no sowal a mikilim to felih",
+       "prefixindex-submit": "pahapinang",
+       "protectedpages-filters": " saoo’:",
+       "protectedpages-noredirect": "mihimed a misafaeloh misiyor a felih",
+       "protectedpages-page": " o felih",
+       "newpages": " faelohay a felih",
+       "newpages-submit": "pahapinang",
+       "newpages-username": "o ngangan no micokaymasay",
+       "move": "malinah",
+       "movethispage": "linahen kona felih",
+       "pager-newer-n": "{{PLURAL:$1|faelo:hay  $1 a codad}}",
+       "pager-older-n": "o matelangay a nisinanotan $1",
+       "apisandbox-add-multi": "mitongal",
+       "booksources": " pikinairaan no nina’angan a tilid",
+       "booksources-search-legend": "mikilim to pina’angan to tilid",
+       "booksources-search": " saoo’",
+       "speciallogtitlelabel": "O patosokan (sakacipinang a sorit ano eca o… {{ns:user}}: o ngangan no micokaymasay):",
+       "log": "nisoritan to romi’ami’ad",
+       "alllogstext": "Pararapiten a maemin mahapinang ko  {{SITENAME}} no kahirahira a nikilokan. Manga’ay kiso a talalaeno a mipili’ to nikilokan, miteked pangangan to micokaymasay (ta’akay sorit ano eca mamangay sorit no padaka) ano eca oya ngangan o madafitay a felif(ta’akay sorit ano eca mamangay sorit no padaka)",
+       "logempty": "awaay ko matatodongay to sakarocek a kilok",
+       "checkbox-all": " Maemin/po:long",
+       "allpages": "O po:long no felih",
+       "allarticles": "O po:long no felih",
+       "allpagessubmit": " pidemak",
+       "allpages-hide-redirects": "mihimed a misafaeloh misiyor a felih",
+       "categories": " pisakilac",
+       "categories-submit": "pahapinang",
+       "sp-deletedcontributions-contribs": " nipafelian",
+       "linksearch-ns": "O pipanganganan",
+       "linksearch-ok": " saoo’",
+       "listusers-submit": "pahapinang",
+       "emailuser": "Pa-Email-en a pacodad konini micokaymasay",
+       "emailusername": "o ngangan no micokaymasay",
+       "watchlist": " o pirorodan to tatapalen a tilid",
+       "mywatchlist": " o pirorodan to tatapalen a tilid",
+       "watchlistfor2": "$2 pisimawan to ’a’arawen a tilid no $1",
+       "watch": "mitapal",
+       "watchthispage": "mitapal to inian a felih",
+       "watchlist-details": "o pirorodan to ’a’arawen a tilid iso i, $1 ko felih (halo- kalalicay a felih )。",
+       "wlheader-showupdated": "O pakarikoray nisongila’an a minengneng ato nisalofan a felih i, oya <strong>kifetolay sorit </strong> ko sapasapinang.",
+       "wlnote": " i kalaenoay nani $3 $4 i ka’ayaway i <strong>$2</strong> mihalakaan i ’ayaw no pinapina a tatokian  <strong>$1</strong> kina--- a mifalic.",
+       "wlshowlast": "pahapinang to ngata $1 a tatokian $2 a romi’ad",
+       "watchlist-hide": " himed",
+       "watchlist-submit": "pahapinang",
+       "enotif_reset": " pahapinangen kona felih a maemin o matiri’ay to",
+       "enotif_minoredit": "O sapado^do^ a mikawitan",
+       "historyaction-submit": "pahapinang",
+       "dellogpage": "falah/ foric nisoritan to romi’ami’ad",
+       "deletionlog": "falah/ foric nisoritan to romi’ami’ad",
+       "rollbacklink": " patatikol",
+       "rollbacklinkcount": "{{PLURAL:$1|a mikawit}}",
+       "protectlogpage": "Sapi’adipel to nisoritan to romi’ami’ad",
+       "protectedarticle": "Mapa’esay to ko \"[[$1]]\"",
+       "modifiedarticleprotection": "Mafalicay to \"[[$1]]\" koya sapi’adipel",
+       "protect-default": " mahayda ko po:long ano micokaymasay",
+       "restriction-type": " o sakatonek a patorod :",
+       "restriction-edit": "misinanot",
+       "restriction-move": "malinah",
+       "restriction-create": " misanga’",
+       "undeleteinvert": "Macaco’isay ko pipili’",
+       "undelete-search-submit": " saoo’",
+       "namespace": "O pipanganganan",
+       "invert": "Macaco’isay ko pipili’",
+       "tooltip-invert": " Mikawit tonini a masa’apeladay, o sapisimed a mipili’ a mipangangan to nifalican a felih(ano mikawit to sapipangangan i, o mamalecad a masimed ko nipanganganan)",
+       "namespace_association": "  pakayniay i pipanganganan",
+       "tooltip-namespace_association": " Mikawit tonini a masa’apelada, o pahapinang to masaloma’ay to ko nikalalicay ato patosokan to sapangangan",
+       "blanknamespace": "(kalimelaan)",
+       "contributions": "{{GENDER:$1| micokaymasay}} nipaini/ nipafeli",
+       "contributions-title": "nipaini/ nipafeli no micokaymasay a $1",
+       "mycontris": " nipafelian",
+       "contribsub2": "{{GENDER:$3|$1}} nipainian/ nipafelian no ($2)",
+       "contributions-userdoesnotexist": "Caay ho ka hayda ko pipangangan a cang-haw no micokaymasay \"$1\".",
+       "nocontribs": "Awaay matama^ ko matatodongay a sapifalih",
+       "month": "paherekan safoladan:",
+       "year": "paherekan mihecaan:",
+       "sp-contributions-newbies": "o nipafelian aca no faelohay cang-haw ko pahapinangen",
+       "sp-contributions-blocklog": " pikilokan to kalonicikeran",
+       "sp-contributions-logs": "nisoritan to romi’ami’ad",
+       "sp-contributions-talk": " kalalicay",
+       "sp-contributions-username": "kaitiraan no IP ano ecangangan no micokaymasay:",
+       "sp-contributions-toponly": "Edeng o safaelohay misanga’an a mikawit ko mapahapinangay",
+       "sp-contributions-newonly": "Edeng o masanga’ay to a felih no nikawitan ko mapahapinangay",
+       "sp-contributions-submit": " saoo’",
+       "whatlinkshere": "militingay tonian a felih",
+       "whatlinkshere-title": "militingay i \"$1\" a felih",
+       "isredirect": " misafaeloh misiyor i felih",
+       "istemplate": "Micaliw micokaymas",
+       "isimage": "patatongod to tang’an",
+       "whatlinkshere-prev": "ya ka’ayaway to $1",
+       "whatlinkshere-next": "{{PLURAL:$1|i kalaeno $1 ko codad}}",
+       "whatlinkshere-links": "makakaffit/matatongod",
+       "whatlinkshere-hideredirs": "$1  misafaeloh misiyor",
+       "whatlinkshere-hidetrans": "$1 micaliw",
+       "whatlinkshere-hidelinks": "$1 kakafit",
+       "whatlinkshere-hideimages": "$1 tang^an makakafit",
+       "whatlinkshere-filters": " saoo’",
+       "whatlinkshere-submit": " pidemak",
+       "ipaddressorusername": "kaitiraan no IP ano ecangangan no micokaymasay:",
+       "ipboptions": "2 tatokian:2 hours,1 romi’ad:1 day,3 romi’ad:3 days,1 lipay:1 week,2 lipay:2 weeks,1 folad:1 month,3 folad:3 months,6 folad:6 months,1 miheca:1 year,awaayay ko tolas no romi’ad:infinite",
+       "autoblocklist-submit": " saoo’",
+       "ipblocklist-submit": " saoo’",
+       "createaccountblock": " materepay  cang-haw  misanga’",
+       "blocklink": " ciker/maciker/cikeren",
+       "contribslink": "nipafelian",
+       "blocklogpage": " pikilokan to kalonicikeran",
+       "blocklogentry": "Maciker to ko [[$1]] paherekan no romi’adtangasa i $2 $3",
+       "reblock-logentry": "Somaden koya nicikeran a paherekan a romi’ad i [[$1]] tangasa i $2 $3",
+       "block-log-flags-nocreate": " materepay  cang-haw  misanga’",
+       "proxyblocker": " Saciker no micaliway a matayalay no tyin-naw",
+       "movelogpage": "o nisoritan pakayni i linah to romi’ami’ad",
+       "export": "pahadaken ko felih",
+       "allmessages-filter-all": " Maemin/po:long",
+       "allmessages-filter-submit": " pidemak",
+       "thumbnail-more": "satata’aken",
+       "import-comment": "pipatongalan to sowal",
+       "tooltip-pt-userpage": "{{GENDER:|no miso micokaymasay}} a felih",
+       "tooltip-pt-mytalk": "{{GENDER:|no miso}} kalalicayan a felih",
+       "tooltip-pt-preferences": "{{GENDER:|no miso}} o kakaolahan",
+       "tooltip-pt-watchlist": "mihinengay kiso to kafafakic nno felih imatini",
+       "tooltip-pt-mycontris": "{{GENDER:|no miso }} nipainian/ nipafelian a kamok",
+       "tooltip-pt-login": "picomod ko sanga’ayay, nika ca katoor",
+       "tooltip-pt-logout": "  mahadak",
+       "tooltip-pt-createaccount": "Miipa’icel kami i tisowanan a misanga’ to cecay a cang-haw ato micomod, ano caacaay ko tadamanay a pidemak koni.",
+       "tooltip-ca-talk": "O nikaaini to i laloma’ay a sowal no felih",
+       "tooltip-ca-edit": "misinanot to inian a felih",
+       "tooltip-ca-addsection": "miteka to faelohay a rekad",
+       "tooltip-ca-viewsource": "Ma’adipelay to konini a felih. Manga’ay kiso a songila’ a mineneng to yin-se-ma nonini a felih.",
+       "tooltip-ca-history": "O nisalofan i ka’ayaw itini tona felih",
+       "tooltip-ca-move": "linahen kona felih",
+       "tooltip-ca-watch": "patongalen i pirorodan to ’a’arawen a tilid iso kona felih",
+       "tooltip-ca-unwatch": "falahen kona felih nani pirorodan to ’a’arawen a tilid",
+       "tooltip-search": " saoo’ {{SITENAME}}",
+       "tooltip-search-go": "ano malecaday to ngangan nona felih, tayra tora felih",
+       "tooltip-search-fulltext": " saoo’ to micokaymasay tona sorit a felih",
+       "tooltip-p-logo": "tayra sa’ayayaw a felih",
+       "tooltip-n-mainpage": "tayra sa’ayayaw a felih",
+       "tooltip-n-mainpage-description": "tayra sa’ayayaw a felih",
+       "tooltip-n-portal": "ona halaka, mimaan kiso, icowa mikerato kanikawan no miso",
+       "tooltip-n-currentevents": "Itini i salaoma’ no nipainian a demak no sinpong a makera ko makakafitay malecaday a tatiri’en a demak.",
+       "tooltip-n-recentchanges": "Silsilenko ko nifalican a kamok koya itiniay i Wiki",
+       "tooltip-n-randompage": "away ko pitooran micomod sa to cecay a felih",
+       "tooltip-n-help": " pilongocan to sakidama",
+       "tooltip-t-whatlinkshere": "silsilen a maemin koya felif makakafitay tonini a felif",
+       "tooltip-t-recentchangeslinked": "Inian a felih i, makakafitay to to nifalican to no romaay o felih i mangataay a romi’ad.",
+       "tooltip-feed-atom": "O lalengatan ninian Atom a feli",
+       "tooltip-t-contributions": "{{GENDER:$1|onini micokaymasay}}to  nipainian/ nipafelian a kamok",
+       "tooltip-t-emailuser": "paefer i-miyo patongod tona {{GENDER:$1| o micokaymasay }}",
+       "tooltip-t-upload": " mipaefer to tang^an",
+       "tooltip-t-specialpages": "O kamok no po:long no ta’arawan i tyin-naw",
+       "tooltip-t-print": "Manga’ayay a lyi-inen a rorong ninian a felih.",
+       "tooltip-t-permalink": "Inian a felih i, o masalofay to a tomerepay/mada’ocay a nikakafit",
+       "tooltip-ca-nstab-main": "misongila’ a minengneng to sowal no felih",
+       "tooltip-ca-nstab-user": " misongila’ a minengneng to micokaymasay a felih",
+       "tooltip-ca-nstab-special": "O micidekay a felih no tyin-naw konini, caay ka nga’ay a mikawit.",
+       "tooltip-ca-nstab-project": "misongila’ a minengneng to halakaan a felih",
+       "tooltip-ca-nstab-image": " misongila’ a minengneng to tang’an no felih",
+       "tooltip-ca-nstab-mediawiki": " misongila’ a minengneng to si-tong no lihaf",
+       "tooltip-ca-nstab-template": " misongila’ a minengneng to sampolo",
+       "tooltip-ca-nstab-category": " misongila’ a minengneng to pisakilac/kasakilac o felih",
+       "tooltip-minoredit": " pahapinangen kona nisinanotan o sapado^do^",
+       "tooltip-save": " mina’ang to nifalican no miso",
+       "tooltip-preview": "ano mamina’ang i, ka’ayawen ho a manengneng ko nifalican iso!",
+       "tooltip-diff": "ahapinang to nifalican no miso a sowal",
+       "tooltip-compareselectedversions": "kilimen kona felih to kasasiroma no namipili’an a nisalofan",
+       "tooltip-watch": "patongalen i pirorodan to ’a’arawen a tilid iso kona felih",
+       "tooltip-rollback": " pili’en a mimi^mi ko \" patikor\" liting, ta patikor tayra i pisinanot no ka’ayaway a painiay to inian a felih",
+       "tooltip-undo": "“patiko”manga’ay patiko toya mikawitan a misorit, ato manga’ay oya sapali’ayaw a mineneng ko sapifohat toya mikawitan a misorit, ta manga’ay kiso a mitongal to lalangatan no demak i sapali’ayaw a sowal.",
+       "tooltip-summary": "pacomden ko nisa’amotoan a pakimad",
+       "simpleantispam-label": "Sapikin-sa to sata’ed to matolakaway a lihaf.\nAkaa <strong>pisorit kiso itini tona  </strong> sanay a pisoritan.",
+       "pageinfo-title": "Lihaf o \"$1\"",
+       "pageinfo-default-sort": "nipatalaan a nitonekan to sakasilsil:",
+       "pageinfo-length": " o raraya’ no felih (makakafitay a wey-yin)",
+       "pageinfo-robot-policy": "O kikay mato o tamdaw ko fana’ ko misanga’ay to tanenengan ato pikiliman",
+       "pageinfo-few-watchers": "Kisafaan ko ’aloman $1 no mikacaway",
+       "pageinfo-redirects-name": "pasayniay tona felih i, miliyaw pasayra to kahakowa no feli",
+       "pageinfo-subpages-name": "Pinaay a felih ko i kalaenoay ninian a felih",
+       "pageinfo-subpages-value": "$1 ($2 ko {{PLURAL:$2|misafaelof a misiyar palalan}};$3 ko {{PLURAL:$3|caayay ko nisafaelohan misiyor palalan}})",
+       "pageinfo-recent-edits": "o misinanotan (tona $1 a romi’ad)",
+       "pageinfo-magic-words": "ma-cit{{PLURAL:$1|sorit}} ($1)",
+       "pageinfo-hidden-categories": "o nihimedan a kasakilac ($1)",
+       "pageinfo-templates": "Micaliw micokaymas to pitodongan a sampolo  ($1)",
+       "pageinfo-toolboxlink": " o lihaf no felih",
+       "pageinfo-contentpage": "O pisa’osian to laloma’ay a sowal a felih",
+       "previousdiff": "← matela:ngay a mikawitan",
+       "nextdiff": "o faelohay a nisinanotan →",
+       "widthheightpage": "$1 × $2,$3 felih",
+       "file-info-size": "$1 × $2 ko kasapinang no siyang-su, o tata’ang no pinaro:$3,MIME kassiroma a:$4",
+       "file-info-size-pages": "$1 × $2 ko kasapinang no siyang-su, o tata’ang no pinaro:$3,MIME kassiroma a:$4,$5 {{PLURAL:$5|felih}}",
+       "file-nohires": "awaayto ko sanga’ayay a cey-si-tu malo sapafeli。",
+       "svg-long-desc": "SVG  tang^an,tata’ak no laleko:$1 × $2  syang-su no sya-sing, o tata’ak no tang^an:$3",
+       "show-big-image": " satapangan tang’an",
+       "show-big-image-preview": " o tata’ak no pa’ayaw a minengneng:$1。",
+       "show-big-image-other": " o romaay a {{PLURAL:$2||}} cyi-si-tu:$1。",
+       "show-big-image-size": "$1 × $2 ko kasapinang no siyang-su",
+       "newimages-newbies": "o nipafelian aca no faelohay cang-haw ko pahapinangen",
+       "ilsubmit": " saoo’",
+       "metadata": "mikitedal to tatiri’en",
+       "metadata-help": "Onini a tang^ani, masalaloma’ ko no roma^  a lihaf, onini a lihaf i, latek o matongalay yo mipalowaday to su-wey ka-mi-la ano eca yo  mipalowad to sapise-ken a kikay. Ano masomad ko satapangay a tang^an i, latek oya masongila’ay a tili, caay to kapasapingan itira toya masomaday to a tang^an.",
+       "metadata-fields": "Oya misilsilan pasadak a lihaf i EXIF nitadtadan a codad, maparo itira cisysingay a felih, ano ira ko nikacicih noya nitadtadan a felih i, edeng oya i kalaenoay ko mamapa’araw. O roma a nitadtadan a codad i, masimed. Caay pasadaken. \n* make\n* model\n* datetimeoriginal\n* exposuretime\n* fnumber\n* isospeedratings\n* focallength\n* artist\n* copyright\n* imagedescription\n* gpslatitude\n* gpslongitude\n* gpsaltitude",
+       "exif-orientation": "O pasayraan",
+       "exif-xresolution": "cyi-si-tu no rimadac no nanom",
+       "exif-yresolution": "mecel nani faled cey-si-tu",
+       "exif-datetime": " pisalof to tang’an a romi’ad toki",
+       "exif-make": "misanga’ay to kamila a kosi",
+       "exif-model": " fangko no kamila to kasasiroma no lalosidan",
+       "exif-software": "Luwan-ti to sakatayal",
+       "exif-artist": "O misoritay",
+       "exif-exifversion": "Exif rorong no codad",
+       "exif-colorspace": "o lahad pitilidan",
+       "exif-datetimeoriginal": "o kairaan no tatiri’en a romi’ad toki",
+       "exif-datetimedigitized": " so romi’ad toki no u-wey-hwa",
+       "exif-source": "lalengatan",
+       "exif-iimcategory": "pisakilac",
+       "exif-orientation-1": " salongan",
+       "exif-contrast-0": " salongan",
+       "exif-saturation-0": " salongan",
+       "exif-sharpness-0": " salongan",
+       "namespacesall": " Maemin/po:long",
+       "monthsall": " Maemin/po:long",
+       "confirm-watch-top": "patongalen i pirorodan to ’a’arawen a tilid iso kona felih?",
+       "confirm-unwatch-top": "falahen kona felih nani pirorodan to ’a’arawen a tilid?",
+       "imgmultigo": " pidemak",
+       "imgmultigoto": "tayra i saka $1 a felih",
+       "img-lang-go": " pidemak",
+       "table_pager_limit_submit": " pidemak",
+       "watchlistedit-raw-title": " misinanot to satapangan no pirorodan to tatapalen a tilid",
+       "watchlisttools-view": "misongila’ a minengneng to pakayniay i   falic",
+       "watchlisttools-edit": " misongila’ a minengneng ato misinanot  to pirorodan to tatapalen a tilid",
+       "watchlisttools-raw": " misinanot to satapangan no pirorodan to tatapalen a tilid",
+       "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1| kalalicay]])",
+       "version-specialpages": " micidekay a felih",
+       "version-ext-colheader-description": " kimad",
+       "version-libraries-description": " kimad",
+       "redirect": "Do^doen ko tang^an, o micokaymasay, o felih, o pisalof ato ID no nikilokan a misafaeloh misiyor",
+       "redirect-summary": "Onini micidekay a pi’arawan i tyin-naw manga’ay a misafaeloh misiyor patayra i tang^an (nipatonekan a ngangan no tang^an), o felih ( nipatonekan misalof a ID ano eca o ID no felih), macokaymasay a felih ( mapatonekay a ID no micokaymasay)、ano eca o kasasiroma no nikilokan( nipatonekan a ID no nikilokan)。O sapilaheci a micokaymas: [[{{#Special:Redirect}}/file/Example.jpg]]、[[{{#Special:Redirect}}/page/64308]]、[[{{#Special:Redirect}}/revision/328429]]、[[{{#Special:Redirect}}/user/101]] ano eca [[{{#Special:Redirect}}/logid/186]]。",
+       "redirect-submit": " pidemak",
+       "redirect-revision": " o pisalof ID no felih",
+       "fileduplicatesearch-submit": " saoo’",
+       "specialpages": " micidekay a felih",
+       "tag-filter": "[[Special:Tags|sakacipinang a ’otoc]] misolap:",
+       "tag-list-wrapper": "([[Special:Tags|$1 sakacipinang a ’otoc]]:$2)",
+       "tag-mw-rollback": " patatikol",
+       "tag-mw-undo": " patikor",
+       "tags-source-header": "lalengatan",
+       "tags-edit": "misinanot",
+       "tags-create-submit": " misanga’",
+       "permanentlink": "tomerepay tongod",
+       "htmlform-cloner-delete": "falah",
+       "logentry-delete-delete": "$1 masopitay to a felih $3",
+       "logentry-delete-restore": "$1{{GENDER:$2| patiko }} o felih  $3($4)",
+       "logentry-delete-revision": "$1 {{GENDER:$2|masomaday to }} ko felih no $3 ilaloma’ {{PLURAL:$5|1 nisalofan |$5 nisalofan }}i felih no:$4",
+       "logentry-move-move": "$1 {{GENDER:$2|malinah to}} ko felih nani $3 tangasa i $4",
+       "logentry-move-move-noredirect": "$1 {{GENDER:$2|malinah to }} ko felih nani  $3 tangsa i $4,caay safaelohen misiyor",
+       "logentry-move-move_redir": "$1 malinah to kona felih nani $3 tangsa $4 oroma sato matahepo koya nisafaelohan misiyor",
+       "logentry-patrol-patrol-auto": "$1 milonok to {{GENDER:$2| sapahapinang }} a felih  $3 to nisalofan i  $4 o masolapay to",
+       "logentry-newusers-newusers": "Ma-{{GENDER:$2| sanga’ay to }} ko cang-haw no micokaymasay $1",
+       "logentry-newusers-create": "Ma-{{GENDER:$2| sanga’ay to }} ko cang-haw no micokaymasay $1",
+       "logentry-newusers-autocreate": "Lonok sanay to {{GENDER:$2| misanga’ }} ko cang-haw no micokaymasay $1",
+       "logentry-upload-upload": "$1 {{GENDER:$2|mapaefer to}} $3",
+       "logentry-upload-overwrite": "$1 {{GENDER:$2|mapaefer to}} faelohay\n rorong no $3",
+       "logentry-upload-revert": "$1 {{GENDER:$2|mapaefer to}} $3",
+       "feedback-cancel": "Sawaden miforic",
+       "searchsuggest-search": " saoo’ {{SITENAME}}",
+       "duration-days": "$1 romi’ad",
+       "log-action-filter-all": " Maemin/po:long",
+       "log-action-filter-block-block": " ciker/maciker/cikeren",
+       "authmanager-userdoesnotexist": "Caay ho ka hayda ko pipangangan a cang-haw no micokaymasay \"$1\"."
+}
index 3e54a4a..6e2147d 100644 (file)
        "logempty": "No bi ha garra elemento en o rechistro con ixas carauteristicas.",
        "log-title-wildcard": "Mirar títols que prencipien con iste texto",
        "allpages": "Todas as pachinas",
-       "nextpage": "Siguient pachina ($1)",
+       "nextpage": "Pachina siguient ($1)",
        "prevpage": "Pachina anterior ($1)",
        "allpagesfrom": "Amostrar as pachinas que prencipien por:",
        "allpagesto": "Amostrar as pachinas que rematen en:",
        "whatlinkshere": "Pachinas que enlazan con ista",
        "whatlinkshere-title": "Pachinas que tienen vinclos ta $1",
        "whatlinkshere-page": "Pachina:",
-       "linkshere-2": "As siguients pachinas tienen vinclos enta '''$1''':",
-       "nolinkshere-2": "Garra pachina tiene vinclos ta '''$1'''.",
-       "nolinkshere-ns-2": "Garra pachina d'o espacio de nombres trigato tiene vinclos ta '''$1'''.",
+       "linkshere": "As siguients pachinas tienen vinclos enta '''$2''':",
+       "nolinkshere": "Garra pachina tiene vinclos ta '''$2'''.",
+       "nolinkshere-ns": "Garra pachina d'o espacio de nombres trigato tiene vinclos ta '''$2'''.",
        "isredirect": "pachina reendrezata",
        "istemplate": "incluyida",
        "isimage": "Vinclo ta un fichero",
        "markedaspatrollederror-noautopatrol": "No tiene premisos ta sinyalar os suyos propios cambios como controlatos.",
        "patrol-log-page": "Rechistro de control de revisions",
        "patrol-log-header": "Iste ye un rechistro de revisions patrullatas.",
-       "log-show-hide-patrol": "$1 o rechistro de patrullache",
        "deletedrevision": "S'ha borrato a versión antiga $1",
        "filedeleteerror-short": "Error borrando o fichero: $1",
        "filedeleteerror-long": "Se troboron errors borrando o fichero:\n\n$1",
index e833c1b..f0fe020 100644 (file)
        "whatlinkshere": "Hwæt hæfþ hlencan hider",
        "whatlinkshere-title": "Trametas þā habbaþ hlencan tō \"$1\"",
        "whatlinkshere-page": "Tramet:",
-       "linkshere-2": "Þā folgiendan trametas habbaþ hlencan tō: '''$1'''",
-       "nolinkshere-2": "Nǣnge trametas habbaþ hlencan tō '''$1'''.",
+       "linkshere": "Þā folgiendan trametas habbaþ hlencan tō: '''$2'''",
+       "nolinkshere": "Nǣnge trametas habbaþ hlencan tō '''$2'''.",
        "isredirect": "edlǣdunge tramet",
        "istemplate": "bysene nytt",
        "isimage": "ymelan hlenca",
index 8382f17..5578f49 100644 (file)
        "whatlinkshere": "एन्जां की जुड़तै",
        "whatlinkshere-title": "$1 सं॑ जुड़लऽ पन्ना",
        "whatlinkshere-page": "पन्ना:",
-       "linkshere-2": "नीचे के सब पन्ना '''$1''' स॑ जुड़लऽ:",
-       "nolinkshere-2": "<strong>$1</strong> स॑ कोय भी पन्ना नै जुड़लऽ छै।",
+       "linkshere": "नीचे के सब पन्ना '''$2''' स॑ जुड़लऽ:",
+       "nolinkshere": "<strong>$2</strong> स॑ कोय भी पन्ना नै जुड़लऽ छै।",
        "isredirect": "पुन: निर्दिष्ट पन्ना",
        "istemplate": "मिलाबऽ",
        "isimage": "फाइल लिंक",
index 97b37ff..a6273c5 100644 (file)
@@ -74,7 +74,8 @@
                        "Aboulouei1",
                        "سامي الرحيلي",
                        "Azouz.anis",
-                       "Elbasyouny"
+                       "Elbasyouny",
+                       "Omar Ghrida"
                ]
        },
        "tog-underline": "سطر تحت الوصلات:",
        "resetpass-submit-loggedin": "تغيير كلمة السر",
        "resetpass-submit-cancel": "إلغاء",
        "resetpass-wrong-oldpass": "كلمة سر حالية أو مؤقتة غير صحيحة.\nربما تكون غيرت كلمة السر الخاصة بك بنجاح أو طلبت كلمة سر مؤقتة جديدة.",
-       "resetpass-recycled": "اÙ\84رجاء Ø¥Ø¹Ø§Ø¯Ø© ØªØ¹Ù\8aÙ\8aÙ\86 كلمة السر الخاصة بك إلى تركيبة أخرى غير كلمة السر الحالية.",
+       "resetpass-recycled": "اÙ\84رجاء ØªØºÙ\8aÙ\8aر كلمة السر الخاصة بك إلى تركيبة أخرى غير كلمة السر الحالية.",
        "resetpass-temp-emailed": "أنت مسجل الدخول حالياً بتركيبة مرسلة عبر البريد الإلكتروني. لإكمال عملية تسجيل الدخول‘ يجب إعادة تعيين كلمة السر هنا:",
        "resetpass-temp-password": "كلمة سر مؤقتة:",
        "resetpass-abort-generic": "منعت مُلحقة إتمام صيرورة تغيير كلمة السّر.",
        "resetpass-expired": "انتهت مدة صلاحية كلمة السر الخاصة بك. الرجاء تعيين كلمة سر جديدة لتسجيل الدخول.",
-       "resetpass-expired-soft": "انتهت مدة صلاحية كلمة السر الخاصة بك. الرجاء تعيين كلمة سر جديدة الآن أو النقر على زر إلغاء لإعادة تعيين كلمة السر لاحقاً.",
+       "resetpass-expired-soft": "انتهت مدة صلاحية كلمة السر الخاصة بك; الرجاء تغيير كلمة سر جديدة الآن أو النقر على زر إلغاء لإعادة تعيين كلمة السر لاحقاً.",
        "resetpass-validity-soft": "كلمة السر الخاصة بك غير صالحة :  $1 \n\nرجاءا اختر كلمة سر جديدة الآن، أو انقر فوق \"{{int:authprovider-resetpass-skip-label}}\" لتغييرها في وقت لاحق.",
        "passwordreset": "إعادة ضبط كلمة السر",
        "passwordreset-text-one": "أكمل هذا النموذج لإعادة ضبط كلمة السر الخاصة بك.",
        "converter-manual-rule-error": "خطأ تم اكتشافه في قاعدة تحويل اللغة اليدوية",
        "undo-success": "يمكن استرجاع التعديل.\nتحقق من المقارنة بالأسفل للتأكد من أن هذا هو ما تريد أن تفعله، ثم احفظ التغييرات بالأسفل للانتهاء من استرجاع التعديل.",
        "undo-failure": "لم يمكن استرجاع التعديل بسبب تعديلات متعارضة تمت على الصفحة.",
+       "undo-main-slot-only": "لا يمكن التراجع عن التعديل لأنه ينطوي على محتوى خارج الفتحة الرئيسية.",
        "undo-norev": "فشل في الرجوع عن التعديل حيث أنه غير موجود أو تم حذفه.",
        "undo-nochange": "التعديل يبدو أنه قد تم الترجع عنه بالفعل.",
        "undo-summary": "الرجوع عن التعديل $1 بواسطة [[Special:Contributions/$2|$2]] ([[User talk:$2|نقاش]])",
        "diff-paragraph-moved-toold": "الفقرة تم نقلها. اضغط للذهاب للموقع القديم.",
        "difference-missing-revision": "{{PLURAL:$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": "نص الصفحة يطابق",
        "group-autoconfirmed": "مستخدمون مؤكدون تلقائيا",
        "group-bot": "بوتات",
        "group-sysop": "إداريون",
+       "group-interface-admin": "إداريو الواجهة",
        "group-bureaucrat": "بيروقراطيون",
        "group-suppress": "مزيلون",
        "group-all": "(الكل)",
        "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-editusercss": "تعديل ملفات CSS للمستخدمين الآخرين",
        "right-edituserjson": "تعديل ملفات جسون للمستخدمين الآخرين",
        "right-edituserjs": "تعديل ملفات جافاسكريبت للمستخدمين الآخرين",
+       "right-editsitecss": "تعديل CSS على مستوى الموقع",
+       "right-editsitejson": "تعديل جسون على مستوى الموقع",
+       "right-editsitejs": "تعديل جافاسكريبت على مستوى الموقع",
        "right-editmyusercss": "تعديل ملفات CSS للمستخدم نفسه",
        "right-editmyuserjson": "تعديل ملفات جسون للمستخدم نفسه",
        "right-editmyuserjs": "تعديل ملفات جافاسكربت للمستخدم نفسه",
        "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-savedqueries-rename": "أعد التسمية",
        "rcfilters-savedqueries-setdefault": "حفظ كقيمة افتراضية",
        "rcfilters-savedqueries-unsetdefault": "إزالة القيمة الافتراضية",
-       "rcfilters-savedqueries-remove": "أزÙ\84",
+       "rcfilters-savedqueries-remove": "حذÙ\81",
        "rcfilters-savedqueries-new-name-label": "الاسم",
        "rcfilters-savedqueries-new-name-placeholder": "صف الغرض من المرشح",
        "rcfilters-savedqueries-apply-label": "أنشئ مرشحا",
        "rcfilters-empty-filter": "لا مرشحات فعالة. كل المساهمات معروضة.",
        "rcfilters-filterlist-title": "مرشحات",
        "rcfilters-filterlist-whatsthis": "كيف تعمل هذه؟",
-       "rcfilters-filterlist-feedbacklink": "أخبرنا ما رأيك حول هذه المرشحات (الجديدة)",
+       "rcfilters-filterlist-feedbacklink": "أخبرنا ما رأيك حول هذه المرشحات",
        "rcfilters-highlightbutton-title": "التعليم على النتائج",
        "rcfilters-highlightmenu-title": "اختر لونًا",
        "rcfilters-highlightmenu-help": "اختر لونا للتعليم على هذه الخاصية",
        "rcfilters-watchlist-showupdated": "التغييرات للصفحات التي لم تزرها منذ حدوث التغييرات تكون <strong>بالخط العريض</strong>، مع علامات صلبة.",
        "rcfilters-preference-label": "أخف النسخة المحسنة من أحدث التغييرات",
        "rcfilters-preference-help": "يسترجع عملية إعادة تصميم الواجهة لعام 2017 وكل الأدوات التي أضيفت منذ ذلك الوقت.",
+       "rcfilters-watchlist-preference-label": "إخفاء النسخة المحسنة من قائمة المراقبة",
+       "rcfilters-watchlist-preference-help": "يتراجع عن إعادة تصميم واجهة عام 2017 وجميع الأدوات التي تمت إضافتها منذ ذلك الحين.",
        "rcfilters-filter-showlinkedfrom-label": "عرض التغييرات في الصفحات الموصولة من",
        "rcfilters-filter-showlinkedfrom-option-label": "<strong>الصفحات الموصولة من</strong> الصفحة المختارة",
        "rcfilters-filter-showlinkedto-label": "عرض التغييرات في الصفحات الموصولة بصفحة",
        "speciallogtitlelabel": "الهدف (عنوان أو {{ns:user}}:اسم المستخدم للمستخدم):",
        "log": "سجلات",
        "logeventslist-submit": "أظهر",
+       "logeventslist-more-filters": "إظهار السجلات الإضافية:",
+       "logeventslist-patrol-log": "سجل الخفر",
+       "logeventslist-tag-log": "سجل الوسم",
        "all-logs-page": "كل السجلات العامة",
        "alllogstext": "عرض شامل لكل السجلات المتوفرة في {{SITENAME}}.\nباستطاعتك جعل القائمة أكثر تحديداً، وذلك باختيار نوع السجل واسم المستخدم (حساس لحالة الحروف)، أو الصفحة المتأثرة (أيضاً حساس لحالة الحروف).",
        "logempty": "لا توجد مدخلات مطابقة في السجل.",
        "dellogpage": "سجل الحذف",
        "dellogpagetext": "بالأسفل قائمة بأحدث عمليات الحذف.",
        "deletionlog": "سجل الحذف",
+       "log-name-create": "سجل إنشاء الصفحات",
+       "log-description-create": "فيما يلي قائمة بأحدث عمليات إنشاء الصفحات.",
+       "logentry-create-create": "$1 {{GENDER:$2|أنشأ|أنشأت}} صفحة $3",
        "reverted": "استرجع لنسخة أقدم",
        "deletecomment": "السبب:",
        "deleteotherreason": "سبب آخر/إضافي:",
        "uctop": "(حالية)",
        "month": "من شهر (وأقدم):",
        "year": "من سنة (وأقدم):",
+       "date": "من تاريخ (وأقدم).",
        "sp-contributions-newbies": "اعرض مساهمات الحسابات الجديدة فقط",
        "sp-contributions-newbies-sub": "للحسابات الجديدة",
        "sp-contributions-newbies-title": "مساهمات المستخدم للحسابات الجديدة",
        "whatlinkshere": "ماذا يصل هنا",
        "whatlinkshere-title": "الصفحات التي تصل إلى \"$1\"",
        "whatlinkshere-page": "الصفحة:",
-       "linkshere-2": "الصفحات التالية تصل إلى '''$1''':",
-       "nolinkshere-2": "لا توجد صفحات تصل إلى '''$1'''.",
-       "nolinkshere-ns-2": "لا تصل أي صفحة إلى '''$1''' في النطاق المختار.",
+       "linkshere": "الصفحات التالية تصل إلى <strong>$2</strong>:",
+       "nolinkshere": "لا توجد صفحات تصل إلى <strong>$2</strong>.",
+       "nolinkshere-ns": "لا توجد صفحات تصل إلى <strong>$2</strong> في النطاق المختار.",
        "isredirect": "صفحة تحويل",
        "istemplate": "مضمن",
        "isimage": "وصلة ملف",
        "markedaspatrollederrornotify": "لم ينجح وسم هذه النسخة بأنها مراجعة",
        "patrol-log-page": "سجل الخفر",
        "patrol-log-header": "هذا سجل بالمراجعات المراجعة.",
-       "log-show-hide-patrol": "$1 سجل الخفر",
-       "log-show-hide-tag": "$1 سجل الوسوم",
        "confirm-markpatrolled-button": "موافق",
        "confirm-markpatrolled-top": "علم على المراجعة $3 من $2 كمراجعة؟",
        "deletedrevision": "حذف المراجعة القديمة $1",
index 15b1e3e..9c910c2 100644 (file)
        "whatlinkshere": "ܡܐ ܐܣܪ ܠܗܪܟܐ",
        "whatlinkshere-title": "ܦܐܬܬ̈ܐ ܕܐܣܝܪܝܢ ܥܡ \"$1\"",
        "whatlinkshere-page": "ܦܐܬܐ:",
-       "linkshere-2": "ܦܐܬܬ̈ܐ ܗܠܝܢ ܐܣܝܪܝܢ ܥܡ '''$1''':",
-       "nolinkshere-2": "ܠܝܬ ܦܐܬܬ̈ܐ ܐܣܪܝܢ ܥܡ '''$1'''.",
-       "nolinkshere-ns-2": "ܠܝܬ ܦܐܬܬ̈ܐ ܐܣܪܝܢ ܥܡ '''$1''' ܒܚܩܠܐ ܓܒܝܐ.",
+       "linkshere": "ܦܐܬܬ̈ܐ ܗܠܝܢ ܐܣܝܪܝܢ ܥܡ '''$2''':",
+       "nolinkshere": "ܠܝܬ ܦܐܬܬ̈ܐ ܐܣܪܝܢ ܥܡ '''$2'''.",
+       "nolinkshere-ns": "ܠܝܬ ܦܐܬܬ̈ܐ ܐܣܪܝܢ ܥܡ '''$2''' ܒܚܩܠܐ ܓܒܝܐ.",
        "isredirect": "ܦܐܬܐ ܕܨܘܝܒܐ",
        "istemplate": "ܚܒܝܫܬܐ",
        "isimage": "ܐܣܘܪܐ ܕܠܦܦܐ",
        "markedaspatrollednotify": "ܫܘܚܠܦܐ ܗܢܐ ܥܠ $1 ܐܫܬܘܕܥ ܐܝܟ ܟܪܝܟܐ.",
        "markedaspatrollederrornotify": "ܠܐ ܐܬܢܨܚ ܫܘܘܕܥܐ ܐܝܟ ܟܪܝܟܬܐ",
        "patrol-log-page": "ܣܓܠܐ ܕܟܪܟܐ",
-       "log-show-hide-patrol": "$1 ܣܓܠܐ ܕܟܪܟܐ",
        "filedeleteerror-short": "ܦܘܕܐ ܒܫܝܦܐ ܕܠܦܦܐ: $1",
        "filedeleteerror-long": "ܦܘܕ̈ܐ ܐܫܟܚܬ ܟܕ ܫܝܦܐ ܠܦܦܐ:\n\n$1",
        "previousdiff": "← ܫܘܚܠܦܐ ܕܩܕܡ",
index 1ca78c1..98c4d62 100644 (file)
        "whatlinkshere": "Lasulu faw püle",
        "whatlinkshere-title": "Wülngiñ nülkükawlelu \"$1\"",
        "whatlinkshere-page": "Pakina:",
-       "linkshere-2": "Tüfachi wülngiñ nülkükawley '''$1''':",
-       "nolinkshere-2": "Chem wülngiñ no rume nülkükawlelu '''$1'''.",
+       "linkshere": "Tüfachi wülngiñ nülkükawley '''$2''':",
+       "nolinkshere": "Chem wülngiñ no rume nülkükawlelu '''$2'''.",
        "isredirect": "wüñongünen wülngiñ",
        "istemplate": "yomtukudungu",
        "isimage": "Adentun lasun",
index 0367678..3aa0599 100644 (file)
@@ -8,7 +8,8 @@
                        "GeekEmad",
                        "Macofe",
                        "Mekakem",
-                       "Vikoula5"
+                       "Vikoula5",
+                       "Qchmqs"
                ]
        },
        "tog-underline": "تسطار الوصيلات:",
@@ -38,7 +39,7 @@
        "tog-shownumberswatching": "بين شحال كاين من مستعمل يتبع الباجه",
        "tog-oldsig": "خطّ‘ اليدّ تاعك الي كاين:",
        "tog-fancysig": "اعتبر التوقيع كي كتيبه ويكي (بلا وصيله توماتيك)",
-       "tog-uselivepreview": "استعمل الشوفة الخفيفة",
+       "tog-uselivepreview": "وري تشوف بلا ماتعاود تطلع الپاجة",
        "tog-forceeditsummary": "نبّهني كي تندخل كاش صفحة خاوية",
        "tog-watchlisthideown": "خبّي الـتبدالات تاوعي فل ليستة تاع الـتتباع",
        "tog-watchlisthidebots": "خبّي الـتبدالات تاع الـروبويات فل ليستة تاع التتباع تاعي",
        "nosuchusershort": "ما كاين حتا مستعملي ب` السميّة \"$1\".\nأكّد على الكتيبة تاعك.",
        "nouserspecified": "لازم لك تمدّ السميّة تاع المستعملي.",
        "login-userblocked": "هاد السميّة تاع المستعملي راهي مطرودة. تسجال` الدخول ماشي مسموح.",
-       "wrongpassword": "كلمت` السرّ المدخّلة ما راهيشي صحيحة.\nالله يسترك عاود سيّي.",
+       "wrongpassword": "او غالط الأسم ولا الكود لي دخلتهم\nتعيش عاود سيي.",
        "wrongpasswordempty": "كلمت` السرّ كانت خاوية.\nالله يعيّشك عاود سيّي.",
        "passwordtooshort": "كلمت` السرّ لازم يكون فيها على القل {{PLURAL:$1|1 حرف واحد|$1 حروف}}.",
        "passwordtoolong": "كلمت` السرّ ما تنجمش تكون طويلة على {{PLURAL:$1|1 حرف واحد|$1 حرف}}.",
-       "passwordtoopopular": "Ù\83Ù\84Ù\85ات Ø§Ù\84Ù\85رÙ\88ر Ø§Ù\84شاÙ\8aعة Ù\85ا Ù\8aÙ\85Ù\83Ù\86Ø´ Ø§Ø³ØªØ®Ø¯Ø§Ù\85Ù\87ا. Ù\85Ù\86 Ù\81ضÙ\84Ù\83  Ø®Ù\8aÙ\91ر Ù\83Ù\84Ù\85Ø© Ø³Ø± Ø³Ø¨Ù\8aسÙ\8aاÙ\84.",
+       "passwordtoopopular": "Ù\85اتÙ\82دش ØªØ¯Ù\8aر Ù\83Ù\88د Ù\85Ù\86 Ø§Ù\84شاÙ\8aعÙ\8aÙ\86 (Ù\86اس Ù\83Ù\84 Ù\8aدÙ\8aرÙ\88 Ù\83Ù\8aÙ\81Ù\87Ù\85). ØªØ¹Ù\8aØ´ Ø¯Ù\8aر Ù\83Ù\88د ØªØ§Ø¹Ù\83 Ù\88حدÙ\83 Ù\88Ù\85اشÙ\8a Ø³Ø§Ù\87Ù\84 Ø¨Ø§Ø´ Ù\8aÙ\81Ù\8aÙ\82Ù\88Ù\84Ù\83 Ø¨Ù\8aÙ\87.",
        "password-name-match": "كلمت` السرّ تاعك لازم لها تكون مبدّلة على سميّت` المستعملي تاعك.",
        "password-login-forbidden": "الستعملية تاع هاد السميّة تاع المستعملي و كلمت` السرّ راهم ممنوعين.",
        "mailmypassword": "استرجع كلمت` السرّ",
        "botpasswords-existing": "كلمات سر البوت اللي كاينة",
        "botpasswords-createnew": "صناعة كلمة سر جديدة للبوت",
        "botpasswords-editexisting": "تعديل كلمة سر موجودة للبوت",
+       "botpasswords-label-needsreset": "(لكود لازم يتبدل)",
        "botpasswords-label-appid": "آسم البوت:",
        "botpasswords-label-create": "أصنع",
        "botpasswords-label-update": "حدّث / ميزاجور",
        "botpasswords-updated-title": "كلمت` السرّ تاع البوت راهي ندارت لها الميزاجور",
        "botpasswords-deleted-title": "كلمت` السرّ تاع البوت تفاصات",
        "resetpass_forbidden": "كلمت` السرّ ما تنجمش تتبدّل",
-       "resetpass_forbidden-reason": "Ù\83Ù\84Ù\85ت` Ø§Ù\84سرÙ\91 Ù\85ا ØªÙ\86جÙ\85Ø´ ØªØªØ¨Ø¯Ù\91Ù\84",
+       "resetpass_forbidden-reason": "Ù\84Ù\83Ù\88د Ù\84Ù\8a Ù\85اتÙ\82دش ØªØ¨Ø¯Ù\84Ù\87Ù\85 :$1",
        "resetpass-no-info": "لازم لك تكون مسجّل الدخول باش تلحق ل هاد الپاجة.",
        "resetpass-submit-loggedin": "بدّل كلمت` السرّ",
        "resetpass-submit-cancel": "بطّل",
        "resetpass-wrong-oldpass": "كلمت` سرّ ماشي مقبولة.\nبالاك راك بدّلتها ولا طلبت كاش كلمت` سرّ مأقّتة.",
-       "resetpass-recycled": "اÙ\84Ù\84Ù\87 Ù\8aØ®Ù\84Ù\91Ù\8aÙ\83 Ø¨Ø¯Ù\91Ù\84 Ù\83Ù\84Ù\85ت` Ø§Ù\84سرÙ\91 ØªØ§Ø¹Ù\83 Ø¨ Ø­Ø§Ø¬Ø© Ù\85Ù\86 ØºÙ\8aر Ø§Ù\84حاجة Ø§Ù\84Ù\91Ù\8a Ø±Ø§Ù\83 Ø¯Ø§Ù\8aرÙ\87ا Ø¶Ø±Ù\83ا.",
+       "resetpass-recycled": "تعÙ\8aØ´ Ø¯Ù\8aر Ù\83Ù\88د Ù\88حداخر Ù\85اشÙ\8a Ø²Ù\8a Ù\84Ù\8a Ø±Ø§Ù\83 Ø¯Ø§Ù\8aرÙ\88 Ø¶Ù\83.",
        "resetpass-temp-emailed": "راك سجّلت الدخول تاعك ب كود مأقّت مبعوت ليك ب إيمال. باش تكمّل الدخول لل پاجات لخرين، لازم لك تختار كلمت` سرّ جديدة هنا:",
        "resetpass-temp-password": "كلمت` سرّ مأقّتة:",
        "resetpass-abort-generic": "التبدال تاعع كلمت` السرّ راه تحبّس علاجال وحد المزيودة (extension).",
        "search-result-category-size": "$1 عضو{{PLURAL:$1||s}} ($2 كاتيكورى فرعيه{{PLURAL:$2||s}}, $3 فيشيي{{PLURAL:$3||يات}})",
        "search-redirect": "(تحويل من $1)",
        "search-section": "(قسمت‘ $1)",
+       "search-file-match": "(كيما الدخلاني تاع الفيشي)",
        "search-suggest": "كنت باغي تقول: $1",
        "searchrelated": "مرتابطه",
        "searchall": "ألكل",
        "recentchanges": "التبدالات الاخّرة",
        "recentchanges-legend": "واش تختار ف`التبدالات التوالا",
        "recentchanges-summary": "اجبر التبدالات اللواخر الّي صراو ف هاد الصفحة.",
+       "recentchanges-noresult": "مكاش حتى تبدال في الوقت لي مخير كيما وش تحوس",
        "recentchanges-feed-description": "تبع التبديلات الجدد للويكي في هاذ التيار .",
        "recentchanges-label-newpage": " هاد التبدال راه صنع باجة جديدة",
        "recentchanges-label-minor": "هاذا تبديل صغير",
        "whatlinkshere": "شنوّ يوصّل ل هنا",
        "whatlinkshere-title": "الباجات اللي تقين في \"$1\"",
        "whatlinkshere-page": "الباجه:",
-       "linkshere-2": "هاذ الباجات يوصلو إلى '''$1''':",
-       "nolinkshere-2": "ما كانش  باجه فيها وصيله ل'''$1'''.",
+       "linkshere": "هاذ الباجات يوصلو إلى '''$2''':",
+       "nolinkshere": "ما كانش  باجه فيها وصيله ل'''$2'''.",
        "isredirect": "باجت تحويل",
        "istemplate": "تضمين",
        "isimage": "وصيلة ملف",
        "htmlform-yes": "إيه",
        "logentry-delete-delete": "$1 {{GENDER:$2| راه محا|راهي محات}}الصفحة $3",
        "logentry-move-move": "{{GENDER:$2|نقّل|نقّلت}} $1 الصفحة $3 لـ $4",
+       "logentry-move-move-noredirect": "{{GENDER:$2|هز|هزت}} $1 صفحة $3 لل $4 بلا {{GENDER:$2|ميخلي|متخلي}} رديركسيون",
        "logentry-newusers-create": "راه تفتح حساب {{GENDER:$2|المستخدم|المستخدمه}} $1",
        "logentry-upload-upload": " {{GENDER:$2|نزّل|نزّلت}} $1 $3",
        "feedback-error2": "غلطة: تبديلتك ما صلحتش",
index c412556..135dca5 100644 (file)
@@ -11,7 +11,8 @@
                        "Macofe",
                        "MtDu",
                        "Abdeaitali",
-                       "Reda Benkhadra"
+                       "Reda Benkhadra",
+                       "Anass Sedrati"
                ]
        },
        "tog-underline": "Ṣetter l-lyanaṫ:",
        "editfont-monospace": "ĥtt tabit lġarḍ",
        "editfont-sansserif": "ĥtt  ba ziyada",
        "editfont-serif": "kht bzwayd",
-       "sunday": "L-Ḫed",
-       "monday": "Ṫ-Ṫnin",
+       "sunday": "لحد",
+       "monday": "تنين",
        "tuesday": "Ṫ-Ṫlaṫ",
        "wednesday": "L-Arbeĝ",
        "thursday": "L-Ĥmis",
-       "friday": "J-Jemĝa",
-       "saturday": "S-Sebṫ",
+       "friday": "جمعا",
+       "saturday": "سبت",
        "sun": "Ḫed",
        "mon": "Ṫnin",
        "tue": "Ṫlaṫ",
        "wed": "Arbeĝ",
        "thu": "Ĥmis",
-       "fri": "Jemĝa",
-       "sat": "Sebṫ",
+       "fri": "جمعا",
+       "sat": "سبت",
        "january": "Yanayer",
-       "february": "Febrayer",
+       "february": "فبراير",
        "march": "Mars",
        "april": "Abril",
        "may_long": "May",
@@ -83,7 +84,7 @@
        "october": "Okṫober",
        "november": "Nowanbir",
        "december": "Dojanbir",
-       "january-gen": "Yanayer",
+       "january-gen": "يناير",
        "february-gen": "Febrayer",
        "march-gen": "Mars",
        "april-gen": "Abril",
        "navigation-heading": "قائمة ديال التصفح",
        "errorpagetitle": "ĥata'",
        "returnto": "Rjeĝ le $1",
-       "tagline": "Men {{SITENAME}}",
-       "help": "Mosaĝada",
-       "search": "Qelleb",
-       "searchbutton": "Qelleb",
+       "tagline": "من {{SITENAME}}",
+       "help": "معاونة",
+       "search": "قلّب",
+       "searchbutton": "قلّب",
        "go": "Sir",
        "searcharticle": "Sir",
        "history": "Ṫariĥ ṣ-ṣefḫa",
        "printableversion": "Vérsyon imkenliha ṫṫetbeĝ",
        "permalink": "Lyan dayem",
        "print": "tbeĝ",
-       "view": "ċof",
-       "edit": "Ṣayeb",
+       "view": "شوف",
+       "edit": "صايب",
        "create": "Ĥṫareĝ",
        "delete": "Mḫi",
        "undelete_short": "strjaa {{PLURAL:$1|wahd taadil|$1 taadil}}",
        "lastmodifiedat": ".آخر مرة تعدلات فيها هاذ الصفحة كان نهار $1، الساعة $2",
        "viewcount": "had sfha tchaft {{PLURAL:$1|wa7d lmrra|$1 mrra}}.",
        "protectedpage": "Ṣefḫa mhmiya",
-       "jumpto": "Sir le:",
+       "jumpto": "سير ل:",
        "jumptonavigation": "Navigasyon",
-       "jumptosearch": "Qelleb",
+       "jumptosearch": "قلّب",
        "view-pool-error": "smh lina serveurat ayana\nbzzaf dlmostakhdimin bghaw iwslo lhad sfha\naafak hawl mn ba3d wahd chwiya\n\n$1",
        "pool-timeout": "Daz l-weqṫ faċ konṫi kaṫṫsenna z-zeqron",
        "pool-queuefull": "Ṣeff l-ĥedma ĝamṛa",
        "currentevents-url": "Project:ahdat  jariya",
        "disclaimers": "Inḍaraṫ",
        "disclaimerpage": "Project:Inḍaraṫ ĝammin",
-       "edithelp": "Mosaĝada",
-       "mainpage": "Ṣ-Ṣefḫa l-owla",
+       "edithelp": "معاونة",
+       "mainpage": "صفحة لولا",
        "mainpage-description": "Ṣ-Ṣefḫa l-owla",
        "policy-url": "Project:siyassa",
        "portal": "bwabt lmojtamaaa",
        "editlink": "ṣayeb",
        "viewsourcelink": "Ċof l-ĝin",
        "editsectionhint": "Ṣayeb s-séksyon : $1",
-       "toc": "L-Meḍmon",
+       "toc": "لمضمون",
        "showtoc": "Werri",
        "hidetoc": "Ḫebbi",
        "collapsible-collapse": "twi",
        "page-atom-feed": "L-Flu Atom dyal \"$1\"",
        "feed-atom": "Atom",
        "feed-rss": "RSS",
-       "red-link-title": "$1 (ṣefḫa ma kaynaċ)",
+       "red-link-title": "$1 (صفحة ما كايناش)",
        "sort-descending": "ṛṫṫḅ b-ttloĝ",
        "sort-ascending": "ṛṫṫḅ b-lhḅot",
-       "nstab-main": "ṣfḫa",
+       "nstab-main": "صفحة",
        "nstab-user": "Ṣ-Ṣefḫa dyal l-mosṫeĥdim",
        "nstab-media": "sfha dyal media",
        "nstab-special": "Ṣefḫa ĥaṣṣa",
        "nstab-template": "Modél",
        "nstab-help": "sfhat lmosaaada",
        "nstab-category": "ṫṣnif",
+       "mainpage-nstab": "صفحة لولا",
        "nosuchaction": "makaynch fiaal bhal hada",
        "nosuchactiontext": "lfial li tlbti mashihch\nimkn ghltti flktba dyal ladresse\nhadchi imkn kadalik ichir lchi khataaa f {{SITENAME}}",
        "nosuchspecialpage": "makaynach sfha bhad smiya",
        "changeemail-newemail": "ĝonwan dial l-email jdid:",
        "changeemail-none": "(walo)",
        "changeemail-submit": "bddel l-email",
-       "bold_sample": "Kṫaba ġliḍa",
-       "bold_tip": "Kṫaba ġliḍa",
-       "italic_sample": "Kṫaba mayla",
-       "italic_tip": "Kṫaba mayla",
+       "bold_sample": "كتابة غليضة",
+       "bold_tip": "كتابة غليضة",
+       "italic_sample": "كتابة مايلة",
+       "italic_tip": "كتابة مايلة",
        "link_sample": "Ĝonwan l-lyan",
        "link_tip": "Lyan daĥili",
        "extlink_sample": "http://www.example.com Ĝonwan l-lyan",
        "nosuchsectiontitle": "maymknch nlgaw lqissm",
        "nosuchsectiontext": "ḫawlṫi ṫĝddl ċi qism ma kayenċ.\nyqdr ikon ṫnql wlla ṫḫyyd mlli knṫi kaṫċof had ṣfḫa.",
        "loginreqtitle": "khassk tsjl dokhol",
-       "loginreqlink": "Ṫkonékta",
+       "loginreqlink": "تكونيكطا",
        "loginreqpagetext": "ĥaṣṣk ddir $1 baċ ṣfaḫi ĥrin.",
        "accmailtitle": "lmot de passe tsaft.",
        "accmailtext": "waḫd klmṫ s-srr mṣayba ĝċwa'iyyn ĝla ḫsab [[User talk:$1|$1]] ṫsiftaṫ l-$2.\n\nṫqdr ṫbddal klmṫ s-srr dialt had l-ḫisab j-jdid f-ṣṣfḫa ṫaĝ ''[[Special:ChangePassword|bḍḍel klmṫ s-srr]]'' mn bĝdmma ṫdĥol.",
        "previousrevision": "Morajaĝa qdem",
        "nextrevision": "L-Vérsyon li mbeĝd →",
        "currentrevisionlink": "Ċof l-versyon l-leĥĥra",
-       "cur": "daba",
+       "cur": "دابا",
        "next": "li jay",
-       "last": "qbel",
+       "last": "قبل",
        "page_first": "lowla",
        "page_last": "lkhra",
        "histlegend": "Meĝlomaṫ ṫefsiriya : ({{MediaWiki:Cur}}) = l-ferq mĝa l-vérsyon dyal daba, ({{MediaWiki:Last}}) = l-ferq mĝa l-vérsyon li qbel, <b>m</b> = ṫeĝdil ma mohimċ bezzaf",
        "searchmenu-new": "'''ṣayb f-had l-wiki ṣfḫṫ \"[[:$1]]\"!'''",
        "searchprofile-articles": "sfht mohtawa",
        "searchprofile-images": "media",
-       "searchprofile-everything": "kolchi",
+       "searchprofile-everything": "كلشي",
        "searchprofile-advanced": "motaqaddim",
        "searchprofile-articles-tooltip": "qllb f $1",
        "searchprofile-images-tooltip": "qllb f tsawr",
        "group-sysop": "Wébmodirin",
        "group-bureaucrat": "bitoqratiyon",
        "group-suppress": "noddar",
-       "group-all": "(kolchi)",
+       "group-all": "(كلشي)",
        "group-user-member": "{{GENDER:$1|Mosṫeĥdim}}",
        "group-autoconfirmed-member": "Mosṫeĥdim moakkad tilqa'iyan",
        "group-bot-member": "bot",
        "rclinks": "Werri l-$1 dyal ṫ-ṫeġyiraṫ l-leĥĥrin li ṫdaro fe had l-$2 l-iyam l-leĥĥrin",
        "diff": "ferq",
        "hist": "Ṫariĥ",
-       "hide": "Ĥebbi",
+       "hide": "خبي",
        "show": "Werri",
        "minoreditletter": "ṣ",
        "newpageletter": "J",
        "listusers-creationsort": "Jmeĝ ĝla ḫsab ṫariĥ l-ĥṫiraĝ",
        "usereditcount": "$1 ṫeĝdil{{PLURAL:$1||aṫ}}",
        "usercreated": "tnch' f $1 saaa $2",
-       "newpages": "Ṣefḫaṫ jdad",
+       "newpages": "صفحات جداد",
        "newpages-username": "smiṫ l-mosṫĥdim:",
        "ancientpages": "aqdam sfahi",
        "move": "Neqqel",
        "log": "sijillaṫ",
        "all-logs-page": "kol sijillat laama",
        "logempty": "ḫṫṫa ċi madda ma mtabqa f-ssijill.",
+       "checkbox-all": "كلشي",
        "allpages": "Ṣ-Ṣefḫaṫ kamlin",
        "nextpage": "sfha jaya ($1)",
        "prevpage": "Ṣ-Ṣefḫa li qbel ($1)",
        "allpagesto": "Werri ṣ-ṣefḫaṫ ḫṫal:",
        "allarticles": "Ṣ-Ṣefḫaṫ kolhom",
        "allinnamespace": "kol sfahi (f nitaq $1)",
-       "allpagessubmit": "Sir",
+       "allpagessubmit": "سير",
        "allpagesprefix": "biyn sfahi katbda b:",
        "categories": "tsnifat",
        "categoriesfrom": "wrri ṫ-ṫṣnifaṫ li badyin mn:",
        "uctop": "(l-foq)",
        "month": "Men ċher (o qdem)",
        "year": "Men ĝam (o men qbel)",
-       "sp-contributions-newbies": "Werri ġir l-mosahamaṫ dyal l-mosṫeĥdimin j-jdad",
+       "sp-contributions-newbies": "وري غير المساهمات ديال المستخدمين الجداد",
        "sp-contributions-newbies-sub": "Le ḫsabaṫ jdad",
        "sp-contributions-newbies-title": "mosahamat lmostkhdim lilhassabat jdida",
        "sp-contributions-blocklog": "Ṫariĥ l-blokajaṫ",
        "sp-contributions-logs": "sijillaṫ",
        "sp-contributions-talk": "ṫnaqeċ",
        "sp-contributions-userrights": "ṫdbir ṣalaḫiyyaṫ l-mosṫĥdim",
-       "sp-contributions-search": "Qelleb ĝla ċi mosahamaṫ",
+       "sp-contributions-search": "قلّب علا شي مساهمات",
        "sp-contributions-username": "Ĝonwan IP ola smiyṫ l-mosṫeĥdim",
        "sp-contributions-toponly": "wrri ġi ṫĝdilaṫ lli hiya l-ṃoṛajaĝṫ l-aĥrra",
        "sp-contributions-submit": "Qelleb",
        "whatlinkshere": "Ṣefḫaṫ mlaqyin",
        "whatlinkshere-title": "Ṣ-Ṣefḫaṫ li mlaqyin mĝa \"$1\"",
        "whatlinkshere-page": "ṣfḫa:",
-       "linkshere-2": "Had ṣ-ṣefḫaṫ kayddiw le '''$1''':",
-       "nolinkshere-2": "ḫṫa ċi ṣfḫa ma ka-twṣṣel l-'''$1'''.",
-       "nolinkshere-ns-2": "ḫṫṫĝ ṣfḫa ma ka-twṣṣal l-'''$1''' f-nnitaq lli ĥṫariṫi",
+       "linkshere": "Had ṣ-ṣefḫaṫ kayddiw le '''$2''':",
+       "nolinkshere": "ḫṫa ċi ṣfḫa ma ka-twṣṣel l-'''$2'''.",
+       "nolinkshere-ns": "ḫṫṫĝ ṣfḫa ma ka-twṣṣal l-'''$2''' f-nnitaq lli ĥṫariṫi",
        "isredirect": "Ṫeḫwil ṣ-ṣefḫa",
        "istemplate": "Daĥel",
        "isimage": "wṣlṫ l-milef",
        "blocklink": "Bloki",
        "unblocklink": "Ḫiyyed l-manĝ",
        "change-blocklink": "beddel l-manĝ",
-       "contribslink": "Mosahamaṫ",
+       "contribslink": "مساهمات",
        "blocklogpage": "Ṫariĥ l-blokajaṫ",
        "blocklogentry": "bloka [[$1]] limoddaṫ $2 $3",
        "unblocklogentry": "débloka $1",
        "allmessages-filter-legend": "Filter",
        "allmessages-filter": "filtri b-ḫasab halṫ l-ṫĝdil:",
        "allmessages-filter-unmodified": "mamaadlch",
-       "allmessages-filter-all": "Kolċi",
+       "allmessages-filter-all": "كلشي",
        "allmessages-filter-modified": "lmoaddal",
        "allmessages-prefix": "filtri hassab lprefix",
        "allmessages-language": "Loġa:",
        "allmessages-filter-submit": "Sir",
-       "thumbnail-more": "Kebber",
+       "thumbnail-more": "كبّر",
        "filemissing": "fichier makaynch",
        "thumbnail_error": "ĥalat fl-mṣayḅa dl-miniatur: $1",
        "djvu_no_xml": "ma ymkn-ċ ṫafḫḫoṣ XML l-milffaṫ DjVu",
        "pageinfo-authors": "ĝadad l-mo'llifin l-mĥṫalfin",
        "pageinfo-toolboxlink": "معلومات على الصفحة",
        "markaspatrolleddiff": "marki kamorajaaa",
-       "log-show-hide-patrol": "$1 sijjil lkhafr",
        "previousdiff": "Ṫ-Ṫeĝdil li mbeĝd",
        "nextdiff": "Ṫ-Ṫeĝdila li mbeĝd",
        "thumbsize": "ḫajm l-miniatur:",
        "file-info-png-looped": "mlfof",
        "newimages-legend": "Filter",
        "newimages-label": "smiyt lfichier olla chwiya mnno:",
+       "newimages-newbies": "وري غير المساهمات ديال المستخدمين الجداد",
        "noimages": "walo maytchaf.",
        "ilsubmit": "Qelleb",
        "bydate": "hassab tarikh",
        "exif-giffilecomment": "ṫ-ṫĝliq dial milef GIF",
        "exif-intellectualgenre": "noĝ l-madda",
        "exif-scenecode": "cod mċhd IPTC",
+       "exif-orientation-1": "عادي",
        "exif-orientation-4": "mḍwwer ofoqiyyen",
        "exif-orientation-8": "mḍwwer 90° <abbr title=\"Ĝks (ṫ-ṫijah) Ĝaqarib s-Saĝa\">ĜĜS</abbr>",
        "exif-componentsconfiguration-0": "ma kayn-ċ",
        "exif-urgency-low": "mnĥafḍa ($1)",
        "exif-urgency-high": "ĝalia ($1)",
        "exif-urgency-other": "l-awlawiyya lli ḫddadha l-mosṫĥdim ($1)",
-       "namespacesall": "kolċi",
-       "monthsall": "kolhom",
+       "namespacesall": "كلشي",
+       "monthsall": "كلشي",
        "confirmemail": "konfirmasyon dyal l'email",
        "confirmemail_send": "sift code lkonfirmation",
        "confirmemail_sent": "tam irssal rissala dyal lkonfirmation.",
        "htmlform-selectorother-other": "okhra",
        "revdelete-restricted": "tḅḅq ḍ-ḍawaḅit ll-idariyyin",
        "revdelete-unrestricted": "ḫyyd ḍ-ḍawaḅit ll-idariyyin",
-       "rightsnone": "(walo)"
+       "rightsnone": "(walo)",
+       "log-action-filter-all": "كلشي"
 }
index c392c6a..b1f5f84 100644 (file)
        "whatlinkshere": "ايه بيوصل هنا",
        "whatlinkshere-title": "الصفحات اللى بتوصل لـ \"$1\"",
        "whatlinkshere-page": "الصفحة:",
-       "linkshere-2": "الصفحات دى فيها وصله ل '''$1''':",
-       "nolinkshere-2": "مافيش صفحات بتوصل ل '''$1'''.",
-       "nolinkshere-ns-2": "مافيش صفحات بتوصل لـ '''$1''' فى النطاق اللى انت اختارته.",
+       "linkshere": "الصفحات دى فيها وصله ل '''$2''':",
+       "nolinkshere": "مافيش صفحات بتوصل ل '''$2'''.",
+       "nolinkshere-ns": "مافيش صفحات بتوصل لـ '''$2''' فى النطاق اللى انت اختارته.",
        "isredirect": "صفحة تحويل",
        "istemplate": "متضمن",
        "isimage": "وصلة ملف",
        "markedaspatrollederror-noautopatrol": "مش مسموح ليك تعلم على تغييراتك الشخصية كأنها متراجعة.",
        "patrol-log-page": "سجل المراجعة",
        "patrol-log-header": "دا سجل بالنسخ المتراجعة",
-       "log-show-hide-patrol": "$1 سجل المراجعة",
        "deletedrevision": "مسح النسخة القديمة $1",
        "filedeleteerror-short": "غلط مسح الملف: $1",
        "filedeleteerror-long": "حصلت غلطات و الملف دا بيتمسح :\n\n$1",
index 031fa94..fead6f8 100644 (file)
@@ -21,7 +21,9 @@
                        "Dibya Dutta",
                        "Matma Rex",
                        "চাণক্য কুমাৰ দাস",
-                       "Fitoschido"
+                       "Fitoschido",
+                       "Sagsag",
+                       "Bodhisattwa"
                ]
        },
        "tog-underline": "সংযোগসমূহ অধোৰেখিত কৰক:",
        "copyrightwarning2": "অনুগ্ৰহ কৰি মন কৰক যে {{SITENAME}}লৈ কৰা সকলো বৰঙণি আন সদস্যই সম্পাদনা কৰিব, সলনি কৰিব অথবা মচি পেলাব পাৰে ।\nআপুনি যদি আপোনাৰ লিখনি নিৰ্দয়ভাৱে সম্পাদনা কৰা ভাল নাপায়, তেনেহলে নিজৰ লিখনি ইয়াত নিদিব ।<br />\nইয়াত আপোনাৰ লিখনি দিয়াৰ লগে লগে আপুনি আপোনা-আপুনি প্ৰতিশ্ৰুতি দিছে যে এই লিখনিটো আপোনাৰ মৌলিক লিখনি, বা কোনো স্বত্বাধিকাৰ নথকা বা কোনো ৰাজহুৱা ৱেবছাইট বা তেনে কোনো মুকলি উৎসৰ পৰা আহৰণ কৰা । (অধিক জানিবলৈ $1 চাওক)\n\n'''স্বত্বাধিকাৰযুক্ত কোনো সমল অনুমতি অবিহনে দাখিল নকৰে যেন!'''",
        "longpageerror": "'''ভুল: আপুনি জমা দিয়া পাঠ {{PLURAL:$1|এক কিলো-বাইট|$1 কিলো-বাইট}} আকাৰৰ, যি {{PLURAL:$2|এক কিলো-বাইট|$2 কিলো-বাইট}} সীমাতকৈ বেছি।'''\nইয়াক সাঁচিব পৰা নাযাব।",
        "readonlywarning": "'''সতৰ্কবাণী: চোৱা-চিতাৰ হেতু এই তথ্যকোষ বন্ধ কৰি ৰখা হৈছে, গতিকে আপুনি এই মূহুৰ্তত আপোনাৰ সম্পাদনা সাঁচিব নোৱাৰিব।'''\nআপুনি লেখাটো টেক্সট-ফাইলত কপী-পে'ষ্ট কৰি পিছলৈ ব্যৱহাৰৰ বাবে সাঁচি ৰাখিব পাৰে।\n\nতথ্যকোষ বন্ধ কৰি ৰখা প্ৰশাসকজনে এই ব্যাখ্যা দিছে: $1",
-       "protectedpagewarning": "'''সতৰ্কবাণী: এই পৃষ্ঠা বন্ধ ৰখা হৈছে; কেৱল প্ৰশাসকৰৰ মৰ্যদাৰ সদস্যইহে সম্পাদনা কৰিব পাৰিব ।'''\nআপোনাৰ সুবিধাৰ বাবে পৃষ্ঠাৰ সাম্প্ৰতিক ল'গ সংৰক্ষণ তলত দিয়া হ'ল ।",
+       "protectedpagewarning": "<strong>সতৰ্কবাণী: এই পৃষ্ঠা সুৰক্ষিত কৰা হৈছে; কেৱল প্ৰশাসনিক মৰ্যাদাৰ সদস্যইহে ইয়াক সম্পাদনা কৰিব পাৰিব।</strong>\nআপোনাৰ সুবিধাৰ বাবে পৃষ্ঠাৰ সাম্প্ৰতিক ল'গ অন্তৰ্ভুক্তি তলত দিয়া হ'ল ।",
        "semiprotectedpagewarning": "টোকা: এই পৃষ্ঠা বন্ধ ৰখা হৈছে; কেৱল পঞ্জীভূত সদস্যই হে সম্পাদনা কৰিব পাৰিব ।\nআপোনাৰ সুবিধাৰ বাবে পৃষ্ঠাৰ সাম্প্ৰতিক ল'গ সংৰক্ষণ তলত দিয়া হ'ল ।",
        "cascadeprotectedwarning": "<strong>সতৰ্কবাণী:</strong> এই পৃষ্ঠাটো সুৰক্ষিত কৰি ৰখা হৈছে যাতে কেৱল প্ৰশাসনিক ক্ষমতা থকা সদস্যই ইয়াক সম্পাদনা কৰিব পাৰে, কাৰণ ই প্ৰপাতাকাৰ-সুৰক্ষিত  {{PLURAL:$1|পৃষ্ঠাটোৰ|পৃষ্ঠাবোৰৰ}} অন্তৰ্ভুক্ত:",
        "titleprotectedwarning": "'''সতৰ্কবাণী: এই পৃষ্ঠাটো সুৰক্ষিত কৰা হৈছে যাতে কেৱল [[Special:ListGroupRights|specific rights]] সদস্যই ইয়াক তৈয়াৰ কৰিব পাৰে ।'''\nআপোনাৰ সুবিধাৰ্থে অভিলেখৰ শেহতীয়া ভৰ্তি তলত দিয়া হ’ল।",
        "undo-failure": "এই সম্পাদনা মধ্যৱৰ্তী সম্পাদনাসমূহৰ দ্বন্দৰ কাৰণে পূৰ্ববৎ কৰা নহ'ব ।",
        "undo-norev": "এই সম্পাদনাটো ৰদ কৰিব নোৱাৰি, কাৰণ এইটো আৰু নাই বা ইয়াক বিলোপ কৰা হ'ল।",
        "undo-nochange": "সম্পাদনাটো ইতিমধ্যেই বাতিল কৰা হৈছে।",
-       "undo-summary": "[[Special:Contributions/$2|$2]] ([[User talk:$2|আলোচনা]]) সম্পাদিত $1 সংশোধনটি বাতিল কৰক",
+       "undo-summary": "[[Special:Contributions/$2|$2]] ([[User talk:$2|আলোচনা]])-ই কৰা $1 নম্বৰ সম্পাদনাটো বাতিল কৰা হৈছে",
        "undo-summary-username-hidden": "এজন গোপন ব্যৱহাৰকাৰীয়ে কৰা $1 সংশোধন বাতিল কৰক",
        "cantcreateaccount-text": "আই পি ঠিকনা ('''$1''')ৰ পৰা একাউণ্ট সৃষ্টিত [[User:$3|$3]]’য়ে বাধা প্ৰদান কৰিছে ।\n\n$3 য়ে আগবঢ়োৱা ইয়াৰ কাৰণ হৈছে ''$2''",
        "cantcreateaccount-range-text": "[[User:$3|$3]]য়ে <strong>$1</strong> পৰিসীমাৰ আই পি ঠিকনাৰ পৰা একাউণ্ট সৃষ্টি বাৰণ কৰিছে যাৰ ভিতৰত আপোনাৰ আই ই ঠিকনাও (<strong>$4</strong>) আছে।\n\n $3য়ে <em>$2</em> বুলি কাৰণ দৰ্শাইছে",
        "recentchanges-legend-plusminus": "(''±১২৩'')",
        "rcfilters-legend-heading": "<strong>সংক্ষিপ্ত ৰূপৰ তালিকা:</strong>",
        "rcfilters-other-review-tools": "আন পুনৰীক্ষণ সঁজুলি",
+       "rcfilters-quickfilters": "সঞ্চিত পৰিস্ৰাৱক",
+       "rcfilters-quickfilters-placeholder-title": "এতিয়ালৈকে কোনো ছেকনী সাঁচি থোৱা নাই",
+       "rcfilters-quickfilters-placeholder-description": "আপোনাৰ ছেকনীৰ ছেটিংছ সাঁচি থ'বলৈ আৰু পাছত সেয়া ব্যৱহাৰ কৰিবলৈ তলত থকা সক্ৰিয় পৰিস্ৰাৱক ক্ষেত্ৰৰ বুক্‌মাৰ্ক চিহ্নটো ক্লিক কৰক।",
+       "rcfilters-savedqueries-defaultlabel": "সঞ্চিত পৰিস্ৰাৱক",
+       "rcfilters-savedqueries-remove": "মচি পেলাওক",
+       "rcfilters-show-new-changes": "নতুন সালসলনিবোৰ চাওক",
        "rcfilters-search-placeholder": "পৰিৱৰ্তনসমূহ ছেকক (ছেকনীৰ নামৰ বাবে মেন্যু বা সন্ধান ব্যৱহাৰ কৰক)",
+       "rcfilters-highlightbutton-title": "ফলাফলসমূহ উজ্জ্বল কৰক",
+       "rcfilters-filter-editsbyself-label": "আপুনি কৰা সালসলনিসমূহ",
+       "rcfilters-filter-editsbyself-description": "আপোনাৰ নিজৰ অৱদানসমূহ।",
+       "rcfilters-filter-editsbyother-label": "আনে কৰা সালসলনিসমূহ",
+       "rcfilters-filter-editsbyother-description": "আপুনি কৰাখিনিৰ বাহিৰে আন সকলো সালসলনি।",
+       "rcfilters-filtergroup-userExpLevel": "সদস্য পঞ্জীয়ন আৰু অভিজ্ঞতা",
+       "rcfilters-filter-user-experience-level-registered-label": "পঞ্জীয়নভুক্ত",
+       "rcfilters-filter-user-experience-level-registered-description": "প্ৰৱেশ কৰা সম্পাদকসকল।",
+       "rcfilters-filter-user-experience-level-unregistered-description": "প্ৰৱেশ নকৰা সম্পাদকসকল।",
+       "rcfilters-filter-user-experience-level-newcomer-label": "নবাগতসকল",
+       "rcfilters-filter-user-experience-level-newcomer-description": "১টাতকৈ কম সম্পাদনা কৰা বা ৪ দিনতকৈ কম সময় সক্ৰিয় থকা পঞ্জীয়নভুক্ত সম্পাদকসকল।",
+       "rcfilters-filter-user-experience-level-learner-label": "ন-শিকাৰুসকল",
+       "rcfilters-filter-user-experience-level-learner-description": "পঞ্জীয়নভুক্ত সম্পাদকসকল যাৰ অভিজ্ঞতাৰ স্তৰ \"নবাগত\" আৰু \"অভিজ্ঞ সদস্য\"ৰ মাজত।",
+       "rcfilters-filter-user-experience-level-experienced-label": "অভিজ্ঞ সদস্যসকল",
+       "rcfilters-filter-user-experience-level-experienced-description": "৫০০তকৈ বেছি সম্পাদনা কৰা আৰু ৩০ দিনতকৈ বেছি সময় সক্ৰিয় থকা পঞ্জীয়নভুক্ত সম্পাদকসকল।",
        "rcfilters-filter-humans-label": "মানুহ (ব'ট নহয়)",
        "rcfilters-filter-pageedits-label": "পৃষ্ঠা সম্পাদনা",
        "rcfilters-filter-newpages-label": "পৃষ্ঠা সৃষ্টি",
        "whatlinkshere": "ইয়ালৈ থকা সংযোগসমূহ",
        "whatlinkshere-title": "\"$1\"লৈ সংযোজিত পৃষ্ঠাসমূহ",
        "whatlinkshere-page": "পৃষ্ঠা:",
-       "linkshere-2": "এই পৃষ্ঠাটো '''$1''' ৰ লগত সংযোজিত:",
-       "nolinkshere-2": "'''$1''' ৰ লগত কোনো পৃষ্ঠা সংযোজিত নহয়।",
-       "nolinkshere-ns-2": "নিৰ্বাচিত নামস্থানৰ কোনো পৃষ্ঠাৰ পৰা $1লৈ সংযোগ নাই ।",
+       "linkshere": "এই পৃষ্ঠাটো '''$2''' ৰ লগত সংযোজিত:",
+       "nolinkshere": "'''$2''' ৰ লগত কোনো পৃষ্ঠা সংযোজিত নহয়।",
+       "nolinkshere-ns": "নিৰ্বাচিত নামস্থানৰ কোনো পৃষ্ঠাৰ পৰা $2লৈ সংযোগ নাই ।",
        "isredirect": "পুনঃনিৰ্দেশনা পৃষ্ঠা",
        "istemplate": "অন্তৰ্ভুক্ত কৰক",
        "isimage": "নথিৰ সংযোগ",
        "markedaspatrollederrornotify": "নিৰীক্ষণবিহীন ৰূপে চিহ্নিত কৰা হ’ল",
        "patrol-log-page": "নিৰীক্ষণ অভিলেখ",
        "patrol-log-header": "এইখন নিৰীক্ষিত সংশোধনসমূহৰ অভিলেখ ।",
-       "log-show-hide-patrol": "নিৰীক্ষণ অভিলেখ $1",
        "deletedrevision": "পুৰণি সংশোধনী $1 বিলোপ কৰা হ’ল",
        "filedeleteerror-short": "নথি বিলোপ কৰাত ত্ৰুটি: $1",
        "filedeleteerror-long": "এই নথিখন বিলোপ কৰাত সমস্যা হৈছে :\n\n$1",
        "special-characters-group-hebrew": "হিব্ৰু",
        "special-characters-group-bangla": "বাংলা",
        "special-characters-group-tamil": "তামিল",
-       "special-characters-group-telugu": "তà§\87লà§\87গু",
+       "special-characters-group-telugu": "তà§\87লà§\81গু",
        "special-characters-group-sinhala": "সিংহলী",
        "special-characters-group-gujarati": "গুজৰাটী",
        "special-characters-group-devanagari": "দেবনাগৰী",
index 1017e86..b3783e9 100644 (file)
        "rcshowhideminor": "$1 M515x512S1f010486x488S2f900502x507 M521x532S10609498x496S10621487x512S21100500x483S2df20479x468",
        "rcshowhideminor-hide": "M546x533S15a56519x474S2ff00482x483S2c601516x507S1f740521x487S1f711484x508",
        "rcshowhidebots-show": "M521x531S10012491x516S15a18479x503S26620486x469",
+       "rcshowhidebots-hide": "M546x533S15a56519x474S2ff00482x483S2c601516x507S1f740521x487S1f711484x508",
        "rcshowhideliu": "$1 M538x521S2a200497x480S20b00462x508S11530523x482S15a37462x483S11551470x493 M526x522S15a56499x510S11520503x479S20e00489x496S26a02474x489",
        "rcshowhideliu-hide": "M546x533S15a56519x474S2ff00482x483S2c601516x507S1f740521x487S1f711484x508",
        "rcshowhideanons-hide": "M546x533S15a56519x474S2ff00482x483S2c601516x507S1f740521x487S1f711484x508",
        "tooltip-summary": "M535x523S14c50508x492S14c58469x492S22520503x477S22520465x477 M529x528S11541487x496S11549471x501S20e00503x488S26507516x473 M554x523S14c40530x476S14c48446x492S26502515x489S26516468x507S20340495x489S20348487x506",
        "patrol-log-page": "M518x560S2035a492x545S10e50501x522S31500482x483 M518x536S15a37483x465S18550493x476S15a37483x509S15a51486x513",
        "patrol-log-header": "M508x525S10004493x475S22a04494x510 M518x560S2035a492x545S10e50501x522S31500482x483 M521x532S10609498x496S10621487x512S21100500x483S2df20479x468 M518x536S15a37483x465S18550493x476S15a37483x509S15a51486x513",
-       "log-show-hide-tag": "$1 M519x514S15a28482x487S11502489x498 M518x536S15a37483x465S18550493x476S15a37483x509S15a51486x513",
        "filedeleteerror-short": "M527x532S1ea40473x511S1f540512x478S22a07497x504S2f700512x468 M520x523S14c19480x496S15a01497x497S20710483x477 M518x526S2ff00482x483S19a00487x506 S38700463x496 $1",
        "ilsubmit": "M546x525S2ff00482x483S16d10492x505S2e502519x502",
        "metadata": "M520x523S14c19480x496S15a01497x497S20710483x477 M538x522S18517516x486S1851f461x495S2ff00482x483S14c00513x436S14c08461x445S26a00511x469S26a10459x478",
        "logentry-newusers-autocreate": "M526x522S15a56499x510S11520503x479S20e00489x496S26a02474x489 M518x517S15a30482x489S1f750484x484S20500496x506S22a04505x495 $1 M531x531S14c30506x469S2a204508x503S2a21c470x503S14c38470x469 {{GENDER:$2|M532x519S20302493x485S2030a489x502S21100509x504S26900516x482S26910468x501}} M520x525S15a18480x490S10a02483x476S23100494x508S20e00500x494",
        "log-name-managetags": "M519x514S15a28482x487S11502489x498 M530x529S10640507x503S10648479x489S26c08503x484S26c18470x471 M518x536S15a37483x465S18550493x476S15a37483x509S15a51486x513",
        "log-name-tag": "M519x514S15a28482x487S11502489x498 M518x536S15a37483x465S18550493x476S15a37483x509S15a51486x513",
-       "searchsuggest-search": "M546x525S2ff00482x483S16d10492x505S2e502519x502",
+       "searchsuggest-search": "M546x525S2ff00482x483S16d10492x505S2e502519x502 {{SITENAME}}",
        "api-error-unknownerror": "M536x518S2ff00482x483S15a11513x486S28108513x453 M518x526S2ff00482x483S19a00487x506 S38700463x496 $1",
        "expandtemplates": "M554x524S14c40530x477S14c48446x493S26506515x490S26512468x508S20340495x490S20348487x507 M510x522S15c10490x513S16d12490x495S22a04494x478",
        "expand_templates_ok": "M515x525S17620499x475S14020485x495",
index 1a15227..d49e1c5 100644 (file)
        "databaseerror-function": "Función: $1",
        "databaseerror-error": "Error: $1",
        "transaction-duration-limit-exceeded": "Para evitar crear un gran atrasu na replicación, esta transaición albortóse porque la duración de la escritura ($1) pasó la llende de $2 {{PLURAL:$2|segundu|segundos}}.\nSi tas cambiando munchos oxetos al mesmu tiempu, intenta meyor facer operaciones múltiples más pequeñes.",
-       "laggedslavemode": "'''Avisu:''' Esta páxina pue que nun tenga actualizaciones recientes.",
+       "laggedslavemode": "<strong>Avisu:</strong> Escurque esta páxina nun tenga anovamientos de recién.",
        "readonly": "Base de datos candada",
        "enterlockreason": "Introduz un motivu pal candáu, amestando una estimación de cuándo va tener llugar el descandáu",
        "readonlytext": "Nestos momentos la base de datos ta candada pa nueves entraes y otros cambios, seique por un mantenimientu de rutina, y n'acabando too volverá a la normalidá.\n\nL'alministrador del sistema que la candó conseñó esti motivu: $1",
        "filenotfound": "Nun pudo atopase'l ficheru «$1».",
        "unexpected": "Valor inesperáu: «$1»=«$2».",
        "formerror": "Fallu: Nun se pudo unviar el formulariu.",
-       "badarticleerror": "Esta aición nun pue facese nesta páxina.",
+       "badarticleerror": "Esta aición nun puede facese nesta páxina.",
        "cannotdelete": "Nun pudo desaniciase la páxina o'l ficheru «$1».\nSeique daquién yá lo desaniciara.",
-       "cannotdelete-title": "Nun se pue desaniciar la páxina «$1»",
+       "cannotdelete-title": "La páxina «$1» nun puede desaniciase",
        "delete-hook-aborted": "Desaniciu albortáu pol enganche.\nNun conseñó esplicación.",
        "no-null-revision": "Nun pudo crease una nueva revisión nula pa la páxina «$1»",
        "badtitle": "Títulu incorreutu",
-       "badtitletext": "El títulu de páxina solicitáu nun ye válidu, ta baleru o tien enllaces interllingua o interwiki incorreutos.\nPue contener un caráuter o más que nun puen usase nos títulos.",
+       "badtitletext": "El títulu de páxina solicitáu nun ye válidu, ta vacíu o tien enllaces interllingua o interwiki incorreutos.\nPuede contener un caráuter o más que nun pueden usase nos títulos.",
        "title-invalid-empty": "El títulu de páxina solicitáu ta baleru o sólo contien el nome d'un espaciu de nomes.",
        "title-invalid-utf8": "El títulu de páxina solicitáu contien una secuencia UTF-8 inválida.",
        "title-invalid-interwiki": "El títulu de páxina solicitáu contien un enllaz interwiki que nun puede usase nos títulos.",
        "viewsource": "Ver fonte",
        "viewsource-title": "Ver la fonte de $1",
        "actionthrottled": "Aición llendada",
-       "actionthrottledtext": "Como midida escontra abusos, nun se pué repetir esta aición munches vegaes en pocu tiempu, y trespasasti esa llende.\nVuelve a intentalo n'unos minutos.",
+       "actionthrottledtext": "Como midida escontra abusos, nun puedes repetir esta aición munches vegaes en pocu tiempu, y trespasasti esa llende.\nVuelve a tentalo en dellos minutos.",
        "protectedpagetext": "Esta páxina ta candada pa torgar ediciones y otres aiciones.",
        "viewsourcetext": "Pues ver y copiar la fonte d'esta páxina.",
        "viewyourtext": "Pues ver y copiar la fonte de <strong>les tos ediciones</strong> d'esta páxina.",
        "welcomecreation-msg": "Creóse la to cuenta.\nNun t'escaezas de camudar les tos [[Special:Preferences|preferencies de {{SITENAME}}]].",
        "yourname": "Nome d'usuariu:",
        "userlogin-yourname": "Nome d'usuariu",
-       "userlogin-yourname-ph": "Escriba'l so nome d'usuariu",
-       "createacct-another-username-ph": "Escriba'l nome d'usuariu",
+       "userlogin-yourname-ph": "Escribe'l to nome d'usuariu",
+       "createacct-another-username-ph": "Escribe'l nome d'usuariu",
        "yourpassword": "Contraseña:",
        "userlogin-yourpassword": "Contraseña",
-       "userlogin-yourpassword-ph": "Escriba la so contraseña",
-       "createacct-yourpassword-ph": "Escriba una contraseña",
+       "userlogin-yourpassword-ph": "Escribe la contraseña",
+       "createacct-yourpassword-ph": "Escribe una contraseña",
        "yourpasswordagain": "Escribi otra vuelta la contraseña:",
        "createacct-yourpasswordagain": "Confirmar la contraseña",
-       "createacct-yourpasswordagain-ph": "Escriba nuevamente la contraseña",
+       "createacct-yourpasswordagain-ph": "Escribe nuevamente la contraseña",
        "userlogin-remembermypassword": "Caltener abierta la sesión",
        "userlogin-signwithsecure": "Usar una conexón segura",
        "cannotlogin-title": "Nun pudo aniciase sesión",
        "logout": "Salir",
        "userlogout": "Salir",
        "notloggedin": "Nun aniciasti sesión",
-       "userlogin-noaccount": "¿Nun tien una cuenta?",
+       "userlogin-noaccount": "¿Nun tienes una cuenta?",
        "userlogin-joinproject": "Xunise a {{SITENAME}}",
        "createaccount": "Crear una cuenta",
-       "userlogin-resetpassword-link": "¿Escaeció la contraseña?",
+       "userlogin-resetpassword-link": "¿Escaecisti la contraseña?",
        "userlogin-helplink2": "Ayuda del aniciu de sesión",
        "userlogin-loggedin": "Yá anició sesión como {{GENDER:$1|$1}}.\nUtilice'l formulariu de más abaxo p'aniciar sesión como otru usuariu.",
        "userlogin-reauth": "Tienes d'aniciar sesión de nueves pa comprobar que yes {{GENDER:$1|$1}}.",
        "userlogin-createanother": "Crear otra cuenta",
        "createacct-emailrequired": "Direición de corréu electrónicu",
        "createacct-emailoptional": "Direición de corréu electrónicu (opcional)",
-       "createacct-email-ph": "Escriba la so direición de corréu electrónicu",
-       "createacct-another-email-ph": "Escriba la direición de corréu electrónicu",
+       "createacct-email-ph": "Escribe la to direición de corréu electrónicu",
+       "createacct-another-email-ph": "Escribe la direición de corréu electrónicu",
        "createaccountmail": "Usar una contraseña al debalu temporal y unviala a la direición de corréu electrónicu conseñada",
        "createaccountmail-help": "Pue usase pa crear una cuenta pa otra persona ensin saber la contraseña.",
        "createacct-realname": "Nome real (opcional)",
        "createacct-reason": "Motivu",
-       "createacct-reason-ph": "Por qué quier crear otra cuenta",
+       "createacct-reason-ph": "Por qué vas crear otra cuenta",
        "createacct-reason-help": "Mensaxe que s'amuesa nel rexistru de creación de cuentes",
        "createacct-submit": "Crear la cuenta",
        "createacct-another-submit": "Crear una cuenta",
        "createacct-continue-submit": "Siguir cola creación de la cuenta",
        "createacct-another-continue-submit": "Siguir cola creación de la cuenta",
-       "createacct-benefit-heading": "{{SITENAME}} failu xente como vusté.",
+       "createacct-benefit-heading": "Persones como tu son les que construyen {{SITENAME}}.",
        "createacct-benefit-body1": "{{PLURAL:$1|edición|ediciones}}",
        "createacct-benefit-body2": "{{PLURAL:$1|páxina|páxines}}",
        "createacct-benefit-body3": "{{PLURAL:$1|collaborador|collaboradores}} de recién",
        "userexists": "El nome d'usuariu conseñáu yá ta usándose.\nPor favor escueyi un nome diferente.",
        "loginerror": "Error d'aniciu de sesión",
        "createacct-error": "Error de creación de cuenta",
-       "createaccounterror": "Nun se pudo crear la cuenta: $1",
+       "createaccounterror": "Nun pudo crease la cuenta: $1",
        "nocookiesnew": "La cuenta d'usuariu ta creada, pero nun aniciasti sesión.\n{{SITENAME}} usa «cookies» pa identificar a los usuarios.\nTienes les «cookies» desactivaes.\nPor favor actívales y anicia sesión col nuevu nome d'usuariu y contraseña.",
-       "nocookieslogin": "{{SITENAME}} usa «cookies» pa identificar a los usuarios.\nTien les «cookies» desactivaes.\nPor favor activeles y vuelva a intentalo.",
-       "nocookiesfornew": "La cuenta nun se creó porque nun pudimos confirmar l'orixe.\nComprueba que tienes activaes les «cookies», recarga esta páxina y vuelvi a intentalo.",
+       "nocookieslogin": "{{SITENAME}} usa «cookies» pa identificar a los usuarios.\nTien les «cookies» desactivaes.\nPor favor actívales y tenta otra vuelta.",
+       "nocookiesfornew": "La cuenta nun se creó porque nun pudimos confirmar l'orixe.\nComprueba que tienes activaes les «cookies», recarga esta páxina y tenta otra vuelta.",
        "createacct-loginerror": "La cuenta creóse correchamente, pero nun pudo aniciase sesión automáticamente. Sigui col [[Special:UserLogin|accesu manual]].",
        "noname": "Nun conseñasti un nome d'usuariu válidu.",
        "loginsuccesstitle": "Identificáu",
        "nouserspecified": "Has d'especificar un nome d'usuariu.",
        "login-userblocked": "Esti usuariu ta bloquiáu. Nun se permite l'aniciu de sesión.",
        "wrongpassword": "Escribisti un nome d'usuariu o contraseña incorreutu.\nTenta otra vuelta.",
-       "wrongpasswordempty": "La contraseña taba en blanco.\nVuelvi a intentalo.",
+       "wrongpasswordempty": "La contraseña taba en blancu.\nTenta otra vuelta.",
        "passwordtooshort": "Les contraseñes han de tener polo menos {{PLURAL:$1|1 caráuter|$1 caráuteres}}.",
        "passwordtoolong": "Les contraseñes nun puen ser mayores de {{PLURAL:$1|1 caráuter|$1 caráuteres}}.",
        "passwordtoopopular": "Les contraseñes más escoyíes de vezu nun pueden usase. Escueye una contraseña más difícil d'aldovinar.",
        "throttled-mailpassword": "Yá s'unvió un corréu de reaniciu la clave {{PLURAL:$1|na postrer hora|nes postreres $1 hores}}.\nPa evitar abusos, namái s'unviará un corréu de reaniciu cada {{PLURAL:$1|hora|$1 hores}}.",
        "mailerror": "Fallu al unviar el corréu: $1",
        "acct_creation_throttle_hit": "Los visitantes d'esta wiki qu'usen la to direición IP yá crearon {{PLURAL:$1|1 cuenta|$1 cuentes}} nel periodu de $2, que ye'l máximu almitíu nesi tiempu.\nPoro, los visitantes qu'usen esta direición IP nun pueden crear más cuentes pol momentu.",
-       "emailauthenticated": "La so direición de corréu electrónicu confirmóse'l $2 a les $3.",
-       "emailnotauthenticated": "La so direición de corréu electrónicu inda nun se confirmó.\nNun s'unviará corréu pa nenguna de les funciones siguientes.",
+       "emailauthenticated": "La direición de corréu electrónicu confirmóse'l $2 a les $3.",
+       "emailnotauthenticated": "La direición de corréu electrónicu inda nun se confirmó.\nNun s'unviará corréu pa nenguna de les funciones siguientes.",
        "noemailprefs": "Conseña una direición de corréu electrónicu nes tos preferencies pa que funcionen eses carauterístiques.",
        "emailconfirmlink": "Confirmar la direición de corréu electrónicu",
        "invalidemailaddress": "La direición de corréu electrónicu nun pue aceutase yá que paez tener un formatu inválidu.\nPor favor conseña una direición con formatu afayadizu o dexa baleru'l campu.",
        "pt-createaccount": "Crear una cuenta",
        "pt-userlogout": "Salir",
        "php-mail-error-unknown": "Fallu desconocíu na función mail() de PHP.",
-       "user-mail-no-addy": "Intentasti unviar un corréu electrónicu ensin direición de corréu.",
-       "user-mail-no-body": "Trató d'unviar un corréu electrónicu con un cuerpu baleru o curtiu enforma.",
+       "user-mail-no-addy": "Tentasti unviar un corréu electrónicu ensin direición de corréu.",
+       "user-mail-no-body": "Tentasti unviar un corréu electrónicu col cuerpu vaciu o curtiu enforma.",
        "changepassword": "Camudar la contraseña",
-       "resetpass_announce": "P'acabar d'aniciar sesión, tien de definir equí una contraseña nueva.",
+       "resetpass_announce": "P'acabar d'aniciar sesión, tienes de configurar una contraseña nueva.",
        "resetpass_text": "<!-- Amestar testu equí -->",
        "resetpass_header": "Camudar la contraseña de la cuenta",
        "oldpassword": "Contraseña antigua:",
        "retypenew": "Vuelvi a escribir la contraseña nueva:",
        "resetpass_submit": "Configurar la contraseña y aniciar sesión",
        "changepassword-success": "Camudóse la contraseña.",
-       "changepassword-throttled": "Ficisti demasiaos intentos d'aniciu de sesión recientes.\nPor favor espera $1 enantes d'intentalo otra vuelta.",
+       "changepassword-throttled": "Ficisti demasiaos intentos d'aniciar sesión de recien.\nPor favor espera $1 enantes de tentar otra vuelta.",
        "botpasswords": "Contraseñes de bots",
        "botpasswords-summary": "Les <em>contraseñes de bot</em> permiten l'accesu a una cuenta d'usuariu por aciu de la API sin usar les credenciales d'accesu de la cuenta principal. Los permisos d'usuariu disponibles al aniciar sesión con una contraseña de bot puen tar torgaos.\n\nSi nun sabes pa qué val esto, probablemente nun tendríes d'usalo. Naide tendría de pidite nunca que xeneres una d'estes y que-y la deas.",
        "botpasswords-disabled": "Les contraseñes de bot tán desactivaes.",
        "botpasswords-label-delete": "Desaniciar",
        "botpasswords-label-resetpassword": "Reestablecer la contraseña",
        "botpasswords-label-grants": "Permisos aplicables:",
-       "botpasswords-help-grants": "Los permisos dan accesu a los permisos d'usuariu que yá tenga la cuenta. Activar un permisu equí nun da accesu a nengún permisu que la to cuenta nun tenga d'otra miente. Mira la [[Special:ListGrants|tabla de permisos]] pa más información.",
+       "botpasswords-help-grants": "Los permisos dan accesu a los permisos d'usuariu que yá tengas na cuenta. Activar un permisu equí nun da accesu a nengún permisu que la to cuenta nun tenga d'otra miente. Mira la [[Special:ListGrants|tabla de permisos]] pa más información.",
        "botpasswords-label-grants-column": "Permitío",
        "botpasswords-bad-appid": "El nome del bot \"$1\" nun ye válidu.",
        "botpasswords-insert-failed": "Nun pudo amestase'l nome de bot «$1». ¿Taba añadíu yá?",
        "resetpass-submit-loggedin": "Camudar la contraseña",
        "resetpass-submit-cancel": "Encaboxar",
        "resetpass-wrong-oldpass": "Contraseña temporal o actual inválida.\nSeique yá camudaras la contraseña o que pidieras una nueva contraseña temporal.",
-       "resetpass-recycled": "Por favor, cambie la so contraseña por otra distinta de la actual.",
+       "resetpass-recycled": "Por favor, cambia la contraseña por otra distinta de la actual.",
        "resetpass-temp-emailed": "Anició sesión con un códigu temporal unviáu per corréu electrónicu.\nPa completar l'aniciu de sesión, tien de definir una nueva contraseña equí:",
        "resetpass-temp-password": "Contraseña temporal:",
        "resetpass-abort-generic": "Una estensión encaboxó'l cambiu de la contraseña.",
-       "resetpass-expired": "La so contraseña caducó. Defina una nueva contraseña p'aniciar sesión.",
-       "resetpass-expired-soft": "La contraseña caducó y precisa reaniciase. Escueye agora una contraseña nueva, o pulsia «{{int:authprovider-resetpass-skip-label}}» pa reaniciala sero.",
-       "resetpass-validity-soft": "La contraseña nun ye válida: $1\n\nEscueye agora una contraseña nueva, o pulsia «{{int:authprovider-resetpass-skip-label}}» pa reaniciala sero.",
+       "resetpass-expired": "La to contraseña caducó. Configura una nueva contraseña p'aniciar sesión.",
+       "resetpass-expired-soft": "La contraseña caducó y precisa cambiase. Escueye agora una contraseña nueva, o pulsia «{{int:authprovider-resetpass-skip-label}}» pa cambiala sero.",
+       "resetpass-validity-soft": "La contraseña nun ye válida: $1\n\nEscueye agora una contraseña nueva, o pulsia «{{int:authprovider-resetpass-skip-label}}» pa cambiala sero.",
        "passwordreset": "Reaniciar contraseña",
-       "passwordreset-text-one": "Complete esti formulariu pa reaniciar la contraseña.",
-       "passwordreset-text-many": "{{PLURAL:$1|Rellene unu de los campos pa recibir una contraseña temporal per corréu.}}",
+       "passwordreset-text-one": "Completa esti formulariu pa recibir per corréu una contraseña temporal.",
+       "passwordreset-text-many": "{{PLURAL:$1|Rellena unu de los campos pa recibir una contraseña temporal per corréu.}}",
        "passwordreset-disabled": "Los reanicios de contraseña tán desactivaos nesta wiki.",
        "passwordreset-emaildisabled": "Les funciones de corréu electrónicu tan desactivaes nesta wiki.",
        "passwordreset-username": "Nome d'usuariu:",
        "passwordreset-domain": "Dominiu:",
        "passwordreset-email": "Direición de corréu electrónicu:",
        "passwordreset-emailtitle": "Detalles de la cuenta en {{SITENAME}}",
-       "passwordreset-emailtext-ip": "Dalguién (seique vusté, dende la direición IP $1)solicitó'l reaniciu de la so contraseña de {{SITENAME}} ($4).\n{{PLURAL:$3|La cuenta d'usuariu siguiente ta asociada|Les cuentes d'usuariu siguientes tán asociaes}}\na esta direición de corréu electrónicu:\n\n$2\n\n{{PLURAL:$3|Esta contraseña provisional caduca|Estes contraseñes provisionales caduquen}} {{PLURAL:$5|nun día|en $5 díes}}.\nTendría d'aniciar sesión y escoyer una contraseña nueva agora. Si esta solicitú la fizo otra persona,\no si recordó la clave orixinal y yá nun quier camudala, pue escaecer esti mensaxe y siguir\nusando la contraseña antigua.",
-       "passwordreset-emailtext-user": "L'usuariu $1 de {{SITENAME}} solicitó un reaniciu de la so contraseña de {{SITENAME}} ($4). {{PLURAL:$3|La cuenta d'usuariu siguiente ta asociada|Les cuentes d'usuariu siguientes tán asociaes}} con esta direición de corréu electrónicu:\n\n$2\n\n{{PLURAL:$3|Esta contraseña provisional caduca|Estes contraseñes provisionales caduquen}} {{PLURAL:$5|nun día|en $5 díes}}.\nTendría d'aniciar sesión y escoyer una contraseña nueva agora. Si esta solicitú la fizo otra persona, o si recordó la clave orixinal y yá nun quier camudala, pue escaecer esti mensaxe y siguir usando la contraseña antigua.",
+       "passwordreset-emailtext-ip": "Dalguién (seique tu, dende la direición IP $1)solicitó'l reaniciu de la contraseña de {{SITENAME}} ($4).\n{{PLURAL:$3|La cuenta d'usuariu siguiente ta asociada|Les cuentes d'usuariu siguientes tán asociaes}}\na esta direición de corréu electrónicu:\n\n$2\n\n{{PLURAL:$3|Esta contraseña provisional caduca|Estes contraseñes provisionales caduquen}} {{PLURAL:$5|nun día|en $5 díes}}.\nTendríes d'aniciar sesión y escoyer una contraseña nueva agora. Si esta solicitú ye d'otra persona,\no si recordasti la clave orixinal y yá nun quies camudala, inora esti mensaxe y sigue\nusando la contraseña antigua.",
+       "passwordreset-emailtext-user": "L'usuariu $1 de {{SITENAME}} solicitó un reaniciu de la contraseña de {{SITENAME}} ($4). {{PLURAL:$3|La cuenta d'usuariu siguiente ta asociada|Les cuentes d'usuariu siguientes tán asociaes}} con esta direición de corréu electrónicu:\n\n$2\n\n{{PLURAL:$3|Esta contraseña provisional caduca|Estes contraseñes provisionales caduquen}} {{PLURAL:$5|nun día|en $5 díes}}.\nTendríes d'aniciar sesión y escoyer una contraseña nueva agora. Si esta solicitú ye d'otra persona, o si recordasti la clave orixinal y yá nun quies camudala, pues inorar esti mensaxe y siguir usando la contraseña antigua.",
        "passwordreset-emailelement": "Nome d'usuariu: \n$1\n\nContraseña temporal: \n$2",
        "passwordreset-emailsentemail": "Si esta direición de corréu electrónicu ta asociada cola to cuenta, unviaráse un corréu pa reaniciar la contraseña.",
        "passwordreset-emailsentusername": "Si hai una direición de corréu electrónicu asociada con esti nome d'usuariu, unviaráse un corréu electrónicu pa reaniciar la contraseña.",
        "blockednoreason": "nun se dio nengún motivu",
        "whitelistedittext": "Tienes d'$1 pa editar páxines.",
        "confirmedittext": "Tienes de confirmar la direición de corréu electrónicu enantes d'editar páxines.\nPor favor, configura y valida la direición de corréu nes [[Special:Preferences|preferencies d'usuariu]].",
-       "nosuchsectiontitle": "Nun pue atopase la seición",
+       "nosuchsectiontitle": "Nun s'alcontró la seición",
        "nosuchsectiontext": "Intentasti editar una seición que nun esiste.\nSeique se treslladara o desaniciara mientres víes la páxina.",
        "loginreqtitle": "Ye necesario aniciar sesión",
        "loginreqlink": "aniciar sesión",
        "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.",
        "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.\nPue [[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 tiene permisu pa crear esta páxina.",
+       "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].",
        "userpage-userdoesnotexist": "La cuenta d'usuariu «$1» nun ta rexistrada.\nPor favor comprueba si quies crear/editar esta páxina.",
        "userpage-userdoesnotexist-view": "La cuenta d'usuariu «$1» nun ta rexistrada.",
        "yourdiff": "Diferencies",
        "copyrightwarning": "Por favor, ten en cuenta que toles collaboraciones de {{SITENAME}} considérense espublizaes baxo la $2 (ver $1 pa más detalles). Si nun quies que'l to trabayu s'edite ensin midida y se distribuya al debalu, nun lu pongas equí.<br />\nAmás tas prometiéndonos qu'escribisti esto tu mesmu, o que lo copiasti d'una fonte llibre, de dominiu públicu o asemeyada.\n<strong>¡Nun unvies obres con drechos d'autor ensin permisu!</strong>",
        "copyrightwarning2": "Por favor, ten en cuenta que toles contribuciones de {{SITENAME}} se puen editar, alterar o desaniciar por otros usuarios. Si nun quies que'l to trabayu s'edite ensin midida, nun lu pongas equí.<br />\nAmás tas dexándonos afitao qu'escribisti esto tu mesmu, o que lo copiasti d'una fonte llibre de dominiu públicu o asemeyao (ver $1 pa más detalles).\n'''¡Nun pongas trabayos con drechos d'autor ensin permisu!'''",
-       "editpage-cannot-use-custom-model": "El modelu de conteníu d'esta páxina nun pue cambiase.",
+       "editpage-cannot-use-custom-model": "El modelu de conteníu d'esta páxina nun puede cambiase.",
        "longpageerror": "'''ERROR: El testu qu'unviasti tien {{PLURAL:$1|un quilobyte|$1 quilobytes}}, que pasa del máximu de {{PLURAL:$2|un quilobyte|$2 quilobytes}}.'''\nNun se pue grabar.",
        "readonlywarning": "<strong>Avisu: La base de datos ta candada por mantenimientu, polo que nun vas poder guardar les tos ediciones nestos momentos.</strong>\nSeique habríes copiar y apegar el testu nun ficheru de testu y guardalu pa intentalo sero.\n\nL'alministrador del sistema que la candó dio esta esplicación: $1",
        "protectedpagewarning": "'''Avisu: Esta páxina ta candada pa que sólo los alministradores puean editala.'''\nLa cabera entrada del rexistru s'ufre darréu pa referencia:",
        "moveddeleted-notice-recent": "Esta páxina desanicióse apocayá (dientro de les postreres 24 hores).\nEl rexistru de desanicios, proteiciones y tresllaos de la páxina amuésense de siguío como referencia.",
        "log-fulllog": "Ver el rexistru ensembre",
        "edit-hook-aborted": "Edición albortada pol enganche.\nNun dio esplicación.",
-       "edit-gone-missing": "Nun se pudo actualizar la páxina.\nPaez que se desanició.",
+       "edit-gone-missing": "Nun pudo actualizase la páxina.\nPaez que se desanició.",
        "edit-conflict": "Conflictu d'edición.",
        "edit-no-change": "S'inoró la to edición, porque nun se fizo nengún cambéu nel testu.",
        "postedit-confirmation-created": "Creóse la páxina.",
        "converter-manual-rule-error": "Detectóse un error na regla de conversión manual de llingua",
        "undo-success": "La edición se pue esfacer.\nPor favor comprueba la comparanza d'abaxo pa confirmar que ye eso lo que quies facer, y depués guarda los cambios p'acabar d'esfacer la edición.",
        "undo-failure": "Nun pudo esfacese la edición por aciu d'ediciones intermedies conflictives.",
-       "undo-norev": "Nun se pudo esfacer la edición porque nun esiste o se desanició.",
+       "undo-norev": "Nun pudo desfacese la edición porque nun esiste o se desanició.",
        "undo-nochange": "Paez que la edición yá ta desfecha.",
        "undo-summary": "Esfacer la revisión $1 de [[Special:Contributions/$2|$2]] ([[User talk:$2|alderique]])",
        "undo-summary-username-hidden": "Desfacer la revisión $1 d'un usuariu tapecíu",
        "mergehistory-merge": "Les siguientes revisiones de [[:$1]] puen fusionase'n [[:$2]]. Usa la columna de botones d'opción pa fusionar namai les revisiones creaes na y enantes de la hora especificada.\nHas fixate en que si uses los enllaces de navegación esborraránse les seleiciones feches nesta columna.",
        "mergehistory-go": "Amosar ediciones fusionables",
        "mergehistory-submit": "Fusionar revisiones",
-       "mergehistory-empty": "Nun se pue fusionar nenguna revisión.",
+       "mergehistory-empty": "Nun puede fusionase nenguna revisión.",
        "mergehistory-done": "$3 {{PLURAL:$3|revisión|revisiones}} de $1 {{PLURAL:$3|fusionóse|fusionáronse}} en [[:$2]].",
        "mergehistory-fail": "Nun pudo facese la fusión d'historiales, por favor comprueba los parámetros de páxina y hora.",
        "mergehistory-fail-bad-timestamp": "La marca de tiempu ye inválida.",
        "powersearch-togglenone": "Dengún",
        "powersearch-remember": "Recordar la seleición pa guetes futures",
        "search-external": "Busca esterna",
-       "searchdisabled": "La busca en {{SITENAME}} ta desactivada. Mentanto, pues buscar en Google.\nHas fixate en que'l conteníu de los sos índices de {{SITENAME}} pué tar desfasáu.",
+       "searchdisabled": "La busca en {{SITENAME}} ta desactivada. Mentanto, puedes buscar en Google.\nRepara en que'l conteníu de los sos índices de {{SITENAME}} puede tar desfasáu.",
        "search-error": "Hebo un error al buscar: $1",
        "search-warning": "Hebo un avisu al buscar: $1",
        "preferences": "Preferencies",
        "rcfilters-other-review-tools": "Otres ferramientes de revisión",
        "rcfilters-group-results-by-page": "Agrupar resultancies per páxina",
        "rcfilters-activefilters": "Filtros activos",
+       "rcfilters-activefilters-hide": "Tapecer",
+       "rcfilters-activefilters-show": "Amosar",
        "rcfilters-advancedfilters": "Filtros avanzaos",
        "rcfilters-limit-title": "Resultancies qu'amosar",
        "rcfilters-limit-and-date-label": "$1 {{PLURAL:$1|cambiu|$1 cambios}}, $2",
        "rcfilters-empty-filter": "Nun hai filtros activos. Amuésense toles contribuciones.",
        "rcfilters-filterlist-title": "Filtros",
        "rcfilters-filterlist-whatsthis": "¿Como funciona esto?",
-       "rcfilters-filterlist-feedbacklink": "Dinos lo que pienses sobre estes (nueves) ferramientes de filtriáu",
+       "rcfilters-filterlist-feedbacklink": "Dinos lo que pienses sobre estes ferramientes de filtriáu",
        "rcfilters-highlightbutton-title": "Resaltar resultaos",
        "rcfilters-highlightmenu-title": "Seleiciona un color",
        "rcfilters-highlightmenu-help": "Seleiciona un color pa resaltar esta propiedá",
        "rcfilters-watchlist-showupdated": "Los cambeos fechos en páxines que nun visitasti desque se ficieron apaecen en <strong>negrina</strong>, con marcadores sólidos.",
        "rcfilters-preference-label": "Tapecer la versión meyorada de Cambios recién",
        "rcfilters-preference-help": "Revierte'l rediseñu de la interfaz de 2017 y toles ferramientes añadíes d'entós aquí.",
+       "rcfilters-watchlist-preference-label": "Tapecer la versión ameyorada de la Llista de siguimientu",
+       "rcfilters-watchlist-preference-help": "Desfai el rediseñu de la interfaz de 2017 y toles ferramientes añadíes d'entós acá.",
        "rcfilters-filter-showlinkedfrom-label": "Amosar los cambios nes páxines enllazaes dende",
        "rcfilters-filter-showlinkedfrom-option-label": "<strong>Páxines enllazaes dende</strong> la páxina seleicionada",
        "rcfilters-filter-showlinkedto-label": "Amosar los cambios nes páxines qu'enllacen a",
        "badfilename": "El nome del ficheru cambióse a «$1».",
        "filetype-mime-mismatch": "La estensión de ficheru \".$1\" nun casa cola triba MIME detectada del ficheru ($2).",
        "filetype-badmime": "Los ficheros de la triba MIME \"$1\" nun tienen permitida la xubida.",
-       "filetype-bad-ie-mime": "Nun se pue xubir esti ficheru porque Internet Explorer detectalu como \"$1\", que nun ta permitíu y pue ser una triba de ficheru peligrosa.",
+       "filetype-bad-ie-mime": "Nun puede xubise esti ficheru porque Internet Explorer detectaríalu como «$1», que ye una triba de ficheru que nun ta permitida y ye posiblemente peligrosa.",
        "filetype-unwanted-type": "'''\".$1\"''' ye una triba de ficheru non recomendáu.\n{{PLURAL:$3|La triba de ficheru preferida ye|Les tribes de ficheru preferíes son}} $2.",
        "filetype-banned-type": "'''\".$1\"''' {{PLURAL:$4|nun ye una triba de ficheru permitida|nun son tribes de ficheru permitíes}}.\n{{PLURAL:$3|La triba de ficheru permitida ye|Les tribes de ficheru permitíes son}} $2.",
        "filetype-missing": "El ficheru nun tien estensión (como \".jpg\").",
        "upload-form-label-not-own-work-local-generic-local": "Quiciabes tamién quieras tentar [[Special:Upload|la páxina de cargues predeterminada]].",
        "upload-form-label-own-work-message-generic-foreign": "Entiendo que toi xubiendo esti ficheru a un depósitu compartíu. Confirmo que toi faciéndolo cumpliendo les condiciones de serviciu y les polítiques de llicencies d'esi sitiu.",
        "upload-form-label-not-own-work-message-generic-foreign": "Si nun puedes xubir esti ficheru baxo les polítiques del depósitu compartíu, zarra esti diálogu y tenta otru métodu.",
-       "upload-form-label-not-own-work-local-generic-foreign": "Tamién pué interesate usar [[Special:Upload|la páxina de carga de {{SITENAME}}]] si esti ficheru pué xubise allí baxo les sos polítiques.",
+       "upload-form-label-not-own-work-local-generic-foreign": "Tamién puedes tentar usar [[Special:Upload|la páxina de carga de {{SITENAME}}]], si esti ficheru puede xubise allí baxo les sos polítiques.",
        "backend-fail-stream": "Nun se pudo tresmitir el ficheru $1.",
        "backend-fail-backup": "Nun se pudo facer copia de seguridá del ficheru $1.",
        "backend-fail-notexists": "El ficheru $1 nun esiste.",
        "filedelete-reason-dropdown": "*Motivos habituales pal desaniciu\n** Frayamientu de Copyright\n** Ficheru duplicáu",
        "filedelete-edit-reasonlist": "Editar los motivos del desaniciu",
        "filedelete-maintenance": "El desaniciu y restauración de ficheros ta desactivao temporalmente mientres ta en mantenimientu.",
-       "filedelete-maintenance-title": "Nun se pue desaniciar el ficheru",
+       "filedelete-maintenance-title": "Nun puede desaniciase'l ficheru",
        "mimesearch": "Busca MIME",
        "mimesearch-summary": "Esta páxina permite filtriar los ficheros pol so tipu MIME.\nEntrada: contenttype/subtype o contenttype/*, p.ex. <code>image/jpeg</code>.",
        "mimetype": "Triba MIME:",
        "protectedtitles-submit": "Amosar títulos",
        "listusers": "Llista d'usuarios",
        "listusers-editsonly": "Amosar namái usuarios con ediciones",
+       "listusers-temporarygroupsonly": "Amosar solo usuarios en grupos d'usuariu temporales",
        "listusers-creationsort": "Ordenar por data de creación",
        "listusers-desc": "Ordenar n'orde descendente",
        "usereditcount": "$1 {{PLURAL:$1|edición|ediciones}}",
        "listgrouprights-namespaceprotection-namespace": "Espaciu de nomes",
        "listgrouprights-namespaceprotection-restrictedto": "Permisu(os) d'edición del usuariu",
        "listgrants": "Permisos",
-       "listgrants-summary": "Esta ye la llista d'autorizaciones colos accesos asociaos a los permisos de usuario. los usuarios puen autorizar a les aplicaciones qu'usen la so cuenta, pero con permisos llendaos basándose nos permisos que'l usuariu diera a l'aplicación. Sicasí, una aplicación qu'actua nel nome d'un usuariu nun pué usar realmente permisos que nun tenga'l propiu usuariu.\nPué haber [[{{MediaWiki:Listgrouprights-helppage}}|más información]] tocante a los permisos individuales.",
+       "listgrants-summary": "Esta ye la llista d'autorizaciones colos accesos asociaos a los permisos d'usuariu. Los usuarios pueden autorizar que les aplicaciones usen la so cuenta, pero con permisos llendaos basándose nos permisos que'l usuariu diera a l'aplicación. Sicasí, una aplicación qu'actua nel nome d'un usuariu nun puede usar realmente permisos que nun tenga'l propiu usuariu.\nPuede haber [[{{MediaWiki:Listgrouprights-helppage}}|más información]] tocante a los permisos individuales.",
        "listgrants-grant": "Permisu",
        "listgrants-rights": "Permisos",
        "trackingcategories": "Categoríes de siguimientu",
        "dellogpage": "Rexistru de desanicios",
        "dellogpagetext": "Más abaxo ta la llista de los desanicios más recién.",
        "deletionlog": "rexistru de desanicios",
+       "log-name-create": "Rexistru de creación de páxines",
+       "log-description-create": "Más abaxo ta la llista de les creaciones de páxines más recién.",
+       "logentry-create-create": "$1 {{GENDER:$2|creó}} la páxina $3",
        "reverted": "Revertida a una revisión anterior",
        "deletecomment": "Motivu:",
        "deleteotherreason": "Motivu distintu/adicional:",
        "changecontentmodel-cannot-convert": "El conteníu de [[:$1]] nun puede convertise a un tipu de $2.",
        "changecontentmodel-nodirectediting": "El modelu de conteníu $1 nun tien encontu pa edición direuta",
        "changecontentmodel-emptymodels-title": "Nun hai modelos de conteníu disponibles",
-       "changecontentmodel-emptymodels-text": "El conteníu de [[:$1]] nun pue convertise a nengún tipu.",
+       "changecontentmodel-emptymodels-text": "El conteníu de [[:$1]] nun puede convertise a nengún tipu.",
        "log-name-contentmodel": "Rexistru de cambios del modelu de conteníu",
        "log-description-contentmodel": "Esta páxina recueye los cambeos nel modelu de conteníu de les páxines, y les páxines creaes con un modelu de conteníu distintu del predetermináu.",
        "logentry-contentmodel-new": "$1 {{GENDER:$2|creó}} la páxina $3 usando un modelu de conteníu non predetermináu «$5»",
        "prot_1movedto2": "[[$1]] treslladáu a [[$2]]",
        "protect-badnamespace-title": "Espaciu de nomes non protexible",
        "protect-badnamespace-text": "Les páxines d'esti espaciu de nomes nun se puen protexer.",
-       "protect-norestrictiontypes-text": "Esta páxina nun se pue protexer porque nun ta disponible dengún tipu de torga.",
+       "protect-norestrictiontypes-text": "Esta páxina nun puede protexese porque nun ta disponible nengún tipu de torga.",
        "protect-norestrictiontypes-title": "Páxina non protexible",
        "protect-legend": "Confirmar proteición",
        "protectcomment": "Motivu:",
        "whatlinkshere": "Lo qu'enllaza equí",
        "whatlinkshere-title": "Páxines qu’enllacien a «$1»",
        "whatlinkshere-page": "Páxina:",
-       "linkshere-2": "Les páxines siguientes enllacien a '''$1''':",
-       "nolinkshere-2": "Nenguna páxina enllaza a '''$1'''.",
-       "nolinkshere-ns-2": "Nenguna páxina enllaza con <strong>$1</strong> nel espaciu de nomes escoyíu.",
+       "linkshere": "Les páxines siguientes enllacien a <strong>$2</strong>:",
+       "nolinkshere": "Nenguna páxina enllaza a <strong>$2</strong>.",
+       "nolinkshere-ns": "Nenguna páxina enllaza con <strong>$2</strong> nel espaciu de nomes escoyíu.",
        "isredirect": "páxina de redireición",
        "istemplate": "tresclusión",
        "isimage": "enllaz al ficheru",
        "tooltip-ca-nstab-main": "Ver la páxina de conteníu",
        "tooltip-ca-nstab-user": "Ver la páxina d'usuariu",
        "tooltip-ca-nstab-media": "Ver la páxina de multimedia",
-       "tooltip-ca-nstab-special": "Esta ye una páxina especial y nun pué editase",
+       "tooltip-ca-nstab-special": "Esta ye una páxina especial que nun puede editase",
        "tooltip-ca-nstab-project": "Vera la páxina de proyeutu",
        "tooltip-ca-nstab-image": "Ver la páxina del ficheru",
        "tooltip-ca-nstab-mediawiki": "Ver el mensaxe del sistema",
        "markedaspatrollederrornotify": "Falló l'aición de marcar como revisáu.",
        "patrol-log-page": "Rexistru de supervisión",
        "patrol-log-header": "Esti ye un rexistru de les revisiones supervisaes.",
-       "log-show-hide-patrol": "$1 rexistru de supervisión",
-       "log-show-hide-tag": "$1 rexistru d'etiquetes",
        "confirm-markpatrolled-button": "Aceutar",
        "confirm-markpatrolled-top": "¿Marcar la revisión $3 de $2 como patrullada?",
        "deletedrevision": "Desaniciada la revisión antigua $1",
        "permanentlink-submit": "Dir a la revisión",
        "dberr-problems": "¡Sentímoslo! Esti sitiu ta esperimentando dificultaes téuniques.",
        "dberr-again": "Tenta esperar dellos minutos y recargar.",
-       "dberr-info": "(Nun se pue entrar na base de datos: $1)",
-       "dberr-info-hidden": "(Nun se pue entrar na base de datos)",
+       "dberr-info": "(Nun hai accesu a la base de datos: $1)",
+       "dberr-info-hidden": "(Nun hai accesu a la base de datos)",
        "dberr-usegoogle": "Pue probar a buscar con Google mentanto.",
        "dberr-outofdate": "Atalanta que los sos índices del nuesu conteníu seique nun tean actualizaos.",
        "dberr-cachederror": "Esta ye una copia na caché de la páxina que se pidiera, y pue que nun tea actualizada.",
        "pagedata-text": "Esta páxina ufre una interfaz de datos pa les páxines. Escribe'l títulu de la páxina na URL, usando la sintaxis de subpáxina.\n* Aplícase la negociación de conteníu en base a la testera Accept del to cliente. Esto significa que los datos de la páxina van dase nel formatu que prefiera'l to cliente.",
        "pagedata-not-acceptable": "Nun s'alcontró nengún formatu que coincidiera. Tipos MIME soportaos: $1",
        "pagedata-bad-title": "Títulu inválidu: $1.",
-       "unregistered-user-config": "Por motivos de seguridá, les subpáxines d'usuariu JavaScript, CSS y JSON nun pueden cargase pa usuarios ensin rexistrar."
+       "unregistered-user-config": "Por motivos de seguridá, les subpáxines d'usuariu JavaScript, CSS y JSON nun pueden cargase pa usuarios ensin rexistrar.",
+       "passwordpolicies": "Polítiques pa les contraseñes",
+       "passwordpolicies-summary": "Esta ye una llista de polítiques de contraseñes efeutives pa los grupos d'usuarios definíos nesta wiki.",
+       "passwordpolicies-group": "Grupu",
+       "passwordpolicies-policies": "Polítiques",
+       "passwordpolicies-policy-minimalpasswordlength": "La contraseña tien de tener polo menos {{PLURAL:$1|1 caráuter|$1 caráuteres}}.",
+       "passwordpolicies-policy-minimumpasswordlengthtologin": "La contraseña tien de tener polo menos {{PLURAL:$1|1 caráuter|$1 caráuteres}} pa poder aniciar sesión",
+       "passwordpolicies-policy-passwordcannotmatchusername": "La contraseña nun puede ser la mesma que'l nome d'usuariu",
+       "passwordpolicies-policy-passwordcannotmatchblacklist": "La contraseña nun puede casar con contraseñes torgaes específicamente",
+       "passwordpolicies-policy-maximalpasswordlength": "La llonxitú de la contraseña tien de ser menor que {{PLURAL:$1|1 caráuter|$1 caráuteres}}",
+       "passwordpolicies-policy-passwordcannotbepopular": "La contraseña nun puede {{PLURAL:$1|ser la contraseña más popular|tar na llista de $1 contraseñes populares}}"
 }
index 185574b..f12e3ce 100644 (file)
        "whatlinkshere": "Kaskina ickwemakina ka witci acteki",
        "whatlinkshere-title": "Masinahikan nte mia ka ici tapitik \"$1\"",
        "whatlinkshere-page": "Masinahikan:",
-       "linkshere-2": "Masinhikan ka ici tapitik <strong>$1</strong>:",
+       "linkshere": "Masinhikan ka ici tapitik <strong>$2</strong>:",
        "isredirect": "masinhikan ke kweskiticohemikok",
        "istemplate": "ka ki acotcipitcikatek",
        "isimage": "e ici tapitik masinahikaniwoc",
index 92939aa..f51958c 100644 (file)
        "whatlinkshere": "Gluyarakiraf bueem",
        "whatlinkshere-title": "Bu gluyasu va \"$1\"",
        "whatlinkshere-page": "Bu :",
-       "linkshere-2": "Van batu bu vlevef bueem va gluyasiki ruldar : '''$1'''",
-       "nolinkshere-2": "Van batu bu nedoyu bu va gluyasiki ruldar : '''$1'''",
-       "nolinkshere-ns-2": "Koe kiblayano yoltxo meku bu gluyasikikirafu gu '''$1'''.",
+       "linkshere": "Van batu bu vlevef bueem va gluyasiki ruldar : '''$2'''",
+       "nolinkshere": "Van batu bu nedoyu bu va gluyasiki ruldar : '''$2'''",
+       "nolinkshere-ns": "Koe kiblayano yoltxo meku bu gluyasikikirafu gu '''$2'''.",
        "isredirect": "graskarabu",
        "istemplate": "kodoplekura",
        "isimage": "skedasiki va ewava",
index db933ef..dde8033 100644 (file)
        "whatlinkshere": "हिँया का जोडान अहै",
        "whatlinkshere-title": "$1 से जोडान पन्ना",
        "whatlinkshere-page": "पन्ना:",
-       "linkshere-2": "नीचे दिहा पन्ना '''$1''' से जोडान है:",
-       "nolinkshere-2": "'''$1''' से कुछ नाइ जोडान् है।",
-       "nolinkshere-ns-2": "चुनल नामस्थानसे '''$1''' से कवनो पन्ना नाइ जोडान् है।",
+       "linkshere": "नीचे दिहा पन्ना '''$2''' से जोडान है:",
+       "nolinkshere": "'''$2''' से कुछ नाइ जोडान् है।",
+       "nolinkshere-ns": "चुनल नामस्थानसे '''$2''' से कवनो पन्ना नाइ जोडान् है।",
        "isredirect": "पुनर्निर्देशन पन्ना",
        "istemplate": "मिलावा जाय",
        "isimage": "फ़ाइल कय कड़ी",
        "markedaspatrollederrornotify": "जाँचा हुआ चिन्हित करना असफल रहा।",
        "patrol-log-page": "परीक्षण लॉग",
        "patrol-log-header": "यह परीक्षित अवतरणों की लॉग है।",
-       "log-show-hide-patrol": "परीक्षण लॉग $1",
-       "log-show-hide-tag": "$1 चिप्पी लग",
        "deletedrevision": "पुरान अवतरण $1 हटाय दिहा गा है",
        "filedeleteerror-short": "फ़ाईल हटावै मा समस्या: $1",
        "filedeleteerror-long": "फ़ाइल हटावै में आवा गल्ती:\n\n$1",
index c7afe94..9049d61 100644 (file)
        "redirectedfrom": "($1 səhifəsindən yönləndirilmişdir)",
        "redirectpagesub": "Yönləndirmə səhifəsi",
        "redirectto": "İstiqamətləndirilir:",
-       "lastmodifiedat": "Bu səhifə sonuncu dəfə $1 tarixində saat $2-də redaktə edilib.",
+       "lastmodifiedat": "Bu səhifə sonuncu dəfə $1 tarixində, saat $2-də redaktə edilib.",
        "viewcount": "Bu səhifəyə $1 {{PLURAL:$1|dəfə}} müraciət olunub.",
        "protectedpage": "Mühafizəli səhifə",
        "jumpto": "Keçid et:",
        "createacct-submit": "İstifadəçi hesabı yarat",
        "createacct-another-submit": "İstifadəçi hesabı yarat",
        "createacct-benefit-heading": "{{SITENAME}} sizin kimi insanlar tərəfindən yaradılır.",
-       "createacct-benefit-body1": "$1 {{PLURAL:$1|redaktə}}",
+       "createacct-benefit-body1": "{{PLURAL:$1|redaktə}}",
        "createacct-benefit-body2": "{{PLURAL:$1|səhifə|səhifə}}",
-       "createacct-benefit-body3": "ən son {{PLURAL:$1|iştirakçılar|iştirakçılar}}",
+       "createacct-benefit-body3": "nəfər yenicə {{PLURAL:$1|redaktə edən}}",
        "badretype": "Daxil etdiyiniz parol uyğun gəlmir.",
        "userexists": "Daxil edilmiş ad artıq istifadədədir.\nLütfən başqa ad seçin.",
        "loginerror": "Daxil olma xətası",
        "group-autoconfirmed": "Avtotəsdiqlənmiş istifadəçilər",
        "group-bot": "Botlar",
        "group-sysop": "İdarəçilər",
+       "group-interface-admin": "İnterfeys idarəçiləri",
        "group-bureaucrat": "Bürokratlar",
        "group-suppress": "Gizlədənlər",
        "group-all": "(bütün)",
        "group-autoconfirmed-member": "Avtotəsdiqlənmiş istifadəçilər",
        "group-bot-member": "{{GENDER:$1|bot}}",
        "group-sysop-member": "{{GENDER:$1|idarəçi}}",
+       "group-interface-admin-member": "{{GENDER:$1|interfeys idarəçisi}}",
        "group-bureaucrat-member": "{{GENDER:$1|bürokrat}}",
        "group-suppress-member": "{{GENDER:$1|gizlədən}}",
        "grouppage-user": "{{ns:project}}:İstifadəçilər",
        "grouppage-autoconfirmed": "{{ns:project}}:Avtotəsdiqlənmiş istifadəçilər",
        "grouppage-bot": "{{ns:project}}:Botlar",
        "grouppage-sysop": "{{ns:project}}:İdarəçilər",
+       "grouppage-interface-admin": "{{ns:project}}:İnterfeys idarəçiləri",
        "grouppage-bureaucrat": "{{ns:project}}:Bürokratlar",
        "grouppage-suppress": "{{ns:project}}:Gizlədənlər",
        "right-read": "Səhifələrin oxunması",
        "recentchanges-page-added-to-category": "[[:$1]] kateqoriyaya əlavə edildi",
        "upload": "Fayl yüklə",
        "uploadbtn": "Sənəd yüklə",
-       "reuploaddesc": "Return to the upload form.",
-       "upload-tryagain": "Dəyşdirilmiş fayl izahını göndər",
+       "reuploaddesc": "Yükləmə formasına geri qayıt",
+       "upload-tryagain": "Dəyişdirilmiş fayl izahını göndər",
        "uploadnologin": "Daxil olmamısınız",
        "uploadnologintext": "Fayl yükləmək üçün siz sistemə $1.",
        "upload_directory_missing": "($1) yükləmə qaydası axtarılır və vebserverdə yaradılması qeyri-mümkündür.",
        "upload_directory_read_only": "\"$1\" kataloqunun arxivi veb-server yazıları üçün qapalıdır.",
        "uploaderror": "Yükləmə xətası",
        "upload-recreate-warning": "'''Diqqət: Bu adda fayl silinib, yaxud adı dəyişdirilib.'''\n\nBu səhifənin silinmə və addəyişmə jurnalı aşağıda göstərilmişdir:",
-       "uploadtext": "Fayl yükləmək üçün aşağıdakı formadan istifadə edin.\nƏvvəllər yüklənmiş fayllara baxmaq üçün [[Special:FileList|yüklənmiş fayllar siyahısına]] keçin, həmçinin (təkrar) yüklənmiş fayllara [[Special:Log/upload|yükləmə jurnalında]], silinmiş fayllara [[Special:Log/delete|silinmə jurnalında]] baxa bilərsiniz.\n\nMəqaləyə fayl yerləşdirmək üçün aşağıdaki formalardan birini istifadə edin:\n* Faylın tam versiyasını yerləşdirmək üçün: '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:File.jpg]]</nowiki></code>''';\n* Faylın 200 pikselədək kiçildilmiş versiyasını mətndən solda, altında izahla yerləşdirmək üçün: '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:File.png|200px|thumb|left|təsvir]]</nowiki></code>''';\n* Səhifədə faylın özünü göstərmədən ona birbaşa keçid yerləşdirmək üçün: '''<code><nowiki>[[</nowiki>{{ns:media}}<nowiki>:File.ogg]]</nowiki></code>'''.",
+       "uploadtext": "Fayl yükləmək üçün aşağıdakı formadan istifadə edin.\nƏvvəllər yüklənmiş fayllara baxmaq üçün [[Special:FileList|yüklənmiş fayllar siyahısına]] keçin, həmçinin (təkrar) yüklənmiş fayllara [[Special:Log/upload|yükləmə jurnalında]], silinmiş fayllara [[Special:Log/delete|silinmə jurnalında]] baxa bilərsiniz.\n\nMəqaləyə fayl yerləşdirmək üçün aşağıdakı formalardan birini istifadə edin:\n* Faylın tam versiyasını yerləşdirmək üçün: '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:File.jpg]]</nowiki></code>''';\n* Faylın 200 pikselədək kiçildilmiş versiyasını mətndən solda və altında izahla yerləşdirmək üçün: '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:File.png|200px|thumb|left|təsvir]]</nowiki></code>''';\n* Səhifədə faylın özünü göstərmədən ona birbaşa keçid yerləşdirmək üçün: '''<code><nowiki>[[</nowiki>{{ns:media}}<nowiki>:File.ogg]]</nowiki></code>'''.",
        "upload-permitted": "İcazə verilən fayl {{PLURAL:$2|tipi|tipləri}}: $1.",
        "upload-preferred": "Üstünlük verilən fayl {{PLURAL:$2|tipi|tipləri}}: $1.",
        "upload-prohibited": "Qadağan olunan fayl {{PLURAL:$2|tipi|tipləri}}: $1.",
        "whatlinkshere": "Bu səhifəyə bağlantılar",
        "whatlinkshere-title": "\"$1\" məqaləsinə keçid verən səhifələr",
        "whatlinkshere-page": "Səhifə:",
-       "linkshere-2": "'''$1''' səhifəsinə keçid verən səhifələr:",
-       "nolinkshere-2": "<strong>$1</strong> səhifəsinə keçid verən səhifə yoxdur.",
-       "nolinkshere-ns-2": "Seçilmiş ad aralığında heç bir səhifə '''$1''' səhifəsinə keçid vermir.",
+       "linkshere": "'''$2''' səhifəsinə keçid verən səhifələr:",
+       "nolinkshere": "<strong>$2</strong> səhifəsinə keçid verən səhifə yoxdur.",
+       "nolinkshere-ns": "Seçilmiş ad aralığında heç bir səhifə '''$2''' səhifəsinə keçid vermir.",
        "isredirect": "İstiqamətləndirmə səhifəsi",
        "istemplate": "daxil olmuş",
        "isimage": "şəkil üçün keçid",
        "anonymous": "{{SITENAME}} saytının anonim {{PLURAL:$1|istifadəçisi|istifadəçiləri}}",
        "siteuser": "{{SITENAME}} istifadəçisi $1",
        "anonuser": "{{SITENAME}} anonim istifadəçisi $1",
+       "lastmodifiedatby": "Bu səhifə sonuncu dəfə $3 tərəfindən $1 tarixində, saat $2-də redaktə edilib.",
        "othercontribs": "$1-in işinə əsaslanıb.",
        "others": "digərləri",
        "siteusers": "{{SITENAME}} {{PLURAL:$2|user|istifadəçi}} $1",
        "markedaspatrollednotify": "\"$1\" səhifəsindəki bu redaktə patrullanmış kimi işarələndi.",
        "patrol-log-page": "Patrul gündəliyi",
        "patrol-log-header": "Bu yoxlanmış dəyişikliklərin gündəliyidir.",
-       "log-show-hide-patrol": "$1 patrul gündəliyi",
        "deletedrevision": "Köhnə versiyaları silindi $1.",
        "filedeleteerror-short": "Fayl silinərkən xəta: $1",
        "filedeleteerror-long": "Fayl silinərkən üzə çıxan xətalar:\n\n$1",
index 4ec9935..f3b60a1 100644 (file)
        "whatlinkshere": "بۇ صفحه‌‌يه باغلانتیلار",
        "whatlinkshere-title": "«$1»-ه باغلانان صفحه‌لر",
        "whatlinkshere-page": "صفحه:",
-       "linkshere-2": "آشاغیداکی صفحه‌لر '''$1'''-ه باغلانیب:",
-       "nolinkshere-2": "<strong>$1</strong>-ه هئچ بیر صفحه باغلانماییب‌دیر.",
-       "nolinkshere-ns-2": "سئچیلمیش آدفضاسیندا، هئچ صحیفه '''$1'''-ه باغلانتی‌سی یوخدور.",
+       "linkshere": "آشاغیداکی صفحه‌لر '''$2'''-ه باغلانیب:",
+       "nolinkshere": "<strong>$2</strong>-ه هئچ بیر صفحه باغلانماییب‌دیر.",
+       "nolinkshere-ns": "سئچیلمیش آدفضاسیندا، هئچ صحیفه '''$2'''-ه باغلانتی‌سی یوخدور.",
        "isredirect": "یوللاندیرما صفحه‌سی",
        "istemplate": "داخیل اولموش",
        "isimage": "فایلا باغلانتی",
        "markedaspatrollederrornotify": "دولانماق برچسبی مووفقیت سیز اولدو",
        "patrol-log-page": "دولانما ژورنالی",
        "patrol-log-header": "بو یوخلانمیش دییشیک‌لیک‌لرین ژورنالی‌دیر.",
-       "log-show-hide-patrol": "$1 دولانما ژورنالی",
-       "log-show-hide-tag": "اِتیکت ژورنالی $1",
        "deletedrevision": "کؤهنه نوسخه لری سیلیندی $1.",
        "filedeleteerror-short": "فایل سیلینرکن ختا: $1",
        "filedeleteerror-long": "فایل سیلینرکن اوزه چیخان ختا‌لار:\n\n$1",
index 033c601..79b9215 100644 (file)
        "whatlinkshere": "Бында һылтанмалар",
        "whatlinkshere-title": "«$1» битенә һылтанған биттәр",
        "whatlinkshere-page": "Бит:",
-       "linkshere-2": "'''$1''' битенә киләһе биттәр һылтана:",
-       "nolinkshere-2": "'''$1''' битенә бер бит тә һылтанмай.",
-       "nolinkshere-ns-2": "'''$1''' битенә һайланған исемдәр арауығынан бер бит тә һылтанмай.",
+       "linkshere": "'''$2''' битенә киләһе биттәр һылтана:",
+       "nolinkshere": "'''$2''' битенә бер бит тә һылтанмай.",
+       "nolinkshere-ns": "'''$2''' битенә һайланған исемдәр арауығынан бер бит тә һылтанмай.",
        "isredirect": "йүнәлтеү бите",
        "istemplate": "ҡушылған",
        "isimage": "файл һылтанмаһы",
        "markedaspatrollederrornotify": "Патрулләнгән тип билдәләү уңышһыҙ тамамланды.",
        "patrol-log-page": "Тикшереү яҙмалары журналы",
        "patrol-log-header": "Был — тикшерелгән өлгөләр яҙмалары журналы.",
-       "log-show-hide-patrol": "тикшереү яҙмалары журналын $1",
-       "log-show-hide-tag": "$1 билдәләр журналы",
        "confirm-markpatrolled-button": "Яҡшы",
        "confirm-markpatrolled-top": "$2 битенең $3 версияһын тикшерелгән тип һанарғамы?",
        "deletedrevision": "Иҫке $1 өлгөһө юйылды",
index 4ca49b6..c71494a 100644 (file)
@@ -19,7 +19,8 @@
                        "George Animal",
                        "Lokal Profil",
                        "Joe Watzmo",
-                       "WhatamIdoing"
+                       "WhatamIdoing",
+                       "Alexx"
                ]
        },
        "tog-underline": "Links unterstreichen:",
        "and": "&#32;und",
        "faq": "Oft gstejte Frong",
        "actions": "Aktiona",
-       "namespaces": "Namasramm",
+       "namespaces": "Namasram",
        "variants": "Variantn",
+       "navigation-heading": "Navigationsmenü",
        "errorpagetitle": "Fehla",
        "returnto": "Zruck za da Seitn $1.",
        "tagline": "Aus {{SITENAME}}",
        "permalink": "Permanenta Link",
        "print": "Drucken",
        "view": "Leesen",
-       "edit": "Werkln",
+       "view-foreign": "Af $1 ooschaung",
+       "edit": "Weakln",
        "create": "Aufbaun",
        "delete": "Leschn",
        "undelete_short": "{{PLURAL:$1|1 Version|$1 Versiona}} wiedaheastäin",
        "personaltools": "Mei Weakzeig",
        "talk": "Dischkrian",
        "views": "Osichtn",
-       "toolbox": "Werkzeigkisten",
+       "toolbox": "Weakzeig",
        "imagepage": "Daateiseiten åzoang",
        "mediawikipage": "Inhoitsseiten åzoang",
        "templatepage": "Vurlongseiten åzoang",
        "pool-errorunknown": "Unbekånnter Feeler",
        "aboutsite": "Iba {{SITENAME}}",
        "aboutpage": "Project:Iba",
-       "copyright": "Da Inhoid is unter da $1 vafiagbor.",
+       "copyright": "Den Inhoid gibts unta da Lizent $1, wen nix andast oogem is.",
        "copyrightpage": "{{ns:project}}:Urhebarecht",
        "currentevents": "Aktuelle Ereigniss",
        "currentevents-url": "Project:Aktuelle Ereigniss",
-       "disclaimers": "Impressum",
+       "disclaimers": "Hoftungsausschluss",
        "disclaimerpage": "Project:Impressum",
        "edithelp": "Huif fias Werkln",
        "mainpage": "Hoamseitn",
        "retrievedfrom": "Vh „$1“",
        "youhavenewmessages": "Du host $1 ($2).",
        "youhavenewmessagesmulti": "Du host neiche Nochrichtn: $1",
-       "editsection": "Werkln",
+       "editsection": "Weakln",
        "editold": "Werkln",
        "viewsourceold": "Quejtext ozoagn",
        "editlink": "werkln",
        "nstab-template": "Vorlog",
        "nstab-help": "Hüfeseiten",
        "nstab-category": "Kategorie",
+       "mainpage-nstab": "Hoamseitn",
        "nosuchaction": "De Akzion gibts ned",
        "nosuchactiontext": "Dé in da URL ågeewerne Akzión werd voh MediaWiki néd unterstytzd.\nEs kå a Schreibfeeler in da URL vurlieng óder es is a feelerhofter Link åklickt worn.\nEs kå sé aa um an Prógrammierfeeler in da Software, dé auf {{SITENAME}} bnutzd werd, håndeln.",
        "nosuchspecialpage": "De Speziaalsaiten gibts ned",
        "actionthrottled": "Aktionsfrequenz drossld",
        "actionthrottledtext": "A Anti-Spam-Skript begrenzd de Ozoi vo de Vaendarunga pro Minutn. Vasuachs in a boar Minutn wieda.",
        "protectedpagetext": "Dé Seiten is gschytzd worn, um Beorweitungen z' vahindern.",
-       "viewsourcetext": "Du kåst ower 'n Quötext åschaung und kópirn:",
+       "viewsourcetext": "Du konst a en Quejtext vo da Seitn ooschaugn und kopian:",
        "viewyourtext": "Du kåst 'n Quejtext vah '''deiner Beorwatung''' derer Seiten betrochten und kópiern:",
        "protectedinterface": "Dé Seiten do enthoit Text fyr d' Benutzerówerflächen voh da Software und is gschytzd, um an Missbrauch vurzbeing.",
        "editinginterface": "'''Ówocht:''' Dé Seiten do enthoit voh da MediaWiki-Software gnutzden Text. \nÄnderrungen auf derer Seiten wirken sé auf d' Benutzerówerflächen aus.\nZiag bittscheh im Foi voh Ywersétzungen in Betrocht, dé bei [https://translatewiki.net/wiki/Main_Page?setlang=de translatewiki.net], da Lókaalisiarungsblottform fyr MediaWiki, durchzfyrn.",
        "accountcreated": "Benytzerkonto is erstöid worn",
        "accountcreatedtext": "'s Benytzerkonto $1 is aigrichtt worn.",
        "loginlanguagelabel": "Sproch: $1",
-       "pt-login": "Eilogga",
+       "pt-login": "Omejdn",
+       "pt-createaccount": "Nutzakonto ooleng",
        "changepassword": "Posswort ändern",
        "oldpassword": "Oids Posswort:",
        "newpassword": "Neichs Posswort:",
        "accmailtext": "E zuafällig genariards Posswort fyr [[User talk:$1|$1]] is an $2 gschickt worn.\n\nDes Posswort fyr des naiche Benutzerkonto kå auf da Speziaalseiten  „[[Special:ChangePassword|Posswort ändern]]“ gändert wern.",
        "newarticle": "(Neich)",
        "newarticletext": "Du bist am Link gfoigt, wos no koa Seitn gibt.\nUm de Seitn ozlegn, trog dein Text im untan Kostn ei (schaug af da [$1 Huifeseitn] fia mea Infos).\nWens a Irrtum is, dassd do bist, nach druck in Zruck-Knopf vom Brausa.",
-       "anontalkpagetext": "---- ''De Seiten werd dodazua hergnumma, am ned-ågmöiderten Benutzer Nochrichten z' hinterlossen.\nWånnst mid de Kommentare auf derer Seiten nix åfanga kåst, is vamuatlich da friarerne Inhower vo derer IP-Adress gmoat und du kåstas ignorirn.\nWånnst a anonymer Benutzer bist und denkst, das irrelevante Kommentare ån di grichtt worn san, [[Special:UserLogin|möid de bittschee å]], um zuakynfteg Vawirrung z' vamein.''",
+       "anontalkpagetext": "----\n<em>Des is a Dischk vo an anonyman Nutze, wo no koa Konto ooglegt hod, oda wo s grod ned nutzt.</em>\nDesweng vawend ma a IP-Adress zua Identifiziarung.\nSo a IP-Adress kina mearane Nutza gmoasam vawendn.\nWannst du a anonma Nutza bist und mid dem Kommentar nix oofanga konst, konst da oafoch a [[Special:CreateAccount|Nutzakonto oolegn]] oda di [[Special:UserLogin|oomejdn]], damidst ned mid andan Nutzan vawexlst weasd.",
        "noarticletext": "De Seitn enthoid momentan koan Text ned.\nDu konst [[Special:Search/{{PAGENAME}}|nochm Titl]] in andan Seitn suacha,\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} de Logbiacha duachsuacha],\noda [{{fullurl:{{FULLPAGENAME}}|action=edit}} de Seitn beorbatn]</span>.",
        "noarticletext-nopermission": "Af dea Seitn gibts zua Zeit koan Text.\nDu konst [[Special:Search/{{PAGENAME}}|in Seitntitl]] in andan Seitn suacha, oda <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} dia de Logbiachln dazua oschaugn]</span>, oba du hosd koa Berechtigung de Seitn ozlegn.",
        "userpage-userdoesnotexist": "Des Benutzerkonto „<nowiki>$1</nowiki>“ is ned vurhånden. Bittschee priaf, ob du de Seiten wirkle erstöin/beorweiten wüist.",
        "template-semiprotected": "(schreibgschitzt fia ned-ogmejdte Nutza)",
        "hiddencategories": "De Seitn is in {{PLURAL:$1|a vasteckde Kategorie|$1 vasteckde Kategorina}} eisortiad:",
        "nocreate-loggedin": "Du host koah Berechtigung, neiche Seiten z' erstön.",
-       "permissionserrors": "Berechtigungsfeeler",
+       "permissionserrors": "Berechtigungsfaila",
        "permissionserrorstext": "Du hosd koa Recht, des z doa. {{PLURAL:$1|Grund|Grind}}:",
        "permissionserrorstext-withaction": "Du hosd aus {{PLURAL:$1|foigendm Grund|foigendn Grind}} koa Recht ned, $2:",
        "recreate-moveddeleted-warn": "'''Obocht: Du legst a Seitn o, wo scho friaa glescht worn is.'''\n\nBittschee ibaleg da genau, obs sinnvoi is de Seitn ozlegn.\nDes Lesch- und Vaschiab-Logbuach dazua findsd do:",
        "histlegend": "Zua Ozoag vo de Endarunga oafoch de z vagleichandn Versiona und Schoitflechn „{{int:compareselectedversions}}“ druckn.<br />\n* ({{int:cur}}) = Unterschied zua aktuelln Version, ({{int:last}}) = Unterschied zua vorherign Version\n* Uhrzeid/Datum = Version za dera Zeid, Nutzanama/IP-Adress vom Beorbata, {{int:minoreditletter}} = Kloane Endarung",
        "history-fieldset-title": "Suach in da Versionsgschicht",
        "history-show-deleted": "Nua gleschte Versiona",
-       "histfirst": "Ejtaste",
+       "histfirst": "Ejdaste",
        "histlast": "Neiaste",
        "historyempty": "(laar)",
        "history-feed-title": "Versiónsgschicht",
        "shown-title": "Zoag $1 {{PLURAL:$1|Ergebnis|Ergebniss}} pro Seitn",
        "viewprevnext": "Zoag ($1 {{int:pipe-separator}} $2) ($3)",
        "searchmenu-exists": "'''Es gibt a Seiten, wo „[[:$1]]“ hoasst.'''",
-       "searchmenu-new": "'''De Seitn „[[:$1]]“ in em Wiki eastejn.'''",
+       "searchmenu-new": "<strong>Schreib an Artike „[[:$1]]“ in dem Wiki.</strong> {{PLURAL:$2|0=|Schaug da aa de Artike oo, wosd iwa dei Suach gfundn host.|Schaug da aa de gfundanan Suachagebniss oo.}}",
        "searchprofile-articles": "Inhoidsseitn",
        "searchprofile-images": "Muitimedia",
        "searchprofile-everything": "Ollas",
        "action-createpage": "Seiten z' dastön",
        "action-autopatrol": "eigerne Beorweitungen ois kontroilird markirn",
        "nchanges": "$1 {{PLURAL:$1|Endarung|Endarunga}}",
+       "enhancedrc-history": "Valaf",
        "recentchanges": "Letzte Endarunga",
        "recentchanges-legend": "Ozoagoptiona",
        "recentchanges-summary": "Auf derer Seiten kåst d' létzden Änderrungen auf '''{{SITENAME}}''' nochévavóing.",
        "recentchanges-label-minor": "Kloane Endarunga",
        "recentchanges-label-bot": "Endarung duach an Bot",
        "recentchanges-label-unpatrolled": "De Endarung is no ned kontrolliad worn",
-       "rcnotefrom": "Untn san de Endarunga seit  '''$2''' (bis za '''$1''' Ozoagn).",
+       "rcnotefrom": "Oozoagt {{PLURAL:$5|wead de Endarung|wean de Endarunga}} seitd <strong>$3, $4</strong> (max. <strong>$1</strong> Eihdräg).",
        "rclistfrom": "Nua Endarunga seit $3 $2 zoagn",
        "rcshowhideminor": "Kloane Endarunga $1",
        "rcshowhideminor-hide": "Ausblendn",
        "rcshowhidebots": "Bots $1",
-       "rcshowhideliu": "Eigloggte Nutza $1",
+       "rcshowhidebots-show": "Ozoang",
+       "rcshowhideliu": "Registriade Nutza $1",
        "rcshowhideliu-hide": "Ausblendn",
        "rcshowhideanons": "Anonyme Nutza $1",
        "rcshowhideanons-hide": "Ausblendn",
        "rcshowhidepatr": "Kontrolliade Endarunga $1",
        "rcshowhidemine": "Meine Beidreg $1",
        "rcshowhidemine-hide": "Ausblendn",
-       "rclinks": "De letztn Endarunga vo de letztn $2 Dog zoagn",
+       "rclinks": "Zoag de letztn $1 Endarunga vo de letztn $2 Dog.",
        "diff": "Untaschied",
        "hist": "Versiona",
        "hide": "Ausblendn",
        "newpageletter": "N",
        "boteditletter": "B",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|beówochtender|beówochtende}} Benutzer]",
+       "rc-change-size-new": "$1 {{PLURAL:$1|Byte|Bytes}} noch da Endarung",
        "newsectionsummary": "Neicher Obschnit /* $1 */",
        "rc-enhanced-expand": "Details zoagn (braucht JavaScript)",
        "rc-enhanced-hide": "Details vastecka",
        "recentchangeslinked-feed": "Valinkts priaffm",
        "recentchangeslinked-toolbox": "Endarunga af valinktn Seitn",
        "recentchangeslinked-title": "Endarunga wo vo „$1“ valinkt san",
-       "recentchangeslinked-summary": "Des is a Listn vo de letztn Endarunga af Seitn, de wo vo ana bstimmtn Seitn valinkt san (bzw. za ana bstimmtn Kategorie ghean).\nSeitn af [[Special:Watchlist|deina Beobochtungslistn]] san '''fett'''.",
+       "recentchangeslinked-summary": "Gib an Seitnnama oo, damidst de Endarunga siagst, wo zua oda vo da Seitn valinkt san. Damidst Mitglieda vo ana Kategorie siagst, gib „{{ns:category}}:''Nam vo da Kategorie''“ eih. 'Endarunga vo Seitn af [[Special:Watchlist|dainer Beobochtalistn]] san<strong>fett</strong> viaraghom.",
        "recentchangeslinked-page": "Seitn:",
        "recentchangeslinked-to": "Zoagt Änderrungen auf Seiten, dé do her valinken",
        "upload": "Affelodn",
        "sharedupload-desc-there": "De Datei stãmmt aus $1 und deaf bei ãndera Projekte vawendt wean. Schau auf'd [$2 Dateibeschreibungsseitn] fia weidare Infoamazionen.",
        "sharedupload-desc-here": "De Datei stammt aus $1 und deaf vo andan Projektn vawendt wean. De Bschreibung vo da [$2 Dateibschreibungsseitn] wead unen ozoagt.",
        "uploadnewversion-linktext": "A neiche Versión voh derer Daatei aufféloon",
+       "upload-disallowed-here": "Du konst de Datei ned iwaschreim.",
        "filerevert-defaultcomment": "zruckgsétzd auf dé Versión vom $1, $2 ($3)",
        "filerevert-submit": "Zrucksetzen",
        "filedelete-legend": "Lésch dé Daatei",
        "emailuserfooter": "Dé E-Mail is voh {{SITENAME}}-Benutzer „$1“ an „$2“ gsendt worn.",
        "usermessage-summary": "Systémnoochricht gspeicherd.",
        "usermessage-editor": "Systém-Messenger",
-       "watchlist": "Beobochtungslistn",
+       "watchlist": "Mei Beobochta",
        "mywatchlist": "Mei Beobochta",
        "watchlistfor2": "Vo $1 $2",
        "nowatchlist": "Es gibt koane Eihträg auf deiner Beówochtungslisten.",
        "notvisiblerev": "Versión is gléschd worn",
        "watchlist-details": "Du beoochst {{PLURAL:$1|$1 Seitn}}, Dischkriaseitn ned mitgrechnad",
        "wlheader-enotif": "Da E-Mail-Benoochrichtigungsdeanst is aktivierd.",
-       "wlheader-showupdated": "Seiten mid noh néd gseengne Änderrungen wern '''fett''' dorgstöd.",
-       "wlnote": "Es {{PLURAL:$1|fóigt d' létzde Änderrung|fóing d' létzden '''$1''' Änderrungen}} voh da/dé {{PLURAL:$2|Stund| '''$2''' Stunden}}. Staund: $3, $4 Uar.",
-       "wlshowlast": "Zoag dé Änderrungen voh dé létzden $1 Stunden, $2 Dog óder  (in dé létzden 30 Dog).",
+       "wlheader-showupdated": "Seitn mid no ned oogschaugtn Endarunga wean '''fett''' gschriem.",
+       "wlnote": "Es {{PLURAL:$1|foigt de letzte Endarung|foign de letztn <strong>$1</strong> Endarunga}} vo de letztn {{PLURAL:$2|Stunde|<strong>$2</strong> Stundn}}. Stand: $3, $4 Uah.",
+       "wlshowlast": "Zoag de Endarunga vo de letztn $1 Stund, $2 Dog.",
        "watchlist-options": "Mei Beobochta: Optiona",
        "watching": "Beówochten ...",
        "unwatching": "Néd Beówochten",
        "contributions": "{{GENDER:$1|Nutza}}beidreg",
        "contributions-title": "Nutzabeidräg vo „$1“",
        "mycontris": "Meine Beidreg",
-       "contribsub2": "Vo $1 ($2)",
+       "contribsub2": "Vo {{GENDER:$3|$1}} ($2)",
        "uctop": "(aktuell)",
        "month": "und Monad:",
        "year": "Bis zan Joar:",
        "whatlinkshere": "Links af de Seitn",
        "whatlinkshere-title": "Seitn, wo af „$1“ valinka",
        "whatlinkshere-page": "Seitn:",
-       "linkshere-2": "De foigandn Seitn valinka af '''„$1“''':",
-       "nolinkshere-2": "Koa Seitn valinkt af '''„$1“'''.",
+       "linkshere": "De foigandn Seitn valinka af '''„$2“''':",
+       "nolinkshere": "Koa Seitn valinkt af '''„$2“'''.",
        "isredirect": "Weidaloatungsseitn",
        "istemplate": "Vorlogneinbindung",
        "isimage": "Dateilink",
        "importlogpage": "Import-Logbuach",
        "tooltip-pt-userpage": "Dei Nutzaseitn",
        "tooltip-pt-mytalk": "Dei Dischkriaseitn",
-       "tooltip-pt-preferences": "Deine Preferenzen",
+       "tooltip-pt-preferences": "{{GENDER:|Deine}} Prefarenzen",
        "tooltip-pt-watchlist": "A Listn vo Seitn, wos du beobochtest",
        "tooltip-pt-mycontris": "A Listn vo de oagna Beidreg",
        "tooltip-pt-login": "Warad schee, wensd di omejdn dadast, es is oba ned zwingend nedig.",
        "tooltip-pt-logout": "Auslogga",
+       "tooltip-pt-createaccount": "Mia lodn di eih, a Nutzakonto oozleng und di oozmejdn; es is owa ned nedig.",
        "tooltip-ca-talk": "Dischkrian iban Seitninhoid",
        "tooltip-ca-edit": "Du konsd de Seitn beorbatn. Bittschee vawendt in Vorschau-Knopf bevorsd speichasd.",
        "tooltip-ca-addsection": "Neichn Obschnitt ofanga",
        "lastmodifiedatby": "Dé Seiten is zletzt am $1 um $2 voh $3 gänderd worn.",
        "othercontribs": "Basiard auf da Orweid voh $1",
        "creditspage": "Seiteninformaziónen",
+       "simpleantispam-label": "Anti-Spam Check.\nDo <strong>nix</strong> eihdrong!",
        "pageinfo-redirects-name": "Ozoi vo de Weidaloatunga zua dea Seitn",
        "pageinfo-subpages-value": "$1 ($2 {{PLURAL:$2|Weidaloatung|Weidaloatunga}}; $3 {{PLURAL:$3|Untaseitn|Untaseitn}})",
+       "pageinfo-toolboxlink": "Seitninformation",
        "pageinfo-redirectsto": "Weidaloatunga af",
        "markedaspatrollederrortext": "Du muasst a Seitenänderrung auswön",
        "deletedrevision": "Oide Version $1 glöscht.",
        "file-info-size": "$1 × $2 Pixel, Dateigress: $3, MIME-Typ: $4",
        "file-nohires": "Es gibt koa hehare Aflesung.",
        "svg-long-desc": "SVG-Datei, Basisgress: $1 × $2 Pixl, Dateigress: $3",
-       "show-big-image": "Volle Aflesung",
+       "show-big-image": "Originaldatei",
+       "show-big-image-size": "$1 × $2 Pixel",
        "newimages": "Neiche Daatein",
        "newimages-summary": "Dé Speziaalseiten zoagt d' zlétzd aufféglooderne Daatei auh.",
        "noimages": "Koane Daatein gfunden.",
        "tags": "Gütige Änderrungsmarkiarunen",
        "tag-filter": "[[Special:Tags|Markiarungs]]-Fuita:",
        "tag-filter-submit": "Füter",
+       "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|Markierung|Markiarunga}}]]: $2)",
        "tags-title": "Markiarungen",
        "tags-intro": "Dé Seiten zoagt olle Markiarungen, dé fyr Beorweidungen vawendt wern, sówia dé Bedeitung voh dé.",
        "tags-tag": "Markiarungsnåm",
        "htmlform-selectorother-other": "Åndre",
        "logentry-move-move_redir": "$1 hod de Seitn $3 af $4 {{GENDER:$2|verschom}} und hod dabei a Weidaloatung ibaschriem",
        "logentry-move-move_redir-noredirect": "$1 hod de Seitn $3 af $4 {{GENDER:$2|verschom}} und dabei a Weidaloatung ibaschriem, ohne a neiche ozlegn",
+       "logentry-newusers-create": "Nutzakonto $1 is {{GENDER:$2|eastejt}} worn",
        "searchsuggest-search": "Suach (af Boarisch oda Deutsch)",
        "searchsuggest-containing": "Voitextsuach noch ..."
 }
index a15010d..e0e4805 100644 (file)
@@ -12,7 +12,8 @@
                        "Oldstoneage",
                        "Baloch Afghanistan",
                        "Mjbmr",
-                       "Macofe"
+                       "Macofe",
+                       "Matěj Suchánek"
                ]
        },
        "tog-underline": ":لینکانآ خط کش",
        "yourdiff": "تفاوتان",
        "copyrightwarning": "لطفا توجه بیت که کل نوشته یات ته {{SITENAME}}  تحت $2 نشر بنت.(بچار په جزیات$1).\nاگه شما لوٹیت شمی نوشتانک اصلاح و دگه چهاپ مبنت، اچه آیانا ادان مهلیت.\nشما ما را قول دهیت که وتی چیزا بنویسیت یا چه یک دامین عمومی کپی کتگیت.\n''' نوشتانکی که کپی رایت دارند بی اجازه ادا هور مکنیت'''",
        "copyrightwarning2": "لطفا توجه کنیت که کل مشارکاتن ته {{SITENAME}} شاید اصلاح, عوض و یا توسط دگه شرکت کننده آن حذف بنت.\nاگر شما نه لوٹیت شمی نوشتاک گون بی رحمی اصلاح مه بنت، اچه شما آیء ادان دیم مه دهیت.<br />\nشما هنچوش ما را قول دهیت که شما شی وت نوشتت یا ایء چه یک دامین عمومی یا هنچوشین آزاتین منبع کپی کتیت.(بچار $1 په جزییات).\n''' نوشتاکی که حق کپی دارنت بی اجازت دیم مه دهیت!'''",
-       "longpageerror": "'''ارور: ائ سیاهگء که راهیگ کتگ ات {{PULAR:$1|یک کیلوبایت|$1 کیلوبایت}} اندازگ داریت. ائ اندازگ چه ماکسیممء {{PLURAL:$2|یک کیلوبایت|$2 کیلوبایت}} گیشتر انت.'''\nنبیت که آئرا ذخیرگ بکن ات.",
+       "longpageerror": "'''ارور: ائ سیاهگء که راهیگ کتگ ات {{PLURAL:$1|یک کیلوبایت|$1 کیلوبایت}} اندازگ داریت. ائ اندازگ چه ماکسیممء {{PLURAL:$2|یک کیلوبایت|$2 کیلوبایت}} گیشتر انت.'''\nنبیت که آئرا ذخیرگ بکن ات.",
        "readonlywarning": "'''هژاری: دیتابیس پر جوڑ کتنء واسته کبل بیتگ انت، پمیشکا انیگء نبیت که وتی ادیتانء ذخیرگ بکن ات.'''\nاگان لوٹ ات وتی سیاهگء مان یک تکست فایلء کپی و پر آیوکء ذخیرگ بکن ات.\n\nهما ماسٹر که آئرا کبل کتگ ائ توضیحء درشان کتگ انت: $1",
        "protectedpagewarning": "'''هوژاری: ائ تاک پراتکت بیتگ انت، گڑا تهنا کاربرانء گون ماسٹری حالتء توان انت که آئرا ادیت بکن انت'''\nآهرین سیاهگ که گون ائ بابتء همگرنچ انت جهلیگء آتکگ انت:",
        "semiprotectedpagewarning": "'''بزان:''' ائ پیج کبل بیتگ تانکه تهنا رجستر کتگین کاربران بتوان انت آئرا ادیت بکن انت.\nآهرین سیاهگ که گون ائ بابتء همگرنچ انت جهلیگء آتکگ:",
        "whatlinkshere": "ای لینکی که ادا هست",
        "whatlinkshere-title": "صفحاتی که لینگ بوتگنت په \"$1\"",
        "whatlinkshere-page": "صفحه:",
-       "linkshere-2": "جهلیگی صفحات لینک بوت '''$1''':",
-       "nolinkshere-2": "هچ لینک صفحه ای په '''$1'''.",
-       "nolinkshere-ns-2": "هج صفحه ای لینک نهنت په '''$1''' ته ای انتخابی نام فضا",
+       "linkshere": "جهلیگی صفحات لینک بوت '''$2''':",
+       "nolinkshere": "هچ لینک صفحه ای په '''$2'''.",
+       "nolinkshere-ns": "هج صفحه ای لینک نهنت په '''$2''' ته ای انتخابی نام فضا",
        "isredirect": "صفحه غیر مستقیم",
        "istemplate": "همراهی",
        "isimage": "لینک عکس",
        "markedaspatrollederror-noautopatrol": "شما را اجازت نیست وتی تغییراتء په عنوان نظارت بیتگین نشان کنیت.",
        "patrol-log-page": "آمار نظارت",
        "patrol-log-header": "شی آماری چه بازبینی آن گشتی انت.",
-       "log-show-hide-patrol": "$1  آمار گشت",
        "deletedrevision": "قدیمی بازبینی $1 حذف بوت",
        "filedeleteerror-short": "حطا حذف فایل: $1",
        "filedeleteerror-long": "حطای پیش آتک وهدی که فایل حذف بیگت:\n\n$1",
index a839c35..2913aa2 100644 (file)
        "whatlinkshere": "Ano an mga makasugpon digde",
        "whatlinkshere-title": "Mga pahina na nakasugpon sa \"$1\"",
        "whatlinkshere-page": "Pahina:",
-       "linkshere-2": "An mga minasunod na pahina isinusugpon sa '''$1''':",
-       "nolinkshere-2": "Mayong mga pahinang kasugpon sa '''$1'''.",
-       "nolinkshere-ns-2": "Mayong pahina na nakatakod sa '''$1''' sa piniling ngaran-espacio.",
+       "linkshere": "An mga minasunod na pahina isinusugpon sa '''$2''':",
+       "nolinkshere": "Mayong mga pahinang kasugpon sa '''$2'''.",
+       "nolinkshere-ns": "Mayong pahina na nakatakod sa '''$2''' sa piniling ngaran-espacio.",
        "isredirect": "palikwaton an pahina",
        "istemplate": "pinagkabalihan",
        "isimage": "kasugpon nin sagunson",
        "markedaspatrollederrornotify": "Pagmamarka bilang patrolyado na nagpalya.",
        "patrol-log-page": "Laóg kan Pigpapatrolya",
        "patrol-log-header": "Ini an sarong talaan kan patrolyadong mga rebisyon.",
-       "log-show-hide-patrol": "$1 talaan sa patrolya",
        "deletedrevision": "Pigparâ an lumang pagribay na $1.",
        "filedeleteerror-short": "Salâ sa pagparà kan dokumento: $1",
        "filedeleteerror-long": "May mga nasabat na salâ mientras na pigpaparâ an ''file'':\n\n$1",
index c777468..84b4e80 100644 (file)
        "customcssprotected": "Вы ня маеце правоў на рэдагаваньне гэтай CSS-старонкі, таму што яна ўтрымлівае пэрсанальныя налады іншага ўдзельніка.",
        "customjsonprotected": "Вы ня маеце дазволу на рэдагаваньне гэтай JSON-старонкі, таму што яна ўтрымлівае пэрсанальныя налады іншага ўдзельніка.",
        "customjsprotected": "Вы ня маеце правоў на рэдагаваньне гэтай старонкі JavaScript, таму што яна ўтрымлівае пэрсанальныя налады іншага ўдзельніка.",
+       "sitecssprotected": "Вы ня маеце дазволу на рэдагаваньне гэтай CSS-старонкі, бо гэта можа паўплываць на ўсіх удзельнікаў",
+       "sitejsonprotected": "Вы ня маеце дазволу на рэдагаваньне гэтай JSON-старонкі, бо гэта можа паўплываць на ўсіх удзельнікаў",
+       "sitejsprotected": "Вы ня маеце дазволу на рэдагаваньне гэтай JavaScript-старонкі, бо гэта можа паўплываць на ўсіх наведнікаў",
        "mycustomcssprotected": "Вы ня маеце дазволу рэдагаваць гэтую CSS-старонку.",
        "mycustomjsonprotected": "Вы ня маеце дазволу на рэдагаваньне гэтай JSON-старонкі.",
        "mycustomjsprotected": "Вы ня маеце дазволу рэдагаваць гэтую JavaScript-старонку.",
        "resetpass-abort-generic": "Зьмяненьне паролю было скасаванае пашырэньнем.",
        "resetpass-expired": "Тэрмін дзеяньня вашага паролю скончыўся. Калі ласка, пазначце новы пароль для ўваходу ў сыстэму.",
        "resetpass-expired-soft": "Тэрмін дзеяньня вашага паролю скончыўся і ён патрабуе замены. Калі ласка, абярыце новы пароль цяпер або націсьніце «{{int:authprovider-resetpass-skip-label}}», каб зьмяніць яго пазьней.",
-       "resetpass-validity-soft": "Ваш пароль зьяўляецца некарэктным: $1\n\nКалі ласка, абярыце зараз новы пароль або націсьніце «{{int:authprovider-resetpass-skip-label}}», каб скінуць яго пазьней.",
+       "resetpass-validity-soft": "Ваш пароль зьяўляецца некарэктным: $1\n\nКалі ласка, абярыце цяпер новы пароль або націсьніце «{{int:authprovider-resetpass-skip-label}}», каб зьмяніць яго пазьней.",
        "passwordreset": "Ачыстка паролю",
        "passwordreset-text-one": "Запоўніце гэтую форму, каб атрымаць часовы пароль электроннай поштай.",
        "passwordreset-text-many": "{{PLURAL:$1|Запоўніце адно з палёў, каб атрымаць часовы пароль праз электронную пошту.}}",
        "converter-manual-rule-error": "Знойдзеная памылка ў ручным правіле моўнага канвэртару",
        "undo-success": "Рэдагаваньне можа быць адмененае. Калі ласка, параўнайце адрозьненьні паміж вэрсіямі, каб упэўніцца, што гэта адпаведныя зьмены, а потым запішыце зьмены для сканчэньня рэдагаваньня.",
        "undo-failure": "Рэдагаваньне ня можа быць скасаванае праз канфлікт паміж папярэднімі рэдагаваньнямі.",
+       "undo-main-slot-only": "Праўка ня можа быць адмененая, бо яна ўключае зьмест па-за асноўным месцам.",
        "undo-norev": "Рэдагаваньне ня можа быць адмененае, таму што яно не існуе альбо было выдаленае.",
        "undo-nochange": "Выглядае, што праўка ўжо была адмененая.",
        "undo-summary": "Скасаваньне праўкі $1 {{GENDER:$2|удзельніка|удзельніцы}} [[Special:Contributions/$2|$2]] ([[User talk:$2|гутаркі]])",
        "diff-paragraph-moved-toold": "Параграф быў перанесены. Націсьніце, каб перайсьці ў першапачатковае месца.",
        "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": "Супадзеньні ў тэкстах старонак",
        "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-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-empty-filter": "Няма актыўных фільтраў. Паказаны ўвесь унёсак.",
        "rcfilters-filterlist-title": "Фільтры",
        "rcfilters-filterlist-whatsthis": "Як гэта працуе?",
-       "rcfilters-filterlist-feedbacklink": "Раскажыце нам, што вы думаеце пра гэтыя (новыя) фільтры",
+       "rcfilters-filterlist-feedbacklink": "Раскажыце нам, што вы думаеце пра гэтыя інструмэнты фільтраў",
        "rcfilters-highlightbutton-title": "Вылучыць вынікі",
        "rcfilters-highlightmenu-title": "Абярыце колер",
        "rcfilters-highlightmenu-help": "Абярыце колер для вылучэньня гэтай уласьцівасьці",
        "rcfilters-watchlist-showupdated": "Зьмены старонак, якія вы не наведвалі пасьля гэтых зьменаў, пазначаныя <strong>тоўстым</strong> з адпаведнымі пазнакамі.",
        "rcfilters-preference-label": "Схаваць палепшаную вэрсію апошніх зьменаў",
        "rcfilters-preference-help": "Адкатвае рэдызайн інтэрфэйсу 2017 году і ўсе інструмэнты, дададзеныя з таго часу.",
+       "rcfilters-watchlist-preference-label": "Схаваць палепшаную вэрсію сьпісу назіраньня",
+       "rcfilters-watchlist-preference-help": "Адмяняе рэдызайн інтэрфэйсу 2017 году і ўсе інструмэнты дададзеныя з таго часу.",
        "rcfilters-filter-showlinkedfrom-label": "Паказаць зьмены на старонках, на якія спасылаецца",
        "rcfilters-filter-showlinkedfrom-option-label": "<strong>Старонкі, на якія спасылаецца</strong> абраная старонка",
        "rcfilters-filter-showlinkedto-label": "Паказаць зьмены старонак, якія спасылаюцца на",
        "upload_directory_read_only": "Сэрвэр ня мае правоў на запіс у дырэкторыю загружаных файлаў ($1).",
        "uploaderror": "Памылка загрузкі",
        "upload-recreate-warning": "<strong>Увага: файл з такой назвай быў выдалены альбо перанесены.</strong>\n\nЖурнал выдаленьняў і пераносаў гэтай старонкі для зручнасьці пададзены тут:",
-       "uploadtext": "Ужывайце форму ніжэй для загрузкі файлаў.\nКаб паглядзець ці адшукаць раней загружаныя файлы, глядзіце [[Special:FileList|сьпіс загружаных файлаў]], загрузкі таксама запісваюцца ў [[Special:Log/upload|журнал загрузак]], а выдаленьні — у [[Special:Log/delete|журнал выдаленьняў]].\n\nКаб улучыць файл у старонку, ужывайце адзін з наступных варыянтаў:\n* '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:File.jpg]]</nowiki></code>''' для поўнай вэрсіі файла\n* '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:File.png|200px|thumb|left|Подпіс да выявы]]</nowiki></code>''' для выявы шырынёй 200 піксэляў у рамцы і тэкстам «Подпіс да выявы» ў якасьці подпісу\n* '''<code><nowiki>[[</nowiki>{{ns:media}}<nowiki>:File.ogg]]</nowiki></code>''' для простай спасылкі на файл безь яго адлюстраваньня.",
+       "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.",
        "upload-prohibited": "{{PLURAL:$2|Забаронены тып|Забароненыя тыпы}} файлаў: $1.",
        "ignorewarning": "Праігнараваць папярэджаньне і захаваць файл",
        "ignorewarnings": "Ігнараваць усе папярэджаньні",
        "minlength1": "Назва файлу павінна ўтрымліваць хаця б адну літару.",
-       "illegalfilename": "Назва файла «$1» зьмяшчае сымбалі, якія нельга выкарыстоўваць у назвах старонак. Калі ласка, зьмяніце назву файла і паспрабуйце загрузіць яго зноў.",
-       "filename-toolong": "Назвы файлаў ня могуць быць даўжэй 240 байтаў.",
-       "badfilename": "Назва файла была зьмененая на «$1».",
-       "filetype-mime-mismatch": "Пашырэньне файла «.$1» не адпавядае выяўленаму MIME-тыпу файла ($2).",
-       "filetype-badmime": "Загрузка файлаў тыпу MIME «$1» забароненая.",
-       "filetype-bad-ie-mime": "Ð\9dемагÑ\87Ñ\8bма Ð·Ð°Ð³Ñ\80Ñ\83зÑ\96Ñ\86Ñ\8c Ð³Ñ\8dÑ\82Ñ\8b Ñ\84айл, Ñ\82амÑ\83 Ñ\88Ñ\82о Internet Explorer Ð²Ñ\8bзнаÑ\87Ñ\8bÑ\9e Ñ\8fго Ñ\8fк Â«$1», Ñ\88Ñ\82о Ð°Ð·Ð½Ð°Ñ\87ае, Ñ\88Ñ\82о Ñ\82Ñ\8bп Ð³Ñ\8dÑ\82ага Ñ\84айла Ð·Ð°Ð±Ð°Ñ\80оненÑ\8b Ñ\96 Ð¿Ð°Ñ\82Ñ\8dнÑ\86Ñ\8bÑ\8fлÑ\8cна небясьпечны.",
+       "illegalfilename": "Назва файлу «$1» зьмяшчае сымбалі, якія нельга выкарыстоўваць у назвах старонак. Калі ласка, зьмяніце назву файлу і паспрабуйце загрузіць яго зноў.",
+       "filename-toolong": "Назвы файлаў ня могуць быць даўжэй за 240 байтаў.",
+       "badfilename": "Назва файлу была зьмененая на «$1».",
+       "filetype-mime-mismatch": "Пашырэньне файлу «.$1» не адпавядае выяўленаму MIME-тыпу файлу ($2).",
+       "filetype-badmime": "Загрузка файлаў MIME-тыпу «$1» забароненая.",
+       "filetype-bad-ie-mime": "Ð\9dемагÑ\87Ñ\8bма Ð·Ð°Ð³Ñ\80Ñ\83зÑ\96Ñ\86Ñ\8c Ð³Ñ\8dÑ\82Ñ\8b Ñ\84айл, Ñ\82амÑ\83 Ñ\88Ñ\82о Internet Explorer Ð²Ñ\8bзнаÑ\87Ñ\8bÑ\86Ñ\8c Ñ\8fго Ñ\8fк Â«$1», Ñ\88Ñ\82о Ð°Ð·Ð½Ð°Ñ\87ае, Ñ\88Ñ\82о Ñ\82Ñ\8bп Ð³Ñ\8dÑ\82ага Ñ\84айлÑ\83 Ð·Ð°Ð±Ð°Ñ\80оненÑ\8b Ñ\96 Ð¿Ð°Ñ\82Ñ\8dнÑ\86Ñ\8bйна небясьпечны.",
        "filetype-unwanted-type": "<strong>«.$1»</strong> — непажаданы тып файла.\n{{PLURAL:$3|1=Пажаданым тыпам файла зьяўляецца|Пажаданымі тыпамі файлаў зьяўляюцца:}} $2.",
        "filetype-banned-type": "<strong>«.$1»</strong> — {{PLURAL:$4|1=забаронены тып файлаў|забароненыя тыпы файлаў}}.\n{{PLURAL:$3|1=Дазволены тып файлаў|Дазволеныя тыпы файлаў}}: $2.",
        "filetype-missing": "Файл ня мае пашырэньня (напрыклад, «.jpg»).",
-       "empty-file": "Ð\94аÑ\81ланÑ\8b Ð\92амі файл пусты.",
-       "file-too-large": "Ð\94аÑ\81ланÑ\8b Ð\92амі файл занадта вялікі.",
-       "filename-tooshort": "Назва файла занадта кароткая.",
-       "filetype-banned": "Гэты тып файла забаронены.",
-       "verification-error": "Ð\93Ñ\8dÑ\82Ñ\8b Ñ\84айл Ð½Ðµ Ð¿Ñ\80айÑ\88оÑ\9e Ð²Ñ\8dÑ\80Ñ\8bÑ\84Ñ\96каÑ\86Ñ\8bÑ\8e.",
-       "hookaborted": "Ð\9fÑ\80апанаванаÑ\8f Ð\92амÑ\96 Ð·Ñ\8cмена Ð±Ñ\8bла Ð°Ð´Ñ\85Ñ\96ленаÑ\8f Ð°Ð¿Ñ\80аÑ\86оÑ\9eÑ\88Ñ\87Ñ\8bкам Ð¿Ð°Ñ\88Ñ\8bÑ\80Ñ\8dнÑ\8cнÑ\8f.",
-       "illegal-filename": "Недазволеная назва файла.",
-       "overwrite": "Замена існуючага файла забароненая.",
+       "empty-file": "Ð\94аÑ\81ланÑ\8b Ð²амі файл пусты.",
+       "file-too-large": "Ð\94аÑ\81ланÑ\8b Ð²амі файл занадта вялікі.",
+       "filename-tooshort": "Назва файлу занадта кароткая.",
+       "filetype-banned": "Гэты тып файлу забаронены.",
+       "verification-error": "Ð\93Ñ\8dÑ\82Ñ\8b Ñ\84айл Ð½Ðµ Ð¿Ñ\80айÑ\88оÑ\9e Ð¿Ñ\80авеÑ\80кÑ\83.",
+       "hookaborted": "Ð\9fÑ\80апанаванаÑ\8f Ð²Ð°Ð¼Ñ\96 Ð·Ñ\8cмена Ð±Ñ\8bла Ð°Ð´Ñ\85Ñ\96ленаÑ\8f Ð¿Ð°Ñ\88Ñ\8bÑ\80Ñ\8dнÑ\8cнем.",
+       "illegal-filename": "Недазволеная назва файлу.",
+       "overwrite": "Замена існага файлу забароненая.",
        "unknown-error": "Узьнікла невядомая памылка.",
        "tmp-create-error": "Немагчыма стварыць часовы файл.",
-       "tmp-write-error": "Памылка запісу часовага файла.",
-       "large-file": "Рэкамэндаваны памер файлаў — ня болей $1;\nпамер гэтага файла — $2.",
-       "largefileserver": "Памер гэтага файла перавышае максымальна дазволены.",
-       "emptyfile": "Загружаны файл, здаецца, пусты. Магчыма гэты адбылося з-за памылкі ў назьве файла.\nУдакладніце, ці Вы сапраўды жадаеце загрузіць гэты файл.",
+       "tmp-write-error": "Памылка запісу часовага файлу.",
+       "large-file": "Рэкамэндаваны памер файлаў — ня болей за $1;\nпамер гэтага файлу — $2.",
+       "largefileserver": "Памер гэтага файлу перавышае максымальна дазволены сэрвэрам.",
+       "emptyfile": "Загружаны файл, здаецца, пусты. Магчыма гэта адбылося з-за памылкі ў назьве файлу. Калі ласка, удакладніце, ці вы сапраўды жадаеце загрузіць гэты файл.",
        "windows-nonascii-filename": "Гэтая вікі не падтрымлівае назвы файлаў з спэцыяльнымі сымбалямі.",
-       "fileexists": "Файл з такой назвай ужо існуе. Калі ласка, праверце <strong>[[:$1]]</strong>, калі Вы ня ўпэўненыя, што жадаеце яго замяніць. [[$1|thumb]]",
-       "filepageexists": "Старонка апісаньня для гэтага файла ўжо існуе як <strong>[[:$1]]</strong>, але файла з такой назвай няма.\nАпісаньне якое Вы дадалі ня зьявіцца на старонцы апісаньня.\nКаб яно там зьявілася, Вам трэба рэдагаваць яе самастойна.\n[[$1|thumb]]",
+       "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": "Верагодна файл зьяўляецца паменшанай копіяй ''(мініятурай)''. [[$1|thumb]]\nКалі ласка, праверце файл <strong>[[:$1]]</strong>.\nКалі правераны файл зьяўляецца той жа выявай, то загрузка мініятуры ня мае сэнсу.",
-       "file-thumbnail-no": "Назва файла пачынаецца з <strong>$1</strong>.\nВерагодна гэта паменшаная копія выявы ''(мініятура)''.\nКалі Вы маеце гэтую выяву ў поўным памеры, загрузіце яе, альбо зьмяніце назву файла.",
+       "fileexists-thumbnail-yes": "Верагодна, файл зьяўляецца паменшанай копіяй (<em>мініятурай</em>).\n[[$1|thumb]]\nКалі ласка, праверце файл <strong>[[:$1]]</strong>.\nКалі правераны файл зьяўляецца той жа выявай, то загрузка дадатковай мініятуры ня мае сэнсу.",
+       "file-thumbnail-no": "Назва файлу пачынаецца з <strong>$1</strong>.\nВерагодна, гэта паменшаная копія выявы (<em>мініятура</em>).\nКалі вы маеце гэтую выяву ў поўным памеры, загрузіце яе, альбо зьмяніце назву файлу.",
        "fileexists-forbidden": "Файл з такой назвай ужо існуе і ня можа быць перапісаны.\nКалі ласка, вярніцеся назад і загрузіце гэты файл з новай назвай. [[File:$1|thumb|center|$1]]",
-       "fileexists-shared-forbidden": "Файл Ð· Ñ\82акой Ð½Ð°Ð·Ð²Ð°Ð¹ Ñ\83жо Ñ\96Ñ\81нÑ\83е Ñ\9e Ð°Ð³Ñ\83лÑ\8cнÑ\8bм Ñ\81Ñ\85овÑ\96Ñ\88Ñ\87Ñ\8b Ñ\84айлаÑ\9e.\nÐ\9aалÑ\96 Ð\92Ñ\8b Ð¶Ð°Ð´Ð°ÐµÑ\86е Ð·Ð°Ð³Ñ\80Ñ\83зÑ\96Ñ\86Ñ\8c Ð\92аÑ\88 Ñ\84айл, Ð²Ñ\8fÑ\80нÑ\96Ñ\86еÑ\81Ñ\8f Ð½Ð°Ð·Ð°Ð´ Ñ\96 Ð·Ð°Ð³Ñ\80Ñ\83зÑ\96Ñ\86е Ð³Ñ\8dÑ\82Ñ\8b Ñ\84айл Ð· Ð½Ð¾Ð²Ð°Ð¹ Ð½Ð°Ð·Ð²Ð°Ð¹. [[File:$1|thumb|center|$1]]",
+       "fileexists-shared-forbidden": "Файл Ð· Ñ\82акой Ð½Ð°Ð·Ð²Ð°Ð¹ Ñ\83жо Ñ\96Ñ\81нÑ\83е Ñ\9e Ð°Ð³Ñ\83лÑ\8cнÑ\8bм Ñ\81Ñ\85овÑ\96Ñ\88Ñ\87Ñ\8b Ñ\84айлаÑ\9e.\nÐ\9aалÑ\96 Ð²Ñ\8b Ð¶Ð°Ð´Ð°ÐµÑ\86е Ð·Ð°Ð³Ñ\80Ñ\83зÑ\96Ñ\86Ñ\8c Ð²Ð°Ñ\88 Ñ\84айл, Ð²Ñ\8fÑ\80нÑ\96Ñ\86еÑ\81Ñ\8f Ð½Ð°Ð·Ð°Ð´ Ñ\96 Ð·Ð°Ð³Ñ\80Ñ\83зÑ\96Ñ\86е Ð³Ñ\8dÑ\82Ñ\8b Ñ\84айл Ð· Ð½Ð¾Ð²Ð°Ð¹ Ð½Ð°Ð·Ð²Ð°Ð¹.\n[[File:$1|thumb|center|$1]]",
        "fileexists-no-change": "Гэтая загрузка зьяўляецца дакладнай копіяй цяперашняй вэрсіі <strong>[[:$1]]</strong>.",
        "fileexists-duplicate-version": "Гэтая загрузка зьяўляецца дакладнай копіяй {{PLURAL:$2|1=старой вэрсіі|старых вэрсіяў}} файлу <strong>[[:$1]]</strong>.",
        "file-exists-duplicate": "Гэты файл дублюе {{PLURAL:$1|1=наступны файл|наступныя файлы}}:",
-       "file-deleted-duplicate": "Ð\9fадобнÑ\8b Ñ\84айл ([[:$1]]) Ñ\83жо Ð²Ñ\8bдалÑ\8fÑ\9eÑ\81Ñ\8f. Ð\9aалÑ\96 Ð»Ð°Ñ\81ка, Ð¿Ð°Ð³Ð»Ñ\8fдзÑ\96Ñ\86е Ð³Ñ\96Ñ\81Ñ\82оÑ\80Ñ\8bÑ\8e Ð²Ñ\8bдаленÑ\8cнÑ\8fÑ\9e Ð³Ñ\8dÑ\82ага Ñ\84айла перад яго паўторнай загрузкай.",
+       "file-deleted-duplicate": "Ð\86дÑ\8dнÑ\82Ñ\8bÑ\87нÑ\8b Ñ\84айл ([[:$1]]) Ñ\83жо Ñ\80аней Ð²Ñ\8bдалÑ\8fÑ\9eÑ\81Ñ\8f. Ð\92ам Ñ\82Ñ\80Ñ\8dба Ð¿Ð°Ð³Ð»Ñ\8fдзеÑ\86Ñ\8c Ð³Ñ\96Ñ\81Ñ\82оÑ\80Ñ\8bÑ\8e Ð²Ñ\8bдаленÑ\8cнÑ\8fÑ\9e Ð³Ñ\8dÑ\82ага Ñ\84айлÑ\83 перад яго паўторнай загрузкай.",
        "file-deleted-duplicate-notitle": "Файл, ідэнтычны гэтаму файлу, раней ужо быў выдалены, а назва файла была забароненая.\nВам трэба зьвярнуцца да некага з правамі прагляду зьвестак забароненых файлаў, каб прааналізаваць сытуацыю перад тым, як загружаць файл ізноў.",
        "uploadwarning": "Папярэджаньне",
-       "uploadwarning-text": "Калі ласка, зьмяніце апісаньне файла ніжэй і паспрабуйце ізноў.",
+       "uploadwarning-text": "Калі ласка, зьмяніце апісаньне файлу ніжэй і паспрабуйце ізноў.",
        "uploadwarning-text-nostash": "Калі ласка, загрузіце файл ізноў, зьмніце апісаньне ніжэй і паспрабуйце яшчэ раз.",
        "savefile": "Захаваць файл",
-       "uploaddisabled": "Загрузка файлаў забароненая",
+       "uploaddisabled": "Загрузка файлаў забароненая.",
        "copyuploaddisabled": "Загрузка праз URL-адрас адключаная.",
        "uploaddisabledtext": "Загрузка файлаў забароненая.",
-       "php-uploaddisabledtext": "Загрузка файлаў была адключаная ў парамэтрах канфігурацыі PHP. Калі ласка, праверце значэньне парамэтра «file_uploads».",
+       "php-uploaddisabledtext": "Загрузка файлаў была адключаная ў парамэтрах канфігурацыі PHP. Калі ласка, праверце значэньне парамэтру file_uploads.",
        "uploadscripted": "Гэты файл утрымлівае HTML-код альбо скрыпт, які можа памылкова апрацоўвацца браўзэрам.",
        "upload-scripted-pi-callback": "Немагчыма загрузіць файл, які ўтрымлівае інструкцыі апрацоўкі табліцы стыляў XML.",
        "upload-scripted-dtd": "Немагчыма загрузіць SVG-файлы, якія ўтрымліваюць нестандартнае DTD-абвяшчэньне.",
        "uploaded-setting-handler-svg": "SVG, які выстаўляе атрыбут «handler» з дапамогай аддаленага адрасу/зьвестак/скрыпту, блякуецца. У загружаным SVG-файле знойдзена <code>$1=\"$2\"</code>.",
        "uploaded-remote-url-svg": "SVG, які выстаўляе любы атрыбут з дапамогай аддаленага URL-адрасу, блякуецца. У загружаным SVG-файле знойдзена <code>$1=\"$2\"</code>.",
        "uploaded-image-filter-svg": "У загружаным SVG-файле знойдзены фільтар выяваў з URL-адрасам: <code>&lt;$1 $2=\"$3\"&gt;</code>.",
-       "uploadscriptednamespace": "Гэты SVG-файл утрымлівае няслушную прастору назваў «<nowiki>$1</nowiki>»",
+       "uploadscriptednamespace": "Гэты SVG-файл утрымлівае недапушчальную прастору назваў «<nowiki>$1</nowiki>».",
        "uploadinvalidxml": "Не атрымалася прааналізаваць XML у загружаным файле.",
        "uploadvirus": "Файл утрымлівае вірус! Падрабязнасьці: $1",
-       "uploadjava": "Файл зьяўляецца ZIP-архівам, які зьмяшчае .class-файл Java.\nЗагрузка Java-файлаў забароненая ў мэтах бясьпекі.",
+       "uploadjava": "Файл зьяўляецца ZIP-архівам, які зьмяшчае .class-файл Java.\nЗагрузка Java-файлаў забароненая, бо яны могуць быць прычынай абыходу абмежаваньняў бясьпекі.",
        "upload-source": "Крынічны файл",
-       "sourcefilename": "Пачатковая назва файла:",
+       "sourcefilename": "Пачатковая назва файлу:",
        "sourceurl": "URL-адрас крыніцы:",
-       "destfilename": "Канчатковая назва файла:",
-       "upload-maxfilesize": "Максымальны памер файла: $1",
-       "upload-description": "Апісаньне файла",
+       "destfilename": "Канчатковая назва файлу:",
+       "upload-maxfilesize": "Максымальны памер файлу: $1",
+       "upload-description": "Апісаньне файлу",
        "upload-options": "Налады загрузкі",
        "watchthisupload": "Назіраць за гэтым файлам",
        "filewasdeleted": "Файл з такой назвай загружаўся, але быў выдалены.\nВам трэба праверыць $1 перад новай загрузкай.",
        "filename-thumb-name": "Гэта выглядае як назва мініятуры. Калі ласка, не загружайце мініятуры назад у тую ж вікі. Калі вам неабходны гэты файл, выпраўце назву на больш зразумелую, каб яна ня ўтрымлівала прэфікс мініятуры.",
-       "filename-bad-prefix": "Назва файла, які Вы загружаеце, пачынаецца з '''«$1»'''. Падобныя бессэнсоўныя назвы звычайна ствараюцца аўтаматычна лічбавымі фотаапаратамі. Калі ласка, абярыце больш зразумелую назву для Вашага файла.",
+       "filename-bad-prefix": "Назва файлу, які вы загружаеце, пачынаецца з <strong>«$1»</strong>, што зьяўляецца неапісальнай назвай, якія звычайна ствараюцца аўтаматычна лічбавымі фотаапаратамі. Калі ласка, абярыце больш зразумелую назву для вашага файлу.",
        "upload-proto-error": "Няслушны пратакол",
        "upload-proto-error-text": "Аддаленая загрузка файлаў патрабуе URL-адрас, які пачынаецца з <code>http://</code> альбо <code>ftp://</code>.",
        "upload-file-error": "Унутраная памылка",
        "uploadstash-zero-length": "Файл мае нулявую даўжыню.",
        "invalid-chunk-offset": "Няслушнае зрушэньне фрагмэнту",
        "img-auth-accessdenied": "Доступ забаронены",
-       "img-auth-nopathinfo": "Адсутнічае PATH_INFO.\nВаш сэрвэр не ўстаноўлены на пропуск гэтай інфармацыі.\nМагчма, ён працуе праз CGI і не падтрымлівае img_auth.\nГлядзіце https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization.",
+       "img-auth-nopathinfo": "Адсутнічаюць зьвесткі пра шлях.\nВаш сэрвэр мусіць быць наладжаны на пропуск зьменных REQUEST_URI і/ці PATH_INFO.\nКалі гэта так, паспрабуйце ўключыць $wgUsePathInfo.\nГлядзіце https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization.",
        "img-auth-notindir": "Неабходнага шляху няма ў дырэкторыі загрузкі, пазначанай у канфігурацыі.",
        "img-auth-badtitle": "Немагчыма стварыць слушную назву з «$1».",
        "img-auth-nologinnWL": "Вы не ўвайшлі ў сыстэму, а «$1» не знаходзіцца ў белым сьпісе.",
        "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": "Немагчыма адкрыць пазначаны URL-адрас.\nКалі ласка, упэўніцеся, што адрас слушны і сайт працуе.",
        "upload-curl-error28": "Ліміт часу загрузкі скончыўся",
        "speciallogtitlelabel": "Мэта (назва ці {{ns:user}}:імя_ўдзельніка для ўдзельніка):",
        "log": "Журналы падзеяў",
        "logeventslist-submit": "Паказаць",
+       "logeventslist-more-filters": "Паказаць дадатковыя журналы:",
+       "logeventslist-patrol-log": "Журнал патруляваньня",
+       "logeventslist-tag-log": "Журнал метак",
        "all-logs-page": "Усе публічныя журналы падзеяў",
        "alllogstext": "Сумесны паказ усіх журналаў падзеяў {{GRAMMAR:родны|{{SITENAME}}}}.\nВы можаце адфільтраваць вынікі па тыпе журналу, удзельніку (улічваецца рэгістар) ці старонцы (таксама ўлічваецца рэгістар).",
        "logempty": "Падобных запісаў у журнале няма.",
        "dellogpage": "Журнал выдаленьняў",
        "dellogpagetext": "Сьпіс апошніх выдаленьняў.",
        "deletionlog": "журнал выдаленьняў",
+       "log-name-create": "Журнал стварэньня старонак",
+       "log-description-create": "Ніжэй знаходзіцца сьпіс апошніх стварэньняў старонак.",
+       "logentry-create-create": "$1 {{GENDER:$2|стварыў|стварыла}} старонку $3",
        "reverted": "Вернутая да папярэдняй вэрсіі",
        "deletecomment": "Прычына:",
        "deleteotherreason": "Іншая/дадатковая прычына:",
        "uctop": "(апошняя)",
        "month": "Ад месяца (і раней):",
        "year": "Ад году (і раней):",
+       "date": "З даты (і раней):",
        "sp-contributions-newbies": "Паказаць унёсак толькі з новых рахункаў",
        "sp-contributions-newbies-sub": "Унёсак пачынаючых",
        "sp-contributions-newbies-title": "Унёсак удзельнікаў з новых рахункаў",
        "whatlinkshere": "Спасылкі на старонку",
        "whatlinkshere-title": "Старонкі, якія спасылаюцца на $1",
        "whatlinkshere-page": "Старонка:",
-       "linkshere-2": "Наступныя старонкі спасылаюцца на <strong>$1</strong>:",
-       "nolinkshere-2": "Ніводная старонка не спасылаецца на <strong>$1</strong>.",
-       "nolinkshere-ns-2": "Ніводная старонка не спасылаецца на '''$1''' з выбранай прасторы назваў.",
+       "linkshere": "Наступныя старонкі спасылаюцца на <strong>$2</strong>:",
+       "nolinkshere": "Ніводная старонка не спасылаецца на <strong>$2</strong>.",
+       "nolinkshere-ns": "Ніводная старонка не спасылаецца на <strong>$2</strong> з абранай прасторы назваў.",
        "isredirect": "старонка-перанакіраваньне",
        "istemplate": "уключэньне",
        "isimage": "спасылка на файл",
        "markedaspatrollederrornotify": "Не атрымалася адпатруляваць старонку.",
        "patrol-log-page": "Журнал патруляваньняў",
        "patrol-log-header": "Гэта журнал патруляваных вэрсіяў.",
-       "log-show-hide-patrol": "$1 журнал патруляваньняў",
-       "log-show-hide-tag": "$1 журнал метак",
        "confirm-markpatrolled-button": "Добра",
        "confirm-markpatrolled-top": "Пазначыць вэрсію $3 старонкі $2 як патруляваную?",
        "deletedrevision": "Выдаленая старая вэрсія $1",
        "unregistered-user-config": "З прычынаў бясьпекі JavaScript, CSS і JSON-падстаронкі ўдзельніка ня могуць быць загружаныя для незарэгістраваных удзельнікаў.",
        "passwordpolicies": "Палітыка пароляў",
        "passwordpolicies-summary": "Гэта сьпіс дзейных палітыкаў пароляў для групаў удзельнікаў, вызначаных у гэтай вікі.",
-       "passwordpolicies-group": "Група"
+       "passwordpolicies-group": "Група",
+       "passwordpolicies-policies": "Палітыкі",
+       "passwordpolicies-policy-minimalpasswordlength": "Пароль мусіць мець даўжыню найменей $1 {{PLURAL:$1|сымбаль|сымбалі|сымбаляў}}",
+       "passwordpolicies-policy-minimumpasswordlengthtologin": "Пароль мусіць мець даўжыню найменш $1 {{PLURAL:$1|сымбаль|сымбалі|сымбаляў}}, каб уваходзіць у сыстэму",
+       "passwordpolicies-policy-passwordcannotmatchusername": "Пароль ня можа супадаць зь імем ўдзельніка",
+       "passwordpolicies-policy-passwordcannotmatchblacklist": "Пароль ня можа супадаць з паролямі з чорнага сьпісу",
+       "passwordpolicies-policy-maximalpasswordlength": "Пароль мусіць быць даўжынёй менш за $1 {{PLURAL:$1|сымбаль|сымбалі|сымбаляў}}",
+       "passwordpolicies-policy-passwordcannotbepopular": "Пароль ня можа {{PLURAL:$1|супадаць з самым папулярным паролем|быць зь сьпісу $1 папулярных пароляў}}"
 }
index 71c2d94..bd5ac50 100644 (file)
@@ -33,7 +33,8 @@
                        "Artsiom91",
                        "Andrus",
                        "Da voli",
-                       "OlegCinema"
+                       "OlegCinema",
+                       "Gorgich"
                ]
        },
        "tog-underline": "Падкрэсліваць спасылкі:",
        "thu": "Чц",
        "fri": "Пт",
        "sat": "Сб",
-       "january": "cтудзень",
+       "january": "студзень",
        "february": "люты",
        "march": "сакавік",
        "april": "красавік",
        "image_sample": "Напрыклад.jpg",
        "image_tip": "Файл у тэксце",
        "media_sample": "Напрыклад.ogg",
-       "media_tip": "Спасылка на медыя-файл",
+       "media_tip": "Спасылка на медыяфайл",
        "sig_tip": "Ваш подпіс і адзначаны час",
        "hr_tip": "Гарызантальная рыса (не злоўжывайце гэтым)",
        "summary": "Тлумачэнне:",
        "diff-paragraph-moved-toold": "Параграф быў перамешчаны. Клікніце, каб перайсці да старога месцазнаходжання.",
        "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»",
        "searchresults-title": "Вынікі пошуку «$1»",
        "titlematches": "Знойдзена ў назвах",
        "textmatches": "Знойдзена ў тэкстах",
        "rcfilters-other-review-tools": "Іншыя інструменты праверкі",
        "rcfilters-group-results-by-page": "Групіраваць вынікі паводле старонкі",
        "rcfilters-activefilters": "Актыўныя фільтры",
+       "rcfilters-activefilters-show": "Паказаць",
        "rcfilters-advancedfilters": "Пашыраныя фільтры",
        "rcfilters-limit-title": "Вынікі для паказу",
        "rcfilters-limit-and-date-label": "$1 {{PLURAL:$1|змена|змены|змен}}, $2",
        "listduplicatedfiles": "Пералік дублікатных файлаў",
        "listduplicatedfiles-summary": "Гэта пералік файлаў, у якіх найноўшая версія файла ўяўляе сабою копію апошняй версіі якога-небудзь іншага файла. Улічваюцца толькі лакальныя файлы.",
        "listduplicatedfiles-entry": "[[:File:$1|$1]] мае [[$3|{{PLURAL:$2|дублікат|$2 дублікаты|$2 дублікатаў}}]].",
-       "unusedtemplates": "ШаблонÑ\8b, Ñ\8fкÑ\96Ñ\8f Ð½Ðµ Ð²Ñ\8bкаÑ\80Ñ\8bÑ\81Ñ\82аны",
+       "unusedtemplates": "Ð\9dевÑ\8bкаÑ\80Ñ\8bÑ\81Ñ\82анÑ\8bÑ\8f Ñ\88аблоны",
        "unusedtemplatestext": "Тут пералічаныя ўсе старонкі ў прасторы назваў {{ns:template}}, якія не ўкладзеныя ў іншыя старонкі.\nПамятайце, што трэба правяраць спасылкі на шаблоны перад тым, як выдаляць іх.",
        "unusedtemplateswlh": "іншыя спасылкі",
        "randompage": "Выпадковая старонка",
        "apisandbox-dynamic-error-exists": "Параметр з назвай \"$1\" ужо існуе.",
        "apisandbox-deprecated-parameters": "Састарэлыя параметры",
        "apisandbox-fetch-token": "Аўтазапаўненне токена",
+       "apisandbox-add-multi": "Дадаць",
        "apisandbox-submit-invalid-fields-title": "Некаторыя палі недапушчальныя",
        "apisandbox-submit-invalid-fields-message": "Калі ласка, выпраўце адзначаныя палі і паспрабуйце ізноў.",
        "apisandbox-results": "Вынікі",
        "whatlinkshere": "Сюды спасылаюцца",
        "whatlinkshere-title": "Старонкі, якія спасылаюцца на \"$1\"",
        "whatlinkshere-page": "Старонка:",
-       "linkshere-2": "Наступныя старонкі спасылаюцца на <strong>$1</strong>:",
-       "nolinkshere-2": "Няма старонак, якія б спасылаліся на '''$1'''.",
-       "nolinkshere-ns-2": "Няма старонак, якія б спасылаліся на '''$1''' у гэтай прасторы назваў.",
+       "linkshere": "Наступныя старонкі спасылаюцца на <strong>$2</strong>:",
+       "nolinkshere": "Няма старонак, якія б спасылаліся на '''$2'''.",
+       "nolinkshere-ns": "Няма старонак, якія б спасылаліся на '''$2''' у гэтай прасторы назваў.",
        "isredirect": "старонка-перасылка",
        "istemplate": "уключэнне",
        "isimage": "Спасылка на выяву",
        "markedaspatrollederrornotify": "Не ўдалося пазначыць як ухваленую.",
        "patrol-log-page": "Журнал ухваленых",
        "patrol-log-header": "Журнал ухваленых версій",
-       "log-show-hide-patrol": "$1 журнал ухваленняў",
-       "log-show-hide-tag": "$1 журнал бірак",
        "confirm-markpatrolled-button": "Добра",
        "confirm-markpatrolled-top": "Пазначыць версію $3 старонкі $2 як патруляваную?",
        "deletedrevision": "Сцёрта старая версія $1",
index 40b3be4..505af10 100644 (file)
@@ -42,7 +42,8 @@
                        "Irus",
                        "Kareyac",
                        "ShockD",
-                       "Fitoschido"
+                       "Fitoschido",
+                       "Vlad5250"
                ]
        },
        "tog-underline": "Подчертаване на препратките:",
        "group-autoconfirmed": "Автоматично одобрени потребители",
        "group-bot": "Ботове",
        "group-sysop": "Администратори",
+       "group-interface-admin": "Интерфейсни администратори",
        "group-bureaucrat": "Бюрократи",
        "group-suppress": "Ревизори",
        "group-all": "(всички)",
        "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-editcontentmodel": "Редактиране на модела на съдържанието на страница",
        "right-editinterface": "Редактиране на потребителския интерфейс",
        "right-editusercss": "Редактиране на CSS файловете на други потребители",
+       "right-edituserjson": "Редактиране на JSON файловете на други потребители",
        "right-edituserjs": "Редактиране на JS файловете на други потребители",
        "right-editmyusercss": "Редактиране на собствените потребителски CSS файлове",
+       "right-editmyuserjson": "Редактиране на собствените потребителски JSON файлове",
        "right-editmyuserjs": "Редактиране на собствените потребителски JavaScript файлове",
        "right-viewmywatchlist": "Преглеждане на собствения списък за наблюдение",
        "right-editmywatchlist": "Редактиране на собствения списък за наблюдение. Забележете, че някои действия все пак ще добавят страници, дори и без текущото право.",
        "rcfilters-other-review-tools": "Други инструменти за проверка",
        "rcfilters-group-results-by-page": "Групиране на резултатите по страница",
        "rcfilters-activefilters": "Активни филтри",
+       "rcfilters-activefilters-hide": "Скриване",
        "rcfilters-advancedfilters": "Разширени филтри",
        "rcfilters-limit-title": "Резултати за показване",
        "rcfilters-limit-and-date-label": "$1 {{PLURAL:$1|промяна|промени}}, $2",
        "rcfilters-filter-humans-label": "Човек (не бот)",
        "rcfilters-filter-humans-description": "Редакции, направени от редактори.",
        "rcfilters-filtergroup-reviewstatus": "Проверка на статуса",
-       "rcfilters-filter-reviewstatus-unpatrolled-label": "Ð\9dепаÑ\82Ñ\80Ñ\83лиÑ\80ано",
+       "rcfilters-filter-reviewstatus-unpatrolled-label": "Ð\9dепаÑ\82Ñ\80Ñ\83лиÑ\80ани",
        "rcfilters-filter-reviewstatus-manual-label": "Ръчно патрулирани",
        "rcfilters-filter-reviewstatus-auto-label": "Автоматично патрулирани",
        "rcfilters-filtergroup-significance": "Значимост",
        "rcfilters-filter-watchlist-notwatched-label": "Извън списъка за наблюдение",
        "rcfilters-filter-watchlist-notwatched-description": "Всички, освен промените в страници от списъка за наблюдение.",
        "rcfilters-filtergroup-watchlistactivity": "Активност по списъка за наблюдение",
-       "rcfilters-filter-watchlistactivity-unseen-label": "Ð\9dевидÑ\8fни промени",
+       "rcfilters-filter-watchlistactivity-unseen-label": "Ð\9dепÑ\80егледани промени",
        "rcfilters-filter-watchlistactivity-unseen-description": "Промени по страници, които не сте посетили откакто са настъпили промените.",
-       "rcfilters-filter-watchlistactivity-seen-label": "Ð\92идени промени",
+       "rcfilters-filter-watchlistactivity-seen-label": "Ð\9fÑ\80егледани промени",
        "rcfilters-filter-watchlistactivity-seen-description": "Промени по страници, които сте посетили откакто са настъпили промените.",
        "rcfilters-filtergroup-changetype": "Вид на промяната",
        "rcfilters-filter-pageedits-label": "Редакции на страници",
        "rcfilters-liveupdates-button": "Обновяване на живо",
        "rcfilters-liveupdates-button-title-on": "Изключване на обновяването в реално време",
        "rcfilters-liveupdates-button-title-off": "Показване на новите промени в реално време",
-       "rcfilters-watchlist-markseen-button": "Ð\9eÑ\82белÑ\8fзване Ð½Ð° Ð²Ñ\81иÑ\87ки Ð¿Ñ\80омени ÐºÐ°Ñ\82о Ð²Ð¸Ð´Ðµни",
+       "rcfilters-watchlist-markseen-button": "Ð\9eÑ\82белÑ\8fзване Ð½Ð° Ð²Ñ\81иÑ\87ки Ð¿Ñ\80омени ÐºÐ°Ñ\82о Ð¿Ñ\80егледани",
        "rcfilters-watchlist-edit-watchlist-button": "Редактиране на списъка за наблюдение",
        "rcfilters-watchlist-showupdated": "Промени по страници, които не сте посетили откакто са внесени промените, са в <strong>получер</strong>, с удебелени маркери.",
        "rcfilters-preference-label": "Скриване на подобрената версия на Последни промени",
-       "rcfilters-preference-help": "Премахва новия дизайн на интерфейса от 2017 г. и всички инструменти, добавени тогава и след това.",
+       "rcfilters-preference-help": "Отменя преработката на интерфейса направена през 2017 година, както и всички инструменти добавени от тогава до сега.",
+       "rcfilters-watchlist-preference-label": "Скриване на подобрената версия на Списък за наблюдение",
+       "rcfilters-watchlist-preference-help": "Отменя преработката на интерфейса направена през 2017 година, както и всички инструменти добавени от тогава до сега.",
        "rcfilters-filter-showlinkedfrom-label": "Показване на промени на страници, към които има връзка от",
        "rcfilters-filter-showlinkedfrom-option-label": "<strong>Страници, към които има връзка от</strong> избраната страница",
        "rcfilters-filter-showlinkedto-label": "Показване на промени на страници, сочещи към",
        "dellogpage": "Дневник на изтриванията",
        "dellogpagetext": "Списък на последните изтривания.",
        "deletionlog": "дневник на изтриванията",
+       "log-name-create": "Дневник на създадените страници",
+       "log-description-create": "По-долу е показан списък на последно създадените страници.",
+       "logentry-create-create": "$1 {{GENDER:$2|създаде}} страница $3",
        "reverted": "Възвръщане към предишна версия",
        "deletecomment": "Причина:",
        "deleteotherreason": "Друга/допълнителна причина:",
        "uctop": "(текуща)",
        "month": "От месец (и по-рано):",
        "year": "От година (и по-рано):",
+       "date": "От дата (и по-рано):",
        "sp-contributions-newbies": "Показване само на приносите на нови потребители",
        "sp-contributions-newbies-sub": "на нови потребители",
        "sp-contributions-newbies-title": "Потребителски приноси за нови сметки",
        "whatlinkshere": "Какво сочи насам",
        "whatlinkshere-title": "Страници, които сочат към „$1“",
        "whatlinkshere-page": "Страница:",
-       "linkshere-2": "Следните страници сочат към <strong>$1</strong>:",
-       "nolinkshere-2": "Няма страници, сочещи към <strong>$1</strong>.",
-       "nolinkshere-ns-2": "Няма страници, сочещи към $1 в избраното именно пространство.",
+       "linkshere": "Следните страници сочат към <strong>$2</strong>:",
+       "nolinkshere": "Няма страници, сочещи към <strong>$2</strong>.",
+       "nolinkshere-ns": "Няма страници, сочещи към $2 в избраното именно пространство.",
        "isredirect": "пренасочваща страница",
        "istemplate": "включване",
        "isimage": "препратка към файла",
        "markedaspatrollederrornotify": "Неуспешно отбелязване на редакция като патрулирана.",
        "patrol-log-page": "Дневник на патрула",
        "patrol-log-header": "Тази страница съдържа дневник на проверените версии.",
-       "log-show-hide-patrol": "$1 на дневника на патрула",
-       "log-show-hide-tag": "$1 на дневника на отбелязванията",
        "confirm-markpatrolled-button": "Добре",
        "confirm-markpatrolled-top": "Маркиране на редакция $3 на $2 като патрулирана?",
        "deletedrevision": "Изтрита стара версия $1",
        "version-other": "Други",
        "version-mediahandlers": "Обработчици на медия",
        "version-hooks": "Куки",
-       "version-parser-extensiontags": "Ð\95Ñ\82икеÑ\82и от парсерни разширения",
+       "version-parser-extensiontags": "Тагове от парсерни разширения",
        "version-parser-function-hooks": "Куки в парсерни функции",
        "version-hook-name": "Име на куката",
        "version-hook-subscribedby": "Ползвана от",
        "tag-filter-submit": "Филтриране",
        "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|Етикет|Етикети}}]]: $2)",
        "tag-mw-contentmodelchange": "промяна на модела на съдържание",
+       "tag-mw-new-redirect": "Ново пренасочване",
+       "tag-mw-removed-redirect": "Премахнато пренасочване",
+       "tag-mw-blank": "Изтриване на съдържанието",
+       "tag-mw-replace": "Заменено",
        "tag-mw-rollback": "Отмяна",
        "tag-mw-undo": "Отмяна",
        "tags-title": "Етикети",
        "authmanager-email-help": "Електронна поща",
        "authmanager-realname-label": "Истинско име",
        "authmanager-realname-help": "Истинско име на потребителя",
+       "authmanager-provider-password": "Автентикация с парола",
        "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": "Промяна на парола",
+       "changecredentials-submit": "Промяна на парола",
+       "credentialsform-provider": "Тип на автентикацията:",
        "credentialsform-account": "Име на сметка:",
        "linkaccounts": "Свързване на сметки",
        "linkaccounts-success-text": "Сметката беше свързана.",
        "edit-error-short": "Грешка: $1",
        "edit-error-long": "Грешки:\n\n$1",
        "revid": "версия $1",
-       "pagedata-bad-title": "Невалидно заглавие: $1."
+       "pagedata-bad-title": "Невалидно заглавие: $1.",
+       "passwordpolicies": "Правила за паролите",
+       "passwordpolicies-summary": "Това е списъкът на действащите правила за паролите на потребителските групи дефинирани в това уики.",
+       "passwordpolicies-policy-minimalpasswordlength": "Паролата трябва да бъде от поне $1 {{PLURAL:$1|знак|знака}}",
+       "passwordpolicies-policy-minimumpasswordlengthtologin": "Паролата трябва да бъде поне $1 {{PLURAL:$1|знак|знака}} за да можете да влезете",
+       "passwordpolicies-policy-passwordcannotmatchusername": "Паролата не може да бъде същата като потребителското име",
+       "passwordpolicies-policy-passwordcannotmatchblacklist": "Паролата не може да съвпада с пароли от черния списък",
+       "passwordpolicies-policy-maximalpasswordlength": "Паролата трябва да бъде по-малко от $1 {{PLURAL:$1|знак|знака}}",
+       "passwordpolicies-policy-passwordcannotbepopular": "Паролата не може да бъде {{PLURAL:$1|най-популярната такава|от списъка на най-популярните $1 пароли}}"
 }
index bbf7078..4d9537c 100644 (file)
        "whatlinkshere": "لینک په ای تاکدیما",
        "whatlinkshere-title": "تاکدیمان که گو  «$1» لینک دارنت",
        "whatlinkshere-page": "تاکدیم:",
-       "linkshere-2": "جهلگین دیم بئ  '''$1''' ئا لینک داریت:",
-       "nolinkshere-2": "هیچ دیمی بئ  '''$1''' ئا لینک نه داریت.",
-       "nolinkshere-ns-2": "هیچ دیمی شه انتخاب بوته ئین نامی فضائان بئ  '''$1''' ئا لینک نداریت.",
+       "linkshere": "جهلگین دیم بئ  '''$2''' ئا لینک داریت:",
+       "nolinkshere": "هیچ دیمی بئ  '''$2''' ئا لینک نه داریت.",
+       "nolinkshere-ns": "هیچ دیمی شه انتخاب بوته ئین نامی فضائان بئ  '''$2''' ئا لینک نداریت.",
        "isredirect": "تاکدیمی تغییرمسیر داتین",
        "istemplate": "تراگنجانش‌هان",
        "isimage": "فایل لینک",
        "markedaspatrollederrornotify": "گشت وارته ئی برچسپ جتین ناکام ات.",
        "patrol-log-page": "گشتئ سیاه چال",
        "patrol-log-header": "ای سیاهه شه گشت وارته ئین ایڈیٹ ئان است.",
-       "log-show-hide-patrol": "$1 گشت جنوکین سیاهه",
-       "log-show-hide-tag": "$1 خالیجای ٹاپه",
        "deletedrevision": "$1 قدیمی پاک بوته ئین نخسه ئی است",
        "filedeleteerror-short": "خطا بئ فایلی پاک کورتین: $1",
        "filedeleteerror-long": "بی پدا  پاک کورتین ئی وختا خطا رخ دات:\n\n$1",
index 0468272..c03b9a9 100644 (file)
        "whatlinkshere": "इहाँ का जुड़ल बा",
        "whatlinkshere-title": "पन्ना जेवन \"$1\" से जुड़ल बा",
        "whatlinkshere-page": "पन्ना:",
-       "linkshere-2": "<strong>$1</strong> से नीचे दिहल पन्ना जुड़ल बाने:",
-       "nolinkshere-2": "'''$1''' से कौनो पन्ना नइखे जुड़ल।",
-       "nolinkshere-ns-2": "चुनल गईल सन्दर्भ में '''$1''' से कौनो पन्ना ना जुड़ेला।",
+       "linkshere": "<strong>$2</strong> से नीचे दिहल पन्ना जुड़ल बाने:",
+       "nolinkshere": "'''$2''' से कौनो पन्ना नइखे जुड़ल।",
+       "nolinkshere-ns": "चुनल गईल सन्दर्भ में '''$2''' से कौनो पन्ना ना जुड़ेला।",
        "isredirect": "अनुप्रेषित पन्ना",
        "istemplate": "ट्रांस्क्लूजन",
        "isimage": "फाइल कड़ी",
index 1e3d606..d677a0b 100644 (file)
        "whatlinkshere": "Tautan apa di sia",
        "whatlinkshere-title": "Tungkaran-tungkaran nang batautan ka ''$1''",
        "whatlinkshere-page": "Tungkaran:",
-       "linkshere-2": "Tungkaran-tungkaran barikut batautan ka '''$1''':",
-       "nolinkshere-2": "Kadada tutungkaran tataut ka '''$1'''.",
-       "nolinkshere-ns-2": "Kadada tutungkaran tataut ka '''$1''' dalam ruang-ngaran nang dipilih.",
+       "linkshere": "Tungkaran-tungkaran barikut batautan ka '''$2''':",
+       "nolinkshere": "Kadada tutungkaran tataut ka '''$2'''.",
+       "nolinkshere-ns": "Kadada tutungkaran tataut ka '''$2''' dalam ruang-ngaran nang dipilih.",
        "isredirect": "tungkaran paugahan",
        "istemplate": "transklusi",
        "isimage": "tautan barakas",
        "markedaspatrollederrornotify": "Manandai sabagai paitihan nang gagal.",
        "patrol-log-page": "Log pa-awasan",
        "patrol-log-header": "Ngini adalah sabuah log matan raralatan nang ta-awasi.",
-       "log-show-hide-patrol": "$1 log pa-awasan",
        "deletedrevision": "Raralatan lawas tahapus: $1",
        "filedeleteerror-short": "Kasalahan mahapus barakas: $1",
        "filedeleteerror-long": "Kasalahan tarikin parhatan mahapus barakas:\n\n$1",
index 5f2c954..f07c2c3 100644 (file)
@@ -37,7 +37,8 @@
                        "Mohammed Galib Hasan",
                        "এম আবু সাঈদ",
                        "Shahadat1971",
-                       "Rasal Lia"
+                       "Rasal Lia",
+                       "আফতাবুজ্জামান"
                ]
        },
        "tog-underline": "সংযোগের নিচে দাগ দেখানো হোক:",
        "actionthrottled": "কাজের গতি ধীরকরণ",
        "actionthrottledtext": "অপব্যবহার প্রতিরোধক সমাধান হিসেবে এই কাজটি খুব কম সময়ে অনেক বেশিবার সম্পাদন করার উপর সীমা বেঁধে দেওয়া হয়েছে, এবং আপনি সেই সীমা অতিক্রম করেছেন।\nঅনুগ্রহ করে কয়েক মিনিট পরে আবার চেষ্টা করুন।",
        "protectedpagetext": "সম্পাদনা অথবা অন্যান্য কাজে বাধা দিতে এই পাতাটিকে সুরক্ষিত করা হয়েছে।",
-       "viewsourcetext": "à¦\8f à¦ªà¦¾à¦¤à¦¾à¦\9fি à¦\86পনি দেখতে এবং উৎসের প্রতিলিপি করতে পারবেন।",
+       "viewsourcetext": "à¦\86পনি à¦\8fà¦\87 à¦ªà¦¾à¦¤à¦¾à¦\9fি দেখতে এবং উৎসের প্রতিলিপি করতে পারবেন।",
        "viewyourtext": "আপনি এই পাতায় করা <strong>আপনার সম্পাদনাগুলি</strong> দেখতে এবং প্রতিলিপি করতে পারেন।",
-       "protectedinterface": "à¦\8fà¦\87 à¦ªà¦¾à¦¤à¦¾à¦° à¦¬à¦¿à¦·à¦¯à¦¼à¦¬à¦¸à§\8dতà§\81 à¦\8fà¦\87 à¦\89à¦\87à¦\95ি à¦¸à¦«à¦\9fà¦\93য়à§\8dযারà§\87র à¦\8fà¦\95à¦\9fি à¦\87নà§\8dà¦\9fারফà§\87স à¦¬à¦¾à¦°à§\8dতা à¦ªà§\8dরদান à¦\95রà§\87, à¦¤à¦¾à¦\87 à¦\8fà¦\9fি à¦¯à¦¾à¦¤à§\87 à¦\85পবà§\8dযবহারà§\87 à¦¨à¦¾ à¦\95রা à¦¹à¦¯à¦¼, à¦¸à§\87à¦\9cনà§\8dয à¦\8fà¦\9fিà¦\95à§\87 à¦¸à§\81রà¦\95à§\8dষিত à¦\95রà§\87 à¦°à¦¾à¦\96া à¦¹à¦¯à¦¼à§\87à¦\9bà§\87।\nসà¦\95ল à¦\89à¦\87à¦\95ির à¦\85নà§\81বাদà§\87 à¦\95à§\8bনà§\8b à¦§à¦°à¦¨à§\87র à¦¸à¦\82যà§\8bà¦\9cন à¦¬à¦¾ à¦ªà¦°à¦¿à¦¬à¦°à§\8dতন à¦\95রতà§\87 à¦\85নà§\81à¦\97à§\8dরহ à¦\95রà§\87 à¦®à¦¿à¦¡à¦¿à¦¯à¦¼à¦¾à¦\89à¦\87à¦\95ি স্থানীয়করণ প্রকল্প [https://translatewiki.net/ translatewiki.net] ব্যবহার করুন।",
+       "protectedinterface": "à¦\8fà¦\87 à¦\89à¦\87à¦\95িতà§\87 à¦\8fà¦\87 à¦ªà¦¾à¦¤à¦¾à¦\9fি à¦¸à¦«à¦\9fà¦\93য়à§\8dযারà§\87র à¦\9cনà§\8dয à¦\87নà§\8dà¦\9fারফà§\87সà§\87র à¦¬à¦¾à¦°à§\8dতা à¦¸à¦°à¦¬à¦°à¦¾à¦¹ à¦\95রà§\87, à¦¤à¦¾à¦\87 à¦\85পবà§\8dযবহার à¦°à§\8bধ à¦\95রার à¦\9cনà§\8dয à¦\8fà¦\9fিà¦\95à§\87 à¦¸à§\81রà¦\95à§\8dষিত à¦\95রà§\87 à¦°à¦¾à¦\96া à¦¹à¦¯à¦¼à§\87à¦\9bà§\87।\nসà¦\95ল à¦\89à¦\87à¦\95ির à¦\9cনà§\8dয à¦\85নà§\81বাদà§\87 à¦\95à§\8bনà§\8b à¦§à¦°à¦¨à§\87র à¦¸à¦\82যà§\8bà¦\9cন à¦¬à¦¾ à¦ªà¦°à¦¿à¦¬à¦°à§\8dতন à¦\95রতà§\87, à¦\85নà§\81à¦\97à§\8dরহ à¦\95রà§\87 à¦®à¦¿à¦¡à¦¿à¦¯à¦¼à¦¾à¦\89à¦\87à¦\95ির স্থানীয়করণ প্রকল্প [https://translatewiki.net/ translatewiki.net] ব্যবহার করুন।",
        "editinginterface": "<strong>সতর্ক বার্তা:</strong> আপনি এমন একটি পাতা সম্পাদনা করছেন যা সফটওয়্যারের জন্য ইন্টারফেস লেখা সরবরাহ করে।\nএই পাতাতে সংঘটিত পরিবর্তন এই উইকির অন্যান্য ব্যবহারকারীদের জন্য দৃশ্যমান ইন্টারফেসে প্রভাব ফেলবে।",
        "translateinterface": "সকল উইকির জন্য অনুবাদ যোগ বা পরিবর্তন করতে দয়া করে [https://translatewiki.net/ translatewiki.net], মিডিয়াউইকি স্থানীয়করণ প্রকল্প ব্যবহার করুন।",
        "cascadeprotected": "এই পাতাটিকে সম্পাদনা করা থেকে সুরক্ষিত করা হয়েছে, কারণ এটি নিম্নোক্ত {{PLURAL:$1|পাতায়|পাতাগুলিতে}} অন্তর্ভুক্ত, {{PLURAL:$1|যেটি|যেগুলি}} \"প্রপাতাকার\" বৈশিষ্ট্য সহযোগে সুরক্ষিত করা আছে:\n$2",
        "customcssprotected": "আপনার এই সিএসএস পাতাটি সম্পাদনা করার অনুমতি নেই, কারণ এ পাতায় অন্য ব্যবহারকারীর নিজস্ব সেটিংস রয়েছে।",
        "customjsonprotected": "আপনার এই JSON পাতাটি সম্পাদনা করার অনুমতি নেই কারণ এই পাতায় অন্য ব্যবহারকারীর নিজস্ব সেটিংস রয়েছে।",
        "customjsprotected": "আপনার এই জাভাস্ক্রিপ্ট পাতাটি সম্পাদনা করার অনুমতি নেই, কারণ এ পাতায় অন্য ব্যবহারকারীর নিজস্ব সেটিংস রয়েছে।",
+       "sitecssprotected": "আপনার এই CSS পাতাটি সম্পাদনা করার অনুমতি নেই কারণ এটি সমস্ত পরিদর্শককে প্রভাবিত করতে পারে",
+       "sitejsonprotected": "আপনার এই JSON পাতাটি সম্পাদনা করার অনুমতি নেই কারণ এটি সমস্ত পরিদর্শককে প্রভাবিত করতে পারে",
+       "sitejsprotected": "আপনার এই জাভাস্ক্রিপ্ট পাতাটি সম্পাদনা করার অনুমতি নেই কারণ এটি সমস্ত পরিদর্শককে প্রভাবিত করতে পারে",
        "mycustomcssprotected": "আপনার এই সিএসএস পাতাটি সম্পাদনা করার অনুমতি নেই।",
        "mycustomjsonprotected": "আপনার এই JSON পাতাটি সম্পাদনা করার অনুমতি নেই।",
        "mycustomjsprotected": "আপনার এই জাভাস্ক্রিপ্ট পাতাটি সম্পাদনা করার অনুমতি নেই।",
        "botpasswords-existing": "বিদ্যমান বট পাসওয়ার্ড",
        "botpasswords-createnew": "একটি নতুন বট পাসওয়ার্ড তৈরি করুন",
        "botpasswords-editexisting": "একটি বিদ্যমান বট পাসওয়ার্ড পরিবর্তন করুন",
+       "botpasswords-label-needsreset": "(পাসওয়ার্ড পুনঃস্থাপন করা প্রয়োজন)",
        "botpasswords-label-appid": "বটের নাম:",
        "botpasswords-label-create": "তৈরি করুন",
        "botpasswords-label-update": "হালনাগাদ করুন",
        "botpasswords-restriction-failed": "বট পাসওয়ার্ডের সীমাবদ্ধতার কারণে অ্যাকাউন্টে প্রবেশের এই প্রচেষ্টাটিকে প্রতিরোধ করা হয়েছে।",
        "botpasswords-invalid-name": "নির্দিষ্টকৃত ব্যবহারকারী নামটিতে বট পাসওয়ার্ড পৃথকীকারক অক্ষরটি (\"$1\") নেই।",
        "botpasswords-not-exist": "ব্যবহারকারী \"$1\"-এর \"$2\" নামক বট পাসওয়ার্ডটি নেই।",
+       "botpasswords-needs-reset": "{{GENDER:$1|ব্যবহারকারী}} \"$1\"-এর \"$2\" নামের বটের জন্য বট পাসওয়ার্ড অবশ্যই পুনঃস্থাপন করা প্রয়োজন।",
        "resetpass_forbidden": "পাসওয়ার্ড পরিবর্তন করা সম্ভব নয়",
        "resetpass_forbidden-reason": "পাসওয়ার্ড পরিবর্তন করা যাবে না: $1",
        "resetpass-no-info": "এই পাতাটিতে সরাসরি প্রবেশাধিকার পেতে আপনাকে অবশ্যই অ্যাকাউন্টে প্রবেশ করতে হবে।",
        "resetpass-temp-password": "অস্থায়ী পাসওয়ার্ড:",
        "resetpass-abort-generic": "পাসওয়ার্ড পরিবর্তন একটি এক্সটেনশনের কারণে স্থগিত করা হয়েছে।",
        "resetpass-expired": "আপনার পাসওয়ার্ডের মেয়াদ উত্তীর্ণ হয়েছে। অ্যাকাউন্টে প্রবেশের জন্য অনুগ্রহ করে নতুন পাসওয়ার্ড নির্ধারণ করুন।",
-       "resetpass-expired-soft": "à¦\86পনার à¦ªà¦¾à¦¸à¦\93য়ারà§\8dডà§\87র à¦®à§\87য়াদ à¦\89তà§\8dতà§\80রà§\8dণ à¦¹à¦¯à¦¼à§\87à¦\9bà§\87 à¦\8fবà¦\82 à¦\86পনাà¦\95à§\87 à¦\8fà¦\95à¦\9fি à¦¨à¦¤à§\81ন à¦ªà¦¾à¦¸à¦\93য়ারà§\8dড à¦¨à¦¿à¦°à§\8dধারণ à¦\95রতà§\87 à¦¹à¦¬à§\87। à¦\85নà§\81à¦\97à§\8dরহ à¦\95রà§\87 à¦\8fà¦\96নà¦\87 à¦\8fà¦\95à¦\9fি à¦¨à¦¤à§\81ন à¦ªà¦¾à¦¸à¦\93য়ারà§\8dড à¦¨à¦¿à¦°à§\8dধারণ à¦\95রà§\81ন à¦\85থবা à¦ªà¦°à§\87 à¦ªà¦°à¦¿à¦¬à¦°à§\8dতন à¦\95রতà§\87 à¦\9aাà¦\87লà§\87 \"{{int:authprovider-resetpass-skip-label}}\" à¦¬à¦¾à¦\9fনà§\87 ক্লিক করুন।",
-       "resetpass-validity-soft": "à¦\86পনার à¦ªà¦¾à¦¸à¦\93য়ারà§\8dড à¦¬à§\88ধ à¦¨à¦¯à¦¼: $1\n\nদয়া à¦\95রà§\87 à¦\8fà¦\95à¦\9fি à¦¨à¦¤à§\81ন à¦ªà¦¾à¦¸à¦\93য়ারà§\8dড à¦¨à¦¿à¦°à§\8dধারণ করুন অথবা পরে করার জন্য \"{{int:authprovider-resetpass-skip-label}}\" ক্লিক করুন।",
+       "resetpass-expired-soft": "à¦\86পনার à¦ªà¦¾à¦¸à¦\93য়ারà§\8dডà§\87র à¦®à§\87য়াদ à¦\89তà§\8dতà§\80রà§\8dণ à¦¹à¦¯à¦¼à§\87à¦\9bà§\87 à¦\8fবà¦\82 à¦\86পনাà¦\95à§\87 à¦ªà¦¾à¦¸à¦\93য়ারà§\8dড à¦ªà¦°à¦¿à¦¬à¦°à§\8dতন à¦\95রতà§\87 à¦¹à¦¬à§\87। à¦\85নà§\81à¦\97à§\8dরহ à¦\95রà§\87 à¦\8fà¦\96নà¦\87 à¦\8fà¦\95à¦\9fি à¦¨à¦¤à§\81ন à¦ªà¦¾à¦¸à¦\93য়ারà§\8dড à¦¨à¦¿à¦°à§\8dধারণ à¦\95রà§\81ন à¦\85থবা à¦ªà¦°à§\87 à¦ªà¦°à¦¿à¦¬à¦°à§\8dতন à¦\95রতà§\87 à¦\9aাà¦\87লà§\87 \"{{int:authprovider-resetpass-skip-label}}\" ক্লিক করুন।",
+       "resetpass-validity-soft": "à¦\86পনার à¦ªà¦¾à¦¸à¦\93য়ারà§\8dড à¦¬à§\88ধ à¦¨à¦¯à¦¼: $1\n\nদয়া à¦\95রà§\87 à¦\8fà¦\95à¦\9fি à¦¨à¦¤à§\81ন à¦ªà¦¾à¦¸à¦\93য়ারà§\8dড à¦\9aয়ন করুন অথবা পরে করার জন্য \"{{int:authprovider-resetpass-skip-label}}\" ক্লিক করুন।",
        "passwordreset": "পাসওয়ার্ড পুনঃস্থাপন করুন",
        "passwordreset-text-one": "ইমেইলের মাধ্যমে একটি অস্থায়ী পাসওয়ার্ড পেতে এই ফরম পূরণ করুন।",
        "passwordreset-text-many": "{{PLURAL:$1|ইমেইলের মাধ্যমে একটি অস্থায়ী পাসওয়ার্ড পেতে ঘরগুলির একটি পূরণ করুন।}}",
        "anontalkpagetext": "----\n<em>এটি একটি বেনামী ব্যবহারকারীর আলাপের পাতা, যিনি এখনও কোন অ্যাকাউন্ট তৈরি করেননি, কিংবা তিনি অ্যাকাউন্টটি ব্যবহার করছেন না।</em>\nআমরা তাই সাংখ্যিক আইপি ঠিকানা ব্যবহার করে তাঁকে শনাক্ত করছি।\nএকাধিক ব্যবহারকারী এরকম একটি আইপি ঠিকানা ব্যবহার করতে পারেন।\nআপনি যদি একজন বেনামী ব্যবহারকারী হয়ে থাকেন এবং যদি অনুভব করেন যে আপনার প্রতি অপ্রাসঙ্গিক মন্তব্য করা হয়েছে, তাহলে অন্যান্য বেনামী ব্যবহারকারীর সাথে ভবিষ্যতে বিভ্রান্তি এড়াতে অনুগ্রহ করে [[Special:CreateAccount|একটি অ্যাকাউন্ট তৈরি করুন]] অথবা  [[Special:UserLogin|অ্যাকাউন্টে প্রবেশ করুন]]।",
        "noarticletext": "বর্তমানে এই পাতায় কোন লেখা নেই।\nআপনি চাইলে অন্যান্য পাতায় [[Special:Search/{{PAGENAME}}| এই শিরোনামটি অনুসন্ধান করতে পারেন]],\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} এ সম্পর্কিত লগ অনুসন্ধান করতে পারেন], \nকিংবা [{{fullurl:{{FULLPAGENAME}}|action=edit}} এই পাতাটি তৈরি করতে পারেন]</span>।",
        "noarticletext-nopermission": "বর্তমানে এই পাতায় কোন লেখা নেই।\nআপনি চাইলে অন্য পাতায় [[Special:Search/{{PAGENAME}}| শিরোনামটি অনুসন্ধান করতে পারেন]], অথবা <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} সম্পর্কিত লগ অনুসন্ধান করতে পারেন]</span>, কিন্তু আপনার এই পাতাটি তৈরী করার অনুমতি নেই।",
-       "missing-revision": "\"{{FULLPAGENAME}}\" এর #$1তম সংস্করণটি প্রদর্শন সম্ভব নয়।\n\nসাধারণত মুছে ফেলা হয়েছে এমন পাতার মেয়াদ উত্তীর্ণ ইতিহাস পাতার লিংক ওপেন করার কারণে এটি হতে পারে। \n[{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} অপসারণ লগে] বিস্তারিত তথ্য জানা যাবে।",
+       "missing-revision": "\"{{FULLPAGENAME}}\" এর #$1তম সংস্করণটি প্রদর্শন সম্ভব নয়।\n\nসাধারণত মুছে ফেলা হয়েছে এমন পাতার মেয়াদ উত্তীর্ণ ইতিহাসের সংযোগ অনুসরণ করার কারণে এটি হতে পারে। \n[{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} অপসারণ লগে] বিস্তারিত তথ্য জানা যাবে।",
        "userpage-userdoesnotexist": "\"<nowiki>$1</nowiki>\" নামের কোন ব্যবহারকারী অ্যাকাউন্ট নিবন্ধিত হয়নি। অনুগ্রহ করে পরীক্ষা করে দেখুন আপনি এই পাতাটি সৃষ্টি/সম্পাদনা করতে চান কি না।",
        "userpage-userdoesnotexist-view": "ব্যবহারকারী অ্যাকাউন্ট \"$1\" অনিবন্ধিত।",
        "blocked-notice-logextract": "এই ব্যবহারকারী বর্তমানে অবরুদ্ধ রয়েছেন।\nসূত্রের জন্য সাম্প্রতিক বাধাদান লগের ভুক্তিটি নিচে দেওয়া হল:",
        "postedit-confirmation-published": "আপনার সম্পাদনা প্রকাশিত হয়েছে।",
        "edit-already-exists": "নতুন পাতা সৃষ্টি করা যায়নি।\nপাতাটি ইতিমধ্যেই বিদ্যমান।",
        "defaultmessagetext": "আদি টেক্সট",
-       "content-failed-to-parse": "$1 à¦®à¦¡à§\87লà§\87র à¦\9cনà§\8dয $2 à¦\95নà§\8dà¦\9fà§\87নà§\8dà¦\9f à¦ªà¦¾à¦°à§\8dস à¦\95রা à¦¯à¦¾à¦\9aà§\8dà¦\9bà§\87 à¦¨à¦¾: $3",
+       "content-failed-to-parse": "$1 à¦®à¦¡à§\87লà§\87র à¦\9cনà§\8dয $2 à¦¬à¦¿à¦·à¦¯à¦¼à¦¬à¦¸à§\8dতà§\81 à¦ªà¦¾à¦°à§\8dস à¦\95রতà§\87 à¦¬à§\8dযরà§\8dথ à¦¹à¦¯à¦¼à§\87à¦\9bà§\87: $3",
        "invalid-content-data": "ভুল কন্টেন্ট ডাটা",
-       "content-not-allowed-here": "\"$1\" à¦\95নà§\8dà¦\9fà§\87নà§\8dà¦\9fà¦\9fি [[$2]] পাতায় অনুমোদিত নয়",
+       "content-not-allowed-here": "\"$1\" à¦¸à¦¾à¦®à¦\97à§\8dরà§\80 [[$2]] পাতায় অনুমোদিত নয়",
        "editwarning-warning": "এই পাতাটি ত্যাগ করলে আপনার আপনার করা পরিবর্তনগুলো হারিয়ে যেতে পারে।\nআপনি যদি প্রবেশ করা থাকেন, আপনি এই সতর্কীকরণ বার্তাটি আপনার পছন্দের \"সম্পাদনা\" অনুচ্ছেদ থেকে নিস্ক্রিয় করতে পারেন।",
        "editpage-invalidcontentmodel-title": "বিষয়বস্তু মডেল সমর্থিত নয়",
        "editpage-invalidcontentmodel-text": "এই \"$1\" বিষয়বস্তু মডেলটি অসমর্থিত।",
        "editpage-notsupportedcontentformat-title": "উল্লেখিত পদ্ধতি সমর্থনযোগ্য নয়।",
        "editpage-notsupportedcontentformat-text": "$1 লেখার ফরম্যাট, $2 কন্টেন্ট মডেলের উপযোগী নয়।",
-       "content-model-wikitext": "à¦\89à¦\87à¦\95িà¦\9fà§\87à¦\95à§\8dসà¦\9f",
+       "content-model-wikitext": "à¦\89à¦\87à¦\95িপাঠà§\8dয",
        "content-model-text": "সাধারণ লেখা",
        "content-model-javascript": "জাভাস্ক্রিপ্ট",
        "content-model-css": "সিএসএস",
        "expansion-depth-exceeded-category-desc": "পাতাটি সর্বোচ্চ এক্সপশন সীমানা অতিক্রম করেছে।",
        "expansion-depth-exceeded-warning": "পাতাটি এক্সেপশন সীমানা অতিক্রম করেছে",
        "parser-unstrip-loop-warning": "ত্রুটিপূর্ণ লুপ খুঁজে পাওয়া গিয়েছে",
-       "unstrip-depth-warning": "লুপ রিকারশন সীমানা অতিক্রম করেছে ($1)",
+       "unstrip-depth-warning": "আনস্ট্রিপ গভীরতার সীমানা অতিক্রম করেছে ($1)",
+       "unstrip-depth-category": "পাতাসমূহ যেখানে আনস্ট্রিপ গভীরতার সীমা অতিক্রম করেছে",
+       "unstrip-size-warning": "Unstrip আকারের সীমা অতিক্রম করেছে ($1)",
+       "unstrip-size-category": "পাতাসমূহ যেখানে আনস্ট্রিপ আকারের সীমা অতিক্রম করেছে",
        "converter-manual-rule-error": "ম্যানুয়াল ভাষা রূপান্তর নিয়মে ত্রুটি পাওয়া গিয়েছে",
        "undo-success": "সম্পাদনাটি বাতিল করা যাবে। অনুগ্রহ করে নিচের তুলনাটি পরীক্ষা করে দেখুন ও নিশ্চিত করুন যে এটাই আপনি করতে চান, এবং তারপর নিচের সম্পাদনাগুলি সংরক্ষণ করে সম্পাদনাটির বাতিল প্রক্রিয়া সমাপ্ত করুন।",
        "undo-failure": "এ সম্পাদনা মধ্যবর্তী সম্পাদনাসমূহের কারণে পূর্বাবস্থায় ফিরিয়ে নেওয়া যাবে না।",
        "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": "নিবন্ধের শিরোনাম মিলেছে",
        "textmatches": "পাতার লেখার সাথে মিলেছে",
        "prefs-watchlist-edits": "নজরতালিকাতে দেখানোর জন্য সর্বাধিক পরিবর্তনের সংখ্যা:",
        "prefs-watchlist-edits-max": "সর্বোচ্চ সংখ্যা: ১০০০",
        "prefs-watchlist-token": "নজরতালিকা টোকেন:",
-       "prefs-watchlist-managetokens": "টোকেন পরিচালনা করুন",
+       "prefs-watchlist-managetokens": "টোকেনসমূহ পরিচালনা করুন",
        "prefs-misc": "বিবিধ",
        "prefs-resetpass": "পাসওয়ার্ড পরিবর্তন",
        "prefs-changeemail": "ইমেইল ঠিকানা পরিবর্তন বা বাতিল করুন",
        "yourrealname": "আসল নাম *",
        "yourlanguage": "ভাষা:",
        "yourvariant": "বিষয়বস্তুর ভাষার বিকল্প:",
-       "prefs-help-variant": "à¦\89à¦\87à¦\95িতà§\87 à¦\95নà§\8dà¦\9fà§\87নà§\8dà¦\9f à¦ªà¦¾à¦¤à¦¾ à¦¦à§\87à¦\96ার à¦\9cনà§\8dয à¦\86পনার à¦ªà¦\9bনà§\8dদà§\87র à¦¬à§\88শিষà§\8dà¦\9f।",
+       "prefs-help-variant": "à¦\8fà¦\87 à¦\89à¦\87à¦\95িতà§\87 à¦¬à¦¿à¦·à¦¯à¦¼à¦¬à¦¸à§\8dতà§\81র à¦ªà¦¾à¦¤à¦¾ à¦¦à§\87à¦\96ার à¦\9cনà§\8dয à¦\86পনার à¦ªà¦\9bনà§\8dদà§\87র à¦¬à§\88à¦\95লà§\8dপিà¦\95 à¦¬à¦¾ à¦¬à¦¾à¦¨à¦¾à¦¨।",
        "yournick": "স্বাক্ষর:",
        "prefs-help-signature": "আলাপ পাতায় আপনার মন্তব্য অবশ্যই \"<nowiki>~~~~</nowiki>\" চিহ্ন দ্বারা স্বাক্ষরিত হতে হবে, যা স্বয়ংক্রিয়ভাবে আপনার স্বাক্ষর ও সময় সংযুক্ত করবে।",
        "badsig": "অবৈধ স্বাক্ষর; এইচটিএমএল ট্যাগ পরীক্ষা করুন।",
        "prefs-dateformat": "তারিখ বিন্যাস",
        "prefs-timeoffset": "সময় অফসেট",
        "prefs-advancedediting": "সাধারণ পছন্দগুলি",
+       "prefs-developertools": "উন্নয়নকারীর সরঞ্জাম",
        "prefs-editor": "সম্পাদক",
        "prefs-preview": "প্রাকদর্শন",
        "prefs-advancedrc": "উচ্চতর পছন্দগুলি",
        "prefs-opt-out": "উন্নতি অনির্বাচন",
-       "prefs-advancedrendering": "à¦\89à¦\9aà§\8dà¦\9aতর à¦\85পশন",
+       "prefs-advancedrendering": "à¦\89à¦\9aà§\8dà¦\9aতর à¦¬à¦¿à¦\95লà§\8dপà¦\97à§\81লি",
        "prefs-advancedsearchoptions": "উচ্চতর পছন্দগুলি",
-       "prefs-advancedwatchlist": "à¦\89à¦\9aà§\8dà¦\9aতর à¦\85পশন",
+       "prefs-advancedwatchlist": "à¦\89à¦\9aà§\8dà¦\9aতর à¦¬à¦¿à¦\95লà§\8dপà¦\97à§\81লি",
        "prefs-displayrc": "প্রদর্শনীর পছন্দগুলি",
        "prefs-displaywatchlist": "প্রদর্শনী অপশন",
        "prefs-tokenwatchlist": "টোকেন",
        "userrights-cannot-shorten-expiry": "\"$1\" দলটির সদস্যতার মেয়াদোত্তীর্ণ হবার সময় ও তারিখ আপনি পূর্ববর্তী কোন সময়ে এগিয়ে নিয়ে আসতে পারবেন না। যেসব ব্যবহারকারীর এই দলটি যোগ বা অপসারণ করার অনুমতি আছে, কেবল তারাই মেয়াদোত্তীর্ণ হবার সময় ও তারিখ এগিয়ে নিয়ে আসতে পারবেন।",
        "userrights-conflict": "ব্যবহারকারী অধিকার দ্বন্দ্ব! অনুগ্রহ করে নিশ্চিত হোন এবং পুনরায় চেষ্টা করুন।",
        "group": "দল:",
-       "group-user": "ব্যবহারকারীগণ",
+       "group-user": "ব্যবহারকারী",
        "group-autoconfirmed": "স্বয়ংনিশ্চিতকৃত ব্যবহারকারী",
        "group-bot": "বট",
        "group-sysop": "প্রশাসক",
+       "group-interface-admin": "ইন্টারফেস প্রশাসক",
        "group-bureaucrat": "ব্যুরোক্র্যাট",
        "group-suppress": "দমনকারী",
        "group-all": "(সমস্ত)",
        "group-autoconfirmed-member": "{{GENDER:$1|স্বয়ংনিশ্চিতকৃত ব্যবহারকারী}}",
        "group-bot-member": "বট",
        "group-sysop-member": "প্রশাসক",
+       "group-interface-admin-member": "{{GENDER:$1|ইন্টারফেস প্রশাসক}}",
        "group-bureaucrat-member": "ব্যুরোক্র্যাট",
        "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-edit": "পাতাগুলি সম্পাদনা করা",
        "right-createpage": "আলাপ পাতা নয়, এমন পাতা তৈরি করা",
        "right-createtalk": "আলাপ পাতা তৈরি করা",
        "right-createaccount": "নতুন ব্যবহারকারীর অ্যাকাউন্ট তৈরি করুন",
        "right-editcontentmodel": "পাতার তথ্যের ধরন সম্পাদনা করুন",
        "right-editinterface": "ব্যবহারকারী ইন্টারফেস সম্পাদনা",
        "right-editusercss": "অন্য ব্যবহারকারীগণের CSS ফাইল সম্পাদনা",
+       "right-edituserjson": "অন্য ব্যবহারকারীগণের JSON ফাইল সম্পাদনা",
        "right-edituserjs": "অন্য ব্যবহারকারীগণের JS ফাইল সম্পাদনা",
+       "right-editsitecss": "সাইটব্যাপী CSS সম্পাদনা করা",
+       "right-editsitejson": "সাইটব্যাপী JSON সম্পাদনা করা",
+       "right-editsitejs": "সাইটব্যাপী জাভাস্ক্রিপ্ট সম্পাদনা করা",
        "right-editmyusercss": "আপনার নিজস্ব ব্যবহারকারী সিএসএস ফাইল সম্পাদনা করুন",
+       "right-editmyuserjson": "আপনার নিজস্ব ব্যবহারকারী JSON ফাইল সম্পাদনা করা",
        "right-editmyuserjs": "আপনার নিজস্ব ব্যবহারকারী জাভাস্ক্রিপ্ট ফাইল সম্পাদনা করুন",
        "right-viewmywatchlist": "আপনার নজরতালিকা দেখুন",
        "right-editmywatchlist": "আপনার নজরতালিকা সম্পাদনা করুন। মনে রাখবেন, এই পরিবর্তনের পরও বিভিন্ন পাতা তালিকায় যুক্ত হয়ে থেতে পারে।",
        "grant-createaccount": "অ্যাকাউন্ট তৈরি করুন",
        "grant-createeditmovepage": "পাতা তৈরি, সম্পাদনা এবং স্থানান্তর করুন",
        "grant-delete": "পাতা, পুনর্বিবেচনা ও লগ ভুক্তিসমূহ মুছে ফেলুন।",
-       "grant-editinterface": "মিডিয়াà¦\89à¦\87à¦\95ি à¦¨à¦¾à¦®à¦¸à§\8dথান à¦\8fবà¦\82 à¦¬à§\8dযবহারà¦\95ারà§\80র à¦¸à¦¿à¦\8fসà¦\8fস/JSON/à¦\9cাভাসà§\8dà¦\95à§\8dরিপà§\8dà¦\9f সম্পাদনা করে",
+       "grant-editinterface": "মিডিয়াà¦\89à¦\87à¦\95ি à¦¨à¦¾à¦®à¦¸à§\8dথান à¦\8fবà¦\82 à¦¸à¦¾à¦\87à¦\9fবà§\8dযাপà§\80/বà§\8dযবহারà¦\95ারà§\80র JSON সম্পাদনা করে",
        "grant-editmycssjs": "আপনার ব্যবহারকারী সিএসএস/জেএসওএন/জাভাস্ক্রিপ্ট সম্পাদনা করুন",
        "grant-editmyoptions": "আপনার ব্যবহারকারী পছন্দসমূহ সম্পাদনা করুন",
        "grant-editmywatchlist": "আপনার নজরতালিকা সম্পাদনা করুন",
+       "grant-editsiteconfig": "সাইটব্যাপী ও ব্যবহারকারীর CSS/JS সম্পাদনা করা",
        "grant-editpage": "বিদ্যমান পাতা সম্পাদনা করুন",
        "grant-editprotected": "সংরক্ষিত পাতা সম্পাদনা করুন",
        "grant-highvolume": "উচ্চ-মাত্রার সম্পাদনা",
        "action-viewmywatchlist": "আপনার নজরতালিকা দেখুন",
        "action-viewmyprivateinfo": "আপনার ব্যক্তিগত তথ্য দেখুন",
        "action-editmyprivateinfo": "আপনার ব্যক্তিগত তথ্য সম্পাদনা করুন",
-       "action-editcontentmodel": "পাতার à¦\95নà§\8dà¦\9fà§\87নà§\8dà¦\9f à¦®à¦¡à§\87ল à¦¸à¦®à§\8dপাদনা à¦\95রà§\81ন",
+       "action-editcontentmodel": "à¦\8fà¦\95à¦\9fি à¦ªà¦¾à¦¤à¦¾à¦° à¦¬à¦¿à¦·à¦¯à¦¼à¦¬à¦¸à§\8dতà§\81র à¦®à¦¡à§\87ল à¦¸à¦®à§\8dপাদনা à¦\95রার",
        "action-managechangetags": "ট্যাগ তৈরি ও সক্রিয়/নিষ্ক্রিয়",
        "action-applychangetags": "আপনার পরিবর্তনগুলোর সাথে ট্যাগ সংযোজন করুন",
        "action-changetags": "নির্দিষ্ট সংস্করণ এবং লগ ভুক্তিগুলিতে যথেচ্ছভাবে ট্যাগ সংযোজন ও অপসারণ করা",
        "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",
        "rcfilters-savedqueries-rename": "নামান্তর",
        "rcfilters-savedqueries-setdefault": "পূর্ব-নির্ধারিত হিসেবে নির্ধারন করুন",
        "rcfilters-savedqueries-unsetdefault": "পূর্ব-নির্ধারিত হিসেবে নির্ধারন সরান",
-       "rcfilters-savedqueries-remove": "সরান",
+       "rcfilters-savedqueries-remove": "à¦\85পসারণ",
        "rcfilters-savedqueries-new-name-label": "নাম",
        "rcfilters-savedqueries-new-name-placeholder": "ছাঁকনির উদ্দেশ্য বর্ণনা করুন",
        "rcfilters-savedqueries-apply-label": "ছাঁকনি তৈরি করুন",
        "rcfilters-empty-filter": "কোনো সক্রিয় ফিল্টার নেই। সমস্ত অবদান দেখানো হয়েছে।",
        "rcfilters-filterlist-title": "ছাঁকনি",
        "rcfilters-filterlist-whatsthis": "এগুলি কিভাবে কাজ করে?",
-       "rcfilters-filterlist-feedbacklink": "আপনি এই (নতুন) ছাঁকন সরঞ্জাম সম্পর্কে কি মনে করেন তা আমাদের বলুন",
+       "rcfilters-filterlist-feedbacklink": "আপনি এই ছাঁকন সরঞ্জাম সম্পর্কে কি মনে করেন তা আমাদের বলুন",
        "rcfilters-highlightbutton-title": "ফলাফলে আলোকপাত করুন",
        "rcfilters-highlightmenu-title": "একটি রং নির্বাচন করুন",
        "rcfilters-highlightmenu-help": "এই বৈশিষ্ট্যটিতে আলোকপাত করতে একটি রঙ নির্বাচন করুন",
        "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-watchlist-showupdated": "পরিবর্তন যখন ঘটেছে তখন থেকে যে পাতাগুলি আপনি এখনো দেখেননি তা মোটা চিহ্নসহ <strong>গাঢ়</strong> করে দেখানো হয়েছে।",
        "rcfilters-preference-label": "সাম্প্রতিক পরিবর্তনের উন্নত সংস্করণটি লুকান",
        "rcfilters-preference-help": "২০১৭-এর পুনঃনকশাকৃত ইন্টারফেস এবং তখন পর্যন্ত ও তখন থেকে যোগ করা সকল সরঞ্জামে ফেরত নিবে।",
+       "rcfilters-watchlist-preference-label": "নজরতালিকার উন্নত সংস্করণটি লুকান",
        "rcfilters-target-page-placeholder": "একটি পাতার নাম (বা বিষয়শ্রেণী) লিখুন",
        "rcnotefrom": "<strong>$2</strong>টা থেকে সংঘটিত পরিবর্তনগুলি (সর্বোচ্চ <strong>$1টি</strong> দেখানো হয়েছে)।",
        "rclistfromreset": "তারিখ নির্বাচন পুনঃস্থাপন করুন",
        "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]] যোগ করা হয়েছে",
        "recentchanges-page-removed-from-category": "বিষয়শ্রেণী থেকে [[:$1]] সরানো হয়েছে",
        "recentchanges-page-removed-from-category-bundled": "বিষয়শ্রেণীতে [[:$1]] সরানো হয়েছে, [[Special:WhatLinksHere/$1|এই পাতাটি অন্য পাতাগুলির মধ্যে অন্তর্ভুক্তকৃত]]",
        "autochange-username": "মিডিয়াউইকি স্বয়ংক্রিয় পরিবর্তন",
-       "upload": "আপলোড",
+       "upload": "আপলোড করুন",
        "uploadbtn": "ফাইল আপলোড করুন",
        "reuploaddesc": "আপলোড বাতিল করুন এবং আপলোড ফর্মে ফেরত যান",
        "upload-tryagain": "পরিবর্তিত ফাইল বর্ণনা জমা দিন",
        "uploadstash-zero-length": "ফাইলটির দৈর্ঘ্য শূন্য।",
        "invalid-chunk-offset": "ত্রুটিপূর্ণ চাংক অফসেট",
        "img-auth-accessdenied": "প্রবেশাধিকার নাই",
-       "img-auth-nopathinfo": "PATH_INFO পাওয়া যাচ্ছে না।\nআপনার সার্ভার থেকে এই তথ্য পাঠানোর জন্য কনফিগার করা হয়নি।\nএটি হয়তো CGI ভিত্তিক এবং img_auth সমর্থন করে না।\nবিস্তারিত দেখুন https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization।",
+       "img-auth-nopathinfo": "পথের তথ্য পাওয়া যাচ্ছে না।\nআপনার সার্ভার অবশ্যই REQUEST_URI ও/বা PATH_INFO চলক অতিক্রম করাতে সমর্থ হতে হবে।\nযদি এটি তাই হয়, তবে $wgUsePathInfo সক্রিয় করার চেষ্টা করুন।\nবিস্তারিত জানতে https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization দেখুন।",
        "img-auth-notindir": "অনুরোধকৃত পাথটি কনফিগার করা আপলোড ডিরেক্টরী নয়।",
        "img-auth-badtitle": "\"$1\" থেকে একটি সঠিক শিরনাম তৈরী করা যাচ্ছে না।",
        "img-auth-nologinnWL": "আপনি প্রবেশ করেননি এবং \"$1\" নজরতালিকায় নেই।",
        "http-timed-out": "HTTP অনুরোধের সময় পার হয়েছে।",
        "http-curl-error": "ইউআরএল নিয়ে আসার ক্ষেত্রে ত্রুটি: $1",
        "http-bad-status": "HTTP অনুরোধের সময় কোন সমস্যা হয়েছে: $1 $2",
+       "http-internal-error": "HTTP অভ্যন্তরীণ ত্রুটি।",
        "upload-curl-error6": "URL-এ পৌঁছানো যায়নি",
        "upload-curl-error6-text": "প্রদত্ত URLটিতে পৌঁছানো যায়নি। অনুগ্রহ করে আবার পরীক্ষা করে দেখুন URLটি সঠিক কি না এবং সাইটটি চালু আছে কি না।",
        "upload-curl-error28": "আপলোড সময়োত্তীর্ণ",
        "protectedtitles-submit": "শিরোনাম প্রদর্শন করুন",
        "listusers": "ব্যবহারকারীর তালিকা",
        "listusers-editsonly": "শুধুমাত্র এমন ব্যবহারকারীদের দেখাও যাদের অবদান আছে",
+       "listusers-temporarygroupsonly": "শুধুমাত্র অস্থায়ী ব্যবহারকারী দলের ব্যবহারকারীদের দেখান",
        "listusers-creationsort": "তৈরির তারিখ অনুসারে সাজাও",
        "listusers-desc": "বড় থেকে ছোট ক্রম অনুযায়ী সাজাও",
        "usereditcount": "$1 {{PLURAL:$1|সম্পাদনা|সম্পাদনা}}",
-       "usercreated": "{{GENDER:$3|তà§\88রি à¦¹à¦¯à¦¼à§\87à¦\9bà§\87}} $1 à¦¤à¦¾à¦°à¦¿à¦\96, à¦¸à¦®à¦¯à¦¼: $2",
+       "usercreated": "{{GENDER:$3|তà§\88রি à¦¹à¦¬à¦¾à¦°}} à¦¤à¦¾à¦°à¦¿à¦\96 $1, à¦¸à¦®à¦¯à¦¼ $2",
        "newpages": "নতুন পাতাসমূহ",
        "newpages-submit": "দেখাও",
        "newpages-username": "ব্যবহারকারী নাম:",
        "speciallogtitlelabel": "লক্ষ্য (ব্যবহারকারীর জন্য শিরোনাম বা {{ns:user}}:ব্যবহারকারী নাম):",
        "log": "লগগুলি",
        "logeventslist-submit": "দেখাও",
+       "logeventslist-more-filters": "অতিরিক্ত লগ দেখান:",
+       "logeventslist-patrol-log": "পরীক্ষণ লগ",
+       "logeventslist-tag-log": "ট্যাগ লগ",
        "all-logs-page": "সব প্রকাশ্য লগ",
        "alllogstext": "{{SITENAME}}-এর সবগুলো লগের সম্মিলিত প্রদর্শন।\nআপনি লগের ধরন, ব্যবহারকারীর নাম, বা পাতার নাম নির্বাচন করে প্রদর্শনটির আকার কমিয়ে আনতে পারেন।",
        "logempty": "মিলে যায় এমন কিছু লগে পাওয়া যায়নি।",
        "trackingcategories-disabled": "বিষয়শ্রেণীটি বিকল",
        "mailnologin": "প্রাপকের ঠিকানা নেই",
        "mailnologintext": "অন্য ব্যবহারকারীদেরকে ই-মেইল পাঠাতে হলে আপনাকে অবশ্যই আগে [[Special:UserLogin|লগ-ইন]] করতে হবে এবং ''[[Special:Preferences|আপনার পছন্দ তালিকায়]] আপনার ই-মেইল ঠিকানাটি ঠিকমত দিতে হবে।",
-       "emailuser": "à¦\87মà§\87à¦\87ল à¦\95রà§\8b",
+       "emailuser": "à¦\8fà¦\87 à¦¬à§\8dযবহারà¦\95ারà§\80à¦\95à§\87 à¦\87মà§\87à¦\87ল à¦\95রà§\81ন",
        "emailuser-title-target": "{{GENDER:$1|ব্যবহারকারীকে}} ইমেইল পাঠান",
        "emailuser-title-notarget": "ব্যবহারকারীকে ই-মেইল করুন",
        "emailpagetext": "আপনি নিচের ফর্মটি ব্যবহার করে এই {{GENDER:$1|ব্যবহারকারীকে}} একটি ই-মেইল পাঠাতে পারেন।\nআপনি [[Special:Preferences|আপনার ব্যবহারকারী পছন্দে]] যে ই-মেইল ঠিকানাটি প্রবেশ করিয়েছেন সেটিকে ই-মেইলের ''প্রেরক'' হিসেবে দেখানো হবে, যেনো মেইলের প্রাপক আপনাকে উত্তর দিতে পারেন।",
        "dellogpage": "পাতা অবলুপ্তি লগ",
        "dellogpagetext": "নিচে সবচেয়ে সাম্প্রতিক অবলুপ্তিগুলোর একাটি তালিকা দেওয়া হল।",
        "deletionlog": "পাতা অবলুপ্তি লগ",
+       "log-name-create": "পাতা সৃষ্টিকরণ লগ",
+       "log-description-create": "নিচে সবচেয়ে সাম্প্রতিক পাতা সৃষ্টিকরণের একাটি তালিকা দেওয়া হল।",
+       "logentry-create-create": "$1 $3 পাতাটি {{GENDER:$2|সৃষ্টি করেছে}}",
        "reverted": "পূর্ববর্তী সংস্করণে ফিরে যাওয়া সফল হয়েছে।",
        "deletecomment": "কারণ:",
        "deleteotherreason": "অন্য/অতিরিক্ত কারণ:",
        "cantrollback": "পূর্বের সংস্করণে ফেরত যাওয়া সম্ভব হল না, সর্বশেষ সম্পাদনাকারী এই নিবন্ধটির একমাত্র লেখক।",
        "alreadyrolled": "[[User:$2|$2]] ([[User talk:$2|আলাপ]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]) দ্বারা সম্পাদিত [[:$1]]-এর সর্বশেষ সম্পাদনাটি পুনর্বহাল করা যাচ্ছে না;\nঅন্য কোন ব্যবহারকারী এই পাতা ইতিমধ্যে সম্পাদনা বা পুনর্বহাল করেছেন।\n\nএই পাতায় সর্বশেষ সম্পাদনা করেছেন [[User:$3|$3]] ([[User talk:$3|আলাপ]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]])।",
        "editcomment": "সম্পাদনা সারাংশ ছিল: \"''$1''\"।",
-       "revertpage": "[[Special:Contributions/$2|$2]] ([[User talk:$2|আলাপ]]) এর সম্পাদিত সংস্করণ হতে [[User:$1|$1]] এর সম্পাদিত সর্বশেষ সংস্করণে ফেরত যাওয়া হয়েছে।",
-       "revertpage-nouser": "একজন গোপন ব্যবহারকারী কর্তৃক সম্পাদিত সম্পাদনাটি বাতিলপূর্বক {{GENDER:$1|[[User:$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": "সেশন পরিত্যক্ত",
        "nocontribs": "এই শর্তগুলির সাথে মিলে যায়, এমন কোন পরিবর্তন খুঁজে পাওয়া যায়নি।",
        "uctop": "(বর্তমান)",
        "month": "এই মাস (বা তার আগে) থেকে:",
-       "year": "এই বছর (এবং তার আগে) থেকে:",
+       "year": "এই বছর (বা তার আগে) থেকে:",
+       "date": "এই তারিখ (বা তার আগে) থেকে:",
        "sp-contributions-newbies": "শুধু নতুন অ্যাকাউন্টের অবদানসমূহ দেখাও",
        "sp-contributions-newbies-sub": "নতুন অ্যাকাউন্টের জন্য",
        "sp-contributions-newbies-title": "নতুন অ্যাকাউন্টের ব্যবহারকারী অবদান",
        "whatlinkshere": "সংযোগকারী পাতাসমূহ",
        "whatlinkshere-title": "যে পাতাগুলি থেকে \"$1\"-এর প্রতি সংযোগ আছে",
        "whatlinkshere-page": "পাতা:",
-       "linkshere-2": "নিচের পাতাসমূহ '''$1''' পাতায় সংযুক্ত আছে:",
-       "nolinkshere-2": "কোনো পাতা থেকে '''$1''' পাতায় সংযোগ নেই।",
-       "nolinkshere-ns-2": "নির্বাচিত নামস্থানে '''$1'''-এর প্রতি কোন পাতা থেকে সংযোগ নেই।",
+       "linkshere": "নিচের পাতাসমূহ <strong>$2</strong> পাতায় সংযুক্ত আছে:",
+       "nolinkshere": "কোনো পাতা থেকে <strong>$2</strong> পাতায় সংযোগ নেই।",
+       "nolinkshere-ns": "নির্বাচিত নামস্থানে <strong>$2</strong> -এর প্রতি কোন পাতা থেকে সংযোগ নেই।",
        "isredirect": "পুনর্নির্দেশ",
        "istemplate": "অন্তর্ভুক্তি",
        "isimage": "ফাইল সংযোগ",
        "autoblockid": "স্বয়ংক্রিয় বাধা #$1",
        "block": "ব্যবহারকারীকে বাধা দাও",
        "unblock": "ব্যবহারকারীর উপর থেকে বাধা অপসারণ",
-       "blockip": "{{GENDER:$1|বà§\8dযবহারà¦\95ারà§\80à¦\95à§\87}} à¦¬à¦¾à¦§à¦¾ à¦¦à¦¾à¦\93",
+       "blockip": "{{GENDER:$1|বà§\8dযবহারà¦\95ারà§\80à¦\95à§\87}} à¦¬à¦¾à¦§à¦¾ à¦¦à¦¿à¦¨",
        "blockiptext": "কোন নির্দিষ্ট আইপি ঠিকানা বা ব্যবহারকারীর লেখার অধিকারে বাধা দিতে নিচের ফর্মটি ব্যবহার করুন।\nএটি কেবলমাত্র ধ্বংসপ্রবণতা প্রতিরোধে ও [[{{MediaWiki:Policy-url}}|নীতিমালা]] মেনে সম্পাদন করা উচিত।\nনিচে একটি নির্দিষ্ট কারণ দিন (উদাহরণস্বরূপ, যেসব পাতার ধ্বংসসাধন করা হয়েছে, সেগুলি উল্লেখ করতে পারেন)।\nআপনি একটি নির্দিষ্ট সীমার অন্তর্গত একাধিক আইপি ঠিকানাকে বাধা দিতে পারেন; এজন্য [https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing CIDR] সিনট্যাক্স বা পদবিন্যাসবিধি ব্যবহার করুন; এরকম বৃহত্তম অনুমোদিত সীমা হচ্ছে IPv4-এর ক্ষেত্রে /$1 এবং IPv6-এর ক্ষেত্রে /$2।",
        "ipaddressorusername": "আইপি ঠিকানা বা ব্যবহারকারীর নাম:",
        "ipbexpiry": "যখন মেয়াদোত্তীর্ণ হবে:",
        "immobile-target-namespace-iw": "পাতা স্থানান্তরের ক্ষেত্রে ইন্টারউইকি লিংক ব্যবহার করা যাবে না।",
        "immobile-source-page": "এই পাতাটির স্থানান্তর সম্ভব নয়।",
        "immobile-target-page": "গন্তব্য শিরোনামে স্থানান্তর করা যাবে না।",
-       "bad-target-model": "à¦\86পনার à¦\89লà§\8dলà§\87à¦\96িত à¦\95নà§\8dà¦\9fà§\87নà§\8dà¦\9f à¦®à¦¡à§\87লà¦\9fি à¦\86লাদা। $1 à¦¥à§\87à¦\95à§\87 $2 à¦\95নভারà§\8dà¦\9f à¦\95রা à¦¯à¦¾à¦\9aà§\8dà¦\9bে না।",
+       "bad-target-model": "à¦\86à¦\95াà¦\99à§\8dà¦\95à§\8dষিত à¦\97নà§\8dতবà§\8dযà¦\9fি à¦\8fà¦\95à¦\9fি à¦­à¦¿à¦¨à§\8dন à¦¸à¦¾à¦®à¦\97à§\8dরà§\80র à¦®à¦¡à§\87ল à¦¬à§\8dযবহার à¦\95রà§\87। $1 à¦¥à§\87à¦\95à§\87 $2-à¦\8f à¦°à§\82পানà§\8dতর à¦\95রা à¦¯à¦¾à¦¬ে না।",
        "imagenocrossnamespace": "কোনো ফাইল ফাইলনয় এমন নামস্থানে স্থানান্তর সম্ভব নয়",
        "nonfile-cannot-move-to-file": "কোনো ফাইলনয় এমন কোনো পাতা ফাইল নামস্থানে স্থানান্তর সম্ভব নয়",
        "imagetypemismatch": "নতুন ফাইল এক্সটেনশনটি ফাইলের ধরনের সাথে মিলছে না",
        "import-error-interwiki": "\"$1\" পাতাটি আমদানি করা যায়নি কারণ এই নামটি বহিঃসংযোগর জন্য নির্ধারিত (আন্তঃউইকি)।",
        "import-error-special": "\"$1\" পাতাটি আমদানি করা যায়নি কারণ এটি একটি বিশেষ নামস্থানকে নির্দেশ করে যেটি সম্পাদনার জন্য অনুমোদিত নয়।",
        "import-error-invalid": "\"$1\" পাতাটি আমদানি করা যায়নি কারণ নামটি সঠিক নয়।",
-       "import-error-unserialize": "$1 à¦ªà¦¾à¦¤à¦¾à¦° $2 à¦¸à¦\82সà§\8dà¦\95রণà¦\9fি à¦¸à¦¿à¦°à¦¿à¦¯à¦¼à¦¾à¦²à¦¾à¦\87à¦\9c à¦\95রা à¦¯à¦¾à¦\9aà§\8dà¦\9bà§\87 à¦¨à¦¾à¥¤ à¦\8fà¦\87 à¦°à¦¿à¦­à¦¿à¦¶à¦¨à§\87 $4 à¦¹à¦¿à¦¸à¦¾à¦¬à§\87 $3 à¦\95নà§\8dà¦\9fà§\87নà§\8dà¦\9f à¦®à¦¡à§\87লà§\87 à¦¸à¦¿à¦°à¦¿à¦¯à¦¼à¦¾à¦²à¦¾à¦\87à¦\9c করা আছে।",
+       "import-error-unserialize": "$1 à¦ªà¦¾à¦¤à¦¾à¦° $2 à¦¸à¦\82সà§\8dà¦\95রণà¦\9fি à¦§à¦¾à¦°à¦¾à¦¬à¦¾à¦¹à¦¿à¦\95ভাবà§\87 à¦ªà§\8dরà¦\95াশ à¦\95রা à¦¯à¦¾à¦\9aà§\8dà¦\9bà§\87 à¦¨à¦¾à¥¤ à¦\8fà¦\87 à¦¸à¦\82সà§\8dà¦\95রণà§\87 $4 à¦¹à¦¿à¦¸à¦¾à¦¬à§\87 $3 à¦¬à¦¿à¦·à¦¯à¦¼à¦¬à¦¸à§\8dতà§\81র à¦®à¦¡à§\87লà§\87 à¦§à¦¾à¦°à¦¾à¦¬à¦¾à¦¹à¦¿à¦\95ভাবà§\87 à¦ªà§\8dরà¦\95াশ করা আছে।",
        "import-error-bad-location": "বিষয়বস্তু মডেল $3 ব্যবহার করে সম্পাদিত $2 নং সংশোধনটি \"$1\" পাতায় সংরক্ষণ করা যাবে না, কারণ ঐ মডেলটি ঐ পাতাতে প্রযোজ্য নয়।",
        "import-options-wrong": "{{PLURAL:$2|পছন্দ}} নির্বাচনে ভুল: <nowiki>$1</nowiki>",
        "import-rootpage-invalid": "মূল পাতার ভুল শিরনাম দেয়া হয়েছে।",
        "tooltip-ca-history": "এই পাতার পুরনো সংস্করণগুলি",
        "tooltip-ca-protect": "এই পাতাকে সুরক্ষিত করো",
        "tooltip-ca-unprotect": "এই পাতার সুরক্ষা পরিবর্তন করো",
-       "tooltip-ca-delete": "পাতাà¦\9fি à¦®à§\81à¦\9bà§\87 à¦«à§\87লà§\8b",
+       "tooltip-ca-delete": "à¦\8fà¦\87 à¦ªà¦¾à¦¤à¦¾à¦\9fি à¦\85পসারণ à¦\95রà§\81ন",
        "tooltip-ca-undelete": "পাতাটি অপসারণের আগে যে সম্পাদনাগুলি করা হয়েছিল সেগুলি উদ্ধার করা হোক",
        "tooltip-ca-move": "পাতাটি স্থানান্তর করুন",
        "tooltip-ca-watch": "এই পাতাটি আপনার নজরতালিকায় যোগ করুন",
        "markedaspatrollederrornotify": "পরীক্ষিত হিসাবে চিহ্নিত করতে ব্যর্থ।",
        "patrol-log-page": "পরীক্ষণ লগ",
        "patrol-log-header": "এটি যাচাইকৃত রিভিশনের তালিকা।",
-       "log-show-hide-patrol": "পরীক্ষণ লগ $1",
-       "log-show-hide-tag": "ট্যাগ লগ $1",
        "confirm-markpatrolled-button": "ঠিক আছে",
        "confirm-markpatrolled-top": "$2-এর $3 নং সংস্করণটি পরীক্ষিত হিসেবে চিহ্নিত করবেন?",
        "deletedrevision": "মুছে ফেলা পুরাতন সংশোধন $1",
        "limitreport-templateargumentsize-value": "$1/$2 {{PLURAL:$2|বাইট}}",
        "limitreport-expansiondepth": "সর্বোচ্চ গভীরতা বিস্তার",
        "limitreport-expensivefunctioncount": "ব্যয়বহুল পার্সার ফাংশন গণনা",
+       "limitreport-unstrip-depth": "Unstrip পুনরাবৃত্তির গভীরতা",
+       "limitreport-unstrip-size": "পরবর্তী-প্রসারিত unstrip আকার",
        "limitreport-unstrip-size-value": "$1/$2 {{PLURAL:$2|বাইট}}",
        "expandtemplates": "টেমপ্লেট সম্প্রসারণ",
        "expand_templates_intro": "এই বিশেষ পাতাটি কিছু উইকিটেক্সট গ্রহণ করে এবং এর ভেতরের সব টেমপ্লেট বারংবার সম্প্রসারিত করে।\nএছাড়াও এটি\n<code><nowiki>{{</nowiki>#language:...}}</code>-এর মত পার্সার ফাংশন,\n<code><nowiki>{{</nowiki>CURRENTDAY}}</code>-এর মত ভ্যারিয়েবল\nমোটকথা দ্বিতীয় বন্ধনীর মধ্যে অবস্থিত সবকিছুকেই সম্প্রসারিত করতে পারে।",
        "special-characters-group-hebrew": "হিব্রু",
        "special-characters-group-bangla": "বাংলা",
        "special-characters-group-tamil": "তামিল",
-       "special-characters-group-telugu": "তà§\87লà§\87গু",
+       "special-characters-group-telugu": "তà§\87লà§\81গু",
        "special-characters-group-sinhala": "সিংহলী",
        "special-characters-group-gujarati": "গুজরাটি",
        "special-characters-group-devanagari": "দেবনাগরী",
        "undelete-cantcreate": "আপনি এই পাতাটি ফিরিয়ে আনতে পারবেন না কারণ এই নামে কোন পাতা বিদ্যমান নেই ও আপনার এই পাতাটি তৈরি করার অনুমতি নেই।",
        "pagedata-title": "পাতার উপাত্ত",
        "pagedata-not-acceptable": "কোন মিলে যাওয়া বিন্যাস পাওয়া যায় নি। সমর্থিত MIME ধরনগুলি হল: $1",
-       "pagedata-bad-title": "অপ্রযোজ্য শিরোনাম: \"$1\""
+       "pagedata-bad-title": "অপ্রযোজ্য শিরোনাম: \"$1\"",
+       "unregistered-user-config": "নিরাপত্তার কারণে জাভাস্ক্রিপ্ট, CSS এবং JSON ব্যবহারকারী উপপাতাগুলি অনিবন্ধিত ব্যবহারকারীদের জন্য লোড করা যাবে না।",
+       "passwordpolicies": "পাসওয়ার্ড নীতি",
+       "passwordpolicies-summary": "এটি এই উইকিতে সংজ্ঞায়িত ব্যবহারকারী দলের কার্যকর পাসওয়ার্ড নীতিগুলির একটি তালিকা।",
+       "passwordpolicies-group": "দল",
+       "passwordpolicies-policies": "নীতিসমূহ",
+       "passwordpolicies-policy-minimalpasswordlength": "পাসওয়ার্ড অবশ্যই {{PLURAL:$1|১ অক্ষরের|$1 অক্ষরের}} হতে হবে",
+       "passwordpolicies-policy-passwordcannotmatchusername": "পাসওয়ার্ড ব্যবহারকারী নামের মত একই হতে পারে না",
+       "passwordpolicies-policy-passwordcannotmatchblacklist": "পাসওয়ার্ড বিশেষত কালো তালিকাভুক্ত পাসওয়ার্ডের সাথে মিলতে পারবে না",
+       "passwordpolicies-policy-maximalpasswordlength": "পাসওয়ার্ড $1 {{PLURAL:$1|অক্ষরের}} চেয়ে কম দীর্ঘ হতে হবে"
 }
index 97cbed7..46cc757 100644 (file)
        "whatlinkshere": "གང་དང་སྦྲེལ་བ།",
        "whatlinkshere-title": "\"$1\" ལ སྦྲེལ་ཡོད་པའི་ཤོག་ངོས།",
        "whatlinkshere-page": "ཤོག་ངོས།",
-       "linkshere-2": "གཤམ་གྱི་ཤོག་ངོས་རྣམས་ '''$1''': ལ་སྦྲེལ་ཡོད།",
-       "nolinkshere-2": "<strong>$1</strong> ཤོག་ངོས་གཅིག་ཀྱང་སྦྲེལ་མཐུད་མི་འདུག།",
+       "linkshere": "གཤམ་གྱི་ཤོག་ངོས་རྣམས་ '''$2''': ལ་སྦྲེལ་ཡོད།",
+       "nolinkshere": "<strong>$2</strong> ཤོག་ངོས་གཅིག་ཀྱང་སྦྲེལ་མཐུད་མི་འདུག།",
        "isimage": "ཡིག་རིས་སྦྲེལ་མཐུད།",
        "whatlinkshere-links": "← སྦྲེལ་མཐུད།",
        "whatlinkshere-hideredirs": "$1 ཁ་ཕྱོགས་བསྐྱར་སྟོན།",
index f048f56..da44540 100644 (file)
@@ -5,7 +5,8 @@
                        "Uttam Singha, Dec 2006",
                        "아라",
                        "Macofe",
-                       "MtDu"
+                       "MtDu",
+                       "Bodhisattwa"
                ]
        },
        "tog-underline": "লিঙ্কর তলে দুরগ দিক:",
        "whatlinkshere": "যে পাতাহানিত্ত এহানাত মিলাপ আসে",
        "whatlinkshere-title": "পাতাহানি $1 -ত মিলাপ আসে",
        "whatlinkshere-page": "পাতা:",
-       "linkshere-2": "থাঙনার পাতাহানি '''$1'''র লগে মিলাপ আসে:",
-       "nolinkshere-2": "পাতা '''$1'''হানাত কোন মিলাপ নেই।",
+       "linkshere": "থাঙনার পাতাহানি '''$2'''র লগে মিলাপ আসে:",
+       "nolinkshere": "পাতা '''$2'''হানাত কোন মিলাপ নেই।",
        "isredirect": "বুলনদের পাতা",
        "istemplate": "বরানি",
        "isimage": "ফাইল মিলাপ",
        "special-characters-group-persian": "ফারসি",
        "special-characters-group-hebrew": "হিব্রু",
        "special-characters-group-bangla": "বাংলা",
-       "special-characters-group-telugu": "তà§\87লà§\87গু",
+       "special-characters-group-telugu": "তà§\87লà§\81গু",
        "special-characters-group-sinhala": "শিংহলী",
        "special-characters-group-gujarati": "গুজরাতি",
        "special-characters-group-thai": "থাই",
index c59dffa..8e9e882 100644 (file)
@@ -21,7 +21,7 @@
        "tog-editondblclick": "ڤیرایشت بٱلگاٛیل ڤا دو کئرٱت پۊرنیڌن",
        "tog-editsectiononrightclick": "ڤیرایشت ڤابیڌن ڤا راست پۊرنیڌن ری بٱرجا داسۊن هر جاگٱ",
        "tog-watchcreations": "اٛزاف کردن او بٱلگاٛیلی کاٛ خوم راست کردوماٛ و او جانیایلی کاٛ خوم لاهامسۊناٛ مئن سئیل بٱرگ خوم",
-       "tog-watchdefault": "اضاف کردن اوصفحاتی که خوم اصلاح کردم به فهرست نمایشی",
+       "tog-watchdefault": "اٛزاف کردن بٱلگاٛیٱل و جانیایٱلی کاٛ مو مئن سئیل برگوم ڤیرایشدسۊن کردوماٛ",
        "tog-watchmoves": "اضاف کردن صفحاتی که خوم جابجا کردم به فهرست نمایشی",
        "tog-watchdeletion": "اضاف کردن صفحاتی که خوم پاک کردم به فهرست نمایشی خوم",
        "tog-minordefault": "علامت نهادن به اصلاحات ناقص",
@@ -32,7 +32,7 @@
        "tog-enotifminoredits": "امیل به مو سی صفحات ناقص اصلاح شده",
        "tog-enotifrevealaddr": "دیاری کردن تیرنشۊن ٱنجوماناماٛ مو مئن دیارکاری ایمیلی",
        "tog-shownumberswatching": "نشودادن شماره کاربران درحال کار یاتماشا",
-       "tog-oldsig": "اÙ\85ضا Ø§Û\8cسنی",
+       "tog-oldsig": "اÙ\9bÙ\85زا Ø§Û\8cسئنی",
        "tog-fancysig": "امضایل ناتموم",
        "tog-uselivepreview": "پیش سئیل زندە ڤن ڤا کار",
        "tog-forceeditsummary": "یادآوری سریع به مو هنگام اصلاح عقیم وخلاصه",
@@ -64,7 +64,7 @@
        "fri": "جمعه",
        "sat": "شنبه",
        "january": "جانڤیە",
-       "february": "فئڤریە",
+       "february": "فڤریٱ",
        "march": "مارس",
        "april": "آڤریل",
        "may_long": "مە",
        "copyrightpage": "{{ns:project}}:کپی رایت",
        "currentevents": "اتفاقات جاری",
        "currentevents-url": "Project:اتفاقات جاری",
-       "disclaimers": "تیە پوٙشنا",
+       "disclaimers": "تی پۊشنیڌنیا",
        "disclaimerpage": "Project: تیە پوشنیدٙئنئ کولی",
        "edithelp": "کمک برای اصلاح",
        "helppage-top-gethelp": "هومیاري",
        "whatlinkshere": "لینک های ای صفحه",
        "whatlinkshere-title": "صفحات آن لینک به \"$1\"",
        "whatlinkshere-page": "بألگە",
-       "linkshere-2": "لینک صفحات ذیل الذکر به '''$1''':",
-       "nolinkshere-2": "هیچ صفحه ای پیوند نداردبه '''$1'''.",
+       "linkshere": "لینک صفحات ذیل الذکر به '''$2''':",
+       "nolinkshere": "هیچ صفحه ای پیوند نداردبه '''$2'''.",
        "isredirect": "صفحه تغییر مسیر",
        "istemplate": "استفاده‌ وابیده داخل صفحه",
        "isimage": "جانیا هوم پیوند",
index 48547d4..48526f5 100644 (file)
        "customcssprotected": "N'oc'h ket aotreet da gemmañ ar bajenn CSS-mañ rak kavout a reer enni arventennoù personel un implijer all.",
        "customjsprotected": "N'oc'h ket aotreet da gemmañ ar bajenn JavaScript-mañ rak kavout a reer enni arventennoù personel un implijer all.",
        "mycustomcssprotected": "N'oc'h ket aotreet da gemmañ d'ar bajenn CSS-mañ.",
+       "mycustomjsonprotected": "N'oc'h ket aotreet da gemmañ ar bajenn JSON-mañ.",
        "mycustomjsprotected": "N'oc'h ket aotreet da gemmañ d'ar bajenn JavaScript-mañ.",
        "myprivateinfoprotected": "N'ho peus ket ar gwirioù evit kemmañ ho titouroù personel.",
        "mypreferencesprotected": "N'ho peus ket ar gwirioù evit kemmañ ho Penndibaboù.",
        "nosuchusershort": "N'eus perzhiad ebet gantañ an anv « $1 ». Gwiriit ar reizhskrivadur.",
        "nouserspecified": "Ret eo deoc'h spisaat un anv implijer.",
        "login-userblocked": "Stanket eo an implijer-mañ. N'eo ket aotret da gevreañ.",
-       "wrongpassword": "Ger-tremen kamm. Klaskit en-dro.",
+       "wrongpassword": "Ger-tremen pe anv implijer kamm. Klaskit en-dro.",
        "wrongpasswordempty": "Ger-tremen ebet. Lakait unan mar plij.",
        "passwordtooshort": "{{PLURAL:$1|1 arouezenn|$1 arouezenn}} hir a rank bezañ ar gerioù-tremen da nebeutañ.",
        "passwordtoolong": "N'hall ket ar gerioù-tremen bezañ enno ouzhpenn $1 {{PLURAL:$1|1 arouezenn|$1 arouezenn}}.",
-       "passwordtoopopular": "N'haller ket ober gant gerioù-ter boutin betek re. Grit gant ur ger-tremen raloc'h.",
+       "passwordtoopopular": "N'haller ket ober gant gerioù-kuzh boutin betek re. Grit gant ur ger-tremen diaesoc'h da gavout.",
        "password-name-match": "Rankout a ra ho ker-tremen bezañ disheñvel diouzh hoc'h anv implijer.",
        "password-login-forbidden": "Berzet eo ober gant an anv implijer hag ar ger-tremen-mañ.",
        "mailmypassword": "Adderaouekaat ar ger-tremen",
        "botpasswords-existing": "Gerioù-tremen botoù a zo anezho",
        "botpasswords-createnew": "Krouiñ ur ger-tremen bot nevez",
        "botpasswords-editexisting": "Cheñch ger-tremen ur bot a zo anezhañ c'hoazh",
+       "botpasswords-label-needsreset": "(ar ger kuzh a rank bezañ riñset)",
        "botpasswords-label-appid": "Anv ar robot",
        "botpasswords-label-create": "Krouiñ",
        "botpasswords-label-update": "Hizivaat",
        "savechanges": "Enrollañ ar c'hemmoù",
        "publishpage": "Embann ar bajenn",
        "publishchanges": "Embann ar c'hemmoù",
+       "savearticle-start": "Enrollañ ar bajenn...",
+       "savechanges-start": "Enrollañ ar c'hemmoù...",
+       "publishpage-start": "Embann ar bajenn...",
+       "publishchanges-start": "Embann ar c'hemmoù",
        "preview": "Rakwelet",
        "showpreview": "Rakwelet",
        "showdiff": "Diskouez ar c'hemmoù",
        "postedit-confirmation-created": "Krouet eo bet ar bajenn.",
        "postedit-confirmation-restored": "Adsavet eo bet ar bajenn.",
        "postedit-confirmation-saved": "Enrollet eo bet ho kemmoù.",
+       "postedit-confirmation-published": "Embannet eo bet ho kemm.",
        "edit-already-exists": "N'eus ket bet gallet krouiñ ur bajenn nevez.\nKrouet e oa bet c'hoazh.",
        "defaultmessagetext": "Testenn dre ziouer",
        "content-failed-to-parse": "C'hwitet eo dielfennadur endalc'had $2 evit ar patrom $1: $3",
        "diff-multi-sameuser": "({{PLURAL:$1|Ur reizhadenn da c'hortoz|$1 reizhadenn da c'hortoz}} gant ar memes implijer kuzhet)",
        "diff-multi-otherusers": "({{PLURAL:$1|Ur reizhadenn da c'hortoz|$1 reizhadenn da c'hortoz}} gant {{PLURAL:$2|un implijer all|$2 implijer}} kuzhet.)",
        "diff-multi-manyusers": "({{PLURAL:$1|Ur reizhadenn da c'hortoz|$1 reizhadenn da c'hortoz}} gant muioc'h eget $2 {{PLURAL:$2|implijer|implijer}} kuzhet.)",
+       "diff-paragraph-moved-tonew": "Fiñvet eo bet ar rannbennad. Klikit evit mont davet al lec'hiadur nevez.",
+       "diff-paragraph-moved-toold": "Ar rannbennad azo bet fiñvet. Klikit evit mont davet al lec'hiadur gozh.",
        "difference-missing-revision": "!!{{PLURAL:$2|Un adweladur|$2 adweladurioù}} eus an disheñvelder ($1) {{PLURAL:$2|n'eo ket bet kavet|n'int ket bet adkavet}}.\n\nC'hoarvezout a ra peurliesañ pa vez heuliet ul liamm disheñvel dispredet war-zu ur bajenn zo bet dilamet.\nGallout a reot kavout munudoù e [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} renabl an dilamadurioù].",
        "searchresults": "Disoc'hoù enklask",
        "searchresults-title": "Disoc'hoù klask evit \"$1\"",
        "timezoneregion-indian": "Meurvor Indez",
        "timezoneregion-pacific": "Meurvor Habask",
        "allowemail": "Aotren ar posteloù a-berzh implijerien all",
+       "email-allow-new-users-label": "Aotreañ e-bostoù a-berzh an implijerien nevez",
+       "email-blacklist-label": "Difenn d'an implijerien-se da gas un e-bost din:",
        "prefs-searchoptions": "Klask",
        "prefs-namespaces": "Esaouennoù",
        "default": "dre ziouer",
        "prefs-files": "Restroù",
        "prefs-custom-css": "CSS personelaet",
+       "prefs-custom-json": "JSON hiniennel",
        "prefs-custom-js": "JS personelaet",
-       "prefs-common-config": "JavaScript ha CSS kenrannet evit an holl wiskadurioù :",
+       "prefs-common-config": "CSS/JSON/JavaScript kenrannet evit an holl wiskadurioù :",
        "prefs-reset-intro": "Ober gant ar bajenn-mañ a c'hallit evit adlakaat ho penndibaboù dre ziouer evit al lec'hienn-mañ. Kement-se n'hallo ket bezañ disc'hraet da c'houde.",
        "prefs-emailconfirm-label": "Kadarnaat ar postel :",
        "youremail": "Postel :",
        "prefs-dateformat": "Furmad an deiziadoù",
        "prefs-timeoffset": "Linkadur eur",
        "prefs-advancedediting": "Dibarzhioù araokaet",
+       "prefs-developertools": "Ostilhoù diorren",
        "prefs-editor": "Aozer",
        "prefs-preview": "Rakwelet",
        "prefs-advancedrc": "Dibarzhioù araokaet",
+       "prefs-opt-out": "Nac'hañ ar c'hemmoù",
        "prefs-advancedrendering": "Dibarzhioù araokaet",
        "prefs-advancedsearchoptions": "Dibarzhioù araokaet",
        "prefs-advancedwatchlist": "Dibarzhioù araokaet",
        "prefs-diffs": "Diforc'hioù",
        "prefs-help-prefershttps": "Efediñ a ray an dibarzh-mañ kentañ gwech ma kevreoc'h.",
        "prefswarning-warning": "Kemmet eo bet ho penndibaboù ganeoc'h, met enrollet n'int ket bet avat.\nMar kuitait ar bajenn-mañ hep klikañ war \"$1\" ne vo ket nevesaet ho penndibaboù",
-       "prefs-tabs-navigation-hint": "Titourig : Gallout a rit implijout an touchennoù bir kleiz ha bir dehoù evit merdeiñ etre an ivinelloù e roll an ivinelloù.",
+       "prefs-tabs-navigation-hint": "Titourig : Gallout a rit implijout an touchennoù bir kleiz ha bir dehou evit merdeiñ etre an ivinelloù e roll an ivinelloù.",
        "userrights": "Gwirioù an implijer",
        "userrights-lookup-user": "Diuzañ un implijer",
        "userrights-user-editname": "Lakait un anv implijer :",
        "right-editcontentmodel": "Kemmañ patrom danvez ur bajenn bennak",
        "right-editinterface": "Kemmañ an etrefas implijer",
        "right-editusercss": "Kemmañ restroù CSS implijerien all",
+       "right-edituserjson": "Kemmañ restroù JSON un implijer all",
        "right-edituserjs": "Kemmañ restroù JS implijerien all",
        "right-editmyusercss": "Aozañ ho restroù implijer CSS deoc'h-c'hwi",
+       "right-editmyuserjson": "Aozañ ho restroù implijer JSON deoc'h-c'hwi",
        "right-editmyuserjs": "Aoazañ ho restroù JavaScript implijer deoc'h-c'hwi",
        "right-viewmywatchlist": "Gwelet ho roll-evezhiañ deoc'h-c'hwi",
        "right-editmywatchlist": "Kemmañ ho roll evezhiañ deoc'h-c'hwi. Notit mat e vo c'hoazh ouzhpennet pajennoù hep ar gwir-mañ gant obererezhioù zo.",
        "grant-createaccount": "Krouiñ kontoù",
        "grant-createeditmovepage": "Krouiñ, aozañ ha dilec'hiañ pajennoù",
        "grant-delete": "Diverkañ ar pajennoù, an adweladennoù hag an enmontoù er marilh",
-       "grant-editinterface": "Kemmañ esaouenn anvioù MediaWiki hag ar CSS/JavaScript implijer",
-       "grant-editmycssjs": "Kemmañ ho CSS/JavaScript implijer",
+       "grant-editinterface": "Kemmañ esaouenn anvioù MediaWiki hag implijer CSS/JSON/JavaScript",
+       "grant-editmycssjs": "Kemmañ ho CSS/JSON/JavaScript implijer",
        "grant-editmyoptions": "Kemmañ ho penndibaboù implijer.",
        "grant-editmywatchlist": "Kemmañ ho roll evezhiañ",
        "grant-editpage": "Kemmañ pajennoù a zo anezho c'hoazh",
        "rcfilters-other-review-tools": "Ostilhoù reizhañ all",
        "rcfilters-group-results-by-page": "Strollañ an disoc'hoù dre bajenn",
        "rcfilters-activefilters": "Siloù oberiant",
+       "rcfilters-activefilters-hide": "Kuzhat",
+       "rcfilters-activefilters-show": "Diskouez",
        "rcfilters-advancedfilters": "Siloù araokaet",
        "rcfilters-limit-title": "Kemmoù da vezañ diskouezet",
        "rcfilters-limit-and-date-label": "$1 {{PLURAL:$1|kemm|kemmoù}}, $2",
        "rcfilters-hideminor-conflicts-typeofchange-global": "Tabut zo etre ar sil \"Kemmoù dister\" hag unan pe meur a sil a Seurt kemmoù peogwir n'haller merkañ kemmoù zo evel \"dister\". Kavet e vo ar siloù o tabutal e takad ar siloù gweredekaet, a-us.",
        "rcfilters-hideminor-conflicts-typeofchange": "Seurtoù kemmoù zo n'hallont ket bezañ merket evel \"dister,\", rak se ez eus tabut etre ar sil-mañ ha siloù ar Seurtoù kemmoù da heul : $1",
        "rcfilters-typeofchange-conflicts-hideminor": "Tabut zo etre ar sil-mañ Seurt kemmoù gant sil ar \"c'hemmoù dister\". Kemmoù zo n'hallont ket bezañ merket evel \"dister\".",
-       "rcfilters-filtergroup-lastRevision": "Stumm diwezhañ",
-       "rcfilters-filter-lastrevision-label": "Stumm diwezhañ",
+       "rcfilters-filtergroup-lastRevision": "Stumm a-vremañ pe stumm red",
+       "rcfilters-filter-lastrevision-label": "Stumm a-vremañ pe stumm red",
        "rcfilters-filter-lastrevision-description": "Kemm diwezhañ graet ouzh ur bajenn.",
        "rcfilters-filter-previousrevision-label": "Stummoù koshoc'h",
        "rcfilters-filter-previousrevision-description": "An holl gemmoù nemet ar c'hemm diwezhañ graet ouzh ur bajenn.",
+       "rcfilters-filter-excluded": "Skarzhet",
+       "rcfilters-tag-prefix-namespace-inverted": "<strong>:not</strong> $1",
+       "rcfilters-exclude-button-off": "Skarzhañ ar re dibabet",
+       "rcfilters-exclude-button-on": "Re dibabet skarzhet",
+       "rcfilters-filter-showlinkedfrom-label": "Diskouez ar c'hemmoù war ar bajennoù liammet",
        "rcfilters-filter-showlinkedto-label": "Diskouez ar c'hemmoù war ar bajennoù liammet",
        "rcfilters-target-page-placeholder": "Skrivañ anv ar bajenn (pe rummad)",
        "rcnotefrom": "Setu aze {{PLURAL:$5|ar c'hemm|ar c'hemmoù}} c'hoarvezet abaoe an <strong>$3, $4</strong> (<strong>$1</strong> d'ar muiañ).",
        "uploadstash-refresh": "Freskaat roll ar restroù",
        "uploadstash-thumbnail": "gwelet ar munud",
        "uploadstash-exception": "Dibosupl stokañ an enporzhiadenn er sanailh ($1) : \"$2\".",
+       "uploadstash-bad-path-unknown-type": "Obererezh dianav \"$1\".",
+       "uploadstash-zero-length": "Ment ar restr a zo mann",
        "invalid-chunk-offset": "Direizh eo offset ar rannad",
        "img-auth-accessdenied": "Moned nac'het",
        "img-auth-nopathinfo": "Mankout a ra ar PATH_INFO.\nN'eo ket kefluniet ho servijer evit reiñ an titour-mañ.\nMarteze eo diazezet war CGI ha n'hall ket skorañ img_auth.\nGwelet https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization",
        "pageswithprop-legend": "Pajennoù gant ur perzh pajenn",
        "pageswithprop-text": "Rollañ a ra ar bajenn-mañ ar pajennoù a ra gant ur perzh pajenn dibar",
        "pageswithprop-prop": "Anv ar perzh :",
+       "pageswithprop-reverse": "Renkañ en urzh enep",
        "pageswithprop-submit": "Mont",
        "pageswithprop-prophidden-long": "talvoud perzh testenn hir kuzhet ($1)",
        "pageswithprop-prophidden-binary": "Talvoud perzh binarel kuzhet ($1)",
        "apisandbox-dynamic-error-exists": "Bez' ez eus c'hoazh eus un arventenn anvet \"$1\".",
        "apisandbox-deprecated-parameters": "Arventennoù dispredet",
        "apisandbox-fetch-token": "Leuniañ emgefre ar jedouer",
+       "apisandbox-add-multi": "Ouzhpennañ",
        "apisandbox-submit-invalid-fields-title": "Direizh eo maeziennoù zo",
        "apisandbox-submit-invalid-fields-message": "Reizhit ar maeziennoù merket ha klaskit en-dro.",
        "apisandbox-results": "Disoc'hoù",
        "whatlinkshere": "Pajennoù liammet",
        "whatlinkshere-title": "Pajennoù liammet ouzh \"$1\"",
        "whatlinkshere-page": "Pajenn :",
-       "linkshere-2": "Ar pajennoù a-is zo enno ul liamm a gas war-du '''$1''':",
-       "nolinkshere-2": "N'eus pajenn ebet enni ul liamm war-du '''$1'''.",
-       "nolinkshere-ns-2": "Pajenn ebet n'eo liammet ouzh '''$1''' en esaouenn anv dibabet.",
+       "linkshere": "Ar pajennoù a-is zo enno ul liamm a gas war-du '''$2''':",
+       "nolinkshere": "N'eus pajenn ebet enni ul liamm war-du '''$2'''.",
+       "nolinkshere-ns": "Pajenn ebet n'eo liammet ouzh '''$2''' en esaouenn anv dibabet.",
        "isredirect": "pajenn adkas",
        "istemplate": "enframmet",
        "isimage": "Liamm war-zu ar restr",
        "markedaspatrollederrornotify": "N'eus ket bet gallet merkañ evel gwiriet.",
        "patrol-log-page": "Log gwiriañ",
        "patrol-log-header": "Setu ur marilh eus ar stummoù patrouilhet.",
-       "log-show-hide-patrol": "$1 istor ar stummoù gwiriet",
-       "log-show-hide-tag": "$1 marilh an dikedenn",
        "confirm-markpatrolled-button": "Mat eo",
        "confirm-markpatrolled-top": "Merkañ adweladenn $3 eus $2 evel gwiriet ?",
        "deletedrevision": "Diverket stumm kozh $1.",
        "newimages-user": "Chomlec'h IP pe anv implijer",
        "newimages-showbots": "Diskouez an ezporzhiadennoù graet gant robotoù",
        "newimages-hidepatrolled": "Kuzhat ar enporzhiadennoù gwiriet",
+       "newimages-mediatype": "Doare media :",
        "noimages": "Netra da welet.",
        "gallery-slideshow-toggle": "Gwintañ ar munudoù",
        "ilsubmit": "Klask",
        "version-specialpages": "Pajennoù dibar",
        "version-parserhooks": "Astennoù an dielfenner",
        "version-variables": "Argemmennoù",
+       "version-editors": "Embannerien",
        "version-antispam": "Mirout ouzh ar strob",
        "version-other": "Diseurt",
        "version-mediahandlers": "Merer danvez liesvedia",
        "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|Dikedenn|Tikedenn}}]] : $2)",
        "tag-mw-contentmodelchange": "cheñch ar patrom danvez",
        "tag-mw-contentmodelchange-description": "KEmmoù a [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:ChangeContentModel cheñch patrom danvez] ur bajenn",
+       "tag-mw-new-redirect": "Adkas nevez",
        "tag-mw-undo": "Dizober",
        "tags-title": "Tikedennoù",
        "tags-intro": "Rollañ a ra ar bajenn-mañ an tikedennoù a c'hall ar meziant implijout da verkañ kemmoù hag o zalvoudegezh.",
        "compare-revision-not-exists": "N'eus ket eus an adweladenn spisaet ganeoc'h.",
        "diff-form": "ur '''furmskrid'''",
        "permanentlink": "Peurliamm",
+       "permanentlink-submit": "Lammañ d'ar c'hemm",
        "dberr-problems": "Ho tigarez ! Kudennoù teknikel zo gant al lec'hienn-mañ.",
        "dberr-again": "Gortozit un nebeud munutennoù a-raok adkargañ.",
        "dberr-info": "(Dibosupl kevreañ ouzh an diaz roadennoù : $1)",
        "restrictionsfield-badip": "Chomlec'h IP pe lijorenn direizh : $1",
        "restrictionsfield-label": "Lijorennoù IP aotreet :",
        "restrictionsfield-help": "Ur chomlec'h IP pe un esaouenn CIDR dre linenn. Evit gweredekaat pep tra, ober gant <pre>0.0.0.0/0\n::/0</pre>",
+       "edit-error-short": "Fazi : $1",
+       "edit-error-long": "Fazi:\n\n\n$1",
        "revid": "Adweladenn $1",
        "pageid": "ID ar bajenn $1",
        "rawhtml-notallowed": "N'hall an tikedennoù &lt;html&gt; bezañ implijet nemet er pajennoù normal.",
        "undelete-cantedit": "N'hallit ket diziverkañ ar bajenn-mañ rak n'oc'h ket aotreet da gemmañ anezhi.",
        "undelete-cantcreate": "N'hallit ket diziverkañ ar bajenn-mañ rak n'eus pajenn ebet gant an anv-mañ ha n'oc'h ket aotreet da grouiñ ar bajenn-mañ.",
        "pagedata-title": "Roadennoù ar bajenn",
-       "pagedata-bad-title": "Titl direizh : $1."
+       "pagedata-bad-title": "Titl direizh : $1.",
+       "passwordpolicies-group": "Strollad",
+       "passwordpolicies-policies": "Politikerezh",
+       "passwordpolicies-policy-passwordcannotmatchusername": "Ar ger-kuzh ne c'hell ket bezañ an anv implijer"
 }
index f97f35a..822a79f 100644 (file)
@@ -27,7 +27,9 @@
                        "Сербијана",
                        "Asmen",
                        "Obsuser",
-                       "Fitoschido"
+                       "Fitoschido",
+                       "BadDog",
+                       "Vlad5250"
                ]
        },
        "tog-underline": "Podvlačenje linkova:",
        "prefs-misc": "Razno",
        "prefs-resetpass": "Promijeni lozinku",
        "prefs-changeemail": "Promijeni ili ukloni adresu e-pošte",
-       "prefs-setemail": "Postavite e-mail adresu",
+       "prefs-setemail": "Postavi adresu e-pošte",
        "prefs-email": "Opcije e-pošte",
        "prefs-rendering": "Izgled",
        "saveprefs": "Sačuvaj",
        "badsig": "Loš sirovi potpis.\nProvjerite HTML tagove.",
        "badsiglength": "Vaš potpis je predug.\nMora biti manji od $1 {{PLURAL:$1|znaka|znaka|znakova}}.",
        "yourgender": "Kako želite da se predstavite?",
-       "gender-unknown": "Kad Vas spominje, softver će pokušati izbjegavati rod kad god je to moguće",
+       "gender-unknown": "Kad Vas spominje, softver će koristiti rodno neutralne riječi kad god je to moguće",
        "gender-male": "On uređuje wiki stranice",
        "gender-female": "Ona uređuje wiki stranice",
        "prefs-help-gender": "Ova postavka nije obavezna.\nSoftver koristi datu vrijednost da bi Vam se obratio i spomenuo Vas drugima koristeći odgovarajući gramatički rod.\nPodatak će biti javan.",
        "right-editcontentmodel": "Uređivanje modela sadržaja stranice",
        "right-editinterface": "Uređivanje korisničkog interfejsa",
        "right-editusercss": "Uređivanje tuđih CSS datoteka",
+       "right-edituserjson": "Uređivanje tuđih JSON datoteka",
        "right-edituserjs": "Uređivanje tuđih JavaScript datoteka",
        "right-editmyusercss": "Uređivanje vlastitih CSS datoteka",
+       "right-editmyuserjson": "Uređivanje vlastitih JSON datoteka",
        "right-editmyuserjs": "Uređivanje vlastitih JavaScript datoteka",
        "right-viewmywatchlist": "Pregledanje vlastitog spiska praćenja",
        "right-editmywatchlist": "Uređivanje vlastitog spiska praćenja. Važno je spomenuti da će neke radnje dodati stranice na spisak, čak i bez ovog prava.",
        "rcfilters-watchlist-showupdated": "Izmjene na stranicama koje niste posjetili otkako su izvršene istaknute su <strong>podebljanim slovima</strong>, s ispunjenim kružićima.",
        "rcfilters-preference-label": "Sakrij poboljšanu verziju nedavnih izmjena",
        "rcfilters-preference-help": "Poništava novi izgled interfejsa iz 2017. i sve alate dodane od tada.",
+       "rcfilters-watchlist-preference-label": "Sakrij poboljšanu verziju spiska praćenja",
+       "rcfilters-watchlist-preference-help": "Poništava novi izgled interfejsa iz 2017. i sve alate dodane od tada.",
        "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 izmjene počev od $3 u $2",
        "protectedtitles-submit": "Prikaži naslove",
        "listusers": "Spisak korisnika",
        "listusers-editsonly": "Prikaž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}}",
        "speciallogtitlelabel": "Cilj (naslov ili {{ns:user}}:korisničko ime):",
        "log": "Zapisnici",
        "logeventslist-submit": "Prikaži",
+       "logeventslist-more-filters": "Prikaži dodatne zapisnike:",
        "all-logs-page": "Svi javni zapisnici",
        "alllogstext": "Skupni prikaz svih dostupnih zapisnika sa {{GRAMMAR:genitiv|{{SITENAME}}}}.\nMožete suziti prikaz izabiranjem specifičnog zapisnika, korisničkog imena (razlikovati velika i mala slova) ili izmijenjenog članka (također treba razlikovati velika i mala slova).",
        "logempty": "Nema zatraženih stavki u zapisniku.",
        "dellogpage": "Zapisnik brisanja",
        "dellogpagetext": "Ispod je spisak nedavno obrisanih stavki.",
        "deletionlog": "zapisnik brisanja",
+       "log-name-create": "Zapisnik stvaranja stranica",
+       "log-description-create": "Ispod je spisak najnovije stvorenih stranica.",
+       "logentry-create-create": "$1 {{GENDER:$2|stvorio je|stvorila je}} stranicu $3",
        "reverted": "Vraćeno na raniju verziju",
        "deletecomment": "Razlog:",
        "deleteotherreason": "Drugi/dodatni razlog:",
        "whatlinkshere": "Šta vodi ovamo",
        "whatlinkshere-title": "Stranice koje vode na \"$1\"",
        "whatlinkshere-page": "Stranica:",
-       "linkshere-2": "Sljedeće stranice vode na <strong>$1</strong>:",
-       "nolinkshere-2": "Nijedna stranica nije povezana sa <strong>$1</strong>.",
-       "nolinkshere-ns-2": "Nijedna stranica nije povezana sa <strong>$1</strong> u izabranom imenskom prostoru.",
+       "linkshere": "Sljedeće stranice vode na <strong>$2</strong>:",
+       "nolinkshere": "Nijedna stranica nije povezana sa <strong>$2</strong>.",
+       "nolinkshere-ns": "Nijedna stranica nije povezana sa <strong>$2</strong> u izabranom imenskom prostoru.",
        "isredirect": "preusmjerenje",
        "istemplate": "uključivanje",
        "isimage": "veza na datoteku",
        "allmessagesname": "Naziv",
        "allmessagesdefault": "Predodređeni tekst",
        "allmessagescurrent": "Trenutni tekst",
-       "allmessagestext": "Ovo je spisak svih sistemskih poruka u dostupnih u imenskom prostoru MediaWiki.\nPosjetite [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation lokalizaciju MediaWikija] i [https://translatewiki.net translatewiki.net] ako želite doprinijeti općoj lokalizaciji MediaWikija.",
+       "allmessagestext": "Ovo je spisak sistemskih poruka u dostupnih u imenskom prostoru MediaWiki.\nPosjetite [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation lokalizaciju MediaWikija] i [https://translatewiki.net translatewiki.net] ako želite doprinijeti općoj lokalizaciji MediaWikija.",
        "allmessagesnotsupportedDB": "Ova stranica ne može biti korištena jer je <i>wgUseDatabaseMessages</i> isključen.",
        "allmessages-filter-legend": "Filter",
        "allmessages-filter": "Filter po stanju podešavanja:",
        "tooltip-pt-createaccount": "Ohrabrujemo vas da otvorite nalog i prijavite se, međutim to nije obavezno",
        "tooltip-ca-talk": "Razgovor o sadržaju",
        "tooltip-ca-edit": "Uredi ovu stranicu",
-       "tooltip-ca-addsection": "Započnite novu sekciju.",
+       "tooltip-ca-addsection": "Započni novu sekciju.",
        "tooltip-ca-viewsource": "Ova stranica je zaštićena.\nMožete joj vidjeti izvorni kôd",
        "tooltip-ca-history": "Prethodne verzije ove stranice.",
        "tooltip-ca-protect": "Zaštitite stranicu od budućih izmjena",
        "tooltip-search": "Pretraži {{GRAMMAR:akuzativ|{{SITENAME}}}}",
        "tooltip-search-go": "Idi na stranicu s tačno ovim imenom ako postoji",
        "tooltip-search-fulltext": "Pretražite stranice s ovim tekstom",
-       "tooltip-p-logo": "Posjetite početnu stranicu",
-       "tooltip-n-mainpage": "Posjetite početnu stranicu",
-       "tooltip-n-mainpage-description": "Posjetite početnu stranicu",
+       "tooltip-p-logo": "Posjeti početnu stranicu",
+       "tooltip-n-mainpage": "Posjeti početnu stranicu",
+       "tooltip-n-mainpage-description": "Posjeti početnu stranicu",
        "tooltip-n-portal": "O projektu, šta možete da uradite, gdje se šta nalazi",
        "tooltip-n-currentevents": "Podaci o onome na čemu se trenutno radi",
        "tooltip-n-recentchanges": "Spisak nedavnih izmjena na wiki.",
        "markedaspatrollederrornotify": "Označavanje stranice pregledanom nije uspjelo.",
        "patrol-log-page": "Zapisnik patroliranja",
        "patrol-log-header": "Ovo je zapisnik patroliranih izmjena.",
-       "log-show-hide-patrol": "$1 zapisnik patroliranja",
-       "log-show-hide-tag": "$1 zapisnik oznaka",
        "confirm-markpatrolled-button": "U redu",
        "confirm-markpatrolled-top": "Označiti izmjenu $3 stranice $2 patroliranom?",
        "deletedrevision": "Obrisana stara izmjena $1",
diff --git a/languages/i18n/btm.json b/languages/i18n/btm.json
new file mode 100644 (file)
index 0000000..6800d66
--- /dev/null
@@ -0,0 +1,711 @@
+{
+       "@metadata": {
+               "authors": [
+                       "Simartampua",
+                       "Apundung"
+               ]
+       },
+       "tog-underline": "Garis torui pranala:",
+       "tog-hideminor": "Bunion editan namenek i parubaan tarbaru",
+       "tog-hidepatrolled": "Bunion editan tarpatroli parubaan tarbaru",
+       "tog-newpageshidepatrolled": "Bunion alaman tarpatroli tingon daftar alaman baru",
+       "tog-hidecategorization": "Bunion pangkatagorian alaman",
+       "tog-extendwatchlist": "Kombangkon daftar pamataan tuna patidaon sude parubaan, inda umna tarbaru",
+       "tog-usenewrc": "Kalompokkon editan i tampilan parubaan tarbaru dot daftar pamataan mardasorkon alaman",
+       "tog-numberheadings": "Len nomor judul sacara otomatis",
+       "tog-showtoolbar": "Tampilkon bilah alat pangeditan",
+       "tog-editondblclick": "Pature alaman dohot klik ganda",
+       "tog-editsectiononrightclick": "Fungsion pangeditan bagian dohot mangklik siamun i judul bagian",
+       "tog-watchcreations": "Tambaon alaman na ubaen dot berkas na uunggah tu daftar pamataan",
+       "tog-watchdefault": "Tambaon alaman na upature tu daftar pamataan",
+       "tog-watchmoves": "Tambaon alaman na upapindah tu daftar pamataan",
+       "tog-watchdeletion": "Tambaon alaman na uapus tu daftar pantauan",
+       "tog-watchuploads": "Tambaon berkas baru nauunggah tu daftar pamataan",
+       "tog-watchrollback": "Tambaon alaman na unjung ubaen mulak tu bagasan daftar pamataanku",
+       "tog-minordefault": "Partando sude editan manjadi editan namenek sacara baku",
+       "tog-previewontop": "Patidaon pratayang dompakso kotak edit dot inda sidungi",
+       "tog-previewonfirst": "Patidaon pratayang i suntingan parjolo",
+       "tog-enotifwatchlistpages": "Kirimkon tuau surel molo sada alaman sanga berkas na u pamatai maruba",
+       "tog-enotifusertalkpages": "Kirimkon jau surel molo alaman parkobaranku maruba",
+       "tog-enotifminoredits": "Kirimkon jau surel juo i parubaan namenek",
+       "tog-enotifrevealaddr": "Tampilkon alamat surelku i surel notifikasi",
+       "tog-shownumberswatching": "Patidaon bahat ni namamatai",
+       "tog-oldsig": "Tekenanmu namadung adong:",
+       "tog-fancysig": "Baen tekenan manjadi teks wiki (indapake pranala otomatis)",
+       "tog-uselivepreview": "Tampilkon pratayang indapake mamuat mulak alaman",
+       "tog-forceeditsummary": "Paingot au molo kotak ringkasan editan nakosong dope",
+       "tog-watchlisthideown": "Bunion editanku i daftar pamataan",
+       "tog-watchlisthidebots": "Bunion editan bot idaftar pantauan",
+       "tog-watchlisthideminor": "Bunion editan namenek tingon pamataan",
+       "tog-watchlisthideliu": "Bunion suntingan masuk log tingon pamataan",
+       "tog-watchlistreloadautomatically": "Muat mulak daftar pamataan sacara otomatis atia sada tapis maruba (JavaScript iporluon)",
+       "tog-watchlistunwatchlinks": "Tambaon pananda pamatai/apus pamataan tu alaman na imatai na maruba (JavaScript iporluon tu manggonti fungsi on)",
+       "tog-watchlisthideanons": "Bunion editan pamake anonim i daftar pamataan",
+       "tog-watchlisthidepatrolled": "Bunion editan tarpatroli i daftar pantauan",
+       "tog-watchlisthidecategorization": "Bunion pangkatagorian alaman",
+       "tog-ccmeonemails": "Kirimkon jau salinan surel nau kirimkon tu alak nalain",
+       "tog-diffonly": "Ulang patidaon isi alaman i toru parbedaan editan",
+       "tog-showhiddencats": "Patidaon kategori namonjap",
+       "tog-norollbackdiff": "Nangkon patidaon parbedaan sidung mambaen paulakan",
+       "tog-useeditwarning": "Ingotkon au molo maninggalkon alaman pangeditan dompak so manyimpan parubaan",
+       "tog-prefershttps": "Totop pake sambungan aman atia masuk log",
+       "underline-always": "Totop",
+       "underline-never": "Inda unjung",
+       "underline-default": "Ulit sanga pangaraun naiobanna",
+       "editfont-style": "Gaya tulisan komputer i kotak pangeditan:",
+       "editfont-monospace": "Tulisan Monospace",
+       "editfont-sansserif": "Tulisan Sans-serif",
+       "editfont-serif": "Tulisan Serif",
+       "sunday": "Akad",
+       "monday": "Sinayan",
+       "tuesday": "Salasa",
+       "wednesday": "Rabu",
+       "thursday": "Kamis",
+       "friday": "Jumahat",
+       "saturday": "Sabtu",
+       "sun": "Aka",
+       "mon": "Sin",
+       "tue": "Sal",
+       "wed": "Rab",
+       "thu": "Kam",
+       "fri": "Jum",
+       "sat": "Sab",
+       "january": "Januari",
+       "february": "Februari",
+       "march": "Maret",
+       "april": "April",
+       "may_long": "Mei",
+       "june": "Juni",
+       "july": "Juli",
+       "august": "Agustus",
+       "september": "September",
+       "october": "Oktober",
+       "november": "November",
+       "december": "Desember",
+       "january-gen": "Januari",
+       "february-gen": "Februari",
+       "march-gen": "Maret",
+       "april-gen": "April",
+       "may-gen": "Mei",
+       "june-gen": "Juni",
+       "july-gen": "Juli",
+       "august-gen": "Agustus",
+       "september-gen": "September",
+       "october-gen": "Oktober",
+       "november-gen": "November",
+       "december-gen": "Desember",
+       "jan": "Jan",
+       "feb": "Feb",
+       "mar": "Mar",
+       "apr": "Apr",
+       "may": "Mei",
+       "jun": "Jun",
+       "jul": "Jul",
+       "aug": "Agu",
+       "sep": "Sep",
+       "oct": "Okt",
+       "nov": "Nov",
+       "dec": "Des",
+       "january-date": "$1 Januari",
+       "february-date": "$1 Februari",
+       "march-date": "$1 Maret",
+       "april-date": "$1 April",
+       "may-date": "$1 Mei",
+       "june-date": "$1 Juni",
+       "july-date": "$1 Juli",
+       "august-date": "$1 Agustus",
+       "september-date": "$1 September",
+       "october-date": "$1 Oktober",
+       "november-date": "$1 November",
+       "december-date": "$1 Desember",
+       "period-am": "AM",
+       "period-pm": "PM",
+       "pagecategories": "{{PLURAL:$1|Category|Kategori}}",
+       "category_header": "Alaman i kategori \"$1\"",
+       "subcategories": "Subkategori",
+       "category-media-header": "Media i kategori \"$1\"",
+       "category-empty": "<em>Kategori on sonnari indadong alaman dot media.</em>",
+       "hidden-categories": "{{PLURAL:$1|Hidden category|Kategori monjap}}",
+       "hidden-category-category": "Kategori namonjap",
+       "category-subcat-count": "{{PLURAL:$2|Kategori on umna puna subkategori ima.|Kategori on puna ima {{PLURAL:$1|subkategori|$1 subkategori}}, tingon bahat $2.}}",
+       "category-subcat-count-limited": "Kategori on puna {{PLURAL:$1|$1 subkategori}} on.",
+       "category-article-count": "{{PLURAL:$2|Kategori on umna marisi alaman ima.|Onma{{PLURAL:$1|alaman ima|$1 alaman}} i kategori on, tingon bahat $2.}}",
+       "category-article-count-limited": "Kategori on puna {{PLURAL:$1|$1 alaman}} onma.",
+       "category-file-count": "{{PLURAL:$2|Kategori on umna marisi alaman ima.|Onma{{PLURAL:$1|alaman ima|$1 alaman}} i kategori on, tingon bahat $2.}}",
+       "listingcontinuesabbrev": "Sat",
+       "index-category": "Alaman na iindeks",
+       "noindex-category": "Alaman naso tarindeks",
+       "broken-file-category": "Alaman dot link berkas sega",
+       "about": "Satontang",
+       "article": "Isi nialaman",
+       "newwindow": "(bukak i tingkap nabaru)",
+       "cancel": "Antai",
+       "moredotdotdot": "Lainna...",
+       "morenotlisted": "Daftar on mungkin inda singkop",
+       "mypage": "Alaman",
+       "mytalk": "Obar",
+       "anontalk": "Obar",
+       "navigation": "Navigasi",
+       "and": "&#32;dot",
+       "faq": "FAQ",
+       "namespaces": "Ruang gorar",
+       "variants": "Mocoman",
+       "navigation-heading": "Menu Navigasi",
+       "errorpagetitle": "Sega",
+       "returnto": "Keimulak tu $1",
+       "tagline": "Tingon {{SITENAME}}",
+       "help": "Tolong",
+       "search": "Jalaki",
+       "search-ignored-headings": "# <pre>\n# Judul na angkan ipatopi ni panjalakan.\n# Editan on nangkan iterapkon sidung alaman dohot judul on iindeks.\n# Amu bisa mamaksaon pangindekskan mulak alaman on dohot mambaen editan kosong (''null edit'')\n# Sintaksisna ima songon onma:\n#   * Sudena tingon karakter \"#\" tu ujung baris ima sada komentar.\n#   * Satiop baris naso-kosong ima judul pas na angkan ipatopi\nReferensi\nPranala luar\nLigin muse\n #</pre>",
+       "searchbutton": "Jalaki",
+       "go": "Kehe",
+       "searcharticle": "Kehe",
+       "history": "Sejarah alaman",
+       "history_short": "Sejarah",
+       "history_small": "sejarah",
+       "updatedmarker": "Iuba sian parabisan uligi",
+       "printableversion": "Versi cetak",
+       "permalink": "Tautan permanen",
+       "print": "Cetak",
+       "view": "Sise",
+       "view-foreign": "Sise i $1",
+       "edit": "Pature",
+       "edit-local": "Baen deskeipsi lokal",
+       "create": "Baen",
+       "create-local": "Baen deskripsi lokal",
+       "delete": "Apus",
+       "newpage": "Alaman baru",
+       "talkpagelinktext": "obar",
+       "personaltools": "Alat pribadi",
+       "talk": "Marpokat",
+       "views": "Sise",
+       "toolbox": "Parkuas",
+       "otherlanguages": "I saro nalain",
+       "redirectedfrom": "(Ialihkon tingon $1)",
+       "redirectpagesub": "Alihkon alaman",
+       "redirectto": "Alihkon tu:",
+       "lastmodifiedat": "Alamanon parabisan ipature i $1, i $2.",
+       "jumpto": "Lumpat tu:",
+       "jumptonavigation": "navigasi",
+       "jumptosearch": "jalaki",
+       "aboutsite": "Satontang {{SITENAME}}",
+       "aboutpage": "Project:Satontang",
+       "copyright": "Konten tarsadio itoru $1 lainkon adong parnyataan nalain.",
+       "copyrightpage": "{{ns:project}}:Hak cipta",
+       "currentevents": "Namasa sonnari",
+       "currentevents-url": "Project:Kajadian nabaru",
+       "disclaimers": "Panulakan",
+       "disclaimerpage": "Project:Panulakan umum",
+       "edithelp": "Bantuan pangeditan",
+       "mainpage": "Alaman Utamo",
+       "mainpage-description": "Alaman utamo",
+       "portal": "Portal komunitas",
+       "portal-url": "Project:Portal komunitas",
+       "privacy": "Kabijakan privasi",
+       "privacypage": "Project:Kabijakan privasi",
+       "retrievedfrom": "Dapot tingon \"$1\"",
+       "youhavenewmessages": "{{PLURAL:$3|Amu puna}} $1 ($2).",
+       "youhavenewmessagesfromusers": "{{PLURAL:$4|Amu puna}} $1 tingon {{PLURAL:$3|another user|$3 pamake}} ($2).",
+       "newmessageslinkplural": "{{PLURAL:$1|a new message|999=tona na baru}}",
+       "newmessagesdifflinkplural": "Parpudi {{PLURAL:$1|change|999=parubaan}}",
+       "editsection": "Pature",
+       "editold": "Pature",
+       "viewsourceold": "Sise sumber",
+       "editlink": "Pature",
+       "viewsourcelink": "Sise sumber",
+       "editsectionhint": "Pature bagian:$1",
+       "toc": "Isi",
+       "site-atom-feed": "$1 Umpan atom",
+       "page-atom-feed": "\"$1\" Umpan atom",
+       "red-link-title": "$1 (alaman inda adong)",
+       "nstab-main": "Alaman",
+       "nstab-user": "Alaman pamake",
+       "nstab-special": "Alaman istimewa",
+       "nstab-project": "Alaman proyek",
+       "nstab-image": "Berkas",
+       "nstab-mediawiki": "Tona",
+       "nstab-template": "Templat",
+       "nstab-category": "Kategori",
+       "mainpage-nstab": "Alaman utamo",
+       "nosuchspecialpage": "Inda adong alaman husus songon i",
+       "nospecialpagetext": "<strong>Amu madung mangido alaman husus naso valid.</strong>\n\nDaftar alaman husus bisa iligi i[[Special:SpecialPages|{{int:specialpages}}]].",
+       "badtitle": "Judul na jat",
+       "badtitletext": "Judul alaman na naipaido inda valid, kosong, sanga judul antar-saro sanga antar-wiki na sala ikaitkon. On mungkin marisi sada sanga lobi karakter na inda bisa ipake i judul.",
+       "viewsource": "Sise sumber",
+       "viewsource-title": "Sise sumber ni $1",
+       "viewsourcetext": "Amu bisa manyise dot mangkopi sumber ni alaman on",
+       "userlogin-yourname": "Gorar pamake",
+       "userlogin-yourname-ph": "Pamusuk gorar pamakemu",
+       "userlogin-yourpassword": "Hata kunci",
+       "userlogin-yourpassword-ph": "Pamasuk hata kunci",
+       "createacct-yourpassword-ph": "Pamasuk hata kunci",
+       "createacct-yourpasswordagain": "Konfirmasi hata kunci",
+       "createacct-yourpasswordagain-ph": "Pamasuk hata kunci mulak",
+       "userlogin-remembermypassword": "Jago totop masuk log",
+       "login": "Masuk log",
+       "userlogin-noaccount": "Ulang adong akun",
+       "userlogin-joinproject": "Martop {{SITENAME}}",
+       "createaccount": "Baen akun",
+       "userlogin-resetpassword-link": "Lupa hata kuncimu?",
+       "userlogin-helplink2": "Tolong dot masuk log",
+       "createacct-emailoptional": "Alamat email (opsional)",
+       "createacct-email-ph": "Pamasuk alamat emailmu",
+       "createacct-submit": "Baen akunmu",
+       "createacct-benefit-heading": "{{SITENAME}} ibaen ni alak songon kamuon.",
+       "createacct-benefit-body1": "{{PLURAL:$1|edit|pature}}",
+       "createacct-benefit-body2": "{{PLURAL:$1|page|alaman}}",
+       "createacct-benefit-body3": "{{PLURAL:$1|contributor|kontributor}} baru",
+       "loginlanguagelabel": "Saro: $1",
+       "pt-login": "Masuk log",
+       "pt-login-button": "Masuk log",
+       "pt-createaccount": "Baen akun",
+       "pt-userlogout": "Kaluar log",
+       "botpasswords-label-needsreset": "(sandi porlu isitel mulak)",
+       "botpasswords-needs-reset": "Hata sandi bot tu gorar bot \"$2\" ni {{GENDER:$1|user}} \"$1\" angkon na isitel mulak.",
+       "passwordreset": "Gonti hata kunci",
+       "bold_sample": "Teks naapal",
+       "bold_tip": "Teks naapal",
+       "italic_sample": "Teks Italic",
+       "italic_tip": "Teks italic",
+       "link_sample": "Judul tautan",
+       "link_tip": "Pranala",
+       "extlink_sample": "http://www.example.com judul tautan",
+       "extlink_tip": "Tautan ruar (ingot http://prefix)",
+       "headline_sample": "Teks judul",
+       "headline_tip": "Judul tingkat 2",
+       "nowiki_sample": "Pamasuk teks naso iformat tuson",
+       "nowiki_tip": "Nangkon roaon pamformatan wiki",
+       "image_tip": "Berkas naisematkon",
+       "media_tip": "Tautan berkas",
+       "sig_tip": "Tekenanmu dot tando woktu",
+       "hr_tip": "Garis horizontal (pake dohot denggan)",
+       "summary": "Ringkasan:",
+       "minoredit": "On suntingan namenek",
+       "watchthis": "Pamatai alamanon",
+       "savearticle": "Simpan alaman",
+       "preview": "Cimak",
+       "showpreview": "Patidaon pratayang",
+       "showdiff": "Patidaon parubaan",
+       "anoneditwarning": "<strong> Paringatan: </ strong> Amu indape masuk. Alamat IP Muyu nangkan tarida sacara publik molo Amu mambaen pangeditan. Molo Amu <strong> [$1 masuk] </ strong> sanga<strong> [$2 mambaen akun] </ strong>, hasil pangeditan Muyu nangkan ikaitkon dohot gorar pamake Muyu, rap dohot manfaat lainna.",
+       "blockedtext": "<strong>Alamat IP muyu madung iblokir sacara otomatis arani ipake ni pamake nalain,.</strong>\n\nNa iblokir ni $1.\nPamvlokiran ibaen arani <em>$2</em>.\n\n* Iblokir sian: $8\n* Blokir kadaluarsa i: $6\n* Sasarab pamblokiran: $7\n\nAmu bisa mayapai $1 sanga [[{{MediaWiki:Grouppage-sysop}}|administrator]] lainna tuna mamokatkon hal on.\n\nAmu inda bisa mamake fitur \"{{int:emailuser}}\" kacuali amu madung mamasukkon alamat surel na sah i [[Special:Preferences|preferensi akun]] dot amu inda iblokir mamakena.\n\nAlama IP muyu saonnari ima $3, dot ID pamblokiran ima #$5.\nTolong baen informasi-informasi in i satiop parsapaan muyu.",
+       "autoblockedtext": "Alamat IP mu nangkan otomatis iblokir arani ipake pamake nalain, na madung iblokir ni $1.\nAlasanna ima:\n\n:<em>$2</em>\n\n* Muloi i blokir: $8\n* Kadaluarsa blokir: $6\n* Blokir na ituju: $7\n\nSapai amuma $1 sanga sada tingon nalainnai [[{{MediaWiki:Grouppage-sysop}}|administrators]] giot mamokatkon blokiran on.\n\nRoaon molo Amu inda tola mamake fitur \"{{int: emailuser}}\" kacuali Amu puna alamat surel valid na tardaftar i [[Special:Preferences|preferensi pamake]] dot Amu indape iblokir mamakena.\n\nAlamat IP mu sonnari ima $3, dot blokir ID ima #$5.\nIaropkon baen sude rincian na iginjang singkop molo mambaen parsaapaan na ibaen muyu.",
+       "loginreqlink": "Masuk log",
+       "newarticletext": "Amu madung paiut tautan tu alaman na so adong dope. Giot mambaen alaman, muloima mangetik i kotak i toru on (ligin [$1 alaman bantuan] giot info lobi lanjut). Molo Amu adong i son arani kasalahan, klik tombol <strong> mulam </ strong> i browser Muyu.",
+       "anontalkpagetext": "---- \n\n<em> on ima alaman marpokat tu pangguna anonim naso mambaen akun dope, sanga na inda mamakena. </em> Arani i ami angkon mamake alamat IP numerik tu mangidentifikasi ia. Songon alamat IP bisa ibagi ni bahat pengguna. Molo Amu ima pangguna anonim dot marasa molo komentar na inda relevan madung iarahkon tu Amu, kehemamu [[Special:CreateAccount|baen akun]] sanga [[Special:UserLogin|masuk log]] tu mangilakkon gamang i tu jolo niari dohot pengguna anonim laina.",
+       "noarticletext": "Saonnari inda adong teks i alaman on. Amu bisa [[Special:Search/{{PAGENAME}}|manjalai judul alaman on]] i alaman lain, <span class = \"plainlinks\"> [{{fullurl: {{# Special: Log}} | page = { {FULLPAGENAMEE}}}} telusuri log terkait], atau [{{fullurl: {{FULLPAGENAME}} | action = edit}} baen alaman on] </ span>.",
+       "noarticletext-nopermission": "Saonnari inda adong teks i alaman on. Amu bisa [[Special:Search/{{PAGENAME}}|manjalai judul alaman on]] i alaman lain, sanga <span class = \"plainlinks\"> [{{fullurl:{{#Special:Log}}|alaman={{FULLPAGENAMEE}}}} jalai log tarkait] </ span>, tai Amu inda puna izin giot mambaen alaman on.",
+       "userpage-userdoesnotexist-view": "Akun pangguna ''$1'' inda tardaftar",
+       "clearyourcache": "<strong> Catatan: </strong> Sidung manyimpan, Amu mungkin angkon malewati cache browser Muyu anso mangida parubaanna. \n* <strong> Firefox/Safari:</strong> Tahan <em> Shift </em> atia mangklik <em> Reload </em>, sanga pisat <em> Ctrl-F5 </em> sanga <em> Ctrl-R </em> (<em> ⌘-R </ em> pada Mac) \n* <strong> Google Chrome: </strong> Pisat <em> Ctrl-Shift-R </em> (<em> ⌘ -Shift-R </em> i Mac) \n* <strong> Internet Explorer: </strong> Tahan <em> Ctrl </em> atia mangklik <em> Segarkon </em>, sanga pisat <em> Ctrl-F5 </em> \n* <strong> Opera: </ strong> Kei tu <em> Menu → Pangaturan </em> (<em> Opera → Preferensi </ em> i Mac) dot sidungi ke <em> Privasi & kaamanan → Apus data panjalajahan → Tembolok gambar dot file </em>.",
+       "previewnote": "<strong> Ingot molo on umna pratinjau. </strong> Parubaan Muyu indape isimpan!",
+       "continue-editing": "Kei tu ganan pangeditan",
+       "editing": "Mangedit $1",
+       "creating": "Baen $1",
+       "editingsection": "Patureon $1 (bagian)",
+       "templatesused": "{{PLURAL:$1|Template|Templat}} baen tu alaman on:",
+       "templatesusedpreview": "{{PLURAL:$1|Template|Templat}} ipake i pratinjau on:",
+       "template-protected": "Larangan",
+       "template-semiprotected": "(satonga-larangan)",
+       "hiddencategories": "Alaman on ima anggota {{PLURAL:$1|1 kategori namonjap|$1 kategori namonjap}}:",
+       "permissionserrors": "Santabi sega",
+       "permissionserrorstext-withaction": "Amu inda iizinkon $2, tu naonan {{PLURAL:$1|reason|alasan}}:",
+       "recreate-moveddeleted-warn": "<strong> Paringotan: Amu mambaen mulak laman na unjung ihapus. </strong> Amu angkon mapartimbangkon sanga sasue giot malanjutkon mangedit alaman on. Log pangapusan dot pamindahan tu alaman on isadioon i son so tagi:",
+       "moveddeleted-notice": "Alaman on nangkan iapus. \nCatatan pangapusan, palarangan, dot pamindahan tu alaman ilehen i toru on manjadi referensi.",
+       "content-model-wikitext": "Tekswiki",
+       "undo-failure": "Pangeditan inda bisa iantai arani pangeditan dompak na konflik.",
+       "viewpagelogs": "Sise log ni alaman on",
+       "currentrev-asof": "Parubaan parpudi ima $1",
+       "revisionasof": "Revisi par $1",
+       "revision-info": "Revisi par $1 by {{GENDER:$6|$2}}$7",
+       "previousrevision": "← Revisi na lobi onok",
+       "nextrevision": "Revisi tarbaru →",
+       "currentrevisionlink": "Revisi parpudi",
+       "cur": "Sonnari",
+       "last": "Cimak",
+       "histlegend": "Seleksi Diff: Tandai kotak radio tingon revisi giot mambandingkon dot pisat enter sanga tombol naitoru.<br />\nLegend: <strong>({{int:cur}})</strong> = parbedaan dohot revisi tarbaru, <strong>({{int:last}})</strong> = parbedaan dohot revisi naparjolo, <strong>{{int:minoreditletter}}</strong> = pengeditan menek.",
+       "history-fieldset-title": "Jalai revisi",
+       "histfirst": "Naonok",
+       "histlast": "Nabaru",
+       "history-feed-title": "Sejarah revisi",
+       "history-feed-description": "Sejarah revisi tu alaman i wiki",
+       "history-feed-item-nocomment": "$1 i $2",
+       "rev-delundel": "Uba visibilitas",
+       "mergelog": "Pasada log",
+       "history-title": "Sejarah Revisi ni \"$1\"",
+       "difference-title": "Parbedaan antara revisi \"$1\"",
+       "lineno": "Baris $1:",
+       "compareselectedversions": "Bandingkon dot revisi tarpili",
+       "editundo": "Mambuka",
+       "diff-empty": "(Inda dong parbedaan)",
+       "diff-multi-sameuser": "({{PLURAL:$1|Sada revisi manonga|$1 revisi manonga}} ni pangguna na sarupo inda ipatidaon)",
+       "diff-multi-otherusers": "({{PLURAL:$1|Sada revisi sedang|$1 revisi sedang}} ibaen {{PLURAL:$2|sada pangguna lainna|$2 pangguna}} inda ipatidaon)",
+       "searchresults": "Jalaki sude hasil",
+       "searchresults-title": "Jalaki sude hasil tu \"$1\"",
+       "prevn": "Cimak {{PLURAL:$1|$1}}",
+       "nextn": "Satorusna {{PLURAL:$1|$1}}",
+       "prevn-title": "Cimak $1 {{PLURAL:$1|result|hasil}}",
+       "nextn-title": "Satorusna $1 {{PLURAL:$1|result|hasil}}",
+       "shown-title": "Patidaon $1 {{PLURAL:$1|result|hasil}} par alaman",
+       "viewprevnext": "Sise ($1 {{int:pipe-separator}} $2) ($3)",
+       "searchmenu-exists": "<strong>Adong gorar ni alaman \"[[:$1]]\" i wiki on.</strong> {{PLURAL:$2|0=|Ligin juo panjalakan napasuo.}}",
+       "searchmenu-new": "<strong> Baen alaman \"[[:$1]]\" i wiki on! </strong> {{PLURAL:$2|0=|Ligin juo alaman na dapot dohot panjalakan Muyu.|Ligin juo hasil panjalakan na dapot.}}",
+       "searchprofile-articles": "Isi nialaman",
+       "searchprofile-images": "Multimedia",
+       "searchprofile-everything": "Sanga aha",
+       "searchprofile-advanced": "Torus",
+       "searchprofile-articles-tooltip": "Jalaki i $1",
+       "searchprofile-images-tooltip": "Jalai berkas",
+       "searchprofile-everything-tooltip": "Jalai sude tontang (ibagasan alaman parpokatan)",
+       "searchprofile-advanced-tooltip": "Jalaki i ruang gorar kustom",
+       "search-result-size": "$1 ({{PLURAL:$2|1 word|$2 hata}})",
+       "search-result-category-size": "{{PLURAL:$1|1 member|$1 anggota}} ({{PLURAL:$2|1 subcategory|$2 subkategori}}, {{PLURAL:$3|1 file|$3 berkas}})",
+       "search-redirect": "(alihkon tingon $1)",
+       "search-section": "(bagian $1)",
+       "search-file-match": "(isi berkas na cocok)",
+       "search-suggest": "On do na imaksudmi:$1",
+       "searchall": "Sude",
+       "search-showingresults": "{{PLURAL:$4|Hasil<strong>$1</strong> tingon <strong>$3</strong>|Hasil <strong>$1 – $2</strong> tingon <strong>$3</strong>}}",
+       "search-nonefound": "Inda adong hasil na cocok dohot kueri.",
+       "mypreferences": "Preferensi",
+       "group-bot": "Bot",
+       "group-sysop": "Administrator",
+       "grouppage-bot": "{{ns:project}}:Bot",
+       "grouppage-sysop": "{{ns:project}}:Administrator",
+       "right-writeapi": "Pamakean ni API tulis",
+       "newuserlogpage": "Log pambaenan pamake",
+       "rightslog": "Log hak pangguna",
+       "action-edit": "Pature alaman on",
+       "action-createaccount": "baen akun pamake on",
+       "enhancedrc-history": "sejarah",
+       "recentchanges": "Parubaan tarbaru",
+       "recentchanges-legend": "Opsi parubaan tarbaru",
+       "recentchanges-summary": "Lacak parubaan tarbaru i wiki i alaman on.",
+       "recentchanges-noresult": "Inda adong parubaan saonok periode na ilehen sasuae dohot kriteria on.",
+       "recentchanges-feed-description": "Jalaki parubaan tarbaru i wiki i umpan on.",
+       "recentchanges-label-newpage": "Editan on mammbaen alaman baru",
+       "recentchanges-label-minor": "On edit na menek",
+       "recentchanges-label-bot": "Naipature ni bot",
+       "recentchanges-label-unpatrolled": "Suntingan on indape ipareso",
+       "recentchanges-label-plusminus": "Ukuran alamanon iuba dohot bahatni byte",
+       "recentchanges-legend-heading": "<strong>Tando:</strong>",
+       "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (ligin juo [[Special:NewPages|daftar alaman nabaru]])",
+       "rcnotefrom": "Itoru {{PLURAL:$5|is the change|ima parubaan}} saonok<strong>$3, $4</strong> (sampe tu <strong>$1</strong> patidaon).",
+       "rclistfrom": "Patidaon parubaan tarbaru imuloi tingon $2, $3",
+       "rcshowhideminor": "$1 pature namenek",
+       "rcshowhideminor-show": "Patidaon",
+       "rcshowhideminor-hide": "Bunion",
+       "rcshowhidebots": "$1 bot",
+       "rcshowhidebots-show": "Patidaon",
+       "rcshowhidebots-hide": "Bunion",
+       "rcshowhideliu": "$1 pamake tardaftar",
+       "rcshowhideliu-show": "Patidaon",
+       "rcshowhideliu-hide": "Bunion",
+       "rcshowhideanons": "$1 pamake anonim",
+       "rcshowhideanons-show": "Patidaon",
+       "rcshowhideanons-hide": "Bunion",
+       "rcshowhidepatr": "$1 edit nai pareso",
+       "rcshowhidemine": "$1 naupature",
+       "rcshowhidemine-show": "Patidaon",
+       "rcshowhidemine-hide": "Bunion",
+       "rclinks": "Patidaon sude $1 parubaan $2 ari",
+       "diff": "beda",
+       "hist": "versi",
+       "hide": "Bunion",
+       "show": "Alaman pamake",
+       "minoreditletter": "m",
+       "newpageletter": "B",
+       "boteditletter": "b",
+       "rc-change-size-new": "$1 {{PLURAL:$1|byte|bytes}} sidung iuba",
+       "rc-old-title": "Aslina ibaen i ''$1''",
+       "recentchangeslinked": "Parubaan tarkait",
+       "recentchangeslinked-feed": "Parubaan tarkait",
+       "recentchangeslinked-toolbox": "Parubaan tarkait",
+       "recentchangeslinked-title": "Parubaan tarkait tu \"$1\"",
+       "recentchangeslinked-summary": "Pamasuk gorar alaman giot maligi parubaaan i alaman na tarsambung tu sanga tingon alaman i. (Giot mangaligi anggota kategori, pamasuk {{ns: category}}: Gorar kategori). Parubaan i alaman [[Special:Watchlist|Daftar Naipamatai mu]] adong i <strong> bold </ strong>.",
+       "recentchangeslinked-page": "Gorar alaman:",
+       "recentchangeslinked-to": "Patidaon parubaaan tu alaman na itautkon tu alaman na baen",
+       "upload": "Unggah berkas",
+       "uploadlogpage": "Unggah log",
+       "filedesc": "Ringkasan",
+       "license": "Ilisensi",
+       "license-header": "Lisensi",
+       "imgfile": "Berkas",
+       "listfiles": "Daftar berkas",
+       "file-anchor-link": "Berkas",
+       "filehist": "Sejarah berkas",
+       "filehist-help": "Klik tanggal / woktu giot maligi file songon na na i woktu i.",
+       "filehist-revert": "Mulak",
+       "filehist-current": "Saonnari",
+       "filehist-datetime": "Tangagal/Woktu",
+       "filehist-thumb": "Gambar",
+       "filehist-thumbtext": "Gambar tu versi par $1",
+       "filehist-nothumb": "Inda adong gambar",
+       "filehist-user": "Pamake",
+       "filehist-dimensions": "Ukuran",
+       "filehist-comment": "Komentar",
+       "imagelinks": "Berkas ipake",
+       "linkstoimage": "Onma {{PLURAL:$1|page links|$1 tautan alaman}} tu berkas on:",
+       "linkstoimage-more": "Lobi tingon $1 {{PLURAL:$1|page links|tautan alaman}} tu berkas on. Daftar naonan patidaon {{PLURAL:$1|first page link|tautan alaman parjolo $1}} tu berkas on sajo. A [[Special:WhatLinksHere/$2|daftar singkop]] tarsadio.",
+       "nolinkstoimage": "Inda adong alaman na martaut tu berkason",
+       "linkstoimage-redirect": "$1 (pangalihan berkas) $2",
+       "sharedupload-desc-here": "File on tingon $1 dot bisa ipake ni proyek lain. Deskripsi i [alaman deskripsi file $2] i sadun ipatidaon naitoruon.",
+       "filepage-nofile": "Inda adong berkas dohot gorar on.",
+       "upload-disallowed-here": "Amu inda bisa manimpo berkas on.",
+       "randompage": "Gaor alaman",
+       "statistics": "Statistik",
+       "double-redirect-fixer": "Papas Pangalihan",
+       "nbytes": "$1 {{PLURAL:$1|byte|bytes}}",
+       "nmembers": "$1 {{PLURAL:$1|member|anggota}}",
+       "prefixindex": "Sude alaman na prefix",
+       "listusers": "Daptar pamake",
+       "newpages": "Alaman baru",
+       "move": "Pindah",
+       "pager-newer-n": "{{PLURAL:$1|newer 1|nabaru $1}}",
+       "pager-older-n": "{{PLURAL:$1|older 1|parpudi $1}}",
+       "booksources": "Sumber buku",
+       "booksources-search-legend": "Jalai tu sumber buku",
+       "booksources-search": "Jalai",
+       "specialloguserlabel": "Panampil:",
+       "speciallogtitlelabel": "Target (judul sanga {{ns:user}}:gorar pangguna tu pangguna):",
+       "log": "Masuk",
+       "all-logs-page": "Sude log",
+       "alllogstext": "Tampilan gabungan tingon sude log na tarsadio tingon {{SITENAME}}. Amu bisa mamparsompit tampilan dohot mamili jenis log, gorar pangguna (sensitif huruf), sanga alaman na tarpangaruh (juo kasus-sensitive).",
+       "logempty": "Inda adong item nacocok i log",
+       "allpages": "Sude alaman",
+       "allarticles": "Sude alaman",
+       "allpagessubmit": "Kehe",
+       "allpages-hide-redirects": "Bunion pangalihan",
+       "categories": "Kategori",
+       "listgrouprights-members": "(daftar anggota)",
+       "emailuser": "Email ni pamake on",
+       "usermessage-editor": "Tona ni sistem",
+       "watchlist": "Daftar Pamataan",
+       "mywatchlist": "Daftar pamataan",
+       "watchlistfor2": "Tu $1 $2",
+       "watch": "Pamatai",
+       "unwatch": "Inda ipamatai",
+       "watchlist-details": "{{PLURAL:$1|$1 page is|$1 alaman}} i pamataanmu (dot alaman parkobaran).",
+       "wlheader-showupdated": "Laman na madung iubah sian parpudi Amu ligi, ipatidaon i huruf <strong> naapal </strong>.",
+       "wlnote": "Itoruon {{PLURAL:$1|is the last change|ima parpudi<strong>$1</strong> parubaan}} i {{PLURAL:$2|hour|<strong>$2</strong> jom}}, i $3, $4.",
+       "wlshowlast": "Patidaon parpudi $1 jom $2 ari",
+       "watchlist-options": "Opsi pamataan",
+       "enotif_reset": "Tandai sude alaman namadung iligi",
+       "dellogpage": "Apus log",
+       "rollbacklink": "balikkon",
+       "rollbacklinkcount": "Paulak $1 {{PLURAL:$1|edit|edits}}",
+       "protectlogpage": "Log nai jago",
+       "protectedarticle": "larangan \"[[$1]]\"",
+       "modifiedarticleprotection": "Gonti tingkat larangan tu ''[[$1]]''",
+       "protect-default": "Patola sude pangguna",
+       "restriction-edit": "Pature",
+       "restriction-move": "Pindah",
+       "namespace": "Ruanggorar:",
+       "invert": "Pilian sabalikna",
+       "tooltip-invert": "Centang kotak on giot mambunion parubaan tu alaman i ruang gorar na ipili (dot ruang gorar tarkait molo icentang)",
+       "namespace_association": "Kumpulan ruang gorar",
+       "tooltip-namespace_association": "Centang kotak on giot mambunion ruang gorar pangecean sanga subjek na tarkait dohot ruang gorar na ipili",
+       "blanknamespace": "(Utamo)",
+       "contributions": "{{GENDER:$1|User}} kontribusi",
+       "contributions-title": "Kontribusi pangguna tu $1",
+       "mycontris": "Kontribusi",
+       "anoncontribs": "Kontribusingku",
+       "contribsub2": "Tu {{GENDER:$3|$1}} ($2)",
+       "nocontribs": "Inda adong parubaan na sasue dohot kriteria on.",
+       "uctop": "(sonnari)",
+       "month": "Tingon bulan (dot nasolpu)",
+       "year": "Tingon taon (dot nasolpu)",
+       "sp-contributions-newbies": "Patidaon kontribusi ni akun nabaru sajope",
+       "sp-contributions-blocklog": "Log blokir",
+       "sp-contributions-uploads": "Unggah",
+       "sp-contributions-logs": "Log",
+       "sp-contributions-talk": "obar",
+       "sp-contributions-search": "Jalaki kontribusi",
+       "sp-contributions-username": "Alama IP Pangguna",
+       "sp-contributions-toponly": "Umna patidaon editan revisi parpudi",
+       "sp-contributions-newonly": "Umna patidaon alaman naibuat",
+       "sp-contributions-submit": "Jalaki",
+       "whatlinkshere": "Tautan aha ison",
+       "whatlinkshere-title": "Alaman puna tautan tu \"$1\"",
+       "whatlinkshere-page": "Alaman:",
+       "linkshere": "Onma alaman namartaut tu <strong>$2</strong>:",
+       "nolinkshere": "Inda adong alaman na martaut tu <strong>$2</strong>.",
+       "isredirect": "Alaman pangalihan",
+       "istemplate": "transklusi",
+       "isimage": "Tautan berkas",
+       "whatlinkshere-prev": "{{PLURAL:$1|previous|parjolo $1}}",
+       "whatlinkshere-next": "{{PLURAL:$1|next|satorusna $1}}",
+       "whatlinkshere-links": "← tautan",
+       "whatlinkshere-hideredirs": "$1 ialihkon",
+       "whatlinkshere-hidetrans": "$1 transklusi",
+       "whatlinkshere-hidelinks": "$1 tautan",
+       "whatlinkshere-hideimages": "$1 tautan berkas",
+       "whatlinkshere-filters": "Saringan",
+       "ipboptions": "2 jom:2 hours,1 ari:1 day,3 ari:3 days,1 poken:1 week,2 poken:2 weeks,1 bulan:1 month,3 bulan:3 months,6 bulan:6 months,1 taon:1 year,onok:infinite",
+       "infiniteblock": "Inda tarbatas",
+       "blocklink": "blokir",
+       "contribslink": "Kontributor",
+       "blocklogpage": "Blokir log",
+       "blocklogentry": "blokir [[$1]] dot woktu kadaluarsa $2 $3",
+       "reblock-logentry": "Gonti sitelan blokir tu [[$1]] dot maso kadaluarsa tu $2 $3",
+       "block-log-flags-nocreate": "Pambaenan akun inonaktipkon",
+       "proxyblocker": "Blokir proxi",
+       "movelogpage": "Pindah log",
+       "export": "Expor alaman",
+       "thumbnail-more": "Pagodang",
+       "importlogpage": "Log impor",
+       "tooltip-pt-userpage": "{{GENDER:|Your user}} alaman",
+       "tooltip-pt-mytalk": "{{GENDER:|Your}} alaman parkobaran",
+       "tooltip-pt-preferences": "{{GENDER:|Your}} preferensi",
+       "tooltip-pt-watchlist": "Daftar nialaman na parubaanna ipamataimu",
+       "tooltip-pt-mycontris": "Daftar {{GENDER:|your}} kontribusi",
+       "tooltip-pt-login": "Amu iaropkon masuk, tai inda wajib",
+       "tooltip-pt-logout": "Kaluar log",
+       "tooltip-pt-createaccount": "Amu iaropkon mambaen akun dot masuk; taiba, i inda wajib",
+       "tooltip-ca-talk": "Pokat satontang isi ni alaman",
+       "tooltip-ca-edit": "Pature alamanon",
+       "tooltip-ca-addsection": "Baen bagian nabaru",
+       "tooltip-ca-viewsource": "Alaman on ilarang.\nAmu bisa manyise sumber",
+       "tooltip-ca-history": "Revisi parpudi ni alaman on",
+       "tooltip-ca-protect": "Jago alamanon",
+       "tooltip-ca-delete": "Apus alaman on",
+       "tooltip-ca-move": "Papindah alamanon",
+       "tooltip-ca-watch": "Baen alamanon tu pamataanmu",
+       "tooltip-ca-unwatch": "Apus alaman on tingon pamataanmu",
+       "tooltip-search": "Jalaki {{SITENAME}}",
+       "tooltip-search-go": "Kehe tu alaman dohot gorar naonan molo adong.",
+       "tooltip-search-fulltext": "Jalaki alaman tu teks on",
+       "tooltip-p-logo": "Ligin alaman utamo",
+       "tooltip-n-mainpage": "Kehe tu alaman utamo",
+       "tooltip-n-mainpage-description": "Kei tu alaman utamo",
+       "tooltip-n-portal": "Satontang proyek, aha ma bisa ibaen kamu, anso dapot",
+       "tooltip-n-currentevents": "Jalai latar bolakang satontang kajadian tarbaru",
+       "tooltip-n-recentchanges": "Daftar parubaan tarbaru i Wikion",
+       "tooltip-n-randompage": "Muat alaman sumbarang",
+       "tooltip-n-help": "Inganan anso binoto",
+       "tooltip-t-whatlinkshere": "Daftar alaman wiki na martaut tuson",
+       "tooltip-t-recentchangeslinked": "Parubaan tarbaru i sude alaman namartautan tu alaman on",
+       "tooltip-feed-atom": "Umpan atom ni alamaon",
+       "tooltip-t-contributions": "Daftar kontribusi ni {{GENDER:$1|pamake on}}",
+       "tooltip-t-emailuser": "Kirim email tu {{GENDER:$1|pamake on}}",
+       "tooltip-t-upload": "Unggah berkas-berkas",
+       "tooltip-t-specialpages": "Daftar ni sude alaman spesial",
+       "tooltip-t-print": "Versi cetak ni alamanon",
+       "tooltip-t-permalink": "Tautan permanen tu revisi ni alamanon",
+       "tooltip-ca-nstab-main": "Sise isi ni alaman",
+       "tooltip-ca-nstab-user": "Sise alaman pamake",
+       "tooltip-ca-nstab-special": "On alaman husus, dot on inda bisa ipature",
+       "tooltip-ca-nstab-project": "Sise alaman proyek",
+       "tooltip-ca-nstab-image": "Sise alaman berkas",
+       "tooltip-ca-nstab-mediawiki": "Sise sistem tona",
+       "tooltip-ca-nstab-template": "Sise templat",
+       "tooltip-ca-nstab-category": "Sise kategori ni alaman",
+       "tooltip-minoredit": "Tandai on pangeditan namenek",
+       "tooltip-save": "Simpan parubaanmu",
+       "tooltip-preview": "Pareso naiubamu. Pake jolo on dompak so isimpan",
+       "tooltip-diff": "Patidaon sanga dia teks naiubamu",
+       "tooltip-compareselectedversions": "Ligin parbedaan antara dua revisi naipili ni alaman on",
+       "tooltip-watch": "Baen alamanon tu pamataanmu",
+       "tooltip-rollback": "\"Balikkon\" paulak pangedit kontributor parpudi tu alaman on dohot sa klik",
+       "tooltip-undo": "\"Undo\" pamulak pangeditan on dot mambuka formulir edit i mode pratinjau. On mamungkinkon manambaon alasan i ringkasan.",
+       "tooltip-summary": "Baen ringkasan pondok",
+       "simpleantispam-label": "Pareso Anti-spam.\nBaen <strong>inda</strong> isi ison!",
+       "pageinfo-title": "Informasi tu ''$1''",
+       "pageinfo-header-basic": "Informasi dasor",
+       "pageinfo-header-edits": "Sejarah edit",
+       "pageinfo-header-restrictions": "Alaman larangan",
+       "pageinfo-header-properties": "Parkuas alaman",
+       "pageinfo-display-title": "Judul tampilan",
+       "pageinfo-default-sort": "Kunci panyortiran default",
+       "pageinfo-length": "Lanjang alaman (i byte)",
+       "pageinfo-article-id": "ID alaman",
+       "pageinfo-language": "Saro isi ni alaman",
+       "pageinfo-content-model": "Model konten alaman",
+       "pageinfo-robot-policy": "Pangindeksan ni robot",
+       "pageinfo-robot-index": "Iizinkon",
+       "pageinfo-robot-noindex": "Inda iizinkon",
+       "pageinfo-watchers": "Bahatni alaman naipamatai",
+       "pageinfo-few-watchers": "Urang tingon $1 {{PLURAL:$1|pamatai|napamatai}}",
+       "pageinfo-redirects-name": "Bahatni pangalihan tu alaman on",
+       "pageinfo-subpages-name": "Bahatni sub alaman ni alaman on",
+       "pageinfo-subpages-value": "$1 ($2 {{PLURAL:$2|redirect|pangalihan}}; $3 {{PLURAL:$3|non-redirect|inda pangalihan}})",
+       "pageinfo-firstuser": "Pambaen alaman",
+       "pageinfo-firsttime": "Tanggal ibaen alaman",
+       "pageinfo-lastuser": "Pangedit parpudi",
+       "pageinfo-lasttime": "Tanggal edit parpudi",
+       "pageinfo-edits": "Bahat ni edit",
+       "pageinfo-authors": "Bahatni sude panulis namarbeda",
+       "pageinfo-recent-edits": "Bahat pangeditan tarbaru (i $1 pardudi)",
+       "pageinfo-recent-authors": "Bahat ni panulis namarbeda i ari nalewat",
+       "pageinfo-magic-words": "Ajaib {{PLURAL:$1|word|hata}} ($1)",
+       "pageinfo-hidden-categories": "Bunion {{PLURAL:$1|category|Kategori}} ($1)",
+       "pageinfo-templates": "Transklusi {{PLURAL:$1|template|templat}} ($1)",
+       "pageinfo-toolboxlink": "Informasi alaman",
+       "pageinfo-contentpage": "Ietong manjadi sada alaman",
+       "pageinfo-contentpage-yes": "Olo",
+       "patrol-log-page": "Log patroli",
+       "previousdiff": "← editan nasolpu",
+       "nextdiff": "Edit tarbaru →",
+       "widthheightpage": "$1 × $2, $3 {{PLURAL:$3|page|alaman}}",
+       "file-info-size": "$1 × $2 piksel, ukuran berkas: $3, Type MIME: $4",
+       "file-info-size-pages": "$1 × $2 piksel, ukuran berkas: $3, tipe MIME : $4, $5 {{PLURAL:$5|page|alaman}}",
+       "file-nohires": "Indadongbe resolusi naum ginjang",
+       "svg-long-desc": "Berkas SVG, nominall $1 × $2 piksel, ukuran berkas: $3",
+       "show-big-image": "Berkas asli",
+       "show-big-image-preview": "Ukuran ni pratayang:$1",
+       "show-big-image-other": "Lainna {{PLURAL:$2|resolution|resolusi}}: $1.",
+       "show-big-image-size": "$1 × $2 piksel",
+       "metadata": "Metadata",
+       "metadata-help": "Berkas on marisi informasi tambahan, mungkin itambaon tingon kamera digital sanga pamindai na ipake tu mambaen sanga mandigitalkonna. Molo berkas madung imodifikasi tingon kaadaan aslina, sadebana detail mungkin inda sudena mancerminkon berkas na imodifikasi.",
+       "metadata-fields": "Bidang metadata gambar na tarcantum i tona on nangkan ibaenkon i tampilan alaman gambar atia tabel metadata iciutkon. \nNalain nangkan ibunion sacara default.\n* make\n* model\n* datetimeoriginal\n* exposuretime\n* fnumber\n* isospeedratings\n* focallength\n* artist\n* copyright\n* imagedescription\n* gpslatitude\n* gpslongitude\n* gpsaltitude",
+       "exif-orientation": "Orientasi",
+       "exif-xresolution": "Resolusi horizontal",
+       "exif-yresolution": "Resolusi vertikal",
+       "exif-datetime": "Parubaan tanggal dot woktu berkas",
+       "exif-make": "Pambaen kamera",
+       "exif-model": "Model kamera",
+       "exif-software": "Perangkat lunak nai pake",
+       "exif-exifversion": "Model Exif",
+       "exif-colorspace": "Ruang warna",
+       "exif-datetimeoriginal": "Tanggal dot waktu pambuatan data",
+       "exif-datetimedigitized": "Tanggal dot woktu idigitalisasi",
+       "exif-orientation-1": "Biaso",
+       "namespacesall": "Sude",
+       "monthsall": "Sude",
+       "imgmultipagenext": "alaman satorusna →",
+       "imgmultigo": "Kei!",
+       "imgmultigoto": "Kei tu alaman $1",
+       "watchlisttools-clear": "Paias pamataan",
+       "watchlisttools-view": "Sise parubaan na pas",
+       "watchlisttools-edit": "Sise dot pature pamataan",
+       "watchlisttools-raw": "Pature daptar pamataan",
+       "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|obarkon]])",
+       "redirect": "Pangalihan ni berkas, pamake, alaman, revisi, sanga log ID",
+       "redirect-summary": "Alaman husus on mangalihkon tu berkas (ilehen gorar berkas), alaman (ilehen ID revisi sanga ID alaman), alaman pangguna (ilehen ID pangguna numerik), sanga entri log (ilehen ID log). Pamakean:\n[[{{#Special:Redirect}}/file/Example.jpg]], [[{{#Special:Redirect}}/page/64308]], [[{{#Special:Redirect}}/revision/328429]], [[{{#Special:Redirect}}/user/101]], sanga [[{{#Special:Redirect}}/logid/186]].",
+       "redirect-submit": "Kei",
+       "redirect-lookup": "Ligima:",
+       "redirect-value": "Nilai:",
+       "redirect-user": "ID pangguna",
+       "redirect-page": "ID alaman",
+       "redirect-revision": "Revisi alaman",
+       "redirect-file": "Gorarberkas:",
+       "specialpages": "Alaman husus",
+       "tag-filter": "[[Special:Tags|Tag]] saring:",
+       "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|Tag|Tags}}]]:$2)",
+       "tags-active-yes": "Olo",
+       "tags-active-no": "Inda",
+       "tags-hitcount": "$1 {{PLURAL:$1|change|parubaan}}",
+       "logentry-delete-delete": "$1 {{GENDER:$2|iapus}} alaman $3",
+       "logentry-delete-restore": "$1 {{GENDER:$2|restored}} alaman $3 ($4)",
+       "logentry-delete-revision": "$1 {{GENDER:$2|iuba}} visibilitas {{PLURAL:$5|a revision|$5 revisi}} i alaman $3: $4",
+       "revdelete-content-hid": "Isi naibunion",
+       "logentry-move-move": "$1 {{GENDER:$2|pindah}} alam $3 to $4",
+       "logentry-move-move-noredirect": "$1 {{GENDER:$2|pindah}} alaman $3 tu $4 inda maninggalkon pangalihan",
+       "logentry-move-move_redir": "$1 {{GENDER:$2|papindah}} alaman $3 tu $4 pangalihan lobi",
+       "logentry-patrol-patrol-auto": "$1 otomatis {{GENDER:$2|itandai}} revisi $4 ni alaman $3 naipatroli",
+       "logentry-newusers-create": "Akun pamake $1 ima {{GENDER:$2|baen}}",
+       "logentry-newusers-autocreate": "Akun pangguna $1 madung {{GENDER:$2|ibaen}} otomatis",
+       "logentry-upload-upload": "$1 {{GENDER:$2|maiunggah}} $3",
+       "logentry-upload-overwrite": "$1 {{GENDER:$2|iunggah}} versi nabaru tingon $3",
+       "searchsuggest-search": "Jalaki {{SITENAME}}",
+       "duration-days": "$1 {{PLURAL:$1|day|ari}}",
+       "randomrootpage": "Gaor alaman urat"
+}
index fb10a20..38f6b80 100644 (file)
@@ -59,7 +59,8 @@
                        "Xð",
                        "Abella",
                        "Pierpao",
-                       "Amire80"
+                       "Amire80",
+                       "Leptictidium"
                ]
        },
        "tog-underline": "Subratlla els enllaços:",
@@ -96,7 +97,7 @@
        "tog-watchlisthideminor": "Amaga les edicions menors de la llista de seguiment",
        "tog-watchlisthideliu": "Amaga a la llista les edicions d'usuaris registrats",
        "tog-watchlistreloadautomatically": "Recarrega la llista de seguiment automàticament sempre que canviï un filtre (cal JavaScript)",
-       "tog-watchlistunwatchlinks": "Afegeix enllaços directes per a seguir o deixar de seguir les entrades de la llista de seguiment (cal Javascript per a la funcionalitat d'alternar)",
+       "tog-watchlistunwatchlinks": "Afegeix marcadors directes ({{int:Watchlist-unwatch}}/{{int:Watchlist-unwatch-undo}}) per a les pàgines en seguiment amb canvis (cal Javascript per a la funcionalitat d'alternar)",
        "tog-watchlisthideanons": "Amaga a la llista les edicions d'usuaris anònims",
        "tog-watchlisthidepatrolled": "Amaga edicions patrullades de la llista de seguiment",
        "tog-watchlisthidecategorization": "Amaga la categorització de les pàgines",
        "cascadeprotected": "Aquesta pàgina està protegida i no es pot modificar perquè està inclosa en {{PLURAL:$1|la següent pàgina, que té|les següents pàgines, que tenen}} activada l'opció de «protecció en cascada»:\n$2",
        "namespaceprotected": "No teniu permís per a modificar pàgines en l'espai de noms '''$1'''.",
        "customcssprotected": "No teniu permisos per editar la pàgina CSS perquè conté els paràmetres personals d'un altre usuari.",
+       "customjsonprotected": "No teniu permisos per editar aquesta pàgina JSON perquè conté configuracions personals d'un altre usuari.",
        "customjsprotected": "No teniu permisos per editar la pàgina JavaScript perquè conté els paràmetres personals d'un altre usuari.",
        "mycustomcssprotected": "No tens permís per editar aquesta pàgina CSS.",
        "mycustomjsonprotected": "No teniu permisos per editar aquesta pàgina JSON.",
        "wrongpasswordempty": "La contrasenya que s'ha introduït estava en blanc. Torneu-ho a provar.",
        "passwordtooshort": "La contrasenya ha de tenir un mínim {{PLURAL:$1|d'un caràcter|de $1 caràcters}}.",
        "passwordtoolong": "La contrasenya ha de tenir un màxim {{PLURAL:$1|d'un caràcter|de $1 caràcters}}.",
-       "passwordtoopopular": "No poden utilitzar-se contrasenyes d'ús habitual. Trieu-ne una més única.",
+       "passwordtoopopular": "No poden utilitzar-se contrasenyes d'ús habitual. Trieu una contrasenya que sigui més difícil d'endevinir.",
        "password-name-match": "La contrasenya ha de ser diferent del vostre nom d'usuari.",
        "password-login-forbidden": "No és permès d'utilitzar aquest nom d'usuari i contrasenya.",
        "mailmypassword": "Restableix la contrasenya",
        "passwordremindertitle": "Nova contrasenya temporal per al projecte {{SITENAME}}",
-       "passwordremindertext": "Algú (vós mateix segurament, des de l'adreça IP $1) ha sol·licitat que us enviéssim una nova contrasenya per a iniciar la sessió en el projecte {{SITENAME}} ($4).\nLa nova contrasenya temporal per a l'usuari «$2» és ara «$3». Si la vostra intenció era aquesta, ara hauríeu d'iniciar la sessió i canviar-la. Tingueu present que és temporal i caducarà d'aquí a {{PLURAL:$5|un dia|$5 dies}}.\n\nSi algú altre hagués fet aquesta sol·licitud o si ja haguéssiu recordat la vostra contrasenya i\nno volguéssiu canviar-la, ignoreu aquest missatge i continueu utilitzant\nla contrasenya antiga.",
+       "passwordremindertext": "Algú (des de l'adreça IP $1) ha sol·licitat una nova contrasenya per al projecte {{SITENAME}} ($4).\nLa nova contrasenya temporal per a l'usuari «$2» és ara «$3». Si la vostra intenció era aquesta, ara hauríeu d'iniciar la sessió i canviar-la. Tingueu present que és temporal i caducarà d'aquí a {{PLURAL:$5|un dia|$5 dies}}.\n\nSi algú altre hagués fet aquesta sol·licitud o si ja haguéssiu recordat la vostra contrasenya i\nno volguéssiu canviar-la, ignoreu aquest missatge i continueu utilitzant\nla contrasenya antiga.",
        "noemail": "No hi ha cap adreça electrònica registrada de l'usuari «$1».",
        "noemailcreate": "Heu d’indicar una adreça electrònica vàlida.",
        "passwordsent": "S'ha enviat una nova contrasenya a l'adreça electrònica registrada per «$1».\nInicieu una sessió després que la rebeu.",
        "botpasswords-existing": "Contrasenyes de bot existents",
        "botpasswords-createnew": "Crea una contrasenya de bot nova",
        "botpasswords-editexisting": "Edita una contrasenya de bot existent",
+       "botpasswords-label-needsreset": "(cal reiniciar la contrasenya)",
        "botpasswords-label-appid": "Nom del bot:",
        "botpasswords-label-create": "Crea",
        "botpasswords-label-update": "Actualitza",
        "resetpass-submit-loggedin": "Canvia la contrasenya",
        "resetpass-submit-cancel": "Cancel·la",
        "resetpass-wrong-oldpass": "Contrasenya actual o temporal no vàlida.\nDeveu haver canviat la vostra contrasenya o demanat una nova contrasenya temporal.",
-       "resetpass-recycled": "Restabliu la contrasenya amb un text diferent que el de la contrasenya actual.",
+       "resetpass-recycled": "Canvieu la contrasenya amb un text diferent que el de la contrasenya actual.",
        "resetpass-temp-emailed": "Heu iniciat una sessió amb un codi temporal enviat per correu.\nPer completar l'inici de sessió heu de definir una contrasenya nova a continuació:",
        "resetpass-temp-password": "Contrasenya temporal:",
        "resetpass-abort-generic": "Una extensió ha interromput el canvi de contrasenya.",
        "resetpass-expired": "La contrasenya ha vençut. Definiu una contrasenya nova per iniciar la sessió.",
-       "resetpass-expired-soft": "La contrasenya ha vençut i cal restablir-la. Trieu una contrasenya nova ara, o feu clic a «{{int:authprovider-resetpass-skip-label}}» per a restablir-la més endavant.",
-       "resetpass-validity-soft": "La contrasenya no és vàlida: $1\n\nTrieu una nova contrasenya ara o cliqueu \"{{int:authprovider-resetpass-skip-label}}\" per a restablir-la més endavant.",
+       "resetpass-expired-soft": "La contrasenya ha vençut i cal canviar-la. Trieu una contrasenya nova ara, o feu clic a «{{int:authprovider-resetpass-skip-label}}» per a canviar-la més endavant.",
+       "resetpass-validity-soft": "La contrasenya no és vàlida: $1\n\nTrieu una nova contrasenya ara o cliqueu \"{{int:authprovider-resetpass-skip-label}}\" per a canviar-la més endavant.",
        "passwordreset": "Restablir contrasenya",
        "passwordreset-text-one": "Cal completar aquest formulari per reiniciar la contrasenya",
        "passwordreset-text-many": "{{PLURAL:$1|Ompliu un dels camps per a rebre una contrasenya temporal al vostre correu electrònic.}}",
        "subject-preview": "Previsualització de l’assumpte:",
        "previewerrortext": "S'ha produït un error quan es provava de previsualitzar els canvis.",
        "blockedtitle": "L'usuari està blocat",
-       "blockedtext": "'''S'ha procedit al blocatge del vostre compte d'usuari o la vostra adreça IP.'''\n\nEl blocatge l'ha dut a terme l'usuari $1.\nEl motiu donat és ''$2''.\n\n* Inici del blocatge: $8\n* Final del blocatge: $6\n* Compte blocat: $7\n\nPodeu contactar amb $1 o un dels [[{{MediaWiki:Grouppage-sysop}}|administradors]] per a discutir-ho.\n\nTingueu en compte que no podeu fer servir el formulari d'enviament de missatges de correu electrònic a cap usuari, a menys que tingueu una adreça de correu vàlida registrada a les vostres [[Special:Preferences|preferències d'usuari]] i no ho tingueu tampoc blocat.\n\nLa vostra adreça IP actual és $3, i el número d'identificació del blocatge és #$5.\nSi us plau, incloeu aquestes dades en totes les consultes que feu.",
-       "autoblockedtext": "La vostra adreça IP ha estat blocada automàticament perquè va ser usada per un usuari actualment blocat. Aquest usuari va ser blocat per l'{{GENDER:$1|administrador|administradora}} $1. El motiu donat per al blocatge és aquest:\n\n:<em>$2</em>\n\n* Inici del blocatge: $8\n* Final del blocatge: $6\n* Usuari blocat: $7\n\nPodeu contactar l'usuari $1 o algun altre dels [[{{MediaWiki:Grouppage-sysop}}|administradors]] per a discutir el blocatge.\n\nRecordeu que per a poder usar l'opció «Envia un missatge de correu electrònic a aquest usuari» haureu d'haver validat una adreça de correu electrònic a les vostres [[Special:Preferences|preferències]].\n\nEl número d'identificació de la vostra adreça IP és $3, i l'ID del blocatge és #$5. Si us plau, incloeu aquestes dades en totes les consultes que feu.",
+       "blockedtext": "<strong>S'ha procedit al blocatge del vostre compte d'usuari o la vostra adreça IP.</strong>\n\nEl blocatge l'ha dut a terme l'usuari $1.\nEl motiu donat és <em>$2</em>.\n\n* Inici del blocatge: $8\n* Final del blocatge: $6\n* Compte blocat: $7\n\nPodeu contactar amb $1 o un dels [[{{MediaWiki:Grouppage-sysop}}|administradors]] per a discutir-ho.\n\nTingueu en compte que no podeu fer servir la funció «{{int:emailuser}}» a menys que tingueu una adreça de correu vàlida registrada a les vostres [[Special:Preferences|preferències d'usuari]] i no ho tingueu tampoc blocat.\n\nLa vostra adreça IP actual és $3, i el número d'identificació del blocatge és #$5.\nSi us plau, incloeu aquestes dades en totes les consultes que feu.",
+       "autoblockedtext": "La vostra adreça IP ha estat blocada automàticament perquè va ser usada per un usuari actualment blocat. Aquest usuari va ser blocat per l'{{GENDER:$1|administrador|administradora}} $1. El motiu donat per al blocatge és aquest:\n\n:<em>$2</em>\n\n* Inici del blocatge: $8\n* Final del blocatge: $6\n* Usuari blocat: $7\n\nPodeu contactar l'usuari $1 o algun altre dels [[{{MediaWiki:Grouppage-sysop}}|administradors]] per a discutir el blocatge.\n\nRecordeu que per a poder usar l'opció «{{int:emailuser}}» haureu d'haver validat una adreça de correu electrònic a les vostres [[Special:Preferences|preferències]].\n\nEl número d'identificació de la vostra adreça IP és $3, i l'ID del blocatge és #$5. Si us plau, incloeu aquestes dades en totes les consultes que feu.",
        "systemblockedtext": "El vostre nom d'usuari o adreça IP ha estat blocada automàticament pel MediaWiki.\nEl motiu donat és:\n\n:<em>$2</em>\n\n* Inici del blocatge: $8\n* Caducitat del blocatge: $6\n* Destinatari del blocatge: $7\n\nLa vostra adreça IP actual és $3.\nAfegiu les dades de més amunt en qualsevol consulta que feu al respecte.",
        "blockednoreason": "no s'ha donat cap motiu",
        "whitelistedittext": "Heu de $1 per modificar pàgines.",
        "blocked-notice-logextract": "En aquests moments aquest compte d'usuari es troba blocat.\nPer més detalls, la darrera entrada del registre es mostra a continuació:",
        "clearyourcache": "<strong>Nota:</strong> Després de desar, possiblement necessitareu refrescar la memòria cau del vostre navegador per a veure'n els canvis.\n* <strong>Firefox / Safari:</strong> Premeu <em>Shift</em> i alhora cliqueu el botó <em>Actualitza</em>, o pressioneu <em>Ctrl+F5</em> o <em>Ctrl+R</em> (<em>⌘+R</em> en un Mac)\n* <strong>Google Chrome:</strong> Premeu <em>Ctrl+Shift+R</em> (<em>⌘+Shift+R</em> en un Mac)\n* <strong>Internet Explorer:</strong> Premeu <em>Ctrl</em> i alhora cliqueu a <em>Actualitza</em> o pressioneu <em>Ctrl+F5</em>\n* <strong>Opera:</strong> Aneu a <em>Menú → Preferències</em> (<em>Opera → Preferències</em> en un Mac) i llavors a <em>Privadesa i seguretat → Neteja dades de navegació → Imatges i fitxers en memòria cau</em>.",
        "usercssyoucanpreview": "'''Consell:''' Utilitzeu el botó \"{{int:showpreview}}\" per provar el vostre nou CSS abans de desar-lo.",
+       "userjsonyoucanpreview": "<strong>Consell:</strong> Utilitzeu el botó «{{int:showpreview}}» per provar el nou JSON abans de desar-lo.",
        "userjsyoucanpreview": "'''Consell:''' Utilitzeu el botó \"{{int:showpreview}}\" per provar el vostre nou JavaScript abans de desar-lo.",
        "usercsspreview": "'''Recordeu que esteu previsualitzant el vostre CSS d'usuari.'''\n'''Encara no s'ha desat!'''",
        "userjspreview": "'''Recordeu que només estau provant/previsualitzant el vostre JavaScript, encara no ho heu desat!'''",
        "longpageerror": "'''Error: El text que heu introduït és {{PLURAL:$1|d'un kilobyte|de $1 kilobytes}} i sobrepassa el màxim permès de {{PLURAL:$2|one kilobyte|$2 kilobytes}}.'''\nNo es pot desar.",
        "readonlywarning": "<strong>Avís: La base de dades està blocada per manteniment, de manera que no podreu desar els canvis ara mateix.</strong>\nÉs possible que vulgueu copiar i enganxar el text en un arxiu de text i desar-ho més tard.\n\nL'administrador de sistema que l'ha blocada ha donat la següent explicació: $1",
        "protectedpagewarning": "'''ATENCIÓ: Aquesta pàgina està protegida i només els usuaris amb drets d'administrador la poden modificar.\nA continuació es mostra la darrera entrada del registre com a referència:",
-       "semiprotectedpagewarning": "'''Avís:''' Aquesta pàgina està blocada i només pot ser modificada per usuaris registrats.\nA continuació es mostra la darrera entrada del registre com a referència:",
+       "semiprotectedpagewarning": "<strong>Avís:</strong> Aquesta pàgina està blocada i només pot ser modificada per usuaris autoconfirmats.\nA continuació es mostra la darrera entrada del registre com a referència:",
        "cascadeprotectedwarning": "<strong>Atenció:</strong> Aquesta pàgina està protegida de forma que només la poden modificar usuaris amb [[Special:ListGroupRights|permisos específics]], ja que està inclosa a {{PLURAL:$1|la següent pàgina|les següents pàgines}} amb l'opció de «protecció en cascada» activada:",
        "titleprotectedwarning": "'''ATENCIÓ: Aquesta pàgina està protegida de tal manera que es necessiten uns [[Special:ListGroupRights|drets específics]] per a poder crear-la.'''\nA continuació es mostra la darrera entrada del registre com a referència:",
        "templatesused": "Aquesta pàgina fa servir {{PLURAL:$1|la següent plantilla|les següents plantilles}}:",
        "parser-template-loop-warning": "S'ha detectat un bucle de plantilla: [[$1]]",
        "template-loop-category": "Pàgines amb bucles de plantilla",
        "template-loop-category-desc": "La pàgina conté un bucle de plantilles, és a dir, una plantilla que s'inclou a si mateixa recursivament.",
+       "template-loop-warning": "<strong>Avís</strong>: Aquesta pàgina crida [[:$1]] provocant un bucle de plantilles (una crida recursiva infinita).",
        "parser-template-recursion-depth-warning": "S'ha excedit el límit de recursivitat de plantilles ($1)",
        "language-converter-depth-warning": "S'ha excedit el límit de profunditat del convertidor d'idiomes ($1)",
        "node-count-exceeded-category": "Pàgines on s'ha excedit el recompte de nodes",
        "histlegend": "Simbologia: (act) = diferència amb la versió actual,\n(prev) = diferència amb la versió anterior, m = modificació menor",
        "history-fieldset-title": "Cerca revisions",
        "history-show-deleted": "Només revisions esborrades",
-       "histfirst": "més antigues",
-       "histlast": "més noves",
+       "histfirst": "les més antigues",
+       "histlast": "les més noves",
        "historysize": "({{PLURAL:$1|1 octet|$1 octets}})",
        "historyempty": "(buit)",
        "history-feed-title": "Historial de revisió",
        "diff-paragraph-moved-toold": "S'ha mogut el paràgraf. Feu clic per a saltar la ubicació antiga.",
        "difference-missing-revision": "{{PLURAL:$2|Una revisió|$2 revisions}} d'aquesta diferència ($1) no {{PLURAL:$2|s'ha|s'han}} trobat.\n\nAixò passa generalment en seguir un enllaç obsolet de diferències a una pàgina que s'ha suprimit.\nEs pot trobar més informació en el [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} registre de supressions].",
        "searchresults": "Resultats de la cerca",
+       "search-filter-title-prefix-reset": "Cerca a totes les pàgines",
        "searchresults-title": "Resultats de la cerca de «$1»",
        "titlematches": "Coincidències de títol de la pàgina",
        "textmatches": "Coincidències de text de pàgina",
        "stub-threshold-disabled": "Inhabilitat",
        "recentchangesdays": "Dies a mostrar en els canvis recents:",
        "recentchangesdays-max": "(màxim $1 {{PLURAL:$1|dia|dies}})",
-       "recentchangescount": "Nombre d'edicions a mostrar per defecte:",
-       "prefs-help-recentchangescount": "Inclou els canvis recents, els historials de pàgines i els registres.",
+       "recentchangescount": "Nombre d'edicions a mostrar per defecte en canvis recents, historials de pàgines i registres:",
+       "prefs-help-recentchangescount": "Nombre màxim: 1000",
        "prefs-help-watchlist-token2": "Aquesta és la clau secreta pel canal de continguts de la vostra llista de seguiment.\nQualsevol que la conegui podria llegir la vostra llista de seguiment, així que no la compartiu.\nSi és necessari, [[Special:ResetTokens|la podeu restaurar]].",
        "savedprefs": "S’han desat les vostres preferències.",
        "savedrights": "S'han desat els grups d'usuari de {{GENDER:$1|$1}}.",
        "timezoneregion-indian": "Oceà Índic",
        "timezoneregion-pacific": "Oceà Pacífic",
        "allowemail": "Permet que altres usuaris m'enviïn missatges per correu electrònic",
+       "email-allow-new-users-label": "Permet correus electrònics d'usuaris novells",
        "email-blacklist-label": "Prohibeix a aquests usuaris que m'enviïn correus electrònics:",
        "prefs-searchoptions": "Cerca",
        "prefs-namespaces": "Espais de noms",
        "default": "per defecte",
        "prefs-files": "Fitxers",
        "prefs-custom-css": "CSS personalitzat",
+       "prefs-custom-json": "JSON personalitzat",
        "prefs-custom-js": "JS personalitzat",
-       "prefs-common-config": "CSS/JS compartit per tots els skins:",
+       "prefs-common-config": "CSS/JSON/JavaScript compartit per a totes les aparences:",
        "prefs-reset-intro": "Podeu usar aquesta pàgina per a restablir les vostres preferències als valors per defecte.\nNo es podrà desfer el canvi.",
        "prefs-emailconfirm-label": "Confirmació de correu electrònic:",
        "youremail": "Correu electrònic:",
        "prefs-dateformat": "Format de la data",
        "prefs-timeoffset": "Decalatge horari",
        "prefs-advancedediting": "Opcions generals",
+       "prefs-developertools": "Eines de desenvolupament",
        "prefs-editor": "Edició",
        "prefs-preview": "Previsualització",
        "prefs-advancedrc": "Opcions avançades",
        "group-autoconfirmed": "Usuaris autoconfirmats",
        "group-bot": "Bots",
        "group-sysop": "Administradors",
+       "group-interface-admin": "Administradors de la interfície",
        "group-bureaucrat": "Buròcrates",
        "group-suppress": "Supressors de Flow",
        "group-all": "(tots)",
        "group-autoconfirmed-member": "{{GENDER:$1|usuari autoconfirmat|usuària autoconfirmada}}",
        "group-bot-member": "{{GENDER:$1|bot}}",
        "group-sysop-member": "{{GENDER:$1|administrador|administradora}}",
+       "group-interface-admin-member": "{{GENDER:$1|administrador|administradora}} de la interfície",
        "group-bureaucrat-member": "{{GENDER:$1|buròcrata}}",
        "group-suppress-member": "{{GENDER:$1|supressor|supressora}} de Flow",
        "grouppage-user": "{{ns:project}}:Usuaris",
        "grouppage-autoconfirmed": "{{ns:project}}:Usuaris autoconfirmats",
        "grouppage-bot": "{{ns:project}}:Bots",
        "grouppage-sysop": "{{ns:project}}:Administradors",
+       "grouppage-interface-admin": "{{ns:project}}:Administradors de la interfície",
        "grouppage-bureaucrat": "{{ns:project}}:Buròcrates",
        "grouppage-suppress": "{{ns:project}}:Supressors de Flow",
        "right-read": "Llegir pàgines",
        "grant-createaccount": "Crea comptes",
        "grant-createeditmovepage": "Crea, modifica i reanomena pàgines",
        "grant-delete": "Suprimeix pàgines, revisions i entrades de registre",
-       "grant-editinterface": "Modifica l'espai de noms MediaWiki i els CSS/JavaScript d'usuari",
-       "grant-editmycssjs": "Modifiqueu el vostre CSS/JavaScript d'usuari",
+       "grant-editinterface": "Modifica l'espai de noms MediaWiki i els CSS/JSON/JavaScript d'usuari",
+       "grant-editmycssjs": "Modifiqueu el vostre CSS/JSON/JavaScript d'usuari",
        "grant-editmyoptions": "Editeu les vostres preferències d'usuari",
        "grant-editmywatchlist": "Modifica la llista de seguiment",
        "grant-editpage": "Modifica les pàgines existents",
        "recentchanges-noresult": "Cap canvi corresponent a aquests criteris en el període indicat.",
        "recentchanges-timeout": "Aquesta cerca ha temporitzat. Podeu provar amb paràmetres de cerca diferents.",
        "recentchanges-network": "A causa d'un error tècnic no s'ha pogut recuperar cap resultat. Intenteu refrescar la pàgina.",
+       "recentchanges-notargetpage": "Introduïu un nom de pàgina a dalt per veure els canvis relacionats amb aquesta pàgina.",
        "recentchanges-feed-description": "Segueix en aquest canal els canvis més recents del wiki.",
        "recentchanges-label-newpage": "Aquesta modificació creà una pàgina",
        "recentchanges-label-minor": "Aquesta és una modificació menor",
        "rcfilters-other-review-tools": "Altres eines de supervisió",
        "rcfilters-group-results-by-page": "Agrupa els resultats per pàgina",
        "rcfilters-activefilters": "Filtres actius",
+       "rcfilters-activefilters-hide": "Amaga",
+       "rcfilters-activefilters-show": "Mostra",
        "rcfilters-advancedfilters": "Filtres avançats",
        "rcfilters-limit-title": "Resultats a mostrar",
        "rcfilters-limit-and-date-label": "$1 {{PLURAL:$1|canvi|canvis}}, $2",
        "rcfilters-empty-filter": "No hi ha cap filtre actiu. Es mostren totes les contribucions.",
        "rcfilters-filterlist-title": "Filtres",
        "rcfilters-filterlist-whatsthis": "Com funciona això?",
-       "rcfilters-filterlist-feedbacklink": "Comenta'ns què et semblen aquestes (noves) eines per filtrar",
+       "rcfilters-filterlist-feedbacklink": "Comenteu-nos què us semblen aquestes eines de filtratge",
        "rcfilters-highlightbutton-title": "Ressalta els resultats",
        "rcfilters-highlightmenu-title": "Selecciona un color",
        "rcfilters-highlightmenu-help": "Seleccioneu un color per ressaltar la propietat",
        "rcfilters-filter-humans-description": "Modificacions fetes per editors humans.",
        "rcfilters-filtergroup-reviewstatus": "Estat de revisió",
        "rcfilters-filter-reviewstatus-unpatrolled-label": "No patrullat",
+       "rcfilters-filter-reviewstatus-manual-description": "Modificacions marcades manualment com a patrullades.",
+       "rcfilters-filter-reviewstatus-manual-label": "Patrullat manualment",
+       "rcfilters-filter-reviewstatus-auto-label": "Autopatrullat",
        "rcfilters-filtergroup-significance": "Significació",
        "rcfilters-filter-minor-label": "Modificacions menors",
        "rcfilters-filter-minor-description": "Modificacions que l'autor va etiquetar com a menors.",
        "rcfilters-watchlist-edit-watchlist-button": "Editeu la vostra llista de pàgines seguides",
        "rcfilters-watchlist-showupdated": "Els canvis fets en pàgines que no heu visitat des que s'efectuaren apareixen en <strong>negreta</strong> amb un punt sòlid al costat.",
        "rcfilters-preference-label": "Amaga la versió millorada de Canvis recents",
+       "rcfilters-watchlist-preference-label": "Amaga la versió millorada de la llista de seguiment",
+       "rcfilters-filter-showlinkedfrom-label": "Mostra els canvis en les pàgines enllaçades des de",
+       "rcfilters-filter-showlinkedfrom-option-label": "<strong>Pàgines enllaçades des de</strong> la pàgina seleccionada",
+       "rcfilters-filter-showlinkedto-label": "Mostra els canvis a les pàgines que enllacin a",
+       "rcfilters-filter-showlinkedto-option-label": "<strong>Pàgines que enllacen a</strong> la pàgina seleccionada",
        "rcfilters-target-page-placeholder": "Escriviu el nom d’una pàgina (o d’una categoria)",
        "rcnotefrom": "A sota hi ha {{PLURAL:$5|el canvi|els canvis}} a partir de <strong>$3, $4</strong> (fins a <strong>$1</strong>).",
        "rclistfromreset": "Reinicialitza la selecció de data",
        "recentchangeslinked-feed": "Canvis relacionats",
        "recentchangeslinked-toolbox": "Canvis relacionats",
        "recentchangeslinked-title": "Canvis relacionats amb «$1»",
-       "recentchangeslinked-summary": "Introduïu un nom de pàgina per veure els canvis en les pàgines enllaçades des de o cap a aquesta pàgina (per veure els membres d'una categoria, introduïu Categoria:Nom de la categoria).\nEls canvis en pàgines de la vostra [[Special:Watchlist|llista de seguiment]] apareixen en <strong>negreta</strong>.",
+       "recentchangeslinked-summary": "Introduïu un nom de pàgina per veure els canvis en les pàgines enllaçades des de o cap a aquesta pàgina (per veure els membres d'una categoria, introduïu {{ns:category}}:Nom de la categoria).\nEls canvis en pàgines de la vostra [[Special:Watchlist|llista de seguiment]] apareixen en <strong>negreta</strong>.",
        "recentchangeslinked-page": "Nom de la pàgina:",
        "recentchangeslinked-to": "Mostra els canvis de les pàgines enllaçades amb la pàgina donada",
        "recentchanges-page-added-to-category": "[[:$1]] afegida a la categoria",
        "uploadstash-bad-path": "El camí no existeix.",
        "uploadstash-bad-path-invalid": "El camí no és vàlid.",
        "uploadstash-bad-path-unknown-type": "El tipus «$1» és desconegut.",
+       "uploadstash-bad-path-unrecognized-thumb-name": "Nom de miniatura no reconegut.",
+       "uploadstash-file-not-found-not-exists": "No es pot trobar el camí, o bé no és un fitxer pla.",
+       "uploadstash-file-too-large": "No es pot servir un fitxer més gran de $1 bytes.",
        "uploadstash-no-extension": "L’extensió és nul·la.",
+       "uploadstash-zero-length": "El fitxer té mida zero.",
        "invalid-chunk-offset": "El desplaçament del fragment no és vàlid",
        "img-auth-accessdenied": "Accés denegat",
        "img-auth-nopathinfo": "Hi manca PATH_INFO.\nEl servidor no està configurat per passar aquesta informació.\nPot estar basat en CGI i no ser compatible amb img_auth.\nConsulteu https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization",
        "speciallogtitlelabel": "Objectiu (títol o «{{ns:user}}:nom d’usuari» per a un usuari):",
        "log": "Registres",
        "logeventslist-submit": "Mostra",
+       "logeventslist-more-filters": "Més filtres:",
+       "logeventslist-tag-log": "Registre d'etiquetes",
        "all-logs-page": "Tots els registres públics",
        "alllogstext": "Presentació combinada de tots els registres disponibles de {{SITENAME}}.\nPodeu reduir l'extensió seleccionant el tipus de registre, el nom d'usuari realitzador (distingeix entre majúscules i minúscules), o la pàgina objectiu (també en distingeix).",
        "logempty": "No hi ha cap coincidència en el registre.",
        "dellogpage": "Registre de supressions",
        "dellogpagetext": "Davall hi ha una llista dels esborraments més recents.",
        "deletionlog": "registre de supressions",
+       "log-name-create": "Registre de creació de pàgines",
+       "log-description-create": "A continuació hi ha una llista de les pàgines creades més recentment.",
+       "logentry-create-create": "$1 {{GENDER:$2|va crear}} la pàgina $3",
        "reverted": "Invertit amb una revisió anterior",
        "deletecomment": "Motiu:",
        "deleteotherreason": "Motiu diferent o addicional:",
        "whatlinkshere": "Què hi enllaça",
        "whatlinkshere-title": "Pàgines que enllacen amb «$1»",
        "whatlinkshere-page": "Pàgina:",
-       "linkshere-2": "Les següents pàgines enllacen amb '''$1''':",
-       "nolinkshere-2": "Cap pàgina no enllaça amb '''$1'''.",
-       "nolinkshere-ns-2": "No s'enllaça cap pàgina a '''$1''' en l'espai de noms triat.",
+       "linkshere": "Les següents pàgines enllacen amb '''$2''':",
+       "nolinkshere": "Cap pàgina no enllaça amb '''$2'''.",
+       "nolinkshere-ns": "No s'enllaça cap pàgina a '''$2''' en l'espai de noms triat.",
        "isredirect": "pàgina redirigida",
        "istemplate": "inclusió",
        "isimage": "enllaç a fitxer",
        "move-page": "Reanomena $1",
        "move-page-legend": "Reanomena la pàgina",
        "movepagetext": "Amb el formulari següent reanomenareu una pàgina, movent tot el seu historial al nou nom.\nEl títol anterior es convertirà en una pàgina de redirecció al nou títol.\nPodeu actualitzar automàticament les redireccions que apuntin al títol original.\nSi no ho feu, assegureu-vos de verificar les redireccions [[Special:DoubleRedirects|dobles]] o [[Special:BrokenRedirects|trencades]].\nSerà de la vostra responsabilitat verificar que els enllaços segueixin apuntant cap a on se suposa que ho han de fer.\n\nTingueu en compte que la pàgina <strong>no</strong> serà traslladada si ja existeix una pàgina amb el títol nou, tret que sigui una redirecció sense més historial.\nAixò significa que podeu reanomenar de nou una pàgina al seu títol original si cometeu un error, i que no podeu sobreescriure una pàgina existent.\n\n<strong>Nota:</strong>\nAçò pot ser un canvi dràstic i inesperat en una pàgina que sigui popular; \nassegureu-vos d'entendre les conseqüències que comporta abans de seguir endavant.",
-       "movepagetext-noredirectfixer": "Amb el formulari següent podeu reanomenar una pàgina movent tot el seu historial al nom nou.\nEl títol anterior es convertirà en una pàgina de redirecció al nou títol. \nAssegureu-vos de verificar les redireccions [[Special:DoubleRedirects|dobles]] o [[Special:BrokenRedirects|trencades]].\nÉs responsabilitat vostra assegurar que els enllaços continuen apuntant cap a on se suposa que han d'anar. \n\nTingueu en compte que la pàgina <strong>no</strong> serà traslladada si ja existeix una pàgina amb el títol nou, tret que sigui una redirecció i no tingui més historial. \nAixò significa que podeu reanomenar de nou una pàgina al seu títol original si cometeu un error, i que no podeu sobreescriure una pàgina existent.\n \n<strong>Nota:</strong>\nAixò pot ser un canvi dràstic i inesperat per una pàgina popular; \nassegureu-vos que sabeu el que feu abans de continuar.",
+       "movepagetext-noredirectfixer": "El formulari següent permet reanomenar una pàgina movent-ne tot l'historial al nom nou.\nEl títol anterior es convertirà en una pàgina de redirecció al nou títol. \nAssegureu-vos de verificar les redireccions [[Special:DoubleRedirects|dobles]] o [[Special:BrokenRedirects|trencades]].\nÉs responsabilitat vostra que els enllaços continuïn apuntant cap on se suposa que han d'anar. \n\nTingueu en compte que la pàgina <strong>no</strong> serà traslladada si ja existeix una pàgina amb el títol nou, tret que sigui una redirecció i no tingui més historial. \nAixò significa que podeu reanomenar de nou una pàgina al seu títol original si cometeu un error, i que no podeu sobreescriure una pàgina existent.\n \n<strong>Nota:</strong>\nAixò pot ser un canvi dràstic i inesperat per a una pàgina popular; \nassegureu-vos que sabeu el que feu abans de continuar.",
        "movepagetalktext": "Si marqueu aquesta casella, la pàgina de discussió associada també serà traslladada automàticament al nou títol, tret que ja existeixi allà una pàgina de discussió no buida.\n\nEn aquest cas, haureu de traslladar o fusionar la pàgina manualment si ho desitgeu.",
        "moveuserpage-warning": "'''Atenció:''' Esteu a punt de moure una pàgina d'usuari. Tingueu en compte que només la pàgina es desplaçarà i que el compte d'usuari ''no'' canviarà de nom.",
        "movecategorypage-warning": "<strong>Avís:</strong> Esteu a punt de moure una pàgina de categoria. Tingueu en compte que només es mourà aquesta pàgina, i que les pàgines dins la categoria antiga <em>no</em> es recategoritzaran automàticament en la nova.",
        "thumbnail_dest_directory": "No s'ha pogut crear el directori de destinació",
        "thumbnail_image-type": "Tipus d'imatge no contemplat",
        "thumbnail_gd-library": "Configuració de la biblioteca GD incompleta: falta la funció $1",
+       "thumbnail_image-size-zero": "La mida del fitxer d'imatge sembla ser zero.",
        "thumbnail_image-missing": "Sembla que falta el fitxer: $1",
        "thumbnail_image-failure-limit": "Hi ha hagut massa intents fallits recents ($1 o més) per dibuixar aquesta miniatura.\nTorneu-ho a provar més endavant.",
        "import": "Importació de pàgines",
        "markedaspatrollederrornotify": "Ha fallat la marca com a patrullat.",
        "patrol-log-page": "Registre de supervisió",
        "patrol-log-header": "Això és un registre de les revisions patrullades.",
-       "log-show-hide-patrol": "$1 el registre de patrulla",
-       "log-show-hide-tag": "$1 el registre d’etiquetes",
        "confirm-markpatrolled-button": "D'acord",
        "confirm-markpatrolled-top": "Voleu marcar la revisió $3 de $2 com a patrullada?",
        "deletedrevision": "S'ha eliminat la revisió antiga $1.",
        "confirm-unwatch-top": "Voleu treure aquesta pàgina de la llista de seguiment?",
        "confirm-rollback-button": "D'acord",
        "confirm-rollback-top": "Voleu revertir les modificacions a la pàgina?",
+       "colon-separator": ":&#32;",
        "quotation-marks": "«$1»",
        "imgmultipageprev": "← pàgina anterior",
        "imgmultipagenext": "pàgina següent →",
        "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|Etiqueta|Etiquetes}}]]: $2)",
        "tag-mw-contentmodelchange": "canvi de model de contingut",
        "tag-mw-new-redirect": "Redirecció nova",
+       "tag-mw-removed-redirect": "Redirecció suprimida",
+       "tag-mw-changed-redirect-target": "La destinació de la redirecció ha canviat",
        "tag-mw-blank": "Buidament",
+       "tag-mw-blank-description": "Modificacions que blanquegen una pàgina",
        "tag-mw-replace": "Substitució",
+       "tag-mw-undo": "Desfés",
        "tags-title": "Etiquetes",
        "tags-intro": "Aquesta pàgina llista les etiquetes amb què el programari pot marcar una modificació, i el seu significat.",
        "tags-tag": "Nom de l'etiqueta",
        "compare-title-not-exists": "El títol que heu especificat no existeix.",
        "compare-revision-not-exists": "La revisió que heu especificat no existeix.",
        "diff-form": "Diferències",
+       "diff-form-oldid": "ID de la revisió antiga (opcional)",
+       "diff-form-revid": "ID de revisió de la diferència",
        "diff-form-submit": "Mostra les diferències",
        "permanentlink": "Enllaç permanent",
        "permanentlink-revid": "ID de la revisó",
        "logentry-delete-delete": "$1 {{GENDER:$2|ha suprimit}} la pàgina $3",
        "logentry-delete-delete_redir": "$1 {{GENDER:$2|ha esborrat}} la redirecció $3 sobreescrivint-la",
        "logentry-delete-restore": "$1 {{GENDER:$2|ha restaurat}} la pàgina $3 ($4)",
+       "logentry-delete-restore-nocount": "$1 {{GENDER:$2|va restaurar}} la pàgina $3",
        "restore-count-revisions": "{{PLURAL:$1|Una revisió|$1 revisions}}",
        "restore-count-files": "{{PLURAL:$1|Un fitxer|$1 fitxers}}",
        "logentry-delete-event": "$1 {{GENDER:$2|ha canviat}} la visibilitat {{PLURAL:$5|d'un esdeveniment al registre|de $5 esdeveniments al registre}} de $3: $4",
        "expandtemplates": "Expansió de plantilles",
        "expand_templates_intro": "Aquesta pàgina especial expandeix de forma recursiva totes les plantilles d'un text donat.\nTambé expandeix les funcions sintàctiques, com ara <code><nowiki>{{</nowiki>#language:…}}</code>, i les variables predefinides, com <code><nowiki>{{</nowiki>CURRENTDAY}}</code> &mdash;de fet, gairebé tot que estigui entre claus dobles.",
        "expand_templates_title": "Títol per contextualitzar ({{FULLPAGENAME}}, etc):",
-       "expand_templates_input": "El vostre text:",
+       "expand_templates_input": "Wikitext d'entrada:",
        "expand_templates_output": "Resultat:",
        "expand_templates_xml_output": "Sortida XML",
        "expand_templates_html_output": "Sortida en HTML sense filtrar",
        "expand_templates_preview": "Previsualitza",
        "expand_templates_preview_fail_html": "<em>Atès que {{SITENAME}} té HTML cru habilitat i s'ha produït una pèrdua de dades de la sessió, s'ha amagat la vista prèvia com a mesura de precaució contra atacs en JavaScript.</em>\n\n<strong>Si això és un intent de previsualització legítim, torneu-ho a provar.</strong>\nSi encara no funciona, intenteu [[Special:UserLogout|finalitzar la sessió]] i comproveu si el vostre navegador permet galetes d'aquest lloc.",
        "expand_templates_preview_fail_html_anon": "<em>Atès que {{SITENAME}} té l'HTML cru habilitat i no heu iniciat una sessió, s'ha amagat la previsualització com a prevenció d'atacs en JavaScript.</em>\n\n<strong>Si això és un intent de previsualització legítim, [[Special:UserLogin|inicieu una sessió]] i torneu-ho a provar.</strong>",
-       "expand_templates_input_missing": "Cal que proporcioneu al menys algun text d'entrada.",
+       "expand_templates_input_missing": "Cal que proporcioneu al menys algun wikitext d'entrada.",
        "pagelanguage": "Canvia l'idioma de la pàgina",
        "pagelang-name": "Pàgina",
        "pagelang-language": "Idioma",
        "gotointerwiki-external": "Esteu a punt d’abandonar {{SITENAME}} per a visitar [[$2]], un lloc web diferent.\n\n'''[$1 Continua a $1]'''",
        "undelete-cantedit": "Com que no podeu editar aquesta pàgina, no en podeu desfer la supressió.",
        "pagedata-title": "Dades de la pàgina",
-       "pagedata-bad-title": "Títol no vàlid: $1"
+       "pagedata-bad-title": "Títol no vàlid: $1",
+       "passwordpolicies": "Polítiques de contrasenya",
+       "passwordpolicies-group": "Grup",
+       "passwordpolicies-policies": "Polítiques",
+       "passwordpolicies-policy-minimalpasswordlength": "La contrasenya ha de tenir un mínim {{PLURAL:$1|d'un caràcter|de $1 caràcters}}",
+       "passwordpolicies-policy-passwordcannotmatchusername": "La contrasenya no pot ser igual que el nom d'usuari"
 }
index 8ae463f..2516889 100644 (file)
        "nextn": "âu $1 bĭk",
        "shown-title": "Mūi hiĕk hiēng-sê $1{{PLURAL:$1|bĭk giék-guō}}",
        "viewprevnext": "Káng ($1 {{int:pipe-separator}} $2) ($3)",
+       "searchmenu-exists": "cī siŏh bĭh wiki ī-gĭng ô „$1“ mìng-chĭng gì dèu-mŭk",
        "searchprofile-articles": "Nô̤i-ṳ̀ng hiĕk",
        "searchprofile-images": "Dŏ̤-mùi-tā̤",
        "searchprofile-everything": "Sū-iū-nó̤h",
        "whatlinkshere": "Diē-nē̤ lièng gáu cē̤-nē̤",
        "whatlinkshere-title": "鏈接遘$1其頁面",
        "whatlinkshere-page": "頁面:",
-       "linkshere-2": "下底其頁面鏈接遘'''$1''':",
-       "nolinkshere-2": "無頁鏈接遘'''$1'''。",
+       "linkshere": "下底其頁面鏈接遘'''$2''':",
+       "nolinkshere": "無頁鏈接遘'''$2'''。",
        "isredirect": "重定向頁面",
        "isimage": "文件鏈接",
        "whatlinkshere-prev": "{{PLURAL:$1|前|前$1}}",
index 0a9db04..2913625 100644 (file)
        "nowiki_sample": "Кхуза хӀоттаде хийца оьшуш доцу йоза",
        "nowiki_tip": "Тергал ца бо вики-бáрамхlоттор",
        "image_sample": "Example.jpg",
-       "image_tip": "ЧоÑ\85Ñ\8c Ð¹Ð¾Ð»Ñ\83 Ñ\84айл",
+       "image_tip": "Файл Ñ\87Ñ\83йиллаÑ\80",
        "media_sample": "Example.ogg",
        "media_tip": "Хьажорг медиа-файлан тӀе",
        "sig_tip": "Хьан куьгтаlор аъ хlоттина хан",
        "expansion-depth-exceeded-category": "Схьаелларан кӀоргалла тӀех даьккхина агӀонаш",
        "expansion-depth-exceeded-warning": "АгӀонгахь чуйихкар тӀехдаьккхина",
        "parser-unstrip-loop-warning": "ДӀачӀагӀанца pre карина",
+       "unstrip-depth-warning": "Рекурси ($1) доза тӀехдаьлла",
+       "unstrip-depth-category": "КӀоргалла цагуш йолу агӀонаш",
+       "unstrip-size-warning": "Unstrip рекурси ($1) доза тӀехдаьлла",
+       "unstrip-size-category": "Билгалдар цагуш долу агӀонаш",
        "undo-success": "Нисйинарг а тlе цалаца мега. Дехар до, хьажа цхьатерра йуй башхо, тешна хила, баккъалла иза хийцам буйте хьуна безарг, тlакха тlе таlайе «дlайазйе агlо», хийцам хlотта ба.",
        "undo-failure": "Юккъера хийцамаш бахьнехь нисдар юхадаккха йиш яц.",
        "undo-norev": "Нисдар юхадаккха цало, иза доцу делла я дӀаяьккхина дела.",
        "timezoneregion-indian": "Индин океан",
        "timezoneregion-pacific": "Тийна океан",
        "allowemail": "Магийта декъашхошна хьайга электронан поштехула кехат кхехьийта",
+       "email-allow-new-users-label": "Магийта керла декъашхошна хьайга электронан поштехула кехат кхехьийта",
        "email-blacklist-label": "ХӀокху декъашхошна электронан пошт соьга яийта бехкам-бе:",
        "prefs-searchoptions": "Лахар",
        "prefs-namespaces": "ЦӀерийн меттигаш",
        "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-liveupdates-button-title-off": "Керла хийцамаш ма-бинехь гайта",
        "rcfilters-preference-label": "Керла хийцамийн дика кечйина верси къайлаяккха",
        "rcfilters-preference-help": "2017 шеран интерфейсан редизайн а, оцу хенахь дуьйна тӀетоьхна гӀирсаш а къайлайоху.",
+       "rcfilters-watchlist-preference-label": "Дика кечбина тергаме могӀам къайлабаккха",
+       "rcfilters-watchlist-preference-help": "ДӀайоху 2017 шеран интерфейсан редизайн, а оцу хенахь а, цул тӀехьа а тӀетоьхна болу гӀирсаш а.",
        "rcfilters-filter-showlinkedfrom-label": "Хьажоргаш йолучу агӀонашна тӀехь нисдарш гайта",
        "rcfilters-filter-showlinkedfrom-option-label": "<strong>Хаьржиначунна хьажоргаш йолу агӀонаш</strong>",
        "rcfilters-filter-showlinkedto-label": "Хьажоргаш йолучу агӀонашна тӀехь нисдарш гайта",
        "uploaddisabled": "Чуяккхар магийна дац",
        "copyuploaddisabled": "URL тӀера чуяккхар дӀадайина ду.",
        "uploaddisabledtext": "Файлаш чуяхар дӀадайина ду.",
+       "uploaded-href-attribute-svg": "Элементаш <a> тӀетовжа (href) мега data: (файл чуйиллар) тӀе, хьажорг http:// я https:// я фрагмент (#, оцу документ тӀехь). Кхечу элементашна, масала <image>  санна, data: а, фрагмент а бен цамагийна. \nСурт чудийлла хьажа SVG форматехь. Карина <code>&lt;$1 $2=\"$3\"&gt;</code>.",
        "uploadscriptednamespace": "ХӀокху SVG-файлан цӀерийн меттиг нийса яц '<nowiki>$1</nowiki>'",
        "upload-source": "ДIайолалун файл",
        "sourcefilename": "ДIайолалун файл:",
        "linkstoimage-redirect": "$1 (файлан дӀасахьажорг) $2",
        "duplicatesoffile": "{{PLURAL:$1|Лахара файл ю дубликат|Лахара $1 файлаш ю дубликаташ}} хӀокху файлан ([[Special:FileDuplicateSearch/$2|мадарра]]):",
        "sharedupload": "ХӀара хӀума оцун $1 чура ю иза хила мега лелош кхечу проекташкахь.",
-       "sharedupload-desc-here": "Ð¥Ó\80аÑ\80а Ñ\84айл $1 Ñ\87Ñ\83Ñ\80а Ñ\8e Ð¸ Ð»ÐµÐ»Ð¾ Ð¹Ð¸Ñ\88 Ñ\8e Ð¼Ð°Ñ\81Ñ\81о Ð¿Ñ\80оекÑ\82аÑ\88каÑ\85Ñ\8c.\nЦÑ\83нна Ñ\85аам Ð³Ð°Ð¹Ñ\82ина Ð»Ð°Ñ\85аÑ\85Ñ\8c. [$2 Ð¤Ð°Ð¹Ð» Ð\92икигÑ\83ламехь]",
+       "sharedupload-desc-here": "Ð¥Ó\80аÑ\80а Ñ\84айл $1 Ñ\87Ñ\83Ñ\80а Ñ\8e Ð¸ Ð»ÐµÐ»Ð¾ Ð¹Ð¸Ñ\88 Ñ\8e Ð¼Ð°Ñ\81Ñ\81о Ð¿Ñ\80оекÑ\82аÑ\88каÑ\85Ñ\8c.\nЦÑ\83нна Ñ\85аам Ð³Ð°Ð¹Ñ\82ина Ð»Ð°Ñ\85аÑ\85Ñ\8c. [$2 Ð¤Ð°Ð¹Ð» Ð\92икилаÑ\80мехь]",
        "filepage-nofile": "Иштта цӀе йолуш файл яц.",
        "filepage-nofile-link": "Иштта цӀе йолуш файл яц. Хьа йиш ю и [$1 чуяккха].",
        "uploadnewversion-linktext": "Чуяккха керла верси хӀокху файлан",
        "dellogpage": "ДӀадаьхнарш долу тéптар",
        "dellogpagetext": "Лахахь гойтуш ю тӀаьххьара дӀаяьхнарш.",
        "deletionlog": "дӀадаьхнарш долу тéптар",
+       "log-name-create": "АгӀонаш кхолларан тептар",
+       "log-description-create": "Лахахь гойтуш ю тӀаьххьара кхоьллина агӀонаш.",
+       "logentry-create-create": "$1 {{GENDER:$2|кхоьллина}} $3 агӀо",
        "deletecomment": "Бахьана:",
        "deleteotherreason": "Кхин бахьана/тӀетохар:",
        "deletereasonotherlist": "Кхин бахьана",
        "whatlinkshere": "Кхуза хьажоргаш",
        "whatlinkshere-title": "«$1» тӀе хьажоргаш йолу агӀонаш",
        "whatlinkshere-page": "АгӀо:",
-       "linkshere-2": "ТӀаьхьайогӀу агӀонаш оцу '''$1''': хьажоргца ю",
-       "nolinkshere-2": "ХӀокху '''$1''' агӀона тӀе кхечу агӀонашкахь хьажоргаш яц.",
-       "nolinkshere-ns-2": "Хаьржинчу меттигехь яц '''$1''' цӀе йолу агӀонаш",
+       "linkshere": "ТӀаьхьайогӀу агӀонаш оцу '''$2''': хьажоргца ю",
+       "nolinkshere": "ХӀокху '''$2''' агӀона тӀе кхечу агӀонашкахь хьажоргаш яц.",
+       "nolinkshere-ns": "Хаьржинчу меттигехь яц '''$2''' цӀе йолу агӀонаш",
        "isredirect": "агӀо-дӀасахьажорг",
        "istemplate": "юкъаялийнарш",
        "isimage": "Файлан хьажорг",
        "markedaspatrollederrornotify": "Хийцамаш хьаьжжина сана билгал бан цабелира.",
        "patrol-log-page": "ТӀехьажаран тептар",
        "patrol-log-header": "Хьажжина версеш йолу тептар.",
-       "log-show-hide-patrol": "$1 тӀехьажаран тептар",
-       "log-show-hide-tag": "$1 билгалонийн тептар",
        "confirm-markpatrolled-button": "ХӀаъ",
        "deletedrevision": "ДӀаяьккхина шира верси $1",
        "filedeleteerror-short": "Файл дӀаяккхаран гӀалат: $1",
        "limitreport-templateargumentsize-value": "$1/$2 {{PLURAL:$2|байт}}",
        "limitreport-expansiondepth": "Шордаларан уггар йокха кӀоргалла",
        "limitreport-expensivefunctioncount": "Анализаторан «еза» функцийн дукхалла",
+       "limitreport-unstrip-depth": "КӀорге рекурси Unstrip",
+       "limitreport-unstrip-size": "Чуьраниг схьаделачул тӀехьа Unstrip болу барам",
        "expandtemplates": "Кепаш схьаястар",
        "expand_templates_intro": "ХӀокху белхан агӀорахь йиш ю йоза хийца.\nКхин кепаш схьаяста.\n<code><nowiki>{{#language:…}}</nowiki></code> кхочуш дан тайп\n<code><nowiki>{{CURRENTDAY}}</nowiki></code>.",
        "expand_templates_title": "АгӀона {{FULLPAGENAME}} корта кхин а:",
        "special-characters-group-greek": "Грекийн",
        "special-characters-group-greekextended": "Грекийн алсам",
        "special-characters-group-cyrillic": "Кирилан",
-       "special-characters-group-arabic": "Ӏарбийн",
+       "special-characters-group-arabic": "Ó\80аÑ\8cÑ\80бийн",
        "special-characters-group-arabicextended": "Ӏаьрбийн алсам",
        "special-characters-group-persian": "Пхьарсхойн",
        "special-characters-group-hebrew": "Жуьгтийн",
        "credentialsform-provider": "ДӀаяздарийн тайпа:",
        "credentialsform-account": "Декъашхочун цӀе:",
        "userjsispublic": "Тергам бе: JavaScript бухара агӀонаш чохь къайлаха хаамаш хийла ца беза, уьш массо декъашхойн тӀекхочуш йолу дера.",
-       "usercssispublic": "Тергам бе: CSS бухара агӀонаш чохь къайлаха хаамаш хийла ца беза, уьш массо декъашхойн тӀекхочуш йолу дера."
+       "usercssispublic": "Тергам бе: CSS бухара агӀонаш чохь къайлаха хаамаш хийла ца беза, уьш массо декъашхойн тӀекхочуш йолу дера.",
+       "passwordpolicies": "Паролийн политика",
+       "passwordpolicies-summary": "ХӀокху агӀонгахь гойту декъашхойн паролашна болу бехкам. Декъашхойн юкъабогӀуш болу бакъонийн тобанашка хьажжина бу бехкам.",
+       "passwordpolicies-policy-minimalpasswordlength": "Пароль $1 {{PLURAL:$1|символал}} еха хила еза",
+       "passwordpolicies-policy-minimumpasswordlengthtologin": "Пароль хила еза $1 {{PLURAL:$1|символал}} еха, декъашхочун шен агӀо караяйтархьама",
+       "passwordpolicies-policy-passwordcannotmatchusername": "Пароль декъашхочун цӀерах тера хила ца еза",
+       "passwordpolicies-policy-passwordcannotmatchblacklist": "Пароль Ӏаьржачу могӀаман юкъахь йолучарех тера хила ца еза",
+       "passwordpolicies-policy-maximalpasswordlength": "Пароль $1 {{PLURAL:$1|символал}} йоца хила ца еза",
+       "passwordpolicies-policy-passwordcannotbepopular": "Пароль дукха {{PLURAL:$1|лелош йолчарех хила ца еза}}"
 }
index 415ae14..c38812e 100644 (file)
        "whatlinkshere": "Unsay mga misumpay dinhi",
        "whatlinkshere-title": "Mga panid nga misumpay ngadto sa \"$1\"",
        "whatlinkshere-page": "Panid:",
-       "linkshere-2": "Ang mosunod nga mga panid misumpay sa '''$1''':",
+       "linkshere": "Ang mosunod nga mga panid misumpay sa '''$2''':",
        "isredirect": "panid sa redirekta",
        "istemplate": "transklusyon",
        "isimage": "sumpay sa payl",
index 138554b..ced2f6a 100644 (file)
        "whatlinkshere": "Håfa ha na'chetton guini",
        "whatlinkshere-title": "I påhina siha ni mana'chetton yan \"$1\"",
        "whatlinkshere-page": "Påhina:",
-       "linkshere-2": "Umachetton i sigienten påhina siha yan '''$1''':",
-       "nolinkshere-2": "Taya' umachetton yan '''$1'''.",
+       "linkshere": "Umachetton i sigienten påhina siha yan '''$2''':",
+       "nolinkshere": "Taya' umachetton yan '''$2'''.",
        "isredirect": "dirihi i påhina",
        "istemplate": "sinaonao",
        "whatlinkshere-prev": "{{PLURAL:$1|ni må'pos|$1 ni manmå'pos}}",
index c0f78de..1e84913 100644 (file)
        "history-feed-item-nocomment": "$1 لە $2",
        "history-feed-empty": "لاپەڕەی داخوازی‌کراو بوونی نیە.<br />\nلەوانەیە لەسەر ویکی سڕدرابێتەوە یان ناوی گۆڕدرابێت.<br />\nبۆ لاپەڕەی وەک ئەوە هەوڵی [[Special:Search|گەڕان لەسەر ویکی]] بدە.",
        "rev-deleted-comment": "(کورتەی دەستکاری سڕایەوە)",
-       "rev-deleted-user": "(Ù\86اÙ\88Û\8c Ø¨Û\95کارÙ\87Û\8eÙ\86Û\95ر Ø³Ú\95اÛ\8cەوە)",
+       "rev-deleted-user": "(Ù\86اÙ\88Û\8c Ø¨Û\95کارÙ\87Û\8eÙ\86Û\95ر Ø³Ú\95دراÙ\88Û\95تەوە)",
        "rev-deleted-event": "(لۆگی کردەوە سڕایەوە)",
        "rev-deleted-text-permission": "ئەم پێداچوونەوەیە لەم پەڕەیە '''سڕدراوەتەوە'''.\nوردەکاری سەبارەت بەوە لە [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} لۆگی سڕینەوە]دا دەست دەکەوێت.",
        "rev-deleted-text-unhide": "ئەم پێداچوونەوەیە لەم پەڕەیە '''سڕدراوەتەوە'''.\nوردەکاری سەبارەت بەوە لە [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} لۆگی سڕینەوە]دا دەست دەکەوێت.\nھێشتا ئەگەر بتەوێ دەتوانی [$1 ئەم پێداچوونەوەیە ببینی].",
        "group-autoconfirmed": "بەکارھێنەرە خۆبەخۆ پەسندکراوەکان",
        "group-bot": "بۆتەکان",
        "group-sysop": "بەڕێوەبەران",
+       "group-interface-admin": "بەڕێوەبەرانی ڕووکار",
        "group-bureaucrat": "بیوروکراتەکان",
        "group-suppress": "چاودێرەکان",
        "group-all": "(ھەموو)",
        "group-autoconfirmed-member": "{{GENDER:$1|بەکارھێنەرە خۆبەخۆ پەسندکراوەکان}}",
        "group-bot-member": "بۆت",
        "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": "خوێندنەوەی پەڕەکان",
        "rcfilters-advancedfilters": "پاڵوێنە پێشکەوتووەکان",
        "rcfilters-limit-title": "ئەنجام بۆ نیشاندان",
        "rcfilters-limit-and-date-label": "$1 گۆڕانکاری، $2",
+       "rcfilters-date-popup-title": "ماوە بۆ گەڕان",
+       "rcfilters-days-title": "ڕۆژ",
+       "rcfilters-hours-title": "کاتژمێر",
        "rcfilters-days-show-days": "$1 {{PLURAL:$1|ڕۆژ}}",
        "rcfilters-quickfilters": "پاڵوێنە پاشەکەوتکراوەکان",
        "rcfilters-quickfilters-placeholder-title": "ھیچ پاڵوێنەیەک پاشەکەوت نەکراوە",
        "rcfilters-view-tags-help-icon-tooltip": "زیاتر بزانە لەسەر دەستکارییە تاگکراوەکان",
        "rcfilters-liveupdates-button": "نوێکردنەوەی زیندوو",
        "rcnotefrom": "ژێرەوە {{PLURAL:$5|گۆڕانکارییەکەیە|گۆڕانکارییەکانە}} لە <strong>$3، $4</strong>ەوە (ھەتا <strong>$1</strong> نیشان دراوە).",
+       "rclistfromreset": "گەڕاندنەوەی ھەڵبژاردەی بەروار",
        "rclistfrom": "گۆڕانکارییە نوێکان نیشان بدە بە دەستپێکردن لە $3 $2",
        "rcshowhideminor": "دەستکارییە بچووکەکان $1",
        "rcshowhideminor-show": "نیشان بدە",
        "dellogpage": "لۆگی سڕینەوە",
        "dellogpagetext": "ئەوەی خوارەوە لیستێكە لە دوایین سڕینەوەکان",
        "deletionlog": "لۆگی سڕینەوە",
+       "log-name-create": "لۆگی دروستکردنی پەڕە",
+       "logentry-create-create": "$1 پەڕەی $3ی دروست کرد",
        "reverted": "گەڕێندراوە بۆ پێداچوونەوەی پێشووتر",
        "deletecomment": "ھۆکار:",
        "deleteotherreason": "ھۆکاری تر/زیاتر:",
        "uctop": "(ھەنووکە)",
        "month": "لە مانگی (و پێشترەوە):",
        "year": "لە ساڵی (و پێشترەوە):",
+       "date": "لە ڕێکەوتی (و پێشترەوە)",
        "sp-contributions-newbies": "تەنیا بەشدارییەکانی ھەژمارە نوێکان نیشان بدە",
        "sp-contributions-newbies-sub": "بۆ ھەژمارە نوێکان",
        "sp-contributions-newbies-title": "بەشدارییەکانی بەکارھێنەر بۆ ھەژمارە نوێکان",
        "whatlinkshere": "بەستەرەکان بە ئێرەوە",
        "whatlinkshere-title": "ئەو پەڕانەی بەستەریان ھەیە بۆ «$1»",
        "whatlinkshere-page": "پەڕە:",
-       "linkshere-2": "پەڕەکانی ژێرەوە بەستەر دراون بۆ <strong>$1</strong>:",
-       "nolinkshere-2": "ھیچ پەڕەیەک بەستەری نییە بۆ <strong>$1</strong>.",
-       "nolinkshere-ns-2": "ھیچ پەڕەیەک بەستەری نییە بۆ <strong>$1</strong> لە بۆشایی ناوی هەڵبژێرراودا.",
+       "linkshere": "پەڕەکانی ژێرەوە بەستەر دراون بۆ <strong>$2</strong>:",
+       "nolinkshere": "ھیچ پەڕەیەک بەستەری نییە بۆ <strong>$2</strong>.",
+       "nolinkshere-ns": "ھیچ پەڕەیەک بەستەری نییە بۆ <strong>$2</strong> لە بۆشایی ناوی هەڵبژێرراودا.",
        "isredirect": "پەڕەی ڕەوانەکەر",
        "istemplate": "بەکارھێنراو",
        "isimage": "بەستەری پەڕگە",
        "markedaspatrollederrornotify": "نیشانکردن وەک پاس دراو سەرکەوتوو نەبوو.",
        "patrol-log-page": "لۆگی پاسدان",
        "patrol-log-header": "ئەمە لۆگێکی پێداچوونەوە پاس دراوەکانە.",
-       "log-show-hide-patrol": "لۆگی پاسدان $1",
        "confirm-markpatrolled-button": "باشە",
        "deletedrevision": "پێداچوونەوەی کۆنی سڕاوە $1",
        "filedeleteerror-short": "هەڵە لە سڕینەوەی پەڕگە: $1",
        "special-characters-group-gujarati": "گوجەراتی",
        "special-characters-group-thai": "تایلەندی",
        "special-characters-group-khmer": "خمێری",
+       "mw-widgets-dateinput-no-date": "ڕێکەوت ھەڵنەبژێردراوە",
        "mw-widgets-usersmultiselect-placeholder": "زیادکردن...",
+       "date-range-from": "لە ڕێکەوتی:",
+       "date-range-to": "بۆ ڕێکەوتی:",
        "log-action-filter-block": "جۆری بلۆک:",
+       "log-action-filter-contentmodel": "جۆری گۆڕینی مۆدێلی ناوەڕۆک:",
+       "log-action-filter-delete": "جۆری سڕینەوە:",
        "log-action-filter-all": "ھەموو",
        "log-action-filter-upload-upload": "بارکردنی نوێ",
        "authmanager-email-label": "ئیمەیڵ"
index 360b865..56f89cb 100644 (file)
        "sp-contributions-submit": "Circà",
        "whatlinkshere": "Pagine chì leganu quì",
        "whatlinkshere-title": "Pagine ligate à \"$1\"",
-       "linkshere-2": "E seguente pagine sò culligate à '''$1''':",
+       "linkshere": "E seguente pagine sò culligate à '''$2''':",
        "istemplate": "inclusione",
        "whatlinkshere-prev": "{{PLURAL:$1|precidente|precidenti $1}}",
        "whatlinkshere-next": "{{PLURAL:$1|seguente|seguenti $1}}",
index 214edc4..316a13d 100644 (file)
        "whatlinkshere": "Ang nagatabid diri",
        "whatlinkshere-title": "Mga pahina nga naga-link sa $1",
        "whatlinkshere-page": "Pahina:",
-       "linkshere-2": "Ang mga gasunod nga pahina ga-link sa '''$1''':",
+       "linkshere": "Ang mga gasunod nga pahina ga-link sa '''$2''':",
        "isredirect": "pahina pangdirekta",
        "istemplate": "transklusyon",
        "isimage": "Link sang litrato",
index 27ff8ba..2241458 100644 (file)
        "whatlinkshere": "Бу саифеге багълантылар",
        "whatlinkshere-title": "«$1» саифесине багъланты олгъан саифелер",
        "whatlinkshere-page": "Саифе:",
-       "linkshere-2": "'''$1''' саифесине багъланты берген саифелер:",
-       "nolinkshere-2": "'''$1''' саифесине багъланты берген саифе ёкъ.",
-       "nolinkshere-ns-2": "Сайлангъан исим фезасында '''$1''' саифесине багълангъан саифе ёкътыр.",
+       "linkshere": "'''$2''' саифесине багъланты берген саифелер:",
+       "nolinkshere": "'''$2''' саифесине багъланты берген саифе ёкъ.",
+       "nolinkshere-ns": "Сайлангъан исим фезасында '''$2''' саифесине багълангъан саифе ёкътыр.",
        "isredirect": "Ёллама саифеси",
        "istemplate": "кирсетильме",
        "isimage": "файл багълантысы",
        "spam_blanking": "Бар олгъан версияларда $1 сайтына багълантылар бар, темизлев",
        "pageinfo-language": "Саифе ичиндекисининъ тили",
        "patrol-log-page": "Тешкерюв журналы",
-       "log-show-hide-patrol": "Тешкерюв журналыны $1",
        "deletedrevision": "$1 сайылы эски версия ёкъ этильди.",
        "filedeleteerror-short": "Файл ёкъ эткенде хата чыкъты: $1",
        "filedelete-missing": "\"$1\" адлы файл ёкъ этилип оламай, чюнки ойле бир файл ёкъ.",
index cd350ed..02405da 100644 (file)
        "whatlinkshere": "Bu saifege bağlantılar",
        "whatlinkshere-title": "“$1” saifesine bağlantı bergen saifeler",
        "whatlinkshere-page": "Saife:",
-       "linkshere-2": "'''$1''' saifesine bağlantı bergen saifeler:",
-       "nolinkshere-2": "'''$1''' saifesine bağlantı bergen saife yoq.",
-       "nolinkshere-ns-2": "Saylanğan isim fezasında '''$1''' saifesine bağlanğan saife yoqtır.",
+       "linkshere": "'''$2''' saifesine bağlantı bergen saifeler:",
+       "nolinkshere": "'''$2''' saifesine bağlantı bergen saife yoq.",
+       "nolinkshere-ns": "Saylanğan isim fezasında '''$2''' saifesine bağlanğan saife yoqtır.",
        "isredirect": "Yollama saifesi",
        "istemplate": "kirsetilme",
        "isimage": "fayl bağlantısı",
        "spam_blanking": "Bar olğan versiyalarda $1 saytına bağlantılar bar, temizlev",
        "pageinfo-language": "Saife içindekisiniñ tili",
        "patrol-log-page": "Teşkerüv jurnalı",
-       "log-show-hide-patrol": "Teşkerüv jurnalını $1",
        "deletedrevision": "$1 sayılı eski versiya yoq etildi.",
        "filedeleteerror-short": "Fayl yoq etkende hata çıqtı: $1",
        "filedelete-missing": "\"$1\" adlı fayl yoq etilip olamay, çünki öyle bir fayl yoq.",
index 160fc43..eee6de0 100644 (file)
        "customcssprotected": "Nemáte povoleno editovat tuto stránku s CSS, protože obsahuje osobní nastavení jiného uživatele.",
        "customjsonprotected": "Nemáte povoleno editovat tuto stránku s JSONem, protože obsahuje osobní nastavení jiného uživatele.",
        "customjsprotected": "Nemáte povoleno editovat tuto stránku s JavaScriptem, protože obsahuje osobní nastavení jiného uživatele.",
+       "sitecssprotected": "Nemáte oprávnění editovat tuto stránku s CSS, protože to může mít dopad na všechny návštěvníky",
+       "sitejsonprotected": "Nemáte oprávnění editovat tuto stránku s JSONem, protože to může mít dopad na všechny návštěvníky",
+       "sitejsprotected": "Nemáte oprávnění editovat tuto stránku s JavaScriptem, protože to může mít dopad na všechny návštěvníky",
        "mycustomcssprotected": "Nemáte oprávnění editovat tuto stránku s CSS.",
        "mycustomjsonprotected": "Nemáte oprávnění editovat tuto stránku s JSONem.",
        "mycustomjsprotected": "Nemáte oprávnění editovat tuto stránku s JavaScriptem.",
        "converter-manual-rule-error": "Detekována chyba v pravidlech manuální jazykové konverze",
        "undo-success": "Editace může být zrušena. Zkontrolujte a pak potvrďte změny zobrazené níže.",
        "undo-failure": "Editace nemohla být zrušena kvůli konfliktu mezilehlých editací.",
+       "undo-main-slot-only": "Editace nemohla být zrušena, protože zapojuje obsah mimo hlavní sloupec",
        "undo-norev": "Tuto editaci není možné vrátit, protože neexistuje nebo byla smazána.",
        "undo-nochange": "Zdá se, že editace již byla zrušena.",
        "undo-summary": "Zrušena verze $1 od uživatele [[Special:Contributions/$2|$2]] ([[User talk:$2|diskuse]])",
        "diff-paragraph-moved-toold": "Odstavec byl přesunut. Kliknutím skočíte na původní umístění.",
        "difference-missing-revision": "{{PLURAL:$2|Jedna z revizí|$2 revize|$2 revizí}} k požadovanému porovnání ($1) {{PLURAL:$2|neexistuje|neexistují|neexistuje}}.\n\nToto je obvykle způsobeno tím, že jste následovali zastaralý odkaz na historickou verzi stránky, jež byla smazána.\nPodrobnosti mohou být uvedeny v [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} knize smazaných stránek].",
        "searchresults": "Výsledky hledání",
+       "search-filter-title-prefix": "Hledání pouze ve stránkách, jejichž název začíná na „$1“",
+       "search-filter-title-prefix-reset": "Hledat ve všech stránkách",
        "searchresults-title": "Výsledky hledání „$1“",
        "titlematches": "Stránky s odpovídajícím názvem",
        "textmatches": "Stránky s odpovídajícím textem",
        "group-autoconfirmed": "Automaticky schválení uživatelé",
        "group-bot": "Roboti",
        "group-sysop": "Správci",
+       "group-interface-admin": "Správci rozhraní",
        "group-bureaucrat": "Byrokraté",
        "group-suppress": "Utajovatelé",
        "group-all": "(všichni)",
        "group-autoconfirmed-member": "automaticky {{GENDER:$1|schválený uživatel|schválená uživatelka|schválený uživatel}}",
        "group-bot-member": "{{GENDER:$1|robot|robotka}}",
        "group-sysop-member": "{{GENDER:$1|správce|správkyně|správce}}",
+       "group-interface-admin-member": "{{GENDER:$1|správce|správkyně}} rozhraní",
        "group-bureaucrat-member": "{{GENDER:$1|byrokrat|byrokratka|byrokrat}}",
        "group-suppress-member": "{{GENDER:$1|utajovatel|utajovatelka|utajovatel}}",
        "grouppage-user": "{{ns:project}}:Uživatelé",
        "grouppage-autoconfirmed": "{{ns:project}}:Automaticky schválení uživatelé",
        "grouppage-bot": "{{ns:project}}:Roboti",
        "grouppage-sysop": "{{ns:project}}:Správci",
+       "grouppage-interface-admin": "{{ns:project}}:Správci rozhraní",
        "grouppage-bureaucrat": "{{ns:project}}:Byrokraté",
        "grouppage-suppress": "{{ns:project}}:Utajovatelé",
        "right-read": "Čtení stránek",
        "right-editusercss": "Editace CSS souborů jiných uživatelů",
        "right-edituserjson": "Editace souborů s JSONem jiných uživatelů",
        "right-edituserjs": "Editace JavaScriptových souborů jiných uživatelů",
+       "right-editsitecss": "Editovat celoprojektové CSS",
+       "right-editsitejson": "Editovat celoprojektový JSON",
+       "right-editsitejs": "Editovat celoprojektový JavaScript",
        "right-editmyusercss": "Editace vlastních uživatelských CSS souborů",
-       "right-editmyuserjson": "Editace vlastní uživatelských souborů s JSONem",
+       "right-editmyuserjson": "Editace vlastních uživatelských souborů s JSONem",
        "right-editmyuserjs": "Editace vlastních uživatelských JavaScriptových souborů",
        "right-viewmywatchlist": "Prohlížení vlastního seznamu sledovaných stránek",
        "right-editmywatchlist": "Editace vlastního seznamu sledovaných stránek. Uvědomte si, že některé akce do něj mohou přidat stránky i bez tohoto oprávnění.",
        "grant-createaccount": "Zakládat účty",
        "grant-createeditmovepage": "Vytvářet, editovat a přesouvat stránky",
        "grant-delete": "Mazat stránky, revize a protokolovací záznamy",
-       "grant-editinterface": "Editovat jmenný prostor MediaWiki a uživatelské CSS/JSON/JavaScript",
+       "grant-editinterface": "Editovat jmenný prostor MediaWiki a celoprojektový/uživatelský JSON",
        "grant-editmycssjs": "Editovat váš uživatelský CSS/JSON/JavaScript",
        "grant-editmyoptions": "Změna vašich uživatelských nastavení",
        "grant-editmywatchlist": "Upravovat váš seznam sledovaných stránek",
+       "grant-editsiteconfig": "Editovat celoprojektové a uživatelské CSS/JS",
        "grant-editpage": "Editovat existující stránky",
        "grant-editprotected": "Editovat zamčené stránky",
        "grant-highvolume": "Hromadné editace",
        "rcfilters-other-review-tools": "Další kontrolní nástroje",
        "rcfilters-group-results-by-page": "Seskupit výsledky podle stránky",
        "rcfilters-activefilters": "Aktivní filtry",
+       "rcfilters-activefilters-hide": "Skrýt",
+       "rcfilters-activefilters-show": "Zobrazit",
+       "rcfilters-activefilters-hide-tooltip": "Skrýt plochu aktivních filtrů",
+       "rcfilters-activefilters-show-tooltip": "Zobrazit plochu aktivních filtrů",
        "rcfilters-advancedfilters": "Pokročilé filtry",
        "rcfilters-limit-title": "Zobrazené výsledky",
        "rcfilters-limit-and-date-label": "{{PLURAL:$1|Jedna změna|$1 změny|$1 změn}}, $2",
        "rcfilters-savedqueries-rename": "Přejmenovat",
        "rcfilters-savedqueries-setdefault": "Nastavit jako výchozí",
        "rcfilters-savedqueries-unsetdefault": "Nemít jako výchozí",
-       "rcfilters-savedqueries-remove": "Odstranit",
+       "rcfilters-savedqueries-remove": "Smazat",
        "rcfilters-savedqueries-new-name-label": "Název",
        "rcfilters-savedqueries-new-name-placeholder": "Popište účel filtru",
        "rcfilters-savedqueries-apply-label": "Vytvořit filtr",
        "rcfilters-empty-filter": "Žádné aktivní filtry. Zobrazeny jsou všechny příspěvky.",
        "rcfilters-filterlist-title": "Filtry",
        "rcfilters-filterlist-whatsthis": "Jak to funguje?",
-       "rcfilters-filterlist-feedbacklink": "Řekněte nám, co si myslíte o těchto (nových) filtrech",
+       "rcfilters-filterlist-feedbacklink": "Sdělte nám svůj názor na tyto filtrovací nástroje",
        "rcfilters-highlightbutton-title": "Zvýraznit výsledky",
        "rcfilters-highlightmenu-title": "Vybrat barvu",
        "rcfilters-highlightmenu-help": "Vyberte barvu pro zvýraznění této vlastnosti",
        "rcfilters-filter-reviewstatus-unpatrolled-label": "Neprověřené",
        "rcfilters-filter-reviewstatus-manual-description": "Editace ručně označené jako prověřené.",
        "rcfilters-filter-reviewstatus-manual-label": "Ručně prověřené",
-       "rcfilters-filter-reviewstatus-auto-description": "Editace pokročilých uživatelů, jejichž práce je autoamticky označena jako prověřená.",
+       "rcfilters-filter-reviewstatus-auto-description": "Editace pokročilých uživatelů, jejichž práce je automaticky označena jako prověřená.",
        "rcfilters-filter-reviewstatus-auto-label": "Automaticky prověřené",
        "rcfilters-filtergroup-significance": "Důležitost",
        "rcfilters-filter-minor-label": "Malé editace",
        "rcfilters-watchlist-showupdated": "Změny stránek, které jste od provedení změn nenavštívili, jsou zobrazeny <strong>tučně</strong> s vyplněnou značkou.",
        "rcfilters-preference-label": "Skrýt vylepšenou verzi posledních změn",
        "rcfilters-preference-help": "Zruší novou podobu rozhraní zavedenou v roce 2017 a všechny nástroje přidané od té doby.",
+       "rcfilters-watchlist-preference-label": "Skrýt vylepšenou verzi sledovaných stránek",
+       "rcfilters-watchlist-preference-help": "Zruší novou podobu rozhraní zavedenou v roce 2017 a všechny nástroje přidané od té doby.",
        "rcfilters-filter-showlinkedfrom-label": "Zobrazit změny stránek, na které se odkazuje",
        "rcfilters-filter-showlinkedfrom-option-label": "<strong>Stránky odkazované z</strong> vybrané stránky",
        "rcfilters-filter-showlinkedto-label": "Zobrazit změny stránek, které sem odkazují",
        "speciallogtitlelabel": "Cíl (název nebo {{ns:user}}:Jméno pro uživatele):",
        "log": "Protokolovací záznamy",
        "logeventslist-submit": "Zobrazit",
+       "logeventslist-more-filters": "Zobrazit další záznamy:",
+       "logeventslist-patrol-log": "Kniha prověřených editací",
+       "logeventslist-tag-log": "Kniha značek",
        "all-logs-page": "Všechny veřejné záznamy",
        "alllogstext": "Společné zobrazení všech dostupných protokolovacích záznamů pro {{grammar:4sg|{{SITENAME}}}}.\nZobrazení můžete zúžit výběrem typu záznamu, uživatelského jména (záleží na velikosti písmen) nebo dotčené stránky (také záleží na velikosti písmen).",
        "logempty": "Protokol neobsahuje žádný odpovídající záznam.",
        "dellogpage": "Kniha smazaných stránek",
        "dellogpagetext": "Zde je seznam posledních smazaných stránek.",
        "deletionlog": "Kniha smazaných stránek",
+       "log-name-create": "Kniha vytvoření stránek",
+       "log-description-create": "Níže se nachází seznam posledních vyvořených stránek.",
+       "logentry-create-create": "$1 {{GENDER:$2|vytvořil|vytvořila|vytvořil(a)}} stránku $3",
        "reverted": "Obnovení předchozí verze",
        "deletecomment": "Důvod:",
        "deleteotherreason": "Jiný/další důvod:",
        "uctop": "(aktuální)",
        "month": "Do měsíce:",
        "year": "Do roku:",
+       "date": "Od data (a dříve):",
        "sp-contributions-newbies": "Zobrazit příspěvky nově založených účtů",
        "sp-contributions-newbies-sub": "Noví uživatelé",
        "sp-contributions-newbies-title": "Příspěvky nových uživatelů",
        "whatlinkshere": "Odkazuje sem",
        "whatlinkshere-title": "Stránky odkazující na „$1“",
        "whatlinkshere-page": "Strana:",
-       "linkshere-2": "Na <strong>$1</strong> odkazují tyto stránky:",
-       "nolinkshere-2": "Žádná stránka na <strong>$1</strong> neodkazuje.",
-       "nolinkshere-ns-2": "Ve zvoleném jmenném prostoru na <strong>$1</strong> neodkazuje žádná stránka.",
+       "linkshere": "Na <strong>$2</strong> odkazují tyto stránky:",
+       "nolinkshere": "Žádná stránka na <strong>$2</strong> neodkazuje.",
+       "nolinkshere-ns": "Ve zvoleném jmenném prostoru na <strong>$2</strong> neodkazuje žádná stránka.",
        "isredirect": "přesměrování",
        "istemplate": "vložení",
        "isimage": "vložení souboru",
        "markedaspatrollederrornotify": "Nepodařilo se označit jako prověřené.",
        "patrol-log-page": "Kniha prověřených editací",
        "patrol-log-header": "Toto je kniha prověřených verzí.",
-       "log-show-hide-patrol": "$1 knihu záznamů patroly",
-       "log-show-hide-tag": "$1 knihu značek",
        "confirm-markpatrolled-button": "OK",
        "confirm-markpatrolled-top": "Označit revizi $3 stránky $2 jako prověřenou?",
        "deletedrevision": "Smazána stará revize $1",
        "revid": "revize $1",
        "pageid": "Stránka s ID $1",
        "rawhtml-notallowed": "Značky &lt;html&gt; nelze používat mimo běžné stránky.",
-       "gotointerwiki": "Opustit {{GENDER:4sg|{{SITENAME}}}}",
+       "gotointerwiki": "Opustit {{GRAMMAR:4sg|{{SITENAME}}}}",
        "gotointerwiki-invalid": "Zadaný název je neplatný.",
        "gotointerwiki-external": "Chystáte se opustit {{GRAMMAR:4sg|{{SITENAME}}}} a navštívit [[$2]], což je jiná webová stránka.\n\n'''[$1 Pokračovat na $1].'''",
        "undelete-cantedit": "Tuto stránku nemůžete obnovit, protože ji nejste oprávněni editovat.",
        "pagedata-text": "Tato stránka poskytuje datové rozhraní ke stránkám. Uveďte prosím název stránky v URL pomocí syntaxe pro podstránky.\n* Funguje dohadování o obsahu na základě hlavičky Accept vašeho klienta. To znamená, že data stránky budou poskytnuta ve formátu preferovaném vaším klientem.",
        "pagedata-not-acceptable": "Nenalezen odpovídající formát. Podporované MIME typy: $1",
        "pagedata-bad-title": "Neplatný název: $1.",
-       "unregistered-user-config": "Z bezpečnostních důvodů nelze načítat uživatelské podstránky s JavaScriptem, CSS nebo JSONem u neregistrovaných uživatelů."
+       "unregistered-user-config": "Z bezpečnostních důvodů nelze načítat uživatelské podstránky s JavaScriptem, CSS nebo JSONem u neregistrovaných uživatelů.",
+       "passwordpolicies-group": "Skupina",
+       "passwordpolicies-policy-minimalpasswordlength": "Heslo musí být alespoň {{PLURAL:$1|$1 znak|$1 znaky|$1 znaků}} dlouhé",
+       "passwordpolicies-policy-minimumpasswordlengthtologin": "Pro přihlášení je vyžadováno alespoň {{PLURAL:$1|$1 znak|$1 znaky|$1 znaků}} dlouhé heslo",
+       "passwordpolicies-policy-passwordcannotmatchusername": "Heslo se nemůže shodovat s uživatelským jménem",
+       "passwordpolicies-policy-passwordcannotmatchblacklist": "Heslo nesmí být v seznamu určitých zakázaných hesel",
+       "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}}"
 }
index 3620a0b..7210a74 100644 (file)
        "whatlinkshere": "Lënkùjącé",
        "whatlinkshere-title": "Starnë lënkùjącé do \"$1\"",
        "whatlinkshere-page": "Starna:",
-       "linkshere-2": "Do '''$1''' lënkùją hewòtné starnë:",
-       "nolinkshere-2": "Niżódnô starna nie lënkùje do '''$1'''.",
+       "linkshere": "Do '''$2''' lënkùją hewòtné starnë:",
+       "nolinkshere": "Niżódnô starna nie lënkùje do '''$2'''.",
        "isredirect": "starna przeczerowaniô",
        "istemplate": "doparłãczony",
        "isimage": "lënk do lopka",
index c490c2a..a6f49ec 100644 (file)
@@ -8,7 +8,8 @@
                        "ОйЛ",
                        "아라",
                        "Илья Драконов",
-                       "Vvs-dm"
+                       "Vvs-dm",
+                       "Matěj Suchánek"
                ]
        },
        "tog-oldsig": "твои нꙑнѣшьн҄ь аѵтографъ :",
        "userexists": "сѫщє польꙃєватєлꙗ имѧ пьса ⁙\nбѫди добръ · ино сѥ иꙁобрѧщи",
        "loginerror": "въхода блаꙁна",
        "createacct-error": "мѣста сътворѥниꙗ блаꙁна",
-       "loginsuccess": "'''нꙑнѣ тꙑ {{GENDER|въшьлъ|въшьла}} въ {{grammar:locative|{{SITENAME}}}} подь имьньмъ ⁖ $1 ⁖.'''",
+       "loginsuccess": "'''нꙑнѣ тꙑ {{GENDER:|въшьлъ|въшьла}} въ {{grammar:locative|{{SITENAME}}}} подь имьньмъ ⁖ $1 ⁖.'''",
        "mailmypassword": "нова таина слова оуставлѥниѥ",
        "accountcreated": "мѣсто сътворєно ѥстъ",
        "accountcreatedtext": "польꙃєватєльско мѣсто [[{{ns:User}}:$1|$1]] ([[{{ns:User talk}}:$1|бєсѣда]]) сътворєно бѣ",
        "whatlinkshere": "дос҄ьдєщьнѩ съвѧꙁиѥ",
        "whatlinkshere-title": "страницѧ ижє съ ⁖ $1 ⁖ съвѧꙁи имѫтъ",
        "whatlinkshere-page": "страница :",
-       "linkshere-2": "сѩ страницѧ съ <strong>$1</strong> съвѧꙁи имѫтъ :",
+       "linkshere": "сѩ страницѧ съ <strong>$2</strong> съвѧꙁи имѫтъ :",
        "isredirect": "прѣнаправлѥниѥ",
        "istemplate": "внѫтри страницѧ",
        "isimage": "дѣла съвѧꙁь",
index 18fd2f6..3a3478c 100644 (file)
        "toc": "Тупмалли",
        "showtoc": "кăтартмалла",
        "hidetoc": "кӑтартмалла мар",
+       "collapsible-expand": "Çавăр",
        "thisisdeleted": "$1 пăхса каялла тавăрмалла-и?",
        "viewdeleted": "$1 пăхар-и?",
        "restorelink": "{{PLURAL:$1|кăларса пăрахнă тӳрлетнине|$1 кăларса пăрахнă тӳрлетнисене}}",
        "searchprofile-articles": "Статьясем",
        "searchprofile-images": "Мультимедиа",
        "searchprofile-everything": "Пур ҫӗрте",
-       "searchprofile-advanced": "Ð\90нлÓ\91лаÑ\82нÓ\91",
+       "searchprofile-advanced": "СаÑ\80лакаÑ\80аÑ\85",
        "searchprofile-articles-tooltip": "$1 -ре шырани",
        "searchprofile-images-tooltip": "Файăлсене шырани",
        "searchprofile-everything-tooltip": "Мӗнпур элсенче (сӳтсе явнинче те) шыра",
-       "searchprofile-advanced-tooltip": "ЯÑ\82аÑ\80лÓ\91 Ñ\8fÑ\82 Ñ\82алккÓ\91Ñ\88Ó\97сенче шыра",
+       "searchprofile-advanced-tooltip": "Ð\9fанÄ\83 Ñ\8fÑ\82 Ñ\85Ñ\83Ñ\88Ñ\88исенче шыра",
        "search-result-size": "$1 ({{PLURAL:$2|1 сăмах|$2 сăмах}})",
        "search-category": "(категори $1)",
        "search-interwiki-caption": "Тăван проектсем",
        "searchrelated": "çыхăнă",
        "showingresults": "Аяларах эсир <strong>$2</strong> пуçласа кăтартнă <strong>$1</strong> йĕркене куратăр.",
        "powersearch-legend": "Анлă шырав",
+       "powersearch-ns": "Ят хушшисенче шыра:",
+       "powersearch-togglelabel": "Тĕрĕсреххи:",
+       "powersearch-toggleall": "Пурне те",
        "powersearch-togglenone": "Нимĕнте",
        "search-external": "Тулти шырамалли",
        "preferences": "Ĕнерлевсем",
        "recentchanges-legend-plusminus": "(<em>±123</em>)",
        "recentchanges-submit": "Кăтарт",
        "rcfilters-legend-heading": "<strong>Кĕскетнисем:</strong>",
+       "rcfilters-other-review-tools": "Урăх пăхмаллисем",
+       "rcfilters-show-new-changes": "Çĕнĕ улăшăннисем",
+       "rcfilters-filterlist-title": "Фильтрсем",
+       "rcfilters-filter-editsbyself-label": "Хăвăр улăштарнисем",
+       "rcfilters-filter-editsbyother-label": "Урăххисем улăштарнисем",
        "rcfilters-filter-user-experience-level-newcomer-label": "Çĕнĕ хутшăнакансем",
+       "rcfilters-filter-user-experience-level-learner-label": "Вĕренекенсем",
+       "rcfilters-filtergroup-automated": "Автоматлă хушнисем",
+       "rcfilters-filter-bots-label": "Бот",
+       "rcfilters-filter-humans-label": "Çын (бот мар)",
+       "rcfilters-filtergroup-significance": "Пĕлтерни",
+       "rcfilters-filter-minor-label": "Кăштах тӳрлетнисем",
+       "rcfilters-filter-major-label": "Ахаль тӳрлетнисем",
+       "rcfilters-filter-categorization-label": "Категорине улăштарнисем",
+       "rcfilters-filtergroup-lastRevision": "Юлашки версисем",
+       "rcfilters-filter-lastrevision-label": "Хальхи верси",
+       "rcfilters-filter-previousrevision-label": "Юлашки верси мар",
        "rclistfrom": "$2, $3 тытăнса çĕнĕ улăшăнисене кăтартни",
        "rcshowhideminor": "пĕчĕк тӳрлетнисене $1",
        "rcshowhideminor-show": "кăтартмалла",
        "longpages": "Вăрăм страницăсем",
        "deadendpages": "Нимĕнпе те çыхăнман страницăсем",
        "protectedpages": "Хӳтĕленĕ страницăсем",
+       "protectedpages-filters": "Фильтрсем:",
        "protectedtitles": "Юраман ятсем",
        "listusers": "Хутшăнакансен списокĕ",
        "newpages": "Çĕнĕ страницăсем",
        "sp-contributions-submit": "Шыра",
        "whatlinkshere": "Кунта каçаканнисем",
        "whatlinkshere-title": "\"$1\" çине каçакан страницăсем",
-       "linkshere-2": "<strong>$1</strong> çине каçакан страницăсем:",
-       "nolinkshere-2": "'''$1''' страница çине ытти страницăсенчен килме пулмасть.",
+       "linkshere": "<strong>$2</strong> çине каçакан страницăсем:",
+       "nolinkshere": "'''$2''' страница çине ытти страницăсенчен килме пулмасть.",
        "whatlinkshere-prev": "{{PLURAL:$1|унчченхи|унчченхи $1}}",
        "whatlinkshere-next": "{{PLURAL:$1|урăххи|урăххисем $1}}",
        "whatlinkshere-links": "← каçаканнисем",
        "whatlinkshere-hideredirs": "куçарнисене $1",
        "whatlinkshere-hidelinks": "Каçаканнисене $1",
-       "whatlinkshere-filters": "Ð\90ласем",
+       "whatlinkshere-filters": "ФилÑ\8cÑ\82Ñ\80сем",
        "whatlinkshere-submit": "Ту",
        "blockip": "{{GENDER:$1|хутшăнакана}} чар",
        "ipaddressorusername": "IP адрес е усă куракан ят:",
        "tooltip-pt-watchlist": "Эсир пăхакан страницисем",
        "tooltip-pt-mycontris": "Сирĕн хушнисем",
        "tooltip-pt-anoncontribs": "Ку IP адреспа тӳрлетнисем",
-       "tooltip-pt-login": "Ð\9aÓ\97ме ÐºÐ¸Ñ\80леÑ\85 Ð¼Ð°Ñ\80\85а Ñ\82а, Ð°Ñ\80а Ð°Ð²Ð°Ð½Ñ\80аÑ\85.",
+       "tooltip-pt-login": "Ð\90ккаÑ\83нÑ\82 Ñ\82Ñ\83Ñ\81а ÐºÄ\95Ñ\80Ä\95Ñ\80, ÐºÄ\95меÑ\81Ä\95Ñ\80 Ñ\82е Ñ\8eÑ\80аÑ\82Ñ\8c",
        "tooltip-pt-logout": "Сеансне пĕтер",
-       "tooltip-pt-createaccount": "Ð\90ккаÑ\83нÑ\82 Ñ\82Ñ\83 Ñ\82а Ñ\81иÑ\81Ñ\82емÓ\91на ÐºÓ\97Ñ\80. Ð\9fаллаÑ\85, Ñ\83нÑ\81Ó\91Ñ\80аÑ\85 Ñ\82а Ñ\8eÑ\80аÑ\82Ñ\8c, Ð°Ð½Ñ\87аÑ\85 Ñ\82а Ð°ÐºÐºÐ°Ñ\83нÑ\82па ÐºÓ\97ни Ð»Ð°Ð¹Ó\91Ñ\85Ñ\80аÑ\85.",
+       "tooltip-pt-createaccount": "Ð\9aÄ\95ме Ð°ÐºÐºÐ°Ñ\83нÑ\82 Ñ\82Ä\83вÄ\83Ñ\80, ÐºÄ\95меÑ\81Ä\95Ñ\80 Ñ\82е Ñ\8eÑ\80аÑ\82Ñ\8c",
        "tooltip-ca-talk": "Статьяна сӳтсе явасси",
        "tooltip-ca-edit": "Кăна тӳрлет",
        "tooltip-ca-addsection": "Çĕнĕ пай ту",
        "specialpages-group-media": "Медиа-материалсемпе тултарăшсем",
        "specialpages-group-users": "Хутшăнакансем тата правасем",
        "specialpages-group-highuse": "Нумай усă куракан страницăсем",
-       "tag-list-wrapper": "([[Special:Tags|$1 метка]]: $2)",
+       "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|Тег|Тегсем}}]]: $2)",
+       "tags-title": "Тегсем",
        "compare-submit": "Танлаштар",
        "htmlform-selectorother-other": "Урăххи",
        "htmlform-no": "Çук",
index fc7cf59..6e5cfb8 100644 (file)
@@ -20,7 +20,8 @@
                        "Dafyddt",
                        "Jdforrester",
                        "Irus",
-                       "Fitoschido"
+                       "Fitoschido",
+                       "Nrowe"
                ]
        },
        "tog-underline": "Tanlinellu cysylltiadau:",
@@ -57,7 +58,7 @@
        "tog-watchlisthideminor": "Cuddio golygiadau bychain rhag y rhestr wylio",
        "tog-watchlisthideliu": "Cuddio golygiadau gan ddefnyddwyr mewngofnodedig rhag y rhestr wylio",
        "tog-watchlistreloadautomatically": "Ail-lwyther y Rhestr wylio yn otomatigpan newider ffiltr (angen JavaScript)",
-       "tog-watchlistunwatchlinks": "Ychwanegwch ddolenau 'gwylio/heb eu gwylio' i'r cofnodion rydych yn eu gwylio (angen JavaScript)",
+       "tog-watchlistunwatchlinks": "Ychwanegwch farciau gweld/heb weld  ({{int:Watchlist-unwatch}}/{{int:Watchlist-unwatch-undo}}) ar ddalennau rydych yn eu wgylio - gyda newidiadau (angen JavaScript)",
        "tog-watchlisthideanons": "Cuddio golygiadau gan ddefnyddwyr anhysbys rhag y rhestr wylio",
        "tog-watchlisthidepatrolled": "Cuddio golygiadau sydd wedi derbyn ymweliad patrôl rhag y rhestr wylio",
        "tog-watchlisthidecategorization": "Cuddiwch y categoriau",
        "resetpass-submit-loggedin": "Newidier y cyfrinair",
        "resetpass-submit-cancel": "Diddymu",
        "resetpass-wrong-oldpass": "Mae'r cyfrinair dros dro neu gyfredol yn annilys.\nEfallai eich bod wedi newid eich cyfrinair neu wedi gofyn am gyfrinair dros dro newydd.",
-       "resetpass-recycled": "Ailosodwch eich cyfrinair os gwelwch yn dda i rywbeth heblaw eich cyfrinair cyfredol.",
+       "resetpass-recycled": "Ailosodwch eich cyfrinair i rywbeth heblaw eich cyfrinair cyfredol.",
        "resetpass-temp-emailed": "Rydych wedi mewngofnodi gyda chod dros dro. I gwbwlhau hyn, mae'n rhaid i chi ailosod eich cyfrinair yma:",
        "resetpass-temp-password": "Cyfrinair dros dro:",
        "resetpass-abort-generic": "Mae estyniad wedi atal newid y cyfrinair.",
        "resetpass-expired": "Mae oes eich cyfrinair wedi dod i ben. Gosodwch gyfrinair newydd i fewngofnodi.",
-       "resetpass-expired-soft": "Mae eich cyfrinair wedi dod i ben ac mae'n rhaid ei ailosod. Dewisiwch gyfrinair newydd sbon nawr, neu cliciwch \"{{int:authprovider-resetpass-skip-label}}\" a'i ailosod rywdro eto.",
-       "resetpass-validity-soft": "Nid yw eich cyfrinair $1 yn dal ddilys.\n\nDewisiwch gyfrinair newydd nawr, neu gliciwch \"{{int:authprovider-resetpass-skip-label}}\" i'w ailosod yn nes ymlaen.",
+       "resetpass-expired-soft": "Mae eich cyfrinair wedi dod i ben ac mae'n rhaid ei ailosod. Dewisiwch gyfrinair newydd sbon nawr, neu gliciwch \"{{int:authprovider-resetpass-skip-label}}\" i'w ailosod rywdro eto.",
+       "resetpass-validity-soft": "Nid yw eich cyfrinair $1 yn ddilys.\n\nDewisiwch gyfrinair newydd nawr, neu gliciwch \"{{int:authprovider-resetpass-skip-label}}\" i'w ailosod.",
        "passwordreset": "Ailosod cyfrinair",
        "passwordreset-text-one": "Cwblhewch y ffurflen hon er mwyn ailosod eich cyfrinair.",
        "passwordreset-text-many": "{{PLURAL:$1|Llanwch un o'r blychau er mwyn derbyn cyfrinair dros dro mewn ebost.}}",
        "savechanges": "Cadw'r holl newidiadau",
        "publishpage": "Cyhoeddi tudalen",
        "publishchanges": "Cyhoeddi newidiadau",
+       "savearticle-start": "Cadw'r ddalen...",
+       "savechanges-start": "Cadw'r newidiadau...",
+       "publishpage-start": "Cyhoeddi'r ddalen...",
+       "publishchanges-start": "Cyhoeddi'r newidiadau...",
        "preview": "Rhagolwg",
        "showpreview": "Dangos rhagolwg",
        "showdiff": "Dangos newidiadau",
        "subject-preview": "Rhagolwg pwnc:",
        "previewerrortext": "Cafwyd nam tra'n ceisio creu rhagolwg o'r newidiadau.",
        "blockedtitle": "Mae'r defnyddiwr hwn wedi cael ei flocio",
-       "blockedtext": "'''Mae eich enw defnyddiwr neu gyfeiriad IP wedi cael ei flocio.'''\n\n$1 a osododd y bloc.\nY rheswm a roddwyd dros y blocio yw: ''$2''.\n\n*Dechreuodd y bloc am: $8\n*Bydd y bloc yn dod i ben am: $6\n*Bwriadwyd blocio: $7\n\nGallwch gysylltu â $1 neu un arall o'r [[{{MediaWiki:Grouppage-sysop}}|gweinyddwyr]] i drafod y bloc.\nSylwch mai dim ond y rhai sydd wedi gosod cyfeiriad e-bost yn eu [[Special:Preferences|dewisiadau defnyddiwr]], a hwnnw heb ei flocio, sydd yn gallu 'anfon e-bost at ddefnyddiwr' trwy'r wici.\n$3 yw eich cyfeiriad IP presennol. Cyfeirnod y bloc yw #$5.\nPan yn ysgrifennu at weinyddwr, cofiwch gynnwys yr holl fanylion uchod, os gwelwch yn dda.",
-       "autoblockedtext": "Rhoddwyd bloc yn awtomatig ar eich cyfeiriad IP oherwydd iddo gael ei ddefnyddio gan ddefnyddiwr arall, a bod bloc wedi ei roi ar hwnnw gan $1.\nY rheswm a roddwyd dros y bloc oedd:\n\n:''$2''\n\n*Dechreuodd y bloc am: $8\n*Daw'r bloc i ben am: $6\n*Bwriadwyd blocio: $7\n\nGallwch gysylltu â $1 neu un arall o'r [[{{MediaWiki:Grouppage-sysop}}|gweinyddwyr]] i drafod y bloc.\n\nSylwch mai dim ond y rhai sydd wedi gosod cyfeiriad e-bost yn eu [[Special:Preferences|dewisiadau defnyddiwr]], a hwnnw heb ei flocio, sydd yn gallu 'anfon e-bost at ddefnyddiwr' trwy'r wici.\n\nEich cyfeiriad IP presennol yw $3. Cyfeirnod y bloc yw $5. Nodwch y manylion hyn wrth drafod y bloc.",
+       "blockedtext": "Mae eich enw defnyddiwr neu gyfeiriad IP wedi cael ei flocio.</strong>\n\n$1 a osododd y bloc.\nY rheswm a roddwyd dros y blocio yw: <em>$2</em>.\n\n*Dechreuodd y bloc am: $8\n*Bydd y bloc yn dod i ben am: $6\n*Defnyddiwr a flociwyd: $7\n\nGallwch gysylltu â $1 neu un arall o'r [[{{MediaWiki:Grouppage-sysop}}|gweinyddwyr]] i drafod y bloc.\nSylwch mai dim ond y rhai sydd wedi gosod cyfeiriad e-bost yn eu [[Special:Preferences|dewisiadau defnyddiwr]], a hwnnw heb ei flocio, sy'n gallu 'anfon e-bost at ddefnyddiwr' trwy'r wici.\n$3 yw eich cyfeiriad IP presennol. Cyfeirnod y bloc yw #$5.\nPan yn ysgrifennu at weinyddwr, cofiwch gynnwys yr holl fanylion uchod, os gwelwch yn dda.",
+       "autoblockedtext": "Rhoddwyd bloc yn awtomatig ar eich cyfeiriad IP oherwydd iddo gael ei ddefnyddio gan ddefnyddiwr arall, a bod bloc wedi ei roi ar hwnnw gan $1.\nY rheswm a roddwyd dros y bloc oedd:\n\n:<em>$2</em>\n\n*Dechreuodd y bloc am: $8\n*Daw'r bloc i ben am: $6\n*Bwriadwyd blocio: $7\n\nGallwch gysylltu â $1 neu un arall o'r [[{{MediaWiki:Grouppage-sysop}}|gweinyddwyr]] i drafod y bloc.\n\nSylwch mai dim ond y rhai sydd wedi gosod cyfeiriad e-bost yn eu [[Special:Preferences|dewisiadau defnyddiwr]], a hwnnw heb ei flocio, sydd yn gallu 'anfon e-bost at ddefnyddiwr' trwy'r wici.\n\nEich cyfeiriad IP presennol yw $3. Cyfeirnod y bloc yw $5. Nodwch y manylion hyn wrth drafod y bloc.",
+       "systemblockedtext": "Mae eich enw defnyddiwr neu eich cyfeiriad IP wedi'i flocio gan MediaWiki.\nY rheswm yw:\n\n:<em>$2</em>\n\n* Dechrau'r bloc: $8\n* Daw'r bloc i ben: $6\n* Y person a geisiwyd ei flocio: $7\n\nEich cyfeiriad IP presennol yw $3.\nPan yn ysgrifennu at weinyddwr, cofiwch gynnwys yr holl fanylion uchod, os gwelwch yn dda.",
        "blockednoreason": "dim rheswm wedi ei roi",
        "whitelistedittext": "Rhaid $1 i olygu tudalennau.",
        "confirmedittext": "Mae'n rhaid i chi gadarnhau eich cyfeiriad e-bost cyn y gallwch ddechrau golygu tudalennau.\nGosodwch eich cyfeiriad e-bost drwy eich [[Special:Preferences|dewisiadau defnyddiwr]] ac yna'i gadarnhau, os gwelwch yn dda.",
        "userjspreview": "'''Cofiwch -- dim ond rhagolwg o'ch JavaScript yw hwn; nid yw wedi'i gadw eto!'''",
        "sitecsspreview": "'''Cofiwch - dim ond rhagolwg o'ch CSS yw hwn.'''\n'''Nid yw wedi'i gadw eto!'''",
        "sitejspreview": "'''Cofiwch - dim ond rhagolwg o'ch côd JavaScript yw hwn.'''\n'''Nid yw wedi'i rhoi ar gadw eto!'''",
-       "userinvalidconfigtitle": "'''Rhybudd:''' Nid oes gwedd o'r enw \"$1\".\nCofiwch bod y tudalennau .css a .js yn defnyddio llythrennau bach, e.e. {{ns:user}}:Foo/vector.css yn hytrach na {{ns:user}}:Foo/Vector.css.",
+       "userinvalidconfigtitle": "<strong>Rhybudd:</strong> Nid oes gwedd o'r enw \"$1\".\nCofiwch bod y tudalennau .css a .js yn defnyddio llythrennau bach, e.e. {{ns:user}}:Foo/vector.css yn hytrach na {{ns:user}}:Foo/Vector.css.",
        "updated": "(Diweddariad)",
        "note": "'''Dalier sylw:'''",
        "previewnote": "'''Cofiwch taw rhagolwg yw hwn.''' Nid yw eich gwaith wedi ei roi ar gadw eto!",
        "longpageerror": "'''GWALL: Mae'r testun yr ydych wedi ei osod yma yn {{PLURAL:$1|$1 cilobeit}} o hyd, ac yn hwy na'r hyd eithaf o {{PLURAL:$2|$2}} cilobeit.\nNi ellir ei roi ar gadw.'''",
        "readonlywarning": "<strong>Rhybudd: Mae'r gronfa ddata wedi'i chloi am gyfnod er mwyn cynnal a chadw, felly fyddwch chi ddim yn gallu cadw'ch golygiadau ar hyn o bryd.</strong>\nGallwch gopïo'r testun a'i gludo i ffeil destun er mwyn ei gadw tan yn hwyrach.\n\nCynigiodd y gweinyddwr a glodd y gronfa ddata y rheswm hwn dros ei chloi: $1",
        "protectedpagewarning": "'''RHYBUDD: Mae'r dudalen hon wedi'i diogelu. Dim ond gweinyddwyr sydd yn gallu ei golygu.'''\nDyma'r cofnod lòg diweddaraf, er gwybodaeth:",
-       "semiprotectedpagewarning": "'''Sylwer:''' Mae'r dudalen hon wedi ei chloi; dim ond defnyddwyr cofrestredig a allant ei golygu.\nDyma'r cofnod lòg diweddaraf, er gwybodaeth:",
-       "cascadeprotectedwarning": "<strong>Gofal:</strong> Mae'r ddalen hon wedi ei chloi fel mai dim ond defnyddwyr â [[Special:ListGroupRights|hawliau arbennig]] all olygu, gan fod y ddalen yn cael ei dynnu i fewn i'r dalennau canlynol:",
+       "semiprotectedpagewarning": "<strong>Sylwer:</strong> Mae'r ddalen hon wedi ei chloi; dim ond defnyddwyr cofrestredig a allant ei golygu.\nDyma'r cofnod lòg diweddaraf, er gwybodaeth:",
+       "cascadeprotectedwarning": "<strong>Gofal:</strong> Mae'r ddalen hon wedi ei chloi fel mai dim ond defnyddwyr â [[Special:ListGroupRights|hawliau arbennig]] all olygu, gan fod y ddalen yn cael ei dynnu i fewn i'r {{PLURAL:$1|ddalen|dalennau}} canlynol:",
        "titleprotectedwarning": "'''RHYBUDD:  Mae'r dudalen hon wedi ei chloi; dim ond rhai defnyddwyr sydd â'r [[Special:ListGroupRights|gallu]] i'w chreu.'''\nDyma'r cofnod lòg diweddaraf, er gwybodaeth:",
        "templatesused": "Defnyddir y {{PLURAL:$1|nodyn hwn|nodyn hwn|nodiadau hyn|nodiadau hyn|nodiadau hyn|nodiadau hyn}} yn y dudalen hon:",
        "templatesusedpreview": "Defnyddir y {{PLURAL:$1|nodyn hwn|nodyn hwn|nodiadau hyn|nodiadau hyn|nodiadau hyn|nodiadau hyn}} yn y rhagolwg hwn:",
        "rcfilters-filter-newpages-description": "Golygiadau creu dalennau",
        "rcfilters-filter-categorization-label": "Newidiadau i'r Categoriau",
        "rcfilters-filter-categorization-description": "Cofnodion y dalennau a ychwanegwyd neu a symudwyd o'r categoriau.",
-       "rcfilters-filter-logactions-label": "Gweithredoedd a logiwyd",
+       "rcfilters-filter-logactions-label": "Gwriansow kovskrifys",
        "rcfilters-filtergroup-lastRevision": "Yr adolygiadau diweddaraf",
        "rcfilters-filter-lastrevision-label": "Yr adolygiad diweddaraf",
        "rcfilters-filter-lastrevision-description": "Dim ond yn newidiadau diweddaraf i'r ddalen.",
        "whatlinkshere": "Beth sy'n cysylltu yma",
        "whatlinkshere-title": "Tudalennau sy'n cysylltu â \"$1\"",
        "whatlinkshere-page": "Tudalen:",
-       "linkshere-2": "Mae'r tudalennau isod yn cysylltu â '''$1''':",
-       "nolinkshere-2": "Nid oes cyswllt ar unrhyw dudalen arall syn arwain at '''$1'''.",
-       "nolinkshere-ns-2": "Nid oes cyswllt ar unrhyw dudalen yn y parth dewisedig sy'n arwain at '''$1'''.",
+       "linkshere": "Mae'r tudalennau isod yn cysylltu â '''$2''':",
+       "nolinkshere": "Nid oes cyswllt ar unrhyw dudalen arall syn arwain at '''$2'''.",
+       "nolinkshere-ns": "Nid oes cyswllt ar unrhyw dudalen yn y parth dewisedig sy'n arwain at '''$2'''.",
        "isredirect": "tudalen ailgyfeirio",
        "istemplate": "cynhwysiad",
        "isimage": "cyswllt ffeil",
        "markedaspatrollederrornotify": "Methwyd rhoi marc ymweliad patrôl arni.",
        "patrol-log-page": "Lòg patrolio",
        "patrol-log-header": "Mae'r lòg hwn yn dangos y golygiadau sydd wedi derbyn ymweliad patrôl.",
-       "log-show-hide-patrol": "$1 lòg patrolio",
        "confirm-markpatrolled-button": "Iawn",
        "confirm-markpatrolled-top": "Nodi fod diwygiad $3 o $2 wedi cael sêl-bendith golygydd?",
        "deletedrevision": "Wedi dileu hen ddiwygiad $1.",
index 067c6fc..ef2234c 100644 (file)
@@ -68,7 +68,8 @@
                        "EeveeSylveon",
                        "Kenn.jensen",
                        "Saederup92",
-                       "Fitoschido"
+                       "Fitoschido",
+                       "Jorn Ari"
                ]
        },
        "tog-underline": "Understreg henvisninger:",
        "savechanges": "Gem ændringer",
        "publishpage": "Offentliggør side",
        "publishchanges": "Offentliggør ændringer",
+       "savearticle-start": "Gem side...",
+       "savechanges-start": "Gem ændringer...",
+       "publishpage-start": "Offentliggør side...",
+       "publishchanges-start": "Offentliggør ændringer...",
        "preview": "Forhåndsvisning",
        "showpreview": "Forhåndsvisning",
        "showdiff": "Vis ændringer",
        "subject-preview": "Forhåndsvisning af emne/overskrift:",
        "previewerrortext": "Der opstod en fejl under forsøget på at lave en forhåndsvisning af dine ændringer.",
        "blockedtitle": "Du eller din IP-adresse er blokeret",
-       "blockedtext": "'''Dit brugernavn eller din IP-adresse er blevet blokeret.'''\n\nBlokeringen er foretaget af $1.\nDen anførte grund er ''$2''.\n\nBlokeringen starter: $8\nBlokeringen udløber: $6\nBlokeringen er rettet mod: $7\n\nDu kan kontakte $1 eller en af de andre [[{{MediaWiki:Grouppage-sysop}}|administratorer]] for at diskutere blokeringen.\nDu kan ikke bruge funktionen 'e-mail til denne bruger' medmindre der er angivet en gyldig e-mailadresse i dine\n[[Special:Preferences|kontoindstillinger]], og du ikke er blevet blokeret fra at bruge den.\n\nDin nuværende IP-adresse er $3, og blokerings-id er #$5.\nAngiv venligst alle ovenstående detaljer ved henvendelser om blokeringen.",
+       "blockedtext": "<strong>Dit brugernavn eller din IP-adresse er blevet blokeret.</strong>\n\nBlokeringen er foretaget af $1.\nDen anførte grund er <em>$2</em>.\n\nBlokeringen starter: $8\nBlokeringen udløber: $6\nBlokeringen er rettet mod: $7\n\nDu kan kontakte $1 eller en af de andre [[{{MediaWiki:Grouppage-sysop}}|administratorer]] for at diskutere blokeringen.\nDu kan ikke bruge funktionen \"{{int:emailuser}}\" medmindre der er angivet en gyldig e-mailadresse i dine [[Special:Preferences|kontoindstillinger]], og du ikke er blevet blokeret fra at bruge den.\n\nDin nuværende IP-adresse er $3, og blokerings-id er #$5.\nAngiv venligst alle ovenstående detaljer ved henvendelser om blokeringen.",
        "autoblockedtext": "Din IP-adresse er blevet blokeret automatisk fordi den blev brugt af en anden bruger som er blevet blokeret af $1.\nBegrundelsen for det er:\n\n:''$2''\n\n* Blokeringsperiodens start: $8\n* Blokeringen udløber: $6\n* Blokeringen er ment for: $7\n\nDu kan kontakte $1 eller en af de andre [[{{MediaWiki:Grouppage-sysop}}|administratorer]] for at diskutere blokeringen.\n\nBemærk at du ikke kan bruge funktionen \"e-mail til denne bruger\" medmindre du har en gyldig e-mailadresse registreret i din [[Special:Preferences|brugerindstilling]], og du ikke er blevet blokeret fra at bruge den.\n\nDin nuværende IP-adresse er $3, og blokerings-id'et er #$5.\nAngiv venligst alle de ovenstående detaljer ved eventuelle henvendelser.",
        "systemblockedtext": "Dit brugernavn eller din IP-adresse er automatisk blokeret af MediaWiki.\nBegrundelsen for det er:\n\n:<em>$2</em>\n\n* Blokeringsperiodens start: $8\n* Blokeringen udløber: $6\n* Blokeringen er ment for: $7\n\nDin nuværende IP-adresse er $3.\nAngiv venligst alle de ovenstående detaljer ved eventuelle henvendelser.",
        "blockednoreason": "ingen begrundelse givet",
        "rcfilters-other-review-tools": "Andre gennemgangsværktøjer",
        "rcfilters-group-results-by-page": "Grupper resultater efter side",
        "rcfilters-activefilters": "Aktive filtre",
+       "rcfilters-activefilters-hide": "Skjul",
+       "rcfilters-activefilters-show": "Vis",
        "rcfilters-advancedfilters": "Avancerede filtre",
-       "rcfilters-limit-title": "Ændringer som skal vises",
+       "rcfilters-limit-title": "Antal resultater som skal vises",
+       "rcfilters-limit-and-date-label": "$1 {{PLURAL:$1|ændring|ændringer}}, $2",
        "rcfilters-days-title": "De sidste dage",
        "rcfilters-hours-title": "De sidste timer",
        "rcfilters-days-show-days": "$1 {{PLURAL:$1|dag|dage}}",
        "rcfilters-days-show-hours": "$1 {{PLURAL:$1|time|timer}}",
        "rcfilters-highlighted-filters-list": "Fremhævede: $1",
        "rcfilters-quickfilters": "Gemte filtre",
-       "rcfilters-quickfilters-placeholder-title": "Ingen links gemt endnu",
+       "rcfilters-quickfilters-placeholder-title": "Ingen filtre gemt endnu",
        "rcfilters-savedqueries-defaultlabel": "Gemte filtre",
        "rcfilters-savedqueries-rename": "Omdøb",
        "rcfilters-savedqueries-setdefault": "Vælg som grundindstilling",
        "rcfilters-savedqueries-unsetdefault": "Fravælg som grundindstilling",
-       "rcfilters-savedqueries-remove": "Fjern",
+       "rcfilters-savedqueries-remove": "Slet",
        "rcfilters-savedqueries-new-name-label": "Navn",
        "rcfilters-savedqueries-new-name-placeholder": "Beskriv formålet med filteret",
        "rcfilters-savedqueries-apply-label": "Opret filter",
        "rcfilters-filtergroup-userExpLevel": "Brugerregistrering og -erfaring",
        "rcfilters-filter-user-experience-level-registered-label": "Registrerede",
        "rcfilters-filter-user-experience-level-registered-description": "Indloggede brugere",
-       "rcfilters-filter-user-experience-level-unregistered-label": "Uregistrerede",
+       "rcfilters-filter-user-experience-level-unregistered-label": "Uregistreret",
        "rcfilters-filter-user-experience-level-unregistered-description": "Redaktører, der ikke er logget ind.",
        "rcfilters-filter-user-experience-level-newcomer-label": "Nybegyndere",
        "rcfilters-filter-user-experience-level-newcomer-description": "Registrerede brugere som har færre end 10 redigeringer eller 4 dages aktivitet.",
        "rcfilters-filter-user-experience-level-learner-label": "Let øvede",
-       "rcfilters-filter-user-experience-level-learner-description": "Mere erfaring end \"nybegyndere\" men mindre end \"erfarne brugere\".",
+       "rcfilters-filter-user-experience-level-learner-description": "Registrerede brugere med mere erfaring end \"nybegyndere\" men mindre end \"erfarne brugere\".",
        "rcfilters-filter-user-experience-level-experienced-label": "Erfarne brugere",
        "rcfilters-filter-user-experience-level-experienced-description": "Registrerede skribenter med mere end 500 redigeringer og 30 dages aktivitet.",
        "rcfilters-filtergroup-automated": "Automatiserede bidrag",
        "rcfilters-filter-humans-label": "Menneske (ikke bot)",
        "rcfilters-filter-humans-description": "Redigeringer udført af mennesker.",
        "rcfilters-filtergroup-reviewstatus": "Gennemgangsstatus",
+       "rcfilters-filter-reviewstatus-unpatrolled-description": "Redigeringer som ikke er manuelt eller automatisk mærket som patruljerede.",
        "rcfilters-filter-reviewstatus-unpatrolled-label": "Upatruljerede",
+       "rcfilters-filter-reviewstatus-manual-description": "Redigeringer som manuelt er mærket som patruljeret.",
+       "rcfilters-filter-reviewstatus-manual-label": "Patruljeret manuelt",
+       "rcfilters-filter-reviewstatus-auto-label": "Autopatruljeret",
        "rcfilters-filtergroup-significance": "Betydning",
        "rcfilters-filter-minor-label": "Mindre redigeringer",
        "rcfilters-filter-minor-description": "Redigeringer som ophavsmanden har markeret som mindre.",
        "recentchangeslinked-feed": "Relaterede ændringer",
        "recentchangeslinked-toolbox": "Relaterede ændringer",
        "recentchangeslinked-title": "Ændringer der relaterer til \"$1\"",
-       "recentchangeslinked-summary": "Indtast et sidenavn for at sændringer på sider henvist til eller fra den side. (For at se medlemmer af en kategori indtast Category:Kategorinavn). Ændringer til sider på [[Special:Watchlist|din overvågningsliste]] er vist med <strong>fed</strong> skrift.",
+       "recentchangeslinked-summary": "Indtast et sidenavn for at sændringer på sider henvist til eller fra den side. (For at se medlemmer af en kategori indtast {{ns:category}}:Kategorinavn). Ændringer til sider på [[Special:Watchlist|din overvågningsliste]] er vist med <strong>fed</strong> skrift.",
        "recentchangeslinked-page": "Sidenavn:",
        "recentchangeslinked-to": "Vis ændringer i sider der henviser til den angivne side i stedet",
        "recentchanges-page-added-to-category": "[[:$1]] tilføjet til kategori",
        "backend-fail-read": "Kunne ikke læse filen $1.",
        "backend-fail-create": "Kunne ikke gemme filen $1.",
        "backend-fail-maxsize": "Kunne ikke gemme filen $1, da den er større end {{PLURAL:$2|en byte|$2 bytes}}.",
-       "backend-fail-readonly": "Lagrings-backend \"$1\" er i øjeblikket skrivebeskyttet. Den angivne begrundelse var: \" $2 \"",
+       "backend-fail-readonly": "Lagrings-backend \"$1\" er i øjeblikket skrivebeskyttet. Den angivne begrundelse er: <em>$2</em>",
        "backend-fail-synced": "Filen \"$1\" er i en inkonsistent tilstand inden for de interne lagringsbackends",
        "backend-fail-connect": "Kunne ikke forbinde til lagringsbackend \"$1\".",
        "backend-fail-internal": "En ukendt fejl opstod i filbackend \"$1\".",
        "dellogpage": "Sletningslog",
        "dellogpagetext": "Herunder vises de nyeste sletninger. Alle tider er serverens tid.",
        "deletionlog": "sletningslog",
+       "log-name-create": "Sideoprettelseslog",
+       "log-description-create": "Nedenfor er en liste over de senest oprettede sider.",
+       "logentry-create-create": "$1 {{GENDER:$2|oprettede}} siden $3",
        "reverted": "Gendannet en tidligere version",
        "deletecomment": "Begrundelse:",
        "deleteotherreason": "Anden/uddybende begrundelse:",
        "uctop": "(seneste)",
        "month": "Fra måned (og tidligere):",
        "year": "Fra år (og tidligere):",
+       "date": "Fra dato (og tidligere):",
        "sp-contributions-newbies": "Vis kun bidrag fra nye brugere",
        "sp-contributions-newbies-sub": "Fra nye kontoer",
        "sp-contributions-newbies-title": "Brugerbidrag fra nye konti",
        "whatlinkshere": "Hvad henviser hertil",
        "whatlinkshere-title": "Sider der linker til \"$1\"",
        "whatlinkshere-page": "Side:",
-       "linkshere-2": "De følgende sider henviser til '''„$1“''':",
-       "nolinkshere-2": "Ingen sider henviser til '''„$1“'''.",
-       "nolinkshere-ns-2": "Ingen side henviser til '''„$1“''' i det valgte navnerum.",
+       "linkshere": "De følgende sider henviser til <strong>$2</strong>:",
+       "nolinkshere": "Ingen sider henviser til <strong>$2</strong>.",
+       "nolinkshere-ns": "Ingen sider henviser til <strong>$2</strong> i det valgte navnerum.",
        "isredirect": "omdirigeringsside",
        "istemplate": "indlejring",
        "isimage": "filhenvisning",
        "markedaspatrollederrornotify": "Markering som patruljeret mislykkedes.",
        "patrol-log-page": "Kontrollog",
        "patrol-log-header": "Patruljerede versioner.",
-       "log-show-hide-patrol": "$1 patruljeringslog",
-       "log-show-hide-tag": "$1 taglog",
        "confirm-markpatrolled-button": "OK",
        "confirm-markpatrolled-top": "Marker version $3 af $2 som patruljeret?",
        "deletedrevision": "Slettede gammel version $1",
index 2718774..0b44ae2 100644 (file)
        "blanknamespace": "(Seiten)",
        "contributions-title": "Benutzerbeiträge von «$1»",
        "whatlinkshere-title": "Seiten, die auf «$1» verlinken",
-       "linkshere-2": "Die folgenden Seiten verlinken auf '''«$1»''':",
-       "nolinkshere-2": "Keine Seite verlinkt auf '''«$1»'''.",
-       "nolinkshere-ns-2": "Keine Seite verlinkt auf '''«$1»''' im gewählten Namensraum.",
+       "linkshere": "Die folgenden Seiten verlinken auf '''«$2»''':",
+       "nolinkshere": "Keine Seite verlinkt auf '''«$2»'''.",
+       "nolinkshere-ns": "Keine Seite verlinkt auf '''«$2»''' im gewählten Namensraum.",
        "ipb-confirmhideuser": "Du bist gerade dabei, einen Benutzer im Modus «Benutzer verstecken» zu sperren. Dies führt dazu, dass der Benutzername in allen Listen und Logbüchern unterdrückt wird. Möchtest du das wirklich tun?",
        "ipb-unblock-addr": "«$1» freigeben",
        "ipb-blocklist-contribs": "Benutzerbeiträge von «$1»",
index f7796da..9c8a5d5 100644 (file)
        "prefs-help-email": "Die Angabe einer E-Mail-Adresse ist optional, ermöglicht aber die Zusendung eines Ersatzpasswortes, sofern Sie Ihr Passwort vergessen haben.",
        "prefs-help-email-others": "Mit anderen Benutzern können Sie auch über die Benutzerdiskussionsseiten Kontakt aufnehmen, ohne dass Sie Ihre Identität offenlegen müssen.",
        "prefs-help-prefershttps": "Diese Einstellung wird bei Ihrer nächsten Anmeldung wirksam.",
-       "userrights-groups-help": "Sie können die Gruppenzugehörigkeit dieses Benutzers ändern:\n* Ein markiertes Kästchen bedeutet, dass der Benutzer Mitglied dieser Gruppe ist.\n* Ein nichtmarkiertes Kästchen bedeutet, dass der Benutzer nicht Mitglied dieser Gruppe ist.\n* Ein * bedeutet, dass Sie das Benutzerrecht nach Erteilung nicht wieder zurücknehmen können (oder umgekehrt).",
+       "userrights-groups-help": "Sie können die Gruppenzugehörigkeit {{GENDER:$1|dieses Benutzers|dieser Benutzerin}} ändern:\n* Ein markiertes Kästchen bedeutet, dass {{GENDER:$1|der Benutzer|die Benutzerin}} Mitglied dieser Gruppe ist.\n* Ein nicht markiertes Kästchen bedeutet, dass {{GENDER:$1|der Benutzer|die Benutzerin}} nicht dieser Gruppe angehört.\n* Ein * bedeutet, dass Sie das Benutzerrecht nach Erteilung nicht wieder zurücknehmen können, oder umgekehrt.\n* Ein # bedeutet, dass Sie den Zeitpunkt des Ablaufs dieser Gruppenzugehörigkeit nur nach hinten verlegen können. Sie können ihn nicht vorverlegen.",
        "userrights-no-interwiki": "Sie haben nicht die erforderliche Berechtigung, um Benutzerrechte in anderen Wikis ändern zu können.",
        "userrights-changeable-col": "Gruppenzugehörigkeit, die Sie ändern dürfen",
        "userrights-unchangeable-col": "Gruppenzugehörigkeit, die Sie nicht ändern dürfen",
index bbc8a08..c139ebb 100644 (file)
@@ -92,7 +92,9 @@
                        "Osnard",
                        "Suriyaa Kudo",
                        "KPFC",
-                       "ToBeFree"
+                       "ToBeFree",
+                       "PerfektesChaos",
+                       "Kurt Jansson"
                ]
        },
        "tog-underline": "Links unterstreichen:",
        "category-empty": "''Diese Kategorie enthält zurzeit keine Seiten oder Medien.''",
        "hidden-categories": "{{PLURAL:$1|Versteckte Kategorie|Versteckte Kategorien}}",
        "hidden-category-category": "Versteckte Kategorien",
-       "category-subcat-count": "{{PLURAL:$2|Diese Kategorie enthält nur folgende Unterkategorie.|Diese Kategorie enthält {{PLURAL:$1|folgende Unterkategorie|die folgende $1 Unterkategorien}}, von $2 insgesamt.}}",
-       "category-subcat-count-limited": "Diese Kategorie enthält folgende {{PLURAL:$1|Unterkategorie|$1 Unterkategorien}}:",
+       "category-subcat-count": "{{PLURAL:$2|Diese Kategorie enthält die folgende Unterkategorie:|Diese Kategorie enthält die {{PLURAL:$1|folgende Unterkategorie|folgenden $1 Unterkategorien}} ($2 insgesamt):}}",
+       "category-subcat-count-limited": "Diese Kategorie enthält die {{PLURAL:$1|folgende Unterkategorie|folgenden $1 Unterkategorien}}:",
        "category-article-count": "{{PLURAL:$2|Diese Kategorie enthält nur die folgende Seite.|Folgende {{PLURAL:$1|Seite ist| $1 Seiten sind}} in dieser Kategorie, von $2 insgesamt.}}",
        "category-article-count-limited": "{{PLURAL:$1|Folgende Seite ist|Die folgenden $1 Seiten sind}} in dieser Kategorie enthalten:",
        "category-file-count": "{{PLURAL:$2|Diese Kategorie enthält nur folgende Datei.|Folgende {{PLURAL:$1|Datei ist|$1 Dateien sind}} in dieser Kategorie, von $2 insgesamt.}}",
        "customcssprotected": "Du hast nicht die Berechtigung, diese CSS enthaltende Seite zu bearbeiten, da sie die persönlichen Einstellungen eines anderen Benutzers enthält.",
        "customjsonprotected": "Du hast keine Berechtigung, diese JSON-Seite zu bearbeiten, da sie persönliche Einstellungen eines anderen Benutzers enthält.",
        "customjsprotected": "Du hast nicht die Berechtigung, diese JavaScript enthaltende Seite zu bearbeiten, da es sich hierbei um die persönlichen Einstellungen eines anderen Benutzers handelt.",
+       "sitecssprotected": "Du hast keine Berechtigung, diese CSS-Seite zu bearbeiten, da sie alle Besucher betreffen könnte.",
+       "sitejsonprotected": "Du hast keine Berechtigung, diese JSON-Seite zu bearbeiten, da sie alle Besucher betreffen könnte.",
+       "sitejsprotected": "Du hast keine Berechtigung, diese JavaScript-Seite zu bearbeiten, da sie alle Besucher betreffen könnte.",
        "mycustomcssprotected": "Du hast keine Berechtigung, diese CSS-Seite zu bearbeiten.",
        "mycustomjsonprotected": "Du hast keine Berechtigung, diese JSON-Seite zu bearbeiten.",
        "mycustomjsprotected": "Du hast keine Berechtigung, diese JavaScript-Seite zu bearbeiten.",
        "resetpass-submit-loggedin": "Passwort ändern",
        "resetpass-submit-cancel": "Abbrechen",
        "resetpass-wrong-oldpass": "Ungültiges temporäres oder aktuelles Passwort.\nMöglicherweise hast du dein Passwort bereits geändert oder ein neues temporäres Passwort beantragt.",
-       "resetpass-recycled": "Bitte setze dein Passwort auf ein anderes Passwort als dein aktuelles fest.",
+       "resetpass-recycled": "Bitte ändere dein Passwort auf ein anderes als dein aktuelles.",
        "resetpass-temp-emailed": "Du hast dich mit einem temporären E-Mail-Code angemeldet.\nUm die Anmeldung abzuschließen, musst du jetzt ein neues Passwort festlegen:",
        "resetpass-temp-password": "Temporäres Passwort:",
        "resetpass-abort-generic": "Die Passwortänderung wurde durch eine Erweiterung abgebrochen.",
        "resetpass-expired": "Dein Passwort ist abgelaufen. Bitte lege ein neues Passwort zur Anmeldung fest.",
-       "resetpass-expired-soft": "Dein Passwort ist abgelaufen und muss zurückgesetzt werden. Bitte wähle jetzt ein neues Passwort aus oder klicke auf „{{int:authprovider-resetpass-skip-label}}“, um es später zurückzusetzen.",
-       "resetpass-validity-soft": "Dein Passwort ist ungültig: $1\n\nBitte wähle jetzt ein neues Passwort oder klicke auf „{{int:authprovider-resetpass-skip-label}}“, um es später zurückzusetzen.",
+       "resetpass-expired-soft": "Dein Passwort ist abgelaufen und muss geändert werden. Bitte wähle jetzt ein neues Passwort aus oder klicke auf „{{int:authprovider-resetpass-skip-label}}“, um es später zu ändern.",
+       "resetpass-validity-soft": "Dein Passwort ist ungültig: $1\n\nBitte wähle jetzt ein neues Passwort aus oder klicke auf „{{int:authprovider-resetpass-skip-label}}“, um es später zu ändern.",
        "passwordreset": "Passwort zurücksetzen",
        "passwordreset-text-one": "Fülle dieses Formular aus, um ein temporäres Passwort per E-Mail zu erhalten.",
        "passwordreset-text-many": "{{PLURAL:$1|Fülle eines der Felder aus, um ein temporäres Passwort per E-Mail zugesandt zu bekommen.}}",
        "showpreview": "Vorschau zeigen",
        "showdiff": "Änderungen zeigen",
        "blankarticle": "<strong>Warnung:</strong> Die Seite, die du erstellst, ist leer.\nWenn du erneut auf „$1“ klickst, wird die Seite ohne Inhalt erstellt.",
-       "anoneditwarning": "<strong>Warnung:</strong> Du bist nicht angemeldet. Deine IP-Adresse wird öffentlich sichtbar, falls du Bearbeitungen durchführst. Sofern du dich <strong>[$1 anmeldest]</strong> oder <strong>[$2 ein Benutzerkonto erstellst]</strong>, werden deine Bearbeitungen zusammen mit anderen Beiträgen deinem Benutzernamen zugeordnet.",
+       "anoneditwarning": "<strong>Warnung:</strong> Du bist nicht angemeldet. Deine IP-Adresse wird bei Bearbeitungen öffentlich sichtbar. <strong>[$1 Melde dich an]</strong> oder <strong>[$2 erstelle ein Benutzerkonto]</strong>, damit Bearbeitungen deinem Benutzernamen zugeordnet werden.",
        "anonpreviewwarning": "''Du bist nicht angemeldet. Beim Speichern wird deine IP-Adresse in der Versionsgeschichte aufgezeichnet.''",
        "missingsummary": "<strong>Hinweis:</strong> Du hast keine Zusammenfassung angegeben. Wenn du erneut auf „$1“ klickst, wird deine Änderung ohne Zusammenfassung übernommen.",
        "selfredirect": "<strong>Warnung:</strong> Du leitest auf diese Seite selbst weiter.\nDu hast vermutlich das falsche Weiterleitungsziel angegeben oder du bearbeitest die falsche Seite.\nWenn du erneut auf „$1“ klickst, wird die Weiterleitung dennoch erstellt.",
        "converter-manual-rule-error": "Bei der manuellen Sprachkonvertierungsregel wurde ein Fehler entdeckt.",
        "undo-success": "Die Bearbeitung kann rückgängig gemacht werden.\nBitte prüfe den Vergleich unten, um sicherzustellen, dass du dies tun möchtest, und speichere dann unten deine Änderungen, um die Bearbeitung rückgängig zu machen.",
        "undo-failure": "Die Änderung konnte nicht rückgängig gemacht werden, da der betroffene Abschnitt zwischenzeitlich verändert wurde.",
+       "undo-main-slot-only": "Die Bearbeitung konnte nicht rückgängig gemacht werden, da sie Inhalte außerhalb der Hauptspalte enthält.",
        "undo-norev": "Die Bearbeitung konnte nicht rückgängig gemacht werden, da sie nicht vorhanden ist oder gelöscht wurde.",
        "undo-nochange": "Anscheinend wurde diese Bearbeitung bereits rückgängig gemacht.",
        "undo-summary": "Änderung $1 von [[Special:Contributions/$2|$2]] ([[User talk:$2|Diskussion]]) rückgängig gemacht.",
        "diff-paragraph-moved-toold": "Der Absatz wurde verschoben. Klicken, um zur alten Stelle zu springen.",
        "difference-missing-revision": "{{PLURAL:$2|Eine Version|$2 Versionen}} dieser Unterschiedsanzeige ($1) {{PLURAL:$2|wurde|wurden}} nicht gefunden.\n\nDieser Fehler wird normalerweise von einem veralteten Link zur Versionsgeschichte einer Seite verursacht, die zwischenzeitlich gelöscht wurde.\nEinzelheiten sind im [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} Lösch-Logbuch] vorhanden.",
        "searchresults": "Suchergebnisse",
+       "search-filter-title-prefix": "Nur in Seiten suchen, deren Titel mit „$1“ beginnt.",
+       "search-filter-title-prefix-reset": "Alle Seiten durchsuchen",
        "searchresults-title": "Suchergebnisse für „$1“",
        "titlematches": "Übereinstimmungen mit Seitentiteln",
        "textmatches": "Übereinstimmungen mit Inhalten",
        "userrights-groupsmember": "Mitglied von:",
        "userrights-groupsmember-auto": "Automatisch Mitglied von:",
        "userrights-groupsmember-type": "$2",
-       "userrights-groups-help": "Du kannst die Gruppenzugehörigkeit {{GENDER:$1|dieses Benutzers|dieser Benutzerin}} ändern:\n* Ein markiertes Kästchen bedeutet, dass {{GENDER:$1|der Benutzer|die Benutzerin}} Mitglied dieser Gruppe ist.\n* Ein nicht markiertes Kästchen bedeutet, dass {{GENDER:$1|der Benutzer|die Benutzerin}} nicht Mitglied dieser Gruppe ist.\n* Ein * bedeutet, dass du das Benutzerrecht nach Erteilung nicht wieder zurücknehmen kannst (oder umgekehrt).\n* Ein # bedeutet, dass du den Zeitpunkt des Ablaufs dieser Gruppenmitgliedschaft nur nach hinten verschieben kannst. Du kannst ihn nicht vorverlegen.",
+       "userrights-groups-help": "Du kannst die Gruppenzugehörigkeit {{GENDER:$1|dieses Benutzers|dieser Benutzerin}} ändern:\n* Ein markiertes Kästchen bedeutet, dass {{GENDER:$1|der Benutzer|die Benutzerin}} Mitglied dieser Gruppe ist.\n* Ein nicht markiertes Kästchen bedeutet, dass {{GENDER:$1|der Benutzer|die Benutzerin}} nicht dieser Gruppe angehört.\n* Ein * bedeutet, dass du das Benutzerrecht nach Erteilung nicht wieder zurücknehmen kannst, oder umgekehrt.\n* Ein # bedeutet, dass du den Zeitpunkt des Ablaufs dieser Gruppenzugehörigkeit nur nach hinten verlegen kannst. Du kannst ihn nicht vorverlegen.",
        "userrights-reason": "Grund:",
        "userrights-no-interwiki": "Du hast nicht die erforderliche Berechtigung, um Benutzerrechte in anderen Wikis ändern zu können.",
        "userrights-nodatabase": "Die Datenbank $1 ist nicht vorhanden oder nicht lokal.",
        "group-autoconfirmed": "Automatisch bestätigte Benutzer",
        "group-bot": "Bots",
        "group-sysop": "Administratoren",
+       "group-interface-admin": "Oberflächenadministratoren",
        "group-bureaucrat": "Bürokraten",
        "group-suppress": "Unterdrücker",
        "group-all": "(alle)",
        "group-autoconfirmed-member": "{{GENDER:$1|Automatisch bestätigter Benutzer|Automatisch bestätigte Benutzerin}}",
        "group-bot-member": "Bot",
        "group-sysop-member": "{{GENDER:$1|Administrator|Administratorin}}",
+       "group-interface-admin-member": "{{GENDER:$1|Oberflächenadministrator|Oberflächenadministratorin}}",
        "group-bureaucrat-member": "{{GENDER:$1|Bürokrat|Bürokratin}}",
        "group-suppress-member": "{{GENDER:$1|Unterdrücker|Unterdrückerin}}",
        "grouppage-user": "{{ns:project}}:Benutzer",
        "grouppage-autoconfirmed": "{{ns:project}}:Automatisch bestätigte Benutzer",
        "grouppage-bot": "{{ns:project}}:Bots",
        "grouppage-sysop": "{{ns:project}}:Administratoren",
+       "grouppage-interface-admin": "{{ns:project}}:Oberflächenadministratoren",
        "grouppage-bureaucrat": "{{ns:project}}:Bürokraten",
        "grouppage-suppress": "{{ns:project}}:Unterdrücker",
        "right-read": "Seiten lesen",
        "right-editusercss": "Fremde CSS-Dateien bearbeiten",
        "right-edituserjson": "JSON-Dateien anderer Benutzer bearbeiten",
        "right-edituserjs": "Fremde JavaScript-Dateien bearbeiten",
+       "right-editsitecss": "Wikiweit CSS bearbeiten",
+       "right-editsitejson": "Wikiweites JSON bearbeiten",
+       "right-editsitejs": "Wikiweites JavaScript bearbeiten",
        "right-editmyusercss": "Eigene Benutzer-CSS-Dateien bearbeiten",
        "right-editmyuserjson": "Eigene Benutzer-JSON-Dateien bearbeiten",
        "right-editmyuserjs": "Eigene Benutzer-JavaScript-Dateien bearbeiten",
        "grant-createaccount": "Benutzerkonten erstellen",
        "grant-createeditmovepage": "Seiten erstellen, bearbeiten und verschieben",
        "grant-delete": "Seiten, Versionen und Logbucheinträge löschen",
-       "grant-editinterface": "MediaWiki-Namensraum und Benutzer-CSS/JSON/JavaScript bearbeiten",
+       "grant-editinterface": "Den MediaWiki-Namensraum und wikiweites/Benutzer-JSON bearbeiten",
        "grant-editmycssjs": "Dein Benutzer-CSS/JSON/JavaScript bearbeiten",
        "grant-editmyoptions": "Deine Benutzereinstellungen bearbeiten",
        "grant-editmywatchlist": "Deine Beobachtungsliste bearbeiten",
+       "grant-editsiteconfig": "Wikiweites und Benutzer-CSS/JS bearbeiten",
        "grant-editpage": "Vorhandene Seiten bearbeiten",
        "grant-editprotected": "Geschützte Seiten bearbeiten",
        "grant-highvolume": "Massenbearbeitungen",
        "rcfilters-other-review-tools": "Andere Überprüfungswerkzeuge",
        "rcfilters-group-results-by-page": "Ergebnisse nach Seite gruppieren",
        "rcfilters-activefilters": "Aktive Filter",
+       "rcfilters-activefilters-hide": "Ausblenden",
+       "rcfilters-activefilters-show": "Anzeigen",
+       "rcfilters-activefilters-hide-tooltip": "Bereich der aktiven Filter ausblenden",
+       "rcfilters-activefilters-show-tooltip": "Bereich der aktiven Filter anzeigen",
        "rcfilters-advancedfilters": "Erweiterte Filter",
        "rcfilters-limit-title": "Anzuzeigende Ergebnisse",
        "rcfilters-limit-and-date-label": "{{PLURAL:$1|Eine Änderung|$1 Änderungen}}, $2",
        "rcfilters-savedqueries-rename": "Umbenennen",
        "rcfilters-savedqueries-setdefault": "Als Standard festlegen",
        "rcfilters-savedqueries-unsetdefault": "Als Standard entfernen",
-       "rcfilters-savedqueries-remove": "Entfernen",
+       "rcfilters-savedqueries-remove": "Löschen",
        "rcfilters-savedqueries-new-name-label": "Name",
        "rcfilters-savedqueries-new-name-placeholder": "Beschreibe den Zweck des Filters",
        "rcfilters-savedqueries-apply-label": "Filter erstellen",
        "rcfilters-empty-filter": "Keine aktiven Filter. Es werden alle Beiträge angezeigt.",
        "rcfilters-filterlist-title": "Filter",
        "rcfilters-filterlist-whatsthis": "Wie funktioniert das?",
-       "rcfilters-filterlist-feedbacklink": "Erzähle uns, was du über diese (neuen) Filterwerkzeuge denkst.",
+       "rcfilters-filterlist-feedbacklink": "Erzähle uns, was du über diese Filterwerkzeuge denkst.",
        "rcfilters-highlightbutton-title": "Ergebnisse hervorheben",
        "rcfilters-highlightmenu-title": "Eine Farbe auswählen",
        "rcfilters-highlightmenu-help": "Eine Farbe auswählen, um diese Eigenschaft hervorzuheben.",
        "rcfilters-watchlist-showupdated": "Änderungen an Seiten, die du seit ihrem Auftreten nicht besucht hast, sind <strong>fett</strong> markiert.",
        "rcfilters-preference-label": "Die neue Version der Letzten Änderungen ausblenden",
        "rcfilters-preference-help": "Macht die Neugestaltung der Oberfläche aus dem Jahr 2017 und alle seitdem hinzugefügten Werkzeuge wieder rückgängig.",
+       "rcfilters-watchlist-preference-label": "Die verbesserte Version der Beobachtungsliste deaktivieren",
+       "rcfilters-watchlist-preference-help": "Setzt die Neugestaltung der Oberfläche aus dem Jahr 2017 und all die Werkzeuge zurück, die seitdem hinzugefügt wurden.",
        "rcfilters-filter-showlinkedfrom-label": "Änderungen auf Seiten anzeigen, die verlinkt sind von",
        "rcfilters-filter-showlinkedfrom-option-label": "<strong>Seiten</strong>, die <strong>von</strong> der ausgewählten Seite <strong>verlinkt</strong> sind",
        "rcfilters-filter-showlinkedto-label": "Änderungen auf Seiten anzeigen, die verlinken auf",
        "uploadstash-zero-length": "Die Datei hat eine Größe von null.",
        "invalid-chunk-offset": "Ungültiger Startpunkt",
        "img-auth-accessdenied": "Zugriff verweigert",
-       "img-auth-nopathinfo": "Die Angabe PATH_INFO fehlt.\nDer Server ist nicht dafür eingerichtet, diese Information weiterzugeben.\nSie könnte CGI-gestützt sein und kann daher „img_auth“ (Authentifizierung des Dateiaufrufs) nicht unterstützen.\nSiehe auch https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization (englisch).",
+       "img-auth-nopathinfo": "Fehlende Pfadinformationen.\nDein Server muss so aufgesetzt sein, dass die Variablen REQUEST_URI und/oder PATH_INFO übergeben werden.\nFalls zutreffend, versuche, $wgUsePathInfo zu aktivieren.\nSiehe https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization.",
        "img-auth-notindir": "Der gewünschte Pfad ist nicht im konfigurierten Uploadverzeichnis.",
        "img-auth-badtitle": "Aus „$1“ kann kein gültiger Titel erstellt werden.",
        "img-auth-nologinnWL": "Du bist nicht angemeldet und „$1“ ist nicht in der weißen Liste.",
        "http-timed-out": "Zeitüberschreitung bei der HTTP-Anfrage.",
        "http-curl-error": "Fehler beim Abruf der URL: $1",
        "http-bad-status": "Während der HTTP-Anfrage ist ein Fehler aufgetreten: $1 $2",
+       "http-internal-error": "Interner HTTP-Fehler.",
        "upload-curl-error6": "URL ist nicht erreichbar",
        "upload-curl-error6-text": "Die angegebene URL ist nicht erreichbar. Prüfe sowohl die URL auf Fehler als auch den Online-Status der Seite.",
        "upload-curl-error28": "Zeitüberschreitung beim Hochladen",
        "speciallogtitlelabel": "Ziel (Titel oder {{ns:user}}:Benutzername für einen Benutzer):",
        "log": "Logbücher",
        "logeventslist-submit": "Anzeigen",
+       "logeventslist-more-filters": "Zusätzliche Logbücher anzeigen:",
+       "logeventslist-patrol-log": "Kontroll-Logbuch",
+       "logeventslist-tag-log": "Markierungs-Logbuch",
        "all-logs-page": "Alle öffentlichen Logbücher",
        "alllogstext": "Dies ist die kombinierte Anzeige aller in {{SITENAME}} geführten Logbücher.\nDie Ausgabe kann durch die Auswahl des Logbuchtyps, des Benutzers oder des Seitentitels eingeschränkt werden (Groß-/Kleinschreibung muss beachtet werden).",
        "logempty": "Keine passenden Einträge.",
        "dellogpage": "Lösch-Logbuch",
        "dellogpagetext": "Dies ist das Logbuch der gelöschten Seiten und Dateien.",
        "deletionlog": "Lösch-Logbuch",
+       "log-name-create": "Seitenerstellungs-Logbuch",
+       "log-description-create": "Es folgt eine Liste der letzten Seitenerstellungen.",
+       "logentry-create-create": "$1 hat die Seite $3 {{GENDER:$2|erstellt}}",
        "reverted": "Auf eine alte Version zurückgesetzt",
        "deletecomment": "Grund:",
        "deleteotherreason": "Anderer/ergänzender Grund:",
        "uctop": "(aktuell)",
        "month": "und Monat:",
        "year": "bis Jahr:",
+       "date": "Von Datum (und früher):",
        "sp-contributions-newbies": "Zeige nur Beiträge neuer Benutzer",
        "sp-contributions-newbies-sub": "Von neuen Benutzern",
        "sp-contributions-newbies-title": "Benutzerbeiträge von neuen Benutzern",
        "whatlinkshere": "Links auf diese Seite",
        "whatlinkshere-title": "Seiten, die auf „$1“ verlinken",
        "whatlinkshere-page": "Seite:",
-       "linkshere-2": "Die folgenden Seiten verlinken auf <strong>$1</strong>:",
-       "nolinkshere-2": "Keine Seite verlinkt auf '''„$1“'''.",
-       "nolinkshere-ns-2": "Keine Seite verlinkt auf '''„$1“''' im gewählten Namensraum.",
+       "linkshere": "Die folgenden Seiten verlinken auf <strong>$2</strong>:",
+       "nolinkshere": "Keine Seite verlinkt auf <strong>$2</strong>.",
+       "nolinkshere-ns": "Keine Seite in dem ausgewählten Namensraum verlinkt auf <strong>$2</strong>.",
        "isredirect": "Weiterleitungsseite",
        "istemplate": "Vorlageneinbindung",
        "isimage": "Dateilink",
        "markedaspatrollederrornotify": "Der Versuch, die Version als kontrolliert zu markieren, ist fehlgeschlagen.",
        "patrol-log-page": "Kontroll-Logbuch",
        "patrol-log-header": "Dies ist das Kontroll-Logbuch.",
-       "log-show-hide-patrol": "Kontroll-Logbuch $1",
-       "log-show-hide-tag": "Markierungs-Logbuch $1",
        "confirm-markpatrolled-button": "Okay",
        "confirm-markpatrolled-top": "Version $3 von $2 als kontrolliert markieren?",
        "deletedrevision": "alte Version $1 gelöscht",
        "passwordpolicies-policy-passwordcannotmatchusername": "Ein Passwort kann nicht mit dem Benutzernamen identisch sein",
        "passwordpolicies-policy-passwordcannotmatchblacklist": "Ein Passwort kann nicht mit speziellen schwarzgelisteten Passwörtern übereinstimmen",
        "passwordpolicies-policy-maximalpasswordlength": "Ein Passwort muss weniger als {{PLURAL:$1|ein|$1}} Zeichen lang sein",
-       "passwordpolicies-policy-passwordcannotbepopular": "Ein Passwort kann nicht {{PLURAL:$1|das beliebteste Passwort|in der Liste der $1 beliebtesten Passwörter}} sein"
+       "passwordpolicies-policy-passwordcannotbepopular": "Ein Passwort kann nicht {{PLURAL:$1|das beliebteste Passwort|in der Liste der $1 beliebtesten Passwörter}} sein",
+       "easydeflate-invaliddeflate": "Der angegebene Inhalt ist nicht ordnungsgemäß komprimiert"
 }
index f80e87f..1ba6eec 100644 (file)
        "february": "Gucige",
        "march": "Adar",
        "april": "Nisane",
-       "may_long": "Gulan",
+       "may_long": "Gulane",
        "june": "Heziran",
        "july": "Temuz",
        "august": "Tebaxe",
        "february-gen": "Sıbat",
        "march-gen": "Adar",
        "april-gen": "Nisane",
-       "may-gen": "Gulan",
+       "may-gen": "Gulane",
        "june-gen": "Heziran",
        "july-gen": "Temuz",
        "august-gen": "Tebaxe",
        "jan": "Çel",
        "feb": "Sbt",
        "mar": "Adr",
-       "apr": "Lsn",
-       "may": "Gln",
+       "apr": "Nsn",
+       "may": "Gul",
        "jun": "Hez",
        "jul": "Tmz",
        "aug": "Tbx",
        "february-date": "$1 Sıbat",
        "march-date": "$1 Adar",
        "april-date": "$1 Nisane",
-       "may-date": "$1 Gulan",
+       "may-date": "$1 Gulane",
        "june-date": "$1 Heziran",
        "july-date": "$1 Temuze",
        "august-date": "$1 Tebaxe",
        "whatlinkshere": "Linkê tedeestey",
        "whatlinkshere-title": "Wesiqe da \"$1\" rê gıre dayen perri",
        "whatlinkshere-page": "Pele:",
-       "linkshere-2": "Pera <strong>$1</strong> rê gıre dayen perri",
-       "nolinkshere-2": "Per da '''$1''' rê pera ke gıre dana çıniya.",
-       "nolinkshere-ns-2": "Cayo ke namey rê weçinayo de qet perre '''$1''' rê link nêbena.",
+       "linkshere": "Pera <strong>$2</strong> rê gıre dayen perri",
+       "nolinkshere": "Per da '''$2''' rê pera ke gıre dana çıniya.",
+       "nolinkshere-ns": "Cayo ke namey rê weçinayo de qet perre '''$2''' rê link nêbena.",
        "isredirect": "pera hetenayışi",
        "istemplate": "Açarnayene",
        "isimage": "gırey dosye",
        "markedaspatrollederrornotify": "Nışan kerdışê dewriyey nêbı",
        "patrol-log-page": "Qeydé çımsernayoğan",
        "patrol-log-header": "Ena listeyê logi revizyonê devriyeyi mocneno.",
-       "log-show-hide-patrol": "Qeydé Çımsernayoğan $1",
-       "log-show-hide-tag": "$1 qeydê etiketi",
        "confirm-markpatrolled-button": "TEMAM",
        "deletedrevision": "Veriyono kihan $1 wederna",
        "filedeleteerror-short": "Wedarnayişê dosya de ğelati esto: $1",
index 2b8e205..0cff6d9 100644 (file)
@@ -20,7 +20,8 @@
                        "TMg",
                        "Macofe",
                        "Matma Rex",
-                       "Fitoschido"
+                       "Fitoschido",
+                       "Vlad5250"
                ]
        },
        "tog-underline": "Wótkaze pódšmarnuś:",
        "right-editsemiprotected": "Boki wobźěłaś, kótarež su pśez \"{{int:protect-level-autoconfirmed}}\" šćitane",
        "right-editinterface": "Wužywański pówjerch wobźěłaś",
        "right-editusercss": "Dataje CSS drugich wužywarjow wobźěłaś",
+       "right-edituserjson": "Dataje JSON drugich wužywarjow wobźěłaś",
        "right-edituserjs": "Dataje JS drugich wužywarjow wobźěłaś",
        "right-editmyusercss": "Twóje swójske wužywarske CSS-dataje wobźěłaś",
+       "right-editmyuserjson": "Twóje swójske wužywarske JSON-dataje wobźěłaś",
        "right-editmyuserjs": "Twóje swójske wužywarske JavaScript-dataje wobźěłaś",
        "right-viewmywatchlist": "Se swójske wobglědowańki woglědaś",
        "right-editmywatchlist": "Swóje wobglědowańki wobźěłaś. Wobglěduj, až někotare akcije hyšći pśidawaju boki bźez toś togo pšawa.",
        "whatlinkshere": "Wótkaze na toś ten bok",
        "whatlinkshere-title": "Boki, kótarež wótkazuju na \"$1\"",
        "whatlinkshere-page": "bok:",
-       "linkshere-2": "Toś te boki wótkazuju na '''„$1“''':",
-       "nolinkshere-2": "Žedne boki njewótkazuju na '''$1'''.",
-       "nolinkshere-ns-2": "Žedne boki we wubranem mjenjowem rumje njewótkazuju na '''$1'''.",
+       "linkshere": "Toś te boki wótkazuju na '''„$2“''':",
+       "nolinkshere": "Žedne boki njewótkazuju na '''$2'''.",
+       "nolinkshere-ns": "Žedne boki we wubranem mjenjowem rumje njewótkazuju na '''$2'''.",
        "isredirect": "dalejpósrědnjujucy bok",
        "istemplate": "zawězanje pśedłogi",
        "isimage": "datajowy wótkaz",
        "markedaspatrollederrornotify": "Markěrowanje ako doglědowane njejo se raźiło.",
        "patrol-log-page": "Protokol kontrolow",
        "patrol-log-header": "To jo protokol pśekontrolowanych wersijow.",
-       "log-show-hide-patrol": "Protokol doglědowanja $1",
        "deletedrevision": "wulašowana stara wersija: $1",
        "filedeleteerror-short": "Zmólka pśi wulašowanju dataje: $1",
        "filedeleteerror-long": "Pśi wulašowanju dataje su se zwěsćili zmólki:\n\n$1",
index 00b5f14..1f8403a 100644 (file)
        "whatlinkshere": "Nunu poingoput hiti",
        "whatlinkshere-title": "Bolikon di poingoput id \"$1\"",
        "whatlinkshere-page": "Bolikon:",
-       "linkshere-2": "Bolikon diti poingoput kumaa id  '''$1''':",
-       "nolinkshere-2": "Ingaa bolikon poingoput id '''$1'''.",
+       "linkshere": "Bolikon diti poingoput kumaa id  '''$2''':",
+       "nolinkshere": "Ingaa bolikon poingoput id '''$2'''.",
        "isredirect": "bolikon pinotilombus",
        "istemplate": "alanai",
        "isimage": "noputan do upa",
index 99021a1..b502538 100644 (file)
        "whatlinkshere": "याँखाइ कि जोणीन्छ",
        "whatlinkshere-title": "$1 सित जोडियाऽ पन्नाअन",
        "whatlinkshere-page": "पानो",
-       "linkshere-2": "निम्न पानाहरू '''$1''' मी जुडन्छ :",
-       "nolinkshere-ns-2": "चुनियाको नामस्थानमी '''$1''' सित जुड्न्या पानाहरू नाइथिन्।",
+       "linkshere": "निम्न पानाहरू '''$2''' मी जुडन्छ :",
+       "nolinkshere-ns": "चुनियाको नामस्थानमी '''$2''' सित जुड्न्या पानाहरू नाइथिन्।",
        "isredirect": "अनुप्रेषित पानो",
        "istemplate": "पारदर्शिता",
        "isimage": "फाइल लिङ्क",
index e8cbc3f..fde4b65 100644 (file)
        "whatlinkshere": "A pûnten ché",
        "whatlinkshere-title": "Pàgini che pûnten a \"$1\"",
        "whatlinkshere-page": "Pàgina:",
-       "linkshere-2": "Al pàgini segvèinti a gh'àn di colegamèint a '''$1'''.",
-       "nolinkshere-2": "Nisóna pàgina la gh'à dèinter colegamèint che pûnten a '''$1'''.",
+       "linkshere": "Al pàgini segvèinti a gh'àn di colegamèint a '''$2'''.",
+       "nolinkshere": "Nisóna pàgina la gh'à dèinter colegamèint che pûnten a '''$2'''.",
        "isredirect": "Pàgina redirect",
        "istemplate": "uniòun",
        "isimage": "Colegamèint vêrs al file",
index ec816d5..a199a90 100644 (file)
        "edit-gone-missing": "Δεν ήταν εφικτό να ενημερωθεί η σελίδα.\nΦαίνεται πως έχει διαγραφεί.",
        "edit-conflict": "Σύγκρουση επεξεργασιών.",
        "edit-no-change": "Η επεξεργασία σας αγνοήθηκε, επειδή δεν έγινε καμία αλλαγή στο κείμενο.",
-       "postedit-confirmation-created": "Î\97 Ï\83ελίδα Î­Ï\87ει Î´Î·Î¼Î¹Î¿Ï\85Ï\81γηθεί.",
+       "postedit-confirmation-created": "Î\97 Ï\83ελίδα Î´Î·Î¼Î¹Î¿Ï\85Ï\81γήθηκε.",
        "postedit-confirmation-restored": "Η σελίδα έχει αποκατασταθεί.",
        "postedit-confirmation-saved": "H επεξεργασία σας αποθηκεύτηκε.",
        "postedit-confirmation-published": "Η επεξεργασία σας δημοσιεύτηκε.",
        "diff-paragraph-moved-toold": "Η παράγραφος αφαιρέθηκε. Πατήστε στο κουμπί για να πάτε σε προηγούμενη τοποθεσία.",
        "difference-missing-revision": "{{PLURAL:$2|Μία αναθεώρηση|$2 αναθεωρήσεις}} αυτής της διαφοράς ($1) δεν {{PLURAL:$2|μπόρεσε να βρεθεί|μπόρεσαν να βρεθούν}}.\n\nΑυτό συνήθως προκαλείται από παλιό σύνδεσμο διαφοράς προς σελίδα που έχει διαγραφεί.\nΛεπτομέρειες θα βρείτε στο [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} ημερολόγιο καταγραφής διαγραφών].",
        "searchresults": "Αποτελέσματα αναζήτησης",
+       "search-filter-title-prefix-reset": "Αναζήτηση όλων των σελίδων",
        "searchresults-title": "Αποτελέσματα αναζήτησης για \"$1\"",
        "titlematches": "Τίτλοι άρθρων που ανταποκρίνονται",
        "textmatches": "Κείμενα σελίδων που ανταποκρίνονται:",
        "group-autoconfirmed": "Αυτοεπιβεβαιωμένοι χρήστες",
        "group-bot": "Ρομπότ",
        "group-sysop": "Διαχειριστές",
+       "group-interface-admin": "Διαχειριστές διεπαφής",
        "group-bureaucrat": "Γραφειοκράτες",
        "group-suppress": "Παρατηρητές",
        "group-all": "(όλοι)",
        "group-autoconfirmed-member": "{{GENDER:$1|αυτοεπιβεβαιωμένος χρήστης|αυτοεπιβεβαιωμένη χρήστρια}}",
        "group-bot-member": "ρομπότ",
        "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}}:Bots",
        "grouppage-sysop": "{{ns:project}}:Διαχειριστές",
+       "grouppage-interface-admin": "{{ns:project}}:Διαχειριστές διεπαφής",
        "grouppage-bureaucrat": "{{ns:project}}:Γραφειοκράτες",
        "grouppage-suppress": "{{ns:project}}:Παρόραμα",
        "right-read": "Ανάγνωση σελίδων",
        "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",
        "rcfilters-savedqueries-rename": "Μετονομασία",
        "rcfilters-savedqueries-setdefault": "Ορισμός ως προεπιλογή",
        "rcfilters-savedqueries-unsetdefault": "Αφαίρεση από προεπιλογή",
-       "rcfilters-savedqueries-remove": "Î\91Ï\86αίÏ\81εÏ\83η",
+       "rcfilters-savedqueries-remove": "Î\94ιαγÏ\81αÏ\86ή",
        "rcfilters-savedqueries-new-name-label": "Όνομα",
        "rcfilters-savedqueries-new-name-placeholder": "Περιγράψτε το σκοπό του φίλτρου",
        "rcfilters-savedqueries-apply-label": "Δημιουργία φίλτρου",
        "rcfilters-empty-filter": "Χωρίς ενεργά φίλτρα. Εμφανίζονται όλες οι συνεισφορές.",
        "rcfilters-filterlist-title": "Φίλτρα",
        "rcfilters-filterlist-whatsthis": "Πως λειτουργούν αυτά;",
-       "rcfilters-filterlist-feedbacklink": "Πείτε μας τι σκέφτεστε για αυτά τα (νέα) εργαλεία φιλτραρίσματος",
+       "rcfilters-filterlist-feedbacklink": "Πείτε μας τι σκέφτεστε για αυτά τα εργαλεία φιλτραρίσματος",
        "rcfilters-highlightbutton-title": "Επισήμανση αποτελεσμάτων",
        "rcfilters-highlightmenu-title": "Επιλέξτε ένα χρώμα",
        "rcfilters-highlightmenu-help": "Επιλέξτε ένα χρώμα για να επισημάνετε αυτή την ιδιότητα",
        "dellogpage": "Αρχείο καταγραφών διαγραφών",
        "dellogpagetext": "Λίστα των πιο πρόσφατων διαγραφών",
        "deletionlog": "Καταγραφές διαγραφών",
+       "log-name-create": "Αρχείο καταγραφών δημιουργίας σελίδων",
+       "log-description-create": "Παρακάτω υπάρχει ένας κατάλογος των πιο πρόσφατων δημιουργιών σελίδας.",
        "reverted": "Επαναφορά σε προηγούμενη αναθεώρηση",
        "deletecomment": "Λόγος:",
        "deleteotherreason": "Άλλος/πρόσθετος λόγος:",
        "whatlinkshere": "Τι συνδέει εδώ",
        "whatlinkshere-title": "Σελίδες που συνδέουν στη σελίδα «$1»",
        "whatlinkshere-page": "Σελίδα:",
-       "linkshere-2": "Οι ακόλουθες σελίδες συνδέουν στη σελίδα '''$1''':",
-       "nolinkshere-2": "Δεν υπάρχουν σελίδες που να συνδέουν στη σελίδα '''$1'''.",
-       "nolinkshere-ns-2": "Καμία σελίδα δεν συνδέει στο '''$1''' στον επιλεγμένο ονοματοχώρο.",
+       "linkshere": "Οι ακόλουθες σελίδες συνδέουν στη σελίδα <strong>$2</strong>:",
+       "nolinkshere": "Δεν υπάρχουν σελίδες που να συνδέουν στη σελίδα <strong>$2</strong>.",
+       "nolinkshere-ns": "Καμία σελίδα δεν συνδέει στο <strong>$2</strong> στον επιλεγμένο ονοματοχώρο.",
        "isredirect": "σελίδα ανακατεύθυνσης",
        "istemplate": "ενσωμάτωση",
        "isimage": "σύνδεσμος αρχείου",
        "markedaspatrollederrornotify": "Σήμανση ως ελεγμένη απέτυχε.",
        "patrol-log-page": "Αρχείο καταγραφής περιπολιών",
        "patrol-log-header": "Αυτό είναι μητρώο ελεγμένων αναθεωρήσεων.",
-       "log-show-hide-patrol": "$1 μητρώου ελέγχου επεξεργασιών",
-       "log-show-hide-tag": "$1 ετικέττα καταγραφής",
        "confirm-markpatrolled-button": "Εντάξει",
        "deletedrevision": "Η παλιά έκδοση της $1 διαγράφτηκε",
        "filedeleteerror-short": "Σφάλμα κατά τη διαγραφή του αρχείου: $1",
        "confirm-unwatch-top": "Κατάργηση αυτής της σελίδας από τη λίστα παρακολούθησης σας;",
        "confirm-rollback-button": "Εντάξει",
        "confirm-rollback-top": "Επαναφέρετε τις επεξεργασίες σε αυτή τη σελίδα;",
+       "semicolon-separator": "•&#32;",
        "quotation-marks": "«$1»",
        "imgmultipageprev": "← προηγούμενη σελίδα",
        "imgmultipagenext": "επόμενη σελίδα →",
index ca3a000..f07453b 100644 (file)
        "italic_sample": "Italic text",
        "savearticle": "Save page",
        "anonpreviewwarning": "<em>You are not logged in. Saving will record your IP address in this page's edit history.</em>",
-       "blockedtext": "<strong>Your username or IP address has been blocked.</strong>\n\nThe block was made by $1.\nThe reason given is <em>$2</em>.\n\n* Start of block: $8\n* Expiry of block: $6\n* Intended blockee: $7\n\nYou can contact $1 or another [[{{MediaWiki:Grouppage-sysop}}|administrator]] to discuss the block.\nYou cannot use the \"email this user\" feature unless a valid email address is specified in your [[Special:Preferences|account preferences]] and you have not been blocked from using it.\nYour current IP address is $3, and the block ID is #$5.\nPlease include all above details in any queries you make.",
+       "blockedtext": "<strong>Your username or IP address has been blocked.</strong>\n\nThe block was made by $1.\nThe reason given is <em>$2</em>.\n\n* Start of block: $8\n* Expiration of block: $6\n* Intended blockee: $7\n\nYou can contact $1 or another [[{{MediaWiki:Grouppage-sysop}}|administrator]] to discuss the block.\nYou cannot use the \"{{int:emailuser}}\" feature unless a valid e-mail address is specified in your [[Special:Preferences|account preferences]] and you have not been blocked from using it.\nYour current IP address is $3, and the block ID is #$5.\nPlease include all above details in any queries you make.",
        "autoblockedtext": "Your IP address has been automatically blocked because it was used by another user, who was blocked by $1.\nThe reason given is:\n\n:<em>$2</em>\n\n* Start of block: $8\n* Expiry of block: $6\n* Intended blockee: $7\n\nYou may contact $1 or one of the other [[{{MediaWiki:Grouppage-sysop}}|administrators]] to discuss the block.\n\nNote that you may not use the \"email this user\" feature unless you have a valid email address registered in your [[Special:Preferences|user preferences]] and you have not been blocked from using it.\n\nYour current IP address is $3, and the block ID is #$5.\nPlease include all above details in any queries you make.",
        "loginreqlink": "log in",
        "noarticletext": "There is currently no text in this page.\nYou can [[Special:Search/{{PAGENAME}}|search for this page title]] in other pages,\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} search the related logs],\nor [{{fullurl:{{FULLPAGENAME}}|action=edit}} create this page]</span>.",
        "boteditletter": "b",
        "rc-change-size-new": "$1 {{PLURAL:$1|byte|bytes}} after change",
        "recentchangeslinked-toolbox": "Related changes",
-       "recentchangeslinked-summary": "This is a list of changes made recently to pages linked from a specified page (or to members of a specified category).\nPages on [[Special:Watchlist|your watchlist]] are <strong>bold</strong>.",
+       "recentchangeslinked-summary": "Enter a page name to see changes on the pages linked to or from that page. (To see members of a category, enter \"{{ns:category}}:Name of category\"). Changes to pages on [[Special:Watchlist|your Watchlist]] are highlighted in <strong>bold</strong>.",
        "upload": "Upload file",
        "license": "Licencing:",
        "license-header": "Licencing",
        "newpages": "New pages",
        "allpagessubmit": "Go",
        "listgrants-summary": "The following is a list of grants with their associated access to user rights. Users can authorise applications to use their account, but with limited permissions based on the grants the user gave to the application. An application acting on behalf of a user cannot actually use rights that the user does not have however.\nThere may be [[{{MediaWiki:Listgrouprights-helppage}}|additional information]] about individual rights.",
+       "emailuser": "E-mail this user",
        "wlshowhidecategorization": "page categorisation",
        "rollbacklink": "rollback",
        "sessionfailure": "There seems to be a problem with your login session;\nthis action has been cancelled as a precaution against session hijacking.\nGo back to the previous page, reload that page and then try again.",
        "tooltip-t-whatlinkshere": "A list of all wiki pages that link here",
        "tooltip-t-recentchangeslinked": "Recent changes in pages linked from this page",
        "tooltip-feed-atom": "Atom feed for this page",
+       "tooltip-t-emailuser": "Send an e-mail to {{GENDER:$1|this user}}",
        "tooltip-t-upload": "Upload files",
        "tooltip-t-specialpages": "A list of all special pages",
        "tooltip-t-print": "Printable version of this page",
index f36c8ed..0948136 100644 (file)
        "customcssprotected": "You do not have permission to edit this CSS page because it contains another user's personal settings.",
        "customjsonprotected": "You do not have permission to edit this JSON page because it contains another user's personal settings.",
        "customjsprotected": "You do not have permission to edit this JavaScript page because it contains another user's personal settings.",
+       "sitecssprotected": "You do not have permission to edit this CSS page because it may affect all visitors",
+       "sitejsonprotected": "You do not have permission to edit this JSON page because it may affect all visitors",
+       "sitejsprotected": "You do not have permission to edit this JavaScript page because it may affect all visitors",
        "mycustomcssprotected": "You do not have permission to edit this CSS page.",
        "mycustomjsonprotected": "You do not have permission to edit this JSON page.",
        "mycustomjsprotected": "You do not have permission to edit this JavaScript page.",
        "resetpass-submit-loggedin": "Change password",
        "resetpass-submit-cancel": "Cancel",
        "resetpass-wrong-oldpass": "Invalid temporary or current password.\nYou may have already changed your password or requested a new temporary password.",
-       "resetpass-recycled": "Please reset your password to something other than your current password.",
+       "resetpass-recycled": "Please change your password to something other than your current password.",
        "resetpass-temp-emailed": "You logged in with a temporary emailed code.\nTo finish logging in, you must set a new password here:",
        "resetpass-temp-password": "Temporary password:",
        "resetpass-abort-generic": "Password change has been aborted by an extension.",
        "resetpass-expired": "Your password has expired. Please set a new password to log in.",
-       "resetpass-expired-soft": "Your password has expired and needs to be reset. Please choose a new password now, or click \"{{int:authprovider-resetpass-skip-label}}\" to reset it later.",
-       "resetpass-validity-soft": "Your password is not valid: $1\n\nPlease choose a new password now, or click \"{{int:authprovider-resetpass-skip-label}}\" to reset it later.",
+       "resetpass-expired-soft": "Your password has expired and needs to be changed. Please choose a new password now, or click \"{{int:authprovider-resetpass-skip-label}}\" to change it later.",
+       "resetpass-validity-soft": "Your password is not valid: $1\n\nPlease choose a new password now, or click \"{{int:authprovider-resetpass-skip-label}}\" to change it later.",
        "passwordreset": "Reset password",
        "passwordreset-text-one": "Complete this form to receive a temporary password via email.",
        "passwordreset-text-many": "{{PLURAL:$1|Fill in one of the fields to receive a temporary password via email.}}",
        "converter-manual-rule-error": "Error detected in manual language conversion rule",
        "undo-success": "The edit can be undone.\nPlease check the comparison below to verify that this is what you want to do, and then save the changes below to finish undoing the edit.",
        "undo-failure": "The edit could not be undone due to conflicting intermediate edits.",
+       "undo-main-slot-only": "The edit could not be undone because it involves content outside the main slot.",
        "undo-norev": "The edit could not be undone because it does not exist or was deleted.",
        "undo-nochange": "The edit appears to have already been undone.",
        "undo-summary": "Undo revision $1 by [[Special:Contributions/$2|$2]] ([[User talk:$2|talk]])",
        "difference-missing-revision": "{{PLURAL:$2|One revision|$2 revisions}} of this difference ($1) {{PLURAL:$2|was|were}} not found.\n\nThis is usually caused by following an outdated diff link to a page that has been deleted.\nDetails can be found in the [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} deletion log].",
        "search-summary": "",
        "searchresults": "Search results",
+       "search-filter-title-prefix": "Only searching in pages whose title starts with \"$1\"",
+       "search-filter-title-prefix-reset": "Search all pages",
        "searchresults-title": "Search results for \"$1\"",
        "titlematches": "Page title matches",
        "textmatches": "Page text matches",
        "group-autoconfirmed": "Autoconfirmed users",
        "group-bot": "Bots",
        "group-sysop": "Administrators",
+       "group-interface-admin": "Interface administrators",
        "group-bureaucrat": "Bureaucrats",
        "group-suppress": "Suppressors",
        "group-all": "(all)",
        "group-autoconfirmed-member": "{{GENDER:$1|autoconfirmed user}}",
        "group-bot-member": "{{GENDER:$1|bot}}",
        "group-sysop-member": "{{GENDER:$1|administrator}}",
+       "group-interface-admin-member": "{{GENDER:$1|interface administrator}}",
        "group-bureaucrat-member": "{{GENDER:$1|bureaucrat}}",
        "group-suppress-member": "{{GENDER:$1|suppressor}}",
        "grouppage-user": "{{ns:project}}:Users",
        "grouppage-autoconfirmed": "{{ns:project}}:Autoconfirmed users",
        "grouppage-bot": "{{ns:project}}:Bots",
        "grouppage-sysop": "{{ns:project}}:Administrators",
+       "grouppage-interface-admin": "{{ns:project}}:Interface administrators",
        "grouppage-bureaucrat": "{{ns:project}}:Bureaucrats",
        "grouppage-suppress": "{{ns:project}}:Suppress",
        "right-read": "Read pages",
        "right-editusercss": "Edit other users' CSS files",
        "right-edituserjson": "Edit other users' JSON files",
        "right-edituserjs": "Edit other users' JavaScript files",
+       "right-editsitecss": "Edit sitewide CSS",
+       "right-editsitejson": "Edit sitewide JSON",
+       "right-editsitejs": "Edit sitewide JavaScript",
        "right-editmyusercss": "Edit your own user CSS files",
        "right-editmyuserjson": "Edit your own user JSON files",
        "right-editmyuserjs": "Edit your own user JavaScript files",
        "grant-createaccount": "Create accounts",
        "grant-createeditmovepage": "Create, edit, and move pages",
        "grant-delete": "Delete pages, revisions, and log entries",
-       "grant-editinterface": "Edit the MediaWiki namespace and user CSS/JSON/JavaScript",
+       "grant-editinterface": "Edit the MediaWiki namespace and sitewide/user JSON",
        "grant-editmycssjs": "Edit your user CSS/JSON/JavaScript",
        "grant-editmyoptions": "Edit your user preferences",
        "grant-editmywatchlist": "Edit your watchlist",
+       "grant-editsiteconfig": "Edit sitewide and user CSS/JS",
        "grant-editpage": "Edit existing pages",
        "grant-editprotected": "Edit protected pages",
        "grant-highvolume": "High-volume editing",
        "rcfilters-other-review-tools": "Other review tools",
        "rcfilters-group-results-by-page": "Group results by page",
        "rcfilters-activefilters": "Active filters",
+       "rcfilters-activefilters-hide": "Hide",
+       "rcfilters-activefilters-show": "Show",
+       "rcfilters-activefilters-hide-tooltip": "Hide Active Filters area",
+       "rcfilters-activefilters-show-tooltip": "Show Active Filters area",
        "rcfilters-advancedfilters": "Advanced filters",
        "rcfilters-limit-title": "Results to show",
        "rcfilters-limit-and-date-label": "$1 {{PLURAL:$1|change|changes}}, $2",
        "rcfilters-savedqueries-rename": "Rename",
        "rcfilters-savedqueries-setdefault": "Set as default",
        "rcfilters-savedqueries-unsetdefault": "Remove as default",
-       "rcfilters-savedqueries-remove": "Remove",
+       "rcfilters-savedqueries-remove": "Delete",
        "rcfilters-savedqueries-new-name-label": "Name",
        "rcfilters-savedqueries-new-name-placeholder": "Describe the purpose of the filter",
        "rcfilters-savedqueries-apply-label": "Create filter",
        "rcfilters-empty-filter": "No active filters. All contributions are shown.",
        "rcfilters-filterlist-title": "Filters",
        "rcfilters-filterlist-whatsthis": "How do these work?",
-       "rcfilters-filterlist-feedbacklink": "Tell us what you think about these (new) filtering tools",
+       "rcfilters-filterlist-feedbacklink": "Tell us what you think about these filtering tools",
        "rcfilters-highlightbutton-title": "Highlight results",
        "rcfilters-highlightmenu-title": "Select a color",
        "rcfilters-highlightmenu-help": "Select a color to highlight this property",
        "rcfilters-watchlist-showupdated": "Changes to pages you haven't visited since the changes occurred are in <strong>bold</strong>, with solid markers.",
        "rcfilters-preference-label": "Hide the improved version of Recent Changes",
        "rcfilters-preference-help": "Rolls back the 2017 interface redesign and all tools added then and since.",
+       "rcfilters-watchlist-preference-label": "Hide the improved version of the Watchlist",
+       "rcfilters-watchlist-preference-help": "Rolls back the 2017 interface redesign and all tools added then and since.",
        "rcfilters-filter-showlinkedfrom-label": "Show changes on pages linked from",
        "rcfilters-filter-showlinkedfrom-option-label": "<strong>Pages linked from</strong> the selected page",
        "rcfilters-filter-showlinkedto-label": "Show changes on pages linking to",
        "uploadstash-zero-length": "File is zero length.",
        "invalid-chunk-offset": "Invalid chunk offset",
        "img-auth-accessdenied": "Access denied",
-       "img-auth-nopathinfo": "Missing PATH_INFO.\nYour server is not set up to pass this information.\nIt may be CGI-based and cannot support img_auth.\nSee https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization.",
+       "img-auth-nopathinfo": "Missing path information.\nYour server must be set up to pass the REQUEST_URI and/or PATH_INFO variables.\nIf it is, try enabling $wgUsePathInfo.\nSee https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization.",
        "img-auth-notindir": "Requested path is not in the configured upload directory.",
        "img-auth-badtitle": "Unable to construct a valid title from \"$1\".",
        "img-auth-nologinnWL": "You are not logged in and \"$1\" is not in the whitelist.",
        "http-timed-out": "HTTP request timed out.",
        "http-curl-error": "Error fetching URL: $1",
        "http-bad-status": "There was a problem during the HTTP request: $1 $2",
+       "http-internal-error": "HTTP internal error.",
        "upload-curl-error6": "Could not reach URL",
        "upload-curl-error6-text": "The URL provided could not be reached.\nPlease double-check that the URL is correct and the site is up.",
        "upload-curl-error28": "Upload timeout",
        "speciallogtitlelabel": "Target (title or {{ns:user}}:username for user):",
        "log": "Logs",
        "logeventslist-submit": "Show",
+       "logeventslist-more-filters": "Show additional logs:",
+       "logeventslist-patrol-log": "Patrol log",
+       "logeventslist-tag-log": "Tag log",
        "all-logs-page": "All public logs",
        "alllogstext": "Combined display of all available logs of {{SITENAME}}.\nYou can narrow down the view by selecting a log type, the username (case-sensitive), or the affected page (also case-sensitive).",
        "logempty": "No matching items in log.",
        "categories": "Categories",
        "categories-summary": "",
        "categories-submit": "Show",
-       "categoriespagetext": "The following {{PLURAL:$1|category contains|categories contain}} pages or media.\n[[Special:UnusedCategories|Unused categories]] are not shown here.\nAlso see [[Special:WantedCategories|wanted categories]].",
+       "categoriespagetext": "The following {{PLURAL:$1|category exists|categories exist}} on the wiki, and may or may not be unused.\nAlso see [[Special:WantedCategories|wanted categories]].",
        "categoriesfrom": "Display categories starting at:",
        "deletedcontributions": "Deleted user contributions",
        "deletedcontributions-summary": "",
        "dellogpage": "Deletion log",
        "dellogpagetext": "Below is a list of the most recent deletions.",
        "deletionlog": "deletion log",
+       "log-name-create": "Page creation log",
+       "log-description-create": "Below is a list of the most recent page creations.",
+       "logentry-create-create": "$1 {{GENDER:$2|created}} page $3",
        "reverted": "Reverted to earlier revision",
        "deletecomment": "Reason:",
        "deleteotherreason": "Other/additional reason:",
        "uctop": "(current)",
        "month": "From month (and earlier):",
        "year": "From year (and earlier):",
+       "date": "From date (and earlier):",
        "sp-contributions-newbies": "Show contributions of new accounts only",
        "sp-contributions-newbies-sub": "For new accounts",
        "sp-contributions-newbies-title": "User contributions for new accounts",
        "whatlinkshere-title": "Pages that link to \"$1\"",
        "whatlinkshere-summary": "",
        "whatlinkshere-page": "Page:",
-       "linkshere-2": "The following pages link to <strong>$1</strong>:",
-       "nolinkshere-2": "No pages link to <strong>$1</strong>.",
-       "nolinkshere-ns-2": "No pages link to <strong>$1</strong> in the chosen namespace.",
+       "linkshere": "The following pages link to <strong>$2</strong>:",
+       "nolinkshere": "No pages link to <strong>$2</strong>.",
+       "nolinkshere-ns": "No pages link to <strong>$2</strong> in the chosen namespace.",
        "isredirect": "redirect page",
        "istemplate": "transclusion",
        "isimage": "file link",
        "markedaspatrollederrornotify": "Marking as patrolled failed.",
        "patrol-log-page": "Patrol log",
        "patrol-log-header": "This is a log of patrolled revisions.",
-       "log-show-hide-patrol": "$1 patrol log",
-       "log-show-hide-tag": "$1 tag log",
        "confirm-markpatrolled-button": "OK",
        "confirm-markpatrolled-top": "Mark revision $3 of $2 as patrolled?",
        "deletedrevision": "Deleted old revision $1",
        "edit-error-long": "Errors:\n\n$1",
        "revid": "revision $1",
        "pageid": "page ID $1",
+       "interfaceadmin-info": "$1\n\nPermissions for editing of sitewide CSS/JS/JSON files were recently separated from the <code>editinterface</code> right. If you do not understand why you are getting this error, see [[mw:MediaWiki_1.32/interface-admin]].",
        "rawhtml-notallowed": "&lt;html&gt; tags cannot be used outside of normal pages.",
        "gotointerwiki": "Leaving {{SITENAME}}",
        "gotointerwiki-invalid": "The specified title is invalid.",
        "unregistered-user-config": "For security reasons JavaScript, CSS and JSON user subpages cannot be loaded for unregistered users.",
        "passwordpolicies": "Password policies",
        "passwordpolicies-summary": "This is a list of the effective password policies for the user groups defined in this wiki.",
-       "passwordpolicies-helppage": "Manual:$wgPasswordPolicy",
        "passwordpolicies-group": "Group",
        "passwordpolicies-policies": "Policies",
        "passwordpolicies-policy-display": "<span class=\"passwordpolicies-policy\">$1 <code>($2)</code></span>",
        "passwordpolicies-policy-passwordcannotmatchusername": "Password cannot be the same as username",
        "passwordpolicies-policy-passwordcannotmatchblacklist": "Password cannot match specifically blacklisted passwords",
        "passwordpolicies-policy-maximalpasswordlength": "Password must be less than $1 {{PLURAL:$1|character|characters}} long",
-       "passwordpolicies-policy-passwordcannotbepopular": "Password cannot be {{PLURAL:$1|the popular password|in the list of $1 popular passwords}}"
+       "passwordpolicies-policy-passwordcannotbepopular": "Password cannot be {{PLURAL:$1|the popular password|in the list of $1 popular passwords}}",
+       "easydeflate-invaliddeflate": "Content provided is not properly deflated"
 }
index cebd18b..8348065 100644 (file)
        "resetpass-temp-password": "Provizora pasvorto:",
        "resetpass-abort-generic": "Ŝanĝo de pasvorto estis nuligita per kromprogramo.",
        "resetpass-expired": "Via pasvorto eksvalidiĝis. Bonvolu difini novan pasvorton por la alsalutado.",
-       "resetpass-expired-soft": "Via pasvorto eksvalidiĝis kaj devas esti rekomencigata. Bonvolu nun elekti novan pasvorton, aŭ klaki \"{{int:authprovider-resetpass-skip-label}}\" por rekomencigi ĝin pli malfrue.",
+       "resetpass-expired-soft": "Via pasvorto eksvalidiĝis kaj devas esti ŝanĝata. Bonvolu nun elekti novan pasvorton, aŭ klaki \"{{int:authprovider-resetpass-skip-label}}\" por ŝanĝi ĝin pli malfrue.",
        "resetpass-validity-soft": "Via pasvorto ne estas valida: $1\n\nBonvolu elekti novan pasvorton nun, aŭ klaku \"{{int:authprovider-resetpass-skip-label}}\", por rekomencigi ĝin pli malfrue.",
        "passwordreset": "Restarigo de pasvorto",
        "passwordreset-text-one": "Plenigu ĉi tiun formularon por renovigi vian pasvorton.",
        "revdelete-edit-reasonlist": "Redakti kialojn por forigo",
        "revdelete-offender": "Aŭtoro de revizio:",
        "suppressionlog": "Protokolo pri subigado",
-       "suppressionlogtext": "Malsupre estas listo de forigoj kaj forbaroj pri enhavo kaŝita de administrantoj.\nRigardu la [[Special:BlockList|forbarliston]] por la listo de nune operaciaj forbaroj kaj forigoj.",
+       "suppressionlogtext": "Jen listo de forigoj kaj forbaroj pri enhavo kaŝita per administrantoj.\nVidi la [[Special:BlockList|forbarliston]] por la listo de forigoj kaj forbaroj aktuale operaciaj.",
        "mergehistory": "Kunigi historiojn de paĝoj",
        "mergehistory-header": "Ĉi tiu paĝo permesas al vi kunigi versiojn de la historio de unu fonta paĝo en pli novan paĝon.\nCertigu ke ĉi tiu ŝanĝo tenos kontinuecon de la historia paĝo.",
        "mergehistory-box": "Kunigi versiojn de du paĝoj:",
        "whatlinkshere": "Ligiloj ĉi tien",
        "whatlinkshere-title": "Paĝoj ligantaj al \"$1\"",
        "whatlinkshere-page": "Paĝo:",
-       "linkshere-2": "La jenaj paĝoj ligas al '''$1''':",
-       "nolinkshere-2": "Neniu paĝo ligas al '''$1'''.",
-       "nolinkshere-ns-2": "Neniuj paĝoj ligas al '''$1''' en la elektita nomspaco.",
+       "linkshere": "La jenaj paĝoj ligas al <strong>$2</strong>:",
+       "nolinkshere": "Neniu paĝo ligas al <strong>$2</strong>.",
+       "nolinkshere-ns": "Neniuj paĝoj ligas al '''$2''' en la elektita nomspaco.",
        "isredirect": "alidirektilo",
        "istemplate": "inkludo",
        "isimage": "ligilo al dosiero",
        "markedaspatrollederrornotify": "Malsukcesis marki la dosieron kiel patrolatan.",
        "patrol-log-page": "Protokolo pri patrolado",
        "patrol-log-header": "Jen protokolo de patrolitaj versioj.",
-       "log-show-hide-patrol": "$1 protokolo pri patrolado",
-       "log-show-hide-tag": "$1 etikedan protokolon",
        "confirm-markpatrolled-button": "Ek!",
        "confirm-markpatrolled-top": "Marki version $3 el $2 kiel patrolita?",
        "deletedrevision": "Forigita malnova versio $1",
index 99d0511..3a99aaa 100644 (file)
        "mycustomjsprotected": "No tiene permiso para editar esta página JavaScript.",
        "myprivateinfoprotected": "No tiene permiso para editar su información privada.",
        "mypreferencesprotected": "No tiene permiso para editar sus preferencias.",
-       "exception-nologin-text": "Por favor inicie sesión para acceder a esta página o llevar a cabo esta acción.",
+       "exception-nologin-text": "Necesita acceder para ver esta página o llevar a cabo esta acción.",
        "exception-nologin-text-manual": "Necesita $1 para poder ver esta página o llevar a cabo esta acción.",
        "logouttext": "<strong>Su sesión ha finalizado.</strong>\n\nPuede que algunas páginas continúen mostrándose como si la sesión estuviera iniciada hasta que actualice la caché de su navegador.",
        "welcomeuser": "Le damos la bienvenida, $1.",
index a500fa5..82eb62a 100644 (file)
                        "KATRINE1992",
                        "Athena in Wonderland",
                        "Truebamateo",
-                       "La Mantis"
+                       "La Mantis",
+                       "Amaia",
+                       "Tiberius1701",
+                       "Astroemi"
                ]
        },
        "tog-underline": "Subrayar los enlaces:",
        "title-invalid-interwiki": "El título de página solicitado contiene un enlace interwiki que no se puede usar en los títulos.",
        "title-invalid-talk-namespace": "El título de la página solicitada apunta a una página de discusión imposible.",
        "title-invalid-characters": "El título  de la página solicitada contiene caracteres no válidos: \"$1\".",
-       "title-invalid-relative": "El título contiene una ruta relativa. Los títulos relativos (./, ../) no son válidos porque a menudo no los pueden manejar los navegadores web.",
+       "title-invalid-relative": "El título contiene una ruta relativa. Los títulos relativos (./, ../) no son válidos porque a menudo no los pueden manipular los navegadores web.",
        "title-invalid-magic-tilde": "El título de la página solicitada contiene una secuencia de virgulillas no válida (<nowiki>~~~</nowiki>).",
        "title-invalid-too-long": "El título de la página solicitada es muy largo. No debe exceder $1 {{PLURAL:$1|byte|bytes}} en codificación UTF-8.",
        "title-invalid-leading-colon": "El título de la página solicitada contiene un caracater (:) no válido en el comienzo.",
        "createacct-another-realname-tip": "El nombre real es opcional.\nSi lo proporcionas, se usará para dar atribución al trabajo del usuario.",
        "pt-login": "Acceder",
        "pt-login-button": "Acceder",
-       "pt-login-continue-button": "Continuar inicio de sesión",
+       "pt-login-continue-button": "Continuar con el acceso",
        "pt-createaccount": "Crear una cuenta",
        "pt-userlogout": "Salir",
        "php-mail-error-unknown": "Error desconocido en la función mail() de PHP.",
        "resetpass-submit-loggedin": "Cambiar contraseña",
        "resetpass-submit-cancel": "Cancelar",
        "resetpass-wrong-oldpass": "La contraseña actual, o temporal, no es correcta.\nPuede que ya hayas cambiado tu contraseña o que hayas pedido una nueva contraseña temporal.",
-       "resetpass-recycled": "Restablece tu contraseña a algo distinto de tu contraseña actual.",
+       "resetpass-recycled": "Cambia tu contraseña a algo distinto de tu contraseña actual.",
        "resetpass-temp-emailed": "Has iniciado sesión con una contraseña temporal enviada por correo electrónico.\nPara continuar, debes establecer una nueva contraseña aquí:",
        "resetpass-temp-password": "Contraseña temporal:",
        "resetpass-abort-generic": "Una extensión ha cancelado el cambio de la contraseña.",
        "resetpass-expired": "Tu contraseña ha caducado. Por favor, establece una nueva contraseña para iniciar sesión.",
-       "resetpass-expired-soft": "Tu contraseña ha caducado, por lo que debes restablecerla. Cámbiala ahora por una nueva, o haz clic en \"{{int:authprovider-resetpass-skip-label}}\" para restablecerla más adelante.",
-       "resetpass-validity-soft": "Tu contraseña no es válida: $1\n\nCámbiala ahora por una nueva, o haz clic en \"{{int:authprovider-resetpass-skip-label}}\" para cambiarla más tarde.",
+       "resetpass-expired-soft": "Tu contraseña ha caducado, por lo que debes cambiarla. Elige ahora una contraseña nueva o pulsa en «{{int:authprovider-resetpass-skip-label}}» para cambiarla más tarde.",
+       "resetpass-validity-soft": "La contraseña no es válida: $1\n\nCámbiala ahora por una nueva, o bien, pulsa en «{{int:authprovider-resetpass-skip-label}}» para cambiarla más tarde.",
        "passwordreset": "Restablecer contraseña",
        "passwordreset-text-one": "Completa este formulario para recibir una contraseña temporal por correo electrónico.",
        "passwordreset-text-many": "{{PLURAL:$1|Rellena uno de los campos para recibir una contraseña temporal por correo electrónico.}}",
        "expansion-depth-exceeded-category": "Páginas que sobrepasan la profundidad de expansión",
        "expansion-depth-exceeded-category-desc": "Esta página sobrepasa la profundidad de expansión máxima.",
        "expansion-depth-exceeded-warning": "La página ha sobrepasado el límite de profundidad de expansión",
-       "parser-unstrip-loop-warning": "Se ha detectado un bucle en la función \"unstrip\"",
-       "unstrip-depth-warning": "Se ha superado el límite de recursividad de la función \"unstrip\" ($1)",
+       "parser-unstrip-loop-warning": "Se ha detectado un bucle en la función «unstrip»",
+       "unstrip-depth-warning": "Se ha superado el límite de recursividad de la función «unstrip» ($1)",
+       "unstrip-depth-category": "Páginas en que se excede el límite de profundidad de la función «unstrip»",
+       "unstrip-size-warning": "Se excedió el límite de tamaño de la función «unstrip» ($1)",
+       "unstrip-size-category": "Páginas en que se excede el límite de tamaño de la función «unstrip»",
        "converter-manual-rule-error": "Se ha detectado un error en una regla manual de conversión de idioma",
        "undo-success": "Puedes deshacer la edición. Antes de deshacer la edición, comprueba la siguiente comparación para verificar que realmente es lo que quieres hacer, y entonces guarda los cambios para así efectuar la reversión.",
        "undo-failure": "No se ha podido deshacer la edición ya que otro usuario ha realizado una edición intermedia.",
+       "undo-main-slot-only": "No se ha podido desacer el cámbio porque contiene contenido fuera del slot principal.",
        "undo-norev": "No se ha podido deshacer la edición porque no existe o ha sido borrada.",
        "undo-nochange": "Parece que ya se había deshecho la edición.",
        "undo-summary": "Se ha deshecho la revisión $1 de [[Special:Contributions/$2|$2]] ([[User talk:$2|disc.]])",
        "diff-paragraph-moved-toold": "Se trasladó el párrafo. Pulsa para saltar a la ubicación anterior.",
        "difference-missing-revision": "No se {{PLURAL:$2|ha encontrado una revisión|han encontrado $2 revisiones}} de la comparación solicitada ($1).\n\nLa causa de esto suele ser un enlace obsoleto hacia una edición de una página que ha sido borrada.\nPara más información, consulta el [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} registro de borrados].",
        "searchresults": "Resultados de la búsqueda",
+       "search-filter-title-prefix": "Buscar solo en las páginas cuyos títulos comiencen por «$1»",
+       "search-filter-title-prefix-reset": "Buscar en todas las páginas",
        "searchresults-title": "Resultados de la búsqueda de «$1»",
        "titlematches": "Resultados por título de página",
        "textmatches": "Resultados por texto de página",
        "prefs-watchlist-edits": "Número máximo de ediciones a mostrar en la lista de seguimiento:",
        "prefs-watchlist-edits-max": "Cantidad máxima: 1000",
        "prefs-watchlist-token": "Clave de lista de seguimiento:",
-       "prefs-watchlist-managetokens": "Administrar tokens",
+       "prefs-watchlist-managetokens": "Gestionar fichas",
        "prefs-misc": "Varias",
        "prefs-resetpass": "Cambiar contraseña",
        "prefs-changeemail": "Cambiar o eliminar la dirección de correo electrónico",
        "rcfilters-other-review-tools": "Otras herramientas de revisión",
        "rcfilters-group-results-by-page": "Agrupar resultados por página",
        "rcfilters-activefilters": "Filtros activos",
+       "rcfilters-activefilters-hide": "Ocultar",
+       "rcfilters-activefilters-show": "Mostrar",
+       "rcfilters-activefilters-hide-tooltip": "Ocultar apartado Filtros activos",
+       "rcfilters-activefilters-show-tooltip": "Mostrar apartado Filtros activos",
        "rcfilters-advancedfilters": "Filtros avanzados",
        "rcfilters-limit-title": "Resultados que mostrar",
        "rcfilters-limit-and-date-label": "$1 {{PLURAL:$1|cambio|cambios}}, $2",
        "rcfilters-empty-filter": "No hay filtros activos. Se muestran todas las contribuciones.",
        "rcfilters-filterlist-title": "Filtros",
        "rcfilters-filterlist-whatsthis": "¿Cómo funcionan?",
-       "rcfilters-filterlist-feedbacklink": "Comparte tus comentarios sobre estas (nuevas) herramientas de filtrado",
+       "rcfilters-filterlist-feedbacklink": "Dinos lo que piensas sobre estas herramientas de filtrado",
        "rcfilters-highlightbutton-title": "Resaltar los resultados",
        "rcfilters-highlightmenu-title": "Selecciona un color",
        "rcfilters-highlightmenu-help": "Selecciona un color para resaltar esta propiedad",
        "rcfilters-watchlist-edit-watchlist-button": "Edita tu lista de seguimiento",
        "rcfilters-watchlist-showupdated": "Los cambios hechos a páginas que no has visitado desde que se efectuaron aparecen en <strong>negrita</strong>, acompañados de marcadores sólidos.",
        "rcfilters-preference-label": "Ocultar la versión mejorada de Cambios recientes",
-       "rcfilters-preference-help": "Revierte el rediseño de interfaz de 2017 y desactiva todas las herramientas añadidas desde entonces.",
+       "rcfilters-preference-help": "Revierte el rediseño de interfaz de 2017 e indisponibiliza todas las herramientas añadidas desde entonces.",
+       "rcfilters-watchlist-preference-label": "Ocultar la versión mejorada de la lista de seguimiento",
+       "rcfilters-watchlist-preference-help": "Revierte el rediseño de la interfaz de 2017 e indisponibiliza todas las herramientas añadidas desde entonces.",
        "rcfilters-filter-showlinkedfrom-label": "Mostrar cambios en páginas enlazadas desde",
        "rcfilters-filter-showlinkedfrom-option-label": "<strong>Páginas enlazadas desde</strong> la página seleccionada",
        "rcfilters-filter-showlinkedto-label": "Mostrar cambios en páginas que enlazan a",
        "uploadstash-bad-path-invalid": "La ruta no es válida.",
        "uploadstash-bad-path-unknown-type": "El tipo «$1» es desconocido.",
        "uploadstash-bad-path-unrecognized-thumb-name": "No se reconoce el nombre de la miniatura.",
-       "uploadstash-bad-path-no-handler": "No se encontró ningún manejador para el MIME $1 del archivo $2.",
+       "uploadstash-bad-path-no-handler": "No se encontró ningún manipulador para el MIME $1 del archivo $2.",
        "uploadstash-bad-path-bad-format": "El formato de la clave «$1» es incorrecto.",
        "uploadstash-file-not-found": "No se encuentra la clave «$1» en el almacén provisional.",
        "uploadstash-file-not-found-no-thumb": "No se pudo obtener la miniatura.",
        "http-timed-out": "La solicitud HTTP ha expirado.",
        "http-curl-error": "Error al recuperar el URL: $1",
        "http-bad-status": "Ha habido un problema durante la solicitud HTTP: $1 $2",
+       "http-internal-error": "Error interno de HTTP.",
        "upload-curl-error6": "No se pudo alcanzar la URL",
        "upload-curl-error6-text": "La URL no pudo ser alcanzada. Por favor comprueba que la URL es correcta y el sitio web está funcionando.",
        "upload-curl-error28": "Tiempo de espera excedido",
        "speciallogtitlelabel": "Objetivo (título o {{ns:user}}:nombre de usuario):",
        "log": "Registros",
        "logeventslist-submit": "Mostrar",
+       "logeventslist-more-filters": "Mostrar registros adicionales:",
+       "logeventslist-patrol-log": "Registro de revisiones",
+       "logeventslist-tag-log": "Registro de etiquetas",
        "all-logs-page": "Todos los registros públicos",
        "alllogstext": "Vista combinada de todos los registros de {{SITENAME}}.\nPuedes filtrar la vista seleccionando un tipo de registro, el nombre del usuario o la página afectada. Se distinguen mayúsculas de minúsculas.",
        "logempty": "No hay elementos en el registro con esas condiciones.",
        "dellogpage": "Registro de borrados",
        "dellogpagetext": "A continuación se muestra una lista de los borrados más recientes.",
        "deletionlog": "registro de borrados",
+       "log-name-create": "Registro de creación de páginas",
+       "log-description-create": "La siguiente es una lista de las páginas creadas recientemente.",
+       "logentry-create-create": "$1 {{GENDER:$2|creó}} la página $3",
        "reverted": "Revertido a una revisión anterior",
        "deletecomment": "Motivo:",
        "deleteotherreason": "Otro motivo:",
        "whatlinkshere": "Lo que enlaza aquí",
        "whatlinkshere-title": "Páginas que enlazan con «$1»",
        "whatlinkshere-page": "Página:",
-       "linkshere-2": "Las siguientes páginas enlazan a <strong>$1</strong>:",
-       "nolinkshere-2": "Ninguna página enlaza con <strong>$1</strong>.",
-       "nolinkshere-ns-2": "Ninguna página enlaza con <strong>$1</strong> en el espacio de nombres elegido.",
+       "linkshere": "Las siguientes páginas enlazan a <strong>$2</strong>:",
+       "nolinkshere": "Ninguna página enlaza con <strong>$2</strong>.",
+       "nolinkshere-ns": "Ninguna página enlaza con <strong>$2</strong> en el espacio de nombres elegido.",
        "isredirect": "página redirigida",
        "istemplate": "inclusión",
        "isimage": "enlace de archivo",
        "markedaspatrollederrornotify": "Error al marcar como verificado.",
        "patrol-log-page": "Registro de revisiones",
        "patrol-log-header": "Este es un registro de revisiones verificadas.",
-       "log-show-hide-patrol": "$1 registro de verificación",
-       "log-show-hide-tag": "$1 registro de etiquetas",
        "confirm-markpatrolled-button": "Aceptar",
        "confirm-markpatrolled-top": "¿Marcar la revisión $3 de $2 como verificada?",
        "deletedrevision": "Borrada revisión antigua $1",
        "watchlistedit-raw-removed": "{{PLURAL:$1|Una página ha sido borrada|$1 páginas han sido borradas}}:",
        "watchlistedit-clear-title": "Vaciar la lista de seguimiento",
        "watchlistedit-clear-legend": "Vaciar la lista de seguimiento",
-       "watchlistedit-clear-explain": "Todos los títulos serán eliminados de tu lista de seguimiento",
+       "watchlistedit-clear-explain": "Se quitarán todos los títulos de la lista de seguimiento",
        "watchlistedit-clear-titles": "Títulos:",
        "watchlistedit-clear-submit": "Vaciar la lista de seguimiento (¡permanente!)",
        "watchlistedit-clear-done": "Se ha vaciado tu lista de seguimiento.",
        "version-editors": "Editores",
        "version-antispam": "Prevención de spam",
        "version-other": "Otro",
-       "version-mediahandlers": "Manejadores multimedia",
+       "version-mediahandlers": "Manipuladores multimedia",
        "version-hooks": "Extensiones",
        "version-parser-extensiontags": "Etiquetas de extensiones sintácticas",
        "version-parser-function-hooks": "Extensiones de funciones sintácticas",
        "limitreport-templateargumentsize-value": "$1/$2 {{PLURAL:$2|byte|bytes}}",
        "limitreport-expansiondepth": "Profundidad máxima de expansión",
        "limitreport-expensivefunctioncount": "Cuenta de la función expansiva del analizador",
+       "limitreport-unstrip-depth": "Profundidad de recursión de función «unstrip»",
        "limitreport-unstrip-size-value": "$1/$2 {{PLURAL:$2|byte|bytes}}",
        "expandtemplates": "Expandir plantillas",
        "expand_templates_intro": "Esta página especial toma un texto wiki y expande todas sus plantillas recursivamente.\nTambién expande las funciones sintácticas como <code><nowiki>{{</nowiki>#language:…}}</code>, y variables como\n<code><nowiki>{{</nowiki>CURRENTDAY}}</code>. De hecho, expande casi cualquier cosa que esté entre llaves dobles.",
        "passwordpolicies-policy-passwordcannotmatchusername": "La contraseña no puede ser la misma que el nombre de usuario",
        "passwordpolicies-policy-passwordcannotmatchblacklist": "La contraseña no puede coincidir con la lista de contraseñas específicamente prohibidas",
        "passwordpolicies-policy-maximalpasswordlength": "La contraseña no puede tener más de $1 {{PLURAL:$1|caracter|caracteres}}",
-       "passwordpolicies-policy-passwordcannotbepopular": "La contraseña no puede encontrarse {{PLURAL:$1|en la lista|en las $1 listas}} de contraseñas populares"
+       "passwordpolicies-policy-passwordcannotbepopular": "La contraseña no puede {{PLURAL:$1|ser la contraseña más popular|encontrarse en la lista de $1 contraseñas populares}}"
 }
index abffdb9..a67c238 100644 (file)
        "customcssprotected": "Sul pole õigust seda CSS-lehekülge redigeerida, sest see sisaldab teise kasutaja isiklikke sätteid.",
        "customjsonprotected": "Sul pole lubatud redigeerida seda JSON-lehekülge, sest see sisaldab teise kasutaja isiklikke eelistusi.",
        "customjsprotected": "Sul pole õigust seda JavaScripti lehekülge redigeerida, sest see sisaldab teise kasutaja isiklikke sätteid.",
+       "sitecssprotected": "Sul pole lubatud seda CSS-lehekülge muuta, sest see võib mõjutada kõiki külastajaid.",
+       "sitejsonprotected": "Sul pole lubatud seda JSON-lehekülge muuta, sest see võib mõjutada kõiki külastajaid.",
+       "sitejsprotected": "Sul pole lubatud seda JavaScripti lehekülge muuta, sest see võib mõjutada kõiki külastajaid.",
        "mycustomcssprotected": "Sul pole õigust redigeerida seda CSS-lehekülge.",
        "mycustomjsonprotected": "Sul pole lubatud seda JSON-lehekülge redigeerida.",
        "mycustomjsprotected": "Sul pole õigust redigeerida seda JavaScript-lehekülge.",
        "botpasswords-existing": "Olemasolevad robotiparoolid",
        "botpasswords-createnew": "Uue robotiparooli loomine",
        "botpasswords-editexisting": "Olemasoleva robotiparooli muutmine",
+       "botpasswords-label-needsreset": "(parool vajab lähtestamist)",
        "botpasswords-label-appid": "Robotinimi:",
        "botpasswords-label-create": "Loo",
        "botpasswords-label-update": "Uuenda",
        "botpasswords-restriction-failed": "Robotiparooli piirangud takistavad sisselogimist.",
        "botpasswords-invalid-name": "Määratud kasutajanimi ei sisalda robotiparooli eraldajat (\"$1\").",
        "botpasswords-not-exist": "Kasutaja \"$1\" robotinimele \"$2\" vastav robotiparool puudub.",
+       "botpasswords-needs-reset": "Kasutaja \"$1\" robotinime \"$2\" robotiparool tuleb lähtestada.",
        "resetpass_forbidden": "Paroole ei saa muuta",
        "resetpass_forbidden-reason": "Paroole ei saa muuta: $1",
        "resetpass-no-info": "Pead olema sisselogitud, et sellele lehele pääseda.",
        "subject-preview": "Resümee eelvaade:",
        "previewerrortext": "Sinu muudatuste eelvaatluse juures esines tõrge.",
        "blockedtitle": "Kasutaja on blokeeritud",
-       "blockedtext": "'''Sinu kasutajanimi või IP-aadress on blokeeritud.'''\n\nBlokeeris $1.\nTema põhjendus on järgmine: ''$2''.\n\n* Blokeeringu algus: $8\n* Blokeeringu lõpp: $6\n* Sooviti blokeerida: $7\n\nKüsimuse arutamiseks võid pöörduda kasutaja $1 või mõne teise [[{{MediaWiki:Grouppage-sysop}}|administraatori]] poole.\n\nPane tähele, et sa ei saa kasutajale teadet saata, kui sa pole kinnitanud oma [[Special:Preferences|eelistuste lehel]] kehtivat e-posti aadressi.\n\nSinu praegune IP-aadress on $3 ning blokeeringu number on #$5. Lisa need andmed kõigile järelepärimistele, mida kavatsed teha.",
-       "autoblockedtext": "Sinu IP-aadress blokeeriti automaatselt, sest seda kasutas teine kasutaja, kelle $1 blokeeris.\nPõhjendus on järgmine:\n\n:''$2''\n\n* Blokeeringu algus: $8\n* Blokeeringu lõpp: $6\n* Sooviti blokeerida: $7\n\nKüsimuse arutamiseks võid pöörduda kasutaja $1 või mõne teise [[{{MediaWiki:Grouppage-sysop}}|administraatori]] poole.\n\nPane tähele, et sa ei saa teisele kasutajale teadet saata, kui sa pole kinnitanud oma [[Special:Preferences|eelistuste lehel]] kehtivat e-posti aadressi ega ole selle kasutamisest blokeeritud.\n\nSinu praegune IP-aadress on $3 ja blokeeringu number #$5. Lisa need andmed kõigile järelpärimistele, mida kavatsed teha.",
+       "blockedtext": "<strong>Sinu kasutajanimi või IP-aadress on blokeeritud.</strong>\n\nBlokeeris $1.\nTema põhjendus on järgmine: <em>$2</em>.\n\n* Blokeeringu algus: $8\n* Blokeeringu lõpp: $6\n* Sooviti blokeerida: $7\n\nKüsimuse arutamiseks võid pöörduda kasutaja $1 või mõne teise [[{{MediaWiki:Grouppage-sysop}}|administraatori]] poole.\n\nSa ei saa kasutada funktsiooni \"{{int:emailuser}}\", kui [[Special:Preferences|konto eelistustes]] pole määratud kehtivat e-posti aadressi või kui sul on keelatud seda funktsiooni kasutada.\n\nSinu praegune IP-aadress on $3 ja blokeeringu number on #$5. Palun lisa need andmed kõigile järelepärimistele, mida kavatsed teha.",
+       "autoblockedtext": "Sinu IP-aadress blokeeriti automaatselt, sest seda kasutas teine kasutaja, kelle $1 blokeeris.\nPõhjendus on järgmine:\n\n:<em>$2</em>\n\n* Blokeeringu algus: $8\n* Blokeeringu lõpp: $6\n* Sooviti blokeerida: $7\n\nKüsimuse arutamiseks võid pöörduda kasutaja $1 või mõne teise [[{{MediaWiki:Grouppage-sysop}}|administraatori]] poole.\n\nPane tähele, et sa ei saa kasutada funktsiooni \"{{int:emailuser}}\", kui [[Special:Preferences|konto eelistustes]] pole määratud kehtivat e-posti aadressi või kui sul on keelatud seda funktsiooni kasutada.\n\nSinu praegune IP-aadress on $3 ja blokeeringu number #$5. Palun lisa need andmed kõigile järelpärimistele, mida kavatsed teha.",
        "systemblockedtext": "MediaWiki tarkvara on sinu kasutajanime või IP-aadressi automaatselt blokeerinud.\nToodud on järgmine põhjus:\n\n:<em>$2</em>\n\n* Blokeerimisaeg: $8\n* Blokeeringu aegumistähtaeg: $6\n* Sooviti blokeerida: $7\n\nSinu praegune IP-aadress on $3.\nLisa need andmed kõigile järelepärimistele, mida kavatsed teha.",
        "blockednoreason": "põhjendust ei ole kirja pandud",
        "whitelistedittext": "Lehekülgede toimetamiseks pead $1.",
        "diff-paragraph-moved-toold": "Lõik teisaldati. Klõpsa, et minna vanasse asukohta.",
        "difference-missing-revision": "Selle erinevuste vaate {{PLURAL:$2|üht|$2}} redaktsiooni ($1) ei leitud.\n\nHarilikult tähendab see seda, et sind siia juhatanud link on vananenud ja siin asunud lehekülg on kustutatud.\nÜksikasjad leiad [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} kustutamislogist].",
        "searchresults": "Otsingu tulemused",
+       "search-filter-title-prefix": "Otsitakse ainult lehekülgedelt, mille pealkirja alguses on \"$1\".",
+       "search-filter-title-prefix-reset": "Otsi kõigilt lehekülgedelt",
        "searchresults-title": "Otsingu \"$1\" tulemused",
        "titlematches": "Vasted lehekülje pealkirjades",
        "textmatches": "Vasted lehekülje tekstides",
        "recentchangescount": "Mitut muudatust viimaste muudatuste loendis, lehekülgede ajalugudes ja logides vaikimisi näidata:",
        "prefs-help-recentchangescount": "Suurim võimalik väärtus: 1000",
        "prefs-help-watchlist-token2": "See on sinu jälgimisloendi veebivoo salavõti.\nIgaüks, kes seda teab, saab lugeda sinu jälgimisloendit. Seega ära jaga seda.\n[[Special:ResetTokens|Klõpsa siia, kui sul on vaja see lähtestada]].",
-       "prefs-help-tokenmanagement": "#REDIRECT [[MediaWiki:Prefs-help-watchlist-token2/et]]",
+       "prefs-help-tokenmanagement": "Saad vaadata ja lähtestada salavõtit, mis võimaldab juurdepääsu konto jälgimisloendi veebivoole. Igaüks, kes võtit teab, saab lugeda sinu jälgimisloendit. Seega ära jaga seda.",
        "savedprefs": "Sinu eelistused on salvestatud.",
        "savedrights": "Kasutaja $1 rühmad on salvestatud.",
        "timezonelegend": "Ajavöönd:",
        "group-autoconfirmed": "Automaatselt kinnitatud kasutajad",
        "group-bot": "Robotid",
        "group-sysop": "Administraatorid",
+       "group-interface-admin": "Liidese administraatorid",
        "group-bureaucrat": "Bürokraadid",
        "group-suppress": "Varjajad",
        "group-all": "(kõik)",
        "group-autoconfirmed-member": "automaatselt kinnitatud kasutaja",
        "group-bot-member": "robot",
        "group-sysop-member": "administraator",
+       "group-interface-admin-member": "{{GENDER:$1|liidese administraator}}",
        "group-bureaucrat-member": "bürokraat",
        "group-suppress-member": "varjaja",
        "grouppage-user": "{{ns:project}}:Kasutajad",
        "grouppage-autoconfirmed": "{{ns:project}}:Automaatselt kinnitatud kasutajad",
        "grouppage-bot": "{{ns:project}}:Robotid",
        "grouppage-sysop": "{{ns:project}}:Administraatorid",
+       "grouppage-interface-admin": "{{ns:project}}:Liidese administraatorid",
        "grouppage-bureaucrat": "{{ns:project}}:Bürokraadid",
        "grouppage-suppress": "{{ns:project}}:Varjaja",
        "right-read": "Lugeda lehekülgi",
        "right-editusercss": "Redigeerida teiste kasutajate CSS-faile",
        "right-edituserjson": "Redigeerida teiste kasutajate JSON-faile",
        "right-edituserjs": "Redigeerida teiste kasutajate JS-faile",
+       "right-editsitecss": "Redigeerida saidiülest CSS-i",
+       "right-editsitejson": "Redigeerida saidiülest JSON-i",
+       "right-editsitejs": "Redigeerida saidiülest JavaScripti",
        "right-editmyusercss": "Redigeerida oma CSS-kasutajafaile",
        "right-editmyuserjson": "Redigeerida oma JSON-kasutajafaile",
        "right-editmyuserjs": "Redigeerida oma JavaScript-kasutajafaile",
        "grant-createaccount": "Kontode loomine",
        "grant-createeditmovepage": "Lehekülgede alustamine, muutmine ja teisaldamine",
        "grant-delete": "Lehekülgede, redaktsioonide ja logisissekannete kustutamine",
-       "grant-editinterface": "MediaWiki nimeruumi ning kasutaja CSSi, JSONi ja JavaScripti redigeerimine",
+       "grant-editinterface": "MediaWiki nimeruumi ning saidiülese ja kasutaja JSONi redigeerimine",
        "grant-editmycssjs": "Oma CSSi, JSONi või JavaScripti muutmine",
        "grant-editmyoptions": "Enda eelistuste muutmine",
        "grant-editmywatchlist": "Oma jälgimisloendi muutmine",
+       "grant-editsiteconfig": "Saidiülese ning kasutaja CSSi ja JavaScripti muutmine",
        "grant-editpage": "Olemasolevate lehekülgede redigeerimine",
        "grant-editprotected": "Kaitstud lehekülgede redigeerimine",
        "grant-highvolume": "Suuremahuline redigeerimine",
        "rcfilters-other-review-tools": "Muud ülevaatusriistad",
        "rcfilters-group-results-by-page": "Rühmita tulemused lehekülje kaupa",
        "rcfilters-activefilters": "Aktiivsed filtrid",
+       "rcfilters-activefilters-hide": "Peida",
+       "rcfilters-activefilters-show": "Näita",
+       "rcfilters-activefilters-hide-tooltip": "Peida aktiivsete filtrite ala",
+       "rcfilters-activefilters-show-tooltip": "Kuva aktiivsete filtrite ala",
        "rcfilters-advancedfilters": "Täpsemad filtrid",
        "rcfilters-limit-title": "Näita nii mitut tulemust",
        "rcfilters-limit-and-date-label": "$1 {{PLURAL:$1|muudatus|muudatust}}, $2",
        "rcfilters-highlighted-filters-list": "Esile tõstetud: $1",
        "rcfilters-quickfilters": "Salvestatud filtrid",
        "rcfilters-quickfilters-placeholder-title": "Filtreid pole veel salvestatud",
-       "rcfilters-quickfilters-placeholder-description": "Et filtri sätted salvestada ja et neid hiljem uuesti kasutada, klõpsa alloleva aktiivsete filtrite loendi juures järjehoidjaikooni.",
+       "rcfilters-quickfilters-placeholder-description": "Salvestamaks filtri sätted, et neid hiljem uuesti kasutada, klõpsa alloleva aktiivsete filtrite loendi juures järjehoidjaikooni.",
        "rcfilters-savedqueries-defaultlabel": "Salvestatud filtrid",
        "rcfilters-savedqueries-rename": "Nimeta ümber",
-       "rcfilters-savedqueries-setdefault": "Määra vaikefiltriteks",
+       "rcfilters-savedqueries-setdefault": "Määra vaikefiltriks",
        "rcfilters-savedqueries-unsetdefault": "Tühista vaikevalik",
-       "rcfilters-savedqueries-remove": "Eemalda",
+       "rcfilters-savedqueries-remove": "Kustuta",
        "rcfilters-savedqueries-new-name-label": "Nimi",
        "rcfilters-savedqueries-new-name-placeholder": "Kirjelda filtri otstarvet",
        "rcfilters-savedqueries-apply-label": "Koosta filter",
        "rcfilters-restore-default-filters": "Taasta vaikefiltrid",
        "rcfilters-clear-all-filters": "Eemalda kõik filtrid",
        "rcfilters-show-new-changes": "Vaata uusimaid muudatusi",
-       "rcfilters-search-placeholder": "Filtri muudatusi (kasuta menüüd või otsi filtri nime)",
+       "rcfilters-search-placeholder": "Filtreeri muudatusi (kasuta menüüd või tipi filtri nimi)",
        "rcfilters-invalid-filter": "Vigane filter",
        "rcfilters-empty-filter": "Aktiivsed filtrid puuduvad. Näidatakse kogu kaastööd.",
        "rcfilters-filterlist-title": "Filtrid",
        "rcfilters-filterlist-whatsthis": "Kuidas see töötab?",
-       "rcfilters-filterlist-feedbacklink": "Ütle meile, mida arvad neist uutest filtririistadest.",
+       "rcfilters-filterlist-feedbacklink": "Ütle meile, mida arvad neist filtririistadest.",
        "rcfilters-highlightbutton-title": "Tulemuste esiletõst",
        "rcfilters-highlightmenu-title": "Vali värvus",
        "rcfilters-highlightmenu-help": "Vali värvus, et see atribuut esile tõsta",
        "rcfilters-watchlist-showupdated": "Muudatused lehekülgedel, mida sa pole pärast muudatuste tegemist külastanud, on <strong>rasvases</strong> kirjas ja tähistatud täidetud punktiga.",
        "rcfilters-preference-label": "Peida viimaste muudatuste täiustatud versioon",
        "rcfilters-preference-help": "Pöörab tagasi 2017. aastast alates tehtud muudatused kujunduses ja lisatud tööriistad.",
+       "rcfilters-watchlist-preference-label": "Peida jälgimisloendi täiustatud versioon",
+       "rcfilters-watchlist-preference-help": "Pöörab tagasi 2017. aastast alates tehtud muudatused kujunduses ja lisatud tööriistad.",
        "rcfilters-filter-showlinkedfrom-label": "Näita muudatusi lehekülgedel, millele viidatakse leheküljelt:",
        "rcfilters-filter-showlinkedfrom-option-label": "<strong>Leheküljed, millele viidatakse</strong> valitud leheküljel",
        "rcfilters-filter-showlinkedto-label": "Näita muudatusi lehekülgedel, millel viidatakse leheküljele",
        "recentchangeslinked-feed": "Seotud muudatused",
        "recentchangeslinked-toolbox": "Seotud muudatused",
        "recentchangeslinked-title": "Leheküljega \"$1\" seotud muudatused",
-       "recentchangeslinked-summary": "Sisesta lehekülje pealkri, et näha muudatusi lehekülgedel, mis viitavad sellele leheküljele, või millele viidatakse sellel leheküljel. Et näha kategooria liikmeid, sisesta \"Kategooria:Kategooria pealkiri\". Sinu [[Special:Watchlist|jälgimisloendi]] leheküljed on  <strong>rasvases kirjas</strong>.",
+       "recentchangeslinked-summary": "Sisesta lehekülje pealkri, et näha muudatusi lehekülgedel, mis viitavad sellele leheküljele, või millele viidatakse sellel leheküljel. Et näha kategooria liikmeid, sisesta \"{{ns:category}}:Kategooria pealkiri\". Sinu [[Special:Watchlist|jälgimisloendi]] leheküljed on  <strong>rasvases kirjas</strong>.",
        "recentchangeslinked-page": "Lehekülje nimi:",
        "recentchangeslinked-to": "Näita hoopis muudatusi lehekülgedel, mis sellele lehele lingivad",
        "recentchanges-page-added-to-category": "kategooriasse lisatud \"[[:$1]]\"",
        "uploadstash-zero-length": "Faili suurus on tühiväärtusega.",
        "invalid-chunk-offset": "Tüki vigane nihe",
        "img-auth-accessdenied": "Juurdepääs keelatud",
-       "img-auth-nopathinfo": "PATH_INFO puudub.\nSinu server pole seadistatud seda teavet edastama.\nSee võib olla CGI-põhine ja ei toeta img_auth-i.\nVaata lehekülge https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization.",
+       "img-auth-nopathinfo": "Puudub teave tee kohta.\nServer peab olema seadistatud edastama muutujaid REQUEST_URI ja/või PATH_INFO.\nKui on, siis proovi lubada säte $wgUsePathInfo.\nVaata lehekülge https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization.",
        "img-auth-notindir": "Soovitud salvestuskoht pole üleslaadimiskataloogi all.",
        "img-auth-badtitle": "Väljendist \"$1\" ei saa sobivat pealkirja moodustada.",
        "img-auth-nologinnWL": "Sa pole sisselogitud ja \"$1\" pole valges nimekirjas.",
        "http-timed-out": "HTTP-päring aegus.",
        "http-curl-error": "Tõrge URL-i $1 lugemisel",
        "http-bad-status": "HTTP-päringu ajal ilmnes tõrge: $1 $2",
+       "http-internal-error": "HTTP sisetõrge.",
        "upload-curl-error6": "Internetiaadress pole kättesaadav",
        "upload-curl-error6-text": "Etteantud internetiaadress ei ole kättesaadav.\nPalun kontrolli, kas aadress on õige ja kas võrgukoht on üleval.",
        "upload-curl-error28": "Üleslaadimise ajalimiit",
        "protectedtitles-submit": "Kuva pealkirjad",
        "listusers": "Kasutajate loend",
        "listusers-editsonly": "Näita vaid kasutajaid, kes on teinud muudatusi",
+       "listusers-temporarygroupsonly": "Näita vaid kasutajaid, kelle rühmaliikmesus on ajutine",
        "listusers-creationsort": "Järjesta konto loomise aja järgi",
        "listusers-desc": "Järjesta laskuvalt",
        "usereditcount": "$1 {{PLURAL:$1|redigeerimine|redigeerimist}}",
        "apisandbox-dynamic-parameters-add-label": "Lisa parameeter:",
        "apisandbox-dynamic-parameters-add-placeholder": "Parameetri nimi",
        "apisandbox-dynamic-error-exists": "Parameeter nimega \"$1\" on juba olemas.",
+       "apisandbox-templated-parameter-reason": "Seda [[Special:ApiHelp/main#main/templatedparams|mallparameetrit]] pakutakse välja $2 {{PLURAL:$1|väärtuse|väärtuste}} põhjal.",
        "apisandbox-deprecated-parameters": "Vananenud parameetrid",
        "apisandbox-fetch-token": "Hangi luba automaatselt",
        "apisandbox-add-multi": "Lisa",
        "speciallogtitlelabel": "Objekt (pealkiri või {{ns:user}}:kasutajanimi):",
        "log": "Logid",
        "logeventslist-submit": "Näita",
+       "logeventslist-more-filters": "Näita lisalogisid:",
+       "logeventslist-patrol-log": "Kontrollimislogi",
+       "logeventslist-tag-log": "Märgiste logi",
        "all-logs-page": "Kõik avalikud logid",
        "alllogstext": "See on {{GRAMMAR:genitive|{{SITENAME}}}} kõigi olemasolevate logide ühendkuva.\nValiku kitsendamiseks vali logitüüp, sisesta kasutajanimi (tõstutundlik) või huvipakkuva lehekülje pealkiri (samuti tõstutundlik).",
        "logempty": "Logis puuduvad vastavad kirjed.",
        "dellogpage": "Kustutamislogi",
        "dellogpagetext": "Allpool on viimaste kustutamiste loend.",
        "deletionlog": "kustutamislogi",
+       "log-name-create": "Lehekülgede alustamise logi",
+       "log-description-create": "Allpool on loetelu viimati alustatud lehekülgedest.",
+       "logentry-create-create": "$1 {{GENDER:$2|alustas}} lehekülge $3",
        "reverted": "Pöörduti tagasi varasemale versioonile",
        "deletecomment": "Põhjus:",
        "deleteotherreason": "Muu või täiendav põhjus:",
        "uctop": "(praegune)",
        "month": "Alates kuust (ja varasemad):",
        "year": "Alates aastast (ja varasemad):",
+       "date": "Alates kuupäevast (ja varasemad):",
        "sp-contributions-newbies": "Näita ainult uute kasutajate kaastööd",
        "sp-contributions-newbies-sub": "Uute kontode kaastöö",
        "sp-contributions-newbies-title": "Uute kasutajate kaastöö",
        "whatlinkshere": "Lingid siia",
        "whatlinkshere-title": "Leheküljed, mis viitavad lehele \"$1\"",
        "whatlinkshere-page": "Lehekülg:",
-       "linkshere-2": "Lehele '''$1''' viitavad järgmised leheküljed:",
-       "nolinkshere-2": "Lehele '''$1''' ei viita ükski lehekülg.",
-       "nolinkshere-ns-2": "Leheküljele <strong>$1</strong> ei ole valitud nimeruumis linke.",
+       "linkshere": "Lehele '''$2''' viitavad järgmised leheküljed:",
+       "nolinkshere": "Lehele '''$2''' ei viita ükski lehekülg.",
+       "nolinkshere-ns": "Leheküljele <strong>$2</strong> ei ole valitud nimeruumis linke.",
        "isredirect": "ümbersuunamislehekülg",
        "istemplate": "kasutamine mallina",
        "isimage": "faililink",
        "markedaspatrollederrornotify": "Kontrollituks märkimine ebaõnnestus.",
        "patrol-log-page": "Kontrollimislogi",
        "patrol-log-header": "See on kontrollitud redaktsioonide logi.",
-       "log-show-hide-patrol": "$1 kontrollimislogi",
-       "log-show-hide-tag": "$1 märgiste logi",
        "confirm-markpatrolled-button": "Sobib",
        "confirm-markpatrolled-top": "Kas märgid lehekülje $2 redaktsiooni $3 kontrollituks?",
        "deletedrevision": "Kustutatud vanem versioon $1",
        "pagedata-title": "Lehekülje andmed",
        "pagedata-text": "See lehekülg varustab leheküljed andmeliidesega. Palun too internetiaadressis ära lehekülje pealkiri, kasutades alamlehekülje süntaksit.\n* Sisu kooskõlastatakse vastavalt sinu kliendi Accept-päisele. See tähendab seda, et andmeid pakutakse vormingus, mida sinu klient eelistab.",
        "pagedata-not-acceptable": "Vastavat vormingut ei leitud. Toetatud MIME tüübid: $1",
-       "pagedata-bad-title": "Vigane pealkiri: $1."
+       "pagedata-bad-title": "Vigane pealkiri: $1.",
+       "unregistered-user-config": "Registreerumata kasutajad ei saa turvakaalutluse tõttu kasutaja JavaScripti, CSS- ja JSON-alamlehekülgi laadida.",
+       "passwordpolicies": "Paroolireeglid",
+       "passwordpolicies-summary": "Siin on loetletud vikis kasutusel olevate kasutajarühmade suhtes kehtivad paroolireeglid.",
+       "passwordpolicies-group": "Rühm",
+       "passwordpolicies-policies": "Reeglid",
+       "passwordpolicies-policy-minimalpasswordlength": "Parool peab olema vähemalt $1 {{PLURAL:$1|märgi}} pikkune.",
+       "passwordpolicies-policy-minimumpasswordlengthtologin": "Parool peab olema vähemalt $1 {{PLURAL:$1|märgi}} pikkune, et saaks sisse logida.",
+       "passwordpolicies-policy-passwordcannotmatchusername": "Parool ei tohi olla sama mis kasutajanimi.",
+       "passwordpolicies-policy-passwordcannotmatchblacklist": "Parool ei tohi olla kantud musta nimekirja.",
+       "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}}.",
+       "easydeflate-invaliddeflate": "Ette antud sisu ei ole õigesti vähendatud"
 }
index 2a01b48..5b31d45 100644 (file)
@@ -31,7 +31,9 @@
                        "Osoitz",
                        "Mikel Ibaiba",
                        "MarcoAurelio",
-                       "Iñaki LL"
+                       "Iñaki LL",
+                       "Amaia",
+                       "Matěj Suchánek"
                ]
        },
        "tog-underline": "Azpimarratu loturak:",
@@ -68,7 +70,7 @@
        "tog-watchlisthideminor": "Segimendu zerrendan, aldaketa txikiak ezkutatu",
        "tog-watchlisthideliu": "Ezkutatu izena emana duten lankideen aldaketak, jarraitze-zerrendan",
        "tog-watchlistreloadautomatically": "Berkargatu automatikoki jarraipen zerrenda iragazkiren bat aldatzerakoan (JavaScript beharrezkoa)",
-       "tog-watchlistunwatchlinks": "Gehitu zuzeneko ezikusi/ikusi loturak ikus-zerrendako sarreretan (JavaScript beharrezkoa funtzionaltasuna aldatzeko)",
+       "tog-watchlistunwatchlinks": "Gehitu zuzeneko ezikusi/ikusi markatzaileak ({{int:Watchlist-unwatch}}/{{int:Watchlist-unwatch-undo}}) aldatuak izan diren ikusitako orrietan (JavaScript beharrezkoa funtzionaltasuna erabiltzeko)",
        "tog-watchlisthideanons": "Ezkutatu lankide anonimoen aldaketak, jarraitze-zerrendan",
        "tog-watchlisthidepatrolled": "Ezkutatu patruilatutako aldaketak jarraitze-zerrendan",
        "tog-watchlisthidecategorization": "Orrialdeen kategorizazioa ezkutatu",
        "cascadeprotected": "Orri hau aldaketen aurka babestua dago, barneratuta dagoelako «kaskadako babesa» aukerarekin babestu {{PLURAL:$1|duten orri honetan|dituzten orri hauetan}}:\n$2",
        "namespaceprotected": "Ez daukazu '''$1''' izen-tarteko orrialdeak aldatzeko baimenik.",
        "customcssprotected": "Ez duzu baimenik CSS orrialde hau aldatzeko beste erabiltzaile baten hobespen pertsonalak dituelako.",
+       "customjsonprotected": "Ez duzu baimenik JSON orrialde hau editatzeko beste erabiltzaile baten hobespen pertsonalak dituelako.",
        "customjsprotected": "Ez duzu baimenik JavaScript orrialde hau aldatzeko beste erabiltzaile baten hobespen pertsonalak dituelako.",
        "mycustomcssprotected": "Ez duzu baimenik CSS orrialde hau aldatzeko.",
+       "mycustomjsonprotected": "Ez duzu baimenik JSON orrialde hau aldatzeko.",
        "mycustomjsprotected": "Ez duzu baimentik JavaScript orrialdea aldatzeko.",
        "myprivateinfoprotected": "Ez duzu eskumenik zure informazio pribatua aldatzeko.",
        "mypreferencesprotected": "Ez daukazu eskumenik zure hobespenak aldatzeko.",
        "wrongpasswordempty": "Pasahitza hutsik dago. Saiatu berriz.",
        "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 arrunki aukeratutako pasahitzak erabili. Aukera ezazu pasahitz originalago bat, mesedez.",
+       "passwordtoopopular": "Ezin dira pasahitz ohikoenak erabili. Aukera ezazu asmatzeko zailagoa den pasahitz 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",
        "passwordremindertitle": "Pasahitzaren gogorarazpena {{SITENAME}}(e)tik",
-       "passwordremindertext": "Norbaitek (ziurrenik zuk, $1 IP helbidetik) pasahitz berri bat\neskatu du {{SITENAME}}(r)ako ($4). Momentu honetan erabiltzeko \"$2\" lankidearentzat\npasahitza sortu da eta \"$3\"(r)a aldatu da. Hau zuk eginiko saiakuntza bazen,\norain saioa hasi beharko duzu zure pasahitza berria aukeratzeko. Zure aldi baterako pasahitzak {{PLURAL:$5|egun baterako|$5 egunetarako}} baino ez du balio izango.\n\nBeste norbaitek eskari hau egin bazuen, edo zure pasahitza gogoratu baduzu,\neta ez baduzu aldatu nahi, mezu honetan irakurritakoari jaramonik ez egin\neta aurretik zenuen pasahitza erabiltzen jarrai ezazu.",
+       "passwordremindertext": "Norbaitek ($1 IP helbidetik) pasahitz berri bat\neskatu du {{SITENAME}}(r)ako ($4). Behin-behineko pasahitz berria sortu da \"$2\" erabiltzailearentzat eta \"$3\"(r)a aldatu da. Zuk eginiko saiakera balitz, jarraian\nsaioa hasi beharko duzu zure pasahitz berria aukeratzeko. Zure behin-behineko pasahitza {{PLURAL:$5|egun baterako|$5 egunetarako}} iraungiko da.\n\nEskari hau beste norbaitek egin izan balu, edo zure pasahitza gogoratu baduzu eta ez baduzu aldatu nahi, ez egin jaramonik mezu honetan irakurritakoari eta aurretik zenuen pasahitza erabiltzen jarrai ezazu.",
        "noemail": "Ez dago \"$1\" erabiltzailearen e-posta helbiderik gordeta.",
        "noemailcreate": "Balioduna den e-posta helbidea eman behar duzu",
        "passwordsent": "Pasahitz berria bidali da \"$1\" erabiltzailearen e-posta helbidera.\nMesedez, saioa hasi jasotakoan.",
        "botpasswords-existing": "Dauden bot-en pasahitzak",
        "botpasswords-createnew": "Sortu errobot pasaitza berri bat",
        "botpasswords-editexisting": "Aldatu lehendik dagoen errobot pasaitza",
+       "botpasswords-label-needsreset": "(pasahitza berrezarri behar da)",
        "botpasswords-label-appid": "Bot izena:",
        "botpasswords-label-create": "Sortu",
        "botpasswords-label-update": "Eguneratu",
        "botpasswords-restriction-failed": "Errobot pasahitza murrizketek logina saihesten dute.",
        "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.",
        "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-submit-loggedin": "Pasahitza aldatu",
        "resetpass-submit-cancel": "Utzi",
        "resetpass-wrong-oldpass": "Behin-behineko edo oraintxuko pasahitza ez da baliagarria.\nAgian dagoeneko aldatu duzu zure pasahitza edo behin-behineko pasahitza bat eskatu duzu.",
-       "resetpass-recycled": "Mesedez berritu zure pasahitza.",
+       "resetpass-recycled": "Mesedez aldatu zure pasahitza.",
        "resetpass-temp-emailed": "Aldi baterako posta elektronikoko kodea erabiliz saioa hasi duzu. \nSaio hastea amaitzeko, hemen pasahitz berria ezarri behar duzu:",
        "resetpass-temp-password": "Behin-behineko pasahitza:",
        "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 da eta berrezarri egin behar da. Aukeratu pasahitz berria orain edo egin klik \"{{int:authprovider-resetpass-skip-label}}\"-n geroago berrarazteko.",
-       "resetpass-validity-soft": "Zure pasahitzak ez du balio: $1\n\nAukeratu beste pasahitza berri bat orain mesedez, edo \"{{int:authprovider-resetpass-skip-label}}\" klikatu geroago berrezartzeko.",
+       "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-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.",
        "passwordreset-text-many": "{{PLURAL:$1|Sartu datuetako bat zure pasahitza berrezartzeko.}}",
        "subject-preview": "Gaiaren aurrebista:",
        "previewerrortext": "Errore bat gertatu da aldaketak aurrezten saiatzean.",
        "blockedtitle": "Erabiltzailea blokeatuta dago",
-       "blockedtext": "'''Zure erabiltzaile izena edo IP helbidea blokeaturik dago.'''\n\n$1 administratzaileak ezarri du blokeoa.\nEmandako arrazoia hau da: ''$2''.\n\n* Blokeoaren hasiera: $8\n* Blokeoaren bukaera: $6\n* Blokeatua: $7\n\nBlokeoari buruz eztabaidatzeko, jo ezazu $1 administratzailearengana edo beste [[{{MediaWiki:Grouppage-sysop}}|administratzaile]] batengana.\n«Bidali mezu elektronikoa lankide honi» tresna erabili ahal izateko, ezinbestekoa da zure [[Special:Preferences|hobespenetan]] baliozkoa den helbide elektroniko bat emanda izatea, eta tresna hori erabiltzeko aukera zuri blokeatu ez izana.\nOrain duzun IP helbidea $3 da, eta blokeoaren zenbakia #$5 da.\nEman itzazu datu hauek guztiak, blokeoari buruzko edozein eskaera egitean.",
-       "autoblockedtext": "Zure IP helbidea automatikoki blokeaturik dago, $1 administratzaileak blokeatutako beste wikilari batek erabili zuelako. Emandako arrazoia hau da:\n\n:''$2''\n\n* Blokeoaren hasiera: $8\n* Blokeoaren bukaera: $6\n* Blokeatua: $7\n\nBlokeoari buruz eztabaidatzeko, jo ezazu $1 administratzailearengana edo beste [[{{MediaWiki:Grouppage-sysop}}|administratzaile]] batengana.\n\n«Bidali mezu elektronikoa lankide honi» tresna erabili ahal izateko, ezinbestekoa da zure [[Special:Preferences|hobespenetan]] baliozkoa den helbide elektroniko bat emanda izatea, eta tresna hori erabiltzeko aukera zuri blokeatu ez izana.\n\nOrain duzun IP helbidea $3 da, eta blokeoaren zenbakia #$5 da.\n\nEman itzazu datu hauek guztiak, blokeoari buruzko edozein eskaera egitean.",
+       "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.",
        "blockednoreason": "ez da arrazoirik zehaztu",
        "whitelistedittext": "$1 behar duzu orrialdeak aldatu ahal izateko..",
        "blocked-notice-logextract": "Erabiltzaile hau blokeatuta dago une honetan.\nAzken blokeoaren erregistroa ageri da behean, erreferentzia gisa:",
        "clearyourcache": "<strong>Oharra:</strong> Gorde ondoren, zure nabigatzailearen katxea ekidin beharko duzu aldaketak ikusteko.\n* <strong>Firefox / Safari:</strong> <em>Shift</em> tekla sakatu birkargatzeko momentuan, edo <em>Ctrl-Shift-R</em> edo <em>Crtl-F5</em>  sakatu (<em>⌘-R</em> Mac batean)\n* <strong>Google Chrome:</strong> <em>Ctrl-Shift-R </em>  sakatu (<em>⌘-Shift-R</em> Mac batean)\n* <strong>Internet Explorer:</strong> <em>Ctrl</em> tekla sakatu birkargatzeko momentuan, edo <em>Ctrl-F5</em> sakatu\n* <strong>Opera</strong> erabiltzaileek <em>Tresnak → Hobespenak</em> atalera joan eta katxea garbitzeko aukera hautatu",
        "usercssyoucanpreview": "'''Laguntza:''' Zure CSS berria gorde aurretik probatzeko \"{{int:showpreview}}\" botoia erabili.",
+       "userjsonyoucanpreview": "<strong>Aholkua:</strong> Gorde aurretik, erabili \"{{int:showpreview}}\" botoia zure JSON berria probatzeko.",
        "userjsyoucanpreview": "'''Laguntza:''' Zure JS berria gorde aurretik probatzeko \"{{int:showpreview}}\" botoia erabili.",
        "usercsspreview": "'''Ez ahaztu zure CSS kodea aurreikusten zabiltzala.'''\n'''Oraindik gorde gabe dago!'''",
+       "userjsonpreview": "<strong>Gogoratu zure JSON erabiltzaile konfigurazioa probatzen/aurreikusten ari zarela. \nOraindik ez da gorde!</strong>",
        "userjspreview": "'''Gogoratu zure JavaScript kodea probatu/aurreikusten zabiltzala, oraindik ez da gorde!'''",
        "sitecsspreview": "'''Ez ahaztu zure CSS kodea aurreikusten zabiltzala.'''\n'''Oraindik gorde gabe dago!'''",
+       "sitejsonpreview": "<strong>Gogoratu JSON konfigurazio hau probatzen/aurreikusten baino ez zaudela. \nOraindik ez da gorde!</strong>",
        "sitejspreview": "'''Gogoratu zure JavaScript kodea probatu/aurreikusten zabiltzala'''\n'''Oraindik ez da gorde!'''",
-       "userinvalidconfigtitle": "'''Oharra:''' Ez da \"$1\" itxura existitzen. Kontuan izan .css eta .js fitxategi pertsonalizatuen izenak letra xehez idatzi behar direla; adibidez, {{ns:user}}:Adibide/vector.css, eta ez {{ns:user}}:Adibide/Vector.css.",
+       "userinvalidconfigtitle": "<strong>Oharra:</strong> Ez da \"$1\" itxura existitzen. Kontuan izan .css eta .js fitxategi pertsonalizatuen izenak letra xehez idatzi behar direla; adibidez, {{ns:user}}:Adibide/vector.css, eta ez {{ns:user}}:Adibide/Vector.css.",
        "updated": "(Eguneratua)",
        "note": "'''Oharra:'''",
        "previewnote": "'''Gogoratu hau aurrikuspen bat dela.'''\nZure aldaketak ez dira oraindik gorde!",
        "explainconflict": "Zu orrialdea aldatzen hasi ondoren beste norbaitek ere aldaketak egin ditu.\nGoiko testu koadroan ikus daiteke orrialdeak uneotan duen edukia.\nZure aldaketak beheko testu koadroan ikus daitezke.\nZure testua dagoenarekin elkartu beharko duzu.\nOrrialdea gordetzeko erabakitzen duzun unean goiko koadroko edukia '''bakarrik''' gordeko da.",
        "yourtext": "Zure testua",
        "storedversion": "Gordetako bertsioa",
-       "editingold": "'''KONTUZ: Artikulu honen bertsio zahar bat aldatzen ari zara. Gorde egiten baduzu, azkenengo aldaketa baino lehenagoko aldakuntzak, ezabatuak izango dira.'''",
+       "editingold": "<strong>KONTUZ: Artikulu honen bertsio zahar bat aldatzen ari zara.</strong> Gordetzen baduzu, bertsio hau baino geroago egindako aldaketa guztiak ezabatuko dira.",
        "unicode-support-fail": "Zure nabigatzaileak Unicode onartzen ez duela dirudi. Orrialdeak editatu behar dira, beraz, edizioa ez da gorde.",
        "yourdiff": "Ezberdintasunak",
        "copyrightwarning": "Kontuan izan ezazu {{SITENAME}} webgunean egindako ekarpen guztiak $2 lizentziaren pean argitaratzen direla (xehetasunetarako, ikus $1). Zuk idatzitakoa libreki aldatua eta banatua izatea nahi ez baduzu, ez ezazu hemen jarri.<br />\nEra berean, hitzematen ari zara hau zuk zeuk idatzia dela, edo jabari publikotik nahiz askea den beste ituri batetik kopiatu duzula.\n'''Ez erabili copyright eskubideek babestutako lanik, baimenik gabe!'''",
        "longpageerror": "'''Errorea: Bidali duzun testuak {{PLURAL:$1|kilobyte 1eko|$1 kilobyteko}} luzera du, eta {{PLURAL:$2|kilobyte 1eko|$2 kilobyteko}} maximoa baino luzeagoa da.'''\nEzin da gorde.",
        "readonlywarning": "<strong>Oharra: Datu-basea blokeatu egin da mantenu lanak burutzeko, beraz ezingo dituzu orain zure aldaketak gorde.</strong>I\nTestua fitxategi baten kopiatu dezakezu, eta beranduago erabiltzeko gorde.\n\nBlokeatu zuen administratzaileak honako azalpena eman zuen: $1",
        "protectedpagewarning": "'''Oharra:  Orri hau blokeatua dago administratzaileek soilik eraldatu ahal dezaten.'''\nAzken erregistroa ondoren ikusgai dago erreferentzia gisa:",
-       "semiprotectedpagewarning": "'''Oharra''': Orrialde hau erregistratutako erabiltzaileek bakarrik aldatzeko babestuta dago.\nErregistroko azken sarrera azpian jartzen da erreferentzia gisa:",
+       "semiprotectedpagewarning": "<strong>Oharra:</strong> Orrialde hau babestuta dago erregistratutako erabiltzaileek bakarrik aldatu ahal izateko.\nErregistroko azken sarrera jarraian ikusgarri dagoena da:",
        "cascadeprotectedwarning": "<strong>Oharra:</strong> Orrialde hau blokeatua izan da eta [[Special:ListGroupRights|baimen zehatzak]] dituzten erabiltzaileek baino ez dute berau aldatzeko ahalmena, honako {{PLURAL:$1|orrialdeko|orrialdeetako}} kaskada-babesean txertatuta dagoelako:",
        "titleprotectedwarning": "'''Oharra: Orrialde hau blokeatuta dago eta bakarrik [[Special:ListGroupRights|erabiltzaile batzuek]] sortu dezakete.'''\nAzken erregistroko sarrera ematen da azpian erreferentzia gisa:",
        "templatesused": "Orri honetan erabiltzen {{PLURAL:$1|den txantiloia|diren txantiloiak}}:",
        "expansion-depth-exceeded-warning": "Espantsio sakonera gainditu duten orrialdeak",
        "parser-unstrip-loop-warning": "Loop unstrip bat aurkitu da",
        "unstrip-depth-warning": "Unstrip errekurtsio limitea gainditu da ($1)",
+       "unstrip-depth-category": "Unstrip depth limitea gainditutako orrialdeak.",
+       "unstrip-size-warning": "Unstrip tamaina limitea gainditua ($1)",
+       "unstrip-size-category": "Unstrip tamaina limitea gainditutako orrialdeak.",
        "converter-manual-rule-error": "Akatsa aurkitu da hizkuntzen eskuszko konbertsio arauan",
        "undo-success": "Aldaketa desegin daiteke.\nMesedez beheko alderaketa egiaztatu, egin nahi duzuna hori dela frogatzeko, eta ondoren azpiko aldaketak gorde, aldaketa desegiten amaitzeko.",
        "undo-failure": "Ezin izan da aldaketa desegin tarteko aldaketekin gatazkak direla-eta.",
+       "undo-main-slot-only": "Aldaketa ezin da desegin, slot nagusitik kanpoko edukia daukalako.",
        "undo-norev": "Aldaketa ezin da desegin ez delako existitzen edo ezabatu zutelako.",
        "undo-nochange": "Aldaketa hau honezkero desegin da.",
        "undo-summary": "[[Special:Contributions/$2|$2]] ([[User talk:$2|eztabaida]]) wikilariaren $1 berrikuspena desegin da",
        "showhideselectedversions": "Erakutsi/ezkutatu aukeratutako berrikuspenak",
        "editundo": "desegin",
        "diff-empty": "(Ez dago alderik)",
-       "diff-multi-sameuser": "(Erabiltzaile berdinaren {{PLURAL:$1|erdiko ekarpen bat ez da|$1 erdiko ekarpen ez dira}} erakusten)",
-       "diff-multi-otherusers": "({{PLURAL:$1|Tarteko berrikusketa bat|$1 tarteko berrikusketak}}  {{PLURAL:$2|beste erabiltzaile bat|$2 erabiltzaileak}} egina ez da erakusten)",
-       "diff-multi-manyusers": "({{PLURAL:$1|Tarteko berrikusketa bat|$1 tarteko berrikusketak}} by more than $2 {{PLURAL:$2|erabiltzaile batek|erabiltzaile batzuek}} baino gehiagok egina ez erakutsia)",
+       "diff-multi-sameuser": "(Erabiltzaile berak tartean egindako {{PLURAL:$1|ekarpen bat ez da|$1 ekarpen ez dira}} erakusten)",
+       "diff-multi-otherusers": "({{PLURAL:$2|Beste erabiltzaile batek|$2 erabiltzailek}} tartean egindako {{PLURAL:$1|berrikusketa bat ez da erakusten|$1 berrikusketa ez dira erakusten}})",
+       "diff-multi-manyusers": "({{PLURAL:$2|Erabiltzaile batek|$2 erabiltzailek}} baino gehiagok tartean egindako {{PLURAL:$1|berrikusketa bat ez da erakusten|$1 berrikusketa ez dira erakusten}})",
        "diff-paragraph-moved-tonew": "Paragrafoa mugitu egin da. Egin klik beste kokaleku batera salto egiteko.",
        "diff-paragraph-moved-toold": "Paragrafoa mugitu egin da. Egin klik aurretiko kokalekura salto egiteko.",
        "difference-missing-revision": " ($1) ezberdinatasunaren  {{PLURAL:$2|Berrikusketa bat|$2 berrikusketa}} ez {{PLURAL:$2|da|dira}} aurkitu.\n\nHau, orokorrean ezabatu egin den orri batera deskonektatua dagoen esteka desegonkor baten ondorioz gertatzen da.\n\nHemen xehetasunak aurki daitezke: [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} deletion log].",
        "searchresults": "Bilaketaren emaitzak",
+       "search-filter-title-prefix": "\"$1\" hasiera duten orriak bakarrik bilatzen",
+       "search-filter-title-prefix-reset": "Orri guztiak bilatu",
        "searchresults-title": "«$1» bilaketaren  emaitzak",
        "titlematches": "Emaitzak artikuluen izenburuetan",
        "textmatches": "Emaitza orrialde testuetan",
        "prefs-watchlist-edits": "Ikuspen zerrendan erakutsi beharreko aldaketa gehienezko kopurua:",
        "prefs-watchlist-edits-max": "Gehenezko zenbakia: 1000",
        "prefs-watchlist-token": "Jarraipen zerrendaren tokena:",
-       "prefs-watchlist-managetokens": "Kudeatu token-ak",
+       "prefs-watchlist-managetokens": "Token-ak kudeatu",
        "prefs-misc": "Denetarik",
        "prefs-resetpass": "Pasahitza aldatu",
        "prefs-changeemail": "Aldatu edo kendu e-mail helbidea",
        "stub-threshold-disabled": "Ezgaitua",
        "recentchangesdays": "Aldaketa berrietan erakutsi beharreko egun kopurua:",
        "recentchangesdays-max": "(gehienez {{PLURAL:$1|egun bat|$1 egun}})",
-       "recentchangescount": "Erakusteko aldaketa kopurua, lehenetsita:",
-       "prefs-help-recentchangescount": "Honek azken aldaketak, orrialdeen historiak eta logak barne-biltzen ditu.",
+       "recentchangescount": "Modu lehenetsian erakutsi beharreko zuzneketa kopurua azken aldaketa, orrialdeen historia eta erregistroetan:",
+       "prefs-help-recentchangescount": "Gehienezko zenbakia: 1000",
        "prefs-help-watchlist-token2": "Hau da zure jarraipen zerrendako web jarioaren giltza sekretua.\nEzagutzen duen orok zure jarraipen zerrenda irakurtzeko aukera izango du, ez partekatu.\n[[Special:ResetTokens|berrezarri dezakezu]].",
+       "prefs-help-tokenmanagement": "Zure jarraipen zerrenda Web bidez ikustea ahalbidetzen dizun ezkutuko kodea ikusi eta berrezarri dezakezu. Kodea ezagutzen duen edonork irakur dezake zure jarraipen zerrenda, beraz ez partekatu.",
        "savedprefs": "Zure hobespenak gorde egin dira.",
        "savedrights": "{{GENDER:$1|$1}} erabiltzailearen taldeak gorde dira.",
        "timezonelegend": "Ordu-eremua:",
        "default": "lehenetsia",
        "prefs-files": "Fitxategiak",
        "prefs-custom-css": "CSS pertsonalizatua",
+       "prefs-custom-json": "JSON pertsonalizatua",
        "prefs-custom-js": "JS pertsonalizatua",
-       "prefs-common-config": "Azal mota guztietan elkarbanatutako CSS/JS:",
+       "prefs-common-config": "CSS/JSON/JavaScript azal guztietarako partekatuak:",
        "prefs-reset-intro": "Orrialde hau erabil dezakezu zure guneko berezko hobespenak berreskuratzeko.\nHau ezin da desegin.",
        "prefs-emailconfirm-label": "E-posta baieztapena:",
        "youremail": "E-posta:",
        "right-editcontentmodel": "Aldatu orri bateko eduki eredua",
        "right-editinterface": "Erabiltzailearen interfazea aldatu",
        "right-editusercss": "Beste lankideen CSS fitxategiak aldatu",
+       "right-edituserjson": "Beste erabiltzaileen JSON fitxategiak aldatu",
        "right-edituserjs": "Beste lankideen JS fitxategiak aldatu",
        "right-editmyusercss": "Aldatu zure CSS fitxategi propioak",
+       "right-editmyuserjson": "Zure erabiltzaile JSON fitxategi propioak aldatu",
        "right-editmyuserjs": "Aldatu zure JavaScript fitxategi propioak",
        "right-viewmywatchlist": "Zure jarraipen zerrenda ikusi",
        "right-editmywatchlist": "Zure jarraipen zerrenda aldatu. Kontuan izan ekintza batzuek orrialdeak gehitu dituztela eskumen hau kenduta ere.",
        "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/JavaScript erabiltzailea aldatu",
-       "grant-editmycssjs": "Zure CSS/JavaScript aldatu",
+       "grant-editinterface": "MediaWiki izen eremua eta CSS/JSON/JavaScript erabiltzailea aldatu",
+       "grant-editmycssjs": "Zure CSS/JSON/JavaScript erabiltzailea aldatu",
        "grant-editmyoptions": "Aldatu zure hobespenak",
        "grant-editmywatchlist": "Zure jarraipen zerrenda aldatu",
        "grant-editpage": "Aldatu dauden orrialdeak",
        "rcfilters-other-review-tools": "Beste berrikusketa tresnak",
        "rcfilters-group-results-by-page": "Talde emaitzak orrika",
        "rcfilters-activefilters": "Iragazki aktiboak",
+       "rcfilters-activefilters-hide": "Ezkutatu",
+       "rcfilters-activefilters-show": "Erakutsi",
+       "rcfilters-activefilters-hide-tooltip": "Ezkutatze Iragazki Aktiboen eremua",
+       "rcfilters-activefilters-show-tooltip": "Erakuste Iragazki Aktiboen eremua",
        "rcfilters-advancedfilters": "Iragazki aurreratuak",
        "rcfilters-limit-title": "Erakusteko emaitzak",
        "rcfilters-limit-and-date-label": "$1 {{PLURAL:$1|aldaketa|aldaketak}}, $2",
        "rcfilters-savedqueries-rename": "Berrizendatu",
        "rcfilters-savedqueries-setdefault": "Lehenetsi",
        "rcfilters-savedqueries-unsetdefault": "Kendu lehenetsi gisa",
-       "rcfilters-savedqueries-remove": "Kendu",
+       "rcfilters-savedqueries-remove": "Ezabatu",
        "rcfilters-savedqueries-new-name-label": "Izena",
        "rcfilters-savedqueries-new-name-placeholder": "Deskribatu filtro honen helburua",
        "rcfilters-savedqueries-apply-label": "Sortu iragazkia",
        "rcfilters-empty-filter": "Filtro aktiborik ez dago. Ekarpen guztiak erakusten.",
        "rcfilters-filterlist-title": "Iragazkiak",
        "rcfilters-filterlist-whatsthis": "Nola erabiltzen da?",
-       "rcfilters-filterlist-feedbacklink": "Esaguzu zer pentsatzen duzun iragazteko tresna hauei buruz (berriak)",
+       "rcfilters-filterlist-feedbacklink": "Esaiguzu zer deritzozun iragazteko tresna hauei buruz",
        "rcfilters-highlightbutton-title": "Nabarmendu emaitzak",
        "rcfilters-highlightmenu-title": "Hautatu kolore bat",
        "rcfilters-highlightmenu-help": "Aukeratu kolore bat propietate hau nabarmentzeko",
        "rcfilters-filter-humans-label": "Gizaki (ez bot)",
        "rcfilters-filter-humans-description": "Gizaki editoreek egindako aldaketak.",
        "rcfilters-filtergroup-reviewstatus": "Berrikuspenaren egoera",
+       "rcfilters-filter-reviewstatus-unpatrolled-description": "Ez eskuz ezta automatikoki berrikusitako bezala markatutako aldaketak.",
        "rcfilters-filter-reviewstatus-unpatrolled-label": "Patruilagabea",
+       "rcfilters-filter-reviewstatus-manual-description": "Berrikusitako bezala eskuz markatutako aldaketak",
        "rcfilters-filter-reviewstatus-manual-label": "Eskuz patruilatuak",
+       "rcfilters-filter-reviewstatus-auto-description": "Erabiltzaile aurreratuek aldatuak, zeintzuen lanak automatikoki markatzen diren berrikusitako bezala.",
+       "rcfilters-filter-reviewstatus-auto-label": "Autoberrikusia",
        "rcfilters-filtergroup-significance": "Munta",
        "rcfilters-filter-minor-label": "Aldaketa txikiak",
        "rcfilters-filter-minor-description": "Egileak sailkatutako aldaketa txikiak.",
        "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-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",
        "rcshowhidecategorization": "orrialde baten kategorizazioa $1",
        "rcshowhidecategorization-show": "Erakutsi",
        "rcshowhidecategorization-hide": "Ezkutatu",
-       "rclinks": "Erakutsi azken $2 egunetako $1 aldaketak",
+       "rclinks": "Erakutsi azken $2 eguneko $1 aldaketak",
        "diff": "ezb",
        "hist": "hist",
        "hide": "Ezkutatu",
        "recentchangeslinked-feed": "Lotutako orrietako aldaketak",
        "recentchangeslinked-toolbox": "Lotutako orrietako aldaketak",
        "recentchangeslinked-title": "«$1»(e)kin harremanetan dauden aldaketak",
-       "recentchangeslinked-summary": "Sartu orrialde baten izena orrialdearekin lotutako edota orrialdetik lotutako orrialdeetan aldaketak ikusteko. (Kategoria baten kideak ikusteko, idatzi Kategoria: Kategoria izena). [[Special:Watchlist|Zure jarraipen zerrendan]] dauden orrietan aldaketak <strong>letra lodian</strong> daude.",
+       "recentchangeslinked-summary": "Sartu orrialde baten izena orrialdearekin lotutako edota orrialdetik lotutako orrialdeetan aldaketak ikusteko. (Kategoria baten kideak ikusteko, idatzi {{ns:category}}: Kategoria izena). [[Special:Watchlist|Zure jarraipen zerrendan]] dauden orrietan aldaketak <strong>letra lodian</strong> daude.",
        "recentchangeslinked-page": "Orriaren izena:",
        "recentchangeslinked-to": "Lotutako orrietarako aldaketak erakutsi emandako orriaren ordez",
        "recentchanges-page-added-to-category": "«[[:$1]]» gehitu da kategoriara",
        "imagelinks": "Fitxategiaren erabilera",
        "linkstoimage": "Hurrengo {{PLURAL:$1|orrialdeak du|$1 orrialdeek dute}} fitxategi honetarako lotura:",
        "linkstoimage-more": "$1 {{PLURAL:$1|orri lotura|orri lotura}} baino gehiago daude fitxategira.\nOndorengo zerrendak fitxategira dauden {{PLURAL:$1|lehen lotura|lehen $1 loturak}} erakusten ditu bakarrik.\n[[Special:WhatLinksHere/$2|Zerrenda osoa]] ere eskuragarri dago.",
-       "nolinkstoimage": "Ez dago fitxategi honetara lotura egiten duen orrialderik.",
+       "nolinkstoimage": "Ez dago fitxategi honetara lotura duen orririk.",
        "morelinkstoimage": "Ikusi fitxategi honen [[Special:WhatLinksHere/$1|lotura gehiago]].",
        "linkstoimage-redirect": "$1 (fitxategiranzko birbideratzea) $2",
        "duplicatesoffile": "Ondorengo fitxategi {{PLURAL:$1|hau beste honen berdina da|$1 hauek beste honen berdinak dira}} ([[Special:FileDuplicateSearch/$2|zehaztasun gehiago]]):",
        "protectedtitles-submit": "Izenburuak erakutsi",
        "listusers": "Erabiltzaileen zerrenda",
        "listusers-editsonly": "Aldaketak egin dituzten erabiltzaileak soilik erakutsi",
+       "listusers-temporarygroupsonly": "Behin-behineko erabiltzaile taldeetako erabiltzaileak bakarrik erakutsi.",
        "listusers-creationsort": "Sorrera dataren arabera sailkatu",
        "listusers-desc": "Beheranzko ordenean antolatu",
        "usereditcount": "{{PLURAL:$1|edizio bat|$1 edizio}}",
        "apisandbox-dynamic-parameters-add-label": "Gehitu parametroa:",
        "apisandbox-dynamic-parameters-add-placeholder": "Parametroaren izena",
        "apisandbox-dynamic-error-exists": "$1 parametro izena dagoeneko existitzen da",
+       "apisandbox-templated-parameter-reason": "[[Special:ApiHelp/main#main/templatedparams|templated parameter]] Hau $2-(a)ren {{PLURAL:$1|balio $1-ean|$1 baliotan}} oinarrituta dago eskainita.",
        "apisandbox-deprecated-parameters": "Aurretiaz zehaztutako parametroak",
        "apisandbox-fetch-token": "Token-a automatikoki bete",
        "apisandbox-add-multi": "Gehitu",
        "speciallogtitlelabel": "Helburua (izenburua edo {{ns:user}}: lankidea):",
        "log": "Erregistroak",
        "logeventslist-submit": "Erakutsi",
+       "logeventslist-more-filters": "Erakutsi erregistro gehiago:",
+       "logeventslist-tag-log": "Etiketen erregistroa",
        "all-logs-page": "Erregistro publiko guztiak",
        "alllogstext": "{{SITENAME}} orrialdearen erregistro guztien erakusketa konbinatua.\nErregistro mota, erabiltzailearen izena edota orrialdearen izena iragaziz bistaratu daiteke. Letra larriak eta xeheak bereizten dira.",
        "logempty": "Ez dago emaitzarik erregistroan.",
        "unwatchthispage": "Jarraitzeari utzi",
        "notanarticle": "Ez da eduki orrialdea",
        "notvisiblerev": "Berrikusketa desegin da",
-       "watchlist-details": "{{PLURAL:$1|$1 orrialdea dago |$1 orrialdeak daude}} jarrai zerrendan (gehi eztabaida orrialdeak).",
+       "watchlist-details": "{{PLURAL:$1|Orri bat duzu|$1 orri dituzu}} jarraipen zerrendan (gehi eztabaida orriak).",
        "wlheader-enotif": "Posta bidezko ohartarazpena gaituta dago.",
-       "wlheader-showupdated": "Bisitatu zenituen azken alditik aldaketak izan dituzten orrialdeak '''beltzez''' nabarmenduta daude.",
-       "wlnote": "Jarraian {{PLURAL:$2|ikus daiteke azken orduko|ikus daitezke azken <strong>$2</strong> orduetako}} azken {{PLURAL:$1|aldaketa|<strong>$1</strong> aldaketak}}, $3, $4 gisa.",
+       "wlheader-showupdated": "Bisitatu zenituen azken alditik aldaketak izan dituzten orriak '''letra lodiz''' nabarmenduta daude.",
+       "wlnote": "Jarraian ageri {{PLURAL:$1|da|dira}} azken {{PLURAL:$2|ordubeteko|<strong>$2</strong> orduko}} {{PLURAL:$1|aldaketa|<strong>$1</strong> aldaketak}}. Data: $3, $4.",
        "wlshowlast": "Erakutsi azken $1 orduak, azken $2 egunak",
        "watchlist-hide": "Ezkutatu",
        "watchlist-submit": "Erakutsi",
        "dellogpage": "Ezabaketa erregistroa",
        "dellogpagetext": "Behean ageri da azken ezabaketen zerrenda.",
        "deletionlog": "ezabaketa erregistroa",
+       "log-name-create": "Orri sorkuntzaren erregistroa",
+       "log-description-create": "Azpian, sortutako azken orrien zerrenda ageri da.",
+       "logentry-create-create": "$1 {{GENDER:$2|erabiltzaileak}} $3 orria sortu du",
        "reverted": "Lehenagoko berrikuspen batera itzuli da",
        "deletecomment": "Arrazoia:",
        "deleteotherreason": "Arrazoi gehigarria:",
        "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; bandalismoak saihesteko ekintza hau ezeztatu egin da. Mesedez, nabigatzaileko \"atzera\" botoian klik egin, hona ekarri zaituen orrialde hori berriz kargatu, eta saiatu berriz.",
+       "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",
        "changecontentmodel-legend": "Aldatu eduki eredua",
        "changecontentmodel-title-label": "Orriaren izenburua",
        "uctop": "(azken aldaketa)",
        "month": "Hilabetea (eta lehenagokoak):",
        "year": "Urtea (eta lehenagokoak):",
+       "date": "Data honetatik (eta lehenagokoak):",
        "sp-contributions-newbies": "Soilik kontu berrien ekarpenak erakutsi",
        "sp-contributions-newbies-sub": "Hasiberrientzako",
        "sp-contributions-newbies-title": "Lankideen ekarpenak lankide berrietn",
        "whatlinkshere": "Honanzko lotura duten orriak",
        "whatlinkshere-title": "$1(e)ra lotura duten orriak",
        "whatlinkshere-page": "Orria:",
-       "linkshere-2": "Hauek dute '''$1''' orrialderako lotura:",
-       "nolinkshere-2": "Ez dago '''$1''' lotura duen orrialderik.",
-       "nolinkshere-ns-2": "Hautatutako izen-tartean ez dago '''$1''' orrialderako lotura duenik.",
+       "linkshere": "Hauek dute '''$2''' orrialderako lotura:",
+       "nolinkshere": "Ez dago «$2» lotura duen orririk.",
+       "nolinkshere-ns": "Hautatutako izen-tartean ez dago '''$2''' orrialderako lotura duenik.",
        "isredirect": "birbideratze orrialdea",
        "istemplate": "erabilpena",
        "isimage": "fitxategi lotura",
        "fix-double-redirects": "Eguneratu jatorrizko izenburura zuzendutako birbideratze guztiak",
        "move-leave-redirect": "Utzi atzean birbideratzea",
        "protectedpagemovewarning": "'''Oharra:''' Orrialde hau babestua izan da, beraz administratzaile eskumenak dituztenek alda dezakete bakarrik.\nAzken erregistroko sarrera ematen da azpian erreferentzia gisa:",
-       "semiprotectedpagemovewarning": "'''Oharra:''' Orrialde hau blokeatu dute, izena emanda duten erabiltzaileek soilik mugitu ahal dezaten. Erregistroko azken sarrera erakusten da jarraian erreferentzia gisa:",
+       "semiprotectedpagemovewarning": "<strong>Oharra:</strong> Orrialde hau blokeatu dute, izena emanda duten erabiltzaileek soilik mugitu ahal dezaten. Erregistroko azken sarrera jarraian erakusten da erreferentzia gisa:",
        "move-over-sharedrepo": "[[:$1]] datu-base partekatu batean existitzen da. Izenburu honetara fitxategi bat mugitzean partekatutako fitxategia gainezarriko du.",
        "file-exists-sharedrepo": "Aukeratutako artxibo izena jadanik partekatutako biltegi batean erabiltzen ari da. Aukeratu beste izen bat mesedez.",
        "export": "Orrialdeak esportatu",
        "thumbnail_dest_directory": "Ezinezkoa izan da helburu direktorioa sortu",
        "thumbnail_image-type": "Irudi mota ez babestua",
        "thumbnail_gd-library": "GD liburutegiaren konfigurazio osagabea: $1 funtzioa falta da",
+       "thumbnail_image-size-zero": "Irudi fitxategiaren tamaina zero dela dirudi.",
        "thumbnail_image-missing": "Fitxategirik ez dagoela dirudi: $1",
        "thumbnail_image-failure-limit": "Koadro txikiak sortzeko saiakera galduak ($1 edo gehiago) gehiegi izan dira. Saiatu berriz geroago mesedez.",
        "import": "Orrialdeak inportatu",
        "tooltip-preferences-save": "Hobespenak gorde",
        "tooltip-summary": "Laburpen labur bat sar ezazu",
        "common.css": "/** Hemen idatzitako CSS kodeak itxura guztietan izango du eragina */",
+       "common.json": "/* Hemen idatzitako JSON oro erabiltzaile guztiek edozein orrialde irekitzerakoan kargatuko da. */",
        "common.js": "/* Hemen idatzitako JavaScript kode oro erabiltzaile guztiek edozein orrialde irekitzerakoan kargatuko da. */",
        "anonymous": "{{SITENAME}}(e)ko lankide {{PLURAL:$1|anonimoa|anonimoak}}",
        "siteuser": "{{SITENAME}}(e)ko $1 erabiltzailea",
        "markedaspatrollederrornotify": "Patruilatu gisa markatzean akatsa egon da.",
        "patrol-log-page": "Patrullatze loga",
        "patrol-log-header": "Hau patruliatutako aldaketen log bat da.",
-       "log-show-hide-patrol": "$1 patruilatze loga",
-       "log-show-hide-tag": "$1 etiketa erregistroa",
        "confirm-markpatrolled-button": "Ados",
        "confirm-markpatrolled-top": "$2ren $3 berrikusketa patruilatu bezala markatu?",
        "deletedrevision": "$1 berrikuspen zaharra ezabatu da",
        "watchlistedit-clear-titles": "Izenburuak:",
        "watchlistedit-clear-submit": "Garbitu jarraipen zerrenda (Behin betiko da!)",
        "watchlistedit-clear-done": "Zure jarraipen-zerrenda garbitu da.",
+       "watchlistedit-clear-jobqueue": "Jarraipen zerrenda garbitzen ari da. Prozesu honen denbora apur bat luza daiteke!",
        "watchlistedit-clear-removed": "{{PLURAL:$1|Izenburu 1 kendu da|$1 izenburu kendu dira}}:",
        "watchlistedit-too-many": " Orrialde gehiegi, hemen erakusteko.",
        "watchlisttools-clear": "Garbitu jarraipen-zerrenda",
        "tags-delete-submit": "Betirako ezabatu etiketa hau",
        "tags-delete-not-allowed": "Luzapen batek definitutako etiketak ezin dira ezabatu, luzapenak bereziki baimendu ezean.",
        "tags-delete-not-found": "\"$1\" etiketa  ez da existitzen.",
-       "tags-delete-too-many-uses": "\"$1\" etiketa $2 {{PLURAL:$2|berrikusketa bat|berrikusketa}} baino gehiagotan aplikatu egin denez ezingo da ezabatu",
+       "tags-delete-too-many-uses": "«$1» etiketa $2 {{PLURAL:$2|berrikusketa batean|berrikusketatan}} baino gehiagotan aplikatu denez, ezingo da ezabatu.",
        "tags-delete-warnings-after-delete": "\"$1\" etiketa ezabatu egin da, baina hurrengo {{PLURAL:$2|abisua|abisuak}} aurkitu d(ir)a:",
        "tags-delete-no-permission": "Ez daukazu baimenik etiketa aldaketak ezabatzeko.",
        "tags-activate-title": "Etiketa aktibatu",
        "permanentlink": "Lotura finkoa",
        "permanentlink-revid": "Berrikuspen IDa",
        "permanentlink-submit": "Berrikusketara joan",
-       "dberr-problems": "Barkatu! Webgune honek zailtasun teknikoak jasaten ari da.",
+       "dberr-problems": "Barkatu! Webgune hau zailtasun teknikoak izaten ari da.",
        "dberr-again": "Saiatu pare bat minutu itxaroten edo kargatu ezazu orrialdea berriro.",
        "dberr-info": "($1: Ezin da datu-basera konektatu)",
        "dberr-info-hidden": "(Ezin da konektatu datu-basera)",
        "logentry-delete-delete_redir": "$1 wikilariak {{GENDER:$2|}} «$3» birbideraketa ezabatu du, gainidatzita",
        "logentry-delete-restore": "$1 administratzaileak «$3» orria {{GENDER:$2|lehengoratu}} du",
        "logentry-delete-restore-nocount": "$1-k {{GENDER:$2|leheneratutako}} $3 orria.",
-       "restore-count-revisions": "{{PLURAL:$1|berrikusketa 1|$1 berrikusketa}}",
+       "restore-count-revisions": "{{PLURAL:$1|1 berrikusketa|$1 berrikusketa}}",
        "restore-count-files": "{{PLURAL:$1|Fitxategi 1|$1 fitxategi}}",
        "logentry-delete-event": "$1 wikilariak ikusgaitasuna {{GENDER:$2|aldatu}} {{PLURAL:$5|dio erregistroko sarrera bati|die erregistroko $5 sarrerari}}, $3 orrian: $4",
        "logentry-delete-revision": "$1 wikilariak ikusgaitasuna {{GENDER:$2|aldatu}} {{PLURAL:$5|dio erregistroko sarrera bati|die erregistroko $5 sarrerari}}, $3 orrian: $4",
        "logentry-move-move": "$1 {{GENDER:$2|wikilariak}} «$3» orria «$4» izenera aldatu du",
        "logentry-move-move-noredirect": "$1 {{GENDER:$2|wikilariak}} «$3» orria «$4» izenera aldatu du, birzuzenketarik utzi gabe",
        "logentry-move-move_redir": "$1 {{GENDER:$2|wikilariak}} «$3» orria «$4» izenera aldatu du, birzuzenketaren gainetik",
-       "logentry-move-move_redir-noredirect": "$1 {{GENDER:wikilariak}} «$3» orria «$4» izenera aldatu du, birbideratze bat gainidatzita, birbideratzerik utzi gabe",
+       "logentry-move-move_redir-noredirect": "$1 {{GENDER:$2|wikilariak}} «$3» orria «$4» izenera aldatu du, birbideratze bat gainidatzita, birbideratzerik utzi gabe",
        "logentry-patrol-patrol": "$1(e)k $3 orrialdearen $4 berrikuspena patruilatutzat {{GENDER:$2|markatu}} du",
        "logentry-patrol-patrol-auto": "$1(e)k $3 orrialdearen $4 berrikuspena patruilatutzat {{GENDER:$2|markatu}} du",
        "logentry-newusers-newusers": "$1 erabiltzaile kontua {{GENDER:$2|sortu da}}",
        "limitreport-templateargumentsize-value": "{{PLURAL:$2|byte $1/$2|$1/$2 byte}}",
        "limitreport-expansiondepth": "Gehienezko espantsio sakonera",
        "limitreport-expensivefunctioncount": "Parser funtzio kontaketa garestia",
+       "limitreport-unstrip-depth": "Unstrip errekurtsio sakona",
+       "limitreport-unstrip-size-value": "{{PLURAL:$2|byte $1/$2|$1/$2 byte}}",
        "expandtemplates": "Txantiloi ordezkatzailea",
        "expand_templates_intro": "Orri berezi honek wiki-testua hartu eta txantiloi guztiak modu errekurtsiboan zabaltzen ditu.\nOnartutako funtzio sintaktikoak ere ordezkatzen ditu, hala nola\n<code><nowiki>{{</nowiki>#language:…}}</code>; eta aldagaiak ere, hala nola\n<code><nowiki>{{</nowiki>CURRENTDAY}}</code>.\nIzan ere, kortxete bikoitzen arteko ia edozer zabaltzen du.",
        "expand_templates_title": "Izenburua ({{FULLPAGENAME}} ordezkatzeko, eta abar):",
        "unlinkaccounts-success": "Kontua desestekatu da.",
        "authenticationdatachange-ignored": "Autentifikazio datuen aldaketa ez da kudeatu. Beharbada ez da hornitzailerik konfiguratu?",
        "userjsispublic": "Kontutan izan mesedez: JavaScript azpiorriek ez lukete datu konfidentzialik eraman behar, beste erabiltzaileek ikusi ahal dituztelako.",
+       "userjsonispublic": "Gogoratu: JSON azpiorriek ez dute datu konfidentzialik eduki behar, beste erabiltzaile batzuek ikus ditzaketelako.",
        "usercssispublic": "Kontutan izan mesedez: CSS azpiorriek ez lukete datu konfidentzialik eraman behar, beste erabiltzaileek ikusi ahal dituztelako.",
        "restrictionsfield-badip": "Baliogabeko IP helbide edo eremua: $1",
        "restrictionsfield-label": "Onartutako IP eremuak:",
        "pagedata-title": "Orri data",
        "pagedata-text": "Orrialde honek orrien interfaze datuak eskaintzen ditu. Eman orrialdearen izenburua URLan, azpiorri sintaxia erabiliz.\n*Edukiaren negoziazioa zure bezeroaren onarpen goiburuan oinarritzen erabiltzen da. Horrek esan nahi du orriaren datuak zure bezeroak nahiago duen formatuan emango direla.",
        "pagedata-not-acceptable": "Bat egiten duen formaturik ez da aurkitu. Onartutako MIME motak: $1",
-       "pagedata-bad-title": "Izenburu baliogabea: $1"
+       "pagedata-bad-title": "Izenburu baliogabea: $1",
+       "unregistered-user-config": "Segurtasun arrazoiengatik JavaScript, CSS eta JSON erabiltzaile azpiorriak ezin dira kargatu erregistratu gabeko erabiltzaileen orrietan.",
+       "passwordpolicies": "Pasahitzen inguruko politika",
+       "passwordpolicies-summary": "Hona wiki honetako erabiltzaile taldeentzako pasahitzen politikaren zerrenda.",
+       "passwordpolicies-group": "Taldea",
+       "passwordpolicies-policies": "Politikak",
+       "passwordpolicies-policy-minimalpasswordlength": "Pasahitzak gutxienez {{PLURAL:$1|kraktere $1eko|$1 karaktereko}} luzera izan behar du",
+       "passwordpolicies-policy-minimumpasswordlengthtologin": "Pasahitzak gutxienez {{PLURAL:$1|kraktere $1eko|$1 karaktereko}} luzera izan behar du saioa hasi ahal izateko",
+       "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}}"
 }
index 73086be..e4f4c7b 100644 (file)
        "whatlinkshere": "Lo que atija aquina",
        "whatlinkshere-title": "Páhinas que atihan a $1",
        "whatlinkshere-page": "Páhina:",
-       "linkshere-2": "Las siguientis páhinas atihan a '''$1''':",
-       "nolinkshere-2": "Denguna páhina atiha a '''$1'''.",
-       "nolinkshere-ns-2": "Nu ai denguna páhina qu´atihi a '''$1''' nel espaciu e nombris lihiu.",
+       "linkshere": "Las siguientis páhinas atihan a '''$2''':",
+       "nolinkshere": "Denguna páhina atiha a '''$2'''.",
+       "nolinkshere-ns": "Nu ai denguna páhina qu´atihi a '''$2''' nel espaciu e nombris lihiu.",
        "isredirect": "Rederihil páhina",
        "istemplate": "inclusión",
        "isimage": "atihu la imahin",
index 1d17909..a7aaabe 100644 (file)
                        "Obzord",
                        "Alp Er Tunqa",
                        "Baloch Khan",
-                       "Fitoschido"
+                       "Fitoschido",
+                       "Alireza Ivaz",
+                       "Iriman",
+                       "Matěj Suchánek"
                ]
        },
        "tog-underline": "خط کشیدن زیر پیوندها:",
        "tog-watchlisthideminor": "ویرایش‌های جزئی در فهرست پی‌گیری‌ها پنهان شود",
        "tog-watchlisthideliu": "ویرایش‌های کاربران وارد شده به سامانه در فهرست پی‌گیری‌ها پنهان شود",
        "tog-watchlistreloadautomatically": "زمانی که یک پالایه تغییر کرد فهرست پیگیری به صورت خودکار به روز شود (نیازمند جاوااسکریپت)",
-       "tog-watchlistunwatchlinks": "اÙ\81زÙ\88دÙ\86 Ù¾Û\8cÙ\88Ù\86دÙ\87اÛ\8c Ù\85ستÙ\82Û\8cÙ\85 Ø®Ø±Ù\88ج Ø§Ø² Ù¾Û\8câ\80\8cÚ¯Û\8cرÛ\8c Ø¨Ù\87 Ù\81Ù\87رست Ù¾Û\8câ\80\8cÚ¯Û\8cرÛ\8c (جاواسکریپت ممکن است نیاز شود)",
+       "tog-watchlistunwatchlinks": "اÙ\81زÙ\88دÙ\86 Ù\85شخصâ\80\8cÚ©Ù\86Ù\86دÙ\87اÛ\8c Ø¹Ø¯Ù\85 Ù¾Û\8cÚ¯Û\8cرÛ\8c/Ù¾Û\8cÚ¯Û\8cرÛ\8c ({{int:Watchlist-unwatch}}/{{int:Watchlist-unwatch-undo}}) Ø¨Ù\87 ØµÙ\81حات Ù¾Û\8cÚ¯Û\8cرÛ\8c Ø¯Ø§Ø±Ø§Û\8c ØªØºÛ\8cÛ\8cرات (جاواسکریپت ممکن است نیاز شود)",
        "tog-watchlisthideanons": "ویرایش‌های کاربران ناشناس در فهرست پی‌گیری‌ها پنهان شود",
        "tog-watchlisthidepatrolled": "ویرایش‌های گشت‌خورده در فهرست پی‌گیری‌ها پنهان شود",
        "tog-watchlisthidecategorization": "نهفتن رده‌بندی صفحه‌ها",
        "customcssprotected": "شما اجازهٔ ویرایش این صفحهٔ سی‌اس‌اس را ندارید، زیرا حاوی تنظیم‌های شخصی یک کاربر دیگر است.",
        "customjsonprotected": "شما اجازهٔ ویرایش در این صفحهٔ JSON را ندارید چون دارای تنظیمات شخصی کاربران است.",
        "customjsprotected": "شما اجازهٔ ویرایش این صفحهٔ جاوااسکریپت را ندارید، زیرا حاوی تنظیم‌های شخصی یک کاربر دیگر است.",
+       "sitecssprotected": "به دلیل تاثیر سراسری بر روی همه بازدیدکنندگان،امکان ویرایش این صفحه css برای شما نیست.",
+       "sitejsonprotected": "به دلیل تاثیر سراسری بر روی همه بازدیدکنندگان،امکان ویرایش این صفحه JSON برای شما نیست.",
+       "sitejsprotected": "به دلیل تاثیر سراسری بر روی همه بازدیدکنندگان،امکان ویرایش این صفحه جاوااسکریپت برای شما نیست.",
        "mycustomcssprotected": "شما دارای مجوز ویرایش این صفحهٔ سی‌اس‌اس نیستید.",
+       "mycustomjsonprotected": "شما اجازه ویرایش این صفحه JSON را ندارید.",
        "mycustomjsprotected": "شما دارای مجوز ویرایش این صفحهٔ جاوااسکریپت نیستید.",
        "myprivateinfoprotected": "شما دارای مجوز ویرایش اطلاعات شخصی خود نیستید.",
        "mypreferencesprotected": "شما دارای مجوز ویرایش تنظیمات خود نیستید.",
        "password-login-forbidden": "استفاده از این نام کاربری و گذرواژه ممنوع است.",
        "mailmypassword": "بازنشانی گذرواژه",
        "passwordremindertitle": "یادآور گذرواژهٔ {{SITENAME}}",
-       "passwordremindertext": "Û\8cÚ© Ù\86Ù\81ر (احتÙ\85اÙ\84اÙ\8b Ø®Ù\88د Ø´Ù\85اØ\8c Ø¨Ø§ Ù\86شاÙ\86Û\8c Ø¢Û\8câ\80\8cÙ¾Û\8c $1) Ú¯Ø°Ø±Ù\88اÚ\98Ù\87Ù\94 Ø¬Ø¯Û\8cدÛ\8c Ø¨Ø±Ø§Û\8c Ø­Ø³Ø§Ø¨ Ú©Ø§Ø±Ø¨Ø±Û\8c Ø´Ù\85ا Ø¯Ø± {{SITENAME}} Ø¯Ø±Ø®Ù\88است Ú©Ø±Ø¯Ù\87â\80\8cاست ($4). \nÛ\8cÚ© Ú¯Ø°Ø±Ù\88اÚ\98Ù\87Ù\94 Ù\85Ù\88Ù\82ت Ø¨Ø±Ø§Û\8c Ú©Ø§Ø±Ø¨Ø± Â«$2» Ø³Ø§Ø®ØªÙ\87 Ø´Ø¯Ù\87 Ù\88 Ø¨Ø±Ø§Ø¨Ø± Ø¨Ø§ Â«$3» Ù\82رار Ø¯Ø§Ø¯Ù\87 Ø´Ø¯Ù\87â\80\8cاست.\nاگر Ù\87دÙ\81تاÙ\86 Ù\87Ù\85Û\8cÙ\86 Ø¨Ù\88دÙ\87â\80\8cاستØ\8c Ø§Ú©Ù\86Ù\88Ù\86 Ø¨Ø§Û\8cد Ù\88ارد Ø³Ø§Ù\85اÙ\86Ù\87 Ø´Ù\88Û\8cد Ù\88 Ú¯Ø°Ø±Ù\88اÚ\98Ù\87Ù\94 Ø¬Ø¯Û\8cدÛ\8c Ø¨Ø±Ú¯Ø²Û\8cÙ\86Û\8cد.\nگذرÙ\88اÚ\98Ù\87Ù\94 Ù\85Ù\88Ù\82ت Ø´Ù\85ا Ø¸Ø±Ù\81 {{PLURAL:$5|Û\8cÚ© Ø±Ù\88ز|$5 Ø±Ù\88ز}} Ø¨Ø§Ø·Ù\84 Ù\85Û\8câ\80\8cØ´Ù\88د.\n\nاگر Ú©Ø³ Ø¯Û\8cگرÛ\8c Ø§Û\8cÙ\86 Ø¯Ø±Ø®Ù\88است Ø±Ø§ Ú©Ø±Ø¯Ù\87â\80\8cاست Û\8cا Ø§Û\8cÙ\86Ú©Ù\87 Ø´Ù\85ا Ú¯Ø°Ø±Ù\88اÚ\98Ù\87Ù\94 Ù¾Û\8cØ´Û\8cÙ\86 Ø®Ù\88د Ø±Ø§ Ø¨Ù\87 Û\8cاد Ø¢Ù\88ردÙ\87â\80\8cاÛ\8cد Ù\88 Ø¯Û\8cگر ØªÙ\85اÛ\8cÙ\84Û\8c Ø¨Ù\87 ØªØºÛ\8cÛ\8cر Ø¢Ù\86 Ù\86دارÛ\8cدØ\8c Ù\85Û\8câ\80\8cتÙ\88اÙ\86Û\8cد Ø§Û\8cÙ\86 Ù¾Û\8cغاÙ\85 Ø±Ø§ Ù\86ادÛ\8cدÙ\87 Ø¨Ú¯Û\8cرÛ\8cد Ù\88 Ù\87Ù\85اÙ\86 Ú¯Ø°Ø±Ù\88اÚ\98Ù\87Ù\94 Ù¾Û\8cØ´Û\8cÙ\86 Ø±Ø§ Ø¨Ù\87 Ú©Ø§Ø± Ø¨Ø±Û\8cد.",
+       "passwordremindertext": "یک نفر (با نشانی آی‌پی $1) گذرواژهٔ جدیدی برای حساب کاربری شما در {{SITENAME}} درخواست کرده‌است ($4). \nیک گذرواژهٔ موقت برای کاربر «$2» ساخته شده و برابر با «$3» قرار داده شده‌است.\nاگر هدفتان همین بوده‌است، اکنون باید وارد سامانه شوید و گذرواژهٔ جدیدی برگزینید.\nگذرواژهٔ موقت شما ظرف {{PLURAL:$5|یک روز|$5 روز}} باطل می‌شود.\n\nاگر کس دیگری این درخواست را کرده‌است یا اینکه شما گذرواژهٔ پیشین خود را به یاد آورده‌اید و دیگر تمایلی به تغییر آن ندارید، می‌توانید این پیغام را نادیده بگیرید و همان گذرواژهٔ پیشین را به کار برید.",
        "noemail": "هیچ آدرس ایمیلی برای کاربر «$1» ثبت نشده است.",
        "noemailcreate": "شما باید یک آدرس ایمیل درست فراهم کنید",
        "passwordsent": "گذرواژه‌ای جدید به آدرس ایمیل ثبت شده برای «$1» ارسال شد.\nلطفاً پس از دریافت آن، دوباره به سیستم وارد شوید.",
        "botpasswords-existing": "گذرواژه‌های موجود ربات",
        "botpasswords-createnew": "ایجاد گذرواژه ربات",
        "botpasswords-editexisting": "ویرایش گذرواژه موجود ربات",
+       "botpasswords-label-needsreset": "(نیاز به تنظیم مجدد گذرواژه)",
        "botpasswords-label-appid": "نام ربات:",
        "botpasswords-label-create": "ایجاد",
        "botpasswords-label-update": "به‌روز رسانی",
        "botpasswords-restriction-failed": "محدودیت‌های گذرواژهٔ ربات از این ورود جلوگیری می‌کند.",
        "botpasswords-invalid-name": "نام کاربری مشخص شده دارای جداکنندهٔ گذرواژهٔ رباتی نیست («$1»).",
        "botpasswords-not-exist": "کاربر «$1» گذرواژهٔ رباتی نام‌دهی شدهٔ «$2» ندارد.",
+       "botpasswords-needs-reset": "گذرواژهٔ رباتی برای ربات «$2» و {{GENDER:$1|کاربر}} «$1» باید از نو تنظیم شود.",
        "resetpass_forbidden": "نمی‌توان گذرواژه‌ها را تغییر داد",
        "resetpass_forbidden-reason": "نمی‌توانید گذرواژه‌ها را تغییر داد: $1",
        "resetpass-no-info": "برای دسترسی مستقیم به این صفحه شما باید به سامانه وارد شده باشید.",
        "resetpass-temp-password": "گذرواژهٔ موقت:",
        "resetpass-abort-generic": "تغییر گذرواژه به دست یکی از افزونه‌ها لغو شده است.",
        "resetpass-expired": "رمز عبور شما منقضی شده‌است. لطفاً برای ورود رمز عبور جدیدی را تنظیم کنید.",
-       "resetpass-expired-soft": "رمز عبور شما منقضی شده‌است و نیاز به تنظیم مجدد دارد. لطفاً اکنون رمز عبور جدیدی را انتخاب کنید، یا برای تنظیم مجدد آن در آینده، دکمهٔ «{{int:authprovider-resetpass-skip-label}}» را کلیک کنید.",
-       "resetpass-validity-soft": "گذرÙ\88اÙ\87Ù\94 Ø´Ù\85ا ØµØ­Û\8cØ­ Ù\86Û\8cست: $1\n\nÙ\84Ø·Ù\81اÙ\8b Û\8cÚ© Ú¯Ø°Ø±Ù\88اÚ\98Ù\87Ù\94 ØªØ§Ø²Ù\87 Ø§Ù\84Ø¢Ù\86 Ø§Ù\86تخاب Ú©Ù\86Û\8cد Û\8cا Ø¨Ø± Â«{{int:authprovider-resetpass-skip-label}}» Ú©Ù\84Û\8cÚ© Ú©Ù\86Û\8cد Ú©Ù\87 Ø¯Ù\88بارÙ\87 Ø¢Ù\86 Ø±Ø§ Ø¨Ø¹Ø¯Ø§Ù\8b Ø§Ù\86تخاب Ú©Ù\86ید.",
+       "resetpass-expired-soft": "رمز عبور شما منقضی شده‌است و نیاز به تغییر دارد. لطفاً اکنون رمز عبور جدیدی را انتخاب کنید، یا برای تغییر آن در آینده، دکمهٔ «{{int:authprovider-resetpass-skip-label}}» را کلیک کنید.",
+       "resetpass-validity-soft": "گذرÙ\88اÙ\87Ù\94 Ø´Ù\85ا ØµØ­Û\8cØ­ Ù\86Û\8cست: $1\n\nÙ\84Ø·Ù\81اÙ\8b Û\8cÚ© Ú¯Ø°Ø±Ù\88اÚ\98Ù\87Ù\94 ØªØ§Ø²Ù\87 Ø§Ù\84Ø¢Ù\86 Ø§Ù\86تخاب Ú©Ù\86Û\8cد Û\8cا Ø¨Ø± Â«{{int:authprovider-resetpass-skip-label}}» Ú©Ù\84Û\8cÚ© Ú©Ù\86Û\8cد Ú©Ù\87 Ø¯Ù\88بارÙ\87 Ø¢Ù\86 Ø±Ø§ Ø¨Ø¹Ø¯Ø§Ù\8b ØªØºÛ\8cÛ\8cر Ø¯Ù\87ید.",
        "passwordreset": "بازنشانی گذرواژه",
        "passwordreset-text-one": "برای بازنشانی گذرواژه‌تان این فرم را کامل کنید.",
        "passwordreset-text-many": "{{PLURAL:$1|برای دریافت یک گذرواژهٔ موقت از طریق ایمیل، یکی از خانه‌ها را پر کنید.}}",
        "subject-preview": "پیش‌نمایش موضوع:",
        "previewerrortext": "در زمان تلاش برای نمایش دادن تغییرات شما، خطایی رخ داد.",
        "blockedtitle": "کاربر بسته شده‌است",
-       "blockedtext": "<strong>دسترسی حساب کاربری یا نشانی آی‌پی شما بسته شده‌است.</strong>\n\nاین قطع دسترسی توسط $1 انجام شده است.\nدلیل ارائه‌شده چنین است: <em>$2</em>\n\n* شروع قطع دسترسی: $8\n* پایان قطع دسترسی: $6\n* کاربری هدف قطع دسترسی: $7\n\nشما می‌توانید با $1 یا [[{{MediaWiki:Grouppage-sysop}}|مدیری]] دیگر تماس بگیرید و در این باره صحبت کنید.\nتوجه کنید که شما نمی‌توانید از قابلیت «ایمیل به این کاربر» استفاده کنید مگر آنکه آدرس ایمیل معتبری در [[Special:Preferences|ترجیحات کاربری]] خودتان ثبت کرده باشید و نیز باید امکان استفاده از این قابلیت برای شما قطع نشده باشد.\nنشانی آی‌پی فعلی شما $3 و شمارهٔ قطع دسترسی شما $5 است.\nلطفاً تمامی جزئیات فوق را در کلیهٔ درخواست‌هایی که در این باره مطرح می‌کنید ذکر کنید.",
-       "autoblockedtext": "دسترسی نشانی آی‌پی شما قطع شده‌است، زیرا این نشانی آی‌پی توسط کاربر دیگری استفاده شده که دسترسی او توسط $1 قطع شده‌است.\nدلیل ارائه‌شده چنین است:\n\n:''$2''\n\n* شروع قطع دسترسی: $8\n* پایان قطع دسترسی: $6\n* کاربری هدف قطع دسترسی: $7\n\nشما می‌توانید با $1 یا [[{{MediaWiki:Grouppage-sysop}}|مدیری]] دیگر تماس بگیرید و در این باره صحبت کنید.\nتوجه کنید که شما نمی‌توانید از قابلیت «ایمیل به این کاربر» استفاده کنید مگر آنکه نشانی ایمیل معتبری در [[Special:Preferences|ترجیحات کاربری]] خودتان ثبت کرده باشید و نیز باید امکان استفاده از این قابلیت برای شما قطع نشده باشد.\nنشانی آی‌پی فعلی شما $3 و شمارهٔ قطع دسترسی شما $5 است.\nلطفاً تمامی جزئیات فوق را در کلیهٔ درخواست‌هایی که در این باره مطرح می‌کنید ذکر کنید.",
+       "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خواهشمند است تمام جزئیات بالا را در هر پرس‌وجویی که انجام می‌دهید قرار دهید.",
        "blockednoreason": "دلیلی مشخص نشده‌است",
        "whitelistedittext": "برای ویرایش مقاله‌ها باید $1.",
        "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>⌘-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> on a Mac) and then to <em>Privacy & security → Clear browsing data → Cached images and files</em>.",
        "usercssyoucanpreview": "'''نکته:''' پیش از ذخیره کردن پرونده سی‌اس‌اس خود، با دکمهٔ '''{{int:showpreview}}''' آن را آزمایش کنید.",
+       "userjsonyoucanpreview": "<strong>نکته:</strong> از دکمه \"{{int:showpreview}}\" برای آزمودن JSON پیش از ذخیره استفاده کنید.",
        "userjsyoucanpreview": "'''نکته:''' پیش از ذخیره کردن پروندهٔ جاوااسکریپت خود، با دکمهٔ '''{{int:showpreview}}''' آن را آزمایش کنید.",
        "usercsspreview": "'''فراموش مکنید که شما فقط دارید پیش‌نمایش سی‌اس‌اس کاربری‌تان را می‌بینید.'''\n'''این سی‌اس‌اس هنوز ذخیره نشده‌است!'''",
+       "userjsonpreview": "<strong>توجه داشته باشید که شما در حال آزمودن و پیش نمایش گرفتن از تنظیمات JSON هستید و هنوز آن را ذخیره نکردید!</strong>",
        "userjspreview": "'''به یاد داشته باشید که شما فقط دارید جاوااسکریپت کاربری‌تان را امتحان می‌کنید/پیش‌نمایش آن را می‌بینید.'''\n'''این جاوااسکریپت هنوز ذخیره نشده‌است!'''",
        "sitecsspreview": "'''به یاد داشته باشید که شما فقط دارید پیش‌نمایش این سی‌اس‌اس را می‌بینید.'''\n'''این سی‌اس‌اس هنوز ذخیره نشده‌است!'''",
+       "sitejsonpreview": "<strong>توجه داشته باشید که شما در حال آزمودن و پیش نمایش گرفتن از تنظیمات JSON هستید و هنوز آن را ذخیره نکردید!</strong>",
        "sitejspreview": "'''به یاد داشته باشید که شما فقط دارید پیش‌نمایش این جاوااسکریپت را می‌بینید.'''\n'''این جاوااسکریپت هنوز ذخیره نشده‌است!'''",
-       "userinvalidconfigtitle": "'''هشدار:''' پوسته‌ای به نام «$1» وجود ندارد.\nبه یاد داشته باشید که صفحه‌های شخصی ‎.css و ‎.js باید عنوانی با حروف کوچک داشته باشند؛ نمونه: {{ns:user}}:فو/vector.css در مقابل {{ns:user}}:فو/Vector.css.",
+       "userinvalidconfigtitle": "<strong>هشدار:</strong> پوسته‌ای به نام «$1» وجود ندارد.\nبه یاد داشته باشید که صفحه‌های شخصی ‎.css ،.json و ‎.js باید عنوانی با حروف کوچک داشته باشند؛ نمونه: {{ns:user}}:فو/vector.css در مقابل {{ns:user}}:فو/Vector.css.",
        "updated": "(به‌روز شد)",
        "note": "'''نکته:'''",
        "previewnote": "'''به یاد داشته باشید که این فقط پیش‌نمایش است.'''\nتغییرات شما هنوز ذخیره نشده‌است!",
        "copyrightwarning": "لطفاً توجه داشته‌باشید که همهٔ مشارکت‌ها در {{SITENAME}} منتشرشده تحت $2 در نظر گرفته‌می‌شوند (برای جزئیات بیش‌تر $1 را ببینید).\nاگر نمی‌خواهید نوشته‌هایتان بی‌رحمانه ویرایش و توزیع شوند؛ بنابراین، آنها را اینجا ارائه نکنید.<br />\nشما همچنین به ما تعهد می‌کنید که خودتان این را نوشته‌اید یا آن را از یک منبع با مالکیت عمومی یا مشابه آزاد آن برداشته‌اید (برای جزئیات بیش‌تر $1 را ببینید).\n<strong>کارهای دارای حق تکثیر را بدون اجازه ارائه نکنید!</strong>",
        "copyrightwarning2": "لطفاً توجه داشته‌باشید که همهٔ مشارکت‌ها در {{SITENAME}} ممکن است توسط دیگر مشارکت‌کنندگان تغییر یابند، ویرایش یا حذف شوند.\nاگر نمی‌خواهید نوشته‌هایتان بی‌رحمانه ویرایش شوند؛ بنابراین، آنها را اینجا ارائه نکنید.<br />\nشما همچنین به ما تعهد می‌کنید که خودتان این را نوشته‌اید یا آن را از یک منبع با مالکیت عمومی یا مشابه آزاد آن برداشته‌اید ($1 را برای جزئیات بیشتر ببینید).\n<strong>کارهای دارای حق تکثیر را بدون اجازه ارائه نکنید!</strong>",
        "editpage-cannot-use-custom-model": "مدل محتوای این صفحه نمی‌تواند عوض شود.",
-       "longpageerror": "'''خطا: متنی که ارسال کرده‌اید {{PULAR:$1|یک کیلوبایت|$1 کیلوبایت}} طول دارد. این مقدار از مقدار بیشینهٔ {{PLURAL:$2|یک کیلوبایت|$2 کیلوبایت}} بیشتر است.'''\nنمی‌توان آن را ذخیره کرد.",
+       "longpageerror": "'''خطا: متنی که ارسال کرده‌اید {{PLURAL:$1|یک کیلوبایت|$1 کیلوبایت}} طول دارد. این مقدار از مقدار بیشینهٔ {{PLURAL:$2|یک کیلوبایت|$2 کیلوبایت}} بیشتر است.'''\nنمی‌توان آن را ذخیره کرد.",
        "readonlywarning": "<strong>هشدار: پایگاه داده برای نگهداری قفل شده‌است، به همین علت هم‌اکنون نمی‌توانید ویرایش‌هایتان را ذخیره کنید.</strong>\nاگر می‌خواهید متن را در یک پروندهٔ متنی کپی کنید و برای آینده ذخیره‌اش کنید.\n\nمدیری که آن را قفل کرده این توضیح را ارائه کرده‌است: $1",
        "protectedpagewarning": "'''هشدار: این صفحه قفل شده‌است تا فقط کاربران با دسترسی مدیریت بتوانند ویرایشش کنند.'''\nآخرین موارد سیاهه در زیر آمده‌است:",
-       "semiprotectedpagewarning": "'''توجه:''' این صفحه قفل شده‌است تا تنها کاربران ثبت‌نام‌کرده قادر به ویرایش آن باشند.\nآخرین موارد سیاهه در زیر آمده‌است:",
+       "semiprotectedpagewarning": "<strong>توجه:</strong>این صفحه قفل شده‌است تا تنها کاربران ثبت‌نام‌کرده قادر به ویرایش آن باشند.\nآخرین موارد سیاهه در زیر آمده‌است:",
        "cascadeprotectedwarning": "<strong>هشدار:</strong> این صفحه به علت قرارگرفتن در {{PLURAL:$1|صفحهٔ|صفحه‌های}} آبشاری-محافظت‌شدهٔ زیر قفل شده‌است تا فقط [[Special:ListGroupRights|گروه خاصی از کاربران]] بتوانند ویرایشش کنند.",
        "titleprotectedwarning": "'''هشدار: این صفحه به شکلی قفل شده‌است که برای ایجاد آن [[Special:ListGroupRights|اختیارات خاصی]] لازم است.'''\nآخرین موارد سیاهه در زیر آمده است:",
        "templatesused": "{{PLURAL:$1|الگوی|الگوهای}} به‌کاررفته در این صفحه:",
        "diff-paragraph-moved-toold": "پاراگراف جابه‌جا شده بود. کلیک کنید تا به جای قدیمش بروید.",
        "difference-missing-revision": "{{PLURAL:$2|یک ویرایش|$2 ویرایش}}  از تفاوت نسخه‌ها ($1) {{PLURAL:$2|یافت|یافت}}  نشد.\n\nاین اتفاق معمولاً در اثر دنبال کردن پیوند تفاوتی به یک صفحهٔ حذف‌شده پیش می‌آید.\nمی‌توانید جزئیات بیشتر را در [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} سیاههٔ حذف] بیابید.",
        "searchresults": "نتایج جستجو",
+       "search-filter-title-prefix-reset": "جستجوی همه صفحات",
        "searchresults-title": "نتایج جستجو برای «$1»",
        "titlematches": "تطبیق عنوان مقاله",
        "textmatches": "تطبیق متن مقاله",
        "prefs-dateformat": "آرایش تاریخ",
        "prefs-timeoffset": "فاصلهٔ زمانی",
        "prefs-advancedediting": "تنظیمات عمومی",
+       "prefs-developertools": "ابزارهای توسعه‌دهندگان",
        "prefs-editor": "ویرایشگر",
        "prefs-preview": "پیش‌نمایش",
        "prefs-advancedrc": "گزینه‌های پیشرفته",
        "group-autoconfirmed": "کاربران تأییدشدهٔ خودکار",
        "group-bot": "ربات‌ها",
        "group-sysop": "مدیران",
+       "group-interface-admin": "مدیران رابط کاربری",
        "group-bureaucrat": "دیوان‌سالاران",
        "group-suppress": "فرونشانندگان",
        "group-all": "(همه)",
        "group-autoconfirmed-member": "{{GENDER:$1|کاربر تأییدشده}}",
        "group-bot-member": "ربات",
        "group-sysop-member": "{{GENDER:$1|مدیر}}",
+       "group-interface-admin-member": "مدیر رابط کاربری",
        "group-bureaucrat-member": "{{GENDER:$1|دیوان‌سالار}}",
        "group-suppress-member": "{{GENDER:$1|فرونشاننده}}",
        "grouppage-user": "{{ns:project}}:کاربران",
        "recentchanges-label-minor": "این یک ویرایش جزئی است",
        "recentchanges-label-bot": "این ویرایش را یک ربات انجام داده است",
        "recentchanges-label-unpatrolled": "این ویرایش هنوز گشت‌زنی نشده است",
-       "recentchanges-label-plusminus": "حجم صفحه به اندازه این مقدار بایت تغییر یافته است",
+       "recentchanges-label-plusminus": "حجم صفحه به اندازه این مقدار بایت تغییر یافته است.",
        "recentchanges-legend-heading": "<strong>اختصارها:</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (همچنین به [[Special:NewPages|فهرست صفحات تازه]] نگاه کنید)",
        "recentchanges-legend-plusminus": "(<em>±۱۲۳</em>)",
        "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",
        "rcfilters-empty-filter": "پالایه‌ای فعال نیست. همهٔ مشارکت‌های دیده می‌شوند.",
        "rcfilters-filterlist-title": "پالایه‌ها",
        "rcfilters-filterlist-whatsthis": "این چطور کار می‌کند؟",
-       "rcfilters-filterlist-feedbacklink": "به ما در مورد این پالایه‌های جدید بازخورد دهید",
+       "rcfilters-filterlist-feedbacklink": "به ما در مورد این پالایه‌ها بازخورد دهید",
        "rcfilters-highlightbutton-title": "پررنگ کردن نتایج",
        "rcfilters-highlightmenu-title": "انتخاب رنگ",
        "rcfilters-highlightmenu-help": "یک رنگ انتخاب کنید تا این خصوصیت پر رنگ شود",
        "rcfilters-filter-humans-description": "ویرایش توسط انسان.",
        "rcfilters-filtergroup-reviewstatus": "وضعیت بازبینی",
        "rcfilters-filter-reviewstatus-unpatrolled-label": "گشت‌نخورده",
+       "rcfilters-filter-reviewstatus-manual-label": "به طور دستی گشت خورد",
        "rcfilters-filtergroup-significance": "اهمیت",
        "rcfilters-filter-minor-label": "ویرایش‌های جزئی",
        "rcfilters-filter-minor-description": "ویرایش‌هایی که به عنوان جزئی برچسب خورده‌اند.",
        "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]] به رده اضافه شد",
        "filehist-dimensions": "ابعاد",
        "filehist-filesize": "اندازهٔ پرونده",
        "filehist-comment": "توضیح",
-       "imagelinks": "به‌کاررفتن پرونده",
+       "imagelinks": "کاربرد پرونده",
        "linkstoimage": "{{PLURAL:$1|صفحهٔ|صفحه‌های}} زیر به این تصویر پیوند {{PLURAL:$1|دارد|دارند}}:",
        "linkstoimage-more": "بیش از $1 صفحه به این پرونده پیوند {{PLURAL:$1|دارد|دارند}}.\nفهرست زیر تنها {{PLURAL:$1|اولین پیوند|اولین $1 پیوند}} به این صفحه را نشان می‌دهد.\n[[Special:WhatLinksHere/$2|فهرست کامل]] نیز موجود است.",
        "nolinkstoimage": "این پرونده در هیچ صفحه‌ای به کار نرفته‌است.",
        "deadendpages": "صفحه‌های بن‌بست",
        "deadendpagestext": "صفحه‌های زیر به هیچ صفحهٔ دیگری در {{SITENAME}} پیوند ندارند.",
        "protectedpages": "صفحه‌های محافظت‌شده",
+       "protectedpages-filters": "پالایه‌ها:",
        "protectedpages-indef": "فقط محافظت‌های بی‌پایان",
        "protectedpages-summary": "در این صفحه فهرست صفحات موجود است که در حال حاضر محافظت شده اند. برای فهرست عنوان‌هایی که از ایجاد محافظت شده‌اند، به [[{{#special:ProtectedTitles}}|{{int:protectedtitles}}]] مراجعه کنید.",
        "protectedpages-cascade": "فقط محافظت‌های آبشاری",
        "apisandbox-dynamic-error-exists": "پارامتری به نام \"$1\"هم اکنون وجود دارد.",
        "apisandbox-deprecated-parameters": "پارامتر های نامناسب",
        "apisandbox-fetch-token": "پرکردن خودکار توکن",
+       "apisandbox-add-multi": "افزودن",
        "apisandbox-submit-invalid-fields-title": "بعضی از بخش‌ها نامعتبر هستند.",
        "apisandbox-submit-invalid-fields-message": "لطفا موارد مشخص شده را اصلاح کرده و دوباره امتحان کنید.",
        "apisandbox-results": "نتیجه‌ها",
        "speciallogtitlelabel": "هدف (عنوان یا {{ns:user}}:نام کاربر برای کاربر):",
        "log": "سیاهه‌ها",
        "logeventslist-submit": "نمایش",
+       "logeventslist-patrol-log": "سیاههٔ گشت",
+       "logeventslist-tag-log": "سیاهه برچسب",
        "all-logs-page": "تمام سیاهه‌های عمومی",
        "alllogstext": "نمایش یک‌جای تمام سیاهه‌های موجود در {{SITENAME}}.\nمی‌توانید با انتخاب نوع سیاهه، نام کاربری (حساس به کوچکی و بزرگی حروف) و صفحه‌های تغییریافته (حساس به بزرگی و کوچکی حروف)، نمایش را محدودتر سازید.",
        "logempty": "مورد منطبق با منظور شما در سیاهه یافت نشد.",
        "whatlinkshere": "پیوندها به این صفحه",
        "whatlinkshere-title": "صفحه‌هایی که به «$1» پیوند دارند",
        "whatlinkshere-page": "صفحه:",
-       "linkshere-2": "صفحه‌های زیر به '''$1''' پیوند دارند:",
-       "nolinkshere-2": "هیچ صفحه‌ای به '''$1''' پیوند ندارد.",
-       "nolinkshere-ns-2": "هیچ صفحه‌ای از فضای نام انتخاب شده به '''$1''' پیوند ندارد.",
+       "linkshere": "صفحه‌های زیر به '''$2''' پیوند دارند:",
+       "nolinkshere": "هیچ صفحه‌ای به '''$2''' پیوند ندارد.",
+       "nolinkshere-ns": "هیچ صفحه‌ای از فضای نام انتخاب شده به '''$2''' پیوند ندارد.",
        "isredirect": "صفحهٔ تغییرمسیر",
        "istemplate": "تراگنجانش‌ها",
        "isimage": "پیوند به پرونده",
        "markedaspatrollederrornotify": "زدن برچسب گشت، ناموفق بود.",
        "patrol-log-page": "سیاههٔ گشت",
        "patrol-log-header": "این سیاهه‌ای از ویرایش‌های گشت‌خورده است.",
-       "log-show-hide-patrol": "$1 سیاههٔ گشت‌زنی",
-       "log-show-hide-tag": "$1 سیاهه برچسب",
        "confirm-markpatrolled-button": "تأیید",
        "confirm-markpatrolled-top": "نسخهٔ $3 از $2 علامت گشت بخورد؟",
        "deletedrevision": "$1 نسخهٔ حذف شدهٔ قدیمی",
        "version-specialpages": "صفحه‌های ویژه",
        "version-parserhooks": "قلاب‌های تجزیه‌گر",
        "version-variables": "متغیرها",
+       "version-editors": "ویرایشگران",
        "version-antispam": "جلوگیری از هرزنامه",
        "version-other": "غیره",
        "version-mediahandlers": "به‌دست‌گیرنده‌های رسانه‌ها",
        "pagedata-title": "اطلاعات صفحه",
        "pagedata-text": "این صفحه یک رابط داده به صفحات است. لطفا نام صفحه را در آدرس به شکل زیرصفحه وارد کنید.\n* مذاکره محتوا با استفاده از هدر Accept ممکن است. این به این معنی است که داده‌ّای صفحه در قالبی که ترجیح دهید باز خواهد شد.",
        "pagedata-not-acceptable": "هیچ قالب تطبیقی یافت نشد. انواع MIME پشتیبانی شده: $1",
-       "pagedata-bad-title": "عنوان نامعتبر: «$1»."
+       "pagedata-bad-title": "عنوان نامعتبر: «$1».",
+       "passwordpolicies": "سیاست‌های گذرواژه",
+       "passwordpolicies-group": "گروه",
+       "passwordpolicies-policies": "سیاست‌ها"
 }
index 182e853..bd1e00a 100644 (file)
@@ -57,7 +57,9 @@
                        "4shadoww",
                        "Pahkiqaz",
                        "Rueter",
-                       "Kyykaarme"
+                       "Kyykaarme",
+                       "Surjection",
+                       "OneMember"
                ]
        },
        "tog-underline": "Linkkien alleviivaus:",
@@ -94,7 +96,7 @@
        "tog-watchlisthideminor": "Piilota pienet muokkaukset tarkkailulistalta",
        "tog-watchlisthideliu": "Piilota kirjautuneiden käyttäjien muokkaukset tarkkailulistalta",
        "tog-watchlistreloadautomatically": "Päivitä tarkkailulista automaattisesti aina kun jotakin suodatinta on muutettu (vaatii JavaScriptiä)",
-       "tog-watchlistunwatchlinks": "Lisää suorat tarkkailemattomat/tarkkaillut linkit tarkkailulistan merkintöihin (JavaScriptiä edellytetään nappuloiden toiminnallisuuteen)",
+       "tog-watchlistunwatchlinks": "Lisää suorat tarkkailemattomat/tarkkaillut linkit ({{int:Watchlist-unwatch}}/{{int:Watchlist-unwatch-undo}}) tarkkailulistan muutettujen sivujen merkintöihin (JavaScriptiä edellytetään nappuloiden toiminnallisuuteen)",
        "tog-watchlisthideanons": "Piilota rekisteröitymättömien käyttäjien muokkaukset tarkkailulistalta",
        "tog-watchlisthidepatrolled": "Piilota muutostentarkastajien hyväksymät muokkaukset tarkkailulistalta",
        "tog-watchlisthidecategorization": "Piilota sivujen luokitusmuutokset",
        "versionrequiredtext": "MediaWikistä tarvitaan vähintään versio $1 tämän sivun käyttämiseen. Katso [[Special:Version|versio]].",
        "ok": "OK",
        "pagetitle": "$1 – {{SITENAME}}",
-       "retrievedfrom": "Noudettu kohteesta $1",
+       "retrievedfrom": "Noudettu kohteesta \"$1\"",
        "youhavenewmessages": "Sinulle on $1 ($2).",
-       "youhavenewmessagesfromusers": "Sinulle on $1 {{PLURAL:$3|toiselta käyttäjältä|$3 käyttäjältä}} ($2).",
+       "youhavenewmessagesfromusers": "{{PLURAL:$4|Sinulle on}} $1 {{PLURAL:$3|toiselta käyttäjältä|$3 käyttäjältä}} ($2).",
        "youhavenewmessagesmanyusers": "Sinulle on $1 uusia viestejä useilta käyttäjiltä ($2).",
        "newmessageslinkplural": "{{PLURAL:$1|uusi viesti|999=uusia viestejä}}",
        "newmessagesdifflinkplural": "{{PLURAL:$1|viimeinen muutos|999=viimeiset muutokset}}",
        "editold": "muokkaa",
        "viewsourceold": "näytä wikiteksti",
        "editlink": "muokkaa",
-       "viewsourcelink": "näytä lähdekoodi",
+       "viewsourcelink": "näytä wikiteksti",
        "editsectionhint": "Muokkaa osiota $1",
        "toc": "Sisällysluettelo",
        "showtoc": "näytä",
        "databaseerror-query": "Kysely: $1",
        "databaseerror-function": "Toiminto (funktio): $1",
        "databaseerror-error": "Virhe: $1",
+       "transaction-duration-limit-exceeded": "Korkean toistoviiveen välttämiseksi tämä transaktio keskeytettiin, koska kirjoituksen pituus ($1) ylitti $2 sekunnin rajan.\nJos muutat monia kohteita samaan aikaan, voit yrittää operaation halkaisemista pienempiin osiin.",
        "laggedslavemode": "'''Varoitus:''' Sivu ei välttämättä sisällä viimeisimpiä muutoksia.",
        "readonly": "Tietokanta on lukittu",
        "enterlockreason": "Anna lukituksen syy sekä sen arvioitu poistamisaika",
        "cascadeprotected": "Tämä sivu on suojattu muokkauksilta, koska se on sisällytetty {{PLURAL:$1|seuraavaan tarttuvasti suojattuun sivuun|seuraaviin tarttuvasti suojattuihin sivuihin}}:\n$2",
        "namespaceprotected": "Sinulla ei ole oikeutta muokata sivuja, jotka ovat nimiavaruudessa <strong>$1</strong>.",
        "customcssprotected": "Sinulla ei ole oikeutta muuttaa tätä CSS-sivua, koska se sisältää toisen käyttäjän henkilökohtaisia asetuksia.",
+       "customjsonprotected": "Sinulla ei ole oikeutta muuttaa tätä JSON-sivua, koska se sisältää toisen käyttäjän henkilökohtaisia asetuksia.",
        "customjsprotected": "Sinulla ei ole oikeutta muuttaa tätä JavaScript-sivua, koska se sisältää toisen käyttäjän henkilökohtaisia asetuksia.",
+       "sitecssprotected": "Sinulla ei ole oikeutta muokata tätä CSS-sivua, koska se saattaa vaikuttaa kaikkiin sivuston käyttäjiin",
+       "sitejsonprotected": "Sinulla ei ole oikeutta muokata tätä JSON-sivua, koska se saattaa vaikuttaa kaikkiin sivuston käyttäjiin",
+       "sitejsprotected": "Sinulla ei ole oikeutta muokata tätä JavaScript-sivua, koska se saattaa vaikuttaa kaikkiin sivuston käyttäjiin",
        "mycustomcssprotected": "Sinulla ei ole oikeutta muokata tätä CSS-sivua.",
        "mycustomjsonprotected": "Sinulla ei ole oikeutta muokata tätä JSON-sivua.",
        "mycustomjsprotected": "Sinulla ei ole oikeutta muokata tätä JavaScript-sivua.",
        "botpasswords-label-delete": "Poista",
        "botpasswords-label-resetpassword": "Hanki uusi salasana",
        "botpasswords-label-grants": "Valittavissa olevat toimintaoikeudet:",
+       "botpasswords-help-grants": "Toimintaoikeudet sallivat pääsyn oikeuksiin, joita käyttäjätililläsi jo on. Toimintaoikeuden käyttöönotto täällä ei lisää käyttäjätilillesi oikeuksia, joita sillä ei jo ole. Lisätietoja löytyy [[Special:ListGrants|toimintaoikeuksien luettelosta]].",
        "botpasswords-label-grants-column": "Myönnetään",
        "botpasswords-bad-appid": "Botin nimi \"$1\" ei kelpaa.",
        "botpasswords-insert-failed": "Botin nimen \"$1\" lisääminen epäonnsitui. Onko se jo lisätty?",
        "resetpass-temp-password": "Väliaikainen salasana:",
        "resetpass-abort-generic": "Laajennus keskeytti salasanan vaihdon.",
        "resetpass-expired": "Salasanasi on vanhentunut. Valitse uusi salasana, jotta pääset kirjautumaan sisään.",
-       "resetpass-expired-soft": "Salasanasi on vanhentunut ja se pitää uudistaa. Valitse uusi salasana nyt tai paina \"{{int:authprovider-resetpass-skip-label}}\", niin voit uudistaa salasanan myöhemmin.",
+       "resetpass-expired-soft": "Salasanasi on vanhentunut ja se pitää vaihtaa. Valitse uusi salasana nyt tai paina \"{{int:authprovider-resetpass-skip-label}}\", niin voit vaihtaa salasanan myöhemmin.",
        "resetpass-validity-soft": "Salasanasi ei ole kelvollinen: $1\n\nValitse nyt uusi salasana tai paina \"{{int:authprovider-resetpass-skip-label}}\", niin voit vaihtaa sen myöhemmin.",
        "passwordreset": "Salasanan uusiminen",
        "passwordreset-text-one": "Täytä tämä lomake uudistaaksesi salasanasi.",
        "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.",
+       "passwordreset-nocaller": "Kutsuja on määriteltävä",
        "passwordreset-nosuchcaller": "Kutsuvaa funktiota ei ole olemassa: $1",
        "passwordreset-ignored": "Salasanan palauttamista ei käsitelty. Ehkä tarjoajaa ei ollut määritetty?",
        "passwordreset-invalidemail": "Virheellinen sähköpostiosoite",
        "accmailtext": "Satunnaisesti generoitu salasana käyttäjälle [[User talk:$1|$1]] on lähetetty osoitteeseen $2. Sen voi vaihtaa kirjautumisen jälkeen [[Special:ChangePassword|asetussivulla]].",
        "newarticle": "(Uusi)",
        "newarticletext": "Linkki toi sivulle, jota ei vielä ole.\nVoit luoda sivun kirjoittamalla alla olevaan kenttään (katso [$1 ohjesivulta] lisätietoja).\nJos et halua luoda sivua, käytä selaimen paluutoimintoa.",
-       "anontalkpagetext": "----''Tämä on nimettömän käyttäjän keskustelusivu. Hän ei ole joko luonut itselleen käyttäjätunnusta tai ei käytä sitä. Siksi hänet tunnistetaan nyt numeerisella IP-osoitteella. Kyseinen IP-osoite voi olla useamman henkilön käytössä. Jos olet nimetön käyttäjä, ja sinusta tuntuu, että aiheettomia kommentteja on ohjattu sinulle, [[Special:CreateAccount|luo itsellesi käyttäjätunnus]] tai [[Special:UserLogin|kirjaudu sisään]] välttääksesi jatkossa sekaannukset muiden nimettömien käyttäjien kanssa.''",
+       "anontalkpagetext": "----''Tämä on nimettömän käyttäjän keskustelusivu. Hän ei ole joko luonut itselleen käyttäjätunnusta tai ei käytä sitä, jonka vuoksi hänet tunnistetaan nyt numeerisella IP-osoitteella. Kyseinen IP-osoite voi olla useamman henkilön käytössä. Jos olet nimetön käyttäjä ja sinusta tuntuu, että aiheettomia kommentteja on ohjattu sinulle, [[Special:CreateAccount|luo itsellesi käyttäjätunnus]] tai [[Special:UserLogin|kirjaudu sisään]] välttääksesi jatkossa sekaannukset muiden nimettömien käyttäjien kanssa.''",
        "noarticletext": "Tällä hetkellä tällä sivulla ei ole tekstiä.\nVoit [[Special:Search/{{PAGENAME}}|etsiä sivun nimellä]] muilta sivuilta,\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} hakea aiheeseen liittyviä lokeja]\ntai [{{fullurl:{{FULLPAGENAME}}|action=edit}} luoda tämän sivun]</span>.",
        "noarticletext-nopermission": "Tällä hetkellä tällä sivulla ei ole tekstiä.\nVoit [[Special:Search/{{PAGENAME}}|etsiä sivun nimellä]] muilta sivuilta tai <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} hakea aiheeseen liittyviä lokeja]</span>, mutta sinulla ei ole oikeutta luoda tätä sivua.",
        "missing-revision": "Sivusta \"{{FULLPAGENAME}}\" ei ole olemassa versiota $1.\n\nYleensä tämä johtuu vanhentuneesta historialinkistä sivulle, joka on poistettu.\nTarkempia tietoja löytyy [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} poistolokista].",
        "userjsonyoucanpreview": "<strong>Vihje:</strong> Käytä \"{{int:showpreview}}\" painiketta testataksesi uutta JSON:iasi ennen tallentamista.",
        "userjsyoucanpreview": "Voit testata uutta JavaScriptiä ennen tallennusta käyttämällä painiketta ”{{int:showpreview}}”.",
        "usercsspreview": "'''Tämä on CSS:n esikatselu. Muutoksia ei ole vielä tallennettu.'''",
+       "userjsonpreview": "<strong>Huomaa, että tämä on vasta JSON-käyttäjäasetusten esikatselu.\nMuutoksia ei ole vielä tallennettu!</strong>",
        "userjspreview": "'''Tämä on JavaScriptin esikatselu.'''",
        "sitecsspreview": "'''Huomaa, että tämä on vasta CSS:n esikatselu.''' \n'''Muutoksia ei ole vielä tallennettu.'''",
+       "sitejsonpreview": "<strong>Huomaa, että tämä on vasta JSON-asetusten esikatselu.\nMuutoksia ei ole vielä tallennettu!</strong>",
        "sitejspreview": "'''Huomaa, että tämä on vasta JavaScript-koodin esikatselu.'''\n'''Muutoksia ei ole vielä tallennettu.'''",
        "userinvalidconfigtitle": "<strong>Varoitus:</strong> Tyyliä nimeltä ”$1” ei ole olemassa. Muista, että käyttäjän määrittelemät .css-, -json- ja .js-sivut alkavat pienellä alkukirjaimella, esim. {{ns:user}}:Matti Meikäläinen/vector.css eikä {{ns:user}}:Matti Meikäläinen/Vector.css.",
        "updated": "(Päivitetty)",
        "content-model-css": "CSS",
        "content-json-empty-object": "Tyhjä objekti",
        "content-json-empty-array": "Tyhjä array",
-       "deprecated-self-close-category": "Sivut, joissa on virheellisiä itsensäsulkevia HTLM-tageja",
+       "deprecated-self-close-category": "Sivut, joissa on virheellisiä itsensäsulkevia HTML-tageja",
        "deprecated-self-close-category-desc": "Sivulla on virheellisiä itsensäsulkevia HTML-tageja, kuten <code>&lt;b/></code> tai <code>&lt;span/></code>. Niiden käyttäytyminen muuttuu pian HTLM5:n määritysten mukaiseksi, joten niiden käyttö wikitekstissä on vanhentunut.",
        "duplicate-args-warning": "<strong>Varoitus:</strong> [[:$1]] kutsuu mallinetta [[:$2]] niin, että parametrille \"$3\" on annettu enemmän kuin yksi arvo. Ainoastaan viimeksi annettu arvo otetaan huomioon.",
        "duplicate-args-category": "Sivut, jotka käyttävät kaksinkertaisia argumentteja mallinekutsuissa",
        "post-expand-template-argument-category": "Käsittelemättömiä mallinemuuttujia sisältävät sivut",
        "parser-template-loop-warning": "Mallinesilmukka havaittu: [[$1]]",
        "template-loop-category": "Sivut, joissa on mallinesilmukoita",
+       "template-loop-category-desc": "Tämä sivu sisältää mallinesilmukan, eli itseänsä kutsuvan mallineen.",
        "template-loop-warning": "<strong>Varoitus:</strong> Tämä sivu kutsuu mallinetta [[:$1]] joka aiheuttaa mallinesilmukan (loputon rekursiivinen kutsu).",
        "parser-template-recursion-depth-warning": "Mallineen rekursioraja ylittyi ($1)",
        "language-converter-depth-warning": "Kielimuuntimen syvyysraja ylittyi ($1)",
        "expansion-depth-exceeded-warning": "Sivu ylitti laajentamissyvyyden.",
        "parser-unstrip-loop-warning": "Unstrip-silmukka havaittiin",
        "unstrip-depth-warning": "Unstrip-rekursion enimmäissyvyys ($1) ylitettiin",
+       "unstrip-depth-category": "Sivut, joissa unstrip-enimmäissyvyys ylittyy",
+       "unstrip-size-warning": "Unstrip-kokoraja ($1) ylitettiin",
+       "unstrip-size-category": "Sivut, joissa unstrip-kokoraja ylittyy",
        "converter-manual-rule-error": "Kielivarianttisäännössä on virhe",
        "undo-success": "Kumoaminen voidaan suorittaa.\nVarmista alla olevasta vertailusta, että haluat saada aikaan tämän lopputuloksen, ja sen jälkeen tallenna alla näkyvät muutokset.",
        "undo-failure": "Muokkausta ei voi kumota välissä olevien ristiriitaisten muutosten vuoksi.",
+       "undo-main-slot-only": "Muokkausta ei voitu kumota, koska muokkaus koskee sisältöä pääalueen ulkopuolella.",
        "undo-norev": "Muokkausta ei voida kumota, koska sitä ei ole olemassa tai se on poistettu.",
        "undo-nochange": "Tämä muokkaus näyttää olevan jo kumottu.",
        "undo-summary": "Kumottu muokkaus $1, jonka teki [[Special:Contributions/$2|$2]] ([[User talk:$2|keskustelu]])",
        "diff-paragraph-moved-toold": "Kappale siirrettiin. Klikkaa hypätäksesi vanhaan sijaintiin.",
        "difference-missing-revision": "{{PLURAL:$2|Yhtä versiota|$2 versiota}} tästä vertailusta ($1) {{PLURAL:$2|ei}} löytynyt.\n\nUseimmiten tämä johtuu vanhentuneesta vertailulinkistä poistettuun sivuun.\nLisätietoja löytyy [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} poistolokista].",
        "searchresults": "Hakutulokset",
+       "search-filter-title-prefix": "Haetaan vain sivuista, joiden otsikko alkaa \"$1\"",
+       "search-filter-title-prefix-reset": "Hae kaikista sivuista",
        "searchresults-title": "Haun tulokset hakusanalle ”$1”",
        "titlematches": "Osumat sivujen otsikoissa",
        "textmatches": "Osumat sivujen teksteissä",
        "prefs-watchlist-edits": "Tarkkailulistalla näytettävien muokkausten enimmäismäärä:",
        "prefs-watchlist-edits-max": "Enintään 1000",
        "prefs-watchlist-token": "Tarkkailulistan avain:",
+       "prefs-watchlist-managetokens": "Hallitse avaimia",
        "prefs-misc": "Muut",
        "prefs-resetpass": "Muuta salasana",
        "prefs-changeemail": "Muuta tai poista sähköpostiosoite",
        "stub-threshold": "Tynkälinkkien muotoilun kynnysarvo ($1):",
        "stub-threshold-sample-link": "näyte",
        "stub-threshold-disabled": "Ei käytössä",
-       "recentchangesdays": "Näytettävien päivien määrä tuoreissa&nbsp;muutoksissa",
+       "recentchangesdays": "Näytettävien päivien määrä tuoreissa&nbsp;muutoksissa:",
        "recentchangesdays-max": "Enintään $1 {{PLURAL:$1|päivä|päivää}}",
-       "recentchangescount": "Näytettävien muutoksien määrä tuoreissa muutoksissa, sivujen historioissa ja logeissa oletuksena",
+       "recentchangescount": "Näytettävien muutoksien määrä tuoreissa muutoksissa, sivuhistorioissa ja lokeissa oletusarvoisesti:",
        "prefs-help-recentchangescount": "Maksimiluku 1000",
        "prefs-help-watchlist-token2": "Tämä on salainen avain tarkkailulistasi verkkosyötteeseen.\nKuka tahansa, joka tietää sen voi lukea tarkkailulistaasi, joten älä paljasta sitä.\nJos sinun täytyy, [[Special:ResetTokens|voit uudistaa sen]].",
+       "prefs-help-tokenmanagement": "Voit nähdä ja nollata tilisi salaisen avaimen, jota käyttämällä pääset katsomaan tarkastuslistasi verkkosyötettä. Kuka tahansa sen tietävä voi lukea tarkkailulistaasi, joten älä paljasta sitä.",
        "savedprefs": "Asetuksesi on tallennettu.",
        "savedrights": "Käyttäjän {{GENDER:$1|$1}} käyttäjäryhmät on tallennettu.",
        "timezonelegend": "Aikavyöhyke",
        "prefs-editor": "Muokkain",
        "prefs-preview": "Esikatselu",
        "prefs-advancedrc": "Lisäasetukset",
+       "prefs-opt-out": "Jättäydy pois uudistuksista",
        "prefs-advancedrendering": "Lisäasetukset",
        "prefs-advancedsearchoptions": "Lisäasetukset",
        "prefs-advancedwatchlist": "Lisäasetukset",
        "userrights-expiry-options": "1 päivä:1 day,1 viikko:1 week,1 kuukausi:1 month,3 kuukautta:3 months,6 kuukautta:6 months,1 vuosi:1 year",
        "userrights-invalid-expiry": "Ryhmän \"$1\" vanhentumisaika on virheellinen.",
        "userrights-expiry-in-past": "Ryhmän \"$1\" vanhentumisaika on mennyt.",
+       "userrights-cannot-shorten-expiry": "Et voi aikaistaa ryhmän \"$1\" jäsenyyden erääntymisaikoja. Vain käyttäjät, joilla on oikeus lisätä ja poistaa ryhmiä, voivat aikaistaa erääntymisaikoja.",
        "userrights-conflict": "Päällekkäinen käyttöoikeuksien muutos! Tarkista tekemäsi muutokset ja vahvista ne.",
        "group": "Ryhmä",
        "group-user": "käyttäjät",
        "group-autoconfirmed": "automaattisesti hyväksytyt käyttäjät",
        "group-bot": "botit",
        "group-sysop": "ylläpitäjät",
+       "group-interface-admin": "käyttöliittymän ylläpitäjät",
        "group-bureaucrat": "byrokraatit",
        "group-suppress": "häivyttäjät (suppressors)",
        "group-all": "(kaikki)",
        "group-autoconfirmed-member": "{{GENDER:$1|automaattisesti hyväksytty käyttäjä}}",
        "group-bot-member": "{{GENDER:$1|botti}}",
        "group-sysop-member": "{{GENDER:$1|ylläpitäjä}}",
+       "group-interface-admin-member": "{{GENDER:$1|käyttöliittymän ylläpitäjä}}",
        "group-bureaucrat-member": "{{GENDER:$1|byrokraatti}}",
        "group-suppress-member": "{{GENDER:$1|häivyttäjä (suppressor)}}",
        "grouppage-user": "{{ns:project}}:Käyttäjät",
        "grouppage-autoconfirmed": "{{ns:project}}:Automaattisesti hyväksytyt käyttäjät",
        "grouppage-bot": "{{ns:project}}:Botit",
        "grouppage-sysop": "{{ns:project}}:Ylläpitäjät",
+       "grouppage-interface-admin": "{{ns:project}}:Käyttöliittymän ylläpitäjät",
        "grouppage-bureaucrat": "{{ns:project}}:Byrokraatit",
        "grouppage-suppress": "{{ns:project}}:Häivytysoikeudet",
        "right-read": "Lukea sivuja",
        "right-editcontentmodel": "Muokata sivun sisältömallia (content model)",
        "right-editinterface": "Muokata käyttöliittymätekstejä",
        "right-editusercss": "Muokata toisten käyttäjien CSS-tiedostoja",
-       "right-edituserjson": "Muokkaa toisten käyttäjien JSON-tiedostoja",
+       "right-edituserjson": "Muokata toisten käyttäjien JSON-tiedostoja",
        "right-edituserjs": "Muokata toisten käyttäjien JavaScript-tiedostoja",
+       "right-editsitecss": "muokata CSS-koodia koko sivustolla",
+       "right-editsitejson": "muokata JSON-koodia koko sivustolla",
+       "right-editsitejs": "muokata JavaScriptiä koko sivustolla",
        "right-editmyusercss": "Muokata omia CSS-tiedostoja",
        "right-editmyuserjson": "Muokkaa omia JSON-tiedostoja",
        "right-editmyuserjs": "Muokata omia JavaScript-tiedostoja",
        "grant-createaccount": "Luoda käyttäjätunnuksia",
        "grant-createeditmovepage": "Luoda, muokata ja siirtää sivuja",
        "grant-delete": "Poistaa sivuja, yksittäisiä versioita ja lokimerkintöjä",
-       "grant-editinterface": "Muokata järjestelmäviesti-nimiavaruutta ja käyttäjien CSS/JSON/JavaScript-sivuja",
+       "grant-editinterface": "Muokata järjestelmäviesti-nimiavaruutta sekä CSS-/JSON-/JavaScript-sivuja sivustonlaajuisesti ja myös käyttäjäkohtaisesti",
        "grant-editmycssjs": "Muokata käyttäjän omia CSS/JSON/JavaScript-sivuja",
        "grant-editmyoptions": "Muokata käyttäjän omia asetuksia",
        "grant-editmywatchlist": "Muokata tarkkailulistaasi",
+       "grant-editsiteconfig": "muokata CSS-/JS-sivuja sivustonlaajuisesti ja käyttäjäkohtaisesti",
        "grant-editpage": "Muokata olemassa olevia sivuja",
        "grant-editprotected": "Muokata suojattuja sivuja",
        "grant-highvolume": "Suorittaa paljon muokkauksia",
        "grant-viewdeleted": "Nähdä poistettuja sivuja ja tiedostoja",
        "grant-viewmywatchlist": "Nähdä oma tarkkailulista",
        "grant-viewrestrictedlogs": "Nähdä rajoitettuja lokimerkintöjä",
-       "newuserlogpage": "Uudet käyttäjät",
+       "newuserlogpage": "Tunnusten luonnin loki",
        "newuserlogpagetext": "Tämä on loki luoduista käyttäjätunnuksista.",
        "rightslog": "Käyttöoikeusloki",
        "rightslogtext": "Tämä on loki käyttäjien käyttöoikeuksien muutoksista.",
        "rcfilters-other-review-tools": "Muut arviointityökalut",
        "rcfilters-group-results-by-page": "Ryhmitä tulokset sivujen mukaan",
        "rcfilters-activefilters": "Aktiiviset suodattimet",
+       "rcfilters-activefilters-hide": "Piilota",
+       "rcfilters-activefilters-show": "Näytä",
+       "rcfilters-activefilters-hide-tooltip": "Piilota Aktiiviset suodattimet -alue",
+       "rcfilters-activefilters-show-tooltip": "Näytä Aktiiviset suodattimet -alue",
        "rcfilters-advancedfilters": "Kehittyneet suodattimet",
        "rcfilters-limit-title": "Näytettävät tulokset",
        "rcfilters-limit-and-date-label": "$1 {{PLURAL:$1|muutos|muutosta}}, $2",
        "rcfilters-empty-filter": "Ei aktiivisia suodattimia. Kaikki muutokset näytetään.",
        "rcfilters-filterlist-title": "Suodattimet",
        "rcfilters-filterlist-whatsthis": "Miten nämä toimivat?",
-       "rcfilters-filterlist-feedbacklink": "Kerro mielipiteesi (uusista) suodattimista",
+       "rcfilters-filterlist-feedbacklink": "Kerro mielipiteesi näistä suodatintyökaluista",
        "rcfilters-highlightbutton-title": "Korosta tulokset",
        "rcfilters-highlightmenu-title": "Valitse väri",
        "rcfilters-highlightmenu-help": "Valitse korostusväri tälle ominaisuudelle",
        "rcfilters-watchlist-showupdated": "Muutokset sivuihin, joilla et ole vieraillut sen jälkeen kun muutokset on tehty, on <strong>lihavoitu</strong> ja värimerkitty.",
        "rcfilters-preference-label": "Piilota tuoreiden muutosten parannettu versio",
        "rcfilters-preference-help": "Peruuttaa vuoden 2017 käyttöliittymän uudistuksen ja kaikki sen jälkeen lisätyt työkalut.",
+       "rcfilters-watchlist-preference-label": "Piilota tarkkailulistan parannettu versio",
+       "rcfilters-watchlist-preference-help": "Poistaa käytöstä vuoden 2017 ulkoasun uudistuksen ja kaikki sen jälkeen lisätyt työkalut.",
+       "rcfilters-filter-showlinkedfrom-label": "Näytä muutokset sivuilla, jonne on linkki sivulta",
+       "rcfilters-filter-showlinkedfrom-option-label": "<strong>Sivut, joihin linkitetään</strong> valitulta sivulta",
+       "rcfilters-filter-showlinkedto-label": "Näytä muutokset sivuilla, joista on linkki sivulle",
+       "rcfilters-filter-showlinkedto-option-label": "<strong>Sivut, jotka linkittävät</strong> valitulle sivulle",
        "rcfilters-target-page-placeholder": "Anna sivun nimi (tai luokka)",
        "rcnotefrom": "Alla ovat muutokset <strong>$3, $4</strong> lähtien. (Enintään <strong>$1</strong> näytetään.)",
        "rclistfromreset": "Tyhjennä ajankohdan valinta",
        "upload-http-error": "HTTP-virhe: $1",
        "upload-copy-upload-invalid-domain": "Tiedostojen tallentamista tästä verkko-osoitteesta ei ole sallittu.",
        "upload-foreign-cant-upload": "Tätä wikiä ei ole konfiguroitu tallentamaan tiedostoja pyydettyyn ulkoiseen tiedostovarastoon.",
+       "upload-foreign-cant-load-config": "Ulkoisen tietovaraston tiedostotallennusten asetusten lataus epäonnistui.",
+       "upload-dialog-disabled": "Tätä lomaketta käyttävät tiedostojen tallennukset ovat poistettu käytöstä tästä wikistä.",
        "upload-dialog-title": "Tiedoston tallennus",
        "upload-dialog-button-cancel": "Peru",
        "upload-dialog-button-back": "Takaisin",
        "uploadstash-errclear": "Tiedostojen tyhjentäminen epäonnistui.",
        "uploadstash-refresh": "Päivitä tiedostoluettelo",
        "uploadstash-thumbnail": "näytä pienoiskuva",
+       "uploadstash-exception": "Tiedostoa ei kyetty säilömään latausmuistiin ($1): \"$2\"",
        "uploadstash-bad-path": "\nPolkua ei ole.",
        "uploadstash-bad-path-invalid": "Polku ei kelpaa.",
        "uploadstash-bad-path-unknown-type": "Tuntematon tyyppi \"$1\".",
+       "uploadstash-bad-path-unrecognized-thumb-name": "Tunnistamaton pienoiskuvan nimi.",
+       "uploadstash-bad-path-no-handler": "Tiedoston $2 MIME-tyypille $1 ei löytynyt käsittelijää.",
        "uploadstash-bad-path-bad-format": "Avain \"$1\" ei ole sopivassa muodossa.",
        "uploadstash-file-not-found": "Avainta \"$1\" ei löytynyt kätköstä.",
+       "uploadstash-file-not-found-no-thumb": "Pienoiskuvaa ei voitu saada.",
+       "uploadstash-file-not-found-no-local-path": "Skaalatulla kohteella ei ole paikallista polkua.",
        "uploadstash-file-not-found-no-object": "Ei voitu luoda paikallista tiedostokohdetta pienoiskuvalle.",
+       "uploadstash-file-not-found-no-remote-thumb": "Pienoiskuvan haku epäonnistui: $1\nURL = $2",
        "uploadstash-file-not-found-missing-content-type": "Puuttuva sisältötyypin ylätunniste",
+       "uploadstash-file-not-found-not-exists": "Polkua ei löytynyt, tai ei selkotiedosto.",
+       "uploadstash-file-too-large": "Yli $1 tavun kokoista tiedostoa ei voida käsitellä.",
        "uploadstash-not-logged-in": "Käyttäjää ei ole kirjautunut sisään, tiedostojen on kuuluttava käyttäjille.",
        "uploadstash-wrong-owner": "Tämä tiedosto ($1) ei kuulu nykyiselle käyttäjälle.",
        "uploadstash-no-such-key": "Ei tälläistä avainta ($1), ei voi poistaa.",
        "http-timed-out": "HTTP-pyyntö aikakatkaistiin.",
        "http-curl-error": "Virhe noudettaessa verkko-osoitetta: $1",
        "http-bad-status": "HTTP-pyynnön aikana oli ongelma: $1 $2",
+       "http-internal-error": "HTTP: sisäinen virhe.",
        "upload-curl-error6": "Toimimaton osoite",
        "upload-curl-error6-text": "Antamaasi osoitteeseen ei saatu yhteyttä. Varmista, että osoite on oikein ja että sivusto on saavutettavissa.",
        "upload-curl-error28": "Etälähetyksen aikakatkaisu",
        "uploadnewversion-linktext": "Tallenna uusi versio tästä tiedostosta",
        "shared-repo-from": "kohteesta $1",
        "shared-repo": "yhteinen mediavarasto",
+       "filepage.css": "/* Tänne syötetty CSS-koodi sisältyy tiedoston kuvaussivulle sekä muunkielisille asiakaswikeille */",
        "upload-disallowed-here": "Et voi tallentaa uutta tiedostoa tämän tilalle.",
        "filerevert": "Tiedoston $1 palautus",
        "filerevert-legend": "Tiedoston palautus",
        "uncategorizedcategories": "Luokittelemattomat luokat",
        "uncategorizedimages": "Luokittelemattomat tiedostot",
        "uncategorizedtemplates": "Luokittelemattomat mallineet",
+       "uncategorized-categories-exceptionlist": "# Sisältää luettelon luokkia, joita ei tulisi mainita Special:UncategorizedCategories-sivulla. Yksi riviä kohden, alkaen \"*\"-merkillä. Muilla merkeillä alkavat rivit jätetään huomiotta. Käytä \"#\"-merkkiä kommenttien kirjoittamiseen.",
        "unusedcategories": "Käyttämättömät luokat",
        "unusedimages": "Käyttämättömät tiedostot",
        "wantedcategories": "Halutut luokat",
        "protectedtitles-summary": "Tällä sivulla on lueteltu ne sivut, jotka on tällä hetkellä suojattu uudelleenluonnilta. Nähdäksesi luettelon olemassaolevista suojatuista sivuista katso [[{{#special:ProtectedPages}}|{{int:protectedpages}}]].",
        "protectedtitlesempty": "Ei suojattuja sivunimiä näillä hakuehdoilla.",
        "protectedtitles-submit": "Hae sivunimet",
-       "listusers": "Käyttäjien luettelo",
+       "listusers": "Käyttäjäluettelo",
        "listusers-editsonly": "Näytä vain käyttäjät, joilla on muokkauksia",
        "listusers-temporarygroupsonly": "Näytä vain väliaikaisten käyttäjäryhmien käyttäjät",
        "listusers-creationsort": "Lajittele tunnuksen luontipäivämäärän mukaan",
        "apisandbox-dynamic-parameters-add-label": "Lisää parametri:",
        "apisandbox-dynamic-parameters-add-placeholder": "Parametrin nimi",
        "apisandbox-dynamic-error-exists": "Parametri nimellä ”$1” on jo olemassa.",
+       "apisandbox-templated-parameter-reason": "Tämä [[Special:ApiHelp/main#main/templatedparams|mallineparametri]] tarjotaan kohteen $2 {{PLURAL:$1|arvon|arvojen}} pohjalta.",
        "apisandbox-deprecated-parameters": "Käytöstä poistuneet parametrit",
        "apisandbox-fetch-token": "Lisää token automaattisesti",
        "apisandbox-add-multi": "Lisää",
        "apisandbox-sending-request": "API-pyyntöä lähetetään...",
        "apisandbox-loading-results": "API-tuloksia vastaanotetaan...",
        "apisandbox-results-error": "Tapahtui virhe ladattaessa API-kyselyn vastausta: $1",
+       "apisandbox-results-login-suppressed": "Tämä pyyntö on käsitelty uloskirjautuneena käyttäjänä, sillä sitä voitaisiin käyttää selaimen Same-Origin-turvakeinon kiertämiseen. Huomioi, että API:n hiekkalaatikon automaattinen avaimen käsittely ei toimi oikein tämänkaltaisen pyyntöjen kanssa, joten sinun tulee täyttää ne käsin.",
+       "apisandbox-request-selectformat-label": "Näytä pyyntödata muodossa:",
        "apisandbox-request-format-url-label": "URL-kyselymerkkijono",
        "apisandbox-request-url-label": "Pyynnön URL",
        "apisandbox-request-json-label": "Pyydetty JSON:",
        "apisandbox-request-time": "Pyyntöön kulunut aika: {{PLURAL:$1|$1 ms}}",
        "apisandbox-results-fixtoken": "Korjaa \"token\" ja lähetä uudelleen",
+       "apisandbox-results-fixtoken-fail": "\"$1\"-avaimen haku epäonnistui.",
        "apisandbox-alert-page": "Tällä sivulla olevat kentät eivät ole kelvollisia.",
        "apisandbox-alert-field": "Tässä kentässä oleva arvo ei ole kelvollinen.",
        "apisandbox-continue": "Jatka",
        "apisandbox-continue-clear": "Tyhjennä",
+       "apisandbox-continue-help": "{{int:apisandbox-continue}} [https://www.mediawiki.org/wiki/API:Query#Continuing_queries jatkaa] viimeistä pyyntöä; {{int:apisandbox-continue-clear}} nollaa jatkamisparametrit.",
        "apisandbox-param-limit": "Kirjoita <kbd>max</kbd> käyttääksesi ylärajaa.",
        "apisandbox-multivalue-all-namespaces": "$1 (Kaikki nimiavaruudet)",
        "apisandbox-multivalue-all-values": "$1 (Kaikki arvot)",
        "speciallogtitlelabel": "Kohde (sivu tai {{ns:user}}:käyttäjänimi):",
        "log": "Lokit",
        "logeventslist-submit": "Näytä",
+       "logeventslist-more-filters": "Näytä lisää lokeja:",
+       "logeventslist-patrol-log": "Partiointiloki",
+       "logeventslist-tag-log": "Merkkausloki",
        "all-logs-page": "Kaikki julkiset lokit",
        "alllogstext": "Tämä on yhdistetty lokien näyttö.\nVoit rajoittaa listaa valitsemalla lokityypin, käyttäjän tai sivun johon muutos on kohdistunut. Jälkimmäiset ovat kirjainkokoherkkiä.",
        "logempty": "Ei tapahtumia lokissa.",
        "listgrouprights-namespaceprotection-namespace": "Nimiavaruus",
        "listgrouprights-namespaceprotection-restrictedto": "Käyttäjän muokkausoikeudet",
        "listgrants": "Toimintaoikeudet",
+       "listgrants-summary": "Alla on luettelo toimintaoikeuksista sekä niiden vastaavista pääsytavoista käyttäjäoikeuksiin. Käyttäjät voivat valtuuttaa sovelluksia käyttämään heidän tiliään rajoitetuin oikeuksien riippuen toimintaoikeuksista, jota käyttäjä on sovellukselle myöntänyt. Käyttäjän puolesta toimiva sovellus ei kuitenkaan voi käyttää oikeuksia, joita käyttäjällä ei ole.\nYksittäisistä oikeuksista saattaa olla saatavilla [[{{MediaWiki:Listgrouprights-helppage}}|lisätietoa]].",
        "listgrants-grant": "Toimintaoikeus (grant)",
        "listgrants-rights": "Oikeudet (rights)",
        "trackingcategories": "Tarkkailuluokat",
        "notvisiblerev": "Versio on poistettu",
        "watchlist-details": "Tarkkailulistallasi on {{PLURAL:$1|$1 sivu|$1 sivua}} (keskustelusivut mukaan lukien).",
        "wlheader-enotif": "Sähköposti-ilmoitus on käytössä.",
-       "wlheader-showupdated": "Sivut, joita on muokattu viimeisen käyntisi jälkeen, on '''lihavoitu'''.",
+       "wlheader-showupdated": "Sivut, joita on muokattu viimeisen käyntisi jälkeen, on <strong>lihavoitu</strong>.",
        "wlnote": "Alla {{PLURAL:$1|on viimeisin muutos|ovat viimeisimmät <strong>$1</strong> muutosta}} edellisen {{PLURAL:$2|tunnin|<strong>$2</strong> tunnin}} ajalta $3 kello $4 lukien.",
        "wlshowlast": "Näytä edelliset $1 tuntia tai $2 päivää",
        "watchlist-hide": "Piilota",
        "dellogpage": "Poistoloki",
        "dellogpagetext": "Alla on loki viimeisimmistä poistoista.",
        "deletionlog": "poistoloki",
+       "log-name-create": "Sivujen luonnin loki",
+       "log-description-create": "Alla on luettelo viimeisimmistä sivujen luonneista.",
+       "logentry-create-create": "$1 {{GENDER:$2|loi}} sivun $3",
        "reverted": "Palautettu aikaisempaan versioon",
        "deletecomment": "Syy:",
        "deleteotherreason": "Muu syy tai tarkennus:",
        "changecontentmodel-nodirectediting": "Sisältömalli $1 ei tue suoraa muokkaamista",
        "changecontentmodel-emptymodels-title": "Mitään sisältömallia ei ole saatavilla",
        "changecontentmodel-emptymodels-text": "Sisältöä sivulla [[:$1]] ei voida muuntaa mihinkään muotoon.",
-       "log-name-contentmodel": "Sisältömallin muutosloki",
+       "log-name-contentmodel": "Sisältömallin muutosten loki",
        "log-description-contentmodel": "Tällä sivulla on lueteltu muutokset sivujen sisältömalliin, ja sivut, jotka on luotu muulla kuin oletussisältömallilla.",
        "logentry-contentmodel-new": "$1 {{GENDER:$2|loi}} sivun $3 käyttäen normaalista poikkeavaa sisältömallia \"$5\"",
        "logentry-contentmodel-change": "$1 {{GENDER:$2|muutti}} sivun $3 sisältömallia muodosta \"$4\" muotoon \"$5\"",
        "contributions-userdoesnotexist": "Käyttäjätunnusta ”$1” ei ole rekisteröity.",
        "nocontribs": "Näihin ehtoihin sopivia muokkauksia ei löytynyt.",
        "uctop": "(uusin)",
-       "month": "Kuukausi",
+       "month": "Alkaen kuukaudesta (ja aiemmin):",
        "year": "Vuosi",
+       "date": "Alkaen päivämäärästä (tai sitä aikaisemmasta):",
        "sp-contributions-newbies": "Näytä uusien tulokkaiden muutokset",
        "sp-contributions-newbies-sub": "Uusien käyttäjien muokkaukset",
        "sp-contributions-newbies-title": "Uusien käyttäjien muokkaukset",
        "whatlinkshere": "Tänne viittaavat sivut",
        "whatlinkshere-title": "Sivut, jotka viittaavat sivulle $1",
        "whatlinkshere-page": "Sivu:",
-       "linkshere-2": "Seuraavilta sivuilta on linkki sivulle <strong>$1</strong>:",
-       "nolinkshere-2": "Sivulle <strong>$1</strong> ei ole linkkejä.",
-       "nolinkshere-ns-2": "Sivulle <strong>$1</strong> ei ole linkkejä valitussa nimiavaruudessa.",
+       "linkshere": "Seuraavilta sivuilta on linkki sivulle <strong>$2</strong>:",
+       "nolinkshere": "Sivulle <strong>$2</strong> ei ole linkkejä.",
+       "nolinkshere-ns": "Sivulle <strong>$2</strong> ei ole linkkejä valitussa nimiavaruudessa.",
        "isredirect": "ohjaussivu",
        "istemplate": "sisällytetty",
        "isimage": "tiedostolinkki",
        "import-mapping-subpage": "Tuonti seuraavan sivun alasivuiksi:",
        "import-upload-filename": "Tiedostonimi:",
        "import-upload-username-prefix": "Interwiki-etuliite:",
+       "import-assign-known-users": "Siirrä muokkaukset paikallisille käyttäjille, jos samanniminen käyttäjä on paikallisesti olemassa",
        "import-comment": "Kommentti:",
        "importtext": "Vie sivuja lähdewikistä käyttäen [[Special:Export|vientityökalua]].\nTallenna tiedot koneellesi ja tuo ne tällä sivulla.",
        "importstart": "Tuodaan sivuja...",
        "tooltip-pt-watchlist": "Lista sivuista, joiden muokkauksia tarkkailet",
        "tooltip-pt-mycontris": "Luettelo {{GENDER:|omista muokkauksistasi}}",
        "tooltip-pt-anoncontribs": "Luettelo tästä IP-osoitteesta tehdyistä muokkauksista",
-       "tooltip-pt-login": "Kirjaudu sisään tai luo tunnus",
+       "tooltip-pt-login": "On suositeltavaa kirjautua sisään. Se ei kuitenkaan ole pakollista.",
        "tooltip-pt-login-private": "Tämän wikin käyttö edellyttää kirjautumista",
        "tooltip-pt-logout": "Kirjaudu ulos",
        "tooltip-pt-createaccount": "On suositeltavaa luoda käyttäjätunnus ja kirjautua sisään. Se ei kuitenkaan ole pakollista.",
        "group-bot.css": "/* Tämä sivun tyylit muuttavat bottien tyylejä */",
        "group-sysop.css": "/* Tämä sivun tyylit muuttavat ylläpitäjien tyylejä */",
        "group-bureaucrat.css": "/* Tämä sivun tyylit muuttavat byrokraattien tyylejä */",
+       "common.json": "/* Tämän sivun JSON-koodi liitetään jokaiseen sivulataukseen */",
        "common.js": "/* Tämän sivun JavaScript-koodi liitetään jokaiseen sivulataukseen */",
        "group-autoconfirmed.js": "/* Tämän sivun JavaScript-koodi liitetään vain automaattisesti hyväksytyille käyttäjille */",
        "group-user.js": "/* Tämän sivun JavaScript ladataan vain rekisteröityneille käyttäjille */",
        "markedaspatrollederrornotify": "Tarkastetuksi merkitseminen epäonnistui.",
        "patrol-log-page": "Muutostentarkastusloki",
        "patrol-log-header": "Tämä on loki tarkastetuista muutoksista.",
-       "log-show-hide-patrol": "$1 muutostentarkastusloki",
-       "log-show-hide-tag": "$1 merkkausloki",
        "confirm-markpatrolled-button": "OK",
        "confirm-markpatrolled-top": "Merkitäänkö versio $3 kohdesivusta $2 partioiduksi?",
        "deletedrevision": "Poistettiin vanha versio $1",
        "exif-photometricinterpretation-1": "Mustavalkoinen (musta on 0)",
        "exif-photometricinterpretation-3": "Paletti",
        "exif-photometricinterpretation-4": "Läpinäkyvyysmaski",
+       "exif-photometricinterpretation-5": "Erotettu (luultavasti CMYK)",
        "exif-photometricinterpretation-9": "CIE L*a*b* (ICC-koodaus)",
        "exif-photometricinterpretation-10": "CIE L*a*b* (ITU-koodaus)",
        "exif-unknowndate": "Tuntematon päiväys",
        "version-entrypoints": "Aloituskohtien URL-osoitteet",
        "version-entrypoints-header-entrypoint": "Aloituskohta",
        "version-entrypoints-header-url": "URL",
+       "version-entrypoints-articlepath": "[https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgArticlePath Artikkelin polku]",
+       "version-entrypoints-scriptpath": "[https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgScriptPath Skriptin polku]",
        "version-libraries": "Asennetut kirjastot",
        "version-libraries-library": "Kirjasto",
        "version-libraries-version": "Versio",
        "blankpage": "Tyhjä sivu",
        "intentionallyblankpage": "Tämä sivu on tarkoituksellisesti tyhjä.",
        "external_image_whitelist": " #Älä muuta tätä riviä lainkaan.<pre>\n#Laita säännöllisten lausekkeiden palaset (vain osa, joka menee //-merkkien väliin) alle\n#Niitä verrataan ulkoisten (suoralinkitettyjen) kuvien URLeihin\n#Ne jotka sopivat, näytetään kuvina, muutoin kuviin näytetään vain linkit\n#Rivit, jotka alkavat #-merkillä ovat kommentteja\n#Tämä on riippumaton kirjainkoosta\n\n#Laita kaikki säännöllisten lausekkeiden palaset tämän rivit yläpuolelle. Älä muuta tätä riviä lainkaan</pre>",
-       "tags": "Voimassa olevat muutosmerkinnät",
+       "tags": "Voimassa olevat muutosten merkkaukset",
        "tag-filter": "[[Special:Tags|Merkkausten]] suodatin:",
        "tag-filter-submit": "Suodata",
        "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|Merkkaus|Merkkaukset}}]]: $2)",
        "mw-widgets-usersmultiselect-placeholder": "Lisää enemmän...",
        "date-range-from": "Aloituspäivä:",
        "date-range-to": "Päättymispäivä:",
-       "sessionmanager-tie": "Cannot combine multiple request authentication types: $1.",
+       "sessionmanager-tie": "Monentyyppisiä kirjautumispyyntöjä ei voi yhdistää: $1.",
        "sessionprovider-generic": "$1 istuntoa",
        "sessionprovider-mediawiki-session-cookiesessionprovider": "istuntoja, joissa on evästeet käytössä",
        "sessionprovider-nocookies": "Evästeet on voitu poistaa käytöstä. Varmista, että sinulla on evästeet käytössä ja yritä sitten uudelleen.",
        "unlinkaccounts-success": "Tunnuksen linkitys poistettiin.",
        "authenticationdatachange-ignored": "Varmennustietojen muutosta ei käsitelty. Ehkä palveluntarjoajaa ei määritelty?",
        "userjsispublic": "Huomio: JavaScript-alasivuilla ei tulisi olla luottamuksellisia tietoja, koska muut käyttäjät voivat nähdä ne.",
+       "userjsonispublic": "Huomio: JSON-alasivuilla ei tulisi olla luottamuksellisia tietoja, koska muut käyttäjät voivat nähdä ne.",
        "usercssispublic": "Huomio: CSS-alasivuilla ei tulisi olla luottamuksellisia tietoja, koska muut käyttäjät voivat nähdä ne.",
        "restrictionsfield-badip": "Virheellinen IP-osoite tai alue: $1",
        "restrictionsfield-label": "Sallitut IP-alueet:",
        "undelete-cantedit": "Et voi palauttaa tätä sivua, koska sinulla ei ole oikeutta muokata tätä sivua.",
        "undelete-cantcreate": "Et voi palauttaa tätä sivua, koska tällä nimellä ei ole olemassaolevaa sivua eikä sinulla ole oikeutta luoda tätä sivua.",
        "pagedata-title": "Sivudata",
+       "pagedata-text": "Tämä sivu tarjoaa datarajapinnan sivuihin. Syötä sivun otsikko URL-osoitteeseen käyttäen alasivusyntaksia.\n* Automaattisen kielivalinnan toiminta riippuu asiakasohjelman Accept-otsikkotiedosta. Tämä tarkoittaa sitä, että asiakasohjelma saa sivun tiedot haluamassaan muodossa.",
        "pagedata-not-acceptable": "Vastaavaa muotoa ei löytynyt. Tuetut MIME-tyypit: $1",
        "pagedata-bad-title": "Virheellinen otsikko: $1.",
+       "unregistered-user-config": "Turvallisuussyistä JavaScript-, CSS- ja JSON-käyttäjäalasivuja ei voi ladata rekisteröimättömiltä käyttäjiltä.",
        "passwordpolicies": "Salasanakäytännöt",
+       "passwordpolicies-summary": "Tämä on luettelo käytössä olevista salasanakäytännöistä tämän wikin käyttäjäryhmille.",
        "passwordpolicies-group": "Ryhmä",
        "passwordpolicies-policies": "Käytännöt",
        "passwordpolicies-policy-minimalpasswordlength": "Salasanan on oltava ainakin $1 {{PLURAL:$1|merkki|merkkiä}} pitkä",
+       "passwordpolicies-policy-minimumpasswordlengthtologin": "Salasanassa on oltava vähintään $1 {{PLURAL:$1|merkki|merkkiä}} pystyäksesi kirjautumaan",
        "passwordpolicies-policy-passwordcannotmatchusername": "Salasana ei voi olla sama kuin käyttäjänimi",
-       "passwordpolicies-policy-maximalpasswordlength": "Salasanan on oltava vähemmän kuin $1 {{PLURAL:$1|merkki|merkkiä}} pitkä"
+       "passwordpolicies-policy-passwordcannotmatchblacklist": "Salasana ei voi vastata mustalla listalla olevia salasanoja",
+       "passwordpolicies-policy-maximalpasswordlength": "Salasanan on oltava vähemmän kuin $1 {{PLURAL:$1|merkki|merkkiä}} pitkä",
+       "passwordpolicies-policy-passwordcannotbepopular": "Salasana ei voi olla {{PLURAL:$1|suosittu salasana|$1 suositun salasanan listalla}}"
 }
index 34b3a95..af388a4 100644 (file)
        "whatlinkshere": "Hvat slóðar higar",
        "whatlinkshere-title": "Síður sum slóða til \"$1\"",
        "whatlinkshere-page": "Síða:",
-       "linkshere-2": "Hesar síður slóða til '''$1''':",
-       "nolinkshere-2": "Ongar síður slóða til '''$1'''.",
-       "nolinkshere-ns-2": "Ongar síður slóða til '''$1''' í tí valda navnarúminum.",
+       "linkshere": "Hesar síður slóða til '''$2''':",
+       "nolinkshere": "Ongar síður slóða til '''$2'''.",
+       "nolinkshere-ns": "Ongar síður slóða til '''$2''' í tí valda navnarúminum.",
        "isredirect": "ávísingarsíða",
        "istemplate": "leggjast innan í",
        "isimage": "fílu slóð",
        "markedaspatrollederrornotify": "Tað miseydnaðist at merkja sum eftirkannað.",
        "patrol-log-page": "Eftirlitsloggur",
        "patrol-log-header": "Hetta er ein loggur yvir patruljeraðum síðuversjónum.",
-       "log-show-hide-patrol": "$1 patrulleringsloggur",
        "deletedrevision": "Slettaði gamla síðuversjón $1",
        "filedeleteerror-short": "Feilur hendi við sletting av fílu: $1",
        "previousdiff": "← Eldri broytingar",
index 80ee461..199787d 100644 (file)
                        "Vexthedorito",
                        "Djiboun",
                        "Pols12",
-                       "KATRINE1992"
+                       "KATRINE1992",
+                       "Friday83260",
+                       "Niridya",
+                       "Pamputt"
                ]
        },
        "tog-underline": "Soulignement des liens :",
        "nstab-user": "Page d’{{GENDER:{{ROOTPAGENAME}}|utilisateur|utilisatrice}}",
        "nstab-media": "Média",
        "nstab-special": "Page spéciale",
-       "nstab-project": "À propos",
+       "nstab-project": "Page de projet",
        "nstab-image": "Fichier",
        "nstab-mediawiki": "Message",
        "nstab-template": "Modèle",
        "customcssprotected": "Vous n’avez pas la permission de modifier cette feuille de style CSS, car elle contient les paramètres personnels d’un autre utilisateur.",
        "customjsonprotected": "Vous n’avez pas le droit de modifier cette page JSON parce qu’elle contient les paramètres personnels d’un autre utilisateur.",
        "customjsprotected": "Vous n’avez pas la permission de modifier cette page de JavaScript, car elle contient les paramètres personnels d’un autre utilisateur.",
+       "sitecssprotected": "Vous n’avez pas le droit de modifier cette page CSS parce que cela peut affecter tous les visiteurs",
+       "sitejsonprotected": "Vous n’avez pas le droit de modifier cette page JSON parce que cela peut affecter tous les visiteurs",
+       "sitejsprotected": "Vous n’avez pas le droit de modifier cette page JavaScript parce que cela peut affecter tous les visiteurs",
        "mycustomcssprotected": "Vous n’avez pas le droit de modifier cette page CSS.",
        "mycustomjsonprotected": "Vous n’avez pas le droit de modifier cette page JSON.",
        "mycustomjsprotected": "Vous n’avez pas le droit de modifier cette page JavaScript.",
        "password-login-forbidden": "L’utilisation de ce nom d’utilisateur ou de ce mot de passe a été interdite.",
        "mailmypassword": "Réinitialiser le mot de passe",
        "passwordremindertitle": "Nouveau mot de passe temporaire pour {{SITENAME}}",
-       "passwordremindertext": "Quelqu’un (depuis l’adresse IP $1) a demandé un nouveau mot de\npasse pour {{SITENAME}} ($4). Un mot de passe temporaire pour l’utilisateur\n« $2 » a été créé et est « $3 ». Si cela était votre intention,\nvous devrez vous connecter et choisir un nouveau mot de passe.\nVotre mot de passe temporaire expirera dans $5 jour{{PLURAL:$5||s}}.\n\nSi vous n’êtes pas l’auteur de cette demande, ou si vous vous souvenez à présent de\nvotre mot de passe et ne souhaitez plus en changer, vous pouvez ignorer ce message\net continuer à utiliser votre ancien mot de passe.",
+       "passwordremindertext": "Quelqu’un (depuis l’adresse IP $1) a demandé un nouveau mot de\npasse pour {{SITENAME}} ($4). Un mot de passe temporaire pour l’utilisateur\n« $2 » a été créé et est « $3 ». Si cela était votre intention,\nvous devrez vous connecter et choisir un nouveau mot de passe.\nVotre mot de passe temporaire expirera dans $5 jour{{PLURAL:$5||s}}.\n\nSi vous n’êtes pas l’auteur de cette demande, ou si vous vous avez retrouvé votre mot de passe et ne souhaitez plus en changer, vous pouvez ignorer ce message\net continuer à utiliser votre ancien mot de passe.",
        "noemail": "Aucune adresse de courriel n’a été enregistrée pour l’utilisat{{GENDER:$1|eur|rice}} « $1 ».",
        "noemailcreate": "Vous devez fournir une adresse de courriel valide",
        "passwordsent": "Un nouveau mot de passe a été envoyé à l’adresse de courriel de l’utilisat{{GENDER:$1|eur|rice}} « $1 ».\nVeuillez vous reconnecter après l’avoir reçu.",
        "resetpass-submit-loggedin": "Changer de mot de passe",
        "resetpass-submit-cancel": "Annuler",
        "resetpass-wrong-oldpass": "Mot de passe actuel ou temporaire invalide.\nVous avez peut-être déjà changé votre mot de passe ou demandé un nouveau mot de passe temporaire.",
-       "resetpass-recycled": "Veuillez réinitialiser votre mot de passe à quelque chose d’autre que l’actuel.",
+       "resetpass-recycled": "Veuillez modifier votre mot de passe avec autre chose que l’actuel.",
        "resetpass-temp-emailed": "Vous êtes connecté{{GENDER:||e}} avec un code temporaire fourni par courriel.\nPour terminer la connexion, vous devez fournir un nouveau mot de passe ici :",
        "resetpass-temp-password": "Mot de passe temporaire :",
        "resetpass-abort-generic": "La modification du mot de passe a été annulée par une extension.",
        "resetpass-expired": "Votre mot de passe a expiré. Veuillez en fournir un nouveau pour vous connecter.",
-       "resetpass-expired-soft": "Votre mot de passe a expiré, et doit être réinitialisé. Veuillez en choisir un nouveau maintenant ou cliquer sur « {{int:authprovider-resetpass-skip-label}} » pour le faire plus tard.",
-       "resetpass-validity-soft": "Votre mot de passe n’est pas valide : $1\n\nVeuillez choisir un nouveau mot de passe maintenant, ou cliquez sur « {{int:authprovider-resetpass-skip-label}} » pour le réinitialiser plus tard.",
+       "resetpass-expired-soft": "Votre mot de passe a expiré, et doit être modifié. Veuillez en choisir un nouveau maintenant ou cliquer sur « {{int:authprovider-resetpass-skip-label}} » pour le faire plus tard.",
+       "resetpass-validity-soft": "Votre mot de passe n’est pas valide : $1\n\nVeuillez choisir un nouveau mot de passe maintenant, ou cliquez sur « {{int:authprovider-resetpass-skip-label}} » pour le modifier plus tard.",
        "passwordreset": "Réinitialisation du mot de passe",
        "passwordreset-text-one": "Remplissez ce formulaire pour réinitialiser votre mot de passe.",
        "passwordreset-text-many": "{{PLURAL:$1|Remplissez un des champs pour recevoir un mot de passe temporaire par courriel.}}",
        "converter-manual-rule-error": "Erreur détectée dans la règle manuelle de conversion de langue",
        "undo-success": "Cette modification va être annulée.\nVeuillez vérifier les différences ci-dessous, puis publier l’annulation si c’est bien ce que vous voulez faire.",
        "undo-failure": "Cette modification ne peut pas être défaite : cela entrerait en conflit avec les modifications intermédiaires.",
+       "undo-main-slot-only": "La modification n'a pas pu être annulée car elle implique un contenu en dehors de la tranche principale.",
        "undo-norev": "La modification n’a pas pu être défaite parce qu’elle est inexistante ou qu’elle a été supprimée.",
        "undo-nochange": "Il semblerait que la modification ait déjà été annulée.",
        "undo-summary": "Annulation des modifications $1 de [[Special:Contributions/$2|$2]] ([[User talk:$2|discussion]])",
        "diff-paragraph-moved-toold": "Le paragraphe a été déplacé. Cliquez pour accéder à l'ancien emplacement.",
        "difference-missing-revision": "{{PLURAL:$2|Une révision|$2 révisions}} de cette différence ($1) {{PLURAL:$2|n’a pas été trouvée|n’ont pas été trouvées}}.\n\nCela survient en général en suivant un lien de différence désuet vers une page qui a été supprimée.\nVous pouvez trouver des détails dans le [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} journal des suppressions].",
        "searchresults": "Résultats de la recherche",
+       "search-filter-title-prefix": "Recherche seulement les pages dont le titre commence par « $1 »",
+       "search-filter-title-prefix-reset": "Rechercher toutes les pages",
        "searchresults-title": "Résultats de recherche pour « $1 »",
        "titlematches": "Correspondances dans les titres des pages",
        "textmatches": "Correspondances dans le texte des pages",
        "prevn-title": "$1 {{PLURAL:$1|résultat précédent|résultats précédents}}",
        "nextn-title": "$1 {{PLURAL:$1|résultat suivant|résultats suivants}}",
        "shown-title": "Afficher $1 résultat{{PLURAL:$1||s}} par page",
-       "viewprevnext": "Voir ($1 {{int:pipe-separator}} $2) ($3).",
+       "viewprevnext": "Voir ($1 {{int:pipe-separator}} $2) ($3)",
        "searchmenu-exists": "<strong>Il existe une page nommée « [[:$1]] » sur ce wiki.</strong> {{PLURAL:$2|0=|Voyez également les autres résultats de votre recherche.}}",
        "searchmenu-new": "<strong>Créer la page « [[:$1|$1]] » sur ce wiki !</strong> {{PLURAL:$2|0=Voyez également la page trouvée avec votre recherche.|Voyez également les résultats de votre recherche.}}",
        "searchprofile-articles": "Pages de contenu",
        "group-autoconfirmed": "Utilisateurs autoconfirmés",
        "group-bot": "Robots",
        "group-sysop": "Administrateurs",
+       "group-interface-admin": "Administrateurs d'interfaces",
        "group-bureaucrat": "Bureaucrates",
        "group-suppress": "Limitateurs",
        "group-all": "(tous)",
        "group-autoconfirmed-member": "{{GENDER:$1|utilisateur autoconfirmé|utilisatrice autoconfirmée}}",
        "group-bot-member": "{{GENDER:$1|robot}}",
        "group-sysop-member": "{{GENDER:$1|administrateur|administratrice}}",
+       "group-interface-admin-member": "{{GENDER:$1|administrateur d’interface}}",
        "group-bureaucrat-member": "{{GENDER:$1|bureaucrate}}",
        "group-suppress-member": "{{GENDER:$1|limitateur|limitatrice}}",
        "grouppage-user": "{{ns:project}}:Utilisateurs",
        "grouppage-autoconfirmed": "{{ns:project}}:Utilisateurs autoconfirmés",
        "grouppage-bot": "{{ns:project}}:Robots",
        "grouppage-sysop": "{{ns:project}}:Administrateurs",
+       "grouppage-interface-admin": "{{ns:project}}:Administrateurs d'interface",
        "grouppage-bureaucrat": "{{ns:project}}:Bureaucrates",
        "grouppage-suppress": "{{ns:project}}:Suppress",
        "right-read": "Lire les pages",
        "right-editusercss": "Modifier les fichiers CSS d'autres utilisateurs",
        "right-edituserjson": "Modifier les fichiers JSON d’un autre utilisateur",
        "right-edituserjs": "Modifier les fichiers JavaScript d'autres utilisateurs",
+       "right-editsitecss": "Modifier le CSS du site",
+       "right-editsitejson": "Modifier le JSON du site",
+       "right-editsitejs": "Modifier le JavaScript du site",
        "right-editmyusercss": "Modifier vos propres fichiers CSS utilisateur",
        "right-editmyuserjson": "Modifier vos propres fichiers utilisateur JSON",
        "right-editmyuserjs": "Modifier vos propres fichiers JavaScript utilisateur",
        "grant-createaccount": "Créer des comptes",
        "grant-createeditmovepage": "Créer, modifier et déplacer des pages",
        "grant-delete": "Supprimer les pages, les révisions et les entrées du journal",
-       "grant-editinterface": "Modifier l’espace de noms MediaWiki et le CSS/JSON/JavaScript utilisateur",
+       "grant-editinterface": "Modifier l’espace de noms MediaWiki et le JSON du site/utilisateur",
        "grant-editmycssjs": "Modifier votre CSS/JSON/JavaScript utilisateur",
        "grant-editmyoptions": "Modifier vos préférences utilisateur",
        "grant-editmywatchlist": "Modifier votre liste de suivi",
+       "grant-editsiteconfig": "Modifier les CSS/JS du site et ceux de l'utilisateur",
        "grant-editpage": "Modifier des pages existantes",
        "grant-editprotected": "Modifier des pages protégées",
        "grant-highvolume": "Modification de gros volumes",
        "recentchanges-legend-plusminus": "(''±123'')",
        "recentchanges-submit": "Lister",
        "rcfilters-tag-remove": "Supprimer « $1 »",
-       "rcfilters-legend-heading": "<strong>Liste des abréviations :</strong>",
+       "rcfilters-legend-heading": "<strong>Liste des abréviations : </strong>",
        "rcfilters-other-review-tools": "Autres outils de relecture",
        "rcfilters-group-results-by-page": "Grouper les résultats par page",
        "rcfilters-activefilters": "Filtres actifs",
+       "rcfilters-activefilters-hide": "Masquer",
+       "rcfilters-activefilters-show": "Afficher",
+       "rcfilters-activefilters-hide-tooltip": "Masquer la zone des Filtres actifs",
+       "rcfilters-activefilters-show-tooltip": "Afficher la zone des Filtres actifs",
        "rcfilters-advancedfilters": "Filtres avancés",
        "rcfilters-limit-title": "Résultats à afficher",
        "rcfilters-limit-and-date-label": "$1 modification{{PLURAL:$1||s}}, $2",
        "rcfilters-empty-filter": "Aucun filtre actif. Toutes les contributions sont affichées.",
        "rcfilters-filterlist-title": "Filtres",
        "rcfilters-filterlist-whatsthis": "Comment ça marche ?",
-       "rcfilters-filterlist-feedbacklink": "Nous dire ce que vous pensez de ces (nouveaux) outils de filtrage",
+       "rcfilters-filterlist-feedbacklink": "Dites nous ce que vous pensez de ces outils de filtrage",
        "rcfilters-highlightbutton-title": "Mettre en valeur les résultats",
        "rcfilters-highlightmenu-title": "Choisir une couleur",
        "rcfilters-highlightmenu-help": "Sélectionner une couleur pour mettre en évidence cette propriété",
        "rcfilters-watchlist-showupdated": "Les modifications faites aux pages que vous n’avez pas visitées depuis qu’elles ont été modifiées sont en <strong>gras</strong>, avec des puces pleines.",
        "rcfilters-preference-label": "Masquer la version améliorée des modifications récentes",
        "rcfilters-preference-help": "Désactive la version 2017 de l'interface ainsi que de tous les outils ajoutés alors et depuis.",
+       "rcfilters-watchlist-preference-label": "Masquer la version améliorée de la liste de suivi",
+       "rcfilters-watchlist-preference-help": "Annuler la nouvelle conception de l’interface 2017 et tous les outils ajoutés alors et depuis.",
        "rcfilters-filter-showlinkedfrom-label": "Montrer les modifications des pages liées depuis",
        "rcfilters-filter-showlinkedfrom-option-label": "<strong>Pages liées depuis</strong> la page sélectionnée",
        "rcfilters-filter-showlinkedto-label": "Montrer les modifications des pages pointant vers",
        "uploadstash-zero-length": "La taille du fichier est zéro.",
        "invalid-chunk-offset": "Offset de segment non valide",
        "img-auth-accessdenied": "Accès refusé",
-       "img-auth-nopathinfo": "PATH_INFO manquant.\nVotre serveur n’est pas paramétré pour transmettre cette information.\nIl fonctionne peut-être en CGI et ne prend pas en charge img_auth.\nVoir : https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization.",
+       "img-auth-nopathinfo": "Manque l'information de chemin.\nVotre serveur doit être paramétré pour transmettre la variable REQUEST_URI et/ou PATH_INFO .\nSi c'est le cas, essayez d'activer $wgUsePathInfo.\nVoir https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization.",
        "img-auth-notindir": "Le chemin demandé n'est pas le répertoire d'import configuré.",
        "img-auth-badtitle": "Impossible de construire un titre valide à partir de « $1 ».",
        "img-auth-nologinnWL": "Vous n'êtes pas connecté et « $1 » n'est pas dans la liste blanche.",
        "http-timed-out": "La requête HTTP a expiré.",
        "http-curl-error": "Erreur lors de la récupération de l'URL : $1",
        "http-bad-status": "Il y a eu un problème lors de la requête HTTP : $1 $2",
+       "http-internal-error": "Erreur interne HTTP.",
        "upload-curl-error6": "URL injoignable",
        "upload-curl-error6-text": "L’URL fournie ne peut pas être atteinte. \nVeuillez vérifier que l’URL est correcte et que le site est en ligne.",
        "upload-curl-error28": "Dépassement du délai lors de l'import",
        "speciallogtitlelabel": "Cible (titre ou {{ns:user}}:nom d'utilisateur) :",
        "log": "Journaux d’opérations",
        "logeventslist-submit": "Lister",
+       "logeventslist-more-filters": "Afficher des journaux supplémentaires :",
+       "logeventslist-patrol-log": "Journal des relectures",
+       "logeventslist-tag-log": "Journal des balises",
        "all-logs-page": "Tous les journaux publics",
        "alllogstext": "Affichage combiné de tous les journaux disponibles sur {{SITENAME}}.\nVous pouvez personnaliser l'affichage en sélectionnant le type de journal, le nom d'utilisateur ou la page concernée (ces deux derniers étant sensibles à la casse).",
        "logempty": "Aucune opération correspondante dans les journaux.",
        "dellogpage": "Journal des suppressions",
        "dellogpagetext": "Voici la liste des suppressions les plus récentes.",
        "deletionlog": "journal des suppressions",
+       "log-name-create": "Journal des créations de pages",
+       "log-description-create": "Ci-dessous, la liste des dernières créations de pages.",
+       "logentry-create-create": "$1 {{GENDER:$2|a créé}} la page $3",
        "reverted": "Version précédente rétablie",
        "deletecomment": "Motif :",
        "deleteotherreason": "Motif autre ou supplémentaire :",
        "uctop": "(actuelle)",
        "month": "À partir du mois (et précédents) :",
        "year": "À partir de l'année (et précédentes) :",
+       "date": "À partir du (et antérieurement) :",
        "sp-contributions-newbies": "Ne montrer que les contributions des nouveaux utilisateurs",
        "sp-contributions-newbies-sub": "Parmi les nouveaux comptes",
        "sp-contributions-newbies-title": "Contributions d'utilisateurs parmi les nouveaux comptes",
        "whatlinkshere": "Pages liées",
        "whatlinkshere-title": "Pages qui pointent vers « $1 »",
        "whatlinkshere-page": "Page :",
-       "linkshere-2": "Les pages ci-dessous contiennent un lien vers <strong>$1</strong> :",
-       "nolinkshere-2": "Aucune page ne contient de lien vers <strong>$1</strong>.",
-       "nolinkshere-ns-2": "Aucune page ne contient de lien vers <strong>$1</strong> dans l'espace de noms choisi.",
+       "linkshere": "Les pages ci-dessous contiennent un lien vers <strong>$2</strong> :",
+       "nolinkshere": "Aucune page ne contient de liens vers <strong>$2</strong>.",
+       "nolinkshere-ns": "Aucune page ne contient de liens vers <strong>$2</strong> dans l'espace de noms choisi.",
        "isredirect": "page de redirection",
        "istemplate": "inclusion",
        "isimage": "lien vers le fichier",
        "tooltip-t-contributions": "Voir la liste des contributions de {{GENDER:$1|cet utilisateur|cette utilisatrice}}",
        "tooltip-t-emailuser": "Envoyer un courriel à {{GENDER:$1|cet utilisateur|cette utilisatrice}}",
        "tooltip-t-info": "Plus d’information sur cette page",
-       "tooltip-t-upload": "Téléverser des fichiers",
+       "tooltip-t-upload": "Importer des fichiers",
        "tooltip-t-specialpages": "Liste de toutes les pages spéciales",
        "tooltip-t-print": "Version imprimable de cette page",
        "tooltip-t-permalink": "Adresse permanente de cette version de la page",
        "markedaspatrollederrornotify": "Échec du marquage de la modification comme relue.",
        "patrol-log-page": "Journal des relectures",
        "patrol-log-header": "Voici l’historique des versions relues.",
-       "log-show-hide-patrol": "$1 l’historique des relectures",
-       "log-show-hide-tag": "$1 le journal des balises",
        "confirm-markpatrolled-button": "Valider",
        "confirm-markpatrolled-top": "Marquer la révision $3 de $2 comme relue ?",
        "deletedrevision": "Ancienne version $1 supprimée",
        "version-specialpages": "Pages spéciales",
        "version-parserhooks": "Greffons de l'analyseur syntaxique",
        "version-variables": "Variables",
-       "version-editors": "Contributeurs",
+       "version-editors": "Éditeurs",
        "version-antispam": "Prévention du pollupostage",
        "version-other": "Divers",
        "version-mediahandlers": "Manipulateurs de médias",
        "passwordpolicies-policy-passwordcannotmatchusername": "Le mot de passe ne peut pas être le même que le nom d'utilisateur",
        "passwordpolicies-policy-passwordcannotmatchblacklist": "Les mots de passe ne peuvent pas être identiques à ceux qui sont dans la liste noire.",
        "passwordpolicies-policy-maximalpasswordlength": "Les mots de passe doivent avoir moins de $1 caractère{{PLURAL:$1||s}} de long",
-       "passwordpolicies-policy-passwordcannotbepopular": "Le mot de passe ne peut pas être {{PLURAL:$1|le mot de passe populaire|dans la liste des $1 mots de passe populaires}}"
+       "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}}",
+       "easydeflate-invaliddeflate": "Le contenu fourni n'est pas correctement développé"
 }
index 9607106..b10a3f6 100644 (file)
        "whatlinkshere": "Pâges liyêes",
        "whatlinkshere-title": "Pâges que pouentont vers « $1 »",
        "whatlinkshere-page": "Pâge :",
-       "linkshere-2": "Cetes pâges contegnont un lim de vers <strong>$1</strong> :",
-       "nolinkshere-2": "Niona pâge contint de lim de vers <strong>$1</strong>.",
-       "nolinkshere-ns-2": "Niona pâge contint de lim de vers <strong>$1</strong> dedens l’èspâço de noms chouèsi.",
+       "linkshere": "Cetes pâges contegnont un lim de vers <strong>$2</strong> :",
+       "nolinkshere": "Niona pâge contint de lim de vers <strong>$2</strong>.",
+       "nolinkshere-ns": "Niona pâge contint de lim de vers <strong>$2</strong> dedens l’èspâço de noms chouèsi.",
        "isredirect": "pâge de redirèccion",
        "istemplate": "transcllusion",
        "isimage": "lim de vers lo fichiér",
        "markedaspatrollederrornotify": "Falyita du marcâjo du changement coment gouardâ.",
        "patrol-log-page": "Jornâl de gouârda",
        "patrol-log-header": "Vê-que un jornâl de les vèrsions gouardâyes.",
-       "log-show-hide-patrol": "$1 lo jornâl de gouârda",
-       "log-show-hide-tag": "$1 lo jornâl de les balises",
        "deletedrevision": "Vielye vèrsion $1 suprimâye",
        "filedeleteerror-short": "Fôta pendent la suprèssion du fichiér : $1",
        "filedeleteerror-long": "Des fôtes sont étâyes rencontrâyes pendent la suprèssion du fichiér :\n\n$1",
index f4b889d..dffd28b 100644 (file)
@@ -12,7 +12,8 @@
                        "Macofe",
                        "Matma Rex",
                        "Nemo bis",
-                       "Fitoschido"
+                       "Fitoschido",
+                       "Tacsipacsi"
                ]
        },
        "tog-underline": "Ferwisangen onerstrik:",
        "category_header": "Sidjen uun kategorii \"$1\"",
        "subcategories": "Onerkategoriin",
        "category-media-header": "Meedien uun kategorii \"$1\"",
-       "category-empty": "\"Uun detdiar kategorii san uun uugenblak nian sidjen of meedien.\"",
+       "category-empty": "<em>Uun detdiar kategorii san uun uugenblak nian sidjen of meedien.</em>",
        "hidden-categories": "{{PLURAL:$1|Ferbürgen kategorii|Ferbürgen kategoriin}}",
        "hidden-category-category": "Ferbürgen kategoriin",
        "category-subcat-count": "{{PLURAL:$2|Detdiar kategorii hää ian onerkategorii.|Uun detdiar kategorii {{PLURAL:$1|stäänt ian onerkategorii|stun $1 onerkategoriin}} faan $2 uun't gehial.}}",
        "whatlinkshere": "Ferwisangen üüb detdiar sidj",
        "whatlinkshere-title": "Sidjen, diar üüb \"$1\" ferwise",
        "whatlinkshere-page": "Sidj:",
-       "linkshere-2": "Jodiar sidjen ferwise üüb '''„$1“''':",
-       "nolinkshere-2": "Nian sidj ferwiset üüb $1",
-       "nolinkshere-ns-2": "Nian sidj ferwiset üüb '''„$1“''' uun di ütjsoocht nöömrüm.",
+       "linkshere": "Jodiar sidjen ferwise üüb '''„$2“''':",
+       "nolinkshere": "Nian sidj ferwiset üüb $2",
+       "nolinkshere-ns": "Nian sidj ferwiset üüb '''„$2“''' uun di ütjsoocht nöömrüm.",
        "isredirect": "widjerfeerang",
        "istemplate": "iinbünjen föörlaagen",
        "isimage": "Dateilink",
        "markedaspatrollederrornotify": "Det werjuun küd ei üs kontroliaret kääntiakent wurd.",
        "patrol-log-page": "Kontrol-logbuk",
        "patrol-log-header": "Det as det kontrol-logbuk.",
-       "log-show-hide-patrol": "Kontrol-logbuk $1",
-       "log-show-hide-tag": "Markiarang-logbuk $1",
        "deletedrevision": "Ual werjuun $1 stregen",
        "filedeleteerror-short": "Bi't striken faan det datei $1 as wat skiaf gingen.",
        "filedeleteerror-long": "Bi't striken faan det datei as wat skiaf gingen:\n\n$1",
index 92e11bf..d4cc49e 100644 (file)
        "whatlinkshere": "Leams a cheste vôs",
        "whatlinkshere-title": "Pagjinis che a son leadis a \"$1\"",
        "whatlinkshere-page": "Pagjine:",
-       "linkshere-2": "Lis pagjinis ca sot a son leadis a '''$1''':",
-       "nolinkshere-2": "Nissune pagjine e à leams a '''$1'''.",
-       "nolinkshere-ns-2": "No son pagjine leadis a '''$1''' intal spazi dai nons sielt.",
+       "linkshere": "Lis pagjinis ca sot a son leadis a '''$2''':",
+       "nolinkshere": "Nissune pagjine e à leams a '''$2'''.",
+       "nolinkshere-ns": "No son pagjine leadis a '''$2''' intal spazi dai nons sielt.",
        "isredirect": "pagjine di reindirizament",
        "istemplate": "includude",
        "isimage": "leam a figure",
index 648cf63..79e62fe 100644 (file)
        "nav-login-createaccount": "Oanmelde",
        "logout": "Ofmelde",
        "userlogout": "Ofmelde",
-       "notloggedin": "Net oanmelde",
+       "notloggedin": "Net oanmeld",
        "userlogin-noaccount": "Hasto gjin akkount?",
        "userlogin-joinproject": "Meidwaan {{SITENAME}}",
        "createaccount": "Registrearje",
        "upload": "Bied triem oan",
        "uploadbtn": "Bied triem oan",
        "reuploaddesc": "Werom nei oanbied-side.",
-       "uploadnologin": "Net oanmelde",
+       "uploadnologin": "Net oanmeld",
        "uploadnologintext": "Jo moatte [[Special:UserLogin|oanmeld]] wêze om in triem oanbiede 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).",
        "whatlinkshere": "Wat is hjirmei keppele?",
        "whatlinkshere-title": "Siden dy't keppele binne mei \"$1\"",
        "whatlinkshere-page": "Side:",
-       "linkshere-2": "Dizze siden binne keppele oan '''$1''':",
-       "nolinkshere-2": "Der binne gjin siden oan '''$1''' keppele.",
-       "nolinkshere-ns-2": "Gjin siden yn de keazen nammeromte keppelje nei '''$1'''.",
+       "linkshere": "Dizze siden binne keppele oan '''$2''':",
+       "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",
index f59930b..703d080 100644 (file)
        "whatlinkshere": "Naisc leis an lch seo",
        "whatlinkshere-title": "Naisc le $1",
        "whatlinkshere-page": "Leathanach:",
-       "linkshere-2": "Tá nasc chuig '''$1''' ar na leathanaigh seo a leanas:",
-       "nolinkshere-2": "Níl leathanach ar bith ann a bhfuil nasc chuig '''$1''' air.",
-       "nolinkshere-ns-2": "Níl leathanach ar bith ann san ainmspás roghnaithe a bhfuil nasc chuig '''$1''' air.",
+       "linkshere": "Tá nasc chuig '''$2''' ar na leathanaigh seo a leanas:",
+       "nolinkshere": "Níl leathanach ar bith ann a bhfuil nasc chuig '''$2''' air.",
+       "nolinkshere-ns": "Níl leathanach ar bith ann san ainmspás roghnaithe a bhfuil nasc chuig '''$2''' air.",
        "isredirect": "Leathanach athsheolaidh",
        "istemplate": "iniamh",
        "isimage": "nasc comhad",
        "rcpatroldisabled": "Mhíchumasaíodh Patról na n-Athruithe is Déanaí",
        "rcpatroldisabledtext": "Tá an tréith Patról na n-Athruithe is Déanaí míchumasaithe faoi láthair.",
        "patrol-log-page": "Log phatról",
-       "log-show-hide-patrol": "$1 log phatról",
        "deletedrevision": "Scriosadh an seanleagan $1",
        "filedeleteerror-short": "Earráid comhad a scriosadh: $1",
        "previousdiff": "← Gabh chuig an difear roimhe seo",
index 00bf854..46e6617 100644 (file)
        "whatlinkshere": "Baalantılar sayfaa",
        "whatlinkshere-title": "$1 baalantısı olan sayfalar",
        "whatlinkshere-page": "Yaprak:",
-       "linkshere-2": "Buraya baalantısı var olan sayfalar '''$1''':",
-       "nolinkshere-2": "Yok buraya baalanan sayfa '''$1'''.",
+       "linkshere": "Buraya baalantısı var olan sayfalar '''$2''':",
+       "nolinkshere": "Yok buraya baalanan sayfa '''$2'''.",
        "isredirect": "yönnendirmäk sayfası",
        "istemplate": "eklemää",
        "isimage": "fayl baalantısı",
index 64ddae7..5830c58 100644 (file)
        "whatlinkshere": "有什哩连到个首",
        "whatlinkshere-title": "连到 $1 𠮶页面",
        "whatlinkshere-page": "页面:",
-       "linkshere-2": "下底𠮶页面链接到$1:",
-       "nolinkshere-2": "冇页面链接到$1。",
-       "nolinkshere-ns-2": "选正𠮶空间名内冇页面链接到$1。",
+       "linkshere": "下底𠮶页面链接到$2:",
+       "nolinkshere": "冇页面链接到$2。",
+       "nolinkshere-ns": "选正𠮶空间名内冇页面链接到$2。",
        "isredirect": "重定向页面",
        "istemplate": "含到",
        "isimage": "档案连结",
index 944d037..8ed0248 100644 (file)
        "whatlinkshere": "有什哩連到箇首",
        "whatlinkshere-title": "連到 $1 嗰頁面",
        "whatlinkshere-page": "頁面:",
-       "linkshere-2": "下底嗰頁面連結到$1:",
-       "nolinkshere-2": "冇頁面連結到$1。",
-       "nolinkshere-ns-2": "選正嗰空間名內冇頁面連結到$1。",
+       "linkshere": "下底嗰頁面連結到$2:",
+       "nolinkshere": "冇頁面連結到$2。",
+       "nolinkshere-ns": "選正嗰空間名內冇頁面連結到$2。",
        "isredirect": "重定向頁",
        "istemplate": "含到",
        "isimage": "檔案連結",
index 89f046e..a7eb5ab 100644 (file)
@@ -24,9 +24,9 @@
        "tog-minordefault": "Marké tout mo modifikasyon kou minò pa défo",
        "tog-previewontop": "Afiché prévizwalizasyon-an laro di zonn di modifikasyon",
        "tog-previewonfirst": "Afiché prévizwalizasyon-an lò di pronmyé modifikasyon",
-       "tog-enotifwatchlistpages": "Avèrti mo pa kouryé lò roun paj ou roun fiché di mo lis di swivi sa modifyé",
+       "tog-enotifwatchlistpages": "Avèrti mo pa kouryé lòské roun paj oben roun fiché di mo lis di swivi sa modifyé",
        "tog-enotifusertalkpages": "Avèrti mo pa kouryé lò mo paj di diskisyon sa modifyé",
-       "tog-enotifminoredits": "Avèrti mo pa kouryé égalman lò dé modifikasyon minò dé paj ou dé fiché",
+       "tog-enotifminoredits": "Avèrti mo pa kouryé égalman lò dé modifikasyon minò dé paj oben dé fiché",
        "tog-enotifrevealaddr": "Afiché mo adrès élèktronik andan kouryé di notifikasyon",
        "tog-shownumberswatching": "Afiché nonm-an di itilizatò an kour",
        "tog-oldsig": "Zòt signatir atchwèl :",
@@ -50,7 +50,7 @@
        "tog-prefershttps": "Toujou itilizé roun konèksyon sékirizé lò mo konèkté",
        "underline-always": "Toujou",
        "underline-never": "Janmè",
-       "underline-default": "Valò pa défo di tenm ou di navigatò",
+       "underline-default": "Valò pa défo di tenm oben di navigatò",
        "editfont-style": "Stil di polis di zonn di modifikasyon",
        "editfont-monospace": "Polis ké chas fiks",
        "editfont-sansserif": "Polis sans-serif",
        "newwindow": "(Ka ouvri so kò andan roun nouvèl finèt)",
        "cancel": "Anilé",
        "moredotdotdot": "Plis...",
-       "morenotlisted": "Sa lis pé sa enkonplèt",
+       "morenotlisted": "Sa lis pouvé fika enkonplèt",
        "mypage": "Paj",
        "mytalk": "Diskisyon",
        "anontalk": "Diskisyon",
        "tagline": "Di {{SITENAME}}",
        "help": "Èd",
        "search": "Sasé",
-       "search-ignored-headings": " #<!-- pa modifyé sa lign --><pre>\n# Tit dé sèksyon ki sa ignoré pa sasé-a.\n# Chanjman éfèktchwé isi ka pran éfè lò ki paj-a ké tit-a sa endèksé.\n# Zòt pé fòrsé réyendèksasyon di paj-a an éfèktchwan oun modifikasyon vid.\n# Sentaks-a sa swivant :\n#   * Tousa ki ka swiv roun « # » jouk finisman di lign-a sa roun koumantèr.\n#   * Tout lign ki pa-vid sa tit ègzak à ignoré, kas konprann osi.\nRéférans\nLyen èkstèrn\nWè osi\n #</pre><!-- pa modifyé sa lign -->",
+       "search-ignored-headings": " #<!-- pa modifyé sa lign --><pre>\n# Tit dé sèksyon ki ké fika ignoré pa sasé-a.\n# Chanjman-yan ki éfèktchwé isi ka pran léfè lò ki paj-a ké tit-a sa endèksé.\n# Zòt pouvé fòrsé réyendèksasyon di paj-a an éfèktchwan roun modifikasyon vid.\n# Sentaks-a sa swivant-a :\n#   * Tousa ki ka swiv roun « # » jouk finisman-an di lign-an sa roun koumantèr.\n#   * Tout lign ki pa-vid sa tit ègzak-a pou ignoré, kas konprann osi.\nRéférans\nLyen ègstèrn\nWè osi\n #</pre><!-- pa modifyé sa lign -->",
        "searchbutton": "Sasé",
        "go": "Konsilté",
        "searcharticle": "Kontinwé",
        "otherlanguages": "Annan rounòt langaj",
        "redirectedfrom": "(Roudirijé dipi $1)",
        "redirectpagesub": "Paj di roudirèksyon",
-       "redirectto": "Roudirijé vèr :",
+       "redirectto": "Roudirijé bò'd :",
        "lastmodifiedat": "Dannyé modifikasyon di sa paj té fè $1 à $2.",
        "viewcount": "Sa paj {{PLURAL:$1|0=pa té janmè konsilté|1=té konsilté roun sèl fwè|té konsilté $1 fwè}}.",
        "protectedpage": "Paj protéjé",
        "confirmable-confirm": "Ès zòt sir{{GENDER:$1||}} ?",
        "confirmable-yes": "Wi",
        "confirmable-no": "Awa",
-       "thisisdeleted": "Ès zòt ka déziré afiché ou rèstoré $1 ?",
+       "thisisdeleted": "Ès zòt ka déziré afiché oben rèstoré $1 ?",
        "viewdeleted": "Wè $1 ?",
        "restorelink": "Wè {{PLURAL:$1|roun modifikasyon éfasé|$1 modifikasyon éfasé}}",
        "feedlinks": "Flux :",
        "nstab-category": "Katégori",
        "mainpage-nstab": "Paj prensipal",
        "nosuchaction": "Aksyon enkonèt",
-       "nosuchactiontext": "Aksyon-an spésifyé andan URL-a sa envalid.\nZòt pitèt mal antré URL-a ou swivi roun lyen éroné.\nLi pé égalman endiké oun anomali andan logisyèl itilizé pa {{SITENAME}}.",
+       "nosuchactiontext": "Aksyon-an èspésifyé annan URL-a sa envalid.\nZòt pitèt mal antré URL-a oben swivi roun lyen éroné.\nLi pouvé égalman endiké oun anomali andan logisyèl itilizé pa {{SITENAME}}.",
        "nosuchspecialpage": "Paj èspésyal inègzistant",
        "nospecialpagetext": "<strong>Zòt doumandé oun paj èspésyal ki pa ka ègzisté.</strong>\n\nOun lis dé paj èspésyal valid ka trouvé so kò asou [[Special:SpecialPages|{{int:specialpages}}]].",
        "error": "Érò",
-       "databaseerror": "Érò di baz di doné",
-       "databaseerror-text": "Oun érò di rékèt di baz di doné aparèt.\nSala pé provini di roun anomali annan lojisyèl-a.",
+       "databaseerror": "Érò di baz-a di data",
+       "databaseerror-text": "Oun érò di rékèt di baz di doné aparèt.\nSala pouvé provini di roun anomali annan lojisyèl-a.",
        "databaseerror-textcl": "Oun érò di rékèt di baz di doné aparèt.",
        "databaseerror-query": "Rékèt : $1",
        "databaseerror-function": "Fonksyon : $1",
        "databaseerror-error": "Érò : $1",
        "transaction-duration-limit-exceeded": "Pou évité roun tròp fò ogmantasyon di délè di réplikasyon, sa tranzaksyon té anilé piskétan douré di ékritir ($1) dépasé limit-a di $2 ségonn. Si zòt ka sasé modifyé oun gran nonm di éléman similtanéman, éséyé plito di éfèktchwé opérasyon-an an plizyò étap pli piti.",
-       "laggedslavemode": "Panga, sa paj pa pé kontni tout dannyé modifikasyon éfèktchwé",
-       "readonly": "Baz di doné vérouyé",
+       "laggedslavemode": "Panga, sa paj pa pouvé kontni tout dannyé modifikasyon éfèktchwé",
+       "readonly": "Baz di data vérouyé",
        "enterlockreason": "Endiké rézon-an di vérouyaj ensi ki roun èstimasyon di so douré",
        "readonlytext": "Ajou ké mizajou di baz di doné sa atchwèlman bloké, probabman pou pèrmèt mentnans di baz-a, aprè sa, tout bagaj ké rantré andan lòrd.\n\nAdministratò sistèm ki vérouyé baz di doné té fourni èksplikasyon swivant :<br /> $1",
-       "missing-article": "Baz-a di doné pa trouvé tèks-a di roun paj ki li té divèt trouvé, entitilé « $1 » $2.\n\nJénéralman, sala ka sirviv an swivan roun lyen vèr roun diff périmé ou vèr listorik di roun paj souprimé.\n\nSi a pa sa ki la, zòt pitèt trouvé roun anomali annan program-an.\nSouplé, signalé li à roun [[Special:ListUsers/sysop|administratò]] é pa bliyé di endiké li URL-a di paj-a.",
+       "missing-article": "Baz-a di data pa trouvé tèks-a di roun paj ki li té divèt trouvé, ki entitilé « $1 » $2.\n\nJénéralman, sala ka sirvini an swivan roun lyen bò'd roun diff périmé oben bò'd listorik di roun paj souprimé.\n\nSi a pa sa ki la, zòt pitèt trouvé roun annonmali annan progranm-an.\nSouplé, signalé li à roun [[Special:ListUsers/sysop|administratò]] é pa bliyé di endiké li URL-a di paj-a.",
        "missingarticle-rev": "(niméro di vèrsyon : $1)",
        "missingarticle-diff": "(diff : $1, $2)",
        "readonly_lag": "Baz-a di doné té otomatikman vérouyé pannan ki sèrvò-ya ségondèr ka réyaligné yé kò asou sèrvò prensipal",
        "internalerror": "Érò entèrn",
        "internalerror_info": "Érò entèrn : $1",
        "internalerror-fatal-exception": "Érò fatal di tip « $1 »",
-       "filecopyerror": "Enposib di kopyé fiché-a « $1 » vèr « $2 ».",
+       "filecopyerror": "Enposib di kopyé fiché-a « $1 » bò'd « $2 ».",
        "filerenameerror": "Enposib di rounonmen fiché-a « $1 » an « $2 ».",
        "filedeleteerror": "Enposib di souprimé fiché-a « $1 ».",
        "directorycreateerror": "Enposib di kréyé répèrtwar-a « $1 ».",
        "filenotfound": "Enposib di trouvé fiché-a « $1 ».",
        "unexpected": "Valò ki pa nòrmal : « $1 » = « $2 ».",
        "formerror": "Érò : enposib di soumèt fòrmilèr-a.",
-       "badarticleerror": "Sa aksyon pa pé sa éfèktchwé asou sa paj.",
+       "badarticleerror": "Sa aksyon pa pouvé fika éfèktchwé asou sa paj.",
        "cannotdelete": "Enposib di souprimé paj-a oben fiché-a « $1 ».\nSouprésyon-an pitèt ja té éfèktchwé pa rounòt moun.",
        "cannotdelete-title": "Enposib di souprimé paj-a « $1 »",
        "delete-hook-aborted": "Souprésyon anilé pa roun ègstansyon.\nPyès èksplikasyon té bay.",
        "no-null-revision": "Enposib di kréyé roun nouvèl révizyon vid pou paj-a « $1 »",
        "badtitle": "Movè tit",
-       "badtitletext": "Tit di paj doumandé pa valid, vid, ou mal formé si a roun tit entèr-lanng ou entèr-projè.\nI ka kontni pitèt oun ou plizyò karaktèr ki pa pé sa itilizé andan tit-ya.",
+       "badtitletext": "Tit di paj doumandé pa valid, vid, oben mal fòrmé si a roun tit entèr-lanng oben entèr-projè.\nI ka kontni pitèt oun oben plizyò karaktèr ki pa pouvé fika itilizé annan tit-ya.",
        "title-invalid-empty": "Tit di paj doumandé sa vid oben ka kontni sèlman non-an di roun lèspas di non.",
        "title-invalid-utf8": "Tit di paj doumandé ka kontni roun sékans UTF-8 envalid.",
        "title-invalid-interwiki": "Paj sib ka kontni roun lyen interwiki ki nou pa pouvé itilizé annan tit-ya.",
-       "title-invalid-talk-namespace": "Tit di paj doumandé ka fè référans à roun paj di diskisyon ki pa pé ègzisté.",
+       "title-invalid-talk-namespace": "Tit di paj doumandé ka fè référans à roun paj di diskisyon ki pa pouvé ègzisté.",
        "title-invalid-characters": "Tit di paj doumandé ka kontni dé karaktèr ki pa valid : « $1 ».",
        "title-invalid-relative": "Tit ka kontni oun chimen roulatif. Tit-ya ki ka référansé dé paj roulativ (./, ../) pa valid pas li sa souvan itilizé pa navigatò di itilizatò-a.",
        "title-invalid-magic-tilde": "Tit di paj doumandé ka kontni roun sékans di tilde majik ki pa valid (<nowiki>~~~</nowiki>).",
        "actionthrottled": "Aksyon limité",
        "actionthrottledtext": "Pou briga kont abi-ya, itilizasyon-an di sa aksyon sa limité à roun sèrten nonm di fwè annan roun laps di tan asé kourt é zòt dépasé sa limit.\nSouplé, éséyé òkò annan tchèk minout.",
        "protectedpagetext": "Sa paj té protéjé pou anpéché so modifikasyon oben dé ròt aksyon.",
-       "viewsourcetext": "Zòt pé wè é kopyé kontni di sa paj.",
+       "viewsourcetext": "Zòt pouvé wè é kopyé kontni-a di sa paj.",
        "viewyourtext": "Zòt pouvé wè ké kopyé kontni-a di <strong>zòt modifikasyon</strong> à sa paj.",
-       "protectedinterface": "Sa paj ka fourni tèks d'entèrfas pou lojisyèl-a asou sa wiki é sa protéjé pou évité abi-ya.\nPou ajouté oben modifyé dé amòrfwazaj asou tout wiki, souplé, itilizé [https://translatewiki.net/ translatewiki.net], projè-a di réjyonalizasyon di MediaWiki.",
+       "protectedinterface": "Sa paj ka fourni tèks d'entèrfas pou lojisyèl-a asou sa wiki é sa protéjé pou évité abi-ya.\nPou ajouté oben modifyé dé anmòrfwézaj asou tout wiki, souplé, itilizé [https://translatewiki.net/ translatewiki.net], projè-a di réjyonalizasyon di MediaWiki.",
        "editinginterface": "<strong>Panga :</strong> zòt ka modifiyé oun paj itilizé pou kréyé tèks-a di lojisyèl.\nChanjman-yan asou sa paj ké répèrkité asou aparans di entèrfas itilizatò pou ròt itilizatò-ya di sa wiki.",
-       "translateinterface": "Pou ajouté oben modifyé dé amòrfwazaj pou tout wiki, souplé, itilizé [https://translatewiki.net/ translatewiki.net], projè-a di lokalizasyon lengwistik di MediaWiki.",
+       "translateinterface": "Pou ajouté oben modifyé dé anmòrfwézaj pou tout wiki, souplé, itilizé [https://translatewiki.net/ translatewiki.net], projè-a di lokalizasyon lengwistik di MediaWiki.",
        "cascadeprotected": "Sa paj protéjé kont modifikasyon-yan pas li sa transkliz pa {{PLURAL:$1|paj-a ki ka swiv, ki té protéjé|paj-ya ki ka swiv, ki té protéjé}} ké lòpsyon « protèksyon an kaskad » aktivé :\n$2",
        "namespaceprotected": "Zòt pa gen pèrmisyon-an di modifyé paj-ya di lèspas di non « <strong>$1</strong> ».",
        "customcssprotected": "Zòt pa gen pèrmisyon-an di modifyé sa féy di stil CSS, pas li ka kontni paramèt pèrsonèl di rounòt itilizatò.",
        "createacct-email-ph": "Zòt adrès di kouryé",
        "createacct-another-email-ph": "Antré adrès-a di kouryé",
        "createaccountmail": "Itilizé roun mo di pas aléyatwar tanporèr é voyé li pou adrès-a di kouryé spésifyé",
-       "createaccountmail-help": "Pé sa itilizé pou kréyé roun kont pou rounòt moun san konèt mo di pas.",
+       "createaccountmail-help": "Pouvé fika itilizé pou kréyé roun kont pou rounòt moun san konèt mo di pas-a.",
        "createacct-realname": "Non réyèl (fakiltatif)",
        "createacct-reason": "Motif",
        "createacct-reason-ph": "Poukisa zòt kréyé rounòt kont",
        "botpasswords-label-delete": "Souprimé",
        "botpasswords-label-resetpassword": "Réyinisyalizé mo di pas",
        "botpasswords-label-grants": "Drwè aplikab :",
-       "botpasswords-help-grants": "Otorizasyon-yan ka pèrmèt di aksédé o drwè ki ja akòrdé à zòt kont itilizatò. Aktivé roun otorizasyon isi pa ka fourni laksè à pyès drwè ki zòt kont itilizatò pé ké gen dayò. Wè [[Special:ListGrants|tablo dé otorizasyon]] pou plis d’enfòrmasyon.",
+       "botpasswords-help-grants": "Otorizasyon-yan ka pèrmèt di aksédé o drwè ki déja akòrdé à zòt kont itilizatò. Aktivé roun otorizasyon isi ka fourni laksè à pyès drwè ki zòt kont itilizatò pa gen dayò. Wè [[Special:ListGrants|tablo dé otorizasyon]] pou plis d’enfòrmasyon.",
        "botpasswords-label-grants-column": "Akòrdé",
        "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é ?",
        "preview": "Prévizwalizasyon",
        "showpreview": "Prévizwalizé",
        "showdiff": "Wè modifikasyon-yan",
-       "anoneditwarning": "<strong>Panga :</strong> zòt pa konèkté. Zòt adrès IP ké sa vizib di tout moun si zòt ka fè dé modifikasyon. Si zòt <strong>[$1 ka konèkté zòt kò]</strong> ou <strong>[$2 kréyé roun kont]</strong>, zòt modifikasyon ké sq atribwé à zòt pròp non di itilizatò(ris) é zòt ké gen dé ròt avantaj.",
-       "blockedtext": "<strong>Zòt kont itilizatò oben zòt adrès IP bloké.</strong>\n\nBlokaj té éfèktchwé pa $1.\nRézon-an évoké sa swivant : <em>$2</em>.\n\n* Koumansman di blokaj : $8\n* Èspirasyon di blokaj : $6\n* Kont bloké : $7.\n\nZòt pé kontakté $1 oben rounòt [[{{MediaWiki:Grouppage-sysop}}|administratò]] pou an diskité.\nZòt pa pouvé itilizé fonksyon-an « {{int:emailuser}} » rounso si oun adrès di kouryé valid sa èspésifyé andan zòt [[Special:Preferences|préférans]] é rounso si sa fonksyonalité pa bloké.\nZòt adrès IP atchwèl sa $3 é zòt idantifyan di blokaj sa $5.\nSouplé, enkli tout détay-ya lasou'l annan chakin dé rékèt ki zòt ké fè.",
+       "anoneditwarning": "<strong>Panga :</strong> zòt pa konèkté. Zòt adrès IP ké fika vizib pa tout moun si zòt ka fè dé modifikasyon. Si zòt <strong>[$1 ka konèkté 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.",
+       "blockedtext": "<strong>Zòt kont itilizatò oben zòt adrès IP bloké.</strong>\n\nBlokaj té éfèktchwé pa $1.\nRézon-an ki évoké ka swiv : <em>$2</em>.\n\n* Koumansman di blokaj : $8\n* Èspirasyon di blokaj : $6\n* Kont bloké : $7.\n\nZòt pouvé kontakté $1 oben rounòt [[{{MediaWiki:Grouppage-sysop}}|administratò]] pou an diskité.\nZòt pa pouvé itilizé fonksyon-an « {{int:emailuser}} » rounso si oun adrès di kouryé valid sa èspésifyé andan zòt [[Special:Preferences|préférans]] é rounso si sa fonksyonalité pa bloké.\nZòt adrès IP atchwèl sa $3 é zòt idantifyan di blokaj sa $5.\nSouplé, enkli tout détay-ya lasou'l annan chakin dé rékèt ki zòt ké fè.",
        "loginreqlink": "konèkté so kò",
-       "newarticletext": "Zòt té ka swiv roun lyen vèr roun paj ki pa ka ègzisté òkò. \nAtò di kréyé sa paj, antré zòt tèks annan bwat ki aprè (zòt pé konsilté [$1 paj d'èd-a] pou plis enfòrmasyon).\nSi zòt pa rivé{{GENDER:|}} isi pa éròr, kliké asou bouton <strong>Routour</strong> di zòt navigatò.",
-       "anontalkpagetext": "----\n<em>Zòt asou paj di diskisyon di oun itilizatò anonim ki pa òkò kréyé di kont ou ki pa ka an itilizé</em>.\nPou sa rézon, nou divèt itilizé so adrès IP pou idantifyé li.\nOun adrès IP pé sa partajé pa plizyò itilizatò.\nSi zòt roun itiliza{{GENDER:|ò|ris}} anonim é si zòt ka kontasté ki dé koumantèr ki pa ka konsèrné zòt sa adrèsé à zòt, zòt pé [[Special:CreateAccount|kréyé roun kont]] ou [[Special:UserLogin|konèkté zòt kò]] atò di évité tout konfizyon fitir ké ròt kontribitò anonim.",
-       "noarticletext": "I pa gen atchwèlman pyès tèks 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 opérasyon lyé]\noben [{{fullurl:{{FULLPAGENAME}}|action=edit}} kréyé sa paj]</span>.",
+       "newarticletext": "Zòt té ka swiv roun lyen bò'd roun paj ki pa ka ègzisté òkò. \nAfen di kréyé sa paj, antré zòt tèks annan bwèt ki aprè (zòt pouvé konsilté [$1 paj di lèd-a] pou plis d'enfòrmasyon).\nSi zòt vini{{GENDER:|}} isi pa éròr, kliké asou bouton <strong>Routour</strong> di zòt navigatò.",
+       "anontalkpagetext": "----\n<em>Zòt asou paj di diskisyon di roun itilizatò anonim ki pa òkò kréyé di kont oben ki pa ka an itilizé</em>.\nPou sa rézon, nou divèt itilizé so adrès IP pou idantifyé li.\nOun adrès IP pouvé fika partajé pa plizyò itilizatò.\nSi zòt roun itiliza{{GENDER:|ò|ris}} anonim é si zòt ka kontasté ki dé koumantèr ki pa ka konsèrné zòt sa adrèsé pou zòt, zòt pouvé [[Special:CreateAccount|kréyé roun kont]] oben [[Special:UserLogin|konèkté zòt kò]] atò di évité tout konfizyon fitir ké ròt kontribitò anonim.",
+       "noarticletext": "I pa gen atchwèlman pyès tèks 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 opérasyon ki lyannen]\noben [{{fullurl:{{FULLPAGENAME}}|action=edit}} kréyé sa paj]</span>.",
        "noarticletext-nopermission": "I pa gen atchwèlman pyès tèks asou sa paj.\nZòt pouvé [[Special:Search/{{PAGENAME}}|fè roun sasé asou sa tit]] andan ròt paj-ya,\noben <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|paj={{FULLPAGENAMEE}}}} sasé annan journal asosyé]</span>, mè zòt pa gen pèrmisyon 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 forsé roucharjman konplè di kach di zòt navigatò pou wè chanjman-yan.\n* <strong>Firefox / Safari :</strong> mentné touch-a <em>Maj</em> (<em>Shift</em>) an klikan asou bouton-an <em>Atchwalizé</em> ou présé <em>Ctrl-F5</em> ou <em>Ctrl-R</em> (<em>⌘-R</em> asou roun Mac) \n* <strong>Google Chrome :</strong> apwiyé asou <em>Ctrl-Maj-R</em> (<em>⌘-Shift-R</em> asou roun Mac) \n* <strong>Internet Explorer :</strong> mentné touch-a <em>Ctrl</em> an klikan asou bouton-an <em>Atchwalizé</em> ou 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é doné d'èksplorasyon-yan → Imaj ké fiché an kach</em>.",
+       "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> mentné 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é doné d'èsplorasyon-yan → Imaj ké fiché an kach</em>.",
        "previewnote": "<strong>Raplé-zòt ki a jis roun prévizwalizasyon.</strong>\nZòt modifikasyon pa òkò anréjistré !",
        "continue-editing": "Alé kot zonn di modifikasyon",
        "editing": "Modifikasyon di $1",
        "template-semiprotected": "(sémi-protéjé)",
        "hiddencategories": "{{PLURAL:$1|Katégori kaché}} don sa paj ka fè parti :",
        "permissionserrors": "Éròr di pèrmisyon",
-       "permissionserrorstext-withaction": "Zòt pa pé $2, pou {{PLURAL:$1|rézon swivant}} :",
+       "permissionserrorstext-withaction": "Zòt pa pouvé $2, pou {{PLURAL:$1|rézon swivant}} :",
        "recreate-moveddeleted-warn": "<strong>Panga : zòt ka roukréyé oun paj ki té présédaman souprimé.</strong>\n\nAsouré-zòt ki li sa pertinan di pourswiv modifikasyon-yan asou sa paj.\nJournal dé souprésyon é dé déplasman pou sa paj sa afiché anba à tit di enfòrmasyon :",
        "moveddeleted-notice": "Sa paj té souprimé. \nJournal dé souprésyon, dé protèksyon é dé déplasman di paj-a sa afiché anba pou référans.",
        "content-model-wikitext": "wikitèks",
-       "undo-failure": "Sa modifikasyon pa pé défèt : sala ké antré an konfli ké modifikasyon-yan entèrmédyèr.",
+       "undo-failure": "Sa modifikasyon pa pouvé défèt : sala ké antré an konfli ké modifikasyon entèrmédjèr-ya.",
        "viewpagelogs": "Wè opérasyon-yan asou sa paj",
        "currentrev-asof": "Vèrsyon atchwèl daté di $1",
        "revisionasof": "Vèrsyon di $1",
        "currentrevisionlink": "Wè vèrsyon atchwèl-a",
        "cur": "atch",
        "last": "dif",
-       "histlegend": "Sélèksyon di dif : koché bouton radyo-ya dé vèrsyon à konparé é apwiyé asou antré ou asou bouton an ba.<br />\nLéjann : <strong>({{int:cur}})</strong> = diférans ké dannyé vèrsyon-an, <strong>({{int:last}})</strong> = diférans ké vèrsyon présédant, <strong>{{int:minoreditletter}}</strong> = modifikasyon minò.",
+       "histlegend": "Sélèksyon di diff : koché bouton radjo-ya dé vèrsyon à konparé é apiyé asou antré oben asou bouton-an ki anba.<br />\nLéjann : <strong>({{int:cur}})</strong> = diférans ké dannyé vèrsyon-an, <strong>({{int:last}})</strong> = diférans ké vèrsyon présédant-a, <strong>{{int:minoreditletter}}</strong> = modifikasyon minò.",
        "history-fieldset-title": "Sasé dé révizyon",
        "histfirst": "Pli ansyenn",
        "histlast": "Pli résant",
        "boteditletter": "b",
        "rc-change-size-new": "$1 {{PLURAL:$1|oktè}} aprè chanjman",
        "rc-old-title": "kréyé inisyalman ké tit « $1 »",
-       "recentchangeslinked": "Swivi dé paj lyé",
-       "recentchangeslinked-feed": "Swivi dé paj lyé",
-       "recentchangeslinked-toolbox": "Swivi dé paj lyé",
+       "recentchangeslinked": "Swivi dé paj ki lyannen",
+       "recentchangeslinked-feed": "Swivi dé paj ki lyannen",
+       "recentchangeslinked-toolbox": "Swivi dé paj ki lyannen",
        "recentchangeslinked-title": "Swivi dé paj asosyé à « $1 »",
-       "recentchangeslinked-summary": "Antré roun non di paj pou wè modifikasyon-yan ki fè résaman asou dé paj lyé dipi oben bò'd sa paj (pou wè manm-yan di oun katégori, antré {{ns:category}}:Non di katégori). Modifikasyon-yan dé paj di [[Special:Watchlist|zòt lis di swivi]] sa <strong>an gra</strong>.",
+       "recentchangeslinked-summary": "Antré roun non di paj pou wè modifikasyon-yan ki fè résaman asou dé paj ki lyannen dipi oben bò'd sa paj (pou wè manm-yan di oun katégori, antré {{ns:category}}:Non di katégori). Modifikasyon-yan dé paj di [[Special:Watchlist|zòt lis di swivi]] sa <strong>an gra</strong>.",
        "recentchangeslinked-page": "Non di paj :",
-       "recentchangeslinked-to": "Afiché modifikasyon-yan dé paj ki ka konpòrté roun lyen vèr paj ki bay plito ki envèrs",
+       "recentchangeslinked-to": "Afiché modifikasyon-yan dé paj ki ka konpòrté roun lyen bò'd paj-a ki bay plito ki lenvèrs-a",
        "upload": "Enpòrté roun fiché",
        "uploadlogpage": "Journal di enpo di fiché",
        "filedesc": "Dèskripsyon",
        "linkstoimage-more": "Plis {{PLURAL:$1|di roun paj ka itilizé|di $1 paj ka itilizé}} sa fiché.\nLis swivant ka afiché sèlman {{PLURAL:$1|pronmyé paj-a ki ka itilizé|$1 pronmyé paj-ya ki ka itilizé}} sa fiché.\nOun [[Special:WhatLinksHere/$2|lis konplèt]] sa disponib.",
        "nolinkstoimage": "Pyès paj pa ka itilizé sa fiché.",
        "linkstoimage-redirect": "$1 (roudirèksyon di fiché) $2",
-       "sharedupload-desc-here": "Sa fiché ka provini di $1. Li pé sa itilizé pa dé ròt projè.\nSo dèskripsyon asou so [$2 paj di dèskripsyon] sa afiché anba.",
+       "sharedupload-desc-here": "Sa fiché ka provini di $1. Li pouvé fika itilizé pa ròt projè.\nSo dèskripsyon asou so [$2 paj di dèskripsyon] sa afiché anba.",
        "filepage-nofile": "Pyès fiché di sa non ka ègzisté.",
-       "upload-disallowed-here": "Zòt pa pé ranplasé sa fiché.",
+       "upload-disallowed-here": "Zòt pa pouvé ranplasé sa fiché.",
        "randompage": "Paj o azò",
-       "statistics": "Statistik",
+       "statistics": "Èstatistik",
        "double-redirect-fixer": "Korèktò di roudirèksyon",
        "nbytes": "$1 {{PLURAL:$1|òktè}}",
        "nmembers": "$1 manm{{PLURAL:$1|}}",
        "booksources-search-legend": "Sasé parmi dé ouvraj di référans",
        "booksources-search": "Sasé",
        "specialloguserlabel": "Otò :",
-       "speciallogtitlelabel": "Sib (tit ou {{ns:user}}:non di itilizatò) :",
+       "speciallogtitlelabel": "Sib (tit oben {{ns:user}}:non di itilizatò) :",
        "log": "Journal d’opérasyon",
        "all-logs-page": "Tout journal piblik",
-       "alllogstext": "Afichaj konbiné di tout journal disponib asou {{SITENAME}}.\nZòt pé pèrsobalizé afichaj an sélèksyonan tip di journal, non di itilizatò ou paj-a konserné (sa dé dannyé sa sansib à lakas).",
+       "alllogstext": "Afichaj konbiné di tout journal disponib asou {{SITENAME}}.\nZòt pouvé pèrsonalizé afichaj an sélèksyonnan tip di journal, non di itilizatò oben paj-a ki konsèrné (sa Dé dannyé sa sansib à lakas).",
        "logempty": "Pyès opérasyon korèspondant andan journal-ya.",
        "allpages": "Tout paj-ya",
        "allarticles": "Tout paj-ya",
        "invert": "Envèrsé sélèksyon-an",
        "tooltip-invert": "Koché sa kaz pou kaché modifikasyon-yan dé paj annan lèspas di non sélèksyoné (ké lèspas di non asosyé si koché)",
        "namespace_association": "Lèspas di non asosyé",
-       "tooltip-namespace_association": "Koché sa kaz pou enklir égalman lèspas di non di diskisyon ou di sijè, asosyé à lèspas di non sélèksyoné",
+       "tooltip-namespace_association": "Koché sa kaz pou enkli égalman lèspas di non di diskisyon oben di sijè, ki asosyé à lèspas di non ki sélèksyoné",
        "blanknamespace": "(Prensipal)",
        "contributions": "Kontribisyon di {{GENDER:$1|itilizatò|itilizatris}}",
        "contributions-title": "Lis di kontribisyon-yan di itiliza{{GENDER:$1|ò|ris}}-a $1",
        "sp-contributions-logs": "journal",
        "sp-contributions-talk": "diskité",
        "sp-contributions-search": "Sasé kontribisyon-yan",
-       "sp-contributions-username": "Adrès IP ou non di itilizatò :",
+       "sp-contributions-username": "Adrès IP oben non di itilizatò :",
        "sp-contributions-toponly": "Montré ki kontribisyon-yan ki sa dannyé-ya dé artik",
        "sp-contributions-newonly": "Afiché inikman modifikasyon-yan ki sa dé kréyasyon di paj",
        "sp-contributions-submit": "Sasé",
-       "whatlinkshere": "Paj lyé",
+       "whatlinkshere": "Paj ki lyannen",
        "whatlinkshere-title": "Paj ki ka pwenté bò'd « $1 »",
        "whatlinkshere-page": "Paj :",
-       "linkshere-2": "Paj-ya ki anba ka kontni roun lyen vèr <strong>$1</strong> :",
-       "nolinkshere-2": "Pyès paj pa gen kontni dé lyen vèr <strong>$1</strong>.",
+       "linkshere": "Paj-ya ki anba ka kontni roun lyen bò'd <strong>$2</strong> :",
+       "nolinkshere": "Pyès paj ka kontni dé lyen bò'd <strong>$2</strong>.",
        "isredirect": "paj di roudirèksyon",
        "istemplate": "enklizyon",
-       "isimage": "Lyen vèr fiché-a",
+       "isimage": "Lyen bò'd fiché-a",
        "whatlinkshere-prev": "{{PLURAL:$1|présédant|$1 présédant}}",
        "whatlinkshere-next": "{{PLURAL:$1|swivant|$1 swivant}}",
        "whatlinkshere-links": "lyen",
        "whatlinkshere-hideredirs": "$1 roudirèksyon-yan",
        "whatlinkshere-hidetrans": "$1 enklizyon-yan",
        "whatlinkshere-hidelinks": "$1 lyen-yan",
-       "whatlinkshere-hideimages": "$1 lyen vèr fiché-a",
+       "whatlinkshere-hideimages": "$1 lyen-yan bò'd fiché-a",
        "whatlinkshere-filters": "Filt",
        "ipboptions": "2 lò:2 hours,1 jou:1 day,3 jou:3 days,1 simenn:1 week,2 simenn:2 weeks,1 mwa:1 month,3 mwa:3 months,6 mwa:6 months,1 lan:1 year,endéfiniman:infinite",
        "infiniteblock": "enfini",
        "tooltip-ca-talk": "Diskisyon o sijè di sa paj di kontni",
        "tooltip-ca-edit": "Modifyé wikikod-a",
        "tooltip-ca-addsection": "Koumansé roun nouvèl sèksyon",
-       "tooltip-ca-viewsource": "Sa paj sa protéjé.\nZòt pé toutfwè vizwalizé sours-a.",
+       "tooltip-ca-viewsource": "Sa paj sa protéjé.\nZòt pouvé toutfwè vizwalizé sours-a.",
        "tooltip-ca-history": "Istorik vèrsyon-yan di sa paj",
        "tooltip-ca-protect": "Protéjé sa paj",
        "tooltip-ca-delete": "Souprimé sa paj",
        "tooltip-p-logo": "Vizité paj prensipal-a",
        "tooltip-n-mainpage": "Vizité paj prensipal-a di sit",
        "tooltip-n-mainpage-description": "Paj prensipal jénéral",
-       "tooltip-n-portal": "À propo di projè, sa ki zòt pé fè, koté trouvé enfòrmasyon-yan",
+       "tooltip-n-portal": "À propo di projè, sa ki zòt pouvé fè, koté trouvé enfòrmasyon-yan",
        "tooltip-n-currentevents": "Trouvé plis d'enfòrmasyon asou atchwalité an kour",
        "tooltip-n-recentchanges": "Lis di modifikasyon résant asou wiki-a",
        "tooltip-n-randompage": "Afiché roun paj o azò",
        "tooltip-n-help": "Aksè à lèd",
-       "tooltip-t-whatlinkshere": "Lis di paj lyé ki ka pwenté asou sala",
+       "tooltip-t-whatlinkshere": "Lis dé paj ki lyannen ki ka pwenté asou sala",
        "tooltip-t-recentchangeslinked": "Lis di modifikasyon résant liyé à sa paj",
        "tooltip-feed-atom": "Flux Atom pou sa paj",
        "tooltip-t-contributions": "Wè lis dé kontribisyon di {{GENDER:$1|sa itilizatò|sa itilizatris}}",
        "tooltip-diff": "Afiché modifikasyon-yan ki zòt apòrté andan tèks-a.",
        "tooltip-compareselectedversions": "Afiché diférans-ya ant dé vèrsyon-yan sélèksyoné di sa paj",
        "tooltip-watch": "Ajouté sa paj annan zòt lis di swivi",
-       "tooltip-rollback": "« Révoké » ka anilé an roun klik modifikasyon(-an ou yan) di sa paj réyalizé pa so dannyé kontribitò",
+       "tooltip-rollback": "« Révoké » ka anilé an roun klik modifikasyon(-an oben yan) di sa paj ki réyalizé pa so dannyé kontribitò",
        "tooltip-undo": "« Anilé » ka rétabli modifikasyon présédant é ka ouvri lafinèt di modifikasyon an mòd prévizwalizasyon. I posib di ajouté roun rézon annan rézimé-a.",
        "tooltip-summary": "Antré roun brèf rézimé",
        "simpleantispam-label": "Vérifikasyon anti-pouryèl.\nPa <strong>enskri</strong> anyen isi !",
        "pageinfo-robot-noindex": "Pa otorizé",
        "pageinfo-watchers": "Nonm di kontribitò ki gen paj andan yé lis di swivi",
        "pageinfo-few-watchers": "Mwens di $1 {{PLURAL:$1|obsèrvatò}}",
-       "pageinfo-redirects-name": "Nonm di roudirèksyon vèr sa paj",
+       "pageinfo-redirects-name": "Nonm di roudirèksyon bò'd sa paj",
        "pageinfo-subpages-name": "Nonm di soupaj di sa paj",
        "pageinfo-subpages-value": "$1 ($2 {{PLURAL:$2|roudirèksyon}}; $3 {{PLURAL:$3|pa-roudirèksyon}})",
        "pageinfo-firstuser": "Kréyatò di paj-a",
        "show-big-image-other": "{{PLURAL:$2|Ròt rézolisyon}} : $1.",
        "show-big-image-size": "$1 × $2 piksèl",
        "metadata": "Métadoné",
-       "metadata-help": "Sa fiché ka kontni dé enfòrmasyon siplémantèr, probabman ajouté pa aparèy foto nimèrik ou nimérizò itilizé pou kréyé. \nSi fiché té modifyé dipi so léta orijinal, serten détay pa pé rouflété antyèrman imaj modifyé-a.",
+       "metadata-help": "Sa fiché ka kontni dé enfòrmasyon siplémantèr, probabman ajouté pa aparèy foto nimèrik-a oben nimérizò-a ki itilizé pou kréyé. \nSi fiché-a té modifyé dipi so léta orijinal, sèrten détay pa pouvé rouflété antchèrman imaj-a ki modifyé.",
        "metadata-fields": "Chan di métadoné d'imaj listé andan sa mésaj ké sa enkli andan paj di dèskripsyon di imaj-a lò tab-a di métadoné ké sa rédjwit. Ròt chan ké sa kaché pa défo.\n* make\n* model\n* datetimeoriginal\n* exposuretime\n* fnumber\n* isospeedratings\n* focallength\n* artist\n* copyright\n* imagedescription\n* gpslatitude\n* gpslongitude\n* gpsaltitude",
        "exif-orientation": "Oryantasyon",
        "exif-xresolution": "Rézolisyon orizontal",
        "watchlisttools-edit": "Wè é modifyé lis di swivi",
        "watchlisttools-raw": "Modifyé lis di swivi an mòd brout",
        "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|diskisyon]])",
-       "redirect": "Roudirijé pa ID di fiché, itilizatò, paj, révizyon ou journal",
+       "redirect": "Roudirijé pa ID di fiché, itilizatò, paj, révizyon oben journal",
        "redirect-summary": "Sa paj èspésyal ka roudirijé bò'd roun fiché (non di fiché fourni), oun paj (ID di révizyon oben di paj fourni), oun paj di itilizatò (idantifyan nimérik di itilizatò fourni), oben roun antré di journal (ID di journal fourni). Itilizasyon : [[{{#Special:Redirect}}/file/Example.jpg]], [[{{#Special:Redirect}}/page/64308]], [[{{#Special:Redirect}}/revision/328429]], [[{{#Special:Redirect}}/user/101]], oben [[{{#Special:Redirect}}/logid/186]].",
        "redirect-submit": "Validé",
        "redirect-lookup": "Sasé :",
        "logentry-delete-restore": "$1 rèstoré paj-a $3 ($4)",
        "logentry-delete-revision": "$1 {{GENDER:$2|modifyé}} vizibilité {{PLURAL:$5|di oun révizyon|di $5 révizyon}} asou paj $3 : $4",
        "revdelete-content-hid": "kontni maské",
-       "logentry-move-move": "$1 déplasé paj $3 vèr $4",
-       "logentry-move-move-noredirect": "$1 {{GENDER:$2|déplasé}} paj-a $3 vèr $4 san lésé di roudirèksyon",
-       "logentry-move-move_redir": "$1 {{GENDER:$2|déplasé}} paj-a $3 vèr $4 pa lasou oun roudirèksyon",
+       "logentry-move-move": "$1 déplasé paj-a $3 bò'd $4",
+       "logentry-move-move-noredirect": "$1 {{GENDER:$2|déplasé}} paj-a $3 bò'd $4 san lésé di roudirèksyon",
+       "logentry-move-move_redir": "$1 {{GENDER:$2|déplasé}} paj-a $3 bò'd $4 asou roun roudirèksyon",
        "logentry-patrol-patrol-auto": "$1 {{GENDER:$2|té otomatikman marké}} révizyon $4 di paj $3 kou rouli",
        "logentry-newusers-create": "Kont di itilizat{{GENDER:$4|ò|ris}} $1 té kréyé",
        "logentry-newusers-autocreate": "Kont $1 {{GENDER:$2|té kréyé}} otomatikman",
index e5a0161..9bdd762 100644 (file)
        "botpasswords-created-body": "Chaidh am facal-faire bot airson a’ bhot air a bheil “$1” aig a’ chleachdaiche “$2” a chruthachadh.",
        "botpasswords-updated-title": "Chaidh am facal-faire bot ùrachadh",
        "resetpass_forbidden": "Cha ghabh na faclan-faire atharrachadh",
+       "resetpass_forbidden-reason": "Cha ghabh na faclan-faire atharrachadh: $1",
        "resetpass-no-info": "Feumaidh tu logadh a-steach mus dèan thu inntrigeadh dìreach dhan duilleag seo.",
        "resetpass-submit-loggedin": "Atharraich am facal-faire",
        "resetpass-submit-cancel": "Sguir dheth",
        "resetpass-temp-password": "Facal-faire sealach:",
        "resetpass-abort-generic": "Chuir leudachan crìoch air atharrachadh an fhacail-fhaire.",
        "resetpass-expired": "Dh'fhalbh an ùine air an fhacal-fhaire agad. Suidhich facal-faire ùr airson logadh a-steach.",
-       "resetpass-expired-soft": "Dh'fhalbh an ùine air an fhacal-fhaire agad is feumaidh tu ath-shuidheachadh. Tagh fear ùr no briog air \"{{int:authprovider-resetpass-skip-label}}\" gus ath-shuidheachadh às a dhèidh seo.",
-       "resetpass-validity-soft": "Chan eil am facal-faire seo dligheach: $1\n\nTagh facal-faire ùr an-dràsta no briog air \"{{int:authprovider-resetpass-skip-label}}\" gus ath-shuidheachadh às a dhèidh seo.",
+       "resetpass-expired-soft": "Dh'fhalbh an ùine air an fhacal-fhaire agad is feumaidh tu atharrachadh. Tagh fear ùr no briog air “{{int:authprovider-resetpass-skip-label}}” gus atharrachadh às a dhèidh seo.",
+       "resetpass-validity-soft": "Chan eil am facal-faire seo dligheach: $1\n\nTagh facal-faire ùr an-dràsta no briog air “{{int:authprovider-resetpass-skip-label}}” gus atharrachadh às a dhèidh seo.",
        "passwordreset": "Ath-shuidhich am facal-faire",
        "passwordreset-text-one": "Lìon am foirm seo gus am facal-faire agad ath-shuidheachadh.",
        "passwordreset-text-many": "Lìon {{PLURAL:$1|an raon|aon dhe na raointean}} gus facal-faire sealach fhaighinn air a' phost-d.",
        "passwordreset-emailtext-user": "Dh'iarr an cleachdaiche $1 air {{SITENAME}} ath-shuidheachadh an fhacail-fhaire air {{SITENAME}} ($4). Tha {{PLURAL:$3|an cunntas-cleachdaiche|na cunntasan-cleachdaiche}} a leanas co-cheangailte ris an t-seòladh puist-d seo:\n\n$2\n\nFalbhaidh an ùine air {{PLURAL:$3|an fhacal-fhaire shealach|na faclan-faire sealach}} seo an ceann $5 {{PLURAL:$5|latha|latha|làithean|latha}}.\nBu chòir dhut logadh a-steach agus facal-faire ùr a thaghadh an-dràsta. Ma dh'iarr cuideigin eile seo no ma chuimhnich thu air an fhacal-fhaire agad 's mur eil thu airson atharrachadh tuilleadh, leig seachad an teachdaireachd seo 's lean ort leis an t-seann fhacal-fhaire.",
        "passwordreset-emailelement": "Ainm-cleachdaiche: \n$1\n\nFacal-faire sealach: \n$2",
        "passwordreset-emailsentemail": "Ma tha am post-d seo co-cheangailte ris a’ chunntas agad, thèid post-d airson ath-shuidheachadh an fhacail-fhaire a chur.",
+       "passwordreset-emailsentusername": "Ma tha post-d co-cheangailte ris an ainm-chleachdaiche seo, thèid post-d airson ath-shuidheachadh an fhacail-fhaire a chur.",
+       "passwordreset-nocaller": "Feumaidh tu gairmear a chur ann",
+       "passwordreset-nosuchcaller": "Chan eil an gairmear seo ann: $1",
+       "passwordreset-ignored": "Cha b’ urrainn dhuinn ath-shuidheachadh an fhacail-fhaire a làimhseachadh. Dh’fhaoidte nach deach solaraiche a rèiteachadh.",
+       "passwordreset-invalidemail": "Seòladh puist-d mì-dhligheach",
+       "passwordreset-nodata": "Cha deach ainm-cleachdaiche no seòladh puist-d a thoirt seachad",
        "changeemail": "Atharraich no thoir air falbh an seòladh puist-d",
        "changeemail-header": "Lìon am foirm seo a dh’atharrachadh an t-seòlaidh phuist-d agad. Ma tha thu airson an co-cheangal eadar post-d sam bith is an cunntas agad a thoirt air falbh, fàg an seòladh ùr bàn nuair a chuireas tu am foirm.",
        "changeemail-no-info": "Feumaidh tu logadh a-steach mus dèan thu inntrigeadh dìreach dhan duilleag seo.",
        "changeemail-password": "Am facal-faire agad air {{SITENAME}}:",
        "changeemail-submit": "Atharraich am post-d",
        "changeemail-throttled": "Dh'fheuch thu ri logadh a-steach ro thric.\nFuirich ort $1 mus feuch thu ris a-rithist.",
+       "changeemail-nochange": "Cuir a-steach post-d ùr eile.",
        "resettokens": "Ath-shuidhich na tòcanan",
        "resettokens-text": "'S urrainn dhut tòcanan ath-shuidheachadh a bheir cothrom dhut air cuid a dhàta prìobhaideach a tha co-cheangailte ris a' chunntas agad.\n\nBu chòir dhut seo a dhèanamh ma thug thu do chuideigin e air mhearachd no ma bhris cuideigin a-steach air a' chunntas agad.",
        "resettokens-no-tokens": "Chan eil tòcan ann a ghabhas ath-shuidheachadh.",
        "savechanges": "Sàbhail na dh’atharraich thu",
        "publishpage": "Foillsich an duilleag",
        "publishchanges": "Foillsich na mùthaidhean",
+       "savearticle-start": "Sàbhail an duilleag...",
+       "savechanges-start": "Sàbhail na h-atharraichean...",
+       "publishpage-start": "Foillsich an duilleag...",
+       "publishchanges-start": "Foillsich na mùthaidhean...",
        "preview": "Ro-shealladh",
        "showpreview": "Seall an ro-shealladh",
        "showdiff": "Seall na mùthaidhean",
        "anonpreviewwarning": "<em>Chan eil thu air logadh a-steach. Ma nì thu sàbhaladh, thèid an seòladh IP agad a chlàradh ann an eachdraidh deasachadh na duilleige seo.</em>",
        "missingsummary": "<strong>Cuimhnich:</strong> Cha dug thu seachad gearr-chunntas air na dh'atharraich thu.\nMa bhriogas tu air \"$1\" a-rithist, thèid na dheasaich thu a shàbhaladh as aonais gearr-chunntais.",
        "selfredirect": "<strong>Rabhadh:</strong> Tha thu ag ath-stiùireadh duilleag dha fhèin.\nDh'fhaoidte gun do shònraich thu an t-amas cearr airson an ath-stiùiridh no gu bheil thu a' deasachadh an duilleag cearr.\nMa nì thu briogadh air \"$1\" a-rithist,m thèid an ath-stiùireadh a chruthachadh co-dhiù.",
-       "missingcommenttext": "Cuir a-steach beachd gu h-ìosal.",
+       "missingcommenttext": "Cuir a-steach beachd.",
        "missingcommentheader": "<strong>Cuimhnich:</strong> Cha dug thu seachad cuspair airson a’ bheachd seo.\nMa bhriogas tu air “$1” a-rithist, thèid na dheasaich thu a shàbhaladh as aonais.",
-       "summary-preview": "Ro-shealladh a' ghearr-chunntais:",
+       "summary-preview": "Ro-shealladh gearr-chunntas an deasachaidh:",
        "subject-preview": "Ro-shealladh a’ chuspair:",
+       "previewerrortext": "Thachair mearachd fhad ’s a bha sinn airson ro-shealladh nan atharraichean a shealltainn dhut.",
        "blockedtitle": "Tha an cleachdair air a bhacadh",
-       "blockedtext": "<strong>Chaidh an t-ainm-cleachdaiche no an seòladh IP agad a bhacadh.</strong>\n\n'S e $1 a chur am bacadh seo ort.\n{{GENDER:$1|Thug e|Thug i|Thugadh}} an cèill gun do {{GENDER:$1|rinn e|rinn i|rinneadh}} sin air sgàth an adhbhair seo: <em>$2</em>.\n\n* Toiseach a' bhacaidh: $8\n* Deireadh a' bhacaidh: $6\n* An neach air a bheil am bacadh: $7\n\n'S urrainn dhut fios a chur gu $1 no [[{{MediaWiki:Grouppage-sysop}}|rianair]] eile gus am bacadh seo a dheasbad.\nChan urrainn dhut am feart \"Cuir post-d dhan chleachdaiche seo\" a chleachdadh ach ma tha seòladh puist-d dligheach ann an [[Special:Preferences|roghainnean a' chunntais agad]] agus mura deach bacadh a chur air a chleachdadh.\n'S e $3 an seòladh IP làithreach agus agus 's e #$5 ID a' bhacaidh.\nThoir iomradh air a' mhion-fhiosrachadh gu h-àrd ma chuireas tu ceist sam bith mu dhèidhinn.",
+       "blockedtext": "<strong>Chaidh an t-ainm-cleachdaiche no an seòladh IP agad a bhacadh.</strong>\n\n’S e $1 a chur am bacadh seo ort.\n’S e “<em>$2</em>” an t-adbhar a thug iad.\n\n* Toiseach a’ bhacaidh: $8\n* Deireadh a’ bhacaidh: $6\n* An neach air a bheil am bacadh: $7\n\n’S urrainn dhut fios a chur gu $1 no [[{{MediaWiki:Grouppage-sysop}}|rianaire]] eile gus am bacadh seo a dheasbad.\nChan urrainn dhut an gleus “Cuir post-d dhan chleachdaiche seo” a chleachdadh ach ma tha seòladh puist-d dligheach ann an [[Special:Preferences|roghainnean a’ chunntais agad]] agus mura deach bacadh a chur air a chleachdadh.\n’S e $3 an seòladh IP làithreach agus agus ’s e #$5 ID a’ bhacaidh.\nThoir iomradh air a’ mhion-fhiosrachadh gu h-àrd ma chuireas tu ceist sam bith mu dhèidhinn.",
        "autoblockedtext": "Chaidh an seòladh IP agad a bhacadh gu fèin-obrachail a chionn 's gun deach a chleachdadh le cuideigin eile a chaidh a bhacadh le $1.\n{{GENDER:$1|Thug e|Thug i|Thugadh}} an cèill gun do {{GENDER:$1|rinn e|rinn i|rinneadh}} sin air sgàth an adhbhair seo: \n\n:<em>$2</em>.\n\n* Toiseach a' bhacaidh: $8\n* Deireadh a' bhacaidh: $6\n* An neach air a bheil am bacadh: $7\n\n'S urrainn dhut fios a chur gu $1 no [[{{MediaWiki:Grouppage-sysop}}|rianair]] eile gus am bacadh seo a dheasbad.\n\nDh'fhaoidte nach urrainn dhut am feart \"Cuir post-d dhan chleachdaiche seo\" a chleachdadh ach ma tha seòladh puist-d dligheach ann an [[Special:Preferences|roghainnean a' chunntais agad]] agus mura deach bacadh a chur air a chleachdadh.\n\n'S e $3 an seòladh IP làithreach agus agus 's e #$5 ID a' bhacaidh.\nThoir iomradh air a' mhion-fhiosrachadh gu h-àrd ma chuireas tu ceist sam bith mu dhèidhinn.",
        "blockednoreason": "cha deach adhbhar a shònrachadh",
        "whitelistedittext": "Feumaidh tu $1 mus urrainn dhut duilleagan a dheasachadh.",
        "recentchanges-legend-heading": "<strong>Treòir:</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (faic [[Special:NewPages|liosta nan duilleagan ùra]] cuideachd)",
        "recentchanges-legend-plusminus": "(<em>±123</em>)",
+       "rcfilters-legend-heading": "<strong>Liosta nan giorrachaidhean:</strong>",
+       "rcfilters-activefilters": "Criathragan gnìomhach",
+       "rcfilters-activefilters-hide": "Falaich",
+       "rcfilters-limit-and-date-label": "$1 {{PLURAL:$1|mhùthadh|mhùthadh|mùthaidhean|mùthadh}}, $2",
+       "rcfilters-days-show-days": "$1 {{PLURAL:$1|latha|latha|làithean|latha}}",
+       "rcfilters-quickfilters": "Criathragan air an sàbhaladh",
+       "rcfilters-quickfilters-placeholder-title": "Cha do shàbhail thu criathrag fhathast",
+       "rcfilters-quickfilters-placeholder-description": "Gus roghainnean nan criathragan agad a shàbhaladh is an cleachdadh às ùr uaireigin eile, briog air ìomhaigheag a’ chomharra-lìn ann an raon na criathraige bheò gu h-ìosal.",
+       "rcfilters-savedqueries-defaultlabel": "Criathragan air an sàbhaladh",
+       "rcfilters-search-placeholder": "Criathraich na h-atharraichean (cleachd an clàr-taice no lorg ainm criathraige)",
+       "rcfilters-filterlist-whatsthis": "Ciamar a dh’obraicheas iad seo?",
+       "rcfilters-highlightbutton-title": "Soillsich toraidhean",
+       "rcfilters-filterlist-noresults": "Cha do lorg sinn criathrag",
+       "rcfilters-filter-editsbyself-label": "Mùthaidhean a rinn thusa",
+       "rcfilters-filter-editsbyself-description": "Na mùthaidhean a rinn thu fhèin.",
+       "rcfilters-filter-editsbyother-label": "Mùthaidhean a rinn daoine eile",
+       "rcfilters-filter-editsbyother-description": "Gach mùthadh ach an fheadhainn agad fhèin.",
+       "rcfilters-filtergroup-userExpLevel": "Clàradh is eòlas a’ chleachdaiche",
+       "rcfilters-filter-user-experience-level-registered-label": "Air clàradh a-steach",
+       "rcfilters-filter-user-experience-level-registered-description": "Deasaichean a rinn clàradh a-steach.",
+       "rcfilters-filter-user-experience-level-unregistered-label": "Gun chlàradh a-steach",
+       "rcfilters-filter-user-experience-level-unregistered-description": "Deasaichean nach do rinn clàradh a-steach.",
+       "rcfilters-filter-user-experience-level-newcomer-label": "Ùranaich",
+       "rcfilters-filter-user-experience-level-newcomer-description": "Deasaichean a chlàraich a-steach ach a rinn nas lugha na 10 deasachaidhean no aig a bheil nas lugha na 4 làithean de ghnìomhachd.",
+       "rcfilters-filter-user-experience-level-learner-label": "Luchd-ionnsachaidh",
+       "rcfilters-filter-user-experience-level-learner-description": "Deasaichean a rinn clàradh a-steach is aig a bheil eòlas eadar feadhainn air ùr-thighinn is feadhainn shàr-eòlach.",
+       "rcfilters-filter-user-experience-level-experienced-label": "Seann-eòlaich",
+       "rcfilters-filter-user-experience-level-experienced-description": "Deasaichean a chlàraich a-steach ach a rinn barrachd air 500 deasachadh is aig a bheil barrachd air 30 latha de ghnìomhachd.",
+       "rcfilters-filtergroup-automated": "Mùthaidhean fèin-obrachail",
+       "rcfilters-filter-bots-description": "Mùthaidhean a rinn innealan fèin-obrachail.",
+       "rcfilters-filter-humans-label": "Duine (chan e bot)",
+       "rcfilters-filter-humans-description": "Deasachaidhean a rinn deasaichean daonna.",
+       "rcfilters-filtergroup-significance": "Cudromachd",
+       "rcfilters-filter-minor-label": "Mùthaidhean beaga",
+       "rcfilters-filter-major-label": "Mùthaichean nach eil beag",
+       "rcfilters-filter-major-description": "Deasachaidhean ris nach eil comharra gur e deasachadh beag a tha ann.",
+       "rcfilters-filtergroup-watchlistactivity": "Gnìomhachd a’ chlàir-fhaire",
+       "rcfilters-filter-watchlistactivity-unseen-label": "Atharraichean gun choimhead",
+       "rcfilters-filter-watchlistactivity-unseen-description": "Atharraichean air duilleagan air nach do thadhail thu on a chaidh an atharrachadh.",
+       "rcfilters-filter-watchlistactivity-seen-label": "Atharraichean air coimhead",
+       "rcfilters-filter-watchlistactivity-seen-description": "Atharraichean air duilleagan air an do thadhail thu on a chaidh an atharrachadh.",
+       "rcfilters-filter-pageedits-label": "Deasachadh duilleige",
+       "rcfilters-filter-newpages-label": "Cruthachadh duilleige",
+       "rcfilters-filter-newpages-description": "Deasachadh a chruthaich duilleag ùr.",
+       "rcfilters-filter-logactions-label": "Gnìomhan logaichte",
+       "rcfilters-filtergroup-lastRevision": "Na mùthaidhean as ùire",
+       "rcfilters-filter-lastrevision-label": "Am mùthadh mu dheireadh",
+       "rcfilters-filter-lastrevision-description": "Dìreach an t-àtharrachadh as ùire air duilleag.",
+       "rcfilters-liveupdates-button": "Ùrachadh beò",
+       "rcfilters-liveupdates-button-title-off": "Seall atharraichean ùra fhad ’s a thathar gan dèanamh",
+       "rcfilters-watchlist-markseen-button": "Comharraich gun dug thu sùil air gach atharrachadh",
+       "rcfilters-watchlist-edit-watchlist-button": "Deasaich liosta nan duilleagan air a’ chlàr-fhaire agad",
+       "rcfilters-watchlist-showupdated": "Tha atharraichean air duilleagan nach do thadhail thu orra on a chaidh an atharrachadh ann an clò <strong>trom</strong> le comharran soladach.",
        "rcnotefrom": "Chì thu {{PLURAL:$5|am mùthadh|na mùthaidhean|na mùthaidhean|na mùthaidhean}} o <strong>$3 $4</strong> (gu ruige <strong>$1</strong> dhiubh) gu h-ìosal.",
        "rclistfrom": "Seall na mùthaidhean ùra a-mach o $3 $2",
        "rcshowhideminor": "$1 mùthaidhean beaga",
        "rcshowhidemine": "$1 na mùthaidhean agam",
        "rcshowhidemine-show": "Seall",
        "rcshowhidemine-hide": "Falaich",
+       "rcshowhidecategorization-hide": "Falaich",
        "rclinks": "Seall {{PLURAL:$1|an $1 mhùthadh|an $1 mhùthadh|na $1 mùthaidhean|am $1 mùthadh}} mu dheireadh thairis air {{PLURAL:$2|an $2 latha|an $2 latha|na $2 làithean|am $2 latha}} mu dheireadh",
        "diff": "diofar",
        "hist": "eachdr",
        "recentchangeslinked-feed": "Mùthaidhean buntainneach",
        "recentchangeslinked-toolbox": "Mùthaidhean buntainneach",
        "recentchangeslinked-title": "Mùthaidhean co-cheangailte ri \"$1\"",
-       "recentchangeslinked-summary": "Seo liosta nam mùthaidhean a chaidh a chur air duilleagan a tha a' ceangal o dhuilleag shònraichte (no ri buill ann an roinn-seòrsa sònraichte).\nTha duilleagan air a' [[Special:Watchlist|chlàr-fhaire]] agad ann an litrichean <strong>troma</strong>.",
+       "recentchangeslinked-summary": "Cuir a-steach ainm duilleige airson atharraichean fhaicinn air duilleagan a tha a’ ceangal ris an duilleag ud no uaipe. (Airson buill de roinn-seòrsa fhaicinn, cuir a-steach {{ns:category}}:Ainm roinn-seòrsa). Tha atharraichean air duilleagan a tha air a’ [[Special:Watchlist|chlàr-fhaire]] agad ann an clò <strong>trom</strong>.",
        "recentchangeslinked-page": "Ainm na duilleige:",
        "recentchangeslinked-to": "Seall mùthaidhean nan duilleagan a tha a' ceangal ris an duilleag sin 'na àite",
        "upload": "Luchdaich suas faidhle",
        "deadendpages": "Duilleagan cùile-dùinte",
        "deadendpagestext": "Cha dèan na duilleagan seo ceangal gu duilleag sam bith eile air {{SITENAME}}.",
        "protectedpages": "Duilleagan fo dhìon",
+       "protectedpages-filters": "Criathragan:",
        "protectedpages-indef": "Dìonan buana a-mhàin",
        "protectedpages-summary": "Chì thu na duilleagan a tha ann 's gan dìon an-seo. Faic [[{{#special:ProtectedTitles}}|{{int:protectedtitles}}]] airson liosta dhe na tiotalan a tha 'gan dìon o chruthachadh.",
        "protectedpages-cascade": "Dìonan o bhith mar eas a-mhàin",
        "unwatchthispage": "Na cum sùil tuilleadh",
        "notanarticle": "Chan e duilleag susbaint a tha ann",
        "notvisiblerev": "Chaidh am mùthadh mu dheireadh le cleachdaiche eile a sguabadh às",
-       "watchlist-details": "Tha {{PLURAL:$1|$1 duilleag|$1 dhuilleag|$1 duilleagan|$1 duilleag}} air a' chlàr-fhaire agad, gun luaidh air na duilleagan deasbaireachd.",
+       "watchlist-details": "Tha {{PLURAL:$1|$1 duilleag|$1 dhuilleag|$1 duilleagan|$1 duilleag}} air a’ chlàr-fhaire agad (agus duilleagan deasbaireachd a bharrachd air sin).",
        "wlheader-enotif": "Tha brathan-naidheachd air a' phost-d an comas.",
        "wlheader-showupdated": "Tha clò <strong>trom</strong> air duilleagan a chaidh atharrachadh on turas mu dheireadh a thadhail thu orra.",
        "wlnote": "Chì thu gu h-ìosal {{PLURAL:$1|a' $1 mhùthadh|an $1 mhùthadh|na $1 mùthaidhean|am $1 mùthadh}} mu dheireadh san {{PLURAL:$2|$2 uair a thìde|$2 uair a thìde|$2 uairean a thìde|$2 uair a thìde}} mu dheireadh, mar a bha e $3, $4.",
        "wlshowlast": "Seall na $1 uairean a thìde mu dheireadh $2 làithean mu dheireadh",
+       "watchlist-hide": "Falaich",
        "watchlist-options": "Roghainnean mo chlàir-faire",
        "watching": "'Ga chur air a' chlàr-fhaire...",
        "unwatching": "A' toirt far a' chlàir-fhaire...",
        "whatlinkshere": "Na tha a' ceangal a-nall an-seo",
        "whatlinkshere-title": "Duilleagan a tha a' ceangal ri \"$1\"",
        "whatlinkshere-page": "Duilleag:",
-       "linkshere-2": "Tha na duilleagan a leanas a' ceangal ri <strong>$1</strong>:",
-       "nolinkshere-2": "Chan eil ceangal air duilleag sam bith a tha a' dol gu <strong>$1</strong>.",
-       "nolinkshere-ns-2": "Chan eil ceangal gu <strong>$1</strong> ann an duilleag sam bith san ainm-spàs a thagh thu.",
+       "linkshere": "Tha na duilleagan a leanas a' ceangal ri <strong>$2</strong>:",
+       "nolinkshere": "Chan eil ceangal air duilleag sam bith a tha a' dol gu <strong>$2</strong>.",
+       "nolinkshere-ns": "Chan eil ceangal gu <strong>$2</strong> ann an duilleag sam bith san ainm-spàs a thagh thu.",
        "isredirect": "duilleag ath-sheòlaidh",
        "istemplate": "transclusion",
        "isimage": "ceangal faidhle",
        "markedaspatrollederrornotify": "Cha b' urrainn dhuinn comharra freiceadain a chur ris.",
        "patrol-log-page": "Loga nam freiceadan",
        "patrol-log-header": "Seo loga nam mùthaidhean le comharra freiceadain riutha.",
-       "log-show-hide-patrol": "$1 loga nam freiceadan",
        "deletedrevision": "Chaidh an seann mhùthadh $1 a sguabadh às",
        "filedeleteerror-short": "Mearachd a' sguabadh às an fhaidhle: $1",
        "filedeleteerror-long": "Thachair mearachd le sguabadh às an fhaidhle:\n\n$1",
index f584af6..3af4877 100644 (file)
        "cascadeprotected": "Esta páxina foi protexida fronte á edición debido a que está transcluída {{PLURAL:$1|na seguinte páxina protexida, que ten|nas seguintes páxinas protexidas, que teñen}} a \"protección en serie\" activada:\n$2",
        "namespaceprotected": "Non ten os permisos necesarios para modificar páxinas no espazo de nomes '''$1'''.",
        "customcssprotected": "Non ten os permisos necesarios para modificar esta páxina de CSS, dado que contén a configuración persoal doutro usuario.",
+       "customjsonprotected": "Non ten os permisos necesarios para modificar esta páxina JSON xa que contén a configuración persoal doutro usuario.",
        "customjsprotected": "Non ten os permisos necesarios para modificar esta páxina de JavaScript, dado que contén a configuración persoal doutro usuario.",
+       "sitecssprotected": "Non ten permiso para editar esta páxina CSS xa que pode afectar a tódolos visitantes",
+       "sitejsonprotected": "Non ten permiso para editar esta páxina JSON xa que pode afectar a tódolos visitantes",
+       "sitejsprotected": "Non ten permiso para editar esta páxina JavaScript xa que pode afectar a tódolos visitantes",
        "mycustomcssprotected": "Non ten os permisos necesarios para editar esta páxina de CSS.",
        "mycustomjsonprotected": "Non ten permisos para editar esta páxina JSON.",
        "mycustomjsprotected": "Non ten os permisos necesarios para editar esta páxina de JavaScript.",
        "botpasswords-restriction-failed": "Algunhas restricións de contrasinal de bots evitaron esta conexión.",
        "botpasswords-invalid-name": "O nome de usuario especificado non contén o separador de contrasinal de bot (\"$1\").",
        "botpasswords-not-exist": "O usuario \"$1\" non ten un contrasinal de bot de nome \"$2\".",
+       "botpasswords-needs-reset": "O contrasinal de bot para o bot de nome \"$2\" {{GENDER:$1|do usuario|da usuaria}} \"$1\" precisa ser definido de novo.",
        "resetpass_forbidden": "Non se poden mudar os contrasinais",
        "resetpass_forbidden-reason": "Os contrasinais non poden cambiarse: $1",
        "resetpass-no-info": "Debe rexistrarse para acceder directamente a esta páxina.",
        "resetpass-submit-loggedin": "Cambiar o contrasinal",
        "resetpass-submit-cancel": "Cancelar",
        "resetpass-wrong-oldpass": "O contrasinal temporal ou actual é incorrecto.\nPode ser que xa cambiase o seu contrasinal ou que solicitase un novo contrasinal temporal.",
-       "resetpass-recycled": "Cambie o seu contrasinal por un distinto do actual.",
+       "resetpass-recycled": "Por favor cambie o seu contrasinal por un distinto do actual.",
        "resetpass-temp-emailed": "Accedeu cun código temporal.\nPara completar o acceso, defina un novo contrasinal aquí:",
        "resetpass-temp-password": "Contrasinal temporal:",
        "resetpass-abort-generic": "Unha extensión cancelou a modificación do contrasinal.",
        "resetpass-expired": "O seu contrasinal caducou. Defina un novo contrasinal para acceder.",
-       "resetpass-expired-soft": "O seu contrasinal caducou e debe restablecelo. Escolla un novo contrasinal ou prema en \"{{int:authprovider-resetpass-skip-label}}\" para restablecelo máis tarde.",
-       "resetpass-validity-soft": "O seu contrasinal non é válido: $1\n\nEscolla un novo contrasinal agora ou prema en \"{{int:authprovider-resetpass-skip-label}}\" para restablecelo máis tarde.",
+       "resetpass-expired-soft": "O seu contrasinal caducou e debe mudalo. Escolla un novo contrasinal ou prema en \"{{int:authprovider-resetpass-skip-label}}\" para mudalo máis tarde.",
+       "resetpass-validity-soft": "O seu contrasinal non é válido: $1\n\nPor favor escolla un novo contrasinal agora, ou prema en \"{{int:authprovider-resetpass-skip-label}}\" para restablecelo máis tarde.",
        "passwordreset": "Restablecer o contrasinal",
        "passwordreset-text-one": "Encha este formulario para restablecer o seu contrasinal.",
        "passwordreset-text-many": "{{PLURAL:$1|Encha un dos campos para recibir por correo electrónico un contrasinal temporal.}}",
        "subject-preview": "Vista previa do asunto:",
        "previewerrortext": "Produciuse un erro ao intentar previsualizar os cambios.",
        "blockedtitle": "O usuario está bloqueado",
-       "blockedtext": "<strong>Bloqueouse o seu nome de usuario ou enderezo IP.</strong>\n\n$1 estableceu o bloqueo.\nO motivo que achegou foi <em>$2</em>.\n\n* Inicio do bloqueo: $8\n* Caducidade do bloqueo: $6\n* Pretendeuse bloquear: $7\n\nPode contactar con $1 ou con calquera outro [[{{MediaWiki:Grouppage-sysop}}|administrador]] para discutir este bloqueo.\nNon pode empregar a característica \"Enviar un correo electrónico a este usuario\" a non ser que dispoña dun enderezo electrónico válido rexistrado nas súas [[Special:Preferences|preferencias de usuario]] e que o seu uso non fose bloqueado.\nO seu enderezo IP actual é $3 e o identificador do bloqueo é #$5.\nPor favor, inclúa todos estes datos nas consultas que faga.",
-       "autoblockedtext": "O seu enderezo IP foi bloqueado automaticamente porque foi empregado por outro usuario que foi bloqueado por $1.\nA razón que deu foi a seguinte:\n\n:''$2''\n\n* Inicio do bloqueo: $8\n* Caducidade do bloqueo: $6\n* Pretendeuse bloquear: $7\n\nPode contactar con $1 ou con calquera outro [[{{MediaWiki:Grouppage-sysop}}|administrador]] para discutir este bloqueo.\n\nTeña en conta que non pode empregar a característica \"Enviar un correo electrónico a este usuario\" a non ser que dispoña dun enderezo electrónico válido rexistrado nas súas [[Special:Preferences|preferencias de usuario]] e e que o seu uso non fose bloqueado.\n\nO seu enderezo IP actual é $3 e o ID do bloqueo é #$5.\nPor favor, inclúa eses datos nas consultas que faga.",
+       "blockedtext": "<strong>Bloqueouse o seu nome de usuario ou enderezo IP.</strong>\n\n$1 estableceu o bloqueo.\nO motivo que achegou foi <em>$2</em>.\n\n* Inicio do bloqueo: $8\n* Caducidade do bloqueo: $6\n* Pretendeuse bloquear: $7\n\nPode contactar con $1 ou con calquera outro [[{{MediaWiki:Grouppage-sysop}}|administrador]] para discutir este bloqueo.\nNon pode empregar a característica \"{{int:emailuser}}\" a non ser que dispoña dun enderezo electrónico válido rexistrado nas súas [[Special:Preferences|preferencias de usuario]] e que o seu uso non fose bloqueado.\nO seu enderezo IP actual é $3 e o identificador do bloqueo é #$5.\nPor favor, inclúa todos estes datos nas consultas que faga.",
+       "autoblockedtext": "O seu enderezo IP foi bloqueado automaticamente porque foi empregado por outro usuario que foi bloqueado por $1.\nA razón que deu foi a seguinte:\n\n:<em>$2</em>\n\n* Inicio do bloqueo: $8\n* Caducidade do bloqueo: $6\n* Pretendeuse bloquear: $7\n\nPode contactar con $1 ou con calquera outro [[{{MediaWiki:Grouppage-sysop}}|administrador]] para discutir este bloqueo.\n\nTeña en conta que non pode empregar a característica \"{{int:emailuser}}\" a non ser que dispoña dun enderezo electrónico válido rexistrado nas súas [[Special:Preferences|preferencias de usuario]] e e que o seu uso non fose bloqueado.\n\nO seu enderezo IP actual é $3 e o ID do bloqueo é #$5.\nPor favor, inclúa eses datos nas consultas que faga.",
        "systemblockedtext": "O seu nome de usuario ou enderezo IP foi bloqueado automaticamente polo sistema MediaWiki.\nO motivo do bloqueo é:\n\n:<em>$2</em>\n\n* Comezo do bloqueo: $8\n* Expiración do bloqueo: $6\n* Destinatario do bloqueo: $7\n\nO seu enderezo IP actual é $3.\nPor favor, inclúa todos estes detalles en calquera consulta que realice.",
        "blockednoreason": "non se deu ningunha razón",
        "whitelistedittext": "Debe $1 para poder editar páxinas.",
        "expansion-depth-exceeded-warning": "A páxina supera a profundidade de expansión",
        "parser-unstrip-loop-warning": "Detectouse un bucle inamovible",
        "unstrip-depth-warning": "Excedeuse o límite de recursión inamovible ($1)",
+       "unstrip-depth-category": "Páxinas nas que se excede o límite de profundidade de eliminación de etiquetas",
+       "unstrip-size-warning": "Límite de profundidade de eliminación de etiquetas superado ($1)",
+       "unstrip-size-category": "Páxinas nas que se excede o límite de tamaño de eliminación de etiquetas",
        "converter-manual-rule-error": "Detectouse un erro na regra manual de conversión da lingua",
        "undo-success": "A edición pódese desfacer.\nComprobe a comparación que aparece a continuación para confirmar que isto é o que desexa facer; despois, garde os cambios para desfacer a edición.",
        "undo-failure": "Non se pode desfacer a edición debido a un conflito con algunha das edicións intermedias.",
+       "undo-main-slot-only": "A edición non puido desfacerse xa que implica contido que se atopa fóra da posición principal.",
        "undo-norev": "A edición non se pode desfacer porque non existe ou foi eliminada.",
        "undo-nochange": "Semella que alguén xa desfixo a edición.",
        "undo-summary": "Desfíxose a edición $1 de [[Special:Contributions/$2|$2]] ([[User talk:$2|conversa]])",
        "diff-paragraph-moved-toold": "Moveuse o parágrafo. Prema para saltar para á localización anterior.",
        "difference-missing-revision": "Non se {{PLURAL:$2|atopou revisión ningunha|atoparon $2 revisións}} desta diferenza ($1).\n\nA miúdo, isto está provocado por seguir unha ligazón de diferenzas obsoleta cara a unha páxina que foi borrada.\nO [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} rexistro de borrados] contén máis detalles.",
        "searchresults": "Resultados da procura",
+       "search-filter-title-prefix": "Procurando só nas páxinas cuxo título comeza con \"$1\"",
+       "search-filter-title-prefix-reset": "Procurar en tódalas páxinas",
        "searchresults-title": "Resultados da procura de \"$1\"",
        "titlematches": "O título da páxina coincide",
        "textmatches": "O texto da páxina coincide",
        "stub-threshold-disabled": "Desactivado",
        "recentchangesdays": "Número de días a mostrar nos cambios recentes:",
        "recentchangesdays-max": "Máximo: $1 {{PLURAL:$1|día|días}}",
-       "recentchangescount": "Número de edicións a mostrar por defecto:",
+       "recentchangescount": "Número de edicións a amosar por defecto nos cambios recentes, nos historiais de páxina e nos rexistrosː",
        "prefs-help-recentchangescount": "Número máximo: 1000",
        "prefs-help-watchlist-token2": "Esta é a clave secreta da fonte de novas web para a súa lista de vixilancia.\nCalquera persoa que a saiba poderá ler a súa lista de vixilancia; non comparta esta clave.\nSe o precisa, [[Special:ResetTokens|pode restablecela]].",
-       "prefs-help-tokenmanagement": "Podes ver e restaurar a chave secreta para a túa conta que pode acceder á fonte web da túa lista de vixiancia. Calquera que coñeza a chave poderá leer a túa lista de vixiancia.",
+       "prefs-help-tokenmanagement": "Podes ver e restaurar a chave secreta para a túa conta que pode acceder á fonte web da túa lista de vixiancia. Calquera que coñeza a chave poderá leer a túa lista de vixiancia, non a comparta.",
        "savedprefs": "Gardáronse as súas preferencias.",
        "savedrights": "Gardáronse os grupos de {{GENDER:$1|usuario|usuaria}} de $1.",
        "timezonelegend": "Fuso horario:",
        "group-autoconfirmed": "Usuarios autoconfirmados",
        "group-bot": "Bots",
        "group-sysop": "Administradores",
+       "group-interface-admin": "Administradores da interface",
        "group-bureaucrat": "Burócratas",
        "group-suppress": "Supresores",
        "group-all": "(todos)",
        "group-autoconfirmed-member": "{{GENDER:$1|usuario autoconfirmado|usuaria autoconfirmada}}",
        "group-bot-member": "{{GENDER:$1|bot}}",
        "group-sysop-member": "{{GENDER:$1|administrador|administradora}}",
+       "group-interface-admin-member": "{{GENDER:$1|administrador|administradora}} da interface",
        "group-bureaucrat-member": "{{GENDER:$1|burócrata}}",
        "group-suppress-member": "{{GENDER:$1|supresor|supresora}}",
        "grouppage-user": "{{ns:project}}:Usuarios",
        "grouppage-autoconfirmed": "{{ns:project}}:Usuarios autoconfirmados",
        "grouppage-bot": "{{ns:project}}:Bots",
        "grouppage-sysop": "{{ns:project}}:Administradores",
+       "grouppage-interface-admin": "{{ns:project}}:Administradores da interface",
        "grouppage-bureaucrat": "{{ns:project}}:Burócratas",
        "grouppage-suppress": "{{ns:project}}:Supresores",
        "right-read": "Ler páxinas",
        "right-editusercss": "Editar os ficheiros CSS doutros usuarios",
        "right-edituserjson": "Editar ficheiros JSON doutros usuarios",
        "right-edituserjs": "Editar os ficheiros JavaScript doutros usuarios",
+       "right-editsitecss": "Editar CSS global do sitio",
+       "right-editsitejson": "Editar JSON global do sitio",
+       "right-editsitejs": "Editar JavaScript global do sitio",
        "right-editmyusercss": "Editar os ficheiros CSS propios",
        "right-editmyuserjson": "Editar os ficheiros JSON do propio usuario",
        "right-editmyuserjs": "Editar os ficheiros JavaScript propios",
        "grant-createaccount": "Crear contas",
        "grant-createeditmovepage": "Crear, editar e mover páxinas",
        "grant-delete": "Borrar páxinas, revisións e entradas de rexistro",
-       "grant-editinterface": "Editar o espazo de nomes MediaWiki e o CSS/JSON/JavaScript de usuario",
+       "grant-editinterface": "Editar o espazo de nomes MediaWiki e o JSON de usuario e global do sitio",
        "grant-editmycssjs": "Editar o seu CSS/JSON/JavaScript de usuario",
        "grant-editmyoptions": "Editar as súas preferencias de usuario",
        "grant-editmywatchlist": "Editar a súa lista de vixilancia",
+       "grant-editsiteconfig": "Editar o CSS/JS de usuario e global do sitio",
        "grant-editpage": "Editar páxinas existentes",
        "grant-editprotected": "Editar páxinas protexidas",
        "grant-highvolume": "Edicións de gran volume",
        "rcfilters-other-review-tools": "Outras ferramentas de revisión",
        "rcfilters-group-results-by-page": "Agrupar resultados por páxina",
        "rcfilters-activefilters": "Filtros activos",
+       "rcfilters-activefilters-hide": "Agochar",
+       "rcfilters-activefilters-show": "Mostrar",
+       "rcfilters-activefilters-hide-tooltip": "Agochar a zona de filtros activos",
+       "rcfilters-activefilters-show-tooltip": "Amosar a zona de filtros activos",
        "rcfilters-advancedfilters": "Filtros avanzados",
        "rcfilters-limit-title": "Resultados a amosar",
        "rcfilters-limit-and-date-label": "$1 {{PLURAL:$1|cambio|cambios}}, $2",
        "rcfilters-empty-filter": "Non hai filtros activos. Móstranse tódalas contribucións.",
        "rcfilters-filterlist-title": "Filtros",
        "rcfilters-filterlist-whatsthis": "Como funciona isto?",
-       "rcfilters-filterlist-feedbacklink": "Coméntenos o que pensa sobre estas (novas) ferramentas de filtrado",
+       "rcfilters-filterlist-feedbacklink": "Coméntenos o que pensa sobre estas ferramentas de filtrado",
        "rcfilters-highlightbutton-title": "Resaltar resultados",
        "rcfilters-highlightmenu-title": "Seleccione unha cor",
        "rcfilters-highlightmenu-help": "Seleccione unha cor para resaltar esta propiedade",
        "rcfilters-filter-humans-label": "Humano (non bot)",
        "rcfilters-filter-humans-description": "Edicións realizadas por editores humanos.",
        "rcfilters-filtergroup-reviewstatus": "Estado de revisión",
+       "rcfilters-filter-reviewstatus-unpatrolled-description": "Edicións non marcadas como patrulladas nin manual nin automaticamente.",
        "rcfilters-filter-reviewstatus-unpatrolled-label": "Sen patrullar",
        "rcfilters-filter-reviewstatus-manual-description": "Edicións marcadas manualmente como vixiadas.",
        "rcfilters-filter-reviewstatus-manual-label": "Vixiadas manualmente",
        "rcfilters-watchlist-showupdated": "Os cambios feitos en páxinas que non visitou dende que se efectuaron aparecen en <strong>grosas</strong>, acompañados de marcadores sólidos.",
        "rcfilters-preference-label": "Ocultar a versión mellorada de cambios recentes",
        "rcfilters-preference-help": "Reverte o redeseño da interface de 2017 e tódalas ferramentas engadidas dende entón.",
+       "rcfilters-watchlist-preference-label": "Agochar a versión mellorada da lista de vixiancia",
+       "rcfilters-watchlist-preference-help": "Revirte o redeseño da interface de 2017 e tódalas ferramentas engadidas dende entón.",
        "rcfilters-filter-showlinkedfrom-label": "Amosar os cambios en páxinas ligadas desde",
        "rcfilters-filter-showlinkedfrom-option-label": "<strong>Páxinas ligadas desde</strong> a páxina seleccionada",
        "rcfilters-filter-showlinkedto-label": "Amosar os cambios en páxinas que ligan con",
        "recentchangeslinked-feed": "Cambios relacionados",
        "recentchangeslinked-toolbox": "Cambios relacionados",
        "recentchangeslinked-title": "Cambios relacionados con \"$1\"",
-       "recentchangeslinked-summary": "Introduce un nome de páxina para ver os cambios en páxinas ligadas dende ou ata esa páxina. (Para ver os membros dunha categoría, introduce Categoría:Nome da categoría). Os cambios na túa [[Special:Watchlist|lista de vixiancia]] están en <strong>negra</strong>.",
+       "recentchangeslinked-summary": "Introduce un nome de páxina para ver os cambios en páxinas ligadas dende ou ata esa páxina. (Para ver os membros dunha categoría, introduce {{ns:category}}:Nome da categoría). Os cambios na túa [[Special:Watchlist|lista de vixiancia]] están en <strong>negra</strong>.",
        "recentchangeslinked-page": "Nome da páxina:",
        "recentchangeslinked-to": "Mostrar os cambios relacionados das páxinas que ligan coa dada",
        "recentchanges-page-added-to-category": "\"[[:$1]]\" engadiuse á categoría",
        "uploadstash-zero-length": "O ficheiro ten tamaño cero.",
        "invalid-chunk-offset": "Desprazamento inválido do fragmento",
        "img-auth-accessdenied": "Acceso rexeitado",
-       "img-auth-nopathinfo": "Falta a PATH_INFO.\nO seu servidor non está configurado para pasar esta información.\nPode ser que estea baseado en CGI e non soporte img_auth.\nVéxase https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization.",
+       "img-auth-nopathinfo": "Falta a información da ruta.\nO seu servidor debe configurarse para pasar as variables REQUEST_URI e/ou PATH_INFO.\nSe o está, ténteo de novo activando $wgUsePathInfo.\nVexa https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization.",
        "img-auth-notindir": "A ruta solicitada non está no directorio de carga configurado.",
        "img-auth-badtitle": "Non é posible construír un título válido a partir de \"$1\".",
        "img-auth-nologinnWL": "Non accedeu ao sistema e \"$1\" non está na lista de branca.",
        "http-timed-out": "O pedido HTTP expirou.",
        "http-curl-error": "Ocorreu un erro ao acceder ao URL: $1",
        "http-bad-status": "Houbo un problema durante a solicitude HTTP: $1 $2",
+       "http-internal-error": "Erro interno do HTTP.",
        "upload-curl-error6": "Non se puido acceder ao enderezo URL",
        "upload-curl-error6-text": "Non se puido acceder ao enderezo URL especificado.\nComprobe que ese enderezo URL é correcto e que o sitio está activo.",
        "upload-curl-error28": "Rematou o tempo de espera da subida",
        "protectedtitles-submit": "Mostrar os títulos",
        "listusers": "Lista de usuarios",
        "listusers-editsonly": "Mostrar só os usuarios con edicións",
+       "listusers-temporarygroupsonly": "Amosar só usuarios en grupos de usuario temporais",
        "listusers-creationsort": "Ordenar por data de creación",
        "listusers-desc": "Ordenar de xeito descendente",
        "usereditcount": "$1 {{PLURAL:$1|edición|edicións}}",
        "apisandbox-dynamic-parameters-add-label": "Engadir un parámetro:",
        "apisandbox-dynamic-parameters-add-placeholder": "Nome do parámetro",
        "apisandbox-dynamic-error-exists": "Xa existe un parámetro co nome \"$1\".",
+       "apisandbox-templated-parameter-reason": "Este [[Special:ApiHelp/main#main/templatedparams|parámetro modelado]] ofrécese en base {{PLURAL:$1|ó valor|ós valores}} de $2.",
        "apisandbox-deprecated-parameters": "Parámetros obsoletos",
        "apisandbox-fetch-token": "Encher automaticamente o identificador",
        "apisandbox-add-multi": "Engadir",
        "speciallogtitlelabel": "Obxectivo (título ou \"{{ns:user}}:nome de usuario\" para un usuario):",
        "log": "Rexistros",
        "logeventslist-submit": "Amosar",
+       "logeventslist-more-filters": "Amosar rexistros adicionais:",
+       "logeventslist-patrol-log": "Rexistro de patrullas",
+       "logeventslist-tag-log": "Rexistro de etiquetas",
        "all-logs-page": "Todos os rexistros públicos",
        "alllogstext": "Vista combinada de todos os rexistros dipoñibles en {{SITENAME}}.\nPode precisar máis a vista seleccionando o tipo de rexistro, o nome do usuario ou o título da páxina afectada.",
        "logempty": "Non se atopou ningún elemento relacionado no rexistro.",
        "dellogpage": "Rexistro de borrados",
        "dellogpagetext": "A continuación atópase a lista cos borrados máis recentes.",
        "deletionlog": "rexistro de borrados",
+       "log-name-create": "Rexistro de creación de páxinas",
+       "log-description-create": "Debaixo está a lista das páxinas creadas máis recentemente.",
+       "logentry-create-create": "$1 {{GENDER:$2|creou}} a páxina $3",
        "reverted": "Volveuse a unha versión anterior",
        "deletecomment": "Motivo:",
        "deleteotherreason": "Outro motivo:",
        "uctop": "(última revisión)",
        "month": "Desde o mes de (e anteriores):",
        "year": "Desde o ano (e anteriores):",
+       "date": "Dende a data (e anteriores):",
        "sp-contributions-newbies": "Mostrar só as contribucións das contas de usuario novas",
        "sp-contributions-newbies-sub": "Contribucións dos usuarios novos",
        "sp-contributions-newbies-title": "Contribucións dos usuarios novos",
        "whatlinkshere": "Páxinas que ligan con esta",
        "whatlinkshere-title": "Páxinas que ligan con \"$1\"",
        "whatlinkshere-page": "Páxina:",
-       "linkshere-2": "As seguintes páxinas ligan con \"'''$1'''\":",
-       "nolinkshere-2": "Ningunha páxina liga con \"'''$1'''\".",
-       "nolinkshere-ns-2": "Ningunha páxina liga con \"'''$1'''\" no espazo de nomes elixido.",
+       "linkshere": "As seguintes páxinas ligan con <strong>$2</strong>:",
+       "nolinkshere": "Ningunha páxina liga con <strong>$2</strong>.",
+       "nolinkshere-ns": "Ningunha páxina liga con <strong>$2</strong> no espazo de nomes elixido.",
        "isredirect": "páxina redirixida",
        "istemplate": "inclusión",
        "isimage": "ligazón ao ficheiro",
        "group-bot.css": "/* O CSS que se coloque aquí afectará soamente aos bots */",
        "group-sysop.css": "/* O CSS que se coloque aquí afectará soamente aos administradores */",
        "group-bureaucrat.css": "/* O CSS que se coloque aquí afectará soamente aos burócratas */",
+       "common.json": "/* Calquera JSON que haxa aquí será cargado para todos os usuarios en tódalas cargas de páxinas. */",
        "common.js": "/* Calquera JavaScript que haxa aquí será cargado para todos os usuarios en cada páxina que vexan. */",
        "group-autoconfirmed.js": "/* Calquera JavaScript que haxa aquí será cargado soamente para os usuarios autoconfirmados */",
        "group-user.js": "/* Calquera código JavaScript escrito aquí cargarase para tódolos usuarios rexistrados */",
        "markedaspatrollederrornotify": "Erro ao marcar como revisada.",
        "patrol-log-page": "Rexistro de revisións patrulladas",
        "patrol-log-header": "Este é un rexistro das revisións patrulladas.",
-       "log-show-hide-patrol": "$1 o rexistro de patrullas",
-       "log-show-hide-tag": "$1 o rexistro de etiquetas",
        "confirm-markpatrolled-button": "Aceptar",
        "confirm-markpatrolled-top": "Quere marcar a revisión $3 de \"$2\" como patrullada?",
        "deletedrevision": "Revisión vella e borrada de \"$1\"",
        "limitreport-templateargumentsize-value": "$1/$2 {{PLURAL:$2|byte|bytes}}",
        "limitreport-expansiondepth": "Máxima profundidade de expansión",
        "limitreport-expensivefunctioncount": "Número de funcións analíticas custosas",
+       "limitreport-unstrip-depth": "Profundidade da recursividade de eliminación de etiquetas",
+       "limitreport-unstrip-size": "Tamaño trala expansión da eliminación de etiquetas",
        "limitreport-unstrip-size-value": "$1/$2 {{PLURAL:$2|byte|bytes}}",
        "expandtemplates": "Expandir os modelos",
        "expand_templates_intro": "Esta páxina especial toma texto wiki e expande todos os modelos dentro del recursivamente.\nTamén expande as funcións de análise como\n<code><nowiki>{{</nowiki>#language:…}}</code> e variables como\n<code><nowiki>{{</nowiki>CURRENTDAY}}</code>.\nDe feito, expande case calquera cousa entre dúas chaves.",
        "pagedata-title": "Datos da páxina",
        "pagedata-text": "Esta páxina porporciona unha interface de datos para páxinas. Por favor, proporcione o título da páxina na URL, usando a sintaxe de subpáxinas.\n* A negociación de contido aplícase baseándose na cabeceira Accept do seu cliente. Isto significa que os datos da páxina serán proporcionados no formato preferido polo seu cliente.",
        "pagedata-not-acceptable": "Non se atopou ningún formato correspondente. Tipos MIME soportadosː $1",
-       "pagedata-bad-title": "Título non válido: $1."
+       "pagedata-bad-title": "Título non válido: $1.",
+       "unregistered-user-config": "Por motivos de seguridade as subpáxinas de usuario JavaScript, CSS e JSON non se poden cargar para usuarios non rexistrados.",
+       "passwordpolicies": "Políticas de contrasinais",
+       "passwordpolicies-summary": "Esta é unha lista das políticas de contrasinais efectivas para os grupos de usuarios definidos nesta wiki.",
+       "passwordpolicies-group": "Grupo",
+       "passwordpolicies-policies": "Políticas",
+       "passwordpolicies-policy-minimalpasswordlength": "O contrasinal debe conter como mínimo $1 {{PLURAL:$1|carácter|caracteres}}",
+       "passwordpolicies-policy-minimumpasswordlengthtologin": "O contrasinal debe conter como mínimo $1 {{PLURAL:$1|carácter|caracteres}} para poder iniciar a sesión",
+       "passwordpolicies-policy-passwordcannotmatchusername": "O contrasinal non pode coincidir co nome de usuario",
+       "passwordpolicies-policy-passwordcannotmatchblacklist": "O contrasinal non pode coincidir con contrasinais incluidos na lista negra",
+       "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}}",
+       "easydeflate-invaliddeflate": "O contido fornecido non está debidamente comprimido"
 }
index f65948d..63a542e 100644 (file)
        "whatlinkshere": "هرچي خال ببؤ ائره",
        "whatlinkshere-title": "ولگؤني گه «$1»ˇ أمرأ خال دأنن",
        "whatlinkshere-page": "ولگ:",
-       "linkshere-2": "جيري ولگؤن '''$1'''ˇ أمرأ خال دأنن:",
+       "linkshere": "جيري ولگؤن '''$2'''ˇ أمرأ خال دأنن:",
        "isredirect": "تغييرمسيرˇ ولگ",
        "isimage": "فاىلˇ خال",
        "whatlinkshere-prev": "{{PLURAL:$1|قبلي|$1 قبلي مؤرد}}",
index 8b89f81..f40ff1e 100644 (file)
        "whatlinkshere": "हाका कितें जुळटा",
        "whatlinkshere-title": " \"$1\" हाका जोडणी आशिल्लीं पानां",
        "whatlinkshere-page": "पान:",
-       "linkshere-2": "मुखावेली पानां '''$1''': हाका जोडणी करतात",
-       "nolinkshere-2": "$1हाका खंयच्याच पानाची जोडणी ना",
+       "linkshere": "मुखावेली पानां '''$2''': हाका जोडणी करतात",
+       "nolinkshere": "$2हाका खंयच्याच पानाची जोडणी ना",
        "isredirect": "पुनर्निर्देशन पान",
        "istemplate": "$1 दूसरात-समावेस",
        "isimage": "फायलीचो दुवो",
index ff45698..4a36b53 100644 (file)
        "whatlinkshere": "Hanga kitem zoddta",
        "whatlinkshere-title": "\"$1\" haka zoddlelim panam",
        "whatlinkshere-page": "Pan:",
-       "linkshere-2": "Sokoilim panam <strong>$1</strong> ak zoddtat:",
-       "nolinkshere-2": "Khoincheim pan '''$1''' ak zoddna.",
+       "linkshere": "Sokoilim panam <strong>$2</strong> ak zoddtat:",
+       "nolinkshere": "Khoincheim pan '''$2''' ak zoddna.",
        "isredirect": "punornirdexon pan",
        "istemplate": "Durasth-somaves",
        "isimage": "failichem zoddop",
index e69303e..a5dd902 100644 (file)
@@ -7,7 +7,8 @@
                        "Matma Rex",
                        "NoiX180",
                        "Zhoelyakin",
-                       "Amire80"
+                       "Amire80",
+                       "Matěj Suchánek"
                ]
        },
        "tog-underline": "Garisiyi totibawa wumbuta",
        "hidden-category-category": "Dalala wanto-wanto'o",
        "category-subcat-count": "{{PLURAL:$2|Kategori boti woluwo subkategori|Kategori boti woluwo {{PLURAL:$1|subkategori|$1 subkategori}} lonto nga'amila $2.}}",
        "category-subcat-count-limited": "Kategori boti woluwo {{PLURAL:$1|subkategori|$1 subkategori}}",
-       "category-article-count": "{{PLURAL:$2|Kategori botiye o tuwango halaman.|Woluwo {{PLURAL:$|$1 halaman}} to delomo kategori, lonto $2 nga'amila.}}",
+       "category-article-count": "{{PLURAL:$2|Kategori botiye o tuwango halaman.|Woluwo {{PLURAL:$1|$1 halaman}} to delomo kategori, lonto $2 nga'amila.}}",
        "category-article-count-limited": "Kategori boti woluwo {{PLURAL:$1|halaman|$1 halaman}} to delomo kategori",
        "category-file-count": "{{PLURAL:$2|To kategori boti woluwo berkas {{PLURAL:$1|berkas|$1 berkas}} to delomo kategori, lonto nga'amila $2}}",
        "category-file-count-limited": "Woluwo {{PLURAL:$1|berkas|S1 berkas}} to delomo kategori.",
        "whatlinkshere": "Wumbuta",
        "whatlinkshere-title": "Halaman botiye o wumbuta ode \"$1\"",
        "whatlinkshere-page": "Halaman",
-       "linkshere-2": "Halaman botiye woluwo wumbuta ode <strong>$1<strong>:",
-       "nolinkshere-2": "Diya'a halaman wumbuta ode <strong>$1</strong>",
+       "linkshere": "Halaman botiye woluwo wumbuta ode <strong>$2<strong>:",
+       "nolinkshere": "Diya'a halaman wumbuta ode <strong>$2</strong>",
        "isredirect": "halaman pilobaleyalo",
        "istemplate": "tranklusi",
        "isimage": "wumbuta lo berkas",
index d1d4424..ca7c9e2 100644 (file)
                        "Amire80"
                ]
        },
+       "tog-underline": "𐌲𐌰𐍅𐌹𐍃𐌰𐌹𐍃 𐌿𐍆𐍃𐍄𐍂𐌹𐌺𐍃:",
        "tog-hideminor": "𐌰𐍆𐍆𐌹𐌻𐌷 𐌻𐌴𐌹𐍄𐌹𐌻𐍉𐍃 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍉𐍃 𐌰𐌽𐌳𐍅𐌰𐌹𐍂𐌸𐌰𐌹𐌶𐍉 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍉",
+       "tog-extendwatchlist": "𐌿𐍆𐍂𐌰𐌺𐌴𐌹 𐍅𐌹𐍄𐌰𐍅𐌹𐌺𐍉𐌽 𐌳𐌿 𐌱𐌰𐌽𐌳𐍅𐌾𐌰𐌽 𐌰𐌻𐌻𐍉𐍃 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍉𐍃, 𐌽𐌹 𐌸𐌰𐍄𐌰𐌹𐌽𐌴𐌹 𐌸𐍉𐍃 𐌰𐍆𐍄𐌿𐌼𐌹𐍃𐍄𐍉𐌽𐍃",
+       "tog-usenewrc": "𐌺𐌿𐌽𐌾𐌴 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍉𐍃 𐌰𐍆𐌰𐍂 𐌻𐌰𐌿𐌱𐌰 𐌹𐌽 𐌰𐍆𐍄𐌿𐌼𐌹𐍃𐍄𐌰𐌹𐌼 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐌹𐌼 𐌰𐌽𐌰 𐍅𐌹𐍄𐌰𐍅𐌹𐌺𐍉𐌽",
+       "tog-watchcreations": "𐌰𐌽𐌰𐌰𐌹𐌰𐌿𐌺 𐌻𐌰𐌿𐌱𐌰𐌽𐍃 𐌸𐌰𐌽𐌶𐌴𐌹 𐌹𐌺 𐍃𐌺𐌰𐍀𐌾𐌰 𐌾𐌰𐌷 𐍆𐌰𐌾𐌻𐌰 𐌸𐍉𐌴𐌹 𐌹𐌺 𐌹𐌽𐌽𐌰𐍄𐌱𐌰𐌹𐍂 𐌳𐌿 𐌼𐌴𐌹𐌽𐌰𐌹 𐍅𐌹𐍄𐌰𐍅𐌹𐌺𐍉𐌽",
+       "tog-watchdefault": "𐌰𐌽𐌰𐌰𐌹𐌰𐌿𐌺 𐌻𐌰𐌿𐌱𐌰𐌽𐍃 𐌾𐌰𐌷 𐍆𐌰𐌾𐌻𐌰 𐌸𐍉𐌴𐌹 𐌹𐌺 𐌹𐌽𐌼𐌰𐌹𐌳𐌾𐌰 𐌳𐌿 𐌼𐌴𐌹𐌽𐌰𐌹 𐍅𐌹𐍄𐌰𐍅𐌹𐌺𐍉𐌽",
+       "tog-watchmoves": "𐌱𐌹𐌰𐌹𐌰𐌿𐌺 𐌻𐌰𐌿𐌱𐌰𐌽𐍃 𐌾𐌰𐌷 𐍆𐌰𐌾𐌻𐌰 𐌸𐍉𐌴𐌹 𐌼𐌹𐌸𐍃𐌰𐍄𐌾𐌹𐍃 𐌳𐌿 𐌸𐌴𐌹𐌽𐌰𐌹 𐍅𐌹𐍄𐌰𐍅𐌹𐌺𐍉𐌽",
+       "tog-watchdeletion": "𐌰𐌽𐌰𐌰𐌹𐌰𐌿𐌺 𐌻𐌰𐌿𐌱𐌰𐌽𐍃 𐌾𐌰𐌷 𐍆𐌰𐌾𐌻𐌰 𐌸𐌰𐌹𐌼𐌴𐌹 𐌹𐌺 𐍆𐍂𐌰𐌵𐌹𐍃𐍄𐌾𐌰 𐌳𐌿 𐌼𐌴𐌹𐌽𐌰𐌹 𐍅𐌹𐍄𐌰𐍅𐌹𐌺𐍉𐌽",
+       "tog-watchuploads": "𐌱𐌹𐌰𐌹𐌰𐌿𐌺 𐌽𐌹𐌿𐌾𐌰 𐍆𐌰𐌾𐌻𐌰 𐌸𐍉𐌴𐌹 𐌹𐌺 𐌰𐍄𐌱𐌰𐌹𐍂𐌰 𐌳𐌿 𐌼𐌴𐌹𐌽𐌰𐌹 𐍅𐌹𐍄𐌰𐍅𐌹𐌺𐍉𐌽",
        "tog-previewontop": "𐌰𐌽𐌳𐌷𐌿𐌻𐌴𐌹 𐍆𐌰𐌿𐍂𐌰𐍃𐌹𐌿𐌽 𐍆𐌰𐌿𐍂𐌰 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐌹𐌰𐍂𐌺𐌰",
        "tog-previewonfirst": "𐌰𐌽𐌳𐌷𐌿𐌻𐌴𐌹 𐍆𐌰𐌿𐍂𐌰𐍃𐌹𐌿𐌽 𐌰𐍄 𐍆𐍂𐌿𐌼𐌹𐍃𐍄𐌰 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽",
+       "tog-enotifwatchlistpages": "𐍃𐌰𐌽𐌳𐌴𐌹 𐌼𐌹𐌺 𐌴-𐌱𐍉𐌺𐍉𐍃 𐌸𐌰𐌽 𐌻𐌰𐌿𐍆𐍃 𐌸𐌰𐌿 𐍆𐌰𐌾𐌻 𐌰𐌽𐌰 𐌼𐌴𐌹𐌽𐌰𐌹 𐍅𐌹𐍄𐌰𐍅𐌹𐌺𐍉𐌽 𐌹𐌽𐌼𐌰𐌹𐌳𐌾𐌰𐌳𐌰",
        "tog-enotifusertalkpages": "𐍃𐌰𐌽𐌳𐌴𐌹 𐌼𐌹𐌺 𐌴-𐌱𐍉𐌺𐍉𐍃 𐌾𐌰𐌱𐌰𐌹 𐌼𐌴𐌹𐌽𐍃 𐌻𐌰𐌿𐍆𐍃 𐌲𐌰𐍅𐌰𐌿𐍂𐌳𐌾𐌹𐍃 𐌹𐌽𐌼𐌰𐌹𐌳𐌾𐌰𐌳𐌰",
+       "tog-enotifminoredits": "𐌾𐌰𐌷 𐍃𐌰𐌽𐌳𐌴𐌹 𐌼𐌹𐌺 𐌴-𐌱𐍉𐌺𐍉𐍃 𐌼𐌹𐌽𐌽𐌹𐌶𐌴𐌹𐌼 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐌹𐌼 𐌻𐌰𐌿𐌱𐌴 𐌾𐌰𐌷 𐍆𐌰𐌾𐌻𐌴",
        "tog-shownumberswatching": "𐌰𐌽𐌳𐌷𐌿𐌻𐌴𐌹 𐍂𐌰𐌸𐌾𐍉𐌽 𐍅𐌹𐍄𐌰𐌽𐌳𐌰𐌹𐌶𐌴 𐌱𐍂𐌿𐌺𐌾𐌰𐌽𐌴",
        "tog-oldsig": "𐌸𐌴𐌹𐌽𐌰 𐍅𐌹𐍃𐌰𐌽𐌳𐌴𐌹 𐌿𐍆𐌼𐌴𐌻𐌴𐌹𐌽𐍃",
+       "tog-watchlisthideown": "𐌰𐍆𐍆𐌹𐌻𐌷 𐌼𐌴𐌹𐌽𐍉𐍃 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍉𐍃 𐍅𐌹𐍄𐌰𐍅𐌹𐌺𐍉𐌽𐍃",
+       "tog-watchlisthidebots": "𐌰𐍆𐍆𐌹𐌻𐌷 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍉𐍃 𐌱𐌰𐌿𐍄𐌴 𐍆𐍂𐌰𐌼 𐍅𐌹𐍄𐌰𐍅𐌹𐌺𐍉𐌽",
+       "tog-watchlisthideminor": "𐌰𐍆𐍆𐌹𐌻𐌷 𐌼𐌹𐌽𐌽𐌹𐌶𐌴𐌹𐌽𐍃 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍉𐍃 𐍅𐌹𐍄𐌰𐍅𐌹𐌺𐍉𐌽𐍃",
+       "tog-watchlisthideliu": "𐌰𐍆𐍆𐌹𐌻𐌷 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍉𐍃 𐌰𐍄𐌲𐌰𐌲𐌲𐌰𐌽𐌰𐌹𐌶𐌴 𐌱𐍂𐌿𐌺𐌾𐌰𐌽𐌴 𐍆𐍂𐌰𐌼 𐍅𐌹𐍄𐌰𐍅𐌹𐌺𐍉𐌽",
+       "tog-ccmeonemails": "𐍃𐌰𐌽𐌳𐌴𐌹 𐌼𐌹𐌺 𐌺𐌰𐌿𐍀𐌹𐍉𐍃 𐌴-𐌱𐍉𐌺𐍉 𐌸𐍉𐌶𐌴𐌹 𐌹𐌺 𐍃𐌰𐌽𐌳𐌾𐌰 𐌳𐌿 𐌰𐌽𐌸𐌰𐍂𐌰𐌹𐌼 𐌱𐍂𐌿𐌺𐌾𐌰𐌼",
+       "tog-showhiddencats": "𐌱𐌰𐌽𐌳𐍅𐌴𐌹 𐌰𐌽𐌰𐌻𐌰𐌿𐌲𐌽𐌰 𐌺𐌿𐌽𐌾𐌰",
+       "tog-useeditwarning": "𐍈𐍉𐍄𐌴𐌹 𐌼𐌹𐌺 𐌸𐌰𐌽 𐌹𐌺 𐌰𐍆𐌻𐌴𐌹𐌸𐌰 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐌹𐌻𐌰𐌿𐍆 𐌼𐌹𐌸 𐌿𐌽𐌲𐌰𐍆𐌰𐍃𐍄𐌰𐌽𐌰𐌹𐌼 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐌹𐌼",
+       "tog-prefershttps": "𐌱𐍂𐌿𐌺𐌴𐌹 𐍃𐌹𐌽𐍄𐌴𐌹𐌽𐍉 𐌰𐍂𐍅𐌾𐌰𐌹𐌶𐍉𐍃 𐌲𐌰𐍅𐌹𐍃𐌰𐌹𐍃 𐌸𐌰𐌽 𐌰𐍄𐌹𐌳𐌳𐌾𐌰",
        "underline-always": "𐍃𐌹𐌽𐍄𐌴𐌹𐌽𐍉",
        "underline-never": "𐌽𐌹 𐌰𐌹𐍅",
+       "editfont-sansserif": "𐍃𐌰𐌽𐍃-𐍃𐌰𐌹𐍂𐌹𐍆 𐍆𐌰𐌿𐌽𐍄",
+       "editfont-serif": "𐍃𐌰𐌹𐍂𐌹𐍆 𐍆𐌰𐌿𐌽𐍄",
        "sunday": "𐌰𐍆𐌰𐍂𐍃𐌰𐌱𐌱𐌰𐍄𐍉",
        "monday": "𐌼𐌴𐌽𐌹𐌽𐍃 𐌳𐌰𐌲𐍃",
        "tuesday": "𐍄𐌴𐌹𐍅𐌹𐍃 𐌳𐌰𐌲𐍃",
@@ -74,6 +94,7 @@
        "february-date": "𐍆𐌰𐌹𐌱𐍂𐌿𐌰𐍂𐌴𐌹𐍃 $1",
        "march-date": "𐌼𐌰𐍂𐍄𐌹𐌿𐍃 $1",
        "april-date": "𐌰𐍀𐍂𐌹𐌻𐌹𐍃 $1",
+       "may-date": "𐌼𐌰𐌹𐌿𐍃 $1",
        "september-date": "𐍃𐌰𐌹𐍀𐍄𐌰𐌹𐌼𐌱𐌰𐌹𐍂 $1",
        "november-date": "𐌽𐌰𐌿𐌱𐌰𐌹𐌼𐌱𐌰𐌹𐍂 $1",
        "pagecategories": "{{PLURAL:$1|𐌺𐌿𐌽𐌹|𐌺𐌿𐌽𐌾𐌰}}",
        "category-subcat-count": "{{PLURAL:$2|𐌸𐌰𐍄𐌰 𐌺𐌿𐌽𐌹 𐌷𐌰𐌱𐌰𐌹𐌸 𐌸𐌰𐍄𐌴𐌹𐌽𐌴𐌹 𐌹𐍆𐍄𐌿𐌼 𐌼𐌹𐌽𐌽𐌹𐌶𐍉𐌽 𐌺𐌿𐌽𐌹|𐌸𐌰𐍄𐌰 𐌺𐌿𐌽𐌹 𐌷𐌰𐌱𐌰𐌹𐌸 {{PLURAL:$1|𐌼𐌹𐌽𐌽𐌹𐌶𐍉𐌽 𐌺𐌿𐌽𐌹|𐌹𐍆𐍄𐌿𐌼𐌰 $1 𐌼𐌹𐌽𐌽𐌹𐌶𐍉𐌽𐌰 𐌺𐌿𐌽𐌾𐌰}}, 𐌰𐌻𐌻𐌰𐌹𐌶𐌴 $2 𐌺𐌿𐌽𐌾𐌴.}}",
        "category-subcat-count-limited": "𐌸𐌰𐍄𐌰 𐌺𐌿𐌽𐌹 𐌷𐌰𐌱𐌰𐌹𐌸 𐌹𐍆𐍄𐌿𐌼𐍉𐌽/𐌹𐍆𐍄𐌿𐌼𐍉𐌽𐌰\n{{PLURAL:$1|𐌼𐌹𐌽𐌽𐌹𐌶𐍉𐌽 𐌺𐌿𐌽𐌹|$1 𐌼𐌹𐌽𐌽𐌹𐌶𐍉𐌽𐌰 𐌺𐌿𐌽𐌾𐌰}}.",
        "category-article-count": "{{PLURAL:$2|𐌸𐌰𐍄𐌰 𐌺𐌿𐌽𐌹 𐌷𐌰𐌱𐌰𐌹𐌸 𐌸𐌰𐍄𐌰𐌹𐌽𐌴𐌹 𐌹𐍆𐍄𐌿𐌼𐌰𐌽 𐌻𐌰𐌿𐍆.|𐌹𐍆𐍄𐌿𐌼𐌰(𐌽𐍃) {{PLURAL:$1|𐌻𐌰𐌿𐍆𐍃 𐌹𐍃𐍄|$1 𐌻𐌰𐌿𐌱𐍉𐍃 𐍃𐌹𐌽𐌳}} 𐌹𐌽 𐌸𐌰𐌼𐌼𐌰 𐌺𐌿𐌽𐌾𐌰, 𐌰𐌻𐌻𐌰𐌹𐌶𐌴 $2 𐌻𐌰𐌿𐌱𐌴.}}",
+       "category-article-count-limited": "{{PLURAL:$1|𐌹𐍆𐍄𐌿𐌼𐍃 𐌻𐌰𐌿𐍆𐍃 𐌹𐍃𐍄|$1 𐌹𐍆𐍄𐌿𐌼𐌰𐌹 𐌻𐌰𐌿𐌱𐍉𐍃 𐍃𐌹𐌽𐌳}} 𐌹𐌽 𐌰𐌽𐌳𐍅𐌰𐌹𐍂𐌸𐌰𐌼𐌼𐌰 𐌺𐌿𐌽𐌾𐌰.",
+       "category-file-count": "{{PLURAL:$2|𐌸𐌰𐍄𐌰 𐌺𐌿𐌽𐌹 𐌷𐌰𐌱𐌰𐌹𐌸 𐌸𐌰𐍄𐌰𐌹𐌽𐌴𐌹 𐌹𐍆𐍄𐌿𐌼 𐍆𐌰𐌾𐌻.|𐌹𐍆𐍄𐌿𐌼𐍉(𐌽𐌰) {{PLURAL:$1|𐍆𐌰𐌾𐌻 𐌹𐍃𐍄|$1 𐍆𐌰𐌾𐌻𐌰 𐍃𐌹𐌽𐌳}} 𐌹𐌽 𐌸𐌰𐌼𐌼𐌰 𐌺𐌿𐌽𐌾𐌰, 𐌰𐌻𐌻𐌰𐌹𐌶𐌴 $2 𐌻𐌰𐌿𐌱𐌴.}}",
+       "broken-file-category": "𐌻𐌰𐌿𐌱𐍉𐍃 𐌼𐌹𐌸 𐌱𐍂𐌹𐌺𐌰𐌽𐌰𐌹𐌼 𐍆𐌰𐌾𐌻𐌰𐌲𐌰𐍅𐌹𐍃𐍃𐌹𐌼",
        "about": "𐌱𐌹",
        "article": "𐌷𐌰𐌱𐌰𐌽𐌳𐍃 𐌻𐌰𐌿𐍆𐍃",
        "newwindow": "(𐌿𐍃𐌻𐌿𐌺𐌹𐌸 𐌹𐌽 𐌽𐌹𐌿𐌾𐌰𐌼𐌼𐌰 𐌰𐌿𐌲𐌰𐌳𐌰𐌿𐍂𐌹𐌽)",
        "cancel": "𐍃𐍅𐌴𐌹𐌱",
        "moredotdotdot": "𐌼𐌰𐌹𐍃...",
+       "morenotlisted": "𐍃𐍉 𐍅𐌹𐌺𐍉 𐌼𐌰𐌲 𐍅𐌹𐍃𐌰𐌽 𐌿𐌽𐌲𐌰𐍆𐌰𐌿𐍂𐌳𐌰.",
        "mypage": "𐌻𐌰𐌿𐍆𐍃",
        "mytalk": "𐌲𐌰𐍅𐌰𐌿𐍂𐌳𐌹",
+       "anontalk": "𐌲𐌰𐍅𐌰𐌿𐍂𐌳𐌹",
        "navigation": "𐌻𐌰𐌿𐌱𐌰𐌲𐌰𐍅𐌹𐍃𐍃𐌴𐌹𐍃",
        "and": "𐌾𐌰𐌷",
+       "faq": "𐍆𐌹𐌻𐌿 𐍆𐍂𐌰𐌹𐌷𐌽𐌰𐌽𐍉𐍃 𐌱𐌹𐌳𐍉𐍃",
        "actions": "𐍄𐍉𐌾𐌰",
        "namespaces": "𐌽𐌰𐌼𐌰𐍂𐌿𐌼𐌰",
        "variants": "𐌼𐌹𐍃𐍃𐌰𐌻𐌴𐌹𐌺",
+       "navigation-heading": "𐌱𐌰𐌿𐍄𐌰",
        "errorpagetitle": "𐌰𐌹𐍂𐌶𐌴𐌹",
        "returnto": "𐌲𐌰𐍅𐌰𐌽𐌳𐌴𐌹 𐌳𐌿 $1.",
        "tagline": "𐍆𐍂𐌰𐌼 {{SITENAME}}",
        "history": "𐌻𐌰𐌿𐌱𐌰𐍃𐍀𐌹𐌻𐌻",
        "history_short": "𐍃𐍀𐌹𐌻𐌻",
        "history_small": "𐍃𐍀𐌹𐌻𐌻",
+       "updatedmarker": "𐌰𐌽𐌰𐌽𐌹𐌿𐌾𐌹𐌸𐍃 𐍆𐍂𐌰𐌼 𐌰𐍆𐍄𐌿𐌼𐌹𐍃𐍄𐌰𐌼𐌼𐌰 𐍃𐌹𐌽𐌸𐌰 𐌸𐌰𐍄𐌴𐌹 𐌹𐌺 𐌲𐌰𐍅𐌴𐌹𐍃𐍉𐌳𐌰 𐌸𐌹𐍃 𐌻𐌰𐌿𐌱𐌹𐍃",
        "printableversion": "𐌿𐍃𐌼𐌴𐍂𐌴𐌹𐌽𐍃 𐌳𐌿 𐌿𐍃𐌼𐌴𐌻𐌾𐌰𐌽",
        "permalink": "𐌰𐌹𐍅𐌴𐌹𐌽𐌰 𐌲𐌰𐍅𐌹𐍃𐍃",
        "print": "𐌿𐍃𐌼𐌴𐌻𐌴𐌹",
        "view": "𐍃𐌰𐌹𐍈",
        "view-foreign": "𐍃𐌰𐌹𐍈 𐌰𐌽𐌰 $1",
        "edit": "𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹",
+       "edit-local": "𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹 𐍃𐍄𐌰𐌳𐌹𐍃 𐍃𐌺𐌴𐌹𐍂𐌴𐌹𐌽",
        "create": "𐍃𐌺𐌰𐍀𐌴𐌹",
+       "create-local": "𐌰𐌽𐌰𐌰𐌹𐌰𐌿𐌺 𐍃𐍄𐌰𐌳𐌹𐍃 𐍃𐌺𐌴𐌹𐍂𐌴𐌹𐌽",
        "delete": "𐍆𐍂𐌰𐌵𐌹𐍃𐍄𐌴𐌹",
        "protect": "𐍆𐍂𐌹𐌸",
        "protect_change": "𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹",
        "talk": "𐌲𐌰𐍅𐌰𐌿𐍂𐌳𐌹",
        "views": "𐍃𐌹𐌿𐌽𐌴𐌹𐍃",
        "toolbox": "𐍃𐌰𐍂𐍅𐌰𐌽𐍃",
+       "tool-link-emailuser": "𐍃𐌰𐌽𐌳𐌴𐌹 𐌴-𐌱𐍉𐌺𐍉𐍃 𐌳𐌿 {{GENDER:$1|𐌼𐌰𐌽𐌽}}",
+       "imagepage": "𐌱𐌰𐌽𐌳𐍅𐌴𐌹 𐍆𐌰𐌾𐌻𐌰𐌻𐌰𐌿𐍆",
        "mediawikipage": "𐌰𐌽𐌳𐌷𐌿𐌻𐌴𐌹 𐍅𐌰𐌿𐍂𐌳𐌰𐌻𐌰𐌿𐍆",
        "viewhelppage": "𐌰𐌽𐌳𐌷𐌿𐌻𐌴𐌹 𐌷𐌹𐌻𐍀𐌰𐌻𐌰𐌿𐍆",
+       "categorypage": "𐍃𐌰𐌹𐍈 𐌺𐌿𐌽𐌾𐌰𐌻𐌰𐌿𐍆",
+       "viewtalkpage": "𐌱𐌰𐌽𐌳𐍅𐌴𐌹 𐌲𐌰𐍅𐌰𐌿𐍂𐌳𐌾𐌰",
        "otherlanguages": "𐌰𐌽𐌸𐌰𐍂𐌰𐌹𐌼 𐍂𐌰𐌶𐌳𐍉𐌼",
        "redirectedfrom": "(𐌹𐍃 {{GENDER:𐍄𐌹𐌿𐌷𐌰𐌽𐍃|𐍄𐌹𐌿𐌷𐌰𐌽𐌰}} 𐌷𐌹𐌳𐍂𐌴 𐍆𐍂𐌰𐌼 $1)",
        "redirectpagesub": "𐌰𐌻𐌾𐌰𐍂 𐌱𐍂𐌹𐌲𐌲𐌰𐌽𐌳𐍃 𐌻𐌰𐌿𐍆𐍃",
-       "lastmodifiedat": "𐍃𐌰 𐌻𐌰𐌿𐍆𐍃 𐌸𐌰𐍄𐌰 𐌰𐍆𐍄𐌿𐌼𐌹𐍃𐍄 𐌹𐌽𐌼𐌰𐌹𐌳𐌹𐌸𐍃 𐍅𐌰𐍃 ($1) ($2).",
+       "lastmodifiedat": "𐍃𐌰 𐌻𐌰𐌿𐍆𐍃 𐌸𐌰𐍄𐌰 𐌰𐍆𐍄𐌿𐌼𐌹𐍃𐍄 𐌹𐌽𐌼𐌰𐌹𐌳𐌹𐌸𐍃 𐍅𐌰𐍃 $1, 𐌰𐍄 $2.",
+       "viewcount": "𐍃𐌰 𐌻𐌰𐌿𐍆𐍃 𐌰𐍄𐌲𐌰𐌲𐌲𐌰𐌽𐍃 𐌹𐍃𐍄 {{PLURAL:$1|𐌰𐌹𐌽𐌰𐌼𐌼𐌰 𐍃𐌹𐌽𐌸𐌰|$1 𐍃𐌹𐌽𐌸𐌰𐌼}}.",
        "protectedpage": "𐍆𐍂𐌹𐌸𐍉𐌽𐍃 𐌻𐌰𐌿𐍆𐍃",
        "jumpto": "𐌲𐌰𐌲𐌲 𐌳𐌿:",
        "jumptonavigation": "𐌻𐌰𐌿𐌱𐌰𐌲𐌰𐍅𐌹𐍃𐍃𐌴𐌹𐍃",
        "jumptosearch": "𐍃𐍉𐌺𐌴𐌹",
+       "view-pool-error": "𐌰𐍆𐌻𐌴𐍄 𐌿𐌽𐍃, 𐍃𐌺𐌰𐌻𐌺𐌹𐌽𐍉𐌽𐌳𐍃 𐌽𐌿 𐌿𐍆𐌰𐍂𐍆𐌹𐌻𐌿 𐌱𐍂𐌿𐌷𐍄𐌹𐌳𐌰𐌹 𐍃𐌹𐌽𐌳. 𐌿𐍆𐌰𐍂𐍆𐌹𐌻𐌿 𐌱𐍂𐌿𐌺𐌾𐌰𐌽𐌳𐌴 𐍃𐍉𐌺𐌾𐌰𐌽𐌳 𐌳𐌿 𐌱𐌰𐌽𐌳𐍅𐌾𐌰𐌽 𐌸𐌰𐌽𐌰 𐌻𐌰𐌿𐍆. 𐌱𐌹𐌳𐌾𐌰𐌼 𐌸𐌿𐌺, 𐌱𐌴𐌹𐌳 𐌻𐌰𐌲𐌲𐌹𐍃 𐌼𐌴𐌻𐌹𐍃 𐍆𐌰𐌿𐍂𐌸𐌹𐌶𐌴𐌹 𐌰𐍆𐍄𐍂𐌰 𐍃𐍉𐌺𐌾𐌰𐌹𐍃 𐌳𐌿 𐌰𐍄𐌲𐌰𐌲𐌲𐌰𐌽 𐌰𐌽𐌰 𐌸𐌰𐌼𐌼𐌰 𐌻𐌰𐌿𐌱𐌰. \n\n$1",
        "pool-errorunknown": "𐌽𐌰𐍃𐌴𐌹 𐌸𐌰𐌽𐌰 𐌻𐌰𐌿𐍆",
+       "poolcounter-usage-error": "𐌱𐍂𐌿𐌺𐌴𐌹𐌽𐌰𐌹𐍃 𐌰𐌹𐍂𐌶𐌴𐌹: $1",
        "aboutsite": "𐌱𐌹 {{SITENAME}}",
        "aboutpage": "Project:𐌱𐌹",
        "copyrightpage": "{{ns:project}}:𐌱𐍂𐌿𐌺𐌴𐌹𐌽𐌹𐍂𐌰𐌹𐌷𐍄𐌴𐌹𐍃",
        "helppage-top-gethelp": "𐌷𐌹𐌻𐍀𐌰",
        "mainpage": "𐌰𐌽𐌰𐍃𐍄𐍉𐌳𐌴𐌹𐌽𐌹𐌻𐌰𐌿𐍆𐍃",
        "mainpage-description": "𐌰𐌽𐌰𐍃𐍄𐍉𐌳𐌴𐌹𐌽𐌹𐌻𐌰𐌿𐍆𐍃",
+       "policy-url": "Project:𐌲𐌰𐍂𐌰𐌹𐌳𐌴𐌹𐌽𐍉𐍃",
        "portal": "𐌲𐌰𐌵𐌿𐌼𐌸𐍃 𐌲𐌰𐌼𐌰𐌹𐌽𐌳𐌿𐌸𐌰𐌹𐍃",
        "portal-url": "Project:𐌲𐌰𐌵𐌿𐌼𐌸𐍃 𐌲𐌰𐌼𐌰𐌹𐌽𐌳𐌿𐌸𐌰𐌹𐍃",
        "privacy": "𐍃𐌿𐌽𐌳𐍂𐌰𐌻𐌴𐌹𐌺𐌴𐌹𐌽𐍃 𐌲𐌰𐍂𐌰𐌹𐌳𐌴𐌹𐌽𐍉𐍃",
        "privacypage": "Project:𐍃𐌿𐌽𐌳𐍂𐌰𐌻𐌴𐌹𐌺𐌴𐌹𐌽𐍃 𐌲𐌰𐍂𐌰𐌹𐌳𐌴𐌹𐌽𐍉𐍃",
+       "badaccess": "𐌰𐌽𐌳𐌻𐌴𐍄𐌹𐍃 𐌰𐌹𐍂𐌶𐌴𐌹",
+       "badaccess-group0": "𐌽𐌹𐍃𐍄 𐌰𐌽𐌳𐌻𐌴𐍄 𐌸𐌿𐍃 𐌳𐌿 𐌿𐍃𐍄𐌹𐌿𐌷𐌰𐌽 𐍄𐌰𐌿𐌹 𐌸𐌰𐍄𐌴𐌹 𐌸𐌿 𐍅𐌹𐌻𐌳𐌴𐍃.",
+       "badaccess-groups": "𐍄𐌰𐌿𐌹 𐌸𐌰𐍄𐌴𐌹 𐌸𐌿 𐍅𐌹𐌻𐌳𐌴𐍃 𐌹𐍃𐍄 𐌼𐌰𐍂𐌺𐍉𐌸 𐌱𐍂𐌿𐌺𐌾𐌰𐌽𐌳𐌰𐌼 𐌹𐌽 {{PLURAL:$2|𐌺𐌿𐌽𐌾𐌰|𐌰𐌹𐌽𐌰𐌼𐌼𐌰 𐌺𐌿𐌽𐌾𐌴}}: $1.",
+       "versionrequired": "𐌿𐍃𐌼𐌴𐍂𐌾𐌰 $1 𐌼𐌰𐌹𐌳𐌾𐌰𐍅𐌹𐌺𐌾𐌹𐍃 𐍃𐌺𐌿𐌻𐌳 𐌹𐍃𐍄",
        "retrievedfrom": "𐌲𐌰𐌽𐌿𐌼𐌰𐌽 𐍆𐍂𐌰𐌼 \"$1\"",
        "youhavenewmessages": "{{PLURAL:$3|𐌷𐌰𐌱𐌰𐌹𐍃}} $1 ($2).",
+       "youhavenewmessagesmanyusers": "𐌷𐌰𐌱𐌰𐌹𐍃 $1 𐌼𐌰𐌽𐌰𐌲𐌰𐌹𐌶𐌴 𐌱𐍂𐌿𐌺𐌾𐌰𐌽𐌳𐌴 ($2).",
        "newmessageslinkplural": "{{PLURAL:$1|𐌽𐌹𐍅𐌹 𐍅𐌰𐌿𐍂𐌳|999=𐌽𐌹𐌿𐌾𐌰 𐍅𐌰𐌿𐍂𐌳𐌰}}",
        "newmessagesdifflinkplural": "𐌰𐍆𐍄𐌿𐌼𐌹𐍃𐍄𐌰/𐌰𐍆𐍄𐌿𐌼𐌹𐍃𐍄𐍉𐍃 {{PLURAL:$1|𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍃|999=𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍉𐍃}}",
        "youhavenewmessagesmulti": "𐌷𐌰𐌱𐌰𐌹𐍃 𐌽𐌹𐌿𐌾𐌰 𐍅𐌰𐌿𐍂𐌳𐌰 𐌰𐌽𐌰 $1",
        "toc": "𐌹𐌽𐌽𐌰𐌽𐌰",
        "showtoc": "𐌰𐍄𐌰𐌿𐌲𐌴𐌹",
        "hidetoc": "𐌰𐍆𐍆𐌹𐌻𐌷",
+       "collapsible-expand": "𐌿𐍆𐌸𐌰𐌽𐌴𐌹",
        "confirmable-confirm": "𐌹𐍃 {{GENDER:$1:𐌸𐌿}} 𐌰𐍂𐌽𐌹𐌱𐌰?",
        "confirmable-yes": "𐌾𐌰",
        "confirmable-no": "𐌽𐌴",
+       "thisisdeleted": "𐌱𐌰𐌽𐌳𐍅𐌴𐌹 𐌸𐌰𐌿 𐌲𐌰𐌵𐌹𐌿𐌾𐌰𐌽 $1?",
+       "viewdeleted": "𐌱𐌰𐌽𐌳𐍅𐌴𐌹 $1?",
+       "restorelink": "{{PLURAL:$1|𐌰𐌹𐌽𐌰 𐍆𐍂𐌰𐌵𐌹𐍃𐍄𐌹𐌳𐌰 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍃|$1 𐍆𐍂𐌰𐌵𐌹𐍃𐍄𐌹𐌳𐍉𐍃 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍉𐍃}}",
        "site-rss-feed": "$1 RSS 𐍂𐌹𐌽𐌽𐍉",
        "site-atom-feed": "$1 𐌰𐍄𐌰𐌿𐌼 𐍂𐌹𐌽𐌽𐍉",
        "page-atom-feed": "\"$1\" 𐌰𐍄𐌰𐌿𐌼 𐍂𐌹𐌽𐌽𐍉",
        "red-link-title": "$1 (𐌻𐌰𐌿𐍆𐍃 𐌽𐌹𐍃𐍄)",
        "nstab-main": "𐌻𐌰𐌿𐍆𐍃",
        "nstab-user": "𐌱𐍂𐌿𐌺𐌾𐌰𐌽𐌳𐌹𐍃 𐌻𐌰𐌿𐍆𐍃",
+       "nstab-media": "𐌼𐌰𐌹𐌳𐌾𐌰𐌻𐌰𐌿𐍆𐍃",
        "nstab-special": "𐌿𐍃𐍃𐌹𐌽𐌳𐍃 𐌻𐌰𐌿𐍆𐍃",
        "nstab-project": "𐍆𐌰𐌿𐍂𐌰𐍅𐌰𐌿𐍂𐍀𐌰𐌻𐌰𐌿𐍆𐍃",
        "nstab-image": "𐍆𐌰𐌾𐌻",
        "nstab-help": "𐌷𐌹𐌻𐍀𐌰𐌻𐌰𐌿𐍆𐍃",
        "nstab-category": "𐌺𐌿𐌽𐌹",
        "mainpage-nstab": "𐌰𐌽𐌰𐍃𐍄𐍉𐌳𐌴𐌹𐌽𐌹𐌻𐌰𐌿𐍆𐍃",
+       "nosuchaction": "𐍃𐍅𐌰𐌻𐌴𐌹𐌺 𐍄𐌰𐌿𐌹 𐌽𐌹𐍃𐍄",
        "nosuchspecialpage": "𐌽𐌹𐍃𐍄 𐍃𐍅𐌰𐌻𐌴𐌹𐌺𐍃 𐌿𐍃𐍃𐌹𐌽𐌳𐍃 𐌻𐌰𐌿𐍆𐍃",
        "error": "𐌰𐌹𐍂𐌶𐌴𐌹",
+       "databaseerror": "𐌰𐌹𐍂𐌶𐌴𐌹𐌽𐍃 𐌳𐌰𐍄𐌰𐌷𐌿𐌶𐌳𐌹𐍃",
+       "databaseerror-function": "𐍆𐌿𐌽𐌺𐍄𐍃𐌾𐍉: $1",
        "databaseerror-error": "𐌰𐌹𐍂𐌶𐌴𐌹: $1",
+       "readonly": "𐌳𐌰𐍄𐌰𐌷𐌿𐌶𐌳 𐌻𐌿𐌺𐌰𐌽 𐌹𐍃𐍄",
+       "enterlockreason": "𐌲𐌹𐍆 𐍅𐌰𐌹𐌷𐍄 𐌻𐌿𐌺𐌰, 𐌾𐌰𐌷 𐍃𐍅𐌰 𐌻𐌰𐌲𐌲𐌰𐌱𐌰 𐍆𐌰𐌿𐍂𐌸𐌹𐌶𐌴𐌹 𐌻𐌿𐌺 𐌿𐍃𐌼𐌴𐍂𐌽𐌰𐌹",
        "missing-article": "𐌳𐌰𐍄𐌰𐌷𐌿𐌶𐌳 𐌽𐌹 𐌱𐌹𐌲𐌰𐍄 𐌱𐍉𐌺𐍉𐍃 𐌻𐌰𐌿𐌱𐌹𐍃 𐌸𐌹𐌶𐌴𐌹 𐍃𐌺𐌿𐌻𐌳𐌴𐌳𐌹 𐌱𐌹𐌲𐌹𐍄𐌰𐌽, 𐌷𐌰𐌹𐍄𐌰𐌽𐍃 \"$1\" $2. \n\n𐌸𐌰𐍄𐌰 𐌿𐍆𐍄𐌰 𐍅𐌰𐌹𐍂𐌸𐌹𐌸 𐌾𐌰𐌱𐌰𐌹 𐌻𐌰𐌹𐍃𐍄𐌾𐌰𐌳𐌰 𐍆𐌰𐌹𐍂𐌽𐌾𐌰 𐌳𐌹𐍆𐍆 𐌸𐌰𐌿 𐍃𐍀𐌹𐌻𐌻𐌰𐌲𐌰𐍅𐌹𐍃𐍃 𐍃𐌴𐌹 𐍆𐍂𐌰𐌵𐌹𐍃𐍄𐌹𐌳𐌰 𐌹𐍃𐍄. 𐌾𐌰𐌱𐌰𐌹 𐌽𐌹𐍃𐍄, 𐌼𐌰𐌷𐍄𐍃 𐌹𐍃𐍄 𐌴𐌹 𐌱𐌹𐌲𐌴𐍄𐌴𐌹𐍃 𐌰𐌹𐍂𐌶𐌴𐌹𐌽 𐌹𐌽 𐍃𐌰𐌿𐍆𐍄𐍅𐌰𐌹𐍂𐌰. \n\n𐌱𐌹𐌳𐌾𐌰𐌼 𐌸𐌿𐌺, 𐌼𐌴𐍂𐌴𐌹 𐌸𐌰𐍄𐌰 𐌳𐌿 [[Special:ListUsers/sysop\n|𐍂𐌴𐌹𐌺]] 𐌲𐌹𐍆𐌿𐌷 𐌲𐌰𐍅𐌹𐍃.",
+       "filedeleteerror": "𐌼𐌰𐌷𐍄𐍃 𐌽𐌹 𐍅𐌰𐍃 𐍆𐍂𐌰𐌵𐌹𐍃𐍄𐌾𐌰𐌽 𐍆𐌰𐌾𐌻𐌰 \"$1\".",
+       "formerror": "𐌰𐌹𐍂𐌶𐌴𐌹: 𐍆𐌰𐌿𐍂𐌼𐌰 𐌹𐌽𐍃𐌰𐌽𐌳𐌾𐌰𐌽 𐌽𐌹 𐍅𐌰𐍃 𐌼𐌰𐌷𐍄𐍃.",
        "badarticleerror": "𐌸𐍉 𐍅𐌰𐌹𐌷𐍄 𐌽𐌹 𐌼𐌰𐌲𐍄 𐍄𐌰𐌿𐌾𐌰𐌽 𐌸𐌰𐌼𐌼𐌰 𐌻𐌰𐌿𐌱𐌰.",
        "cannotdelete-title": "𐌽𐌹 𐌼𐌰𐌲 𐍆𐍂𐌰𐌵𐌹𐍃𐍄𐌾𐌰𐌽 𐌻𐌰𐌿𐌱𐌰 \"$1\"",
        "badtitle": "𐌿𐌽𐍂𐌰𐌹𐌷𐍄𐌰𐍄𐌰 𐌿𐍆𐌰𐍂𐌼𐌴𐌻𐌹",
        "badtitletext": "𐍆𐍂𐌰𐌹𐌷𐌰𐌽𐍃 𐌻𐌰𐌿𐍆𐍃 𐍅𐌰𐍃 𐌿𐌽𐌲𐌰𐌼𐌰𐌲𐌰𐌽𐌳𐍃, 𐌻𐌰𐌿𐍃, 𐌰𐌹𐌸𐌸𐌰𐌿 𐌿𐌽𐍂𐌰𐌹𐌷𐍄𐌰𐌱𐌰 𐌲𐌰𐍅𐌹𐌳𐌰𐌽𐍃 𐌼𐌹𐌸𐍂𐌰𐌶𐌳𐌰 𐌸𐌰𐌿 𐌼𐌹𐌸-𐍅𐌹𐌺𐌹 𐌿𐍆𐌰𐍂𐌼𐌴𐌻𐌹. 𐌼𐌰𐌲𐌹 𐌷𐌰𐌱𐌰𐌽 𐌰𐌹𐌽𐌰 𐌸𐌰𐌿 𐌼𐌰𐌽𐌰𐌲𐌹𐌶𐍉𐍃 𐌱𐍉𐌺𐍉𐍃 𐌱𐍂𐌿𐌺𐌹𐌳𐍉𐍃 𐌹𐌽 𐌿𐍆𐌰𐍂𐌼𐌴𐌻𐌾𐌰𐌼.",
        "viewsource": "𐍃𐌰𐌹𐍈 𐌱𐍂𐌿𐌽𐌽𐌰𐌽",
+       "viewsource-title": "𐌱𐌰𐌽𐌳𐍅𐌴𐌹 𐌱𐍂𐌿𐌽𐌽𐌰𐌽 𐍆𐌰𐌿𐍂 $1",
        "protectedpagetext": "𐍃𐌰 𐌻𐌰𐌿𐍆𐍃 𐌷𐌰𐌱𐌰𐌹𐌸 𐌼𐌿𐌽𐌳, 𐌴𐌹 𐌽𐌹 𐍅𐌰𐌹𐍂𐌸𐌴𐌹𐌽𐌰 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍉𐍃 𐌸𐌰𐌿 𐌰𐌽𐌸𐌰𐍂𐍉𐍃 𐍅𐌰𐌹𐌷𐍄𐍃 𐌹𐌽 𐌸𐌰𐌼𐌼𐌰 𐌻𐌰𐌿𐌱𐌰",
+       "viewsourcetext": "𐌼𐌰𐌲𐍄 𐌱𐌰𐌽𐌳𐍅𐌾𐌰𐌽 𐌾𐌰𐌷 𐌺𐌰𐌿𐍀𐌾𐌰 𐍃𐌺𐌰𐍀𐌾𐌰𐌽 𐌸𐌹𐍃 𐌻𐌰𐌿𐌱𐌹𐍃.",
+       "viewyourtext": "𐌼𐌰𐌲𐍄 𐍃𐌰𐌹𐍈𐌰𐌽 𐌾𐌰𐌷 𐌲𐌰𐌻𐌴𐌹𐌺𐍉𐌽 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍉𐍃 <strong>𐌸𐌴𐌹𐌽𐌰𐌹𐌶𐍉 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍉</strong> 𐌳𐌿 𐌸𐌰𐌼𐌼𐌰 𐌻𐌰𐌿𐌱𐌰.",
+       "namespaceprotected": "𐌽𐌹 𐌷𐌰𐌱𐌰𐌹𐍃 𐌰𐌽𐌳𐌻𐌴𐍄 𐌳𐌿 𐌹𐌽𐌼𐌰𐌹𐌳𐌾𐌰𐌽 𐌻𐌰𐌿𐌱𐌰𐌽𐍃 𐌹𐌽 <strong>$1</strong> 𐌽𐌰𐌼𐌰𐍂𐌿𐌼𐌰.",
+       "customcssprotected": "𐌽𐌹 𐌷𐌰𐌱𐌰𐌹𐍃 𐌰𐍄𐌲𐌰𐌲𐌲 𐌳𐌿 𐌹𐌽𐌼𐌰𐌹𐌳𐌾𐌰𐌽 𐌸𐌰𐌽𐌰 CSS 𐌻𐌰𐌿𐍆 𐌿𐌽𐍄𐌴 𐌷𐌰𐌱𐌰𐌹𐌸 𐌻𐌰𐌲𐌴𐌹𐌽𐌹𐌽𐍃 𐌰𐌽𐌸𐌰𐍂𐌹𐍃 𐌱𐍂𐌿𐌺𐌾𐌹𐌽𐍃.",
+       "customjsonprotected": "𐌽𐌹 𐌷𐌰𐌱𐌰𐌹𐍃 𐌰𐍄𐌲𐌰𐌲𐌲 𐌳𐌿 𐌹𐌽𐌼𐌰𐌹𐌳𐌾𐌰𐌽 𐌸𐌰𐌽𐌰 JSON 𐌻𐌰𐌿𐍆 𐌿𐌽𐍄𐌴 𐌷𐌰𐌱𐌰𐌹𐌸 𐌻𐌰𐌲𐌴𐌹𐌽𐌹𐌽𐍃 𐌰𐌽𐌸𐌰𐍂𐌹𐍃 𐌱𐍂𐌿𐌺𐌾𐌹𐌽𐍃.",
+       "customjsprotected": "𐌽𐌹 𐌷𐌰𐌱𐌰𐌹𐍃 𐌰𐍄𐌲𐌰𐌲𐌲 𐌳𐌿 𐌹𐌽𐌼𐌰𐌹𐌳𐌾𐌰𐌽 𐌸𐌰𐌽𐌰 JavaScript 𐌻𐌰𐌿𐍆 𐌿𐌽𐍄𐌴 𐌷𐌰𐌱𐌰𐌹𐌸 𐌻𐌰𐌲𐌴𐌹𐌽𐌹𐌽𐍃 𐌰𐌽𐌸𐌰𐍂𐌹𐍃 𐌱𐍂𐌿𐌺𐌾𐌹𐌽𐍃.",
+       "mycustomcssprotected": "𐌽𐌹 𐌷𐌰𐌱𐌰𐌹𐍃 𐌰𐌽𐌳𐌻𐌴𐍄 𐌳𐌿 𐌹𐌽𐌼𐌰𐌹𐌳𐌾𐌰𐌽 𐌸𐌰𐌽𐌰 CSS 𐌻𐌰𐌿𐍆.",
+       "mycustomjsonprotected": "𐌽𐌹 𐌷𐌰𐌱𐌰𐌹𐍃 𐌰𐌽𐌳𐌻𐌴𐍄 𐌳𐌿 𐌹𐌽𐌼𐌰𐌹𐌳𐌾𐌰𐌽 𐌸𐌰𐌽𐌰 JSON 𐌻𐌰𐌿𐍆.",
        "mycustomjsprotected": "𐌽𐌹 𐌷𐌰𐌱𐌰𐌹𐍃 𐌰𐌽𐌳𐌻𐌴𐍄 𐌳𐌿 𐌹𐌽𐌼𐌰𐌹𐌳𐌾𐌰𐌽 𐌸𐌰𐌽𐌰 JavaScript 𐌻𐌰𐌿𐍆.",
+       "ns-specialprotected": "𐌿𐍃𐍃𐌹𐌽𐌳𐌰𐌹 𐌻𐌰𐌿𐌱𐍉𐍃 𐌽𐌹 𐌼𐌰𐌲𐌿𐌽 𐌹𐌽𐌼𐌰𐌹𐌳𐌾𐌰𐌽𐌳𐌰.",
+       "titleprotected": "𐌸𐌰𐍄𐌰 𐌿𐍆𐌰𐍂𐌼𐌴𐌻𐌹 𐌼𐌿𐌽𐌸 𐌷𐌰𐌱𐌰𐌹𐌸 𐍆𐍂𐌰𐌼 𐌲𐌰𐍃𐌺𐌰𐍆𐍄𐌰 𐍆𐍂𐌰𐌼 𐌱𐍂𐌿𐌺𐌾𐌰𐌽𐌳 [[User:$1|$1]].\n𐌲𐌹𐌱𐌰𐌽𐌰 𐍆𐌰𐌹𐍂𐌹𐌽𐌰 𐌹𐍃𐍄 <em>$2</em>.",
+       "exception-nologin-text": "𐌱𐌹𐌳𐌾𐌰𐌼 𐌸𐌿𐌺, 𐌰𐍄𐌲𐌰𐌲𐌲 𐌳𐌿 𐌰𐍄𐌲𐌰𐌲𐌲𐌰𐌽 𐌹𐌽 𐌸𐌰𐌽𐌰 𐌻𐌰𐌿𐍆 𐌸𐌰𐌿 𐌸𐍉 𐍄𐌰𐌿𐌹.",
+       "cannotlogoutnow-title": "𐌰𐍆𐌻𐌴𐌹𐌸𐌰𐌽 𐌽𐌿 𐌼𐌰𐌷𐍄𐍃 𐌽𐌹𐍃𐍄",
+       "cannotlogoutnow-text": "𐌸𐌰𐌽 $1 𐌱𐍂𐌿𐌺𐌾𐌰𐌳𐌰 𐌰𐍆𐌻𐌴𐌹𐌸𐌰𐌽 𐌼𐌰𐌷𐍄𐍃 𐌽𐌹𐍃𐍄.",
        "welcomeuser": "𐍅𐌰𐌹𐌻𐌰 𐌰𐌽𐌳𐌰𐌽𐌴𐌼𐍃, $1!",
+       "welcomecreation-msg": "𐌸𐌴𐌹𐌽𐌰 𐍂𐌰𐌷𐌽𐌴𐌹𐌽𐍃 𐌲𐌰𐍃𐌺𐍀𐌰𐌽𐌰 𐌹𐍃𐍄.\n𐌼𐌰𐌲𐍄 {{SITENAME}} [[Special:Preferences|𐍆𐍂𐌹𐌾𐍉𐌽𐍉𐍃 𐍅𐌰𐌹𐌷𐍄𐌹𐌽𐍃]] 𐌹𐌽𐌼𐌰𐌹𐌳𐌾𐌰𐌽 𐌾𐌰𐌱𐌰𐌹 𐍅𐌹𐌻𐌴𐌹𐍃.",
        "yourname": "𐌰𐍄𐌲𐌰𐌲𐌲𐌰𐌽𐌰𐌼𐍉:",
        "userlogin-yourname": "𐌰𐍄𐌲𐌰𐌲𐌲𐌰𐌽𐌰𐌼𐍉",
        "userlogin-yourname-ph": "𐌼𐌴𐌻𐌴𐌹 𐌰𐍄𐌲𐌰𐌲𐌲𐌰𐌽𐌰𐌼𐍉 𐌸𐌴𐌹𐌽",
        "userlogin-yourpassword": "𐌲𐌰𐌼𐍉𐍄𐌰𐍅𐌰𐌿𐍂𐌳",
        "userlogin-yourpassword-ph": "𐌼𐌴𐌻𐌴𐌹 𐌲𐌰𐌼𐍉𐍄𐌰𐍅𐌰𐌿𐍂𐌳 𐌸𐌴𐌹𐌽",
        "createacct-yourpassword-ph": "𐌼𐌴𐌻𐌴𐌹 𐌲𐌰𐌼𐍉𐍄𐌰𐍅𐌰𐌿𐍂𐌳",
+       "yourpasswordagain": "𐌼𐌴𐌻𐌴𐌹 𐌲𐌰𐌼𐍉𐍄𐌰𐍅𐌰𐌿𐍂𐌳 𐌰𐍆𐍄𐍂𐌰:",
        "createacct-yourpasswordagain": "𐌲𐌰𐍃𐌹𐌲𐌻𐌴𐌹 𐌲𐌰𐌼𐍉𐍄𐌰𐍅𐌰𐌿𐍂𐌳",
        "createacct-yourpasswordagain-ph": "𐌼𐌴𐌻𐌴𐌹 𐌲𐌰𐌼𐍉𐍄𐌰𐍅𐌰𐌿𐍂𐌳 𐌰𐍆𐍄𐍂𐌰",
        "userlogin-remembermypassword": "𐌲𐌰𐍆𐌰𐍃𐍄 𐌼𐌹𐌺 {{GENDER:𐌰𐍄𐌲𐌰𐌲𐌲𐌰𐌽𐌰𐌽𐌰|𐌰𐍄𐌲𐌰𐌲𐌲𐌰𐌽𐌰}}",
+       "userlogin-signwithsecure": "𐌱𐍂𐌿𐌺𐌴𐌹 𐌰𐍂𐌽𐌾𐌰𐌹𐌶𐍉𐍃 𐌲𐌰𐍅𐌹𐍃𐌰𐌹𐍃",
+       "cannotlogin-title": "𐌰𐍄𐌲𐌰𐌲𐌲𐌰𐌽 𐌼𐌰𐌷𐍄𐍃 𐌽𐌹𐍃𐍄",
+       "cannotlogin-text": "𐌰𐍄𐌲𐌰𐌲𐌲𐌰𐌽 𐌼𐌰𐌷𐍄𐍃 𐌽𐌹𐍃𐍄.",
        "cannotloginnow-title": "𐌽𐌿 𐌽𐌹 𐌼𐌰𐌲𐍄 𐌰𐍄𐌲𐌰𐌲𐌲𐌰𐌽",
+       "cannotloginnow-text": "𐌰𐍄𐌲𐌰𐌲𐌲𐌰𐌽 𐌼𐌰𐌷𐍄𐍃 𐌽𐌹𐍃𐍄 𐌸𐌰𐌽 $1 𐌱𐍂𐌿𐌺𐌾𐌰𐌳𐌰.",
+       "cannotcreateaccount-title": "𐌼𐌰𐌷𐍄𐍃 𐌽𐌹 𐍅𐌰𐍃 𐌳𐌿 𐍃𐌺𐌰𐍀𐌾𐌰𐌽 𐍂𐌰𐌷𐌽𐌴𐌹𐌽𐌹𐌽𐍃",
+       "password-change-forbidden": "𐌽𐌹 𐌼𐌰𐌲𐍄 𐌹𐌽𐌼𐌰𐌹𐌳𐌾𐌰𐌽 𐌲𐌰𐌼𐍉𐍄𐌰𐍅𐌰𐌿𐍂𐌳𐌰 𐌰𐌽𐌰 𐌸𐌰𐌼𐌼𐌰 𐍅𐌹𐌺𐌾𐌰.",
        "login": "𐌰𐍄𐌲𐌰𐌲𐌲",
-       "nav-login-createaccount": "ð\90\8c°ð\90\8d\84ð\90\8c²ð\90\8c°ð\90\8c²ð\90\8c² / ð\90\8d\83ð\90\8cºð\90\8c°ð\90\8d\80ð\90\8c´ð\90\8c¹ ð\90\8cºð\90\8c°ð\90\8d\85ð\90\8d\84ð\90\8d\83ð\90\8c¾ð\90\8d\89𐌽",
+       "nav-login-createaccount": "ð\90\8c°ð\90\8d\84ð\90\8c²ð\90\8c°ð\90\8c²ð\90\8c² / ð\90\8d\83ð\90\8cºð\90\8c°ð\90\8d\80ð\90\8c´ð\90\8c¹ ð\90\8d\82ð\90\8c°ð\90\8c·ð\90\8c½ð\90\8c´ð\90\8c¹𐌽",
        "logout": "𐌰𐍆𐌻𐌴𐌹𐌸",
        "userlogout": "𐌰𐍆𐌻𐌴𐌹𐌸",
-       "userlogin-noaccount": "ð\90\8c½ð\90\8c¹ ð\90\8c·ð\90\8c°ð\90\8c±ð\90\8c°ð\90\8c¹ð\90\8d\83 ð\90\8cºð\90\8c°ð\90\8d\85ð\90\8d\84ð\90\8d\83ð\90\8c¾ð\90\8d\89𐌽?",
+       "userlogin-noaccount": "ð\90\8c½ð\90\8c¹ ð\90\8c·ð\90\8c°ð\90\8c±ð\90\8c°ð\90\8c¹ð\90\8d\83 ð\90\8d\82ð\90\8c°ð\90\8c·ð\90\8c½ð\90\8c´ð\90\8c¹𐌽?",
        "userlogin-joinproject": "𐌲𐌰𐌳𐌰𐌹𐌻𐌴𐌹 𐌹𐌽 𐌽𐌰𐍄𐌾𐌰𐍃𐍄𐌰𐌳𐌰 {{SITENAME}}",
-       "createaccount": "ð\90\8d\83ð\90\8cºð\90\8c°ð\90\8d\80ð\90\8c´ð\90\8c¹ ð\90\8cºð\90\8c°ð\90\8d\85ð\90\8d\84ð\90\8d\83ð\90\8c¾ð\90\8d\89𐌽",
+       "createaccount": "ð\90\8d\83ð\90\8cºð\90\8c°ð\90\8d\80ð\90\8c´ð\90\8c¹ ð\90\8d\82ð\90\8c°ð\90\8c·ð\90\8c½ð\90\8c´ð\90\8c¹𐌽",
        "userlogin-resetpassword-link": "𐌿𐍆𐌰𐍂𐌼𐌿𐌽𐌽𐍉𐌳𐌴𐍃 𐌸𐌴𐌹𐌽𐌰𐌼𐌼𐌰 𐌲𐌰𐌼𐍉𐍄𐌰𐍅𐌰𐌿𐍂𐌳𐌰?",
        "userlogin-helplink2": "𐌷𐌹𐌻𐍀𐌰 𐌼𐌹𐌸 𐌰𐍄𐌲𐌰𐌲𐌲𐌰",
+       "userlogin-createanother": "𐍃𐌺𐌰𐍀𐌴𐌹 𐌰𐌽𐌸𐌰𐍂𐌰 𐍂𐌰𐌷𐌽𐌴𐌹𐌽",
        "createacct-emailoptional": "𐌴-𐌱𐍉𐌺𐍉𐍃 (𐌼𐌰𐌷𐍄𐌴𐌹𐌲𐍉𐍃)",
        "createacct-email-ph": "𐌼𐌴𐌻𐌴𐌹 𐌸𐌴𐌹𐌽𐍉𐍃 𐌴-𐌱𐍉𐌺𐍉𐍃",
+       "createacct-another-email-ph": "𐌼𐌴𐌻𐌴𐌹 𐌴-𐌱𐍉𐌺𐍉𐍃",
+       "createaccountmail-help": "𐌼𐌰𐌲 𐌱𐍂𐌿𐌺𐌾𐌰𐌳𐌰 𐌳𐌿 𐍃𐌺𐌰𐍀𐌾𐌰𐌽 𐍂𐌰𐌷𐌽𐌴𐌹𐌽 𐌰𐌽𐌸𐌰𐍂𐌰𐌼𐌼𐌰 𐌼𐌰𐌽 𐌹𐌽𐌿𐌷 𐌲𐌰𐌼𐍉𐍄𐌰𐍅𐌰𐌿𐍂𐌳 𐌻𐌰𐌹𐍃𐌾𐌰𐌽",
+       "createacct-realname": "𐍃𐌿𐌽𐌾𐌴𐌹𐌽 𐌽𐌰𐌼𐍉 (𐌼𐌰𐌷𐍄𐌴𐌹𐌲)",
        "createacct-reason": "𐌲𐍂𐌿𐌽𐌳𐌿𐍃",
-       "createacct-submit": "𐍃𐌺𐌰𐍀𐌴𐌹 𐌸𐌴𐌹𐌽𐌰 𐌺𐌰𐍅𐍄𐍃𐌾𐍉𐌽",
+       "createacct-reason-ph": "𐌳𐌿𐍈𐌴 𐌸𐌿 𐍃𐌺𐌰𐍀𐌾𐌹𐍃 𐍂𐌰𐌷𐌽𐌴𐌹𐌽",
+       "createacct-submit": "𐍃𐌺𐌰𐍀𐌴𐌹 𐌸𐌴𐌹𐌽𐌰 𐍂𐌰𐌷𐌽𐌴𐌹𐌽",
+       "createacct-another-submit": "𐍃𐌺𐌰𐍀𐌴𐌹 𐍂𐌰𐌷𐌽𐌴𐌹𐌽",
+       "createacct-continue-submit": "𐌸𐌰𐌹𐍂𐌷𐍅𐌹𐍃 𐌼𐌹𐌸 𐌲𐌰𐍃𐌺𐌰𐍆𐍄𐌰𐌹 𐍂𐌰𐌷𐌽𐌴𐌹𐌽𐌰𐌹𐍃",
+       "createacct-another-continue-submit": "𐌸𐌰𐌹𐍂𐌷𐍅𐌹𐍃 𐌼𐌹𐌸 𐌲𐌰𐍃𐌺𐌰𐍆𐍄𐌰𐌹 𐍂𐌰𐌷𐌽𐌴𐌹𐌽𐌰𐌹𐍃",
        "createacct-benefit-heading": "{{SITENAME}} 𐍄𐌰𐍅𐌹𐌸 𐌹𐍃𐍄 𐍆𐍂𐌰𐌼 𐌼𐌰𐌽𐌽𐌰𐌼 𐍃𐍅𐌴 𐌸𐌿𐌺.",
        "createacct-benefit-body1": "{{PLURAL:$1|𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍃|𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍉𐍃}}",
        "createacct-benefit-body2": "{{PLURAL:$1|𐌻𐌰𐌿𐍆𐍃|𐌻𐌰𐌿𐌱𐍉𐍃}}",
+       "badretype": "𐌲𐌰𐌼𐍉𐍄𐌰𐍅𐌰𐌿𐍂𐌳𐌰 𐌸𐍉𐌴𐌹 𐌸𐌿 𐌲𐌰𐌼𐌴𐌻𐌹𐌳𐌴𐍃 𐌽𐌹 𐌹𐌽𐌲𐌰𐌻𐌴𐌹𐌺𐍉𐌽𐌳.",
+       "usernameinprogress": "𐍂𐌰𐌷𐌽𐌴𐌹𐌽𐌹𐌲𐌰𐍃𐌺𐌰𐍆𐍄𐍃 𐌸𐌰𐌼𐌼𐌰 𐌰𐍄𐌲𐌰𐌲𐌲𐌰𐌽𐌰𐌼𐌹𐌽 𐌾𐌿 𐍄𐍉𐌾𐌰𐌳𐌰. 𐌱𐌹𐌳𐌾𐌰𐌼 𐌸𐌿𐌺 𐌴𐌹 𐌱𐌹𐌳𐌰𐌹𐍃.",
+       "userexists": "𐌲𐌰𐌼𐌴𐌻𐌹𐌸 𐌰𐍄𐌲𐌰𐌲𐌲𐌰𐌽𐌰𐌼𐍉 𐌾𐌿 𐌱𐍂𐌿𐌺𐌾𐌰𐌳𐌰.\n𐌱𐌹𐌳𐌾𐌰𐌼 𐌸𐌿𐌺, 𐍅𐌰𐌻𐌴𐌹 𐌰𐌽𐌸𐌰𐍂 𐌽𐌰𐌼𐍉.",
+       "createacct-error": "𐌰𐌹𐍂𐌶𐌴𐌹 𐌹𐌽 𐌲𐌰𐍃𐌺𐌰𐍆𐍄𐌰𐌹 𐍂𐌰𐌷𐌽𐌴𐌹𐌽𐌰𐌹𐍃",
+       "createaccounterror": "𐌼𐌰𐌷𐍄𐍃 𐌽𐌹 𐍅𐌰𐍃 𐌳𐌿 𐍃𐌺𐌰𐍀𐌾𐌰𐌽 𐍂𐌰𐌷𐌽𐌴𐌹𐌽: $1",
+       "nocookiesfornew": "𐌱𐍂𐌿𐌺𐌾𐌰𐍂𐌰𐌷𐌽𐌴𐌹𐌽𐍃 𐌽𐌹 𐌲𐌰𐍃𐌺𐌰𐍀𐌰𐌽𐌰 𐌿𐌽𐍄𐌴 𐍅𐌴𐌹𐍃 𐌽𐌹 𐌼𐌰𐌷𐍄𐌴𐌳𐌿𐌼 𐌱𐍂𐌿𐌽𐌽𐌰𐌽 𐌲𐌰𐍃𐌹𐌲𐌻𐌾𐌰𐌽. 𐍅𐌹𐍃 𐌰𐍂𐌽𐌹𐌱𐌰 𐌸𐌰𐍄𐌴𐌹 𐌸𐌿 𐌰𐌽𐌳𐌻𐌴𐍄𐌹𐍃 𐌺𐍉𐌺𐍉𐍃, 𐌰𐍆𐍄𐍂𐌰𐌰𐌽𐌰𐌽𐌹𐌿𐌴𐌹 𐌻𐌰𐌿𐍆 𐌾𐌰𐌷 𐍃𐍉𐌺𐌴𐌹 𐌰𐍆𐍄𐍂𐌰.",
+       "nosuchuser": "𐌽𐌹𐍃𐍄 𐌱𐍂𐌿𐌺𐌾𐌰𐌽𐌳𐍃 𐌼𐌹𐌸 𐌽𐌰𐌼𐌹𐌽 \"$1\".\n𐌽𐌰𐌼𐌽𐌰 𐌱𐍂𐌿𐌺𐌾𐌰𐌽𐌳𐌴 𐌼𐌰𐌲𐌿𐌽 𐌷𐌰𐌱𐌰𐌽 𐌷𐌰𐌿𐌱𐌹𐌳𐌹𐍃 𐌱𐍉𐌺𐍉𐍃.\n𐍃𐌰𐌹𐍈 𐌰𐍆𐍄𐍂𐌰 𐌸𐌴𐌹𐌽𐌰 𐌼𐌴𐌻𐌴𐌹𐌽𐍃, 𐌸𐌰𐌿 [[Special:CreateAccount|𐍃𐌺𐌰𐍀𐌴𐌹 𐍂𐌰𐌷𐌽𐌴𐌹𐌽]].",
+       "nouserspecified": "𐍃𐌺𐌰𐌻𐍄 𐌲𐌹𐌱𐌰𐌽 𐌰𐍄𐌲𐌰𐌲𐌲𐌰𐌽𐌰𐌼𐍉.",
+       "wrongpasswordempty": "𐌲𐌰𐌼𐌴𐌻𐌹𐌸 𐌲𐌰𐌼𐍉𐍄𐌰𐍅𐌰𐌿𐍂𐌳 𐍅𐌰𐍃 𐌻𐌰𐌿𐍃.\n𐌱𐌹𐌳𐌾𐌰𐌼 𐌸𐌿𐌺, 𐍃𐍉𐌺𐌴𐌹 𐌰𐍆𐍄𐍂𐌰.",
+       "passwordtooshort": "𐌲𐌰𐌼𐍉𐍄𐌰𐍅𐌰𐌿𐍂𐌳𐌰 𐍃𐌺𐌿𐌻𐌿𐌽 𐌼𐌰𐌹𐍃 𐌸𐌰𐌿 {{PLURAL:$1|•𐌰• 𐌱𐍉𐌺𐌰|$1 𐌱𐍉𐌺𐍉𐍃}} 𐍅𐌹𐍃𐌰𐌽.",
+       "passwordtoolong": "𐌲𐌰𐌼𐍉𐍄𐌰𐍅𐌰𐌿𐍂𐌳𐌰 𐌽𐌹 𐌼𐌰𐌲𐌿𐌽 𐍅𐌹𐍃𐌰𐌽 𐌻𐌰𐌲𐌲𐌹𐌶𐍉𐌽𐌰 𐌸𐌰𐌿 {{PLURAL:$1|•𐌰• 𐌱𐍉𐌺𐌰|$1 𐌱𐍉𐌺𐍉𐍃}}.",
+       "passwordtoopopular": "𐍆𐌹𐌻𐌿 𐌲𐌰𐍅𐌰𐌻𐌹𐌳𐌰 𐌲𐌰𐌼𐍉𐍄𐌰𐍅𐌰𐌿𐍂𐌳𐌰 𐍅𐌰𐌻𐌾𐌰𐌽 𐌼𐌰𐌷𐍄𐍃 𐌽𐌹𐍃𐍄. 𐌱𐌹𐌳𐌾𐌰𐌼 𐌸𐌿𐌺, 𐍅𐌰𐌻𐌴𐌹 𐌰𐌽𐌸𐌰𐍂 𐌲𐌰𐌼𐍉𐍄𐌰𐍅𐌰𐌿𐍂𐌳 𐌸𐌰𐍄𐌴𐌹 𐌰𐌲𐌻𐌿 𐌹𐍃𐍄 𐌳𐌿 𐌱𐌹𐌲𐌹𐍄𐌰𐌽.",
+       "password-name-match": "𐌸𐌴𐌹𐌽 𐌲𐌰𐌼𐍉𐍄𐌰𐍅𐌰𐌿𐍂𐌳 𐌽𐌹 𐍃𐌺𐌰𐌻 𐍃𐌰𐌼𐌰𐌻𐌴𐌹𐌺 𐍅𐌹𐍃𐌰𐌽 𐍃𐍅𐌰𐍃𐍅𐌴 𐌸𐌴𐌹𐌽 𐌰𐍄𐌲𐌰𐌲𐌲𐌰𐌽𐌰𐌼𐍉.",
+       "password-login-forbidden": "𐌱𐍂𐌿𐌺𐌴𐌹𐌽𐍃 𐌸𐌹𐍃 𐌰𐍄𐌲𐌰𐌲𐌲𐌰𐌽𐌰𐌼𐌹𐌽𐍃 𐌾𐌰𐌷 𐌸𐌹𐍃 𐌲𐌰𐌼𐍉𐍄𐌰𐍅𐌰𐌿𐍂𐌳𐌹𐍃 𐍆𐌰𐌿𐍂𐌱𐌹𐌿𐌳𐌰𐌽𐌰 𐌹𐍃𐍄.",
+       "mailmypassword": "𐌰𐍆𐍄𐍂𐌰 𐍃𐌰𐍄𐌴𐌹 𐌲𐌰𐌼𐍉𐍄𐌰𐍅𐌰𐌿𐍂𐌳",
+       "noemailcreate": "𐍃𐌺𐌰𐌻𐍄 𐍂𐌰𐌹𐌷𐍄𐍉𐍃 𐌴-𐌱𐍉𐌺𐍉𐍃 𐌲𐌹𐌱𐌰𐌽.",
+       "emailconfirmlink": "𐌲𐌰𐍃𐌹𐌲𐌻𐌴𐌹 𐌸𐌴𐌹𐌽𐍉𐍃 𐌴-𐌱𐍉𐌺𐍉𐍃",
+       "emaildisabled": "𐍃𐌰 𐌽𐌰𐍄𐌾𐌰𐍃𐍄𐌰𐌸𐍃 𐌽𐌹 𐌼𐌰𐌲 𐍃𐌰𐌽𐌳𐌾𐌰𐌽 𐌴-𐌱𐍉𐌺𐍉𐍃.",
+       "accountcreated": "𐍂𐌰𐌷𐌽𐌴𐌹𐌽𐍃 𐌲𐌰𐍃𐌺𐌰𐍀𐌰𐌽𐌰",
+       "accountcreatedtext": "𐌱𐍂𐌿𐌺𐌾𐌰𐍂𐌰𐌷𐌽𐌴𐌹𐌽𐍃 [[{{ns:User}}:$1|$1]] ([[{{ns:User talk}}:$1|𐌲𐌰𐍅𐌰𐌿𐍂𐌳𐌹]]) 𐌲𐌰𐍃𐌺𐌰𐍀𐌰𐌽𐌰 𐌹𐍃𐍄.",
+       "createaccount-title": "𐌲𐌰𐍃𐌺𐌰𐍆𐍄𐍃 𐍂𐌰𐌷𐌽𐌴𐌹𐌽𐌰𐌹𐍃 𐍆𐌰𐌿𐍂 {{SITENAME}}",
        "loginlanguagelabel": "𐍂𐌰𐌶𐌳𐌰: $1",
        "pt-login": "𐌰𐍄𐌲𐌰𐌲𐌲",
        "pt-login-button": "𐌰𐍄𐌲𐌰𐌲𐌲",
-       "pt-createaccount": "𐍃𐌺𐌰𐍀𐌴𐌹 𐌺𐌰𐍅𐍄𐍃𐌾𐍉𐌽",
+       "pt-login-continue-button": "𐌸𐌰𐌹𐍂𐌷𐍅𐌹𐍃 𐌰𐍄𐌲𐌰𐌲𐌲𐌰𐌽",
+       "pt-createaccount": "𐍃𐌺𐌰𐍀𐌴𐌹 𐍂𐌰𐌷𐌽𐌴𐌹𐌽",
        "pt-userlogout": "𐌰𐍆𐌻𐌴𐌹𐌸",
+       "changepassword": "𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹 𐌲𐌰𐌼𐍉𐍄𐌰𐍅𐌰𐌿𐍂𐌳",
+       "resetpass_announce": "𐌳𐌿 𐌿𐍃𐍄𐌹𐌿𐌷𐌰𐌽 𐌰𐍄𐌲𐌰𐌲𐌲, 𐍃𐌺𐌰𐌻𐍄 𐌽𐌹𐍅𐌹 𐌲𐌰𐌼𐍉𐍄𐌰𐍅𐌰𐌿𐍂𐌳 𐍅𐌰𐌻𐌾𐌰𐌽.",
+       "resetpass_header": "𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹 𐌲𐌰𐌼𐍉𐍄𐌰𐍅𐌰𐌿𐍂𐌳 𐍂𐌰𐌷𐌽𐌴𐌹𐌽𐌰𐌹𐍃",
+       "oldpassword": "𐍆𐌰𐌹𐍂𐌽𐌹 𐌲𐌰𐌼𐍉𐍄𐌰𐍅𐌰𐌿𐍂𐌳:",
+       "newpassword": "𐌽𐌹𐍅𐌹 𐌲𐌰𐌼𐍉𐍄𐌰𐍅𐌰𐌿𐍂𐌳:",
+       "retypenew": "𐌰𐍆𐍄𐍂𐌰 𐌼𐌴𐌻𐌴𐌹 𐌽𐌹𐍅𐌹 𐌲𐌰𐌼𐍉𐍄𐌰𐍅𐌰𐌿𐍂𐌳:",
+       "resetpass_submit": "𐌻𐌰𐌲𐌴𐌹 𐌲𐌰𐌼𐍉𐍄𐌰𐍅𐌰𐌿𐍂𐌳 𐌾𐌰𐌷 𐌰𐍄𐌲𐌰𐌲𐌲",
+       "changepassword-success": "𐌸𐌴𐌹𐌽 𐌲𐌰𐌼𐍉𐍄𐌰𐍅𐌰𐌿𐍂𐌳 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌸 𐌹𐍃𐍄!",
+       "botpasswords": "𐌱𐌰𐌿𐍄𐌹𐍃 𐌲𐌰𐌼𐍉𐍄𐌰𐍅𐌰𐌿𐍂𐌳𐌰",
+       "botpasswords-existing": "𐍅𐌹𐍃𐌰𐌽𐌳𐍉𐌽𐌳𐌰 𐌱𐌰𐌿𐍄𐌹𐍃 𐌲𐌰𐌼𐍉𐍄𐌰𐍅𐌰𐌿𐍂𐌳𐌰",
+       "botpasswords-label-appid": "𐌽𐌰𐌼𐍉 𐌱𐌰𐌿𐍄𐌹𐍃:",
+       "botpasswords-label-create": "𐍃𐌺𐌰𐍀𐌴𐌹",
+       "botpasswords-label-update": "𐌰𐌽𐌰𐌽𐌹𐌿𐌴𐌹",
+       "botpasswords-label-cancel": "𐍃𐍅𐌴𐌹𐌱",
+       "botpasswords-label-delete": "𐍆𐍂𐌰𐌵𐌹𐍃𐍄𐌴𐌹",
+       "botpasswords-label-grants-column": "𐌲𐌹𐌱𐌰𐌽",
+       "resetpass_forbidden": "𐌲𐌰𐌼𐍉𐍄𐌰𐍅𐌰𐌿𐍂𐌳 𐌽𐌹 𐌼𐌰𐌲 𐌹𐌽𐌼𐌰𐌹𐌳𐌾𐌰𐌳𐌰",
+       "resetpass-submit-loggedin": "𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹 𐌲𐌰𐌼𐍉𐍄𐌰𐍅𐌰𐌿𐍂𐌳",
+       "resetpass-submit-cancel": "𐍃𐍅𐌴𐌹𐌱",
        "passwordreset": "𐌰𐍆𐍄𐍂𐌰 𐍃𐌰𐍄𐌴𐌹 𐌲𐌰𐌼𐍉𐍄𐌰𐍅𐌰𐌿𐍂𐌳",
+       "passwordreset-username": "𐌰𐍄𐌲𐌰𐌲𐌲𐌰𐌽𐌰𐌼𐍉:",
        "bold_sample": "𐍃𐍅𐌹𐌽𐌸𐍉𐍃 𐌱𐍉𐌺𐍉𐍃",
        "bold_tip": "𐍃𐍅𐌹𐌽𐌸𐍉𐍃 𐌱𐍉𐌺𐍉𐍃",
        "italic_sample": "𐍅𐍂𐌰𐌹𐌵𐍉𐍃 𐌱𐍉𐌺𐍉𐍃",
        "summary": "𐌼𐌰𐌿𐍂𐌲𐌿𐍃 𐍃𐌺𐌴𐌹𐍂𐌴𐌹𐌽𐍃:",
        "subject": "𐌿𐍆𐍅𐌰𐌿𐍂𐍀𐌰:",
        "minoredit": "𐌸𐌰𐍄𐌰 𐌹𐍃𐍄 𐌼𐌹𐌽𐌽𐌹𐌶𐌴𐌹 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍃",
-       "watchthis": "𐌰𐍄𐍅𐌹𐍄 𐌻𐌰𐌿𐌱𐌰",
-       "savearticle": "𐌲𐌰𐍆𐌰𐍃𐍄 𐌻𐌰𐌿𐍆",
+       "watchthis": "𐌰𐍄𐍅𐌹𐍄𐌰𐌹 𐌸𐌰𐌼𐌼𐌰 𐌻𐌰𐌿𐌱𐌰",
+       "savearticle": "𐌲𐌰𐍆𐌰𐍃𐍄𐌰𐌹 𐌻𐌰𐌿𐍆",
        "savechanges": "𐌲𐌰𐍆𐌰𐍃𐍄 𐌹𐌽𐌼𐌰𐌹𐌳𐌹𐌽𐌹𐌽𐍃",
        "publishpage": "𐌼𐌴𐍂𐌴𐌹 𐌻𐌰𐌿𐍆",
        "publishchanges": "𐌼𐌴𐍂𐌴𐌹 𐌹𐌽𐌼𐌰𐌹𐌳𐌹𐌽𐌹𐌽𐍃",
        "loginreqlink": "𐌰𐍄𐌲𐌰𐌲𐌲",
        "newarticle": "(𐌽𐌹𐍅𐌹)",
        "newarticletext": "𐌻𐌰𐌹𐍃𐍄𐌹𐌳𐌴𐍃 𐌲𐌰𐍅𐌹𐍃 𐌳𐌿 𐌻𐌰𐌿𐌱𐌰 𐍃𐌰𐌴𐌹 𐌽𐌹𐍃𐍄. 𐌳𐌿 𐍃𐌺𐌰𐍀𐌾𐌰𐌽 𐌸𐌰𐌽𐌰 𐌻𐌰𐌿𐍆, 𐌰𐌽 𐌰𐍃𐍄𐍉𐌳𐌴𐌹 𐌼𐌴𐌻𐌾𐌰𐌽 𐌹𐌽 𐌰𐍂𐌺𐌰𐌹 𐌿𐍆 (𐍃𐌰𐌹𐍈 [$1 𐌷𐌹𐌻𐍀𐌰𐌻𐌰𐌿𐍆] 𐌼𐌰𐌽𐌰𐌲𐌹𐌶𐌹𐌽 𐌺𐌿𐌽𐌸𐌾𐌰). 𐌾𐌰𐌱𐌰𐌹 𐌹𐍃 𐌷𐌴𐍂 𐌹𐌽 𐌰𐌹𐍂𐌶𐌴𐌹𐌽𐍃, 𐌲𐌰𐌲𐌲 𐌳𐌿 <strong>𐌹𐌱𐌿𐌺𐌰𐌷𐌰𐌿𐌱𐌹𐌳𐌹𐌻𐍉𐌽</strong>.",
+       "anontalkpagetext": "----\n<em>𐌸𐌰𐍄𐌰 𐌹𐍃𐍄 𐌲𐌰𐍅𐌰𐌿𐍂𐌳𐌾𐌰𐌻𐌰𐌿𐍆𐍃 𐌿𐌽𐌽𐌰𐌼𐌽𐌹𐌸𐌰𐌼𐌼𐌰 𐌱𐍂𐌿𐌺𐌾𐌰𐌽𐌳 𐍃𐌰𐌴𐌹 𐌽𐌰𐌿𐌷 𐌽𐌹 𐌲𐌰𐍃𐌺𐍉𐍀 𐍂𐌰𐌷𐌽𐌴𐌹𐌽, 𐌸𐌰𐌿 𐍃𐌰𐌴𐌹 𐌽𐌹 𐌱𐍂𐌿𐌺𐌾𐌹𐌸 𐌸𐌹𐍃.<em>\n𐌹𐌽 𐌸𐌹𐍃 𐍃𐌺𐌿𐌻𐌳 𐌹𐍃𐍄 𐌿𐌽𐍃 𐌳𐌿 𐌱𐍂𐌿𐌺𐌾𐌰𐌽 𐍂𐌰𐌸𐌾𐍉𐌽𐍃 IP 𐌳𐌿 𐌺𐌿𐌽𐌽𐌰𐌽 𐌹𐌽𐌰/𐌹𐌾𐌰.\n𐌾𐌰𐌱𐌰𐌹 𐌸𐌿 𐌹𐍃 𐌿𐌽𐌽𐌰𐌼𐌽𐌹𐌸𐍃 𐌱𐍂𐌿𐌺𐌾𐌰𐌽𐌳𐍃 𐌾𐌰𐌷 𐌹𐍃𐍄 𐌸𐌿𐍃 𐍃𐍅𐌰𐍃𐍅𐌴 𐌿𐌽𐌲𐌰𐌷𐌰𐌷𐌾𐍉 𐍅𐌰𐌿𐍂𐌳𐌰 𐍅𐌴𐍃𐌿𐌽 𐌸𐌿𐍃, 𐌱𐌹𐌳𐌾𐌰𐌼 𐌸𐌿𐌺, [[Special:CreateAccount|𐍃𐌺𐌰𐍀𐌴𐌹 𐍂𐌰𐌷𐌽𐌴𐌹𐌽]] 𐌸𐌰𐌿 [[Special:UserLogin|𐌰𐍄𐌲𐌰𐌲𐌲]] 𐌴𐌹 𐌽𐌹 𐍃𐌹𐌾𐌰𐌹 𐌰𐌹𐍂𐌶𐌴𐌹𐌽𐍃 𐌼𐌹𐌸 𐌰𐌽𐌸𐌰𐍂𐌰𐌹𐌼 𐌿𐌽𐌽𐌰𐌼𐌽𐌹𐌸𐌰𐌹𐌼 𐌱𐍂𐌿𐌺𐌾𐌰𐌽𐌳𐌰𐌼 𐌹𐌽 𐌰𐌽𐌰𐍅𐌰𐌹𐍂𐌸𐌰.",
        "noarticletext": "𐌽𐌿 𐌽𐌹 𐍃𐌹𐌽𐌳 𐌱𐍉𐌺𐍉𐍃 𐌹𐌽 𐌸𐌰𐌼𐌼𐌰 𐌻𐌰𐌿𐌱𐌰.\n𐌼𐌰𐌲𐍄 [[Special:Search/{{PAGENAME}}|𐍃𐍉𐌺𐌾𐌰𐌽 𐌸𐌰𐍄𐌰 𐌻𐌰𐌿𐌱𐌰-𐌿𐍆𐌰𐍂𐌼𐌴𐌻𐌹]] 𐌹𐌽 𐌰𐌽𐌸𐌰𐍂𐌰𐌹𐌼 𐌻𐌰𐌿𐌱𐌰𐌼,  <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} 𐍃𐍉𐌺𐌾𐌰𐌽 𐌲𐌰𐌷𐌰𐌷𐌾𐍉 𐌲𐌰𐍆𐌰𐍃𐍄𐍉𐍃], 𐌰𐌹𐌸𐌸𐌰𐌿 [{{fullurl:{{FULLPAGENAME}}|action=edit}} 𐍃𐌺𐌰𐍀𐌾𐌰𐌽 𐌸𐌰𐌽𐌰 𐌻𐌰𐌿𐍆.]</ span>",
        "noarticletext-nopermission": "𐌽𐌿 𐌽𐌹 𐍃𐌹𐌽𐌳 𐌱𐍉𐌺𐍉𐍃 𐌹𐌽 𐌸𐌰𐌼𐌼𐌰 𐌻𐌰𐌿𐌱𐌰.\n𐌼𐌰𐌲𐍄 [[Special:Search/{{PAGENAME}}|𐍃𐍉𐌺𐌾𐌰𐌽 𐌸𐌰𐍄𐌰 𐌻𐌰𐌿𐌱𐌰-𐌿𐍆𐌰𐍂𐌼𐌴𐌻𐌹]] 𐌹𐌽 𐌰𐌽𐌸𐌰𐍂𐌰𐌹𐌼 𐌻𐌰𐌿𐌱𐌰𐌼, 𐌸𐌰𐌿 <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} 𐍃𐍉𐌺𐌾𐌰𐌽 𐌲𐌰𐌷𐌰𐌷𐌾𐍉 𐌲𐌰𐍆𐌰𐍃𐍄𐍉𐍃]</span>, 𐌹𐌸 𐌽𐌹 𐌷𐌰𐌱𐌰𐌹𐍃 𐌰𐌽𐌳𐌻𐌴𐍄 𐍃𐌺𐌰𐍀𐌾𐌰𐌽 𐌸𐌰𐌽𐌰 𐌻𐌰𐌿𐍆.",
-       "userpage-userdoesnotexist-view": "ð\90\8c±ð\90\8d\82ð\90\8c¿ð\90\8cºð\90\8c¾ð\90\8c°ð\90\8cºð\90\8c°ð\90\8d\85ð\90\8d\84ð\90\8d\83ð\90\8c¾ð\90\8d\89 \"$1\" 𐌽𐌹𐍃𐍄 𐌰𐌽𐌰𐌼𐌴𐌻𐌹𐌳𐌰.",
+       "userpage-userdoesnotexist-view": "ð\90\8c±ð\90\8d\82ð\90\8c¿ð\90\8cºð\90\8c¾ð\90\8c°ð\90\8d\82ð\90\8c°ð\90\8c·ð\90\8c½ð\90\8c´ð\90\8c¹ð\90\8c½ \"$1\" 𐌽𐌹𐍃𐍄 𐌰𐌽𐌰𐌼𐌴𐌻𐌹𐌳𐌰.",
        "updated": "(𐌰𐌽𐌰𐌽𐌹𐍅𐌹𐌸)",
        "previewnote": "<strong>𐌲𐌰𐌼𐌹𐌽𐌸𐌴𐌹 𐌸𐌰𐍄𐌴𐌹 𐌸𐌰𐍄𐌰 𐌹𐍃𐍄 𐌸𐌰𐍄𐌰𐌹𐌽𐌴𐌹 𐍆𐌰𐌿𐍂𐌰𐍃𐌹𐌿𐌽𐍃.</strong>\n𐌸𐌴𐌹𐌽𐍉𐍃 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍉𐍃 𐌽𐌰𐌿𐌷 𐌽𐌹 𐌲𐌰𐍆𐌰𐍃𐍄𐌰𐌽𐍉𐍃 𐍃𐌹𐌽𐌳!",
        "continue-editing": "𐌲𐌰𐌲𐌲 𐌳𐌿 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐌹𐍃𐍄𐌰𐌳𐌰",
        "editingsection": "{{GENDER:𐌹𐌽𐌼𐌰𐌹𐌳𐌾𐌰𐌽𐌳𐍃|𐌹𐌽𐌼𐌰𐌹𐌳𐌾𐌰𐌽𐌳𐌴𐌹}} $1 (𐌳𐌰𐌹𐌻)",
        "editingcomment": "{{GENDER:𐌹𐌽𐌼𐌰𐌹𐌳𐌾𐌰𐌽𐌳𐍃|𐌹𐌽𐌼𐌰𐌹𐌳𐌾𐌰𐌽𐌳𐌴𐌹}} $1 (𐌽𐌹𐌿𐌾𐌰 𐌳𐌰𐌹𐌻)",
        "yourdiff": "𐌲𐌰𐍃𐌺𐌰𐌹𐌳𐌴𐌹𐌽𐍉𐍃",
+       "templatesused": "{{PLURAL:$1|𐍆𐌰𐌿𐍂𐌰𐌼𐌴𐌻𐌴𐌹𐌽𐍃 𐌱𐍂𐌿𐌺𐌹𐌸|𐍆𐌰𐌿𐍂𐌰𐌼𐌴𐌻𐌴𐌹𐌽𐍉𐍃 𐌱𐍂𐌿𐌺𐌹𐌳𐍉𐍃}} 𐌰𐌽𐌽𐌰 𐌸𐌰𐌼𐌼𐌰 𐌻𐌰𐌿𐌱𐌰:",
+       "templatesusedpreview": "{{PLURAL:$1|𐍆𐌰𐌿𐍂𐌰𐌼𐌴𐌻𐌴𐌹𐌽𐍃|𐍆𐌰𐌿𐍂𐌰𐌼𐌴𐌻𐌴𐌹𐌽𐍉𐍃}} 𐌱𐍂𐌿𐌺𐌾𐌰𐌽𐌳𐌰 𐌹𐌽 𐌸𐌹𐌶𐌰𐌹 𐍆𐌰𐌿𐍂𐌰𐍃𐌹𐌿𐌽𐌰𐌹:",
        "template-protected": "(𐌷𐌰𐌱𐌰𐌹𐌸 𐌼𐌿𐌽𐌳)",
        "template-semiprotected": "(𐌷𐌰𐌱𐌰𐌹𐌸 𐌷𐌰𐌻𐌱𐌰𐌼𐌿𐌽𐌸)",
        "hiddencategories": "𐍃𐌰 𐌻𐌰𐌿𐍆𐍃 𐌹𐍃𐍄 𐌲𐌰𐌳𐌰𐌹𐌻𐌰 {{PLURAL:$1|1 𐌰𐌽𐌰𐌻𐌰𐌿𐌲𐌽𐌹𐍃 𐌺𐌿𐌽𐌾𐌹𐍃|$1 𐌰𐌽𐌰𐌻𐌰𐌿𐌲𐌽𐌰𐌹𐌶𐌴 𐌺𐌿𐌽𐌾𐌴}}:‎",
        "permissionserrors": "𐌰𐌹𐍂𐌶𐌴𐌹 𐌰𐌽𐌳𐌻𐌴𐍄𐌹𐍃",
        "permissionserrorstext-withaction": "𐌽𐌹 𐌷𐌰𐌱𐌰𐌹𐍃 𐌰𐌽𐌳𐌻𐌴𐍄 𐌳𐌿 $2, 𐌹𐌽 {{PLURAL:$1|𐌹𐍆𐍄𐌿𐌼𐌰𐌹𐌶𐍉𐍃 𐍅𐌰𐌹𐌷𐍄𐌰𐌹𐍃|𐌹𐍆𐍄𐌿𐌼𐌰𐌹𐌶𐍉 𐍅𐌰𐌹𐌷𐍄𐌴}}:",
-       "moveddeleted-notice": "𐍃𐌰 𐌻𐌰𐌿𐍆𐍃 𐌿𐍃𐌽𐌿𐌼𐌰𐌽𐍃 𐌹𐍃𐍄. 𐌿𐍃𐌽𐌿𐌼𐍄𐍃 𐌾𐌰𐌷 𐌲𐌰𐍆𐌰𐍃𐍄𐌰𐌹𐌽𐍃 𐌼𐌹𐌸𐍃𐌰𐍄𐌴𐌹𐌽𐌰𐌹𐍃 𐌿𐍆 𐍃𐌹𐌽𐌳 𐌿𐍃𐍄𐌰𐌹𐌺𐌽𐌴𐌹𐌽𐌰𐌹.",
+       "moveddeleted-notice": "𐍃𐌰 𐌻𐌰𐌿𐍆𐍃 𐌿𐍃𐌽𐌿𐌼𐌰𐌽𐍃 𐌹𐍃𐍄. \n𐌿𐍃𐌽𐌿𐌼𐍄𐍃, 𐌼𐌿𐌽𐌳𐍃 𐌾𐌰𐌷 𐌻𐌰𐌿𐌲 𐌼𐌹𐌸𐍃𐌰𐍄𐌴𐌹𐌽𐌰𐌹𐍃 𐍃𐌹𐌽𐌳 𐌿𐍆 𐌿𐍃𐍄𐌰𐌹𐌺𐌽𐌴𐌹𐌽𐌰𐌹.",
        "postedit-confirmation-created": "𐌻𐌰𐌿𐍆𐍃 𐌲𐌰𐍃𐌺𐌰𐍀𐌰𐌽𐍃 𐌹𐍃𐍄.",
        "edit-already-exists": "𐌽𐌹 𐍅𐌰𐍃 𐌼𐌰𐌷𐍄𐍃 𐍃𐌺𐌰𐍀𐌾𐌰𐌽 𐌸𐌰𐌽𐌰 𐌻𐌰𐌿𐍆. \n𐌾𐌿 𐌹𐍃𐍄.",
        "content-model-wikitext": "𐍅𐌹𐌺𐌹𐌱𐍉𐌺𐍉𐍃",
        "page_last": "𐍃𐍀𐌴𐌳𐌿𐌼𐌹𐍃𐍄",
        "histfirst": "𐍆𐌰𐌹𐍂𐌽𐌹𐍃𐍄",
        "histlast": "𐌽𐌹𐌿𐌾𐌹𐍃𐍄",
+       "history-feed-title": "𐌰𐍆𐍄𐍂𐌰𐍃𐌹𐌿𐌽𐌹𐍃𐍀𐌹𐌻𐌻",
+       "history-feed-description": "𐌰𐍆𐍄𐍂𐌰𐍃𐌹𐌿𐌽𐌹𐍃𐍀𐌹𐌻𐌻 𐌸𐌰𐌼𐌼𐌰 𐌻𐌰𐌿𐌱𐌰 𐌰𐌽𐌰 𐌸𐌰𐌼𐌼𐌰 𐍅𐌹𐌺𐌾𐌰",
        "history-feed-item-nocomment": "$1 𐌰𐍄 $2",
        "rev-delundel": "𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹 𐌰𐌽𐌰𐍃𐌹𐌿𐌽",
        "revdel-restore": "𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹 𐌰𐌽𐌰𐍃𐌹𐌿𐌽",
        "difference-multipage": "(𐌰𐌽𐌸𐌰𐍂𐌻𐌴𐌹𐌺𐌾𐌰 𐌼𐌹𐌸 𐌻𐌰𐌿𐌱𐌰𐌼)",
        "lineno": "𐍃𐍄𐍂𐌹𐌺𐍃 $1:",
        "editundo": "𐍃𐌺𐌰𐍀𐌴𐌹 𐌰𐍆𐍄𐍂𐌰",
+       "diff-empty": "(𐌽𐌹 𐌰𐌽𐌸𐌰𐍂𐌻𐌴𐌹𐌺𐌴𐌹)",
        "diff-multi-sameuser": "({{PLURAL:$1|𐌰𐌹𐌽𐌰 𐌼𐌹𐌳𐌿𐌼𐌰𐌲𐌰𐌱𐍉𐍄𐌴𐌹𐌽𐍃|$1 𐌼𐌹𐌳𐌿𐌼𐌰 𐌲𐌰𐌱𐍉𐍄𐌴𐌹𐌽𐍉𐍃}} 𐍆𐍂𐌰𐌼 𐍃𐌰𐌼𐌹𐌽 𐌱𐍂𐌿𐌺𐌾𐌹𐌽 𐌽𐌹 𐌰𐍄𐌰𐌿𐌲𐌹𐌳𐌰/𐌰𐍄𐌰𐌿𐌲𐌹𐌳𐍉𐍃)",
        "searchresults": "𐍃𐍉𐌺𐌴𐌹𐌽𐌰𐌹𐍃 𐍄𐍉𐌾𐌰",
        "searchresults-title": "𐍃𐍉𐌺𐌴𐌹𐌽𐌰𐌹𐍃 𐍄𐍉𐌾𐌰 𐍆𐌰𐌿𐍂 \"$1\"",
        "nextn-title": "𐌰𐍆𐍄𐌿𐌼(𐌰) $1 {{PLURAL:$1|𐍄𐌰𐌿𐌹|𐍄𐍉𐌾𐌰}}",
        "shown-title": "𐌱𐌰𐌽𐌳𐍅𐌴𐌹 $1 {{PLURAL:$1|𐍄𐌰𐌿𐌹|𐍄𐍉𐌾𐌰}} 𐍈𐌰𐍂𐌾𐌰𐌼𐌼𐌴𐌷 𐌻𐌰𐌿𐌱𐌰.",
        "viewprevnext": "𐍃𐌹𐌿𐌽𐌴𐌹𐍃 ($1 {{int:pipe-separator}} $2) ($3)",
-       "searchmenu-new": "<strong>𐍃𐌺𐌰𐍀𐌴𐌹 𐌻𐌰𐌿𐍆 \"[[:$1]]\" 𐌰𐌽𐌰 𐌸𐌹𐌶𐌰𐌹 𐍅𐌹𐌺𐌹!</strong> {{{{PLURAL:$2|0=|𐍃𐌰𐌹 𐌾𐌰𐌷 𐌻𐌰𐌿𐍆 𐌱𐌹𐌲𐌹𐍄𐌰𐌽𐌰 𐌸𐌴𐌹𐌽𐌰𐌹 𐍃𐍉𐌺𐌴𐌹𐌽𐌰𐌹.|𐍃𐌰𐌹 𐌾𐌰𐌷 𐍄𐍉𐌾𐌰 𐍃𐍉𐌺𐌴𐌹𐌽𐌰𐌹𐍃 𐌱𐌹𐌲𐌹𐍄𐌰𐌽𐌰.}}",
+       "searchmenu-exists": "<strong>𐌹𐍃𐍄 𐌻𐌰𐌿𐍆𐍃 𐌷𐌰𐌹𐍄𐌰𐌽𐍃 \"[[:$1]]\" 𐌰𐌽𐌰 𐌸𐌰𐌼𐌼𐌰 𐍅𐌹𐌺𐌾𐌰.</strong> {{PLURAL:$2|0=|𐍃𐌰𐌹𐍈 𐌾𐌰𐌷 𐌰𐌽𐌸𐌰𐍂𐌰 𐍄𐍉𐌾𐌰 𐍃𐍉𐌺𐌴𐌹𐌽𐌰𐌹𐍃 𐌸𐍉𐌴𐌹 𐌱𐌹𐌲𐌹𐍄𐌰𐌽𐌰 𐍃𐌹𐌽𐌳.}}",
+       "searchmenu-new": "<strong>𐍃𐌺𐌰𐍀𐌴𐌹 𐌻𐌰𐌿𐍆 \"[[:$1]]\" 𐌰𐌽𐌰 𐌸𐌰𐌼𐌼𐌰 𐍅𐌹𐌺𐌾𐌰!</strong> {{{{PLURAL:$2|0=|𐍃𐌰𐌹 𐌾𐌰𐌷 𐌻𐌰𐌿𐍆 𐌱𐌹𐌲𐌹𐍄𐌰𐌽𐌰 𐌸𐌴𐌹𐌽𐌰𐌹 𐍃𐍉𐌺𐌴𐌹𐌽𐌰𐌹.|𐍃𐌰𐌹 𐌾𐌰𐌷 𐍄𐍉𐌾𐌰 𐍃𐍉𐌺𐌴𐌹𐌽𐌰𐌹𐍃 𐌱𐌹𐌲𐌹𐍄𐌰𐌽𐌰.}}",
        "searchprofile-articles": "𐌷𐌰𐌱𐌰𐌽𐌳𐌰𐌽𐍃 𐌻𐌰𐌿𐌱𐍉𐍃",
        "searchprofile-images": "𐌼𐌰𐌽𐌰𐌲𐌼𐌰𐌹𐌳𐌾𐌰",
        "searchprofile-everything": "𐌰𐌻𐌻",
        "searchprofile-everything-tooltip": "𐍃𐍉𐌺𐌴𐌹 𐌰𐌻𐌻 𐌸𐌰𐍄𐌰 (𐌾𐌰𐌷 𐌲𐌰𐍅𐌰𐌿𐍂𐌳𐌾𐌰𐌻𐌰𐌿𐌱𐌰𐌽𐍃)",
        "searchprofile-advanced-tooltip": "𐍃𐍉𐌺𐌴𐌹 𐌹𐌽 𐌱𐌹𐌿𐌷𐍄𐌰𐌹𐌼 𐌽𐌰𐌼𐌰𐍂𐌿𐌼𐌰𐌼",
        "search-result-size": "$1 ({{PLURAL:$2|•𐌰• 𐍅𐌰𐌿𐍂𐌳|•$2• 𐍅𐌰𐌿𐍂𐌳𐌰}})",
-       "search-redirect": "(𐌰𐍆𐍄𐍂𐌰𐍅𐌴𐌹𐍄𐍃 𐍆𐍂𐌰𐌼 𐌸𐌰𐌼𐌼𐌰 $1)",
+       "search-result-category-size": "{{PLURAL:$1|1 𐌲𐌰𐌳𐌰𐌹𐌻𐌰|$1 𐌲𐌰𐌳𐌰𐌹𐌻𐌰𐌽𐍃}} ({{PLURAL:$2|1 𐌼𐌹𐌽𐌽𐌹𐌶𐍉 𐌺𐌿𐌽𐌹|$2 𐌼𐌹𐌽𐌽𐌹𐌶𐍉𐌽𐌰 𐌺𐌿𐌽𐌾𐌰}}, {{PLURAL:$3|1 𐍆𐌰𐌾𐌻|$3 𐍆𐌰𐌾𐌻𐌰}})",
+       "search-redirect": "(𐌰𐍆𐍄𐍂𐌰𐍄𐌰𐌿𐌷𐍄𐍃 𐍆𐍂𐌰𐌼 $1)",
        "search-section": "(𐍆𐌴𐍂𐌰 $1)",
        "search-suggest": "𐌲𐌰𐌼𐌰𐌽𐍄: $1",
        "searchall": "𐌰𐌻𐌻𐍃",
-       "search-showingresults": "{{ZPLURAL:$4|𐍄𐌰𐌿𐌹 <strong>$1 𐍅𐌰𐌹𐌷𐍄𐌰𐌹𐍃 <strong>$3|𐍄𐍉𐌾𐌰 <strong>$1 - $2 𐍅𐌰𐌹𐌷𐍄𐌰𐌹𐍃 <strong>$3}}",
+       "search-showingresults": "{{PLURAL:$4|𐍄𐌰𐌿𐌹 <strong>$1 𐍅𐌰𐌹𐌷𐍄𐌰𐌹𐍃 <strong>$3|𐍄𐍉𐌾𐌰 <strong>$1 - $2 𐍅𐌰𐌹𐌷𐍄𐌰𐌹𐍃 <strong>$3}}",
        "search-nonefound": "𐌽𐌹 𐍄𐌰𐌿𐌹 𐍅𐌰𐍃 𐍃𐌰𐌼𐌰𐌽𐌰 𐍃𐍅𐌰 𐍃𐍉𐌺𐌴𐌹𐌽.",
        "powersearch-legend": "𐍃𐍉𐌺𐌴𐌹",
        "preferences": "𐌼𐌴𐌹𐌽𐍉𐍃 𐍆𐍂𐌹𐌾𐍉𐌽𐍉𐍃 𐍅𐌰𐌹𐌷𐍄𐍃",
        "prefs-skin": "𐍆𐌹𐌻𐌻",
        "skin-preview": "𐍆𐌰𐌿𐍂𐌰𐍃𐌰𐌹𐍈",
        "prefs-rc": "𐌰𐍆𐍄𐌿𐌼𐌹𐍃𐍄𐍉𐍃 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍉𐍃",
-       "saveprefs": "𐌲𐌰𐍆𐌰𐍃𐍄",
+       "prefs-watchlist": "𐍅𐌹𐍄𐌰𐍅𐌹𐌺𐍉",
+       "prefs-editwatchlist": "𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹 𐍅𐌹𐍄𐌰𐍅𐌹𐌺𐍉𐌽",
+       "saveprefs": "𐌲𐌰𐍆𐌰𐍃𐍄𐌰𐌹",
        "searchresultshead": "𐍃𐍉𐌺𐌴𐌹",
+       "group-bot": "𐌱𐌰𐌿𐍄𐌰",
        "grouppage-bot": "{{ns:project}}:𐌱𐌰𐌿𐍄𐌰",
        "grouppage-sysop": "{{ns:project}}:𐍂𐌴𐌹𐌺𐍃",
        "right-writeapi": "𐌱𐍂𐌿𐌺𐌴𐌹𐌽𐍃 API 𐌼𐌴𐌻𐌴𐌹𐌽𐌰𐌹𐍃",
+       "newuserlogpage": "𐌱𐍂𐌿𐌺𐌾𐌰𐌽𐌳𐌹𐍃 𐌲𐌰𐍃𐌺𐌰𐍆𐍄𐌰𐌹𐍃 𐌻𐌰𐌿𐌲",
        "rightslog": "𐌱𐍂𐌿𐌺𐌾𐌰𐌽𐌳𐌹𐍃 𐍂𐌰𐌹𐌷𐍄𐌴 𐌻𐌰𐌿𐌲",
        "action-edit": "𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹 𐌸𐌰𐌽𐌰 𐌻𐌰𐌿𐍆",
        "nchanges": "$1 {{PLURAL:$1|𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍃|𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍉𐍃}}",
        "enhancedrc-history": "𐍃𐍀𐌹𐌻𐌻",
        "recentchanges": "𐌰𐍆𐍄𐌿𐌼𐌹𐍃𐍄𐍉𐍃 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍉𐍃",
+       "recentchanges-legend": "𐌰𐍆𐍄𐌿𐌼𐌹𐍃𐍄𐌰𐌹𐌶𐍉 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍉 𐌼𐌰𐌷𐍄𐌴𐌹𐍃",
        "recentchanges-summary": "𐌰𐍆𐌰𐍂𐌻𐌰𐌹𐍃𐍄𐌴𐌹 𐌸𐌰𐌹𐌼 𐌰𐌽𐌳𐍅𐌰𐌹𐍂𐌸𐌹𐍃𐍄𐍉𐌼 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍉𐌼 𐌳𐌿 𐍅𐌹𐌺𐌾𐌰 𐌰𐌽𐌰 𐌸𐌰𐌼𐌼𐌰 𐌻𐌰𐌿𐌱𐌰.",
        "recentchanges-label-newpage": "𐍃𐍉 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍃 𐌲𐌰𐍃𐌺𐍉𐍀 𐌽𐌹𐌿𐌾𐌰𐌽𐌰 𐌻𐌰𐌿𐍆",
        "recentchanges-label-minor": "𐌸𐌰𐍄𐌰 𐌹𐍃𐍄 𐌻𐌴𐌹𐍄𐌹𐌻𐌰 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍃",
        "recentchanges-label-bot": "𐍃𐍉 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍃 𐍄𐍉𐌾𐌰𐌳𐌰 𐍅𐌰𐍂𐌸 𐍆𐍂𐌰𐌼 𐌼𐌰𐌷𐍄𐌹𐍃𐌺𐌰𐌻𐌺𐌰 (𐌱𐌰𐌿𐍄)",
+       "recentchanges-label-unpatrolled": "𐍃𐍉 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍃 𐌽𐌰𐌿𐌷 𐌽𐌹𐍃𐍄 𐍅𐌰𐍂𐌳𐌹𐌳𐌰",
        "recentchanges-label-plusminus": "𐌻𐌰𐌿𐌱𐌰𐌼𐌹𐌺𐌹𐌻𐌴𐌹 𐌹𐌽𐌼𐌰𐌹𐌳𐌹𐌳𐌰 𐌼𐌹𐌸 𐌸𐌹𐌶𐌰𐌹 𐍂𐌰𐌸𐌾𐍉𐌽 𐌱𐌹𐍄𐍉",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (𐍃𐌰𐌹𐍈 𐌾𐌰𐌷[[Special:NewPages|𐍅𐌹𐌺𐍉 𐌽𐌹𐌿𐌾𐌰𐌹𐌶𐌴 𐌻𐌰𐌿𐌱𐌴]])",
-       "rcfilters-limit-title": "ð\90\8c¹ð\90\8c½ð\90\8c¼ð\90\8c°ð\90\8c¹ð\90\8c³ð\90\8c´ð\90\8c¹ð\90\8c½ð\90\8d\89ð\90\8d\83 𐌳𐌿 𐌱𐌰𐌽𐌳𐍅𐌾𐌰𐌽",
+       "rcfilters-limit-title": "ð\90\8d\84ð\90\8d\89ð\90\8c¾ð\90\8c° 𐌳𐌿 𐌱𐌰𐌽𐌳𐍅𐌾𐌰𐌽",
        "rcfilters-show-new-changes": "𐌱𐌰𐌽𐌳𐍅𐌴𐌹 𐌽𐌹𐌿𐌾𐌰𐍃𐍄𐍉𐍃 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐌹𐌽𐍃",
        "rcfilters-filter-editsbyself-label": "𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍉𐍃 𐍆𐍂𐌰𐌼 𐌸𐌿𐍃",
        "rcfilters-filter-editsbyother-label": "𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍉𐍃 𐍆𐍂𐌰𐌼 𐌰𐌽𐌸𐌰𐍂𐌰𐌹𐌼",
+       "rcfilters-filter-watchlist-notwatched-description": "𐌰𐌻𐌻 𐌰𐌻𐌾𐌰 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐌹𐌼 𐌸𐌴𐌹𐌽𐌰𐌹𐌼 𐍅𐌹𐍄𐌰𐌽𐌰𐌹𐌼 𐌻𐌰𐌿𐌱𐌰𐌼 𐌰𐌽𐌰 𐍅𐌹𐍄𐌰𐍅𐌹𐌺𐍉𐌽.",
+       "rcfilters-watchlist-edit-watchlist-button": "𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹 𐌸𐌴𐌹𐌽𐌰 𐍅𐌹𐌺𐍉𐌽 𐌸𐌰𐌿 𐍅𐌹𐍄𐌰𐌽𐌰𐌽𐍃 𐌻𐌰𐌿𐌱𐌰𐌽𐍃",
        "rclistfrom": "𐌱𐌰𐌽𐌳𐍅𐌴𐌹 𐌽𐌹𐌿𐌾𐍉𐍃 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐌹𐌽𐍃 𐌰𐌽𐌰𐍃𐍄𐍉𐌳𐌾𐌰𐌽𐌳𐌴𐌹𐌽𐍃 𐍆𐍂𐌰𐌼 $2, $3",
        "rcshowhideminor": "$1 𐌼𐌹𐌽𐌽𐌹𐌶𐌴𐌹𐌽𐍃 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍉𐍃",
        "rcshowhideminor-show": "𐌱𐌰𐌽𐌳𐍅𐌴𐌹",
        "rcshowhideanons": "$1 𐌰𐍆𐍆𐌹𐌻𐌷𐌰𐌽𐌰𐌹 𐌱𐍂𐌿𐌺𐌾𐌰𐌽𐌳𐍃",
        "rcshowhideanons-show": "𐌱𐌰𐌽𐌳𐍅𐌴𐌹",
        "rcshowhideanons-hide": "𐌰𐍆𐍆𐌹𐌻𐌷",
+       "rcshowhidepatr": "$1 𐍅𐌰𐍂𐌳𐌹𐌳𐍉𐍃 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍉𐍃",
        "rcshowhidemine": "$1 𐌼𐌴𐌹𐌽𐍉𐍃 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍉𐍃",
        "rcshowhidemine-show": "𐌱𐌰𐌽𐌳𐍅𐌴𐌹",
        "rcshowhidemine-hide": "𐌰𐍆𐍆𐌹𐌻𐌷",
        "newpageletter": "N",
        "boteditletter": "b",
        "rc-change-size-new": "$1 {{PLURAL:$1|𐌱𐌰𐌾𐍄|𐌱𐌰𐌾𐍄𐌰}} 𐌰𐍆𐌰𐍂 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐌰𐌹",
+       "rc-old-title": "𐌸𐌰𐍄𐌴𐌹 𐍆𐍂𐌿𐌼𐌹𐍃𐍄 𐌲𐌰𐍃𐌺𐌰𐍀𐌰𐌽 𐌹𐍃𐍄 𐍃𐍅𐌰 \"$1\"",
        "recentchangeslinked": "𐌲𐌰𐌱𐌿𐌽𐌳𐌰𐌽𐍉𐍃 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍉𐍃",
        "recentchangeslinked-feed": "𐌲𐌰𐌱𐌿𐌽𐌳𐌰𐌽𐍉𐍃 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍉𐍃",
        "recentchangeslinked-toolbox": "𐌲𐌰𐌱𐌿𐌽𐌳𐌰𐌽𐍉𐍃 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍉𐍃",
        "recentchangeslinked-title": "𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍉𐍃 𐌲𐌰𐌱𐌿𐌽𐌳𐌰𐌽𐍉𐍃 𐌼𐌹𐌸 \"$1\"",
-       "recentchangeslinked-summary": "A𐌸𐌰𐍄𐌰 𐌹𐍃𐍄 𐍅𐌹𐌺𐍉 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍉 𐌽𐌹𐌿𐌾𐌰𐌱𐌰 𐌲𐌰𐍄𐌰𐍅𐌹𐌳𐍉𐍃 𐌻𐌰𐌿𐌱𐌰𐌼 𐌲𐌰𐌱𐌿𐌽𐌳𐌰𐌹 𐍃𐌿𐌼𐌰𐌼𐌼𐌰 𐌻𐌰𐌿𐌱𐌰 (𐌸𐌰𐌿 𐌲𐌰𐌳𐌰𐌹𐌻𐌰𐌼 𐍃𐌿𐌼𐌹𐍃 𐌺𐌿𐌽𐌾𐌹𐍃). <strong>𐌻𐌰𐌿𐌱𐍉𐍃 𐌰𐌽𐌰 [[Special:Watchist|your]] 𐍃𐌹𐌽𐌳 </strong>𐍃𐍅𐌹𐌽𐌸𐌰𐌹.",
+       "recentchangeslinked-summary": "𐌼𐌴𐌻𐌴𐌹 𐌽𐌰𐌼𐍉 𐌻𐌰𐌿𐌱𐌹𐍃 𐌳𐌿 𐍃𐌰𐌹𐍈𐌰𐌽 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍉𐍃 𐌰𐌽𐌰 𐌻𐌰𐌿𐌱𐌰𐌼 𐌲𐌰𐍅𐌹𐌳𐌰𐌽𐍉𐍃 𐌳𐌿 𐌸𐌰𐌿 𐌰𐍆 𐌸𐌰𐌼𐌼𐌰 𐌻𐌰𐌿𐌱𐌰. (𐌳𐌿 𐍃𐌰𐌹𐍈𐌰𐌽 𐌲𐌰𐌳𐌰𐌹𐌻𐌰𐌽𐍃 𐌺𐌿𐌽𐌾𐌹𐍃, 𐌼𐌴𐌻𐌴𐌹 {{ns:category}}:𐌽𐌰𐌼𐍉 𐌺𐌿𐌽𐌾𐌹𐍃). 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍉𐍃 𐌳𐌿 𐌻𐌰𐌿𐌱𐌰𐌼 𐌰𐌽𐌰 [[Special:Watchlist|𐌸𐌴𐌹𐌽𐌰𐌹 𐍅𐌹𐍄𐌰𐍅𐌹𐌺𐍉𐌽]] 𐍃𐌹𐌽𐌳 <strong>𐍃𐍅𐌹𐌽𐌸𐌰𐌱𐌰</strong>.",
        "recentchangeslinked-page": "𐌻𐌰𐌿𐌱𐌰𐌽𐌰𐌼𐍉:",
        "recentchangeslinked-to": "𐌱𐌰𐌽𐌳𐍅𐌴𐌹 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐌹𐌽𐍃 𐌻𐌰𐌿𐌱𐌴 𐌸𐌰𐌹𐌴𐌹 𐌲𐌰𐍅𐌹𐌳𐌰𐌽𐌰𐌹 𐌳𐌿 𐌲𐌹𐌱𐌰𐌽𐌰𐌼𐌼𐌰 𐌻𐌰𐌿𐌱𐌰.",
        "upload": "𐌰𐍄𐌱𐌰𐌹𐍂 𐍆𐌰𐌾𐌻",
        "uploadbtn": "𐌰𐍄𐌱𐌰𐌹𐍂 𐍆𐌰𐌾𐌻",
        "uploadlogpage": "𐌰𐍄𐌱𐌰𐌹𐍂 𐌻𐌰𐌿𐌲",
        "filedesc": "𐌼𐌰𐌿𐍂𐌲𐌿𐍃 𐍃𐌺𐌴𐌹𐍂𐌴𐌹𐌽𐍃",
-       "watchthisupload": "Witan so seido",
+       "watchthisupload": "𐌰𐍄𐍅𐌹𐍄 𐌸𐌰𐌼𐌼𐌰 𐍆𐌰𐌾𐌻𐌰",
        "imgfile": "𐍆𐌰𐌾𐌻",
        "listfiles": "𐍆𐌰𐌾𐌻𐌰𐍅𐌹𐌺𐍉",
        "file-anchor-link": "𐍆𐌰𐌾𐌻",
        "newpages": "𐌽𐌹𐌿𐌾𐌰𐌹 𐌻𐌰𐌿𐌱𐍉𐍃",
        "move": "𐌼𐌹𐌸𐍃𐌰𐍄𐌴𐌹",
        "movethispage": "𐌼𐌹𐌸𐍃𐌰𐍄𐌴𐌹 𐌸𐌰𐌽𐌰 𐌻𐌰𐌿𐍆",
+       "pager-older-n": "{{PLURAL:$1|𐍆𐌰𐌹𐍂𐌽𐌹𐌶𐌰 1|𐍆𐌰𐌹𐍂𐌽𐌹𐌶𐌰𐌽𐍃 $1}}",
        "booksources": "𐌱𐍉𐌺𐌰𐌱𐍂𐌿𐌽𐌽𐌰𐌽𐍃",
        "booksources-search-legend": "𐍃𐍉𐌺𐌴𐌹 𐌱𐍉𐌺𐌰𐌱𐍂𐌿𐌽𐌽𐌰𐌽𐍃",
        "booksources-search": "𐍃𐍉𐌺𐌴𐌹",
-       "specialloguserlabel": "Niutand:",
-       "speciallogtitlelabel": "Namo:",
+       "specialloguserlabel": "𐍄𐌰𐌿𐌾𐌰𐌽𐌳𐍃:",
+       "speciallogtitlelabel": "𐌼𐌿𐌽𐌳𐍂𐌴𐌹 (𐌿𐍆𐌰𐍂𐌼𐌴𐌻𐌹 𐌸𐌰𐌿 {{ns:user}}:𐌰𐍄𐌲𐌰𐌲𐌲𐌰𐌽𐌰𐌼𐍉 𐌱𐍂𐌿𐌺𐌾𐌰𐌽𐌳):",
        "log": "𐌻𐌰𐌿𐌲𐌰",
        "all-logs-page": "𐌰𐌻𐌻𐌰 𐌰𐌽𐌳𐌰𐌿𐌲𐌾𐍉 𐌻𐌰𐌿𐌲𐌰",
        "allpages": "𐌰𐌻𐌻𐌰𐌹 𐌻𐌰𐌿𐌱𐍉𐍃",
        "allpagessubmit": "𐌲𐌰𐌲𐌲",
        "categories": "𐌺𐌿𐌽𐌾𐌰",
        "linksearch-ns": "𐌽𐌰𐌼𐌰𐍂𐌿𐌼:",
+       "listgrouprights-members": "(𐍅𐌹𐌺𐍉 𐌲𐌰𐌳𐌰𐌹𐌻𐌰𐌽𐌴)",
        "emailuser": "{{GENDER: 𐍃𐌰𐌽𐌳𐌴𐌹 𐌴-𐌱𐍉𐌺𐍉𐍃 𐌳𐌿 𐌸𐌰𐌼𐌼𐌰 𐌱𐍂𐌿𐌺𐌾𐌰𐌽𐌳|𐍃𐌰𐌽𐌳𐌴𐌹 𐌴-𐌱𐍉𐌺𐍉𐍃 𐌳𐌿 𐌸𐌹𐌶𐌰𐌹 𐌱𐍂𐌿𐌺𐌾𐌰𐌽𐌳𐌾𐌰𐌹}}",
        "watchlist": "𐍅𐌹𐍄𐌰𐍅𐌹𐌺𐍉",
        "mywatchlist": "𐍅𐌹𐍄𐌰𐍅𐌹𐌺𐍉",
-       "watch": "𐌰𐍄𐍅𐌹𐍄",
+       "watch": "𐌰𐍄𐍅𐌹𐍄𐌰𐌹",
        "watchthispage": "𐌰𐍄𐍅𐌹𐍄 𐌸𐌰𐌼𐌼𐌰 𐌻𐌰𐌿𐌱𐌰",
        "unwatch": "𐌿𐌽𐍅𐌹𐍄",
-       "watchlist-details": "{{PLURAL:$1|$1 𐌻𐌰𐌿𐍆𐍃|$1 𐌻𐌰𐌿𐌱𐍉𐍃}} 𐌰𐌽𐌰 𐌸𐌴𐌹𐌽𐌰𐌹 𐍅𐌹𐍄𐌰𐍅𐌹𐌺𐍉𐌽, 𐌽𐌹 𐍃𐌿𐌽𐌳𐍂𐍉 𐍂𐌰𐌷𐌽𐌾𐌰𐌽𐌳𐌰 𐌲𐌰𐍅𐌰𐌿𐍂𐌳𐌾𐌰𐌻𐌰𐌿𐌱𐍉𐍃.",
+       "watchlist-details": "{{PLURAL:$1|$1 𐌻𐌰𐌿𐍆𐍃|$1 𐌻𐌰𐌿𐌱𐍉𐍃}} 𐌰𐌽𐌰 𐌸𐌴𐌹𐌽𐌰𐌹 𐍅𐌹𐍄𐌰𐍅𐌹𐌺𐍉𐌽 (𐌾𐌰𐌷 𐌲𐌰𐍅𐌰𐌿𐍂𐌳𐌾𐌴 𐌻𐌰𐌿𐌱𐍉𐍃)",
+       "wlheader-showupdated": "𐌻𐌰𐌿𐌱𐍉𐍃 𐌸𐌰𐌹𐌴𐌹 𐌹𐌽𐌼𐌰𐌹𐌳𐌹𐌳𐌰𐌹 𐍃𐌹𐌽𐌳 𐍆𐍂𐌰𐌼 𐌰𐍆𐍄𐌿𐌼𐌹𐍃𐍄𐌰𐌼𐌼𐌰 𐌼𐌴𐌻𐌰 𐌸𐌰𐍄𐌴𐌹 𐌲𐌰𐍅𐌴𐌹𐍃𐍉𐌳𐌴𐍃 𐌱𐌰𐌽𐌳𐍅𐌹𐌳𐌰𐌹 𐍃𐌹𐌽𐌳 𐌹𐌽 <strong>𐍃𐍅𐌹𐌽𐌸𐌰𐌹𐌼 𐌱𐍉𐌺𐍉𐌼</strong>.",
+       "wlshowlast": "𐌱𐌰𐌽𐌳𐍅𐌴𐌹 𐌰𐍆𐍄𐌿𐌼𐌹𐍃𐍄𐍉𐍃 $1 𐍈𐌴𐌹𐌻𐍉𐍃, 𐌰𐍆𐍄𐌿𐌼𐌹𐍃𐍄𐌰𐌹 $2 𐌳𐌰𐌲𐍉𐍃",
        "watching": "𐍅𐌹𐍄𐌰𐌽𐌳𐍃...",
        "unwatching": "𐌿𐌽𐍅𐌹𐍄𐌰𐌽𐌳𐍃...",
        "created": "𐌲𐌰𐍃𐌺𐌰𐍀𐌾𐌰𐌽",
        "delete-legend": "𐍆𐍂𐌰𐌵𐌹𐍃𐍄𐌴𐌹",
        "actioncomplete": "𐍄𐌰𐌿𐌹 𐌿𐍃𐍆𐌿𐌻𐌻𐌹𐌸",
        "dellogpage": "𐌻𐌰𐌿𐌲 𐍆𐍂𐌰𐌵𐌹𐍃𐍄𐌴𐌹𐌽𐌰𐌹𐍃",
+       "log-name-create": "𐌻𐌰𐌿𐌲 𐌲𐌰𐍃𐌺𐌰𐍆𐍄𐌰𐌹𐍃 𐌻𐌰𐌿𐌱𐌹𐍃",
+       "log-description-create": "𐌿𐍆 𐌹𐍃𐍄 𐍅𐌹𐌺𐍉 𐌰𐍆𐍄𐌿𐌼𐌹𐍃𐍄𐌰𐌹𐌶𐍉 𐌻𐌰𐌿𐌱𐌴 𐌲𐌰𐍃𐌺𐌰𐍆𐍄𐌴.",
+       "logentry-create-create": "$1 {{GENDER:$2|𐌲𐌰𐍃𐌺𐍉𐍀}} 𐌻𐌰𐌿𐍆 $3",
        "deleteotherreason": "𐌰𐌽𐌸𐌰𐍂𐌰/𐌼𐌰𐌹𐍃 𐌼𐌹𐍄𐍉𐌽𐍃:",
        "deletereasonotherlist": "𐌰𐌽𐌸𐌰𐍂𐌰 𐌼𐌹𐍄𐍉𐌽𐍃",
        "rollbacklink": "𐌰𐍆𐍅𐌰𐌻𐍅𐌴𐌹",
        "rollbacklinkcount": "𐌰𐍆𐍅𐌰𐌻𐍅𐌴𐌹 $1 {{PLURAL:$1|𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽|𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐌹𐌽𐍃}}",
        "protectlogpage": "𐍆𐍂𐌹𐌸𐌿𐌲𐌰𐍆𐌰𐍃𐍄𐌰𐌹𐌽𐍃",
+       "protectedarticle": "𐌲𐌰𐍆 \"[[$1]]\" 𐌼𐌿𐌽𐌳",
+       "modifiedarticleprotection": "𐌹𐌽𐌼𐌰𐌹𐌳𐌹𐌳𐌰 𐌷𐌰𐌿𐌷𐌹𐌸𐌰 𐌼𐌿𐌽𐌳𐌹𐍃 𐍆𐌰𐌿𐍂 \"[[$1]]\"",
        "prot_1movedto2": "[[$1]] 𐌼𐌹𐌸𐍃𐌰𐍄𐌹𐌸 𐌳𐌿 [[$2]]",
        "protect-default": "𐌰𐌽𐌳𐌻𐌴𐍄 𐌰𐌻𐌻𐌰𐌹𐌼 𐌱𐍂𐌿𐌺𐌾𐌰𐌽𐌳𐌰𐌼",
        "protect-level-sysop": "𐌰𐌽𐌳𐌻𐌴𐍄𐌹𐌸 𐌸𐌰𐍄𐌰𐌹𐌽𐌴𐌹 𐍂𐌴𐌹𐌺𐍃",
        "contributions": "𐌱𐌹𐌰𐌿𐌺𐌰𐌹𐌽𐌴𐌹𐍃 𐌱𐍂𐌿𐌺𐌾𐌰𐌽𐌳𐌹𐍃 {{{{GENDER:$1|User}}",
        "mycontris": "𐌱𐌹𐌰𐌿𐌺𐌰𐌹𐌽𐌴𐌹𐍃",
        "contribsub2": "𐍆𐌰𐌿𐍂 $1 ($2)",
+       "nocontribs": "𐌽𐌹 𐌱𐌹𐌲𐌹𐍄𐌰𐌽𐍉𐍃 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍉𐍃 𐌲𐌰𐌻𐌴𐌹𐌺𐍉𐌽𐌳𐌴𐌹𐌽𐍃 𐌸𐌰𐌹𐌼 𐌱𐌹𐌳𐍉𐌼.",
        "uctop": "(𐌷𐌰𐌿𐌱𐌹𐌸)",
        "month": "𐍆𐍂𐌰𐌼 𐌼𐌴𐌽𐍉𐌸 (𐌾𐌰𐌷 𐌰𐌹𐍂𐌹𐍃):",
        "year": "𐍆𐍂𐌰𐌼 𐌾𐌴𐍂𐌰 (𐌾𐌰𐌷 𐌰𐌹𐍂𐌹𐍃):",
-       "sp-contributions-newbies-sub": "ð\90\8c½ð\90\8c¹ð\90\8c¿ð\90\8c¾ð\90\8c°ð\90\8c¹ð\90\8c¼ ð\90\8cºð\90\8c°ð\90\8d\85ð\90\8d\84ð\90\8d\83ð\90\8c¾ð\90\8d\89𐌼",
+       "sp-contributions-newbies-sub": "ð\90\8c½ð\90\8c¹ð\90\8c¿ð\90\8c¾ð\90\8c°ð\90\8c¹ð\90\8c¼ ð\90\8d\82ð\90\8c°ð\90\8c·ð\90\8c½ð\90\8c´ð\90\8c¹ð\90\8c½ð\90\8c¹𐌼",
        "sp-contributions-blocklog": "𐍆𐌰𐌿𐍂𐌳𐌰𐌼𐌼𐌴𐌹𐌽𐌰𐌹𐍃 𐌲𐌰𐍆𐌰𐍃𐍄𐌰𐌹𐌽𐍃.",
+       "sp-contributions-uploads": "𐌰𐍄𐌱𐌰𐌹𐍂𐌹𐌳𐍉𐍃 𐍅𐌰𐌹𐌷𐍄𐍃",
+       "sp-contributions-logs": "𐌻𐌰𐌿𐌲𐌰",
        "sp-contributions-talk": "𐌲𐌰𐍅𐌰𐌿𐍂𐌳𐌹",
+       "sp-contributions-username": "IP 𐍃𐍄𐌰𐌸𐍃 𐌸𐌰𐌿 𐌰𐍄𐌲𐌰𐌲𐌲𐌰𐌽𐌰𐌼𐍉:",
+       "sp-contributions-toponly": "𐌱𐌰𐌽𐌳𐍅𐌴𐌹 𐌸𐌰𐍄𐌰𐌹𐌽𐌴𐌹 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍉𐍃 𐌸𐍉𐌶𐌴𐌹 𐍃𐌹𐌽𐌳 𐌰𐍆𐍄𐌿𐌼𐌹𐍃𐍄𐍉𐍃 𐌰𐍆𐍄𐍂𐌰𐍃𐌹𐌿𐌽𐌴𐌹𐍃",
+       "sp-contributions-newonly": "𐌱𐌰𐌽𐌳𐍅𐌴𐌹 𐌸𐌰𐍄𐌰𐌹𐌽𐌴𐌹 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍉𐍃 𐌸𐍉𐌶𐌴𐌹 𐍃𐌹𐌽𐌳 𐌻𐌰𐌿𐌱𐌹𐍃 𐌲𐌰𐍃𐌺𐌰𐍆𐍄𐌴𐌹𐍃",
        "sp-contributions-submit": "𐍃𐍉𐌺𐌴𐌹",
        "whatlinkshere": "𐌰𐌻𐌻𐌰𐌹 𐌻𐌰𐌿𐌱𐍉𐍃 𐌸𐌰𐌹𐌴𐌹 𐌱𐍂𐌹𐌲𐌲𐌰𐌽𐌳 𐌸𐌿𐌺 𐌷𐌹𐌳𐍂𐌴",
        "whatlinkshere-title": "𐌻𐌰𐌿𐌱𐍉𐍃 𐌸𐌰𐌹𐌴𐌹 𐍄𐌰𐌹𐌺𐌽𐌾𐌰𐌽𐌳 𐌳𐌿 \"$1\"",
        "whatlinkshere-page": "𐌻𐌰𐌿𐍆𐍃:",
-       "linkshere-2": "𐌹𐍆𐍄𐌿𐌼𐌰𐌹 𐌻𐌰𐌿𐌱𐍉𐍃 𐌱𐍂𐌹𐌲𐌲𐌰𐌽𐌳 𐌸𐌿𐌺  <strong>$1</strong>:",
+       "linkshere": "𐌹𐍆𐍄𐌿𐌼𐌰𐌹 𐌻𐌰𐌿𐌱𐍉𐍃 𐌱𐍂𐌹𐌲𐌲𐌰𐌽𐌳 𐌸𐌿𐌺  <strong>$2</strong>:",
+       "nolinkshere": "𐌽𐌹 𐌻𐌰𐌿𐌱𐍉𐍃 𐌲𐌰𐍅𐌹𐌳𐌰𐌽𐌳 𐌳𐌿 <strong>$2</strong>.",
        "isredirect": "𐌰𐌻𐌾𐌰𐍂 𐌱𐍂𐌹𐌲𐌲𐌰𐌽𐌳𐍃 𐌻𐌰𐌿𐍆𐍃",
        "istemplate": "𐍄𐍂𐌰𐌽𐍃𐌺𐌻𐌿𐍃𐌾𐍉",
+       "isimage": "𐍆𐌰𐌾𐌻𐌰𐌲𐌰𐍅𐌹𐍃𐍃",
        "whatlinkshere-prev": "{{PLURAL:$1|𐌰𐍆𐍄𐌿𐌼𐌹𐍃𐍄𐌰|𐌰𐍆𐍄𐌿𐌼𐌹𐍃𐍄𐌰𐌽𐍃 $1}}",
        "whatlinkshere-next": "{{PLURAL:$1|𐌹𐍆𐍄𐌿𐌼𐌰|𐌹𐍆𐍄𐌿𐌼𐌰𐌽𐍃 $1}}",
        "whatlinkshere-links": "← 𐌲𐌰𐍅𐌹𐍃𐍃𐌴𐌹𐍃",
        "blocklogpage": "𐍆𐌰𐌿𐍂𐌳𐌰𐌼𐌼𐌴𐌹𐌽𐌰𐌹𐍃 𐌲𐌰𐍆𐌰𐍃𐍄𐌰𐌹𐌽𐍃.",
        "blocklogentry": "𐌰𐍆𐌳𐍂𐌰𐌿𐍃𐌹𐌸 [[$1]] 𐍆𐌰𐌿𐍂 $2 $3",
        "newtitle": "𐌽𐌹𐌿𐌾𐌹 𐌿𐍆𐌰𐍂𐌼𐌴𐌻𐌹:",
-       "move-watch": "𐌰𐍄𐍅𐌹𐍄 𐌱𐍂𐌿𐌽𐌽𐌰𐌻𐌰𐌿𐌱𐌰 𐌾𐌰𐌷 𐌼𐌿𐌽𐌳𐍂𐌴𐌹𐌻𐌰𐌿𐌱𐌰",
+       "move-watch": "𐌰𐍄𐍅𐌹𐍄𐌰𐌹 𐌱𐍂𐌿𐌽𐌽𐌰𐌻𐌰𐌿𐌱𐌰 𐌾𐌰𐌷 𐌼𐌿𐌽𐌳𐍂𐌹𐌻𐌰𐌿𐌱𐌰",
        "movepagebtn": "𐌼𐌹𐌸𐍃𐌰𐍄𐌴𐌹 𐌻𐌰𐌿𐍆",
        "movelogpage": "𐌼𐌹𐌸𐍃𐌰𐍄𐌴𐌹 𐌲𐌰𐍆𐌰𐍃𐍄𐌰𐌹𐌽",
        "movereason": "𐍆𐌰𐌹𐍂𐌹𐌽𐌰:",
        "export": "𐌿𐍄𐌱𐌰𐌹𐍂 𐌻𐌰𐌿𐌱𐌰𐌽𐍃",
        "allmessages-filter-translate": "𐌲𐌰𐍃𐌺𐌴𐌹𐍂𐌴𐌹",
        "thumbnail-more": "\n𐌼𐌹𐌺𐌹𐌻𐌴𐌹",
+       "importlogpage": "𐌹𐌽𐌽𐌰𐍄𐌱𐌰𐌹𐍂 𐌻𐌰𐌿𐌲",
        "tooltip-pt-userpage": "{{GENDER:|Your user}} 𐌻𐌰𐌿𐍆𐍃",
        "tooltip-pt-mytalk": "{{GENDER:|𐌸𐌴𐌹𐌽𐍃}} 𐌻𐌰𐌿𐍆𐍃 𐌲𐌰𐍅𐌰𐌿𐍂𐌳𐌾𐌹𐍃",
        "tooltip-pt-preferences": "{{GENDER:|Your}} 𐌲𐌰𐌻𐌴𐌹𐌺𐌰𐌽𐌳𐌴𐌹𐌽𐍃 𐍅𐌰𐌹𐌷𐍄𐍃",
        "tooltip-pt-mycontris": "A list of {{GENDER:|your}} 𐌱𐌹𐌰𐌿𐌺𐌰𐌹𐌽𐌴𐌹𐍃 𐌱𐍂𐌿𐌺𐌾𐌰𐌽𐌳𐌹𐍃",
        "tooltip-pt-login": "𐍄𐌹𐌼𐍂𐌾𐌰𐌶𐌰 𐌳𐌿 𐌰𐍄𐌲𐌰𐌲𐌲𐌰𐌽, 𐌹𐌸 𐌽𐌹𐍃𐍄 𐍃𐌺𐌿𐌻𐌳 𐌸𐌿𐍃",
        "tooltip-pt-logout": "𐌰𐍆𐌻𐌴𐌹𐌸",
-       "tooltip-pt-createaccount": "ð\90\8c±ð\90\8c°ð\90\8d\84ð\90\8c¹ð\90\8c¶ð\90\8d\89 ð\90\8c¹ð\90\8d\83ð\90\8d\84 ð\90\8c¸ð\90\8c¿ð\90\8d\83 ð\90\8d\83ð\90\8cºð\90\8c°ð\90\8d\80ð\90\8c¾ð\90\8c°ð\90\8c½ ð\90\8cºð\90\8c°ð\90\8d\85ð\90\8d\84ð\90\8d\83ð\90\8c¾ð\90\8d\89𐌽, 𐌹𐌸 𐍃𐌺𐌿𐌻𐌳 𐌽𐌹𐍃𐍄",
+       "tooltip-pt-createaccount": "ð\90\8c±ð\90\8c°ð\90\8d\84ð\90\8c¹ð\90\8c¶ð\90\8d\89 ð\90\8c¹ð\90\8d\83ð\90\8d\84 ð\90\8c¸ð\90\8c¿ð\90\8d\83 ð\90\8d\83ð\90\8cºð\90\8c°ð\90\8d\80ð\90\8c¾ð\90\8c°ð\90\8c½ ð\90\8d\82ð\90\8c°ð\90\8c·ð\90\8c½ð\90\8c´ð\90\8c¹𐌽, 𐌹𐌸 𐍃𐌺𐌿𐌻𐌳 𐌽𐌹𐍃𐍄",
        "tooltip-ca-talk": "𐌲𐌰𐍅𐌰𐌿𐍂𐌳𐌹 𐌱𐌹 𐌷𐌰𐌱𐌰𐌽𐌳𐌰𐌽 𐌻𐌰𐌿𐍆",
        "tooltip-ca-edit": "𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹 𐌸𐌰𐌽𐌰 𐌻𐌰𐌿𐍆",
        "tooltip-ca-addsection": "𐌰𐌽𐌰𐍃𐍄𐍉𐌳𐌴𐌹 𐌽𐌹𐌿𐌾𐌰 𐌳𐌰𐌹𐌻",
        "tooltip-search-go": "𐌲𐌰𐌲𐌲 𐌳𐌿 𐌻𐌰𐌿𐌱𐌰 𐌼𐌹𐌸 𐌸𐌰𐌼𐌼𐌰 𐌲𐌰𐌻𐌴𐌹𐌺𐌰𐌼𐌼𐌰 𐌽𐌰𐌼𐌹𐌽",
        "tooltip-search-fulltext": "𐍃𐍉𐌺𐌴𐌹 𐌻𐌰𐌿𐌱𐌰𐌽𐍃 𐌸𐌰𐌹𐌼 𐌱𐍉𐌺𐍉𐌼",
        "tooltip-p-logo": "𐌲𐌰𐍅𐌴𐌹𐍃 𐌷𐌰𐌿𐌱𐌹𐌳𐌰𐌻𐌰𐌿𐌱𐌹𐍃",
-       "tooltip-n-mainpage": "𐌲𐌰𐍅𐌴𐌹𐍃 𐌷𐌰𐌿𐌱𐌹𐌳𐌰𐌻𐌰𐌿𐌱𐌹𐍃",
+       "tooltip-n-mainpage": "𐌲𐌰𐍅𐌴𐌹𐍃𐍉 𐌷𐌰𐌿𐌱𐌹𐌳𐌰𐌻𐌰𐌿𐌱𐌹𐍃",
        "tooltip-n-mainpage-description": "𐌲𐌰𐍅𐌴𐌹𐍃 𐌷𐌰𐌿𐌱𐌹𐌳𐌰𐌻𐌰𐌿𐌱𐌹𐍃",
        "tooltip-n-portal": "𐌱𐌹 𐍆𐌰𐌿𐍂𐌰𐍅𐌰𐌿𐍂𐍀𐌰, 𐍈𐌰 𐌼𐌰𐌲𐍄 𐍄𐌰𐌿𐌾𐌰𐌽, 𐍈𐌰𐍂 𐌱𐌹𐌲𐌹𐍄𐌹𐍃 𐍅𐌰𐌹𐌷𐍄𐌹𐌽𐍃",
        "tooltip-n-currentevents": "𐌱𐌹𐌲𐌹𐍄 𐌼𐌰𐌹𐍃 𐌺𐌿𐌽𐌸𐌹 𐌱𐌹 𐌽𐌹𐌿𐌾𐍉𐍃 𐍅𐌰𐌿𐍂𐌸𐌰𐌽𐍉𐍃 𐍅𐌰𐌹𐌷𐍄𐌹𐌽𐍃",
        "tooltip-ca-nstab-image": "𐌱𐌰𐌽𐌳𐍅𐌴𐌹 𐍆𐌰𐌾𐌻𐌰𐌻𐌰𐌿𐍆",
        "tooltip-ca-nstab-template": "𐍃𐌰𐌹𐍈 𐍆𐌰𐌿𐍂𐌰𐌼𐌴𐌻𐌴𐌹𐌽",
        "tooltip-ca-nstab-category": "𐍃𐌰𐌹𐍈 𐌺𐌿𐌽𐌾𐌰𐌻𐌰𐌿𐍆",
-       "tooltip-save": "𐌲𐌰𐍆𐌰𐍃𐍄 𐌸𐌴𐌹𐌽𐍉𐍃 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐌹𐌽𐍃",
+       "tooltip-save": "𐌲𐌰𐍆𐌰𐍃𐍄𐌰𐌹 𐌸𐌴𐌹𐌽𐍉𐍃 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐌹𐌽𐍃",
        "tooltip-preview": "𐍆𐌰𐌿𐍂𐌰𐍃𐌰𐌹𐍈 𐌸𐌴𐌹𐌽𐍉𐍃 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍉𐍃. 𐌱𐌹𐌳𐌾𐌰𐌼 𐌸𐌿𐌺, 𐌱𐍂𐌿𐌺𐌴𐌹 𐌸𐌹𐍃 𐌸𐌰𐍄𐌰 𐍆𐍂𐌿𐌼𐌹𐍃𐍄 𐍆𐌰𐌿𐍂𐌸𐌹𐌶𐌴𐌹 𐌲𐌰𐍆𐌰𐍃𐍄𐌰𐌹𐍃.",
        "tooltip-diff": "𐌱𐌰𐌽𐌳𐍅𐌴𐌹 𐍈𐌹𐌻𐌴𐌹𐌺𐍉𐍃 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐌹𐌽𐍃 𐌲𐌰𐍄𐌰𐍅𐌹𐌳𐌴𐍃 𐌳𐌿 𐌸𐌰𐌹𐌼 𐌱𐍉𐌺𐍉𐌼",
        "tooltip-watch": "𐌱𐌹𐌰𐌹𐌰𐌿𐌺 𐌸𐌰𐌽𐌰 𐌻𐌰𐌿𐍆 𐌳𐌿 𐌸𐌴𐌹𐌽𐌰𐌹 𐍅𐌹𐍄𐌰𐍅𐌹𐌺𐍉𐌽",
        "tooltip-undo": "\"𐌽𐌹𐌿𐍃𐌺𐌰𐍀𐌾𐌰𐌽\" 𐌱𐌰𐌺𐌼𐌰𐌹𐌳𐌾𐌹𐌸 𐌹𐌽𐌼𐌰𐌹𐌳𐌲𐌴𐌹𐌽𐍃 𐌾𐌰𐌷 𐌿𐍃𐌻𐌿𐌺𐍉𐌸 𐌼𐌰𐌹𐌳𐌾𐌰𐍆𐍉𐍂𐌼𐍉𐌽 𐍃𐍅𐌴 𐍆𐌰𐌿𐍂𐍃𐌰𐌹𐍈𐌰 𐌷𐌹𐍅𐌾𐌰. 𐌸𐌰𐍄𐌰 𐌻𐌴𐍄 𐌰𐌽𐌰𐌿𐌺𐌰𐌽𐌰𐌽 𐍃𐌰𐌿𐌸𐌰 𐌹𐌽 𐌹𐌽𐌽𐌰𐌷𐌰𐌻𐌳𐌰𐌰𐌽𐌲𐌰𐌱𐌰.",
        "tooltip-summary": "𐌼𐌴𐌻𐌴𐌹 𐌻𐌴𐌹𐍄𐌹𐌻𐌰 𐌰𐍆𐌼𐌰𐌿𐍂𐌲𐌴𐌹𐌽",
        "simpleantispam-label": "𐌰𐌽𐍄𐌹-𐍃𐍀𐌰𐌼 𐍃𐍉𐌺𐌴𐌹𐌽𐍃.\n<strong>𐌽𐌹</strong> 𐌼𐌴𐌻𐌴𐌹 𐌷𐌴𐍂!",
+       "pageinfo-title": "𐌹𐌽𐍆𐌰𐌿𐍂𐌼𐌰𐍄𐍃𐌾𐍉 𐍆𐌰𐌿𐍂 \"$1\"",
        "pageinfo-header-edits": "𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹 𐍃𐍀𐌹𐌻𐌻",
        "pageinfo-header-restrictions": "𐌻𐌰𐌿𐌱𐌹𐍃 𐌼𐌿𐌽𐌳𐍃",
        "pageinfo-display-title": "𐌱𐌰𐌽𐌳𐍅𐌴𐌹 𐌿𐍆𐌰𐍂𐌼𐌴𐌻𐌾𐌰",
        "pageinfo-article-id": "𐌻𐌰𐌿𐌱𐌹𐍃 𐌹𐌳",
        "pageinfo-robot-index": "𐌰𐌽𐌳𐌻𐌴𐍄𐌰𐌽",
+       "pageinfo-robot-noindex": "𐌰𐌽𐌳𐌻𐌴𐍄𐌰𐌽 𐌽𐌹𐍃𐍄",
+       "pageinfo-watchers": "𐍂𐌰𐌸𐌾𐍉 𐌻𐌰𐌿𐌱𐌰𐍅𐌹𐍄𐌰𐌽𐌳𐌴",
+       "pageinfo-subpages-name": "𐍂𐌰𐌸𐌾𐍉 𐌼𐌹𐌽𐌽𐌹𐌶𐌰𐌽𐌴 𐌻𐌰𐌿𐌱𐌴 𐌸𐌹𐍃 𐌻𐌰𐌿𐌹𐍃",
        "pageinfo-firstuser": "𐌻𐌰𐌿𐌱𐌰𐍃𐌺𐌰𐍀𐌾𐌰𐌽𐌳𐍃",
+       "pageinfo-firsttime": "𐌳𐌰𐌲𐍃 𐌲𐌰𐍃𐌺𐌰𐍆𐍄𐌰𐌹𐍃 𐌻𐌰𐌿𐌱𐌹𐍃",
        "pageinfo-lastuser": "𐌰𐍆𐍄𐌿𐌼𐌹𐍃𐍄𐍃 𐌹𐌽𐌼𐌰𐌹𐌳𐌾𐌰𐌽𐌳𐍃",
+       "pageinfo-lasttime": "𐌳𐌰𐌲𐍃 𐌰𐍆𐍄𐌿𐌼𐌹𐍃𐍄𐌰𐌹𐌶𐍉𐍃 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐌰𐌹𐍃",
+       "pageinfo-edits": "𐌰𐌻𐌻𐌰 𐍂𐌰𐌸𐌾𐍉 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍉",
+       "pageinfo-authors": "𐌰𐌻𐌻𐌰 𐍂𐌰𐌸𐌾𐍉 𐌼𐌹𐍃𐍃𐌰𐌻𐌴𐌹𐌺𐌰𐌹𐌶𐌴 𐌱𐍉𐌺𐌰𐍂𐌾𐌴",
        "pageinfo-recent-edits": "𐌰𐌽𐌳𐍅𐌰𐌹𐍂𐌸𐌰 𐍂𐌰𐌸𐌾𐍉 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍉 (𐌹𐌽 $1)",
        "pageinfo-recent-authors": "𐌰𐌽𐌳𐍅𐌰𐌹𐍂𐌸𐌰 𐍂𐌰𐌸𐌾𐍉 𐌼𐌹𐍃𐍃𐌰𐌻𐌴𐌹𐌺𐌰𐌹𐌶𐌴 𐌼𐌴𐌻𐌾𐌰𐌽𐌳𐌴",
        "pageinfo-magic-words": "{{PLURAL:$1|𐌻𐌿𐌱𐌾𐌰𐌻𐌴𐌹𐍃|𐌻𐌿𐌱𐌾𐌰𐌻𐌴𐌹𐍃𐌰}} {{PLURAL:$1|𐍅𐌰𐌿𐍂𐌳|𐍅𐌰𐌿𐍂𐌳𐌰}} ($1)",
+       "pageinfo-hidden-categories": "{{PLURAL:$1|𐌰𐌽𐌰𐌻𐌰𐌿𐌲𐌽 𐌺𐌿𐌽𐌹|𐌰𐌽𐌰𐌻𐌰𐌿𐌲𐌽𐌰 𐌺𐌿𐌽𐌾𐌰}} ($1)",
        "pageinfo-toolboxlink": "𐌺𐌿𐌽𐌸𐌹 𐌻𐌰𐌿𐌱𐌹𐍃",
        "pageinfo-contentpage-yes": "𐌾𐌰𐌹",
        "previousdiff": "← 𐍆𐌰𐌹𐍂𐌽𐌹𐌶𐌴𐌹 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍃",
        "nextdiff": "𐌽𐌹𐌿𐌾𐌹𐌶𐌴𐌹 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍃 →",
+       "widthheightpage": "$1 × $2, $3 {{PLURAL:$3|𐌻𐌰𐌿𐍆𐍃|𐌻𐌰𐌿𐌱𐍉𐍃}}",
        "file-info-size": "$1 × $2 𐍀𐌹𐌺𐍃𐌴𐌻𐌰, 𐍆𐌴𐌹𐌻𐍅𐌰𐌷𐍃𐍄𐌿𐍃: $3, 𐌼𐌹𐌼𐌴 𐌺𐌿𐌽𐌹: $4",
        "show-big-image": "𐍆𐍂𐌿𐌼𐌹𐍃𐍄 𐍆𐌰𐌾𐌻",
        "show-big-image-preview": "𐌼𐌹𐌺𐌹𐌻𐌴𐌹 𐌸𐌹𐌶𐍉𐍃 𐍆𐌰𐌿𐍂𐌰𐍃𐌹𐌿𐌽𐌰𐌹𐍃: $1.",
        "show-big-image-size": "$1 × $2 𐍆𐍂𐌹𐍃𐌰𐌷𐍄𐌹𐍃𐍄𐌰𐌱𐌴𐌹𐍃",
        "ilsubmit": "𐍃𐍉𐌺𐌴𐌹",
        "metadata": "𐌿𐍆𐌰𐍂𐌳𐌰𐍄𐌰",
+       "exif-software": "𐌱𐍂𐌿𐌺𐌹𐌸 𐍃𐌰𐌿𐍆𐍄𐍅𐌰𐌹𐍂",
+       "exif-exifversion": "Exif 𐌿𐍃𐌼𐌴𐍂𐌹",
        "exif-colorspace": "𐍆𐌰𐍂𐍅𐌰𐍂𐌿𐌼",
        "exif-orientation-1": "𐌱𐌹 𐌱𐌹𐌿𐌷𐍄𐌾𐌰",
        "namespacesall": "𐌰𐌻𐌻",
        "imgmultigo": "𐌲𐌰𐌲𐌲!",
        "imgmultigoto": "𐌲𐌰𐌲𐌲 𐌳𐌿 𐌻𐌰𐌿𐌱𐌰 $1",
        "table_pager_limit_submit": "Affgaggan",
+       "watchlisttools-view": "𐌱𐌰𐌽𐌳𐍅𐌴𐌹 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍉𐍃 𐌲𐌰𐌲𐌰𐌷𐌰𐍆𐍄𐌹𐌳𐍉𐍃 𐌳𐌿 𐌸𐌰𐌼𐌼𐌰",
        "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|𐌲𐌰𐍅𐌰𐌿𐍂𐌳𐌾𐌰]])",
        "version-other": "Anþar",
        "version-poweredby-translators": "translatewiki.net 𐌲𐌰𐍃𐌺𐌴𐌹𐍂𐌾𐌰𐌽𐍃",
        "redirect-submit": "𐌲𐌰𐌲𐌲",
        "redirect-value": "𐍅𐌰𐌹𐍂𐌸:",
+       "redirect-page": "𐌻𐌰𐌿𐌱𐌹𐍃 ID",
        "redirect-revision": "𐌰𐍆𐍄𐍂𐌰𐍃𐌹𐌿𐌽𐍃 𐌻𐌰𐌿𐌱𐌹𐍃",
        "redirect-file": "𐍆𐌰𐌾𐌻𐌰𐌽𐌰𐌼𐍉",
        "specialpages": "𐌿𐍃𐍃𐌹𐌽𐌳𐌰𐌹 𐌻𐌰𐌿𐌱𐍉𐍃",
        "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|𐍃𐍉𐌺𐌴𐌹𐌽𐌹𐍅𐌰𐌿𐍂𐌳|𐍃𐍉𐌺𐌴𐌹𐌽𐌹𐍅𐌰𐌿𐍂𐌳𐌰}}]]: $2)",
        "tags-source-header": "𐌱𐍂𐌿𐌽𐌽𐌰",
        "tags-actions-header": "𐍄𐍉𐌾𐌰",
+       "tags-active-yes": "𐌾𐌰𐌹",
+       "tags-active-no": "𐌽𐌴",
        "tags-source-none": "𐌽𐌹 𐌾𐌿 𐌱𐍂𐌿𐌺𐌾𐌰𐌳𐌰",
        "tags-edit": "𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹",
        "tags-delete": "𐌿𐍃𐌽𐌹𐌼",
        "tags-deactivate-submit": "𐌿𐌽𐌲𐌰𐌵𐌹𐌿𐌴𐌹",
        "logentry-delete-delete": "$1 {{GENDER:$2|𐌿𐍃𐌽𐌰𐌼}} 𐌻𐌰𐌿𐍆 $3",
        "logentry-move-move": "$1 {{GENDER:$2|𐌼𐌹𐌸𐍃𐌰𐍄𐌹𐌳𐌰}} 𐌻𐌰𐌿𐍆 $3 𐌳𐌿 $4",
-       "logentry-newusers-create": "𐌱𐍂𐌿𐌺𐌾𐌰𐌺𐌰𐍅𐍄𐍃𐌾𐍉 $1 𐍅𐌰𐍃 𐌲𐌰𐍃𐌺𐌰𐍀𐌰𐌽𐌰",
+       "logentry-newusers-create": "𐌱𐍂𐌿𐌺𐌾𐌰𐍂𐌰𐌷𐌽𐌴𐌹𐌽𐍃 $1 𐍅𐌰𐍃 𐌲𐌰𐍃𐌺𐌰𐍀𐌰𐌽𐌰",
+       "logentry-upload-upload": "$1 {{GENDER:$2|𐌿𐍆𐌰𐍂𐌱𐌰𐍂}} $3",
        "rightsnone": "(𐌽𐌹)",
        "searchsuggest-search": "𐍃𐍉𐌺𐌴𐌹",
        "duration-days": "$1 {{PLURAL:$1|𐌳𐌰𐌲𐍃|𐌳𐌰𐌲𐍉𐍃}}"
index 1bd6255..4b224c2 100644 (file)
        "whatlinkshere": "Τὰ ἐνθάδε ἄγοντα",
        "whatlinkshere-title": "Δέλτοι συνεζευγμέναι μετὰ τοῦ \"$1\"",
        "whatlinkshere-page": "Δέλτος:",
-       "linkshere-2": "Τάδε ἄγουσι πρὸς '''$1''':",
-       "nolinkshere-2": "Οὐδένα ἄγουσι πρὸς '''$1'''.",
-       "nolinkshere-ns-2": "Οὐδεμία δέλτος συνδέεται τῇ '''$1''' ἐν τῷ ἐπιλεγμένῳ ὀνοματείῳ.",
+       "linkshere": "Τάδε ἄγουσι πρὸς '''$2''':",
+       "nolinkshere": "Οὐδένα ἄγουσι πρὸς '''$2'''.",
+       "nolinkshere-ns": "Οὐδεμία δέλτος συνδέεται τῇ '''$2''' ἐν τῷ ἐπιλεγμένῳ ὀνοματείῳ.",
        "isredirect": "ἀναδιευθύνειν δέλτον",
        "istemplate": "περίκλεισις",
        "isimage": "σύνδεσμος ἀρχείου",
        "markedaspatrollederrortext": "Δεῖ σε ὁρίσειν ἀναθεώρησιν τινὰ ἵνα σεσημασμένη αὕτη ᾖ ὡς περιπολουμένη.",
        "patrol-log-page": "Κατάλογος περιπόλων",
        "patrol-log-header": "Ὅδε ἐστὶ κατάλογος περιπολουμένων ἀναθεωρήσεων.",
-       "log-show-hide-patrol": "$1 κατάλογος περιπόλου",
        "deletedrevision": "Προτέρα ἔκδοσις διαγραφεῖσα $1",
        "filedeleteerror-short": "Ἀρχεῖον διαγράφον σφάλματα: $1",
        "filedeleteerror-long": "Σφάλματα ἀπαντἠθησαν ἐν τῷ διαγράφειν τὸ ἀρχεῖον:\n\n$1",
index 924d5f8..7554e12 100644 (file)
        "whatlinkshere": "Was verwyst do druff?",
        "whatlinkshere-title": "Sytene, wo uf „$1“ verlinke",
        "whatlinkshere-page": "Syte:",
-       "linkshere-2": "Die Sytene hen e Link, wu zu '''„$1“''' fiere:",
-       "nolinkshere-2": "Kei Artikel verwyyst uf '''„$1“'''.",
-       "nolinkshere-ns-2": "Kei Syte verwyyst uf '''„$1“''' im gwehlte Namensruum.",
+       "linkshere": "Die Sytene hen e Link, wu zu '''„$2“''' fiere:",
+       "nolinkshere": "Kei Artikel verwyyst uf '''„$2“'''.",
+       "nolinkshere-ns": "Kei Syte verwyyst uf '''„$2“''' im gwehlte Namensruum.",
        "isredirect": "Wyterleitigssyte",
        "istemplate": "Vorlageybindig",
        "isimage": "Dateigleich",
        "markedaspatrollederrornotify": "D Markierig als kontrolliert isch nid glunge.",
        "patrol-log-page": "Kontroll-Logbuech",
        "patrol-log-header": "Des isch s Kontroll-Logbuech.",
-       "log-show-hide-patrol": "Kontroll-Logbuech $1",
-       "log-show-hide-tag": "Markierigs-Logbuech $1",
        "deletedrevision": "alti Version: $1",
        "filedeleteerror-short": "Fähler bi dr Datei-Leschig: $1",
        "filedeleteerror-long": "Bi dr Datei-Leschig sin Fähler feschtgstellt wore:\n\n$1",
index 676e09d..7efe8d2 100644 (file)
        "index-category": "અનુક્રમણિકા બનાવેલા પાનાં",
        "noindex-category": "અનુક્રમણિકા નહીં બનાવેલા પાનાં",
        "broken-file-category": "ફાઇલોની ત્રૂટક કડીઓવાળાં પાનાં",
+       "categoryviewer-pagedlinks": "($1) ($2)",
+       "category-header-numerals": "$1–$2",
        "about": "વિષે",
        "article": "લેખનું પાનું",
        "newwindow": "(નવા પાનામાં ખુલશે)",
        "versionrequired": "મીડીયાવિકિનું $1 સંસ્કરણ જરૂરી",
        "versionrequiredtext": "આ પાનાના વપરાશ માટે મીડિયાવિકિનું $1 સંસ્કરણ જરૂરી.\n\nજુઓ [[Special:Version|સંસ્કરણ પાનું]].",
        "ok": "મંજૂર",
+       "pagetitle": "$1 - {{SITENAME}}",
+       "pagetitle-view-mainpage": "{{SITENAME}}",
+       "backlinksubtitle": "← $1",
        "retrievedfrom": "\"$1\" થી મેળવેલ",
        "youhavenewmessages": "{{PLURAL:$3|તમારી પાસે}} $1 ($2).",
        "youhavenewmessagesfromusers": "{{PLURAL:$4|આપ}}ને માટે {{PLURAL:$3|અન્ય સભ્ય|$3 અન્ય સભ્યો}} તરફથી $1 છે. ($2).",
        "site-atom-feed": "$1 એટમ ફીડ",
        "page-rss-feed": "\"$1\" RSS ફીડ",
        "page-atom-feed": "\"$1\" એટમ ફીડ",
+       "feed-atom": "ઍટમ",
+       "feed-rss": "RSS",
        "red-link-title": "$1 (પાનું અસ્તિત્વમાં નથી)",
        "sort-descending": "ઉતરતા ક્રમમાં ગોઠવો",
        "sort-ascending": "ચડતા ક્રમમાં ગોઠવો",
        "nosuchusershort": "\"$1\" નામનો કોઇ સભ્ય નથી, તમારી જોડણી તપાસો.",
        "nouserspecified": "તમારે સભ્ય નામ દર્શાવવાની જરૂર છે.",
        "login-userblocked": "આ યુઝર પ્રતિબંધિત છે. પ્રવેશ વર્જીત.",
-       "wrongpassword": "તમà«\87 àª²àª\96à«\87લà«\80 àª\97à«\81પà«\8dત àª¸àª\82àª\9cà«\8dàª\9eા àª\96à«\8bàª\9fà«\80 છે.\nફરીથી પ્રયત્ન કરો.",
+       "wrongpassword": "àª\96à«\8bàª\9fà«\81àª\82 àª¸àª­à«\8dયનામ àª\85થવા àª\97à«\81પà«\8dત àª¸àª\82àª\9cà«\8dàª\9eા (પાસવરà«\8dડâ\80\8c) àª¦àª¾àª\96લ àª\95રà«\87 છે.\nફરીથી પ્રયત્ન કરો.",
        "wrongpasswordempty": "તમે ગુપ્ત સંજ્ઞા લખવાનું ભુલી ગયા લાગો છો.\nફરીથી પ્રયત્ન કરો.",
        "passwordtooshort": "ગુપ્ત સંજ્ઞામાં ઓછામાં {{PLURAL:$1|ઓછો એક અક્ષર હોવો |ઓછા $1 અક્ષર હોવા}} જોઇએ.",
+       "passwordtoolong": "ગુપ્ત સંજ્ઞા (પાસવર્ડ) {{PLURAL:$1|1 અક્ષર|$1 અક્ષરો}} કરતા લાંબો રાખી શકાતો નથી.",
        "password-name-match": "તમારી ગુપ્તસંજ્ઞા તમારા સભ્યનામ કરતાં અલગ જ હોવી જોઇએ.",
        "password-login-forbidden": "આ સભ્યનામ અને ગુપ્તસંજ્ઞા વાપરવા પર પ્રતિબંધ છે.",
        "mailmypassword": "પાસવર્ડ ફરી ગોઠવો",
        "summary-preview": "સંપાદન સારાંશ પૂર્વાવલોકન:",
        "subject-preview": "વિષયનું પૂર્વાવલોકન:",
        "blockedtitle": "સભ્ય પ્રતિબંધિત છે",
-       "blockedtext": "<strong>àª\86પનાàª\82 àª¸àª­à«\8dય àª¨àª¾àª® àª\85થવા àª\86àª\87.પà«\80. àª\8fડà«\8dરà«\87સ àªªàª° àªªà«\8dરતિબàª\82ધ àª®à«\81àª\95વામાàª\82 àª\86વà«\8dયà«\8b àª\9bà«\87.</strong>\n\nàª\86 àªªà«\8dરતિબàª\82ધ $1àª\8f àª®à«\81àª\95à«\8dયà«\8b àª\9bà«\87.\nàª\9cà«\87નà«\87 àª®àª¾àª\9fà«\87 àª\95ારણ àª\86પવામાàª\82 àª\86વà«\8dયà«\81àª\82 àª\9bà«\87, <em>$2</em>.\n\n* àªªà«\8dરતિબàª\82ધ àª®à«\81àª\95à«\8dયા àª¤àª¾àª°à«\80àª\96: $8\n* àªªà«\8dરતિબàª\82ધ àª\89ઠાવવાનà«\80 àª¤àª¾àª°à«\80àª\96: $6\n* àª\9cà«\87ના àª\89પર àªªà«\8dરતિબàª\82ધ àª®à«\81àª\95à«\8dયà«\8b àª\9bà«\87 àª¤à«\87: $7\n\nàª\86પનાàª\82 àªªàª° àª®à«\81àª\95વામાàª\82 àª\86વà«\87લાàª\82 àªªà«\8dરતિબàª\82ધ àªµàª¿àª·à«\87 àª\9aરà«\8dàª\9aા àª\95રવા àª®àª¾àª\9fà«\87 àª\86પ $1નà«\8b àª\95à«\87 àª\85નà«\8dય [[{{MediaWiki:Grouppage-sysop}}|પà«\8dરબàª\82ધàª\95]]નà«\8b àª¸àª\82પરà«\8dàª\95 àª\95રà«\80 àª¶àª\95à«\8b àª\9bà«\8b.\nàª\86પ 'સભà«\8dયનà«\87 àª\87-મà«\87લ àª\95રà«\8b' àª¨à«\80 àª\95ડà«\80 àªµàª¾àªªàª°à«\80 àª¨àª¹à«\80 àª¶àª\95à«\8b, àªªàª°àª\82તà«\81 àª\9cà«\8b àª\86પનાàª\82 [[Special:Preferences|મારà«\80 àªªàª¸àª\82દ]]માàª\82 àª¯à«\8bàª\97à«\8dય àª\87-મà«\87લ àª¸àª°àª¨àª¾àª®à«\81àª\82 àªµàª¾àªªàª°à«\8dયà«\81àª\82 àª¹àª¶à«\87 àª\85નà«\87 àª¤àª®àª¾àª°àª¾ àª¤à«\87 àª\96ાતà«\81àª\82 àªµàª¾àªªàª°àªµàª¾ àª\89પર àªªà«\8dરતિબàª\82ધ àª¨àª¹à«\80 àª®à«\81àª\95à«\8dયà«\8b àª¹à«\8bય àª¤à«\8b àª¤àª®à«\87 àª¤à«\87 àª\95ડà«\80નà«\8b àª\89પયà«\8bàª\97 àª\95રà«\80 àª¶àª\95શà«\8b.\nતમારà«\82àª\82 àª¹àª¾àª²àª¨à«\81àª\82 àª\86àª\87.પà«\80 àª¸àª°àª¨àª¾àª®à«\81àª\82 àª\9bà«\87 $3, àª\85નà«\87 àª\9cà«\87ના àªªàª° àªªà«\8dરતિબàª\82ધ àª®à«\81àª\95વામાàª\82 àª\86વà«\8dયà«\8b àª\9bà«\87 àª¤à«\87 àª\9bà«\87  #$5.\nમહેરબાની કરીને કોઇ પણ પત્ર વ્યવહારમાં ઉપરની બધીજ માહિતીનો ઉલ્લેખ કરશો.",
+       "blockedtext": "<strong>àª\86પનાàª\82 àª¸àª­à«\8dય àª¨àª¾àª® àª\85થવા àª\86àª\87.પà«\80. àª¸àª°àª¨àª¾àª®àª¾ àªªàª° àªªà«\8dરતિબàª\82ધ àª®à«\81àª\95વામાàª\82 àª\86વà«\8dયà«\8b àª\9bà«\87.</strong>\n\nàª\86 àªªà«\8dરતિબàª\82ધ $1 àªµàª¡à«\87 àª®à«\82àª\95વામાàª\82 àª\86વà«\8dયà«\8b àª\9bà«\87.\nàª\9cà«\87નà«\87 àª®àª¾àª\9fà«\87 àª\95ારણ àª\86પવામાàª\82 àª\86વà«\8dયà«\81àª\82 àª\9bà«\87, <em>$2</em>.\n\n* àªªà«\8dરતિબàª\82ધ àª®à«\81àª\95à«\8dયા àª¤àª¾àª°à«\80àª\96: $8\n* àªªà«\8dરતિબàª\82ધ àª\89ઠાવવાનà«\80 àª¤àª¾àª°à«\80àª\96: $6\n* àª\9cà«\87ના àª\89પર àªªà«\8dરતિબàª\82ધ àª®à«\81àª\95à«\8dયà«\8b àª\9bà«\87 àª¤à«\87: $7\n\nàª\86પનાàª\82 àªªàª° àª®à«\81àª\95વામાàª\82 àª\86વà«\87લાàª\82 àªªà«\8dરતિબàª\82ધ àªµàª¿àª·à«\87 àª\9aરà«\8dàª\9aા àª\95રવા àª®àª¾àª\9fà«\87 àª\86પ $1નà«\8b àª\95à«\87 àª\85નà«\8dય [[{{MediaWiki:Grouppage-sysop}}|પà«\8dરબàª\82ધàª\95]]નà«\8b àª¸àª\82પરà«\8dàª\95 àª\95રà«\80 àª¶àª\95à«\8b àª\9bà«\8b.\n\nàª\86પ \"{{int:emailuser}}\" àª¨à«\80 àª\95ડà«\80 àªµàª¾àªªàª°à«\80 àª¨àª¹à«\80 àª¶àª\95à«\8b, àªªàª°àª\82તà«\81 àª\9cà«\8b àª\86પનાàª\82 [[Special:Preferences|મારà«\80 àªªàª¸àª\82દ]]માàª\82 àª¯à«\8bàª\97à«\8dય àª\87-મà«\87લ àª¸àª°àª¨àª¾àª®à«\81àª\82 àªµàª¾àªªàª°à«\8dયà«\81 àª¹àª¶à«\87 àª\85નà«\87 àª¤àª®àª¾àª°àª¾ àª¤à«\87 àª\96ાતà«\81àª\82 àªµàª¾àªªàª°àªµàª¾ àª\89પર àªªà«\8dરતિબàª\82ધ àª¨àª¹à«\80 àª®à«\81àª\95à«\8dયà«\8b àª¹à«\8bય àª¤à«\8b àª¤àª®à«\87 àª¤à«\87 àª\95ડà«\80નà«\8b àª\89પયà«\8bàª\97 àª\95રà«\80 àª¶àª\95શà«\8b.\n\nતમારà«\82àª\82 àª¹àª¾àª²àª¨à«\81àª\82 àª\86àª\87.પà«\80. àª¸àª°àª¨àª¾àª®à«\81àª\82 $3 àª\9bà«\87, àª\85નà«\87 àªªà«\8dરતિબàª\82ધ àª\95à«\8dરમાàª\82àª\95 #$5 àª\9bà«\87.\n\nમહેરબાની કરીને કોઇ પણ પત્ર વ્યવહારમાં ઉપરની બધીજ માહિતીનો ઉલ્લેખ કરશો.",
        "autoblockedtext": "તમારાં IP સરનામા પર સ્વયંચાલિત રીતે રોક લગાવી દેવાઈ છે કેમકે તે અન્ય સભ્ય દ્વારા વાપરવામાં આવ્યું હતું જેના પર $1 દ્વારા પહેલેથી પ્રતિબંધ મૂકવામાં આવ્યો છે.\n:''$2''\n\n* રોકની શરુઆત : $8\n* રોકની સમાપ્તિ : $6\n* પ્રસ્તાવિત રોક સહન કરનાર : $7\n\nતમે $1 અથવા કોઇ અન્ય [[{{MediaWiki:Grouppage-sysop}}|પ્રબંધક]]નો સંપર્ક કરી રોકની ચર્ચા કરી શકો.\n\nનોંધો કે તેમે \"આ સભ્યને ઈ-મેલ કરો\" વિકલ્પ નહિ વાપરી શકો, સિવાયકે તમરી પાસે તમારા [[Special:Preferences|user preferences]]માં વૈધ ઈ-મેલ સરનામું હોય અને તે વાપરવા પર પ્રતિબંધ ન મૂકવામાં આવ્યો હોય.\n\nતમારું હાલનું IP સરનામું $3 છે, અને રોકની ID છે #$5.\nઆ માહિતી તમારી પૂછપરછમાં જરૂર ઉમેરશો.",
        "blockednoreason": "કોઇ કારણ દર્શાવવામાં આવ્યું નથી",
        "whitelistedittext": "ફેરફાર કરવા માટે તમારે $1 કરવાનું છે.",
        "recentchangeslinked-feed": "આની સાથે જોડાયેલા ફેરફાર",
        "recentchangeslinked-toolbox": "આની સાથે જોડાયેલા ફેરફાર",
        "recentchangeslinked-title": "\"$1\" ને લગતા ફેરફારો",
-       "recentchangeslinked-summary": "àª\86 àª\8fવા àª«à«\87રફારà«\8bનà«\80 àª¯àª¾àª¦à«\80 àª\9bà«\87 àª\9cà«\87 àª\86 àª\9aà«\8bàª\95à«\8dàª\95સ àªªàª¾àª¨àª¾ (àª\95à«\87 àª¶à«\8dરà«\87ણà«\80નાàª\82 àª¸àª­à«\8dય àªªàª¾àª¨àª¾àª\93) àª¸àª¾àª¥à«\87 àª\9cà«\8bડાયà«\87લા àªªàª¾àª¨àª¾àª\93માàª\82 àª¤àª¾àª\9cà«\87તરમાàª\82 àª\95રવામાàª\82 àª\86વà«\8dયા àª¹à«\8bય.\n[[Special:Watchlist|તમારà«\80 àª§à«\8dયાનસà«\82àª\9aિમાàª\82]] àª¹à«\8bય àª¤à«\87વા àªªàª¾àª¨àª¾àª\82 <strong>àª\98ાàª\9fા àª\85àª\95à«\8dષર</strong>માàª\82 àªµàª°à«\8dણવà«\8dયાàª\82 àª\9bે.",
+       "recentchangeslinked-summary": "પાનાàª\82 àª¸àª¾àª¥à«\87 àª\9cà«\8bડાયà«\87લા àª«à«\87રફારà«\8b àª\9cà«\8bવા àª®àª¾àª\9fà«\87 àªªàª¾àª¨àª¾àª¨à«\81àª\82 àª¨àª¾àª® àª¦àª¾àª\96લ àª\95રà«\8b. (શà«\8dરà«\87ણà«\80ના àª¸àª­à«\8dયà«\8b àª\9cà«\8bવા àª®àª¾àª\9fà«\87, {{ns:category}}:શà«\8dરà«\87ણà«\80નà«\81àª\82 àª¨àª¾àª® àª¦àª¾àª\96લ àª\95રà«\8b). Changes to pages on [[Special:Watchlist|તમારà«\80 àª§à«\8dયાનસà«\82àª\9aિ]]માàª\82 àª¹à«\8bય àª¤à«\87વા àª«à«\87રફારà«\8b <strong>àª\98ાàª\9fા àª\85àª\95à«\8dષરà«\8b</strong>માàª\82 àª¦à«\87àª\96ાશે.",
        "recentchangeslinked-page": "પાનાનું નામ:",
        "recentchangeslinked-to": "આને બદલે આપેલા પાનાં સાથે જોડાયેલા લેખોમાં થયેલા ફેરફારો શોધો",
        "upload": "ફાઇલ ચડાવો",
        "ancientpages": "સૌથી જૂનાં પાનાં",
        "move": "નામ બદલો",
        "movethispage": "આ પાનું ખસેડો",
-       "unusedimagestext": "નà«\80àª\9aà«\87નà«\80 àª«àª¾àª\87લà«\8b àª\85સà«\8dતિતà«\8dવમાàª\82 àª¤à«\8b àª\9bà«\87 àªªàª£ àª\95à«\8bàª\87 àªªàª¾àª¨àª¾ àªªàª° àª¤à«\87નà«\8b àª\89પયà«\8bàª\97 àª¥àª¯à«\87લ àª¨àª¥à«\80.\nàª\95à«\8dરà«\8dપયા àª¨à«\8bàª\82ધ àª²à«\87àª\96à«\8b àª\95à«\87 àª\86 àª«àª¾àª\87લનà«\87 àª\85નà«\8dય àªµà«\87બસાàª\87àª\9fà«\8b àª¸à«\80ધા URL àª¨àª¾ àª®àª¾àª§à«\8dયમ àª¦à«\8dવારા àªµàª¾àªªàª°à«\80 àª¶àª\95à«\87 àª\9bà«\87 àª\85નà«\87 àª\95à«\8bàª\87 àªªàª£ àª\89પયà«\8bàª\97 àª¸àª¿àªµàª¾àª¯ àª\98ણà«\80 àª«àª¾àª\87લà«\8b àª\85હà«\80àª\82 àª¯àª¾àª¦àª¿માં હોઇ શકે.",
+       "unusedimagestext": "નà«\80àª\9aà«\87નà«\80 àª«àª¾àª\87લà«\8b àª\85સà«\8dતિતà«\8dવમાàª\82 àª\9bà«\87 àªªàª°àª\82તà«\81 àª\95à«\8bàª\87 àªªàª¾àª¨àª¾àª\82 àªªàª° àª¤à«\87નà«\8b àª\89પયà«\8bàª\97 àª¥àª¯à«\87લ àª¨àª¥à«\80.\nàª\95à«\83પા àª\95રà«\80 àª¨à«\8bàª\82ધ àª²à«\87શà«\8b àª\95à«\87 àª\86 àª«àª¾àª\87લનà«\87 àª\85નà«\8dય àªµà«\87બસાàª\87àª\9fà«\8b àª¸à«\80ધા URLના àª®àª¾àª§à«\8dયમ àª¦à«\8dવારા àªµàª¾àªªàª°à«\80 àª¶àª\95à«\87 àª\9bà«\87 àª\85નà«\87 àª\95à«\8bàª\87 àªªàª£ àª\89પયà«\8bàª\97 àª¸àª¿àªµàª¾àª¯ àª\98ણà«\80 àª«àª¾àª\87લà«\8b àª\85હà«\80àª\82 àª¯àª¾àª¦à«\80માં હોઇ શકે.",
        "unusedcategoriestext": "નીચેના શ્રેણી પાના છે પણા કોઈ લેખ આનો ઉપયોગ કરતાં નથી",
        "notargettitle": "કોઇ લક્ષ્ય નથી",
        "notargettext": "આ ક્રિયા જેના પર કરવાની છે તે સભ્ય કે પાનાની માહિતી તમે પૂરી પાડી નથી",
        "whatlinkshere": "અહી શું જોડાય છે",
        "whatlinkshere-title": "\"$1\" ને જોડતા પાનાં",
        "whatlinkshere-page": "પાનું:",
-       "linkshere-2": "નીચેના પાનાઓ '''$1''' સાથે જોડાય છે:",
-       "nolinkshere-2": "'''$1'''ની સાથે કોઇ પાના જોડાતા નથી.",
-       "nolinkshere-ns-2": "પસંદ કરેલ નામ સ્થળમાં કોઇ પાના '''$1'''  સાથે જોડાયેલ નથી.",
+       "linkshere": "નીચેના પાનાઓ '''$2''' સાથે જોડાય છે:",
+       "nolinkshere": "'''$2'''ની સાથે કોઇ પાના જોડાતા નથી.",
+       "nolinkshere-ns": "પસંદ કરેલ નામ સ્થળમાં કોઇ પાના '''$2'''  સાથે જોડાયેલ નથી.",
        "isredirect": "દિશાનિર્દેશ કરેલ પાનું",
        "istemplate": "સમાવેશ",
        "isimage": "ફાઇલની કડી",
        "imported-log-entries": "આયાતી $1 {{PLURAL:$1|log entry|log entries}}.",
        "importfailed": "આયાત નિષ્ફળ: <nowiki>$1</nowiki>",
        "importunknownsource": "અજ્ઞાત આયાતી સ્રોત પ્રકાર",
-       "importcantopen": "આયાતી ફાઈલ નખોલી શકાઈ",
+       "importcantopen": "આયાતી ફાઈલ ન ખોલી શકાઈ",
        "importbadinterwiki": "ખરાબ આંતરીકા વિકિ કડી",
        "importsuccess": "આયાત સંપૂર્ણ",
        "importnosources": "કોઇ પણ આંતર વિકિ સ્રોત જણાવાયા નથી અને સીધા ઇતિહાસ ફાઇલ ચડાવવા પર રોક લાગેલી છે.",
        "markedaspatrollederror-noautopatrol": "તમે તમારા પોતાના ફેરફારોને નીરીક્ષિત અંકિત ન કરી શકો",
        "patrol-log-page": "ચકાસણી લોગ",
        "patrol-log-header": "આ નીરીક્ષિત ફેરફાઓનો લોગ છે",
-       "log-show-hide-patrol": "$1 ચકાસણી લોગ",
        "deletedrevision": "જુના સુધારા ભૂસો $1",
        "filedeleteerror-short": "ફાઇલ : $1 ભૂંસવામાં તૃટિ",
        "filedeleteerror-long": "$1 આ ફાઈલ ભૂંસતી વખતે ચૂક થઈ",
index 701507a..f88debf 100644 (file)
        "whatlinkshere": "Cre ta kiangley rish shoh",
        "whatlinkshere-title": "Duillagyn ta kianglt rish $1",
        "whatlinkshere-page": "Duillag:",
-       "linkshere-2": "Ta ny duillagyn shoh kianglt rish '''$1''':",
-       "nolinkshere-2": "Cha nel duillag erbee kianglt rish '''$1'''.",
+       "linkshere": "Ta ny duillagyn shoh kianglt rish '''$2''':",
+       "nolinkshere": "Cha nel duillag erbee kianglt rish '''$2'''.",
        "isredirect": "duillag aa-enmyssit",
        "istemplate": "goaill stiagh",
        "isimage": "kiangley coadan",
index 5ca721e..07c5c5b 100644 (file)
        "preview": "Rigya-gani",
        "showpreview": "Sufar rigya-gani",
        "showdiff": "Nuna sauye-sauye",
-       "anoneditwarning": "'''Hattara:''' Ba ku yi logi ba.\nZa a rubuta adireshinku na IP a cikin tarihin sauye-sauyen wannan shafi.",
+       "anoneditwarning": "'''Hattara:''' Ba ku yi login ba.\nZa a rubuta adireshinku na IP a cikin tarihin sauye-sauyen wannan shafi.",
        "summary-preview": "Rigya-gani na taƙaici:",
        "loginreqlink": "Shiga",
        "newarticle": "(Sabo)",
        "whatlinkshere": "Mahaɗan wannan shafi",
        "whatlinkshere-title": "Shafuna masu mahaɗi da \"$1\"",
        "whatlinkshere-page": "Shafi:",
-       "linkshere-2": "Waɗannan shafuna sun haɗu da '''$1''':",
+       "linkshere": "Waɗannan shafuna sun haɗu da '''$2''':",
        "isredirect": "shafin turawa",
        "istemplate": "gami",
        "isimage": "majigi shigagge",
index 9f97204..012bb35 100644 (file)
@@ -15,7 +15,8 @@
                        "LNDDYL",
                        "唐吉訶德的侍從",
                        "飞舞回堂前",
-                       "Macofe"
+                       "Macofe",
+                       "Ruthven"
                ]
        },
        "tog-underline": "Lièn-chiap kâ-tái sien:",
        "whatlinkshere": "Nâi-têu lièn to liá-têu",
        "whatlinkshere-title": "Lièn-chiap to \"$1\" ke ya̍p-mien",
        "whatlinkshere-page": "Ya̍p-mien:",
-       "linkshere-2": "Hâ-poi ya̍p-mien lièn-chiap to <strong>$1</strong>:",
-       "nolinkshere-2": "無頁面鏈接到'''$1'''。",
-       "nolinkshere-ns-2": "Chhai só-sién ke miàng-sṳ khûng-kiên tú mò ya̍p-mien lièn-chiap to $1.",
+       "linkshere": "Hâ-poi ya̍p-mien lièn-chiap to <strong>$2</strong>:",
+       "nolinkshere": "無頁面鏈接到'''$2'''。",
+       "nolinkshere-ns": "Chhai só-sién ke miàng-sṳ khûng-kiên tú mò ya̍p-mien lièn-chiap to $2.",
        "isredirect": "chhùng-thin-hiong ya̍p",
        "istemplate": "pâu-hàm",
        "isimage": "vùn-khien lièn-chiap",
index bc55341..990dcb0 100644 (file)
        "whatlinkshere": "He aha ka mea e loulou iho ai",
        "whatlinkshere-title": "Nā ʻAoʻao e loulou iā \"$1\"",
        "whatlinkshere-page": "‘Ao‘ao:",
-       "linkshere-2": "Loulou kēia mau ʻaoʻao iā <strong>$1</strong>:",
-       "nolinkshere-2": "ʻAʻohe ‘ao‘ao e loulou iā '''$1'''.",
+       "linkshere": "Loulou kēia mau ʻaoʻao iā <strong>$2</strong>:",
+       "nolinkshere": "ʻAʻohe ‘ao‘ao e loulou iā '''$2'''.",
        "isredirect": "ʻaoʻao kia hou",
        "istemplate": "kumo",
        "isimage": "loulou waihona",
index 505e254..5b124c7 100644 (file)
@@ -67,7 +67,7 @@
        "tog-shownumberswatching": "הצגת מספר המשתמשים העוקבים",
        "tog-oldsig": "החתימה הנוכחית שלך:",
        "tog-fancysig": "התייחסות לחתימה כקוד ויקי (ללא קישור אוטומטי)",
-       "tog-uselivepreview": "×\9c×\94ר×\90×\95ת תצוגה מקדימה בלי לטעון מחדש את הדף",
+       "tog-uselivepreview": "×\94צ×\92ת תצוגה מקדימה בלי לטעון מחדש את הדף",
        "tog-forceeditsummary": "הצגת אזהרה בעת הכנסת תקציר עריכה ריק",
        "tog-watchlisthideown": "הסתרת עריכות שלי ברשימת המעקב",
        "tog-watchlisthidebots": "הסתרת עריכות של בוטים ברשימת המעקב",
        "customcssprotected": "אין לך הרשאה לערוך את דף ה־CSS הזה, משום שהוא מכיל הגדרות אישיות של משתמש אחר.",
        "customjsonprotected": "אין לך הרשאה לערוך את דף ה־JSON הזה, משום שהוא מכיל הגדרות אישיות של משתמש אחר.",
        "customjsprotected": "אין לך הרשאה לערוך את דף ה־JavaScript הזה, משום שהוא מכיל הגדרות אישיות של משתמש אחר.",
+       "sitecssprotected": "אין לך הרשאה לערוך את דף ה־CSS הזה, משום שהוא עשוי להשפיע על כל המבקרים באתר.",
+       "sitejsonprotected": "אין לך הרשאה לערוך את דף ה־JSON הזה, משום שהוא עשוי להשפיע על כל המבקרים באתר.",
+       "sitejsprotected": "אין לך הרשאה לערוך את דף ה־JavaScript הזה, משום שהוא עשוי להשפיע על כל המבקרים באתר.",
        "mycustomcssprotected": "אין לך הרשאה לערוך את דף ה־CSS הזה.",
        "mycustomjsonprotected": "אין לך הרשאה לערוך את דף ה־JSON הזה.",
        "mycustomjsprotected": "אין לך הרשאה לערוך את דף ה־JavaScript הזה.",
        "resetpass-submit-loggedin": "שינוי הסיסמה",
        "resetpass-submit-cancel": "ביטול",
        "resetpass-wrong-oldpass": "הסיסמה הזמנית או הנוכחית אינה תקינה.\nייתכן שכבר שינית את סיסמתך או שכבר ביקשת סיסמה זמנית חדשה.",
-       "resetpass-recycled": "×\99ש ×\9c×\90פס ×\90ת ×\94ס×\99ס×\9e×\94 ×\9cס×\99ס×\9e×\94 ×\94ש×\95× ×\94 ×\9eס×\99×\9eסתך הנוכחית.",
+       "resetpass-recycled": "×\99ש ×\9cשנ×\95ת ×\90ת ×\94ס×\99ס×\9e×\94 ×\9cס×\99ס×\9e×\94 ×\94ש×\95× ×\94 ×\9eס×\99ס×\9eתך הנוכחית.",
        "resetpass-temp-emailed": "נכנסת באמצעות סיסמה זמנית שנשלחה {{GENDER:|אליך|אלייך}} בדוא\"ל.\nכדי לסיים את הכניסה, יש להגדיר כאן סיסמה חדשה:",
        "resetpass-temp-password": "סיסמה זמנית:",
        "resetpass-abort-generic": "שינוי הסיסמה בוטל על־ידי הרחבה.",
        "resetpass-expired": "סיסמתך פקעה. נא להגדיר סיסמה חדשה כדי להיכנס.",
-       "resetpass-expired-soft": "×\94ס×\99ס×\9e×\94 ×©×\9c×\9a ×¤×§×¢×\94, ×\95צר×\99×\9a ×\9c×\90פס ×\90×\95ת×\94. ×\99ש ×\9c×\91×\97×\95ר ×¡×\99ס×\9e×\94 ×\97×\93ש×\94 ×\9bעת, ×\90×\95 ×\9c×\9c×\97×\95×¥ ×¢×\9c \"{{int:authprovider-resetpass-skip-label}}\" ×\9b×\93×\99 ×\9c×\90פס אותה מאוחר יותר.",
-       "resetpass-validity-soft": "×\94ס×\99ס×\9e×\94 ×©×\9c×\9a ×\90×\99× ×\94 ×ª×§×\99× ×\94: $1\n\n×\99ש ×\9c×\91×\97×\95ר ×¡×\99ס×\9e×\94 ×\97×\93ש×\94 ×\9bעת ×\90×\95 ×\9c×\9c×\97×\95×¥ ×¢×\9c \"{{int:authprovider-resetpass-skip-label}}\" ×\9b×\93×\99 ×\9c×\90פס את הסיסמה מאוחר יותר.",
+       "resetpass-expired-soft": "×\94ס×\99ס×\9e×\94 ×©×\9c×\9a ×¤×§×¢×\94, ×\95צר×\99×\9a ×\9cשנ×\95ת ×\90×\95ת×\94. ×\99ש ×\9c×\91×\97×\95ר ×¡×\99ס×\9e×\94 ×\97×\93ש×\94 ×\9bעת, ×\90×\95 ×\9c×\9c×\97×\95×¥ ×¢×\9c \"{{int:authprovider-resetpass-skip-label}}\" ×\9b×\93×\99 ×\9cשנ×\95ת אותה מאוחר יותר.",
+       "resetpass-validity-soft": "×\94ס×\99ס×\9e×\94 ×©×\9c×\9a ×\90×\99× ×\94 ×ª×§×\99× ×\94: $1\n\n×\99ש ×\9c×\91×\97×\95ר ×¡×\99ס×\9e×\94 ×\97×\93ש×\94 ×\9bעת ×\90×\95 ×\9c×\9c×\97×\95×¥ ×¢×\9c \"{{int:authprovider-resetpass-skip-label}}\" ×\9b×\93×\99 ×\9cשנ×\95ת את הסיסמה מאוחר יותר.",
        "passwordreset": "איפוס סיסמה",
        "passwordreset-text-one": "יש למלא טופס זה כדי לקבל סיסמה זמנית בדוא\"ל.",
        "passwordreset-text-many": "{{PLURAL:$1||יש למלא אחד מהשדות הבאים כדי לקבל סיסמה זמנית בדוא\"ל.}}",
        "converter-manual-rule-error": "התגלתה שגיאה בכלל המרת שפה ידני",
        "undo-success": "ניתן לבטל את העריכה.\nאנא {{GENDER:|בדוק|בדקי|בדקו}} את השוואת הגרסאות שלהלן כדי לוודא שזה אכן מה {{GENDER:|שאתה רוצה|שאת רוצה|שאתם רוצים}} לעשות, ולאחר מכן {{GENDER:|שמור|שמרי|שמרו}} את השינויים למטה כדי לסיים את ביטול העריכה.",
        "undo-failure": "לא ניתן היה לבטל את העריכה עקב התנגשות עם עריכות מאוחרות יותר.",
+       "undo-main-slot-only": "לא ניתן היה לבטל את העריכה כיוון שהיא כוללת תוכן מחוץ למיקום הראשי.",
        "undo-norev": "לא ניתן היה לבטל את העריכה כי היא אינה קיימת או כי היא נמחקה.",
        "undo-nochange": "נראה שהעריכה כבר בוטלה.",
        "undo-summary": "ביטול גרסה $1 של [[Special:Contributions/$2|$2]] ([[User talk:$2|שיחה]])",
        "diff-paragraph-moved-toold": "הפסקה הועברה. ניתן ללחוץ כאן כדי לעבור למיקומה הישן.",
        "difference-missing-revision": "{{PLURAL:$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": "דפים עם תוכן תואם",
        "group-autoconfirmed": "משתמשים ותיקים",
        "group-bot": "בוטים",
        "group-sysop": "מפעילי מערכת",
+       "group-interface-admin": "מנהלי ממשק",
        "group-bureaucrat": "ביורוקרטים",
        "group-suppress": "מעלימים",
        "group-all": "(הכול)",
        "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-editusercss": "עריכת קובצי CSS של משתמשים אחרים",
        "right-edituserjson": "עריכת קובצי JSON של משתמשים אחרים",
        "right-edituserjs": "עריכת קובצי JavaScript של משתמשים אחרים",
+       "right-editsitecss": "עריכת קובצי CSS של האתר כולו",
+       "right-editsitejson": "עריכת קובצי JSON של האתר כולו",
+       "right-editsitejs": "עריכת קובצי JavaScript של האתר כולו",
        "right-editmyusercss": "עריכת קובצי CSS של המשתמש עצמו",
        "right-editmyuserjson": "עריכת קובצי JSON של המשתמש עצמו",
        "right-editmyuserjs": "עריכת קובצי JavaScript של המשתמש עצמו",
        "grant-createaccount": "יצירת חשבונות",
        "grant-createeditmovepage": "יצירה, עריכה והעברה של דפים",
        "grant-delete": "מחיקת דפים, גרסאות ורשומות יומן",
-       "grant-editinterface": "עריכת מרחב השם מדיה ויקי ו־CSS/JSON/JavaScript של משתמשים",
+       "grant-editinterface": "עריכת מרחב השם מדיה ויקי וקובצי JSON של האתר כולו ושל משתמשים",
        "grant-editmycssjs": "עריכת CSS/JSON/JavaScript שלך",
        "grant-editmyoptions": "עריכת העדפות המשתמש שלך",
        "grant-editmywatchlist": "עריכת רשימת המעקב שלך",
+       "grant-editsiteconfig": "עריכת קובצי CSS/JS של האתר כולו ושל משתמשים",
        "grant-editpage": "עריכת דפים קיימים",
        "grant-editprotected": "עריכת דפים מוגנים",
        "grant-highvolume": "ביצוע עריכות מרובות",
        "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": "{{PLURAL:$1|שינוי אחד|$1 שינויים}}, $2",
        "rcfilters-savedqueries-rename": "שינוי שם",
        "rcfilters-savedqueries-setdefault": "הגדרה כברירת מחדל",
        "rcfilters-savedqueries-unsetdefault": "ביטול הגדרה כברירת מחדל",
-       "rcfilters-savedqueries-remove": "×\94סרה",
+       "rcfilters-savedqueries-remove": "×\9e×\97×\99קה",
        "rcfilters-savedqueries-new-name-label": "שם",
        "rcfilters-savedqueries-new-name-placeholder": "תיאור מטרת המסנן",
        "rcfilters-savedqueries-apply-label": "יצירת המסנן",
        "rcfilters-empty-filter": "אין מסננים פעילים. כל התרומות מוצגות.",
        "rcfilters-filterlist-title": "מסננים",
        "rcfilters-filterlist-whatsthis": "איך הם עובדים?",
-       "rcfilters-filterlist-feedbacklink": "באפשרותך לספר לנו מה דעתך על כלי הסינון (החדשים) האלה",
+       "rcfilters-filterlist-feedbacklink": "באפשרותך לספר לנו מה דעתך על כלי הסינון האלה",
        "rcfilters-highlightbutton-title": "הבלטת התוצאות",
        "rcfilters-highlightmenu-title": "בחירת צבע",
        "rcfilters-highlightmenu-help": "בחירת צבע להבלטת מאפיין זה",
        "rcfilters-watchlist-showupdated": "שינויים בדפים שלא ביקרת בהם מאז ביצוע השינויים מופיעים בכתב <strong>מודגש</strong>, ומסומנים בצבע.",
        "rcfilters-preference-label": "הסתרת הגרסה המשופרת של השינויים האחרונים",
        "rcfilters-preference-help": "ביטול של העיצוב מחדש של הממשק (שבוצע בשנת 2017) ושל כל הכלים שנוספו אז ומאז.",
+       "rcfilters-watchlist-preference-label": "הסתרת הגרסה המשופרת של רשימת המעקב",
+       "rcfilters-watchlist-preference-help": "ביטול של העיצוב מחדש של הממשק (שבוצע בשנת 2017) ושל כל הכלים שנוספו אז ומאז.",
        "rcfilters-filter-showlinkedfrom-label": "הצגת שינויים בדפים שמקושרים מתוך",
        "rcfilters-filter-showlinkedfrom-option-label": "<strong>דפים שמקושרים מתוך</strong> הדף שנבחר",
        "rcfilters-filter-showlinkedto-label": "הצגת שינויים בדפים שמקשרים אל",
        "uploadstash-zero-length": "הקובץ באורך אפס.",
        "invalid-chunk-offset": "היסט גוש לא תקין",
        "img-auth-accessdenied": "הגישה נדחתה",
-       "img-auth-nopathinfo": "PATH_INFO חסר.\nהשרת אינו מוגדר להעברת מידע זה.\nייתכן שהוא מבוסס על CGI ולכן אינו יכול לתמוך ב־img_auth.\nלמידע נוסף: https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization.",
+       "img-auth-nopathinfo": "חסר מידע על הנתיב.\nהשרת חייב להיות מוגדר להעברת המשתנים REQUEST_URI ו/או PATH_INFO.\nאם הוא אכן מוגדר כך, ניתן לנסות להפעיל את ‎$wgUsePathInfo.\nלמידע נוסף: https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization",
        "img-auth-notindir": "הנתיב המבוקש אינו בתיקיית ההעלאות שהוגדרה.",
        "img-auth-badtitle": "לא ניתן ליצור כותרת תקינה מתוך \"$1\".",
        "img-auth-nologinnWL": "לא נכנסת לחשבון, והדף \"$1\" אינו ברשימה המותרת.",
        "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": "לא ניתן להגיע לכתובת ה־URL שנכתבה.\nיש לבדוק אם כתובת זו נכונה ואם האתר זמין.",
        "upload-curl-error28": "הסתיים זמן ההמתנה להעלאה",
        "speciallogtitlelabel": "יעד (שם הדף, או \"{{ns:user}}:שם\" עבור משתמש):",
        "log": "יומנים",
        "logeventslist-submit": "הצגה",
+       "logeventslist-more-filters": "הצגת יומנים נוספים:",
+       "logeventslist-patrol-log": "יומן שינויים בדוקים",
+       "logeventslist-tag-log": "יומן תגיות",
        "all-logs-page": "כל היומנים הציבוריים",
        "alllogstext": "זוהי תצוגה משולבת של כל סוגי היומנים הזמינים ב{{grammar:תחילית|{{SITENAME}}}}.\nניתן לצמצם את התצוגה על־ידי בחירת סוג היומן, שם המשתמש (תלוי־רישיות) או הדף המושפע (גם כן תלוי־רישיות).",
        "logempty": "אין פריטים תואמים ביומן.",
        "dellogpage": "יומן מחיקות",
        "dellogpagetext": "להלן רשימה של המחיקות האחרונות שבוצעו.",
        "deletionlog": "יומן המחיקות",
+       "log-name-create": "יומן יצירות דפים",
+       "log-description-create": "להלן רשימה של הדפים האחרונים שנוצרו.",
+       "logentry-create-create": "$1 {{GENDER:$2|יצר|יצרה}} את הדף $3",
        "reverted": "שוחזר לגרסה קודמת",
        "deletecomment": "סיבה:",
        "deleteotherreason": "סיבה אחרת/נוספת:",
        "viewdeletedpage": "הצגה של דפים מחוקים",
        "undeletepagetext": "{{PLURAL:$1|הדף שלהלן נמחק, אך הוא עדיין בארכיון וניתן לשחזר אותו|הדפים שלהלן נמחקו, אך הם עדיין בארכיון וניתן לשחזר אותם}}.\nייתכן שהארכיון ינוקה מעת לעת.",
        "undelete-fieldset-title": "שחזור גרסאות",
-       "undeleteextrahelp": "×\9b×\93×\99 ×\9cש×\97×\96ר ×\90ת ×\94×\99ס×\98×\95ר×\99×\99ת ×\94×\92רס×\90×\95ת ×\94×\9e×\9c×\90×\94 ×©×\9c ×\94×\93×£, ×\90×\9c {{GENDER:|תס×\9e×\9f|תס×\9e× ×\99|תס×\9e× ×\95}} ×©×\95×\9d ×ª×\99×\91ת ×¡×\99×\9e×\95×\9f; ×¤×©×\95×\98 {{GENDER:|×\9c×\97×¥|×\9c×\97צ×\99\9c×\97צ×\95}} ×¢×\9c <strong>{{int:undeletebtn}}</strong>.\n×\9b×\93×\99 ×\9cש×\97×\96ר ×\92רס×\90×\95ת ×\9eס×\95×\99×\9e×\95ת ×\91×\9c×\91×\93, {{GENDER:|ס×\9e×\9f|ס×\9e× ×\99|ס×\9e× ×\95}} ×\90ת ×\94×\92רס×\90×\95ת ×©{{GENDER:|×\91רצ×\95× ×\9a\91רצ×\95× ×\9a\91רצ×\95× ×\9b×\9d}} ×\9cש×\97×\96ר ×\95×\9c×\90×\97ר ×\9e×\9b×\9f {{GENDER:|×\9c×\97×¥|×\9c×\97צ×\99\9c×\97צ×\95}} על <strong>{{int:undeletebtn}}</strong>.",
+       "undeleteextrahelp": "×\9b×\93×\99 ×\9cש×\97×\96ר ×\90ת ×\94×\99ס×\98×\95ר×\99×\99ת ×\94×\92רס×\90×\95ת ×\94×\9e×\9c×\90×\94 ×©×\9c ×\94×\93×£, ×\99ש ×\9c×\94ש×\90×\99ר ×\90ת ×\9b×\9c ×ª×\99×\91×\95ת ×\94ס×\99×\9e×\95×\9f ×¨×\99ק×\95ת ×\95×\9c×\9c×\97×\95×¥ ×¢×\9c <strong>{{int:undeletebtn}}</strong>.\n×\9b×\93×\99 ×\9cש×\97×\96ר ×\92רס×\90×\95ת ×\9eס×\95×\99×\9e×\95ת ×\91×\9c×\91×\93, ×\99ש ×\9cס×\9e×\9f ×\90ת ×\94×\92רס×\90×\95ת ×©×ª×©×\95×\97×\96רנ×\94 ×\95×\9c×\90×\97ר ×\9e×\9b×\9f ×\9c×\9c×\97×\95×¥ על <strong>{{int:undeletebtn}}</strong>.",
        "undeleterevisions": "{{PLURAL:$1|גרסה אחת נמחקה|$1 גרסאות נמחקו}}",
-       "undeletehistory": "×\90×\9d {{GENDER:|תש×\97×\96ר|תש×\97×\96ר×\99|תש×\97×\96ר×\95}} ×\90ת ×\94×\93×£, ×\94×\92רס×\90×\95ת ×\99ש×\95×\97×\96ר×\95 ×\9c×\94×\99ס×\98×\95ר×\99×\99ת ×\94ש×\99× ×\95×\99×\99×\9d ×©×\9c×\95.\n×\90×\9d ×\94×\93×£ ×\94×\96×\94 × ×\9e×\97ק ×\91×¢×\91ר ×\95×\9c×\90×\97ר ×\9e×\9b×\9f × ×\95צר ×\9e×\97×\93ש, ×\94×\92רס×\90×\95ת ×©{{GENDER:|תש×\97×\96ר|תש×\97×\96ר×\99|תש×\97×\96ר×\95}} ×\99×\9e×\95×\96×\92×\95 ×\9c×\94×\99ס×\98×\95ר×\99×\99ת ×\94ש×\99× ×\95×\99×\99×\9d ×©×\9c ×\94×\93×£ ×\95×\99×\95פ×\99×¢×\95 ×\91ת×\95ר ×\94×\92רס×\90×\95ת ×\94×\99שנ×\95ת ×\91×\99×\95תר ×©×\9c×\95.",
+       "undeletehistory": "ש×\97×\96×\95ר ×\94×\93×£ ×\99×\92ר×\95×\9d ×\9c×\9b×\9a ×©×\94×\92רס×\90×\95ת ×©×\9c×\95 ×ª×©×\95×\97×\96רנ×\94 ×\95ת×\95פענ×\94 ×\91×\94×\99ס×\98×\95ר×\99×\99ת ×\94ש×\99× ×\95×\99×\99×\9d ×©×\9c ×\94×\93×£.\n×\90×\9d ×\94×\93×£ ×\94×\96×\94 × ×\9e×\97ק ×\91×¢×\91ר ×\95×\9c×\90×\97ר ×\9e×\9b×\9f × ×\95צר ×\9e×\97×\93ש ×\91×\90×\95ת×\95 ×\94ש×\9d, ×\94×\92רס×\90×\95ת ×\94×\9eש×\95×\97×\96ר×\95ת ×ª×\95פענ×\94 ×\91ת×\95ר ×\94×\92רס×\90×\95ת ×\94×\99שנ×\95ת ×\91×\99×\95תר.",
        "undeleterevdel": "השחזור לא יכול להתבצע אם הגרסה האחרונה של הדף מחוקה או מוסתרת.\nבמקרה כזה, יש לבטל קודם את ההסתרה של הגרסה האחרונה.",
        "undeletehistorynoadmin": "דף זה נמחק.\nהסיבה למחיקה מוצגת בתקציר שלמטה, וגם פרטים על המשתמשים שערכו את הדף לפני שהוא נמחק.\nהטקסט של הגרסאות הללו זמין למפעילי מערכת בלבד.",
        "undelete-revision": "גרסה שנמחקה מהדף $1 (מ־$5, $4) מאת $3:",
-       "undeleterevision-missing": "הגרסה שגויה או חסרה. ייתכן שמדובר בקישור שבור, או שהגרסה שוחזרה או הוסרה מהארכיון.",
+       "undeleterevision-missing": "הגרסה שגויה או חסרה.\nייתכן שמדובר בקישור שבור, או שהגרסה שוחזרה או הוסרה מהארכיון.",
        "undeleterevision-duplicate-revid": "לא ניתן היה לשחזר {{PLURAL:$1|גרסה אחת|$1 גרסאות}}, כיוון ששדה <code>rev_id</code> {{PLURAL:$1|שלה|שלהן}} כבר נמצא בשימוש.",
        "undelete-nodiff": "לא נמצאה גרסה קודמת.",
        "undeletebtn": "שחזור",
        "undeleteinvert": "הפיכת הבחירה",
        "undeletecomment": "סיבה:",
        "cannotundelete": "השחזור (או חלק ממנו) נכשל:\n$1",
-       "undeletedpage": "<strong>×\94×\93×£ $1 ×©×\95×\97×\96ר</strong>\n\nר×\90×\95 ×\90ת [[Special:Log/delete|×\99×\95×\9e×\9f ×\94×\9e×\97×\99ק×\95ת]] ×\9cרש×\99×\9e×\94 ×©×\9c ×\94×\9e×\97×\99ק×\95ת ×\95×\94ש×\97×\96×\95ר×\99×\9d ×©×\91×\95צע×\95 ×\9c×\90×\97ר×\95× ×\94.",
-       "undelete-header": "{{GENDER:|ראה|ראי|ראו}} את [[Special:Log/delete|יומן המחיקות]] לרשימה של דפים שנמחקו לאחרונה.",
+       "undeletedpage": "<strong>×\94×\93×£ $1 ×©×\95×\97×\96ר</strong>\n\nרש×\99×\9eת ×\94×\9e×\97×\99ק×\95ת ×\95×\94ש×\97×\96×\95ר×\99×\9d ×©×\91×\95צע×\95 ×\9c×\90×\97ר×\95× ×\94 ×\9e×\95פ×\99×¢×\94 ×\91[[Special:Log/delete|×\99×\95×\9e×\9f ×\94×\9e×\97×\99ק×\95ת]].",
+       "undelete-header": "רשימת הדפים שנמחקו לאחרונה מופיעה ב[[Special:Log/delete|יומן המחיקות]].",
        "undelete-search-title": "חיפוש דפים שנמחקו",
        "undelete-search-box": "חיפוש דפים שנמחקו",
        "undelete-search-prefix": "הצגת דפים החל מ:",
        "undelete-filename-mismatch": "לא ניתן לשחזר את גרסת הקובץ מ־$1: שם הקובץ לא תואם.",
        "undelete-bad-store-key": "לא ניתן לשחזר את גרסת הקובץ מ־$1: הקובץ היה חסר לפני המחיקה.",
        "undelete-cleanup-error": "שגיאת בעת מחיקת קובץ הארכיון \"$1\" שאינו בשימוש.",
-       "undelete-missing-filearchive": "שחזור קובץ הארכיון שמספרו $1 נכשל כיוון שהוא אינו בבסיס הנתונים. ייתכן שהוא כבר שוחזר.",
+       "undelete-missing-filearchive": "שחזור קובץ הארכיון שמספרו $1 נכשל כיוון שהוא אינו בבסיס הנתונים.\nייתכן שהוא כבר שוחזר.",
        "undelete-error": "שגיאה בשחזור דף",
        "undelete-error-short": "שגיאה בשחזור הקובץ: $1",
        "undelete-error-long": "שגיאות שאירעו בעת שחזור הקובץ:\n\n$1",
-       "undelete-show-file-confirm": "×\94×\90×\9d ×\90ת×\9d ×\91×\98×\95×\97×\99×\9d ×©×\91רצ×\95× ×\9b×\9d לצפות בגרסה המחוקה של הקובץ \"<nowiki>$1</nowiki>\" מ־$3, $2?",
+       "undelete-show-file-confirm": "×\94×\90×\9d ×\91רצ×\95× ×\9a לצפות בגרסה המחוקה של הקובץ \"<nowiki>$1</nowiki>\" מ־$3, $2?",
        "undelete-show-file-submit": "כן",
        "namespace": "מרחב שם:",
        "invert": "ללא מרחב זה",
        "tooltip-invert": "יש לסמן תיבה זו כדי להסתיר שינויים בדפים בתוך מרחב השם שנבחר (ובתוך מרחב השם הצמוד, אם הוא סומן)",
-       "tooltip-whatlinkshere-invert": "יש לסמן תיבה זו כדי להסתיר קישורים מדפים בתוך מרחב השם שנבחר",
+       "tooltip-whatlinkshere-invert": "יש לסמן תיבה זו כדי להסתיר קישורים מדפים בתוך מרחב השם שנבחר.",
        "namespace_association": "מרחב שם צמוד",
        "tooltip-namespace_association": "יש לסמן תיבה זו כדי לכלול גם את מרחב דפי השיחה או דפי הנושא המשויכים למרחב השם הנבחר",
        "blanknamespace": "(ראשי)",
        "uctop": "(נוכחי)",
        "month": "עד החודש:",
        "year": "עד השנה:",
+       "date": "עד התאריך:",
        "sp-contributions-newbies": "הצגת תרומות של משתמשים חדשים בלבד",
        "sp-contributions-newbies-sub": "עבור משתמשים חדשים",
        "sp-contributions-newbies-title": "תרומות של משתמשים חדשים",
        "sp-contributions-newonly": "הצגת עריכות שהן יצירות של דפים בלבד",
        "sp-contributions-hideminor": "הסתרת עריכות משניות",
        "sp-contributions-submit": "חיפוש",
-       "sp-contributions-outofrange": "לא ניתן להציג תוצאות. טווח ה־IP המבוקש גדול יותר ממגבלת ה־CIDR, שהיא /$1.",
+       "sp-contributions-outofrange": "לא ניתן להציג תוצאות. טווח ה־IP המבוקש גדול יותר ממגבלת ה־CIDR, שהיא <span dir=\"ltr\">/$1</span>.",
        "whatlinkshere": "דפים המקושרים לכאן",
        "whatlinkshere-title": "דפים המקשרים לדף \"$1\"",
        "whatlinkshere-page": "דף:",
-       "linkshere-2": "הדפים שלהלן מקושרים לדף '''$1''':",
-       "nolinkshere-2": "אין דפים המקושרים לדף '''$1'''.",
-       "nolinkshere-ns-2": "אין דפים המקושרים לדף '''$1''' במרחב השם שנבחר.",
+       "linkshere": "הדפים שלהלן מקשרים לדף <strong>$2</strong>:",
+       "nolinkshere": "אין דפים המקשרים לדף <strong>$2</strong>.",
+       "nolinkshere-ns": "אין דפים המקשרים לדף <strong>$2</strong> במרחב השם שנבחר.",
        "isredirect": "דף הפניה",
        "istemplate": "הכללה",
        "isimage": "קישור לקובץ",
        "whatlinkshere-hidetrans": "$1 הכללות",
        "whatlinkshere-hidelinks": "$1 קישורים",
        "whatlinkshere-hideimages": "$1 קישורים לקובץ",
-       "whatlinkshere-filters": "×\9eסננ×\99×\9d",
+       "whatlinkshere-filters": "ס×\99× ×\95×\9f",
        "whatlinkshere-submit": "הצגה",
        "autoblockid": "חסימה אוטומטית #$1",
        "block": "חסימת משתמש",
        "unblock": "שחרור חסימה של משתמש",
        "blockip": "חסימת ה{{GENDER:$1|משתמש|משתמשת}}",
-       "blockiptext": "×\94שת×\9eש×\95 ×\91×\98×\95פס ×©×\9c×\94×\9c×\9f ×\9b×\93×\99 ×\9c×\97ס×\95×\9d ×\90ת ×\94רש×\90×\95ת ×\94×\9bת×\99×\91×\94 ×\9e×\9bת×\95×\91ת IP ×\90×\95 ×\9eשת×\9eש ×\9eס×\95×\99×\9e×\99×\9d.\n×\97ס×\99×\9e×\95ת ×\9b×\90×\9c×\94 ×¦×¨×\99×\9b×\95ת ×\9c×\94ת×\91צע ×¨×§ ×\9b×\93×\99 ×\9c×\9e× ×\95×¢ ×\94ש×\97ת×\94, ×\95×\91×\94ת×\90×\9d ×\9c[[{{MediaWiki:Policy-url}}|× ×\94×\9c×\99×\9d]].\n×\90× ×\90 ×\9e×\9c×\90×\95 ×\90ת ×\94ס×\99×\91×\94 ×\94פר×\98× ×\99ת ×\9c×\97ס×\99×\9e×\94 ×\9c×\94×\9c×\9f (×\9c×\93×\95×\92×\9e×\94, ×\91×\90×\9eצע×\95ת ×¦×\99×\95×\9f ×\93פ×\99×\9d ×\9eס×\95×\99×\9e×\99×\9d ×©×\94ש×\97×\99ת ×\94×\9eשת×\9eש).\n×\91×\90פשר×\95ת×\9b×\9d לחסום טווחי כתובות IP באמצעות תחביר [https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing CIDR]; הטווח הגדול ביותר שניתן לחסום הוא <span dir=\"ltr\">/$1</span> עבור IPv4 ו־<span dir=\"ltr\">/$2</span> עבור IPv6.",
+       "blockiptext": "× ×\99ת×\9f ×\9c×\94שת×\9eש ×\91×\98×\95פס ×©×\9c×\94×\9c×\9f ×\9b×\93×\99 ×\9c×\97ס×\95×\9d ×\90ת ×\94רש×\90×\95ת ×\94×\9bת×\99×\91×\94 ×\9e×\9bת×\95×\91ת IP ×\9eס×\95×\99×\9eת ×\90×\95 ×\9eש×\9d ×\9eשת×\9eש ×\9eס×\95×\99×\9d.\n×\97ס×\99×\9e×\95ת ×\9b×\90×\9c×\94 ×¦×¨×\99×\9b×\95ת ×\9c×\94ת×\91צע ×¨×§ ×\9b×\93×\99 ×\9c×\9e× ×\95×¢ ×\94ש×\97ת×\94, ×\95×\91×\94ת×\90×\9d ×\9c[[{{MediaWiki:Policy-url}}|× ×\94×\9c×\99×\9d]].\n×\99ש ×\9c×\9e×\9c×\90 ×\90ת ×\94ס×\99×\91×\94 ×\94פר×\98× ×\99ת ×\9c×\97ס×\99×\9e×\94 ×\9c×\94×\9c×\9f (×\9c×\93×\95×\92×\9e×\94, ×\91×\90×\9eצע×\95ת ×¦×\99×\95×\9f ×\93פ×\99×\9d ×\9eס×\95×\99×\9e×\99×\9d ×©×\94ש×\97×\99ת ×\94×\9eשת×\9eש).\n×\91×\90פשר×\95ת×\9a לחסום טווחי כתובות IP באמצעות תחביר [https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing CIDR]; הטווח הגדול ביותר שניתן לחסום הוא <span dir=\"ltr\">/$1</span> עבור IPv4 ו־<span dir=\"ltr\">/$2</span> עבור IPv6.",
        "ipaddressorusername": "כתובת IP או שם משתמש:",
        "ipbexpiry": "פקיעה:",
        "ipbreason": "סיבה:",
        "ipb-disableusertalk": "ביטול האפשרות של המשתמש לערוך את דף השיחה של עצמו בעת החסימה",
        "ipb-change-block": "חסימת המשתמש מחדש עם הגדרות אלה",
        "ipb-confirm": "אישור החסימה",
-       "badipaddress": "×\9eשת×\9eש ×\90×\95 ×\9bת×\95×\91ת IP ×©×\92×\95×\99×\99×\9d.",
+       "badipaddress": "×\9bת×\95×\91ת IP ×©×\92×\95×\99×\94",
        "blockipsuccesssub": "החסימה הושלמה בהצלחה",
-       "blockipsuccesstext": "{{GENDER:$1|המשתמש|המשתמשת}} [[Special:Contributions/$1|$1]] {{GENDER:$1|נחסם|נחסמה}}.\n\nראו את [[Special:BlockList|רשימת החסומים]] כדי לצפות בחסימות.",
-       "ipb-blockingself": "{{GENDER:|אתה עומד|את עומדת|אתם עומדים}} לחסום את {{GENDER:|עצמך|עצמך|עצמכם}}! האם {{GENDER:|אתה בטוח שאתה רוצה|את בטוחה שאת רוצה|אתם בטוחים שאתם רוצים}} לעשות את זה?",
-       "ipb-confirmhideuser": "{{GENDER:|אתה עומד|את עומדת|אתם עומדים}} לחסום משתמש עם האפשרות \"הסתרת משתמש\". זה יעלים את שם המשתמש בכל הרשימות ופעולות היומן. האם {{GENDER:|אתה בטוח שברצונך|את בטוחה שברצונך|אתם בטוחים שברצונכם}} לעשות את זה?",
-       "ipb-confirmaction": "אם {{GENDER:|אתה בטוח שברצונך|את בטוחה שברצונך|אתם בטוחים שברצונכם}} לעשות זאת, אנא {{GENDER:|סמן|סמני|סמנו}} את השדה \"{{int:ipb-confirm}}\" שמופיע למטה.",
+       "blockipsuccesstext": "{{GENDER:$1|המשתמש|המשתמשת}} [[Special:Contributions/$1|$1]] {{GENDER:$1|נחסם|נחסמה}}.<br />\nניתן לעיין ב[[Special:BlockList|רשימת החסומים]] כדי לצפות בחסימות.",
+       "ipb-blockingself": "החשבון שלך ייחסם! האם ברצונך לעשות זאת?",
+       "ipb-confirmhideuser": "חשבון המשתמש ייחסם תוך הפעלת האפשרות \"הסתרת משתמש\". פעולה זו תעלים את שם המשתמש בכל הרשימות ופעולות היומן. האם ברצונך לעשות זאת?",
+       "ipb-confirmaction": "אם באמת התכוונת לעשות זאת, יש לסמן את השדה \"{{int:ipb-confirm}}\" שמופיע למטה.",
        "ipb-edit-dropdown": "עריכת סיבות החסימה",
        "ipb-unblock-addr": "שחרור חסימה של $1",
-       "ipb-unblock": "שחרור חסימה של משתמש או כתובת IP",
+       "ipb-unblock": "ש×\97ר×\95ר ×\97ס×\99×\9e×\94 ×©×\9c ×\9eשת×\9eש ×\90×\95 ×©×\9c ×\9bת×\95×\91ת IP",
        "ipb-blocklist": "הצגת החסימות הנוכחיות",
        "ipb-blocklist-contribs": "תרומות של {{GENDER:$1|$1}}",
-       "ipb-blocklist-duration-left": "× ×\95תר×\95 $1",
+       "ipb-blocklist-duration-left": "×\94×\96×\9e×\9f ×©× ×\95תר: $1",
        "unblockip": "שחרור חסימה של משתמש",
-       "unblockiptext": "{{GENDER:|השתמש|השתמשי|השתמשו}} בטופס שלהלן כדי להחזיר את הרשאות הכתיבה לכתובת IP חסומה או למשתמש חסום.",
+       "unblockiptext": "ניתן להשתמש בטופס שלהלן כדי להחזיר את הרשאות הכתיבה לכתובת IP חסומה או למשתמש חסום.",
        "ipusubmit": "הסרת חסימה זו",
        "unblocked": "[[User:$1|$1]] {{GENDER:$1|שוחרר מחסימתו|שוחררה מחסימתה}}.",
-       "unblocked-range": "$1 שוחרר מחסימתו.",
+       "unblocked-range": "חסימת הטווח $1 שוחררה.",
        "unblocked-id": "חסימה מספר $1 שוחררה.",
-       "unblocked-ip": "[[Special:Contributions/$1|$1]] שוחררה מחסימתה.",
+       "unblocked-ip": "הכתובת [[Special:Contributions/$1|$1]] שוחררה מחסימתה.",
        "blocklist": "משתמשים חסומים",
        "autoblocklist": "חסימות אוטומטיות",
        "autoblocklist-submit": "חיפוש",
        "blocklog-showsuppresslog": "{{GENDER:$1|משתמש זה נחסם והוסתר|משתמשת זו נחסמה והוסתרה}} בעבר.\nיומן ההעלמות מוצג להלן:",
        "blocklogentry": "חסם את [[$1]] למשך $2 $3",
        "reblock-logentry": "שינה את הגדרות החסימה של [[$1]] עם זמן פקיעה של $2 $3",
-       "blocklogtext": "×\96×\94×\95 ×\99×\95×\9e×\9f ×¤×¢×\95×\9c×\95ת ×\94×\97ס×\99×\9e×\94 ×\95×\94ש×\97ר×\95ר ×©×\9c ×\9eשת×\9eש×\99×\9d.\n×\9bת×\95×\91×\95ת IP ×©× ×\97ס×\9e×\95 ×\90×\95×\98×\95×\9e×\98×\99ת ×\90×\99× ×\9f ×\9e×\95פ×\99×¢×\95ת.\nר×\90×\95 ×\92×\9d ×\90ת [[Special:BlockList|רש×\99×\9eת ×\94×\97ס×\95×\9e×\99×\9d]] ×\9cרש×\99×\9e×\94 ×©×\9c ×\94×\97ר×\9e×\95ת ×\95×\97ס×\99×\9e×\95ת פעילות כעת.",
+       "blocklogtext": "×\96×\94×\95 ×\99×\95×\9e×\9f ×©×\9c ×¤×¢×\95×\9c×\95ת ×\94×\97ס×\99×\9e×\94 ×\95×\94ש×\97ר×\95ר ×©×\9c ×\9eשת×\9eש×\99×\9d.\n×\9bת×\95×\91×\95ת IP ×©× ×\97ס×\9e×\95 ×\90×\95×\98×\95×\9e×\98×\99ת ×\90×\99× ×\9f ×\9e×\95פ×\99×¢×\95ת.\n× ×\99ת×\9f ×\9c×¢×\99×\99×\9f ×\91[[Special:BlockList|רש×\99×\9eת ×\94×\97ס×\95×\9e×\99×\9d]] ×\9cצפ×\99×\99×\94 ×\91×\97ס×\99×\9e×\95ת ×\94פעילות כעת.",
        "unblocklogentry": "שחרר את החסימה של $1",
        "block-log-flags-anononly": "משתמשים אנונימיים בלבד",
        "block-log-flags-nocreate": "יצירת חשבונות נחסמה",
        "block-log-flags-hiddenname": "שם המשתמש הוסתר",
        "range_block_disabled": "האפשרות לחסום טווח כתובות אינה פעילה.",
        "ipb_expiry_invalid": "זמן פקיעת החסימה אינו תקין.",
-       "ipb_expiry_old": "×\96×\9e×\9f ×\94תפ×\95×\92ה כבר עבר.",
+       "ipb_expiry_old": "×\96×\9e×\9f ×\94פק×\99×¢ה כבר עבר.",
        "ipb_expiry_temp": "חסימות הכוללות הסתרת שם משתמש חייבות להיות לזמן בלתי מוגבל.",
        "ipb_hide_invalid": "לא ניתן להעלים את החשבון הזה; {{PLURAL:$1|בוצעה ממנו יותר מעריכה אחת|בוצעו ממנו יותר מ־$1 עריכות}}.",
        "ipb_already_blocked": "המשתמש \"$1\" כבר נחסם.",
        "ipb-otherblocks-header": "{{PLURAL:$1|חסימה אחרת|חסימות אחרות}}",
        "unblock-hideuser": "אין באפשרותך לשחרר את החסימה של המשתמש הזה, כיוון ששם המשתמש שלו הוסתר.",
        "ipb_cant_unblock": "שגיאה: חסימה מספר $1 לא נמצאה. ייתכן שהיא כבר שוחררה.",
-       "ipb_blocked_as_range": "שגיאה: כתובת ה־IP $1 אינה חסומה ישירות ולכן לא ניתן לשחרר את חסימתה. עם זאת, היא חסומה כחלק מהטווח $2, שניתן לשחרר את חסימתו.",
-       "ip_range_invalid": "טווח IP שגוי.",
+       "ipb_blocked_as_range": "שגיאה: כתובת ה־IP‏ $1 אינה חסומה ישירות ולכן לא ניתן לשחרר את חסימתה.\nעם זאת, היא חסומה כחלק מהטווח $2, שניתן לשחרר את חסימתו.",
+       "ip_range_invalid": "טווח כתובות IP שגוי.",
        "ip_range_toolarge": "לא ניתן לחסום טווחים גדולים מ־<span dir=\"ltr\">/$1</span>.",
-       "ip_range_exceeded": "טווח ה־IP חורג מהטווח המרבי. הטווח המותר: /$1.",
+       "ip_range_exceeded": "טווח ה־IP חורג מהטווח המרבי. הטווח המותר: <span dir=\"ltr\">/$1</span>.",
        "ip_range_toolow": "בפועל, טווחי IP אינם מורשים.",
        "proxyblocker": "חוסם פרוקסי",
        "proxyblockreason": "כתובת ה־IP שלכם נחסמה משום שהיא כתובת של שרת פרוקסי פתוח.\nאנא צרו קשר עם ספק האינטרנט שלכם או עם התמיכה הטכנית של הארגון שלכם והודיעו להם על בעיית האבטחה החמורה הזאת.",
        "sorbs_create_account_reason": "כתובת ה־IP שלך רשומה ככתובת פרוקסי פתוחה ב־DNSBL שאתר {{SITENAME}} משתמש בו.\nאין באפשרותך ליצור חשבון.",
        "softblockrangesreason": "תרומות אנונימיות אינן מותרות מכתובת ה־IP שלך ($1). נא להיכנס לחשבון.",
        "xffblockreason": "כתובת IP הנמצאת בכותרת X-Forwarded-For, בין אם שלכם או של שרת פרוקסי שאתם משתמשים בו, נחסמה. סיבת החסימה המקורית הייתה: $1",
-       "cant-see-hidden-user": "×\94×\9eשת×\9eש ×©×\90ת×\9d ×\9eנס×\99×\9d ×\9c×\97ס×\95×\9d ×\9b×\91ר × ×\97ס×\9d ×\95×\94×\95סתר.\n×\9b×\99×\95×\95×\9f ×©×\90×\99×\9f ×\9c×\9b×\9d ×\94רש×\90×\94 ×\9c×\94סתרת ×\9eשת×\9eש×\99×\9d, ×\90×\99×\9f ×\91×\90פשר×\95ת×\9b×\9d לצפות בחסימת המשתמש או לערוך אותה.",
-       "ipbblocked": "×\90×\99× ×\9b×\9d ×\99×\9b×\95×\9c×\99×\9d ×\9c×\97ס×\95×\9d ×\90×\95 ×\9cש×\97רר ×\90ת ×\97ס×\99×\9eת×\9d ×©×\9c ×\9eשת×\9eש×\99×\9d ×\90×\97ר×\99×\9d, ×\9b×\99×\95×\95×\9f ×©×\90ת×\9d ×¢×¦×\9e×\9b×\9d ×\97ס×\95×\9e×\99ם.",
-       "ipbnounblockself": "×\90×\99×\9f ×\91×\90פשר×\95ת×\9a ×\9c×\91×\98×\9c את החסימה של עצמך.",
+       "cant-see-hidden-user": "×\94×\9eשת×\9eש ×©× ×\99ס×\99ת ×\9c×\97ס×\95×\9d ×\9b×\91ר × ×\97ס×\9d ×\95×\94×\95סתר.\n×\9b×\99×\95×\95×\9f ×©×\90×\99×\9f ×\9c×\9a ×\94רש×\90×\94 ×\9c×\94סתרת ×\9eשת×\9eש×\99×\9d, ×\90×\99×\9f ×\91×\90פשר×\95ת×\9a לצפות בחסימת המשתמש או לערוך אותה.",
+       "ipbblocked": "×\90×\99×\9f ×\91×\90פשר×\95ת×\9a ×\9c×\97ס×\95×\9d ×\9eשת×\9eש×\99×\9d ×\90×\97ר×\99×\9d ×\90×\95 ×\9cש×\97רר ×\90ת ×\97ס×\99×\9eת×\9d, ×\9b×\99×\95×\95×\9f ×©×\94×\97ש×\91×\95×\9f ×©×\9c×\9a ×\97ס×\95ם.",
+       "ipbnounblockself": "×\90×\99×\9f ×\91×\90פשר×\95ת×\9a ×\9cש×\97רר את החסימה של עצמך.",
        "lockdb": "נעילת בסיס נתונים",
        "unlockdb": "שחרור בסיס נתונים",
-       "lockdbtext": "נעילת בסיס הנתונים תמנע ממשתמשים את האפשרות לערוך דפים, לשנות את העדפותיהם, לערוך את רשימות המעקב שלהם, ופעולות אחרות הדורשות ביצוע שינויים בבסיס הנתונים.\n\nאנא אשרו שזה מה שאתם מתכוונים לעשות, ושתשחררו את בסיס הנתונים מנעילה כאשר פעולת התחזוקה תסתיים.",
-       "unlockdbtext": "שחרור בסיס הנתונים מנעילה יחזיר לכל המשתמשים את היכולת לערוך דפים, לשנות את העדפות המשתמש שלהם, לערוך את רשימות המעקב שלהם, ולבצע פעולות אחרות הדורשות ביצוע שינויים בבסיס הנתונים.\nאנא אשרו שזה מה אכן מה שברצונכם לעשות.",
+       "lockdbtext": "נעילת בסיס הנתונים תמנע ממשתמשים את האפשרות לערוך דפים, לשנות את העדפותיהם, לערוך את רשימות המעקב שלהם ולבצע פעולות אחרות הדורשות ביצוע שינויים בבסיס הנתונים.\nנא לאשר שזה אכן מה שהתכוונת לעשות, ולשחרר את בסיס הנתונים מנעילה כאשר פעולת התחזוקה תסתיים.",
+       "unlockdbtext": "שחרור בסיס הנתונים מנעילה יחזיר לכל המשתמשים את היכולת לערוך דפים, לשנות את העדפות המשתמש שלהם, לערוך את רשימות המעקב שלהם ולבצע פעולות אחרות הדורשות ביצוע שינויים בבסיס הנתונים.\nנא לאשר שזה אכן מה שהתכוונת לעשות.",
        "lockconfirm": "כן, ברצוני לנעול את בסיס הנתונים.",
        "unlockconfirm": "כן, ברצוני לשחרר את בסיס הנתונים מנעילה.",
        "lockbtn": "נעילת בסיס הנתונים",
        "lockdbsuccesssub": "נעילת בסיס הנתונים הושלמה בהצלחה",
        "unlockdbsuccesssub": "שוחררה הנעילה מבסיס הנתונים",
        "lockdbsuccesstext": "בסיס הנתונים ננעל.<br />\nיש לזכור [[Special:UnlockDB|לשחרר את הנעילה]] לאחר שפעולת התחזוקה תסתיים.",
-       "unlockdbsuccesstext": "שוחררה הנעילה של בסיס הנתונים",
-       "lockfilenotwritable": "קובץ נעילת בסיס הנתונים אינו ניתן לכתיבה. כדי שאפשר יהיה לנעול את בסיס הנתונים או לבטל את נעילתו, שרת האינטרנט צריך לקבל הרשאות לכתוב אליו.",
+       "unlockdbsuccesstext": "שוחררה הנעילה של בסיס הנתונים.",
+       "lockfilenotwritable": "קובץ נעילת בסיס הנתונים אינו ניתן לכתיבה.\nכדי שאפשר יהיה לנעול את בסיס הנתונים או לבטל את נעילתו, שרת האינטרנט צריך לקבל הרשאות לכתוב אליו.",
        "databaselocked": "בסיס הנתונים כבר נעול.",
        "databasenotlocked": "בסיס הנתונים אינו נעול.",
        "lockedbyandtime": "(על־ידי $1 ב־$3, $2)",
        "movepagetext": "ניתן להשתמש בטופס שלהלן כדי לשנות את השם של הדף הזה ולהעביר את כל היסטוריית העריכות שלו לשם החדש.\nהשם הישן יהפוך לדף הפניה אל השם החדש.\nבאפשרותך לעדכן באופן אוטומטי דפי הפניה שכרגע מפנים לשם הנוכחי של הדף.\nנא לוודא לאחר ההעברה שאין [[Special:DoubleRedirects|הפניות כפולות]] או [[Special:BrokenRedirects|הפניות שבורות]] (אלא אם כן בחרת לבצע את העדכון האוטומטי הנ\"ל).\nכמו כן, באחריותך לוודא שכל הקישורים ימשיכו לקשר למקומות שאליהם הם אמורים לקשר.\n\nיש לשים לב לכך שהדף <strong>לא</strong> יועבר אם כבר יש דף תחת השם החדש, אלא אם כן הדף עם השם החדש הוא הפניה ואין לו עריכות קודמות.\nזה אומר שניתן יהיה להחזיר את הדף לשם המקורי במקרה שתיעשה טעות, אבל לא ניתן \"לדרוס\" דף קיים.\n\n<strong>לתשומת לבך:</strong>\nהעברה זו עלולה להיות שינוי דרסטי ומהותי לדף פופולרי;\nיש לקחת בחשבון את התוצאות של הפעולה הזאת לפני ביצוע ההעברה.",
        "movepagetext-noredirectfixer": "ניתן להשתמש בטופס שלהלן כדי לשנות את השם של הדף הזה ולהעביר את כל היסטוריית העריכות שלו לשם החדש.\nהשם הישן יהפוך לדף הפניה אל השם החדש.\nנא לוודא לאחר ההעברה שאין [[Special:DoubleRedirects|הפניות כפולות]] או [[Special:BrokenRedirects|הפניות שבורות]].\nכמו כן, באחריותך לוודא שכל הקישורים ימשיכו לקשר למקומות שאליהם הם אמורים לקשר.\n\nיש לשים לב לכך שהדף <strong>לא</strong> יועבר אם כבר יש דף תחת השם החדש, אלא אם כן הדף עם השם החדש הוא הפניה ואין לו עריכות קודמות.\nזה אומר שניתן יהיה להחזיר את הדף לשם המקורי במקרה שתיעשה טעות, אבל לא ניתן \"לדרוס\" דף קיים.\n\n<strong>לתשומת לבך:</strong>\nהעברה זו עלולה להיות שינוי דרסטי ומהותי לדף פופולרי;\nיש לקחת בחשבון את התוצאות של הפעולה הזאת לפני ביצוע ההעברה.",
        "movepagetalktext": "אם האפשרות הזאת מסומנת, דף השיחה של הדף הזה יועבר אוטומטית לשם החדש, אלא אם קיים דף שיחה שאינו ריק תחת השם החדש. במקרה כזה, יש להעביר או למזג את הדפים באופן ידני, במידת הצורך.",
-       "moveuserpage-warning": "'''אזהרה:''' אתם עומדים להעביר דף משתמש. שימו לב שרק הדף יועבר וששם המשתמש '''לא''' ישתנה.",
-       "movecategorypage-warning": "<strong>×\90×\96×\94ר×\94:</strong> ×\90ת×\9d ×¢×\95×\9e×\93×\99×\9d ×\9c×\94×¢×\91×\99ר ×\93×£ ×§×\98×\92×\95ר×\99×\94. ×©×\99×\9e×\95 ×\9c×\91 ×©×¨×§ ×\94×\93×£ ×\99×\95×¢×\91ר ×\95ש×\9b×\9c ×\94×\93פ×\99×\9d ×\91ק×\98×\92×\95ר×\99×\94 ×\94×\99שנ×\94 <strong>×\9c×\90</strong> יסווגו לקטגוריה החדשה.",
-       "movenologintext": "×¢×\9c×\99×\9b×\9d ×\9c×\94×\99×\95ת ×¨×©×\95×\9e×\99×\9d ×\95[[Special:UserLogin|×\9c×\94×\99×\9bנס ×\9c×\97ש×\91×\95×\9f]] כדי להעביר דפים.",
+       "moveuserpage-warning": "<strong>אזהרה:</strong> הדף שיועבר הוא דף משתמש. חשוב לציין שרק הדף יועבר וששם המשתמש <em>לא</em> ישתנה.",
+       "movecategorypage-warning": "<strong>×\90×\96×\94ר×\94:</strong> ×\94×\93×£ ×©×\99×\95×¢×\91ר ×\94×\95×\90 ×\93×£ ×§×\98×\92×\95ר×\99×\94. ×\97ש×\95×\91 ×\9cצ×\99×\99×\9f ×©×¨×§ ×\94×\93×£ ×\99×\95×¢×\91ר ×\95ש×\9b×\9c ×\94×\93פ×\99×\9d ×\91ק×\98×\92×\95ר×\99×\94 ×\94×\99שנ×\94 <em>×\9c×\90</em> יסווגו לקטגוריה החדשה.",
+       "movenologintext": "×\99ש ×\9c×\99צ×\95ר ×\97ש×\91×\95×\9f ×\95[[Special:UserLogin|×\9c×\94×\99×\9bנס ×\90×\9c×\99×\95]] כדי להעביר דפים.",
        "movenotallowed": "אין לך הרשאה להעביר דפים.",
        "movenotallowedfile": "אין לך הרשאה להעביר קבצים.",
        "cant-move-user-page": "אין לך הרשאה להעביר דפי משתמש (למעט דפי משנה).",
        "delete_and_move_confirm": "אישור מחיקת הדף",
        "delete_and_move_reason": "מחיקה כדי לאפשר העברה מהשם \"[[$1]]\"",
        "selfmove": "הכותרת זהה;\nלא ניתן להעביר דף לעצמו.",
-       "immobile-source-namespace": "לא ניתן להעביר דפים במרחב השם \"$1\"",
-       "immobile-target-namespace": "לא ניתן להעביר דפים למרחב השם \"$1\"",
+       "immobile-source-namespace": "לא ניתן להעביר דפים במרחב השם \"$1\".",
+       "immobile-target-namespace": "לא ניתן להעביר דפים למרחב השם \"$1\".",
        "immobile-target-namespace-iw": "קישור בינוויקי אינו יעד תקין להעברת דף.",
        "immobile-source-page": "דף זה אינו ניתן להעברה.",
        "immobile-target-page": "לא ניתן להעביר אל כותרת יעד זו.",
        "bad-target-model": "היעד המבוקש משתמש במודל תוכן שונה. לא ניתן להמיר $1 ל{{grammar:תחילית|$2}}.",
-       "imagenocrossnamespace": "לא ניתן להעביר קובץ למרחב שם אחר",
-       "nonfile-cannot-move-to-file": "לא ניתן להעביר דף שאינו קובץ למרחב קובץ",
-       "imagetypemismatch": "סיומת הקובץ החדשה אינה מתאימה לסוג הקובץ",
-       "imageinvalidfilename": "שם קובץ היעד אינו תקין",
+       "imagenocrossnamespace": "לא ניתן להעביר קובץ למרחב שם אחר.",
+       "nonfile-cannot-move-to-file": "לא ניתן להעביר דף שאינו קובץ למרחב קובץ.",
+       "imagetypemismatch": "סיומת הקובץ החדשה אינה מתאימה לסוג הקובץ.",
+       "imageinvalidfilename": "שם קובץ היעד אינו תקין.",
        "fix-double-redirects": "עדכון הפניות לכותרת הדף המקורית",
        "move-leave-redirect": "השארת הפניה בדף המקורי",
-       "protectedpagemovewarning": "'''אזהרה:''' דף זה מוגן כך שרק מפעילי מערכת יכולים להעביר אותו.\nפעולת היומן האחרונה מוצגת להלן:",
+       "protectedpagemovewarning": "<strong>אזהרה:</strong> דף זה מוגן כך שרק מפעילי מערכת יכולים להעביר אותו.\nפעולת היומן האחרונה מוצגת להלן:",
        "semiprotectedpagemovewarning": "<strong>הערה:</strong> דף זה מוגן כך שרק משתמשים ותיקים יכולים להעביר אותו.\nפעולת היומן האחרונה מוצגת להלן:",
        "move-over-sharedrepo": "[[:$1]] כבר קיים במאגר משותף. העברת הקובץ לכותרת זו תדרוס את הקובץ המשותף.",
        "file-exists-sharedrepo": "קובץ בשם שנבחר כבר קיים כקובץ משותף.\nיש לבחור שם אחר.",
        "export": "ייצוא דפים",
-       "exporttext": "×\91×\90פשר×\95ת×\9b×\9d ×\9c×\99×\99צ×\90 ×\90ת ×\94ת×\95×\9b×\9f ×\95×\90ת ×\94×\99ס×\98×\95ר×\99×\99ת ×\94ער×\99×\9b×\94 ×©×\9c ×\93×£ ×\90×\97×\93 ×\90×\95 ×©×\9c ×\9eספר ×\93פ×\99×\9d, ×\91ת×\91× ×\99ת ×©×\9c ×§×\95×\91×¥ XML.\n× ×\99ת×\9f ×\9c×\99×\99×\91×\90 ×\90ת ×\94ק×\95×\91×¥ ×\9c×\9e×\99×\96×\9d ×\95×\99ק×\99 ×\90×\97ר ×\94×\9eשת×\9eש ×\91ת×\95×\9bנת ×\9e×\93×\99×\94Ö¾×\95×\99ק×\99 ×\91×\90×\9eצע×\95ת [[Special:Import|×\93×£ ×\94×\99×\99×\91×\95×\90]].\n\n×\9b×\93×\99 ×\9c×\99×\99צ×\90 ×\93פ×\99×\9d, ×\94ק×\99ש×\95 ×\90ת ×©×\9e×\95ת×\99×\94×\9d ×\91ת×\99×\91ת ×\94×\98קס×\98 ×©×\9c×\94×\9c×\9f, ×\9b×\9c ×©×\9d ×\91ש×\95ר×\94 × ×¤×¨×\93ת, ×\95×\91×\97ר×\95 האם לייצא גם את הגרסה הנוכחית וגם את היסטוריית השינויים של הדפים, או רק את הגרסה הנוכחית עם מידע על העריכה האחרונה.\n\nבנוסף, ניתן להשתמש בקישור, כגון [[{{#Special:Export}}/{{MediaWiki:Mainpage}}]] לדף [[{{MediaWiki:Mainpage}}]] ללא היסטוריית השינויים שלו.",
+       "exporttext": "×\91×\90פשר×\95ת×\9a ×\9c×\99×\99צ×\90 ×\90ת ×\94ת×\95×\9b×\9f ×\95×\90ת ×\94×\99ס×\98×\95ר×\99×\99ת ×\94ער×\99×\9b×\94 ×©×\9c ×\93×£ ×\90×\97×\93 ×\90×\95 ×©×\9c ×\9eספר ×\93פ×\99×\9d, ×\91ת×\91× ×\99ת ×©×\9c ×§×\95×\91×¥ XML.\n× ×\99ת×\9f ×\9c×\99×\99×\91×\90 ×\90ת ×\94ק×\95×\91×¥ ×\9c×\90תר ×\95×\99ק×\99 ×\90×\97ר ×\94×\9eשת×\9eש ×\91ת×\95×\9bנת ×\9e×\93×\99×\94Ö¾×\95×\99ק×\99 ×\91×\90×\9eצע×\95ת [[Special:Import|×\93×£ ×\94×\99×\99×\91×\95×\90]].\n\n×\9b×\93×\99 ×\9c×\99×\99צ×\90 ×\93פ×\99×\9d, ×\99ש ×\9c×\94ק×\9c×\99×\93 ×\90ת ×©×\9e×\95ת×\99×\94×\9d ×\91ת×\99×\91ת ×\94×\98קס×\98 ×©×\9c×\94×\9c×\9f, ×\9b×\9c ×©×\9d ×\91ש×\95ר×\94 × ×¤×¨×\93ת, ×\95×\9c×\91×\97×\95ר האם לייצא גם את הגרסה הנוכחית וגם את היסטוריית השינויים של הדפים, או רק את הגרסה הנוכחית עם מידע על העריכה האחרונה.\n\nבנוסף, ניתן להשתמש בקישור, כגון [[{{#Special:Export}}/{{MediaWiki:Mainpage}}]] לדף [[{{MediaWiki:Mainpage}}]] ללא היסטוריית השינויים שלו.",
        "exportall": "ייצוא כל הדפים",
        "exportcuronly": "לכלול רק את הגרסה הנוכחית, ללא כל ההיסטוריה",
-       "exportnohistory": "----\n'''הערה:''' ייצוא ההיסטוריה המלאה של דפים דרך טופס זה הופסקה עקב בעיות ביצועים.",
+       "exportnohistory": "----\n<strong>הערה:</strong> ייצוא ההיסטוריה המלאה של דפים דרך טופס זה הופסקה עקב בעיות ביצועים.",
        "exportlistauthors": "הכללת רשימה מלאה של התורמים לכל הדף",
        "export-submit": "ייצוא",
        "export-addcattext": "הוספת דפים מהקטגוריה:",
        "allmessagesname": "שם",
        "allmessagesdefault": "טקסט ברירת המחדל של ההודעה",
        "allmessagescurrent": "הטקסט הנוכחי של ההודעה",
-       "allmessagestext": "×\96×\95×\94×\99 ×¨×©×\99×\9e×\94 ×©×\9c ×\9b×\9c ×\94×\95×\93×¢×\95ת ×\94×\9eער×\9bת ×\91×\9eר×\97×\91 ×\94ש×\9d {{ns:mediawiki}}.\n×\90× ×\90 ×\91קר×\95 ×\91×\93×£ [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation MediaWiki Localisation] ×\95×\91×\90תר [https://translatewiki.net translatewiki.net] ×\90×\9d ×\91רצ×\95× ×\9b×\9d לתרום לתרגום הכללי של מדיה־ויקי.",
-       "allmessagesnotsupportedDB": "לא ניתן להשתמש בדף זה כיוון ש־wgUseDatabseMessages מבוטל.",
-       "allmessages-filter-legend": "×\9eסנן",
+       "allmessagestext": "×\96×\95×\94×\99 ×¨×©×\99×\9e×\94 ×©×\9c ×\94×\95×\93×¢×\95ת ×\94×\9eער×\9bת ×\91×\9eר×\97×\91 ×\94ש×\9d \"{{ns:mediawiki}}\".\n× ×\99ת×\9f ×\9c×\91קר ×\91×\93×£ [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation MediaWiki Localisation] ×\95×\91×\90תר [https://translatewiki.net translatewiki.net] ×\9b×\93×\99 לתרום לתרגום הכללי של מדיה־ויקי.",
+       "allmessagesnotsupportedDB": "לא ניתן להשתמש בדף זה כיוון ש־<strong dir=\"ltr\">$wgUseDatabaseMessages</strong> מבוטל.",
+       "allmessages-filter-legend": "ס×\99× ×\95ן",
        "allmessages-filter": "סינון לפי מצב ההודעה:",
        "allmessages-filter-unmodified": "הודעות שלא שונו",
        "allmessages-filter-all": "הכול",
        "thumbnail_error_remote": "הודעת שגיאה של $1:\n$2",
        "djvu_page_error": "דף ה־DjVu מחוץ לטווח",
        "djvu_no_xml": "לא ניתן היה לקבל את ה־XML עבור קובץ ה־DjVu",
-       "thumbnail-temp-create": "×\9c×\90 ×\94צ×\9c×\99×\97×\94 ×\99צ×\99רת ×§×\95×\91×¥ ×ª×\9e×\95× ×\94 ×\9e×\9e×\95×\96ערת זמני",
+       "thumbnail-temp-create": "×\9c×\90 ×\94×\99×\99ת×\94 ×\90פשר×\95ת ×\9c×\99צ×\95ר ×\90ת ×§×\95×\91×¥ ×\94ת×\9e×\95× ×\94 ×\94×\9e×\9e×\95×\96ערת ×\94זמני",
        "thumbnail-dest-create": "לא הייתה אפשרות לשמור את התמונה הממוזערת אל יעדה",
        "thumbnail_invalid_params": "פרמטרים שגויים לתמונה הממוזערת",
        "thumbnail_toobigimagearea": "קובץ בגודל של יותר מ־$1",
        "thumbnail_dest_directory": "לא ניתן היה ליצור את תיקיית היעד",
        "thumbnail_image-type": "סוג התמונה אינו נתמך",
-       "thumbnail_gd-library": "הגדרת הספריה GD אינה שלמה: חסרה הפונקציה $1",
+       "thumbnail_gd-library": "×\94×\92×\93רת ×\94ספר×\99×\99×\94 GD ×\90×\99× ×\94 ×©×\9c×\9e×\94: ×\97סר×\94 ×\94פ×\95נקצ×\99×\94 $1",
        "thumbnail_image-size-zero": "נראה שקובץ התמונה הוא בגודל אפס.",
        "thumbnail_image-missing": "נראה שהקובץ הבא חסר: $1",
        "thumbnail_image-failure-limit": "היו לאחרונה ניסיונות רבים מדי ($1 או יותר) ליצור את התמונה הממוזערת הזאת. נא לנסות שוב מאוחר יותר.",
        "import-upload-username-prefix": "קידומת בינוויקי:",
        "import-assign-known-users": "הקצאת העריכות למשתמשים המקומיים כאשר משתמשים בשמות זהים קיימים באתר המקומי",
        "import-comment": "הערה:",
-       "importtext": "נא לייצא את הקובץ מאתר המקור באמצעות ב[[Special:Export|כלי הייצוא]].\nשמרו אותו למחשב שלכם והעלו אותו לכאן.",
+       "importtext": "נא לייצא את הקובץ מאתר המקור באמצעות [[Special:Export|כלי הייצוא]].\nיש לשמור אותו במחשב ולהעלות אותו לכאן.",
        "importstart": "ייבוא דפים...",
        "import-revision-count": "&rlm;{{PLURAL:$1|גרסה אחת|$1 גרסאות}}",
        "importnopages": "אין דפים לייבוא.",
        "importsuccess": "הייבוא הושלם בהצלחה!",
        "importnosources": "לא הוגדרו אתרי ויקי שמהם ניתן לייבא, ואפשרות ההעלאה הישירה של דף עם היסטוריה מבוטלת.",
        "importnofile": "לא הועלה קובץ ייבוא.",
-       "importuploaderrorsize": "העלאת קובץ הייבוא נכשלה. הקובץ היה גדול יותר מגודל ההעלאה המותר.",
-       "importuploaderrorpartial": "העלאת קובץ הייבוא נכשלה. הקובץ הועלה באופן חלקי בלבד.",
-       "importuploaderrortemp": "העלאת קובץ הייבוא נכשלה. חסרה תיקייה זמנית.",
+       "importuploaderrorsize": "העלאת קובץ הייבוא נכשלה.\nהקובץ היה גדול יותר מגודל ההעלאה המותר.",
+       "importuploaderrorpartial": "העלאת קובץ הייבוא נכשלה.\nהקובץ הועלה באופן חלקי בלבד.",
+       "importuploaderrortemp": "העלאת קובץ הייבוא נכשלה.\nחסרה תיקייה זמנית.",
        "import-parse-failure": "שגיאה בפענוח ה־XML",
        "import-noarticle": "אין דף לייבוא!",
-       "import-nonewrevisions": "×\9b×\9c ×\94×\92רס×\90×\95ת ×\99×\95×\91×\90×\95 ×\91×¢×\91ר.",
+       "import-nonewrevisions": "×\9c×\90 ×\99×\95×\91×\90×\95 ×\92רס×\90×\95ת (×\9b×\95×\9c×\9f ×\9b×\91ר ×§×\99×\99×\9e×\95ת, ×\90×\95 ×©×\94×\9f ×\9c×\90 ×\94×\95×¢×\9c×\95 ×¢×§×\91 ×©×\92×\99×\90×\95ת).",
        "xml-error-string": "$1 בשורה $2, עמודה $3 (בית מספר $4): $5",
        "import-upload": "העלאת קובץ XML",
        "import-token-mismatch": "נתוני ההתחברות אבדו.\n\nייתכן שנותקתם מהחשבון. '''אנא ודאו שאתם עדיין מחוברים לחשבון ונסו שוב.'''\nאם זה עדיין לא עובד, נסו [[Special:UserLogout|לצאת מהחשבון]] ולהיכנס אליו שנית, וודאו שהדפדפן שלכם מאפשר קבלת עוגיות מאתר זה.",
        "import-error-create": "לא ניתן לייבא את הדף \"$1\" כיוון שאין לך הרשאה ליצור אותו.",
        "import-error-interwiki": "לא ניתן לייבא את הדף \"$1\" כיוון ששמו שמור לקישור חיצוני (בינוויקי).",
        "import-error-special": "לא ניתן לייבא את הדף \"$1\" כיוון שהוא שייך למרחב שם מיוחד שלא יכול להכיל דפים.",
-       "import-error-invalid": "לא ניתן לייבא את הדף \"$1\" כיוון ששמו אינו תקין.",
+       "import-error-invalid": "לא ניתן לייבא את הדף \"$1\" כיוון ששמו אינו תקין באתר זה.",
        "import-error-unserialize": "לא ניתן היה לפענח את הגרסה $2 של הדף \"$1\". הגרסה מסומנת כאילו היא משתמשת במודל התוכן $3, אך קודדה כ{{GRAMMAR:תחילית|$4}}.",
        "import-error-bad-location": "גרסה $2 המשתמשת במודל התוכן $3 אינה ניתנת לשמירה ב‏‏֫דף \"$1\" באתר ויקי זה, כיוון שהמודל אינו נתמך בדף זה.",
        "import-options-wrong": "{{PLURAL:$2|אפשרות שגויה|אפשרויות שגויות}}: <nowiki>$1</nowiki>",
        "import-logentry-interwiki-detail": "{{PLURAL:$1|גרסה אחת של הדף $2 יובאה|$1 גרסאות של הדף $2 יובאו}}",
        "javascripttest": "בדיקת JavaScript",
        "javascripttest-pagetext-unknownaction": "הפעולה \"$1\" אינה ידועה.",
-       "javascripttest-qunit-intro": "ר×\90×\95 ×\90ת [$1 תיעוד הבדיקות] באתר mediawiki.org.",
+       "javascripttest-qunit-intro": "× ×\99ת×\9f ×\9c×¢×\99×\99×\9f ×\91[$1 תיעוד הבדיקות] באתר mediawiki.org.",
        "tooltip-pt-userpage": "דף {{GENDER:|המשתמש|המשתמשת}} שלך",
-       "tooltip-pt-anonuserpage": "×\93×£ ×\94×\9eשת×\9eש ×©×\9c ×\9eשת×\9eש ×\90× ×\95× ×\99×\9e×\99 ×\96×\94",
+       "tooltip-pt-anonuserpage": "×\93×£ ×\94×\9eשת×\9eש ×©×\9c ×\9bת×\95×\91ת IP ×\96×\95",
        "tooltip-pt-mytalk": "דף השיחה שלך",
-       "tooltip-pt-anontalk": "דיון על העריכות שנעשו מכתובת ה־IP הזאת",
+       "tooltip-pt-anontalk": "דיון על העריכות שנעשו מכתובת IP זו",
        "tooltip-pt-preferences": "ההעדפות שלך",
        "tooltip-pt-watchlist": "רשימת הדפים {{GENDER:|שאתה עוקב|שאת עוקבת}} אחרי השינויים בהם",
        "tooltip-pt-mycontris": "רשימת העריכות שביצעת",
-       "tooltip-pt-anoncontribs": "רשימת העריכות שנעשו מכתובת ה־IP הזאת",
+       "tooltip-pt-anoncontribs": "רשימת העריכות שנעשו מכתובת IP זו",
        "tooltip-pt-login": "מומלץ להיכנס לחשבון, אך אין חובה לעשות זאת",
        "tooltip-pt-login-private": "יש להיכנס לחשבון כדי להשתמש באתר הוויקי הזה",
        "tooltip-pt-logout": "יציאה מהחשבון",
        "tooltip-summary": "תיאור קצר של השינויים שביצעת",
        "common.css": "/* הסגנונות הנכתבים כאן ישפיעו על כל העיצובים */",
        "print.css": "/* הסגנונות הנכתבים כאן ישפיעו על הפלט בהדפסה בלבד */",
-       "noscript.css": "/* הסגנונות הנכתבים כאן ישפיעו על משתמשים עם ג'אווה-סקריפט מבוטל */",
+       "noscript.css": "/* הסגנונות הנכתבים כאן ישפיעו על משתמשים עם ג'אווה־סקריפט מבוטל */",
        "group-autoconfirmed.css": "/* הסגנונות הנכתבים כאן ישפיעו על משתמשים ותיקים בלבד */",
        "group-user.css": "/* הסגנונות הנכתבים כאן ישפיעו על משתמשים רשומים בלבד */",
        "group-bot.css": "/* הסגנונות הנכתבים כאן ישפיעו על בוטים בלבד */",
        "group-sysop.css": "/* הסגנונות הנכתבים כאן ישפיעו על מפעילי מערכת בלבד */",
        "group-bureaucrat.css": "/* הסגנונות הנכתבים כאן ישפיעו על ביורוקרטים בלבד */",
        "common.json": "/* כל ה־JSON שנכתב כאן ייטען עבור כל המשתמשים בכל טעינת עמוד. */",
-       "common.js": "/* ×\9b×\9c ×\94סקר×\99פ×\98×\99×\9d ×©נכתבים כאן ייטענו עבור כל המשתמשים בכל טעינת עמוד. */",
+       "common.js": "/* ×\9b×\9c ×\94סקר×\99פ×\98×\99×\9d ×\94נכתבים כאן ייטענו עבור כל המשתמשים בכל טעינת עמוד. */",
        "group-autoconfirmed.js": "/* כל הסקריפטים הנכתבים כאן ייטענו עבור משתמשים ותיקים בלבד */",
        "group-user.js": "/* כל הסקריפטים הנכתבים כאן ייטענו עבור משתמשים רשומים בלבד */",
        "group-bot.js": "/* כל הסקריפטים הנכתבים כאן ייטענו עבור בוטים בלבד */",
        "spam_reverting": "שחזור לגרסה אחרונה שלא כוללת קישורים ל־$1",
        "spam_blanking": "כל הגרסאות כוללות קישורים ל־$1, מרוקן את הדף",
        "spam_deleting": "כל הגרסאות כוללות קישורים ל־$1, מוחק את הדף",
-       "simpleantispam-label": "×\91×\93×\99קת ×\90× ×\98×\99־ספ×\90×\9d.\n<strong>×\90×\9c</strong> ×ª×\9e×\9c×\90×\95 שדה זה!",
+       "simpleantispam-label": "×\91×\93×\99קת ×\90× ×\98×\99־ספ×\90×\9d.\n<strong>×\90×\99×\9f</strong> ×\9c×\9e×\9c×\90 שדה זה!",
        "pageinfo-title": "מידע על הדף \"$1\"",
        "pageinfo-not-current": "מצטערים, לא ניתן להציג את המידע הזה לגרסאות ישנות.",
        "pageinfo-header-basic": "מידע בסיסי",
        "pageinfo-magic-words": "{{PLURAL:$1|מילת קסם|מילות קסם}} ($1)",
        "pageinfo-hidden-categories": "{{PLURAL:$1|קטגוריה מוסתרת|קטגוריות מוסתרות}} ($1)",
        "pageinfo-templates": "{{PLURAL:$1|תבנית מוכללת|תבניות מוכללות}} ($1)",
-       "pageinfo-transclusions": "{{PLURAL:$1|דף|דפים}} שמוכלל בהם ($1)",
+       "pageinfo-transclusions": "{{PLURAL:$1|דף|דפים}} שמוכלל {{PLURAL:$1|בו|בהם}} ($1)",
        "pageinfo-toolboxlink": "מידע על הדף",
        "pageinfo-redirectsto": "מפנה אל",
        "pageinfo-redirectsto-info": "מידע",
        "markedaspatrolled": "השינוי סומן כבדוק",
        "markedaspatrolledtext": "הגרסה שבחרת בדף [[:$1]] סומנה כבדוקה.",
        "rcpatroldisabled": "אפשרות סימון השינויים כבדוקים מבוטלת",
-       "rcpatroldisabledtext": "ת×\9b×\95נת ×¡×\99×\9e×\95×\9f ×©×\99× ×\95×\99×\99×\9d ×\9b×\91×\93×\95ק×\99×\9d ×\91×\93×£ ×\94ש×\99× ×\95×\99×\99×\9d ×\94×\90×\97ר×\95× ×\99×\9d ×\91×\95×\98×\9c×\94.",
+       "rcpatroldisabledtext": "ת×\9b×\95נת ×¡×\99×\9e×\95×\9f ×\94ש×\99× ×\95×\99×\99×\9d ×\9b×\91×\93×\95ק×\99×\9d ×\91×\93×£ ×\94ש×\99× ×\95×\99×\99×\9d ×\94×\90×\97ר×\95× ×\99×\9d ×\9e×\91×\95×\98×\9cת ×\9bר×\92×¢.",
        "markedaspatrollederror": "לא ניתן לסמן כבדוק",
        "markedaspatrollederrortext": "יש לציין גרסה שברצונך לסמן כבדוקה.",
-       "markedaspatrollederror-noautopatrol": "×\90×\99× ×\9a ×\9e×\95רש×\94 לסמן שינויים של עצמך כבדוקים.",
+       "markedaspatrollederror-noautopatrol": "×\90×\99×\9f ×\91×\90פשר×\95ת×\9a לסמן שינויים של עצמך כבדוקים.",
        "markedaspatrollednotify": "שינוי זה בדף \"$1\" סומן כבדוק.",
        "markedaspatrollederrornotify": "סימון השינוי כבדוק נכשל.",
        "patrol-log-page": "יומן שינויים בדוקים",
        "patrol-log-header": "יומן זה מציג גרסאות שנבדקו.",
-       "log-show-hide-patrol": "$1 יומן שינויים בדוקים",
-       "log-show-hide-tag": "$1 יומן תגיות",
        "confirm-markpatrolled-button": "אישור",
        "confirm-markpatrolled-top": "לסמן את גרסה $3 בדף $2 כבדוקה?",
        "deletedrevision": "מחיקת גרסה ישנה ($1)",
        "file-info-png-looped": "בלולאה",
        "file-info-png-repeat": "מוצג {{PLURAL:$1|פעם אחת|פעמיים|$1 פעמים}}",
        "file-info-png-frames": "{{PLURAL:$1|תמונה אחת|$1 תמונות}}",
-       "file-no-thumb-animation": "'''לתשומת לבך: בשל מגבלות טכניות, תמונות ממוזערות של הקובץ הזה לא תהיינה מונפשות.'''",
-       "file-no-thumb-animation-gif": "'''לתשומת לבך: בשל מגבלות טכניות, תמונות ממוזערות של תמונות GIF בעלות רזולוציה גבוהה כמו זאת לא תהיינה מונפשות.'''",
+       "file-no-thumb-animation": "<strong>לתשומת לבך: בשל מגבלות טכניות, תמונות ממוזערות של הקובץ הזה לא תהיינה מונפשות.</strong>",
+       "file-no-thumb-animation-gif": "<strong>לתשומת לבך: בשל מגבלות טכניות, תמונות ממוזערות של תמונות GIF בעלות רזולוציה גבוהה כמו זאת לא תהיינה מונפשות.</strong>",
        "newimages": "גלריית קבצים חדשים",
        "imagelisttext": "להלן רשימה של {{PLURAL:$1|קובץ אחד|$1 קבצים}}, ממוינים $2:",
        "newimages-summary": "דף מיוחד זה מציג את הקבצים האחרונים שהועלו.",
-       "newimages-legend": "×\9eסנן",
+       "newimages-legend": "ס×\99× ×\95ן",
        "newimages-label": "שם הקובץ (או חלק ממנו):",
        "newimages-user": "כתובת IP או שם משתמש",
        "newimages-newbies": "הצגת תרומות של משתמשים חדשים בלבד",
        "bydate": "לפי תאריך",
        "sp-newimages-showfrom": "הצגת קבצים חדשים החל מ־$2, $1",
        "seconds-abbrev": "{{PLURAL:$1|שנייה|$1 שניות}}",
-       "minutes-abbrev": "{{PLURAL:$1|דקה|$1 דק'}}",
+       "minutes-abbrev": "{{PLURAL:$1|דקה|$1 דקות}}",
        "hours-abbrev": "{{PLURAL:$1|שעה|שעתיים|$1 שעות}}",
        "days-abbrev": "{{PLURAL:$1|יום|יומיים|$1 ימים}}",
        "seconds": "{{PLURAL:$1|שנייה|$1 שניות}}",
        "exif-colorspace": "מרחב הצבע",
        "exif-componentsconfiguration": "משמעות כל רכיב",
        "exif-compressedbitsperpixel": "שיטת דחיסת התמונה",
-       "exif-pixelxdimension": "רוחב התמונה הנכון",
-       "exif-pixelydimension": "גובה התמונה הנכון",
+       "exif-pixelxdimension": "רוחב התמונה",
+       "exif-pixelydimension": "גובה התמונה",
        "exif-usercomment": "הערות המשתמש",
        "exif-relatedsoundfile": "קובץ שמע מקושר",
        "exif-datetimeoriginal": "התאריך והשעה של יצירת הקובץ",
        "exif-subsectimedigitized": "תת־השניות של הפיכת הקובץ לדיגיטלי",
        "exif-exposuretime": "זמן חשיפה",
        "exif-exposuretime-format": "$1 שניות ($2)",
-       "exif-fnumber": "מספר F",
+       "exif-fnumber": "מספר המִפתח",
        "exif-exposureprogram": "תוכנית החשיפה",
        "exif-spectralsensitivity": "רגישות הספקטרום",
        "exif-isospeedratings": "דירוג מהירות ה־ISO",
        "exif-shutterspeedvalue": "מהירות צמצם ביחידות APEX",
        "exif-aperturevalue": "מִפתח APEX",
        "exif-brightnessvalue": "בהירות ביחידות APEX",
-       "exif-exposurebiasvalue": "נטיית החשיפה",
+       "exif-exposurebiasvalue": "נטיית החשיפה ביחידות APEX",
        "exif-maxaperturevalue": "גודל המִפתח המרבי",
        "exif-subjectdistance": "מרחק נושא הצילום",
        "exif-meteringmode": "שיטת מדידה",
        "exif-focallength-format": "{{PLURAL:$1|מילימטר אחד|$1 מילימטרים}}",
        "exif-subjectarea": "נושא האזור",
        "exif-flashenergy": "אנרגיית המַבזק",
-       "exif-focalplanexresolution": "×\9eש×\98×\97 ×\94פ×\95ק×\95ס ברזולוציה האופקית",
-       "exif-focalplaneyresolution": "×\9eש×\98×\97 ×\94פ×\95ק×\95ס ברזולוציה האנכית",
-       "exif-focalplaneresolutionunit": "×\99×\97×\99×\93ת ×\94×\9e×\99×\93×\94 ×©×\9c ×\9eש×\98×\97 ×\94פ×\95ק×\95ס ברזולוציה",
+       "exif-focalplanexresolution": "×\9eש×\98×\97 ×\94×\9e×\95ק×\93 ברזולוציה האופקית",
+       "exif-focalplaneyresolution": "×\9eש×\98×\97 ×\94×\9e×\95ק×\93 ברזולוציה האנכית",
+       "exif-focalplaneresolutionunit": "×\99×\97×\99×\93ת ×\94×\9e×\99×\93×\94 ×©×\9c ×\9eש×\98×\97 ×\94×\9e×\95ק×\93 ברזולוציה",
        "exif-subjectlocation": "נושא המיקום",
        "exif-exposureindex": "מדד החשיפה",
        "exif-sensingmethod": "שיטת חישה",
        "exif-customrendered": "עיבוד תמונה מותאם",
        "exif-exposuremode": "מצב החשיפה",
        "exif-whitebalance": "איזון צבע לבן",
-       "exif-digitalzoomratio": "×\99×\97ס ×\94×\96×\95×\9d ×\94×\93×\99×\92×\99×\98×\9c×\99",
+       "exif-digitalzoomratio": "×\99×\97ס ×\94×\94תקר×\91×\95ת ×\94×\93×\99×\92×\99×\98×\9c×\99ת",
        "exif-focallengthin35mmfilm": "אורך מוקדי העדשות בסרט צילום של 35 מ\"מ",
        "exif-scenecapturetype": "אופן צילום הסצנה",
        "exif-gaincontrol": "בקרת הסצנה",
        "exif-gpsaltituderef": "התייחסות גובה",
        "exif-gpsaltitude": "גובה",
        "exif-gpstimestamp": "זמן GPS (שעון אטומי)",
-       "exif-gpssatellites": "לוויינים ששמשו למדידה",
+       "exif-gpssatellites": "×\9c×\95×\95×\99×\99× ×\99×\9d ×©×©×\99×\9eש×\95 ×\9c×\9e×\93×\99×\93×\94",
        "exif-gpsstatus": "מעמד המקלט",
        "exif-gpsmeasuremode": "מצב מדידה",
        "exif-gpsdop": "דיוק מדידה",
        "exif-gpstrack": "מהירות התנועה",
        "exif-gpsimgdirectionref": "התייחסות לכיוון התמונה",
        "exif-gpsimgdirection": "כיוון התמונה",
-       "exif-gpsmapdatum": "מידע סקר מדידת הארץ שנעשה בו שימוש",
+       "exif-gpsmapdatum": "×\9e×\99×\93×¢ ×¢×\9c ×¡×§×¨ ×\9e×\93×\99×\93ת ×\94×\90רץ ×©× ×¢×©×\94 ×\91×\95 ×©×\99×\9e×\95ש",
        "exif-gpsdestlatituderef": "התייחסות לקו־הרוחב של היעד",
        "exif-gpsdestlatitude": "קו־הרוחב של היעד",
        "exif-gpsdestlongituderef": "התייחסות לקו־האורך של היעד",
        "exif-originalimageheight": "גובה התמונה לפני קיטוע",
        "exif-originalimagewidth": "רוחב התמונה לפני קיטוע",
        "exif-compression-1": "לא דחוס",
-       "exif-compression-2": "ק×\99×\93×\95×\93 ×\94×\95פ×\9e×\9f ×\9e×\95ת×\90×\9d ×\97×\93Ö¾×\9e×\99×\9e×\93×\99 ×\9c×\90×\95ר×\9a ×¨×\99צ×\94 CCITT ×§×\91×\95צ×\94 3",
+       "exif-compression-2": "קידוד הופמן מותאם חד־ממדי לאורך ריצה CCITT קבוצה 3",
        "exif-compression-3": "קידוד פקס CCITT קבוצה 3",
        "exif-compression-4": "קידוד פקס CCITT קבוצה 4",
        "exif-compression-6": "JPEG (ישן)",
        "exif-sensingmethod-4": "חיישן אזור בצבע עם שלושה שבבים",
        "exif-sensingmethod-5": "חיישן אזור עם צבע רציף",
        "exif-sensingmethod-7": "חיישן טריליניארי",
-       "exif-sensingmethod-8": "×\97×\99×\99ש×\9f ×¢×\9d ×¦×\91×¢ ×¨×¦×\99×£ ×\9c×\99× ×\99×\90רי",
+       "exif-sensingmethod-8": "×\97×\99×\99ש×\9f ×¢×\9d ×¦×\91×¢ ×¨×¦×\99×£ ×§×\95×\95י",
        "exif-filesource-3": "מצלמת תמונות ספרתית",
        "exif-scenetype-1": "תמונה שצולמה ישירות",
        "exif-customrendered-0": "תהליך רגיל",
        "exif-gpslatitude-s": "קו־רוחב דרומי",
        "exif-gpslongitude-e": "קו־אורך מזרחי",
        "exif-gpslongitude-w": "קו־אורך מערבי",
-       "exif-gpsaltitude-above-sealevel": "{{PLURAL:$1|×\9e×\98ר ×\90×\97ר|$1 מטרים}} מעל פני הים",
-       "exif-gpsaltitude-below-sealevel": "{{PLURAL:$1|×\9e×\98ר ×\90×\97ר|$1 מטרים}} מתחת לפני הים",
+       "exif-gpsaltitude-above-sealevel": "{{PLURAL:$1|×\9e×\98ר ×\90×\97×\93|$1 מטרים}} מעל פני הים",
+       "exif-gpsaltitude-below-sealevel": "{{PLURAL:$1|×\9e×\98ר ×\90×\97×\93|$1 מטרים}} מתחת לפני הים",
        "exif-gpsstatus-a": "מדידה בתהליך",
        "exif-gpsstatus-v": "מדידה בו־זמנית",
        "exif-gpsmeasuremode-2": "מדידה בשני ממדים",
        "exif-rating-rejected": "נדחה",
        "exif-isospeedratings-overflow": "מעל 65535",
        "exif-maxaperturevalue-value": "$1 APEX (יחידות: f/$2)",
-       "exif-iimcategory-ace": "אמנויות, תרבות ובידור",
+       "exif-iimcategory-ace": "×\90×\95×\9e× ×\95×\99×\95ת, ×ª×¨×\91×\95ת ×\95×\91×\99×\93×\95ר",
        "exif-iimcategory-clj": "פשע ומשפט",
        "exif-iimcategory-dis": "אסונות ותאונות",
        "exif-iimcategory-fin": "כלכלה ועסקים",
        "monthsall": "הכול",
        "confirmemail": "אימות כתובת דוא\"ל",
        "confirmemail_noemail": "אין לך כתובת דוא\"ל תקפה המוגדרת ב[[Special:Preferences|העדפות המשתמש]] שלך.",
-       "confirmemail_text": "{{GENDER:|עליך|עלייך|עליכם}} לאמת את כתובת הדוא\"ל {{GENDER:|שלך|שלך|שלכם}} לפני ש{{GENDER:|תוכל|תוכלי|תוכלו}} להשתמש בשירותי הדוא\"ל של {{SITENAME}}.\n{{GENDER:|לחץ|לחצי|לחצו}} על הכפתור שלמטה כדי לשלוח קוד אימות לכתובת הדוא\"ל ש{{GENDER:|הזנת|הזנת|הזנתם}}.\nההודעה {{GENDER:|שתקבל|שתקבלי|שתקבלו}} תכלול קישור שמכיל קוד;\n{{GENDER:|פתח|פתחי|פתחו}} את הקישור בדפדפן {{GENDER:|שלך|שלך|שלכם}} כדי לאשר שכתובת הדוא\"ל תקפה.",
-       "confirmemail_pending": "קוד האימות כבר נשלח לדואר האלקטרוני {{GENDER:|שלך|שלך|שלכם}};\nאם {{GENDER:|יצרת|יצרת|יצרתם}} את החשבון לאחרונה, כדאי להמתין מספר דקות עד שהדוא\"ל יגיע לפני בקשת קוד חדש.",
-       "confirmemail_send": "×\9cש×\9c×\95×\97 קוד אימות",
+       "confirmemail_text": "חובה לאמת את כתובת הדוא\"ל כדי להשתמש בשירותי הדוא\"ל של {{SITENAME}}.\nכדי לשלוח קוד אימות לכתובת הדוא\"ל שהזנת, יש ללחוץ על הכפתור שלמטה.\nהודעת הדוא\"ל שתישלח תכלול קישור שמכיל קוד;\nיש לפתוח את הקישור בדפדפן כדי לאשר שכתובת הדוא\"ל תקפה.",
+       "confirmemail_pending": "קוד האימות כבר נשלח לדואר האלקטרוני שלך;\nאם יצרת את החשבון לאחרונה, כדאי להמתין מספר דקות עד שהדוא\"ל יגיע לפני בקשת קוד חדש.",
+       "confirmemail_send": "ש×\9c×\99×\97ת קוד אימות",
        "confirmemail_sent": "הדוא\"ל עם קוד האימות נשלח.",
-       "confirmemail_oncreate": "ק×\95×\93 ×\90×\99×\9e×\95ת ×\93×\95×\90\"×\9c × ×©×\9c×\97 ×\9c×\9bת×\95×\91ת ×\94×\93×\95×\90\"×\9c ×©×\9c×\9b×\9d. ×\94ק×\95×\93 ×\94×\96×\94 ×\90×\99× ×\95 × ×\93רש ×\9c×\9b× ×\99ס×\94, ×\90×\9a ×ª×¦×\98ר×\9b×\95 לספקו כדי להשתמש בכל תכונה מבוססת דוא\"ל באתר זה.",
-       "confirmemail_sendfailed": "אתר {{SITENAME}} לא הצליח לשלוח דוא\"ל האימות שלך.\nנא לבדוק שבכתובת הדוא\"ל שלך אין תווים בלתי־תקינים.\n\nמערכת שליחת הדוא\"ל החזירה את ההודעה הבאה: $1",
-       "confirmemail_invalid": "קוד האימות שגוי. ייתכן שפג תוקפו.",
+       "confirmemail_oncreate": "ק×\95×\93 ×\90×\99×\9e×\95ת × ×©×\9c×\97 ×\9c×\9bת×\95×\91ת ×\94×\93×\95×\90\"×\9c ×©×\9c×\9a.\n×\94ק×\95×\93 ×\94×\96×\94 ×\90×\99× ×\95 × ×\93רש ×\9c×\9b× ×\99ס×\94 ×\9c×\97ש×\91×\95×\9f, ×\90×\9a ×\99×\94×\99×\94 ×¦×\95ר×\9a לספקו כדי להשתמש בכל תכונה מבוססת דוא\"ל באתר זה.",
+       "confirmemail_sendfailed": "×\90תר {{SITENAME}} ×\9c×\90 ×\94צ×\9c×\99×\97 ×\9cש×\9c×\95×\97 ×\90ת ×\93×\95×\90\"×\9c ×\94×\90×\99×\9e×\95ת ×©×\9c×\9a.\n× ×\90 ×\9c×\91×\93×\95ק ×©×\91×\9bת×\95×\91ת ×\94×\93×\95×\90\"×\9c ×©×\9c×\9a ×\90×\99×\9f ×ª×\95×\95×\99×\9d ×\91×\9cת×\99־תק×\99× ×\99×\9d.\n\n×\9eער×\9bת ×©×\9c×\99×\97ת ×\94×\93×\95×\90\"×\9c ×\94×\97×\96×\99ר×\94 ×\90ת ×\94×\94×\95×\93×¢×\94 ×\94×\91×\90×\94: $1",
+       "confirmemail_invalid": "קוד האימות שגוי.\nייתכן שפג תוקפו.",
        "confirmemail_needlogin": "נדרשת $1 כדי לאמת את כתובת הדוא\"ל שלך.",
        "confirmemail_success": "כתובת הדוא\"ל שלך אושרה.\nכעת באפשרותך [[Special:UserLogin|להיכנס לחשבון שלך]] וליהנות מהאתר.",
        "confirmemail_loggedin": "כתובת הדוא\"ל שלך אושרה כעת.",
        "confirm-unwatch-button": "אישור",
        "confirm-unwatch-top": "להסיר את הדף הזה מרשימת המעקב שלך?",
        "confirm-rollback-button": "אישור",
-       "confirm-rollback-top": "×\9cש×\97×\96×\95ר ×\90ת ×\94ש×\99× ×\95×\99×\99×\9d ×\9c×\93×£ ×\94זה?",
+       "confirm-rollback-top": "×\9cש×\97×\96ר ×\90ת ×\94ער×\99×\9b×\95ת ×\91×\93×£ זה?",
        "quotation-marks": "\"$1\"",
        "imgmultipageprev": "→ לדף הקודם",
        "imgmultipagenext": "לדף הבא ←",
        "size-exapixel": "{{PLURAL:$1|אקסה־פיקסל אחד|$1 אקסה־פיקסלים}}",
        "size-zetapixel": "{{PLURAL:$1|זטה־פיקסל אחד|$1 זטה־פיקסלים}}",
        "size-yottapixel": "{{PLURAL:$1|יוטה־פיקסל אחד|$1 יוטה־פיקסלים}}",
+       "bitrate-bits": "{{PLURAL:$1|ביט אחד|$1 ביטים}} בשנייה",
+       "bitrate-kilobits": "{{PLURAL:$1|קילו־ביט אחד|$1 קילו־ביטים}} בשנייה",
+       "bitrate-megabits": "{{PLURAL:$1|מגה־ביט אחד|$1 מגה־ביטים}} בשנייה",
+       "bitrate-gigabits": "{{PLURAL:$1|ג'יגה־ביט אחד|$1 ג'יגה־ביטים}} בשנייה",
+       "bitrate-terabits": "{{PLURAL:$1|טרה־ביט אחד|$1 טרה־ביטים}} בשנייה",
+       "bitrate-petabits": "{{PLURAL:$1|פטה־ביט אחד|$1 פטה־ביטים}} בשנייה",
+       "bitrate-exabits": "{{PLURAL:$1|אקסה־ביט אחד|$1 אקסה־ביטים}} בשנייה",
+       "bitrate-zetabits": "{{PLURAL:$1|זטה־ביט אחד|$1 זטה־ביטים}} בשנייה",
+       "bitrate-yottabits": "{{PLURAL:$1|יוטה־ביט אחד|$1 יוטה־ביטים}} בשנייה",
        "lag-warn-normal": "שינויים שבוצעו לפני פחות מ{{PLURAL:$1|שנייה אחת|־$1 שניות}} אינם מוצגים ברשימה זו.",
        "lag-warn-high": "בגלל עיכוב בעדכון בסיס הנתונים, שינויים שבוצעו לפני פחות מ{{PLURAL:$1|שנייה אחת|־$1 שניות}} אינם מוצגים ברשימה זו.",
        "watchlistedit-normal-title": "עריכת רשימת המעקב",
        "watchlistedit-normal-done": "{{PLURAL:$1|כותרת אחת הוסרה|$1 כותרות הוסרו}} מרשימת המעקב:",
        "watchlistedit-raw-title": "עריכת הרשימה הגולמית",
        "watchlistedit-raw-legend": "עריכת הרשימה הגולמית",
-       "watchlistedit-raw-explain": "×\94×\93פ×\99×\9d ×\91רש×\99×\9eת ×\94×\9eעק×\91 ×\9e×\95צ×\92×\99×\9d ×\9c×\94×\9c×\9f, ×\95× ×\99ת×\9f ×\9cער×\95×\9a ×\90×\95ת×\9d ×\91×\90×\9eצע×\95ת ×\94×\95ספ×\94 ×\95×\94סר×\94 ×©×\9c×\94×\9d ×\9e×\94רש×\99×\9e×\94;\n×\9b×\9c ×\9b×\95תרת ×\9e×\95פ×\99×¢×\94 ×\91ש×\95ר×\94 × ×¤×¨×\93ת.\n×\9c×\90×\97ר ×¡×\99×\95×\9d ×\94ער×\99×\9b×\94, ×\99ש ×\9c×\9c×\97×\95×¥ ×¢×\9c \"{{int:Watchlistedit-raw-submit}}\".\n×\91×\90פשר×\95ת×\9b×\9d גם [[Special:EditWatchlist|להשתמש בעורך הרגיל]].",
+       "watchlistedit-raw-explain": "×\94×\93פ×\99×\9d ×\91רש×\99×\9eת ×\94×\9eעק×\91 ×\9e×\95צ×\92×\99×\9d ×\9c×\94×\9c×\9f, ×\95× ×\99ת×\9f ×\9cער×\95×\9a ×\90×\95ת×\9d ×\91×\90×\9eצע×\95ת ×\94×\95ספ×\94 ×©×\9c×\94×\9d ×\9cרש×\99×\9e×\94 ×\95×\94סרת×\9d ×\9e×\9e× ×\94;\n×\9b×\9c ×\9b×\95תרת ×\9e×\95פ×\99×¢×\94 ×\91ש×\95ר×\94 × ×¤×¨×\93ת.\n×\9c×\90×\97ר ×¡×\99×\95×\9d ×\94ער×\99×\9b×\94, ×\99ש ×\9c×\9c×\97×\95×¥ ×¢×\9c \"{{int:Watchlistedit-raw-submit}}\".\n×\91×\90פשר×\95ת×\9a גם [[Special:EditWatchlist|להשתמש בעורך הרגיל]].",
        "watchlistedit-raw-titles": "דפים:",
        "watchlistedit-raw-submit": "עדכון רשימת המעקב",
        "watchlistedit-raw-done": "רשימת המעקב עודכנה.",
        "watchlisttools-raw": "עריכת רשימת המעקב הגולמית",
        "iranian-calendar-m1": "פרורדין",
        "iranian-calendar-m2": "ארדיבהשת",
-       "iranian-calendar-m3": "ח׳רדאד",
+       "iranian-calendar-m3": "ח'רדאד",
        "iranian-calendar-m4": "תיר",
        "iranian-calendar-m5": "מרדאד",
        "iranian-calendar-m6": "שהריור",
        "iranian-calendar-m7": "מהר",
        "iranian-calendar-m8": "אבאן",
-       "iranian-calendar-m9": "אד׳ר",
+       "iranian-calendar-m9": "אד'ר",
        "iranian-calendar-m10": "די",
        "iranian-calendar-m11": "בהמן",
        "iranian-calendar-m12": "אספנד",
        "passwordpolicies-policy-passwordcannotmatchusername": "הסיסמה לא יכולה להיות זהה לשם המשתמש",
        "passwordpolicies-policy-passwordcannotmatchblacklist": "הסיסמה לא יכולה להתאים לסיסמאות מסוימות שנמצאות ברשימה השחורה",
        "passwordpolicies-policy-maximalpasswordlength": "הסיסמה חייבת להיות קצרה יותר {{PLURAL:$1|מתו אחד|מ־$1 תווים}}",
-       "passwordpolicies-policy-passwordcannotbepopular": "הסיסמה לא יכולה להיות זהה {{PLURAL:$1|לסיסמה נפוצה|לאחת הסיסמאות שנמצאות ברשימה של $1 הסיסמאות הנפוצות}}"
+       "passwordpolicies-policy-passwordcannotbepopular": "הסיסמה לא יכולה להיות זהה {{PLURAL:$1|לסיסמה נפוצה|לאחת הסיסמאות שנמצאות ברשימה של $1 הסיסמאות הנפוצות}}",
+       "easydeflate-invaliddeflate": "התוכן שהועבר אינו דחוס כנדרש"
 }
index 2bf6fc3..5d11142 100644 (file)
        "customcssprotected": "आपको इस CSS पृष्ठ को संपादित करने की अनुमति नहीं है, क्योंकि इसमें अन्य सदस्य की व्यक्तिगत सेटिंग्स शामिल हैं।",
        "customjsonprotected": "आपको इस JSON पृष्ठ को संपादित करने की अनुमति नहीं है, क्योंकि इसमें अन्य सदस्य की व्यक्तिगत सेटिंग्स शामिल हैं।",
        "customjsprotected": "आपको इस जावास्क्रिप्ट पृष्ठ को संपादित करने की अनुमति नहीं है, क्योंकि इसमें अन्य सदस्य की व्यक्तिगत सेटिंग्स शामिल हैं।",
+       "sitecssprotected": "आपको इस सी.एस.एस पृष्ठ को सम्पादित करने की अनुमति नहीं है क्योंकि यह सभी प्रयोक्ताओं को प्रभावित कर सकता है।",
+       "sitejsonprotected": "आपको इस JSON पृष्ठ को सम्पादित करने की अनुमति नहीं है क्योंकि यह सभी प्रयोक्ताओं को प्रभावित कर सकता है।",
+       "sitejsprotected": "आपको इस जावास्क्रिप्ट पृष्ठ को सम्पादित करने की अनुमति नहीं है क्योंकि यह सभी प्रयोक्ताओं को प्रभावित कर सकता है।",
        "mycustomcssprotected": "आपके पास इस CSS पृष्ठ को सम्पादित करने का अधिकार नहीं है।",
        "mycustomjsonprotected": "आपके पास इस JSON पृष्ठ को सम्पादित करने का अधिकार नहीं है।",
        "mycustomjsprotected": "आपके पास इस जावास्क्रिप्ट पृष्ठ को सम्पादित करने का अधिकार नहीं है।",
        "password-login-forbidden": "इस सदस्यनाम और कूटशब्द का उपयोग वर्जित है।",
        "mailmypassword": "कूटशब्द पुनःस्थापित करें",
        "passwordremindertitle": "{{SITENAME}} के लिये नया अस्थायी कूटशब्द",
-       "passwordremindertext": "किसी ने (शायद आपने ही, $1 आइ॰पी पते से) {{SITENAME}} ($4) पर इस्तेमाल के लिये नया कूटशब्द मँगाया है। सदस्य \"$2\" के लिए एक अस्थायी कूटशब्द बना दिया गया है, और यह अभी \"$3\" है। यदि यह आपकी ही मंशा थी, तो अब आपको सत्रारंभ करके एक नया कूटशब्द चुनना होगा।\nआपके अस्थायी कूटशब्द की अवधि {{PLURAL:$5|एक दिन|$5 दिनों}} में समाप्त हो जाएगी।\n\nयदि यह अनुरोध किसी और ने किया था, या आप अपना पुराना कूटशब्द अब नहीं बदलना चाहते क्योंकि आपको अपना पुराना कूटशब्द याद आ गया है, तो आप इस संदेश को नज़रंदाज़ कर सकते हैं, और अपने पुराने कूटशब्द का पहले की तरह इस्तेमाल करते रह सकते हैं।",
+       "passwordremindertext": "किसी ने ($1 आइ॰पी पते से) {{SITENAME}} ($4) पर इस्तेमाल के लिये नया कूटशब्द मँगाया है। सदस्य \"$2\" के लिए एक अस्थायी कूटशब्द बना दिया गया है, और यह अभी \"$3\" है। यदि यह आपकी ही मंशा थी, तो अब आपको लॉग इन करके एक नया कूटशब्द चुनना होगा।\nआपके अस्थायी कूटशब्द की अवधि {{PLURAL:$5|एक दिन|$5 दिनों}} में समाप्त हो जाएगी।\n\nयदि यह अनुरोध किसी और ने किया था, या आप अपना पुराना कूटशब्द अब नहीं बदलना चाहते क्योंकि आपको अपना पुराना कूटशब्द याद आ गया है, तो आप इस संदेश को नज़रंदाज़ कर सकते हैं, और अपने पुराने कूटशब्द का पहले की तरह इस्तेमाल करते रह सकते हैं।",
        "noemail": "\"$1\" सदस्य के लिये कोई भी ई-मेल पता दर्ज नहीं किया गया है।",
        "noemailcreate": "आपको वैध ई-मेल पता देने होगा।",
        "passwordsent": "\"$1\" के ई-मेल पते पर एक नया कूटशब्द भेज दिया गया है।\nई-मेल पाने बाद कृपया दुबारा लॉग इन करें।",
        "botpasswords-existing": "वर्तमान बॉट पासवर्ड",
        "botpasswords-createnew": "बॉट के लिए नया पासवर्ड बनाएँ",
        "botpasswords-editexisting": "बॉट के वर्तमान पासवर्ड को बदलें",
+       "botpasswords-label-needsreset": "(कूटशब्द रीसेट करने की आवश्यकता है)",
        "botpasswords-label-appid": "बॉट नाम:",
        "botpasswords-label-create": "बनाएँ",
        "botpasswords-label-update": "अद्यतन",
        "botpasswords-restriction-failed": "इस प्रवेश में बॉट पासवर्ड रुकावट डाल रहा है।",
        "botpasswords-invalid-name": "जो सदस्य नाम आप बता रहे हो, उसमें बॉट पासवर्ड अलग करने वाला (\"$1\") नहीं है।",
        "botpasswords-not-exist": "सदस्य \"$1\" के आप बॉट पासवर्ड नहीं है, जिसका नाम \"$2\" है।",
+       "botpasswords-needs-reset": "{{GENDER:$1|सदस्य}} ''$1'' के बॉट नाम ''$2'' का कूटशब्द रीसेट करना पड़ेगा।",
        "resetpass_forbidden": "कूटशब्द बदले नहीं जा सकते",
        "resetpass_forbidden-reason": "पासवर्ड नहीं बदला : $1",
        "resetpass-no-info": "इस पृष्ठ का सीधे प्रयोग करने के लिए आपको लॉग इन करना होगा।",
        "resetpass-submit-loggedin": "कूटशब्द बदलें",
        "resetpass-submit-cancel": "रद्द करें",
        "resetpass-wrong-oldpass": "अस्थायी या वर्तमान कूटशब्द अवैध है।\nसंभव है कि या तो आपने पहले ही सफलतापूर्वक अपना कूटशब्द बदल लिया हो, या आपने एक नए अस्थायी कूटशब्द का अनुरोध किया हो।",
-       "resetpass-recycled": "रà¥\80सà¥\87à¤\9f à¤\95रनà¥\87 à¤\95à¥\87 à¤²à¤¿à¤\8f à¤¨à¤¯à¥\87 à¤ªà¤¾à¤¸à¤µà¤°à¥\8dड à¤®à¥\87à¤\82 à¤\95à¥\83पया à¤\85पनà¥\87 à¤µà¤°à¥\8dतमान à¤ªà¤¾à¤¸à¤µà¤°à¥\8dड à¤\95à¥\87 à¤\85लावा à¤\95िसà¥\80 à¤\85नà¥\8dय à¤ªà¤¾à¤¸à¤µà¤°à¥\8dड à¤\95ा à¤ªà¥\8dरयà¥\8bà¤\97 à¤\95रà¥\87à¤\82।",
+       "resetpass-recycled": "अपने वर्तमान पासवर्ड के अलावा किसी अन्य पासवर्ड का प्रयोग करें।",
        "resetpass-temp-emailed": "आपने एक अस्थायी ईमेल किये गये कोड के साथ लॉग इन किया।\nलॉग इन सम्पूर्ण करने के लिए आपको यहाँ एक नया पासवर्ड सेट करना होगा:",
        "resetpass-temp-password": "अस्थायी कूटशब्द:",
        "resetpass-abort-generic": "कूटशब्द में बदलाव किसी एक्सटेंशन द्वारा रोक दिया गया है।",
        "resetpass-expired": "आपके पासवर्ड की वैधता अवधि समाप्त हो चुकी है। कृपया लॉग इन करने के लिए एक नया पासवर्ड सेट करें।",
-       "resetpass-expired-soft": "à¤\86पà¤\95ा à¤ªà¤¾à¤¸à¤µà¤°à¥\8dड à¤\95à¥\80 à¤µà¥\88धता à¤\85वधि à¤¸à¤®à¤¾à¤ªà¥\8dत à¤¹à¥\8b à¤\97यà¥\80 à¤¹à¥\88 à¤\94र à¤\89सà¥\87 à¤°à¥\80सà¥\87à¤\9f à¤\95रनà¥\87 à¤\95à¥\80 à¤\9c़रà¥\82रत à¤¹à¥\88। à¤\95à¥\83पया à¤\8fà¤\95 à¤¨à¤¯à¤¾ à¤ªà¤¾à¤¸à¤µà¤°à¥\8dड à¤\9aà¥\81नà¥\87à¤\82, à¤¯à¤¾ à¤¬à¤¾à¤¦ à¤®à¥\87à¤\82 à¤°à¥\80सà¥\87à¤\9f à¤\95रने के लिए \"{{int:authprovider-resetpass-skip-label}}\" पर क्लिक करें।",
-       "resetpass-validity-soft": "à¤\86पà¤\95ा à¤ªà¤¾à¤¸à¤µà¤°à¥\8dड à¤®à¤¾à¤¨à¥\8dय à¤¨à¤¹à¥\80à¤\82 à¤¹à¥\88: $1 \n\nà¤\95à¥\83पया à¤\85ब à¤\8fà¤\95 à¤¨à¤¯à¤¾ à¤ªà¤¾à¤¸à¤µà¤°à¥\8dड à¤\9aà¥\81नà¥\87à¤\82, à¤¯à¤¾ à¤\89सà¥\87 à¤¬à¤¾à¤¦ à¤®à¥\87à¤\82 à¤ªà¥\81नरà¥\8dसà¥\8dथापित à¤\95रने के लिए \"{{int:authprovider-resetpass-skip-label}}\" पर क्लिक करें।",
+       "resetpass-expired-soft": "à¤\86पà¤\95ा à¤ªà¤¾à¤¸à¤µà¤°à¥\8dड à¤\95à¥\80 à¤µà¥\88धता à¤\85वधि à¤¸à¤®à¤¾à¤ªà¥\8dत à¤¹à¥\8b à¤\97यà¥\80 à¤¹à¥\88 à¤\94र à¤\89सà¥\87 à¤¬à¤¦à¤²à¤¨à¥\87 à¤\95à¥\80 à¤\9c़रà¥\82रत à¤¹à¥\88। à¤\95à¥\83पया à¤\8fà¤\95 à¤¨à¤¯à¤¾ à¤ªà¤¾à¤¸à¤µà¤°à¥\8dड à¤\9aà¥\81नà¥\87à¤\82, à¤¯à¤¾ à¤¬à¤¾à¤¦ à¤®à¥\87à¤\82 à¤¬à¤¦à¤²ने के लिए \"{{int:authprovider-resetpass-skip-label}}\" पर क्लिक करें।",
+       "resetpass-validity-soft": "à¤\86पà¤\95ा à¤ªà¤¾à¤¸à¤µà¤°à¥\8dड à¤®à¤¾à¤¨à¥\8dय à¤¨à¤¹à¥\80à¤\82 à¤¹à¥\88: $1 \n\nà¤\95à¥\83पया à¤¨à¤¯à¤¾ à¤ªà¤¾à¤¸à¤µà¤°à¥\8dड à¤\9aà¥\81नà¥\87à¤\82, à¤¯à¤¾ à¤¬à¤¾à¤¦ à¤®à¥\87à¤\82 à¤¬à¤¦à¤²ने के लिए \"{{int:authprovider-resetpass-skip-label}}\" पर क्लिक करें।",
        "passwordreset": "कूटशब्द रीसेट",
        "passwordreset-text-one": "अपना कूटशब्द रीसेट करने के लिए यह फ़ॉर्म भरें।",
        "passwordreset-text-many": "{{PLURAL:$1|ईमेल के माध्यम से एक अस्थायी पासवर्ड प्राप्त करने के लिए कोई एक डिब्बा भरें।}}",
        "subject-preview": "विषय की झलक:",
        "previewerrortext": "आपके परिवर्तनों का पूर्वावलोकन करने का प्रयास करते समय एक त्रुटि हुई।",
        "blockedtitle": "सदस्य अवरुद्ध है",
-       "blockedtext": "'''आपका सदस्यनाम अथवा आइ॰पी पता अवरोधित कर दिया गया हैं ।'''\n\nअवरोध $1 द्वारा किया गया था।\nअवरोध का कारण है ''$2''\n\n* अवरोध का आरंभ: $8\n* अवरोध की समाप्ति: $6\n* अवरोधित इकाई: $7\n\nइस अवरोध के बारे में चर्चा करने के लिए आप $1 या किसी अन्य [[{{MediaWiki:Grouppage-sysop}}|प्रबन्धक]] से संपर्क कर सकते हैं।\nअगर आपने [[Special:Preferences|अपनी वरीयताओं]] में वैध ई-मेल पता प्रविष्ट किया है तो ही आप 'इस प्रयोक्ता को ई-मेल भेजें' वाली सुविधा का इस्तेमाल कर सकते हैं और आपको इसका इस्तेमाल करने से नहीं रोका गया है।\nआपका मौजूदा आइ॰पी पता $3 है और अवरोध क्रमांक #$5 है।\nअपने किसी भी प्रश्न में कृपया यह सभी जानकारी भी शामिल करें।",
-       "autoblockedtext": "एक और सदस्य आपके ही आइ॰पी का प्रयोग कर रहे थे और उन्हें $1 द्वारा अवरोधित कर दिया गया था। फलस्वरूप आपका आइ॰पी पता भी स्वचालित रूप से अवरोधित हो गया है।\nअवरोध करने का कारण है:\n\n:''$2''\n\n* अवरोध प्रारंभ: $8\n* अवरोध समाप्ति: $6\n* अवरोधित सदस्य: $7\n\nअवरोध की चर्चा करने के लिए आप $1 या किसी अन्य [[{{MediaWiki:Grouppage-sysop}}|प्रबंधक]] से संपर्क कर सकते हैं।\n\nकृपया ध्यान दें कि यदि आपक \"इस सदस्य को ई-मेल भेजें\" वाली सुविधा का प्रयोग करना चाहते हैं तो आपकी [[Special:Preferences|वरीयताओं]] में वैध ई-मेल पता होना चाहिए और इसका प्रयोग आपके लिए अवरोधित नहीं होना चाहिए।\n\nआपका मौजूदा आइ॰पी पता $3 है और अवरोध क्रमांक #$5 है।\nअपने किसी भी प्रश्न में कृपया यह सभी जानकारी भी शामिल करें।",
+       "blockedtext": "<strong>आपका सदस्यनाम अथवा आइ॰पी पता अवरोधित कर दिया गया हैं ।</strong>\n\nअवरोध $1 द्वारा किया गया था।\nअवरोध का कारण है <em>$2</em>\n\n* अवरोध का आरंभ: $8\n* अवरोध की समाप्ति: $6\n* अवरोधित इकाई: $7\n\nइस अवरोध के बारे में चर्चा करने के लिए आप $1 या किसी अन्य [[{{MediaWiki:Grouppage-sysop}}|प्रबन्धक]] से संपर्क कर सकते हैं।\nअगर आपने [[Special:Preferences|अपनी वरीयताओं]] में वैध ई-मेल पता प्रविष्ट किया है तो ही आप {{int:emailuser}} सुविधा का इस्तेमाल कर सकते हैं और आपको इसका इस्तेमाल करने से नहीं रोका गया है।\nआपका मौजूदा आइ॰पी पता $3 है और अवरोध क्रमांक #$5 है।\nअपने किसी भी प्रश्न में कृपया यह सभी जानकारी भी शामिल करें।",
+       "autoblockedtext": "एक और सदस्य आपके ही आइ॰पी का प्रयोग कर रहे थे और उन्हें $1 द्वारा अवरोधित कर दिया गया था। फलस्वरूप आपका आइ॰पी पता भी स्वचालित रूप से अवरोधित हो गया है।\nअवरोध करने का कारण है:\n\n:<em>$2</em>\n\n* अवरोध प्रारंभ: $8\n* अवरोध समाप्ति: $6\n* अवरोधित सदस्य: $7\n\nअवरोध की चर्चा करने के लिए आप $1 या किसी अन्य [[{{MediaWiki:Grouppage-sysop}}|प्रबंधक]] से संपर्क कर सकते हैं।\n\nकृपया ध्यान दें कि यदि आपक \"{{int:emailuser}}\" सुविधा का प्रयोग करना चाहते हैं तो आपकी [[Special:Preferences|वरीयताओं]] में वैध ई-मेल पता होना चाहिए और इसका प्रयोग आपके लिए अवरोधित नहीं होना चाहिए।\n\nआपका मौजूदा आइ॰पी पता $3 है और अवरोध क्रमांक #$5 है।\nअपने किसी भी प्रश्न में कृपया यह सभी जानकारी भी शामिल करें।",
        "systemblockedtext": "आपका यूज़र नेम या आईपी का पता स्वचालित रूप से MediaWiki द्वारा अवरुद्ध कर दिया गया है।\nकारण दिया है:\n:<em>$2</em>\n\n* ब्लॉक का प्रारंभ: $8\n* ब्लॉक की समय सीमा समाप्त: $6\n* इरादा : $7\n\nआपका वर्तमान आईपी पता $3 है।\nआप किसी भी प्रश्न में सभी जानकारी भी शामिल करें।",
        "blockednoreason": "कोई कारण नहीं दिया है",
        "whitelistedittext": "पृष्ठ संपादित करने के लिये आपको $1 करना होगा।",
        "userjsonyoucanpreview": "<strong>टिप:</strong> संजोने से पहले अपनी नई JSON को जाँचने के लिये \"{{int:showpreview}}\" बटन का प्रयोग करें।",
        "userjsyoucanpreview": "'''टिप''': संजोने से पहले अपनी नई जावास्क्रिप्ट को जाँचने के लिये \"{{int:showpreview}}\" बटन का प्रयोग करें।",
        "usercsspreview": "'''ध्यान दें कि आप अपनी सी॰एस॰एस की झलक देख रहे हैं।'''\n'''यह अभी तक संजोई नहीं गई है!'''",
+       "userjsonpreview": "<strong>ध्यान दें कि आप अपनी सदस्य JSON कॉन्फिग की झलक देख रहे हैं।\nयह अभी तक संजोई नहीं गई है!</strong>",
        "userjspreview": "'''ध्यान दें कि आप अपनी जावास्क्रिप्ट की झलक देख रहे हैं।'''\n'''यह अभी तक संजोई नहीं गई है!'''",
        "sitecsspreview": "''''ध्यान दें कि आप इस सी॰एस॰एस की झलक देख रहे हैं।'''\n'''यह अभी तक संजोई नहीं गई है!'''",
+       "sitejsonpreview": "<strong>ध्यान दें कि आप इस JSON कॉन्फिग की झलक देख रहे हैं।\nयह अभी तक संजोई नहीं गई है!</strong>",
        "sitejspreview": "'''ध्यान दें कि आप इस जावास्क्रिप्ट कोड की झलक देख रहे हैं।'''\n'''यह अभी तक संजोया नहीं गया है!'''",
        "userinvalidconfigtitle": "'''चेतावनी:''' \"$1\" नाम की कोई त्वचा नहीं है।\nबदले हुए .css और .js पृष्ठों के शीर्षक नीचे स्तर की लिपि (lowercase) का प्रयोग करते हैं। उदाहरण: {{ns:user}}:Foo/vector.css न की {{ns:user}}:Foo/Vector.css",
        "updated": "(अद्यतनीत)",
        "whatlinkshere": "यहाँ क्या जुड़ता है",
        "whatlinkshere-title": "$1 से जुड़े हुए पृष्ठ",
        "whatlinkshere-page": "पृष्ठ:",
-       "linkshere-2": "नीचे दिये हुए पृष्ठ '''$1''' से जुडते हैं:",
-       "nolinkshere-2": "<strong>$1</strong> से कोई भी पन्ना नहीं जुड़ा है।",
-       "nolinkshere-ns-2": "चुने हुए नामस्थानसे '''$1''' को जुडने वाले पृष्ठ नहीं हैं।",
+       "linkshere": "नीचे दिये हुए पृष्ठ '''$2''' से जुडते हैं:",
+       "nolinkshere": "<strong>$2</strong> से कोई भी पन्ना नहीं जुड़ा है।",
+       "nolinkshere-ns": "चुने हुए नामस्थानसे '''$2''' को जुडने वाले पृष्ठ नहीं हैं।",
        "isredirect": "पुनर्निर्देशन पृष्ठ",
        "istemplate": "मिलाईयें",
        "isimage": "फ़ाइल प्रयोग",
        "markedaspatrollederrornotify": "जाँचा हुआ चिन्हित करना असफल रहा।",
        "patrol-log-page": "परीक्षण लॉग",
        "patrol-log-header": "यह परीक्षित अवतरणों की लॉग है।",
-       "log-show-hide-patrol": "परीक्षण लॉग $1",
-       "log-show-hide-tag": "$1 टैग लॉग",
        "confirm-markpatrolled-button": "ठीक है",
        "confirm-markpatrolled-top": "$2 के $3 संशोधन को परीक्षित चिन्ह्नत करे?",
        "deletedrevision": "पुराना अवतरण $1 हटा दिया",
        "pagedata-title": "पृष्ठ आँकड़े",
        "pagedata-text": "यह पृष्ठ पृष्ठों के लिए एक डेटा इंटरफ़ेस प्रदान करता है। कृपया उपपृष्ठ सिंटैक्स का उपयोग करके यूआरएल में पेज शीर्षक प्रदान करें।\n* कन्टैंट वार्ता आपके क्लाइंट के एसेडर हेडर के आधार पर लागू होती है। इसका मतलब यह है कि पेज डेटा को आपके क्लाइंट द्वारा पसंदीदा प्रारूप में प्रदान किया जाएगा।",
        "pagedata-not-acceptable": "कोई अनुकूल प्रारूप नहीं मिला। सुमेलित ऍमआइऍमई प्रकार: $1",
-       "pagedata-bad-title": "अमान्य शीर्षक: $1"
+       "pagedata-bad-title": "अमान्य शीर्षक: $1",
+       "passwordpolicies-group": "समूह",
+       "passwordpolicies-policies": "पॉलिसी",
+       "passwordpolicies-policy-minimalpasswordlength": "आपका कूटशब्द कम से कम {{PLURAL:$1|1 कैरेक्टर|$1 कैरेक्टरों}} का होना चाहिये।"
 }
index b215c80..bce4509 100644 (file)
        "whatlinkshere": "Hian konchij jurre hae",
        "whatlinkshere-title": "Panna jon ki $1 se jurre hai",
        "whatlinkshere-page": "Panna:",
-       "linkshere-2": "Niche waala panna '''$1''' se jorre hai:",
-       "nolinkshere-2": "Koi panna '''$1''' ke nai jorre hai.",
-       "nolinkshere-ns-2": "Chuna gais namespace me koi panna '''$1''' se nai jiurre hai.",
+       "linkshere": "Niche waala panna '''$2''' se jorre hai:",
+       "nolinkshere": "Koi panna '''$2''' ke nai jorre hai.",
+       "nolinkshere-ns": "Chuna gais namespace me koi panna '''$2''' se nai jiurre hai.",
        "isredirect": "panna ke redirect karo",
        "istemplate": "milao",
        "isimage": "file ke jorr",
        "markedaspatrollederrornotify": "Patrolled mark kare ke kosis fail hoe gais hae.",
        "patrol-log-page": "Pahraa de waala suchi",
        "patrol-log-header": "Ii pahraa dewa gais badlao ke suchi hai.",
-       "log-show-hide-patrol": "$1 pahraa de waala suchi",
-       "log-show-hide-tag": "$1 tag log",
        "confirm-markpatrolled-button": "OK",
        "confirm-markpatrolled-top": "Mark karo ki ii revision $3 of $2 patrolled hai?",
        "deletedrevision": "Purana badlao ke mitae dia hai $1",
index 7de08f0..ade51d1 100644 (file)
        "whatlinkshere": "Ang nagatabid diri",
        "whatlinkshere-title": "Mga pahina nga naga tabid sa $1",
        "whatlinkshere-page": "Pahina:",
-       "linkshere-2": "Ang mga sumunod nga pahina ay nagatabid sa '''$1''':",
-       "nolinkshere-2": "Waay panid nga nakasugpon sa '''$1'''.",
+       "linkshere": "Ang mga sumunod nga pahina ay nagatabid sa '''$2''':",
+       "nolinkshere": "Waay panid nga nakasugpon sa '''$2'''.",
        "isredirect": "pahina sa ginadirekta liwat",
        "istemplate": "transklusyon",
        "isimage": "Ang sugpon sang file",
index def7267..938791d 100644 (file)
@@ -38,7 +38,9 @@
                        "Сербијана",
                        "Wumbolo",
                        "Fitoschido",
-                       "Hamster"
+                       "Hamster",
+                       "BadDog",
+                       "Vlad5250"
                ]
        },
        "tog-underline": "Podcrtavanje poveznica",
        "prefs-dateformat": "Format datuma",
        "prefs-timeoffset": "Vremensko poravnavanje",
        "prefs-advancedediting": "Napredne mogućnosti",
+       "prefs-developertools": "Razvijateljski alati",
        "prefs-editor": "Uređivač",
        "prefs-preview": "Prikaži kako će izgledati",
        "prefs-advancedrc": "Napredne mogućnosti",
        "group-autoconfirmed": "Automatski potvrđeni suradnici",
        "group-bot": "Botovi",
        "group-sysop": "Administratori",
+       "group-interface-admin": "Administratori sučelja",
        "group-bureaucrat": "Birokrati",
        "group-suppress": "Otajnici",
        "group-all": "(svi)",
        "group-user-member": "{{GENDER:$1|suradnik|suradnica}}",
-       "group-autoconfirmed-member": "{{GENDER:$1|automatski potvrđen suradnik|automatski potvrđena suradnica}}",
+       "group-autoconfirmed-member": "{{GENDER:$1|automatski potvrđeni suradnik|automatski potvrđena suradnica}}",
        "group-bot-member": "{{GENDER:$1|bot}}",
        "group-sysop-member": "{{GENDER:$1|administrator|administratorica}}",
+       "group-interface-admin-member": "{{GENDER:$1|administrator sučelja|administratorica sučelja}}",
        "group-bureaucrat-member": "{{GENDER:$1|birokrat|birokratica}}",
        "group-suppress-member": "{{GENDER:$1|otajnik|otajnica}}",
        "grouppage-user": "{{ns:project}}:Suradnici",
        "grouppage-autoconfirmed": "{{ns:project}}:automatski potvrđeni suradnici",
        "grouppage-bot": "{{ns:project}}:Botovi",
        "grouppage-sysop": "{{ns:project}}:Administratori",
+       "grouppage-interface-admin": "{{ns:project}}:Administratori sučelja",
        "grouppage-bureaucrat": "{{ns:project}}:Birokrati",
        "grouppage-suppress": "{{ns:project}}:Otajnost",
        "right-read": "Čitanje stranica",
        "right-editcontentmodel": "Odredi modela sadržaja stranice",
        "right-editinterface": "Uređivanje suradničkog sučelja",
        "right-editusercss": "Uređivanje CSS stranica drugih suradnika",
+       "right-edituserjson": "Uređivanje JSON stranica drugih suradnika",
        "right-edituserjs": "Uređivanje JS stranica drugih suradnika",
        "right-editmyusercss": "Uređivanje vlastitih CSS stranica",
+       "right-editmyuserjson": "Uređivanje vlastitih JSON stranica",
        "right-editmyuserjs": "Uređivanje vlastitih JavaScript stranica",
        "right-viewmywatchlist": "Pregled svojeg popisa praćenih stranica",
        "right-editmywatchlist": "Uređivanje vlastitog popisa praćenja. Određenim djelovanjima moguće je dodavati stranice i bez ovoga dopuštenja.",
        "rcfilters-other-review-tools": "Ostali alati za pregledavanje:",
        "rcfilters-group-results-by-page": "Grupiranje rezultata po stranici",
        "rcfilters-activefilters": "Aktivni filtri",
+       "rcfilters-activefilters-hide": "Skrij",
+       "rcfilters-activefilters-show": "Pokaži",
        "rcfilters-advancedfilters": "Napredni filtri",
        "rcfilters-limit-title": "Rezultata za prikaz",
        "rcfilters-limit-and-date-label": "{{PLURAL:$1|$1 izmjena|$1 izmjene|$1 izmjena}}, $2",
        "rcfilters-liveupdates-button-title-off": "Prikaži nove izmjene uživo",
        "rcfilters-watchlist-markseen-button": "Označi sve izmjene kao pregledane",
        "rcfilters-watchlist-edit-watchlist-button": "Izmijeni popis praćenih stranica",
+       "rcfilters-watchlist-showupdated": "Izmjene na stranicama koje niste posjetili otkako su se izmjene dogodile istaknute su <strong>podebljanim slovima</strong>, s ispunjenim kružićima.",
        "rcfilters-preference-label": "Skrij poboljšanu inačicu nedavnih promjena",
        "rcfilters-preference-help": "Vraća natrag stanje prije redizajna sučelja 2017., te svih oruđa dodanih tada i poslije toga.",
+       "rcfilters-watchlist-preference-label": "Sakrij poboljšanu inačicu popisa praćenja",
+       "rcfilters-watchlist-preference-help": "Vraća natrag stanje prije redizajna sučelja 2017., te svih oruđa dodanih tada i poslije toga.",
        "rcnotefrom": "Ispod {{PLURAL:$5|je izmjena|su izmjene}} od <strong>$3, $4</strong> (prikazano ih do <strong>$1</strong>).",
        "rclistfromreset": "Vrati na zadano izbor datuma",
        "rclistfrom": "Prikaži nove promjene počevši od $3 $2",
        "protectedtitles-submit": "Prikaži nazive",
        "listusers": "Popis suradnika",
        "listusers-editsonly": "Prikaži samo suradnike s uređivanjem",
+       "listusers-temporarygroupsonly": "Pokaži samo suradnike u privremenim suradničkim skupinama",
        "listusers-creationsort": "Razvrstaj po datumu stvaranja",
        "listusers-desc": "Sortiraj obrnutim redoslijedom",
        "usereditcount": "$1 {{PLURAL:$1|uređivanje|uređivanja|uređivanja}}",
        "magiclink-tracking-pmid-desc": "Ova stranica rabi čarobne PMID poveznice. Za njihovu migraciju vidi [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org].",
        "magiclink-tracking-isbn": "Stranice s čarobnim ISBN poveznicama",
        "magiclink-tracking-isbn-desc": "Ova stranica rabi čarobne ISBN poveznice. Za njihovu migraciju vidi [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org].",
-       "specialloguserlabel": "Suradnik:",
-       "speciallogtitlelabel": "Cilj (naslov ili {{ns:user}}:suradničko ime):",
+       "specialloguserlabel": "Izvršitelj:",
+       "speciallogtitlelabel": "Cilj (naslov ili {{ns:user}}:suradničko ime za suradnika):",
        "log": "Evidencije",
        "logeventslist-submit": "Prikaži",
+       "logeventslist-more-filters": "Prikaži dodatne evidencije:",
+       "logeventslist-patrol-log": "Evidencija ophodnje",
+       "logeventslist-tag-log": "Evidencija oznaka",
        "all-logs-page": "Sve javne evidencije",
        "alllogstext": "Skupni prikaz svih dostupnih evidencija projekta {{SITENAME}}.\nMožete suziti prikaz odabirući tip evidencije, suradničko ime ili stranicu u upitu.",
        "logempty": "Nema pronađenih stavki u evidenciji.",
        "dellogpage": "Evidencija brisanja",
        "dellogpagetext": "Dolje je popis nedavnih brisanja.\nSva vremena su prema poslužiteljevom vremenu.",
        "deletionlog": "evidencija brisanja",
+       "log-name-create": "Evidencija stvaranja stranica",
+       "logentry-create-create": "$1 {{GENDER:$2|stvorio|stvorila}} je stranicu $3",
        "reverted": "Vraćeno na prijašnju inačicu",
        "deletecomment": "Razlog:",
        "deleteotherreason": "Drugi/dodatni razlog:",
        "uctop": "(vrh)",
        "month": "Od mjeseca (i ranije):",
        "year": "Od godine (i ranije):",
+       "date": "Do nadnevka (i prije):",
        "sp-contributions-newbies": "Prikaži samo doprinose novih suradnika",
        "sp-contributions-newbies-sub": "Za nove suradnike",
        "sp-contributions-newbies-title": "Doprinosi novih suradnika",
        "whatlinkshere": "Što vodi ovamo",
        "whatlinkshere-title": "Stranice koje vode na »$1«",
        "whatlinkshere-page": "Stranica:",
-       "linkshere-2": "Sljedeće stranice povezuju ovamo ($1):",
-       "nolinkshere-2": "Nijedna stranica ne vodi ovamo (tj. nema poveznica na stranicu $1).",
-       "nolinkshere-ns-2": "Nijedna stranica ne vodi na '''$1''' u odabranom imenskom prostoru.",
+       "linkshere": "Sljedeće stranice povezuju ovamo ($2):",
+       "nolinkshere": "Nijedna stranica ne vodi ovamo (tj. nema poveznica na stranicu $2).",
+       "nolinkshere-ns": "Nijedna stranica ne vodi na '''$2''' u odabranom imenskom prostoru.",
        "isredirect": "stranica za preusmjeravanje",
        "istemplate": "kao predložak",
        "isimage": "poveznica na datoteku",
        "allmessagesname": "Ime",
        "allmessagesdefault": "Prvotni tekst",
        "allmessagescurrent": "Trenutačni tekst",
-       "allmessagestext": "Ovo je popis svih sistemskih poruka u imenskom prostoru MediaWiki. Molimo posjetite [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation lokalizaciju MediaWikija] i [https://translatewiki.net translatewiki.net] ako želite doprinijeti lokalizaciji MediaWiki softvera.",
+       "allmessagestext": "Ovo je popis sistemskih poruka u imenskom prostoru MediaWiki. Molimo posjetite [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation lokalizaciju MediaWikija] i [https://translatewiki.net translatewiki.net] ako želite doprinijeti lokalizaciji MediaWiki softvera.",
        "allmessagesnotsupportedDB": "Ova stranica ne može biti korištena jer je isključen parametar '''$wgUseDatabaseMessages'''.",
        "allmessages-filter-legend": "Filtriraj",
        "allmessages-filter": "Filtriraj prema prilagođenom obliku:",
        "markedaspatrollederrornotify": "Označavanje stranice pregledanom nije uspjelo.",
        "patrol-log-page": "Evidencija ophodnji i samoophodnji",
        "patrol-log-header": "Ovo su evidencije ophođenih izmjena.",
-       "log-show-hide-patrol": "$1 evidenciju ophodnji",
-       "log-show-hide-tag": "$1 evidenciju oznaka",
        "confirm-markpatrolled-button": "U redu",
        "confirm-markpatrolled-top": "Označiti izmjenu $3 stranice $2 pregledanom?",
        "deletedrevision": "izbrisana stara inačica $1",
        "lag-warn-normal": "Promjene načinjene prije manje od $1 {{PLURAL:$1|sekunde|sekundi}} možda ne će biti prikazane na ovom popisu.",
        "lag-warn-high": "Zbog preopterećenosti poslužitelja na kom je baza podataka, izmjene novije od $1 {{PLURAL:$1|sekunde|sekundi}} možda ne će biti prikazane na ovom popisu.",
        "watchlistedit-normal-title": "Uredi popis praćenja",
-       "watchlistedit-normal-legend": "Ukloni stranice iz popisa praćenja",
+       "watchlistedit-normal-legend": "Uklanjanje naslova s popisa praćenja",
        "watchlistedit-normal-explain": "Prikazane su stranice na Vašem popisu praćenja.\nDa uklonite stranicu s popisa praćenja, označite kućicu kraj nje i kliknite gumb \"{{int:Watchlistedit-normal-submit}}\".\nMožete također [[Special:EditWatchlist/raw|uređivati ovaj popis u okviru za uređivanje]].",
        "watchlistedit-normal-submit": "Ukloni stranice",
        "watchlistedit-normal-done": "{{PLURAL:$1|1 stranica je uklonjena|$1 stranice su uklonjene|$1 stranica je uklonjeno}} iz Vašeg popisa praćenja:",
        "revdelete-unrestricted": "uklonjeno ograničenje za administratore",
        "logentry-block-block": "$1 {{GENDER:$2|blokirao|blokirala}} je {{GENDER:$4|$3}} na rok od $5 $6",
        "logentry-block-unblock": "$1 {{GENDER:$2|odblokirao|odblokirala}} je {{GENDER:$4|$3}}",
-       "logentry-block-reblock": "$1 {{GENDER:$2|promijenio|promijenila}} je postavke blokiranja {{GENDER:$4|suradnika|suradnice}} {{GENDER:$4|$3}} s krajnjim rokom koji ističe $5 $6",
+       "logentry-block-reblock": "$1 {{GENDER:$2|promijenio|promijenila}} je postavke blokiranja {{GENDER:$4|suradnika|suradnice}} {{GENDER:$4|$3}} s krajnjim rokom koji istječe $5 $6",
        "logentry-suppress-block": "$1 {{GENDER:$2|blokirao|blokirala}} je {{GENDER:$4|$3}} s krajnjim rokom koji ističe $5 $6",
        "logentry-suppress-reblock": "$1 {{GENDER:$2|promijenio|promijenila}} je postavke blokiranja {{GENDER:$4|suradnika|suradnice}} {{GENDER:$4|$3}} s krajnjim rokom koji ističe $5 $6",
        "logentry-import-interwiki": "$1 {{GENDER:$2|uvezao|uvezla}} je $3 s drugog wikija",
        "gotointerwiki-invalid": "Navedeni naslov nije valjan.",
        "gotointerwiki-external": "Napuštate projekt {{SITENAME}} da biste posjetili zasebno mrežno mjesto [[$2]].\n\n<strong>[$1 Nastavljate na $1]</strong>",
        "pagedata-title": "Podatci o stranici",
-       "pagedata-bad-title": "Naslov nije valjan: $1."
+       "pagedata-bad-title": "Naslov nije valjan: $1.",
+       "passwordpolicies": "Pravila za zaporke",
+       "passwordpolicies-summary": "Ovo je popis pravila za zaporke za suradničke grupe definirane na ovom wikiju.",
+       "passwordpolicies-policy-minimalpasswordlength": "Zaporka mora sadržavati najmanje {{PLURAL:$1|1 znak|$1 znaka|$1 znakova}}",
+       "passwordpolicies-policy-minimumpasswordlengthtologin": "Da biste se prijavili, zaporka mora sadržavati najmanje {{PLURAL:$1|1 znak|$1 znaka|$1 znakova}}",
+       "passwordpolicies-policy-passwordcannotmatchusername": "Zaporka ne može biti ista kao i suradničko ime",
+       "passwordpolicies-policy-passwordcannotmatchblacklist": "Zaporka se ne može podudarati sa zaporkama na crnoj listi",
+       "passwordpolicies-policy-maximalpasswordlength": "Zaporka mora biti kraća od {{PLURAL:$1|1 znaka|$1 znaka|$1 znakova}}"
 }
index 88774fd..8b28e9f 100644 (file)
        "whatlinkshere": "Links uff die Seit",
        "whatlinkshere-title": "Seite, die uff \"$1\" verlinke",
        "whatlinkshere-page": "Seit:",
-       "linkshere-2": "Die follichende Seite verlinke uff '''\"$1\"''':",
-       "nolinkshere-2": "Ken Seit verlinkt uff '''„$1“'''.",
-       "nolinkshere-ns-2": "Ken Seit verlinkt uff '''\"$1\"''' im gewählte Noomeraum.",
+       "linkshere": "Die follichende Seite verlinke uff '''\"$2\"''':",
+       "nolinkshere": "Ken Seit verlinkt uff '''„$2“'''.",
+       "nolinkshere-ns": "Ken Seit verlinkt uff '''\"$2\"''' im gewählte Noomeraum.",
        "isredirect": "Weiterleitungsseit",
        "istemplate": "Voarlooche-einbinnunge (transclusões)",
        "isimage": "Dateilink",
        "markedaspatrollederrornotify": "Der Versuch, die Version als wie kontrolliert se markiere, ist fehlgeschlooht.",
        "patrol-log-page": "Kontroll-Logbuch",
        "patrol-log-header": "Das ist das Kontroll-Logbuch.",
-       "log-show-hide-patrol": "Kontroll-Logbuch $1",
        "deletedrevision": "alte Version $1 abgewischt",
        "filedeleteerror-short": "Fehler bei Datei-Abwäsch: $1",
        "filedeleteerror-long": "Bei der Datei-Abwischung woorre Fehler festgestellt:\n\n$1",
index 735e55e..f979761 100644 (file)
        "whatlinkshere": "Što wotkazuje sem",
        "whatlinkshere-title": "Strony, kotrež na „$1“ wotkazuja",
        "whatlinkshere-page": "Strona:",
-       "linkshere-2": "Sćěhowace strony na stronu '''$1''' wotkazuja:",
-       "nolinkshere-2": "Žane strony na '''$1''' njewotkazuja.",
-       "nolinkshere-ns-2": "Žane strony njewotkazuja na '''$1''' we wubranym mjenowym rumje.",
+       "linkshere": "Sćěhowace strony na stronu '''$2''' wotkazuja:",
+       "nolinkshere": "Žane strony na '''$2''' njewotkazuja.",
+       "nolinkshere-ns": "Žane strony njewotkazuja na '''$2''' we wubranym mjenowym rumje.",
        "isredirect": "daleposrědkowanje",
        "istemplate": "zapřijeće předłohi",
        "isimage": "Datajowy wotkaz",
        "markedaspatrollederrornotify": "Markěrowanje jako dohladowane je so njeporadźiło.",
        "patrol-log-page": "Protokol přepruwowanjow",
        "patrol-log-header": "To je protokol dohladowanych wersijow.",
-       "log-show-hide-patrol": "Protokol dohladowanja $1",
-       "log-show-hide-tag": "Protokol markěrowanjow $1",
        "confirm-markpatrolled-button": "W porjadku",
        "confirm-markpatrolled-top": "Wersiju $3 strony $2 jako přehladowanu markěrować?",
        "deletedrevision": "Stara wersija $1 wušmórnjena",
index 04d5473..5769b9f 100644 (file)
        "whatlinkshere": "Paj ki gen lyen vè paj sa a",
        "whatlinkshere-title": "Paj ki genyen lyen ki ap mennen nan \"$1\"",
        "whatlinkshere-page": "Paj :",
-       "linkshere-2": "Paj yo ki anba ap mene nan <b>$1</b> :",
-       "nolinkshere-2": "Pyès paj genyen lyen pou paj sa a <b>$1</b>.",
+       "linkshere": "Paj yo ki anba ap mene nan <b>$2</b> :",
+       "nolinkshere": "Pyès paj genyen lyen pou paj sa a <b>$2</b>.",
        "isredirect": "paj redireksyon",
        "istemplate": "anndan",
        "isimage": "lyen fichye a",
index 31cf225..ed27e30 100644 (file)
        "customcssprotected": "Nem szerkesztheted ezt a CSS-lapot, mert egy másik felhasználó személyes beállításait tartalmazza.",
        "customjsonprotected": "Nem szerkesztheted ezt a JSON-lapot, mert egy másik felhasználó személyes beállításait tartalmazza.",
        "customjsprotected": "Nem szerkesztheted ezt a JavaScript-lapot, mert egy másik felhasználó személyes beállításait tartalmazza.",
+       "sitecssprotected": "Nincs jogosultságod szerkeszteni ezt a CSS lapot, mert az érintene minden látogatót.",
+       "sitejsonprotected": "Nincs jogosultságod szerkeszteni ezt a JSON lapot, mert az érintene minden látogatót.",
+       "sitejsprotected": "Nincs jogosultságod szerkeszteni ezt a JavaScript lapot, mert az érintene minden látogatót.",
        "mycustomcssprotected": "Nincs jogod szerkeszteni ezt a CSS-lapot.",
        "mycustomjsonprotected": "Nincs jogod szerkeszteni ezt a JSON-lapot.",
        "mycustomjsprotected": "Nincs jogod szerkeszteni ezt a JavaScript-lapot.",
        "botpasswords-restriction-failed": "A botjelszó-korlátozások megakadályozzák ezt a bejelentkezést.",
        "botpasswords-invalid-name": "A megadott felhasználónév nem tartalmazza a botjelszó-elválasztót („$1”).",
        "botpasswords-not-exist": "A(z) „$1” felhasználó nem rendelkezik „$2” nevű botjelszóval.",
+       "botpasswords-needs-reset": "„$1” {{GENDER:$1|felhasználó}} „$2” botjának jelszavát vissza kell állítani.",
        "resetpass_forbidden": "A jelszavak nem változtathatók meg",
        "resetpass_forbidden-reason": "A jelszavakat nem változtathatóak meg: $1",
        "resetpass-no-info": "Be kell jelentkezned, hogy közvetlenül elérd ezt a lapot.",
        "resetpass-temp-password": "Ideiglenes jelszó:",
        "resetpass-abort-generic": "A jelszómódosítást megszakította egy kiterjesztés.",
        "resetpass-expired": "A jelszavad lejárt. Adjál meg egy új jelszót a bejelentkezéshez!",
-       "resetpass-expired-soft": "A jelszavad lejárt, ezért újat kell beállítanod. Válassz most egy új jelszót, vagy kattints a {{int:authprovider-resetpass-skip-label}} gombra, ha később akarod csak beállítani.",
-       "resetpass-validity-soft": "A jelszavad érvénytelen: $1\n\nAdj meg egy új jelszót most, vagy kattints a „{{int:authprovider-resetpass-skip-label}}” gombra, ha később akarod megadni.",
+       "resetpass-expired-soft": "A jelszavad lejárt, ezért újat kell beállítanod. Válassz most egy új jelszót, vagy kattints a {{int:authprovider-resetpass-skip-label}} gombra, ha csak később akarod megváltoztatni.",
+       "resetpass-validity-soft": "A jelszavad érvénytelen: $1\n\nAdj meg egy új jelszót most, vagy kattints a „{{int:authprovider-resetpass-skip-label}}” gombra, ha csak később akarod megváltoztatni.",
        "passwordreset": "Jelszó visszaállítása",
        "passwordreset-text-one": "A jelszó átmeneti beállításához töltsd ki az űrlapot.",
        "passwordreset-text-many": "{{PLURAL:$1|Az átmeneti jelszó elküldéséhez töltsd ki az alábbi mezők egyikét.}}",
        "diff-paragraph-moved-toold": "A szakaszt áthelyezték. Kattints ide a régi helyére való ugráshoz.",
        "difference-missing-revision": "Az összehasonlítandó változatok {{PLURAL:$2|egyike ($1) nem található|($1) nem találhatóak}}.\n\nEzt általában egy elavult, törölt oldalra mutató laptörténeti hivatkozás használata okozza. Részletek a [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} törlési naplóban] találhatóak.",
        "searchresults": "A keresés eredménye",
+       "search-filter-title-prefix": "Keresés csak olyan lapokban, amelyek címe a következőképp kezdődik: „$1”",
+       "search-filter-title-prefix-reset": "Keresés az összes lapban",
        "searchresults-title": "Keresési eredmények: „$1”",
        "titlematches": "Címbeli egyezések",
        "textmatches": "Szövegbeli egyezések",
        "action-viewmywatchlist": "saját figyelőlista megtekintése",
        "action-viewmyprivateinfo": "személyes adatok megtekintése",
        "action-editmyprivateinfo": "személyes adatok szerkesztése",
-       "action-editcontentmodel": "a lap tartalom modelljének szerkesztése",
+       "action-editcontentmodel": "a lap tartalommodelljének szerkesztése",
        "action-managechangetags": "címkék létrehozása és (de)aktiválása",
        "action-applychangetags": "változtatások címkézése",
        "action-changetags": "egyedi változtatások és napló bejegyzések tetszőleges címkével való ellátása és törlése",
        "rcfilters-other-review-tools": "Egyéb hasznos hivatkozások",
        "rcfilters-group-results-by-page": "Eredmények csoportosítása lapok szerint",
        "rcfilters-activefilters": "Aktív szűrők",
+       "rcfilters-activefilters-hide": "Elrejt",
+       "rcfilters-activefilters-show": "Mutat",
+       "rcfilters-activefilters-hide-tooltip": "Aktív szűrők dobozának elrejtése",
+       "rcfilters-activefilters-show-tooltip": "Aktív szűrők dobozának megjelenítése",
        "rcfilters-advancedfilters": "Haladó szűrők",
        "rcfilters-limit-title": "Megjelenítendő találatok száma",
        "rcfilters-limit-and-date-label": "$1 változtatás, $2",
        "rcfilters-savedqueries-rename": "Átnevezés",
        "rcfilters-savedqueries-setdefault": "Beállítás alapértelmezettként",
        "rcfilters-savedqueries-unsetdefault": "Eltávolítás, mint alapértelmezés",
-       "rcfilters-savedqueries-remove": "Eltávolítás",
+       "rcfilters-savedqueries-remove": "Törlés",
        "rcfilters-savedqueries-new-name-label": "Név",
        "rcfilters-savedqueries-new-name-placeholder": "Írd le a szűrő célját.",
        "rcfilters-savedqueries-apply-label": "Gyors hivatkozás létrehozása",
        "rcfilters-empty-filter": "Nincs aktív szűrő. Minden közreműködés látható.",
        "rcfilters-filterlist-title": "Szűrők",
        "rcfilters-filterlist-whatsthis": "Hogy működnek?",
-       "rcfilters-filterlist-feedbacklink": "Mond el nekünk, mit gondolsz az (új) szűrőkről",
+       "rcfilters-filterlist-feedbacklink": "Mond el nekünk, mit gondolsz ezekről a szűrőkről",
        "rcfilters-highlightbutton-title": "Kiemelt találatok",
        "rcfilters-highlightmenu-title": "Válassz egy színt",
        "rcfilters-highlightmenu-help": "Válassz színt ennek a tulajdonságnak kijelöléséhez",
        "rcfilters-watchlist-showupdated": "Az újabb változtatások, amiket még nem néztél meg, <strong>vastagítva</strong> láthatók, kitöltött jelzőkkel.",
        "rcfilters-preference-label": "A friss változtatások fejlesztett változatának elrejtése",
        "rcfilters-preference-help": "A 2017-es felületátdolgozás és minden azóta hozzáadott eszköz visszaállítása.",
+       "rcfilters-watchlist-preference-label": "A Figyelőlista fejlesztett változatának elrejtése",
+       "rcfilters-watchlist-preference-help": "A 2017-es felületátdolgozás és minden azóta hozzáadott eszköz visszaállítása.",
        "rcfilters-filter-showlinkedfrom-label": "A következő lapra hivatkozó lapok változtatásainak megjelenítése",
        "rcfilters-filter-showlinkedfrom-option-label": "A kiválasztott <strong>lapról</strong> hivatkozott lapok",
        "rcfilters-filter-showlinkedto-label": "A következő lapról hivatkozott lapok változtatásainak megjelenítése",
        "protectedtitles-submit": "Leírások mutatása",
        "listusers": "Szerkesztők",
        "listusers-editsonly": "Csak a szerkesztéssel rendelkező szerkesztők mutatása",
+       "listusers-temporarygroupsonly": "Csak az ideiglenes szerkesztői csoportokban szereplő szerkesztők mutatása",
        "listusers-creationsort": "Rendezés létrehozási dátum szerint",
        "listusers-desc": "Rendezés csökkenő sorrendben",
        "usereditcount": "{{PLURAL:$1|egy|$1}} szerkesztés",
        "speciallogtitlelabel": "Cél (cím vagy felhasználóhoz {{ns:user}}:felhasználói név):",
        "log": "Rendszernaplók",
        "logeventslist-submit": "Mutat",
+       "logeventslist-more-filters": "További szűrők:",
+       "logeventslist-patrol-log": "Ellenőrzési napló (patrol)",
+       "logeventslist-tag-log": "Címkenapló",
        "all-logs-page": "Minden nyilvános napló",
        "alllogstext": "A(z) {{SITENAME}} naplóinak összesített listája.\nA naplótípus, a felhasználónév (kis- és nagybetűérzékeny) vagy az érintett lap kiválasztásával (ez is kis- és nagybetűérzékeny) szűkítheted a találatok listáját.",
        "logempty": "Nincs illeszkedő naplóbejegyzés.",
        "watchlistanontext": "Jelentkezz be a figyelőlistád megtekintéséhez és szerkesztéséhez.",
        "watchnologin": "Nem vagy bejelentkezve",
        "addwatch": "Hozzáadás a figyelőlistához",
-       "addedwatchtext": "A(z) „[[:$1]]” lapot és vitalapját hozzáadtam a [[Special:Watchlist|figyelőlistádhoz]].",
-       "addedwatchtext-talk": "A(z) „[[:$1]]” lapot és a hozzá tartozó tartalmi lapot hozzáadtam a [[Special:Watchlist|figyelőlistádhoz]].",
+       "addedwatchtext": "A(z) „[[:$1]]” lap és vitalapja hozzáadva a [[Special:Watchlist|figyelőlistádhoz]].",
+       "addedwatchtext-talk": "A(z) „[[:$1]]” lap és a hozzá tartozó tartalmi lap hozzáadva a [[Special:Watchlist|figyelőlistádhoz]].",
        "addedwatchtext-short": "Az oldal: \"$1\" hozzá lett adva a figyelőlistádhoz.",
        "removewatch": "Eltávolítás a figyelőlistáról",
-       "removedwatchtext": "A(z) „[[:$1]]” lapot és vitalapját eltávolítottam a [[Special:Watchlist|figyelőlistáról]].",
-       "removedwatchtext-talk": "A(z) „[[:$1]]” lapot és a hozzá tartozó tartalmi lapot eltávolítottam a [[Special:Watchlist|figyelőlistáról]].",
+       "removedwatchtext": "A(z) „[[:$1]]” lap és vitalapja eltávolítva a [[Special:Watchlist|figyelőlistádról]].",
+       "removedwatchtext-talk": "A(z) „[[:$1]]” lap és a hozzá tartozó tartalmi lap eltávolítva a [[Special:Watchlist|figyelőlistádról]].",
        "removedwatchtext-short": "Az oldal: \"$1\" el lett távolítva a figyelőlistádról.",
        "watch": "Lap figyelése",
        "watchthispage": "Lap figyelése",
        "dellogpage": "Törlési napló",
        "dellogpagetext": "Itt láthatók a legutóbb törölt lapok.",
        "deletionlog": "törlési napló",
+       "log-name-create": "Laplétrehozási napló",
+       "log-description-create": "Itt láthatók a legutóbb létrehozott lapok.",
+       "logentry-create-create": "$1 {{GENDER:$2|létrehozta}} a következő lapot: $3",
        "reverted": "Visszaállítva a korábbi változatra",
        "deletecomment": "Ok:",
        "deleteotherreason": "További indoklás:",
        "whatlinkshere": "Mi hivatkozik erre",
        "whatlinkshere-title": "A(z) „$1” lapra hivatkozó lapok",
        "whatlinkshere-page": "Lap:",
-       "linkshere-2": "Az alábbi lapok hivatkoznak erre: $1",
-       "nolinkshere-2": "$1: erre a lapra egyetlen más lap sem hivatkozik.",
-       "nolinkshere-ns-2": "A kiválasztott névtérben egyetlen oldal sem hivatkozik a(z) '''$1''' lapra.",
+       "linkshere": "Az alábbi lapok hivatkoznak erre: $2",
+       "nolinkshere": "$2: erre a lapra egyetlen más lap sem hivatkozik.",
+       "nolinkshere-ns": "A kiválasztott névtérben egyetlen oldal sem hivatkozik a(z) '''$2''' lapra.",
        "isredirect": "átirányítás",
        "istemplate": "beillesztve",
        "isimage": "fájlhivatkozás",
        "markedaspatrollederrornotify": "Nem sikerült ellenőrzöttnek jelölni.",
        "patrol-log-page": "Ellenőrzési napló (patrol)",
        "patrol-log-header": "Ez az ellenőrzött változatok naplója.",
-       "log-show-hide-patrol": "járőrnapló $1",
-       "log-show-hide-tag": "címkenapló $1",
        "confirm-markpatrolled-button": "OK",
        "confirm-markpatrolled-top": "Ellenőrzöttnek jelölöd a(z) $2 lap $3 változatát?",
        "deletedrevision": "Régebbi változat törölve: $1",
        "watchlistedit-normal-legend": "Lapok eltávolítása a figyelőlistáról",
        "watchlistedit-normal-explain": "A figyelőlistádra felvett lapok címei alább láthatóak.\nHa el szeretnél távolítani egy címet, pipáld ki a mellette található jelölőnégyzetet, majd kattints „{{int:Watchlistedit-normal-submit}}” gombra.\nLehetőséged van a [[Special:EditWatchlist/raw|figyelőlista nyers változatának]] szerkesztésére is.",
        "watchlistedit-normal-submit": "A kijelöltek eltávolítása",
-       "watchlistedit-normal-done": "{{PLURAL:$1|A következő|A következő $1}} cikket eltávolítottam a figyelőlistádról:",
+       "watchlistedit-normal-done": "{{PLURAL:$1|A következő|A következő $1}} cikket eltávolítottuk a figyelőlistádról:",
        "watchlistedit-raw-title": "A nyers figyelőlista szerkesztése",
        "watchlistedit-raw-legend": "A nyers figyelőlista szerkesztése",
        "watchlistedit-raw-explain": "A figyelőlistádra felvett lapok az alábbi listában találhatók. A lista szerkeszthető;\nminden egyes sor egy figyelt lap címe. Ha kész vagy, kattints a lista alatt található\n„{{int:Watchlistedit-raw-submit}}” feliratú gombra. Használhatod a [[Special:EditWatchlist|hagyományos listaszerkesztőt]] is.",
        "watchlistedit-raw-titles": "A figyelőlistádon található cikkek:",
        "watchlistedit-raw-submit": "Mentés",
        "watchlistedit-raw-done": "A figyelőlistád változtatásait elmentettem.",
-       "watchlistedit-raw-added": "A {{PLURAL:$1|következő|következő $1}} cikket hozzáadtam a figyelőlistádhoz:",
-       "watchlistedit-raw-removed": "A {{PLURAL:$1|következő|következő $1}} cikket eltávolítottam a figyelőlistádról:",
+       "watchlistedit-raw-added": "A {{PLURAL:$1|következő|következő $1}} cikket hozzáadtuk a figyelőlistádhoz:",
+       "watchlistedit-raw-removed": "A {{PLURAL:$1|következő|következő $1}} cikket eltávolítottuk a figyelőlistádról:",
        "watchlistedit-clear-title": "A figyelőlista kiürítése",
        "watchlistedit-clear-legend": "Figyelőlista kiürítése",
        "watchlistedit-clear-explain": "Minden cím el lesz távolítva a figyelőlistádról",
        "unlinkaccounts-success": "A fiókok szétkapcsolva.",
        "authenticationdatachange-ignored": "A hitelesítő adatok változtatása nincs kezelve. Talán nincs beállítva szolgáltató?",
        "userjsispublic": "Figyelem: JavaScript-allapokon ne tárolj bizalmas adatokat, mivel minden felhasználó számára láthatóak.",
+       "userjsonispublic": "Figyelem: JSON-allapokon ne tárolj bizalmas adatokat, mivel minden felhasználó számára láthatóak.",
        "usercssispublic": "Figyelem: CSS-allapokon ne tárolj bizalmas adatokat, mivel minden felhasználó számára láthatóak.",
        "restrictionsfield-badip": "Érvénytelen IP-cím vagy -tartomány: $1",
        "restrictionsfield-label": "Engedélyezett IP-tartományok:",
        "pagedata-bad-title": "Érvénytelen cím: $1.",
        "unregistered-user-config": "Biztonsági okokból JavaScript, CSS és JSON szerkesztői alapok nem töltődnek be regisztrálatlan felhasználóknak.",
        "passwordpolicies": "Jelszóirányelvek",
+       "passwordpolicies-summary": "Ez egy lista a hatékony jelszóirányelvekről a wikin használt felhasználói csoportok szerint.",
        "passwordpolicies-group": "Csoport",
        "passwordpolicies-policies": "Irányelvek",
        "passwordpolicies-policy-minimalpasswordlength": "A jelszónak legalább $1 karakterből kell állnia",
        "passwordpolicies-policy-minimumpasswordlengthtologin": "A jelszónak legalább $1 karakterből kell állnia a bejelentkezéshez",
        "passwordpolicies-policy-passwordcannotmatchusername": "A jelszó nem lehet azonos a felhasználónévvel",
-       "passwordpolicies-policy-maximalpasswordlength": "A jelszó legfeljebb $1 karakter hosszú lehet"
+       "passwordpolicies-policy-passwordcannotmatchblacklist": "A jelszó nem lehet azonos a feketelistán szereplő jelszavakkal.",
+       "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}}"
 }
index 9c2d190..c1deea2 100644 (file)
        "whatlinkshere": "Այստեղ հղվող էջերը",
        "whatlinkshere-title": "Էջեր, որոնք հղում են դեպի «$1»",
        "whatlinkshere-page": "Էջ.",
-       "linkshere-2": "Հետևյալ էջերը հղում են '''$1''' էջին.",
-       "nolinkshere-2": "Ուրիշ էջերից '''$1''' էջին հղումներ չկան։",
-       "nolinkshere-ns-2": "Ընտրված անվանատարածքում '''$1''' էջին հղվող էջեր չկան։",
+       "linkshere": "Հետևյալ էջերը հղում են '''$2''' էջին.",
+       "nolinkshere": "Ուրիշ էջերից '''$2''' էջին հղումներ չկան։",
+       "nolinkshere-ns": "Ընտրված անվանատարածքում '''$2''' էջին հղվող էջեր չկան։",
        "isredirect": "վերահղման էջ",
        "istemplate": "ներառում",
        "isimage": "ֆայլի հղում",
diff --git a/languages/i18n/hyw.json b/languages/i18n/hyw.json
new file mode 100644 (file)
index 0000000..a5c4009
--- /dev/null
@@ -0,0 +1,702 @@
+{
+       "@metadata": {
+               "authors": [
+                       "ArmenBakkalian",
+                       "Armeniki",
+                       "Azniv Stepanian",
+                       "Rajemian",
+                       "Դավիթ Սարոյան"
+               ]
+       },
+       "underline-always": "Միշտ",
+       "underline-never": "Երբեք",
+       "sunday": "Կիրակի",
+       "monday": "Երկուշաբթի",
+       "tuesday": "Երեքշաբթի",
+       "wednesday": "Չորեքշաբթի",
+       "thursday": "Հինգշաբթի",
+       "friday": "Ուրբաթ",
+       "saturday": "Շաբաթ",
+       "sun": "Կիր.",
+       "mon": "Բշ.",
+       "tue": "Գշ.",
+       "wed": "Դշ.",
+       "thu": "Եշ.",
+       "fri": "Ուրբ.",
+       "sat": "Շաբ.",
+       "january": "Յունուար",
+       "february": "Փետրուար",
+       "march": "Մարտ",
+       "april": "Ապրիլ",
+       "may_long": "Մայիս",
+       "june": "Յունիս",
+       "july": "Յուլիս",
+       "august": "Օգոստոս",
+       "september": "Սեպտեմբեր",
+       "october": "Հոկտեմբեր",
+       "november": "Նոյեմբեր",
+       "december": "Դեկտեմբեր",
+       "january-gen": "Յունուար",
+       "february-gen": "Փետրուար",
+       "march-gen": "Մարտ",
+       "april-gen": "Ապրիլ",
+       "may-gen": "Մայիս",
+       "june-gen": "Յունիս",
+       "july-gen": "Յուլիս",
+       "august-gen": "Օգոստոս",
+       "september-gen": "Սեպտեմբեր",
+       "october-gen": "Հոկտեմբեր",
+       "november-gen": "Նոյեմբեր",
+       "december-gen": "Դեկտեմբեր",
+       "jan": "Յունր․",
+       "feb": "Փետր․",
+       "mar": "Մարտ",
+       "apr": "Ապր․",
+       "may": "Մայ․",
+       "jun": "Յնս․",
+       "jul": "Յլս․",
+       "aug": "Օգստ․",
+       "sep": "Սեպտ․",
+       "oct": "Հոկտ․",
+       "nov": "Նոյ․",
+       "dec": "Դեկտ․",
+       "january-date": "$1 Յունուար",
+       "february-date": "$1 Փետրուար",
+       "march-date": "$1 Մարտ",
+       "april-date": "$1 Ապրիլ",
+       "may-date": "$1 Մայիս",
+       "june-date": "$1 Յունիս",
+       "july-date": "$1 Յուլիս",
+       "august-date": "$1 Օգոստոս",
+       "september-date": "$1 Սեպտեմբեր",
+       "october-date": "$1 Հոկտեմբեր",
+       "november-date": "$1 Նոյեմբեր",
+       "december-date": "$1 Դեկտեմբեր",
+       "pagecategories": "{{PLURAL:$1|Ստորոգութիւն|Ստորոգութիւններ}}",
+       "category_header": "«$1» ստորոգութեան մէջ էջեր",
+       "subcategories": "Ենթաստորոգութիւններ",
+       "category-media-header": "\"$1\" ստորոգութեան հաղորդամիջոց",
+       "category-empty": "<em>Այս ստորոգութիւնը ներկայիս դատարկ է։<em>",
+       "hidden-categories": "{{PLURAL:$1|Թաքուն ստորոգութիւն|Թաքուն ստորոգութիւններ}}",
+       "category-subcat-count": "{{PLURAL:$2|Այս ստորոգութիւնը ունի միայն հետեւեալ ենթաստորոգութիւնը։|Այս ստորոգութիւնը ունի հետեւեալ {{PLURAL:$1|ենթաստորոգութիւն|ենթաստորոգութիւններ}}ը՝ ընդհանուր $2էն։}}",
+       "category-article-count": "{{PLURAL:$2|Այս ստորոգութիւնը կը պարունակէ միայն հետեւեալ էջը։|Ստորեւ այս ստորոգութեան ընդհանուր $2էն {{PLURAL:$1|էջը|$1 էջերը}}։}}",
+       "category-file-count": "{{PLURAL:$2|Այս ստորոգութիւնը կը պարունակէ միայն հետեւեալ էջը։|Ստորեւ այս ստորոգութեան ընդհանուր $2-էն {{PLURAL:$1|էջը|$1 էջերը}}։}}",
+       "listingcontinuesabbrev": "շար.",
+       "noindex-category": "Չցուցակագրուած էջեր",
+       "broken-file-category": "Հասցէազուրկ նիշքի յղումներով էջեր",
+       "about": "Նախագիծին մասին",
+       "newwindow": "(Նոր պատուհանի մէջ կը բացուի)",
+       "cancel": "Չեղարկել",
+       "mypage": "Էջ",
+       "mytalk": "Քննարկում",
+       "anontalk": "Քննարկել",
+       "navigation": "Նաւարկութիւն",
+       "and": "&#32;եւ",
+       "namespaces": "Անուանատարածքներ",
+       "variants": "Տարբերակներ",
+       "navigation-heading": "Նաւարկութեան ցուցակ",
+       "returnto": "Վերադարնալ դէպի $1։",
+       "tagline": "{{SITENAME}}էն",
+       "help": "Օգնութիւն",
+       "search": "Որոնել",
+       "searchbutton": "Որոնել",
+       "searcharticle": "‎Յառաջանալ",
+       "history": "Էջի պատմութիւն",
+       "history_short": "Պատմութիւն",
+       "history_small": "պատմութիւն",
+       "updatedmarker": "փոփոխուած իմ վերջին այցելութեան ի վեր",
+       "printableversion": "Տպագրելի տարբերակ",
+       "permalink": "Մնայուն յղում",
+       "print": "Տպել",
+       "view": "‎Տեսնել",
+       "view-foreign": "Դիտել $1ին վրայ",
+       "edit": "Խմբագրել",
+       "edit-local": "Խմբագրել տեղային նկարագրութիւնը",
+       "create": "Ստեղծել",
+       "create-local": "Աւելցնել տեղական նկարագրութիւն",
+       "delete": "Ջնջել",
+       "undelete_short": "Ստորագծել {{PLURAL:$1|մէկ խմբագրութիւն|$1 խմբագրութիւններ}}",
+       "viewdeleted_short": "Դիտել {{PLURAL:$1|ջնջուած խմբագրութիւն}}",
+       "protect": "Առաջարկ",
+       "protect_change": "փոխել",
+       "unprotect": "Փոխել պաշտպանութիւնը",
+       "newpage": "Նոր էջ",
+       "talkpagelinktext": "Քննարկել",
+       "specialpage": "Յատուկ էջ",
+       "personaltools": "Անձնական գործիքներ",
+       "talk": "Քննարկում",
+       "views": "Տեսնուած",
+       "toolbox": "Գործիքներ",
+       "tool-link-userrights": "Փոխել {{GENDER:$1|գործածող}} խումբեր",
+       "tool-link-userrights-readonly": "Տեսնալ {{GENDER:$1|գործածող}} խումբեր",
+       "tool-link-emailuser": "Ղրկել ասիկա էլ-նամակով {{GENDER:$1|գործածողին}}",
+       "imagepage": "Դիտել նիշքի էջը",
+       "mediawikipage": "Դիտել հաղորդագրութեան էջը",
+       "viewhelppage": "Դիտել օգնութեան էջը",
+       "viewtalkpage": "Դիտել քննարկումը",
+       "otherlanguages": "Այլ լեզուներով",
+       "redirectedfrom": "(Վերայղուած է $1-էն)",
+       "redirectpagesub": "վերայղման էջ",
+       "redirectto": "Վերայղել դէպի՝",
+       "lastmodifiedat": "Այս էջը վերջին անգամ խմբագրուած է $1 թուականի ժամը $2ին:",
+       "protectedpage": "Պաշտպանուած էջ",
+       "jumpto": "Ցատկել դէպի",
+       "jumptonavigation": "նաւարկութիւն",
+       "jumptosearch": "որոնել",
+       "view-pool-error": "Կը ներէք, բայց ծարյաղ-համակարքիչները այս ժամանակին գերբեռնուած են:\nՇատ գործածողներ այս էջը կը փորձէն դիտել:\nՀաճեցէք սպասել որոշ ժամանակ եւ փորձել նորէն դիտել էջը:\n$1",
+       "generic-pool-error": "Կը ներէք, բայց ծարյաղ-համակարքիչները այս ժամանակին գերբեռնուած են:\nՇատ գործածողներ այս աղբիւրը կը փորձէն դիտել:\nՀաճեցէք սպասել որոշ ժամանակ եւ փորձել նորէն դիտել աղբիւրը:",
+       "pool-timeout": "Արգելափակման ժամկէտը սպառուած է",
+       "pool-errorunknown": "Անյայտ սխալ",
+       "poolcounter-usage-error": "Օգտագործման սխալ. $1",
+       "aboutsite": "{{SITENAME}}-ի մասին",
+       "aboutpage": "Project:Ուիքիփետիայի Մասին",
+       "copyright": "Բովանդակութիւնը առկայ է $1 ներքոյ, եթէ այլ բան նշուած չէ։",
+       "copyrightpage": "{{ns:project}}:Հեղինակային իրաւունքներ",
+       "currentevents": "Ընթացիկ իրադարձութիւններ",
+       "currentevents-url": "Project:Ընթացիկ իրադարձութիւններ",
+       "disclaimers": "Պատասխանատուութենէ Հրաժարում",
+       "disclaimerpage": "Project:Պատասխանատուութեան ընդհանուր բացասում",
+       "edithelp": "Խմբագրութեան ուղեցոյց",
+       "helppage-top-gethelp": "Օգնութիւն",
+       "mainpage": "Գլխաւոր էջ",
+       "mainpage-description": "Գլխաւոր էջ",
+       "portal": "Համայնքային դարպաս",
+       "portal-url": "Project:Համայնքային դարպաս",
+       "privacy": "Սեփական տուեալներու պահպանման քաղաքականութիւն",
+       "privacypage": "Project:Սեփական տուեալներու պահպանման քաղաքականութիւն",
+       "ok": "Լաւ",
+       "retrievedfrom": "Վերցուած է «$1» էջէն",
+       "youhavenewmessages": "{{PLURAL:$3|Դուք ունիք}} $1 ($2)։",
+       "youhavenewmessagesfromusers": "{{PLURAL:$4|Դուք ունիք}} $1 {{PLURAL:$3|այլ մասնակից|$3 մասնակիցէն}} ($2):",
+       "youhavenewmessagesmanyusers": "Դուք ունիք $1 քանի մը գործածողներէն ($2)։",
+       "newmessageslinkplural": "{{PLURAL:$1|Նոր հաղորդագրութիւն|999=Նոր հաղորդագրութիւններ}}",
+       "newmessagesdifflinkplural": "վերջին {{PLURAL:$1|փոփոխութիւն|999=փոփոխութիւններ}}",
+       "youhavenewmessagesmulti": "Դուք նոր հաղորդագրութիւններ ունիք $1-ին վրայ",
+       "editsection": "Խմբագրել",
+       "editold": "խմբագրել",
+       "viewsourceold": "Տեսնել աղբիւրը",
+       "editlink": "Խմբագրել",
+       "viewsourcelink": "Տեսնել աղբիւրը",
+       "editsectionhint": " Խմբագրել <$1> բաժինը",
+       "toc": "Բովանդակութիւն",
+       "showtoc": "Ցուցադրել",
+       "hidetoc": "թաքցնել",
+       "collapsible-collapse": "Ծալել",
+       "collapsible-expand": "Տարածել",
+       "confirmable-confirm": "Վստա՞հ էք {{GENDER:$1|դուք}} ։",
+       "confirmable-yes": "Այո",
+       "confirmable-no": "Ոչ",
+       "thisisdeleted": "Դիտե՞լ կամ վերականգնե՞լ $1։",
+       "viewdeleted": "Դիտե՞լ $1։",
+       "restorelink": "{{PLURAL:$1|մէկ ջնջուած խմբագրութիւն|$1 ջնջուած խմբագրութիւններ}}",
+       "feedlinks": "Սնուցման.",
+       "feed-invalid": "Սխալ բաժանորդագրթեան սնուցմանի տեսակ։",
+       "site-rss-feed": "$1 RSS սնուցում",
+       "site-atom-feed": "$1 Atom սնուցում",
+       "page-rss-feed": "«$1» RSS սնուցում",
+       "page-atom-feed": "«$1» Atom սնուցում",
+       "red-link-title": "$1 (էջը գոյութիւն չունի)",
+       "sort-descending": "Դասաւորէ՛ մեծէն-փոքրիկ",
+       "sort-ascending": "Դասաւորէ՛ փոքրիկէն-մեծ",
+       "nstab-main": "Էջ",
+       "nstab-user": "Մասնակիցի էջ",
+       "nstab-media": "Մետիայի էջ",
+       "nstab-special": "Յատուկ էջ",
+       "nstab-project": "Նախագիծի էջ",
+       "nstab-image": "Նիշք",
+       "nstab-mediawiki": "Հաղորդագրութիւն",
+       "nstab-template": "Կաղապար",
+       "nstab-help": "Օգնութեան էջ",
+       "nstab-category": "Ստորոգութիւն",
+       "mainpage-nstab": "Գլխաւոր էջ",
+       "nosuchaction": "Այս գործողութիւնը չկայ",
+       "nosuchspecialpage": "Այդպիսի յատուկ էջ չկայ",
+       "nospecialpagetext": "<strong> Ձեր խնդրած յատուկ էջը անվաւեր է։</strong>\n\nՎաւերական յատուկ էջերու ցանկը կը գտնէք այստեղ՝ [[Special:SpecialPages|{{int:յատուկէջեր}}]].",
+       "databaseerror-query": "Հարցակէտ. $1",
+       "databaseerror-function": "Գործառնութիւն. $1",
+       "databaseerror-error": "Սխալ. $1",
+       "internalerror": "Ներքին սխալ",
+       "internalerror_info": "Ներքին սխալ. $1",
+       "internalerror-fatal-exception": "Ճակատագրական բացառութիւն «$1» տեսակի",
+       "badtitle": "Անընդունելի խորագիր",
+       "badtitletext": "Խնդրուած էջի վերնագիրը անվաւեր էր, պարապ էր, կամ կը պարունակէր միջլեզուական կամ միջուիքիի սխալ ներյղում մը։ \nՀնարաւոր է որ ան կը պարունակէ մէկ կամ աւելի գիրեր, որոնց վերնագիրներու մէջ օգտագործումը արտօնուած չէ։",
+       "viewsource": "Տեսնել աղբիւրը",
+       "viewsource-title": "Տեսնել $1 էջի աղբիւրը",
+       "viewsourcetext": "Կրնաք այս էջին աղբիւրը տեսնել ու ընդօրինակել։",
+       "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": "Դարձեալ մուտքագրեցէ'ք անցաբառը",
+       "userlogin-remembermypassword": "Մնալ համակարգին մէջ",
+       "login": "Մուտք գործել",
+       "userlogin-noaccount": "Հաշիւ չունի՞ք։",
+       "userlogin-joinproject": "Միացէ՛ք {{SITENAME}} նախագիծին",
+       "createaccount": "Հաշիւ ստեղծել",
+       "userlogin-resetpassword-link": "Անցաբառը մոռցա՞ծ էք",
+       "userlogin-helplink2": "Մուտք գործելու օգնութիւն",
+       "createacct-emailoptional": "Իմակահասցէ (ոչ պարտադիր)",
+       "createacct-email-ph": "Մուտքագրեցէ՛ք ձեր իմակահասցէն",
+       "createacct-reason": "Պատճառ",
+       "createacct-submit": "Ստեղծել ձեր հաշիւը",
+       "createacct-benefit-heading": "{{SITENAME}}՝ ստեղծուած է ձեզի պէս մարդոց կողմէ։",
+       "createacct-benefit-body1": "{{PLURAL:$1|խմբագրում}}",
+       "createacct-benefit-body2": "$1 {{PLURAL:$1|էջ}}",
+       "createacct-benefit-body3": "վերջին {{PLURAL:$1|մասնակից}}",
+       "loginlanguagelabel": "Լեզու՝ $1",
+       "pt-login": "Մուտք գործել",
+       "pt-login-button": "Մուտք գործել",
+       "pt-createaccount": "Հաշիւ ստեղծել",
+       "pt-userlogout": "Դուրս գալ",
+       "passwordreset": "Վերականգնել անցաբառը",
+       "bold_sample": "Շեշտուած տառերով գրութիւն",
+       "bold_tip": "Շեշտուած տառերով գրութիւն",
+       "italic_sample": "Շեղատառ գրութիւն",
+       "italic_tip": "Շեղատառ գրութիւն",
+       "link_sample": "Յղման վերնագիր",
+       "link_tip": "Ներքին յղում",
+       "extlink_sample": "http://www.example.com յղման վերնագիրը",
+       "extlink_tip": "Արտաքին յղում (յիշել http:// նախածանց)",
+       "headline_sample": "Վերնագրի գրութիւն",
+       "headline_tip": "Երկրորդ մակարդակի վերնագիր",
+       "nowiki_sample": "Մուտքագրեցէ՛ք չձեւաւորուած գրութիւնը այստեղ",
+       "nowiki_tip": "Անտեսել ուիքի ձեւաւորումը",
+       "image_tip": "Ներփակ նիշք",
+       "media_tip": "Նիշքին յղումը",
+       "sig_tip": "Ձեր ստորագրութիւնը ժամակնիքով",
+       "hr_tip": "Հորիզոնական գիծ (գործածել խնայողաբար)",
+       "summary": "Ամփոփում՝",
+       "minoredit": "Ասիկա մանր խմբագրում է",
+       "watchthis": "Հսկել այս էջը",
+       "savearticle": "Էջը պահել",
+       "preview": "Կանխաստուգել",
+       "showpreview": "Կանխաստուգել",
+       "showdiff": "Ցուցնել փոփոխութիւնները",
+       "anoneditwarning": "<strong>Զգուշացում։</strong> Մուտք գործած չէք համակարգ։ Որեւէ խմբագրումի պարագային ձեր IP հասցէն տեսանելի կը դառնայ բոլորին։ Եթե <strong>[$1 մուտք գործէք]</strong> կամ <strong>[$2 ստեղծէք մասնակցային հաշիւ]</strong>, ձեր կատարած խմբագրումները կը կապուին ձեր մասնակցային անունին հետ, ինչպէս նաեւ կ՚ունենաք այլ առաւելութիւններ։",
+       "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:Նախասիրութիւններ|մասնակիցի նախասիրութիւններուն մէջ]] եւ արգելակուած չէ վեր անոր օգտագործումը.\nՁեր ընթացիկ IP հասցէն է $3, եւ արգելակման ինքնութեան համարն է #$5.\nԿը շնդրենք որ այս մանրամասնութիւնները նշէք ձեր բոլոր թղթակցութիւններուն մէջ։",
+       "loginreqlink": "մուտք գործել",
+       "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>։",
+       "noarticletext-nopermission": "Ներկայիս այս էջին վրայ որեւէ գրութիւն չկայ։\nԿրնաք [[Special:Search/{{PAGENAME}}|այս վերնագիրով էջը որոնել]] այլ էջերու մէջ, կամ <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} որոնել համապատասխան տեղեկատետրերը], սակայն իրաւունք չունիք այս էջը ստեղծելու։",
+       "userpage-userdoesnotexist-view": "«$1» անունով գրանցուած մասնակից չկայ։",
+       "clearyourcache": "<strong>Նշում՝</strong> Պահելէ ետք կրնայ ըլլալ որ պէտք ունենաք մաքրելու դիտարկիչին պաշարը (cache) փոփոխութիւնները կարենալ տեսնելու համար։\n* <strong>Firefox / Safari:</strong> Սեղմած պահել <em>Shiftը</em> մինչ կը սեղմէք  <em>Reload</em>, կամ ալ սեղմել <em>Ctrl-F5</em> կամ <em>Ctrl-R</em> (<em>⌘-R</em> Macի վրայ)\n* <strong>Google Chrome:</strong> Սեղմել <em>Ctrl-Shift-R</em> (<em>⌘-Shift-R</em> Macի վրայ)\n* <strong>Internet Explorer:</strong> Սեղմած պահել <em>Ctrl</em> մինչ կը սեղմէք  <em>Refresh</em>, կամ ալ սեղմել <em>Ctrl-F5</em>\n* <strong>Opera:</strong> Երթալ <em>Menu → Settings</em> (<em>Opera → Preferences</em> Macի վրայ) եւ ապա <em>Privacy & security → մաքրել թերթատման տեղեկութիւնները → Պաշարի մէջ դրուած նկարներ եւ նիշքեր</em>.",
+       "previewnote": "<strong>Յիշել որ ասիկա միայն կանխաստուգում է. ձեր կատարած փոփոխութիւնները տակաւին չեն պահուած։<strong>",
+       "continue-editing": "Շարունակել խմբագրել",
+       "editing": "Կը խմբագրուի՝ $1 էջը",
+       "creating": "«$1» էջի ստեղծում",
+       "editingsection": "$1 բաժինի խմբագրում",
+       "templatesused": "Այս էջին մէջ օգտագործուած {{PLURAL:$1|կաղապարը|կաղապարները}}.",
+       "templatesusedpreview": "{{PLURAL:$1|Կաղապար}} օգտագործուած այս կանխաստուգումին մէջ՝",
+       "template-protected": "(պահպանուած)",
+       "template-semiprotected": "(մասամբ պահպանուած է)",
+       "hiddencategories": "Այս էջը կը պատկանի հետեւեալ {{PLURAL:$1|1 թաքուն ստորոգութեան|$1 թաքուն ստորոգութիւնններուն}}.",
+       "permissionserrors": "Արտօնութեան սխալ",
+       "permissionserrorstext-withaction": "Արտօնութիւն չունիք $2 հետեւեալ {{PLURAL:$1|պատճառով|պատճառներով}}.",
+       "recreate-moveddeleted-warn": "<strong>Զգուշացում. Նախապէս ջնջուած էջ մը պիտի վերստեղծուի։<strong>\n\nԿը խնդրուի մտածել այս էջի խմբագրման նպատակայարմարութեան մասին։ \nՁեր դիւրութեան համար ներքեւ կը գտնէք այս էջի ջնջումին և տեղափոխումին տեղեկատետրերը։",
+       "moveddeleted-notice": "Այս էջը ջնջուած է։\nԷջին ջնջումի, պահպանումի եւ փոխադրումի տեղեկատետրը տրամադրելի է ներքեւ որպէս տեղեկութիւն։",
+       "content-model-wikitext": "ուիքիթէքսթ",
+       "undo-failure": "Խմբագրումը կարելի չեղաւ ետ ընել միջանկեալ խմբագրումներու հետ ընդհարումի պատճառով։",
+       "viewpagelogs": "Տեսնել այս էջին տեղեկատետրերը",
+       "currentrev-asof": "Ընթացիկ տարբերակը $1ի դրութեամբ",
+       "revisionasof": "$1-ի տարբերակ",
+       "revision-info": "$1ի տարբերակ, $2ի կողմէ",
+       "previousrevision": "←Նախորդ տարբերակ",
+       "nextrevision": "Յաջորդ տարբերակ→",
+       "currentrevisionlink": "Վերջին տարբերակ",
+       "cur": "ընթ.",
+       "last": "նախ.",
+       "histlegend": "Տարբերութիւններու համեմատում. դրէ՛ք նշման կէտեր այն տարբերակներու կողքին, որոնք կ՚ուզէք համեմատել եւ սեղմեցէ՛ք ներքեւ գտնուող կոճակը։<br />\nԾանօթ.՝ <strong>({{int:cur}})</strong> = ընթացիկ տարբերակի հետ համեմատած տարբերութիւններ,\n<strong>({{int:last}})</strong> = նախորդ տարբերակի հետ համեմատած տարբերութիւններ,<br />'''չ''' = չնչին խմբագրում",
+       "history-fieldset-title": "Որոնել տարբերակներ",
+       "histfirst": "հնագոյն",
+       "histlast": "նորագոյն",
+       "history-feed-title": "Վերանայումներու ցուցակ",
+       "history-feed-description": "Ուիքիի այս էջին վերանայումներու ցուցակը",
+       "history-feed-item-nocomment": "$1՝ $2",
+       "rev-delundel": "ցուցնել/թաքցնել",
+       "mergelog": "Ձուլման տեղեկատետր",
+       "history-title": "«$1»ի վերանայումներու ցուցակ",
+       "difference-title": "«$1»ի խմբագրումներու միջեւ տարբերութիւն",
+       "lineno": "Տող $1.",
+       "compareselectedversions": "Համեմատել ընտրուած տարբերակները",
+       "editundo": "Յետարկել",
+       "diff-empty": "(Տարբերութիւն չկայ)",
+       "diff-multi-sameuser": "(նոյն մասնակիցի ցոյց չտրուած {{PLURAL:$1|մէկ միջանկեալ խմբագրում|$1 միջանկեալ խմբագրումներ}})",
+       "diff-multi-otherusers": "(նոյն մասնակիցի ցոյց չտրուած {{PLURAL:$1|մէկ միջանկեալ վերանայում|$2 միջանկեալ վերանայումներ}})",
+       "searchresults": "Որոնման արդիւնքներ",
+       "searchresults-title": "«$1»-ի որոնման արդիւնքները",
+       "prevn": "նախորդ {{PLURAL:$1|$1}}",
+       "nextn": "յաջորդ {{PLURAL:$1|$1}}",
+       "prevn-title": "Նախորդ $1 {{PLURAL:$1|արդիւնքը|արդիւնքները}}",
+       "nextn-title": "Յաջորդ $1 {{PLURAL:$1|արդիւնքը|արդիւնքները}}",
+       "shown-title": "Իւրաքանչիւր էջի վրայ ցոյց տալ $1 {{PLURAL:$1|արդիւնք|արդիւնքներ}}",
+       "viewprevnext": "Տեսնել ($1 {{int:pipe-separator}} $2) ($3)",
+       "searchmenu-exists": "<strong>\"[[:$1]]\" անունով էջ կայ այս ուիքիին մէջ։</strong> {{PLURAL:$2|0=|Տե՛ս նաեւ որոնումին բերած միւս արդիւնքները.}}",
+       "searchmenu-new": "<strong>Ստեղծել «[[:$1]]» էջը այս ուիքիին մէջ։</strong> {{PLURAL:$2|0=|Տե՛ս նաեւ որոնումով գտած էջդ։| Տե՛ս նաեւ որոնումին բերած արդիւնքները։}}",
+       "searchprofile-articles": "Բովանդակութեան էջեր",
+       "searchprofile-images": "Բազմահաղորդամիջոցներ",
+       "searchprofile-everything": "Ամէն ինչ",
+       "searchprofile-advanced": "Յառաջացած",
+       "searchprofile-articles-tooltip": "Որոնել $1-ին մէջ",
+       "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-redirect": "(Վերայղուած է $1-էն)",
+       "search-section": "(բաժին $1)",
+       "search-file-match": "(համապատասխան է նիշքի բովանդակութեան)",
+       "search-suggest": "$1 Նկատի ունի՞ք",
+       "searchall": "բոլոր",
+       "search-showingresults": "{{PLURAL:$4|<strong>$1</strong> արդիւնք <strong>$3</strong>-էն|<strong>$1 - $2</strong> արդիւնքներ <strong>$3</strong>-էն}}",
+       "search-nonefound": "Որոնումին համապատասխանող արդիւնքներ չգտնուեցան",
+       "mypreferences": "Նախընտրութիւններ",
+       "group-bot": "Մեքենայիկներ",
+       "group-sysop": "Վարիչներ",
+       "grouppage-bot": "{{ns:project}}:Մեքենայիկներ",
+       "grouppage-sysop": "{{ns:project}}:Վարիչներ",
+       "right-writeapi": "API գիրի օգտագործումը",
+       "newuserlogpage": "Մասնակիցներու գրանցման տեղեկատետր",
+       "rightslog": "Մասնակիցի իրաւունքներու տեղեկատետր",
+       "action-edit": "խմբագրել այս էջը",
+       "action-createaccount": "Այս մասնակիցին հաշիւը ստեղծել",
+       "enhancedrc-history": "պատմութիւն",
+       "recentchanges": "Վերջին փոփոխութիւնները",
+       "recentchanges-legend": "Վերջին փոփոխութիւններու նախընտրութիւններ",
+       "recentchanges-summary": "Հետեւեցէ՛ք ուիքիին մէջ կատարուած վերջին փոփոխութիւններուն՝ այստեղ։",
+       "recentchanges-noresult": "Տուեալ ժամանակահատուածի ընթացքին կատարուած որեւէ փոփոխութիւն չի համապատասխաներ այս պայմաններուն։",
+       "recentchanges-feed-description": "Հետեւեցէ՛ք ուիքիի այս հոսքին մէջ կատարուած վերջին փոփոխութիւններուն։",
+       "recentchanges-label-newpage": "Այս խմբագրումը նոր էջ ստեղծեց",
+       "recentchanges-label-minor": "Ասիկա մանր խմբագրում է",
+       "recentchanges-label-bot": "Այս խմբագրումը իրականացուած է մեքենայիկի մը կողմէ",
+       "recentchanges-label-unpatrolled": "Այս խմբագրումը տակաւին ստուգուած չէ",
+       "recentchanges-label-plusminus": "Էջին ծաւալը փոխուեցաւ այսքան պայթով",
+       "recentchanges-legend-heading": "<strong>Ծանօթ.՝</strong>",
+       "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (տե՛ս նաեւ՝  [[Special:NewPages|նոր էջերու ցանկ]])",
+       "rcnotefrom": "Ներքեւ {{PLURAL:$5|փոփոխութիւնն է|փոփոխութիւններն են}} սկսեալ <strong>$3, $4</strong> (մինչեւ <strong>$1</strong> ցոյց տրուած).",
+       "rclistfrom": "Ցոյց տալ նոր փոփոխութիւնները սկսած $3 $2",
+       "rcshowhideminor": "$1 չնչին խմբագրումներ",
+       "rcshowhideminor-show": "Ցուցնել",
+       "rcshowhideminor-hide": "Թաքցնել",
+       "rcshowhidebots": "$1 մեքենայիկներ",
+       "rcshowhidebots-show": "Ցուցնել",
+       "rcshowhidebots-hide": "Թաքցնել",
+       "rcshowhideliu": "$1 գրանցուած մասնակիցները",
+       "rcshowhideliu-show": "Ցուցնել",
+       "rcshowhideliu-hide": "Թաքցնել",
+       "rcshowhideanons": "$1 անանուն մասնակիցները",
+       "rcshowhideanons-show": "Ցուցնել",
+       "rcshowhideanons-hide": "Թաքցնել",
+       "rcshowhidepatr": "$1 ստուգուած խմբագրումները",
+       "rcshowhidemine": "$1 իմ խմբագրումներս",
+       "rcshowhidemine-show": "Ցուցնել",
+       "rcshowhidemine-hide": "Թաքցնել",
+       "rclinks": "Ցոյց տալ վերջին $1 փոփոխութիւնները վերջին $2 օրուան ընթացքին",
+       "diff": "տարբ.",
+       "hist": "պատմ.",
+       "hide": "Թաքցնել",
+       "show": "Ցուցնել",
+       "minoreditletter": "Չ",
+       "newpageletter": "Ն",
+       "boteditletter": "Մ",
+       "rc-change-size-new": "$1{{PLURAL:$1|պայթ}}փոփոխութենէն ետք",
+       "rc-old-title": "Սկիզբը ստեղծուած էր որպէս «$1»",
+       "recentchangeslinked": "Առնչուած փոփոխութիւններ",
+       "recentchangeslinked-feed": "Առնչուած փոփոխութիւններ",
+       "recentchangeslinked-toolbox": "Առնչուող փոփոխութիւններ",
+       "recentchangeslinked-title": "«$1» էջին առնչուած փոփոխութիւնները",
+       "recentchangeslinked-summary": "Նշել Էջի թիւը տեսնելու համար այդ էջին կամ էջէն յղուող փոփոխութիւնները։ (Ստորոգութեան մը անդամները տեսնելու համար, նշել {{ns:category}}:Ստորագութեան անունը))։\n[[Special:Հսկողութեան ցանկ|ձեր հսկողութեան ցանկ]]ի էջին վրայ գտնուող փոփոխութիւնները <strong>շեշտուած տառերով են</strong>։",
+       "recentchangeslinked-page": "Էջին անունը՝",
+       "recentchangeslinked-to": "Փոխարէնը ցոյց տալ տուեալ էջին առնչուած էջերուն մէջ կատարուած փոփոխութիւնները։",
+       "upload": "Վերբեռնել նիշք",
+       "uploadlogpage": "Վերբեռնումի տեղեկատետր",
+       "filedesc": "Ամփոփում",
+       "license": "Արտօնագրութիւն՝",
+       "license-header": "Արտօնագրում",
+       "imgfile": "Նիշք",
+       "listfiles": "Նիշքերու ցանկ",
+       "file-anchor-link": "Նիշք",
+       "filehist": "Նիշքի պատմութիւն",
+       "filehist-help": "‎Սեղմել օրուան/ժամին վրայ նիշքի այդ պահուն ունեցած վիճակը տեսնելու համար",
+       "filehist-revert": "յետարկել",
+       "filehist-current": "ընթացիկ",
+       "filehist-datetime": "Օր/Ժամ",
+       "filehist-thumb": "Մանրապատկեր",
+       "filehist-thumbtext": "$1 տարբերակի մանրապատկերը",
+       "filehist-nothumb": "Մանրապատկեր չկայ",
+       "filehist-user": "Մասնակից",
+       "filehist-dimensions": "Ծաւալ",
+       "filehist-comment": "Մեկնաբանութիւն",
+       "imagelinks": "Նիշքի գործածութիւն",
+       "linkstoimage": "Հետեւեալ {{PLURAL:$1|էջը կը յղուի|$1 էջերը կը յղուին}} այս նիշքին՝",
+       "linkstoimage-more": "$1է աւելի {{PLURAL:$1|էջի յղում|էջի յղումներ}} կան այս նիշքին։\nՀետեւեալ ցանկը ցոյց կու տայ {{PLURAL:$1|առաջին էջի յղում|առաջին $1 էջի յղումներ}} այս նիշքին միայն։\n[[Special:WhatLinksHere/$2|ամբողջական ցանկ]] մը տրամադրելի է։",
+       "nolinkstoimage": "Այս նիշքին յղուող էջեր չկան։",
+       "linkstoimage-redirect": "$1 (նիշքի վերայղում) $2",
+       "sharedupload-desc-here": "Այս նիշքը առնուած է $1-էն եւ կրնայ օգտագործուիլ այլ նախագիծերու մէջ։ $1-ի մէջ անոր [$2 նիշքը նկարագրող էջի]ի նկարագրութիւնը ներկայացուած է ստորեւ։",
+       "filepage-nofile": "Այս անունով նիշք մը գոյութիւն չունի։",
+       "upload-disallowed-here": "Այս նիշքը կարելի չէ ջնջել ու փոխարինել։",
+       "randompage": "Պատահական էջ",
+       "statistics": "Վիճակագրութիւն",
+       "double-redirect-fixer": "Վերայղումներու շտկիչ",
+       "nbytes": "$1 {{PLURAL:$1|պայթ}}",
+       "nmembers": "$1 {{PLURAL:$1|անդամ|անդամներ}}",
+       "prefixindex": "Բոլոր նախածանցներով էջերը",
+       "listusers": "Մասնակիցներու ցանկ",
+       "newpages": "Նոր էջեր",
+       "move": "Տեղափոխել այս էջը",
+       "pager-newer-n": "{{PLURAL:$1|նոր 1|աւելի նոր $1}}",
+       "pager-older-n": "{{PLURAL:$1|աւելի հին 1|աւելի հին $1}}",
+       "booksources": "Գիրքի աղբիւրներ",
+       "booksources-search-legend": "Որոնել գիրքի մասին",
+       "booksources-search": "Որոնել",
+       "specialloguserlabel": "Կատարող․",
+       "speciallogtitlelabel": "Թիրախ (վերնագիր կամ {{ns:user}}:մասնակիցի մասնակցային անուն)՝",
+       "log": "Տեղեկատետրեր",
+       "all-logs-page": "Բոլոր հանրային տեղեկատետրերը",
+       "alllogstext": "{{SITENAME}} կայքի տեղեկատետրերու միացեալ ցանկ։\nԿրնաք արդիւնքները սահմանափակել ըստ տեղեկատետրի տեսակին, մասնակիցի անունին կամ համապատասխան էջին։",
+       "logempty": "Համապատասխան տարրեր չկան տեղեկատետերին մէջ։",
+       "allpages": "Բոլոր էջերը",
+       "allarticles": "Բոլոր էջերը",
+       "allpagessubmit": "‎Յառաջանալ",
+       "allpages-hide-redirects": "Թաքցնել վերայղումները",
+       "categories": "Ստորոգութիւններ",
+       "listgrouprights-members": "(անդամներու ցանկ)",
+       "emailuser": "էլ-նամակ ուղարկել այս մասնակիցին",
+       "usermessage-editor": "Համակարգային սուրհանդակի անուն",
+       "watchlist": "Հսկողութեան ցանկ",
+       "mywatchlist": "Հսկողութեան ցանկ",
+       "watchlistfor2": "$1 $2-ի համար",
+       "watch": "Հսկել",
+       "unwatch": "Հանել հսկումէն",
+       "watchlist-details": "Ձեր հսկողութեան ցանկը ունի {{PLURAL:$1|$1 էջ}}` (առաւել քննարկման էջեր)։",
+       "wlheader-showupdated": "Ձեր վերջին այցելութենէն ետք փոփոխուած Էջերը տրուած են <strong>շեշտուած տառերով<strong>։",
+       "wlnote": "Ներքեւ տրուած {{PLURAL:$1|է վերջին փոփոխութիւնը|են վերջին '''$1''' փոփոխութիւնները}} վերջին <strong>$2</strong> ժամուան ընթացքին՝ $3, $4ի դրութեամբ։",
+       "wlshowlast": "Ցոյց տալ վերջին $1 ժամերը $2 օրերը",
+       "watchlist-options": "Հսկողութեան ացանկի նախընտրութիւններ",
+       "enotif_reset": "Նշել բոլոր  այցելուած էջերը",
+       "dellogpage": "Ջնջումներու տեղեկատետր",
+       "rollbacklink": "Նախորդ տարբերակը ետ բերել",
+       "rollbacklinkcount": "Յետարկում $1 {{PLURAL:$1|խմբագրում|խմբագրումներ}}",
+       "protectlogpage": "Պահպանման տեղեկատետր",
+       "protectedarticle": "պահպանուեցաւ «[[$1]]» էջը",
+       "modifiedarticleprotection": "պահպանութեան մակարդակը փոխուեցաւ «[[$1]]» էջին համար",
+       "protect-default": "Թոյլատրել բոլոր մասնակիցներուն",
+       "restriction-edit": "Խմբագրել",
+       "restriction-move": "Տեղափոխել այս էջը",
+       "namespace": "Անուանատարածք՝",
+       "invert": "Ընտրութիւնը շրջել",
+       "tooltip-invert": "Նշեցէ՛ք տուփիկը թաքցնելու համար տուեալ անուանատարածքի եւ կից անուանատարածքներու (եթէ նշուած է) էջերու վրայի փոփոխութիւնները ։",
+       "namespace_association": "Առնչուած անուանատարածք",
+       "tooltip-namespace_association": "Նշեցէ՛ք տուփիկը՝ ներառնելու համար տուեալ անուանատարածքին հետ կապուած քննարկումները կամ նիւթերու անուանատարածքը նոյնպէս։",
+       "blanknamespace": "(Գլխաւոր)",
+       "contributions": "{{GENDER:$1|Մասնակիցի}} ներդրումները",
+       "contributions-title": "$1 մասնակիցի ներդրումը",
+       "mycontris": "Ներդրումներ",
+       "anoncontribs": "Ներդրումներ",
+       "contribsub2": "{{GENDER:$3|$1}}ի ներդրումները ($2)",
+       "nocontribs": "Այս չափանիշներուն համապատասխանող փոփոխութիւններ չգտնուեցան։",
+       "uctop": "(ընթացիկ)",
+       "month": "Սկսած ամիսէն (եւ աւելի վաղ)՝",
+       "year": "Սկսեալ տարիէն (եւ աւելի վաղ)՝",
+       "sp-contributions-newbies": "Ցոյց տալ միայն նոր հաշիւներէ եղած ներդրումները",
+       "sp-contributions-blocklog": "արգելակումներու տեղեկատետր",
+       "sp-contributions-uploads": "վերբեռնումներ",
+       "sp-contributions-logs": "Տեղեկատետրեր",
+       "sp-contributions-talk": "Քննարկում",
+       "sp-contributions-search": "Որոնել ներդրումները",
+       "sp-contributions-username": "IP-հասցէ կամ մասնակիցի անուն.",
+       "sp-contributions-toponly": "Ցոյց տալ միայն վերջին տարբերակի խմբագրումները",
+       "sp-contributions-newonly": "Ցոյց տալ միայն էջ ստեղծող խմբագրումները",
+       "sp-contributions-submit": "Որոնել",
+       "whatlinkshere": "Այստեղ յղող էջեր",
+       "whatlinkshere-title": "Էջեր որոնք կը յղեն դէպի «$1»",
+       "whatlinkshere-page": "Էջ",
+       "linkshere": "Հետևեալ էջերը կը յղուին  <strong>$2</strong> էջին՝",
+       "nolinkshere": "<strong>$2</strong>ին յղուող էջեր չկան։",
+       "isredirect": "վերայղման էջ",
+       "istemplate": "ներառում",
+       "isimage": "Նիշքի յղում",
+       "whatlinkshere-prev": "{{PLURAL:$1|նախորդ|նախորդ $1}}",
+       "whatlinkshere-next": "{{PLURAL:$1|յաջորդ|յաջորդ $1}}",
+       "whatlinkshere-links": "← յղումներ",
+       "whatlinkshere-hideredirs": "$1 վերայղումները",
+       "whatlinkshere-hidetrans": "$1 ներառումները",
+       "whatlinkshere-hidelinks": "$1 յղումները",
+       "whatlinkshere-hideimages": "$1 նիշքի յղումները",
+       "whatlinkshere-filters": "Զտիչներ",
+       "ipboptions": "2 ժամ:2 hours,1 օր:1 day,3 օր:3 days,1 շաբաթ:1 week,2 շաբաթ:2 weeks,1 ամիս:1 month,3 ամիս:3 months,6 ամիս:6 months,1 տարի:1 year,անժամկէտ:infinite",
+       "infiniteblock": "Միշտ",
+       "blocklink": "‎Արգելակել",
+       "contribslink": "Ներդրումներ",
+       "blocklogpage": "արգելակումներու տեղեկատետր",
+       "blocklogentry": "արգելակուած [[$1]] մասնակից $2 տեւողութեամբ (Պատճառը՝ $3)",
+       "reblock-logentry": "փոխեց [[$1]] մասնակիցի արգելակումը՝ աւարտման $2 $3 ժամով",
+       "block-log-flags-nocreate": "մասնակցային հաշիւի ստեղծումը արգիլուած է",
+       "proxyblocker": "Փոխանորդի արգելակում",
+       "movelogpage": "Տեղափոխութիւններու տեղեկատետր",
+       "export": "Արտածել էջերը",
+       "thumbnail-more": "Մեծցնել",
+       "importlogpage": "Ներմուծման տեղեկատետր",
+       "tooltip-pt-userpage": "{{GENDER:|Ձեր մասնակիցի}} էջը",
+       "tooltip-pt-mytalk": "{{GENDER:|Ձեր}} քննարկման էջը",
+       "tooltip-pt-preferences": "{{GENDER:|Ձեր}} նախընտրութիւնները",
+       "tooltip-pt-watchlist": "Ձեր հսկողութեան տակ գտնուող էջերու ցանկը",
+       "tooltip-pt-mycontris": "{{GENDER:|ձեր}} ներդրումներու ցանկը",
+       "tooltip-pt-login": "Կը քաջալերենք մուտք գործել համակարգ, թէեւ պարտադիր չէ",
+       "tooltip-pt-logout": "Դուրս գալ",
+       "tooltip-pt-createaccount": "Կը քաջալերենք հաշիւ ստեղծել եւ անով մուտք գործել համակարգ, թէեւ պարտադիր չէ",
+       "tooltip-ca-talk": "Բովանդակութեան էջի քննարկում",
+       "tooltip-ca-edit": "Խմբագրէ՛ այս էջը",
+       "tooltip-ca-addsection": "Ստեղծել նոր բաժին",
+       "tooltip-ca-viewsource": "Այս էջը պահպանուած է։ \nԿրնաք տեսնել անոր աղբիւրը",
+       "tooltip-ca-history": "Այս էջի նախորդ խմբագրումները",
+       "tooltip-ca-protect": "Պահպանել այս էջը",
+       "tooltip-ca-delete": "Ջնջել այս էջը",
+       "tooltip-ca-move": "Տեղափոխել այս էջը",
+       "tooltip-ca-watch": "Այս էջը աւելցնել հսկողութեան ցանկիդ վրան",
+       "tooltip-ca-unwatch": "Հանել այս էջը ձեր հսկողութեան ցանկէն",
+       "tooltip-search": "Որոնել {{SITENAME}} կայքին մէջ",
+       "tooltip-search-go": "Անցնիլ դէպի նոյնանուն էջ, եթէ գոյութիւն ունի",
+       "tooltip-search-fulltext": "Որոնել այս գրութիւնը պարունակող էջերը",
+       "tooltip-p-logo": "Այցելել գլխաւոր էջը",
+       "tooltip-n-mainpage": "Այցելել գլխաւոր էջը",
+       "tooltip-n-mainpage-description": "Այցելել գլխաւոր էջը",
+       "tooltip-n-portal": "Նախագիծին մասին. ինչ կրնաս ընել, ուր կրնաս գտնել",
+       "tooltip-n-currentevents": "Տեղեկութիւններ ընթացիկ իրադարձութիւններու մասին",
+       "tooltip-n-recentchanges": "Ուիքիին մէջ կատարուած վերջին փոփոխութիւններու ցանկը",
+       "tooltip-n-randompage": "Այցելել պատահական էջ մը",
+       "tooltip-n-help": "Գտնելու տեղը",
+       "tooltip-t-whatlinkshere": "Այս էջին յղուող բոլոր ուիքի էջերու ցանկը",
+       "tooltip-t-recentchangeslinked": "Այս էջին կապուած էջերուն վերջին փոփոխութիւնները",
+       "tooltip-feed-atom": "Այս էջին Աթոմ սնուցումը",
+       "tooltip-t-contributions": "{{GENDER:$1|այս մասնակիցին}} ներդրումներուն ցանկը",
+       "tooltip-t-emailuser": "Իմակ ուղարկել {{GENDER:$1|այս մասնակիցին}}",
+       "tooltip-t-upload": "Վերբեռնել նիշքեր",
+       "tooltip-t-specialpages": "Բոլոր յատուկ էջերու ցանկ",
+       "tooltip-t-print": "Այս էջին տպագրելի տարբերակը",
+       "tooltip-t-permalink": "Էջի այս տարբերակին մնայուն յղումը",
+       "tooltip-ca-nstab-main": "Տեսնել բովանդակութեան էջը",
+       "tooltip-ca-nstab-user": "Տեսնել մասնակիցին էջը",
+       "tooltip-ca-nstab-special": "Ասիկա յատուկ էջ է եւ կարելի չէ խմբագրել",
+       "tooltip-ca-nstab-project": "Տեսնել նախագիծի էջը",
+       "tooltip-ca-nstab-image": "Տեսնել նիշքի էջը",
+       "tooltip-ca-nstab-mediawiki": "Տեսնել համակարգային հաղորդագրութիւնը",
+       "tooltip-ca-nstab-template": "Տեսնել կաղապարը",
+       "tooltip-ca-nstab-category": "Տեսնել ստորոգութեան էջը",
+       "tooltip-minoredit": "Նշել որպէս չնչին խմբագրում",
+       "tooltip-save": "Պահել ձեր փոփոխութիւնները",
+       "tooltip-preview": "Կանխաստուգել ձեր կատարած փոխոխութիւնները։  Կը խնդրուի օգտուիլ անկէ նախքան պահելը։",
+       "tooltip-diff": "Ցոյց տալ ձեր կատարած փոփոխութիւնները գրութեան մէջ",
+       "tooltip-compareselectedversions": "Տեսնել այս էջին ընտրուած երկու տարբերակներուն միջեւ տարբերութիւնները",
+       "tooltip-watch": "Աւելցնել այս էջը ձեր հսկողութեան ցանկին վրայ",
+       "tooltip-rollback": "«Յետարկում»ը մէկ սեղմումով վերջին մասնակիցին կատարած բոլոր խմբագրումները ետ կ՚ընէ",
+       "tooltip-undo": "«Յետարկել»ը կը շրջէ կատարուած փոփոխութիւնը եւ խմբագրումը կը տրամադրէ կանխաստուգման վիճակով, թոյլ տալով նշել պատճառը ամփոփումին մէջ։",
+       "tooltip-summary": "Մուտքագրեցէ՛ք հակիրճ ամփոփում մը",
+       "simpleantispam-label": "Հակա–լցոնային ստուգում։\n<strong>Մի՛</strong> ամբողջացնէք ասիկա։",
+       "pageinfo-title": "$1-ի տուեալները",
+       "pageinfo-header-basic": "Հիմնական տուեալներ",
+       "pageinfo-header-edits": "Խմբագրել պատմութիւնը",
+       "pageinfo-header-restrictions": "Էջի պահպանութիւն",
+       "pageinfo-header-properties": "Էջի յատկանիշներ",
+       "pageinfo-display-title": "Վերնագիր",
+       "pageinfo-default-sort": "Միախմբումի ակամայ բանալի",
+       "pageinfo-length": "էջի երկայնք (պայթերով)",
+       "pageinfo-article-id": "Էջի ինքնութեան համար",
+       "pageinfo-language": "Բովանդակութեան լեզու",
+       "pageinfo-content-model": "Էջի պարունակութեան բնատիպ",
+       "pageinfo-robot-policy": "Մեքենայական ցուցակագրում",
+       "pageinfo-robot-index": "Արտօնուած",
+       "pageinfo-robot-noindex": "Էջը կարելի չէ ցուցակագրել",
+       "pageinfo-watchers": "Էջը նայողներու թիւը",
+       "pageinfo-few-watchers": "$1էն պակաս {{PLURAL:$1|հսկող|հսկողներ}}",
+       "pageinfo-redirects-name": "Դէպի այս էջ վերայղումներու թիւ",
+       "pageinfo-subpages-name": "Ենթաէջերու թիւը",
+       "pageinfo-subpages-value": "$1 ($2 {{PLURAL:$2|վերայղում}}; $3 {{PLURAL:$3|ոչ-վերայղում}})",
+       "pageinfo-firstuser": "Էջը ստեղծողը",
+       "pageinfo-firsttime": "Էջի ստեղծման թուականը",
+       "pageinfo-lastuser": "Վերջին խմբագրող",
+       "pageinfo-lasttime": "Վերջին խմբագրման թուական",
+       "pageinfo-edits": "Խմբագրումներու ընդհանուր գումար",
+       "pageinfo-authors": "Անջատ հեղինակներու ընդհանուր գումար",
+       "pageinfo-recent-edits": "Վերջին խմբագրումներու գումարը (վերջին $1)",
+       "pageinfo-recent-authors": "Անջատ հեղինակներու վերջին գումարը",
+       "pageinfo-magic-words": "Կախարդական {{PLURAL:$1|բառ|բառեր}} ($1)",
+       "pageinfo-hidden-categories": "Թաքուն {{PLURAL:$1|խմբաւորում|խմբաւորումներ}} ($1)",
+       "pageinfo-templates": "Օգտագործուած {{PLURAL:$1|կաղապար|կաղապարներ}} ($1)",
+       "pageinfo-toolboxlink": "‎Էջի մասին տեղեկութիւն",
+       "pageinfo-contentpage": "Իբրեւ բովանդակութեան էջ հաշուըւած",
+       "pageinfo-contentpage-yes": "Այո",
+       "patrol-log-page": "Հսկողութեան տեղեկատետր",
+       "previousdiff": "← Նախորդ խմբագրում",
+       "nextdiff": "Յաջորդ խմբագրում →",
+       "widthheightpage": "$1 × $2, $3 {{PLURAL:$3|էջ}}",
+       "file-info-size": "$1 × $2 կէտիկներ, նիշքի չափը՝ $3, MIME-տեսակը՝ $4",
+       "file-info-size-pages": "$1 × $2 կէտիկ, նիշքի չափը՝ $3, MIME տեսակը՝ $4, $5 {{PLURAL:$5|էջ}}",
+       "file-nohires": "Աւելի բարձր կէտաչափով տարբերակ չկայ։",
+       "svg-long-desc": "SVG նիշք, անուանապէս $1 × $2 կէտիկ, նիշքի չափը՝ $3",
+       "show-big-image": "Սկզբնական նիշք",
+       "show-big-image-preview": "Կանխաստուգման չափը՝ $1։",
+       "show-big-image-other": "Այլ {{PLURAL:$2|1=չափ|չափեր}}: $1.",
+       "show-big-image-size": "$1 × $2 կէտիկ",
+       "metadata": "Անդրտուեալներ",
+       "metadata-help": "Նիշքը յաւելեալ տեղեկութիւններ կը պարունակէ, հաւանաբար աւելցուած թուային լուսանկարչական գործիքէն կամ հպահանէն, զանոնք ստեղծելու կամ թուայնացնելու ծառայող։\nԵթէ նիշքը ձեւափոխուած է իր սկզբնական վիճակէն, ապա որոշ մանրամասնութիւններ կրնան չհամապատասխանել ձեւափոխուած նիշքին։",
+       "metadata-fields": "Այս գիրին մէջ նշուած պատկերի անդրտուեալներու դաշտերը պիտի երեւին պատկերի էջին վրայ երբ անդրտուեալներու աղիւսակը ծալլուի։\nՄիւսները ակամայ կը մնան թաքուն։\n* make\n* model\n* datetimeoriginal\n* exposuretime\n* fnumber\n* isospeedratings\n* focallength\n* artist\n* copyright\n* imagedescription\n* gpslatitude\n* gpslongitude\n* gpsaltitude",
+       "exif-orientation": "Արեւելում",
+       "exif-xresolution": "Հորիզոնական կէտաչափ",
+       "exif-yresolution": "Ուղղահայեաց կէտաչափ",
+       "exif-datetime": "Նիշքի փոփոխութեան թուական եւ ժամանակ",
+       "exif-make": "Լուսանկարչական գործիքի արտադրող",
+       "exif-model": "Լուսանկարչական գործիքի տիպ",
+       "exif-software": "Օգտագործուած ծրագիր",
+       "exif-exifversion": "Exifի տարբերակ",
+       "exif-colorspace": "գունատարածք",
+       "exif-datetimeoriginal": "Տուեալի արտադրման թուական եւ ժամանակ",
+       "exif-datetimedigitized": "Թուայնացման թուականը եւ ժամը",
+       "exif-orientation-1": "Բնական",
+       "namespacesall": "բոլոր",
+       "monthsall": "բոլոր",
+       "imgmultipagenext": "յաջորդ էջը →",
+       "imgmultigo": "Անցնի՛լ",
+       "imgmultigoto": "Անցնիլ $1 էջը",
+       "watchlisttools-clear": "Մաքրել հսկողութեան ցանկը",
+       "watchlisttools-view": "Ցուցադրել փոփոխութիւնները",
+       "watchlisttools-edit": "Տեսնել եւ խմբագրել հսկողութեան ցանկը",
+       "watchlisttools-raw": "Խմբագրել հում հսկողութեան ցանկը",
+       "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|քննարկում]])",
+       "redirect": "Վերայղում նիշքի, մասնակիցի, էջի, տարբերակի կամ տեղեկատետրի ինքնութեան համարէն",
+       "redirect-summary": "Այս յատուկ էջը կը վերայղուի նիշքի մը (տրուած ըլլալով նիշքին անունը), էջի մը (տրուած ըլլալով վերանայման կամ էջի ինքնութեան համարը), մասնակիցի էջի մը. տրուած ըլլալով մասնակիցի մը թուային ինքնութեան համարը), եւ կամ տեղեկատետրի մը մէջ տողի մը, (տրուած ըլլալով տեղեկատետրի ինքնութեան համարը)։ Գործածութիւն՝  [[{{#Special:Redirect}}/file/Example.jpg]], [[{{#Special:Redirect}}/page/64308]], [[{{#Special:Redirect}}/revision/328429]], [[{{#Special:Redirect}}/user/101]], or [[{{#Special:Redirect}}/logid/186]].",
+       "redirect-submit": "Յառաջ",
+       "redirect-lookup": "Որոնում՝",
+       "redirect-value": "Արժէք՝",
+       "redirect-user": "Մասնակիցի ինքնութեան համար",
+       "redirect-page": "Էջի ինքնութեան համար",
+       "redirect-revision": "Էջի տարբերակներ",
+       "redirect-file": "Նիշքի անունը",
+       "specialpages": "Յատուկ էջեր",
+       "tag-filter": "[[Special:Tags|Պիտակներու]] զտիչ՝",
+       "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|Պիտակ}}]]: $2)",
+       "tags-active-yes": "Այո",
+       "tags-active-no": "Ոչ",
+       "tags-hitcount": "{{PLURAL:$1|փոփոխութիւն}}",
+       "logentry-delete-delete": "$1 {{GENDER:$2|ջնջեց}} $3 էջը",
+       "logentry-delete-restore": "$1 {{GENDER:$2|վերականգնեց}} $3 ($4) էջը",
+       "logentry-delete-revision": "$1 {{GENDER:$2|փոխեց}} {{PLURAL:$5|1 խմբագրման|$5 խմբագրումներու}} տեսանելիութիւնը $3 էջին վրայ՝ $4",
+       "revdelete-content-hid": "բովանդակութիւնը թաքնուած",
+       "logentry-move-move": "$1 տեղափոխեց էջը «$3»-էն «$4»",
+       "logentry-move-move-noredirect": "$1ը {{GENDER:$2|տեղափոխեց}} էջ $3էն էջ $4 առանց վերայղում ձգելու",
+       "logentry-move-move_redir": "$1 {{GENDER:$2|տեղափոխեց}} էջ $3ը վերայղելով դէպի էջ $4",
+       "logentry-patrol-patrol-auto": "$1 ինքնաշխատ ձեւով {{GENDER:$2|ստուգուած նշեց}} $3 էջի $4 տարբերակը",
+       "logentry-newusers-create": "$1 մասնակիցին հաշիւը {{GENDER:$2|ստեղծուեցաւ}}",
+       "logentry-newusers-autocreate": "$1 մասնակցային հաշիւը {{GENDER:$2|ստեղծուած է}} ինքնաբերաբար",
+       "logentry-upload-upload": "$1 {{GENDER:$2|ներբեռնուած է}} $3",
+       "logentry-upload-overwrite": "$1 {{GENDER:$2|վերբեռնեց}} $3ի նոր տարբերակ",
+       "searchsuggest-search": "Որոնել {{SITENAME}} կայքին մէջ",
+       "duration-days": "$1 {{PLURAL:$1|օր}}",
+       "randomrootpage": "Պատահական արմատ էջ"
+}
index 695f247..48828ae 100644 (file)
        "resetpass-submit-loggedin": "Cambiar contrasigno",
        "resetpass-submit-cancel": "Cancellar",
        "resetpass-wrong-oldpass": "Le contrasigno temporari o actual es invalide.\nEs possibile que tu ha ja cambiate tu contrasigno o requestate un nove contrasigno temporari.",
-       "resetpass-recycled": "Redefini tu contrasigno a un differente del actual, per favor.",
+       "resetpass-recycled": "Cambia tu contrasigno a un differente del actual, per favor.",
        "resetpass-temp-emailed": "Tu ha aperite session con un codice temporari que tu recipeva in e-mail.\nPro completar le accesso, tu debe definir un nove contrasigno hic:",
        "resetpass-temp-password": "Contrasigno temporari:",
        "resetpass-abort-generic": "Le cambio del contrasigno ha essite abortate per un extension.",
        "resetpass-expired": "Le contrasigno ha expirate. Per favor defini un nove contrasigno pro aperir session.",
-       "resetpass-expired-soft": "Le contrasigno ha expirate e debe esser redefinite. Per favor elige un nove contrasigno ora, o clicca sur \"{{int:authprovider-resetpass-skip-label}}\" pro redefinir lo plus tarde.",
-       "resetpass-validity-soft": "Le contrasigno non es valide: $1\n\nPer favor elige un nove contrasigno ora, o clicca sur \"{{int:authprovider-resetpass-skip-label}}\" pro redefinir lo plus tarde.",
+       "resetpass-expired-soft": "Le contrasigno ha expirate e debe esser cambiate. Per favor, elige un nove contrasigno ora, o clicca sur \"{{int:authprovider-resetpass-skip-label}}\" pro cambiar lo plus tarde.",
+       "resetpass-validity-soft": "Le contrasigno non es valide: $1\n\nPer favor, elige un nove contrasigno ora, o clicca sur \"{{int:authprovider-resetpass-skip-label}}\" pro cambiar lo plus tarde.",
        "passwordreset": "Reinitialisar contrasigno",
        "passwordreset-text-one": "Completa iste formulario pro reinitialisar tu contrasigno.",
        "passwordreset-text-many": "{{PLURAL:$1|Completa un de iste campos pro reciper un contrasigno temporari in e-mail.}}",
        "expansion-depth-exceeded-category": "Paginas in que le profunditate de expansion excede le limite",
        "expansion-depth-exceeded-category-desc": "Le pagina excede le profunditate de expansion maxime.",
        "expansion-depth-exceeded-warning": "Le profunditate de expansion in iste pagina excede le limite",
-       "parser-unstrip-loop-warning": "Bucla de \"unstrip\" detegite",
-       "unstrip-depth-warning": "Limite de recursion de \"unstrip\" excedite ($1)",
+       "parser-unstrip-loop-warning": "Bucla detegite in le function \"unstrip\"",
+       "unstrip-depth-warning": "Limite de profunditate de \"unstrip\" excedite ($1)",
+       "unstrip-depth-category": "Paginas con recursion excessive de \"unstrip\"",
+       "unstrip-size-warning": "Limite de dimension de \"unstrip\" excedite ($1)",
+       "unstrip-size-category": "Paginas con dimension excessive de \"unstrip\"",
        "converter-manual-rule-error": "Error detegite in le regula manual de conversion de lingua",
        "undo-success": "Le modification pote esser disfacite.\nPer favor controla le comparation infra pro verificar que tu vole facer isto, e postea salveguarda le modificationes infra pro assi disfacer le modification.",
        "undo-failure": "Le modification non poteva esser annullate a causa de conflicto con modificationes intermedie.",
+       "undo-main-slot-only": "Le modification non poteva esser disfacite perque illo implica contento foras del cannellatura principal.",
        "undo-norev": "Impossibile annullar le modification proque illo non existe o esseva delite.",
        "undo-nochange": "Pare que iste modification ha jam essite disfacite.",
        "undo-summary": "Annullava le version $1 per [[Special:Contributions/$2|$2]] ([[User talk:$2|Discussion]] | [[Special:Contributions/$2|{{MediaWiki:Contribslink}}]])",
        "prefs-watchlist-edits": "Numero maxime de modificationes a monstrar in le observatorio:",
        "prefs-watchlist-edits-max": "Numero maxime: 1000",
        "prefs-watchlist-token": "Indicio pro le observatorio:",
-       "prefs-watchlist-managetokens": "Gerer indicios",
+       "prefs-watchlist-managetokens": "Gerer claves",
        "prefs-misc": "Misc",
        "prefs-resetpass": "Cambiar contrasigno",
        "prefs-changeemail": "Cambiar o remover adresse de e-mail",
        "stub-threshold-disabled": "Disactivate",
        "recentchangesdays": "Numero de dies a monstrar in modificationes recente:",
        "recentchangesdays-max": "(non plus de $1 {{PLURAL:$1|die|dies}})",
-       "recentchangescount": "Numero de modificationes a monstrar per predefinition:",
-       "prefs-help-recentchangescount": "Isto include modificationes recente, historias de paginas, e registros.",
+       "recentchangescount": "Numero predefinite de modificationes a monstrar in le lista de modificationes recente, in le historias de paginas e in le registros:",
+       "prefs-help-recentchangescount": "Numero maxime: 1000",
        "prefs-help-watchlist-token2": "Isto es le clave secrete pro le syndication web de tu observatorio.\nOmne persona qui lo cognosce pote leger tu observatorio, dunque, non divide lo.\nIn caso de necessitate, [[Special:ResetTokens|clicca hic pro reinitialisar lo]].",
        "prefs-help-tokenmanagement": "Tu pote vider e reinitialisar le clave secrete pro tu conto que pote acceder al aggregator Web de tu observatorio. Tote persona que cognosce le clave potera leger tu observatorio, dunque non divulga lo.",
        "savedprefs": "Tu preferentias ha essite confirmate.",
        "default": "predefinite",
        "prefs-files": "Files",
        "prefs-custom-css": "CSS personalisate",
+       "prefs-custom-json": "JSON personalisate",
        "prefs-custom-js": "JS personalisate",
-       "prefs-common-config": "CSS/JS commun a tote le apparentias:",
+       "prefs-common-config": "CSS/JSON/JavaScript commun a tote le apparentias:",
        "prefs-reset-intro": "Iste pagina es pro reinitialisar tu preferentias al valores predefinite del sito.\nLe operation non pote esser disfacite.",
        "prefs-emailconfirm-label": "Confirmation del e-mail:",
        "youremail": "E-mail:",
        "prefs-dateformat": "Formato de data",
        "prefs-timeoffset": "Differentia de tempore",
        "prefs-advancedediting": "Optiones general",
+       "prefs-developertools": "Instrumentos pro disveloppatores",
        "prefs-editor": "Editor",
        "prefs-preview": "Previsualisation",
        "prefs-advancedrc": "Optiones avantiate",
        "right-editcontentmodel": "Modificar le modello de contento de un pagina",
        "right-editinterface": "Modificar le interfacie de usator",
        "right-editusercss": "Modificar le files CSS de altere usatores",
+       "right-edituserjson": "Modificar le files JSON de altere usatores",
        "right-edituserjs": "Modificar le files JS de altere usatores",
        "right-editmyusercss": "Modificar le proprie files CSS de usator",
-       "right-editmyuserjs": "Modificar le proprie files JavaScript de usator",
+       "right-editmyuserjson": "Modificar le files JSON del proprie usator",
+       "right-editmyuserjs": "Modificar le files JavaScript del proprie usator",
        "right-viewmywatchlist": "Vider le proprie observatorio",
        "right-editmywatchlist": "Modificar le proprie observatorio. Remarca que alcun actiones totevia adde paginas mesmo sin iste derecto.",
        "right-viewmyprivateinfo": "Vider le proprie datos private (p.ex. adresse de e-mail, nomine real)",
        "grant-createaccount": "Crear contos",
        "grant-createeditmovepage": "Crear, modificar e renominar paginas",
        "grant-delete": "Deler paginas, versiones e entratas de registro",
-       "grant-editinterface": "Modificar le spatio de nomines MediaWiki e le CSS/JavaScript de usatores",
-       "grant-editmycssjs": "Modificar le CSS/JavaScript del proprie usator",
+       "grant-editinterface": "Modificar le spatio de nomines MediaWiki e le CSS/JSON/JavaScript de usatores",
+       "grant-editmycssjs": "Modificar le CSS/JSON/JavaScript del proprie usator",
        "grant-editmyoptions": "Modificar tu preferentias de usator",
        "grant-editmywatchlist": "Modificar tu observatorio",
        "grant-editpage": "Modificar paginas existente",
        "rcfilters-other-review-tools": "Altere instrumentos de revision",
        "rcfilters-group-results-by-page": "Gruppar resultatos per pagina",
        "rcfilters-activefilters": "Filtros active",
+       "rcfilters-activefilters-hide": "Celar",
+       "rcfilters-activefilters-show": "Monstrar",
+       "rcfilters-activefilters-hide-tooltip": "Celar le area de filtros active",
+       "rcfilters-activefilters-show-tooltip": "Monstrar le area de filtros active",
        "rcfilters-advancedfilters": "Filtros avantiate",
        "rcfilters-limit-title": "Resultatos a monstrar",
        "rcfilters-limit-and-date-label": "$1 modification{{PLURAL:$1||es}}, $2",
        "rcfilters-savedqueries-rename": "Renominar",
        "rcfilters-savedqueries-setdefault": "Predefinir",
        "rcfilters-savedqueries-unsetdefault": "Remover predefinition",
-       "rcfilters-savedqueries-remove": "Remover",
+       "rcfilters-savedqueries-remove": "Deler",
        "rcfilters-savedqueries-new-name-label": "Nomine",
        "rcfilters-savedqueries-new-name-placeholder": "Describe le proposito del filtro",
        "rcfilters-savedqueries-apply-label": "Crear filtro",
        "rcfilters-empty-filter": "Nulle filtro active. Tote le contributiones es monstrate.",
        "rcfilters-filterlist-title": "Filtros",
        "rcfilters-filterlist-whatsthis": "Como functiona istes?",
-       "rcfilters-filterlist-feedbacklink": "Da nos tu opinion sur iste (nove) instrumentos de filtrage",
+       "rcfilters-filterlist-feedbacklink": "Da nos tu opinion sur iste instrumentos de filtrage",
        "rcfilters-highlightbutton-title": "Colorar le resultatos",
        "rcfilters-highlightmenu-title": "Selige un color",
        "rcfilters-highlightmenu-help": "Selige un color pro illuminar iste proprietate",
        "rcfilters-filter-humans-label": "Persona (non robot)",
        "rcfilters-filter-humans-description": "Modificationes facite per esseres human.",
        "rcfilters-filtergroup-reviewstatus": "Stato de revision",
+       "rcfilters-filter-reviewstatus-unpatrolled-description": "Modificationes non marcate como patruliate, manual- o automaticamente.",
        "rcfilters-filter-reviewstatus-unpatrolled-label": "Non patruliate",
+       "rcfilters-filter-reviewstatus-manual-description": "Modificationes manualmente marcate como patruliate.",
+       "rcfilters-filter-reviewstatus-manual-label": "Patruliate manualmente",
+       "rcfilters-filter-reviewstatus-auto-description": "Modificationes per usatores avantiate cuje travalio se marca automaticamente como patruliate.",
+       "rcfilters-filter-reviewstatus-auto-label": "Autopatruliate",
        "rcfilters-filtergroup-significance": "Importantia",
        "rcfilters-filter-minor-label": "Modificationes minor",
        "rcfilters-filter-minor-description": "Modificationes que le autor ha marcate como minor.",
        "rcfilters-watchlist-showupdated": "Le modificationes del paginas que tu non ha visitate post que illos ha essite apportate se monstra in <strong>grasse</strong>, con marcatores solide.",
        "rcfilters-preference-label": "Celar le version meliorate del Modificationes recente",
        "rcfilters-preference-help": "Disface le nove interfacie de 2017 e tote le instrumentos addite alora e posta.",
+       "rcfilters-watchlist-preference-label": "Celar le version meliorate del observatorio",
+       "rcfilters-watchlist-preference-help": "Disface le redesigno del interfacie de 2017 e tote le instrumentos addite desde alora.",
        "rcfilters-filter-showlinkedfrom-label": "Monstrar modificationes sur paginas ligate ab",
        "rcfilters-filter-showlinkedfrom-option-label": "<strong>Paginas ligate ab</strong> le pagina seligite",
        "rcfilters-filter-showlinkedto-label": "Monstrar modificationes sur paginas que liga a",
        "deadendpages": "Paginas sin exito",
        "deadendpagestext": "Le sequente paginas non ha ligamines a altere paginas in {{SITENAME}}.",
        "protectedpages": "Paginas protegite",
+       "protectedpages-filters": "Filtros:",
        "protectedpages-indef": "Solmente protectiones infinite",
        "protectedpages-summary": "Iste pagina lista paginas existente que es actualmente protegite. Pro un lista de titulos protegite contra creation, vide [[{{#special:ProtectedTitles}}|{{int:protectedtitles}}]].",
        "protectedpages-cascade": "Protectiones in cascada solmente",
        "protectedtitles-submit": "Monstrar titulos",
        "listusers": "Lista de usatores",
        "listusers-editsonly": "Monstrar solmente usatores con modificationes",
+       "listusers-temporarygroupsonly": "Monstrar solmente usatores in gruppos temporari",
        "listusers-creationsort": "Ordinar per data de creation",
        "listusers-desc": "Ordinar in senso descendente",
        "usereditcount": "$1 {{PLURAL:$1|modification|modificationes}}",
        "apisandbox-dynamic-parameters-add-label": "Adder parametro:",
        "apisandbox-dynamic-parameters-add-placeholder": "Nomine del parametro",
        "apisandbox-dynamic-error-exists": "Un parametro con le nomine \"$1\" jam existe.",
+       "apisandbox-templated-parameter-reason": "Iste [[Special:ApiHelp/main#main/templatedparams|parametro de patrono]] es offerite a base del {{PLURAL:$1|valor|valores}} of $2.",
        "apisandbox-deprecated-parameters": "Parametros obsolescente",
        "apisandbox-fetch-token": "Auto-reimpler le indicio",
+       "apisandbox-add-multi": "Adder",
        "apisandbox-submit-invalid-fields-title": "Alcun campos non es valide",
        "apisandbox-submit-invalid-fields-message": "Per favor, corrige le campos marcate e reproba.",
        "apisandbox-results": "Resultatos",
        "speciallogtitlelabel": "Objectivo (titulo o {{ns:user}}:nomine de usator):",
        "log": "Registros",
        "logeventslist-submit": "Monstrar",
+       "logeventslist-more-filters": "Altere filtros:",
+       "logeventslist-patrol-log": "Registro de patrulia",
+       "logeventslist-tag-log": "Registro de etiquettas",
        "all-logs-page": "Tote le registros public",
        "alllogstext": "Presentation combinate de tote le registros disponibile de {{SITENAME}}.\nPro restringer le presentation, selige un typo de registro, le nomine de usator (sensibile al majusculas e minusculas), o le pagina in question (etiam sensibile al majusculas e minusculas).",
        "logempty": "Le registro contine nihil pro iste pagina.",
        "dellogpage": "Registro de deletiones",
        "dellogpagetext": "Infra es un lista del plus recente deletiones.\nTote le horas es in le fuso horari del servitor.",
        "deletionlog": "registro de deletiones",
+       "log-name-create": "Registro de creation de paginas",
+       "log-description-create": "Infra es un lista del paginas create le plus recentemente.",
+       "logentry-create-create": "$1 {{GENDER:$2|creava}} le pagina $3",
        "reverted": "Revertite al version anterior",
        "deletecomment": "Motivo:",
        "deleteotherreason": "Motivo altere/additional:",
        "uctop": "(ultime)",
        "month": "A partir del mense (e anterior):",
        "year": "A partir del anno (e anterior):",
+       "date": "A partir del data (e anterior):",
        "sp-contributions-newbies": "Monstrar contributiones de nove contos solmente",
        "sp-contributions-newbies-sub": "Pro nove contos",
        "sp-contributions-newbies-title": "Contributiones de nove contos de usator",
        "whatlinkshere": "Paginas ligate a iste",
        "whatlinkshere-title": "Paginas con ligamines verso $1",
        "whatlinkshere-page": "Pagina:",
-       "linkshere-2": "Le sequente paginas contine ligamines a '''$1''':",
-       "nolinkshere-2": "Nulle pagina contine un ligamine verso '''$1'''.",
-       "nolinkshere-ns-2": "Nulle pagina liga a '''$1''' in le spatio de nomines seligite.",
+       "linkshere": "Le sequente paginas contine ligamines a <strong>$2</strong>:",
+       "nolinkshere": "Nulle pagina contine un ligamine a <strong>$2</strong>.",
+       "nolinkshere-ns": "Nulle pagina liga a <strong>$2</strong> in le spatio de nomines seligite.",
        "isredirect": "pagina de redirection",
        "istemplate": "transclusion",
        "isimage": "ligamine al file",
        "fix-double-redirects": "Actualisar tote le redirectiones que puncta verso le titulo original",
        "move-leave-redirect": "Lassar un redirection",
        "protectedpagemovewarning": "'''Attention:''' Iste pagina ha essite protegite de sorta que solmente usatores con privilegios de administrator pote renominar lo. Le ultime entrata del registro es fornite hic infra pro referentia:",
-       "semiprotectedpagemovewarning": "'''Nota:''' Iste pagina ha essite protegite de sorta que solmente usatores registrate pote renominar lo. Le ultime entrata del registro es fornite hic infra pro referentia:",
+       "semiprotectedpagemovewarning": "<strong>Nota:</strong> Iste pagina ha essite protegite de sorta que solmente usatores autoconfirmate pote renominar lo. Le ultime entrata del registro es fornite hic infra pro referentia:",
        "move-over-sharedrepo": "[[:$1]] jam existe in un repositorio commun. Si le file es renominate a iste titulo, illo supplantara le file commun.",
        "file-exists-sharedrepo": "Le nomine de file seligite es ja in uso in un repositorio partite.\nPer favor selige un altere nomine.",
        "export": "Exportar paginas",
        "thumbnail_dest_directory": "Impossibile crear directorio de destination",
        "thumbnail_image-type": "typo de imagine non supportate",
        "thumbnail_gd-library": "le configuration del bibliotheca GD es incomplete: manca le function $1",
+       "thumbnail_image-size-zero": "Le dimension del file de imagine pare esser zero.",
        "thumbnail_image-missing": "le file pare mancar: $1",
        "thumbnail_image-failure-limit": "Il ha habite recentemente troppo de tentativas fallite ($1 o plus) de generar iste miniatura. Per favor reproba plus tarde.",
        "import": "Importar paginas",
        "interlanguage-link-title": "$1 (in $2)",
        "common.css": "/* Le CSS placiate hic se applicara a tote le stilos */",
        "print.css": "/* Le CSS placiate hic influentiara le apparentia del paginas imprimite */",
+       "common.json": "/* Omne JSON hic essera cargate pro tote le usatores a cata cargamento de pagina. */",
        "common.js": "/* Omne JavaScript hic se executara pro tote le usatores a cata cargamento de pagina. */",
        "anonymous": "{{PLURAL:$1|Usator|Usatores}} anonyme de {{SITENAME}}",
        "siteuser": "Usator $1 de {{SITENAME}}",
        "markedaspatrollederrornotify": "Le marcar como patruliate ha fallite.",
        "patrol-log-page": "Registro de patrulia",
        "patrol-log-header": "Isto es un registro de versiones patruliate.",
-       "log-show-hide-patrol": "$1 le registro de versiones patruliate",
-       "log-show-hide-tag": "$1 registro de etiquettas",
        "confirm-markpatrolled-button": "OK",
        "confirm-markpatrolled-top": "Marcar le version $3 de $2 como patruliate?",
        "deletedrevision": "Deleva le ancian version $1",
        "watchlistedit-clear-titles": "Titulos:",
        "watchlistedit-clear-submit": "Rader le observatorio (isto es permanente!)",
        "watchlistedit-clear-done": "Tu observatorio ha essite radite.",
+       "watchlistedit-clear-jobqueue": "Tu observatorio es in curso de vacuation. Isto pote prender un certe tempore.",
        "watchlistedit-clear-removed": "{{PLURAL:$1|1 titulo|$1 titulos}} ha essite removite:",
        "watchlistedit-too-many": "Il ha troppo de paginas pro monstrar los hic.",
        "watchlisttools-clear": "Rader le observatorio",
        "version-specialpages": "Paginas special",
        "version-parserhooks": "Uncinos del analysator syntactic",
        "version-variables": "Variabiles",
+       "version-editors": "Editores",
        "version-antispam": "Prevention de spam",
        "version-other": "Altere",
        "version-mediahandlers": "Executores de media",
        "limitreport-templateargumentsize-value": "$1/$2 {{PLURAL:$2|byte|bytes}}",
        "limitreport-expansiondepth": "Maxime profunditate de expansion",
        "limitreport-expensivefunctioncount": "Numero de functiones analysator costose",
+       "limitreport-unstrip-depth": "Profunditate de recursion de \"unstrip\"",
+       "limitreport-unstrip-size": "Dimension de \"unstrip\" post expansion",
+       "limitreport-unstrip-size-value": "$1/$2 {{PLURAL:$2|byte|bytes}}",
        "expandtemplates": "Expander patronos",
        "expand_templates_intro": "Iste pagina special prende wikitexto e expande recursivemente tote le patronos in illo.\nIllo expande etiam le functiones del analysator syntactic como\n<code><nowiki>{{</nowiki>#language:…}}</code>, e variabiles como\n<code><nowiki>{{</nowiki>CURRENTDAY}}</code>.\nDe facto, illo expande quasi toto inter accolladas duple.",
        "expand_templates_title": "Titulo de contexto, pro {{FULLPAGENAME}} etc.:",
        "unlinkaccounts-success": "Le conto ha essite disligate.",
        "authenticationdatachange-ignored": "Le cambiamento del datos de authentication non ha succedite. Pote esser que nulle fornitor ha essite configurate?",
        "userjsispublic": "Nota ben: Subpaginas JavaScript non debe continer datos confidential perque altere usatores pote vider los.",
+       "userjsonispublic": "Nota ben: Subpaginas JSON non debe continer datos confidential perque altere usatores pote vider los.",
        "usercssispublic": "Nota ben: Subpaginas CSS non debe continer datos confidential perque altere usatores pote vider los.",
        "restrictionsfield-badip": "Adresse o intervallo IP non valide: $1",
        "restrictionsfield-label": "Intervallos IP permittite:",
        "pagedata-title": "Datos de pagina",
        "pagedata-text": "Iste pagina forni un interfacie de datos a paginas. Forni le titulo del pagina in le URL, usante le syntaxe de subpaginas.\n* Le negotiation de contento depende del capite \"Accept\" de tu cliente. Isto significa que le datos del pagina essera fornite in le formato que tu cliente prefere.",
        "pagedata-not-acceptable": "Nulle formato correspondente trovate. Typos MIME supportate: $1",
-       "pagedata-bad-title": "Titulo invalide: $1."
+       "pagedata-bad-title": "Titulo invalide: $1.",
+       "unregistered-user-config": "Pro motivos de securitate, subpaginas de usator con JavaScript, CSS e JSON non pote esser cargate pro usatores non registrate.",
+       "passwordpolicies": "Politicas de contrasigno",
+       "passwordpolicies-summary": "Isto es un lista de politicas de contrasigno in vigor pro le gruppos de usatores definite in iste wiki.",
+       "passwordpolicies-group": "Gruppo",
+       "passwordpolicies-policies": "Politicas",
+       "passwordpolicies-policy-minimalpasswordlength": "Le contrasigno debe continer al minus $1 {{PLURAL:$1|character|characteres}}",
+       "passwordpolicies-policy-minimumpasswordlengthtologin": "Le contrasigno debe continer al minus $1 {{PLURAL:$1|character|characteres}} pro poter aperir session",
+       "passwordpolicies-policy-passwordcannotmatchusername": "Le contrasigno non pote esser identic al nomine de usator",
+       "passwordpolicies-policy-passwordcannotmatchblacklist": "Le contrasigno non pote corresponder a contrasignos in le lista nigre",
+       "passwordpolicies-policy-maximalpasswordlength": "Le contrasigno debe continer minus de $1 {{PLURAL:$1|character|characteres}}",
+       "passwordpolicies-policy-passwordcannotbepopular": "Le contrasigno non pote esser {{PLURAL:$1|le contrasigno le plus popular|in le lista de $1 contrasignos popular}}"
 }
index 631fc26..fc966d7 100644 (file)
        "listingcontinuesabbrev": "samb.",
        "index-category": "Halaman yang diindeks",
        "noindex-category": "Halaman yang diindeks",
-       "broken-file-category": "Halaman dengan gambar rusak",
+       "broken-file-category": "Halaman dengan berkas rusak",
        "categoryviewer-pagedlinks": "($1) ($2)",
        "about": "Tentang",
        "article": "Halaman isi",
        "whatlinkshere": "Pranala balik",
        "whatlinkshere-title": "Halaman yang memiliki pranala ke \"$1\"",
        "whatlinkshere-page": "Halaman:",
-       "linkshere-2": "Halaman-halaman berikut ini memiliki pranala ke '''$1''':",
-       "nolinkshere-2": "Tidak ada halaman yang memiliki pranala ke '''$1'''.",
-       "nolinkshere-ns-2": "Tidak ada halaman yang memiliki pranala ke '''$1''' pada ruang nama yang dipilih.",
+       "linkshere": "Halaman-halaman berikut ini memiliki pranala ke '''$2''':",
+       "nolinkshere": "Tidak ada halaman yang memiliki pranala ke '''$2'''.",
+       "nolinkshere-ns": "Tidak ada halaman yang memiliki pranala ke '''$2''' pada ruang nama yang dipilih.",
        "isredirect": "halaman pengalihan",
        "istemplate": "tranklusi",
        "isimage": "pranala berkas",
        "markedaspatrollederrornotify": "Menandai sebagai terpatroli gagal.",
        "patrol-log-page": "Log patroli",
        "patrol-log-header": "Ini adalah log revisi terpatroli.",
-       "log-show-hide-patrol": "$1 log patroli",
-       "log-show-hide-tag": "log tag $1",
        "confirm-markpatrolled-button": "OK",
        "confirm-markpatrolled-top": "Tandai revisi $3 dari $2 sebagai terperiksa?",
        "deletedrevision": "Revisi lama yang dihapus $1",
index e802ab6..6f6d173 100644 (file)
        "whatlinkshere": "Referenties a ti-ci págine",
        "whatlinkshere-title": "Págines quo liga por \"$1\"",
        "whatlinkshere-page": "Págine:",
-       "linkshere-2": "Li sequent págines liga por '''$1''':",
-       "nolinkshere-2": "Nequant págine liga por '''$1'''.",
+       "linkshere": "Li sequent págines liga por '''$2''':",
+       "nolinkshere": "Nequant págine liga por '''$2'''.",
        "isredirect": "págine de redirecterion",
        "istemplate": "inclusion",
        "isimage": "referentie a un file",
index d2567cc..e154b98 100644 (file)
        "whatlinkshere": "Ihe na bia nga",
        "whatlinkshere-title": "Ihü ná gá \"$1\" shí jikodo",
        "whatlinkshere-page": "Ihü:",
-       "linkshere-2": "Ihüá na gá '''$1''':",
-       "nolinkshere-2": "Ọ díghị ihü na jikodo gá '''$1'''.",
-       "nolinkshere-ns-2": "Ọ díghị ihü na jikodo gá '''$1''' na áhàámá nke Í chọrọ.",
+       "linkshere": "Ihüá na gá '''$2''':",
+       "nolinkshere": "Ọ díghị ihü na jikodo gá '''$2'''.",
+       "nolinkshere-ns": "Ọ díghị ihü na jikodo gá '''$2''' na áhàámá nke Í chọrọ.",
        "isredirect": "ihü nke nkúfù",
        "istemplate": "ọ jè ákwúkwó usòrò",
        "isimage": "jikodo nnunuuche",
index 4775c24..e174f14 100644 (file)
@@ -9,7 +9,8 @@
                        "לערי ריינהארט",
                        "아라",
                        "Macofe",
-                       "Nemo bis"
+                       "Nemo bis",
+                       "Matěj Suchánek"
                ]
        },
        "tog-underline": "Pinag-ugisan ti silpo:",
        "botpasswords-existing": "Dagiti adda a kontrasenias ti bot",
        "botpasswords-createnew": "Agpartuat iti baro a kontrasenias ti bot",
        "botpasswords-editexisting": "Urnosen ti maysa nga adda a kontrasenias ti bot",
+       "botpasswords-label-needsreset": "(nasken a maisaad manen ti kontrasenias)",
        "botpasswords-label-appid": "Nagan ti bot:",
        "botpasswords-label-create": "Agpartuat",
        "botpasswords-label-update": "Pabaruen",
        "subject-preview": "Panangipadas ti suheto:",
        "previewerrortext": "Adda napasamak a maysa a biddut bayat a nagpadpadas kadagiti binawbaliwam.",
        "blockedtitle": "Naseraan ti agar-aramat",
-       "blockedtext": "<strong>Naseraan ti naganmo nga agar-aramat wenno ti adres ti IP.</strong>\n\nTi serra ket inaramid babaen ni $1. \nTi rason a naited ket <em>$2</em>.\n\n* Rugi ti serra: $8\n* Panagpaso ti serra: $6\n* Naikeddeng a serraanna: $7\n\nMabalinmo a kontaken ni $1 wenno sabali pay nga [[{{MediaWiki:Grouppage-sysop}}|administrador]] no kayatmo a maipalawag daytoy a panagserra.\nDimo mabalin nga aramaten ti ramit nga esuratan daytoy nga agar-aramat malaksid no adda napudno nga adres ti esurat a nainaganan iti [[Special:Preferences|pakabilangan ti kakaykayatm]] ken no saanka a naparitan nga agaramat iti daytoy.\nTi agdama nga adres ti IP ket $3, ti naserraan nga ID ket #$5. \nPangngaasi nga iramanmo amin dagiti salaysay dita ngato kadagiti ania man nga aramidem nga usisa.",
-       "autoblockedtext": "Ti bukodmo nga adres ti IP ket automatiko a naserraan ngamin ket inusar ti sabali nga agar-aramat, a sinerraan ni $1.\nTi rason nga inted ket:\n\n:<em>$2</em>\n\n* Rugi ti serra: $8\n* Panagpaso ti serra: $6\n* Naikeddenga a serraanna: $7\n\nMabalinmo a kontaken ni $1 wenno maysa kadagiti [[{{MediaWiki:Grouppage-sysop}}|administrador]] tapno maipalawag daytoy a panagserra.\n\nLaglagipem a saanmo a mabalin nga usaren ti \"esuratan daytoy nga agar-aramat\" a langa malaksid no addaanka ti napudno nga adres ti esurat a nakarehistro iti [[Special:Preferences|kakaykayatam]] ken saanka a naserraan manipud ti panagusar daytoy.\n\nTi agdama a bukodmo nga adres ti IP ket $3, ken ti ID ti naserraan ket #$5.\nPangngaasi nga iramanmo amin dagiti salaysay dita ngato kadagiti ania man nga aramidem nga usisa.",
+       "blockedtext": "<strong>Naseraan ti naganmo nga agar-aramat wenno ti adres ti IP.</strong>\n\nTi serra ket inaramid babaen ni $1. \nTi rason a naited ket <em>$2</em>.\n\n* Rugi ti serra: $8\n* Panagpaso ti serra: $6\n* Naikeddeng a serraanna: $7\n\nMabalinmo a kontaken ni $1 wenno sabali pay nga [[{{MediaWiki:Grouppage-sysop}}|administrador]] no kayatmo a maipalawag daytoy a panagserra.\nDimo mabalin nga aramaten ti ramit nga {{int:emailuser}} malaksid no adda napudno nga adres ti esurat a nainaganan iti [[Special:Preferences|pakabilangan ti kakaykayatm]] ken no saanka a naparitan nga agaramat iti daytoy.\nTi agdama nga adres ti IP ket $3, ti naserraan nga ID ket #$5. \nPangngaasi nga iramanmo amin dagiti salaysay dita ngato kadagiti ania man nga aramidem nga usisa.",
+       "autoblockedtext": "Ti bukodmo nga adres ti IP ket automatiko a naserraan ngamin ket inusar ti sabali nga agar-aramat, a sinerraan ni $1.\nTi rason nga inted ket:\n\n:<em>$2</em>\n\n* Rugi ti serra: $8\n* Panagpaso ti serra: $6\n* Naikeddeng a serraanna: $7\n\nMabalinmo a kontaken ni $1 wenno maysa kadagiti [[{{MediaWiki:Grouppage-sysop}}|administrador]] tapno maipalawag daytoy a panagserra.\n\nLaglagipem a saanmo a mabalin nga usaren ti \"{{int:emailuser}}\" a langa malaksid no addaanka iti napudno nga adres ti esurat a nakarehistro iti [[Special:Preferences|kakaykayatam]] ken saanka a naserraan manipud iti panagusar daytoy.\n\nTi agdama a bukodmo nga adres ti IP ket $3, ken ti ID ti naserraan ket #$5.\nPangngaasi nga iramanmo amin dagiti salaysay dita ngato kadagiti ania man nga aramidem nga usisa.",
        "systemblockedtext": "Ti naganmo nga agar-aramat wenno adres ti IP ket automatikon a sinerraan babaen ti MediaWiki.\nTi naited a rason ket:\n\n:<em>$2</em>\n\n* Rugi ti serra: $8\n* Panagpaso ti serra: $6\n* Naikeddeng a maserraan: $7\nTi agdama nga adresmo nga IP ket $3.\nPangngaasi nga iraman amin dagiti salaysay dita ngato kadagiti ania man nga aramidem nga usisa.",
        "blockednoreason": "awan ti naited a rason",
        "whitelistedittext": "Pangngaasi a $1 tapno makaurnos kadagiti panid.",
        "rcfilters-watchlist-markseen-button": "Markaan amin a sinuksukatan a kas nakitan",
        "rcfilters-watchlist-edit-watchlist-button": "Urnosem ti listaam kadagiti mabuybuya a panid",
        "rcfilters-preference-label": "Ilemmeng ti napasayaat a bersion ti Kaudian a Balbaliw",
+       "rcfilters-filter-showlinkedfrom-option-label": "<strong>Pampanid a maisilpo manipud iti</strong> napili a panid",
        "rcfilters-filter-showlinkedto-label": "Ipakita dagiti binaliwan iti pakaisilpuan dagiti panid",
        "rcfilters-filter-showlinkedto-option-label": "<strong>Pampanid a maisilpo iti</strong> napili a panid",
        "rcfilters-target-page-placeholder": "Mangikabil iti nagan ti panid (wenno kategoria)",
        "recentchangeslinked-feed": "Mainaig a sinukatan",
        "recentchangeslinked-toolbox": "Mainaig a sinuksukatan",
        "recentchangeslinked-title": "Sinukatan a mainaig iti \"$1\"",
-       "recentchangeslinked-summary": "Mangikabil iti maysa a nagan ti panid tapno makita dagiti panagbaliw kadagiti naisilpo a panid wenno iti dayta a panid. (Tapno makita dagiti kameng iti maysa a kategoria, ikabil ti Kategoria:Nagan ti kategoria). Dagiti panagbaliw kadagiti panid iti [[Special:Watchlist|Listaan ti bambantayam]] ket addada iti <strong>napuskol</strong>.",
+       "recentchangeslinked-summary": "Mangikabil iti maysa a nagan ti panid tapno makita dagiti panagbaliw kadagiti naisilpo a panid wenno iti dayta a panid. (Tapno makita dagiti kameng iti maysa a kategoria, ikabil ti {{ns:category}}:Nagan ti kategoria). Dagiti panagbaliw kadagiti panid iti [[Special:Watchlist|Listaan ti bambantayam]] ket addada iti <strong>napuskol</strong>.",
        "recentchangeslinked-page": "Nagan ti panid:",
        "recentchangeslinked-to": "Ipakita dagiti sinukatan kadagiti panid nga imbes a naisilpo iti naited a panid",
        "recentchanges-page-added-to-category": "nainayon ti [[:$1]] iti kategoria",
        "uploadbtn": "Agikarga iti papeles",
        "reuploaddesc": "Ukasen ti panagikarga ken agsubli idiay porma ti panagikarga",
        "upload-tryagain": "Mangited iti napabaro a deskripsion ti papeles",
+       "upload-tryagain-nostash": "Mangited iti naikarga manen a papeles ken ti nabaliwan a deskripsion",
        "uploadnologin": "Saan a nakastrek",
        "uploadnologintext": "Pangngaasi a $1 tapno makaikarga kadagiti papeles.",
        "upload_directory_missing": "Ti pagikargaan a direktorio ($1) ket awan ken saan a mabalin a mapartuat babaen ti webserver.",
        "file-deleted-duplicate-notitle": "Ti papales a kapada iti daytoy a papeles ket dati a naikkat, ken nalapdan ti titulo.\nNasken nga agdamagka iti sabali nga addaan iti abilidad a mangrepaso ti nalapdan a datos ti papeles tapno marepaso ti kasasaad sakbay a mapan nga agikarga manen iti daytoy.",
        "uploadwarning": "Ballaag ti panagikarga",
        "uploadwarning-text": "Pangngaasi a baliwam ti deskripsion ti papeles dita baba ken padasen manen.",
+       "uploadwarning-text-nostash": "Pangngaasi nga ikarga manen ti papeles, baliwan ti deskripsion dita baba ken padasen manen.",
        "savefile": "Idulin ti papeles",
        "uploaddisabled": "Nabaldado dagiti panagikarga.",
        "copyuploaddisabled": "Nabaldado ti panagikarga babaen ti URL.",
        "protectedtitles-submit": "Ipakita dagiti titulo",
        "listusers": "Listaan ti agar-aramat",
        "listusers-editsonly": "Ipakita laeng dagiti agar-aramat nga addaan kadagiti inurnos",
+       "listusers-temporarygroupsonly": "Ipakita laeng dagiti agar-aramat kadagiti temporario a grupo ti agar-aramat.",
        "listusers-creationsort": "Ilasin babaen ti petsa a pannakapartuat",
        "listusers-desc": "Ilasin iti agpababa nga urnos",
        "usereditcount": "$1 {{PLURAL:$1|nga inurnos|kadagiti inurnos}}",
        "dellogpage": "Listaan ti panagikkat",
        "dellogpagetext": "Adda dita baba ti listaan dagiti kaudian a panangikkat.",
        "deletionlog": "listaan ti panagikkat",
+       "log-name-create": "Listaan ti panagpartuat iti panid",
+       "log-description-create": "Dita baba ket listaan dagiti kaudian a panagpartuat iti panid.",
+       "logentry-create-create": "{{GENDER:$2|Pinartuat}} ni $1 ti panid ti $3",
        "reverted": "Naisubli iti nasapsapa a rebision",
        "deletecomment": "Rason:",
        "deleteotherreason": "Sabali/maipatinayon a rason:",
        "deletereason-dropdown": "* Kadawyan a rasrason ti panagikkat\n** Spam\n** Bandalismo\n** Panaglabsing iti karbengan ti kopia\n** Kiddaw ti mannurat\n** Naputed a baw-ing",
        "delete-edit-reasonlist": "Urnosen dagiti rason ti panagikkat",
        "delete-toobig": "Daytoy a panid ket dakkel ti pakasaritaanna, sumurok a  $1 {{PLURAL:a panagbaliwan|dagiti panagbaliwan}}.\nTi panagikkat ti kastoy a pammpanid ket naparitan tapno mapawilan ti saan nga inkarkaro a pannakadadael ti {{SITENAME}}.",
-       "delete-warning-toobig": "Daytoy a panid ket adda ti dakkel unay a pakasaritaan ti panagurnos, ti kaadu nga $1 {{PLURAL:$1|panagbaliw|dagiti panagbaliw}}.\nTi panagikkat ket madisturbo ti panagpataray ti database ti {{SITNAME}};\nagal-aluadka a mangrugi.",
+       "delete-warning-toobig": "Daytoy a panid ket adda ti dakkel unay a pakasaritaan ti panagurnos, ti kaadu nga $1 {{PLURAL:$1|panagbaliw|dagiti panagbaliw}}.\nTi panagikkat ket madisturbo ti panagpataray ti database ti {{SITENAME}};\nagal-aluadka a mangrugi.",
        "deleteprotected": "Saanmo a maikkat daytoy a panid gapu ta nasalaknibanen.",
        "deleting-backlinks-warning": "<strong>Ballaag:</strong> [[Special:WhatLinksHere/{{FULLPAGENAME}}|Dagiti dadduma a panid]] ket naisilpo wenno nailak-am manipud iti panid a gangani nga ikkatem.",
        "deleting-subpages-warning": "<strong>Ballaag:</strong> Ti panid nga ik-ikkatem ket addaan [[Special:PrefixIndex/{{FULLPAGENAME}}/|{{PLURAL:$1|iti subpanid|kadagiti $1 a subpanid|51=kadagiti sumurok a 50 a subpanid}}]].",
        "whatlinkshere": "Dagiti nakasilpo ditoy",
        "whatlinkshere-title": "Pampanid a nakasilpo iti \"$1\"",
        "whatlinkshere-page": "Panid:",
-       "linkshere-2": "Dagiti sumaganad a panid ket nakasilpo iti <strong>$1</strong>:",
-       "nolinkshere-2": "Awan ti pampanid a nakasilpo iti <strong>$1</strong>.",
-       "nolinkshere-ns-2": "Awan ti pampanid a nakasilpo iti <strong>$1</strong> iti napili a nagan ti espasio.",
+       "linkshere": "Dagiti sumaganad a panid ket nakasilpo iti <strong>$2</strong>:",
+       "nolinkshere": "Awan ti pampanid a nakasilpo iti <strong>$2</strong>.",
+       "nolinkshere-ns": "Awan ti pampanid a nakasilpo iti <strong>$2</strong> iti napili a nagan ti espasio.",
        "isredirect": "baw-ing a panid",
        "istemplate": "mailak-am",
        "isimage": "silpo ti papeles",
        "ip_range_toolarge": "Dagiti serra a nasakop a dakdakkel ngem /$1 ket saan a maipalubos.",
        "proxyblocker": "Pannakbagi a panagserra",
        "proxyblockreason": "Ti IP a pagtaengam ket naserraan ngamin ket daytoy ket nakalukat a panakbagi.\nPangngaasi a kontakem ti agit-ited ti serbisio ti Internetmo wenno teknikal a suporta ti gunglom ken ibagam kaniada ti nakaro a parikut ti seguridad.",
-       "sorbsreason": "Ti IP a pagtaengam ket nailista a kasla \"nalukatan a pannakbagi\" iti DNSBL nga inusar babaen ti {{SITNAME}}.",
-       "sorbs_create_account_reason": "Ti IP a pagtaengam ket nailista a kasla \"nalukatan a pannakbagi\" iti DNSBL nga inusar babaen ti {{SITNAME}}.\nSaanka a makapartuat ti pakabilangan.",
+       "sorbsreason": "Ti IP a pagtaengam ket nailista a kasla \"nalukatan a pannakbagi\" iti DNSBL nga inusar babaen ti {{SITENAME}}.",
+       "sorbs_create_account_reason": "Ti IP a pagtaengam ket nailista a kasla \"nalukatan a pannakbagi\" iti DNSBL nga inusar babaen ti {{SITENAME}}.\nSaanka a makapartuat ti pakabilangan.",
        "softblockrangesreason": "Dagiti kontribusion ti di ammo ket saan a maipalubos manipud iti IP nga adresmo ($1). Pagngaasi a sumrek.",
        "xffblockreason": "Ti maysa nga adres ti IP nga adda iti paulo ti X-Forwarded-For, mabalin a kukuam wenno ti pannakbagi a server nga us-usarem, ket naserraan. Ti kasisigud a rason ti pannakaserra idi ket: $1",
        "cant-see-hidden-user": "Ti agar-aramat a kayatmo a serraan ket naserraanen ken nailemmeng.\nGapu ta awan met ti karbengam nga agilemming ti agar-aramat, saanmo a makita wenno maurnos ti serra ti agar-aramat.",
        "markedaspatrollederrornotify": "Ti panagmarka a kas napatruliaan ket napaay.",
        "patrol-log-page": "Listaan ti napatruliaan",
        "patrol-log-header": "Daytoy ket listaan dagiti napatruliaan a rebision.",
-       "log-show-hide-patrol": "$1 listaan ti napatruliaan",
-       "log-show-hide-tag": "$1 ti listaan ti etiketa",
        "confirm-markpatrolled-button": "Sige",
        "confirm-markpatrolled-top": "Markaan ti rebision $3 iti $2 a kas napatruliaan?",
        "deletedrevision": "Naikkat a daan a rebision ti $1",
        "monthsall": "amin",
        "confirmemail": "Pasingkedan ti esurat a pagtaengam",
        "confirmemail_noemail": "Awan ti umisu nga e-surat a pagtaengam a naikabil idiay [[Special:Preferences|kaykayat ti agar-aramat]].",
-       "confirmemail_text": "Ti {{SITNAME}} ket masapulna a pasingkedam ti esurat a pagtaengam sakbay nga agusar ti esurat a langa.\nIpabalinmo dita baba a buton ti panagitulod ti pasingkedan a surat dita a pagtaengam.\nTi surat ket mangiraman ti panilpo nga aglaon ti maysa a kodigo;\nikabil ti panilpo dita pagbasabasam tapno mapasingkedam a ti esurat a pagtaengam ket umisu.",
+       "confirmemail_text": "Ti {{SITENAME}} ket masapulna a pasingkedam ti esurat a pagtaengam sakbay nga agusar ti esurat a langa.\nIpabalinmo dita baba a buton ti panagitulod ti pasingkedan a surat dita a pagtaengam.\nTi surat ket mangiraman ti panilpo nga aglaon ti maysa a kodigo;\nikabil ti panilpo dita pagbasabasam tapno mapasingkedam a ti esurat a pagtaengam ket umisu.",
        "confirmemail_pending": "Ti pasingkedan a kodigo ket naipatulod kenkan:\nno kadamdama ka a nangaramid ti pakabilangam, aguray ka pay ti mano a minutos a sumangpet sakbay ka nga agpadas ti agkiddaw ti baro a kodigo.",
        "confirmemail_send": "Agipatulod ti pasingkedan a kodigo",
        "confirmemail_sent": "Naipatuloden ti pammasingked nga esurat.",
        "gotointerwiki-invalid": "Ti nainaganan a titulo ket imbalido.",
        "pagedata-title": "Datos ti panid",
        "pagedata-not-acceptable": "Awan ti kapada a pormat ti nabirukan. Dagiti masuportaran a kita ti MIME: $1",
-       "pagedata-bad-title": "Imbalido ti titulo: $1."
+       "pagedata-bad-title": "Imbalido ti titulo: $1.",
+       "unregistered-user-config": "Para kadagiti rason ti seguridad dagiti subpanid ti agar-aramat iti JavaScript, CSS ken JSON ket saan a maikarga  para kadagiti di nairehistro nga agar-aramat.",
+       "passwordpolicies": "Dagiti annuroten ti kontrasenias",
+       "passwordpolicies-summary": "Daytoy ti listaan dagiti epektibo nga annuroten ti kontrasenias para kadagiti grupo ti agar-aramat iti daytoy a wiki.",
+       "passwordpolicies-group": "Grupo",
+       "passwordpolicies-policies": "Dagiti annuroten",
+       "passwordpolicies-policy-minimalpasswordlength": "Ti kontrasenias ket nasken a saan a basbassit ngem $1 a {{PLURAL:$1|karakter|karkarakter}} iti kaatiddog",
+       "passwordpolicies-policy-minimumpasswordlengthtologin": "Ti kontrasenias ket nasken a saan a basbassit ngem $1 a {{PLURAL:$1|karakter|karkarakter}} iti kaatiddog tapno makabaelan ti sumrek",
+       "passwordpolicies-policy-passwordcannotmatchusername": "Ti kontrasenia ket saan a mabalin a kapada a kas ti nagan ti agar-aramat",
+       "passwordpolicies-policy-passwordcannotmatchblacklist": "Ti kontrasenias ket saan a mabalin a maipada kadagiti naiparit a kontrasenias",
+       "passwordpolicies-policy-maximalpasswordlength": "Ti kontrasenias ket nasken a basbassit ngem $1 a {{PLURAL:$1|karakter|karkarakter}} iti kaatiddog",
+       "passwordpolicies-policy-passwordcannotbepopular": "Ti kontrasenias ket saan a mabalin {{PLURAL:$1|a ti popular a kontrasenias|nga adda iti listaan dagiti $1 a popular a kontrasenias}}"
 }
index cdd4758..e54666d 100644 (file)
@@ -12,7 +12,8 @@
                        "ElizaMag",
                        "Adam-Yourist",
                        "Matma Rex",
-                       "Tusholi"
+                       "Tusholi",
+                       "Kaganer"
                ]
        },
        "tog-underline": "ТIатовжамá кIала така хьакхар:",
        "tog-hidecategorization": "Къайлаяха оагӀоний оагӀаташ",
        "tog-extendwatchlist": "Хьашеръе зéма хьаязъяьр шедола хувцамаш юкъелоацаш, тIехьара даь хувцамаш хинна ца Iеш.",
        "tog-usenewrc": "Хувцамех тоабаш е керда нийсдарашка а зéма хьаязъяьра чу а",
-       "tog-numberheadings": "Ше-шегIа номераш увттае кепакертошта",
+       "tog-numberheadings": "Ши-шегIа номераш увттае кепакертошта",
        "tog-showtoolbar": "Кечала панель хьахьокха хувцам беча хана",
-       "tog-editondblclick": "Ð\9dиÑ\81Ñ\8aе Ð¾Ð°Ð³Ó\80онаÑ\88 Ñ\88озза IоÑ\82Ó\80аÑ\82оÓ\80аеча (JavaScript)",
-       "tog-editsectiononrightclick": "Ð\9dийÑ\81де Ð´Ã¡ÐºÑ\8aа Ñ\88озза Ð´Ð°Ñ\85ка Ð°Ñ\8cÑ\82Ñ\82еÑ\85Ñ\8cаÑ\80а Ñ\82оIаеÑ\80 Ñ\82Ó\80аÑ\82оÓ\80айиÑ\87а Ð´Ã¡ÐºÑ\8aа Ñ\86IеÑ\80а Ñ\82Iа (JavaScript)",
-       "tog-watchcreations": "Зем беш йола оагIонашта а файлашта а тIатоха аз хьаяь оагIонаши чуяьккха файлаши",
-       "tog-watchdefault": "Зем беш йола оагIонашта а файлашта а тIатоха аз хийца оагIонаши файлай йоазонца сурташ оттадари",
-       "tog-watchmoves": "Зем беш йола оагIонашта а файлашта а тIатоха аз цIи хийца оагIонаши файлаши",
+       "tog-editondblclick": "Тоае Ð¾Ð°Ð³Ó\80онаÑ\88 Ñ\88озза Ñ\82Ó\80аÑ\82оÓ\80айича (JavaScript)",
+       "tog-editsectiononrightclick": "Тоаде Ð¾Ð°Ð³Iон Ð´Ã¡ÐºÑ\8aа Ñ\86Ñ\83н ÐºÐµÐ¿Ð°ÐºÐµÑ\80Ñ\82á Ð´Ð°Ñ\85килга Ð°Ñ\8cÑ\82Ñ\82еÑ\85Ñ\8cаÑ\80а Ñ\82оIаеÑ\80г Ñ\82Ó\80аÑ\82оÓ\80айиÑ\87а (JavaScript)",
+       "tog-watchcreations": "Зем беш йолча оагIонашта а файлашта а тIатоха аз хьаяь оагIонаши чуяьха хинна файлаши",
+       "tog-watchdefault": "Зем беш йолча оагIонашта а файлашта а тIатоха аз хийца оагIонаши файлах лаьцараши",
+       "tog-watchmoves": "Зем беш йолча оагIонашта а файлашта а тIатоха аз цIи хийца оагIонаши файлаши",
        "tog-watchdeletion": "Зем беш йола оагIонашта а файлашта а тIатоха аз дIаяьккха оагIонаши файлаши",
        "tog-minordefault": "Массаза зIамига долаш санна белгалде хувцамаш.",
        "tog-previewontop": "Хьалххе бӀаргтохар хьагойта хувцама кора хьалхашкахь",
        "tog-previewonfirst": "Хувцам бе аьнна дехьаваьлча хьалххе бӀаргтохар хьахьокха",
-       "tog-enotifwatchlistpages": "ЭлекÑ\82Ñ\80онни Ð¿Ð¾Ñ\87Ñ\82е Ð³Iолла Ñ\85оам Ð±Ðµ Ñ\81ога Ð½Ð°Ð³Ð°Ñ\85Ñ\8c аз зем беш йола оагIонаши файлаши цхьанне хийцача",
+       "tog-enotifwatchlistpages": "ЭлекÑ\82Ñ\80онни Ð¿Ð¾Ñ\88Ñ\82е Ð³Iолла Ñ\85оамбе Ñ\81ога аз зем беш йола оагIонаши файлаши цхьанне хийцача",
        "tog-enotifusertalkpages": "Электронни почте гIолла хоам бе сога са дувца оттадара оагIув хийцача",
        "tog-enotifminoredits": "ОагIонаштеи файлаштеи даь хинна хувцамаш геттара зIамига дале а хоам бе сога",
        "tog-enotifrevealaddr": "ДӀабӀаргадайта са поштан цӀай нахá дӀатӀаухача цхьа хӀама хайташ долча хоамаш чу",
        "tog-shownumberswatching": "Ер оагIув шоаш зембеча оагIонашта юкъеяьккха болча доакьошхой таьрахь хьагойта",
-       "tog-oldsig": "Хьа карара кулг яздар:",
-       "tog-fancysig": "Ð\9aÑ\83лг Ñ\8fздаÑ\80а Ñ\88ий Ð¹Ð¾Ð»Ð° Ð²Ð¸ÐºÐ¸-Ñ\80азмеÑ\82ка (авÑ\82омаÑ\82иÑ\87еÑ\81ки Ñ\82IаÑ\85Ñ\8cожаÑ\8fÑ\80г Ð¹оацаш)",
+       "tog-oldsig": "Хьа карара кулг яздар иштта да:",
+       "tog-fancysig": "Ð\9aÑ\83лг Ñ\8fздаÑ\80а Ñ\85Ñ\8cа Ñ\85Ñ\8cай Ð²Ð¸ÐºÐ¸-Ñ\80азмеÑ\82ка (Ñ\88и-Ñ\88егIа Ð±Ð¾Ð»Ð° Ñ\82IаÑ\82овжам Ð±оацаш)",
        "tog-uselivepreview": "Хьахьокха хьалххе бӀаргтохар оагӀув юха хьа а ца елаш",
        "tog-forceeditsummary": "ДIахьалхадаккха, нагахьа санна хувцама йоазонца сурт оттадара моттиг хьалъйизанза яле",
        "tog-watchlisthideown": "Аз даь хувцамаш зéма хьаязъяьра чура къайладаха",
        "tog-watchlisthidebots": "Боташ даь хувцамаш зéма хьаязъяьра чура къайладаха",
        "tog-watchlisthideminor": "ЗIамига хувцамаш зéма хьаязъяьра чура къайладаха",
        "tog-watchlisthideliu": "Ражача чубаьннабоацача доакъошхоша даь хувцамаш къайладаха зема хьаязъяьра чура",
-       "tog-watchlisthideanons": "ЦIийоацача доакъошхоша хувцамаш къайладаха зем бара хьаязъяьр чура",
+       "tog-watchlistreloadautomatically": "Ши-шегIа кердаювлийта зема хьаязъяьр фильтр хувц мел луча хана (JavaScript эша)",
+       "tog-watchlistunwatchlinks": "ТIатоха укх тайпара ({{int:Watchlist-unwatch}}/{{int:Watchlist-unwatch-undo}}) маркераш зем беш йола оагIонаш зема хьаязъяьрá чуяккха а цу чура араяккха а атта торо хургьйолаш (JavaScript эша)",
+       "tog-watchlisthideanons": "Дагара йоазув доацача доакъошхоша даь хувцамаш къайладаха зема хьаязъяьра чура",
        "tog-watchlisthidepatrolled": "Ха даь дола хувцамаш къайладаха зéма хьаязъяьра чу",
        "tog-watchlisthidecategorization": "ОагӀонашта оагIаташ тохар къайладаккха",
        "tog-ccmeonemails": "Сона хьатIаахийта аз доакъашхошта дIадахийта дола каьхатий кепаш",
-       "tog-diffonly": "Ма гойта оагIон чулоацам ши верси вIашидистара кIал",
+       "tog-diffonly": "Ма гойта оагIон чулоацам ши эрш вIаши юстача хана",
        "tog-showhiddencats": "Гойта къайла оагIаташ",
        "tog-useeditwarning": "Хоамбе хьадаь хувцамаш дӀа а ца яздеш аз болх дӀаберзабеча хана",
        "underline-always": "Даиман",
        "thu": "ера",
        "fri": "пIаьраска",
        "sat": "шоатта",
-       "january": "АгIой",
-       "february": "Саь-кур",
-       "march": "Мутт-хьал",
-       "april": "Тушоли",
-       "may_long": "Села",
-       "june": "Этинга",
+       "january": "АгIой ''(январь)''",
+       "february": "Саь-кур ''(февраль)''",
+       "march": "Мутт-хьал ''(март)''",
+       "april": "Тушол ''(апрель)''",
+       "may_long": "Села ''(май)''",
+       "june": "Этинга ''(июнь)''",
        "july": "Баьцамеа",
        "august": "Мяцхали",
        "september": "Михий",
        "october": "АьрхIий",
        "november": "Лай чилла",
        "december": "Чан-тар",
-       "january-gen": "АгIой",
-       "february-gen": "Саь-кур",
-       "march-gen": "Мутт-хьал",
-       "april-gen": "Тушоли",
-       "may-gen": "Села",
-       "june-gen": "Этинга",
+       "january-gen": "АгIой ''(январь)'' бетта",
+       "february-gen": "Саь-кур ''(февраль)'' бетта",
+       "march-gen": "Мутт-хьал ''(март)'' бетта",
+       "april-gen": "Тушол ''(апрель)'' бетта",
+       "may-gen": "Села ''(май)'' бетта",
+       "june-gen": "Этинга ''(июнь)'' бетта",
        "july-gen": "Баьцамеа",
        "august-gen": "Мяцхали",
        "september-gen": "Михий",
        "october-gen": "АьрхIий",
        "november-gen": "Лай чилла",
        "december-gen": "Чан-тар",
-       "jan": "АгIой",
-       "feb": "Саь-кур",
-       "mar": "Мутт-хьал",
+       "jan": "АгIой ''(янв)''",
+       "feb": "Саь-кур ''(фев)''",
+       "mar": "Мутт-хьал ''(мар)''",
        "apr": "Tушоли",
-       "may": "Села",
-       "jun": "Этинга",
+       "may": "Села ''(май)''",
+       "jun": "Этинга ''(июн)''",
        "jul": "Баьцамеа",
        "aug": "Мяцхали",
        "sep": "Михий",
        "oct": "АьрхIий",
        "nov": "Лай чилла",
        "dec": "Чан-тар",
-       "january-date": "АгIой $1",
-       "february-date": "Саь-кур $1",
-       "march-date": "Мутт-хьал $1",
-       "april-date": "Тушоли $1",
-       "may-date": "Села $1",
-       "june-date": "Этинга $1",
+       "january-date": "АгIой ''(Январь)'' $1",
+       "february-date": "Саь-кур ''(февраль)'' $1",
+       "march-date": "Мутт-хьал ''(март)'' $1",
+       "april-date": "Тушол ''(апрель)'' $1",
+       "may-date": "Села ''(май)'' $1",
+       "june-date": "Этинга ''(июнь)'' $1",
        "july-date": "Баьцамеа $1",
        "august-date": "Мяцхали $1",
        "september-date": "Михий $1",
        "print": "Зарба тоха",
        "view": "Хьажар",
        "view-foreign": "Укх $1 сайта чу хьажа",
-       "edit": "Ð\9dийÑ\81де",
+       "edit": "Тоаде",
        "edit-local": "Хувца локальни йоазонца сурт оттадар",
        "create": "Хьакхолла",
        "create-local": "ТIатоха локальни йоазонца сурт оттадар",
        "newpage": "Керда оагӀув",
        "talkpagelinktext": "дувца оттадар",
        "specialpage": "ГIулакха оагӀув",
-       "personaltools": "Ð\94оакÑ\8aаÑ\88Ñ\85оÑ\87Ñ\83н Ð³Ó\80иÑ\80Ñ\81аш",
-       "talk": "Ð\94Ñ\83вÑ\86а Ð¾Ñ\82Ñ\82адар",
+       "personaltools": "Ð\94оакÑ\8aаÑ\88Ñ\85оÑ\87Ñ\83н ÐºÐµÑ\87алаш",
+       "talk": "ЮвÑ\86ар",
        "views": "Хьажараш",
-       "toolbox": "Ð\93Ó\80иÑ\80Ñ\81аш",
+       "toolbox": "Ð\9aеÑ\87алаш",
        "imagepage": "Файла оагIон бIаргтоха",
        "mediawikipage": "Хьахьокха хоам бара оагIув",
        "templatepage": "Лера оагIон бIаргтоха",
        "viewhelppage": "Новкъостал эцар",
-       "categorypage": "Ð\9aаÑ\82егоÑ\80ен Ð¾Ð°Ð³Iон бIаргтоха",
-       "viewtalkpage": "Дувца оттадара бIаргтоха",
+       "categorypage": "Ð\9eагÓ\80аÑ\82а Ð¾Ð°Ð³Iонга бIаргтоха",
+       "viewtalkpage": "Дувцара оагIонга бIаргтоха",
        "otherlanguages": "Кхыча меттаех",
        "redirectedfrom": "($1 яха оагIув дIа-хьа хьожаяьй укхаза)",
        "redirectpagesub": "ДIа-хьа хьожавара оагIув",
        "copyrightpage": "{{ns:project}}:Автора бокъонаш",
        "currentevents": "Карарча хана хинна хIамаш",
        "currentevents-url": "Project:Карарча хана хинна хӏамаш",
-       "disclaimers": "Бехктокхам тIацаэцар",
-       "disclaimerpage": "Project:Бехктокхам тIацаэцар",
+       "disclaimers": "Бехктокхам тӀацаэцар",
+       "disclaimerpage": "Project:Бехктокхам тӀацаэцар",
        "edithelp": "Хувцам бара новкъостал",
        "helppage-top-gethelp": "Новкъoстал",
        "mainpage": "Керттера оагӀув",
        "privacypage": "Project:КъайлагIара хIамай политика",
        "badaccess": "ТIакхоачилга гӀалат",
        "badaccess-group0": "Оаш дIадийха хинна ардам кхоачашде йиш яц шун.",
-       "badaccess-groups": "ДIадийха ардам кхоачашде могаш ба алхха доакъашхой {{PLURAL:$2|1=тоабан «$1»|укх тоабаш чура: $1}}",
+       "badaccess-groups": "ДӀадийхар кхоачашде йиш йолаш ба алхха {{PLURAL:$2|1=«$1»|$1}}.",
        "versionrequired": "Эшаш я $1 версех йола MediaWiki",
        "versionrequiredtext": "Укх оагIонца болх бергболаш $1 версех йола MediaWiki эша. Хьажа [[Special:Version|програмни Iалашдарах бола хоамага]].",
        "ok": "Мег",
        "newmessageslinkplural": "{{PLURAL:$1|керда хоам}}",
        "newmessagesdifflinkplural": "{{PLURAL:$1|тӀехьара хувцам|999=тӀехьара хувцамаш}}",
        "youhavenewmessagesmulti": "Хьога кхаьчад керда хоамаш $1 чу",
-       "editsection": "нийсде",
+       "editsection": "тоае",
        "editold": "хувца",
        "viewsourceold": "Хьажа дIадолалу ко́дага",
        "editlink": "хувца",
        "collapsible-expand": "хьадоаржаде",
        "confirmable-yes": "XӀау",
        "confirmable-no": "A",
-       "thisisdeleted": "БIаргтоха е юхаметтаоттае $1?",
+       "thisisdeleted": "БӀаргтоха е юхаметтаоттае $1?",
        "viewdeleted": "Хьажа $1?",
-       "restorelink": "{{PLURAL:$1|1=дIадaьккха нийсдар|$1 дIадaьккха нийсдараш}}",
+       "restorelink": "{{PLURAL:$1|1=дӀадaьккха нийсдар|$1 дӀадaьккха нийсдараш}}",
        "feedlinks": "Укх тайпара:",
        "site-rss-feed": "$1 — RSS-мугI",
        "site-atom-feed": "$1 — Atom-мугI",
        "page-rss-feed": "$1 — RSS-мугI",
        "page-atom-feed": "«$1» — Atom-мугI",
        "red-link-title": "$1 (укх тайпара оагӀув яц)",
+       "sort-descending": "Лостам бе зIамигахиларгахьа",
+       "sort-ascending": "Лостам бе докхахиларгахьа",
        "nstab-main": "Статья",
        "nstab-user": "Доакъашхо",
        "nstab-media": "Мультимедиа",
        "nstab-special": "ГIулакха оагӀув",
        "nstab-project": "Проектах лаьца",
        "nstab-image": "Файл",
-       "nstab-mediawiki": "Хоамбар",
+       "nstab-mediawiki": "Хоам",
        "nstab-template": "Ло",
        "nstab-help": "Новкъостал",
        "nstab-category": "ОагӀат",
        "cannotdelete-title": "ДIаяккха йиш яц «$1» яха оагIув",
        "badtitle": "Мегаш йоаца цӀи",
        "badtitletext": "Езаш йола оагӀон цӀи нийса яц, яьсса я, е харцахь йоалаяй меттий юкъера цIи е интервики цӀи. Иштта, цӀера юкъе оттаде мегаш доаца хьаракаш нийсаденна хила мегаш да.",
-       "viewsource": "Хьажар",
+       "viewsource": "Хьажа",
        "viewsource-title": "$1 яхача оагӏон чухьнахьарча текстага хьажар",
        "actionthrottled": "Сухала доазув дар",
        "protectedpagetext": "Ер оагIув лораяь я цу тIа хувцамаш дергдоацаш.",
        "viewsourcetext": "Укх оагIон чухьнахьарча текстах бIаргатоха а, цунах кеп яьккха а, йиш я хьа.",
+       "exception-nologin-text-manual": "Укх оагIон тIакхача йиш хургйолаш $1 деза шо.",
        "virus-unknownscanner": "йовзанза антивирус:",
-       "welcomeuser": "Маьрша воагIалва, доакъашхо $1!",
+       "logouttext": "<strong>Оаша болх чакхбаьккхаб.</strong>\n\nЦхьайола оагIонаш хьагуш хила мег оаша болх чакхбаьккхабоацаш санна. Из хургдоацаш браузера кэш IоцIенъе.",
+       "welcomeuser": "Марша воагIалва, доакъашхо $1!",
        "yourname": "Дагара йоазон цIи:",
        "userlogin-yourname": "Доакъашхочун цӀи",
        "userlogin-yourname-ph": "Iочуязъе хьай дагара йоазон цӀи",
        "createacct-yourpasswordagain": "Бакъйе пароль",
        "createacct-yourpasswordagain-ph": "Кхы цхьаькхаза Ӏочуязъе пароль",
        "userlogin-remembermypassword": "Ражача чувиса",
-       "yourdomainname": "Ð¥Ñ\8cа Ð½Ð°Ð½Ð°-Ñ\86Iа:",
-       "login": "ЧÑ\83вала/Ñ\8fла",
+       "yourdomainname": "Ð¥Ñ\8cа Ð´Ð¾Ð¼ÐµÐ½:",
+       "login": "ЧÑ\83довла",
        "nav-login-createaccount": "Шоаш довзийтар / Дагара йоазув кхоллар",
        "logout": "Аравала/яла",
        "userlogout": "Аравала/яла",
        "createacct-benefit-body3": "ТӀехьарча хана хинна {{PLURAL:$1|доакъашхо|доакъашхой}}",
        "badretype": "Оаша Iочуяьздаь къайладIоагIий цIераш цхьантара яц.",
        "loginerror": "Доакъашхо вовзара гIалат",
-       "mailmypassword": "КъайладIоагIа тIеракхоссар",
-       "mailerror": "Каьхат дIадохьиййташ гӀалат хилар: $1",
-       "emailconfirmlink": "Бакъде хьа электронни пошта адрес",
+       "mailmypassword": "Пароль тIеракхоссар",
+       "mailerror": "Каьхат дIадохьийтача хана гӀалат хилар: $1",
+       "emailauthenticated": "Хьа электронни пошта цIай бакъдаьд (тIатоадаьд) укх хана: $3, $2.",
+       "emailconfirmlink": "Бакъде хьай электронни пошта цIай",
        "loginlanguagelabel": "Мотт: $1",
-       "pt-login": "ЧÑ\83вала/Ñ\8fла",
-       "pt-login-button": "ЧÑ\83вала/Ñ\8fла",
+       "pt-login": "ЧÑ\83довла",
+       "pt-login-button": "ЧÑ\83довла",
        "pt-createaccount": "Дагара йоазув хьакхолла",
        "pt-userlogout": "Аравала/яла",
        "changepassword": "КъайладIоaгIа дIахувцар",
        "botpasswords-label-create": "Хьакхолла",
        "botpasswords-label-update": "Кердадаккха",
        "botpasswords-label-cancel": "Эшац",
-       "botpasswords-label-delete": "ДIадаккха",
+       "botpasswords-label-delete": "ДIаяккха",
        "botpasswords-label-resetpassword": "Пароль тIеракхоссар",
        "resetpass-submit-loggedin": "КъайладIоагӀа дӀахувца",
        "resetpass-submit-cancel": "Эшац",
        "passwordreset-username": "Доакъашхочун цӀи:",
        "passwordreset-domain": "Домен:",
        "passwordreset-email": "Электронни почта адрес:",
+       "changeemail": "дIахувца е дIаяккха электронни пошт",
        "resettokens-tokens": "Токенаш:",
        "bold_sample": "Сома йоазон текст",
        "bold_tip": "Сома йоазон текст",
        "preview": "Хьалххе бIаргтохар",
        "showpreview": "Хьалххе бIаргтохар",
        "showdiff": "Даь дола хувцамаш",
-       "anoneditwarning": "<strong>Теркам бе!</strong> Хьо автор хинна система чуваьннавац. Нагахьа санна Iа моллагIа хувцам бой, Хьа IP-адрес дийла массанен бIаргагуш хургда. Нагахьа санна Хьо <strong>[$1 хьачувоале]</strong> е <strong>[$2 дагара йоазув хьакхолле]</strong>, нийсдараш (хувцамаш) бувзам болаш хургда Хьа доакъашхой цIерца, иштта кхыдола толажагIи гIойленагIи дола дикаьш хургда Хьона.",
+       "anoneditwarning": "<strong>Теркам бе!</strong> Хьо ражача дIаязвеннавац. Нагахьа санна Iа моллагIа хувцам бой, Хьа IP-цIай хьадийла массанена бIаргагуш хургда. Нагахьа санна Хьо <strong>[$1 ражача хьачувоале]</strong> е Iа <strong>[$2 дагара йоазув хьакхолле]</strong>, хьа тоадар (хувцамаш) бувзам болаш хургда Хьа цIерца, иштта кхыдола толашагIеи гIойленагIеи дола дикаьш хургда Хьона.",
        "summary-preview": "Хувцама сурт оттадарах хьалхе бӀаргтохар:",
        "subject-preview": "Темах/кепакертах хьалххе бӀаргтохар:",
        "blockedtitle": "Доакъашхочун чIега техаб",
        "blockedtext": "<strong>Хьа дагара йоазон е IP-адреса блоктехай.</strong>\n\nБлоктохар даьд $1 яхача администраторо.\nБелгалдаьд ер бахьан: «<em>$2</em>».\n\n* Блоктохара дух: $8\n* Блоктохара чаккхе: $6\n* Блоктохара дагалоаттам: $7\n\nХьа аьттув ба $1-ца е моллагIа кхыволча [[{{MediaWiki:Grouppage-sysop}}|администраторца]] бувзаме вала блоктохар тахкар духьа.\nТеркал делахь, хьа йиш хургьяц «письмо участнику» яхача функцех пайда эца, нагахьа санна хьай [[Special:Preferences|персональни настройкаш]] чу нийса дола электронни поштан адрес белгалдаькха деце, е нагахьа санна хьона теха блока чу цу тайпара каьхат дахьийтар могадаь деце.\nХьа IP-адрес — $3, блоктохара идентификатор — $5.\nБоккъала, белгалдаха уж хоамаш (дараш) Iайха моллагIа каьхат дохьийтача хана.",
        "blockednoreason": "бахьан белгалдаьккха дац",
-       "loginreqlink": "довзийта",
-       "loginreqpagetext": "Оаш шоаш $1 деза кхыйола оагIонашка хьожаргдолаш.",
+       "whitelistedittext": "Шо $1 деза оагIонашта хувцам бергболаш.",
+       "loginreqlink": "чудовла",
+       "loginreqpagetext": "Шо $1 деза кхыйола оагIонашка хьожаргдолаш.",
        "accmailtitle": "КъайладIоагӀа дӀадахьийтад",
        "newarticle": "(Kерда)",
        "newarticletext": "Шо тIатовжама гIолла дехьадаьннад йолаш йоацача оагӀон тӀа.\nИз хьакхолларгьйолаш кӀалхагӀа доалача корачу текст Iочуязъе (нагахьа санна кхетаде хала дале [$1 новкъосталара оагӀонга] хьажа).\nЦаховш укхаза нийсденнадале, шоай браузера чу '''Юха''' (Назад) яха тоIаера тӀа пӀелг тоӀабе.",
        "template-protected": "(лорадаь да)",
        "template-semiprotected": "(цхьа долча даькъе гIо оттадаь да)",
        "hiddencategories": "Ер оагIув {{PLURAL:$1|$1 къайла категориех|1=цаI къайла категорех}} я:",
-       "permissionserrors": "ТÓ\80акÑ\85оаÑ\87илга Ð±Ð¾ÐºÑ\8aоний гӀалат",
-       "permissionserrorstext-withaction": "Ер $2 де Хьа бокъо яц {{PLURAL:$1|1=из бахьан долаш|из бахьанаш долаш}}:",
+       "permissionserrors": "ТÓ\80акÑ\85аÑ\87аÑ\80а Ð±Ð¾ÐºÑ\8aонаÑ\88Ñ\86аÑ\80а гӀалат",
+       "permissionserrorstext-withaction": "$2 шун бокъо яц {{PLURAL:$1|1=укх бахьан}}:",
        "recreate-moveddeleted-warn": "'''Теркам бе. Хьо юхакхолла гӀерта хьалха дIаяьккха хинна оагӀув.'''\n\nДIатахка, боккъонца эший хьона из оагIув юхакхолла.\nКӀалхагIа хьекха да укх оагӀон дӀадаккхари цӀи хувцари тептараш.",
        "moveddeleted-notice": "Ер оагӀув дӀаяьккха хиннай.\nШоана новкъостала кӀалха хьахьекха да укх оагIонца дувзаденна тептараш.",
        "log-fulllog": "БIаргтоха таптарага бIарчча",
        "previousrevision": "← XьалхайоагIа",
        "nextrevision": "ТIехьайоагIа →",
        "currentrevisionlink": "ХIанзара верси",
-       "cur": "хӀанза.",
+       "cur": "карара",
        "next": "тӀехь.",
-       "last": "хьалха.",
+       "last": "хьалхара",
        "page_first": "цхьоаллагIа",
        "page_last": "тӀехьара",
        "histlegend": "Эрший хоржам: хьабелгалъе шун вIаши йиста безам бола оагIон эршаш, тIаккха тоIае '''{{int:compare-submit}}'''.<br />\nКхетавар: '''({{int:cur}})''' — карарча эршаи хержача эршаи юкъе йола башхалонаш; '''({{int:last}})''' — хьалха йоагIача эршаи хержача эршаи юкъе йола башхалонаш; '''{{int:minoreditletter}}''' — зIамига хувцамаш.",
        "difference-title": "$1 — эршашта юкъе йола башхало",
        "lineno": "МугI $1:",
        "compareselectedversions": "ВIаши йиста хержа версеш",
+       "showhideselectedversions": "Хьахьокха/къайлаяха хьахержа эршаш",
        "editundo": "юхадаккха",
        "diff-empty": "(башхалонаш яц)",
        "diff-multi-sameuser": "({{PLURAL:$1|цхьа юкъ хулаш йола верси|$1 юкъ хулаш йола версеш}} гуш яц цу доакъашхочун)",
        "diff-multi-otherusers": "(Укх {{PLURAL:$2|цхьан доакъашхочун|$2 доакъашхой}} \n{{PLURAL:$1|юккъера верси гайтаяц|юккъера версеш гайтаяц}})",
        "searchresults": "Лахар чакхдоалаш корадаьр",
        "searchresults-title": "«$1» лахар",
-       "notextmatches": "Ð\9eагIонай Ñ\82екÑ\81Ñ\82аÑ\88Ñ\82а Ñ\8eкÑ\8aе цхьатара хилар дац",
-       "prevn": "{{PLURAL:$1|1=Ñ\85Ñ\8cалÑ\85айогIаÑ\80\85Ñ\8cалÑ\85айогIаÑ\80аÑ\88}} $1",
-       "nextn": "{{PLURAL:$1|1=Ñ\82IеÑ\85Ñ\8cайоагIаÑ\80\82IеÑ\85Ñ\8cайоагIаÑ\80аÑ\88}} $1",
+       "notextmatches": "Ð\9eагIоний Ñ\82екÑ\81Ñ\82аÑ\88Ñ\82а Ñ\87Ñ\83 цхьатара хилар дац",
+       "prevn": "{{PLURAL:$1|1=Ñ\85Ñ\8cалÑ\85айогIаÑ\87а|Ñ\85Ñ\8cалÑ\85айогIаÑ\87а}} $1-ннега",
+       "nextn": "{{PLURAL:$1|1=Ñ\82IеÑ\85Ñ\8cайоагIаÑ\87а|Ñ\82IеÑ\85Ñ\8cайоагIаÑ\87а}} $1-ннега",
        "prevn-title": "{{PLURAL:$1|ХьалхадоагIа $1 дIаяздар}}",
        "nextn-title": "{{PLURAL:$1|ТIадоагIа $1 яздар|ТIадоагIа $1 яздараш}}",
        "shown-title": "Гойта $1 {{PLURAL:$1|яздаьр|яздаьраш}} укх оáгIон тIа",
        "searchprofile-images-tooltip": "Файлаш лахар",
        "searchprofile-everything-tooltip": "Массайолча оагIонаш тIа лахар (дувцара оагIонаш чу а лоацаш)",
        "searchprofile-advanced-tooltip": "Лаха хьахержача цIерий аренашка",
-       "search-result-size": "$1 ({{PLURAL:$2|$2 дош|$2 дешаш}})",
+       "search-result-size": "$1 ({{PLURAL:$2|$2 дош}})",
        "search-result-category-size": "$1 {{PLURAL:$1|юкъедахар}} ($2 {{PLURAL:$2|кIалоагIат}}, $3 {{PLURAL:$3|файл}})",
        "search-redirect": "($1 яхача оагIон тIара дIа-хьа хьожадар)",
        "search-section": "(дáкъа «$1»)",
        "searchrelated": "вIашагIдувзаденна",
        "searchall": "деррига",
        "search-showingresults": "{{PLURAL:$4|Кораяьй <strong>$1</strong> — цхьа оагӀув|Из дош корадаьд <strong>$3</strong> оагӀонашка, царех гойта $2 оагӀув}}",
-       "search-nonefound": "Хьа дехар дара вIаши нийса доагIаш дар корадаьдац.",
+       "search-nonefound": "Iа лехача дешашта вIаши нийса доагIаш дар корадаьдац.",
        "powersearch-legend": "Шердаь лахар",
-       "powersearch-ns": "ЦIеÑ\80ий Ð°Ñ\80енаÑ\88каÑ\85Ñ\8c лахар:",
+       "powersearch-ns": "ЦIеÑ\80ий Ð¼ÐµÑ\82Ñ\82игаÑ\88ка лахар:",
        "powersearch-toggleall": "Деррига",
        "powersearch-togglenone": "Цхьаккха",
        "powersearch-remember": "Дагалáца хержар кхы тӀехьагӀа лохача хана накъадаргдолаш",
-       "preferences": "Ð\93IиÑ\80Ñ\81 Ñ\82оаÑ\8fÑ\80аш",
+       "preferences": "Ð\9eÑ\82Ñ\82амаш",
        "mypreferences": "Оттамаш",
+       "prefs-edits": "Тоадарий дукхал:",
        "prefs-skin": "ТIера кийчдара тема",
        "skin-preview": "Хьалххе бIаргтохар",
        "prefs-user-pages": "Доакъашхочун оагIонаш",
-       "prefs-personal": "Доакъашхочун дараш",
-       "prefs-rc": "Керда нийсдараш",
-       "prefs-watchlist": "Зéма хьаязъяьр",
+       "prefs-personal": "Доакъашхочун хьакъехьа",
+       "prefs-rc": "Дукха ха йоаццаш тоадаьр",
+       "prefs-watchlist": "Зем",
+       "prefs-editwatchlist": "Зема хьаязъяьр хувцар",
+       "prefs-editwatchlist-label": "Шун зема хьаязъяьра чура яздараш хувцар",
+       "prefs-editwatchlist-edit": "Хьа зема хьаязъяьра чура цIерашка хьажар а уж дIаяхар",
+       "prefs-editwatchlist-raw": "Текст санна зема хьаязъяьр хувцар",
+       "prefs-editwatchlist-clear": "IоцIенъе зема хьаязъяьр",
        "prefs-watchlist-days": "Дéной дукхал:",
-       "prefs-resetpass": "Хувца къайладIоагIа",
+       "prefs-watchlist-edits": "Эггара дукхагIа тоадаьрий массал, зема хьаязъяьра чу хьахьокха йиш йола",
+       "prefs-watchlist-edits-max": "Эггара дукхагIа: 1000",
+       "prefs-watchlist-token": "Зема хьаязъяьра токен:",
+       "prefs-resetpass": "ДIахувца пароль",
+       "prefs-changeemail": "дIахувца е дIаяккха электронни пошт",
+       "prefs-setemail": "Электронни пошта цIай дӀаоттадар",
+       "prefs-email": "Электронни поштан оттамаш",
        "prefs-rendering": "ТIера куц",
        "saveprefs": "ДIаязде",
-       "prefs-editing": "Хувцам",
+       "restoreprefs": "Юхадоаладе юххьанцара хинна оттамаш",
+       "prefs-editing": "Тоадар",
        "searchresultshead": "Лахаp",
+       "stub-threshold": "Кечамий тIатовжамаш хьакийчдар оттадарá доазув ($1):",
+       "stub-threshold-sample-link": "масала",
+       "recentchangesdays": "Масса дийнахь даь керда хувцамаш хьахьокха деза:",
+       "recentchangescount": "Тайп-тайпара хьаязъяьрашка хьагуш дола тоадаьрий дукхал",
+       "prefs-help-recentchangescount": "Эггара дукхагIа: 1000",
+       "prefs-help-watchlist-token2": "Ер хьа зема хьаязъяьра веб-канала къайла дIоагIа да.\nИз дIайханачунна аьттув хургба хьа зема хьаязъяьр еша, цу бахьан дIа ма хайта из кхычарга.\nЭшаш дале нагахь санна, [[Special:ResetTokens|хьа йиш из тIеракхосса]].",
        "timezonelegend": "Сахьата оаса:",
-       "localtime": "Моттига ха:",
+       "localtime": "Меттигара ха:",
+       "timezoneuseserverdefault": "Сервера ($1) оттамаш леладе",
+       "timezoneuseoffset": "Кхыдар (белгалде ха меттахьялар)",
+       "servertime": "Сервера ха:",
+       "guesstimezone": "Браузера чура оттамаш леладе",
        "timezoneregion-africa": "Африка",
        "timezoneregion-america": "Америка",
        "timezoneregion-antarctica": "Антарктика",
        "timezoneregion-arctic": "Арктика",
        "timezoneregion-asia": "Ази",
-       "timezoneregion-atlantic": "Ð\9cалÑ\85бÑ\83зеÑ\80а Ð¾ÐºÐµÐ°Ð½",
+       "timezoneregion-atlantic": "Ð\9cалÑ\85бÑ\83зеÑ\80а Ð¾Ð°ÐºÐ°Ñ\84оÑ\80д",
        "timezoneregion-australia": "Астрали",
        "timezoneregion-europe": "Европа",
-       "timezoneregion-indian": "ХIиндий океан",
-       "timezoneregion-pacific": "Тийна океан",
+       "timezoneregion-indian": "ХIиндий оакафорд",
+       "timezoneregion-pacific": "Тийна оакафорд",
+       "allowemail": "Могадайта кхыча доакъашхошка сайна каьхат ахийта электронни поште гIолла",
+       "email-allow-new-users-label": "Могадайта дукха ха яьланза кердача доакъашхошка сайна каьхат ахийта электронни поште гIолла",
+       "email-blacklist-label": "ХьатIа ма ахийта сона каьхаташ электронни поште гIолла укх доакъашхошкара:",
        "prefs-searchoptions": "Лахар",
        "prefs-namespaces": "ЦIерий моттигаш",
+       "default": "юххьанцара хиннача тайпара",
        "prefs-files": "Файлаш",
-       "youremail": "Электронни почта:",
+       "prefs-custom-css": "Доалахь йола CSS",
+       "prefs-custom-js": "Доалахь йола JS",
+       "prefs-common-config": "Юкъара йола CSS/JSON/JavaScript массайолча кийчдара темашта:",
+       "prefs-emailconfirm-label": "Электронни пошт тIатоаяр:",
+       "youremail": "Электронни пошт:",
        "username": "{{GENDER:$1|Доакъашхочун цӀи}}:",
+       "prefs-memberingroups": "{{GENDER:$2|Дáкъа лоацаш ва|Дáкъа лоацаш я}} {{PLURAL:$1|1=укх тоаба чу|укх тоабашка}}:",
+       "prefs-registration": "Дагара йоазув кхелла ха:",
        "yourrealname": "Бокъонца йола цIи:",
        "yourlanguage": "Мотт:",
+       "yournick": "Керда кулг яздар:",
+       "prefs-help-signature": "Дувцара оагIонаш чу шоай къамаьла тIехьа кулг язде деза ер «<nowiki>~~~~</nowiki>» диъ хьарак оттадаь, цунах тIаккха хьахул шун кулг яздари хаи (сахьати миноташи).",
+       "yourgender": "Мишта аьлча бакъахьа да хьох?",
+       "gender-unknown": "МаIа е кхал хилар белгалцадахар",
        "gender-male": "ВикиоагIонаш тоаеш ва из",
        "gender-female": "ВикиоагIонаш тоаеш я из",
+       "prefs-help-gender": "Укхаза оттадаьр ражо леладергда шуга йистхулача хана шо маIа да е кхал да хьежжа.\nМассанена ховш а бIаргагуш а хургда уж оттамаш.",
        "email": "Email",
-       "prefs-help-email": "ЭлекÑ\82Ñ\80онни Ð¿Ð¾Ñ\87Ñ\82а Ð°Ð´Ñ\80еÑ\81 Ð¾Ñ\82Ñ\82аде Ð¿Ð°Ñ\80аз Ð´Ð°Ñ\86, Ð°Ð¼Ð¼Ð° Ð¸Ð· Ñ\8dÑ\88аÑ\88 Ñ\85Ñ\83Ñ\80гда, Ð½Ð°Ð³Ð°Ñ\85Ñ\8cа Ñ\81анна Ñ\85Ñ\8cона Ñ\85Ñ\8cа ÐºÑ\8aайладIоагIа Ð´Ð¸Ñ\86лой.",
+       "prefs-help-email": "ЭлекÑ\82Ñ\80онни Ð¿Ð¾Ñ\88Ñ\82а Ñ\86Iай Ð¾Ñ\82Ñ\82аде Ð´ÐµÐºÑ\85аÑ\80ийла Ð´Ð°Ñ\86 Ñ\88о, Ñ\86Ñ\85Ñ\8cабакÑ\8aда Ð¸Ð· Ñ\8dÑ\88аÑ\88 Ñ\85Ñ\83Ñ\80гда Ð½Ð°Ð³Ð°Ñ\85Ñ\8cа Ñ\81анна Ñ\88оана Ñ\88оай Ð¿Ð°Ñ\80олÑ\8c Ð¹Ð¸Ñ\86лойÑ\8f.",
        "prefs-help-email-others": "Иштта цунца кхыболча доакъашхошта аьттув хургба шоаца бувзам бе а, шун оагIон тIа е шун дувца оттадара оагIон тIа йола тIахьожаяргаца.\nШун электронни почта адрес цхьаннена гуш хургъяц.",
+       "prefs-info": "Кертера дараш",
+       "prefs-i18n": "Меттаца дувзаденнар",
        "prefs-signature": "Кулг яздар",
+       "prefs-dateformat": "Таьрахьа формат",
+       "prefs-timeoffset": "Хáна оттамаш",
+       "prefs-advancedediting": "Юкъара параметраш",
+       "prefs-developertools": "Кийчдархочун кечалаш",
        "prefs-preview": "Хьалххе бIаргтохар",
+       "prefs-advancedrc": "Кхыдола шердаь оттамаш",
+       "prefs-opt-out": "Алсамдалар тӀацаэцар",
+       "prefs-advancedrendering": "Кхыдола шердаь оттамаш",
+       "prefs-advancedsearchoptions": "Шердаь оттамаш",
+       "prefs-advancedwatchlist": "Кхыдола шердаь оттамаш",
+       "prefs-diffs": "Эрший башхало",
        "userrights-user-editname": "Iочуязъе доакъашхочун цӀи:",
        "editusergroup": "Йотта доакъашхой тоабаш",
        "saveusergroups": "ДIаязъе {{GENDER:$1|доакъашхочун}} тоабаш",
        "userrights-unchangeable-col": "Хьа хувца йиш йоаца тоабаш",
        "group": "Тоаба:",
        "group-user": "Доакъашхой",
+       "group-autoconfirmed": "АвтохьатӀаийца доакъашхой",
        "group-bot": "Бóташ",
        "group-sysop": "Администратораш",
+       "group-bureaucrat": "Бюрократаш",
        "group-all": "(деррига)",
        "group-user-member": "{{GENDER:$1|доакъашхо}}",
+       "group-autoconfirmed-member": "{{GENDER:$1|автохьатӀаийца доакъашхо}}",
        "group-bot-member": "{{GENDER:$1|бот}}",
        "group-sysop-member": "{{GENDER:$1|администратор}}",
        "grouppage-user": "{{ns:project}}:Доакъашхой",
+       "grouppage-autoconfirmed": "{{ns:project}}:АвтохьатӀаийца доакъашхой",
        "grouppage-bot": "{{ns:project}}:Боташ",
        "grouppage-sysop": "{{ns:project}}:Администратораш",
+       "grouppage-bureaucrat": "{{ns:project}}:Бюрократаш",
        "right-read": "оагӀонашка хьажар",
        "right-edit": "оагӀонаш нийсъяр",
+       "right-createpage": "дувцара оагIонаш йоаца оагӀонаш кхоллар",
        "right-createtalk": "дувца оттадара оагӀонаш кхоллар",
+       "right-createaccount": "доакъашхошта керда дагара йоазонаш кхоллар",
        "right-move": "оагIонай цIераш хувцар",
        "right-movefile": "файлай цӀераш хувцар",
+       "right-autoconfirmed": "ӀP-цӀай тӀара сухала доазув дар Ӏехадар",
        "right-writeapi": "дIаяздеш лелае API",
+       "right-editsemiprotected": "оагIонаш тоаяр, лораяь йола иштта «{{int:protect-level-autoconfirmed}}»",
+       "right-viewmywatchlist": "ший зема хьаязъяьрага хьажар",
+       "right-editmywatchlist": "ший зема хьаязъяьр хувцар",
+       "right-viewmyprivateinfo": "шийх лаьца долчунга хьажар (масала, электронни пошта цIай, боккъонца йола цӀи)",
+       "right-editmyprivateinfo": "хьайх лаьца дар хувцар (масала, электронни пошта цIай, боккъонца йола цӀи)",
+       "right-editmyoptions": "ший хьадаь оттамаш хувцар",
+       "right-noratelimit": "сухала доазув дар Iехадар",
        "newuserlogpage": "Доакъашхой дIаязбаь таптар",
        "rightslog": "Доакъашхочун бокъоний тéптар",
        "action-read": "ер оагӀув éшар",
        "recentchanges-label-plusminus": "байташкахь боарам хувцар",
        "recentchanges-legend-heading": "<strong>Легенда:&nbsp;</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (хьажа иштта [[Special:NewPages|керда оагIонашка]])",
+       "recentchanges-submit": "Хьахьокха",
+       "rcfilters-tag-remove": "ДIадаккха '$1'",
+       "rcfilters-legend-heading": "<strong>Лоацдаьраш:&nbsp;</strong>",
+       "rcfilters-other-review-tools": "Тохкама кхыйола кечалаш",
+       "rcfilters-group-results-by-page": "Корадаьчарех тоабаш хьае",
+       "rcfilters-activefilters": "Хьалотадаь луттаргаш",
+       "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": "ДӀаязъяь луттаргаш хIанзехьа йолаш яц",
+       "rcfilters-quickfilters-placeholder-description": "Луттарга оттамаш дIаяздергдолаши тIехьагIа царех юха а пайда эцаргболаши, лохегIа «Хьалотадаь луттаргаш» яздаьча моттиге юкъеехкарг белгалъеш долча хьаракá IотIатоIае.",
+       "rcfilters-savedqueries-defaultlabel": "ДӀаязъяь луттаргаш",
+       "rcfilters-savedqueries-rename": "ЦIи хувца",
+       "rcfilters-savedqueries-setdefault": "Ше хиннача тайпара дIаоттаде",
+       "rcfilters-savedqueries-unsetdefault": "Ше хиннача тайпах яр дIаяккха",
+       "rcfilters-savedqueries-remove": "ДIаяккха",
+       "rcfilters-savedqueries-new-name-label": "ЦIи",
+       "rcfilters-restore-default-filters": "Юхаметтаоттаде луттаргаш юххьанцара хиннача тайпара",
+       "rcfilters-clear-all-filters": "ӀоцIенде деррига луттаргаш",
+       "rcfilters-show-new-changes": "ТӀехьара хувцамаш",
+       "rcfilters-search-placeholder": "Луттаргаш лаха (меню гIолла е укхаза Iочуязъеш)",
+       "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-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": "Ражача дIаэйтта доакъашхой.",
+       "rcfilters-filter-user-experience-level-unregistered-label": "ДӀаязбеннабоацараш",
+       "rcfilters-filter-user-experience-level-unregistered-description": "Ражача дIаэйтта боаца доакъашхой.",
+       "rcfilters-filter-user-experience-level-newcomer-label": "Дукха ха йоаццаш дIаязбеннараш",
+       "rcfilters-filter-user-experience-level-newcomer-description": "ДIаязбенна доакъашхой, 10 кIезигагIа даь тоадаьр долаш е 4 дийнахь мара болх ца баь болаш",
+       "rcfilters-filter-user-experience-level-learner-label": "Iамеш",
+       "rcfilters-filter-user-experience-level-learner-description": "«Керда доакъашхои» «Поалхаме доакъашхои» яхача даржашта юкъе бола дӀаязбенна доакъашхой.",
+       "rcfilters-filter-user-experience-level-experienced-label": "Поалхаме доакъашхой",
+       "rcfilters-filter-user-experience-level-experienced-description": "500 совгIа тоадаьр долаш 30 дийнахь болх баь болаш дӀаязбенна доакъашхой.",
+       "rcfilters-filtergroup-automated": "Авто-къахьегам",
+       "rcfilters-filter-bots-label": "Бот",
+       "rcfilters-filter-bots-description": "Авто-кечалашца даь тоадар.",
+       "rcfilters-filter-humans-label": "Саг ва (бот яц)",
+       "rcfilters-filter-humans-description": "Доакъашхоша даь тоадар.",
+       "rcfilters-filtergroup-significance": "Лоадам",
+       "rcfilters-filter-minor-label": "ЗӀамига хувцамаш",
+       "rcfilters-filter-minor-description": "Авторо зIамига да аьнна белгалдаь тоадаьраш.",
+       "rcfilters-filter-major-label": "ЛерттIа хувцамаш",
+       "rcfilters-filter-major-description": "Авторо зIамига да аьнна белгалдаьдоаца тоадаьраш.",
+       "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": "Ерригаш, Iа зем беш йола оагIонаш юкъерайоахаш.",
+       "rcfilters-filtergroup-changetype": "Хувцама тайпа",
+       "rcfilters-filter-pageedits-label": "ОагӀона тоадаьраш",
+       "rcfilters-filter-pageedits-description": "Чулоацами, дувцара оагIонаши, оагIаташи тоаяр",
+       "rcfilters-filter-newpages-label": "ОагӀонаш кхоллар",
+       "rcfilters-filter-newpages-description": "Керда оагӀонаш кхолла аьнна даь тоадар.",
+       "rcfilters-filter-categorization-label": "ОагIаташ хувцар",
+       "rcfilters-filter-categorization-description": "ОагIаташ чура араяьхача е оагIаташта тIатехача оагIонех лаьца.",
+       "rcfilters-filter-logactions-label": "Протокол лелаеш хьадаьр",
+       "rcfilters-filter-logactions-description": "Администратораш хьадаьр, дагара йоазонаш кхоллар, оагIонаш дIаяхар, файлаш хьачуяхар...",
+       "rcfilters-filtergroup-lastRevision": "ТIехьара эршаш",
+       "rcfilters-filter-lastrevision-label": "Карара эрш",
+       "rcfilters-filter-lastrevision-description": "ОагIон тIа алхха тIехьара хинна хувцам.",
+       "rcfilters-filter-previousrevision-label": "ТIехьара йоаца эрш",
+       "rcfilters-filter-previousrevision-description": "«ТӀехьара эрш» мел доаца тоадаьраш.",
+       "rcfilters-view-tags": "Фосташ",
+       "rcfilters-liveupdates-button": "Ши-шегIа кердадувлийта",
+       "rcfilters-liveupdates-button-title-on": "ДIадоаде ши-шегIа кердадалар",
+       "rcfilters-liveupdates-button-title-off": "Керда хувцам бешше хьахьокха",
+       "rcfilters-preference-label": "Къайлаяккха «Керда хувцамий» толашагIа йола эрш",
+       "rcfilters-preference-help": "Юхатотта 2017 шера хинна интерфейса редизайн а цу хана тӀатеха кечалаш а.",
        "rcnotefrom": "КIалхагIа {{PLURAL:$5|хувцам белгалбаьккхаб}} <strong>$3, $4</strong> тIера (хьахьекхабац <strong>$1</strong>-л дукхагIа).",
        "rclistfrom": "$3 $2 денза даь хувцамаш хьахьокха",
-       "rcshowhideminor": "$1 Ð·Iамига Ð½Ð¸Ð¹Ñ\81даÑ\80аÑ\88",
+       "rcshowhideminor": "$1 Ð·Iамига Ð´Ð¾Ð»Ð° Ñ\82оадаÑ\80",
        "rcshowhideminor-show": "Хьахьокха",
        "rcshowhideminor-hide": "Къайладаккха",
        "rcshowhidebots": "$1 боташ",
        "rcshowhideliu": "$1 ражача дӏаэтта доакъашхой",
        "rcshowhideliu-show": "Хьахьокха",
        "rcshowhideliu-hide": "Къайлабаха",
-       "rcshowhideanons": "$1 цIияккханза доакъашхой",
+       "rcshowhideanons": "$1 Ñ\88оай Ñ\86IиÑ\8fккÑ\85анза Ð´Ð¾Ð°ÐºÑ\8aаÑ\88Ñ\85ой",
        "rcshowhideanons-show": "Хьахьокха",
        "rcshowhideanons-hide": "Къайлабаха",
        "rcshowhidepatr": "$1 техка хувцамаш",
        "rcshowhidepatr-show": "Хьахьокха",
        "rcshowhidepatr-hide": "Къайладаккха",
-       "rcshowhidemine": "$1 хьа нийсдараш",
+       "rcshowhidemine": "$1 Iайха тоадаьраш",
        "rcshowhidemine-show": "Хьахьокха",
        "rcshowhidemine-hide": "Къайладаккха",
+       "rcshowhidecategorization": "$1 оагIаташ тIатохар",
+       "rcshowhidecategorization-show": "Хьахьокха",
+       "rcshowhidecategorization-hide": "Ма хьокха",
        "rclinks": "Хьахьокха $2 дийнахь даь хинна тIеххьара $1 хувцамаш",
        "diff": "башхало",
        "hist": "истори",
        "recentchangeslinked": "ВIашагIдувзаденна нийсдараш",
        "recentchangeslinked-feed": "ВIашагIдувзаденна нийсдараш",
        "recentchangeslinked-toolbox": "ВIашагIдувзаденна хувцамаш",
-       "recentchangeslinked-title": "$1ца вIашидувзаденна хувцамаш",
+       "recentchangeslinked-title": "$1ца вIаши дувзаденна хувцамаш",
        "recentchangeslinked-summary": "Ӏочуязъе оагӀон цӀи, цунна тӀатовжаш йолча оагӀонаш чу даь дола хувцамаш бӀаргагургдолаш (ОагӀата доакъашхой бӀаргагургболаш Ӏочуязъе {{ns:category}}:ОагӀата цӀи).\n[[Special:Watchlist|Хьа зéма хьаязъяьрá]] юкъейоагӀача оагӀонаш чу даь хувцамаш <strong>сомача лапӀазаца</strong> белгалдаь да.",
        "recentchangeslinked-page": "ОагIон цIи",
        "recentchangeslinked-to": "Вешта, белгаляьккха оагIон тIахьожавеш дола оагIонашта даь хувцамаш хьахьокха.",
        "upload": "Файл чуяккха",
        "uploadbtn": "Файл чуяккха",
+       "uploadnologintext": "Шо $1 деза сервера тIа файлаш хьачуйоахаргйолаш.",
        "uploadlogpage": "Чуяьккхарий тептар",
        "filedesc": "Лоаца йоазонца сурт оттадар",
        "fileuploadsummary": "Лоаца сурт оттадар:",
        "license": "Лицензи ялар:",
        "license-header": "Лицензировани",
+       "listfiles-delete": "дӀаяккха",
        "imgfile": "файл",
        "listfiles": "Файлий хьаязъяьр",
        "listfiles_date": "Ди",
        "file-anchor-link": "Файл",
        "filehist": "Файла истори",
        "filehist-help": "Ди/ха долча IотIатоIае цу хана файл мишта хиннай хьажа йиш хуpгьйолаш",
+       "filehist-deleteone": "дӀаяккха",
        "filehist-revert": "юхаяьккха",
        "filehist-current": "xIанзара",
        "filehist-datetime": "Ди/Ха",
        "unwatchedpages": "Цхьанне а зем беш йоаца оагIонаш",
        "randompage": "Цаховш нийсъенна статья",
        "statistics": "ГӀулакх-хьал",
+       "statistics-header-pages": "ОагӀонашца дола гӀулакх-хьал",
+       "statistics-header-edits": "Тоадара гӀулакх-хьал",
+       "statistics-header-users": "Доакъашхошца дола гӀулакх-хьал",
+       "statistics-header-hooks": "Кхыдолчунца дола гӀулакх-хьал",
        "statistics-articles": "Статьяш",
        "statistics-pages": "ОагIонаш",
+       "statistics-pages-desc": "Вике чу мел йола оагӀонаш, дувцара оагӀонаши юхаластараши кхыйола оагӀонаши юкъелоацаш.",
+       "statistics-files": "ДIачуяьха файлаш",
+       "statistics-edits": "{{grammar:genitive|{{SITENAME}}}} дӀаоттаяьча денз даь хувцамаш",
+       "statistics-edits-average": "Цхьан оагӀона деш долча тоадара юкъера дукхал",
+       "statistics-users": "Ражача дӏаийтта доакъашхой",
+       "statistics-users-active": "Хьинаре доакъашхой",
+       "statistics-users-active-desc": "Доакъашхой, {{PLURAL:$1|тӀехьарча $1 дийнахь}} цхьа моллагӀа хувцам баь бола.",
        "double-redirect-fixer": "ДӀа-хьа хьожавара оагIонаш тоаер",
        "brokenredirects-edit": "нийсъе",
        "brokenredirects-delete": "дӀаяккха",
        "withoutinterwiki-submit": "Хьахьокха",
        "nbytes": "$1 {{PLURAL:$1|байт}}",
        "nmembers": "$1 {{PLURAL:$1|объект}}",
-       "prefixindex": "ОагӀоний цӀерий дешхьалхех хьахокхар",
-       "prefixindex-namespace": "ОагӀоний цӀераш шоай дешхьалхех хьахьокхар (цIерий моттиг «{{ns:$1}}»)",
+       "prefixindex": "ОагӀонаш шоай цӀерий хьалхарча алапах хьахокхар",
+       "prefixindex-namespace": "ОагӀоний цӀераш шоай дешхьалхех хьахьокхар (цӀерий моттиг «{{ns:$1}}»)",
+       "prefixindex-submit": "Хьахьокха",
+       "prefixindex-strip": "ДIакъайлаяха хьелехача оагIоний дешхьалхенаш (префиксаш)",
        "shortpages": "Лоаца оагIонаш",
        "longpages": "ЙIаьха оагIонаш",
+       "protectedpages-filters": "Луттаргаш:",
        "protectedpages-page": "ОагIув",
        "listusers": "Доакъашхой хьаязъяьр",
+       "usereditcount": "$1 {{PLURAL:$1|тоадаьр}}",
        "usercreated": "{{GENDER:$3|система чу дӀаязвеннав|система чу дӀаязъяннай}} $1 $2",
        "newpages": "Керда оагIонаш",
+       "newpages-submit": "Хьахьокха",
+       "newpages-username": "Доакъашхо:",
        "move": "ЦIи хувца",
        "movethispage": "ЦIи хувца укх оагIон",
-       "pager-newer-n": "$1 дукхагIа {{PLURAL:$1|керда}}",
-       "pager-older-n": "{{PLURAL:$1|къаьнара дара|къаьнара дараш|къаьнара долaчарех}} $1",
+       "pager-newer-n": "{{PLURAL:$1|кердагIа}} $1-ннега",
+       "pager-older-n": "{{PLURAL:$1|къаьнагIа}} $1-ннега",
        "booksources": "Кинижкий хьасташ",
        "booksources-search-legend": "Джейнах лаьца хоам лахар",
        "booksources-search": "Хьалáха",
        "all-logs-page": "Деррига тIакхача йиш йола тептараш",
        "alllogstext": "{{SITENAME}} яхача сайта тептарий юкъара хьаязъяьр.\nХьалехараш къерда йиш я тептара тайпах, доакъашхочун цIерах (регистр лоархIаш я) е хьоахаяьча оагIонах (укхаза а иштта регистр лоархI).",
        "logempty": "Укх оагӀон дӀаяздаьраш тептара чу дац.",
+       "checkbox-select": "Харжар: $1",
+       "checkbox-all": "Деррига",
+       "checkbox-none": "Цхьаккха",
+       "checkbox-invert": "Инверт яр",
        "allpages": "Еррига оагIонаш",
        "prevpage": "Хьалха йоагIа оагIув ($1)",
        "allpagesfrom": "Гучаяха оагӀонаш, дӀайолалуш йола укх алапех:",
        "allpagesto": "Хьахьокхар соцадé укхун тӀа:",
        "allarticles": "Еррига оагIонаш",
        "allpagessubmit": "Кхоачашде",
+       "allpagesprefix": "Хьалаха оагӀонаш, дӀайолалуш йола укх алапах:",
        "allpages-hide-redirects": "ДIакъайладаха дӀа-хьа хьожавераш",
        "categories": "ОагӀаташ",
+       "categories-submit": "Хьахьокха",
+       "sp-deletedcontributions-contribs": "къахьегам",
        "linksearch": "Арахьара тIахьожаяргаш лахар",
        "linksearch-ns": "ЦIерий моттигаш:",
        "linksearch-ok": "Хьалаха",
        "linksearch-line": "$1 яхача оагIонна тIатовжам $2 чура",
+       "activeusers": "Хьинаре доакъашхой",
+       "activeusers-submit": "Хьахьокха хьинаре бола доакъашхой",
+       "listgrouprights": "Доакъашхой тоабан бокъонаш",
+       "listgrouprights-summary": "ЛохегIа Iохьоахаяьй укх вике чу йола доакъашхой тоабаш. Белгалъяьй цар торонаши бокъонаши.\nИштта, эшаш хила мег [[{{MediaWiki:Listgrouprights-helppage}}|кхыбола хоам]] а.",
+       "listgrouprights-key": "Легенда:\n* <span class=\"listgrouprights-granted\">ДIаенна бокъонаш</span>\n* <span class=\"listgrouprights-revoked\">ДӀаяьха бакъонаш</span>",
+       "listgrouprights-group": "Тоаба",
+       "listgrouprights-rights": "Бокъонаш",
        "listgrouprights-members": "(доакъашхой хьаязъяьр)",
        "listgrouprights-namespaceprotection-namespace": "ЦIерий моттиг",
+       "listgrants-rights": "Бокъонаш",
        "emailuser": "Доакъашхочоа каьхат",
+       "emailusername": "Доакъашхочун цIи:",
        "usermessage-editor": "Системан дIакхоачадар",
-       "watchlist": "Зем бара хьаязъяьр",
-       "mywatchlist": "Зем бара хьаязъяьр",
-       "watchlistfor2": "Цунна $1 $2",
+       "watchlist": "Зем",
+       "mywatchlist": "Зем",
+       "watchlistfor2": "Доакъашхо $1 $2",
+       "addwatch": "Зема хьаязъяьрá юкъеяьккха",
        "addedwatchtext": "Статья «[[:$1]]» а, цун дувца оттадара оагIув а тIатехай хьа [[Special:Watchlist|зем бара хьаязъяьра]].",
        "removedwatchtext": "Статья «[[:$1]]» а, иштта цун дувца оттадара оагIув а дIаяьккхай хьа [[Special:Watchlist|зем бара хьаязъяьр]] чура.",
        "watch": "Зем бе",
        "watchthispage": "Зем бе укх оагӀон",
        "unwatch": "Ма бе зем",
        "notanarticle": "Статья яц",
-       "watchlist-details": "Хьа зем бара хьаязъяьр чу $1 {{PLURAL:$1|оагIув}} я (иштта дувца оттадара оагIонаш а).",
+       "watchlist-details": "Хьа зема хьаязъяьра чу $1 {{PLURAL:$1|оагIув}} я (иштта я дувцара оагIонаш а).",
        "wlheader-showupdated": "Хувцаенна оагIонаш '''сома''' шрифтаца белгалъяьй.",
-       "wlnote": "Ð\9aIалÑ\85а Ñ\85Ñ\8cагойÑ\82 {{PLURAL:$2|Ñ\82IеÑ\85Ñ\8cаÑ\80Ñ\87а Ñ\81аÑ\85Ñ\8cаÑ\82а|Ñ\82IеÑ\85Ñ\8cаÑ\80Ñ\87а <strong>$2</strong> Ñ\81аÑ\85Ñ\8cаÑ\82а}} Ð´Ð°Ñ\8c Ñ\85инна {{PLURAL:$1|Ñ\82IеÑ\85Ñ\85Ñ\8cаÑ\80а Ñ\85Ñ\83вÑ\86ам|Ñ\82IеÑ\85хьара <strong>$1</strong> хувцам}} ($3 $4).",
+       "wlnote": "Ð\9bоÑ\85егIа Ñ\85Ñ\8cагойÑ\82 {{PLURAL:$2|Ñ\82IеÑ\85Ñ\8cаÑ\80Ñ\87а Ñ\81аÑ\85Ñ\8cаÑ\82а|Ñ\82IеÑ\85Ñ\8cаÑ\80Ñ\87а <strong>$2</strong> Ñ\81аÑ\85Ñ\8cаÑ\82а}} Ð´Ð°Ñ\8c Ñ\85инна {{PLURAL:$1|Ñ\82IеÑ\85Ñ\8cаÑ\80а Ñ\85Ñ\83вÑ\86ам|Ñ\82Iехьара <strong>$1</strong> хувцам}} ($3 $4).",
        "wlshowlast": "Хьахьокха тIехьарча $2 ден $1 сахьатá",
+       "watchlist-hide": "Ма хьокха",
+       "watchlist-submit": "Хьахьокха",
+       "wlshowtime": "МалагIча ха юкъа хиннар гойта деза:",
+       "wlshowhideminor": "зӀамига хувцамаш",
+       "wlshowhidebots": "бóташ",
+       "wlshowhideliu": "шоашка дагара йоазонаш дола доакъашхой",
+       "wlshowhideanons": "шоай цIераш къайлаяьха доакъашхой",
+       "wlshowhidepatr": "техка тоадаьраш",
+       "wlshowhidemine": "са тоадар",
+       "wlshowhidecategorization": "оагIаташ тIатохар",
        "watchlist-options": "Зем бара хьаязъяьра тоадараш",
        "watching": "Зем бара хьаязъяьр чу тIатохар",
        "unwatching": "Зем бара хьаязъяьр чура дIадаккхар",
        "enotif_reset": "Белгалъе еррига оагӀонаш бӀаргтехача санна",
+       "enotif_impersonal_salutation": "{{grammar:genitive|{{SITENAME}}}} – доакъашхо",
        "deletepage": "ДIаяккха оагIув",
-       "confirmdeletetext": "Оаш дIадийхад бIарчча дIадаккхар оагIон а (е сурта), цун деррига хувцара истори а. '''Дехар да''', бакъде шоай из бокъонца де безам болаш долга а, из дича хургдар кхеташ долга а, из дар укх [[{{MediaWiki:Policy-url}}|бокъонашца]] долга.",
-       "actioncomplete": "Ардам кхоачашдаьд",
-       "actionfailed": "Ардам кхоачашдаьдац",
+       "excontent": "чудар: «$1»",
+       "excontentauthor": "чухьнахьадар: «$1», цу оагIон цаI марка воаца автор ва [[Special:Contributions/$2|$2]] ([[User talk:$2|дувцара оагIув]])",
+       "delete-confirm": "$1 — дӀаяккхар",
+       "delete-legend": "ДӀаяккхар",
+       "historywarning": "<strong>Теркам:</strong> Хьо дӀаяккха гӀертача оагӀон тоадара истори я $1 {{PLURAL:$1|эрш}} чулоацаш:",
+       "confirmdeletetext": "Оаш дIадийхад еррига оагIув (е сурт) дIаяккхар а, цун деррига хувцара истори дIаяккхар а. '''Дехар да''', бакъде шоай из бокъонца де безам болаш долга а, из дича хургдар кхеташ долга а, из хьадар укх [[{{MediaWiki:Policy-url}}|бокъонашца]] долга а.",
+       "actioncomplete": "Кхоачашдаьд",
+       "actionfailed": "Кхоачашдаьдац",
        "deletedtext": "«$1» дIаяьккхай.\nХьажа $2 тIехьара дIадаккхарий хьаязъяьрга бIаргтохаргболаш.",
        "dellogpage": "ДӀадаккхарий тептар",
        "deletecomment": "Бахьан:",
        "deleteotherreason": "Кхыдола бахьан/тIатохар:",
        "deletereasonotherlist": "Кхыдола бахьан",
+       "deleting-backlinks-warning": "'''ДӀахьалхадаккхар:''' Iа дӀайоаккхаш йолча оагIонна тӀатовжаш я [[Special:WhatLinksHere/{{FULLPAGENAME}}|кхыйола оагӀонаш]].",
        "rollbacklink": "юхаяккха",
        "rollbacklinkcount": "юхататта $1 {{PLURAL:$1|нийсдар}}",
+       "rollback-success": "{{GENDER:$3|$1}} яха доакъашхочо тоадаьр юхататтад; юхайоалаяьй {{GENDER:$4|$2}} доакъашхочун эрш.",
        "protectlogpage": "ГIон тептар",
        "protectedarticle": "Лораяьй оагӀув «[[$1]]»",
        "modifiedarticleprotection": "Лорадара лагIа хийцад «[[$1]]» яхача оагIон",
        "protect-cascadeon": "Каскадни лорадар оттадаь йолча {{PLURAL:$1|1=кIалхагIа белгалъяь оагIон чу|кIалхагIа белгалъяь оагIонаш чу}} юкъеяьккха хилара бахьане ер оагIув хIанза лораяь я. Укх оагIон лорадара дарж хувцаро каскадни лорадар меттахдоаккхадац.",
        "protect-default": "Лорадар доацаш",
        "protect-fallback": "Могадаьд алхха ше «$1» волача доакъашхошта",
-       "protect-level-autoconfirmed": "Могадаьд алхха ше-ше къоабалбаь хинна доакъашхошта",
+       "protect-level-autoconfirmed": "Могадаьд алхха автохьатӀаийца доакъашхошта",
        "protect-level-sysop": "Могадаьд алхха администраторашта",
        "protect-summary-cascade": "каскадни",
        "protect-expiring": "чакхъйоала $1 (UTC)",
        "protect-cantedit": "Хьа хувца йиш яц укх оагIон лорадара лагIа, цун хувцам бе хьа бокъо ца хиларах.",
        "restriction-type": "Бокъонаш:",
        "restriction-level": "ТIакхоачилга лагIа:",
-       "restriction-edit": "Хувцам",
+       "restriction-edit": "Хувцар",
        "restriction-move": "ЦIи хувцаp",
        "restriction-create": "Хьакхоллар",
        "restriction-upload": "Доттар",
+       "undeletepage": "ДӀаяьхача оагӀонашка хьажар а уж меттаоттаяр а",
        "undeletelink": "бIаргтоха/юхадаккха",
        "undeleteviewlink": "хьажа",
+       "undeletedpage": "'''Меттаоттаяьй оагӀув «$1».'''\n\nТIехьарча хана дӀаяьха а юхаметтаоттаяь а хиннача оагIонашка хьажара духьа хьадела [[Special:Log/delete|тептар]].",
        "undelete-search-submit": "Хьалáха",
        "namespace": "ЦIерий моттигаш:",
        "invert": "Хержар юхадаккха",
-       "tooltip-invert": "Ð\9eÑ\82Ñ\82ае ÐµÑ\80 Ð±ÐµÐ»Ð³Ð°Ð»Ð¾, Ñ\85еÑ\80жа Ñ\86IеÑ\80ий Ð°Ñ\80е Ñ\87Ñ\83 Ð° (белгалÑ\8aÑ\8fÑ\8c Ñ\8fле Ð²IаÑ\88агIÑ\8aÑ\8eвзаенна Ñ\86IеÑ\80ий Ð°Ñ\80е Ñ\87Ñ\83 Ð°), Ð¾Ð°Ð³IонаÑ\88 Ñ\82Iа Ð° Ð´Ð°Ñ\8c хувцамаш къайладоахаргдолаш",
-       "namespace_association": "Ювзаенна Ð°Ñ\80е",
-       "tooltip-namespace_association": "Оттае ер белгало, иштта хержа цIерий ареца вIашагIъювзаенна дувца оттадара цIерий аре (е кхыяр) юкъейоаккхаргйолаш",
+       "tooltip-invert": "Ð\9eÑ\82Ñ\82ае ÐµÑ\80 Ð±ÐµÐ»Ð³Ð°Ð»Ð¾, Ñ\85еÑ\80жа Ñ\86IеÑ\80ий Ð¼ÐµÑ\82Ñ\82ига Ð´Ð¾Ð°Ð·Ð¾Ð½ Ñ\87Ñ\83Ñ\85Ñ\8c (белгалÑ\8aÑ\8fÑ\8c Ñ\8fле Ð²IаÑ\88агIÑ\8aÑ\8eвзаеннаÑ\87а Ñ\86IеÑ\80ий Ð¼ÐµÑ\82Ñ\82игаÑ\88ка Ð°) Ð¾Ð°Ð³IонаÑ\88 Ñ\82Iа Ð´Ð°Ñ\8c Ð´Ð¾Ð»Ð° хувцамаш къайладоахаргдолаш",
+       "namespace_association": "Ð\92IаÑ\88агIйийÑ\85ка Ð¼Ð¾Ñ\82Ñ\82иг",
+       "tooltip-namespace_association": "Оттае ер белгало, иштта хьахержача цIерий меттигаца вIашагIъювзаенна дувцара цIерий моттиг (е кхыяр) юкъейоаккхаргйолаш",
        "blanknamespace": "(Кертера)",
        "contributions": "{{GENDER:$1|Доакъашхочун}} къахьегам",
        "contributions-title": "{{GENDER:$1|Доакъашхочун}} $1 къахьегам",
-       "mycontris": "Са Ðºъахьегам",
+       "mycontris": "Ð\9aъахьегам",
        "anoncontribs": "Къахьегам",
        "contribsub2": "Къахьегам {{GENDER:$3|$1}} ($2)",
        "nocontribs": "ДIадийха хувцамаш корадаьдац",
        "month": "Укх бетт (кхы хьалхагIа)",
        "year": "Укх шер (кхы хьалхагIа):",
        "sp-contributions-newbies": "Хьахьокха алхха керда дагара йоазонашца баь бола къахьегам",
-       "sp-contributions-blocklog": "чIега тохараш",
-       "sp-contributions-uploads": "чуяьккхараш",
+       "sp-contributions-blocklog": "блок тохар",
+       "sp-contributions-deleted": "{{GENDER:$1|доакъашхочун}} дӀадаьккха хинна тоадар",
+       "sp-contributions-uploads": "чуяьхараш",
        "sp-contributions-logs": "тептараш",
        "sp-contributions-talk": "дувца оттадар",
+       "sp-contributions-userrights": "{{GENDER:$1|доакъашхочун}} бокъонашта урхалдар",
        "sp-contributions-search": "Къахьегама лахар",
        "sp-contributions-username": "IP-адрес е доакъашхочун цӀи:",
-       "sp-contributions-toponly": "Гойта алхха тIехьара версеш санна лоархIаш дола нийсдараш",
-       "sp-contributions-newonly": "ОагIонаш кхоллара мара хувцамаш ма гойта.",
+       "sp-contributions-toponly": "Гойта алхха тIехьара эршаш хинна дола тоадаьраш",
+       "sp-contributions-newonly": "Гойта алхха оагIонаш хьакхоллар.",
+       "sp-contributions-hideminor": "Къайладаха зIамига тоадаьраш",
        "sp-contributions-submit": "Хьалáха",
        "whatlinkshere": "Тӏатовжамаш укхаза",
        "whatlinkshere-title": "«$1» яхача оагӏонна тӏатовжаш йола оагӏонаш",
        "whatlinkshere-page": "ОагIув:",
-       "linkshere-2": "«'''$1'''» ← укхунна тӀахьожавеш я тӀехьайоагӀа оагӀонаш:",
-       "nolinkshere-2": "Кхыйолча оагӏонашкара '''$1''' яхача оагӏон тIатовжамаш доацаш да.",
+       "linkshere": "<strong>$2</strong> ← укхунна тӀахьожавеш я тӀехьайоагӀа оагӀонаш:",
+       "nolinkshere": "Кхыйолча оагӏонашкара <strong>$2</strong> яхача оагӏонна тIатовжамаш доацаш да.",
        "isredirect": "дIа-хьа хьожавара оагIув",
        "istemplate": "юкъейоалаяр",
        "isimage": "Файлови тӏатовжам",
-       "whatlinkshere-prev": "{{PLURAL:$1|1=хьалхайоагIа|хьалхайоагIараш}} $1",
-       "whatlinkshere-next": "{{PLURAL:$1|1=Ñ\82IеÑ\85Ñ\8cайоагIаÑ\80\82IеÑ\85Ñ\8cайоагIаÑ\80аÑ\88}} $1",
+       "whatlinkshere-prev": "{{PLURAL:$1|1=хьалхайоагIача|хьалхайоагIача}} $1-ннега",
+       "whatlinkshere-next": "{{PLURAL:$1|1=Ñ\82IеÑ\85Ñ\8cайоагIаÑ\87а|Ñ\82IеÑ\85Ñ\8cайоагIаÑ\87а}} $1-ннега",
        "whatlinkshere-links": "← тӏатовжамаш",
        "whatlinkshere-hideredirs": "$1 дӀа-хьа хьожавараш",
        "whatlinkshere-hidetrans": "$1 юкъедоаладаьраш",
        "whatlinkshere-hidelinks": "$1 тӏатовжамаш",
        "whatlinkshere-hideimages": "$1 файлай тIатовжамаш",
-       "whatlinkshere-filters": "ФилÑ\8cÑ\82Ñ\80аш",
+       "whatlinkshere-filters": "Ð\9bÑ\83Ñ\82Ñ\82аÑ\80гаш",
        "blockip": "ЧIега тоха {{GENDER:$1|доакъашхочун}}",
        "ipboptions": "2 сахьат:2 hours,1 ди:1 day,3 ди:3 days,1 кIира:1 week,2 кIира:2 weeks,1 бутт:1 month,3 бутт:3 months,6 бутт:6 months,1 шу:1 year,хоадаяь ха йоаца:infinite",
        "ipblocklist": "ЧIега теха доакъашхой",
        "movepagebtn": "ОагIон цIи хувца",
        "pagemovedsub": "ОагӀонах керда цӀи тиллай",
        "movepage-moved": "'''«$1» яхача оагӀонах «$2» яха цӀи тиллай'''",
+       "movepage-moved-redirect": "Хьакхеллад дIа-юхаластар",
        "articleexists": "Иззамо цӀи йола оагӀув тхьовре йолаш я е оаш тилла цӀи мегаш яц.\nДехар да, кхыйола цӀи харжа.",
        "movetalk": "Дувца оттадара оагӀон а хувца цӀи",
        "movelogpage": "ЦӀераш хувцара тептар",
        "movereason": "Бахьан:",
        "revertmove": "юха",
+       "delete_and_move_reason": "ДӀаяьккхай укх оагIон «[[$1]]» цӀи хувцара духьа",
        "export": "Оагӏоний экспорт",
        "allmessagesname": "Хоам",
        "allmessagesdefault": "Массаза йола текст",
+       "allmessages-filter-legend": "Луттарг",
        "allmessages-filter-all": "Еррига",
        "allmessages-language": "Мотт:",
        "allmessages-filter-submit": "Дехьавала",
        "importlogpage": "Импорта тептар",
        "tooltip-pt-userpage": "{{GENDER:|Хьа}} доакъашхочун оагIув",
        "tooltip-pt-mytalk": "{{GENDER:|Хьа}} дувца оттадара оагIув",
+       "tooltip-pt-anontalk": "Шун IP-цIайна лаьрхIа дувцара оагӀув",
        "tooltip-pt-preferences": "{{GENDER:|Хьа оттамаш}}",
        "tooltip-pt-watchlist": "Iа зем бу оагIонаш",
-       "tooltip-pt-mycontris": "{{GENDER:|хьа}} хувцамаш",
-       "tooltip-pt-login": "Укхаза хьай цIи аьле чувала/яла йиша я, амма из параз дац",
+       "tooltip-pt-mycontris": "{{GENDER:|Хьа}} хувцамаш",
+       "tooltip-pt-anoncontribs": "Укх IP-цIайна тIара даь хувцамаш",
+       "tooltip-pt-login": "Укхаза ражача чу а даьнна регистраци е йиш я.",
        "tooltip-pt-logout": "Аравала/яла",
-       "tooltip-pt-createaccount": "Ð¥Ñ\8cа Ð±Ð¾ÐºÑ\8aо Ñ\8f Ð´Ð°Ð³Ð°Ñ\80а Ð¹Ð¾Ð°Ð·Ñ\83в Ñ\85Ñ\8cа Ð° ÐºÑ\85елла Ñ\80ажаÑ\87а Ñ\87Ñ\83вала.",
+       "tooltip-pt-createaccount": "ШÑ\83н Ð±Ð¾ÐºÑ\8aо Ñ\8f Ð´Ð°Ð³Ð°Ñ\80а Ð¹Ð¾Ð°Ð·Ñ\83в Ñ\85Ñ\8cа Ð° ÐºÑ\85елла Ñ\80ажаÑ\87а Ñ\87Ñ\83довла.",
        "tooltip-ca-talk": "ОагIон чулоацамах лаьца дувцар",
        "tooltip-ca-edit": "Нийсъе ер оагIув",
        "tooltip-ca-addsection": "Керда дáкъа хьаде",
        "tooltip-ca-nstab-help": "Новкъостала оагIув",
        "tooltip-ca-nstab-category": "ОагӀата оагӀув",
        "tooltip-minoredit": "Ер хувцар кIезига дар санна белгалде",
-       "tooltip-save": "Ð¥Ñ\8cа Ñ\85Ñ\83вÑ\86амаÑ\88 Ð»Ð¾Ñ\80адеÑ\88 Ð´IаÑ\8fзде",
+       "tooltip-save": "Ð\94IаÑ\8fзде Ñ\85Ñ\8cай Ñ\85Ñ\83вÑ\86амаÑ\88",
        "tooltip-preview": "ОагIонна хьалххе бIаргтохар.\nДехар да, оагӀув дIаязъелехь хьажа из мишта я!",
        "tooltip-diff": "Чухьнахьара текстаца даь хувцамаш хьахьокха",
        "tooltip-compareselectedversions": "Укх оагIон хержа шин версешта юкъе йола башхалога хьажа.",
        "pageinfo-length": "ОагӀон йIоахал (байтах)",
        "pageinfo-article-id": "ОагӀон ID",
        "pageinfo-language": "ОагӀон мотт",
+       "pageinfo-language-change": "хувца",
        "pageinfo-content-model": "ОагӀон чудара модель",
+       "pageinfo-content-model-change": "хувца",
        "pageinfo-robot-policy": "Лахара роботашца йола индексаци",
        "pageinfo-robot-index": "Могадаьд",
        "pageinfo-robot-noindex": "Могадаьдац",
        "patrol-log-page": "ТӀахьожама тептар",
        "previousdiff": "← КъаьнагIа дола нийсдаьр",
        "nextdiff": "КердагӀа дола нийсдаьр →",
+       "imagemaxsize": "Сурта боарамá доазув тохар:<br />''(Файлах лаьца дувцача оагӀона)''",
+       "thumbsize": "Сурта зIамагIа йолча эрша боарам:",
        "widthheightpage": "$1 × $2, $3 {{PLURAL:$3|оагӀув}}",
        "file-info-size": "$1 × $2 {{PLURAL:$2|пиксель}}, файла боарам: $3, MIME-тайпа: $4",
        "file-info-size-pages": "$1 × $2 пиксель, файлан боарам: $3, MIME-тайп: $4, $5 {{PLURAL:$5|1=оагӀув}}",
        "show-big-image-preview": "Хьалххе бIаргтохача хана бола боарам: $1.",
        "show-big-image-other": "{{PLURAL:$2|1=Кхыбола тIера боарам}}: $1.",
        "show-big-image-size": "$1 × $2 пиксель",
+       "newimages-legend": "Луттарг",
        "noimages": "Суртaш дац.",
        "ilsubmit": "Хьалаха",
+       "days": "{{PLURAL:$1|$1 ди}}",
+       "weeks": "{{PLURAL:$1|$1 кӀира}}",
+       "months": "{{PLURAL:$1|$1 бутт}}",
+       "years": "{{PLURAL:$1|$1 шу}}",
+       "ago": "$1 хьалхагIа",
+       "just-now": "хIанзза",
+       "hours-ago": "$1 {{PLURAL:$1|сахьат}} хьалхагIа",
+       "minutes-ago": "$1 {{PLURAL:$1|минот}} хьалха",
+       "seconds-ago": "$1 {{PLURAL:$1|секунд}} хьалха",
+       "monday-at": "оршот дийнахь $1",
+       "tuesday-at": "шинара дийнахь $1",
+       "wednesday-at": "кхаьрача дийнахь $1",
+       "thursday-at": "ерача дийнахь $1",
+       "friday-at": "пӀаьраска дийнахь $1",
+       "saturday-at": "шоатта дийнахь $1",
+       "sunday-at": "кӀирандийнахь $1",
+       "yesterday-at": "селхан $1 даьлча",
        "bad_image_list": "Формат хила езаш я иштта:\n\nЛоархIаш хургда алхха хьаязъяьра элементаш (укх * яхача хьаракаца дIадолалуш дола могIараш).\nМогIара хьалхара тIатовжам хила безаш ба хьачудаккха йиш йоацача суртá тIатовжаш.\nАмма цун тIехьадоагIа тIатовжамаш тIатовжаш хургда сурт чуоттаде йиш йолча статьяшта.",
        "metadata": "Мета-дараш",
        "metadata-help": "Файло кхыдола дараш чулоац, цифрацара суртдоакхарго е сканеро тIатохаш дола. Нагахьа санна файл хьачуякхачул тIехьагIа хийца хинна яле, цхьаццайола параметраш хIанзарча сурта тIа йоацаш хила мег.",
        "metadata-fields": "Укх хьаязъяьра чу Iохьоахаяь сурта метадарий йистош хьахьекха хургья сурта оагIон тIа дIахьулъяьча метадарий таблица чу. Юхейиса йистош къайла хургья.\n* make\n* model\n* datetimeoriginal\n* exposuretime\n* fnumber\n* isospeedratings\n* focallength\n* artist\n* copyright\n* imagedescription\n* gpslatitude\n* gpslongitude\n* gpsaltitude",
        "exif-imagewidth": "Шерал",
        "exif-imagelength": "Лакхал",
+       "exif-bitspersample": "Беса кIоаргал",
        "exif-orientation": "Сурта белгало",
        "exif-xresolution": "ПхьорагIа тIера боарам",
        "exif-yresolution": "УрагIа тIера боарам",
        "exif-exposureprogram-1": "Кара",
        "exif-scenecapturetype-1": "Ландшафт",
        "exif-scenecapturetype-2": "Сага сурт",
+       "exif-dc-rights": "Бокъонаш",
        "exif-iimcategory-edu": "Дешарца Iомадар",
        "exif-iimcategory-evn": "Гонахье",
        "exif-iimcategory-hth": "УнахцIано",
        "exif-iimcategory-wea": "Хаоттам",
        "namespacesall": "деррига",
        "monthsall": "деррига",
+       "confirm-purge-title": "Укх оагIон кэш ӀоцIенъе",
        "confirm_purge_button": "Мега",
+       "confirm-purge-top": "Укх оагӀон кэш ӀоцIенъйой?",
+       "confirm-purge-bottom": "Кэш ӀоцӀенъячул тӀехьагIа оагIон тӀехьара эрш хьахьокхаргья.",
        "imgmultipagenext": "тӀехьайоагӀа оагӀув →",
        "imgmultigo": "Дехьавала!",
        "imgmultigoto": "$1 оагIон тIа дехьавала",
        "table_pager_limit_submit": "Кхоачашде",
-       "watchlisttools-clear": "IоцIанъе зем бара хьаязъяьр",
-       "watchlisttools-view": "Хьаязъяьр чура оагIонаш тIа дола хувцамаш",
+       "watchlistedit-normal-title": "Зема хьаязъяьр хувцар",
+       "watchlisttools-clear": "IоцIанъе зема хьаязъяьр",
+       "watchlisttools-view": "Хьаязъяьра чура оагIонаш тIа даь хувцамаш",
        "watchlisttools-edit": "Хьажа а хувца а хьаязъяьр",
-       "watchlisttools-raw": "Ð\9cаÑ\81Ñ\81аза Ð¹Ð¾Ð»Ð° Ñ\82екÑ\81Ñ\82 Ñ\81анна Ñ\85Ñ\83вÑ\86а",
+       "watchlisttools-raw": "Тоае Ñ\82екÑ\81Ñ\82 Ñ\81анна",
        "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|дувца оттадар]])",
        "duplicate-defaultsort": "Теркам. Долча тайпара дIанийсдара дIоагIа «$2» юхакъоастаду долча тайпара дIанийсдара хьалха хинна дIоагIа «$1».",
        "version": "Эрш",
        "specialpages-group-users": "Доакъашхойи бокъонаши",
        "specialpages-group-pages": "ОагIонай хьаязъяьраш",
        "specialpages-group-pagetools": "ОагIонашта эша кечалаш",
+       "specialpages-group-developer": "Кийчдархочун кечалаш",
        "external_image_whitelist": "#Ер мугI ший болча тайпара бита<pre>\n#Укхаз оттаде кастта дувлача выражений фрагменташ (// юкъе дола дакъа)\n#арахьара суртий URL адресашца дIанийсалургда уш.\n#Мегаргдола сурташ санна хьахьекха хургда, дIаходараш, сурташта тIахьожаяргаш санна хьахьекха хургда.\n#Укханца # долалуш дола могIараш алараш санна лоархIаш да.\n#МогIараш регистраца кIаьда дац\n\n#Укх могIара лакхе оттаде кастта дувлача выражений фрагменташ. Ер мугI ший болча тайпара бита</pre>",
-       "tag-filter": "[[Special:Tags|Ð\91елгалонай]] Ñ\84илÑ\8cÑ\82Ñ\80:",
+       "tag-filter": "[[Special:Tags|ФоÑ\81Ñ\82аÑ\88]] Ð»Ñ\83Ñ\82Ñ\82аÑ\80г:",
        "tag-filter-submit": "Литта",
-       "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|1=Ð\91елгало|Ð\91елгалонаш}}]]: $2)",
+       "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|1=ФоÑ\81Ñ\82|ФоÑ\81Ñ\82аш}}]]: $2)",
        "tag-mw-undo": "эшац",
-       "tags-title": "Ð\91елгалонаш",
-       "tags-tag": "Ð\91елгалон цӀи",
+       "tags-title": "ФоÑ\81Ñ\82аш",
+       "tags-tag": "ФоÑ\81Ñ\82а цӀи",
        "tags-hitcount-header": "Белгалдаь нийсдараш",
        "tags-active-yes": "XӀау",
        "tags-active-no": "A",
        "tags-edit": "нийсде",
+       "tags-delete": "дӀаяккха",
        "tags-hitcount": "$1 {{PLURAL:$1|1=хувцам|хувцамаш}}",
        "tags-create-submit": "Хьакхолла",
+       "tags-deactivate-submit": "ДӀайоае",
        "compare-page1": "ЦхьоаллагIа оагIув",
        "compare-page2": "ШоллагIа оагӀув",
        "compare-rev1": "Хьалхара эрш",
        "compare-rev2": "ШоллагӀа эрш",
+       "compare-submit": "ВIаши йиста",
        "htmlform-submit": "ДIадахьийта",
        "htmlform-reset": "Хувцамаш юхадаккха",
        "htmlform-selectorother-other": "Кхыдар",
        "duration-days": "{{PLURAL:$1|ди}}",
        "expand_templates_preview": "Хьалххе бIаргтохар",
        "pagelang-name": "ОагIув",
+       "pagelang-language": "Мотт",
        "special-characters-group-latin": "Латиний",
        "special-characters-group-greek": "Эллиной",
        "special-characters-group-cyrillic": "Кириллица",
        "special-characters-group-arabic": "Iарбий",
        "special-characters-group-persian": "Фаьрсий",
        "special-characters-group-hebrew": "Жугтий",
-       "randomrootpage": "Цаховш нийсъенна овлан оагӀув"
+       "mw-widgets-dateinput-no-date": "Ди хержадац",
+       "date-range-from": "Укх денз:",
+       "date-range-to": "Укх денга кхаччалца:",
+       "randomrootpage": "Цаховш нийсъенна овлан оагӀув",
+       "log-action-filter-rights": "Бокъонаш хувцаялара тайпа:",
+       "log-action-filter-all": "Еррига"
 }
index e99c976..9b69a62 100644 (file)
@@ -53,7 +53,7 @@
        "tog-watchlisthideminor": "Celez mikra redaktaji de la surveyaji",
        "tog-watchlisthideliu": "Celar l'editadi dal uzanti enrejistrita qui esas en la listo",
        "tog-watchlistreloadautomatically": "Rimontrez automatale la listo, kande filtrilo modifikesos (bezonas JavaScript)",
-       "tog-watchlistunwatchlinks": "Add direct unwatch/watch links to watchlist entries (bezonas l'uzo di JavaScript)",
+       "tog-watchlistunwatchlinks": "Adjuntar direkta ligili ({{int:Watchlist-unwatch}}/{{int:Watchlist-unwatch-undo}}) a la listi di pagini modifikita (bezonas l'uzo di JavaScript)",
        "tog-watchlisthideanons": "Celar de la listo l'editadi facita da anonima redakteri",
        "tog-watchlisthidepatrolled": "Celez patroliita chanji en la surveyo-listo",
        "tog-watchlisthidecategorization": "Celar la kategorizeso di pagini",
        "badarticleerror": "Ica ago ne povas facesar en ca pagino.",
        "cannotdelete": "Ne es posibla efacar la pagino od arkivo \"$1\".\nForsan, ulu ja efacis ol.",
        "cannotdelete-title": "Ne povas efacar pagino \"$1\"",
+       "delete-hook-aborted": "L'efaco di la pagino abortesis da ula extenso (\"hook\").\nNe existas expliko pri to.",
        "no-null-revision": "Ne povis krear nova nula-revizo por pagino \"$1\"",
        "badtitle": "Nekorekta titulo",
        "badtitletext": "La solicitita pagino esas nevalida, vakua od esas\nnekorekta interlinguale od interwikale ligilo.",
        "viewsourcetext": "Vu povas vidar ed kopiar la fonto-kodexo di ta pagino.",
        "viewyourtext": "Vu darfas vidar e kopiar la fonto di <strong>vua redakti</strong> ad ita pagino.",
        "protectedinterface": "Ita pagino provizas 'interface' texto por la programaro en ita wiki, ed esas protektita por preventar mis-uzo.\nPor introduktar o chanjar tradukaji di la wiki-i, voluntez vizitar [https://translatewiki.net/ translatewiki.net], la projeto qua provizas tradukaji a MediaWiki.",
-       "editinginterface": "<strong>Averto:</strong> Vu redaktas pagino qua uzesas por provizar 'interface' texto di la programaro.\nChanji a ta pagino chanjos la aspekto di pagini por altra uzeri di ta wiki.",
+       "editinginterface": "<strong>Averto:</strong> Vu redaktas pagino qua uzesas por furnisar texto di 'interface' por la programaro.\nModifiki en ica pagino chanjos l'aspekto di pagini por altra uzeri di ta wiki.",
        "translateinterface": "Por introduktar o chanjar tradukaji en omna wiki-i, voluntez uzar [https://translatewiki.net/ translatewiki.net], la komuna projeto MediaWiki.",
        "cascadeprotected": "Ica pagino protektesis kontre l'editado pro ke lua kontenajo transskribesas en la sequanta {{PLURAL:$1|pagino, qua esas|pagini, qui esas}} protektita kande selektesis por ol la formo di \"protekto en kaskado\":\n$2",
        "namespaceprotected": "Vu ne es permisita redaktar pagini en la nomaro <strong>$1</strong>.",
        "customcssprotected": "Vu ne es permisita redaktar ita CSS pagino nam ol kontenas personal ajustaji di altra uzero.",
+       "customjsonprotected": "Vu ne havas permiso por redaktar ica pagino JSON pro ke ol kontenas personal ajustaji di altra uzero.",
        "customjsprotected": "Vu ne es permisita redaktar ita JavaScript pagino nam ol kontenas personal ajustaji di altra uzero.",
        "mycustomcssprotected": "Vu ne es permisita redaktar ita CSS pagino.",
+       "mycustomjsonprotected": "Vu ne es permisita redaktar ita pagino JSON.",
        "mycustomjsprotected": "Vu ne es permisita redaktar ita JavaScript pagino.",
        "myprivateinfoprotected": "Vu ne es permisita redaktar vua privata informajo.",
        "mypreferencesprotected": "Vu ne es permisita redaktar vua preferaji.",
        "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.",
+       "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>",
        "viewpagelogs": "Videz registrari por ca pagino",
        "nohistory": "Ne esas redakto-historio por ica pagino.",
        "currentrev": "Aktuala versiono",
        "notextmatches": "Nula paginala texto fitas",
        "prevn": "antea {{PLURAL:$1|$1}}",
        "nextn": "sequanta {{PLURAL:$1|$1}}",
+       "prev-page": "Antea pagino",
        "prevn-title": "Antea $1 {{PLURAL:$1|rezultajo|rezultaji}}",
        "nextn-title": "Sequanta $1 {{PLURAL:$1|rezultajo|rezultaji}}",
        "shown-title": "Montrez $1 {{PLURAL:$1|rezulto|rezulti}} per pagino",
        "powersearch-remember": "Memorez la selektajo por futura serchi",
        "search-external": "Extera sercho",
        "searchdisabled": "La sercho en la kompleta texto desaktivigesis temporale pro superkargo dil servanto. Ni esperas riaktivigar ol pos facar ula proxima aktualigi. Dum ica tempo, vu povas serchar per Google.",
+       "search-error": "Eventis eroro dum serchado: $1",
        "preferences": "Preferaji",
        "mypreferences": "Preferaji",
        "prefs-edits": "Nombro di redaktaji:",
        "timezoneregion-europe": "Europa",
        "timezoneregion-indian": "Indiana Oceano",
        "timezoneregion-pacific": "Pacifico",
-       "allowemail": "Permisez e-posti de altra uzanti",
+       "allowemail": "Permisez e-posti de altra uzeri",
        "email-allow-new-users-label": "Permisez e-posti de la nova uzeri",
        "email-blacklist-label": "Impedez la sequanta uzeri sendar e-posto a me:",
        "prefs-namespaces": "Nomari",
        "prefs-help-email": "Informar vua adreso di e-posto esas fakultativa, tamen ol bezonesos se vu oblivior vua pasovorto e bezonor la sendo di nova pasovorto.",
        "prefs-help-email-others": "Vu povas anke selektar se permisos altri skribar a vu per e-posto, per ligilo en vua uzanto-pagino o diskuto-pagino.\nVua e-posto adreso ne revelesos, kande l'altri skribos a vu.",
        "prefs-help-email-required": "E-postala adreso es bezonata.",
-       "prefs-info": "Bazala informeso",
+       "prefs-info": "Bazala informo",
        "prefs-i18n": "Internacioniigo",
        "prefs-signature": "Signaturo",
        "prefs-timeoffset": "Registro dil tempo",
        "rcfilters-activefilters": "Agiva filtrili",
        "rcfilters-advancedfilters": "Rafinita filtrili",
        "rcfilters-limit-title": "Rezulti por montrar",
+       "rcfilters-limit-and-date-label": "$1 {{PLURAL:$1|modifikuro|modifikuri}}, $2",
        "rcfilters-date-popup-title": "Quanto di tempo por serchar",
        "rcfilters-days-title": "Recenta dii",
        "rcfilters-hours-title": "Recenta hori",
        "rcfilters-days-show-hours": "$1 {{PLURAL:$1|horo|hori}}",
        "rcfilters-quickfilters": "Konservita filtrili",
        "rcfilters-quickfilters-placeholder-title": "Nula filtrilo konservesis til nun",
+       "rcfilters-quickfilters-placeholder-description": "Por konservar vua ajusto di filtrili ed uzar li pose, kliktez en la marko-rubando ikono en la buxo adinfre, ube l'agiva filtrili montresas.",
        "rcfilters-savedqueries-defaultlabel": "Konservita filtrili",
+       "rcfilters-clear-all-filters": "Efacar omna filtrili",
        "rcfilters-show-new-changes": "Videz la maxim recenta chanji",
        "rcfilters-search-placeholder": "Filtrar la modifikuri (uzez la menuo o serchez segun la nomo dil filtrilo)",
+       "rcfilters-filterlist-feedbacklink": "Dicez a ni quon vu pensas pri la filtrili",
        "rcfilters-filter-editsbyself-label": "Vua modifikuri",
+       "rcfilters-filter-editsbyother-label": "Modifikuri da altri",
+       "rcfilters-filter-editsbyother-description": "Omna modififuri, ecepte vua propra.",
        "rcfilters-filter-user-experience-level-registered-label": "Enrejistrita",
+       "rcfilters-filter-user-experience-level-registered-description": "Enrejistrita redakteri.",
        "rcfilters-filter-user-experience-level-unregistered-label": "Sen registro",
        "rcfilters-filter-user-experience-level-unregistered-description": "Redakteri qui ne facis 'log in'.",
        "rcfilters-filter-user-experience-level-newcomer-label": "Nova uzeri",
+       "rcfilters-filter-user-experience-level-newcomer-description": "Enrejistrita uzeri qui havas min kam 10 redakturi o 4 dii di aktiveso.",
        "rcfilters-filter-user-experience-level-learner-label": "Lernanti",
        "rcfilters-filter-user-experience-level-learner-description": "Redakteri enrejistrita kun konoco inter \"Nova uzeri\" ed \"experta uzeri.\"",
        "rcfilters-filter-user-experience-level-experienced-label": "Experta uzeri",
        "rcfilters-filter-user-experience-level-experienced-description": "Plu kam 30 dii di agemeso e 500 redakti.",
+       "rcfilters-filter-bots-description": "Redakturi kreita da automatala informatikoprogrami.",
        "rcfilters-filter-humans-label": "Homala (ne 'bot')",
+       "rcfilters-filter-humans-description": "Redakturi kreita da homi.",
        "rcfilters-filtergroup-significance": "Senco",
+       "rcfilters-filtergroup-watchlist": "Pagini surveyata",
+       "rcfilters-filter-watchlist-watched-label": "En mea surveyo-listo",
+       "rcfilters-filter-watchlist-watched-description": "Modifikuri en pagini de vua surveyo-listo.",
+       "rcfilters-filter-watchlist-watchednew-label": "Nova modifikuri en la surveyo-listo",
        "rcfilters-filter-pageedits-label": "Redakti di pagini",
+       "rcfilters-filter-pageedits-description": "Redakturi en la kontenajo dil Wiki, diskuti, deskriptado di kategorii...",
        "rcfilters-filter-newpages-label": "Kreado di pagini",
-       "rcfilters-filter-categorization-label": "Modifiki di la kategorio",
+       "rcfilters-filter-newpages-description": "Redakturi qui kreas nova pagini.",
+       "rcfilters-filter-categorization-label": "Modifikuri di kategorio",
        "rcfilters-filter-logactions-label": "Agadi enrejistrata",
+       "rcfilters-filter-logactions-description": "Agadi dal administreri, kreado di konti, efaco di pagini, sendo di arkivi...",
+       "rcfilters-view-tags": "Redakturi etiketizata",
        "rcfilters-liveupdates-button": "Quika aktualigi",
        "rcnotefrom": "Infre {{PLURAL:$5|esas la chanjo|esas la chanji}} de <strong>$3, $4</strong> (montrata til <strong>$1</strong>).",
        "rclistfrom": "Montrar nova chanji startante de $3 $2",
        "recentchangeslinked-summary": "Skribez la nomo di ula pagino por vidar la modifikuri en pagini ligita ad ol. (Por vidar la membri di ula kategoriio, skribez Kategorio:Nomo di la kategorio). Chanji en la pagini qui esas en [[Special:Watchlist|vua surveryo-listo]] aparos en <strong>dika literi</strong>.",
        "recentchangeslinked-page": "Nomo di la pagino:",
        "recentchangeslinked-to": "Montrez chanji a pagini ligita a la specigita pagino vice",
+       "recentchanges-page-added-to-category": "[[:$1]] adjuntita a kategorio",
        "autochange-username": "Automatala chanjo di MediaWiki",
        "upload": "Adkargar arkivo",
        "uploadbtn": "Adkargar arkivo",
        "unusedimagestext": "La sequanta arkivi existas, ma ne esas enterigita en irga pagino.\nVoluntez remarkar ke altra ret-siti povus ligesar ad arkivo per direta URL, e do ol povus esar listizita hike malgre ke on aktive uzas lo.",
        "notargettitle": "Ne esas vakua pagino",
        "notargettext": "Vu ne definis en qua pagino agar ica funciono.",
+       "nopagetitle": "La pagino ne existas",
+       "nopagetext": "La pagino quon vu serchis ne existas.",
        "pager-newer-n": "{{PLURAL:$1|plu nova 1|plu nova $1}}",
        "pager-older-n": "{{PLURAL:$1|plu anciena 1|plu anciena $1}}",
        "apihelp-no-such-module": "Modulo « $1 » ne esis trovita.",
        "enotif_anon_editor": "anonima uzero $1",
        "deletepage": "Efacar pagino",
        "confirm": "Konfirmez",
-       "excontent": "La kontenajo esis: '$1'",
+       "excontent": "La kontenajo esis: \"$1\"",
        "excontentauthor": "la kontenajo esis: \"$1\", e l'unika redaktero esis \"[[Special:Contributions/$2|$2]]\" ([[User talk:$2|talk]])",
        "exbeforeblank": "La kontenajo ante efaco esis: '$1'",
        "delete-confirm": "Efacar \"$1\"",
        "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.",
+       "logentry-contentmodel-change-revertlink": "restaurar",
+       "logentry-contentmodel-change-revert": "restaurar",
        "protectlogpage": "Protekto-registraro",
        "protectedarticle": "protektita \"[[$1]]\"",
        "modifiedarticleprotection": "la nivelo di protekto modifikesis a \"[[$1]]\"",
        "protectexpiry": "Expiras:",
        "protect_expiry_invalid": "Expirotempo es ne-valida.",
        "protect_expiry_old": "Expirotempo es in pasinta.",
+       "protect-cascadeon": "Ica pagino esas nune protektita, pro ke existas kopio de ol en {{PLURAL:$1|pagino qua|pagini qui}} protektesas \"seriale\" (cascade protection).\nModifiki en la nivelo di protektado por ica pagino ne modifikos la \"protekto seriala\".",
        "protect-default": "Permisar omna uzanti",
        "protect-fallback": "Permisez nur uzeri kun permiso \"$1\"",
        "protect-level-autoconfirmed": "Permisar nur uzeri automatale konfirmata",
        "whatlinkshere": "Quo ligesas adhike",
        "whatlinkshere-title": "Pagini qui ligas ad \"$1\"",
        "whatlinkshere-page": "Pagino:",
-       "linkshere-2": "Ca pagini esas ligilizita ad '''$1''':",
-       "nolinkshere-2": "Nula pagino ligas ad '''$1'''.",
+       "linkshere": "Ca pagini esas ligilizita a(d) <strong>$2</strong>:",
+       "nolinkshere": "Nula pagino ligas ad <strong>$2</strong>.",
        "isredirect": "ridirektanta pagino",
        "istemplate": "inkluzo",
        "isimage": "arkivo-ligilo",
        "whatlinkshere-filters": "Filtrili",
        "block": "Blokusar uzero",
        "blockip": "Blokusado di IP-adresi",
-       "blockiptext": "Uzez la formulario adinfre por blokusar aceso de specifika adreso IP o de specifika uzeronomo.\nFacez to NUR POR PREVENTAR VANDALISMO, e segun la [[{{MediaWiki:Policy-url}}|politiko de ica Wiki]].\nInformez adinfre la specifika motivi (example, mencionez specifika pagini qui subisis vandalismo dal IP/uzero).\nVu povas blokusar serio di adresi IP per l'uzo dil sintaxo [https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing CIDR]; la maxim longa serio permisata esas /$1 por IPv4 e /$2 por IPv6.",
+       "blockiptext": "Uzez la formulario adinfre por blokusar aceso de specifika adreso IP o de specifika uzeronomo.\nFacez to NUR POR PREVENTAR VANDALISMO, e segun la [[{{MediaWiki:Policy-url}}|politiko de ica Wiki]].\nInformez adinfre la specifika motivi (exemple, mencionez specifika pagini qui subisis vandalismo dal IP/uzero).\nVu povas blokusar serio di adresi IP per l'uzo dil sintaxo [https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing CIDR]; la maxim longa serio permisata esas /$1 por IPv4 e /$2 por IPv6.",
        "ipaddressorusername": "IP-adreso od uzantonomo:",
        "ipbexpiry": "Expiro:",
        "ipbreason": "Motivo:",
        "ipboptions": "2 hori:2 hours,1 dio:1 day,3 dii:3 days,1 semano:1 week,2 semani:2 weeks,1 monato:1 month,3 monati:3 months,6 monati:6 months,1 yaro:1 year,nefinita:infinite",
        "ipbwatchuser": "Vigilar la pagino di prizentado e la pagino di diskuto de ica uzero",
        "ipb-disableusertalk": "Impedar l'uzero redaktar en lua propra diskutopagino dum la blokuso",
+       "ipb-change-block": "Riblokuzar l'uzero pro altra motivi",
        "badipaddress": "IP-adreso ne esas valida",
        "blockipsuccesssub": "Blokusado sucesis",
        "blockipsuccesstext": "[[Special:Contributions/$1|$1]] blokusesis.<br />\nVidez [[Special:BlockList|IP-blokuslisto]] por revizor blokusadi.",
        "ipb-edit-dropdown": "Redaktar blokuso-motivi",
+       "ipb-unblock-addr": "Desblokusar $1",
+       "ipb-blocklist": "Vidar existanta blokusi",
        "ipb-blocklist-contribs": "Kontributadi dil uzero {{GENDER:$1|$1}}",
        "unblockip": "Desblokusar uzero",
        "unblockiptext": "Uzez la sequanta formularo por restaurar la skribo-aceso ad IP-adreso qua blokusesis antee.",
        "ipblocklist-submit": "Serchar",
        "ipblocklist-otherblocks": "Altra {{PLURAL:$1|blokuso|blokusi}}",
        "infiniteblock": "nefinita",
+       "emailblock": "e-posto blokusita",
        "blocklist-nousertalk": "ne povas redaktar lua propra diskuto-pagino",
        "blocklink": "blokusar",
        "unblocklink": "desblokusar",
        "contribslink": "kontrib",
        "autoblocker": "Autoblokusita nam vu havas la sama IP-adreso kam \"[[User:$1|$1]]\". Motivo: \"$2\"",
        "blocklogpage": "Blokuso-registraro",
+       "blocklog-showlog": "Ica uzero ja blokusesis antee.\nInfre esas l'informo pri la blokuso, por vua konoco:",
        "blocklogentry": "blokusis [[$1]] dum periodo de $2 $3",
        "reblock-logentry": "modifikis la tempo di blokuso [[$1]] por durado di $2 $3",
        "unblocklogentry": "desblokusis \"$1\"",
        "block-log-flags-noemail": "e-posto blokusita",
        "block-log-flags-nousertalk": "ne povas redaktar lua propra diskuto-pagino",
        "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}}",
        "ip_range_invalid": "Nevalida IP-rango.",
        "proxyblocker": "Blokuso di 'Proxy'",
        "monthsall": "omna",
        "confirmemail": "Konfirmez adreso di e-posto",
        "confirmemail_needlogin": "Vu mustas $1 pro konfirmar vua adreso di e-posto.",
+       "confirmemail_loggedin": "Vua adreso di e-posto konfirmesis nun.",
        "notificationemail_subject_changed": "L'adreso di e-posto en {{SITENAME}} modifikesis",
        "scarytranscludetoolong": "[URL es tro longa]",
        "deletedwhileediting": "'''Averto''': Ta pagino efacesis pos ke vu redakteskis!",
        "watchlistedit-raw-explain": "Tituli en vua surveyo-listo montresas adinfre, e povas modifikesar per adjuntado od eskarto de la listo; nur un titulo per lineo.\nKande vu finos, kliktez \"{{int:Watchlistedit-raw-submit}}\".\nVu anke povas [[Special:EditWatchlist|uzar la redaktero ordinara ('standard')]].",
        "watchlistedit-raw-titles": "Tituli:",
        "watchlistedit-raw-submit": "Aktualigar surveyo-listo",
+       "watchlistedit-clear-title": "Vakuigar la surveyo-listo",
+       "watchlistedit-clear-legend": "Vakuigar la surveyo-listo",
+       "watchlistedit-clear-explain": "Omna tituli eliminesos de vua surveyo-listo",
+       "watchlistedit-clear-submit": "Vakuigar la surveyo-listo (To esas permananta!)",
        "watchlistedit-too-many": "Esas multa pagini por montrar hike.",
        "watchlisttools-clear": "Vakuigar la surveyo-listo",
        "watchlisttools-view": "Vidar relatanta chanji",
        "redirect-file": "Arkivo-nomo",
        "fileduplicatesearch-submit": "Serchar",
        "specialpages": "Specala pagini",
+       "specialpages-group-maintenance": "Raporti pri manteno",
        "specialpages-group-other": "Altra specala pagini",
        "specialpages-group-login": "Enirar / krear konto",
        "specialpages-group-changes": "Recenta chanji e registri",
        "tags-delete-too-many-uses": "L'etiketo \"$1\" uzesas en plua kam $2 {{PLURAL:$2|revizo|revizi}}, do ol ne povas eskartesar.",
        "tags-delete-warnings-after-delete": "L'etiketo \"$1\" efacesis, ma la sequanta {{PLURAL:$2|avizo|avizi}} renkontresis:",
        "tags-activate-not-found": "L'etiketo \"$1\" ne existas.",
+       "tags-update-blocked": "Dum ke {{GENDER:$1|vu}} blokusabos, vu ne povos modifikar od efacar etiketi.",
+       "dberr-problems": "Pardonez! Ica retopagino subisas teknikala problemi.",
+       "dberr-again": "Voluntez vartar kelka minuti, e riprobez acesar ol.",
+       "dberr-info": "(Ne povis acesar la datumaro: $1)",
+       "dberr-info-hidden": "(La datumaro ne esas disponebla)",
+       "dberr-outofdate": "Atencez ke l'indexi pri kontenaji povas esar antiquatra.",
        "htmlform-reset": "Desfacar chanji",
        "htmlform-selectorother-other": "Altra",
        "htmlform-cloner-create": "Adjuntar plue",
        "duration-years": "$1 {{PLURAL:$1|yaro|yari}}",
        "limitreport-title": "Analizo di dati pri profilo:",
        "limitreport-ppvisitednodes": "Quanto di nodi vizitita dal preprocesoro",
+       "limitreport-ppgeneratednodes": "Quanto di nodi kreita dal preprocesoro",
        "limitreport-postexpandincludesize": "Grandeso dil inkluzo pos expanso",
        "limitreport-expansiondepth": "Maxima profundeso di expanso",
        "limitreport-expensivefunctioncount": "Kontado di funcioni kustoza di analizo sintaxala",
        "mw-widgets-titleinput-description-redirect": "Ridirektar ad $1",
        "sessionprovider-nocookies": "''Bisquiti'' forsan esas desacendita. Certigez ke vu acendar ''bisquiti'' e riprobez.",
        "randomrootpage": "Hazarda radikopagino",
-       "log-action-filter-delete": "Tipo di efacado:"
+       "log-action-filter-delete": "Tipo di efacado:",
+       "log-action-filter-suppress-reblock": "User suppression by reblock"
 }
index 47cd5be..f14b845 100644 (file)
        "customcssprotected": "Þú hefur ekki leyfi að breyta þessari CSS-umbrotsíðu, því hún hefur notandastillingar annars notanda.",
        "customjsprotected": "Þú hefur ekki leyfi til að breyta þessari JavaScript síðu, því hún hefur notandastillingar annars notanda.",
        "mycustomcssprotected": "Þú hefur ekki leyfi til þess að breyta þessari CSS-síðu.",
+       "mycustomjsonprotected": "Þú hefur ekki heimild til að breyta þessari JSON-síðu.",
        "mycustomjsprotected": "Þú hefur ekki leyfi til þess að breyta þessari JavaScript-síðu.",
        "myprivateinfoprotected": "Þú ert ekki með réttindi til að breyta einkaupplýsingunum þínum.",
        "mypreferencesprotected": "Þú ert ekki með réttindi til að breyta kjörstillingunum þínum.",
        "wrongpasswordempty": "Lykilorðsreiturinn var auður. Reyndu aftur.",
        "passwordtooshort": "Lykilorð skal vera að minnsta kosti $1 {{PLURAL:$1|stafur|stafir}}.",
        "passwordtoolong": "Lykilorð geta ekki verið lengri en $1 {{PLURAL:$1|stafur|stafir}}.",
-       "passwordtoopopular": "Ekki má nota algeng lykilorð. Veldu eitthvað alveg sérstakt lykilorð.",
+       "passwordtoopopular": "Ekki má nota títt valin lykilorð. Vinsamlegast velja lykilorð sem erfiðara er að giska á.",
        "password-name-match": "Þarf að lykilorð þitt sé öðruvísi notandanafni þínu",
        "password-login-forbidden": "Notkun þessa notandanafns og lykilorðs er ekki leyfileg.",
        "mailmypassword": "Endurstilla lykilorð",
        "botpasswords-existing": "Fyrirliggjandi lykilorð vélmenna",
        "botpasswords-createnew": "Búa til nýtt lykilorð vélmennis",
        "botpasswords-editexisting": "Breyta fyrirliggjandi lykilorði vélmennis",
+       "botpasswords-label-needsreset": "(lykilorð þarf að endurstilla)",
        "botpasswords-label-appid": "Heiti vélmennis:",
        "botpasswords-label-create": "Búa til",
        "botpasswords-label-update": "Uppfæra",
        "savechanges": "Vista breytingar",
        "publishpage": "Gefa út síðu",
        "publishchanges": "Gefa út breytingar",
+       "savearticle-start": "Vista síðu…",
+       "savechanges-start": "Vista breytingar…",
+       "publishpage-start": "Birta síðu...",
+       "publishchanges-start": "Gefa út breytingar...",
        "preview": "Forskoða",
        "showpreview": "Forskoða",
        "showdiff": "Sýna breytingar",
        "anoneditwarning": "<strong>Viðvörun:</strong> Þú ert ekki innskráð(ur). Vistfang þitt verður sýnt opinberlega ef þú gerir einhverjar breytingar. Ef þú <strong>[$1 skráir þig inn]</strong> eða <strong>[$2 stofnar aðgang]</strong> munu breytingarnar þínar vera tengdar við notandanafn þitt, ásamt öðrum kostum.",
        "anonpreviewwarning": "<em>Þú ert ekki skráð(ur) inn. Vistfang þitt skráist í breytingaskrá síðunnar.</em>",
        "missingsummary": "'''Áminning:''' Þú hefur ekki skrifað breytingarágrip.\nEf þú smellir á Vista aftur, verður breyting þín vistuð án þess.",
+       "selfredirect": "<strong>Viðvörun:</strong> Þú ert að vísa þessa síðu á sjálfa sig.\nÞað kann að vera að þú hafir valið vitlausa marksíðu fyrir tilvísunina eða að þú sért að breyta vitlausri síðu.\nEf þú smellir aftur á „$1“ verður tilvísunin samt búin til.",
        "missingcommenttext": "Gerðu svo vel og skrifaðu athugasemd.",
        "missingcommentheader": "<strong>Áminning:</strong> Þú hefur ekki gefið upp umræðuefni.\nEf þú smellir á \"$1\" aftur, verður breyting þín vistuð án þess.",
        "summary-preview": "Forskoða breytingarágrip:",
        "subject-preview": "Forskoðun viðfangsefnis:",
        "previewerrortext": "Óvænt villa kom upp þegar reynt var að forskoða breytingarnar þínar.",
        "blockedtitle": "Notandi er bannaður",
-       "blockedtext": "'''Notandanafn þitt eða vistfang hefur verið bannað.'''\n\nBannið var sett af $1.\nÁstæðan er eftirfarandi: ''$2''.\n\n* Bannið hófst: $8\n* Banninu lýkur: $6\n* Sá sem banna átti: $7\n\nÞú getur haft samband við $1 eða annan [[{{MediaWiki:Grouppage-sysop}}|stjórnanda]] til að ræða bannið.\nÞú getur ekki notað „Senda þessum notanda tölvupóst“ aðgerðina nema gilt netfang sé skráð í [[Special:Preferences|kjörstillingum þínum]] og að þér hafi ekki verið óheimilað það.\nNúverandi vistfang þitt er $3, og bannnúmerið er #$5.\nHafðu með allar þessar upplýsingar hér fyrir ofan í fyrirspurnum þínum.",
-       "autoblockedtext": "Vistfang þitt hefur verið sjálfvirkt bannað því það var notað af öðrum notanda, sem var bannaður af $1.\nÁstæðan er eftirfarandi:\n\n:''$2''\n\n* Bannið hófst: $8\n* Banninu lýkur: $6\n* Sá sem banna átti: $7\n\nÞú getur haft samband við $1 eða annan [[{{MediaWiki:Grouppage-sysop}}|stjórnanda]] til að ræða bannið.\n\nAthugaðu að þú getur ekki notað „Senda þessum notanda tölvupóst“ aðgerðina nema gilt netfang sé skráð í [[Special:Preferences|kjörstillingum þínum]] og að þér hafi ekki verið óheimilað það.\n\nNúverandi vistfang þitt er $3, og bannnúmerið er #$5.\nHafðu með allar þessar upplýsingar hér fyrir ofan í fyrirspurnum þínum.",
+       "blockedtext": "<strong>Þitt notandanafn eða vistfang hefur verið bannað.</strong>\n\nBannið var sett af $1.\nÁstæðan er eftirfarandi: <em>$2</em>.\n\n* Bannið hófst: $8\n* Banninu lýkur: $6\n* Sá sem banna átti: $7\n\nÞú getur haft samband við $1 eða annan [[{{MediaWiki:Grouppage-sysop}}|stjórnanda]] til að ræða bannið.\nÞú getur ekki notað „Senda þessum notanda tölvupóst“ aðgerðina nema gilt netfang sé skráð í [[Special:Preferences|kjörstillingum þínum]] og að þér hafi ekki verið óheimilað það.\nNúverandi vistfang þitt er $3, og bannnúmerið er #$5.\nHafðu með allar þessar upplýsingar hér fyrir ofan í fyrirspurnum þínum.",
+       "autoblockedtext": "Vistfang þitt hefur verið sjálfvirkt bannað því það var notað af öðrum notanda, sem var bannaður af $1.\nÁstæðan er eftirfarandi:\n\n:<em>$2</em>\n\n* Bannið hófst: $8\n* Banninu lýkur: $6\n* Sá sem banna átti: $7\n\nÞú getur haft samband við $1 eða annan [[{{MediaWiki:Grouppage-sysop}}|stjórnanda]] til að ræða bannið.\n\nAthugaðu að þú getur ekki notað „Senda þessum notanda tölvupóst“ aðgerðina nema gilt netfang sé skráð í [[Special:Preferences|kjörstillingum þínum]] og að þér hafi ekki verið óheimilað það.\n\nNúverandi vistfang þitt er $3, og bannnúmerið er #$5.\nHafðu með allar þessar upplýsingar hér fyrir ofan í fyrirspurnum þínum.",
        "systemblockedtext": "Notandanafnið þitt eða IP-vistfangið hafa verið útilokuð sjálfvirkt af MediaWiki.\nUppgefin ástæða er:\n\n:<em>$2</em>\n\n* Upphaf útilokunar: $8\n* Útilokun rennur út: $6\n* Sá sem átti að útiloka: $7\n\nNúverandi IP-vistfang þitt er$3.\nHafðu allar þessar upplýsingar með í öllum þeim fyrirspurnum sem þú gætir gert vegna þessa.",
        "blockednoreason": "engin ástæða gefin",
        "whitelistedittext": "Þú þarft að $1 þig til að breyta síðum.",
        "blocked-notice-logextract": "Þessi notandi er í banni.\nSíðasta færsla notandans úr bannskrá er birt hér fyrir neðan til skýringar:",
        "clearyourcache": "<strong>Athugaðu:</strong> Eftir vistun kann að vera að þú þurfir að komast hjá skyndiminni vafrans þíns til að sjá breytingarnar.\n* <strong>Firefox / Safari:</strong> Haltu <em>Shift</em> samtímis og þú smellir á <em>Endurhlaða (Reload)</em>, eða ýttu á annaðhvort <em>Ctrl-F5</em> eða <em>Ctrl-R</em> (<em>⌘-R</em> á Mac)\n* <strong>Google Chrome:</strong> Ýttu á <em>Ctrl-Shift-R </em>(<em>⌘-Shift-R</em> á Mac)\n* <strong>Internet Explorer:</strong> Haltu <em>Ctrl</em> samtímis og þú smellir á <em>Endurnýja (Refresh)</em>, eða ýttu á <em>Ctrl-F5</em>\n* <strong>Opera:</strong> Farðu í <em>Verkfæri (Tools) → Stillingar (Preferences)</em> og svo <em>Friðhelgi og öryggi (Privacy & security) → Hreinsa vafragögn (Clear browsing data) → Myndir og skrár í skyndiminni (Chached images and files)</em>",
        "usercssyoucanpreview": "'''Ath:''' Hægt er að nota „{{int:showpreview}}“ hnappinn til að prófa CSS-kóða áður en hann er vistaður.",
+       "userjsonyoucanpreview": "<strong>Ath.:</strong> Hægt er að nota hnappinn „{{int:showpreview}}“ til að prófa JSON-kóða áður en hann er vistaður.",
        "userjsyoucanpreview": "'''Ath:''' Hægt er að nota \"{{int:showpreview}}\" hnappinn til að prófa JavaScript-kóða áður en hann er vistaður.",
        "usercsspreview": "'''Mundu að þú ert aðeins að forskoða CSS-kóðann þinn.'''\n'''Hann hefur ekki enn verið vistaður!'''",
        "userjspreview": "'''Mundu að þú ert aðeins að prófa/forskoða JavaScript-kóðann þinn.'''\n'''Hann hefur ekki enn verið vistaður!'''",
        "rcfilters-other-review-tools": "Önnur rýniverkfæri",
        "rcfilters-group-results-by-page": "Flokka niðurstöður eftir síðum",
        "rcfilters-activefilters": "Virkar síur",
+       "rcfilters-activefilters-hide": "Fela",
+       "rcfilters-activefilters-show": "Sýna",
        "rcfilters-advancedfilters": "Ítarlegar síur",
        "rcfilters-limit-title": "Breytingar sem á að birta",
        "rcfilters-limit-and-date-label": "$1 {{PLURAL:$1|breyting|breytingar}}, $2",
        "rcfilters-savedqueries-rename": "Endurnefna",
        "rcfilters-savedqueries-setdefault": "Setja sem sjálfgefið",
        "rcfilters-savedqueries-unsetdefault": "Fjarlægja sjálfgefið",
-       "rcfilters-savedqueries-remove": "Fjarlægja",
+       "rcfilters-savedqueries-remove": "Eyða",
        "rcfilters-savedqueries-new-name-label": "Heiti",
        "rcfilters-savedqueries-new-name-placeholder": "Lýstu markmiði síunnar",
        "rcfilters-savedqueries-apply-label": "Búa til síu",
        "deadendpages": "Botnlangar",
        "deadendpagestext": "Eftirfarandi síður tengjast ekki við aðrar síður á {{SITENAME}}.",
        "protectedpages": "Verndaðar síður",
+       "protectedpages-filters": "Síur:",
        "protectedpages-indef": "Aðeins óendanlegar verndanir",
        "protectedpages-summary": "Þessi skrá sýnir lista yfir síður sem eru til og eru verndaðar í auknablikinu. Til að sjá lista yfir titla sem eru verndaðir gegn stofnun þeirra, sjáðu [[{{#special:ProtectedTitles}}|{{int:protectedtitles}}]].",
        "protectedpages-cascade": "Keðjuverndun eingöngu",
        "apisandbox-dynamic-parameters-add-label": "Bæta við viðfangi:",
        "apisandbox-dynamic-parameters-add-placeholder": "Heiti viðfangs",
        "apisandbox-deprecated-parameters": "Úrelt viðföng",
+       "apisandbox-add-multi": "Bæta við",
        "apisandbox-submit-invalid-fields-title": "Sumir reitir eru ógildir",
        "apisandbox-results": "Niðurstöður",
+       "apisandbox-sending-request": "Sendir API-beiðni...",
        "apisandbox-request-url-label": "Slóð á beiðni:",
        "apisandbox-request-format-json-label": "JSON",
        "apisandbox-request-json-label": "JSON beiðni:",
        "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",
+       "changecontentmodel-legend": "Breyta efnislíkani",
        "changecontentmodel-title-label": "Titill síðu",
+       "changecontentmodel-model-label": "Nýtt efnislíkan",
        "changecontentmodel-reason-label": "Ástæða:",
        "changecontentmodel-submit": "Breyta",
+       "changecontentmodel-success-title": "Efnislíkaninu var breytt",
        "logentry-contentmodel-change-revertlink": "taka aftur",
        "logentry-contentmodel-change-revert": "taka aftur",
        "protectlogpage": "Verndunarskrá",
        "whatlinkshere": "Hvað tengist hingað",
        "whatlinkshere-title": "Síður sem tengjast „$1“",
        "whatlinkshere-page": "Síða:",
-       "linkshere-2": "Eftirfarandi síður tengjast á '''$1''':",
-       "nolinkshere-2": "Engar síður tengjast á '''$1'''.",
-       "nolinkshere-ns-2": "Engar síður tengjast '''$1''' í þessu nafnrými.",
+       "linkshere": "Eftirfarandi síður tengjast á '''$2''':",
+       "nolinkshere": "Engar síður tengjast á '''$2'''.",
+       "nolinkshere-ns": "Engar síður tengjast '''$2''' í þessu nafnrými.",
        "isredirect": "endurbeind síða",
        "istemplate": "innifalið",
        "isimage": "skráartengill",
        "unblocked-id": "Bann $1 hefur verið fjarlægt",
        "unblocked-ip": "[[Special:Contributions/$1|$1]] hefur verið afbannaður.",
        "blocklist": "Bannaðir notendur og vistföng",
+       "autoblocklist": "Sjálfvirk bönn",
        "autoblocklist-submit": "Leita",
+       "autoblocklist-legend": "Sýna sjálfvirk bönn",
+       "autoblocklist-total-autoblocks": "Samanlagður fjöldi sjálfvirkra banna: $1",
+       "autoblocklist-empty": "Listinn yfir sjálfvirk bönn er tómur.",
+       "autoblocklist-otherblocks": "{{PLURAL:$1|Annað sjálfvirkt bann|Önnur sjálfvirk bönn}}",
        "ipblocklist": "Bannaðir notendur og vistföng",
        "ipblocklist-legend": "Finna bannaðan notanda",
        "blocklist-userblocks": "Fela notendabönn",
        "tooltip-ca-nstab-help": "Sýna hjálparsíðuna",
        "tooltip-ca-nstab-category": "Sýna efnisflokkasíðuna",
        "tooltip-minoredit": "Merkja þessa breytingu sem minniháttar",
-       "tooltip-save": "Vista breytingarnar",
-       "tooltip-publish": "Gefa út breytingarnar þínar",
+       "tooltip-save": "Vista breytingar þínar",
+       "tooltip-publish": "Gefa út breytingar þínar",
        "tooltip-preview": "Forskoða breytingarnar þínar. Gerðu þetta áður en þú vistar.",
        "tooltip-diff": "Sýna hvaða breytingar þú gerðir á textanum.",
        "tooltip-compareselectedversions": "Sjá breytingarnar á þessari grein á milli útgáfanna sem þú valdir.",
        "markedaspatrollederrornotify": "Mistókst að merkja síðuna sem yfirfarna.",
        "patrol-log-page": "Yfirferðarskrá",
        "patrol-log-header": "Þetta er skrá yfir yfirfarnar breytingar.",
-       "log-show-hide-patrol": "$1 listi yfir yfirfarnar síður",
-       "log-show-hide-tag": "$1 merkjaannáll",
        "confirm-markpatrolled-button": "Í lagi",
        "deletedrevision": "Eyddi gamla útgáfu $1",
        "filedeleteerror-short": "Villa við eyðingu: $1",
        "version-specialpages": "Kerfissíður",
        "version-parserhooks": "Tengikrókar þáttara (parser hooks)",
        "version-variables": "Breytur",
+       "version-editors": "Ritstjórar",
        "version-antispam": "Varnir gegn amasendingum",
        "version-api": "API",
        "version-other": "Aðrar",
        "tag-mw-new-redirect": "Ný endurbeining",
        "tag-mw-removed-redirect": "Fjarlægði endurbeiningu",
        "tag-mw-replace": "Skipt út",
+       "tag-mw-rollback": "Afturköllun",
        "tag-mw-undo": "Afturkalla",
        "tags-title": "Merki",
        "tags-intro": "Þessi síða sýnir merkin sem hugbúnaðurinn gæti merkt breytingar með, og hvað þau þýða.",
index 255781a..1babfda 100644 (file)
                        "Manvydasz",
                        "S4b1nuz E.656",
                        "Daimona Eaytoy",
-                       "Sarah Bernabei"
+                       "Sarah Bernabei",
+                       "Wedhro"
                ]
        },
        "tog-underline": "Sottolinea i collegamenti:",
        "botpasswords-existing": "Password bot esistenti",
        "botpasswords-createnew": "Crea una nuova password bot",
        "botpasswords-editexisting": "Modifica password bot esistenti",
+       "botpasswords-label-needsreset": "(occorre ripristinare la password)",
        "botpasswords-label-appid": "Nome bot:",
        "botpasswords-label-create": "Crea",
        "botpasswords-label-update": "Aggiorna",
        "resetpass-submit-loggedin": "Cambia password",
        "resetpass-submit-cancel": "Annulla",
        "resetpass-wrong-oldpass": "Password temporanea o attuale non valida.\nLa password potrebbe essere stata già modificata, oppure potrebbe essere stata richiesta una nuova password temporanea.",
-       "resetpass-recycled": "Si prega di reimpostare con una password diversa dalla password attuale.",
+       "resetpass-recycled": "Si prega di modificare la tua password con una diversa da quella attuale.",
        "resetpass-temp-emailed": "L'accesso è stato effettuato con un codice temporaneo, inviato via email. Per completare la registrazione, è necessario impostare una nuova password qui:",
        "resetpass-temp-password": "Password temporanea:",
        "resetpass-abort-generic": "La modifica della password è stata interrotta da un'estensione.",
        "resetpass-expired": "La password è scaduta. Si prega di impostare una nuova password per effettuare l'accesso.",
-       "resetpass-expired-soft": "La tua password è scaduta e deve essere reimpostata. Si prega di scegliere una nuova password o fare clic su \"{{int:authprovider-resetpass-skip-label}}\" per reimpostarla successivamente.",
-       "resetpass-validity-soft": "La tua password non è valida: $1\n\nSi prega di scegliere una nuova password o fare clic su \"{{int:authprovider-resetpass-skip-label}}\" per reimpostarla successivamente.",
+       "resetpass-expired-soft": "La tua password è scaduta e deve essere modificata. Si prega di scegliere una nuova password o fare clic su \"{{int:authprovider-resetpass-skip-label}}\" per modificarla successivamente.",
+       "resetpass-validity-soft": "La tua password non è valida: $1\n\nSi prega di scegliere una nuova password o fare clic su \"{{int:authprovider-resetpass-skip-label}}\" per modificarla successivamente.",
        "passwordreset": "Reimposta password",
        "passwordreset-text-one": "Compila questo modulo per reimpostare la tua password.",
        "passwordreset-text-many": "{{PLURAL:$1|Compila uno dei campi per ricevere una password temporanea tramite email.}}",
        "recentchangescount": "Numero di modifiche da mostrare nelle ultime modifiche, cronologie e registri, per impostazione predefinita:",
        "prefs-help-recentchangescount": "Numero massimo: 1000",
        "prefs-help-watchlist-token2": "Questa è la chiave segreta per il feed web dei tuoi osservati speciali.\nChiunque la conosce sarà in grado di leggere i tuoi osservati speciali, per cui non condividerla. Se necessario, [[Special:ResetTokens|puoi reimpostarla]].",
-       "prefs-help-tokenmanagement": "Puoi visualizzare e reimpostare la chiave segreta per la tua utenza con cui puoi accedere al feed web dei tuoi osservati speciali. Chiunque conosce la chiave sarà in grado di leggere i tuoi osservati speciali, quindi non condividerla.",
+       "prefs-help-tokenmanagement": "Puoi visualizzare e reimpostare la chiave segreta per la tua utenza con cui puoi accedere al feed web dei tuoi osservati speciali. Chiunque conosca la chiave sarà in grado di leggere i tuoi osservati speciali, quindi non condividerla.",
        "savedprefs": "Le preferenze sono state salvate.",
        "savedrights": "I gruppi utente di {{GENDER:$1|$1}} sono stati salvati.",
        "timezonelegend": "Fuso orario:",
        "default": "predefinito",
        "prefs-files": "File",
        "prefs-custom-css": "CSS personalizzato",
+       "prefs-custom-json": "JSON personalizzato",
        "prefs-custom-js": "JavaScript personalizzato",
        "prefs-common-config": "CSS/JSON/JavaScript condiviso per tutti i temi:",
        "prefs-reset-intro": "È possibile usare questa pagina per reimpostare le proprie preferenze a quelle predefinite del sito.\nL'operazione non può essere annullata.",
        "group-autoconfirmed": "Utenti autoconvalidati",
        "group-bot": "Bot",
        "group-sysop": "Amministratori",
+       "group-interface-admin": "Amministratori dell'interfaccia",
        "group-bureaucrat": "Burocrati",
        "group-suppress": "Soppressori",
        "group-all": "(tutti)",
        "group-autoconfirmed-member": "{{GENDER:$1|utente autoconvalidato|utente autoconvalidata|utente autoconvalidato/a}}",
        "group-bot-member": "{{GENDER:$1|bot}}",
        "group-sysop-member": "{{GENDER:$1|amministratore|amministratrice|amministratore/trice}}",
+       "group-interface-admin-member": "{{GENDER:$1|amministratore|amministratrice|amministratore/trice}} dell'interfaccia",
        "group-bureaucrat-member": "{{GENDER:$1|burocrate}}",
        "group-suppress-member": "{{GENDER:$1|soppressore|sopprimitrice}}",
        "grouppage-user": "{{ns:project}}:Utenti",
        "grouppage-autoconfirmed": "{{ns:project}}:Utenti autoconvalidati",
        "grouppage-bot": "{{ns:project}}:Bot",
        "grouppage-sysop": "{{ns:project}}:Amministratori",
+       "grouppage-interface-admin": "{{ns:project}}:Amministratori dell'interfaccia",
        "grouppage-bureaucrat": "{{ns:project}}:Burocrati",
        "grouppage-suppress": "{{ns:project}}:Soppressori",
        "right-read": "Legge pagine",
        "right-editcontentmodel": "Modifica il modello di contenuto di una pagina",
        "right-editinterface": "Modifica l'interfaccia utente",
        "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-editmyusercss": "Modifica il file CSS del proprio utente",
        "right-editmyuserjson": "Modifica il file JSON del proprio utente",
        "grant-createaccount": "Crea un'utenza",
        "grant-createeditmovepage": "Crea, modifica e sposta le pagine",
        "grant-delete": "Cancella pagine, versioni, e voci di registro",
-       "grant-editinterface": "Modifica il namespace MediaWiki e i CSS/JSON/JavaScript degli utenti",
+       "grant-editinterface": "Modifica il namespace MediaWiki e i JSON del sito/utenti",
        "grant-editmycssjs": "Modifica i CSS/JSON/JavaScript della tua utenza",
        "grant-editmyoptions": "Modifica le preferenze della tua utenza",
        "grant-editmywatchlist": "Modifica i tuoi osservati speciali",
        "rcfilters-other-review-tools": "Altri strumenti di revisione",
        "rcfilters-group-results-by-page": "Raggruppa risultati per pagina",
        "rcfilters-activefilters": "Filtri attivi",
+       "rcfilters-activefilters-hide": "Nascondi",
+       "rcfilters-activefilters-show": "Mostra",
+       "rcfilters-activefilters-hide-tooltip": "Nascondi 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",
        "rcfilters-savedqueries-rename": "Rinomina",
        "rcfilters-savedqueries-setdefault": "Imposta come predefinito",
        "rcfilters-savedqueries-unsetdefault": "Rimuovi come predefinito",
-       "rcfilters-savedqueries-remove": "Rimuovi",
+       "rcfilters-savedqueries-remove": "Cancella",
        "rcfilters-savedqueries-new-name-label": "Nome",
        "rcfilters-savedqueries-new-name-placeholder": "Descrivi lo scopo del filtro",
        "rcfilters-savedqueries-apply-label": "Crea filtro",
        "rcfilters-empty-filter": "Nessun filtro attivo. Sono mostrati tutti i contributi.",
        "rcfilters-filterlist-title": "Filtri",
        "rcfilters-filterlist-whatsthis": "Come funzionano?",
-       "rcfilters-filterlist-feedbacklink": "Dicci cosa ne pensi su questi (nuovi) strumenti di filtraggio",
+       "rcfilters-filterlist-feedbacklink": "Dicci cosa ne pensi su questi strumenti di filtraggio",
        "rcfilters-highlightbutton-title": "Evidenzia risultati",
        "rcfilters-highlightmenu-title": "Seleziona un colore",
        "rcfilters-highlightmenu-help": "Seleziona un colore per evidenziare questa proprietà",
        "rcfilters-watchlist-showupdated": "Le modifiche alle pagine che non hai ancora visitato da quando le modifiche sono avvenute, vengono evidenziate in <strong>grassetto</strong> e con dei pallini pieni.",
        "rcfilters-preference-label": "Nascondi la versione migliorata delle ultime modifiche",
        "rcfilters-preference-help": "Ripristina la riprogettazione dell'interfaccia 2017 e tutti gli strumenti aggiunti allora e da allora.",
+       "rcfilters-watchlist-preference-label": "Nascondi la versione migliorata degli osservati speciali",
+       "rcfilters-watchlist-preference-help": "Ripristina la riprogettazione dell'interfaccia 2017 e tutti gli strumenti aggiunti allora e da allora.",
        "rcfilters-filter-showlinkedfrom-label": "Mostra le modifiche alle pagine collegate da",
        "rcfilters-filter-showlinkedfrom-option-label": "<strong>Pagine con collegamenti da</strong> la pagina selezionata",
        "rcfilters-filter-showlinkedto-label": "Mostra le modifiche alle pagine che collegano a",
        "uploadstash-bad-path": "Il percorso non esiste.",
        "uploadstash-bad-path-invalid": "Il percorso non è valido.",
        "uploadstash-bad-path-unknown-type": "Tipo sconosciuto \"$1\".",
+       "uploadstash-file-not-found-no-thumb": "Non è stato possibile ottenere la miniatura.",
+       "uploadstash-file-not-found-no-remote-thumb": "Recupero della miniatura fallito: $1\nURL = $2",
        "uploadstash-zero-length": "Il file ha lunghezza zero.",
        "invalid-chunk-offset": "Offset della parte non valido.",
        "img-auth-accessdenied": "Accesso negato",
-       "img-auth-nopathinfo": "PATH_INFO mancante.\nIl server non è impostato per passare questa informazione.\nPotrebbe essere basato su CGI e non può supportare img_auth.\nVedi https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization",
+       "img-auth-nopathinfo": "Informazioni mancanti sul percorso.\nIl server deve essere è impostato per passare le variabili REQUEST_URI e/o PATH_INFO.\nSe è così, abilita $wgUsePathInfo.\nVedi https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization",
        "img-auth-notindir": "Il percorso richiesto non si trova nella directory di upload configurata.",
        "img-auth-badtitle": "Impossibile costruire un titolo valido da \"$1\".",
        "img-auth-nologinnWL": "Non si è effettuato l'accesso e \"$1\" non è nella whitelist.",
        "http-timed-out": "Richiesta HTTP scaduta.",
        "http-curl-error": "Errore durante il recupero dell'URL: $1",
        "http-bad-status": "Si è verificato un problema durante la richiesta HTTP: $1 $2",
+       "http-internal-error": "Errore interno HTTP.",
        "upload-curl-error6": "URL non raggiungibile",
        "upload-curl-error6-text": "Impossibile raggiungere la URL specificata. Verificare che la URL sia scritta correttamente e che il sito in questione sia attivo.",
        "upload-curl-error28": "Tempo scaduto per l'upload",
        "pageswithprop-text": "Questa pagina elenca le pagine che utilizzano una particolare proprietà di pagina.",
        "pageswithprop-prop": "Nome proprietà:",
        "pageswithprop-reverse": "Ordinamento inverso",
+       "pageswithprop-sortbyvalue": "Ordina in base al valore della proprietà",
        "pageswithprop-submit": "Vai",
        "pageswithprop-prophidden-long": "valore testuale lungo della proprietà nascosto ($1)",
        "pageswithprop-prophidden-binary": "valore binario della proprietà nascosto ($1)",
        "uncategorizedcategories": "Categorie prive di categorie",
        "uncategorizedimages": "File privi di categorie",
        "uncategorizedtemplates": "Template privi di categorie",
+       "uncategorized-categories-exceptionlist": "# Contiene un elenco di categorie che non dovrebbero figurare in Special:UncategorizedCategories. Una categoria per linea, a cominciare da \"*\". Le linee che iniziano per un altro carattere (spazi bianchi inclusi) saranno ignorate. Usa «#» per aggiungere commenti.",
        "unusedcategories": "Categorie vuote",
        "unusedimages": "File non utilizzati",
        "wantedcategories": "Categorie richieste",
        "protectedtitles-submit": "Mostra titoli",
        "listusers": "Elenco degli utenti",
        "listusers-editsonly": "Mostra solo utenti con dei contributi",
+       "listusers-temporarygroupsonly": "Mostra solo utenti in gruppi utenti temporanei",
        "listusers-creationsort": "Ordina per data di creazione",
        "listusers-desc": "Ordina in senso decrescente",
        "usereditcount": "$1 {{PLURAL:$1|contributo|contributi}}",
        "speciallogtitlelabel": "Azione effettuata su (titolo della pagina o {{ns:user}}:Nome utente):",
        "log": "Registri",
        "logeventslist-submit": "Mostra",
+       "logeventslist-more-filters": "Mostra registri aggiuntivi:",
+       "logeventslist-patrol-log": "Modifiche verificate",
+       "logeventslist-tag-log": "Etichette",
        "all-logs-page": "Tutti i registri pubblici",
        "alllogstext": "Presentazione unificata di tutti i registri di {{SITENAME}}.\nÈ possibile restringere i criteri di ricerca selezionando il tipo di registro, l'utente che ha eseguito l'azione, e/o la pagina interessata (entrambi i campi sono sensibili al maiuscolo/minuscolo).",
        "logempty": "Il registro non contiene elementi corrispondenti alla ricerca.",
        "dellogpage": "Cancellazioni",
        "dellogpagetext": "Di seguito sono elencate le pagine cancellate di recente.",
        "deletionlog": "cancellazioni",
+       "log-name-create": "Creazioni di pagine",
+       "log-description-create": "Di seguito sono elencate le pagine create di recente.",
+       "logentry-create-create": "$1 {{GENDER:$2|ha creato}} la pagina $3",
        "reverted": "Ripristinata la versione precedente",
        "deletecomment": "Motivo:",
        "deleteotherreason": "Altri motivi/dettagli:",
        "uctop": "(attuale)",
        "month": "Dal mese (e precedenti):",
        "year": "Dall'anno (e precedenti):",
+       "date": "Dal giorno (e precedenti):",
        "sp-contributions-newbies": "Mostra solo i contributi dei nuovi utenti",
        "sp-contributions-newbies-sub": "Per i nuovi utenti",
        "sp-contributions-newbies-title": "Contributi dei nuovi utenti",
        "whatlinkshere": "Puntano qui",
        "whatlinkshere-title": "Pagine che puntano a \"$1\"",
        "whatlinkshere-page": "Pagina:",
-       "linkshere-2": "Le seguenti pagine contengono dei collegamenti a <strong>$1</strong>:",
-       "nolinkshere-2": "Nessuna pagina contiene collegamenti che puntano a '''$1'''.",
-       "nolinkshere-ns-2": "Non vi sono pagine che puntano a '''$1''' nel namespace selezionato.",
+       "linkshere": "Le seguenti pagine contengono dei collegamenti a <strong>$2</strong>:",
+       "nolinkshere": "Nessuna pagina contiene collegamenti che puntano a <strong>$2</strong>.",
+       "nolinkshere-ns": "Non vi sono pagine che puntano a <strong>$2</strong> nel namespace selezionato.",
        "isredirect": "redirect",
        "istemplate": "inclusione",
        "isimage": "collegamento al file",
        "ipb_blocked_as_range": "Errore: L'indirizzo IP $1 non è soggetto a blocco individuale e non può essere sbloccato. Il blocco è invece attivo a livello dell'intervallo $2, che può essere sbloccato.",
        "ip_range_invalid": "Intervallo di indirizzi IP non valido.",
        "ip_range_toolarge": "Non è possibile bloccare range superiori al /$1",
+       "ip_range_exceeded": "L'intervallo di IP supera il limite massimo. Intervallo contentito: /$1.",
+       "ip_range_toolow": "Gli intervalli di IP non sono consentiti, di fatto.",
        "proxyblocker": "Blocco dei proxy aperti",
        "proxyblockreason": "Questo indirizzo IP è stato bloccato perché risulta essere un proxy aperto. Si prega di contattare il proprio fornitore di accesso a Internet o il supporto tecnico e informarli di questo grave problema di sicurezza.",
        "sorbsreason": "Questo indirizzo IP è elencato come proxy aperto nella lista DNSBL utilizzata da {{SITENAME}}.",
        "import-mapping-subpage": "Importa come sottopagine della pagina seguente:",
        "import-upload-filename": "Nome file:",
        "import-upload-username-prefix": "Prefisso interwiki:",
+       "import-assign-known-users": "Assegna le modifiche agli utenti locali qualora l'utente indicato esista localmente",
        "import-comment": "Oggetto:",
        "importtext": "Si prega di esportare il file dal sito wiki di origine con la [[Special:Export|funzione di esportazione]], salvarlo sul proprio disco e poi caricarlo qui.",
        "importstart": "Importazione delle pagine in corso...",
        "markedaspatrollederrornotify": "Errore durante la verifica.",
        "patrol-log-page": "Modifiche verificate",
        "patrol-log-header": "Di seguito sono elencate le verifiche delle modifiche.",
-       "log-show-hide-patrol": "$1 registro delle modifiche verificate",
-       "log-show-hide-tag": "$1 registro delle etichette",
        "confirm-markpatrolled-button": "OK",
        "confirm-markpatrolled-top": "Segna versione $3 di $2 come verificata?",
        "deletedrevision": "Cancellata la vecchia versione di $1.",
        "watchlistedit-clear-titles": "Titoli:",
        "watchlistedit-clear-submit": "Svuota gli osservati speciali (sarà permanente!)",
        "watchlistedit-clear-done": "La lista degli osservati speciali è stata svuotata.",
+       "watchlistedit-clear-jobqueue": "I tuoi osservati speciali sono in corso di svuotamento. Potrebbe volerci un po' di tempo!",
        "watchlistedit-clear-removed": "{{PLURAL:$1|È stata eliminata una pagina|Sono state eliminate $1 pagine}}:",
        "watchlistedit-too-many": "Ci sono troppe pagine da visualizzare qui.",
        "watchlisttools-clear": "svuota la lista degli osservati speciali",
        "unlinkaccounts-success": "L'utenza è stata scollegata.",
        "authenticationdatachange-ignored": "Il cambiamento dei dati di autenticazione non è stato gestito. Forse non è stato configurato nessun provider?",
        "userjsispublic": "Ricorda: le sottopagine JavaScript non devono contenere dati riservati poichè sono visualizzabili da altri utenti.",
+       "userjsonispublic": "Ricorda: le sottopagine JSON non dovrebbero contenere dati personali perché sono visibili agli altri utenti.",
        "usercssispublic": "Ricorda: le sottopagine CSS non devono contenere dati riservati poichè sono visualizzabili da altri utenti.",
        "restrictionsfield-badip": "Indirizzo IP o intervallo non valido: $1",
        "restrictionsfield-label": "Intervalli IP consentiti:",
        "pagedata-not-acceptable": "Nessun formato corrispondente trovato. Tipi MIME supportati: $1",
        "pagedata-bad-title": "Titolo non valido: $1.",
        "unregistered-user-config": "Per motivi di sicurezza, non è possibile caricare sottopagine utente JavaScript, CSS e JSON per utenti non registrati.",
-       "passwordpolicies-group": "Gruppo"
+       "passwordpolicies-group": "Gruppo",
+       "passwordpolicies-policies": "Politiche",
+       "passwordpolicies-policy-minimalpasswordlength": "La password deve essere lunga almeno $1 {{PLURAL:$1|carattere|caratteri}}",
+       "passwordpolicies-policy-minimumpasswordlengthtologin": "La password deve essere lunga almeno $1 {{PLURAL:$1|carattere|caratteri}} per poter accedere",
+       "passwordpolicies-policy-passwordcannotmatchusername": "La password non può essere uguale al nome utente",
+       "passwordpolicies-policy-passwordcannotmatchblacklist": "La password non può corrispondere a password specificate nell'elenco delle password proibite",
+       "passwordpolicies-policy-maximalpasswordlength": "La password deve essere lunga meno di $1 {{PLURAL:$1|carattere|caratteri}}",
+       "passwordpolicies-policy-passwordcannotbepopular": "La password non può essere {{PLURAL:$1|la password più popolare|nell'elenco delle $1 password più popolari}}"
 }
index 2c02c2a..ca6445d 100644 (file)
        "botpasswords-existing": "既存のボット用パスワード",
        "botpasswords-createnew": "ボット用パスワードの新規作成",
        "botpasswords-editexisting": "既存のボットのパスワードを編集",
+       "botpasswords-label-needsreset": "(パスワードをリセットする必要があります)",
        "botpasswords-label-appid": "ボット名:",
        "botpasswords-label-create": "作成",
        "botpasswords-label-update": "更新",
        "previewerrortext": "変更のプレビューを処理中に、エラーが発生しました。",
        "blockedtitle": "利用者はブロックされています",
        "blockedtext": "<strong>この利用者名またはIPアドレスはブロックされています。</strong>\n\nブロックは$1によって実施されました。\nブロックの理由は <em>$2</em> です。\n\n* ブロック開始日時: $8\n* ブロック解除予定: $6\n* ブロック対象: $7\n\nこのブロックについて、$1もしくは他の[[{{MediaWiki:Grouppage-sysop}}|管理者]]に問い合わせることができます。\nただし、[[Special:Preferences|個人設定]]で有効なメールアドレスが登録されていない場合、またはメール送信機能の使用がブロックされている場合、「この利用者にメールを送信」の機能は使えません。\n現在ご使用中のIPアドレスは$3、このブロックIDは#$5です。\nお問い合わせの際には、上記の情報を必ず書いてください。",
-       "autoblockedtext": "このIPアドレスは、$1によりブロックされた利用者によって使用されたため、自動的にブロックされています。\n理由は次の通りです。\n\n:<em>$2</em>\n\n* ブロック開始日時: $8\n* ブロック解除予定: $6\n* ブロック対象: $7\n\n$1または他の[[{{MediaWiki:Grouppage-sysop}}|管理者]]にこのブロックについて問い合わせることができます。\n\nただし、[[Special:Preferences|個人設定]]に正しいメールアドレスが登録されていない場合、またはメール送信がブロックされている場合、「この利用者にメールを送信」機能を使用できないことに注意してください。\n\n現在ご使用中のIPアドレスは$3 、このブロックIDは#$5です。\nお問い合わせの際は、上記の情報を必ず書いてください。",
+       "autoblockedtext": "このIPアドレスは、$1によりブロックされた利用者によって使用されたため、自動的にブロックされています。\n理由は次の通りです。\n\n:<em>$2</em>\n\n* ブロック開始日時: $8\n* ブロック解除予定: $6\n* ブロック対象: $7\n\n$1または他の[[{{MediaWiki:Grouppage-sysop}}|管理者]]にこのブロックについて問い合わせることができます。\n\nただし、[[Special:Preferences|個人設定]]に正しいメールアドレスが登録されていない場合、またはメール送信がブロックされている場合、「{{int:emailuser}}」機能を使用できないことに注意してください。\n\n現在ご使用中のIPアドレスは$3 、このブロックIDは#$5です。\nお問い合わせの際は、上記の情報を必ず書いてください。",
        "systemblockedtext": "あなたの利用者名またはIPアドレスはMediaWikiによって自動的にブロックされています。\n理由は次の通りです。\n\n:<em>$2</em>\n\n* ブロック開始日時: $8\n* ブロック解除予定: $6\n* ブロック対象: $7\n\nあなたの現在のIPアドレスは $3 です。\nお問い合わせの際は、上記の詳細情報をすべて含めてください。",
        "blockednoreason": "理由が設定されていません",
        "whitelistedittext": "このページを編集するには$1してください。",
        "revdelete-text-file": "削除されたファイルの版はファイルの履歴に表示されつづけますが、一般の利用者はその内容の一部を閲覧できなくなります。",
        "logdelete-text": "削除された記録項目は記録に表示され続けますが、一般の利用者はその内容の一部を閲覧できなくなります。",
        "revdelete-text-others": "追加の制限を設定しない限り、他の管理者は非表示コンテンツにまだアクセスすることも復元することもできます。",
-       "revdelete-confirm": "ã\81\93ã\81®æ\93\8dä½\9cã\82\92è¡\8cã\81\8aã\81\86ã\81¨ã\81\97ã\81¦ã\81\84ã\82\8bã\81\93ã\81¨ã\80\81ã\81\9dã\81®結果を理解していること、[[{{MediaWiki:Policy-url}}|方針]]に従っていること、を確認してください。",
+       "revdelete-confirm": "ã\81\93ã\81®æ\93\8dä½\9cã\81«ã\82\88ã\82\8aç\94\9fã\81\98ã\82\8b結果を理解していること、[[{{MediaWiki:Policy-url}}|方針]]に従っていること、を確認してください。",
        "revdelete-suppress-text": "秘匿は、<strong>以下の場合に限って</strong>使用すべきです:\n* 名誉毀損のおそれがある記述\n* 非公開個人情報\n*: <em>自宅の住所、電話番号、個人を識別できる公的な番号など</em>",
        "revdelete-legend": "閲覧レベル制限を設定",
        "revdelete-hide-text": "版の本文",
        "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": "過去$2の$1{{PLURAL:$1|件の変更}}",
        "rcfilters-empty-filter": "絞り込みは行われていません。全ての項目が表示さます。",
        "rcfilters-filterlist-title": "フィルター",
        "rcfilters-filterlist-whatsthis": "これらはどのように機能しますか?",
-       "rcfilters-filterlist-feedbacklink": "(新しい)絞り込み機能に関するフィードバックをお願いします",
+       "rcfilters-filterlist-feedbacklink": "絞り込み機能に関するフィードバック",
        "rcfilters-highlightbutton-title": "該当項目を強調表示する",
        "rcfilters-highlightmenu-title": "色を選ぶ",
        "rcfilters-highlightmenu-help": "この項目を何色で強調表示するか選択してください",
        "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": "閲覧済みの変更",
        "dellogpage": "削除記録",
        "dellogpagetext": "以下は最近の削除と復元の一覧です。",
        "deletionlog": "削除記録",
+       "log-name-create": "ページ作成記録",
+       "log-description-create": "以下はページ作成の最近の記録です。",
+       "logentry-create-create": "$1 がページ「$3」を{{GENDER:$2|作成しました}}",
        "reverted": "以前の版への差し戻し",
        "deletecomment": "理由:",
        "deleteotherreason": "他の、または追加の理由:",
        "whatlinkshere": "リンク元",
        "whatlinkshere-title": "「$1」へリンクしているページ",
        "whatlinkshere-page": "ページ:",
-       "linkshere-2": "以下のページが、<strong>$1</strong> にリンクしています:",
-       "nolinkshere-2": "<strong>$1</strong> にリンクしているページはありません。",
-       "nolinkshere-ns-2": "指定した名前空間内に、<strong>$1</strong> にリンクしているページはありません。",
+       "linkshere": "以下のページが、<strong>$2</strong> にリンクしています:",
+       "nolinkshere": "<strong>$2</strong> にリンクしているページはありません。",
+       "nolinkshere-ns": "指定した名前空間内に、<strong>$2</strong> にリンクしているページはありません。",
        "isredirect": "転送ページ",
        "istemplate": "参照読み込み",
        "isimage": "ファイルへのリンク",
        "markedaspatrollederrornotify": "巡回済みにするのに失敗しました。",
        "patrol-log-page": "巡回記録",
        "patrol-log-header": "以下は巡回された版の記録です。",
-       "log-show-hide-patrol": "巡回記録を$1",
-       "log-show-hide-tag": "タグ記録を$1",
        "confirm-markpatrolled-button": "OK",
        "confirm-markpatrolled-top": "ページ$2の$3の版を巡回済みにマークしますか?",
        "deletedrevision": "古い版 $1 を削除しました",
        "autosumm-blank": "ページの白紙化",
        "autosumm-replace": "内容を「$1」で置換",
        "autoredircomment": "[[$1]]への転送ページ",
-       "autosumm-removed-redirect": "[[$1]] へのリダイレクトを除しました",
+       "autosumm-removed-redirect": "[[$1]] へのリダイレクトを除しました",
        "autosumm-changed-redirect-target": "転送先を [[$1]] から [[$2]] に変更しました",
        "autosumm-new": "ページの作成:「$1」",
        "autosumm-newblank": "空白のページを作成しました",
        "tag-mw-contentmodelchange-description": "ページの[https://www.mediawiki.org/wiki/Special:MyLanguage/Help:ChangeContentModel コンテンツモデルを変更]する",
        "tag-mw-new-redirect": "新規リダイレクト",
        "tag-mw-new-redirect-description": "新たな転送ページの作成または既存ページの転送化の編集",
-       "tag-mw-removed-redirect": "転送廃止",
-       "tag-mw-removed-redirect-description": "既存の転送を廃止する編集",
+       "tag-mw-removed-redirect": "リダイレクト解消",
+       "tag-mw-removed-redirect-description": "既存のリダイレクトを解消する編集",
        "tag-mw-changed-redirect-target": "転送先変更",
        "tag-mw-changed-redirect-target-description": "転送先を変更する編集",
        "tag-mw-blank": "白紙化",
        "htmlform-user-not-exists": "<strong>$1</strong>は存在しません。",
        "htmlform-user-not-valid": "<strong>$1</strong>は有効な利用者名ではありません。",
        "logentry-delete-delete": "$1 がページ「$3」を{{GENDER:$2|削除しました}}",
-       "logentry-delete-delete_redir": "$1 がリダイレクト「$3」を上書きにより{{GENDER:$2|削除しました}}",
+       "logentry-delete-delete_redir": "$1 がリダイレクト「$3」を上書き{{GENDER:$2|削除しました}}",
        "logentry-delete-restore": "$1 がページ「$3 ($4)」を{{GENDER:$2|復元しました}}",
        "logentry-delete-restore-nocount": "$1 がページ「$3」を{{GENDER:$2|復元しました}}",
        "restore-count-revisions": "{{PLURAL:$1|1|$1}}件の版",
        "undelete-cantcreate": "同名のページが存在せず、このページを作成する許可がないため復元できません。",
        "pagedata-title": "ページ・データ",
        "pagedata-not-acceptable": "該当する形式が見つかりません。対応している MIME タイプ: $1",
-       "pagedata-bad-title": "「$1」は無効なページ名です。"
+       "pagedata-bad-title": "「$1」は無効なページ名です。",
+       "unregistered-user-config": "セキュリティ上の理由から、JavaScript、CSSおよびJSONの利用者サブページは、登録されていない利用者に対しては読み込みできません。",
+       "passwordpolicies": "パスワードポリシー",
+       "passwordpolicies-summary": "これは、このウィキで定義されている利用者グループの有効なパスワードポリシーの一覧です。",
+       "passwordpolicies-group": "グループ",
+       "passwordpolicies-policies": "ポリシー",
+       "passwordpolicies-policy-minimalpasswordlength": "パスワードは$1{{PLURAL:$1|文字}}以上でなければなりません",
+       "passwordpolicies-policy-minimumpasswordlengthtologin": "ログインできるようにするには、パスワードは$1{{PLURAL:$1|文字}}以上でなければなりません",
+       "passwordpolicies-policy-passwordcannotmatchusername": "パスワードは利用者名と同じにすることはできません",
+       "passwordpolicies-policy-passwordcannotmatchblacklist": "パスワードは、特にブラックリストに載っているものと一致するものは設定できません",
+       "passwordpolicies-policy-maximalpasswordlength": "パスワードは$1{{PLURAL:$1|文字}}以下でなければなりません",
+       "passwordpolicies-policy-passwordcannotbepopular": "パスワードは{{PLURAL:$1|一般的なものにすることはできません|一般的な$1個のパスワードのリストと一致するものにすることはできません}}"
 }
index 79354d1..ffc35a1 100644 (file)
        "whatlinkshere": "Wa lingk ya",
        "whatlinkshere-title": "Piej wa lingk tu \"$1\"",
        "whatlinkshere-page": "Piej:",
-       "linkshere-2": "Di falarin piejdem lingk tu '''$1''':",
+       "linkshere": "Di falarin piejdem lingk tu '''$2''':",
        "isredirect": "riidirek piej",
        "istemplate": "chranskluujan",
        "isimage": "fail lingk",
index ae892bd..3ccc96d 100644 (file)
        "whatlinkshere": "Hwa henwise hertil",
        "whatlinkshere-title": "Side som linke te $1",
        "whatlinkshere-page": "Siid:",
-       "linkshere-2": "Di följenje side henwise te '''„$1“''':",
-       "nolinkshere-2": "Ien side henwise te '''„$1“'''.",
+       "linkshere": "Di följenje side henwise te '''„$2“''':",
+       "nolinkshere": "Ien side henwise te '''„$2“'''.",
        "isredirect": "omdirigiirengssiid",
        "istemplate": "inlejreng",
        "isimage": "filhenwisneng",
index 6ee482f..66df3aa 100644 (file)
        "policy-url": "Project:Kabijakan",
        "portal": "Gapura paguyuban",
        "portal-url": "Project:Garupa paguyuban",
-       "privacy": "Pranatan bab privasi",
-       "privacypage": "Project:Pranatan bab privasi",
+       "privacy": "Niti privasi",
+       "privacypage": "Project:Niti privasi",
        "badaccess": "Aksès ora olèh",
        "badaccess-group0": "Panjenengan ora pareng nglakokaké tindhakan sing panjenengan gayuh.",
        "badaccess-groups": "Tumindak sing panjenengan péngini winates marang panganggo ing {{PLURAL:$2|golongan|golongan}}: $1.",
        "title-invalid-empty": "Sesirah kaca sing dikarepaké kosong utawa mung ngemu jenengé mandala-aran.",
        "title-invalid-utf8": "Sesirah kaca sing dikarepaké ngemu reroncèn UTF-8 sing ora sah.",
        "title-invalid-interwiki": "Sesirah kaca sing dikarepaké ngemu pranala interwiki sing ora bisa dicakaké dadi sesirah",
-       "title-invalid-talk-namespace": "Sesirah kaca sing dikarepaké nggayut kaca parembugan sing ora ana.",
+       "title-invalid-talk-namespace": "Sesirah kaca kang dikarepaké ngener ing kaca parembugan kang ora ana.",
        "title-invalid-characters": "Sesirah kaca sing dikarepaké ngemu karakter sing ora sah: \"$1\".",
        "title-invalid-relative": "Sesirah ngemu alamat rélatif. Sesirah kaca relatif (./, ../) iku ora sah amarga ora bisa ditekani lumantar pangluru.",
        "title-invalid-magic-tilde": "Sesirah kaca sing dikarepaké ngemu reroncèn tilda (<nowiki>~~~</nowiki>) sing ora sah.",
        "nosuchusershort": "Ora ana panganggo mawa asma \"$1\". Coba dipriksa manèh pasang aksarané (éjaané).",
        "nouserspecified": "Panjenengan kudu milih jeneng panganggo.",
        "login-userblocked": "Panganggo iki pinalangan. Ora kena mbelu.",
-       "wrongpassword": "Tembung wadi sing diisèkaké salah.\nMangga jajalen manèh.",
+       "wrongpassword": "Jenang panganggo utawa tembung wadi kang diisèkaké salah.\nMangga jajalen manèh.",
        "wrongpasswordempty": "Tembung wadi kosong.\nJajalen manèh.",
        "passwordtooshort": "Tembung sesinglon paling sethithik cacahé {{PLURAL:$1|1 aksara|$1 aksara}}.",
        "passwordtoolong": "Tembung wadi ora kena munjuli {{PLURAL:$1|1 pralambang|$1 pralambang}}.",
        "rcfilters-group-results-by-page": "Golongaké kasilé miturut kacané",
        "rcfilters-activefilters": "Saringan murub",
        "rcfilters-advancedfilters": "Saringan lanjutan",
-       "rcfilters-limit-title": "Owahan-owahan sing arep dituduhaké",
+       "rcfilters-limit-title": "Kasil kang arep dituduhaké",
        "rcfilters-days-title": "Dina-dina sing mentas waé",
        "rcfilters-hours-title": "Jam-jam sing mentas waé",
        "rcfilters-days-show-days": "$1 {{PLURAL:$1|dina|dina}}",
        "rcfilters-quickfilters": "Saringan sumimpen",
-       "rcfilters-quickfilters-placeholder-title": "Durung ana pranala sing disimpen",
+       "rcfilters-quickfilters-placeholder-title": "Durung ana saringan kang kasimpen",
        "rcfilters-quickfilters-placeholder-description": "Saperlu nyimpen setèlaning saringan lan nganggo setèlan iku manèh ing tembé, kliken ikon markah buku ing babagan Saringan Murub ing ngisor.",
        "rcfilters-savedqueries-defaultlabel": "Saringan sumimpen",
        "rcfilters-savedqueries-rename": "Ganti jeneng",
        "rcfilters-savedqueries-add-new-title": "Simpen setèlané saringan sing saiki",
        "rcfilters-restore-default-filters": "Pulihaké saringan gawan",
        "rcfilters-clear-all-filters": "Resiki kabèh saringan",
-       "rcfilters-search-placeholder": "Saring owah-owahan anyar (lurua utawa wiwita ngetik)",
+       "rcfilters-search-placeholder": "Owah-owahan saringan (anggo menu utawa golèk jeneng saringan)",
        "rcfilters-invalid-filter": "Saringan ora sah",
        "rcfilters-empty-filter": "Ora ana saringan sing aktif. Kabèh sumbangan katuduhaké.",
        "rcfilters-filterlist-title": "Saringan",
-       "rcfilters-filterlist-whatsthis": "Apa iki?",
-       "rcfilters-filterlist-feedbacklink": "Wènèhi saran ngenani saringan (béta) sing anyar",
+       "rcfilters-filterlist-whatsthis": "Kapiyé cara nganggo iki?",
+       "rcfilters-filterlist-feedbacklink": "Kandhani awak dhéwé panemumu bab piranti saringan iki",
        "rcfilters-highlightbutton-title": "Sentrongi kasil",
        "rcfilters-highlightmenu-title": "Pilih werna",
        "rcfilters-highlightmenu-help": "Pilih werna kanggo nyentrong properti iki",
        "newpageletter": "A",
        "boteditletter": "b",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|cacahé sing ngawasi|cacahé sing ngawasi}}]",
-       "rc-change-size-new": "$1 {{PLURAL:$1|bét|bét}} sawisé diowahi",
+       "rc-change-size-new": "$1 {{PLURAL:$1|bèt|bèt}} sawisé kaowahan",
        "newsectionsummary": "/* $1 */ pérangan anyar",
        "rc-enhanced-expand": "Tuduhaké princèn",
        "rc-enhanced-hide": "Dhelikaké princèn",
        "sp-contributions-newonly": "Tuduhaké besutan mligi kaca gawéan",
        "sp-contributions-hideminor": "Dhelikaké besutan cilik",
        "sp-contributions-submit": "Golèk",
-       "whatlinkshere": "Sing nggayut mréné",
+       "whatlinkshere": "Kang nggayut mréné",
        "whatlinkshere-title": "Kaca mawa pranala nggayut \"$1\"",
        "whatlinkshere-page": "Kaca:",
-       "linkshere-2": "Kaca-kaca ing ngisor iki nggayut menyang <strong>$1</strong>:",
-       "nolinkshere-2": "Ora ana kaca sing nduwé pranala menyang '''$1'''.",
-       "nolinkshere-ns-2": " Ora ana kaca sing nduwé pranala menyang '''$1''' ing bilik jeneng sing kapilih.",
+       "linkshere": "Kaca-kaca ing ngisor iki nggayut menyang <strong>$2</strong>:",
+       "nolinkshere": "Ora ana kaca sing nduwé pranala menyang '''$2'''.",
+       "nolinkshere-ns": " Ora ana kaca sing nduwé pranala menyang '''$2''' ing bilik jeneng sing kapilih.",
        "isredirect": "kaca lih-lihan",
        "istemplate": "tranklusi",
        "isimage": "pranala barkas",
        "tooltip-ca-watch": "Tambahaké kaca iki menyang pawawangané panjenengan",
        "tooltip-ca-unwatch": "Busak kaca iki saka pawawanganing panjenengan",
        "tooltip-search": "Golèk ing {{SITENAME}}",
-       "tooltip-search-go": "Jujug kaca asesirah persis mangkéné yèn ana",
-       "tooltip-search-fulltext": "Golèk kaca isi tèks kaya mangkéné",
+       "tooltip-search-go": "Jujug kaca kang sesirah persis mangkéné yèn ana",
+       "tooltip-search-fulltext": "Golèk kaca kang isi tèks mangkéné",
        "tooltip-p-logo": "Menyang tepas",
        "tooltip-n-mainpage": "Menyang tepas",
        "tooltip-n-mainpage-description": "Menyang tepas",
        "tooltip-n-recentchanges": "Pratélaning owah-owahan anyar sajeroning wiki.",
        "tooltip-n-randompage": "Mot sembarang kaca",
        "tooltip-n-help": "Papan kanggo golèk pitulung",
-       "tooltip-t-whatlinkshere": "Pratélané kabèh kaca wiki sing nggayut mréné",
+       "tooltip-t-whatlinkshere": "Pratélan kabèh kaca wiki kang nggayut mréné",
        "tooltip-t-recentchangeslinked": "Owah-owahan anyar saka kaca-kaca sing nggayut kaca iki",
        "tooltip-feed-rss": "''RSS feed'' kanggo kaca iki",
        "tooltip-feed-atom": "Pakan atom tumrap kaca iki",
        "tooltip-t-specialpages": "Pratélaning kabèh kaca mirunggan",
        "tooltip-t-print": "Vèrsi céthak kaca iki",
        "tooltip-t-permalink": "Pranala permanèn saka owahan iki",
-       "tooltip-ca-nstab-main": "Deleng kaca isi",
+       "tooltip-ca-nstab-main": "Deleng kaca kontèn",
        "tooltip-ca-nstab-user": "Deleng kaca panganggo",
        "tooltip-ca-nstab-media": "Deleng kaca médhia",
        "tooltip-ca-nstab-special": "Iki kaca mirunggan lan ora bisa dibesut",
        "markedaspatrollederrornotify": "Penanda patroli gagal dibuat.",
        "patrol-log-page": "Log patroli",
        "patrol-log-header": "Iki log revisi sing wis dipatroli.",
-       "log-show-hide-patrol": "$1 log patroli",
        "confirm-markpatrolled-button": "YA",
        "deletedrevision": "Revisi lawas sing dibusak $1.",
        "filedeleteerror-short": "Kaluputan nalika mbusak berkas: $1",
        "tag-filter-submit": "Penyaring",
        "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|Tenger|Tenger}}]]: $2)",
        "tag-mw-contentmodelchange": "owahan modhèl isi",
+       "tag-mw-new-redirect": "Alihan anyar",
        "tag-mw-blank": "Ngosongaké",
        "tags-title": "Tag",
        "tags-intro": "Kaca iki isi pratélan tenger sing dienggo nandhani besutan déning piranti alus, sinartan tegesé.",
index c33e82e..64a68cc 100644 (file)
        "savechanges": "ცვლილებების შენახვა",
        "publishpage": "გვერდის გამოქვეყნება",
        "publishchanges": "ცვლილებების შენახვა",
+       "publishchanges-start": "ცვლილებების შენახვა…",
        "preview": "წინასწარი გადახედვა",
        "showpreview": "წინასწარი გადახედვის ჩვენება",
        "showdiff": "ცვლილებების ჩვენება",
        "postedit-confirmation-created": "გვერდი შეიქმნა.",
        "postedit-confirmation-restored": "გვერდი აღდგა.",
        "postedit-confirmation-saved": "თქვენი რედაქტირება შენახულია.",
+       "postedit-confirmation-published": "თქვენი რედაქტირება შენახულია.",
        "edit-already-exists": "ახალი გვერდის შექმნა არ მოხერხდა.\nის უკვე არსებობს.",
        "defaultmessagetext": "შეტყობინების სტანდარტული ტექსტი",
        "content-failed-to-parse": "$2-ის შინაარსი არ შეესაბამება $1-ის ტიპს: $3.",
        "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}}:მომხმარებლები",
        "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": "{{PLURAL:$1|ცვლილება|$1 ცვლილება}}, $2",
        "rcfilters-watchlist-showupdated": "ცვლილებები გვერდებზე, რომლებიც თქვენ ჯერ არ გინახავთ ამ ცვლილებების გაკეთების შემდეგ, ნაჩვენებია <strong>მუქად</strong>, განსხვავებული ფერით.",
        "rcfilters-preference-label": "ბოლო ცვლილებების გაუმჯობესებული ვერსიის დამალვა",
        "rcfilters-preference-help": "გათიშავს 2017 წლის ინტერფეისის დიზაინზე გაკეთებულ განახლებას, გაითიშება მას შემდეგ დამატებული ყველა ხელსაწყო.",
+       "rcfilters-watchlist-preference-label": "კონტროლის სიის გაუმჯობესებული ვერსიის დამალვა",
+       "rcfilters-watchlist-preference-help": "აუქმებს 2017 წლის ინტერფეისისა და ყველა ხელსაწყოს რედიზაინს დამატებულს მაშინ და შემდგომ.",
+       "rcfilters-filter-showlinkedfrom-label": "ცვლილებების ჩვენება დაკავშირებულ გვერდებზე",
+       "rcfilters-filter-showlinkedto-option-label": "<strong>არჩეულზე, დაკავშირებული</strong> გვერდები",
        "rcnotefrom": "ქვემოთ {{PLURAL:$5|ნაჩვენებია ცვლილება|ნაჩვენებია ცვლილებები}} <strong>$3, $4</strong>-დან (ნაჩვენებია არაუმეტეს <strong>$1</strong>).",
        "rclistfromreset": "თარიღის საწყის კონფიგურაციაზე დაბრუნება",
        "rclistfrom": "ახალი ცვლილებების ჩვენება დაწყებული $3 $2-დან",
        "filedelete-edit-reasonlist": "წაშლის მიზეზების რედაქტირება",
        "filedelete-maintenance": "ფაილების წაშლა და აღდგენა დროებით გათიშულია ტექნიკური სამუშაობის განმავლობაში.",
        "filedelete-maintenance-title": "ფაილის წაშლა ვერ ხერხდება",
-       "mimesearch": "MIME ძიება",
+       "mimesearch": "MIME-ის ძიება",
        "mimesearch-summary": "ამ გვერდის მეშვეობით შესაძლებელია ფაილების მოძიება მათი MIME-ტიპის მიხედვით. შეტანის ფორმა: შიგთავსის ტიპი/ქვეტიპი, მაგ <code>image/jpeg</code>.",
        "mimetype": "MIME ტიპი:",
        "download": "გადმოტვირთვა",
        "whatlinkshere": "ბმული გვერდზე",
        "whatlinkshere-title": "გვერდები, რომლებიც შეიცავენ „$1“-ის ბმულებს",
        "whatlinkshere-page": "გვერდი:",
-       "linkshere-2": "მომდევნო გვერდები შეიცავენ ბმულებს '''$1'''-ზე:",
-       "nolinkshere-2": "'''$1'''-ზე ბმული არ არის.",
-       "nolinkshere-ns-2": "არჩეულ სახელთა სივრცეში არ არის გვერდები, რომლებიც მისამართდება '''$1'''.",
+       "linkshere": "მომდევნო გვერდები შეიცავენ ბმულებს '''$2'''-ზე:",
+       "nolinkshere": "'''$2'''-ზე ბმული არ არის.",
+       "nolinkshere-ns": "არჩეულ სახელთა სივრცეში არ არის გვერდები, რომლებიც მისამართდება '''$2'''.",
        "isredirect": "გადამისამართების გვერდი",
        "istemplate": "ჩართვა",
        "isimage": "ბმული ფაილზე",
        "markedaspatrollederrornotify": "პატრულირებულად მონიშვნა ვერ მოხერხდა.",
        "patrol-log-page": "პატრულირების ჟურნალი",
        "patrol-log-header": "ეს არის პატრულირებულ ვერსიათა ჟურნალი.",
-       "log-show-hide-patrol": "$1 პატრულირების ჟურნალი",
-       "log-show-hide-tag": "$1 დასათაურების ჟურნალი",
        "confirm-markpatrolled-button": "კარგი",
        "confirm-markpatrolled-top": "მოინიშნოს $2-ის $3 ცვლილება  შემოწმებულად?",
        "deletedrevision": "წაშლილია ძველი ვერსია $1.",
        "log-action-filter-delete-delete": "გვერდის წაშლა",
        "log-action-filter-delete-delete_redir": "გადამისამართების გადაწერა",
        "log-action-filter-delete-restore": "გვერდის აღდგენა",
-       "log-action-filter-delete-event": "á\83¯ურნალის ჩანაწერის წაშლა",
+       "log-action-filter-delete-event": "á\83\9fურნალის ჩანაწერის წაშლა",
        "log-action-filter-delete-revision": "ვერსიის წაშლა",
        "log-action-filter-import-interwiki": "Transwiki-ს იმპორტი",
        "log-action-filter-import-upload": "XML ატვირთვიდან იმპორტი",
        "pagedata-title": "გვერდის მონაცემი",
        "pagedata-text": "ეს გვერდი აჩვენებს მონაცემის ინტერფეისს გვერდებზე. გთხოვთ წარმოადგინეთ გვერდის სათაური URL-ში, ქვეგვერდის სინტაქსის გამოყენებით.\n* Content negotiation მუშაობს კლიენტის Accept ჰედერზე დაფუძნებით. ეს ნიშნავს, რომ გვერდის მონაცემი გამოჩნდება თქვენი კლიენტის ფორმატით.",
        "pagedata-not-acceptable": "შესაბამისი ფორმატი ვერ მოიძებნა. მხარდაჭერილი MIME ტიპები: $1",
-       "pagedata-bad-title": "არასწორი სათაური: \"$1\"."
+       "pagedata-bad-title": "არასწორი სათაური: \"$1\".",
+       "passwordpolicies": "პაროლების პოლიტიკა"
 }
index e29c671..c836f82 100644 (file)
        "whatlinkshere": "Siltelgen betler",
        "whatlinkshere-title": "\"$1\" betine siltelgen betler",
        "whatlinkshere-page": "Bet:",
-       "linkshere-2": "To'mendegi betler mınag'an siltelgen: '''$1''':",
-       "nolinkshere-2": "'''$1''' degenge hesh bet siltemeydi.",
+       "linkshere": "To'mendegi betler mınag'an siltelgen: '''$2''':",
+       "nolinkshere": "'''$2''' degenge hesh bet siltemeydi.",
        "isredirect": "burıwshı bet",
        "istemplate": "qosıw",
        "isimage": "fayl siltewi",
index 385687b..631949d 100644 (file)
        "whatlinkshere": "Ayen i d-yettawi ɣer da",
        "whatlinkshere-title": "Isebtaren i sɛan azday ɣer « $1 »",
        "whatlinkshere-page": "Asebter :",
-       "linkshere-2": "Isebtar-agi sɛan azday ɣer '''$1''':",
-       "nolinkshere-2": "Ulac asebter i yesɛan azday ɣer '''$1'''.",
-       "nolinkshere-ns-2": "Ulac asebter i yesɛan azday ɣer '''$1''' deg yisem n taɣult i textareḍ.",
+       "linkshere": "Isebtar-agi sɛan azday ɣer '''$2''':",
+       "nolinkshere": "Ulac asebter i yesɛan azday ɣer '''$2'''.",
+       "nolinkshere-ns": "Ulac asebter i yesɛan azday ɣer '''$2''' deg yisem n taɣult i textareḍ.",
        "isredirect": "Asebter n usemmimeḍ",
        "istemplate": "asekcam",
        "isimage": "azday ɣer afaylu",
        "markedaspatrollederrornotify": "Axṣar n ucṛaḍ am aken yetsenqed.",
        "patrol-log-page": "Aɣmis n usenqad",
        "patrol-log-header": "Atan amezruy n ileqman yetwalsɣren.",
-       "log-show-hide-patrol": "$1 amezruy n alstiɣuryin",
        "deletedrevision": "Tasiwelt taqdimt $1 tettumḥa.",
        "filedeleteerror-short": "Tuccḍ deg tukksa n ufaylu : $1",
        "filedeleteerror-long": "Llant tuccḍiwin deg tukksa n ufaylu :\n\n$1",
index 5e14d55..27e530f 100644 (file)
        "whatlinkshere": "ТехьэпӀэхэр мыбдеж",
        "whatlinkshere-title": "«$1» техьэ напэкІуэцІхэр",
        "whatlinkshere-page": "НапэкIуэцI:",
-       "linkshere-2": "Мыбым '''$1'''  тохьэ напэкӀуэцӀхэр:",
+       "linkshere": "Мыбым '''$2'''  тохьэ напэкӀуэцӀхэр:",
        "isredirect": "напэкIуэцI-егъэкIуэкIа",
        "istemplate": "хэгъэхьэныгъэ",
        "isimage": "сурэтым и техьэпӀэ",
index 09db309..769a567 100644 (file)
        "whatlinkshere": "Takayɩhatʋ kɩtamtʋ",
        "whatlinkshere-title": "Takayɩhatʋ ndʋ tɩtamsɩna \\ $1 \\ yɔ",
        "whatlinkshere-page": "Takayɩhayʋʋ :",
-       "linkshere-2": "Takayɩhatʋ ndʋ tɩwɛ pɩ-tɛɛ yɔ tɩwɛna kpasɩ <strong>$1<strong> yɔɔ:",
+       "linkshere": "Takayɩhatʋ ndʋ tɩwɛ pɩ-tɛɛ yɔ tɩwɛna kpasɩ <strong>$2<strong> yɔɔ:",
        "isredirect": "Kɩpɩsɩnaʋ takayɩhayʋʋ",
        "istemplate": "tɛɣʋ",
        "isimage": "takayaɣ yɔɔ kpayaɣ",
index 637b2ae..d9b0a87 100644 (file)
        "sp-contributions-logs": "لاگز",
        "sp-contributions-talk": "تبادلہ خیال",
        "sp-contributions-search": "تان نیویشیرو مضمونن تلاش کورے",
-       "sp-contributions-username": "آئی.پی پتہ یا اسمِ صارف:",
+       "sp-contributions-username": "آئی پی پتہ یا صارف نام:",
        "sp-contributions-toponly": "صرف حالیہ ترین نظرثانی ترمیماتن پشاؤے",
        "sp-contributions-submit": "Search/تلاش",
        "whatlinkshere": "ھیارا کیہ کیہ لنک شینی",
        "whatlinkshere-title": "لنک شدہ صفحات \"$1\"",
        "whatlinkshere-page": " صفحہ:",
-       "linkshere-2": " '''$1''' درج ذیل صفحات لنک کوری شینی:",
-       "nolinkshere-2": "'''$1''' کیہ روابط نیکی",
+       "linkshere": " '''$2''' درج ذیل صفحات لنک کوری شینی:",
+       "nolinkshere": "'''$2''' کیہ روابط نیکی",
        "isredirect": "خور ژاغا آلدو صفحہ",
        "istemplate": "ٹرانسکلوژن",
        "isimage": "ھوٹوان لنک",
index d1a7c01..9b798f0 100644 (file)
        "whatlinkshere": "Çı itay rê gırê beno",
        "whatlinkshere-title": "Pelê ke be \"$1\"i bestninê pa",
        "whatlinkshere-page": "Pele:",
-       "linkshere-2": "Ni pelgi '''$1'''i asnenê:",
-       "nolinkshere-2": "Pelgê ke '''$1'''i asnenê çinê.",
+       "linkshere": "Ni pelgi '''$2'''i asnenê:",
+       "nolinkshere": "Pelgê ke '''$2'''i asnenê çinê.",
        "isredirect": "pela ciheti",
        "istemplate": "ilawekerdis",
        "isimage": "girê dosya",
index a94f33a..3967e27 100644 (file)
        "whatlinkshere": "سىلتەلگەن بەتتەر",
        "whatlinkshere-title": "$1 دەگەنگە سىلتەلگەن بەتتەر",
        "whatlinkshere-page": "بەت:",
-       "linkshere-2": "'''$1''' دەگەنگە مىنا بەتتەر سىلتەيدى:",
-       "nolinkshere-2": "'''$1''' دەگەنگە ەش بەت سىلتەمەيدى.",
-       "nolinkshere-ns-2": "تاڭدالعان ەسىم اياسىندا '''$1''' دەگەنگە ەشقانداي بەت سىلتەمەيدى.",
+       "linkshere": "'''$2''' دەگەنگە مىنا بەتتەر سىلتەيدى:",
+       "nolinkshere": "'''$2''' دەگەنگە ەش بەت سىلتەمەيدى.",
+       "nolinkshere-ns": "تاڭدالعان ەسىم اياسىندا '''$2''' دەگەنگە ەشقانداي بەت سىلتەمەيدى.",
        "isredirect": "ايداتۋ بەتى",
        "istemplate": "كىرىكبەت",
        "isimage": "سۋرەت سىلتەمەسى",
index 28d497c..93f7982 100644 (file)
        "whatlinkshere": "Мұнда сілтейтін беттер",
        "whatlinkshere-title": "$1 дегенге сілтейтін беттер",
        "whatlinkshere-page": "Бет:",
-       "linkshere-2": "'''$1''' дегенге мына беттер сілтейді:",
-       "nolinkshere-2": "'''$1''' дегенге еш бет сілтемейді.",
-       "nolinkshere-ns-2": "Таңдалған есім кеңістігінде '''$1''' дегенге ешқандай бет сілтемейді.",
+       "linkshere": "'''$2''' дегенге мына беттер сілтейді:",
+       "nolinkshere": "'''$2''' дегенге еш бет сілтемейді.",
+       "nolinkshere-ns": "Таңдалған есім кеңістігінде '''$2''' дегенге ешқандай бет сілтемейді.",
        "isredirect": "бағыттау беті",
        "istemplate": "кіріcтірілген",
        "isimage": "файл сілтемесі",
        "markedaspatrollederrornotify": "Тексерілді деп белгіленбеді.",
        "patrol-log-page": "Тексеру журналы",
        "patrol-log-header": "Бұл тексерілген нұсқалар журналы",
-       "log-show-hide-patrol": "$1 тексеру журналы",
-       "log-show-hide-tag": "$1 белгі журналы",
        "deletedrevision": "Ескі түзетуін жойды: $1",
        "filedeleteerror-short": "Файл жою қатесі: $1",
        "filedeleteerror-long": "Файлды жойғанда қателер кездесті:\n\n$1",
index 342339a..eac51e1 100644 (file)
        "whatlinkshere": "Mında silteýtin better",
        "whatlinkshere-title": "$1 degenge silteýtin better",
        "whatlinkshere-page": "Bet:",
-       "linkshere-2": "'''$1''' degenge mına better silteýdi:",
-       "nolinkshere-2": "'''$1''' degenge eş bet siltemeýdi.",
-       "nolinkshere-ns-2": "Tañdalğan esim ayasında '''$1''' degenge eşqandaý bet siltemeýdi.",
+       "linkshere": "'''$2''' degenge mına better silteýdi:",
+       "nolinkshere": "'''$2''' degenge eş bet siltemeýdi.",
+       "nolinkshere-ns": "Tañdalğan esim ayasında '''$2''' degenge eşqandaý bet siltemeýdi.",
        "isredirect": "aýdatw beti",
        "istemplate": "kirikbet",
        "isimage": "swret siltemesi",
index 11c13cc..e130589 100644 (file)
        "botpasswords-existing": "ពាក្យសម្ងាត់រូបយន្តមានហើយ",
        "botpasswords-createnew": "បង្កើតពាក្យសម្ងាត់រូបយន្តថ្មី",
        "botpasswords-editexisting": "កែប្រែពាក្យសម្ងាត់រូបយន្តមានហើយ",
+       "botpasswords-label-needsreset": "(ពាក្យសម្ងាត់ចាំបាច់ត្រូវកំណត់ឡើងវិញ)",
        "botpasswords-label-appid": "ឈ្មោះរូបយន្ត៖",
        "botpasswords-label-create": "បង្កើត",
        "botpasswords-label-update": "បន្ទាន់សម័យ",
        "subject-preview": "ការមើលជាមុនរបស់ប្រធានបទ៖",
        "previewerrortext": "មានបញ្ហាកើតឡើងពេលព្យាយាមមើលជាមុនបន្លាស់ប្ដូររបស់អ្នក។",
        "blockedtitle": "អ្នកប្រើនេះត្រូវបានហាមឃាត់ហើយ",
-       "blockedtext": "'''ឈ្មោះគណនីឬអាសយដ្ឋានIPរបស់អ្នកស្ថិតក្រោមការហាមឃាត់ហើយ។'''\n\nការហាមឃាត់ត្រូវបានធ្វើដោយ $1\n\nដោយសំអាងលើហេតុផល ''$2''។\n\n\n* ចាប់ផ្ដើមការហាមឃាត់ ៖ $8\n* ផុតកំណត់ការហាមឃាត់ ៖ $6\n* គណនីហាមឃាត់់ ៖ $7\n\n\nអ្នកអាចទាក់ទងទៅ $1 ឬ [[{{MediaWiki:Grouppage-sysop}}|អ្នកអភិបាល]]ដទៃទៀតដើម្បីពិភាក្សាពីការហាមឃាត់នេះ ។\n\nអ្នកមិនអាចប្រើប្រាស់មុខងារ \"អ៊ីមែលទៅអ្នកប្រើប្រាស់នេះ\" បានទេ លើកលែងតែអាសយដ្ឋានអ៊ីមែលត្រឹមត្រូវមួយ​ត្រូវបានផ្ដល់អោយក្នុង[[Special:Preferences|ចំណង់ចំណូលចិត្ត]]​របស់លោកអ្នកហើយលោកអ្នកមិនត្រូវបានគេហាមឃាត់មិនឱ្យប្រើប្រាស់មុខងារនោះ។\n\nអាសយដ្ឋានIPបច្ចុប្បន្នរបស់លោកអ្នកគឺ $3 និងអត្តលេខហាមឃាត់គឺ #$5 ។\n\nសូមបញ្ចូលព័ត៌មានលំអិតទាំងអស់ខាងលើនេះ ក្នុងអ៊ីមែលទាក់ទងនឹងបញ្ហានេះ។",
-       "autoblockedtext": "អាសយដ្ឋានIPរបស់អ្នកបានត្រូវហាមឃាត់ដោយស្វ័យប្រវត្តិ ព្រោះវាត្រូវបានប្រើប្រាស់ដោយអ្នកប្រើប្រាស់ម្នាក់ទៀត ដែលត្រូវបានហាមឃាត់ដោយ $1 ។\n\nមូលហេតុលើកឡើង៖\n\n:''$2''\n\n* ការចាប់ផ្តើមហាមឃាត់៖ $8\n* ពេលផុតកំណត់ហាមឃាត់៖ $6\n* គណនីហាមឃាត់៖ $7\n\nអ្នកអាចទាក់ទង $1 ឬ[[{{MediaWiki:Grouppage-sysop}}|អ្នកអភិបាល]]ណាម្នាក់ ដើម្បីពិភាក្សាអំពីការហាមឃាត់នេះ។\n\nសូមកត់សម្គាល់ថាអ្នកមិនអាចប្រើប្រាស់មុខងារ \"អ៊ីមែលអ្នកប្រើប្រាស់នេះ\" បានទេ លុះត្រាតែមានអាសយដ្ឋានអ៊ីមែលត្រឹមត្រូវមួយ បានចុះឈ្មោះក្នុង[[Special:Preferences|ចំណង់ចំណូលចិត្ត]]របស់អ្នក ហើយអ្នកមិនត្រូវបានហាមឃាត់មិនឱ្យប្រើប្រាស់មុខងារនោះ ។\n\nអាសយដ្ឋានIPបច្ចុប្បន្នរបស់អ្នកគឺ $3។ អត្តលេខហាមឃាត់គឺ #$5។\nសូមបញ្ចូលព័ត៌មានលំអិតទាំងអស់ខាងលើនេះ ក្នុងអ៊ីមែលទាក់ទងនឹងបញ្ហានេះ។",
+       "blockedtext": "<strong>ឈ្មោះគណនីឬអាសយដ្ឋានIPរបស់អ្នកស្ថិតក្រោមការហាមឃាត់ហើយ។</strong>\n\nការហាមឃាត់ត្រូវបានធ្វើដោយ $1\n\nដោយមូលហេតុ <em>$2</em>។\n\n\n* ចាប់ផ្ដើមការហាមឃាត់ ៖ $8\n* ផុតកំណត់ការហាមឃាត់ ៖ $6\n* គណនីហាមឃាត់់ ៖ $7\n\n\nអ្នកអាចទាក់ទងទៅ $1 ឬ [[{{MediaWiki:Grouppage-sysop}}|អ្នកអភិបាល]]ដទៃទៀតដើម្បីពិភាក្សាពីការហាមឃាត់នេះ ។\n\nអ្នកមិនអាចប្រើប្រាស់មុខងារ\"{{int:emailuser}}\"បានទេ លើកលែងតែអាសយដ្ឋានអ៊ីមែលត្រឹមត្រូវមួយ​ត្រូវបានផ្ដល់អោយក្នុង[[Special:Preferences|ចំណង់ចំណូលចិត្ត]]​របស់លោកអ្នកហើយលោកអ្នកមិនត្រូវបានគេហាមឃាត់មិនឱ្យប្រើប្រាស់មុខងារនោះ។\n\nអាសយដ្ឋានIPបច្ចុប្បន្នរបស់លោកអ្នកគឺ $3 និងអត្តលេខហាមឃាត់គឺ #$5 ។\n\nសូមបញ្ចូលព័ត៌មានលម្អិតទាំងអស់ខាងលើនេះ ក្នុងអ៊ីមែលទាក់ទងនឹងបញ្ហានេះ។",
+       "autoblockedtext": "អាសយដ្ឋានIPរបស់អ្នកបានត្រូវហាមឃាត់ដោយស្វ័យប្រវត្តិ ព្រោះវាត្រូវបានប្រើប្រាស់ដោយអ្នកប្រើប្រាស់ម្នាក់ទៀត ដែលត្រូវបានហាមឃាត់ដោយ $1 ។\n\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សូមបញ្ចូលព័ត៌មានលម្អិតទាំងអស់ខាងលើនេះ ក្នុងអ៊ីមែលទាក់ទងនឹងបញ្ហានេះ។",
+       "systemblockedtext": "អាសយដ្ឋានIPរបស់អ្នកបានត្រូវហាមឃាត់ដោយស្វ័យប្រវត្តិដោយមេឌាវិគី។\n\nមូលហេតុ៖\n\n:<em>$2</em>\n\n* ចាប់ផ្តើមហាមឃាត់៖ $8\n* ផុតកំណត់ហាមឃាត់៖ $6\n* គណនីហាមឃាត់៖ $7\n\nអាសយដ្ឋានIPបច្ចុប្បន្នរបស់អ្នកគឺ $3។ \nសូមបញ្ចូលព័ត៌មានលម្អិតទាំងអស់ខាងលើនេះ ក្នុងអ៊ីមែលទាក់ទងនឹងបញ្ហានេះ។",
        "blockednoreason": "គ្មានហេតុផល​ត្រូវបានលើកឡើង",
        "whitelistedittext": "អ្នកត្រូវតែ $1 ដើម្បី​កែប្រែ​ខ្លឹមសារទំព័រ។",
        "confirmedittext": "អ្នកត្រូវតែផ្ទៀងផ្ទាត់បញ្ជាក់អាសយដ្ឋានអ៊ីមែលរបស់អ្នកមុននឹងកែប្រែខ្លឹមសារអត្ថបទ។\n\nសូមកំណត់និងផ្តល់សុពលភាពឱ្យអាសយដ្ឋានអ៊ីមែលរបស់អ្នកតាម [[Special:Preferences|ចំណង់ចំណូលចិត្ត]] របស់អ្នក។",
        "undo-norev": "កំណែ​មិន​អាច​មិន​ធ្វើ​ឡើង​វិញ​បាន​ទេ​ ពីព្រោះ​វា​មិន​មាន​ឬ​ត្រូវ​បាន​លុប​បាត់​ទៅ​ហើយ​។",
        "undo-summary": "មិន​ធ្វើ​វិញ​នូវ​កំណែ​ប្រែ $1 ដោយ​ [[Special:Contributions/$2|$2]] ([[User talk:$2|ការពិភាក្សា​]])",
        "undo-summary-username-hidden": "មិន​ធ្វើ​វិញ​នូវ​កំណែ​ប្រែ $1 ដោយអ្នកប្រើប្រាស់លាក់ឈ្មោះ",
-       "cantcreateaccount-text": "ការបង្កើតគណនីពីអាសយដ្ឋាន IP ('''$1''') នេះ ត្រូវបានរារាំងដោយ [[User:$3|$3]]។\n\nហេតុផលដែលត្រូវលើកឡើងដោយ $3 គឺ ''$2''",
+       "cantcreateaccount-text": "ការបង្កើតគណនីពីអាសយដ្ឋាន IP (<strong>$1</strong>) នេះ ត្រូវបានហាមឃាត់ដោយ [[User:$3|$3]]។\n\nមូលហេតុដែល$3ផ្តល់មកគឺ <em>$2</em>",
+       "cantcreateaccount-range-text": "ការបង្កើតគណនីពីអាសយដ្ឋានIPក្នុងចន្លោះ<strong>$1</strong> ដែលរួមមានអាសយដ្ឋានIP(<strong>$4</strong>)របស់អ្នកផងដែរ ត្រូវបានហាមឃាត់ដោយ [[User:$3|$3]]។\n\nមូលហេតុដែល$3ផ្តល់មកគឺ <em>$2</em>",
        "viewpagelogs": "មើលកំណត់ហេតុសម្រាប់ទំព័រនេះ",
        "nohistory": "មិនមានប្រវត្តិកំណែប្រែ​ចំពោះទំព័រនេះ។",
        "currentrev": "កំណែថ្មីបំផុត",
        "right-siteadmin": "ចាក់សោនិងបើកសោមូលដ្ឋានទិន្នន័យ",
        "right-override-export-depth": "នាំចេញទំព័ររួមទាំងទំព័រដែលមានភ្ជាប់តំណភ្ជាប់​រហូតដល់លំដាប់ទី៥",
        "right-sendemail": "ផ្ញើអ៊ីមែលទៅកាន់អ្នកប្រើដទៃ",
+       "grant-blockusers": "ការហាមឃាត់និងដកការហាមឃាត់អ្នកប្រើប្រាស់",
        "grant-createaccount": "បង្កើតគណនី",
        "grant-basic": "សិទ្ធិបឋម",
        "grant-viewdeleted": "មើលឯកសារនិងទំព័រដែលបានលុបចោល",
        "protect_expiry_old": "ពេលវេលាផុតកំណត់ ឋិតក្នុងអតីតកាល។",
        "protect-unchain-permissions": "ដោះសោរជំរើសក្នុងការការពារលើសពីនេះទៀត",
        "protect-text": "លោកអ្នកអាចមើលនិងផ្លាស់ប្ដូរកម្រិតការពារទីនេះចំពោះទំព័រ'''$1'''។",
-       "protect-locked-blocked": "អ្នកមិនអាចប្តូរកម្រិតការពារពេលស្ថិតក្រោមការហាមឃាត់ទេ។ នេះគឺជាការកំណត់ថ្មីៗសម្រាប់ទំព័រ'''$1'''៖",
+       "protect-locked-blocked": "អ្នកមិនអាចប្តូរកម្រិតការពារពេលស្ថិតក្រោមការហាមឃាត់ទេ។ នេះគឺជាការកំណត់ថ្មីៗសម្រាប់ទំព័រ<strong>$1</strong>៖",
        "protect-locked-dblock": "កម្រិត​នៃ​ការ​ការពារ​មិន​អាច​ផ្លាស់​ប្ដូរ​បាន​ទេ​ ដោយសារ​មាន​ជាប់​​សោ​មូលដ្នាន​ទិន្នន័យសកម្ម​។\nនេះ​គឺជា​ការ​កំណត់​បច្ចុប្បន្ន​សម្រាប់​ទំព័រ​ '''$1''' ៖",
        "protect-locked-access": "គណនីរបស់អ្នកគ្មានការអនុញ្ញាតក្នុងការផ្លាស់ប្ដូរ កម្រិតកាពារទំព័រ ។\nនេះជាការកំណត់បច្ចុប្បន្ន ចំពោះទំព័រ '''$1''' ៖",
        "protect-cascadeon": "បច្ចុប្បន្នទំព័រនេះត្រូវបានការពារ ព្រោះវាបានស្ថិតក្នុង {{PLURAL:$1|ទំព័រដែលមាន}} ការការពារជាថ្នាក់​។\n\nអ្នកអាចផ្លាស់ប្តូរកម្រិតការពារនៃ ទំព័រ ប៉ុន្តែវានឹងមិនប៉ះពាល់ដល់ការការពារជាថ្នាក់ទេ។",
        "whatlinkshere": "អ្វី​ដែលភ្ជាប់មកទីនេះ",
        "whatlinkshere-title": "ទំព័រនានាដែល​តភ្ជាប់​ទៅ \"$1\"",
        "whatlinkshere-page": "ទំព័រ៖",
-       "linkshere-2": "ទំព័រដូចតទៅ​នេះតភ្ជាប់មក '''$1''' ៖",
-       "nolinkshere-2": "គ្មានទំព័រណាមួយតភ្ជាប់ទៅ '''$1''' ទេ។",
-       "nolinkshere-ns-2": "គ្មានទំព័រណាមួយតភ្ជាប់ទៅ '''$1''' ក្នុងប្រភេទដែលបានជ្រើសរើស។",
+       "linkshere": "ទំព័រដូចតទៅ​នេះតភ្ជាប់មក '''$2''' ៖",
+       "nolinkshere": "គ្មានទំព័រណាមួយតភ្ជាប់ទៅ '''$2''' ទេ។",
+       "nolinkshere-ns": "គ្មានទំព័រណាមួយតភ្ជាប់ទៅ '''$2''' ក្នុងប្រភេទដែលបានជ្រើសរើស។",
        "isredirect": "ទំព័របញ្ជូនបន្ត",
        "istemplate": "ការដាក់បញ្ចូល",
        "isimage": "តំណភ្ជាប់ឯកសារ",
        "block": "ដាក់ការហាមឃាត់លើអ្នកប្រើប្រាស់",
        "unblock": "ដកការហាមឃាត់លើអ្នកប្រើប្រាស់",
        "blockip": "ហាមឃាត់{{GENDER:$1|អ្នកប្រើប្រាស់}}",
-       "blockiptext": "សូម​ប្រើប្រាស់​សំណុំ​បែបបទ​ខាងក្រោម​ដើម្បី​ហាមឃាត់ការសរសេរ​ពី​អាសយដ្ឋាន IP ឬ​ឈ្មោះ​អ្នកប្រើប្រាស់ណាមួយ​។\nការ​ធ្វើ​បែបនេះ​គួរតែ​ធ្វើឡើង​ក្នុង​គោលបំណង​បង្ការ​ការប៉ុនប៉ង​បំផ្លាញ(vandalism)ដូច​ដែល​មាន​ចែង​ក្នុង[[{{MediaWiki:Policy-url}}|គោលការណ៍]]។\nសូមបំពេញមូលហេតុច្បាស់លាស់មួយខាងក្រោម (ឧទាហរណ៍៖ រាយឈ្មោះទំព័រនានាដែលត្រូវបានគេបំផ្លាញ)។",
+       "blockiptext": "សូម​ប្រើប្រាស់​សំណុំ​បែបបទ​ខាងក្រោម​ដើម្បី​ហាមឃាត់ការសរសេរ​ពី​អាសយដ្ឋានIP ឬ​អត្តនាមណាមួយ​។\nការ​ធ្វើ​បែបនេះ​គួរតែ​ធ្វើឡើង​ក្នុង​គោលបំណង​បង្ការ​ការប៉ុនប៉ងបំផ្លិច​បំផ្លាញដូច​ដែល​មាន​ចែង​ក្នុង[[{{MediaWiki:Policy-url}}|គោលការណ៍]]។\nសូមបំពេញមូលហេតុច្បាស់លាស់មួយខាងក្រោម (ឧទាហរណ៍៖ រាយឈ្មោះទំព័រនានាដែលគេបំផ្លិចបំផ្លាញ)។\nអ្នកអាចហាមឃាត់អាសយដ្ឋានIPជាជួរដោយប្រើកូដ[https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing CIDR] ។ ប្រវែងជួរវែងបំផុតគឺ /$1 សម្រាប់ IPv4 និង /$2 សម្រាប់ IPv6។",
        "ipaddressorusername": "អាសយដ្ឋានIP ឬអត្តនាម៖",
        "ipbexpiry": "រយៈពេលផុតកំណត់៖",
        "ipbreason": "មូលហេតុ៖",
-       "ipbreason-dropdown": "*á\9e\98á\9e¼á\9e\9bá\9e á\9f\81á\9e\8fá\9e»á\9e á\9e¶á\9e\98á\9e\83á\9e¶á\9e\8fá\9f\8bá\9e\87á\9e¶á\9e\91á\9e¼á\9e\91á\9f\85\n** á\9e\8aá\9e¶á\9e\80á\9f\8bá\9e\94á\9e\89á\9f\92á\9e\85á\9e¼á\9e\9bá\9e\96á\9f\90á\9e\8fá\9f\8cá\9e\98á\9e¶á\9e\93á\9e\98á\9e·á\9e\93á\9e\96á\9e·á\9e\8f\n** á\9e\8aá\9e\80á\9e\81á\9f\92á\9e\9bá\9e¹á\9e\98á\9e\91á\9e¶á\9f\86á\9e\84á\9e\9fá\9f\92á\9e\9aá\9e»á\9e\84á\9e\96á\9e¸á\9e\91á\9f\86á\9e\96á\9f\90á\9e\9aá\9e\93á\9e¶á\9e\93á\9e¶\n** á\9e\8aá\9e¶á\9e\80á\9f\8bá\9e\8fá\9f\86á\9e\8eá\9e\97á\9f\92á\9e\87á\9e¶á\9e\94á\9f\8bá\9e\9fá\9f\92á\9e\94á\9f\89á\9e¶á\9e\98á\9e\8fá\9e\97á\9f\92á\9e\87á\9e¶á\9e\94á\9f\8bá\9e\91á\9f\85á\9e\9cá\9e·á\9e\94á\9e\9fá\9f\83á\9e\90á\9f\8dá\9e\81á\9e¶á\9e\84á\9e\80á\9f\92á\9e\9aá\9f\85\n** á\9e\94á\9e\89á\9f\92á\9e\85á\9e¼á\9e\9bá\9e\81á\9f\92á\9e\9bá\9e¹á\9e\98á\9e\9fá\9e¶á\9e\9aá\9e\82á\9f\92á\9e\98á\9e¶á\9e\93á\9e\93á\9f\90á\9e\99á\9e¬á\9e\81á\9f\92á\9e\9bá\9e¹á\9e\98á\9e\9fá\9e¶á\9e\9aá\9e\98á\9e·á\9e\93á\9e¢á\9e¶á\9e\85á\9e\99á\9e\9bá\9f\8bá\9e\94á\9e¶á\9e\93á\9e\91á\9f\85á\9e\80á\9f\92á\9e\93á\9e»á\9e\84á\9e\91á\9f\86á\9e\96á\9f\90á\9e\9aá\9e\93á\9e¶á\9e\93á\9e¶\n** á\9e¢á\9f\86á\9e\96á\9e¾á\9e\82á\9f\86á\9e\9aá\9e¶á\9e\98á\9e\80á\9f\86á\9e á\9f\82á\9e\84á\9e¬á\9e\9aá\9f\86á\9e\9bá\9f\84á\9e\97á\9e\94á\9f\86á\9e\96á\9e¶á\9e\93á\9e\9fá\9e·á\9e\91á\9f\92á\9e\92á\9e·á\9e\98á\9e\93á\9e»á\9e\9fá\9f\92á\9e\9f\n** á\9e\94á\9f\92á\9e\9aá\9e¾á\9e\94á\9f\92á\9e\9aá\9e¶á\9e\9fá\9f\8bá\9e\82á\9e\8eá\9e\93á\9e¸á\9e\85á\9f\92á\9e\9aá\9e¾á\9e\93á\9e\80á\9f\92á\9e\93á\9e»á\9e\84á\9e\82á\9f\84á\9e\9bá\9e\94á\9f\86á\9e\8eá\9e\84á\9e\98á\9e·á\9e\93á\9e\9bá\9f\92á\9e¢\n** á\9e\94á\9f\92á\9e\9aá\9e¾á\9e\94á\9f\92á\9e\9aá\9e¶á\9e\9fá\9f\8bá\9e\88á\9f\92á\9e\98á\9f\84á\9f\87ដែលមិនអាចទទួលយកបាន",
+       "ipbreason-dropdown": "*á\9e\98á\9e¼á\9e\9bá\9e á\9f\81á\9e\8fá\9e»á\9e á\9e¶á\9e\98á\9e\83á\9e¶á\9e\8fá\9f\8bá\9e\87á\9e¶á\9e\91á\9e¼á\9e\91á\9f\85\n** á\9e\8aá\9e¶á\9e\80á\9f\8bá\9e\94á\9e\89á\9f\92á\9e\85á\9e¼á\9e\9bá\9e\96á\9f\90á\9e\8fá\9f\8cá\9e\98á\9e¶á\9e\93á\9e\98á\9e·á\9e\93á\9e\96á\9e·á\9e\8f\n** á\9e\8aá\9e\80á\9e\81á\9f\92á\9e\9bá\9e¹á\9e\98á\9e\91á\9e¶á\9f\86á\9e\84á\9e\9fá\9f\92á\9e\9aá\9e»á\9e\84á\9e\96á\9e¸á\9e\91á\9f\86á\9e\96á\9f\90á\9e\9aá\9e\93á\9e¶á\9e\93á\9e¶\n** á\9e\8aá\9e¶á\9e\80á\9f\8bá\9e\8fá\9f\86á\9e\8eá\9e\97á\9f\92á\9e\87á\9e¶á\9e\94á\9f\8bá\9e\9fá\9f\92á\9e\94á\9f\89á\9e¶á\9e\98á\9e\8fá\9e\97á\9f\92á\9e\87á\9e¶á\9e\94á\9f\8bá\9e\91á\9f\85á\9e\9cá\9e·á\9e\94á\9e\9fá\9f\83á\9e\90á\9f\8dá\9e\81á\9e¶á\9e\84á\9e\80á\9f\92á\9e\9aá\9f\85\n** á\9e\94á\9e\89á\9f\92á\9e\85á\9e¼á\9e\9bá\9e\81á\9f\92á\9e\9bá\9e¹á\9e\98á\9e\9fá\9e¶á\9e\9aá\9e\82á\9f\92á\9e\98á\9e¶á\9e\93á\9e\93á\9f\90á\9e\99á\9e¬á\9e\81á\9f\92á\9e\9bá\9e¹á\9e\98á\9e\9fá\9e¶á\9e\9aá\9e\98á\9e·á\9e\93á\9e¢á\9e¶á\9e\85á\9e\99á\9e\9bá\9f\8bá\9e\94á\9e¶á\9e\93á\9e\91á\9f\85á\9e\80á\9f\92á\9e\93á\9e»á\9e\84á\9e\91á\9f\86á\9e\96á\9f\90á\9e\9aá\9e\93á\9e¶á\9e\93á\9e¶\n** á\9e¢á\9f\86á\9e\96á\9e¾á\9e\82á\9f\86á\9e\9aá\9e¶á\9e\98á\9e\80á\9f\86á\9e á\9f\82á\9e\84á\9e¬á\9e\9aá\9f\86á\9e\9bá\9f\84á\9e\97á\9e\94á\9f\86á\9e\96á\9e¶á\9e\93á\9e\9fá\9e·á\9e\91á\9f\92á\9e\92á\9e·á\9e\98á\9e\93á\9e»á\9e\9fá\9f\92á\9e\9f\n** á\9e\94á\9f\92á\9e\9aá\9e¾á\9e\94á\9f\92á\9e\9aá\9e¶á\9e\9fá\9f\8bá\9e\82á\9e\8eá\9e\93á\9e¸á\9e\85á\9f\92á\9e\9aá\9e¾á\9e\93á\9e\80á\9f\92á\9e\93á\9e»á\9e\84á\9e\82á\9f\84á\9e\9bá\9e\94á\9f\86á\9e\8eá\9e\84á\9e\98á\9e·á\9e\93á\9e\9bá\9f\92á\9e¢\n** á\9e\94á\9f\92á\9e\9aá\9e¾á\9e\94á\9f\92á\9e\9aá\9e¶á\9e\9fá\9f\8bá\9e¢á\9e\8fá\9f\92á\9e\8fá\9e\93á\9e¶á\9e\98ដែលមិនអាចទទួលយកបាន",
        "ipb-hardblock": "ហាមមិនអោយអ្នកប្រើប្រាស់ដែលបានកត់ឈ្មោះចូល មិនអោយធ្វើការកែប្រែពីអាសយដ្ឋាន IP នេះ",
        "ipbcreateaccount": "ហាមមិនអោយបង្កើតគណនី",
        "ipbemailban": "ហាមមិនអោយអ្នកប្រើប្រាស់ផ្ញើរអ៊ីមែល",
        "ipb-change-block": "ហាមឃាត់អ្នកប្រើប្រាស់នេះឡើងវិញតាមការកំណត់ទាំងនេះ",
        "ipb-confirm": "បញ្ជាក់ទទួលស្គាល់ការហាមឃាត់",
        "badipaddress": "អាសយដ្ឋានIPមិនត្រឹមត្រូវ",
-       "blockipsuccesssub": "ដាក់ការហាមឃាត់បានសំរេច",
+       "blockipsuccesssub": "ដាក់ការហាមឃាត់បានសម្រេច",
+       "blockipsuccesstext": "[[Special:Contributions/$1|$1]] ត្រូវបានហាមឃាត់<br />\nសូមមើល[[Special:BlockList|បញ្ជីការហាមឃាត់]] ដើម្បីត្រួតពិនិត្យការហាមឃាត់ឡើងវិញ។",
        "ipb-blockingself": "អ្នករៀបនឹងរាំងខ្ទប់ខ្លួនឯងហើយ! តើអ្នកប្រាកដថាចង់ធ្វើបែបនេះមែនទេ?",
-       "ipb-confirmhideuser": "á\9e¢á\9f\92á\9e\93á\9e\80á\9e\9aá\9f\80á\9e\94á\9e\93á\9e¹á\9e\84á\9e\9aá\9e¶á\9f\86á\9e\84á\9e\81á\9f\92á\9e\91á\9e\94់អ្នកប្រើប្រាស់ម្នាក់ដែលមានប្រើមុខងារ \"អ្នកប្រើប្រាស់លាក់មុខ\"។ ការធ្វើបែបនេះនឹងលាក់ឈ្មោះរបស់អ្នកប្រើប្រាស់នេះនៅក្នុងបញ្ជីនិងកំណត់ហេតុទាំងអស់។ តើអ្នកប្រាកដថាចង់ធ្វើបែបនេះមែនទេ?",
+       "ipb-confirmhideuser": "á\9e¢á\9f\92á\9e\93á\9e\80á\9e\9aá\9f\80á\9e\94á\9e\93á\9e¹á\9e\84á\9e á\9e¶á\9e\98á\9e\83á\9e¶á\9e\8f់អ្នកប្រើប្រាស់ម្នាក់ដែលមានប្រើមុខងារ \"អ្នកប្រើប្រាស់លាក់មុខ\"។ ការធ្វើបែបនេះនឹងលាក់ឈ្មោះរបស់អ្នកប្រើប្រាស់នេះនៅក្នុងបញ្ជីនិងកំណត់ហេតុទាំងអស់។ តើអ្នកប្រាកដថាចង់ធ្វើបែបនេះមែនទេ?",
        "ipb-edit-dropdown": "កែប្រែមូលហេតុនៃការហាមឃាត់",
        "ipb-unblock-addr": "ដកការហាមឃាត់លើ $1",
        "ipb-unblock": "ដកការហាមឃាត់លើអ្នកប្រើប្រាស់ ឬ អាសយដ្ឋាន IP",
        "blocklist-params": "ប៉ារ៉ាមែត្ររបស់ការហាមឃាត់",
        "blocklist-reason": "មូលហេតុ",
        "ipblocklist-submit": "ស្វែងរក",
+       "ipblocklist-otherblocks": "{{PLURAL:$1|ការហាមឃាត់|ការហាមឃាត់}}ផ្សេងទៀត",
        "infiniteblock": "ជារៀងរហូត",
        "expiringblock": "ផុតកំណត់ នៅថ្ងៃ $1 ម៉ោង $2",
        "anononlyblock": "សម្រាប់តែអនាមិកជនប៉ុណ្ណោះ",
        "createaccountblock": "ការបង្កើតគណនីត្រូវបានហាមឃាត់",
        "emailblock": "អ៊ីមែលដែលត្រូវបានហាមឃាត់",
        "blocklist-nousertalk": "មិនអាចកែប្រែទំព័រពិភាក្សាខ្លួនឯងទេ",
-       "ipblocklist-empty": "á\9e\94á\9e\89á\9f\92á\9e\87á\9e¸á\9e á\9e¶á\9e\98á\9e\83á\9e¶á\9e\8fá\9f\8bá\9e\82á\9eºá\9e\91ទេ។",
+       "ipblocklist-empty": "á\9e\82á\9f\92á\9e\98á\9e¶á\9e\93á\9e¢á\9f\92á\9e\9cá\9e¸á\9e\93á\9f\85á\9e\80á\9f\92á\9e\93á\9e»á\9e\84á\9e\94á\9e\89á\9f\92á\9e\87á\9e¸á\9e\80á\9e¶á\9e\9aá\9e á\9e¶á\9e\98á\9e\83á\9e¶á\9e\8fá\9f\8bទេ។",
        "ipblocklist-no-results": "អាសយដ្ឋានIPឬអត្តនាមដែលបានផ្ដល់មកគឺមិនស្ថិតក្នុងបញ្ជីការហាមឃាត់ទេ។",
        "blocklink": "ដាក់ការហាមឃាត់",
        "unblocklink": "ដកការហាមឃាត់",
        "change-blocklink": "ផ្លាស់ប្ដូរការហាមឃាត់",
        "contribslink": "ការរួមចំណែក",
        "emaillink": "ផ្ញើអ៊ីមែល",
-       "autoblocker": "á\9e¢á\9f\92á\9e\93á\9e\80á\9e\94á\9e¶á\9e\93á\9e\8fá\9f\92á\9e\9aá\9e¼á\9e\9cá\9e\94á\9e¶á\9e\93á\9e á\9e¶á\9e\98á\9e\83á\9e¶á\9e\8fá\9f\8bá\9e\8aá\9f\84á\9e\99á\9e\9fá\9f\92á\9e\9cá\9f\90á\9e\99á\9e\94á\9f\92á\9e\9aá\9e\9cá\9e\8fá\9f\92á\9e\8fá\9e· á\9e\96á\9e¸á\9e\96á\9f\92á\9e\9aá\9f\84á\9f\87á\9e¢á\9e¶á\9e\9fá\9e\99á\9e\8aá\9f\92á\9e\8bá\9e¶á\9e\93IPá\9e\9aá\9e\94á\9e\9fá\9f\8bá\9e¢á\9f\92á\9e\93á\9e\80á\9e\8fá\9f\92á\9e\9aá\9e¼á\9e\9cá\9e\94á\9e¶á\9e\93á\9e\94á\9f\92á\9e\9aá\9e¾á\9e\94á\9f\92á\9e\9aá\9e¶á\9e\9fá\9f\8bá\9e\8aá\9f\84á\9e\99\"[[User:$1|$1]]\"á\9f\94 á\9e\98á\9e¼á\9e\9bá\9e á\9f\81á\9e\8fá\9e»á\9e\9bá\9e¾á\9e\80á\9e¡á\9e¾á\9e\84á\9e\85á\9f\86á\9e\96á\9f\84á\9f\87á\9e\80á\9e¶á\9e\9aá\9e á\9e¶á\9e\98á\9e\83á\9e¶á\9e\8fá\9f\8b$1á\9e\82á\9eºá\9f\96 \"$2\"",
+       "autoblocker": "á\9e¢á\9f\92á\9e\93á\9e\80á\9e\94á\9e¶á\9e\93á\9e\8fá\9f\92á\9e\9aá\9e¼á\9e\9cá\9e\94á\9e¶á\9e\93á\9e á\9e¶á\9e\98á\9e\83á\9e¶á\9e\8fá\9f\8bá\9e\8aá\9f\84á\9e\99á\9e\9fá\9f\92á\9e\9cá\9f\90á\9e\99á\9e\94á\9f\92á\9e\9aá\9e\9cá\9e\8fá\9f\92á\9e\8fá\9e· á\9e\96á\9e¸á\9e\96á\9f\92á\9e\9aá\9f\84á\9f\87á\9e¢á\9e¶á\9e\9fá\9e\99á\9e\8aá\9f\92á\9e\8bá\9e¶á\9e\93IPá\9e\9aá\9e\94á\9e\9fá\9f\8bá\9e¢á\9f\92á\9e\93á\9e\80á\9e\8fá\9f\92á\9e\9aá\9e¼á\9e\9cá\9e\94á\9e¶á\9e\93á\9e\94á\9f\92á\9e\9aá\9e¾á\9e\94á\9f\92á\9e\9aá\9e¶á\9e\9fá\9f\8bá\9e\90á\9f\92á\9e\98á\9e¸á\9f\97á\9e\93á\9f\81á\9f\87á\9e\8aá\9f\84á\9e\99\"[[User:$1|$1]]\"á\9f\94 á\9e\98á\9e¼á\9e\9bá\9e á\9f\81á\9e\8fá\9e»á\9e á\9e¶á\9e\98á\9e\83á\9e¶á\9e\8fá\9f\8b$1á\9e\82á\9eº \"$2\"",
        "blocklogpage": "កំណត់ហេតុនៃការហាមឃាត់",
-       "blocklog-showlog": "អ្នកប្រើប្រាស់នេះត្រូវបានរាំងខ្ទប់មុននេះម្ដងហើយ។\nកំណត់ហេតុស្ដីពីការរាំងខ្ទប់ត្រូវបានផ្ដល់អោយដូចខាងក្រោម៖",
-       "blocklogentry": "បានហាមឃាត់ [[$1]]​ដោយរយៈពេលផុតកំណត់$2 $3",
+       "blocklog-showlog": "អ្នកប្រើប្រាស់នេះត្រូវបានហាមឃាត់មុននេះម្ដងហើយ។\nកំណត់ហេតុស្ដីពីការហាមឃាត់ត្រូវបានផ្ដល់អោយដូចខាងក្រោម៖",
+       "blocklogentry": "បានហាមឃាត់ [[$1]] ​ដោយរយៈពេលផុតកំណត់ $2 $3",
+       "reblock-logentry": "បានផ្លាស់ប្ដូរការកំណត់ការហាមឃាត់ [[$1]] ​ដោយរយៈពេលផុតកំណត់ $2 $3",
        "blocklogtext": "នេះជាកំណត់ហេតុនៃការហាមឃាត់និងឈប់ហាមឃាត់អ្នកប្រើប្រាស់។ អាសយដ្ឋានIPដែលត្រូវបានហាមឃាត់ដោយស្វ័យប្រវត្តិមិនត្រូវបានដាក់ក្នុងបញ្ជីនេះទេ។ សូមមើល[[Special:BlockList|បញ្ជីនៃការហាមឃាត់]]ចំពោះបញ្ជីនៃហាមឃាត់នាថ្មីៗ។",
        "unblocklogentry": "បានឈប់ហាមឃាត់ $1",
        "block-log-flags-anononly": "សម្រាប់​តែ​អ្នកប្រើប្រាស់​អនាមិក​ប៉ុណ្ណោះ",
        "markedaspatrollederror": "មិនអាចគូសចំណាំថាបានល្បាត",
        "patrol-log-page": "កំណត់ហេតុនៃការតាមដាន",
        "patrol-log-header": "នេះជាកំណត់ហេតុនៃកំណែ​ប្រែ​ដែល​បាន​តាមដាន",
-       "log-show-hide-patrol": "កំណត់ហេតុនៃការតាមដាន $1",
        "confirm-markpatrolled-button": "យល់ព្រម",
        "deletedrevision": "កំណែចាស់ដែលត្រូវបានលុបចេញ $1",
        "filedeleteerror-short": "កំហុសនៃការលុបឯកសារ៖ $1",
        "tag-filter": "[[Special:Tags|ស្លាក​]] តម្រង​:",
        "tag-filter-submit": "តម្រង",
        "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|ស្លាក|ស្លាក}}]]: $2)",
+       "tag-mw-undo": "មិនធ្វើវិញ",
        "tags-title": "ស្លាក​",
        "tags-intro": "ទំព័រ​រាយ​នាម​ស្លាក​ទាំង​ឡាយ​ដែល​កម្មវិធី​ software អាចកត់​សម្គាល់កំណែ​ជាមួយ​ និង​អត្ថ​ន័យ​របស់​វា។​",
        "tags-tag": "ឈ្មោះ​ស្លាក",
        "revdelete-uname-unhid": "អត្តនាមត្រូវបានបង្ហាញ",
        "revdelete-restricted": "បានអនុវត្តការដាក់កំហិតចំពោះអ្នកអភិបាល",
        "revdelete-unrestricted": "បានដកការដាក់កំហិតចេញសម្រាប់អ្នកអភិបាល",
+       "logentry-block-block": "$1 {{GENDER:$2|បាមហាមឃាត់}} {{GENDER:$4|$3}} រយៈពេល $5 $6",
        "logentry-move-move": "$1 {{GENDER:$2|បានប្ដូរទីតាំង}} ទំព័រ $3 ទៅ $4",
        "logentry-move-move-noredirect": "$1 {{GENDER:$2|បានប្ដូរទីតាំង}} ទំព័រ $3 ទៅ $4 ដោយមិនបន្សល់ទុកតំណភ្ជាប់បញ្ជូនបន្ត",
        "logentry-move-move_redir": "$1 {{GENDER:$2|បានប្ដូរទីតាំង}} ទំព័រ $3 ទៅ $4 តាមរយៈការបញ្ជូនបន្ត",
index 6017c32..4e3b594 100644 (file)
        "whatlinkshere": "ಇಲ್ಲಿಗೆ ಯಾವ ಸಂಪರ್ಕ ಕೂಡುತ್ತದೆ",
        "whatlinkshere-title": "\"$1\" ಪುಟಕ್ಕೆ ಸಂಪರ್ಕ ಹೊಂದಿರುವ ಪುಟಗಳು",
        "whatlinkshere-page": "ಪುಟ:",
-       "linkshere-2": "'''$1'''ಗೆ ಈ ಪುಟಗಳು ಸಂಪರ್ಕ ಹೊಂದಿವೆ:",
-       "nolinkshere-2": "'''$1''' ಗೆ ಯಾವ ಪುಟಗಳೂ ಸಂಪರ್ಕ ಹೊಂದಿಲ್ಲ.",
-       "nolinkshere-ns-2": "ಆಯ್ಕೆ ಮಾಡಿದ ಪುಟಪ್ರಬೇಧದಲ್ಲಿ ಯಾವ ಪುಟವೂ '''$1''' ಅಲ್ಲಿಗೆ ಸಂಪರ್ಕ ಹೊಂದಿಲ್ಲ.",
+       "linkshere": "'''$2'''ಗೆ ಈ ಪುಟಗಳು ಸಂಪರ್ಕ ಹೊಂದಿವೆ:",
+       "nolinkshere": "'''$2''' ಗೆ ಯಾವ ಪುಟಗಳೂ ಸಂಪರ್ಕ ಹೊಂದಿಲ್ಲ.",
+       "nolinkshere-ns": "ಆಯ್ಕೆ ಮಾಡಿದ ಪುಟಪ್ರಬೇಧದಲ್ಲಿ ಯಾವ ಪುಟವೂ '''$2''' ಅಲ್ಲಿಗೆ ಸಂಪರ್ಕ ಹೊಂದಿಲ್ಲ.",
        "isredirect": "ಪುನರ್ನಿರ್ದೇಶನ ಪುಟ",
        "istemplate": "ಸೇರ್ಪಡೆ",
        "isimage": "ಚಿತ್ರಕ್ಕೆ ಕೊಂಡಿ",
index aa1d5a5..9230c36 100644 (file)
@@ -70,7 +70,8 @@
                        "렌즈",
                        "CYAN",
                        "Nuevo Paso",
-                       "Doyoon1995"
+                       "Doyoon1995",
+                       "Jay94ks"
                ]
        },
        "tog-underline": "링크에 밑줄 긋기:",
        "customcssprotected": "여기에는 다른 사용자의 개인 설정이 포함되어 있기 때문에 이 CSS 문서를 편집할 수 없습니다.",
        "customjsonprotected": "다른 사용자의 개인 설정이 포함되어 있기 때문에 이 JSON 문서를 편집할 권한이 없습니다.",
        "customjsprotected": "여기에는 다른 사용자의 개인 설정이 포함되어 있기 때문에 이 자바스크립트 문서를 편집할 수 없습니다.",
+       "sitecssprotected": "모든 방문자에 영향을 미칠 수 있기 때문에 이 CSS를 편집할 권한이 없습니다",
+       "sitejsonprotected": "모든 방문자에게 영향을 미칠 수 있기 때문에 이 JSON 문서를 편집할 권한이 없습니다",
+       "sitejsprotected": "모든 방문자에게 영향을 미칠 수 있기 때문에 이 자바스크립트 문서의 편집 권한이 없습니다",
        "mycustomcssprotected": "이 CSS 문서를 편집할 권한이 없습니다.",
        "mycustomjsonprotected": "이 JSON 문서를 편집할 권한이 없습니다.",
        "mycustomjsprotected": "이 자바스크립트 문서를 편집할 권한이 없습니다.",
        "createaccountmail-help": "비밀번호를 기억하지 않고도 다른 사용자를 위한 계정을 만들 수 있습니다.",
        "createacct-realname": "실명 (선택 사항)",
        "createacct-reason": "이유",
-       "createacct-reason-ph": "왜 다른 계정을 만들어야 합니까",
+       "createacct-reason-ph": "ì\99\9c ë\8b¤ë¥¸ ê³\84ì \95ì\9d\84 ë\98\90 ë§\8cë\93¤ì\96´ì\95¼ í\95©ë\8b\88ê¹\8c",
        "createacct-reason-help": "계정 생성 로그에 표시되는 메시지",
        "createacct-submit": "계정 만들기",
        "createacct-another-submit": "계정 만들기",
        "resetpass-submit-loggedin": "비밀번호 바꾸기",
        "resetpass-submit-cancel": "취소",
        "resetpass-wrong-oldpass": "비밀번호가 잘못되었거나 현재의 비밀번호와 같습니다.\n이미 비밀번호를 바꾸었거나 새 임시 비밀번호를 요청했을 수 있습니다.",
-       "resetpass-recycled": "현재 비밀번호와 다른 비밀번호로 재설정해주세요.",
+       "resetpass-recycled": "현재 비밀번호와 다른 비밀번호로 변경해주세요.",
        "resetpass-temp-emailed": "임시 이메일 코드로 로그인되어 있습니다.\n로그인을 마치려면, 여기서 새 비밀번호를 설정해야 합니다:",
        "resetpass-temp-password": "임시 비밀번호:",
        "resetpass-abort-generic": "비밀번호 바꾸기가 확장 기능에 의해 중단되었습니다.",
        "resetpass-expired": "비밀번호가 만료되었습니다. 로그인하려면 새 비밀번호를 설정해야 합니다.",
-       "resetpass-expired-soft": "비밀번호가 만료되어 재설정해야 합니다. 지금 새로운 비밀번호를 선택하거나, \"{{int:authprovider-resetpass-skip-label}}\"를 클릭하고 나중에 재설정해주세요.",
-       "resetpass-validity-soft": "귀하의 비밀번호는 유효하지 않습니다: $1\n\n새로운 비밀번호를 지금 설정하거나, \"{{int:authprovider-resetpass-skip-label}}\"을 눌러 나중에 재설정하세요.",
+       "resetpass-expired-soft": "비밀번호가 만료되어 변경해야 합니다. 지금 새로운 비밀번호를 선택하거나, \"{{int:authprovider-resetpass-skip-label}}\"를 클릭하고 나중에 재설정해주세요.",
+       "resetpass-validity-soft": "귀하의 비밀번호는 유효하지 않습니다: $1\n\n새로운 비밀번호를 지금 설정하거나, \"{{int:authprovider-resetpass-skip-label}}\"을 눌러 나중에 변경하세요.",
        "passwordreset": "비밀번호 재설정",
        "passwordreset-text-one": "이메일을 통해 임시 비밀번호를 받으려면 이 양식을 채우세요.",
        "passwordreset-text-many": "{{PLURAL:$1|이메일을 통해 임시 비밀번호를 받으려면 필드 중 하나를 채우세요.}}",
        "subject-preview": "주제 미리 보기:",
        "previewerrortext": "변경사항을 미리보기하는 도중 오류가 발생했습니다.",
        "blockedtitle": "사용자가 차단됨",
-       "blockedtext": "'''사용자 계정 또는 IP 주소가 차단되었습니다.'''\n\n차단한 사람은 $1입니다.\n차단한 이유는 다음과 같습니다: $2\n\n* 차단이 시작된 시간: $8\n* 차단이 끝나는 시간: $6\n* 차단된 사용자: $7\n\n$1 또는 [[{{MediaWiki:Grouppage-sysop}}|다른 관리자]]에게 차단에 대해 문의할 수 있습니다.\n[[Special:Preferences|계정 환경 설정]]에 올바른 이메일 주소가 있어야만 '이메일 보내기' 기능을 사용할 수 있습니다. 또 이메일 보내기 기능이 차단되어 있으면 이메일을 보낼 수 없습니다.\n현재 당신의 IP 주소는 $3이고, 차단 ID는 #$5입니다.\n문의할 때에 이 정보를 같이 알려주세요.",
-       "autoblockedtext": "당신의 IP 주소는 $1님이 차단한 사용자가 사용했던 IP이기 때문에 자동으로 차단되었습니다.\n차단된 이유는 다음과 같습니다:\n\n:$2\n\n* 차단이 시작된 시간: $8\n* 차단이 끝나는 시간: $6\n* 차단된 사용자: $7\n\n$1 또는 [[{{MediaWiki:Grouppage-sysop}}|다른 관리자]]에게 차단에 대해 문의할 수 있습니다.\n\n[[Special:Preferences|사용자 환경 설정]]에 올바른 이메일 주소가 있어야만 \"이메일 보내기\" 기능을 사용할 수 있습니다. 또한 이메일 보내기 기능이 차단되어 있으면 이메일을 보낼 수 없습니다.\n\n현재 IP 주소는 $3이고, 차단 ID는 #$5입니다.\n문의할 때에 이 정보를 같이 알려주세요.",
+       "blockedtext": "'''사용자 계정 또는 IP 주소가 차단되었습니다.'''\n\n차단한 사람은 $1입니다.\n차단한 이유는 다음과 같습니다: <em>$2</em>.\n\n* 차단이 시작된 시간: $8\n* 차단이 끝나는 시간: $6\n* 차단된 사용자: $7\n\n$1 또는 [[{{MediaWiki:Grouppage-sysop}}|다른 관리자]]에게 차단에 대해 문의할 수 있습니다.\n[[Special:Preferences|계정 환경 설정]]에 올바른 이메일 주소가 있어야만 '이메일 보내기' 기능을 사용할 수 있습니다. 또 이메일 보내기 기능이 차단되어 있으면 이메일을 보낼 수 없습니다.\n현재 당신의 IP 주소는 $3이고, 차단 ID는 #$5입니다.\n문의할 때에 이 정보를 같이 알려주세요.",
+       "autoblockedtext": "당신의 IP 주소는 $1님이 차단한 사용자가 사용했던 IP이기 때문에 자동으로 차단되었습니다.\n차단된 이유는 다음과 같습니다:\n\n:<em>$2</em>\n\n* 차단이 시작된 시간: $8\n* 차단이 끝나는 시간: $6\n* 차단된 사용자: $7\n\n$1 또는 [[{{MediaWiki:Grouppage-sysop}}|다른 관리자]]에게 차단에 대해 문의할 수 있습니다.\n\n[[Special:Preferences|사용자 환경 설정]]에 올바른 이메일 주소가 있어야만 \"이메일 보내기\" 기능을 사용할 수 있습니다. 또한 이메일 보내기 기능이 차단되어 있으면 이메일을 보낼 수 없습니다.\n\n현재 IP 주소는 $3이고, 차단 ID는 #$5입니다.\n문의할 때에 이 정보를 같이 알려주세요.",
        "systemblockedtext": "당신의 사용자 이름 또는 IP 주소가 자동으로 미디어위키에 의해 차단되었습니다.\n이유는 다음과 같습니다:\n\n:<em>$2</em>\n\n* 차단 시작: $8\n* 차단 만료: $6\n* 차단 대상: $7\n\n당신의 현재 IP 주소는 $3입니다.\n문의에 대해 상기의 상세 설명을 모두 포함해 주십시오.",
        "blockednoreason": "이유를 입력하지 않음",
        "whitelistedittext": "문서를 편집하기 전에 $1해야 합니다.",
        "converter-manual-rule-error": "언어 변환 규칙을 수동으로 지정하는 도중 오류",
        "undo-success": "편집을 되돌릴 수 있습니다.\n이 편집을 되돌리려면 아래의 바뀐 내용을 확인한 후 저장해주세요.",
        "undo-failure": "중간의 다른 편집과 충돌하여 이 편집을 되돌릴 수 없습니다.",
+       "undo-main-slot-only": "메인 슬롯 이외의 내용을 수반하기 때문에 이 편집의 실행을 취소할 수 없습니다.",
        "undo-norev": "문서가 없거나 삭제되었기 때문에 편집을 되돌릴 수 없습니다.",
        "undo-nochange": "편집이 이미 되돌려진 것으로 나타납니다.",
        "undo-summary": "[[Special:Contributions/$2|$2]] ([[User talk:$2|토론]])의 $1판 편집을 되돌림",
        "diff-paragraph-moved-toold": "문단이 이동되었습니다. 오래된 위치로 이동하려면 클릭하십시오.",
        "difference-missing-revision": "문서 비교에서 {{PLURAL:$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": "문서 내용 일치",
        "group-autoconfirmed": "자동 인증된 사용자",
        "group-bot": "봇",
        "group-sysop": "관리자",
+       "group-interface-admin": "인터페이스 관리자",
        "group-bureaucrat": "사무관",
        "group-suppress": "기록보호자",
        "group-all": "(모두)",
        "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-editusercss": "다른 사용자의 CSS 문서를 편집",
        "right-edituserjson": "다른 사용자의 JSON 파일을 편집",
        "right-edituserjs": "다른 사용자의 자바스크립트 문서를 편집",
+       "right-editsitecss": "사이트 CSS 편집",
+       "right-editsitejson": "사이트 JSON 편집",
+       "right-editsitejs": "사이트 자바스크립트 편집",
        "right-editmyusercss": "자신의 사용자 CSS 파일 편집하기",
        "right-editmyuserjson": "자신의 사용자 JSON 파일 편집하기",
        "right-editmyuserjs": "자신의 사용자 자바스크립트 파일 편집하기",
        "grant-createaccount": "계정 만들기",
        "grant-createeditmovepage": "문서 만들기, 편집 및 이동",
        "grant-delete": "문서, 판 및 기록 항목 삭제",
-       "grant-editinterface": "미ë\94\94ì\96´ì\9c\84í\82¤ ì\9d´ë¦\84ê³µê°\84ê³¼ ì\82¬ì\9a©ì\9e\90 CSS/JSON/ì\9e\90ë°\94ì\8a¤í\81¬ë¦½í\8a¸ 편집",
+       "grant-editinterface": "미ë\94\94ì\96´ì\9c\84í\82¤ ì\9d´ë¦\84ê³µê°\84ê³¼ ì\82¬ì\9d´í\8a¸/ì\82¬ì\9a©ì\9e\90 JSON 편집",
        "grant-editmycssjs": "자신의 사용자 CSS/JSON/자바스크립트 편집하기",
        "grant-editmyoptions": "사용자 환경 설정 편집하기",
        "grant-editmywatchlist": "내 주시문서 목록 편집하기",
+       "grant-editsiteconfig": "사이트 및 사용자 CSS/JS 편집",
        "grant-editpage": "기존 문서 편집하기",
        "grant-editprotected": "보호된 문서 편집하기",
        "grant-highvolume": "대용량 편집",
        "recentchanges": "최근 바뀜",
        "recentchanges-legend": "최근 바뀜 설정",
        "recentchanges-summary": "이 페이지에서 위키의 최근 바뀜을 추적합니다.",
-       "recentchanges-noresult": "ì§\80ì \95í\95\9c ì¡°ê±´ê³¼ ì\9d¼ì¹\98í\95\98ë\8a\94 ì£¼ì\96´ì§\84 ê¸°ê°\84 ë\8f\99ì\95\88 바뀜이 없습니다.",
+       "recentchanges-noresult": "주ì\96´ì§\84 ê¸°ê°\84 ë\8f\99ì\95\88ì\97\90 ì\9d´ ì¡°ê±´ë\93¤ì\97\90 ë§\9eë\8a\94 바뀜이 없습니다.",
        "recentchanges-timeout": "이 검색의 시간이 초과되었습니다. 다른 검색 변수를 사용할 수 있습니다.",
        "recentchanges-network": "기술적인 문제로 결과를 불러올 수 없습니다. 페이지를 다시 새로 고침해 주십시오.",
        "recentchanges-notargetpage": "해당 문서에 관한 변경사항을 보려면 상단에 문서 제목을 입력하십시오.",
        "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": "{{PLURAL:$1|변경사항}} $1개, $2",
        "rcfilters-savedqueries-rename": "이름 바꾸기",
        "rcfilters-savedqueries-setdefault": "기본값으로 설정",
        "rcfilters-savedqueries-unsetdefault": "기본값으로 제거",
-       "rcfilters-savedqueries-remove": "ì \9cê±°",
+       "rcfilters-savedqueries-remove": "ì\82­ì \9c",
        "rcfilters-savedqueries-new-name-label": "이름",
        "rcfilters-savedqueries-new-name-placeholder": "필터의 목적을 설명하세요",
        "rcfilters-savedqueries-apply-label": "필터 만들기",
        "rcfilters-empty-filter": "활성화된 필터가 없습니다. 모든 기여가 표시됩니다.",
        "rcfilters-filterlist-title": "필터",
        "rcfilters-filterlist-whatsthis": "이것들이 어떻게 동작합니까?",
-       "rcfilters-filterlist-feedbacklink": "이 (새로운) 필터 도구에 대한 의견을 주세요",
+       "rcfilters-filterlist-feedbacklink": "이 필터 도구에 대한 의견을 주세요",
        "rcfilters-highlightbutton-title": "결과 강조",
        "rcfilters-highlightmenu-title": "색 선택",
        "rcfilters-highlightmenu-help": "이 속성을 강조할 색을 선택하십시오",
        "rcfilters-watchlist-showupdated": "변경이 발생한 이후로 방문한 적이 없는 문서의 변경사항은 <strong>굵게</strong> 표시됩니다.",
        "rcfilters-preference-label": "개선된 버전의 최근 바뀜 숨기기",
        "rcfilters-preference-help": "2017년 인터페이스 재설계 부분과 그 당시와 그 이후에 추가된 모든 도구를 되돌립니다.",
+       "rcfilters-watchlist-preference-label": "개선된 버전의 주시문서 목록 숨기기",
+       "rcfilters-watchlist-preference-help": "2017 인터페이스 재설계와 이후에 추가된 모든 도구를 되돌립니다.",
        "rcfilters-filter-showlinkedfrom-label": "다음 문서에서 링크한 문서의 변경사항 보기",
        "rcfilters-filter-showlinkedfrom-option-label": "<strong>선택된 문서에서 링크하는</strong> 문서들",
        "rcfilters-filter-showlinkedto-label": "다음 문서로 링크한 문서의 변경사항 보기",
        "uploadstash-bad-path-bad-format": "\"$1\" 키는 적절한 포맷이 아닙니다.",
        "uploadstash-file-not-found": "저장소에서 \"$1\" 키를 찾지 못했습니다.",
        "uploadstash-file-not-found-no-thumb": "섬네일을 가져오지 못했습니다.",
+       "uploadstash-file-not-found-no-local-path": "썸네일을 가르키는 로컬 경로가 없습니다.",
        "uploadstash-file-not-found-no-object": "섬네일을 위한 로컬 파일 객체를 만들 수 없습니다.",
        "uploadstash-file-not-found-no-remote-thumb": "섬네일 가져오기를 실패했습니다: $1\nURL = $2",
        "uploadstash-file-not-found-missing-content-type": "content-type 헤더가 없습니다.",
        "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": "URL에 접근할 수 없습니다.\nURL이 맞고 해당 웹사이트가 작동하는지 확인해주세요.",
        "upload-curl-error28": "올리기 시간 초과",
        "apisandbox-dynamic-parameters-add-label": "변수 추가:",
        "apisandbox-dynamic-parameters-add-placeholder": "변수 이름",
        "apisandbox-dynamic-error-exists": "\"$1\"이라는 변수 이름은 이미 존재합니다.",
+       "apisandbox-templated-parameter-reason": "이 [[Special:ApiHelp/main#main/templatedparams|템플릿 매개 변수]]는 $2의 {{PLURAL:$1|value|values}}에 따라 제공됩니다.",
        "apisandbox-deprecated-parameters": "앞으로 제거될 변수",
        "apisandbox-fetch-token": "토큰 자동 채우기",
        "apisandbox-add-multi": "추가",
        "speciallogtitlelabel": "대상 (문서 제목 또는 {{ns:user}}:사용자 이름으로 사용자 검색):",
        "log": "기록 목록",
        "logeventslist-submit": "보기",
+       "logeventslist-more-filters": "추가 기록 표시:",
+       "logeventslist-patrol-log": "점검 기록",
+       "logeventslist-tag-log": "태그 기록",
        "all-logs-page": "모든 공개 기록",
        "alllogstext": "{{SITENAME}}에서 사용할 수 있는 모든 기록이 표시됩니다.\n기록 종류나 사용자 이름(대소문자 구별) 또는 영향을 받는 문서(대소문자 구별)를 선택하여 범위를 좁혀서 살펴볼 수 있습니다.",
        "logempty": "일치하는 항목이 없습니다.",
        "dellogpage": "삭제 기록",
        "dellogpagetext": "아래의 목록은 최근에 삭제된 문서입니다.",
        "deletionlog": "삭제 기록",
+       "log-name-create": "문서 만들기 기록",
+       "log-description-create": "아래의 목록은 최근에 생성된 문서입니다.",
+       "logentry-create-create": "$1님이 $3 문서를 {{GENDER:$2|만들었습니다}}",
        "reverted": "이전 판으로 되돌렸습니다",
        "deletecomment": "이유:",
        "deleteotherreason": "다른 이유/추가적인 이유:",
        "uctop": "(최신)",
        "month": "월:",
        "year": "연도:",
+       "date": "날짜부터 (혹은 이전):",
        "sp-contributions-newbies": "새 사용자의 기여만 보기",
        "sp-contributions-newbies-sub": "새 사용자의 기여",
        "sp-contributions-newbies-title": "새 사용자의 기여",
        "whatlinkshere": "여기를 가리키는 문서",
        "whatlinkshere-title": "\"$1\" 문서를 가리키는 문서 목록",
        "whatlinkshere-page": "문서:",
-       "linkshere-2": "다음 문서가 '''$1''' 문서를 가리키고 있습니다:",
-       "nolinkshere-2": "'''$1''' 문서를 가리키는 문서가 없습니다.",
-       "nolinkshere-ns-2": "선택한 이름공간에는 '''$1''' 문서를 가리키는 문서가 없습니다.",
+       "linkshere": "다음 문서가 <strong>$2</strong> 문서를 가리키고 있습니다:",
+       "nolinkshere": "<strong>$2</strong> 문서를 가리키는 문서가 없습니다.",
+       "nolinkshere-ns": "선택한 이름공간에는 <strong>$2</strong> 문서를 가리키는 문서가 없습니다.",
        "isredirect": "넘겨주기 문서",
        "istemplate": "끼워넣기",
        "isimage": "연결된 파일",
        "markedaspatrollederrornotify": "점검한 것으로 표시를 실패했습니다.",
        "patrol-log-page": "점검 기록",
        "patrol-log-header": "문서 점검에 대한 기록입니다.",
-       "log-show-hide-patrol": "점검 기록을 $1",
-       "log-show-hide-tag": "태그 기록을 $1",
        "confirm-markpatrolled-button": "확인",
        "confirm-markpatrolled-top": "$2의 $3 판을 점검한 것으로 표시하시겠습니까?",
        "deletedrevision": "예전 $1 판이 삭제되었습니다.",
index 5cc99c4..89e4ac1 100644 (file)
        "whatlinkshere": "Бетге джибериуле",
        "whatlinkshere-title": "«$1» бетге джиберген бетле",
        "whatlinkshere-page": "Бет:",
-       "linkshere-2": "'''$1''' битге джиберген бетле:",
-       "nolinkshere-2": "'''$1'' бетге башха бетле джибермейдиле.",
-       "nolinkshere-ns-2": "Сайланнган атла аламда '''$1''' бетге джиберген бет джокъду.",
+       "linkshere": "'''$2''' битге джиберген бетле:",
+       "nolinkshere": "'''$2'' бетге башха бетле джибермейдиле.",
+       "nolinkshere-ns": "Сайланнган атла аламда '''$2''' бетге джиберген бет джокъду.",
        "isredirect": "джибериу бет",
        "istemplate": "къошуу",
        "isimage": "файлгъа джибериу",
        "markedaspatrollednotify": "«$1» бетдеги бу тюрлениу тинтиб къаралгъанча белгиленди.",
        "patrol-log-page": "Патруль этиуню журналы",
        "patrol-log-header": "Бу осмакъланнган версияланы журналыды.",
-       "log-show-hide-patrol": "Осмакълауну журналы $1",
        "deletedrevision": "$1 эски версия кетерилгенди.",
        "filedeleteerror-short": "Файл кетериуню халаты: $1",
        "filedeleteerror-long": "Файлны кетериуде халатлагъа тюбелди:\n\n$1",
index b00dfbe..f958d1f 100644 (file)
        "whatlinkshere": "Linkit tänne",
        "whatlinkshere-title": "Šivut, kumpaset viitatah šivulla \"$1\"",
        "whatlinkshere-page": "Šivu:",
-       "linkshere-2": "Šeuruavilta šivuilta on linkki šivulla <strong>$1</strong>:",
+       "linkshere": "Šeuruavilta šivuilta on linkki šivulla <strong>$2</strong>:",
        "isredirect": "ohjauššivu",
        "istemplate": "šisällytetty",
        "isimage": "failin linkki",
index 52ad3d1..d3f6dbd 100644 (file)
        "whatlinkshere": "Wat noh heh link",
        "whatlinkshere-title": "Sigge, woh Lengks op „$1“ dren sen",
        "whatlinkshere-page": "Sigg:",
-       "linkshere-2": "Dat sin de Sigge, di op <strong>„$1“</strong> lengke donn:",
-       "nolinkshere-2": "Kein Sigg link noh <strong>„$1“</strong>.",
-       "nolinkshere-ns-2": "Nix link op <strong>„$1“</strong> en dämm Appachtemang.",
+       "linkshere": "Dat sin de Sigge, di op <strong>„$2“</strong> lengke donn:",
+       "nolinkshere": "Kein Sigg link noh <strong>„$2“</strong>.",
+       "nolinkshere-ns": "Nix link op <strong>„$2“</strong> en dämm Appachtemang.",
        "isredirect": "Ömleidongssigg",
        "istemplate": "weed enjeföch",
        "isimage": "weed aanjezeisch",
        "markedaspatrollederrornotify": "Dat di Sigg nohjekik es, kunnte mer nit faßhalde.",
        "patrol-log-page": "Logbohch vun de nohjelohrte Änderonge",
        "patrol-log-header": "<!-- -->",
-       "log-show-hide-patrol": "$1 et Logbuch vum Sigge nohlooere",
-       "log-show-hide-tag": "Donn et Logbohch vun de Makkehronge $1",
        "deletedrevision": "De ahle Väsjohn „$1“ es fottjeschmeße",
        "filedeleteerror-short": "Fähler bem Dattei-Fottschmiiße: $1",
        "filedeleteerror-long": "Bem Fosooch, de Dattei fottzeschmihße, hatte mer Fähler:\n\n$1",
index 68ded3d..11abb52 100644 (file)
@@ -21,7 +21,8 @@
                        "Matma Rex",
                        "Stryn",
                        "Cûndûllah el-Kurdî",
-                       "Fitoschido"
+                       "Fitoschido",
+                       "Kur"
                ]
        },
        "tog-underline": "Xetekê di bin girêdanê de çêke:",
        "resetpass_forbidden": "Şîfre nikarin werin guhertin",
        "resetpass-submit-loggedin": "Şîfreyê biguherîne",
        "resetpass-submit-cancel": "Betal bike",
+       "resetpass-recycled": "Ji kerema xwe şîfreya xwe ya mewcûd biguherîne şîfreyeke din.",
        "resetpass-temp-password": "Şîfreya demkî:",
        "resetpass-expired": "Wextê şîfreya te derbas bû. Ji kerema xwe re\nji bo têketinê şîfreyek nû çêke.",
-       "resetpass-expired-soft": "Wextê şîfreya te derbas bû û hewceye ko be guhertin. Ji kerema xwe re şîfreyek nû çêke an jî ji bo paşî çêkî li \"{{int:authprovider-resetpass-skip-label}}\" bitikîne.",
-       "resetpass-validity-soft": "Şîfreya te derbasdar nîne: $1\n\nJi kerema xwe re şîfreyek nû çêke an jî ji bo paşî çêkî li \"{{int:authprovider-resetpass-skip-label}}\" bitikîne.",
+       "resetpass-expired-soft": "Mideta şîfreya te xelas bûye û divê bê guhertin. Ji kerema xwe re şîfreyeke nû çêbike an jî ji bo ku paşiyê biguherîne li \"{{int:authprovider-resetpass-skip-label}}\" bitikîne.",
+       "resetpass-validity-soft": "Şîfreya te ne derbasdar e: $1\n\nJi kerema xwe re şîfreyek nû çêke an jî ji bo paşiyê biguherîne li \"{{int:authprovider-resetpass-skip-label}}\" bitikîne.",
        "passwordreset": "Şîfreyê nû bike",
        "passwordreset-text-one": "Ji bo ji nû ve sazkirina şîfreyê vê formê dagire.",
        "passwordreset-username": "Navê bikarhêner:",
        "subject-preview": "Pêşdîtina mijarê:",
        "previewerrortext": "Wextê pêşdîtina guhertinên te, pirsgirekek derket.",
        "blockedtitle": "Bikarhêner hate astengkirin",
-       "blockedtext": "'''Navê te yê bikarhêneriyê an jî IP'ya te hate astengkirin.'''\n\nAstengkirin ji aliyê $1 ve pêkhat. Sedema astengkirina te ev e: ''$2''.\n\n* Destpêka astengkirinê: $8\n* Xelasbûna astengkirinê: $6\n* Astengkirin ji van re: $7\n\nTu dikarî bi $1  re an jî [[{{MediaWiki:Grouppage-sysop}}|koordînatorên]] din re ji bo astengkirinê bikevî têkiliyê. Tu nikarî 'Ji vê/vî bikarhênerê/î re e-name bişîne' bikarbînî heta  di [[Special:Preferences|tercihên xwe]] de navnîşana e-nameyeke derbasdar bikarbînî û tu ji bo bikaranîna vê fonksiyonê nehatî astengkirin.\n\nIP'ya te ya niha $3 ye, û ID'ya astengkirina te #$5 e. Ji kerema xwe yek ji van hejmaran têxe nav peyama xwe.",
+       "blockedtext": "'''Navê te yê bikarhêneriyê an jî IP'ya te hate astengkirin.'''\n\nAstengkirin ji aliyê $1 ve pêk hat. Sedema astengkirina te ev e: ''$2''.\n\n* Destpêka astengkirinê: $8\n* Xelasbûna astengkirinê: $6\n* Astengkirin ji van re: $7\n\nTu dikarî bi $1 re an jî bi [[{{MediaWiki:Grouppage-sysop}}|koordînatorên]] din re ji bo astengkirinê bikevî têkiliyê. Tu nikarî 'Ji vê/vî bikarhênerê/î re e-name bişîne' bikar bînî heta ku di [[Special:Preferences|tercihên xwe]] de navnîşana e-nameyeke derbasdar bi kar bînî û tu ji bo bikaranîna vê fonksiyonê nehatî astengkirin.\n\nIP'ya te ya niha $3 ye, û ID'ya astengkirina te #$5 e. Ji kerema xwe yek ji van hejmaran têxe nav peyama xwe.",
        "autoblockedtext": "Navnîşana IP ya te otomatîk hate astengkirin, ji ber ku bikarhênerekî/e din wê bikartîne, yê niha ji $1 hate astengkirin.\nSedema astengkirinê ev e:\n\n: ''$2''\n\n*Destpêka astengkirinê: $8\n*Dawiya astengkirinê: $6\n\nEger tu difikirî ku ev astengkirin ne sererast e, ji kerema xwe bi $1 re an jî yekî din ji [[{{MediaWiki:Grouppage-sysop}}|koordînatoran]] re bipeyive.\n\nZanibe ku tu nikarî e-nameya bişînî heta tu di [[Special:Preferences|tercihên xwe]] de navnîşana e-nameyan binivîsînî û tu ji bo bikaranîna vê nehatî astengkirin.\n\n'''Heke tu bixwazî peyamekê bişînî, ji kerema xwe van tiştan têxe nav nameya xwe:'''\n\n*Koordînator, yê te astengkir: $1\n*Sedema astengkirinê: $2\n*ID'ya astengkirinê: #$5",
        "blockednoreason": "sedem nehatiye gotin",
        "whitelistedittext": "Ji bo guherandina rûpelan, $1 pêwîst e.",
        "userpage-userdoesnotexist": "Hesabê bikarhêneran \"<nowiki>$1</nowiki>\" nehatiye qeydkirin. Heke tu bixwazî vê rûpelê çêkî/biguherînî ji kerema xwe lê binêre.",
        "userpage-userdoesnotexist-view": "Hesabê bikarhêner  \"$1\"  nehatiye qeyd kirin.",
        "blocked-notice-logextract": "Ev bikarhêner hatiye astengkirin.\nAstengkirina dawî bi referansa li jêr hatiye piştrastkirin:",
-       "clearyourcache": "<strong>Zanibe:</strong> Piştî qeydkirinê, ji bo dîtina guherandinan dibe ku paqijkirina cache'ê ya geroka te hewce bike.\n* <strong>Firefox / Safari:</strong> Gava ku <em>Shift<em> tikandîbe û pêl li <em>Reload<em> bike an jî <em>Ctrl-F5</em> an <em>Ctrl-R</em> bike (ji bo Mac: <em>⌘-R</em>)\n* <strong>Google Chrome:</strong> Bitikîne ser <em>Ctrl-Shift-R</em> (ji bo Mac: <em>⌘-Shift-R</em>)\n* <strong>Internet Explorer:</strong> Gava ku <em>Ctrl</em> tikandîbe, pêl li <em>Nûkirinê</em> bike, an jî <em>Ctrl-F5</em> bike\n* <strong>Opera:</strong> Divê ji ''Tools → Preferences'' daneyên geroka xwe bi temamî paqij bikî.",
+       "clearyourcache": "<strong>Zanibe:</strong> Piştî qeydkirinê, ji bo dîtina guherandinan dibe ku paqijkirina cache'ê ya geroka te hewce bike.\n* <strong>Firefox / Safari:</strong> Gava ku <em>Shift</em> tikandîbe û pêl li <em>Reload</em> bike an jî <em>Ctrl-F5</em> an <em>Ctrl-R</em> bike (ji bo Mac: <em>⌘-R</em>)\n* <strong>Google Chrome:</strong> Bitikîne ser <em>Ctrl-Shift-R</em> (ji bo Mac: <em>⌘-Shift-R</em>)\n* <strong>Internet Explorer:</strong> Gava ku <em>Ctrl</em> tikandîbe, pêl li <em>Nûkirinê</em> bike, an jî <em>Ctrl-F5</em> bike\n* <strong>Opera:</strong> Divê ji ''Tools → Preferences'' daneyên geroka xwe bi temamî paqij bikî.",
        "usercssyoucanpreview": "'''Tîp:''' 'Pêşdîtin' bikarwîne ji bo tu bibînê çawa CSS'ê te yê nuh e berî tomarkirinê.",
        "userjsyoucanpreview": "'''Tîp:''' 'Pêşdîtin' bikarwîne ji bo tu bibînê çawa JS'ê te yê nuh e berî tomarkirinê.",
        "usercsspreview": "'''Zanibe ku tu tenê pêşdîtina CSS dibînî.'''\n'''Ew hê nehatiye tomarkirin!'''",
        "right-move": "Rûpelan bigerîne",
        "right-upload": "Dosyeyan lê bar bike",
        "right-autoconfirmed": "Rûpelên nîv-parastî biguherîne",
+       "right-writeapi": "Bikaranîna write APIyê",
        "right-delete": "Rûpelan jê bibe",
        "right-bigdelete": "Rûpelên bi dîrokên pir dirêj jê bibe",
        "right-browsearchive": "Li rûpelên jêbirî bigerre",
        "recentchanges-submit": "Nîşan bide",
        "rcfilters-legend-heading": "<strong>Lîsteya kurtenavan:</strong>",
        "rcfilters-activefilters": "Parzûnên çalak",
+       "rcfilters-activefilters-hide": "Veşêre",
+       "rcfilters-activefilters-show": "Nîşan bide",
        "rcfilters-days-show-days": "{{PLURAL:$1|rojek|$1 roj}}",
        "rcfilters-days-show-hours": "{{PLURAL:$1|saetek|$1 saet}}",
        "rcfilters-quickfilters": "Parzûnên tomarkirî",
        "rcfilters-savedqueries-new-name-label": "Nav",
        "rcfilters-savedqueries-cancel-label": "Betal bike",
        "rcfilters-filterlist-title": "Parzûn",
+       "rcfilters-filterlist-feedbacklink": "Ji me re biêje ka tu li ser van alavên fîltrekirinê çi difikirî.",
        "rcfilters-filter-editsbyself-label": "Guhêrandinên ji aliyê te",
        "rcfilters-filter-editsbyother-label": "Guherandinên ji aliyên kesên din",
        "rcfilters-filter-bots-label": "Bot",
        "recentchangeslinked-feed": "Guherandinên peywend",
        "recentchangeslinked-toolbox": "Guherandinên peywend",
        "recentchangeslinked-title": "Guherandinên têkildarî \"$1\"",
-       "recentchangeslinked-summary": "Ji bo ku guherandinên di rûpelên ku ji vê rûpelê re lînk dane de an jî rûpelên ku ji vê rûpelê hatine lînkdayîn bibînî navê rûpelê binivîse. (Ji bo ku endamên vê kategoriyê bibînî, Category:'navê kategoriyê' binivîse). Rûpelên ku di [[Special:Watchlist|lîsteya te ya şopandinê]] de ne bi nivîsa <strong>stûr</strong> têne nîşandan.",
+       "recentchangeslinked-summary": "Ji bo ku guherandinên di rûpelên ku ji vê rûpelê re lînk dane de an jî rûpelên ku ji vê rûpelê hatine lînkdayîn bibînî navê rûpelê binivîse. (Ji bo ku endamên vê kategoriyê bibînî, {{ns:category}}:'navê kategoriyê' binivîse). Rûpelên ku di [[Special:Watchlist|lîsteya te ya şopandinê]] de ne bi nivîsa <strong>stûr</strong> têne nîşandan.",
        "recentchangeslinked-page": "Navê rûpelê:",
        "recentchanges-page-added-to-category": "[[:$1]] li kategoriyê hate zêdekirin",
        "recentchanges-page-removed-from-category": "[[:$1]] ji kategoriyê hate jêbirin",
        "filehist-datetime": "Dîrok/Katjimêr",
        "filehist-thumb": "Thumbnail",
        "filehist-thumbtext": "Versiyona biçûkkirî yê $1",
+       "filehist-nothumb": "Rismê biçûk tine",
        "filehist-user": "Bikarhêner",
        "filehist-dimensions": "Mezinahî",
        "filehist-filesize": "Mezinahiya pelê",
        "nolinkstoimage": "Rûpelekî ku ji vî wêneyî re girêdankê çêdike nîne.",
        "linkstoimage-redirect": "$1 (beralîkirina pelê) $2",
        "sharedupload-desc-here": "Ev dosye ji $1 û dibe ku ji aliyê projeyên din ve jî hatibe bikaranîn.\nAgahdariya li ser [$2 rûpela danasîna dosyeyê] li jêr tê nîşandan.",
+       "filepage-nofile": "Dosyeyekê bi vê navê tine ye.",
        "filepage-nofile-link": "Dosyeyek bi vî navî tune ye, lê tu dikarî wê [$1 bar bikî].",
        "uploadnewversion-linktext": "Versiyoneke nû ya vê daneyê barbike",
        "shared-repo-from": "ji $1",
        "whatlinkshere": "Girêdanên li ser vê rûpelê",
        "whatlinkshere-title": "Rûpelên ku yê berve \"$1\" tên",
        "whatlinkshere-page": "Rûpel:",
-       "linkshere-2": "Ev rûpel tên ser vê rûpelê '''$1''':",
-       "nolinkshere-2": "Ne ji rûpelekê lînk tên ser '''$1'''.",
-       "nolinkshere-ns-2": "Ne lînkek berve '''$1''' di vê namespace'a da tê.",
+       "linkshere": "Ev rûpel tên ser vê rûpelê '''$2''':",
+       "nolinkshere": "Girêdan bo <strong>$2</strong> nehat dîtin.",
+       "nolinkshere-ns": "Ne lînkek berve '''$2''' di vê namespace'a da tê.",
        "isredirect": "rûpelê beralî bike",
        "istemplate": "tê bikaranîn",
        "isimage": "girêdana wêneyî",
        "pageinfo-header-properties": "Taybetmendiyên rûpelê",
        "pageinfo-display-title": "Sernavê nîşan bide",
        "pageinfo-language": "Zimanê naveroka rûpelê",
+       "pageinfo-robot-noindex": "Destûr nehatiye dayîn",
        "pageinfo-watchers": "Hejmara şopînerên rûpelê",
        "pageinfo-redirects-name": "Hejmara beralîkirinên ber bi vê rûpelê ve",
        "pageinfo-subpages-name": "Binrûpelên vê rûpelê",
        "file-nohires": "Versyonekî jê mezintir tune.",
        "svg-long-desc": "Daneya SVG, mezinbûna rast: $1 × $2 pixel; mezinbûna daneyê: $3",
        "show-big-image": "Dosyeya orjînal",
+       "show-big-image-preview": "Mezinahiya vê pêşdîtinê: $1.",
+       "show-big-image-other": "{{PLURAL:$2|Resolusyona|Resolusyonên}} din: $1.",
        "show-big-image-size": "$1 × $2 pixel",
        "newimages": "Pêşangeha wêneyên nû",
        "imagelisttext": "Jêr lîsteyek ji $1 file'an heye, duxrekirin $2.",
        "watchlistedit-raw-titles": "Sernav:",
        "watchlistedit-raw-removed": "{{PLURAL:$1|1 gotar hate|$1 gotar hatin}} jêbirin:",
        "watchlistedit-clear-titles": "Sernav:",
+       "watchlisttools-clear": "Lîsteya şopandinê paqij bike",
+       "watchlisttools-view": "Guherandinên eleqedar bibîne",
        "watchlisttools-edit": "Lîsteya şopandinê bibîne û biguherîne",
+       "watchlisttools-raw": "Lîsteya şopandinê ya xam (netertîbkirî) biguherîne",
        "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|gotûbêj]])",
        "timezone-local": "Herêmî",
        "version": "Versiyon",
        "version-libraries-description": "Danasîn",
        "version-libraries-authors": "Xwedî",
        "redirect-submit": "Here",
+       "redirect-lookup": "Li vê bigere:",
        "redirect-user": "ID'ya Bikarhêner",
        "redirect-page": "ID'ya  Rûpelê",
+       "redirect-revision": "Revizyona rûpelê",
+       "redirect-file": "Navê dosyeyê",
        "fileduplicatesearch-filename": "Navê dosyeyê:",
        "fileduplicatesearch-submit": "Lê bigere",
        "specialpages": "Rûpelên taybet",
index 8188df5..4ec03ed 100644 (file)
@@ -68,6 +68,8 @@
        "october-date": "Байсан $1",
        "november-date": "Маййилик $1",
        "december-date": "Тунлу $1",
+       "period-am": "ТБ",
+       "period-pm": "ТС",
        "pagecategories": "{{PLURAL:$1|Категория|Категориялар}}‎",
        "category_header": "\"$1\" категориядан сагьифалар",
        "subcategories": "Субкатегориялар",
        "jumpto": "Мунда гёчмек:",
        "jumptonavigation": "навигация",
        "jumptosearch": "излев",
+       "pool-errorunknown": "Белгисиз янгылыш",
        "poolcounter-usage-error": "Къоллав хата: $1",
        "aboutsite": "{{SITENAME}} гьакъында",
        "aboutpage": "Project:Сыпатлав",
        "helppage-top-gethelp": "Кёмек",
        "mainpage": "Баш Сагьифа",
        "mainpage-description": "Баш сагьифа",
+       "policy-url": "Project:Къайдалар",
        "portal": "Бирлешив портал",
        "portal-url": "Project:Бирлешив портал",
        "privacy": "Энчилилик ёругъу",
        "privacypage": "Project:Конфиденциаллыкъ сиясаты",
+       "badaccess": "Гириш хатасы",
        "ok": "OK",
        "retrievedfrom": "Чыкъмагъы — «$1»",
        "youhavenewmessages": "{{PLURAL:$3|Сен алдынг}} $1 ($2).",
        "confirmable-confirm": "{{GENDER:$1|сен}} аминмисен?",
        "confirmable-yes": "Дюр",
        "confirmable-no": "Ёкъ",
+       "viewdeleted": "Къарамакъмы $1?",
        "feedlinks": "Агъыш",
+       "site-rss-feed": "$1 RSS агъым",
        "site-atom-feed": "$1 Atom агъышы",
+       "page-rss-feed": "\"$1\" RSS агъым",
        "page-atom-feed": "\"$1\" Atom агъышы",
        "red-link-title": "$1 (олай сагьифасы ёкъдур)",
+       "sort-descending": "Кемивюне гёре тизмек",
+       "sort-ascending": "Артывуна гёре тизмек",
        "nstab-main": "Макъала",
        "nstab-user": "Къоллавчу сагьифасы",
        "nstab-special": "Хас сагьифа",
        "nstab-help": "Кёмек сагьифа",
        "nstab-category": "Категория",
        "mainpage-nstab": "Баш сагьифа",
+       "nosuchaction": "Булай гьаракат ёкъ",
        "nosuchspecialpage": "Олай хас сагьифасы ёкъдур",
        "nospecialpagetext": "<strong>Сен талап этген хас сагьифа ёкъ.</strong>\n\nДурус хас сагьифалар булан тизме мунда: [[Special:SpecialPages|{{int:specialpages}}]].",
        "error": "Хата",
+       "databaseerror-query": "Талап: $1",
        "databaseerror-function": "Функция: $1",
        "databaseerror-error": "Хата: $1",
+       "missingarticle-rev": "(тюрю № $1)",
+       "missingarticle-diff": "(Башгъалыгъы: $1, $2)",
        "internalerror": "Ичдеги хата",
+       "internalerror_info": "Ичдеги хата: $1",
        "badtitle": "Къыйышмайгъан ат",
        "badtitletext": "Чакъырылгъан сагьифаны аты бузукъ эди, яда бош, яда тил-ара яда вики-ара байланывлары янгылыш кюйде берилген эди.\nБалики, атында бир-эки ярамайгъан гьарп берилген эди.",
        "viewsource": "Кюрчю кодуна къарамакъ",
        "viewsource-title": "$1 сагьифаны аслу текстине къарамакъ",
        "viewsourcetext": "Бу сагьифаны аслу кодуна къарап ва ону кёплеп боласан.",
+       "welcomeuser": "Хош гединг, $1!",
+       "yourname": "Къоллавчу аты",
        "userlogin-yourname": "Къоллавчу аты",
        "userlogin-yourname-ph": "Гьисабынгны атын бер",
+       "yourpassword": "Чечил:",
        "userlogin-yourpassword": "Чечил",
        "userlogin-yourpassword-ph": "Чечилингни бер",
        "createacct-yourpassword-ph": "Чечилингни бер",
        "createacct-yourpasswordagain-ph": "Чечилингни янгыдан бер",
        "userlogin-remembermypassword": "Мени къайытлы сакъламакъ",
        "login": "Гирмек",
+       "logout": "Чыкъмакъ",
+       "userlogout": "Чыкъмакъ",
        "userlogin-noaccount": "Бир бет ёкъму?",
        "userlogin-joinproject": "{{SITENAME}} проектни ортакъчы болмакъ",
        "createaccount": "Янгы бет этмек",
        "userlogin-resetpassword-link": "Чечилингни унутгъанмысан?",
        "userlogin-helplink2": "Гириш саялы кёмек",
+       "createacct-emailrequired": "Поч ерлешими",
        "createacct-emailoptional": "Электрон почну ерлешими (гёнгюллю)",
        "createacct-email-ph": "Электрон почну ерлешимин бер",
+       "createacct-another-email-ph": "Электрон почну ерлешимин бер",
+       "createacct-realname": "Герти ат (истесенг)",
+       "createacct-reason": "Себеп",
        "createacct-submit": "Бетинг яса",
+       "createacct-another-submit": "Гьисап бет ачмакъ",
        "createacct-benefit-heading": "{{SITENAME}} сени йимик адамланы ортакъ загьматы.",
        "createacct-benefit-body1": "{{PLURAL:$1|тюзлев}}",
        "createacct-benefit-body2": "{{PLURAL:$1|сагьифа|сагьифалар}}",
        "pt-login-button": "Гирмек",
        "pt-createaccount": "Янгы бет этмек",
        "pt-userlogout": "Чыкъмакъ",
+       "changepassword": "Чечил алышдырыв",
+       "oldpassword": "Эсги чечил:",
+       "newpassword": "Янгы чечил:",
+       "botpasswords-label-create": "Яратмакъ",
+       "botpasswords-label-update": "Янгыртмакъ",
+       "botpasswords-label-cancel": "Гери алыв",
+       "botpasswords-label-delete": "Тайдырмакъ",
+       "botpasswords-label-resetpassword": "Чечилни янгыдан бегетмек",
+       "resetpass-submit-loggedin": "Чечил алышдырыв",
+       "resetpass-submit-cancel": "Гери алыв",
        "passwordreset": "Чечилни янгыдан бегетмек",
+       "passwordreset-username": "Къоллавчу аты",
+       "changeemail-none": "(ёкъ)",
        "bold_sample": "Къалын матын",
        "bold_tip": "Къалын матын",
        "italic_sample": "Авункъу матын",
        "minoredit": "Увакъ тюзлев",
        "watchthis": "Бу сагьифаны гьызарламакъ",
        "savearticle": "Сагьифаны сакъламакъ",
+       "savearticle-start": "Сагьифаны сакъламакъ",
+       "savechanges-start": "Алышынывланы сакъламакъ",
        "preview": "Ингкъарав",
        "showpreview": "Ингкъарав",
        "showdiff": "Тюзлевлени гёрсетмек",
        "anoneditwarning": "<strong>Тергев:</strong> Сен гириш этмединг. Тюзлевлер этсенг сени IP адресинг публикли гёрюнер. Эгер <strong>[$1 гириш]</strong> яда <strong>[$2 къайыт]</strong> этсенг, тюзлевлеринг сени ортакъчы аты булан гьисап этилер, оьзге пайдалардан да къайры.",
-       "blockedtext": "Сени ÐºÑ\8aоллавÑ\87Ñ\83 Ð°Ñ\82Ñ\8bнг Ñ\8fда IP Ð°Ð´Ñ\80еÑ\81инг ÐºÑ\8aамалгÑ\8aан Ñ\8dди.''\n\nÐ\9aÑ\8aамав Ñ\8dÑ\82ген $1 ($2).\nСебеп Ð±ÐµÑ\80илген: ''$3'.\n\n* Ð\9aÑ\8aамав Ð±Ð°Ñ\88ладÑ\8b: $4\n* Ð\9aÑ\8aамав Ð±Ð¸Ñ\82е: $5\n* Ð\9aÑ\8aамавнÑ\83 Ð¼Ñ\83Ñ\80адÑ\8b: $7\n\n$1 Ð±Ñ\83лан Ñ\8fда ÐºÑ\8aайÑ\81Ñ\8b Ð¾Ñ\8cзге [[{{MediaWiki:Grouppage-sysop}}|админиÑ\81Ñ\82Ñ\80аÑ\82оÑ\80]] Ð±Ñ\83лан ÐºÑ\8aаÑ\82нап ÐºÑ\8aамавнÑ\83 Ð³Ñ\8cакÑ\8aÑ\8bнда Ñ\81Ñ\91йлеÑ\88меге Ð±Ð¾Ð»Ð°Ñ\81ан.\nТеÑ\80геп ÐºÑ\8aой, Ñ\81ени [[Special:Preferences|Ñ\8dнÑ\87или ÐºÑ\8eйлемлеÑ\80ингде]] e-mail Ð°Ð´Ñ\80еÑ\81инг Ñ\82Ñ\8eз Ð±ÐµÑ\80мединг Ð±Ñ\83Ñ\81а Ñ\8fда Ð³ÐµÑ\80Ñ\82и Ñ\8dÑ\82мединг Ð±Ñ\83Ñ\81а, Ñ\8fда ÐºÑ\8aамав Ñ\88аÑ\80Ñ\82лагÑ\8aа Ð¼Ð°ÐºÑ\82Ñ\83п Ñ\8fзÑ\8bвÑ\83нÑ\83 ÐºÑ\8aадагÑ\8aа Ð³Ð¸Ñ\80е Ð±Ñ\83Ñ\81а, \"кÑ\8aоллавÑ\87Ñ\83гÑ\8aа Ð¼Ð°ÐºÑ\82Ñ\83п\" Ñ\84Ñ\83нкÑ\86иÑ\8fнÑ\8b ÐºÑ\8aоллап Ð±Ð¾Ð»Ð¼Ð°Ñ\81Ñ\81ан.\nСени IP Ð°Ð´Ñ\80еÑ\81инг â\80\94 $3, ÐºÑ\8aамавнÑ\83 Ð¸Ð´ÐµÐ½Ñ\82иÑ\84икаÑ\82оÑ\80Ñ\83 â\80\94 $5. Ð¢Ð¸Ð»ÐµÐ², Ð±Ñ\83 Ð¼Ð°Ñ\8aлÑ\8eмаÑ\82ланÑ\8b Ð±Ð°Ñ\80Ñ\8b Ñ\82алаплаÑ\80Ñ\8bнга Ð³Ð¸Ð¹Ð¸Ñ\80.",
+       "blockedtext": "Къамав этген $1 ($2).\nСебеп берилген: ''$3'.\n\n* Къамав башлады: $4\n* Къамав бите: $5\n* Къамавну мурады: $7\n\n$1 булан яда къайсы оьзге [[{{MediaWiki:Grouppage-sysop}}|администратор]] булан къатнап къамавну гьакъында сёйлешмеге боласан.\nТергеп къой, сени [[Special:Preferences|энчили кюйлемлерингде]] e-mail адресинг тюз бермединг буса яда герти этмединг буса, яда къамав шартлагъа мактуп язывуну къадагъа гире буса, \"къоллавчугъа мактуп\" функцияны къоллап болмассан.\nСени IP адресинг — $3, къамавну идентификатору — $5. Тилев, бу маълюматланы бары талапларынга гийир.",
        "loginreqlink": "гирмек",
+       "newarticle": "(Янгы)",
        "newarticletext": "Сен гьалиде яратылмагъан сагьифагъа гёчдинг.\nБу сагьифаны яратмакъ учун, тюбюндеги къутугъунда язып башлагъыз (артыкъ маълюмат учун [$1 кёмек сагьифагъа] къара).\nЯнгылыш этип бери гёчген бусанг, сени браузеринг <strong>артгъа</strong> тюймесине бас.",
        "anontalkpagetext": "<em>Бу гьали де бет яратмагъан яда бетин къолламайгъан аноним къоллавчуну учун сёйлешив.</em>\nШолай буса биз ону белгилемек учун санавлу IP адресни пайдаламакъ герекбиз.\nБу IP адрес бир нече къоллавчуланы арасында пайланып турмагъа бола.\nСен аноним къоллавчу бусанг, ва сагъа тюгюл язывлар бакъдырылгъан деп ойлаша бусанг, тилев, [[Special:CreateAccount|янгы бет ярат]] яда [[Special:UserLogin|гириш эт]], гележекде оьзге аноним къоллавчулар булан сен къарашыкъ болмас учун.",
        "noarticletext": "Бу сагьифа гьали де матынсыз. Сен башгъа сагьифаларда [[Special:Search/{{PAGENAME}}|булай атын эсгеривлерини излемеге]]  боласан, <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} тийишли гюнделик язывланы тапмагъа] яда '''[{{fullurl:{{FULLPAGENAME}}|action=edit}} булай аты булан сагьифа яратмагъа боласан]'''</span>.",
        "noarticletext-nopermission": "Бу сагьифа гьали де текстсиз. Сен башгъа сагьифаларда [[Special:Search/{{PAGENAME}}|булай атын эсгеривлерини излемеге]], яда <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} тийишли гюнделиклени тапмагъа боласан]. </span> Тек бу сагьифаны яратмагъа ихтиярынг ёкъ.",
        "userpage-userdoesnotexist-view": "\"$1\" гьисап къайытланмагъан.",
        "clearyourcache": "<strong>Note:</strong> Сакълангъан сонг, тюрлевлени гёрмек саялы сагъа браузерингни кэшин янгыртмагъа яда тазаламагъа герек болма бола \n* <strong>Firefox / Safari:</strong> <em>Shift</em> тутуп <em>Reload</em> бас, башгъалай <em>Ctrl-F5</em> яда <em>Ctrl-R</em> бас (Mac буса <em>⌘-R</em>)\n* <strong>Google Chrome:</strong> <em>Ctrl-Shift-R</em> бас(Mac буса <em>⌘-Shift-R</em>)\n* <strong>Internet Explorer:</strong> <em>Ctrl</em> тутуп <em>Refresh</em> бас, яда <em>Ctrl-F5</em> бас\n* <strong>Opera:</strong> <em>Menu → Settings</em> бёлмеге гёч (Mac буса <em>Opera → Preferences</em>) ва сонг <em>Privacy & security → Clear browsing data → Cached images and files</em>.",
+       "updated": "(Янгыртылгъан)",
        "previewnote": "<strong>Бу ингкъарав экенни эсде сакъла.</strong>\nАлышынывларынг гьали де сакъланмагъан!",
        "continue-editing": "Тюзлевню давамламакъ",
        "editing": "Тюзлев $1",
        "creating": "$1 сагьифасын ясаву",
        "editingsection": "Тюзлев: $1 (бёлме)",
+       "yourtext": "Текстинг",
+       "yourdiff": "Башгъалыкълар",
        "templatesused": "Бу сагьифада къоллангъан {{PLURAL:$1|къалип|къалиплер}}",
        "templatesusedpreview": "Бу инггёрсетивде пайдалангъан {{PLURAL:$1|уьлгюлер|}}:",
        "template-protected": "(къоругъан)",
        "recreate-moveddeleted-warn": "<strong>Тергев бер: Алдын тайдырылгъан сагьифаны ярашдырма айланасан.</strong>\n\nБашлап тергеп къара, гертиден де тарыкъмы экен ол сагьифаны ярашдырмагъа.\nТайдырыв ва атын алышдырыв гюнделиги тюпде берилген:",
        "moveddeleted-notice": "Бу сагьифа тайдырылгъан эди.\nБу сагьифаны тайдырыв, къорув ва атянгыртыв гюнделиги маълюмат саялы тюпде гёрсетилген.",
        "content-model-wikitext": "викиматын",
+       "content-model-javascript": "JavaScript",
        "undo-failure": "Аралыкъ алышынывланы къыйышывсызлгъы учун тюзлев гери алынмай.",
        "viewpagelogs": "Бу сагьифа учун гюнделиклени гёрсетмек",
        "currentrev-asof": "Ахырынчы тюрю $1 тархда",
        "nextrevision": "Сонггъу тюрю →",
        "currentrevisionlink": "Ахырынчы тюрю",
        "cur": "гьал.",
+       "next": "гелеген",
        "last": "ингкъ.",
+       "page_first": "биринчи",
+       "page_last": "ахырынчы",
        "histlegend": "Тюзлевлерден сайлав: тенглешдирмеге сюеген бары тюрлерин белгилеп '''{{int:compare-submit}}''' бас.<br />\nАчыкълавлар: '''({{int:cur}})''' — гьалиги тюрюнден башгъалыкъ; '''({{int:last}})''' — алдагъы тюрюнден башгъалыкъ; '''{{int:minoreditletter}}''' — увакъ тюзелтив.",
        "history-fieldset-title": "Тюзлевлеге излев",
        "histfirst": "инг эсгилер",
        "histlast": "инг янгылар",
+       "historyempty": "(бош)",
        "history-feed-title": "Тюзлевлер тарихи",
        "history-feed-description": "Бу сагьифаны викиде тюзлев тарихи",
        "history-feed-item-nocomment": "$1 $2 заманда",
        "rev-delundel": "гёрсетмек/яшырмакъ",
+       "rev-showdeleted": "гёрсетмек",
+       "revdelete-show-file-submit": "Дюр",
+       "revdelete-radio-same": "(алышдырмамакъ)",
+       "revdelete-radio-set": "Яшырылгъан",
+       "revdelete-log": "Себеп:",
+       "pagehist": "Сагьифа тарихи",
+       "deletedhist": "Тайдырыв тарихи",
+       "revdelete-reasonotherlist": "Башгъа себеп",
+       "mergehistory-reason": "Себеп:",
        "mergelog": "Бирлешдирив гюнделиги",
+       "revertmerge": "Бёлмек",
        "history-title": "\"$1\" тюзлев тарихи",
        "difference-title": "Тюрлени арасында башгъалыгъы \"$1\"",
        "lineno": "Сатыр: $1",
        "searchresults-title": "\"$1\" учун натижаланы излемек",
        "prevn": "алдагъы {{PLURAL:$1|$1}}",
        "nextn": "сонггъу {{PLURAL:$1|$1}}",
+       "prev-page": "алдагъы сагьифа",
+       "next-page": "гелеген сагьифа",
        "prevn-title": "Алдагъы $1 {{PLURAL:$1|гьасил}}",
        "nextn-title": "Гелеген $1 {{PLURAL:$1|гьасил|гьасиллер}}",
        "shown-title": "Айры бир сагьифада $1 {{PLURAL:$1|языв|язывланы}} гёрсетмек",
        "search-result-category-size": "{{PLURAL:$1|1 ортакъчы|$1 ортакъчы}} ({{PLURAL:$2|1 тюп категория|$2 тюп категория}}, {{PLURAL:$3|1 саплам|$3 саплам}})",
        "search-redirect": "($1 сагьифадан бакъдырылгъан)‎",
        "search-section": "($1 бёлме)",
+       "search-category": "(категория $1)",
        "search-file-match": "(сапламны ичделигине рас геле)",
        "search-suggest": "Буну ойлаймысан экен: $1",
+       "search-interwiki-more": "(дагъы)",
+       "search-interwiki-more-results": "дагъы да натижалар",
+       "search-relatedarticle": "Байлавлу",
+       "searchrelated": "байлавлу",
        "searchall": "бары да",
        "search-showingresults": "{{PLURAL:$4|<strong>$1</strong> натижа <strong>$3</strong> натижалардан|<strong>$1 – $2</strong> натижа <strong>$3</strong> натижалардан}}",
        "search-nonefound": "Бу талапгъа тийишли натижалар табулмады.",
+       "powersearch-legend": "Генглешген излев",
+       "powersearch-toggleall": "Тюм",
+       "powersearch-togglenone": "Ёкъ",
        "mypreferences": "Кюйлемлер",
+       "skin-preview": "Ингкъарав",
+       "prefs-user-pages": "Къоллавчу сагьифасы",
+       "prefs-watchlist": "Гьызарлав тизмеси",
+       "saveprefs": "Сакъламакъ",
+       "prefs-editing": "Тюзлев",
+       "searchresultshead": "Излев",
+       "stub-threshold-sample-link": "уьлгю",
+       "stub-threshold-disabled": "Сёнген",
+       "timezoneregion-asia": "Азия",
+       "timezoneregion-europe": "Авропа",
+       "prefs-searchoptions": "Излев",
+       "prefs-namespaces": "Атлар аралыгъы",
+       "prefs-files": "Сапламлар",
+       "youremail": "Эмейл:",
+       "group-membership-link-with-expiry": "$1 ($2 ерли)",
+       "yourrealname": "Герти аты:",
+       "yourlanguage": "Тил:",
+       "yournick": "Янгы къолбас",
+       "email": "Эмейл",
+       "prefs-signature": "Къолбас",
+       "prefs-preview": "Ингкъарав",
+       "editusergroup": "Ортакъчына гюплерин юклемек",
+       "group": "Гюп:",
+       "group-user": "Къоллавчулар",
        "group-bot": "Ботлар",
        "group-sysop": "Юрютювчилер",
+       "group-all": "(тюм)",
+       "grouppage-user": "{{ns:project}}:Къоллавчулар",
        "grouppage-bot": "{{ns:project}}:Ботлар",
        "grouppage-sysop": "{{ns:project}}:Башчылар",
+       "right-read": "Сагьифа охув",
+       "right-edit": "Сагьифа тюзлев",
        "right-writeapi": "Языв учун API‎ къоллав",
+       "right-delete": "Сагьифа тайдырыв",
        "newuserlogpage": "Янгы къоллавчу тизме гюнделиги",
        "rightslog": "Ортакъчы ихтиярларын гюнделиги",
+       "action-read": "бу сагьифаны охув",
        "action-edit": "бу сагьифаны тюзлемек",
+       "action-createpage": "бу сагьифаны яратмакъ",
        "action-createaccount": "бу гьисапны яратыву",
        "enhancedrc-history": "тарих",
        "recentchanges": "Яп-янгы тюзлевлер",
        "recentchanges-label-plusminus": "Сагьифаны гёлеми шунчакъы байт булан алышынгъан",
        "recentchanges-legend-heading": "<strong>Уйдурма:</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (шунда да  [[Special:NewPages|янгы сагьифаланы сиягьына къарагъыз]])",
+       "recentchanges-submit": "Гёрсетмек",
+       "rcfilters-savedqueries-rename": "Атын алышдырмакъ",
+       "rcfilters-savedqueries-remove": "Тайдырмакъ",
+       "rcfilters-savedqueries-new-name-label": "Ат",
+       "rcfilters-savedqueries-cancel-label": "Гери алыв",
+       "rcfilters-filterlist-title": "Сюзгючлер",
+       "rcfilters-highlightmenu-title": "Тюсюн сайламакъ",
+       "rcfilters-filter-user-experience-level-learner-label": "Охуйгъанлар",
+       "rcfilters-filter-bots-label": "Бот",
        "rcnotefrom": "Тюбюндеги — <strong>$3, $4</strong> гюнден берли {{PLURAL:$5|тюзлевюдюр|тюзлевлеридир}}.",
        "rclistfrom": "$2, $3 тюзлевлерден башлап гёрсетмек",
        "rcshowhideminor": "$1 увакъ тюзлевлер",
        "rcshowhideanons-show": "Гёрсетмек",
        "rcshowhideanons-hide": "Яшырмакъ",
        "rcshowhidepatr": "$1 тергелген тюзлевлер",
+       "rcshowhidepatr-show": "Гёрсетмек",
+       "rcshowhidepatr-hide": "Яшырмакъ",
        "rcshowhidemine": "$1 мени тюзлевлерим",
        "rcshowhidemine-show": "Гёрсетмек",
        "rcshowhidemine-hide": "Яшырмакъ",
+       "rcshowhidecategorization-show": "Гёрсетмек",
+       "rcshowhidecategorization-hide": "Яшырмакъ",
        "rclinks": "Ахырынчы $2 гюнню ичинде ахырынчы $1 тюзлевню гёрсетмек",
        "diff": "алыш.",
        "hist": "тарих",
        "recentchangeslinked-feed": "Байлавлу тюзлевлер",
        "recentchangeslinked-toolbox": "Байлавлу тюзлевлер",
        "recentchangeslinked-title": "\"$1\" сагьифагъа байлавлу тюзлевлер",
-       "recentchangeslinked-summary": "Ð\91Ñ\83 Ñ\81агÑ\8cиÑ\84агÑ\8aа Ð±Ð°Ð¹Ð»Ð°Ð²Ð»Ñ\83 Ñ\82Ñ\8eзлевлеÑ\80и Ð±Ñ\83лан Ñ\81агÑ\8cиÑ\84аланÑ\8b, Ñ\8fда Ð¾ Ñ\81агÑ\8cиÑ\84адан Ð±Ð°Ð¹Ð»Ð°Ð²Ð»Ñ\83ланÑ\8b Ð³Ñ\91Ñ\80мек Ñ\83Ñ\87Ñ\83н атын яз. (Категорияны ортакъчаларын гёрмек учун Category:Категорияны атын яз). Сени [[Special:Watchlist|Гьызарлав тизменгдеги]] алышынывлар <strong>къалын</strong> гьарплылар.",
+       "recentchangeslinked-summary": "СагÑ\8cиÑ\84агÑ\8aа Ñ\8fда Ñ\81агÑ\8cиÑ\84адан Ð±Ð°Ð¹Ð»Ð°Ð²Ð»Ñ\83 Ñ\81агÑ\8cиÑ\84алаÑ\80да Ñ\82Ñ\8eзлевлеÑ\80ин Ð³Ñ\91Ñ\80мек Ñ\83Ñ\87Ñ\83н Ð¾Ð½Ñ\83 атын яз. (Категорияны ортакъчаларын гёрмек учун Category:Категорияны атын яз). Сени [[Special:Watchlist|Гьызарлав тизменгдеги]] алышынывлар <strong>къалын</strong> гьарплылар.",
        "recentchangeslinked-page": "Сагьифаны аты:",
        "recentchangeslinked-to": "Къайта, бу сагьифагъа байлавлу сагьифаланы алышынывларын гёрсетмек",
        "upload": "Сапламны юклемек",
+       "uploadbtn": "Сапламны юклемек",
        "uploadlogpage": "Юклев журналы",
+       "filename": "Сапламны аты",
        "filedesc": "Къысгъартылым",
+       "fileuploadsummary": "Къысгъартылым:",
+       "filesource": "Эник:",
+       "upload-dialog-button-cancel": "Гери алыв",
+       "upload-dialog-button-back": "Артгъа",
+       "upload-dialog-button-done": "Гьазир",
+       "upload-dialog-button-save": "Сакъламакъ",
+       "upload-dialog-button-upload": "Юклемек",
+       "upload-form-label-infoform-title": "Толу",
+       "upload-form-label-infoform-name": "Ат",
+       "upload-form-label-infoform-description": "Тасвир",
+       "upload-form-label-usage-title": "Къоллав",
+       "upload-form-label-usage-filename": "Сапламны аты",
+       "upload-form-label-infoform-date": "Тарх",
        "license": "Лицензиялав:",
        "license-header": "Лицензиялав",
+       "listfiles-delete": "тайдырмакъ",
        "imgfile": "саплам",
        "listfiles": "Саплам тизмеси",
+       "listfiles_thumb": "Гиччисурат",
+       "listfiles_date": "Тарх",
+       "listfiles_name": "Ат",
+       "listfiles_user": "Къоллавчу",
+       "listfiles_size": "Гёлем",
+       "listfiles_description": "Тасвир",
+       "listfiles_count": "Тюрлер",
+       "listfiles-latestversion": "Гьалиги тюрю",
+       "listfiles-latestversion-yes": "Дюр",
+       "listfiles-latestversion-no": "Ёкъ",
        "file-anchor-link": "Саплам",
        "filehist": "Саплам тарихи",
        "filehist-help": "Тарх/замангъа бассанг саплам о вакътиде нечик болгъанны гёрежексен",
+       "filehist-deleteall": "Тюмюн тайдырмакъ",
+       "filehist-deleteone": "тайдырмакъ",
        "filehist-revert": "къайтармакъ",
        "filehist-current": "гьалиги",
        "filehist-datetime": "Тарх/Заман",
        "filehist-nothumb": "миниатюрю ёкъ",
        "filehist-user": "Къоллавчу",
        "filehist-dimensions": "Оьлчевлери",
+       "filehist-filesize": "Саплам гёлеми",
        "filehist-comment": "Ёрум",
        "imagelinks": "Сапламны къоллаву",
        "linkstoimage": "Шундан сонггъу {{PLURAL:$1|сагьифа|$1 сагьифалар}} бу сапламгъа байлангъан:",
        "sharedupload-desc-here": "Бу саплам $1 проектдендир, ва башгъасында да къолланма бола. Ону [$2 тасвир сагьифасындан] маълюматы тюпде бериле.‎",
        "filepage-nofile": "Булай аты булан саплам ёкъдур.",
        "upload-disallowed-here": "Бу сапламны уьстюнде язмакъ болмайсан.",
+       "filerevert-comment": "Себеп:",
+       "filerevert-submit": "Къайтармакъ",
+       "filedelete": "$1 тайдырмакъ",
+       "filedelete-legend": "Сапламны тайдырмакъ",
+       "filedelete-comment": "Себеп:",
+       "filedelete-submit": "Тайдырмакъ",
+       "filedelete-reason-otherlist": "Башгъа себеп",
+       "mimesearch": "MIME излев",
+       "download": "эндирмек",
+       "unusedtemplateswlh": "башгъа байланывлар",
        "randompage": "Хапарсыз сагьифа",
+       "randomincategory-category": "Категория:",
+       "randomincategory-submit": "Гёчмек",
        "statistics": "Истатистик",
+       "statistics-pages": "Сагьифа",
+       "pageswithprop-submit": "Тапмакъ",
        "double-redirect-fixer": "Ёллав дуруславу",
+       "brokenredirects-edit": "тюзлемек",
+       "brokenredirects-delete": "тайдырмакъ",
+       "withoutinterwiki-submit": "Гёрсетмек",
        "nbytes": "$1 {{PLURAL:$1|байт|байтлар}}‎",
        "nmembers": "$1 {{PLURAL:$1|ортакъчы}}",
        "prefixindex": "Префикс булан бары да сагьифалар",
        "sp-contributions-toponly": "Янгыз ахырынчы тюрню тюзлевлерин гёрсетмек",
        "sp-contributions-newonly": "Янгыз сагьифа яратыв деген тюзлевлени гёрсетмек",
        "sp-contributions-submit": "Излев",
-       "whatlinkshere": "Ð\9cÑ\83нда байланылгъан",
+       "whatlinkshere": "Ð\91еÑ\80и байланылгъан",
        "whatlinkshere-title": "\"$1\" бетге байлангъан сагьифалар",
        "whatlinkshere-page": "Сагьифа:",
-       "linkshere-2": "Гелеген сагьифалар бугъар байлавлу <strong>$1</strong>:",
-       "nolinkshere-2": "Бугъар байлавлу сагьифалар ёкъ <strong>$1</strong>:",
+       "linkshere": "Гелеген сагьифалар бугъар байлавлу <strong>$2</strong>:",
+       "nolinkshere": "Бугъар байлавлу сагьифалар ёкъ <strong>$2</strong>:",
        "isredirect": "ёллав-сагьифа",
        "istemplate": "къошув",
        "isimage": "сапламлы байланыв",
index b767225..89b7548 100644 (file)
        "viewhelppage": "Gweles an folen weres",
        "categorypage": "Gweles folen an klass",
        "viewtalkpage": "Gweles an dadhlow",
-       "otherlanguages": "Yn yethow erel",
-       "redirectedfrom": "(Daskedyes dhyworth $1)",
+       "otherlanguages": "Yn tavosow erel",
+       "redirectedfrom": "(Daskevarwodhys dhyworth $1)",
        "redirectpagesub": "Folen dhaskedya",
-       "lastmodifiedat": "Gwrys veu diwettha chanj an folen ma an $1, dhe $2.",
+       "redirectto": "Daskidya dhe:",
+       "lastmodifiedat": "Diwettha chanj an folen ma a veu an $1, dhe $2.",
        "protectedpage": "Folen dhifresys",
        "jumpto": "Lamma dhe:",
        "jumptonavigation": "kevrennow lewya",
        "pool-errorunknown": "Gwall ankoth",
        "aboutsite": "A-dro dhe {{SITENAME}}",
        "aboutpage": "Project:Kedhlow",
-       "copyright": "Kavadow yw an dalgh yn-dann $1.",
+       "copyright": "Kavadow yw an dalgh yn-dann $1, marnas avisyes yn ken maner.",
        "copyrightpage": "{{ns:project}}:Gwirbryntyansow",
        "currentevents": "Hwarvosow a-lemmyn",
        "currentevents-url": "Project:Hwarvosow a-lemmyn",
        "disclaimers": "Avisyansow",
        "disclaimerpage": "Project:Avisyans ollgemmyn",
        "edithelp": "Gweres ow chanjya",
-       "mainpage": "Dynnargh",
-       "mainpage-description": "Dynnargh",
+       "mainpage": "Folen dre",
+       "mainpage-description": "Folen dre",
        "policy-url": "Project:Polici",
        "portal": "Porth an gemeneth",
        "portal-url": "Project:Porth an gemeneth",
        "youhavenewmessages": "$1 a'gas beus ($2).",
        "youhavenewmessagesfromusers": "Hwi a'gas beus $1 dhyworth {{PLURAL:$3|devnydhyer aral|$3 devnydhyer}} ($2).",
        "youhavenewmessagesmanyusers": "Hwi a'gas beus $1 dhyworth lies devnydhyer ($2).",
-       "newmessageslinkplural": "{{PLURAL:$1|messach nowyth|messajys nowyth}}",
-       "newmessagesdifflinkplural": "{{PLURAL:$1|chanj|chanjyow}} diwettha",
+       "newmessageslinkplural": "{{PLURAL:$1|messach nowydh|999=messajys nowydh}}",
+       "newmessagesdifflinkplural": "an {{PLURAL:$1|chanj|999=chanjyow}} diwettha",
        "youhavenewmessagesmulti": "Messajys nowyth a'gas beus war $1",
        "editsection": "chanjya",
        "editold": "chanjya",
        "toc": "Rol an folen",
        "showtoc": "diskwedhes",
        "hidetoc": "kudha",
+       "collapsible-collapse": "Diskara",
        "collapsible-expand": "Efani",
        "thisisdeleted": "Gweles po daskor $1?",
        "viewdeleted": "Gweles $1?",
        "site-atom-feed": "Feed Atom $1",
        "page-rss-feed": "Feed RSS \"$1\"",
        "page-atom-feed": "Feed Atom \"$1\"",
-       "red-link-title": "$1 (nyns eus folen henwys yndelma)",
+       "red-link-title": "$1 (nyns eus an folen ma)",
        "nstab-main": "Folen",
        "nstab-user": "Folen dhevnydhyer",
        "nstab-media": "Folen media",
        "nstab-template": "Skantlyn",
        "nstab-help": "Gweres",
        "nstab-category": "Klass",
+       "mainpage-nstab": "Folen dre",
        "error": "Gwall",
        "databaseerror": "Gwall database",
        "readonly": "Alhwedhys yw an database",
        "filenotfound": "Ny allas kavos an restren \"$1\".",
        "cannotdelete-title": "Ny yllir dilea an folen \"$1\"",
        "badtitle": "Titel drog",
+       "badtitletext": "Drog po gwag o an folen wovynnys, po titel kammkevrennys kesyeth po keswiki o.\nMartesen yma unn lytheren po moy ynno na yllir usya yn titlys.",
        "viewsource": "Gweles an bennfenten",
        "viewsource-title": "Gweles an bennfenten rag $1",
-       "protectedpagetext": "Difresys re beu an folen-ma rag gwitha rag chanjya po gwriansow erel.",
-       "viewsourcetext": "Hwi a yll gweles ha kopia pennfenten an folen-ma:",
+       "protectedpagetext": "Difresys yw an folen ma dhe witha rag chanjya po gwriansow erel.",
+       "viewsourcetext": "Hwi a yll gweles ha kopia pennfenten an folen ma.",
        "mycustomcssprotected": "Ny'gas beus kummyes dhe janjya an folen CSS-ma.",
        "mycustomjsprotected": "Ny'gas beus kummyes dhe janjya an folen JavaScript-ma.",
        "ns-specialprotected": "Ny yllir chanjya folennow arbennek.",
        "password-change-forbidden": "Ny yllir chanjya geryow tremena war an wiki-ma.",
        "login": "Omgelmi",
        "nav-login-createaccount": "Omgelmi / Gwruthyl akont nowyth",
-       "logout": "Digelmi",
-       "userlogout": "Digelmi",
+       "logout": "Omdenna",
+       "userlogout": "Omdenna",
        "notloggedin": "Digelmys",
        "userlogin-noaccount": "A nyns eus akont dhywgh?",
        "userlogin-joinproject": "Junya {{SITENAME}}",
        "pt-login": "Omgelmi",
        "pt-login-button": "Omgelmi",
        "pt-createaccount": "Gwruthyl akont",
-       "pt-userlogout": "Digelmi",
+       "pt-userlogout": "Omdenna",
        "changepassword": "Chanjya an ger-tremena",
        "resetpass_announce": "Hwi a omgelmis dre goden ebostyes anbarthus.\nRag gorfenna omgelmi, res yw dhywgh settya ger tremena nowyth omma:",
        "resetpass_header": "Chanjya ger tremena an akont",
        "image_tip": "Restren neythys",
        "media_tip": "Kevren restren",
        "sig_tip": "Agas sinans ha stampa-termyn",
+       "hr_tip": "Linen worwelyek (na usyowgh re)",
        "summary": "Berrskrif:",
-       "subject": "Testen/Pennlinen:",
+       "subject": "Testen:",
        "minoredit": "Chanj byghan yw hemma",
        "watchthis": "Golya an folen ma",
        "savearticle": "Gwitha an folen",
+       "savechanges": "Gwitha an chanjyow",
+       "publishpage": "Dyllo an folen",
+       "publishchanges": "Dyllo an chanjyow",
+       "savearticle-start": "Gwitha an folen…",
+       "savechanges-start": "Gwitha an chanjyow…",
+       "publishpage-start": "Dyllo an folen…",
+       "publishchanges-start": "Dyllo an chanjyow…",
        "preview": "Ragwel",
        "showpreview": "Diskwedhes ragwel",
        "showdiff": "Diskwedhes an chanjyow",
+       "blankarticle": "<strong>Bedhowgh war:</strong> Gwag yw an folen esowgh ow kul.\nMar klyckyowgh \"$1\" arta, an folen a vydh gwrys heb dalgh.",
        "anoneditwarning": "<strong>Gwarnyans:</strong> Nyns owgh hwi omgelmys. Gweladow yn foblek vydh agas trigva IP mar kwrewgh chanjyow. Mars <strong>[$1 omgelmowgh]</strong> po <strong>[$2 gwruthyl akont]</strong>, agas chanjyow a vydh askrifys dhe'gas hanow devnydher, keffrys ha lesow erel.",
        "anonpreviewwarning": "''Nyns owgh omgelmys. Dre witha, agas trigva IP a vydh rekordyes istori chanjya an folen-ma.''",
+       "missingsummary": "<strong>Bedhowgh war:</strong> Nyns eus berrskrif skrifys genowgh.\nMar klyckyowgh \"$1\" arta, agas chanj a vydh gwithys heb berrskrif.",
        "summary-preview": "Ragwel a'n berrskrif:",
        "loginreqtitle": "Res yw omgelmi",
        "loginreqlink": "omgelmi",
        "accmailtitle": "Ger-tremena danvenys.",
        "newarticle": "(Nowyth)",
        "newarticletext": "Hwi re holyas kevren dhe folen nag yw gwruthys hwath.\nRag gwruthyl an folen, dallethewgh jynnskrifa y'n gist a-woles (gwelewgh an [$1 folen weres] rag moy kedhlow).\nMar teuthowgh omma yn kamm, klyckyewgh boton '''war-dhelergh''' agas peurell.",
-       "noarticletext": "Nyns eus tekst y'n folen ma a-lemmyn.\nHwi a yll [[Special:Search/{{PAGENAME}}|hwilas titel an folen ma]] yn folennow erel,\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} hwilas y'n kovnotennow kelmys],\npo [{{fullurl:{{FULLPAGENAME}}|action=edit}} chanjya an folen ma]</span>.",
+       "noarticletext": "Nyns eus tekst y'n folen ma a-lemmyn.\nHwi a yll [[Special:Search/{{PAGENAME}}|hwilas titel an folen ma]] yn folennow erel,\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} hwilas y'n kovnotennow kelmys],\npo [{{fullurl:{{FULLPAGENAME}}|action=edit}} gwruthyl an folen ma]</span>.",
        "noarticletext-nopermission": "Nyns eus tekst y'n folen ma a-lemmyn.\nHwi a yll [[Special:Search/{{PAGENAME}}|hwilas titel an folen ma]] yn folennow erel, po <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} hwilas y'n kovnotennow kelmys]</span>, mes ny'gas beus kummyas dhe wruthyl an folen ma.",
        "userpage-userdoesnotexist": "Nyns yw kovskrifys an akont devnydhyer \"$1\".\nCheckyewgh mar pleg mara'gas beus hwans dhe wruthyl/dhe janjya an folen-ma.",
        "userpage-userdoesnotexist-view": "Nyns yw kovskrifys an akont devnydhyer \"$1\".",
        "template-semiprotected": "(hanter-difresys)",
        "hiddencategories": "Esel a {{PLURAL:$1|1 glass kudhys|$1 klass kudhys}} yw an folen ma:",
        "permissionserrorstext-withaction": "Nyns eus kummyas dhywgh dhe $2, rag an {{PLURAL:$1|acheson|achesonys}} a syw:",
-       "moveddeleted-notice": "Diles veu an folen ma.\nA-woles yma kovnotennow dhilea ha gwaya an folen.",
+       "recreate-moveddeleted-warn": "<strong>Gwarnyans: Yth esowgh ow kul folen a veu diles kens.</strong>\n\nY tal dhywgh prederi mars yw gwiw pesya ow chanjya an folen ma.\nOttomma kovnoten dhilea ha gwaya an folen ma:",
+       "moveddeleted-notice": "Diles veu an folen ma.\nA-woles yma kovnotennow dhilea, difres ha gwaya an folen.",
        "log-fulllog": "Gweles an govnoten dhien",
        "editwarning-warning": "Mar kesowgh an folen ma, hwi a allsa kelli chanjyow gwrys genowgh.\nMars owgh hwi omgelmys, hwi a yll diallosegi an gwarnyans ma yn tregh \"{{int:prefs-editing}}\" agas dewisyow.",
+       "content-model-wikitext": "wikitekst",
        "undo-success": "Y hyllir diswul an chanj-ma.\nCheckyewgh mar pleg an kehevelyans a-woles rag gwirya bos hemma an pyth a vynnowgh, hag ena gwithewgh an chanjyow a-woles rag gorfenna diswul an chanj.",
        "undo-summary": "Amendyans $1 gans [[Special:Contributions/$2|$2]] ([[User talk:$2|keskows]]) diswrys",
        "viewpagelogs": "Gweles kovnotennow an folen ma",
        "currentrev": "Amendyans diwettha",
        "currentrev-asof": "An amendyans diwettha a-dhia $1",
-       "revisionasof": "Versyon an folen a-dhia $1",
+       "revisionasof": "Versyon a-dhia $1",
        "revision-info": "Amendyans a-dhia $1 gans {{GENDER:$6|$2}}$7",
        "previousrevision": "← Amendyans kottha",
        "nextrevision": "Amendyans nowyttha →",
        "page_first": "kynsa",
        "page_last": "diwettha",
        "histlegend": "Dewis dyffransow: Merkyewgh kistennow radyo a'n amendyansow dhe geheveli, ha gweskewgh 'entra' po an boton orth goles an folen.<br />\nAlhwedh: '''({{int:cur}})''' = an dyffrans dhyworth an amendyans diwettha, '''({{int:last}})''' = an dyffrans dhyworth an amendyans kyns, '''{{int:minoreditletter}}''' = chanj byhan.",
-       "history-fieldset-title": "Peuri an istori",
+       "history-fieldset-title": "Hwilas amendyansow",
        "history-show-deleted": "Diles hepken",
-       "histfirst": "An moyha a-varr",
-       "histlast": "An diwettha",
+       "histfirst": "an kottha",
+       "histlast": "an nowettha",
        "historysize": "({{PLURAL:$1|1 bayt}})",
        "historyempty": "(gwag)",
        "history-feed-title": "Istori amendya",
        "compareselectedversions": "Keheveli an amendyansow dewisyes",
        "showhideselectedversions": "Diskwedhes/kudha amendyansow dewisyes",
        "editundo": "diswul",
-       "searchresults": "Sewyansow an hwilans",
-       "searchresults-title": "Sewyansow an hwilans rag \"$1\"",
+       "diff-empty": "(Dihevelepter vyth)",
+       "diff-multi-sameuser": "(Nyns yw diskwedhys {{PLURAL:$1|unn janj|$1 chanj}} kresel gans an keth devnydhyer)",
+       "diff-multi-otherusers": "(Nyns yw diskwedhys {{PLURAL:$1|unn janj|$1 chanj}} kresel gans {{PLURAL:$2|unn devnydhyer aral|$2 usyer}})",
+       "searchresults": "Sewyansow hwilas",
+       "searchresults-title": "Sewyansow hwilas rag \"$1\"",
        "notextmatches": "Nyns eus tekst folen vyth owth omdhesedha",
        "prevn": "{{PLURAL:$1|$1}} kyns",
        "nextn": "nessa {{PLURAL:$1|$1}}",
        "prevn-title": "$1 {{PLURAL:$1|sewyans}} kyns",
        "nextn-title": "$1 {{PLURAL:$1|sewyans}} nessa",
-       "shown-title": "Diskwedhes $1 {{PLURAL:$1|sewyans}} yn folen",
+       "shown-title": "Diskwedhes $1 {{PLURAL:$1|sewyans}} war pub folen",
        "viewprevnext": "Gweles ($1 {{int:pipe-separator}} $2) ($3)",
        "searchmenu-exists": "''Yma folen henwys \"[[:$1]]\" war an wiki-ma'''",
        "searchmenu-new": "<strong>Gwrewgh an folen \"[[:$1]]\" war an wiki ma!</strong> {{PLURAL:$2|0=|Gweler ynwegh an folen a veu kevys yn unn hwilas.|Gweler ynwedh an sewyans hwilas kevys.}}",
        "searchprofile-advanced-tooltip": "Hwilas yn spasys hanow personelhes",
        "search-result-size": "$1 ({{PLURAL:$2|1 ger|$2 ger}})",
        "search-result-category-size": "{{PLURAL:$1|1 esel|$1 esel}} ({{PLURAL:$2|1 isglass|$2 isglass}}, {{PLURAL:$3|1 restren|$3 restren}})",
-       "search-redirect": "(daskedyans $1)",
+       "search-redirect": "(daskevarwodhyans a $1)",
        "search-section": "(tregh $1)",
        "search-suggest": "Esewgh hwi ow menya: $1",
        "search-interwiki-caption": "Ragdresow hwor",
        "searchrelated": "kelmys",
        "searchall": "oll",
        "search-showingresults": "{{PLURAL:$4|Sewyans <strong>$1</strong> a <strong>$3</strong>|Sewyansow <strong>$1 - $2</strong> a <strong>$3</strong>}}",
-       "search-nonefound": "Nyns esa sewyans vyth owth omdhesedha orth an govyn.",
+       "search-nonefound": "Ny veu sewyans vyth par dhe'n govyn.",
        "powersearch-legend": "Hwilans avonsys",
        "powersearch-ns": "Hwilas yn spasys-hanow:",
        "powersearch-togglelabel": "Dewis:",
        "right-move": "Gwaya folennow",
        "right-movefile": "Gwaya restrennow",
        "right-upload": "Ughkarga restrennow",
+       "right-writeapi": "Devnydh a'n API skrifa",
        "right-delete": "Dilea folennow",
        "newuserlogpage": "Kovnoten gwruthyl akontow devnydhyer",
        "rightslog": "Kovnoten wiryow an devnydhyer",
        "action-edit": "chanjya an folen-ma",
-       "action-move": "gwaya an folen-ma",
+       "action-createaccount": "formya an akont usyer ma",
+       "action-move": "gwaya an folen ma",
        "action-movefile": "gwaya an restren-ma",
        "action-upload": "ughkarga an restren-ma",
-       "action-delete": "dilea an folen-ma",
+       "action-delete": "dilea an folen ma",
        "nchanges": "$1 {{PLURAL:$1|chanj|chanj}}",
        "enhancedrc-history": "istori",
        "recentchanges": "Chanjyow a-dhiwedhes",
-       "recentchanges-legend": "Etholyow an chanjyow a-dhiwedhes",
-       "recentchanges-summary": "War an folen-ma y hyllir helerghi an chanjyow diwettha eus gwrys dhe'n wiki.",
+       "recentchanges-legend": "Dewisyow an chanjyow a-dhiwedhes",
+       "recentchanges-summary": "Homm yw rol a janjyow a-dhiwedhes dhe'n wiki ma.",
        "recentchanges-noresult": "Nyns eus chanj vyth dres an termyn res a omdhesedh orth an etholyow-ma.",
        "recentchanges-feed-description": "Y hyllir helerhi an chanjyow diwettha gwrys dhe'n wiki y'n feed-ma.",
-       "recentchanges-label-newpage": "Gans an chanj ma y feu gwruthys folen nowydh",
-       "recentchanges-label-minor": "Chanj byghan yw hemma",
-       "recentchanges-label-bot": "Gwrys veu an chanj ma gans bott",
-       "recentchanges-label-unpatrolled": "Ny veu an chanj ma patrolyes hwath",
+       "recentchanges-label-newpage": "Folen nowydh",
+       "recentchanges-label-minor": "Chanj byghan",
+       "recentchanges-label-bot": "Chanj gans bott",
+       "recentchanges-label-unpatrolled": "Ny veu patrolyes hwath",
+       "recentchanges-label-plusminus": "Chanj dhe vyns an folen (baytys)",
        "recentchanges-legend-heading": "<strong>Alhwedh:</strong>",
-       "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (gweler ynwedh an [[Special:NewPages|rol a folennow nowydh]])",
-       "rclistfrom": "Diskwedhes chanjyow nowydh yn unn dhalleth dhyworth $3 $2",
+       "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} ([[Special:NewPages|rol leun]])",
+       "rcfilters-legend-heading": "<strong>Berrheansow:</strong>",
+       "rcfilters-activefilters": "Sidhlow byw",
+       "rcfilters-days-show-days": "$1 {{PLURAL:$1|jydh|dydh}}",
+       "rcfilters-search-placeholder": "Sidhla an chanjyow (usyowgh an rol po hwilas hanow an sidhel)",
+       "rcfilters-filter-humans-label": "Den (nyns yw bott)",
+       "rcfilters-filter-pageedits-label": "Chanjyow dhe folennow",
+       "rcfilters-filter-newpages-label": "Folennow gwrys",
+       "rcfilters-liveupdates-button": "Nowedhansow byw",
+       "rcnotefrom": "A-woles yma {{PLURAL:$5|an chanj|an chanjyow}} a-dhia <strong>$3, $4</strong> (ow tiskwedhes bys yn <strong>$1</strong>).",
+       "rclistfrom": "Diskwedhes chanjyow nowydh a-dhia $3 $2",
        "rcshowhideminor": "$1 chanjyow byghan",
+       "rcshowhideminor-show": "Diskwedhes",
        "rcshowhideminor-hide": "Kudha",
        "rcshowhidebots": "$1 bottow",
        "rcshowhidebots-show": "Diskwedhes",
+       "rcshowhidebots-hide": "Kudha",
        "rcshowhideliu": "$1 devnydhoryon govskrifys",
+       "rcshowhideliu-show": "Diskwedhes",
        "rcshowhideliu-hide": "Kudha",
        "rcshowhideanons": "$1 devnydhyoryon dhihanow",
        "rcshowhideanons-show": "Diskwedhes",
        "rcshowhideanons-hide": "Kudha",
+       "rcshowhidepatr-hide": "Kudha",
        "rcshowhidemine": "$1 ow chanjyow",
+       "rcshowhidemine-show": "Diskwedhes",
        "rcshowhidemine-hide": "Kudha",
+       "rcshowhidecategorization-hide": "Kudha",
        "rclinks": "Diskwedhes an $1 chanj diwettha gwrys y'n $2 dydh diwettha",
-       "diff": "dyffrans",
+       "diff": "dihevelepter",
        "hist": "istori",
        "hide": "Kudha",
        "show": "Diskwedhes",
        "minoreditletter": "B",
        "newpageletter": "N",
-       "boteditletter": "bott",
+       "boteditletter": "b",
        "rc-change-size-new": "$1 {{PLURAL:$1|byte|bytes}} wosa an chanj",
        "newsectionsummary": "/* $1 */ tregh nowyth",
        "rc-enhanced-expand": "Diskwedhes an manylyon (res yw JavaScript)",
        "rc-enhanced-hide": "Kudha an manylyon",
+       "rc-old-title": "gwrys yn kensa avel \"$1\"",
        "recentchangeslinked": "Chanjyow kelmys",
        "recentchangeslinked-feed": "Chanjyow kelmys",
        "recentchangeslinked-toolbox": "Chanjyow kelmys",
        "recentchangeslinked-title": "Chanjyow kelmys dhe \"$1\"",
-       "recentchangeslinked-summary": "Homm yw rol a janjyow gwrys a-dhiwedhes dhe folennow yw kevrennys dhyworth folen res (po dhe eseli a glass res).\n'''Tew''' yw folennow eus war agas [[Special:Watchlist|rol wolya]].",
+       "recentchangeslinked-summary": "Entrowgh hanow folen rag gweles chanjyow war folennow kevrennys a po bys y'n folen na. (Rag gweles eseli klass, entrowgh {{ns:category}}:Hanow an klass). Skrifys yn <strong>tew</strong> yw chanjyow dhe folennow war [[Special:Watchlist|agas rol golya]].",
        "recentchangeslinked-page": "Hanow an folen:",
        "recentchangeslinked-to": "Diskwedhes chanjyow dhe folennow kevrennys dhe'n folen res yn le",
        "upload": "Ughkarga restren",
        "filesource": "Pennfenten:",
        "savefile": "Gwitha restren",
        "watchthisupload": "Golya an folen-ma",
+       "license-header": "Leshyans",
        "imgfile": "restren",
        "listfiles_date": "Dedhyans",
        "listfiles_name": "Hanow",
        "listfiles_count": "Versyons",
        "file-anchor-link": "Restren",
        "filehist": "Istori an restren",
-       "filehist-help": "Klyckyewgh war dhedhyans/eur rag gweles an folen dell omdhiskwedhas nena.",
+       "filehist-help": "Klyckyewgh war dhedhyans/eur rag gweles an folen dell o an termyn na.",
        "filehist-deleteall": "dilea oll",
        "filehist-deleteone": "dilea",
        "filehist-revert": "gorthtreylya",
        "filehist-current": "a-lemmyn",
        "filehist-datetime": "Dedhyans/Eur",
        "filehist-thumb": "Skeusennik",
-       "filehist-thumbtext": "Skeusennik rag an versyon a-dhia $1",
+       "filehist-thumbtext": "Skeusennik an versyon a-dhia $1",
        "filehist-nothumb": "Nyns eus skeusennik",
        "filehist-user": "Devnydhyer",
        "filehist-dimensions": "Mynsow",
        "filehist-filesize": "Mens an restren",
-       "filehist-comment": "Kampoll",
+       "filehist-comment": "Kampol",
        "imagelinks": "Devnydh an restren",
        "linkstoimage": "Yma an {{PLURAL:$1|folen|$1 folen}} a syw ow kevrenna dhe'n restren ma:",
        "linkstoimage-more": "Yma moy es $1 {{PLURAL:$1|folen}} ow kevrenna dhe'n restren-ma.\nNy dhiskwa an rol a syw marnas an {{PLURAL:$1|kynsa kevren folen|kynsa $1 kevren folen}} dhe'n restren-ma.\nYma [[Special:WhatLinksHere/$2|rol leun]] kavadow.",
        "nolinkstoimage": "Nyns eus folen vyth ow kevrenna dhe'n restren-ma.",
        "morelinkstoimage": "Gweles [[Special:WhatLinksHere/$1|moy kevrennow]] dhe'n restren-ma.",
-       "sharedupload": "Yma an folen-ma ow tos dhyworth $1 ha hy a alsa bos yn-dann devnydh gans ragdresow erel.",
-       "sharedupload-desc-here": "Yma an restren ma dhe $1 ha ragdresow erel a allsa bos orth hy devnydhya.\nDiskwedhys a-woles yw an deskrifans war hy [$2 folen dheskrifans] ena.",
+       "linkstoimage-redirect": "$1 (ow taskidya restren) $2",
+       "sharedupload": "An folen ma a dheu a $1 hag a allsa bos usys gans ragdresow erel.",
+       "sharedupload-desc-here": "Yma an restren ma dhe $1 ha ragdresow erel a allsa bos orth hy devnydhya.\nDiskwedhys a-woles yma an deskrifans war hy [$2 folen dheskrifans] ena.",
+       "filepage-nofile": "Nyns eus folen henwys yndelma.",
        "uploadnewversion-linktext": "Ughkarga versyon nowyth a'n restren-ma",
+       "upload-disallowed-here": "Ny yllowgh gorskrifa an restren ma.",
        "filedelete": "Dilea $1",
        "filedelete-legend": "Dilea an restren",
        "filedelete-submit": "Dilea",
        "listredirects": "Rol an daswedyansow",
        "unusedtemplates": "Skantlyns heb devnydh",
        "unusedtemplateswlh": "kevrennow erel",
-       "randompage": "Folen dre happ",
+       "randompage": "Folen jonsus",
        "statistics": "Statystygyon",
        "statistics-pages": "Folennow",
        "brokenredirects-edit": "chanjya",
        "newpages-username": "Hanow-usyer:",
        "ancientpages": "An kottha folennow",
        "move": "Gwaya",
-       "movethispage": "Gwaya an folen-ma",
+       "movethispage": "Gwaya an folen ma",
        "pager-newer-n": "{{PLURAL:$1|1 nowyttha|$1 nowyttha}}",
        "pager-older-n": "{{PLURAL:$1|1 kottha|$1 kottha}}",
        "booksources": "Pennfentynyow lyver",
        "booksources-search-legend": "Hwilas pennfentynyow lyver",
+       "booksources-search": "Hwilas",
        "specialloguserlabel": "Awtour:",
        "speciallogtitlelabel": "Kosten (titel po devnydhyer):",
        "log": "Kovnotennow",
        "mywatchlist": "Rol wolya",
        "watchlistfor2": "Rag $1 ($2)",
        "watch": "Golya",
-       "watchthispage": "Golya an folen-ma",
+       "watchthispage": "Golya an folen ma",
        "unwatch": "Diswolya",
        "watchlist-details": "Yma {{PLURAL:$1|$1 folen}} war agas rol wolya, marnas folennow keskows.",
        "wlheader-showupdated": "Yn '''tew''' y tiskwedhir folennow re beu chanjyes a-dhia agas vysytyans diwettha.",
        "wlnote": "A-woles yma an {{PLURAL:$1|chanj diwettha|'''$1''' chanj diwettha}} y'n {{PLURAL:$2|our|'''$2''' our}} diwettha, a-dhia $3, $4.",
-       "wlshowlast": "Diskwedhes an $1 our diwettha, an $2 dydh diwettha, po",
+       "wlshowlast": "Diskwedhes an $1 our $2 dydh diwettha",
+       "watchlist-hide": "Kudha",
        "watchlist-options": "Etholyow an rol wolya",
        "watching": "Ow kolya...",
        "unwatching": "Ow tisgolya...",
        "deletecomment": "Acheson:",
        "deleteotherreason": "Acheson aral/keworansel:",
        "deletereasonotherlist": "Acheson aral",
-       "rollbacklink": "revya war-dhelergh",
+       "rollbacklink": "rolya war-dhelergh",
+       "rollbacklinkcount": "rolya $1 {{PLURAL:$1|janj|chanj}} war-dhelergh",
        "protectlogpage": "Kovnoten dhifres",
        "protectedarticle": "\"[[$1]]\" difresys",
+       "modifiedarticleprotection": "a janjyas nivel difresans \"[[$1]]\"",
        "prot_1movedto2": "[[$1]] gwayys dhe [[$2]]",
        "protectcomment": "Acheson:",
        "protectexpiry": "Ow tiwedha:",
        "undelete-show-file-submit": "Ya",
        "namespace": "Spas hanow:",
        "invert": "Trebuchya an dewisyans",
+       "tooltip-invert": "Tyckyowgh an gist ma rag kudha chanjyow dhe folennow y'n hanow spas dewisyes (ha'n hanow spas kevrennys, mars yw tyckyes)",
        "namespace_association": "Spas hanow kelmys",
+       "tooltip-namespace_association": "Tyckyowgh an gist ma dhe geworra ynwedh an hanow spas keskows po testen kevrennys dhe'n hanow spas dewisyes",
        "blanknamespace": "(Penn)",
        "contributions": "Kevrohow an {{GENDER:$1|devnydhyer}}",
        "contributions-title": "Kevrohow $1",
        "mycontris": "Kevrohow",
-       "contribsub2": "Rag $1 ($2)",
-       "uctop": "(gwartha)",
+       "anoncontribs": "Kevrohow",
+       "contribsub2": "Gans {{GENDER:$3|$1}} ($2)",
+       "uctop": "(a-lemmyn)",
        "month": "Dhyworth an mis (ha moy a-varr):",
        "year": "Dhyworth an vledhen (ha moy a-varr):",
        "sp-contributions-newbies": "Diskwedhes yn unnik kevrohow akontow nowyth",
        "sp-contributions-search": "Hwilas kevrohow",
        "sp-contributions-username": "Trigva IP po hanow devnydhyer:",
        "sp-contributions-toponly": "Diskwedhes yn unnik chanjyow yw amendyansow diwettha",
+       "sp-contributions-newonly": "Diskwedhes yn unnik chanjyow a wrug folennow nowydh",
        "sp-contributions-submit": "Hwilas",
-       "whatlinkshere": "Pyth a gevren dhe omma",
+       "whatlinkshere": "Folennow kevrennys",
        "whatlinkshere-title": "Folennow ow kevrenna dhe \"$1\"",
        "whatlinkshere-page": "Folen:",
-       "linkshere-2": "Yma an folennow a syw ow kevrenna dhe '''$1''':",
-       "nolinkshere-2": "Nyns eus folen vyth ow kevrenna dhe '''$1'''.",
+       "linkshere": "Yma an folennow a syw ow kevrenna dhe '''$2''':",
+       "nolinkshere": "Nyns eus folen vyth ow kevrenna dhe '''$2'''.",
        "isredirect": "folen daskedyans",
        "istemplate": "treuskludyans",
        "isimage": "kevren an restren",
        "whatlinkshere-prev": "{{PLURAL:$1|kyns|$1 kyns}}",
        "whatlinkshere-next": "{{PLURAL:$1|nessa|nessa $1}}",
        "whatlinkshere-links": "← kevrennow",
-       "whatlinkshere-hideredirs": "$1 daskedyansow",
-       "whatlinkshere-hidetrans": "$1 treuskludyans",
+       "whatlinkshere-hideredirs": "$1 daskidyansow",
+       "whatlinkshere-hidetrans": "$1 treuskludyansow",
        "whatlinkshere-hidelinks": "$1 kevrennow",
        "whatlinkshere-hideimages": "$1 kevrennow restren",
        "whatlinkshere-filters": "Sidhlow",
        "movepagetext": "Devnydhya an furvlen a-woles a dhashenow folen, yn unn waya oll y istori dhe'n hanow nowyth.\nAn titel koth a vydh folen dhaskedyans dhe'n titel nowyth.\nHwi a yll nowedhi daskedyansow a boynt dhe'n titel derowel yn awtomatek.\nMar ny wrewgh, surhewgh hwi dhe jeckya rag [[Special:DoubleRedirects|daskedyansow dobyl]] po [[Special:BrokenRedirects|terrys]].\nOmgemeryansek owgh rag surhe y pes kevrennow poyntya dhe'n tyller ewn.\n\nNotyewgh '''na wayir''' an folen mars eus folen orth an titel nowyth seulabrys, marnas bos an pyth kampollys diwettha daskedyans ha ny'n jeves istori chanjya kyns vyth.\nHemm a styr y hyllowgh diswul dashenwel folen mar kwrewgh kammwrians, ha ny yllowgh gorskrifa folen eus ena seulabrys.\n\n'''Gwarnyans!'''\nHemm a yll bos chanj tromm ha bras dres ehen rag folen gerys-da;\nSurhewgh mar pleg hwi dhe gonvedhes sewyansow an gwrians-ma kyns mos yn-rag.",
        "moveuserpage-warning": "'''Gwarnyans''': Yth esowgh ow mos dhe waya folen dhevnydhyer. Notyewgh mar pleg ny vydh marnas an folen gwayys ha ''ny vydh'' an devnydhyer dashenwys.",
        "newtitle": "Dhe ditel nowyth:",
-       "move-watch": "Golya an folen-ma",
+       "move-watch": "Golya an folen ma",
        "movepagebtn": "Gwaya an folen",
        "pagemovedsub": "Gwaya a sewenis",
        "movepage-moved": "'''Gwayys re beu \"$1\" dhe \"$2\"'''",
        "import-upload-filename": "Hanow an restren:",
        "importstart": "Owth ymperthi folennow...",
        "import-noarticle": "Nyns eus folen vyth dhe ymperthi!",
-       "tooltip-pt-userpage": "Agas folen dhevnydhyer",
-       "tooltip-pt-mytalk": "Agas folen gows",
-       "tooltip-pt-preferences": "Agas dewisyow",
+       "tooltip-pt-userpage": "{{GENDER:|Agas folen dhevnydhyer}}",
+       "tooltip-pt-mytalk": "{{GENDER:|Agas folen gows}}",
+       "tooltip-pt-preferences": "{{GENDER:|Agas dewisyow}}",
        "tooltip-pt-watchlist": "Rol a folennow esowgh ow kolya rag chanjyow",
-       "tooltip-pt-mycontris": "Rol a'gas kevrohow",
-       "tooltip-pt-login": "Ni a gomend hwi dhe omgelmi, mes nyns yw besi",
-       "tooltip-pt-logout": "Digelmi",
-       "tooltip-pt-createaccount": "Ni a gomend hwi dhe wruthyl akont hag omgelmi; byttegyns nyns yw besi",
+       "tooltip-pt-mycontris": "Rol {{GENDER:|a'gas kevrohow}}",
+       "tooltip-pt-login": "Ni a gomend hwi dhe omgelmi, mes nyns yw bysi",
+       "tooltip-pt-logout": "Omdenna",
+       "tooltip-pt-createaccount": "Ni a gomend hwi dhe wruthyl akont hag omgelmi; byttegyns nyns yw bysi",
        "tooltip-ca-talk": "Dadhlow a-dro dhe'n folen",
        "tooltip-ca-edit": "Chanjya an folen ma",
        "tooltip-ca-addsection": "Dalleth tregh nowydh",
        "tooltip-ca-protect": "Difres an folen-ma",
        "tooltip-ca-delete": "Dilea an folen-ma",
        "tooltip-ca-move": "Gwaya an folen ma",
-       "tooltip-ca-watch": "Keworra an folen ma dhe'gas rol wolya",
+       "tooltip-ca-watch": "Keworra an folen ma dh'agas rol wolya",
        "tooltip-ca-unwatch": "Dilea an folen-ma dhyworth agas rol wolya",
        "tooltip-search": "Hwilas yn {{SITENAME}}",
        "tooltip-search-go": "Mos dhe folen dhedhi an keth hanow ma, mars eus",
        "tooltip-search-fulltext": "Hwilas an tekst ma y'n folennow",
-       "tooltip-p-logo": "Mos dhe'n folen dynnargh",
-       "tooltip-n-mainpage": "Mos dhe'n folen dynnargh",
-       "tooltip-n-mainpage-description": "Mos dhe'n folen dynnargh",
-       "tooltip-n-portal": "A-dro dhe'n ragdres, an pyth a yllowgh gul, ple hyllir kavos taklow",
+       "tooltip-p-logo": "Mos dhe'n folen dre",
+       "tooltip-n-mainpage": "Mos dhe'n folen dre",
+       "tooltip-n-mainpage-description": "Mos dhe'n folen dre",
+       "tooltip-n-portal": "A-dro dhe'n ragdres, pyth a yllowgh gul, ple hyllir kavos taklow",
        "tooltip-n-currentevents": "Kavos kedhlow a-dro dhe hwarvosow a-lemmyn",
        "tooltip-n-recentchanges": "Rol a janjyow a-dhiwedhes y'n wiki",
        "tooltip-n-randompage": "Karga folen dre happ",
        "tooltip-n-help": "Gweres",
-       "tooltip-t-whatlinkshere": "Rol a bub folen wiki a gevren dhe omma",
-       "tooltip-t-recentchangeslinked": "Chanjyow a-dhiwedhes yn folennow a gevren an folen ma dhedha",
+       "tooltip-t-whatlinkshere": "Rol a bub folen wiki kevrennys dhe'n folen ma",
+       "tooltip-t-recentchangeslinked": "Chanjyow a-dhiwedhes yn folennow kevrennys dhyworth an folen ma",
        "tooltip-feed-rss": "Feed RSS rag an folen-ma",
        "tooltip-feed-atom": "Feed Atom rag an folen ma",
-       "tooltip-t-contributions": "Gweles rol a gevrohow an devnydhyer ma",
-       "tooltip-t-emailuser": "Danvon ebost dhe'n devnydhyer-ma",
+       "tooltip-t-contributions": "Rol a gevrohow gans {{GENDER:$1|an usyer ma}}",
+       "tooltip-t-emailuser": "Danvon ebost dhe'n {{GENDER:$1|usyer|usyores}} ma",
        "tooltip-t-upload": "Ughkarga restrennow",
        "tooltip-t-specialpages": "Rol a geniver folen arbennek",
        "tooltip-t-print": "Versyon pryntyadow a'n folen ma",
        "tooltip-t-permalink": "Kevren fast dhe'n amendyans ma a'n folen",
        "tooltip-ca-nstab-main": "Gweles an folen",
        "tooltip-ca-nstab-user": "Gweles an folen dhevnydhyer",
-       "tooltip-ca-nstab-special": "Folen arbennek yw homma; ny yllowgh chanjya an folen hy honan.",
+       "tooltip-ca-nstab-special": "Folen arbennek yw homma; ny yllir hy chanjya",
        "tooltip-ca-nstab-project": "Gweles folen an wiki",
        "tooltip-ca-nstab-image": "Gweles folen an restren",
+       "tooltip-ca-nstab-mediawiki": "Gweles messach an system",
        "tooltip-ca-nstab-template": "Gweles an skantlyn",
        "tooltip-ca-nstab-category": "Gweles folen an klass",
        "tooltip-minoredit": "Merkya hemma avel chanj byhan",
        "tooltip-diff": "Diskwedhes an chanjyow a wrussowgh dhe'n tekst",
        "tooltip-compareselectedversions": "Gweles an dyffransow ynter dew amendyansow dewisyes an folen-ma",
        "tooltip-watch": "Keworra an folen-ma dhe'gas rol wolya",
-       "tooltip-rollback": "\"Revya war-dhelergh\" a worthtreyl chanjyow an diwettha devnydhyer der unn glyck",
+       "tooltip-rollback": "\"Rolya war-dhelergh\" a worthtreyl chanj(yow) an diwettha devnydhyer der unn glyck",
        "tooltip-undo": "\"Diswul\" a worthtreyl an chanj ma hag ygeri an furvlen janjya y'n modh ragweles. Y hyllir keworra acheson y'n berrskrif.",
-       "tooltip-summary": "Entrewgh berrskrif",
+       "tooltip-summary": "Keworrewgh berrskrif",
        "siteuser": "devnydhyer {{SITENAME}} $1",
-       "lastmodifiedatby": "Chanj diwettha an folen-ma o dhe $2, $1 gans $3.",
+       "lastmodifiedatby": "Chanj diwettha an folen ma a veu dhe $2 an $1 gans $3.",
        "siteusers": "{{PLURAL:$2|devnydhyer|devnydhyoryon}} {{SITENAME}} $1",
+       "simpleantispam-label": "Prov gorth-spam.\n<strong>Na</strong> lenwowgh hemma!",
+       "pageinfo-title": "Kedhlow \"$1\"",
+       "pageinfo-header-edits": "Istori chanjya",
+       "pageinfo-watchers": "Niver a dus ow kolya",
+       "pageinfo-few-watchers": "Le es $1 {{PLURAL:$1|golyer|golyoryon}}",
+       "pageinfo-firstuser": "Gwrier an folen",
+       "pageinfo-firsttime": "Dedhyans gwrians an folen",
+       "pageinfo-edits": "Niver a janjyow",
        "pageinfo-toolboxlink": "Kedhlow an folen",
        "previousdiff": "← Chanj kottha",
        "nextdiff": "Chanj nowyttha →",
+       "widthheightpage": "$1 × $2, $3 {{PLURAL:$3|folen}}",
        "file-info-size": "$1 × $2 piksel, myns an restren: $3, eghen MIME: $4",
        "file-nohires": "Nyns eus klerder ughella kavadow.",
        "svg-long-desc": "Restren SVG, $1 × $2 piksel yn hanow, myns an restren: $3",
        "metadata-collapse": "Kudha manylyon ystynnys",
        "exif-imagewidth": "Les",
        "exif-imagelength": "Uhelder",
+       "exif-xresolution": "Klerder gorwelyek",
+       "exif-yresolution": "Klerder plommwedhek",
        "exif-artist": "Awtour",
        "exif-meteringmode-255": "Aral",
        "exif-contrast-0": "Usadow",
        "version": "Versyon",
        "version-other": "Aral",
        "version-version": "($1)",
+       "redirect-submit": "Mos",
+       "redirect-lookup": "Hwilas:",
+       "redirect-user": "ID an usyer",
+       "redirect-page": "ID an folen",
+       "redirect-revision": "Amendyans an folen",
+       "redirect-file": "Hanow an restren",
        "fileduplicatesearch-filename": "Hanow an restren:",
        "fileduplicatesearch-submit": "Hwilas",
        "specialpages": "Folennow arbennek",
        "blankpage": "Folen wag",
        "tag-filter": "Sidhel [[Special:Tags|tagyow]]:",
        "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|Tagg|Taggys}}]]: $2)",
+       "tags-title": "Taggys",
+       "tags-active-no": "Nag yw",
        "tags-edit": "chanjya",
        "dberr-problems": "Drog yw genen! An wiasva-ma a's teves kaletter teknogel.",
        "dberr-again": "Assayewgh gortos pols ha daskarga.",
        "logentry-move-move-noredirect": "$1 {{GENDER:$2|a wayas}} an folen $3 dhe $4 heb gasa daskedyans",
        "logentry-move-move_redir": "$1 {{GENDER:$2|a wayas}} an folen $3 dhe $4 dres daskedyans",
        "logentry-newusers-create": "{{GENDER:$2|Gwruthys}} veu an akont devnydhyer $1",
-       "searchsuggest-search": "Hwilas",
+       "logentry-newusers-autocreate": "{{GENDER:$2|Gwrys}} veu an akont usyer $1 yn awtomatek",
+       "logentry-upload-upload": "$1 {{GENDER:$2|a ughkargas}} $3",
+       "logentry-upload-overwrite": "$1 {{GENDER:$2|a ughkargas}} versyon nowydh a $3",
+       "searchsuggest-search": "Hwilas yn {{SITENAME}}",
        "searchsuggest-containing": "ynni...",
+       "duration-days": "$1 {{PLURAL:$1|jydh|dydh}}",
        "special-characters-group-latin": "Latin",
        "special-characters-group-latinextended": "Latin ystynnys",
        "special-characters-group-ipa": "IPA",
index bcedaee..bd7ae38 100644 (file)
        "whatlinkshere": "Шилтемелерди бул жакка",
        "whatlinkshere-title": "\"$1\" -га шилтеме берген барактар",
        "whatlinkshere-page": "Барак:",
-       "linkshere-2": "'''$1''' барагына шилтеме берген барактар:",
-       "nolinkshere-2": "'''$1''' барагына шилтеме берген барак жок.",
+       "linkshere": "'''$2''' барагына шилтеме берген барактар:",
+       "nolinkshere": "'''$2''' барагына шилтеме берген барак жок.",
        "isredirect": "багыттама барак",
        "istemplate": "бириктирүү",
        "isimage": "файл шилтемеси",
index 616258d..edb6586 100644 (file)
        "whatlinkshere": "Nexus ad paginam",
        "whatlinkshere-title": "Paginae quae ad \"$1\" nectuntur",
        "whatlinkshere-page": "Pagina:",
-       "linkshere-2": "Paginae sequentes ad '''$1''' nectunt:",
-       "nolinkshere-2": "Nullae paginae ad '''$1''' nectunt.",
-       "nolinkshere-ns-2": "Nullae paginae spatii nominalis selecti ad '''$1''' nectunt.",
+       "linkshere": "Paginae sequentes ad '''$2''' nectunt:",
+       "nolinkshere": "Nullae paginae ad '''$2''' nectunt.",
+       "nolinkshere-ns": "Nullae paginae spatii nominalis selecti ad '''$2''' nectunt.",
        "isredirect": "pagina redirectionis",
        "istemplate": "inclusio",
        "isimage": "nexus fasciculi",
        "markaspatrolledtext": "Indicare hanc paginam qua circumita",
        "markedaspatrolled": "Indicare hanc paginam qua circumita",
        "patrol-log-page": "Acta emendationum circumitarum",
-       "log-show-hide-patrol": "$1 acta emendationum circumitarum",
        "deletedrevision": "Abolita redactio imaginis $1",
        "previousdiff": "← Differentia superior",
        "nextdiff": "Differentia proxima →",
index 9e035e9..c1d7b45 100644 (file)
        "whatlinkshere": "Hojas atadas",
        "whatlinkshere-title": "Hojas que dan link a \"$1\"",
        "whatlinkshere-page": "Hoja:",
-       "linkshere-2": "Las hojas venideras dan link a '''$1''':",
-       "nolinkshere-2": "Dinguna ója tiene atamientos kon '''$1'''",
+       "linkshere": "Las hojas venideras dan link a '''$2''':",
+       "nolinkshere": "Dinguna ója tiene atamientos kon '''$2'''",
        "isredirect": "Hoja redirigida",
        "istemplate": "inclusión",
        "isimage": "atamiento de la dosya",
index 764e56e..817e647 100644 (file)
        "resetpass-temp-password": "Temporäert Passwuert:",
        "resetpass-abort-generic": "D'Ännere vum Passwuert gouf duerch eng Erweiderung ofgebrach.",
        "resetpass-expired": "Äert Passwuert ass ofgelaf. Gitt w.e.g. en neit Passwuert u fir Iech anzeloggen.",
-       "resetpass-expired-soft": "Äert Passwuert ass ofgelaf a muss zeréckgesat. Sicht w.e.g. elo en neit Passwuert eraus oder klickt  \"{{int:authprovider-resetpass-skip-label}}\" fir et spéider zeréckzesetzen.",
-       "resetpass-validity-soft": "Ärt Passwuert ass net valabel: $1",
+       "resetpass-expired-soft": "Äert Passwuert ass ofgelaf a muss geännert ginn. Sicht w.e.g. elo en neit Passwuert eraus oder klickt  \"{{int:authprovider-resetpass-skip-label}}\" fir et spéider z'änneren.",
+       "resetpass-validity-soft": "Äert Passwuert ass net valabel: $1\n\nWielt elo en neit Passwuert oder klickt op \"{{int:authprovider-resetpass-skip-label}}\" fir et méi spéit z'änneren.",
        "passwordreset": "Passwuert zrécksetzen",
        "passwordreset-text-one": "Fëllt dëse Formulaire aus fir Äert Passwuert zréckzesetzen.",
        "passwordreset-text-many": "{{PLURAL:$1|Fëllt eent vun de Felder aus fir en temporäert Passwuert per E-Mail ze kréien.}}",
        "previewnote": "'''Denkt drun datt dëst nëmmen eng net gespäichert Versioun ass.'''\nÄr Ännerunge sinn nach net gespäichert!",
        "continue-editing": "Gitt weider an de Beräich fir z'änneren",
        "previewconflict": "Dir gesitt an dem ieweschten Textfeld wéi den Text ausgesi wäert, wann Dir späichert.",
-       "session_fail_preview": "Är Ännerung konnt net gespäichert gi well d'Date vun Ärer Sessioun verluergaange sinn.\nDir gouft eventuell ausgeloggt. <strong>Iwwerpréift w.e.g. ob Dir nach ageloggt sidd a probéiert nach eng Kéier</strong>.\nWann de Problem dann ëmmer nach bestoe sollt, da versicht Iech [[Special:UserLogout|auszeloggen]] an dann erëm anzeloggen an iwwerpréift datt Äre Browser Cookië vun dësem Site  akzeptéiert.",
-       "session_fail_preview_html": "Är Ännerung konnt net gespäichert gi well d'Date vun Ärer Sessioun verluergaange sinn.\n\n<em>Well op {{SITENAME}} 'raw HTML' aktivéiert ass, gouf d'Uweise vun der nach net gespäicherter Versioun ausgeblennt fir JavaScript-Attacken ze vermeiden.</em>\n\n<strong>Wann Dir eng berechtegt Ännerung maache wëllt, da versicht et w.e.g. nach eng Kéier.</strong>\n\nWann de Problem dann ëmmer nach bestoe sollt, versicht Iech [[Special:UserLogout|auszeloggen]] an dann erëm anzeloggen a vergewëssert Iech datt Äre Browser d^Späichere vu Cookieë vun dësem Site zouléisst.",
+       "session_fail_preview": "Är Ännerung konnt net gespäichert gi well d'Date vun Ärer Sessioun verluergaange sinn.\nDir gouft eventuell ausgeloggt. <strong>Iwwerpréift w.e.g. ob Dir nach ageloggt sidd a probéiert nach eng Kéier</strong>.\nWann de Problem dann ëmmer nach bestoe sollt, da versicht Iech [[Special:UserLogout|auszeloggen]] an dann erëm anzeloggen an iwwerpréift ob Äre Browser Cookië vun dësem Site  akzeptéiert.",
+       "session_fail_preview_html": "Är Ännerung konnt net gespäichert gi well d'Date vun Ärer Sessioun verluergaange sinn.\n\n<em>Well op {{SITENAME}} 'raw HTML' aktivéiert ass, gouf d'Uweise vun der nach net gespäicherter Versioun ausgeblennt fir JavaScript-Attacken ze vermeiden.</em>\n\n<strong>Wann Dir eng berechtegt Ännerung maache wëllt, da versicht et w.e.g. nach eng Kéier.</strong>\n\nWann de Problem dann ëmmer nach bestoe sollt, versicht Iech [[Special:UserLogout|auszeloggen]] an dann erëm anzeloggen a vergewëssert Iech ob Äre Browser d'Späichere vu Cookieë vun dësem Site zouléisst.",
        "token_suffix_mismatch": "'''Är Ännerung gouf refuséiert, well Äre Browser Zeechen am Ännerungs-Identifiant verännert huet.'''\nD'Ännerung gouf refuséiert, fir ze verhënneren datt den Text op der Säit onliesbar gëtt.\nDëst geschitt heiansdo wann Dir en anonyme Proxy-Service um Internet benotzt.",
        "edit_form_incomplete": "'''En Deel vum Ännerungsformulaire koum net um Server un; iwwerpréift w.e.g ob Är Ännerunge komplett sinn a probéiert nach emol.'''",
        "editing": "Ännere vu(n) $1",
        "diff-paragraph-moved-toold": "Den Abschnitt gouf geréckelt. Klickt fir op déi al Plaz ze sprangen.",
        "difference-missing-revision": "{{PLURAL:$2|Eng Versioun|$2 Versioune}} vun dëser Differenz ($1) {{PLURAL:$2|gouf|goufen}} net fonnt.\n\nDat geschitt normalerweis wann Dir op e vereelste Link vun enger Versioun vun enger Säit klickt déi geläscht ginn ass.\nDetailer fannt Dir am [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} Logbuch vum Läschen].",
        "searchresults": "Resultat vum Sichen",
+       "search-filter-title-prefix-reset": "Op all de Säite sichen",
        "searchresults-title": "Resultater vum Sichen no \"$1\"",
        "titlematches": "Iwwereneestëmmungen am Säitentitel",
        "textmatches": "Iwwereneestëmmungen am Säitentext",
        "rcfilters-other-review-tools": "Aner Méiglechkeete fir z'iwwerliesen",
        "rcfilters-group-results-by-page": "Resultater no de Säite gruppéieren",
        "rcfilters-activefilters": "Aktiv Filteren",
+       "rcfilters-activefilters-hide": "Verstoppen",
+       "rcfilters-activefilters-show": "Weisen",
        "rcfilters-advancedfilters": "Erweidert Filteren",
        "rcfilters-limit-title": "Resultater fir ze weisen",
        "rcfilters-limit-and-date-label": "{{PLURAL:$1|Eng Ännerung|$1 Ännerungen}}, $2",
        "rcfilters-savedqueries-rename": "Ëmbenennen",
        "rcfilters-savedqueries-setdefault": "Als Standard festleeën",
        "rcfilters-savedqueries-unsetdefault": "Als Standard ewechhuelen",
-       "rcfilters-savedqueries-remove": "Ewechhuelen",
+       "rcfilters-savedqueries-remove": "Läschen",
        "rcfilters-savedqueries-new-name-label": "Numm",
        "rcfilters-savedqueries-new-name-placeholder": "Den Zweck vum Filter beschreiwen",
        "rcfilters-savedqueries-apply-label": "Filter uleeën",
        "rcfilters-empty-filter": "Keen aktive Filter. All Kontributioune gi gewisen.",
        "rcfilters-filterlist-title": "Filteren",
        "rcfilters-filterlist-whatsthis": "Wéi geet dat?",
-       "rcfilters-filterlist-feedbacklink": "Sot eis wat Dir vun dësen (neien) Filterméiglechkeeten haalt",
+       "rcfilters-filterlist-feedbacklink": "Sot eis wat Dir vun dësen Filterméiglechkeeten haalt",
        "rcfilters-highlightbutton-title": "Resultater ervirhiewen",
        "rcfilters-highlightmenu-title": "Eng Faarf eraussichen",
        "rcfilters-highlightmenu-help": "Sicht eng Faarf eraus fir dës Eegenschaft ervirzehiewen.",
        "rcfilters-watchlist-edit-watchlist-button": "Ännert Är Lëscht vun iwwerwaachte Säiten",
        "rcfilters-watchlist-showupdated": "Ännerungen op Säiten déi Dir net besicht hutt zanter d'Ännerunge gemaach goufen si <strong>fett</strong> geschriwwen.",
        "rcfilters-preference-label": "Déi verbessert Versioun vun de rezenten Ännerunge verstoppen",
+       "rcfilters-watchlist-preference-label": "Déi verbessert Versioun vun der Iwwerwaachungslëscht verstoppen",
        "rcfilters-target-page-placeholder": "Gitt en Numm vun enger Säit (oder enger Kategorie) an",
        "rcnotefrom": "Hei drënner {{PLURAL:$5|gëtt d'Ännerung|ginn d'Ännerungen}} zanter <strong>$3, $4</strong> (maximal <strong>$1</strong> Ännerunge gi gewisen).",
        "rclistfromreset": "Eraussiche vum Datum zrécksetzen",
        "http-timed-out": "HTTP-Ufro huet ze laang gebraucht (time out).",
        "http-curl-error": "Feeler beim Ofruff vun der URL: $1",
        "http-bad-status": "Et gouf e Problem bei der HTTP-Ufro: $1 $2",
+       "http-internal-error": "Internen HTTP-Feeler.",
        "upload-curl-error6": "URL ass net z'erreechen",
        "upload-curl-error6-text": "Déi URL déi Dir uginn hutt kann net erreecht ginn.\nKuckt w.e.g. no op kee Feeler an der URL ass an op de Site och online ass.",
        "upload-curl-error28": "D'Eroplueden huet ze laang gedauert (timeout)",
        "speciallogtitlelabel": "Zil (Titel oder {{ns:user}}:Benotzernumm fir e Benotzer):",
        "log": "Logbicher",
        "logeventslist-submit": "Weisen",
+       "logeventslist-more-filters": "Méi Filteren:",
        "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.",
        "uctop": "(aktuell)",
        "month": "Vum Mount (a virdrun):",
        "year": "Vum Joer (a virdrun):",
+       "date": "Vum Datum (a virdrun):",
        "sp-contributions-newbies": "Nëmme Kontributioune vun neie Mataarbechter weisen",
        "sp-contributions-newbies-sub": "Fir déi Nei",
        "sp-contributions-newbies-title": "Kontributioune vun neie Benotzer",
        "whatlinkshere": "Linken op dës Säit",
        "whatlinkshere-title": "Säiten, déi mat \"$1\" verlinkt sinn",
        "whatlinkshere-page": "Säit:",
-       "linkshere-2": "Déi folgend Säite linken op '''$1''':",
-       "nolinkshere-2": "Keng Säit ass mat '''$1''' verlinkt.",
-       "nolinkshere-ns-2": "Keng Säite linken op '''$1''' am gewielten Nummraum.",
+       "linkshere": "Déi folgend Säite linken op <strong>$2</strong>:",
+       "nolinkshere": "Keng Säit ass mat <strong>$2</strong> verlinkt.",
+       "nolinkshere-ns": "Keng Säite linken op <strong>$2</strong> am gewielten Nummraum.",
        "isredirect": "Viruleedung",
        "istemplate": "an dëser Säit dran",
        "isimage": "Link op de Fichier",
        "block": "Benotzer spären",
        "unblock": "D'Spär vum Benotzer ophiewen",
        "blockip": "{{GENDER:$1|Benotzer}} spären",
-       "blockiptext": "Benotzt dëse Formulaire fir eng spezifesch IP-Adress oder e Benotzernumm ze spären.\nDëst soll nëmmen am Fall vu Vandalismus gemaach ginn, en accordance mat den [[{{MediaWiki:Policy-url}}|interne Richlinen]].\nGitt e spezifesche Grond un (zum Beispill Säite wou Vandalismus virgefall ass).\nDir kënnt IP-Beräicher spären an deem Dir d' [https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing CIDR] Syntax benotzt; de gréissten erlaabte Beräich as  /$1 fir IPv4 an /$2 fir IPv6",
+       "blockiptext": "Benotzt dëse Formulaire fir eng spezifesch IP-Adress oder e Benotzernumm ze spären.\nDëst soll nëmmen am Fall vu Vandalismus gemaach ginn, en accordance mat den [[{{MediaWiki:Policy-url}}|interne Richtlinnen]].\nGitt e spezifesche Grond un (zum Beispill Säite wou Vandalismus virgefall ass).\nDir kënnt IP-Beräicher spären an deem Dir d' [https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing CIDR] Syntax benotzt; de gréissten erlaabte Beräich as  /$1 fir IPv4 an /$2 fir IPv6",
        "ipaddressorusername": "IP-Adress oder Benotzernumm:",
        "ipbexpiry": "Gültegkeet:",
        "ipbreason": "Grond:",
-       "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 bedréit aner Mataarbechter\n**Mëssbrauch vu verschiddene Benotzernimm\n**Net akzeptabele Benotzernumm",
+       "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": "Opmaache vun engem Benotzerkont verhënneren",
        "ipbemailban": "Verhënneren datt de Benotzer E-Maile verschéckt",
        "markedaspatrollederrornotify": "Markéieren als kontrolléiert huet net funktionéiert.",
        "patrol-log-page": "Logbuch vun den iwwerkuckte Versiounen",
        "patrol-log-header": "Dëst ass d'Logbuch vun den nogekuckte Versiounen.",
-       "log-show-hide-patrol": "Kontroll-Logbuch $1",
        "confirm-markpatrolled-button": "OK",
        "confirm-markpatrolled-top": "Versioun $3 vu(n) $2 als kontrolléiert markéieren?",
        "deletedrevision": "Al, geläscht Versioun vu(n) $1",
index 2b857b1..5b501c8 100644 (file)
@@ -15,7 +15,8 @@
                        "Soul Train",
                        "Умар",
                        "아라",
-                       "Amire80"
+                       "Amire80",
+                       "Stjn"
                ]
        },
        "tog-underline": "ЭлячӀунрин кӀаникай цӀар чӀугун",
        "noarticletext-nopermission": "Исятда и ччина са текстни авач.\nКвевай [[Special:Search/{{PAGENAME}}| и тӀвар алай ччин]] муькуь ччинра жугъуриз ва я\n<span class=\"plainlinks\"> [{{fullurl: {{# Special:Log}} | page = {{FULLPAGENAMEE}}}} журналрин талукь тир кхьей затӀар жугъуриз] жеда.",
        "blocked-notice-logextract": "И уртах алайчIава блокарнава.\nАгъадихъ блокарунин журналдикай эхиримжи кхьинар къалурнава:",
        "previewnote": "'''Рикlел хуьх хьи, им анжах сифтедин килигун я.'''  \nКуь масакIавилер гьеле хвенвач!",
-       "editing": "$1 Ð\94уьзар хъувун",
+       "editing": "$1 Ð´уьзар хъувун",
        "editingsection": "Дуьзар хъувун $1  (пай)",
        "editingcomment": "$1 дуьзар хъувун (цIийи пай)",
        "editconflict": "Дуьзар хъувунрин акьунар: $1",
        "whatlinkshere": "Иниз вуч элячIзава",
        "whatlinkshere-title": "\"$1\" - даз элячlзавай ччинар",
        "whatlinkshere-page": "Ччин:",
-       "linkshere-2": "Гуьгъуьнин ччинар '''$1''': - даз  элячlзава",
-       "nolinkshere-2": "'''$1''' ччиниз са ччинни элячIзавач.",
+       "linkshere": "Гуьгъуьнин ччинар '''$2''': - даз  элячlзава",
+       "nolinkshere": "'''$2''' ччиниз са ччинни элячIзавач.",
        "isredirect": "Рахкъурунин ччин",
        "istemplate": "кутун",
        "isimage": "Файлдин элячlун",
index 8578dc9..f279596 100644 (file)
@@ -12,7 +12,8 @@
                        "Angel Blaise",
                        "Fitoschido",
                        "Robin van der Vliet",
-                       "Mafcadio"
+                       "Mafcadio",
+                       "Matěj Suchánek"
                ]
        },
        "tog-underline": "Sulini de lias:",
        "perfcachedts": "La datos seguente veni de prememoria e la refresci la plu resente ia aveni a $1. No plu ca {{PLURAL:$4|un resulta|$4 resultas}} es disponable en la prememoria.",
        "querypage-no-updates": "Refrescis de esta paje es aora descomutada.\nDatos asi no va es refrescida a presente.",
        "viewsource": "Regarda vicitesto",
-       "viewsource-title": "Regarda vicitesto per $1",
+       "viewsource-title": "Regarda fonte per $1",
        "actionthrottled": "Ata limitada",
        "actionthrottledtext": "Per defende contra malusa, usores no pote fa esta ata a tro multe veses en un tempo corta, e tu ia esede esta limita.\nPer favore, atenta denova pos alga minutos.",
        "protectedpagetext": "Esta paje es protejeda per preveni editas o otra atas.",
        "cascadeprotected": "Esta paje es protejeda contra editas car lo es transcluida en la {{PLURAL:$1|paje|pajes}} seguente, cual es cascadin protejeda:\n$2",
        "namespaceprotected": "Tu no es permeteda a edita pajes en la spasio de nom <strong>$1</strong>.",
        "customcssprotected": "Tu no es permeteda a edita esta paje de CSS, car lo conteni la preferes personal de un otra usor.",
+       "customjsonprotected": "Tu no es permeteda a edita esta paje de JSON, car lo conteni la preferes personal de un otra usor.",
        "customjsprotected": "Tu no es permeteda a edita esta paje de JavaScript, car lo conteni la preferes personal de un otra usor.",
        "mycustomcssprotected": "Tu no es permeteda a edita esta paje de CSS.",
+       "mycustomjsonprotected": "Tu no es permeteda a edita esta paje de JSON.",
        "mycustomjsprotected": "Tu no es permeteda a edita esta paje de JavaScript.",
        "myprivateinfoprotected": "Tu no es permeteda a edita tua informas privata.",
        "mypreferencesprotected": "Tu no es permeteda a edita tua preferes.",
        "nowiki_sample": "Ajunta asi testo nonformatida",
        "nowiki_tip": "Iniora sintatica de vici",
        "image_tip": "Fix interna",
-       "media_tip": "Lia a un fix",
+       "media_tip": "Lia de fix",
        "sig_tip": "Tua suscrive con indica de ora",
        "hr_tip": "Linia orizonal (per usas rara)",
        "summary": "Resoma:",
        "savechanges": "Fisa cambias",
        "publishpage": "Publici paje",
        "publishchanges": "Publici cambias",
+       "publishchanges-start": "Publici cambias...",
        "preview": "Previde",
        "showpreview": "Mostra previde",
        "showdiff": "Mostra cambias",
        "listduplicatedfiles": "Lista de fixes jemelo",
        "listduplicatedfiles-summary": "Esta es un lista de fixes de cual sua revisa la plu resente es identica con la revisa la plu resente de alga otra fix. Sola fixes local es considerada.",
        "listduplicatedfiles-entry": "[[:File:$1|$1]] ave [[$3|{{PLURAL:$2|un jemelo|$2 jemelos}}]].",
-       "unusedtemplates": "modeles nonusada",
+       "unusedtemplates": "Modeles nonusada",
        "unusedtemplatestext": "Esta paje lista tota pajes en la spasio de nom {{ns:template}} cual no es incluida en un otra paje.\nNo oblida esplora otra lias a la stensiles ante sutrae los.",
        "unusedtemplateswlh": "otra lias",
        "randompage": "Paje acaso",
        "listusers-submit": "Mostra",
        "listusers-noresult": "No usor trovada.",
        "listusers-blocked": "(impedida)",
-       "activeusers": "Lista ativa de usores",
+       "activeusers": "Lista de usores ativa",
        "activeusers-intro": "Esta es un lista de usores ci ia es ativa en alga modo en la {{PLURAL:$1|dia|dias}} la plu resente.",
        "activeusers-count": "$1 {{PLURAL:$1|ata|atas}} en la {{PLURAL:$3|dia|$3 dias}} la plu resente.",
        "activeusers-from": "Mostra usores comensante a:",
        "whatlinkshere": "Lias a esta paje",
        "whatlinkshere-title": "Pajes cual lia a \"$1\"",
        "whatlinkshere-page": "Paje:",
-       "linkshere-2": "La pajes seguente lia a <strong>$1</strong>:",
-       "nolinkshere-2": "No pajes lia a <strong>$1</strong>.",
-       "nolinkshere-ns-2": "No pajes lia a <strong>$1</strong> en la spasio de nom elejeda.",
+       "linkshere": "La pajes seguente lia a <strong>$2</strong>:",
+       "nolinkshere": "No pajes lia a <strong>$2</strong>.",
+       "nolinkshere-ns": "No pajes lia a <strong>$2</strong> en la spasio de nom elejeda.",
        "isredirect": "paje redirijente",
        "istemplate": "transclui",
        "isimage": "lia de fix",
        "tooltip-pt-watchlist": "Un lista de pajes cual tu monitori per cambias",
        "tooltip-pt-mycontris": "Un lista de tua contribuis",
        "tooltip-pt-anoncontribs": "Un lista de editas fada de esta adirije IP",
-       "tooltip-pt-login": "Nos recomenda ce tu autentici, ma esta no es no obligante",
+       "tooltip-pt-login": "Nos recomenda ce tu autentici, ma esta no es obligante",
        "tooltip-pt-login-private": "Tu nesesa autentici per usa esta vici",
        "tooltip-pt-logout": "Desautentici",
        "tooltip-pt-createaccount": "Nos recomenda ce tu crea un conta e autentici, ma esta no es obligante",
        "markedaspatrollederrornotify": "La marca como patruliada ia fali.",
        "patrol-log-page": "Arcivo de patrulias",
        "patrol-log-header": "Esta es un rejistra de revisas patruliada.",
-       "log-show-hide-patrol": "$1 rejistra de patrulias",
-       "log-show-hide-tag": "$1 rejistra de eticetas",
        "confirm-markpatrolled-button": "Oce",
        "confirm-markpatrolled-top": "Marca revisa $3 de $2 como patruliada?",
        "deletedrevision": "Sutrae revisa vea $1",
        "logentry-delete-restore": "$1 {{GENDER:$2|restora}} paje $3 ($4)",
        "logentry-delete-restore-nocount": "$1 {{GENDER:$2|restora}} paje $3",
        "restore-count-revisions": "{{PLURAL:$|1 revisa|$1 revisas}}",
-       "restore-count-files": "{{PLURAL:$|1 fix|$1 fixes}}",
+       "restore-count-files": "{{PLURAL:$1|1 fix|$1 fixes}}",
        "logentry-delete-event": "$1 {{GENDER:$2|cambia}} la vidablia de {{PLURAL:$5|un entrada|$5 entradas}} de rejistra en $3: $4",
        "logentry-delete-revision": "$1 {{GENDER:$2|cambia}} la vidablia de {{PLURAL:$5|un revisa|$5 revisas}} en paje $3: $4",
        "logentry-delete-event-legacy": "$1 {{GENDER:$2|cambia}} la vidablia de entradas de rejistra en $3",
index d6f438e..fe1221f 100644 (file)
@@ -3,7 +3,8 @@
                "authors": [
                        "Kizito",
                        "아라",
-                       "Macofe"
+                       "Macofe",
+                       "Erinamukuta"
                ]
        },
        "tog-underline": "Enyunzi ebengako olukoloboze?",
        "nstab-template": "Lutiba",
        "nstab-help": "Buyambi",
        "nstab-category": "Ttuluba lya",
+       "mainpage-nstab": "Olupapula Olusinga Omugaso",
        "nosuchaction": "Ekikolwa ekyo tekisoboka",
        "nosuchactiontext": "Ekikolwa ekikongojedwa mu URL tekisoboka.<br />\nOyinza okuba nga URL wagiwandise bubi, oba yo URL y'eyinza okuba nga ya nsobi.<br />\nKiyinza ate okuba nti sofutiweya {{SITENAME}} gy'ekozesa erimu ebitali bituufu.",
        "nosuchspecialpage": "Olwo olupapula olwawule teruliwo",
        "whatlinkshere": "Empapula ezikuggusa ku luno",
        "whatlinkshere-title": "Empapula eziriko enyunzi ezigguka ku $1",
        "whatlinkshere-page": "Lupapula:",
-       "linkshere-2": "Zino z'empapula eziriko enyunzi ezigguka ku '''$1''':",
-       "nolinkshere-2": "Tewali mpapula eziriko enyunzi ezigguka ku '''$1'''.",
+       "linkshere": "Zino z'empapula eziriko enyunzi ezigguka ku '''$2''':",
+       "nolinkshere": "Tewali mpapula eziriko enyunzi ezigguka ku '''$2'''.",
        "isredirect": "lupapula olukutwalabutwazi ku lunnaalwo",
        "istemplate": "kitundu ekyeyazike",
        "isimage": "lukozesa ekifaananyi kino",
index a86d842..f7db609 100644 (file)
        "whatlinkshere": "Links nao dees pagina",
        "whatlinkshere-title": "Pagina's die verwieze nao \"$1\"",
        "whatlinkshere-page": "Pagina:",
-       "linkshere-2": "De volgende pagina's verwieze nao '''$1''':",
-       "nolinkshere-2": "D'r zint gein pazjena's mit links nao '''$1''' haer.",
-       "nolinkshere-ns-2": "Geine inkele pazjena link nao '''$1''' in de gekaoze naamruumde.",
+       "linkshere": "De volgende pagina's verwieze nao '''$2''':",
+       "nolinkshere": "D'r zint gein pazjena's mit links nao '''$2''' haer.",
+       "nolinkshere-ns": "Geine inkele pazjena link nao '''$2''' in de gekaoze naamruumde.",
        "isredirect": "redirect pagina",
        "istemplate": "ingevoog es sjabloon",
        "isimage": "bestandjslink",
        "markedaspatrollederrornotify": "Markere es gecontroleerd mislök.",
        "patrol-log-page": "Markeerlogbook",
        "patrol-log-header": "Dit logbook bevat versies die gemarkeerd zeen es gecontroleerd.",
-       "log-show-hide-patrol": "Markeerlogbook $1",
-       "log-show-hide-tag": "$1 labellogbook",
        "confirm-markpatrolled-button": "Ok",
        "confirm-markpatrolled-top": "Markeer bewirking $3 van $2 es gecontroleerd?",
        "deletedrevision": "Aw versie $1 gewis",
index fea67cc..3849fa2 100644 (file)
        "whatlinkshere": "Cöse se colega chì",
        "whatlinkshere-title": "Pàgine c'apontàn a $1",
        "whatlinkshere-page": "Pàgina:",
-       "linkshere-2": "E pàgine segoenti apontan a '''$1''':",
-       "nolinkshere-2": "Nisciùnn-a pàgina a se collega con '''$1'''.",
-       "nolinkshere-ns-2": "Pagine ch'apontan a '''$1''' into namespace seleçionou no ghe n'è.",
+       "linkshere": "E pàgine segoenti apontan a '''$2''':",
+       "nolinkshere": "Nisciùnn-a pàgina a se collega con '''$2'''.",
+       "nolinkshere-ns": "Pagine ch'apontan a '''$2''' into namespace seleçionou no ghe n'è.",
        "isredirect": "Paggina de rindirissamento",
        "istemplate": "Incluxon",
        "isimage": "Colegaménto a-o file",
        "markedaspatrollederrornotify": "Errô durante a veifica.",
        "patrol-log-page": "Modiffiche controlæ",
        "patrol-log-header": "Questo o l'è 'n registro de revixoin controlæ.",
-       "log-show-hide-patrol": "$1 registro di controlli",
-       "log-show-hide-tag": "$1 registro di etichette",
        "confirm-markpatrolled-button": "OK",
        "confirm-markpatrolled-top": "Marca verscion $3 de $2 comme veificâ?",
        "deletedrevision": "Scassou a vegia verscion de $1.",
index 4f060a4..2e98cb9 100644 (file)
@@ -11,7 +11,8 @@
                        "Ebraminio",
                        "Process cq",
                        "Alirezaaa",
-                       "Fitoschido"
+                       "Fitoschido",
+                       "Matěj Suchánek"
                ]
        },
        "tog-underline": "خط کیشائن ژێر پیوندەل:",
        "copyrightwarning": "لطفاً توجه داشته‌باشید که همهٔ مشارکت‌ها در {{SITENAME}} منتشرشده تحت $2 در نظر گرفته‌می‌شوند (برای جزئیات بیش‌تر $1 را ببینید).\nاگر نمی‌خواهید نوشته‌هایتان بی‌رحمانه ویرایش و توزیع شوند؛ بنابراین، آنها را اینجا ارائه نکنید.<br />\nشما همچنین به ما تعهد می‌کنید که خودتان این را نوشته‌اید یا آن را از یک منبع با مالکیت عمومی یا مشابه آزاد آن برداشته‌اید (برای جزئیات بیش‌تر $1 را ببینید).\n<strong>کارهای دارای حق تکثیر را بدون اجازه ارائه نکنید!</strong>",
        "copyrightwarning2": "لطفاً توجه داشته‌باشید که همهٔ مشارکت‌ها در {{SITENAME}} ممکن است توسط دیگر مشارکت‌کنندگان تغییر یابند، ویرایش یا حذف شوند.\nاگر نمی‌خواهید نوشته‌هایتان بی‌رحمانه ویرایش شوند؛ بنابراین، آنها را اینجا ارائه نکنید.<br />\nشما همچنین به ما تعهد می‌کنید که خودتان این را نوشته‌اید یا آن را از یک منبع با مالکیت عمومی یا مشابه آزاد آن برداشته‌اید ($1 را برای جزئیات بیشتر ببینید).\n<strong>کارهای دارای حق تکثیر را بدون اجازه ارائه نکنید!</strong>",
        "editpage-cannot-use-custom-model": "مدل محتوای این صفحه نمی‌تواند عوض شود.",
-       "longpageerror": "'''خطا: متنی که ارسال کرده‌اید {{PULAR:$1|یک کیلوبایت|$1 کیلوبایت}} طول دارد. این مقدار از مقدار بیشینهٔ {{PLURAL:$2|یک کیلوبایت|$2 کیلوبایت}} بیشتر است.'''\nنمی‌توان آن را ذخیره کرد.",
+       "longpageerror": "'''خطا: متنی که ارسال کرده‌اید {{PLURAL:$1|یک کیلوبایت|$1 کیلوبایت}} طول دارد. این مقدار از مقدار بیشینهٔ {{PLURAL:$2|یک کیلوبایت|$2 کیلوبایت}} بیشتر است.'''\nنمی‌توان آن را ذخیره کرد.",
        "readonlywarning": "<strong>هشدار: پایگاه داده برای نگهداری قفل شده‌است، به همین علت هم‌اکنون نمی‌توانید ویرایش‌هایتان را ذخیره کنید.</strong>\nاگر می‌خواهید متن را در یک پروندهٔ متنی کپی کنید و برای آینده ذخیره‌اش کنید.\n\nمدیری که آن را قفل کرده این توضیح را ارائه کرده‌است: $1",
        "protectedpagewarning": "'''هشدار: این صفحه قفل شده‌است تا فقط کاربران با دسترسی مدیریت بتوانند ویرایشش کنند.'''\nآخرین موارد سیاهه در زیر آمده‌است:",
        "semiprotectedpagewarning": "'''توجه:''' این صفحه قفل شده‌است تا تنها کاربران ثبت‌نام‌کرده قادر به ویرایش آن باشند.\nآخرین موارد سیاهه در زیر آمده‌است:",
        "whatlinkshere": "پیوندەل وە ئێ وەڵگە",
        "whatlinkshere-title": "وۀلگۀلئ گإ  وۀ «$1» پیوۀند دِرِن",
        "whatlinkshere-page": ":وةڵگە(پەڕە)",
-       "linkshere-2": "The following pages link to <strong>$1</strong>:",
-       "nolinkshere-2": "هیچ صفحه‌ای به '''$1''' پیوند ندارد.",
-       "nolinkshere-ns-2": "هیچ صفحه‌ای از فضای نام انتخاب شده به '''$1''' پیوند ندارد.",
+       "linkshere": "The following pages link to <strong>$2</strong>:",
+       "nolinkshere": "هیچ صفحه‌ای به '''$2''' پیوند ندارد.",
+       "nolinkshere-ns": "هیچ صفحه‌ای از فضای نام انتخاب شده به '''$2''' پیوند ندارد.",
        "isredirect": "وەڵگە ڕێ گؤەڕن(تغییرمسییر)",
        "istemplate": " تراگنجانش‌ها",
        "isimage": "پیوند پرونده",
        "markedaspatrollederrornotify": "زدن برچسب گشت، ناموفق بود.",
        "patrol-log-page": "سیاههٔ گشت",
        "patrol-log-header": "این سیاهه‌ای از ویرایش‌های گشت‌خورده است.",
-       "log-show-hide-patrol": "$1 سیاههٔ گشت‌زنی",
-       "log-show-hide-tag": "$1 سیاهه برچسب",
        "deletedrevision": "$1 نسخهٔ حذف شدهٔ قدیمی",
        "filedeleteerror-short": "خطا در حذف پرونده: $1",
        "filedeleteerror-long": "در زمان حذف پرونده خطا رخ داد:\n\n$1",
index a4fb8c9..d66f127 100644 (file)
        "whatlinkshere": "Pagin che se culeghen chì",
        "whatlinkshere-title": "Paginn che menen a \"$1\"",
        "whatlinkshere-page": "Pagina:",
-       "linkshere-2": "I paginn chì de sota gh'hann di ligam che porten a '''$1''':",
+       "linkshere": "I paginn chì de sota gh'hann di ligam che porten a '''$2''':",
        "isredirect": "redirezión",
        "istemplate": "inclüsión",
        "isimage": "ligam a un archivi",
index 84fcc2c..14c9294 100644 (file)
        "sp-contributions-submit": "ຊອກຫາ",
        "whatlinkshere": "ໜ້າທີ່ເຊື່ອມຕໍ່ມາໜ້ານີ້",
        "whatlinkshere-title": "ໜ້າທີ່ເຊື່ອມຕໍ່ຫາ $1",
-       "linkshere-2": "ບັນດາໜ້າຕໍ່ໄປ ລິ້ງຄ໌ ຫາ ''$1''':",
-       "nolinkshere-2": "ບໍ່ມີໜ້າລິ້ງຄ໌ ຫາ '''$1'''.",
-       "nolinkshere-ns-2": "ບໍ່ມີໜ້າລິ້ງຄ໌ ຫາ '''$1''' ໃນ ຂອບເຂດຊື່ ທີ່ ທ່ານເລືອກ.",
+       "linkshere": "ບັນດາໜ້າຕໍ່ໄປ ລິ້ງຄ໌ ຫາ ''$2''':",
+       "nolinkshere": "ບໍ່ມີໜ້າລິ້ງຄ໌ ຫາ '''$2'''.",
+       "nolinkshere-ns": "ບໍ່ມີໜ້າລິ້ງຄ໌ ຫາ '''$2''' ໃນ ຂອບເຂດຊື່ ທີ່ ທ່ານເລືອກ.",
        "isredirect": "ໜ້າໂອນ",
        "istemplate": "ລວມ",
        "whatlinkshere-prev": "{{PLURAL:$1|ກ່ອນ|ກ່ອນ $1}}",
index a8146a8..82d0b26 100644 (file)
        "whatlinkshere": "Ling'ki di bye petulo",
        "whatlinkshere-title": "Petulo bye ling'ki di $1",
        "whatlinkshere-page": "Petulo:",
-       "linkshere-2": "Bye petulo ling'ki di '''$1''':",
-       "nolinkshere-2": "0 petulo ling'ki di '''$1'''.",
-       "nolinkshere-ns-2": "0 petulo ling'ki di '''$1''' bye sa di bye fatukile efro.",
+       "linkshere": "Bye petulo ling'ki di '''$2''':",
+       "nolinkshere": "0 petulo ling'ki di '''$2'''.",
+       "nolinkshere-ns": "0 petulo ling'ki di '''$2''' bye sa di bye fatukile efro.",
        "isredirect": "petulo abezi",
        "istemplate": "yang'idole",
        "whatlinkshere-prev": "{{PLURAL:$1|kona|kona $1}}",
index e822bba..ab62a89 100644 (file)
        "whatlinkshere": "کوم هوم پیۋندیا هان ایچاٛ",
        "whatlinkshere-title": "بلگه ای که د $1 هوم پیوند بیه",
        "whatlinkshere-page": "بلگٱ",
-       "linkshere-2": "بلگیا نهایی د '''$1''' هوم پیوند بیه",
-       "nolinkshere-2": "هیژ بگله ای د  '''$1''' هوم پیوند نبیه",
-       "nolinkshere-ns-2": "هیچ بلگه ای د نومجا انتخاو بیه وه'''$1''' هوم پیوند ناره.",
+       "linkshere": "بلگیا نهایی د '''$2''' هوم پیوند بیه",
+       "nolinkshere": "هیژ بگله ای د  '''$2''' هوم پیوند نبیه",
+       "nolinkshere-ns": "هیچ بلگه ای د نومجا انتخاو بیه وه'''$2''' هوم پیوند ناره.",
        "isredirect": "بلگه دوباره ورگشتن",
        "istemplate": "نشونی دئن",
        "isimage": "جانیا هوم پیوند",
        "markedaspatrollederrornotify": "نشودار کردن چی نشودار بیه شکست حرده",
        "patrol-log-page": "پهرستنومه گشتن",
        "patrol-log-header": "یه پهرستنومه وانئریا سردیاری کرده هئ.",
-       "log-show-hide-patrol": "$1 پهرستنومه سردیاری کردن",
-       "log-show-hide-tag": "سردیس پهرستنومه $1",
        "deletedrevision": "وانئری دماتری پاکسابیه د $1",
        "filedeleteerror-short": "خطا پاک نبیئن جانیا:$1",
        "filedeleteerror-long": "د گات پاکسا کردن جانیا یه گل خطا پیش اوما:\n\n\n$1",
index 4387feb..78a2748 100644 (file)
@@ -38,7 +38,8 @@
                        "Nemo bis",
                        "Nersip",
                        "Manvydasz",
-                       "Fitoschido"
+                       "Fitoschido",
+                       "Matěj Suchánek"
                ]
        },
        "tog-underline": "Nuorodos pabraukimas:",
        "create": "Sukurti",
        "create-local": "Pridėti vietos aprašymą",
        "delete": "Trinti",
-       "undelete_short": "Atkurti $1 {{PLURAL:$1:redagavimą|redagavimus|redagavimų}}",
+       "undelete_short": "Atkurti $1 {{PLURAL:$1|redagavimą|redagavimus|redagavimų}}",
        "viewdeleted_short": "Peržiūrėti $1 {{PLURAL:$1|ištrintą keitimą|ištrintus keitimus|ištrintų keitimų}}",
        "protect": "Užrakinti",
        "protect_change": "keisti",
        "subject-preview": "Temos peržiūra:",
        "previewerrortext": "Įvyko klaida bandant peržiūrėti jūsų pakeitimus.",
        "blockedtitle": "Naudotojas yra užblokuotas",
-       "blockedtext": "'''Jūsų naudotojo vardas arba IP adresas yra užblokuotas.'''\n\nUžblokavo $1. Nurodyta priežastis yra ''$2''.\n\n* Blokavimo pradžia: $8\n* Blokavimo pabaiga: $6\n* Užblokuotasis: $7\n\nJūs galite susisiekti su $1 arba kuriuo nors kitu [[{{MediaWiki:Grouppage-sysop}}|administratoriumi]] ir aptarti neaiškumus dėl blokavimo.\nAtkreipkite dėmesį, kad negalėsite naudotis funkcija „Rašyti laišką šiam naudotojui“, jei nesate užsiregistravę ir pateikę galiojančio el. pašto adreso naudotojo paskyros [[Special:Preferences|nustatymuose]], arba, jei jums užblokuotas šios funkcijos naudojimas.\nJūsų IP adresas yra $3, o blokavimo ID yra #$5.\nPrašome nurodyti vieną iš jų ar abu, kai kreipiatės dėl blokavimo.",
+       "blockedtext": "'''Jūsų naudotojo vardas arba IP adresas yra užblokuotas.'''\n\nUžblokavo $1. Nurodyta priežastis yra ''$2''.\n\n* Blokavimo pradžia: $8\n* Blokavimo pabaiga: $6\n* Užblokuotasis: $7\n\nJūs galite susisiekti su $1 arba kuriuo nors kitu [[{{MediaWiki:Grouppage-sysop}}|administratoriumi]] ir aptarti neaiškumus dėl blokavimo.\nAtkreipkite dėmesį, kad negalėsite naudotis funkcija „{{int:emailuser}}“, jei nesate užsiregistravę ir pateikę galiojančio el. pašto adreso naudotojo paskyros [[Special:Preferences|nustatymuose]], arba, jei jums užblokuotas šios funkcijos naudojimas.\nJūsų IP adresas yra $3, o blokavimo ID yra #$5.\nPrašome nurodyti vieną iš jų ar abu, kai kreipiatės dėl blokavimo.",
        "autoblockedtext": "Jūsų IP adresas buvo automatiškai užblokuotas, nes jį naudojo kitas naudotojas, kurį užblokavo $1.\nNurodyta priežastis yra ši:\n\n:''$2''\n\n* Blokavimo pradžia: $8\n* Blokavimo pabaiga: $6\n* Numatomas blokavimo laikas: $7\n\nJūs galite susisiekti su $1 arba kitu [[{{MediaWiki:Grouppage-sysop}}|administratoriumi]], kad aptartumėte neaiškumus dėl blokavimo.\n\nJūs negalite naudotis funkcija „Rašyti laišką šiam naudotojui“, jei nesate nurodę tikro el. pašto adreso savo [[Special:Preferences|naudotojo nustatymuose]]. Taip pat Jūs negalite naudotis šia funkcija, jei Jums užblokuotas jos naudojimas.\n\nJūsų IP adresas yra $3, blokavimo ID yra $5.\nPrašome nurodyti šiuos duomenis visais atvejais, kai kreipiatės dėl blokavimo.",
        "blockednoreason": "priežastis nenurodyta",
        "whitelistedittext": "Jūs turite $1, kad redaguotumėte puslapius.",
        "rcfilters-other-review-tools": "Kiti peržiūros įrankiai",
        "rcfilters-group-results-by-page": "Grupuoti rezultatus pagal puslapį",
        "rcfilters-activefilters": "Aktyvūs filtrai",
+       "rcfilters-activefilters-hide": "Slėpti",
+       "rcfilters-activefilters-show": "Rodyti",
+       "rcfilters-activefilters-hide-tooltip": "Slėpti aktyvių filtrų sritį",
+       "rcfilters-activefilters-show-tooltip": "Rodyti aktyvių filtrų sritį",
        "rcfilters-advancedfilters": "Detalūs filtrai",
        "rcfilters-limit-title": "Rodyti rezultatų",
        "rcfilters-limit-and-date-label": "$1 {{PLURAL:$1|keitimas|keitimai|keitimų}}, $2",
        "rcfilters-savedqueries-rename": "Pervadinti",
        "rcfilters-savedqueries-setdefault": "Nustatyti kaip numatytą",
        "rcfilters-savedqueries-unsetdefault": "Pašalinti kaip numatytą",
-       "rcfilters-savedqueries-remove": "Pašalinti",
+       "rcfilters-savedqueries-remove": "Ištrinti",
        "rcfilters-savedqueries-new-name-label": "Pavadinimas",
        "rcfilters-savedqueries-new-name-placeholder": "Apibūdinkite šio filtro tikslą",
        "rcfilters-savedqueries-apply-label": "Sukurti filtrą",
        "rcfilters-empty-filter": "Nėra aktyvių filtrų. Rodomi visi indėliai.",
        "rcfilters-filterlist-title": "Filtrai",
        "rcfilters-filterlist-whatsthis": "Kaip tai veikia?",
-       "rcfilters-filterlist-feedbacklink": "Pateikite atsiliepimą apie šiuos (naujus) filtravimo įrankius",
+       "rcfilters-filterlist-feedbacklink": "Pateikite atsiliepimą apie šiuos filtravimo įrankius",
        "rcfilters-highlightbutton-title": "Paryškinti rezultatus",
        "rcfilters-highlightmenu-title": "Pasirinkite spalvą",
        "rcfilters-highlightmenu-help": "Pasirinkite spalvą šio elemento paryškinimui",
        "whatlinkshere": "Susiję puslapiai",
        "whatlinkshere-title": "Puslapiai, kurie nurodo į „$1“",
        "whatlinkshere-page": "Puslapis:",
-       "linkshere-2": "Šie puslapiai rodo į '''$1''':",
-       "nolinkshere-2": "Į '''$1''' nuorodų nėra.",
-       "nolinkshere-ns-2": "Nurodytoje vardų srityje nei vienas puslapis nenurodo į '''$1'''.",
+       "linkshere": "Šie puslapiai rodo į '''$2''':",
+       "nolinkshere": "Į '''$2''' nuorodų nėra.",
+       "nolinkshere-ns": "Nurodytoje vardų srityje nei vienas puslapis nenurodo į '''$2'''.",
        "isredirect": "nukreipiamasis puslapis",
        "istemplate": "įterpimas",
        "isimage": "rinkmenos nuoroda",
        "markedaspatrollederrornotify": "Nepavyko pažymėti kaip patikrinto.",
        "patrol-log-page": "Patikrinimų sąrašas",
        "patrol-log-header": "Tai patvirtintų versijų sąrašas.",
-       "log-show-hide-patrol": "$1 patvirtinimų sąrašą",
-       "log-show-hide-tag": "$1 žymės žurnalas",
        "confirm-markpatrolled-button": "GERAI",
        "deletedrevision": "Ištrinta sena versija $1",
        "filedeleteerror-short": "Klaida trinant rinkmeną: $1",
index 97c76b0..d7c7e26 100644 (file)
        "whatlinkshere": "Hemi zawmpuite",
        "whatlinkshere-title": "$1-a thlunzawm phêkte",
        "whatlinkshere-page": "Phêk:",
-       "linkshere-2": "A hnuaia phêkte hian '''$1''' hi an thlunzawm:",
-       "nolinkshere-2": "'''$1'''-a zawm phek pakhat mah a awm lo.",
+       "linkshere": "A hnuaia phêkte hian '''$2''' hi an thlunzawm:",
+       "nolinkshere": "'''$2'''-a zawm phek pakhat mah a awm lo.",
        "isredirect": "Hruailuhna phêk",
        "istemplate": "ziahhnan",
        "isimage": "taksa thlunzawmna",
        "markedaspatrolledtext": "[[:$1]] ennawnna thlansa hi vil anga chhinchhiah a ni.",
        "markedaspatrollederror": "Vil anga chhinchhiah theih a ni lo",
        "patrol-log-page": "Vil chhinchhiahna",
-       "log-show-hide-patrol": "Vil chhinchhiahna $1",
        "filedeleteerror-long": "Taksa paih tum laiin buaina a lo thleng\n\n$1",
        "previousdiff": "←Siamţhatna hlui zâwk",
        "nextdiff": "Siamţhatna thar zâwk→",
index a474cd4..d55e07a 100644 (file)
        "whatlinkshere": "لینکل ئی بألگە",
        "whatlinkshere-title": "بألگل کە لینک دائنە ڤە \"$1\"",
        "whatlinkshere-page": "بألگە:",
-       "linkshere-2": "لینک ھ بألگل دوٙمین الذیکر ڤە '''$1''':",
+       "linkshere": "لینک ھ بألگل دوٙمین الذیکر ڤە '''$2''':",
        "isredirect": "بألگە تأغییر مأسیر",
        "istemplate": "ئیستیفادھ ڤابیدھ داخل بألگە",
        "isimage": "لینک ھ فایل",
index 2edaca7..e3a3066 100644 (file)
        "botpasswords-existing": "Esošās botu paroles",
        "botpasswords-createnew": "Izveidot jaunu bota paroli",
        "botpasswords-editexisting": "Rediģētu esošu bota paroli",
+       "botpasswords-label-needsreset": "(paroli nepieciešams atiestatīt)",
        "botpasswords-label-appid": "Bota nosaukums:",
        "botpasswords-label-create": "Izveidot",
        "botpasswords-label-update": "Atjaunināt",
        "botpasswords-created-title": "Bota parole izveidota",
        "botpasswords-updated-title": "Bota parole atjaunināta",
        "botpasswords-deleted-title": "Bota parole dzēsta",
+       "botpasswords-restriction-failed": "Botu paroles ierobežojumi liedz šo pieslēgšanos.",
        "resetpass_forbidden": "Paroles nav iespējams nomainīt",
        "resetpass_forbidden-reason": "Paroles nav iespējams nomainīt: $1",
        "resetpass-no-info": "Jums ir nepieciešams ieiet, lai tūlīt piekļūtu šai lapai.",
        "grant-generic": "\"$1\" tiesību paka",
        "grant-group-page-interaction": "Darboties ar lapām",
        "grant-group-file-interaction": "Darboties ar multimediju failiem",
+       "grant-group-watchlist-interaction": "Darboties ar tavu uzraugāmo lapu sarakstu",
        "grant-group-email": "Sūtīt e-pastu",
        "grant-group-high-volume": "Veikt liela apjoma aktivitātes",
        "grant-group-administration": "Veikt administratīvās darbības",
        "grant-group-private-information": "Piekļūt privātiem datiem par tevi",
+       "grant-group-other": "Dažādas darbības",
        "grant-blockusers": "Bloķēt un atbloķēt dalībniekus",
        "grant-createaccount": "Izveidot kontu",
        "grant-createeditmovepage": "Izveidot, labot un pārvietot lapas",
        "grant-uploadfile": "Augšupielādēt jaunus failus",
        "grant-basic": "Pamattiesības",
        "grant-viewdeleted": "Skatīt dzēstos failus un lapas",
+       "grant-viewmywatchlist": "Skatīt tavu uzraugāmo rakstu sarakstu",
        "newuserlogpage": "Jauno dalībnieku reģistrs",
        "newuserlogpagetext": "Jauno lietotājvārdu reģistrs.",
        "rightslog": "Dalībnieku tiesību reģistrs",
        "rcfilters-filter-minor-description": "Labojumi, kas atzīmēti kā maznozīmīgi.",
        "rcfilters-filter-major-label": "Nozīmīgi labojumi",
        "rcfilters-filter-major-description": "Labojumi, kas nav atzīmēti kā maznozīmīgi.",
+       "rcfilters-filtergroup-watchlist": "Uzraugāmie raksti",
        "rcfilters-filter-watchlist-watchednew-description": "Izmaiņas uzraugāmajās lapās, kuras nav apmeklētas kopš izmaiņu veikšanas.",
        "rcfilters-filter-watchlistactivity-unseen-label": "Neapskatītas izmaiņas",
        "rcfilters-filter-watchlistactivity-unseen-description": "Izmaiņas lapās, kuras nav apmeklētas kopš izmaiņu veikšanas.",
        "activeusers-submit": "Parādīt aktīvos dalībniekus",
        "listgrouprights": "Dalībnieku grupu tiesības",
        "listgrouprights-summary": "Šis ir šajā viki definēto dalībnieku grupu uzskaitījums, kopā ar tām atbilstošajām piekļuves tiesībām.\nPapildu informāciju par katru individuālu piekļuves tiesību veidu, iespējams, var atrast [[{{MediaWiki:Listgrouprights-helppage}}|šeit]].",
+       "listgrouprights-key": "Apzīmējumi:\n* <span class=\"listgrouprights-granted\">Piešķirtās tiesības</span>\n* <span class=\"listgrouprights-revoked\">Atceltās tiesības</span>",
        "listgrouprights-group": "Grupa",
        "listgrouprights-rights": "Tiesības",
        "listgrouprights-helppage": "Help:Grupu tiesības",
        "whatlinkshere": "Norādes uz šo rakstu",
        "whatlinkshere-title": "Lapas, kurās ir saites uz lapu \"$1\"",
        "whatlinkshere-page": "Lapa:",
-       "linkshere-2": "Šajās lapās ir norādes uz lapu '''$1''':",
-       "nolinkshere-2": "Nevienā lapā nav norāžu uz lapu '''$1'''.",
-       "nolinkshere-ns-2": "Neviena lapa nenorāda uz '''$1''' izvēlētajā vārdtelpā.",
+       "linkshere": "Šajās lapās ir norādes uz lapu '''$2''':",
+       "nolinkshere": "Nevienā lapā nav norāžu uz lapu '''$2'''.",
+       "nolinkshere-ns": "Neviena lapa nenorāda uz '''$2''' izvēlētajā vārdtelpā.",
        "isredirect": "pāradresācijas lapa",
        "istemplate": "izsaukts",
        "isimage": "faila saite",
        "markedaspatrollednotify": "Šī izmaiņa lapā \"$1\" ir atzīmēta kā patrulēta.",
        "patrol-log-page": "Pārbaudes reģistrs",
        "patrol-log-header": "Šis ir pārbaudīto versiju reģistrs.",
-       "log-show-hide-patrol": "$1 pārbaudes reģistrs",
        "confirm-markpatrolled-button": "Labi",
        "confirm-markpatrolled-top": "Atzīmēt lapas \"$2\" versiju $3 kā pārbaudītu?",
        "deletedrevision": "Izdzēstā vecā versija $1",
index 6f9503b..43496d7 100644 (file)
        "whatlinkshere": "取佐",
        "whatlinkshere-title": "「$1」取佐",
        "whatlinkshere-page": "題",
-       "linkshere-2": "取佐'''$1'''如下:",
-       "nolinkshere-2": "無頁取佐'''$1'''。",
-       "nolinkshere-ns-2": "名冊內無頁取佐'''$1'''。",
+       "linkshere": "取佐'''$2'''如下:",
+       "nolinkshere": "無頁取佐'''$2'''。",
+       "nolinkshere-ns": "名冊內無頁取佐'''$2'''。",
        "isredirect": "渡",
        "istemplate": "含",
        "isimage": "檔佐",
        "markedaspatrollederror-noautopatrol": "己易不可自審。",
        "patrol-log-page": "誌哨",
        "patrol-log-header": "此乃誌哨也。",
-       "log-show-hide-patrol": "$1誌巡",
        "deletedrevision": "刪舊審$1",
        "filedeleteerror-short": "刪檔有誤:$1",
        "filedeleteerror-long": "刪檔有誤:\n\n$1",
index 381e60a..0fecdc4 100644 (file)
        "whatlinkshere": "Butʼkʼaşa na ixvenu kʼontʼaktʼepe",
        "whatlinkshere-title": "\"$1\" maddeşa kʼontʼaktʼi na ikips butʼkʼape",
        "whatlinkshere-page": "Butʼkʼa:",
-       "linkshere-2": "'''$1''' butʼkʼaşa kʼontʼaktʼi na ikips butʼkʼape:",
+       "linkshere": "'''$2''' butʼkʼaşa kʼontʼaktʼi na ikips butʼkʼape:",
        "isredirect": "redirektʼiş butʼkʼa",
        "istemplate": "okʼatu",
        "isimage": "dosyaşi kʼontʼaktʼi",
index 63b2084..d4c3e75 100644 (file)
        "whatlinkshere": "एतय कोन लिङ्क अछि",
        "whatlinkshere-title": "\"$1\" सँ सम्बन्धित पन्नासभ",
        "whatlinkshere-page": "पन्ना:",
-       "linkshere-2": "ई सभ पन्ना सम्बन्धित अछि '''$1''':",
-       "nolinkshere-2": "'''$1''' पर कोनो पन्नाक लागि नै अछि।",
-       "nolinkshere-ns-2": "कोनो पन्नाक लागि '''$1''' चुनल नामगाममे नै अछि।",
+       "linkshere": "ई सभ पन्ना सम्बन्धित अछि '''$2''':",
+       "nolinkshere": "'''$2''' पर कोनो पन्नाक लागि नै अछि।",
+       "nolinkshere-ns": "कोनो पन्नाक लागि '''$2''' चुनल नामगाममे नै अछि।",
        "isredirect": "पुनर्निर्देशन पृष्ठ",
        "istemplate": "परागत",
        "isimage": "फाइल लिङ्क",
        "markedaspatrollederrornotify": "जाँचल चिन्हासी असफल भेल।",
        "patrol-log-page": "परीक्षण लौग",
        "patrol-log-header": "ई परीक्षित अवतरणसभक लौग छी।",
-       "log-show-hide-patrol": "$1 निरीक्षण लौग",
-       "log-show-hide-tag": "$1 ट्याग लग",
        "deletedrevision": "पुरान संशोधन $1 हटा देलौं",
        "filedeleteerror-short": "संचिका मेटेबामे भ्रम : $1",
        "filedeleteerror-long": "संचिका मेटेबा काल भ्रम संकेत भेटल:\n$1",
index c5b6f61..2bb8ea7 100644 (file)
        "whatlinkshere": "Pranala Kaca Kiye",
        "whatlinkshere-title": "Kaca-kaca sing duwe pranala maring \"$1\"",
        "whatlinkshere-page": "Kaca:",
-       "linkshere-2": "Kaca-kaca kiye duwe pranala maring '''$1''':",
-       "nolinkshere-2": "Ora ana kaca sing nduwé pranala maring '''$1'''.",
+       "linkshere": "Kaca-kaca kiye duwe pranala maring '''$2''':",
+       "nolinkshere": "Ora ana kaca sing nduwé pranala maring '''$2'''.",
        "isredirect": "kaca pangalihan",
        "istemplate": "karo cithakan",
        "isimage": "pranala berkas",
index e236da3..8f4fd3c 100644 (file)
        "whatlinkshere": "Сюлмафкст тяза",
        "whatlinkshere-title": "Лопат конат сюлмафт \"$1\" мархта",
        "whatlinkshere-page": "Лопа:",
-       "linkshere-2": "Ся лопатне сюлмафт '''$1''' мархта:",
-       "nolinkshere-2": "Лопат, конат сюлмафт '''$1''' мархта ашет.",
-       "nolinkshere-ns-2": "Аш лопат сюлмафт '''$1''' мархта  кочкаф лемботмоста.",
+       "linkshere": "Ся лопатне сюлмафт '''$2''' мархта:",
+       "nolinkshere": "Лопат, конат сюлмафт '''$2''' мархта ашет.",
+       "nolinkshere-ns": "Аш лопат сюлмафт '''$2''' мархта  кочкаф лемботмоста.",
        "isredirect": "умборондафтф лопа",
        "istemplate": "сувафтома",
        "isimage": "↓архтофксонь сюлмафкссь",
        "markedaspatrollederror-noautopatrol": "Тондейть аф мярьгови тяштемс эсь полфнемацень кода патрулень варжафт.",
        "patrol-log-page": "Патрулень лувомась",
        "patrol-log-header": "Патруль ала верзиетнень лувомась.",
-       "log-show-hide-patrol": "$1 патрулень лувомась",
        "deletedrevision": "Нардаф сире илякстоптома $1",
        "filedeleteerror-short": "Лиссь эльбятькс нардамста файл: $1",
        "filedeleteerror-long": "Лиссть эльбятькст нардамста файл:\n\n$1",
index 0467390..8d0cf62 100644 (file)
        "redirectedfrom": "(tonga teto avy amin'ny $1)",
        "redirectpagesub": "Pejy fihodinana",
        "redirectto": "Mihodina mankany:",
-       "lastmodifiedat": "Voaova farany tamin'ny $1 amin'ny $2 ity pejy ity<br />",
+       "lastmodifiedat": "Voaova farany tamin'ny $1 amin'ny $2 ity pejy ity.",
        "viewcount": "voastsidika in-$1 ity pejy ity.{{PLURAL:}}",
        "protectedpage": "Pejy voaaro",
        "jumpto": "Hanketo:",
        "cascadeprotected": "Ankehitriny dia voaaro ity pejy ity satria misy pejy voaaro {{PLURAL:$1|iray|$1}} mampiasa ity pejy ity. Io pejy io dia mampiasa ny fiarovana \"mirihana\":\n\n$2",
        "namespaceprotected": "Tsy manana alalàna manova ny toeran'anarana « '''$1''' » ianao.",
        "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.",
        "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.",
        "myprivateinfoprotected": "Tsy manana alalana ahafahana manova ny fampahalalana tsy sarababem-bahoakanao ianao.",
        "mypreferencesprotected": "Tsy manana alalana ahafahana manova ny safidinao ianao.",
        "nosuchusershort": "Tsy misy mpikambana hoe \"$1\". Hamarino ny tsipelina.",
        "nouserspecified": "Tsy maintsy mampiditra solonanarana ianao.",
        "login-userblocked": "Voasakana io mpikambana io. Fidirana tsy nahazoan-dalana.",
-       "wrongpassword": "Diso ny tenimiafina. Manandrama tenimiafina hafa azafady.",
+       "wrongpassword": "Diso ny tenimiafina. \nAndramo indray azafady.",
        "wrongpasswordempty": "Tsy nampiditra tenimiafina ianao, azafady mba avereno indray.",
        "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 manokana kokoa.",
+       "passwordtoopopular": "Tsy azo ampiasana ny tenimiafina ampiasaina matetika. Misafidiana tenimiafina sarotra vinavinaina kokoa.",
        "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",
        "passwordremindertitle": "Fampatsiahivana tenimiafina avy amin'i {{SITENAME}}",
-       "passwordremindertext": "Nisy olona, izay ianao ihany angamba, avy tamin'ny adiresy IP $1, nangataka\nny handefasanay tenimiafina vaovao ho an'ny sehatra {{SITENAME}} ao amin'ny\n$4.\nLasa \"$3\" ankehitriny ny tenimiafin'i \"$2\"\nAfaka miditra ary ianao ankehitriny ary manova ny tenimiafinao.\nLany andro anatin'ny $5 andro ny tenimiafinao\n\nRaha olon-kafa io nangataka io, na tadidinao ihany ny tenimiafinao taloha ka\ntsy irinao hovana intsony, dia fafao fotsiny ity hafatra ity dia ilay\ntenimiafina taloha ihany no ampiasao.{{PLURAL:}}",
+       "passwordremindertext": "Nisy olona (avy amin'ny adiresy IP $1) nangataka tenimiafina vaovao ho an'i {{SITENAME}} ($4). Noforonina ny tenimiafina vonjimaika ho an'ny mpikambana \"$2\" ary natao ho \"$3\". Raha ny finiavanao no nahatonga  izany, dia mila miditra ianao ary misafidy tenimiafina vaovao dien'izao.\nHitsahatra afaka {{PLURAL:$5|iray andro|$5 andro}} ny tenimiafinao.\n\nRaha olon-kafa no nanao ity hataka ity, na efa tadidinao indray ny tenimiafinao ka tsy te-hanova azy intsony, dia azonao tsy raharahiana ity hafatra ity ary azonao ampiasaina ilay tenimiafinao taloha.",
        "noemail": "Tsy nanome adiresy imailaka i \"$1\".",
        "noemailcreate": "Tsy maintsy misy ny adiresy imailaka ho atsofokao",
        "passwordsent": "Nandefasana tenimiafina vaovao any amin'ny adiresy imailak'i \"$1\".\nAzafady midira rehefa voarainao io imailaka io.",
        "changepassword-success": "Voaova soa aman-tsara ny tenimiafinao!",
        "changepassword-throttled": "Betsaka loatra ny andram-pidirana nataonao.\nAndraso $1 aloha ny mamerina.",
        "botpasswords": "Tenimiafin-drôbô",
+       "botpasswords-summary": "Ny <em>Tenimiafina rôbô</em> dia manome alalana ny mampiasa ny kaontim-pikambana iray amin'ny alalana API ka tsy mila mampiasa ny tenimiafin'ny mpikambana. Ny zom-pikambana ananana rehefa tafiditra amin'ny alalana tenimiafina rôbô dia mety ho voafetra.\n\nRaha tsy fantatrao ny antony hanaovanao izany dia tsy tokony hanao izany ianao. Tsy tokony hisy ny olona hangataka anao hamoaka iray amin'itony ary hanome azy.",
        "botpasswords-disabled": "Tsy ampiasaina ny tenimiafin-drôbô.",
+       "botpasswords-no-central-id": "Raha hampiasa tenimiafina rôbô dia tsy maintsy tafiditra anaty kaonty iombonan-tsehatra ianao.",
        "botpasswords-existing": "Tenimiafin-drôbô efa misy",
        "botpasswords-createnew": "Hamorona tenimiafina rôbô vaovao",
        "botpasswords-editexisting": "Hanova tenimiafina rôbô efa misy",
+       "botpasswords-label-needsreset": "(mila famerenana ny tenimiafina)",
        "botpasswords-label-appid": "Anarana rôbô:",
        "botpasswords-label-create": "Foronina",
        "botpasswords-label-update": "Vaozina",
        "botpasswords-insert-failed": "Tsy afaka nanampy ny anarana rôbô \"$1\". Tsy efa nampiana ve ilay izy?",
        "botpasswords-update-failed": "Tsy afaka nanavao ny anarana rôbô \"$1\". Nofafàna ve ilay izy?",
        "botpasswords-created-title": "Noforonina ilay tenimiafina rôbô",
-       "botpasswords-created-body": "Noforonina ny tenimiafina rôbô \"$1\" an'ny mpikambana \"$2\".",
+       "botpasswords-created-body": "Noforonina ny tenimiafina rôbô \"$1\"{{GENDER:$2|}} an'ny mpikambana \"$2\".",
        "botpasswords-updated-title": "Nohavaozina ny tenimiafina rôbô",
-       "botpasswords-updated-body": "Nohavaozina ny tenimiafina rôbô \"$1\" an'ny mpikambana \"$2\".",
+       "botpasswords-updated-body": "Nohavaozina ny tenimiafina rôbô \"$1\" an'ny mpikambana \"$2\"{{GENDER:$2|}}.",
        "botpasswords-deleted-title": "Nofafàna ny tenimiafina rôbô",
-       "botpasswords-deleted-body": "Nofafàna ny tenimiafina rôbô \"$1\" an'ny mpikambana \"$2\".",
-       "botpasswords-newpassword": "Ny tenimiafina idirana amin'i <strong>$1</strong> dia <strong>$2</strong>. <em>Raiketo ilay izy ho an'ny fampiasàna any aoriana any.</em>",
+       "botpasswords-deleted-body": "Nofafàna ny tenimiafina rôbô \"$1\" an'ny mpikambana \"$2{{GENDER:$2|}}\".",
+       "botpasswords-newpassword": "Ny tenimiafina hidirana amin'i <strong>$1</strong> dia <strong>$2</strong>. <em>Raiketo izany ho fampatsiahivana ho an'ny ho avy</em><br>(Ho an'ny rôbô taloha izay mila ny anaram-pidirana mitovy amin'ny anaram-pikambana dia azonao ampiasaina ho anaram-pikambana i <strong>$3</strong> ary niy tenimiafina <strong>$4</strong>.)",
        "botpasswords-no-provider": "Tsy afaka antsoina ny BotPasswordsSessionProvider.",
        "botpasswords-restriction-failed": "Manakana ity fidirana ity ny fepetra mifehy ny tenimiafina rôbô.",
        "resetpass_forbidden": "Tsy afaka ovaina ny tenimiafina",
        "resetpass-submit-loggedin": "Ovay ny tenimiafina",
        "resetpass-submit-cancel": "Aoka ihany",
        "resetpass-wrong-oldpass": "Tsy izy ny tenimiafinao (ankehitriny na vonjimaika)\nMety efa nanova tenimiafina na nangataka hahazo tenimiafina vonjimaika angamba ianao.",
-       "resetpass-recycled": "Avereno amy zavatra hafa nohon'ny tenimiafinao ankehitriny ny tenimiafinao.",
+       "resetpass-recycled": "Ovay ho zavatra samihafa amin'ny tenimiafinao ankehitriny ny tenimiafinao.",
        "resetpass-temp-emailed": "Niditra tamin'ny alalan'ny tenimiafina vonjimaika nalefa mailaka ianao.\nMba hamaranana ny fidirana, dia tsy maintsy mampiditra tenimiafina vaovao eto ianao :",
        "resetpass-temp-password": "Tenimiafina miserana :",
        "resetpass-abort-generic": "Nosakanan'ny itatra (extension) iray ny fanovana tenimiafina.",
        "resetpass-expired": "Efa nitsahatra ny tenimiafinao. Mampidira tenimiafina vaovao hahafahanao miditra.",
-       "resetpass-expired-soft": "Efa nitsahatra ny tenimiafinao, ary tsy maintsy averina ilay izy. Safidio avy hatrany ny tenimiafina, na tsindrio \"{{int:authprovider-resetpass-skip-label}}\" raha tsy hanao izany androany",
-       "resetpass-validity-soft": "Tsy ekena ny tenimiafinao : $1\n\nTenimiafina vaovao fidiana, na tsindrio \"{{int:authprovider-resetpass-skip-label}}\" raha hamerina azy amin'ny fotoana hafa.",
+       "resetpass-expired-soft": "Efa nitsahatra ny tanimiafinao ka mila ovaina. Misafidiana tenimiafina vaovao dien'izao, na tsindrio \"{{int:authprovider-resetpass-skip-label}}\" raha hanova azy amin'ny fotoana hafa.",
+       "resetpass-validity-soft": "Tsy ekena ny tenimiafinao : $1\n\nMisafidiana tenimiafina vaovao izao, na tsindrio  \"{{int:authprovider-resetpass-skip-label}}\" raha te-hanova azy any aoriana.",
        "passwordreset": "Famafana ary famerenana ny tenimiafina",
        "passwordreset-text-one": "Fenoy ity fôrmiolera ity mba hamerenana ny tenimiafinao",
        "passwordreset-text-many": "{{PLURAL:$1|Fenoy ny saha mba hahazoanao tenimiafina vonjimaika.}}",
        "passwordreset-emailtext-ip": "Nisy olona (izay mety ianao, avy amin'ny adiresy IP $1) nangataka ny hamerina ny tenimiafin'ny kaontim-pikambany ho an'i {{SITENAME}} ($4). Mampiasa ity adiresy mailaka ity {{PLURAL:$3|ity kaontim-pikambana mpikambana io|ireo kaontim-mpikambana ireo}}:\n\n$2\n\nHitsahatra afaka $5 andro {{PLURAL:$3|io tenimiafina io|ireo tenimiafina ireo}}.\nTokony miditra ianao ary mifidy tenimiafina vaovao. Raha misy olon-kafa nanao ity hataka ity, na efa tadidinao indray ilay tenimiafinao taloha, ary raha tsy tia hanova azy intsony, azonao tsy raharahiana ity hafatra ity ary mitohy mampiasa ny tenimiafinao taloha.",
        "passwordreset-emailtext-user": "Nisy mpikambana mitondra anarana $1 eo amin'i {{SITENAME}} nangataka fampatsiahivana mikasika ny kaontinao eo amin'i {{SITENAME}} ($4). Manana io adiresy imailaka {{PLURAL:$3|io kaontim-pikambana io|ireo kaontim-pikambana ireo}} :\n\n$2\n\nHitsahatra afaka {{PLURAL:$5|iray|$5}} andro {{PLURAL:$3|io|ireo}} tenimiafina {{PLURAL:$3|io|ireo}}. Mila miditra dien'izao ianao izao ary mifidy tenimiafina vaovao. Raha tsy avy aminao ity hataka ity na efa nahatadidy ny tenimiafinao taloha ianao, ary raha tsy tianao hovaina intsony ilay tenimiafinao, dia azonao tsy raharahiana ity hafatra ity ary mampiasa ny tenimiafinao taloha.",
        "passwordreset-emailelement": "Anaram-pikambana : \n$1\n\nTenimiafina miserana : \n$2",
-       "passwordreset-emailsentemail": "Lasa ny mailaka famerenana tenimiafina.",
+       "passwordreset-emailsentemail": "Raha miaraka amin'ny kaontinao ity adiresy mailaka ity, dia ho alefa ny mailaka famerenan-tenimiafina.",
        "passwordreset-nocaller": "Mila manitsy mpiantso",
        "passwordreset-nosuchcaller": "Tsy misy ilay mpiantso: $1",
        "passwordreset-invalidemail": "Adiresy mailaka tsy azo raisina",
        "savechanges": "Hitahiry ny fiovana",
        "publishpage": "Hamoaka pejy",
        "publishchanges": "Hamoaka ny fiovana",
+       "savearticle-start": "Hitahiry pejy...",
+       "savechanges-start": "Mitahiry ny fiovana...",
+       "publishpage-start": "Hamoaka ny pejy...",
+       "publishchanges-start": "Hamoaka ny fiovana...",
        "preview": "Topi-maso",
        "showpreview": "Asehoy aloha",
        "showdiff": "Asehoy ny fiovana",
-       "blankarticle": "<strong>Tandremo:</strong> Fotsy ny pejy tianao hoforonina.\nRaha manindry an'i \"$1\" indray ianao dia hoforonina tsy hisy vontoatiny na inona na innona ilay pejy.",
+       "blankarticle": "<strong>Tandremo:</strong> Fotsy ny pejy tianao hoforonina.\nRaha manindry an'i \"$1\" indray ianao dia hoforonina tsy hisy vontoatiny na inona na inona ilay pejy.",
        "anoneditwarning": "<strong>Fampitandremana :</strong> Tsy niditra tamin'ny kaontinao ianao. Ho hitan'ny vahoaka ny adiresy IP-nao raha manova inona na inona ianao. Raha <strong>[$1 miditra amin'ny kaontinao]</strong> ianao dia ho anisan'ny tombontsoa anananao ny fanaovana ny fiovana amin'ny solonanaranao.",
        "anonpreviewwarning": "''Tsy niditra ianao. Hampitahiry ny adiresy IP anao ao amin'ny tantaram-panovan'ity pejy ity ny fitehirizana ny fanovana.''",
        "missingsummary": "'''Hafatra fampantsiahivana''' : tsy mbola nanome ny ambangovangom-panovanao ianao.\nRaha mbola tsindriano fanindroany eo amin'ny bokotra $1, ho voatahiry tsy fanambarana ny fanovanao.",
-       "missingcommenttext": "Ampidiro ny ambangovangony azafady.",
-       "missingcommentheader": "'''Fampahatsiahivana :''' Tsy nampiditra lohateny amin'ity resaka ity ianao.\nRaha tsindrianao indray eo amin'ny « {{MediaWiki:Savearticle}} » ho voatahiry tsy misy lohateny ny fanovananao.",
-       "summary-preview": "Topi-maso n'ilay ambangovangony :",
-       "subject-preview": "Topi maso ny lazaina :",
+       "missingcommenttext": "Mampidira ambangovangony azafady.",
+       "missingcommentheader": "<strong>Fampatsiahivana: </strong> Tsy nampiditra lohahevitra ho an'ity hafatra ity ianao. Raha tsindrianao fanindroany \"$1\" dia ho tehirizina tsy misy lohahevitra ny hafatrao.",
+       "summary-preview": "Topi-mason'ny ambangovangom-panovana :",
+       "subject-preview": "Topi-mason-dohahevitra:",
        "previewerrortext": "Nisy hadisoana nitranga tamin'ny fanandramana namoaka topi-mason'ny fanovanao",
        "blockedtitle": "Mpikambana voasakana",
-       "blockedtext": "'''Voasakana ny solonanaranao na ny adiresy IP anao.'''\n\nNataon'i $1 ny fisakanana.\nNy antony : ''$2''.\n\n* Fanombohan'ilay fisakanana : $8\n* Farany : $6\n* Kaonty voasakana : $7.\n\nAfaka antsoinao i $1 na [[{{MediaWiki:Grouppage-sysop}}|ny mpandrindra]] mba hiresaka mombamomba n'izany.\nAfaka andefasanao imailaka ra nampiditra ny adiresy imailakanao ianao ao anatin'ny [[Special:Preferences|mombamombanao]].\n'''$3''' ny adiresy IP-nao ary ny ''identifiant de blocage''-nao dia #$5.\nAsio ao anaty ny fangatahanao io adiresy io.",
-       "autoblockedtext": "Voasakana ny adiresy IP anareo satria nampiasain'ny olon-kafa io adiresy ampiasainao io. Ary voasakan'i $1 ilay olona nampiasa ny adiresinao.<br />\nIty ny antony navoakany\n\n:''$2''\n\n* nanomboka tamin'ny $8 ilay fisakanana\n* Amin'ny $6 ilay fisakanana no mijanona\n* $7 no anaran'ilay kaonty voasakana\n\nAfaka antsoinao i $1 na miantso ny [[{{MediaWiki:Grouppage-sysop}}|mpandrindra]] mba hiresaka momba ny fanakananao.\n\nJereo koa fa tsy afaka mampiasa ny asa ''emailuser'' ianao ra tsy nanometraka ny adiresy imailakao anatin'ny [[Special:Preferences|safidinao]]. Jereo koa ra tsy nesorinao ny asa ''emailuser''.\n\n$3 izao ny adiresinao, ary ny isa ny fisakananai dia $5.\nSoraty ireo fanoroana ireo anatin'ny fangatahana ataonao.",
+       "blockedtext": "<strong>Voasakana ny adiresy IP-nao na ny anaram-pikambanao.</strong>\n\nI $1 no nanao ny sakana.\nNy antony nomeny dia <em>$2</em>.\n\n* Fiantombohan'ny sakana: $8\n* Fitsaharan'ny sakana: $6\n* Ny iriana ho sakanana: $7\n\nAzonao atao ny mifandray amin'i $1 na [[{{MediaWiki:Grouppage-sysop}}|mpandrindra]] hafa raha mila miady hevitra momba ny sakana.\nTsy afaka mampiasa ny fahafahana \"{{int:emailuser}}\" ianao raha tsy nanome adiresy azo anoratana anao ao amin'ny [[Special:Preferences|safidin'ny kaontinao]] ary koa raha tsy nosakanana tsy afaka mampiasa azy ianao.\nNy adiresy IP-nao dia $3 ary ny ID ny sakana dia #$5.\nSoraty avokoa ireo antsipirihany eo ambony ireo anatin'ny hataka izay ataonao.",
+       "autoblockedtext": "<strong>Voasakana ny adiresy IP-nao satria nampiasaim-pikambana hafa izay nosakanan'i $1 ilay izy.</strong>\n\n\nNy antony nomeny dia:\n:<em>$2</em>.\n\n* Fiantombohan'ny sakana: $8\n* Fitsaharan'ny sakana: $6\n* Ny iriana ho sakanana: $7\n\nAzonao atao ny mifandray amin'i $1 na [[{{MediaWiki:Grouppage-sysop}}|mpandrindra]] hafa raha mila miady hevitra momba ny sakana.\nTsy afaka mampiasa ny fahafahana \"{{int:emailuser}}\" ianao raha tsy nanome adiresy azo anoratana anao ao amin'ny [[Special:Preferences|safidin'ny kaontinao]] ary koa raha tsy nosakanana tsy afaka mampiasa azy ianao.\nNy adiresy IP-nao dia $3 ary ny ID ny sakana dia #$5.\nSoraty avokoa ireo antsipirihany eo ambony ireo anatin'ny hataka izay ataonao.",
        "blockednoreason": "tsy nisy antony nomeny",
        "whitelistedittext": "Mila $1 aloha ianao vao afaka manova/mamorona pejy eto amin'ity wiki ity.",
        "confirmedittext": "Tsy maintsy marihina ny adiresy imailakao aloha no manova pejy.\nAmpidiro sy Checkeo ny adiresy imailakao amin'ny [[Special:Preferences|safidinao]].",
        "permissionserrorstext": "Tsy afaka manao ilay aza nangatahanao ianao noho ny antony {{PLURAL:$1||maro}} manaraka :",
        "permissionserrorstext-withaction": "{{PLURAL:$1|Tsy manana alalàna ianao|Tsy manana alalàna ianao}} $2. Io ny antony ($2):",
        "recreate-moveddeleted-warn": "'''Tandremo''' : Mamerina pejy efa voafafa ianareo.'''\n\nMarino raha tsara tohizana ny fanovana eto amin'ity pejy ity. Ny laogim-pamafana sy ny famindran-toerana dia eo ambany :",
-       "moveddeleted-notice": "Voafafa ity pejy ity.\nEo ambany eo any laogin'ny famindran-toerana sy ny famafana ho an'ny antsipirihany.",
+       "moveddeleted-notice": "Voafafa ity pejy ity.\nAseho ho  fampatsiahivana eo ambany eo any laogin'ny famindran-toerana sy ny famafana.",
        "log-fulllog": "Hijery ny laogy manontolo",
        "edit-hook-aborted": "Tsy nety ny fanovàna\nTsy nanome antony",
        "edit-gone-missing": "Tsy afaka natao update ilay pejy.\nMety voafafa angamba izy.",
        "page_first": "voalohany",
        "page_last": "farany",
        "histlegend": "Safidim-pahasamihafana: Mariho ireo bokotra radiôn'ny versiona mba hampitahàna azy ireo  ary tsindrony ilay bokotra amin'ny faran'ny pejy: <strong>({{int:cur}})</strong> = fampitahana amin'ny versiona farany indrindra, <strong>({{int:last}})</strong> = fahasamihafana amin'ny versiona farany nialoha ity, <strong>{{int:minoreditletter}}</strong> = fiovana madinika.",
-       "history-fieldset-title": "Karohy ny tantara",
+       "history-fieldset-title": "Hikaroka tantara",
        "history-show-deleted": "Voafafa ihany",
        "histfirst": "antitra indrindra",
        "histlast": "vaovao indrindra",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (jereo koa ny [[Special:NewPage|lisitry ny pejy vaovao]])",
        "recentchanges-submit": "Aseho",
        "rcfilters-activefilters": "Sivana miasa",
+       "rcfilters-activefilters-hide-tooltip": "Hanafina ny faritry ny sivana miasa",
        "rcfilters-advancedfilters": "Sivana havanana kokoa",
        "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-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-and-setdefault-label": "Hamorona sivana solon'ny tsy misy",
        "rcfilters-savedqueries-cancel-label": "Avela",
+       "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-search-placeholder": "Hanivana ny fiovana farany (tetezo na manomboha manoratra)",
        "rcfilters-filter-excluded": "Foanana",
        "rcfilters-tag-prefix-namespace-inverted": "<strong>:not</strong> $1",
        "rcfilters-view-tags": "Fiovam-pejy voamarika",
+       "rcfilters-view-namespaces-tooltip": "Hanasivana ny valiny araka ny anaran-tsehatra",
+       "rcfilters-view-return-to-default-tooltip": "Hiverina amin'ny menion'ny sivana",
        "rcfilters-liveupdates-button": "Fihavaozana mivantana",
        "rcnotefrom": "Eo ambany dia ahitana ireo fiovana{{PLURAL:$5}} hatry ny <strong>$3, $4</strong> (naseho hatramin'ny <strong>$1</strong>).",
        "rclistfrom": "Asehoy izay vao niova manomboka ny $3 $2",
        "rcshowhidecategorization": "$1 ny fisokajiam-pejy",
        "rcshowhidecategorization-show": "Aseho",
        "rcshowhidecategorization-hide": "Afenina",
-       "rclinks": "Asehoy ny $1 niova farany tato anatin'ny $2 andro",
+       "rclinks": "Haneho ny fiovana $1 farany tanatin'ny andro $2 farany",
        "diff": "Fampitahana",
        "hist": "tant.",
        "hide": "Afeno",
        "recentchangeslinked-feed": "Novaina",
        "recentchangeslinked-toolbox": "Novaina",
        "recentchangeslinked-title": "Fanaraha-maso ny pejy miarak'amin'ny « $1 »",
-       "recentchangeslinked-summary": "Mampiseho ny fanovàna vao haingana ity pejy manokana ity. Voasoratra amin'ny '''sora-matavy''' ny lohaten'ny [[Special:Watchlist|pejy arahinao-maso]].",
+       "recentchangeslinked-summary": "Mampiseho ny fanovàna vao haingana ity pejy manokana ity. Voasoratra amin'ny '''sora-matavy''' ny lohaten'ny [[Special:Watchlist|pejy arahinao-maso]] dia hiseho amin'ny <strong>sora-baventy</strong>.",
        "recentchangeslinked-page": "anaram-pejy :",
        "recentchangeslinked-to": "Ampisehoy ny fanovàn'ny pejy misy rohy makany amin'ny pejy fa tsy atao mivadika",
        "recentchanges-page-added-to-category": "Nampiana tamin'ny sokajy [[:$1]]",
        "whatlinkshere": "Pejy mirohy eto",
        "whatlinkshere-title": "Pejy mirohy any amin'i « $1 »",
        "whatlinkshere-page": "Pejy :",
-       "linkshere-2": "Ireo pejy ireo dia manana rohy mankany amin'i '''$1'''",
-       "nolinkshere-2": "Tsy nahitana pejy mirohy any amin'i '''$1'''.",
-       "nolinkshere-ns-2": "Tsy nahitana pejy mirohy any amin'i $1 ao amin'ny anaran-tsehatra nofidiana.",
+       "linkshere": "Ireo pejy ireo dia manana rohy mankany amin'i '''$2'''",
+       "nolinkshere": "Tsy nahitana pejy mirohy any amin'i '''$2'''.",
+       "nolinkshere-ns": "Tsy nahitana pejy mirohy any amin'i $2 ao amin'ny anaran-tsehatra nofidiana.",
        "isredirect": "pejy fihodinana",
        "istemplate": "tsofo-pejy",
        "isimage": "rohy mankany amin'ilay rakitra",
        "markedaspatrollederrornotify": "Tsy nahamarika azy ho voaara-maso.",
        "patrol-log-page": "Laogin'ny fanovana voamarina",
        "patrol-log-header": "Ity dia laogy mikasikan'ny fanovana voamarina.",
-       "log-show-hide-patrol": "$1 ny laogy mikasikan'ny versiona voamarina",
-       "log-show-hide-tag": "$1 laogim-balizy",
        "confirm-markpatrolled-button": "OK",
        "confirm-markpatrolled-top": "Hanamarika ny reviziôna $3 an'i $2 ho voamarina?",
        "deletedrevision": "Fanovana an'i $1 taloha voafafa.",
        "version-libraries-license": "Fahazoan-dalana",
        "version-libraries-description": "Visavisa",
        "version-libraries-authors": "Mpamorona",
+       "redirect-summary": "Ity pejy manokana ity dia manome fihodinana mankany amina rakitra (anaran-drakitra) na pejy (ID fiovana na pejy nomena). Fampiasana:\n[[{{#Special:Redirect}}/file/Example.jpg]],\n[[{{#Special:Redirect}}/page/64308]],\n[[{{#Special:Redirect}}/revision/328429]],\n[[{{#Special:Redirect}}/user/101]], na\n[[{{#Special:Redirect}}/logid/186]].",
        "redirect-submit": "Alefa",
        "redirect-lookup": "Karohana:",
        "redirect-value": "Sanda:",
        "tag-filter": "manasongadina [[Special:Tags|balizy]] :",
        "tag-filter-submit": "Manasongadina",
        "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|Marika}}]]: $2)",
+       "tag-mw-new-redirect": "Fihodinana vaovao",
        "tags-title": "Balizy",
        "tags-intro": "Ity pejy ity dia manalisitra ny balizy azon'ny rindrankajy ampiasaina mba hanamarika fanovana iray sy ny dikany.",
        "tags-tag": "Anaran'ny balizy",
        "revdelete-restricted": "nametraka fanerena ho an'ny mpandrindra",
        "revdelete-unrestricted": "fanerena nesorina tamin'ny mpandrindra",
        "logentry-move-move": "nanova ny anaran'i $3 ho $4 i $1",
+       "logentry-move-move-noredirect": "$1{{GENDER:$2|}} dia namindra ny pejy $3 ho $4 fa tsy namela fihodinana",
+       "logentry-move-move_redir": "$1 dia namindra{{GENDER:$2|}} ny pejy $3 any amin'i $4 ary nanitsaka fihodinana",
+       "logentry-patrol-patrol-auto": "$1 dia nanamarika ho azy ny{{GENDER:$2|}} fiovana $4 ny pejy $3 ho voatety",
        "logentry-newusers-newusers": "{{GENDER:$2|Noforonina}} ny kaontim-pikambana $1",
        "logentry-newusers-create": "{{GENDER:$2|Noforonina}} ny kaontim-pikambana $1",
        "logentry-newusers-create2": "{{GENDER:$2|Noforonin}}'i $1 ny kaomtim-pikambana $3",
index c9c2dc7..89b4dfd 100644 (file)
        "whatlinkshere": "Тышке кондышо кылвер-влак",
        "whatlinkshere-title": "\"$1\" дене лаштык-влак кылым палемдат",
        "whatlinkshere-page": "Лаштык:",
-       "linkshere-2": "'''$1''' лаштык дене кылдалтше лаштык-влак:",
-       "nolinkshere-2": "'''$1''' лаштык дене тетла нимогай лаштык кылдалтын огыл",
-       "nolinkshere-ns-2": "Тыгай лӱм-влакын кумдыкышто '''$1''' лаштык дене нимогай лаштык-влак огыт кылдалт.",
+       "linkshere": "'''$2''' лаштык дене кылдалтше лаштык-влак:",
+       "nolinkshere": "'''$2''' лаштык дене тетла нимогай лаштык кылдалтын огыл",
+       "nolinkshere-ns": "Тыгай лӱм-влакын кумдыкышто '''$2''' лаштык дене нимогай лаштык-влак огыт кылдалт.",
        "isredirect": "вес вере колтышо лаштык",
        "istemplate": "пуртымаш",
        "isimage": "файлыш кылвер",
index 81c9e84..642e01e 100644 (file)
        "whatlinkshere": "Pautan baliak",
        "whatlinkshere-title": "Laman nan takaik ka \"$1\"",
        "whatlinkshere-page": "Laman:",
-       "linkshere-2": "Laman-laman ko bakaik ka '''$1''':",
-       "nolinkshere-2": "Indak ado laman nan punyo tautan ka '''$1'''.",
-       "nolinkshere-ns-2": "Indak ado pautan laman ka '''$1''' pado ruang namo nan dipiliah.",
+       "linkshere": "Laman-laman ko bakaik ka '''$2''':",
+       "nolinkshere": "Indak ado laman nan punyo tautan ka '''$2'''.",
+       "nolinkshere-ns": "Indak ado pautan laman ka '''$2''' pado ruang namo nan dipiliah.",
        "isredirect": "laman pangaliahan",
        "istemplate": "transklusi",
        "isimage": "pautan berkas",
        "rcpatroldisabled": "Patroli parubahan baru dimatian",
        "patrol-log-page": "Log patroli",
        "patrol-log-header": "Iko daftar log revisi nan alah dipatroli.",
-       "log-show-hide-patrol": "$1 log patroli",
        "previousdiff": "← Revisi sabalunnyo",
        "nextdiff": "Revisi salanjuiknyo →",
        "imagemaxsize": "Bateh ukuran gambar:<br />''(untuak laman katarangan berkas)''",
index b55fb55..fb304eb 100644 (file)
@@ -22,7 +22,8 @@
                        "Kaldari",
                        "Xð",
                        "Srdjan m",
-                       "Acamicamacaraca"
+                       "Acamicamacaraca",
+                       "Vlad5250"
                ]
        },
        "tog-underline": "Потцртување на врски:",
        "customcssprotected": "Немате дозвола да ја менувате оваа страница со CSS бидејќи содржи туѓи лични нагодувања.",
        "customjsonprotected": "Немате дозвола да ја менувате оваа страница со JSON бидејќи содржи туѓи лични нагодувања.",
        "customjsprotected": "Немате дозвола да ја менувате оваа страница со JavaScript  бидејќи содржи туѓи лични нагодувања.",
+       "sitecssprotected": "Немате дозвола да ја менувате оваа страница со CSS бидејќи може да ги засегне сите посетители",
+       "sitejsonprotected": "Немате дозвола да ја менувате оваа страница со JSON бидејќи може да ги засегне сите посетители",
+       "sitejsprotected": "Немате дозвола да ја менувате оваа страница со JavaScript бидејќи може да ги засегне сите посетители",
        "mycustomcssprotected": "Немате дозвола да ја уредувате оваа каскадна стилска страница (CSS).",
        "mycustomjsonprotected": "Немате дозвола да ја уредувате оваа страница со JSON.",
        "mycustomjsprotected": "Немате дозвола да ја уредувате оваа страница со JavaScript.",
        "resetpass-temp-password": "Привремена лозинка:",
        "resetpass-abort-generic": "Смената на лозинката е откажана од додаток.",
        "resetpass-expired": "Лозинката ви е истечена. Задајте нова лозинка за да се најавите.",
-       "resetpass-expired-soft": "Лозинката ви е истечена и ќе мора да зададете друга. Изберете ја сега, или пак стиснете на „{{int:authprovider-resetpass-skip-label}}“ за да ја зададете подоцна.",
-       "resetpass-validity-soft": "Лозинката ви е неважечка: $1\n\nИзберете друга сега, или пак стиснете на „{{int:authprovider-resetpass-skip-label}}“ за да ја зададете подоцна.",
+       "resetpass-expired-soft": "Лозинката ви е истечена и ќе мора да ја смените. Изберете ја сега, или пак стиснете на „{{int:authprovider-resetpass-skip-label}}“ за да ја смените подоцна.",
+       "resetpass-validity-soft": "Лозинката ви е неважечка: $1\n\nИзберете друга сега, или пак стиснете на „{{int:authprovider-resetpass-skip-label}}“ за да ја смените подоцна.",
        "passwordreset": "Менување на лозинка",
        "passwordreset-text-one": "Пополнете го образецов за да ја измените лозинката.",
        "passwordreset-text-many": "{{PLURAL:$1|Пополнете едно од полињата за добиете привремена лозинка по е-пошта.}}",
        "converter-manual-rule-error": "Пронајдов грешка во правилото за рачно претворање на јазик",
        "undo-success": "Уредувањето може да се откаже.\nВе молиме споредете ги промените со претходната верзија за да проверите дали тоа е сигурно она што сакате да го направите, а потоа зачувајте ги промените за да го завршите откажувањето на претходното уредување.",
        "undo-failure": "Уредувањето не можеше да се откаже заради меѓувремени спротиставени уредувања.",
+       "undo-main-slot-only": "Уредувањето не може да се отповика бидејќи има содржина вон главниот жлеб.",
        "undo-norev": "Измената не можеше да биде вратена бидејќи не постои или била избришана.",
        "undo-nochange": "Се чини дека измената (уредувањето) е веќе вратена.",
        "undo-summary": "Откажано уредувањето $1 на уредникот [[Special:Contribs/$2|$2]] ([[User talk:$2|разговор]])",
        "diff-paragraph-moved-toold": "Пасусот е преместен. Стиснете за да прејдете на старото место.",
        "difference-missing-revision": "Не пронајдов {{PLURAL:$2|една преработка|$2 преработки}} од оваа разлика ($1).\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": "Совпаднат текст во страниците",
        "group-autoconfirmed": "Автопотврдени корисници",
        "group-bot": "Ботови",
        "group-sysop": "Администратори",
+       "group-interface-admin": "Администратори на посредникот",
        "group-bureaucrat": "Бирократи",
        "group-suppress": "Притајувачи",
        "group-all": "(сите)",
        "group-autoconfirmed-member": "автопотврден корисник",
        "group-bot-member": "бот",
        "group-sysop-member": "администратор",
+       "group-interface-admin-member": "{{GENDER:$1|администратор на посредникот}}",
        "group-bureaucrat-member": "бирократ",
        "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-editusercss": "Уредување на CSS податотеки на други корисници",
        "right-edituserjson": "Уредување на JSON-податотеките на други корисници",
        "right-edituserjs": "Уредување на JS податотеки на други корисници",
+       "right-editsitecss": "Уредување на CSS за цело вики",
+       "right-editsitejson": "Уредување на JSON за цело вики",
+       "right-editsitejs": "Уредување на JavaScript за цело вики",
        "right-editmyusercss": "Уредување на сопствени кориснички каскадни стилски податотеки (CSS)",
        "right-editmyuserjson": "Уредување на сопствените кориснички JSON-податотеки",
        "right-editmyuserjs": "Уредување на сопствени кориснички податотеки со JavaScript",
        "grant-createaccount": "Правење сметки",
        "grant-createeditmovepage": "Создавање, уредување и преместување страници",
        "grant-delete": "Бришење страници, преработки и дневнички записи",
-       "grant-editinterface": "Измена на именскиот простор „МедијаВики“ и кориснички  CSS/JSON/JavaScript",
+       "grant-editinterface": "Измена на именскиот простор „МедијаВики“ и JSON за цело вики/за корисник",
        "grant-editmycssjs": "Уредување на вашиот кориснички CSS/JSON/JavaScript",
        "grant-editmyoptions": "Уредување на вашите кориснички нагодувања",
        "grant-editmywatchlist": "Уредување на вашите набљудувани",
+       "grant-editsiteconfig": "Измена на CSS/JS за цело вики и за корисник",
        "grant-editpage": "Менување постоечки страници",
        "grant-editprotected": "Уредување на заштитени страници",
        "grant-highvolume": "Високообемно уредување",
        "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-savedqueries-rename": "Преименувај",
        "rcfilters-savedqueries-setdefault": "Задај како основно",
        "rcfilters-savedqueries-unsetdefault": "Отстрани од основно",
-       "rcfilters-savedqueries-remove": "Ð\9eÑ\82Ñ\81Ñ\82Ñ\80ани",
+       "rcfilters-savedqueries-remove": "Ð\98збÑ\80иÑ\88и",
        "rcfilters-savedqueries-new-name-label": "Назив",
        "rcfilters-savedqueries-new-name-placeholder": "Опишете ја намената на филтерот",
        "rcfilters-savedqueries-apply-label": "Создај филтер",
        "rcfilters-empty-filter": "Нема активни филтри. Прикажани се сите придонеси.",
        "rcfilters-filterlist-title": "Филтри",
        "rcfilters-filterlist-whatsthis": "Како работи ова?",
-       "rcfilters-filterlist-feedbacklink": "Дајте ни ваше мислење за овие (нови) филтерски алатки",
+       "rcfilters-filterlist-feedbacklink": "Дајте ни ваше мислење за овие филтерски алатки",
        "rcfilters-highlightbutton-title": "Истакнување на исход",
        "rcfilters-highlightmenu-title": "Изберете боја",
        "rcfilters-highlightmenu-help": "Изберете боја за да го истакнете ова својство",
        "rcfilters-watchlist-showupdated": "Промени во страниците што ги немате посетено откако се случиле се <strong>задебелени</strong>.",
        "rcfilters-preference-label": "Скриј ја подобрената верзија во Скорешните промени",
        "rcfilters-preference-help": "Го отповикува преуредувањето на околината од 2017 г. и сите алатки додадени оттогаш.",
+       "rcfilters-watchlist-preference-label": "Скриј ја подобрената верзија на набљудуваните",
+       "rcfilters-watchlist-preference-help": "Ја отповикува преработката на посредникот од 2017 г. и сите алатки додадени со неа.",
        "rcfilters-filter-showlinkedfrom-label": "Прикажи промени во страници кои водат од",
        "rcfilters-filter-showlinkedfrom-option-label": "<strong>Страници кон кои води</strong> избраната страница",
        "rcfilters-filter-showlinkedto-label": "Прикажи промени во страници кои водат кон",
        "uploadstash-zero-length": "Податотеката има нулта должина.",
        "invalid-chunk-offset": "Неважечка појдовна точка",
        "img-auth-accessdenied": "Оневозможен пристап",
-       "img-auth-nopathinfo": "Недостасува PATH_INFO.\nВашиот опслужувач не е нагоден за да ја предаде оваа информација.\nМожеби се заснова на CGI, и така не подржува img_auth.\nПогл. https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization.",
+       "img-auth-nopathinfo": "Недостасува информација за патеката.\nВашиот опслужувач мора да е наместен да ги дава променливите REQUEST_URI и/или PATH_INFO.\nАко е веќе наместен, овозможете го $wgUsePathInfo.\nПогл. https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization.",
        "img-auth-notindir": "Бараниот пат не води кон зададената папка за подигање.",
        "img-auth-badtitle": "Не може да се конструира важечки наслов од „$1“.",
        "img-auth-nologinnWL": "Не сте најавени и „$1“ не е на списокот на допуштени.",
        "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": "Наведеното URL не е достапно.\nПроверете дали URL-то е исправно и достапно.",
        "upload-curl-error28": "Истече времето за подигање",
        "speciallogtitlelabel": "Цел (наслов или {{ns:user}}:корисничко име на корисникот):",
        "log": "Дневници",
        "logeventslist-submit": "Прикажи",
+       "logeventslist-more-filters": "Прикажи повеќе дневници:",
+       "logeventslist-patrol-log": "Дневник на патролирања",
+       "logeventslist-tag-log": "Дневник на ознаки",
        "all-logs-page": "Сите јавни дневници",
        "alllogstext": "Комбиниран приказ на сите расположиви дневници на {{SITENAME}}.\nМожете да го ограничите прикажаното избирајќи тип на дневник, корисничко име (разликува големи и мали букви), или страница (разликува големи и мали букви).",
        "logempty": "Дневникот нема записи што одговараат на ова.",
        "dellogpage": "Дневник на бришења",
        "dellogpagetext": "Подолу е наведен список на најновите бришења.",
        "deletionlog": "дневник на бришењата",
+       "log-name-create": "Дневник на создавање страници",
+       "log-description-create": "Подолу е наведен список на најновите создавања.",
+       "logentry-create-create": "$1 {{GENDER:$2|ја создаде}} страница $3",
        "reverted": "Вратено на претходната преработка",
        "deletecomment": "Причина:",
        "deleteotherreason": "Друга/дополнителна причина:",
        "rollback-success": "Откажани уредувањата на {{GENDER:$3|$1}};; вратено на последната верзија на {{GENDER:$4|$2}}.",
        "rollback-success-notify": "Откажани уредувањата на $1;\nвратено на последната преработка на $2. [$3 Пок. промени]",
        "sessionfailure-title": "Седницата не успеа",
-       "sessionfailure": "Ð\98ма Ð¿Ñ\80облем Ñ\81о Ð²Ð°Ñ\88аÑ\82а Ñ\81едниÑ\86а;\nоваа Ð´ÐµÑ\98Ñ\81Ñ\82во Ðµ Ð¾Ñ\82кажано ÐºÐ°ÐºÐ¾ Ð¿Ñ\80евенÑ\82ива Ð¿Ñ\80оÑ\82ив Ð¿Ñ\80еземаÑ\9aе Ñ\81едниÑ\86и.\nПоднесете го образецот повторно.",
+       "sessionfailure": "Се Ñ\98ави Ð¿Ñ\80облем Ñ\81о Ð½Ð°Ñ\98авнаÑ\82а Ñ\81едниÑ\86а;\nова Ð´ÐµÑ\98Ñ\81Ñ\82во Ðµ Ð¾Ñ\82кажано Ð·Ð° Ð´Ð° Ñ\81е Ñ\81пÑ\80еÑ\87и Ð½ÐµÑ\98зина ÐºÑ\80ажба.\nПоднесете го образецот повторно.",
        "changecontentmodel": "Промена на содржинскиот модел на страница",
        "changecontentmodel-legend": "Промена на содржински модел",
        "changecontentmodel-title-label": "Наслов на страницата",
        "uctop": "(тековно)",
        "month": "Од месец (и порано):",
        "year": "Од година (и порано):",
+       "date": "Од датумот (и порано):",
        "sp-contributions-newbies": "Прикажи само придонеси на нови корисници",
        "sp-contributions-newbies-sub": "За нови кориснички сметки",
        "sp-contributions-newbies-title": "Придонеси на нови корисници",
        "whatlinkshere": "Што води овде",
        "whatlinkshere-title": "Страници со врски што водат до „$1“",
        "whatlinkshere-page": "Страница:",
-       "linkshere-2": "Следните страници водат кон „'''$1'''“:",
-       "nolinkshere-2": "Нема страници што водат кон '''$1'''.",
-       "nolinkshere-ns-2": "Нема страници што водат кон '''$1''' во избраниот именски простор.",
+       "linkshere": "Следните страници водат кон <strong>$2</strong>:",
+       "nolinkshere": "Нема страници што водат кон <strong>$2</strong>.",
+       "nolinkshere-ns": "Нема страници што водат кон <strong>$2</strong> во избраниот именски простор.",
        "isredirect": "пренасочувачка страница",
        "istemplate": "превметнување",
        "isimage": "врска до податотеката",
        "markedaspatrollederrornotify": "Означувањето како испатролирано не успеа.",
        "patrol-log-page": "Дневник на патролирања",
        "patrol-log-header": "Ова е дневник на патролирани преработки.",
-       "log-show-hide-patrol": "$1 дневник на патролирање",
-       "log-show-hide-tag": "$1 дневник на ознаки",
        "confirm-markpatrolled-button": "ОК",
        "confirm-markpatrolled-top": "Да ја означан преработката $3 на $2 како испатролирана?",
        "deletedrevision": "Избришана стара преработка $1.",
        "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 (<strong>исклучено</strong>)",
        "mediastatistics": "Статистики за слики и снимки",
        "mediastatistics-summary": "Статистики за подигнати типови податотеки. Се зема предвид само последната верзија на податотеката. Старите и избришаните верзии не се бројат.",
+       "mediastatistics-nfiles": "$1 ($2 %)",
        "mediastatistics-nbytes": "{{PLURAL:$1|Еден бајт|$1 бајти}} ($2; $3%)",
        "mediastatistics-bytespertype": "Вкупен обем на пасусот: {{PLURAL:$1|$1 бајт|$1 бајти}} ($2; $3%).",
        "mediastatistics-allbytes": "Вкупен обем на сите податотеки: {{PLURAL:$1|$1 бајт|$1 бајти}} ($2).",
        "passwordpolicies-policy-passwordcannotmatchusername": "Лозинката не може да биде иста што и корисничкото име",
        "passwordpolicies-policy-passwordcannotmatchblacklist": "Лозинката не смее да биде од оние на црниот список",
        "passwordpolicies-policy-maximalpasswordlength": "Лозинката не треба да има повеќе од $1 {{PLURAL:$1|знак|знаци}}",
-       "passwordpolicies-policy-passwordcannotbepopular": "Лозинката не треба да биде {{PLURAL:$1|најзастапената|од списокот на $1 најзастапени лозинки}}"
+       "passwordpolicies-policy-passwordcannotbepopular": "Лозинката не треба да биде {{PLURAL:$1|најзастапената|од списокот на $1 најзастапени лозинки}}",
+       "easydeflate-invaliddeflate": "Содржината не е соодветно прочистена"
 }
index 75bf700..98c7062 100644 (file)
        "botpasswords-label-grants": "ബാധകമായ അനുമതികൾ:",
        "botpasswords-label-grants-column": "അനുവദിച്ചിരിക്കുന്നവ",
        "resetpass_forbidden": "രഹസ്യവാക്കുകൾ മാറ്റുന്നത് അനുവദിക്കുന്നില്ല",
+       "resetpass_forbidden-reason": "രഹസ്യവാക്കുകൾ മാറ്റാൻ കഴിയില്ല: $1",
        "resetpass-no-info": "ഈ താൾ നേരിട്ടു കാണുന്നതിന് താങ്കൾ ലോഗിൻ ചെയ്തിരിക്കണം.",
        "resetpass-submit-loggedin": "രഹസ്യവാക്ക് മാറ്റുക",
        "resetpass-submit-cancel": "റദ്ദാക്കുക",
        "resetpass-wrong-oldpass": "താത്കാലികമായി ലഭിച്ച അല്ലെങ്കിൽ നിലവിലുള്ളതായി നൽകിയ രഹസ്യവാക്ക് അസാധുവാണ്.\nതാങ്കൾ രഹസ്യവാക്ക് വിജയകരമായി മാറ്റിയിട്ടുണ്ടാകാം അല്ലെങ്കിൽ പുതിയ താത്കാലിക രഹസ്യവാക്ക് അഭ്യർത്ഥിച്ചിട്ടുണ്ടാകാം.",
-       "resetpass-recycled": "താà´\99àµ\8dà´\95à´³àµ\81à´\9fàµ\86 à´°à´¹à´¸àµ\8dയവാà´\95àµ\8dà´\95àµ\8d à´¨à´¿à´²à´µà´¿à´²àµ\81à´³àµ\8dളതിൽ à´¨à´¿à´¨àµ\8dà´¨àµ\81à´\82 à´µàµ\8dയതàµ\8dയസàµ\8dതമായതാà´\95àµ\8dà´\95ുക.",
+       "resetpass-recycled": "താà´\99àµ\8dà´\95à´³àµ\81à´\9fàµ\86 à´°à´¹à´¸àµ\8dയവാà´\95àµ\8dà´\95àµ\8d à´¨à´¿à´²à´µà´¿à´²àµ\81à´³àµ\8dളതിൽ à´¨à´¿à´¨àµ\8dà´¨àµ\81à´\82 à´µàµ\8dയതàµ\8dയസàµ\8dതമായതായി à´®à´¾à´±àµ\8dà´±ുക.",
        "resetpass-temp-emailed": "ഇമെയിൽ വഴി ലഭിച്ച താൽക്കാലിക കോഡ് ഉപയോഗിച്ചാണ് താങ്കൾ പ്രവേശിച്ചിരിക്കുന്നത്.\nപ്രവേശനം പൂർത്തിയാക്കാൻ, ഇവിടെ പുതിയ രഹസ്യവാക്ക് സജ്ജമാക്കുക:",
        "resetpass-temp-password": "താത്കാലിക രഹസ്യവാക്ക്:",
        "resetpass-abort-generic": "രഹസ്യവാക്ക് മാറ്റുന്നത് ഒരു അനുബന്ധം തടഞ്ഞിരിക്കുന്നു.",
        "resetpass-expired": "താങ്കളുടെ രഹസ്യവാക്ക് കാലഹരണപ്പെട്ടിരിക്കുന്നു. പ്രവേശിക്കാനായി പുതിയ രഹസ്യവാക്ക് സജ്ജമാക്കുക.",
-       "resetpass-expired-soft": "താà´\99àµ\8dà´\95à´³àµ\81à´\9fàµ\86 à´°à´¹à´¸àµ\8dയവാà´\95àµ\8dà´\95àµ\8d à´\95ാലഹരണപàµ\8dà´ªàµ\86à´\9fàµ\8dà´\9fà´¿à´°à´¿à´\95àµ\8dà´\95àµ\81à´¨àµ\8dനതിനാൽ à´ªàµ\81à´¨à´\83à´¸à´\9càµ\8dà´\9càµ\80à´\95à´°à´¿à´\95àµ\8dà´\95àµ\87à´£àµ\8dà´\9fà´¤àµ\81à´£àµ\8dà´\9fàµ\8d. à´\87à´ªàµ\8dà´ªàµ\8bൾ à´¤à´¨àµ\8dà´¨àµ\86 à´ªàµ\81തിയ à´°à´¹à´¸àµ\8dയവാà´\95àµ\8dà´\95àµ\8d à´¤à´¿à´°à´\9eàµ\8dà´\9eàµ\86à´\9fàµ\81à´\95àµ\8dà´\95àµ\81à´\95 à´\85à´²àµ\8dà´²àµ\86à´\99àµ\8dà´\95ിൽ à´ªà´¿à´¨àµ\8dà´¨àµ\80à´\9fàµ\8d à´ªàµ\81à´¨à´\83à´¸à´\9càµ\8dà´\9càµ\80à´\95à´°à´¿à´\95àµ\8dà´\95ാനായി \"{{int:authprovider-resetpass-skip-label}}\" ഞെക്കുക.",
-       "resetpass-validity-soft": "താà´\99àµ\8dà´\95à´³àµ\81à´\9fàµ\86 à´°à´¹à´¸àµ\8dയവാà´\95àµ\8dà´\95àµ\8d à´¸à´¾à´§àµ\81തയàµ\81à´³àµ\8dളതലàµ\8dà´²: $1\n\nദയവായി à´ªàµ\81തിയàµ\8aà´°àµ\81 à´°à´¹à´¸àµ\8dയവാà´\95àµ\8dà´\95àµ\8d à´\87à´ªàµ\8dà´ªàµ\8bൾ à´¤à´¨àµ\8dà´¨àµ\86 à´¤à´¿à´°à´\9eàµ\8dà´\9eàµ\86à´\9fàµ\81à´\95àµ\8dà´\95àµ\81à´\95 à´\85à´²àµ\8dà´²àµ\86à´\99àµ\8dà´\95ിൽ à´ªà´¿à´¨àµ\8dà´¨àµ\80à´\9fàµ\8d à´ªàµ\81à´¨à´\83à´¸à´\9càµ\8dà´\9càµ\80à´\95à´°à´¿à´\95àµ\8dà´\95ുന്നതിനായി \"{{int:authprovider-resetpass-skip-label}}\" ഞെക്കുക.",
+       "resetpass-expired-soft": "താà´\99àµ\8dà´\95à´³àµ\81à´\9fàµ\86 à´°à´¹à´¸àµ\8dയവാà´\95àµ\8dà´\95àµ\8d à´\95ാലഹരണപàµ\8dà´ªàµ\86à´\9fàµ\8dà´\9fà´¿à´°à´¿à´\95àµ\8dà´\95àµ\81à´¨àµ\8dനതിനാൽ à´®à´¾à´±àµ\8dà´±àµ\87à´£àµ\8dà´\9fà´¤àµ\81à´£àµ\8dà´\9fàµ\8d. à´\87à´ªàµ\8dà´ªàµ\8bൾ à´¤à´¨àµ\8dà´¨àµ\86 à´ªàµ\81തിയ à´°à´¹à´¸àµ\8dയവാà´\95àµ\8dà´\95àµ\8d à´¤à´¿à´°à´\9eàµ\8dà´\9eàµ\86à´\9fàµ\81à´\95àµ\8dà´\95àµ\81à´\95 à´\85à´²àµ\8dà´²àµ\86à´\99àµ\8dà´\95ിൽ à´ªà´¿à´¨àµ\8dà´¨àµ\80à´\9fàµ\8d à´®à´¾à´±àµ\8dà´±àµ\81à´µാനായി \"{{int:authprovider-resetpass-skip-label}}\" ഞെക്കുക.",
+       "resetpass-validity-soft": "താà´\99àµ\8dà´\95à´³àµ\81à´\9fàµ\86 à´°à´¹à´¸àµ\8dയവാà´\95àµ\8dà´\95àµ\8d à´¸à´¾à´§àµ\81തയàµ\81à´³àµ\8dളതലàµ\8dà´²: $1\n\nദയവായി à´ªàµ\81തിയàµ\8aà´°àµ\81 à´°à´¹à´¸àµ\8dയവാà´\95àµ\8dà´\95àµ\8d à´\87à´ªàµ\8dà´ªàµ\8bൾ à´¤à´¨àµ\8dà´¨àµ\86 à´¤à´¿à´°à´\9eàµ\8dà´\9eàµ\86à´\9fàµ\81à´\95àµ\8dà´\95àµ\81à´\95 à´\85à´²àµ\8dà´²àµ\86à´\99àµ\8dà´\95ിൽ à´ªà´¿à´¨àµ\8dà´¨àµ\80à´\9fàµ\8d à´®à´¾à´±àµ\8dà´±ുന്നതിനായി \"{{int:authprovider-resetpass-skip-label}}\" ഞെക്കുക.",
        "passwordreset": "രഹസ്യവാക്ക് പുനഃക്രമീകരിക്കുക",
        "passwordreset-text-one": "രഹസ്യവാക്ക് പുനർസജ്ജീകരിക്കാനായി ഈ ഫോം പൂരിപ്പിക്കുക.",
        "passwordreset-text-many": "{{PLURAL:$1|ഇമെയിൽ വഴി താത്കാലിക രഹസ്യവാക്ക് ലഭിക്കാനായി താഴെ നൽകിയിരിക്കുന്നവയിൽ ഏതെങ്കിലുമൊന്ന് പൂരിപ്പിച്ചു നൽകുക.}}",
        "edit-conflict": "തിരുത്തൽ സമരസപ്പെടായ്ക.",
        "edit-no-change": "ഇപ്പോഴുള്ള സ്ഥിതിയിൽ നിന്നു യാതൊരു മാറ്റവും ഇല്ലാത്തതിനാൽ താങ്കളുടെ തിരുത്തലുകൾ തിരസ്കരിക്കപ്പെട്ടിരിക്കുന്നു.",
        "postedit-confirmation-created": "താൾ സൃഷ്ടിച്ചിരിക്കുന്നു.",
-       "postedit-confirmation-restored": "താൾ à´ªàµ\81ൻഃസ്ഥാപിച്ചിരിക്കുന്നു.",
+       "postedit-confirmation-restored": "താൾ à´ªàµ\81à´¨ഃസ്ഥാപിച്ചിരിക്കുന്നു.",
        "postedit-confirmation-saved": "താങ്കളുടെ തിരുത്ത് സേവ് ചെയ്തിരിക്കുന്നു.",
        "postedit-confirmation-published": "താങ്കളുടെ തിരുത്ത് പ്രസിദ്ധീകരിച്ചിരിക്കുന്നു.",
        "edit-already-exists": "പുതിയ താൾ സൃഷ്ടിക്കാൻ കഴിഞ്ഞില്ല.\nതാൾ ഇപ്പോൾ തന്നെ നിലവിലുണ്ട്.",
        "diff-multi-manyusers": "(ഇടയ്ക്ക് {{PLURAL:$2|ഒന്നിലധികം|$2 എണ്ണത്തിലധികം}} ഉപയോക്താക്കൾ ചെയ്തിട്ടുള്ള {{PLURAL:$1|ഒരു പതിപ്പ്|$1 പതിപ്പുകൾ}} പ്രദർശിപ്പിക്കുന്നില്ല.)",
        "difference-missing-revision": "ഈ വ്യത്യാസത്തിൽ ($1) {{PLURAL:$2|ഒരു നാൾപ്പതിപ്പ്|$2 നാൾപ്പതിപ്പുകൾ}} കാണാനായില്ല.\n\nമായ്ക്കപ്പെട്ട താളിന്റെ കാലഹരണപ്പെട്ട നാൾവഴി കണ്ണി ഉപയോഗിച്ചാലാണ് സാധാരണ ഇങ്ങനെ സംഭവിക്കുക.\nകൂടുതൽ വിവരങ്ങൾ [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} മായ്ക്കൽ രേഖയിൽ] കാണാവുന്നതാണ്.",
        "searchresults": "തിരച്ചിലിന്റെ ഫലം",
+       "search-filter-title-prefix-reset": "എല്ലാ താളുകളും തിരയുക",
        "searchresults-title": "\"$1\" എന്നു തിരഞ്ഞതിനു ലഭ്യമായ ഫലങ്ങൾ",
        "titlematches": "താളിന്റെ തലക്കെട്ടുമായി യോജിക്കുന്ന ഫലങ്ങൾ",
        "textmatches": "താങ്കൾ തിരഞ്ഞ വാക്കുകൾ ഉള്ള താളുകൾ",
        "stub-threshold-disabled": "നിർജ്ജീവമാക്കപ്പെട്ടിരിക്കുന്നു",
        "recentchangesdays": "പുതിയ മാറ്റങ്ങളിൽ കാണിക്കേണ്ട ദിവസങ്ങളുടെ എണ്ണം:",
        "recentchangesdays-max": "പരമാവധി {{PLURAL:$1|ഒരു ദിവസം|$1 ദിവസങ്ങൾ}}",
-       "recentchangescount": "സമàµ\80à´ªà´\95ാലമാറàµ\8dà´±à´\99àµ\8dà´\99ളിലàµ\81à´\82 à´¤à´¾à´³àµ\81à´\95à´³àµ\81à´\9fàµ\86 à´¨à´¾àµ¾à´ªàµ\8dപതിപàµ\8dà´ªàµ\81à´\95ളിലàµ\81à´\82 à´°àµ\87à´\96à´\95ളിലàµ\81à´\82 à´¸àµ\8dവതàµ\87 à´ªàµ\8dരദർശിപàµ\8dപിà´\95àµ\8dà´\95àµ\87à´£àµ\8dà´\9f à´¤à´¿à´°àµ\81à´¤àµ\8dതലàµ\81à´\95à´³àµ\81à´\9fàµ\86 à´\8eà´£àµ\8dà´£à´\82:",
+       "recentchangescount": "സമീപകാലമാറ്റങ്ങളിലും താളുകളുടെ നാൾപ്പതിപ്പുകളിലും രേഖകളിലും സ്വതേ പ്രദർശിപ്പിക്കേണ്ട തിരുത്തുകളുടെ എണ്ണം:",
        "prefs-help-recentchangescount": "പരമാവധി എണ്ണം: 1000",
        "prefs-help-watchlist-token2": "ഇത് താങ്കൾ ശ്രദ്ധിക്കുന്നവയുടെ  പട്ടികയുടെ വെബ്‌ഫീഡിനുള്ള രഹസ്യചാവിയാണ്.\nഇത് അറിയാവുന്നവർക്ക് താങ്കൾ ശ്രദ്ധിക്കുന്നവയെന്താണെന്ന് വായിക്കാനാവുമെന്നതിനാൽ, പങ്ക് വെയ്ക്കാതിരിക്കുക.\nതാങ്കൾക്കാവശ്യമെങ്കിൽ [[Special:ResetTokens|ഇത് പുനസജ്ജീകരിക്കാവുന്നതാണ്]].",
        "savedprefs": "താങ്കളുടെ ക്രമീകരണങ്ങൾ കാത്തുസൂക്ഷിച്ചിരിക്കുന്നു.",
        "default": "സ്വതേ",
        "prefs-files": "പ്രമാണങ്ങൾ",
        "prefs-custom-css": "സ്വന്തം സി.എസ്.എസ്.",
+       "prefs-custom-json": "ഐച്ഛിക ജെസൺ",
        "prefs-custom-js": "സ്വന്തം ജെ.എസ്.",
        "prefs-common-config": "എല്ലാ ദൃശ്യരൂപങ്ങൾക്കുമായി പങ്ക് വെയ്ക്കപ്പെട്ട സി.എസ്.എസ്./ജെസൺ/ജാവാസ്ക്രിപ്റ്റ്:",
        "prefs-reset-intro": "സൈറ്റിൽ സ്വതേയുണ്ടാവേണ്ട ക്രമീകരണങ്ങൾ പുനഃക്രമീകരിക്കാൻ താങ്കൾക്ക് ഈ താൾ ഉപയോഗിക്കാവുന്നതാണ്.\nഇത് തിരിച്ചു ചെയ്യാൻ സാദ്ധ്യമല്ല.",
        "prefs-dateformat": "ദിന ലേഖന രീതി",
        "prefs-timeoffset": "സമയ വ്യത്യാസം",
        "prefs-advancedediting": "പൊതുവായിട്ടുള്ള ഐച്ഛികങ്ങൾ",
+       "prefs-developertools": "വികസന ഉപകരണങ്ങൾ",
        "prefs-editor": "എഡിറ്റർ",
        "prefs-preview": "എങ്ങനെയുണ്ടെന്ന് കാണൽ",
        "prefs-advancedrc": "വിപുലമായ ഉപാധികൾ",
        "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": "{{PLURAL:$1|ഒരു മാറ്റം|$1 മാറ്റങ്ങൾ}}, $2",
        "rcfilters-savedqueries-rename": "പേരുമാറ്റുക",
        "rcfilters-savedqueries-setdefault": "സ്വതേയുള്ളതാക്കുക",
        "rcfilters-savedqueries-unsetdefault": "സ്വതേയുള്ളതെന്നത് ഒഴിവാക്കുക",
-       "rcfilters-savedqueries-remove": "à´¨àµ\80à´\95àµ\8dà´\95à´\82 à´\9aàµ\86à´¯àµ\8dà´¯ുക",
+       "rcfilters-savedqueries-remove": "മായàµ\8dà´\95àµ\8dà´\95ുക",
        "rcfilters-savedqueries-new-name-label": "പേര്‌",
        "rcfilters-savedqueries-new-name-placeholder": "അരിപ്പയുടെ ഉപയോഗം വിവരിക്കുക",
        "rcfilters-savedqueries-apply-label": "അരിപ്പ സൃഷ്ടിക്കുക",
        "rcfilters-empty-filter": "സജീവ അരിപ്പകൾ ഇല്ല. എല്ലാ സംഭാവനകളും പ്രദർശിപ്പിക്കുന്നു.",
        "rcfilters-filterlist-title": "അരിപ്പകൾ",
        "rcfilters-filterlist-whatsthis": "ഇതെങ്ങനെയാണ് പ്രവർത്തിക്കുന്നത്?",
-       "rcfilters-filterlist-feedbacklink": "ഈ (പുതിയ) അരിച്ചെടുക്കൽ ഉപകരണങ്ങൾ എങ്ങനെയുണ്ടെന്ന് ഞങ്ങളോട് പറയുക",
+       "rcfilters-filterlist-feedbacklink": "ഈ അരിച്ചെടുക്കൽ ഉപകരണങ്ങൾ എങ്ങനെയുണ്ടെന്ന് ഞങ്ങളോട് പറയുക",
        "rcfilters-highlightbutton-title": "ഫലങ്ങൾ പ്രമുഖമാക്കി കാട്ടുക",
        "rcfilters-highlightmenu-title": "നിറം തിരഞ്ഞെടുക്കുക",
        "rcfilters-highlightmenu-help": "ഈ ഇനം പ്രമുഖമാക്കി കാട്ടാൻ ഒരു നിറം തിരഞ്ഞെടുക്കുക",
        "deadendpages": "അന്തർ വിക്കി കണ്ണിയാൽ ബന്ധിപ്പിക്കപ്പെടാത്ത താളുകൾ",
        "deadendpagestext": "താഴെക്കാണുന്ന താളുകളിൽനിന്ന് {{SITENAME}} സം‌രംഭത്തിലെ മറ്റൊരു താളിലേയ്ക്കും കണ്ണി ചേർത്തിട്ടില്ല.",
        "protectedpages": "സംരക്ഷിക്കപ്പെട്ടിരിക്കുന്ന താളുകൾ",
+       "protectedpages-filters": "അരിപ്പകൾ:",
        "protectedpages-indef": "അനന്തകാലത്തേയ്ക്ക് സംരക്ഷിക്കപ്പെട്ടവ മാത്രം",
        "protectedpages-summary": "ഇപ്പോൾ നിലവിലുള്ള സംരക്ഷിക്കപ്പെട്ടിട്ടുള്ള താളുകളുടെ പട്ടിക ഈ താളിൽ കാണാം. സൃഷ്ടിക്കുന്നതിൽ നിന്നും സംരക്ഷിക്കപ്പെട്ടിട്ടുള്ള തലക്കെട്ടുകൾക്കായി [[{{#special:ProtectedTitles}}|{{int:protectedtitles}}]] കാണുക.",
        "protectedpages-cascade": "നിർഝരിത സംരക്ഷണങ്ങൾ മാത്രം",
        "dellogpage": "മായ്ക്കൽ രേഖ",
        "dellogpagetext": "സമീപകാലത്ത് മായ്ക്കപ്പെട്ട താളുകളുടെ പട്ടിക താഴെ കാണാം.",
        "deletionlog": "മായ്ക്കൽ രേഖ",
+       "log-name-create": "താൾ സൃഷ്ടിയുടെ രേഖ",
+       "log-description-create": "സമീപകാലത്ത് സൃഷ്ടിക്കപ്പെട്ട താളുകളുടെ പട്ടിക താഴെ കാണാം.",
+       "logentry-create-create": "$3 എന്ന താൾ $1 {{GENDER:$2|സൃഷ്ടിച്ചു}}",
        "reverted": "പൂർവ്വസ്ഥിതിയിലേക്കാക്കിയിരിക്കുന്നു.",
        "deletecomment": "കാരണം:",
        "deleteotherreason": "മറ്റ്/കൂടുതൽ കാരണങ്ങൾ:",
        "whatlinkshere": "ഈ താളിലേക്കുള്ള കണ്ണികൾ",
        "whatlinkshere-title": "\"$1\" എന്ന താളിലേക്കുള്ള കണ്ണികൾ",
        "whatlinkshere-page": "താൾ:",
-       "linkshere-2": "താഴെക്കൊടുത്തിരിക്കുന്ന താളുകളിൽ നിന്നും '''$1''' എന്ന താളിലേക്ക് കണ്ണികളുണ്ട്:",
-       "nolinkshere-2": "'''$1''' എന്ന താളിലേക്ക് കണ്ണികളൊന്നും നിലവിലില്ല.",
-       "nolinkshere-ns-2": "തിരഞ്ഞെടുത്ത നാമമേഖലയിൽ '''$1''' എന്ന താളിലേക്ക് മറ്റൊരു താളുകളിൽനിന്നും കണ്ണികളില്ല.",
+       "linkshere": "താഴെക്കൊടുത്തിരിക്കുന്ന താളുകളിൽ നിന്നും '''$2''' എന്ന താളിലേക്ക് കണ്ണികളുണ്ട്:",
+       "nolinkshere": "'''$2''' എന്ന താളിലേക്ക് കണ്ണികളൊന്നും നിലവിലില്ല.",
+       "nolinkshere-ns": "തിരഞ്ഞെടുത്ത നാമമേഖലയിൽ '''$2''' എന്ന താളിലേക്ക് മറ്റൊരു താളുകളിൽനിന്നും കണ്ണികളില്ല.",
        "isredirect": "തിരിച്ചുവിടൽ താൾ",
        "istemplate": "ഉൾപ്പെടുത്തൽ",
        "isimage": "പ്രമാണത്തിന്റെ കണ്ണി",
        "thumbnail_dest_directory": "ലക്ഷ്യ ഡയറക്ടറി സൃഷ്ടിക്കുവാൻ സാധിച്ചില്ല",
        "thumbnail_image-type": "ചിത്രത്തിന്റെ തരം പിന്തുണക്കപ്പെട്ടതല്ല",
        "thumbnail_gd-library": "അപൂർണ്ണമായ ജി.ഡി. ലൈബ്രറി ക്രമീകരണം: ഫങ്ഷൻ $1 ലഭ്യമല്ല",
+       "thumbnail_image-size-zero": "ചിത്രപ്രമാണത്തിന്റെ വലിപ്പം പൂജ്യമായി കാണുന്നു.",
        "thumbnail_image-missing": "പ്രമാണം ലഭ്യമല്ലെന്നു കാണുന്നു: $1",
        "thumbnail_image-failure-limit": "ഈ ലഘുചിത്രം സൃഷ്ടിക്കാൻ നിരവധി പരാജയപ്പെട്ട ശ്രമങ്ങൾ ($1 അല്ലെങ്കിൽ കൂടുതൽ) നടന്നിട്ടുണ്ട്. ദയവായി പിന്നീട് ശ്രമിക്കുക.",
        "import": "താളുകൾ ഇറക്കുമതി ചെയ്യുക",
        "import-mapping-subpage": "ഇനിക്കൊടുക്കുന്ന താളിന്റെ ഉപതാളുകളായി ഇറക്കുമതി ചെയ്യുക:",
        "import-upload-filename": "പ്രമാണത്തിന്റെ പേര്‌",
        "import-upload-username-prefix": "അന്തർവിക്കി പൂർവ്വാക്ഷരങ്ങൾ:",
+       "import-assign-known-users": "പേരുനൽകിയിട്ടുള്ള ഉപയോക്താക്കൾ പ്രാദേശികമായി ഉണ്ടങ്കിൽ തിരുത്തുകൾ പ്രാദേശിക ഉപയോക്താക്കളുടേതായി നൽകുക",
        "import-comment": "കുറിപ്പ്:",
        "importtext": "ദയവായി സ്രോതസ്സ് വിക്കിയിൽ നിന്ന് [[Special:Export|കയറ്റുമതി ഉപകരണം]] ഉപയോഗിച്ച് പ്രമാണം കയറ്റുമതി ചെയ്യുക.\nഅത് താങ്കളുടെ കമ്പ്യൂട്ടറിൽ ശേഖരിച്ച് ഇവിടെ അപ്‌‌ലോഡ് ചെയ്യുക.",
        "importstart": "താളുകൾ ഇറക്കുമതി ചെയ്യുന്നു...",
        "imported-log-entries": "{{PLURAL:$1|രേഖയിലെ ഒരുൾപ്പെടുത്തൽ|രേഖയിലെ $1 ഉൾപ്പെടുത്തലുകൾ}} ഇറക്കുമതി ചെയ്തു.",
        "importfailed": "ഇറക്കുമതി പരാജയപ്പെട്ടു: <nowiki>$1</nowiki>",
        "importunknownsource": "അപരിചിതമായ ഇറക്കുമതി സ്രോതസ്സ് തരം",
+       "importnoprefix": "അന്തർവിക്കി പൂർവ്വപദം ഒന്നും നൽകിയിട്ടില്ലായിരുന്നു",
        "importcantopen": "ഇറക്കുമതി പ്രമാണം തുറക്കാൻ കഴിഞ്ഞില്ല",
        "importbadinterwiki": "മോശമായ അന്തർവിക്കി കണ്ണി",
        "importsuccess": "ഇറക്കുമതി ചെയ്തുകഴിഞ്ഞു!",
        "import-nonewrevisions": "ഒരു നാൾപ്പതിപ്പും ഇറക്കുമതി ചെയ്തിട്ടില്ല (എല്ലാം നിലവിൽ ഉണ്ട്, അല്ലെങ്കിൽ പിഴവുകളുള്ളതിനാൽ ഒഴിവാക്കി).",
        "xml-error-string": "$2 വരിയിൽ $1, നിര $3 (ബൈറ്റ് $4): $5",
        "import-upload": "എക്സ്.എം.എൽ. ഡേറ്റ അപ്‌‌ലോഡ് ചെയ്യുക",
-       "import-token-mismatch": "à´¸àµ\86ഷൻ à´¡à´¾à´±àµ\8dà´± à´¨à´·àµ\8dà´\9fà´ªàµ\8dà´ªàµ\86à´\9fàµ\8dà´\9fതിനാൽ à´¦à´¯à´µà´¾à´¯à´¿ à´µàµ\80à´£àµ\8dà´\9fàµ\81à´\82 à´¶àµ\8dരമിà´\95àµ\8dà´\95àµ\82à´\95",
+       "import-token-mismatch": "à´¸àµ\86ഷൻ à´¡àµ\87à´±àµ\8dà´± à´¨à´·àµ\8dà´\9fà´ªàµ\8dà´ªàµ\86à´\9fàµ\8dà´\9fà´¿à´°à´¿à´\95àµ\8dà´\95àµ\81à´¨àµ\8dà´¨àµ\81.\n\nതാà´\99àµ\8dà´\95ൾ à´ªàµ\81റതàµ\8dà´¤àµ\8d à´\95à´\9fà´¨àµ\8dനിà´\9fàµ\8dà´\9fàµ\81à´£àµ\8dà´\9fà´¾à´\95à´¾à´\82. '''à´\87à´ªàµ\8dà´ªàµ\8bà´´àµ\81à´\82 à´ªàµ\8dà´°à´µàµ\87ശിà´\9aàµ\8dà´\9aà´¿à´°à´¿à´\95àµ\8dà´\95àµ\81à´\95യാണàµ\86à´¨àµ\8dà´¨àµ\8d à´\89റപàµ\8dà´ªàµ\8d à´µà´°àµ\81à´¤àµ\8dതിയിà´\9fàµ\8dà´\9fàµ\8d à´µàµ\80à´£àµ\8dà´\9fàµ\81à´\82 à´¶àµ\8dരമിà´\95àµ\8dà´\95àµ\81à´\95'''.\nà´\8eà´¨àµ\8dനിà´\9fàµ\8dà´\9fàµ\81à´\82 à´¶à´°à´¿à´¯à´¾à´µàµ\81à´¨àµ\8dനിലàµ\8dà´²àµ\86à´\99àµ\8dà´\95ിൽ [[Special:UserLogout|à´²àµ\8bà´\97àµ\97à´\9fàµ\8dà´\9fàµ\8d à´\9aàµ\86à´¯àµ\8dതതിനàµ\81 à´¶àµ\87à´·à´\82]] à´µàµ\80à´£àµ\8dà´\9fàµ\81à´\82 à´²àµ\8bà´\97ിൻ à´\9aàµ\86à´¯àµ\8dà´¤àµ\81à´¨àµ\8bà´\95àµ\8dà´\95àµ\81à´\95, à´¤à´¾à´\99àµ\8dà´\95à´³àµ\81à´\9fàµ\86 à´¬àµ\8dà´°àµ\97സർ à´\88 à´¸àµ\88à´±àµ\8dറിൽ à´¨à´¿à´¨àµ\8dà´¨àµ\81à´®àµ\81à´³àµ\8dà´³ à´\95àµ\81à´\95àµ\8dà´\95à´¿à´\95ൾ à´\85à´¨àµ\81വദിà´\95àµ\8dà´\95àµ\81à´¨àµ\8dà´¨àµ\81à´£àµ\8dà´\9fàµ\86à´¨àµ\8dà´¨àµ\8d à´\89റപàµ\8dà´ªàµ\81വരàµ\81à´¤àµ\8dà´¤àµ\81à´\95.",
        "import-invalid-interwiki": "താങ്കൾ നിർദ്ദേശിച്ച വിക്കിയിൽനിന്നും ഇറക്കുമതിചെയ്യാൻ സാധിച്ചില്ല",
        "import-error-edit": "\"$1\" എന്ന താൾ തിരുത്താനുള്ള അനുമതി താങ്കൾക്ക് ഇല്ലാത്തതിനാൽ അത് ഇറക്കുമതി ചെയ്തില്ല.",
        "import-error-create": "\"$1\" എന്ന താൾ സൃഷ്ടിക്കാനുള്ള അനുമതി താങ്കൾക്ക് ഇല്ലാത്തതിനാൽ അത് ഇറക്കുമതി ചെയ്തില്ല.",
        "group-bot.css": "/* ഇവിടെ നൽകുന്ന സി.എസ്.എസ്. ബോട്ടുകൾക്ക് ബാധകമായിരിക്കും */",
        "group-sysop.css": "/* ഇവിടെ നൽകുന്ന സി.എസ്.എസ്. കാര്യനിർവാഹകർക്ക് ബാധകമായിരിക്കും */",
        "group-bureaucrat.css": "/* ഇവിടെ നൽകുന്ന സി.എസ്.എസ്. ബ്യൂറോക്രാറ്റുകൾക്ക് ബാധകമായിരിക്കും */",
+       "common.json": "/* ഇവിടെ നൽകുന്ന ജെസൺ എല്ലാ ഉപയോക്താക്കൾക്കും, എല്ലാ താളുകളിലും പ്രവർത്തിക്കുന്നതായിരിക്കും */",
        "common.js": "/* ഇവിടെ നൽകുന്ന ജാവാസ്ക്രിപ്റ്റ് എല്ലാ ഉപയോക്താക്കൾക്കും, എല്ലാ താളുകളിലും പ്രവർത്തിക്കുന്നതായിരിക്കും */",
        "group-autoconfirmed.js": "/* ഇവിടെ നൽകുന്ന ജാവാസ്ക്രിപ്റ്റ് യാന്ത്രികമായി സ്ഥിരീകരിക്കപ്പെട്ട ഉപയോക്താക്കൾക്ക് ബാധകമായിരിക്കും */",
        "group-bot.js": "/* ഇവിടെ നൽകുന്ന ജാവാസ്ക്രിപ്റ്റ് ബോട്ടുകൾക്ക് ബാധകമായിരിക്കും */",
        "markedaspatrollederrornotify": "റോന്തുചുറ്റിയതെന്ന് അടയാളപ്പെടുത്തൽ പരാജയപ്പെട്ടു.",
        "patrol-log-page": "റോന്തുചുറ്റൽ പ്രവർത്തനരേഖ",
        "patrol-log-header": "റോന്തുചുറ്റപ്പെട്ട നാൾപ്പതിപ്പുകളുടെ രേഖയാണിത്",
-       "log-show-hide-patrol": "റോന്തുചുറ്റൽ രേഖ $1",
-       "log-show-hide-tag": "ടാഗ് രേഖ $1",
        "confirm-markpatrolled-button": "ശരി",
        "confirm-markpatrolled-top": "$2 താളിലെ $3 നാൾപ്പതിപ്പ് റോന്തുചുറ്റിയതായി അടയാളപ്പെടുത്തണോ?",
        "deletedrevision": "$1 എന്ന പഴയ പതിപ്പ് മായ്ച്ചിരിക്കുന്നു",
        "newimages-hidepatrolled": "റോന്തുചുറ്റപ്പെട്ട അപ്‌ലോഡുകൾ മറയ്ക്കുക",
        "newimages-mediatype": "മീഡിയ തരം:",
        "noimages": "ഒന്നും കാണാനില്ല.",
+       "gallery-slideshow-toggle": "ലഘുചിത്രങ്ങൾ മാറ്റിക്കാണിക്കുക",
        "ilsubmit": "തിരയൂ",
        "bydate": "ദിനക്രമത്തിൽ",
        "sp-newimages-showfrom": "$2, $1 നു ശേഷം അപ്‌ലോഡ് ചെയ്ത പ്രമാണങ്ങൾ പ്രദർശിപ്പിക്കുക",
        "specialpage-securitylevel-not-allowed-title": "അനുവദിച്ചിട്ടില്ല",
        "cannotauth-not-allowed-title": "അനുമതി നിഷേധിച്ചിരിക്കുന്നു",
        "cannotauth-not-allowed": "ഈ താൾ ഉപയോഗിക്കാൻ താങ്കൾക്ക് അനുവാദമില്ല",
+       "changecredentials": "സാധൂകരണ ഇനങ്ങൾ മാറ്റുക",
+       "changecredentials-submit": "സാധൂകരണ ഇനങ്ങൾ മാറ്റുക",
+       "changecredentials-invalidsubpage": "$1 അംഗീകാരമുള്ള സാധൂകരണ രീതിയല്ല.",
+       "changecredentials-success": "താങ്കളുടെ സാധൂകരണ ഇനങ്ങൾ മാറിയിട്ടുണ്ട്.",
+       "removecredentials": "സാധൂകരണ ഇനങ്ങൾ നീക്കംചെയ്യുക",
+       "removecredentials-submit": "സാധൂകരണ ഇനങ്ങൾ നീക്കംചെയ്യുക",
+       "removecredentials-invalidsubpage": "$1 അംഗീകാരമുള്ള സാധൂകരണ രീതിയല്ല.",
+       "removecredentials-success": "താങ്കളുടെ സാധൂകരണ ഇനങ്ങൾ നീക്കംചെയ്തിട്ടുണ്ട്.",
+       "credentialsform-provider": "സാധൂകരണ രീതി:",
        "credentialsform-account": "അംഗത്വ നാമം:",
        "cannotlink-no-provider-title": "കണ്ണി ചേർക്കാവുന്ന അംഗത്വങ്ങൾ ഒന്നുമില്ല",
        "cannotlink-no-provider": "കണ്ണി ചേർക്കാവുന്ന അംഗത്വങ്ങൾ ഒന്നുമില്ല",
        "undelete-cantedit": "താങ്കൾക്ക് ഈ താൾ തിരുത്താൻ അനുമതി ഇല്ലാത്തതിനാൽ ഈ താൾ താങ്കൾക്ക് പുനഃസ്ഥാപിക്കാനാവില്ല.",
        "pagedata-title": "താൾ വിവരങ്ങൾ",
        "pagedata-not-acceptable": "ഒത്തുപോവുന്ന ഫോർമാറ്റ് കണ്ടെത്താനായില്ല. പിന്തുണയുള്ള മൈം തരങ്ങൾ: $1",
-       "pagedata-bad-title": "അസാധുവായ തലക്കെട്ട്: $1."
+       "pagedata-bad-title": "അസാധുവായ തലക്കെട്ട്: $1.",
+       "unregistered-user-config": "സുരക്ഷാകാരണങ്ങളാൽ രജിസ്റ്റർ ചെയ്യാത്ത ഉപയോക്താക്കൾക്ക് ജാവാസ്ക്രിപ്റ്റ്, സി.എസ്.എസ്., ജെസൺ ഉപയോക്തൃ ഉപതാളുകൾ എടുക്കാൻ കഴിയില്ല.",
+       "passwordpolicies": "രഹസ്യവാക്ക് നയങ്ങൾ",
+       "passwordpolicies-summary": "ഉപയോക്തൃ ഗണത്തിനായി ഈ വിക്കിയിൽ നടപ്പിലുള്ള രഹസ്യവാക്ക് നയങ്ങളുടെ പട്ടികയാണ് ഇത്.",
+       "passwordpolicies-group": "ഗണം",
+       "passwordpolicies-policies": "നയങ്ങൾ",
+       "passwordpolicies-policy-minimalpasswordlength": "രഹസ്യവാക്ക് കുറഞ്ഞത് {{PLURAL:$1|ഒരു അക്ഷരം|$1 അക്ഷരങ്ങൾ}} നീളമുള്ളതാവണം.",
+       "passwordpolicies-policy-minimumpasswordlengthtologin": "പ്രവേശിക്കാനായി രഹസ്യവാക്ക് കുറഞ്ഞത് {{PLURAL:$1|ഒരു അക്ഷരം|$1 അക്ഷരങ്ങൾ}} നീളമുള്ളതാവണം.",
+       "passwordpolicies-policy-passwordcannotmatchusername": "ഉപയോക്തൃനാമം തന്നെ രഹസ്യവാക്ക് ആകാൻ പാടില്ല",
+       "passwordpolicies-policy-passwordcannotmatchblacklist": "രഹസ്യവാക്ക് കരിമ്പട്ടികയിൽ ഉള്ള രഹസ്യവാക്കുകൾക്ക് സമാനമാകരുത്",
+       "passwordpolicies-policy-maximalpasswordlength": "രഹസ്യവാക്കിന് കുറഞ്ഞത് $1 {{PLURAL:$1|അക്ഷരം|അക്ഷരങ്ങൾ}} നീളമുണ്ടാവണം",
+       "passwordpolicies-policy-passwordcannotbepopular": "രഹസ്യവാക്ക് {{PLURAL:$1|പ്രചുരപ്രചാരത്തിൽ ഉള്ളത്|പ്രചുരപ്രചാരത്തിലുള്ള $1 രഹസ്യവാക്കുകളുടെ പട്ടികയിൽ ഉള്ളത്}} ആകരുത്."
 }
index 113c30f..84528b9 100644 (file)
        "whatlinkshere": "Энд холбогдсон хуудсууд",
        "whatlinkshere-title": "\"$1\"-д холбоостой хуудаснууд",
        "whatlinkshere-page": "Хуудас:",
-       "linkshere-2": "Дараах хуудсууд '''$1'''-тай холбогдсон байна:",
-       "nolinkshere-2": "'''$1'''-тай холбогдсон хуудас байхгүй байна.",
-       "nolinkshere-ns-2": "Сонгосон нэрний зайд '''$1''' руу холбогдсон хуудас байхгүй байна.",
+       "linkshere": "Дараах хуудсууд '''$2'''-тай холбогдсон байна:",
+       "nolinkshere": "'''$2'''-тай холбогдсон хуудас байхгүй байна.",
+       "nolinkshere-ns": "Сонгосон нэрний зайд '''$2''' руу холбогдсон хуудас байхгүй байна.",
        "isredirect": "чиглүүлэгч",
        "istemplate": "оруулалт",
        "isimage": "файлын холбоос",
        "markedaspatrollederror-noautopatrol": "Та өөрийн өөрчлөлтүүдээ эргүүлээр хянагдсан гэж тэмдэглэж болохгүй.",
        "patrol-log-page": "Эргүүлийн лог",
        "patrol-log-header": "Энэ нь манагдсан засваруудын лог юм.",
-       "log-show-hide-patrol": "мануулын логийг $1",
        "deletedrevision": "Хуучин засвар $1 нь устгагдлаа",
        "filedeleteerror-short": "Файлыг устгахад алдаа гарлаа: $1",
        "filedeleteerror-long": "Дараах файлыг устгахад алдаа гарлаа:\n\n$1",
diff --git a/languages/i18n/mni.json b/languages/i18n/mni.json
new file mode 100644 (file)
index 0000000..5f22f95
--- /dev/null
@@ -0,0 +1,879 @@
+{
+       "@metadata": {
+               "authors": [
+                       "Awangba Mangang"
+               ]
+       },
+       "tog-underline": "ꯃꯔꯤꯂꯩꯅꯥꯍꯜꯂꯨ",
+       "tog-hideminor": "ꯂꯣꯠꯂꯨ ꯈꯖꯤꯛꯇꯪ ꯁꯣꯏꯕꯗꯒꯤ",
+       "tog-hidepatrolled": "ꯂꯣꯠꯂꯨ ꯈꯖꯤꯛꯇꯪ ꯁꯣꯏꯕꯗꯒꯤ ꯍꯧꯖꯤꯛꯀꯤ ꯑꯍꯣꯡꯕꯗꯒꯤ",
+       "tog-newpageshidepatrolled": "Hide patrolled pages from new page list",
+       "tog-hidecategorization": "ꯂꯥꯃꯥꯏꯒꯤ ꯃꯊꯪ ꯃꯅꯥꯎ ꯅꯥꯏꯕꯥ ꯂꯣꯠꯄꯥ",
+       "tog-extendwatchlist": "ꯌꯦꯡꯅꯕꯥ ꯄꯥꯔꯦꯡꯗꯨ ꯄꯥꯛꯊꯣꯛꯍꯟꯂꯨ ꯑꯍꯣꯡꯕꯥ ꯂꯣꯏꯅꯥ ꯎꯅꯕꯥ, ꯍꯧꯖꯤꯛꯀꯤ ꯈꯋꯥꯏꯗꯒꯤ ꯑꯅꯛꯄ ꯑꯍꯣꯡꯕꯗꯨ ꯅꯠꯇꯕꯥ",
+       "tog-usenewrc": "Group changes by page in recent changes and watchlist",
+       "tog-numberheadings": "ꯃꯁꯥ ꯃꯇꯣꯝꯇꯥ-ꯃꯁꯤꯡ-ꯃꯀꯣꯛꯁꯤꯡ",
+       "tog-showtoolbar": "ꯁꯦꯝꯒꯠꯅꯕ ꯇꯨꯜꯕꯥꯔ ꯎꯨꯠꯂꯨ",
+       "tog-editondblclick": "꯲ ꯔꯛ ꯅꯝꯃꯒꯥ ꯂꯥꯃꯥꯏꯗꯨ ꯁꯦꯝꯒꯠꯂꯨ",
+       "tog-editsectiononrightclick": "section titles ꯗ ꯌꯦꯠꯅ ꯅꯝꯗꯨꯅꯥ ꯁꯦꯝꯒꯠꯂꯛꯅꯕꯒꯤ ꯃꯐꯝꯗꯨ ꯌꯥꯍꯟꯂꯨ",
+       "tog-watchcreations": "ꯍꯥꯞꯆꯤꯟꯂꯨ ꯑꯩꯅꯥ ꯁꯦꯝꯂꯛꯄꯥ ꯂꯥꯃꯥꯏꯗꯨ ꯑꯃꯗꯤ ꯑꯩꯅꯥ ꯊꯥꯒꯠꯂꯛꯄꯥ ꯐꯥꯏꯜ ꯗꯨ ꯑꯩꯒꯤ ꯌꯦꯡꯅꯕꯥ ꯄꯔꯦꯡꯗꯥ",
+       "tog-watchdefault": "ꯍꯥꯞꯆꯤꯟꯂꯨ ꯂꯥꯃꯥꯏ ꯑꯃꯗꯤ ꯑꯩꯅꯥ ꯁꯦꯝꯒꯠꯂꯛꯄꯥ ꯐꯥꯏꯜ ꯗꯨ ꯑꯩꯒꯤ ꯌꯦꯡꯅꯕꯥ ꯄꯔꯦꯡꯗ",
+       "tog-watchmoves": "I move to my watchlist ꯍꯥꯞꯆꯤꯟꯂꯨ ꯂꯥꯃꯥꯏ ꯑꯃꯗꯤ ꯐꯥꯏꯜꯁꯤꯡ",
+       "tog-watchdeletion": "ꯍꯥꯞꯆꯤꯟꯂꯨ ꯂꯥꯃꯥꯏ ꯑꯃꯗꯤ ꯐꯥꯏꯜ ꯑꯩꯅꯥ ꯀꯛꯊꯠꯈꯤꯕꯥ ꯗꯨ ꯑꯩꯒꯤ ꯌꯦꯡꯅꯕꯥ ꯄꯔꯦꯡꯗꯥ",
+       "tog-watchuploads": "ꯍꯥꯞꯆꯤꯟꯂꯨ ꯑꯅꯧꯕꯥ ꯐꯥꯏꯜ ꯑꯩꯅꯥ ꯊꯥꯒꯠꯈꯤꯕꯗꯨ ꯑꯩꯒꯤ ꯌꯦꯡꯅꯕꯥ ꯄꯔꯦꯡꯗꯥ",
+       "tog-watchrollback": "ꯂꯥꯃꯥꯏ ꯍꯥꯞꯆꯤꯟꯂꯨ where I have performed a rollback to ꯑꯩꯒꯤ ꯌꯦꯡꯅꯕꯥ ꯄꯔꯦꯡꯗꯥ",
+       "tog-minordefault": "Mark all edits minor by default",
+       "tog-previewontop": "Show preview before edit box",
+       "tog-previewonfirst": "Show preview on first edit",
+       "tog-enotifwatchlistpages": "Email me when a page or a file on my watchlist is changed",
+       "tog-enotifusertalkpages": "Email me when my user talk page is changed",
+       "tog-enotifminoredits": "Email me also for minor edits of pages and files",
+       "tog-enotifrevealaddr": "Reveal my email address in notification emails",
+       "tog-shownumberswatching": " watching users ꯀꯤ ꯃꯁꯤꯡꯗꯨ ꯎꯨꯠꯂꯨ",
+       "tog-oldsig": "ꯅꯪꯒꯤ gi hanna leijariba khutyek",
+       "tog-fancysig": "Khutyek tu wikitext oina khanlu(Mashamatomta Samnafam yaodaba)",
+       "tog-uselivepreview": "Anouba ꯂꯥꯃꯥꯏ chingthadabida hannagido ootlu",
+       "tog-forceeditsummary": "Ahangba semgatlakpa hapchinlak pa matamda hairak o eingonda",
+       "tog-watchlisthideown": " watchlist tagi eigi semgatlakpa c lotlu",
+       "tog-watchlisthidebots": "watchlist tagi bot semgatlakpa du lotlu",
+       "tog-watchlisthideminor": "Yengnaba Parengdagi eigi apikpa semgatlak pa su lotlu",
+       "tog-watchlisthideliu": " watchlist tagi changsinlu sijinnariba shingna semgatlakliba du lotnaba",
+       "tog-watchlistreloadautomatically": "Reload the watchlist automatically whenever a filter is changed (JavaScript required)",
+       "tog-watchlistunwatchlinks": "Add direct unwatch/watch markers ({{int:Watchlist-unwatch}}/{{int:Watchlist-unwatch-undo}}) to watched pages with changes (JavaScript required for toggle functionality)",
+       "tog-watchlisthideanons": " watchlist tagi changsinlu sijinnariba shingna semgatlakliba du lotnaba",
+       "tog-watchlisthidepatrolled": "Yengnaba Parengdagi eigi apikpa semgatlak pa su lotlu",
+       "tog-watchlisthidecategorization": "ꯂꯥꯃꯥꯏꯒꯤ ꯃꯊꯪ ꯃꯅꯥꯎ ꯅꯥꯏꯕꯥ ꯂꯣꯠꯄꯥ",
+       "tog-ccmeonemails": "Send me copies of emails I send to other users",
+       "tog-diffonly": "ꯂꯥꯃꯥꯏꯒꯤ ꯑꯌꯥꯎꯕꯥꯗꯨ ꯃꯈꯥꯒꯤ diffs ꯇꯥ ꯎꯨꯠꯀꯅꯨ",
+       "tog-showhiddencats": "ꯑꯔꯣꯠꯄꯥ ꯃꯊꯪ ꯃꯅꯥꯎ ꯅꯥꯏꯕꯗꯨ ꯎꯨꯠꯂꯨ",
+       "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",
+       "underline-always": "ꯑꯗꯨꯝ",
+       "underline-never": "ꯁꯪꯇꯧ ꯇꯧꯔꯣꯏꯗꯕꯥ",
+       "underline-default": "Skin or browser default",
+       "editfont-style": "font style ꯒꯤ ꯁꯦꯝꯒꯠꯂꯛꯅꯕꯥ ꯃꯐꯝ:",
+       "editfont-monospace": "Monospaced font",
+       "editfont-sansserif": "Sans-serif font",
+       "editfont-serif": "Serif font",
+       "sunday": "ꯅꯣꯡꯃꯥꯏꯖꯤꯡ",
+       "monday": "ꯅꯤꯡꯊꯧꯀꯥꯕꯥ",
+       "tuesday": "ꯂꯩꯄꯥꯛꯄꯣꯛꯄꯥ",
+       "wednesday": "ꯌꯨꯝꯁꯥꯀꯩꯁꯥ",
+       "thursday": "ꯁꯥꯒꯣꯜꯁꯦꯟ",
+       "friday": "ꯏꯔꯥꯏ",
+       "saturday": "ꯊꯥꯡꯖꯥ",
+       "sun": "ꯅꯨꯃꯤꯠ",
+       "mon": "ꯅꯤꯡ",
+       "tue": "ꯂꯩ",
+       "wed": "ꯌꯨꯝ",
+       "thu": "ꯁꯥꯀꯣꯜ",
+       "fri": "ꯏꯔꯥꯏ",
+       "sat": "ꯊꯥꯡ",
+       "january": "ꯖꯥꯅꯨꯋꯥꯔꯤ",
+       "february": "ꯐꯦꯕꯨꯋꯥꯔꯤ",
+       "march": "ꯃꯥꯔꯆ",
+       "april": "ꯑꯦꯄꯔꯤꯜ",
+       "may_long": "ꯃꯦ",
+       "june": "ꯖꯨꯟ",
+       "july": "ꯖꯨꯂꯥꯏ",
+       "august": "ꯑꯥꯒꯥꯁꯇ",
+       "september": "ꯁꯦꯄꯇꯦꯝꯕꯔ",
+       "october": "ꯑꯣꯛꯇꯣꯕꯔ",
+       "november": "ꯅꯣꯕꯦꯝꯕꯔ",
+       "december": "ꯗꯤꯁꯦꯝꯕꯔ",
+       "january-gen": "ꯖꯥꯅꯨꯋꯥꯔꯤ",
+       "february-gen": "ꯐꯦꯕꯨꯋꯥꯔꯤ",
+       "march-gen": "ꯃꯥꯔꯆ",
+       "april-gen": "ꯑꯦꯄꯔꯤꯜ",
+       "may-gen": "ꯃꯦ",
+       "june-gen": "ꯖꯨꯟ",
+       "july-gen": "ꯖꯨꯂꯥꯏ",
+       "august-gen": "ꯑꯥꯒꯥꯁꯇ",
+       "september-gen": "ꯁꯦꯞꯇꯦꯝꯕꯔ",
+       "october-gen": "ꯑꯣꯛꯇꯣꯕꯔ",
+       "november-gen": "ꯅꯣꯕꯦꯝꯕꯔ",
+       "december-gen": "ꯗꯤꯁꯦꯝꯕꯔ",
+       "jan": "ꯖꯥꯟ",
+       "feb": "ꯐꯦꯕ",
+       "mar": "ꯃꯥꯔ",
+       "apr": "ꯑꯦꯄꯔ",
+       "may": "ꯃꯦ",
+       "jun": "ꯖꯨꯟ",
+       "jul": "ꯖꯨꯜ",
+       "aug": "ꯑꯥꯒ",
+       "sep": "ꯁꯦꯞ",
+       "oct": "ꯑꯣꯇ",
+       "nov": "ꯅꯣꯕ",
+       "dec": "ꯗꯦꯈ",
+       "january-date": "$1 ꯖꯥꯅꯨꯋꯥꯔꯤ",
+       "february-date": "$1 ꯄꯦꯕꯔꯨꯋꯥꯔꯤ",
+       "march-date": "$1ꯃꯥꯔꯆ",
+       "april-date": "$1 ꯑꯦꯄꯔꯤꯜ",
+       "may-date": "$1 ꯃꯦ",
+       "june-date": "$1 ꯖꯨꯟ",
+       "july-date": "$1 ꯖꯨꯂꯥꯏ",
+       "august-date": "$1 ꯑꯒꯨꯁꯇ",
+       "september-date": "$1 ꯁꯦꯞꯇꯦꯝꯕꯔ",
+       "october-date": "$1 ꯑꯣꯛꯇꯣꯕꯔ",
+       "november-date": "$1 ꯅꯥꯕꯦꯝꯕꯔ",
+       "december-date": "$1 ꯗꯤꯁꯦꯝꯕꯔ",
+       "period-am": "ꯑꯦ ꯑꯦꯝ",
+       "period-pm": "ꯄꯤ ꯑꯦꯝ",
+       "pagecategories": "{{PLURAL:$1|Category|Categories}}",
+       "category_header": "$1 ꯗꯥ ꯂꯩꯕꯥ ꯂꯥꯃꯥꯏꯒꯤ ꯃꯆꯥꯈꯥꯏꯕꯥ",
+       "subcategories": "ꯃꯆꯥꯈꯥꯏꯕꯥ ꯃꯆꯥ",
+       "category-media-header": "$1 ꯗꯥ ꯂꯩꯕꯥ ꯃꯦꯗꯤꯌꯥꯒꯤ ꯃꯆꯥꯈꯥꯏꯕꯥ",
+       "category-empty": "<em>This category currently contains no pages or media.</em>",
+       "hidden-categories": "{{PLURAL:$1|Hidden category|Hidden categories}}",
+       "hidden-category-category": "ꯑꯔꯣꯠꯄꯥ ꯃꯊꯪ ꯃꯅꯥꯎ ꯅꯥꯏꯕꯥ",
+       "category-subcat-count": "{{PLURAL:$2|This category has only the following subcategory.|This category has the following {{PLURAL:$1|subcategory|$1 subcategories}}, out of $2 total.}}",
+       "category-subcat-count-limited": "This category has the following {{PLURAL:$1|subcategory|$1 subcategories}}.",
+       "category-article-count": "{{PLURAL:$2|This category contains only the following page.|The following {{PLURAL:$1|page is|$1 pages are}} in this category, out of $2 total.}}",
+       "category-article-count-limited": "The following {{PLURAL:$1|page is|$1 pages are}} in the current category.",
+       "category-file-count": "{{PLURAL:$2|This category contains only the following file.|The following {{PLURAL:$1|file is|$1 files are}} in this category, out of $2 total.}}",
+       "category-file-count-limited": "The following {{PLURAL:$1|file is|$1 files are}} in the current category.",
+       "listingcontinuesabbrev": "ꯆꯠꯊꯕꯥ",
+       "index-category": "Indexed ꯂꯥꯃꯥꯏꯁꯤꯡ",
+       "noindex-category": "Noindexed ꯂꯥꯃꯥꯏꯁꯤꯡ",
+       "broken-file-category": " ꯀꯥꯏꯔꯕꯥ file links ꯒꯥ ꯂꯣꯏꯅꯕꯥ ꯂꯥꯃꯥꯏꯁꯤꯡ",
+       "about": "ꯄꯣꯠꯇꯨꯗꯤ ꯃꯔꯝꯗꯥ",
+       "article": "ꯂꯥꯃꯥꯏꯁꯤꯗꯥ ꯌꯥꯎꯕꯥ ꯄꯨꯝꯅꯃꯛ",
+       "newwindow": "ꯑꯅꯧꯕꯥ ꯊꯣꯡꯅꯥꯎꯗꯥ ꯍꯥꯡꯗꯣꯛ ꯎ",
+       "cancel": "ꯀꯛꯊꯠꯄꯥ",
+       "moredotdotdot": "ꯋꯥꯠꯂꯤ",
+       "morenotlisted": "ꯃꯁꯤꯒꯤ ꯄꯔꯦꯡꯁꯤ ꯃꯄꯨꯡ ꯐꯥꯗꯦ",
+       "mypage": "ꯂꯥꯃꯥꯏ",
+       "mytalk": "ꯉꯥꯡꯐꯝ",
+       "anontalk": "ꯉꯥꯡꯐꯝ",
+       "navigation": "ꯆꯠꯄꯥ",
+       "and": "꯱ꯁꯪ #꯳꯲; ꯑꯃꯁꯨꯪ",
+       "faq": "FAQ",
+       "actions": "Actions",
+       "namespaces": "ꯃꯥꯃꯤꯡꯒꯤ ꯃꯐꯝ",
+       "variants": "ꯈꯦꯇꯅꯕꯥ",
+       "navigation-heading": "ꯆꯠꯅꯕ ꯌꯦꯡꯐꯝ",
+       "errorpagetitle": "ꯑꯔꯥꯟꯕꯥ",
+       "returnto": "$1 ꯗꯥ ꯍꯟꯂꯨ",
+       "tagline": "ꯗꯒꯤ",
+       "help": "ꯃꯥꯇꯦꯡ",
+       "search": "ꯊꯤꯕꯥ",
+       "search-ignored-headings": " #<!-- leave this line exactly as it is --> <pre>\n# Headings that will be ignored by search.\n# Changes to this take effect as soon as the page with the heading is indexed.\n# You can force page reindexing by doing a null edit.\n# The syntax is as follows:\n#   * Everything from a \"#\" character to the end of the line is a comment.\n#   * Every non-blank line is the exact title to ignore, case and everything.\nReferences\nExternal links\nSee also\n #</pre> <!-- leave this line exactly as it is -->",
+       "searchbutton": "ꯇꯤꯕꯥ",
+       "go": "ꯆꯠꯂꯨ",
+       "searcharticle": "ꯆꯠꯂꯨ",
+       "history": "ꯂꯥꯃꯥꯏꯒꯤ ꯄꯨꯋꯥꯔꯤ",
+       "history_short": "ꯄꯨꯋꯥꯔꯤ",
+       "history_small": "ꯄꯨꯋꯥꯔꯤ",
+       "updatedmarker": "updated since my last visit",
+       "printableversion": "ꯅꯝꯊꯣꯛꯄꯥꯌꯥꯕꯥ ꯃꯑꯣꯡ",
+       "permalink": "ꯃꯇꯝꯄꯨꯝꯕꯒꯤ ꯁꯝꯅꯐꯝ",
+       "print": "ꯅꯝꯕꯥ",
+       "view": "ꯃꯤꯠꯌꯦꯡ",
+       "view-foreign": "$1 ꯗꯥ ꯌꯦꯡꯉꯨ",
+       "edit": "ꯁꯦꯝꯒꯠꯄꯥ",
+       "edit-local": "Edit local description",
+       "create": "ꯁꯥꯕꯥ",
+       "create-local": "ꯁꯨꯋꯥꯏꯒꯤ ꯁꯟꯗꯣꯛꯅꯥ ꯇꯥꯛꯄꯗꯨ ꯍꯥꯞꯆꯤꯟꯂꯨ",
+       "delete": "ꯀꯛꯊꯠꯄꯥ",
+       "undelete_short": "Undelete {{PLURAL:$1|one edit|$1 edits}}",
+       "viewdeleted_short": "View {{PLURAL:$1|one deleted edit|$1 deleted edits}}",
+       "protect": "ꯉꯥꯛꯊꯣꯛꯂꯕꯥ",
+       "protect_change": "ꯑꯍꯣꯡꯕꯥ",
+       "unprotect": "ꯍꯥꯛꯊꯣꯛꯂꯕꯥ ꯗꯨ ꯍꯣꯡꯕꯥ",
+       "newpage": "ꯑꯅꯧꯕꯥ ꯂꯥꯃꯥꯏ",
+       "talkpagelinktext": "ꯉꯥꯡꯐꯝ",
+       "specialpage": "MediaWiki:Bs-wikiadmin-mediawiki-akhannaba-lamai-text/mni",
+       "personaltools": "ꯏꯁꯥꯒꯥ ꯂꯣꯏꯅꯕꯥ ꯈꯨꯠꯂꯥꯏ",
+       "talk": "ꯈꯟꯅ ꯅꯩꯅꯕ",
+       "views": "ꯃꯤꯠꯌꯦꯡ",
+       "toolbox": "ꯈꯨꯠꯂꯥꯏꯁꯤꯡ",
+       "tool-link-userrights": "Change {{GENDER:$1|user}} groups",
+       "tool-link-userrights-readonly": "View {{GENDER:$1|user}} groups",
+       "tool-link-emailuser": "Email this {{GENDER:$1|user}}",
+       "imagepage": "File lamai du ootlu",
+       "mediawikipage": "ꯄꯥꯎꯖꯦꯜꯒꯤ ꯂꯥꯃꯥꯏꯗꯨ ꯎꯨꯠꯂꯨ",
+       "templatepage": "ꯇꯦꯝꯄꯂꯦꯠꯀꯤ ꯂꯥꯃꯥꯏꯗꯨ ꯎꯨꯠꯂꯨ",
+       "viewhelppage": "ꯃꯇꯦꯡ ꯄꯥꯡꯅꯕꯒꯤ ꯂꯥꯃꯥꯏꯗꯨ ꯎꯨꯠꯂꯨ",
+       "categorypage": "Macahkhaiba lamai oootlooo",
+       "viewtalkpage": "ꯈꯟꯅꯥ ꯅꯩꯅꯕꯗꯨ ꯎꯨꯠꯂꯨ",
+       "otherlanguages": "ꯑꯇꯣꯞꯄꯥ ꯂꯣꯟꯁꯤꯡꯗꯥ",
+       "redirectedfrom": "(Redirected from $1)",
+       "redirectpagesub": "ꯑꯃꯨꯛ ꯍꯟꯂꯛꯄꯥ ꯂꯥꯃꯥꯏ",
+       "redirectto": "Redirect to:",
+       "lastmodifiedat": "$2$1 ꯃꯁꯤꯒꯤ ꯂꯃꯥꯏꯁꯤ ꯑꯔꯣꯏꯕꯥ ꯁꯦꯝꯒꯠꯈꯤꯕꯥ",
+       "viewcount": "This page has been accessed {{PLURAL:$1|once|$1 times}}?",
+       "protectedpage": "ꯍꯥꯛꯊꯣꯛꯂꯕꯥ ꯂꯥꯃꯥꯏ",
+       "jumpto": "ꯑꯗꯨꯗꯥ  ꯆꯣꯡꯈꯠꯄꯥ",
+       "jumptonavigation": "ꯆꯠꯄꯥ",
+       "jumptosearch": "ꯊꯤꯕꯥ",
+       "view-pool-error": "Sorry, the servers are overloaded at the moment.\nToo many users are trying to view this page.\nPlease wait a while before you try to access this page again.\n\n$1",
+       "generic-pool-error": "Sorry, the servers are overloaded at the moment.\nToo many users are trying to view this resource.\nPlease wait a while before you try to access this resource again.",
+       "pool-timeout": "ꯃꯇꯝ ꯍꯦꯟꯂꯦ ꯂꯣꯟꯅꯕꯥꯒꯤ ꯉꯥꯏꯕꯥ",
+       "pool-queuefull": "ꯄꯨꯜꯒꯤ ꯄꯔꯦꯡ ꯊꯟꯂꯦ",
+       "pool-errorunknown": "ꯁꯛꯈꯪꯗꯕꯥ ꯑꯔꯥꯟꯕꯥ",
+       "pool-servererror": "$1 ꯄꯨꯜ ꯀꯥꯎꯟꯇꯔ ꯇꯧꯅꯕꯥ ꯂꯩꯇꯔꯦ",
+       "poolcounter-usage-error": "$1:ꯁꯤꯖꯤꯟꯅꯔꯤꯕꯥ ꯑꯔꯥꯟꯕꯥ",
+       "aboutsite": "ꯃꯔꯝꯗꯥ",
+       "aboutpage": "Project:ꯃꯔꯝꯗꯥ",
+       "copyright": "$1 ꯒꯤ ꯃꯇꯦꯡꯅ ꯃꯅꯨꯡꯒꯤ ꯑꯌꯥꯑꯣꯕꯥ ꯐꯪꯒꯅꯤ ꯅꯠꯇꯔꯒꯥ ꯏꯁꯤꯟꯗꯔꯤꯒꯩ",
+       "copyrightpage": "{{ns:project}}: ꯁꯤꯟꯗꯣꯔꯛꯄꯒꯤ ꯍꯛ",
+       "currentevents": "ꯍꯧꯖꯤꯛꯀꯤ ꯊꯧꯔꯝꯁꯤꯡ",
+       "currentevents-url": "Project:houjikkee thouram",
+       "disclaimers": "ꯌꯥꯅꯤꯡꯗꯕꯥ ꯐꯣꯡꯗꯣꯛꯄꯁꯤꯡ",
+       "disclaimerpage": "Project:ꯃꯌꯥꯝꯒꯤ ꯑꯣꯏꯅꯥ ꯌꯥꯅꯤꯡꯗꯕꯥ ꯐꯣꯡꯗꯣꯔꯛꯄꯥ",
+       "edithelp": "ꯁꯦꯝꯒꯠꯅꯕꯥ ꯃꯥꯇꯦꯡ",
+       "helppage-top-gethelp": "ꯃꯥꯇꯦꯡ",
+       "mainpage": "ꯃꯔꯨ ꯑꯣꯏꯕꯥ ꯂꯃꯥꯏ",
+       "mainpage-description": "ꯃꯔꯨ ꯑꯣꯏꯕꯥ ꯂꯃꯥꯏ",
+       "policy-url": "Project:ꯈꯣꯡꯊꯥꯡ",
+       "portal": "ꯃꯤꯌꯥꯝꯒꯤ ꯄꯣꯔꯇꯦꯜ",
+       "portal-url": "Project:ꯃꯤꯌꯥꯝꯒꯤ ꯄꯣꯔꯇꯦꯜ",
+       "privacy": "ꯑꯔꯣꯟꯕꯥ ꯊꯧꯔꯥꯡ",
+       "privacypage": "Project:ꯑꯔꯣꯟꯕꯥ ꯊꯧꯔꯥꯡ",
+       "badaccess": "ꯑꯌꯥꯕꯥꯗꯨ ꯁꯣꯏꯔꯦ",
+       "badaccess-group0": "ꯅꯪ ꯍꯧꯖꯤꯛ ꯑꯦꯛꯁꯟ ꯂꯧꯈꯠꯄꯥ ꯌꯥꯗꯔꯤ ꯅꯪꯅꯥ ꯍꯪꯒꯠꯆꯔꯤꯕꯗꯨꯒꯤ ꯃꯇꯥꯡꯗ",
+       "badaccess-groups": "The action you have requested is limited to users in {{PLURAL:$2|the group|one of the groups}}: $1.",
+       "versionrequired": "ꯃꯦꯗꯤꯌꯥ ꯋꯤꯀꯤꯅ ꯋꯥꯠꯂꯤꯕꯥ $1ꯕꯔꯖꯟ",
+       "versionrequiredtext": "ꯃꯦꯗꯤꯌꯥ ꯋꯤꯀꯤꯅ ꯋꯥꯠꯂꯤꯕꯥ $1ꯕꯔꯖꯟ ꯃꯁꯤꯒꯤ ꯂꯥꯃꯥꯏꯁꯤꯗꯥ ꯁꯤꯖꯤꯟꯅꯕꯥ [[Special:Version|version page]].",
+       "ok": "ꯌꯥꯔꯦ",
+       "retrievedfrom": "$1 ꯃꯐꯝꯗꯨꯗꯒꯤ ꯑꯣꯏꯔꯛꯄꯥ",
+       "youhavenewmessages": "{{PLURAL:$3|You have}} $1 ($2).",
+       "youhavenewmessagesfromusers": "{{PLURAL:$4|You have}} $1 from {{PLURAL:$3|another user|$3 users}} ($2).",
+       "youhavenewmessagesmanyusers": "ꯅꯪ $1 ꯂꯩꯔꯦ $2 ꯁꯤꯖꯤꯟꯅꯔꯤꯕꯥ ꯃꯌꯥꯝꯗꯒꯤ",
+       "newmessageslinkplural": "{{PLURAL:$1|a new message|999=new messages}}",
+       "newmessagesdifflinkplural": "ꯑꯔꯣꯏꯕꯥ {{PLURAL:$1|change|999=changes}}",
+       "youhavenewmessagesmulti": "$1 ꯅꯪꯒꯤ ꯑꯅꯧꯕꯥ ꯃꯦꯁꯦꯁ",
+       "editsection": "ꯁꯦꯝꯒꯠꯄꯥ",
+       "editold": "ꯁꯦꯝꯒꯠꯄꯥ",
+       "viewsourceold": "ꯍꯧꯔꯛꯐꯝ ꯎꯨꯇꯂꯨ",
+       "editlink": "ꯁꯦꯝꯒꯠꯄꯥ",
+       "viewsourcelink": "ꯍꯧꯔꯛꯐꯝ ꯎꯨꯇꯂꯨ",
+       "editsectionhint": "ꯁꯦꯝꯒꯠꯄꯒꯤ ꯁꯔꯨꯛ: $1",
+       "toc": "ꯑꯌꯥꯎꯕꯥ",
+       "showtoc": "ꯎꯨꯠꯂꯨ",
+       "hidetoc": "ꯂꯣꯇꯄꯥ",
+       "collapsible-collapse": "ꯁꯨꯞꯆꯤꯟꯕꯥ",
+       "collapsible-expand": "ꯄꯥꯛꯊꯣꯛꯄꯥ",
+       "confirmable-confirm": "Are {{GENDER:$1|you}} sure?",
+       "confirmable-yes": "ꯍꯣꯏ",
+       "confirmable-no": "ꯅꯠꯇꯦ",
+       "thisisdeleted": "View or restore $1?",
+       "viewdeleted": "$1 ꯌꯦꯡꯍꯟꯂꯨ?",
+       "restorelink": "{{PLURAL:$1|one deleted edit|$1 deleted edits}}",
+       "feedlinks": "ꯐꯤꯗ",
+       "feed-invalid": "ꯌꯥꯎꯗꯕꯥ subscription feed type.",
+       "feed-unavailable": "Syndication feeds are not available",
+       "site-rss-feed": "$1 RSS feed",
+       "site-atom-feed": "$1 ꯑꯦꯇꯣꯝ ꯇꯥꯛꯄꯥ",
+       "page-rss-feed": "\"$1\" RSS feed",
+       "page-atom-feed": "\"$1\" Atom feed",
+       "red-link-title": "$1 ꯂꯃꯥꯏꯗꯨ ꯂꯩꯇꯔꯦ",
+       "sort-descending": "ꯑꯇꯦꯟꯕꯥ ꯍꯟꯊꯔꯛꯂꯤꯕꯥ",
+       "sort-ascending": "ꯑꯇꯦꯟꯕꯥ ꯍꯦꯟꯒꯠꯂꯛꯂꯤꯕꯥ",
+       "nstab-main": "ꯂꯥꯃꯥꯏ",
+       "nstab-user": "Sijinnariba Lamai",
+       "nstab-media": "ꯃꯦꯗꯤꯌꯥꯒꯤ ꯂꯥꯃꯥꯏ",
+       "nstab-special": "MediaWiki:Bs-wikiadmin-mediawiki-akhannaba-lamai-text/mni",
+       "nstab-project": "ꯄꯥꯡꯊꯣꯛꯀꯗꯕꯥ ꯂꯥꯃꯥꯏ",
+       "nstab-image": "ꯈꯣꯝꯖꯤꯟꯗꯨꯅꯥ ꯍꯥꯞꯐꯝ",
+       "nstab-mediawiki": "ꯄꯥꯎꯖꯦꯜ",
+       "nstab-template": "ꯇꯦꯝꯄꯂꯦꯠ",
+       "nstab-help": "ꯂꯥꯃꯥꯏꯒꯤ ꯃꯇꯦꯂꯧꯐꯝ",
+       "nstab-category": "ꯃꯥꯆꯥꯛꯈꯥꯏꯕꯥ",
+       "mainpage-nstab": "ꯃꯔꯨ ꯑꯣꯏꯕꯥ ꯂꯃꯥꯏ",
+       "nosuchaction": "ꯃꯁꯤꯒꯨꯕꯥ ꯃꯥꯑꯣꯡꯁꯤ ꯅꯠꯇꯦ",
+       "nosuchactiontext": "The action specified by the URL is invalid.\nYou might have mistyped the URL, or followed an incorrect link.\nThis might also indicate a bug in the software used by {{SITENAME}}.",
+       "nosuchspecialpage": "ꯃꯁꯤꯒꯥ ꯃꯥꯟꯅꯕꯥ ꯑꯈꯟꯅꯕꯥ ꯂꯥꯃꯥꯏ ꯂꯩꯇꯦ",
+       "nospecialpagetext": "<strong>You have requested an invalid special page.</strong>\n\nA list of valid special pages can be found at [[Special:SpecialPages|{{int:specialpages}}]].",
+       "error": "ꯑꯔꯥꯟꯕꯥ",
+       "databaseerror": "ꯗꯇꯥꯕꯦꯁꯀꯤ ꯑꯁꯣꯏꯕꯥ",
+       "databaseerror-text": "A database query error has occurred.\nThis may indicate a bug in the software.",
+       "databaseerror-textcl": "ꯗꯇꯥꯕꯦꯁꯀꯤ ꯅꯪꯉꯥꯏꯇꯕꯥ ꯑꯁꯣꯏꯕꯁꯤ ꯍꯧꯖꯤꯛ ꯃꯌꯣꯛꯅꯔꯤ",
+       "databaseerror-query": "Query: $1",
+       "databaseerror-function": "$1:ꯊꯧꯔꯝ",
+       "databaseerror-error": "ꯑꯁꯣꯏꯕꯥ: $1",
+       "transaction-duration-limit-exceeded": "To avoid creating high replication lag, this transaction was aborted because the write duration ($1) exceeded the $2 second limit.\nIf you are changing many items at once, try doing multiple smaller operations instead.",
+       "laggedslavemode": "<strong>Warning:</strong> Page may not contain recent updates.",
+       "readonly": "ꯗꯇꯥꯕꯦꯁ ꯊꯤꯡꯖꯤꯟꯂꯦ",
+       "enterlockreason": "ꯊꯤꯡꯖꯤꯟꯕꯒꯤ ꯃꯔꯝꯗꯨ ꯍꯥꯞꯄꯨ, ꯑꯦꯁꯇꯤꯃꯦꯠꯀꯥ ꯂꯣꯏꯅꯅ ꯍꯣꯔꯦꯟ ꯊꯤꯡꯖꯤꯟꯂꯤꯕꯗꯨ ꯊꯥꯗꯣꯧꯂꯕꯥ ꯃꯇꯝꯐꯥꯑꯣ",
+       "readonlytext": "The database is currently locked to new entries and other modifications, probably for routine database maintenance, after which it will be back to normal.\n\nThe system administrator who locked it offered this explanation: $1",
+       "missing-article": "The database did not find the text of a page that it should have found, named \"$1\" $2.\n\nThis is usually caused by following an outdated diff or history link to a page that has been deleted.\n\nIf this is not the case, you may have found a bug in the software.\nPlease report this to an [[Special:ListUsers/sysop|administrator]], making note of the URL.",
+       "missingarticle-rev": "(revision#: $1)",
+       "missingarticle-diff": "(Diff: $1, $2)",
+       "readonly_lag": "ꯗꯇꯥꯕꯦꯁ ꯁꯤ ꯃꯁꯥ ꯃꯇꯣꯝꯇꯥ ꯊꯤꯡꯖꯤꯟꯂꯦ while the slave database servers catch up to the master",
+       "nonwrite-api-promise-error": "The 'Promise-Non-Write-API-Action' HTTP header was sent but the request was to an API write module.",
+       "internalerror": "ꯃꯅꯨꯡꯒꯤ ꯑꯁꯣꯏꯕꯥ",
+       "internalerror_info": "ꯃꯅꯪꯨꯒꯤ ꯑꯁꯣꯏꯕꯥ: $1",
+       "internalerror-fatal-exception": "Fatal exception of type \"$1\"",
+       "filecopyerror": "ꯐꯥꯏꯜꯁꯤ ꯁꯤꯟꯗꯣꯛꯄꯥ ꯌꯥꯗꯔꯦ $1 ꯗꯒꯤ $2 ꯗꯥ",
+       "filerenameerror": "ꯐꯥꯏꯜꯁꯤ ꯑꯃꯨꯛ ꯅꯧꯅꯥ ꯃꯃꯤꯡ ꯊꯣꯟꯕꯥ ꯌꯥꯗꯔꯦ $1 ꯗꯒꯤ $2",
+       "filedeleteerror": "$1 ꯐꯥꯏꯜ ꯀꯛꯊꯠꯄꯥ ꯌꯥꯗꯔꯦ",
+       "directorycreateerror": "$1 ꯗꯥꯏꯔꯦꯛꯇꯔꯤ ꯁꯦꯝꯕꯥ ꯌꯥꯗꯔꯦ",
+       "directoryreadonlyerror": "$1 ꯗꯥꯏꯔꯦꯛꯇꯔꯤ ꯁꯤ ꯄꯥꯅꯕꯥ ꯈꯛꯇꯅꯤ",
+       "directorynotreadableerror": "$1 ꯗꯥꯏꯔꯦꯛꯇꯔꯤ ꯁꯤ ꯄꯥꯕꯥ ꯌꯥꯗꯦ",
+       "filenotfound": "$1 ꯐꯥꯏꯜ ꯊꯤꯕꯥ ꯐꯪꯗꯔꯦ",
+       "unexpected": "ꯊꯥꯖꯔꯨꯗꯕꯥ ꯃꯁꯤꯡ $1=$2",
+       "formerror": "ꯑꯔꯥꯟꯕꯥ: ꯐꯣꯝ ꯊꯥꯖꯤꯟꯕꯥ ꯌꯥꯗꯦ",
+       "badarticleerror": "ꯃꯁꯤꯒꯤ ꯂꯥꯃꯥꯏꯁꯤꯗꯥ ꯃꯁꯤꯒꯨꯝꯕꯥ ꯃꯥꯑꯣꯡꯁꯤ ꯄꯥꯡꯊꯣꯛꯄꯥ ꯌꯥꯗꯦ",
+       "cannotdelete": "ꯂꯥꯃꯥꯏ ꯅꯠꯇꯔꯒꯥ $1 ꯐꯥꯏꯜ ꯁꯤ ꯀꯛꯊꯠꯄꯥ ꯌꯥꯗꯦ. \nꯃꯁꯤ ꯍꯥꯟꯅꯅ ꯃꯤꯑꯣꯏ ꯈꯔꯅꯥ ꯀꯛꯊꯠꯈꯔꯦ",
+       "cannotdelete-title": "$1 ꯂꯥꯃꯥꯏꯁꯤ ꯀꯛꯊꯠꯄꯥ ꯌꯥꯗꯦ",
+       "delete-hook-aborted": "ꯀꯛꯊꯠꯄꯥ aborted by hook.\nIt gave no ꯁꯟꯇꯣꯛꯅꯥ ꯇꯥꯛꯄꯥ",
+       "no-null-revision": "$1ꯂꯥꯃꯥꯏꯒꯤ ꯑꯅꯧꯕꯥ ꯀꯔꯤꯝꯇꯥ ꯌꯥꯑꯣꯗꯕꯥ ꯑꯃꯨꯛꯍꯟꯕꯥ ꯃꯤꯠꯌꯦꯡꯗꯥ ꯁꯦꯝꯕꯥ ꯌꯥꯗꯦ",
+       "badtitle": "ꯑꯐꯠꯇꯕꯥ ꯃꯃꯤꯡ",
+       "badtitletext": "The requested page title was invalid, empty, or an incorrectly linked inter-language or inter-wiki title.\nIt may contain one or more characters that cannot be used in titles.",
+       "title-invalid-empty": "The requested page title is empty or contains only the name of a namespace.",
+       "title-invalid-utf8": "The requested page title contains an invalid UTF-8 sequence.",
+       "title-invalid-interwiki": "ꯍꯪꯒꯠꯆꯔꯤꯕꯥ ꯂꯥꯃꯥꯏꯁꯤꯒꯤ ꯃꯃꯤꯡ ꯁꯤ ꯋꯤꯀꯤ ꯒꯥ ꯃꯔꯤ ꯂꯩꯅꯕꯥ ꯁꯝꯅꯐꯝ ꯌꯥꯑꯣ ꯏ ꯃꯗꯨꯗꯤ ꯃꯃꯤꯡ ꯑꯣꯏꯅꯥ ꯁꯤꯖꯤꯟꯅꯕꯥ ꯌꯥꯗꯕꯥ",
+       "viewsource": "ꯍꯧꯔꯛꯐꯝ ꯎꯨꯇꯂꯨ",
+       "viewsource-title": "$1 ꯒꯤ ꯍꯧꯔꯛꯐꯝ ꯎꯨꯠꯂꯨ",
+       "viewsourcetext": "ꯅꯪꯅꯥ ꯌꯦꯡꯕꯥ ꯌꯥꯒꯅꯤ ꯑꯃꯗꯤ ꯃꯁꯤꯒꯤ ꯂꯥꯃꯥꯏꯁꯤꯒꯤ ꯍꯧꯔꯛꯐꯝ ꯁꯤꯟꯇꯣꯛ ꯎ",
+       "mycustomjsonprotected": "ꯅꯪꯅꯥ ꯃꯁꯤ json ꯂꯥꯃꯥꯏꯁꯤ ꯁꯦꯝꯒꯠꯅꯕꯥ ꯑꯌꯥꯕꯥ ꯄꯤꯗꯦ",
+       "mycustomjsprotected": "JavaScript ꯂꯥꯃꯥꯏꯁꯤ ꯅꯪꯅꯥ ꯁꯦꯝꯒꯠꯅꯕꯒꯤ ꯑꯌꯥꯕꯥ ꯄꯤꯗꯦ",
+       "myprivateinfoprotected": "ꯅꯪꯅꯥ ꯅꯪꯒꯤ ꯑꯔꯣꯟꯕꯥ ꯑꯀꯨꯞꯄ ꯋꯥꯔꯣꯜ ꯂꯧꯐꯝ ꯁꯤ ꯁꯦꯝꯒꯠꯅꯕꯒꯤ ꯑꯌꯥꯕꯥ ꯄꯤꯗꯦ",
+       "mypreferencesprotected": "ꯅꯪꯅꯥ ꯅꯪꯒꯤ ꯄꯔꯤꯐꯔꯦꯟꯁ ꯁꯤ ꯁꯦꯝꯒꯠꯅꯕꯒꯤ ꯑꯌꯥꯕꯥ ꯄꯤꯗꯦ",
+       "ns-specialprotected": "ꯑꯈꯟꯅꯕꯥ ꯂꯥꯃꯥꯏꯅꯤ ꯁꯦꯝꯗꯣꯛꯄꯥ ꯌꯥꯗꯦ",
+       "titleprotected": "ꯃꯁꯤꯒꯤ ꯃꯃꯤꯡ ꯁꯤ ꯉꯥꯛꯊꯣꯛꯂꯦ ꯁꯥꯒꯠꯂꯛꯄꯗꯥ [[User:$1|$1]].\nThe reason given is <em>$2</em>.",
+       "filereadonlyerror": "Unable to modify the file \"$1\" because the file repository \"$2\" is in read-only mode.\n\nThe system administrator who locked it offered this explanation: \"$3\".",
+       "invalidtitle-knownnamespace": "Invalid title with namespace \"$2\" and text \"$3\"",
+       "invalidtitle-unknownnamespace": "Invalid title with unknown namespace number $1 and text \"$2\"",
+       "exception-nologin": "ꯂꯦꯒ ꯏꯟ ꯇꯧꯗꯦ",
+       "exception-nologin-text": "ꯆꯥꯟꯕꯤꯗꯨꯅꯥ ꯂꯣꯒ ꯏꯟ ꯇꯧꯁꯤꯟꯂꯨ ꯃꯁꯤꯒꯤ ꯂꯥꯃꯥꯏꯁꯤꯗꯥ ꯆꯪꯁꯤꯟꯅꯕꯥ ꯅꯠꯇꯔꯒꯥ ꯃꯊꯧ ꯄꯥꯡꯊꯣꯛꯅꯕꯥ",
+       "exception-nologin-text-manual": "Please $1 to be able to access this page or action.",
+       "virus-badscanner": "ꯑꯐꯠꯇꯕꯥ ꯀꯟꯐꯤꯒꯨꯔꯦꯁꯟ: Unknown virus scanner: <em>$1</em>",
+       "virus-scanfailed": "ꯁꯦꯡꯗꯣꯛꯄꯥ ꯃꯥꯏꯄꯥꯛꯇꯔꯦ (code $1)",
+       "virus-unknownscanner": "ꯁꯛꯈꯪꯗꯕꯥ ꯑꯦꯟꯇꯤ ꯕꯥꯏꯔꯨꯁ",
+       "logouttext": "<strong>You are now logged out.</strong>\n\nNote that some pages may continue to be displayed as if you were still logged in, until you clear your browser cache.",
+       "cannotlogoutnow-title": "ꯍꯧꯖꯤꯛ ꯂꯣꯒ out ꯇꯧꯕꯥ ꯌꯥꯗꯦ",
+       "cannotlogoutnow-text": "$1 ꯁꯤꯖꯤꯟꯅꯔꯤꯉꯩꯗꯥ ꯂꯣꯒꯒꯤꯡ out ꯁꯤ ꯑꯣꯏꯊꯣꯛꯇꯦ",
+       "welcomeuser": "$1ꯂꯦꯡꯁꯤꯟꯕꯤꯔꯛꯁꯤ",
+       "welcomecreation-msg": "ꯅꯪꯒꯤ ꯑꯦꯀꯥꯎꯟꯇ ꯁꯤ ꯁꯥꯈꯔꯦ\nꯅꯪꯒꯤ ꯑꯄꯥꯝꯕꯒꯤ ꯃꯇꯨꯡ ꯏꯟꯅꯥ ꯍꯣꯡꯗꯣꯛꯄꯥ ꯌꯥꯔꯦ ꯅꯪꯅꯥ {{SITENAME}} [[Special:Preferences|preferences]] ꯅꯪꯒꯤ ꯑꯄꯥꯝꯕꯒꯤ ꯃꯇꯨꯡꯏꯟꯅꯥ.",
+       "yourname": "ꯁꯤꯖꯤꯟꯅꯔꯤꯕꯥ ꯃꯃꯤꯡ",
+       "userlogin-yourname": "Username",
+       "userlogin-yourname-ph": "Enter your username",
+       "createacct-another-username-ph": "ꯁꯤꯖꯤꯟꯅꯔꯤꯕꯥ ꯃꯃꯤꯡ ꯗꯨ ꯏꯁꯤꯟꯂꯣ",
+       "yourpassword": "ꯆꯪꯁꯤꯟꯅꯕꯥ ꯋꯥꯍꯩ",
+       "userlogin-yourpassword": "ꯆꯪꯁꯤꯟꯅꯕꯥ ꯋꯥꯍꯩ",
+       "userlogin-yourpassword-ph": "ꯄꯥꯁꯋ꯭ꯇ ꯏꯔꯛ ꯎ",
+       "createacct-yourpassword-ph": "ꯄꯥꯁꯋ꯭ꯇ ꯏꯔꯛ ꯎ",
+       "yourpasswordagain": "ꯑꯃꯨꯛꯍꯟꯅꯥ ꯄꯥꯁꯋꯔꯇ ꯅꯝꯃꯨ",
+       "createacct-yourpasswordagain": "Confirm password",
+       "createacct-yourpasswordagain-ph": "ꯑꯃꯨꯛ ꯍꯟꯅꯥ ꯄꯥꯁꯋ꯭ꯇ ꯏꯌꯨ",
+       "userlogin-remembermypassword": "ꯑꯩꯕꯨ ꯑꯗꯨꯝ ꯂꯣꯒ ꯏꯟ ꯇꯧꯍꯟꯂꯨ",
+       "userlogin-signwithsecure": "ꯁꯣꯏꯔꯣꯏꯗꯕꯥ ꯁꯝꯅꯕꯥ  ꯁꯤꯖꯤꯟ ꯅꯧ",
+       "cannotlogin-title": "ꯂꯣꯒ ꯏꯟ ꯌꯥꯗꯦ",
+       "cannotlogin-text": "ꯂꯣꯒ ꯏꯟ ꯁꯤ ꯑꯣꯏꯊꯣꯛꯇꯦ",
+       "cannotloginnow-title": "ꯍꯧꯖꯤꯛ ꯂꯣꯒ ꯏꯟ ꯇꯧꯕꯥ ꯌꯥꯗꯦ",
+       "cannotloginnow-text": "$1 ꯁꯤꯖꯤꯟꯅꯔꯤꯉꯩꯗꯥ ꯂꯣꯒꯒꯤꯡ ꯏꯟ ꯁꯤ ꯑꯣꯏꯊꯣꯛꯇꯦ",
+       "cannotcreateaccount-title": "ꯑꯦꯀꯥꯎꯟ ꯁꯥꯕꯥ ꯌꯥꯗꯦ",
+       "cannotcreateaccount-text": "ꯍꯦꯛꯇꯥ ꯑꯣꯀꯥꯎꯅ ꯁꯥꯕꯥ ꯁꯤ ꯃꯁꯤꯒꯤ ꯋꯤꯀꯤ ꯁꯤ ꯗ ꯌꯥꯍꯟꯗꯦ",
+       "yourdomainname": "ꯅꯪꯒꯤ ꯗꯣꯃꯦꯟ",
+       "password-change-forbidden": "ꯅꯪꯅꯥ ꯃꯁꯤꯒꯤ ꯋꯤꯀꯤ ꯁꯤꯗꯥ ꯄꯥꯁꯋꯔꯇ ꯍꯣꯡꯕꯥ ꯌꯥꯔꯣꯏ",
+       "externaldberror": "There was either an authentication database error or you are not allowed to update your external account.",
+       "login": "Chang Sinba",
+       "login-security": "ꯅꯪꯒꯤ ꯁꯛꯑꯣꯡ ꯈꯟꯗꯣꯛꯄꯥ",
+       "nav-login-createaccount": "ꯂꯣꯒ ꯏꯟ/ꯑꯦꯀꯥꯎꯟ ꯁꯥꯕꯥ",
+       "logout": "Log out",
+       "userlogout": "ꯂꯣꯒ ꯑꯧꯇ",
+       "notloggedin": "ꯂꯦꯒ ꯏꯟ ꯇꯧꯗꯦ",
+       "userlogin-noaccount": "ꯑꯦꯀꯥꯎꯟ ꯂꯩꯇꯕꯔꯥ",
+       "userlogin-joinproject": "ꯌꯥꯎꯕꯥ {{ꯃꯃꯤꯡ ꯏꯐꯝ}}",
+       "createaccount": "ꯑꯩꯒꯤ ꯑꯣꯏꯕꯥ ꯑꯃꯥ ꯁꯦꯝꯕꯥ",
+       "userlogin-resetpassword-link": "ꯄꯥꯁꯋꯔꯇ ꯀꯥꯎꯈꯔꯕꯥ",
+       "userlogin-helplink2": "ꯂꯣꯒꯒꯤꯡ ꯇꯧꯗꯨꯅꯥ ꯃꯇꯦꯡ ꯄꯥꯡ ꯎ",
+       "userlogin-loggedin": "You are already logged in as {{GENDER:$1|$1}}.\nUse the form below to log in as another user.",
+       "userlogin-reauth": "You must log in again to verify that you are {{GENDER:$1|$1}}.",
+       "userlogin-createanother": "ꯅꯪꯒꯤ ꯑꯇꯣꯞꯄꯥ ꯑꯦꯀꯥꯎꯟꯇ ꯁꯦꯝꯕꯥ",
+       "createacct-emailrequired": "ꯏꯃꯦꯜ ꯂꯥꯐꯝ",
+       "createacct-emailoptional": "Email address (ꯑꯇꯣꯞꯄꯥ ꯱)",
+       "createacct-email-ph": "Enter your email address",
+       "createacct-another-email-ph": "Enter your email address",
+       "createaccountmail": "Use a temporary random password and send it to the specified email address",
+       "createaccountmail-help": "ꯄꯥꯁꯋꯔꯇ ꯈꯪꯗꯅꯥ ꯑꯇꯣꯞꯄꯒꯤ ꯑꯦꯀꯥꯎꯟ ꯁꯥꯕꯗꯥ ꯁꯤꯖꯤꯟꯅꯕꯥ ꯌꯥꯏ",
+       "createacct-realname": "ꯑꯆꯨꯝꯕꯥ ꯃꯃꯤꯡ(ꯑꯇꯣꯞꯄꯥ ꯱)",
+       "createacct-reason": "ꯃꯔꯝ",
+       "createacct-reason-ph": "ꯅꯪꯅꯥ ꯀꯔꯤꯒꯤ ꯑꯇꯣꯞꯄꯥ ꯑꯦꯀꯥꯎꯟ ꯁꯥꯔꯤꯅꯣ",
+       "createacct-reason-help": "ꯄꯥꯎꯖꯦꯜꯁꯤ ꯑꯦꯀꯥꯎꯟ ꯁꯦꯝꯕꯥ ꯂꯣꯒ ꯇꯥ ꯎꯨꯠꯂꯦ",
+       "createacct-submit": "ꯅꯪꯒꯤ ꯑꯦꯀꯥꯎꯟꯇ ꯁꯦꯝꯕꯥ",
+       "createacct-another-submit": "ꯑꯩꯒꯤ ꯑꯣꯏꯕꯥ ꯑꯃꯥ ꯁꯦꯝꯕꯥ",
+       "createacct-continue-submit": "ꯃꯈꯥ ꯆꯠꯊꯧ ꯑꯦꯀꯥꯎꯟ ꯁꯦꯝꯕꯗꯨ",
+       "createacct-another-continue-submit": "ꯃꯈꯥ ꯆꯠꯊꯧ ꯑꯦꯀꯥꯎꯟ ꯁꯦꯝꯕꯗꯨ",
+       "createacct-benefit-heading": "{{SITENAME}} ꯁꯤ ꯅꯪꯒꯥ ꯃꯥꯟꯅꯕꯥ ꯃꯤꯑꯣꯏꯁꯤꯡꯅꯥ ꯁꯦꯝꯕꯅꯤ",
+       "createacct-benefit-body1": "{{PLURAL:$1|edit|edits}}",
+       "createacct-benefit-body2": "{{PLURAL:$1|page|pages}}",
+       "createacct-benefit-body3": "ꯍꯧꯖꯤꯛꯀꯤ {{PLURAL:$1|contributor|contributors}}",
+       "badretype": "ꯅꯪꯅꯥ ꯏꯔꯤꯕꯥ ꯄꯥꯡꯋꯔꯇ ꯁꯤ ꯆꯥꯟꯅꯗꯔꯦ",
+       "usernameinprogress": "ꯉꯍꯥꯛꯇꯪ ꯉꯥꯏꯕꯤꯈꯣ ꯃꯁꯤꯒꯤ ꯁꯤꯖꯤꯟꯅꯔꯤꯕꯥ ꯃꯃꯤꯡ ꯁꯤ ꯒꯤ ꯑꯦꯀꯥꯎꯟ ꯁꯦꯝꯕꯗꯥ ꯈꯨꯃꯥꯡ ꯆꯥꯎꯁꯤꯟꯂꯦ",
+       "createacct-error": "ꯑꯀꯥꯎꯟ ꯁꯦꯝꯕꯗꯥ ꯑꯁꯣꯏꯕꯥ ꯂꯩꯔꯦ",
+       "createaccounterror": "$1 ꯑꯦꯀꯥꯎꯟ ꯁꯥꯕꯥ ꯌꯥꯗꯔꯦ",
+       "nocookiesnew": "The user account was created, but you are not logged in.\n{{SITENAME}} uses cookies to log in users.\nYou have cookies disabled.\nPlease enable them, then log in with your new username and password.",
+       "nocookieslogin": "{{SITENAME}} uses cookies to log in users.\nYou have cookies disabled.\nPlease enable them and try again.",
+       "loginsuccesstitle": "ꯂꯣꯒ ꯏꯟ",
+       "login-userblocked": "ꯃꯁꯤꯒꯤ ꯁꯤꯖꯤꯟꯅꯔꯤꯕꯥꯁꯤ ꯊꯤꯡꯖꯤꯟꯈꯔꯦ? ꯂꯣꯒ ꯏꯟ ꯌꯥꯔꯥꯔꯣꯏ",
+       "passwordtooshort": "ꯄꯥꯁꯋꯔꯇ ꯁꯤ ꯌꯥꯝꯗꯔꯕꯗꯥ ꯃꯁꯤ ꯈꯔꯥꯁꯤ ꯌꯥꯎꯒꯗꯕꯅꯤ {{PLURAL:$1|1 character|$1 characters}}.",
+       "mailmypassword": "ꯄꯥꯁꯋ꯭ꯇ ꯁꯦꯝꯗꯣꯛꯄꯥ",
+       "passwordremindertitle": " {{SITENAME}} ꯁꯤꯒꯤ ꯑꯅꯧꯕꯥ ꯉꯥꯏꯍꯥꯛꯀꯤ ꯑꯣꯏꯕꯥ ꯄꯥꯁꯋꯔꯇ",
+       "passwordremindertext": "Someone (from IP address $1) requested a new\npassword for {{SITENAME}} ($4). A temporary password for user\n\"$2\" has been created and was set to \"$3\". If this was your\nintent, you will need to log in and choose a new password now.\nYour temporary password will expire in {{PLURAL:$5|one day|$5 days}}.\n\nIf someone else made this request, or if you have remembered your password,\nand you no longer wish to change it, you may ignore this message and\ncontinue using your old password.",
+       "emailconfirmlink": "ꯅꯪꯒꯤ ꯏꯃꯦꯜ ꯑꯦꯗꯔꯦꯁ ꯌꯥꯕꯔꯥ ꯌꯦꯡ ꯎ",
+       "accountcreated": "ꯑꯦꯀꯥꯎꯟ ꯁꯥꯈꯔꯦ",
+       "loginlanguagelabel": "$1 ꯂꯣꯟ",
+       "pt-login": "ꯆꯪꯁꯤꯟꯕ ꯃꯅꯨꯪꯗ",
+       "pt-login-button": "Chang Sinba",
+       "pt-login-continue-button": "ꯂꯣꯘ ꯏꯟ ꯃꯈꯥ ꯆꯠꯊꯧ",
+       "pt-createaccount": "ꯑꯩꯒꯤ ꯑꯣꯏꯕꯥ ꯑꯃꯥ ꯁꯦꯝꯕꯥ",
+       "pt-userlogout": "Log out",
+       "changepassword": "ꯄꯥꯁꯋ꯭ꯔꯇ ꯍꯣꯡꯗꯣꯛꯄꯥ",
+       "oldpassword": "ꯑꯔꯤꯕꯥ ꯄꯥꯁꯋꯔꯇ",
+       "newpassword": "ꯑꯅꯧꯕꯥ ꯄꯥꯁꯋꯔꯇ",
+       "retypenew": "ꯑꯃꯨꯛꯍꯟꯅꯥ ꯑꯅꯧꯕꯥ  ꯄꯥꯁꯋꯔꯇ ꯅꯝꯃꯨ",
+       "resetpass_submit": "ꯄꯥꯁꯋꯔꯇ ꯁꯦꯝꯃꯨ ꯱ꯗꯤ ꯂꯣꯒ ꯏꯟ",
+       "changepassword-success": "ꯅꯪꯒꯤ ꯄꯥꯁꯋꯔꯇ ꯁꯤ ꯍꯣꯡꯗꯣꯛꯈꯔꯦ",
+       "changepassword-throttled": "You have made too many recent login attempts.\nPlease wait $1 before trying again.",
+       "botpasswords": "ꯕꯣꯇ ꯄꯥꯁꯋꯔꯇ",
+       "botpasswords-summary": "<em>Bot passwords</em> allow access to a user account via the API without using the account's main login credentials. The user rights available when logged in with a bot password may be restricted.\n\nIf you don't know why you might want to do this, you should probably not do it. No one should ever ask you to generate one of these and give it to them.",
+       "botpasswords-disabled": "ꯕꯣꯇ ꯄꯥꯁꯋꯔꯇ ꯌꯥꯉꯟꯗꯕꯥ",
+       "botpasswords-label-create": "ꯁꯥꯕꯥ",
+       "botpasswords-label-update": "ꯅꯧꯊꯣꯛꯍꯟꯕꯥ",
+       "botpasswords-label-cancel": "ꯀꯛꯊꯠꯄꯥ",
+       "botpasswords-label-delete": "ꯃꯥꯡꯍꯟꯕꯥ",
+       "botpasswords-label-resetpassword": "ꯄꯥꯁꯋ꯭ꯇ ꯑꯃꯨꯛ ꯍꯟꯅꯥ ꯁꯦꯝꯗꯣꯛꯄꯥ",
+       "botpasswords-label-grants": "ꯆꯥꯟꯅꯕꯥ ꯌꯥꯕꯥ ꯑꯌꯥꯕ",
+       "botpasswords-help-grants": "Grants allow access to rights already held by your user account. Enabling a grant here does not provide access to any rights that your user account would not otherwise have. See the [[Special:ListGrants|table of grants]] for more information.",
+       "botpasswords-created-title": "ꯕꯣꯠ ꯄꯥꯁꯋ꯭ꯔꯇ ꯁꯥꯈꯔꯦ",
+       "botpasswords-deleted-title": "ꯕꯣꯠ ꯄꯥꯁꯋ꯭ꯔꯇ ꯀꯛꯊꯠꯈꯔꯦ",
+       "resetpass_forbidden": "ꯄꯥꯁꯋ꯭ꯔꯇ ꯍꯣꯡꯗꯣꯧꯄꯥ ꯌꯥꯔꯣꯏ",
+       "resetpass_forbidden-reason": "$1 ꯄꯥꯁꯋ꯭ꯔꯇ ꯍꯣꯡꯗꯣꯧꯄꯥ ꯌꯥꯔꯣꯏ",
+       "resetpass-no-info": "ꯃꯁꯤꯒꯤ ꯂꯥꯃꯥꯏꯁꯤ ꯍꯦꯧꯇꯥ ꯌꯧꯅꯕꯥ ꯅꯪ ꯁꯣꯏꯗꯅꯥ ꯂꯣꯒ ꯏꯟ ꯇꯧꯒꯗꯕꯅꯤ",
+       "resetpass-submit-loggedin": "ꯄꯥꯁꯋ꯭ꯔꯇ ꯍꯣꯡꯗꯣꯛꯄꯥ",
+       "resetpass-submit-cancel": "ꯀꯛꯊꯠꯄꯥ",
+       "resetpass-wrong-oldpass": "ꯃꯇꯝ ꯈꯔꯥꯒꯤ ꯑꯣꯏꯅꯥ ꯀꯔꯤꯝꯇꯥ ꯌꯥꯎꯗꯦ  ꯅꯠꯇꯔꯒꯥ ꯍꯧꯖꯤꯧꯀꯤ ꯄꯥꯁꯋ꯭ꯔꯇ꯫\nꯅꯪꯅꯥ ꯄꯥꯁꯋꯑꯔꯇ ꯍꯥꯟꯅꯗꯒꯤ ꯍꯣꯡꯂꯝꯂꯅꯤ ꯅꯠꯇꯔꯒꯥ ꯍꯪꯒꯠꯂꯨ ꯉꯥꯏꯍꯥꯛꯀꯤ ꯑꯣꯏꯕꯥ ꯄꯥꯁꯋ꯭ꯔꯇ",
+       "resetpass-temp-password": "ꯉꯩꯍꯥꯛꯀꯤ ꯑꯣꯏꯕꯥ ꯄꯥꯁꯋ꯭ꯔꯇ",
+       "passwordreset": "ꯄꯥꯁꯋ꯭ꯇ ꯁꯦꯝꯗꯣꯛꯄꯥ",
+       "passwordreset-username": "ꯁꯤꯖꯤꯟꯅꯔꯤꯕꯥ ꯃꯃꯤꯡ",
+       "passwordreset-domain": "ꯗꯣꯃꯦꯟ",
+       "passwordreset-email": "ꯏꯃꯦꯜ ꯂꯥꯐꯝ",
+       "passwordreset-emailtitle": "{{SITENAME}} ꯑꯀꯨꯞꯄꯥ ꯃꯔꯣꯜ",
+       "passwordreset-emailtext-ip": "Someone (probably you, from IP address $1) requested a reset of your\npassword for {{SITENAME}} ($4). The following user {{PLURAL:$3|account is|accounts are}}\nassociated with this email address:\n\n$2\n\n{{PLURAL:$3|This temporary password|These temporary passwords}} will expire in {{PLURAL:$5|one day|$5 days}}.\nYou should log in and choose a new password now. If someone else made this\nrequest, or if you have remembered your original password, and you no longer\nwish to change it, you may ignore this message and continue using your old\npassword.",
+       "passwordreset-emailtext-user": "User $1 on {{SITENAME}} requested a reset of your password for {{SITENAME}}\n($4). The following user {{PLURAL:$3|account is|accounts are}} associated with this email address:\n\n$2\n\n{{PLURAL:$3|This temporary password|These temporary passwords}} will expire in {{PLURAL:$5|one day|$5 days}}.\nYou should log in and choose a new password now. If someone else made this\nrequest, or if you have remembered your original password, and you no longer\nwish to change it, you may ignore this message and continue using your old\npassword.",
+       "passwordreset-emailelement": "$1 ꯁꯤꯖꯤꯟꯅꯔꯤꯕꯥ\n$2 ꯉꯩꯍꯥꯛꯀꯤ ꯑꯣꯏꯕꯥ ꯄꯥꯁꯋꯔꯇ",
+       "changeemail-none": "ꯑꯃꯥꯇꯥ ꯅꯠꯇꯦ",
+       "changeemail-password": "ꯅꯪꯒꯤ {{SITENAME}} ꯄꯥꯁꯋ꯭ꯔꯇ:",
+       "changeemail-submit": "ꯏ-ꯃꯦꯜ ꯍꯣꯡꯕꯥ",
+       "bold_sample": "ꯆꯥꯎꯅꯥ ꯏꯕꯥ",
+       "bold_tip": "ꯆꯥꯎꯅꯥ ꯏꯕꯥ",
+       "italic_sample": "ꯋꯥꯔꯦꯡ ꯐꯆꯅꯥ ꯏꯕꯥ",
+       "italic_tip": "ꯋꯥꯔꯦꯡ ꯐꯩꯅꯥ ꯏꯕꯥ",
+       "link_sample": "ꯃꯩꯃꯤꯡꯃꯤ ꯁꯝꯅꯐꯝ",
+       "link_tip": "ꯃꯅꯨꯡꯒꯥ ꯁꯝꯅꯐꯝ",
+       "extlink_sample": "http://www.example.com link title",
+       "extlink_tip": "ꯑꯇꯣꯞꯄꯥꯒꯥ ꯁꯝꯅꯐꯝ",
+       "headline_sample": "ꯃꯀꯣꯛꯀꯤ ꯋꯥꯔꯦꯡ ꯄꯥꯔꯦꯡ",
+       "headline_tip": "꯲ ꯁꯨꯕꯥ ꯃꯀꯣꯛꯀꯤ ꯄꯔꯦꯡ",
+       "nowiki_sample": "ꯍꯥꯞꯆꯤꯟꯂꯨ non formating ꯋꯥꯔꯦꯡꯗꯨ ꯁꯤꯗꯥ",
+       "nowiki_tip": "ꯋꯤꯀꯤꯒꯤ ꯃꯥꯑꯣꯡ ꯁꯦꯝꯕꯗꯨ ꯊꯧꯑꯣꯏꯗꯕꯥ",
+       "image_tip": "ꯅꯝꯁꯤꯟꯂꯕꯥ ꯐꯥꯏꯜ",
+       "media_tip": "ꯐꯥꯏꯜꯒꯤ ꯁꯝꯅꯐꯝ",
+       "sig_tip": "ꯃꯇꯝꯒꯤ ꯏꯁꯇꯥꯝꯒꯥ ꯂꯣꯏꯟꯅꯥ ꯅꯪꯒꯤ ꯈꯨꯇꯌꯦꯛ",
+       "hr_tip": "ꯐꯩꯅꯥ ꯆꯤꯡꯕꯥ ꯂꯥ ꯏ (ꯃꯔꯤꯛ ꯃꯔꯤꯛ ꯑꯣꯏꯅꯥ ꯁꯤꯖꯤꯟꯅꯧ)",
+       "summary": "ꯑꯇꯦꯟꯕꯥ ꯁꯟꯗꯣꯛꯅꯥ ꯇꯥꯛꯄꯥ",
+       "subject": "ꯍꯤꯔꯝ",
+       "minoredit": "ꯃꯁꯤ ꯑꯄꯤꯛꯄꯥ ꯁꯦꯝꯒꯠꯄꯅꯤ",
+       "watchthis": "ꯃꯁꯤꯒꯤ ꯂꯥꯃꯥꯏꯁꯤ ꯌꯦꯡꯉꯨ",
+       "savearticle": "ꯂꯥꯃꯥꯏ ꯇꯨꯪꯁꯤꯟꯕꯥ",
+       "savechanges": "ꯑꯍꯣꯡꯕꯗꯨ ꯇꯨꯪꯁꯤꯟꯂꯨ",
+       "publishpage": "ꯂꯥꯃꯥꯏ ꯐꯣꯡꯗꯣꯛ ꯎ",
+       "publishchanges": "ꯑꯍꯣꯡꯕꯁꯤꯡꯗꯨ ꯐꯣꯡꯗꯣꯛ ꯎ",
+       "savearticle-start": "ꯂꯥꯃꯥꯏ ꯁꯤ ꯇꯨꯡꯁꯤꯜꯂꯨ",
+       "savechanges-start": "ꯑꯍꯣꯡꯕꯁꯤꯡꯗꯨ ꯇꯨꯪꯁꯤꯟꯂꯨ",
+       "publishpage-start": "ꯂꯥꯃꯥꯏ ꯐꯣꯡꯗꯣꯛ ꯎ",
+       "publishchanges-start": "ꯑꯍꯣꯡꯕꯁꯤꯡꯗꯨ ꯐꯣꯡꯗꯣꯛ ꯎ",
+       "preview": "ꯃꯥꯃꯥꯡꯒꯤ",
+       "showpreview": "ꯍꯥꯟꯅꯒꯤꯗꯨ ꯎꯨꯇꯂꯨ",
+       "showdiff": "ꯑꯍꯣꯡꯕꯗꯨ ꯎꯨꯇꯂꯨ",
+       "blankarticle": "<strong>Warning:</strong> The page you are creating is blank.\nIf you click \"$1\" again, the page will be created without any content.",
+       "anoneditwarning": "<strong>Warning:</strong> You are not logged in. Your IP address will be publicly visible if you make any edits. If you <strong>[$1 log in]</strong> or <strong>[$2 create an account]</strong>, your edits will be attributed to your username, along with other benefits.",
+       "loginreqlink": "Chang Sinba",
+       "accmailtitle": "ꯄꯥꯁꯋ꯭ꯔꯇ ꯊꯥꯕ",
+       "newarticle": "ꯑꯅꯧꯕꯥ",
+       "newarticletext": "You have followed a link to a page that does not exist yet.\nTo create the page, start typing in the box below (see the [$1 help page] for more info).\nIf you are here by mistake, click your browser's <strong>back</strong> button.",
+       "anontalkpagetext": "----\n<em>This is the discussion page for an anonymous user who has not created an account yet, or who does not use it.</em>\nWe therefore have to use the numerical IP address to identify him/her.\nSuch an IP address can be shared by several users.\nIf you are an anonymous user and feel that irrelevant comments have been directed at you, please [[Special:CreateAccount|create an account]] or [[Special:UserLogin|log in]] to avoid future confusion with other anonymous users.",
+       "noarticletext": "There is currently no text in this page.\nYou can [[Special:Search/{{PAGENAME}}|search for this page title]] in other pages,\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} search the related logs],\nor [{{fullurl:{{FULLPAGENAME}}|action=edit}} create this page]</span>.",
+       "noarticletext-nopermission": "There is currently no text in this page.\nYou can [[Special:Search/{{PAGENAME}}|search for this page title]] in other pages, or <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} search the related logs]</span>, but you do not have permission to create this page.",
+       "missing-revision": "The revision #$1 of the page named \"{{FULLPAGENAME}}\" does not exist.\n\nThis is usually caused by following an outdated history link to a page that has been deleted.\nDetails can be found in the [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} deletion log].",
+       "userpage-userdoesnotexist-view": "$1 ꯁꯤꯖꯤꯅꯅꯔꯤꯕ ꯑꯦꯀꯥꯎꯅ ꯁꯤ ꯃꯤꯡ ꯆꯟꯗꯔꯤ",
+       "continue-editing": "ꯁꯦꯝꯒꯠꯄꯒꯤ ꯃꯐꯝꯗꯨꯗꯥ ꯆꯠꯂꯨ",
+       "editing": "$1 ꯁꯦꯝꯒꯠꯂꯤ",
+       "creating": "Creating $1",
+       "editingsection": "Editing $1 (section)",
+       "yourtext": "ꯅꯪꯒꯤ ꯇꯦꯀꯁ",
+       "yourdiff": "ꯈꯦꯠꯅꯕꯥ ꯁꯤꯡ",
+       "copyrightwarning": "Please note that all contributions to {{SITENAME}} are considered to be released under the $2 (see $1 for details).\nIf you do not want your writing to be edited mercilessly and redistributed at will, then do not submit it here.<br />\nYou are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource.\n<strong>Do not submit copyrighted work without permission!</strong>",
+       "templatesused": "{{PLURAL:$1|Template|Templates}} used on this page:",
+       "template-protected": "ꯉꯥꯛꯊꯣꯛꯂꯕꯥ",
+       "template-semiprotected": "ꯇꯪꯈꯥꯏ ꯉꯥꯛꯊꯣꯛꯂꯕꯥ",
+       "hiddencategories": "This page is a member of {{PLURAL:$1|1 hidden category|$1 hidden categories}}:",
+       "permissionserrors": "ꯑꯌꯥꯕꯥꯗꯨ ꯁꯣꯏꯔꯦ",
+       "permissionserrorstext-withaction": "You do not have permission to $2, for the following {{PLURAL:$1|reason|reasons}}:",
+       "moveddeleted-notice": "ꯃꯁꯤꯒꯤ ꯂꯥꯃꯥꯏꯁꯤ ꯀꯛꯊꯠꯈꯔꯦ. \nꯀꯛꯊꯠꯄꯥ, ꯉꯥꯛꯊꯣꯛꯄꯥ ꯑꯃꯗꯤ ꯂꯣꯒ ꯂꯦꯡꯍꯟꯕꯥ ꯂꯥꯃꯥꯏꯒꯤꯗꯃꯛ ꯇꯨ ꯃꯈꯥꯒꯤ ꯁꯤꯗꯥ ꯔꯤꯐꯔꯦꯟꯁ ꯎꯨꯠꯂꯦ",
+       "edit-conflict": "ꯁ‍ꯦꯝꯒꯠꯐꯝꯒꯤ ꯈꯠꯅ ꯆꯩꯅꯕꯥ",
+       "content-model-wikitext": "ꯋꯤꯀꯤ ꯋꯥꯍꯩ ꯋꯥꯇꯥ",
+       "content-json-empty-object": "ꯑꯍꯥꯡꯕꯥ ꯄꯣꯠꯁꯛ",
+       "viewpagelogs": "ꯃꯁꯤꯒꯤ ꯂꯥꯃꯥꯏꯁꯤꯒꯤ ꯅꯧꯅ ꯆꯪꯉꯨ",
+       "currentrev-asof": "$1 ꯒꯤ ꯅꯧꯅꯥ ꯑꯃꯨꯛꯍꯟꯅꯥ ꯌꯦꯡꯕꯥ ꯃꯤꯠꯌꯦꯡ",
+       "revisionasof": "Revision as of $1",
+       "revision-info": "Revision as of $1 by {{GENDER:$6|$2}}$7",
+       "previousrevision": "ꯑꯔꯤꯕꯥ ꯑꯃꯨꯛ ꯍꯟꯅꯥ ꯌꯦꯡꯕꯥ",
+       "nextrevision": "ꯑꯅꯧꯕꯥ ꯑꯃꯨꯛꯍꯟꯅꯥ ꯌꯦꯡꯕꯥ",
+       "currentrevisionlink": "ꯈꯋꯥꯏꯗꯒꯤ ꯅꯧꯅꯥ ꯑꯃꯨꯛ ꯌꯦꯡꯕꯥ",
+       "cur": "ꯍꯧ",
+       "last": "ꯃꯃꯥꯡꯒꯤ",
+       "page_first": "ꯑꯍꯥꯟꯕ",
+       "page_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": "ꯊꯤꯋꯨ ꯑꯃꯨꯛ ꯍꯝꯁꯟꯅꯥ ꯌꯦꯡꯅꯕꯥ",
+       "histfirst": "ꯈꯋꯥꯏꯗꯒꯤ ꯑꯔꯤꯕꯥ",
+       "histlast": "ꯑꯅꯧꯕꯥ",
+       "history-feed-title": "ꯄꯨꯋꯥꯔꯤ ꯑꯃꯨꯛ ꯍꯟꯅ ꯌꯦꯡꯕ",
+       "history-feed-item-nocomment": "$2 ꯗ$1",
+       "rev-delundel": "ꯑꯍꯣꯡꯕꯥ ꯎꯍꯟꯂꯤꯕꯥ",
+       "revdelete-show-file-submit": "ꯍꯣꯏ",
+       "revdelete-radio-unset": "ꯎꯍꯟꯕ",
+       "mergelog": "ꯂꯣꯒ ꯄꯨꯟꯁꯤꯟꯕ",
+       "history-title": "Revision history of \"$1\"",
+       "difference-title": "$1 ꯒꯤ ꯑꯃꯨꯛꯍꯟꯕꯥ ꯈꯦꯠꯅꯕꯥꯒꯤ ꯃꯔꯛ",
+       "lineno": "ꯂꯥ ꯏ $1",
+       "compareselectedversions": "ꯈꯟꯒꯠꯂꯕ ꯁꯤꯡ ꯑꯃꯨꯛ ꯍꯟꯅ ꯌꯦꯡꯕꯗꯨ ꯆꯥꯡꯗꯝꯅꯧ",
+       "editundo": "ꯇꯧꯒꯅꯨ",
+       "diff-empty": "ꯈꯩꯠꯅꯕ ꯂꯩꯇꯦ",
+       "diff-multi-sameuser": "({{PLURAL:$1|One intermediate revision|$1 intermediate revisions}} by the same user not shown)",
+       "searchresults": "ꯊꯤꯕꯒꯤ ꯐꯣꯜ",
+       "searchresults-title": "Search results for \"$1\"",
+       "prevn": "ꯍꯥꯟꯅꯒꯤ {{PLURAL:$1|$1}}",
+       "nextn": "ꯃꯥꯊꯪ{{PLURAL:$1|$1}}",
+       "prevn-title": "ꯃꯃꯥꯡꯒꯤ $1 {{PLURAL:$1|result|results}}",
+       "nextn-title": "Next $1 {{PLURAL:$1|result|results}}",
+       "shown-title": "Show $1 {{PLURAL:$1|result|results}} per page",
+       "viewprevnext": "ꯎꯨꯇꯂꯨ ($1 {{int:pipe-separator}} $2) ($3)",
+       "searchmenu-new": "<strong>Create the page \"[[:$1]]\" on this wiki!</strong> {{PLURAL:$2|0=|See also the page found with your search.|See also the search results found.}}",
+       "searchprofile-articles": "ꯂꯥꯃꯥꯏꯁꯤꯡꯒꯤ ꯑꯌꯥꯎꯕ",
+       "searchprofile-images": "ꯃꯜꯇꯤꯃꯦꯗꯤꯌꯥ",
+       "searchprofile-everything": "ꯄꯨꯝꯅꯃꯛ",
+       "searchprofile-advanced": "ꯈꯨꯃꯥꯡꯆꯥꯎꯁꯤꯜꯂꯕ",
+       "searchprofile-articles-tooltip": "$1ꯗ ꯊꯤꯌꯨ",
+       "searchprofile-images-tooltip": "ꯐꯥꯏꯜꯁꯤꯡ ꯒꯤ ꯗꯃꯛ ꯊꯤꯕꯥ",
+       "searchprofile-everything-tooltip": "ꯃꯁꯤꯗ ꯌꯥꯎꯔꯤꯕꯁꯤ ꯂꯣꯏꯅ ꯊꯤꯌꯨ",
+       "searchprofile-advanced-tooltip": "ꯀꯁꯇꯝꯒꯤ ꯃꯤꯡ ꯏꯕꯝ ꯗꯒꯤ ꯊꯤꯌꯨ",
+       "search-result-size": "$1 ({{PLURAL:$2|1 word|$2 words}})",
+       "search-redirect": "(redirect from $1)",
+       "search-section": "(section $1)",
+       "search-suggest": "$1 ꯁꯤꯔꯥ ꯅꯪꯅꯥ ꯍꯥꯏꯅꯤꯡꯂꯤꯕꯥꯁꯤ",
+       "searchall": "ꯄꯨꯂꯞ",
+       "search-showingresults": "{{PLURAL:$4|Result <strong>$1</strong> of <strong>$3</strong>|Results <strong>$1 – $2</strong> of <strong>$3</strong>}}",
+       "search-nonefound": "ꯃꯁꯤꯒꯤ ꯐꯣꯜꯁꯤꯒꯥ ꯆꯥꯟꯅꯕꯥ ꯂꯩꯇꯦ",
+       "mypreferences": "Preferences",
+       "group-bot": "ꯕꯣꯇꯁꯤꯡ",
+       "group-sysop": "ꯆꯨꯞꯂꯤ ꯄꯥꯏꯔꯤꯕꯁꯤꯡ",
+       "grouppage-bot": "{{ns:project}}:ꯕꯣꯠꯁꯤꯡ",
+       "grouppage-sysop": "ꯉꯥꯛ ꯁꯦꯟꯂꯤꯕ {{ns:project}}",
+       "right-writeapi": "API sijinaduna eba",
+       "newuserlogpage": "User creation log",
+       "action-edit": "ꯃꯁꯤꯒꯤ ꯂꯥꯃꯥꯏꯁꯤ ꯁꯦꯝꯒꯠꯂꯨ",
+       "action-createaccount": "ꯃꯁꯤ ꯁꯤꯖꯤꯟꯅꯔꯤꯕ ꯑꯦꯀꯥꯎꯟ ꯁꯤ ꯁꯦꯝꯃꯨ",
+       "enhancedrc-history": "ꯄꯨꯋꯥꯔꯤ",
+       "recentchanges": "ꯍꯧꯖꯤꯛꯀꯤ ꯑꯣꯏꯕꯥ ꯑꯍꯣꯡꯕꯁꯤꯡ",
+       "recentchanges-legend": "ꯍꯧꯖꯤꯛꯀꯤ ꯑꯣꯏꯕꯥ ꯑꯍꯣꯡꯕꯥ ꯈꯟꯐꯝꯁꯤꯡ",
+       "recentchanges-summary": "ꯋꯤꯀꯤꯄꯦꯗꯤꯌꯥ ꯂꯃꯥꯏꯒꯤ ꯍꯧꯖꯤꯛꯀꯤ ꯑꯣꯏꯕꯥ ꯑꯍꯣꯡꯕꯒꯤ ꯃꯐꯝ ꯇꯥꯛꯄꯥ",
+       "recentchanges-noresult": "ꯑꯍꯣꯡꯕꯥ ꯂꯩꯍꯟꯒꯅꯨ ꯑꯩꯈꯣꯏꯅꯥ ꯄꯤꯔꯤꯕꯥ ꯃꯇꯝ ꯁꯤꯗꯥ ꯆꯥꯟꯅꯕꯥ ꯱ ꯌꯥꯎꯗꯔꯤꯐꯥꯎ",
+       "recentchanges-label-newpage": "ꯃꯁꯤꯒꯤ ꯁꯦꯝꯒꯠꯄꯁꯤꯅꯥ ꯑꯅꯧꯕꯥ ꯂꯥꯃꯥꯏ ꯱ ꯁꯥꯔꯦ",
+       "recentchanges-label-minor": "ꯃꯁꯤ ꯑꯄꯤꯛꯄꯥ ꯁꯦꯝꯒꯠꯄꯅꯤ",
+       "recentchanges-label-bot": "ꯃꯁꯤꯒꯤ ꯁꯦꯝꯒꯠꯄꯁꯤ ꯕ ꯅꯥ ꯄꯥꯡꯊꯣꯛꯄꯅꯤ",
+       "recentchanges-label-unpatrolled": "ꯃꯁꯤꯒꯤ ꯁꯦꯝꯒꯠꯄꯁꯤ ꯍꯧꯖꯤꯛꯐꯥꯎ ꯌꯦꯡꯁꯤꯟꯗ꯭ꯔꯤ",
+       "recentchanges-label-plusminus": "ꯕꯥꯏꯠꯀꯤ ꯑꯍꯣꯡꯕꯒꯤ ꯃꯇꯪ ꯏꯟꯅꯥ ꯂꯥꯃꯥꯏꯁꯤꯒꯤ ꯑꯆꯧꯕꯥ ꯂꯦꯞꯄꯤ",
+       "recentchanges-legend-heading": "<ꯑꯀꯟꯕꯥ>ꯊꯥꯏꯅꯗꯒꯤ</ꯑꯀꯟꯕꯥ>",
+       "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (also see [[Special:NewPages|list of new pages]])",
+       "rcnotefrom": "Below {{PLURAL:$5|is the change|are the changes}} since <strong>$3, $4</strong> (up to <strong>$1</strong> shown).",
+       "rclistfrom": "$2$3 ꯁꯤꯗꯒꯤ ꯍꯧꯔꯒꯥ ꯑꯅꯧꯕꯥ ꯑꯍꯣꯡꯕꯗꯨ ꯎꯨꯇꯂꯨ",
+       "rcshowhideminor": "$1 ꯄꯤꯛꯅꯥ ꯁꯦꯝꯒꯠꯄꯥ",
+       "rcshowhideminor-show": "ꯎꯨꯇꯄꯥ",
+       "rcshowhideminor-hide": "ꯂꯣꯇꯄꯥ",
+       "rcshowhidebots": "$1 bots",
+       "rcshowhidebots-show": "ꯎꯨꯇꯄꯥ",
+       "rcshowhidebots-hide": "ꯂꯣꯇꯄꯥ",
+       "rcshowhideliu": "ꯃꯃꯤꯡ ꯆꯟꯂꯕꯥ ꯄꯥꯏꯔꯤꯕꯥ $1",
+       "rcshowhideliu-show": "ꯎꯨꯇꯄꯥ",
+       "rcshowhideliu-hide": "ꯂꯣꯇꯄꯥ",
+       "rcshowhideanons": "$1 ꯃꯁꯛ ꯃꯥꯅꯥꯗꯕꯥ ꯄꯥꯏꯔꯤꯕꯥ ꯃꯤ",
+       "rcshowhideanons-show": "ꯎꯨꯇꯄꯥ",
+       "rcshowhideanons-hide": "ꯂꯣꯇꯄꯥ",
+       "rcshowhidepatr": "$1 ꯁꯦꯝꯒꯠꯄꯁꯤꯡ ꯆꯠꯂꯤꯕ",
+       "rcshowhidemine": "$1 ꯑꯩꯅꯥ ꯁꯦꯝꯒꯠꯄꯁꯤꯡ",
+       "rcshowhidemine-show": "ꯎꯨꯇꯄꯥ",
+       "rcshowhidemine-hide": "ꯂꯣꯇꯄꯥ",
+       "rclinks": "$1 ꯒꯤ ꯑꯔꯣꯏꯕꯥ ꯑꯍꯣꯡꯕꯥꯗꯎ ꯎꯨꯇꯂꯎ $2 ꯃꯅꯨꯡꯗꯥ",
+       "diff": "ꯈꯦꯠ",
+       "hist": "ꯄꯨꯋꯥ",
+       "hide": "ꯂꯣꯇꯄꯥ",
+       "show": "ꯎꯨꯇꯄꯥ",
+       "minoreditletter": "ꯃ",
+       "newpageletter": "ꯟ",
+       "boteditletter": "ꯕ",
+       "rc-change-size-new": "{{PLURAL:$1|$1}} ꯍꯣꯡꯗꯣꯛꯑꯕꯥ ꯃꯇꯨꯪꯗꯥ",
+       "rc-old-title": "$1 ꯑꯆꯨꯝꯕ ꯑꯣꯏꯅ ꯁꯥꯔꯛꯄ",
+       "recentchangeslinked": "ꯃꯔꯤꯂꯩꯅꯕꯥ ꯑꯍꯣꯡꯕꯁꯤꯡ",
+       "recentchangeslinked-feed": "ꯃꯔꯤꯂꯩꯅꯕꯥ ꯑꯍꯣꯡꯕꯁꯤꯡ",
+       "recentchangeslinked-toolbox": "ꯃꯔꯤꯂꯩꯅꯕꯥ ꯑꯍꯣꯡꯕꯁꯤꯡ",
+       "recentchangeslinked-title": "$1 ꯂꯩꯅꯕꯥ ꯑꯍꯣꯡꯕꯁꯤꯡ",
+       "recentchangeslinked-summary": "Enter a page name to see changes on pages linked to or from that page. (To see members of a category, enter {{ns:category}}:Name of category). Changes to pages on [[Special:Watchlist|your Watchlist]] are in <strong>bold</strong>.",
+       "recentchangeslinked-page": "ꯂꯥꯃꯥꯏ ꯃꯥꯃꯤꯡ",
+       "recentchangeslinked-to": "ꯂꯥꯃꯥꯏꯁꯤꯒꯥ ꯁꯝꯅꯐꯝꯒꯤ ꯑꯍꯣꯡꯕꯗꯨ ꯎꯠꯂꯨ ꯄꯤꯔꯝꯂꯤꯕꯥ ꯂꯥꯃꯥꯏꯗꯨ ꯃꯍꯨꯠꯇꯥ",
+       "upload": "ꯐꯥꯏꯜ ꯊꯥꯒꯠꯂꯨ",
+       "uploadlogpage": "ꯂꯣꯒ ꯊꯥꯒꯌꯄ",
+       "filedesc": "ꯑꯇꯦꯟꯕꯥ ꯁꯟꯗꯣꯛꯅꯥ ꯇꯥꯛꯄꯥ",
+       "license": "ꯑꯌꯥꯕ:",
+       "license-header": "ꯑꯌꯥꯕꯥ",
+       "imgfile": "ꯈꯣꯝꯖꯤꯟꯗꯨꯅꯥ ꯍꯥꯞꯐꯝ",
+       "listfiles": "ꯐꯥꯏꯜ ꯄꯥꯔꯦꯡ",
+       "file-anchor-link": "ꯈꯣꯝꯖꯤꯟꯗꯨꯅꯥ ꯍꯥꯞꯐꯝ",
+       "filehist": "ꯐꯥꯏꯜꯒꯤ ꯄꯨꯋꯥꯔꯤ",
+       "filehist-help": "ꯆꯩꯆꯠ/ꯃꯇꯝꯗ ꯅꯝꯃꯨ ꯃꯇꯝ ꯑꯗꯨꯗ ꯐꯥꯏꯜ ꯑꯗꯨ ꯎꯨꯅꯕ",
+       "filehist-revert": "ꯑꯃꯨꯛ ꯍꯟꯂꯟꯕꯥ",
+       "filehist-current": "ꯍꯧꯖꯤꯛꯀꯤ",
+       "filehist-datetime": "ꯆꯩꯆꯠ/ꯃꯇꯝ",
+       "filehist-thumb": "Khutpina namba",
+       "filehist-thumbtext": "Thumbnail for version as of $1",
+       "filehist-nothumb": "ꯊꯝꯅꯦꯜ ꯅꯠꯇꯦ",
+       "filehist-user": "ꯄꯥꯏꯔꯤꯕꯥ",
+       "filehist-dimensions": "ꯄꯥꯛ ꯆꯥꯎꯕꯥ",
+       "filehist-comment": "ꯑꯄꯥꯝꯕꯥ ꯐꯣꯡꯗꯣꯛ ꯎ",
+       "imagelinks": "ꯐꯥꯏꯜꯒꯤ ꯁꯤꯖꯤꯟꯅꯐꯝ",
+       "linkstoimage": "The following {{PLURAL:$1|page links|$1 pages link}} to this file:",
+       "nolinkstoimage": "ꯃꯁꯤꯒꯤ ꯂꯥꯃꯥꯏꯁꯤꯒꯥ ꯃꯔꯤ ꯂꯩꯅꯕꯥ ꯁꯝꯅꯐꯝ ꯐꯥꯏꯜ ꯂꯩꯇꯦ",
+       "sharedupload-desc-here": "This file is from $1 and may be used by other projects.\nThe description on its [$2 file description page] there is shown below.",
+       "filepage-nofile": "ꯃꯁꯤꯒꯤ ꯐꯥꯏꯜ ꯃꯃꯤꯡ ꯁꯤ ꯒꯥ ꯃꯥꯟꯅꯕ ꯂꯩꯇꯦ",
+       "upload-disallowed-here": "ꯃꯁꯤꯒꯤ ꯐꯥꯏꯜꯁꯤ ꯅꯪꯅꯥ ꯑꯃꯨꯛ ꯍꯟꯅꯥ ꯏꯕꯥ ꯌꯥꯔꯣꯏ",
+       "randompage": "ꯆꯥꯡ ꯅꯥꯏꯗꯕꯥ ꯂꯥꯃꯥꯏ",
+       "statistics": "ꯍꯦꯟꯒꯠꯂꯛꯄ ꯍꯥꯏꯊꯔꯧꯄ ꯌꯦꯡꯅꯕ",
+       "nbytes": "$1 {{PLURAL:$1|byte|bytes}}",
+       "nmembers": "$1 {{PLURAL:$1|member|members}}",
+       "prefixindex": "ꯋꯥꯇꯞ ꯀꯥ ꯂꯣꯏꯅꯕ ꯂꯥꯃꯥꯏꯁꯤꯡ ꯄꯨꯝꯅꯃꯛ",
+       "listusers": "ꯁꯤꯖꯤꯟꯅꯔꯤꯕ ꯁꯤꯡꯒꯤ ꯄꯥꯔꯦꯡ",
+       "newpages": "ꯑꯅꯧꯕꯥ ꯂꯥꯃꯥꯏꯁꯤꯡ",
+       "move": "ꯂꯦꯡꯍꯟꯕꯥ",
+       "pager-newer-n": "{{PLURAL:$1|newer 1|newer $1}}",
+       "pager-older-n": "{{PLURAL:$1|older 1|older $1}}",
+       "booksources": "ꯂꯥꯏꯔꯤꯛꯀꯤ ꯍꯧꯔꯛꯐꯝ",
+       "booksources-search-legend": "ꯂꯥꯏꯔꯤꯛꯀꯤ ꯍꯧꯔꯛꯐꯝ ꯊꯤꯕꯥ",
+       "booksources-search": "ꯊꯤꯕꯥ",
+       "specialloguserlabel": "ꯄꯥꯡꯊꯣꯛꯂꯤꯕ ꯃꯤ",
+       "log": "ꯆꯪꯕꯥ",
+       "allpages": "ꯂꯥꯃꯥꯏ ꯂꯣꯏꯅꯥ",
+       "allarticles": "ꯂꯥꯃꯥꯏ ꯂꯣꯏꯅꯥ",
+       "allpagessubmit": "ꯆꯠꯂꯨ",
+       "allpages-hide-redirects": "ꯃꯥꯏꯀꯩ ꯄꯤꯔꯧꯄꯗꯨ ꯂꯣꯌꯂꯨ",
+       "categories": "ꯃꯊꯪ ꯃꯅꯥꯎ ꯈꯥꯏꯗꯣꯛꯄꯥ",
+       "emailuser": "ꯃꯁꯤ ꯁꯤꯖꯤꯟꯅꯔꯤꯕꯁꯤ ꯏ-ꯃꯦꯜ ꯊꯥꯖꯤꯟꯂꯨ",
+       "watchlist": "ꯌꯦꯡꯂꯤꯕ ꯄꯥꯥꯔꯦꯡ",
+       "mywatchlist": "Watchlist",
+       "watchlistfor2": "$1$2 ꯒꯤ",
+       "watch": "ꯌꯦꯡꯕꯥ",
+       "unwatch": "ꯌꯦꯡꯗꯕ",
+       "watchlist-details": "{{PLURAL:$1|$1 page is|$1 pages are}} ꯗ ꯅꯪꯅ ꯌꯦꯡꯂꯤꯕ ꯄꯥꯔꯦꯡꯁꯤꯡ(plus talk pages).",
+       "wlshowlast": "$1 ꯄꯨꯪ ꯱ $2 ꯅꯨꯃꯤꯠꯁꯤꯡ ꯑꯔꯣꯏꯕꯗꯨ ꯎꯨꯠꯂꯨ",
+       "watchlist-options": "ꯌꯦꯡꯂꯤꯕ ꯄꯔꯦꯡ ꯑꯄꯥꯝꯕ ꯈꯟꯅꯕ",
+       "enotif_reset": "ꯂꯥꯃꯥꯏꯁꯤꯡ ꯁꯤ ꯂꯣꯏꯅ ꯊꯨꯪꯈꯔꯦ ꯍꯥꯏꯅ ꯍꯧ ꯎ",
+       "dellogpage": "ꯀꯛꯊꯠꯄꯥꯒꯤ ꯂꯣꯒ",
+       "rollbacklink": "ꯑꯃꯨꯛ ꯍꯟꯍꯟꯕꯥ",
+       "rollbacklinkcount": "rollback $1 {{PLURAL:$1|edit|edits}}",
+       "protectlogpage": "ꯂꯣꯒ ꯉꯥꯛꯊꯣꯛꯄꯥ",
+       "protectedarticle": "\"[[$1]]\" ꯉꯥꯛꯊꯣꯛꯂꯦ",
+       "protect-default": "ꯁꯤꯖꯤꯟꯅꯔꯤꯕꯁꯤꯡ ꯄꯨꯂꯞ ꯌꯥꯍꯟꯕ",
+       "restriction-edit": "ꯁꯦꯝꯒꯠꯄꯥ",
+       "restriction-move": "ꯂꯦꯡꯍꯟꯕꯥ",
+       "namespace": "ꯃꯥꯃꯤꯡꯒꯤ ꯃꯐꯝ",
+       "invert": "ꯈꯟꯂꯤꯕꯗꯨ ꯃꯀꯣꯛꯇꯒꯤ ꯂꯥꯛꯍꯟꯕ",
+       "tooltip-invert": "Akhannaba maming gi manungda page tungi ahongba lotnaba oopu du yeng ngoo",
+       "namespace_association": "Maming eefam ga marileinaba",
+       "tooltip-namespace_association": "Oopu du yengoo maming eefam gi hiramga mari leinaba khangatlaba maming eefam amadi wa ngangfam manung channaba",
+       "blanknamespace": "ꯃꯔꯨꯑꯣꯏꯕꯥ",
+       "contributions": "{{GENDER:$1|User}} ꯈꯣꯝꯒꯠꯂꯛꯄꯁꯤꯡ",
+       "contributions-title": "$1 ꯁꯤꯖꯤꯟꯅꯔꯤꯕꯁꯤꯅ ꯈꯣꯝꯖꯤꯜꯂꯛꯄꯁꯤꯡ",
+       "mycontris": "ꯈꯣꯝꯒꯠꯂꯛꯂꯤꯕꯁꯤꯡ",
+       "anoncontribs": "ꯈꯣꯝꯒꯠꯂꯛꯂꯤꯕꯁꯤꯡ",
+       "contribsub2": "{{GENDER:$3|$1}}$2 ꯒꯤ",
+       "uctop": "ꯍꯧꯖꯤꯛ",
+       "month": "ꯃꯗꯨꯒꯤ ꯊꯥꯗꯒꯤ (ꯑꯃꯗꯤ ꯅꯧꯔꯤꯕꯥ)",
+       "year": "ꯃꯗꯨꯒꯤ ꯆꯥꯍꯤꯗꯒꯤ (ꯑꯃꯗꯤ ꯅꯧꯔꯤꯕꯥ)",
+       "sp-contributions-blocklog": "ꯆꯪꯁꯤꯟꯕꯥ ꯊꯤꯡꯕꯥ",
+       "sp-contributions-uploads": "ꯊꯥꯒꯠꯄ",
+       "sp-contributions-logs": "ꯆꯪꯕꯁꯤꯟꯕ ꯃꯌꯥꯝ",
+       "sp-contributions-talk": "ꯉꯥꯡꯐꯝ",
+       "sp-contributions-search": "ꯈꯣꯝꯖꯤꯟꯂꯛꯂꯤꯕꯁꯤꯡꯗꯨ ꯊꯤꯌꯨ",
+       "sp-contributions-username": "ꯑꯥꯏ ꯄꯤ ꯂꯩꯐꯝ / ꯁꯤꯖꯤꯟꯅꯔꯤꯕ ꯃꯃꯤꯡ",
+       "sp-contributions-toponly": "ꯑꯅꯧꯕ ꯑꯃꯨꯛꯍꯟꯅ ꯌꯦꯡꯗꯨꯅ ꯁꯦꯝꯒꯠꯂꯛꯄꯁꯤꯡꯗꯨ ꯎꯨꯠꯂꯨ",
+       "sp-contributions-submit": "ꯊꯤꯕꯥ",
+       "whatlinkshere": "ꯃꯁꯤꯗꯥ ꯀꯔꯤ ꯁꯝꯃꯤ",
+       "whatlinkshere-title": "$1 ꯒꯥ ꯃꯔꯤ ꯂꯩꯅꯕꯥ ꯁꯝꯅꯐꯝ",
+       "whatlinkshere-page": "ꯂꯥꯃꯥꯏ",
+       "linkshere": "$2<strong> ꯒꯥ ꯁꯝꯅꯐꯝ ꯑꯣꯏꯕꯥ ꯂꯥꯃꯥꯏꯁꯤꯡ",
+       "nolinkshere": " <strong>$2</strong> ꯃꯁꯤꯒ ꯁꯝꯅꯕ ꯂꯥꯃꯥꯏꯁꯤꯡ ꯂꯩꯇꯦ",
+       "isredirect": "ꯑꯃꯨꯛ ꯍꯟꯂꯛꯄꯥ ꯂꯥꯃꯥꯏ",
+       "istemplate": " transclusions",
+       "isimage": "ꯐꯥꯏꯜꯒꯤ ꯁꯝꯅꯐꯝ",
+       "whatlinkshere-prev": "{{PLURAL:$1|previous|previous $1}}",
+       "whatlinkshere-next": "{{PLURAL:$1|next|next $1}}",
+       "whatlinkshere-links": " ꯁꯝꯅꯐꯝ",
+       "whatlinkshere-hideredirs": "$1 redirects",
+       "whatlinkshere-hidetrans": "$1 transclusions",
+       "whatlinkshere-hidelinks": "$1 ꯁꯝꯅꯐꯝ",
+       "whatlinkshere-hideimages": "$1 ꯒꯤ ꯐꯥꯏꯜ ꯁꯝꯅꯐꯝ",
+       "whatlinkshere-filters": "ꯁꯦꯡꯇꯣꯛꯐꯝ",
+       "ipboptions": "ꯄꯨꯪ ꯲:2 hours,  ꯅꯣꯡꯃ:1 day, ꯅꯨꯃꯤꯠ ꯳ꯅꯤ:3 days, ꯆꯥꯌꯣꯜ ꯱: 1 week, ꯆꯥꯌꯣꯜ ꯲: 2weeks, ꯊꯥ ꯱: 1 month, ꯊꯥ ꯳: 3 months, ꯊꯥ ꯶: 6 months, ꯆꯥꯍꯤ ꯱: 1 year, ꯃꯁꯤꯡꯊꯤꯉꯝꯗꯅ:infinite ‌.",
+       "infiniteblock": "ꯃꯁꯤꯡ ꯊꯤꯉꯝꯗꯅ",
+       "blocklink": "ꯊꯤꯡꯕ",
+       "contribslink": "ꯈꯣꯝ",
+       "blocklogpage": "ꯆꯪꯁꯤꯟꯕꯥ ꯊꯤꯡꯕꯥ",
+       "reblock-logentry": "[[$1]] ꯒꯤ ꯁꯦꯝꯐꯝꯒꯤ ꯑꯍꯣꯡꯕꯗꯨ ꯊꯤꯡꯉꯨ  $2 $3 ꯒꯤ ꯑꯍꯦꯟꯕ ꯃꯇꯝꯒ ꯂꯣꯏꯅꯅ",
+       "movelogpage": "ꯂꯣꯒ ꯁꯤ ꯂꯦꯡꯍꯟꯂꯨ",
+       "export": "ꯂꯥꯃꯥꯏꯁꯤꯡ ꯄꯨꯊꯣꯛꯈꯣ",
+       "thumbnail-more": "ꯆꯥꯑꯣꯍꯟꯕꯥ",
+       "importlogpage": "ꯂꯣꯒ ꯄꯨꯁꯤꯟꯂꯛꯄ",
+       "tooltip-pt-userpage": "{{GENDER:|Your user}} ꯂꯥꯃꯥꯏ",
+       "tooltip-pt-mytalk": "{{GENDER:|Your}} ꯉꯥꯡꯐꯝ ꯂꯥꯃꯥꯏ",
+       "tooltip-pt-preferences": "{{GENDER:|Your}} preferences",
+       "tooltip-pt-watchlist": "ꯑꯍꯣꯡꯕꯗꯥ ꯌꯦꯡꯁꯤꯟꯅꯕꯥ ꯅꯪꯒꯤ ꯂꯥꯃꯥꯏ ꯄꯔꯦꯡ ꯱",
+       "tooltip-pt-mycontris": "A list of {{GENDER:|your}} ꯈꯣꯝꯒꯠꯂꯛꯂꯤꯕꯥ ꯁꯤꯡ",
+       "tooltip-pt-login": "ꯅꯪꯅꯥ ꯃꯅꯨꯡ ꯆꯪꯉꯛꯄꯁꯤ ꯄꯨꯛꯅꯤꯡ ꯊꯧꯒꯠꯂꯤ, ꯇꯧꯕꯇꯕꯨ ꯃꯁꯤ ꯁꯪꯁꯣꯏ ꯁꯣꯏꯗꯅꯥ ꯆꯡꯕꯗꯤ ꯅꯠꯇꯦ",
+       "tooltip-pt-logout": "Log out",
+       "tooltip-pt-createaccount": "ꯅꯪꯒꯤ ꯑꯣꯏꯕꯥ ꯱ ꯁꯦꯝꯕꯥ ꯑꯃꯥꯁꯨꯪ ꯃꯅꯨꯡ ꯆꯪꯁꯤꯟꯕꯥꯁꯤ ꯄꯨꯛꯅꯤꯡ ꯊꯧꯒꯠꯂꯤ, ꯇꯧꯕꯇꯕꯨ ꯃꯁꯤ ꯁꯪꯁꯣꯏ ꯁꯣꯏꯗꯅꯥ ꯆꯡꯕꯗꯤ ꯅꯠꯇꯦ",
+       "tooltip-ca-talk": "ꯃꯅꯨꯡꯆꯟꯂꯤꯕꯥ ꯂꯥꯃꯥꯏꯁꯤꯒꯤ ꯃꯇꯥꯁꯗꯥ ꯈꯟꯅꯥ ꯅꯩꯅꯕꯥ",
+       "tooltip-ca-edit": "ꯃꯁꯤꯒꯤ ꯂꯥꯃꯥꯏꯁꯤ ꯁꯦꯝꯒꯠꯂꯨ",
+       "tooltip-ca-addsection": "Anouba khaidokpadu houro",
+       "tooltip-ca-viewsource": "ꯃꯁꯤꯒꯤ ꯂꯥꯃꯥꯏꯁꯤ ꯉꯥꯛꯊꯣꯛꯂꯦ \nꯅꯪꯅꯥ ꯂꯥꯃꯥꯏꯁꯤꯒꯤ ꯍꯧꯔꯛꯐꯝ ꯎꯒꯅꯤ",
+       "tooltip-ca-history": "ꯍꯧꯈꯔꯕꯥ ꯂꯥꯃꯥꯏ ꯑꯃꯨꯛ ꯍꯟꯅꯥ ꯌꯦꯡꯕꯥ",
+       "tooltip-ca-protect": "ꯃꯁꯤꯒꯤ ꯂꯥꯃꯥꯏꯁꯤ ꯉꯥꯛ ꯎ",
+       "tooltip-ca-delete": "ꯃꯁꯤꯒꯤ ꯂꯥꯃꯥꯏꯁꯤ ꯀꯛꯊꯠꯂꯨ",
+       "tooltip-ca-move": "ꯃꯁꯤꯒꯤ ꯂꯥꯃꯥꯏꯁꯤ ꯂꯦꯡꯍꯟꯂꯨ",
+       "tooltip-ca-watch": "ꯅꯪꯒꯤ ꯌꯦꯡꯅꯕꯥ ꯄꯥꯔꯦꯡꯗꯨꯗꯥ ꯍꯥꯞꯆꯏꯟꯂꯨ ꯃꯁꯤꯒꯤ ꯂꯥꯃꯥꯏꯁꯤ",
+       "tooltip-ca-unwatch": "ꯅꯪꯒꯤ ꯌꯦꯡꯅꯕ ꯄꯥꯔꯦꯡ ꯗꯒꯤ ꯃꯁꯤꯒꯤ ꯂꯥꯃꯥꯏꯁꯤ ꯂꯧꯊꯣꯛ ꯎ",
+       "tooltip-search": "ꯊꯤꯔꯣ",
+       "tooltip-search-go": "ꯂꯩꯔꯒꯥ ꯆꯠꯂꯨ ꯃꯗꯨꯒꯤ ꯆꯞꯆꯕ ꯂꯥꯃꯥꯏ ꯗꯨꯗ",
+       "tooltip-search-fulltext": "ꯏꯔꯤꯕꯥ ꯃꯇꯦꯛꯁꯤꯒꯤ ꯂꯃꯥꯏ ꯁꯤ ꯊꯤꯔꯣ",
+       "tooltip-p-logo": "ꯃꯔꯨ ꯑꯣꯏꯕꯥ ꯂꯥꯃꯥꯏꯗꯨꯗꯥ ꯌꯧꯁꯤꯟꯂꯨ",
+       "tooltip-n-mainpage": "ꯃꯔꯨ ꯑꯣꯏꯕꯥ ꯂꯥꯃꯥꯏꯗꯨꯗꯥ ꯌꯧꯁꯤꯟꯂꯨ",
+       "tooltip-n-mainpage-description": "ꯃꯔꯨ ꯑꯣꯏꯕꯥ ꯂꯥꯃꯥꯏꯗꯨꯗꯥ ꯌꯧꯁꯤꯟꯂꯨ",
+       "tooltip-n-portal": "ꯊꯧꯑꯣꯡ ꯂꯥꯛꯄꯗꯨꯒꯤ ꯃꯔꯝꯗ꯬",
+       "tooltip-n-currentevents": "ꯆꯠꯊꯔꯤꯕꯥ ꯊꯧꯔꯝꯁꯤꯒꯤ ꯃꯅꯨꯒꯤ ꯑꯣꯏꯕꯥ ꯋꯥꯔꯣꯟꯗꯨ ꯄꯨꯊꯣꯛ ꯎ",
+       "tooltip-n-recentchanges": "ꯍꯧꯖꯤꯛꯀꯤ ꯑꯣꯏꯅꯥ ꯋꯤꯀꯤꯄꯦꯗꯤꯌꯥꯗꯥ ꯑꯍꯣꯡꯕꯥꯁꯤꯡꯒꯤ ꯄꯥꯔꯦꯡ",
+       "tooltip-n-randompage": "ꯆꯥꯡ ꯅꯥꯏꯗꯕꯥ ꯂꯃꯥꯏ ꯍꯥꯞꯆꯤꯟꯕꯥ",
+       "tooltip-n-help": "ꯄꯨꯊꯣꯔꯛꯅꯕꯥ ꯃꯐꯝꯅꯤ",
+       "tooltip-t-whatlinkshere": "ꯃꯁꯤꯗ ꯁꯝꯂꯤꯕ ꯑꯄꯨꯟꯕ ꯋꯤꯀꯤ ꯂꯥꯃꯥꯏꯁꯤꯡꯒꯤ ꯄꯥꯔꯦꯡ ꯱",
+       "tooltip-t-recentchangeslinked": "ꯃꯁꯤꯒꯤ ꯂꯃꯥꯏꯁꯤꯒꯥ ꯃꯔꯤ ꯂꯩꯅꯕꯥ ꯍꯧꯖꯤꯛꯀꯤ ꯑꯍꯣꯡꯕꯥ ꯂꯥꯃꯥꯏꯁꯤꯡ",
+       "tooltip-feed-atom": "ꯂꯥꯃꯥꯏꯁꯤꯒꯤ ꯃꯁꯥ ꯃꯇꯣꯝꯇꯥ ꯌꯣꯛꯈꯠꯂꯛꯄꯥ",
+       "tooltip-t-contributions": " {{GENDER:$1|this user}} ꯅꯥ ꯈꯣꯝꯖꯤꯟꯂꯛꯂꯤꯕꯥ ꯄꯥꯔꯦꯡ ꯱",
+       "tooltip-t-upload": "ꯐꯥꯏꯜꯁꯤꯡ ꯊꯥꯒꯠꯂꯨ",
+       "tooltip-t-specialpages": "ꯑꯈꯟꯅꯕ ꯂꯥꯃꯥꯏꯁꯤꯡꯒꯤ ꯄꯥꯔꯦꯡ ꯱",
+       "tooltip-t-print": "Namba Yaba ma ong  gi Lamai",
+       "tooltip-t-permalink": "Amuk han na yengba lamaisigi Lengdaba Samnafam",
+       "tooltip-ca-nstab-main": "ꯂꯃꯥꯏꯁꯤꯒꯤ ꯑꯌꯥꯎꯕꯁꯤꯡꯗꯨ ꯎꯨꯇꯂꯨ",
+       "tooltip-ca-nstab-user": "ꯁꯤꯖꯤꯟꯅꯔꯤꯕꯥ ꯂꯥꯃꯥꯏꯁꯤ ꯌꯦꯡꯕꯥ",
+       "tooltip-ca-nstab-special": "ꯃꯁꯤ ꯑꯈꯟꯅꯕꯥ ꯂꯥꯃꯥꯏꯅꯤ, ꯁꯦꯝꯒꯠꯄꯥ ꯌꯥꯔꯣꯏ",
+       "tooltip-ca-nstab-project": "ꯂꯃꯥꯏꯁꯤꯒꯤ ꯇꯧꯒꯗꯥ ꯊꯧꯔꯥꯡꯗꯨ ꯎꯨꯇꯂꯨ",
+       "tooltip-ca-nstab-image": "ꯐꯥꯏꯜ ꯂꯥꯃꯥꯏꯗꯨꯨꯨꯨꯨ ꯎꯨꯠꯂꯨ",
+       "tooltip-ca-nstab-mediawiki": "ꯊꯧꯁꯤꯜꯒꯤ ꯑꯣꯏꯕ ꯄꯥꯎꯖꯦꯜꯗꯨ ꯎꯨꯠꯂꯨ",
+       "tooltip-ca-nstab-template": "ꯇꯦꯝꯄꯂꯦꯠ ꯇꯨ ꯎꯨꯠꯂꯨ",
+       "tooltip-ca-nstab-category": "Macahkhaiba lamai sure oootlooo",
+       "tooltip-save": "ꯅꯪꯒꯤ ꯑꯍꯣꯡꯕꯗꯨ ꯇꯨꯡꯁꯤꯟꯂꯨ",
+       "tooltip-preview": "ꯅꯪꯒꯤ ꯑꯍꯣꯡꯕꯗꯨ ꯑꯃꯨꯛ ꯍꯟꯅꯥ ꯎꯠꯂꯨ. ꯆꯥꯟꯕꯤꯗꯨꯅꯥ ꯃꯁꯤ ꯍꯥꯟꯅꯥ ꯁꯤꯖꯤꯅꯧ ꯇꯪꯁꯤꯟꯗ꯭ꯔꯤꯉꯧꯗꯥ",
+       "tooltip-diff": "ꯅꯪꯅꯥ ꯏꯔꯤꯕꯥ ꯄꯥꯔꯦꯡꯗꯨꯗꯥ ꯑꯍꯣꯡꯕꯥ ꯎꯠꯂꯨ",
+       "tooltip-compareselectedversions": "See the differences between the two selected revisions of this page",
+       "tooltip-watch": "ꯍꯥꯞꯆꯤꯟꯂꯨ ꯃꯁꯤꯒꯤ ꯂꯥꯃꯥꯏꯁꯤ ꯅꯪꯅ ꯌꯦꯡꯂꯤꯕ ꯄꯔꯦꯡ ꯗ",
+       "tooltip-rollback": "ꯑꯔꯣꯏꯕꯥ ꯈꯣꯝꯒꯠꯛꯂꯤꯕꯥꯁꯤꯡꯒꯤ ꯁꯦꯝꯒꯠꯄꯁꯤꯡ ꯗꯨꯒꯤ ꯂꯥꯃꯥꯏ ꯑꯃꯨꯛ ꯅꯝꯕꯗꯥ ꯂꯥꯛꯍꯟꯂꯨ ꯍꯥꯟꯅꯒꯤ ꯃꯐꯝꯗꯨꯗꯥ",
+       "tooltip-undo": "\"Undo\" reverts this edit and opens the edit form in preview mode. It allows adding a reason in the summary.",
+       "tooltip-summary": "ꯑꯇꯦꯟꯕꯥ ꯀꯨꯞꯅꯥ ꯁꯟꯗꯣꯛꯅꯩ ꯇꯥꯛꯄꯥ ꯏꯌꯨ",
+       "simpleantispam-label": "Anti-spam check.\nDo <strong>not</strong> fill this in!",
+       "pageinfo-title": "$1 ꯒꯤ ꯑꯀꯨꯞꯄ ꯋꯥꯔꯣꯜ",
+       "pageinfo-header-basic": "ꯆꯪꯗꯌꯥꯗ꯭ꯔꯕ ꯑꯀꯨꯞꯄ ꯋꯥꯔꯣꯜ",
+       "pageinfo-header-edits": "ꯄꯨꯋꯥꯔꯤ ꯁꯦꯝꯒꯠꯄ",
+       "pageinfo-header-restrictions": "ꯉꯥꯛꯊꯣꯛꯂꯕꯥ ꯂꯥꯃꯥꯏ",
+       "pageinfo-header-properties": "ꯂꯥꯃꯥꯏꯁꯤ ꯒꯤ ꯑꯣꯏꯒꯗꯕꯁꯤꯡ",
+       "pageinfo-display-title": "ꯂꯥꯃꯥꯤꯒꯤ ꯃꯃꯤꯡ ꯌꯦꯡꯍꯟꯕ",
+       "pageinfo-default-sort": "ꯑꯇꯦꯟꯕ-꯱ꯍꯦꯛ-ꯇ ꯌꯥꯕ ‌‌‌‌‌",
+       "pageinfo-length": "ꯂꯥꯃꯥꯏꯒꯤ ꯑꯁꯥꯡꯕ(ꯕꯥꯏꯇ ꯇ)",
+       "pageinfo-article-id": "ꯂꯥꯃꯥꯏꯒꯤ ꯁꯛꯇꯥꯛ",
+       "pageinfo-language": "ꯂꯥꯃꯥꯏꯁꯤꯗ ꯏꯔꯤꯕ ꯂꯣꯟ",
+       "pageinfo-content-model": "ꯂꯥꯃꯥꯏꯁꯤꯗ ꯌꯥꯎꯔꯤꯕ ꯃꯑꯣꯡ ꯃꯇꯧ",
+       "pageinfo-robot-index": "ꯌꯥꯍꯟꯕ",
+       "pageinfo-robot-noindex": "ꯌꯥꯍꯟꯗꯕꯥ",
+       "pageinfo-watchers": "ꯂꯥꯃꯥꯏꯁꯤꯕꯎ ꯌꯦꯡꯂꯤꯕ ꯃꯤꯑꯣꯤꯁꯤꯡꯒꯤ ꯃꯁꯤꯡ",
+       "pageinfo-few-watchers": " $1 ꯁꯤꯗꯒꯤ ꯋꯥꯠꯅ {{PLURAL:$1|ꯌꯦꯡꯂꯤꯕ|ꯌꯦꯡꯂꯤꯕꯁꯤꯡ}}",
+       "pageinfo-redirects-name": "ꯃꯁꯤꯒꯤ ꯂꯥꯃꯥꯏꯁꯤꯗ ꯃꯥꯏꯀꯩ ꯇꯥꯛꯂꯛꯄ ꯃꯁꯤꯡ",
+       "pageinfo-subpages-name": "ꯂꯥꯃꯥꯏꯁꯤ ꯒꯤ ꯃꯅꯨꯡ ꯆꯟꯕꯥ ꯀꯨꯞꯊꯕꯥ ꯂꯥꯃꯥꯏꯁꯤꯡ",
+       "pageinfo-subpages-value": "$1 ($2 {{PLURAL:$2|redirect|redirects}}; $3 {{PLURAL:$3|non-redirect|non-redirects}})",
+       "pageinfo-firstuser": "ꯂꯥꯃꯥꯏ ꯁꯥꯔꯤꯕ ꯃꯤꯑꯣꯏꯁꯤꯡ",
+       "pageinfo-firsttime": "ꯂꯥꯃꯥꯏ ꯁꯥꯈꯤꯕꯒꯤ ꯆꯩꯆꯠ",
+       "pageinfo-lastuser": "ꯈꯋꯥꯏꯗꯒꯤ ꯅꯧꯕ ꯁꯦꯝꯒꯠꯂꯛꯂꯤꯕꯁꯤꯡ",
+       "pageinfo-lasttime": "ꯅꯧꯔꯤꯕ ꯁꯦꯝꯒꯠꯄꯒꯤ ꯆꯩꯆꯠ",
+       "pageinfo-edits": "ꯑꯄꯨꯟꯕ ꯁꯦꯝꯒꯠꯄꯒꯤ ꯃꯁꯤꯡ",
+       "pageinfo-authors": "ꯑꯄꯨꯟꯕ ꯑꯈꯟꯅꯕ ꯑꯌꯤꯕꯁꯤꯡꯒꯤ ꯃꯁꯤꯡ",
+       "pageinfo-magic-words": "Magic {{PLURAL:$1|word|words}} ($1)",
+       "pageinfo-hidden-categories": "ꯂꯣꯠꯍꯟꯕ {{PLURAL:$1|category|ꯃꯆꯥꯛꯈꯥꯏꯕ}} ($1)",
+       "pageinfo-toolboxlink": "ꯂꯥꯃꯥꯏꯒꯤ ꯃꯇꯥꯡꯗꯥ",
+       "pageinfo-contentpage": "ꯂꯥꯃꯥꯏꯁꯤꯒꯤ ꯃꯅꯨꯪꯗ ꯌꯥꯎꯕ ꯑꯣꯏꯅꯥ ꯃꯁꯤꯡ ꯊꯤꯔꯦ",
+       "pageinfo-contentpage-yes": "ꯍꯣꯏ",
+       "previousdiff": "ꯑꯔꯤꯕꯥ ꯁꯦꯝꯒꯠꯂꯛꯐꯝ",
+       "nextdiff": "ꯑꯅꯧꯕꯥ ꯁꯦꯝꯗꯠꯄ",
+       "widthheightpage": "$1 × $2, $3 {{PLURAL:$3|ꯂꯥꯃꯥꯏ|ꯂꯥꯃꯥꯏꯁꯤꯡ}}",
+       "file-info-size": "$1 × $2 pixels, file size: $3, MIME type: $4",
+       "file-info-size-pages": "$1 × $2 pixels, ꯐꯥꯏꯜ ꯆꯥꯎꯕꯒꯤ ꯆꯥꯡ: $3, MIME type: $4, $5 {{PLURAL:$5|ꯂꯥꯃꯥꯏ|ꯂꯥꯃꯥꯏꯁꯤꯡ}}",
+       "file-nohires": "ꯃꯁꯤꯗꯒꯤ ꯍꯦꯟꯅꯥ ꯁꯦꯡꯕꯥ ꯂꯩꯇꯔꯦ",
+       "svg-long-desc": "SVG file, nominally $1 × $2 pixels, file size: $3",
+       "show-big-image": "File Asengba",
+       "show-big-image-preview": "Size of this preview: $1.",
+       "show-big-image-other": "Other {{PLURAL:$2|resolution|resolutions}}: $1.",
+       "show-big-image-size": "$1 × $2 pixels",
+       "metadata": "ꯃꯦꯇꯥꯗꯥꯇꯥ",
+       "metadata-help": "This file contains additional information, probably added from the digital camera or scanner used to create or digitize it.\nIf the file has been modified from its original state, some details may not fully reflect the modified file.",
+       "metadata-fields": "ꯃꯥꯇꯥꯗꯥꯇꯥꯒꯤ ꯃꯥꯃꯤꯒꯤ ꯄꯥꯔꯦꯡ ꯑꯗꯨ ꯃꯥꯃꯤꯒꯤ ꯂꯥꯃꯥꯏꯗꯨꯒꯤ ꯄꯥꯎꯖꯦꯜꯗꯥ ꯎꯨꯇꯂꯦ ꯃꯦꯇꯥꯗꯥꯇꯥ ꯒꯤ\nꯎꯨꯇꯊꯣꯛꯐꯝꯗꯨ ꯀꯥꯏꯔꯥꯀꯥꯟꯗꯥ \nꯑꯇꯩꯗꯤ ꯂꯣꯠꯂꯅꯤ ꯎꯨꯇꯄꯥ ꯉꯝꯗꯕꯒꯤ\n* make\n* model\n* datetimeoriginal\n* exposuretime\n* fnumber\n* isospeedratings\n* focallength\n* artist\n* copyright\n* imagedescription\n* gpslatitude\n* gpslongitude\n* gpsaltitude",
+       "exif-orientation": "ꯃꯐꯝ ꯆꯥꯟꯅꯍꯟꯕꯥ",
+       "exif-xresolution": " resolution ꯐꯩꯅꯥ",
+       "exif-yresolution": " resolution ꯌꯨꯡꯅꯥ",
+       "exif-datetime": "ꯐꯥꯏꯜ ꯍꯣꯡꯕꯒꯤ ꯆꯩꯆꯠ ꯑꯃꯗꯤ ꯃꯇꯝ",
+       "exif-make": "Camera ꯁꯥꯔꯤꯕꯁꯤꯡ",
+       "exif-model": "Camera model",
+       "exif-software": "Software ꯁꯤꯖꯤꯟꯅꯔꯤꯕꯥ",
+       "exif-exifversion": "Exif version",
+       "exif-colorspace": "ꯉꯛꯁꯝꯒꯤ ꯑꯍꯥꯡꯕꯥ",
+       "exif-datetimeoriginal": "data generationꯒꯤ ꯃꯇꯝ ꯑꯝꯗꯤ ꯆꯩꯆꯠ",
+       "exif-datetimedigitized": "ꯃꯥꯃꯤ ꯇꯥꯏꯕꯪꯗꯥ ꯍꯥꯞꯆꯤꯟꯕꯒꯤ ꯃꯇꯝ ꯑꯃꯥꯗꯤ ꯆꯩꯆꯠ",
+       "exif-orientation-1": "ꯆꯥꯡ ꯅꯥꯏꯅꯥ",
+       "namespacesall": "ꯄꯨꯂꯞ",
+       "monthsall": "ꯄꯨꯂꯞ",
+       "imgmultipagenext": "ꯃꯊꯪ ꯂꯥꯃꯥꯏ",
+       "imgmultigo": "ꯆꯠꯂꯨ",
+       "imgmultigoto": "$1 ꯂꯥꯃꯥꯏ ꯗ ꯆꯠꯂꯨ",
+       "watchlisttools-clear": "ꯌꯦꯡꯂꯤꯕ ꯄꯥꯔꯦꯡꯗꯨ ꯁꯦꯡꯗꯣꯛ ꯨꯎ",
+       "watchlisttools-view": "ꯃꯁꯤꯒ ꯆꯥꯟꯅꯕ ꯑꯍꯣꯡꯕꯗꯨ ꯎꯨꯠꯂꯨ",
+       "watchlisttools-edit": "ꯌꯦꯡꯂꯤꯕ ꯄꯥꯔꯦꯡꯗꯨ ꯁꯦꯝꯒꯌꯂꯨ ꯱ꯁꯨꯡ ꯎꯨꯠꯂꯨ",
+       "watchlisttools-raw": "ꯑꯍꯤꯡꯕ ꯌꯦꯡꯂꯤꯕ ꯄꯥꯔꯦꯡꯗꯨ ꯁꯦꯝꯒꯠꯂꯨ",
+       "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|talk]])",
+       "redirect-submit": "ꯆꯠꯂꯨ",
+       "redirect-lookup": "ꯌꯦꯡꯈꯠꯂꯨ",
+       "redirect-value": "ꯃꯔꯨꯑꯣꯏꯕꯥ",
+       "redirect-user": "ꯁꯤꯖꯤꯟꯅꯔꯤꯕ ꯁꯛꯇꯥꯛ",
+       "redirect-page": "ꯂꯥꯃꯥꯏꯒꯤ ꯁꯛꯇꯛ",
+       "redirect-revision": "ꯂꯥꯃꯥꯏ ꯑꯃꯨꯧꯍꯟꯅ ꯌꯦꯡꯕ",
+       "redirect-file": "ꯐꯥꯏꯜ ꯃꯃꯤꯡ",
+       "specialpages": "ꯑꯈꯟꯅꯕ ꯂꯥꯃꯥꯏꯁꯤꯡ",
+       "tag-filter": "[[Special:Tags|Tag]] filter:",
+       "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|Tag|Tags}}]]: $2)",
+       "tags-active-yes": "ꯍꯣꯏ",
+       "tags-active-no": "ꯅꯠꯇꯦ",
+       "logentry-delete-delete": "$1 {{GENDER:$2|deleted}} page $3",
+       "logentry-delete-restore": "$1 {{GENDER:$2|restored}} ꯂꯥꯃꯥꯏ $3 ($4)",
+       "revdelete-content-hid": "ꯑꯌꯥꯎꯕꯗꯎ ꯂꯣꯌꯂꯒ ꯊꯝꯕ",
+       "logentry-move-move": "$1 {{GENDER:$2|moved}} page $3 to $4",
+       "logentry-newusers-create": "User account $1 was {{GENDER:$2|created}}",
+       "logentry-upload-upload": "$1 {{GENDER:$2|uploaded}} $3",
+       "searchsuggest-search": "ꯊꯤꯔꯣ",
+       "duration-days": "$1 {{PLURAL:$1|ꯅꯨꯃꯤꯌ|ꯅꯨꯃꯤꯠꯁꯤꯡ}}",
+       "randomrootpage": "ꯆꯥꯡ ꯅꯥꯏꯗꯕ ꯂꯥꯃꯥꯏꯒꯤ ꯃꯔꯥ"
+}
index e860acb..57e3609 100644 (file)
        "prefs-dateformat": "दिनांक प्रारुपण",
        "prefs-timeoffset": "वेळ बरोबरी",
        "prefs-advancedediting": "सर्वसामान्य पर्याय",
+       "prefs-developertools": "विकसक उपकरण",
        "prefs-editor": "संपादक",
        "prefs-preview": "झलक",
        "prefs-advancedrc": "प्रगत पर्याय",
        "whatlinkshere": "येथे काय जोडले आहे",
        "whatlinkshere-title": "\"$1\" ला जुळलेली पाने",
        "whatlinkshere-page": "पान:",
-       "linkshere-2": "खालील लेख '''$1''' या पानांशी जोडले आहेत:",
-       "nolinkshere-2": "'''$1''' येथे कोणत्याही पानांचे दुवे नाहीत.",
-       "nolinkshere-ns-2": "निवडलेल्या नामविश्वातील कोणतीही पाने <strong>$1</strong>ला दुवा देत नाहीत .",
+       "linkshere": "खालील लेख '''$2''' या पानांशी जोडले आहेत:",
+       "nolinkshere": "'''$2''' येथे कोणत्याही पानांचे दुवे नाहीत.",
+       "nolinkshere-ns": "निवडलेल्या नामविश्वातील कोणतीही पाने <strong>$2</strong>ला दुवा देत नाहीत .",
        "isredirect": "पुनर्निर्देशित पान",
        "istemplate": "आंतर्न्यास (ट्रांसक्लूजन)",
        "isimage": "संचिका दुवा",
        "markedaspatrollederrornotify": "'पहारा दिला' म्हणून अंकित करणे विफल झाले.",
        "patrol-log-page": "टेहळणीतील नोंदी",
        "patrol-log-header": "ही पाहणीनंतरच्या निरीक्षणाची नोंद आहे.",
-       "log-show-hide-patrol": "$1 गस्तीची नोंद",
        "confirm-markpatrolled-button": "ठीक आहे",
        "confirm-markpatrolled-top": "$2च्या $3 आवृत्तीवर पहारा दिला म्हणून खूण करायची?",
        "deletedrevision": "जुनी आवृत्ती ($1) वगळली.",
        "logentry-protect-protect-cascade": "$1 ने $3 $4 [निपतन]ला {{GENDER:$2|सुरक्षित केले}}",
        "logentry-protect-modify": "$1 ने $3 $4 ची  सुरक्षा पातळी {{GENDER:$2|बदलली}}",
        "logentry-protect-modify-cascade": "$1 ने $3 $4 [निपतन]ची  सुरक्षा पातळी {{GENDER:$2|बदलली}}",
-       "logentry-rights-rights": "$1 ने {{GENDER:$6|$3}} साठी $4 वरुन $5 ला गट सदस्यता{{GENDER:$2|बदलली}}",
+       "logentry-rights-rights": "$1 ने {{GENDER:$6|$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",
index 96132fd..50f6e19 100644 (file)
        "savechanges": "Simpan perubahan",
        "publishpage": "Terbitkan",
        "publishchanges": "Terbit perubahan",
+       "savearticle-start": "Simpan laman...",
+       "savechanges-start": "Simpan perubahan...",
+       "publishpage-start": "Terbitkan laman...",
+       "publishchanges-start": "Terbitkan perubahan...",
        "preview": "Pralihat",
        "showpreview": "Paparkan pralihat",
        "showdiff": "Lihat perubahan",
        "whatlinkshere": "Pautan ke laman ini",
        "whatlinkshere-title": "Laman yang mengandungi pautan ke \"$1\"",
        "whatlinkshere-page": "Laman:",
-       "linkshere-2": "Laman-laman berikut mengandungi pautan ke '''$1''':",
-       "nolinkshere-2": "Tiada laman yang mengandungi pautan ke '''$1'''.",
-       "nolinkshere-ns-2": "Tiada laman yang mengandungi pautan ke '''$1''' dalam ruang nama yang dinyatakan.",
+       "linkshere": "Laman-laman berikut mengandungi pautan ke '''$2''':",
+       "nolinkshere": "Tiada laman yang mengandungi pautan ke '''$2'''.",
+       "nolinkshere-ns": "Tiada laman yang mengandungi pautan ke '''$2''' dalam ruang nama yang dinyatakan.",
        "isredirect": "laman lencongan",
        "istemplate": "penyertaan",
        "isimage": "pautan fail",
        "markedaspatrollederrornotify": "Penandaan sebagai dironda gagal.",
        "patrol-log-page": "Log pemeriksaan",
        "patrol-log-header": "Yang berikut ialah log rondaan bagi semakan.",
-       "log-show-hide-patrol": "$1 log rondaan",
-       "log-show-hide-tag": "$1 log teg",
        "deletedrevision": "Menghapuskan semakan lama $1.",
        "filedeleteerror-short": "Ralat ketika menghapuskan fail: $1",
        "filedeleteerror-long": "Berlaku ralat ketika menghapuskan fail tersebut:\n\n$1",
index e67b778..5ab6b4c 100644 (file)
        "whatlinkshere": "Li jwasslu 'l hawn",
        "whatlinkshere-title": "Paġni li jippuntaw lejn $1",
        "whatlinkshere-page": "Paġna:",
-       "linkshere-2": "Il-paġni segwenti jorbtu lejn '''$1''':",
-       "nolinkshere-2": "L-ebda paġna ma twassal għal '''$1'''.",
-       "nolinkshere-ns-2": "L-ebda paġna ma tipponta lejn '''$1''' fl-ispazju tal-isem magħżul.",
+       "linkshere": "Il-paġni segwenti jorbtu lejn '''$2''':",
+       "nolinkshere": "L-ebda paġna ma twassal għal '''$2'''.",
+       "nolinkshere-ns": "L-ebda paġna ma tipponta lejn '''$2''' fl-ispazju tal-isem magħżul.",
        "isredirect": "paġna ta' rindirizz",
        "istemplate": "inklużjoni",
        "isimage": "ħolqa lejn il-fajl",
        "markedaspatrollederrornotify": "L-ivverifikar tal-modifika falla.",
        "patrol-log-page": "Modifiki verifikati",
        "patrol-log-header": "Dan huwa reġistru ta' reviżjonijiet verifikati.",
-       "log-show-hide-patrol": "$1 r-reġistru tal-modifiki verifikati",
-       "log-show-hide-tag": "$1 r-reġistru tat-tikketti",
        "deletedrevision": "Reviżjoni preċedenti, mħassra: $1",
        "filedeleteerror-short": "Problema waqt li kont qiegħed tħassar il-fajl: $1",
        "filedeleteerror-long": "Ġew verifikati xi problemi waqt li kont qiegħed tħassar il-fajl:\n\n$1",
index 297cde8..021ca92 100644 (file)
        "whatlinkshere": "L que lhiga eiqui",
        "whatlinkshere-title": "Páiginas que lhígan a \"$1\"",
        "whatlinkshere-page": "Páigina:",
-       "linkshere-2": "Estas páiginas ténen lhigaçones pa <strong>$1</strong>:",
-       "nolinkshere-2": "Nun eisisten lhigaçones pa '''$1'''.",
+       "linkshere": "Estas páiginas ténen lhigaçones pa <strong>$2</strong>:",
+       "nolinkshere": "Nun eisisten lhigaçones pa '''$2'''.",
        "isredirect": "páigina de ancaminamiento",
        "istemplate": "ancluson",
        "isimage": "lhigaçon pa l fexeiro",
index 912a2b6..cf3cc7f 100644 (file)
        "bold_tip": "စာလုံးမည်း",
        "italic_sample": "စာလုံး အစောင်း",
        "italic_tip": "စာလုံး အစောင်း",
-       "link_sample": "လင့် ခေါင်းစဉ်",
-       "link_tip": "အတွင်းပိုင်း လင့်",
-       "extlink_sample": "http://www.example.com လင့် ခေါင်းစဉ်",
+       "link_sample": "လင့်ခ် ခေါင်းစဉ်",
+       "link_tip": "အတွင်းပိုင်း လင့်ခ်",
+       "extlink_sample": "http://www.example.com လင့်ခ် ခေါင်းစဉ်",
        "extlink_tip": "ပြင်ပလင့်များ (http:// ကို ရှေ့ဆုံးမှ ထည့်ရေးရန် မမေ့ပါနှင့်)",
        "headline_sample": "ခေါင်းကြီးစာသား",
        "headline_tip": "အဆင့် ၂ ခေါင်းစီး",
        "summary-preview": "တည်းဖြတ်အကျဉ်းချုပ် နမူနာ:",
        "subject-preview": "အကြောင်းအရာ နမူနာ:",
        "blockedtitle": "အသုံးပြုသူကို ပိတ်ပင်ထားသည်",
-       "blockedtext": "<strong>သင်၏ အသုံးပြုသူအမည် သို့မဟုတ် အိုင်ပီလိပ်စာသည် ပိတ်ပင်ခြင်း ခံထားရသည်။</strong>\n\nဤပိတ်ပင်မှုအား $1 က ဆောင်ရွက်ခဲ့သည်။\nအကြောင်းရင်းမှာ <em>$2</em> ဖြစ်သည်။\n\n* ပိတ်ပင်ခြင်း စတင်ချိန်: $8\n* ပိတ်ပင်ခြင်း သက်တမ်းကုန်ချိန်: $6\n* ရည်ရွယ်ရာ blockee: $7\n\nသင်သည် ပိတ်ပင်မှုအတွက် ဆွေးနွေးရန် $1 သို့မဟုတ် အခြား [[{{MediaWiki:Grouppage-sysop}}|စီမံခန့်ခွဲသူ]] အား ဆက်သွယ်နိုင်သည်။\nသင့်အနေဖြင့် [[Special:Preferences|အကောင့်၏ ရွေးချယ်စရာများ]]ထဲတွင် ရေရာသော အီးမေးလိပ်စာအား မထည့်သွင်းထားပါက \"ဤအသုံးပြုသူအား အီးမေးပို့ပါ\" လုပ်ဆောင်ချက်ကို အသုံးပြုနိုင်မည် မဟုတ်ပါ။ အလားတူ ယင်းလုပ်ဆောင်ချက်ကို ပိတ်ပင်မခံရမှ လုပ်ဆောင်နိုင်မည်ဖြစ်သည်။\nသင်၏ လက်ရှိ အိုင်ပီလိပ်စာမှာ $3 ဖြစ်ပြီး၊ ပိတ်ပင်မှုအိုင်ဒီမှာ #$5 ဖြစ်သည်။\nသင်ပြုလုပ်မည့် စုံစမ်းမေးမြန်းမှုများတွင် အထက်ပါ အချက်များ အားလုံး ပါဝင်နေပါစေ။",
+       "blockedtext": "<strong>သင်၏ အသုံးပြုသူအမည် သို့မဟုတ် အိုင်ပီလိပ်စာသည် ပိတ်ပင်ခြင်း ခံထားရသည်။</strong>\n\nဤပိတ်ပင်မှုအား $1 က ဆောင်ရွက်ခဲ့သည်။\nအကြောင်းရင်းမှာ <em>$2</em> ဖြစ်သည်။\n\n* ပိတ်ပင်ခြင်း စတင်ချိန်: $8\n* ပိတ်ပင်ခြင်း သက်တမ်းကုန်ချိန်: $6\n* ရည်ရွယ်ရာ blockee: $7\n\nသင်သည် ပိတ်ပင်မှုအတွက် ဆွေးနွေးရန် $1 သို့မဟုတ် အခြား [[{{MediaWiki:Grouppage-sysop}}|စီမံခန့်ခွဲသူ]] အား ဆက်သွယ်နိုင်သည်။\nသင့်အနေဖြင့် [[Special:Preferences|အကောင့်၏ ရွေးချယ်စရာများ]]ထဲတွင် ရေရာသော အီးမေးလိပ်စာအား မထည့်သွင်းထားပါက \"{{int:emailuser}}\" လုပ်ဆောင်ချက်ကို အသုံးပြုနိုင်မည် မဟုတ်ပါ။ အလားတူ ယင်းလုပ်ဆောင်ချက်ကို ပိတ်ပင်မခံရမှ လုပ်ဆောင်နိုင်မည်ဖြစ်သည်။\nသင်၏ လက်ရှိ အိုင်ပီလိပ်စာမှာ $3 ဖြစ်ပြီး၊ ပိတ်ပင်မှုအိုင်ဒီမှာ #$5 ဖြစ်သည်။\nသင်ပြုလုပ်မည့် စုံစမ်းမေးမြန်းမှုများတွင် အထက်ပါ အချက်များ အားလုံး ပါဝင်နေပါစေ။",
        "blockednoreason": "အကြောင်းပြချက် မပေးထားပါ",
        "whitelistedittext": "စာမျက်နှာများကို တည်းဖြတ်ရန် $1ရမည်။",
        "nosuchsectiontitle": "အပိုင်းကို ရှာမရနိုင်ပါ",
        "rev-deleted-user": "(အသုံးပြုသူအမည် ဖယ်ရှားပြီး)",
        "rev-deleted-event": "(အသေးစိတ် မှတ်တမ်း ဖယ်ရှားပြီးပြီ)",
        "rev-deleted-text-permission": "ဤစာမျက်နှာ ရာဇဝင်များသည် <strong>ဖျက်ထားပြီး</strong>ဖြစ်သည်။\nအသေးစိတ်များကို [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} ဖျက်ထားသည့် မှတ်တမ်း]တွင် တွေ့ရှိနိုင်ပါသည်။",
+       "rev-deleted-unhide-diff": "ဤမူကွဲ၏ တည်းဖြတ်မူတစ်ခုအား <strong>ဖျက်ထားသည်</strong>။\nအသေးစိတ်ကို [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} ဖျက်ထားသည့် မှတ်တမ်း]တွင် တွေ့ရှိနိုင်သည်။\nသင့်အနေဖြင့် ဆန္ဒရှိပါက [$1 ဤမူကွဲ]ကို ဆက်လက် ကြည့်ရှုနိုင်သည်။",
+       "rev-deleted-diff-view": "ဤမူကွဲ၏ တည်းဖြတ်မူတစ်ခုအား <strong>ဖျက်ထားသည်</strong>။\nဤမူကွဲကို ကြည့်ရှုနိုင်ပြီး အသေးစိတ်ကို [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} ဖျက်ထားသည့် မှတ်တမ်း]တွင် တွေ့ရှိနိုင်သည်။",
        "rev-delundel": "အမြင်ပုံစံ ပြောင်းလဲရန်",
        "rev-showdeleted": "ပြ",
        "revisiondelete": "မူများကို ဖျက်ရန်/မဖျက်တော့ရန်",
        "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-groups-help": "ဤအသုံးပြုသူ၏ အုပ်စုများကို အောက်ပါအတိုင်း သင်ပြောင်းလဲနိုင်သည်\n* အမှန်ခြစ်အကွက်သည် ထိုအသုံးပြုသူသည် ယင်းအုပ်စုတွင် ပါဝင်ကြောင်း ဆိုလိုသည်။\n* အမှန်ခြစ်မပါသော အကွက်သည် ထိုအသုံးပြုသူသည် ယင်းအုပ်စုတွင် မပါဝင်ကြောင်း ဆိုလိုသည်။\n* ခရေပွင့် * အမှတ်အသားသည် အုပ်စုတစ်ခုအတွင်းသို့ ထည့်သွင်းပြီးပါက ပြန်လည် ဖယ်ရှားမရနိုင်ကြောင်း (အပြန်အလှန်) ကို ဆိုလိုသည်။\n* သင်္ကေတ # အမှတ်အသားသည် ဤအုပ်စုအဖွဲ့ဝင် သက်တမ်းကို ပြန်လည်ထည့်သွင်းနိုင်ပြီး ရှေ့တိုးပေးရန် မဖြစ်နိုင်ကြောင်း ဖော်ပြသည်။",
        "userrights-reason": "အ​ကြောင်း​ပြ​ချက်:",
        "userrights-changeable-col": "သင်ပြောင်းလဲပေးနိုင်သောအုပ်စုများ",
        "userrights-unchangeable-col": "သင်ပြောင်းလဲမပေးနိုင်သောအုပ်စုများ",
+       "userrights-expiry-none": "သက်တမ်းကုန်ဆုံးခြင်း မရှိ",
        "group": "အုပ်စု -",
        "group-user": "အသုံးပြုသူများ",
        "group-autoconfirmed": "အလိုအလျောက် အတည်ပြုထားသော အသုံးပြုသူများ",
        "right-userrights": "အသုံးပြုသူ၏အခွင့်အရေးများအားလုံးကို တည်းဖြတ်ရန်",
        "right-userrights-interwiki": "အခြားဝီကီများမှ အသုံးပြုသူများ၏ အသုံးပြုသူအခွင့်အရေးများကို တည်းဖြတ်ရန်",
        "right-sendemail": "အခြားအသုံးပြုသူများကို အီးမေးပို့ရန်",
+       "grant-blockusers": "အသုံးပြုသူများအား ပိတ်ပင်ခြင်းနှင့် ပိတ်ပင်မှု ဖယ်ရှားခြင်း",
        "grant-editmywatchlist": "သင့် စောင့်ကြည့်စာရင်းကို တည်းဖြတ်ရန်",
        "newuserlogpage": "အသုံးပြုသူအသစ်ရောက်လာခြင်း မှတ်တမ်း",
        "newuserlogpagetext": "ဤသည်မှာ အသုံးပြုသူအသစ် ဖန်တီးမှု မှတ်တမ်း ဖြစ်သည်။",
        "recentchangeslinked-feed": "ဆက်စပ်သော ​အ​ပြောင်း​အ​လဲ​များ​",
        "recentchangeslinked-toolbox": "ဆက်စပ်သော အပြောင်းအလဲများ",
        "recentchangeslinked-title": "\"$1\" နှင့် ဆက်စပ်သော အပြောင်းအလဲများ",
-       "recentchangeslinked-summary": "ဤစာမျက်နှာမှ သို့မဟုတ် ဤစာမျက်နှာသို့ ချိတ်ဆက်ထားသော စာမျက်နှာများ၏ ပြောင်းလဲမှုများကို ကြည့်ရှုနိုင်ရန် စာမျက်နှာအမည်တစ်ခုကို ထည့်သွင်းပါ။ (ကဏ္ဍတစ်ခု၏ အဖွဲ့ဝင်များကို ကြည့်ရှုရန် Category:ကဏ္ဍအမည် ကို ရိုက်ထည့်ပါ။) [[Special:Watchlist|သင့်စောင့်ကြည့်စာရင်း]]ရှိ စာမျက်နှာများ၏ ပြောင်းလဲမှုများကို <strong>စာလုံးအထူ</strong>ဖြင့် ပြထားသည်။",
+       "recentchangeslinked-summary": "ဤစာမျက်နှာမှ သို့မဟုတ် ဤစာမျက်နှာသို့ ချိတ်ဆက်ထားသော စာမျက်နှာများ၏ ပြောင်းလဲမှုများကို ကြည့်ရှုနိုင်ရန် စာမျက်နှာအမည်တစ်ခုကို ထည့်သွင်းပါ။ (ကဏ္ဍတစ်ခု၏ အဖွဲ့ဝင်များကို ကြည့်ရှုရန် {{ns:category}}:ကဏ္ဍအမည် ကို ရိုက်ထည့်ပါ။) [[Special:Watchlist|သင့်စောင့်ကြည့်စာရင်း]]ရှိ စာမျက်နှာများ၏ ပြောင်းလဲမှုများကို <strong>စာလုံးအထူ</strong>ဖြင့် ပြထားသည်။",
        "recentchangeslinked-page": "စာမျက်နှာ အမည် -",
        "recentchangeslinked-to": "ပေးထားသော စာမျက်နှာများအစား လင့်များနှင့် ဆက်စပ်နေသာ စာမျက်နှာများ၏ အပြောင်းအလဲများကို ပြရန်",
        "recentchanges-page-added-to-category": "ကဏ္ဍထဲသို့ [[:$1]] ကို ပေါင်းထည့်ခဲ့သည်",
        "whatlinkshere": "ဘယ်ကလင့်ခ်ထားလဲ",
        "whatlinkshere-title": "\"$1\" သို့ ချိတ်ဆက်ထားသော စာမျက်နှာများ",
        "whatlinkshere-page": "စာမျက်နှာ -",
-       "linkshere-2": "အောက်ပါစာမျက်နှာများသည် <strong>$1</strong> သို့ ချိတ်ဆက်ထားသည် -",
-       "nolinkshere-2": "'''$1''' သို့ လင့်ထားသော စာမျက်နှာ မရှိပါ။",
+       "linkshere": "အောက်ပါစာမျက်နှာများသည် <strong>$2</strong> သို့ ချိတ်ဆက်ထားသည် -",
+       "nolinkshere": "<strong>$2</strong> သို့ လင့်ခ်ထားသော စာမျက်နှာ မရှိပါ။",
        "isredirect": "ပြန်ညွှန်းသော စာမျက်နှာ",
        "istemplate": "ထည့်သွင်းကူးယူချက်",
        "isimage": "ဖိုင်လင့်",
        "whatlinkshere-prev": "{{PLURAL:$1|နောက်သို့|နောက်သို့ $1}}",
        "whatlinkshere-next": "{{PLURAL:$1|ရှေ့သို့|ရှေ့သို့ $1}}",
-       "whatlinkshere-links": "← လင့်များ",
+       "whatlinkshere-links": "â\86\90 á\80\9cá\80\84á\80·á\80ºá\80\81á\80ºá\80\99á\80»á\80¬á\80¸",
        "whatlinkshere-hideredirs": "ပြန်ညွှန်းများ $1",
        "whatlinkshere-hidetrans": "ထည့်သွင်းကူးယူချက် $1",
        "whatlinkshere-hidelinks": "လင့်ခ်များ $1 ခု",
        "whatlinkshere-hideimages": "ဖိုင်အချိတ်အဆက်များ $1 ခု",
        "whatlinkshere-filters": "စိစစ်မှုများ",
+       "unblock": "အသုံးပြုသူကို ပိတ်ပင်ထားရာမှ ပြန်ဖွင့်ပေးရန်",
        "blockip": "{{GENDER:$1|အသုံးပြုသူ}} ပိတ်ပင်ရန်",
        "ipaddressorusername": "အိုင်ပီလိပ်စာ သို့ အသုံးပြုသူအမည် -",
        "ipbexpiry": "သက်တမ်းကုန်လွန်ရက် -",
        "unblocked": "[[User:$1|$1]] ကို ပိတ်ပင်ထားရာမှ ပြန်ဖွင့်ပေးလိုက်သည်",
        "unblocked-id": "$1 ကို ပိတ်ပင်ထားမှုကို ဖယ်ရှာလိုက်သည်",
        "blocklist": "ပိတ်ပင်ထားသော အသုံးပြုသူများ",
+       "autoblocklist": "အလိုအလျောက် ပိတ်ပင်မှုများ",
+       "autoblocklist-legend": "အလိုအလျောက် ပိတ်ပင်မှုများ စာရင်း",
+       "autoblocklist-localblocks": "ဒေသဆိုင်ရာ {{PLURAL:$1|အလိုအလျောက် ပိတ်ပင်မှု|အလိုအလျောက် ပိတ်ပင်မှုများ}}",
+       "autoblocklist-otherblocks": "အခြား {{PLURAL:$1|အလိုအလျောက် ပိတ်ပင်မှု|အလိုအလျောက် ပိတ်ပင်မှုများ}}",
        "ipblocklist": "ပိတ်ပင်ထားသော အသုံးပြုသူများ",
        "ipblocklist-legend": "ပိတ်ပင်ထားသော အသုံးပြုသူတစ်ဦးကို ရှာရန်",
        "ipblocklist-submit": "ရှာဖွေရန်",
        "blocklist-nousertalk": "မိမိ၏ဆွေးနွေးချက်စာမျက်နှာကို တည်းဖြတ်မရနိုင်ပါ",
        "ipblocklist-empty": "ပိတ်ပင်ထားမှုစာရင်းသည် ဗလာဖြစ်နေသည်။",
        "blocklink": "ပိတ်ပင်",
-       "unblocklink": "á\80\9cá\80\84á\80·á\80º á\80\95á\80¼á\80\94á\80ºá\80\96á\80¼á\80±ရန်",
+       "unblocklink": "á\80\99á\80\95á\80­á\80\90á\80ºá\80\95á\80\84á\80ºá\80\90á\80±á\80¬á\80·ရန်",
        "change-blocklink": "စာကြောင်းအမည် ပြောင်းရန်",
        "contribslink": "ပံ့ပိုး",
        "blocklogpage": "ပိတ်ပင်တားဆီးမှု မှတ်တမ်း",
        "filemissing": "ဖိုင်ပျောက်နေသည်",
        "thumbnail_error": "ပုံစံငယ်ဖန်တီးရာတွင် အမှားပြနေသည် - $1",
        "import": "စာမျက်နှာများထည့်သွင်းရန်",
-       "import-interwiki-submit": "á\80\91á\80\8aá\80·်သွင်းရန်",
+       "import-interwiki-submit": "á\80\90á\80\84်သွင်းရန်",
        "import-upload-filename": "ဖိုင်အမည် -",
        "import-comment": "မှတ်ချက် -",
        "importstart": "စာမျက်နှာများကို ထည့်သွင်းနေသည်...",
        "markedaspatrolledtext": "[[:$1]] ၏ ရွေးချယ်ထားသော တည်းဖြတ်မူကို စောင့်ကြပ်စစ်ဆေးပြီးကြောင်း မှတ်သားပြီးပါပြီ။",
        "markedaspatrollednotify": "$1 သို့ ဤပြောင်းလဲမှုအား စောင့်ကြပ်စစ်ဆေးပြီးကြောင်း မှတ်သားပြီးပါပြီ။",
        "patrol-log-page": "စောင့်ကြပ်စစ်ဆေးမှု မှတ်တမ်း",
-       "log-show-hide-patrol": "စောင့်ကြပ်စစ်ဆေးမှု မှတ်တမ်း $1",
        "filedeleteerror-short": "ဖိုင်ဖျက်ရာတွင် အမှားအယွင်း - $1",
        "previousdiff": "← တည်းဖြတ်မူ အဟောင်း",
        "nextdiff": "ပိုသစ်သော တည်းဖြတ်မှု",
        "newimages-label": "ဖိုင်အမည် (သို့ ယင်း၏အစိတ်အပိုင်း) -",
        "noimages": "ကြည့်စရာဘာမှ မရှိပါ။",
        "ilsubmit": "ရှာဖွေရန်",
-       "bydate": "á\80\9bá\80\80á\80ºá\80\85á\80½á\80²á\80\96á\80¼á\80­á\80\84á\80·á\80º",
+       "bydate": "ရက်စွဲဖြင့်",
        "sp-newimages-showfrom": "$1 နေ့ $2 အချိန်ကစသော ဖိုင်အသစ်များကို ပြရန်",
        "bad_image_list": "ဖောမတ်ပုံစံမှာ အောက်ပါအတိုင်းဖြစ်သည်။\n\nစာရင်းတွင်ထည့်သွင်းထားသော အရာများကိုသာ ထည့်သွင်းစဉ်းစားမည်။ (ခရေပွင့် * ဖြင့်စသော စာကြောင်းများ)\nစာကြောင်း၏ ပထမဆုံး လင့်သည် ဖိုင်ညံ့ ဖြစ်ရမည်။\nယင်းစာကြောင်းတွင်ပင် နောက်ထပ်လာသောလင့်များကို ချွင်းချက်အဖြစ် စဉ်းစားမည်။ ဆိုလိုသည်မှာ ၎င်းလင့်များတွင်လည်း အဆိုပါ ဖိုင်ညံ့ ပါကောင်း ပါဝင်နေမည်။",
        "metadata": "Metadata",
        "specialpages-group-maintenance": "ထိန်းသိမ်းမှု အစီရင်ခံချက်များ",
        "specialpages-group-other": "အခြားအထူးစာမျက်နှာများ",
        "specialpages-group-login": "Log in ဝင်ရန်/ အကောင့် ဖန်တီးရန်",
-       "specialpages-group-changes": "လတ်တလောအေပြောင်းအလဲနှင့် မှတ်တမ်းများ",
+       "specialpages-group-changes": "လတ်တလော အပြောင်းအလဲနှင့် မှတ်တမ်းများ",
        "specialpages-group-media": "မီဒီယာ အစီရင်ခံချက်များနှင့် Upload တင်ထားသည်များ",
        "specialpages-group-users": "အသုံးပြုသူများနှင့် အခွင့်အရေးများ",
        "specialpages-group-highuse": "အသုံးများသော စာမျက်နှာများ",
        "tag-mw-blank": "ဗလာပြုလုပ်ခြင်း",
        "tag-mw-replace": "အစားထိုးခဲ့သည်",
        "tag-mw-rollback": "နောက်ပြန် ပြန်ပြင်ခြင်း",
+       "tag-mw-undo": "နောက်ပြန် ပြန်ပြင်ခြင်း",
        "tags-title": "အမည်တွဲ",
        "tags-tag": "အမည်တွဲ အမည်",
        "tags-active-yes": "မှန်",
        "logentry-newusers-autocreate": "အသုံးပြုသူအကောင့် $1 ကို အလိုအလျောက် {{GENDER:$2|ဖန်တီးခဲ့သည်}}",
        "logentry-protect-protect": "$1 က  $3 ကို {{GENDER:$2|ကာကွယ်ခဲ့သည်}} $4",
        "logentry-protect-modify": "$3 အတွက် ကာကွယ်မှုအဆင့်ကို $1 {{GENDER:$2|က ပြောင်းလဲခဲ့သည်}} $4",
+       "logentry-rights-rights": "{{GENDER:$6|$3}} အတွက် အုပ်စုအဖွဲ့ဝင် $4 မှ $5 သို့ $1 က {{GENDER:$2|ပြောင်းလဲခဲ့သည်}}",
        "logentry-upload-upload": "$1 သည် $3 ကို {{GENDER:$2|upload တင်ခဲ့သည်}}",
        "logentry-upload-overwrite": "$3 ၏ ဗားရှင်းအသစ်ကို $1 {{GENDER:$2|upload တင်ခဲ့သည်}}",
        "rightsnone": "(ဘာမှမရှိ)",
        "log-action-filter-newusers-create2": "မှတ်ပုံတင်ထားသော အသုံးပြုသူမှ ဖန်တီးမှု",
        "log-action-filter-newusers-autocreate": "အလိုအလျောက် ဖန်တီးမှု",
        "log-action-filter-newusers-byemail": "အီးမေးလ်မှတဆင့် စကားဝှက်ပို့၍ ဖန်တီးမှု",
-       "gotointerwiki": "{{SITENAME}} မှ ထွက်ခွာနေသည်"
+       "gotointerwiki": "{{SITENAME}} မှ ထွက်ခွာနေသည်",
+       "passwordpolicies": "စကားဝှက် မူဝါဒများ",
+       "passwordpolicies-summary": "ဤသည်မှာ ဤဝီကီရှိ အသုံးပြုသူအုပ်စုများအတွက် အကျုံးဝင်သော စကားဝှက် မူဝါဒများ ဖြစ်သည်။"
 }
index 903c2c4..20ebd82 100644 (file)
        "whatlinkshere": "Мезе тезэнь сюлмави",
        "whatlinkshere-title": "$1 марто сюлмазь лопатне",
        "whatlinkshere-page": "Лопась:",
-       "linkshere-2": "Сыця лопатьне сюлмававить '''$1''' марто:",
-       "nolinkshere-2": "Кодаткак лопат асульмавить '''$1''' марто.",
+       "linkshere": "Сыця лопатьне сюлмававить '''$2''' марто:",
+       "nolinkshere": "Кодаткак лопат асульмавить '''$2''' марто.",
        "isredirect": "Лиякс витнинк-петнинк лопанть",
        "istemplate": "совавтомс",
        "isimage": "файлань сюлмавома пене",
        "markaspatrolledtext": "Тешкстамс те лопанть ванстнемань ютазекс",
        "markedaspatrolled": "Тешкстазь ванстнемань ютазекс",
        "patrol-log-page": "Ванстнемадо конёв",
-       "log-show-hide-patrol": "$1 патрулонь журналонть",
        "deletedrevision": "Нардань ташто лиякстомтома $1",
        "filedeleteerror-short": "\"$1\" керьмазонть нардамсто лиссь ильведевкс",
        "previousdiff": "← Седе икелень верзиязо",
index b4e276f..7636827 100644 (file)
        "whatlinkshere": "لینک‌ئون ِاینتا صفحه",
        "whatlinkshere-title": "وألـگ‌ئونی که \"$1\" ره لـیـنک هه‌دانه",
        "whatlinkshere-page": "صفحه:",
-       "linkshere-2": "اینان صفحه‌ئون به '''$1''' لینک هدانه:",
+       "linkshere": "اینان صفحه‌ئون به '''$2''' لینک هدانه:",
        "isredirect": "دکشی‌ین صفحه",
        "istemplate": "تراگنجانش‌ئون",
        "isimage": "فایل ِلینک",
index 1f1925d..e8f2db4 100644 (file)
        "whatlinkshere": "In tlein quitzonhuilia nican",
        "whatlinkshere-title": "Zāzaniltin quitzonhuiliah $1",
        "whatlinkshere-page": "Tlahcuilolamatl:",
-       "linkshere-2": "Inīn zāzaniltin quitzonhuiliah '''$1''' īhuīc:",
-       "nolinkshere-2": "Ahtle quitzonhuilia '''$1''' īhuīc.",
+       "linkshere": "Inīn zāzaniltin quitzonhuiliah '''$2''' īhuīc:",
+       "nolinkshere": "Ahtle quitzonhuilia '''$2''' īhuīc.",
        "isredirect": "Tlacueptli tlahcuilolamatl",
        "isimage": "īxiptlahtli tzonhuiliztli",
        "whatlinkshere-prev": "{{PLURAL:$1|achtopa|$1 achtopa}}",
index 93069ae..38beb03 100644 (file)
@@ -10,7 +10,8 @@
                        "Macofe",
                        "進也",
                        "Liuxinyu970226",
-                       "Yoxem"
+                       "Yoxem",
+                       "Matěj Suchánek"
                ]
        },
        "tog-underline": "Liân-kiat oē té-sûn:",
        "sp-contributions-userrights": "{{GENDER:$1|iōng-chiá}} khoân-hān koán-lí",
        "sp-contributions-search": "Chhoē chhut kòng-hiàn",
        "sp-contributions-username": "IP Chū-chí a̍h iōng-chiá miâ:",
+       "sp-contributions-newonly": "Taⁿ piáu-sū chhòng-kiàn ia̍h-bīn ê pian-chi̍p",
+       "sp-contributions-hideminor": "Am-khàm sè-hāng pian-chi̍p",
        "sp-contributions-submit": "Chhoē",
        "whatlinkshere": "Tó-ūi liân kàu chia",
        "whatlinkshere-title": "Liân khì \"$1\" ê ia̍h-bīn",
        "whatlinkshere-page": "Ia̍h:",
-       "linkshere-2": "Í-hā '''$1''' liân kàu chia:",
-       "nolinkshere-2": "Bô poàⁿ ia̍h liân kàu '''$1'''.",
+       "linkshere": "Í-hā '''$2''' liân kàu chia:",
+       "nolinkshere": "Bô poàⁿ ia̍h liân kàu '''$2'''.",
        "isredirect": "choán-ia̍h",
        "isimage": "tóng-àn liân-kiat",
        "whatlinkshere-prev": "{{PLURAL:$1|chêng|chêng $1 ê}}",
        "movelogpagetext": "Ē-kha lia̍t-chhut hông soá-ūi ê ia̍h.",
        "movereason": "Lí-iû:",
        "revertmove": "hôe-tńg",
+       "delete_and_move_reason": "Thâi-ia̍h hō͘ \"[[$1]]\" thang sóa-ia̍h kòe--lâi",
        "selfmove": "Goân piau-tê kap sin piau-tê sio-siâng; bô hoat-tō· sóa.",
        "protectedpagemovewarning": "'''KÉNG-KÒ: Pún ia̍h só tiâu leh. Kan-taⁿ ū hêng-chèng te̍k-koân ê iōng-chiá (sysop) ē-sái soá tín-tāng.'''\nĒ-kha ū choè-kīn ê kì-lio̍k thang chham-khó:",
        "export": "Su-chhut ia̍h",
        "filemissing": "Bô tóng-àn",
        "import": "Su-ji̍p ia̍h",
        "tooltip-pt-userpage": "{{GENDER:|Lí ê iōng-chiá}} ê ia̍h",
-       "tooltip-pt-mytalk": "{{GENDER:Lí}} ê thó-lūn ia̍h",
+       "tooltip-pt-mytalk": "{{GENDER:|Lí}} ê thó-lūn ia̍h",
        "tooltip-pt-preferences": "{{GENDER:|Lí ê}} siat-tēng",
        "tooltip-pt-watchlist": "你監視的頁有改過的清單",
        "tooltip-pt-mycontris": "{{GENDER:|Lí}} ê kòng-hiàn lia̍t-toaⁿ",
        "table_pager_limit_submit": "Lâi-khì",
        "autosumm-blank": "Kā ia̍h ê loē-iông the̍h tiāu",
        "autoredircomment": "Choán khì [[$1]]",
+       "autosumm-changed-redirect-target": "Choán-ia̍h bo̍k-phiau kái [[$1]] kòe [[$2]] oân-sêng",
        "autosumm-new": "$1 ê ia̍h í-keng kiàn-li̍p",
        "watchlistedit-normal-submit": "Mài kàm-sī",
        "watchlistedit-normal-done": "Í-keng uì lí ê kám-sī-toaⁿ soá {{PLURAL:$1|ia̍h}} cháu:",
        "specialpages": "Te̍k-sû-ia̍h",
        "tag-filter": "[[Special:Tags|Piau-chhiam]] chhoē mi̍h:",
        "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|piau-chhiam}}]]: $2)",
+       "tag-mw-new-redirect": "Sin choán-ia̍h",
+       "tag-mw-changed-redirect-target": "Choán-ia̍h bo̍k-phiau kái-piàn",
+       "logentry-delete-delete_redir": "$1 ēng têng-siá lâi kā choán-ia̍h $3 {{GENDER:$2|thâi-tiāu}}",
        "logentry-move-move": "$1 {{GENDER:$2|sóa}} $3 chit ia̍h khì $4",
        "logentry-move-move_redir": "$1 iōng choán-ia̍h {{GENDER:$2|sóa}} ia̍h-bīn $3 kòe $4",
        "logentry-newusers-create": "已經{{GENDER:$2|開好}}用者口座 $1",
        "expand_templates_input": "Su-ji̍p bûn-jī:",
        "expand_templates_output": "Kiat-kó:",
        "expand_templates_remove_comments": "Comments the̍h tiāu",
+       "mw-widgets-dateinput-no-date": "Ji̍t-kî iáu-bōe soán",
        "mw-widgets-mediasearch-input-placeholder": "搜揣媒體",
        "date-range-from": "Khai-sí ji̍t-chí:",
        "date-range-to": "Kiat-sok ji̍t-chí:"
index 443bb11..6b18e71 100644 (file)
@@ -16,7 +16,8 @@
                        "Nemo bis",
                        "S4b1nuz E.656",
                        "Ruthven",
-                       "Fitoschido"
+                       "Fitoschido",
+                       "Sannita"
                ]
        },
        "tog-underline": "Sottolinia 'e jonte:",
        "mainpage-nstab": "Paggena prencepale",
        "nosuchaction": "Operazione nun ricanusciuta",
        "nosuchactiontext": "L'azione specificata dint'a l'URL nun è bbona.\nPuò darse ca l'URL fosse stata digitata 'n modo sbagliàto o che fosse stato seguito nu link sbagliàto.\nChesto putesse innecà pùre nu bug dint'a {{SITENAME}}.",
-       "nosuchspecialpage": "Chista paggena speciale nun ce sta",
+       "nosuchspecialpage": "Chesta paggena speciale nun ce sta",
        "nospecialpagetext": "<strong>'A paggena speciale richiesta nun è ricanusciuta.</strong>\n\nL'elenco d' 'e paggene valide spiciale 'o truove int'a [[Special:SpecialPages|l'Elenco d' 'e paggine spiciale]].",
        "error": "Sbaglio",
        "databaseerror": "Sbaglio dint'a database",
        "readonly": "Database arrestato",
        "enterlockreason": "Miette 'o mutivo 'e blocco, nzieme a 'o mumento quanno se penza ca 'o blocco se sarrà fernuto",
        "readonlytext": "Mo mmo 'o database s'è arrestato pe n'operazione semprice 'e manutenzione e nun se ponno azzeccà cagnamiente o pàggene nove. Quanno sarrà fernuta, atanno 'a paggena addeventarrà nurmale.\n\nL'ammenistratore 'e sistema c'ha fatto 'o blocco, nce dà sta spiegazione: $1",
-       "missing-article": "'O database nun trova 'o testo 'e na paggena c'adda stà, c' 'o nomme \"$1\" $2.\n\nNormalmente, chesto succere quanno s'è richiamato, a partire d' 'a cronologgia o pùre a 'o confronto tra verzione, nu cullegamento a na paggena scancellata, a nu confronto tra verziune inesistente o a nu confronto tra verziune re-pulezzate d' 'a cronologgia.\n\n'N caso cuntrario, può darse pure nu sbaglio dint'o software.\nPer piacere, mannate na mmasciata ccà all'[[Special:ListUsers/sysop|amministratore]] annummenanno l'URL 'n quistiona.",
+       "missing-article": "'O database nun trova 'o testo 'e na paggena ca c'avess' a stà, c' 'o nomme \"$1\" $2.\n\nNurmalmente, chisto succere quanno s'è richiammato na cronologgia o pùre a nu confronto tra verzione 'e a na paggena scancellata.\n\n'N caso cuntrario, può darse pure nu sbaglio dint'o software.\nPe ppiacere, mannate na mmasciata ccà all'[[Special:ListUsers/sysop|amministratore]] annummenanno l'URL 'n quistiona.",
        "missingarticle-rev": "(nummero 'e verzione: $1)",
        "missingarticle-diff": "(Diff: $1, $2)",
        "readonly_lag": "'O database s'è arrestato automaticamente pe' tramente ca 'e servers 'e database schiave sincronizzano c' 'o server masto.",
        "viewsource": "Vere sorgente",
        "viewsource-title": "Vere surgente 'e $1",
        "actionthrottled": "Azione ritardata",
-       "actionthrottledtext": "Comme misura anti-abuse, site lemmetato 'a ffà st'azione troppe vote dint'a nu curto spazio 'e tiempo, e mò stu lèmmeto è stato superato.\nPe' piacere pruvate n'ata vota dint'a cocche minuto.",
+       "actionthrottledtext": "Comme mesùra anti-abuse, site lemmetato 'a ffà st'azione troppe vote dint'a nu curto spazio 'e tiempo, e mo stu lèmmeto l'avite superato.\nPe piacere pruvate n'ata vota dint'a quacche minuto.",
        "protectedpagetext": "Sta paggena s'è prutetta pe' ne bloccà 'a mudifeca o n'ata azione.",
        "viewsourcetext": "Putite vedé e copià 'o codece surgiva 'e sta paggena.",
        "viewyourtext": "Putite vedé e copià 'o codice surgiva d' 'e <strong>cagnamiénte vuoste</strong> a sta paggena.",
        "cascadeprotected": "Sta paggena è stata prutetta 'a 'o cangamento pecché trascluse int'a {{PLURAL:$1|sta paggena, che è prutetta|sti paggene, che songo prutette}} quann' 'a l'ozione \"ricurziva\" è attiva:\n$2",
        "namespaceprotected": "Nun avite permesso a cagnà 'e paggene dint'a stu namespace '''$1'''.",
        "customcssprotected": "Nun v'è permesso 'a cagnà sta paggena CSS, pecché cuntene 'e mpustaziune perzunale 'e n'at'utente.",
+       "customjsonprotected": "Nun v'è permesso 'a cagnà sta paggena JSON, pecché cuntene 'e mpustaziune perzunale 'e n'at'utente.",
        "customjsprotected": "Nun v'è permesso 'a cagnà sta paggena JavaScript, pecché cuntene 'e mpustaziune perzunale 'e n'at'utente.",
        "mycustomcssprotected": "Nun v'è permesso 'a cagnà sta paggena CSS.",
+       "mycustomjsonprotected": "Nun v'è permesso 'a cagnà sta paggena JSON.",
        "mycustomjsprotected": "Nun v'è licenzia pe cagnà sta paggena JavaScript.",
        "myprivateinfoprotected": "Nun v'è licenzia pe cagnà 'a nfurmaziona privata vuosta.",
        "mypreferencesprotected": "Nun v'è licenzia 'a cagnà 'e preferenze tuoje.",
        "virus-scanfailed": "scanziona fallita (codece $1)",
        "virus-unknownscanner": "antivirus scanusciuto:",
        "logouttext": "'''Site asciùte.'''\n\nNota ca arcune paggene putessero cuntinuà ad cumparì comme se 'o logout nun fosse affettuato fin quanno nun sarrà pulezzata 'a cache d\"o proprio browser.",
-       "cannotlogoutnow-title": "Nun se pò ascì mò",
+       "cannotlogoutnow-title": "Mo nun se pò ascì",
        "cannotlogoutnow-text": "'A disconessione nun è possibbele quanno s'ausa $1.",
        "welcomeuser": "Bemmenuto, $1!",
        "welcomecreation-msg": "'O cunto vuosto è stato criato.\nMo' putite cagnà 'e [[Special:Preferences|preferenze 'e {{SITENAME}}]].",
        "userlogin-signwithsecure": "Usa na conessione sicura",
        "cannotlogin-title": "Nun se pò trasì",
        "cannotlogin-text": "Trasì nun è possibbele mò.",
-       "cannotloginnow-title": "Nun se pò trasì mò",
+       "cannotloginnow-title": "Mo nun se pò trasì",
        "cannotloginnow-text": "'A connessione nun è possibbele quanno s'ausa $1.",
        "cannotcreateaccount-title": "Nun se ponno crià cunte",
        "cannotcreateaccount-text": "'A criazione diretta 'e cunte è stutata int'a stu wiki.",
        "nosuchusershort": "Nun ce stanno utente cu o nòmme \"$1\". Cuntrolla si scrivìste buòno.",
        "nouserspecified": "Tiene 'a dìcere nu nomme pricìso.",
        "login-userblocked": "Chist'utente è bloccato. Nun se può effettuà 'o login.",
-       "wrongpassword": "'A password nzertàta nun è bbona.\nPe' piacere pruvate n'ata vota.",
+       "wrongpassword": "'A password nzertàta nun è bbona. Pe' piacere, pruvate n'ata vota.",
        "wrongpasswordempty": "'A password nzertàta è abbacante.\nPe' piacere pruvate n'ata vota.",
        "passwordtooshort": "'E password hann'avé minimo {{PLURAL:$1|nu carattere|$1 carattere}}.",
        "passwordtoolong": "'E password nun ponno essere cchiù luonghe 'e {{PLURAL:$1|nu carattere|$1 carattere}}.",
-       "passwordtoopopular": "'E parole comune nun se ponno ausà pe' ve fà na password. Sciglite na password cchiù unica.",
+       "passwordtoopopular": "'E parole comune nun se ponno ausà comme password. Scigliteve na password cchiù tosta.",
        "password-name-match": "'A password adda essere diverza 'a 'o nomme utente.",
        "password-login-forbidden": "L'uso 'e stu nomme utente e password è stato proibito.",
        "mailmypassword": "Riabbìa 'a password",
        "passwordremindertitle": "Nnova password temporale pe' {{SITENAME}}",
-       "passwordremindertext": "Cocche perzona (pussibbilmente tu, cu n'innerizzo IP $1) ha dimmannato l'invio 'e na password d'accieso nova pe' {{SITENAME}} ($4).\nNa password temporanea e' l'utente \"$2\" s'è abbiata comme \"$3\".\nSi chest'è stata l'intenzione toja, allora hè a trasì dint'o sito e cagnà 'a password mò. 'A password temporanea scade aropp'a {{PLURAL:$5|nu juorno|$5 ghiuorne}}.\n\nSi nun sì stato tu a dimannà 'a password, o pure hè truvat'a password e nun 'a bbuò cagnà cchiù, allora nun fà niente e continua a usare 'a password viecchia.",
+       "passwordremindertext": "Quaccheduno (pussibbilmente tu, cu n'innerizzo IP $1) ha dimmannato l'invio 'e na password d'accieso nova pe {{SITENAME}} ($4).\nNa password temporanea 'e l'utente \"$2\" s'è abbiata comme \"$3\".\nSi chest'è stata l'intenzione toja, allora hè a trasì dint'o sito e cagnà 'a password primm'e mo. 'A password temporanea scade aropp'a {{PLURAL:$5|nu juorno|$5 ghiuorne}}.\n\nSi nun sì stato tu a dimannà 'a password, o pure hê truvat'a password e nun 'a bbuò cagnà cchiù, allora nun fà niente e continua a usare 'a password viecchia.",
        "noemail": "Nun ce sta indirizzo e-mail pe' l'utente \"$1\".",
        "noemailcreate": "S'add'appruviggiunà n'indirizzo e-mail buono.",
        "passwordsent": "Na password nova è stata inviata a l'innerizzo e-mail riggistrato 'a ll'utente \"$1\".\nPe' piacere, trasite appena avite ricevuta sta password.",
        "eauthentsent": "Na mmasciata 'e conferma t'è stata mannata a l'indirizzo e-mail nzignàto.\nApprimm' 'e te mannà n'atu mail, hè 'a stà 'a ffà 'e struzione dint'a l'e-mail, pe' cunfermà ca 'o cunto fosse d' 'o tujo overo.",
        "throttled-mailpassword": "S'è mannata na mail pe te' riabbià 'a password 'a meno 'e {{PLURAL:$1|n'ora|$1 ore}}.\nPe' ce sparagnà abbuse, 'a funzione 'e riabbiamento d' 'a password se può usa sulamente na vota ogne {{PLURAL:$1|ora|$1 ore}}.",
        "mailerror": "Errore pe' tramente ca se mannava na mmasciata: $1",
-       "acct_creation_throttle_hit": "'E vvisite a sta wiki ausanno l'IP tuoja se so' mise a crià {{PLURAL:$1|1 registrazzione|$1 registrazzione}} int'a ll'urdeme juorne ($2), chesto fosse 'o massimo premmesso pe' stu periodo 'e tiempo.\nPerciò, 'e utente ca ausano chisto innerezzo IP nun se ponno riggistrà ancora mò mò.",
+       "acct_creation_throttle_hit": "'E vvisite a sta wiki ausanno l'IP tuoja se so' mise a crià {{PLURAL:$1|1 registrazzione|$1 registrazzione}} int'a ll'urdeme juorne ($2), chesto fosse 'o massimo premmesso pe' stu periodo 'e tiempo.\nPerciò, ll'utente ca ausano chisto innerezzo IP nun se ponno riggistrà mo.",
        "emailauthenticated": "'O ndirizzo email è stato cunfermato 'o $2 a 'e $3.",
        "emailnotauthenticated": "'O ndirizzo 'e posta elettronica nun è stat'ancora cunfermato.\nNun se mannarranno mmasciate e-mail p' ' funzione ccà abbascio.",
        "noemailprefs": "Avite 'a specificà nu ndirizzo e-mail pe ll'attivà sti funzione.",
        "botpasswords-existing": "Password bot esistente",
        "botpasswords-createnew": "Crèa na password bot nòva",
        "botpasswords-editexisting": "Cagna na password bot esistente",
+       "botpasswords-label-needsreset": "('a password adda esse cangiata)",
        "botpasswords-label-appid": "Nomme d' 'o bot:",
        "botpasswords-label-create": "Crèa",
        "botpasswords-label-update": "Agghiuorna",
-       "botpasswords-label-cancel": "Canciella",
+       "botpasswords-label-cancel": "Scancella",
        "botpasswords-label-delete": "Scancèlla",
        "botpasswords-label-resetpassword": "Riabbìa 'a password",
        "botpasswords-label-grants": "Assegnaziune apprecabbele:",
        "botpasswords-insert-failed": "Nun se pò azzeccà 'o nomme bot \"$1\". Fosse stato già azzeccato?",
        "botpasswords-update-failed": "Se scassaje a carrecà 'o nomme bot \"$1\". È stato scancellato?",
        "botpasswords-created-title": "Password bot criata",
-       "botpasswords-created-body": "'A password bot \"$1\" 'a ll'utente \"$2\" fuje criata.",
+       "botpasswords-created-body": "'A password pe' 'o bot \"$1\" 'e ll'{{GENDER:$2|utente}} \"$2\" fuje criata.",
        "botpasswords-updated-title": "Password bot agghiurnata",
-       "botpasswords-updated-body": "'A password bot \"$1\" 'a ll'utente \"$2\" fuje agghiurnata.",
+       "botpasswords-updated-body": "'A password pe' 'o bot \"$1\" 'e ll'{{GENDER:$2|utente}} \"$2\" fuje agghiurnata.",
        "botpasswords-deleted-title": "Password bot scancellata",
-       "botpasswords-deleted-body": "'A password bot \"$1\" 'a ll'utente \"$2\" è stata scancellata.",
+       "botpasswords-deleted-body": "'A password pe' 'o bot \"$1\" 'e ll'{{GENDER:$2|utente}} \"$2\" è stata scancellata.",
        "botpasswords-newpassword": "'A password nòva pe' puté trasì cu <strong>$1</strong> è <strong>$2</strong>. <em>Pe' piacere signatevello chesto pe' ve ffà conzurtaziune future.</em> <br>('E bott viecchie addò servisse nu nomme utente comm'a chell' 'e l'utente, putite ancora ausà <strong>$3</strong> comm' 'o nomm' 'utente e <strong>$4</strong> comm' 'a password.)",
        "botpasswords-no-provider": "BotPasswordsSessionProvider nun è disponibbele.",
        "botpasswords-restriction-failed": "'E restriziune 'e password bot nun ve permettessero st'acciesso.",
        "botpasswords-invalid-name": "'O nomme utente nnecato nun cuntenesse nu spartetóre 'e bot password (\"$1\").",
        "botpasswords-not-exist": "L'utente \"$1\" nun téne na password bot chiammata \"$2\".",
+       "botpasswords-needs-reset": "'A password pe' 'o bot \"$1\" 'e ll'{{GENDER:$2|utente}} \"$2\" adda esse cangiata.",
        "resetpass_forbidden": "'E password nun se ponno cagnà",
        "resetpass_forbidden-reason": "'E password nun se ponno cagnà: $1",
        "resetpass-no-info": "Avite 'a trasì ('o login) pe ffà l'acciesso a sta paggena direttamente.",
        "resetpass-submit-loggedin": "Cagna password",
-       "resetpass-submit-cancel": "Canciella",
+       "resetpass-submit-cancel": "Scancella",
        "resetpass-wrong-oldpass": "'A password temporanea o attuale nun è bbona.\n'A password putesse avé cagnato, o pure s'è addimannata na password temporanea nova.",
        "resetpass-recycled": "Pe piacere riabbiate 'a password e mettete na password differénte a chella 'e mmò.",
        "resetpass-temp-emailed": "Sì trasuto cu nu codece temporaneo, mannato via e-mail. Pe' fà cumpleta 'a riggistraziona, avite 'e abbià na password nova ccà:",
        "savechanges": "Sarva 'e cagnamiénte",
        "publishpage": "Pubbreca paggena",
        "publishchanges": "Pubbreca 'e cagnamiente",
+       "savearticle-start": "Sarva 'a paggena...",
+       "savechanges-start": "Sarva 'e cagnamiénte...",
+       "publishpage-start": "Pubbreca 'a paggena...",
+       "publishchanges-start": "Pubbreca 'e cagnamiente...",
        "preview": "Anteprimma",
        "showpreview": "Vire anteprimma",
        "showdiff": "Fa veré 'e cagnamiente",
        "anonpreviewwarning": "''Nun avite fatto 'o login. Sarvann' 'a paggena, l'indirizzo IP d' 'o vuosto sarrà riggistrato dint'a cronologgia.''",
        "missingsummary": "'''Attenziò:''' nun s'è specificato l'oggetto 'e stu cagnamiento. Clicann' 'a \"$1\" n'ata vota 'o cagnamiento sarrà sarvato cu l'oggetto abbacante.",
        "selfredirect": "<strong>Attenziò:</strong> State crianno nu redirect a 'o stesso articolo.\nPuò darse c'avites specificato 'o pizzo sbagliato p' 'o redirect, o ca stavate cagnanno 'o pizzo sbagliato.\nSi cliccate \"$1\" n'ata vota, si criarrà 'o redirect.",
-       "missingcommenttext": "Pe' piacere scrivete nu commento ccà abbascio.",
+       "missingcommenttext": "Pe' piacere, scrivete nu commento.",
        "missingcommentheader": "<strong>Arricurdateve:</strong> nun s'è specificato l'oggetto/titolo pe stu commento. Clicann' 'a \"$1\" n'ata vota 'o cagnamiento sarrà sarvato c' 'o titolo/oggetto abbacante.",
        "summary-preview": "Anteprimma'e l'oggetto:",
        "subject-preview": "Anteprimma 'e l'oggetto:",
        "previewerrortext": "È succiesso n'errore quanno se steva a ffà pre-veré 'e cagnamiente vuoste.",
        "blockedtitle": "Utente bloccato.",
        "blockedtext": "<strong>'O nomme utente o ll'IP vuosto è stato bloccato.</strong>\n\n'O blocco è stato mpustato 'a $1. 'O mutivo d' 'o blocco è chisto: ''$2''\n\n* Abbiàta d' 'o blocco: $8\n* Ammaturità d' 'o blocco: $6\n* Tiempo 'e blocco: $7\n\nPutite cuntattà $1 o n'atu [[{{MediaWiki:Grouppage-sysop}}|ammenistratore]] pe discutere d'ô blocco.\n\nVedite c' 'a funzione \"{{int:emailuser}}\" nun è attiva si nun s'ave riggistrato 'o ndirizzo e-mail buono dint' 'e [[Special:Preferences|preferenze]] o pùre si ll'uso 'e tale funzione è stato bloccato.\n\n'O ndirizzo IP 'e mo è $3, 'o nummero ID d' 'o blocco è #$5.\nPe piacere avite 'a specificà tutte sti dettaglie quanno facite carche dumanna.",
-       "autoblockedtext": "Ll'IP vuosto è stato bloccato pecché 'o steva piglianno n'atu utente, ch'è stato bloccato pe' $1.\n\n'O mutivo d' 'o blocco è chesto:\n\n:''$2''\n\n* Abbiàta d' 'o blocco: $8\n* Ammaturità d' 'o blocco: $6\n* Tiempo 'e blocco: $7\n\nPutite cuntattà $1 o n'atu [[{{MediaWiki:Grouppage-sysop}}|ammenistratore]] pe' discutere 'o blocco.\n\nVedite c' 'a funzione 'Scrivete a ll'utente' nun è attiva si nun s'è riggistrato 'o ndirizzo e-mail buono dint' 'e [[Special:Preferences|preferenze]] o pùre si ll'uso 'e tale funzione è stato bloccato.\n\n'O ndirizzo IP attuale è $3, 'o nummero ID d' 'o blocco è #$5.\nPe' piacere avite 'e specificà tutte sti dettaglie ccà ncoppa quanno facite cocche dumanna.",
-       "systemblockedtext": "'O nomme utente d' 'o vuosto o ll'IP address fosse stata automaticamente bluccata 'a MediaWiki.\n'O mutivo fosse chesto:\n\n:<em>$2</em>\n\n* Inizio d' 'o blocco: $8\n* Ammatura 'o blocco: $6\n* Intervall' 'e blocco: $7\n\n'O indirizzo IP 'e mò fosse $3.\nPe' piacere, facite specifice tuttuquante 'e ddettaglie ccà quanno iate a ghienchere na richiesta 'e chiarimiente.",
+       "autoblockedtext": "Ll'IP vuosto è stato bloccato pecché 'o steva ausanno n'atu utente, ch'è stato bloccato 'a $1.\n\n'O mutivo d' 'o blocco è chesto:\n\n:''$2''\n\n* 'O blocco è abbiate: $8\n* 'O blocco fernesce: $6\n* Tiempo 'e blocco: $7\n\nPutite cuntattà $1 o n'atu [[{{MediaWiki:Grouppage-sysop}}|ammenistratore]] pe' discutere chisto blocco.\n\nVedite c' 'a funzione \"Scrivete a ll'utente\" è attiva sule si avite messe 'nu ndirizzo e-mail buono dint' 'e vostre [[Special:Preferences|preferenze]] e si nun siete state bloccato.\n\n'O ndirizzo IP attuale vostro è $3, 'o nummero ID d' 'o blocco è #$5.\n\nPe' piacere avite 'e specificà tutte sti dettaglie ccà ncoppa quanno facite cocche dumanna.",
+       "systemblockedtext": "'O nomme utente d' 'o vuosto o ll'IP address songo stati automaticamente bluccati 'a MediaWiki.\n'O mutivo fosse chesto:\n\n:<em>$2</em>\n\n* Inizio d' 'o blocco: $8\n* Ammatura 'o blocco: $6\n* Intervall' 'e blocco: $7\n\n'O indirizzo IP fusse $3.\nPe piacere, facite specifice tutt' 'e ddettaglie ccà quanno iate a fà na richiesta 'e chiarimiente.",
        "blockednoreason": "nisciuna ragione è stata indicata",
        "whitelistedittext": "Pe' cagnà 'e ppaggene è necessario $1.",
        "confirmedittext": "Pe puté cagnà paggene avite 'a cunfermà l'indirizzo e-mail.\nPe' piacere abbiate e ffà 'a validazione d' 'o ndirizzo e-mail pe' bbìa d' 'e [[Special:Preferences|preferenze d'utente]].",
        "blocked-notice-logextract": "St'utente è bloccato mò.\nL'urdemo elemento d' 'o riggistro 'e blocche è ripurtato ccà abbascio p'avé nu riferimento:",
        "clearyourcache": "<strong>Nota:</strong> aroppo sarvate putisse necessità 'e pulezzà 'a caché d' 'o navigatóre pe' vedé 'e cagnamiente. \n*<strong>Firefox / Safari</strong>: sprémme 'o buttóne maiuscole e ffà clic ncopp'a ''Recarreca'', o pure spremme ''Ctrl-F5'' o ''Ctrl-R'' (''⌘-R'' ncopp'a Mac)\n*<strong>Google Chrome''': spremme ''Ctrl-Shift-R'' (''⌘-Shift-R'' ncopp'a nu Mac)\n*<strong>Internet Explorer</strong>: spremme 'o buttóne ''Ctrl'' pe' tramente ca faie click ncopp'a ''Refresh'', o pure spremmere ''Ctrl-F5''\n* <strong>Opera:</strong> Vaje addò 'o <em>Menu → Mpustaziune</em> (<em>Opera → Mpustaziune</em> ncopp' 'o Mac) e po' ncopp'a <em>Privacy & sicurezza → Pulezza date d' 'o browser → Immaggene e file d' 'a cache</em>.",
        "usercssyoucanpreview": "'''Cunziglio:''' spremme 'o buttone 'Vide anteprimma' pe' pruvà 'o CSS nuovo apprimma d' 'o sarvà.",
+       "userjsonyoucanpreview": "<strong>Cunziglio:</strong> premme 'o buttone \"{{int:showpreview}}\" pe' pruvà 'o JSON nuovo apprimma d' 'o sarvà.",
        "userjsyoucanpreview": "'''Cunziglio:''' spremme 'o buttone 'Vide anteprimma' pe' pruvà 'o JavaScript nuovo apprimma d' 'o sarvà.",
        "usercsspreview": "'''Arricuordate ca chest'è sulamente n'anteprimma p' 'o CSS perzunale. 'E cagnamiente nun so' state ancora sarvate!'''",
+       "userjsonpreview": "<strong>Arricuordate ca chest'è sulamente n'anteprimma p' 'o JSON perzunale. 'E cagnamiente nun so' state ancora sarvate!</strong>",
        "userjspreview": "'''Arricuordate ca chest'è sulamente n'anteprimma p' 'o JavaScript perzunale. 'E cagnamiente nun so' state ancora sarvate!'''",
        "sitecsspreview": "'''Arricuordate ca chest'è sulamente n'anteprimma p' 'o CSS. 'E cagnamiente nun so' state ancora sarvate!'''",
+       "sitejsonpreview": "<strong>Arricuordate ca chest'è sulamente n'anteprimma d' 'a configurazzione d' 'o JSON. 'E cagnamiente nun so' state ancora sarvate!</strong>",
        "sitejspreview": "'''Arricuordate ca chest'è sulamente n'anteprimma p' 'o codece JavaScript. 'E cagnamiente nun so' state ancora sarvate!'''",
-       "userinvalidconfigtitle": "'''Attenziò:''' Nun esiste nisciuna skin c' 'o nomme \"$1\". Vide ch' 'e paggene .css e .js personalezzate teneno nu titolo n minucola, p'esempio {{ns:user}}:Esempio/vector.css e nun {{ns:user}}:Esempio/Vector.css.",
+       "userinvalidconfigtitle": "<strong>Attenziò:</strong> Nun esiste nisciuna skin c' 'o nomme \"$1\". Vide ch' 'e paggene .css e .js personalezzate teneno nu titolo ca minuscola, p'esempio {{ns:user}}:Esempio/vector.css (e no {{ns:user}}:Esempio/Vector.css).",
        "updated": "(Agghiurnato)",
        "note": "'''Nota:'''",
        "previewnote": "'''Chesta è sola n'anteprimma; 'e cagnamiénte â paggena nun songo ancora sarvate!'''",
        "editingsection": "Cagnamiénto 'e $1 (sezzione)",
        "editingcomment": "Cagnamiénto 'e $1 (nova sezzione)",
        "editconflict": "Conflitto d'edizzione: $1",
-       "explainconflict": "N'at'utente ave sarvato na nova verziona d' 'a paggena pe' tramente ca stevate a fà 'e cagnamiente.\n'A cascia 'e mudifeca ncoppa cuntene 'o testo d' 'a paggena ca mò sta online, accussì comme è stato agghiurnato a l'at'utente.\n'A verziona ch' 'e cagnamiente vuoste è stata mmece riportata dint'a cascia 'e mudifeca abbascio.\nSi 'e vulite cunfermà avite 'a ripurtà 'e cagnamiente d' 'e vuoste dint'o testo ca esiste (dint'a cascia ncoppa).\nSpremmendo 'o buttón '$1', sarrà sarvato '''sulamente''' 'o testo cuntenuto dint'a cascia 'e cagnamiento ncoppa.",
+       "explainconflict": "N'at'utente ave sarvato na verziona nova d' 'a paggena pe tramente ca stevate a ffà 'e cagnamiente.\n'A cascia 'e mmudifeca ncoppa tene 'o testo d' 'a paggena ca sta online mo, accussì comme fuje agghiurnato pe ll'at'utente.\n'A verziona ch' 'e cagnamiente vuoste è stata mmece riportata dint'a cascia 'e mudifeca abbascio.\nSi 'e vulite cunfermà, avite 'a ripurtà 'e cagnamiente d' 'e vuoste dint'o testo ca esiste (dint'a cascia ncoppa).\nSpremmendo 'o buttón '$1', sarrà sarvato '''sulamente''' 'o testo cuntenuto dint'a cascia 'e cagnamiento ncoppa.",
        "yourtext": "'O testo vuosto",
-       "storedversion": "A verziona 'n memoria",
+       "storedversion": "A verziona int'a memoria",
        "editingold": "'''Attenziò: staje cagnanno na verziona nun agghiurnata d' 'a paggena. Si 'a sarve accussì, tutte 'e cagnamiente fatte aropp'a sta verziona sarranno sperdute.'''",
+       "unicode-support-fail": "Pare ca 'o browser vostro nun tene 'o supporto pe Unicode. 'E cagnamiente nun so' state sarvate, pecché Unicode è obbligatorio 'a tenè pe mudificà 'e paggene.",
        "yourdiff": "Differenze",
        "copyrightwarning": "Pe' piacere tenite a mmente ca tutte 'e contribbute a {{SITENAME}} songo cunziderate pubbrecate dint'e térmene d'uso d' 'a licienza $2 (vedite $1 pe n'avé cchiù dettaglie).\nSi nun vulite ca 'e testi vuoste fossero cagnate e distribuite 'a uno qualunque senza lémmeto, nun 'e mannate ccà.<br />\nMannanno stu testo dichiarate pùre, sott'a responsabilità vuosta, ch'è stato scritto 'a vuje perzunalmente o pure ca è stato copiato 'a na fonte n pubblico dominio o similarmente libbera.\n'''Nun mannate materiale prutetto 'a copyright senz'avé autorizzaziona!'''",
        "copyrightwarning2": "Pe' piacere tenite a mmente ca tutte 'e contribbute a {{SITENAME}} se ponno cagnà, alterà, o distribbuì pe l'ati cuntribbuttòre.\n\nSi nun vulite ca 'e teste vuoste fossero cagnàte spenzieratamente, nun 'e mannate ccà.<br />\nMannanno stu testo dichiarate pùre, sott'a responsabilità vosta, ch'è stato scritto 'a vuje perzunalmente o pure ca è stato copiato 'a na fonte n pubblico dominio o similarmente libbera (vedete $1 pe' n'avé dettaglie).\n'''Nun mannate materiale prutetto 'a copyright senza n'avé autorizzaziona!'''",
        "longpageerror": "'''Errore: 'o testo mannato è luongo {{PLURAL:$1|1|$1}} kilobyte, ch'è cchiù grosso d' 'a diminziona massima cunzentita ({{PLURAL:$2|1|$2}} kilobyte).'''\n'O testo nun se pò sarvà.",
        "readonlywarning": "<strong>Attenziò</strong>: 'o database è bloccato pe se ffà 'a manutenzione. P' 'o mumento nun se ponno sarvà 'e cagnamiente fatte.\nPe' nun 'e sperdere, copia sti cuntenute dint'a nu file 'e testo e sarvatillo pe' tramente c'aspiette 'o sblocco d' 'o database.\n\nL'ammenistratore 'e sistema ca mpustaje 'o blocco ave scritto sta spiegazione: $1.",
        "protectedpagewarning": "'''Attenziò: sta paggena è stata bloccata 'n modo tale ca sulamente l'utente ch' 'e privilegge d'ammenistratore 'a ponno cagnà.'''\nL'urdemo elemento d' 'o riggistro è scritto ccà abbascio pe' n'avé riferimento:",
-       "semiprotectedpagewarning": "'''Nota:''' Sta paggena è stata bloccata 'n modo ca sulamente l'utente riggistrate 'a ponno cagnà.\nL'urdemo elemento d' 'o riggistro è scritto ccà abbascio pe n'avé nfurmazione:",
+       "semiprotectedpagewarning": "<strong>Nota:</strong> Sta paggena è stata bloccata 'n modo ca sulamente l'utente autoconfermati 'a ponno cagnà. L'urdemo elemento d' 'o riggistro è scritto ccà abbascio pe n'avé nfurmazione:",
        "cascadeprotectedwarning": "<strong>Attenziò:</strong> Sta paggena è stata bloccata 'n modo ca sulamente l'utente ch' 'e [[Special:ListGroupRights|privilegge specifiche]] 'a ponno cagnà. Chesto succiere pecché 'a paggena è appennuta dint'a {{PLURAL:$1|la paggena innecata ccà abbascio, ch'è stata prutetta|'e paggene innecate ccà abbascio, che so' state prutette}} sciglienno 'a prutezione \"ricurziva\":",
        "titleprotectedwarning": "'''Attenziò: sta paggena è stata bloccata 'n modo ca fossero necessarie [[Special:ListGroupRights|deritte specifici]] p' 'a crià.'''\nL'urdemo elemento d' 'o riggistro è riportato ccà abbascio pe nfurmazione:",
        "templatesused": "{{PLURAL:$1|Template|Templates}} ausate 'a chesta paggena:",
        "permissionserrors": "Nun haje 'e premmesse abbastante.",
        "permissionserrorstext": "Nun haje premmesse pe lle ffà st'azziune, {{PLURAL:$1|'o mutivo è chesto|'e mutive so' chiste}}:",
        "permissionserrorstext-withaction": "Nun haje premmesse abbastante pe' $2, {{PLURAL:$1|'o mutivo è chesto|'e mutive so' chiste}}:",
-       "contentmodelediterror": "Vuje nun putite cagnà sta verziona pecché 'o mudell' 'e cuntenute è <code>$1</code>, ca cagnasse nu poco nfacc' 'o mudell' 'e mò d' 'a paggena è <code>$2</code>.",
+       "contentmodelediterror": "Vuje nun putite cagnà sta verziona pecché 'o mudello d' 'e cuntenute è <code>$1</code>, ca cagnasse nu poco nfacc' 'o mudello d' 'a paggena  <code>$2</code> 'e mo.",
        "recreate-moveddeleted-warn": "'''Attenziò: staje a crià na paggena scancellata già.'''\n\nVire si è bbuono 'e cuntinuà a cagnà sta paggena. L'elenco ch' 'e relative scancellamiente e spustamente s'è scritto ccà abbascio pe' ffà comodo:",
        "moveddeleted-notice": "Sta paggena è stata scancellata.\n'A lista d' 'e relative scancellamiente e spustamente sta cca 'bbascio pe' n'avé 'nfurmazione.",
-       "moveddeleted-notice-recent": "Scusate, sta mmasciata è stata scancellata mo mo (dint'a sti 24 ore).\n\nL'aziune 'e scancellazione e spustamento pe' sta paggena so dispunibbele ccà p' 'a cumpretezza.",
+       "moveddeleted-notice-recent": "Scusate, sta paggena è stata scancellata mo mo (dint'a sti 24 ore).\n\nTutte l'azziune 'e scancellazione e spustamento pe' sta paggena so dispunibbele ccà pe' cumpretezza.",
        "log-fulllog": "Vide log sano",
        "edit-hook-aborted": "'O cagnamiento è stato annullato 'a 'o «hook».\nNun dette spiegazione nisciuna.",
        "edit-gone-missing": "Nun se può agghiurnà 'a paggena.\nPare ch' 'è stata scancellata.",
        "postedit-confirmation-created": "'A paggena è stata criata.",
        "postedit-confirmation-restored": "'A paggena è stata arripigliata.",
        "postedit-confirmation-saved": "'O cagnamiento è stato sarvato.",
+       "postedit-confirmation-published": "'E cagnamiente so' state pubbricate.",
        "edit-already-exists": "Nun se può crià na paggena nova.\nEsiste già.",
        "defaultmessagetext": "Mmasciata 'e testo predefinita",
        "content-failed-to-parse": "Nun se può analizzare $2 p' 'o mudello $1: $3",
        "undo-success": "'O cagnamiento se può annullà.\nPe' piacere vedete 'e differenze mmustate nfra 'e verziune pe' te ffà capace ca 'e cuntenute songo bbuone, e astipate 'e cagnamiente ccà abbascio pe' fernì e accussì turnà arreto.",
        "undo-failure": "Nun se può fà turnà arreto 'o cagnamiento pecché ce sta nu conflitto ch' 'e cagnamiente intermedie.",
        "undo-norev": "Nun se può fà turnà arreto 'o cagnamiento pecché nun esiste o s'è scancellato.",
-       "undo-nochange": "Pare c' 'o cagnamiento s'è già fatto turnà arreto.",
-       "undo-summary": "Canciella 'o cagnamiento $1 'e [[Special:Contributions/$2|$2]] ([[User talk:$2|Chiàcchiera]])",
+       "undo-nochange": "Pare ca sto cagnamiento s'ha scancellato già.",
+       "undo-summary": "Scancella 'o càgno $1 'e [[Special:Contributions/$2|$2]] ([[User talk:$2|Chiàcchiera]])",
        "undo-summary-username-hidden": "Annullato 'o cagnamiento $1 pe n'utente annascunnuto",
        "cantcreateaccount-text": "'A riggistraziona è stata bloccata 'a l'utente [[User:$3|$3]] 'a st'innerizzo IP ('''$1''').\n\n'O mutivo dato 'a $3 è chistu ccà: ''$2''",
        "cantcreateaccount-range-text": "'A criazione 'e cunte 'a ll'indirizze int'o ntervallo <strong>$1</strong>, che cummiglia 'o vuosto (<strong>$4</strong>), è stata bloccata 'a l'utente [[User:$3|$3]].\n\n'O mutivo dato 'a $3 è chistu ccà: <em>$2</em>",
        "rev-showdeleted": "faje vedé",
        "revisiondelete": "Scancella o ripiglia verziune",
        "revdelete-nooldid-title": "Verziona nun specificata",
-       "revdelete-nooldid-text": "Nun avite specificato nu target 'e verziona addò s'avess'apprecà sta funzione, o 'a verziona specificata nun esiste o pure jate truvanno 'annascónnere 'a verziona 'e mò.",
+       "revdelete-nooldid-text": "Nun avite specificato nisciuna verzione 'e target addò s'aviss'apprecà sta funzione, o 'a verziona specificata nun esiste o pure jate truvanno 'annascùnnere 'a verziona 'e mo.",
        "revdelete-no-file": "'O file specificato nun esiste.",
        "revdelete-show-file-confirm": "Sì sicuro/a ca vulite veré 'a verziona scancellata d' 'o file \"<nowiki>$1</nowiki>\" d' 'o $2 a 'e $3?",
        "revdelete-show-file-submit": "Sì",
        "revdelete-text-file": "'E verziune 'e file scancellate cumpareno ancora dint' 'a cronologgia d' 'o file, ma parte d' 'o cuntenuto lloro nun sarrà a disposizione a 'o pubbreco.",
        "logdelete-text": "'E fatte 'e riggistro scancellate cumpareno ancora dint' 'a cronologgia 'e riggistro, ma na parte d' 'o cuntenuto lloro nun sarrà a disposizione a 'o pubbreco.",
        "revdelete-text-others": "Ll'at'ammenistrature puterranno ancora trasì e arrepiglià 'e cuntenute annascunnute, si nun so' state mpustate cchiù restrizziune.",
-       "revdelete-confirm": "Pe' piacere cunfermate ca overo vulite ffà chesto, ca cunuscete 'e cunseguenze, e ca state facenno chesto rispettanno 'e [[{{MediaWiki:Policy-url}}|linee guida]].",
+       "revdelete-confirm": "Pe ppiacere cunfermate ca overo vulite ffà chisto, ca cunuscite 'e cunseguenze, e ca state facenno chisto rispettanno 'e [[{{MediaWiki:Policy-url}}|linee guida]].",
        "revdelete-suppress-text": "Sti luvamiente hana essere fatte '''unicamente''' dint' 'e situaziune ccà abbascio:\n* nfurmaziune potenzialmente diffamatorie\n* date perzunale inopportune\n*: ''indirizze, nummeri 'e telefono, codece fiscale, ecc.''",
        "revdelete-legend": "Miette 'e limmete 'e visibilità",
        "revdelete-hide-text": "Testo d' 'a verziona",
        "revdelete-edit-reasonlist": "Càgna 'e mutive pe' fà 'o scancellamiento",
        "revdelete-offender": "Autore d' 'a verziona:",
        "suppressionlog": "Riggistro 'e luvamiente",
-       "suppressionlogtext": "Ccà abbascio ce sta n'alenco ch' 'e scancellamiente e blocche ca teneno cuntenute annascunnuto a l'ammenistrature.\nVide l'[[Special:BlockList|elenco d' 'e blocche]] pe' l'elenco e banne e blocche attive 'e mò.",
+       "suppressionlogtext": "Ccà abbascio ce sta n'alenco 'e scancellamiente e blocche ca teneno cuntenute annascunnuti â ll'ammenistrature.\nVide l'[[Special:BlockList|elenco d' 'e blocche]] pe ll'elenco e banne e blocche attive ca ce stanno mo.",
        "mergehistory": "Aunisce 'e cronologgie",
        "mergehistory-header": "Sta paggena te permette d'aunì 'e verziune d' 'a cronologgia 'e na paggena origgine a na paggena nova.\nVedite ca s'avesse 'a nchiantà stu cagnamiento senza scassà 'a continuità storeca d' 'a paggena.",
        "mergehistory-box": "Aunisce 'a cronologgia 'e ddoje ppaggene:",
        "mergehistory-same-destination": "'E paggene d'origgine e destinazione nun ponno essere eguale",
        "mergehistory-reason": "Mutivo:",
        "mergelog": "Riggistro d'aunione",
-       "revertmerge": "Annulla aunione",
+       "revertmerge": "Sfàjere ll'aunione",
        "mergelogpagetext": "Ccà abbascio ce sta na lista cu ll'urdeme aunione int'a cronologgia d' 'e ddoje paggene.",
        "history-title": "$1: cronologgia d' 'e cagnamiente",
        "difference-title": "Differenze nfra 'e verziune 'e \"$1\"",
        "lineno": "Riga $1:",
        "compareselectedversions": "Cunfronta 'e verziune scigliute",
        "showhideselectedversions": "Cagna visibbelità d' 'e verziune scigliute",
-       "editundo": "annulla",
+       "editundo": "sfàjere",
        "diff-empty": "(Nisciuna differenza)",
        "diff-multi-sameuser": "({{PLURAL:$1|Na verziona ntermedia|$1 verziune ntermedie}} 'e n'utente stisso nun {{PLURAL:$1|è mmustata|songo mmustate}})",
        "diff-multi-otherusers": "({{PLURAL:$1|Na virzione ntermedia|$1 verziune ntermedie}} 'a {{PLURAL:$2|n'at'utente|$2 n'ati ddoj'utente}} nun è mmustata)",
        "right-createaccount": "Crìa utenze nove",
        "right-autocreateaccount": "Tràse automaticamente cu n'utenza 'e fore",
        "right-minoredit": "Nzigna 'e cagnamiente comme minure",
-       "right-move": "Muove 'e paggene",
+       "right-move": "Muove 'e ppaggene",
        "right-move-subpages": "Muove 'e paggene nzieme ê sottopaggene suje",
        "right-move-rootuserpages": "Muove 'e paggene princepale d'utente",
        "right-move-categorypages": "Muove 'e categurìe",
        "right-suppressrevision": "Vide, annascunne e ripiglia 'e verziune specifiche d' 'e paggene a cocherun'utente",
        "right-viewsuppressed": "Vide 'e verziune annascunnute a coccherun'utente",
        "right-suppressionlog": "Vide 'e riggistre private",
-       "right-block": "Blocca 'e cagnamiente 'a parte 'e l'at'utente",
-       "right-blockemail": "Blocca n'utente a mannà e-mail",
+       "right-block": "Nun fa fa' cagnamienti a ll'at'utente",
+       "right-blockemail": "Nun fa mannà e-mail a n'utente",
        "right-hideuser": "Blocca n'utente e fallo sparì 'a 'o pubbreco",
        "right-ipblock-exempt": "Ignora 'e blocche 'e l'IP, 'e blocche automatece e li blocche 'e range 'e l'IP",
        "right-unblockself": "Sblocca se stesso",
        "right-viewmyprivateinfo": "Vide 'e proprie date private (e.g. e-mail, nomme overo)",
        "right-editmyprivateinfo": "Cagna 'e date perzunale proprie (p'esempio: e-mail, nomme overo)",
        "right-editmyoptions": "Cagna 'e preferenze proprie",
-       "right-rollback": "Annulla ampresso 'e cagnamiente 'e ll'urdem'utente c'avesse cagnato na paggena particulare",
+       "right-rollback": "Sfàje ampresso 'e cagnamiente 'e ll'urdem'utente ca cagnaje na paggena particulare",
        "right-markbotedits": "Nzégna 'e cagnamiente suggette a rollback ('o torna arreto) comme affettuate 'a nu bot",
        "right-noratelimit": "Nun suggetto a lemmeto d'aziune",
        "right-import": "Carreca paggene 'a n'ati wiki",
        "right-changetags": "Azzecca o lèva a caso 'e [[Special:Tags|tag]] dint'a verziune nnividuale e riggistre 'e log",
        "right-deletechangetags": "Scancella l'[[Special:Tags|etichette]] d' 'o database",
        "grant-generic": "Pacco 'e deritte \"$1\"",
-       "grant-group-page-interaction": "Interagisce ch' 'e paggene",
+       "grant-group-page-interaction": "Interagisce ch' 'e ppaggene",
        "grant-group-file-interaction": "Intergische ch' 'e file 'e media",
        "grant-group-watchlist-interaction": "Interagisce cu l'elenco 'e cuntrollo vuosto",
        "grant-group-email": "Manna e-mail",
        "grant-group-administration": "Secuta aziune ammenistrative",
        "grant-group-private-information": "Tràse dint' 'e date private ncopp'a tte",
        "grant-group-other": "Attività differénte",
-       "grant-blockusers": "Blocca e sblocca utente",
+       "grant-blockusers": "Fremma e lassa i ll'utenti",
        "grant-createaccount": "Crìa cunte",
        "grant-createeditmovepage": "Créa, cagna e móve paggene",
        "grant-delete": "Scancella paggene, verziune, trasute 'e riggistro",
        "action-reupload-shared": "sovrascrive stu file prisente dint'a ll'archivio condiviso",
        "action-upload_by_url": "carreca stu file 'a n'indirizzo URL",
        "action-writeapi": "usa l'API 'n scrittura",
-       "action-delete": "scancèlla chista paggena",
+       "action-delete": "scancèlla chesta paggena",
        "action-deleterevision": "scancellà 'e verziune",
        "action-deletedhistory": "vide 'a cronologgia scancellata 'e sta paggena",
        "action-browsearchive": "ascìa dint' 'e paggene scancellate",
-       "action-undelete": "arripiglia chista paggena",
+       "action-undelete": "arripiglia chesta paggena",
        "action-suppressrevision": "rivedé e arripiglià 'e cagnamiente annascunnute",
        "action-suppressionlog": "vide stu riggistro privato",
-       "action-block": "blocca 'e cagnamiente 'a parte 'e st'utente",
+       "action-block": "fremma st'utente 'e fa' cagnamiente",
        "action-protect": "cagna 'e livelle 'e prutezione pe' sta paggena",
-       "action-rollback": "annulla ampresso 'e cagnamiente 'e ll'urdem'utente c'avesse cagnato na paggena particulare",
+       "action-rollback": "Sfàje ampresso 'e cagnamiente 'e ll'urdem'utente ca cagnaje na paggena particulare",
        "action-import": "carreca paggene 'a n'ata wiki",
        "action-importupload": "carreca paggene 'a n'upload 'e file",
        "action-patrol": "nzegna 'e cagnamiente 'e l'ati utente comme cuntrullate",
        "recentchanges-summary": "Ncopp'a chesta paggena song' appresentate ll'urdeme cagnamiente fatte ê cuntenute d\"o sito.",
        "recentchanges-noresult": "Nisciuno cagnamiento dint'o periodo dato ca soddisfà sti criterie.",
        "recentchanges-feed-description": "Ncoppa chistu feed song' appresentate ll'urdeme cagnamiente fatte ê cuntenute d\"o sito.",
-       "recentchanges-label-newpage": "Chista modifica ha criato 'na nova paggena",
+       "recentchanges-label-newpage": "Chisto cagno ha criato na paggena nova",
        "recentchanges-label-minor": "Chisto è nu cagnamiénto piccerillo",
        "recentchanges-label-bot": "Cagnamiento affettuato 'a nu bot",
-       "recentchanges-label-unpatrolled": "Chista modifica nun è stata 'ncora verificata",
-       "recentchanges-label-plusminus": "'A grannezza d' 'a paggena s'è cagnata pe' bbia 'e stu nummero 'e bytes",
+       "recentchanges-label-unpatrolled": "Chisto cagno nun è stato 'ncora verificato",
+       "recentchanges-label-plusminus": "Nummero 'e bytes cagnati int' 'a paggena",
        "recentchanges-legend-heading": "<strong>Liggenda:</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (vide [[Special:NewPages|'e paggene nove]])",
        "recentchanges-submit": "Faje vedé",
        "tmp-write-error": "Errore a scrivere nu file temporaneo.",
        "large-file": "S'arraccumanna 'e nun appassà 'e diminsione 'e $1 p'ogne file; stu file è gruosso $2.",
        "largefileserver": "Stu file appassa 'e dimensiune permesse 'a la configurazione d' 'o server",
-       "emptyfile": "'O file carrecato mò mò pare abbacante. Può darse ch'è stato n'errore int' 'o nomme d' 'o file. Cuntrullate ca vulite overamente carrecà stu file.",
+       "emptyfile": "'O file c'avite carrecato pare avvacante. Può essere ch'è stato n'errore int' 'o nomme d' 'o file. Cuntrullate ca vulite overamente carrecà stu file.",
        "windows-nonascii-filename": "Chista wiki nun supporta nomme d' 'e file cu carattere spiciale",
        "fileexists": "Nu file cu stu nomme esiste già.\nPe' piacere cuntrullate primma <strong>[[:$1]]</strong> si nun site sicure ca 'o vulite cagnà.\n[[$1|thumb]]",
        "filepageexists": "'A paggena 'e descrizione 'e stu file è stata già criata a l'indirizzo <strong>[[:$1]]</strong>, pùre si nun esiste ancora nu file cu stu nomme. 'A descrizione 'e l'oggetto nzertàta 'n fase 'e carreca nun cumparerrà ncopp' 'a paggena 'e descrizione. Pe' ffà l'oggetto cumparì ncopp' 'a paggena 'e descrizione, l'avisseve 'a cagnà manualmente.\n[[$1|thumb]]",
        "uploaded-animate-svg": "Truvato 'o tag \"animate\" ca putesse stà a cagnà href, ausanno l'attribbuto \"from\" <code>&lt;$1 $2=\"$3\"&gt;</code> int' 'o file carrecato SVG.",
        "uploaded-setting-event-handler-svg": "Mpustà n'attributo event-handler è bluccato, truvato <code>&lt;$1 $2=\"$3\"&gt;</code> int' 'o fie carrecato SVG.",
        "uploaded-setting-href-svg": "Ausà 'o tag \"set\" pe' putè azzeccà attribbute \"href\" a l'elemento parente è bluccato.",
-       "uploaded-wrong-setting-svg": "D'ausà 'o tag \"set\" pe' putè azzeccà nu target remoto/date/script a n'attribbuto mò è bluccato. Truvato 'o code>&lt;set to=\"$1\"&gt;</code> dint' 'o file SVG carrecato.",
+       "uploaded-wrong-setting-svg": "D'ausà 'o tag \"set\" pe putè azzeccà nu target remoto/date/script a n'attribbuto mo sta bluccato. Truvato 'o code>&lt;set to=\"$1\"&gt;</code> dint' 'o file SVG carrecato.",
        "uploaded-setting-handler-svg": "'o SVG ca mpustasse l'attribbuto \"handler\" cu nu remoto/date/script è bluccato. Truvato <code>$1=\"$2\"</code> dint' 'o file SVG carrecato.",
        "uploaded-remote-url-svg": "SVG ca mpustasse n'attribbuto 'e stile cu n'URL remota bluccata. Truvate <code>$1=\"$2\"</code> int' 'o file carrecato SVG.",
        "uploaded-image-filter-svg": "Truvato filtro immaggene cu n'URL: <code>&lt;$1 $2=\"$3\"&gt;</code> int' 'o file SVG carrecato.",
        "upload-foreign-cant-load-config": "Scassaje a carrecà 'o file 'e mpustaziune p' 'e repositorie 'e fore.",
        "upload-dialog-disabled": "'A carreca 'e file tramite sta fenesta 'e dialogo è stutata int'a stu wiki.",
        "upload-dialog-title": "Carreca file",
-       "upload-dialog-button-cancel": "Canciella",
+       "upload-dialog-button-cancel": "Scancella",
        "upload-dialog-button-done": "Fatto",
        "upload-dialog-button-save": "Sarva",
        "upload-dialog-button-upload": "Carreca",
        "backend-fail-read": "Nun se può lieggere 'o file \"$1\".",
        "backend-fail-create": "Nun se può scrivere 'o file \"$1\"",
        "backend-fail-maxsize": "Nun se può scrivere 'o file \"$1\" pecché chist'è cchiù gruosso 'e {{PLURAL:$2|nu byte|$2 byte}}",
-       "backend-fail-readonly": "L'archivio 'e rezza \"$1\" è mò mò 'n sola-lettura. 'O mutivo è: <em>$2</em>",
+       "backend-fail-readonly": "L'archivio 'e rezza \"$1\" sta mo c'â sola-lettura. 'O mutivo è: <em>$2</em>",
        "backend-fail-synced": "'O file \"$1\" è int' 'a nu stato ncunzistente dint'a l'archivie nterne.",
        "backend-fail-connect": "Nun se può cunnettà â memoria 'e rezza \"$1\".",
        "backend-fail-internal": "N'errore scanusciuto s'è verificato int'a l'archivie 'e rezza \"$1\".",
        "backend-fail-usable": "Nun se può lieggere o scrivere 'o file \"$1\" pecché mancano 'e permesse sufficiente o nun esiste 'a cartella/cuntenitore.",
        "filejournal-fail-dbconnect": "Nun se può fà connessione a l'archivio d' 'o database pe' puté astipà archivie 'n rezza \"$1\".",
        "filejournal-fail-dbquery": "Nun se può agghiurnà l'archivio d' 'o database pe' puté astipà l'archivie 'n rezza \"$1\".",
-       "lockmanager-notlocked": "Nun se può sbloccà \"$1\"; nun è bluccato.",
+       "lockmanager-notlocked": "Nun se può sbloccà \"$1\"; nun sta bluccato.",
        "lockmanager-fail-closelock": "Nun se può nchiure 'o file 'e blocco pe' \"$1\".",
        "lockmanager-fail-deletelock": "Nun se può scancellà 'o file 'e blocco pe' \"$1\".",
        "lockmanager-fail-acquirelock": "Nun se può piglià 'o blocco pe' \"$1\".",
        "filerevert-submit": "Arrepiglia",
        "filerevert-success": "'''[[Media:$1|$1]]''' è stat'arripigliato â verziona [$4 d' 'e $3 d' 'o $2].",
        "filerevert-badversion": "Nun ce sta na virziona lucale 'e stu file cu l'orario addimannato.",
-       "filerevert-identical": "'A verziona 'e mò d' 'o file è già eguale eguale a chilla scigliuta.",
+       "filerevert-identical": "'A verziona 'e mo d' 'o file è già eguale eguale a chella scigliuta.",
        "filedelete": "Scancella $1",
        "filedelete-legend": "Scancella 'o file",
        "filedelete-intro": "State pe' scancellà 'o file '''[[Media:$1|$1]]''' cu tutta 'a cronologgia 'e chisto.",
        "nrevisions": "$1 {{PLURAL:$1|verzione|verziune}}",
        "nimagelinks": "Ausate ncopp'a {{PLURAL:$1|na paggena|$1 paggene}}",
        "ntransclusions": "ausate ncopp'a {{PLURAL:$1|na paggena|$1 paggene}}",
-       "specialpage-empty": "Nun ce stanno risultate pe' stu report.",
+       "specialpage-empty": "Nun ce stanno risultate pe stu report.",
        "lonelypages": "Paggene orfane",
        "lonelypagestext": "'E paggene ccà abbascio nun so state cullegate o appennute int' 'a n'ati paggene ncopp'a {{SITENAME}}.",
        "uncategorizedpages": "Paggene senza categurìa",
        "deadendpagestext": "'E paggene ccà abbascio nun spontano a n'ati paggene ncopp'a {{SITENAME}}.",
        "protectedpages": "Paggene prutette",
        "protectedpages-indef": "Sulamente prutezziune a tiempo nun definito",
-       "protectedpages-summary": "Sta paggena elenca 'e paggene ch'esisteno e ca songo prutette mò. Pe n'avé n'elenco 'e titule prutette â criazione, vedite [[{{#special:ProtectedTitles}}|{{int:protectedtitles}}]].",
+       "protectedpages-summary": "Sta paggena elenca 'e paggene ch'esisteno e ca mo stanne prutette. P'avé n'elenco 'e titule prutette â criazione, vedite [[{{#special:ProtectedTitles}}|{{int:protectedtitles}}]].",
        "protectedpages-cascade": "Sulamente prutezziune ricurzive",
        "protectedpages-noredirect": "Annascunne redirect",
-       "protectedpagesempty": "Nisciuna paggena è prutetta pe mò cu sti parametre.",
+       "protectedpagesempty": "Nisciuna paggena è prutetta pe mo cu sti parametre.",
        "protectedpages-timestamp": "Data e ora",
        "protectedpages-page": "Paggena",
        "protectedpages-expiry": "Ammatura",
        "protectedpages-unknown-performer": "Utente scanusciuto",
        "protectedtitles": "Paggene prutette",
        "protectedtitles-summary": "Sta paggena elenca 'e titule ca song'attualmente prutette 'a criazione. Pe' n'avé n'elenco 'e paggene prutette ch'esisteno, vedite [[{{#special:ProtectedPages}}|{{int:protectedpages}}]].",
-       "protectedtitlesempty": "Nisciunu titolo è prutetto pe mò cu sti parametre.",
+       "protectedtitlesempty": "Nisciuno titolo è prutetto pe mo cu sti parametre.",
        "protectedtitles-submit": "Mmusta titule",
        "listusers": "Lista 'e l'utente",
        "listusers-editsonly": "Fà vedé sulamente l'utente cu cagnamiente fatte",
        "listusers-creationsort": "Arrecetta pe' data 'e criazione",
-       "listusers-desc": "Arrecetta 'a l'auto a 'o vascio",
+       "listusers-desc": "Desponne 'a screscere",
        "usereditcount": "{{PLURAL:$1|nu càgnamiento|$1 càgnamiente}}",
        "usercreated": "{{GENDER:$3|Criato/a}} 'o $1 a $2",
        "newpages": "Paggene cchiù frische",
        "apisandbox-dynamic-parameters-add-label": "Azzecca nu parametro:",
        "apisandbox-dynamic-parameters-add-placeholder": "Nomme d' 'o parametro",
        "apisandbox-dynamic-error-exists": "Nu parametro denommenato \"$1\" esiste già.",
-       "apisandbox-deprecated-parameters": "Parametre mò obsoleti",
+       "apisandbox-deprecated-parameters": "Parametri obsoleti",
        "apisandbox-fetch-token": "Auto-ghienche 'o token",
        "apisandbox-submit-invalid-fields-title": "Cocche campo nun è buono",
        "apisandbox-submit-invalid-fields-message": "Pe' piacere curriggite 'e campe nzegnàte e tentate n'ata vota.",
        "deleteprotected": "Nun putite scancellà sta paggena pecché è stata prutetta.",
        "deleting-backlinks-warning": "<strong>Attenzione:</strong>\n[[Special:WhatLinksHere/{{FULLPAGENAME}}|ati paggene]] cunteneno cullegamiente o paggene appennute â n'ata paggena ca state pe' scancellà.",
        "rollback": "Ausa na revizione 'e primma",
-       "rollbacklink": "a vascio",
-       "rollbacklinkcount": "annulla {{PLURAL:$1|nu cagnamiento|$1 cagnamiente}}",
-       "rollbacklinkcount-morethan": "annulla cchiù 'e {{PLURAL:$1|nu cagnamiento|$1 cagnamiente}}",
+       "rollbacklink": "sfàjere",
+       "rollbacklinkcount": "sfàje {{PLURAL:$1|nu cagnamiento|$1 cagnamiente}}",
+       "rollbacklinkcount-morethan": "sfàje cchiù 'e {{PLURAL:$1|nu cagnamiento|$1 cagnamiente}}",
        "rollbackfailed": "Annullamento fallito",
        "rollback-missingparam": "Parammetre obbligate mancante int' 'a richiesta.",
        "rollback-missingrevision": "Nun se ponno carrecà 'e date d' 'a verziuna.",
        "whatlinkshere": "Paggene ca cullegano a chesta",
        "whatlinkshere-title": "Paggene ca cullegano a $1",
        "whatlinkshere-page": "Paggena:",
-       "linkshere-2": "'E paggene ccà abbascio cunteneno jonte ca spuntano a '''$1'''.",
-       "nolinkshere-2": "Nisciuna paggena cuntene jonte ca spuntasse a <strong>$1</strong>.",
-       "nolinkshere-ns-2": "Nun ce stanno paggene ca spuntassero '''$1''' dint' 'o namespace scigliuto.",
+       "linkshere": "'E ppaggene ccà abbascio teneno jonte a <strong>$2</strong>.",
+       "nolinkshere": "Nisciuna paggena cuntene jonte a <strong>$2</strong>.",
+       "nolinkshere-ns": "Nun ce stanno paggene ca spuntassero '''$2''' dint' 'o namespace scigliuto.",
        "isredirect": "redirect a paggena",
        "istemplate": "'nclusione",
        "isimage": "Cullegamente a file multimediale",
        "whatlinkshere-filters": "Filtre",
        "whatlinkshere-submit": "Vaje",
        "autoblockid": "Autoblocco #$1",
-       "block": "Blocca l'utente",
+       "block": "Fremma st'utente.",
        "unblock": "Sblocca l'utente",
-       "blockip": "Blocca {{GENDER:$1|utente}}",
+       "blockip": "Fremma {{GENDER:$1|utente}}",
        "blockiptext": "Ausa 'o modulo ccà abbascio pe' bluccà l'acciesso 'e scrittura a n'indirizzo IP o utente.\nChisto s'avesse 'a ffà sulamente pe' se pruteggere d' 'o vandalismo, d'accordo ch' [[{{MediaWiki:Policy-url}}|'e reole]].\nMettite pure nu mutivo specifico ccà abbascio (p'esempio, facenno 'o nomme 'e paggene addò se so' fatte 'e vandalisme).\nPutite bluccà ntervalle IP ausanno 'a sintasse [https://it.wikipedia.org/wiki/CIDR CIDR]; l'intervallo cchiù ampio cunzentito è /$1 pe' IPv4 e /$2 pe' IPv6.",
        "ipaddressorusername": "Nnerizzo IP o nomme utente",
        "ipbexpiry": "Ammatura:",
        "ipbreason-dropdown": "* Mutive comune pe' ffà 'o blocco\n** Steva nzertanno nfurmaziune fauze\n** Steva a luvà cuntenute d' 'e paggene\n** Steva a fà spam 'e cullegamiente a 'e site 'e fore\n** Steva a nzertà robbe senza senso dint' 'e paggene\n** Minacce e ntimidaziune\n** Abbuso 'e cunte utente multiple\n** Nomme utente inaccettabbele",
        "ipb-hardblock": "Nun permettere 'o cagnamiento a l'utente riggistrate ca veneno 'a st'indirizzo IP",
        "ipbcreateaccount": "Nun fà crià 'o cunto",
-       "ipbemailban": "Blocca utente a mannà e-mail",
-       "ipbenableautoblock": "Automaticamende blocca l'urdeme indirizze IP ausate 'a st'utente, e pure tutte l'IP c'ausasse pe' pruvà 'e fà ati cagnamiente",
-       "ipbsubmit": "Blocca st'utente",
+       "ipbemailban": "Nun fa mannà e-mail a st'utente",
+       "ipbenableautoblock": "Fremma automaticamende l'urdeme indirizze IP ausate 'a st'utente, e pùre tutte ll'IP c'ausasse pe pruvà 'e fà ati cagnamienti",
+       "ipbsubmit": "Fremma st'utente",
        "ipbother": "N'ata durata:",
        "ipboptions": "2 ore:2 hours,1 juorno:1 day,3 juorne:3 days,1 semmana:1 week,2 semmane:2 weeks,1 mese:1 month,3 mise:3 months,6 mise:6 months,1 anno:1 year,infinito:infinite",
        "ipbhidename": "Annascunne 'o nomme utente d' 'a lista 'e cagnamiente e l'ati liste",
-       "ipbwatchuser": "Fà vedé 'a paggena utente e le chiacchieriate 'e st'utente",
+       "ipbwatchuser": "Fà vedé 'a paggena utente e 'e chiacchieriate 'e chist'utente",
        "ipb-disableusertalk": "Nun permettere a st'utente edità 'a paggena 'e chiacchiera d' 'a soja pe' tramente ch'e bloccato",
-       "ipb-change-block": "Blocca n'ata vota l'utente cu sti mpustaziune",
+       "ipb-change-block": "Fremma n'ata vota ll'utente cu ste mpustaziune",
        "ipb-confirm": "Cunferma 'o blocco",
        "badipaddress": "Indirizzo IP nun valido",
        "blockipsuccesssub": "Blocco aseguito",
        "sorbsreason": "L'indirizzo IP vuosto è elencato comm'a nu proxy araputo dint' 'a lista DNSBL ausata 'a {{SITENAME}}.",
        "sorbs_create_account_reason": "L'indirizzo IP d' 'o vuosto è elencato comm'a nu proxy araputo dint' 'a DNSBL ausata 'a {{SITENAME}}. Nun putite crià nu cunto.",
        "xffblockreason": "N'indirizzo IP prisente dint' 'e cap'e paggena X-Forwarded-For, o chillu d' 'o vuosto o chillu 'e n'atu server proxy ca stat'ausann, è stato bloccato. 'O mutivo origgenale 'e blocco era: $1",
-       "cant-see-hidden-user": "L'utente ca state a bluccà è stato già bluccato e annascunnuto. Si nun tenite 'o deritto ''hideuser'', nun putite veré stu blocco d'utente.",
+       "cant-see-hidden-user": "L'utente ca state fremmanno he sito bluccato e annascunnuto già. Si nun tenite 'o deritto ''hideuser'', nun putite veré stu blocco utente.",
        "ipbblocked": "Nun putite bloccà o sbluccà utente pecche vuje stesso site bluccato.",
        "ipbnounblockself": "Nun avite permesso a ve bluccà vuje stesso.",
-       "lockdb": "Blocca 'o database",
+       "lockdb": "Nzerra 'o database",
        "unlockdb": "Sblocca 'o database",
        "lockdbtext": "Bluccanno 'o database se luvarranno l'abbilità 'e tutte l'utente 'e cagnà 'e paggene, cagnà 'e preferenze lloro, cagnà 'a lista 'e paggene cuntrullate e ati cose ca richiedessero cagnamiente ô database.\nPe' piacere cunfermate ca chisto e chello ca vulite fà, e ca luvarrate 'o blocco ô database quanno sta manutenziona sarrà fernuta.",
        "unlockdbtext": "Sbluccanno 'o database se s'arrepigliarranno l'abbilità 'e tutte l'utente 'e cagnà 'e paggene, cagnà 'e preferenze lloro, cagnà 'a lista 'e paggene cuntrullate e ati cose ca richiedessero cagnamiente ô database.\nPe' piacere cunfermate ca chisto e chello ca vulite fà.",
        "lockconfirm": "Sì, overo vulesse bluccà 'o database.",
        "unlockconfirm": "Sì, overo vulesse sbluccà 'o database.",
-       "lockbtn": "Blocca 'o database",
+       "lockbtn": "Nzerra 'o database",
        "unlockbtn": "Sblocca 'o database",
        "locknoconfirm": "Nun avite scigliuto 'a casciulella 'e cunferma.",
        "lockdbsuccesssub": "Blocco d' 'o database secutato",
        "lockdbsuccesstext": "'O database è stato bloccato.<br />\nArricuordateve 'e [[Special:UnlockDB|luvà 'o blocco]] appriesso c' 'a manutenziona sarrà fernuta.",
        "unlockdbsuccesstext": "'O database è stato sbluccato.",
        "lockfilenotwritable": "Nun se può scrivere ncopp' 'o file 'e blocco d' 'o database.\nPe' bluccà o sbluccà 'o database abbesuogne 'e scrivere dint' 'o server web.",
-       "databaselocked": "'O database è bluccato già.",
-       "databasenotlocked": "'O database nun è bluccato.",
+       "databaselocked": "'O database sta stutato già.",
+       "databasenotlocked": "'O database nun sta stutato.",
        "lockedbyandtime": "(pe' {{GENDER:$1|$1}} 'o $2 a 'e $3)",
        "move-page": "Mòve $1",
        "move-page-legend": "Mòve paggena",
        "tooltip-pt-login": "A reggistrazione è cunsigliata",
        "tooltip-pt-logout": "Jésce (logout)",
        "tooltip-pt-createaccount": "Pigliateve curaggio e criate n'utente e trasìte; eziamme ca chisto nun s'avesse 'a ffà pe' fforza",
-       "tooltip-ca-talk": "Vede e discussione rilative a chista paggena",
+       "tooltip-ca-talk": "Vide 'e chiacchere rilative a chesta paggena",
        "tooltip-ca-edit": "Cagna sta paggena",
        "tooltip-ca-addsection": "Cummincia 'na nova sezzione",
        "tooltip-ca-viewsource": "Chista paggena è prutetta, ma puo vere 'o codice sorgente",
-       "tooltip-ca-history": "Vversione precedente 'e chista paggena",
+       "tooltip-ca-history": "Vversione 'e primma 'e chesta paggena",
        "tooltip-ca-protect": "Prutegge chesta paggena",
        "tooltip-ca-unprotect": "Càgna 'a prutezzione 'e chesta paggena",
-       "tooltip-ca-delete": "Scancèlla chista paggena",
+       "tooltip-ca-delete": "Scancèlla chesta paggena",
        "tooltip-ca-undelete": "Arrepiglia 'e cagnamiente fatte 'a sta paggena apprimma ca fuieno scancellate",
        "tooltip-ca-move": "Mòve sta paggena",
        "tooltip-ca-watch": "Azzecca sta paggena int' 'a lista 'e paggene cuntrullate vuosta",
        "tooltip-t-upload": "Carreca file",
        "tooltip-t-specialpages": "Lista 'e tutte e paggene speciale",
        "tooltip-t-print": "Vversione pe stampà 'a chesta paggena",
-       "tooltip-t-permalink": "Jonta permanente a chista vversione dda paggena",
+       "tooltip-t-permalink": "Jonta permanente a chesta vversione dda paggena",
        "tooltip-ca-nstab-main": "Vere a paggena e contenuto",
        "tooltip-ca-nstab-user": "Vere a paggena utente",
        "tooltip-ca-nstab-media": "Vide 'a pàggena d' 'e media",
-       "tooltip-ca-nstab-special": "Chista è 'na paggena speciale e nun può essere càgnata",
+       "tooltip-ca-nstab-special": "Chesta è 'na paggena speciale e nun può essere càgnata",
        "tooltip-ca-nstab-project": "Vere a paggena 'e servizio",
        "tooltip-ca-nstab-image": "Vere a paggena ddo file",
        "tooltip-ca-nstab-mediawiki": "Vide 'a mmasciata d' 'o sistema",
        "tooltip-watchlistedit-raw-submit": "Agghiurna l'elenco 'e paggene cuntrullate",
        "tooltip-recreate": "Arricrèa 'e paggene pure si so state scancellate",
        "tooltip-upload": "Accummencia 'a carreca",
-       "tooltip-rollback": "\"A vascio\" annulla 'e cagnamiente a chesta paggena a ll'ultimo contributore cu nu click sulo",
-       "tooltip-undo": "\"Annulla\" annulla stu cagnamiento e arape 'u form 'e cagnamiento facenno vedé l'anteprimma.\nPermette azzeccà nu mutivo dint' 'o riepilego.",
+       "tooltip-rollback": "\"Sfàjere\" scancella 'e cagnamiente a ll'urdemo contributore 'e sta paggena cu nu click sulo",
+       "tooltip-undo": "\"Sfàjere\" scancella sto cagnamiento e arape 'o form facenno vedé l'anteprimma.\nPermette 'e azzeccà nu mutivo dint' 'o riepilego.",
        "tooltip-preferences-save": "Riggistra 'e preferenze",
        "tooltip-summary": "Miette nu riepilego piccerillo",
        "anonymous": "{{PLURAL:$1|utente|utente}} anonime 'e {{SITENAME}}",
        "markedaspatrollederrornotify": "Errore pe' tramente ca se nzegnava comme cuntrullata.",
        "patrol-log-page": "Riggistro 'e cuntrolle",
        "patrol-log-header": "Chest'è nu riggistro ch' 'e verziune cuntrullate.",
-       "log-show-hide-patrol": "$1 riggistro 'e cuntrolle",
-       "log-show-hide-tag": "$1 tag log",
        "deletedrevision": "Viecchia verziona scancellata $1",
        "filedeleteerror-short": "Errore pe' tramente ca se scancellava nu file: $1",
        "filedeleteerror-long": "N'errore s'è apprisentato pe' tramente ca se scancellava 'o file:\n\n$1",
        "months": "{{PLURAL:$1|$1 mese|$1 mese}}",
        "years": "{{PLURAL:$1|$1 anno|$1 anne}}",
        "ago": "$1 fà",
-       "just-now": "mò mò",
+       "just-now": "mo mmo",
        "hours-ago": "$1 {{PLURAL:$1|ora|ore}} fà",
        "minutes-ago": "$1 {{PLURAL:$1|minuto|minute}} fà",
        "seconds-ago": "$1 {{PLURAL:$1|secondo|seconde}} fà",
        "confirmemail": "Cunfermate 'o nderizzo mail",
        "confirmemail_noemail": "Nun tenite nu nderizzo e-mail bbuono pe' ve putè configurà ncopp' 'e [[Special:Preferences|preferenze vuoste]].",
        "confirmemail_text": "{{SITENAME}} bbuò ca vuje validasseve 'o nderizzo e-mail vuosto apprimm' 'e putè ausà 'e ffunziune 'e-mail.\nSpremmete 'o buttone 'e sotto pe' mannà na mmasciata e-mail 'e cunferma a l'indirizzo vuosto.\n'A mmasciata e-mail ca v'arreverrà tenesse nu cullegamento cu nu codece; carrecate 'o cullegamiento dint' 'a nu navigatóre web pe' ve putè cunfermà cu stu ndirizzo e nce ffà assapé 'o sito ch' 'è bbuono.",
-       "confirmemail_pending": "Nu codece 'e cunferma è stato gia mannato a l'email vuosto;\nSi mò mò nu cunto utente avite criato, allora putite aspettà cocche minuto ca chist'arriva, apprimm' 'e pruvà n'ata vota 'addimannà nu codece nuovo.",
+       "confirmemail_pending": "Nu codece 'e cunferma è stato mannato ggià a ll'email vuosto;\nSi avite criato 'a poco nu cunto utente, allòra putite aspettà quacche minuto ca chist'arriva, primm' 'e pruvà n'ata vota a 'ddimannà nu codece nuovo.",
        "confirmemail_send": "Manna nu codece 'e cunferma",
        "confirmemail_sent": "Mmasciata e-mail 'e cunferma mannata.",
        "confirmemail_oncreate": "'O codece 'e cunferma è stato mannato al'indirizzo e-mail d' 'o vuosto.\nStu codece nun è addimannato pe' ve putè fà trasì, ma vuje n'avite abbesuogno 'e l'avé apprimm' 'e putè ausà cocche funziune 'e chille ca facessero l'uso d' 'o cunto e-mail ncopp'a sta wiki.",
        "confirmemail_sendfailed": "{{SITENAME}} nun può mannà 'a mmasciata e-mail d' 'a vuosta 'e cunferma.\nPe' piacere cuntrullate si 'o nderizzo e-mail c'avite scritto tenesse cocche carattere nvalido.\n\nMmasciata d'errore a 'o mailer: $1",
        "confirmemail_invalid": "'O codece 'e cunferma nun è bbuono.\n'O codece fosse ammaturato.",
        "confirmemail_needlogin": "Abbesognate $1 pe cunfirmà 'o nnerizzo 'e e-mail d''o vuosto.",
-       "confirmemail_success": "'O ndirizzo e-mail d' 'o vuosto è stato cunfermato.\nVuje mò ne putite [[Special:UserLogin|trasì]] e ve putite spassà ncopp' 'a wiki.",
+       "confirmemail_success": "'O ndirizzo e-mail d' 'o vuosto è stato cunfermato.\nMo putite [[Special:UserLogin|trasì]] e ve putite spassà ncopp' 'a wiki.",
        "confirmemail_loggedin": "'O nnerizzo 'e e-mail è vàleto",
        "confirmemail_subject": "Indirizzo e-mail 'e cunferma pe' {{SITENAME}}",
        "confirmemail_body": "Coccheruno, può darse ca site vuje, 'a l'indirizzo IP $1,\nha riggistrato nu cunto utente \"$2\" cu st'indirizzo e-mail ncopp'a {{SITENAME}}.\n\nPe' putè cunfermà ca stu cunto è stato overo criato e vuje e ve putè apiccià 'a funziona e-mail 'e {{SITENAME}}, arapite stu cullegamento dint' 'o navigatóre web d' 'o vuosto:\n\n$3\n\nSi vuje *NUN* avite riggistrato 'o cunto utente, secutate stu cullegamento pe' ve scancellà st'indirizzo e-mail utente:\n\n$5\n\nStu codece 'e cunferma murarrà 'o $4.",
        "invalidateemail": "Scancella 'a cunferma 'e l'e-mail",
        "notificationemail_subject_changed": "L'indirizzo email riggistrato ncopp'a {{SITENAME}} è stato cagnato",
        "notificationemail_subject_removed": "L'indirizzo email riggistrato dint'a {{SITENAME}} è stato luvato",
-       "notificationemail_body_changed": "Coccheruno, probbabilmente vuje, 'a ll'indirizzo IP $1,\nave cagnato l'indirizze e-mail d' 'o cunto \"$2\" a \"$3\" ncopp'a {{SITENAME}}.\n\nSi nun eravate vuje, pe' piacere tuzzuliate mò mò n'ammenistratore.",
-       "notificationemail_body_removed": "Coccheruno, probbabilmente vuje, 'a ll'indirizzo IP $1,\nave luvato l'indirizze e-mail d' 'o cunto \"$2\" ncopp'a {{SITENAME}}.\n\nSi nun eravate vuje, pe' piacere tuzzuliate mò mò n'ammenistratore.",
+       "notificationemail_body_changed": "Coccheruno, probbabilmente vuje, a ll'indirizzo IP $1,\nave cagnato 'o ndirizzo e-mail d' 'o cunto \"$2\" a \"$3\" ncopp'a {{SITENAME}}.\n\nSi nun eravate vuje, pe piacere tuzzuliate a n'ammenistratore primma 'e mo.",
+       "notificationemail_body_removed": "Coccheruno, probbabilmente vuje, 'a ll'indirizzo IP $1,\nave luvato l'indirizze e-mail d' 'o cunto \"$2\" ncopp'a {{SITENAME}}.\n\nSi nun eravate vuje, pe piacere tuzzuliate a n'ammenistratore.",
        "scarytranscludedisabled": "['A funziona cullegamiento nfra site wiki è stata stutata]",
        "scarytranscludefailed": "[L'analisi d' 'o template s'è scassato pe' $1]",
        "scarytranscludefailed-httpstatus": "[L'analisi d' 'o template s'è scassato pe' $1: HTTP $2]",
        "timezone-local": "Lucale",
        "duplicate-defaultsort": "<strong>Attenziò:</strong> A chiave d'arricetto \"$2\" se miette ncuollo a nu valore 'e primma \"$1\".",
        "duplicate-displaytitle": "<strong>Attenziò:</strong> A chiave d'arricetto \"$2\" se scagna p' 'o valore 'e primma \"$1\".",
-       "restricted-displaytitle": "<strong>Attenziò:</strong> 'O titolo ccà \"$1\" è stato lassato perdere pecché nun fosse eguale a 'o titolo 'e mò d' 'a paggena.",
+       "restricted-displaytitle": "<strong>Attenziò:</strong> 'O titolo ccà \"$1\" è stato lassato perdere pecché nun fosse eguale a 'o titolo 'e mo d' 'a paggena.",
        "invalid-indicator-name": "<strong>Errore:</strong> attribbuto <code>name</code> 'e ll'innecature d' 'o stato d' 'a paggena nu può rummanè abbacante.",
        "version": "Verziona",
        "version-extensions": "Estenziune installate",
        "version-poweredby-credits": "Sta wiki funziona pe' bbìa 'e <strong>[https://www.mediawiki.org/ MediaWiki]</strong>, copyright © 2001-$1 $2.",
        "version-poweredby-others": "ati",
        "version-poweredby-translators": "tradutture 'e translatewiki.net",
-       "version-credits-summary": "Nuje vulessemo tené a mmente 'e perzune ccà abbascio pe' purtà rispetto a 'e cuntribbute 'e lloro ncopp'a [[Special:Version|MediaWiki]].",
+       "version-credits-summary": "Nuje vulessemo tené a mmente 'e perzune ccà abbascio pe purtà rispetto a 'e cuntribbute 'e lloro ncopp'a [[Special:Version|MediaWiki]].",
        "version-license-info": "MediaWiki è nu software libbero; vuje 'o putite redestribbuì e/o cagnà sott' 'e termine d' 'a licienza GNU GPL ('a Licienza Pubbreca Generale) comme pubbrecata d' 'a Free Software Foundation; o pure 'a verziona 2 d' 'a Licienza, o pure (comme vulite vuje) 'a n'ata verziona cchiù nnova.\n\nMediaWiki è destribbuita c' 'a speranza d'essere utile, ma SENZA NISCIUNA GARANZIA; senza manco 'a garanzia p' 'a CUMMERCIABBELETÀ O IDONIETÀ PE' NU SCOPO PARTICULARE. Iate a vedé 'a GNU GPL pe' n'avé cchiù nfurmaziune.\n\nAvísseve 'a ricevere [{{SERVER}}{{SCRIPTPATH}}/COPYING na copia d' 'a Licienza GNU GPL] cu stu prugramma; si nò, scrivete â Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA o [//www.gnu.org/licenses/old-licenses/gpl-2.0.html liggite sta paggena ncopp' 'a l'Internet].",
        "version-software": "Software installato",
        "version-software-product": "Prodotto",
        "specialpages-group-maintenance": "Report 'e manutenzione",
        "specialpages-group-other": "Ati paggene speciale",
        "specialpages-group-login": "Trasite o criate n'acciesso nuovo",
-       "specialpages-group-changes": "Cagnamiente 'e mò mò e riggistre",
+       "specialpages-group-changes": "Urdeme cagnamiénte e riggistre",
        "specialpages-group-media": "Riepileghe 'e media e carreche",
        "specialpages-group-users": "Utente e deritte",
        "specialpages-group-highuse": "Pàggene ausate assaje proprio",
-       "specialpages-group-pages": "Lista d' 'e paggene",
+       "specialpages-group-pages": "Lista d' 'e ppaggene",
        "specialpages-group-pagetools": "Strumiente p' 'e paggene",
        "specialpages-group-wiki": "Data e strumiente",
        "specialpages-group-redirects": "Redirezionamiente d' 'e paggene speciale",
        "tags-deactivate": "stuta",
        "tags-hitcount": "$1 {{PLURAL:$1|cagnamiento|cagnamiente}}",
        "tags-manage-no-permission": "Nun tenite 'o permesso pe' cagnà 'e tag.",
-       "tags-manage-blocked": "Nun putite cagnà sti tag quanno site bluccato/a.",
+       "tags-manage-blocked": "Nun putite cagnà sti tag quanno state {{GENDER:$1|fremmato|freammata}}.",
        "tags-create-heading": "Crìa nu tag nuovo",
        "tags-create-explanation": "Comme predefinito, 'e tag criate nuove nuove se farranno disponibbele pe ll'ausà ll'utente e re bot",
        "tags-create-tag-name": "Nomme 'e ll'etichetta ('o tag):",
        "tags-create-warnings-below": "Vulite cuntinuà a crià 'o tag?",
        "tags-delete-title": "Scancella tag",
        "tags-delete-explanation-initial": "State pe' scancellà 'o tag \"$1\" d' 'o database.",
-       "tags-delete-explanation-in-use": "Sarrà luvato d' 'o {{PLURAL:$2|$2 verziona o d' 'o riggistro|tutt' 'e verziune $2 e/o 'e nutarelle int' 'o riggistro}} ô quale fosse azzeccato mò mò.",
+       "tags-delete-explanation-in-use": "Sarrà luvato d' 'o {{PLURAL:$2|$2 verziona o d' 'o riggistro|tutt' 'e verziune $2 e/o 'e nutarelle int' 'o riggistro}} addò stesse azzeccato.",
        "tags-delete-explanation-warning": "St'aziona è <strong>irreversibbele</strong> e <strong>nun se pò turnà arreto</strong>, pure 'a ll'ammenistrature d' 'o database. Faciteve capace ca stu tag è chillu ca vulite scancellà.",
        "tags-delete-explanation-active": "<strong>'O tag \"$1\" è ancora attivo, e sarrà apprecato int' 'o futuro.</strong> Pe' fernì cu st'attività, jate, a lloco addò 'o tag s'è apprecato, e stutate llànno.",
        "tags-delete-reason": "Mutivo:",
        "tags-apply-not-allowed-one": "'O tag \"$1\" nun è premmesso a se ffà manualmente apprecà.",
        "tags-apply-not-allowed-multi": "{{PLURAL:$2|'O tag ccà abbascio nun è|'E tag ccà abbascio nun songo}} premmesse 'e s'apprecà manualmente: $1",
        "tags-update-no-permission": "Nun tenite premmesse pe' putè azzeccà o luvà tag 'e cagnamiento 'a 'e verziune nnividuale o entrate 'o log.",
-       "tags-update-blocked": "Nun putite azzeccà o luvà tag quanno site bluccato/a.",
+       "tags-update-blocked": "Nun putite azzeccà o luvà tag quanno state {{GENDER:$1|bluccato|bluccata}}.",
        "tags-update-add-not-allowed-one": "'O tag \"$1\" nun è premmesso 'e s'azzeccà 'n manuale.",
        "tags-update-add-not-allowed-multi": "{{PLURAL:$2|'O tag ccà abbascio nun è|'E tag ccà abbascio nu so'}} premmesse 'e s'azzeccà manualmente: $1",
        "tags-update-remove-not-allowed-one": "'O tag \"$1\" nun è permesso d' 'o luvà.",
        "dberr-info": "(Nun se può trasì 'o database: $1)",
        "dberr-info-hidden": "(Nun se può trasì 'o database)",
        "dberr-usegoogle": "Pe' tramente putite pruvà 'ascianno ncoppa Google.",
-       "dberr-outofdate": "Vedite ca l'indice lloro d' 'e cuntenute nuoste ponno nun essere agghiurnate mò mò.",
+       "dberr-outofdate": "Vedite ca ll'indice lloro d'ê cuntenute nuoste ponno essere passate.",
        "dberr-cachederror": "Chest'è na copia \"cache\" d' 'a paggena c'avite asciato, e putesse nun essere agghiurnata.",
        "htmlform-invalid-input": "Ce sta cocche probblema cu l'input c'avite miso.",
        "htmlform-select-badoption": "'O valore c'avite specificato nun è n'opziona bbuona.",
        "htmlform-int-toohigh": "'O valore c'avite specificato sta pe' copp' 'o massimo 'e $1.",
        "htmlform-required": "Stu valore ce vuò.",
        "htmlform-submit": "Manna",
-       "htmlform-reset": "Annulla 'e cagnamiente",
+       "htmlform-reset": "Sfàje 'e cagnamiente",
        "htmlform-selectorother-other": "Ato",
        "htmlform-no": "No",
        "htmlform-yes": "Sì",
        "logentry-delete-delete": "$1 {{GENDER:$2|scancellaje}} 'a paggena $3",
        "logentry-delete-restore": "$1 {{GENDER:$2|arrepigliaje}} 'a paggena $3 ($4)",
        "logentry-delete-event": "$1 {{GENDER:$2|cagnaie}} 'a vesibbiletà 'e {{PLURAL:$5|n'azione d' 'o riggistro|$5 aziune d' 'o riggistro}} ncopp' 'a 'a $3: $4",
-       "logentry-delete-revision": "$1 {{GENDER:$2|cagnaie}} 'a vesibbiletà 'e {{PLURAL:$5|na verziona|$5 verziune}} ncopp' 'a 'a $3: $4",
-       "logentry-delete-event-legacy": "$1 {{GENDER:$2|cagnaie}} 'a vesibbiletà 'e l'aziune dint' 'o riggistro ncopp' 'a $3: $4",
-       "logentry-delete-revision-legacy": "$1 {{GENDER:$2|cagnaie}} 'a vesibbiletà d' 'e verziune ncopp' 'a $3",
+       "logentry-delete-revision": "$1 {{GENDER:$2|cagnaie}} 'a vesibbiletà 'e {{PLURAL:$5|na verziona|$5 verziune}} ncopp'a $3: $4",
+       "logentry-delete-event-legacy": "$1 {{GENDER:$2|cagnaie}} 'a vesibbiletà 'e l'aziune int' 'o riggistro ncopp'a $3: $4",
+       "logentry-delete-revision-legacy": "$1 {{GENDER:$2|cagnaie}} 'a vesibbiletà d'ê verziune ncopp'a $3",
        "logentry-suppress-delete": "$1 {{GENDER:$2|luvaje pe' sempe}} 'a paggena $3",
        "logentry-suppress-event": "$1 {{GENDER:$2|annascunnuto cagnaie|annascunnuta cagnaie}} 'a vesibbiletà 'e {{PLURAL:$5|n'azione d' 'o riggistro|$5 aziune d' 'o riggistro}} ncopp' 'a 'a $3: $4",
        "logentry-suppress-revision": "$1 {{GENDER:$2|annascunnuto cagnaie|annascunnuta cagnaie}} 'a vesibbiletà 'e {{PLURAL:$5|na verziona|$5 verziune}} ncopp' 'a 'a $3: $4",
-       "logentry-suppress-event-legacy": "$1 {{GENDER:$2|annascunnuto cagnaie|annascunnuta cagnaie}} 'a vesibbiletà 'e l'aziune 'e riggistro ncopp' 'a $3",
-       "logentry-suppress-revision-legacy": "$1 {{GENDER:$2|annascunnuto cagnaie|annascunnuta cagnaie}} 'a vesibbiletà d' 'e verziune ncopp' 'a $3",
+       "logentry-suppress-event-legacy": "$1 cagnaie {{GENDER:$2|annascunnuto|annascunnuta}} 'a vesibbiletà 'e l'aziune 'e riggistro ncopp' 'a $3",
+       "logentry-suppress-revision-legacy": "$1 cagnaie {{GENDER:$2|annascunnuto|annascunnuta}} 'a vesibbiletà d' 'e verziune ncopp'a $3",
        "revdelete-content-hid": "cuntenute annascunnute",
        "revdelete-summary-hid": "riepilego 'e cagnamiente annascunnute",
        "revdelete-uname-hid": "nomme utente annascunnuto",
        "revdelete-uname-unhid": "nomme utente fatto avvedè",
        "revdelete-restricted": "restriziune apprecate a ll'ammenistrature",
        "revdelete-unrestricted": "restriziune luvate a ll'ammenistrature",
-       "logentry-block-block": "$1 {{GENDER:$2|ave bluccato}} {{GENDER:$4|$3}} cu na scadenza 'e $5 $6",
+       "logentry-block-block": "$1 {{GENDER:$2|ave fremmato}} {{GENDER:$4|$3}} cu na scadenza 'e $5 $6",
        "logentry-block-unblock": "$1 {{GENDER:$2|ave sbluccato}} {{GENDER:$4|$3}}",
        "logentry-block-reblock": "$1 {{GENDER:$2|ave cagnato}} 'e mpustaziune 'e blocco pe' {{GENDER:$4|$3}} cu na scadenza 'e $5 $6",
-       "logentry-suppress-block": "$1 {{GENDER:$2|ave bluccato}} {{GENDER:$4|$3}} cu na scadenza 'e $5 $6",
+       "logentry-suppress-block": "$1 {{GENDER:$2|ave fremmato}} {{GENDER:$4|$3}} cu na scadenza 'e $5 $6",
        "logentry-suppress-reblock": "$1 {{GENDER:$2|cagnaje}} 'e mpustaziune 'e blocco 'e {{GENDER:$4|$3}} ch' 'ammaturasse a nu $5 $6",
        "logentry-import-upload": "$1 {{GENDER:$2|ave mpurtato}} $3 pe' bbìa d' 'a carreca",
        "logentry-import-upload-details": "$1 {{GENDER:$2|mpurtaje}} $3 pe' carreca 'e file ($4 {{PLURAL:$4|verziona|verziune}})",
        "feedback-bugcheck": "Tutt'appost! Avite surtanto 'a cuntrullà ca chisto nun è unu d' 'e [$1 bug canusciute].",
        "feedback-bugnew": "Aggio cuntrullato. Manna nu bug nuovo.",
        "feedback-bugornote": "Si site pronto/a a descrivere nu probblema tecnico ch' 'e dettaglie, pe' piacere [$1 mannate nu bug].\nSi nun site pronto/a, allora putite ausà 'o modulo semprice ca vedite ccà abbascio. 'O commento vuosto sarrà mpezzato dint' 'a paggena [$3 $2]\", seguenno 'o nomme utente vuosto e 'o navigatóre web ca state ausanno.",
-       "feedback-cancel": "Canciella",
+       "feedback-cancel": "Scancella",
        "feedback-close": "Fatto",
        "feedback-external-bug-report-button": "Archivia na fatica tecnica",
        "feedback-dialog-title": "Manna 'o feedback",
        "log-name-pagelang": "Cagna 'o riggistro d' 'a lengua",
        "log-description-pagelang": "Chest'è nu riggistro 'e cagnamiente 'e lengua d' 'e paggene.",
        "logentry-pagelang-pagelang": "$1 {{GENDER:$2|ave cagnato}} 'a lengua d' 'a paggena $3 'a $4 a $5.",
-       "default-skin-not-found": "Oops! 'A skin predefinta ' 'o wiki vuosto, definita 'n <code dir=\"ltr\">$wgDefaultSkin</code> comme <code>$1</code>, nun se tròva.\n\n'A installazione pare ca tenesse {{PLURAL:$4|'a skin|'e skin}} ccà abbascio. Vedite [https://www.mediawiki.org/wiki/Manual:Skin_configuration Manuale: configurazione skin] pe' n'avè cchiù nfurmaziune ncopp' 'a manera {{PLURAL:$4|'e ll'abbià}} o scegliere chilla predefinita.\n\n$2\n\n; Si avite installato MediaWiki mò mò:\n: Probabbilmente l'avite installato 'a git, o direttamente 'a 'o codece sorgente ausanno cocch'atu metodo. Chesto era permesso. Verite 'e installà cocche skin 'a [https://www.mediawiki.org/wiki/Category:All_skins directory ncoppa mediawiki.org], tramite:\n:* Scarrecanno 'o [https://www.mediawiki.org/wiki/Download programma 'e installazione tarball], ca venesse fornito ch' 'e diverze skin ed estenziune. Putite fare copia-azzecca d' 'a directory <code dir=\"ltr\">skins/</code>.\n:* Scarrecanne 'e tarballs individuale 'e skin 'a [https://www.mediawiki.org/wiki/Special:SkinDistributor mediawiki.org].\n:* [https://www.mediawiki.org/wiki/Download_from_Git#Using_Git_to_download_MediaWiki_skins Ausanno Git pe' scarrecà skin].\n: Facenno accussì nun se mmescasse 'o repository git vuosto si site sviluppatore MediaWiki.\n\n; Si avite MediaWiki agghiurnato MediaWiki mò mò:\n: MediaWiki 1.24 e verziune appriesso nun abbìa automatecamente 'e skin installate (vedite [https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery Manuale: rilevamento automateco skin]). Putite copià {{PLURAL:$5|'a linea|'e linee}} ccà abbascio dint' 'o <code>LocalSettings.php</code> pe' putè appiccià {{PLURAL:$5|'o|tutt' 'e}} {{PLURAL:$5|skin}} installate mò mò:\n\n<pre dir=\"ltr\">$3</pre>\n\n; Si avite cagnato mò mò <code>LocalSettings.php</code>:\n: Cuntrullate 'e nomme d' 'e skin n'ata vota pe' ve sparagnà cocch'errore 'e battitura.",
+       "default-skin-not-found": "Mannàggia! 'A skin predefinta ' 'o wiki vuosto, definita 'n <code dir=\"ltr\">$wgDefaultSkin</code> comme <code>$1</code>, nun se tròva.\n\n'A installazione pare ca tenesse {{PLURAL:$4|'a skin|'e skin}} ccà abbascio. Vedite [https://www.mediawiki.org/wiki/Manual:Skin_configuration Manuale: configurazione skin] pe n'avè cchiù nfurmaziune ncopp' 'a manera {{PLURAL:$4|'e ll'abbià}} o seleziunà chella predefinita.\n\n$2\n\n; Si avite installato MediaWiki mo mo:\n: Probabbilmente l'avite installato 'a git, o direttamente ro codece sorgente ausanno quacch'atu metodo. Ne putiva fà. Verite 'e installà quacche skin 'a [https://www.mediawiki.org/wiki/Category:All_skins directory ncoppa mediawiki.org], tramite:\n:* Scarrecanno 'o [https://www.mediawiki.org/wiki/Download programma 'e installazione tarball], ca venesse dato cu 'e diverze skin e estenziune. Putite fà copia-azzecca d' 'a directory <code dir=\"ltr\">skins/</code>.\n:* Scarrecanne 'e tarballs individuale 'e skin 'a [https://www.mediawiki.org/wiki/Special:SkinDistributor mediawiki.org].\n:* [https://www.mediawiki.org/wiki/Download_from_Git#Using_Git_to_download_MediaWiki_skins Ausanno Git pe' scarrecà skin].\n: Facenno accussì nun se mmescasse 'o repository git vuosto si site sviluppatore MediaWiki.\n\n; Si avite MediaWiki agghiurnato MediaWiki mò mò:\n: MediaWiki 1.24 e verziune appriesso nun abbìa automatecamente 'e skin installate (vedite [https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery Manuale: rilevamento automateco skin]). Putite copià {{PLURAL:$5|'a linea|'e linee}} ccà abbascio dint' 'o <code>LocalSettings.php</code> pe' putè appiccià {{PLURAL:$5|'o|tutt' 'e}} {{PLURAL:$5|skin}} installate mo mmo:\n\n<pre dir=\"ltr\">$3</pre>\n\n; Si avite cagnato mo mo <code>LocalSettings.php</code>:\n: Cuntrullate 'e nomme d' 'e skin n'ata vota pe' ve sparagnà ciert'errure 'e battitura.",
        "default-skin-not-found-no-skins": "oops! 'O skin predefinito p' 'a wiki vuosta, definito int'a <code>$wgDefaultSkin</code> comm'a <code>$1</code>, nun è a disposizione.\n\nVuje nun tenite nisciuno skin installato.\n\n; Si avite installato o agghiurnato MediaWiki mo' mo':\n: È possibbele ca l'avite installato 'a git, o direttamente d' 'o codece sorgente ausanno n'atu metodo. Chesto s'aspettava. Mediawiki 1.24 o cchiù nuova nun include nisciuno skin dint' 'o repositorio prencepale. Tentate 'e installà cocche skin 'a [https://www.mediawiki.org/wiki/Category:All_skins sta cartella 'e mediawiki.org], facenno:\n:* Scarreca 'e [https://www.mediawiki.org/wiki/Download tarball installer], ca venesse cu nu cuofeno 'e skin e estensiune. Vuje putite cupià e azzeccà 'a cartella <code>skins/</code> 'a chiste.\n:* Scarrecanno tarball 'e skin individuale 'a [https://www.mediawiki.org/wiki/Special:SkinDistributor mediawiki.org].\n:* [https://www.mediawiki.org/wiki/Download_from_Git#Using_Git_to_download_MediaWiki_skins Ausanno Git pe' puté scarrecà skin].\n: A ffà chesto nun avesse nteferì c' 'o repositorio d' 'o git vuosto, si vuje site sviluppatore MediaWiki. Vedite [https://www.mediawiki.org/wiki/Manual:Skin_configuration Manuale: Mpustaziona skin] pe' n'avé nfurmaziune ncopp'a comme s'avesser'appiccià skin e scegliere 'o valore predefinito.",
        "default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (funzione appicciata)",
        "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 (<strong>funzione stutata</strong>)",
        "authmanager-authplugin-setpass-denied": "'O plugin autenticazione nun premmettesse 'e cagnà 'e password.",
        "authmanager-authplugin-setpass-bad-domain": "Dominio invalido.",
        "authmanager-autocreate-noperm": "'A criazione automatica 'e ll'utenza nun fosse premmessa.",
-       "authmanager-autocreate-exception": "Criazione 'e cunte automatica mò mò è stutata pe' bbìa 'e ll'errure precedenti.",
+       "authmanager-autocreate-exception": "Criazione 'e cunte automatica stutata pe nu poc'ê tiempo pe vvìa 'e ll'errure precedenti.",
        "authmanager-userdoesnotexist": "'O cunto utente \"$1\" nun è riggistrato.",
        "authmanager-userlogin-remembermypassword-help": "Si 'a pasword adda essere arricurdata cchiù a luongo cu rispett'a tutt' 'a durata d' 'a sessione.",
        "authmanager-username-help": "Nomme utente pe' ll'autenticaziona.",
        "authmanager-provider-password": "Autenticaziona basata ncopp' 'a password",
        "authmanager-provider-password-domain": "Autenticaziona cu' password e basata ncopp'a nu dominio",
        "authmanager-provider-temporarypassword": "Password a tiempo determinato",
-       "authprovider-confirmlink-message": "Verenno 'e tentative d'acciesso mò, l'utente ccà putessero avé nu cullegamento c' 'o cunto wiki d' 'o vuosto. A ffà cullegamento premmettesse appiccià 'o sistema 'e trasuta pe' bbìa 'e sti cunte. Pe' piacere sciglite 'e cunte addò vulite fà cullegamento.",
+       "authprovider-confirmlink-message": "Verenno 'e tentative d'acciesso, chisti cunte ccà putessero avé nu cullegamento c' 'o cunto wiki d' 'o vuosto. Jontanneli premmettesse appiccià 'o sistema 'e trasuta cu sti cunte. Pe piacere sciglite 'e cunte ca vulite jontà.",
        "authprovider-confirmlink-request-label": "Cunte ca s'avesser'a cullegà",
        "authprovider-confirmlink-success-line": "$1: cullegato e apposto.",
        "authprovider-confirmlink-failed": "'O cullegamento 'e ll'utenza nun è ngarrato sano sano: $1",
index b847a1d..bc7c9dd 100644 (file)
@@ -51,7 +51,8 @@
                        "Nemo bis",
                        "Telaneo",
                        "Jon Harald Søby",
-                       "Fitoschido"
+                       "Fitoschido",
+                       "Orf3us"
                ]
        },
        "tog-underline": "Strek under lenker:",
        "customcssprotected": "Du har ikke tillatelse til å redigere denne CSS-siden fordi den inneholder en annen brukers personlige innstillinger.",
        "customjsonprotected": "Du har ikke tillatelse til å redigere denne JSON-siden fordi den inneholder en annen bruker sine personlige innstillinger.",
        "customjsprotected": "Du har ikke tillatelse til å redigere denne JavaScript-siden fordi den inneholder en annen brukers personlige innstillinger.",
+       "sitecssprotected": "Du har ikke tillatelse til å redigere denne CSS-siden fordi det kan påvirke alle besøkende",
+       "sitejsonprotected": "Du har ikke tillatelse til å redigere denne JSON-siden fordi det kan påvirke alle besøkende",
+       "sitejsprotected": "Du har ikke tillatelse til å redigere denne JavaScript-siden fordi det kan påvirke alle besøkende",
        "mycustomcssprotected": "Du har ikke rettigheter til å redigere denne CSS-siden.",
        "mycustomjsonprotected": "Du har ikke tillatelse til å redigere denne JSON-siden.",
        "mycustomjsprotected": "Du har ikke rettigheter til å redigere denne Javascript-siden.",
        "botpasswords-existing": "Eksisterende robotpassord",
        "botpasswords-createnew": "Opprett et nytt robotpassord",
        "botpasswords-editexisting": "Redigere et eksisterende robotpassord",
+       "botpasswords-label-needsreset": "(passordet må settes på nytt)",
        "botpasswords-label-appid": "Robotnavn:",
        "botpasswords-label-create": "Opprett",
        "botpasswords-label-update": "Oppdater",
        "botpasswords-restriction-failed": "Begrensninger for robotpassord tillater ikke denne innloggingen.",
        "botpasswords-invalid-name": "Det angitte brukernavnet inneholder ikke separasjonstegnet for robotpassord (\"$1\").",
        "botpasswords-not-exist": "Brukeren \"$1\" har ikke noe robotpassord for \"$2\".",
+       "botpasswords-needs-reset": "Botpassordet for botnavnet «$2» for {{GENDER:$1|brukeren}} «$1» må settes på nytt.",
        "resetpass_forbidden": "Passord kan ikke endres",
        "resetpass_forbidden-reason": "Passordene kan ikke endres: $1",
        "resetpass-no-info": "Du må være logget inn for å gå til denne siden direkte",
        "resetpass-submit-loggedin": "Endre passord",
        "resetpass-submit-cancel": "Avbryt",
        "resetpass-wrong-oldpass": "Ugyldig midlertidig eller aktivt passord.\nDet kan tenkes at allerede har gjennomført et vellykket bytte av passord, eller bedt om et nytt midlertidig passord.",
-       "resetpass-recycled": "Vær vennlig å endre passordet til noe annen enn gjeldende passord.",
+       "resetpass-recycled": "Endre passordet ditt til noe annet enn det nåværende passordet.",
        "resetpass-temp-emailed": "Du logget inn med en midlertidig kode sendt på e-post.\nFor å avslutte innloggingen må du angi et nytt passord her:",
        "resetpass-temp-password": "Midlertidig passord:",
        "resetpass-abort-generic": "Endring av passord har blitt avbrutt av en utvidelse.",
        "resetpass-expired": "Passordet ditt har utløpt. Vær vennlig å angi et nytt passord for å logge inn.",
        "resetpass-expired-soft": "Passordet ditt har utløpt og må endres. Vær vennlig å angi et nytt passord, eller klikk \"{{int:authprovider-resetpass-skip-label}}\" for å endre det senere.",
-       "resetpass-validity-soft": "Ditt passord er ikke gyldig: $1",
+       "resetpass-validity-soft": "Passordet ditt er ikke gyldig: $1\n\nVelg et nytt passord nå, eller klikk på «{{int:authprovider-resetpass-skip-label}}» for å endre det seinere.",
        "passwordreset": "Tilbakestilling av passord",
        "passwordreset-text-one": "Fyll ut skjemaet for å tilbakestille passordet",
        "passwordreset-text-many": "{{PLURAL:$1|Fyll inn ett av datafeltene for å tilbakestille passordet ditt via epost.}}",
        "subject-preview": "Forhåndsvisning av overskrift:",
        "previewerrortext": "En feil oppsto mens dine endringer skulle forhåndsvises.",
        "blockedtitle": "Brukeren er blokkert",
-       "blockedtext": "'''Ditt brukernavn eller din IP-adresse har blitt blokkert.'''\n\nBlokkeringen ble utført av $1. Grunnen som ble oppgitt var ''$2''.\n\n* Blokkeringen begynte: $8\n* Blokkeringen utgår: $6\n* Blokkering ment på: $7\n\nDu kan kontakte $1 eller en annen [[{{MediaWiki:Grouppage-sysop}}|administrator]] for å diskutere blokkeringen.\nDu kan ikke bruke «E-post til denne brukeren»-funksjonen med mindre du har oppgitt en gyldig e-postadresse i [[Special:Preferences|innstillingene dine]] og du ikke er blokkert fra å sende e-post.\nDin nåværende IP-adresse er $3, og blokkerings-ID-en er #$5.\nVennligst ta all denne informasjonen ved henvendelser.",
-       "autoblockedtext": "Din IP-adresse har blitt automatisk blokkert fordi den ble brukt av en annen bruker som ble blokkert av $1.\nDen oppgitte grunnen var:\n\n:'''$2'''\n\n* Blokkeringen begynte: $8\n* Blokkeringen utgår: $6\n* Blokkeringen er ment for: $7\n\nDu kan kontakte $1 eller en av de andre [[{{MediaWiki:Grouppage-sysop}}|administratorene]] for å diskutere blokkeringen.\n\nMerk at du ikke kan bruke «E-post til denne brukeren»-funksjonen med mindre du har registrert en gyldig e-postadresse i [[Special:Preferences|innstillingene dine]].\n\nDin IP-adresse er $3, og blokkerings-ID-en er #$5.\nVennligst ta med all denne informasjonen ved henvendelser.",
+       "blockedtext": "<strong>Ditt brukernavn eller din IP-adresse har blitt blokkert.</strong>\n\nBlokkeringen ble utført av $1. Grunnen som ble oppgitt var <em>$2</em>.\n\n* Blokkeringen begynte:  $8\n* Blokkeringen opphører: $6\n* Blokkeringen ment for: $7\n\nDu kan kontakte $1 eller en annen [[{{MediaWiki:Grouppage-sysop}}|administrator]] for å diskutere blokkeringen.\nDu kan ikke bruke «{{int:emailuser}}»-funksjonen med mindre du har oppgitt en gyldig e-postadresse i [[Special:Preferences|innstillingene dine]] og du ikke har blitt blokkert fra å sende e-post.\nDin nåværende IP-adresse er $3, og blokkerings-ID-en er #$5.\nVennligst ta med all denne informasjonen ved henvendelser.",
+       "autoblockedtext": "Din IP-adresse har blitt automatisk blokkert fordi den ble brukt av en annen bruker som ble blokkert av $1.\nDen oppgitte grunnen var:\n\n:'''$2'''\n\n* Blokkeringen begynte: $8\n* Blokkeringen utgår: $6\n* Blokkeringen er ment for: $7\n\nDu kan kontakte $1 eller en av de andre [[{{MediaWiki:Grouppage-sysop}}|administratorene]] for å diskutere blokkeringen.\n\nMerk at du ikke kan bruke «{{int:emailuser}}»-funksjonen med mindre du har registrert en gyldig e-postadresse i [[Special:Preferences|innstillingene dine]].\n\nDin IP-adresse er $3, og blokkerings-ID-en er #$5.\nVennligst ta med all denne informasjonen ved henvendelser.",
        "systemblockedtext": "Ditt brukernavn eller IP-adresse har blitt blokkert automatisk av MediaWiki.\n\nBlokkeringen grunnes:\n\n:<em>$2</em>\n\n* Blokkeringen startet: $8\n* Blokkeringen gjelder til: $6\n* Blokkeringen er ment for: $7\n\nDin nåværende IP-adresse er $3.\nVennligst inkluder informasjonen over i alle spørsmål du spør angående dette.",
        "blockednoreason": "ingen grunn gitt",
        "whitelistedittext": "Du må $1 for å redigere artikler.",
        "converter-manual-rule-error": "En feil ble oppdaget i en manuell språkkonverteringsregel",
        "undo-success": "Redigeringen kan omgjøres. Sjekk sammenligningen under for å bekrefte at du vil gjøre dette, og lagre endringene for å fullføre omgjøringen.",
        "undo-failure": "Redigeringen kunne ikke omgjøres på grunn av konflikterende etterfølgende redigeringer.",
+       "undo-main-slot-only": "Redigeringen kunne ikke omgjøres fordi den involverer innhold utenfor hovedspalten.",
        "undo-norev": "Redigeringen kunne ikke fjernes fordi den ikke eksisterer eller ble slettet",
        "undo-nochange": "Det ser ut til at redigeringen allerede er tilbakestilt.",
        "undo-summary": "Fjerner revisjon $1 av [[Special:Contributions/$2|$2]] ([[User talk:$2|diskusjon]])",
        "diff-paragraph-moved-toold": "Avsnittet ble flyttet. Klikk for å hoppe til den gamle plasseringen.",
        "difference-missing-revision": "{{PLURAL:$2|En revisjon|$2 revisjoner}} av denne forskjellen ($1) {{PLURAL:$2|ble|ble}} ikke funnet.\n\nDette skyldes som regel at en gammel forskjell-lenke er fulgt til en side som er slettet.\nDetaljer kan finnes i [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} sletteloggen].",
        "searchresults": "Søkeresultater",
+       "search-filter-title-prefix": "Søker bare i sider der tittelen begynner med «$1»",
+       "search-filter-title-prefix-reset": "Søk i alle sider",
        "searchresults-title": "Søkeresultater for «$1»",
        "titlematches": "Artikkeltitler med treff på forespørselen",
        "textmatches": "Artikkeltekster med treff på forespørselen",
        "group-autoconfirmed": "Autobekreftede brukere",
        "group-bot": "Roboter",
        "group-sysop": "Administratorer",
+       "group-interface-admin": "Grensesnittadministratorer",
        "group-bureaucrat": "Byråkrater",
        "group-suppress": "Sidefjernere",
        "group-all": "(alle)",
        "group-autoconfirmed-member": "{{GENDER:$1|autobekreftet bruker}}",
        "group-bot-member": "{{GENDER:$1|bot}}",
        "group-sysop-member": "{{GENDER:$1|administrator}}",
+       "group-interface-admin-member": "{{GENDER:$1|grensesnittadministrator}}",
        "group-bureaucrat-member": "{{GENDER:$1|byråkrat}}",
        "group-suppress-member": "{{GENDER:$1|historikkrydder}}",
        "grouppage-user": "{{ns:project}}:Brukere",
        "grouppage-autoconfirmed": "{{ns:project}}:Autobekreftede brukere",
        "grouppage-bot": "{{ns:project}}:Roboter",
        "grouppage-sysop": "{{ns:project}}:Administratorer",
+       "grouppage-interface-admin": "{{ns:project}}:Grensesnittadministratorer",
        "grouppage-bureaucrat": "{{ns:project}}:Byråkrater",
        "grouppage-suppress": "{{ns:project}}:Historikkrydding",
        "right-read": "Se sider",
        "right-editusercss": "Redigere andre brukeres CSS-filer",
        "right-edituserjson": "Rediger andre brukere sine JSON-filer",
        "right-edituserjs": "Redigere andre brukeres JS-filer",
+       "right-editsitecss": "Redigere CSS for hele nettstedet",
+       "right-editsitejson": "Redigere JSON for hele nettstedet",
+       "right-editsitejs": "Redigere JavaScript for hele nettstedet",
        "right-editmyusercss": "Redigere sine egne CSS-filer",
        "right-editmyuserjson": "Rediger din egen bruker sine JSON-filer",
        "right-editmyuserjs": "Redigere sine egne JavaScript-filer",
        "grant-createaccount": "Opprette kontoer",
        "grant-createeditmovepage": "Opprette, redigere eller flytte sider",
        "grant-delete": "Slette sider, revisjoner og logginnlegg",
-       "grant-editinterface": "Redigere MediaWiki-navnerommet og CSS/JSON/JavaScript i brukernavnerommet",
+       "grant-editinterface": "Redigere MediaWiki-navnerommet og JSON for helle nettstedet og i brukernavnerommet",
        "grant-editmycssjs": "Redigere din bruker-CSS/JSON/JavaScript",
        "grant-editmyoptions": "Rediger dine brukerinnstillinger",
        "grant-editmywatchlist": "Redigere overvåkningslisten din",
+       "grant-editsiteconfig": "Redigere CSS og JavaScript for hele nettstedet og i brukernavnerommet",
        "grant-editpage": "Redigere eksisterende sider",
        "grant-editprotected": "Redigere beskyttede sider",
        "grant-highvolume": "Høy&shy;volum&shy;redigering",
        "rcfilters-other-review-tools": "Andre gjennomgangsverktøy",
        "rcfilters-group-results-by-page": "Grupper resultater etter side",
        "rcfilters-activefilters": "Aktive filtre",
+       "rcfilters-activefilters-hide": "Skjul",
+       "rcfilters-activefilters-show": "Vis",
+       "rcfilters-activefilters-hide-tooltip": "Skjul området for aktive filtre",
+       "rcfilters-activefilters-show-tooltip": "Vis området for aktive filtre",
        "rcfilters-advancedfilters": "Avanserte filtre",
        "rcfilters-limit-title": "Antall resultater som skal vises",
        "rcfilters-limit-and-date-label": "$1 {{PLURAL:$1|endring|endringer}}, $2",
        "rcfilters-savedqueries-rename": "Gi nytt navn",
        "rcfilters-savedqueries-setdefault": "Sett som standard",
        "rcfilters-savedqueries-unsetdefault": "Fjern som standard",
-       "rcfilters-savedqueries-remove": "Fjern",
+       "rcfilters-savedqueries-remove": "Slett",
        "rcfilters-savedqueries-new-name-label": "Navn",
        "rcfilters-savedqueries-new-name-placeholder": "Beskriv formålet til filteret",
        "rcfilters-savedqueries-apply-label": "Opprett filter",
        "rcfilters-empty-filter": "Ingen aktive filtre. Alle bidrag vises.",
        "rcfilters-filterlist-title": "Filtre",
        "rcfilters-filterlist-whatsthis": "Hvordan virker dette?",
-       "rcfilters-filterlist-feedbacklink": "Gi tilbakemelding på disse (nye) filterverktøyene",
+       "rcfilters-filterlist-feedbacklink": "Gi tilbakemelding på disse filterverktøyene",
        "rcfilters-highlightbutton-title": "Marker resultater",
        "rcfilters-highlightmenu-title": "Velg en farge",
        "rcfilters-highlightmenu-help": "Velg en farge for å merke denne egenskapen",
        "rcfilters-watchlist-showupdated": "Endringer til sider du ikke har besøkt siden endringene ble gjort vises med <strong>fet</strong> skrift.",
        "rcfilters-preference-label": "Skjul den forbedrede versjonen av siste endringer",
        "rcfilters-preference-help": "Fjerner grensesnittendringen fra 2017 og alle verktøyene som ble lagt fra og med da.",
+       "rcfilters-watchlist-preference-label": "Skjul den forbedrede versjonen av overvåkningslisten",
+       "rcfilters-watchlist-preference-help": "Ruller tilbake det omarbeidede grensesnittet fra 2017 og alle verktøy som ble lagt til da og etterpå.",
        "rcfilters-filter-showlinkedfrom-label": "Vis endringer på sider som lenkes fra",
        "rcfilters-filter-showlinkedfrom-option-label": "<strong>Sider som lenkes fra</strong> den valgte siden",
        "rcfilters-filter-showlinkedto-label": "Vis endringer på sider som lenker til",
        "uploadstash-zero-length": "Filen har en lengde på null.",
        "invalid-chunk-offset": "Ugyldig delforskyvning",
        "img-auth-accessdenied": "Ingen tilgang",
-       "img-auth-nopathinfo": "Manglende PATH_INFO.\nTjeneren din er ikke satt opp til å gi denne informasjonen.\nDen er kanskje CGI-basert og støtter ikke img_auth.\nhttps://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization Se bildeautorisasjon.",
+       "img-auth-nopathinfo": "Manglende stiinformasjon.\nTjeneren må være satt opp til å sende variablene REQUEST_URI og/eller PATH_INFO.\nOm den er det, prøv å slå på $wgUsePathInfo.\nSe https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization .",
        "img-auth-notindir": "Den ønskede stien finnes ikke i den oppsatte opplastingsmappa.",
        "img-auth-badtitle": "Kunne ikke lage en gyldig tittel ut fra «$1».",
        "img-auth-nologinnWL": "Du er ikke logget inn, og «$1» er ikke på hvitelista.",
        "http-timed-out": "Tidsavbrudd på HTTP-forespørsel.",
        "http-curl-error": "Feil under henting av adresse: $1",
        "http-bad-status": "Det var et problem under HTTP-forespørselen: $1 $2",
+       "http-internal-error": "Intern HTTP-feil.",
        "upload-curl-error6": "Klarte ikke nå adressen",
        "upload-curl-error6-text": "Adressen kunne ikke nås. Vennligst dobbelsjekk at adressen er korrekt og at siden er oppe.",
        "upload-curl-error28": "Opplastingstimeout",
        "protectedtitles-submit": "Vis titler",
        "listusers": "Brukerliste",
        "listusers-editsonly": "Vis bare brukere med redigeringer",
+       "listusers-temporarygroupsonly": "Vis kun brukere i midlertidige brukergrupper",
        "listusers-creationsort": "Sorter etter opprettelsesdato",
        "listusers-desc": "Sorter i synkende rekkefølge",
        "usereditcount": "{{PLURAL:$1|én redigering|$1 redigeringer}}",
        "apisandbox-dynamic-parameters-add-label": "Legg til parameter:",
        "apisandbox-dynamic-parameters-add-placeholder": "Parameternavn",
        "apisandbox-dynamic-error-exists": "En parameter med navn «$1» finnes fra før.",
+       "apisandbox-templated-parameter-reason": "Denne [[Special:ApiHelp/main#main/templatedparams|malparameteren]] tilbys basert på {{PLURAL:$1|verdien|verdiene}} til $2.",
        "apisandbox-deprecated-parameters": "Utgåtte parametre",
        "apisandbox-fetch-token": "Fyll inn nøkkelen automatisk",
        "apisandbox-add-multi": "Legg til",
        "speciallogtitlelabel": "Mål (tittel eller {{ns:user}}:brukernavn for brukeren):",
        "log": "Logger",
        "logeventslist-submit": "Vis",
+       "logeventslist-more-filters": "Vis flere logger:",
+       "logeventslist-patrol-log": "Patruljeringslogg",
+       "logeventslist-tag-log": "Merkelogg",
        "all-logs-page": "Alle offentlige logger",
        "alllogstext": "Kombinert visning av alle loggene på {{SITENAME}}.\nDu kan minske antallet resultater ved å velge loggtype, brukernavn eller den siden som er påvirket (husk å skille mellom store og små bokstaver).",
        "logempty": "Ingen elementer i loggen.",
        "dellogpage": "Slettelogg",
        "dellogpagetext": "Under er ei liste over nylige slettinger.",
        "deletionlog": "slettelogg",
+       "log-name-create": "Logg over nye sider",
+       "log-description-create": "Under er ei liste over nylige sideopprettelser.",
+       "logentry-create-create": "$1 {{GENDER:$2|opprettet}} siden $3",
        "reverted": "Gjenopprettet en tidligere versjon",
        "deletecomment": "Årsak:",
        "deleteotherreason": "Annen/utdypende grunn:",
        "uctop": "(siste)",
        "month": "Fra måned (og tidligere):",
        "year": "Fra år (og tidligere):",
+       "date": "Fra dato (og tidligere):",
        "sp-contributions-newbies": "Vis kun bidrag fra nye kontoer",
        "sp-contributions-newbies-sub": "For nybegynnere",
        "sp-contributions-newbies-title": "Bidrag av nye kontoer",
        "whatlinkshere": "Lenker hit",
        "whatlinkshere-title": "Sider som lenker til «$1»",
        "whatlinkshere-page": "Side:",
-       "linkshere-2": "Følgende sider lenker til '''$1''':",
-       "nolinkshere-2": "Ingen sider lenker til '''$1'''.",
-       "nolinkshere-ns-2": "Ingen sider lenker til '''$1''' i valgte navnerom.",
+       "linkshere": "Følgende sider lenker til '''$2''':",
+       "nolinkshere": "Ingen sider lenker til '''$2'''.",
+       "nolinkshere-ns": "Ingen sider lenker til '''$2''' i valgte navnerom.",
        "isredirect": "omdirigeringsside",
        "istemplate": "transklusjon",
        "isimage": "fillenke",
        "markedaspatrollederrornotify": "Patruljering feilet.",
        "patrol-log-page": "Patruljeringslogg",
        "patrol-log-header": "Dette er en logg over patruljerte sideversjoner.",
-       "log-show-hide-patrol": "$1 patruljeringslogg",
-       "log-show-hide-tag": "$1 merkelogg",
        "confirm-markpatrolled-button": "OK",
        "confirm-markpatrolled-top": "Merk revisjon $3 av $2 som patruljert?",
        "deletedrevision": "Slettet gammel revisjon $1.",
        "authmanager-password-help": "Passord for autentisering.",
        "authmanager-domain-help": "Domene for ekstern autentisering.",
        "authmanager-retype-help": "Passord igjen for å bekrefte.",
-       "authmanager-email-label": "Epost",
+       "authmanager-email-label": "E-post",
        "authmanager-email-help": "Epostadresse",
        "authmanager-realname-label": "Virkelig navn",
        "authmanager-realname-help": "Brukerens virkelige navn",
        "pagedata-title": "Sidedata",
        "pagedata-text": "Denne siden gir et datagrensesnitt til sidene. Oppgi en sidetittel i URL-en, med undersidesyntaks.\n* Innholdsforhandlingen er basert på din klients Accept-header. Dette betyr at data for siden blir angitt på formatet som foretrekkes av din klient.",
        "pagedata-not-acceptable": "Ingen passende format funnet. Støttede MIME-typer: $1",
-       "pagedata-bad-title": "Ugyldig tittel: $1."
+       "pagedata-bad-title": "Ugyldig tittel: $1.",
+       "unregistered-user-config": "For å ivareta sikkerhet kan ikke JavaScript-, CSS- og JSON-undersider lastes for uregistrerte brukere.",
+       "passwordpolicies": "Passord-regler",
+       "passwordpolicies-summary": "Det finnes en liste over gode passord-regler for brukergrupper definert i denne wikien.",
+       "passwordpolicies-group": "Gruppe",
+       "passwordpolicies-policies": "Regler",
+       "passwordpolicies-policy-minimalpasswordlength": "Passordet må være på minst $1 {{PLURAL:$1|tegn}}.",
+       "passwordpolicies-policy-minimumpasswordlengthtologin": "Passordet må være på minst $1 {{PLURAL:$1|tegn}} for å kunne logge inn",
+       "passwordpolicies-policy-passwordcannotmatchusername": "Passordet kan ikke være det samme som brukernavnet",
+       "passwordpolicies-policy-passwordcannotmatchblacklist": "Passordet kan ikke matche spesifikt svartelistede passord",
+       "passwordpolicies-policy-maximalpasswordlength": "Passordet må være på minst $1 {{PLURAL:$1|tegn}}",
+       "passwordpolicies-policy-passwordcannotbepopular": "Passordet kan ikke være {{PLURAL:$1|det populære passordet|i lista over $1 populære passord}}",
+       "easydeflate-invaliddeflate": "Det gitte innholdet er ikke riktig komprimert"
 }
index c7cc0c6..a03d104 100644 (file)
        "viewdeleted_short": "{{PLURAL:$1|Eén versie die vortedaon is|$1 versies die vortedaon bin}} bekieken",
        "protect": "Beveiligen",
        "protect_change": "wiezigen",
-       "unprotect": "Beveyliging wysigen",
+       "unprotect": "Beveiliging wysigen",
        "newpage": "Nieje zied",
        "talkpagelinktext": "Oaverleg",
-       "specialpage": "Spesiale zied",
+       "specialpage": "Speciale syde",
        "personaltools": "Persoonlike instellingen",
        "talk": "Oaverleg",
        "views": "Weergaven",
        "nstab-main": "Artikel",
        "nstab-user": "Gebruker",
        "nstab-media": "Media",
-       "nstab-special": "Spesiale zied",
-       "nstab-project": "Projektzied",
-       "nstab-image": "Bestaand",
-       "nstab-mediawiki": "Tiejige",
+       "nstab-special": "Speciale syde",
+       "nstab-project": "Projektsyde",
+       "nstab-image": "Bestand",
+       "nstab-mediawiki": "Bericht",
        "nstab-template": "Mal",
-       "nstab-help": "Hulpe",
-       "nstab-category": "Kategorie",
+       "nstab-help": "Hülpe",
+       "nstab-category": "Kategory",
        "mainpage-nstab": "Vöärblad",
        "nosuchaction": "De op-egeven haandeling besteet niet",
        "nosuchactiontext": "De opdrachte in t webadres in ongeldig.\nJe hebben t webadres misschien verkeerd in-etikt of de verkeerde verwiezing evolgd.\nDit kan oek dujen op n fout in de programmatuur van {{SITENAME}}.",
        "rcfilters-savedqueries-add-new-title": "Filterinstellingen upslån",
        "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 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-view-namespaces-tooltip": "Filter resultåten up naamruumte",
        "rcfilters-view-tags-tooltip": "Filter resultåten döär gebruuk te maken van bewarkingsetiketten",
        "rcfilters-liveupdates-button": "Rechtstreakse aktualisering",
-       "rcfilters-liveupdates-button-title-off": "Nieje wiezigingen voortdalik laoten zien",
+       "rcfilters-liveupdates-button-title-off": "Nye wysigingen voorddalik låten seen",
        "rcnotefrom": "Dit bin de wiezigingen sinds <strong>$2</strong> (maximum van <strong>$1</strong> wiezigingen).",
        "rclistfrom": "Bekiek wiezigingen vanaof $3 $2",
        "rcshowhideminor": "$1 kleine wiezigingen",
        "rc-enhanced-hide": "Details verbargen",
        "rc-old-title": "oorspronkelik an-emaakt as \"$1\"",
        "recentchangeslinked": "Soortgelyke wysigingen",
-       "recentchangeslinked-feed": "Volg verwiezigingen",
-       "recentchangeslinked-toolbox": "Volg verwiezigingen",
+       "recentchangeslinked-feed": "Volg verwysingen",
+       "recentchangeslinked-toolbox": "Volg verwysingen",
        "recentchangeslinked-title": "Wiezigingen verwaant an $1",
        "recentchangeslinked-summary": "Op disse spesiale zied steet n lieste mit de leste wieziginen op ziejen waornaor verwezen wördt. Ziejen op [[Special:Watchlist|joew volglieste]] staon '''vet'''.",
        "recentchangeslinked-page": "Ziednaam:",
        "whatlinkshere": "Verwysingen hyrhinne",
        "whatlinkshere-title": "Ziejen die verwiezen naor \"$1\"",
        "whatlinkshere-page": "Zied:",
-       "linkshere-2": "Disse ziejen verwiezen naor '''$1''':",
-       "nolinkshere-2": "Gien enkele zied verwis naor '''$1'''.",
-       "nolinkshere-ns-2": "Gien enkele zied verwis naor '''$1''' in de ekeuzen naamruumte.",
+       "linkshere": "Disse ziejen verwiezen naor '''$2''':",
+       "nolinkshere": "Gien enkele zied verwis naor '''$2'''.",
+       "nolinkshere-ns": "Gien enkele zied verwis naor '''$2''' in de ekeuzen naamruumte.",
        "isredirect": "deurverwiezing",
        "istemplate": "in-evoegd as mal",
        "isimage": "bestaandsverwiezing",
        "markedaspatrollederrornotify": "Markeren as nao-ekeken is mislokt.",
        "patrol-log-page": "Markeerlogboek",
        "patrol-log-header": "In dit logboek staon de versies die op nao-ekeken ezet bin.",
-       "log-show-hide-patrol": "Markeerlogboek $1",
        "deletedrevision": "Vortedaone ouwe versie $1.",
        "filedeleteerror-short": "Fout bie t vortdoon van bestaand: $1",
        "filedeleteerror-long": "Der waren fouten bie t vortdoon van t bestaand:\n\n$1",
index b5b6faa..c5b1a28 100644 (file)
        "whatlinkshere": "Wat wiest na disse Siet hen",
        "whatlinkshere-title": "Sieden, de na „$1“ wiest",
        "whatlinkshere-page": "Siet:",
-       "linkshere-2": "Disse Sieden wiest na '''„$1“''':",
-       "nolinkshere-2": "Kene Siet wiest na '''„$1“'''.",
-       "nolinkshere-ns-2": "Kene Sieden wiest na '''$1''' in’n utwählten Naamruum.",
+       "linkshere": "Disse Sieden wiest na '''„$2“''':",
+       "nolinkshere": "Kene Siet wiest na '''„$2“'''.",
+       "nolinkshere-ns": "Kene Sieden wiest na '''$2''' in’n utwählten Naamruum.",
        "isredirect": "Wiederleiden",
        "istemplate": "inbunnen dör Vörlaag",
        "isimage": "Dateilenk",
        "markedaspatrollederror-noautopatrol": "Du kannst de Saken, de du sülvst ännert hest, nich as nakeken marken.",
        "patrol-log-page": "Nakiek-Logbook",
        "patrol-log-header": "Dit is dat Patrolleer-Logbook.",
-       "log-show-hide-patrol": "Nakiek-Logbook $1",
        "deletedrevision": "Löschte ole Version $1",
        "filedeleteerror-short": "Fehler bi dat Wegsmieten vun de Datei: $1",
        "filedeleteerror-long": "Dat geev Fehlers bi dat Wegsmieten vun de Datei:\n\n$1",
index 1e22e2a..5002cfa 100644 (file)
@@ -27,7 +27,8 @@
                        "रमेश सिंह बोहरा",
                        "Nirajan pant",
                        "Drjpoudel",
-                       "Fitoschido"
+                       "Fitoschido",
+                       "Nabin Sapkota"
                ]
        },
        "tog-underline": "रेखाङ्कित लिङ्क:",
        "subject-preview": "विषयको पूर्वावलोकन:",
        "previewerrortext": "तपाईंको परिवर्तनको पूर्वावलोकन बनाउन खोज्दा समस्या आएको छ ।",
        "blockedtitle": "प्रयोककर्तालाई रोक लगाइएको छ",
-       "blockedtext": "'''तपाà¤\88à¤\82à¤\95à¥\8b à¤ªà¥\8dरयà¥\8bà¤\97à¤\95रà¥\8dता à¤¨à¤¾à¤® à¤¯à¤¾ à¤\86à¤\87 à¤ªà¥\80 à¤ à¥\87à¤\97ानालाà¤\88 à¤°à¥\8bà¤\95 à¤²à¤\97ाà¤\87à¤\8fà¤\95à¥\8b à¤\9b à¥¤'''\n\nरà¥\8bà¤\95 à¤²à¤\97ाà¤\89नà¥\87  $1.\nरà¥\8bà¤\95 à¤²à¤\97ाà¤\89नाà¤\95à¥\8b à¤\95ारण ''$2''.\n\n* à¤°à¥\8bà¤\95 à¤¸à¥\81रà¥\82 à¤¹à¥\81नà¥\87 : $8\n* à¤°à¥\8bà¤\95 à¤¸à¤\95िनà¥\87: $6\n* à¤°à¥\8bà¤\95बाà¤\9f à¤²à¤\95à¥\8dषित: $7\n\nतपाà¤\88à¤\82लà¥\87  $1 à¤µà¤¾ à¤\85रà¥\81 à¤\95à¥\81नà¥\88  [[{{MediaWiki:Grouppage-sysop}}|पà¥\8dरवनà¥\8dधà¤\95]] à¤¸à¤\81à¤\97 à¤°à¥\8bà¤\95à¤\95à¥\8b à¤¬à¤¾à¤°à¥\87मा à¤\9bलफल à¤\97रà¥\8dन à¤¸à¤®à¥\8dपरà¥\8dà¤\95 à¤\97रà¥\8dन à¤¸à¤\95à¥\8dनà¥\81हà¥\81नà¥\8dà¤\9b à¥¤\nतपाà¤\88à¤\81लà¥\87  'पà¥\8dरयà¥\8bà¤\97à¤\95रà¥\8dतालाà¤\88 à¤\87-मà¥\87ल à¤\97रà¥\8dनà¥\87 ' सुविधा मान्य इमेल ठेगाना [[Special:Preferences|अभिरुचीहरू]]मा नखुलाए सम्म प्रयोगगर्न पाउनुहुने छैन र यसको प्रयोग गर्नबाट रोक लगाइएको छैन ।\nतपाईंको IP ठेगाना $3 को, र रोक्का संख्या #$5.\nकृपया तपाईँको प्रश्नमा सबै जानकारी खुलाउनुहोला ।",
+       "blockedtext": "'''तपाà¤\88à¤\82à¤\95à¥\8b à¤ªà¥\8dरयà¥\8bà¤\97à¤\95रà¥\8dता à¤¨à¤¾à¤® à¤µà¤¾ à¤\86à¤\87पà¥\80 à¤ à¥\87à¤\97ानालाà¤\88 à¤°à¥\8bà¤\95 à¤²à¤\97ाà¤\87à¤\8fà¤\95à¥\8b à¤\9b à¥¤'''\n\nरà¥\8bà¤\95 à¤²à¤\97ाà¤\89नà¥\87  $1.\nरà¥\8bà¤\95 à¤²à¤\97ाà¤\89नाà¤\95à¥\8b à¤\95ारण ''$2''.\n\n* à¤°à¥\8bà¤\95 à¤¸à¥\81रà¥\82 à¤¹à¥\81नà¥\87 : $8\n* à¤°à¥\8bà¤\95 à¤¸à¤\95िनà¥\87: $6\n* à¤°à¥\8bà¤\95बाà¤\9f à¤²à¤\95à¥\8dषित: $7\n\nतपाà¤\88à¤\82लà¥\87  $1 à¤µà¤¾ à¤\85रà¥\81 à¤\95à¥\81नà¥\88  [[{{MediaWiki:Grouppage-sysop}}|पà¥\8dरवनà¥\8dधà¤\95]] à¤¸à¤\81à¤\97 à¤°à¥\8bà¤\95à¤\95à¥\8b à¤¬à¤¾à¤°à¥\87मा à¤\9bलफल à¤\97रà¥\8dन à¤¸à¤®à¥\8dपरà¥\8dà¤\95 à¤\97रà¥\8dन à¤¸à¤\95िनà¥\8dà¤\9b à¥¤\nतपाà¤\88à¤\81लà¥\87  ''{{int:emailuser}}'' सुविधा मान्य इमेल ठेगाना [[Special:Preferences|अभिरुचीहरू]]मा नखुलाए सम्म प्रयोगगर्न पाउनुहुने छैन र यसको प्रयोग गर्नबाट रोक लगाइएको छैन ।\nतपाईंको IP ठेगाना $3 को, र रोक्का संख्या #$5.\nकृपया तपाईँको प्रश्नमा सबै जानकारी खुलाउनुहोला ।",
        "autoblockedtext": "तपाईंको IP ठेगानामाथि रोक लगाइएकोछ किन भनें यो अर्को प्रयोगकर्ताले प्रयोग गरेको थियो, जसलाई $1ले रोक लगाएका थिए। \nरोक लगाउनुको कारण:\n:''$2''  \n\n* रोकावट सुरु: $8\n* रोकावट सकिने: $6\n* रोकावटको प्रयोजन: $7\n\nतपाईं $1 सित सम्पर्क गर्न सक्नुहुन्छ अथवा कुनै [[{{MediaWiki:Grouppage-sysop}}|प्रबन्धक]]सँग रोकबारे चर्चा गर्न सक्नुहुन्छ ।\n\nध्यान दिनुहोस् कि तपाईंले यस प्रयोगकर्ताका लागि ई-मेलको प्रयोग तबसम्म गर्नसक्नुहुन्न जबसम्म तपाईंको [[Special:Preferences|अभिरुचि]] पंजिकृत गर्नु हुन्न वा यस ई-मेलको प्रयोगमाथि रोक लगाइएको हुँदैन । \n\nतपाईंको वर्तमान IP ठेगाना हो- $3, अनि रोक लगाइएको ID हो- #$5.\nकृपया कुनै बेला सोधनी गर्नु परे उपर्युक्त विवरण दर्शाउनु होला ।",
        "blockednoreason": "कारण दिइएको छैन",
        "whitelistedittext": "पाना सम्पादन गर्न तपाँईले $1 गर्नु पर्दछ।",
        "accmailtext": "जथाभावीरूपमा सृजना गरिएको प्रवेशशब्द प्रयोगकर्ता [[User talk:$1|$1]] को  $2 मा पठाइएको छ।\n\nयो नयाँ खाताको प्रवेशशब्द  ''[[Special:ChangePassword|change password]]'' मा प्रवेश गरेर परिवर्तन गर्न सकिन्छ ।",
        "newarticle": "(नयाँ)",
        "newarticletext": "तपाईंले अहिले सम्म नभएको पृष्ठको लिङ्क पहिल्याउनु भएको छ।\nयो पृष्ठ निर्माण गर्न तलको कोष्ठमा टाइप गर्नुहोस्  ।(थप जानकारीको लागि [$1 help page] हेर्नुहोस् )।\nयहाँ त्यत्तिकै आइपुग्नु भएको हो भने , ब्राउजरको  '''back''' बटन थिच्नुहोस् ।",
-       "anontalkpagetext": "----''यो वार्तालाप पृष्ठ अज्ञात प्रयोगकर्ताको हो जसले अहिलेसम्म खाता बनाएकै छैन, अथवा जसले यस पृष्ठको उपयोग गर्दैन।\nयस कारण हामीले उसलाई उसको आइ पी (IP) ठेगानाले चिन्न सक्छौं। \nयस्तो आइ पी (IP) ठेगाना धेरै प्रयोगकर्ताहरूको साझा हुनसक्छ।\nयदि तपाईं अज्ञात प्रयोगकर्ता हुनुहुन्छ र तपाईंमाथि अचाहिँदो टिप्पणी भएको अनुभव गर्नुहुन्छ भने भविष्यमा अन्य अज्ञात प्रयोगकर्तासितको भ्रमबाट बाँच्न कृपया [[Special:CreateAccount|खाता खोल्नुहोस्]] अथवा [[Special:UserLogin|प्रवेश गर्नुहोस्]] ''",
+       "anontalkpagetext": "----''यो वार्तालाप पृष्ठ अज्ञात प्रयोगकर्ताको हो जसले अहिलेसम्म खाता बनाएकै छैन, अथवा जसले यस पृष्ठको उपयोग गर्दैन।\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}}|यस पृष्ठको शीर्षकको लागि खोज]] गर्न सक्नुहुन्छ,\nअथवा <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|पृष्ठ={{FULLPAGENAMEE}}}} सम्बन्धित लगहरू खोज्न सक्नुहुनेछ ]</span> तर तपाईंलाई नयाँ पृष्ठ बनाउने अधिकार छैन।",
        "missing-revision": "\"{{FULLPAGENAME}}\" पृष्ठको अवतरण #$1 रहेको छैन।\n\nसामान्य रूपमा यसो एउटा हटाइएको पृष्ठको पुरानो लिङ्कमा क्लिक गर्दा हुन्छ।\nअधिक जानकारीको लागि तपाईं [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} हटाएको लग] हेर्न सक्नुहुन्छ।",
        "recentchangeslinked-feed": "सम्बन्धित परिवर्तनहरू",
        "recentchangeslinked-toolbox": "सम्बन्धित परिवर्तनहरू",
        "recentchangeslinked-title": "\"$1\" सँग सम्बन्धित परिवर्तन",
-       "recentchangeslinked-summary": "यà¥\8b à¤¸à¥\82à¤\9aà¥\80 à¤¨à¤¿à¤°à¥\8dदिषà¥\8dà¤\9f à¤ªà¥\83षà¥\8dठ (वा à¤¨à¤¿à¤°à¥\8dदिषà¥\8dà¤\9f à¤¶à¥\8dरà¥\87णà¥\80)सित à¤\9cà¥\8bडिà¤\8fà¤\95ा à¤­à¤°à¥\8dà¤\96रà¥\88 à¤ªà¤°à¤¿à¤µà¤°à¥\8dतन à¤­à¤\8fà¤\95ा à¤ªà¥\83षà¥\8dठà¤\95à¥\8b  à¤¹à¥\8b à¥¤ [[Special:Watchlist|तपाà¤\88à¤\82à¤\95à¥\8b à¤¨à¤¿à¤\97रानà¥\80 सूची]]का पृष्ठहरू <strong>गाढा अक्षरमा</strong> छन् ।",
+       "recentchangeslinked-summary": "à¤\95à¥\81नà¥\88 à¤ªà¥\83षà¥\8dठà¤\95à¥\8b à¤µà¤¾  à¤¯à¤¸à¤¸à¤\81à¤\97 à¤¸à¤®à¥\8dबनà¥\8dधित à¤ªà¤°à¤¿à¤µà¤°à¥\8dतन à¤¹à¥\87रà¥\8dनà¤\95à¥\8b à¤²à¤¾à¤\97ि à¤\89à¤\95à¥\8dत à¤ªà¥\83षà¥\8dठà¤\95à¥\8b à¤¨à¤¾à¤® à¤¹à¤¾à¤²à¥\8dनà¥\81हà¥\8bस। (à¤\95à¥\81नà¥\88 à¤¶à¥\8dरà¥\87णà¥\80à¤\95à¥\8b à¤¸à¤¾à¤®à¤¾à¤\97à¥\8dरà¥\80हरà¥\81à¤\95à¥\8b à¤²à¤¾à¤\97ि {{ns:category}}: à¤¶à¥\8dरà¥\87णà¥\80à¤\95à¥\8b à¤¨à¤¾à¤® à¤¹à¤²à¥\8dनà¥\81हà¥\8bस à¥¤  [[Special:Watchlist|तपाà¤\88à¤\82à¤\95à¥\8b à¤\85वलà¥\8bà¤\95न सूची]]का पृष्ठहरू <strong>गाढा अक्षरमा</strong> छन् ।",
        "recentchangeslinked-page": "पृष्ठ नाम:",
        "recentchangeslinked-to": "यसको सट्टा यो पृष्ठसँग जोडिएका पृष्ठहरूको परिवर्तन देखाउने",
        "upload": "फाइल उर्ध्वभरण",
        "unwatchthispage": "निगरानीबाट हटाउने",
        "notanarticle": "सामाग्री सहितको पेज हैन",
        "notvisiblerev": "पूर्वावलोकन हटाइयो",
-       "watchlist-details": "तपाà¤\88à¤\82à¤\95à¥\8b à¤¨à¤¿à¤\97रानà¥\80 à¤¸à¥\82à¤\9aà¥\80मा à¤°à¤¹à¥\87à¤\95ा {{PLURAL:$1|$1 à¤ªà¥\83षà¥\8dठ|$1 à¤ªà¥\83षà¥\8dठहरà¥\82}} à¤µà¤¾à¤°à¥\8dतालाप à¤ªà¥\83षà¥\8dठ à¤\97निà¤\8fà¤\95ा à¤\9bà¥\88ननà¥\8d।",
+       "watchlist-details": "तपाà¤\88à¤\82à¤\95à¥\8b à¤\85वलà¥\8bà¤\95न à¤¸à¥\82à¤\9aà¥\80मा à¤°à¤¹à¥\87à¤\95ा {{PLURAL:$1|$1 à¤ªà¥\83षà¥\8dठ|$1 à¤ªà¥\83षà¥\8dठहरà¥\82}} (तथा à¤µà¤¾à¤°à¥\8dतालाप à¤ªà¥\83षà¥\8dठहरà¥\82)।",
        "wlheader-enotif": "ईमेल जानकारी सक्रिय गरियो ।",
        "wlheader-showupdated": "तपाईंले पछिल्लो पल्ट भ्रमण गरेपछि परिवर्तन भएका पृष्ठहरूलाई <strong>गाढा<strong> गरेर देखाइएको छ ।",
        "wlnote": "$3 र $4 अनुसार विगत {{PLURAL:$2|घण्टामा|'''$2''' घण्टाहरूमा}} {{PLURAL:$1|गरिएको अन्तिम परिवर्तन तल दिइएकोछ|गरिएका अन्तिम  '''$1''' परिवर्तनहरू तल दिइएका छन्}}।",
        "whatlinkshere": "यहाँ के जोडिन्छ",
        "whatlinkshere-title": "$1 सँग जोडिएका पानाहरू",
        "whatlinkshere-page": "पृष्ठ:",
-       "linkshere-2": "निम्न पृष्ठहरू '''$1''' मा जोडिन्छ :",
-       "nolinkshere-2": " '''$1'''मा लिंक भएका कुनै पृष्ठहरू छैनन्",
-       "nolinkshere-ns-2": "चुनिएको नामस्थानमा '''$1''' सित जोडिने पृष्ठहरू छैनन्।",
+       "linkshere": "निम्न पृष्ठहरू '''$2''' मा जोडिन्छ :",
+       "nolinkshere": " '''$2'''मा लिंक भएका कुनै पृष्ठहरू छैनन्",
+       "nolinkshere-ns": "चुनिएको नामस्थानमा '''$2''' सित जोडिने पृष्ठहरू छैनन्।",
        "isredirect": "अनुप्रेषित पृष्ठ",
        "istemplate": "पारदर्शिता",
        "isimage": "फाइल लिङ्क",
        "markedaspatrollederrornotify": "गस्ती अङ्कित गर्न विफल।",
        "patrol-log-page": "निगरानीको लग",
        "patrol-log-header": "गस्ती गरिएका संस्करणहरूको लग यस प्रकार रहेका छन् ।",
-       "log-show-hide-patrol": "$1 निगरानी लग",
-       "log-show-hide-tag": "$1 ट्याग लग",
        "confirm-markpatrolled-button": "ठीक छ",
        "deletedrevision": "पुराना पुनरावलोकनहरू $1 मेटिए",
        "filedeleteerror-short": "$1 फाइल मेटाइमा भूल",
        "version-libraries-description": "वर्णन",
        "version-libraries-authors": "लेखकहरू",
        "redirect": "फाइल, प्रयोगकर्ता, वा संशोधन आइडीको आधारमा अनुप्रेषित गर्ने",
-       "redirect-summary": "यस à¤µà¤¿à¤¶à¥\87ष à¤ªà¥\83षà¥\8dठ (पà¥\8dरदान à¤\97रिà¤\8fà¤\95à¥\8b à¤«à¤¾à¤\87लनाम), à¤ªà¥\83षà¥\8dठà¤\95à¥\8b (पà¥\83षà¥\8dठ à¤\86à¤\87डà¥\80 à¤\85थवा à¤\85वतरण à¤\86à¤\87डà¥\80), à¤µà¤¾ (पà¥\8dरयà¥\8bà¤\97à¤\95रà¥\8dता à¤\86à¤\87डà¥\80) à¤°à¤¾à¤\96à¥\8dदा à¤ªà¥\8dरयà¥\8bà¤\97à¤\95रà¥\8dतापà¥\83षà¥\8dठमा à¤®à¤¾ à¤¸à¤¾à¤°à¤¿à¤¨à¥\87à¤\9b। à¤\89दाहरण: [[{{#Special:Redirect}}/file/Example.jpg]], [[{{#Special:Redirect}}/page/64308]], [[{{#Special:Redirect}}/revision/328429]], à¤µà¤¾ [[{{#Special:Redirect}}/user/101]]।",
+       "redirect-summary": "यस à¤µà¤¿à¤¶à¥\87ष à¤ªà¥\83षà¥\8dठ (पà¥\8dरदान à¤\97रिà¤\8fà¤\95à¥\8b à¤«à¤¾à¤\87लनाम), à¤ªà¥\83षà¥\8dठà¤\95à¥\8b (पà¥\83षà¥\8dठ à¤\86à¤\87डà¥\80 à¤\85थवा à¤\85वतरण à¤\86à¤\87डà¥\80), à¤ªà¥\8dरयà¥\8bà¤\97à¤\95रà¥\8dता à¤ªà¥\83षà¥\8dठ (पà¥\8dरयà¥\8bà¤\97à¤\95रà¥\8dता à¤\86à¤\87डà¥\80) à¤µà¤¾ à¤²à¤\97 à¤\87नà¥\8dà¤\9fà¥\8dरà¥\80 (दिà¤\88à¤\8fà¤\95à¥\8b à¤²à¤\97 à¤\86à¤\87डà¥\80) à¤°à¤¾à¤\96à¥\8dदा à¤ªà¥\8dरयà¥\8bà¤\97à¤\95रà¥\8dता à¤ªà¥\83षà¥\8dठमा à¤\85नà¥\81पà¥\8dरà¥\87षण à¤¹à¥\81नà¥\87à¤\9b à¥¤ à¤\89दाहरण: [[{{#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 be89871..d8e0678 100644 (file)
        "customcssprotected": "U kunt deze CSS-pagina niet bewerken, omdat die persoonlijke instellingen van een andere gebruiker bevat.",
        "customjsonprotected": "U kunt deze JSONpagina niet bewerken, omdat die persoonlijke instellingen van een andere gebruiker bevat.",
        "customjsprotected": "U kunt deze JavaScriptpagina niet bewerken, omdat die persoonlijke instellingen van een andere gebruiker bevat.",
+       "sitecssprotected": "U hebt geen toestemming om deze CSS-pagina te bewerken omdat het invloed kan hebben op alle bezoekers",
+       "sitejsonprotected": "U hebt geen toestemming om deze JSON-pagina te bewerken omdat het invloed kan hebben op alle bezoekers",
+       "sitejsprotected": "U hebt geen toestemming om deze JavaScript-pagina te bewerken omdat het invloed kan hebben op alle bezoekers",
        "mycustomcssprotected": "U hebt geen rechten om deze CSS-pagina te bewerken.",
        "mycustomjsonprotected": "U hebt geen rechten om deze JSONpagina te bewerken.",
        "mycustomjsprotected": "U hebt geen rechten om deze JavaScriptpagina te bewerken.",
        "previewerrortext": "Er is een fout opgetreden tijdens het weergeven van uw wijzigingen.",
        "blockedtitle": "Gebruiker is geblokkeerd",
        "blockedtext": "'''Uw gebruikersaccount of IP-adres is geblokkeerd.'''\n\nDe blokkade is uitgevoerd door $1.\nDe opgegeven reden is ''$2''.\n\n* Aanvang blokkade: $8\n* Einde blokkade: $6\n* Bedoeld te blokkeren: $7\n\nU kunt contact opnemen met $1 of een andere [[{{MediaWiki:Grouppage-sysop}}|beheerder]] om de blokkade te bespreken.\nU kunt geen gebruik maken van de functie \"{{int:emailuser}}\", tenzij u een geldig e-mailadres hebt opgegeven in uw [[Special:Preferences|voorkeuren]] en het gebruik van deze functie niet geblokkeerd is.\nUw huidige IP-adres is $3 en het blokkadenummer is #$5.\nVermeld alle bovenstaande gegevens als u ergens op deze blokkade reageert.",
-       "autoblockedtext": "Uw IP-adres is automatisch geblokkeerd, omdat het gebruikt is door een andere gebruiker, die geblokkeerd is door $1.\nDe opgegeven reden is:\n\n:''$2''\n\n* Aanvang blokkade: $8\n* Einde blokkade: $6\n* Bedoeld te blokkeren: $7\n\nU kunt contact opnemen met $1 of een andere [[{{MediaWiki:Grouppage-sysop}}|beheerder]] om de blokkade te bespreken.\n\nU kunt geen gebruik maken van de functie \"{{ing:emailuser}}\", tenzij u een geldig e-mailadres hebt opgegeven in uw [[Special:Preferences|voorkeuren]], en het gebruik van deze functie niet is geblokkeerd.\n\nUw huidige IP-adres is $3 en het blokkadenummer is #$5.\nVermeld alle bovenstaande gegevens als u ergens op deze blokkade reageert.",
+       "autoblockedtext": "Uw IP-adres is automatisch geblokkeerd, omdat het gebruikt is door een andere gebruiker, die geblokkeerd is door $1.\nDe opgegeven reden is:\n\n:''$2''\n\n* Aanvang blokkade: $8\n* Einde blokkade: $6\n* Bedoeld te blokkeren: $7\n\nU kunt contact opnemen met $1 of een andere [[{{MediaWiki:Grouppage-sysop}}|beheerder]] om de blokkade te bespreken.\n\nU kunt geen gebruik maken van de functie \"{{int:emailuser}}\", tenzij u een geldig e-mailadres hebt opgegeven in uw [[Special:Preferences|voorkeuren]], en het gebruik van deze functie niet is geblokkeerd.\n\nUw huidige IP-adres is $3 en het blokkadenummer is #$5.\nVermeld alle bovenstaande gegevens als u ergens op deze blokkade reageert.",
        "systemblockedtext": "Uw gebruikersaccount of IP-adres is automatisch geblokkeerd door MediaWiki.\nDe opgegeven reden is:\n\n:<em>$2</em>\n\n* Aanvang blokkade: $8\n* Einde blokkade: $6\n* Bedoeld te blokkeren: $7\n\nUw huidige IP-adres is $3.\nVermeld alle bovenstaande gegevens als u ergens op deze blokkade reageert.",
        "blockednoreason": "geen reden opgegeven",
        "whitelistedittext": "U moet $1 om pagina's te bewerken.",
        "expansion-depth-exceeded-warning": "De pagina bevat te veel sjablonen",
        "parser-unstrip-loop-warning": "Er is een \"unstrip\"-lus gedetecteerd",
        "unstrip-depth-warning": "De recursielimiet ($1) voor \"unstrip\" is overschreden",
+       "unstrip-depth-category": "Pagina's waar de \"unstrip\" dieptelimiet is overschreden.",
+       "unstrip-size-warning": "De groottelimiet ($1) voor \"unstrip\" is overschreden",
+       "unstrip-size-category": "Pagina's waar de \"unstrip\" groottelimiet is overschreden",
        "converter-manual-rule-error": "Er is een fout gedetecteerd in een handmatig toegevoegde taalconversieregel.",
        "undo-success": "Deze bewerking kan ongedaan gemaakt worden.\nHieronder staat de tekst waarin de wijziging ongedaan is gemaakt.\nControleer voor het opslaan of het resultaat gewenst is.",
        "undo-failure": "De wijziging kan niet ongedaan gemaakt worden vanwege andere strijdige wijzigingen.",
+       "undo-main-slot-only": "De wijziging kan niet ongedaan gemaakt wordenomdat deze inhoud bevat die niet in het hoofdslot bevind.",
        "undo-norev": "De bewerking kon niet ongedaan gemaakt worden, omdat die niet bestaat of is verwijderd.",
        "undo-nochange": "De bewerking lijkt al ongedaan gemaakt te zijn.",
        "undo-summary": "Versie $1 van [[Special:Contributions/$2|$2]] ([[User talk:$2|overleg]]) ongedaan gemaakt",
        "diff-paragraph-moved-toold": "Deze paragraaf is verplaatst. Klik om naar de oude locatie te springen.",
        "difference-missing-revision": "{{PLURAL:$2|Eén versie|$2 versies}} van deze verschillen ($1) {{PLURAL:$2|is|zijn}} niet aangetroffen.\n\nDit wordt meestal veroorzaakt door het volgen van een verouderde koppeling verschillen voor een pagina die is verwijderd.\nMeer gegevens zijn mogelijk te vinden in het [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} verwijderingslogboek].",
        "searchresults": "Zoekresultaten",
+       "search-filter-title-prefix": "Alleen zoeken naar pagina's waarvan de titel begint met \"$1\"",
+       "search-filter-title-prefix-reset": "Alle zoeken naar alle pagina's",
        "searchresults-title": "Zoekresultaten voor \"$1\"",
        "titlematches": "Overeenkomst met onderwerp",
        "textmatches": "Overeenkomst met inhoud",
        "group-autoconfirmed": "autobevestigde gebruikers",
        "group-bot": "bots",
        "group-sysop": "beheerders",
+       "group-interface-admin": "Interfacemoderator",
        "group-bureaucrat": "bureaucraten",
        "group-suppress": "toezichthouders",
        "group-all": "(iedereen)",
        "group-autoconfirmed-member": "{{GENDER:$1|autobevestigde gebruiker}}",
        "group-bot-member": "{{GENDER:$1|bot}}",
        "group-sysop-member": "{{GENDER:$1|beheerder}}",
+       "group-interface-admin-member": "{{GENDER:$1|interfacemoderator}}",
        "group-bureaucrat-member": "{{GENDER:$1|bureaucraat}}",
        "group-suppress-member": "{{GENDER:$1|toezichthouder}}",
        "grouppage-user": "{{ns:project}}:Gebruikers",
        "grouppage-autoconfirmed": "{{ns:project}}:Geregistreerde gebruikers",
        "grouppage-bot": "{{ns:project}}:Bots",
        "grouppage-sysop": "{{ns:project}}:Beheerders",
+       "grouppage-interface-admin": "{{ns:project}}:Interfacemoderator",
        "grouppage-bureaucrat": "{{ns:project}}:Bureaucraten",
        "grouppage-suppress": "{{ns:project}}:Toezicht",
        "right-read": "Pagina's bekijken",
        "right-editusercss": "De CSS-bestanden van andere gebruikers bewerken",
        "right-edituserjson": "De JSONbestanden van andere gebruikers bewerken",
        "right-edituserjs": "De JavaScriptbestanden van andere gebruikers bewerken",
+       "right-editsitecss": "Wikibrede CSS bewerken",
+       "right-editsitejson": "Wikibrede JSON bewerken",
+       "right-editsitejs": "Wikibrede JavaScript bewerken",
        "right-editmyusercss": "Uw eigen CSS-pagina's bewerken",
-       "right-editmyuserjson": "Uw eigen JSonpagina's bewerken",
+       "right-editmyuserjson": "Uw eigen JSON-pagina's bewerken",
        "right-editmyuserjs": "Uw eigen JavaScriptpagina's bewerken",
        "right-viewmywatchlist": "Uw eigen volglijst bekijken",
        "right-editmywatchlist": "Uw eigen volglijst bewerken. Via sommige handelingen kunnen nog steeds pagina's toegevoegd worden, zelfs zonder deze bevoegdheid",
        "grant-createaccount": "Accounts aanmaken",
        "grant-createeditmovepage": "Pagina's aanmaken, bewerken en hernoemen",
        "grant-delete": "Pagina's, wijzigingen en logboekregels verwijderen",
-       "grant-editinterface": "De naamruimte MediaWiki en CSS, JSON en JavaScript van gebruikers bewerken",
+       "grant-editinterface": "De MediaWiki-naamruimte en JSON van de wiki en gebruikers bewerken",
        "grant-editmycssjs": "Eigen CSS, JSON en JavaScript bewerken",
        "grant-editmyoptions": "Eigen voorkeuren instellen",
        "grant-editmywatchlist": "Eigen volglijst bewerken",
+       "grant-editsiteconfig": "CSS/JS van de wiki en gebruikers bewerken",
        "grant-editpage": "Bestaande pagina's bewerken",
        "grant-editprotected": "Beveiligde pagina's bewerken",
        "grant-highvolume": "Veel bewerkingen in korte tijd maken",
        "rcfilters-other-review-tools": "Andere controlehulpmiddelen",
        "rcfilters-group-results-by-page": "Resultaten per pagina groeperen",
        "rcfilters-activefilters": "Actieve filters",
+       "rcfilters-activefilters-hide": "Verbergen",
+       "rcfilters-activefilters-show": "Weergeven",
+       "rcfilters-activefilters-hide-tooltip": "Verberg actieve filters",
+       "rcfilters-activefilters-show-tooltip": "Toon active filters",
        "rcfilters-advancedfilters": "Geavanceerde filters",
        "rcfilters-limit-title": "Resultaten om te tonen",
        "rcfilters-limit-and-date-label": "$1 {{PLURAL:$1|wijziging|wijzigingen}}, $2",
        "rcfilters-empty-filter": "Geen actieve filters. Alle bijdragen worden weergegeven.",
        "rcfilters-filterlist-title": "Filters",
        "rcfilters-filterlist-whatsthis": "Hoe werkt dit?",
-       "rcfilters-filterlist-feedbacklink": "Laat ons weten wat u denkt over deze (nieuwe) filterhulpmiddelen",
+       "rcfilters-filterlist-feedbacklink": "Laat ons weten wat u denkt over deze filterhulpmiddelen",
        "rcfilters-highlightbutton-title": "Resultaten markeren",
        "rcfilters-highlightmenu-title": "Kies een kleur",
        "rcfilters-highlightmenu-help": "Selecteer een kleur om deze eigenschap uit te lichten",
        "rcfilters-filter-reviewstatus-unpatrolled-label": "Niet gecontroleerd",
        "rcfilters-filter-reviewstatus-manual-description": "Bewerkingen die handmatig zijn gecontroleerd",
        "rcfilters-filter-reviewstatus-manual-label": "Handmatig gecontroleerd",
-       "rcfilters-filter-reviewstatus-auto-description": "Bewerkingen door geavanceerde gebruikers wiens werk automatisch gecontroleerd is.",
+       "rcfilters-filter-reviewstatus-auto-description": "Bewerkingen door geavanceerde gebruikers wier werk automatisch gecontroleerd wordt.",
        "rcfilters-filter-reviewstatus-auto-label": "Automatisch gecontroleerd",
        "rcfilters-filtergroup-significance": "Belangrijkheid",
        "rcfilters-filter-minor-label": "Kleine bewerkingen",
        "rcfilters-watchlist-showupdated": "Wijzigingen aan pagina's die u niet hebt bezocht sinds de wijzigingen zijn aangebracht, worden <strong>vet</strong> en met gevulde opsommingstekens weergeven.",
        "rcfilters-preference-label": "De verbeterde versie van Recente wijzigingen verbergen",
        "rcfilters-preference-help": "Zet het oude uiterlijk van de recente wijzigingen-pagina terug, inclusief alle hulpmiddelen die sindsdien zijn toegevoegd.",
+       "rcfilters-watchlist-preference-label": "Verberg de verbeterde versie van de volglijst",
        "rcfilters-filter-showlinkedfrom-label": "Toon wijzigingen op pagina's gekoppeld aan",
        "rcfilters-filter-showlinkedfrom-option-label": "<strong>Paginas gekoppeld aan</strong> de geselecteerde pagina",
        "rcfilters-filter-showlinkedto-label": "Toon wijzigingen op pagina's gekoppeld naar",
        "uploadstash-zero-length": "Bestandsgrootte is nul.",
        "invalid-chunk-offset": "Ongeldige chunkoffset",
        "img-auth-accessdenied": "Toegang geweigerd",
-       "img-auth-nopathinfo": "PATH_INFO ontbreekt.\nUw server is niet ingesteld om deze gegevens door te geven.\nMisschien gebruikt deze CGI, en dan wordt img_auth niet ondersteund.\nZie https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization voor meer informatie.",
+       "img-auth-nopathinfo": "Padinformatie ontbreekt.\nUw server moet ingesteld zijn om de REQUEST_URI en/of PATH_INFO variabelen door te geven.\nAls de server juist ingesteld is, kunt u proberen $wgUsePathInfo aan te zetten.\nZie https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization voor meer informatie.",
        "img-auth-notindir": "Het opgegeven pad is niet de ingestelde uploadmap.",
        "img-auth-badtitle": "Het was niet mogelijk een geldige paginanaam te maken van \"$1\".",
        "img-auth-nologinnWL": "U bent niet aangemeld en \"$1\" staat niet op de witte lijst.",
        "http-timed-out": "Timeout bij het HTTP-verzoek.",
        "http-curl-error": "Fout bij het ophalen van URL: $1",
        "http-bad-status": "Er is een probleem opgetreden bij het HTTP-verzoek: $1 $2",
+       "http-internal-error": "HTTP interne fout.",
        "upload-curl-error6": "Kon de URL niet bereiken",
        "upload-curl-error6-text": "De opgegeven URL is niet bereikbaar.\nControleer of de URL juist is, en of de website beschikbaar is.",
        "upload-curl-error28": "Uploadtime-out",
        "speciallogtitlelabel": "Doel (paginanaam of {{ns:user}}:gebruikersnaam voor gebruiker):",
        "log": "Logboeken",
        "logeventslist-submit": "Weergeven",
+       "logeventslist-more-filters": "Toon extra logboeken:",
+       "logeventslist-patrol-log": "Markeerlogboek",
+       "logeventslist-tag-log": "Labellogboek",
        "all-logs-page": "Alle openbare logboeken",
        "alllogstext": "Dit is het gecombineerde logboek van {{SITENAME}}.\nU kunt de lijst filteren door een specifiek logboektype te selecteren, of de gebruikersnaam (hoofdlettergevoelig) of paginatitel (tevens hoofdlettergevoelig) in te geven.",
        "logempty": "Er zijn geen regels in het logboek die voldoen aan deze criteria.",
        "dellogpage": "Verwijderingslogboek",
        "dellogpagetext": "Hieronder wordt een lijst met recent verwijderde pagina's en bestanden weergegeven.",
        "deletionlog": "verwijderingslogboek",
+       "log-name-create": "Logboek nieuwe pagina's",
+       "log-description-create": "Hieronder wordt een lijst met recent aangemaakte pagina's weergegeven.",
+       "logentry-create-create": "$1 {{GENDER:$2|heeft}} de pagina $3 aangemaakt",
        "reverted": "Eerdere versie hersteld",
        "deletecomment": "Reden:",
        "deleteotherreason": "Andere reden:",
        "uctop": "(laatste wijziging)",
        "month": "Van maand (en eerder):",
        "year": "Van jaar (en eerder):",
+       "date": "Vanaf (en eerder):",
        "sp-contributions-newbies": "Alleen bijdragen van nieuwe accounts bekijken",
        "sp-contributions-newbies-sub": "Voor nieuwelingen",
        "sp-contributions-newbies-title": "Gebruikersbijdragen van nieuwe accounts",
        "whatlinkshere": "Verwijzingen naar deze pagina",
        "whatlinkshere-title": "Pagina's die verwijzen naar \"$1\"",
        "whatlinkshere-page": "Pagina:",
-       "linkshere-2": "De volgende pagina's verwijzen naar '''$1''':",
-       "nolinkshere-2": "Geen enkele pagina verwijst naar '''$1'''.",
-       "nolinkshere-ns-2": "Geen enkele pagina in de gekozen naamruimte verwijst naar '''$1'''.",
+       "linkshere": "De volgende pagina's verwijzen naar <strong>$2</strong>:",
+       "nolinkshere": "Geen enkele pagina verwijst naar <strong>$2</strong>.",
+       "nolinkshere-ns": "Geen enkele pagina in de gekozen naamruimte verwijst naar <strong>$2</strong>.",
        "isredirect": "doorverwijspagina",
        "istemplate": "ingevoegd als sjabloon",
        "isimage": "bestandskoppeling",
        "thumbnail_dest_directory": "Niet in staat doelmap aan te maken",
        "thumbnail_image-type": "Dit bestandstype wordt niet ondersteund",
        "thumbnail_gd-library": "De instellingen voor de GD-bibliotheek zijn incompleet. De functie $1 ontbreekt",
-       "thumbnail_image-size-zero": "De afbeeldingsbestandsgrootte lijkt nul te zijn.",
+       "thumbnail_image-size-zero": "De grootte van het afbeeldingsbestand lijkt nul te zijn.",
        "thumbnail_image-missing": "Het bestand lijkt niet aanwezig te zijn: $1",
        "thumbnail_image-failure-limit": "Het maken van een miniatuurafbeelding is te vaak mislukt ($1 keer of vaker). Probeer het later nog eens.",
        "import": "Pagina's importeren",
        "markedaspatrollederrornotify": "Markeren als gecontroleerd mislukt.",
        "patrol-log-page": "Markeerlogboek",
        "patrol-log-header": "Dit logboek bevat versies die gemarkeerd zijn als gecontroleerd.",
-       "log-show-hide-patrol": "markeerlogboek $1",
-       "log-show-hide-tag": "labellogboek $1",
        "confirm-markpatrolled-button": "OK",
        "confirm-markpatrolled-top": "Wilt u bewerking $3 van $2 als gecontroleerd markeren?",
        "deletedrevision": "De oude versie $1 is verwijderd",
        "version-poweredby-others": "anderen",
        "version-poweredby-translators": "translatewiki.net-vertalers",
        "version-credits-summary": "We erkennen graag de volgende personen voor hun bijdrage aan [[Special:Version|MediaWiki]].",
-       "version-license-info": "MediaWiki is vrije software; u kunt MediaWiki verspreiden en/of aanpassen onder de voorwaarden van de GNU General Public License zoals gepubliceerd door de Free Software Foundation; ofwel versie 2 van de Licentie, of - naar uw wens - enige latere versie.\n\nMediaWiki wordt verspreid in de hoop dat het nuttig is, maar <em>ZONDER ENIGE GARANTIE</em>; zonder zelfs de impliciete garantie van <strong>VERKOOPBAARHEID</strong> of <string>GESCHIKTHEID VOOR ENIG DOEL IN HET BIJZONDER</strong>. Zie de GNU General Public License voor meer informatie.\n\nSamen met dit programma hoort u een [{{SERVER}}{{SCRIPTPATH}}/COPYING kopie van de GNU General Public License] te hebben ontvangen; zo niet, schrijf dan naar de Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA of [//www.gnu.org/licenses/old-licenses/gpl-2.0.html lees de licentie online].",
+       "version-license-info": "MediaWiki is vrije software; u kunt MediaWiki verspreiden en/of aanpassen onder de voorwaarden van de GNU General Public License zoals gepubliceerd door de Free Software Foundation; ofwel versie 2 van de Licentie, of - naar uw wens - enige latere versie.\n\nMediaWiki wordt verspreid in de hoop dat het nuttig is, maar <em>ZONDER ENIGE GARANTIE</em>; zonder zelfs de impliciete garantie van <strong>VERKOOPBAARHEID</strong> of <strong>GESCHIKTHEID VOOR ENIG DOEL IN HET BIJZONDER</strong>. Zie de GNU General Public License voor meer informatie.\n\nSamen met dit programma hoort u een [{{SERVER}}{{SCRIPTPATH}}/COPYING kopie van de GNU General Public License] te hebben ontvangen; zo niet, schrijf dan naar de Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA of [//www.gnu.org/licenses/old-licenses/gpl-2.0.html lees de licentie online].",
        "version-software": "Geïnstalleerde software",
        "version-software-product": "Product",
        "version-software-version": "Versie",
        "limitreport-cputime-value": "$1 {{PLURAL:$1|seconde|seconden}}",
        "limitreport-walltime": "Werkelijk tijdsgebruik",
        "limitreport-walltime-value": "$1 {{PLURAL:$1|seconde|seconden}}",
-       "limitreport-ppvisitednodes": "Aantal nodes bekeken tijdens de voorverwerking:",
-       "limitreport-ppgeneratednodes": "Aantal nodes aangemaakt tijdens de voorverwerking:",
+       "limitreport-ppvisitednodes": "Aantal nodes bekeken tijdens de voorverwerking",
+       "limitreport-ppgeneratednodes": "Aantal nodes aangemaakt tijdens de voorverwerking",
        "limitreport-postexpandincludesize": "Inclusiegrootte na uitbreiden",
        "limitreport-postexpandincludesize-value": "$1/$2 {{PLURAL:$2|byte|bytes}}",
        "limitreport-templateargumentsize": "Grootte sjabloonparameters",
        "limitreport-templateargumentsize-value": "$1 / $2 {{PLURAL:$2|byte|bytes}}",
        "limitreport-expansiondepth": "Hoogste uitbreidingsdiepte",
        "limitreport-expensivefunctioncount": "Aantal kostbare parserfuncties",
+       "limitreport-unstrip-depth": "\"Unstrip\" recursiediepte",
+       "limitreport-unstrip-size": "\"Unstrip\" grootte na uitbreiden",
        "limitreport-unstrip-size-value": "$1/$2 {{PLURAL:$2|byte|bytes}}",
        "expandtemplates": "Sjablonen substitueren",
        "expand_templates_intro": "Deze speciale pagina leest de opgegeven wikitekst in en substitueert recursief alle sjablonen in de wikitekst.\nHet substitueert ook alle parserfuncties zoals\n<code><nowiki>{{</nowiki>#language:…}}</code> en\nvariabelen als <code><nowiki>{{</nowiki>CURRENTDAY}}</code>.\nVrijwel alles tussen dubbele accolades wordt gesubstitueerd.",
        "pagedata-text": "Deze pagina biedt een data-interface voor pagina's. Geef een paginatitel op door deze in de URL op te nemen, op de manier van een deelpagina.\n* De inhoud wordt afgestemd op de door de client meegestuurde Accept Header. Dit betekent dat de gegevens voor de pagina worden aangeboden in het voorkeursformaat van uw client.",
        "pagedata-not-acceptable": "Er is geen overeenkomende indeling gevonden. Ondersteunde MIME-typen: $1",
        "pagedata-bad-title": "Ongeldige titel: $1.",
-       "unregistered-user-config": "Vanwege veiligheidsredenen wordt worden gebruikersdeelpagina's met JavaScript, CSS en JSON niet langer geladen voor gebruikers die niet zijn geregistreerd.",
+       "unregistered-user-config": "Om veiligheidsredenen worden gebruikersdeelpagina's met JavaScript, CSS en JSON niet geladen voor gebruikers die niet zijn geregistreerd.",
        "passwordpolicies": "Wachtwoordbeleid",
        "passwordpolicies-summary": "Dit is een lijst met de wachtwoordbeleidvormen die van toepassing zijn op de gebruikersgroepen van deze wiki.",
        "passwordpolicies-group": "Groep",
index 72ebc90..3dd1344 100644 (file)
        "cascadeprotected": "Denne sida er verna mot endring fordi ho er inkludert i fylgjande {{PLURAL:$1|side|sider}} som har djupvern slått på:\n$2",
        "namespaceprotected": "Du har ikkje tilgang til å endre sidene i '''$1'''-namnerommet.",
        "customcssprotected": "↓Du har ikkje tilgang til å endre denne sida, fordi ho inneheld ein annan brukar sine personlege innstillingar.",
-       "customjsprotected": "↓Du har ikkje tilgang til å endra denne JavaScript-sida fordi ho inneheld ein annen brukar sine personlege innstillingar.",
+       "customjsprotected": "↓Du har ikkje løyve til å endra denne JavaScript-sida fordi ho inneheld dei personlege innstillingane til ein annan brukar.",
        "mycustomcssprotected": "Du har ikkje løyve til å endra denne CSS-sida.",
        "mycustomjsprotected": "Du har ikkje løyve til å endra denne JavaScript-sida.",
        "myprivateinfoprotected": "Du har ikkje løyve til endra den private informasjonen din.",
        "revdelete-show-file-submit": "Ja",
        "revdelete-selected-text": "{{PLURAL:$1|Vald versjon|Valde versjonar}} av [[:$2]]:",
        "logdelete-selected": "{{PLURAL:$1|Vald loggoppføring|Valde loggoppføringar}}:",
+       "revdelete-text-text": "Sletta versjonar vil framleis syna i historikken til sida, men delar av innhaldet deira vil vera utilgjengeleg for ålmenta.",
+       "revdelete-text-others": "Andre administratorar vil framleis ha tilgang til det løynde innhaldet og kan attoppretta det, minder vidare avgrensingar er sette.",
        "revdelete-confirm": "Stadfest at du ynskjer å gjera dette, at du skjønar konsekvensane, og at du gjer det i samsvar med [[{{MediaWiki:Policy-url}}|retningslinene]].",
        "revdelete-suppress-text": "Løyning av sideversjonar bør '''berre''' nyttast i desse tilfella:\n* Mogeleg ærekrenkjande informasjon\n* Upassanda personleg informasjon\n*: ''heimeadresser og -telefonnummer,  personnummer, osb.''",
        "revdelete-legend": "Set avgrensing av synlegdom",
        "diff-multi-sameuser": "({{PLURAL:$1|Éin mellomversjon|$1 mellomversjonar}} av den same brukaren er ikkje {{PLURAL:$1|vist|viste}})",
        "diff-multi-otherusers": "({{PLURAL:$1|Éin mellomliggjande versjon|$1 mellomliggjande versjonar}} av {{PLURAL:$2|éin annan brukar|$2 brukarar}} er ikkje {{PLURAL:$1|vist|viste}})",
        "diff-multi-manyusers": "({{PLURAL:$1|Ein mellomversjon|$1 mellomversjonar}} av meir enn $2 {{PLURAL:$2|brukar|brukarar}}  er ikkje {{PLURAL:$1|vist|viste}})",
+       "diff-paragraph-moved-tonew": "Avsnittet vart flytt. Klikk for å gå til den nye plasseringa.",
+       "diff-paragraph-moved-toold": "Avsnittet vart flytt. Klikk for å gå til den gamle plasseringa.",
        "difference-missing-revision": "{{PLURAL:$2|Éin versjon|$2 versjonar}} av skilnaden ($1) vart ikkje {{PLURAL:$2|funnen|funne}}.\n\nDette skriv seg som oftast frå at ein har fylgt ei forelda versjonslenkje til ei side som er sletta.\nDetaljar kan ein finna i [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} sletteloggen].",
        "searchresults": "Søkjeresultat",
        "searchresults-title": "Søkjeresultat for «$1»",
        "search-external": "Eksternt søk",
        "searchdisabled": "Søkjefunksjonen på {{SITENAME}} er slått av akkurat no.\nI mellomtida kan du søkje gjennom Google.\nVer merksam på at registra deira kan vera utdaterte.",
        "search-error": "Det oppstod ein feil under søket: $1",
+       "search-warning": "Det vart gjeve ei åtvaring under søket: $1",
        "preferences": "Innstillingar",
        "mypreferences": "Innstillingar",
        "prefs-edits": "Tal på endringar:",
        "timezoneregion-indian": "Indiahavet",
        "timezoneregion-pacific": "Stillehavet",
        "allowemail": "Tillat e-post frå andre brukarar",
+       "email-allow-new-users-label": "Tillat e-post frå heilt nye brukarar",
+       "email-blacklist-label": "Hindra desse brukarane frå å senda meg e-post:",
        "prefs-searchoptions": "Søk",
        "prefs-namespaces": "Namnerom",
        "default": "standard",
        "prefs-diffs": "Skilnader",
        "prefs-help-prefershttps": "Denne innstillinga vil verta verksam neste gongen du loggar inn.",
        "userrights": "Administrering av brukartilgang",
-       "userrights-lookup-user": "Administrer brukargrupper",
+       "userrights-lookup-user": "Vel ein brukar",
        "userrights-user-editname": "Skriv inn brukarnamn:",
-       "editusergroup": "Endre brukargrupper",
+       "editusergroup": "Last inn brukargrupper",
        "editinguser": "Endrar brukarrettane til brukaren '''[[User:$1|$1]]''' $2",
+       "viewinguserrights": "Viser brukarrettane til {{GENDER:$1|brukaren}} <strong>[[User:$1|$1]]</strong> $2",
        "userrights-editusergroup": "Endre brukargrupper",
+       "userrights-viewusergroup": "Sjå {{GENDER:$1|brukargrupper}}",
        "saveusergroups": "Lagre brukargrupper",
        "userrights-groupsmember": "Medlem av:",
        "userrights-groupsmember-auto": "Implisitt medlem av:",
        "right-siteadmin": "Låse og låse opp databasen",
        "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-high-volume": "Utføra høgvolumaktivitet",
+       "grant-group-administration": "Utføra administrative handlingar",
        "grant-blockusers": "Blokkera og avblokkera brukarar",
        "grant-createaccount": "Oppretta kontoar",
        "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-editpage": "Endra oppretta sider",
        "grant-highvolume": "Høgvolumendring",
        "grant-protect": "Verna og avverna sider",
+       "grant-rollback": "Rulla attende endringar på sider",
        "grant-sendemail": "Senda e-post til andre brukarar",
        "grant-uploadeditmovefile": "Lasta opp, byta ut og flytta filer",
        "grant-uploadfile": "Lasta opp nye filer",
        "rcfilters-legend-heading": "<strong>Liste over forkortingar:</strong>",
        "rcfilters-group-results-by-page": "Grupper resultat etter side",
        "rcfilters-activefilters": "Aktive filter",
+       "rcfilters-activefilters-hide": "Gøym",
+       "rcfilters-activefilters-show": "Vis",
+       "rcfilters-activefilters-hide-tooltip": "Gøym området for aktive filter",
+       "rcfilters-activefilters-show-tooltip": "Vis området for aktive filter",
        "rcfilters-advancedfilters": "Avanserte filter",
-       "rcfilters-limit-title": "Tal endringar som skal visast",
+       "rcfilters-limit-title": "Resultat som skal visast",
        "rcfilters-limit-and-date-label": "{{PLURAL:$1|éi endring|$1 endringar}}, $2",
        "rcfilters-date-popup-title": "Søk i tidsperioden",
        "rcfilters-days-title": "Dei siste dagane",
        "rcfilters-quickfilters-placeholder-description": "For å lagra filterinnstillingane dine og bruka dei på nytt seinare, klikk på bokmerkeikonet i området for aktive filter under.",
        "rcfilters-savedqueries-defaultlabel": "Lagra filter",
        "rcfilters-savedqueries-rename": "Gje nytt namn",
+       "rcfilters-savedqueries-setdefault": "Set som standard",
        "rcfilters-savedqueries-new-name-label": "Namn",
        "rcfilters-savedqueries-new-name-placeholder": "Skildra føremålet med filteret",
        "rcfilters-savedqueries-apply-label": "Lagra innstillingar",
+       "rcfilters-savedqueries-apply-and-setdefault-label": "Opprett standardfilter",
        "rcfilters-savedqueries-add-new-title": "Lagra gjeldande filterinnstillingar",
+       "rcfilters-savedqueries-already-saved": "Desse filtera er alt lagra. Endra innstillingane dine for å oppretta eit nytt lagra filter.",
        "rcfilters-clear-all-filters": "Fjern alle filter",
        "rcfilters-show-new-changes": "Sjå dei nyaste endringane",
        "rcfilters-search-placeholder": "Filtrer endringar (nytt meny eller søk etter filternamn)",
        "rcfilters-invalid-filter": "Ugyldig filter",
        "rcfilters-empty-filter": "Ingen aktive filter. Alle bidrag er viste.",
        "rcfilters-filterlist-title": "Filter",
+       "rcfilters-filterlist-whatsthis": "Korleis verkar desse?",
        "rcfilters-filterlist-feedbacklink": "Gje attendemelding på dei nye (beta)filtera",
        "rcfilters-highlightbutton-title": "Uthev resultat",
        "rcfilters-highlightmenu-title": "Vel ein farge",
        "booksources-search": "Søk",
        "booksources-text": "Nedanfor finn du ei liste over lenkjer til andre nettstader som sel nye og brukte bøker, og desse kan ha meir informasjon om bøker du leitar etter:",
        "booksources-invalid-isbn": "Det oppgjevne ISBN-nummeret er ugyldig; sjekk med kjelda di om du har oppgjeve det rett.",
+       "magiclink-tracking-rfc": "Sider som nyttar magiske RFC-lenkjer",
+       "magiclink-tracking-pmid": "Sider som nyttar magiske PMID-lenkjer‎",
+       "magiclink-tracking-isbn": "Sider som nyttar magiske ISBN-lenkjer",
        "specialloguserlabel": "Utøvar:",
        "speciallogtitlelabel": "Mål (tittel eller {{ns:user}}:brukarnamn for brukar):",
        "log": "Loggar",
        "trackingcategories-msg": "Sporingskategori",
        "trackingcategories-name": "Meldingsnamn",
        "trackingcategories-desc": "Inkluderingsgrunnlag",
+       "restricted-displaytitle-ignored": "Sider med ignorerte visingstitlar",
+       "restricted-displaytitle-ignored-desc": "Ein <code><nowiki>{{DISPLAYTITLE}}</nowiki></code>-funksjon på denne sida  er sett bort ifrå av di argumentet ikkje svarar til den faktiske tittelen til sida.",
        "noindex-category-desc": "Sida vert ikkje indeksert av robotar av di ho inneheld trylleordet <code><nowiki>__NOINDEX__</nowiki></code> og er i eit namnerom der dette flagget er tillate.",
        "trackingcategories-nodesc": "Inga skilding er tilgjengeleg.",
        "trackingcategories-disabled": "Kategorien er avslegen",
        "dellogpage": "Slettelogg",
        "dellogpagetext": "Her er ei liste over dei siste slettingane.",
        "deletionlog": "slettelogg",
+       "logentry-create-create": "$1 {{GENDER:$2|oppretta}} sida $3",
        "reverted": "Attenderulla til ein tidlegare versjon",
        "deletecomment": "Årsak:",
        "deleteotherreason": "Annan grunn:",
        "editcomment": "Samandraget for endringa var: <em>$1</em>.",
        "revertpage": "Attenderulla endring gjord av [[Special:Contributions/$2|$2]] ([[User talk:$2|diskusjon]]) til siste versjonen av [[User:$1|$1]]",
        "revertpage-nouser": "Attenderulla endring gjord av ein løynd brukar til siste versjonen av {{GENDER:$1|[[User:$1|$1]]}}",
-       "rollback-success": "Rulla attende endringane av $1, attende til siste versjonen av $2.",
+       "rollback-success": "Rulla attende endringane av {{GENDER:$3|$1}}, attende til siste versjonen av {{GENDER:$4|$2}}.",
        "sessionfailure-title": "Feil med omgangen.",
        "sessionfailure": "Det ser ut til å vera eit problem med innloggingsøkta di. Handlinga er vorten avbroten for å vera føre var mot kidnapping av økta. Bruk attendeknappen i nettlesaren din og prøv om att.",
        "changecontentmodel": "Endra innhaldsmodellen til ei side",
        "whatlinkshere": "Lenkjer hit",
        "whatlinkshere-title": "Sider som har lenkje til «$1»",
        "whatlinkshere-page": "Side:",
-       "linkshere-2": "Desse sidene har lenkjer til '''$1''':",
-       "nolinkshere-2": "Ingen sider har lenkjer til '''$1'''.",
-       "nolinkshere-ns-2": "Ingen sider har lenkje til '''$1''' i det valde namnerommet.",
+       "linkshere": "Desse sidene har lenkjer til '''$2''':",
+       "nolinkshere": "Ingen sider har lenkjer til '''$2'''.",
+       "nolinkshere-ns": "Ingen sider har lenkje til '''$2''' i det valde namnerommet.",
        "isredirect": "omdirigeringsside",
        "istemplate": "inkludert som mal",
        "isimage": "fillenkje",
        "markedaspatrollederrornotify": "Det gjekk ikkje å merkja endringa som patruljert.",
        "patrol-log-page": "Patruljeringslogg",
        "patrol-log-header": "Dette er ein logg over patruljerte sideversjonar.",
-       "log-show-hide-patrol": "$1 patruljeringslogg",
-       "log-show-hide-tag": "$1 merkelogg",
        "deletedrevision": "Slett gammal versjon $1",
        "filedeleteerror-short": "Feil ved sletting av fila: $1",
        "filedeleteerror-long": "Det vart ein feil under filslettinga av:\n\n$1",
        "exif-model": "Kameramodell",
        "exif-software": "Programvare brukt",
        "exif-artist": "Skapar",
-       "exif-copyright": "Opphavsrettsleg eigar",
+       "exif-copyright": "Opphavsrettshaldar",
        "exif-exifversion": "Exif-versjon",
        "exif-flashpixversion": "Støtta Flashpix-versjon",
        "exif-colorspace": "Fargerom",
        "watchlisttools-raw": "Endre på overvakingslista i råformat",
        "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|diskusjon]])",
        "duplicate-defaultsort": "Åtvaring: Standardsorteringa «$2» tar over for den tidlegare sorteringa «$1».",
+       "restricted-displaytitle": "<strong>Åtvaring:</strong> Visingstittelen «$1» vart sett bort frå sidan han ikkje svarar til den faktiske tittelen til sida.",
        "version": "Versjon",
        "version-extensions": "Installerte utvidingar",
        "version-skins": "Installerte drakter",
        "mw-widgets-dateinput-placeholder-month": "ÅÅÅÅ-MM",
        "mw-widgets-titleinput-description-new-page": "sida finst ikkje enno",
        "mw-widgets-titleinput-description-redirect": "omdirigering til $1",
+       "mw-widgets-categoryselector-add-category-placeholder": "Legg til ein kategori …",
        "mw-widgets-usersmultiselect-placeholder": "Legg til fleire …",
        "date-range-from": "Frå dato:",
        "date-range-to": "Til dato:",
index 702f91e..38e4253 100644 (file)
        "whatlinkshere": "Ke eng yeo e hlomaganyago mo",
        "whatlinkshere-title": "Matlakala a go hlomaganya go \"$1\"",
        "whatlinkshere-page": "Letlakala:",
-       "linkshere-2": "Matlaka a latelago a hlomaganya le '''$1''':",
-       "nolinkshere-2": "Ga go letlakala leo le hlomaganyago go '''$1'''.",
+       "linkshere": "Matlaka a latelago a hlomaganya le '''$2''':",
+       "nolinkshere": "Ga go letlakala leo le hlomaganyago go '''$2'''.",
        "isredirect": "''redirect'' letlakala",
        "istemplate": "tsentšho",
        "isimage": "Hlomaganyo ya Faele",
index 239d754..e3dffcf 100644 (file)
        "whatlinkshere": "natj beda nitja",
        "whatlinkshere-title": "Bibol beda $1",
        "whatlinkshere-page": "Bibol:",
-       "linkshere-2": "Ngawaliny bibol beda-ang <strong>$1</strong>",
-       "nolinkshere-2": "Uart bibol beda <strong>$1</strong>.",
+       "linkshere": "Ngawaliny bibol beda-ang <strong>$2</strong>",
+       "nolinkshere": "Uart bibol beda <strong>$2</strong>.",
        "isredirect": "Dtallangiritch bibol",
        "istemplate": "transclusion",
        "isimage": "file beda",
index 400d86a..6913368 100644 (file)
@@ -20,7 +20,8 @@
                        "Fitoschido",
                        "Vriullop",
                        "Unuaiga",
-                       "Guilhelma"
+                       "Guilhelma",
+                       "Matěj Suchánek"
                ]
        },
        "tog-underline": "Soslinhar los ligams :",
        "title-invalid-characters": "Lo títol  de la pagina demandada conten de caractèrs invalids : « $1 ».",
        "title-invalid-relative": "Lo títol conten un camin relatiu. Los títols relatius (./, ../) son pas valids perque los navigadors web pòdon pas sovent i arribar.",
        "title-invalid-magic-tilde": "Lo títol de la pagina sollicitada conten una sequéncia de tildas pas valida (<nowiki>~~~</nowiki>).",
-       "title-invalid-too-long": "Lo títol de la pagina sollicitada es tròp long. A pas d’excedir  $ 1  {{PLURALA:$1|byte|bytes}} en codificacion UTF-8.",
+       "title-invalid-too-long": "Lo títol de la pagina sollicitada es tròp long. A pas d’excedir $1 {{PLURAL:$1|byte|bytes}} en codificacion UTF-8.",
        "title-invalid-leading-colon": "Lo títol de la pagina sollicitada conten dos ponches a la debuta.",
        "perfcached": "Las donadas seguendas son en cache e benlèu, son pas a jorn. Un maximum de {{PLURAL:$1|un resultat|$1 resultats}} es disponible dins lo cache.",
        "perfcachedts": "Las donadas seguendas son en cache e benlèu, son pas a jorn. Un maximum de {{PLURAL:$1|un resultat|$1 resultats}} es disponible dins lo cache.",
        "botpasswords-existing": "Senhals de robòts existents",
        "botpasswords-createnew": "Crear un novèl senhal de robòts",
        "botpasswords-editexisting": "Modificar un senhal de robòts existent",
+       "botpasswords-label-needsreset": "(lo vòstre mot de passa deu èsser inicializat tornarmai)",
        "botpasswords-label-appid": "Nom del robòt :",
        "botpasswords-label-create": "Crear",
        "botpasswords-label-update": "Metre a jorn",
        "botpasswords-updated-body": "Lo senhal pel robòt « $1 » de l'{{GENDER:$2|utilizaire|utilizaira}} « $2 » es estat mes a jorn.",
        "botpasswords-deleted-title": "Senhal de robòts suprimit",
        "botpasswords-deleted-body": "Lo senhal pel robòt « $1 » de l'{{GENDER:$2|utilizaire|utilizaira}} « $2 » es suprimit.",
+       "botpasswords-newpassword": "Lo mot de passa novèl per se connectar a <strong>$1</strong> es <strong>$2</strong>. <em>Vos cal lo registrar per lo vos remembrar mai tard.</em> <br> (Per los robòts vièlhs qu'an de besonh que lo nom per se connectar siá lo meteis que lo nom d'utilizaire, podètz tanben emplegar <strong>$3</strong> coma nom d'utilizaire e <strong>$4</strong> coma mot de passa.)",
        "botpasswords-no-provider": "BotPasswordsSessionProvider es pas disponible.",
        "botpasswords-restriction-failed": "Las restriccions de mot de passa de bots empachan aquela connexion.",
        "botpasswords-invalid-name": "Lo nom d'usatgièr especificat conten pas de separador de mot de passa de robòt (\"$1\").",
        "botpasswords-not-exist": "L'usatgièr «$1» a pas de mot de passa de robòt nomenat «$2».",
+       "botpasswords-needs-reset": "Cal tornar inicializar lo mot de passa pel robòt nomenat \"$2\" de l'utilizaire {{GENDER:$1|user}} \"$1\".",
        "resetpass_forbidden": "Los senhals pòdon pas èsser cambiats",
        "resetpass_forbidden-reason": "Los senhaus pòdon pas èsser cambiats : $1",
        "resetpass-no-info": "Vos cal èsser connectat per aver accès a aquesta pagina.",
        "subject-preview": "Apercebut del subjècte :",
        "previewerrortext": "S'es produsida una error quand ensagèretz  de previsualizar los cambiaments.",
        "blockedtitle": "L'utilizaire es blocat",
-       "blockedtext": "'''Vòstre compte d'utilizaire o vòstra adreça IP es estat blocat'''\n\nLo blocatge es estat efectuat per $1.\nLa rason invocada es la seguenta : ''$2''.\n\n* Començament del blocatge : $8\n* Expiracion del blocatge : $6\n* Compte blocat : $7.\n\nPodètz contactar $1 o un autre [[{{MediaWiki:Grouppage-sysop}}|administrator]] per ne discutir.\nPodètz pas utilizar la foncion « Mandar un corrièr electronic a aqueste utilizaire » que se una adreça de corrièr valida es especificada dins vòstras [[Special:Preferences|preferéncias]].\nVòstra adreça IP actuala es $3 e vòstre identificant de blocatge es #$5.\nIncluissètz aquesta adreça dins tota requèsta.",
-       "autoblockedtext": "Vòstra adreça IP es estada blocada automaticament perque es estada utilizada per un autre utilizaire, ele-meteis blocat per $1.\nLa rason invocadaa es :\n\n:''$2''\n\n* Començament del blocatge : $8\n* Expiracion del blocatge : $6\n* Compte blocat : $7\n\nPodètz contactar $1 o un dels autres [[{{MediaWiki:Grouppage-sysop}}|administrators]] per discutir d'aqueste blocatge.\n\nNotatz que podètz pas utilizar la foncionalitat \"Mandar un messatge a aqueste utilizaire\" tant qu'auretz pas  una adreça e-mail enregistrada dins vòstras [[Special:Preferences|preferéncias]] e tant que seretz pas blocat per son utilizacion.\n\nVòstra adreça IP actuala es $3, e lo numèro de blocatge es $5.\nPrecisatz aquestas indicacions dins totas las requèstas que faretz.",
+       "blockedtext": "'''Vòstre compte d'utilizaire o vòstra adreça IP es estat blocat'''\n\nLo blocatge es estat efectuat per $1.\nLa rason invocada es la seguenta : ''$2''.\n\n* Començament del blocatge : $8\n* Expiracion del blocatge : $6\n* Compte blocat : $7.\n\nPodètz contactar $1 o un autre [[{{MediaWiki:Grouppage-sysop}}|administrator]] per ne discutir.\nPodètz pas utilizar la foncion « Mandar un corrièr electronic a aqueste utilizaire » que se una adreça de corrièr valida es especificada dins vòstras [[Special:Preferences|preferéncias]].\nVòstra adreça IP actuala es $3 e vòstre identificant de blocatge es #$5.\nInclusètz aquesta adreça dins tota requèsta.",
+       "autoblockedtext": "Vòstra adreça IP es estada blocada automaticament perque es estada utilizada per un autre utilizaire, el-meteis blocat per $1.\nLa rason invocada es :\n\n:''$2''\n\n* Començament del blocatge : $8\n* Expiracion del blocatge : $6\n* Compte blocat : $7\n\nPodètz contactar $1 o un dels autres [[{{MediaWiki:Grouppage-sysop}}|administrators]] per discutir d'aqueste blocatge.\n\nNotatz que podètz pas utilizar la foncionalitat \"Mandar un messatge a aqueste utilizaire\" tant qu'auretz pas  una adreça e-mail enregistrada dins vòstras [[Special:Preferences|preferéncias]] e tant que seretz pas blocat per son utilizacion.\n\nVòstra adreça IP actuala es $3, e lo numèro de blocatge es $5.\nPrecisatz aquestas indicacions dins totas las requèstas que faretz.",
        "systemblockedtext": "Lo vòstre nom d'usatgièr o adreça IP foguèt estat blocat automaticament pel MediaWiki.\nLo motiu balhat es:\n\n:<em>$2</em>\n\n* Començament del blocatge: $8\n* Fin del delai de blocatge: $6\n* Element pertocat: $7\n\nLa vòstra adreça IP actuala es $3.\nApondètz las donadas de mai amont per cada demanda  que faretz.",
        "blockednoreason": "Cap de rason balhada",
        "whitelistedittext": "Vos cal èsser $1 per modificar las paginas.",
        "parser-template-loop-warning": "Modèl en bocla detectat : [[$1]]",
        "template-loop-category": "Paginas amb boclas de patron",
        "template-loop-category-desc": "La pagina conten una bocla dins lo patron, es a dire, un patron que se sona el meteis recursivament.",
-       "template-loop-warning": "<strong>Attencion:</strong> Aquesta pagina sona [[:$1]. Aquò es l'encausa d'una bocla de patron (una sonada infinida resursiva).",
+       "template-loop-warning": "<strong>Atencion:</strong> Aquesta pagina sona [[:$1]. Aquò es la causa d'una bocla de patron (una sonada infinida recursiva).",
        "parser-template-recursion-depth-warning": "Limit de longor de la recursion del modèl depassat ($1)",
        "language-converter-depth-warning": "Limit de prigondor del convertissor de lenga depassada ($1)",
        "node-count-exceeded-category": "Paginas ont nombre de nosèls es depassat",
        "saveusergroups": "Enregistrar los gropes de l’{{GENDER:$1|utilizaire|utilizaira}}",
        "userrights-groupsmember": "Membre de :",
        "userrights-groupsmember-auto": "Membre implicit de :",
-       "userrights-groups-help": "Podètz modificar los gropes als quals aparten {{GENDER:$1|aqueste utilizaire|aquesta utilizaira}}.\n* Una casa marcada significa que l'utilizair{{GENDER:$1|e|a}} se tròba dins aqueste grop.\n* Una casa pas marcada significa, al contrari, que s’i tròba pas.\n* Un asterisc * indica que podètz pas levar aqueste grop un còp que l'avètz apondut e vice-versa.\n* Un dièsi (#) indica que podètz que ralongar lo delai d'expiracion del grop e non pas l'acorchir.",
+       "userrights-groups-help": "Podètz modificar los gropes qu'aqueste utilizaire ne fa partida:\n* Una casa marcada significa que l'utilizaire {{GENDER:$1|e|a}} se tròba dins aqueste grop.\n* Una casa pas marcada significa, al contrari, que s’i tròba pas.\n* Un asterisc * indica que podètz pas suprimir aqueste grop un còp que l'avètz apondut e recipròcament.\n* Un dièsi (#) indica que podètz que aumentar lo delai d'expiracion del grop e non pas lo diminuir.",
        "userrights-reason": "Motiu :",
        "userrights-no-interwiki": "Sètz pas abilitat per modificar los dreits dels utilizaires sus d'autres wikis.",
        "userrights-nodatabase": "La basa de donadas « $1 » existís pas o es pas en local.",
        "right-siteadmin": "Verrolhar e desverrolhar la basa de donadas",
        "right-override-export-depth": "Exportar las paginas en incluent las paginas ligadas fins a una prigondor de 5 nivèls",
        "right-sendemail": "Mandar un corrièl als autres utilizaires",
+       "right-managechangetags": "Crear, activar e desactivar [[Special:Tags|tags]]",
        "right-applychangetags": "Aplicar [[Special:Tags|las balisas]] amb sas pròprias modificacions",
+       "right-changetags": "Apondre e suprimir arbitràriament [[Special:Tags|tags]] sus de revisions individualas e d'intradas de jornal",
+       "right-deletechangetags": "Suprimir [[Special:Tags|tags]] dempuèi la basa de donadas",
        "grant-generic": "ensemble de dreits « $1 »",
        "grant-group-page-interaction": "Interagir amb de paginas",
        "grant-group-file-interaction": "Interagir amb de mèdias",
        "grant-group-watchlist-interaction": "Interagir amb vòstra lista de seguiment",
        "grant-group-email": "Mandar un corrièr electronic",
+       "grant-group-high-volume": "Realizar una activitat de volum naut",
        "grant-group-customization": "Personalizacion e preferéncias",
        "grant-group-administration": "Efectuar d'accions administrativas",
        "grant-group-private-information": "Accedir a vòstras donadas privadas",
        "grant-blockusers": "Blocar e desblocar d'utilizaires",
        "grant-createaccount": "Crear de comptes",
        "grant-createeditmovepage": "Crear, modificar e desplaçar de paginas",
+       "grant-delete": "Suprimir paginas, revisions e dintradas de jornal",
        "grant-editinterface": "Modificar l'espaci de noms de MediaWiki e lo CSS/JSON/Javascript",
        "grant-editmycssjs": "Modificar vòstre CSS/JSON/JavaScript utilizator",
        "grant-editmyoptions": "Modificar vòstras preferéncias d'utilizaire",
+       "grant-editmywatchlist": "Modificar la vòstra lista de seguiment",
        "grant-editpage": "Modificar de paginas existentas",
        "grant-editprotected": "Modificar de paginas protegidas",
+       "grant-highvolume": "Modificacion de volum naut",
+       "grant-oversight": "Amagar los usatgièrs e suprimir las revisions",
        "grant-patrol": "Verificar las modificacions de paginas",
        "grant-privateinfo": "Accedir a las informacions privadas",
+       "grant-protect": "Protegir e desprotegir paginas",
+       "grant-rollback": "Anullar modificacions sus de paginas",
        "grant-sendemail": "Mandar de corriers electronics als autres utilizaires",
        "grant-uploadeditmovefile": "Telecargar, remplaçar e renomenar de fichièrs",
        "grant-uploadfile": "Importar de fichièrs novèls",
        "grant-basic": "Dreits de basa",
        "grant-viewdeleted": "Afichar los fichièrs e paginas suprimits",
        "grant-viewmywatchlist": "Afichar vòstra lista de seguiment",
+       "grant-viewrestrictedlogs": "Afichar las entradas del jornal confidencialas",
        "newuserlogpage": "Istoric de las creacions de comptes",
        "newuserlogpagetext": "Jornal de las creacions de comptes d'utilizaires.",
        "rightslog": "Istoric de las modificacions d'estatut",
        "action-createpage": "crear aquesta pagina",
        "action-createtalk": "crear aquesta pagina de discussion",
        "action-createaccount": "crear aqueste compte d'utilizaire",
+       "action-autocreateaccount": "Crear automaticament aquel compte d'usatgièr extèrne",
        "action-history": "afichar l’istoric d'aquesta pagina",
        "action-minoredit": "marcar aqueste cambiament coma menor",
        "action-move": "renomenar aquesta pagina",
        "action-deleterevision": "suprimir las revisions",
        "action-deletelogentry": "suprimir las entradas del jornal",
        "action-deletedhistory": "veire l’istoric suprimit d'una pagina",
+       "action-deletedtext": "Afichar lo tèxte de la revision suprimida",
        "action-browsearchive": "recercar de paginas suprimidas",
        "action-undelete": "restablir de paginas",
        "action-suppressrevision": "visionar e restablir de revisions suprimidas",
        "action-viewmywatchlist": "afichar vòstra pròpria lista de seguiment",
        "action-viewmyprivateinfo": "veire vòstras informacions personalas",
        "action-editmyprivateinfo": "modificar vòstras informacions personalas",
+       "action-editcontentmodel": "Editar lo modèl de contengut d'una pagina",
+       "action-managechangetags": "Crear e (des)activar d'etiquetas",
+       "action-applychangetags": "Aplicar las etiquetas amb los vòstres cambiaments",
+       "action-changetags": "Apondre e suprimir arbitràriament d'etiquetas  a las revisions individualas e a las entradas de jornal.",
+       "action-deletechangetags": "Suprimir d'etiquetas dempuèi la basa de donadas",
        "action-purge": "purgar aquesta pagina",
        "nchanges": "$1 {{PLURAL:$1|cambiament|cambiaments}}",
        "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|dempuèi la darrièra visita}}",
        "recentchanges-legend": "Opcions dels darrièrs cambiaments",
        "recentchanges-summary": "Vaquí sus aquesta pagina, los darrièrs cambiaments de {{SITENAME}}.",
        "recentchanges-noresult": "Pas cap de modificacion que correspond a aqueles critèris sul periòde indicat.",
+       "recentchanges-timeout": "Aquesta cerca dura tròp de temps. Podètz ensajar de paramètres de cerca diferents",
+       "recentchanges-network": "Se pòt pas afichar pas cap de resultat en causa d'una error tecnica. Ensajatz de tornar cargar la pagina.",
+       "recentchanges-notargetpage": "Dintrar lo nom d'una pagina per veire los cambiaments relatius a aquesta pagina.",
        "recentchanges-feed-description": "Seguissètz los darrièrs cambiaments d'aqueste wiki dins un flux.",
        "recentchanges-label-newpage": "Aquesta modificacion a creat una pagina novèla",
        "recentchanges-label-minor": "Aqueste cambiament es menor",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (veire tanben la [[Special:NewPages|lista de las paginas novèlas]]).",
        "recentchanges-legend-plusminus": "(''±123'')",
        "recentchanges-submit": "Afichar",
+       "rcfilters-tag-remove": "Suprimir '$1'",
+       "rcfilters-legend-heading": "<strong>Lista de las abreviacions:</strong>",
+       "rcfilters-other-review-tools": "Autras aisinas de supervision",
+       "rcfilters-group-results-by-page": "Agropar los resultats per pagina",
        "rcfilters-activefilters": "Filtres actius",
+       "rcfilters-advancedfilters": "Filtres avançats",
+       "rcfilters-limit-title": "Resultats d'affichar",
+       "rcfilters-days-title": "Darrièrs jorns",
        "rcfilters-hours-title": "Darrièras oras",
        "rcfilters-days-show-days": "($1 {{PLURAL:$1|jorn|jorns}})",
        "rcfilters-days-show-hours": "$1 {{PLURAL:$1|ora|oras}}",
+       "rcfilters-highlighted-filters-list": "Mes en evidéncia: $1",
        "rcfilters-quickfilters": "Filtres salvats",
+       "rcfilters-quickfilters-placeholder-title": "Pas encara de filtre salvagardat",
+       "rcfilters-quickfilters-placeholder-description": "Per salvagardar los paramètres de los vòstres filtres e tornar los utilizar mai tard , clicatz sus l'icòna dels favorits dins l'airal de Filtres Actius, dejós.",
        "rcfilters-savedqueries-defaultlabel": "Filtres salvats",
        "rcfilters-savedqueries-rename": "Renomenar",
        "rcfilters-savedqueries-setdefault": "Activar per defaut",
        "rcfilters-savedqueries-apply-label": "Crear un filtre",
        "rcfilters-savedqueries-apply-and-setdefault-label": "Crear lo filtre per defaut",
        "rcfilters-savedqueries-cancel-label": "Anullar",
+       "rcfilters-savedqueries-add-new-title": "Salvagardar los paramètres del filtre actual",
+       "rcfilters-savedqueries-already-saved": "Aquestes filtres son ja salvagardats. Vos cal modificar de paramètres  per crear un novèl filtre salvagardat.",
+       "rcfilters-restore-default-filters": "Restaurar los filtres per defaut",
+       "rcfilters-clear-all-filters": "Escafar totes los filtres",
+       "rcfilters-show-new-changes": "Veire los cambiaments los mai recents",
+       "rcfilters-search-placeholder": "Filtrar los cambiaments (utilizatz lo menu o cercatz lo nom d'un filtre)",
        "rcfilters-invalid-filter": "Filtre pas valid",
+       "rcfilters-empty-filter": "I a pas cap de filtre actiu. Se mòstran totas las contribucions.",
        "rcfilters-filterlist-title": "Filtres",
+       "rcfilters-filterlist-whatsthis": "Cossí fonciona aquò ?",
+       "rcfilters-filterlist-feedbacklink": "Digatz nos que pensatz d'aquestas aisinas (novelas) per filtrar",
+       "rcfilters-highlightbutton-title": "Valorar los resultats",
        "rcfilters-highlightmenu-title": "Causir una color",
+       "rcfilters-highlightmenu-help": "Causir una color per valorar aquesta proprietat",
        "rcfilters-filterlist-noresults": "Cap de filtre pas trobat",
+       "rcfilters-noresults-conflict": "S'es pas trobat cap de resultat perque los critèris de cèrca son en conflicte",
+       "rcfilters-state-message-subset": "Aquel filtre fonciona pas perque los seus resultats son inclús dins los resultats de la cerca seguenta , {{PLURAL:$2|filtre mai larg |filtres mai larges}} (ensajatz de los destriar amb la mesa en forma): $1",
+       "rcfilters-state-message-fullcoverage": "Seleccionar totes los filtres d'aquel grop es equivalent a una seleccion voida, doncas aquel filtre a pas d'efèit. Lo grop compren: $1",
        "rcfilters-filtergroup-authorship": "Paternitat de las contribucions",
        "rcfilters-filter-editsbyself-label": "Modificacions faitas per vos",
        "rcfilters-filter-editsbyself-description": "Vòstras pròprias contribucions.",
        "rcfilters-filter-editsbyother-label": "Modificacions faitas pels autres.",
+       "rcfilters-filter-editsbyother-description": "Totes los cambiaments a l'excepcion de los vòstres.",
+       "rcfilters-filtergroup-userExpLevel": "Registrament dels usatgièrs e experiéncia",
        "rcfilters-filter-user-experience-level-registered-label": "Connectat",
        "rcfilters-filter-user-experience-level-registered-description": "Editors connectats.",
        "rcfilters-filter-user-experience-level-unregistered-label": "Pas connectat",
        "rcfilters-filter-user-experience-level-unregistered-description": "Editors que son pas connectats.",
        "rcfilters-filter-user-experience-level-newcomer-label": "Novèls arribants",
+       "rcfilters-filter-user-experience-level-newcomer-description": "Editors registrats qu'an fait mens de 10 cambiaments o que son actius dempuèi mens de 4 jorns.",
        "rcfilters-filter-user-experience-level-learner-label": "Aprenents",
+       "rcfilters-filter-user-experience-level-learner-description": "Editors registrats, que lor nivèl d'experiéncia es entre \"Utilizaire novelari\" e \"Utilizaire experimentat.\"",
        "rcfilters-filter-user-experience-level-experienced-label": "Utilizaires experimentats",
+       "rcfilters-filter-user-experience-level-experienced-description": "Editors registrats amb mai de 500 cambiaments e 30 jorns d'activitat.",
        "rcfilters-filtergroup-automated": "Contribucions automatizadas",
        "rcfilters-filter-bots-label": "Robòt",
+       "rcfilters-filter-bots-description": "Cambiaments faits per d'aisinas automaticas",
        "rcfilters-filter-humans-label": "Èsser uman (pas robòt)",
        "rcfilters-filter-humans-description": "Modificacions faitas per d'editors umans.",
+       "rcfilters-filtergroup-reviewstatus": "Estat de revision",
+       "rcfilters-filter-reviewstatus-unpatrolled-description": "Cambiaments que son pas marcats coma revisats manualament o automaticament.",
        "rcfilters-filter-reviewstatus-unpatrolled-label": "Pas patrolhat",
+       "rcfilters-filter-reviewstatus-manual-description": "Cambiaments manuals marcats coma revisats",
+       "rcfilters-filter-reviewstatus-manual-label": "Verificat manualament",
+       "rcfilters-filter-reviewstatus-auto-description": "Edicions per d'usatgièrs experimentats que lor trabalh es marcat automaticament coma verificat.",
+       "rcfilters-filter-reviewstatus-auto-label": "Verificat automaticament",
        "rcfilters-filtergroup-significance": "Significacion",
        "rcfilters-filter-minor-label": "Cambiaments menors",
        "rcfilters-filter-minor-description": "Modificacions que l'autor a marcadas coma menoras.",
        "rcfilters-filter-major-label": "Modificacions pas menoras",
        "rcfilters-filter-major-description": "Modificacions pas marcadas coma menoras.",
+       "rcfilters-filtergroup-watchlist": "Paginas de la lista de seguiment",
+       "rcfilters-filter-watchlist-watched-label": "Sus la lista de seguiment",
+       "rcfilters-filter-watchlist-watched-description": "Cambiaments faits sus las paginas de la vòstra lista de seguiment.",
+       "rcfilters-filter-watchlist-watchednew-label": "Cambiaments novèls dins la lista de seguiment",
+       "rcfilters-filter-watchlist-watchednew-description": "Cambiaments dins las paginas en seguiment qu'avètz pas vistas dempuèi que de cambiaments foguèron faits.",
+       "rcfilters-filter-watchlist-notwatched-label": "Es pas sus la lista de seguiment",
+       "rcfilters-filter-watchlist-notwatched-description": "Tot a l'excepcion de cambiaments faits sus las vòstras paginas de seguiment.",
+       "rcfilters-filtergroup-watchlistactivity": "Activitat sus la lista de seguiment",
+       "rcfilters-filter-watchlistactivity-unseen-label": "Cambiaments pas vists",
+       "rcfilters-filter-watchlistactivity-unseen-description": "Cambiaments dins las paginas en seguiment qu'avètz pas vistas dempuèi que de cambiaments foguèron faits.",
+       "rcfilters-filter-watchlistactivity-seen-label": "Cambiaments qu'avètz ja vistes",
+       "rcfilters-filter-watchlistactivity-seen-description": "Cambiaments dins las paginas  qu'avètz vistas dempuèi que de cambiaments foguèron faits.",
        "rcfilters-filtergroup-changetype": "Tipe de cambiament",
        "rcfilters-filter-pageedits-label": "Modificacions de pagina",
        "rcfilters-filter-pageedits-description": "Modificacions del contengut del wiki, de las discussions, de las descripcions de las categorias...",
        "rcfilters-filter-newpages-label": "Creacions de pagina",
        "rcfilters-filter-newpages-description": "Modificacions a l'origina de paginas novèlas.",
        "rcfilters-filter-categorization-label": "Cambiaments de categoria",
+       "rcfilters-filter-categorization-description": "Registraments de paginas apondudas o suprimidas de las categorias.",
        "rcfilters-filter-logactions-label": "Accions traçadas",
        "rcfilters-filter-logactions-description": "Accions dels administrators, creacions de comptes, supressions de paginas, telecargaments...",
+       "rcfilters-hideminor-conflicts-typeofchange": "D'unes tipes de cambiament pòdon pas èsser designats coma  \"minors\", doncas aqueste filtre es en conflicte amb los filtres  de Tipe de cambiament seguent: $1",
+       "rcfilters-typeofchange-conflicts-hideminor": "Aqueste filtre «Tipe de cambiament» es en conflicte amb lo filtre «Edicions minoras». D'unes tipes de cambiaments  pòdon pas èstre considerats coma «minors».",
+       "rcfilters-filtergroup-lastRevision": "Darrièras revisions",
+       "rcfilters-filter-lastrevision-label": "Darrièra revision",
+       "rcfilters-filter-lastrevision-description": "Sonque lo cambiament de pagina lo mai recent.",
+       "rcfilters-filter-previousrevision-label": "Pas la darrièra revision",
+       "rcfilters-filter-previousrevision-description": "Totes los cambiaments que son pas «la darrièra revision».",
+       "rcfilters-filter-excluded": "Exclús",
+       "rcfilters-tag-prefix-namespace-inverted": "<strong>:Pas</strong> $1",
+       "rcfilters-exclude-button-off": "Exclure los seleccionats",
+       "rcfilters-exclude-button-on": "Seleccionats excluses",
+       "rcfilters-view-tags": "Cambiaments marcats",
+       "rcfilters-view-namespaces-tooltip": "Resultat del filtratge per espaci de noms",
+       "rcfilters-view-tags-tooltip": "Resultat del filtratge per etiqueta d'edicion",
+       "rcfilters-view-return-to-default-tooltip": "Tornar al menut de filtres principal",
+       "rcfilters-view-tags-help-icon-tooltip": "Ne saber mai suls cambiaments marcats",
+       "rcfilters-liveupdates-button": "Actualizacion en dirècte",
+       "rcfilters-liveupdates-button-title-on": "Desactivar los cambiaments en dirècte",
        "rcnotefrom": "Çaijós {{PLURAL:$5|la modificacion efectuada|las modificacions efectuadas}} dempuèi lo <strong>$3, $4</strong> (afichadas fins a <strong>$1</strong>).",
        "rclistfrom": "Afichar las modificacions novèlas dempuèi lo $3 $2",
        "rcshowhideminor": "$1 los cambiaments menors",
        "recentchangeslinked-feed": "Seguit dels ligams",
        "recentchangeslinked-toolbox": "Seguit dels ligams",
        "recentchangeslinked-title": "Seguit dels ligams associats a \"$1\"",
-       "recentchangeslinked-summary": "Entrar un nom de pagina per veire las modificacions faitas recentament sus de paginas ligadas dempuèi o cap a aquesta pagina (per veire los membres d’una categoria, entratz Categoria:Nom de categoria). Las modificacions de las paginas de [[Special:Watchlist|vòstra lista de seguiment]] son <strong>en gras</strong>.",
+       "recentchangeslinked-summary": "Dintrar un nom de pagina per veire las modificacions faitas recentament sus de paginas ligadas dempuèi o cap a aquesta pagina (per veire los membres d’una categoria, entratz Categoria:Nom de categoria). Las modificacions de las paginas de [[Special:Watchlist|vòstra lista de seguiment]] son <strong>en gras</strong>.",
        "recentchangeslinked-page": "Nom de la pagina :",
        "recentchangeslinked-to": "Afichar los cambiaments cap a las paginas ligadas al luòc de la pagina donada",
        "recentchanges-page-added-to-category": "[[:$1]] apondut a la categoria",
        "whatlinkshere": "Paginas ligadas a aquesta",
        "whatlinkshere-title": "Paginas que puntan cap a « $1 »",
        "whatlinkshere-page": "Pagina :",
-       "linkshere-2": "Las paginas çaijós contenon un ligam cap a '''$1''':",
-       "nolinkshere-2": "Cap de pagina conten pas de ligam cap a '''$1'''.",
-       "nolinkshere-ns-2": "Cap de pagina conten pas de ligam cap a '''$1''' dins l’espaci de nom causit.",
+       "linkshere": "Las paginas çaijós contenon un ligam cap a '''$2''':",
+       "nolinkshere": "Cap de pagina conten pas de ligam cap a '''$2'''.",
+       "nolinkshere-ns": "Cap de pagina conten pas de ligam cap a '''$2''' dins l’espaci de nom causit.",
        "isredirect": "pagina de redireccion",
        "istemplate": "inclusion",
        "isimage": "ligam cap al fichièr",
        "markedaspatrollederrornotify": "Fracàs del marcatge coma contrarotlat.",
        "patrol-log-page": "Istoric de las versions patrolhadas",
        "patrol-log-header": "Vaquí un jornal de las versions patrolhadas.",
-       "log-show-hide-patrol": "$1 l'istoric de las relecturas",
-       "log-show-hide-tag": "$1 lo jornal de las balisas",
        "confirm-markpatrolled-button": "D'acòrdi",
        "deletedrevision": "La version anciana $1 es estada suprimida.",
        "filedeleteerror-short": "Error al moment de la supression del fichièr : $1",
index f2433a8..c9dc411 100644 (file)
        "whatlinkshere": "Linkit tänne",
        "whatlinkshere-title": "Sivut, kudamat kosketah sivuu \"$1\"",
        "whatlinkshere-page": "Sivu:",
-       "linkshere-2": "Nämmä sivut linkittiäkseh sivuh <strong>$1</strong>:",
+       "linkshere": "Nämmä sivut linkittiäkseh sivuh <strong>$2</strong>:",
        "isredirect": "uvvellehohjavussivu",
        "istemplate": "sizällyttämine",
        "isimage": "failan linku",
index 06aa815..7da0f30 100644 (file)
        "mostimages": "ଫାଇଲରେ ବେଶି ଯୋଡ଼ାଯାଇଥିବା ଥିବା",
        "mostinterwikis": "ସବୁଠାରୁ ଅଧିକ ଉଇକିଥିବା ପୃଷ୍ଠାଗୁଡିକ",
        "mostrevisions": "ସବୁଠାରୁ ଅଧିକ ସଙ୍କଳନ ଥିବା ପୃଷ୍ଠାସମୂହ",
-       "prefixindex": "à¬\86à¬\97ରà­\81 à¬\95ିà¬\9bି à¬¯à­\8bଡ଼ା à¬¸à¬¹ à¬¥à¬¿à¬¬à¬¾ à¬¸à¬¬à­\81 à¬«à¬°à¬¦ସବୁ",
+       "prefixindex": "à¬\86à¬\97ରà­\81 à¬\95ିà¬\9bି à¬¯à­\8bଡ଼ା à¬¸à¬¹ à¬¥à¬¿à¬¬à¬¾ à¬¸à¬¬à­\81 à¬ªà­\83ଷà­\8dଠାସବୁ",
        "prefixindex-namespace": "ଉପସର୍ଗ ଲାଗିଥିବା ସବୁଯାକ ପୃଷ୍ଠା ($1 ଗୋଟି ନେମସ୍ପେସ)",
        "prefixindex-strip": "ତାଲିକାରୁ ନାମ ଆଗରୁ ଲାଗୁଥିବା ଶବ୍ଦ ହଟାନ୍ତୁ",
        "shortpages": "ଛୋଟ ପୃଷ୍ଠାସମୂହ",
        "allpagesprefix": "ଉପସର୍ଗ ଥିବା ପୃଷ୍ଠାସମୂହର ଦେଖଣା:",
        "allpagesbadtitle": "ଆପଣ ଅନୁରୋଧ କରିଥିବା ପୃଷ୍ଠାଟି ଭୁଲ, ଅଲଗା ଭାଷାର ବ୍ୟବହାର କରାଯାଇଛି ବା ଭୁଲ ଇଣ୍ଟର ଉଇକି ଉପସର୍ଗ ଦିଆଯାଇଛି ।\nଏଥିରେ ଥିବା ଗୋଟିଏ ବା ଦୁଇଟି ଅକ୍ଷର ଶିରୋନାମା ଭାବରେ ବ୍ୟବହାର କରାଯାଇ ପାରିବ ନାହିଁ ।",
        "allpages-bad-ns": "{{SITENAME}}ରେ \"$1\" ନେମସ୍ପେସଟିଏ ନାହିଁ ।",
-       "allpages-hide-redirects": "ପà­\81ନà¬\83ପà­\8dରà­\87ରଣସମà­\82ହକୁ ଲୁଚାଇବେ",
+       "allpages-hide-redirects": "ଲà­\87à¬\89à¬\9fାଣିସବà­\81କୁ ଲୁଚାଇବେ",
        "cachedspecial-viewing-cached-ttl": "ଆପଣ ଏହି ପୃଷ୍ଠାର ଏକ ପୁରୁଣା ସଂସ୍କରଣ ଦେଖୁଛନ୍ତି, ଯାହାକି $1 ପୁରୁଣା ହୋଇଥାଇପାରେ ।",
        "cachedspecial-viewing-cached-ts": "ଆପଣ ଏହି ପୃଷ୍ଠାର ଏକ ପୁରୁଣା ସଂସ୍କରଣ ଦେଖୁଛନ୍ତି, ଯାହାକି ପ୍ରକୃତରେ ସଂପୂର୍ଣ ନ ହୋଇଥାଇପାରେ ।",
        "cachedspecial-refresh-now": "ନୂତନତମ ଦେଖନ୍ତୁ ।",
        "whatlinkshere": "ଏଠାରେ ଥିବା ଲିଙ୍କ",
        "whatlinkshere-title": "\"$1\" କୁ ପୃଷ୍ଠା ଲିଙ୍କ",
        "whatlinkshere-page": "ପୃଷ୍ଠା:",
-       "linkshere-2": "ଏହି ପୃଷ୍ଠା ସବୁ  <strong>$1</strong> ସହ ଯୋଡ଼ା ଯାଇଅଛି:",
-       "nolinkshere-2": "'''$1''' ସହିତ କୌଣସିଟି ପୃଷ୍ଠା ଯୋଡ଼ାଯାଇନାହିଁ ।",
-       "nolinkshere-ns-2": "ବଛା ଯାଇଥିବା ନେମସ୍ପେସରେ '''$1''' ନାଆଁ ସହ କୌଣସି ବି ପୃଷ୍ଠା ଯୋଡ଼ାଯାଇନାହିଁ ।",
+       "linkshere": "ଏହି ପୃଷ୍ଠା ସବୁ  <strong>$2</strong> ସହ ଯୋଡ଼ା ଯାଇଅଛି:",
+       "nolinkshere": "'''$2''' ସହିତ କୌଣସିଟି ପୃଷ୍ଠା ଯୋଡ଼ାଯାଇନାହିଁ ।",
+       "nolinkshere-ns": "ବଛା ଯାଇଥିବା ନେମସ୍ପେସରେ '''$2''' ନାଆଁ ସହ କୌଣସି ବି ପୃଷ୍ଠା ଯୋଡ଼ାଯାଇନାହିଁ ।",
        "isredirect": "ଆଉଥରେ ଫେରିବା ପୃଷ୍ଠା",
        "istemplate": "ଆଧାର ସହ ଭିତରେ ରଖିବା",
        "isimage": "ଫାଇଲର ଲିଙ୍କ",
        "markedaspatrollederrornotify": "ଶ୍ରେଣୀବିଭାଗ କରିହେଲାନି ।",
        "patrol-log-page": "ଜଗିବା ଇତିହାସ",
        "patrol-log-header": "ଏହା ଏକ ଜଗାଯାଇଥିବା ସଂସ୍କରଣର ଇତିହାସ ।",
-       "log-show-hide-patrol": "$1 ଜଗିବା ଇତିହାସ",
        "deletedrevision": "ଲିଭାଯାଇଥିବା ପୁରୁଣା $1",
        "filedeleteerror-short": "ଫାଇଲ ଲିଭାଇବାରେ ଅସୁବିଧା: $1",
        "filedeleteerror-long": "ତଳଲିଖିତ ଫାଇଲକୁ ଲିଭାଇବାରେ ଅସୁବିଧା:\n\n$1",
index dea5c69..369e367 100644 (file)
        "whatlinkshere": "Чи æрвиты ардæм",
        "whatlinkshere-title": "Фæрстæ, кæдон æрвитынц ардæм: «$1»",
        "whatlinkshere-page": "Фарс:",
-       "linkshere-2": "Ацы фæрстæ æрвитынц '''$1''':",
-       "nolinkshere-2": "Никæцы фарс æрвиты ардæм: '''$1'''.",
-       "nolinkshere-ns-2": "Амынд номдоны мидæг никæцы фарс æрвиты ардæм <strong>$1</strong>.",
+       "linkshere": "Ацы фæрстæ æрвитынц '''$2''':",
+       "nolinkshere": "Никæцы фарс æрвиты ардæм: '''$2'''.",
+       "nolinkshere-ns": "Амынд номдоны мидæг никæцы фарс æрвиты ардæм <strong>$2</strong>.",
        "isredirect": "æрвитæн фарс",
        "istemplate": "æфтыдæй",
        "isimage": "файлмæ æрвитæн",
index af9527f..e9ed794 100644 (file)
@@ -26,7 +26,8 @@
                        "Tow",
                        "Sony dandiwal",
                        "Stephanecbisson",
-                       "Fitoschido"
+                       "Fitoschido",
+                       "Matěj Suchánek"
                ]
        },
        "tog-underline": "ਲਿੰਕ ਹੇਠ-ਲਾਈਨ:",
        "newpageletter": "ਨ",
        "boteditletter": "ਬੋਟ",
        "number_of_watching_users_pageview": "[$1 ਵੇਖ ਰਹੇ ਹਨ {{PLURAL:$1|ਯੂਜ਼ਰ}}]",
-       "rc-change-size-new": "$1 {{PLURAL:$|ਬਾਈਟ|ਬਾਈਟਾਂ}} ਤਬਦੀਲੀ ਤੋਂ ਬਾਅਦ",
+       "rc-change-size-new": "$1 {{PLURAL:$1|ਬਾਈਟ|ਬਾਈਟਾਂ}} ਤਬਦੀਲੀ ਤੋਂ ਬਾਅਦ",
        "newsectionsummary": "/* $1 */ ਨਵਾਂ ਭਾਗ",
        "rc-enhanced-expand": "ਵੇਰਵੇ ਵੇਖਾਓ",
        "rc-enhanced-hide": "ਵੇਰਵਾ ਲੁਕਾਓ",
        "whatlinkshere": "ਇੱਥੇ ਕੀ ਆ ਕੇ ਜੁੜਦਾ ਹੈ",
        "whatlinkshere-title": "$1 ਨਾਲ ਜੋੜਨ ਵਾਲੇ ਸਫ਼ੇ",
        "whatlinkshere-page": "ਸਫ਼ਾ:",
-       "linkshere-2": "ਇਹ ਪੰਨੇ '''$1''' ਨਾਲ ਜੋੜਦੇ ਹਨ:",
-       "nolinkshere-2": "ਕੋਈ ਵੀ ਸਫ਼ਾ '''$1''' ਨਾਲ ਨਹੀਂ ਜੋੜਦਾ।",
+       "linkshere": "ਇਹ ਪੰਨੇ '''$2''' ਨਾਲ ਜੋੜਦੇ ਹਨ:",
+       "nolinkshere": "ਕੋਈ ਵੀ ਸਫ਼ਾ '''$2''' ਨਾਲ ਨਹੀਂ ਜੋੜਦਾ।",
        "isredirect": "ਰੀਡਿਰੈਕਟ ਸਫ਼ਾ",
        "istemplate": "ਟਾਕਰਾ ਕਰੋ",
        "isimage": "ਫ਼ਾਈਲ ਲਿੰਕ",
index 4b23940..e9d6018 100644 (file)
        "whatlinkshere": "Deng pakasuglung keti",
        "whatlinkshere-title": "Deng bulung a makasuglung king \"$1\"",
        "whatlinkshere-page": "Bulung:",
-       "linkshere-2": "Pakasuglung la king '''$1''' deng makatuking bulung:",
-       "nolinkshere-2": "Alang bulung a makasuglung king '''$1'''.",
-       "nolinkshere-ns-2": "Alang bulung a makatuglung king '''$1''' ketang mepiling pirinan lagyu (namespace).",
+       "linkshere": "Pakasuglung la king '''$2''' deng makatuking bulung:",
+       "nolinkshere": "Alang bulung a makasuglung king '''$2'''.",
+       "nolinkshere-ns": "Alang bulung a makatuglung king '''$2''' ketang mepiling pirinan lagyu (namespace).",
        "isredirect": "Bulung ning pamanaliling direksiun",
        "istemplate": "misingit",
        "isimage": "Isuglung king larawan",
index ca5abff..9e3fddb 100644 (file)
        "whatlinkshere": "Cha lie quoé ichi",
        "whatlinkshere-title": "Paches qu'il ont des loïens aveuc \"$1\"",
        "whatlinkshere-page": "Pache:",
-       "linkshere-2": "Chés paches-lo il sont érliées à '''$1''':",
-       "nolinkshere-2": "i n'y o poin d'pache aveuc un loïen vers  '''$1'''.",
-       "nolinkshere-ns-2": "i n'y o poin d'pache aveuc un loïen vers '''$1''' dins echl'éspace d'noms coési.",
+       "linkshere": "Chés paches-lo il sont érliées à '''$2''':",
+       "nolinkshere": "i n'y o poin d'pache aveuc un loïen vers  '''$2'''.",
+       "nolinkshere-ns": "i n'y o poin d'pache aveuc un loïen vers '''$2''' dins echl'éspace d'noms coési.",
        "isredirect": "pache érdirigée",
        "istemplate": "transclusion",
        "isimage": "Loïen aveuc l'fichié",
index b421a6a..76c083e 100644 (file)
        "whatlinkshere": "Was dohea zaische dud",
        "whatlinkshere-title": "Saide wu uff \"$1\" valing'gn",
        "whatlinkshere-page": "Said:",
-       "linkshere-2": "Die Saide valing'gn uff '''$1''':",
-       "nolinkshere-2": "Kä Said zaischd uff '''$1'''.",
+       "linkshere": "Die Saide valing'gn uff '''$2''':",
+       "nolinkshere": "Kä Said zaischd uff '''$2'''.",
        "isredirect": "Waidalaidungsaid",
        "istemplate": "Vorlacheoibindung",
        "isimage": "Dadailing'g",
index 8158169..c5a4235 100644 (file)
@@ -98,7 +98,8 @@
                        "Anwar2",
                        "Acamicamacaraca",
                        "DeRudySoulStorm",
-                       "Railfail536"
+                       "Railfail536",
+                       "Vlad5250"
                ]
        },
        "tog-underline": "Podkreślenie linków:",
        "customcssprotected": "Nie jesteś uprawniony do edytowania tej strony CSS, ponieważ zawiera ona ustawienia osobiste innego użytkownika.",
        "customjsonprotected": "Nie jesteś uprawniony do edytowania tej strony JSON, ponieważ zawiera ona ustawienia osobiste innego użytkownika.",
        "customjsprotected": "Nie jesteś uprawniony do edytowania tej strony JavaScript, ponieważ zawiera ona ustawienia osobiste innego użytkownika.",
+       "sitecssprotected": "Nie masz uprawnień do edytowania tej strony CSS, ponieważ może to wpłynąć na wszystkich odwiedzających",
+       "sitejsonprotected": "Nie masz uprawnień do edytowania tej strony JSON, ponieważ może to wpłynąć na wszystkich odwiedzających",
+       "sitejsprotected": "Nie masz uprawnień do edytowania tej strony JavaScript, ponieważ może to wpłynąć na wszystkich odwiedzających",
        "mycustomcssprotected": "Nie masz uprawnień do edytowania tej strony CSS.",
        "mycustomjsonprotected": "Nie masz uprawnień do edytowania tej strony JSON.",
        "mycustomjsprotected": "Nie masz uprawnień do edytowania tej strony JavaScript.",
        "password-login-forbidden": "Wykorzystanie tej nazwy użytkownika lub hasła zostało zabronione.",
        "mailmypassword": "Zresetuj hasło",
        "passwordremindertitle": "Nowe tymczasowe hasło do {{GRAMMAR:D.lp|{{SITENAME}}}}",
-       "passwordremindertext": "Ktoś (prawdopodobnie Ty, spod adresu IP $1)\npoprosił o przesłanie nowego hasła do {{GRAMMAR:D.lp|{{SITENAME}}}} ($4).\nDla użytkownika „$2” zostało wygenerowane tymczasowe hasło i jest nim „$3”.\nJeśli było to zamierzone działanie, to po zalogowaniu się, musisz podać nowe hasło.\nTymczasowe hasło wygaśnie za {{PLURAL:$5|1 dzień|$5 dni}}.\n\nJeśli to nie Ty prosiłeś o przesłanie hasła lub przypomniałeś sobie hasło i nie chcesz go zmieniać, wystarczy, że zignorujesz tę wiadomość i dalej będziesz się posługiwać swoim dotychczasowym hasłem.",
+       "passwordremindertext": "Ktoś (z adresu IP $1) poprosił o przesłanie nowego hasła do {{GRAMMAR:D.lp|{{SITENAME}}}} ($4).\nDla użytkownika „$2” zostało wygenerowane tymczasowe hasło „$3”.\nJeśli było to zamierzone działanie, po zalogowaniu się, musisz podać nowe hasło.\nTymczasowe hasło wygaśnie za {{PLURAL:$5|1 dzień|$5 dni}}.\n\nJeśli to ktoś inny prosił o przesłanie hasła lub przypomniałeś sobie hasło i nie chcesz go zmieniać, wystarczy, że zignorujesz tę wiadomość i dalej będziesz się posługiwał swoim dotychczasowym hasłem.",
        "noemail": "Brak zdefiniowanego adresu e‐mail dla użytkownika „$1”.",
        "noemailcreate": "Musisz podać prawidłowy adres e‐mail",
        "passwordsent": "Nowe hasło zostało wysłane na adres e‐mail użytkownika „$1”.\nPo otrzymaniu go zaloguj się ponownie.",
        "botpasswords-restriction-failed": "Logowanie nie powiodło się z powodu ograniczeń na hasło bota.",
        "botpasswords-invalid-name": "Określona nazwa użytkownika nie zawiera separatora hasła bota (\"$1\").",
        "botpasswords-not-exist": "Użytkownik \"$1\" nie ma hasła dla bota o nazwie \"$2\".",
+       "botpasswords-needs-reset": "Hasło dla bota o nazwie „$2” {{GENDER:$1|użytkownika|użytkowniczki}} „$1” musi zostać zresetowane.",
        "resetpass_forbidden": "Hasła nie mogą zostać zmienione",
        "resetpass_forbidden-reason": "Hasła nie mogą zostać zmienione: $1",
        "resetpass-no-info": "Musisz być zalogowany, by uzyskać bezpośredni dostęp do tej strony.",
        "resetpass-temp-password": "Tymczasowe hasło:",
        "resetpass-abort-generic": "Zmiana hasła została przerwana przez rozszerzenie.",
        "resetpass-expired": "Twoje hasło wygasło. Proszę ustawić nowe hasło do logowania.",
-       "resetpass-expired-soft": "Twoje hasło wygasło i musi zostać zresetowane. Proszę wybrać nowe hasło albo kliknąć na „{{int:authprovider-resetpass-skip-label}}”, aby zresetować je później.",
-       "resetpass-validity-soft": "Twoje hasło jest niepoprawne: $1\n\nWybierz teraz nowe hasło albo kliknij „{{int:authprovider-resetpass-skip-label}}”, aby zresetować je później.",
+       "resetpass-expired-soft": "Twoje hasło wygasło i musi zostać zmienione. Wybierz nowe hasło albo kliknij na „{{int:authprovider-resetpass-skip-label}}”, aby zmienić je później.",
+       "resetpass-validity-soft": "Twoje hasło jest niepoprawne: $1\n\nWybierz nowe hasło albo kliknij „{{int:authprovider-resetpass-skip-label}}”, aby zmienić je później.",
        "passwordreset": "Wyczyść hasło",
        "passwordreset-text-one": "Wypełnij ten formularz, aby otrzymać tymczasowe hasło na email.",
        "passwordreset-text-many": "{{PLURAL:$1|Wypełnij jedno z poniższych pól, aby otrzymać tymczasowe hasło przez e-mail.}}",
        "expansion-depth-exceeded-warning": "Strona przekroczyła głębokość rozbudowy",
        "parser-unstrip-loop-warning": "Wykryto nieskończoną pętlę",
        "unstrip-depth-warning": "Przekroczono maksymalną głębokość zagnieżdżania ($1)",
+       "unstrip-depth-category": "Strony, które przekraczają limit zagnieżdżenia",
        "unstrip-size-warning": "Przekroczono maksymalną głębokość zagnieżdżania ($1)",
+       "unstrip-size-category": "Strony, które przekraczają dopuszczalny rozmiar dla funkcji unstrip",
        "converter-manual-rule-error": "Błąd w językowych regułach konwersji",
        "undo-success": "Edycja może zostać wycofana. Porównaj ukazane poniżej różnice między wersjami, a następnie zapisz zmiany.",
        "undo-failure": "Edycja nie może zostać wycofana z powodu konfliktu z wersjami pośrednimi.",
+       "undo-main-slot-only": "Zmiany nie można cofnąć, ponieważ dotyczy treści znajdujących się poza głównym wątkiem.",
        "undo-norev": "Edycja nie może być cofnięta, ponieważ nie istnieje lub została usunięta.",
        "undo-nochange": "Wygląda na to, że edycja została już anulowana.",
        "undo-summary": "Anulowanie wersji $1 autora [[Special:Contributions/$2|$2]] ([[User talk:$2|dyskusja]])",
        "diff-paragraph-moved-toold": "Akapit został przeniesiony. Kliknij aby przeskoczyć do jego poprzedniego położenia.",
        "difference-missing-revision": "{{PLURAL:$2|Wersja|$2 wersje|$2 wersji}} #$1 strony \"{{PAGENAME}}\" nie {{PLURAL:$2|została znaleziona|zostały znalezione|zostało znalezionych}}.\n\nZazwyczaj jest to spowodowane przestarzałym linkiem do usuniętej strony. Powód usunięcia znajduje się w [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} rejestrze].",
        "searchresults": "Wyniki wyszukiwania",
+       "search-filter-title-prefix": "Wyszukiwanie tylko na stronach, których tytuł zaczyna się od „$1”",
+       "search-filter-title-prefix-reset": "Przeszukaj wszystkie strony",
        "searchresults-title": "Wyniki wyszukiwania „$1”",
        "titlematches": "Znaleziono w tytułach",
        "textmatches": "Znaleziono w treści stron",
        "group-autoconfirmed": "Automatycznie zatwierdzeni użytkownicy",
        "group-bot": "Boty",
        "group-sysop": "Administratorzy",
+       "group-interface-admin": "Administratorzy interfejsu",
        "group-bureaucrat": "Biurokraci",
        "group-suppress": "Rewizorzy",
        "group-all": "(wszyscy)",
        "group-autoconfirmed-member": "{{GENDER:$1|automatycznie zatwierdzony użytkownik|automatycznie zatwierdzona użytkowniczka}}",
        "group-bot-member": "{{GENDER:$1|bot}}",
        "group-sysop-member": "{{GENDER:$1|administrator|administratorka}}",
+       "group-interface-admin-member": "{{GENDER:$1|administrator|administratorka}} interfejsu",
        "group-bureaucrat-member": "{{GENDER:$1|biurokrata|biurokratka}}",
        "group-suppress-member": "{{GENDER:$1|rewizor|rewizorka}}",
        "grouppage-user": "{{ns:project}}:Użytkownicy",
        "grouppage-autoconfirmed": "{{ns:project}}:Automatycznie zatwierdzeni użytkownicy",
        "grouppage-bot": "{{ns:project}}:Boty",
        "grouppage-sysop": "{{ns:project}}:Administratorzy",
+       "grouppage-interface-admin": "{{ns:project}}:Administratorzy interfejsu",
        "grouppage-bureaucrat": "{{ns:project}}:Biurokraci",
        "grouppage-suppress": "{{ns:project}}:Rewizorzy",
        "right-read": "Czytanie treści stron",
        "right-browsearchive": "Przeszukiwanie usuniętych stron",
        "right-undelete": "Odtwarzanie usuniętych stron",
        "right-suppressrevision": "Podgląd, ukrywanie i odkrywanie wersji ukrytych przed wszystkimi",
-       "right-viewsuppressed": "Umożliwia zobaczenie wersji ukrytych przed każdym użytkownikiem",
+       "right-viewsuppressed": "Podgląd wersji ukrytych przed każdym użytkownikiem",
        "right-suppressionlog": "Podgląd rejestru ukrywania",
        "right-block": "Blokowanie użytkownikom możliwości edycji",
        "right-blockemail": "Blokowanie użytkownikom możliwości wysyłania wiadomości",
        "right-editusercss": "Edycja plików CSS innych użytkowników",
        "right-edituserjson": "Edycja plików JSON innych użytkowników",
        "right-edituserjs": "Edycja plików JS innych użytkowników",
+       "right-editsitecss": "Edycja plików CSS projektu",
+       "right-editsitejson": "Edycja plików JSON projektu",
+       "right-editsitejs": "Edycja plików JavaScript projektu",
        "right-editmyusercss": "Edycja swoich plików CSS",
        "right-editmyuserjson": "Edycja swoich plików JSON",
        "right-editmyuserjs": "Edycja swoich plików JavaScript",
        "grant-createaccount": "Tworzenie kont",
        "grant-createeditmovepage": "Tworzenie, edycja i przenoszenie stron",
        "grant-delete": "Usuwanie stron, wersji stron i wpisów rejestru",
-       "grant-editinterface": "Edycja przestrzeni nazw MediaWiki oraz CSS/JSON/JavaScript użytkownika",
+       "grant-editinterface": "Edycja przestrzeni nazw MediaWiki oraz plików JSON projektu i innych użytkowników",
        "grant-editmycssjs": "Edycja swoich plików CSS/JSON/JavaScript",
        "grant-editmyoptions": "Edycja swoich preferencji",
        "grant-editmywatchlist": "Edycja listy obserwowanych",
+       "grant-editsiteconfig": "Edycja plików CSS i JS projektu i innych użytkowników",
        "grant-editpage": "Edycja istniejących stron",
        "grant-editprotected": "Edycja stron zabezpieczonych",
        "grant-highvolume": "Masowe edytowanie",
        "rcfilters-other-review-tools": "Inne narzędzia do sprawdzania",
        "rcfilters-group-results-by-page": "Grupuj wyniki według stron",
        "rcfilters-activefilters": "Aktywne filtry",
+       "rcfilters-activefilters-hide": "Ukryj",
+       "rcfilters-activefilters-show": "Pokaż",
+       "rcfilters-activefilters-hide-tooltip": "Ukryj obszar aktywnych filtrów",
+       "rcfilters-activefilters-show-tooltip": "Pokaż obszar aktywnych filtrów",
        "rcfilters-advancedfilters": "Zaawansowane filtry",
        "rcfilters-limit-title": "Wyników do pokazania",
        "rcfilters-limit-and-date-label": "$1 {{PLURAL:$1|zmiana|zmiany|zmian}}, $2",
        "rcfilters-empty-filter": "Brak aktywnych filtrów. Wyświetlane są wszystkie zmiany.",
        "rcfilters-filterlist-title": "Filtry",
        "rcfilters-filterlist-whatsthis": "Jak to działa?",
-       "rcfilters-filterlist-feedbacklink": "Napisz co sądzisz o tych nowych narzędziach filtrowania",
+       "rcfilters-filterlist-feedbacklink": "Napisz nam, co sądzisz o tych narzędziach filtrowania",
        "rcfilters-highlightbutton-title": "Podświetl wyniki",
        "rcfilters-highlightmenu-title": "Wybierz kolor",
        "rcfilters-highlightmenu-help": "Wybierz kolor, aby podświetlić tę właściwość",
        "rcfilters-watchlist-showupdated": "<strong>Wytłuszczono</strong> strony, których nie odwiedził{{GENDER:|e|a|e}}ś od czasu zapisania ostatnich zmian.",
        "rcfilters-preference-label": "Wyłącz ulepszenia strony Ostatnich zmian",
        "rcfilters-preference-help": "Wycofuje wszystkie zmiany interfejsu z 2017 i narzędzia dodane od tamtej pory.",
+       "rcfilters-watchlist-preference-label": "Ukryj ulepszoną wersję listy obserwowanych",
+       "rcfilters-watchlist-preference-help": "Wycofaj zmiany wyglądu interfejsu z 2017 i wszystkie narzędzia dodane wtedy i od tego czasu.",
        "rcfilters-filter-showlinkedfrom-label": "Pokaż zmiany na stronach linkowanych z",
        "rcfilters-filter-showlinkedfrom-option-label": "<strong>Strony linkowane z</strong> zaznaczonej strony",
        "rcfilters-filter-showlinkedto-label": "Pokaż zmiany na stronach linkujących do",
        "uploadstash-zero-length": "Plik ma zerowy rozmiar.",
        "invalid-chunk-offset": "Nieprawidłowe przesunięcie fragmentu",
        "img-auth-accessdenied": "Odmowa dostępu",
-       "img-auth-nopathinfo": "Brak PATH_INFO.\nSerwer nie został skonfigurowany, tak aby przekazywał tę informację.\nMożliwe, że jest oparty na CGI i nie może obsługiwać img_auth.\nWięcej o informacji o autoryzacji grafik na https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization.",
+       "img-auth-nopathinfo": "Brak informacji o ścieżce.\nSerwer musi być skonfigurowany tak, aby przekazywał zmienne REQUEST_URI lub PATH_INFO.\nJeżeli jest już odpowiednio skonfigurowany, spróbuj włączyć $wgUsePathInfo.\nWięcej o informacji o autoryzacji grafik na https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization.",
        "img-auth-notindir": "Żądana ścieżka nie jest w obrębie katalogu skonfigurowanego do przesyłania plików.",
        "img-auth-badtitle": "Nie można wygenerować prawidłowego tytuł z „$1”.",
        "img-auth-nologinnWL": "Nie jesteś zalogowany, a „$1” nie jest na białej liście.",
        "http-timed-out": "Przekroczony czas żądania HTTP.",
        "http-curl-error": "Błąd pobierania z adresu $1",
        "http-bad-status": "Wystąpił problem z realizacją żądania HTTP $1 $2",
+       "http-internal-error": "Błąd wewnętrzny HTTP.",
        "upload-curl-error6": "Adres URL jest nieosiągalny",
        "upload-curl-error6-text": "Podany adres URL jest nieosiągalny. Upewnij się, czy podany adres URL jest prawidłowy i czy dana strona jest dostępna.",
        "upload-curl-error28": "Upłynął limit czasu odpowiedzi",
        "speciallogtitlelabel": "Co (tytuł lub {{ns:user}}:nick użytkownika):",
        "log": "Rejestr operacji",
        "logeventslist-submit": "Pokaż",
+       "logeventslist-more-filters": "Pokaż dodatkowe rejestry:",
+       "logeventslist-patrol-log": "Rejestr patrolowania",
+       "logeventslist-tag-log": "Rejestr znaczników",
        "all-logs-page": "Wszystkie publiczne operacje",
        "alllogstext": "Wspólny rejestr wszystkich typów operacji dla {{GRAMMAR:D.lp|{{SITENAME}}}}.\nMożesz zawęzić liczbę wyników poprzez wybranie typu rejestru, nazwy użytkownika lub tytułu strony.",
        "logempty": "W rejestrze nie znaleziono pozycji odpowiadających zapytaniu.",
        "dellogpage": "Usunięte",
        "dellogpagetext": "Poniżej znajduje się lista ostatnio wykonanych usunięć.",
        "deletionlog": "rejestr usunięć",
+       "log-name-create": "Rejestr tworzenia stron",
+       "log-description-create": "Poniżej znajduje się lista ostatnio utworzonych stron.",
+       "logentry-create-create": "$1 {{GENDER:$2|utworzył|utworzyła|utworzył(a)}} stronę $3",
        "reverted": "Przywrócono poprzednią wersję",
        "deletecomment": "Powód:",
        "deleteotherreason": "Inny lub dodatkowy powód:",
        "uctop": "(ostatnia)",
        "month": "Do miesiąca (włącznie):",
        "year": "Do roku (włącznie):",
+       "date": "Od daty (i wcześniej):",
        "sp-contributions-newbies": "Pokazuj wyłącznie wkład nowych użytkowników",
        "sp-contributions-newbies-sub": "Dla nowych użytkowników",
        "sp-contributions-newbies-title": "Wkład nowych użytkowników",
        "whatlinkshere": "Linkujące",
        "whatlinkshere-title": "Strony linkujące do „$1”",
        "whatlinkshere-page": "Strona:",
-       "linkshere-2": "Następujące strony odwołują się do '''$1''':",
-       "nolinkshere-2": "Żadna strona nie odwołuje się do '''$1'''.",
-       "nolinkshere-ns-2": "Żadna strona nie odwołuje się do '''$1''' w wybranej przestrzeni nazw.",
+       "linkshere": "Następujące strony odwołują się do <strong>$2</strong>:",
+       "nolinkshere": "Żadna strona nie odwołuje się do <strong>$2</strong>.",
+       "nolinkshere-ns": "Żadna strona nie odwołuje się do <strong>$2</strong> w wybranej przestrzeni nazw.",
        "isredirect": "strona przekierowująca",
        "istemplate": "dołączony szablon",
        "isimage": "link do pliku",
        "pageinfo-category-subcats": "Liczba podkategorii",
        "pageinfo-category-files": "Liczba plików",
        "pageinfo-user-id": "ID użytkownika",
+       "pageinfo-file-hash": "Wartość skrótu",
        "markaspatrolleddiff": "oznacz edycję jako „sprawdzoną”",
        "markaspatrolledtext": "Oznacz tę stronę jako „sprawdzoną”",
        "markaspatrolledtext-file": "Oznacz tę wersję pliku jako „sprawdzoną”",
        "markedaspatrollederrornotify": "Oznaczenie strony jako sprawdzonej nie powiodło się.",
        "patrol-log-page": "Rejestr patrolowania",
        "patrol-log-header": "Poniżej znajduje się rejestr patrolowania stron.",
-       "log-show-hide-patrol": "$1 rejestr sprawdzania",
-       "log-show-hide-tag": "$1 rejestr znaczników",
        "confirm-markpatrolled-button": "OK",
        "confirm-markpatrolled-top": "Oznaczyć wersję $3 strony $2 jako sprawdzoną?",
        "deletedrevision": "Usunięto poprzednie wersje $1",
        "version-specialpages": "Strony specjalne",
        "version-parserhooks": "Haki analizatora składni (ang. parser hooks)",
        "version-variables": "Zmienne",
-       "version-editors": "Edytorzy",
+       "version-editors": "Edytory",
        "version-antispam": "Ochrona przed spamem",
        "version-other": "Pozostałe",
        "version-mediahandlers": "Wtyczki obsługi mediów",
        "logentry-protect-modify-cascade": "$1 {{GENDER:$2|zmienił|zmieniła|zmienił(a)}} poziom zabezpieczenia dla $3 $4 [kaskadowo]",
        "logentry-rights-rights": "$1 {{GENDER:$2|zmienił|zmieniła|zmienił(a)}} przynależność {{GENDER:$6|$3}} do grupy z $4 do $5",
        "logentry-rights-rights-legacy": "$1 {{GENDER:$2|zmienił|zmieniła}} przynależność $3 do grup",
-       "logentry-rights-autopromote": "$1 automatycznie {{GENDER:$2|zmienił|zmieniła}} przynależność ($4 → $5)",
+       "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-tag-update-remove-logentry": "$1 {{GENDER:$2|usunął|usunęła}} {{PLURAL:$9|znacznik|znaczniki}} $8 z wpisu w rejestrze $5 strony $3",
        "logentry-tag-update-revision": "$1 {{GENDER:$2|zmienił|zmieniła}} znaczniki w wersji $4 strony $3 ({{PLURAL:$7|dodano}} $6; {{PLURAL:$9|usunięto}} $8)",
        "logentry-tag-update-logentry": "$1 {{GENDER:$2|zmienił|zmieniła}} znaczniki we wpisie w rejestrze $5 strony $3 ({{PLURAL:$7|dodano}} $6; {{PLURAL:$9|usunięto}} $8)",
-       "rightsnone": "brak",
+       "rightsnone": "(brak)",
        "rightslogentry-temporary-group": "$1 (tymczasowo, do $2)",
        "feedback-adding": "Dodawanie opinii do strony...",
        "feedback-back": "Wstecz",
        "limitreport-templateargumentsize-value": "$1/$2 {{PLURAL:$2|bajt|bajty|bajtów}}",
        "limitreport-expansiondepth": "Największa głębokość ekspansji",
        "limitreport-expensivefunctioncount": "Liczba wywołań kosztownych funkcji parsera",
+       "limitreport-unstrip-depth": "Głębokość rekurencji funkcji unstrip",
+       "limitreport-unstrip-size": "Rozmiar dla funkcji unstrip po rozwinięciu",
        "limitreport-unstrip-size-value": "$1/$2 {{PLURAL:$2|bajt|bajty|bajtów}}",
        "expandtemplates": "Rozwijanie szablonów",
        "expand_templates_intro": "We wprowadzonym na tej stronie tekście źródłowym zostaną rozwinięte rekurencyjnie wszystkie szablony.\nRozwinięte także zostaną funkcje parsera takie jak\n<code><nowiki>{{</nowiki>#language:…}}</code> i zmienne jak\n<code><nowiki>{{</nowiki>CURRENTDAY}}</code>.\nW zasadzie rozwijane jest prawie wszystko w podwójnych nawiasach klamrowych.",
        "passwordpolicies-policy-minimalpasswordlength": "Hasło musi mieć co najmniej $1 {{PLURAL:$1|znak|znaki|znaków}}",
        "passwordpolicies-policy-minimumpasswordlengthtologin": "Aby się zalogować, hasło musi mieć co najmniej $1 {{PLURAL:$1|znak|znaki|znaków}}",
        "passwordpolicies-policy-passwordcannotmatchusername": "Hasło nie może być takie samo jak nazwa użytkownika",
-       "passwordpolicies-policy-maximalpasswordlength": "Hasło musi mieć mniej niż $1 {{PLURAL:$1|znak|znaki|znaków}}"
+       "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ł}}"
 }
index 5a88383..f837484 100644 (file)
@@ -19,7 +19,8 @@
                        "Macofe",
                        "Matma Rex",
                        "Fitoschido",
-                       "Paolo Castellina"
+                       "Paolo Castellina",
+                       "Matěj Suchánek"
                ]
        },
        "tog-underline": "Anliure con la sotliniadura",
        "page_first": "prima",
        "page_last": "ùltima",
        "histlegend": "Confront antra version diferente: che as selession-a le casele dle version che a veul e peui che a sgnaca ël boton për anandié ël process.<br />\nLegenda: (cor) = diferense con la version corenta,\n(prim) = diferense con la version prima, c = modìfica cita",
-       "history-fieldset-title": "Varda la cronologìa",
+       "history-fieldset-title": "Sërché dle revision",
        "history-show-deleted": "Mach ëscancelà",
        "histfirst": "ij pì vej",
        "histlast": "ij pì recent",
        "searchprofile-advanced-tooltip": "Sërché ant jë spassi nominaj përsonalisà",
        "search-result-size": "$1 ({{PLURAL:$2|un|$2}} mòt)",
        "search-result-category-size": "{{PLURAL:$1|1 mèmber|$1 mèmber}} ({{PLURAL:$2|1 sot-categorìa|$2 sot-categorìe}}, {{PLURAL:$3|1 archivi|$3 archivi}})",
-       "search-redirect": "(ridiression $1)",
+       "search-redirect": "(ridiression da $1)",
        "search-section": "(session $1)",
        "search-category": "(categorìa $1)",
        "search-file-match": "(a corëspond al contnù d'archivi)",
        "recentchangeslinked-feed": "Modìfiche colegà",
        "recentchangeslinked-toolbox": "Modìfiche colegà",
        "recentchangeslinked-title": "Modìfiche ch'a-i intro con \"$1\"",
-       "recentchangeslinked-summary": "Costa a l'é na lista ëd modìfiche fàite da pòch a pàgine colegà a cola spessificà (o a mèmber ëd na categorìa spessificà).\nLe pàgine dzora a [[Special:Watchlist|la lista ëd lòn ch'as ten sot-euj]] a resto marcà an '''grassèt'''.",
+       "recentchangeslinked-summary": "Scrive un nòm ëd na pàgina për vëdde ij cangiament an s'ëd pàgine colegà vers o da cola pàgina. (Për vëdde ij mèmber ëd na categorìa, ch'a scriva {{ns:category}}:Nòm ëd categorìa). Ij cangiament a dle pàgine dla [[Special:Watchlist|ròba ch'as ten sot-euj]] a son an <strong>grassèt</strong>.",
        "recentchangeslinked-page": "Nòm ëd la pàgina:",
        "recentchangeslinked-to": "Mostré nopà le modìfiche a le pàgine colegà a cola dàita",
        "upload": "Carié n'archivi",
        "largefileserver": "St'archivi-sì a resta pì gròss che lòn che la màchina sentral a përmet.",
        "emptyfile": "L'archivi che a l'ha pen-a carià a smija veujd.\nSòn a podrìa esse rivà përchè che chiel a l'ha scrivù mal ël nòm dl'archivi midem.\nPër piasì che a contròla se a l'é pro cost l'archivi che a veul carié.",
        "windows-nonascii-filename": "Sta wiki-sì a manten pa ij nòm d'archivi con caràter speciaj.",
-       "fileexists": "N'archivi con ës nòm-sì a-i é già, për piasì che a contròla <strong>[[:$1]]</strong> se {{GENDER|a}} l'é pa sigur dë vorèj cangelo.\n[[$1|thumb]]",
+       "fileexists": "N'archivi con ës nòm-sì a-i é già, për piasì che a contròla <strong>[[:$1]]</strong> se {{GENDER:|a}} l'é pa sigur dë vorèj cangelo.\n[[$1|thumb]]",
        "filepageexists": "La pàgina ëd descrission për st'archivi-sì a l'é già stàita creà an <strong>[[:$1]]</strong>, mach ch'a-i é gnun archivi ch'as ciama parèj.\nLòn ch'a buta për somari as ës-ciairerà nen ant la pàgina ëd descrission.\nPër podèj buté sò somari a l'ha da modifichesse la pàgina a man.\n[[$1|thumb]]",
        "fileexists-extension": "N'archivi con ës nòm-sì a-i é già: [[$2|thumb]]\n* Nòm dl'archivi ch'as carìa: <strong>[[:$1]]</strong>\n* Nòm dl'archivi ch'a-i é già: <strong>[[:$2]]</strong>\nVeul-lo dle vire dovré un nòm pi esplìssit?",
        "fileexists-thumbnail-yes": "L'archivi a jë smija a na ''figurin-a''. [[$1|thumb]]\nPër piasì, ch'a contròla l'archivi <strong>[[:$1]]</strong>.\nS'a l'é la midema figura a amzura pijn-a, a veul dì ch'a fa nen dë manca dë carié na figurin-a.",
        "booksources-text": "Ambelessì sota a-i é na lista d'àotri sit che a vendo dij lìber neuv e dë sconda man, e che a peulo ëdcò smon-e dj'anformassion rësgoard ai test che a l'é antramentr che a sërca:",
        "booksources-invalid-isbn": "L'ISBN dàit a smija che a sia pa vàlid; ch'a contròla s'a-i é n'eror an copiand da la sorgiss original.",
        "specialloguserlabel": "Esecutor:",
-       "speciallogtitlelabel": "Obietiv (tìtol o utent):",
+       "speciallogtitlelabel": "Obietiv (tìtol o {{ns:user}}:stranòm ëd l'utent):",
        "log": "Registr",
        "all-logs-page": "Tùit ij registr pùblich",
        "alllogstext": "Visualisassion combinà ëd tùit ij registr ëd {{SITENAME}}.\nA peul arstrenze la visualisassion an selessionand la sòrt ëd registr, lë stranòm utent (sensìbil a majùscol/minùscol), e la pàgina anteressà (sensìbil a majùscol/minùscol).",
        "unwatchthispage": "Chité-lì ëd ten-e sossì sot-euj",
        "notanarticle": "Sòn a l'é pa n'artìcol",
        "notvisiblerev": "La revision a l'é stàita scancelà",
-       "watchlist-details": "A l'é dëmentrè ch'as ten sot-euj {{PLURAL:$1|$1 pàgina|$1 pàgine}}, nen contand an manera separà cole ëd discussion.",
+       "watchlist-details": "La lista 'd lòn ch'as ten sot-euj {{PLURAL:$1|$1 pàgina|$1 pàgine}}, nen contand an manera separà cole ëd discussion.",
        "wlheader-enotif": "La notìfica për pòsta eletrònica a l'é abilità.",
        "wlheader-showupdated": "Le pàgine che a son ëstàite modificà da quand che a l'é passaje ansima l'ùltima vira a resto marcà an '''grassèt'''",
        "wlnote": "Ambelessì sota a-i {{PLURAL:$1|é l'ùltima modìfica|son j'ùltime <strong>$1</strong> modìfiche}} ant {{PLURAL:$2|l'ùltima ora|j'ùltime <strong>$2</strong> ore}}, a parte da $3, $4.",
        "whatlinkshere": "Pàgine con dj'anliure che a men-o a costa-sì",
        "whatlinkshere-title": "Pàgine ch'a men-o a «$1»",
        "whatlinkshere-page": "Pàgina:",
-       "linkshere-2": "Le pàgine sì-sota a l'han andrinta dj'anliure che a men-o a '''$1''':",
-       "nolinkshere-2": "A-i é pa gnun-a pàgina che a l'abia dj'anliure che a men-o a '''$1'''.",
-       "nolinkshere-ns-2": "An cost ëspassi nominal-sì a-i é gnun-e pàgine con dj'anliure ch'a men-o a '''$1'''.",
+       "linkshere": "Le pàgine sì-sota a l'han andrinta dj'anliure che a men-o a '''$2''':",
+       "nolinkshere": "A-i é pa gnun-a pàgina che a l'abia dj'anliure che a men-o a '''$2'''.",
+       "nolinkshere-ns": "An cost ëspassi nominal-sì a-i é gnun-e pàgine con dj'anliure ch'a men-o a '''$2'''.",
        "isredirect": "ridiression",
        "istemplate": "inclusion",
        "isimage": "anliura a l'archivi",
        "whatlinkshere-hideredirs": "$1 ridiression",
        "whatlinkshere-hidetrans": "$1 anclusion",
        "whatlinkshere-hidelinks": "$1 anliure",
-       "whatlinkshere-hideimages": "$1 j'archivi lijà",
+       "whatlinkshere-hideimages": "$1 liure da archivi",
        "whatlinkshere-filters": "Filtr",
        "autoblockid": "Blocagi automàtich #$1",
        "block": "Bloché l'utent",
        "tooltip-feed-rss": "Fluss RSS për costa pàgina",
        "tooltip-feed-atom": "Fluss Atom për costa pàgina.",
        "tooltip-t-contributions": "Vardé la lista dle contribussion ëd {{GENDER:$1|cost utent}}",
-       "tooltip-t-emailuser": "Mandeje un mëssagi ëd pòsta a st'utent",
+       "tooltip-t-emailuser": "Mandé 'n mëssaggi ëd pòsta eletrònica a {{GENDER:$1|cost|cost}} utent",
        "tooltip-t-info": "Pi d'anformassio su costa pàgina",
        "tooltip-t-upload": "Carié n'archivi ëd figure ò son.",
        "tooltip-t-specialpages": "Lista ëd tute le pàgine speciaj.",
        "markedaspatrollederrornotify": "Marcadura com verificà falìa.",
        "patrol-log-page": "Registr dij contròj",
        "patrol-log-header": "Cost-sì a l'é un registr ëd le revision controlà.",
-       "log-show-hide-patrol": "$1 registr verificà",
-       "log-show-hide-tag": "tichëtta d'argistr $1",
        "deletedrevision": "Veja version scancelà $1",
        "filedeleteerror-short": "Eror ën scanceland l'archivi: $1",
        "filedeleteerror-long": "A-i son ësta-ie dj'eror ën scanceland l'archivi:\n\n$1",
        "version-libraries": "Biblioteche anstalà",
        "version-libraries-library": "Biblioteca",
        "version-libraries-version": "Version",
-       "redirect": "Ridirigiù da archivi, utent, pàgina o ID ëd revision",
+       "redirect": "Ridiression për ID d'archivi, utent, pàgina, revision o argistr",
        "redirect-summary": "Costa pàgina special a ponta a n'archivi (dàit ël nòm dl'archivi), na pàgina (dàit n'ID ëd revision o n'ID ëd pàgina) o na pàgina d'utent (dàit n'identificativ numérich a l'utent). Usagi: [[{{#Special:Redirect}}/file/Example.jpg]], [[{{#Special:Redirect}}/revision/328429]], o [[{{#Special:Redirect}}/user/101]].",
        "redirect-submit": "Andé",
        "redirect-lookup": "Arserca:",
        "feedback-thanks": "Mersì! Sò coment a l'é stàit publicà an sla pàgina \"[$2 $1]\".",
        "feedback-thanks-title": "Mersì!",
        "feedback-useragent": "Agent d'utent:",
-       "searchsuggest-search": "Arserché",
+       "searchsuggest-search": "Sërca an {{SITENAME}}",
        "searchsuggest-containing": "contenent ...",
        "api-error-badtoken": "Eror antern: sìmbol pa bon.",
        "api-error-emptypage": "La creassion ëd pàgine neuve veujde a l'é nen përmëttùa.",
index 4519eca..449de37 100644 (file)
        "oct": "اکتوبر",
        "nov": "نومبر",
        "dec": "دسمبر",
-       "january-date": "جنوری",
+       "january-date": "جنوری $1",
        "february-date": "فروری $1",
        "march-date": "مارچ $1",
        "april-date": "اپریل $1",
        "talk": "گل بات",
        "views": "وکھالے",
        "toolbox": "سَند",
+       "tool-link-emailuser": "اس {{GENDER:$1|ورتن والے}} نوں ای میل کرو",
        "imagepage": "فائل آلا صفہ ویکھو",
        "mediawikipage": "سنیعا آلا صفحہ ویکھو",
        "templatepage": "سچے آلا صفحہ ویکھو",
        "jumptonavigation": "پاندھ",
        "jumptosearch": "کھوج",
        "view-pool-error": "$1",
+       "generic-pool-error": "معاف کرو، اس ویلے سرور کم نہیں کر رہے۔\nاس چیز نوں اس ویلے بہت زیادہ ورتن والے ویکھن دی کوشش کر رہے ہیں۔\nاس چیز نوں دوبارہ دیکھن دی کوشش کرن تو پہلاں تھوڑی دیر انتظار کرو۔",
        "pool-timeout": "تالے لئی انتظار",
        "pool-queuefull": "چنوتی کرن ل‏ئی بندے پورے نیں۔",
        "pool-errorunknown": "انجان غلطی",
        "hidetoc": "چھپاؤ",
        "collapsible-collapse": "لُکاؤ",
        "collapsible-expand": "ودھاؤ",
+       "confirmable-confirm": "کیا {{GENDER:$1|توانوں}} پورا یقین ہے؟",
+       "confirmable-yes": "ہاں",
        "confirmable-no": "نئیں",
        "thisisdeleted": "$1 ویکھو یا واپس لاؤ",
-       "viewdeleted": "ویکھو 1$ ؟",
+       "viewdeleted": "$1 ویکھنیاں ہن؟",
        "restorelink": "{{PLURAL:$1|اک مٹائی گئی تبدیلی|1$ مٹائیاں گئیاں تبدیلیاں}}",
        "feedlinks": "دسو:",
        "feed-invalid": "ناں منی جان والی سبسکرپشن فیڈ ٹائپ",
        "perfcachedts": "تھلے دتا گیا ڈیٹا کاشیڈ اے تے  $1 نوں نواں کیتا گیا۔ زیادہ توں زیادہ {{PLURAL:$4|اک نتیجہ ہووے|$4 نتیجے ہوون}} نتیجے کاشے چ ہیگے نیں .",
        "querypage-no-updates": "اس صفحے نوں اپڈیٹ فلحال نئیں کیتا جا سکدا۔\nایدا مال ہلے نواں نئیں کیتا جاۓ گا۔",
        "viewsource": "ویکھو",
-       "viewsource-title": "1 لئی سورس ویکھو",
+       "viewsource-title": "$1 لئی سورس ویکھو",
        "actionthrottled": "اے کم کئی واری کیتا گیا اے",
-       "actionthrottledtext": "سپاÙ\85 Ø±Ù\88Ú© Ú©Ù\85 Ù\84ئÛ\8cØ\8c ØªÙ\88اÙ\86Ù\88Úº Ø§Û\8cس Ú©Ù\85 ØªÙ\88Úº Ú©Ø¦Û\8c Ù\88ارÛ\8c Ø§Ú© ØªÚ¾Ù\88Ú\91Û\92 Ù\88Û\8cÙ\84Û\92 Ú\86 Ø±Ù\88Ú©Û\8cا Ú¯Û\8cا Ø§Û\92  Ù¾Ø± ØªØ³Ø§Úº Ø§Ù¾Ù\86Û\8c Ø­Ø¯ ØªÙ\88Úº Ø§Ú¯Û\92 Ù\88دÛ\92Û\94 \nÙ\85Û\81رباÙ\86Û\8c Ú©Ø±Ú©Û\92 ØªÚ¾Ù\88Ú\91Û\92 Ú\86ر Ù\85گرÙ\88Úº  فیر کوشش کرنا۔",
+       "actionthrottledtext": "خراب Ø±Ù\88Ú© Ú©Ù\85 Ù\84ئÛ\8cØ\8c ØªÙ\88اÙ\86Ù\88Úº Ø§Û\8cس Ú©Ù\85 ØªÙ\88Úº Ú©Ø¦Û\8c Ù\88ارÛ\8c Ø§Ú© ØªÚ¾Ù\88Ú\91Û\92 Ù\88Û\8cÙ\84Û\92 Ú\86 Ø±Ù\88Ú©Û\8cا Ú¯Û\8cا Ø§Û\92 Ù¾Ø± ØªØ³Ø§Úº Ø§Ù¾Ù\86Û\8c Ø­Ø¯ ØªÙ\88Úº Ø§Ú¯Û\92 Ù\88دÛ\92Û\94 \nÙ\85Û\81رباÙ\86Û\8c Ú©Ø±Ú©Û\92 ØªÚ¾Ù\88Ú\91Û\92 Ú\86ر Ù\85گرÙ\88Úº فیر کوشش کرنا۔",
        "protectedpagetext": "اس صفحے دے اتے تبدیلی کرن نوں روکیا گیا اے۔",
        "viewsourcetext": "تسی اس صفحے دی لکھائی نوں ویکھ تے نقل کر سکدے او:",
        "viewyourtext": "تسیں آپنی تبدیلیاں دا ذریعہ ایس صفے تے ویکھ تے کاپی کرسکدے او۔",
        "virus-badscanner": "غلط تریقہ کار: انجان وائرس کھوجی: ''$1''",
        "virus-scanfailed": "کھوج نا ہوسکی (کوڈ $1)",
        "virus-unknownscanner": "اندیکھا اینٹیوائرس:",
-       "logouttext": "'''تسی لاگ آؤٹ ہوگۓ او.'''\nتسی   {{SITENAME}} نوں گمنامی چ ورت سکدے او یا تسی <span class='plainlinks'>[$1 لاگ ان دوبارہ]</span> ہوجاؤ اوسے ناں توں یا وکھرے ورتن والے توں۔ اے گل چیتے رکھنا جے کج صفیاں تے تسی لاگ ان دسے جاؤگے جدوں تک تسی اپنے براؤزر دے کاشے نوں صاف ناں کرلو۔\nYou can continue to use {{SITENAME}} anonymously, or you can <span class='plainlinks'>[$1 log in again]</span> as the same or as a different user.\nNote that some pages may continue to be displayed as if you were still logged in, until you clear your browser cache.",
+       "logouttext": "</strong>ہن تسی لاگ آؤٹ ہوگۓ او۔</strong>\n\nدھیان دیو کہ جدوں تک تسی اپنے براؤزر دا کیش صاف نہیں کردے، کجھ صفے ایداں ویکھائی دے سکدے ہن کہ جویں تسی اجے وی لگانا ہی ہو۔",
+       "welcomeuser": "جی آیاں نوں، $1!",
        "yourname": "ورتن والہ:",
        "userlogin-yourname": "ورتن ناں",
        "userlogin-yourname-ph": "اپنا ورتن ناں لکھو",
        "createaccount": "کھاتہ بناؤ",
        "userlogin-resetpassword-link": "اپنی کنجی بھل گۓ او؟",
        "userlogin-helplink2": "لاگ ان ہون وچ ہتھ ونڈائی",
+       "createacct-emailrequired": "ای میل پتہ",
        "createacct-emailoptional": "ای-میل پتہ (مرضی نال)",
        "createacct-email-ph": "اپنا ای-میل پتہ دیؤ",
+       "createacct-another-email-ph": "ای میل پتہ دیو",
        "createaccountmail": "ای میل دے نال",
+       "createacct-realname": "اصل ناں (اختیاری)",
        "createacct-reason": "وجہ",
        "createacct-reason-ph": "تسیں اک ہور کھاتہ کیوں بنا رہے او",
        "createacct-submit": "اپنا کھاتا کھولو",
+       "createacct-another-submit": "کھاتہ بناؤ",
        "createacct-benefit-heading": "پنجابی وکی نوں تواڈے ورگے لوکاں نے بنایا اے۔",
        "createacct-benefit-body1": "$1 {{PLURAL:$1|تبدیلی|تبدیلیاں}}",
        "createacct-benefit-body2": "{{PLURAL:$1|صفہ|صفے}}",
        "nosuchusershort": "اس \"$1\" ناں دا کوئی ورتن آلا نہيں اے۔\n\nاپنی الف، بے چیک کرو۔",
        "nouserspecified": "توانوں اپنا ورتن آلا ناں دسنا ہوۓ گا۔",
        "login-userblocked": "اے ورتن آلے روکیا ہویا اے۔ اے لاگ ان نئیں کرسکدا۔",
-       "wrongpassword": "تواڈی کنجی ٹھیک نہیں۔<br />\nفیر ٹرائی مارو۔",
+       "wrongpassword": "تواڈی کنجی یا ورتن ناں ٹھیک نہیں۔<br />\nفیر کوشش کرو۔",
        "wrongpasswordempty": "تواڈی کنجی کم نہیں کر رہی۔<br />\nفیر ٹرائی مارو۔",
        "passwordtooshort": "کنجی کم از کم {{PLURAL:$1|1 ہندسے|$1 ہندسیاں}} دی ہونی چائیدی اے۔",
        "password-name-match": "کنجی ورتن ناں توں مختلف ہونی چائیدی اے۔",
        "password-login-forbidden": "اس ورتن ناں یا کنجی دا ورتن تے پابندی اے۔",
-       "mailmypassword": "نئی کنجی ای میل کرو",
+       "mailmypassword": "کنجی سیٹ کرو",
        "passwordremindertitle": "{{SITENAME}} لئی نوی عارضی کنجی",
        "passwordremindertext": "کسے نے (غالبن تسی $1 آئی پی پتے توں) نوی کنجی ($4) {{SITENAME}} واسطے منگی۔ اک عارضی کنجی ورتن والے \"$2\" دے لئی بنائی گئی سی تے \"$3\" تے سیٹ کر دتی گئی سی۔ اگر اے تواڈا کم اے تے توانوں اندر آکے اک  نویں  کنجی چننی پۓ گی۔ تواڈی کچی\n کنجی {{PLURAL:$5|اک دن|$5 دناں}} چ مک جائیگی۔\nاگر کسے ہور نے اے درخواست کیتی اے یا تسی اپنی پرانی کنجی لب لئی اے تے تسی اینوں بدلنا نئیں چاندے تے تسی اس سنعے نوں چھڈو تے پرانی کنجی استعمال کرو۔",
        "noemail": "اس ورتن والے \"$1\" دا کوئی ای میل پتہ نئیں ہے گا۔",
        "passwordreset-emailtext-user": "ورتنوالے $1 نے {{سائیٹناں}} تے تواڈے کھاتے بارے پچھیا اے {{SITENAME}} لئی ($4)۔ تھلے دتا گیا ورتن {{PLURAL:$3|کھاتہ|کھاتے}} ایس ای-میل نال جڑدا اے۔\n\n$2\n\n{{PLURAL:$3|ایہ عارضی کنجی|اے عارضی کنجیاں}} مک جائیگا {{PLURAL:$5|اک دن|$5 دن}}۔ تسیں ہن لاکان ہوو تے نویں کنجی چنو۔ اگر کسے ہور نے اے چٹھی پیجی یا توانوں اپنی پہلی کنجی یاد آگئی اے تے تسیں اونوں بدلنا نئیں چاندے تے تسیں ایس سنیعے نوں پھل جاؤ تے پرانی کنجی نال ای کم چلاؤ۔",
        "passwordreset-emailelement": "ورتن ناں: \n$1\n\nعارضی کنجی: \n$2",
        "passwordreset-emailsentemail": "یاد کران واسطے اک ای-میل بھیج دتی گئی اے۔",
-       "changeemail": "ای-میل پتہ بدلو",
+       "changeemail": "ای-میل پتہ بدلو یا ہٹاؤ",
        "changeemail-header": "کھاتے دا ای-میل پتہ بدلو",
        "changeemail-no-info": "تسی لاگ ان ہوکے ای اس صفحے نوں ویکھ سکدے او۔",
        "changeemail-oldemail": "ہلے دا ای-میل پتہ:",
        "sig_tip": "تواڈے دستخط ویلے دے نال",
        "hr_tip": "سدھی لکیر",
        "summary": "ویروا:",
-       "subject": "موضوع/شہ سرخی:",
+       "subject": "موضوع:",
        "minoredit": "اے نکا جیا کم اے",
        "watchthis": "اس صفے تے اکھ رکھو",
        "savearticle": "کم بچاؤ",
        "savechanges": "کم بچاؤ",
+       "publishpage": "صفہ چھاپو",
+       "savearticle-start": "صفہ بچاؤ…",
+       "savechanges-start": "کم بچاؤ…",
+       "publishpage-start": "صفہ چھاپو…",
+       "publishchanges-start": "کم چھاپو…",
        "preview": "وکھاؤ",
        "showpreview": "کچا کم ویکھو",
        "showdiff": "تبدیلیاں وکھاؤ",
        "missingcommenttext": "تھلے اپنی گل لکھو۔",
        "missingcommentheader": "'''یادکرائی:''' تساں ایس گل تے سرخی / سرناواں نئیں دتا۔\nاگر تسیں  \"$1\" دوبارہ کلک کردے اوہ تواڈی تبدیلی اک توں بنا بچاۓ گا۔",
        "summary-preview": "کچے کم دا خلاصہ:",
-       "subject-preview": "سرناواں / سرخی وکھالہ:",
+       "subject-preview": "موضوع دا کچا کم:",
        "blockedtitle": "ورتن آلے نوں روکیا ہویا اے",
        "blockedtext": "تواڈا ورتن والا ناں یا فیر آئی پی ایڈریس روک دتا گیا اے۔'''\n\nتوانوں $1 نے روکیا اے۔<br />\nایدی وجہ ''$2'' اے۔\n\n* رکوائی دی پہل:$8\n* رکوائی دا انت:$6\n* روکیا جان آلا:$7\n\nتسی $1 نال مل ملسکدے او یا اک ہور [[{{MediaWiki:Grouppage-sysop}}|ایڈمنسٹریٹر]] نال روک دے بارے چ گل بات کر سکدے او۔<br />\nتسی اس ورتن آلے نوں ای میل نئیں کر سکدے جدوں تک توانوں [[Special:Preferences|account preferences]] کوئی ای میل ایڈریس نا دتا جاۓ تے توانوں اس دے استعمال توں روکیا نا گیا ہوۓ۔\nتواڈا موجودہ آئی پی پتہ $3 اے تے روکی گئی آئی ڈی #$5 اے۔\nمہربانی کر کے کوئی وی سوال جواب کرن آسطے اتے دتیاں گئیاں تفصیلات ضرور دیو۔",
        "autoblockedtext": "تواڈا آئی پی پتہ  اپنے آپ روک دتا گیا جے کیوں جے اینوں اک ہور ورتن والا ورت ریا سی۔ جینوں $1 نے روک دتا اے۔\nوجہ ایہ دتی کئی اے:\n\n:''$2''\n*روک دا شروع: $8\n*روک دا مکن: $6\n* روکے گۓ:$7\n\nتسیں $1 نال گل کرو یا کسے [[{{MediaWiki:Grouppage-sysop}}|administrators]] مکھۓ نال روک تے گل کرو۔\n\nایہ گل یاد رکھو جے تسیں \"ایس ورتن والے نوں ای-میل کرو\" والا فیخر نئیں ورت سکدے جدوں تک تواڈے کول اک پکا ای-میل پتہ [[Special:Preferences|user preferences]] تے جینوں ورتن تے  روک ناں لگی ہووے۔\nتھواڈا ہن دا آئی پی پتہ $3 اے تے روکی آئی ڈی #$5۔\nکسے وی سوال جواب لئي اوپر دسیاں گلاں وی شامل کرو۔",
        "edit-no-change": "تواڈی تبدیلی ول کوئی توجہ نئیں، کیوں جے لکھت چ کوئی تبدیلی نئیں۔",
        "edit-already-exists": "نواں صفہ نئیں بن سکدا۔\nایہ پہلے ای ہیگا اے۔",
        "editwarning-warning": "اے صفے توں جان تے ہو سکدا اوہ ساریاں تبدیلیاں مک جان جیہڑیاں تساں بناياں نیں۔\nاگر تسیں لاکان او، تسیں ایڈیٹنگ سیکشن چ  اپنی پسنداں چ ایس خبرداری نوں پعلے ناں۔",
+       "content-model-wikitext": "وکی ٹکسٹ",
        "expensive-parserfunction-warning": "'''خبردار:''' ایس صفے تے چوکھیاں ساریاں پارسر کلز نیں۔\nایدے چ $2 توں تھوڑی {{PLURAL:$2|کال|کالاں}} ہونیاں چاسیدیاں نیں، ایتھے {{PLURAL:$1|ہن $1 کال|ہن $1 کالاں}}",
        "expensive-parserfunction-category": "صفے بعوت ساریاں ایکسپنسو فنکشن کالز نال",
        "post-expand-template-inclusion-warning": "'''خبردار:''' ٹمپلیٹ ناپ چوکھا وڈا اے۔\nکج ٹمپلیٹ نئیں پاۓ جان گے۔",
        "notextmatches": "کوئی صفح نئیں لبیا",
        "prevn": "پہلا {{PLURAL:$1|$1}}",
        "nextn": "اگلا {{PLURAL:$1|$1}}",
+       "next-page": "اگلا صفہ",
        "prevn-title": "پہلے $1 {{PLURAL:$1|نتیجے}}",
        "nextn-title": "اگلے $1 {{PLURAL:$1|نتیجے}}",
        "shown-title": "وکھاؤ $1 {{PLURAL:$1|نتیجے}}",
        "skin-preview": "کچا کم",
        "datedefault": "خاص پسند نئیں",
        "prefs-labs": "لیبز فیچرز",
+       "prefs-user-pages": "ورتن والے دے صفے",
        "prefs-personal": "ورتن آلے دا پروفائل",
        "prefs-rc": "نویاں تبدیلیاں",
        "prefs-watchlist": "نظر تھلے صفحے",
+       "prefs-editwatchlist": " اکھ تھلے رکھی ہوئی نو تبدیل کرو",
        "prefs-watchlist-days": "اکھ تھلے رکھی لسٹ چ دسے گۓ دن:",
        "prefs-watchlist-days-max": "زیادہ توں زیادہ  $1 {{PLURAL:$1|دن|دن}}",
        "prefs-watchlist-edits": "ودائی ہوئی اکھ تھلے رکھی لسٹ چ زیادہ توں زیادہ نمبر دسو۔",
        "whatlinkshere": "ایتھے کیدا جوڑ اے",
        "whatlinkshere-title": "او صفے جہڑے \"$1\" نال جڑے نیں",
        "whatlinkshere-page": "صفہ:",
-       "linkshere-2": "تھلے دتے گۓ صفے اس دے نال جڑدے نے '''$1''':",
-       "nolinkshere-2": "'''$1''' دے نال کسے دا جوڑ نہیں",
-       "nolinkshere-ns-2": "چنے ناں چ کسے صفے دا '''$1''' نال جوڑ نئیں۔",
+       "linkshere": "تھلے دتے گۓ صفے اس دے نال جڑدے نے '''$2''':",
+       "nolinkshere": "'''$2''' دے نال کسے دا جوڑ نہیں",
+       "nolinkshere-ns": "چنے ناں چ کسے صفے دا '''$2''' نال جوڑ نئیں۔",
        "isredirect": "ریڈائرکٹ صفہ",
        "istemplate": "ملن",
        "isimage": "مورت دا جوڑ",
        "javascripttest-qunit-intro": "mediawiki.org تے [$1 ٹسٹنگ ڈوکومنٹیشن] ویکھو۔",
        "tooltip-pt-userpage": "{{GENDER:|میرا صفہ}}صفہ",
        "tooltip-pt-anonuserpage": "ورتن صفہ IP  پتے لئی تسی تبدیل کر رۓ او۔۔۔",
-       "tooltip-pt-mytalk": "{{GENDER:|Your}} گل بات",
+       "tooltip-pt-mytalk": "{{GENDER:|تواڈا}} گل بات صفہ",
        "tooltip-pt-anontalk": "ایس IP  پتے دیاں تبدیلیاں تے گل بات",
        "tooltip-pt-preferences": "میریاں تانگاں",
        "tooltip-pt-watchlist": "او صفے جنہاں وچ تبدیلیاں تسی ویکھ رہے او",
        "pageinfo-edits": "تبدیلیاں گنتی",
        "pageinfo-authors": "وکھرے لکھاریاں دی گنتی",
        "pageinfo-toolboxlink": "صفحہ جانکاری",
+       "pageinfo-protect-cascading-yes": "ہاں",
        "markaspatrolleddiff": "ویکھے گۓ دا نشان لاؤ",
        "markaspatrolledtext": "ایس صفے تے ویکھن دا نشان لاؤ",
        "markedaspatrolled": "ویکھن دا نشان لاؤ",
        "markedaspatrollederror-noautopatrol": "تھوانوں اے اجازت نئیں جے تسی اپنی تبدیلیاں تے گشت دا نشان لاؤ۔",
        "patrol-log-page": "گشت لاگ",
        "patrol-log-header": "اے گست لائیآں ہوئیآن ریوین دی لاگ اے۔",
-       "log-show-hide-patrol": "$1 گشت لاگ",
        "deletedrevision": "پرانیاں مٹائیاں ریوین $1",
        "filedeleteerror-short": "فاغل مٹان چ غلطی: $1",
        "filedeleteerror-long": "فائل مٹان لگیاں غلطیاں ہوئیاں:\n$1",
        "table_pager_empty": "کوئی نتارہ نئیں",
        "autosumm-blank": "ایس صفے نوں خالی کرو",
        "autosumm-replace": "\"$1\" نال مواد بدلو",
-       "autoredircomment": "صفے نوں [[$1]] ول ریڈائرکٹ کرو",
+       "autoredircomment": "صفے نوں [[$1]] ول ریڈائرکٹ کیتا",
        "autosumm-new": "\"$1\" نال صفہ بنایا گیا۔",
        "autosumm-newblank": "خالی صفحہ بنایا",
        "lag-warn-normal": "$1 توں نویاں تبدیلیاں {{PLURAL:$1|سکنٹ}}",
        "tag-filter": "[[Special:Tags|Tag]] نتارا:",
        "tag-filter-submit": "فلٹر",
        "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|ٹیگ|ٹیگز}}]]: $2)",
+       "tag-mw-new-redirect": "نواں مڑجوڑ",
        "tags-title": "ٹیگز",
        "tags-intro": "ایس صفے تے ٹیگ دی لسٹ اے جینوں سوفٹوئیر تبدیلی دا نشان لا سکدا اے۔",
        "tags-tag": "ٹیگ ناں",
        "logentry-newusers-create": "$1 {{GENDER:$2|بنایا}} اک ورتن والا کھاتہ",
        "logentry-newusers-create2": "$1 {{GENDER:$2|بنایا}} {{GENDER:$4|اک ورتن کھاتہ}} $3",
        "logentry-newusers-autocreate": "کھاتہ $1 اپنے آپ ای {{GENDER:$2|بنایا گیا}} بنایا گیا۔",
+       "logentry-protect-protect": "$1 نے $3 نوں {{GENDER:$2|محفوظ کیتا}}  $4",
        "logentry-upload-upload": "$1 {{جنس:$2|چڑھائی گئی}} $3",
        "rightsnone": "(کوئی وی نئیں)",
        "feedback-adding": "مشورہ  صفے تے دیو۔۔۔۔۔۔۔",
index ba2addf..b9dd3e7 100644 (file)
        "whatlinkshere": "Ντο δεκνίζ' αδακές",
        "whatlinkshere-title": "Σελίδας ντο συνδέουν ση σελίδαν $1",
        "whatlinkshere-page": "Σελίδαν:",
-       "linkshere-2": "Αβούτα τα σελίδας δεκνίζνε σο '''$1''':",
-       "nolinkshere-2": "'Κ ευρέθεν σελίδα το δεκνίζ' ση σελίδαν '''$1'''.",
+       "linkshere": "Αβούτα τα σελίδας δεκνίζνε σο '''$2''':",
+       "nolinkshere": "'Κ ευρέθεν σελίδα το δεκνίζ' ση σελίδαν '''$2'''.",
        "isredirect": "σελίδαν διπλού σύνδεσμονος",
        "istemplate": "ενσωμάτωση",
        "isimage": "σύνδεσμον εικόνας",
index 1f6ca9e..27f1641 100644 (file)
        "whatlinkshere": "Ka autenginna stwi",
        "whatlinkshere-title": "Pāusan autengināntei prei \"$1\"",
        "whatlinkshere-page": "Pāusan:",
-       "linkshere-2": "Ripīntei pāusai autenginna prei '''$1''':",
-       "nolinkshere-2": "Niaīnan pāusan ni autenginna prei '''$1'''.",
-       "nolinkshere-ns-2": "Niaīnan pāusan ni autenginna prei '''$1''' en etrīnktai tītelin plattibin.",
+       "linkshere": "Ripīntei pāusai autenginna prei '''$2''':",
+       "nolinkshere": "Niaīnan pāusan ni autenginna prei '''$2'''.",
+       "nolinkshere-ns": "Niaīnan pāusan ni autenginna prei '''$2''' en etrīnktai tītelin plattibin.",
        "isredirect": "prawesnas pāusan",
        "istemplate": "entensīsenis",
        "isimage": "autengīnsenis prei bildin",
        "markedaspatrollederror-noautopatrol": "Ni assei enwarīntan, kāi pazentlitun swajjans kitawīdinsnans kāigi \"izbandātans\".",
        "patrol-log-page": "Izbandāsnas registerin",
        "patrol-log-header": "Sta ast izbandātan wersiōnin regīsterin.",
-       "log-show-hide-patrol": "$1 izbandāsnas registerin",
        "deletedrevision": "Āupausinā di panzdaumans wersiōnins stesse $1",
        "filedeleteerror-short": "Blānda prei zūrbrukes $1 āupausinsnan",
        "filedeleteerror-long": "Blāndas tikka prei zūrbrukes āupausinsnan:\n\n$1",
index 62206cb..2b5b10e 100644 (file)
        "template-loop-category": "مخونه له کينډۍ پته ترلاسه شوو سره",
        "undo-failure": "د منازعې منځنۍ برخې د بدلونونو له امله دا سمون ندی رد شوی.",
        "undo-norev": "دا سمون ناکړل کېدای نه شي دا ځکه چې دا سمون نشته او يا هم ړنگ شوی.",
+       "undo-summary": "د [[Special:Contributions/$2|$2]] سمونه $1 ([[User talk:$2|خبرې اترې]]) بيرته پر شا کړي",
        "viewpagelogs": "د دې مخ يادښتونه کتل",
        "nohistory": "ددې مخ د سمون کوم پېښليک نه شته.",
        "currentrev": "اوسنۍ بڼه",
        "rcfilters-savedqueries-apply-and-setdefault-label": "د فرض په ډول د فيلټر جوړول",
        "rcfilters-savedqueries-cancel-label": "ناگارل",
        "rcfilters-savedqueries-add-new-title": "د امستنې اوسنۍ فيلټر خوندي کړي",
+       "rcfilters-restore-default-filters": "د ډيفاولټ فلټرونه بیا تازه کول",
        "rcfilters-search-placeholder": "د فلټر بدلونونه (د مینو کارول یا د فلټر نوم لټونه)",
        "rcfilters-invalid-filter": "غلط فلټر",
        "rcfilters-empty-filter": "هيڅ فعال فلټر نشته. ټولي سمونې ښکاره شوي.",
        "undeletepagetitle": "'''د [[:$1|$1]] ړنگې شوې بڼې په لاندې توگه دي'''.",
        "viewdeletedpage": "ړنگ شوي مخونه کتل",
        "undelete-fieldset-title": "بڼې بيازېرمل",
+       "undeleteextrahelp": "د ټول مخ د معلوماتو د بيا کتنې لپاره د '''''{{int:undeletebtn}}''''' پر\nبټن کښي کاږي، او ددي ترمخه چي د '''''{{int:undeletebtn}}''''' پر مخ ګوته يا موس بټن کښي کاږي نو لږ فکر پر وکړي.",
        "undeleterevisions": "$1 {{PLURAL:$1|بڼه|بڼې}} خونديځ کې {{PLURAL:$1|ورگډ شو|ورگډ شول}}",
        "undeletehistory": "که تاسې همدا مخ بيازېرمه کوۍ، نو ټولې بڼې به يې پېښليک کې زېرمه شي.\nکه چېرته د ړنگېدو وروسته په همدې نوم يو بل نوی مخ جوړ شوی وي، نو زېرمه شوې بڼې به يې په پخواني پېښليک کې ښکاره شي.",
+       "undeleterevdel": "ړنګيدنه بيرته راګرځول به د مخ په پيښنليک کي نشي ښکاره، او تاسو که ليکنه ړنګه کړي نو د کارنانو سمونې به بيا هم پرځای پاته وي. \nپه دا ډول پيښو کې تاسو بايد د کارنانو سمونې پټې يا ړنګې کړي.",
+       "undelete-revision": "د $1 ړنګه شوي بڼه (چې د $4 نيټې په $5 بجو) د $3 لخوا داسې جوړه شوي وه:",
        "undelete-nodiff": "کومې پخوانۍ بڼې و نه موندل شوې.",
        "undeletebtn": "بيازېرمل",
        "undeletelink": "کتل/بيازېرمل",
        "whatlinkshere": "د دې مخ تړنې",
        "whatlinkshere-title": "هغه مخونه چې د \"$1\" سره تړنې لري",
        "whatlinkshere-page": "مخ:",
-       "linkshere-2": "دغه لانديني مخونه د '''$1''' سره تړنې لري:",
-       "nolinkshere-2": "د '''$1''' سره هېڅ يو مخ هم تړنې نه لري .",
+       "linkshere": "دغه لانديني مخونه د '''$2''' سره تړنې لري:",
+       "nolinkshere": "د '''$2''' سره هېڅ يو مخ هم تړنې نه لري .",
        "isredirect": "د مخ گرځونې مخ",
        "istemplate": "ورگډېدنه",
        "isimage": "د دوتنې تړنه",
        "siteuser": "د {{SITENAME}} کارن $1",
        "anonuser": "د {{SITENAME}} ورکنومی کارن $1",
        "lastmodifiedatby": "دا مخ وروستی ځل $3 لخوا په $2، $1 بدلون موندلی.",
-       "othercontribs": "نور کار پر اساس د $1.",
+       "othercontribs": "نور کار پر اساس $1.",
        "others": "نور",
-       "siteusers": "د {{SITENAME}} {{PLURAL:$2|کارن|کارنان}} $1",
+       "siteusers": "د {{SITENAME}} {{PLURAL:$2|د کارن|د کارنانو}} لکه $1",
        "anonusers": "د {{SITENAME}} {{PLURAL:$2|ورکنومی کارن|ورکنومي کارنان}} $1",
        "creditspage": "د دې مخ کرېډټونه",
        "simpleantispam-label": "سپام-ضد څارنه.\nدا برخه <strong>مه</strong> ډکوئ!",
        "markedaspatrollederrornotify": "د څارل شوي په توگه په نښه کول نابريال شو.",
        "patrol-log-page": "د څارنې يادښت",
        "patrol-log-header": "دا د څارل شويو مخکتنو يو يادښت دی.",
-       "log-show-hide-patrol": "د څارنې يادښت $1",
-       "log-show-hide-tag": "نښلن يادښت $1",
        "confirm-markpatrolled-button": "ښه",
        "deletedrevision": "د $1 زړه ړنگه شوې بڼه",
        "filedeleteerror-short": "د دوتنې د ړنگولو ستونزه: $1",
        "limitreport-expansiondepth-value": "$1/$2",
        "limitreport-expensivefunctioncount": "د قیمتي پارسير فعالیت شمیرې",
        "limitreport-expensivefunctioncount-value": "$1/$2",
+       "limitreport-unstrip-depth": "د ناڅاپه بیاکتنې ژورتيا",
+       "limitreport-unstrip-size": "د نسکوریدو وروسته د پراخولو اندازه",
        "limitreport-unstrip-size-value": "$1/$2 {{PLURAL:$2|ټکۍ|ټکي}}",
        "expandtemplates": "کينډۍ غځول",
        "expand_templates_intro": "په دا ځانګړي مخ کي متن پاڼه ترلاسه کیږي کوم چي په ټول ډوله مخونو کي کارول کیږي دلته دا مخ بيا بیا وده کوي. د تحلیل دندو لکه <code><nowiki>{{</nowiki>#language:…}}</code> او متغیرونه لکه <code><nowiki>{{</nowiki>CURRENTDAY}}</code> هم سره نښلوي — په واقعیت کې، د ډلو دننه هر څه. دا خپله د ميډياويکي په اړونده مرحله کولو سره ترسره کيږي.",
index 1ceac81..07604da 100644 (file)
                        "Trigonometria87",
                        "RadiX",
                        "Fitoschido",
-                       "Ed g2s"
+                       "Ed g2s",
+                       "Matěj Suchánek"
                ]
        },
        "tog-underline": "Ligação sublinhada:",
        "sort-descending": "Ordenar por ordem descendente",
        "sort-ascending": "Ordenar por ordem ascendente",
        "nstab-main": "Página",
-       "nstab-user": "Página d{{GENDER:{{BASEPAGENAME}}|o usuário|a usuária|e usuário(a)}}",
+       "nstab-user": "Página {{GENDER:{{ROOTPAGENAME}}|do usuário|da usuária|de usuário(a)}}",
        "nstab-media": "Página de mídia",
        "nstab-special": "Página especial",
        "nstab-project": "Página do projeto",
        "createacct-loginerror": "A conta foi criada com êxito, mas não pôde ser autenticado automaticamente. Por favor, faça o [[Special:UserLogin|início de sessão manualmente]].",
        "noname": "Você não colocou um nome de usuário válido.",
        "loginsuccesstitle": "Autenticado",
-       "loginsuccess": "'''Agora você está {{GENDER:autenticado|autenticada}} ao wiki {{SITENAME}} como \"$1\"'''.",
+       "loginsuccess": "'''Agora você está {{GENDER:|autenticado|autenticada}} ao wiki {{SITENAME}} como \"$1\"'''.",
        "nosuchuser": "Não existe nenhum usuário com o nome \"$1\".\nOs nomes de usuário são sensíveis a letras maiúsculas.\nVerifique se digitou corretamente ou [[Special:CreateAccount|crie uma nova conta]].",
        "nosuchusershort": "Não existe um usuário com o nome \"$1\". Verifique o nome que introduziu.",
        "nouserspecified": "Você precisa especificar um nome de usuário.",
        "resetpass-submit-loggedin": "Alterar senha",
        "resetpass-submit-cancel": "Cancelar",
        "resetpass-wrong-oldpass": "Senha temporária ou atual inválida.\nVocê pode já ter alterado com sucesso a sua senha, ou solicitado uma nova senha temporária.",
-       "resetpass-recycled": "Por favor, redefina sua nova senha para uma diferente da atual.",
+       "resetpass-recycled": "Por favor, altere sua senha para algo diferente da sua senha atual.",
        "resetpass-temp-emailed": "Você está autenticado com o código temporário enviado. Para finalizar a autenticação, você deve inserir uma nova senha aqui:",
        "resetpass-temp-password": "Senha temporária:",
        "resetpass-abort-generic": "Uma extensão cancelou a alteração da senha.",
        "resetpass-expired": "Sua senha expirou. Por favor insira uma nova senha para autenticar-se.",
-       "resetpass-expired-soft": "Sua senha expirou e necessita ser resetada. Por favor escolha uma nova agora, ou clique \"{{int:authprovider-resetpass-skip-label}}\" para resetar mais tarde.",
-       "resetpass-validity-soft": "Sua senha não é válida: $1\n\nPor favor escolha uma nova senha agora, ou clique \"{{int:authprovider-resetpass-skip-label}}\" para redefini-la mais tarde.",
+       "resetpass-expired-soft": "Sua senha expirou e precisa ser alterada. Escolha uma nova senha agora ou clique em \"{{int:authprovider-resetpass-skip-label}}\" para alterá-la mais tarde.",
+       "resetpass-validity-soft": "Sua senha não é válida: $1\n\nPor favor escolha uma nova senha agora, ou clique \"{{int:authprovider-resetpass-skip-label}}\" para mudar depois.",
        "passwordreset": "Redefinir senha",
        "passwordreset-text-one": "Complete este formulário para trocar sua senha.",
        "passwordreset-text-many": "{{PLURAL:$1|Preencha um dos campos para trocar sua senha.}}",
        "converter-manual-rule-error": "Erro detectado na regra de conversão de língua manual",
        "undo-success": "A edição pôde ser desfeita. Por gentileza, verifique o comparativo a seguir para se certificar de que é isto que deseja fazer, salvando as alterações após ter terminado de revisá-las.",
        "undo-failure": "A edição não pôde ser desfeita devido a alterações intermediárias conflitantes.",
+       "undo-main-slot-only": "A edição não pode ser desfeita porque envolve conteúdo fora do espaço principal.",
        "undo-norev": "A edição não pôde ser desfeita porque não existe ou foi apagada.",
        "undo-nochange": "Parece que a edição já foi desfeita.",
        "undo-summary": "Desfeita a edição $1 de [[Special:Contributions/$2|$2]] ([[User talk:$2|Discussão]])",
        "revdelete-text-file": "Versões dos arquivos apagados continuarão a aparecer no arquivo de histórico, mas parte de seus conteúdos estarão inacessíveis ao público.",
        "logdelete-text": "Eventos de log apagados continuarão a aparecer nos logs, mas parte de seus conteúdos estarão inacessíveis ao público.",
        "revdelete-text-others": "Outros administradores do site {{SITENAME}} continuarão capazes de acessar o conteúdo oculto e podem apagá-lo pela mesma interface, a menos que restrições adicionais tenham sido feitas.",
-       "revdelete-confirm": "Por favor confirme que pretende executar esta ação, que compreende as suas consequências e que o faz em concordância com as [[{{MediaWiki:Policy-url}}|políticas e recomendações]].",
+       "revdelete-confirm": "Por favor, confirme que pretende executar esta ação, que compreende as consequências dela e que o faz em concordância com as [[{{MediaWiki:Policy-url}}|políticas e recomendações]].",
        "revdelete-suppress-text": "A supressão deverá ser usada '''apenas''' para os seguintes casos:\n* Informação potencialmente difamatória\n* Informação pessoal inapropriada\n*: ''endereços de domicílio e números de telefone, números da segurança social, etc''",
        "revdelete-legend": "Definir restrições de visualização",
        "revdelete-hide-text": "Texto de revisão",
        "diff-paragraph-moved-toold": "O parágrafo foi movido. Clique para saltar para a posição anterior.",
        "difference-missing-revision": "{{PLURAL:$2|Uma revisão|$2 revisões}} desta diferença ($1) não {{PLURAL:$2|foi encontrada|foram encontradas}}.\n\nIsto é geralmente causado por seguir um link de histórico desatualizado para uma página que foi eliminada.\nOs detalhes podem ser encontrados no [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} registro de eliminação].",
        "searchresults": "Resultados da pesquisa",
+       "search-filter-title-prefix": "A pesquisar só nas páginas cujo título começa por \"$1\"",
+       "search-filter-title-prefix-reset": "Pesquisar em todas as páginas",
        "searchresults-title": "Resultados da pesquisa por \"$1\"",
        "titlematches": "Resultados nos títulos das páginas",
        "textmatches": "Resultados nos textos das páginas",
        "datedefault": "Sem preferência",
        "prefs-labs": "Características de laboratório",
        "prefs-user-pages": "Páginas de usuário",
-       "prefs-personal": "Dados do usuário",
+       "prefs-personal": "Dados pessoais",
        "prefs-rc": "Mudanças recentes",
        "prefs-watchlist": "Lista de páginas vigiadas",
        "prefs-editwatchlist": "Editar lista de páginas vigiadas",
        "timezoneregion-pacific": "Oceano Pacífico",
        "allowemail": "Permitir que outros usuários enviem-me e-mails",
        "email-allow-new-users-label": "Permitir e-mails de novos usuários",
-       "email-blacklist-label": "Proibir que estes usuários enviem-me e-mails:",
+       "email-blacklist-label": "Proibir que estes usuários me enviem e-mails:",
        "prefs-searchoptions": "Busca",
        "prefs-namespaces": "Espaços nominais",
        "default": "padrão",
        "prefs-help-gender": "A configuração dessa preferência é opcional.\nO ''software'' utiliza seu valor para tratar e mencionar você a outros usando o gênero gramatical adequado.\nEssa informação será pública.",
        "email": "E-mail",
        "prefs-help-realname": "O fornecimento de seu nome verdadeiro é opcional.\nCaso decida fornecê-lo, este será utilizado para dar-lhe crédito pelo seu trabalho.",
-       "prefs-help-email": "O endereço de correio eletrônico é opcional, mas será necessário para recriar sua senha caso esqueça a antiga.",
+       "prefs-help-email": "O endereço de e-mail é opcional, mas será necessário para recriar sua senha caso esqueça a antiga.",
        "prefs-help-email-others": "Você também pode optar por permitir que outros entrem em contato com você através de sua página de usuário ou de discussão sem ter de revelar seus dados pessoais.",
        "prefs-help-email-required": "O endereço de e-mail é requerido.",
        "prefs-info": "Informações básicas",
        "rcfilters-other-review-tools": " Outras ferramentas de revisão:",
        "rcfilters-group-results-by-page": "Agrupar resultado por página",
        "rcfilters-activefilters": "Filtros ativos",
+       "rcfilters-activefilters-hide": "Ocultar",
+       "rcfilters-activefilters-show": "Exibir",
+       "rcfilters-activefilters-hide-tooltip": "Ocultar a área dos filtros ativos",
+       "rcfilters-activefilters-show-tooltip": "Mostrar a área dos filtros ativos",
        "rcfilters-advancedfilters": "Filtros avançados",
        "rcfilters-limit-title": "Resultados para mostrar",
        "rcfilters-limit-and-date-label": "$1 {{PLURAL:$1|mudança|mudanças}}, $2",
        "rcfilters-savedqueries-rename": "Renomear",
        "rcfilters-savedqueries-setdefault": "Definir como padrão",
        "rcfilters-savedqueries-unsetdefault": "Remover como padrão",
-       "rcfilters-savedqueries-remove": "Remover",
+       "rcfilters-savedqueries-remove": "Excluir",
        "rcfilters-savedqueries-new-name-label": "Nome",
        "rcfilters-savedqueries-new-name-placeholder": "Descreva a finalidade do filtro",
        "rcfilters-savedqueries-apply-label": "Criar filtro",
        "rcfilters-empty-filter": "Nenhum filtro ativo. Todas as contribuições são mostradas.",
        "rcfilters-filterlist-title": "Filtros",
        "rcfilters-filterlist-whatsthis": "Como funcionam estes?",
-       "rcfilters-filterlist-feedbacklink": "Diga-nos o que você pensa sobre estas (novas) ferramentas de filtragem",
+       "rcfilters-filterlist-feedbacklink": "Conte-nos o que você pensa sobre essas ferramentas de filtragem",
        "rcfilters-highlightbutton-title": "Destacar resultados",
        "rcfilters-highlightmenu-title": "Selecione uma cor",
        "rcfilters-highlightmenu-help": "Selecione uma cor para realçar esta propriedade",
        "rcfilters-watchlist-showupdated": "As alterações nas páginas que você não visitou desde as mudanças ocorridas estão em <strong>negrito</strong>, com marcadores sólidos.",
        "rcfilters-preference-label": "Ocultar a versão melhorada das Mudanças Recentes",
        "rcfilters-preference-help": "Reverte o redesenho da interface de 2017 e todas as ferramentas adicionadas na altura e desde então.",
+       "rcfilters-watchlist-preference-label": "Ocultar a versão melhorada das páginas vigiadas",
+       "rcfilters-watchlist-preference-help": "Reverte o redesenho da interface em 2017 e todas as ferramentas adicionadas nessa altura e desde então.",
        "rcfilters-filter-showlinkedfrom-label": "Mostrar alterações nas páginas ligadas de",
        "rcfilters-filter-showlinkedfrom-option-label": "<strong>Páginas ligadas da</strong> página selecionada",
        "rcfilters-filter-showlinkedto-label": "Mostrar alterações nas páginas que ligam para",
        "uploadlogpagetext": "Segue listagem dos uploads de arquivos mais recentes.\nA [[Special:NewFiles|galeria de arquivos novos]] oferece uma listagem mais visual.",
        "filename": "Nome do arquivo",
        "filedesc": "Descrição do arquivo",
-       "fileuploadsummary": "Sumário:",
+       "fileuploadsummary": "Resumo:",
        "filereuploadsummary": "Alterações no arquivo:",
        "filestatus": "Status dos direitos autorais:",
        "filesource": "Fonte:",
        "tmp-write-error": "Erro ao alterar arquivo temporário.",
        "large-file": "É recomendável que os arquivos não sejam maiores que $1;\neste possui $2.",
        "largefileserver": "Este arquivo é maior do que o servidor está configurado para permitir.",
-       "emptyfile": "O arquivo enviado parece estar vazio.\nIsso pode ter ocorrido por um erro de digitação no nome do arquivo.\nVerifique se você realmente deseja enviar este arquivo.",
+       "emptyfile": "O arquivo enviado parece estar vazio.\nIsso pode ter ocorrido por um erro de digitação no nome.\nVerifique se você realmente deseja enviá-lo.",
        "windows-nonascii-filename": "O wiki não aceita nomes de arquivos com caracteres especiais.",
        "fileexists": "Já existe um arquivo com este nome.\nVerifique <strong>[[:$1]]</strong> caso não tenha certeza se deseja alterar o arquivo atual.\n[[$1|thumb]]",
        "filepageexists": "A página de descrição deste arquivo já foi criada em <strong>[[:$1]]</strong>, mas atualmente não existe nenhum arquivo com este nome.\nO sumário que você inseriu não aparecerá na página de descrição.\nPara que ele apareça, será necessário editá-lo manualmente.\n[[$1|thumb]]",
        "http-timed-out": "Esgotado o tempo de espera da requisição HTTP.",
        "http-curl-error": "Erro ao requisitar a URL: $1",
        "http-bad-status": "Ocorreu um problema durante a requisição HTTP: $1 $2",
+       "http-internal-error": "Erro interno do HTTP.",
        "upload-curl-error6": "Não foi possível acessar a URL",
        "upload-curl-error6-text": "Não foi possível acessar o endereço (URL) fornecido. Por gentileza, se certifique que o endereço foi fornecido corretamente e de que o site esteja acessível.",
        "upload-curl-error28": "Tempo limite para o envio do arquivo excedido",
        "speciallogtitlelabel": "Alvo (título da página ou {{ns:user}}:'nomedeusuário' para usuários):",
        "log": "Registros",
        "logeventslist-submit": "Exibir",
+       "logeventslist-more-filters": "Mostrar registos adicionais:",
+       "logeventslist-patrol-log": "Registro de edições patrulhadas",
+       "logeventslist-tag-log": "Registro de etiquetas",
        "all-logs-page": "Todos os registros públicos",
        "alllogstext": "Exibição combinada de todos registros disponíveis para o {{SITENAME}}.\nVocê pode diminuir a lista escolhendo um tipo de registro, um nome de usuário (sensível a maiúsculas e minúsculas), ou uma página afetada (também sensível a maiúsculas e minúsculas).",
        "logempty": "Nenhum item correspondente no registro.",
        "categories-submit": "Exibir",
        "categoriespagetext": "{{PLURAL:$1|A seguinte categoria contém|As seguintes contém}} páginas ou mídia.\n[[Special:UnusedCategories|Categorias não utilizadas]] não são mostradas aqui.\nVeja também [[Special:WantedCategories|categorias pedidas]].",
        "categoriesfrom": "Listar categorias começando por:",
-       "deletedcontributions": "Edições eliminadas",
+       "deletedcontributions": "Contribuições eliminadas",
        "deletedcontributions-title": "Contribuições eliminadas",
        "sp-deletedcontributions-contribs": "contribuições",
        "linksearch": "Pesquisa de links externos",
        "removedwatchtext-short": "A página \"$1\" foi removida de sua lista de páginas vigiadas.",
        "watch": "Vigiar",
        "watchthispage": "Vigiar esta página",
-       "unwatch": "Desinteressar-se",
+       "unwatch": "Deixar de vigiar",
        "unwatchthispage": "Parar de vigiar esta página",
        "notanarticle": "Não é uma página de conteúdo",
        "notvisiblerev": "Edição eliminada",
        "dellogpage": "Registro de eliminações",
        "dellogpagetext": "Abaixo uma lista das eliminações mais recentes.",
        "deletionlog": "registro de eliminações",
+       "log-name-create": "Registo de criação de páginas",
+       "log-description-create": "Encontra abaixo uma lista das criações de páginas mais recentes.",
+       "logentry-create-create": "$1 {{GENDER:$2|criou}} a página $3",
        "reverted": "Revertido para versão anterior",
        "deletecomment": "Motivo:",
        "deleteotherreason": "Justificativa adicional:",
        "uctop": "(atual)",
        "month": "Mês (inclusive anteriores):",
        "year": "Ano (inclusive anteriores):",
+       "date": "A partir da data (e anterior):",
        "sp-contributions-newbies": "Mostrar apenas as contribuições das novas contas",
        "sp-contributions-newbies-sub": "Para contas novas",
        "sp-contributions-newbies-title": "Contribuições de contas novas",
        "sp-contributions-blocklog": "registro de bloqueios",
        "sp-contributions-suppresslog": "Contribuições de {{GENDER:$1|usuário}} suprimidas",
-       "sp-contributions-deleted": "contribuições eliminadas do {{GENDER:$1|usuário}}",
+       "sp-contributions-deleted": "{{GENDER:$1|contribuições}} eliminadas",
        "sp-contributions-uploads": "envios",
        "sp-contributions-logs": "registros",
-       "sp-contributions-talk": "disc",
-       "sp-contributions-userrights": "gerenciamento de privilégios de {{GENDER:$1|usuários}}",
-       "sp-contributions-blocked-notice": "Este usuário atualmente está bloqueado. O registro de bloqueio mais recente é fornecido abaixo para referência:",
+       "sp-contributions-talk": "discussão",
+       "sp-contributions-userrights": "{{GENDER:$1|gestão}} dos privilégios",
+       "sp-contributions-blocked-notice": "{{GENDER:$1|Este usuário atualmente está bloqueado|Esta usuária atualmente está bloqueada|Este(a) usuário(a) atualmente está bloqueado(a)}}. O registro de bloqueio mais recente é fornecido abaixo para referência:",
        "sp-contributions-blocked-notice-anon": "Este endereço IP encontra-se bloqueado.\nSegue, para referência, a entrada mais recente no registro de bloqueios:",
        "sp-contributions-search": "Navegar pelas contribuições",
        "sp-contributions-username": "Endereço de IP ou usuário(a):",
        "whatlinkshere": "Páginas afluentes",
        "whatlinkshere-title": "Páginas que têm links para \"$1\"",
        "whatlinkshere-page": "Página:",
-       "linkshere-2": "As seguintes páginas possuem links para '''$1''':",
-       "nolinkshere-2": "Não há afluentes para '''$1''' com as condições especificadas.",
-       "nolinkshere-ns-2": "Não há links para '''$1''' no espaço nominal selecionado.",
+       "linkshere": "As seguintes páginas têm link para <strong>$2</strong>:",
+       "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": "transclusão",
        "isimage": "link para o arquivo",
        "ipbcreateaccount": "Prevenir a criação de contas",
        "ipbemailban": "Impedir usuário(a) de enviar e-mail",
        "ipbenableautoblock": "Bloquear automaticamente o endereço de IP mais recente usado por este(a) usuário(a) e todos os IPs subsequentes dos quais ele(a) tentar editar",
-       "ipbsubmit": "Bloquear este(a) usuário(a)",
+       "ipbsubmit": "Bloquear",
        "ipbother": "Outro período:",
        "ipboptions": "2 horas:2 hours,1 dia:1 day,3 dias:3 days,1 semana:1 week,2 semanas:2 weeks,1 mês:1 month,3 meses:3 months,6 meses:6 months,1 ano:1 year,indefinido:infinite",
        "ipbhidename": "Ocultar nome de usuário em edições e listas",
        "movenosubpage": "Esta página não tem subpáginas.",
        "movereason": "Motivo:",
        "revertmove": "reverter",
-       "delete_and_move_text": "A página de destino \"[[:$1]]\" já existe. Deseja excluí-lo para abrir caminho para o movimento?",
+       "delete_and_move_text": "A página de destino \"[[:$1]]\" já existe. Deseja eliminá-la para abrir caminho para o movimento?",
        "delete_and_move_confirm": "Sim, eliminar a página",
        "delete_and_move_reason": "Eliminada para mover \"[[$1]]\"",
        "selfmove": "O título fonte e o título destinatário são os mesmos; não é possível mover uma página para ela mesma.",
        "markaspatrolledtext-file": "Marcar esta versão de artigo como patrulhada",
        "markedaspatrolled": "Marcado como verificado",
        "markedaspatrolledtext": "A revisão selecionada de [[:$1]] foi marcada como patrulhada.",
-       "rcpatroldisabled": "Edições verificadas nas Mudanças Recentes desativadas",
-       "rcpatroldisabledtext": "A funcionalidade de Edições verificadas nas Mudanças Recentes está atualmente desativada.",
+       "rcpatroldisabled": "Edições verificadas nas mudanças recentes desativadas",
+       "rcpatroldisabledtext": "A funcionalidade de edições verificadas nas mudanças recentes está atualmente desativada.",
        "markedaspatrollederror": "Não é possível marcar como verificado",
        "markedaspatrollederrortext": "Você precisa de especificar uma revisão para poder marcar como verificado.",
        "markedaspatrollederror-noautopatrol": "Você não está autorizado a marcar suas próprias edições como edições patrulhadas.",
        "markedaspatrollederrornotify": "Falha ao marcar como patrulhada.",
        "patrol-log-page": "Registro de edições patrulhadas",
        "patrol-log-header": "Este é um registro de edições patrulhadas.",
-       "log-show-hide-patrol": "$1 registro de edições patrulhadas",
-       "log-show-hide-tag": "$1 etiqueta de log",
        "confirm-markpatrolled-button": "OK",
        "confirm-markpatrolled-top": "Marque a revisão $3 de $2 como patrulhado?",
        "deletedrevision": "Apagou a versão antiga $1",
        "watchlistedit-clear-explain": "Todos os títulos serão removidos da sua lista de páginas vigiadas",
        "watchlistedit-clear-titles": "Títulos:",
        "watchlistedit-clear-submit": "Limpar a lista de páginas vigiadas (Esta ação é permanente!)",
-       "watchlistedit-clear-done": "Sua lista de páginas vigiadas foi limpa.",
+       "watchlistedit-clear-done": "Sua lista de páginas vigiadas foi esvaziada.",
        "watchlistedit-clear-jobqueue": "A sua lista de páginas vigiadas está a ser esvaziada. Esta operação pode ser demorada.",
        "watchlistedit-clear-removed": "{{PLURAL:$1|Foi removido um título|Foram removidos $1 títulos}}:",
        "watchlistedit-too-many": "Há muitas páginas para exibir aqui.",
        "rawhtml-notallowed": "As tags &lt;html&gt; não podem ser usadas fora das páginas normais.",
        "gotointerwiki": "Saindo {{SITENAME}}",
        "gotointerwiki-invalid": "O título especificado é inválido.",
-       "gotointerwiki-external": "Você está prestes a sair {{SITENAME}} para visitar [[$2]] que é um website separado.\n\n[$1 Continuar para $1].",
+       "gotointerwiki-external": "Você está prestes a sair {{SITENAME}} para visitar [[$2]] que é um website separado.\n\n'''[$1 Continuar para $1]'''",
        "undelete-cantedit": "Você não pode restaurar esta página, porque você não está autorizado a editar esta página.",
        "undelete-cantcreate": "Você não pode restaurar esta página, pois não há uma página com este nome e você não está autorizado a criar esta página.",
        "pagedata-title": "Dados de página",
        "pagedata-text": "Esta página fornece uma interface de dados para páginas. Forneça o título da página no URL, usando a sintaxe de subpáginas, por favor.\n* Aplica-se a negociação de conteúdo com base no cabeçalho Accept do seu cliente. Isto significa que os dados da página serão fornecidos no formato preferido do seu cliente.",
        "pagedata-not-acceptable": "Nenhum formato correspondente encontrado. Tipos MIME suportados: $1",
        "pagedata-bad-title": "Título inválido: $1.",
-       "unregistered-user-config": "Por razões de segurança as subpáginas de utilizador com JavaScript, CSS e JSON não podem ser carregadas para usuários não registados."
+       "unregistered-user-config": "Por razões de segurança as subpáginas de utilizador com JavaScript, CSS e JSON não podem ser carregadas para usuários não registados.",
+       "passwordpolicies": "Políticas de senha",
+       "passwordpolicies-summary": "Esta é uma lista da senha efetiva para os grupos de usuários definidos neste wiki.",
+       "passwordpolicies-group": "Grupo",
+       "passwordpolicies-policies": "Políticas",
+       "passwordpolicies-policy-minimalpasswordlength": "A senha deve ter pelo menos $1 {{PLURAL:$1|caráter|caracteres}}",
+       "passwordpolicies-policy-minimumpasswordlengthtologin": "A senha deve ter pelo menos $1 {{PLURAL:$1|caráter|caracteres}} para poder entrar",
+       "passwordpolicies-policy-passwordcannotmatchusername": "Senha não pode ser o mesmo que nome de usuário",
+       "passwordpolicies-policy-passwordcannotmatchblacklist": "A senha não pode corresponder senhas especificamente na lista negra",
+       "passwordpolicies-policy-maximalpasswordlength": "A senha deve ser menor que $1 {{PLURAL:$1|caráter|caracteres}}",
+       "passwordpolicies-policy-passwordcannotbepopular": "A senha não pode {{PLURAL:$1|ser a mais popular|estar na lista das $1 palavras-passe mais populares}}"
 }
index b769e52..8baa4d0 100644 (file)
@@ -77,7 +77,8 @@
                        "RadiX",
                        "MokaAkashiyaPT",
                        "Athena in Wonderland",
-                       "Fitoschido"
+                       "Fitoschido",
+                       "Ldacosta"
                ]
        },
        "tog-underline": "Sublinhar hiperligações:",
@@ -87,7 +88,7 @@
        "tog-hidecategorization": "Ocultar categorização de páginas",
        "tog-extendwatchlist": "Listagem expandida de todas as mudanças às páginas vigiadas, não apenas das mais recentes",
        "tog-usenewrc": "Agrupar alterações por página nas mudanças recentes e páginas vigiadas",
-       "tog-numberheadings": "Auto-numerar cabeçalhos",
+       "tog-numberheadings": "Numerar cabeçalhos automaticamente",
        "tog-showtoolbar": "Mostrar barra de edição",
        "tog-editondblclick": "Editar páginas quando houver um clique duplo",
        "tog-editsectiononrightclick": "Possibilitar a edição de secções por clique com o botão direito no título da secção",
        "protect_change": "alterar",
        "unprotect": "Alterar proteção",
        "newpage": "Página nova",
-       "talkpagelinktext": "Discussão",
+       "talkpagelinktext": "discussão",
        "specialpage": "Página especial",
        "personaltools": "Ferramentas pessoais",
        "talk": "Discussão",
        "viewhelppage": "Ver página de ajuda",
        "categorypage": "Ver página de categoria",
        "viewtalkpage": "Ver discussão",
-       "otherlanguages": "Noutros idiomas",
+       "otherlanguages": "Noutras línguas",
        "redirectedfrom": "(Redirecionado de $1)",
        "redirectpagesub": "Página de redirecionamento",
        "redirectto": "Redireciona para:",
-       "lastmodifiedat": "Esta página foi editada pela última vez à(s) $2 de $1.",
+       "lastmodifiedat": "Esta página foi editada pela última vez às $2 de $1.",
        "viewcount": "Esta página foi acedida {{PLURAL:$1|uma vez|$1 vezes}}.",
        "protectedpage": "Página protegida",
        "jumpto": "Ir para:",
        "sort-descending": "Ordenar por ordem descendente",
        "sort-ascending": "Ordenar por ordem ascendente",
        "nstab-main": "Página",
-       "nstab-user": "Página d{{GENDER:{{BASEPAGENAME}}|o utilizador|a utilizadora|e utilizador(a)}}",
+       "nstab-user": "Página {{GENDER:{{ROOTPAGENAME}}|do utilizador|da utilizadora}}",
        "nstab-media": "Multimédia",
        "nstab-special": "Página especial",
        "nstab-project": "Página do projeto",
        "customcssprotected": "Não tem permissão para editar esta página de CSS porque a página contém as configurações pessoais de outro utilizador.",
        "customjsonprotected": "Não tem permissão para editar esta página de JSON porque a página contém as configurações pessoais de outro utilizador.",
        "customjsprotected": "Não tem permissão para editar esta página de JavaScript porque a página contém as configurações pessoais de outro utilizador.",
+       "sitecssprotected": "Não tem permissão para editar esta página de CSS porque ela pode afetar todos os visitantes",
+       "sitejsonprotected": "Não tem permissão para editar esta página de JSON porque ela pode afetar todos os visitantes",
+       "sitejsprotected": "Não tem permissão para editar esta página de JavaScript porque ela pode afetar todos os visitantes",
        "mycustomcssprotected": "Não tem permissão para editar esta página de CSS.",
        "mycustomjsonprotected": "Não tem permissão para editar esta página de JSON.",
        "mycustomjsprotected": "Não tem permissão para editar esta página de JavaScript.",
        "resetpass-submit-loggedin": "Alterar palavra-passe",
        "resetpass-submit-cancel": "Cancelar",
        "resetpass-wrong-oldpass": "Palavra-passe temporária ou atual inválida.\nPode ter já alterado a sua palavra-passe ou solicitado uma nova palavra-passe temporária.",
-       "resetpass-recycled": "Redefina a sua palavra-passe para uma diferente da atual, por favor.",
+       "resetpass-recycled": "Altere a sua palavra-passe para uma diferente da atual, por favor.",
        "resetpass-temp-emailed": "Iniciou a sessão com um código temporário.\nPara completar a autenticação, tem de definir uma palavra-passe nova aqui:",
        "resetpass-temp-password": "Palavra-passe temporária:",
        "resetpass-abort-generic": "A alteração da palavra-passe foi cancelada por uma extensão.",
        "resetpass-expired": "A sua palavra-passe expirou. Por favor, defina uma nova para iniciar a sessão.",
-       "resetpass-expired-soft": "A sua palavra-passe expirou e tem de ser redefinida. Escolha uma nova agora ou clique \"{{int:authprovider-resetpass-skip-label}}\" para redefini-la mais tarde.",
-       "resetpass-validity-soft": "A sua palavra-passe não é válida: $1\n\nPor favor, escolha uma nova palavra-passe agora, ou clique em \"{{int:authprovider-resetpass-skip-label}}\" para redefini-la mais tarde.",
+       "resetpass-expired-soft": "A sua palavra-passe expirou e tem de ser alterada. Escolha uma nova agora ou clique \"{{int:authprovider-resetpass-skip-label}}\" para alterá-la mais tarde.",
+       "resetpass-validity-soft": "A sua palavra-passe não é válida: $1\n\nEscolha uma palavra-passe nova agora, ou clique em \"{{int:authprovider-resetpass-skip-label}}\" para alterá-la mais tarde, por favor.",
        "passwordreset": "Redefinir palavra-passe",
        "passwordreset-text-one": "Preencha este formulário para receber uma palavra-passe temporária por correio eletrónico.",
        "passwordreset-text-many": "{{PLURAL:$1|Preencha um dos campos para receber uma palavra-passe temporária por correio eletrónico.}}",
        "converter-manual-rule-error": "Erro detetado na regra de conversão de língua manual",
        "undo-success": "É possível desfazer a edição.\nVerifique a comparação abaixo, por favor, para se certificar de que corresponde ao que pretende fazer.\nDepois grave as alterações, para finalizar e desfazer a edição.",
        "undo-failure": "Não foi possível desfazer a edição por conflito com alterações intermédias.",
+       "undo-main-slot-only": "Não foi possível desfazer a edição porque ela envolve conteúdo fora do segmento de revisão principal.",
        "undo-norev": "Não foi possível desfazer a edição porque não existe ou foi apagada.",
        "undo-nochange": "A edição parece já ter sido desfeita.",
-       "undo-summary": "Desfez a edição $1 de [[Special:Contributions/$2|$2]] ([[User talk:$2|Discussão]])",
+       "undo-summary": "Desfez a edição $1 de [[Special:Contributions/$2|$2]] ([[User talk:$2|discussão]])",
        "undo-summary-username-hidden": "Desfez a edição $1 de um utilizador oculto",
        "cantcreateaccount-text": "A criação de contas a partir deste endereço IP (<strong>$1</strong>) foi bloqueada por [[User:$3|$3]].\n\nO motivo apresentado por $3 foi <em>$2</em>",
        "cantcreateaccount-range-text": "A criação de conta a partir dos endereços IP no intervalo <strong>$1</strong>, que inclui o seu endereço IP (<strong>$4</strong>), foi bloqueada por [[User:$3|$3]].\n\nO motivo apresentado por $3 foi <em>$2</em>",
        "rev-deleted-comment": "(resumo da edição suprimido)",
        "rev-deleted-user": "(nome de utilizador removido)",
        "rev-deleted-event": "(registos de detalhes eliminados)",
-       "rev-deleted-user-contribs": "[nome de utilizador(a) ou IP removido do histórico – edição ocultada das contribuições públicas]",
+       "rev-deleted-user-contribs": "[nome de utilizador ou IP removido do histórico – edição ocultada das contribuições públicas]",
        "rev-deleted-text-permission": "Esta revisão de página foi <strong>eliminada</strong>.\nEncontrará detalhes no [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} registo de eliminações].",
        "rev-suppressed-text-permission": "Esta revisão de página foi <strong>suprimida</strong>.\nPode consultar os detalhes no [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} registo de supressões].",
        "rev-deleted-text-unhide": "Esta revisão de página foi <strong>eliminada</strong>.\nEncontrará detalhes no [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} registo de eliminações].\nPode mesmo assim [$1 ver esta revisão] se deseja prosseguir.",
        "diff-paragraph-moved-toold": "O parágrafo foi movido. Clique para saltar para a posição anterior.",
        "difference-missing-revision": "{{PLURAL:$2|Uma revisão|$2 revisões}} desta diferença ($1) não {{PLURAL:$2|foi encontrada|foram encontradas}}.\n\nIsto é geralmente causado por seguir uma hiperligação de diferenças desatualizada para uma página que foi eliminada.\nOs detalhes podem ser encontrados no [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} registo de eliminação].",
        "searchresults": "Resultados da pesquisa",
+       "search-filter-title-prefix": "A pesquisar só nas páginas cujo título começa por \"$1\"",
+       "search-filter-title-prefix-reset": "Pesquisar em todas as páginas",
        "searchresults-title": "Resultados da pesquisa de \"$1\"",
        "titlematches": "Resultados no título das páginas",
        "textmatches": "Resultados no conteúdo das páginas",
        "datedefault": "Sem preferência",
        "prefs-labs": "Funcionalidades dos laboratórios",
        "prefs-user-pages": "Páginas de utilizador",
-       "prefs-personal": "Dados do utilizador",
+       "prefs-personal": "Dados pessoais",
        "prefs-rc": "Mudanças recentes",
        "prefs-watchlist": "Páginas vigiadas",
        "prefs-editwatchlist": "Editar lista de páginas vigiadas",
        "gender-unknown": "Ao mencioná-lo, o software irá utilizar palavras de género neutro sempre que possível",
        "gender-male": "Ele é um utilizador",
        "gender-female": "Ela é uma utilizadora",
-       "prefs-help-gender": "Esta preferência é opcional.\nO software usa o seu valor para o endereçar e para o mencionar a outros usando o género gramatical apropriado.\nEsta informação será pública.",
+       "prefs-help-gender": "Esta preferência é opcional.\nO ''software'' usa o valor para se dirigir a si e para o mencionar a outros usando o género gramatical apropriado.\nEsta informação será pública.",
        "email": "Correio eletrónico",
        "prefs-help-realname": "O fornecimento do nome verdadeiro é opcional.\nSe optar por revelá-lo, será utilizado para atribuir-lhe crédito pelo seu trabalho.",
        "prefs-help-email": "Opcional: o endereço de correio eletrónico é opcional, mas será necessário para redefinir a palavra-passe caso esqueça a antiga.",
        "userrights-lookup-user": "Selecionar um utilizador",
        "userrights-user-editname": "Introduza um nome de utilizador:",
        "editusergroup": "Carregar grupos do utilizador",
-       "editinguser": "A modificar os privilégios {{GENDER:$1|do utilizador|da utilizadora|do(a) utilizador(a)}}  <strong>[[User:$1|$1]]</strong> $2",
+       "editinguser": "A modificar os privilégios {{GENDER:$1|do utilizador|da utilizadora}}  <strong>[[User:$1|$1]]</strong> $2",
        "viewinguserrights": "A ver os privilégios {{GENDER:$1|do utilizador|da utilizadora}} <strong>[[User:$1|$1]]</strong> $2",
        "userrights-editusergroup": "Editar grupos {{GENDER:$1|do utilizador|da utilizadora}}",
        "userrights-viewusergroup": "Ver grupos {{GENDER:$1|do utilizador|da utilizadora}}",
-       "saveusergroups": "Gravar grupos {{GENDER:$1|do utilizador|da utilizadora|do(a) utilizador(a)}}",
+       "saveusergroups": "Gravar grupos {{GENDER:$1|do utilizador|da utilizadora}}",
        "userrights-groupsmember": "Membro de:",
        "userrights-groupsmember-auto": "Membro implícito de:",
        "userrights-groupsmember-type": "$1",
        "group-autoconfirmed": "Utilizadores autoconfirmados",
        "group-bot": "Robôs",
        "group-sysop": "Administradores",
+       "group-interface-admin": "Administradores da interface",
        "group-bureaucrat": "Burocratas",
        "group-suppress": "Supressores",
        "group-all": "(todos)",
        "group-user-member": "{{GENDER:$1|utilizador|utilizadora}}",
-       "group-autoconfirmed-member": "{{GENDER:$1|utilizador autoconfirmado|utilizadora autoconfirmada|utilizador(a) autoconfirmado(a)}}",
+       "group-autoconfirmed-member": "{{GENDER:$1|utilizador autoconfirmado|utilizadora autoconfirmada}}",
        "group-bot-member": "{{GENDER:$1|robô}}",
        "group-sysop-member": "{{GENDER:$1|administrador|administradora}}",
+       "group-interface-admin-member": "{{GENDER:$1|administrador|administradora}} da interface",
        "group-bureaucrat-member": "{{GENDER:$1|burocrata}}",
-       "group-suppress-member": "{{GENDER:$1|supressor|supressora|supressor(a)}}",
+       "group-suppress-member": "{{GENDER:$1|supressor|supressora}}",
        "grouppage-user": "{{ns:project}}:Utilizadores",
        "grouppage-autoconfirmed": "{{ns:project}}:Autoconfirmados",
        "grouppage-bot": "{{ns:project}}:Robôs",
        "grouppage-sysop": "{{ns:project}}:Administradores",
+       "grouppage-interface-admin": "{{ns:project}}:Administradores da interface",
        "grouppage-bureaucrat": "{{ns:project}}:Burocratas",
        "grouppage-suppress": "{{ns:project}}:Suprimir",
        "right-read": "Ler páginas",
        "right-editusercss": "Editar os ficheiros CSS de outros utilizadores",
        "right-edituserjson": "Editar os ficheiros JSON de outros utilizadores",
        "right-edituserjs": "Editar os ficheiros JS de outros utilizadores",
+       "right-editsitecss": "Editar CSS global do ''site''",
+       "right-editsitejson": "Editar JSON global do ''site''",
+       "right-editsitejs": "Editar JavaScript global do ''site''",
        "right-editmyusercss": "Editar os seus próprios ficheiros CSS de utilizador",
        "right-editmyuserjson": "Editar os ficheiros JSON do próprio utilizador",
        "right-editmyuserjs": "Editar os seus próprios ficheiros JavaScript de utilizador",
        "grant-createaccount": "Criar contas",
        "grant-createeditmovepage": "Criar, editar e mover páginas",
        "grant-delete": "Eliminar páginas, revisões e entradas de registo",
-       "grant-editinterface": "Editar o domínio MediaWiki e o CSS/JSON/JavaScript do utilizador",
+       "grant-editinterface": "Editar o espaço nominal/domínio MediaWiki e o JSON dos utilizadores ou global do ''site''",
        "grant-editmycssjs": "Editar o seu CSS/JSON/JavaScript personalizado",
        "grant-editmyoptions": "Editar as suas preferências de utilizador",
        "grant-editmywatchlist": "Editar a sua lista de páginas vigiadas",
+       "grant-editsiteconfig": "Editar o CSS e JS dos utilizadores ou global do ''site''",
        "grant-editpage": "Editar páginas existentes",
        "grant-editprotected": "Editar páginas protegidas",
        "grant-highvolume": "Alta quantidade de edições",
        "rcfilters-other-review-tools": "Outras ferramentas de revisão",
        "rcfilters-group-results-by-page": "Agrupar resultados por página",
        "rcfilters-activefilters": "Filtros ativos",
+       "rcfilters-activefilters-hide": "Ocultar",
+       "rcfilters-activefilters-show": "Mostrar",
+       "rcfilters-activefilters-hide-tooltip": "Ocultar a área dos filtros ativos",
+       "rcfilters-activefilters-show-tooltip": "Mostrar a área dos filtros ativos",
        "rcfilters-advancedfilters": "Filtros avançados",
        "rcfilters-limit-title": "Resultados a mostrar",
        "rcfilters-limit-and-date-label": "$1 {{PLURAL:$1|mudança|mudanças}}, $2",
        "rcfilters-savedqueries-rename": "Alterar o nome",
        "rcfilters-savedqueries-setdefault": "Ativar por padrão",
        "rcfilters-savedqueries-unsetdefault": "Remover por padrão",
-       "rcfilters-savedqueries-remove": "Remover",
+       "rcfilters-savedqueries-remove": "Eliminar",
        "rcfilters-savedqueries-new-name-label": "Nome",
        "rcfilters-savedqueries-new-name-placeholder": "Descreve o propósito do filtro",
        "rcfilters-savedqueries-apply-label": "Criar filtro",
        "rcfilters-empty-filter": "Não há filtros ativos. São mostradas todas as contribuições.",
        "rcfilters-filterlist-title": "Filtros",
        "rcfilters-filterlist-whatsthis": "Como é que funcionam?",
-       "rcfilters-filterlist-feedbacklink": "Diga-nos o que acha das (novas) ferramentas de filtragem",
+       "rcfilters-filterlist-feedbacklink": "Diga-nos o que acha destas ferramentas de filtragem",
        "rcfilters-highlightbutton-title": "Realçar resultados",
        "rcfilters-highlightmenu-title": "Selecionar uma cor",
        "rcfilters-highlightmenu-help": "Selecione uma cor para realçar esta propriedade",
        "rcfilters-watchlist-showupdated": "As mudanças das páginas que ainda não visitou após terem sido alteradas aparecem a <strong>negrito</strong>, com marcadores sólidos.",
        "rcfilters-preference-label": "Ocultar a versão melhorada das mudanças recentes",
        "rcfilters-preference-help": "Reverte o redesenho da interface de 2017 e todas as ferramentas adicionadas na altura e desde então.",
+       "rcfilters-watchlist-preference-label": "Ocultar a versão melhorada das páginas vigiadas",
+       "rcfilters-watchlist-preference-help": "Reverte o redesenho da interface em 2017 e todas as ferramentas adicionadas nessa altura e desde então.",
        "rcfilters-filter-showlinkedfrom-label": "Mostrar mudanças de páginas para as quais esta página contém hiperligações",
        "rcfilters-filter-showlinkedfrom-option-label": "<strong>Páginas para as quais</strong> a página selecionada contém hiperligações",
        "rcfilters-filter-showlinkedto-label": "Mostrar mudanças nas páginas que contêm hiperligações para",
        "uploadstash-zero-length": "O ficheiro tem tamanho zero.",
        "invalid-chunk-offset": "Deslocamento de fragmento inválido",
        "img-auth-accessdenied": "Acesso negado",
-       "img-auth-nopathinfo": "PATH_INFO em falta.\nO seu servidor não está configurado para passar esta informação.\nPode ser baseado em CGI e não consegue suportar img_auth.\nConsulte a documentação em https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization.",
+       "img-auth-nopathinfo": "Informação do caminho em falta.\nO seu servidor tem de estar configurado para passar as variáveis REQUEST_URI e/ou PATH_INFO.\nSe já está, tente ativar $wgUsePathInfo.\nConsulte https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization.",
        "img-auth-notindir": "O endereço especificado não conduz ao diretório de carregamento de ficheiros configurado.",
        "img-auth-badtitle": "Não é possível construir um título válido a partir de \"$1\".",
        "img-auth-nologinnWL": "Não tem a sessão iniciada e o ficheiro \"$1\" não está na lista branca.",
        "http-timed-out": "O pedido HTTP expirou.",
        "http-curl-error": "Ocorreu um erro ao aceder ao URL: $1",
        "http-bad-status": "Ocorreu um problema durante o pedido HTTP: $1 $2",
+       "http-internal-error": "Erro interno do HTTP.",
        "upload-curl-error6": "Não foi possível aceder ao URL",
        "upload-curl-error6-text": "Não foi possível aceder ao URL.\nVerifique se o endereço está correto e o sítio disponível, por favor.",
        "upload-curl-error28": "Tempo limite para o envio do ficheiro excedido",
        "uploadnewversion-linktext": "Carregar uma nova versão deste ficheiro",
        "shared-repo-from": "de $1",
        "shared-repo": "um repositório partilhado",
+       "filepage.css": "/* Os estilos CSS colocados aqui serão incluídos na página de descrição do ficheiro, também incluída nas wikis clientes externas */",
        "upload-disallowed-here": "Não pode substituir este ficheiro.",
        "filerevert": "Reverter $1",
        "filerevert-legend": "Reverter ficheiro",
        "mostinterwikis": "Páginas com mais hiperligações interwikis",
        "mostrevisions": "Páginas com mais revisões",
        "prefixindex": "Todas as páginas iniciadas por",
-       "prefixindex-namespace": "Todas as páginas com prefixo (domínio $1)",
+       "prefixindex-namespace": "Todas as páginas com prefixo (espaço nominal $1)",
        "prefixindex-submit": "Mostrar",
        "prefixindex-strip": "Remover prefixo",
        "shortpages": "Páginas curtas",
        "protectedtitles-submit": "Mostrar títulos",
        "listusers": "Utilizadores",
        "listusers-editsonly": "Mostrar apenas utilizadores com edições",
+       "listusers-temporarygroupsonly": "Mostrar apenas os utilizadores em grupos de utilizadores temporários",
        "listusers-creationsort": "Ordenar por data de criação",
        "listusers-desc": "Ordenar de forma decrescente",
        "usereditcount": "$1 {{PLURAL:$1|edição|edições}}",
        "speciallogtitlelabel": "Alvo (título ou página ou {{ns:user}}:nome de utilizador):",
        "log": "Registos",
        "logeventslist-submit": "Mostrar",
+       "logeventslist-more-filters": "Mostrar registos adicionais:",
+       "logeventslist-patrol-log": "Registo de edições patrulhadas",
+       "logeventslist-tag-log": "Registo de etiquetas",
        "all-logs-page": "Todos os registos públicos",
        "alllogstext": "Apresentação combinada de todos os registos disponíveis na wiki {{SITENAME}}.\nPode reduzir a lista escolhendo um tipo de registo, um nome de utilizador ou um título de página. Respeite maiúsculas e minúsculas.",
        "logempty": "Não existe nenhuma entrada correspondente no registo.",
        "listusersfrom": "Mostrar utilizadores começados por:",
        "listusers-submit": "Mostrar",
        "listusers-noresult": "Não foram encontrados utilizadores.",
-       "listusers-blocked": "({{GENDER:$1|bloqueado|bloqueada|bloqueado(a)}})",
+       "listusers-blocked": "({{GENDER:$1|bloqueado|bloqueada}})",
        "activeusers": "Utilizadores ativos",
        "activeusers-intro": "Esta é uma lista dos utilizadores com qualquer tipo de atividade {{PLURAL:$1|no último dia|nos últimos $1 dias}}.",
        "activeusers-count": "$1 {{PLURAL:$1|ação|ações}} {{PLURAL:$3|no último dia|nos últimos $3 dias}}",
        "listgrouprights-namespaceprotection-namespace": "Domínio",
        "listgrouprights-namespaceprotection-restrictedto": "Direito(s) do utilizador para editar",
        "listgrants": "Concessões de permissões a aplicações ligadas",
-       "listgrants-summary": "Esta é uma lista das possíveis concessões de permissões e das respetivas permissões dos utilizadores que são atribuídas por cada concessão. Os utilizadores podem autorizar aplicações a utilizar a sua conta, agindo assim em seu nome mas com as permissões limitadas com base nestas concessões. Uma aplicação que age em nome de um utilizador não pode utilizar permissões que o utilizador não possui.\nPoderá existir [[{{MediaWiki:Listgrouprights-helppage}}|informação adicional]] sobre as permissões individuais.",
+       "listgrants-summary": "Esta é uma lista das possíveis concessões de permissões e das respetivas permissões dos utilizadores que são atribuídas por cada concessão. Os utilizadores podem autorizar aplicações a utilizar a sua conta, agindo assim em seu nome mas com as permissões limitadas com base nestas concessões. Uma aplicação que age em nome de um utilizador não pode utilizar permissões que o utilizador não tem.\nPoderá existir [[{{MediaWiki:Listgrouprights-helppage}}|informação adicional]] sobre as permissões individuais.",
        "listgrants-grant": "Concessão de permissões",
        "listgrants-rights": "Permissões",
        "trackingcategories": "Categorias de monitorização",
        "nowikiemailtext": "Este utilizador optou por não receber correio eletrónico de outros utilizadores.",
        "emailnotarget": "O nome do destinatário não existe ou é inválido.",
        "emailtarget": "Introduza o nome do destinatário",
-       "emailusername": "Utilizador(a):",
+       "emailusername": "Utilizador:",
        "emailusernamesubmit": "Enviar",
        "email-legend": "Enviar uma mensagem a outro utilizador da wiki {{SITENAME}}",
        "emailfrom": "De:",
        "mywatchlist": "Páginas vigiadas",
        "watchlistfor2": "Para $1 $2",
        "nowatchlist": "A sua lista de páginas vigiadas está vazia.",
-       "watchlistanontext": "Por favor, inicie sessão para ver ou editar itens da sua lista de páginas vigiadas.",
+       "watchlistanontext": "Para ver ou editar entradas da sua lista de páginas vigiadas, inicie uma sessão, por favor.",
        "watchnologin": "Não está autenticado(a)",
        "addwatch": "Adicionar às páginas vigiadas",
-       "addedwatchtext": "\"[[:$1]]\" e a sua página de discussão foram adicionadas à sua [[Special:Watchlist|lista de páginas vigiadas]].",
-       "addedwatchtext-talk": "\"[[:$1]]\" e a sua página associada foram adicionadas à sua lista de [[Special:Watchlist|páginas vigiadas]].",
-       "addedwatchtext-short": "A página \"$1\" foi adicionada à sua lista de vigiadas.",
+       "addedwatchtext": "\"[[:$1]]\" e a respetiva página de discussão foram adicionadas à sua [[Special:Watchlist|lista de páginas vigiadas]].",
+       "addedwatchtext-talk": "\"[[:$1]]\" e a respetiva página associada foram adicionadas à sua lista de [[Special:Watchlist|páginas vigiadas]].",
+       "addedwatchtext-short": "A página \"$1\" foi adicionada às suas páginas vigiadas.",
        "removewatch": "Remover das páginas vigiadas",
-       "removedwatchtext": "\"[[:$1]]\" e a sua página de discussão foram removidas da sua lista de [[Special:Watchlist|páginas vigiadas]].",
-       "removedwatchtext-talk": "\"[[:$1]]\" e a sua página associada foram removidas da sua lista de [[Special:Watchlist|páginas vigiadas]].",
-       "removedwatchtext-short": "A página \"$1\" foi removida da sua lista de vigiadas.",
+       "removedwatchtext": "\"[[:$1]]\" e a respetiva página de discussão foram removidas da sua lista de [[Special:Watchlist|páginas vigiadas]].",
+       "removedwatchtext-talk": "\"[[:$1]]\" e a respetiva página associada foram removidas da sua lista de [[Special:Watchlist|páginas vigiadas]].",
+       "removedwatchtext-short": "A página \"$1\" foi removida das suas páginas vigiadas.",
        "watch": "Vigiar",
        "watchthispage": "Vigiar esta página",
-       "unwatch": "Desinteressar-se",
+       "unwatch": "Deixar de vigiar",
        "unwatchthispage": "Parar de vigiar esta página",
        "notanarticle": "Não é uma página de conteúdo",
-       "notvisiblerev": "Edição eliminada",
+       "notvisiblerev": "A última revisão feita por um utilizador diferente foi eliminada",
        "watchlist-details": "{{PLURAL:$1|Existe $1 página|Existem $1 páginas}} na sua lista de páginas vigiadas (mais as páginas de discussão).",
        "wlheader-enotif": "A notificação por correio eletrónico está ativa.",
        "wlheader-showupdated": "As páginas modificadas desde a última vez que as visitou aparecem destacadas a <strong>negrito</strong>.",
        "deletepage": "Eliminar página",
        "confirm": "Confirmar",
        "excontent": "o conteúdo era: \"$1\"",
-       "excontentauthor": "o conteúdo era: \"$1\", e {{GENDER:$2|o único editor|a única editora|o(a) único(a) editor(a)}} era [[Special:Contributions/$2|$2]] ([[User talk:$2|discussão]])",
+       "excontentauthor": "o conteúdo era: \"$1\", e {{GENDER:$2|o único editor|a única editora}} era [[Special:Contributions/$2|$2]] ([[User talk:$2|discussão]])",
        "exbeforeblank": "o conteúdo antes de esvaziar era: \"$1\"",
        "delete-confirm": "Eliminar \"$1\"",
        "delete-legend": "Eliminar",
        "actionfailed": "Operação falhou",
        "deletedtext": "\"$1\" foi eliminada.\nConsulte $2 para um registo de eliminações recentes.",
        "dellogpage": "Registo de eliminações",
-       "dellogpagetext": "Abaixo uma lista das eliminações mais recentes.",
+       "dellogpagetext": "Encontra abaixo uma lista das eliminações mais recentes.",
        "deletionlog": "registo de eliminações",
+       "log-name-create": "Registo de criação de páginas",
+       "log-description-create": "Encontra abaixo uma lista das criações de páginas mais recentes.",
+       "logentry-create-create": "$1 {{GENDER:$2|criou}} a página $3",
        "reverted": "Revertido para versão anterior",
        "deletecomment": "Motivo:",
        "deleteotherreason": "Outro/motivo adicional:",
        "undelete-error-long": "Foram encontrados erros ao tentar restaurar o ficheiro:\n\n$1",
        "undelete-show-file-confirm": "Tem a certeza de que quer ver a revisão eliminada do ficheiro \"<nowiki>$1</nowiki>\" de $2 às $3?",
        "undelete-show-file-submit": "Sim",
-       "namespace": "Domínio:",
+       "namespace": "Espaço nominal:",
        "invert": "Inverter seleção",
        "tooltip-invert": "Marque esta caixa para esconder as alterações a páginas no domínio selecionado (e no domínio associado, se escolheu fazê-lo)",
        "tooltip-whatlinkshere-invert": "Marque esta caixa de seleção para ocultar ligações de páginas dentro do domínio selecionado.",
-       "namespace_association": "Domínio associado",
+       "namespace_association": "Espaço nominal associado",
        "tooltip-namespace_association": "Marque esta caixa para incluir também o domínio de conteúdo ou de discussão associado à sua seleção",
        "blanknamespace": "(Principal)",
        "contributions": "Contribuições {{GENDER:$1|do utilizador|da utilizadora}}",
        "uctop": "(atual)",
        "month": "Até o mês:",
        "year": "Até o ano:",
+       "date": "Na data (e anteriores):",
        "sp-contributions-newbies": "Mostrar só as contribuições de contas recentes",
        "sp-contributions-newbies-sub": "Para contas novas",
        "sp-contributions-newbies-title": "Contribuições de contas novas",
        "sp-contributions-blocklog": "registo de bloqueios",
        "sp-contributions-suppresslog": "contribuições suprimidas {{GENDER:$1|do utilizador|da utilizadora}}",
-       "sp-contributions-deleted": "contribuições eliminadas {{GENDER:$1|do utilizador|da utilizadora}}",
+       "sp-contributions-deleted": "{{GENDER:$1|contribuições}} eliminadas",
        "sp-contributions-uploads": "carregamentos",
        "sp-contributions-logs": "registos",
        "sp-contributions-talk": "discussão",
-       "sp-contributions-userrights": "Gestão de privilégios {{GENDER:$1|do utilizador|da utilizadora}}",
-       "sp-contributions-blocked-notice": "Este utilizador está bloqueado neste momento.\nPara referência é apresentado abaixo o último registo de bloqueio:",
+       "sp-contributions-userrights": "{{GENDER:$1|gestão}} dos privilégios",
+       "sp-contributions-blocked-notice": "{{GENDER:$1|Este utilizador está bloqueado|Esta utilizadora está bloqueada}} neste momento.\nPara referência é apresentado abaixo o último registo de bloqueio:",
        "sp-contributions-blocked-notice-anon": "Este endereço IP está bloqueado neste momento.\nPara referência é apresentado abaixo o último registo de bloqueio:",
        "sp-contributions-search": "Pesquisar contribuições",
        "sp-contributions-username": "Endereço IP ou nome de utilizador:",
        "whatlinkshere": "Páginas afluentes",
        "whatlinkshere-title": "Páginas com hiperligações para \"$1\"",
        "whatlinkshere-page": "Página:",
-       "linkshere-2": "As seguintes páginas têm hiperligações para <strong>$1</strong>:",
-       "nolinkshere-2": "Não existem afluentes para <strong>$1</strong> com as condições especificadas.",
-       "nolinkshere-ns-2": "Não existem afluentes para <strong>$1</strong> no espaço nominal selecionado.",
+       "linkshere": "As seguintes páginas têm hiperligações para <strong>$2</strong>:",
+       "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",
        "isimage": "hiperligação para ficheiro",
        "javascripttest": "Teste de JavaScript",
        "javascripttest-pagetext-unknownaction": "Ação \"$1\" desconhecida.",
        "javascripttest-qunit-intro": "Consulte a [ $1 documentação de testes] no mediawiki.org.",
-       "tooltip-pt-userpage": "A sua página de {{GENDER:|utilizador|utilizadora|utilizador(a)}}",
+       "tooltip-pt-userpage": "A sua página de {{GENDER:|utilizador|utilizadora}}",
        "tooltip-pt-anonuserpage": "A página de utilizador para o endereço IP que está a usar",
        "tooltip-pt-mytalk": "A {{GENDER:|sua}} página de discussão",
        "tooltip-pt-anontalk": "Discussão sobre edições feitas a partir deste endereço IP",
        "tooltip-t-recentchangeslinked": "Mudanças recentes nas páginas para as quais esta contém hiperligações",
        "tooltip-feed-rss": "''Feed'' RSS desta página",
        "tooltip-feed-atom": "''Feed'' Atom desta página",
-       "tooltip-t-contributions": "Ver as contribuições {{GENDER:$1|deste utilizador|desta utilizadora|deste(a) utilizador(a)}}",
-       "tooltip-t-emailuser": "Enviar uma mensagem de correio a {{GENDER:$1|este utilizador|esta utilizadora|este(a) utilizador(a)}}",
+       "tooltip-t-contributions": "Ver as contribuições {{GENDER:$1|deste utilizador|desta utilizadora}}",
+       "tooltip-t-emailuser": "Enviar uma mensagem de correio a {{GENDER:$1|este utilizador|esta utilizadora}}",
        "tooltip-t-info": "Mais informações sobre esta página",
        "tooltip-t-upload": "Carregar ficheiros",
        "tooltip-t-specialpages": "Lista de páginas especiais",
        "interlanguage-link-title-nonlang": "$1 – $2",
        "common.css": "/* Código CSS colocado aqui será aplicado a todos os temas */",
        "print.css": "/* Código CSS colocado aqui afectará as impressões */",
-       "noscript.css": "/* Os estilos CSS colocados aqui afetarão os utilizadores que tenham o JavaScript desativado em seus navegadores */",
+       "noscript.css": "/* Os estilos CSS colocados aqui afetarão os utilizadores que tenham o JavaScript desativado */",
+       "group-autoconfirmed.css": "/* Os estilos CSS colocados aqui só afetarão os utilizadores autoconfirmados */",
+       "group-user.css": "/* Os estilos CSS colocados aqui só afetarão os utilizadores registados */",
+       "group-bot.css": "/* Os estilos CSS colocados aqui só afetarão robôs */",
+       "group-sysop.css": "/* Os estilos CSS colocados aqui só afetarão os administradores */",
+       "group-bureaucrat.css": "/* Os estilos CSS colocados aqui só afetarão os burocratas */",
        "common.json": "/* Qualquer JSON colocado aqui será carregado para todos os utilizadores em cada carregamento de página. */",
        "common.js": "/* Código Javascript colocado aqui será carregado para todos os utilizadores em cada carregamento de página */",
+       "group-autoconfirmed.js": "/* O código JavaScript colocado aqui só será carregado para utilizadores autoconfirmados */",
+       "group-user.js": "/* O código JavaScript colocado aqui só será carregado para utilizadores registados */",
+       "group-bot.js": "/* O código JavaScript colocado aqui só será carregado para robôs */",
+       "group-sysop.js": "/* O código JavaScript colocado aqui só será carregado para administradores */",
+       "group-bureaucrat.js": "/* O código JavaScript colocado aqui só será carregado para burocratas */",
        "anonymous": "{{PLURAL:$1|Utilizador anónimo|Utilizadores anónimos}} da wiki {{SITENAME}}",
        "siteuser": "$1 da wiki {{SITENAME}}",
        "anonuser": "utilizador anónimo $1 da wiki {{SITENAME}}",
-       "lastmodifiedatby": "Esta página foi editada pela última vez à(s) $2 de $1 por $3.",
+       "lastmodifiedatby": "Esta página foi editada pela última vez às $2 de $1 por $3.",
        "othercontribs": "Baseado no trabalho de $1.",
        "others": "outros",
        "siteusers": "{{PLURAL:$2|um utilizador|$2 utilizadores}} da wiki {{SITENAME}} ($1)",
        "markaspatrolledtext-file": "Marcar esta versão do ficheiro como patrulhada",
        "markedaspatrolled": "Marcada como patrulhada",
        "markedaspatrolledtext": "A edição selecionada de [[:$1]] foi marcada como patrulhada.",
-       "rcpatroldisabled": "Edições patrulhadas nas Mudanças Recentes desativadas",
-       "rcpatroldisabledtext": "A funcionalidade de edições patrulhadas nas Mudanças Recentes está atualmente desativada.",
+       "rcpatroldisabled": "Edições patrulhadas nas mudanças recentes desativadas",
+       "rcpatroldisabledtext": "A funcionalidade de edições patrulhadas nas mudanças recentes está atualmente desativada.",
        "markedaspatrollederror": "Não é possível marcar como patrulhada",
        "markedaspatrollederrortext": "É necessário especificar uma edição a ser marcada como patrulhada.",
        "markedaspatrollederror-noautopatrol": "Não está autorizado a marcar as suas próprias edições como edições patrulhadas.",
        "markedaspatrollederrornotify": "A marcação como patrulhada falhou.",
        "patrol-log-page": "Registo de edições patrulhadas",
        "patrol-log-header": "Este é um registo de edições patrulhadas.",
-       "log-show-hide-patrol": "$1 registo de edições patrulhadas",
-       "log-show-hide-tag": "$1 registo de etiquetas",
        "confirm-markpatrolled-button": "OK",
        "confirm-markpatrolled-top": "Marcar a revisão $3 de $2 como patrulhada?",
        "deletedrevision": "Apagou a versão antiga $1",
        "exif-compression-2": "CCITT Grupo 3 1-D Codificação Unidimensional Huffman Modificado e Run Length Encoding",
        "exif-compression-3": "CCITT Grupo 3 codificação de fax",
        "exif-compression-4": "CCITT Grupo 4 codificação de fax",
+       "exif-compression-6": "JPEG (antigo)",
        "exif-copyrighted-true": "Direitos de autor reservados",
        "exif-copyrighted-false": "Estado dos direitos de autor indefinido",
-       "exif-photometricinterpretation-1": "Preto e branco (Preto é 0)",
+       "exif-photometricinterpretation-0": "Preto e branco (branco é 0)",
+       "exif-photometricinterpretation-1": "Preto e branco (preto é 0)",
+       "exif-photometricinterpretation-3": "Palete",
+       "exif-photometricinterpretation-4": "Máscara de transparência",
+       "exif-photometricinterpretation-5": "Separados (provavelmente CMYK)",
+       "exif-photometricinterpretation-9": "CIE L*a*b* (codificação ICC)",
+       "exif-photometricinterpretation-10": "CIE L*a*b* (codificação ITU)",
+       "exif-photometricinterpretation-32803": "Matriz de filtros de cores",
+       "exif-photometricinterpretation-34892": "Linear não processado",
        "exif-unknowndate": "Data desconhecida",
        "exif-orientation-1": "Normal",
        "exif-orientation-2": "Espelhamento horizontal",
        "exif-orientation-8": "Rodado 90° no sentido horário",
        "exif-planarconfiguration-1": "formato irregular",
        "exif-planarconfiguration-2": "formato plano",
+       "exif-xyresolution-i": "$1 ppp",
        "exif-xyresolution-c": "$1 pt/cm",
        "exif-colorspace-65535": "Cor não calibrada",
        "exif-componentsconfiguration-0": "não existe",
        "exif-meteringmode-1": "Média",
        "exif-meteringmode-2": "MédiaPonderadaAoCentro",
        "exif-meteringmode-3": "Ponto",
-       "exif-meteringmode-4": "MultiPonto",
+       "exif-meteringmode-4": "Multiponto",
        "exif-meteringmode-5": "Padrão",
        "exif-meteringmode-6": "Parcial",
        "exif-meteringmode-255": "Outro",
        "confirm-purge-title": "Purgar esta página",
        "confirm_purge_button": "OK",
        "confirm-purge-top": "Limpar esta página da memória cache?",
-       "confirm-purge-bottom": "Recarregar uma página limpa a cache e força a sua versão mais recente a aparecer.",
+       "confirm-purge-bottom": "Purgar uma página limpa-a da ''cache'' e força a sua versão mais recente a aparecer.",
        "confirm-watch-button": "OK",
        "confirm-watch-top": "Adicionar esta página à lista de páginas vigiadas?",
        "confirm-unwatch-button": "OK",
        "autosumm-changed-redirect-target": "Alteração do redirecionamento de [[$1]] para [[$2]]",
        "autosumm-new": "Criou a página com \"$1\"",
        "autosumm-newblank": "Página em branco criada",
-       "lag-warn-normal": "Alterações realizadas {{PLURAL:$1|no último segundo|nos últimos $1 segundos}} podem não constar desta lista.",
-       "lag-warn-high": "Devido a latência elevada no acesso ao servidor da base de dados, as alterações realizadas {{PLURAL:$1|no último segundo|nos últimos $1 segundos}} podem não constar desta lista.",
+       "size-pixel": "$1 {{PLURAL:$1|píxel|píxeis}}",
+       "lag-warn-normal": "As alterações realizadas {{PLURAL:$1|no último segundo|nos últimos $1 segundos}} podem não constar desta lista.",
+       "lag-warn-high": "Devido a uma latência elevada no acesso ao servidor da base de dados, as alterações realizadas {{PLURAL:$1|no último segundo|nos últimos $1 segundos}} podem não constar desta lista.",
        "watchlistedit-normal-title": "Editar lista de páginas vigiadas",
        "watchlistedit-normal-legend": "Remover páginas da lista de páginas vigiadas",
        "watchlistedit-normal-explain": "As suas páginas vigiadas são listadas abaixo.\nPara remover uma página, marque a caixa de seleção correspondente e clique o botão \"{{int:Watchlistedit-normal-submit}}\".\nTambém pode [[Special:EditWatchlist/raw|editar a lista de páginas vigiadas em forma de texto]].",
        "watchlistedit-clear-explain": "Todos os títulos serão removidos da sua lista de páginas vigiadas.",
        "watchlistedit-clear-titles": "Páginas:",
        "watchlistedit-clear-submit": "Limpar páginas vigiadas (isto é permanente!)",
-       "watchlistedit-clear-done": "A sua lista de páginas vigiadas foi limpa.",
+       "watchlistedit-clear-done": "A sua lista de páginas vigiadas foi esvaziada.",
        "watchlistedit-clear-jobqueue": "A sua lista de páginas vigiadas está a ser esvaziada. Esta operação pode ser demorada.",
        "watchlistedit-clear-removed": "{{PLURAL:$1|1 página foi removida|$1 páginas foram removidas}}:",
        "watchlistedit-too-many": "Existem demasiadas páginas para apresentar.",
        "logentry-protect-protect-cascade": "$1 {{GENDER:$2|protegeu}} $3 $4 [em cascata]",
        "logentry-protect-modify": "$1 {{GENDER:$2|alterou}} o nível de proteção para $3 $4",
        "logentry-protect-modify-cascade": "$1 {{GENDER:$2|alterou}} o nível de proteção para $3 $4 [em cascata]",
-       "logentry-rights-rights": "$1 {{GENDER:$2|modificou}} os privilégios {{GENDER:$3|do utilizador $3|da utilizadora $3|do(a) utilizador(a) $3}} de $4 para $5",
+       "logentry-rights-rights": "$1 {{GENDER:$2|modificou}} os privilégios {{GENDER:$3|do utilizador|da utilizadora}} $3 de $4 para $5",
        "logentry-rights-rights-legacy": "$1 alterou os grupos de $3",
        "logentry-rights-autopromote": "$1 foi automaticamente {{GENDER:$2|promovido|promovida}} de $4 a $5",
        "logentry-upload-upload": "$1 {{GENDER:$2|carregou}} $3",
        "authmanager-email-label": "Correio eletrónico",
        "authmanager-email-help": "Endereço de correio eletrónico",
        "authmanager-realname-label": "Nome verdadeiro",
-       "authmanager-realname-help": "Nome verdadeiro do(a) utilizador(a)",
+       "authmanager-realname-help": "Nome verdadeiro do utilizador",
        "authmanager-provider-password": "Autenticação baseada em palavra-passe",
        "authmanager-provider-password-domain": "Autenticação baseada em palavra-passe e domínio",
        "authmanager-provider-temporarypassword": "Palavra-passe temporária",
        "pagedata-text": "Esta página fornece uma interface de dados para páginas. Forneça o título da página no URL, usando a sintaxe de subpáginas, por favor.\n* Aplica-se a negociação de conteúdo com base no cabeçalho Accept do seu cliente. Isto significa que os dados da página serão fornecidos no formato preferido do seu cliente.",
        "pagedata-not-acceptable": "Não foi encontrado nenhum formato correspondente. Tipos MIME suportados: $1",
        "pagedata-bad-title": "Título inválido: $1.",
-       "unregistered-user-config": "Por razões de segurança as subpáginas de utilizador com JavaScript, CSS e JSON não podem ser carregadas para utilizadores não registados."
+       "unregistered-user-config": "Por razões de segurança as subpáginas de utilizador com JavaScript, CSS e JSON não podem ser carregadas para utilizadores não registados.",
+       "passwordpolicies": "Regras para palavras-passe",
+       "passwordpolicies-summary": "Esta lista contém as normas efetivas para palavras-passe dos grupos de utilizadores definidos nesta wiki.",
+       "passwordpolicies-group": "Grupo",
+       "passwordpolicies-policies": "Normas e recomendações",
+       "passwordpolicies-policy-minimalpasswordlength": "A palavra-passe tem de ter pelo menos $1 {{PLURAL:$1|carácter|caracteres}}",
+       "passwordpolicies-policy-minimumpasswordlengthtologin": "A palavra-passe tem de ter pelo menos $1 {{PLURAL:$1|carácter|caracteres}} para poder iniciar sessão",
+       "passwordpolicies-policy-passwordcannotmatchusername": "A palavra-passe não pode ser igual ao nome de utilizador",
+       "passwordpolicies-policy-passwordcannotmatchblacklist": "A palavra-passe não pode corresponder às especificamente bloqueadas pela lista negra",
+       "passwordpolicies-policy-maximalpasswordlength": "A palavra-passe tem de ter menos de $1 {{PLURAL:$1|carácter|caracteres}}",
+       "passwordpolicies-policy-passwordcannotbepopular": "A palavra-passe não pode {{PLURAL:$1|ser a mais popular|estar na lista das $1 palavras-passe mais populares}}",
+       "easydeflate-invaliddeflate": "O conteúdo fornecido não está devidamente comprimido"
 }
index 2551051..41765df 100644 (file)
                        "Acamicamacaraca",
                        "Avatar6",
                        "Akapochtli",
-                       "ديفيد"
+                       "ديفيد",
+                       "Daimona Eaytoy"
                ]
        },
        "sidebar": "{{notranslate}}",
        "customcssprotected": "Used as error message. Parameters:\n* $1 - (Unused) the action the user attempted to perform",
        "customjsonprotected": "Used as error message. Parameters:\n* $1 - (Unused) the action the user attempted to perform",
        "customjsprotected": "Used as error message. Parameters:\n* $1 - (Unused) the action the user attempted to perform",
+       "sitecssprotected": "Used as error message. Parameters:\n* $1 - (Unused) the action the user attempted to perform",
+       "sitejsonprotected": "Used as error message. Parameters:\n* $1 - (Unused) the action the user attempted to perform",
+       "sitejsprotected": "Used as error message. Parameters:\n* $1 - (Unused) the action the user attempted to perform",
        "mycustomcssprotected": "Used as error message. Parameters:\n* $1 - (Unused) the action the user attempted to perform",
        "mycustomjsonprotected": "Used as error message. Parameters:\n* $1 - (Unused) the action the user attempted to perform",
        "mycustomjsprotected": "Used as error message. Parameters:\n* $1 - (Unused) the action the user attempted to perform",
        "expansion-depth-exceeded-category": "This message is used as a category name for a [[mw:Help:Tracking categories|tracking category]] where pages are placed automatically if the [[meta:Help:Expansion_depth|expansion depth]] of the preprocessor exceeds the limit.",
        "expansion-depth-exceeded-category-desc": "Expansion depth exceeded category description. Shown on [[Special:TrackingCategories]].\n\nSee also:\n* {{msg-mw|Expansion-depth-exceeded-category}}",
        "expansion-depth-exceeded-warning": "Error message shown when a page exceeded the [[meta:Help:Expansion_depth|expansion depth limit]] of the preprocessor.\n\nParameters:\n* $1 - (Unused) the value of the depth limit\n* $2 - (Unused) the value of the max depth limit\nSee also:\n* {{msg-mw|Expansion-depth-exceeded-category}}",
-       "parser-unstrip-loop-warning": "{{Doc-important|Do not translate function name <code>unstrip</code>.}}\nThis error is shown when a parser extension tag such as <code><nowiki><pre></nowiki></code> includes a reference to itself in its own output.\n\nThe reference must be to the exact same invocation of the tag at the same location in the source, merely writing <code><nowiki><pre><pre></pre></pre></nowiki></code> will not do it.\n\nThis is usually impossible and unlikely to happen by accident, so translation is not essential.\n\n\"Unstrip\" refers to the internal function of the parser, called \"unstrip\", which recursively puts the output of parser functions in the place of the parser function call and which would enter an infinite loop in the situation above.\n\nSee also:\n*{{msg-mw|Parser-unstrip-recursion-limit}}",
-       "unstrip-depth-warning": "{{doc-important|Do not translate function name <code>unstrip</code>.}}\nThis message is shown when the recursion limit for nested parser extension tags is exceeded.\n\nThis warning may be encountered due to input text like <code><nowiki><ref><ref><ref>...</ref></ref></ref></nowiki></code>.\n\nParameters:\n* $1 - the depth limit\n\n\"Unstrip\" refers to the internal function of the parser, called 'unstrip', which recursively puts the output of parser functions in the place of the parser function call.\n\nSee also:\n* {{msg-mw|Parser-unstrip-loop-warning}}",
-       "unstrip-depth-category": "This message is used as the category name of a [[mw:Help:Tracking categories|tracking category]] in which pages are placed automatically if the unstrip recursion depth limit is exceeded.",
-       "unstrip-size-warning": "{{doc-important|Do not translate function name <code>unstrip</code>.}}\nThis message is shown when the maximum expansion size for nested parser extension tags is exceeded.\n\nParameters:\n* $1 - the size limit\n\n\"Unstrip\" refers to the internal function of the parser, called 'unstrip', which recursively puts the output of parser functions in the place of the parser function call.\n\nSee also:\n* {{msg-mw|Parser-unstrip-loop-warning}}",
-       "unstrip-size-category": "This message is used as the category name of a [[mw:Help:Tracking categories|tracking category]] in which pages are placed automatically if the unstrip expansion size limit is exceeded.",
+       "parser-unstrip-loop-warning": "{{Doc-important|Do not translate function name <code>unstrip</code>.}}\nThis error is shown when a parser extension tag such as <code><nowiki><pre></nowiki></code> includes a reference to itself in its own output.\n\nThe reference must be to the exact same invocation of the tag at the same location in the source, merely writing <code><nowiki><pre><pre></pre></pre></nowiki></code> will not do it.\n\nThis is usually impossible and unlikely to happen by accident, so translation is not essential.\n\n\"Unstrip\" refers to the internal function of the parser, called \"unstrip\", which recursively puts the output of parser functions in the place of the parser function call and which would enter an infinite loop in the situation above.\n\nSee also:\n*{{msg-mw|Limitreport-unstrip-depth}}\n*{{msg-mw|Limitreport-unstrip-size}}\n*{{msg-mw|Unstrip-depth-category}}\n*{{msg-mw|Unstrip-depth-warning}}\n*{{msg-mw|Unstrip-size-category}}\n*{{msg-mw|Unstrip-size-warning}}",
+       "unstrip-depth-warning": "{{doc-important|Do not translate function name <code>unstrip</code>.}}\nThis message is shown when the recursion limit for nested parser extension tags is exceeded.\n\nThis warning may be encountered due to input text like <code><nowiki><ref><ref><ref>...</ref></ref></ref></nowiki></code>.\n\nParameters:\n* $1 - the depth limit\n\n\"Unstrip\" refers to the internal function of the parser, called 'unstrip', which recursively puts the output of parser functions in the place of the parser function call.\n\nSee also:\n*{{msg-mw|Limitreport-unstrip-depth}}\n*{{msg-mw|Limitreport-unstrip-size}}\n*{{msg-mw|Parser-unstrip-loop-warning}}\n*{{msg-mw|Unstrip-depth-category}}\n*{{msg-mw|Unstrip-size-category}}\n*{{msg-mw|Unstrip-size-warning}}",
+       "unstrip-depth-category": "{{Doc-important|Do not translate function name <code>unstrip</code>.}}\nThis message is used as the category name of a [[mw:Help:Tracking categories|tracking category]] in which pages are placed automatically if the unstrip recursion depth limit is exceeded.\n\n\"Unstrip\" refers to the internal function of the parser, called \"unstrip\", which recursively puts the output of parser functions in the place of the parser function call.\n\nSee also:\n*{{msg-mw|Limitreport-unstrip-depth}}\n*{{msg-mw|Limitreport-unstrip-size}}\n*{{msg-mw|Parser-unstrip-loop-warning}}\n*{{msg-mw|Unstrip-depth-warning}}\n*{{msg-mw|Unstrip-size-category}}\n*{{msg-mw|Unstrip-size-warning}}",
+       "unstrip-size-warning": "{{doc-important|Do not translate function name <code>unstrip</code>.}}\nThis message is shown when the maximum expansion size for nested parser extension tags is exceeded.\n\nParameters:\n* $1 - the size limit\n\n\"Unstrip\" refers to the internal function of the parser, called 'unstrip', which recursively puts the output of parser functions in the place of the parser function call.\n\nSee also:\n*{{msg-mw|Limitreport-unstrip-depth}}\n*{{msg-mw|Limitreport-unstrip-size}}\n*{{msg-mw|Parser-unstrip-loop-warning}}\n*{{msg-mw|Unstrip-depth-category}}\n*{{msg-mw|Unstrip-depth-warning}}\n*{{msg-mw|Unstrip-size-category}}",
+       "unstrip-size-category": "{{Doc-important|Do not translate function name <code>unstrip</code>.}}\nThis message is used as the category name of a [[mw:Help:Tracking categories|tracking category]] in which pages are placed automatically if the unstrip expansion size limit is exceeded.\n\n\"Unstrip\" refers to the internal function of the parser, called \"unstrip\", which recursively puts the output of parser functions in the place of the parser function call.\n\nSee also:\n*{{msg-mw|Limitreport-unstrip-depth}}\n*{{msg-mw|Limitreport-unstrip-size}}\n*{{msg-mw|Parser-unstrip-loop-warning}}\n*{{msg-mw|Unstrip-depth-category}}\n*{{msg-mw|Unstrip-depth-warning}}\n*{{msg-mw|Unstrip-size-warning}}",
        "converter-manual-rule-error": "Used as error message when a manual conversion rule for the [[mw:Language_converter|language converter]] has errors. For example it's not using the correct syntax, or not supplying text in all variants.",
        "undo-success": "Text on special page to confirm edit revert. You arrive on this page by clicking on the \"undo\" link on a revision history special page.\n\n{{Identical|Undo}}",
        "undo-failure": "Message appears if an attempt to revert an edit by clicking the \"undo\" link on the page history fails.\n\nSee also:\n* {{msg-mw|Undo-norev}}\n* {{msg-mw|Undo-nochange}}\n{{Identical|Undo}}",
+       "undo-main-slot-only": "Message appears if an attempt to revert an edit by clicking the \"undo\" link on the page history fails because it involves content outside the page's main slot, which is not yet supported.\nThis message is temporary, see https://phabricator.wikimedia.org/T189808\n\nSee also:\n* {{msg-mw|Undo-failure}}\n{{Identical|Undo}}",
        "undo-norev": "Message appears if an attempt to revert an edit by clicking the \"undo\" link on the page history fails.\n\nSee also:\n* {{msg-mw|Undo-failure}}\n* {{msg-mw|Undo-nochange}}\n{{Identical|Undo}}",
        "undo-nochange": "Message appears if an attempt to revert an edit by clicking the \"undo\" link results in an edit making no change to the current version of the page.\n\nSee also:\n* {{msg-mw|Undo-failure}}\n* {{msg-mw|Undo-norev}}",
        "undo-summary": "Edit summary for an undo action. Parameters:\n* $1 - revision ID\n* $2 - username\n{{Identical|Undo}}",
        "difference-missing-revision": "Text displayed when the requested revision does not exist using a diff link.\n\nExample: [{{canonicalurl:Project:News|diff=426850&oldid=99999999}} Diff with invalid revision#]\n\nParameters:\n* $1 - the list of missing revisions IDs\n* $2 - the number of items in $1 (one or two)",
        "search-summary": "{{doc-specialpagesummary|search}}",
        "searchresults": "This is the title of the page that contains the results of a search.\n\n{{Identical|Search results}}",
+       "search-filter-title-prefix": "Subtitle added to indicate that the user is filtering for pages whose title starts with $1, \n* $1 - the title prefix",
+       "search-filter-title-prefix-reset": "Appears next to {{msg-mw|search-filter-title-prefix}} as a link to let users reset the prefix filter",
        "searchresults-title": "Appears as page title in the html header of the search result special page.\n\nParameters:\n* $1 - the search term",
        "titlematches": "Used as section header in [[Special:Search]].\n\nThis message is followed by search results.",
        "textmatches": "When displaying search results",
        "prefs-editor": "Used in [[Special:Preferences]], tab \"Editing\" ({{int:prefs-editing}}).\n\n{{Identical|Editor}}",
        "prefs-preview": "Used in [[Special:Preferences]], tab \"Editing\".\n{{Identical|Preview}}",
        "prefs-advancedrc": "Used in [[Special:Preferences]], tab \"Recent changes\".\n{{Identical|Advanced options}}",
-       "prefs-opt-out": "Used in [[Special:Preferences]], tab \"Recent changes\".",
+       "prefs-opt-out": "Used in [[Special:Preferences]], tabs \"Recent changes\" and \"Watchlist\".",
        "prefs-advancedrendering": "Used in [[Special:Preferences]], tab \"Appearence\".\n{{Identical|Advanced options}}",
        "prefs-advancedsearchoptions": "Used in [[Special:Preferences]], tab \"Search options\".\n{{Identical|Advanced options}}",
        "prefs-advancedwatchlist": "Used in [[Special:Preferences]], tab \"Watchlist\".\n{{Identical|Advanced options}}",
        "group-autoconfirmed": "{{doc-group|autoconfirmed}}\nOn Wikimedia sites autoconfirmed users are users which are older than 4 days. After those 4 days, they have more rights.",
        "group-bot": "{{doc-group|bot}}\n{{Identical|Bot}}",
        "group-sysop": "{{doc-group|sysop}}\n{{Identical|Administrator}}",
+       "group-interface-admin": "{{doc-group|interface-admin}}",
        "group-bureaucrat": "{{doc-group|bureaucrat}}",
        "group-suppress": "{{doc-group|suppress}}\nThis is an optional (disabled by default) user group, meant for the suppression feature in [[mw:Flow|Flow]]. It is not to be confused with the Oversighters group, which also has access to the [[mw:RevisionDelete|RevisionDelete]] feature, to change the visibility of revisions through [[Special:RevisionDelete]].\n\n{{Identical|Suppress}}",
        "group-all": "The name of the user group that contains all users, including anonymous users\n\n{{Identical|All}}",
        "group-autoconfirmed-member": "{{doc-group|autoconfirmed|member}}",
        "group-bot-member": "{{doc-group|bot|member}}",
        "group-sysop-member": "{{doc-group|sysop|member}}\n{{Identical|Administrator}}",
+       "group-interface-admin-member": "{{doc-group|interface-admin|member}}",
        "group-bureaucrat-member": "{{doc-group|bureaucrat|member}}",
        "group-suppress-member": "{{doc-group|suppress|member}}\nThis is a member of the optional (disabled by default) user group, meant for the [[mw:RevisionDelete|RevisionDelete]] feature, to change the visibility of revisions through [[Special:RevisionDelete]].\n\n{{Identical|Suppress}}",
        "grouppage-user": "{{doc-group|user|page}}\n{{Identical|User}}",
        "grouppage-autoconfirmed": "{{doc-group|autoconfirmed|page}}",
        "grouppage-bot": "{{doc-group|bot|page}}\n{{Identical|Bot}}",
        "grouppage-sysop": "{{doc-group|sysop|page}}",
+       "grouppage-interface-admin": "{{doc-group|interface-admin|page}}",
        "grouppage-bureaucrat": "{{doc-group|bureaucrat|page}}",
        "grouppage-suppress": "{{doc-group|suppress|page}}\n{{Identical|Suppress}}",
        "right-read": "{{doc-right|read}}\nBasic right to read any page.",
        "right-editusercss": "{{doc-right|editusercss}}\nSee also:\n* {{msg-mw|Right-editmyusercss}}",
        "right-edituserjson": "{{doc-right|edituserjson}}\nSee also:\n* {{msg-mw|Right-editmyuserjson}}",
        "right-edituserjs": "{{doc-right|edituserjs}}\nSee also:\n* {{msg-mw|Right-editmyuserjs}}",
+       "right-editsitecss": "{{doc-right|editsitecss}}",
+       "right-editsitejson": "{{doc-right|editsitejson}}",
+       "right-editsitejs": "{{doc-right|editsitejs}}",
        "right-editmyusercss": "{{doc-right|editmyusercss}}\nSee also:\n* {{msg-mw|Right-editusercss}}",
        "right-editmyuserjson": "{{doc-right|editmyuserjson}}\nSee also:\n* {{msg-mw|Right-edituserjson}}",
        "right-editmyuserjs": "{{doc-right|editmyuserjs}}\nSee also:\n* {{msg-mw|Right-edituserjs}}",
        "right-applychangetags": "{{doc-right|applychangetags}}",
        "right-changetags": "{{doc-right|changetags}}",
        "right-deletechangetags": "{{doc-right|deletechangetags}}",
-       "grant-generic": "Used if the grant name is not defined. Parameters:\n* $1 - grant name\n\nDefined grants (grant name refers: blockusers, createeditmovepage, ...):\n* {{msg-mw|grant-checkuser}}\n* {{msg-mw|grant-blockusers}}\n* {{msg-mw|grant-createaccount}}\n* {{msg-mw|grant-createeditmovepage}}\n* {{msg-mw|grant-delete}}\n* {{msg-mw|grant-editinterface}}\n* {{msg-mw|grant-editmycssjs}}\n* {{msg-mw|grant-editmyoptions}}\n* {{msg-mw|grant-editmywatchlist}}\n* {{msg-mw|grant-editpage}}\n* {{msg-mw|grant-editprotected}}\n* {{msg-mw|grant-highvolume}}\n* {{msg-mw|grant-oversight}}\n* {{msg-mw|grant-patrol}}\n* {{msg-mw|grant-privateinfo}}\n* {{msg-mw|grant-protect}}\n* {{msg-mw|grant-rollback}}\n* {{msg-mw|grant-sendemail}}\n* {{msg-mw|grant-uploadeditmovefile}}\n* {{msg-mw|grant-uploadfile}}\n* {{msg-mw|grant-basic}}\n* {{msg-mw|grant-viewdeleted}}\n* {{msg-mw|grant-viewmywatchlist}}",
+       "grant-generic": "Used if the grant name is not defined. Parameters:\n* $1 - grant name\n\nDefined grants (grant name refers: blockusers, createeditmovepage, ...):\n* {{msg-mw|grant-checkuser}}\n* {{msg-mw|grant-blockusers}}\n* {{msg-mw|grant-createaccount}}\n* {{msg-mw|grant-createeditmovepage}}\n* {{msg-mw|grant-delete}}\n* {{msg-mw|grant-editinterface}}\n* {{msg-mw|grant-editmycssjs}}\n* {{msg-mw|grant-editmyoptions}}\n* {{msg-mw|grant-editmywatchlist}}\n* {{msg-mw|grant-editsiteconfig}}\n* {{msg-mw|grant-editpage}}\n* {{msg-mw|grant-editprotected}}\n* {{msg-mw|grant-highvolume}}\n* {{msg-mw|grant-oversight}}\n* {{msg-mw|grant-patrol}}\n* {{msg-mw|grant-privateinfo}}\n* {{msg-mw|grant-protect}}\n* {{msg-mw|grant-rollback}}\n* {{msg-mw|grant-sendemail}}\n* {{msg-mw|grant-uploadeditmovefile}}\n* {{msg-mw|grant-uploadfile}}\n* {{msg-mw|grant-basic}}\n* {{msg-mw|grant-viewdeleted}}\n* {{msg-mw|grant-viewmywatchlist}}",
        "grant-group-page-interaction": "{{Related|Grant-group}}",
        "grant-group-file-interaction": "{{Related|Grant-group}}",
        "grant-group-watchlist-interaction": "{{Related|Grant-group}}",
        "grant-createaccount": "Name for grant \"createaccount\".\n{{Related|Grant}}\n{{Identical|Create account}}",
        "grant-createeditmovepage": "Name for grant \"createeditmovepage\".\n{{Related|Grant}}",
        "grant-delete": "Name for grant \"delete\".\n{{Related|Grant}}",
-       "grant-editinterface": "Name for grant \"editinterface\".\n\n\"JS\" stands for \"JavaScript\".\n{{Related|Grant}}",
+       "grant-editinterface": "Name for grant \"editinterface\".\n{{Related|Grant}}",
        "grant-editmycssjs": "Name for grant \"editmycssjs\".\n\n\"JS\" stands for \"JavaScript\".\n{{Related|Grant}}",
        "grant-editmyoptions": "Name for grant \"editmyoptions\".\n{{Related|Grant}}",
        "grant-editmywatchlist": "Name for grant \"editmywatchlist\".\n{{Related|Grant}}\n{{Identical|Edit your watchlist}}",
+       "grant-editsiteconfig": "Name for grant \"editsiteconfig\".\n{{Related|Grant}}",
        "grant-editpage": "Name for grant \"editpage\".\n{{Related|Grant}}",
        "grant-editprotected": "Name for grant \"editprotected\".\n{{Related|Grant}}",
        "grant-highvolume": "Name for grant \"highvolume\".\n{{Related|Grant}}",
        "rcfilters-other-review-tools": "Used as a heading for the community collection of other links on [[Special:RecentChanges]] when RCFilters are enabled.",
        "rcfilters-group-results-by-page": "A label for the checkbox describing whether the results in [[Special:RecentChanges]] are grouped by page when RCFilters are enabled.",
        "rcfilters-activefilters": "{{doc-important|Translations of this message should not more than 3 cm long, otherwise it will make bad user experiences for potential mobile users.}}\nTitle for the filters selection showing the active filters.",
+       "rcfilters-activefilters-hide": "Label for the button that hides the active filters list and dropdown in [[Special:RecentChanges]].\n{{Identical|Hide}}",
+       "rcfilters-activefilters-show": "Label for the button that shows the active filters list and dropdown in [[Special:RecentChanges]].\n{{Identical|Show}}",
+       "rcfilters-activefilters-hide-tooltip": "Tooltip for the button that hides the active filters list and dropdown in [[Special:RecentChanges]].",
+       "rcfilters-activefilters-show-tooltip": "Tooltip for the button that shows the active filters list and dropdown in [[Special:RecentChanges]].",
        "rcfilters-advancedfilters": "Title for the buttons allowing the user to switch to the various advanced filters views.",
        "rcfilters-limit-title": "Title for the options to change the number of results shown.",
        "rcfilters-limit-and-date-label": "Title for the button that opens the operation to control how many results to show and in which time period to search. \n\nParameters: $1 - Number of results shown\n\n$2 - Time period to search. One of {{msg-mw|rcfilters-days-title}} or {{msg-mw|rcfilters-hours-title}} is used as $2\n{{Identical|Change}}",
        "rcfilters-savedqueries-rename": "Label for the menu option that edits a quick filter in [[Special:RecentChanges]]\n{{Identical|Rename}}",
        "rcfilters-savedqueries-setdefault": "Label for the menu option that sets a quick filter as default in [[Special:RecentChanges]]",
        "rcfilters-savedqueries-unsetdefault": "Label for the menu option that unsets a quick filter as default in [[Special:RecentChanges]]",
-       "rcfilters-savedqueries-remove": "Label for the menu option that removes a quick filter as default in [[Special:RecentChanges]]\n{{Identical|Remove}}",
+       "rcfilters-savedqueries-remove": "Label for the menu option that removes a quick filter as default in [[Special:RecentChanges]]\n{{Identical|Delete}}",
        "rcfilters-savedqueries-new-name-label": "Label for the input that holds the name of the new saved filters in [[Special:RecentChanges]]\n{{Identical|Name}}",
        "rcfilters-savedqueries-new-name-placeholder": "Placeholder for the input that holds the name of the new saved filters in [[Special:RecentChanges]]",
        "rcfilters-savedqueries-apply-label": "Label for the button to apply saving a new filter setting in [[Special:RecentChanges]]. This is for a small popup, please try to use a short string.",
        "rcfilters-watchlist-showupdated": "Message at the top of [[Special:Watchlist]] when the Structured filters are enabled that describes what unseen changes look like.\n\nCf. {{msg-mw|wlheader-showupdated}}",
        "rcfilters-preference-label": "Option in RecentChanges tab of [[Special:Preferences]].",
        "rcfilters-preference-help": "Explanation for the option in the RecentChanges tab of [[Special:Preferences]].",
+       "rcfilters-watchlist-preference-label": "Option in Watchlist tab of [[Special:Preferences]].",
+       "rcfilters-watchlist-preference-help": "Explanation for the option in the Watchlist tab of [[Special:Preferences]].",
        "rcfilters-filter-showlinkedfrom-label": "Label that indicates that the page is showing changes that link FROM the target page. Used on [[Special:Recentchangeslinked]] when structured filters are enabled.",
        "rcfilters-filter-showlinkedfrom-option-label": "Menu option to show changes FROM the target page. Used on [[Special:Recentchangeslinked]] when structured filters are enabled.",
        "rcfilters-filter-showlinkedto-label": "Label that indicates that the page is showing changes that link TO the target page. Used on [[Special:Recentchangeslinked]] when structured filters are enabled.",
        "http-timed-out": "Used as error message when executing HTTP request.\n\nSee also:\n* {{msg-mw|Http-request-error}}\n* {{msg-mw|Http-read-error}}\n* {{msg-mw|Http-host-unreachable|6}}",
        "http-curl-error": "Used as curl error message when the error is other than known messages.\n* $1 - error code; not URL\nKnown messages are:\n* {{msg-mw|http-host-unreachable}}\n* {{msg-mw|http-timed-out}}",
        "http-bad-status": "Parameters:\n* $1 - an HTTP error code (e.g. 404)\n* $2 - the HTTP error message (e.g. File Not Found)",
+       "http-internal-error": "Used as generic error message when executing HTTP request and no more specific message is available.",
        "upload-curl-error6": "See also:\n* {{msg-mw|Upload-curl-error6|title}}\n* {{msg-mw|Upload-curl-error6-text|body}}",
        "upload-curl-error6-text": "See also:\n* {{msg-mw|Upload-curl-error6|title}}\n* {{msg-mw|Upload-curl-error6-text|body}}",
        "upload-curl-error28": "See also:\n* {{msg-mw|Upload-curl-error28|title}}\n* {{msg-mw|Upload-curl-error28-text|body}}",
        "speciallogtitlelabel": "Used in [[Special:Log]] as a label for an input field with which the log can be filtered.  This filter selects for pages or users on which a log action was performed.",
        "log": "{{doc-special|Log}}\n{{Identical|Log}}",
        "logeventslist-submit": "Submit button on [[Special:Log]]\n{{Identical|Show}}",
+       "logeventslist-more-filters": "Label on [[Special:Log]]. Some log types are hidden by default when viewing \"all\" logs, because they might be very verbose, and these options show them.",
+       "logeventslist-patrol-log": "Patrol log option label on [[Special:Log]]",
+       "logeventslist-tag-log": "Tag log option label on [[Special:Log]]",
        "all-logs-page": "{{doc-logpage}}\nTitle of [[Special:Log]].",
        "alllogstext": "Header of [[Special:Log]]",
        "logempty": "Used as warning when there are no items to show.",
        "categories": "The page name of [[Special:Categories]].\n{{Identical|Category}}",
        "categories-summary": "{{doc-specialpagesummary|categories}}",
        "categories-submit": "Submit button on [[Special:Categories]]\n{{Identical|Show}}",
-       "categoriespagetext": "{{doc-important|Do not translate or change links.}}\nText displayed in [[Special:Categories]].\n\nIn order to translate \"Unused categories\" and \"wanted categories\" see {{msg-mw|Unusedcategories}} and {{msg-mw|Wantedcategories}}.\n\nParameters:\n* $1 - number of categories",
+       "categoriespagetext": "{{doc-important|Do not translate or change links.}}\nText displayed in [[Special:Categories]].\n\nIn order to translate \"wanted categories\" see {{msg-mw|Wantedcategories}}.\n\nParameters:\n* $1 - number of categories",
        "categoriesfrom": "Used as label for the input box in [[Special:Categories]].\n\nThis message follows the fieldset label {{msg-mw|categories}}, and is followed by the input box.",
        "deletedcontributions": "The message is shown as a link on [[Special:SpecialPages]] to [[Special:DeletedContributions]].\n\n{{Identical|Deleted user contributions}}",
        "deletedcontributions-summary": "{{doc-specialpagesummary|deletedcontributions}}",
        "dellogpage": "{{doc-logpage}}\n\nThe name of the deletion log. Used as heading on [[Special:Log/delete]] and in the drop down menu for selecting logs on [[Special:Log]].\n{{Identical|Deletion log}}",
        "dellogpagetext": "Text in [[Special:Log/delete]].",
        "deletionlog": "Used as text for the link which points to the deletion log:\n* Used as <code>$1</code> in {{msg-mw|Filewasdeleted}}\n* Used as <code>$2</code> in {{msg-mw|Deletedtext}}\n* Used in log lines on [[Special:DeletedContributions]]\n{{Identical|Deletion log}}",
+       "log-name-create": "{{doc-logpage}}\n\nThe name of the page creation log. Used as heading on [[Special:Log/create]] and in the drop down menu for selecting logs on [[Special:Log]].",
+       "log-description-create": "Text in [[Special:Log/create]].",
+       "logentry-create-create": "{{Logentry|[[Special:Log/create]]}}",
        "reverted": "{{Identical|Revert}}",
        "deletecomment": "{{Identical|Reason}}",
        "deleteotherreason": "{{Identical|Other/additional reason}}",
        "uctop": "This message is used in [[Special:Contributions]]. It is used to show that a particular edit was the last made to a page. Example: 09:57, 11 February 2008 (hist) (diff) Pagename‎ (edit summary) (current)\n{{Identical|Current}}",
        "month": "Used in [[Special:Contributions]] and history pages ([{{fullurl:Sandbox|action=history}} example]), as label for a dropdown box to select a specific month to view the edits made in that month, and the earlier months. See also {{msg-mw|year}}.",
        "year": "Used in [[Special:Contributions]] and history pages ([{{fullurl:Sandbox|action=history}} example]), as label for an input box to select a specific year to view the edits made in that year, and the earlier years.\n\nSee also:\n* {{msg-mw|month}}",
+       "date": "Used in [[Special:Contributions]] and history pages ([{{fullurl:Sandbox|action=history}} example]), as label for an input box to select a specific date to view the edits made on that date, and earlier.",
        "sp-contributions-newbies": "Text of radio button on special page [[Special:Contributions]].",
        "sp-contributions-newbies-sub": "Note at the top of the page of results for a search on [[Special:Contributions]] where 'Show contributions for new accounts only' has been selected.",
        "sp-contributions-newbies-title": "The page title in your browser bar, but not the page title.\n\nSee also:\n* {{msg-mw|Sp-contributions-newbies-sub}}",
        "whatlinkshere-title": "Title of the special page [[Special:WhatLinksHere]]. This page appears when you click on the 'What links here' button in the toolbox. $1 is the name of the page concerned.",
        "whatlinkshere-summary": "{{doc-specialpagesummary|whatlinkshere}}",
        "whatlinkshere-page": "{{Identical|Page}}",
-       "linkshere-2": "This message is the header line of the [[Special:WhatLinksHere/$1]] page generated by clicking \"What links here\" in the sidebar toolbox.\n\nIt is followed by a navigation bar built using {{msg-mw|Viewprevnext}}.\n\nParameters:\n* $1 - HTML link to the page.",
-       "nolinkshere-2": "Used in [[Special:WhatLinksHere]] if empty. Parameters:\n* $1 - HTML link to the page\nSee also:\n* {{msg-mw|Nolinkshere-ns-html}}",
-       "nolinkshere-ns-2": "Used in [[Special:WhatLinksHere]] if empty. Parameters:\n* $1 - HTML link to the page\nSee also:\n* {{msg-mw|Nolinkshere-html}}",
+       "linkshere": "This message is the header line of the [[Special:WhatLinksHere/$1]] page generated by clicking \"What links here\" in the sidebar toolbox.\n\nIt is followed by a navigation bar built using {{msg-mw|Viewprevnext}}.\n\nParameters:\n* $1 - Plain page title\n* $2 - HTML link to the page.",
+       "nolinkshere": "Used in [[Special:WhatLinksHere]] if empty. Parameters:\n* $1 - Plain page title\n* $2 - HTML link to the page.\nSee also:\n* {{msg-mw|Nolinkshere-ns}}",
+       "nolinkshere-ns": "Used in [[Special:WhatLinksHere]] if empty. Parameters:\n* $1 - Plain page title\n* $2 - HTML link to the page.\nSee also:\n* {{msg-mw|Nolinkshere}}",
        "isredirect": "Displayed in [[Special:WhatLinksHere]] (see [{{fullurl:Special:WhatLinksHere/Project:Translator|hidelinks=1}} Special:WhatLinksHere/Project:Translator] for example).\n\n{{Identical|Redirect page}}",
        "istemplate": "Means that a page (a template, specifically) is used as <code><nowiki>{{Page name}}</nowiki></code>.\nDisplayed in [[Special:WhatLinksHere]] (see [[Special:WhatLinksHere/Template:New portal]] for example).\nIf you are not sure how to translate this term, think of something like \"inclusion\", \"embedding\", or \"insertion\".\n{{Identical|Transclusion}}",
        "isimage": "This message is displayed on [[Special:WhatLinksHere]] for images. It means that the image is used on the page (as opposed to just being linked to like an non-image page).\n{{Identical|File link}}",
        "markedaspatrollederrornotify": "Notification shown after the user has failed to mark a change as patrolled.\n\nSee also:\n* {{msg-mw|Markedaspatrollednotify}} - notification on success",
        "patrol-log-page": "{{doc-logpage}}",
        "patrol-log-header": "Text that appears above the log entries on the [[Special:log|patrol log]].",
-       "log-show-hide-patrol": "Used in [[Special:Log]]. Parameters:\n* $1 - link text; one of {{msg-mw|Show}} or {{msg-mw|Hide}}\n{{Related|Log-show-hide}}",
-       "log-show-hide-tag": "Used in [[Special:Log]]. Parameters:\n* $1 - link text; one of {{msg-mw|Show}} or {{msg-mw|Hide}}\n{{Related|Log-show-hide}}",
        "confirm-markpatrolled-button": "Used as Submit button text.\n{{Identical|OK}}",
        "confirm-markpatrolled-top": "Confirmation message on interstitial form.\n\nParameters:\n* $1 - Target page title\n* $2 - Link to target page with page title as label\n* $3 - Link to recent change diff with revision ID as label",
        "deletedrevision": "Used as log comment. Parameters:\n* $1 - archive name of old image",
        "limitreport-expansiondepth-value": "{{optional}}\nFormat for the \"Highest expansion depth\" row in the limit report table.\n\nParameters:\n* $1 - the depth\n* $2 - the maximum",
        "limitreport-expensivefunctioncount": "Label for the \"Expensive parser function count\" row in the limit report table",
        "limitreport-expensivefunctioncount-value": "{{optional}}\nFormat for the \"Expensive parser function count\" row in the limit report table.\n\nParameters:\n* $1 - the usage\n* $2 - the maximum",
-       "limitreport-unstrip-depth": "Label for the \"unstrip depth\" row in the limit report table. \"Unstrip\" is a MediaWiki function name and as such does not need to be translated.",
+       "limitreport-unstrip-depth": "{{Doc-important|Do not translate function name <code>unstrip</code>.}}\nLabel for the \"unstrip depth\" row in the limit report table.\n\n\"Unstrip\" refers to the internal function of the parser, called \"unstrip\", which recursively puts the output of parser functions in the place of the parser function call.\n\nSee also:\n*{{msg-mw|Limitreport-unstrip-size}}\n*{{msg-mw|Parser-unstrip-loop-warning}}\n*{{msg-mw|Unstrip-depth-category}}\n*{{msg-mw|Unstrip-depth-warning}}\n*{{msg-mw|Unstrip-size-category}}\n*{{msg-mw|Unstrip-size-warning}}",
        "limitreport-unstrip-depth-value": "{{optional}}\nFormat for the \"unstrip depth\" row in the limit report table.\n\nParameters:\n* $1 - the usage\n* $2 - the maximum",
-       "limitreport-unstrip-size": "Label for the \"unstrip size\" row in the limit report table. \"Unstrip\" is a MediaWiki function name and as such does not need to be translated.",
+       "limitreport-unstrip-size": "{{Doc-important|Do not translate function name <code>unstrip</code>.}}\nLabel for the \"unstrip size\" row in the limit report table.\n\n\"Unstrip\" refers to the internal function of the parser, called \"unstrip\", which recursively puts the output of parser functions in the place of the parser function call.\n\nSee also:\n*{{msg-mw|Limitreport-unstrip-depth}}\n*{{msg-mw|Parser-unstrip-loop-warning}}\n*{{msg-mw|Unstrip-depth-category}}\n*{{msg-mw|Unstrip-depth-warning}}\n*{{msg-mw|Unstrip-size-category}}\n*{{msg-mw|Unstrip-size-warning}}",
        "limitreport-unstrip-size-value": "Format for the \"unstrip size\" row in the limit report table.\n\nParameters:\n* $1 - the usage\n* $2 - the maximum\n{{Identical|Byte}}",
        "expandtemplates": "{{doc-special|ExpandTemplates}}\nThe name of the [[mw:Extension:ExpandTemplates|Expand Templates extension]].",
        "expand_templates_intro": "This is the explanation given in the heading of the [[Special:ExpandTemplates]] page; it describes its functionality to the users.\nFor more information, see [[mw:Extension:ExpandTemplates]]",
        "edit-error-long": "Error message. Parameters:\n* $1 - the error details\nSee also:\n* {{msg-mw|edit-error-short}}\n{{Identical|Error}}",
        "revid": "Used to format a revision ID number in text. Parameters:\n* $1 - Revision ID number.\n{{Identical|Revision}}",
        "pageid": "Used to format a page ID number in text. Parameters:\n* $1 - Page ID number.",
+       "interfaceadmin-info": "Used to wrap the normal permission error for actions which used to only require editinterface but now require more permissions. Parameters:\n* $1 - The normal permission error.",
        "rawhtml-notallowed": "Error message given when $wgRawHtml = true; is set and a user uses an &lt;html&gt; tag in a system message or somewhere other than a normal page.",
        "gotointerwiki": "{{doc-special|GoToInterwiki}}\n\nSpecial:GoToInterwiki is a warning page displayed before redirecting users to external interwiki links. Its triggered by people going to something like [[Special:Search/google:foo]].\n{{Identical|Leaving}}",
        "gotointerwiki-invalid": "Message shown on Special:GoToInterwiki if given an invalid title.",
        "unregistered-user-config": "Shown when viewing a user JS, CSS or JSON subpage with ?action=raw&ctype=<mime type> where there is no such user. It is shown as a paragraph after a header saying 'Forbidden'.",
        "passwordpolicies": "The name of the special page [[Special:PasswordPolicies]].",
        "passwordpolicies-summary": "The description used on [[Special:PasswordPolicies]].\n\nRefers to {{msg-mw|Passwordpolicies-helppage}}.",
-       "passwordpolicies-helppage": "The link used on [[Special:PasswordPolicies]].",
        "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-passwordcannotmatchusername": "Password policy that enforces that the password of the account cannot be the same as the username",
        "passwordpolicies-policy-passwordcannotmatchblacklist": "Password policy that enforces that passwords are not on a list of blacklisted passwords (often previously used during MediaWiki automated testing)",
        "passwordpolicies-policy-maximalpasswordlength": "Password policy that enforces a maximum number of characters a password must be. $1 - maximum number of characters that a password can be",
-       "passwordpolicies-policy-passwordcannotbepopular": "Password policy that enforces that a password is not in a list of $1 number of \"popular\" passwords. $1 - number of popular passwords the password will be checked against"
+       "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",
+       "easydeflate-invaliddeflate": "Error message if the content passed to easydeflate was not deflated (compressed) properly"
 }
index 9d090ba..9bc8be5 100644 (file)
        "talk": "Rimachina",
        "views": "Rikunakuna",
        "toolbox": "Llamk'anakuna",
+       "tool-link-userrights": "{{GENDER:$1|Ruraqpa}} huñunkunata llamk'apuy",
+       "tool-link-emailuser": "Kay {{GENDER:$1|ruraqman}} e-chaskita kachay",
        "imagepage": "Willañiqimanta p'anqata qhaway",
        "mediawikipage": "Willay p'anqata qhaway",
        "templatepage": "Plantilla p'anqata qhaway",
        "yourtext": "Qillqasqayki",
        "storedversion": "Hallch'asqa musuqchasqa",
        "editingold": "'''Paqtataq: Kay p'anqap mawk'a hukchasqantam llamk'apuchkanki. Waqaychaptiykiqa, chaymanta aswan musuq hukchasqankuna chinkanqam.'''",
+       "unicode-support-fail": "Wamp'unaykiqa manayá llamk'achinchu sapatuyru (Unicode) nisqata. P'anqakunata llamk'apunapaqqa muchusqa kaptinmi, llamk'apusqaykiqa manam waqaychasqachu.",
        "yourdiff": "Hukchasqaykikuna",
        "copyrightwarning": "Lliw {{SITENAME}}paq llamk'apuykunaqa $2 nisqawanmi uyaychasqa kanqa ($1 p'anqata qhaway). Llamk'asqaykikunata huk runakunap allinchayninta qispilla mast'ariyninta mana munaspaykiqa, ama kayman qillqamuychu.<br />\nTakyachichkankim: Kayqa ñuqap qillqasqaymi icha qispi pukyumanta iskaychamusqaymi, nispa.\n<br />'''Mana saqillasqa kaspaykiqa, ama qillqarimuychu iskaychay hayñi ''(copyright)'' nisqayuq qillqakunata iskaychamuspa!'''",
        "copyrightwarning2": "Lliw {{SITENAME}}paq llamk'apuykunaqa huk ruraqkunap llamk'apunallanmi, hukchanallanmi icha qullunallanmi. Llamk'asqaykikunata huk runakunap allinchayninta qispilla mast'ariyninta mana munaspaykiqa, ama kayman qillqamuychu.<br />\nTakyachichkankim: Kayqa ñuqap qillqasqaymi, ñuqamanmi kapuwan icha qispi pukyumanta iskaychamusqaymi, nispa ($1 p'anqata qhaway).\n<br />'''Mana saqillasqa kaspaykiqa, ama qillqarimuychu iskaychay hayñi ''(copyright)'' nisqayuq qillqakunata iskaychamuspa!'''",
        "prefs-rc": "Ñaqha hukchasqakuna",
        "prefs-watchlist": "Watiqasqa p'anqakuna",
        "prefs-watchlist-days": "Hayk'a p'unchawkunata watiqana sutisuyupi rikuchiy:",
-       "prefs-watchlist-days-max": "Ama {{PLURAL:$1|huk p'unchawmanta|$1 p'unchawmanta}} aswan p'unchaw kachunchu",
+       "prefs-watchlist-days-max": "Ama $1-manta aswan {{PLURAL:$1|p'unchawkuna}} kachunchu",
        "prefs-watchlist-edits": "Hayk'a hukchasqakunata hatunchasqa watiqana sutisuyupi rikuchiy:",
        "prefs-watchlist-edits-max": "Ama waranqamanta aswan kachunchu",
        "prefs-watchlist-token": "Watiqay sutisuyu sanancha:",
        "stub-threshold": "Kay hatun kaykamam <a href=\"#\" class=\"stub\">t'una qillqasqa t'inki</a> nisqa kachun (byte):",
        "stub-threshold-disabled": "Ama nisqa",
        "recentchangesdays": "Ñaqha hukchasqakunapi rikuchina p'unchawkuna:",
-       "recentchangesdays-max": "(ama $1-manta aswan {{PLURAL:$1|p'unchaw|p'unchaw}} kachunchu)",
+       "recentchangesdays-max": "Ama $1-manta aswan {{PLURAL:$1|p'unchawkuna}} kachunchu",
        "recentchangescount": "Rikuchina hukchasqakunap yupaynin, kikinmanta:",
        "prefs-help-recentchangescount": "Kaypiqa ñaqha hukchasqakunam, p'anqap wiñay kawsayninkunam, hallch'akunapas.",
        "savedprefs": "Allinkachinaykikunaqa hallch'asqañam.",
        "userrights-user-editname": "Ruraqpa sutinta qillqamuy:",
        "editusergroup": "Ruraqkunap huñunkunata hukchay",
        "editinguser": "Kay ruraqpa hayñinkunata hukchaspa: '''[[User:$1|$1]]''' $2",
-       "userrights-editusergroup": "Ruraqkunap huñunkunata hukchay",
+       "userrights-editusergroup": "{{GENDER:$1|Ruraqpa}} huñunkunata llamk'apuy",
        "saveusergroups": "Ruraq huñukunata waqaychay",
        "userrights-groupsmember": "Kayman kapuq:",
        "userrights-groupsmember-auto": "Ch'aqtasqalla wankurisqa kaypi:",
        "right-siteadmin": "Willañiqintinta hark'ay, paskaypas",
        "right-override-export-depth": "P'anqakunata hawaman quy, t'inkisqa p'anqakunatapas pichqa ñiqin t'inkipayasqakama",
        "right-sendemail": "Huk ruraqkunaman e-chaskita kachay",
+       "grant-group-administration": "Kamachiqpa llamk'ayninkuna ruray",
        "newuserlogpage": "Rakiquna kamariy hallch'a",
        "newuserlogpagetext": "Kayqa ruraqkunap rakiqunankunata kamariymanta hallch'am.",
        "rightslog": "Ruraqpa hayñinkunap hukyasqankuna",
        "recentchanges-label-plusminus": "P'anqap chhikan, kay byte yupaywan wakinchasqa",
        "recentchanges-legend-heading": "<strong>Sut'ichana:</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} ([[Special:NewPages|musuq p'anqakunatapas]] qhaway)",
+       "rcfilters-legend-heading": "<strong>Pisichaykuna:</strong>",
+       "rcfilters-other-review-tools": "Huk qhawakipana llamk'anakuna",
+       "rcfilters-activefilters": "Llamk'achkaq ch'illchinakuna",
+       "rcfilters-activefilters-hide": "Pakay",
+       "rcfilters-activefilters-show": "Rikuchiy",
+       "rcfilters-activefilters-hide-tooltip": "Llamk'achkaq ch'illchinakuna nisqa k'itita pakay",
+       "rcfilters-activefilters-show-tooltip": "Llamk'achkaq ch'illchinakuna nisqa k'itita rikuchiy",
+       "rcfilters-limit-and-date-label": "$1 {{PLURAL:$1|hukchasqa|hukchasqakuna}}, $2",
+       "rcfilters-days-show-days": "$1 {{PLURAL:$1|p'unchaw|p'unchawkuna}}",
+       "rcfilters-quickfilters": "Waqaychasqa ch'illchinakuna",
+       "rcfilters-quickfilters-placeholder-title": "Manaraqmi ima ch'illchina waqaychasqachu",
+       "rcfilters-quickfilters-placeholder-description": "Chillch'ina churasqakunata qhipaqta llamk'achinaypaq waqaychanaykipaqqa, urapi kaq Llamk'achkaq Ch'illchina suyuchapi sananchana rikch'achata ñit'iy.",
+       "rcfilters-savedqueries-defaultlabel": "Waqaychasqa ch'illchinakuna",
+       "rcfilters-search-placeholder": "Hukchasqakunata ch'illchiy (sutisuyuta llamk'achiy icha ch'illchinap sutinta maskay)",
+       "rcfilters-filter-editsbyself-description": "Kikiykip llamk'apusqaykikuna.",
+       "rcfilters-filter-bots-label": "Rurana antacha",
+       "rcfilters-filter-bots-description": "Rurana antachakunap llamk'apusqankuna.",
+       "rcfilters-filter-humans-label": "Chiqap runa",
+       "rcfilters-filter-humans-description": "Chiqap runakunap llamk'apusqankuna.",
+       "rcfilters-filter-pageedits-label": "P'anqakunapi hukchasqakuna",
+       "rcfilters-filter-pageedits-description": "Wiki samiqpi, rimanakuykunapi, katiguriya t'iktuykunapi hukkunapipas hukchasqakuna",
+       "rcfilters-filter-newpages-label": "Kamarisqa p'anqakuna",
+       "rcfilters-filter-newpages-description": "P'anqa kamariq llamk'apusqakuna.",
+       "rcfilters-filter-logactions-label": "Hallch'asqa rurasqakuna",
+       "rcfilters-filter-logactions-description": "Kamachiqpa rurasqankuna, rakiquna kamarisqakuna, p'anqa qullasqakuna, churkusqakuna, hukkunapas",
+       "rcfilters-view-namespaces-tooltip": "Taripasqakunata suti k'itikama ch'illchiy",
+       "rcfilters-view-tags-tooltip": "Taripasqakunata llamk'apuna sananchakunawan ch'illchiy",
+       "rcfilters-liveupdates-button": "Tuylla musuqchasqakuna",
+       "rcfilters-liveupdates-button-title-on": "Tuylla musuqchasqakunata thasnuy",
+       "rcfilters-liveupdates-button-title-off": "Tuylla wakinchasqakunata kay hinallata rikuchiy",
        "rcnotefrom": "Kay qatiqpiqa <strong>$2</strong>-mantapacha (<strong>$1</strong>-kama) hukchasqakunatam rikunki.",
        "rclistfrom": "$3 $2-manta musuq hukchasqakunata rikuchiy",
        "rcshowhideminor": "$1 uchuylla llamk'apusqakunata",
        "wlheader-showupdated": "Qayna watukamusqaykimantapacha hukchasqa p'anqakunataqa '''yanasapa''' nisqapim rikunki.",
        "wlnote": "Kay qatiqpiqa {{PLURAL:$1|qhipaq hukchasqam|'''$1''' qhipaq hukchasqakunam}} qhipaq {{PLURAL:$2|urapim|'''$2''' urakunapim}}, musuqchasqa $3, $4.",
        "wlshowlast": "$1 ura, $2 p'unchaw -mantapacha hukchasqakunata rikuchiy",
+       "watchlist-hide": "Pakay",
        "watchlist-options": "Watiqana sutisuyupaq allinkachinakuna",
        "watching": "Watiqasqakunaman yapaspa...",
        "unwatching": "Watiqasqakunamanta qulluspa...",
        "sp-contributions-username": "IP huchha icha ruraqpa sutin:",
        "sp-contributions-toponly": "Pata musuqchasqakunallata rikuchiy",
        "sp-contributions-newonly": "P'anqa kamarisqakunallata rikuchiy",
+       "sp-contributions-hideminor": "Aslla llamk'apusqakunata pakay",
        "sp-contributions-submit": "Maskay",
        "whatlinkshere": "Kayman t'inkimuq",
        "whatlinkshere-title": "$1 sutiyuq p'anqaman t'inkimuqkuna",
        "whatlinkshere-page": "P'anqa:",
-       "linkshere-2": "'''$1''' sutiyuq p'anqamanqa kay qatiq p'anqakunam t'inkimun:",
-       "nolinkshere-2": "Manam kachkanchu '''$1'''-man t'inkiq p'anqa.",
-       "nolinkshere-ns-2": "Manam kachkanchu '''$1'''-man t'inkiq p'anqa akllasqa suti k'itipi.",
+       "linkshere": "'''$2''' sutiyuq p'anqamanqa kay qatiq p'anqakunam t'inkimun:",
+       "nolinkshere": "Manam kachkanchu '''$2'''-man t'inkiq p'anqa.",
+       "nolinkshere-ns": "Manam kachkanchu '''$2'''-man t'inkiq p'anqa akllasqa suti k'itipi.",
        "isredirect": "pusapusqa p'anqa",
        "istemplate": "ch'aqtasqa",
        "isimage": "willañiqi t'inki",
        "markedaspatrollederrornotify": "Qhawakipasqa niyqa manam aypanchu.",
        "patrol-log-page": "Qhawakipay hallch'a",
        "patrol-log-header": "Kayqa patrullasqa musuqchasqakunamanta hallch'asqam.",
-       "log-show-hide-patrol": "$1 patrullay hallch'a",
        "deletedrevision": "Qullusqam mawk'a qhawakipasqa $1",
        "filedeleteerror-short": "Manam atinichu kay willañiqita qulluyta: $1",
        "filedeleteerror-long": "Pantasqakunam rikch'akurqan kay willañiqita qulluypi:\n\n$1",
        "duration-seconds": "$1 {{PLURAL:$1|sikundu|sikundukuna}}",
        "duration-minutes": "$1 {{PLURAL:$1|minutu|minutukuna}}",
        "duration-hours": "$1 {{PLURAL:$1|ura|urakuna}}",
-       "duration-days": "{{PLURAL:$1|p'unchaw|p'unchawkuna}}",
+       "duration-days": "$1 {{PLURAL:$1|p'unchaw|p'unchawkuna}}",
        "duration-weeks": "{{PLURAL:$1|simana|simanakuna}}",
        "duration-years": "{{PLURAL:$1|wata|watakuna}}",
        "duration-decades": "{{PLURAL:$1|chunkawata|chunkawatakuna}}",
        "special-characters-group-khmer": "Khmer",
        "special-characters-title-endash": "kuru aspi",
        "special-characters-title-emdash": "suni aspi",
-       "special-characters-title-minus": "qichuy sanancha"
+       "special-characters-title-minus": "qichuy sanancha",
+       "mw-widgets-dateinput-no-date": "Manam akllasqa p'unchaw kanchu",
+       "date-range-from": "Kay p'unchawmanta:",
+       "date-range-to": "Kay p'unchawkama:"
 }
index 0f24732..fbfc9e5 100644 (file)
        "whatlinkshere": "Kayman tinkikuna",
        "whatlinkshere-title": "$1-man tinkiyuk pankakuna",
        "whatlinkshere-page": "Panka:",
-       "linkshere-2": "Chay pankakunaka '''$1'''-man tinkiyukmi kan:",
-       "nolinkshere-2": "Mana pankaka '''$1'''-man tinkikunchu.",
+       "linkshere": "Chay pankakunaka '''$2'''-man tinkiyukmi kan:",
+       "nolinkshere": "Mana pankaka '''$2'''-man tinkikunchu.",
        "isredirect": "pushashka panka",
        "istemplate": "Ukupi tiyak panka (''inclusión'')",
        "isimage": "rikcha tinki",
index a9adaa9..85e0cb0 100644 (file)
        "whatlinkshere": "ⵎⵉⵏ ⵉⵇⵇⵏⴻⵏ ⵖⵔ ⴷⴰ",
        "whatlinkshere-title": "Tasniwin id-izedyen ɣar \"$1\"",
        "whatlinkshere-page": "ⵜⴰⵙⵏⴰ:",
-       "linkshere-2": "Tasna ya tzedi ɣa '''$1''':",
-       "nolinkshere-2": "war tlli ca n Tasna tqqen-d da '''$1'''.",
+       "linkshere": "Tasna ya tzedi ɣa '''$2''':",
+       "nolinkshere": "war tlli ca n Tasna tqqen-d da '''$2'''.",
        "isredirect": "Tasna n (redirect)",
        "istemplate": "Asidef",
        "isimage": "amaqqan usatul",
index 0a894b1..c673979 100644 (file)
        "whatlinkshere": "Colliaziuns sin questa pagina",
        "whatlinkshere-title": "Paginas ch'èn colliadas cun \"$1\"",
        "whatlinkshere-page": "Pagina:",
-       "linkshere-2": "Suandantas paginas èn colliadas cun '''$1''':",
-       "nolinkshere-2": "Naginas paginas èn colliadas cun '''$1'''.",
-       "nolinkshere-ns-2": "Naginas paginas èn colliadas cun '''$1''' en il tip da pagina tschernì.",
+       "linkshere": "Suandantas paginas èn colliadas cun '''$2''':",
+       "nolinkshere": "Naginas paginas èn colliadas cun '''$2'''.",
+       "nolinkshere-ns": "Naginas paginas èn colliadas cun '''$2''' en il tip da pagina tschernì.",
        "isredirect": "Pagina che renviescha",
        "istemplate": "Integraziun da models",
        "isimage": "colliaziun da datoteca",
        "markedaspatrollederrornotify": "Sbagl durant marcar sco controllà.",
        "patrol-log-page": "Protocol da controllas",
        "patrol-log-header": "Quai è il protocol da las versiuns controlladas.",
-       "log-show-hide-patrol": "$1 il protocol da controllas",
        "deletedrevision": "Stizzà la versiun veglia $1.",
        "filedeleteerror-short": "Errur cun stizzar la datoteca: $1",
        "filedeleteerror-long": "Cun stizzar la datoteca èn errurs vegnidas constatadas:\n\n$1",
index 939d795..e0c49ab 100644 (file)
@@ -72,7 +72,7 @@
        "tog-watchlisthideminor": "Ascunde modificările minore din lista de pagini urmărite",
        "tog-watchlisthideliu": "Ascunde modificările efectuate de utilizatori autentificați din lista de pagini urmărite",
        "tog-watchlistreloadautomatically": "Reîncarcă automat lista paginilor urmărite de fiecare dată când un filtru este modificat (necesită JavaScript)",
-       "tog-watchlistunwatchlinks": "Adaugă legături directe pentru urmărire/neurmărire inrărilor din lista de pagini urmărite (este nevoie de JavaScript pentru a activa funcționalitatea)",
+       "tog-watchlistunwatchlinks": "Adaugă legături directe pentru urmărirea/neurmărirea ({{int:Watchlist-unwatch}}/{{int:Watchlist-unwatch-undo}}) intrărilor din lista de pagini urmărite (este nevoie de JavaScript pentru a activa funcționalitatea)",
        "tog-watchlisthideanons": "Ascunde modificările făcute de utilizatori anonimi din lista de pagini urmărite",
        "tog-watchlisthidepatrolled": "Ascunde paginile patrulate din lista de pagini urmărite",
        "tog-watchlisthidecategorization": "Ascunde categorisirea paginilor",
        "cascadeprotected": "Această pagină a fost protejată la modificare, deoarece este inclusă în {{PLURAL:$1|următoarea pagină|următoarele pagini}} {{PLURAL:$1|protejată|protejate}} cu opțiunea „în cascadă”:\n$2",
        "namespaceprotected": "Nu aveți permisiunea de a modifica pagini din spațiul de nume '''$1'''.",
        "customcssprotected": "Nu aveți permisiunea de a modifica această pagină CSS, deoarece conține setările personale ale altui utilizator.",
+       "customjsonprotected": "Nu aveți permisiunea de a modifica această pagină JSON, deoarece conține setările personale ale altui utilizator.",
        "customjsprotected": "Nu aveți permisiunea de a modifica această pagină JavaScript, deoarece conține setările personale ale altui utilizator.",
        "mycustomcssprotected": "Nu aveți permisiunea să modificați această pagină CSS.",
+       "mycustomjsonprotected": "Nu aveți permisiunea să modificați această pagină JSON.",
        "mycustomjsprotected": "Nu aveți permisiunea să modificați această pagină JavaScript.",
        "myprivateinfoprotected": "Nu aveți permisiunea să vă modificați informațiile personale.",
        "mypreferencesprotected": "Nu aveți permisiunea să vă modificați preferințele.",
        "wrongpasswordempty": "Spațiul pentru introducerea parolei nu a fost completat. Vă rugăm să încercați din nou.",
        "passwordtooshort": "Parola trebuie să aibă cel puțin {{PLURAL:$1|1 caracter|$1 caractere|$1 de caractere}}.",
        "passwordtoolong": "Parolele nu pot fi mai lungi de {{PLURAL:$1|un caracter|$1 caractere|$1 de caractere}}.",
-       "passwordtoopopular": "Parolele comune nu pot fi utilizate. Alegeți o parolă mai puțin obișnuită.",
+       "passwordtoopopular": "Parolele comune nu pot fi utilizate. Alegeți o parolă mai greu de ghicit.",
        "password-name-match": "Parola dumneavoastră trebuie să fie diferită de numele de utilizator.",
        "password-login-forbidden": "Utilizarea acestui nume de utilizator și a acestei parole este interzisă.",
        "mailmypassword": "Resetează parola",
        "passwordremindertitle": "Noua parolă temporară la {{SITENAME}}",
-       "passwordremindertext": "Cineva (probabil dumneavoastră, de la adresa $1)\na cerut să vi se trimită o nouă parolă pentru {{SITENAME}} ($4).\nO parolă temporară pentru utilizatorul „$2” a fost generată și este acum „$3”.\nParola temporară va expira {{PLURAL:$5|într-o zi|în $5 zile|în $5 de zile}}.\n\nDacă această cerere a fost efectuată de altcineva sau dacă v-ați amintit\nparola și nu doriți să o schimbați, ignorați acest mesaj și continuați\nsă folosiți vechea parolă.",
+       "passwordremindertext": "Cineva (de la adresa IP $1)\na cerut să vi se trimită o nouă parolă pentru {{SITENAME}} ($4).\nO parolă temporară pentru utilizatorul „$2” a fost generată și este acum „$3”.\nParola temporară va expira {{PLURAL:$5|într-o zi|în $5 zile|în $5 de zile}}.\n\nDacă această cerere a fost efectuată de altcineva sau dacă v-ați amintit\nparola și nu doriți să o schimbați, ignorați acest mesaj și continuați\nsă folosiți vechea parolă.",
        "noemail": "Nu este nici o adresă de e-mail înregistrată pentru utilizatorul „$1”.",
        "noemailcreate": "Trebuie oferită o adresă e e-mail validă.",
        "passwordsent": "O nouă parolă a fost trimisă la adresa de e-mail a utilizatorului \"$1\". Te rugăm să te autentifici pe {{SITENAME}} după ce o primești.",
        "botpasswords-existing": "Parole de robot existente",
        "botpasswords-createnew": "Creați o nouă parolă de bot",
        "botpasswords-editexisting": "Editați o parolă de bot",
+       "botpasswords-label-needsreset": "(parola trebuie resetată)",
        "botpasswords-label-appid": "Numele robotului:",
        "botpasswords-label-create": "Creare",
        "botpasswords-label-update": "Actualizează",
        "botpasswords-restriction-failed": "Restricțiile privind parola botului împiedică această conectare.",
        "botpasswords-invalid-name": "Numele de utilizator specificat nu conține separatorul de parole pentru bot (\"$1\").",
        "botpasswords-not-exist": "Utilizatorul \"$1\" nu are un bot de parole numit \"$2\".",
+       "botpasswords-needs-reset": "Parola de robot pentru robotul \"$1\" al {{GENDER:$2|utilizatorului|utilizatoarei}} \"$2\" trebuie resetată.",
        "resetpass_forbidden": "Parolele nu pot fi schimbate.",
        "resetpass_forbidden-reason": "Parolele nu pot fi schimbate: $1",
        "resetpass-no-info": "Trebuie să fiți autentificat pentru a accesa această pagină direct.",
        "resetpass-abort-generic": "Schimbarea parolei a fost anulată de către o extensie.",
        "resetpass-expired": "Parola dumneavoastră a expirat. Alegeți o parolă nouă pentru a vă autentifica.",
        "resetpass-expired-soft": "Parola dumneavoastră a expirat și trebuie schimbată. Alegeți o parolă nouă acum sau apăsați „{{int:authprovider-resetpass-skip-label}}” pentru a o reseta mai târziu.",
-       "resetpass-validity-soft": "Parola dumneavoastră nu este validă: $1 \n\nAlegeți o parolă nouă acum sau apăsați „{{int:authprovider-resetpass-skip-label}}” pentru a o reseta mai târziu.",
+       "resetpass-validity-soft": "Parola dumneavoastră nu este validă: $1 \n\nAlegeți o parolă nouă acum sau apăsați „{{int:authprovider-resetpass-skip-label}}” pentru a o schimba mai târziu.",
        "passwordreset": "Resetare parolă",
        "passwordreset-text-one": "Completați acest formular pentru a vă reseta parola.",
        "passwordreset-text-many": "{{PLURAL:$1|Completați unul din câmpuri pentru a primi o parolă temporară prin e-mail.}}",
        "savechanges": "Salvează modificările",
        "publishpage": "Publică pagina",
        "publishchanges": "Publică modificările",
+       "savearticle-start": "Salvare pagină...",
+       "savechanges-start": "Salvează modificările...",
+       "publishpage-start": "Publică pagina...",
+       "publishchanges-start": "Publică modificările...",
        "preview": "Previzualizare",
        "showpreview": "Previzualizare",
        "showdiff": "Afișare diferențe",
        "subject-preview": "Previzualizare subiect/titlu:",
        "previewerrortext": "A survenit o eroare ca urmare a tentativei de previzualizare a modificărilor dumneavoastră.",
        "blockedtitle": "Utilizatorul este blocat",
-       "blockedtext": "'''Adresa IP sau contul dumneavoastră de utilizator a fost blocat.'''\n\nBlocarea a fost făcută de $1.\nMotivul blocării este ''$2''.\n\n* Începutul blocării: $8\n* Sfârșitul blocării: $6\n* Utilizatorul vizat: $7\n\nÎl puteți contacta pe $1 sau pe alt [[{{MediaWiki:Grouppage-sysop}}|administrator]] pentru a discuta blocarea.\nNu puteți folosi opțiunea 'trimite un e-mai utilizatorului' decât dacă o adresă de e-mail validă este specificată în [[Special:Preferences|preferințele contului]] și nu sunteți blocat la folosirea ei.\nAdresa dumneavoastră IP curentă este $3, iar ID-ul blocării este $5. Vă rugăm să includeți oricare sau ambele informații în orice interogări.",
-       "autoblockedtext": "Această adresă IP a fost blocată automat deoarece a fost folosită de către un alt utilizator, care a fost blocat de $1.\nMotivul blocării este:\n\n:''$2''\n\n* Începutul blocării: $8\n* Sfârșitul blocării: $6\n* Intervalul blocării: $7\n\nPuteți contacta pe $1 sau pe unul dintre ceilalți [[{{MediaWiki:Grouppage-sysop}}|administratori]] pentru a discuta blocarea.\n\nNu veți putea folosi opțiunea de \"trimite e-mail\" decât dacă aveți înregistrată o adresă de e-mail validă la [[Special:Preferences|preferințe]] și nu sunteți blocat la folosirea ei.\n\nAveți adresa IP $3, iar identificatorul dumneavoastră de blocare este $5.\nVă rugăm să includeți detaliile de mai sus în orice interogări pe care le faceți.",
+       "blockedtext": "* Începutul blocării: $8\n* Sfârșitul blocării: $6\n* Utilizatorul vizat: $7\n\nÎl puteți contacta pe $1 sau pe alt [[{{MediaWiki:Grouppage-sysop}}|administrator]] pentru a discuta blocarea.\nNu puteți folosi opțiunea 'trimite un e-mai utilizatorului' decât dacă o adresă de e-mail validă este specificată în [[Special:Preferences|preferințele contului]] și nu sunteți blocat la folosirea ei.\nAdresa dumneavoastră IP curentă este $3, iar ID-ul blocării este #$5. Vă rugăm să includeți toate detaliile de mai sus în orice mesaj.",
+       "autoblockedtext": "Această adresă IP a fost blocată automat deoarece a fost folosită de către un alt utilizator, care a fost blocat de $1.\nMotivul blocării este:\n\n:<em>$2</em>\n\n* Începutul blocării: $8\n* Sfârșitul blocării: $6\n* Intervalul blocării: $7\n\nPuteți contacta pe $1 sau pe unul dintre ceilalți [[{{MediaWiki:Grouppage-sysop}}|administratori]] pentru a discuta blocarea.\n\nNu veți putea folosi opțiunea de \"{{int:emailuser}}\" decât dacă aveți înregistrată o adresă de e-mail validă la [[Special:Preferences|preferințe]] și nu sunteți blocat la folosirea ei.\n\nAveți adresa IP $3, iar identificatorul dumneavoastră de blocare este #$5.\nVă rugăm să includeți detaliile de mai sus în orice mesaje pe care le trimiteți.",
        "systemblockedtext": "Numele de utilizator sau adresa IP a fost blocat automat de MediaWiki.\nMotivul indicat este:\n\n:<em>$2</em>\n\n\n* Începutul blocării: $8\n* Expirarea blocării: $6\n* Utilizatorul vizat: $7\n\nAdresa IP curentă a dumneavoastră este $3.\nVă rugăm să includeți toate detaliile de mai sus în orice interogare pe care o veți faceți.",
        "blockednoreason": "nici un motiv oferit",
        "whitelistedittext": "Trebuie să vă $1 pentru a putea modifica pagini.",
        "blocked-notice-logextract": "Acest utilizator este momentan blocat.\nUltima intrare în jurnalul blocărilor este afișată mai jos pentru referință:",
        "clearyourcache": "<strong>Notă:</strong> După salvare, trebuie să treceți peste memoria cache a navigatorului pentru a putea vedea modificările:\n* <strong>Firefox / Safari:</strong> țineți apăsat pe <em>Shift</em> în timp ce faceți clic pe <em>Reîncărcare</em> ori apăsați <em>Ctrl-F5</em> sau <em>Ctrl-R</em> (<em>⌘-R</em> pe un sistem Mac);\n* <strong>Google Chrome:</strong> apăsați <em>Ctrl-Shift-R</em> (<em>⌘-Shift-R</em> pe un sistem Mac);\n* <strong>Internet Explorer:</strong> țineți apăsat pe <em>Ctrl</em> în timp ce faceți clic pe ''Reîmprospătare'' sau apăsați <em>Ctrl-F5</em>;\n* <strong>Opera:</strong> Mergeți la <em>Meniu → Setări</em> (<em>Opera → Preferințe</em> pe un sistem Mac) și apoi la <em>Confidențialitate & securitate → Șterge istoricul de navigare → Imagini și fișiere memorate în cache</em>.",
        "usercssyoucanpreview": "'''Sfat:''' Folosiți butonul „{{int:showpreview}}” pentru a testa noul CSS înainte de a-l salva.",
+       "userjsonyoucanpreview": "'''Sfat:''' Folosiți butonul „{{int:showpreview}}” pentru a testa noul JSON înainte de a-l salva.",
        "userjsyoucanpreview": "'''Sfat:''' Folosiți butonul „{{int:showpreview}}” pentru a testa noul JavaScript înainte de a-l salva.",
        "usercsspreview": "'''Rețineți că vizualizați doar o previzualizare a CSS-ului dumneavoastră de utilizator.'''\n'''Acesta nu a fost încă salvat!'''",
+       "userjsonpreview": "<strong>Rețineți că vedeți doar o previzualizare a JSON-ului dumneavoastră de utilizator.\nAcesta nu a fost încă salvat!</strong>",
        "userjspreview": "'''Rețineți că vizualizați doar o previzualizare/versiune de testare a JavaScript-ului dumneavoastră de utilizator.'''\n'''Acesta nu a fost încă salvat!'''",
        "sitecsspreview": "'''Rețineți că doar previzualizați această foaie de stil.'''\n'''Ea nu a fost salvată încă!'''",
+       "sitejsonpreview": "<strong>Rețineți că doar previzualizați această configurație JSON.\nEl nu a fost salvat încă!</strong>",
        "sitejspreview": "'''Rețineți că doar previzualizați acest cod JavaScript.'''\n'''El nu a fost salvat încă!'''",
-       "userinvalidconfigtitle": "'''Avertizare:''' Nu există aspectul „$1”.\nPaginile .css și .js specifice utilizatorilor au titluri care încep cu literă mică; de exemplu {{ns:user}}:Foo/vector.css în comparație cu {{ns:user}}:Foo/Vector.css.",
+       "userinvalidconfigtitle": "<strong>Avertizare:</strong> Nu există skinul „$1”.\nPaginile .css, .json și .js specifice utilizatorilor au titluri care încep cu literă mică; de exemplu {{ns:user}}:Foo/vector.css în loc de {{ns:user}}:Foo/Vector.css.",
        "updated": "(Actualizat)",
        "note": "'''Notă:'''",
        "previewnote": "'''Țineți cont că aceasta este doar o previzualizare.'''\nModificările dumneavoastră nu au fost încă salvate!",
        "longpageerror": "'''Eroare: Textul pe care l-ați trimis are o lungime de {{PLURAL:$1|un kilooctet|$1 kiloocteți|$1 de kiloocteți}}, ceea ce înseamnă mai mult decât maximul de {{PLURAL:$2|un kilooctet|$2 kiloocteți|$2 de kiloocteți}}.'''\nSalvarea nu este posibilă.",
        "readonlywarning": "<strong>Atenție: Baza de date a fost blocată pentru întreținere, deci nu veți putea salva modificările în acest moment.</strong>\nPuteți copia textul într-un fișier text, păstrându-l pentru mai târziu.\n\nAdministratorul de sistem care a efectuat blocarea a oferit următoarea explicație: $1",
        "protectedpagewarning": "'''Atenție: această pagină a fost protejată astfel încât poate fi modificată doar de către administratori.'''\nUltima intrare în jurnal este afișată mai jos pentru referință:",
-       "semiprotectedpagewarning": "'''Observație: această pagină a fost protejată și poate fi modificată doar de către utilizatorii înregistrați.'''\nUltima intrare în jurnal este afișată mai jos pentru referință:",
+       "semiprotectedpagewarning": "<strong>Observație:</strong> această pagină a fost protejată și poate fi modificată doar de către utilizatorii autoconfirmați.\nUltima intrare în jurnal este afișată mai jos pentru referință:",
        "cascadeprotectedwarning": "<strong>Atenție:</strong> Această pagină a fost protejată, astfel încât numai [[Special:ListGroupRights|utilizatori cu drepturi specifice]] o pot modifica, fiind inclusă în {{PLURAL:$1|următoarea pagină protejată|următoarele pagini protejate}} în cascadă:",
        "titleprotectedwarning": "'''Atenție: această pagină a fost protejată astfel încât doar anumiți [[Special:ListGroupRights|utilizatori]] o pot crea.'''\nUltima intrare în jurnal este afișată mai jos pentru referință:",
        "templatesused": "{{PLURAL:$1|Format folosit|Formate folosite}} în această pagină:",
        "diff-paragraph-moved-toold": "Paragraful a fost mutat. Clic pentru a ajunge la vechea locație.",
        "difference-missing-revision": "{{PLURAL:$2|O versiune a|$2 versiuni ale|$2 de versiuni ale}} acestei diferențe ($1) nu {{PLURAL:$2|a fost găsită|au fost găsite}}.\n\nAcest lucru se întâmplă de obicei atunci când se accesează o legătură expirată către istoricul unei pagini șterse.\nDetalii se pot găsi în [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} jurnalul ștergerilor].",
        "searchresults": "Rezultatele căutării",
+       "search-filter-title-prefix-reset": "Caută toate paginile",
        "searchresults-title": "Rezultatele căutării pentru „$1”",
        "titlematches": "Rezultate din titlurile paginilor",
        "textmatches": "Rezultate din conținutul paginilor",
        "default": "standard",
        "prefs-files": "Fișiere",
        "prefs-custom-css": "CSS personalizat",
+       "prefs-custom-json": "JSON personalizat",
        "prefs-custom-js": "JS personalizat",
-       "prefs-common-config": "Pagini CSS și JavaScript comune pentru toate interfețele:",
+       "prefs-common-config": "Pagini CSS/JSON/JavaScript comune pentru toate interfețele:",
        "prefs-reset-intro": "Poți folosi această pagină pentru a reseta preferințele la valorile implicite.\nAcțiunea nu este reversibilă.",
        "prefs-emailconfirm-label": "Confirmare e-mail:",
        "youremail": "Adresă de e-mail:",
        "prefs-dateformat": "Format dată",
        "prefs-timeoffset": "Decalaj orar",
        "prefs-advancedediting": "Opțiuni generale",
+       "prefs-developertools": "Unelte pentru dezvolatori",
        "prefs-editor": "Editor",
        "prefs-preview": "Previzualizare",
        "prefs-advancedrc": "Opțiuni avansate",
        "right-editcontentmodel": "Modifică modelul de conținut al unei pagini",
        "right-editinterface": "Modifică interfața cu utilizatorul",
        "right-editusercss": "Modifică fișierele CSS ale altor utilizatori",
+       "right-edituserjson": "Modifică fișierele JSON ale altor utilizatori",
        "right-edituserjs": "Modifică fișierele JS ale altor utilizatori",
        "right-editmyusercss": "Modificați-vă propriile fișiere CSS",
+       "right-editmyuserjson": "Modificați-vă propriile fișiere JSON",
        "right-editmyuserjs": "Modificați-vă propriile fișiere JavaScript",
        "right-viewmywatchlist": "Vizualizați propria listă de pagini urmărite",
        "right-editmywatchlist": "Modificați propria listă de pagini urmărite. Rețineți că anumite acțiuni vor adăuga pagini chiar și fără acest drept.",
        "grant-createaccount": "Creare conturi",
        "grant-createeditmovepage": "Creează, editează și redenumește pagini",
        "grant-delete": "Șterge pagini, revizii și loguri",
-       "grant-editinterface": "Editați spațiul de nume MediaWiki și CSS/JavaScript de utilizator",
-       "grant-editmycssjs": "Editați CSS/JavaScript ale contului dv.",
+       "grant-editinterface": "Editați spațiul de nume MediaWiki și CSS/JSON/JavaScript de utilizator",
+       "grant-editmycssjs": "Editați CSS/JSON/JavaScript ale contului dv.",
        "grant-editmyoptions": "Modificați-vă preferințele de utilizator",
        "grant-editmywatchlist": "Modificați-vă lista de pagini urmărite",
        "grant-editpage": "Editați pagini existente",
        "rcfilters-other-review-tools": "Alte unelte de revizuire",
        "rcfilters-group-results-by-page": "Grupează rezultatele după pagină",
        "rcfilters-activefilters": "Filtre active",
+       "rcfilters-activefilters-hide": "Ascunde",
+       "rcfilters-activefilters-show": "Arată",
+       "rcfilters-activefilters-hide-tooltip": "Ascunde zona filtrelor active",
+       "rcfilters-activefilters-show-tooltip": "Arată zona filtrelor active",
        "rcfilters-advancedfilters": "Filtre avansate",
        "rcfilters-limit-title": "Schimbări de afișat",
        "rcfilters-limit-and-date-label": "$1 {{PLURAL:$1|schimbare|schimbări|de schimbări}}, $2",
        "rcfilters-savedqueries-rename": "Redenumește",
        "rcfilters-savedqueries-setdefault": "Setează ca predefinit",
        "rcfilters-savedqueries-unsetdefault": "Eliminați ca implicit",
-       "rcfilters-savedqueries-remove": "Elimină",
+       "rcfilters-savedqueries-remove": "Șterge",
        "rcfilters-savedqueries-new-name-label": "Nume",
        "rcfilters-savedqueries-new-name-placeholder": "Descrie scopul fitrului",
        "rcfilters-savedqueries-apply-label": "Crează filtru",
        "rcfilters-empty-filter": "Nu există filtre active. Toate contribuțiile sunt afișate.",
        "rcfilters-filterlist-title": "Filtre",
        "rcfilters-filterlist-whatsthis": "Cum funcționează acestea?",
-       "rcfilters-filterlist-feedbacklink": "Spuneți-ne ce credeți despre aceste (noi) unelte de filtrare",
+       "rcfilters-filterlist-feedbacklink": "Spuneți-ne ce credeți despre aceste unelte de filtrare",
        "rcfilters-highlightbutton-title": "Evidențiați rezultatele",
        "rcfilters-highlightmenu-title": "Selectați o culoare",
        "rcfilters-highlightmenu-help": "Selectați o culoare pentru a evidenția această proprietate",
        "rcfilters-filter-humans-description": "Modificări făcute de oameni.",
        "rcfilters-filtergroup-reviewstatus": "Statutul reviziei",
        "rcfilters-filter-reviewstatus-unpatrolled-label": "Nepatrulate",
+       "rcfilters-filter-reviewstatus-manual-description": "Modificări marcate manual ca patrulate.",
+       "rcfilters-filter-reviewstatus-manual-label": "Patrulate manual",
+       "rcfilters-filter-reviewstatus-auto-label": "Patrulate automat",
        "rcfilters-filtergroup-significance": "Semnificație",
        "rcfilters-filter-minor-label": "Modificări minore",
        "rcfilters-filter-minor-description": "Modificări pe care autorul le-a marcat ca fiind minore.",
        "recentchangeslinked-feed": "Modificări corelate",
        "recentchangeslinked-toolbox": "Modificări corelate",
        "recentchangeslinked-title": "Modificări legate de „$1”",
-       "recentchangeslinked-summary": "Introduceți titlul unei pagini pentru a vedea schimbările din paginile spre care trimite sau care trimit spre ea. (Pentru a vedea membrii unei categorii, scrieți Categorie:Numele categoriei).\nSchimbările din paginile pe care le [[Special:Watchlist|urmăriți]] apar cu <strong>aldine</strong>.",
+       "recentchangeslinked-summary": "Introduceți titlul unei pagini pentru a vedea schimbările din paginile spre care trimite sau care trimit spre ea. (Pentru a vedea membrii unei categorii, scrieți {{ns:category}}:Numele categoriei).\nSchimbările din paginile pe care le [[Special:Watchlist|urmăriți]] apar cu <strong>aldine</strong>.",
        "recentchangeslinked-page": "Numele paginii:",
        "recentchangeslinked-to": "Arată în schimb modificările asupra paginilor care se leagă de pagina indicată",
        "recentchanges-page-added-to-category": "[[:$1]] a fost adăugată în categorii",
        "deadendpages": "Pagini fără legături",
        "deadendpagestext": "Următoarele pagini nu se leagă de alte pagini din acestă wiki.",
        "protectedpages": "Pagini protejate",
+       "protectedpages-filters": "Filtre:",
        "protectedpages-indef": "Doar protejări pe termen nelimitat",
        "protectedpages-summary": "Această pagină enumeră paginile protejate în acest moment. Pentru o listă a titlurilor protejate la creare, vedeți [[{{#special:ProtectedTitles}}|{{int:protectedtitles}}]].",
        "protectedpages-cascade": "Doar protejări în cascadă",
        "apisandbox-dynamic-error-exists": "Un parametru cu numele „$1” există deja.",
        "apisandbox-deprecated-parameters": "Parametri învechiți",
        "apisandbox-fetch-token": "Completează automat jetonul",
+       "apisandbox-add-multi": "Adaugă",
        "apisandbox-submit-invalid-fields-title": "Anumite câmpuri nu sunt valide",
        "apisandbox-submit-invalid-fields-message": "Corectați câmpurile marcate și încercați din nou.",
        "apisandbox-results": "Rezultate",
        "speciallogtitlelabel": "Destinație (titlu sau {{ns:user}}:numeutilizator pentru utilizator):",
        "log": "Jurnale",
        "logeventslist-submit": "Afișează",
+       "logeventslist-more-filters": "Arată jurnale adiționale:",
+       "logeventslist-patrol-log": "Jurnal de patrulare",
+       "logeventslist-tag-log": "Jurnal etichete",
        "all-logs-page": "Toate jurnalele publice",
        "alllogstext": "Afișare combinată a tuturor jurnalelor {{SITENAME}}.\nPuteți limita vizualizarea selectând tipul jurnalului, numele de utilizator sau pagina afectată.",
        "logempty": "Nici o înregistrare în jurnal.",
        "dellogpage": "Jurnal ștergeri",
        "dellogpagetext": "Mai jos se află lista celor mai recente elemente șterse.",
        "deletionlog": "jurnal pagini șterse",
+       "log-name-create": "Jurnal creare pagini",
+       "log-description-create": "Mai jos se află lista celor mai recente pagini create.",
+       "logentry-create-create": "$1 {{GENDER:$2|a creat|a creat}} pagina $3",
        "reverted": "Revenire la o versiune mai veche",
        "deletecomment": "Motiv:",
        "deleteotherreason": "Motiv diferit/suplimentar:",
        "uctop": "(actuală)",
        "month": "Din luna (și dinainte):",
        "year": "Din anul (și dinainte):",
+       "date": "Din data (și dinainte):",
        "sp-contributions-newbies": "Arată doar contribuțiile conturilor noi",
        "sp-contributions-newbies-sub": "Pentru începători",
        "sp-contributions-newbies-title": "Contribuțiile utilizatorului pentru conturile noi",
        "whatlinkshere": "Ce trimite aici",
        "whatlinkshere-title": "Pagini care conțin legături spre „$1”",
        "whatlinkshere-page": "Pagină:",
-       "linkshere-2": "Următoarele pagini conțin legături către <strong>$1</strong>:",
-       "nolinkshere-2": "Nici o pagină nu trimite la '''$1'''.",
-       "nolinkshere-ns-2": "Nici o pagină din spațiul de nume ales nu trimite la '''$1'''.",
+       "linkshere": "Următoarele pagini conțin legături către <strong>$2</strong>:",
+       "nolinkshere": "Nici o pagină nu trimite la '''$2'''.",
+       "nolinkshere-ns": "Nici o pagină din spațiul de nume ales nu trimite la '''$2'''.",
        "isredirect": "pagină de redirecționare",
        "istemplate": "prin includerea formatului",
        "isimage": "legătură către fișier",
        "tooltip-ca-nstab-category": "Vezi categoria",
        "tooltip-minoredit": "Marchează această modificare ca fiind minoră",
        "tooltip-save": "Salvați modificările dumneavoastră",
-       "tooltip-publish": "Publică modificările tale",
+       "tooltip-publish": "Publicați-vă modificările",
        "tooltip-preview": "Previzualizați-vă modificările. Vă rugăm să faceți acest lucru înainte de a salva pagina.",
        "tooltip-diff": "Afișează modificările pe care le-ați efectuat asupra textului",
        "tooltip-compareselectedversions": "Vezi diferențele între cele două versiuni selectate de pe această pagină.",
        "markedaspatrollederrornotify": "Marcarea ca patrulată a eșuat.",
        "patrol-log-page": "Jurnal verificări",
        "patrol-log-header": "Aceasta este o listă a tuturor versiunilor marcate ca verificate.",
-       "log-show-hide-patrol": "$1 jurnalul versiunilor verificate",
-       "log-show-hide-tag": "$1 jurnal etichete",
        "confirm-markpatrolled-button": "OK",
        "confirm-markpatrolled-top": "Marcați revizia $3 a $2 ca patrulată?",
        "deletedrevision": "A fost ștearsă vechea versiune $1.",
        "version-specialpages": "Pagini speciale",
        "version-parserhooks": "Hook-uri parser",
        "version-variables": "Variabile",
+       "version-editors": "Editori",
        "version-antispam": "Prevenirea spamului",
        "version-other": "Altele",
        "version-mediahandlers": "Suport media",
        "diff-form": "Diferențe",
        "diff-form-submit": "Arată diferențele",
        "permanentlink": "Legătură permanentă",
+       "permanentlink-submit": "Mergi la versiunea",
        "dberr-problems": "Ne cerem scuze! Acest site întâmpină dificultăți tehnice.",
        "dberr-again": "Așteptați câteva minute și încercați din nou.",
        "dberr-info": "(Nu se poate accesa baza de date: $1)",
        "limitreport-templateargumentsize-value": "$1/$2 {{PLURAL:$2|octet|octeți|de octeți}}",
        "limitreport-expansiondepth": "Cea mai mare profunzime a expansiunii",
        "limitreport-expensivefunctioncount": "Număr de funcții de analiză costisitoare",
+       "limitreport-unstrip-size-value": "$1/$2 {{PLURAL:$2|octet|octeți|de octeți}}",
        "expandtemplates": "Expandare formate",
        "expand_templates_intro": "Această pagină specială servește la expandarea recursivă a tuturor formatelor dintr-un wikitext. Ea acționează și asupra funcțiilor de analiză (''parser'') de tipul <nowiki>{{</nowiki>#if:...}}, a variabilelor precum <nowiki>{{</nowiki>CURRENTDAY}} și în general asupra oricăror coduri cuprinse între acolade duble.",
        "expand_templates_title": "Titlul contextului (de exemplu pentru {{PAGENAME}}):",
        "pagelang-reason": "Motiv",
        "pagelang-submit": "Trimite",
        "pagelang-nonexistent-page": "Pagina $1 nu există.",
+       "pagelang-unchanged-language": "Pagina $1 e deja în limba $2.",
        "right-pagelang": "Modifică limba paginii",
        "action-pagelang": "modificați limba paginii",
        "log-name-pagelang": "Jurnal modificare limbă",
        "special-characters-group-thai": "Thailandeză",
        "special-characters-group-lao": "Laoțiană",
        "special-characters-group-khmer": "Khmeră",
+       "special-characters-group-canadianaboriginal": "Aborigen Canadian",
        "special-characters-title-endash": "linie de pauză (en dash)",
        "special-characters-title-emdash": "linie de pauză (em dash)",
        "special-characters-title-minus": "semnul minus",
        "mw-widgets-dateinput-no-date": "Nicio dată selectată",
        "mw-widgets-dateinput-placeholder-day": "AAAA-LL-ZZ",
        "mw-widgets-dateinput-placeholder-month": "AAAA-LL",
+       "mw-widgets-mediasearch-input-placeholder": "Căutare de multimedia",
        "mw-widgets-mediasearch-noresults": "Niciun rezultat găsit.",
        "mw-widgets-titleinput-description-new-page": "pagina nu există încă",
        "mw-widgets-titleinput-description-redirect": "redirecționare către $1",
        "log-action-filter-managetags-delete": "Ștergere tag",
        "log-action-filter-managetags-activate": "Activare tag",
        "log-action-filter-managetags-deactivate": "Dezactivare tag",
+       "log-action-filter-newusers-create": "Creare de utilizator anonim",
+       "log-action-filter-newusers-create2": "Creare de un utilizator înregistrat",
        "log-action-filter-newusers-autocreate": "Creare automată",
        "log-action-filter-patrol-patrol": "Patrulă manuală",
        "log-action-filter-patrol-autopatrol": "Patrulă automată",
        "gotointerwiki-invalid": "Titlul specificat nu este valid.",
        "pagedata-title": "Datele paginii",
        "pagedata-not-acceptable": "Niciun format corespunzător găsit. Tipuri MIME acceptate: $1",
-       "pagedata-bad-title": "Titlu invalid: $1."
+       "pagedata-bad-title": "Titlu invalid: $1.",
+       "passwordpolicies": "Politică parole",
+       "passwordpolicies-group": "Grup",
+       "passwordpolicies-policies": "Politici",
+       "passwordpolicies-policy-minimalpasswordlength": "Parola trebuie să aibă cel puțin $1 {{PLURAL:$1|caracter|caractere|de caractere}}.",
+       "passwordpolicies-policy-minimumpasswordlengthtologin": "Parola trebuie să aibă cel puțin $1 {{PLURAL:$1|caracter|caractere|de caractere}} pentru a vă putea autentifica.",
+       "passwordpolicies-policy-passwordcannotmatchusername": "Parola nu poate fi identică cu numele de utilizator",
+       "passwordpolicies-policy-passwordcannotmatchblacklist": "Parolele nu pot fi cele de pe lista neagră",
+       "passwordpolicies-policy-maximalpasswordlength": "Parola trebuie să aibă cel puțin $1 {{PLURAL:$1|caracter|caractere|de caractere}}.",
+       "passwordpolicies-policy-passwordcannotbepopular": "Parola nu poate fi {{PLURAL:$1|o parolă populară|în lista celor $1 parole populare|în lista celor $1 de parole populare}}."
 }
index e153ec3..e32a7c2 100644 (file)
@@ -9,7 +9,9 @@
                        "C.R.",
                        "Macofe",
                        "Purodha",
-                       "Fitoschido"
+                       "Fitoschido",
+                       "Ruthven",
+                       "Matěj Suchánek"
                ]
        },
        "tog-underline": "Collegaminde sottolinèate:",
        "subject-preview": "Andeprime de l'oggette:",
        "previewerrortext": "'N'errore ha assute quanne ste facive l'andeprime de le cangiaminde.",
        "blockedtitle": "L'utende è blocchete",
-       "blockedtext": "''''U nome de l'utende o l'indirizze IP ha state bloccate.'''\n\n'U blocche ha state fatte da $1.\n'U mutive date jè ''$2''.\n\n* 'U Blocche accumenze: $8\n* 'U Blocche spicce: $6\n* Tipe de blocche: $7\n\nTu puè condatta $1 o n'otre [[{{MediaWiki:Grouppage-sysop}}|amministratore]] pe 'ngazzarte sus a 'u blocche.\nTu non ge puè ausà 'u strumende 'manne 'na mail a stu utende' senza ca mitte n'indirizze e-mail valide jndr'à le\n[[Special:Preferences|preferenze tue]] e ce è state blocchete sus 'a l'use sue.\nL'IP ca tine mò jè $3 e 'u codece d'u blocche jè #$5.\nPe piacere mitte ste doje 'mbormaziune ce manne 'na richieste de sblocche.",
+       "blockedtext": "<strong>'U nome de l'utende o l'indirizze IP ha state bloccate.</strong>\n\n'U blocche ha state fatte da $1.\n'U mutive date jè <em>$2</em>.\n\n* 'U Blocche accumenze: $8\n* 'U Blocche spicce: $6\n* Tipe de blocche: $7\n\nTu puè condatta $1 o n'otre [[{{MediaWiki:Grouppage-sysop}}|amministratore]] pe 'ngazzarte sus a 'u blocche.\nTu non ge puè ausà 'u strumende \"{{int:emailuser}}\" senza ca mitte n'indirizze email valide jndr'à le\n[[Special:Preferences|preferenze tune]] e ce è state bloccate sus a l'use sue.\nL'IP ca tine mò jè $3 e 'u codece d'u blocche jè #$5.\nPe piacere mitte ste doje 'mbormaziune ce manne 'na richieste de sblocche.",
        "autoblockedtext": "L'indirizze IP tue ha state automaticamende blocchete purcè ha state ausete da n'otre utende, ca avère state blocchete da $1.\n'U mutive date jè 'u seguende:\n\n:''$2''\n\n* Inizie d'u blocche: $8\n* Scadenze d'u blocche: $6\n* Blocche 'ndise: $7\n\nTu puè cundattà $1 o une de l'otre [[{{MediaWiki:Grouppage-sysop}}|amministrature]] pe parà de stu probbleme.\n\nVide Bbuene ca tu non ge puè ausà 'a funziona \"manne n'e-mail a stu utende\" senze ca tu tìne 'n'indirizze e-mail valide e reggistrete jndr'à seziona [[Special:Preferences|me piace accussì]] e tu non ge sinde blocchete da ausarle.\n\nL'indirizze IP corrende jè $3, e 'u codece d'u blocche jè #$5.\nPe piacere mitte tutte le dettaglie ca ponne essere utile pe le richieste tue.",
        "blockednoreason": "nisciune mutive",
        "whitelistedittext": "Tu ha $1 pàggene da cangià.",
        "prefs-help-recentchangescount": "Quiste 'nglude le urteme cangiaminde, le storie de le pàggene e le archivije.",
        "prefs-help-watchlist-token2": "Queste jè 'a chiave segrete a le feed d'u web de l'elenghe de le pàggene condrollate tune.\nCengate vò ccu canosce ce pò leggere l'elenghe de le pàggene condrollate tune, accussì non g'ù pò condividere.\nCe è abbesogne, [[Special:ResetTokens|'u puè azzerà]].",
        "savedprefs": "Le preferenze tue onne state aggiornete.",
-       "savedrights": "Le gruppe utinde de {{GENDER:$1$1}} onne state reggistrate.",
+       "savedrights": "Le gruppe utinde de {{GENDER:$1|$1}} onne state reggistrate.",
        "timezonelegend": "Orarie d'a zone:",
        "localtime": "Orarie lochele:",
        "timezoneuseserverdefault": "Ause 'u valore de default de uicchi ($1)",
        "recentchangeslinked-feed": "Cangiaminde culleghete",
        "recentchangeslinked-toolbox": "Cangiaminde culleghete",
        "recentchangeslinked-title": "Cangiaminde culleghete a \"$1\"",
-       "recentchangeslinked-summary": "Mitte 'u nome de 'na pàgene pe 'ndrucà le cangiaminde a le pàggene ca sò collegate o ca appondane a sta pàgene. (Pe 'ndrucà le membre de 'na categorije, mitte Categoria:Nome d'a categorije). Le cangiaminde a le pàggene ca stonne jndr'à l'elenghe de [[Special:Watchlist|le Pàggene condrollate]] stonne in <strong>grascette</strong>.",
+       "recentchangeslinked-summary": "Mitte 'u nome de 'na pàgene pe 'ndrucà le cangiaminde a le pàggene ca sò collegate o ca appondane a sta pàgene. (Pe 'ndrucà le membre de 'na categorije, mitte {{ns:category}}:Nome d'a categorije). Le cangiaminde a le pàggene ca stonne jndr'à l'elenghe de [[Special:Watchlist|le Pàggene condrollate]] stonne in <strong>grascette</strong>.",
        "recentchangeslinked-page": "Nome d'a vôsce:",
        "recentchangeslinked-to": "Fa vedè le cangiaminde de le pàggene colleghete a 'na certa pàgene",
        "recentchanges-page-added-to-category": "[[:$1]] aggiunde a categorije",
        "whatlinkshere": "Appondene aqquà",
        "whatlinkshere-title": "Pàggene ca appondene a \"$1\"",
        "whatlinkshere-page": "Pàgene:",
-       "linkshere-2": "Le pàggene ca avènene appondene a '''$1''':",
-       "nolinkshere-2": "Nisciuna pàgene apponde a '''$1'''.",
-       "nolinkshere-ns-2": "Nisciuna pàgene apponde a '''$1''' jndr'à 'u namespace scacchiete.",
+       "linkshere": "Le pàggene ca avènene appondene a '''$2''':",
+       "nolinkshere": "Nisciuna pàgene apponde a '''$2'''.",
+       "nolinkshere-ns": "Nisciuna pàgene apponde a '''$2''' jndr'à 'u namespace scacchiete.",
        "isredirect": "pàgene de ridirezionamende",
        "istemplate": "inclusione",
        "isimage": "collegamende a 'u file",
        "tooltip-feed-rss": "RSS feed pe sta pàgene",
        "tooltip-feed-atom": "Atom feed pe sta pàgene",
        "tooltip-t-contributions": "Vide l'elenghe de le condrebbute de {{GENDER:$1|stu utende}}",
-       "tooltip-t-emailuser": "Manne n'e-mail a {{GENDER:$1stu utende}}",
+       "tooltip-t-emailuser": "Manne n'e-mail a {{GENDER:$1|stu utende}}",
        "tooltip-t-info": "Cchiù 'mbormaziune sus a sta pàgene",
        "tooltip-t-upload": "Careche le file",
        "tooltip-t-specialpages": "Liste de tutte le pàggene speciale",
        "markedaspatrollederrornotify": "Signate cumme condrollate fallite.",
        "patrol-log-page": "Archivije de le condrolle",
        "patrol-log-header": "Quiste è l'archivije de le revisiune condrollate.",
-       "log-show-hide-patrol": "$1 archivije de le condrolle",
-       "log-show-hide-tag": "$1 archivije de le tag",
        "confirm-markpatrolled-button": "OK",
        "confirm-markpatrolled-top": "Signe 'a revisione $3 de $2 cumme condrollate?",
        "deletedrevision": "Vecchia revisione scangellete $1",
index 182c3b3..185ddac 100644 (file)
                        "Patrick Star",
                        "Happy13241",
                        "Vcohen",
-                       "AttemptToCallNil"
+                       "AttemptToCallNil",
+                       "Stjn",
+                       "Vlad5250"
                ]
        },
        "tog-underline": "Подчёркивание ссылок:",
        "pagetitle": "$1 — {{SITENAME}}",
        "pagetitle-view-mainpage": "{{SITENAME}}",
        "backlinksubtitle": "← $1",
-       "retrievedfrom": "Источник — «$1»",
-       "youhavenewmessages": "Вы получили $1 ($2).",
+       "retrievedfrom": "Источник — $1",
+       "youhavenewmessages": "{{PLURAL:$3|Вы получили}} $1 ($2).",
        "youhavenewmessagesfromusers": "{{PLURAL:$4|Вы получили}} $1 от {{PLURAL:$3|$3 участника|$3 участников|1=другого участника}} ($2).",
        "youhavenewmessagesmanyusers": "Вы получили $1 от множества пользователей ($2).",
        "newmessageslinkplural": "{{PLURAL:$1|1=новое сообщение|999=новые сообщения}}",
        "customcssprotected": "У вас нет разрешения редактировать эту CSS-страницу, так как она содержит личные настройки другого участника.",
        "customjsonprotected": "У вас нет разрешения редактировать эту JSON-страницу, так как она содержит личные настройки другого участника.",
        "customjsprotected": "У вас нет разрешения редактировать эту JavaScript-страницу, так как она содержит личные настройки другого участника.",
+       "sitecssprotected": "У вас нет разрешения редактировать эту CSS-страницу, поскольку её изменение может повлиять на всех посетителей.",
+       "sitejsonprotected": "У вас нет разрешения для редактирования этой JSON-страницы, поскольку её изменение может повлиять на всех посетителей.",
+       "sitejsprotected": "У вас нет разрешения редактировать эту JavaScript страницу, поскольку её изменение может повлиять на всех посетителей.",
        "mycustomcssprotected": "У вас нет прав для редактирования этого CSS страницы.",
        "mycustomjsonprotected": "У вас нет прав для редактирования этой JSON-страницы.",
        "mycustomjsprotected": "У вас нет прав для редактирования JavaScript на странице.",
        "resetpass-abort-generic": "Изменение пароля было прервано расширением.",
        "resetpass-expired": "Срок действия вашего пароля истёк. Пожалуйста, установите новый пароль для входа в систему.",
        "resetpass-expired-soft": "Срок действия вашего пароля истёк, и теперь он должен быть изменён. Пожалуйста, выберите новый пароль или нажмите «{{int:authprovider-resetpass-skip-label}}», чтобы изменить его позже.",
-       "resetpass-validity-soft": "Задан некорректный пароль: $1\n\nПожалуйста, выберите новый пароль или нажмите «{{int:authprovider-resetpass-skip-label}}», чтобы сбросить его позже.",
+       "resetpass-validity-soft": "Задан некорректный пароль: $1\n\nПожалуйста, выберите новый пароль или нажмите «{{int:authprovider-resetpass-skip-label}}», чтобы изменить его позже.",
        "passwordreset": "Сброс пароля",
        "passwordreset-text-one": "Заполните эту форму, чтобы сбросить свой пароль.",
        "passwordreset-text-many": "{{PLURAL:$1|Заполните одно из полей для получения временного пароля по электронной почте.}}",
        "expansion-depth-exceeded-warning": "На странице превышен предел вложенности",
        "parser-unstrip-loop-warning": "Обнаружен незакрытый pre",
        "unstrip-depth-warning": "Превышен предел рекурсии ($1)",
-       "unstrip-depth-category": "Страницы где незаметная глубина превышена",
-       "unstrip-size-warning": "Unstrip превышен предел рекурсии ($1)",
-       "unstrip-size-category": "Страницы где незаметная разметка превышена",
+       "unstrip-depth-category": "Страницы с превышенным лимитом глубины Unstrip",
+       "unstrip-size-warning": "Превышен лимит размера Unstrip ($1)",
+       "unstrip-size-category": "Страницы с превышенным лимитом размера Unstrip",
        "converter-manual-rule-error": "Ошибка в ручном правиле преобразования языка",
        "undo-success": "Правка может быть отменена. Пожалуйста, просмотрите сравнение версий, чтобы убедиться, что это именно те изменения, которые вас интересуют, и нажмите «Записать страницу», чтобы изменения вступили в силу.",
        "undo-failure": "Правка не может быть отменена из-за несовместимости промежуточных изменений.",
+       "undo-main-slot-only": "Правка не может быть отменена, поскольку оно включает контент вне основного слота.",
        "undo-norev": "Правка не может быть отменена, так как её не существует или она была удалена.",
        "undo-nochange": "Правка, похоже, уже была отменена.",
        "undo-summary": "Отмена правки $1, сделанной [[Special:Contributions/$2|$2]] ([[User talk:$2|обсуждение]])",
        "mergelog": "Журнал объединений",
        "revertmerge": "Разделить",
        "mergelogpagetext": "Ниже приведён список последних объединений историй страниц.",
-       "history-title": "$1 — история изменений",
-       "difference-title": "$1 — различия между версиями",
+       "history-title": "$1: история изменений",
+       "difference-title": "$1: различия между версиями",
        "difference-title-multipage": "Разница между страницами «$1» и «$2»",
        "difference-multipage": "(Различия между страницами)",
        "lineno": "Строка $1:",
        "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»",
+       "search-filter-title-prefix-reset": "Искать все страницы",
        "searchresults-title": "Поиск «$1»",
        "titlematches": "Совпадения в названиях страниц",
        "textmatches": "Совпадения в текстах страниц",
        "nextn-title": "{{PLURAL:$1|Следующая $1 запись|Следующие $1 записи|Следующие $1 записей}}",
        "shown-title": "Показывать $1 {{PLURAL:$1|запись|записи|записей}} на странице",
        "viewprevnext": "Просмотреть ($1 {{int:pipe-separator}} $2) ($3)",
-       "searchmenu-exists": "'''В этой вики есть страница «[[:$1]]»'''",
+       "searchmenu-exists": "<strong>В этой вики есть страница «[[:$1]]».</strong> {{PLURAL:$2|0=|См. также другие результаты поиска.}}",
        "searchmenu-new": "<strong>Создать страницу «[[:$1]]» в этом вики-проекте!</strong>\n{{PLURAL:$2|0=|См. также страницу, найденную по результатами вашего поиска.|См. также найденные результаты поиска.}}",
        "searchprofile-articles": "Основные страницы",
        "searchprofile-images": "Мультимедиа",
        "recentchangesdays": "Количество дней, за которые показывать свежие правки:",
        "recentchangesdays-max": "(не более $1 {{PLURAL:$1|дня|дней}})",
        "recentchangescount": "Количество правок, по умолчанию отображаемое в списке свежих правок, истории страниц и в журналах:",
-       "prefs-help-recentchangescount": "Ð\9dаиболÑ\8cÑ\88ее значение: 1000",
+       "prefs-help-recentchangescount": "Ð\9cакÑ\81ималÑ\8cное значение: 1000",
        "prefs-help-watchlist-token2": "Это секретный ключ для веб-канала вашего списка наблюдений.\nЛюбой, кто знает его, сможет читать ваш список наблюдения, поэтому не сообщайте его другим.\nЕсли необходимо, [[Special:ResetTokens|вы можете сбросить его]].",
        "prefs-help-tokenmanagement": "Вы можете просмотреть и сбросить для своей учётной записи секретный ключ, который может получить доступ к веб-каналу вашего списка наблюдения. Любой, кто знает ключ, сможет прочитать ваш список наблюдения, поэтому не делитесь им ни с кем.",
        "savedprefs": "Настройки сохранены.",
        "userrights-irreversible-marker": "$1*",
        "userrights-no-shorten-expiry-marker": "$1#",
        "userrights-expiry-current": "Истекает $1",
-       "userrights-expiry-none": "Ð\9dикогда",
+       "userrights-expiry-none": "Ð\91еÑ\81Ñ\81Ñ\80оÑ\87но",
        "userrights-expiry": "Права истекают:",
        "userrights-expiry-existing": "$2, $3",
        "userrights-expiry-othertime": "Другое время:",
        "group-autoconfirmed": "Автоподтверждённые участники",
        "group-bot": "Боты",
        "group-sysop": "Администраторы",
+       "group-interface-admin": "Администраторы интерфейса",
        "group-bureaucrat": "Бюрократы",
        "group-suppress": "Скрывающие",
        "group-all": "(все)",
        "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-edit": "Ð\9fравка страниц",
        "right-createpage": "создание страниц, не являющихся обсуждениями",
        "right-createtalk": "создание страниц обсуждений",
        "right-createaccount": "создание новых учётных записей участников",
        "right-autocreateaccount": "автоматический вход с помощью внешней учётной записи участника",
-       "right-minoredit": "пÑ\80оÑ\81Ñ\82ановка Ð¾Ñ\82меÑ\82ки Â«Ð¼Ð°Ð»Ð¾Ðµ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸ÐµÂ»",
+       "right-minoredit": "оÑ\82меÑ\82ка Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ð¹ ÐºÐ°Ðº Ð¼Ð°Ð»Ñ\8bÑ\85",
        "right-move": "переименование страниц",
        "right-move-subpages": "переименование страниц с их подстраницами",
        "right-move-rootuserpages": "переименование корневых страниц участников",
        "right-movefile": "переименование файлов",
        "right-suppressredirect": "подавление перенаправлений при переименовании страниц",
        "right-upload": "загрузка файлов",
-       "right-reupload": "запиÑ\81Ñ\8c Ñ\84айлов Ð¿Ð¾Ð²ÐµÑ\80Ñ\85 Ñ\81Ñ\83Ñ\89еÑ\81Ñ\82вÑ\83Ñ\8eÑ\89иÑ\85",
+       "right-reupload": "пеÑ\80езапиÑ\81Ñ\8c Ñ\81Ñ\83Ñ\89еÑ\81Ñ\82вÑ\83Ñ\8eÑ\89иÑ\85 Ñ\84айлов",
        "right-reupload-own": "перезапись файлов тем же участником",
        "right-reupload-shared": "подмена файлов из общих хранилищ локальными",
        "right-upload_by_url": "загрузка файлов с адреса URL",
        "right-purge": "очистка кэша страниц без подтверждения",
        "right-autoconfirmed": "обход ограничений скорости на IP-адрес",
        "right-bot": "автоматический процесс",
-       "right-nominornewtalk": "малые правки на СО участников не создают для них уведомление о новом сообщении",
+       "right-nominornewtalk": "малые правки на страницах обсуждений участников не создают для них уведомление о новом сообщении",
        "right-apihighlimits": "уменьшение ограничений на выполнение API-запросов",
        "right-writeapi": "использование API для записи",
        "right-delete": "удаление страниц",
        "right-editusercss": "правка CSS-файлов других участников",
        "right-edituserjson": "правка JSON-файлов других участников",
        "right-edituserjs": "правка JavaScript-файлов других участников",
+       "right-editsitecss": "редактирование общесайтовых CSS-страниц",
+       "right-editsitejson": "редактирование общесайтовых JSON-страниц",
+       "right-editsitejs": "редактирование общесайтовых JavaScript-страниц",
        "right-editmyusercss": "редактирование своих пользовательских CSS-файлов",
        "right-editmyuserjson": "редактирование своих пользовательских JSON-файлов",
        "right-editmyuserjs": "редактирование своих пользовательских JavaScript-файлов",
        "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": "Редактирование вашего списка наблюдения",
+       "grant-editsiteconfig": "Правка CSS/JavaScript сайта и пользователя",
        "grant-editpage": "Редактирование существующих страниц",
        "grant-editprotected": "Редактирование защищённых страниц",
        "grant-highvolume": "Редактирование с высокой интенсивностью",
        "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-restore-default-filters": "Восстановить фильтры по умолчанию",
        "rcfilters-clear-all-filters": "Очистить все фильтры",
        "rcfilters-show-new-changes": "Последние изменения",
-       "rcfilters-search-placeholder": "Ð\98зменениÑ\8f Ñ\84илÑ\8cÑ\82Ñ\80ов (используйте меню или ищите по названию фильтра)",
+       "rcfilters-search-placeholder": "ФилÑ\8cÑ\82Ñ\80оваÑ\82Ñ\8c Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ\8f (используйте меню или ищите по названию фильтра)",
        "rcfilters-invalid-filter": "Недопустимый фильтр",
        "rcfilters-empty-filter": "Нет активных фильтров. Показываются все правки.",
        "rcfilters-filterlist-title": "Фильтры",
        "rcfilters-filterlist-whatsthis": "Как это работает?",
-       "rcfilters-filterlist-feedbacklink": "Расскажите нам, что вы думаете об этих (новых) инструментах фильтрации",
+       "rcfilters-filterlist-feedbacklink": "Расскажите нам, что вы думаете об этих инструментах фильтрации",
        "rcfilters-highlightbutton-title": "Выделить результаты",
        "rcfilters-highlightmenu-title": "Выберите цвет",
        "rcfilters-highlightmenu-help": "Выберите цвет, чтобы подсветить это свойство",
        "rcfilters-filter-major-description": "Правки, не помеченные как малые.",
        "rcfilters-filtergroup-watchlist": "Страницы в списке наблюдения",
        "rcfilters-filter-watchlist-watched-label": "В списке наблюдения",
-       "rcfilters-filter-watchlist-watched-description": "Изменения страниц в вашем Списке наблюдения.",
+       "rcfilters-filter-watchlist-watched-description": "Изменения страниц в вашем списке наблюдения.",
        "rcfilters-filter-watchlist-watchednew-label": "Новые изменения в списке наблюдения",
        "rcfilters-filter-watchlist-watchednew-description": "Правки на страницах из вашего списка наблюдения, которые вы не просмотрели с их совершения.",
        "rcfilters-filter-watchlist-notwatched-label": "Нет в списке наблюдения",
        "rcfilters-view-namespaces-tooltip": "Результаты фильтра по пространствам имён",
        "rcfilters-view-tags-tooltip": "Фильтровать результаты, используя метки правок",
        "rcfilters-view-return-to-default-tooltip": "Вернуться в главное меню фильтров",
-       "rcfilters-view-tags-help-icon-tooltip": "УзнаÑ\82Ñ\8c Ð±Ð¾Ð»Ñ\8cÑ\88е Ð¾ Ñ\80едакÑ\82оÑ\80е Ñ\82егов",
+       "rcfilters-view-tags-help-icon-tooltip": "Ð\9fодÑ\80обнее Ð¾ Ð¿Ñ\80авкаÑ\85 Ñ\81 Ð¼ÐµÑ\82ками",
        "rcfilters-liveupdates-button": "Обновлять автоматически",
        "rcfilters-liveupdates-button-title-on": "Отключить автоматические обновления",
        "rcfilters-liveupdates-button-title-off": "Показывать новые изменения сразу после их появления",
        "rcfilters-watchlist-showupdated": "Изменения страниц, которые вы не посещали с того момента, как они изменились, выделены <strong>жирным</strong> и отмечены полным маркером.",
        "rcfilters-preference-label": "Скрыть улучшенную версию «Свежих правок»",
        "rcfilters-preference-help": "Откатывает редизайн интерфейса 2017 года и все инструменты, добавленные с тех пор.",
+       "rcfilters-watchlist-preference-label": "Скрыть улучшенную версию cписка наблюдения",
+       "rcfilters-watchlist-preference-help": "Отменяет редизайн интерфейса 2017 года и все инструменты, добавленные тогда и позднее.",
        "rcfilters-filter-showlinkedfrom-label": "Показать правки на ссылаемых страницах",
        "rcfilters-filter-showlinkedfrom-option-label": "<strong>Страницы, на которые ссылается</strong> выбранная",
        "rcfilters-filter-showlinkedto-label": "Показать правки на ссылающихся страницах",
        "uploadstash-zero-length": "Файл нулевой длины.",
        "invalid-chunk-offset": "Недопустимое смещение фрагмента",
        "img-auth-accessdenied": "Доступ запрещён",
-       "img-auth-nopathinfo": "Отсутствует <code>PATH_INFO</code>.\nВаш сервер не настроен для передачи этих сведений.\nВозможно, он работает на основе CGI и не поддерживает <code>img_auth</code>.\nСм. https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization.",
+       "img-auth-nopathinfo": "Отсутствует информация о пути.\nВаш сервер должен быть настроен для передачи переменных REQUEST_URI и/или PATH_INFO.\nЕсли это так, попробуйте включить $wgUsePathInfo.\nСм. https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization.",
        "img-auth-notindir": "Запрашиваемый путь не относится к настроенной папке загрузок.",
        "img-auth-badtitle": "Невозможно построить правильный заголовок из «$1».",
        "img-auth-nologinnWL": "Вы не вошли в систему, а «$1» не входит в белый список.",
        "http-timed-out": "Истекло время ожидания HTTP-запроса.",
        "http-curl-error": "Ошибка обращения к URL: $1",
        "http-bad-status": "Во время обработки HTTP-запроса обнаружена проблема: $1 $2",
+       "http-internal-error": "Внутренняя ошибка HTTP.",
        "upload-curl-error6": "Невозможно обратить по указанному адресу.",
        "upload-curl-error6-text": "Невозможно обратить по указанному адресу. Пожалуйста, проверьте, что адрес верен, а сайт доступен.",
        "upload-curl-error28": "Время, отведённое на загрузку, истекло",
        "filerevert-success": "'''[[Media:$1|$1]]''' был возвращён к [$4 версии от $3, $2].",
        "filerevert-badversion": "Не существует предыдущей локальной версии этого файла с указанной меткой времени.",
        "filerevert-identical": "Текущая версия файла уже идентична выбранной.",
-       "filedelete": "$1 — удаление",
+       "filedelete": "$1: удаление",
        "filedelete-legend": "Удалить файл",
        "filedelete-intro": "Вы собираетесь удалить файл '''[[Media:$1|$1]]''' со всей его историей.",
        "filedelete-intro-old": "Вы удаляете версию <strong>[[Media:$1|$1]]</strong> от [$4 $3, $2].",
        "apisandbox": "Песочница API",
        "apisandbox-jsonly": "Для использования API-песочницы требуется JavaScript.",
        "apisandbox-api-disabled": "API отключен на этом сайте.",
-       "apisandbox-intro": "Используйте эту страницу для экспериментов с <strong>MediaWiki API</strong>.\nОбратитесь к [[mw:API:Main page|документации API]] для получения дополнительной информации об использовании API. Например, о том, [https://www.mediawiki.org/wiki/API#A_simple_example как получить содержание Заглавной страницы]. Выберите действие, чтобы увидеть другие примеры.\nОбратите внимание, что, хотя это и песочница, действия, выполненные на этой странице, могут внести изменения в вики.",
+       "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": "Очистить",
        "apisandbox-retry": "Повторить",
        "apisandbox-continue": "Продолжить",
        "apisandbox-continue-clear": "Очистить",
        "apisandbox-continue-help": "{{int:apisandbox-continue}} [https://www.mediawiki.org/wiki/API:Query#Continuing_queries продолжит] последний запрос; {{int:apisandbox-continue-clear}} очистит связанные с продолжением параметры.",
-       "apisandbox-param-limit": "Введите <kbd>максимальное</kbd> использование максимального предела.",
+       "apisandbox-param-limit": "Введите <kbd>max</kbd> для использования максимального предела.",
        "apisandbox-multivalue-all-namespaces": "$1 (Все пространства имён)",
        "apisandbox-multivalue-all-values": "$1 (Все значения)",
        "booksources": "Источники книг",
        "speciallogtitlelabel": "Цель (название или {{ns:user}}:имя участника):",
        "log": "Журналы",
        "logeventslist-submit": "Показать",
+       "logeventslist-more-filters": "Показать дополнительные журналы:",
+       "logeventslist-patrol-log": "Журнал патрулирования",
+       "logeventslist-tag-log": "Журнал меток",
        "all-logs-page": "Все доступные журналы",
        "alllogstext": "Общий список журналов сайта {{SITENAME}}.\nВы можете отфильтровать результаты по типу журнала, имени участника (учитывается регистр) или затронутой странице (также учитывается регистр).",
        "logempty": "Подходящие записи в журнале отсутствуют.",
        "excontent": "содержимое: «$1»",
        "excontentauthor": "содержимое: «$1», единственным автором которого был [[Special:Contributions/$2|$2]] ([[User talk:$2|обсуждение]])",
        "exbeforeblank": "содержимое до очистки: «$1»",
-       "delete-confirm": "$1 — удаление",
+       "delete-confirm": "$1: удаление",
        "delete-legend": "Удаление",
        "historywarning": "<strong>Внимание:</strong> Вы собираетесь удалить страницу, у которой есть история правок, содержащая $1 {{PLURAL:$1|версию|версии|версий}}:",
        "historyaction-submit": "Показать",
        "dellogpage": "Журнал удалений",
        "dellogpagetext": "Ниже приведён журнал последних удалений.",
        "deletionlog": "журнал удалений",
+       "log-name-create": "Журнал создания страниц",
+       "log-description-create": "Ниже приведён список самых свежих созданий страниц.",
+       "logentry-create-create": "$1 {{GENDER:$2|создал|создала}} страницу $3",
        "reverted": "Откачено к ранней версии",
        "deletecomment": "Причина:",
        "deleteotherreason": "Другая причина/дополнение:",
        "editcomment": "Было дано описание изменения: <em>$1</em>.",
        "revertpage": "Откат правок [[Special:Contributions/$2|$2]] ([[User talk:$2|обсуждение]]) к версии [[User:$1|$1]]",
        "revertpage-nouser": "Откат правок (имя участника скрыто) к версии {{GENDER:$1|[[User:$1|$1]]}}",
-       "rollback-success": "Ð\9eÑ\82каÑ\82 Ð¿Ñ\80авок {{GENDER:$3|$1}}; Ð²Ð¾Ð·Ð²Ñ\80аÑ\82 Ðº Ð²ÐµÑ\80Ñ\81ии {{GENDER:$4|$2}}.",
-       "rollback-success-notify": "Ð\9eÑ\82каÑ\82 Ð¿Ñ\80авок $1; Ð²Ð¾Ð·Ð²Ñ\80аÑ\82 Ðº Ð²ÐµÑ\80Ñ\81ии $2. [$3 Показать изменения]",
+       "rollback-success": "Ð\9eÑ\82каÑ\87енÑ\8b Ð¿Ñ\80авки {{GENDER:$3|$1}}; Ð²Ð¾Ð·Ð²Ñ\80аÑ\89ена Ð¿Ð¾Ñ\81леднÑ\8fÑ\8f Ð²ÐµÑ\80Ñ\81иÑ\8f {{GENDER:$4|$2}}.",
+       "rollback-success-notify": "Ð\9eÑ\82каÑ\87енÑ\8b Ð¿Ñ\80авки $1; Ð²Ð¾Ð·Ð²Ñ\80аÑ\89ена Ð¿Ð¾Ñ\81леднÑ\8fÑ\8f Ð²ÐµÑ\80Ñ\81иÑ\8f $2. [$3 Показать изменения]",
        "sessionfailure-title": "Ошибка сеанса",
        "sessionfailure": "Похоже, возникли проблемы с текущим сеансом работы;\nэто действие было отменено в целях предотвращения «захвата сеанса».\nПожалуйста, переотправьте форму.",
        "changecontentmodel": "Редактирование контентной модели страницы",
        "anoncontribs": "Вклад",
        "contribsub2": "Вклад {{GENDER:$3|$1}} ($2)",
        "contributions-userdoesnotexist": "Не зарегистрировано учётной записи «$1».",
-       "nocontribs": "Ð\98зменений, Ñ\81ооÑ\82веÑ\82Ñ\81Ñ\82вÑ\83Ñ\8eÑ\89иÑ\85 Ð·Ð°Ð´Ð°Ð½Ð½Ñ\8bм Ñ\83Ñ\81ловиÑ\8fм, Ð½Ð°Ð¹Ð´ÐµÐ½Ð¾ Ð½Ðµ Ð±Ñ\8bло.",
+       "nocontribs": "Ð\98зменений, Ñ\81ооÑ\82веÑ\82Ñ\81Ñ\82вÑ\83Ñ\8eÑ\89иÑ\85 Ð·Ð°Ð´Ð°Ð½Ð½Ñ\8bм Ñ\83Ñ\81ловиÑ\8fм, Ð½Ðµ Ð½Ð°Ð¹Ð´ÐµÐ½о.",
        "uctop": "(текущая)",
        "month": "С месяца (и ранее):",
        "year": "С года (и ранее):",
+       "date": "С даты (и ранее):",
        "sp-contributions-newbies": "Показать только вклад, сделанный с новых учётных записей",
        "sp-contributions-newbies-sub": "С новых учётных записей",
        "sp-contributions-newbies-title": "Вклад с недавно созданных учётных записей",
        "whatlinkshere": "Ссылки сюда",
        "whatlinkshere-title": "Страницы, ссылающиеся на «$1»",
        "whatlinkshere-page": "Страница:",
-       "linkshere-2": "Следующие страницы ссылаются на «'''$1'''»:",
-       "nolinkshere-2": "На страницу '''$1''' отсутствуют ссылки с других страниц.",
-       "nolinkshere-ns-2": "В выбранном пространстве имён нет страниц, ссылающихся на '''$1'''.",
+       "linkshere": "Следующие страницы ссылаются на <strong>$2</strong>:",
+       "nolinkshere": "На страницу <strong>$2</strong> отсутствуют ссылки с других страниц.",
+       "nolinkshere-ns": "В выбранном пространстве имён нет страниц, ссылающихся на <strong>$2</strong>.",
        "isredirect": "страница-перенаправление",
        "istemplate": "включение",
        "isimage": "файловая ссылка",
        "ip_range_invalid": "Недопустимый диапазон IP-адресов.",
        "ip_range_toolarge": "Блокировки диапазонов свыше /$1 запрещены.",
        "ip_range_exceeded": "IP-диапазон превышает максимальный диапазон. Допустимый диапазон: /$1.",
-       "ip_range_toolow": "Ð\94иапазонÑ\8b IP Ð½Ðµ Ñ\80азÑ\80еÑ\88ены.",
+       "ip_range_toolow": "Ð\94иапазонÑ\8b IP Ð¿Ð¾ Ñ\81Ñ\83Ñ\82и Ð·Ð°Ð¿Ñ\80еÑ\89ены.",
        "proxyblocker": "Блокировка прокси",
        "proxyblockreason": "Ваш IP-адрес заблокирован потому, что это открытый прокси-сервер. Пожалуйста, свяжитесь со своиим интернет-провайдером или службой поддержки, и сообщите им об этой серьёзной проблеме безопасности.",
        "sorbs": "DNSBL",
        "movenosubpage": "У этой страницы нет подстраниц.",
        "movereason": "Причина:",
        "revertmove": "возврат",
-       "delete_and_move_text": "Страница с именем «[[:$1]]» уже существует. \nХотите удалить её, чтобы сделать возможным переименование?",
+       "delete_and_move_text": "ЦелеваÑ\8f Ñ\81траница с именем «[[:$1]]» уже существует. \nХотите удалить её, чтобы сделать возможным переименование?",
        "delete_and_move_confirm": "Да, удалить эту страницу",
        "delete_and_move_reason": "Удалено для возможности переименования «[[$1]]»",
        "selfmove": "Невозможно переименовать страницу: исходное и новое имя страницы совпадают.",
        "tooltip-ca-talk": "Обсуждение основной страницы",
        "tooltip-ca-edit": "Редактировать данную страницу",
        "tooltip-ca-addsection": "Создать новый раздел",
-       "tooltip-ca-viewsource": "Эта страница защищена от изменений, но вы можете посмотреть и скопировать её исходный текст",
+       "tooltip-ca-viewsource": "Эта страница защищена от изменений. Вы можете посмотреть  её исходный текст.",
        "tooltip-ca-history": "Журнал изменений страницы",
        "tooltip-ca-protect": "Защитить страницу от изменений",
        "tooltip-ca-unprotect": "Изменить защиту этой страницы",
        "markedaspatrollederrornotify": "Отметить изменение как проверенное не удалось.",
        "patrol-log-page": "Журнал патрулирования",
        "patrol-log-header": "Это журнал патрулированных версий.",
-       "log-show-hide-patrol": "$1 журнал патрулирования",
-       "log-show-hide-tag": "$1 журнал меток",
        "confirm-markpatrolled-button": "OK",
        "confirm-markpatrolled-top": "Пометить версию $3 страницы $2 как отпатрулированную?",
        "deletedrevision": "Удалена старая версия $1",
        "tag-mw-changed-redirect-target-description": "Правки, которые изменяют цель перенаправления",
        "tag-mw-blank": "очистка",
        "tag-mw-blank-description": "Правки, очищающие страницу",
-       "tag-mw-replace": "заменено",
+       "tag-mw-replace": "замена",
        "tag-mw-replace-description": "Правки, которые удаляют более 90 % содержимого страницы",
        "tag-mw-rollback": "откат",
        "tag-mw-rollback-description": "Правки, которые откатывают предыдущие правки по нажатию ссылки отката",
        "limitreport-expansiondepth-value": "$1/$2",
        "limitreport-expensivefunctioncount": "Количество «дорогих» функций анализатора",
        "limitreport-expensivefunctioncount-value": "$1/$2",
-       "limitreport-unstrip-depth": "Ð\93лÑ\83биннаÑ\8f Ñ\80екÑ\83Ñ\80Ñ\81иÑ\8f Unstrip",
+       "limitreport-unstrip-depth": "Ð\93лÑ\83бина Ñ\80екÑ\83Ñ\80Ñ\81ии Unstrip",
        "limitreport-unstrip-depth-value": "$1/$2",
-       "limitreport-unstrip-size": "Ð\9fоÑ\81ле Ñ\80аÑ\81Ñ\88иÑ\80ениÑ\8f Ñ\80азмеÑ\80 Unstrip",
+       "limitreport-unstrip-size": "РазмеÑ\80 Unstrip Ð¿Ð¾Ñ\81ле Ñ\80аÑ\81кÑ\80Ñ\8bÑ\82иÑ\8f Ð²ÐºÐ»Ñ\8eÑ\87ений",
        "limitreport-unstrip-size-value": "$1/$2 {{PLURAL:$2|байт|байта|байт}}",
        "expandtemplates": "Развёртка шаблонов",
        "expand_templates_intro": "Эта служебная страница преобразует текст, рекурсивно разворачивая все шаблоны в нём.\nТакже развёртке подвергаются функции парсера\n<code><nowiki>{{#language:…}}</nowiki></code> и переменные вида\n<code><nowiki>{{CURRENTDAY}}</nowiki></code> — в общем, всё внутри двойных фигурных скобок.",
        "passwordpolicies-policy-passwordcannotmatchusername": "Пароль не может совпадать с названием учётной записи",
        "passwordpolicies-policy-passwordcannotmatchblacklist": "Пароль не может совпадать ни с одним паролем, внесённым в чёрный список",
        "passwordpolicies-policy-maximalpasswordlength": "Пароль должен быть короче $1 {{PLURAL:$1|символа|символов}}",
-       "passwordpolicies-policy-passwordcannotbepopular": "Пароль не может соответствовать {{PLURAL:$1|самому часто используемому паролю|какому-либо из $1 самых часто используемых паролей}}"
+       "passwordpolicies-policy-passwordcannotbepopular": "Пароль не может соответствовать {{PLURAL:$1|самому часто используемому паролю|какому-либо из $1 самых часто используемых паролей}}",
+       "easydeflate-invaliddeflate": "Предоставленное содержимое не спущено надлежащим образом"
 }
index 0b1f038..591f262 100644 (file)
@@ -14,7 +14,8 @@
                        "Matma Rex",
                        "KHMELNYTSKYIA",
                        "Igor Kercsa",
-                       "Fitoschido"
+                       "Fitoschido",
+                       "Vlad5250"
                ]
        },
        "tog-underline": "Підкреслёвати одказы:",
        "right-editsemiprotected": "Едітованя сторінок замкнутых на „{{int:protect-level-autoconfirmed}}“",
        "right-editinterface": "Едітованя інтерфейсу хоснователя",
        "right-editusercss": "Едітованя CSS файлів іншых хоснователїв",
+       "right-edituserjson": "Едітованя JSON файлів іншых хоснователїв",
        "right-edituserjs": "Едітованя JS файлів іншых хоснователїв",
        "right-editmyusercss": "Едітовати вашы властны хосновательскы CSS файлы.",
+       "right-editmyuserjson": "Едітовати вашы властны хосновательскы JSON файлы",
        "right-editmyuserjs": "Едітовати вашы властны хосновательскы JavaScript файлы",
        "right-viewmywatchlist": "Перезераня властного списку слїдованых сторінок",
        "right-editmywatchlist": "Едітованя властного списку слїдованых сторінок. Усвідомте собі, же дакотры дїї будуть до нёго придавати сторінкы і без такого права.",
        "whatlinkshere": "Одказы на тоту сторінку",
        "whatlinkshere-title": "Сторінкы, што ся одказують на \"$1\"",
        "whatlinkshere-page": "Сторінка:",
-       "linkshere-2": "Наслїдуючі сторінкы ся одказують на '''$1''':",
-       "nolinkshere-2": "Жадна сторінка на '''$1''' не одказує.",
-       "nolinkshere-ns-2": "У выбранім просторї назв на '''$1''' не одказує жадна сторінка.",
+       "linkshere": "Наслїдуючі сторінкы ся одказують на '''$2''':",
+       "nolinkshere": "Жадна сторінка на '''$2''' не одказує.",
+       "nolinkshere-ns": "У выбранім просторї назв на '''$2''' не одказує жадна сторінка.",
        "isredirect": "сторінка напрямлена",
        "istemplate": "вложіня",
        "isimage": "Одказ на файл",
        "markedaspatrollederrornotify": "Не вдало ся поставити позначку про патролёваня",
        "patrol-log-page": "Книга перевіреных едітовань",
        "patrol-log-header": "Тото є книга перевіреных верзій.",
-       "log-show-hide-patrol": "$1 книгу записів патролованя",
        "deletedrevision": "Змазана стара ревізія $1",
        "filedeleteerror-short": "Хыба мазаня файлу: $1",
        "filedeleteerror-long": "Выникла хыба під час мазаня файлу:\n\n$1",
index 6b9a08a..6ce1512 100644 (file)
@@ -24,7 +24,8 @@
                        "Macofe",
                        "Matma Rex",
                        "రహ్మానుద్దీన్",
-                       "Fitoschido"
+                       "Fitoschido",
+                       "Charunandan16"
                ]
        },
        "tog-underline": "परिसन्धेः अधो रेखाङ्कनम्:",
        "dellogpage": "अपाकरणानाम् आवलिः",
        "dellogpagetext": "सद्यः कालीनापमर्जितपुटानाम् आवली अधः अस्ति ।",
        "deletionlog": "अपमर्जनसूचिका ।",
+       "log-description-create": "नवीनतमानां पृष्ठरचनानाम् इयम् आवली",
        "reverted": "प्राचीनपुनरावृत्तिः पूर्ववत् कृता ।",
        "deletecomment": "कारणम् :",
        "deleteotherreason": "अपरं/अतिरिक्तं कारणम् :",
        "whatlinkshere": "अनेन सह सम्बद्धाः",
        "whatlinkshere-title": "\"$1\" सम्बद्धानि पृष्ठानि",
        "whatlinkshere-page": "पृष्ठम्:",
-       "linkshere-2": "'''$1''' इत्यनेन सह अधो लिखितानां पृष्ठानां परिसन्धिं करोतु:",
-       "nolinkshere-2": "'''$1''' इत्यनेन सह न किमपि पृष्ठं परिसन्धितम्",
-       "nolinkshere-ns-2": "चितनामस्थानात्  '''$1''' इत्येनं योजनयोग्यं पृष्ठं नास्ति  ।",
+       "linkshere": "'''$2''' इत्यनेन सह अधो लिखितानां पृष्ठानां परिसन्धिं करोतु:",
+       "nolinkshere": "'''$2''' इत्यनेन सह न किमपि पृष्ठं परिसन्धितम्",
+       "nolinkshere-ns": "चितनामस्थानात्  '''$2''' इत्येनं योजनयोग्यं पृष्ठं नास्ति  ।",
        "isredirect": "अनुप्रेषण-पृष्ठम्",
        "istemplate": "अन्यलेखभागः (transclusion)",
        "isimage": "सञ्चिकासम्बन्धः",
        "markedaspatrollederrornotify": "समीक्षितम् इति चिह्नीकरणं विफलम्।",
        "patrol-log-page": "निरीक्षिता संरक्षितावलिः",
        "patrol-log-header": "इयम् आरक्षितपुनरावृत्तीनां सूचिका अस्ति ।",
-       "log-show-hide-patrol": "$1 इत्यनेन निरीक्षिता संरक्षितावलिः",
-       "log-show-hide-tag": "$1 चिह्नाऽऽवलिः",
        "deletedrevision": "अपमर्जितप्राचीनपुनरावृत्तिः $1",
        "filedeleteerror-short": "सञ्चिकानपमर्जने दोषः : $1",
        "filedeleteerror-long": " सञ्चिकानामपमर्जने आगता समस्या  $1",
index 3dc7eb0..0bad36e 100644 (file)
        "listfiles_size": "Кээмэйэ",
        "listfiles_description": "Быһаарыыта",
        "listfiles_count": "Барыллар",
-       "listfiles-show-all": "Ð\91илÑ\8d Ñ\8dÑ\80гÑ\8d Ñ\82оÑ\80Ñ\83мнаÑ\80Ñ\8bн Ñ\8dмиÑ\8d ÐºÐ¸Ð»Ð»Ñ\8dр",
+       "listfiles-show-all": "Ð\91илÑ\8d Ñ\85ойÑ\83ккÑ\83 Ñ\82оÑ\80Ñ\83мнаÑ\80Ñ\8bн Ñ\8dмиÑ\8d ÐºÓ©Ñ\80дөр",
        "listfiles-latestversion": "Билиҥҥи барыла",
        "listfiles-latestversion-yes": "Сөп",
        "listfiles-latestversion-no": "Суох",
        "whatlinkshere": "Манна сигэнэллэр",
        "whatlinkshere-title": "Сирэй манна сигэнэр \"$1\"",
        "whatlinkshere-page": "Сирэй:",
-       "linkshere-2": "'''$1''' билэҕэ манна көрдөрүллүбүт сирэйдэр сигэнэллэр:",
-       "nolinkshere-2": "'''$1''' сирэйгэ сигэнэр сирэйдэр суохтар.",
-       "nolinkshere-ns-2": "Талыллыбыт бөлөххө (namespace) бу '''$1''' сирэйгэ сигэнэр сирэйдэр суохтар.",
+       "linkshere": "'''$2''' билэҕэ манна көрдөрүллүбүт сирэйдэр сигэнэллэр:",
+       "nolinkshere": "'''$2''' сирэйгэ сигэнэр сирэйдэр суохтар.",
+       "nolinkshere-ns": "Талыллыбыт бөлөххө (namespace) бу '''$2''' сирэйгэ сигэнэр сирэйдэр суохтар.",
        "isredirect": "көлбөрүтэр сирэй",
        "istemplate": "иһинээҕи",
        "isimage": "билэ сигэтэ",
        "markedaspatrollederrornotify": "Бэлиэтэммит курдук бэлиэтиир сатаммата.",
        "patrol-log-page": "Бэрэбиэркэ сурунаала",
        "patrol-log-header": "Ботуруулламмыт торумнар сурунааллара.",
-       "log-show-hide-patrol": "$1 ботурууллааһын сурунаала",
-       "log-show-hide-tag": "$1 тиэк сурунаала",
        "confirm-markpatrolled-button": "Сөп",
        "confirm-markpatrolled-top": "$2 сирэй $3 торумун ботуруулламмыт курдук бэлиэтиигин дуо?",
        "deletedrevision": "$1 урукку торума сотулунна",
index 16618df..282761a 100644 (file)
@@ -35,6 +35,8 @@
        "tog-watchdefault": "ᱤᱧᱟᱜ ᱥᱟᱯᱲᱟᱣ ᱧᱮᱞᱚᱜ ᱛᱟᱹᱞᱠᱟᱹᱨᱮ ᱥᱟᱦᱴᱟᱠᱩ ᱟᱨ ᱨᱮᱫᱠᱩ ᱥᱮᱞᱮᱫ ᱢᱮ",
        "tog-watchmoves": "ᱤᱧᱟᱜ ᱥᱟᱯᱲᱟᱣ ᱧᱮᱞᱚᱜ ᱛᱟᱹᱞᱠᱟᱹᱨᱮ ᱥᱟᱦᱴᱟᱠᱩ ᱟᱨ ᱨᱮᱫᱠᱩ ᱚᱪᱟᱜᱽ ᱢᱮ",
        "tog-watchdeletion": "ᱤᱧᱟᱜ ᱥᱟᱯᱲᱟᱣ ᱧᱮᱞᱚᱜ ᱛᱟᱹᱞᱠᱟᱹᱨᱮ ᱥᱟᱦᱴᱟᱠᱩ ᱟᱨ ᱨᱮᱫᱠᱩ ᱜᱮᱫ ᱜᱤᱰᱤᱭ ᱢᱮ",
+       "tog-watchuploads": "ᱱᱟᱶᱟ ᱨᱮᱫ ᱥᱮᱞᱮᱫᱽᱢᱮ ᱤᱧᱟᱜ ᱧᱮᱞ ᱞᱤᱥᱴᱤ ᱨᱤᱧ ᱞᱟᱫᱮᱭᱟ",
+       "tog-watchrollback": "ᱥᱟᱦᱴᱟ ᱥᱮᱞᱮᱫᱽᱢᱮ ᱡᱟᱦᱟᱸᱨᱮ ᱤᱧᱟᱜ ᱧᱮᱞ ᱞᱤᱥᱴᱤᱧ ᱟᱹᱪᱩᱨ ᱨᱩᱣᱟᱹᱲ ᱟᱠᱟᱫᱼᱟ",
        "tog-minordefault": "ᱮᱛᱦᱚᱵᱨᱮ ᱥᱟᱱᱟᱢ ᱥᱟᱯᱲᱟᱣᱠᱩ ᱦᱩᱰᱤᱧ ᱞᱮᱠᱟᱛᱮ ᱪᱤᱱᱦᱟᱹ ᱠᱟᱜ ᱢᱮ",
        "tog-previewontop": "ᱥᱟᱯᱲᱟᱣ ᱵᱟᱠᱥᱳ ᱞᱟᱦᱟᱨᱮ ᱩᱱᱩᱫᱩᱜ ᱩᱫᱩᱜᱽ ᱢᱮ",
        "tog-previewonfirst": "ᱯᱟᱹᱦᱤᱞ ᱥᱟᱯᱲᱟᱣ ᱨᱮ ᱩᱱᱩᱫᱩᱜ ᱩᱫᱩᱜᱽ ᱢᱮ",
        "october-date": "ᱚᱠᱴᱚᱵᱚᱨ $1",
        "november-date": "ᱱᱚᱵᱷᱮᱢᱵᱚᱨ $1",
        "december-date": "ᱰᱤᱥᱮᱢᱵᱚᱨ $1",
+       "period-am": "ᱮᱹᱮᱢ",
+       "period-pm": "ᱯᱤᱹᱮᱢ",
        "pagecategories": "{{PLURAL:$1|ᱛᱷᱚᱠ|ᱛᱷᱚᱠᱠᱩ}}",
        "category_header": "ᱛᱷᱚᱠ ᱨᱮᱱ ᱥᱟᱦᱴᱟᱞᱩ \"$1\"",
        "subcategories": "ᱦᱩᱰᱤᱧ ᱛᱷᱚᱠᱠᱩ",
        "talk": "ᱜᱟᱞᱢᱟᱨᱟᱣ",
        "views": "ᱧᱮᱞᱚᱜᱚᱜ",
        "toolbox": "ᱦᱟᱹᱛᱭᱟᱹᱨ",
+       "tool-link-userrights": "{{GENDER:$1|ᱵᱮᱵᱷᱟᱨᱤᱭᱟᱹ}} ᱜᱟᱫᱮᱞ ᱵᱚᱫᱚᱞ",
+       "tool-link-userrights-readonly": "{{GENDER:$1|ᱵᱮᱵᱷᱟᱨᱤᱭᱟᱹ}} ᱜᱟᱫᱮᱞ ᱧᱮᱞ",
+       "tool-link-emailuser": "ᱤᱢᱮᱞᱟᱭᱢᱮ ᱱᱩᱭ {{GENDER:$1|ᱵᱮᱵᱷᱟᱨᱤᱭᱟᱹ}}",
        "imagepage": "ᱨᱮᱫ ᱥᱟᱦᱴᱟ ᱧᱮᱞᱢᱮ",
        "mediawikipage": "ᱠᱷᱚᱵᱚᱨ ᱥᱟᱦᱴᱟ ᱧᱮᱞᱢᱮ",
        "templatepage": "ᱪᱷᱟᱸᱪ ᱥᱟᱦᱴᱟ ᱩᱫᱩᱜᱽ ᱢᱮ",
        "jumpto": "ᱫᱚᱱᱢᱮ :",
        "jumptonavigation": "ᱟᱹᱪᱩᱨᱵᱟᱲᱟ",
        "jumptosearch": "ᱥᱮᱸᱫᱽᱨᱟ",
-       "view-pool-error": "Ikạkańmẽ, sarvarre nitoḱ do aḍi cap menaḱa.\nẠḍi aema beoharko noa sakam ńel lạgit́ko kurumuṭueda.\nNãwate noa sakam ńel kurumuṭuy lạgit́te dayakate mit́ghạṛi tạṅgiymẽ.\n$1",
-       "pool-timeout": "Somoy paromena cạbi lạgit́te tạṅgi hoyoḱkana",
-       "pool-queuefull": "Pool queue is full",
+       "view-pool-error": "ᱤᱠᱟᱹᱠᱟᱹᱧᱢᱮ, ᱥᱟᱨᱵᱷᱟᱨ ᱨᱮ ᱱᱮᱛᱚᱜ ᱫᱚ ᱟᱹᱰᱤ ᱪᱟᱯ ᱢᱮᱱᱟᱜ-ᱟ᱾\nᱟᱹᱰᱤ ᱟᱭᱢᱟ ᱵᱮᱵᱷᱟᱨᱤᱭᱟᱹᱠᱩ ᱱᱚᱣᱟ ᱥᱟᱦᱴᱟ ᱧᱮᱞ ᱞᱟᱹᱜᱤᱛᱠᱩ ᱠᱩᱨᱩᱢᱩᱴᱩᱭᱮᱫᱟ᱾\nᱱᱟᱣᱟᱛᱮ ᱱᱚᱣᱟ ᱥᱟᱦᱴᱟ ᱧᱮᱞ ᱠᱩᱨᱩᱢᱩᱴᱩ ᱞᱟᱹᱜᱤᱛᱛᱮ ᱫᱟᱭᱟᱠᱟᱛᱮ ᱢᱤᱫᱜᱷᱟᱹᱲᱤ ᱛᱟᱺᱜᱤᱭᱢᱮ᱾\n\n$1",
+       "generic-pool-error": "ᱤᱠᱟᱹᱠᱟᱹᱧᱢᱮ, ᱱᱚᱶᱟ ᱥᱚᱨᱵᱷᱚᱨ ᱨᱮ ᱱᱤᱛ ᱟᱹᱰᱤᱜᱟᱱ ᱪᱟᱯ ᱢᱮᱱᱟᱜᱼᱟ ᱾\nᱟᱹᱰᱤ ᱟᱭᱢᱟ ᱵᱮᱵᱷᱟᱨᱤᱭᱟᱹ ᱱᱚᱶᱟ ᱥᱟᱠᱟᱢ ᱧᱮᱞ ᱞᱟᱹᱜᱤᱫ ᱠᱚ ᱨᱤᱠᱟᱹᱭᱮᱫᱼᱟ ᱾\nᱱᱚᱶᱟ ᱥᱟᱠᱟᱢ ᱧᱮᱞ ᱞᱟᱹᱜᱤᱰ ᱱᱟᱥᱮ ᱛᱟᱺᱜᱤ ᱢᱮ ᱾",
+       "pool-timeout": "ᱚᱠᱛᱚ ᱯᱟᱨᱚᱢᱮᱱᱟ ᱪᱟᱹᱵᱤ ᱞᱟᱹᱜᱤᱛᱛᱮ ᱛᱟᱸᱜᱤ ᱦᱩᱭᱩᱜ ᱠᱟᱱᱟ",
+       "pool-queuefull": "Pool queue ᱫᱚ ᱯᱮᱨᱮᱡᱽ ᱟᱠᱟᱱᱟ",
        "pool-errorunknown": "ᱵᱟᱝ ᱵᱟᱰᱟᱭ ᱦᱩᱲᱟᱹᱜ",
+       "poolcounter-usage-error": "ᱵᱮᱵᱷᱟᱨᱟᱜ ᱦᱩᱲᱟᱹᱜᱺ $1",
        "aboutsite": "{{SITENAME}} ᱵᱟᱵᱚᱛ",
        "aboutpage": "Project: ᱵᱟᱵᱚᱛ",
        "copyright": "ᱩᱱᱩᱫᱩᱜ ᱫᱚ ᱧᱟᱢᱚᱜ-ᱟ $1 ᱞᱮᱠᱟᱛᱮ  ᱵᱟᱝᱠᱷᱟᱱ ᱚᱞ ᱛᱟᱦᱮᱱᱟ",
        "privacy": "ᱩᱠᱩ ᱮᱠᱛᱤᱭᱟᱨ",
        "privacypage": "Project: ᱩᱠᱩ ᱮᱠᱛᱤᱭᱟᱨ",
        "badaccess": "ᱟᱹᱭᱫᱟᱹᱨᱤ ᱦᱩᱲᱟᱹᱜ",
-       "badaccess-group0": "Am do oka kạmi lạgit́em aroj akat́, ona kạmi purạo lạgit́te ạidạri do bạnuḱa.",
-       "badaccess-groups": "Am do oka kạmim menjoṅkan ona do khạli {{PLURAL:$2 rạsiạkore noa rạsiạreaḱ mit́ṭenre}} mitṭen beoharić sompadon daṛeyaḱa: $1.",
+       "badaccess-group0": "ᱟᱢ ᱫᱚ ᱚᱠᱟ ᱠᱟᱹᱢᱤ ᱞᱟᱹᱜᱤᱛ ᱮᱢ ᱟᱨᱚᱡᱽ ᱟᱠᱟᱛ, ᱚᱱᱟ ᱠᱟᱹᱢᱤ ᱯᱩᱨᱟᱹᱣ ᱞᱟᱹᱜᱤᱛᱛᱮ ᱟᱹᱭᱫᱟᱹᱨᱤ ᱫᱚ ᱵᱟᱹᱱᱩᱜ-ᱟ᱾",
+       "badaccess-groups": "ᱟᱢ ᱫᱚ ᱚᱠᱟ ᱠᱟᱹᱢᱤᱢ ᱢᱮᱱᱡᱚᱝᱠᱟᱱ ᱚᱱᱟ ᱫᱚ ᱠᱷᱟᱹᱞᱤ {{PLURAL:$2 ᱨᱟᱹᱥᱤᱭᱟᱹᱠᱚᱨᱮ ᱱᱚᱣᱟ ᱨᱟᱹᱥᱤᱭᱟᱹ ᱨᱮᱭᱟᱜ ᱢᱤᱫᱴᱮᱱ ᱨᱮ}} ᱢᱤᱫᱴᱮᱱ ᱵᱮᱵᱷᱟᱨᱤᱡ ᱥᱟᱯᱲᱟᱣ ᱫᱟᱲᱮᱭᱟᱜ-ᱟ: $1᱾",
        "versionrequired": "ᱢᱤᱰᱤᱭᱟ ᱩᱭᱠᱤ ᱨᱮᱭᱟᱜ $1 ᱱᱟᱣᱟ ᱵᱷᱟᱨᱥᱚᱱ ᱡᱟᱹᱨᱩᱲᱟ",
-       "versionrequiredtext": "Version $1 of MediaWiki is required to use this page.\nSee [[Special:Version|version page]].",
+       "versionrequiredtext": "Version $1 of ᱢᱤᱰᱤᱭᱟ ᱣᱤᱠᱤ ᱫᱚ ᱱᱚᱣᱟ ᱥᱟᱦᱴᱟ ᱵᱮᱵᱷᱟᱨ ᱞᱟᱜᱟᱣᱭᱟ᱾\nᱧᱮᱞᱢᱮ [[Special:Version|version page]]᱾",
        "ok": "ᱴᱷᱤᱠ ᱜᱮᱭᱟ",
        "retrievedfrom": "\"$1\" ᱠᱷᱚᱱ ᱧᱟᱢ ᱟᱹᱜᱩᱭ",
        "youhavenewmessages": "{{PLURAL:$3|ᱟᱢᱟᱜ ᱢᱮᱱᱟᱜ-ᱟ}} $1 ($2)᱾",
        "youhavenewmessagesfromusers": "{{PLURAL:$4|ᱟᱢ ᱫᱚ}} $1 ᱠᱷᱚᱱ {{PLURAL:$3|ᱟᱨᱢᱤᱫ ᱵᱮᱵᱷᱟᱨᱤᱭᱟᱹ|$3 ᱵᱷᱮᱵᱷᱟᱨᱩᱭᱟᱹ}} ($2) ᱾",
+       "youhavenewmessagesmanyusers": "ᱟᱭᱢᱟ ᱵᱮᱵᱦᱟᱨᱤᱭᱟᱹ ($2) ᱠᱷᱚᱱ ᱟᱢ ᱫᱚ $1",
        "newmessageslinkplural": "{{PLURAL:$1|ᱢᱤᱫ ᱱᱟᱶᱟ ᱢᱮᱥᱮᱡᱽ|999=ᱱᱟᱶᱟ ᱢᱮᱥᱮᱡᱽᱠᱚ}}",
        "newmessagesdifflinkplural": "ᱢᱩᱪᱟᱹᱫ {{PLURAL:$1|ᱵᱚᱫᱚᱞ|999=ᱵᱚᱫᱚᱞᱠᱚ}}",
        "youhavenewmessagesmulti": "ᱟᱢᱟᱜ ᱱᱟᱣᱟ ᱠᱷᱚᱵᱟᱨᱠᱚ ᱫᱚ $1 ᱨᱮ ᱢᱮᱱᱟᱜ-ᱟ",
        "hidetoc": "ᱫᱟᱱᱟᱝ",
        "collapsible-collapse": "ᱢᱩᱨᱪᱷᱟᱹᱣ ᱪᱟᱵᱟ",
        "collapsible-expand": "ᱯᱷᱟᱭᱞᱟᱣ",
+       "confirmable-confirm": "{{GENDER:$1|ᱟᱢ}} ᱴᱷᱟᱹᱣᱠᱟᱹ ᱭᱮᱜ-ᱟᱢ?",
        "confirmable-yes": "ᱦᱮᱸ",
        "confirmable-no": "ᱵᱟᱝ",
        "thisisdeleted": "ᱧᱮᱞ ᱥᱮ ᱨᱩᱭᱟᱹᱲ ᱫᱚᱲᱦᱟ $1?",
        "viewdeleted": "$1 ᱧᱮᱞᱢᱮ",
-       "restorelink": "{{PLURAL:$1 mit́ṭen ocoḱgiḍi sompadon $1 gan udug giḍi sompadon}}",
+       "restorelink": "{{PLURAL:$1 ᱢᱤᱫᱴᱮᱱ ᱚᱪᱚᱜ ᱜᱤᱰᱤ ᱥᱟᱯᱲᱟᱣ $1 ᱜᱟᱱ ᱩᱫᱩᱜᱽ ᱜᱤᱰᱤ ᱥᱟᱯᱲᱟᱣ}}",
        "feedlinks": "ᱟᱡᱚ:",
-       "feed-invalid": "Garhak feed reaḱ rokom do ạnlekate baṅkana",
+       "feed-invalid": "ᱜᱟᱨᱦᱟᱠ feed ᱨᱮᱭᱟᱜ ᱨᱚᱠᱚᱢ ᱫᱚ ᱚᱝᱞᱮᱠᱟᱛᱮ ᱵᱟᱝᱠᱟᱱᱟ᱾",
        "feed-unavailable": "ᱥᱤᱱᱰᱤᱠᱮᱥᱚᱱ ᱟᱡᱚ ᱠᱩᱫᱚ ᱵᱟᱝ ᱧᱟᱢᱚᱜ ᱠᱟᱱᱟ",
        "site-rss-feed": "$1 RSS feed",
        "site-atom-feed": " $1 ᱡᱚᱢ ᱚᱪᱚ",
        "page-rss-feed": "\"$1\" RSS feed",
        "page-atom-feed": " $1 ᱡᱚᱢ ᱚᱪᱚ",
        "red-link-title": "$1 (ᱱᱤᱭᱟᱹ ᱥᱟᱦᱴᱟ ᱫᱚ ᱵᱟᱹᱱᱩᱜ-ᱟ)",
-       "sort-descending": "Ulṭạo horop lekate sajao",
+       "sort-descending": "ᱩᱞᱴᱟᱹᱣᱛᱮ ᱥᱟᱡᱟᱣ",
        "sort-ascending": "ᱥᱟᱢᱴᱟᱣ ᱛᱮ",
        "nstab-main": "ᱥᱟᱦᱴᱟ",
        "nstab-user": "ᱵᱮᱵᱦᱟᱹᱨᱤᱭᱟᱹᱜ ᱥᱟᱦᱴᱟ",
        "nstab-category": "ᱛᱷᱚᱠ",
        "mainpage-nstab": "ᱢᱩᱬᱩᱛ ᱥᱟᱦᱴᱟ",
        "nosuchaction": "ᱱᱚᱝᱠᱟᱱ ᱠᱟᱹᱢᱤ ᱵᱟᱹᱱᱩᱜ-ᱟ",
-       "nosuchactiontext": "Noa URL re goṭa akan kạmi do ạnlekate baṅkana.\nAm do paseć mit́ṭen vul joṛaoem emakada se URL oltem vul akada.\nNoa do noṅkanaḱ menkana je {{SITENAME}} sayeṭre beoharen sofṭower re mit́ṭen vul menaḱa.",
+       "nosuchactiontext": "ᱱᱚᱣᱟ URL ᱨᱮ ᱜᱚᱴᱟ ᱟᱠᱟᱱ ᱠᱟᱹᱢᱤ ᱫᱚ ᱟᱹᱱᱞᱮᱠᱟᱛᱮ ᱵᱟᱝᱠᱟᱱᱟ᱾\nᱟᱢ ᱫᱚ ᱯᱟᱥᱮᱡ ᱢᱤᱫᱴᱮᱱ ᱵᱷᱩᱞ ᱡᱚᱱᱚᱲᱮᱢ ᱮᱢᱠᱟᱫᱟ ᱥᱮ URL ᱚᱞᱛᱮᱢ ᱵᱷᱩᱞ ᱟᱠᱟᱫᱟ᱾\nᱱᱚᱣᱟ ᱫᱚ ᱱᱚᱝᱠᱟᱱᱟᱜ ᱢᱮᱱᱠᱟᱱᱟ ᱡᱮ {{SITENAME}} ᱥᱟᱭᱮᱴᱨᱮ ᱵᱮᱵᱷᱟᱨᱮᱱ ᱥᱚᱯᱷᱴᱚᱭᱟᱨ ᱨᱮ ᱢᱤᱫᱴᱮᱱ ᱵᱷᱩᱞ ᱢᱮᱱᱟᱜ-ᱟ᱾",
        "nosuchspecialpage": "ᱱᱚᱝᱠᱟᱱᱟ ᱟᱥᱚᱠᱟᱭ ᱥᱟᱦᱴᱟ ᱫᱚ ᱵᱟᱹᱱᱩᱜ-ᱟ",
        "nospecialpagetext": "<strong>ᱟᱢ ᱫᱚ ᱡᱟᱦᱟᱸ ᱥᱟᱦᱴᱟ ᱞᱟᱹᱜᱤᱫ ᱮᱢ ᱱᱮᱦᱚᱨ ᱟᱠᱟᱫᱟ ᱚᱱᱟᱫᱚ ᱵᱟᱹᱱᱩᱜ-ᱟ </strong>\nᱡᱟᱦᱟᱸ ᱥᱟᱦᱴᱟᱠᱩ ᱱᱚᱸᱰᱮ ᱢᱮᱱᱟᱜ-ᱟ ᱚᱱᱟᱨᱮᱱᱟᱜ ᱛᱟᱹᱞᱠᱟᱹ ᱱᱚᱸᱰᱮᱢ ᱧᱟᱢᱟ [[Special:SpecialPages|{{int:specialpages}}]]᱾",
        "error": "ᱦᱩᱲᱟᱹᱜ",
        "databaseerror": "ᱰᱟᱴᱟᱵᱮᱡᱽ ᱦᱩᱲᱟᱹᱜ",
+       "databaseerror-query": "ᱠᱩᱠᱞᱤ: $1",
+       "databaseerror-function": "ᱠᱟᱹᱢᱤ: $1",
        "databaseerror-error": "ᱦᱩᱲᱟᱹᱜ: $1",
-       "laggedslavemode": "'''Sontoroḱme:''' sakamre do nahaḱ nãwãnaḱko paseć bạnuḱa.",
+       "laggedslavemode": "<strong>'''ᱥᱚᱱᱛᱚᱨᱚᱜᱢᱮ:</strong>''' ᱥᱟᱦᱴᱟᱨᱮ ᱫᱚ ᱱᱟᱦᱟᱜ ᱱᱟᱣᱟᱱᱟᱜᱠᱩ ᱯᱟᱥᱮᱡ ᱵᱟᱹᱱᱩᱜ-ᱟ᱾",
        "readonly": "ᱰᱟᱴᱟᱵᱮᱡᱽ ᱛᱟᱞᱟᱜᱮᱭᱟ",
-       "enterlockreason": "Cạbie reaḱ karon do cet́kana ma lạimẽ, Saõte tinre tala cạbim jhija ona okte hõ lạimẽ",
+       "enterlockreason": "ᱪᱟᱹᱵᱤ ᱨᱮᱭᱟᱜ ᱠᱟᱨᱚᱱ ᱫᱚ ᱪᱮᱫᱠᱟᱱᱟ ᱢᱟ ᱞᱟᱹᱭᱢᱮ, ᱥᱟᱶᱛᱮ ᱛᱤᱱᱨᱮ ᱛᱟᱞᱟᱢ ᱡᱷᱤᱡᱟ ᱚᱱᱟ ᱚᱠᱛᱮ ᱦᱚᱸ ᱞᱟᱹᱭᱢᱮ",
        "readonlytext": "ᱱᱟᱣᱟ ᱦᱟᱹᱴᱤᱧ ᱟᱨ ᱮᱴᱟᱜᱟᱜ ᱥᱟᱯᱲᱟᱣ ᱞᱟᱹᱜᱤᱛᱛᱮ ᱰᱟᱴᱟᱵᱮᱡᱽ ᱫᱚ ᱱᱤᱛ ᱵᱚᱱᱰᱷᱚ ᱜᱮᱭᱟ᱾ ᱯᱟᱥᱮᱡ ᱰᱟᱴᱟᱵᱮᱡ ᱨᱩᱠᱷᱤᱭᱟᱨᱮ ᱱᱤᱭᱚᱢ ᱞᱮᱠᱟᱛᱮ ᱠᱟᱹᱢᱤ ᱪᱟᱞᱟᱜ ᱠᱟᱱᱟ᱾ ᱛᱷᱚᱲᱟ ᱜᱷᱟᱹᱲᱤᱡ ᱯᱚᱨ ᱞᱟᱦᱟᱛᱮ ᱞᱮᱠᱟ ᱟᱹᱪᱩᱨ ᱦᱟᱹᱡᱩᱜ-ᱟ᱾\nᱥᱟᱥᱮᱛᱤᱪ ᱫᱚ ᱱᱚᱣᱟ ᱠᱟᱛᱷᱟᱭ ᱨᱚᱲ ᱠᱮᱫᱟ: $1",
-       "missing-article": "\"$1\" $2 noa ńutumanaḱ sakhiyạ̣t sakamre olakanaḱ do bań ṅamoka.\nNoa hoy renaḱ karon do hoyoḱkana cabak tạrik pharak se noare joṛao sakam do get́ giḍi akana.\nJudi noa do karon bań hoylen khan, noa do am sopṭoyer re kạtićtem ńam daṛeyaḱa.\nDaya katet́ noa do nonde [[Special:ListUsers/sysop|administrator]],  ṭhen lạime, URL hotete.",
+       "missing-article": "\"$1\" $2 ᱱᱚᱣᱟ ᱧᱩᱛᱩᱢᱟᱱᱟᱜ ᱥᱟᱹᱠᱷᱭᱟᱹᱛ ᱥᱟᱦᱴᱟᱨᱮ ᱚᱞ ᱟᱠᱟᱱᱟᱜ ᱫᱚ ᱵᱟᱝ ᱧᱟᱢᱚG-ᱟ᱾\nᱱᱚᱣᱟ ᱦᱩᱭ ᱨᱮᱱᱟᱜ ᱠᱟᱨᱚᱱ ᱫᱚ ᱦᱩᱭᱩᱜᱠᱟᱱᱟ ᱪᱟᱵᱟᱜ ᱛᱟᱹᱨᱤᱠ ᱯᱷᱟᱨᱟᱠ ᱥᱮ ᱱᱚᱣᱟᱨᱮ ᱡᱚᱱᱚᱲ ᱥᱟᱦᱴᱟ ᱫᱚ ᱜᱮᱫ ᱜᱤᱰᱤ ᱟᱠᱟᱱᱟ᱾\nᱡᱩᱫᱤ ᱱᱚᱣᱟ ᱫᱚ ᱠᱟᱨᱚᱱ ᱵᱟᱝ ᱦᱩᱭᱞᱮᱱ ᱠᱷᱟᱱ, ᱱᱚᱣᱟ ᱫᱚ ᱟᱢ ᱥᱚᱯᱷᱴᱚᱭᱟᱨ ᱨᱮ ᱠᱟᱹᱴᱤᱡᱛᱮᱢ ᱧᱟᱢ ᱫᱟᱲᱮᱭᱟᱜ-ᱟ᱾\nᱫᱟᱭᱟᱠᱟᱛᱮ ᱱᱚᱣᱟ ᱫᱚ ᱱᱚᱸᱰᱮ [[Special:ListUsers/sysop|administrator]], ᱴᱷᱮᱱ ᱞᱟᱹᱭᱢᱮ, URL ᱦᱚᱛᱮᱛᱮ᱾",
        "missingarticle-rev": "(ᱥᱩᱫᱷᱨᱟᱹᱣ#:$1)",
        "missingarticle-diff": "(ᱯᱷᱟᱨᱟᱠ: $1, $2)",
-       "readonly_lag": "á¸\8caá¹­abes do aÄ\87hote tege bondo hoe akana, je lekate udhin reaḱ á¸\8daá¹­abes sarvarkor mukhiạ á¸\8daá¹­abes sarvar lekate heÄ\87 daá¹\9beaḱ.",
+       "readonly_lag": "á±°á±\9fá±´á±\9fᱵᱮᱥ á±«á±\9a á±\9fᱪá±\9bá±® á±µá±\9aᱱᱫá±\9a á±¦á±©á±­ á±\9fá± á±\9fá±±á±\9f, á±¡á±® á±\9eᱮᱠá±\9fá±\9bá±® á±©á±«á±·á±¤á±± á±¨á±®á±­á±\9fá±\9c á±«á±\9fá±´á±\9fᱵᱮᱥ á±¥á±\9fᱨᱵᱷá±\9fᱨᱠᱳ á±¢á±©á±¬á±©á±\9b á±«á±\9fá±´á±\9fᱵᱮᱥ á±¥á±\9fᱨᱵᱷá±\9fᱨ á±\9eᱮᱠá±\9fá±\9bá±® á±¦á±®á±¡ á±«á±\9fᱲᱮᱭá±\9fá±\9c",
        "internalerror": "ᱵᱷᱤᱛᱨᱤ ᱦᱩᱲᱟᱹᱜ",
        "internalerror_info": "ᱵᱷᱤᱛᱨᱤ ᱦᱩᱲᱟᱹᱜ: $1",
        "filecopyerror": "\"$1\" ᱨᱮᱫ ᱠᱷᱚᱱ \"$2\" ᱨᱮᱫ ᱵᱟᱝ ᱠᱚᱯᱤᱞᱮᱱᱟ᱾",
        "filerenameerror": "\"$1\" ᱨᱮᱫ ᱨᱮᱭᱟᱜ ᱧᱩᱛᱩᱢ ᱵᱚᱫᱚᱞ ᱠᱟᱛᱮ \"$2\" ᱮᱢ ᱵᱟᱝ ᱜᱟᱱᱚᱜ ᱠᱟᱱᱟ᱾",
        "filedeleteerror": "$1 ᱨᱮᱫ ᱫᱚ ᱵᱟᱝ ᱜᱮᱫᱽ ᱜᱤᱰᱤ ᱞᱮᱱᱟ",
        "directorycreateerror": "\"$1\" ᱰᱟᱭᱨᱮᱠᱴᱳᱨᱤ ᱫᱚ ᱵᱟᱝ ᱛᱮᱭᱟᱨᱞᱮᱱᱟ᱾",
+       "directorynotreadableerror": "ᱯᱟᱠᱷᱟ \"$1\" ᱫᱚ ᱯᱟᱲᱦᱟᱣ ᱵᱟᱭ ᱜᱟᱱᱚᱜᱼᱟ ᱾",
        "filenotfound": "\"$1\" ᱨᱮᱫ ᱫᱚ ᱵᱟᱝ ᱧᱟᱢᱞᱮᱱᱟ᱾",
        "unexpected": "ᱵᱟᱝ ᱟᱥᱟᱜ ᱠᱟᱱ ᱢᱟᱹᱱ: \"$1\"=\"$2\".",
        "formerror": "ᱦᱩᱲᱟᱹᱜ: ᱯᱷᱚᱨᱚᱢ ᱫᱚ ᱵᱟᱝ ᱡᱤᱢᱟᱹᱞᱮᱱᱟ᱾",
        "badarticleerror": "ᱱᱚᱣᱟ ᱠᱟᱹᱢᱤ ᱫᱚ ᱱᱚᱣᱟ ᱥᱟᱦᱴᱟᱨᱮ ᱵᱟᱝ ᱦᱩᱭᱞᱮᱱᱟ᱾",
-       "cannotdelete": "$1 sakam se rẽt do baṅ get giḍilena.\nPasec eṭaḱ hoṛ noa do lahareko get giḍi akada.",
+       "cannotdelete": "$1 ᱥᱟᱦᱴᱟ ᱥᱮ ᱨᱮᱫ ᱫᱚ ᱵᱟᱝ ᱜᱮᱫ ᱜᱤᱰᱤᱞᱮᱱᱟ᱾\nᱯᱟᱥᱮᱡ ᱮᱴᱟᱜ ᱦᱚᱲ ᱱᱚᱣᱟ ᱫᱚ ᱞᱟᱦᱟᱨᱮᱜᱮ ᱜᱮᱫ ᱜᱤᱰᱤ ᱟᱠᱟᱫᱟ᱾",
        "cannotdelete-title": "\"$1\" ᱥᱟᱦᱴᱟ ᱫᱚ ᱵᱟᱝ ᱜᱮᱫ ᱜᱤᱰᱤ ᱟᱠᱟᱱᱟ",
        "badtitle": "ᱵᱟᱹᱨᱤᱡ ᱴᱟᱭᱴᱮᱞ",
        "badtitletext": "ᱟᱢᱮᱢ ᱱᱮᱦᱚᱨᱟᱠᱟᱱ ᱥᱟᱦᱴᱟ ᱧᱤᱛᱩᱢ ᱫᱚ ᱵᱟᱝ ᱴᱷᱤᱠᱟ, ᱠᱷᱟᱹᱞᱤ ᱥᱮ ᱵᱷᱩᱞᱜᱮ ᱵᱷᱤᱛᱨᱤ ᱯᱟᱹᱨᱥᱤᱛᱮ ᱥᱮ ᱩᱭᱠᱤ ᱴᱟᱭᱴᱮᱞ ᱛᱮ ᱡᱚᱱᱚᱲ ᱜᱮᱭᱟ᱾\nᱱᱚᱣᱟᱨᱮ ᱫᱚ ᱢᱤᱫ ᱥᱮ ᱟᱭᱢᱟ ᱩᱱᱩᱫᱩᱜ ᱢᱮᱱᱟᱜ ᱚᱠᱟ ᱫᱚ ᱧᱤᱛᱩᱢᱨᱮ ᱵᱟᱝ ᱵᱮᱵᱦᱟᱨᱚᱜ᱾",
-       "querypage-no-updates": "Noa sakam reaḱ nahaḱ halot bondo gea. Nonḍe doho akana ḍaṭako do baṅ saphaḱa.",
+       "querypage-no-updates": "ᱱᱚᱣᱟ ᱥᱟᱦᱴᱟ ᱨᱮᱭᱟᱜ ᱱᱟᱦᱟᱜ ᱦᱟᱞᱚᱛ ᱵᱚᱱᱫᱽ ᱜᱮᱭᱟ᱾\nᱱᱚᱸᱰᱮ ᱫᱚᱦᱚ ᱟᱠᱟᱱ ᱰᱟᱴᱟᱠᱳ ᱫᱚ ᱵᱟᱝ ᱥᱟᱯᱷᱟᱜ-ᱟ᱾",
        "viewsource": "ᱯᱷᱮᱰᱟᱛ ᱧᱮᱞ",
        "viewsource-title": "$1 ᱨᱮᱱᱟᱜ ᱯᱷᱮᱰᱟᱛ ᱧᱮᱞᱢᱮ",
        "actionthrottled": "ᱠᱟᱹᱢᱤ ᱨᱮᱭᱟᱜ ᱫᱷᱟᱨᱟ ᱵᱟᱹᱭ",
        "protectedpagetext": "ᱱᱚᱣᱟ ᱥᱟᱦᱴᱟ ᱫᱚ ᱚᱞ ᱥᱟᱯᱲᱟᱣ ᱞᱟᱹᱜᱤᱛᱛᱮ ᱫᱚ ᱵᱟᱸᱪᱟᱣ ᱜᱮᱭᱟ᱾",
        "viewsourcetext": "ᱱᱚᱭᱟ ᱥᱟᱦᱴᱟᱢ ᱧᱮᱞ ᱫᱟᱲᱮᱭᱟᱜ-ᱟ ᱟᱨᱮᱢ ᱠᱚᱯᱤ ᱫᱟᱲᱮᱭᱟᱜ-ᱟ᱾",
-       "viewyourtext": "ᱟᱢ ᱫᱚ '''ᱟᱢᱟᱜ ᱥᱟᱯᱲᱟᱣ''' ᱥᱟᱦᱴᱟ ᱧᱮᱞ ᱟᱨ ᱮᱢ ᱠᱚᱯᱤ ᱦᱟᱛᱟᱣ ᱫᱟᱲᱮᱭᱟᱜ-ᱟ:",
-       "protectedinterface": "Noa sakam reaḱ babotko do wiki sofṭoyer reaḱ mit́ṭen inṭarfes khobore ema, onate noa do rukhiyạ doho hoeakana.",
-       "cascadeprotected": "Noa sakam do sompadon khon rukhiyạre menaḱa, karon sakam do latar reaḱ {{PLURAL:$1 gan sakam reaḱ gan sakam reaḱ}} bhitrire, oka sakam do (cascading) te rukhiyạ menaḱa:\n$2",
-       "namespaceprotected": "Amaḱ do sakamko joṛao lạgit́te ạidạri banuḱ tama '''$1''' ńutumjayga.",
-       "ns-specialprotected": "Asokay teaḱ sakamkodo baṅ oltoṅgea.",
+       "viewyourtext": "ᱟᱢ ᱫᱚ <strong>'''ᱟᱢᱟᱜ ᱥᱟᱯᱲᱟᱣ</strong>''' ᱥᱟᱦᱴᱟ ᱧᱮᱞ ᱟᱨ ᱮᱢ ᱠᱚᱯᱤ ᱦᱟᱛᱟᱣ ᱫᱟᱲᱮᱭᱟᱜ-ᱟ:",
+       "protectedinterface": "ᱱᱚᱣᱟ ᱥᱟᱦᱴᱟ ᱨᱮᱭᱟᱜ ᱵᱟᱵᱚᱛᱠᱚ ᱫᱚ ᱣᱤᱠᱤ ᱥᱚᱯᱷᱴᱚᱭᱟᱨ ᱨᱮᱭᱟᱜ ᱢᱤᱫᱴᱮᱱ ᱤᱱᱴᱟᱨᱯᱷᱮᱥ ᱠᱷᱚᱵᱚᱨᱮ ᱮᱢᱟ, ᱚᱱᱟᱛᱮ ᱱᱚᱣᱟ ᱫᱟ ᱨᱩᱠᱷᱤᱭᱟᱹ ᱫᱚᱦᱚ ᱦᱩᱭᱠᱟᱱᱟ᱾",
+       "cascadeprotected": "ᱱᱚᱣᱟ ᱥᱟᱦᱴᱟ ᱫᱚ ᱥᱟᱯᱲᱟᱣ ᱠᱷᱚᱱ ᱨᱩᱠᱷᱤᱭᱟᱹᱨᱮ ᱢᱮᱱᱟᱜ-ᱟ, ᱠᱟᱨᱚᱱ ᱱᱚᱣᱟ ᱥᱟᱦᱴᱟ ᱫᱚ ᱞᱟᱛᱟᱨ ᱨᱮᱭᱟᱜ {{PLURAL:$1 ᱜᱟᱱ ᱥᱟᱦᱴᱟ ᱨᱮᱭᱟᱜ ᱜᱟᱱ ᱥᱟᱦᱴᱟ ᱨᱮᱭᱟᱜ}} ᱵᱷᱤᱛᱨᱤᱨᱮ, ᱚᱠᱟ ᱥᱟᱦᱴᱟ ᱫᱚ (cascading) ᱛᱮ ᱨᱩᱠᱷᱤᱭᱟᱹ ᱢᱮᱱᱟᱜ-ᱟ:\n$2",
+       "namespaceprotected": "ᱥᱟᱦᱴᱟ ᱡᱚᱱᱚᱲ ᱞᱟᱹᱜᱤᱛ ᱟᱢᱟᱜ ᱟᱹᱭᱫᱟᱹᱨᱤ ᱫᱚ ᱵᱟᱹᱱᱩᱜ ᱛᱟᱢᱟ '''$1''' ᱧᱩᱛᱩᱢ ᱡᱟᱭᱜᱟ᱾",
+       "ns-specialprotected": "ᱟᱥᱚᱠᱟᱭ ᱛᱮᱭᱟᱜ ᱥᱟᱦᱴᱟᱠᱚ ᱥᱟᱯᱲᱟᱣ ᱨᱮᱭᱟᱜ ᱟᱹᱭᱫᱟᱹᱨᱤ ᱫᱚ ᱟᱢᱟᱜ ᱵᱟᱹᱱᱩᱜ-ᱟ᱾",
        "exception-nologin": "ᱵᱟᱢ ᱵᱚᱞᱚ ᱟᱠᱟᱱᱟ",
        "exception-nologin-text": "ᱫᱟᱭᱟᱠᱟᱛᱮ ᱵᱚᱞᱚᱱ ᱢᱮ ᱱᱚᱶᱟ ᱥᱟᱦᱴᱟ ᱨᱮ ᱡᱟᱦᱟᱸᱱ ᱠᱟᱹᱢᱤ ᱞᱟᱹᱜᱤᱫ",
        "virus-badscanner": "Vul konfigareson: baṅ orom vairas skenar: \"$1\"",
        "virus-scanfailed": "Esken baṅ hoelena (Code $1)",
        "virus-unknownscanner": "Baṅ urum anṭvayras:",
+       "cannotlogoutnow-title": "ᱱᱤᱛ ᱚᱰᱚᱠ ᱵᱟᱭ ᱜᱟᱱᱚᱜ ᱠᱟᱱᱟ",
+       "cannotlogoutnow-text": "ᱚᱰᱚᱠᱚᱜ ᱫᱚ ᱵᱟᱭ ᱜᱟᱱᱚᱜᱼᱟ ᱡᱚᱠᱷᱚᱱ $1 ᱵᱮᱵᱷᱟᱨᱚᱜ ᱠᱟᱱᱟ",
        "welcomeuser": "ᱥᱟᱹᱜᱩᱱ ᱫᱟᱨᱟᱢ, $1!",
-       "welcomecreation-msg": "Amaḱ ekaunṭ do̠ jhićena. Amaḱ pạsindko bodol alom hiṛińa.",
+       "welcomecreation-msg": "ᱟᱢᱟᱜ ᱮᱠᱟᱶᱩᱴ ᱫᱚ ᱛᱮᱭᱟᱨᱮᱱᱟ ᱾\nᱟᱢ ᱥᱟᱱᱟᱢᱮ ᱠᱷᱟᱱ ᱟᱢᱟᱜ {{SITENAME}} [[Special:Preferences|ᱠᱩᱥᱤᱠᱚ]] ᱵᱚᱫᱚᱞ ᱫᱟᱲᱮᱭᱟᱜ ᱟᱢ ᱾",
        "yourname": "ᱵᱮᱵᱷᱟᱨᱤᱭᱟᱹ ᱧᱩᱛᱩᱢ:",
        "userlogin-yourname": "ᱵᱮᱵᱷᱟᱨᱤᱭᱟᱹ ᱧᱩᱛᱩᱢ",
        "userlogin-yourname-ph": "ᱟᱢᱟᱜ ᱵᱮᱵᱦᱟᱨᱤᱭᱟᱹ ᱧᱤᱛᱩᱢ ᱵᱚᱞᱚᱭ ᱢᱮ",
        "createacct-yourpasswordagain": "ᱫᱟᱱᱟᱝ ᱥᱟᱵᱟᱫᱽ ᱴᱷᱟᱹᱣᱠᱟᱹᱭ ᱢᱮ",
        "createacct-yourpasswordagain-ph": "ᱫᱟᱱᱟᱝ ᱥᱟᱵᱟᱫᱽ ᱟᱫᱮᱨᱢᱮ ᱫᱚᱲᱦᱟ",
        "userlogin-remembermypassword": "ᱵᱚᱞᱚ ᱛᱷᱤᱨᱜᱮ ᱫᱚᱦᱚᱠᱟᱹᱧᱢᱮ",
+       "userlogin-signwithsecure": "ᱥᱤᱠᱣᱟᱹᱨ ᱠᱷᱚᱸᱡᱟ ᱵᱮᱵᱷᱟᱨ ᱢᱮ",
+       "cannotlogin-title": "ᱵᱚᱞᱚ ᱵᱟᱭ ᱜᱟᱱ ᱞᱮᱱᱟ",
+       "cannotlogin-text": "ᱵᱚᱞᱚ ᱵᱟᱭ ᱦᱩᱭ ᱫᱟᱲᱮᱭᱟᱜᱼᱟ ᱾",
+       "cannotloginnow-title": "ᱱᱤᱛ ᱵᱟᱝ ᱵᱚᱞᱚᱱᱟ",
+       "cannotloginnow-text": "ᱵᱚᱞᱚᱱ ᱫᱚ ᱵᱟᱭ ᱜᱟᱱᱚᱜᱼᱟ ᱡᱚᱠᱷᱚᱱ $1 ᱵᱮᱵᱷᱟᱨᱚᱜ ᱠᱟᱱᱟ",
+       "cannotcreateaccount-title": "ᱮᱠᱟᱶᱩᱴ ᱵᱟᱝ ᱛᱮᱭᱟᱨᱞᱮᱱᱟ",
        "yourdomainname": "ᱟᱢᱟᱜ ᱧᱩᱛᱩᱢ:",
        "externaldberror": "Hoe daṛeyaḱa jahan bahre reaḱ jacaeaḱ ḍaṭabes vul hoeakana se amaḱ bahre reaḱ ekaunṭ do nahaḱ halot aguire ạidạri bạnuḱa.",
        "login": "ᱵᱚᱞᱚᱜ ᱢᱮ",
        "createacct-emailoptional": "ᱤᱢᱮᱞ ᱴᱷᱤᱠᱱᱟ (ᱟᱢᱠᱩᱥᱤ)",
        "createacct-email-ph": "ᱟᱢᱟᱜ ᱤᱢᱮᱞ ᱵᱩᱴᱟᱹ ᱟᱫᱮᱨᱢᱮ",
        "createacct-another-email-ph": "ᱤᱢᱮᱞ ᱵᱩᱴᱟᱹ ᱟᱫᱮᱨᱢᱮ",
-       "createaccountmail": "E-mail hotete",
+       "createaccountmail": "E-mail ᱦᱚᱛᱮᱛᱮ",
        "createacct-realname": "ᱥᱚᱛ ᱧᱩᱛᱩᱢ (ᱚᱯᱥᱱᱟᱞ)",
        "createacct-reason": "ᱚᱡᱮ",
        "createacct-reason-ph": "ᱪᱮᱫᱟᱜ ᱟᱢ ᱮᱴᱟᱜ ᱦᱤᱥᱟᱹᱵᱮᱢ ᱛᱮᱭᱟᱨᱫᱟ",
        "nocookieslogin": "{{SITENAME}} re kuki hotete beoharićaḱ bhitri boloḱ do hoyoḱa. Amaḱ sendrare kuki bondo menaḱa. Kuki cạlu kate arhõ kurumuṭuimẽ.",
        "nocookiesfornew": "Beoharićaḱ ekaunṭ do baṅ tear akana, Cedaḱ je noa ńamoḱ jaega babote ale do bale uruma.\nAle do baḍae ocolem amaḱ kuki doe kạmikana, sakam do arhõ rakaṕ lạgit́te kurumuṭuemẽ.",
        "noname": "Am do asol beoharićaḱ ńutum ṭhikte bam emakada.",
-       "loginsuccesstitle": "Bhitri boloḱ do moctege puraoena",
+       "loginsuccesstitle": "ᱵᱷᱤᱛᱨᱤ ᱵᱚᱠᱟᱜ ᱫᱚ ᱢᱚᱡᱽᱛᱮᱜᱮ ᱯᱩᱨᱟᱹᱣᱱᱟ",
        "loginsuccess": "'''Am do nitge \"$1\" ńutumte {{SITENAME}} rem bolo akana.'''",
-       "nosuchuser": "\"$1\" ńutuman jahan beoharić bạnuea.\nBeoharićaḱ ńutum do bukṛogea.\nAmaḱ bananko ńelmẽ, se [[Special:Userlogin/signup nãwã mit́ṭen ekaunṭ tearmẽ]].",
+       "nosuchuser": "\"$1\" ᱧᱩᱛᱩᱢᱟᱱ ᱡᱟᱸᱦᱟᱱ ᱵᱮᱵᱷᱟᱨᱤᱡ ᱵᱟᱹᱱᱩᱭᱟ᱾ ᱵᱮᱵᱷᱟᱨᱤᱡ ᱧᱩᱛᱩᱢ ᱫᱚ ᱵᱩᱠᱨᱩᱜᱮᱭᱟ᱾ ᱟᱢᱟᱜ ᱵᱟᱱᱟᱱᱠᱩ  ᱧᱮᱞᱢᱮ, ᱥᱮ [[Special:CreateAccount|ᱱᱟᱣᱟ ᱢᱤᱫᱴᱮᱱ ᱮᱠᱟᱶᱩᱴ ᱛᱮᱭᱟᱨᱢᱮ]]᱾",
        "nosuchusershort": "\"$1\" ńutuman jahãe beoharko do banuḱkoa. Ńutum reaḱ banan biḍaomẽ.",
        "nouserspecified": "Am do pusṭaote laṛcaṛićaḱ ńutum em hoyoḱtama.",
        "login-userblocked": "Nui laṛcaṛic doe esetgea. bhitri boloḱ ạidạri bań emoḱ kana.",
-       "wrongpassword": "Bań milaoaḱ oku nambar em hoyakana.\nDaya kate arhõ mitdhom kurumuṭuyme.",
+       "wrongpassword": "ᱵᱮᱷᱟᱨᱤᱭᱟᱜ ᱧᱩᱛᱩᱢ ᱥᱮ ᱩᱠᱩ ᱱᱟᱢᱵᱟᱨ ᱵᱟᱝ ᱢᱤᱞᱟᱹᱜ ᱠᱟᱱᱟ᱾ ᱫᱚᱲᱦᱟᱛᱮ ᱠᱩᱨᱩᱢᱩᱴᱩᱭᱢᱮ᱾",
        "wrongpasswordempty": "Em hoyen oku nambar do cetge banuḱa.\nDaya katet́ arhõ kurumuṭuyme.",
        "passwordtooshort": "Uku nambar do {{PLURAL:$1 1 horop reaḱ $1 horop reaḱ}} mudre hoyoḱ jạruṛa.",
        "password-name-match": "Amaḱ oku nambar do amaḱ ńutum khon eṭaḱ hoyoḱ jạruṛtama.",
        "noemail": "\"$1\" beoharić lạgit́te do jahan e-mail ṭhikana rukhiyạ doho bạnuḱa.",
        "noemailcreate": "Am do mitṭen jewet e-mail ṭhikạna em jaruṛ menaḱtama.",
        "passwordsent": "\"$1\" ṭhikạnate resṭariyen e-mail lạgit́te mitṭen oku nambar em hoyena.\nDaya kate ńam porte arhõ bhitri boloḱme.",
-       "blocked-mailpassword": "Amaḱ IP ṭhikạna khon sompadon do bondo menaḱa, Onate noa ṭhikạna baṅ beohar kate uku nambar ruạṛ baṅ hoyoḱa.",
+       "blocked-mailpassword": "ᱟᱢᱟᱜ IP ᱴᱷᱤᱠᱟᱹᱱᱟ ᱠᱷᱚᱱ ᱥᱟᱯᱲᱟᱣ ᱰᱚᱱᱫᱽ ᱜᱮᱭᱟ᱾ ᱚᱱᱟᱛᱮ ᱱᱚᱣᱟ ᱴᱷᱤᱠᱟᱹᱱᱟ ᱵᱟᱝ ᱵᱮᱵᱷᱟᱨ ᱠᱟᱛᱮ ᱩᱠᱩ ᱱᱟᱢᱵᱟᱨ ᱨᱩᱣᱟᱹᱲ ᱵᱟᱝ ᱦᱩᱭᱩᱜ-ᱟ᱾",
        "mailerror": "E-mail kulte eṭkẽṭõrẽ: $1",
-       "emailauthenticated": "Amaḱ e-mail ṭhikạna do $2 tạrikh reaḱ $3 re jạhirena.",
-       "emailnotauthenticated": "Amaḱ e-mail reaḱ ṭhikạna do <strong> nit hõ baṅ jacay akana</strong> latar reaḱ features lạgit́te jahan e-mail do baṅkuloḱa.",
+       "emailauthenticated": "ᱟᱢᱟᱜ ᱤ-ᱢᱮᱞ ᱴᱷᱤᱠᱟᱹᱱᱟ ᱫᱚ $2 ᱛᱟᱹᱨᱤᱠᱷ ᱨᱮᱭᱟᱜ $3 ᱨᱮ ᱡᱟᱹᱦᱤᱨᱮᱱᱟ᱾",
+       "emailnotauthenticated": "ᱟᱢᱟᱜ e-mail ᱨᱮᱭᱟᱜ ᱴᱷᱤᱠᱟᱹᱱᱟ ᱫᱚ <strong> ᱱᱤᱛ ᱦᱚᱸ ᱵᱟᱝ ᱡᱟᱹᱪᱟᱹᱭ ᱟᱠᱟᱱᱟ </strong> ᱞᱟᱛᱟᱨ ᱨᱮᱭᱟᱜ features ᱞᱟᱹᱜᱤᱛᱛᱮ ᱡᱟᱸᱦᱟᱸᱱ e-mail ᱫᱚ ᱵᱟᱝᱠᱩᱞᱟᱠᱳ᱾",
        "noemailprefs": "Noa features ko kạmie ocoy lạgit́te mit́ṭen e-mail ṭhikạna dohoe hoyoḱa.",
        "emailconfirmlink": "Amaḱ e-mail ṭhikana do sạriyme.",
        "invalidemailaddress": "Noa e-mail ṭhikạna do baṅ hataoa, karon noa formeṭ do pusṭạote baṅ em akana. Dayakate pusṭao formeṭte ṭhikạna emmẽ, se khet do khạliemẽ.",
        "cannotchangeemail": "Ekaunṭ e-mail ṭhikạnakodo noa wiki re baṅ bodoloḱ kana.",
        "emaildisabled": "Noa sayeṭre do e-mail em subita bạnuḱa.",
        "accountcreated": "ᱦᱤᱥᱟᱹᱵ ᱠᱷᱟᱛᱟ ᱛᱮᱭᱟᱨᱱᱟ",
-       "accountcreatedtext": "$1 lạgit́te ekaunṭ do benaoena.",
+       "accountcreatedtext": "$1 ᱞᱟᱹᱜᱤᱛᱛᱮ ᱮᱠᱟᱣᱱᱴ ᱫᱚ ᱵᱮᱱᱟᱣᱮᱱᱟ᱾",
        "createaccount-title": "{{SITENAME}} ᱞᱟᱹᱜᱤᱛᱛᱮ ᱦᱤᱥᱟᱹᱵ ᱠᱷᱟᱛᱟ ᱛᱮᱭᱟᱨ",
        "createaccount-text": "Okoe co am lạgit́te mitṭen ekaunṭko amaḱ e-mail ṭhikạna lạgit {{SITENAME}} re ($4) ńutum \"$2\", oku nambar \"$3\".\nAm do mesagem baṅ daṛeyaḱa, judi noa ekaunṭ do vulge benaolen khan.",
-       "login-throttled": "Am do mitghạri lahare por por aema dhao boloḱem kurumuṭu keda.\nArhõ kurumuṭue lahare dayakate thoṛagan tạṅgiemẽ.",
-       "login-abort-generic": "Amaḱ bhitri boloḱ do baṅ hoylena - batena.",
+       "login-throttled": "ᱟᱢ ᱫᱚ ᱢᱤᱫᱜᱷᱟᱹᱲᱤ ᱞᱟᱦᱟᱨᱮ ᱟᱭᱢᱟ ᱫᱷᱟᱣ ᱵᱚᱞᱚᱜᱮᱢ ᱠᱩᱨᱩᱢᱩᱴᱩ ᱠᱮᱫᱟ᱾ \nᱟᱨᱦᱚᱸ ᱠᱩᱨᱩᱢᱩᱴᱩᱭ ᱞᱟᱦᱟᱨᱮ ᱫᱟᱭᱟᱠᱟᱛᱮ ᱛᱷᱟᱲᱟᱜᱟᱱ ᱛᱟᱸᱜᱤᱭᱢᱮ᱾",
+       "login-abort-generic": "ᱟᱢᱟᱜ ᱵᱷᱤᱛᱨᱤ ᱵᱚᱠᱟᱜ ᱫᱚ ᱵᱟᱝ ᱦᱩᱭᱞᱮᱱᱟ - ᱵᱟᱫᱽᱱᱟ",
        "loginlanguagelabel": "ᱯᱟᱹᱨᱥᱤ: $1",
        "pt-login": "ᱵᱚᱞᱚᱜ ᱫᱩᱭᱟᱹᱨ",
        "pt-login-button": "ᱵᱚᱞᱚᱜ ᱢᱮ",
+       "pt-login-continue-button": "ᱞᱮᱛᱟᱲ ᱵᱚᱞᱚ ᱠᱚᱜᱼᱢᱮ",
        "pt-createaccount": "ᱴᱷᱟᱭ ᱵᱮᱱᱟᱣᱢᱮ",
        "pt-userlogout": "ᱚᱰᱚᱠᱚᱜ ᱢᱮ",
        "user-mail-no-addy": "Jahan e-mail ṭhikana bạgi kate e-mail kul kurumuṭu hoena.",
        "newpassword": "ᱱᱟᱶᱟ ᱫᱟᱱᱟᱝᱥᱟᱵᱟᱫᱽᱺ",
        "retypenew": "ᱫᱚᱲᱦᱟᱛᱮ ᱫᱟᱱᱟᱝ ᱥᱟᱵᱟᱫᱽ ᱚᱞᱢᱮ:",
        "resetpass_submit": "ᱫᱟᱱᱟᱝ ᱥᱟᱵᱟᱫᱽ ᱮᱢᱢᱮ ᱟᱨ ᱵᱚᱞᱚᱜ ᱢᱮ",
-       "changepassword-success": "Amaḱ oku namber do napayte bodolena!\nNitoḱ do am bhitritem boloḱkana...",
+       "changepassword-success": "ᱟᱢᱟᱜ ᱫᱟᱱᱟᱝ ᱥᱟᱵᱟᱫᱽ ᱫᱚ ᱵᱚᱫᱚᱞᱮᱱᱟ!",
        "botpasswords": "ᱵᱚᱴ ᱫᱟᱱᱟᱝ ᱥᱟᱵᱟᱫᱽ",
        "botpasswords-createnew": "ᱱᱟᱶᱟ ᱵᱚᱴ ᱫᱟᱱᱟᱝ ᱥᱟᱵᱟᱫᱽ ᱛᱮᱭᱟᱨᱢᱮ",
        "botpasswords-label-appid": "ᱵᱚᱴ ᱧᱩᱛᱩᱢ:",
        "passwordreset-email": "ᱤᱢᱮᱞ ᱵᱩᱴᱟᱹ:",
        "passwordreset-emailtitle": "{{SITENAME}} sayeṭre beoharićaḱ purạo thutiko",
        "passwordreset-emailelement": "ᱵᱮᱵᱦᱟᱨᱤᱭᱟᱜ ᱧᱩᱛᱩᱢ: \n$1\n\nᱢᱤᱫ ᱜᱷᱟᱹᱲᱤ ᱞᱟᱹᱜᱤᱛ ᱫᱟᱱᱟᱝ ᱱᱟᱵᱟᱫᱽ: \n$2",
-       "passwordreset-emailsentemail": "Mitṭen disạ ruaṛ e-mail do kulena.",
+       "passwordreset-emailsentemail": "ᱱᱚᱣᱟ ᱤᱢᱮᱞ ᱴᱷᱤᱠᱟᱹᱱᱟ ᱦᱤᱥᱟᱹᱵ ᱠᱷᱟᱛᱟ ᱥᱟᱶᱛᱮ ᱢᱮᱥᱟ ᱢᱮᱱᱟᱜ ᱠᱷᱟᱡ ᱩᱠᱩ ᱱᱚᱢᱵᱚᱨ ᱫᱤᱥᱟᱹ ᱨᱩᱣᱟᱹᱲ  ᱤᱢᱮᱞ ᱫᱚ ᱠᱩᱞᱮᱱᱟ᱾",
        "changeemail": "ᱤᱢᱮᱞ ᱴᱷᱤᱠᱱᱟ ᱵᱚᱫᱚᱞ ᱢᱮ ᱥᱮ ᱚᱪᱚᱜᱽ ᱢᱮ",
-       "changeemail-header": "Ekaunṭ e-mail ṭhikạna do bodolme",
+       "changeemail-header": "e-mail ᱴᱷᱤᱠᱟᱹᱱᱟ ᱵᱚᱫᱚᱞ ᱞᱟᱹᱜᱤᱛᱛᱮ ᱱᱤᱭᱟᱹ ᱯᱷᱚᱨᱢ ᱯᱩᱨᱳᱱᱢᱮ᱾ ᱡᱟᱸᱦᱟᱸᱱ email ᱡᱩ ᱦᱤᱥᱟᱹᱵ ᱠᱷᱟᱛᱟ ᱨᱮ ᱢᱮᱥᱟ ᱢᱮᱱᱟᱜ-ᱟ ᱚᱱᱟᱠᱩ ᱚᱪᱚᱜ ᱞᱟᱹᱜᱤᱛ email ᱴᱷᱤᱠᱟᱹᱱᱟ ᱚᱞ ᱡᱟᱜᱟ ᱫᱚ ᱯᱷᱟᱠᱟ ᱫᱚᱦᱚᱭᱢᱮ᱾",
        "changeemail-no-info": "Noa sakam sojhete laṛcaṛ lạgit́te am do bhitri boloḱ hoyoḱtama.",
        "changeemail-oldemail": "ᱱᱮᱛᱚᱜ-ᱟᱜ ᱤᱢᱮᱞ ᱴᱷᱤᱠᱟᱹᱱᱟ",
        "changeemail-newemail": "ᱱᱟᱣᱟ ᱤᱢᱮᱞ ᱵᱩᱴᱟᱹ:",
        "savechanges": "ᱵᱚᱫᱚᱞᱠᱚ ᱨᱩᱠᱷᱤᱭᱟᱹᱭ ᱢᱮ",
        "publishpage": "ᱥᱟᱦᱴᱟ ᱯᱟᱨᱥᱟᱞ ᱢᱮ",
        "publishchanges": "ᱵᱚᱫᱚᱞᱠᱚ ᱯᱟᱨᱥᱟᱞ ᱢᱮ",
+       "savearticle-start": "ᱥᱟᱦᱴᱟ ᱨᱩᱠᱷᱭᱟᱹᱹᱹ",
+       "savechanges-start": "ᱵᱚᱫᱚᱞ ᱨᱩᱠᱷᱭᱟᱹᱹᱹ",
+       "publishpage-start": "ᱥᱟᱦᱴᱟ ᱯᱟᱨᱥᱟᱞᱹᱹᱹ",
+       "publishchanges-start": "ᱵᱚᱫᱚᱞᱠᱚ ᱯᱟᱨᱥᱟᱞ",
        "preview": "ᱧᱮᱞ ᱵᱤᱰᱟᱹᱣ",
        "showpreview": "ᱧᱮᱞᱡᱚᱝ ᱩᱫᱩᱜᱽᱢᱮ",
        "showdiff": "ᱵᱚᱫᱚᱞᱠᱩ ᱩᱫᱩᱜᱽ ᱢᱮ",
        "loginreqlink": "ᱵᱚᱞᱚᱜ ᱢᱮ",
        "loginreqpagetext": "Eṭagaḱ sakamko ńel lạgit́te do am $1 hoyoḱ jạruṛtama.",
        "accmailtitle": "ᱫᱟᱱᱟᱝ ᱥᱟᱵᱟᱫᱽ ᱠᱩᱞ ᱦᱩᱭᱱᱟ",
-       "accmailtext": "[[User talk:$1 $1]] lạgit́te aćte benaoen uku nambar do $2 kul hoena.\nBhitri bolo kateḱ noa nãwã ekaunṭ lạgit uku nambar \"[[Special:ChangePassword Change password]]\" sakam khonem bodol daṛyakya.",
+       "accmailtext": "[[User talk:$1 $1]] ᱞᱟᱹᱜᱤᱛᱛᱮ ᱟᱪᱛᱮ ᱵᱮᱱᱟᱣᱮᱱ ᱩᱠᱩ ᱱᱚᱢᱵᱚᱨ ᱫᱚ $2 ᱠᱩᱞ  ᱦᱩᱭᱮᱱᱟ᱾\nᱵᱷᱤᱛᱨᱤ ᱵᱚᱞᱚ ᱠᱟᱛᱮ ᱱᱚᱣᱟ ᱱᱟᱣᱟ ᱦᱤᱥᱟᱹᱵ ᱠᱷᱟᱛᱟ ᱞᱟᱹᱜᱤᱛ ᱩᱠᱩ ᱱᱚᱢᱵᱚᱨ \"[[Special:ChangePassword Change password]]\" ᱥᱟᱦᱴᱟ ᱠᱷᱚᱱᱮᱢ ᱵᱚᱫᱚᱞ ᱫᱟᱲᱮᱭᱟᱜ-ᱟ᱾",
        "newarticle": "(ᱱᱟᱣᱟᱱᱟᱜ)",
        "newarticletext": "ᱟᱢ ᱚᱠᱟ ᱥᱟᱦᱴᱟ ᱨᱮᱱᱟᱜ ᱡᱚᱱᱟᱲᱮᱢ ᱯᱟᱸᱡᱟᱸ ᱟᱹᱜᱩᱭᱫᱟ ᱚᱱᱚ ᱫᱚ ᱵᱟᱱᱩᱜ-ᱟ᱾\nᱚᱱᱟ ᱥᱟᱦᱴᱟ ᱛᱮᱭᱟᱨ ᱞᱟᱹᱜᱤᱛ ᱛᱮ, ᱞᱟᱛᱟᱨ ᱵᱟᱠᱥᱚ ᱵᱷᱤᱛᱨᱤᱨᱮ ᱚᱞ ᱮᱦᱚᱵ ᱢᱮ (ᱟᱨᱦᱚᱸ ᱡᱟᱹᱥᱛᱤ ᱵᱟᱰᱟᱭ ᱞᱟᱹᱜᱤᱛᱴᱮ [$1 ᱜᱚᱸᱲᱚᱸ ᱥᱟᱦᱴᱟ] ᱯᱟᱸᱡᱚᱸᱭᱢᱮ)᱾\nᱟᱢ ᱵᱷᱩᱞᱛᱮ ᱱᱚᱸᱰᱮᱢ ᱦᱮᱡ ᱟᱠᱟᱱ ᱠᱷᱟᱡ, ᱟᱢᱟᱜ ᱵᱨᱟᱣᱡᱟᱨ ᱨᱮᱱᱟᱜ '''ᱛᱟᱭᱚᱢ''' ᱵᱟᱴᱚᱱ ᱞᱤᱱᱢᱮ᱾",
        "anontalkpagetext": "----\n\n<em>ᱱᱚᱶᱟ ᱫᱚ ᱜᱟᱞᱚᱪ ᱥᱟᱦᱴᱟ ᱠᱟᱱᱟ ᱩᱠᱩᱧᱩᱛᱩᱢ ᱵᱮᱵᱷᱟᱨᱤᱭᱟᱹ ᱠᱚᱣᱟᱜ ᱡᱟᱦᱟᱸᱭ ᱫᱚ ᱠᱷᱟᱛᱟ ᱵᱟᱭ ᱛᱮᱭᱟᱨ ᱟᱠᱟᱫᱟ ᱱᱤᱛ ᱦᱟᱹᱵᱤᱡ, ᱟᱨᱵᱟᱝ ᱡᱟᱦᱟᱸᱭ ᱵᱮᱵᱷᱟᱨ ᱟᱠᱟᱫᱟ ᱱᱚᱶᱟ ᱾</em>\nᱚᱱᱟᱛᱮ ᱟᱞᱮ ᱮᱞᱮᱞ IP ᱞᱮ ᱵᱮᱵᱷᱟᱨᱮᱜ-ᱟ ᱩᱱᱤ ᱪᱤᱱᱦᱟᱹᱣ ᱞᱟᱹᱜᱤᱫ ᱾\nᱚᱱᱠᱟᱱ IP ᱵᱩᱴᱟᱹ ᱫᱚ ᱦᱟᱹᱴᱤᱧ ᱫᱟᱲᱮᱭᱟᱜ-ᱟ ᱛᱤᱢᱤᱱ ᱵᱮᱵᱷᱟᱨᱤᱭᱟᱹ ᱫᱟᱨᱟᱭᱛᱮ ᱾\nᱡᱩᱫᱤ ᱟᱢ ᱩᱠᱩᱧᱩᱛᱩᱢ ᱵᱮᱵᱷᱟᱨᱤᱭᱟᱹ ᱠᱟᱱᱟᱢ ᱟᱨ ᱵᱷᱟᱹᱵᱤᱭᱮᱜ-ᱟᱢ ᱵᱟᱝ ᱡᱚᱲᱟᱣᱟᱱ ᱠᱟᱛᱷᱟ ᱟᱢᱮ ᱩᱫᱩᱜᱢᱮ ᱠᱟᱱᱟ, ᱮᱱᱠᱷᱟᱱ  [[Special:CreateAccount|ᱠᱷᱟᱛᱟ ᱛᱮᱭᱟᱨᱢᱮ]] ᱟᱨᱵᱟᱝ [[Special:UserLogin|ᱞᱚᱜᱤᱱ]] ᱢᱮ ᱫᱟᱨᱟᱭ ᱵᱷᱮᱣᱱᱟ ᱠᱚ ᱥᱟᱦᱟᱭ ᱞᱟᱹᱜᱤᱫ ᱮᱴᱟᱜ ᱩᱠᱩᱧᱩᱛᱩᱢ ᱵᱮᱵᱷᱟᱨᱤᱭᱟᱹ ᱠᱚ ᱥᱟᱶ ᱾",
        "edit-no-change": "ᱟᱢᱟᱜ ᱥᱟᱯᱲᱟᱣ ᱵᱟᱝ ᱦᱟᱛᱟᱣᱞᱮᱱᱟ ᱡᱮᱫᱟᱜ ᱡᱮ ᱚᱞᱨᱮ ᱡᱟᱸᱦᱟᱸᱱ ᱵᱚᱫᱚᱞ ᱵᱟᱹᱱᱩᱜ-ᱟ᱾",
        "postedit-confirmation-created": "ᱱᱚᱣᱟ ᱥᱟᱦᱴᱟ ᱫᱚ ᱛᱮᱭᱟᱨᱠᱟᱱᱟ᱾",
        "postedit-confirmation-restored": "ᱱᱚᱣᱟ ᱥᱟᱦᱴᱟ ᱫᱚ ᱟᱹᱜᱩ ᱨᱩᱣᱟᱹᱲ ᱦᱩᱭᱠᱟᱱᱟ᱾",
+       "postedit-confirmation-saved": "ᱟᱢᱟᱜ ᱥᱟᱯᱲᱟᱣ ᱫᱚ ᱨᱩᱠᱷᱭᱟᱹᱭᱮᱱᱟ",
+       "postedit-confirmation-published": "ᱟᱢᱟᱜ ᱥᱟᱯᱲᱟᱣ ᱫᱚ ᱯᱟᱨᱥᱟᱞᱮᱱᱟ",
        "edit-already-exists": "ᱱᱟᱣᱟ ᱥᱟᱦᱴᱟ ᱵᱟᱝ ᱛᱮᱭᱟᱨ ᱞᱮᱱᱟ᱾\nᱱᱚᱣᱟ ᱫᱚ ᱞᱟᱦᱟ ᱠᱷᱚᱱ ᱢᱮᱱᱟᱜ ᱜᱮᱭᱟ᱾",
        "defaultmessagetext": "ᱯᱩᱭᱞᱩ ᱚᱞᱠᱟᱱ ᱠᱷᱚᱵᱚᱨ",
        "content-model-wikitext": "ᱣᱤᱠᱤ-ᱚᱞ",
        "rev-showdeleted": "ᱥᱚᱫᱚᱨ",
        "revisiondelete": "ᱜᱮᱫ ᱜᱤᱰᱤ/ᱵᱟᱝ ᱜᱮᱫ ᱜᱤᱰᱤ ᱥᱩᱫᱷᱨᱟᱹᱣᱠᱚ",
        "revdelete-show-file-submit": "ᱦᱮᱸ",
-       "revdelete-hide-text": "Nãwã aroe olko ukuemẽ",
+       "revdelete-hide-text": "ᱚᱞᱠᱩ ᱧᱮᱞ ᱨᱩᱣᱟᱹᱲ ᱢᱮ",
        "revdelete-hide-image": "ᱨᱮᱫ ᱥᱟᱛᱚᱢᱠᱩ ᱩᱠᱩᱭᱢᱮ",
        "revdelete-hide-name": "ᱠᱟᱹᱢᱤ ᱟᱨ ᱵᱮᱡᱷᱟ ᱩᱠᱩᱭᱢᱮ",
        "revdelete-hide-comment": "ᱥᱟᱯᱲᱟᱣ ᱜᱩᱴᱠᱟᱛᱷᱟ",
        "deletedhist": "ᱜᱮᱫ ᱜᱤᱰᱤᱭᱟᱠᱟᱱ ᱱᱟᱜᱟᱢ",
        "revdelete-reasonotherlist": "ᱮᱴᱟᱜ ᱚᱡᱮ",
        "mergehistory-from": "ᱯᱷᱮᱰᱟᱛ ᱥᱟᱦᱴᱟᱺ",
+       "mergehistory-no-source": "ᱯᱷᱮᱰᱟᱛ ᱥᱟᱦᱴᱟ $1 ᱵᱟᱹᱱᱩᱜᱼᱟ ᱾",
+       "mergehistory-invalid-source": "ᱯᱷᱮᱰᱟᱛ ᱥᱟᱦᱴᱟ ᱫᱚ ᱡᱚᱛᱟᱛ ᱥᱟᱛᱟᱢ ᱦᱩᱭᱩᱜ ᱞᱟᱹᱠᱛᱤ",
        "mergehistory-reason": "ᱚᱡᱮ:",
        "mergelog": "ᱞᱚᱜᱽ ᱢᱮᱥᱟ",
        "revertmerge": "ᱵᱟᱝ ᱢᱤᱛ",
        "search-result-category-size": "{{PLURAL:$1|1 ᱥᱚᱦᱮᱫ|$1 ᱥᱚᱦᱮᱫᱠᱩ}} ({{PLURAL:$2|1 ᱦᱩᱰᱤᱧ ᱛᱷᱚᱠ|$ 2 ᱦᱩᱰᱤᱧ ᱛᱷᱚᱠᱠᱩ}}, {{PLURAL:$3|1 ᱨᱮᱫ|$3 ᱨᱮᱫᱠᱩ}})",
        "search-redirect": "(ᱥᱚᱡᱷᱮ ᱦᱤᱡᱩᱜ-ᱟ $1 ᱠᱷᱚᱱ)",
        "search-section": "(ᱦᱟᱹᱴᱤᱧ $1)",
+       "search-category": "(ᱛᱷᱚᱠ $1)",
        "search-file-match": "(ᱢᱤᱫᱩᱜᱟᱜ ᱨᱮᱫ ᱩᱱᱩᱫᱩᱜ)",
        "search-suggest": "ᱪᱮᱫ ᱮᱢ ᱢᱮᱱ ᱚᱪᱚᱭᱮᱫᱟ: $1",
        "search-interwiki-caption": "ᱥᱟᱶᱛᱮᱱ ᱯᱨᱚᱡᱮᱠᱴ ᱠᱷᱚᱱ ᱚᱨᱡᱚ",
        "datedefault": "ᱠᱩᱥᱤ ᱵᱟᱹᱱᱩᱜ-ᱟ",
        "prefs-user-pages": "ᱵᱮᱵᱦᱟᱨᱤᱭᱟᱜ ᱥᱟᱦᱴᱟᱠᱚ",
        "prefs-resetpass": "ᱫᱟᱱᱟᱝ ᱥᱟᱵᱟᱫᱽ ᱵᱚᱫᱚᱞ",
-       "prefs-changeemail": "E-mail ᱴᱷᱤᱠᱟᱱᱟ ᱵᱚᱫᱚᱞ ᱥᱮ ᱜᱮᱫ ᱜᱤᱰᱤᱭᱢᱮ",
+       "prefs-changeemail": "ᱤᱢᱮᱞ ᱴᱷᱤᱠᱟᱱᱟ ᱵᱚᱫᱚᱞ ᱥᱮ ᱜᱮᱫ ᱜᱤᱰᱤᱭᱢᱮ",
        "prefs-setemail": "ᱤᱢᱮᱞ ᱵᱩᱴᱟᱹ ᱡᱚᱲᱟᱣᱢᱮ",
        "saveprefs": "ᱨᱩᱠᱷᱤᱭᱟᱹᱭᱢᱮ",
        "searchresultshead": "ᱥᱮᱸᱫᱽᱨᱟ",
+       "timezonelegend": "ᱮᱞᱟᱠᱟ ᱚᱠᱛᱚᱺ",
+       "localtime": "ᱴᱚᱴᱷᱟ ᱚᱠᱛᱚᱺ",
+       "timezoneuseserverdefault": "ᱡᱟᱣᱞᱮᱠᱟ ($1) ᱣᱤᱠᱤ ᱵᱮᱵᱷᱟᱨ",
+       "timezoneuseoffset": "ᱮᱴᱟᱜᱟᱜ (ᱚᱯᱷᱥᱮᱴ ᱥᱚᱫᱚᱨ)",
+       "servertime": "ᱥᱚᱨᱵᱷᱚᱨ ᱚᱠᱛᱚᱺ",
+       "guesstimezone": "ᱵᱨᱟᱣᱡᱟᱨ ᱠᱷᱚᱱ ᱯᱮᱨᱮᱡ",
        "timezoneregion-africa": "ᱟᱯᱷᱨᱤᱠᱟ",
        "timezoneregion-america": "ᱟᱢᱮᱨᱤᱠᱟ",
+       "timezoneregion-antarctica": "ᱟᱱᱴᱟᱨᱠᱴᱤᱠᱟ",
+       "timezoneregion-arctic": "ᱟᱨᱠᱴᱤᱠ",
        "timezoneregion-asia": "ᱮᱥᱤᱭᱟ",
+       "timezoneregion-atlantic": "ᱟᱴᱞᱟᱱᱴᱤᱠ ᱢᱟᱦᱟᱫᱚᱨᱭᱟ",
        "timezoneregion-australia": "ᱚᱥᱴᱨᱮᱞᱤᱭᱟ",
+       "timezoneregion-europe": "ᱤᱣᱨᱚᱯ",
+       "timezoneregion-indian": "ᱥᱤᱧᱚᱛ ᱢᱟᱦᱟᱫᱚᱨᱭᱟ",
+       "timezoneregion-pacific": "ᱯᱮᱥᱤᱯᱷᱤᱠ ᱢᱟᱦᱟᱫᱚᱨᱭᱟ",
        "prefs-searchoptions": "ᱥᱮᱸᱫᱽᱨᱟ",
        "prefs-files": "ᱨᱮᱫᱠᱚ",
        "youremail": "Email:",
        "right-createaccount": "ᱱᱟᱶᱟ ᱵᱮᱵᱷᱟᱨᱤᱭᱟᱹ ᱠᱷᱟᱛᱟ ᱛᱮᱭᱟᱨ",
        "right-move": "ᱥᱟᱦᱴᱟᱠᱚ ᱥᱟᱦᱟᱭᱢᱮ",
        "right-move-subpages": "ᱥᱟᱦᱴᱟ ᱥᱟᱦᱟᱦᱟᱭᱢᱮ ᱥᱟᱶᱛᱮᱱ ᱥᱟᱦᱴᱟᱠᱚ ᱥᱟᱶ",
-       "right-movefile": "ᱨᱮᱫᱠá±\9a á±\9aᱪá±\9aá±\9cá±½ ᱢᱮ",
+       "right-movefile": "ᱨᱮᱫᱠá±\9a á±©á±ªá±\9fᱹᱲᱢᱮ",
        "right-upload": "ᱨᱮᱫ ᱠᱚ ᱞᱟᱫᱮᱢᱮ",
        "right-writeapi": "ᱚᱞ API ᱨᱮᱱᱟᱜ ᱵᱮᱵᱷᱟᱨ",
        "right-delete": "ᱥᱟᱦᱴᱟᱠᱚ ᱜᱮᱫᱽ ᱢᱮ",
        "right-browsearchive": "ᱥᱮᱸᱫᱽᱨᱟᱭ ᱢᱮ ᱜᱮᱫ ᱟᱠᱟᱱᱟ ᱥᱟᱦᱴᱟᱠᱚ",
-       "newuserlogpage": "ᱵᱮᱵᱦᱟᱨᱤᱭᱟᱜ ᱛᱮᱭᱟᱨ ᱪᱟᱹᱵᱤ",
+       "newuserlogpage": "ᱵᱮᱵᱷᱟᱨᱤᱭᱟᱜ ᱛᱮᱭᱟᱨ ᱪᱟᱹᱵᱤ",
        "rightslog": "ᱵᱮᱵᱷᱟᱨᱤᱭᱟᱹ ᱟᱹᱭᱫᱟᱹᱨ ᱞᱚᱜᱽ",
        "action-edit": "ᱱᱚᱭᱟ ᱥᱟᱦᱴᱟ ᱥᱟᱯᱲᱟᱣᱢᱮ",
        "action-createaccount": "ᱱᱚᱶᱟ ᱵᱮᱵᱷᱟᱨᱤᱭᱟᱹ ᱠᱷᱟᱛᱟ ᱵᱮᱱᱟᱣ",
        "rcfilters-days-show-days": "$1 {{PLURAL:$1|ᱢᱟᱦᱟ|ᱢᱟᱦᱟᱸ}}",
        "rcfilters-days-show-hours": "$1 {{PLURAL:$1|ᱴᱟᱲᱟᱝ|ᱴᱟᱬᱟᱝ}}",
        "rcfilters-savedqueries-rename": "ᱧᱩᱢ-ᱟᱹᱨᱩ",
-       "rcfilters-savedqueries-remove": "á±\9aᱪá±\9aá±\9c",
+       "rcfilters-savedqueries-remove": "á±\9cᱮᱫ á±\9cᱤᱰᱤ",
        "rcfilters-savedqueries-new-name-label": "ᱧᱩᱛᱩᱢ",
        "rcfilters-savedqueries-cancel-label": "ᱵᱟᱹᱜᱤ",
        "rcnotefrom": "ᱞᱟᱛᱟᱨ {{PLURAL:$5|ᱵᱚᱫᱚᱞ|ᱵᱚᱫᱚᱞ ᱠᱚ}} <strong>$3, $4</strong> ᱠᱷᱚᱱ (<strong>$1</strong> ᱦᱟᱹᱵᱤᱡ ᱩᱫᱩᱜ-ᱮᱱᱟ)",
        "newpages": "ᱱᱟᱶᱟ ᱥᱟᱦᱴᱟᱠᱳ",
        "newpages-username": "ᱵᱮᱵᱦᱟᱨᱤᱡ ᱧᱩᱛᱩᱢᱺ",
        "ancientpages": "ᱢᱟᱨᱮ ᱥᱟᱦᱴᱟᱠᱚ",
-       "move": "á±\9aᱪá±\9aá±\9c",
+       "move": "ᱩᱪá±\9fᱹᱲ",
        "movethispage": "ᱱᱚᱶᱟ ᱥᱟᱦᱴᱟ ᱥᱟᱦᱟᱭᱢᱮ",
        "pager-newer-n": "{{PLURAL:$1|1 ᱱᱟᱣᱟᱱᱟᱜ | ᱱᱟᱣᱟᱱᱟᱜ $1}}",
        "pager-older-n": "{{PLURAL:$1|ᱢᱟᱨᱮᱭᱟᱜ 1|ᱢᱟᱨᱮᱭᱟᱜ $1}}",
        "protectexpiry": "ᱢᱮᱭᱟᱫ ᱯᱟᱨᱚᱢ:",
        "protect-default": "ᱡᱚᱛᱚ ᱵᱮᱵᱷᱟᱨᱤᱭᱟᱹᱠᱚ ᱫᱟᱣ ᱮᱢ",
        "restriction-edit": "ᱥᱟᱯᱲᱟᱣ",
-       "restriction-move": "á±\9aᱪá±\9aá±\9c",
+       "restriction-move": "ᱩᱪá±\9fᱹᱲ",
        "restriction-create": "ᱛᱮᱭᱟᱨ",
        "undeletelink": "ᱧᱮᱞ/ᱫᱚᱦᱚ ᱨᱩᱣᱟᱹᱲ",
        "undeleteviewlink": "ᱧᱮᱞ",
        "whatlinkshere": "ᱱᱚᱸᱰᱮ ᱫᱚ ᱪᱮᱫ ᱡᱚᱱᱚᱲ ᱠᱳ",
        "whatlinkshere-title": "ᱚᱠᱟ ᱥᱟᱦᱴᱟ ᱠᱚᱫᱚ \"$1\" ᱨᱮ ᱡᱚᱱᱚᱲ ᱢᱮᱱᱟᱜ-ᱟ",
        "whatlinkshere-page": "ᱥᱟᱦᱴᱟ:",
-       "linkshere-2": "ᱞᱟᱛᱟᱨ ᱨᱮᱭᱟᱜ ᱥᱟᱦᱴᱟᱠᱚ ᱫᱚ <strong>$1</strong> ᱥᱟᱶ ᱡᱚᱱᱚᱲ ᱢᱮᱱᱟᱜ-ᱟ :",
-       "nolinkshere-2": "ᱥᱟᱦᱴᱟ ᱡᱚᱱᱚᱲ ᱵᱟᱱᱩᱜ-ᱟ ᱱᱤᱭᱟᱹ <strong>$1</strong>.",
+       "linkshere": "ᱞᱟᱛᱟᱨ ᱨᱮᱭᱟᱜ ᱥᱟᱦᱴᱟᱠᱚ ᱫᱚ <strong>$2</strong> ᱥᱟᱶ ᱡᱚᱱᱚᱲ ᱢᱮᱱᱟᱜ-ᱟ :",
+       "nolinkshere": "ᱥᱟᱦᱴᱟ ᱡᱚᱱᱚᱲ ᱵᱟᱱᱩᱜ-ᱟ ᱱᱤᱭᱟᱹ <strong>$2</strong>.",
        "isredirect": "ᱵᱟᱝ ᱥᱚᱡᱽᱦᱮ ᱥᱟᱦᱴᱟ",
        "istemplate": "ᱥᱮᱞᱮᱫ",
        "isimage": "ᱨᱮᱫ ᱡᱚᱱᱚᱲ",
        "block-log-flags-noemail": "E-mail ᱵᱚᱸᱫᱷ ᱜᱮᱭᱟ",
        "block-log-flags-hiddenname": "ᱵᱮᱵᱦᱟᱨᱤᱭᱟᱜ ᱧᱩᱛᱩᱢ ᱩᱠᱩ ᱜᱮᱭᱟ",
        "proxyblocker": "ᱯᱨᱚᱠᱥᱤ ᱮᱥᱮᱫᱤᱡ",
-       "movepagebtn": "á±¥á±\9fᱦᱴá±\9f á±¥á±\9fᱦá±\9fá±­ᱢᱮ",
+       "movepagebtn": "á±¥á±\9fᱦᱴá±\9f á±©á±ªá±\9fᱹᱲᱢᱮ",
        "pagemovedsub": "ᱚᱪᱟᱜ ᱫᱚ ᱦᱩᱭᱱᱟ",
        "movelogpage": "ᱛᱟᱞᱟ ᱪᱟᱹᱵᱤ ᱚᱪᱚᱜᱽᱢᱮ",
        "revertmove": "ᱨᱩᱣᱟᱹᱲ ᱟᱹᱜᱩ",
        "logentry-delete-restore": "$1 {{GENDER:$2|ᱨᱟᱠᱷᱟ ᱫᱚᱲᱦᱟ}} ᱠᱮᱜ-ᱟ ᱥᱟᱦᱴᱟ $3 ($4)",
        "logentry-delete-revision": "$1 {{GENDER:$2|ᱵᱚᱫᱚᱞᱠᱮᱜ-ᱟᱭ}} ᱧᱮᱞᱚᱜᱟᱜ {{PLURAL:$5|ᱫᱚᱦᱲᱟᱭᱮᱱᱟᱜ|$5 ᱫᱚᱦᱲᱟᱭᱮᱱᱟᱜ ᱠᱚ}} $3: $4 ᱥᱟᱦᱴᱟ ᱪᱮᱛᱟᱱᱨᱮ",
        "revdelete-content-hid": "ᱩᱱᱩᱫᱩᱜ ᱫᱟᱱᱟᱝ",
-       "logentry-move-move": "$1 á±µá±®á±µá±¦á±\9fᱨᱤᱡ $3 á±¥á±\9fᱦᱴá±\9f á±«á±\9a $4 á±§á±¤á±\9bᱩᱢᱨᱮ {{GENDER:$2|á±\9aᱪá±\9aá±\9c}} á±\9fá± á±\9fᱫá±\9f",
+       "logentry-move-move": "$1 á±µá±®á±µá±·á±\9fᱨᱤᱡ $3 á±¥á±\9fᱦᱴá±\9f á±«á±\9a $4 á±§á±¤á±\9bᱩᱢᱨᱮ {{GENDER:$2|ᱩᱪá±\9fᱹᱲ}} á± á±®á±«á±¼á±\9fá±­",
        "logentry-move-move-noredirect": "$1 {{GENDER:$2|ᱩᱪᱟᱹᱲᱠᱮᱜ-ᱟᱭ}} ᱥᱟᱦᱴᱟ $3 to $4 ᱢᱚᱦᱰᱟ ᱵᱤᱱ ᱵᱟᱹᱜᱤ ᱠᱟᱛᱮ",
-       "logentry-move-move_redir": "$1 {{GENDER:$2|ᱩᱪᱟᱹᱲᱮᱱᱟ}} ᱥᱟᱦᱴᱟ $3 ᱠᱷᱚᱱ $4 ᱪᱮᱛᱟᱱ ᱢᱚᱸᱦᱰᱟ ᱦᱟᱠᱟᱱᱟ",
+       "logentry-move-move_redir": "ᱥᱟᱦᱴᱟ $3 ᱠᱷᱚᱱ $4 ᱛᱮ $1 {{GENDER:$2|ᱩᱪᱟᱹᱲ ᱠᱮᱫᱼᱟᱭ}} ᱢᱚᱸᱦᱰᱟ ᱥᱟᱶᱛᱮ",
        "logentry-patrol-patrol-auto": "$1 ᱟᱡᱛᱮᱜᱮ {{GENDER:$2|ᱪᱤᱱᱦᱟᱹᱭᱮᱱᱟ}} $4 ᱧᱮᱞᱟᱹᱨᱩ $3 ᱥᱟᱦᱴᱟ ᱨᱮᱱᱟᱜ ᱾",
        "logentry-newusers-create": "ᱵᱮᱵᱦᱟᱨᱤᱭᱟᱜ ᱦᱤᱥᱟᱹᱵ $1 ᱫᱚ {{GENDER:$2|ᱛᱮᱭᱟᱨᱱᱟ}}",
        "logentry-newusers-autocreate": "ᱵᱮᱵᱷᱟᱨᱤᱭᱟᱹ ᱠᱷᱟᱛᱟ $1 ᱫᱚ {{GENDER:$2|ᱛᱮᱭᱟᱨᱮᱱᱟ}} ᱟᱡᱛᱮᱜᱮ",
index 52e2f63..6297db0 100644 (file)
        "whatlinkshere": "Pàginas chi ligant a custa",
        "whatlinkshere-title": "Pàginas chi ligant a \"$1\"",
        "whatlinkshere-page": "Pàgina:",
-       "linkshere-2": "Is pàginas chi sighint ligant a '''$1''':",
-       "nolinkshere-2": "Peruna pàgina ligat a '''$1'''.",
-       "nolinkshere-ns-2": "Peruna pàgina ligat a '''$1''' in su nùmene-logu seberadu.",
+       "linkshere": "Is pàginas chi sighint ligant a '''$2''':",
+       "nolinkshere": "Peruna pàgina ligat a '''$2'''.",
+       "nolinkshere-ns": "Peruna pàgina ligat a '''$2''' in su nùmene-logu seberadu.",
        "isredirect": "pàgina de reindiritzamentu",
        "istemplate": "inclusione",
        "isimage": "ligòngiu a documentu",
index 9903b2a..3f8abdf 100644 (file)
        "whatlinkshere": "Chi punta ccà",
        "whatlinkshere-title": "Pàggini ca pùntanu a \"$1\"",
        "whatlinkshere-page": "Pàggina:",
-       "linkshere-2": "Sti pàggini hannu nu liami a '''$1''':",
-       "nolinkshere-2": "Nudda pàggina havi nu liami a '''$1'''.",
-       "nolinkshere-ns-2": "Nun ci sugnu pàggini chi puntano a '''$1''' ntô namespace silizziunatu.",
+       "linkshere": "Sti pàggini hannu nu liami a '''$2''':",
+       "nolinkshere": "Nudda pàggina havi nu liami a '''$2'''.",
+       "nolinkshere-ns": "Nun ci sugnu pàggini chi puntano a '''$2''' ntô namespace silizziunatu.",
        "isredirect": "pàggina di rinnirizzamentu",
        "istemplate": "nclusioni",
        "isimage": "lijami ô file",
        "markedaspatrollederrornotify": "La marcatura comu virificatu nun arriniscìu.",
        "patrol-log-page": "Riggistru dî canciamenti virificati",
        "patrol-log-header": "Chistu è nu riggistru dî virsioni virificati.",
-       "log-show-hide-patrol": "$1 lu riggistru dî canciamenti virificati",
-       "log-show-hide-tag": "$1 lu riggistru di l'etichetti",
        "deletedrevision": "Cancillata na virsioni vecchia di $1",
        "filedeleteerror-short": "Erruri ntâ cancillazzioni dû file: $1",
        "filedeleteerror-long": "Ammatteru erruri ntô tintativu di cancillari lu file:\n\n$1",
index b09b2ef..aabc640 100644 (file)
        "whatlinkshere": "Whit airts here",
        "whatlinkshere-title": "Pages that link til \"$1\"",
        "whatlinkshere-page": "Page:",
-       "linkshere-2": "The follaein pages link til <strong>$1</strong>:",
-       "nolinkshere-2": "Nae pages link wi '''$1'''.",
-       "nolinkshere-ns-2": "No pages aiet til <strong>$1</strong> in the chosen namespace.",
+       "linkshere": "The follaein pages link til <strong>$2</strong>:",
+       "nolinkshere": "Nae pages link wi '''$2'''.",
+       "nolinkshere-ns": "No pages aiet til <strong>$2</strong> in the chosen namespace.",
        "isredirect": "reguidal page",
        "istemplate": "transclusion",
        "isimage": "file airtin",
        "markedaspatrollederrornotify": "Maurking aes patrowed failed.",
        "patrol-log-page": "Patrow log",
        "patrol-log-header": "This is ae log o patrowed reveesions.",
-       "log-show-hide-patrol": "$1 patrow log",
-       "log-show-hide-tag": "$1 tag log",
        "deletedrevision": "Delytit auld reveesion $1.",
        "filedeleteerror-short": "Mistak delytin file: $1",
        "filedeleteerror-long": "mistaks were encoontered while delytin the file:\n\n$1",
index deec6e6..07cf146 100644 (file)
@@ -9,7 +9,8 @@
                        "Macofe",
                        "Indus Asia",
                        "BukhariSaeed",
-                       "Fitoschido"
+                       "Fitoschido",
+                       "Tweety"
                ]
        },
        "tog-underline": "ڳنڍڻي هيٺان لڪير:",
        "listingcontinuesabbrev": "جاري.",
        "index-category": "ڏسڻيل صفحا",
        "noindex-category": "غيرڏسڻيل صفحا",
-       "broken-file-category": "Ù\81ائÙ\8aÙ\84 Ø¬Ù\8a Ù½Ù½ل ڳنڍڻن وارا صفحا",
+       "broken-file-category": "ٽٽÙ\84 Ù\81ائل ڳنڍڻن وارا صفحا",
        "about": "بابت",
        "article": "موادي صفحو",
        "newwindow": "(نئين دريءَ ۾ کلندو)",
        "viewsource-title": "$1 جو ڪوڊ ڏسو",
        "protectedpagetext": "هيءُ صفحو ترميمن ۽ ٻين عملن کان بچائڻ لاءِ تحفظيل آهي.",
        "viewsourcetext": "توهان هن صفحي جو ڪوڊ ڏسي ۽ نقل ڪري سگھو ٿا.",
+       "protectedinterface": "هي صفحو سافٽ ويئر جو انٽرفيس متعين ڪري ٿو ۽ غلط استعال کان بچڻ لاءِ ان کي تحفظيو ويو آهي.\nتمام وڪي ۾ ترجمو شامل ڪرڻ لاءِ يا هن ۾ تبديلي ڪرڻ لاءِ ميڊياوڪي ترجمو [https://translatewiki.net/ translatewiki.net] استعمال ڪيو.",
        "namespaceprotected": "توهان کي نانءُپولار <strong>$1</strong> جا صفحا سنوارڻ جا اختيار ناهن.",
        "mycustomcssprotected": "توهان کي هيءُ CSS صفحو سنوارڻ جي اجازت نہ آهي.",
        "mycustomjsprotected": "توهان کي هيءُ جاوا اسڪرپٽ صفحو سنوارڻ جي اجازت حاصل ڪانهي.",
        "media_tip": "فائيل جو ڳنڍڻو",
        "sig_tip": "توھان جي صحيح بمع اوقاتي مھر",
        "hr_tip": "افقي لڪير (ڪفايت سان استعمال ڪريو)",
-       "summary": "تÙ\8eتÙ\8f:",
+       "summary": "Ø®Ù\84اصÙ\88:",
        "subject": "موضوع:",
        "minoredit": "ھيءَ ھڪ معمولي ترميم آھي",
        "watchthis": "هيءُ صفحو نظر ۾ رکو",
        "preview": "پيش نگاھ",
        "showpreview": "پيش نگاھ",
        "showdiff": "تبديليون ڏيکاريو",
+       "blankarticle": "<strong>چتاءُ:</strong> اوهان خيالي صفحو تخليق ڪري رهيا آهيو.\nجيڪڏهن اوهان «$1» تي ٻيهر ڪلڪ ڪريو، ته هي صفحو بغير ڪنهن مواد جي ڇاپيو ويندو.",
        "anoneditwarning": "<strong>چتاءُ:</strong> توھان داخل ٿيل نہ آھيو. توھان جو آءِپي پتو عوامي طور ظاھر ٿيندو جي توھان ڪي ترميمون ڪريو ٿا. جيڪڏھن توھان <strong>[$1 داخل ٿيو]</strong> ٿا يا <strong>[$2 کاتو کوليو]</strong> ٿا، تہ ٻين فائدن سان گڏ توھان جون ترميمون توھان جي واپرائيندڙ-نانءَ سان منسوب ڪيون وينديون.",
        "anonpreviewwarning": "توهان داخل ٿيل نہ آهيو. جيڪڏهن توهان صفحي ۾ تبديليون سانڍيون تہ اهڙين تبديلين ساڻ توهان جو آءِپي پتو درج ڪيو ويندو.",
        "missingcommenttext": "براءِ مھرباني ڪو تاثر درج ڪندا.",
        "summary-preview": "تت جي پيش نگاھ:",
        "subject-preview": "موضوع جي پيش نگاھ:",
        "blockedtitle": "واپرائيندڙ بندشيل آهي",
-       "blockedtext": "'''توھان جي واپرائيندڙ-نانءُ يا آءِ پي کي بندشيو ويو آھي.'''\n\nبندش $1 ھنئي. جڏھن تہ ڄاڻايل سبب ''$2'' آهي.\n\n\n* بندش جو آغاز: $8\n* بندش جو انجام: $6\n* بندش جو هدف: $7\n\nاھڙي روڪ تي بحث ڪرڻ لاءِ توھان $1 يا ڪنھن ٻي [[{{MediaWiki:Grouppage-sysop}}|منتظم]] سان رابطو ڪري سگھو ٿا. جيڪڏهن توھان جو درست [[Special:Preferences|کاتي جي ترجيحن]] ۾ درست برقٽپال پتو درج ٿيل نہ آهي تہ توهان 'هن واپرائيندڙ کي برقٽپال ڪريو' وارو فيچر نہ ٿا \nاستعمال ڪري سگھو. توھان جو ھاڻوڪو آءِپي پتو $3 آھي، ۽ بندش سڃاڻپ $5 آهي. مھرباني ڪري ڪنھن بہ پڇا ڳاڇا يا لھ و چڙھ لاءِ انھن مان ڪنھن ھڪ يا ٻنھي جو حوالو ڏيندا.",
+       "blockedtext": "<strong>توھان جي واپرائيندڙ-نانءُ يا آءِ پي کي بندشيو ويو آھي.</strong>\n\nبندش $1 ھنئي. جڏھن تہ ڄاڻايل سبب ''$2'' آهي.\n\n\n* بندش جي شروعات: $8\n* بندش جي پڄاڻي: $6\n* بندش جو هدف: $7\n\nاھڙي روڪ تي بحث ڪرڻ لاءِ توھان $1 يا ڪنھن ٻي [[{{MediaWiki:Grouppage-sysop}}|منتظم]] سان رابطو ڪري سگھو ٿا. جيڪڏهن توھان جو درست [[Special:Preferences|کاتي جي ترجيحن]] ۾ درست برقٽپال پتو درج ٿيل نہ آهي تہ توهان 'هن واپرائيندڙ کي برقٽپال ڪريو' وارو فيچر نہ ٿا \nاستعمال ڪري سگھو. توھان جو ھاڻوڪو آءِپي پتو $3 آھي، ۽ بندش سڃاڻپ $5 آهي. مھرباني ڪري ڪنھن بہ پڇا ڳاڇا يا لھ و چڙھ لاءِ انھن مان ڪنھن ھڪ يا ٻنھي جو حوالو ڏيندا.",
        "blockednoreason": "سبب اڻڄاڻايل",
        "whitelistedittext": "صفحا سنوارڻ لاءِ مھرباني ڪري $1.",
        "confirmedittext": "صفحا سنوارڻ کان اڳ توھان کي پنھنجي برقٽپال پتي جي تصديق ڪرڻي پوندي.\nمھرباني ڪري [[Special:Preferences|واپرائيندڙ جي ترجيحن]] ذريعي پنھنجو برقٽپال پتو ڄاڻايو ۽ تصديقيو.",
        "newarticletext": "توھان اھڙي صفحي جو ڳنڍڻو وٺي ھتي پھتا آھيو، جيڪو اڃا وجود نٿو رکي.\nاھڙو صفحو جوڙڻ لاءِ، ھيٺين دٻي ۾ لکڻ شروع ڪريو (وڌيڪ ڄاڻڻ لاءِ [$1 امدادي صفحو] ڏسندا).\nجي توھان ھتي غلطيءَ ۾ اچي ويا آهيو، تہ رڳو پنھنجي جھانگُوءَ جي <strong>back</strong> بٽڻ تي ٽڙڪ ڪريو.",
        "noarticletext": "في‌الوقت هن صفحي اندر ڪو بہ ٽيڪسٽ نہ آهي.\nتوهان ٻين صفحن ۾ [[Special:Search/{{PAGENAME}}|search ساڳي عنوان جي ڳولا]] ڪري سگھو ٿا،  \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 وجود نٿو رکي.\n\nاڪثر اهو تڏهن ٿيندو آهي، جڏهن اوهان ڪنهن پراڻي ڳنڍڻي تان اچو يا صفحو [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} ڊاٺو] ويو هجي.\n\n.",
        "userpage-userdoesnotexist-view": "واپرائيندڙ کاتو $1 درج ٿيل نہ آهي.",
        "blocked-notice-logextract": "هيءُ واپرائيندڙ في‌الحال بندشيل آهي.\nتازو بندش لاگ حوالي طور پيش ڪجي ٿو:",
        "updated": "(تجديديل)",
        "compareselectedversions": "چونڊيل پرت ڀيٽيو",
        "editundo": "اڻڪريو",
        "diff-empty": "(ڪو بہ تفاوت ڪونھي)",
+       "diff-multi-sameuser": "({{PLURAL:$1|هڪ تڪڙو مسودو|$1 تڪڙا مسودا}} ساڳي واپرائيندڙ طرفان ظهار نه ٿيندا)",
        "searchresults": "ڳولا نتيجا",
        "searchresults-title": "”$1“ لاءِ ڳولا نتيجا",
        "titlematches": "صفحي جو عنوان مشابھت رکي ٿو",
        "prevn": "پويان {{PLURAL:$1|$1}}",
        "nextn": "اڳيان {{PLURAL:$1|$1}}",
        "prev-page": "اڳوڻو صفحو",
-       "next-page": "ايندڙ صفحو",
+       "next-page": "اڳيون صفحو",
        "prevn-title": "{{PLURAL:$1|پويون|پويان}} $1 {{PLURAL:$1|نتيجو|نتيجا}}",
        "nextn-title": "{{PLURAL:$1|ٻيو|ٻيا}} $1 {{PLURAL:$1|نتيجو|نتيجا}}",
        "shown-title": "$1 {{PLURAL:$1|نتيجو|نتيجا}} في صفحو ڏيکاريو",
        "prefs-email": "برقٽپال چارا",
        "prefs-rendering": "حليو",
        "saveprefs": "سانڍيو",
+       "restoreprefs": "شروعاتي ترتيبون واپس ڪيو (سمورن خانن ۾)",
        "prefs-editing": "سنوارڻ",
        "searchresultshead": "ڳولا",
        "stub-threshold-sample-link": "نمونو",
        "timezoneregion-indian": "سنڌي ساگر",
        "timezoneregion-pacific": "ماٺو ساگر",
        "allowemail": "ٻين واپرائيندڙن کي مون ڏانھن برقٽپال ڪرڻ جي اجازت ڏيو",
+       "email-allow-new-users-label": "نوان واپرائيندڙ برق ٽپال موڪلين",
+       "email-blacklist-label": "هنن واپرائندڙن کي مون ڏانهن برقٽپال ڪرڻ جي اجازت نه ڏيو:",
        "prefs-searchoptions": "ڳولا",
        "prefs-namespaces": "نانءُپولار",
        "default": "ڏنل",
        "prefs-files": "فائيلس",
+       "prefs-reset-intro": "اوهان هن صفحي جي مدد سان مرتب ڪيل ترجيحات کي اصل ترجيحات ۾ بدلائي سگھو ٿا.\nياد رکو، هي عمل واپس نٿو ٿي سگھي.",
        "prefs-emailconfirm-label": "برقٽپال خاطري:",
        "youremail": "برقٽپال:",
        "username": "{{GENDER:$1|واپرائيندڙ-نانءُ}}",
        "yourrealname": "اصل نالو:",
        "yourlanguage": "ٻولي:",
        "yournick": "نئين صحيح:",
+       "prefs-help-signature": "بحث صفحي تي رايا ڏيڻ وقت هن نشانين ذريعي \"<nowiki>~~~~</nowiki>\" دستخط ڪيو، جيڪي پاڻ مرادو توهان جي دستخط ۽ وقت ۾ تبديل ٿي ويندا.",
        "badsiglength": "اها صحيح هيڪاندي ڊگھي آهي.\nاها وڌ ۾ وڌ $1 {{PLURAL:$1|اکر|اکرن}} تي ٻڌل هوڻ گھرجي.",
        "yourgender": "توهان ڪهڙو تعارف چاهيندا؟",
        "gender-unknown": "توهان جو ذڪر ڪندي، جيترو ٿي سگھيو، منطقگري بي جنس لفظن جو استعمال ڪندي.",
        "gender-male": "هيءُ وڪي صفحا سنواريندو آهي",
        "gender-female": "هيءَ وڪي صفحا سنواريندي آهي",
+       "prefs-help-gender": "هن ترجيح جي تربيت اختياري آهي.\nاوهان يا ٻين واپرائيندڙن جو سافٽويئر ويليو ذريعي مناسب وياڪرڻي جنس مطابق ذڪر ڪندو.\nهي معلومات عام هوندي.",
        "email": "برقٽپال",
        "prefs-help-realname": "اصل نالو اختياري آهي.\nجيڪڏهن توهان اصل نالو ڄاڻائڻ جو فيصلو ٿا ڪريو، تہ اهو توهان کي توهان جي ڪم جي مڃتا ڏيڻ لاءِ ڪم آندو ويندو.",
        "prefs-help-email": "برقٽپال ڄاڻائڻ اختياري آهي، پر جڏهن توهان ڳجھولفظ وسري ويندا آهيو، تڏهن ان جو استعمال توهان کي نئون ڳجھولفظ ڏيڻ لاءِ استعمال ڪيو ويندو آهي.",
+       "prefs-help-email-others": "اوهان چونڊ ڪري سگھو ٿا ته اوهان جي ذاتي يا بحث صفحي تي موجود ڳنڍڻي ذريعي ٻيو ڪو واپرائيندڙ اوهان کي برقٽپال ڪري سگھي ٿو يا نه.\nاوهان جو برقٽپال پتو ٻين پاران رابطي ڪرڻ وقت ڳجهو رکيو ويندو.",
        "prefs-help-email-required": "برقٽپال پتو گھربل آهي.",
        "prefs-info": "بنيادي ڄاڻ",
        "prefs-i18n": "بين‌الاقوامڪاري",
        "rcfilters-days-show-days": "$1 {{PLURAL:$1|ڏينھُن|ڏينھَن}}",
        "rcfilters-highlighted-filters-list": "نمايان-ٿيل:$1",
        "rcfilters-quickfilters": "سانڍيل ڇاڻيون",
+       "rcfilters-quickfilters-placeholder-title": "اڃان ڪا به ڇاڻي سانڍيل ناهي",
        "rcfilters-savedqueries-defaultlabel": "سانڍيل ڇاڻيون",
        "rcfilters-savedqueries-rename": "ٻيھر نالو ڏيو",
        "rcfilters-savedqueries-new-name-label": "نالو",
        "recentchangeslinked-feed": "لاڳاپيل تبديليون",
        "recentchangeslinked-toolbox": "لاڳاپيل تبديليون",
        "recentchangeslinked-title": "\"$1\" سان لاڳاپيل تبديليون",
+       "recentchangeslinked-summary": "تبديليون ڏسڻ لاءِ صفحي جو نالو هڻو پوءِ اها هن صفحي تي هجن يا ڳنڍيل صفحي تي. (زمري جارُڪن ڏسڻ لاءِ، {{ns:زمرو}}:زمري جو نالو)هڻو. [[Special:Watchlist|your Watchlist]] صفحي تي تبديليون <strong>bold</strong> ۾ آهن.",
        "recentchangeslinked-page": "صفحي جو نالو:",
        "recentchangeslinked-to": "رڳو ڄاڻايل صفحي سان ڳانڍيل صفحن ۾ ٿيل تبديليون نمايو",
        "upload": "فائيل چاڙھيو",
        "uploadnologin": "داخل ٿيل ناھيو",
        "uploadnologintext": "فائيل چاڙهڻ لاءِ $1.",
        "uploaderror": "چاڙھ چُڪَ",
+       "uploadtext": "فائل چاڙهڻ لاءِ هيٺيون فارم استعمال ڪيو.\nپراڻا چاڙهيل فائل ڏسڻ يا ڳولڻ لاءِ [[Special:FileList|چاڙهيل فائلن جي فهرست]] تي وڃو، ٻهير چاڙهيل فائل [[Special:Log/upload|چاڙهيل لاگ]] ۽ ختم ڪيل [[Special:Log/delete|ڊاٺ لاگ]] تي ڏسي سگھجن ٿا.\n\nفائل جي استعمال لاءِ هيٺ ڏيکاريل طريقو استعمال ڪري سگھجي ٿو:\n* <strong><code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:فائل جو نالو.jpg]]</nowiki></code></strong> فائل جي مڪمل استعمال لاءِ\n* <strong><code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:فائل جو نالو.png|200px|thumb|left|متبادل اکر]]</nowiki></code></strong> هن جي مدد سان تصوير جي سائيز ڏئي سگھجي ٿي جيئن 200 پگزل\n* <strong><code><nowiki>[[</nowiki>{{ns:media}}<nowiki>:File.ogg]]</nowiki></code></strong> فائل کي ڏيکارڻ کان بغير شامل ڪرڻ",
        "uploadlogpage": "چاڙھ لاگ",
        "filename": "فائيل نانءُ",
-       "filedesc": "تÙ\8eتÙ\8f",
-       "fileuploadsummary": "تÙ\8eتÙ\8f:",
+       "filedesc": "Ø®Ù\84اصÙ\88",
+       "fileuploadsummary": "Ø®Ù\84اصÙ\88:",
        "filereuploadsummary": "فائيل تبديليون:",
        "filesource": "ذريعو:",
        "ignorewarnings": "چتائن کي نظرانداز ڪريو",
        "emailuser": "هن واپرائيندڙ کي برقٽپال اماڻيو",
        "emailuser-title-target": "ھن {{GENDER:$1|واپرائيندڙ}} ڏانھن برقٽپال موڪليو",
        "emailuser-title-notarget": "واپرائيندڙ ڏانھن برقٽپال اماڻيو",
+       "emailpagetext": "هيٺ ڏنل فارم جي ذريعي اوهان هن {{GENDER:$1|واپرائيندڙ}} کي برقي ٽپال پيغام موڪلي سگھو ٿا. جيڪو برق ٽپال پتو اوهان [[Special:Preferences|پنهنجي ترجيحات]] ۾ ڏنو آهي اهو هتي \"کان\" جي طور نظر ايندو، جيئن وصول ڪندڙ اوهان کي سڌو جواب ڏئي سگھي.",
        "usermaildisabled": "واپرائيندڙ برقٽپال ناقابلِڪار بڻيل",
        "usermaildisabledtext": "توهان هن وڪي تي ٻين واپرائيندڙن ڏانهن برقٽپال نٿا موڪلي سگھو",
        "noemailtitle": "برقٽپال پتو ناھي",
        "protectlogpage": "تحفظ لاگ",
        "protectedarticle": "محفوظ ٿيل \"[[$1]]\"",
        "modifiedarticleprotection": "\"[[$1]]\" جي تحفظ جي سطح تبديل ڪئي",
+       "movedarticleprotection": "\"[[$2]]\" جو حفاظت درجو \"[[$1]]\" جي طرف منتقل ڪيو",
        "prot_1movedto2": "[[$1]] کي چوري [[$2]] تي رکيو ويو",
        "protect-legend": "تحفظڻ جي پڪ ڪريو",
        "protectcomment": "سبب:",
        "anoncontribs": "ڀاڱيداريون",
        "contribsub2": "{{GENDER:$3|$1}} ($2) لاءِ",
        "contributions-userdoesnotexist": "واپرائيندڙ کاتو \"$1\" درج ٿيل نہ آهي.",
+       "nocontribs": "هن معيار تي ڪي به ترميمون نه لڌيون.",
        "uctop": "(هاڻوڪو)",
        "month": "مھيني کان (۽ اڳوڻيون):",
        "year": "سال کان (۽ اڳوڻيون):",
        "whatlinkshere": "هتان ڇا ڳنڍيل آهي",
        "whatlinkshere-title": "\"$1\" سان ڳنڍيندڙ صفحا",
        "whatlinkshere-page": "صفحو:",
-       "linkshere-2": "هيٺيان صفحا <strong>$1</strong> سان ڳنڍيل آهن:",
-       "nolinkshere-2": "'''$1''' سان ڪو بہ صفحو ڳنڍيل ناهي.",
+       "linkshere": "هيٺيان صفحا <strong>$2</strong> سان ڳنڍيل آهن:",
+       "nolinkshere": "'''$2''' سان ڪو بہ صفحو ڳنڍيل ناهي.",
        "isredirect": "چورڻو صفحو",
        "istemplate": "شموليت",
        "isimage": "فائيل جو ڳنڍڻو",
        "whatlinkshere-next": "{{PLURAL:$1|اڳيون|اڳيان $1}}",
        "whatlinkshere-links": "← ڳنڍڻا",
        "whatlinkshere-hideredirs": "$1 چوري ٿو",
+       "whatlinkshere-hidetrans": "$1 شموليت",
        "whatlinkshere-hidelinks": "$1 ڳنڍڻا",
        "whatlinkshere-hideimages": "$1 ڳنڍي ٿو",
        "whatlinkshere-filters": "ڇاڻيون",
        "block": "واپرائيندڙ کي بندشيو",
        "unblock": "واپرائيندڙ کي اڻبندشيو",
        "blockip": "{{GENDER:$1|واپرائيندڙ}} تي بندش وجھو",
+       "ipaddressorusername": "آئي پي پتو يا واپرائيندڙ-نانءُ:",
        "ipbexpiry": "اختتام:",
        "ipbreason": "سبب:",
        "ipbother": "ٻيو وقت:",
        "ipb-confirm": "بندش جي پڪ ڪريو",
        "badipaddress": "ناقابلڪار آءِ پي پتو",
        "blockipsuccesssub": "بندش ڪامياب ٿي",
+       "ipb-blockingself": "اوهان پنهنجي پاڻ تي بندش وجهي رهيا آهيو! ڇا اوهان اهو ڪرڻ پسند ڪندو؟",
        "unblockip": "واپرائيندڙ کي اڻبندشيو",
        "ipusubmit": "اها بندش هٽايو",
        "unblocked-range": "$1 تان بندش هٽي چڪي آهي.",
        "unlockbtn": "اعدادخاني کي کوليو",
        "move-page": "$1 چوريو",
        "move-page-legend": "صفحو چوريو",
-       "movepagetext": "هيٺيون فارم استعمال ڪندي ڪنهن صفحي کي نئون عنوان ڏئي سگھجي ٿو، جنهن سان سمورو صفحو نئين عنوان ڏانهن هليو ويندو. \nاڳوڻو عنوان نئين عنوان ڏانهن چورڻو بنجي ويندو. \nتوهان  چورڻن کي سنواري سگھو ٿا جيڪي اصل عنوان ڏانهن خودبخود اشارو ڪن ٿا.\nIf you choose not to, be sure to check for [[Special:DoubleRedirects|double]] or [[Special:BrokenRedirects|broken redirects]].\nان ڳالهه جي پڪ ڪرڻ ذميواري توهان تي آهي ته ڳنڍڻا اتي ئي وٺي وڃن ٿا جتي انهن کي وٺي وڃڻ گھرجي.\n\nياد رکندا ته جيڪڏهن نئين عنوان سان اڳي ئي ڪو مضمون موجود آهي ته پوءِ صفحو '''نه''' چوريو ويندو، سوا ان جي ته موجوده صفحو محظ خالي آهي يا ڪا به سوانح نه رکندڙ ڪو چورڻو آهي.\n\n<strong>نوٽ!</strong>\nاها هڪ مقبول صفحي لاءِ ڪا غير متوقه ۽ انتهائي اڻوڻندڙ تبديلي ثابت ٿي سگھي ٿي؛ براءِ مهرباني اڳتي وڌڻ کان اڳ پڪ ڪندا ته توهان اها تبديلي آڻڻ جي نتيجن کان چڱيءَ ريت واقف آهيو.",
+       "movepagetext": "هيٺيون فارم استعمال ڪندي ڪنهن صفحي کي نئون عنوان ڏئي سگھجي ٿو، جنهن سان سمورو صفحو نئين عنوان ڏانهن هليو ويندو. \nاڳوڻو عنوان نئين عنوان ڏانهن چورڻو بنجي ويندو. \nتوهان  چورڻن کي سنواري سگھو ٿا جيڪي اصل عنوان ڏانهن خودبخود اشارو ڪن ٿا.\nانهي ڳالهه جي پڪ ڪري وٺو ته [[Special:BrokenRedirects|ٽٽل چورڻا]] يا [[Special:DoubleRedirects|ٻٽا چورڻا]] نه هجن.\nان ڳالهه جي پڪ ڪرڻ ذميواري توهان تي آهي ته ڳنڍڻا اتي ئي وٺي وڃن ٿا جتي انهن کي وٺي وڃڻ گھرجي.\n\nياد رکندا ته جيڪڏهن نئين عنوان سان اڳي ئي ڪو مضمون موجود آهي ته پوءِ صفحو '''نه''' چوريو ويندو، سوا ان جي ته موجوده صفحو محظ خالي آهي يا ڪا به سوانح نه رکندڙ ڪو چورڻو آهي.\n\n<strong>نوٽ!</strong>\nاها هڪ مقبول صفحي لاءِ ڪا غير متوقه ۽ انتهائي اڻوڻندڙ تبديلي ثابت ٿي سگھي ٿي؛ براءِ مهرباني اڳتي وڌڻ کان اڳ پڪ ڪندا ته توهان اها تبديلي آڻڻ جي نتيجن کان چڱيءَ ريت واقف آهيو.",
+       "movepagetext-noredirectfixer": "هيٺيون فارم استعمال ڪندي ڪنهن صفحي کي نئون عنوان ڏئي سگھجي ٿو، جنهن سان سمورو صفحو نئين عنوان ڏانهن هليو ويندو. \nاڳوڻو عنوان نئين عنوان ڏانهن چورڻو بنجي ويندو. \nتوهان  چورڻن کي سنواري سگھو ٿا جيڪي اصل عنوان ڏانهن خودبخود اشارو ڪن ٿا.\nانهي ڳالهه جي پڪ ڪري وٺو ته [[Special:BrokenRedirects|ٽٽل چورڻا]] يا [[Special:DoubleRedirects|ٻٽا چورڻا]] نه هجن.\nان ڳالهه جي پڪ ڪرڻ ذميواري توهان تي آهي ته ڳنڍڻا اتي ئي وٺي وڃن ٿا جتي انهن کي وٺي وڃڻ گھرجي.\n\nياد رکندا ته جيڪڏهن نئين عنوان سان اڳي ئي ڪو مضمون موجود آهي ته پوءِ صفحو '''نه''' چوريو ويندو، سوا ان جي ته موجوده صفحو محظ خالي آهي يا ڪا به سوانح نه رکندڙ ڪو چورڻو آهي.\n\n<strong>نوٽ!</strong>\nاها هڪ مقبول صفحي لاءِ ڪا غير متوقه ۽ انتهائي اڻوڻندڙ تبديلي ثابت ٿي سگھي ٿي؛ مهرباني ڪري اڳتي وڌڻ کان اڳ پڪ ڪندا ته توهان اها تبديلي آڻڻ جي نتيجن کان چڱيءَ ريت واقف آهيو.",
        "movepagetalktext": "جيڪڏهن توهان هن خاني کي نشان لڳائيندئو، واسطيدار مباحثي صفحو پاڻ ئي چوريو ويندو ماسواءِ اتي ڪو اڳ ئي ڪو غيرخالي مباحثي صفحو موجود هجي.\n\nان صورت ۾، جيڪڏهن توهان چاهيو ته صفحي کي پاڻ چوري يا ضم ڪري سگھو ٿا.",
+       "movecategorypage-warning": "<strong>چتاءُ:</strong> اوهان زمري واري صفحي کي چورڻ وڃي رهيا آهيو. ياد رکو صرف صفحو چورندو، جيڪڏهن ڪي به صفحا پراڻي زمري ۾ شامل آهن، انهن جي نئين زمري ۾ درجابندي <em>نه</em> ٿيندي.",
        "movenotallowed": "توهان کي صفحا چورڻ جي اجازت حاصل ڪانهي.",
        "movenotallowedfile": "توهان کي فائيلس چورڻ جي اجازت حاصل ڪانهي.",
        "newtitle": "نئون عنوان:",
        "movepagebtn": "صفحو چوريو",
        "pagemovedsub": "چورڻ جو عمل ڪامياب ٿيو",
        "movepage-moved": "'''\"$1\" کي چوري \"$2\" تي رکيو ويو آهي'''",
+       "movepage-moved-redirect": "چورڻو مڪمل ٿيو.",
        "articleexists": "ان نالي سان صفحو اڳي ئي وجود رکي ٿو، يا ته توهان جو ڏنل نالو ناقابلڪار آهي.",
        "movetalk": "لاڳاپيل مباحثي صفحو چوريو",
        "movelogpage": "چورڻ لاگ",
        "tooltip-compareselectedversions": "هن صفحي جن ٻن چونڊيل پرتن درميان تفاوت ڏسو.",
        "tooltip-watch": "هيءُ صفحو پنهنجي نظر ۾ فھرست ۾ شامل ڪريو",
        "tooltip-rollback": "\"واپس ورايو\" ھن صفحي ۾ پوئين ڀاڱيدار جي ڪيل ترميم(ن) کي ھڪ ٽڙڪ سان اڻڪري ٿو",
+       "tooltip-undo": "\"اڻڪريو\" هن ترميم کي واپس ڪيو ۽ پيش نگاه ۾ ترميم کي کوليو. اهو اوهان کي تت شامل ڪرڻ جو موقعو ڏيندو.",
        "tooltip-preferences-save": "ترجيحون سانڍيو",
        "tooltip-summary": "ننڍو خلاصو ڏيو",
        "anonymous": "{{SITENAME}} جا گمنام {{PLURAL:$1|واپرائيندڙ|واپرائيندڙَ}}",
        "pageinfo-language": "صفحي جي مواد جي ٻولي",
        "pageinfo-content-model": "صفحي جي مواد جو ماڊل",
        "pageinfo-robot-index": "اجازت ڏنل",
+       "pageinfo-robot-noindex": "اجازت ناهي",
        "pageinfo-watchers": "صفحا ڏسندڙن جو انگ",
        "pageinfo-few-watchers": "$1 کان گھٽ {{PLURAL:$1|ڏسندڙ}}",
        "pageinfo-redirects-name": "ھن صفحي ڏانھن ڇوريل صفحن جو انگ",
        "file-info-gif-frames": "$1 {{PLURAL:$1|فريم|فريمَ}}",
        "file-info-png-frames": "$1 {{PLURAL:$1|فريم|فريمَ}}",
        "newimages": "نون فائيلن جي گيلري",
+       "newimages-user": "آئي پي پتو يا واپرائيندڙ-نانءُ",
        "noimages": "ڏسڻ لاءِ ڪجھہ ناهي.",
        "ilsubmit": "ڳوليو",
        "bydate": "تاريخوار",
        "sunday-at": "$1 بجي آچر",
        "yesterday-at": "$1 بجي ڪالهہ",
        "metadata": "اعدادِ اعداد",
+       "metadata-help": "هن فائل ۾ وڌيڪ ڄاڻ موجود آهي، جيڪو ڪنهن ڊجيٽل ڪيمرا يا اسڪينر متعلق آهي،  جنهن سان هي عڪس چٽيو ويو آهي. \nجيڪڏهن فائل ترميم ڪيل هجي ته پوءِ ممڪن آهي ته ڪجه ڄاڻ ضايع ٿي چڪو هجي.",
        "metadata-expand": "توسيعي تفصيل ڏيکاريو",
        "metadata-collapse": "توسيعي تفصيل لڪايو",
        "metadata-fields": "عڪس جي ميٽا ڊيٽا فيلڊ لسٽ ڪيل آهي هن پيغام ۾ جيڪو شامل ڪيو ويندو عڪس جي صفحي جي ڊسپلي تي، جڏهن ميٽا ڊيٽا جي ٽيبل ختم ٿيندي، ٻيا طئي ٿيل طريقي سان لڪل هوندا. \n* make\n* model\n* datetimeoriginal\n* exposuretime\n* fnumber\n* isospeedratings\n* focallength\n* artist\n* copyright\n* imagedescription\n* gpslatitude\n* gpslongitude\n* gpsaltitude",
        "exif-software": "مستعمل منطقگري",
        "exif-artist": "ليکڪ",
        "exif-copyright": "حق ۽ واسطا رکندڙ",
+       "exif-exifversion": "اِي ايڪس آئي ايف ورشن",
        "exif-colorspace": "رنگ پولار",
        "exif-pixelxdimension": "عڪس جي ويڪر",
        "exif-pixelydimension": "عڪس جي اوچائي",
        "confirmemail_success": "توهان جي برقٽپال پتي جي تصديق ڪئي وئي آهي.\nهاڻ توهان [[Special:UserLogin|داخل ٿي]] ۽ وڪي جو مزو وٺي سگھو ٿا.",
        "confirmemail_loggedin": "توهان جي برقٽپال پتي جي تصديق هاڻي ٿي چڪي آهي.",
        "confirmemail_subject": "{{SITENAME}} برقٽپال پتي جي تصديق",
+       "confirmemail_body": "ڪنهن، شايد اوهان جي، هن آئي پي پتي $1 کان {{SITENAME}} ۾ «$2» جي نالي سان کاتو کوليو ۽ هن برق ٽپال کي استعمال ڪيو آهي.\n\nهن ڳالهه جي تصديق ڪري وٺو ته هي کاتو اوهان جو ئي آهي ۽ {{SITENAME}} تي پڻ هي برق ٽپال ڏنل آهي، ته پوءِ هيٺين ڳنڍڻي تي ڪلڪ ڪيو. يا ڪاپي ڪري برائوزر تي کوليو.\n\n$3\n\nجيڪڏهن اوهان کاتي ۾ برق ٽپال رجسٽر *نه* ڪيو آهي ته هيٺين ڳنڍڻي کي ڪلڪ ڪيو يا برائوزر ۾ کوليو:\n\n$5\n\nهن ڪوڊ جي تصديقي جي مدت $4 تي ختم ٿي ويندي.",
        "recreate": "ورسرجيو",
        "confirm-watch-button": "ٺيڪ",
        "confirm-watch-top": "هيءُ صفحو پنهنجي نظر ۾ فھرست ۾ شامل ڪندا؟",
        "watchlisttools-view": "لاڳاپيل تبديليون ڏسو",
        "watchlisttools-edit": "نظر ۾ فهرست ڏسو ۽ سنواريو",
        "watchlisttools-raw": "ڪچي نظر ۾ فھرست سنواريو",
+       "hijri-calendar-m1": "محرم",
+       "hijri-calendar-m2": "صفر",
+       "hijri-calendar-m3": "ربيع الاول",
+       "hijri-calendar-m4": "ربيع الثاني",
+       "hijri-calendar-m5": "جمادي الاول",
+       "hijri-calendar-m6": "جمادي الثاني",
+       "hijri-calendar-m7": "رجب",
+       "hijri-calendar-m8": "شعبان",
+       "hijri-calendar-m9": "رمضان",
+       "hijri-calendar-m10": "شوال",
+       "hijri-calendar-m11": "ذوالقعد",
+       "hijri-calendar-m12": "ذوالحج",
        "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|ڳالھ]])",
        "version": "ڀيرو",
        "version-extensions": "تنصيب شده توسيعات",
        "tag-filter": "[[Special:Tags|ٽيگ]] ڇاڻي:",
        "tag-filter-submit": "ڇاڻي",
        "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|ٽيگ|ٽيگز}}]]: $2)",
+       "tag-mw-new-redirect": "نئون چوريل",
+       "tag-mw-blank": "خالي",
        "tag-mw-rollback-description": "واپس-ورايو ڳنڍڻي کي استعمال ڪندي پوين ترميمن کي واپس ورائيندڙ ترميمون",
        "tags-title": "ٽيگس",
        "tags-tag": "ٽيگ نانءُ",
        "logentry-delete-revision": "$1 $3: $4 صفحي تي {{PLURAL:$5|ھڪ مسودي|$5 مسودن}} جي ظاھريت {{GENDER:$2|تبديل ڪئي}}",
        "revdelete-content-hid": "مواد لڪيل",
        "revdelete-uname-hid": "واپرائيندڙ-نانءُ لڪل",
+       "logentry-block-block": "$1، {{GENDER:$4|$3}} تي $5 وقت جي خاتمي تائين {{GENDER:$2|بندش هئي آهي}} $6",
        "logentry-move-move": "$1 {{GENDER:$2|چوريو}} صفحو $3 ڏانهن $4",
        "logentry-move-move-noredirect": "$1 $3 صفحي کي $4 ڏانھن {{GENDER:$2|چوريو}} سواءِ ڪو ريڊائريڪٽ ڇڏيندي",
        "logentry-move-move_redir": "$1 $3 کي $4 ڏانھن ريڊائريڪٽ مٿان {{GENDER:$2|چوريو}}",
        "logentry-patrol-patrol-auto": "$1 پاڻمرادو صفحي $3 جي $4 مسودي تي گشت ڪيل طور {{GENDER:$2|نشان لڳايو}}",
        "logentry-newusers-create": "واپرائيندڙ کاتو $1 {{GENDER:$2|سرجيو ويو}}",
        "logentry-newusers-autocreate": "واپرائيندڙ کاتو $1 پاڻمرادو {{GENDER:$2|تخليق ڪيو}} ويو",
+       "logentry-protect-protect": "$1 {{GENDER:$2|محفوظ ڪيو}} $3 $4",
        "logentry-upload-upload": "$1 {{GENDER:$2|چاڙهيو}} $3",
        "logentry-upload-overwrite": "$1 $3 جو ھڪ نئون ورزن {{GENDER:$2|چاڙھيو}}",
        "rightsnone": "(ڪو بہ نہ)",
        "mw-widgets-mediasearch-noresults": "ڪي-بہ نتيجا نہ لڌا.",
        "mw-widgets-titleinput-description-new-page": "اڃا اهو صفحو وجود نہ ٿو رکي",
        "mw-widgets-titleinput-description-redirect": "$1 ڏانهن چوريل",
+       "mw-widgets-usersmultiselect-placeholder": "وڌيڪ شامل ڪيو...",
        "date-range-from": "تاريخ کان:",
        "date-range-to": "تاريخ تائين:",
        "log-action-filter-all": "سڀ"
index 6976bd4..69434b2 100644 (file)
        "whatlinkshere": "Puntani inogghi",
        "whatlinkshere-title": "Pàgini chi pùntani a \"$1\"",
        "whatlinkshere-page": "Pàgina:",
-       "linkshere-2": "Li sighenti pàgini cuntenani cullegamenti a '''$1''':",
-       "nolinkshere-2": "Nisciuna pàgina cunteni dei cullegamenti chi pùntani a '''$1'''.",
-       "nolinkshere-ns-2": "Nò vi so pàgini chi pùntani a '''$1''' i' lu namespace sciubaraddu.",
+       "linkshere": "Li sighenti pàgini cuntenani cullegamenti a '''$2''':",
+       "nolinkshere": "Nisciuna pàgina cunteni dei cullegamenti chi pùntani a '''$2'''.",
+       "nolinkshere-ns": "Nò vi so pàgini chi pùntani a '''$2''' i' lu namespace sciubaraddu.",
        "isredirect": "rinviu",
        "istemplate": "incrusioni",
        "isimage": "Cullegamentu a file",
index c39abf8..d952dd4 100644 (file)
        "whatlinkshere": "بەسیارەگان وە ئێرە",
        "whatlinkshere-title": "ئەو پەڕەیلە ک وە «$1» بەسیار دێرن",
        "whatlinkshere-page": "پەڕە:",
-       "linkshere-2": "ئەی پەڕەیلە بەستیار دێرن وە '''$1''':",
-       "nolinkshere-2": "هۊچ لاپەڕەێگ بەسیار وە '''$1''' نەێرێد .",
+       "linkshere": "ئەی پەڕەیلە بەستیار دێرن وە '''$2''':",
+       "nolinkshere": "هۊچ لاپەڕەێگ بەسیار وە '''$2''' نەێرێد .",
        "isredirect": "پەڕەێ ڕەوانەکەر",
        "istemplate": "ناوتەپیاێەگان (transclusions)",
        "isimage": "بەسیار پەڕگە",
index a33423a..6db5b71 100644 (file)
        "sp-contributions-submit": "Oza",
        "whatlinkshere": "Siiddut mat čujuhit deike",
        "whatlinkshere-title": "Siiddut mat čujuhit $1",
-       "linkshere-2": "Čuovvovaš siidduin lea liŋka siidui <strong>$1</strong>:",
-       "nolinkshere-2": "Siidui <strong>$1</strong> eai leat liŋkkat.",
-       "nolinkshere-ns-2": "Siidui <strong>$1</strong> eai leat liŋkkat válljejuvvon nammagomuvuođas.",
+       "linkshere": "Čuovvovaš siidduin lea liŋka siidui <strong>$2</strong>:",
+       "nolinkshere": "Siidui <strong>$2</strong> eai leat liŋkkat.",
+       "nolinkshere-ns": "Siidui <strong>$2</strong> eai leat liŋkkat válljejuvvon nammagomuvuođas.",
        "isredirect": "ođđasitstivrensiidu",
        "istemplate": "lasihuvvon mállevuođđui",
        "whatlinkshere-prev": "← {{PLURAL:$1|ovddit siidu|$1 ovddit siiddu}}",
index 6e99960..9a26fdc 100644 (file)
        "whatlinkshere": "Kaŋ ga dobu ne",
        "whatlinkshere-title": "Moɲey kaŋ ga dobu \"$1\" ga",
        "whatlinkshere-page": "Moo:",
-       "linkshere-2": "Moɲey wey ga dobu <strong>$1</strong> ga:",
-       "nolinkshere-2": "Mooyaŋ kul ši dobu <strong>$1</strong> ga.",
-       "nolinkshere-ns-2": "Mooyaŋ kul ši dobu <strong>$1</strong> ga maafarru suubantaa ra.",
+       "linkshere": "Moɲey wey ga dobu <strong>$2</strong> ga:",
+       "nolinkshere": "Mooyaŋ kul ši dobu <strong>$2</strong> ga.",
+       "nolinkshere-ns": "Mooyaŋ kul ši dobu <strong>$2</strong> ga maafarru suubantaa ra.",
        "isredirect": "moo kuubi",
        "istemplate": "kanandiyan",
        "isimage": "tuku dobu",
        "markedaspatrollederrornotify": "Goo ma šilbay kaŋ a ga kurandi.",
        "patrol-log-page": "Kuryan taariki",
        "patrol-log-header": "Woo ti filla kurantey taarikoo.",
-       "log-show-hide-patrol": "kuryan taariki $1",
        "deletedrevision": "Filla žeena tuusante $1",
        "filedeleteerror-short": "Tuku tuusuyan firka: $1",
        "filedeleteerror-long": "Firkayaŋ bangay tukoo tuusuyanoo waate:\n\n$1",
index d489059..be33940 100644 (file)
        "whatlinkshere": "Sosėjė̄ straipsnē",
        "whatlinkshere-title": "Poslapē, katrėi ruod i \"$1\"",
        "whatlinkshere-page": "Poslapis:",
-       "linkshere-2": "Anėi poslapē ruod i '''$1''':",
-       "nolinkshere-2": "I '''$1''' nūruodu nier.",
-       "nolinkshere-ns-2": "Nurodītuo vardū srėtī anė vėins poslapis neruod i '''$1'''.",
+       "linkshere": "Anėi poslapē ruod i '''$2''':",
+       "nolinkshere": "I '''$2''' nūruodu nier.",
+       "nolinkshere-ns": "Nurodītuo vardū srėtī anė vėins poslapis neruod i '''$2'''.",
        "isredirect": "nusokėma poslapis",
        "istemplate": "īspraudėms",
        "isimage": "abruozdielė nūruoda",
        "markedaspatrolled": "Pažīmiets kāp patėkrints",
        "markedaspatrolledtext": "Pasėrinkta versėjė siekmingā pažīmieta kāp patėkrinta",
        "patrol-log-page": "Patikrinėma istuorėjė",
-       "log-show-hide-patrol": "$1 patvirtėnėmu saraša",
        "deletedrevision": "Ėštrinta sena versėjė $1.",
        "filedeleteerror-short": "Klaida trėnont faila: $1",
        "previousdiff": "← Onkstesnis pakeitėms",
index d775349..d8a7a88 100644 (file)
@@ -16,7 +16,8 @@
                        "Xð",
                        "Сербијана",
                        "Acamicamacaraca",
-                       "Fitoschido"
+                       "Fitoschido",
+                       "BadDog"
                ]
        },
        "tog-underline": "Podvuci linkove:",
        "whatlinkshere": "Što upućuje ovamo",
        "whatlinkshere-title": "Stranice koje vode / Странице које воде до $1",
        "whatlinkshere-page": "Stranica:",
-       "linkshere-2": "Sljedeće stranice vode na '''$1''':",
-       "nolinkshere-2": "Nema linkova na '''$1'''.",
-       "nolinkshere-ns-2": "Nijedna stranica nije povezana sa '''$1''' u odabranom imenskom prostoru.",
+       "linkshere": "Sljedeće stranice vode na '''$2''':",
+       "nolinkshere": "Nema linkova na '''$2'''.",
+       "nolinkshere-ns": "Nijedna stranica nije povezana sa '''$2''' u odabranom imenskom prostoru.",
        "isredirect": "preusmjeri stranicu",
        "istemplate": "kao šablon",
        "isimage": "link na datoteku",
        "allmessagesname": "Naziv",
        "allmessagesdefault": "Uobičajeni tekst",
        "allmessagescurrent": "Trenutni tekst",
-       "allmessagestext": "Ovo je spisak svih sistemskih poruka u dostupnih u MediaWiki imenskom prostoru.\nMolimo posjetite [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation MediaWiki lokalizaciju] i [https://translatewiki.net translatewiki.net] ako želite doprinijeti općoj lokalizaciji MediaWikija.",
+       "allmessagestext": "Ovo je spisak sistemskih poruka u dostupnih u MediaWiki imenskom prostoru.\nMolimo posjetite [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation MediaWiki lokalizaciju] i [https://translatewiki.net translatewiki.net] ako želite doprinijeti općoj lokalizaciji MediaWikija.",
        "allmessagesnotsupportedDB": "Ova stranica ne može biti korištena jer je '''$wgUseDatabaseMessages''' isključen.",
        "allmessages-filter-legend": "Filter",
        "allmessages-filter": "Filter po stanju podešavanja:",
        "markedaspatrollederrornotify": "Nije uspjelo označavanje ove stranice kao patrolirane.",
        "patrol-log-page": "Evidencija patroliranja",
        "patrol-log-header": "Ovdje se nalazi evidencija patroliranih revizija.",
-       "log-show-hide-patrol": "$1 zapis patroliranja",
        "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",
index 1e52adb..1e285b5 100644 (file)
        "whatlinkshere": "ⵎⴰⴷ ⵉⵜⵜⴰⵡⵉⵏ ⵙ ⵖⵉⴷ",
        "whatlinkshere-title": "ⵜⴰⵙⵏⵉⵡⵉⵏ ⵜⵜⴰⵡⵉⵏⵉⵏ ⵙ \"$1\"",
        "whatlinkshere-page": "ⵜⴰⵙⵏⴰ:",
-       "linkshere-2": "ⵜⴰⵙⵏⵉⵡⵉⵏ ⴰⴷ ⴹⴼⴰⵔⵏⵉⵏ ⴰⵔ ⵜⵜⴰⵡⵉⵏⵜ ⵙ <strong>$1</strong>:",
-       "nolinkshere-2": "ⵓⵍⴰ ⴽⵔⴰ ⵏ ⵜⴰⵙⵏⴰ ⵓⵔ ⴰⵔ ⵜⴻⵜⵜⴰⵡⵉ ⵙ <strong>$1</strong>.",
-       "nolinkshere-ns-2": "Ur tlla kra n tasna izdin d  '''$1''' ɣ tɣult l-ittuystayn.",
+       "linkshere": "ⵜⴰⵙⵏⵉⵡⵉⵏ ⴰⴷ ⴹⴼⴰⵔⵏⵉⵏ ⴰⵔ ⵜⵜⴰⵡⵉⵏⵜ ⵙ <strong>$2</strong>:",
+       "nolinkshere": "ⵓⵍⴰ ⴽⵔⴰ ⵏ ⵜⴰⵙⵏⴰ ⵓⵔ ⴰⵔ ⵜⴻⵜⵜⴰⵡⵉ ⵙ <strong>$2</strong>.",
+       "nolinkshere-ns": "Ur tlla kra n tasna izdin d  '''$2''' ɣ tɣult l-ittuystayn.",
        "isredirect": "Tasna immutin",
        "istemplate": "Illa gis",
        "isimage": "ⴰⵍⵉⵏⴽ ⵏ ⵓⴼⴰⵢⵍⵓ",
        "minutes-ago": "$1 {{PLURAL:$1|ⵜⵓⵙⴷⵉⴷⵜ|ⵜⵓⵙⴷⵉⴷⵉⵏ}} ⴰⵢⴰ",
        "seconds-ago": "$1 {{PLURAL:$1|ⵜⵙⵉⵏⵜ|ⵜⵙⵉⵏⵉⵏ}} ⴰⵢⴰ",
        "bad_image_list": "zud ghikad :\n\nghir lhwayj n lista (stour libdounin s *) karaytyo7asab",
-       "variantname-shi-tfng": "ⵜⴰⵛⵍⵃⵉⵜ",
-       "variantname-shi-latn": "Tašlḥiyt",
-       "variantname-shi": "disable",
+       "variantname-shi-tfng": "",
+       "variantname-shi-latn": "Tacelḥiyt",
+       "variantname-shi": "Tacelḥiyt",
        "metadata": "ⵎⵉⵜⴰⴷⴰⵜⴰ",
        "metadata-help": "ⵢⵓⵙⵢ ⵓⴼⴰⵢⵍⵓ ⴰⴷ ⵓⵎⵍⴰⵏ , lli tfl lkamira tuṭunit niɣd aṣfḍ n uxddam lliɣ ay sgadda asdaw ad.\nⵉⵖ ⵉⵏⴼⵍ ⵓⴼⴰⵢⵍⵓ ⵣⵖ ⴰⴷⴷⴰⴷ ⵏⵏⵙ ⴰⵏⵚⵍⵉ, .",
        "metadata-expand": "Ml ifruriyn lluzzanin",
index 62a1800..10e1ac2 100644 (file)
        "nchanges": "$1 {{PLURAL:$1|လႅၵ်ႈလၢႆႈ|ၸိူဝ်းလႅၵ်ႈလၢႆႈ}}",
        "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|ၸဵမ်မိူဝ်ႈ ၵႂႃႇဢႅတ်ႇပွၵ်ႈၵမ်းလိုၼ်း}}",
        "enhancedrc-history": "ပိုၼ်း",
-       "recentchanges": "á\80\99á\80®á\80¸á\80\9cá\80½á\80\84á\80ºá\82\88á\80\9cá\82\85á\81µá\80ºá\82\88á\80\9cá\81¢á\82\86á\82\88á\80\95á\82\86á\82\87á\82\81á\80­á\80¯á\80\84á\80º",
+       "recentchanges": "á\80\9cá\80½á\80\84á\80ºá\82\88á\80\9cá\82\85á\81µá\80ºá\82\88á\80\9cá\81¢á\82\86á\82\88á\80\99á\82\82á\80ºá\82\87á\80\99á\82\82á\80ºá\82\87",
        "recentchanges-legend": "ၵၼ်လိူၵ်ႈသၢင်ႈ လွင်ႈလႅၵ်ႈလၢႆႈဢၼ်ပူၼ်ႉမႃး",
        "recentchanges-summary": "ၸွမ်းတူၺ်းႁွႆး ဢၼ်ပဵၼ်ၵၢၼ် တိုၵ်ႉႁႃလႅၵ်ႈလၢႆႈၵႂႃႇ တွၼ်ႈတႃႇၼႃႈလိၵ်ႈ ဝီႇၶီႇၼႆႉ။",
        "recentchanges-noresult": "ၼႂ်းၵႃႈၶၢဝ်းယၢမ်း ဢၼ်ပၼ်ဝႆႉ တႃႇၵိုၵ်းတူၺ်း ပိူင်တႅၵ်ႈတႃႇတႅပ်းတတ်းၼၼ်ႉ ဢမ်ႇႁၼ်မီး လွင်ႈလႅၵ်ႈလၢႆႈသင်။",
        "whatlinkshere": "ႁဵင်းၵွင်ႉ ဢၼ်မီးတီႈၼႆႈပဵၼ်သင်",
        "whatlinkshere-title": "ၼႃႈလိၵ်ႈၸိူဝ်းလိင်ႉၸူး \"$1\"",
        "whatlinkshere-page": "ၼႃႈလိၵ်ႈ",
-       "linkshere-2": "ၼႃႈလိၵ်ႈၽၢႆႇတႂ်ႈၼႆႉ မၼ်းၵွင်ႉသၢၼ် ဝႆႉၸူး <strong>$1</strong>:",
-       "nolinkshere-2": "ဢမ်ႇမီးၼႃႈလိၵ်ႈ ၸိူဝ်းၵွင်ႉၸူး<strong>$1</strong>.",
-       "nolinkshere-ns-2": "ဢမ်ႇမီးၼႃႈလိၵ်ႈ ၸိူဝ်းၵွင်ႉၸူး <strong>$1</strong>တီႈၼႂ်း လွၵ်းၸိုဝ်ႈ ဢၼ်လိူၵ်ႈဝႆႉၼၼ်ႉ။",
+       "linkshere": "ၼႃႈလိၵ်ႈၽၢႆႇတႂ်ႈၼႆႉ မၼ်းၵွင်ႉသၢၼ် ဝႆႉၸူး <strong>$2</strong>:",
+       "nolinkshere": "ဢမ်ႇမီးၼႃႈလိၵ်ႈ ၸိူဝ်းၵွင်ႉၸူး<strong>$2</strong>.",
+       "nolinkshere-ns": "ဢမ်ႇမီးၼႃႈလိၵ်ႈ ၸိူဝ်းၵွင်ႉၸူး <strong>$2</strong>တီႈၼႂ်း လွၵ်းၸိုဝ်ႈ ဢၼ်လိူၵ်ႈဝႆႉၼၼ်ႉ။",
        "isredirect": "ပိၼ်ႇႁူဝ်ၼႃႈလိၵ်ႈ",
        "istemplate": "တူဝ်ၶဝ်ႈပႃး",
        "isimage": "ၾၢႆႇၵွင်ႉ",
index 170c9b8..a1493ae 100644 (file)
        "search-ignored-headings": "#<!-- eǧǧ izirigen-agi akken llan --><pre>\n# Izwal n tgezmiyin ad ttwazeglen deg unadi\n# Ibeddilen yettwagen dagi ad ddun ticki asebter s uzwel yettwarna ar umatar.\n# Tzemreḍ ad ḥettmeḍ tulsa n tmerna ar umatar n usebter s usnifel ilem\n# Taseddast d tagi :\n#   * Yal iziirig ibeddun s \"#\" d awennit\n#   * Yal izirig yeččuren d azwel ara tzegleḍ, ula d taṛuzi n usekkil\nTimsisɣal\nIseɣwan izɣarayen\nWali daɣen\n #</pre><!-- eǧǧ izirig-agi akken yella -->",
        "searchbutton": "Iruzzi",
        "go": "Ẓer",
-       "searcharticle": "áº\92er",
+       "searcharticle": "á¹\9auḥ",
        "history": "Amezruy n usebter",
        "history_short": "Amazray",
        "history_small": "amazray",
        "right-reupload-shared": "Ɛefes deg udigan afaylu yellan ɣef azadur azduklan",
        "right-upload_by_url": "Kter afaylu seg tansa URL",
        "enhancedrc-history": "amazray",
+       "recentchanges": "Ibeddilen imaynuten",
+       "recentchanges-label-newpage": "Abeddel agi ad yesnulfu asebter amaynut",
+       "recentchanges-label-minor": "Wagi d-abeddel amectuḥ",
+       "recentchanges-label-bot": "D-arubut id yeseqdacen abeddel agi",
        "recentchanges-submit": "Ssken",
        "rcshowhideminor-show": "Ssken",
        "rcshowhideminor-hide": "Ffer",
        "rcshowhidemine-show": "Ssken",
        "rcshowhidemine-hide": "Ffer",
        "rcshowhidecategorization-show": "Ssken",
+       "diff": "amgi",
+       "hist": "amez",
        "hide": "Ffer",
        "show": "Ssken",
+       "minoreditletter": "m",
+       "newpageletter": "N",
+       "boteditletter": "b",
+       "rc-change-size-new": "$1 {{PLURAL:$1|atamḍan|itamḍanen}} seld abeddel",
+       "recentchangeslinked-toolbox": "Ibeddlen imaynuten n isebtar myezdin",
        "upload": "Azen afaylu",
        "imgfile": "Afaylu",
        "file-anchor-link": "Afaylu",
+       "filehist": "Amazray n ufaylu",
+       "filehist-thumbtext": "Tugna tamectuḥt i lqem n $1",
+       "imagelinks": "Aseqdec n ufaylu",
+       "randompage": "Asebter menwala",
        "withoutinterwiki-submit": "Ssken",
        "nbytes": "$1 {{PLURAL:$1|byte|bytes}}",
        "prefixindex-submit": "Ssken",
+       "newpages": "Isebtar imaynuten",
        "newpages-submit": "Ssken",
        "newpages-username": "Isem n useqdac:",
        "logeventslist-submit": "Ssken",
+       "allpagessubmit": "Ṛuḥ",
        "categories-submit": "Ssken",
        "linksearch-ok": "Iruzzi",
        "listusers-submit": "Ssken",
        "emailusername": "Isem n useqdac:",
        "watchlist-submit": "Ssken",
        "historyaction-submit": "Ssken",
+       "rollbacklink": "semmet",
        "restriction-edit": "Glef",
        "undelete-search-submit": "Iruzzi",
        "namespace": "Talluntin n isemawen",
+       "blanknamespace": "(Agejdan)",
        "sp-contributions-submit": "Iruzzi",
+       "whatlinkshere": "Ayen i d-yettawi ɣer da",
        "ipblocklist-submit": "Iruzzi",
+       "contribslink": "attekki",
+       "thumbnail-more": "Ssemɣer",
+       "tooltip-pt-login": "Lukan tkecmeḍ xir, meɛna am tebɣiḍ",
        "tooltip-pt-logout": "Ffeɣ",
+       "tooltip-pt-createaccount": "Yelha limer ad ternuḍ amiḍan sakin ad teqqneḍ; maca, ur issefk ara",
+       "tooltip-ca-talk": "Aseqerdec ɣef usebter-agi n ugbur",
+       "tooltip-ca-edit": "Ẓreg asebter-agi",
+       "tooltip-ca-history": "Tisiwal ssabeq n usebter-agi.",
+       "tooltip-ca-watch": "Rnu asebter-agi ar tebdart-ik n uḍfaṛ",
        "tooltip-search": "Iruzzi {{SITENAME}}",
+       "tooltip-search-go": "Ṛuḥ ɣer usebter i sɛan isem agi ma yella",
+       "tooltip-search-fulltext": "Nadi isebtar i sɛan aḍris agi",
+       "tooltip-p-logo": "Rzu ar usebter agejdan",
+       "tooltip-n-mainpage": "Rzu ar usebter agejdan",
+       "tooltip-n-mainpage-description": "Rzu ar usebter agejdan",
+       "tooltip-n-portal": "Ɣef usenfar, ayen tzemrḍ ad txedmeḍ, anda tafeḍ tiɣawsiwin",
+       "tooltip-n-currentevents": "Af ayen yeḍran tura",
+       "tooltip-n-recentchanges": "Umuɣ n yibeddlen imaynuten deg wiki",
+       "tooltip-n-randompage": "Ẓer asebter menwala",
+       "tooltip-n-help": "Amkan ideg tafeḍ",
+       "tooltip-t-whatlinkshere": "Umuɣ n akk isebtar i yesɛan azday ar dagi",
+       "tooltip-t-recentchangeslinked": "Ibeddlen imaynuten deg isebtar myezdin seg usebter-agi",
        "tooltip-t-upload": "Azen ifuyla",
+       "tooltip-t-specialpages": "Umuɣ n akk isebtar usligen",
+       "tooltip-t-print": "Lqem tasiggezt n usebter agi",
+       "tooltip-t-permalink": "Azday ameɣlal ɣer lqem agi n usebter",
+       "tooltip-ca-nstab-main": "Ẓer ayen yellan deg usebter",
+       "tooltip-ca-nstab-special": "Wagi d asebter uzzig, ur tezmireḍ ara ad t-tbeddleḍ",
        "tooltip-ca-nstab-category": "Ẓer asebter n taggayin",
+       "tooltip-rollback": "\"Semmet\" yesemmet s-yiwen asenned akk d-acu amseqdac aneggaru yebeddel deg usebter",
        "pageinfo-toolboxlink": "Tilɣa n udasil",
        "pageinfo-contentpage-yes": "Ih",
        "show-big-image-size": "$1 × $2 pixels",
        "ilsubmit": "Iruzzi",
        "days": "{{PLURAL:$1|$1 ass|$1 ussan}}",
+       "metadata": "Adferisefka",
+       "metadata-fields": "Urtan n adferisefka n tugniwin yellan deg umuɣ n izen agi, ad seddun deg usebter n aglam n tugna mi ṭabla n adferisefka at illi tesemẓi. Urtan nniḍen ad illin ffren m-ulac.\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",
        "namespacesall": "akk",
        "monthsall": "akk",
        "fileduplicatesearch-submit": "Iruzzi",
        "specialpages": "Asebter uslig",
+       "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|Ticṛeṭ|Ticraḍ}}]] : $2)",
        "tags-active-yes": "Ih",
        "tags-active-no": "Uhu",
        "searchsuggest-search": "Iruzzi {{SITENAME}}",
index 277a0c9..ebec299 100644 (file)
        "whatlinkshere": "මෙතනට සබැඳෙන්නේ කුමක්ද",
        "whatlinkshere-title": "\"$1\" වෙත සබැ‍ඳෙන පිටු",
        "whatlinkshere-page": "පිටුව:",
-       "linkshere-2": "ඉදිරියෙහි දැක්වෙන පිටු, '''$1''' වෙත සබැඳෙයි:",
-       "nolinkshere-2": "'''$1''' වෙත කිසිදු පිටුවක් සබැඳී නොමැත.",
-       "nolinkshere-ns-2": "තෝරාගෙන ඇති නාම-අවකාශය තුලදී, කිසිදු පිටුවක්, '''$1''' වෙත නොබැඳෙයි.",
+       "linkshere": "ඉදිරියෙහි දැක්වෙන පිටු, '''$2''' වෙත සබැඳෙයි:",
+       "nolinkshere": "'''$2''' වෙත කිසිදු පිටුවක් සබැඳී නොමැත.",
+       "nolinkshere-ns": "තෝරාගෙන ඇති නාම-අවකාශය තුලදී, කිසිදු පිටුවක්, '''$2''' වෙත නොබැඳෙයි.",
        "isredirect": "පිටුව යළි-යොමුකරන්න",
        "istemplate": "අන්තහ්කරණය",
        "isimage": "ගොනු සබැඳිය",
        "markedaspatrollederror-noautopatrol": "ඔබගේ ස්වීය වෙනස්වීම් පරික්‍ෂාකර බැලූ ලෙස සලකුණු කිරීමට ඔබ හට ඉඩ දෙනු නොලැබේ.",
        "patrol-log-page": "පරික්ෂාකිරීම් සටහන",
        "patrol-log-header": "මෙය පරික්‍ෂාකර බැලූ සංශෝධනයන්ගේ ලඝු-සටහනකි.",
-       "log-show-hide-patrol": "පරික්‍ෂාකිරීම් ලඝු-සටහන් $1",
-       "log-show-hide-tag": "$1 ටැගය ලඝු-සටහන",
        "deletedrevision": "පැරැණි සංශෝධනය $1 මකාදමන ලදි",
        "filedeleteerror-short": "ගොනුව මකාදැමීමේ දෝෂය: $1",
        "filedeleteerror-long": "ගොනුව මකාදැමීමේදී දෝෂයන් හමුවුණි:\n\n$1",
index 7518cc7..4accf55 100644 (file)
@@ -37,7 +37,9 @@
                        "LacoR",
                        "Xð",
                        "Pmikolas44",
-                       "Fitoschido"
+                       "Fitoschido",
+                       "Matěj Suchánek",
+                       "Vlad5250"
                ]
        },
        "tog-underline": "Podčiarkovať odkazy:",
        "print": "Tlač",
        "view": "Zobraziť",
        "view-foreign": "Prehliadnuť na {{GRAMMAR:lokál|$1}}",
-       "edit": "upraviť",
+       "edit": "Upraviť",
        "edit-local": "Upraviť miestny popis",
        "create": "Vytvoriť",
        "create-local": "Pridať miestny popis",
        "savechanges": "Uložiť zmeny",
        "publishpage": "Publikovať stránku",
        "publishchanges": "Publikovať zmeny",
+       "publishchanges-start": "Zverejniť zmeny…",
        "preview": "Náhľad",
        "showpreview": "Zobraziť náhľad",
        "showdiff": "Zobraziť rozdiely",
        "timezoneregion-indian": "Indický oceán",
        "timezoneregion-pacific": "Tichý oceán",
        "allowemail": "Povoliť prijímanie e-mailov od iných používateľov",
+       "email-allow-new-users-label": "Povoliť e-maily od úplne nových používateľov",
        "email-blacklist-label": "Znemožniť týmto používateľom posielať mi e-maily:",
        "prefs-searchoptions": "Vyhľadávanie",
        "prefs-namespaces": "Menné priestory",
        "prefs-dateformat": "Formát dátumu",
        "prefs-timeoffset": "Časový posun",
        "prefs-advancedediting": "Všeobecné možnosti",
+       "prefs-developertools": "Vývojárske nástroje",
        "prefs-editor": "Používateľ",
        "prefs-preview": "Náhľad",
        "prefs-advancedrc": "Rozšírené možnosti",
        "right-editcontentmodel": "Upravovať model obsahu stránky",
        "right-editinterface": "Upravovať správy používateľského rozhrania",
        "right-editusercss": "Upravovať CSS súbory ostatných používateľov",
+       "right-edituserjson": "Upravovať JSON súbory ostatných používateľov",
        "right-edituserjs": "Upravovať JS súbory ostatných používateľov",
        "right-editmyusercss": "Upraviť svoje vlastné používateľské súbory CSS",
+       "right-editmyuserjson": "Upraviť svoje vlastné používateľské súbory JSON",
        "right-editmyuserjs": "Upraviť svoje vlastné používateľské súbory JavaScript",
        "right-viewmywatchlist": "Zobraziť vlastný zoznam sledovaných stránok",
        "right-editmywatchlist": "Upraviť vlastný zoznam sledovaných stránok. Všimnite si, že niektoré operácie budú môcť pridať stránky aj bez tohto oprávnenia.",
        "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-date-popup-title": "Hľadané časové obdobie",
        "rcfilters-days-title": "Posledné dni",
        "rcfilters-hours-title": "Posledné hodiny",
        "rcfilters-days-show-days": "$1 {{PLURAL:$1|deň|dni|dní}}",
        "rcfilters-watchlist-showupdated": "Zmeny stránok, ktoré ste od ich zmeny nenavštívili, sú zobrazené <strong>hrubo</strong> s vyplneným krúžkom.",
        "rcfilters-preference-label": "Skryť vylepšenú verziu posledných úprav",
        "rcfilters-preference-help": "Zruší novú podobu rozhrania z roku 2017 a všetky nástroje odvtedy pridané.",
+       "rcfilters-watchlist-preference-label": "Skryť vylepšenú verziu sledovaných stránok",
+       "rcfilters-watchlist-preference-help": "Zruší novú podobu rozhrania z roku 2017 a všetky nástroje odvtedy pridané.",
        "rcnotefrom": "Nižšie {{PLURAL:$5|je zobrazená úprava|sú zobrazené úpravy}} od <strong>$2</strong> (do <strong>$1</strong>).",
        "rclistfromreset": "Obnoviť výber údajov",
        "rclistfrom": "Zobraziť nové úpravy počnúc od $3 $2",
        "watcherrortext": "Vyskytla sa chyba počas zmeny nastavenia vášho zoznamu sledovaných pre „$1“.",
        "enotif_reset": "Označiť všetky stránky ako „navštívené“",
        "enotif_impersonal_salutation": "používateľ {{GRAMMAR:genitív|{{SITENAME}}}}",
-       "enotif_subject_deleted": "Stránku {{GENDER:genitív|{{SITENAME}}}} „$1“ odstránil používateľ $2",
-       "enotif_subject_created": "Stránku {{GENDER:genitív|{{SITENAME}}}} „$1“ vytvoril používateľ $2",
-       "enotif_subject_moved": "Stránku {{GENDER:genitív|{{SITENAME}}}} „$1“ presunul používateľ $2",
-       "enotif_subject_restored": "Stránku {{GENDER:genitív|{{SITENAME}}}} „$1“ obnovil používateľ $2",
-       "enotif_subject_changed": "Stránku {{GENDER:genitív|{{SITENAME}}}} „$1“ zmenil používateľ $2",
+       "enotif_subject_deleted": "Stránku {{GRAMMAR:genitív|{{SITENAME}}}} „$1“ odstránil používateľ {{GENDER:$2|$2}}",
+       "enotif_subject_created": "Stránku {{GRAMMAR:genitív|{{SITENAME}}}} „$1“ vytvoril používateľ {{GENDER:$2|$2}}",
+       "enotif_subject_moved": "Stránku {{GRAMMAR:genitív|{{SITENAME}}}} „$1“ presunul používateľ {{GENDER:$2|$2}}",
+       "enotif_subject_restored": "Stránku {{GRAMMAR:genitív|{{SITENAME}}}} „$1“ obnovil používateľ {{GENDER:$2|$2}}",
+       "enotif_subject_changed": "Stránku {{GRAMMAR:genitív|{{SITENAME}}}} „$1“ zmenil používateľ {{GENDER:$2|$2}}",
        "enotif_body_intro_deleted": "Stránka {{GENDER:genitív|{{SITENAME}}}} „$1“ zmazal $PAGEEDITDATE používateľ $2, pozri $3.",
        "enotif_body_intro_created": "Stránka {{GENDER:genitív|{{SITENAME}}}} „$1“ vytvoril $PAGEEDITDATE používateľ $2, pozri aktuálnu verziu $3.",
        "enotif_body_intro_moved": "Stránka {{GENDER:genitív|{{SITENAME}}}} „$1“ presunul $PAGEEDITDATE používateľ $2, pozri aktuálnu verziu $3.",
        "dellogpage": "Záznam zmazaní",
        "dellogpagetext": "Tu je zoznam posledných zmazaní.",
        "deletionlog": "záznam zmazaní",
+       "log-name-create": "Záznam vytvorení stránok",
+       "log-description-create": "Toto je zoznam posledných vytvorených stránok.",
        "reverted": "Obnovené na skoršiu verziu",
        "deletecomment": "Dôvod:",
        "deleteotherreason": "Iný/ďalší dôvod:",
        "whatlinkshere": "Odkazy na túto stránku",
        "whatlinkshere-title": "Stránky odkazujúce na „$1“",
        "whatlinkshere-page": "Page:",
-       "linkshere-2": "Nasledujúce stránky odkazujú na '''$1''':",
-       "nolinkshere-2": "Žiadne stránky neodkazujú na '''$1'''.",
-       "nolinkshere-ns-2": "Žiadne stránky neodkazujú na '''$1''' vo zvolenom mennom priestore.",
+       "linkshere": "Nasledujúce stránky odkazujú na '''$2''':",
+       "nolinkshere": "Žiadne stránky neodkazujú na '''$2'''.",
+       "nolinkshere-ns": "Žiadne stránky neodkazujú na '''$2''' vo zvolenom mennom priestore.",
        "isredirect": "presmerovacia stránka",
        "istemplate": "použitá",
        "isimage": "odkaz na súbor",
        "ipb-unblock-addr": "Odblokovať $1",
        "ipb-unblock": "Odblokovať používateľa alebo IP adresu",
        "ipb-blocklist": "Zobraziť existujúce blokovania",
-       "ipb-blocklist-contribs": "Príspevky {{GENDER:redaktora|redaktorky}} $1",
+       "ipb-blocklist-contribs": "Príspevky {{GENDER:$1|redaktora|redaktorky}} $1",
        "ipb-blocklist-duration-left": "zostáva $1",
        "unblockip": "Odblokovať používateľa",
        "unblockiptext": "Použite tento formulár na obnovenie možnosti zápisov\nz/od momentálne zablokovanej IP adresy/používateľa.",
        "unblocked-id": "Blokovanie $1 bolo odstránené",
        "unblocked-ip": "Adresa [[Special:Contributions/$1|$1]] bola odblokovaná.",
        "blocklist": "Zablokovaní používatelia",
+       "autoblocklist": "Automatické blokovania",
+       "autoblocklist-submit": "Hľadať",
+       "autoblocklist-legend": "Zoznam automatických blokovaní",
+       "autoblocklist-localblocks": "Miestne automatické {{PLURAL:$1|blokovanie|blokovania}}",
+       "autoblocklist-total-autoblocks": "Celkový počet automatických blokovaní: $1",
+       "autoblocklist-empty": "Zoznam automatických blokovaní je prázdny.",
+       "autoblocklist-otherblocks": "Iné automatické {{PLURAL:$1|blokovanie|blokovania}}",
        "ipblocklist": "Zablokovaní používatelia",
        "ipblocklist-legend": "Nájsť zablokovaného používateľa",
        "blocklist-userblocks": "Skryť blokovania účtov",
        "markedaspatrollederrornotify": "Nepodarilo sa označiť ako preverené.",
        "patrol-log-page": "Záznam preverených úprav",
        "patrol-log-header": "Toto je záznam preverených revízií.",
-       "log-show-hide-patrol": "$1 záznam preverených úprav",
-       "log-show-hide-tag": "$1 záznam značiek",
        "confirm-markpatrolled-button": "OK",
        "confirm-markpatrolled-top": "Označiť revíziu $3 stránky $2 ako preverenú?",
        "deletedrevision": "Zmazať staré verzie $1",
        "table_pager_limit_submit": "Spustiť",
        "table_pager_empty": "Bez výsledkov",
        "autosumm-blank": "Odstránený obsah stránky",
-       "autosumm-replace": "Nahrádzam stránku textom „$1“",
+       "autosumm-replace": "Obsah stránky nahradený textom „$1“",
        "autoredircomment": "Presmerovanie na [[$1]]",
+       "autosumm-removed-redirect": "Zrušené presmerovanie na [[$1]]",
+       "autosumm-changed-redirect-target": "Cieľ presmerovania zmenený z [[$1]] na [[$2]]",
        "autosumm-new": "Vytvorená stránka „$1“",
        "autosumm-newblank": "Vytvorená prázdna stránka",
        "lag-warn-normal": "Úpravy za {{PLURAL:$1|poslednú sekundu|posledné $1 sekundy|posledných $1 sekúnd}} nemusia byť v tomto zozname zobrazené.",
        "specialpages-group-wiki": "Údaje a nástroje",
        "specialpages-group-redirects": "Špeciálne stránky, ktoré sú presmerovania",
        "specialpages-group-spam": "Nástroje proti spamu",
-       "specialpages-group-developer": "Nástroje vývojárov",
+       "specialpages-group-developer": "Vývojárske nástroje",
        "blankpage": "Prázdna stránka",
        "intentionallyblankpage": "Táto stránka je zámerne prázdna. Používa sa na meranie výkonnosti atď.",
        "external_image_whitelist": "  #Nechajte tento riadok presne tak, ako je<pre>\n#Časti regulárnych výrazov (tie, ktoré sa píšu medzi //) napíšte dolu\n#Budú porovnané s URL externých obrázkov\n#Tie, ktoré budú zodpovedať reg. výrazu sa zobrazia ako obrázky, inak sa zobrazí iba odkaz na obrázok\n#Riadky, ktoré začínajú znakom # sa považujú za komentáre\n#Na veľkosti písmen nezáleží\n\n#Napíšte všetky časti reg. výrazov nad tento riadok. Nechajte tento riadok presne tak, ako je</pre>",
index 588058b..a9d9e7c 100644 (file)
@@ -9,7 +9,7 @@
        "tog-hideminor": "چھوٹیاں تبدیلیاں لُکاؤ",
        "tog-hidepatrolled": "تازہ تبدیلیاں وچوں زیرنگرانی تبدیلیاں لکاؤ",
        "tog-newpageshidepatrolled": "نویں ورقیاں دی فہرست وچوں نگرانی ہیٹھ ورقے لُکاؤ",
-       "tog-hidecategorization": "Ù\88رÙ\82Û\8cاں Ø¯Û\8cاں Ù\82سÙ\85 بندی لُکاؤ",
+       "tog-hidecategorization": "Ù\88رÙ\82Û\8cاں Ø¯Û\8cاں Ù\88Ù\86Ú©Û\8c بندی لُکاؤ",
        "tog-numberheadings": "سرخیاں کوں خود کار نمبر ݙیوو",
        "tog-showtoolbar": "آلات ترمیم ݙکھاؤ",
        "tog-editondblclick": "ڈبل کلک نال ورقے وچ تبدیلیاں کرو",
@@ -20,8 +20,8 @@
        "tog-watchlisthideown": "میݙیاں تبدیلیاں اکھیں ہیٹھ فہرست وچوں لکاؤ",
        "tog-watchlisthidebots": "بوٹ دیاں تبدیلیاں اکھیں ہیٹھ فہرست وچوں لکاؤ",
        "tog-watchlisthideminor": "چھوٹیاں تبدیلیاں اکھیں ہیٹھ فہرست وچوں لکاؤ",
-       "tog-watchlisthidecategorization": "Ù\88رÙ\82Û\8cاں Ø¯Û\8cاں Ù\82سÙ\85 بندی لُکاؤ",
-       "tog-showhiddencats": "Ù\84Ú³Û\8cاں Ù\82سÙ\85اں ݙکھاؤ",
+       "tog-watchlisthidecategorization": "Ù\88رÙ\82Û\8cاں Ø¯Û\8cاں Ù\88Ù\86Ú©Û\8c بندی لُکاؤ",
+       "tog-showhiddencats": "Ù\84Ú³Û\8cاں Ù\88Ù\86Ú©Û\8cاں ݙکھاؤ",
        "underline-always": "ہمیشہ",
        "underline-never": "کݙاہیں وی کائناں",
        "underline-default": "سکن یا براؤزر دا طے شدہ",
        "december-date": "$1 دسمبر",
        "period-am": "سویر",
        "period-pm": "شام",
-       "pagecategories": "{{PLURAL:$1|زمرہ|زمرہ جات}}",
-       "category_header": "زمرہ \"$1\" وچ ورقے",
-       "subcategories": "ذیلی زمرہ جات",
-       "category-media-header": "زمرہ \"$1\" وچ میڈیا",
+       "pagecategories": "{{PLURAL:$1|ونکی|ونکیاں}}",
+       "category_header": "ونکی \"$1\" وچ ورقے",
+       "subcategories": "ذیلی ونکیاں",
+       "category-media-header": "ونکی \"$1\" وچ میڈیا",
        "category-empty": "<em>ایں قسم وچ اڄݨ تائیں کوئی ورقہ یا میڈیا کائنی۔</em>",
-       "hidden-categories": "{{PLURAL:$1|Ù¾Ù\88Ø´Û\8cدÛ\81 Ø²Ù\85رÛ\81|Ù¾Ù\88Ø´Û\8cدÛ\81 Ø²Ù\85رÛ\81 Ø¬Ø§Øª}}",
-       "hidden-category-category": "Ù\84Ú©Û\8cاں Ù\82سÙ\85اں",
+       "hidden-categories": "{{PLURAL:$1|Ù\84Ú³Û\8c Ù\88Ù\86Ú©Û\8c\84Ù\8fÚ³Û\8cاں Ù\88Ù\86Ú©Û\8cاں}}",
+       "hidden-category-category": "Ù\84Ú©Û\8cاں Ù\88Ù\86Ú©Û\8cاں",
        "listingcontinuesabbrev": "جاری۔",
        "index-category": "فہرست شدہ ورقے",
        "noindex-category": "غیر فہرست شدہ صفحات",
        "faq": "عام طور تے پچھے ونڄݨ آلے سوال",
        "actions": "کم",
        "namespaces": "ناں جاہیں",
-       "variants": "Ù\82سÙ\85اں",
+       "variants": "Ù\88Ù\86Ú©Û\8cاں",
        "navigation-heading": "نیوی ڳیشݨ فہرست",
        "errorpagetitle": "نقص",
        "returnto": "واپس $1 چلو",
        "edithelp": "لکھݨ وچ مدد",
        "helppage-top-gethelp": "مدد",
        "mainpage": "وݙا ورقہ",
-       "mainpage-description": "Ù¾Û\81Ù\84ا ورقہ",
+       "mainpage-description": "Ù\88Ý\99ا ورقہ",
        "policy-url": "Project:پالیسی",
        "portal": "بیٹھک",
        "portal-url": "Project:دیوان عام",
        "nstab-mediawiki": "سنیہہ",
        "nstab-template": "سانچہ",
        "nstab-help": "مدد ورقہ",
-       "nstab-category": "زمرہ",
+       "nstab-category": "ونکی",
        "mainpage-nstab": "وݙا ورقہ",
        "nosuchaction": "کوئی اینجھا کم کائنی",
        "nosuchspecialpage": "اینجھا کوئی خاص ورقہ کائنی",
        "templatesusedpreview": "ایں کچے کم تے  ورتے ڳئے {{PLURAL:$1|سانچے|سانچہ}}:",
        "template-protected": "(بچایا ڳیا)",
        "template-semiprotected": "(نیم محفوظ)",
-       "hiddencategories": "اÛ\8cÛ\81 Ù\88رÙ\82Û\81 {{PLURAL:$1|1 Ù\84Ù\8fÚ©Û\92 Ø²Ù\85رÛ\8cاں|$1 Ù\84کا Ø²Ù\85رÛ\81 }} وچ شامل ہے:",
+       "hiddencategories": "اÛ\8cÛ\81 Ù\88رÙ\82Û\81 {{PLURAL:$1|1 Ù\84Ù\8fÚ³Û\8cاں Ù\88Ù\86Ú©Û\8cاں|$1 Ù\84Ú³Û\8c Ù\88Ù\86Ú©Û\8c }} وچ شامل ہے:",
        "permissionserrors": "خطائے اجازت",
        "permissionserrorstext-withaction": "انہاں {{PLURAL:$1|وجہ|وجوہات}} پاروں تہاکوں$2 دی اجازت کائنی",
        "moveddeleted-notice": "ایہ ورقہ مٹایا ڳیا ہے۔ مٹاوݨ دا لاگ،حفاظت دا لاگ تے ورقہ ٹورݨ دا لاگ  حوالے کیتے ہیٹھاں ݙتے ہوئے ہن۔",
        "recentchanges-submit": "ݙیکھاؤ",
        "rcfilters-tag-remove": "ہٹاؤ '$1'",
        "rcfilters-activefilters": "فعال نتارے",
+       "rcfilters-activefilters-hide": "لُکاؤ",
+       "rcfilters-activefilters-show": "ݙِکھاؤ",
        "rcfilters-advancedfilters": "ودھائے نتارے",
        "rcfilters-limit-title": "ݙیکھاوݨ کیتے نتیجے",
        "rcfilters-limit-and-date-label": "$1{{PLURAL:$1|تبدیلی|تبدیلیاں}}، $2",
        "upload-form-label-usage-title": "استعمال",
        "upload-form-label-usage-filename": "فائل دا ناں",
        "upload-form-label-own-work": "یہ میݙا ذاتی کم ہے",
-       "upload-form-label-infoform-categories": "Ù\82سÙ\85اںØ\8c Ø²Ù\85رÛ\92",
+       "upload-form-label-infoform-categories": "Ù\88Ù\86Ú©Û\8cاں",
        "upload-form-label-infoform-date": "تاریخ",
        "backend-fail-delete": "مِسَل \"$1\" کوں مٹایا نی ونڄ سڳیا۔",
        "license": "اجازت نامہ:",
        "filedelete-submit": "مٹاؤ",
        "filedelete-maintenance-title": "مِسل نی مٹا سڳدے",
        "randompage": "رلے ملے ورقے",
-       "randomincategory-category": "Ù\82سÙ\85:",
+       "randomincategory-category": "Ù\88Ù\86Ú©Û\8c:",
        "randomincategory-submit": "ڄلو",
        "statistics": "شماريات",
        "statistics-pages": "ورقے",
        "allarticles": "سارے مقالے",
        "allpagessubmit": "ڄلو",
        "allpages-hide-redirects": "رجوع مکررات لکاؤ",
-       "categories": "زمرہ",
+       "categories": "ونکی",
        "categories-submit": "ݙِکھاؤ",
        "deletedcontributions": "ورتݨ آلے دے کم مٹا ݙتے ڳئے",
        "linksearch-ok": "ڳولو",
        "delete-legend": "مٹاؤ",
        "historyaction-submit": "ݙِکھاؤ",
        "dellogpage": "مٹاوݨ آلی لاگ",
+       "log-name-create": "ورقہ بݨاوݨ آلی لاگ",
        "deletecomment": "سبب:",
        "rollbacklink": "واپس",
        "rollbacklinkcount": "واپس $1 {{PLURAL:$1|تبدیلی|تبدیلیاں}}",
        "whatlinkshere": "مربوط ورقے",
        "whatlinkshere-title": "«$1» دے نال جُڑے ہوے ورقے",
        "whatlinkshere-page": "ورقہ",
-       "linkshere-2": "<strong>$1</strong> نال درج ذیل ورقے مربوط ہن:",
-       "nolinkshere-2": "<strong>$1</strong> نال کوئی ورقہ مربوط کائنی۔",
+       "linkshere": "<strong>$2</strong> نال درج ذیل ورقے مربوط ہن:",
+       "nolinkshere": "<strong>$2</strong> نال کوئی ورقہ مربوط کائنی۔",
        "isredirect": "ورقہ ریڈائریکٹ کرو",
        "istemplate": "شامل شدہ",
        "isimage": "فائل دا ربط",
        "tooltip-search": "ڳولو {{SITENAME}}",
        "tooltip-search-go": "جے ایں عنوان دا ورقہ ہے تاں اتھ ونڄو",
        "tooltip-search-fulltext": "ایں عبارت کوں ورقیاں وچ ڳولو",
-       "tooltip-p-logo": "Ù¾Û\81Ù\84ا ورقہ ݙیکھو",
-       "tooltip-n-mainpage": "Ù¾Û\81Ù\84ا ورقہ ݙیکھو",
+       "tooltip-p-logo": "Ù\88Ý\99ا ورقہ ݙیکھو",
+       "tooltip-n-mainpage": "Ù\88Ý\99ا ورقہ ݙیکھو",
        "tooltip-n-mainpage-description": "پہلے ورقے تے ونڄو",
        "tooltip-n-portal": "ایں مںصوبے بارے، تساں کیا کر سڳدو، ، چیزاں کتھوں ڳولوں",
        "tooltip-n-currentevents": "موجودہ حالات وچ پچھلیاں معلومات ݙیکھو",
        "pageinfo-recent-edits": "حالیہ ترامیم دی تعداد (گزشتہ $1 وچ)",
        "pageinfo-recent-authors": "مختلف مصنفین دی حالیہ تعداد",
        "pageinfo-magic-words": "جادوئی {{PLURAL:$1|لفظ|الفاظ}} ($1)",
-       "pageinfo-hidden-categories": "Ù¾Ù\88Ø´Û\8cدÛ\81 {{PLURAL:$1|زÙ\85رÛ\81|زÙ\85رÛ\81 Ø¬Ø§Øª}} ($1)",
+       "pageinfo-hidden-categories": "Ù\84Ú³Û\92 {{PLURAL:$1|Ù\88Ù\86Ú©Û\8c\88Ù\86Ú©Û\8cاں}} ($1)",
        "pageinfo-templates": "زیر استعمال {{PLURAL:$1|سانچہ|سانچے}} ($1)",
        "pageinfo-toolboxlink": "معلومات ورقہ",
        "pageinfo-contentpage": "شمار بطور ورقہ",
index db23653..a0d4524 100644 (file)
@@ -15,7 +15,8 @@
                        "Matma Rex",
                        "NegativeTwelveDollars",
                        "Xð",
-                       "HairyFotr"
+                       "HairyFotr",
+                       "Upwinxp"
                ]
        },
        "tog-underline": "Podčrtavanje povezav:",
        "customcssprotected": "Nimate pravice urejati te strani CSS, ker vsebuje osebne nastavitve drugega uporabnika.",
        "customjsonprotected": "Nimate pravice urejati te strani JSON, ker vsebuje osebne nastavitve drugega uporabnika.",
        "customjsprotected": "Nimate pravice urejati te strani JavaScript, ker vsebuje osebne nastavitve drugega uporabnika.",
+       "sitecssprotected": "Nimate dovoljenja urejati te strani CSS, saj lahko vpliva na vse obiskovalce",
+       "sitejsonprotected": "Nimate dovoljenja urejati te strani JSON, saj lahko vpliva na vse obiskovalce",
+       "sitejsprotected": "Nimate dovoljenja urejati te strani JavaScript, saj lahko vpliva na vse obiskovalce",
        "mycustomcssprotected": "Nimate pravic za urejanje te strani s CSS.",
        "mycustomjsonprotected": "Nimate pravic za urejanje te strani z JSON.",
        "mycustomjsprotected": "Nimate pravic za urejanje te strani z JavaScriptom.",
        "createacct-another-username-ph": "Vnesite uporabniško ime",
        "yourpassword": "Geslo:",
        "userlogin-yourpassword": "Geslo",
-       "userlogin-yourpassword-ph": "Vnesite svoje geslo",
+       "userlogin-yourpassword-ph": "Vnesi svoje geslo",
        "createacct-yourpassword-ph": "Vnesite geslo",
        "yourpasswordagain": "Ponovno vpišite geslo",
        "createacct-yourpasswordagain": "Potrdite geslo",
        "userlogin-resetpassword-link": "Ste pozabili svoje geslo?",
        "userlogin-helplink2": "Pomoč pri prijavi",
        "userlogin-loggedin": "Prijavljeni ste že kot {{GENDER:$1|$1}}.\nUporabite spodnji obrazec, da se prijavite kot drug uporabnik.",
-       "userlogin-reauth": "Ponovno se morate prijaviti, da potrditev, da ste {{GENDER:$1|$1}}.",
+       "userlogin-reauth": "Za potrditev, da si res {{GENDER:$1|$1}}, se moraš ponovno prijaviti.",
        "userlogin-createanother": "Ustvari drug račun",
        "createacct-emailrequired": "E-poštni naslov",
        "createacct-emailoptional": "E-poštni naslov (izbirno)",
        "resetpass-submit-loggedin": "Spremenite geslo",
        "resetpass-submit-cancel": "Prekliči",
        "resetpass-wrong-oldpass": "Neveljavno začasno ali trenutno geslo.\nMorda ste že spremenili geslo ali pa ste zahtevali novo začasno geslo.",
-       "resetpass-recycled": "Prosimo, ponastavite svoje geslo na nekaj drugega kot svoje trenutno geslo.",
+       "resetpass-recycled": "Prosimo, spremenite svoje geslo na nekaj drugega kot svoje trenutno geslo.",
        "resetpass-temp-emailed": "Trenutno ste prijavljeni z začasno kodo, poslano z e-pošto. Za zaključitev prijave morate tukaj nastaviti novo geslo:",
        "resetpass-temp-password": "Začasno geslo:",
        "resetpass-abort-generic": "Razširitev je prekinila spremembo gesla.",
        "resetpass-expired": "Vaše geslo je poteklo. Prosimo, nastavite novo geslo za prijavo.",
-       "resetpass-expired-soft": "Vaše geslo je poteklo in ga morate ponastaviti. Prosimo, izberite novo geslo zdaj ali kliknite »{{int:authprovider-resetpass-skip-label}}«, da ga ponastavite pozneje.",
-       "resetpass-validity-soft": "Vaše geslo ni veljavno: $1\n\nProsimo, izberite novo geslo zdaj ali kliknite »{{int:authprovider-resetpass-skip-label}}«, da ga ponastavite pozneje.",
+       "resetpass-expired-soft": "Vaše geslo je poteklo in ga morate spremeniti. Prosimo, izberite novo geslo zdaj ali kliknite »{{int:authprovider-resetpass-skip-label}}«, da ga spremenite pozneje.",
+       "resetpass-validity-soft": "Vaše geslo ni veljavno: $1\n\nProsimo, izberite novo geslo zdaj ali kliknite »{{int:authprovider-resetpass-skip-label}}«, da ga spremenite pozneje.",
        "passwordreset": "Ponastavitev gesla",
        "passwordreset-text-one": "Da ponastavite svoje geslo, izpolnite naslednji obrazec.",
        "passwordreset-text-many": "{{PLURAL:$1|Da po e-pošti prejmete začasno geslo, izpolnite eno od polj.}}",
        "session_fail_preview": "Oprostite! Zaradi izgube podatkov o seji nam vašega urejanja žal ni uspelo obdelati.\n\nMorda ste bili odjavljeni. <strong>Prosimo, preverite, da ste še vedno prijavljeni, in poskusite znova.</strong>\nČe še vedno ne deluje, se poskusite [[Special:UserLogout|odjaviti]] in znova prijaviti; prav tako preverite, da vaš brskalnik dovoljuje piškotke s te strani.",
        "session_fail_preview_html": "Oprostite! Zaradi izgube podatkov o seji nam vašega urejanja ni uspelo obdelati.\n\n<em>Ker ima {{SITENAME}} omogočen surov HTML, smo predogled skrili kot previdnostni ukrep pred napadi z JavaScriptom.</em>\n\n<strong>Če gre za dobronameren poskus urejanja, vas prosimo, da poskusite znova.</strong>\nČe še vedno ne deluje, se poskusite [[Special:UserLogout|odjaviti]] in znova prijaviti; prav tako preverite, da vaš brskalnik dovoljuje piškotke s te strani.",
        "token_suffix_mismatch": "'''Vaše urejanje je bilo zavrnjeno, ker je vaš odjemalec pokvaril ločila v urejevalnem zahtevku.'''\nUrejanje je bilo zavrnjeno z namenom preprečitve okvare v besedilu strani.\nNajvečkrat je razlog uporaba hroščato spletno anonimizacijsko storitev.",
-       "edit_form_incomplete": "'''Nekateri deli urejevalnega obrazca niso dosegli strežnika; prepričajte se, da so vaša urejanja neokrnjena in poskusite znova.'''",
+       "edit_form_incomplete": "<strong>Nekateri deli urejevalnega obrazca niso dosegli strežnika; prepričajte se, da so vaša urejanja neokrnjena, in poskusite znova.</strong>",
        "editing": "Urejanje $1",
        "creating": "Ustvarjanje strani $1",
        "editingsection": "Urejanje $1 (razdelek)",
        "converter-manual-rule-error": "Odkril sem napako v ročnem pravilu pretvorbe jezikov",
        "undo-success": "Urejanje ste razveljavili. Prosimo, preverite prikazano primerjavo redakcij in, če ustrezajo, shranite spremembe.",
        "undo-failure": "Zaradi navzkrižij urejanj, ki so se vmes pojavila, tega urejanja ni moč razveljaviti.",
+       "undo-main-slot-only": "Urejanja nismo mogli razveljaviti, ker vključuje vsebino zunaj glavne reže.",
        "undo-norev": "Urejanja ni mogoče razveljaviti, ker ne obstaja ali je bilo izbrisano.",
        "undo-nochange": "Zdi se, da je urejanje nekdo že razveljavil.",
        "undo-summary": "Redakcija $1 uporabnika [[Special:Contributions/$2|$2]] ([[User talk:$2|pogovor]]) razveljavljena",
        "diff-paragraph-moved-toold": "Odstavek je bil premaknjen. Kliknite, da skočite na staro nahajališče.",
        "difference-missing-revision": "{{PLURAL:$2|Ene redakcije|$2 redakcij}} razlike ($1) {{PLURAL:$2|nisem}} našel.\n\nPo navadi se to zgodi, ko sledite zastareli povezavi na razliko redakcij strani, ki jo je nekdo izbrisal.\nPodrobnosti lahko najdete v [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} dnevniku brisanja].",
        "searchresults": "Izid iskanja",
+       "search-filter-title-prefix": "Išči samo na straneh, katerih naslovi se začnejo z \"$1\"",
+       "search-filter-title-prefix-reset": "Išči vse strani",
        "searchresults-title": "Zadetki za povpraševanje »$1«",
        "titlematches": "Ujemanje z naslovom članka",
        "textmatches": "Ujemanje z besedilom članka",
        "prefs-rc": "Zadnje spremembe",
        "prefs-watchlist": "Spisek nadzorov",
        "prefs-editwatchlist": "Uredi spisek nadzorov",
-       "prefs-editwatchlist-label": "Uredite vnose na svojem spisku nadzorov:",
-       "prefs-editwatchlist-edit": "Preglejte in odstranite naslove s svojega spiska nadzorov",
-       "prefs-editwatchlist-raw": "Uredite gol spisek nadzorov",
-       "prefs-editwatchlist-clear": "Počistite svoj spisek nadzorov",
+       "prefs-editwatchlist-label": "Uredi vnose na svojem spisku nadzorov:",
+       "prefs-editwatchlist-edit": "Preglej in odstrani naslove s svojega spiska nadzorov",
+       "prefs-editwatchlist-raw": "Uredi gol spisek nadzorov",
+       "prefs-editwatchlist-clear": "Počisti svoj spisek nadzorov",
        "prefs-watchlist-days": "Število dni za prikaz na spisku nadzorov:",
        "prefs-watchlist-days-max": "Največ $1 {{PLURAL:$1|dan|dneva|dni}}",
        "prefs-watchlist-edits": "Največje število sprememb za prikaz na spisku nadzorov:",
        "recentchangesdays-max": "Največ $1 {{PLURAL:$1|dan|dneva|dnevi|dni}}",
        "recentchangescount": "Število urejanj v zadnjih spremembah, zgodovinah strani in dnevnikih, privzeto:",
        "prefs-help-recentchangescount": "Največje število: 1000",
-       "prefs-help-watchlist-token2": "To je skrivni ključ do spletnega vira vašega spiska nadzorov.\nKdor ve zanj, lahko bere vaš spisek nadzorov, zato ključa ne delite.\nČe želite, [[Special:ResetTokens|ga lahko ponastavite]].",
+       "prefs-help-watchlist-token2": "To je skrivni ključ do spletnega vira tvojega spiska nadzorov.\nKdor ga pozna, lahko bere tvoj spisek nadzorov, zato ključa ne deli z drugimi.\nČe želiš, [[Special:ResetTokens|ga lahko ponastaviš]].",
        "prefs-help-tokenmanagement": "Lahko si ogledate ali ponastavite skrivni ključ vašega računa, s katerim lahko dostopate do spletnega vira vašega spiska nadzorov. Vsak, ki pozna vaš ključ, lahko bere vaš spisek nadzorov, zato ga ne delite.",
        "savedprefs": "Spremembe smo uspešno shranili.",
        "savedrights": "Uporabniške skupine {{GENDER:$1|$1}} smo shranili.",
        "prefs-help-signature": "Komentarje na pogovornih straneh je treba podpisati s »<nowiki>~~~~</nowiki>«, kar bo pretvorjeno v vaš podpis s časovnim žigom.",
        "badsig": "Neveljaven surovi podpis; preverite oznake HTML.",
        "badsiglength": "Vaš podpis je preobsežen.\nNe sme biti daljši od $1 {{PLURAL:$1|znaka|znakov}}.",
-       "yourgender": "Kako vam je ljubše, da vas opišemo?",
-       "gender-unknown": "Ko boste omenjeni, bo programje uporabilo nevtralen spol, kjer je to mogoče",
+       "yourgender": "Kako želiš biti obravnavan?",
+       "gender-unknown": "Ob tvoji omembi bo programje uporabilo nevtralne izraze za spol, kjer je to mogoče",
        "gender-male": "On ureja wikistrani.",
        "gender-female": "Ona ureja wikistrani.",
        "prefs-help-gender": "Nastavitev ni obvezna.\nProgramje uporablja njeno vrednost za vaše naslavljanje in omenjanje v ustreznem slovničnem spolu.\nPodatek bo javno prikazan.",
        "group-autoconfirmed": "Samodejno potrjeni uporabniki",
        "group-bot": "Boti",
        "group-sysop": "Administratorji",
+       "group-interface-admin": "Administratorji vmesnika",
        "group-bureaucrat": "Birokrati",
        "group-suppress": "Ukinjevalci",
        "group-all": "(vsi)",
        "group-autoconfirmed-member": "{{GENDER:$1|samodejno potrjen uporabnik|samodejno potrjena uporabnica}}",
        "group-bot-member": "{{GENDER:$1|bot}}",
        "group-sysop-member": "{{GENDER:$1|administrator|administratorka}}",
+       "group-interface-admin-member": "{{GENDER:$1|administrator vmesnika|administratorka vmesnika}}",
        "group-bureaucrat-member": "{{GENDER:$1|birokrat|birokratinja}}",
        "group-suppress-member": "{{GENDER:$1|ukinjevalec|ukinjevalka}}",
        "grouppage-user": "{{ns:project}}:Uporabniki",
        "grouppage-autoconfirmed": "{{ns:project}}:Samodejno potrjeni uporabniki",
        "grouppage-bot": "{{ns:project}}:Boti",
        "grouppage-sysop": "{{ns:project}}:Administratorji",
+       "grouppage-interface-admin": "{{ns:project}}:Administratorji vmesnika",
        "grouppage-bureaucrat": "{{ns:project}}:Birokrati",
        "grouppage-suppress": "{{ns:project}}:Ukinjevalci",
        "right-read": "Branje strani",
        "right-editusercss": "Uredi CSS datotek drugih uporabnikov",
        "right-edituserjson": "Urejanje JSON-datotek drugih uporabnikov",
        "right-edituserjs": "Uredi JS datotek drugih uporabnikov",
+       "right-editsitecss": "Urejanje CSS spletišča",
+       "right-editsitejson": "Urejanje JSON spletišča",
+       "right-editsitejs": "Urejanje JavaScripta spletišča",
        "right-editmyusercss": "Uredite svoje uporabniške datoteke CSS",
        "right-editmyuserjson": "Urejanje svojih uporabniških datotek JSON",
        "right-editmyuserjs": "Uredite svoje uporabniške datoteke JavaScript",
        "grant-createaccount": "Ustvarjanje računov",
        "grant-createeditmovepage": "Ustvarjanje, urejanje in prestavljanje strani",
        "grant-delete": "Brisanje strani, redakcij in dnevniških vnosov",
-       "grant-editinterface": "Urejanje imenskega prostora MediaWiki in uporabniškega CSS/JSON/JavaScripta",
+       "grant-editinterface": "Urejanje imenskega prostora MediaWiki in JSON spletišča/uporabnika",
        "grant-editmycssjs": "Urejanje svojega uporabniškega CSS/JSON/JavaScripta",
        "grant-editmyoptions": "Urejanje svojih uporabniških nastavitev",
        "grant-editmywatchlist": "Urejanje svojega spiska nadzorov",
+       "grant-editsiteconfig": "Urejanje CSS/JS spletišča in uporabnika",
        "grant-editpage": "Urejanje obstoječih strani",
        "grant-editprotected": "Urejanje zaščitenih strani",
        "grant-highvolume": "Visokoobsežno urejanje",
        "rcfilters-other-review-tools": "Druga orodja za pregled",
        "rcfilters-group-results-by-page": "Združi rezultate po strani",
        "rcfilters-activefilters": "Dejavni filtri",
+       "rcfilters-activefilters-hide": "Skrij",
+       "rcfilters-activefilters-show": "Prikaži",
+       "rcfilters-activefilters-hide-tooltip": "Skrij območje Aktivnih filtrov",
+       "rcfilters-activefilters-show-tooltip": "Pokaži območje Aktivnih filtrov",
        "rcfilters-advancedfilters": "Napredni filtri",
        "rcfilters-limit-title": "Rezultati za prikaz",
        "rcfilters-limit-and-date-label": "$1 {{PLURAL:$1|sprememba|spremembi|spremembe|sprememb}}, $2",
        "rcfilters-savedqueries-rename": "Preimenuj",
        "rcfilters-savedqueries-setdefault": "Nastavi kot privzeto",
        "rcfilters-savedqueries-unsetdefault": "Odstrani kot privzeto",
-       "rcfilters-savedqueries-remove": "Odstrani",
+       "rcfilters-savedqueries-remove": "Izbriši",
        "rcfilters-savedqueries-new-name-label": "Ime",
        "rcfilters-savedqueries-new-name-placeholder": "Opišite namen filtra",
        "rcfilters-savedqueries-apply-label": "Ustvari filter",
        "rcfilters-empty-filter": "Ni dejavnih filtrov. Prikazani so vsi prispevki.",
        "rcfilters-filterlist-title": "Filtri",
        "rcfilters-filterlist-whatsthis": "Kako to deluje?",
-       "rcfilters-filterlist-feedbacklink": "Povejte nam, kaj menite o teh (novih) orodjih za filtriranje",
+       "rcfilters-filterlist-feedbacklink": "Povejte nam, kaj menite o teh orodjih za filtriranje",
        "rcfilters-highlightbutton-title": "Označi rezultate",
        "rcfilters-highlightmenu-title": "Izberite barvo",
        "rcfilters-highlightmenu-help": "Izberite barvo za označitev te lastnosti",
        "rcfilters-liveupdates-button-title-on": "Izklopi posodobitve v živo",
        "rcfilters-liveupdates-button-title-off": "Prikaži nove spremembe, ko se zgodijo",
        "rcfilters-watchlist-markseen-button": "Označi vse spremembe kot pregledane",
-       "rcfilters-watchlist-edit-watchlist-button": "Uredite svoj seznam nadzorovanih strani",
+       "rcfilters-watchlist-edit-watchlist-button": "Uredi svoj seznam nadzorovanih strani",
        "rcfilters-watchlist-showupdated": "Spremembe strani, ki jih niste obiskali od zadnje spremembe, so prikazane <strong>krepko</strong>, z močnimi oznakami.",
        "rcfilters-preference-label": "Skrij izboljšano različico Zadnjih sprememb",
        "rcfilters-preference-help": "Povrne preoblikovanje vmesnika leta 2017 in vsa takrat in od takrat dodana orodja.",
+       "rcfilters-watchlist-preference-label": "Skrij izboljšano različico spiska nadzorov",
+       "rcfilters-watchlist-preference-help": "Razveljavi preoblikovanje vmesnika leta 2017 in vsa orodja, dodana takrat in od takrat.",
        "rcfilters-filter-showlinkedfrom-label": "Pokaži spremembe na straneh, na katere se povezuje",
        "rcfilters-filter-showlinkedfrom-option-label": "<strong>Strani, na katere kaže</strong> izbrana stran",
        "rcfilters-filter-showlinkedto-label": "Pokaži spremembe na straneh, ki kažejo na",
        "uploadstash-zero-length": "Datoteka ima nično dolžino.",
        "invalid-chunk-offset": "Neveljaven odmik delčka",
        "img-auth-accessdenied": "Dostop zavrnjen",
-       "img-auth-nopathinfo": "Manjka PATH_INFO.\nVaš strežnik ne poda te informacije.\nMorda temelji na CGI in ne more podpirati img_auth.\nOglejte si  https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization.",
+       "img-auth-nopathinfo": "Manjka informacija o poti.\nVaš strežnik mora biti nastavljen tako, da posreduje spremenljivki REQUEST_URI in/ali PATH_INFO.\nČe je, poskusite omogočiti $wgUsePathInfo.\nOglejte si  https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization.",
        "img-auth-notindir": "Zahtevana pot ni v konfigurirani mapi za nalaganje.",
        "img-auth-badtitle": "Ni mogoče sestaviti veljavnega naslova iz »$1«.",
        "img-auth-nologinnWL": "Niste prijavljeni in »$1« ni na seznamu dovoljenih datotek.",
        "http-timed-out": "Zahteva HTTP je potekla.",
        "http-curl-error": "Napaka pri doseganju URL: $1",
        "http-bad-status": "Med zahtevo HTTP je prišlo do težave: $1 $2",
+       "http-internal-error": "Notranja napaka HTTP.",
        "upload-curl-error6": "Ni možno doseči URL",
        "upload-curl-error6-text": "Navedenega naslova URL ni mogoče doseči.\nProsimo, ponovno preverite pravilnost URL-a in delovanje strani.",
        "upload-curl-error28": "Časovna prekinitev nalaganja",
        "statistics": "Statistika",
        "statistics-header-pages": "Statistika strani",
        "statistics-header-edits": "Statistika urejanj",
-       "statistics-header-users": "Uporabniška statistika",
+       "statistics-header-users": "Statistika uporabnikov",
        "statistics-header-hooks": "Drugi statistični podatki",
        "statistics-articles": "Članki",
        "statistics-pages": "Strani",
        "protectedtitles-submit": "Prikaži naslove",
        "listusers": "Seznam uporabnikov",
        "listusers-editsonly": "Pokaži samo uporabnike z urejanji",
+       "listusers-temporarygroupsonly": "Pokaži samo uporabnike v začasnih uporabniških skupinah",
        "listusers-creationsort": "Razvrsti po datumu ustvaritve",
        "listusers-desc": "Razvrsti padajoče",
        "usereditcount": "$1 {{PLURAL:$1|urejanje|urejanji|urejanja|urejanj}}",
        "apisandbox-dynamic-parameters-add-label": "Dodaj parameter:",
        "apisandbox-dynamic-parameters-add-placeholder": "Ime parametra",
        "apisandbox-dynamic-error-exists": "Parameter z imenom »$1« že obstaja.",
+       "apisandbox-templated-parameter-reason": "Ta [[Special:ApiHelp/main#main/templatedparams|parameter s predlogo]] je ponujen na podlagi {{PLURAL:$1|vrednosti}} $2.",
        "apisandbox-deprecated-parameters": "Zastareli parametri",
        "apisandbox-fetch-token": "Samodejno izpolni žeton",
        "apisandbox-add-multi": "Dodaj",
        "speciallogtitlelabel": "Cilj (naslov ali {{ns:user}}:uporabniškoime za uporabnika):",
        "log": "Dnevniki",
        "logeventslist-submit": "Prikaži",
+       "logeventslist-more-filters": "Prikaži dodatne dnevnike:",
+       "logeventslist-patrol-log": "Dnevnik patrulje",
+       "logeventslist-tag-log": "Dnevnik oznak",
        "all-logs-page": "Vsi javni dnevniki",
        "alllogstext": "Združeno so prikazani dnevniki sprememb uporabniških pravic, preimenovanj uporabnikov, nalaganja predstavnostnih datotek, prestavljanja in zaščite strani, brisanja, registracij uporabnikov, sprememb položaja botov ter blokiranja in deblokiranja uporabnikov na strani {{SITENAME}}. Pogled lahko zožite z izbiro dnevnika, uporabniškega imena ali strani. Vedite, da polje »Uporabnik« razlikuje med malimi in velikimi črkami.",
        "logempty": "O tej strani ni v dnevniku ničesar.",
        "watchlist": "Spisek nadzorov",
        "mywatchlist": "Spisek nadzorov",
        "watchlistfor2": "Za $1 $2",
-       "nowatchlist": "Vaš spisek nadzorov je prazen.",
+       "nowatchlist": "Tvoj spisek nadzorov je prazen.",
        "watchlistanontext": "Za pregled ali urejanje vsebine vašega spiska nadzorov se morate prijaviti.",
        "watchnologin": "Niste prijavljeni",
        "addwatch": "Dodaj na spisek nadzorov",
        "dellogpage": "Dnevnik brisanja",
        "dellogpagetext": "Spodaj je prikazan seznam nedavnih brisanj.",
        "deletionlog": "dnevnik brisanja",
+       "log-name-create": "Dnevnik ustvarjanja strani",
+       "log-description-create": "Spodaj je prikazan seznam nedavnih ustvarjanj strani.",
+       "logentry-create-create": "$1 je {{GENDER:$2|ustvaril|ustvarila|ustvaril(-a)}} stran $3",
        "reverted": "Vrnjeno na prejšnjo redakcijo.",
        "deletecomment": "Razlog:",
        "deleteotherreason": "Drugi/dodatni razlogi:",
        "uctop": "(trenutno)",
        "month": "Od meseca (in prej):",
        "year": "Od leta (in prej):",
+       "date": "Od datuma (in prej):",
        "sp-contributions-newbies": "Prikaži samo prispevke novih računov",
        "sp-contributions-newbies-sub": "Prispevki novincev",
        "sp-contributions-newbies-title": "Uporabniški prispevki novih računov",
        "whatlinkshere": "Kaj se povezuje sem",
        "whatlinkshere-title": "Strani, ki se povezujejo na $1",
        "whatlinkshere-page": "Stran:",
-       "linkshere-2": "Na '''$1''' kažejo naslednje strani:",
-       "nolinkshere-2": "Nobena stran ne kaže na '''$1'''.",
-       "nolinkshere-ns-2": "Nobena stran se ne povezuje na '''$1''' v izbranem imenskem prostoru.",
+       "linkshere": "Na '''$1''' kažejo naslednje strani:",
+       "nolinkshere": "Nobena stran ne kaže na <strong>$2</strong>.",
+       "nolinkshere-ns": "Nobena stran se ne povezuje na <strong>$2</strong> v izbranem imenskem prostoru.",
        "isredirect": "preusmeritvena stran",
        "istemplate": "vključitev",
        "isimage": "povezava na datoteko",
        "markedaspatrollederrornotify": "Označevanje kot nadzorovano ni uspelo.",
        "patrol-log-page": "Dnevnik patrulje",
        "patrol-log-header": "To je dnevnik nadzorovanih redakcij.",
-       "log-show-hide-patrol": "$1 dnevnik nadzora",
-       "log-show-hide-tag": "$1 dnevnik oznak",
        "confirm-markpatrolled-button": "V redu",
        "confirm-markpatrolled-top": "Označimo redakcijo $3 strani $2 kot nadzorovano?",
        "deletedrevision": "Prejšnja redakcija $1 je izbrisana",
        "exif-lightsource-19": "Običajna svetloba C",
        "exif-lightsource-24": "ISO-ateljejski volfram",
        "exif-lightsource-255": "Drugačen",
-       "exif-flash-fired-0": "Flash se ni sprožil",
-       "exif-flash-fired-1": "Flash se je sprožil",
+       "exif-flash-fired-0": "Bliskavica se ni sprožila",
+       "exif-flash-fired-1": "Bliskavica se je sprožila",
        "exif-flash-return-0": "stroboskop ni uporabil funkcije zaznavanja",
        "exif-flash-return-2": "stroboskop ni zaznal svetlobe",
        "exif-flash-return-3": "stroboskop je zaznal svetlobo",
        "lag-warn-high": "Zaradi visoke zasedenosti strežniških podatkovnih baz, spremembe novejše od $1 {{PLURAL:$1|sekunde|sekund}} morda ne bodo prikazane na seznamu.",
        "watchlistedit-normal-title": "Uredi spisek nadzorov",
        "watchlistedit-normal-legend": "Odstrani strani iz spiska nadzorov",
-       "watchlistedit-normal-explain": "Strani na vašem spisku nadzorov so prikazane spodaj.\nDa odstranite stran, označite kvadratek poleg nje in kliknite »{{int:Watchlistedit-normal-submit}}«.\nLahko tudi [[Special:EditWatchlist/raw|uredite gol spisek]].",
+       "watchlistedit-normal-explain": "Spodaj so prikazane strani tvojega spiska nadzorov.\nZa odstranitev strani označi kvadratek poleg nje in klikni »{{int:Watchlistedit-normal-submit}}«.\nLahko tudi [[Special:EditWatchlist/raw|urediš gol spisek]].",
        "watchlistedit-normal-submit": "Odstrani strani",
        "watchlistedit-normal-done": "Z vašega spiska nadzorov {{PLURAL:$1|je bila odstranjena $1 stran|sta bili odstranjeni $1 strani|so bile odstranjene $1 strani|je bilo odstranjenih $1 strani}}:",
        "watchlistedit-raw-title": "Urejanje golega spiska nadzorov",
        "watchlistedit-raw-added": "{{PLURAL:$1|Dodana je bila $1 stran|Dodani sta bili $1 strani|Dodane so bile $1 strani|Dodanih je bilo $1 strani}}:",
        "watchlistedit-raw-removed": "{{PLURAL:$1|Odstranjena je bila $1 stran|Odstranjeni sta bili 2 strani|Odstranjene so bile $1 strani|Odstranjenih je bilo $1 strani}}:",
        "watchlistedit-clear-title": "Počisti spisek nadzorov",
-       "watchlistedit-clear-legend": "Počistite spisek nadzorov",
+       "watchlistedit-clear-legend": "Počisti spisek nadzorov",
        "watchlistedit-clear-explain": "Vse naslove bomo odstranili z vašega spiska nadzorov",
        "watchlistedit-clear-titles": "Naslovi:",
        "watchlistedit-clear-submit": "Počisti spisek nadzorov (To je trajno!)",
        "pagedata-text": "Ta stran nudi podatkovni vmesnik do strani. Prosimo, navedite naslov strani v URL-ju z uporabo skladnje podstrani.\n* Pogajanje o vsebini se nanaša na glavo Accept vašega odjemalca. To pomeni, da bomo podatke strani posredovali v obliki, ki vašemu odjemalcu bolj ustreza.",
        "pagedata-not-acceptable": "Nismo našli ujemajoče oblike. Podprte vrste MIME: $1",
        "pagedata-bad-title": "Neveljaven naslov: $1.",
-       "unregistered-user-config": "Iz varnostnih razlogov uporabniških podstrani JavaScript, CSS in JSON ne moremo naložiti neregistriranim uporabnikom."
+       "unregistered-user-config": "Iz varnostnih razlogov uporabniških podstrani JavaScript, CSS in JSON ne moremo naložiti neregistriranim uporabnikom.",
+       "passwordpolicies": "Pravilniki gesel",
+       "passwordpolicies-summary": "To je seznam trenutno veljavnih pravilnikov gesel za uporabniške skupine, opredeljene v tem wikiju.",
+       "passwordpolicies-group": "Skupina",
+       "passwordpolicies-policies": "Pravilniki",
+       "passwordpolicies-policy-minimalpasswordlength": "Geslo mora dolgo biti vsaj $1 {{PLURAL:$1|znak|znaka|znake|znakov}}",
+       "passwordpolicies-policy-minimumpasswordlengthtologin": "Geslo mora biti dolgo vsaj $1 {{PLURAL:$1|znak|znaka|znake|znakov}}, da je omogočena prijava",
+       "passwordpolicies-policy-passwordcannotmatchusername": "Geslo ne more biti enako kot uporabniško ime",
+       "passwordpolicies-policy-passwordcannotmatchblacklist": "Geslo se ne sme ujemati s posebej prepovedanimi gesli",
+       "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}}",
+       "easydeflate-invaliddeflate": "Dana vsebina ni pravilno stisnjena"
 }
index e468f4d..2514d5b 100644 (file)
        "whatlinkshere": "Links uff de Seite",
        "whatlinkshere-title": "Seyta, de uff „$1“ verlinka",
        "whatlinkshere-page": "Seite:",
-       "linkshere-2": "De folgenden Seyta verlinka uff '''„$1“''':",
-       "nolinkshere-2": "Kenne Seite verlinkt uff '''„$1“'''.",
-       "nolinkshere-ns-2": "Kenne Seite verlinkt uff '''„$1“''' eim gewählta Noamasraum.",
+       "linkshere": "De folgenden Seyta verlinka uff '''„$1“''':",
+       "nolinkshere": "Kenne Seite verlinkt uff '''„$2“'''.",
+       "nolinkshere-ns": "Kenne Seite verlinkt uff '''„$2“''' eim gewählta Noamasraum.",
        "isredirect": "Weiterleitungsseyte",
        "istemplate": "Vorlageneinbindung",
        "isimage": "Dateilink",
        "markedaspatrollederror-noautopatrol": "Is ies ne erlaubt, eigene Beoarbeetunga ols kontrolliert zu markieren.",
        "patrol-log-page": "Kontroll-Logbichl",
        "patrol-log-header": "Dies ies doas Kontroll-Logbuch.",
-       "log-show-hide-patrol": "Kontroll-Logbichl $1",
        "deletedrevision": "aale Version: $1",
        "filedeleteerror-short": "Fahler bei Datei-Läschung: $1",
        "filedeleteerror-long": "Bei dar Datei-Läschung wurden Fahler festgestellt:\n\n$1",
index 1aac592..726c5d4 100644 (file)
        "whatlinkshere": "Maxaa meeshaan la xiriiro",
        "whatlinkshere-title": "Boggaga la xiriiro \"$1\"",
        "whatlinkshere-page": "Bogga:",
-       "linkshere-2": "Bogyaashaan waxey la xiriiraan  '''$1''':",
-       "nolinkshere-2": "Boggag la xiriiro   '''$1''' ma jirto.",
+       "linkshere": "Bogyaashaan waxey la xiriiraan  '''$1''':",
+       "nolinkshere": "Boggag la xiriiro   '''$2''' ma jirto.",
        "isredirect": "bogga loo sii toosiyay",
        "istemplate": "ku jiri kara",
        "isimage": "faylka la xiriiro",
index a0cf5bf..d1f3d62 100644 (file)
                        "Arianit",
                        "Denisa",
                        "Fanjiayi",
-                       "Fitoschido"
+                       "Fitoschido",
+                       "Luanibraj",
+                       "Matěj Suchánek",
+                       "Bjakupi"
                ]
        },
        "tog-underline": "Nënvizimi i lidhjes:",
        "rcfilters-watchlist-markseen-button": "Shenjo të gjitha ndryshimet si të para",
        "rcfilters-watchlist-edit-watchlist-button": "Redakto listën tuaj të faqeve të mbikëqyrura",
        "rcfilters-preference-label": "Fshih versionin e përmirësuar të Ndryshimeve të Fundit",
+       "rcfilters-watchlist-preference-label": "Fshehni versionin e permiresuar te Listes-vrojtuese",
+       "rcfilters-watchlist-preference-help": "E kthen nderfaqen e ri-dizajnit te 2017 dhe te gjitha mjetet atehere dhe qe nga ai moment.",
        "rcfilters-target-page-placeholder": "Shto një emër faqeje (ose kategorie)",
        "rcnotefrom": "Më poshtë {{PLURAL:$5|është shfaqur ndryshimi|janë shfaqur ndryshimet}} që nga <strong>$3, $4</strong> (deri në <strong>$1</strong>).",
        "rclistfromreset": "Anulo përzgjedhjen e datës",
        "dellogpage": "Regjistri i grisjeve",
        "dellogpagetext": "Më poshtë është një listë e grisjeve më të fundit.",
        "deletionlog": "regjistrin e grisjeve",
+       "log-name-create": "Krijimi i faqes logjike",
+       "log-description-create": "Me poshte eshte nje liste e krimit te faqeve me te fundit",
+       "logentry-create-create": "$1{{GENDER:$2|created}} faqe $3",
        "reverted": "Kthehu tek një version i vjetër",
        "deletecomment": "Arsyeja:",
        "deleteotherreason": "Arsye tjetër:",
        "whatlinkshere": "Lidhjet këtu",
        "whatlinkshere-title": "Faqe që lidhen tek $1",
        "whatlinkshere-page": "Faqja:",
-       "linkshere-2": "Faqet e mëposhtme lidhen këtu '''$1''':",
-       "nolinkshere-2": "Asnjë faqe nuk lidhet tek '''$1'''.",
-       "nolinkshere-ns-2": "Nuk ka faqe në hapësirën e zgjedhur që lidhen tek '''$1'''.",
+       "linkshere": "Faqet e mëposhtme lidhen këtu '''$1''':",
+       "nolinkshere": "Asnjë faqe nuk lidhet me <strong>$2</strong>.",
+       "nolinkshere-ns": "Asnjë faqe nuk lidhet me<strong>$2</strong> në hapësirën e zgjedhur të emrit.",
        "isredirect": "faqe përcjellëse",
        "istemplate": "përfshirë",
        "isimage": "Lidhja e dokumentit",
        "importlogpage": "Regjistri i importeve",
        "importlogpagetext": "Importimet administrative të faqeve me historik redaktimi nga wiki-t e tjera.",
        "import-logentry-upload-detail": "$1 {{PLURAL:$1|version|versione}} u importuan",
-       "import-logentry-interwiki-detail": "$1 {{PLURAL:$!1|version|versione}} u importuan nga $2",
+       "import-logentry-interwiki-detail": "$1 {{PLURAL:$1|version|versione}} u importuan nga $2",
        "javascripttest": "Duke testuar JavaScript",
        "javascripttest-pagetext-unknownaction": "Veprim i panjohur \"$1\".",
        "javascripttest-qunit-intro": "Shiko [$1 dokumentacionin e testimit] në mediawiki.org.",
        "markedaspatrollederrornotify": "Shënimi si i patrulluar dështoi.",
        "patrol-log-page": "Regjistri i patrollimeve",
        "patrol-log-header": "Këto janë të dhëna të revizioneve të patrulluara.",
-       "log-show-hide-patrol": "$1 regjistri i patrollimeve",
-       "log-show-hide-tag": "$1 regjistri i etiketave",
        "confirm-markpatrolled-button": "Në rregull",
        "confirm-markpatrolled-top": "Shëno versionin $3 nga $2 si të patrolluar",
        "deletedrevision": "Gris versionin e vjetër $1",
index e7a03f1..388d26f 100644 (file)
@@ -38,7 +38,8 @@
                        "Acamicamacaraca",
                        "BokicaK",
                        "BadDog",
-                       "Fitoschido"
+                       "Fitoschido",
+                       "Stalker"
                ]
        },
        "tog-underline": "Подвлачење веза:",
@@ -49,8 +50,8 @@
        "tog-extendwatchlist": "Прошири списак надгледања за приказ свих измена, не само скорашњих",
        "tog-usenewrc": "Групиши измене по страници у скорашњим изменама и списку надгледања",
        "tog-numberheadings": "Аутоматски нумериши поднаслове",
-       "tog-showtoolbar": "Ð\9fÑ\80икажи Ñ\82Ñ\80акÑ\83 Ñ\81 алаткама за уређивање",
-       "tog-editondblclick": "Уређивање страница двоструким кликом",
+       "tog-showtoolbar": "ТÑ\80ака Ñ\81а алаткама за уређивање",
+       "tog-editondblclick": "Уреди странице двоструким кликом",
        "tog-editsectiononrightclick": "Уређивање одељака десним кликом на њихове наслове",
        "tog-watchcreations": "Додај странице које направим и датотеке које отпремим у мој списак надгледања",
        "tog-watchdefault": "Додај странице и датотеке које изменим у мој списак надгледања",
@@ -66,7 +67,7 @@
        "tog-enotifminoredits": "Пошаљи ми имејл и код мањих измена страница и датотека",
        "tog-enotifrevealaddr": "Откриј моју имејл адресу у порукама обавештења",
        "tog-shownumberswatching": "Прикажи број корисника који надгледају",
-       "tog-oldsig": "Ваш тренутни потпис:",
+       "tog-oldsig": "Ваш постојећи потпис:",
        "tog-fancysig": "Сматрај потпис као викитекст (без самоповезивања)",
        "tog-uselivepreview": "Прикажи претпреглед без поновног учитавања странице",
        "tog-forceeditsummary": "Упозори ме када не унесем опис измене",
@@ -81,7 +82,7 @@
        "tog-watchlisthidecategorization": "Сакриј категоризацију страница",
        "tog-ccmeonemails": "Пошаљи ми копије имејлова које пошаљем другим корисницима",
        "tog-diffonly": "Не приказуј садржај странице испод разлика",
-       "tog-showhiddencats": "Ð\9fÑ\80икажи Ñ\81кривене категорије",
+       "tog-showhiddencats": "Скривене категорије",
        "tog-norollbackdiff": "Не приказуј разлику након извршеног враћања",
        "tog-useeditwarning": "Упозори ме када напуштам страницу са несачуваним изменама",
        "tog-prefershttps": "Увек користи сигурну везу док сам пријављен.",
        "december-date": "$1. децембар",
        "period-am": "преподне",
        "period-pm": "поподне",
-       "pagecategories": "{{PLURAL:$1|Категорија|Категорије|Категорија}}",
+       "pagecategories": "{{PLURAL:$1|Категорија|Категорије}}",
        "category_header": "Странице у категорији „$1“",
        "subcategories": "Поткатегорије",
        "category-media-header": "Датотеке у категорији „$1“",
        "variants": "Варијанте",
        "navigation-heading": "Навигациони мени",
        "errorpagetitle": "Грешка",
-       "returnto": "Назад на $1.",
+       "returnto": "Назад на страницу „$1“.",
        "tagline": "Извор: {{SITENAME}}",
        "help": "Помоћ",
        "search": "Претрага",
        "permalink": "Трајна веза",
        "print": "Штампај",
        "view": "Погледај",
-       "view-foreign": "Ð\92иди на пројекту $1",
+       "view-foreign": "Ð\9fогледаÑ\98 на пројекту $1",
        "edit": "Уреди",
        "edit-local": "Уреди локални опис",
        "create": "Направи",
        "pool-servererror": "Услуга бројача редова није доступна ($1).",
        "poolcounter-usage-error": "Грешка при употреби: $1",
        "aboutsite": "О пројекту {{SITENAME}}",
-       "aboutpage": "Project:О нама",
+       "aboutpage": "Project:О_пројекту_{{SITENAME}}",
        "copyright": "Садржај је доступан под лиценцом $1 осим ако је другачије наведено.",
        "copyrightpage": "{{ns:project}}:Ауторска права",
        "currentevents": "Актуелности",
        "pagetitle-view-mainpage": "{{SITENAME}}",
        "backlinksubtitle": "← $1",
        "retrievedfrom": "Преузето из „$1“",
-       "youhavenewmessages": "Имате $1 ($2).",
+       "youhavenewmessages": "{{PLURAL:$3|Имате}} $1 ($2).",
        "youhavenewmessagesfromusers": "{{PLURAL:$4|Имате}} $1 од {{PLURAL:$3|другог корисника|$3 корисника}} ($2).",
        "youhavenewmessagesmanyusers": "Имате $1 од много корисника ($2).",
        "newmessageslinkplural": "{{PLURAL:$1|нову поруку|нове поруке|нових порука}}",
        "youhavenewmessagesmulti": "Имате нове поруке на $1",
        "editsection": "уреди",
        "editold": "уреди",
-       "viewsourceold": "изворни код",
+       "viewsourceold": "изворник",
        "editlink": "уреди",
-       "viewsourcelink": "изворни код",
-       "editsectionhint": "Уреди одељак „$1“",
+       "viewsourcelink": "изворник",
+       "editsectionhint": "Уредите одељак „$1“",
        "toc": "Садржај",
        "showtoc": "прикажи",
        "hidetoc": "сакриј",
-       "collapsible-collapse": "Скупи",
-       "collapsible-expand": "Ð\9fрикажи",
+       "collapsible-collapse": "сакриј",
+       "collapsible-expand": "прикажи",
        "confirmable-confirm": "Да ли {{GENDER:$1|сте}} сигурни?",
        "confirmable-yes": "Да",
        "confirmable-no": "Не",
        "perfcached": "Следећи подаци су кеширани и можда нису ажурирани. У кешу {{PLURAL:$1|је доступан највише један резултат|су доступна највише $1 резултата|је доступно највише $1 резултата}}.",
        "perfcachedts": "Следећи подаци су кеширани и последњи пут ажурирани на датум $2 у $3 ч. У кешу {{PLURAL:$4|је доступан највише један резултат|су доступна највише $4 резултата|је доступно највише $4 резултата}}.",
        "querypage-no-updates": "Ажурирање ове странице је тренутно онемогућено.\nПодаци који се овде налазе могу бити застарели.",
-       "viewsource": "Изворни код",
-       "viewsource-title": "Изворни код за страницу $1",
+       "viewsource": "Изворник",
+       "viewsource-title": "Изворник странице $1",
        "actionthrottled": "Радња је успорена",
        "actionthrottledtext": "У циљу борбе против непожељних порука, ограничене су вам измене у одређеном времену, а управо сте прешли то ограничење. Покушајте поново за неколико минута.",
        "protectedpagetext": "Ова страница је закључана за измене и друге радње.",
-       "viewsourcetext": "Можете читати и копирати изворник ове странице.",
-       "viewyourtext": "Ð\9cожеÑ\82е Ð´Ð° Ð¿Ð¾Ð³Ð»ÐµÐ´Ð°Ñ\82е Ð¸ ÐºÐ¾Ð¿Ð¸Ñ\80аÑ\82е Ð¸Ð·Ð²Ð¾Ñ\80ник <strong>ваших измена</strong> на овој страници.",
+       "viewsourcetext": "Можете да читате и копирате изворник ове странице.",
+       "viewyourtext": "Ð\9cожеÑ\82е Ð´Ð° Ð¿Ð¾Ð³Ð»ÐµÐ´Ð°Ñ\82е Ð¸ ÐºÐ¾Ð¿Ð¸Ñ\80аÑ\82е Ð¸Ð·Ð²Ð¾Ñ\80ник <strong>Ð\92аших измена</strong> на овој страници.",
        "protectedinterface": "Ова страница садржи текст интерфејса за софтвер на овом викију и заштићена је ради спречавања злоупотребе.\nДа бисте додали или изменили преводе било којег викија, посетите [https://translatewiki.net/ translatewiki.net], пројекат за локализацију Медијавикија.",
        "editinginterface": "<strong>Упозорење:</strong> уређујете страницу која се користи за приказивање текста корисничког окружења.\nИзмене на овој страници ће утицати на све кориснике овог викија.",
        "translateinterface": "Да додате или промените преводе за све викије, посетите [https://translatewiki.net/ Транслејтвики], пројекат за локализацију Медијавикија.",
        "customcssprotected": "Немате дозволу да мењате ову CSS страницу јер садржи лична подешавања другог корисника.",
        "customjsprotected": "Немате дозволу да мењате ову страницу JavaScript јер садржи лична подешавања другог корисника.",
        "mycustomcssprotected": "Немате дозволу за мењање ове CSS странице.",
+       "mycustomjsonprotected": "Немате дозволу за мењање ове JSON странице.",
        "mycustomjsprotected": "Немате дозволу за мењање ове JavaScript странице.",
        "myprivateinfoprotected": "Немате дозволу за мењање ваших личних информација.",
        "mypreferencesprotected": "Немате дозволу за мењање ваших подешавања.",
        "virus-badscanner": "Неисправно подешавање: непознати скенер за вирусе: <em>$1</em>",
        "virus-scanfailed": "неуспешно скенирање (код $1)",
        "virus-unknownscanner": "непознати антивирус:",
-       "logouttext": "<strong>Ð\9eдÑ\98авÑ\99ени Ñ\81Ñ\82е.</strong>\n\nÐ\98маÑ\98Ñ\82е Ð½Ð° Ñ\83мÑ\83 Ð´Ð° Ð½ÐµÐºÐµ Ñ\81Ñ\82Ñ\80аниÑ\86е Ð¼Ð¾Ð³Ñ\83 Ð½Ð°Ñ\81Ñ\82авиÑ\82и Ð´Ð° Ñ\81е Ð¿Ñ\80иказÑ\83Ñ\98Ñ\83 ÐºÐ°Ð¾ Ð´Ð° Ñ\81Ñ\82е Ñ\98оÑ\88 Ð¿Ñ\80иÑ\98авÑ\99ени, Ñ\81ве Ð´Ð¾Ðº Ð½Ðµ Ð¾Ñ\87иÑ\81Ñ\82иÑ\82е Ð¿Ñ\80ивÑ\80еменÑ\83 Ð¼ÐµÐ¼Ð¾Ñ\80иÑ\98Ñ\83 Ð\92аÑ\88ег прегледача.",
+       "logouttext": "<strong>Сада Ñ\81Ñ\82е Ð¾Ð´Ñ\98авÑ\99ени.</strong>\n\nÐ\97апамÑ\82иÑ\82е Ð´Ð° Ð½ÐµÐºÐµ Ñ\81Ñ\82Ñ\80аниÑ\86е Ð¼Ð¾Ð³Ñ\83 Ð´Ð° Ð½Ð°Ñ\81Ñ\82аве Ð´Ð° Ñ\81е Ð¿Ñ\80иказÑ\83Ñ\98Ñ\83 ÐºÐ°Ð¾ Ð´Ð° Ñ\81Ñ\82е Ñ\98оÑ\88 Ñ\83век Ð¿Ñ\80иÑ\98авÑ\99ени, Ð´Ð¾Ðº Ð½Ðµ Ð¾Ñ\87иÑ\81Ñ\82иÑ\82е Ð¿Ñ\80ивÑ\80еменÑ\83 Ð¼ÐµÐ¼Ð¾Ñ\80иÑ\98Ñ\83 Ñ\81вог прегледача.",
        "cannotlogoutnow-title": "Одјава тренутно није могућа",
        "cannotlogoutnow-text": "Одјава није могућа током употребе $1.",
        "welcomeuser": "Добро дошли, $1!",
        "userlogin-yourpassword-ph": "Унесите своју лозинку",
        "createacct-yourpassword-ph": "Унесите лозинку",
        "yourpasswordagain": "Поново унеси лозинку:",
-       "createacct-yourpasswordagain": "Потврди лозинку",
+       "createacct-yourpasswordagain": "Потврдите лозинку",
        "createacct-yourpasswordagain-ph": "Унесите лозинку поново",
        "userlogin-remembermypassword": "Остави ме пријављеног/у",
        "userlogin-signwithsecure": "Користите сигурну конекцију",
        "userlogout": "Одјава",
        "notloggedin": "Нисте пријављени",
        "userlogin-noaccount": "Немате налог?",
-       "userlogin-joinproject": "Ð\9eÑ\82воÑ\80иÑ\82е Ð³Ð°",
+       "userlogin-joinproject": "Ð\9fÑ\80идÑ\80Ñ\83жиÑ\82е Ñ\81е Ð¿Ñ\80оÑ\98екÑ\82Ñ\83 {{SITENAME}}",
        "createaccount": "Отвори налог",
        "userlogin-resetpassword-link": "Заборавили сте лозинку?",
        "userlogin-helplink2": "Помоћ при пријављивању",
        "nocookieslogin": "{{SITENAME}} користи колачиће за пријављивање корисника.\nВама су колачићи онемогућени. Омогућите их и покушајте поново.",
        "nocookiesfornew": "Кориснички налог није отворен јер његов извор није потврђен.\nОмогућите колачиће на прегледачу и поново учитајте страницу.",
        "nocookiesforlogin": "{{int:nocookieslogin}}",
+       "createacct-loginerror": "Налог је успешно направљен, али се не можете аутоматски пријавити. Пређите на [[Special:UserLogin|ручно пријављивање]].",
        "noname": "Унели сте неисправно корисничко име.",
        "loginsuccesstitle": "Успешно пријављивање",
        "loginsuccess": "<strong>Пријављени сте на {{SITENAME}} као „$1”.</strong>",
        "wrongpasswordempty": "Нисте унели лозинку. Покушајте поново.",
        "passwordtooshort": "Лозинка мора имати најмање {{PLURAL:$1|један знак|$1 знака|$1 знакова}}.",
        "passwordtoolong": "Лозинке не могу бити дуже од {{PLURAL:$1|$1 знака|$1 знакова}}.",
-       "passwordtoopopular": "ЧеÑ\81Ñ\82о ÐºÐ¾Ñ\80иÑ\88Ñ\9bене Ñ\88иÑ\84Ñ\80е Ð½Ðµ Ð¼Ð¾Ð³Ñ\83 Ð±Ð¸Ñ\82и ÐºÐ¾Ñ\80иÑ\88Ñ\9bене. Ð\9cолимо Ð¸Ð·Ð°Ð±ÐµÑ\80иÑ\82е Ñ\81ложениÑ\98Ñ\83 Ð»Ð¾Ð·Ð¸Ð½ÐºÑ\83.",
+       "passwordtoopopular": "ЧеÑ\81Ñ\82о Ð¸Ð·Ð°Ð±Ñ\80ане Ð»Ð¾Ð·Ð¸Ð½ÐºÐµ Ð½Ðµ Ð¼Ð¾Ð³Ñ\83 Ð´Ð° Ñ\81е ÐºÐ¾Ñ\80иÑ\81Ñ\82е. Ð\98забеÑ\80иÑ\82е Ð»Ð¾Ð·Ð¸Ð½ÐºÑ\83 ÐºÐ¾Ñ\98Ñ\83 Ñ\98е Ñ\82еже Ð¿Ð¾Ð³Ð¾Ð´Ð¸Ñ\82и.",
        "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Ако је неко други затражио промену лозинке, или сте се сетили ваше лозинке и не желите да је мењате, занемарите ову поруку.",
+       "passwordremindertext": "Неко са IP адресе $1 је затражио нову лозинку на викију {{SITENAME}} ($4).\nСтворена је привремена лозинка за {{GENDER:$2|корисника|корисницу|корисника}} $2 која гласи $3.\nУколико је ово ваш захтев, сада се пријавите и поставите нову лозинку.\nПривремена лозинка истиче за {{PLURAL:$5|један дан|$5 дана}}.\n\nАко је неко други затражио промену лозинке, или сте се сетили ваше лозинке и не желите да је мењате, занемарите ову поруку.",
        "noemail": "Не постоји имејл адреса за {{GENDER:$1|корисника|корисницу}} $1.",
        "noemailcreate": "Морате навести исправну имејл адресу.",
        "passwordsent": "Нова лозинка је послата на имејл адресу {{GENDER:$1|корисника|кориснице|корисника}} $1.\nПријавите се пошто је примите.",
        "acct_creation_throttle_hit": "Посетиоци овог викија који користе вашу IP адресу су већ отворили {{PLURAL:$1|1=један налог|$1 налога}} претходни $2, што је највећи дозвољени број у том временском периоду.\nЗбог тога посетиоци с ове IP адресе тренутно не могу отворити више налога.",
        "emailauthenticated": "Ваша имејл адреса је потврђена на дан $2 у $3.",
        "emailnotauthenticated": "Ваша имејл адреса још увек није потврђена.\nИмејл неће бити послат ни у једном од следећих случајева.",
-       "noemailprefs": "УнеÑ\81иÑ\82е Ð¸Ð¼ÐµÑ\98л Ð°Ð´Ñ\80еÑ\81Ñ\83 ÐºÐ°ÐºÐ¾ Ð±Ð¸ Ð¾Ð²Ðµ Ð¼Ð¾Ð³Ñ\83Ñ\9bноÑ\81Ñ\82и Ñ\80адиле.",
+       "noemailprefs": "Ð\9dаведиÑ\82е Ð¸Ð¼ÐµÑ\98л Ð°Ð´Ñ\80еÑ\81Ñ\83 Ñ\83 Ñ\81воÑ\98им Ð¿Ð¾Ð´ÐµÑ\88аваÑ\9aима Ð·Ð° Ñ\80ад Ð¾Ð²Ð¸Ñ\85 Ð¼Ð¾Ð³Ñ\83Ñ\9bноÑ\81Ñ\82и.",
        "emailconfirmlink": "Потврдите своју имејл адресу",
        "invalidemailaddress": "Имејл адреса не може бити прихваћена јер је неисправног облика.\nУнесите исправну адресу или оставите празно поље.",
        "cannotchangeemail": "На овом викију не можете променити имејл адресу налога.",
        "changepassword-throttled": "Превише пута сте покушали да се пријавите.\nМолимо вас да сачекате $1 пре него што покушате поново.",
        "botpasswords": "Лозинке ботова",
        "botpasswords-disabled": "Лозинке ботова су онемогућене.",
+       "botpasswords-no-central-id": "Да би сте користили ботовске лозинке, морате бити пријављени на средишњи налог.",
        "botpasswords-existing": "Постојећа лозинка бота",
        "botpasswords-createnew": "Направи нову лозинку за бота",
        "botpasswords-editexisting": "Измени постојећу лозинку за бота",
+       "botpasswords-label-needsreset": "(лозинку треба ресетовати)",
        "botpasswords-label-appid": "Име бота:",
        "botpasswords-label-create": "Направи",
        "botpasswords-label-update": "Ажурирај",
        "botpasswords-label-resetpassword": "Ресетуј лозинку",
        "botpasswords-label-grants": "Применљиве дозволе:",
        "botpasswords-label-grants-column": "Одобрено",
-       "botpasswords-bad-appid": "„$1” није валидан назив бота.",
+       "botpasswords-bad-appid": "Име бота „$1” није валидно.",
        "botpasswords-insert-failed": "Неуспешно додавање бота \"$1\". Да ли је већ додат?",
        "botpasswords-update-failed": "Није могуће ажурирати бота \"$1\". Да ли је обрисан?",
        "botpasswords-created-title": "Направљена лозинка бота",
        "resetpass-submit-loggedin": "Промени лозинку",
        "resetpass-submit-cancel": "Откажи",
        "resetpass-wrong-oldpass": "Неисправна привремена или тренутна лозинка.\nМожда сте већ променили лозинку или сте затражили нову привремену лозинку.",
-       "resetpass-recycled": "Унели сте садашњу лозинку, да бисте ресетовали лозинку морате унети нову.",
+       "resetpass-recycled": "Унели сте садашњу лозинку, да бисте променили лозинку морате унети нову.",
        "resetpass-temp-emailed": "Пријавили сте се са привременим кодом из имејла.\nДа бисте завршили пријављивање морате поставити нову лозинку овде:",
        "resetpass-temp-password": "Привремена лозинка:",
        "resetpass-abort-generic": "Промену лозинке је спречио додатак.",
        "resetpass-expired": "Ваша лозинка је истекла. Поставите нову лозинку да бисте се пријавили.",
-       "resetpass-expired-soft": "Ваша лозинка је истекла и морате поставити нову. Поставите нову лозинку или кликните „{{int:authprovider-resetpass-skip-label}}“ да је поставите касније.",
-       "resetpass-validity-soft": "Ð\92аÑ\88а Ð»Ð¾Ð·Ð¸Ð½ÐºÐ° Ð½Ð¸Ñ\98е Ð¸Ñ\81пÑ\80авна: $1\n\nÐ\9cолимо Ð¸Ð·Ð°Ð±ÐµÑ\80иÑ\82е Ð½Ð¾Ð²Ñ\83 Ð¸Ð»Ð¸ ÐºÐ»Ð¸ÐºÐ½Ð¸Ñ\82е â\80\9e{{int:authprovider-resetpass-skip-label}}â\80\9c Ð´Ð° Ñ\80еÑ\81еÑ\82Ñ\83Ñ\98ете касније.",
+       "resetpass-expired-soft": "Ваша лозинка је истекла и морате је променити. Поставите нову лозинку или кликните „{{int:authprovider-resetpass-skip-label}}“ да је промените касније.",
+       "resetpass-validity-soft": "Ð\92аÑ\88а Ð»Ð¾Ð·Ð¸Ð½ÐºÐ° Ð½Ð¸Ñ\98е Ð¸Ñ\81пÑ\80авна: $1\n\nÐ\9cолимо Ð¸Ð·Ð°Ð±ÐµÑ\80иÑ\82е Ð½Ð¾Ð²Ñ\83 Ð¸Ð»Ð¸ ÐºÐ»Ð¸ÐºÐ½Ð¸Ñ\82е â\80\9e{{int:authprovider-resetpass-skip-label}}â\80\9c Ð´Ð° Ñ\98е Ð¿Ñ\80омените касније.",
        "passwordreset": "Обнављање лозинке",
        "passwordreset-text-one": "Попуните овај образац да бисте добили привремену лозинку на имејл.",
        "passwordreset-text-many": "{{PLURAL:$1|Испуните једно од поља како бисте добили привремену лозинку на имејл.}}",
        "subject-preview": "Преглед теме:",
        "previewerrortext": "Догодила се грешка приликом приказивања ваших измена.",
        "blockedtitle": "Корисник је блокиран",
-       "blockedtext": "<strong>Ð\92аÑ\88е ÐºÐ¾Ñ\80иÑ\81ниÑ\87ко Ð¸Ð¼Ðµ Ð¸Ð»Ð¸ IP Ð°Ð´Ñ\80еÑ\81а Ñ\98е Ð±Ð»Ð¾ÐºÐ¸Ñ\80ана.</strong>\n\nÐ\91локиÑ\80аÑ\9aе Ñ\98е {{GENDER:$4|извÑ\80Ñ\88ио|извÑ\80Ñ\88ила}} $1.\nРазлог Ñ\98е <em>$2</em>.\n\n* Ð\94аÑ\82Ñ\83м Ð±Ð»Ð¾ÐºÐ¸Ñ\80аÑ\9aа: $8\n* Ð\91локиÑ\80аÑ\9aе Ð¸Ñ\81Ñ\82иÑ\87е: $6\n* Ð\98ме ÐºÐ¾Ñ\80иÑ\81ника: $7\n\nÐ\9eбÑ\80аÑ\82иÑ\82е Ñ\81е {{GENDER:$4|коÑ\80иÑ\81никÑ\83|коÑ\80иÑ\81ниÑ\86и}} $1 Ð¸Ð»Ð¸ [[{{MediaWiki:Grouppage-sysop}}|админиÑ\81Ñ\82Ñ\80аÑ\82оÑ\80Ñ\83]] Ð´Ð° Ñ\80азÑ\98аÑ\81ниÑ\82е Ñ\81Ñ\82ваÑ\80.\nÐ\9dе Ð¼Ð¾Ð¶ÐµÑ\82е ÐºÐ¾Ñ\80иÑ\81Ñ\82иÑ\82и Ð¼Ð¾Ð³Ñ\83Ñ\9bноÑ\81Ñ\82 â\80\9eÐ\9fоÑ\88аÑ\99и Ð¸Ð¼ÐµÑ\98л Ð¾Ð²Ð¾Ð¼ ÐºÐ¾Ñ\80иÑ\81никÑ\83â\80\9c Ð°ÐºÐ¾ Ð½Ð¸Ñ\81Ñ\82е Ñ\83нели Ð¸Ñ\81пÑ\80авнÑ\83 Ð¸Ð¼ÐµÑ\98л Ð°Ð´Ñ\80еÑ\81Ñ\83 Ñ\83 [[Special:Preferences|подеÑ\88аваÑ\9aима]].\nÐ\92аÑ\88а Ð±Ð»Ð¾ÐºÐ¸Ñ\80ана IP Ð°Ð´Ñ\80еÑ\81а Ñ\98е $3, Ð° ID Ð±Ð»Ð¾ÐºÐ¸Ñ\80аÑ\9aа $5.\nÐ\9dаведиÑ\82е Ñ\81ве Ð¿Ð¾Ð´Ð°Ñ\82ке Ð¸Ð·Ð½Ð°Ð´ при стварању било каквих упита.",
-       "autoblockedtext": "Ваша IP адреса је блокирана јер ју је употребљавао други корисник, кога је {{GENDER:$4|блокирао|блокирала}} $1.\nРазлог:\n\n:<em>$2</em>\n\n* Датум блокирања: $8\n* Блокирање истиче: $6\n* Име корисника: $7\n\nОбратите се {{GENDER:$4|кориснику|корисници}} $1 или [[{{MediaWiki:Grouppage-sysop}}|администратору]] да разјасните ствар.\n\nНе можете користити могућност „Пошаљи имејл овом кориснику“ ако нисте унели исправну имејл адресу у [[Special:Preferences|подешавањима]].\n\nВаша блокирана IP адреса је $3, а ID $5.\nНаведите све податке изнад при стварању било каквих упита.",
+       "blockedtext": "<strong>Ð\92аÑ\88е ÐºÐ¾Ñ\80иÑ\81ниÑ\87ко Ð¸Ð¼Ðµ Ð¸Ð»Ð¸ IP Ð°Ð´Ñ\80еÑ\81а Ñ\98е Ð±Ð»Ð¾ÐºÐ¸Ñ\80ана.</strong>\n\nÐ\91локиÑ\80аÑ\9aе Ñ\98е {{GENDER:$4|извÑ\80Ñ\88ио|извÑ\80Ñ\88ила}} $1.\nРазлог Ñ\98е <em>$2</em>.\n\n* Ð\9fоÑ\87еÑ\82ак Ð±Ð»Ð¾ÐºÐ¸Ñ\80аÑ\9aа: $8\n* Ð\98Ñ\81Ñ\82ек Ð±Ð»Ð¾ÐºÐ¸Ñ\80аÑ\9aа: $6\n* Ð\91локиÑ\80ани: $7\n\nÐ\9cожеÑ\82е Ð´Ð° Ñ\81е Ð¾Ð±Ñ\80аÑ\82иÑ\82е {{GENDER:$4|коÑ\80иÑ\81никÑ\83|коÑ\80иÑ\81ниÑ\86и}} $1 Ð¸Ð»Ð¸ [[{{MediaWiki:Grouppage-sysop}}|админиÑ\81Ñ\82Ñ\80аÑ\82оÑ\80Ñ\83]] Ñ\80ади Ð´Ð¸Ñ\81кÑ\83Ñ\81иÑ\98е Ð¾ Ð±Ð»Ð¾ÐºÐ¸Ñ\80аÑ\9aÑ\83.\nÐ\9dе Ð¼Ð¾Ð¶ÐµÑ\82е Ð´Ð° ÐºÐ¾Ñ\80иÑ\81Ñ\82иÑ\82е Ð¼Ð¾Ð³Ñ\83Ñ\9bноÑ\81Ñ\82 â\80\9e{{int:emailuser}}â\80\9d Ð¾Ñ\81им Ð°ÐºÐ¾ Ñ\81Ñ\82е Ñ\83нели Ð²Ð°Ð»Ð¸Ð´Ð½Ñ\83 Ð¸Ð¼ÐµÑ\98л Ð°Ð´Ñ\80еÑ\81Ñ\83 Ñ\83 Ñ\81воÑ\98им [[Special:Preferences|подеÑ\88аваÑ\9aима]] Ð½Ð°Ð»Ð¾Ð³Ð° Ð¸ Ð½Ð¸Ñ\81Ñ\82е Ð±Ð»Ð¾ÐºÐ¸Ñ\80ани Ð¾Ð´ ÐºÐ¾Ñ\80иÑ\88Ñ\9bеÑ\9aа Ð¸Ñ\81Ñ\82е.\nÐ\92аÑ\88а Ñ\82Ñ\80енÑ\83Ñ\82на IP Ð°Ð´Ñ\80еÑ\81а Ñ\98е $3, Ð° ID Ð±Ð»Ð¾ÐºÐ¸Ñ\80аÑ\9aа #$5.\nÐ\9dаведиÑ\82е Ñ\81ве Ð¸Ð½Ñ\84оÑ\80маÑ\86иÑ\98е Ð¾Ð´Ð¾Ð·Ð³Ð¾ при стварању било каквих упита.",
+       "autoblockedtext": "Ваша IP адреса је блокирана јер ју је употребљавао други корисник, кога је {{GENDER:$4|блокирао|блокирала}} $1.\nРазлог:\n\n:<em>$2</em>\n\n* Датум блокирања: $8\n* Блокирање истиче: $6\n* Име корисника: $7\n\nОбратите се {{GENDER:$4|кориснику|корисници}} $1 или [[{{MediaWiki:Grouppage-sysop}}|администратору]] да разјасните ствар.\n\nНе можете користити могућност „{{int:emailuser}}“ ако нисте унели исправну имејл адресу у [[Special:Preferences|подешавањима]].\n\nВаша блокирана IP адреса је $3, а ID $5.\nНаведите све податке изнад при стварању било каквих упита.",
        "blockednoreason": "разлог није наведен",
        "whitelistedittext": "За уређивање странице је потребно да будете $1.",
        "confirmedittext": "Морате да потврдите своју имејл адресу пре уређивања страница.\nПоставите и потврдите имејл адресу преко [[Special:Preferences|подешавања]].",
        "newarticle": "(нови)",
        "newarticletext": "Дошли сте на страницу која још не постоји.\nДа бисте је направили, почните да куцате у прозор испод овог текста (погледајте [$1 страницу за помоћ]).\nАко сте овде дошли грешком, вратите се на претходну страницу.",
        "anontalkpagetext": "----\n<em>Ово је страница за разговор с анонимним корисником који још нема налог или га не користи.</em>\nЗбог тога морамо да користимо бројчану IP адресу како бисмо га препознали.\nТакву адресу може делити више корисника.\nАко сте анонимни корисник и мислите да су вам упућене примедбе, [[Special:CreateAccount|отворите налог]] или се [[Special:UserLogin|пријавите]] да бисте избегли будућу забуну с осталим анонимним корисницима.",
-       "noarticletext": "Ð\9dа Ð¾Ð²Ð¾Ñ\98 Ñ\81Ñ\82Ñ\80аниÑ\86и Ñ\82Ñ\80енÑ\83Ñ\82но Ð½ÐµÐ¼Ð° Ñ\81адÑ\80жаÑ\98а.\nМожете [[Special:Search/{{PAGENAME}}|потражити овај наслов]] на другим страницама,\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} претражити сродне извештаје] или [{{fullurl:{{FULLPAGENAME}}|action=edit}} направити ову страницу]</span>.",
-       "noarticletext-nopermission": "Ð\9dа Ð¾Ð²Ð¾Ñ\98 Ñ\81Ñ\82Ñ\80аниÑ\86и Ñ\82Ñ\80енÑ\83Ñ\82но Ð½ÐµÐ¼Ð° Ñ\81адÑ\80жаÑ\98а.\nМожете [[Special:Search/{{PAGENAME}}|потражити овај наслов]] на другим страницама или <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} претражити сродне дневнике]</span>, али немате дозволу да направите ову страницу.",
+       "noarticletext": "Ð\9dа Ð¾Ð²Ð¾Ñ\98 Ñ\81Ñ\82Ñ\80аниÑ\86и Ñ\82Ñ\80енÑ\83Ñ\82но Ð½ÐµÐ¼Ð° Ñ\82екÑ\81Ñ\82а.\nМожете [[Special:Search/{{PAGENAME}}|потражити овај наслов]] на другим страницама,\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} претражити сродне извештаје] или [{{fullurl:{{FULLPAGENAME}}|action=edit}} направити ову страницу]</span>.",
+       "noarticletext-nopermission": "Ð\9dа Ð¾Ð²Ð¾Ñ\98 Ñ\81Ñ\82Ñ\80аниÑ\86и Ñ\82Ñ\80енÑ\83Ñ\82но Ð½ÐµÐ¼Ð° Ñ\82екÑ\81Ñ\82а.\nМожете [[Special:Search/{{PAGENAME}}|потражити овај наслов]] на другим страницама или <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} претражити сродне дневнике]</span>, али немате дозволу да направите ову страницу.",
        "missing-revision": "Не могу да пронађем измену бр. $1 на страници под називом „{{FULLPAGENAME}}“.\n\nОво се обично дешава када пратите застарелу везу до странице која је обрисана.\nВише информација можете пронаћи у [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} дневнику брисања].",
        "userpage-userdoesnotexist": "Кориснички налог „<nowiki>$1</nowiki>“ није отворен.\nРазмислите да ли заиста желите да направите/уредите ову страницу.",
        "userpage-userdoesnotexist-view": "Кориснички налог „$1“ није отворен.",
        "blocked-notice-logextract": "Овај корисник је тренутно блокиран.\nИзвештај о последњем блокирању можете погледати испод:",
-       "clearyourcache": "<strong>Ð\9dапомена:</strong> Ð½Ð°ÐºÐ¾Ð½ Ñ\87Ñ\83ваÑ\9aа, Ð¼Ð¾Ð¶Ð´Ð° Ñ\9bеÑ\82е Ð¼Ð¾Ñ\80аÑ\82и Ð´Ð° Ð¾Ñ\87иÑ\81Ñ\82иÑ\82е ÐºÐµÑ\88 Ð¿Ñ\80егледаÑ\87а ÐºÐ°ÐºÐ¾ Ð±Ð¸Ñ\81Ñ\82е Ð²Ð¸Ð´ÐµÐ»Ð¸ Ð¸Ð·Ð¼ÐµÐ½Ðµ.\n* <strong>ФаÑ\98еÑ\80Ñ\84окÑ\81 / Ð¡Ð°Ñ\84аÑ\80и:</strong> Ð´Ñ\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> Ð¿Ñ\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> Ð´Ñ\80жиÑ\82е <em>Ctrl</em> Ð¸ ÐºÐ»Ð¸ÐºÐ½Ð¸Ñ\82е Ð½Ð° <em>Ð\9eÑ\81вежи</em> Ð¸Ð»Ð¸ Ð¿Ñ\80иÑ\82иÑ\81ниÑ\82е <em>Ctrl-F5</em>\n* <strong>Ð\9eпеÑ\80а:</strong> Ð¸Ð´Ð¸Ñ\82е Ð½Ð° <em>Ð\90лаÑ\82ке â\86\92 Ð\9fодеÑ\88аваÑ\9aа</em> (<em>Ð\9eпеÑ\80а â\86\92 Ð\9fоÑ\81Ñ\82авке</em> на Меку) и затим <em>Приватност и безбедност → Очистите податке о прегледима → Кеширане слике и датотеке</em>.",
+       "clearyourcache": "<strong>Ð\9dапомена:</strong> Ð\9dакон Ñ\87Ñ\83ваÑ\9aа, Ð¼Ð¾Ð¶Ð´Ð° Ñ\9bеÑ\82е Ð¼Ð¾Ñ\80аÑ\82и Ð´Ð° Ð¾Ñ\87иÑ\81Ñ\82иÑ\82е ÐºÐµÑ\88 Ð¿Ñ\80егледаÑ\87а ÐºÐ°ÐºÐ¾ Ð±Ð¸Ñ\81Ñ\82е Ð²Ð¸Ð´ÐµÐ»Ð¸ Ð¸Ð·Ð¼ÐµÐ½Ðµ.\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> на Меку) и затим <em>Приватност и безбедност → Очистите податке о прегледима → Кеширане слике и датотеке</em>.",
        "usercssyoucanpreview": "<strong>Савет:<strong> кориситите дугме „{{int:showpreview}}“ да испробате свој нови CSS пре него што га сачувате.",
        "userjsyoucanpreview": "<strong>Савет:</strong> кориситите дугме „{{int:showpreview}}“ да испробате свој нови јаваскрипт пре него што га сачувате.",
        "usercsspreview": "<strong>Ово је само преглед CSS-а.\nСтраница још није сачувана!</strong>",
        "editpage-cannot-use-custom-model": "Модел садржаја ове странице се не може променити.",
        "longpageerror": "<strong>Грешка: текст који сте унели је величине {{PLURAL:$1|један килобајт|$1 килобајта}}, што је веће од {{PLURAL:$2|дозвољеног једног килобајта|дозвољена $2 килобајта|дозвољених $2 килобајта}}.</strong>\nСтраница не може бити сачувана.",
        "readonlywarning": "<strong>Упозорење: база података је закључана ради одржавања, тако да тренутно нећете моћи да сачувате измене.</strong>\nМожда бисте желели сачувати текст за касније у некој текстуалној датотеци.\n\nСистемски администратор је навео следеће објашњење: $1",
-       "protectedpagewarning": "<strong>УпозоÑ\80еÑ\9aе: Ð¾Ð²Ð° Ñ\81Ñ\82Ñ\80аниÑ\86а Ñ\98е Ð·Ð°Ñ\88Ñ\82иÑ\9bена, Ñ\82ако Ð´Ð° Ñ\81амо Ð°Ð´Ð¼Ð¸Ð½Ð¸Ñ\81Ñ\82Ñ\80аÑ\82оÑ\80и Ð¼Ð¾Ð³Ñ\83 Ð´Ð° Ñ\98е Ð¼ÐµÑ\9aаÑ\98Ñ\83.</strong>\nÐ\9fоÑ\81ледÑ\9aи Ð·Ð°Ð¿Ð¸Ñ\81 Ñ\83 Ð´Ð½ÐµÐ²Ð½Ð¸ÐºÑ\83 Ñ\98е Ð¿Ñ\80иказан Ð¸Ñ\81под:",
-       "semiprotectedpagewarning": "<strong>Ð\9dапомена:</strong> Ð\9eва Ñ\81Ñ\82Ñ\80аниÑ\86а Ñ\98е Ð·Ð°Ñ\88Ñ\82иÑ\9bена, Ñ\82ако Ð´Ð° Ñ\81амо Ñ\80егиÑ\81Ñ\82Ñ\80овани ÐºÐ¾Ñ\80иÑ\81ниÑ\86и Ð¼Ð¾Ð³Ñ\83 Ð´Ð° Ñ\98е Ñ\83Ñ\80еÑ\92Ñ\83Ñ\98Ñ\83.\nÐ\9fоÑ\81ледÑ\9aи Ð·Ð°Ð¿Ð¸Ñ\81 Ñ\83 Ð´Ð½ÐµÐ²Ð½Ð¸ÐºÑ\83 Ñ\98е Ð¿Ñ\80иказан Ð¸Ñ\81под:",
+       "protectedpagewarning": "<strong>УпозоÑ\80еÑ\9aе: Ð¾Ð²Ð° Ñ\81Ñ\82Ñ\80аниÑ\86а Ñ\98е Ð·Ð°Ñ\88Ñ\82иÑ\9bена, Ñ\82ако Ð´Ð° Ñ\81амо ÐºÐ¾Ñ\80иÑ\81ниÑ\86и Ñ\81 Ð°Ð´Ð¼Ð¸Ð½Ð¸Ñ\81Ñ\82Ñ\80аÑ\82оÑ\80Ñ\81ким Ð¾Ð²Ð»Ð°Ñ\88Ñ\9bеÑ\9aима Ð¼Ð¾Ð³Ñ\83 Ð´Ð° Ñ\98е Ð¼ÐµÑ\9aаÑ\98Ñ\83.</strong>\nÐ\9fоÑ\81ледÑ\9aи Ð·Ð°Ð¿Ð¸Ñ\81 Ñ\83 Ð´Ð½ÐµÐ²Ð½Ð¸ÐºÑ\83 Ñ\98е Ð¿Ñ\80иказан Ð¸Ñ\81под ÐºÐ°Ð¾ Ñ\80еÑ\84еÑ\80енÑ\86а:",
+       "semiprotectedpagewarning": "<strong>Ð\9dапомена:</strong> Ð¾Ð²Ð° Ñ\81Ñ\82Ñ\80аниÑ\86а Ñ\98е Ð·Ð°Ñ\88Ñ\82иÑ\9bена, Ñ\82ако Ð´Ð° Ñ\81амо Ð°Ñ\83Ñ\82омаÑ\82Ñ\81ки Ð¿Ð¾Ñ\82вÑ\80Ñ\92ени ÐºÐ¾Ñ\80иÑ\81ниÑ\86и Ð¼Ð¾Ð³Ñ\83 Ð´Ð° Ñ\98е Ñ\83Ñ\80еÑ\92Ñ\83Ñ\98Ñ\83.\nÐ\9fоÑ\81ледÑ\9aи Ð·Ð°Ð¿Ð¸Ñ\81 Ñ\83 Ð´Ð½ÐµÐ²Ð½Ð¸ÐºÑ\83 Ñ\98е Ð¿Ñ\80иказан Ð¸Ñ\81под ÐºÐ°Ð¾ Ñ\80еÑ\84еÑ\80енÑ\86а:",
        "cascadeprotectedwarning": "<strong>Упозорење:</strong> Ова страница је заштићена тако да је могу уређивати само корисници са [[Special:ListGroupRights|одређеним правима]] (администратори), јер је иста укључена у {{PLURAL:$1|следећу страницу која је заштићена|следеће странице које су заштићене}} „преносивом” заштитом:",
-       "titleprotectedwarning": "<strong>Упозорење: ову страницу могу направити само корисници [[Special:ListGroupRights|с одређеним правима]].</strong>\nПоследњи запис у дневнику је приказан испод:",
+       "titleprotectedwarning": "<strong>Упозорење: ова страница је заштићена, тако да су потребна [[Special:ListGroupRights|посебна правима]] да се она направи.</strong>\nПоследњи запис у дневнику је приказан испод као референца:",
        "templatesused": "{{PLURAL:$1|Шаблон који се користи|Шаблони који се користе}} на овој страници:",
        "templatesusedpreview": "{{PLURAL:$1|Шаблон|Шаблони}} у овом претпрегледу:",
        "templatesusedsection": "{{PLURAL:$1|Шаблон|Шаблони}} у овом одељку:",
        "permissionserrorstext-withaction": "Немате дозволу за $2 из {{PLURAL:$1|следећег|следећих}} разлога:",
        "contentmodelediterror": "Не можете уредити ову измену јер је њен модел садржаја <code>$1</code>, што се разликује од тренутног модела садржаја странице <code>$2</code>.",
        "recreate-moveddeleted-warn": "<strong>Упозорење: поново правите страницу која је претходно обрисана.</strong>\n\nРазмотрите да ли је прикладно да наставите с уређивањем ове странице.\nОвде је наведена историја брисања и премештања с образложењем:",
-       "moveddeleted-notice": "Ð\9eва Ñ\81Ñ\82Ñ\80аниÑ\86а Ñ\98е Ð¾Ð±Ñ\80иÑ\81ана.\nÐ\98Ñ\81Ñ\82оÑ\80иÑ\98а Ñ\9aеног Ð±Ñ\80иÑ\81аÑ\9aа, Ð·Ð°Ñ\88Ñ\82иÑ\82е Ð¸ Ð¿Ñ\80емеÑ\88Ñ\82аÑ\9aа Ð½Ð°Ð»Ð°Ð·Ð¸ Ñ\81е Ð¸Ñ\81под:",
+       "moveddeleted-notice": "Ð\9eва Ñ\81Ñ\82Ñ\80аниÑ\86а Ñ\98е Ð¾Ð±Ñ\80иÑ\81ана.\nÐ\94невник Ð±Ñ\80иÑ\81аÑ\9aа, Ð·Ð°Ñ\88Ñ\82иÑ\82е Ð¸ Ð¿Ñ\80емеÑ\88Ñ\82аÑ\9aа Ñ\81Ñ\82Ñ\80аниÑ\86е Ð½Ð°Ð»Ð°Ð·Ð¸ Ñ\81е Ð¸Ñ\81под.",
        "moveddeleted-notice-recent": "Жао нам је, ова страница је недавно обрисана (у последњих 24 сата).\nИсторија њеног брисања, заштите и премештања налази се испод:",
        "log-fulllog": "Погледај целу историју",
        "edit-hook-aborted": "Измену је прекинула кука.\nНије дато никакво образложење.",
        "viewpagelogs": "Дневници ове странице",
        "nohistory": "Не постоји историја измена ове странице.",
        "currentrev": "Тренутна измена",
-       "currentrev-asof": "Ð\9fоÑ\81ледÑ\9aа измена на датум $2 у $3",
+       "currentrev-asof": "ТÑ\80енÑ\83Ñ\82на измена на датум $2 у $3",
        "revisionasof": "Измена на датум $2 у $3",
        "revision-info": "Измена од $1 од стране {{GENDER:$6|корисника $2|кориснице $2}}$7",
        "previousrevision": "← Старија измена",
        "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": "најновије",
        "rev-suppressed-diff-view": "Једна од измена ове разлике је '''сакривена'''.\nИпак можете да видите ову разлику; више детаља можете наћи у [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} историји сакривања].",
        "rev-delundel": "промени видљивост",
        "rev-showdeleted": "прикажи",
-       "revisiondelete": "Ð\9eбÑ\80иÑ\88и/вÑ\80аÑ\82и Ð¸Ð·Ð¼ÐµÐ½Ðµ",
+       "revisiondelete": "Ð\91Ñ\80иÑ\81аÑ\9aе/вÑ\80аÑ\9bаÑ\9aе Ð¸Ð·Ð¼ÐµÐ½Ð°",
        "revdelete-nooldid-title": "Нема тражене измене",
        "revdelete-nooldid-text": "Нисте изабрали одредишну измену на којој треба да се изврши ова функција, та измена не постоји, или покушавате сакрити тренутну измену.",
        "revdelete-no-file": "Тражена датотека не постоји.",
        "revertmerge": "растави",
        "mergelogpagetext": "Испод је списак најскоријих спајања историја двеју страница.",
        "history-title": "Историја измена странице „$1“",
-       "difference-title": "$1 — разлика између измена",
+       "difference-title": "Разлика између измена на страници „$1”",
        "difference-title-multipage": "Разлика између страница „$1“ и „$2“",
        "difference-multipage": "(разлике између страница)",
        "lineno": "Ред $1:",
        "compareselectedversions": "Упореди изабране измене",
        "showhideselectedversions": "Промени видљивост изабраних измена",
        "editundo": "поништи",
-       "diff-empty": "(Ð\9dема разлике)",
+       "diff-empty": "(нема разлике)",
        "diff-multi-sameuser": "({{PLURAL:$1|Једна међуизмена истог корисника није приказана|$1 међуизмене истог корисника нису приказане|$1 међуизмена истог корисника није приказано}})",
        "diff-multi-otherusers": "({{PLURAL:$1|Једна међуизмена|$1 међуизмене|$1 међуизмена}} од стране {{PLURAL:$2|још једног корисника није приказана|$2 корисника није приказано}})",
        "diff-multi-manyusers": "({{PLURAL:$1|Није приказана међуизмена|Нису приказане $1 међуизмене|Није приказано $1 међуизмена}} од више од $2 корисника)",
        "next-page": "следећа страница",
        "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": "<strong>Постоји страница под називом „[[:$1]]”!</strong> {{PLURAL:$2|0=|Такође погледајте друге пронађене резултате претраге.}}",
-       "searchmenu-new": "<strong>Направите страницу „[[:$1]]”!</strong> {{PLURAL:$2|0=|Такође погледајте резултат претраге.|Такође погледајте резултате претраге.}}",
+       "searchmenu-new": "<strong>Направите страницу „[[:$1]]” на овом викију!</strong> {{PLURAL:$2|0=|Такође погледајте резултат претраге.|Такође погледајте резултате претраге.}}",
        "searchprofile-articles": "Странице са садржајем",
        "searchprofile-images": "Датотеке",
        "searchprofile-everything": "Све",
        "searchprofile-images-tooltip": "Претражите датотеке",
        "searchprofile-everything-tooltip": "Претражите сав садржај (укључујући странице за разговор)",
        "searchprofile-advanced-tooltip": "Претражите прилагођене именске просторе",
-       "search-result-size": "$1 ({{PLURAL:$2|1 реч|$2 речи|$2 речи}})",
+       "search-result-size": "$1 ({{PLURAL:$2|1 реч|$2 речи}})",
        "search-result-category-size": "{{PLURAL:$1|1 члан|$1 члана|$1 чланова}}, ({{PLURAL:$2|1 поткатегорија|$2 поткатегорије|$2 поткатегорија}}, {{PLURAL:$3|1 датотека|$3 датотеке|$3 датотека}})",
-       "search-redirect": "(преусмерено са $1)",
+       "search-redirect": "(преусмерење са $1)",
        "search-section": "(одељак $1)",
        "search-category": "(категорија $1)",
        "search-file-match": "(подудара се садржај датотеке)",
-       "search-suggest": "Да ли сте мислили на: $1",
+       "search-suggest": "Да ли сте мислили: $1",
        "search-rewritten": "Приказани резултати за $1. Ипак претражи $2.",
        "search-interwiki-caption": "Резултати са сестринских пројеката",
        "search-interwiki-default": "Резултати са $1:",
        "showingresults": "Испод {{PLURAL:$1|је приказан <strong>1</strong> резултат|су приказана <strong>$1</strong> резултата|је приказано <strong>$1</strong> резултата}}, почев од броја <strong>$2</strong>.",
        "showingresultsinrange": "Испод {{PLURAL:$1|је приказан <strong>1</strong> резултат|су приказана <strong>$1</strong> резултата|је приказано <strong>$1</strong> резултата}}, у распону од <strong>$2</strong> до <strong>$3</strong>.",
        "search-showingresults": "{{PLURAL:$4|Резултат <strong>$1</strong> од <strong>$3</strong>|Резултати <strong>$1—$2</strong> од <strong>$3</strong>}}",
-       "search-nonefound": "Ð\9dема Ð¿Ð¾ÐºÐ»Ð°Ð¿Ð°Ñ\9aа.",
+       "search-nonefound": "Ð\9dиÑ\81Ñ\83 Ð¿Ñ\80онаÑ\92ени Ñ\80езÑ\83лÑ\82аÑ\82и ÐºÐ¾Ñ\98и Ð¾Ð´Ð³Ð¾Ð²Ð°Ñ\80аÑ\98Ñ\83 Ñ\83пиÑ\82Ñ\83.",
        "search-nonefound-thiswiki": "Нема резултата на овом сајту који се поклапају са термином претраге.",
        "powersearch-legend": "Напредна претрага",
        "powersearch-ns": "Претрага по именским просторима:",
        "powersearch-togglelabel": "Изабери:",
        "powersearch-toggleall": "Све",
        "powersearch-togglenone": "Ништа",
-       "powersearch-remember": "Ð\97апамÑ\82и Ð¼Ð¾Ñ\98 Ð¸Ð·Ð±Ð¾Ñ\80 Ð·Ð° Ð±Ñ\83дÑ\83Ñ\9bе Ð¿Ñ\80еÑ\82Ñ\80аге",
+       "powersearch-remember": "Запамти избор за будуће претраге",
        "search-external": "Спољашња претрага",
        "searchdisabled": "Претрага је онемогућена.\nУ међувремену можете тражити преко Гугла.\nУпамтите да његови пописи овог викија могу бити застарели.",
        "search-error": "Дошло је до грешке приликом претраге: $1",
        "prefs-watchlist-days": "Број дана у списку надгледања:",
        "prefs-watchlist-days-max": "Највише $1 {{PLURAL:$1|дан|дана|дана}}",
        "prefs-watchlist-edits": "Највећи број измена приказаних на списку надгледања:",
-       "prefs-watchlist-edits-max": "Ð\9dаÑ\98веÑ\9bа Ð²Ñ\80едноÑ\81Ñ\82 Ñ\98е Ñ\85иÑ\99адÑ\83",
+       "prefs-watchlist-edits-max": "Ð\9dаÑ\98веÑ\9bи Ð±Ñ\80оÑ\98: 1000",
        "prefs-watchlist-token": "Жетон списка надгледања:",
+       "prefs-watchlist-managetokens": "Управљај жетонима",
        "prefs-misc": "Друга подешавања",
        "prefs-resetpass": "промени лозинку",
        "prefs-changeemail": "промени или уклони имејл адресу",
-       "prefs-setemail": "Ð\9fостави имејл адресу",
-       "prefs-email": "Ð\9fодеÑ\88аваÑ\9aа имејла",
+       "prefs-setemail": "постави имејл адресу",
+       "prefs-email": "Ð\9eпÑ\86иÑ\98е имејла",
        "prefs-rendering": "Изглед",
        "saveprefs": "Сачувај",
-       "restoreprefs": "Ð\92Ñ\80аÑ\82и Ñ\81ве Ð½Ð° Ð¿Ð¾Ð´Ñ\80азÑ\83мевано (у свим одељцима)",
+       "restoreprefs": "Ð\92Ñ\80аÑ\82и Ñ\81ва Ð¿Ð¾Ð´Ñ\80азÑ\83мевана Ð¿Ð¾Ð´ÐµÑ\88аваÑ\9aа (у свим одељцима)",
        "prefs-editing": "Уређивање",
        "searchresultshead": "Претрага",
        "stub-threshold": "Праг за обликовање везе као клице ($1):",
        "recentchangesdays": "Број дана у скорашњим изменама:",
        "recentchangesdays-max": "Највише $1 {{PLURAL:$1|дан|дана}}",
        "recentchangescount": "Подразумевани број измена за приказ у скорашњим изменама, историјама страница и дневницима:",
-       "prefs-help-recentchangescount": "Ð\9dаÑ\98веÑ\9bа Ð²Ñ\80едноÑ\81Ñ\82: 1000",
-       "prefs-help-watchlist-token2": "Ово је тајни кључ за веб-довод Вашег списка надгледања. \nСвако ко зна овај кључ биће у могућности да види Ваш списак надгледања, зато кључ немојте одавати никоме. \nАко је потребно, кључ [[Special:ResetTokens|можете ресетовати]].",
+       "prefs-help-recentchangescount": "Ð\9dаÑ\98веÑ\9bа Ð±Ñ\80оÑ\98: 1000",
+       "prefs-help-watchlist-token2": "Ово је тајни кључ за веб-довод Вашег списка надгледања. \nСвако ко зна овај кључ биће у могућности да чита Ваш списак надгледања, зато га немојте делити. \nАко је потребно, [[Special:ResetTokens|можете га обновити]].",
        "savedprefs": "Ваша подешавања су сачувана.",
        "savedrights": "Корисничке групе за {{GENDER:$1|$1}} су сачуване.",
        "timezonelegend": "Временска зона:",
        "timezoneregion-europe": "Европа",
        "timezoneregion-indian": "Индијски океан",
        "timezoneregion-pacific": "Тихи океан",
-       "allowemail": "Ð\9eмогÑ\83Ñ\9bи примање имејлова од других корисника",
-       "email-allow-new-users-label": "Ð\9eмогÑ\83Ñ\9bи примање имејлова од новајлија",
-       "email-blacklist-label": "Забрани следећим корисницима да ми шаљу имејлове:",
+       "allowemail": "Ð\94озволи примање имејлова од других корисника",
+       "email-allow-new-users-label": "Ð\94озволи примање имејлова од новајлија",
+       "email-blacklist-label": "Забрани примање имејлова од следећих корисника:",
        "prefs-searchoptions": "Претрага",
        "prefs-namespaces": "Именски простори",
        "default": "подразумевана",
        "prefs-emailconfirm-label": "Потврда имејла:",
        "youremail": "Имејл:",
        "username": "{{GENDER:$1|Корисничко име}}:",
-       "prefs-memberingroups": "{{PLURAL:$1|Група|Групе}}:",
+       "prefs-memberingroups": "{{GENDER:$2|Члан|Чланица}} {{PLURAL:$1|групе|група}}:",
        "prefs-memberingroups-type": "$1",
        "group-membership-link-with-expiry": "$1 (до $2)",
        "prefs-registration": "Време регистрације:",
        "yourvariant": "Варијанта језика:",
        "prefs-help-variant": "Жељена варијанта или правопис за приказ страница са садржајем овог викија.",
        "yournick": "Нови потпис:",
-       "prefs-help-signature": "Коментари на страницама за разговор би требали бити потписани с „<nowiki>~~~~</nowiki>“ што ће бити претворено у Ваш потпис и време.",
+       "prefs-help-signature": "Коментари на страницама за разговор треба да буду потписани са „<nowiki>~~~~</nowiki>“ које ће бити претворено у Ваш потпис с тренутним временом.",
        "badsig": "Потпис је неисправан.\nПроверите ознаке HTML.",
        "badsiglength": "Ваш потпис је предугачак.\nНе сме бити дужи од $1 {{PLURAL:$1|знака|знака|знакова}}.",
        "yourgender": "Како желите да се представите?",
-       "gender-unknown": "Ð\9dе Ð¶ÐµÐ»Ð¸Ð¼ Ð´Ð° Ñ\81е Ð¿Ñ\80едÑ\81Ñ\82авим",
+       "gender-unknown": "Ð\9aад Ð\92аÑ\81 Ñ\81помиÑ\9aе, Ñ\81оÑ\84Ñ\82веÑ\80 Ñ\9bе ÐºÐ¾Ñ\80иÑ\81Ñ\82иÑ\82и Ñ\80одно Ð½ÐµÑ\83Ñ\82Ñ\80алне Ñ\80еÑ\87и ÐºÐ°Ð´ Ð³Ð¾Ð´ Ñ\98е Ñ\82о Ð¼Ð¾Ð³Ñ\83Ñ\9bе",
        "gender-male": "Он уређује вики странице",
        "gender-female": "Она уређује вики странице",
-       "prefs-help-gender": "Ð\9dеобавезно: ÐºÐ¾Ñ\80иÑ\81Ñ\82и Ñ\81е Ð·Ð° Ð¸Ñ\81пÑ\80авно Ð¾Ð±Ñ\80аÑ\9bаÑ\9aе Ñ\81оÑ\84Ñ\82веÑ\80а ÐºÐ¾Ñ\80иÑ\81ниÑ\86има, Ð·Ð°Ð²Ð¸Ñ\81но Ð¾Ð´ Ñ\9aиÑ\85овог Ð¿Ð¾Ð»Ð°.\nÐ\9eваÑ\98 Ð¿Ð¾Ð´Ð°Ñ\82ак Ñ\9bе Ð±Ð¸Ñ\82и Ñ\98аван.",
+       "prefs-help-gender": "Ð\9fоÑ\81Ñ\82авÑ\99аÑ\9aе Ð¾Ð²Ð¾Ð³ Ð¿Ð¾Ð´ÐµÑ\88аваÑ\9aа Ñ\98е Ð½ÐµÐ¾Ð±Ð°Ð²ÐµÐ·Ð½Ð¾.\nСоÑ\84Ñ\82веÑ\80 ÐºÐ¾Ñ\80иÑ\81Ñ\82и Ð´Ð°Ñ\82Ñ\83 Ð²Ñ\80едноÑ\81Ñ\82 Ð´Ð° Ð±Ð¸ Ð\92ам Ñ\81е Ð¾Ð±Ñ\80аÑ\82ио Ð¸ Ñ\81поменÑ\83о Ð\92аÑ\81 Ð´Ñ\80Ñ\83гима ÐºÐ¾Ñ\80иÑ\81Ñ\82еÑ\9bи Ð¾Ð´Ð³Ð¾Ð²Ð°Ñ\80аÑ\98Ñ\83Ñ\9bи Ð³Ñ\80амаÑ\82иÑ\87ки Ñ\80од.\nÐ\9eва Ð¸Ð½Ñ\84оÑ\80маÑ\86иÑ\98а Ñ\9bе Ð±Ð¸Ñ\82и Ñ\98авна.",
        "email": "Имејл",
        "prefs-help-realname": "Право име није обавезно.\nАко изаберете да га унесете, оно ће бити коришћено за приписивање вашег рада.",
-       "prefs-help-email": "Имејл адреса није обавезна, али је потребна у случају да заборавите лозинку.",
-       "prefs-help-email-others": "Ð\9cожеÑ\82е Ñ\98е ÐºÐ¾Ñ\80иÑ\81Ñ\82иÑ\82и Ð¸ Ð´Ð° Ð¾Ð¼Ð¾Ð³Ñ\83Ñ\9bиÑ\82е Ð´Ñ\80Ñ\83гима Ð´Ð° Ð²Ð°Ñ\81 ÐºÐ¾Ð½Ñ\82акÑ\82иÑ\80аÑ\98Ñ\83 Ð¿Ñ\80еко ÐºÐ¾Ñ\80иÑ\81ниÑ\87ке Ñ\81Ñ\82Ñ\80аниÑ\86е Ð¸Ð»Ð¸ Ñ\81Ñ\82Ñ\80аниÑ\86е Ð·Ð° Ñ\80азговоÑ\80, Ð±ÐµÐ· Ð¾Ñ\82кÑ\80иваÑ\9aа Ñ\81вог Ð¸Ð´ÐµÐ½Ñ\82иÑ\82еÑ\82а.",
+       "prefs-help-email": "Имејл адреса није обавезна, али је потребна за обнављање лозинке, ако је заборавите.",
+       "prefs-help-email-others": "ТакоÑ\92е Ð¼Ð¾Ð¶ÐµÑ\82е Ð¸Ð·Ð°Ð±Ñ\80аÑ\82и Ð´Ð° Ð´Ð¾Ð¿Ñ\83Ñ\81Ñ\82иÑ\82е Ð´Ñ\80Ñ\83гима Ð´Ð° Ð\92аÑ\81 ÐºÐ¾Ð½Ñ\82акÑ\82иÑ\80аÑ\98Ñ\83 Ð¿Ñ\80еко Ð¸Ð¼ÐµÑ\98ла Ð¿Ñ\83Ñ\82ем Ð²ÐµÐ·Ðµ Ð½Ð° Ð\92аÑ\88оÑ\98 ÐºÐ¾Ñ\80иÑ\81ниÑ\87коÑ\98 Ñ\81Ñ\82Ñ\80аниÑ\86и Ð¸Ð»Ð¸ Ñ\81Ñ\82Ñ\80аниÑ\86и Ð·Ð° Ñ\80азговоÑ\80.\nÐ\92аÑ\88а Ð¸Ð¼ÐµÑ\98л Ð°Ð´Ñ\80еÑ\81а Ð½ÐµÑ\9bе Ð±Ð¸Ñ\82и Ð¿Ñ\80иказана Ð´Ñ\80Ñ\83гим ÐºÐ¾Ñ\80иÑ\81ниÑ\86има ÐºÐ¾Ñ\98и Ð\92аÑ\81 ÐºÐ¾Ð½Ñ\82акÑ\82иÑ\80аÑ\98Ñ\83.",
        "prefs-help-email-required": "Потребна је имејл адреса.",
-       "prefs-info": "Ð\9eÑ\81новни Ð¿Ð¾Ð´Ð°Ñ\86и",
+       "prefs-info": "Ð\9eÑ\81новне Ð¸Ð½Ñ\84оÑ\80маÑ\86иÑ\98е",
        "prefs-i18n": "Интернационализација",
        "prefs-signature": "Потпис",
        "prefs-dateformat": "Формат датума",
        "prefs-timeoffset": "Временска разлика",
        "prefs-advancedediting": "Главна подешавања",
+       "prefs-developertools": "Програмерске алатке",
        "prefs-editor": "Уређивач",
        "prefs-preview": "Претпреглед",
-       "prefs-advancedrc": "Ð\9dапÑ\80една Ð¿Ð¾Ð´ÐµÑ\88аваÑ\9aа",
+       "prefs-advancedrc": "Ð\9dапÑ\80едне Ð¾Ð¿Ñ\86иÑ\98е",
        "prefs-opt-out": "Онемогућавање побољшања",
-       "prefs-advancedrendering": "Ð\9dапÑ\80една Ð¿Ð¾Ð´ÐµÑ\88аваÑ\9aа",
-       "prefs-advancedsearchoptions": "Ð\9dапÑ\80една Ð¿Ð¾Ð´ÐµÑ\88аваÑ\9aа",
-       "prefs-advancedwatchlist": "Ð\9dапÑ\80една Ð¿Ð¾Ð´ÐµÑ\88аваÑ\9aа",
+       "prefs-advancedrendering": "Ð\9dапÑ\80едне Ð¾Ð¿Ñ\86иÑ\98е",
+       "prefs-advancedsearchoptions": "Ð\9dапÑ\80едне Ð¾Ð¿Ñ\86иÑ\98е",
+       "prefs-advancedwatchlist": "Ð\9dапÑ\80едне Ð¾Ð¿Ñ\86иÑ\98е",
        "prefs-displayrc": "Подешавања приказа",
        "prefs-displaywatchlist": "Подешавања приказа",
        "prefs-tokenwatchlist": "Жетон",
        "group-user-member": "{{GENDER:$1|корисник|корисница|корисник}}",
        "group-autoconfirmed-member": "{{GENDER:$1|аутоматски потврђен корисник|аутоматски потврђена корисница}}",
        "group-bot-member": "{{GENDER:$1|бот}}",
-       "group-sysop-member": "{{GENDER:$1|администратор|администраторка|администратор}}",
+       "group-sysop-member": "{{GENDER:$1|администратор|администраторка}}",
        "group-bureaucrat-member": "{{GENDER:$1|бирократа|бирократкиња}}",
        "group-suppress-member": "{{GENDER:$1|брисач измена}}",
        "grouppage-user": "{{ns:project}}:Корисници",
        "right-bot": "сматрање измена као аутоматски процес",
        "right-nominornewtalk": "непоседовање мањих измена на страницама за разговор отвара прозор за нове поруке",
        "right-apihighlimits": "коришћење виших граница за упите из API-ја",
-       "right-writeapi": "пиÑ\81аÑ\9aе API-ја",
+       "right-writeapi": "могÑ\83Ñ\9bноÑ\81Ñ\82 Ð¿Ð¸Ñ\81аÑ\9aа API-ја",
        "right-delete": "брисање страница",
        "right-bigdelete": "брисање страница с великом историјом",
        "right-deletelogentry": "брисање и враћање одређених ставки у дневнику",
        "right-editcontentmodel": "мењање модела садржаја странице",
        "right-editinterface": "уређивање корисничког окружења",
        "right-editusercss": "уређивање туђих CSS датотека",
+       "right-edituserjson": "уређивање туђих JSON датотека",
        "right-edituserjs": "уређивање туђих JavaScript датотека",
        "right-editmyusercss": "уређивање сопствених CSS датотека",
+       "right-editmyuserjson": "уређивање сопствених JSON датотека",
        "right-editmyuserjs": "уређивање сопствених JavaScript датотека",
        "right-viewmywatchlist": "преглед сопственог списка надгледања",
        "right-editmywatchlist": "уређивање сопственог списка надгледања; неке предузете радње ће свеједно додати странице на списак и без овог права",
        "grant-delete": "Брисање страница, измена и уноса у дневницима",
        "grant-editinterface": "Уређивање Медијавики именског простора и корисничких CSS/JSON/Јаваскрипт страница",
        "grant-editmycssjs": "Уређивање вашег CSS/JSON/Јаваскрипта",
-       "grant-editmyoptions": "УÑ\80еÑ\92иваÑ\9aе Ð²аших подешавања",
+       "grant-editmyoptions": "УÑ\80еÑ\92иваÑ\9aе Ð\92аших подешавања",
        "grant-editmywatchlist": "Уређивање вашег списка надгледања",
        "grant-editpage": "Уређивање постојећих страница",
        "grant-editprotected": "Уређивање заштићених страница",
        "action-userrights-interwiki": "уређивање корисничких права на другим викијима",
        "action-siteadmin": "закључавање или откључавање базе података",
        "action-sendemail": "слање имејлова",
-       "action-editmyoptions": "Ñ\83Ñ\80еÑ\92иваÑ\9aе Ð²аших подешавања",
+       "action-editmyoptions": "Ñ\83Ñ\80еÑ\92иваÑ\9aе Ð\92аших подешавања",
        "action-editmywatchlist": "измену сопственог списак надгледања",
        "action-viewmywatchlist": "преглед вашег списак надгледања",
        "action-viewmyprivateinfo": "прегледање ваших личних података",
        "recentchanges": "Скорашње измене",
        "recentchanges-legend": "Опције скорашњих измена",
        "recentchanges-summary": "Пратите скорашње измене на овој страници.",
-       "recentchanges-noresult": "Ð\9dема Ð¸Ð·Ð¼ÐµÐ½Ð° Ñ\83 Ð·Ð°Ð´Ð°Ñ\82ом Ð¿ÐµÑ\80иодÑ\83 ÐºÐ¾Ñ\98и одговарају овим критеријумима.",
+       "recentchanges-noresult": "Ð\9dема Ð¸Ð·Ð¼ÐµÐ½Ð° Ñ\82оком Ð´Ð°Ñ\82ог Ð¿ÐµÑ\80иода Ð° ÐºÐ¾Ñ\98е одговарају овим критеријумима.",
        "recentchanges-timeout": "Ова претрага је истекла. Можда желите да покушате другачије параметре претраге.",
-       "recentchanges-network": "Ð\97бог Ñ\82еÑ\85ниÑ\87ког Ð¿Ñ\80облема Ð½Ðµ Ð¼Ð¾Ð³Ñ\83 Ð´Ð° Ñ\83Ñ\87иÑ\82ам Ñ\80езÑ\83лÑ\82аÑ\82е. Ð\9fокÑ\83Ñ\88аÑ\98Ñ\82е Ð¿Ð¾Ð½Ð¾Ð²Ð½Ð¾ Ð´Ð° Ñ\83Ñ\87иÑ\82ате страницу.",
+       "recentchanges-network": "Ð\97бог Ñ\82еÑ\85ниÑ\87ког Ð¿Ñ\80облема Ð½Ðµ Ð¼Ð¾Ð³Ñ\83 Ð´Ð° Ñ\83Ñ\87иÑ\82ам Ñ\80езÑ\83лÑ\82аÑ\82е. Ð\9fокÑ\83Ñ\88аÑ\98Ñ\82е Ð´Ð° Ð¾Ñ\81вежите страницу.",
        "recentchanges-notargetpage": "Унесите назив странице како бисте видели сродне измене.",
        "recentchanges-feed-description": "Пратите скорашње измене уз помоћ овог довода.",
-       "recentchanges-label-newpage": "Ð\9dова страница",
+       "recentchanges-label-newpage": "Ð\9eвом Ð¸Ð·Ð¼ÐµÐ½Ð¾Ð¼ Ñ\98е Ð½Ð°Ð¿Ñ\80авÑ\99ена Ð½ова страница",
        "recentchanges-label-minor": "Ово је мања измена",
-       "recentchanges-label-bot": "Ову измену је начинио бот",
+       "recentchanges-label-bot": "Ову измену је направио бот",
        "recentchanges-label-unpatrolled": "Ова измена још није патролирана",
        "recentchanges-label-plusminus": "Промена величине странице у бајтовима",
        "recentchanges-legend-heading": "<strong>Легенда:</strong>",
-       "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} ([[Special:NewPages|списак нових страница]])",
+       "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (такође погледајте [[Special:NewPages|списак нових страница]])",
+       "recentchanges-legend-plusminus": "(<em>±123</em>)",
        "recentchanges-submit": "Прикажи",
-       "rcfilters-tag-remove": "УклониÑ\82е Ñ\84илÑ\82еÑ\80 â\80\9e$1â\80\9d",
+       "rcfilters-tag-remove": "УклониÑ\82е Ñ\84илÑ\82еÑ\80 â\80\9e$1â\80\9c",
        "rcfilters-legend-heading": "<strong>Списак скраћеница:</strong>",
-       "rcfilters-other-review-tools": "Ð\9eÑ\81Ñ\82але алатке за преглед",
+       "rcfilters-other-review-tools": "Ð\94Ñ\80Ñ\83ге алатке за преглед",
        "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-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-quickfilters-placeholder-title": "Још нема сачуваних филтера",
+       "rcfilters-quickfilters-placeholder-description": "Да бисте сачували своја подешавања филтера и поново их употребљавали касније, кликните на икону за ознаку у подручју активних филтера — испод.",
        "rcfilters-savedqueries-defaultlabel": "Сачувани филтери",
        "rcfilters-savedqueries-rename": "Преименуј",
        "rcfilters-savedqueries-setdefault": "Постави као подразумевано",
        "rcfilters-savedqueries-apply-and-setdefault-label": "Направи подразумевани филтер",
        "rcfilters-savedqueries-cancel-label": "Откажи",
        "rcfilters-savedqueries-add-new-title": "Сачувајте тренутна подешавања филтера",
-       "rcfilters-savedqueries-already-saved": "Ð\9eви Ñ\84илÑ\82еÑ\80и Ñ\81Ñ\83 Ð²ÐµÑ\9b Ñ\81аÑ\87Ñ\83вани. Ð\98змениÑ\82е Ð\92аÑ\88а Ð¿Ð¾Ð´ÐµÑ\88аваÑ\9aа ÐºÐ°ÐºÐ¾ бисте направили нове сачуване филтере.",
+       "rcfilters-savedqueries-already-saved": "Ð\9eви Ñ\84илÑ\82еÑ\80и Ñ\81Ñ\83 Ð²ÐµÑ\9b Ñ\81аÑ\87Ñ\83вани. Ð\98змениÑ\82е Ð\92аÑ\88а Ð¿Ð¾Ð´ÐµÑ\88аваÑ\9aа Ð´Ð° бисте направили нове сачуване филтере.",
        "rcfilters-restore-default-filters": "Врати подразумеване филтере",
        "rcfilters-clear-all-filters": "Уклоните све филтере",
-       "rcfilters-show-new-changes": "Ð\9fогледаÑ\98 Ð½ајновије измене",
+       "rcfilters-show-new-changes": "Ð\9dајновије измене",
        "rcfilters-search-placeholder": "Филтрирајте измене (користите мени или претрагу за име филтера)",
        "rcfilters-invalid-filter": "Неисправан филтер",
        "rcfilters-empty-filter": "Нема активних филтера. Сви доприноси су приказани.",
        "rcfilters-filterlist-title": "Филтери",
        "rcfilters-filterlist-whatsthis": "Како ово функционише?",
-       "rcfilters-filterlist-feedbacklink": "Реците нам шта мислите о овим (новим) алаткама за филтрирање",
+       "rcfilters-filterlist-feedbacklink": "Реците нам шта мислите о овим алаткама за филтрирање",
        "rcfilters-highlightbutton-title": "Истакни резултате",
-       "rcfilters-highlightmenu-title": "Ð\9eдабеÑ\80и Ð±Ð¾Ñ\98Ñ\83",
+       "rcfilters-highlightmenu-title": "Ð\98збоÑ\80 Ð±Ð¾Ñ\98е",
        "rcfilters-highlightmenu-help": "Изаберите боју да бисте истакнули ово својство",
        "rcfilters-filterlist-noresults": "Нема пронађених филтера",
        "rcfilters-noresults-conflict": "Није пронађен ниједан резултат јер су критеријуми претраге сукобљени",
        "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-newcomer-description": "Регистровани уредници који имају мање од 10 измена или 4 дана активности.",
        "rcfilters-filter-user-experience-level-learner-label": "Ученици",
-       "rcfilters-filter-user-experience-level-learner-description": "РегиÑ\81Ñ\82Ñ\80овани Ñ\83Ñ\80едниÑ\86и Ñ\81а Ð²Ð¸Ñ\88е Ð¸Ñ\81кÑ\83Ñ\81Ñ\82ва Ð¾Ð´ â\80\9eноваÑ\98лиÑ\98аâ\80\9d, Ð°Ð»Ð¸ Ð¼Ð°Ñ\9aе Ð¾Ð´ „искусних корисника”.",
+       "rcfilters-filter-user-experience-level-learner-description": "РегиÑ\81Ñ\82Ñ\80овани Ñ\83Ñ\80едниÑ\86и Ñ\87иÑ\98е Ñ\98е Ð¸Ñ\81кÑ\83Ñ\81Ñ\82во Ð¸Ð·Ð¼ÐµÑ\92Ñ\83 â\80\9eноваÑ\98лиÑ\98аâ\80\9d Ð¸ „искусних корисника”.",
        "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": "Ð\98змене Ð½Ð°Ð¿Ñ\80авÑ\99ене Ð°Ñ\83Ñ\82омаÑ\82изованим Ð°Ð»Ð°Ñ\82има.",
+       "rcfilters-filter-bots-description": "Ð\98змене Ð½Ð°Ð¿Ñ\80авÑ\99ене Ð°Ñ\83Ñ\82омаÑ\82изованим Ð°Ð»Ð°Ñ\82кама.",
        "rcfilters-filter-humans-label": "Човек (није бот)",
        "rcfilters-filter-humans-description": "Измене које су направили људи-уредници.",
        "rcfilters-filtergroup-reviewstatus": "Патролираност",
-       "rcfilters-filter-reviewstatus-unpatrolled-description": "Измене нису ручно или аутоматски означене патролираним.",
+       "rcfilters-filter-reviewstatus-unpatrolled-description": "Ð\98змене ÐºÐ¾Ñ\98е Ð½Ð¸Ñ\81Ñ\83 Ñ\80Ñ\83Ñ\87но Ð¸Ð»Ð¸ Ð°Ñ\83Ñ\82омаÑ\82Ñ\81ки Ð¾Ð·Ð½Ð°Ñ\87ене Ð¿Ð°Ñ\82Ñ\80олиÑ\80аним.",
        "rcfilters-filter-reviewstatus-unpatrolled-label": "Непатролирано",
-       "rcfilters-filter-reviewstatus-manual-description": "Измене ручно означене патролираним.",
+       "rcfilters-filter-reviewstatus-manual-description": "Измене које су ручно означене патролираним.",
        "rcfilters-filter-reviewstatus-manual-label": "Ручно патролирано",
-       "rcfilters-filter-reviewstatus-auto-description": "Ð\98змене Ð¸Ñ\81кÑ\83Ñ\81ниÑ\85 Ñ\83Ñ\80едника чији је рад аутоматски означен патролираним.",
+       "rcfilters-filter-reviewstatus-auto-description": "Ð\98змене Ð½Ð°Ð¿Ñ\80едниÑ\85 ÐºÐ¾Ñ\80иÑ\81ника чији је рад аутоматски означен патролираним.",
        "rcfilters-filter-reviewstatus-auto-label": "Аутоматски патролирано",
        "rcfilters-filtergroup-significance": "Значај",
        "rcfilters-filter-minor-label": "Мање измене",
        "rcfilters-filter-pageedits-label": "Измене страница",
        "rcfilters-filter-pageedits-description": "Измене вики садржаја, расправа, описа категорија…",
        "rcfilters-filter-newpages-label": "Прављење страница",
-       "rcfilters-filter-newpages-description": "Измене којима се стварају нове странице.",
+       "rcfilters-filter-newpages-description": "Измене којима се праве нове странице.",
        "rcfilters-filter-categorization-label": "Измене категорија",
        "rcfilters-filter-categorization-description": "Записи о страницама додатим или уклоњеним из категорија.",
-       "rcfilters-filter-logactions-label": "РадÑ\9aе Ð·Ð°Ð±ÐµÐ»ÐµÐ¶ÐµÐ½Ðµ Ñ\83 Ð´Ð½ÐµÐ²Ð½Ð¸Ñ\86има",
-       "rcfilters-filter-logactions-description": "Административне радње, стварање налога, брисање страница, отпремања…",
+       "rcfilters-filter-logactions-label": "Ð\97абележене Ñ\80адÑ\9aе",
+       "rcfilters-filter-logactions-description": "Административне радње, прављење налога, брисање страница, отпремања…",
        "rcfilters-hideminor-conflicts-typeofchange-global": "Филтер за „мање” измене је у сукобу са једним или више филтера типа измена, зато што одређени типови измена не могу да се означе као „мање”. Сукобљени филтери су означени у подручју Активни филтери, изнад.",
        "rcfilters-hideminor-conflicts-typeofchange": "Одређени типови измена не могу да се означе као „мање”, тако да је овај филтер у сукобу са следећим филтерима типа измена: $1",
        "rcfilters-typeofchange-conflicts-hideminor": "Овај филтер типа измене је у сукобу са филтером за „мање” измене. Одређени типови измена не могу да се означе као „мање”.",
        "rcfilters-view-tags-help-icon-tooltip": "Сазнајте више о означеним изменама",
        "rcfilters-liveupdates-button": "Ажурирај уживо",
        "rcfilters-liveupdates-button-title-on": "Искључите ажурирања уживо",
-       "rcfilters-liveupdates-button-title-off": "Ð\9fÑ\80иказ Ð½Ð¾Ð²Ð¸Ñ\85 Ð¸Ð·Ð¼ÐµÐ½Ð° уживо",
+       "rcfilters-liveupdates-button-title-off": "Ð\9fÑ\80икажиÑ\82е Ð½Ð¾Ð²Ðµ Ð¸Ð·Ð¼ÐµÐ½Ðµ уживо",
        "rcfilters-watchlist-markseen-button": "Означи све измене као погледане",
        "rcfilters-watchlist-edit-watchlist-button": "Промени списак надгледаних страница",
-       "rcfilters-watchlist-showupdated": "Измене на страницама које нисте посетили од када је измена извршена су <strong>подебљане</strong>, са испуњеним ознакама.",
+       "rcfilters-watchlist-showupdated": "Измене страница које нисте посетили од када је измена извршена су <strong>подебљане</strong>, са испуњеним ознакама.",
        "rcfilters-preference-label": "Сакриј побољшану верзију скорашњих измена",
        "rcfilters-preference-help": "Поништава редизајн интерфејса из 2017. и све алатке додате тада и после.",
+       "rcfilters-watchlist-preference-label": "Сакриј побољшану верзију списка надгледања",
        "rcfilters-filter-showlinkedfrom-label": "Прикажи измене на страницама са којих долазе везе",
        "rcfilters-filter-showlinkedfrom-option-label": "<strong>Странице са којих долазе везе до</strong> изабране странице",
        "rcfilters-filter-showlinkedto-label": "Прикажи измене на страницама ка којима воде везе",
        "recentchangeslinked-feed": "Сродне измене",
        "recentchangeslinked-toolbox": "Сродне измене",
        "recentchangeslinked-title": "Сродне измене са „$1“",
-       "recentchangeslinked-summary": "УнеÑ\81иÑ\82е Ð¸Ð¼Ðµ Ñ\81Ñ\82Ñ\80аниÑ\86е Ð´Ð° Ð±Ð¸Ñ\81Ñ\82е Ð²Ð¸Ð´ÐµÐ»Ð¸ Ð¿Ñ\80омене Ð½Ð° Ñ\81Ñ\82Ñ\80аниÑ\86ама ÐºÐ¾Ñ\98е Ñ\81Ñ\83 Ð¿Ð¾Ð²ÐµÐ·Ð°Ð½Ðµ Ñ\81а Ð¸Ð»Ð¸ Ñ\81а Ñ\82е Ñ\81Ñ\82Ñ\80аниÑ\86е. (Ð\94а Ð±Ð¸Ñ\81Ñ\82е Ð²Ð¸Ð´ÐµÐ»Ð¸ Ñ\87ланове Ð½ÐµÐºÐµ ÐºÐ°Ñ\82егоÑ\80иÑ\98е, Ñ\83неÑ\81иÑ\82е Ð\9aаÑ\82егоÑ\80иÑ\98а:Ð\9dазив ÐºÐ°Ñ\82егоÑ\80иÑ\98е). Ð\9fÑ\80омене Ð½Ð° Ñ\81Ñ\82Ñ\80аниÑ\86ама ÐºÐ¾Ñ\98е Ñ\81Ñ\83 Ð½Ð° [[Special:Watchlist|ваÑ\88ем Ñ\81пиÑ\81кÑ\83 Ð½Ð°Ð´Ð³Ð»ÐµÐ´Ð°Ñ\9aа]] Ñ\81Ñ\83 '''подебÑ\99ане'''.",
+       "recentchangeslinked-summary": "УнеÑ\81иÑ\82е Ð¸Ð¼Ðµ Ñ\81Ñ\82Ñ\80аниÑ\86е Ð´Ð° Ð±Ð¸Ñ\81Ñ\82е Ð²Ð¸Ð´ÐµÐ»Ð¸ Ð¿Ñ\80омене Ð½Ð° Ñ\81Ñ\82Ñ\80аниÑ\86ама ÐºÐ¾Ñ\98е Ñ\81Ñ\83 Ð¿Ð¾Ð²ÐµÐ·Ð°Ð½Ðµ Ñ\81а Ð¸Ð»Ð¸ Ñ\81а Ñ\82е Ñ\81Ñ\82Ñ\80аниÑ\86е. (Ð\94а Ð±Ð¸Ñ\81Ñ\82е Ð²Ð¸Ð´ÐµÐ»Ð¸ Ñ\87ланове ÐºÐ°Ñ\82егоÑ\80иÑ\98е, Ñ\83неÑ\81иÑ\82е {{ns:category}}:Ð\98ме ÐºÐ°Ñ\82егоÑ\80иÑ\98е). Ð\9fÑ\80омене Ð½Ð° Ñ\81Ñ\82Ñ\80аниÑ\86ама ÐºÐ¾Ñ\98е Ñ\81Ñ\83 Ð½Ð° [[Special:Watchlist|Ð\92аÑ\88ем Ñ\81пиÑ\81кÑ\83 Ð½Ð°Ð´Ð³Ð»ÐµÐ´Ð°Ñ\9aа]] Ñ\81Ñ\83 <strong>подебÑ\99ане</strong>.",
        "recentchangeslinked-page": "Назив странице:",
        "recentchangeslinked-to": "Прикажи измене страница које су повезане с датом страницом",
        "recentchanges-page-added-to-category": "[[:$1]] је додата у категорију",
        "destfilename": "Назив:",
        "upload-maxfilesize": "Максимална величина датотеке: $1",
        "upload-description": "Опис датотеке",
-       "upload-options": "Ð\9fодеÑ\88аваÑ\9aа отпремања",
+       "upload-options": "Ð\9eпÑ\86иÑ\98е отпремања",
        "watchthisupload": "Надгледај ову датотеку",
        "filewasdeleted": "Датотека с овим називом је раније послата, али је обрисана.\nПроверите $1 пре него што наставите с поновним слањем.",
        "filename-bad-prefix": "Назив датотеке коју шаљете почиње са <strong>„$1“</strong>, а њега обично додељују дигитални фотоапарати.\nИзаберите назив датотеке који описује њен садржај.",
        "img-auth-accessdenied": "Приступ је одбијен",
        "img-auth-nopathinfo": "Недостаје PATH_INFO.\nВаш сервер није подешен да прослеђује овакве податке.\nМожда је заснован на CGI-ју који не подржава img_auth.\nПогледајте https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization?uselang=sr-ec.",
        "img-auth-notindir": "Захтевана путања није у подешеној фасцикли за отпремање.",
-       "img-auth-badtitle": "Не могу да створим исправан наслов за „$1“.",
+       "img-auth-badtitle": "Не могу да направим валидан наслов за „$1“.",
        "img-auth-nologinnWL": "Нисте пријављени и „$1” није на списку дозвољених.",
        "img-auth-nofile": "Датотека „$1“ не постоји.",
        "img-auth-isdir": "Покушавате да приступите фасцикли „$1“.\nДозвољен је само приступ датотекама.",
        "upload-curl-error28": "Отпремање је истекло",
        "upload-curl-error28-text": "Сервер не одговара на упит.\nПроверите да ли сајт ради, мало осачекајте и покушајте поново.\nПробајте касније када буде мање оптерећење.",
        "license": "Лиценца:",
-       "license-header": "Ð\9bиÑ\86енÑ\86а:",
+       "license-header": "Ð\9bиÑ\86енÑ\86иÑ\80аÑ\9aе",
        "nolicense": "Није изабрано",
        "licenses-edit": "Уреди избор лиценци",
        "license-nopreview": "(преглед није доступан)",
        "filehist-revert": "врати",
        "filehist-current": "тренутно",
        "filehist-datetime": "Датум/време",
-       "filehist-thumb": "УмаÑ\9aени Ð¿Ñ\80иказ",
-       "filehist-thumbtext": "УмаÑ\9aени Ð¿Ñ\80иказ Ð·Ð° Ð¸Ð·Ð´Ð°Ñ\9aе Ð¾Ð´ $1",
+       "filehist-thumb": "Ð\9cиниÑ\98аÑ\82Ñ\83Ñ\80а",
+       "filehist-thumbtext": "Ð\9cиниÑ\98аÑ\82Ñ\83Ñ\80а Ð·Ð° Ð²ÐµÑ\80зиÑ\98Ñ\83 Ð½Ð° Ð´Ð°Ð½ $1",
        "filehist-nothumb": "Нема умањеног приказа",
        "filehist-user": "Корисник",
        "filehist-dimensions": "Димензије",
        "deadendpages": "Странице без унутрашњих веза",
        "deadendpagestext": "Следеће странице немају везе до других страница на овом викију.",
        "protectedpages": "Заштићене странице",
+       "protectedpages-filters": "Филтери:",
        "protectedpages-indef": "Само неограничене заштите",
        "protectedpages-summary": "На овој страници се налази списак тренутно заштићених страница. За списак заштићених наслова види [[{{#special:ProtectedTitles}}|{{int:protectedtitles}}]].",
        "protectedpages-cascade": "Само преносиве заштите",
        "protectedtitles-submit": "Прикажи наслове",
        "listusers": "Списак корисника",
        "listusers-editsonly": "Прикажи само кориснике који су уређивали",
+       "listusers-temporarygroupsonly": "Прикажи само кориснике у привременим корисничким групама",
        "listusers-creationsort": "Поређај по датуму стварања",
        "listusers-desc": "Поређај у опадајућем редоследу",
        "usereditcount": "$1 {{PLURAL:$1|измена|измене|измена}}",
        "apisandbox-dynamic-error-exists": "Параметар под називом \"$1\" већ постоји.",
        "apisandbox-deprecated-parameters": "Застарели параметри",
        "apisandbox-fetch-token": "Аутоматски попуни токен",
+       "apisandbox-add-multi": "Додај",
        "apisandbox-submit-invalid-fields-title": "Нека поља нису исправна",
        "apisandbox-submit-invalid-fields-message": "Молимо Вас поправите означена поља и покушајте поново.",
        "apisandbox-results": "Резултати",
        "apisandbox-multivalue-all-namespaces": "$1 (сви именски простори)",
        "apisandbox-multivalue-all-values": "$1 (све вредности)",
        "booksources": "Штампани извори",
-       "booksources-search-legend": "ТÑ\80ажи ÐºÑ\9aижевне изворе",
+       "booksources-search-legend": "Ð\9fÑ\80еÑ\82Ñ\80ажи Ñ\88Ñ\82ампане изворе",
        "booksources-isbn": "ISBN:",
        "booksources-search": "Претражи",
        "booksources-text": "Испод се налази списак веза ка сајтовима који се баве продајом нових и половних књига, а који би могли имати додатне податке о књигама које тражите:",
        "speciallogtitlelabel": "Циљ (наслов или {{ns:user}}:корисничко име):",
        "log": "Дневници",
        "logeventslist-submit": "Прикажи",
+       "logeventslist-more-filters": "Приказ додатних дневника:",
+       "logeventslist-patrol-log": "Дневник патролирања",
+       "logeventslist-tag-log": "Дневник ознака",
        "all-logs-page": "Сви јавни дневници",
        "alllogstext": "Скупни приказ свих доступних историја овог викија.\nМожете сузити приказ одабирући врсту историје, корисничког имена или тражене странице.",
        "logempty": "Нема пронађених уноса у дневнику.",
        "allinnamespace": "Све странице (именски простор $1)",
        "allpagessubmit": "Иди",
        "allpagesprefix": "Прикажи странице с префиксом:",
-       "allpagesbadtitle": "Ð\9dаведени Ð½Ð°Ð·Ð¸Ð² Ñ\81Ñ\82Ñ\80аниÑ\86е Ð½Ð¸Ñ\98е Ð¸Ñ\81пÑ\80аван Ð¸Ð»Ð¸ Ñ\81адÑ\80жи Ð¼ÐµÑ\92Ñ\83Ñ\98езиÑ\87ки Ð¸Ð»Ð¸ Ð¼ÐµÑ\92Ñ\83вики Ð¿Ñ\80еÑ\84икÑ\81.\nÐ\9cожда Ñ\81адÑ\80жи Ð·Ð½Ð°ÐºÐ¾Ð²Ðµ који се не могу користити у насловима.",
+       "allpagesbadtitle": "Ð\9dаведени Ð½Ð°Ð·Ð¸Ð² Ñ\81Ñ\82Ñ\80аниÑ\86е Ð½Ð¸Ñ\98е Ð²Ð°Ð»Ð¸Ð´Ð°Ð½ Ð¸Ð»Ð¸ Ñ\81адÑ\80жи Ð¼ÐµÑ\92Ñ\83Ñ\98езиÑ\87ки Ð¸Ð»Ð¸ Ð¼ÐµÑ\92Ñ\83вики Ð¿Ñ\80еÑ\84икÑ\81.\nÐ\9cожда Ñ\81адÑ\80жи Ñ\98едан Ð¸Ð»Ð¸ Ð²Ð¸Ñ\88е Ð·Ð½Ð°ÐºÐ¾Ð²Ð° који се не могу користити у насловима.",
        "allpages-bad-ns": "{{SITENAME}} нема именски простор „$1“.",
        "allpages-hide-redirects": "Сакриј преусмерења",
        "cachedspecial-viewing-cached-ttl": "Гледате кеширану верзију ове странице, која може бити стара и до $1.",
        "trackingcategories-nodesc": "Опис није доступан.",
        "trackingcategories-disabled": "Категорија је онемогућена",
        "mailnologin": "Нема адресе за слање",
-       "mailnologintext": "Ð\9cоÑ\80аÑ\82е Ð±Ð¸Ñ\82и [[Special:UserLogin|пÑ\80иÑ\98авÑ\99ени]] Ð¸ Ð¸Ð¼Ð°Ñ\82и Ð¸Ñ\81пÑ\80аван имејл адресу у [[Special:Preferences|подешавањима]] да бисте слали имејлове другим корисницима.",
+       "mailnologintext": "Ð\9cоÑ\80аÑ\82е Ð±Ð¸Ñ\82и [[Special:UserLogin|пÑ\80иÑ\98авÑ\99ени]] Ð¸ Ð¸Ð¼Ð°Ñ\82и Ð²Ð°Ñ\99анÑ\83 имејл адресу у [[Special:Preferences|подешавањима]] да бисте слали имејлове другим корисницима.",
        "emailuser": "Пошаљи имејл",
        "emailuser-title-target": "Слање имејла {{GENDER:$1|кориснику|корисници}}",
        "emailuser-title-notarget": "Слање имејла кориснику",
        "watchnologin": "Нисте пријављени",
        "addwatch": "Додај на списак надгледања",
        "addedwatchtext": "Страница „[[:$1]]“ и њена страница за разговор је додата на Ваш [[Special:Watchlist|списак надгледања]].",
+       "addedwatchtext-talk": "Страница „[[:$1]]” и њена придружена страница је додата на Ваш [[Special:Watchlist|списак надгледања]]",
        "addedwatchtext-short": "Страница „$1“ је додата на Ваш списак надгледања.",
        "removewatch": "Уклони са списка надгледања",
-       "removedwatchtext": "Страница „[[:$1]]“ и њена страница за разговор је уклоњена с вашег [[Special:Watchlist|списка надгледања]].",
+       "removedwatchtext": "Страница „[[:$1]]“ и њена страница за разговор је уклоњена са Вашег [[Special:Watchlist|списка надгледања]].",
        "removedwatchtext-short": "Страница „$1“ је уклоњена с вашег списка надгледања.",
        "watch": "Надгледај",
        "watchthispage": "Надгледај ову страницу",
        "wlshowhidepatr": "патролиране измене",
        "wlshowhidemine": "моје измене",
        "wlshowhidecategorization": "категоризацију страница",
-       "watchlist-options": "Ð\9fодеÑ\88аваÑ\9aа списка надгледања",
-       "watching": "Надгледање…",
-       "unwatching": "УклаÑ\9aаÑ\9aе Ñ\81а Ñ\81пиÑ\81ка Ð½Ð°Ð´Ð³Ð»ÐµÐ´Ð°Ñ\9aа...",
+       "watchlist-options": "Ð\9eпÑ\86иÑ\98е списка надгледања",
+       "watching": "Надгледам…",
+       "unwatching": "Ð\9fÑ\80еÑ\81Ñ\82аÑ\98ем Ð´Ð° Ð½Ð°Ð´Ð³Ð»ÐµÐ´Ð°Ð¼...",
        "watcherrortext": "Дошло је до грешке при промени поставки вашег списка надгледања за „$1“.",
        "enotif_reset": "Означи све странице као посећене",
        "enotif_impersonal_salutation": "{{SITENAME}} корисник",
        "excontentauthor": "садржај је био: „$1“, а једини уредник „[[Special:Contributions/$2|$2]]“ ([[User talk:$2|разговор]])",
        "exbeforeblank": "садржај пре брисања је био: „$1“",
        "delete-confirm": "Брисање странице „$1“",
-       "delete-legend": "Ð\9eбÑ\80иÑ\88и",
+       "delete-legend": "Ð\91Ñ\80иÑ\81аÑ\9aе",
        "historywarning": "<strong>Упозорење:</strong> страница коју желите да обришете има историју са $1 {{PLURAL:$1|изменом|измене|измена}}:",
        "historyaction-submit": "Прикажи",
        "confirmdeletetext": "Управо ћете обрисати страницу, укључујући и њену историју.\nПотврдите своју намеру, да разумете последице и да ово радите у складу с [[{{MediaWiki:Policy-url}}|правилима]].",
        "dellogpage": "Дневник брисања",
        "dellogpagetext": "Испод је списак последњих брисања.",
        "deletionlog": "дневник брисања",
+       "log-name-create": "Дневник прављења страница",
+       "log-description-create": "Испод је списак скорашњих прављења страница.",
+       "logentry-create-create": "$1 је {{GENDER:$2|направио|направила}} страницу $3",
        "reverted": "Враћено на ранију измену",
        "deletecomment": "Разлог:",
        "deleteotherreason": "Други/додатни разлог:",
        "cantrollback": "Не могу да вратим измену.\nПоследњи аутор је уједно и једини.",
        "alreadyrolled": "Враћање последње измене странице [[:$1]] од стране {{GENDER:$2|корисника|кориснице|корисника}} [[User:$2|$2]] ([[User talk:$2|разговор]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]) није успело; неко други је у међувремену изменио или вратио страницу.\n\nПоследњу измену је {{GENDER:$3|направио|направила|направио}} [[User:$3|$3]] ([[User talk:$3|разговор]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).",
        "editcomment": "Опис измене: <em>$1</em>.",
-       "revertpage": "Враћене измене [[Special:Contribs/$2|$2]] ([[User talk:$2|разговор]]) на последњу измену корисника [[User:$1|$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 Прикажи измене]",
        "logentry-contentmodel-change-revert": "врати",
        "protectlogpage": "Дневник заштите",
        "protectlogtext": "Испод је списак заштићених страница.\nПогледајте [[Special:ProtectedPages|списак заштићених страница]] за више детаља.",
-       "protectedarticle": "је заштитио „[[$1]]“",
-       "modifiedarticleprotection": "промењен степен заштите за „[[$1]]“",
+       "protectedarticle": "је {{GENDER:|заштитио|заштитила}} страницу „[[$1]]“",
+       "modifiedarticleprotection": "је {{GENDER:|променио|променила}} степен заштите странице „[[$1]]“",
        "unprotectedarticle": "је скинуо заштиту са странице „[[$1]]“",
        "movedarticleprotection": "је преместио подешавања заштите са „[[$2]]“ на „[[$1]]“",
        "protectedarticle-comment": "{{GENDER:$2|Заштићена}} страница [[$1]]",
        "minimum-size": "Најмања величина",
        "maximum-size": "Највећа величина:",
        "pagesize": "(бајтови)",
-       "restriction-edit": "Уређивање",
-       "restriction-move": "Ð\9fремештање",
+       "restriction-edit": "уређивање",
+       "restriction-move": "премештање",
        "restriction-create": "прављење",
        "restriction-upload": "отпремање",
        "restriction-level-sysop": "потпуно заштићено",
        "undelete-show-file-submit": "Да",
        "namespace": "Именски простор:",
        "invert": "Обрни избор",
-       "tooltip-invert": "Ð\9eзнаÑ\87иÑ\82е Ð¾Ð²Ñ\83 ÐºÑ\83Ñ\9bиÑ\86Ñ\83 Ð´Ð° Ð±Ð¸Ñ\81Ñ\82е Ñ\81акÑ\80или Ð¸Ð·Ð¼ÐµÐ½Ðµ Ð½Ð° Ñ\81Ñ\82Ñ\80аниÑ\86ама Ñ\83 Ð¾Ð´абраном именском простору (и повезаним именским просторима, ако је означено)",
-       "tooltip-whatlinkshere-invert": "Означите ову кутију за сакривање веза са страница у изабраном именском простору.",
+       "tooltip-invert": "Ð\9eзнаÑ\87иÑ\82е Ð¾Ð²Ñ\83 ÐºÑ\83Ñ\82иÑ\98Ñ\83Ñ\86Ñ\83 Ð´Ð° Ð±Ð¸Ñ\81Ñ\82е Ñ\81акÑ\80или Ð¸Ð·Ð¼ÐµÐ½Ðµ Ñ\81Ñ\82Ñ\80аниÑ\86а Ñ\83 Ð¸Ð·абраном именском простору (и повезаним именским просторима, ако је означено)",
+       "tooltip-whatlinkshere-invert": "Означите ову кутијицу за сакривање веза са страница у изабраном именском простору.",
        "namespace_association": "Повезани именски простор",
-       "tooltip-namespace_association": "Ð\9eзнаÑ\87иÑ\82е Ð¾Ð²Ñ\83 ÐºÑ\83Ñ\9bиÑ\86Ñ\83 Ð´Ð° Ð±Ð¸Ñ\81Ñ\82е Ñ\83кÑ\99Ñ\83Ñ\87или Ð¸ Ñ\80азговоÑ\80 Ð¸Ð»Ð¸ Ð¸Ð¼ÐµÐ½Ñ\81ки Ð¿Ñ\80оÑ\81Ñ\82оÑ\80 Ñ\82еме ÐºÐ¾Ñ\98а Ñ\98е Ð¿Ð¾Ð²ÐµÐ·Ð°Ð½Ð° Ñ\81 Ð¾Ð´абраним именским простором",
+       "tooltip-namespace_association": "Ð\9eзнаÑ\87иÑ\82е Ð¾Ð²Ñ\83 ÐºÑ\83Ñ\82иÑ\98иÑ\86Ñ\83 Ð´Ð° Ð±Ð¸Ñ\81Ñ\82е Ñ\83кÑ\99Ñ\83Ñ\87или Ð¸ Ñ\80азговоÑ\80 Ð¸Ð»Ð¸ Ð¸Ð¼ÐµÐ½Ñ\81ки Ð¿Ñ\80оÑ\81Ñ\82оÑ\80 Ñ\82еме ÐºÐ¾Ñ\98а Ñ\98е Ð¿Ð¾Ð²ÐµÐ·Ð°Ð½Ð° Ñ\81а Ð¸Ð·абраним именским простором",
        "blanknamespace": "(главни)",
        "contributions": "{{GENDER:$1|Кориснички}} доприноси",
        "contributions-title": "Доприноси {{GENDER:$1|корисника|кориснице}} $1",
        "contribsub2": "За {{GENDER:$3|$1}} ($2)",
        "contributions-userdoesnotexist": "Кориснички налог „$1“ није отворен.",
        "nocontribs": "Нема измена које одговарају наведеним критеријумима.",
-       "uctop": "(последња)",
+       "uctop": "(тренутна)",
        "month": "од месеца (и раније):",
        "year": "од године (и раније):",
+       "date": "Од датума (и раније):",
        "sp-contributions-newbies": "Прикажи само доприносе нових корисника",
        "sp-contributions-newbies-sub": "За нове кориснике",
        "sp-contributions-newbies-title": "Доприноси нових корисника",
        "whatlinkshere": "Шта води овде",
        "whatlinkshere-title": "Странице које су повезане са „$1”",
        "whatlinkshere-page": "Страница:",
-       "linkshere-2": "Следеће странице имају везу до <strong>$1</strong>:",
-       "nolinkshere-2": "Ниједна страница није повезана са: <strong>$1</strong>.",
-       "nolinkshere-ns-2": "Ниједна страница не води до '''$1''' у изабраном именском простору.",
+       "linkshere": "Следеће странице имају везу до <strong>$2</strong>:",
+       "nolinkshere": "Ниједна страница није повезана са: <strong>$2</strong>.",
+       "nolinkshere-ns": "Ниједна страница не води до '''$2''' у изабраном именском простору.",
        "isredirect": "преусмерење",
        "istemplate": "укључивање",
        "isimage": "веза до датотеке",
        "blocklogpage": "Дневник блокирања",
        "blocklog-showlog": "{{GENDER:$1|Овај корисник је раније блокиран|Ова корисница је раније блокирана}}.\nИсторија блокирања се налази испод:",
        "blocklog-showsuppresslog": "{{GENDER:$1|Овај корисник је раније блокиран и сакривен|Ова корисница је раније блокирана и сакривена}}.\nИсторија сакривања се налази испод:",
-       "blocklogentry": "је блокирао [[$1]] с роком истицања од $2 $3",
-       "reblock-logentry": "{{GENDER:|је променио|је променила|је променио}} подешавања за блокирање {{GENDER:$1|корисника|кориснице|корисника}} [[$1]] с роком истека од $2 ($3)",
+       "blocklogentry": "је блокирао [[$1]] са временом истицања од $2 $3",
+       "reblock-logentry": "{{GENDER:|је променио|је променила}} подешавања за блокирање {{GENDER:$1|корисника|кориснице}} [[$1]] са временом истека од $2 ($3)",
        "blocklogtext": "Ово је дневник блокирања и деблокирања корисника.\nАутоматски блокиране ИП адресе нису наведене.\nТекуће забране и блокирања можете наћи [[Special:BlockList|овде]].",
        "unblocklogentry": "је деблокирао $1",
        "block-log-flags-anononly": "само анонимни корисници",
        "databaselocked": "База података је већ закључана.",
        "databasenotlocked": "База није закључана.",
        "lockedbyandtime": "(од $1 дана $2 у $3)",
-       "move-page": "Ð\9fÑ\80емеÑ\88Ñ\82аÑ\9aе â\80\9e$1â\80\9c",
+       "move-page": "Ð\9fÑ\80емеÑ\88Ñ\82аÑ\9aе â\80\9e$1â\80\9d",
        "move-page-legend": "Премештање странице",
        "movepagetext": "Доњи образац ће преименовати страницу, премештајући целу историју на ново име.\nСтари наслов постаће преусмерење на нови.\nМожете ажурирати преусмерења која воде до изворног наслова;\nпогледајте [[Special:DoubleRedirects|двострука]] или [[Special:BrokenRedirects|покварена]] преусмерења.\nНа вама је одговорност да везе и даље иду тамо где треба.\n\nСтраница <strong>неће</strong> бити премештена ако већ постоји страница с тим именом (осим ако је празна, садржи преусмерење или нема историју измена).\nТо значи да можете вратити страницу на претходно име ако погрешите, али не можете ''преписати'' постојећу.\n\n<strong>Напомена:</strong>\nОво може представљати драстичну и неочекивану измену за популарну страницу;\nдобро размислите о последицама пре него што наставите.",
        "movepagetext-noredirectfixer": "Доњи образац ће преименовати страницу, премештајући целу историју на ново име.\nСтари наслов постаће преусмерење на нови.\nПогледајте [[Special:DoubleRedirects|двострука]] или [[Special:BrokenRedirects|покварена]] преусмерења.\nНа вама је одговорност да везе и даље иду тамо где треба.\n\nСтраница <strong>неће</strong> бити премештена ако већ постоји страница с тим именом (осим ако је празна, садржи преусмерење или нема историју измена).\nТо значи да можете вратити страницу на претходно име ако погрешите, али не можете ''преписати'' постојећу.\n\n<strong>Напомена:</strong>\nОво може представљати драстичну и неочекивану измену за популарну страницу;\nдобро размислите о последицама пре него што наставите.",
        "imageinvalidfilename": "Циљани назив датотеке је неисправан",
        "fix-double-redirects": "Ажурирајте сва преусмерења која воде до првобитног наслова",
        "move-leave-redirect": "Остави преусмерење",
-       "protectedpagemovewarning": "'''УпозоÑ\80еÑ\9aе:''' Ð¾Ð²Ð° Ñ\81Ñ\82Ñ\80аниÑ\86а Ñ\98е Ð·Ð°Ñ\88Ñ\82иÑ\9bена, Ñ\82ако Ð´Ð° Ñ\81амо ÐºÐ¾Ñ\80иÑ\81ниÑ\86и Ñ\81 Ð°Ð´Ð¼Ð¸Ð½Ð¸Ñ\81Ñ\82Ñ\80аÑ\82оÑ\80Ñ\81ким Ð¾Ð²Ð»Ð°Ñ\88Ñ\9bеÑ\9aима Ð¼Ð¾Ð³Ñ\83 Ð´Ð° Ñ\98е Ð¿Ñ\80емеÑ\81Ñ\82е.\nÐ\97а Ð²Ð¸Ñ\88е Ð¸Ð½Ñ\84оÑ\80маÑ\86иÑ\98а, Ð¿Ð¾Ñ\81ледÑ\9aи Ð·Ð°Ð¿Ð¸Ñ\81 Ñ\83 Ð´Ð½ÐµÐ²Ð½Ð¸ÐºÑ\83 Ð¸Ð·Ð¼ÐµÐ½Ð° Ñ\98е Ð¿Ñ\80иказан Ð¸Ñ\81под:",
-       "semiprotectedpagemovewarning": "<strong>Ð\9dапомена:</strong> Ð\9eва Ñ\81Ñ\82Ñ\80аниÑ\86а Ñ\98е Ð·Ð°Ñ\88Ñ\82иÑ\9bена, Ñ\82ако Ð´Ð° Ñ\81амо Ñ\80егиÑ\81Ñ\82Ñ\80овани ÐºÐ¾Ñ\80иÑ\81ниÑ\86и Ð¼Ð¾Ð³Ñ\83 Ð´Ð° Ñ\98е Ð¿Ñ\80емеÑ\81Ñ\82е.\nÐ\9fоÑ\81ледÑ\9aи Ð·Ð°Ð¿Ð¸Ñ\81 Ñ\83 Ð´Ð½ÐµÐ²Ð½Ð¸ÐºÑ\83 Ð¸Ð·Ð¼ÐµÐ½Ð° Ð¿Ñ\80иказан Ñ\98е испод као референца:",
+       "protectedpagemovewarning": "'''УпозоÑ\80еÑ\9aе:''' Ð¾Ð²Ð° Ñ\81Ñ\82Ñ\80аниÑ\86а Ñ\98е Ð·Ð°Ñ\88Ñ\82иÑ\9bена, Ñ\82ако Ð´Ð° Ñ\81амо ÐºÐ¾Ñ\80иÑ\81ниÑ\86и Ñ\81 Ð°Ð´Ð¼Ð¸Ð½Ð¸Ñ\81Ñ\82Ñ\80аÑ\82оÑ\80Ñ\81ким Ð¾Ð²Ð»Ð°Ñ\88Ñ\9bеÑ\9aима Ð¼Ð¾Ð³Ñ\83 Ð´Ð° Ñ\98е Ð¿Ñ\80емеÑ\81Ñ\82е.\nÐ\9fоÑ\81ледÑ\9aи Ð·Ð°Ð¿Ð¸Ñ\81 Ñ\83 Ð´Ð½ÐµÐ²Ð½Ð¸ÐºÑ\83 Ñ\98е Ð¿Ñ\80иказан Ð¸Ñ\81под ÐºÐ°Ð¾ Ñ\80еÑ\84еÑ\80енÑ\86а:",
+       "semiprotectedpagemovewarning": "<strong>Ð\9dапомена:</strong> Ð¾Ð²Ð° Ñ\81Ñ\82Ñ\80аниÑ\86а Ñ\98е Ð·Ð°Ñ\88Ñ\82иÑ\9bена, Ñ\82ако Ð´Ð° Ñ\81амо Ð°Ñ\83Ñ\82омаÑ\82Ñ\81ки Ð¿Ð¾Ñ\82вÑ\80Ñ\92ени ÐºÐ¾Ñ\80иÑ\81ниÑ\86и Ð¼Ð¾Ð³Ñ\83 Ð´Ð° Ñ\98е Ð¿Ñ\80емеÑ\81Ñ\82е.\nÐ\9fоÑ\81ледÑ\9aи Ð·Ð°Ð¿Ð¸Ñ\81 Ñ\83 Ð´Ð½ÐµÐ²Ð½Ð¸ÐºÑ\83 Ñ\98е Ð¿Ñ\80иказан испод као референца:",
        "move-over-sharedrepo": "[[:$1]] се налази на дељеном складишту. Ако преместите датотеку на овај наслов, то ће заменити дељену датотеку.",
        "file-exists-sharedrepo": "Наведени назив датотеке се већ користи у дељеном складишту.\nИзаберите други назив.",
        "export": "Извоз страница",
        "allmessagesname": "Назив",
        "allmessagesdefault": "Подразумевани текст",
        "allmessagescurrent": "Тренутни текст поруке",
-       "allmessagestext": "Ð\9eво Ñ\98е Ñ\81пиÑ\81ак Ñ\81виÑ\85 Ñ\81иÑ\81Ñ\82емÑ\81киÑ\85 Ð¿Ð¾Ñ\80Ñ\83ка ÐºÐ¾Ñ\98е Ñ\81Ñ\83 Ð´Ð¾Ñ\81Ñ\82Ñ\83пне Ñ\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 Ð¢Ñ\80анÑ\81леÑ\98Ñ\82вики] Ð°ÐºÐ¾ Ð¶ÐµÐ»Ð¸Ñ\82е Ð´Ð° Ð¿Ð¾Ð¼Ð¾Ð³Ð½ÐµÑ\82е Ñ\83 Ð¿Ñ\80евоÑ\92еÑ\9aÑ\83.",
+       "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] Ð°ÐºÐ¾ Ð¶ÐµÐ»Ð¸Ñ\82е Ð´Ð° Ð´Ð¾Ð¿Ñ\80инеÑ\81еÑ\82е Ð¾Ð¿Ñ\88Ñ\82оÑ\98 Ð»Ð¾ÐºÐ°Ð»Ð¸Ð·Ð°Ñ\86иÑ\98и Ð\9cедиÑ\98авикиÑ\98а.",
        "allmessagesnotsupportedDB": "Ова страница не може да се користи јер је '''$wgUseDatabaseMessages''' онемогућен.",
        "allmessages-filter-legend": "Филтер",
        "allmessages-filter": "Филтрирај по стању:",
        "allmessages-language": "Језик:",
        "allmessages-filter-submit": "Иди",
        "allmessages-filter-translate": "Преведи",
-       "thumbnail-more": "Повећај",
+       "thumbnail-more": "Повећајте",
        "filemissing": "Недостаје датотека",
        "thumbnail_error": "Грешка при стварању минијатуре: $1",
        "thumbnail_error_remote": "Порука о грешци из $1:\n$2",
        "import-error-special": "Не могу да увезем страницу „$1“ јер она припада посебном именском простору које не прихвата странице.",
        "import-error-invalid": "Не могу да увезем страницу „$1“ јер је њен назив неисправан.",
        "import-error-unserialize": "Верзија $2 странице $1 не може бити прочитана/увезена. Записано је да верзија користи $3 тип садржаја у $4 формату.",
-       "import-options-wrong": "{{PLURAL:$2|Ð\9fогÑ\80еÑ\88но Ð¿Ð¾Ð´ÐµÑ\88аваÑ\9aе|Ð\9fогÑ\80еÑ\88на Ð¿Ð¾Ð´ÐµÑ\88аваÑ\9aа}}: <nowiki>$1</nowiki>",
+       "import-options-wrong": "{{PLURAL:$2|Ð\9fогÑ\80еÑ\88на Ð¾Ð¿Ñ\86иÑ\98а|Ð\9fогÑ\80еÑ\88не Ð¾Ð¿Ñ\86иÑ\98е}}: <nowiki>$1</nowiki>",
        "import-rootpage-invalid": "Наведена основна страница има неисправан наслов.",
        "import-rootpage-nosubpage": "Именски простор „$1“ основне странице не дозвољава подстранице.",
        "importlogpage": "Дневник увоза",
        "tooltip-pt-watchlist": "Списак страница које надгледате",
        "tooltip-pt-mycontris": "Списак {{GENDER:|Ваших}} доприноса",
        "tooltip-pt-anoncontribs": "Списак измена направљених са ове IP адресе",
-       "tooltip-pt-login": "Ð\9fÑ\80епоÑ\80Ñ\83Ñ\87Ñ\83Ñ\98емо Вам да се пријавите, иако то није обавезно",
+       "tooltip-pt-login": "Ð\9fÑ\80едлажемо Вам да се пријавите, иако то није обавезно",
        "tooltip-pt-login-private": "Морате да се пријавите да бисте користили овај Вики",
        "tooltip-pt-logout": "Одјавите се",
-       "tooltip-pt-createaccount": "Ð\9fÑ\80епоÑ\80Ñ\83Ñ\87иÑ\98емо Вам да отворите налог и пријавите се, иако то није обавезно",
+       "tooltip-pt-createaccount": "Ð\9fÑ\80едлажемо Вам да отворите налог и пријавите се, иако то није обавезно",
        "tooltip-ca-talk": "Разговор о страници са садржајем",
        "tooltip-ca-edit": "Уредите ову страницу",
        "tooltip-ca-addsection": "Започните нови одељак",
-       "tooltip-ca-viewsource": "Ð\9eва Ñ\81Ñ\82Ñ\80аниÑ\86а Ñ\98е Ð·Ð°ÐºÑ\99Ñ\83Ñ\87ана. \nÐ\9cожеÑ\82е Ð¿Ð¾Ð³Ð»ÐµÐ´Ð°Ñ\82и Ð¸Ð·Ð²Ð¾Ñ\80ни Ñ\82екÑ\81Ñ\82.",
+       "tooltip-ca-viewsource": "Ð\9eва Ñ\81Ñ\82Ñ\80аниÑ\86а Ñ\98е Ð·Ð°ÐºÑ\99Ñ\83Ñ\87ана. \nÐ\9cожеÑ\82е Ð´Ð° Ð¿Ð¾Ð³Ð»ÐµÐ´Ð°Ñ\82е Ñ\9aен Ð¸Ð·Ð²Ð¾Ñ\80ник",
        "tooltip-ca-history": "Претходне измене ове странице",
        "tooltip-ca-protect": "Заштитите ову страницу",
        "tooltip-ca-unprotect": "Промени заштиту ове странице",
        "tooltip-ca-delete": "Обришите ову страницу",
        "tooltip-ca-undelete": "Врати измене направљене на овој страници пре него што буде обрисана",
        "tooltip-ca-move": "Премести ову страницу",
-       "tooltip-ca-watch": "Додајте ову страницу на списак надгледања",
-       "tooltip-ca-unwatch": "Уклони ову страницу са списка надгледања",
-       "tooltip-search": "Ð\9fÑ\80еÑ\82Ñ\80ага",
-       "tooltip-search-go": "Идите на страницу с овим именом, ако постоји",
-       "tooltip-search-fulltext": "Претражите странице с овим текстом",
+       "tooltip-ca-watch": "Ð\94одаÑ\98Ñ\82е Ð¾Ð²Ñ\83 Ñ\81Ñ\82Ñ\80аниÑ\86Ñ\83 Ð½Ð° Ñ\81воÑ\98 Ñ\81пиÑ\81ак Ð½Ð°Ð´Ð³Ð»ÐµÐ´Ð°Ñ\9aа",
+       "tooltip-ca-unwatch": "Уклоните ову страницу са списка надгледања",
+       "tooltip-search": "Ð\9fÑ\80еÑ\82Ñ\80ажиÑ\82е Ð¿Ñ\80оÑ\98екаÑ\82 {{SITENAME}}",
+       "tooltip-search-go": "Идите на страницу с тачно овим именом ако постоји",
+       "tooltip-search-fulltext": "Претражите странице са овим текстом",
        "tooltip-p-logo": "Посетите главну страну",
        "tooltip-n-mainpage": "Посетите главну страну",
        "tooltip-n-mainpage-description": "Посетите главну страну",
        "tooltip-n-portal": "О пројекту, шта можете да радите и где да пронађете ствари",
-       "tooltip-n-currentevents": "СазнаÑ\98Ñ\82е Ð²Ð¸Ñ\88е Ð¾ Ñ\82Ñ\80енÑ\83Ñ\82ним Ð´Ð¾Ð³Ð°Ñ\92аÑ\98има",
+       "tooltip-n-currentevents": "Ð\9fÑ\80онаÑ\92иÑ\82е Ð´Ð¾Ð´Ð°Ñ\82не Ð¸Ð½Ñ\84оÑ\80маÑ\86иÑ\98е Ð¾ Ð°ÐºÑ\82Ñ\83елноÑ\81Ñ\82има",
        "tooltip-n-recentchanges": "Списак скорашњих измена на викију",
        "tooltip-n-randompage": "Учитајте случајну страницу",
-       "tooltip-n-help": "Место где можете да се информишете",
-       "tooltip-t-whatlinkshere": "Списак свих страница које воде овде",
-       "tooltip-t-recentchangeslinked": "Скорашње измене на страницама које су повезане с овом страницом",
+       "tooltip-n-help": "Место где можете да научите нешто",
+       "tooltip-t-whatlinkshere": "Списак свих вики страница које воде овде",
+       "tooltip-t-recentchangeslinked": "Скорашње измене на страницама које су повезане са овом страницом",
        "tooltip-feed-rss": "RSS довод ове странице",
        "tooltip-feed-atom": "Атом довод ове странице",
        "tooltip-t-contributions": "Списак доприноса {{GENDER:$1|овог корисника|ове кориснице|овог корисника}}",
        "tooltip-t-permalink": "Трајна веза ка овој измени странице",
        "tooltip-ca-nstab-main": "Погледајте страницу са садржајем",
        "tooltip-ca-nstab-user": "Погледајте корисничку страницу",
-       "tooltip-ca-nstab-media": "Погледајте мултимедијалну датотеку",
+       "tooltip-ca-nstab-media": "Погледајте медијску страницу",
        "tooltip-ca-nstab-special": "Ово је посебна страница. Не можете је мењати.",
        "tooltip-ca-nstab-project": "Погледајте страницу пројекта",
-       "tooltip-ca-nstab-image": "Прикажи страницу датотеке",
+       "tooltip-ca-nstab-image": "Погледајте страницу датотеке",
        "tooltip-ca-nstab-mediawiki": "Погледајте системску поруку",
        "tooltip-ca-nstab-template": "Погледајте шаблон",
        "tooltip-ca-nstab-help": "Погледајте страницу за помоћ",
-       "tooltip-ca-nstab-category": "Ð\9fогледаÑ\98Ñ\82е Ñ\81Ñ\82Ñ\80аниÑ\86Ñ\83 ÐºÐ°Ñ\82егоÑ\80иÑ\98а",
+       "tooltip-ca-nstab-category": "Ð\9fогледаÑ\98Ñ\82е Ñ\81Ñ\82Ñ\80аниÑ\86Ñ\83 ÐºÐ°Ñ\82егоÑ\80иÑ\98е",
        "tooltip-minoredit": "Означите ову измену као мању",
        "tooltip-save": "Сачувајте своје измене",
-       "tooltip-publish": "Објавите Ваше измене",
+       "tooltip-publish": "Објавите своје измене",
        "tooltip-preview": "Прегледајте своје измене. Користите ово дугме пре чувања.",
        "tooltip-diff": "Погледајте које измене сте направили на тексту",
        "tooltip-compareselectedversions": "Погледаjте разлике између две изабране измене ове странице.",
        "tooltip-watch": "Додајте ову страницу на свој списак надгледања",
-       "tooltip-watchlistedit-normal-submit": "Уклони наслове",
+       "tooltip-watchlistedit-normal-submit": "Уклоните наслове",
        "tooltip-watchlistedit-raw-submit": "Ажурирај списак",
        "tooltip-recreate": "Поново направите страницу иако је обрисана",
        "tooltip-upload": "Започните отпремање",
-       "tooltip-rollback": "â\80\9eÐ\92Ñ\80аÑ\82иâ\80\9c Ð²Ñ\80аÑ\9bа Ð¸Ð·Ð¼ÐµÐ½Ðµ Ð¿Ð¾Ñ\81ледÑ\9aег ÐºÐ¾Ñ\80иÑ\81ника једним кликом",
-       "tooltip-undo": "Опција „поништи” враћа ову измену и отвара образац за уређивање у претпрегледном моду. Омогућава додавање разлога у опису измене.",
+       "tooltip-rollback": "â\80\9eÐ\92Ñ\80аÑ\82иâ\80\9c Ð²Ñ\80аÑ\9bа Ð¸Ð·Ð¼ÐµÐ½Ðµ Ð¿Ð¾Ñ\81ледÑ\9aег Ð´Ð¾Ð¿Ñ\80иноÑ\81иоÑ\86а Ð¾Ð²Ðµ Ñ\81Ñ\82Ñ\80аниÑ\86е једним кликом",
+       "tooltip-undo": "„Поништи” враћа ову измену и отвара образац за уређивање у претпрегледном моду. Дозвољава додавање разлога у опису измене.",
        "tooltip-preferences-save": "Сачувај подешавања",
        "tooltip-summary": "Унесите кратак опис",
        "interlanguage-link-title": "$1 — $2",
        "spam_blanking": "Све измене садрже везе до $1. Чистим",
        "spam_deleting": "Све измене садрже везе до $1. Бришем",
        "simpleantispam-label": "Анти-спам провера. \n<strong>Не</strong> попуњавај ово унутра!",
-       "pageinfo-title": "Ð\9fодаÑ\86и Ð¾ „$1“",
+       "pageinfo-title": "Ð\98нÑ\84оÑ\80маÑ\86иÑ\98е Ð·Ð° „$1“",
        "pageinfo-not-current": "Нажалост, немогуће је прибавити ове податке за старије измене.",
-       "pageinfo-header-basic": "Ð\9eÑ\81новни Ð¿Ð¾Ð´Ð°Ñ\86и",
+       "pageinfo-header-basic": "Ð\9eÑ\81новне Ð¸Ð½Ñ\84оÑ\80маÑ\86иÑ\98е",
        "pageinfo-header-edits": "Историја измена",
        "pageinfo-header-restrictions": "Заштита странице",
        "pageinfo-header-properties": "Својства странице",
        "pageinfo-robot-noindex": "Није дозвољено",
        "pageinfo-watchers": "Број надгледача странице",
        "pageinfo-visiting-watchers": "Број надгледача странице који су посетили скорашње измене",
-       "pageinfo-few-watchers": "Ð\9cаÑ\9aе Ð¾Ð´ $1 {{PLURAL:$1|пÑ\80аÑ\82иоÑ\86а|пÑ\80аÑ\82иоÑ\86а|пÑ\80аÑ\82илаÑ\86а}}",
+       "pageinfo-few-watchers": "Ð\9cаÑ\9aе Ð¾Ð´ $1 {{PLURAL:$1|надгледаÑ\87а}}",
        "pageinfo-redirects-name": "Број преусмерења на ову страницу",
        "pageinfo-redirects-value": "$1",
-       "pageinfo-subpages-name": "Ð\9fодÑ\81Ñ\82Ñ\80аниÑ\86е ове странице",
+       "pageinfo-subpages-name": "Ð\91Ñ\80оÑ\98 Ð¿Ð¾Ð´Ñ\81Ñ\82Ñ\80аниÑ\86а ове странице",
        "pageinfo-subpages-value": "$1 ($2 {{PLURAL:$2|преусмерење|преусмерења|преусмерења}}; $3 {{PLURAL:$3|непреусмерење|непреусмерења|непреусмерења}})",
        "pageinfo-firstuser": "Аутор странице",
        "pageinfo-firsttime": "Датум стварања странице",
        "pageinfo-hidden-categories": "{{PLURAL:$1|Сакривена категорија|Сакривене категорије}} ($1)",
        "pageinfo-templates": "{{PLURAL:$1|Укључени шаблон|Укључени шаблони}} ($1)",
        "pageinfo-transclusions": "{{PLURAL:$1|Страница|Странице}} укључене у ($1)",
-       "pageinfo-toolboxlink": "Ð\9fодаÑ\86и о страници",
+       "pageinfo-toolboxlink": "Ð\98нÑ\84оÑ\80маÑ\86иÑ\98е о страници",
        "pageinfo-redirectsto": "Преусмерава на",
        "pageinfo-redirectsto-info": "подаци",
        "pageinfo-contentpage": "Рачуна се као страница са садржајем",
        "markedaspatrollederrornotify": "Означавање ове измене патролираном није успело.",
        "patrol-log-page": "Дневник патролирања",
        "patrol-log-header": "Ово је дневник патролираних измена.",
-       "log-show-hide-patrol": "$1 дневник патролирања",
-       "log-show-hide-tag": "$1 дневник ознака",
        "confirm-markpatrolled-button": "У реду",
        "confirm-markpatrolled-top": "Означити измену $3 странице $2 патролираном?",
        "deletedrevision": "Обрисана стара измена $1.",
        "svg-long-desc": "SVG датотека, номинално $1 × $2 пиксела, величина: $3",
        "svg-long-desc-animated": "Анимирана SVG датотека, номинално: $1 × $2 пиксела, величина: $3",
        "svg-long-error": "Неисправна SVG датотека: $1",
-       "show-big-image": "Ð\9fÑ\83на Ð²ÐµÐ»Ð¸Ñ\87ина",
+       "show-big-image": "Ð\98звоÑ\80на Ð´Ð°Ñ\82оÑ\82ека",
        "show-big-image-preview": "Величина овог приказа: $1.",
        "show-big-image-preview-differ": "Величина $3 прегледа за ову $2 датотеку је $1.",
        "show-big-image-other": "$2 {{PLURAL:$2|друга резолуција|друге резолуције|других резолуција}}: $1.",
        "version-libraries-description": "Опис",
        "version-libraries-authors": "Аутори",
        "redirect": "Преусмерење на датотеку, корисника, страницу, измену или дневник (ID)",
-       "redirect-summary": "Ова посебна страница преусмерава до датотеке (са датим именом датотеке), странице (са датим ID-ом измене или ID-ом странице), корисничке странице (са датим нумеричким корисничким ID-ом), или уноса у дневнику (са датим дневничким ID-ом). Употреба: [[{{#Special:Redirect}}/file/Example.jpg]], [[{{#Special:Redirect}}/page/64308]], [[{{#Special:Redirect}}/revision/328429]], [[{{#Special:Redirect}}/user/101]], or [[{{#Special:Redirect}}/logid/186]].",
+       "redirect-summary": "Ова посебна страница преусмерава до датотеке (с датим именом датотеке), странице (с датим ID-ом измене или ID-ом странице), корисничке странице (с датим нумеричким корисничким ID-ом), или уноса у дневнику (с датим дневничким ID-ом). Употреба: [[{{#Special:Redirect}}/file/Example.jpg]], [[{{#Special:Redirect}}/page/64308]], [[{{#Special:Redirect}}/revision/328429]], [[{{#Special:Redirect}}/user/101]], or [[{{#Special:Redirect}}/logid/186]].",
        "redirect-submit": "Иди",
        "redirect-lookup": "Тип вредности:",
        "redirect-value": "Вредност:",
        "tags": "Важеће ознаке измена",
        "tag-filter": "Филтер за [[Special:Tags|ознаке]]:",
        "tag-filter-submit": "Филтрирај",
-       "tag-list-wrapper": "([[Special:Tags|$1 {{PLURAL:$1|ознака|ознаке|ознака}}]]: $2)",
+       "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|ознака|ознаке}}]]: $2)",
        "tag-mw-contentmodelchange": "промена модела садржаја",
        "tag-mw-contentmodelchange-description": "Измене које мењају модел садржаја странице",
        "tag-mw-new-redirect": "ново преусмерење",
        "tag-mw-removed-redirect-description": "Измене које мењају постојеће преусмерење у страницу без преусмерења",
        "tag-mw-changed-redirect-target": "промењено одредиште преусмерења",
        "tag-mw-changed-redirect-target-description": "Измене које мењају одредиште преусмерења",
-       "tag-mw-blank": "Страница испражњена",
+       "tag-mw-blank": "страница испражњена",
        "tag-mw-blank-description": "Измене које бришу читав садржај странице",
-       "tag-mw-replace": "Уклоњена већина текста",
+       "tag-mw-replace": "уклоњена већина текста",
        "tag-mw-replace-description": "Измене које уклањају више од 90% садржаја странице",
        "tag-mw-rollback": "враћање",
        "tag-mw-rollback-description": "Измене које враћају страницу на претходне измене",
-       "tag-mw-undo": "поништена ранија измена",
+       "tag-mw-undo": "поништење",
        "tag-mw-undo-description": "Измене које поништавају претходне измене",
        "tags-title": "Ознаке",
        "tags-intro": "На овој страници је наведен списак ознака с којима програм може да означи измене и његово значење.",
        "htmlform-title-not-exists": "$1 не постоји.",
        "htmlform-user-not-exists": "<strong>$1</strong> не постоји.",
        "htmlform-user-not-valid": "<strong>$1</strong> није исправно корисничко име.",
-       "logentry-delete-delete": "$1 је {{GENDER:$2|обрисао|обрисала|обрисао}} страницу $3",
+       "logentry-delete-delete": "$1 је {{GENDER:$2|обрисао|обрисала}} страницу $3",
        "logentry-delete-delete_redir": "$1 је {{GENDER:$2|обрисао|обрисала}} преусмерење $3 преписивањем",
        "logentry-delete-restore": "$1 је {{GENDER:$2|вратио|вратила}} страницу $3 ($4)",
        "logentry-delete-restore-nocount": "$1 је {{GENDER:$2|вратио|вратила}} страницу $3",
        "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ила}} кориснички налог $3 и лозинка је послата на имејл",
+       "logentry-newusers-byemail": "$1 Ñ\98е {{GENDER:$2|напÑ\80авио|напÑ\80авила}} кориснички налог $3 и лозинка је послата на имејл",
        "logentry-newusers-autocreate": "Кориснички налог $1 је аутоматски {{GENDER:$2|отворен}}",
        "logentry-protect-move_prot": "$1 је {{GENDER:$2|преместио|преместила}} подешавања заштите са $4 на $3",
        "logentry-protect-unprotect": "$1 je {{GENDER:$2|скинуо|скинула}} заштиту са странице $3",
        "feedback-cancel": "Откажи",
        "feedback-close": "Урађено",
        "feedback-external-bug-report-button": "Пријави грешку",
-       "feedback-dialog-title": "Ð\9fоÑ\88аÑ\99и Ð¿Ð¾Ð²Ñ\80аÑ\82нÑ\83 Ð¸Ð½Ñ\84оÑ\80маÑ\86иÑ\98Ñ\83",
+       "feedback-dialog-title": "СлаÑ\9aе Ð¿Ð¾Ð²Ñ\80аÑ\82не Ð¸Ð½Ñ\84оÑ\80маÑ\86иÑ\98е",
        "feedback-error1": "Грешка: непрепознат резултат од АПИ-ја",
        "feedback-error2": "Грешка: уређивање није успело",
        "feedback-error3": "Грешка: нема одговора од АПИ-ја",
        "log-description-pagelang": "Ово је дневник измена у језицима страница.",
        "logentry-pagelang-pagelang": "$1 је {{GENDER:$2|променио|променила}} језик странице $3 из $4 у $5.",
        "default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (омогућена)",
+       "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 (<strong>онемогућена</strong>)",
        "mediastatistics": "Статистика датотека",
        "mediastatistics-summary": "Статистике о типовима послатих датотека. Овде су урачунате само најновије верзије датотека. Старе или обрисане верзије нису урачунате.",
+       "mediastatistics-nbytes": "{{PLURAL:$1|$1 бајт|$1 бајта|$1 бајтова}} ($2; $3%)",
+       "mediastatistics-bytespertype": "Укупна величина датотеке овог одељка: {{PLURAL:$1|$1 бајт|$1 бајта|$1 бајтова}} ($2; $3%).",
+       "mediastatistics-allbytes": "Укупна величина свих датотека: {{PLURAL:$1|$1 бајт|$1 бајта|$1 бајтова}} ($2).",
        "mediastatistics-table-mimetype": "MIME тип",
        "mediastatistics-table-extensions": "Могуће екстензије",
        "mediastatistics-table-count": "Број датотека",
        "json-error-state-mismatch": "Невалидан или покварени JSON",
        "json-error-ctrl-char": "Грешка контролног симбола, могуће је да је неисправно енкодиран",
        "json-error-syntax": "Грешка у синтакси",
+       "json-error-utf8": "Малформирани UTF-8 знаци, могуће је да су неисправно енкодирани",
+       "json-error-recursion": "Једна или више рекурзивних референци у вредности коју треба енкодирати.",
+       "json-error-inf-or-nan": "Једна или више NAN или INF вредности у вредности коју треба енкодирати",
        "json-error-unsupported-type": "Дата је вреднос врсте која се не може енкодирати",
        "headline-anchor-title": "Веза до овог одељка",
        "special-characters-group-latin": "Латиница",
        "special-characters-group-latinextended": "Проширена латиница",
-       "special-characters-group-ipa": "Ð\98Ð\9fА",
+       "special-characters-group-ipa": "Ð\9cФА",
        "special-characters-group-symbols": "Симболи",
        "special-characters-group-greek": "Грчки",
        "special-characters-group-greekextended": "Проширени грчки",
        "mw-widgets-dateinput-no-date": "Датум није изабран",
        "mw-widgets-dateinput-placeholder-day": "ГГГГ-ММ-ДД",
        "mw-widgets-dateinput-placeholder-month": "ГГГГ-ММ",
-       "mw-widgets-mediasearch-input-placeholder": "Претражи датотеке",
+       "mw-widgets-mediasearch-input-placeholder": "Претражите датотеке",
        "mw-widgets-mediasearch-noresults": "Нема резултата.",
        "mw-widgets-titleinput-description-new-page": "страница још увек не постоји",
        "mw-widgets-titleinput-description-redirect": "преусмерава на $1",
        "date-range-to": "До датума:",
        "sessionprovider-generic": "$1 сесије",
        "sessionprovider-mediawiki-session-cookiesessionprovider": "сесије са колачићима",
+       "sessionprovider-nocookies": "Колачићи су можда онемогућени. Уверите се да су колачићи омогућени и почните поново.",
        "randomrootpage": "Случајна коренска страница",
        "log-action-filter-block": "Тип блокирања:",
        "log-action-filter-contentmodel": "Тип промене модела садржаја:",
        "log-action-filter-newusers-create": "отворио анониман корисник",
        "log-action-filter-newusers-create2": "отворио регистрован корисник",
        "log-action-filter-newusers-autocreate": "аутоматски отворен",
+       "log-action-filter-newusers-byemail": "отварање лозинком посланом на имејлу",
        "log-action-filter-patrol-patrol": "ручно",
        "log-action-filter-patrol-autopatrol": "аутоматско",
        "log-action-filter-protect-protect": "закључавање",
        "undelete-cantcreate": "Не можете повратити ову страницу јер нема постојеће странице са овим именом и немате дозволу да направите ову страницу.",
        "pagedata-title": "Подаци странице",
        "pagedata-not-acceptable": "Није пронађен одговарајући облик. Подржане MIME-врсте: $1",
-       "pagedata-bad-title": "Невалидан наслов: $1."
+       "pagedata-bad-title": "Невалидан наслов: $1.",
+       "passwordpolicies": "Правила за лозинке",
+       "passwordpolicies-group": "Група",
+       "passwordpolicies-policies": "Правила",
+       "passwordpolicies-policy-minimalpasswordlength": "Лозинка мора да има најмање {{PLURAL:$1|један знак|$1 знака|$1 знакова}}",
+       "passwordpolicies-policy-passwordcannotmatchusername": "Лозинка не може да буде иста као корисничко име",
+       "passwordpolicies-policy-passwordcannotmatchblacklist": "Лозинка се не може подударати са лозинкама на црној листи",
+       "passwordpolicies-policy-maximalpasswordlength": "Лозинка мора да буде краћа од $1 {{PLURAL:$1|знака|знакова}}",
+       "passwordpolicies-policy-passwordcannotbepopular": "Лозинка не може да буде {{PLURAL:$1|популарна лозинка|на списку $1 популарних лозинки}}"
 }
index d947d2a..8f4753c 100644 (file)
                        "Prevodim",
                        "Bugoslav",
                        "Acamicamacaraca",
-                       "Fitoschido"
+                       "Fitoschido",
+                       "BadDog",
+                       "Vlad5250"
                ]
        },
        "tog-underline": "Podvlačenje veza:",
-       "tog-hideminor": "Sakrij manje izmene u spisku skorašnjih izmena",
-       "tog-hidepatrolled": "Sakrij patrolirane izmene u spisku skorašnjih izmena",
+       "tog-hideminor": "Sakrij manje izmene sa spiska skorašnjih izmena",
+       "tog-hidepatrolled": "Sakrij patrolirane izmene sa spiska skorašnjih izmena",
        "tog-newpageshidepatrolled": "Sakrij patrolirane stranice sa spiska novih stranica",
        "tog-hidecategorization": "Sakrij kategorizaciju stranica",
        "tog-extendwatchlist": "Proširi spisak nadgledanja za prikaz svih izmena, ne samo skorašnjih",
-       "tog-usenewrc": "Grupni prikaz izmena svake pojedinačne stranice u skorašnjim izmenama i spisku nadgledanja",
+       "tog-usenewrc": "Grupiši izmene po stranici u skorašnjim izmenama i spisku nadgledanja",
        "tog-numberheadings": "Automatski numeriši podnaslove",
-       "tog-showtoolbar": "Prikaži traku s alatkama za uređivanje",
-       "tog-editondblclick": "Uređivanje stranica dvostrukim klikom",
+       "tog-showtoolbar": "Traka sa alatkama za uređivanje",
+       "tog-editondblclick": "Uredi stranice dvostrukim klikom",
        "tog-editsectiononrightclick": "Uređivanje odeljaka desnim klikom na njihove naslove",
-       "tog-watchcreations": "Dodaj stranice koje napravim i datoteke koje pošaljem u spisak nadgledanja",
-       "tog-watchdefault": "Dodaj stranice i datoteke koje izmenim u spisak nadgledanja",
-       "tog-watchmoves": "Dodaj stranice i datoteke koje premestim u spisak nadgledanja",
-       "tog-watchdeletion": "Dodaj stranice i datoteke koje obrišem u spisak nadgledanja",
-       "tog-watchuploads": "Dodaj datoteke koje otpremim u spisak nadgledanja",
-       "tog-watchrollback": "Dodaj stranice na kojima sam vratio izmene u spisak nadgledanja",
+       "tog-watchcreations": "Dodaj stranice koje napravim i datoteke koje otpremim u moj spisak nadgledanja",
+       "tog-watchdefault": "Dodaj stranice i datoteke koje izmenim u moj spisak nadgledanja",
+       "tog-watchmoves": "Dodaj stranice i datoteke koje premestim u moj spisak nadgledanja",
+       "tog-watchdeletion": "Dodaj stranice i datoteke koje obrišem u moj spisak nadgledanja",
+       "tog-watchuploads": "Dodaj datoteke koje otpremim u moj spisak nadgledanja",
+       "tog-watchrollback": "Dodaj stranice na kojima sam vratio izmene u moj spisak nadgledanja",
        "tog-minordefault": "Označavaj sve izmene kao manje",
-       "tog-previewontop": "Prikaži pregled pre okvira za uređivanje",
-       "tog-previewonfirst": "Prikaži pregled na prvoj izmeni",
-       "tog-enotifwatchlistpages": "Pošalji mi imejl kada se promeni stranica/datoteka koju nadgledam",
-       "tog-enotifusertalkpages": "Pošalji mi imejl kada se promeni moja stranica za razgovor",
-       "tog-enotifminoredits": "Pošalji mi imejl i za manje izmene u stranicama i datotekama",
-       "tog-enotifrevealaddr": "Prikaži moju imejl adresu u porukama obaveštenja",
+       "tog-previewontop": "Prikaži pretpregled pre okvira za uređivanje",
+       "tog-previewonfirst": "Prikaži pretpregled pri prvoj izmeni",
+       "tog-enotifwatchlistpages": "Pošalji mi imejl kada se promeni stranica ili datoteka sa mog spiska nadgledanja",
+       "tog-enotifusertalkpages": "Pošalji mi imejl kad se promeni moja stranica za razgovor",
+       "tog-enotifminoredits": "Pošalji mi imejl i kod manjih izmena stranica i datoteka",
+       "tog-enotifrevealaddr": "Otkrij moju imejl adresu u porukama obaveštenja",
        "tog-shownumberswatching": "Prikaži broj korisnika koji nadgledaju",
-       "tog-oldsig": "Potpis:",
+       "tog-oldsig": "Vaš postojeći potpis:",
        "tog-fancysig": "Smatraj potpis kao vikitekst (bez samopovezivanja)",
-       "tog-uselivepreview": "Koristi trenutni pregled",
+       "tog-uselivepreview": "Prikaži pretpregled bez ponovnog učitavanja stranice",
        "tog-forceeditsummary": "Upozori me kada ne unesem opis izmene",
        "tog-watchlisthideown": "Sakrij moje izmene sa spiska nadgledanja",
        "tog-watchlisthidebots": "Sakrij izmene botova sa spiska nadgledanja",
        "tog-watchlisthideminor": "Sakrij manje izmene sa spiska nadgledanja",
        "tog-watchlisthideliu": "Sakrij izmene prijavljenih korisnika sa spiska nadgledanja",
-       "tog-watchlistreloadautomatically": "Automatski osveži spisak nadgledanja kad god se filter izmeni (potrebna JavaScript-a)",
+       "tog-watchlistreloadautomatically": "Automatski osveži spisak nadgledanja kad god se filter izmeni (potreban JavaScript)",
+       "tog-watchlistunwatchlinks": "Dodaj veze za direktno dodavanje/uklanjanje stavki sa spiska nadgledanja (potreban JavaScript)",
        "tog-watchlisthideanons": "Sakrij izmene anonimnih korisnika sa spiska nadgledanja",
        "tog-watchlisthidepatrolled": "Sakrij patrolirane izmene sa spiska nadgledanja",
        "tog-watchlisthidecategorization": "Sakrij kategorizaciju stranica",
        "tog-ccmeonemails": "Pošalji mi kopije imejlova koje pošaljem drugim korisnicima",
        "tog-diffonly": "Ne prikazuj sadržaj stranice ispod razlika",
-       "tog-showhiddencats": "Prikaži skrivene kategorije",
+       "tog-showhiddencats": "Skrivene kategorije",
        "tog-norollbackdiff": "Ne prikazuj razliku nakon izvršenog vraćanja",
-       "tog-useeditwarning": "Upozori me kada napuštam stranicu sa nesačuvanim promenama",
-       "tog-prefershttps": "Uvek koristi bezbednu konekciju dok sam prijavljen.",
-       "underline-always": "uvek podvlači",
-       "underline-never": "nikad ne podvlači",
+       "tog-useeditwarning": "Upozori me kada napuštam stranicu sa nesačuvanim izmenama",
+       "tog-prefershttps": "Uvek koristi sigurnu vezu dok sam prijavljen.",
+       "underline-always": "uvek",
+       "underline-never": "nikad",
        "underline-default": "prema temi ili pregledaču",
-       "editfont-style": "Izgled fonta u uređivačkom okviru:",
+       "editfont-style": "Stil fonta u okviru za uređivanje:",
        "editfont-monospace": "srazmerno širok font",
        "editfont-sansserif": "beserifni font",
        "editfont-serif": "serifni font",
        "category-file-count-limited": "{{PLURAL:$1|1=Sledeća datoteka je|Sledeće $1 datoteke su|Sledećih $1 datoteka je}} u ovoj kategoriji.",
        "listingcontinuesabbrev": "nast.",
        "index-category": "Popisane stranice",
-       "noindex-category": "Neindeksirane stranice",
+       "noindex-category": "Nepopisane stranice",
        "broken-file-category": "Stranice s neispravnim vezama do datoteka",
+       "categoryviewer-pagedlinks": "$1 ($2)",
+       "category-header-numerals": "$1–$2",
        "about": "O nama",
-       "article": "Stranica sa sadržajem",
+       "article": "Članak",
        "newwindow": "(otvara se u novom prozoru)",
        "cancel": "Otkaži",
        "moredotdotdot": "Više…",
        "variants": "Varijante",
        "navigation-heading": "Navigacioni meni",
        "errorpagetitle": "Greška",
-       "returnto": "Nazad na $1.",
+       "returnto": "Nazad na stranicu „$1“.",
        "tagline": "Izvor: {{SITENAME}}",
        "help": "Pomoć",
        "search": "Pretraga",
-       "search-ignored-headings": "#<!-- ovu liniju ostavite onakvu kakva jeste --> <pre>\n# Naslovi koji će biti ignorisani upitom\n# Promene su vidljive odmah nakon što stranica sa naslovom bude popisana\n# Možete iznuditi ponovno popisivanje sa \"null\" promenom\n# Sintaksa je sledeća:\n# * Svaka vrsta koja započinje \"#\" znakom pa sve do kraja je komentar\n# * Svaka ne prazna vrsta je tačan naslov za zanemariti, u tačnom obliku\nReference\nSpoljašnje veze\nPogledajte\n#</pre> <!-- ovu liniju ostavite onakvu kakva jeste -->",
+       "search-ignored-headings": " #<!-- ne menjajte ništa u ovom redu --> <pre>\n# Naslovi koji će biti zanemareni pri pretrazi.\n# Izmene su vidljive odmah nakon što se stranica sa naslovom popiše.\n# Možete iznuditi ponovno popisivanje „nultom” izmenom.\n# Sintaksa je sledeća:\n#  * Svaki red koji započinje znakom „#” je komentar.\n#  * Svaki ne prazni red je tačan naslov koji će biti zanemaren, s tim da se razlikuju mala i velika slova i sve ostalo\nReference\nSpoljašnje veze\nTakođe pogledajte\n #</pre> <!-- ne menjajte ništa u ovom redu -->",
        "searchbutton": "Pretraži",
        "go": "Idi",
        "searcharticle": "Idi",
        "permalink": "Trajna veza",
        "print": "Štampaj",
        "view": "Pogledaj",
-       "view-foreign": "Vidi na projektu $1",
+       "view-foreign": "Pogledaj na projektu $1",
        "edit": "Uredi",
        "edit-local": "Uredi lokalni opis",
        "create": "Napravi",
        "create-local": "Dodaj lokalni opis",
        "delete": "Obriši",
-       "undelete_short": "Vrati {{PLURAL:$1|1=jednu obrisanu izmenu|$1 obrisane izmene|$1 obrisanih izmena}}",
+       "undelete_short": "Vrati {{PLURAL:$1|obrisanu izmenu|$1 obrisane izmene|$1 obrisanih izmena}}",
        "viewdeleted_short": "Pogledaj {{PLURAL:$1|obrisanu izmenu|$1 obrisane izmene|$1 obrisanih izmena}}",
        "protect": "Zaštiti",
        "protect_change": "promeni",
        "views": "Pregledi",
        "toolbox": "Alatke",
        "tool-link-userrights": "Uredi {{GENDER:$1|korisničke}} grupe",
-       "tool-link-userrights-readonly": "Prikaži {{GENDER:$1|korisnik}} grupe",
-       "tool-link-emailuser": "Pošalji imejl",
+       "tool-link-userrights-readonly": "{{GENDER:$1|Korisničke}} grupe",
+       "tool-link-emailuser": "Pošalji imejl {{GENDER:$1|korisniku|korisnici}}",
        "imagepage": "Pogledaj stranicu datoteke",
        "mediawikipage": "Pogledaj stranicu poruke",
        "templatepage": "Pogledaj stranicu šablona",
        "viewhelppage": "Pogledaj stranicu pomoći",
-       "categorypage": "Pogledaj stranicu kategorija",
+       "categorypage": "Pogledaj stranicu kategorije",
        "viewtalkpage": "Pogledaj razgovor",
        "otherlanguages": "Na drugim jezicima",
        "redirectedfrom": "(preusmereno sa $1)",
        "redirectpagesub": "Preusmerenje",
        "redirectto": "Preusmerava na:",
        "lastmodifiedat": "Ova stranica je poslednji put uređena na datum $1 u $2 č.",
-       "viewcount": "Ova stranica je pregledana {{PLURAL:$1|jedanput|$1 puta|$1 puta}}.",
+       "viewcount": "Ovoj stranici je pristupljeno {{PLURAL:$1|jedanput|$1 puta}}.",
        "protectedpage": "Zaštićena stranica",
        "jumpto": "Idi na:",
        "jumptonavigation": "navigaciju",
        "pool-timeout": "Istek vremena čeka na zaključavanje",
        "pool-queuefull": "Red je pun zahteva",
        "pool-errorunknown": "Nepoznata greška",
-       "pool-servererror": "Brojač fonda trenutno nije dostupan ($1)",
-       "poolcounter-usage-error": "Greška tokom upotrebe: $1",
+       "pool-servererror": "Usluga brojača redova nije dostupna ($1).",
+       "poolcounter-usage-error": "Greška pri upotrebi: $1",
        "aboutsite": "O projektu {{SITENAME}}",
-       "aboutpage": "Project:O nama",
+       "aboutpage": "Project:O_projektu_{{SITENAME}}",
        "copyright": "Sadržaj je dostupan pod licencom $1 osim ako je drugačije navedeno.",
        "copyrightpage": "{{ns:project}}:Autorska prava",
        "currentevents": "Aktuelnosti",
        "mainpage-description": "Glavna strana",
        "policy-url": "Project:Pravila",
        "portal": "Portal zajednice",
-       "portal-url": "Project:Radionica",
+       "portal-url": "Project:Portal zajednice",
        "privacy": "Politika privatnosti",
        "privacypage": "Project:Politika privatnosti",
        "badaccess": "Greške u ovlašćenjima",
-       "badaccess-group0": "Nije vam dozvoljeno da izvršite zahtevanu radnju.",
+       "badaccess-group0": "Nije Vam dozvoljeno da izvršite zahtevanu radnju.",
        "badaccess-groups": "Radnja koju ste zahtevali je ograničena samo korisnicima u {{PLURAL:$2|sledećoj grupi|sledećim grupama}}: $1.",
-       "versionrequired": "Potrebno je izdanje $1 Medijavikija",
+       "versionrequired": "Potrebna je verzija $1 Medijavikija",
        "versionrequiredtext": "Potrebno je izdanje $1 Medijavikija da biste koristili ovu stranicu.\nPogledajte stranicu za [[Special:Version|izdanje]].",
        "ok": "U redu",
        "pagetitle": "$1 — {{SITENAME}}",
        "pagetitle-view-mainpage": "{{SITENAME}}",
        "backlinksubtitle": "← $1",
        "retrievedfrom": "Preuzeto iz „$1“",
-       "youhavenewmessages": "Imate $1 ($2).",
-       "youhavenewmessagesfromusers": "Imate $1 od {{PLURAL:$3|drugog korisnika|$3 korisnika|$3 korisnika}} ($2).",
+       "youhavenewmessages": "{{PLURAL:$3|Imate}} $1 ($2).",
+       "youhavenewmessagesfromusers": "{{PLURAL:$4|Imate}} $1 od {{PLURAL:$3|drugog korisnika|$3 korisnika}} ($2).",
        "youhavenewmessagesmanyusers": "Imate $1 od mnogo korisnika ($2).",
-       "newmessageslinkplural": "{{PLURAL:$1|novu poruku|999=nove poruke}}",
-       "newmessagesdifflinkplural": "{{PLURAL:$1|poslednja izmena|999=poslednje izmene}}",
-       "youhavenewmessagesmulti": "Imate novih poruka na $1",
+       "newmessageslinkplural": "{{PLURAL:$1|novu poruku|nove poruke|novih poruka}}",
+       "newmessagesdifflinkplural": "{{PLURAL:$1|poslednja izmena|poslednje izmene|poslednjih izmena}}",
+       "youhavenewmessagesmulti": "Imate nove poruke na $1",
        "editsection": "uredi",
        "editold": "uredi",
        "viewsourceold": "izvorni kod",
        "editlink": "uredi",
        "viewsourcelink": "izvorni kod",
-       "editsectionhint": "Uredi odeljak „$1“",
+       "editsectionhint": "Uredite odeljak „$1“",
        "toc": "Sadržaj",
        "showtoc": "prikaži",
        "hidetoc": "sakrij",
-       "collapsible-collapse": "Skupi",
-       "collapsible-expand": "Proširi",
+       "collapsible-collapse": "sakrij",
+       "collapsible-expand": "prikaži",
        "confirmable-confirm": "Da li {{GENDER:$1|ste}} sigurni?",
        "confirmable-yes": "Da",
        "confirmable-no": "Ne",
-       "thisisdeleted": "Pogledati ili vratiti $1?",
-       "viewdeleted": "Pogledati $1?",
-       "restorelink": "{{PLURAL:$1|1=obrisanu izmenu|$1 obrisane izmene|$1 obrisanih izmena}}",
+       "thisisdeleted": "Pogledaj ili vrati $1?",
+       "viewdeleted": "Pogledaj $1?",
+       "restorelink": "{{PLURAL:$1|obrisanu izmenu|$1 obrisane izmene|$1 obrisanih izmena}}",
        "feedlinks": "Dovod:",
        "feed-invalid": "Neispravna vrsta dovoda.",
        "feed-unavailable": "Dovodi nisu dostupni",
        "sort-descending": "Poređaj opadajuće",
        "sort-ascending": "Poređaj rastuće",
        "nstab-main": "Stranica",
-       "nstab-user": "{{GENDER:{{BASEPAGENAME}}|Korisnik|Korisnica}}",
+       "nstab-user": "{{GENDER:{{BASEPAGENAME}}|Korisnik|Korisnica|Korisnik}}",
        "nstab-media": "Mediji",
        "nstab-special": "Posebno",
        "nstab-project": "Projekat",
        "nosuchaction": "Nema takve radnje",
        "nosuchactiontext": "Radnja navedena u adresi nije ispravna.\nMožda ste pogrešno napisali adresu ili ste pratili zastarelu vezu.\nMoguće je i da se radi o grešci u softveru vikija.",
        "nosuchspecialpage": "Nema takve posebne stranice",
-       "nospecialpagetext": "<strong>Posebna stranica ne postoji.</strong>\n\nSpisak svih posebnih stranica nalazi se [[Special:SpecialPages|ovde]].",
+       "nospecialpagetext": "<strong>Posebna stranica koju ste zahtevali ne postoji.</strong>\n\nSpisak svih posebnih stranica nalazi se na „[[Special:SpecialPages|{{int:specialpages}}]]”.",
        "error": "Greška",
        "databaseerror": "Greška u bazi podataka",
        "databaseerror-text": "Došlo je do greške u upitu baze podataka. Možda je u pitanju programska greška.",
        "databaseerror-function": "Funkcija: $1",
        "databaseerror-error": "Greška: $1",
        "transaction-duration-limit-exceeded": "Zbog izbegavanja velikih kopirajućih zaostajanja, ova transakcija je prekinuta zbog toga što je trajanje zapisivanja ($1) premašilo ($2) sekundi ograničenja. \nUkoliko menjate puno artikala odjednom, pokušajte sa više manjih operacija.",
-       "laggedslavemode": "<strong>Upozorenje:</strong> stranica je možda zastarela.",
+       "laggedslavemode": "<strong>Upozorenje:</strong> moguće je da stranica nije ažurirana.",
        "readonly": "Baza podataka je zaključana",
        "enterlockreason": "Unesite razlog za zaključavanje, uključujući i vreme otključavanja",
        "readonlytext": "Baza podataka je trenutno zaključana, što znači da je nije moguće menjati.\n\nSistemski administrator je naveo sledeće objašnjenje: $1",
        "missingarticle-diff": "(razlika: $1, $2)",
        "readonly_lag": "Baza podataka je automatski zaključana da bi se sekundarni serveri baze podataka uskladili s glavnim.",
        "internalerror": "Unutrašnja greška",
-       "internalerror_info": "Unutrašnja greška: $1",
-       "internalerror-fatal-exception": "Kritični izuzetak tipa $1",
-       "filecopyerror": "Ne mogu da umnožim datoteku „$1“ u „$2“.",
+       "internalerror_info": "Interna greška: $1",
+       "internalerror-fatal-exception": "Fatalna greška tipa „$1“",
+       "filecopyerror": "Ne mogu da kopiram datoteku „$1“ u „$2“.",
        "filerenameerror": "Ne mogu da preimenujem datoteku „$1“ u „$2“.",
        "filedeleteerror": "Ne mogu da obrišem datoteku „$1“.",
-       "directorycreateerror": "Ne mogu da napravim fasciklu „$1“.",
+       "directorycreateerror": "Ne mogu da napravim direktorijum „$1“.",
        "directoryreadonlyerror": "Direktorijum „$1“ je samo za čitanje.",
        "directorynotreadableerror": "Direktorijum „$1“ nije čitljiv.",
        "filenotfound": "Ne mogu da pronađem datoteku „$1“.",
        "unexpected": "Neočekivana vrednost: „$1“=„$2“.",
-       "formerror": "Greška: ne mogu da pošaljem obrazac",
+       "formerror": "Greška: ne mogu da pošaljem obrazac.",
        "badarticleerror": "Ova radnja se ne može izvršiti na ovoj stranici.",
        "cannotdelete": "Ne mogu da obrišem stranicu ili datoteku „$1“.\nVerovatno ju je neko drugi obrisao.",
        "cannotdelete-title": "Ne mogu da obrišem stranicu „$1“",
        "delete-hook-aborted": "Brisanje je prekinula kuka.\nNije dato nikakvo obrazloženje.",
-       "no-null-revision": "Nije moguće napraviti \"null\" reviziju za stranicu $1",
+       "no-null-revision": "Ne mogu da napravim novu praznu verziju za stranicu „$1“",
        "badtitle": "Neispravan naslov",
        "badtitletext": "Naslov stranice je neispravan, prazan ili je međujezički ili međuviki naslov pogrešno povezan.\nMožda sadrži znakove koji se ne mogu koristiti u naslovima.",
-       "title-invalid-empty": "Zatraženi naslov strane je prazan ili sadrži samo razmak.",
-       "title-invalid-utf8": "Zatraženi naslov stranice sadrži nevažeći UTF-8 niz.",
-       "title-invalid-interwiki": "Zatraženi naslov stranice sadrži \"interwiki\" vezu koja ne može biti upotrebljenja za naslove.",
-       "title-invalid-talk-namespace": "Zatraženi naslov strane se odnosi na stranicu za razgovor koja ne može da postoji.",
-       "title-invalid-characters": "Traženi naslov ima nevažeće karaktere: „$1“.",
-       "title-invalid-relative": "Naslov ima relativan put. Relativni naslovi (./, ../) su nevažeći, zato što će često biti nedostupni kroz korisnički pretraživač.",
-       "title-invalid-magic-tilde": "Naslov stranice koju ste tražili je nevažeći jer sadrži magični niz tildi (<nowiki>~~~</nowiki>)",
-       "title-invalid-too-long": "Naslov stranice koju ste tražili je predugačak. Ne sme da bude duži od $1 {{PLURAL:$1|bajt|bajtovi}} u UTF-8 znacima.",
-       "title-invalid-leading-colon": "Naslov stranice koju ste tražili sadrži dvotačku na početku.",
+       "title-invalid-empty": "Traženo ime stranice je prazno ili sadrži samo naziv imenskog prostora.",
+       "title-invalid-utf8": "Traženi naziv stranice sadrži nevažeći UTF-8 znak.",
+       "title-invalid-interwiki": "Traženi naslov stranice sadrži unutrašnju viki vezu koja ne može biti korištena u naslovima.",
+       "title-invalid-talk-namespace": "Traženi naslov stranice se odnosi na stranicu za razgovor koja ne može postojati.",
+       "title-invalid-characters": "Traženi naslov ima nevažeće znakove: „$1“.",
+       "title-invalid-relative": "Naslov ima relativnu putanju. Relativni naslovi stranica (./, ../) nisu važeći jer će često biti nedostupni u korisničkom pregledaču.",
+       "title-invalid-magic-tilde": "Traženi naslov stranice sadrži nevažeći sled magičnog znaka tilda (<nowiki>~~~</nowiki>).",
+       "title-invalid-too-long": "Traženi naziv stranice je predugačak. Ne sme biti duži od $1 {{PLURAL:$1|bajta|bajtova}} u UTF-8 kodiranju.",
+       "title-invalid-leading-colon": "Zahtevani naslov stranice sadrži nevažeću dvotačku na početku.",
        "perfcached": "Sledeći podaci su keširani i možda nisu ažurirani. U kešu {{PLURAL:$1|je dostupan najviše jedan rezultat|su dostupna najviše $1 rezultata|je dostupno najviše $1 rezultata}}.",
        "perfcachedts": "Sledeći podaci su keširani i poslednji put ažurirani na datum $2 u $3 č. U kešu {{PLURAL:$4|je dostupan najviše jedan rezultat|su dostupna najviše $4 rezultata|je dostupno najviše $4 rezultata}}.",
        "querypage-no-updates": "Ažuriranje ove stranice je trenutno onemogućeno.\nPodaci koji se ovde nalaze mogu biti zastareli.",
        "viewsource": "Izvorni kod",
-       "viewsource-title": "Izvorni tekst stranice $1",
+       "viewsource-title": "Izvorni kod za stranicu $1",
        "actionthrottled": "Radnja je usporena",
-       "actionthrottledtext": "Kao meru protiv zloupotrebe, ograničeno vam je izvođenje ove radnje previše puta u kratkom vremenskom periodu, a vi ste premašili ovo ograničenje.\nMolimo pokušajte ponovo za nekoliko minuta.",
+       "actionthrottledtext": "U cilju borbe protiv nepoželjnih poruka, ograničene su vam izmene u određenom vremenu, a upravo ste prešli to ograničenje. Pokušajte ponovo za nekoliko minuta.",
        "protectedpagetext": "Ova stranica je zaključana za izmene i druge radnje.",
-       "viewsourcetext": "Možete čitati i kopirati izvornik ove stranice.",
-       "viewyourtext": "Možete da pogledate i kopirate izvorni tekst <strong>vaših izmena</strong> na ovoj stranici.",
+       "viewsourcetext": "Možete da čitate i kopirate izvornik ove stranice.",
+       "viewyourtext": "Možete da pogledate i kopirate izvorni kod <strong>Vaših izmena</strong> na ovoj stranici.",
        "protectedinterface": "Ova stranica sadrži tekst interfejsa za softver na ovom vikiju i zaštićena je radi sprečavanja zloupotrebe.\nDa biste dodali ili izmenili prevode bilo kojeg vikija, posetite [https://translatewiki.net/ translatewiki.net], projekat za lokalizaciju Medijavikija.",
        "editinginterface": "<strong>Upozorenje:</strong> uređujete stranicu koja se koristi za prikazivanje teksta korisničkog okruženja.\nIzmene na ovoj stranici će uticati na sve korisnike ovog vikija.",
        "translateinterface": "Da dodate ili promenite prevode za sve vikije, posetite [https://translatewiki.net/ Translejtviki], projekat za lokalizaciju Medijavikija.",
        "cascadeprotected": "Ova stranica je zaključana jer sadrži {{PLURAL:$1|sledeću stranicu koja je zaštićena|sledeće stranice koje su zaštićene}} „prenosivom“ zaštitom:\n$2",
-       "namespaceprotected": "Nemate dozvolu da uređujete stranice u imenskom prostoru <strong>$1</strong>.",
+       "namespaceprotected": "Nemate dozvolu da uređujete stranice u imenskom prostoru: <strong>$1</strong>.",
        "customcssprotected": "Nemate dozvolu da menjate ovu CSS stranicu jer sadrži lična podešavanja drugog korisnika.",
-       "customjsprotected": "Nemate dozvolu da menjate ovu stranicu javaskripta jer sadrži lične postavke drugog korisnika.",
+       "customjsprotected": "Nemate dozvolu da menjate ovu stranicu JavaScript jer sadrži lična podešavanja drugog korisnika.",
        "mycustomcssprotected": "Nemate dozvolu za menjanje ove CSS stranice.",
+       "mycustomjsonprotected": "Nemate dozvolu za menjanje ove JSON stranice.",
        "mycustomjsprotected": "Nemate dozvolu za menjanje ove JavaScript stranice.",
        "myprivateinfoprotected": "Nemate dozvolu za menjanje vaših ličnih informacija.",
        "mypreferencesprotected": "Nemate dozvolu za menjanje vaših podešavanja.",
        "exception-nologin": "Niste prijavljeni",
        "exception-nologin-text": "Prijavite se da biste pristupili ovoj stranici ili radnji.",
        "exception-nologin-text-manual": "Morate biti $1 da biste pristupili ovoj stranici ili radnji.",
-       "virus-badscanner": "Neispravna postavka: nepoznati skener za viruse: ''$1''",
+       "virus-badscanner": "Neispravno podešavanje: nepoznati skener za viruse: <em>$1</em>",
        "virus-scanfailed": "neuspešno skeniranje (kod $1)",
        "virus-unknownscanner": "nepoznati antivirus:",
-       "logouttext": "<strong>Odjavljeni ste.</strong>\n\nImajte na umu da neke stranice mogu nastaviti da se prikazuju kao da ste još prijavljeni, sve dok ne očistite privremenu memoriju svog pregledača.",
-       "welcomeuser": "Dobrodošli, $1!",
+       "logouttext": "<strong>Sada ste odjavljeni.</strong>\n\nZapamtite da neke stranice mogu da nastave da se prikazuju kao da ste još uvek prijavljeni, dok ne očistite privremenu memoriju svog pregledača.",
+       "cannotlogoutnow-title": "Odjava trenutno nije moguća",
+       "cannotlogoutnow-text": "Odjava nije moguća tokom upotrebe $1.",
+       "welcomeuser": "Dobro došli, $1!",
        "welcomecreation-msg": "Vaš nalog je otvoren.\nNe zaboravite da promenite svoja [[Special:Preferences|podešavanja]].",
        "yourname": "Korisničko ime:",
        "userlogin-yourname": "Korisničko ime",
        "userlogin-yourpassword": "Lozinka",
        "userlogin-yourpassword-ph": "Unesite svoju lozinku",
        "createacct-yourpassword-ph": "Unesite lozinku",
-       "yourpasswordagain": "Potvrda lozinke:",
+       "yourpasswordagain": "Ponovo unesi lozinku:",
        "createacct-yourpasswordagain": "Potvrdite lozinku",
-       "createacct-yourpasswordagain-ph": "Unesite lozinku još jednom",
+       "createacct-yourpasswordagain-ph": "Unesite lozinku ponovo",
        "userlogin-remembermypassword": "Ostavi me prijavljenog/u",
        "userlogin-signwithsecure": "Koristite sigurnu konekciju",
+       "cannotlogin-title": "Prijava nije moguća",
+       "cannotlogin-text": "Prijava nije moguća",
+       "cannotloginnow-title": "Prijava trenutno nije moguća",
+       "cannotloginnow-text": "Prijava nije moguća kada se koristi $1.",
+       "cannotcreateaccount-title": "Otvaranje naloga nije moguće",
+       "cannotcreateaccount-text": "Direktno pravljenje naloga nije omogućeno na ovom vikiju.",
        "yourdomainname": "Domen:",
        "password-change-forbidden": "Ne možete da promenite lozinku na ovom vikiju.",
        "externaldberror": "Došlo je do greške pri prepoznavanju baze podataka ili nemate ovlašćenja da ažurirate svoj spoljni nalog.",
        "login": "Prijavi me",
-       "login-security": "Verifikacija vašeg identiteta",
+       "login-security": "Verifikacija vašeg indentiteta",
        "nav-login-createaccount": "Prijava/registracija",
        "logout": "Odjava",
        "userlogout": "Odjava",
        "notloggedin": "Niste prijavljeni",
        "userlogin-noaccount": "Nemate nalog?",
-       "userlogin-joinproject": "Otvorite ga",
+       "userlogin-joinproject": "Pridružite se projektu {{SITENAME}}",
        "createaccount": "Otvori nalog",
        "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 bi verifikovali da ste {{GENDER:$1|$1}}.",
        "userlogin-createanother": "Otvori još jedan nalog",
        "createacct-emailrequired": "Imejl adresa",
-       "createacct-emailoptional": "Imejl adresa (opciono)",
-       "createacct-email-ph": "Unesite Vašu imejl adresu",
+       "createacct-emailoptional": "Imejl adresa (neobavezno)",
+       "createacct-email-ph": "Unesite svoju imejl adresu",
        "createacct-another-email-ph": "Unesite imejl adresu",
-       "createaccountmail": "Koristite privremenu, slučajno stvorenu lozinku i pošaljite na navedenu adresu elektronske pošte",
-       "createacct-realname": "Pravo ime (opciono)",
+       "createaccountmail": "Koristite privremenu, slučajno stvorenu lozinku i pošaljite na navedenu imejl adresu",
+       "createaccountmail-help": "Može se koristiti da se nekome napravi nalog bez saznanja lozinke.",
+       "createacct-realname": "Pravo ime (neobavezno)",
        "createacct-reason": "Razlog",
        "createacct-reason-ph": "Zašto pravite još jedan nalog?",
+       "createacct-reason-help": "Poruka koja se prikazuje u dnevniku stvaranja korisničkih naloga",
        "createacct-submit": "Otvori nalog",
        "createacct-another-submit": "Otvori nalog",
+       "createacct-continue-submit": "Nastavite otvaranje naloga",
+       "createacct-another-continue-submit": "Nastavite otvaranje naloga",
        "createacct-benefit-heading": "{{SITENAME}} je projekat koji stvaraju ljudi poput Vas.",
-       "createacct-benefit-body1": "{{PLURAL:$1|izmena|izmene}}",
-       "createacct-benefit-body2": "{{PLURAL:$1|stranica|stranice}}",
-       "createacct-benefit-body3": "{{PLURAL:$1|aktivni korisnik|aktivnih korisnika}}",
+       "createacct-benefit-body1": "{{PLURAL:$1|izmena|izmene|izmena}}",
+       "createacct-benefit-body2": "{{PLURAL:$1|stranica|stranice|stranica}}",
+       "createacct-benefit-body3": "nedavno {{PLURAL:$1|aktivni korisnik|aktivna korisnika|aktivnih korisnika}}",
        "badretype": "Unete lozinke se ne poklapaju.",
-       "usernameinprogress": "Nalog za ovo korisničko ime se već pravi, molimo sačekajte.",
+       "usernameinprogress": "Nalog za ovo korisničko ime se već pravi, sačekajte.",
        "userexists": "Korisničko ime je zauzeto. Izaberite drugo.",
        "loginerror": "Greška pri prijavljivanju",
        "createacct-error": "Došlo je do greške pri otvaranju naloga",
-       "createaccounterror": "Ne mogu da otvorim nalog: $1",
+       "createaccounterror": "Ne mogu da otvorim nalog: $1.",
        "nocookiesnew": "Korisnički nalog je otvoren, ali niste prijavljeni.\n{{SITENAME}} koristi kolačiće za prijavu. Vama su kolačići onemogućeni.\nOmogućite ih, pa se onda prijavite sa svojim korisničkim imenom i lozinkom.",
        "nocookieslogin": "{{SITENAME}} koristi kolačiće za prijavljivanje korisnika.\nVama su kolačići onemogućeni. Omogućite ih i pokušajte ponovo.",
        "nocookiesfornew": "Korisnički nalog nije otvoren jer njegov izvor nije potvrđen.\nOmogućite kolačiće na pregledaču i ponovo učitajte stranicu.",
        "nocookiesforlogin": "{{int:nocookieslogin}}",
+       "createacct-loginerror": "Nalog je uspešno napravljen, ali se ne možete automatski prijaviti. Pređite na [[Special:UserLogin|ručno prijavljivanje]].",
        "noname": "Uneli ste neispravno korisničko ime.",
        "loginsuccesstitle": "Uspešno prijavljivanje",
-       "loginsuccess": "'''Prijavljeni ste kao „$1“.'''",
+       "loginsuccess": "<strong>Prijavljeni ste na {{SITENAME}} kao „$1”.</strong>",
        "nosuchuser": "Ne postoji korisnik s imenom „$1“.\nKorisnička imena su osetljiva na mala i velika slova.\nProverite da li ste ga dobro uneli ili [[Special:CreateAccount|otvorite novi nalog]].",
        "nosuchusershort": "Korisnik s imenom „$1“ ne postoji.\nProverite da li ste pravilno napisali.",
        "nouserspecified": "Morate navesti korisničko ime.",
        "login-userblocked": "{{GENDER:$1|Ovaj korisnik je blokiran|Ova korisnica je blokirana|Ovaj korisnik je blokiran}}. Prijava nije dozvoljena.",
-       "wrongpassword": "Uneli ste neispravnu lozinku. Pokušajte ponovo.",
+       "wrongpassword": "Uneli ste neispravno korisničko ime ili lozinku. Pokušajte ponovo.",
        "wrongpasswordempty": "Niste uneli lozinku. Pokušajte ponovo.",
        "passwordtooshort": "Lozinka mora imati najmanje {{PLURAL:$1|jedan znak|$1 znaka|$1 znakova}}.",
        "passwordtoolong": "Lozinke ne mogu biti duže od {{PLURAL:$1|$1 znaka|$1 znakova}}.",
+       "passwordtoopopular": "Često izabrane lozinke ne mogu da se koriste. Izaberite lozinku koju je teže pogoditi.",
        "password-name-match": "Lozinka se mora razlikovati od korisničkog imena.",
        "password-login-forbidden": "Korišćenje ovog korisničkog imena i lozinke je zabranjeno.",
        "mailmypassword": "Resetuj lozinku",
        "passwordremindertitle": "{{SITENAME}} — privremena lozinka",
-       "passwordremindertext": "Neko, verovatno vi, sa IP adrese $1 je zatražio novu lozinku na vikiju {{SITENAME}} ($4).\nStvorena je privremena lozinka za {{GENDER:$2|korisnika|korisnicu|korisnika}} $2 koja glasi $3.\nUkoliko je ovo vaš zahtev, sada se prijavite i postavite novu lozinku.\nPrivremena lozinka ističe za {{PLURAL:$5|jedan dan|$5 dana|$5 dana}}.\n\nAko je neko drugi zatražio promenu lozinke, ili ste se setili vaše lozinke i ne želite da je menjate, zanemarite ovu poruku.",
+       "passwordremindertext": "Neko sa IP adrese $1 je zatražio novu lozinku na vikiju {{SITENAME}} ($4).\nStvorena je privremena lozinka za {{GENDER:$2|korisnika|korisnicu|korisnika}} $2 koja glasi $3.\nUkoliko je ovo vaš zahtev, sada se prijavite i postavite novu lozinku.\nPrivremena lozinka ističe za {{PLURAL:$5|jedan dan|$5 dana}}.\n\nAko je neko drugi zatražio promenu lozinke, ili ste se setili vaše lozinke i ne želite da je menjate, zanemarite ovu poruku.",
        "noemail": "Ne postoji imejl adresa za {{GENDER:$1|korisnika|korisnicu}} $1.",
        "noemailcreate": "Morate navesti ispravnu imejl adresu.",
        "passwordsent": "Nova lozinka je poslata na imejl adresu {{GENDER:$1|korisnika|korisnice|korisnika}} $1.\nPrijavite se pošto je primite.",
-       "blocked-mailpassword": "Vašoj IP adresi je onemogućeno uređivanje stranica, kao i mogućnost zahtevanja nove lozinke.",
-       "eauthentsent": "Na navedenu imejl adresu je poslat potvrdni kod.\nPre nego što pošaljemo daljnje poruke, pratite uputstva s imejla da biste potvrdili da ste Vi otvorili nalog.",
+       "blocked-mailpassword": "Vaša IP adresa ima zabranu uređivanja. Radi sprečavanja zloupotrebe, nije dozvoljeno vraćanje lozinke sa nje.",
+       "eauthentsent": "Na navedenu imejl adresu je poslat potvrdni kôd.\nPre nego što pošaljemo daljnje poruke, pratite uputstva s imejla da biste potvrdili da ste Vi otvorili nalog.",
        "throttled-mailpassword": "Poruka za promenu lozinke je poslata u {{PLURAL:$1|1=poslednjih sat vremena|poslednja $1 sata|poslednjih $1 sati}}.\nDa bismo sprečili zloupotrebu, podsetnik šaljemo samo jednom u roku od {{PLURAL:$1|1=sat vremena|$1 sata|$1 sati}}.",
        "mailerror": "Greška pri slanju poruke: $1",
        "acct_creation_throttle_hit": "Posetioci ovog vikija koji koriste vašu IP adresu su već otvorili {{PLURAL:$1|1=jedan nalog|$1 naloga}} prethodni $2, što je najveći dozvoljeni broj u tom vremenskom periodu.\nZbog toga posetioci s ove IP adrese trenutno ne mogu otvoriti više naloga.",
-       "emailauthenticated": "Vaša imejl adresa je potvrđena $2 u $3.",
-       "emailnotauthenticated": "Vaša imejl adresa još nije potvrđena.\nImejl neće biti poslat ni u jednom od sledećih slučajeva.",
-       "noemailprefs": "Unesite imejl adresu kako bi ove mogućnosti radile.",
+       "emailauthenticated": "Vaša imejl adresa je potvrđena na dan $2 u $3.",
+       "emailnotauthenticated": "Vaša imejl adresa još uvek nije potvrđena.\nImejl neće biti poslat ni u jednom od sledećih slučajeva.",
+       "noemailprefs": "Navedite imejl adresu u svojim podešavanjima za rad ovih mogućnosti.",
        "emailconfirmlink": "Potvrdite svoju imejl adresu",
        "invalidemailaddress": "Imejl adresa ne može biti prihvaćena jer je neispravnog oblika.\nUnesite ispravnu adresu ili ostavite prazno polje.",
        "cannotchangeemail": "Na ovom vikiju ne možete promeniti imejl adresu naloga.",
        "accountcreatedtext": "Korisnički nalog [[{{ns:User}}:$1|$1]] ([[{{ns:User talk}}:$1|talk]]) je otvoren.",
        "createaccount-title": "Otvaranje korisničkog naloga za {{SITENAME}}",
        "createaccount-text": "Neko je otvorio nalog s vašom imejl adresom na {{SITENAME}} ($4) pod imenom $2 i lozinkom $3.\nPrijavite se i promenite svoju lozinku.\n\nAko je ovo greška, zanemarite ovu poruku.",
-       "login-throttled": "Previše puta ste pokušali da se prijavite. \nMolimo vas da sačekate $1 pre nego što pokušate ponovo.",
+       "login-throttled": "Previše puta ste pokušali da se prijavite.\nMolimo vas da sačekate $1 pre nego što pokušate ponovo.",
        "login-abort-generic": "Neuspešna prijava – prekinuto",
        "login-migrated-generic": "Vaš nalog je migriran i vaše korisničko više ne postoji na ovom vikiju.",
        "loginlanguagelabel": "Jezik: $1",
        "pt-userlogout": "Odjavi me",
        "php-mail-error-unknown": "Nepoznata greška u funkciji PHP mail().",
        "user-mail-no-addy": "Pokušali ste da pošaljete imejl bez imejl adrese.",
-       "user-mail-no-body": "Pokušano slanje elektronske poruke s praznim ili nerazumno kratkim sadržajem.",
+       "user-mail-no-body": "Pokušano slanje imejla s praznim ili nerazumno kratkim sadržajem.",
        "changepassword": "Promeni lozinku",
        "resetpass_announce": "Da biste završili prijavu, podesite novu lozinku ovde.",
        "resetpass_text": "<!-- Ovde unesite tekst -->",
        "newpassword": "Nova lozinka:",
        "retypenew": "Potvrda lozinke:",
        "resetpass_submit": "Postavi lozinku i prijavi me",
-       "changepassword-success": "Vaša lozinka je promenjena.",
+       "changepassword-success": "Vaša lozinka je uspešno promenjena!",
        "changepassword-throttled": "Previše puta ste pokušali da se prijavite.\nMolimo vas da sačekate $1 pre nego što pokušate ponovo.",
        "botpasswords": "Lozinke botova",
+       "botpasswords-disabled": "Lozinke botova su onemogućene.",
+       "botpasswords-no-central-id": "Da bi ste koristili botovske lozinke, morate biti prijavljeni na središnji nalog.",
+       "botpasswords-existing": "Postojeća lozinka bota",
+       "botpasswords-createnew": "Napravi novu lozinku za bota",
+       "botpasswords-editexisting": "Izmeni postojeću lozinku za bota",
+       "botpasswords-label-needsreset": "(lozinku treba resetovati)",
        "botpasswords-label-appid": "Ime bota:",
        "botpasswords-label-create": "Napravi",
        "botpasswords-label-update": "Ažuriraj",
        "botpasswords-label-cancel": "Otkaži",
        "botpasswords-label-delete": "Obriši",
+       "botpasswords-label-resetpassword": "Resetuj lozinku",
+       "botpasswords-label-grants": "Primenljive dozvole:",
        "botpasswords-label-grants-column": "Odobreno",
+       "botpasswords-bad-appid": "„$1” nije validan naziv bota.",
+       "botpasswords-insert-failed": "Neuspešno dodavanje bota \"$1\". Da li je već dodat?",
+       "botpasswords-update-failed": "Nije moguće ažurirati bota \"$1\". Da li je obrisan?",
+       "botpasswords-created-title": "Napravljena lozinka bota",
+       "botpasswords-created-body": "Lozinka za bota „$1” korisnika „$2” je napravljena.",
+       "botpasswords-updated-title": "Lozinka bota promenjena",
+       "botpasswords-updated-body": "Lozinka za bota „$1” korisnika „$2” je ažurirana.",
+       "botpasswords-deleted-title": "Obrisana lozinka bota",
+       "botpasswords-deleted-body": "Lozinka za bota „$1” korisnika „$2” je obrisana.",
+       "botpasswords-no-provider": "BotPasswordsSessionProvider nije dostupan.",
+       "botpasswords-restriction-failed": "Ne možete se prijaviti zbog ograničenja lozinki za botove.",
+       "botpasswords-not-exist": "Korisnik „$1“ nema lozinku bota „$2“.",
        "resetpass_forbidden": "Lozinka ne može biti promenjena",
+       "resetpass_forbidden-reason": "Lozinke nije moguće promeniti: $1",
        "resetpass-no-info": "Morate biti prijavljeni da biste pristupili ovoj stranici.",
        "resetpass-submit-loggedin": "Promeni lozinku",
        "resetpass-submit-cancel": "Otkaži",
-       "resetpass-wrong-oldpass": "Neispravna privremena ili tekuća lozinka.\nMožda ste već promenili lozinku ili ste zatražili novu privremenu lozinku.",
-       "resetpass-recycled": "Uneli ste sadašnju lozinku, da biste resetovali lozinku morate uneti novu.",
-       "resetpass-temp-emailed": "Prijavili ste se sa privremenim kodom iz imejla.\nDa biste završili prijavljivanje morate postaviti novu lozinku ovde:",
+       "resetpass-wrong-oldpass": "Neispravna privremena ili trenutna lozinka.\nMožda ste već promenili lozinku ili ste zatražili novu privremenu lozinku.",
+       "resetpass-recycled": "Uneli ste sadašnju lozinku, da biste promenili lozinku morate uneti novu.",
+       "resetpass-temp-emailed": "Prijavili ste se sa privremenim kôdom iz imejla.\nDa biste završili prijavljivanje morate postaviti novu lozinku ovde:",
        "resetpass-temp-password": "Privremena lozinka:",
        "resetpass-abort-generic": "Promenu lozinke je sprečio dodatak.",
        "resetpass-expired": "Vaša lozinka je istekla. Postavite novu lozinku da biste se prijavili.",
-       "resetpass-expired-soft": "Vaša lozinka je istekla i morate postaviti novu. Postavite novu lozinku ili kliknite „{{int:authprovider-resetpass-skip-label}}“ da je postavite kasnije.",
-       "resetpass-validity-soft": "Vaša lozinka nije valjana: $1\n\nMolimo izaberite novu ili kliknite „{{int:authprovider-resetpass-skip-label}}“ da resetujete kasnije.",
+       "resetpass-expired-soft": "Vaša lozinka je istekla i morate je promeniti. Postavite novu lozinku ili kliknite „{{int:authprovider-resetpass-skip-label}}“ da je promenite kasnije.",
+       "resetpass-validity-soft": "Vaša lozinka nije ispravna: $1\n\nMolimo izaberite novu ili kliknite „{{int:authprovider-resetpass-skip-label}}“ da je promenite kasnije.",
        "passwordreset": "Obnavljanje lozinke",
        "passwordreset-text-one": "Popunite ovaj obrazac da biste dobili privremenu lozinku na imejl.",
        "passwordreset-text-many": "{{PLURAL:$1|Ispunite jedno od polja kako biste dobili privremenu lozinku na imejl.}}",
        "passwordreset-emailtext-ip": "Neko (verovatno Vi, sa IP adrese $1) je zatražio novu lozinku na vikiju {{SITENAME}} ($4).\nSledeći {{PLURAL:$3|korisnički nalog je povezan|korisnički nalozi su povezani}} s ovom imejl adresom:\n\n$2\n\n{{PLURAL:$3|Privremena lozinka ističe|Privremene lozinke ističu}} za {{PLURAL:$5|jedan dan|$5 dana}}.\nPrijavite se i izaberite novu lozinku. Ako je neko drugi zahtevao ovu radnju ili ste se setili lozinke i ne želite da je menjate, zanemarite ovu poruku i nastavite koristiti staru lozinku.",
        "passwordreset-emailtext-user": "{{GENDER:$1|Korisnik je zatražio|Korisnica je zatražila}} podsetnik o podacima za prijavu na vikiju {{SITENAME}} ($4).\nSledeći {{PLURAL:$3|korisnički nalog je povezan|korisnički nalozi su povezani}} s ovom imejl adresom:\n\n$2\n\n{{PLURAL:$3|Privremena lozinka ističe|Privremene lozinke ističu}} za {{PLURAL:$5|jedan dan|$5 dana}}.\nPrijavite se i izaberite novu lozinku. Ako je neko drugi zahtevao ovu radnju ili ste se setili lozinke i ne želite da je menjate, zanemarite ovu poruku.",
        "passwordreset-emailelement": "Korisničko ime: \n$1\n\nPrivremena lozinka: \n$2",
-       "passwordreset-emailsentemail": "Podsetnik o lozinci je poslat na vašu adresu.",
+       "passwordreset-emailsentemail": "Ako je ovo imejl adresa povezana sa Vašim nalogom, podsetnik o lozinci će biti poslat na imejl.",
        "passwordreset-emailsentusername": "Ako ste naveli imejl adresu prilikom registracije, biće poslat imejl za resetovanje lozinke.",
-       "changeemail": "Promeni ili ukloni imejl adresu",
-       "changeemail-header": "Promenite e-adresu naloga",
+       "passwordreset-nocaller": "Pozivalac se mora navesti",
+       "passwordreset-nosuchcaller": "Pozivalac ne postoji: $1",
+       "passwordreset-ignored": "Resetovanje lozinke nije uspelo. Možda poslužilac nije konfigurisan?",
+       "passwordreset-invalidemail": "Neispravna imejl adresa",
+       "passwordreset-nodata": "Korisničko ime i adresa e-pošte nisu navedeni",
+       "changeemail": "Promena ili uklanjanje imejl adrese",
+       "changeemail-header": "Popunite ovaj obrazac da bi ste promenili Vašu imejl adresu. Ako želi da uskratite pristup bilo kojoj imejl adresi Vašem nalogu, ostavite prazno polje za novu imejl adresu prilikom popunjavanje obrasca.",
        "changeemail-no-info": "Morate biti prijavljeni da biste pristupili ovoj stranici.",
        "changeemail-oldemail": "Trenutna imejl adresa:",
        "changeemail-newemail": "Nova imejl adresa:",
        "changeemail-throttled": "Previše puta ste pokušali da se prijavite.\nMolimo vas da sačekate $1 pre nego što pokušate ponovo.",
        "changeemail-nochange": "Unesite drugu imejl adresu.",
        "resettokens": "Resetovanje žetona",
+       "resettokens-text": "Možete ponovo postaviti žetone koji će vam omogućiti pristup određenim privatnim podacima povezanim sa vašim nalogom ovde.\n\nTrebali biste to da uradite ako ih mimo volje podelite s nekim ili ako je vaš nalog ugrožen.",
        "resettokens-no-tokens": "Nema žetona za resetovanje.",
        "resettokens-tokens": "Žetoni:",
        "resettokens-token-label": "$1 (trenutna vrednost: $2)",
-       "resettokens-watchlist-token": "Žeton za veb dovod (Atom/RSS) vašeg [[Special:Watchlist|spiska nadgledanja]]",
+       "resettokens-watchlist-token": "Žeton za veb dovod (Atom/RSS) [[Special:Watchlist|izmena na stranicama u vašem spisku nadgledanja]]",
        "resettokens-done": "Žetoni su resetovani",
        "resettokens-resetbutton": "Resetuj izabrane žetone",
        "bold_sample": "Podebljan tekst",
        "bold_tip": "Podebljan tekst",
-       "italic_sample": "Iskošeni tekst",
-       "italic_tip": "Iskošeni tekst",
+       "italic_sample": "Iskošen tekst",
+       "italic_tip": "Iskošen tekst",
        "link_sample": "Naslov veze",
        "link_tip": "Unutrašnja veza",
-       "extlink_sample": "http://www.primer.com naslov veze",
-       "extlink_tip": "Spoljna veza (s predmetkom http://)",
-       "headline_sample": "Naslov",
-       "headline_tip": "Podnaslov",
+       "extlink_sample": "http://www.example.com/ naslov veze",
+       "extlink_tip": "Spoljašnja veza (s prefiksom http://)",
+       "headline_sample": "Tekst naslova",
+       "headline_tip": "Podnaslov (nivo 2)",
        "nowiki_sample": "Ubacite neoblikovan tekst ovde",
        "nowiki_tip": "Zanemari viki oblikovanje",
        "image_sample": "Primer.jpg",
-       "image_tip": "Ugrađena datoteka",
+       "image_tip": "Ugrađivanje datoteke",
        "media_sample": "Primer.ogg",
        "media_tip": "Veza",
        "sig_tip": "Vaš potpis sa trenutnim vremenom",
-       "hr_tip": "Vodoravna linija (koristiti retko)",
+       "hr_tip": "Vodoravna linija (koristite retko)",
        "summary": "Opis izmene:",
        "subject": "Tema:",
        "minoredit": "Ovo je manja izmena",
        "savechanges": "Sačuvaj izmene",
        "publishpage": "Objavi stranicu",
        "publishchanges": "Objavi izmene",
+       "savearticle-start": "Sačuvaj stranicu...",
+       "savechanges-start": "Sačuvaj izmene...",
+       "publishpage-start": "Objavi stranicu...",
+       "publishchanges-start": "Objavi izmene...",
        "preview": "Pretpregled",
        "showpreview": "Prikaži pretpregled",
        "showdiff": "Prikaži izmene",
        "blankarticle": "<strong>Upozorenje:</strong> Stranica koju pravite je prazna.\nAko još jednom pritisnete „$1”, stranica će biti napravljena bez ikakvog sadržaja.",
        "anoneditwarning": "<strong>Upozorenje:</strong> Niste prijavljeni. Ako objavite stranicu, Vaša IP adresa će biti javno vidljiva u njenoj istoriji izmena i drugde. Ako se <strong>[$1 prijavite]</strong> ili <strong>[$2 otvorite nalog]</strong>, pored ostalih pogodnosti koje dobijate Vaše izmene će biti pripisivane Vašem korisničkom imenu.",
        "anonpreviewwarning": "<em>Niste prijavljeni. Ako objavite stranicu, Vaša IP adresa će biti javno vidljiva u njenoj istoriji izmena i drugde.</em>",
-       "missingsummary": "'''Podsetnik:''' Niste uneli opis izmene.\nAko ponovo kliknete na „$1”, Vaša izmena će biti sačuvana bez opisa.",
+       "missingsummary": "<strong>Podsetnik:</strong> Niste uneli opis izmene.\nAko ponovo kliknete na „$1”, Vaša izmena će biti sačuvana bez opisa.",
        "selfredirect": "<strong>Upozorenje:</strong> Preusmeravate ovu stranicu na nju samu.\nMožda vam je odredišna stranica za preusmerenje pogrešna ili uređujete pogrešnu stranicu.\nAko još jednom pritisnete „$1”, preusmerenje će svejedno biti napravljeno.",
-       "missingcommenttext": "Unesite komentar ispod.",
+       "missingcommenttext": "Molimo unesite komentar.",
        "missingcommentheader": "<strong>Napomena:</strong> Niste uneli naslov teme ovog komentara.\nAko ponovo kliknete na „$1”, izmena će biti sačuvana bez naslova.",
-       "summary-preview": "Pregled opisa:",
-       "subject-preview": "Pregled tema:",
+       "summary-preview": "Pregled opisa izmene:",
+       "subject-preview": "Pregled teme:",
+       "previewerrortext": "Dogodila se greška prilikom prikazivanja vaših izmena.",
        "blockedtitle": "Korisnik je blokiran",
-       "blockedtext": "<strong>Vaše korisničko ime ili IP adresa je blokirana.</strong>\n\nBlokiranje je {{GENDER:$4|izvršio|izvršila}} $1.\nRazlog je <em>$2</em>.\n\n* Datum blokiranja: $8\n* Blokiranje ističe: $6\n* Ime korisnika: $7\n\nObratite se {{GENDER:$4|korisniku|korisnici}} $1 ili [[{{MediaWiki:Grouppage-sysop}}|administratoru]] da razjasnite stvar.\nNe možete koristiti mogućnost „Pošalji imejl ovom korisniku“ ako niste uneli ispravnu imejl adresu u [[Special:Preferences|podešavanjima]].\nVaša blokirana IP adresa je $3, a ID blokiranja $5.\nNavedite sve podatke iznad pri stvaranju bilo kakvih upita.",
-       "autoblockedtext": "Vaša IP adresa je blokirana jer ju je upotrebljavao drugi korisnik, koga je {{GENDER:$4|blokirao|blokirala}} $1.\nRazlog:\n\n:<em>$2</em>\n\n* Datum blokiranja: $8\n* Blokiranje ističe: $6\n* Ime korisnika: $7\n\nObratite se {{GENDER:$4|korisniku|korisnici}} $1 ili [[{{MediaWiki:Grouppage-sysop}}|administratoru]] da razjasnite stvar.\n\nNe možete koristiti mogućnost „Pošalji imejl ovom korisniku“ ako niste uneli ispravnu imejl adresu u [[Special:Preferences|podešavanjima]].\n\nVaša blokirana IP adresa je $3, a ID $5.\nNavedite sve podatke iznad pri stvaranju bilo kakvih upita.",
+       "blockedtext": "<strong>Vaše korisničko ime ili IP adresa je blokirana.</strong>\n\nBlokiranje je {{GENDER:$4|izvršio|izvršila}} $1.\nRazlog je <em>$2</em>.\n\n* Početak blokiranja: $8\n* Istek blokiranja: $6\n* Blokirani: $7\n\nMožete da se obratite {{GENDER:$4|korisniku|korisnici}} $1 ili [[{{MediaWiki:Grouppage-sysop}}|administratoru]] radi diskusije o blokiranju.\nNe možete da koristite mogućnost „{{int:emailuser}}” osim ako ste uneli validnu imejl adresu u svojim [[Special:Preferences|podešavanjima]] naloga i niste blokirani od korišćenja iste.\nVaša trenutna IP adresa je $3, a ID blokiranja #$5.\nNavedite sve informacije odozgo pri stvaranju bilo kakvih upita.",
+       "autoblockedtext": "Vaša IP adresa je blokirana jer ju je upotrebljavao drugi korisnik, koga je {{GENDER:$4|blokirao|blokirala}} $1.\nRazlog:\n\n:<em>$2</em>\n\n* Datum blokiranja: $8\n* Blokiranje ističe: $6\n* Ime korisnika: $7\n\nObratite se {{GENDER:$4|korisniku|korisnici}} $1 ili [[{{MediaWiki:Grouppage-sysop}}|administratoru]] da razjasnite stvar.\n\nNe možete koristiti mogućnost „{{int:emailuser}}“ ako niste uneli ispravnu imejl adresu u [[Special:Preferences|podešavanjima]].\n\nVaša blokirana IP adresa je $3, a ID $5.\nNavedite sve podatke iznad pri stvaranju bilo kakvih upita.",
        "blockednoreason": "razlog nije naveden",
        "whitelistedittext": "Za uređivanje stranice je potrebno da budete $1.",
        "confirmedittext": "Morate da potvrdite svoju imejl adresu pre uređivanja stranica.\nPostavite i potvrdite imejl adresu preko [[Special:Preferences|podešavanja]].",
-       "nosuchsectiontitle": "Ne mogu da pronađem odeljak",
+       "nosuchsectiontitle": "Ne mogu da pronađem odeljak.",
        "nosuchsectiontext": "Pokušali ste da uredite odeljak koji ne postoji.\nMožda je premešten ili obrisan dok ste pregledali stranicu.",
        "loginreqtitle": "Potrebna je prijava",
        "loginreqlink": "prijavljeni",
        "loginreqpagetext": "Morate biti $1 da biste videli druge stranice.",
        "accmailtitle": "Lozinka je poslata.",
-       "accmailtext": "Lozika za {{GENDER:$1|korisnika|korisnicu}} [[User talk:$1|$1]] je poslata na $2. Nakon prijave, lozinka se može promeniti [[Special:ChangePassword|ovde]].",
+       "accmailtext": "Lozinka za {{GENDER:$1|korisnika|korisnicu}} [[User talk:$1|$1]] je poslata na $2. Nakon prijave, lozinka se može promeniti [[Special:ChangePassword|ovde]].",
        "newarticle": "(novi)",
        "newarticletext": "Došli ste na stranicu koja još ne postoji.\nDa biste je napravili, počnite da kucate u prozor ispod ovog teksta (pogledajte [$1 stranicu za pomoć]).\nAko ste ovde došli greškom, vratite se na prethodnu stranicu.",
-       "anontalkpagetext": "---- Ovo je stranica za razgovor s anonimnim korisnikom koji još nema nalog ili ga ne koristi.\nZbog toga moramo da koristimo brojčanu IP adresu kako bismo ga prepoznali.\nTakvu adresu može deliti više korisnika.\nAko ste anonimni korisnik i mislite da su vam upućene primedbe, [[Special:CreateAccount|otvorite nalog]] ili se [[Special:UserLogin|prijavite]] da biste izbegli buduću zabunu s ostalim anonimnim korisnicima.",
-       "noarticletext": "Na ovoj stranici trenutno nema sadržaja.\nMožete [[Special:Search/{{PAGENAME}}|potražiti ovaj naslov]] na drugim stranicama,\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} pretražiti srodne izveštaje] ili [{{fullurl:{{FULLPAGENAME}}|action=edit}} napraviti ovu stranicu]</span>.",
-       "noarticletext-nopermission": "Na ovoj stranici trenutno nema sadržaja.\nMožete [[Special:Search/{{PAGENAME}}|potražiti ovaj naslov]] na drugim stranicama ili <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} pretražiti srodne dnevnike]</span>, ali nemate dozvolu da napravite ovu stranicu.",
+       "anontalkpagetext": "----\n<em>Ovo je stranica za razgovor s anonimnim korisnikom koji još nema nalog ili ga ne koristi.</em>\nZbog toga moramo da koristimo brojčanu IP adresu kako bismo ga prepoznali.\nTakvu adresu može deliti više korisnika.\nAko ste anonimni korisnik i mislite da su vam upućene primedbe, [[Special:CreateAccount|otvorite nalog]] ili se [[Special:UserLogin|prijavite]] da biste izbegli buduću zabunu s ostalim anonimnim korisnicima.",
+       "noarticletext": "Na ovoj stranici trenutno nema teksta.\nMožete [[Special:Search/{{PAGENAME}}|potražiti ovaj naslov]] na drugim stranicama,\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} pretražiti srodne izveštaje] ili [{{fullurl:{{FULLPAGENAME}}|action=edit}} napraviti ovu stranicu]</span>.",
+       "noarticletext-nopermission": "Na ovoj stranici trenutno nema teksta.\nMožete [[Special:Search/{{PAGENAME}}|potražiti ovaj naslov]] na drugim stranicama ili <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} pretražiti srodne dnevnike]</span>, ali nemate dozvolu da napravite ovu stranicu.",
        "missing-revision": "Ne mogu da pronađem izmenu br. $1 na stranici pod nazivom „{{FULLPAGENAME}}“.\n\nOvo se obično dešava kada pratite zastarelu vezu do stranice koja je obrisana.\nViše informacija možete pronaći u [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} dnevniku brisanja].",
        "userpage-userdoesnotexist": "Korisnički nalog „<nowiki>$1</nowiki>“ nije otvoren.\nRazmislite da li zaista želite da napravite/uredite ovu stranicu.",
        "userpage-userdoesnotexist-view": "Korisnički nalog „$1“ nije otvoren.",
        "blocked-notice-logextract": "Ovaj korisnik je trenutno blokiran.\nIzveštaj o poslednjem blokiranju možete pogledati ispod:",
-       "clearyourcache": "<strong>Napomena:</strong> nakon čuvanja, možda ćete morati da očistite keš pregledača kako biste videli promene.\n* <strong>Fajerfoks / Safari:</strong> držite <em>Shift</em> i kliknite na <em>Osveži</em>, ili pritisnite <em>Ctrl-F5</em> ili <em>Ctrl-R</em> (<em>⌘-R</em> na Meku)\n* <strong>Gugl kroum:</strong> pritisnite <em>Ctrl-Shift-R</em> (<em>⌘-Shift-R</em> na Meku)\n* <strong>Internet eksplorer:</strong> držite <em>Ctrl</em> i kliknite na <em>Osveži</em> ili pritisnite <em>Ctrl-F5</em>\n* <strong>Opera:</strong> idite na <em>Alatke → Podešavanja</em> (<em>Opera → Postavke</em> na Meku) i zatim <em>Privatnost i bezbednost → Očistite podatke o pregledima → Keširane slike i datoteke</em>.",
-       "usercssyoucanpreview": "'''Savet:''' korisitite dugme „{{int:showpreview}}“ da isprobate svoj novi CSS pre nego što ga sačuvate.",
-       "userjsyoucanpreview": "'''Savet:''' korisitite dugme „{{int:showpreview}}“ da isprobate svoj novi javaskript pre nego što ga sačuvate.",
-       "usercsspreview": "'''Ovo je samo pregled CSS-a.'''\n'''Stranica još nije sačuvana!'''",
-       "userjspreview": "'''Ovo je samo pregled javaskripta.'''\n'''Stranica još nije sačuvana!'''",
-       "sitecsspreview": "'''Ovo je samo pregled CSS-a.'''\n'''Stranica još nije sačuvana!'''",
-       "sitejspreview": "'''Ovo je samo pregled javaskripta.'''\n'''Stranica još nije sačuvana!'''",
-       "userinvalidconfigtitle": "<strong>Upozorenje:</strong> ne postoji tema „$1“.\nPrilagođene stranice CSS i javaskript počinju malim slovom, npr. {{ns:user}}:Foo/vector.css, a ne {{ns:user}}:Foo/Vector.css.",
-       "updated": "(Ažurirano)",
+       "clearyourcache": "<strong>Napomena:</strong> Nakon čuvanja, možda ćete morati da očistite keš pregledača kako biste videli izmene.\n* <strong>Fajerfoks / Safari:</strong> Držite <em>Shift</em> i kliknite na <em>Osveži</em> ili pritisnite <em>Ctrl-F5</em> ili <em>Ctrl-R</em> (<em>⌘-R</em> na Meku)\n* <strong>Gugl kroum:</strong> Pritisnite <em>Ctrl-Shift-R</em> (<em>⌘-Shift-R</em> na Meku)\n* <strong>Internet eksplorer:</strong> Držite <em>Ctrl</em> i kliknite na <em>Osveži</em> ili pritisnite <em>Ctrl-F5</em>\n* <strong>Opera:</strong> Idite na <em>Alatke → Podešavanja</em> (<em>Opera → Podešavanja</em> na Meku) i zatim <em>Privatnost i bezbednost → Očistite podatke o pregledima → Keširane slike i datoteke</em>.",
+       "usercssyoucanpreview": "<strong>Savet:<strong> korisitite dugme „{{int:showpreview}}“ da isprobate svoj novi CSS pre nego što ga sačuvate.",
+       "userjsyoucanpreview": "<strong>Savet:</strong> korisitite dugme „{{int:showpreview}}“ da isprobate svoj novi javaskript pre nego što ga sačuvate.",
+       "usercsspreview": "<strong>Ovo je samo pregled CSS-a.\nStranica još nije sačuvana!</strong>",
+       "userjspreview": "<strong>Ovo je samo pregled javaskripta.\nStranica još nije sačuvana!</strong>",
+       "sitecsspreview": "<strong>Ovo je samo pregled CSS-a.\nStranica još nije sačuvana!</strong>",
+       "sitejspreview": "<strong>Ovo je samo pregled javaskripta.\nStranica još nije sačuvana!</strong>",
+       "userinvalidconfigtitle": "<strong>Upozorenje:</strong> ne postoji tema „$1“.\nPrilagođene stranice CSS, JSON i Javaskript počinju malim slovom, npr. {{ns:user}}:Foo/vector.css, a ne {{ns:user}}:Foo/Vector.css.",
+       "updated": "(ažurirano)",
        "note": "<strong>Napomena:</strong>",
        "previewnote": "<strong>Ne zaboravite da je ovo samo pretpregled.</strong>\nVaše izmene još nisu sačuvane!",
        "continue-editing": "Idi na uređivački okvir",
-       "previewconflict": "Ovaj pregled oslikava kako će tekst u tekstualnom okviru izgledati.",
+       "previewconflict": "Ovaj pregled oslikava kako će izgledati tekst u tekstualnom okviru.",
        "session_fail_preview": "Izvinjavamo se! Nismo mogli da obradimo Vašu izmenu zbog gubitka podataka sesije.\n\nMožda ste odjavljeni. <strong>Proverite da li ste prijavljeni i pokušajte ponovo</strong>.\nAko i dalje ne radi, pokušajte da se [[Special:UserLogout|odjavite]] i ponovo prijavite, te proverite da li su na Vašem pretraživaču dozvoljeni kolačići sa ovog sajta.",
-       "session_fail_preview_html": "'''Nismo mogli da obradimo vašu izmenu zbog gubitka podataka sesije.'''\n\n''Budući da je na ovom vikiju omogućen unos HTML oznaka, pregled je sakriven kao mera predostrožnosti protiv napada preko javaskripta.''\n\n'''Ako ste pokušali da napravite pravu izmenu, pokušajte ponovo.\nAko i dalje ne radi, pokušajte da se [[Special:UserLogout|odjavite]] i ponovo prijavite.'''",
-       "token_suffix_mismatch": "'''Vaša izmena je odbačena jer je vaš pregledač ubacio znakove interpunkcije u novčić uređivanja.\nTo se ponekad događa kada se koristi neispravan posrednik.'''",
+       "session_fail_preview_html": "Nismo mogli da obradimo vašu izmenu zbog gubitka podataka sesije.\n\n<em>Budući da je na ovom vikiju omogućen unos HTML oznaka, pregled je sakriven kao mera predostrožnosti protiv napada preko javaskripta.</em>\n\n<strong>Ako ste pokušali da napravite pravu izmenu, pokušajte ponovo.<strong>\nAko i dalje ne radi, pokušajte da se [[Special:UserLogout|odjavite]] i ponovo prijavite i proverite da li Vaš pregledač dozvoljava kolačiće sa ovog sajta.",
+       "token_suffix_mismatch": "<strong>Vaša izmena je odbačena jer je vaš pregledač ubacio znakove interpunkcije u novčić uređivanja.</strong>\nTo se ponekad događa kada se koristi neispravan posrednik.",
        "edit_form_incomplete": "<strong>Neki delovi obrasca za uređivanje nisu stigli do servera. Proverite da li su vaše izmene nepromenjene i pokušajte ponovo.</strong>",
        "editing": "Uređujete $1",
        "creating": "Pravljenje stranice $1",
        "yourtext": "Vaš tekst",
        "storedversion": "Uskladištena izmena",
        "editingold": "<strong>Upozorenje: uređujete zastarelu izmenu ove stranice.</strong>\nAko je sačuvate, sve novije izmene će biti izgubljene.",
+       "unicode-support-fail": "Vaš pregledač ne podržava Unicode. On je neopohodan za uređivanje stranica, pa zato ne mogu sačuvati izmenu.",
        "yourdiff": "Razlike",
-       "copyrightwarning": "Imajte na umu da se svi doprinosi na ovom vikiju smatraju kao objavljeni pod licencom $2 (više na $1).\nAko ne želite da se vaši tekstovi menjaju i razmenjuju bez ograničenja, onda ih ne šaljite ovde.<br />\nIsto tako obećavate da ste vi autor teksta, ili da ste ga umnožili s izvora koji je u javnom vlasništvu.\n'''Ne šaljite radove zaštićene autorskim pravima bez dozvole!'''",
-       "copyrightwarning2": "Imajte na umu da se svi doprinosi na ovom vikiju mogu menjati, vraćati ili brisati od drugih korisnika.\nAko ne želite da se vaši tekstovi slobodno menjaju i raspodeljuju, ne šaljite ih ovde.<br />\nIsto tako obećavate da ste vi autor teksta, ili da ste ga umnožili s izvora koji je u javnom vlasništvu (više na $1).\n'''Ne šaljite radove zaštićene autorskim pravima 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.",
+       "copyrightwarning": "Imajte na umu da se svi doprinosi na ovom vikiju smatraju kao objavljeni pod licencom $2 (više na $1).\nAko ne želite da se vaši tekstovi menjaju i razmenjuju bez ograničenja, onda ih ne šaljite ovde.<br />\nIsto tako obećavate da ste Vi autor teksta, ili da ste ga umnožili s izvora koji je u javnom vlasništvu.\n<strong>Ne šaljite radove zaštićene autorskim pravima bez dozvole!</strong>",
+       "copyrightwarning2": "Imajte na umu da se svi doprinosi na ovom vikiju mogu menjati, vraćati ili brisati od drugih korisnika.\nAko ne želite da se vaši tekstovi slobodno menjaju i raspodeljuju, ne šaljite ih ovde.<br />\nIsto tako obećavate da ste vi autor teksta, ili da ste ga umnožili s izvora koji je u javnom vlasništvu (više na $1).\n<strong>Ne šaljite radove zaštićene autorskim pravima bez dozvole!</strong>",
+       "editpage-cannot-use-custom-model": "Model sadržaja ove stranice se ne može promeniti.",
+       "longpageerror": "<strong>Greška: tekst koji ste uneli je veličine {{PLURAL:$1|jedan kilobajt|$1 kilobajta}}, što je veće od {{PLURAL:$2|dozvoljenog jednog kilobajta|dozvoljena $2 kilobajta|dozvoljenih $2 kilobajta}}.</strong>\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\nSistemski administrator je naveo sledeće objašnjenje: $1",
        "protectedpagewarning": "<strong>Upozorenje: ova stranica je zaštićena, tako da samo administratori mogu da je menjaju.</strong>\nPoslednji zapis u dnevniku je prikazan ispod:",
-       "semiprotectedpagewarning": "<strong>Napomena:</strong> Ova stranica je zaštićena, tako da samo registrovani korisnici mogu da je uređuju.\nPoslednji zapis u dnevniku prikazan je ispod kao referenca:",
+       "semiprotectedpagewarning": "<strong>Napomena:</strong> ova stranica je zaštićena, tako da samo registrovani korisnici mogu da je uređuju.\nPoslednji zapis u dnevniku je prikazan ispod kao referenca:",
        "cascadeprotectedwarning": "<strong>Upozorenje:</strong> Ova stranica je zaštićena tako da je mogu uređivati samo korisnici sa [[Special:ListGroupRights|određenim pravima]] (administratori), jer je ista uključena u {{PLURAL:$1|sledeću stranicu koja je zaštićena|sledeće stranice koje su zaštićene}} „prenosivom” zaštitom:",
-       "titleprotectedwarning": "<strong>Upozorenje: ovu stranicu mogu napraviti samo korisnici [[Special:ListGroupRights|s određenim pravima]].</strong>\nIspod su navedeni poslednji zapisi u dnevniku:",
-       "templatesused": "{{PLURAL:$1|Šablon|Šabloni}} na ovoj stranici:",
-       "templatesusedpreview": "{{PLURAL:$1|Šablon|Šabloni}} u ovom pregledu:",
+       "titleprotectedwarning": "<strong>Upozorenje: ovu stranicu mogu napraviti samo korisnici [[Special:ListGroupRights|s određenim pravima]].</strong>\nPoslednji zapis u dnevniku je prikazan ispod:",
+       "templatesused": "{{PLURAL:$1|Šablon koji se koristi|Šabloni koji se koriste}} na ovoj stranici:",
+       "templatesusedpreview": "{{PLURAL:$1|Šablon|Šabloni}} u ovom pretpregledu:",
        "templatesusedsection": "{{PLURAL:$1|Šablon|Šabloni}} u ovom odeljku:",
        "template-protected": "(zaštićeno)",
        "template-semiprotected": "(poluzaštićeno)",
        "permissionserrors": "Greška u dozvoli",
        "permissionserrorstext": "Nemate ovlašćenje za ovu radnju iz {{PLURAL:$1|1=sledećeg|sledećih}} razloga:",
        "permissionserrorstext-withaction": "Nemate dozvolu za $2 iz {{PLURAL:$1|sledećeg|sledećih}} razloga:",
+       "contentmodelediterror": "Ne možete urediti ovu izmenu jer je njen model sadržaja <code>$1</code>, što se razlikuje od trenutnog modela sadržaja stranice <code>$2</code>.",
        "recreate-moveddeleted-warn": "<strong>Upozorenje: ponovo pravite stranicu koja je prethodno obrisana.</strong>\n\nRazmotrite da li je prikladno da nastavite s uređivanjem ove stranice.\nOvde je navedena istorija brisanja i premeštanja s obrazloženjem:",
-       "moveddeleted-notice": "Ova stranica je obrisana.\nIstorija njenog brisanja i premeštanja nalazi se ispod:",
-       "moveddeleted-notice-recent": "Žao nam je, ova stranica je nedavno obrisana (u poslednjih 24 sata).\nOvde je navedena istorija brisanja i premeštanja s obrazloženjem.",
+       "moveddeleted-notice": "Ova stranica je obrisana.\nDnevnik brisanja, zaštite i premeštanja stranice nalazi se ispod.",
+       "moveddeleted-notice-recent": "Žao nam je, ova stranica je nedavno obrisana (u poslednjih 24 sata).\nIstorija njenog brisanja, zaštite i premeštanja nalazi se ispod:",
        "log-fulllog": "Pogledaj celu istoriju",
        "edit-hook-aborted": "Izmenu je prekinula kuka.\nNije dato nikakvo obrazloženje.",
        "edit-gone-missing": "Ne mogu da ažuriram stranicu.\nIzgleda da je obrisana.",
        "postedit-confirmation-created": "Stranica je napravljena.",
        "postedit-confirmation-restored": "Stranica je vraćena.",
        "postedit-confirmation-saved": "Vaša izmena je sačuvana.",
+       "postedit-confirmation-published": "Vaša izmena je objavljena.",
        "edit-already-exists": "Ne mogu da napravim stranicu.\nIzgleda da ona već postoji.",
        "defaultmessagetext": "Podrazumevani 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. Ako ste prijavljeni, možete onemogućiti ovo upozorenje u svojim podešavanjima, u odeljku „{{int:prefs-editing}}“.",
+       "editpage-invalidcontentmodel-title": "Model sadržaja nije podržan",
+       "editpage-invalidcontentmodel-text": "Model sadržaja „$1“ nije podržan.",
        "editpage-notsupportedcontentformat-title": "Format sadržaja nije podržan",
+       "editpage-notsupportedcontentformat-text": "Format sadržaja $1 nije podržan za model sadržaja $2.",
        "content-model-wikitext": "vikitekst",
        "content-model-text": "čist tekst",
        "content-model-javascript": "javaskript",
        "content-model-css": "CSS",
+       "content-model-json": "JSON",
+       "content-json-empty-object": "Prazan objekat",
+       "content-json-empty-array": "Prazan niz",
+       "deprecated-self-close-category": "Stranice koje koriste nevalidne samozatvarajuće HTML tagove",
        "duplicate-args-warning": "<strong>Upozorenje:</strong> [[:$1]] poziva [[:$2]] sa više od jedne vrednosti za parametar „$3“. Samo poslednja navedena vrednost će biti korišćena.",
-       "expensive-parserfunction-warning": "'''Upozorenje:''' ova stranica sadrži previše poziva za raščlanjivanje.\n\nTrebalo bi da ima manje od $2 {{PLURAL:$2|poziv|poziva|poziva}}, a sada ima $1.",
+       "duplicate-args-category": "Stranice s dupliranim argumentima kod poziva šablona",
+       "duplicate-args-category-desc": "Stranica sadrži pozive šablona koji koriste dvostruke argumente, kao što su <code><nowiki>{{foo|bar=1|bar=2}}</nowiki></code> ili <code><nowiki>{{foo|bar|1=baz}}</nowiki></code>.",
+       "expensive-parserfunction-warning": "<strong>Upozorenje:</strong> ova stranica sadrži previše poziva za raščlanjivanje.\n\nTrebalo bi da ima manje od $2 {{PLURAL:$2|poziv|poziva}}, a sada ima $1.",
        "expensive-parserfunction-category": "Stranice s previše poziva za raščlanjivanje",
-       "post-expand-template-inclusion-warning": "'''Upozorenje:''' veličina uključenog šablona je prevelika.\nNeki šabloni neće biti uključeni.",
-       "post-expand-template-inclusion-category": "Stranice gde su uključeni šabloni preveliki",
+       "post-expand-template-inclusion-warning": "<strong>Upozorenje:</strong> veličina obuhvaćenog šablona je prevelika.\nNeki šabloni neće biti obuhvaćeni.",
+       "post-expand-template-inclusion-category": "Stranice gde su obuhvaćeni preveliki šabloni",
        "post-expand-template-argument-warning": "'''Upozorenje:''' ova stranica sadrži najmanje jedan argument u šablonu koji ima preveliku veličinu.\nOvakve argumente bi trebalo izbegavati.",
        "post-expand-template-argument-category": "Stranice koje sadrže izostavljene argumente u šablonu",
        "parser-template-loop-warning": "Otkrivena je petlja šablona: [[$1]]",
+       "template-loop-category": "Stranice sa petljama šablona",
+       "template-loop-category-desc": "Stranica sadrži petlju šablona, tj. šablon koji poziva sam rebe rekurzivno.",
        "parser-template-recursion-depth-warning": "Dubina uključivanja šablona je prekoračena ($1)",
        "language-converter-depth-warning": "Prekoračena je granica dubine jezičkog pretvarača ($1)",
        "node-count-exceeded-category": "Stranice u kojima je prekoračen broj čvorova",
+       "node-count-exceeded-category-desc": "Stranice sa previše čvorova (node).",
        "node-count-exceeded-warning": "Stranica u kojoj je prekoračen broj čvorova",
        "expansion-depth-exceeded-category": "Stranice u kojima je prekoračena dubina proširenja",
+       "expansion-depth-exceeded-category-desc": "Stranica je prekoračila najveću dubinu proširenja.",
        "expansion-depth-exceeded-warning": "Stranica u kojoj je prekoračena dubina proširenja",
        "parser-unstrip-loop-warning": "Utvrđena je petlja",
        "unstrip-depth-warning": "Prekoračen limit Unstrip rekurzije ($1)",
        "undo-summary-username-hidden": "Poništi izmenu $1 skrivenog korisnika",
        "cantcreateaccount-text": "Otvaranje naloga s ove IP adrese (<strong>$1</strong>) je blokirao/la [[User:$3|$3]].\n\nRazlog koji je naveo/la $3 je <em>$2</em>",
        "cantcreateaccount-range-text": "Otvaranje naloga sa IP adresa u rasponu <strong>$1</strong>, koji uključuje i vašu IP adresu (<strong>$4</strong>) je blokirao/la [[User:$3|$3]].\n\nRazlog koji je naveo/la $3 je <em>$2</em>",
-       "viewpagelogs": "Pogledaj dnevnike ove stranice",
+       "viewpagelogs": "Dnevnici ove stranice",
        "nohistory": "Ne postoji istorija izmena ove stranice.",
-       "currentrev": "Tekuća izmena",
-       "currentrev-asof": "Poslednja verzija na datum $2 u $3",
-       "revisionasof": "Izmena od $2 u $3",
-       "revision-info": "Izmena od $1 koju je {{GENDER:$6|uredio $2|uredila $2}}$7",
+       "currentrev": "Trenutna izmena",
+       "currentrev-asof": "Trenutna izmena na datum $2 u $3",
+       "revisionasof": "Izmena na datum $2 u $3",
+       "revision-info": "Izmena od $1 od strane {{GENDER:$6|korisnika $2|korisnice $2}}$7",
        "previousrevision": "← Starija izmena",
        "nextrevision": "Novija izmena →",
-       "currentrevisionlink": "Tekuća izmena",
+       "currentrevisionlink": "Trenutna izmena",
        "cur": "tren",
        "next": "sled",
        "last": "razl",
        "page_first": "prva",
        "page_last": "poslednja",
-       "histlegend": "Izbor razlika: izaberite kutijice izmena za upoređivanje i pritisnite enter ili dugme na dnu.<br />\nObjašnjenje: <strong>({{int:cur}})</strong> = razlika s trenutnom izmenom, <strong>({{int:last}})</strong> = razlika s prethodnom izmenom, <strong>{{int:minoreditletter}}</strong> = mala izmena",
-       "history-fieldset-title": "Pregled izmena",
+       "histlegend": "Izbor razlika: izaberite kutijice izmena za upoređivanje i pritisnite enter ili dugme na dnu.<br />\nObjašnjenje: <strong>({{int:cur}})</strong> = razlika s trenutnom izmenom, <strong>({{int:last}})</strong> = razlika s prethodnom izmenom, <strong>{{int:minoreditletter}}</strong> = manja izmena",
+       "history-fieldset-title": "Pretraga izmena",
        "history-show-deleted": "Samo obrisane izmene",
        "histfirst": "najstarije",
        "histlast": "najnovije",
        "history-feed-description": "Istorija izmena ove stranice na vikiju",
        "history-feed-item-nocomment": "$1 u $2",
        "history-feed-empty": "Tražena stranica ne postoji.\nMoguće da je obrisana s vikija ili je preimenovana.\nPokušajte da [[Special:Search|pretražite viki]] za slične stranice.",
+       "history-edit-tags": "Uredi oznake izabranih izmena",
        "rev-deleted-comment": "(opis izmene uklonjen)",
        "rev-deleted-user": "(korisničko ime uklonjeno)",
        "rev-deleted-event": "(detalji unosa uklonjeni)",
        "rev-deleted-user-contribs": "[korisničko ime ili IP adresa je uklonjena – izmena je sakrivena sa spiska doprinosa]",
        "rev-deleted-text-permission": "Izmena ove stranice je '''obrisana'''.\nDetalje možete videti u [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} istoriji brisanja].",
+       "rev-suppressed-text-permission": "Izmena ove stranice je <strong>sakrivena</strong>. Više detalja možete naći u [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} istoriji sakrivanja].",
        "rev-deleted-text-unhide": "Izmena ove stranice je '''obrisana'''.\nDetalje možete videti u [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} istoriji brisanja].\nIpak možete da [$1 vidite ovu izmenu] ako želite da nastavite.",
        "rev-suppressed-text-unhide": "Izmena ove stranice je '''sakrivena'''.\nDetalje možete videti u [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} istoriji sakrivanja].\nIpak možete da [$1 vidite ovu izmenu] ako želite da nastavite.",
        "rev-deleted-text-view": "Izmena ove stranice je '''obrisana'''.\nMožete je pogledati; više detalja možete naći u [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} istoriji brisanja].",
        "revdelete-no-file": "Tražena datoteka ne postoji.",
        "revdelete-show-file-confirm": "Želite li da vidite obrisanu izmenu datoteke „<nowiki>$1</nowiki>“ od $2; $3?",
        "revdelete-show-file-submit": "Da",
-       "revdelete-selected-text": "{{PLURAL:$1|Izabrana izmena|Izabrane izmene}} [[:$2]]:",
+       "revdelete-selected-text": "{{PLURAL:$1|Izabrana izmena|Izabrane izmene|Izabranih izmena}} [[:$2]]:",
        "revdelete-selected-file": "{{PLURAL:$1|Izabrana verzija datoteke|Izabrane verzije datoteke}} [[:$2]]:",
        "logdelete-selected": "{{PLURAL:$1|Izabrana stavka u istoriji|Izabrane stavke u istoriji}}:",
        "revdelete-text-text": "Izbrisane izmene će i dalje biti vidljive u istoriji stranice, ali delovi njihovog sadržaja neće biti javno dostupni.",
        "mergehistory-empty": "Nema izmena za spajanje.",
        "mergehistory-done": "$3 {{PLURAL:$3|izmena stranice $1 je spojena|izmene stranice $1 su spojene|izmena stranice $1 je spojeno}} u [[:$2]].",
        "mergehistory-fail": "Ne mogu da spojim istorije. Proverite stranicu i vremenske parametre.",
+       "mergehistory-fail-bad-timestamp": "Vremenska oznaka nije ispravna.",
+       "mergehistory-fail-invalid-source": "Izvorna stranica nije ispravna.",
+       "mergehistory-fail-invalid-dest": "Odredišna stranica nije ispravna.",
+       "mergehistory-fail-no-change": "Spajanje istorije nije spojilo nijednu izmenu. Proverite parametre stranice i vremena.",
+       "mergehistory-fail-permission": "Nemate ovlašćenje za spajanje istorije.",
+       "mergehistory-fail-self-merge": "Izvorna i odredišna stranica ne mogu biti iste.",
+       "mergehistory-fail-timestamps-overlap": "Izvorne izmene se preklapaju ili dolaze nakon odredišnih izmena.",
        "mergehistory-fail-toobig": "Nije moguće spojiti istorije jer više od $1 {{PLURAL:$1|izmene će biti premeštene|izmena će biti premešteno}}.",
        "mergehistory-no-source": "Izvorna stranica $1 ne postoji.",
        "mergehistory-no-destination": "Odredišna stranica $1 ne postoji.",
        "revertmerge": "rastavi",
        "mergelogpagetext": "Ispod je spisak najskorijih spajanja istorija dveju stranica.",
        "history-title": "Istorija izmena stranice „$1“",
-       "difference-title": "$1 — razlika između izmena",
+       "difference-title": "Razlika između izmena na stranici „$1”",
        "difference-title-multipage": "Razlika između stranica „$1“ i „$2“",
        "difference-multipage": "(razlike između stranica)",
        "lineno": "Red $1:",
        "compareselectedversions": "Uporedi izabrane izmene",
        "showhideselectedversions": "Promeni vidljivost izabranih izmena",
        "editundo": "poništi",
-       "diff-empty": "(Nema razlike)",
-       "diff-multi-sameuser": "({{PLURAL:$1|Jedna međuizmena istog korisnika nije prikazana|$1 međuizmene istog korisnika nije prikazano|$1 međuizmena istog korisnika nije prikazano}})",
+       "diff-empty": "(nema razlike)",
+       "diff-multi-sameuser": "({{PLURAL:$1|Jedna međuizmena istog korisnika nije prikazana|$1 međuizmene istog korisnika nisu prikazane|$1 međuizmena istog korisnika nije prikazano}})",
        "diff-multi-otherusers": "({{PLURAL:$1|Jedna međuizmena|$1 međuizmene|$1 međuizmena}} od strane {{PLURAL:$2|još jednog korisnika nije prikazana|$2 korisnika nije prikazano}})",
        "diff-multi-manyusers": "({{PLURAL:$1|Nije prikazana međuizmena|Nisu prikazane $1 međuizmene|Nije prikazano $1 međuizmena}} od više od $2 korisnika)",
+       "diff-paragraph-moved-tonew": "Odlomak je premešten. Kliknite da pređete na njegovo novo mesto.",
+       "diff-paragraph-moved-toold": "Odlomak je premešten. Kliknite da pređete na njegovo staro mesto.",
        "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 zastarelu vezu do stranice koja je obrisana.\nViše informacija možete pronaći u [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} dnevniku brisanja].",
        "searchresults": "Rezultati pretrage",
        "searchresults-title": "Rezultati pretrage za „$1“",
        "titlematches": "Naslov stranice odgovara",
        "textmatches": "Tekst stranice odgovara",
        "notextmatches": "Nijedan tekst stranice ne odgovara",
-       "prevn": "prethodnih {{PLURAL:$1|$1}}",
-       "nextn": "sledećih {{PLURAL:$1|$1}}",
+       "prevn": "{{PLURAL:$1|prethodnu $1|prethodne $1|prethodnih $1}}",
+       "nextn": "{{PLURAL:$1|sledeću $1|sledeće $1|sledećih $1}}",
        "prev-page": "prethodna stranica",
        "next-page": "sledeća stranica",
        "prevn-title": "$1 {{PLURAL:$1|prethodni  rezultat|prethodna rezultata|prethodnih rezultata}}",
        "nextn-title": "$1 {{PLURAL:$1|sledeći rezultat|sledeća rezultata|sledećih rezultata}}",
-       "shown-title": "Prikaži $1 {{PLURAL:$1|rezultat|rezultata|rezultata}} po stranici",
+       "shown-title": "Prikaži $1 {{PLURAL:$1|rezultat|rezultata}} po stranici",
        "viewprevnext": "Pogledaj ($1 {{int:pipe-separator}} $2) ($3).",
        "searchmenu-exists": "<strong>Postoji stranica pod nazivom „[[:$1]]”!</strong> {{PLURAL:$2|0=|Takođe pogledajte druge pronađene rezultate pretrage.}}",
-       "searchmenu-new": "<strong>Napravite stranicu „[[:$1]]”!</strong> {{PLURAL:$2|0=|Takođe pogledajte rezultat pretrage.|Takođe pogledajte rezultate pretrage.}}",
-       "searchprofile-articles": "Članci",
+       "searchmenu-new": "<strong>Napravite stranicu „[[:$1]]” na ovom vikiju!</strong> {{PLURAL:$2|0=|Takođe pogledajte rezultat pretrage.|Takođe pogledajte rezultate pretrage.}}",
+       "searchprofile-articles": "Stranice sa sadržajem",
        "searchprofile-images": "Datoteke",
        "searchprofile-everything": "Sve",
        "searchprofile-advanced": "Napredno",
        "searchprofile-images-tooltip": "Pretražite datoteke",
        "searchprofile-everything-tooltip": "Pretražite sav sadržaj (uključujući stranice za razgovor)",
        "searchprofile-advanced-tooltip": "Pretražite prilagođene imenske prostore",
-       "search-result-size": "$1 ({{PLURAL:$2|1 reč|$2 reči|$2 reči}})",
+       "search-result-size": "$1 ({{PLURAL:$2|1 reč|$2 reči}})",
        "search-result-category-size": "{{PLURAL:$1|1 član|$1 člana|$1 članova}}, ({{PLURAL:$2|1 potkategorija|$2 potkategorije|$2 potkategorija}}, {{PLURAL:$3|1 datoteka|$3 datoteke|$3 datoteka}})",
-       "search-redirect": "(preusmereno sa $1)",
+       "search-redirect": "(preusmerenje sa $1)",
        "search-section": "(odeljak $1)",
        "search-category": "(kategorija $1)",
        "search-file-match": "(podudara se sadržaj datoteke)",
-       "search-suggest": "Da li ste mislili na: $1",
+       "search-suggest": "Da li ste mislili: $1",
        "search-rewritten": "Prikazani rezultati za $1. Ipak pretraži $2.",
-       "search-interwiki-caption": "Bratski projekti",
+       "search-interwiki-caption": "Rezultati sa sestrinskih projekata",
        "search-interwiki-default": "Rezultati sa $1:",
        "search-interwiki-more": "(više)",
+       "search-interwiki-more-results": "još rezultata",
        "search-relatedarticle": "Povezano",
        "searchrelated": "povezano",
        "searchall": "sve",
        "showingresults": "Ispod {{PLURAL:$1|je prikazan <strong>1</strong> rezultat|su prikazana <strong>$1</strong> rezultata|je prikazano <strong>$1</strong> rezultata}}, počev od broja <strong>$2</strong>.",
        "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": "Nema poklapanja.",
+       "search-nonefound": "Nisu pronađeni rezultati koji odgovaraju upitu.",
+       "search-nonefound-thiswiki": "Nema rezultata na ovom sajtu koji se poklapaju sa terminom pretrage.",
        "powersearch-legend": "Napredna pretraga",
        "powersearch-ns": "Pretraga po imenskim prostorima:",
        "powersearch-togglelabel": "Izaberi:",
        "powersearch-toggleall": "Sve",
        "powersearch-togglenone": "Ništa",
        "powersearch-remember": "Zapamti moj izbor za buduće pretrage",
-       "search-external": "Spoljna pretraga",
+       "search-external": "Spoljašnja pretraga",
        "searchdisabled": "Pretraga je onemogućena.\nU međuvremenu možete tražiti preko Gugla.\nUpamtite da njegovi popisi ovog vikija mogu biti zastareli.",
        "search-error": "Došlo je do greške prilikom pretrage: $1",
+       "search-warning": "Upozorenje prilikom pretrage: $1",
        "preferences": "Podešavanja",
        "mypreferences": "Podešavanja",
        "prefs-edits": "Broj izmena:",
        "prefsnologintext2": "Morate biti prijavljeni da biste menjali svoja podešavanja.",
        "prefs-skin": "Tema",
-       "skin-preview": "Pregledaj",
+       "skin-preview": "pregledaj",
        "datedefault": "Svejedno",
        "prefs-labs": "Probne mogućnosti",
        "prefs-user-pages": "Korisničke stranice",
        "prefs-watchlist": "Spisak nadgledanja",
        "prefs-editwatchlist": "Uređivanje spiska nadgledanja",
        "prefs-editwatchlist-label": "Uređivanje spiska:",
-       "prefs-editwatchlist-edit": "Uredi spisak",
-       "prefs-editwatchlist-raw": "Uredi sirov spisak",
-       "prefs-editwatchlist-clear": "Isprazni spisak",
+       "prefs-editwatchlist-edit": "uredi spisak",
+       "prefs-editwatchlist-raw": "uredi sirov spisak",
+       "prefs-editwatchlist-clear": "isprazni spisak",
        "prefs-watchlist-days": "Broj dana u spisku nadgledanja:",
        "prefs-watchlist-days-max": "Najviše $1 {{PLURAL:$1|dan|dana|dana}}",
-       "prefs-watchlist-edits": "Najveći broj izmena u proširenom spisku nadgledanja:",
-       "prefs-watchlist-edits-max": "Najveća vrednost je hiljadu",
+       "prefs-watchlist-edits": "Najveći broj izmena prikazanih na spisku nadgledanja:",
+       "prefs-watchlist-edits-max": "Najveći broj: 1000",
        "prefs-watchlist-token": "Žeton spiska nadgledanja:",
+       "prefs-watchlist-managetokens": "Upravljaj žetonima",
        "prefs-misc": "Druga podešavanja",
-       "prefs-resetpass": "Promeni lozinku",
-       "prefs-changeemail": "Promeni ili ukloni imejl adresu",
-       "prefs-setemail": "Postavi imejl adresu",
-       "prefs-email": "Postavke imejla",
+       "prefs-resetpass": "promeni lozinku",
+       "prefs-changeemail": "promeni ili ukloni imejl adresu",
+       "prefs-setemail": "postavi imejl adresu",
+       "prefs-email": "Opcije imejla",
        "prefs-rendering": "Izgled",
        "saveprefs": "Sačuvaj",
-       "restoreprefs": "Vrati sve na podrazumevano (u svim odeljcima)",
+       "restoreprefs": "Vrati sva podrazumevana podešavanja (u svim odeljcima)",
        "prefs-editing": "Uređivanje",
        "searchresultshead": "Pretraga",
        "stub-threshold": "Prag za oblikovanje veze kao klice ($1):",
        "stub-threshold-sample-link": "primer",
-       "stub-threshold-disabled": "Onemogućeno",
+       "stub-threshold-disabled": "onemogućeno",
        "recentchangesdays": "Broj dana u skorašnjim izmenama:",
        "recentchangesdays-max": "Najviše $1 {{PLURAL:$1|dan|dana}}",
-       "recentchangescount": "Broj izmena za prikaz:",
-       "prefs-help-recentchangescount": "Podrazumeva skorašnje izmene, istorije stranica i dnevnike.",
-       "prefs-help-watchlist-token2": "Ovo je tajni ključ za veb-dovod Vašeg spiska nadgledanja. \nSvako ko zna ovaj ključ biće u mogućnosti da vidi Vaša nadgledanja; stoga, ključ nemojte odavati nikome. \nAko je potrebno, ključ možete [[Special:ResetTokens|resetovati]].",
+       "recentchangescount": "Podrazumevani broj izmena za prikaz u skorašnjim izmenama, istorijama stranica i dnevnicima:",
+       "prefs-help-recentchangescount": "Najveća broj: 1000",
+       "prefs-help-watchlist-token2": "Ovo je tajni ključ za veb-dovod Vašeg spiska nadgledanja. \nSvako ko zna ovaj ključ biće u mogućnosti da čita Vaš spisak nadgledanja, zato ga nemojte deliti. \nAko je potrebno, [[Special:ResetTokens|možete ga obnoviti]].",
        "savedprefs": "Vaša podešavanja su sačuvana.",
-       "savedrights": "Korisnička prava za {{GENDER:$1|$1}} su sačuvana.",
+       "savedrights": "Korisničke grupe za {{GENDER:$1|$1}} su sačuvane.",
        "timezonelegend": "Vremenska zona:",
        "localtime": "Lokalno vreme:",
        "timezoneuseserverdefault": "podrazumevane vrednosti ($1)",
        "timezoneregion-europe": "Evropa",
        "timezoneregion-indian": "Indijski okean",
        "timezoneregion-pacific": "Tihi okean",
-       "allowemail": "Omogući primanje imejlova od drugih korisnika",
+       "allowemail": "Dozvoli primanje imejlova od drugih korisnika",
+       "email-allow-new-users-label": "Dozvoli primanje imejlova od novajlija",
+       "email-blacklist-label": "Zabrani primanje imejlova od sledećih korisnika:",
        "prefs-searchoptions": "Pretraga",
        "prefs-namespaces": "Imenski prostori",
-       "default": "podrazumevano",
+       "default": "podrazumevana",
        "prefs-files": "Datoteke",
-       "prefs-custom-css": "Prilagođeni CSS",
-       "prefs-custom-js": "Prilagođeni javaskript",
-       "prefs-common-config": "Deljeni CSS/javaskript za sve teme:",
-       "prefs-reset-intro": "Možete koristiti ovu stranicu da poništite svoje postavke na podrazumevane vrednosti.\nOva radnja se ne može vratiti.",
+       "prefs-custom-css": "prilagođeni CSS",
+       "prefs-custom-json": "Prilagođeni JSON",
+       "prefs-custom-js": "prilagođeni Javaskript",
+       "prefs-common-config": "Deljeni CSS/JSON/Javaskript za sve teme:",
+       "prefs-reset-intro": "Možete koristiti ovu stranicu da poništite svoja podešavanja na podrazumevane vrednosti.\nOva radnja se ne može vratiti.",
        "prefs-emailconfirm-label": "Potvrda imejla:",
        "youremail": "Imejl:",
        "username": "{{GENDER:$1|Korisničko ime}}:",
-       "prefs-memberingroups": "{{PLURAL:$1|Grupa|Grupe}}:",
+       "prefs-memberingroups": "{{GENDER:$2|Član|Članica}} {{PLURAL:$1|grupe|grupâ}}:",
        "prefs-memberingroups-type": "$1",
        "group-membership-link-with-expiry": "$1 (do $2)",
        "prefs-registration": "Vreme registracije:",
        "yourvariant": "Varijanta jezika:",
        "prefs-help-variant": "Željena varijanta ili pravopis za prikaz stranica sa sadržajem ovog vikija.",
        "yournick": "Novi potpis:",
-       "prefs-help-signature": "Komentare na stranicama za razgovor potpisujte sa četiri tilde: <nowiki>~~~~</nowiki>. Ovaj vikitekst će biti pretvoren u Vaš potpis i trenutno vreme.",
+       "prefs-help-signature": "Komentari na stranicama za razgovor treba da budu potpisani sa „<nowiki>~~~~</nowiki>“ koje će biti pretvoreno u Vaš potpis s trenutnim vremenom.",
        "badsig": "Potpis je neispravan.\nProverite oznake HTML.",
        "badsiglength": "Vaš potpis je predugačak.\nNe sme biti duži od $1 {{PLURAL:$1|znaka|znaka|znakova}}.",
        "yourgender": "Kako želite da se predstavite?",
-       "gender-unknown": "Ne želim da se predstavim",
+       "gender-unknown": "Kad Vas spominje, softver će koristiti rodno neutralne reči kad god je to moguće",
        "gender-male": "On uređuje viki stranice",
        "gender-female": "Ona uređuje viki stranice",
-       "prefs-help-gender": "Neobavezno: koristi se za ispravno obraćanje softvera korisnicima, zavisno od njihovog pola.\nOvaj podatak će biti javan.",
+       "prefs-help-gender": "Postavljanje ovog podešavanja je neobavezno.\nSoftver koristi datu vrednost da bi Vam se obratio i spomenuo Vas drugima koristeći odgovarajući gramatički rod.\nOva informacija će biti javna.",
        "email": "Imejl",
        "prefs-help-realname": "Pravo ime nije obavezno.\nAko izaberete da ga unesete, ono će biti korišćeno za pripisivanje vašeg rada.",
-       "prefs-help-email": "Imejl adresa nije obavezna, ali je potrebna u slučaju da zaboravite lozinku.",
-       "prefs-help-email-others": "Možete je koristiti i da omogućite drugima da vas kontaktiraju preko korisničke stranice ili stranice za razgovor, bez otkrivanja svog identiteta.",
+       "prefs-help-email": "Imejl adresa nije obavezna, ali je potrebna za obnavljanje lozinke, ako je zaboravite.",
+       "prefs-help-email-others": "Takođe možete izabrati da dopustite drugima da Vas kontaktiraju preko imejla putem veze na Vašoj korisničkoj stranici ili stranici za razgovor.\nVaša imejl adresa neće biti prikazana drugim korisnicima koji Vas kontaktiraju.",
        "prefs-help-email-required": "Potrebna je imejl adresa.",
-       "prefs-info": "Osnovni podaci",
+       "prefs-info": "Osnovne informacije",
        "prefs-i18n": "Internacionalizacija",
        "prefs-signature": "Potpis",
        "prefs-dateformat": "Format datuma",
        "prefs-timeoffset": "Vremenska razlika",
        "prefs-advancedediting": "Glavna podešavanja",
+       "prefs-developertools": "Programerske alatke",
        "prefs-editor": "Uređivač",
        "prefs-preview": "Pretpregled",
-       "prefs-advancedrc": "Napredne postavke",
+       "prefs-advancedrc": "Napredne opcije",
        "prefs-opt-out": "Onemogućavanje poboljšanja",
-       "prefs-advancedrendering": "Napredne postavke",
-       "prefs-advancedsearchoptions": "Napredne postavke",
-       "prefs-advancedwatchlist": "Napredne postavke",
-       "prefs-displayrc": "Postavke prikaza",
-       "prefs-displaywatchlist": "Postavke prikaza",
+       "prefs-advancedrendering": "Napredne opcije",
+       "prefs-advancedsearchoptions": "Napredne opcije",
+       "prefs-advancedwatchlist": "Napredne opcije",
+       "prefs-displayrc": "Podešavanja prikaza",
+       "prefs-displaywatchlist": "Podešavanja prikaza",
        "prefs-tokenwatchlist": "Žeton",
        "prefs-diffs": "Razlike",
        "prefs-help-prefershttps": "Ova podešavanja će stupiti na snagu pri sledećoj prijavi.",
        "prefswarning-warning": "Promenili ste vaša podešavanja ali niste ih još sačuvali.\nAko ne pritisnete „$1“ vaša podešavanja će biti izgubljena.",
        "prefs-tabs-navigation-hint": "Savet: možete koristiti tipke sa levom i desnom strelicom za kretanje kroz kartice.",
-       "userrights": "Upravljanje korisničkim pravima",
-       "userrights-lookup-user": "Upravljanje korisničkim grupama",
+       "userrights": "Korisnička prava",
+       "userrights-lookup-user": "Izaberi korisnika",
        "userrights-user-editname": "Korisničko ime:",
-       "editusergroup": "Uredi {{GENDER:$1|korisničke}} grupe",
-       "editinguser": "Menjate korisnička prava {{GENDER:$1|korisnika|korisnice|korisnika}} '''[[User:$1|$1]]''' $2",
-       "userrights-editusergroup": "Promena korisničkih grupa",
+       "editusergroup": "Učitaj korisničke grupe",
+       "editinguser": "Menjate korisnička prava {{GENDER:$1|korisnika|korisnice}} <strong>[[User:$1|$1]]</strong> $2",
+       "viewinguserrights": "Korisnička prava {{GENDER:$1|korisnika|korisnice}} <strong>[[User:$1|$1]]</strong> $2",
+       "userrights-editusergroup": "Promena {{GENDER:$1|korisničkih}} grupa",
+       "userrights-viewusergroup": "Pregled {{GENDER:$1|korisničkih}} grupa",
        "saveusergroups": "Sačuvaj {{GENDER:$1|korisničke}} grupe",
        "userrights-groupsmember": "Član:",
        "userrights-groupsmember-auto": "Podrazumevano član i:",
-       "userrights-groups-help": "Možete promeniti grupe kojima ovaj korisnik pripada.\n* Označen kvadratić označava da se korisnik nalazi u toj grupi.\n* Neoznačen kvadratić označava da se korisnik ne nalazi u toj grupi.\n* Zvezdica označava da ne možete ukloniti grupu ako je dodate i obratno.",
+       "userrights-groups-help": "Možete promeniti grupe kojima ovaj korisnik pripada:\n* Označen kvadratić označava da se korisnik nalazi u toj grupi.\n* Neoznačen kvadratić označava da se korisnik ne nalazi u toj grupi.\n* Zvezdica (*) označava da ne možete ukloniti tu grupu ako je dodate i obratno.\n* Taraba (#) označava da jedino možete odložiti vreme isteka članstva u toj grupi; ne možete ga ubrzati.",
        "userrights-reason": "Razlog:",
        "userrights-no-interwiki": "Nemate ovlašćenja da menjate korisnička prava na drugim vikijima.",
        "userrights-nodatabase": "Baza podataka $1 ne postoji ili nije lokalna.",
        "userrights-changeable-col": "Grupe koje možete da promenite",
        "userrights-unchangeable-col": "Grupe koje ne možete da promenite",
        "userrights-irreversible-marker": "$1*",
+       "userrights-expiry-current": "Ističe $1",
+       "userrights-expiry-none": "Ne ističe",
+       "userrights-expiry": "Ističe:",
        "userrights-expiry-existing": "Postojeće vreme isteka: $3, $2",
        "userrights-expiry-othertime": "Drugo vreme:",
+       "userrights-expiry-options": "1 dan:1 day,1 nedelja:1 week,1 mesec:1 month,3 meseca:3 months,6 meseci:6 months,1 godina:1 year",
+       "userrights-invalid-expiry": "Vreme isticanja grupe „$1“ nije ispravno.",
+       "userrights-expiry-in-past": "Vreme isticanja grupe „$1“ je prošlo.",
+       "userrights-cannot-shorten-expiry": "Ne možete ubrzati istek članstva u grupi „$1”. Samo korisnici sa dozvolom da dodaju ili uklone ovu grupu mogu da ubrzaju rok isteka.",
        "userrights-conflict": "Sukob promena korisničkih prava! Molimo proverite vaše izmene.",
        "group": "Grupa:",
        "group-user": "Korisnici",
        "group-user-member": "{{GENDER:$1|korisnik|korisnica|korisnik}}",
        "group-autoconfirmed-member": "{{GENDER:$1|automatski potvrđen korisnik|automatski potvrđena korisnica}}",
        "group-bot-member": "{{GENDER:$1|bot}}",
-       "group-sysop-member": "{{GENDER:$1|administrator|administratorka}}",
+       "group-sysop-member": "{{GENDER:$1|administrator|administratorka|administrator}}",
        "group-bureaucrat-member": "{{GENDER:$1|birokrata|birokratkinja}}",
        "group-suppress-member": "{{GENDER:$1|brisač izmena}}",
        "grouppage-user": "{{ns:project}}:Korisnici",
        "right-createpage": "pravljenje stranica (izuzev stranica za razgovor)",
        "right-createtalk": "pravljenje stranica za razgovor",
        "right-createaccount": "otvaranje novih korisničkih naloga",
+       "right-autocreateaccount": "Prijavite se automatski sa eksternim korisničkim nalogom",
        "right-minoredit": "označavanje izmena manjim",
-       "right-move": "Premeštanje stranica",
+       "right-move": "premeštanje stranica",
        "right-move-subpages": "premeštanje stranica s njihovim podstranicama",
        "right-move-rootuserpages": "premeštanje osnovnih korisničkih stranica",
-       "right-move-categorypages": "Premeštanje kategorija",
-       "right-movefile": "Premeštanje datoteka",
+       "right-move-categorypages": "premeštanje kategorija",
+       "right-movefile": "premeštanje datoteka",
        "right-suppressredirect": "premeštanje stranica bez ostavljanja preusmerenja",
-       "right-upload": "Otpremanje datoteka",
+       "right-upload": "otpremanje datoteka",
        "right-reupload": "zamenjivanje postojećih datoteka",
        "right-reupload-own": "zamenjivanje sopstvenih datoteka",
        "right-reupload-shared": "menjanje datoteka na deljenom skladištu multimedije",
        "right-purge": "čišćenje keš memorije stranice bez potvrde",
        "right-autoconfirmed": "bez ograničavanja stavki za IP adrese",
        "right-bot": "smatranje izmena kao automatski proces",
-       "right-nominornewtalk": "neposedovanje malih izmena na stranicama za razgovor otvara prozor za nove poruke",
+       "right-nominornewtalk": "neposedovanje manjih izmena na stranicama za razgovor otvara prozor za nove poruke",
        "right-apihighlimits": "korišćenje viših granica za upite iz API-ja",
-       "right-writeapi": "pisanje API-ja",
+       "right-writeapi": "mogućnost pisanja API-ja",
        "right-delete": "brisanje stranica",
        "right-bigdelete": "brisanje stranica s velikom istorijom",
        "right-deletelogentry": "brisanje i vraćanje određenih stavki u dnevniku",
        "right-viewsuppressed": "pregledanje izmena skrivenih od svih korisnika",
        "right-suppressionlog": "pregledanje privatnih dnevnika",
        "right-block": "blokiranje daljih izmena drugih korisnika",
-       "right-blockemail": "Blokiraj korisniku slanje imejla",
+       "right-blockemail": "blokiranje korisnika da šalju imejl",
        "right-hideuser": "blokiranje korisničkog imena i njegovo sakrivanje od javnosti",
        "right-ipblock-exempt": "zaobilaženje blokiranja IP adrese, automatska blokiranja i blokiranja opsega",
        "right-unblockself": "deblokiranje samog sebe",
        "right-protect": "menjanje stepena zaštite i uređivanje stranica pod prenosivom zaštitom",
-       "right-editprotected": "uređivanje stranice pod zaštitom „{{int:protect-level-sysop}}“",
+       "right-editprotected": "uređivanje stranica pod zaštitom „{{int:protect-level-sysop}}“",
        "right-editsemiprotected": "uređivanje stranica pod zaštitom „{{int:protect-level-autoconfirmed}}“",
+       "right-editcontentmodel": "menjanje modela sadržaja stranice",
        "right-editinterface": "uređivanje korisničkog okruženja",
        "right-editusercss": "uređivanje tuđih CSS datoteka",
+       "right-edituserjson": "uređivanje tuđih JSON datoteka",
        "right-edituserjs": "uređivanje tuđih JavaScript datoteka",
        "right-editmyusercss": "uređivanje sopstvenih CSS datoteka",
+       "right-editmyuserjson": "uređivanje sopstvenih JSON datoteka",
        "right-editmyuserjs": "uređivanje sopstvenih JavaScript datoteka",
-       "right-viewmywatchlist": "vidi sopstveni spisak nadgledanja",
+       "right-viewmywatchlist": "pregled sopstvenog spiska nadgledanja",
        "right-editmywatchlist": "uređivanje sopstvenog spiska nadgledanja; neke preduzete radnje će svejedno dodati stranice na spisak i bez ovog prava",
-       "right-viewmyprivateinfo": "vidite svoje lične podatke (npr. imejl adresu, pravo ime)",
-       "right-editmyprivateinfo": "uređivanje sopstvenih ličnih podataka (npr. imejl adresa, pravo ime)",
+       "right-viewmyprivateinfo": "pregled svojih ličnih podataka (npr. imejl adresu, pravo ime)",
+       "right-editmyprivateinfo": "uređivanje sopstvenih ličnih podataka (npr. imejl adrese, pravog imena)",
        "right-editmyoptions": "uređivanje sopstvenih podešavanja",
        "right-rollback": "brzo vraćanje izmena poslednjeg korisnika koji je menjao određenu stranicu",
        "right-markbotedits": "označavanje vraćenih izmena kao izmene bota",
        "right-userrights-interwiki": "uređivanje korisničkih prava na drugim vikijima",
        "right-siteadmin": "zaključavanje i otključavanje baze podataka",
        "right-override-export-depth": "izvoz stranica uključujući i povazene stranice do dubine od pet veza",
-       "right-sendemail": "Pošalji imejl drugim korisnicima",
+       "right-sendemail": "slanje imejla drugim korisnicima",
        "right-managechangetags": "pravljenje i (de)aktiviranje [[Special:Tags|oznaka]]",
+       "right-applychangetags": "primenjivanje [[Special:Tags|oznaka]] na nečije izmene",
+       "right-changetags": "dodavanje i uklanjanje raznih [[Special:Tags|oznaka]] na pojedinačnim izmenama i unosima u dnevnicima",
+       "right-deletechangetags": "brisanje [[Special:Tags|oznaka]] iz baze podataka",
+       "grant-generic": "Skup prava „$1“",
        "grant-group-page-interaction": "Uređivanje stranica",
        "grant-group-file-interaction": "Uređivanje datoteka",
        "grant-group-watchlist-interaction": "Uređivanje vašeg spiska nadgledanja",
-       "grant-group-email": "Slanje e-poruka",
+       "grant-group-email": "Pošalji imejl",
+       "grant-group-high-volume": "Izvršavanje velikog broja radnji",
+       "grant-group-customization": "Prilagođavanje i podešavanja",
+       "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": "Otvaranje naloga",
        "grant-createeditmovepage": "Pravljenje, uređivanje i premeštanje stranica",
        "grant-delete": "Brisanje stranica, izmena i unosa u dnevnicima",
-       "grant-editinterface": "Uređivanje Medijaviki imenskog prostora i korisničkih CSS/JavaScript stranica",
+       "grant-editinterface": "Uređivanje Medijaviki imenskog prostora i korisničkih CSS/JSON/Javaskript stranica",
+       "grant-editmycssjs": "Uređivanje vašeg CSS/JSON/Javaskripta",
+       "grant-editmyoptions": "Uređivanje Vaših podešavanja",
        "grant-editmywatchlist": "Uređivanje vašeg spiska nadgledanja",
        "grant-editpage": "Uređivanje postojećih stranica",
        "grant-editprotected": "Uređivanje zaštićenih stranica",
+       "grant-highvolume": "Masovno uređivanje",
+       "grant-oversight": "Skrivanje korisnika i izmena",
+       "grant-patrol": "Patroliranje izmena",
+       "grant-privateinfo": "Pristupi privatnim informacijama",
+       "grant-protect": "Zaključavanje i otključavanje stranica",
+       "grant-rollback": "Vraćanje izmena",
+       "grant-sendemail": "Slanje imejlova drugim korisnicima",
        "grant-uploadeditmovefile": "Otpremanje, zamena i premeštanje datoteka",
        "grant-uploadfile": "Otpremanje novih datoteka",
+       "grant-basic": "Osnovna prava",
+       "grant-viewdeleted": "Pregled obrisanih stranica i datoteka",
+       "grant-viewmywatchlist": "Pregled vašeg spisak nadgledanja",
+       "grant-viewrestrictedlogs": "Pregledanje ograničenih unosa u dnevniku",
        "newuserlogpage": "Dnevnik novih korisnika",
        "newuserlogpagetext": "Ovo je dnevnik novih korisnika.",
        "rightslog": "Dnevnik korisničkih prava",
        "action-createpage": "pravljenje stranica",
        "action-createtalk": "pravljenje stranica za razgovor",
        "action-createaccount": "otvaranje ovog korisničkog naloga",
+       "action-autocreateaccount": "automatsko pravljenje ovog spoljašnjeg korisničkog naloga",
        "action-history": "gledanje istorije ove stranice",
        "action-minoredit": "označavanje ove izmene kao manje",
        "action-move": "premeštanje ove stranice",
        "action-upload_by_url": "otpremanje ove datoteke preko veb-adrese",
        "action-writeapi": "pisanje API-ja",
        "action-delete": "brisanje ove stranice",
-       "action-deleterevision": "brisanje ove izmene",
-       "action-deletedhistory": "pregledanje obrisane istorije ove stranice",
+       "action-deleterevision": "brisanje izmena",
+       "action-deletelogentry": "birsanje unosa u dnevnicima",
+       "action-deletedhistory": "pregledanje obrisane istorije stranice",
+       "action-deletedtext": "pregled obrisanog teksta izmene",
        "action-browsearchive": "pretraživanje obrisanih stranica",
-       "action-undelete": "vraćanje ove stranice",
-       "action-suppressrevision": "pregledanje i vraćanje ove sakrivene izmene",
+       "action-undelete": "vraćanje stranica",
+       "action-suppressrevision": "pregledanje i vraćanje sakrivenih izmena",
        "action-suppressionlog": "pregledanje ove privatne istorije",
        "action-block": "blokiranje daljih izmena ovog korisnika",
        "action-protect": "menjanje stepena zaštite ove stranice",
        "action-userrights-interwiki": "uređivanje korisničkih prava na drugim vikijima",
        "action-siteadmin": "zaključavanje ili otključavanje baze podataka",
        "action-sendemail": "slanje imejlova",
+       "action-editmyoptions": "uređivanje Vaših podešavanja",
        "action-editmywatchlist": "izmenu sopstvenog spisak nadgledanja",
        "action-viewmywatchlist": "pregled vašeg spisak nadgledanja",
        "action-viewmyprivateinfo": "pregledanje vaših ličnih podataka",
        "action-editmyprivateinfo": "uređivanje vaših ličnih podataka",
-       "action-managechangetags": "pravljenje i/ili brisanje oznaka iz baze podataka",
+       "action-editcontentmodel": "menjanje modela sadržaja stranice",
+       "action-managechangetags": "pravljenje i (de)aktiviranje oznaka",
+       "action-applychangetags": "dodavanje oznaka na vaše izmene",
+       "action-changetags": "dodavanje i uklanjanje raznih oznaka na pojedinačnim izmenama i unosima u dnevnicima",
+       "action-deletechangetags": "Obriši oznake iz baze podataka",
+       "action-purge": "čišćenje privremene memorije ove stranice",
        "nchanges": "$1 {{PLURAL:$1|izmena|izmene|izmena}}",
+       "ntimes": "$1×",
        "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|izmena od vaše poslednje posete}}",
        "enhancedrc-history": "istorija",
        "recentchanges": "Skorašnje izmene",
        "recentchanges-legend": "Opcije skorašnjih izmena",
        "recentchanges-summary": "Pratite skorašnje izmene na ovoj stranici.",
-       "recentchanges-noresult": "Nema promena u zadatom vremenu za zadate kriterijume.",
+       "recentchanges-noresult": "Nema izmena tokom datog perioda a koje odgovaraju ovim kriterijumima.",
+       "recentchanges-timeout": "Ova pretraga je istekla. Možda želite da pokušate drugačije parametre pretrage.",
+       "recentchanges-network": "Zbog tehničkog problema ne mogu da učitam rezultate. Pokušajte da osvežite stranicu.",
        "recentchanges-notargetpage": "Unesite naziv stranice kako biste videli srodne izmene.",
        "recentchanges-feed-description": "Pratite skorašnje izmene uz pomoć ovog dovoda.",
-       "recentchanges-label-newpage": "Nova stranica",
+       "recentchanges-label-newpage": "Ovom izmenom je napravljena nova stranica",
        "recentchanges-label-minor": "Ovo je manja izmena",
        "recentchanges-label-bot": "Ovu izmenu je napravio bot",
        "recentchanges-label-unpatrolled": "Ova izmena još nije patrolirana",
        "recentchanges-label-plusminus": "Promena veličine stranice u bajtovima",
        "recentchanges-legend-heading": "<strong>Legenda:</strong>",
-       "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} ([[Special:NewPages|spisak novih stranica]])",
+       "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (takođe pogledajte [[Special:NewPages|spisak novih stranica]])",
+       "recentchanges-legend-plusminus": "(<em>±123</em>)",
        "recentchanges-submit": "Prikaži",
+       "rcfilters-tag-remove": "Uklonite filter „$1“",
        "rcfilters-legend-heading": "<strong>Spisak skraćenica:</strong>",
-       "rcfilters-other-review-tools": "Ostali alati za pregled:",
+       "rcfilters-other-review-tools": "Druge alatke za pregled",
+       "rcfilters-group-results-by-page": "Grupiši rezultate po stranicama",
        "rcfilters-activefilters": "Aktivni filteri",
+       "rcfilters-activefilters-hide": "Sakrij",
+       "rcfilters-activefilters-show": "Prikaži",
+       "rcfilters-activefilters-hide-tooltip": "Sakrijte područje aktivnih filtera",
+       "rcfilters-activefilters-show-tooltip": "Prikažite područje aktivnih filtera",
        "rcfilters-advancedfilters": "Napredni filteri",
        "rcfilters-limit-title": "Broj izmena za prikaz",
+       "rcfilters-limit-and-date-label": "$1 {{PLURAL:$1|izmena|izmene|izmena}}, $2",
+       "rcfilters-date-popup-title": "Vremenski period za pretragu",
+       "rcfilters-days-title": "Skorašnji dani",
        "rcfilters-hours-title": "Skorašnji sati",
-       "rcfilters-days-show-days": "$1 {{PLURAL:$1|dana|dana}}",
+       "rcfilters-days-show-days": "$1 {{PLURAL:$1|dan|dana}}",
        "rcfilters-days-show-hours": "$1 {{PLURAL:$1|sat|sata}}",
-       "rcfilters-quickfilters-placeholder-description": "Da biste sačuvali svoja podešavanja filtera i upotrebljavali ih kasnije, kliknite na ikonu za oznaku u području aktivnih filtera, ispod.",
-       "rcfilters-search-placeholder": "Filtriraj skorašnje izmene (upotrebite meni ili potražite ime filtera)",
+       "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 svoja podešavanja filtera i ponovo ih upotrebljavali kasnije, kliknite na ikonu za oznaku u području aktivnih filtera — ispod.",
+       "rcfilters-savedqueries-defaultlabel": "Sačuvani filteri",
+       "rcfilters-savedqueries-rename": "Preimenuj",
+       "rcfilters-savedqueries-setdefault": "Postavi kao podrazumevano",
+       "rcfilters-savedqueries-unsetdefault": "Ukloni kao podrazumevano",
+       "rcfilters-savedqueries-remove": "Ukloni",
+       "rcfilters-savedqueries-new-name-label": "Ime",
+       "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čuvajte trenutna podešavanja filtera",
+       "rcfilters-savedqueries-already-saved": "Ovi filteri su već sačuvani. Izmenite Vaša podešavanja da biste napravili nove sačuvane filtere.",
+       "rcfilters-restore-default-filters": "Vrati podrazumevane filtere",
+       "rcfilters-clear-all-filters": "Uklonite sve filtere",
+       "rcfilters-show-new-changes": "Najnovije izmene",
+       "rcfilters-search-placeholder": "Filtrirajte izmene (koristite meni ili pretragu za ime filtera)",
+       "rcfilters-invalid-filter": "Neispravan filter",
+       "rcfilters-empty-filter": "Nema aktivnih filtera. Svi doprinosi su prikazani.",
+       "rcfilters-filterlist-title": "Filteri",
+       "rcfilters-filterlist-whatsthis": "Kako ovo funkcioniše?",
+       "rcfilters-filterlist-feedbacklink": "Recite nam šta mislite o ovim alatkama za filtriranje",
+       "rcfilters-highlightbutton-title": "Istakni rezultate",
+       "rcfilters-highlightmenu-title": "Izbor boje",
+       "rcfilters-highlightmenu-help": "Izaberite boju da biste istaknuli ovo svojstvo",
+       "rcfilters-filterlist-noresults": "Nema pronađenih filtera",
+       "rcfilters-noresults-conflict": "Nije pronađen nijedan rezultat jer su kriterijumi pretrage sukobljeni",
+       "rcfilters-state-message-subset": "Ovaj filter nema efekta jer su njegovi rezultati uključeni sa onima {{PLURAL:$2|sledećeg, šireg filtera|sledećih, širih filtera}} (pokušajte sa označavanjem da biste ih raspoznali): $1",
+       "rcfilters-state-message-fullcoverage": "Odabir svih filtera u grupi je isto kao i odabir nijednog, tako da ovaj filter nema efekta. Grupa uključuje: $1",
        "rcfilters-filtergroup-authorship": "Autorstvo doprinosa",
        "rcfilters-filter-editsbyself-label": "Vaše izmene",
+       "rcfilters-filter-editsbyself-description": "Vaši doprinosi.",
        "rcfilters-filter-editsbyother-label": "Izmene drugih",
        "rcfilters-filter-editsbyother-description": "Sve izmene osim Vaših.",
+       "rcfilters-filtergroup-userExpLevel": "Korisnička registracija i iskustvo",
        "rcfilters-filter-user-experience-level-registered-label": "Registrovani",
        "rcfilters-filter-user-experience-level-registered-description": "Prijavljeni urednici.",
        "rcfilters-filter-user-experience-level-unregistered-label": "Neregistrovani",
        "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": "Manje od 10 izmena i 4 dana aktivnosti.",
+       "rcfilters-filter-user-experience-level-newcomer-description": "Registrovani urednici koji imaju manje od 10 izmena ili 4 dana aktivnosti.",
        "rcfilters-filter-user-experience-level-learner-label": "Učenici",
-       "rcfilters-filter-user-experience-level-learner-description": "Više dana aktivnosti i izmena od „novajlija”, ali manje od „iskusnih korisnika”.",
+       "rcfilters-filter-user-experience-level-learner-description": "Registrovani urednici čije je iskustvo između „novajlija” i „iskusnih korisnika”.",
        "rcfilters-filter-user-experience-level-experienced-label": "Iskusni korisnici",
        "rcfilters-filter-user-experience-level-experienced-description": "Registrovani urednici sa više od 500 izmena i 30 dana aktivnosti.",
-       "rcfilters-filter-bots-description": "Izmene napravljene automatizovanim alatima.",
+       "rcfilters-filtergroup-automated": "Automatizovani doprinosi",
+       "rcfilters-filter-bots-label": "Bot",
+       "rcfilters-filter-bots-description": "Izmene napravljene automatizovanim alatkama.",
        "rcfilters-filter-humans-label": "Čovek (nije bot)",
        "rcfilters-filter-humans-description": "Izmene koje su napravili ljudi-urednici.",
+       "rcfilters-filtergroup-reviewstatus": "Patroliranost",
+       "rcfilters-filter-reviewstatus-unpatrolled-description": "Izmene koje nisu ručno ili automatski označene patroliranim.",
        "rcfilters-filter-reviewstatus-unpatrolled-label": "Nepatrolirano",
+       "rcfilters-filter-reviewstatus-manual-description": "Izmene 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": "Automatski patrolirano",
+       "rcfilters-filtergroup-significance": "Značaj",
        "rcfilters-filter-minor-label": "Manje izmene",
        "rcfilters-filter-minor-description": "Izmene koje je autor označio kao manje.",
        "rcfilters-filter-major-label": "Ne-manje izmene",
        "rcfilters-filter-major-description": "Izmene koje nisu označene kao manje.",
-       "rcfilters-filter-watchlist-watched-description": "Izmene stranica koje su na Vašem spisku nadgledanja.",
+       "rcfilters-filtergroup-watchlist": "Stranice na spisku nadgledanja",
+       "rcfilters-filter-watchlist-watched-label": "Na spisku nadgledanja",
+       "rcfilters-filter-watchlist-watched-description": "Izmene stranica na Vašem spisku nadgledanja.",
        "rcfilters-filter-watchlist-watchednew-label": "Nove izmene na spisku nadgledanja",
        "rcfilters-filter-watchlist-watchednew-description": "Izmene stranica na spisku nadgledanja koje niste posetili od kada su napravljene izmene.",
+       "rcfilters-filter-watchlist-notwatched-label": "Nije na spisku nadgledanja",
        "rcfilters-filter-watchlist-notwatched-description": "Sve osim izmena stranica na Vašem spisku nadgledanja.",
-       "rcfilters-filtergroup-changetype": "Vrsta izmene",
+       "rcfilters-filtergroup-watchlistactivity": "Stanje na spisku nadgledanja",
+       "rcfilters-filter-watchlistactivity-unseen-label": "Nepogledane izmene",
+       "rcfilters-filter-watchlistactivity-unseen-description": "Izmene stranica koje niste posetili od kada su napravljene izmene.",
+       "rcfilters-filter-watchlistactivity-seen-label": "Pogledane izmene",
+       "rcfilters-filter-watchlistactivity-seen-description": "Izmene stranica koje ste posetili od kada su napravljene izmene.",
+       "rcfilters-filtergroup-changetype": "Tip izmene",
        "rcfilters-filter-pageedits-label": "Izmene stranica",
-       "rcfilters-filter-pageedits-description": "Izmene viki sadržaja, rasprava, opisa kategorija...",
-       "rcfilters-filter-newpages-label": "Stvaranje stranica",
-       "rcfilters-filter-newpages-description": "Izmene kojima se stvaraju nove stranice.",
+       "rcfilters-filter-pageedits-description": "Izmene viki sadržaja, rasprava, opisa kategorija",
+       "rcfilters-filter-newpages-label": "Pravljenje stranica",
+       "rcfilters-filter-newpages-description": "Izmene kojima se prave nove stranice.",
        "rcfilters-filter-categorization-label": "Izmene kategorija",
-       "rcfilters-filter-logactions-label": "Radnje zabeležene u dnevnicima",
+       "rcfilters-filter-categorization-description": "Zapisi o stranicama dodatim ili uklonjenim iz kategorija.",
+       "rcfilters-filter-logactions-label": "Zabeležene radnje",
+       "rcfilters-filter-logactions-description": "Administrativne radnje, pravljenje naloga, brisanje stranica, otpremanja…",
+       "rcfilters-hideminor-conflicts-typeofchange-global": "Filter za „manje” izmene je u sukobu sa jednim ili više filtera tipa izmena, zato što određeni tipovi izmena ne mogu da se označe kao „manje”. Sukobljeni filteri su označeni u području Aktivni filteri, iznad.",
+       "rcfilters-hideminor-conflicts-typeofchange": "Određeni tipovi izmena ne mogu da se označe kao „manje”, tako da je ovaj filter u sukobu sa sledećim filterima tipa izmena: $1",
+       "rcfilters-typeofchange-conflicts-hideminor": "Ovaj filter tipa izmene je u sukobu sa filterom za „manje” izmene. Određeni tipovi izmena ne mogu da se označe kao „manje”.",
        "rcfilters-filtergroup-lastRevision": "Poslednje izmene",
        "rcfilters-filter-lastrevision-label": "Poslednja izmena",
+       "rcfilters-filter-lastrevision-description": "Samo najnovija izmena na stranici.",
        "rcfilters-filter-previousrevision-label": "Nije poslednja izmena",
        "rcfilters-filter-previousrevision-description": "Sve izmene koje nisu „poslednje izmene”.",
+       "rcfilters-filter-excluded": "Izostavljeno",
+       "rcfilters-tag-prefix-namespace-inverted": "<strong>:nije</strong> $1",
+       "rcfilters-exclude-button-off": "Izostavi označeno",
+       "rcfilters-exclude-button-on": "Izostavi odabrano",
        "rcfilters-view-tags": "Označene izmene",
-       "rcfilters-view-namespaces-tooltip": "Filter rezultata prema imenskom prostoru",
-       "rcfilters-view-tags-tooltip": "Filtriranje rezultata prema oznaci izmene",
+       "rcfilters-view-namespaces-tooltip": "Filtrirajte rezultate prema imenskom prostoru",
+       "rcfilters-view-tags-tooltip": "Filtrirajte rezultate prema oznaci izmene",
+       "rcfilters-view-return-to-default-tooltip": "Povratak na glavni meni",
        "rcfilters-view-tags-help-icon-tooltip": "Saznajte više o označenim izmenama",
-       "rcfilters-liveupdates-button": "Ažuriranja uživo",
-       "rcfilters-watchlist-markseen-button": "Označi sve izmene kao viđene",
-       "rcfilters-watchlist-showupdated": "Izmene na stranicama koje niste posetili od kada je izmena izvršena su <strong>podebljane</strong>, sa ispunjenim oznakama.",
+       "rcfilters-liveupdates-button": "Ažuriraj uživo",
+       "rcfilters-liveupdates-button-title-on": "Isključite ažuriranja uživo",
+       "rcfilters-liveupdates-button-title-off": "Prikažite nove izmene uživo",
+       "rcfilters-watchlist-markseen-button": "Označi sve izmene kao pogledane",
+       "rcfilters-watchlist-edit-watchlist-button": "Promeni spisak nadgledanih stranica",
+       "rcfilters-watchlist-showupdated": "Izmene stranica koje niste posetili od kada je izmena izvršena su <strong>podebljane</strong>, sa ispunjenim oznakama.",
        "rcfilters-preference-label": "Sakrij poboljšanu verziju skorašnjih izmena",
        "rcfilters-preference-help": "Poništava redizajn interfejsa iz 2017. i sve alatke dodate tada i posle.",
+       "rcfilters-watchlist-preference-label": "Sakrij poboljšanu verziju spiska nadgledanja",
+       "rcfilters-filter-showlinkedfrom-label": "Prikaži izmene 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 izmene 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 izmena|su izmene}} od <strong>$3, $4</strong> (do <strong>$1</strong> prikazano).",
-       "rclistfrom": "Prikaži nove izmene počev od $2 $3",
+       "rclistfromreset": "Resetuj odabir datuma",
+       "rclistfrom": "Prikaži nove izmene počev od $2, $3",
        "rcshowhideminor": "$1 manje izmene",
        "rcshowhideminor-show": "Prikaži",
        "rcshowhideminor-hide": "Sakrij",
        "recentchangeslinked-feed": "Srodne izmene",
        "recentchangeslinked-toolbox": "Srodne izmene",
        "recentchangeslinked-title": "Srodne izmene sa „$1“",
-       "recentchangeslinked-summary": "Ova posebna stranica prikazuje spisak poslednjih izmena na stranicama koje su povezane (ili članovi određene kategorije).\nStranice s [[Special:Watchlist|vašeg spiska nadgledanja]] su '''podebljane'''.",
+       "recentchangeslinked-summary": "Unesite ime stranice da biste videli promene na stranicama koje su povezane sa ili sa te stranice. (Da biste videli članove kategorije, unesite {{ns:category}}:Ime kategorije). Promene na stranicama koje su na [[Special:Watchlist|Vašem spisku nadgledanja]] su <strong>podebljane</strong>.",
        "recentchangeslinked-page": "Naziv stranice:",
        "recentchangeslinked-to": "Prikaži izmene stranica koje su povezane s datom stranicom",
        "recentchanges-page-added-to-category": "[[:$1]] je dodata u kategoriju",
-       "recentchanges-page-added-to-category-bundled": "[[:$1]] i još [[Special:WhatLinksHere/$1|{{PLURAL:$2|jedna stranica|$2 stranice}}]] su dodate u kategoriju",
+       "recentchanges-page-added-to-category-bundled": "[[:$1]] je dodana u kategoriju, [[Special:WhatLinksHere/$1|ova stranica je povezana sa drugim stranicama]]",
        "recentchanges-page-removed-from-category": "[[:$1]] je uklonjena iz kategorije",
-       "recentchanges-page-removed-from-category-bundled": "[[:$1]] i još [[Special:WhatLinksHere/$1|{{PLURAL:$2|jedna stranica|$2 stranice}}]] su uklonjene iz kategorije",
+       "recentchanges-page-removed-from-category-bundled": "[[:$1]] je uklonjena iz kategorije, [[Special:WhatLinksHere/$1|ova stranica je povezana sa drugim stranicama]]",
        "autochange-username": "Medijaviki automatska izmena",
-       "upload": "Otpremi datoteku",
+       "upload": "Otpremanje datoteke",
        "uploadbtn": "Otpremi datoteku",
        "reuploaddesc": "Nazad na obrazac za otpremanje",
        "upload-tryagain": "Pošalji izmenjeni opis datoteke",
+       "upload-tryagain-nostash": "Pošaljite re-otpremljenu datoteku i izmenjen opis",
        "uploadnologin": "Niste prijavljeni",
        "uploadnologintext": "Morate biti $1 da biste otpremali datoteke.",
        "upload_directory_missing": "Fascikla za slanje ($1) nedostaje i server je ne može napraviti.",
        "windows-nonascii-filename": "Ovaj viki ne podržava nazive datoteka s posebnim znacima.",
        "fileexists": "Datoteka s ovim nazivom već postoji. Pogledajte <strong>[[:$1]]</strong> ako niste sigurni da li želite da je promenite.\n[[$1|thumb]]",
        "filepageexists": "Stranica s opisom ove datoteke je već napravljena ovde <strong>[[:$1]]</strong>, iako datoteka ne postoji.\nOpis koji ste naveli se neće pojaviti na stranici s opisom.\nDa bi se vaš opis ovde našao, potrebno je da ga ručno izmenite.\n[[$1|thumb]]",
-       "fileexists-extension": "Datoteka sa sličnim nazivom već postoji: [[$2|thumb]]\n* Naziv datoteke koju šaljete: <strong>[[:$1]]</strong>\n* Naziv postojeće datoteke: <strong>[[:$2]]</strong>\nIzaberite drugačiji naziv.",
+       "fileexists-extension": "Datoteka sa sličnim nazivom već postoji: [[$2|thumb]]\n* Naziv datoteke koju šaljete: <strong>[[:$1]]</strong>\n* Naziv postojeće datoteke: <strong>[[:$2]]</strong>\nDa li želite da koristite prepoznatljivije ime?",
        "fileexists-thumbnail-yes": "Izgleda da je datoteka umanjeno izdanje slike ''(thumbnail)''.\n[[$1|thumb]]\nProverite datoteku <strong>[[:$1]]</strong>.\nAko je proverena datoteka ista slika originalne veličine, nije potrebno slati dodatnu sliku.",
        "file-thumbnail-no": "Datoteka počinje sa <strong>$1</strong>.\nIzgleda da se radi o umanjenoj slici ''(thumbnail)''.\nUkoliko imate ovu sliku u punoj veličini, pošaljite je, a ako nemate, promenite naziv datoteke.",
        "fileexists-forbidden": "Datoteka s ovim nazivom već postoji i ne može se zameniti.\nAko i dalje želite da pošaljete datoteku, vratite se i izaberite drugi naziv.\n[[File:$1|thumb|center|$1]]",
        "fileexists-shared-forbidden": "Datoteka s ovim nazivom već postoji u zajedničkoj ostavi.\nVratite se i pošaljite datoteku s drugim nazivom.\n[[File:$1|thumb|center|$1]]",
+       "fileexists-no-change": "Datoteka je duplikat trenutne verzije <strong>[[:$1]]</strong>.",
+       "fileexists-duplicate-version": "Datoteka je duplikat {{PLURAL:$2|stare verzije|starih verzija}} <strong>[[:$1]]</strong>.",
        "file-exists-duplicate": "Ovo je duplikat {{PLURAL:$1|sledeće datoteke|sledećih datoteka}}:",
        "file-deleted-duplicate": "Datoteka istovetna ovoj ([[:$1]]) je prethodno obrisana.\nPogledajte istoriju brisanja pre ponovnog slanja.",
+       "file-deleted-duplicate-notitle": "Datoteka identična ovoj prethodno je obrisana i ime joj je sakriveno.\nTrebali biste pitati nekoga ko može videti podatke skrivenih datoteka da pregleda situaciju pre nego što ponovo otpremite datoteku.",
        "uploadwarning": "Upozorenje pri otpremanju",
        "uploadwarning-text": "Izmenite opis datoteke i pokušajte ponovo.",
+       "uploadwarning-text-nostash": "Re-otpremite datoteku, izmenite opis ispod i pokušajte ponovo.",
        "savefile": "Sačuvaj datoteku",
        "uploaddisabled": "Otpremanje je onemogućeno.",
        "copyuploaddisabled": "Otpremanje putem veb-adrese je onemogućeno.",
        "uploaddisabledtext": "Otpremanje datoteka je onemogućeno.",
        "php-uploaddisabledtext": "Otpremanje datoteka je onemogućeno u PHP-u.\nProverite podešavanja file_uploads.",
-       "uploadscripted": "Datoteka sadrži HTML ili skriptni kod koji može biti pogrešno protumačen od strane pregledača.",
+       "uploadscripted": "Datoteka sadrži HTML ili skriptni kôd koji može biti pogrešno protumačen od strane pregledača.",
+       "upload-scripted-pi-callback": "Datoteka koja sadrži instrukcije za obradu XML stilskog oblika se ne može otpremiti.",
+       "upload-scripted-dtd": "Nije moguće otpremanje SVG datoteka koje sadrže nestandardnu DTD deklaraciju.",
+       "uploaded-script-svg": "Pronađen skriptni elemenat „$1“ u postavljenoj SVG datoteci.",
+       "uploaded-hostile-svg": "Pronađen nebezbedan CSS u stilskom elementu postavljene SVG datoteke.",
+       "uploaded-event-handler-on-svg": "Nije dozvoljeno postavljanje atributa koji kontrolišu događaje <code>$1=\"$2\"</code> u SVG datotekama.",
+       "uploaded-href-unsafe-target-svg": "Pronađen href sa nesigurnim podacima: URI odredište <code>&lt;$1 $2=\"$3\"&gt;</code> u postavljenoj SVG datoteci.",
+       "uploaded-animate-svg": "Pronađena „animate“ oznaka koja možda menja href koristeći se „from“ atributom <code>&lt;$1 $2=\"$3\"&gt;</code> u postavljenoj SVG datoteci.",
        "uploadscriptednamespace": "Ova SVG datoteka sadrži pogrešan imenski prostor „<nowiki>$1</nowiki>“",
+       "uploadinvalidxml": "Nije moguće raščlaniti XML otpremljene datoteke.",
        "uploadvirus": "Datoteka sadrži virus!\nDetalji: $1",
        "uploadjava": "Datoteka je formata ZIP koji sadrži java .class element.\nSlanje java datoteka nije dozvoljeno jer one mogu izazvati zaobilaženje sigurnosnih ograničenja.",
        "upload-source": "Izvorna datoteka",
        "destfilename": "Naziv:",
        "upload-maxfilesize": "Maksimalna veličina datoteke: $1",
        "upload-description": "Opis datoteke",
-       "upload-options": "Postavke otpremanja",
+       "upload-options": "Opcije otpremanja",
        "watchthisupload": "Nadgledaj ovu datoteku",
        "filewasdeleted": "Datoteka s ovim nazivom je ranije poslata, ali je obrisana.\nProverite $1 pre nego što nastavite s ponovnim slanjem.",
        "filename-bad-prefix": "Naziv datoteke koju šaljete počinje sa <strong>„$1“</strong>, a njega obično dodeljuju digitalni fotoaparati.\nIzaberite naziv datoteke koji opisuje njen sadržaj.",
        "upload-too-many-redirects": "Adresa sadrži previše preusmerenja",
        "upload-http-error": "Došlo je do HTTP greške: $1",
        "upload-copy-upload-invalid-domain": "Primerci otpremanja nisu dostupni na ovom domenu.",
-       "upload-dialog-title": "Otpremanje datoteka",
+       "upload-dialog-disabled": "Postavljanje datoteka pomoću ovog dijaloga je onemogućeno na ovom vikiju.",
+       "upload-dialog-title": "Otpremi datoteku",
        "upload-dialog-button-cancel": "Otkaži",
+       "upload-dialog-button-back": "Nazad",
        "upload-dialog-button-done": "Gotovo",
        "upload-dialog-button-save": "Sačuvaj",
        "upload-dialog-button-upload": "Otpremi",
        "upload-form-label-infoform-title": "Detalji",
-       "upload-form-label-infoform-name": "Ime",
+       "upload-form-label-infoform-name": "Naziv",
        "upload-form-label-infoform-description": "Opis",
+       "upload-form-label-usage-title": "Upotrebe",
        "upload-form-label-usage-filename": "Naziv datoteke",
        "upload-form-label-own-work": "Ovo je moje sopstveno delo",
        "upload-form-label-infoform-categories": "Kategorije",
        "upload-form-label-infoform-date": "Datum",
+       "upload-form-label-not-own-work-local-generic-local": "Takođe možete pokušati [[Special:Upload|podrazumevanu stranicu za otpremanje]].",
        "backend-fail-stream": "Ne mogu da emitujem datoteku $1.",
        "backend-fail-backup": "Ne mogu da napravim rezervu datoteke $1.",
        "backend-fail-notexists": "Datoteka $1 ne postoji.",
        "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 se zaključam za „$1“.",
-       "lockmanager-fail-openlock": "Ne mogu da otvorim katanac za „$1“.",
+       "lockmanager-fail-openlock": "Ne mogu da otvorim katanac za „$1“. Uverite se da je Vaš direktorijum za otpremanje ispravno konfigurisan i da Vaš veb-server ima dozvolu da piše u tom direktorijumu. Pogledajte https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgUploadDirectory za više informacija.",
        "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 pruža pristup datotekama koje su otpremljene ili se otpremaju, ali još nisu objavljene. Ove datoteke nisu vidljive nikome, osim korisniku koji ih je otpremio.",
        "uploadstash-clear": "Očisti sakrivene datoteke",
        "uploadstash-nofiles": "Nemate sakrivene datoteke.",
-       "uploadstash-badtoken": "Izvršavanje date radnje nije uspelo. Razlog tome može biti istek vremena za uređivanje. Pokušajte ponovo.",
+       "uploadstash-badtoken": "Izvršavanje ove radnje nije uspelo, razlog tome može biti istek vremena za uređivanje. Pokušajte ponovo.",
        "uploadstash-errclear": "Čišćenje datoteka nije uspelo.",
        "uploadstash-refresh": "Osveži spisak datoteka",
+       "uploadstash-thumbnail": "pogledaj minijaturu",
+       "uploadstash-exception": "Ne mogu sačuvati datoteku u skladište ($1): „$2“.",
+       "uploadstash-bad-path": "Putanja ne postoji.",
+       "uploadstash-bad-path-invalid": "Putanja nije ispravna.",
+       "uploadstash-bad-path-unknown-type": "Nepoznat tip „$1“.",
+       "uploadstash-bad-path-unrecognized-thumb-name": "Neprepoznato ime minijature.",
+       "uploadstash-bad-path-bad-format": "Ključ „$1“ nije u odgovarajućem obliku.",
+       "uploadstash-file-not-found-no-thumb": "Ne mogu dobiti minijaturu.",
+       "uploadstash-file-not-found-no-local-path": "Nema lokalne putanje za umanjenu stavku.",
+       "uploadstash-file-not-found-no-object": "Ne mogu napraviti lokalni datotečni objekat za minijaturu.",
+       "uploadstash-file-not-found-no-remote-thumb": "Dobavljanje minijature nije uspelo: $1\nAdresa = $2",
+       "uploadstash-file-not-found-missing-content-type": "Nedostaje zaglavlje za vrstu sadržaja.",
+       "uploadstash-file-not-found-not-exists": "Ne mogu naći putanju ili ovo nije obična datoteka.",
+       "uploadstash-file-too-large": "Ne mogu poslužiti datoteku veću od $1 {{PLURAL:$1|bajta|bajtova}}",
+       "uploadstash-not-logged-in": "Niko nije prijavljen. 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": "Nema traženog dodatka.",
+       "uploadstash-zero-length": "Datoteka je prazna",
        "invalid-chunk-offset": "Neispravna polazna tačka",
        "img-auth-accessdenied": "Pristup je odbijen",
        "img-auth-nopathinfo": "Nedostaje PATH_INFO.\nVaš server nije podešen da prosleđuje ovakve podatke.\nMožda je zasnovan na CGI-ju koji ne podržava img_auth.\nPogledajte https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization?uselang=sr-ec.",
        "img-auth-nologinnWL": "Niste prijavljeni i „$1” nije na spisku dozvoljenih.",
        "img-auth-nofile": "Datoteka „$1“ ne postoji.",
        "img-auth-isdir": "Pokušavate da pristupite fascikli „$1“.\nDozvoljen je samo pristup datotekama.",
-       "img-auth-streaming": "Učitavanje „$1“.",
+       "img-auth-streaming": "Učitavam „$1“...",
        "img-auth-public": "Svrha img_auth.php je da prosleđuje datoteke iz privatnih vikija.\nOvaj viki je postavljen kao javni.\nRadi sigurnosti, img_auth.php je onemogućen.",
        "img-auth-noread": "Korisnik nema pristup za čitanje „$1“.",
        "http-invalid-url": "Neispravna adresa: $1",
        "upload-curl-error28": "Otpremanje je isteklo",
        "upload-curl-error28-text": "Server ne odgovara na upit.\nProverite da li sajt radi, malo osačekajte i pokušajte ponovo.\nProbajte kasnije kada bude manje opterećenje.",
        "license": "Licenca:",
-       "license-header": "Licenca:",
+       "license-header": "Licenciranje",
        "nolicense": "Nije izabrano",
        "licenses-edit": "Uredi izbor licenci",
        "license-nopreview": "(pregled nije dostupan)",
        "upload_source_url": "(vaša izabrana datoteka od ispravnih i javno dostupnih adresa)",
        "upload_source_file": "(vaša odabrana datoteka sa vašeg računara)",
        "listfiles-delete": "obriši",
-       "listfiles-summary": "Ova posebna stranica prikazuje sve poslate datoteke.",
+       "listfiles-summary": "Ova posebna stranica prikazuje sve otpremljene datoteke.",
        "listfiles_search_for": "Naziv datoteke:",
-       "listfiles-userdoesnotexist": "Korisnički nalog „$1“ nije registrovan.",
+       "listfiles-userdoesnotexist": "Korisnički nalog „$1“ nije otvoren.",
        "imgfile": "datoteka",
        "listfiles": "Spisak datoteka",
        "listfiles_thumb": "Minijatura",
        "listfiles_size": "Veličina",
        "listfiles_description": "Opis",
        "listfiles_count": "Verzije",
-       "listfiles-show-all": "Obuhvati stare verzije slika",
+       "listfiles-show-all": "Obuhvati stare verzije datoteka",
        "listfiles-latestversion": "Trenutna verzija",
        "listfiles-latestversion-yes": "Da",
        "listfiles-latestversion-no": "Ne",
        "filehist-revert": "vrati",
        "filehist-current": "trenutno",
        "filehist-datetime": "Datum/vreme",
-       "filehist-thumb": "Umanjeni prikaz",
-       "filehist-thumbtext": "Umanjeni prikaz za izdanje od $1",
+       "filehist-thumb": "Minijatura",
+       "filehist-thumbtext": "Minijatura za verziju na dan $1",
        "filehist-nothumb": "Nema umanjenog prikaza",
        "filehist-user": "Korisnik",
        "filehist-dimensions": "Dimenzije",
        "filehist-comment": "Komentar",
        "imagelinks": "Upotreba datoteke",
        "linkstoimage": "{{PLURAL:$1|Sledeća stranica koristi|$1 sledeće stranice koriste|$1 sledećih stranica koristi}} ovu datoteku:",
-       "linkstoimage-more": "Više od $1 {{PLURAL:$1|stranice|stranice|stranica}} je povezano s ovom datotekom.\nSledeći spisak prikazuje samo {{PLURAL:$1|prvu stranicu povezanu|prve $1 stranice povezane|prvih $1 stranica povezanih}} s ovom datotekom.\nDostupan je i [[Special:WhatLinksHere/$2|potpuni spisak]].",
+       "linkstoimage-more": "Više od $1 {{PLURAL:$1|stranica|stranice|stranica}} je povezano s ovom datotekom.\nSledeći spisak prikazuje samo {{PLURAL:$1|prvu stranicu povezanu|prve $1 stranice povezane|prvih $1 stranica povezanih}} s ovom datotekom.\nDostupan je i [[Special:WhatLinksHere/$2|potpuni spisak]].",
        "nolinkstoimage": "Nema stranica koje koriste ovu datoteku.",
        "morelinkstoimage": "Pogledajte [[Special:WhatLinksHere/$1|više veza]] do ove datoteke.",
        "linkstoimage-redirect": "$1 (preusmerenje datoteke) $2",
        "filerevert-submit": "Vrati",
        "filerevert-success": "Datoteka '''[[Media:$1|$1]]''' je vraćena na [$4 izdanje od $2; $3].",
        "filerevert-badversion": "Ne postoji ranije lokalno izdanje datoteke s navedenim vremenskim podacima.",
+       "filerevert-identical": "Trenutna izmena datoteke indentična je izabranoj.",
        "filedelete": "Obriši $1",
        "filedelete-legend": "Obriši datoteku",
        "filedelete-intro": "Brišete datoteku '''[[Media:$1|$1]]''' zajedno s njenom istorijom.",
        "pageswithprop-legend": "Strane s osobinom strane",
        "pageswithprop-text": "Ova strana izlistava strane koje imaju određenu osobinu",
        "pageswithprop-prop": "Ime osobine:",
+       "pageswithprop-reverse": "Poređaj u suprotnom redosledu",
+       "pageswithprop-sortbyvalue": "Poređaj prema svojstvima",
        "pageswithprop-submit": "Idi",
+       "pageswithprop-prophidden-long": "sakriveno dugo tekstualno svojstvo ($1)",
+       "pageswithprop-prophidden-binary": "sakriveno dugo binarno svojstvo ($1)",
        "doubleredirects": "Dvostruka preusmerenja",
        "doubleredirectstext": "Ova stranica prikazuje stranice koje preusmeravaju na druga preusmerenja.\nSvaki red sadrži veze prema prvom i drugom preusmerenju, kao i odredišnu stranicu drugog preusmerenja koja je obično „pravi“ članak na koga prvo preusmerenje treba da upućuje.\n<del>Precrtani</del> unosi su već rešeni.",
        "double-redirect-fixed-move": "[[$1]] je premešten.\nAutomatski je ažurirano i sada preusmerava na [[$2]].",
-       "double-redirect-fixed-maintenance": "Automatski ispravlja dvostruka preusmerenja iz [[$1]] u [[$2]]. Kao deo održavanja.",
+       "double-redirect-fixed-maintenance": "Automatski ispravlja dvostruka preusmerenja iz [[$1]] u [[$2]] kao deo održavanja",
        "double-redirect-fixer": "Ispravljač preusmerenja",
        "brokenredirects": "Pokvarena preusmerenja",
        "brokenredirectstext": "Sledeća preusmerenja upućuju na nepostojeće stranice:",
        "deadendpages": "Stranice bez unutrašnjih veza",
        "deadendpagestext": "Sledeće stranice nemaju veze do drugih stranica na ovom vikiju.",
        "protectedpages": "Zaštićene stranice",
+       "protectedpages-filters": "Filteri:",
        "protectedpages-indef": "Samo neograničene zaštite",
        "protectedpages-summary": "Na ovoj stranici se nalazi spisak trenutno zaštićenih stranica. Za spisak zaštićenih naslova vidi [[{{#special:ProtectedTitles}}|{{int:protectedtitles}}]].",
        "protectedpages-cascade": "Samo prenosive zaštite",
        "protectedtitles-submit": "Prikaži naslove",
        "listusers": "Spisak korisnika",
        "listusers-editsonly": "Prikaži samo korisnike koji su uređivali",
+       "listusers-temporarygroupsonly": "Prikaži samo korisnike u privremenim korisničkim grupama",
        "listusers-creationsort": "Poređaj po datumu stvaranja",
-       "listusers-desc": "Sortiraj u opadajućem redosledu",
+       "listusers-desc": "Poređaj u opadajućem redosledu",
        "usereditcount": "$1 {{PLURAL:$1|izmena|izmene|izmena}}",
        "usercreated": "{{GENDER:$3|je napravio|je napravila|je napravio}} dana $1 u $2",
        "newpages": "Nove stranice",
        "nopagetitle": "Ne postoji takva stranica",
        "nopagetext": "Tražena stranica ne postoji.",
        "pager-newer-n": "{{PLURAL:$1|noviji 1|novija $1|novijih $1}}",
-       "pager-older-n": "{{PLURAL:$1|stariji 1|starijih $1}}",
+       "pager-older-n": "{{PLURAL:$1|stariji 1|starija $1|starijih $1}}",
        "suppress": "Potisni",
        "querypage-disabled": "Ova posebna stranica je onemogućena radi poboljšanja performansi.",
        "apihelp": "API pomoć",
        "apihelp-no-such-module": "Modul „$1“ nije pronađen.",
        "apisandbox": "API pesak",
+       "apisandbox-jsonly": "JavaScript je neophodan za korišćenje API peska.",
        "apisandbox-api-disabled": "API je onemogućen na ovom sajtu.",
-       "apisandbox-submit": "Postavi zahtev",
+       "apisandbox-submit": "Pošalji zahtev",
+       "apisandbox-reset": "Očisti",
+       "apisandbox-retry": "Pokušaj ponovo",
+       "apisandbox-loading": "Učitavam informacije za API modul „$1”...",
+       "apisandbox-load-error": "Došlo je do greške prilikom učitavanja informacija za API modul \"$1\": $2",
+       "apisandbox-no-parameters": "Ovaj API modul nema parametre.",
+       "apisandbox-helpurls": "Linkovi za pomoć",
+       "apisandbox-examples": "Primeri",
+       "apisandbox-dynamic-parameters": "Dodatni parametri",
+       "apisandbox-dynamic-parameters-add-label": "Dodaj parametar:",
+       "apisandbox-dynamic-parameters-add-placeholder": "Naziv parametra",
+       "apisandbox-dynamic-error-exists": "Parametar pod nazivom \"$1\" već postoji.",
+       "apisandbox-deprecated-parameters": "Zastareli parametri",
+       "apisandbox-fetch-token": "Automatski popuni token",
+       "apisandbox-add-multi": "Dodaj",
+       "apisandbox-submit-invalid-fields-title": "Neka polja nisu ispravna",
+       "apisandbox-submit-invalid-fields-message": "Molimo Vas popravite označena polja i pokušajte ponovo.",
        "apisandbox-results": "Rezultati",
+       "apisandbox-sending-request": "Slanje API zahteva...",
+       "apisandbox-loading-results": "Prijem API rezultata...",
+       "apisandbox-results-error": "Došlo je do greške prilikom učitavanja rezultata API upita: $1.",
+       "apisandbox-request-selectformat-label": "Prikaži sahtevane podatke kao:",
        "apisandbox-request-url-label": "Adresa zahteva:",
+       "apisandbox-request-format-json-label": "JSON",
+       "apisandbox-request-json-label": "Zatražite JSON:",
+       "apisandbox-request-time": "Vreme za izvršavanje zahtjeva: {{PLURAL:$1|$1 milisekunda|$1 milisekunde|$1 milisekundi}}",
+       "apisandbox-results-fixtoken": "Ispravi žeton i pošalji ponovo",
+       "apisandbox-results-fixtoken-fail": "Nisam uspeo da dobijem žeton „$1“.",
+       "apisandbox-alert-page": "Polja na stranici su neispravna.",
+       "apisandbox-alert-field": "Vrednost ovog polja je neispravna.",
+       "apisandbox-continue": "Nastavi",
+       "apisandbox-continue-clear": "Očisti",
+       "apisandbox-param-limit": "Unesite <kbd>max</kbd> da bi ste koristili najveće ograničenje.",
+       "apisandbox-multivalue-all-namespaces": "$1 (svi imenski prostori)",
+       "apisandbox-multivalue-all-values": "$1 (sve vrednosti)",
        "booksources": "Štampani izvori",
-       "booksources-search-legend": "Traži književne izvore",
+       "booksources-search-legend": "Pretraži štampane izvore",
        "booksources-isbn": "ISBN:",
        "booksources-search": "Pretraži",
        "booksources-text": "Ispod se nalazi spisak veza ka sajtovima koji se bave prodajom novih i polovnih knjiga, a koji bi mogli imati dodatne podatke o knjigama koje tražite:",
        "booksources-invalid-isbn": "Navedeni ISBN broj nije ispravan. Proverite da nije došlo do greške pri umnožavanju iz prvobitnog izvora.",
+       "magiclink-tracking-rfc": "Stranice s magičnim RFC vezama",
+       "magiclink-tracking-pmid": "Stranice s magičnim PMID vezama",
        "magiclink-tracking-isbn": "Stranice sa ISBN magičnim vezama",
        "specialloguserlabel": "Izvršilac:",
        "speciallogtitlelabel": "Cilj (naslov ili {{ns:user}}:korisničko ime):",
        "log": "Dnevnici",
        "logeventslist-submit": "Prikaži",
+       "logeventslist-more-filters": "Prikaz dodatnih dnevnika:",
        "all-logs-page": "Svi javni dnevnici",
        "alllogstext": "Skupni prikaz svih dostupnih istorija ovog vikija.\nMožete suziti prikaz odabirući vrstu istorije, korisničkog imena ili tražene stranice.",
        "logempty": "Nema pronađenih unosa u dnevniku.",
        "deletedcontributions": "Obrisani korisnički doprinosi",
        "deletedcontributions-title": "Obrisani korisnički doprinosi",
        "sp-deletedcontributions-contribs": "doprinosi",
-       "linksearch": "Pretraga spoljnih veza",
+       "linksearch": "Pretraga spoljašnjih veza",
        "linksearch-pat": "Obrazac pretrage:",
        "linksearch-ns": "Imenski prostor:",
        "linksearch-ok": "Pretraži",
        "activeusers-intro": "Ovo je spisak korisnika koji su bili aktivni {{PLURAL:$1|1=prethodni dan|u poslednja $1 dana|u poslednjih $1 dana}}.",
        "activeusers-count": "$1 {{PLURAL:$1|radnja|radnje|radnji}} {{PLURAL:$3|prethodni dan|u poslednja $3 dana|u poslednjih $3 dana}}",
        "activeusers-from": "Prikaži korisnike počev od:",
+       "activeusers-groups": "Prikaži korisnike koji su članovi grupa:",
+       "activeusers-excludegroups": "Izuzmi korisnike koji su članovi grupa:",
        "activeusers-noresult": "Korisnik nije pronađen.",
        "activeusers-submit": "Prikaži aktivne korisnike",
        "listgrouprights": "Prava korisničkih grupa",
        "listgrouprights-namespaceprotection-namespace": "Imenski prostor",
        "listgrouprights-namespaceprotection-restrictedto": "Prava potrebna za uređivanje",
        "listgrants": "Dozvole",
+       "listgrants-grant": "Dozvola",
        "listgrants-rights": "Prava",
        "trackingcategories": "Medijaviki kategorije",
        "trackingcategories-summary": "Ova posebna stranica je spisak kategorija koje su deo Medijavikija, one se automatski ažuriraju i njihovi nazivi se mogu menjati uređivanjem sistemskih poruka u imenskom prostoru {{ns:8}}.",
+       "trackingcategories-msg": "Praćenje kategorije",
        "trackingcategories-name": "Ime poruke",
        "trackingcategories-desc": "Koje stranice se nalaze u kategoriji",
+       "restricted-displaytitle-ignored": "Stranice sa zanemarenim naslovima za prikaz",
        "noindex-category-desc": "Stranice koje u sebi imaju magičnu reč <code><nowiki>__NOINDEX__</nowiki></code>.",
        "index-category-desc": "Stranice koje u sebi imaju magičnu reč <code><nowiki>__INDEX__</nowiki></code> i samim tim su indeksirane od strane robota.",
        "broken-file-category-desc": "Stranice koje imaju veze do nepostojećih datoteka.",
        "trackingcategories-nodesc": "Opis nije dostupan.",
        "trackingcategories-disabled": "Kategorija je onemogućena",
        "mailnologin": "Nema adrese za slanje",
-       "mailnologintext": "Morate biti [[Special:UserLogin|prijavljeni]] i imati ispravnu imejl adresu u [[Special:Preferences|podešavanjima]] da biste slali imejlove drugim korisnicima.",
+       "mailnologintext": "Morate biti [[Special:UserLogin|prijavljeni]] i imati ispravan imejl adresu u [[Special:Preferences|podešavanjima]] da biste slali imejlove drugim korisnicima.",
        "emailuser": "Pošalji imejl",
        "emailuser-title-target": "Slanje imejla {{GENDER:$1|korisniku|korisnici}}",
        "emailuser-title-notarget": "Slanje imejla korisniku",
        "mywatchlist": "Spisak nadgledanja",
        "watchlistfor2": "Za $1 $2",
        "nowatchlist": "Vaš spisak nadgledanja je prazan.",
-       "watchlistanontext": "Morate biti $1 da biste gledali i uređivali stavke na vašem spisku nadgledanja.",
+       "watchlistanontext": "Morate biti prijavljeni da biste gledali i uređivali stavke na vašem spisku nadgledanja.",
        "watchnologin": "Niste prijavljeni",
        "addwatch": "Dodaj na spisak nadgledanja",
        "addedwatchtext": "Stranica „[[:$1]]“ i njena stranica za razgovor je dodata na Vaš [[Special:Watchlist|spisak nadgledanja]].",
+       "addedwatchtext-talk": "Stranica „[[:$1]]” i njena pridružena stranica je dodata na Vaš [[Special:Watchlist|spisak nadgledanja]]",
        "addedwatchtext-short": "Stranica „$1“ je dodata na Vaš spisak nadgledanja.",
        "removewatch": "Ukloni sa spiska nadgledanja",
-       "removedwatchtext": "Stranica „[[:$1]]“ i njena stranica za razgovor je uklonjena s vašeg [[Special:Watchlist|spiska nadgledanja]].",
+       "removedwatchtext": "Stranica „[[:$1]]“ i njena stranica za razgovor je uklonjena sa Vašeg [[Special:Watchlist|spiska nadgledanja]].",
        "removedwatchtext-short": "Stranica „$1“ je uklonjena s vašeg spiska nadgledanja.",
        "watch": "Nadgledaj",
        "watchthispage": "Nadgledaj ovu stranicu",
        "notvisiblerev": "Izmena je obrisana",
        "watchlist-details": "Na Vašem spisku nadgledanja {{PLURAL:$1|je $1 stranica|su $1 stranice|je $1 stranica}} (plus stranice za razgovor).",
        "wlheader-enotif": "Obaveštenje imejlom je omogućeno.",
-       "wlheader-showupdated": "Stranice koje su izmenjene otkad ste ih poslednji put posetili su '''podebljane'''.",
+       "wlheader-showupdated": "Stranice koje su izmenjene otkad ste ih poslednji put posetili su <strong>podebljane</strong>.",
        "wlnote": "Ispod {{PLURAL:$1|je poslednja izmena|su poslednje <strong>$1</strong> izmene|je poslednjih <strong>$1</strong> izmena}} u {{PLURAL:$2|prethodnom satu|prethodna <strong>$2</strong> sata|prethodnih <strong>$2</strong> sati}}, zaključno sa $3, $4.",
        "wlshowlast": "Prikaži poslednjih $1 sati, $2 dana",
        "watchlist-hide": "Sakrij",
        "wlshowhidepatr": "patrolirane izmene",
        "wlshowhidemine": "moje izmene",
        "wlshowhidecategorization": "kategorizaciju stranica",
-       "watchlist-options": "Postavke spiska nadgledanja",
-       "watching": "Nadgledanje…",
-       "unwatching": "Uklanjanje sa spiska nadgledanja...",
+       "watchlist-options": "Opcije spiska nadgledanja",
+       "watching": "Nadgledam…",
+       "unwatching": "Prestajem da nadgledam...",
        "watcherrortext": "Došlo je do greške pri promeni postavki vašeg spiska nadgledanja za „$1“.",
        "enotif_reset": "Označi sve stranice kao posećene",
        "enotif_impersonal_salutation": "{{SITENAME}} korisnik",
-       "enotif_subject_deleted": "Stranicu $1 na {{SITENAME}} {{GENDER:$2|obrisao je|obrisala je}} $2",
-       "enotif_subject_created": "Stranicu $1 na {{SITENAME}} {{GENDER:$2|napravio je|napravila je}} $2",
+       "enotif_subject_deleted": "Stranicu $1 na {{SITENAME}} {{GENDER:$2|obrisao je|obrisala je|obrisao je}} $2",
+       "enotif_subject_created": "Stranicu $1 na {{SITENAME}} {{GENDER:$2|napravio je|napravila je|napravio je}} $2",
        "enotif_subject_moved": "Stranicu $1 na {{SITENAME}} {{GENDER:$2|premestio je|premestila je}} $2",
-       "enotif_subject_restored": "Stranicu $1 na {{SITENAME}} {{GENDER:$2|vratio je|vratila je}} $2",
+       "enotif_subject_restored": "Stranicu $1 na {{SITENAME}} {{GENDER:$2|vratio je|vratila je|vratio je}} $2",
        "enotif_subject_changed": "Stranicu $1 na {{SITENAME}} {{GENDER:$2|promenio|promenila}} je $2",
        "enotif_body_intro_deleted": "Stranicu $1 na {{SITENAME}} {{GENDER:$2|obrisao|obrisala}} je $2 dana $PAGEEDITDATE Pogledajte $3.",
        "enotif_body_intro_created": "Stranicu $1 na {{SITENAME}} {{GENDER:$2|napravio|napravila}} je $2 dana $PAGEEDITDATE Trenutna izmena nalazi se na $3.",
        "enotif_lastvisited": "Za sve izmene od vaše poslednje posete, pogledajte $1.",
        "enotif_lastdiff": "Da vidite ovu izmenu, pogledajte $1.",
        "enotif_anon_editor": "anoniman korisnik $1",
-       "enotif_body": "Poštovani $WATCHINGUSERNAME,\n \t\n$PAGEINTRO $NEWPAGE\n\nOpis: $PAGESUMMARY $PAGEMINOREDIT\n\nKontakt:\nmejl: $PAGEEDITOR_EMAIL\nviki: $PAGEEDITOR_WIKI\n\nNeće biti drugih obaveštenja u slučaju daljih izmena ukoliko ne posetite ovu stranicu kada ste prijavljeni.\nMožete i da poništite postavke obaveštenja za sve stranice u vašem spisku nadgledanja.\n\nSrdačan pozdrav, {{SITENAME}}\n\n--\nDa biste promenili postavke imejl obaveštenja, posetite\n{{canonicalurl:{{#special:Preferences}}}}\n\nDa biste promenili postavke spiska nadgledanja, posetite\n{{canonicalurl:{{#special:EditWatchlist}}}}\n\nDa biste uklonili ovu stranicu sa spiska nadgledanja, posetite\n$UNWATCHURL\n\nPodrška i dalja pomoć:\n$HELPPAGE",
+       "enotif_body": "Poštovani $WATCHINGUSERNAME,\n \t\n$PAGEINTRO $NEWPAGE\n\nOpis: $PAGESUMMARY $PAGEMINOREDIT\n\nKontakt:\nmejl: $PAGEEDITOR_EMAIL\nviki: $PAGEEDITOR_WIKI\n\nNeće biti drugih obaveštenja u slučaju daljih izmena ukoliko ne posetite ovu stranicu kada ste prijavljeni.\nMožete i da poništite podešavanja obaveštenja za sve stranice u vašem spisku nadgledanja.\n\nSrdačan pozdrav, {{SITENAME}}\n\n--\nDa biste promenili podešavanja imejl obaveštenja, posetite\n{{canonicalurl:{{#special:Preferences}}}}\n\nDa biste promenili podešavanja spiska nadgledanja, posetite\n{{canonicalurl:{{#special:EditWatchlist}}}}\n\nDa biste uklonili ovu stranicu sa spiska nadgledanja, posetite\n$UNWATCHURL\n\nPodrška i dalja pomoć:\n$HELPPAGE",
+       "enotif_minoredit": "Ovo je manja izmena",
        "created": "napravljena",
        "changed": "izmenjena",
        "deletepage": "Obriši stranicu",
        "confirm": "Potvrdi",
        "excontent": "sadržaj je bio: „$1“",
-       "excontentauthor": "sadržaj je bio: „$1“, a jedini urednik [[Special:Contributions/$2|$2]] ([[User talk:$2|razgovor]])",
+       "excontentauthor": "sadržaj je bio: „$1“, a jedini urednik „[[Special:Contributions/$2|$2]]“ ([[User talk:$2|razgovor]])",
        "exbeforeblank": "sadržaj pre brisanja je bio: „$1“",
        "delete-confirm": "Brisanje stranice „$1“",
        "delete-legend": "Obriši",
        "dellogpage": "Dnevnik brisanja",
        "dellogpagetext": "Ispod je spisak poslednjih brisanja.",
        "deletionlog": "dnevnik brisanja",
+       "logentry-create-create": "$1 je {{GENDER:$2|napravio|napravila}} stranicu $3",
        "reverted": "Vraćeno na raniju izmenu",
        "deletecomment": "Razlog:",
        "deleteotherreason": "Drugi/dodatni razlog:",
        "rollbacklinkcount": "vrati $1 {{PLURAL:$1|izmenu|izmene|izmena}}",
        "rollbacklinkcount-morethan": "vrati više od $1 {{PLURAL:$1|izmene|izmene|izmena}}",
        "rollbackfailed": "Neuspešno vraćanje",
+       "rollback-missingparam": "Nedostaje potreban parametar na zahtevu.",
+       "rollback-missingrevision": "Ne mogu učitati podatke o izmeni.",
        "cantrollback": "Ne mogu da vratim izmenu.\nPoslednji autor je ujedno i jedini.",
        "alreadyrolled": "Vraćanje poslednje izmene stranice [[:$1]] od strane {{GENDER:$2|korisnika|korisnice|korisnika}} [[User:$2|$2]] ([[User talk:$2|razgovor]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]) nije uspelo; neko drugi je u međuvremenu izmenio ili vratio stranicu.\n\nPoslednju izmenu je {{GENDER:$3|napravio|napravila|napravio}} [[User:$3|$3]] ([[User talk:$3|razgovor]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).",
        "editcomment": "Opis izmene: <em>$1</em>.",
-       "revertpage": "Vraćene izmene [[Special:Contribs/$2|$2]] ([[User talk:$2|razgovor]]) na poslednju izmenu korisnika [[User:$1|$1]]",
-       "revertpage-nouser": "Vraćene su izmene skrivenog korisnika na poslednju izmenu {{GENDER:$1|korisnika|korisnice}} [[User:$1|$1]]",
-       "rollback-success": "Vraćene su izmene {{GENDER:$1|korisnika|korisnice}} $1\nna poslednju izmenu {{GENDER:$2|korisnika|korisnice}} $2.",
+       "revertpage": "Vraćene izmene {{GENDER:$2|korisnika|korisnice}} [[Special:Contribs/$2|$2]] ([[User talk:$2|razgovor]]) na poslednju izmenu {{GENDER:$1|korisnika|korisnice}} [[User:$1|$1]]",
+       "revertpage-nouser": "Izmene skrivenog korisnika su vraćene na poslednju izmenu {{GENDER:$1|korisnika|korisnice}} [[User:$1|$1]]",
+       "rollback-success": "Izmene {{GENDER:$1|korisnika|korisnice}} {{GENDER:$3|$1}} su vraćene 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 izmene]",
        "sessionfailure-title": "Sesija je okončana",
-       "sessionfailure": "Izgleda da postoji problem s vašom sesijom;\nova radnja je otkazana da bi se izbegla zloupotreba.\nVratite se na prethodnu stranicu, ponovo je učitajte i pokušajte ponovo.",
-       "changecontentmodel": "Promeni model sadržaja stranice",
+       "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",
        "changecontentmodel-legend": "Promeni model sadržaja",
        "changecontentmodel-title-label": "Naslov stranice",
        "changecontentmodel-model-label": "Novi model sadržaja",
        "changecontentmodel-reason-label": "Razlog:",
+       "changecontentmodel-submit": "Promeni",
        "changecontentmodel-success-title": "Model sadržaja je promenjen",
        "changecontentmodel-success-text": "Model sadržaja stranice [[:$1]] je promenjen.",
        "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",
+       "changecontentmodel-emptymodels-title": "Nema dostupnih modela sadržaja",
+       "changecontentmodel-emptymodels-text": "Model sadržaja stranice [[:$1]] se ne može pretvoriti ni u jednu drugu vrstu.",
        "log-name-contentmodel": "Dnevnik promene modela sadržaja",
-       "log-description-contentmodel": "Događaji koji imaju vezu sa modelima sadržaja stranica",
+       "log-description-contentmodel": "Ova stranica prikazuje izmene u modelima sadržaja stranica i stranice koje su napravljene sa modelom sadržaja koji se razlikuje od podrazumevanog.",
+       "logentry-contentmodel-new": "$1 je {{GENDER:$2|napravio|napravila}} stranicu $3 s nestandardnim modelom sadržaja „$5“",
        "logentry-contentmodel-change": "$1 je {{GENDER:$2|promenio|promenila}} model sadržaja stranice $3 iz „$4“ u „$5“",
        "logentry-contentmodel-change-revertlink": "vrati",
        "logentry-contentmodel-change-revert": "vrati",
        "protectlogpage": "Dnevnik zaštite",
        "protectlogtext": "Ispod je spisak zaštićenih stranica.\nPogledajte [[Special:ProtectedPages|spisak zaštićenih stranica]] za više detalja.",
-       "protectedarticle": "je zaštitio „[[$1]]“",
-       "modifiedarticleprotection": "promenjen stepen zaštite za „[[$1]]“",
+       "protectedarticle": "je {{GENDER:|zaštitio|zaštitila}} stranicu „[[$1]]“",
+       "modifiedarticleprotection": "je {{GENDER:|promenio|promenila}} stepen zaštite stranice „[[$1]]“",
        "unprotectedarticle": "je skinuo zaštitu sa stranice „[[$1]]“",
        "movedarticleprotection": "je premestio podešavanja zaštite sa „[[$2]]“ na „[[$1]]“",
+       "protectedarticle-comment": "{{GENDER:$2|Zaštićena}} stranica [[$1]]",
+       "modifiedarticleprotection-comment": "{{GENDER:$2|Promenjen}} nivo zaštite [[$1]]",
+       "unprotectedarticle-comment": "{{GENDER:$2|Skinuta}} zaštita sa [[$1]]",
        "protect-title": "Stepen zaštite za „$1“",
        "protect-title-notallowed": "Pregled stepena zaštite za „$1“",
        "prot_1movedto2": "je premestio [[$1]] na [[$2]]",
        "protect-badnamespace-text": "Stranice u ovom imenskom prostoru se ne mogu zaštititi.",
        "protect-norestrictiontypes-text": "Ova stranica se ne može zaštititi jer nema dostupnih vrsta ograničenja.",
        "protect-norestrictiontypes-title": "Nezaštitljiva strana",
-       "protect-legend": "Postavke zaštite",
+       "protect-legend": "Podešavanja zaštite",
        "protectcomment": "Razlog:",
        "protectexpiry": "Ističe:",
        "protect_expiry_invalid": "Vreme isteka je neispravno.",
        "protect_expiry_old": "Vreme isteka je starije od trenutnog vremena.",
-       "protect-unchain-permissions": "Otključaj daljnje postavke zaštite",
+       "protect-unchain-permissions": "Otključaj daljnja podešavanja zaštite",
        "protect-text": "Ovde možete da pogledate i promenite stepen zaštite za stranicu '''$1'''.",
-       "protect-locked-blocked": "Ne možete menjati stepene zaštite dok ste blokirani.\nOvo su trenutne postavke stranice '''$1''':",
-       "protect-locked-dblock": "Stepeni zaštite se ne mogu menjati jer je aktivna baza podataka zaključana.\nOvo su postavke stranice '''$1''':",
-       "protect-locked-access": "Nemate ovlašćenja za menjanje stepena zaštite stranice.\nOvo su trenutne postavke stranice '''$1''':",
+       "protect-locked-blocked": "Ne možete menjati stepene zaštite dok ste blokirani.\nOvo su trenutna podešavanja stranice '''$1''':",
+       "protect-locked-dblock": "Stepeni zaštite se ne mogu menjati jer je aktivna baza podataka zaključana.\nOvo su podešavanja stranice '''$1''':",
+       "protect-locked-access": "Nemate ovlašćenja za menjanje stepena zaštite stranice.\nOvo su trenutna podešavanja stranice '''$1''':",
        "protect-cascadeon": "Ova stranica je trenutno zaštićena jer se nalazi na {{PLURAL:$1|stranici koja ima|stranicama koje imaju}} prenosivu zaštitu.\nMožete da promenite stepen zaštite, ali to neće uticati na prenosivu zaštitu.",
        "protect-default": "Dopušteno svim korisnicima",
        "protect-fallback": "Dozvoljeno samo korisnicima sa dozvolom „$1“",
        "minimum-size": "Najmanja veličina",
        "maximum-size": "Najveća veličina:",
        "pagesize": "(bajtovi)",
-       "restriction-edit": "Uređivanje",
-       "restriction-move": "Premeštanje",
+       "restriction-edit": "uređivanje",
+       "restriction-move": "premeštanje",
        "restriction-create": "pravljenje",
        "restriction-upload": "otpremanje",
        "restriction-level-sysop": "potpuno zaštićeno",
        "undeletepagetext": "{{PLURAL:$1|Sledeća stranica je obrisana, ali je još u arhivi i može biti vraćena|Sledeće $1 stranice su obrisane, ali su još u arhivi i mogu biti vraćene|Sledećih $1 stranica je obrisano, ali su još u arhivi i mogu biti vraćene}}.\nArhiva se povremeno čisti od ovakvih stranica.",
        "undelete-fieldset-title": "Vraćanje izmena",
        "undeleteextrahelp": "Da biste vratili celu istoriju stranice, ostavite sve kućice neoznačene i kliknite na dugme '''''{{int:undeletebtn}}'''''.\nAko želite da vratite određene izmene, označite ih i kliknite na '''''{{int:undeletebtn}}'''''.",
-       "undeleterevisions": "$1 {{PLURAL:$1|izmena je arhivirana|izmene su arhivirane|izmena je arhivirano}}",
-       "undeletehistory": "Ako vratite stranicu, sve revizije će biti vraćene njenoj istoriji.\nAko je u međuvremenu napravljena nova stranica s istim nazivom, vraćene izmene će se pojaviti u njenoj ranijoj istoriji.",
+       "undeleterevisions": "{{PLURAL:$1|Izmena}} obrisano: $1",
+       "undeletehistory": "Ako vratite stranicu, sve izmene će biti vraćene njenoj istoriji.\nAko je u međuvremenu napravljena nova stranica s istim nazivom, vraćene izmene će se pojaviti u njenoj ranijoj istoriji.",
        "undeleterevdel": "Vraćanje neće biti izvršeno ako je rezultat toga delimično brisanje poslednje izmene.\nU takvim slučajevima morate isključiti ili otkriti najnovije obrisane izmene.",
        "undeletehistorynoadmin": "Ova stranica je obrisana.\nRazlog za brisanje se nalazi ispod, zajedno s detaljima o korisniku koji je izmenio ovu stranicu pre brisanja.\nTekst obrisanih izmena je dostupan samo administratorima.",
        "undelete-revision": "Obrisana izmena stranice $1 (dana $4; $5) od strane {{GENDER:$3|korisnika|korisnice|korisnika}} $3:",
        "undeleterevision-missing": "Neispravna ili nepostojeća izmena.\nMožda ste uneli pogrešnu vezu, ili je izmena vraćena ili uklonjena iz arhive.",
+       "undeleterevision-duplicate-revid": "Ne mogu vratiti {{PLURAL:$1|izmenu|$1 izmene|$1 izmena}} jer se {{PLURAL:$1|njen|njihov}} <code>rev_id</code> već koristi.",
        "undelete-nodiff": "Prethodne izmene nisu pronađene.",
        "undeletebtn": "Vrati",
        "undeletelink": "pogledaj/vrati",
        "undelete-search-title": "Pretraga obrisanih stranica",
        "undelete-search-box": "Pretraži obrisane stranice",
        "undelete-search-prefix": "Prikaži stranice koje počinju sa:",
+       "undelete-search-full": "Prikaži naslove koji sadrže:",
        "undelete-search-submit": "Pretraži",
        "undelete-no-results": "Odgovarajuća stranica u dnevniku brisanja nije pronađena.",
        "undelete-filename-mismatch": "Ne mogu da vratim izmenu datoteke od $1: naziv datoteke se ne poklapa",
        "undelete-show-file-submit": "Da",
        "namespace": "Imenski prostor:",
        "invert": "Obrni izbor",
-       "tooltip-invert": "Označite ovu kućicu da biste sakrili izmene na stranicama u odabranom imenskom prostoru (i povezanim imenskim prostorima, ako je označeno)",
+       "tooltip-invert": "Označite ovu kutijucu da biste sakrili izmene stranica u izabranom imenskom prostoru (i povezanim imenskim prostorima, ako je označeno)",
+       "tooltip-whatlinkshere-invert": "Označite ovu kutijicu za sakrivanje veza sa stranica u izabranom imenskom prostoru.",
        "namespace_association": "Povezani imenski prostor",
-       "tooltip-namespace_association": "Označite ovu kućicu da biste uključili i razgovor ili imenski prostor teme koja je povezana s odabranim imenskim prostorom",
+       "tooltip-namespace_association": "Označite ovu kutijicu da biste uključili i razgovor ili imenski prostor teme koja je povezana sa izabranim imenskim prostorom",
        "blanknamespace": "(glavni)",
        "contributions": "{{GENDER:$1|Korisnički}} doprinosi",
        "contributions-title": "Doprinosi {{GENDER:$1|korisnika|korisnice}} $1",
        "mycontris": "Doprinosi",
        "anoncontribs": "Doprinosi",
        "contribsub2": "Za {{GENDER:$3|$1}} ($2)",
-       "contributions-userdoesnotexist": "Korisnički nalog „$1“ nije registrovan.",
+       "contributions-userdoesnotexist": "Korisnički nalog „$1“ nije otvoren.",
        "nocontribs": "Nema izmena koje odgovaraju navedenim kriterijumima.",
-       "uctop": "(poslednja)",
+       "uctop": "(trenutna)",
        "month": "od meseca (i ranije):",
        "year": "od godine (i ranije):",
        "sp-contributions-newbies": "Prikaži samo doprinose novih korisnika",
        "sp-contributions-newbies-sub": "Za nove korisnike",
        "sp-contributions-newbies-title": "Doprinosi novih korisnika",
        "sp-contributions-blocklog": "dnevnik blokiranja",
+       "sp-contributions-suppresslog": "obrisani {{GENDER:$1|korisnički}} doprinosi",
        "sp-contributions-deleted": "obrisani {{GENDER:$1|doprinosi}}",
        "sp-contributions-uploads": "otpremanja",
        "sp-contributions-logs": "dnevnici",
        "sp-contributions-username": "IP adresa ili korisničko ime:",
        "sp-contributions-toponly": "Samo najnovije izmene",
        "sp-contributions-newonly": "Samo izmene kojima su napravljene nove stranice",
+       "sp-contributions-hideminor": "Sakrij manje izmene",
        "sp-contributions-submit": "Pretraži",
        "whatlinkshere": "Šta vodi ovde",
        "whatlinkshere-title": "Stranice koje su povezane sa „$1”",
        "whatlinkshere-page": "Stranica:",
-       "linkshere-2": "Sledeće stranice imaju vezu do '''$1''':",
-       "nolinkshere-2": "Nijedna stranica nije povezana sa: '''$1'''.",
-       "nolinkshere-ns-2": "Nijedna stranica ne vodi do '''$1''' u izabranom imenskom prostoru.",
+       "linkshere": "Sledeće stranice imaju vezu do <strong>$1</strong>:",
+       "nolinkshere": "Nijedna stranica nije povezana sa: <strong>$2</strong>.",
+       "nolinkshere-ns": "Nijedna stranica ne vodi do '''$2''' u izabranom imenskom prostoru.",
        "isredirect": "preusmerenje",
        "istemplate": "uključivanje",
-       "isimage": "veza ka datoteci",
-       "whatlinkshere-prev": "{{PLURAL:$1|prethodni|prethodnih $1}}",
-       "whatlinkshere-next": "{{PLURAL:$1|sledeći|sledećih $1}}",
+       "isimage": "veza do datoteke",
+       "whatlinkshere-prev": "{{PLURAL:$1|prethodni|prethodna $1|prethodnih $1}}",
+       "whatlinkshere-next": "{{PLURAL:$1|sledeći|sledeća $1|sledećih $1}}",
        "whatlinkshere-links": "← veze",
        "whatlinkshere-hideredirs": "$1 preusmerenja",
        "whatlinkshere-hidetrans": "$1 uključivanja",
        "whatlinkshere-submit": "Idi",
        "autoblockid": "Automatsko blokiranje #$1",
        "block": "Blokiraj korisnika",
-       "unblock": "Deblokiraj korisnika",
-       "blockip": "Blokiraj korisnika",
+       "unblock": "Deblokiranje korisnika",
+       "blockip": "Blokiraj {{GENDER:$1|korisnika|korisnicu}}",
        "blockiptext": "Koristite donji obrazac da biste zabranili pristup za pisanje s određene IP adrese ili korisničkog imena.\nOvo bi trebalo da vršite samo radi sprečavanja vandalizma, u skladu sa [[{{MediaWiki:Policy-url}}|smernicama]].\nIzaberite konkretan razlog ispod (primer: navođenje konkretnih stranica koje su vandalizovane). Možete blokirati opsege IP adresa pomoću [https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing CIDR] sintakse, najveći dozvoljeni opseg za IPv4 je /$1 odnosno /$2 za IPv6.",
        "ipaddressorusername": "IP adresa ili korisničko ime:",
        "ipbexpiry": "Ističe:",
        "ipb-unblock-addr": "Deblokiraj $1",
        "ipb-unblock": "Deblokiraj korisničko ime ili IP adresu",
        "ipb-blocklist": "Pogledaj postojeća blokiranja",
-       "ipb-blocklist-contribs": "Doprinosi za $1",
+       "ipb-blocklist-contribs": "Doprinosi za {{GENDER:$1|$1}}",
+       "ipb-blocklist-duration-left": "preostalo: $1",
        "unblockip": "Deblokiraj korisnika",
        "unblockiptext": "Koristite obrazac ispod da biste vratili pravo pisanja blokiranoj IP adresi ili korisničkom imenu.",
        "ipusubmit": "Ukloni ovu blokadu",
        "unblocked-id": "Blokiranje $1 je uklonjeno",
        "unblocked-ip": "[[Special:Contributions/$1|$1]] je deblokiran.",
        "blocklist": "Blokirani korisnici",
+       "autoblocklist": "Autoblokovi",
+       "autoblocklist-submit": "Pretraži",
+       "autoblocklist-legend": "Spisak autoblokiranja",
+       "autoblocklist-localblocks": "{{PLURAL:$1|Lokalni autoblok|Lokalni autoblokovi}}",
+       "autoblocklist-total-autoblocks": "Ukupno autoblokova: $1",
+       "autoblocklist-empty": "Spisak autoblokiranja je prazan.",
+       "autoblocklist-otherblocks": "{{PLURAL:$1|Drugi autoblok|Drugi autoblokovi}}",
        "ipblocklist": "Blokirani korisnici",
        "ipblocklist-legend": "Pronalaženje blokiranog korisnika",
        "blocklist-userblocks": "Sakrij blokiranja naloga",
        "emaillink": "pošalji imejl",
        "autoblocker": "Automatski ste blokirani jer delite IP adresu s korisnikom/com [[User:$1|$1]].\nRazlog blokiranja: „$2“",
        "blocklogpage": "Dnevnik blokiranja",
-       "blocklog-showlog": "{{GENDER:$1|Ovaj korisnik je ranije blokiran|Ova korisnica je ranije blokirana|Ovaj korisnik je ranije blokiran}}.\nIstorija blokiranja se nalazi ispod:",
+       "blocklog-showlog": "{{GENDER:$1|Ovaj korisnik je ranije blokiran|Ova korisnica je ranije blokirana}}.\nIstorija blokiranja se nalazi ispod:",
        "blocklog-showsuppresslog": "{{GENDER:$1|Ovaj korisnik je ranije blokiran i sakriven|Ova korisnica je ranije blokirana i sakrivena}}.\nIstorija sakrivanja se nalazi ispod:",
-       "blocklogentry": "je blokirao [[$1]] s rokom isticanja od $2 $3",
-       "reblock-logentry": "{{GENDER:|je promenio|je promenila|je promenio}} podešavanja za blokiranje {{GENDER:$1|korisnika|korisnice|korisnika}} [[$1]] s rokom isteka od $2 ($3)",
+       "blocklogentry": "je blokirao [[$1]] sa vremenom isticanja od $2 $3",
+       "reblock-logentry": "{{GENDER:|je promenio|je promenila}} podešavanja za blokiranje {{GENDER:$1|korisnika|korisnice}} [[$1]] sa vremenom isteka od $2 ($3)",
        "blocklogtext": "Ovo je dnevnik blokiranja i deblokiranja korisnika.\nAutomatski blokirane IP adrese nisu navedene.\nTekuće zabrane i blokiranja možete naći [[Special:BlockList|ovde]].",
        "unblocklogentry": "je deblokirao $1",
        "block-log-flags-anononly": "samo anonimni korisnici",
        "block-log-flags-hiddenname": "korisničko ime je sakriveno",
        "range_block_disabled": "Administratorska mogućnost za blokiranje raspona IP adresa je onemogućena.",
        "ipb_expiry_invalid": "Vreme isteka je neispravno.",
+       "ipb_expiry_old": "Vreme isteka je u prošlosti.",
        "ipb_expiry_temp": "Sakrivene blokade korisnika moraju biti trajne.",
        "ipb_hide_invalid": "Ne mogu da potisnem ovaj nalog; ima više od {{PLURAL:$1|jedne izmene|$1 izmena}}.",
        "ipb_already_blocked": "„$1“ je već blokiran.",
        "ipb_blocked_as_range": "Greška: IP adresa $1 nije direktno blokirana i ne može da se deblokira.\nOna je blokirana kao deo blokade $2, koja može biti deblokirana.",
        "ip_range_invalid": "Neispravan raspon IP adresa.",
        "ip_range_toolarge": "Opsežna blokiranja veća od /$1 nisu dozvoljena.",
+       "ip_range_toolow": "IP-opsezi nisu dozvoljeni.",
        "proxyblocker": "Bloker posrednika",
        "proxyblockreason": "Vaša IP adresa je blokirana jer predstavlja otvoreni posrednik.\nObratite se vašem dobavljaču internet usluga ili tehničku podršku i obavestite ih o ovom ozbiljnom bezbednosnom problemu.",
        "sorbs": "DNSBL",
        "lockdbsuccesstext": "Baza podataka je zaključana.<br />\nSetite se da je [[Special:UnlockDB|otključate]] kada završite s održavanjem.",
        "unlockdbsuccesstext": "Baza je otključana.",
        "lockfilenotwritable": "Datoteka za zaključavanje baze nije otvorena za pisanje.\nDa biste zaključali i otključali bazu, datoteka mora biti dostupna za pisanje od strane mrežnog servera.",
+       "databaselocked": "Baza podataka je već zaključana.",
        "databasenotlocked": "Baza nije zaključana.",
        "lockedbyandtime": "(od $1 dana $2 u $3)",
-       "move-page": "PremeÅ¡tanje â\80\9e$1â\80\9c",
+       "move-page": "PremeÅ¡tanje â\80\9e$1â\80\9d",
        "move-page-legend": "Premeštanje stranice",
        "movepagetext": "Donji obrazac će preimenovati stranicu, premeštajući celu istoriju na novo ime.\nStari naslov postaće preusmerenje na novi.\nMožete ažurirati preusmerenja koja vode do izvornog naslova;\npogledajte [[Special:DoubleRedirects|dvostruka]] ili [[Special:BrokenRedirects|pokvarena]] preusmerenja.\nNa vama je odgovornost da veze i dalje idu tamo gde treba.\n\nStranica <strong>neće</strong> biti premeštena ako već postoji stranica s tim imenom (osim ako je prazna, sadrži preusmerenje ili nema istoriju izmena).\nTo znači da možete vratiti stranicu na prethodno ime ako pogrešite, ali ne možete ''prepisati'' postojeću.\n\n<strong>Napomena:</strong>\nOvo može predstavljati drastičnu i neočekivanu izmenu za popularnu stranicu;\ndobro razmislite o posledicama pre nego što nastavite.",
        "movepagetext-noredirectfixer": "Donji obrazac će preimenovati stranicu, premeštajući celu istoriju na novo ime.\nStari naslov postaće preusmerenje na novi.\nPogledajte [[Special:DoubleRedirects|dvostruka]] ili [[Special:BrokenRedirects|pokvarena]] preusmerenja.\nNa vama je odgovornost da veze i dalje idu tamo gde treba.\n\nStranica <strong>neće</strong> biti premeštena ako već postoji stranica s tim imenom (osim ako je prazna, sadrži preusmerenje ili nema istoriju izmena).\nTo znači da možete vratiti stranicu na prethodno ime ako pogrešite, ali ne možete ''prepisati'' postojeću.\n\n<strong>Napomena:</strong>\nOvo može predstavljati drastičnu i neočekivanu izmenu za popularnu stranicu;\ndobro razmislite o posledicama pre nego što nastavite.",
        "cant-move-user-page": "Nemate dozvolu za premeštanje osnovnih korisničkih stranica (osim podstranica).",
        "cant-move-to-user-page": "Nemate dozvolu za premeštanje stranice na vašu korisničku stranicu (osim na korisničku podstranicu).",
        "cant-move-category-page": "Nemate dozvolu da premeštate stranice kategorija.",
+       "cant-move-to-category-page": "Nemate dozvolu da premestite stranicu na stranicu kategorije.",
+       "cant-move-subpages": "Nemate dozvolu da premeštate podstranice.",
+       "namespace-nosubpages": "Imeniski prostor „$1“ ne dozvoljava podstranice.",
        "newtitle": "Novi naslov:",
        "move-watch": "Nadgledaj ovu stranicu",
        "movepagebtn": "Premesti stranicu",
        "delete_and_move_text": "Odredišna stranica „[[:$1]]“ već postoji. \nŽelite li da je obrišete da biste oslobodili mesto za premeštanje?",
        "delete_and_move_confirm": "Da, obriši stranicu",
        "delete_and_move_reason": "Obrisano da se oslobodi mesto za premeštanje iz „[[$1]]“",
-       "selfmove": "Izvorni i odredišni naslovi su istovetni;\nne mogu da premestim stranicu preko same sebe.",
+       "selfmove": "Naslov je istovetan;\nne možete premestiti stranicu preko same sebe.",
        "immobile-source-namespace": "Ne mogu premestiti stranice u imenski prostor „$1“.",
        "immobile-target-namespace": "Ne mogu premestiti stranice u imenski prostor „$1“.",
        "immobile-target-namespace-iw": "Međuviki veza nije ispravno odredište za premeštanje stranice.",
        "export-download": "Sačuvaj kao datoteku",
        "export-templates": "Uključi šablone",
        "export-pagelinks": "Uključi povezane stranice do dubine od:",
+       "export-manual": "Ručno dodaj stranice:",
        "allmessages": "Sistemske poruke",
        "allmessagesname": "Naziv",
        "allmessagesdefault": "Podrazumevani tekst",
        "allmessagescurrent": "Trenutni tekst poruke",
-       "allmessagestext": "Ovo je spisak svih sistemskih poruka koje su dostupne u imenskom prostoru „Medijaviki“.\nPosetite [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation Medijaviki lokalizaciju] i [https://translatewiki.net Translejtviki] ako želite da pomognete u prevođenju.",
+       "allmessagestext": "Ovo je spisak sistemskih poruka dostupnih u imenskom prostoru „Medijaviki“.\nPosetite [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation Medijaviki lokalizaciju] i [https://translatewiki.net translatewiki.net] ako želite da doprinesete opštoj lokalizaciji Medijavikija.",
        "allmessagesnotsupportedDB": "Ova stranica ne može da se koristi jer je '''$wgUseDatabaseMessages''' onemogućen.",
        "allmessages-filter-legend": "Filter",
        "allmessages-filter": "Filtriraj po stanju:",
        "allmessages-language": "Jezik:",
        "allmessages-filter-submit": "Idi",
        "allmessages-filter-translate": "Prevedi",
-       "thumbnail-more": "Povećaj",
+       "thumbnail-more": "Povećajte",
        "filemissing": "Nedostaje datoteka",
        "thumbnail_error": "Greška pri stvaranju minijature: $1",
+       "thumbnail_error_remote": "Poruka o grešci iz $1:\n$2",
        "djvu_page_error": "DjVu stranica je nedostupna",
        "djvu_no_xml": "Ne mogu da preuzmem XML za DjVu datoteku.",
        "thumbnail-temp-create": "Ne mogu da napravim privremenu datoteku minijature",
        "thumbnail-dest-create": "Ne mogu da sačuvam minijaturu u odredištu",
        "thumbnail_invalid_params": "Neispravni parametri za minijaturu",
+       "thumbnail_toobigimagearea": "Datoteka sa veličinama većim od $1",
        "thumbnail_dest_directory": "Ne mogu da napravim odredišnu fasciklu",
        "thumbnail_image-type": "Vrsta slike nije podržana",
-       "thumbnail_gd-library": "Nedovršene postavke grafičke biblioteke: nedostaje funkcija $1",
+       "thumbnail_gd-library": "Nedovršena podešavanja grafičke biblioteke: nedostaje funkcija $1",
+       "thumbnail_image-size-zero": "Izgleda da je veličina datoteke nula.",
        "thumbnail_image-missing": "Datoteka nedostaje: $1",
+       "thumbnail_image-failure-limit": "Bilo je previše skorašnjih neuspešnih pokušaja ($1 ili više) renderovanja ove minijature. Pokušajte ponovo kasnije.",
        "import": "Uvoz stranica",
-       "importinterwiki": "Uvoz iz drugo vikija",
+       "importinterwiki": "Uvoz sa drugog vikija",
        "import-interwiki-text": "Izaberite viki i naslov stranice za uvoz.\nDatumi i imena urednika će biti sačuvani.\nSve radnje pri uvozu s drugih vikija su zabeležene u [[Special:Log/import|dnevniku uvoza]].",
        "import-interwiki-sourcewiki": "Izvorna viki:",
        "import-interwiki-sourcepage": "Izvorna stranica:",
        "import-mapping-namespace": "Uvezi u imenski prostor:",
        "import-mapping-subpage": "Uvezi kao podstranice sledeće stranice:",
        "import-upload-filename": "Naziv datoteke:",
+       "import-upload-username-prefix": "Međuviki prefiks:",
        "import-comment": "Komentar:",
        "importtext": "Izvezite datoteku s izvornog vikija koristeći [[Special:Export|izvoz]].\nSačuvajte je na računar i pošaljite ovde.",
        "importstart": "Uvozim stranice…",
        "imported-log-entries": "{{PLURAL:$1|Uvezena je $1 stavka izveštaja|Uvezene su $1 stavke izveštaja|Uvezeno je $1 stavki izveštaja}}.",
        "importfailed": "Neuspešan uvoz: <nowiki>$1</nowiki>",
        "importunknownsource": "Nepoznata vrsta za uvoz",
-       "importcantopen": "Ne mogu da otvorim datoteku za uvoz",
+       "importnoprefix": "Nije naveden međuviki prefiks",
+       "importcantopen": "Ne mogu da otvorim datoteku za uvoz.",
        "importbadinterwiki": "Neispravna međuviki veza",
        "importsuccess": "Uvoženje je završeno!",
        "importnosources": "Nije određen nijedan izvor za uvoz, tako da je otpremanje istorije onemogućeno.",
        "importuploaderrortemp": "Ne mogu da pošaljem datoteku za uvoz.\nNedostaje privremena fascikla.",
        "import-parse-failure": "Pogrešno raščlanjivanje XML-a.",
        "import-noarticle": "Nema stranice za uvoz!",
-       "import-nonewrevisions": "Izmene nisu uvezene (sve su već bile ili prisutne ili preskočene zbog greški).",
+       "import-nonewrevisions": "Izmene nisu uvezene (sve su već bile ili prisutne ili preskočene zbog grešaka).",
        "xml-error-string": "$1 u redu $2, kolona $3 (bajt $4): $5",
        "import-upload": "Otpremanje XML podataka",
-       "import-token-mismatch": "Gubitak podataka o sesiji.\nPokušajte ponovo.",
+       "import-token-mismatch": "Gubitak podataka o sesiji.\n\nMožda ste odjavljeni. '''Molimo Vas proverite da li ste još uvek prijavljeni i pokušajte ponovo'''.\n\nAko i dalje ne radi, pokušajte se [[Special:UserLogout|odjaviti]] i ponovo prijaviti i proverite da li Vaš veb-prtraživač dozvoljava kolačiće sa ovog sajta.",
        "import-invalid-interwiki": "Ne mogu da uvozim s navedenog vikija.",
        "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-logentry-upload-detail": "$1 {{PLURAL:$1|izmena uvezena|izmene uvezene|izmena uvezeno}}",
        "import-logentry-interwiki-detail": "$1 {{PLURAL:$1|izmena uvezena|izmene uvezene|izmena uvezeno}} iz $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 adresu s koje uređujete",
        "tooltip-pt-mytalk": "{{GENDER:|Vaša}} stranica za razgovor",
-       "tooltip-pt-anontalk": "Razgovor o izmenama s ove IP adrese",
+       "tooltip-pt-anontalk": "Razgovor o izmenama sa ove IP adrese",
        "tooltip-pt-preferences": "{{GENDER:|Vaša}} podešavanja",
        "tooltip-pt-watchlist": "Spisak stranica koje nadgledate",
-       "tooltip-pt-mycontris": "Spisak {{GENDER:|vaših}} doprinosa",
+       "tooltip-pt-mycontris": "Spisak {{GENDER:|Vaših}} doprinosa",
        "tooltip-pt-anoncontribs": "Spisak izmena napravljenih sa ove IP adrese",
-       "tooltip-pt-login": "Preporučujemo vam da se prijavite, iako to nije obavezno.",
+       "tooltip-pt-login": "Predlažemo Vam da se prijavite, iako to nije obavezno",
+       "tooltip-pt-login-private": "Morate da se prijavite da biste koristili ovaj Viki",
        "tooltip-pt-logout": "Odjavite se",
-       "tooltip-pt-createaccount": "Ohrabrujemo vas da otvorite nalog i prijavite se ali to nije obavezno",
+       "tooltip-pt-createaccount": "Predlažemo Vam da otvorite nalog i prijavite se, iako to nije obavezno",
        "tooltip-ca-talk": "Razgovor o stranici sa sadržajem",
-       "tooltip-ca-edit": "Uredi ovu stranicu",
+       "tooltip-ca-edit": "Uredite ovu stranicu",
        "tooltip-ca-addsection": "Započnite novi odeljak",
-       "tooltip-ca-viewsource": "Ова страница је закључана. \nМожете погледати изворни текст.",
-       "tooltip-ca-history": "Prethodne verzije ove stranice",
+       "tooltip-ca-viewsource": "Ova stranica je zaključana. \nMožete da pogledate njen izvorni kod",
+       "tooltip-ca-history": "Prethodne izmene ove stranice",
        "tooltip-ca-protect": "Zaštitite ovu stranicu",
        "tooltip-ca-unprotect": "Promeni zaštitu ove stranice",
        "tooltip-ca-delete": "Obrišite ovu stranicu",
        "tooltip-ca-undelete": "Vrati izmene napravljene na ovoj stranici pre nego što bude obrisana",
        "tooltip-ca-move": "Premesti ovu stranicu",
-       "tooltip-ca-watch": "Dodaj ovu stranicu na spisak nadgledanja",
-       "tooltip-ca-unwatch": "Ukloni ovu stranicu sa spiska nadgledanja",
-       "tooltip-search": "Pretraga",
-       "tooltip-search-go": "Idite na stranicu s ovim imenom, ako postoji",
-       "tooltip-search-fulltext": "Pretražite stranice s ovim tekstom",
+       "tooltip-ca-watch": "Dodajte ovu stranicu na svoj spisak nadgledanja",
+       "tooltip-ca-unwatch": "Uklonite ovu stranicu sa spiska nadgledanja",
+       "tooltip-search": "Pretražite projekat {{SITENAME}}",
+       "tooltip-search-go": "Idite na stranicu s tačno ovim imenom ako postoji",
+       "tooltip-search-fulltext": "Pretražite stranice sa ovim tekstom",
        "tooltip-p-logo": "Posetite glavnu stranu",
        "tooltip-n-mainpage": "Posetite glavnu stranu",
        "tooltip-n-mainpage-description": "Posetite glavnu stranu",
        "tooltip-n-portal": "O projektu, šta možete da radite i gde da pronađete stvari",
-       "tooltip-n-currentevents": "Saznajte više o tekućim događajima",
+       "tooltip-n-currentevents": "Pronađite dodatne informacije o aktuelnostima",
        "tooltip-n-recentchanges": "Spisak skorašnjih izmena na vikiju",
-       "tooltip-n-randompage": "Otvorite slučajnu stranicu",
-       "tooltip-n-help": "Mesto gde možete da se informišete",
-       "tooltip-t-whatlinkshere": "Spisak svih stranica koje vode ovde",
-       "tooltip-t-recentchangeslinked": "Skorašnje izmene na stranicama koje su povezana s ovom stranicom",
+       "tooltip-n-randompage": "Učitajte slučajnu stranicu",
+       "tooltip-n-help": "Mesto gde možete da naučite nešto",
+       "tooltip-t-whatlinkshere": "Spisak svih viki stranica koje vode ovde",
+       "tooltip-t-recentchangeslinked": "Skorašnje izmene na stranicama koje su povezane sa ovom stranicom",
        "tooltip-feed-rss": "RSS dovod ove stranice",
        "tooltip-feed-atom": "Atom dovod ove stranice",
-       "tooltip-t-contributions": "Spisak doprinosa {{GENDER:$1|ovog korisnika|ove korisnice}}",
+       "tooltip-t-contributions": "Spisak doprinosa {{GENDER:$1|ovog korisnika|ove korisnice|ovog korisnika}}",
        "tooltip-t-emailuser": "Pošaljite imejl {{GENDER:$1|ovom korisniku|ovoj korisnici}}",
        "tooltip-t-info": "Više informacija o ovoj stranici",
-       "tooltip-t-upload": "Otpremi datoteke",
+       "tooltip-t-upload": "Otpremite datoteke",
        "tooltip-t-specialpages": "Spisak svih posebnih stranica",
        "tooltip-t-print": "Verzija ove stranice za štampanje",
-       "tooltip-t-permalink": "Stalna veza ka ovoj izmeni stranice",
+       "tooltip-t-permalink": "Trajna veza ka ovoj izmeni stranice",
        "tooltip-ca-nstab-main": "Pogledajte stranicu sa sadržajem",
        "tooltip-ca-nstab-user": "Pogledajte korisničku stranicu",
-       "tooltip-ca-nstab-media": "Pogledajte multimedijalnu datoteku",
+       "tooltip-ca-nstab-media": "Pogledajte medijsku stranicu",
        "tooltip-ca-nstab-special": "Ovo je posebna stranica. Ne možete je menjati.",
        "tooltip-ca-nstab-project": "Pogledajte stranicu projekta",
-       "tooltip-ca-nstab-image": "Prikaži stranu datoteke",
+       "tooltip-ca-nstab-image": "Pogledajte stranicu datoteke",
        "tooltip-ca-nstab-mediawiki": "Pogledajte sistemsku poruku",
        "tooltip-ca-nstab-template": "Pogledajte šablon",
        "tooltip-ca-nstab-help": "Pogledajte stranicu za pomoć",
-       "tooltip-ca-nstab-category": "Pogledajte stranicu kategorija",
+       "tooltip-ca-nstab-category": "Pogledajte stranicu kategorije",
        "tooltip-minoredit": "Označite ovu izmenu kao manju",
        "tooltip-save": "Sačuvajte svoje izmene",
-       "tooltip-publish": "Objavi svoje izmene",
+       "tooltip-publish": "Objavite svoje izmene",
        "tooltip-preview": "Pregledajte svoje izmene. Koristite ovo dugme pre čuvanja.",
        "tooltip-diff": "Pogledajte koje izmene ste napravili na tekstu",
        "tooltip-compareselectedversions": "Pogledajte razlike između dve izabrane izmene ove stranice.",
        "tooltip-watch": "Dodajte ovu stranicu na svoj spisak nadgledanja",
-       "tooltip-watchlistedit-normal-submit": "Ukloni naslove",
+       "tooltip-watchlistedit-normal-submit": "Uklonite naslove",
        "tooltip-watchlistedit-raw-submit": "Ažuriraj spisak",
        "tooltip-recreate": "Ponovo napravite stranicu iako je obrisana",
        "tooltip-upload": "Započnite otpremanje",
-       "tooltip-rollback": "„Vrati“ vraća izmene poslednjeg korisnika jednim klikom",
-       "tooltip-undo": "Poništava ovu izmenu i otvara obrazac za uređivanje.",
-       "tooltip-preferences-save": "Sačuvaj postavke",
+       "tooltip-rollback": "„Vrati“ vraća izmene poslednjeg doprinosioca ove stranice jednim klikom",
+       "tooltip-undo": "„Poništi” vraća ovu izmenu i otvara obrazac za uređivanje u pretpreglednom modu. Dozvoljava dodavanje razloga u opisu izmene.",
+       "tooltip-preferences-save": "Sačuvaj podešavanja",
        "tooltip-summary": "Unesite kratak opis",
        "interlanguage-link-title": "$1 — $2",
        "interlanguage-link-title-nonlang": "$1 — $2",
        "spam_reverting": "Vraćam na poslednju izmenu koja ne sadrži veze do $1",
        "spam_blanking": "Sve izmene sadrže veze do $1. Čistim",
        "spam_deleting": "Sve izmene sadrže veze do $1. Brišem",
-       "simpleantispam-label": "Anti-spama provera. \n<strong>Ne</strong> popunjavaj ovo unutra!",
-       "pageinfo-title": "Podaci o „$1“",
+       "simpleantispam-label": "Anti-spam provera. \n<strong>Ne</strong> popunjavaj ovo unutra!",
+       "pageinfo-title": "Informacije za „$1“",
        "pageinfo-not-current": "Nažalost, nemoguće je pribaviti ove podatke za starije izmene.",
-       "pageinfo-header-basic": "Osnovni podaci",
+       "pageinfo-header-basic": "Osnovne informacije",
        "pageinfo-header-edits": "Istorija izmena",
        "pageinfo-header-restrictions": "Zaštita stranice",
        "pageinfo-header-properties": "Svojstva stranice",
        "pageinfo-length": "Dužina stranice (u bajtovima)",
        "pageinfo-article-id": "ID stranice",
        "pageinfo-language": "Jezik sadržaja stranice",
-       "pageinfo-content-model": "Model sadržaj stranice",
+       "pageinfo-language-change": "promeni",
+       "pageinfo-content-model": "Model sadržaja stranice",
+       "pageinfo-content-model-change": "promeni",
        "pageinfo-robot-policy": "Indeksiranje od strane robota",
        "pageinfo-robot-index": "Dozvoljeno",
        "pageinfo-robot-noindex": "Nije dozvoljeno",
-       "pageinfo-watchers": "Broj nadgledača stranicе",
+       "pageinfo-watchers": "Broj nadgledača stranice",
        "pageinfo-visiting-watchers": "Broj nadgledača stranice koji su posetili skorašnje izmene",
-       "pageinfo-few-watchers": "Manje od $1 {{PLURAL:$1|pratioca|pratilaca}}",
+       "pageinfo-few-watchers": "Manje od $1 {{PLURAL:$1|nadgledača}}",
        "pageinfo-redirects-name": "Broj preusmerenja na ovu stranicu",
-       "pageinfo-subpages-name": "Podstranice ove stranice",
+       "pageinfo-redirects-value": "$1",
+       "pageinfo-subpages-name": "Broj podstranica ove stranice",
        "pageinfo-subpages-value": "$1 ($2 {{PLURAL:$2|preusmerenje|preusmerenja|preusmerenja}}; $3 {{PLURAL:$3|nepreusmerenje|nepreusmerenja|nepreusmerenja}})",
        "pageinfo-firstuser": "Autor stranice",
        "pageinfo-firsttime": "Datum stvaranja stranice",
        "pageinfo-recent-edits": "Broj skorašnjih izmena (u poslednjih $1)",
        "pageinfo-recent-authors": "Broj skorašnjih zasebnih autora",
        "pageinfo-magic-words": "{{PLURAL:$1|Magična reč|Magične reči}} ($1)",
-       "pageinfo-hidden-categories": "{{PLURAL:$1|Skrivena kategorija|Skrivene kategorije}} ($1)",
+       "pageinfo-hidden-categories": "{{PLURAL:$1|Sakrivena kategorija|Sakrivene kategorije}} ($1)",
        "pageinfo-templates": "{{PLURAL:$1|Uključeni šablon|Uključeni šabloni}} ($1)",
        "pageinfo-transclusions": "{{PLURAL:$1|Stranica|Stranice}} uključene u ($1)",
-       "pageinfo-toolboxlink": "Podaci o stranici",
+       "pageinfo-toolboxlink": "Informacije o stranici",
        "pageinfo-redirectsto": "Preusmerava na",
        "pageinfo-redirectsto-info": "podaci",
        "pageinfo-contentpage": "Računa se kao stranica sa sadržajem",
        "pageinfo-protect-cascading-yes": "Da",
        "pageinfo-protect-cascading-from": "Stranice sa prenosivom zaštitom od",
        "pageinfo-category-info": "Informacije o kategoriji",
+       "pageinfo-category-total": "Ukupno",
        "pageinfo-category-pages": "Broj stranica",
        "pageinfo-category-subcats": "Broj potkategorija",
        "pageinfo-category-files": "Broj datoteka",
+       "pageinfo-user-id": "ID korisnika",
+       "pageinfo-file-hash": "Hash vrednost",
        "markaspatrolleddiff": "Označi kao patrolirano",
        "markaspatrolledtext": "Označi stranicu kao patroliranu",
        "markaspatrolledtext-file": "Označi ovu verziju datoteke kao patroliranu",
        "markedaspatrolledtext": "Izabrana izmena stranice [[:$1]] označena je kao patrolirana.",
        "rcpatroldisabled": "Patroliranje skorašnjih izmena je onemogućeno",
        "rcpatroldisabledtext": "Patroliranje skorašnjih izmena je onemogućeno.",
-       "markedaspatrollederror": "Ne mogu da označim kao patrolirano",
+       "markedaspatrollederror": "Ne mogu da označim kao patrolirano.",
        "markedaspatrollederrortext": "Morate izabrati izmenu da biste je označili kao patroliranu.",
        "markedaspatrollederror-noautopatrol": "Ne možete da označite svoje izmene kao patrolirane.",
        "markedaspatrollednotify": "Ova izmena na stranici „$1” označena je kao patrolirana.",
        "markedaspatrollederrornotify": "Označavanje ove izmene patroliranom nije uspelo.",
        "patrol-log-page": "Dnevnik patroliranja",
        "patrol-log-header": "Ovo je dnevnik patroliranih izmena.",
-       "log-show-hide-patrol": "$1 dnevnik patroliranja",
-       "log-show-hide-tag": "$1 dnevnik oznaka",
+       "confirm-markpatrolled-button": "U redu",
+       "confirm-markpatrolled-top": "Označiti izmenu $3 stranice $2 patroliranom?",
        "deletedrevision": "Obrisana stara izmena $1.",
        "filedeleteerror-short": "Greška pri brisanju datoteke: $1",
        "filedeleteerror-long": "Došlo je do grešaka pri brisanju datoteke:\n\n$1",
        "filedelete-archive-read-only": "Server ne može da piše po skladišnoj fascikli ($1).",
        "previousdiff": "← Starija izmena",
        "nextdiff": "Novija izmena →",
-       "mediawarning": "<strong>Upozorenje:</strong> ova vrsta datoteke može sadržati štetan kod.\nAko ga pokrenete, Vaš računar može biti ugrožen.",
+       "mediawarning": "<strong>Upozorenje:</strong> ova vrsta datoteke može sadržati štetan kôd.\nAko ga pokrenete, Vaš računar može biti ugrožen.",
        "imagemaxsize": "Ograničenje veličine slike:<br /><em>(na stranicama za opis datoteka)</em>",
        "thumbsize": "Veličina minijature:",
        "widthheight": "$1 × $2",
        "svg-long-desc": "SVG datoteka, nominalno $1 × $2 piksela, veličina: $3",
        "svg-long-desc-animated": "Animirana SVG datoteka, nominalno: $1 × $2 piksela, veličina: $3",
        "svg-long-error": "Neispravna SVG datoteka: $1",
-       "show-big-image": "Puna veličina",
+       "show-big-image": "Izvorna datoteka",
        "show-big-image-preview": "Veličina ovog prikaza: $1.",
        "show-big-image-preview-differ": "Veličina $3 pregleda za ovu $2 datoteku je $1.",
-       "show-big-image-other": "{{PLURAL:$2|Druga rezolucija|Druge rezolucije}}: $1.",
+       "show-big-image-other": "$2 {{PLURAL:$2|druga rezolucija|druge rezolucije|drugih rezolucija}}: $1.",
        "show-big-image-size": "$1 × $2 piksela",
        "file-info-gif-looped": "petlja",
        "file-info-gif-frames": "$1 {{PLURAL:$1|kadar|kadra|kadrova}}",
        "newimages-summary": "Ova posebna stranica prikazuje poslednje otpremljene datoteke.",
        "newimages-legend": "Filter",
        "newimages-label": "Naziv datoteke (ili njen deo):",
+       "newimages-user": "IP adresa ili korisničko ime",
+       "newimages-newbies": "Prikaži samo doprinose novih korisnika",
        "newimages-showbots": "Prikaži datoteke koje su poslali botovi",
        "newimages-hidepatrolled": "Sakrij patrolirana otpremanja",
+       "newimages-mediatype": "Vrsta datoteke:",
        "noimages": "Nema ništa.",
+       "gallery-slideshow-toggle": "minijature",
        "ilsubmit": "Pretraži",
        "bydate": "po datumu",
        "sp-newimages-showfrom": "prikaži nove datoteke počevši od $1, $2",
        "seconds-abbrev": "$1 s",
        "minutes-abbrev": "$1 m",
        "hours-abbrev": "$1 č",
-       "days-abbrev": "$1 d",
+       "days-abbrev": "$1 d.",
        "seconds": "{{PLURAL:$1|$1 sekunda|$1 sekunda|$1 sekundi}}",
        "minutes": "{{PLURAL:$1|$1 minut|$1 minuta|$1 minuta}}",
        "hours": "{{PLURAL:$1|$1 sat|$1 sata|$1 sati}}",
        "variantname-gan": "gan",
        "variantname-sr-ec": "Ćirilica",
        "variantname-sr-el": "Latinica",
-       "variantname-sr": "Ћир./lat.",
+       "variantname-sr": "Ćir./lat.",
        "variantname-kk-kz": "kk-kz",
        "variantname-kk-tr": "kk-tr",
        "variantname-kk-cn": "kk-cn",
        "variantname-shi-latn": "shi-Latn",
        "variantname-shi": "shi",
        "metadata": "Metapodaci",
-       "metadata-help": "Ova datoteka sadrži dodatne podatke koji verovatno dolaze od digitalnog fotoaparata ili skenera.\nAko je prvobitno stanje datoteke promenjeno, moguće je da neki detalji ne opisuju izmenjenu datoteku.",
+       "metadata-help": "Ova datoteka sadrži dodatne podatke, koji verovatno dolaze od digitalnog fotoaparata ili skenera korišćenog za digitalizaciju.\nAko je prvobitno stanje datoteke promenjeno, moguće je da neki detalji ne opisuju izmenjenu datoteku u potpunosti.",
        "metadata-expand": "Prikaži detalje",
        "metadata-collapse": "Sakrij detalje",
        "metadata-fields": "Polja za metapodatke slike navedena u ovoj poruci će biti uključena na stranici za slike kada se skupi tabela metapodataka. Ostala polja će biti sakrivena po podrazumevanim postavkama.\n* make\n* model\n* datetimeoriginal\n* exposuretime\n* fnumber\n* isospeedratings\n* focallength\n* artist\n* copyright\n* imagedescription\n* gpslatitude\n* gpslongitude\n* gpsaltitude",
        "exif-keywords": "Ključne reči",
        "exif-worldregioncreated": "Oblast sveta gde je slikana fotografija",
        "exif-countrycreated": "Zemlja gde je slikana fotografija",
-       "exif-countrycodecreated": "Kod zemlje gde je slika napravljena",
+       "exif-countrycodecreated": "Kôd zemlje gde je slika napravljena",
        "exif-provinceorstatecreated": "Pokrajina ili država gde je slikana fotografija",
        "exif-citycreated": "Grad gde je slikana fotografija",
        "exif-sublocationcreated": "Oblast grada gde je slikana fotografija",
        "exif-worldregiondest": "Prikazana oblast sveta",
        "exif-countrydest": "Prikazana zemlja",
-       "exif-countrycodedest": "Kod prikazane zemlje",
+       "exif-countrycodedest": "Kôd prikazane zemlje",
        "exif-provinceorstatedest": "Prikazana pokrajina ili država",
        "exif-citydest": "Prikazani grad",
        "exif-sublocationdest": "Prikazana oblast grada",
        "exif-urgency": "Hitnost",
        "exif-fixtureidentifier": "Naziv rubrike",
        "exif-locationdest": "Prikazana lokacija",
-       "exif-locationdestcode": "Kod prikazanog mesta",
+       "exif-locationdestcode": "Kôd prikazanog mesta",
        "exif-objectcycle": "Doba dana za koji je medij namenjen",
        "exif-contact": "Podaci za kontakt",
        "exif-writer": "Pisac",
        "exif-iimsupplementalcategory": "Dopunske kategorije",
        "exif-datetimeexpires": "Ne koristi nakon",
        "exif-datetimereleased": "Objavljeno",
-       "exif-originaltransmissionref": "Izvorni prenos koda lokacije",
+       "exif-originaltransmissionref": "Izvorni prenos kôda lokacije",
        "exif-identifier": "Naznaka",
        "exif-lens": "Korišćeni objektiv",
        "exif-serialnumber": "Serijski broj kamere",
        "exif-contentwarning": "Upozorenje o sadržaju",
        "exif-giffilecomment": "Komentar na datoteku GIF",
        "exif-intellectualgenre": "Vrsta stavke",
-       "exif-subjectnewscode": "Kod predmeta",
-       "exif-scenecode": "IPTC kod scene",
+       "exif-subjectnewscode": "Kôd predmeta",
+       "exif-scenecode": "IPTC kôd scene",
        "exif-event": "Prikazani događaj",
        "exif-organisationinimage": "Prikazana organizacija",
        "exif-personinimage": "Prikazana osoba",
        "exif-compression-34712": "JPEG2000",
        "exif-copyrighted-true": "Zaštićeno autorskim pravom",
        "exif-copyrighted-false": "Nije definisan",
+       "exif-photometricinterpretation-0": "Crno-belo (bela je 0)",
+       "exif-photometricinterpretation-1": "Crno-belo (crna je 0)",
        "exif-photometricinterpretation-2": "RGB",
+       "exif-photometricinterpretation-3": "Paleta",
        "exif-photometricinterpretation-6": "YCbCr",
        "exif-unknowndate": "Nepoznat datum",
        "exif-orientation-1": "Normalno",
        "monthsall": "sve",
        "confirmemail": "Potvrda imejl adrese",
        "confirmemail_noemail": "Niste uneli ispravnu imejl adresu u [[Special:Preferences|podešavanjima]].",
-       "confirmemail_text": "{{SITENAME}} zahteva da potvrdite imejl adresu pre nego što počnete da koristite mogućnosti imejla.\nKliknite na dugme ispod za slanje poruke na vašu adresu.\nU poruci će se nalaziti veza s potvrdnim kodom;\nunesite je u pregledač da biste potvrdili da je vaša imejl adresa ispravna.",
-       "confirmemail_pending": "Potvrdni kod vam je već poslat. Ako ste upravo otvorili nalog, onda verovatno treba da sačekate nekoliko minuta da pristigne, pre nego što ponovo zatražite novi kod.",
-       "confirmemail_send": "Pošalji potvrdni kod",
+       "confirmemail_text": "{{SITENAME}} zahteva da potvrdite imejl adresu pre nego što počnete da koristite mogućnosti imejla.\nKliknite na dugme ispod za slanje poruke na vašu adresu.\nU poruci će se nalaziti veza s potvrdnim kôdom;\nunesite je u pregledač da biste potvrdili da je vaša imejl adresa ispravna.",
+       "confirmemail_pending": "Potvrdni kôd vam je već poslat. Ako ste upravo otvorili nalog, onda verovatno treba da sačekate nekoliko minuta da pristigne, pre nego što ponovo zatražite novi kôd.",
+       "confirmemail_send": "Pošalji potvrdni kôd",
        "confirmemail_sent": "Potvrdna poruka je poslata.",
-       "confirmemail_oncreate": "Poslat je potvrdni kod na vašu imejl adresu.\nOvaj kod nije potreban za prijavljivanje, ali vam treba da biste uključili mogućnosti imejla na vikiju.",
+       "confirmemail_oncreate": "Poslat je potvrdni kôd na vašu imejl adresu.\nOvaj kôd nije potreban za prijavljivanje, ali vam treba da biste uključili mogućnosti imejla na vikiju.",
        "confirmemail_sendfailed": "{{SITENAME}} ne može da pošalje imejl potvrdu.\nProverite da li je imejl adresa pravilno napisana.\n\nGreška: $1",
        "confirmemail_invalid": "Potvrdni kod je neispravan. Verovatno je istekao.",
        "confirmemail_needlogin": "Morate biti $1 da biste potvrdili imejl adresu.",
        "confirmemail_body_set": "Neko, verovatno vi, sa IP adrese $1,\npromenio je imejl adresu naloga „$2“ u ovu adresu na {{SITENAME}}.\n\nDa bismo potvrdili da ovaj nalog stvarno pripada vama i ponovo aktivirali\nmogućnosti imejla na {{SITENAME}}, otvorite sledeću vezu u pregledaču:\n\n$3\n\nAko nalog *ne* pripada vama, pratite sledeću vezu da otkažete potvrdu imejl adrese:\n\n$5\n\nOvaj potvrdni kod ističe $4.",
        "confirmemail_invalidated": "Potvrda imejl adrese je otkazana",
        "invalidateemail": "Otkazivanje potvrde imejla",
+       "notificationemail_body_changed": "Neko, verovatno Vi je promenio imejl adresu naloga iz $2“ u „$3“ sa IP adrese $1 na sajtu {{SITENAME}}.\n\nAko ovo niste bili Vi, odmah obavestite administratore sajta.",
+       "notificationemail_body_removed": "Neko, verovatno Vi sa IP adrese $1 je uklonio imejl adresu za nalog „$2“ na {{SITENAME}}.\n\n\nAko ovo niste bili Vi, odmah obavestite administratore sajta.",
        "scarytranscludedisabled": "[Međuviki uključivanje šablona je onemogućeno]",
        "scarytranscludefailed": "[Dobavljanje šablona za $1 nije uspelo]",
        "scarytranscludefailed-httpstatus": "[Ne mogu da preuzmem šablon $1: HTTP $2]",
        "confirmrecreate": "{{GENDER:$1|Korisnik|Korisnica}} [[User:$1|$1]] ([[User talk:$1|razgovor]]) je {{GENDER:$1|obrisao|obrisala}} ovu stranicu nakon što ste počeli da je uređujete iz sledećeg razloga:\n: <em>$2</em>\nPotvrdite da stvarno želite da napravite stranicu.",
        "confirmrecreate-noreason": "{{GENDER:$1|Korisnik|Korisnica}} [[User:$1|$1]] ([[User talk:$1|razgovor]]) je {{GENDER:$1|obrisao|obrisala}} ovu stranicu nakon što ste počeli da je uređujete. Potvrdite da stvarno želite da ponovo napravite ovu stranicu.",
        "recreate": "Ponovo napravi",
-       "unit-pixel": "px",
+       "unit-pixel": "p",
+       "confirm-purge-title": "Osveži ovu stranicu",
        "confirm_purge_button": "U redu",
        "confirm-purge-top": "Očistiti privremenu memoriju ove stranice?",
        "confirm-purge-bottom": "Ova radnja čisti privremenu memoriju i prikazuje najnoviju izmenu.",
        "confirm-watch-top": "Dodati ovu stranicu u spisak nadgledanja?",
        "confirm-unwatch-button": "U redu",
        "confirm-unwatch-top": "Ukloniti ovu stranicu sa spiska nadgledanja?",
+       "confirm-rollback-button": "U redu",
+       "confirm-rollback-top": "Vrati izmene na ovoj stranici?",
        "semicolon-separator": ";&#32;",
        "comma-separator": ",&#32;",
        "colon-separator": ":&#32;",
        "autosumm-blank": "Uklonjen celokupan sadržaj stranice",
        "autosumm-replace": "Zamenjen sadržaj stranice sa „$1“",
        "autoredircomment": "Preusmerenje na [[$1]]",
+       "autosumm-removed-redirect": "Uklonjeno preusmerenje ka [[$1]]",
+       "autosumm-changed-redirect-target": "Promenjena odredišna stranica u preusmerenju iz [[$1]] u [[$2]]",
        "autosumm-new": "Nova stranica: $1",
        "autosumm-newblank": "Napravljena prazna stranica",
        "size-bytes": "$1 {{PLURAL:$1|bajt|bajta|bajtova}}",
        "watchlistedit-clear-removed": "{{PLURAL:$1|1 naslov je uklonjen|$1 naslova su uklonjena|$1 naslova je uklonjeno}}:",
        "watchlistedit-too-many": "Ima previše stranica za prikaz ovde.",
        "watchlisttools-clear": "isprazni spisak nadgledanja",
-       "watchlisttools-view": "Prikaži srodne izmene",
+       "watchlisttools-view": "prikaži srodne izmene",
        "watchlisttools-edit": "prikaži i uredi spisak nadgledanja",
        "watchlisttools-raw": "izmeni sirov spisak nadgledanja",
        "iranian-calendar-m1": "Farvardin",
        "hebrew-calendar-m6": "Adar",
        "hebrew-calendar-m6a": "Adar I",
        "hebrew-calendar-m6b": "Adar II",
-       "hebrew-calendar-m7": "Nisane",
+       "hebrew-calendar-m7": "Nisan",
        "hebrew-calendar-m8": "Ijar",
        "hebrew-calendar-m9": "Sivan",
        "hebrew-calendar-m10": "Tamuz",
        "hebrew-calendar-m6-gen": "Adar",
        "hebrew-calendar-m6a-gen": "Adar I",
        "hebrew-calendar-m6b-gen": "Adar II",
-       "hebrew-calendar-m7-gen": "Nisane",
+       "hebrew-calendar-m7-gen": "Nisan",
        "hebrew-calendar-m8-gen": "Ijar",
        "hebrew-calendar-m9-gen": "Sivan",
        "hebrew-calendar-m10-gen": "Tamuz",
        "hebrew-calendar-m12-gen": "Elul",
        "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|razgovor]])",
        "timezone-utc": "UTC",
+       "timezone-local": "Lokalno",
        "duplicate-defaultsort": "<strong>Upozorenje:</strong> Podrazumevani ključ svrstavanja „$2“ menja raniji podrazumevani ključ svrstavanja „$1“.",
        "duplicate-displaytitle": "<strong>Upozorenje:</strong> naslov za prikaz „$2“ zameniće postojeći „$1“.",
        "restricted-displaytitle": "<strong>Upozorenje:</strong> Naslov za prikaz „$1” je ignorisan pošto nije ekvivalentan stvarnom naslovu stranice.",
        "version-specialpages": "Posebne stranice",
        "version-parserhooks": "Kuke raščlanjivača",
        "version-variables": "Promenljive",
+       "version-editors": "Za uređivanje",
        "version-antispam": "Sprečavanje nepoželjnih poruka",
        "version-api": "API",
        "version-other": "Drugo",
        "version-ext-license": "Licenca",
        "version-ext-colheader-name": "Ekstenzija",
        "version-skin-colheader-name": "Tema",
-       "version-ext-colheader-version": "Verzija",
+       "version-ext-colheader-version": "Izdanje",
        "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 ovu ekstenziju nije nađena informacija o licenci.",
+       "version-credits-title": "Zasluge za $1",
+       "version-credits-not-found": "Za ovu ekstenziju nije nađena informacija o zaslugama.",
        "version-poweredby-credits": "Ovaj viki pokreće '''[https://www.mediawiki.org/ Medijaviki]''', autorska prava © 2001-$1 $2.",
        "version-poweredby-others": "ostali",
        "version-poweredby-translators": "translatewiki.net prevodioci",
        "version-credits-summary": "Želeli bismo da zahvalimo sledećim ljudima na njihovom doprinosu [[Special:Version|Medijavikiji]].",
-       "version-license-info": "Medijaviki je slobodan softver možete ga redistribuirati i/ili modifikovati pod uslovima GNU-ove opšte javne licence verzija 2 ili svake sledeće koju objavi Zadužbina za slobodan softver.\n\nMedijaviki se redistribuira u nadi da će biti od koristi, ali BEZ IKAKVE GARANCIJE čak i bez PODRAZUMEVANE GARANCIJE FUNKCIONALNOSTI ili PRIKLADNOSTI ZA ODREĐENEU NAMENU. Pogledajte GNU-ovu opštu javnu licencu za više informacija.\n\nTrebalo bi da ste dobili [{{SERVER}}{{SCRIPTPATH}}/COPYING primerak GNU-ove opšte javne licence] zajedno sa ovim programom. Ako niste, pišite na Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA ili [//www.gnu.org/licenses/old-licenses/gpl-2.0.html pročitajte ovde].",
+       "version-license-info": "Medijaviki je slobodan softver možete ga redistribuirati i/ili modifikovati pod uslovima GNU-ove opšte javne licence verzija 2 ili svake sledeće koju objavi Zadužbina za slobodan softver.\n\nMedijaviki se redistribuira u nadi da će biti od koristi, ali <em>BEZ IKAKVE GARANCIJE</em> čak i bez <strong>PODRAZUMEVANE GARANCIJE FUNKCIONALNOSTI</strong> ili <strong>PRIKLADNOSTI ZA ODREĐENEU NAMENU</strong>. Pogledajte GNU-ovu opštu javnu licencu za više informacija.\n\nTrebalo bi da ste dobili [{{SERVER}}{{SCRIPTPATH}}/COPYING primerak GNU-ove opšte javne licence] zajedno sa ovim programom. Ako niste, pišite na Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA ili [//www.gnu.org/licenses/old-licenses/gpl-2.0.html pročitajte ovde].",
        "version-software": "Instalirani softver",
        "version-software-product": "Proizvod",
-       "version-software-version": "Verzija",
+       "version-software-version": "Izdanje",
        "version-entrypoints": "Adrese ulazne tačke",
        "version-entrypoints-header-entrypoint": "Ulazna tačka",
        "version-entrypoints-header-url": "Adresa",
        "version-libraries-license": "Licenca",
        "version-libraries-description": "Opis",
        "version-libraries-authors": "Autori",
-       "redirect": "Preusmerenje na datoteku, korisnika, stranicu ili izmenu",
+       "redirect": "Preusmerenje na datoteku, korisnika, stranicu, izmenu ili dnevnik (ID)",
+       "redirect-summary": "Ova posebna stranica preusmerava do datoteke (s datim imenom datoteke), stranice (s datim ID-om izmene ili ID-om stranice), korisničke stranice (s datim numeričkim korisničkim ID-om), ili unosa u dnevniku (s datim dnevničkim ID-om). Upotreba: [[{{#Special:Redirect}}/file/Example.jpg]], [[{{#Special:Redirect}}/page/64308]], [[{{#Special:Redirect}}/revision/328429]], [[{{#Special:Redirect}}/user/101]], or [[{{#Special:Redirect}}/logid/186]].",
        "redirect-submit": "Idi",
        "redirect-lookup": "Tip vrednosti:",
        "redirect-value": "Vrednost:",
        "redirect-user": "Korisnički ID",
        "redirect-page": "ID stranice",
-       "redirect-revision": "Verzija stranice",
+       "redirect-revision": "Izmena stranice",
        "redirect-file": "Naziv datoteke",
-       "redirect-not-exists": "Vrednost nije pronađen",
-       "fileduplicatesearch": "Pretraga duplikata",
+       "redirect-logid": "ID dnevnika",
+       "redirect-not-exists": "Vrednost nije pronađena",
+       "fileduplicatesearch": "Pretraži duplikate",
        "fileduplicatesearch-summary": "Pretraga dupliranih datoteka prema heš vrednosti.",
        "fileduplicatesearch-filename": "Naziv datoteke:",
        "fileduplicatesearch-submit": "Pretraži",
        "specialpages-group-highuse": "Najčešće korišćene stranice",
        "specialpages-group-pages": "Spiskovi stranica",
        "specialpages-group-pagetools": "Alatke",
-       "specialpages-group-wiki": "Podaci i alati",
+       "specialpages-group-wiki": "Podaci i alatke",
        "specialpages-group-redirects": "Preusmeravanje posebnih stranica",
        "specialpages-group-spam": "Alatke protiv nepoželjnih poruka",
-       "specialpages-group-developer": "Programerski alati",
+       "specialpages-group-developer": "Programerske alatke",
        "blankpage": "Prazna stranica",
        "intentionallyblankpage": "Ova stranica je namerno ostavljena praznom.",
        "external_image_whitelist": " #Ostavite ovaj red onakvim kakav jeste<pre>\n#Ispod dodajte odlomke regularnih izraza (samo deo koji se nalazi između //)\n#Oni će biti upoređeni s adresama spoljašnjih slika\n#One koje se poklapaju biće prikazane kao slike, a preostale kao veze do slika\n#Redovi koji počinju s tarabom se smatraju komentarima\n#Svi unosi su osetljivi na mala i velika slova\n\n#Dodajte sve odlomke regularnih izraza iznad ovog reda. Ovaj red ne dirajte</pre>",
        "tags": "Važeće oznake izmena",
        "tag-filter": "Filter za [[Special:Tags|oznake]]:",
        "tag-filter-submit": "Filtriraj",
-       "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|Oznaka|Oznake}}]]: $2)",
+       "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|oznaka|oznake}}]]: $2)",
+       "tag-mw-contentmodelchange": "promena modela sadržaja",
        "tag-mw-contentmodelchange-description": "Izmene koje menjaju model sadržaja stranice",
-       "tag-mw-rollback": "Vraćanje",
+       "tag-mw-new-redirect": "novo preusmerenje",
+       "tag-mw-new-redirect-description": "Izmene kojima je napravljeno novo preusmerenje ili je stranica izmenjena da bude preusmerenje",
+       "tag-mw-removed-redirect": "uklonjeno preusmerenje",
+       "tag-mw-removed-redirect-description": "Izmene koje menjaju postojeće preusmerenje u stranicu bez preusmerenja",
+       "tag-mw-changed-redirect-target": "promenjeno odredište preusmerenja",
+       "tag-mw-changed-redirect-target-description": "Izmene koje menjaju odredište preusmerenja",
+       "tag-mw-blank": "stranica ispražnjena",
+       "tag-mw-blank-description": "Izmene koje brišu čitav sadržaj stranice",
+       "tag-mw-replace": "uklonjena većina teksta",
+       "tag-mw-replace-description": "Izmene koje uklanjaju više od 90% sadržaja stranice",
+       "tag-mw-rollback": "vraćanje",
+       "tag-mw-rollback-description": "Izmene koje vraćaju stranicu na prethodne izmene",
+       "tag-mw-undo": "poništenje",
+       "tag-mw-undo-description": "Izmene koje poništavaju prethodne izmene",
        "tags-title": "Oznake",
        "tags-intro": "Na ovoj stranici je naveden spisak oznaka s kojima program može da označi izmene i njegovo značenje.",
        "tags-tag": "Naziv oznake",
        "tags-edit": "uredi",
        "tags-delete": "obriši",
        "tags-activate": "aktiviraj",
-       "tags-deactivate": "dekativiraj",
+       "tags-deactivate": "deaktiviraj",
        "tags-hitcount": "$1 {{PLURAL:$1|izmena|izmene|izmena}}",
        "tags-manage-no-permission": "Nemate dozvolu da menjate oznake.",
        "tags-create-heading": "Nova oznaka",
        "tags-delete-reason": "Razlog:",
        "tags-delete-submit": "Nepovratno obriši ovu oznaku",
        "tags-delete-not-found": "Oznaka „$1“ ne postoji.",
+       "tags-delete-too-many-uses": "Oznaka „$1” je primenjena na više od $2 {{PLURAL:$2|izmene|izmena}}, što znači da se ne može obrisati.",
+       "tags-delete-no-permission": "Nemate dozvolu da brišete oznake za izmenu.",
        "tags-activate-title": "Aktiviranje oznaka",
        "tags-activate-question": "Aktivirate oznaku „$1“.",
        "tags-activate-reason": "Razlog:",
        "tags-deactivate-reason": "Razlog:",
        "tags-deactivate-not-allowed": "Nije moguće deaktivirati oznaku „$1“.",
        "tags-deactivate-submit": "Dekativiraj",
+       "tags-update-no-permission": "Nemate dozvolu za dodavanje ili uklanjanje oznake izmena iz zasebnih izmena ili unosa u dnevniku.",
+       "tags-update-blocked": "Ne možete dodavati niti uklanjati oznake izmena dok {{GENDER:$1|ste}} blokirani.",
+       "tags-update-add-not-allowed-one": "Nije dozvoljeno da se oznaka „$1” dodaje ručno.",
        "tags-edit-title": "Uredi oznake",
        "tags-edit-manage-link": "Upravljaj oznakama",
        "tags-edit-existing-tags": "Postojeće oznake:",
+       "tags-edit-existing-tags-none": "<em>Nema</em>",
        "tags-edit-new-tags": "Nove oznake:",
+       "tags-edit-add": "Dodaj ove oznake:",
+       "tags-edit-remove": "Ukloni ove oznake:",
+       "tags-edit-remove-all-tags": "(ukloni sve oznake)",
+       "tags-edit-chosen-placeholder": "Izaberi neke oznake",
+       "tags-edit-chosen-no-results": "Odgovarajuće oznake nisu pronađene",
        "tags-edit-reason": "Razlog:",
+       "tags-edit-success": "Izmene su primenjene.",
+       "tags-edit-failure": "Ne mogu da primenim izmene:\n$1",
+       "tags-edit-nooldid-title": "Neispravna odredišna izmena",
+       "tags-edit-none-selected": "Izaberite bar jednu oznaku koju treba dodati ili ukloniti.",
        "comparepages": "Upoređivanje stranica",
        "compare-page1": "Stranica 1",
        "compare-page2": "Stranica 2",
        "compare-invalid-title": "Navedeni naslov je neispravan.",
        "compare-title-not-exists": "Navedeni naslov ne postoji.",
        "compare-revision-not-exists": "Navedena izmena ne postoji.",
-       "diff-form": "'''forma'''",
-       "permanentlink": "Stalna veza",
+       "diff-form": "Razlike",
+       "diff-form-oldid": "ID stare izmene (neobavezno)",
+       "diff-form-revid": "ID izmene ili razlike",
+       "diff-form-submit": "Prikaži razlike",
+       "permanentlink": "Trajna veza",
+       "permanentlink-revid": "ID izmene",
+       "permanentlink-submit": "Idi na izmenu",
        "dberr-problems": "Došlo je do tehničkih problema.",
        "dberr-again": "Sačekajte nekoliko minuta i ponovo učitajte stranicu.",
        "dberr-info": "(Ne mogu pristupiti bazi podataka: $1)",
        "htmlform-int-toolow": "Navedena vrednost je ispod minimuma od $1",
        "htmlform-int-toohigh": "Navedena vrednost je iznad maksimuma od $1",
        "htmlform-required": "Ova vrednost je obavezna.",
-       "htmlform-submit": "Pošalji",
+       "htmlform-submit": "Postavi",
        "htmlform-reset": "Vrati izmene",
        "htmlform-selectorother-other": "Drugo",
        "htmlform-no": "Ne",
        "htmlform-cloner-create": "Dodaj još",
        "htmlform-cloner-delete": "Ukloni",
        "htmlform-cloner-required": "Bar jedna vrednost je potrebna.",
+       "htmlform-date-placeholder": "GGGG-MM-DD",
+       "htmlform-time-placeholder": "ČČ:MM:SS",
+       "htmlform-datetime-placeholder": "GGGG-MM-DD ČČ:MM:SS",
        "htmlform-title-badnamespace": "[[:$1]] nije u imenskom prostoru „{{ns:$2}}“.",
+       "htmlform-title-not-creatable": "Stranica „$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> nije ispravno korisničko ime.",
        "logentry-delete-delete": "$1 je {{GENDER:$2|obrisao|obrisala}} stranicu $3",
        "logentry-delete-delete_redir": "$1 je {{GENDER:$2|obrisao|obrisala}} preusmerenje $3 prepisivanjem",
-       "logentry-delete-restore": "$1 je {{GENDER:$2|vratio|vratila}} stranicu $3",
+       "logentry-delete-restore": "$1 je {{GENDER:$2|vratio|vratila}} stranicu $3 ($4)",
+       "logentry-delete-restore-nocount": "$1 je {{GENDER:$2|vratio|vratila}} stranicu $3",
+       "restore-count-revisions": "{{PLURAL:$1|1 izmena|$1 izmene|$1 izmena}}",
+       "restore-count-files": "{{PLURAL:$1|1 datoteka|$1 datoteke|$1 datoteka}}",
        "logentry-delete-event": "$1 je {{GENDER:$2|promenio|promenila}} vidljivost {{PLURAL:$5|1=događaja|$5 događaja}} u dnevniku $3: $4",
        "logentry-delete-revision": "$1 je {{GENDER:$2|promenio|promenila}} vidljivost {{PLURAL:$5|1=jedne izmene|$5 izmene|$5 izmena}} na stranici $3: $4",
        "logentry-delete-event-legacy": "$1 je {{GENDER:$2|promenio|promenila}} vidljivost događaja u dnevniku $3",
        "logentry-delete-revision-legacy": "$1 je {{GENDER:$2|promenio|promenila}} vidljivost izmena na stranici $3",
        "logentry-suppress-delete": "$1 je {{GENDER:$2|potisnuo|potisnula}} stranicu $3",
-       "logentry-suppress-event": "$1 je tajno {{GENDER:$2|promenio|promenila}} vidljivost {{PLURAL:$5|1=događaja|$5 događaja}} u dnevniku $3: $4",
+       "logentry-suppress-event": "$1 je tajno {{GENDER:$2|promenio|promenila}} vidljivost {{PLURAL:$5|događaja|$5 događaja}} u dnevniku $3: $4",
        "logentry-suppress-revision": "$1 je tajno {{GENDER:$2|promenio|promenila}} vidljivost {{PLURAL:$5|izmene|$5 izmena}} na stranici $3: $4",
-       "logentry-suppress-event-legacy": "$1 је tajno {{GENDER:$2|promenio|promenila}} vidljivost događaj u dnevniku $3",
+       "logentry-suppress-event-legacy": "$1 je potajno {{GENDER:$2|promenio|promenila}} vidljivost događaja u dnevniku $3",
        "logentry-suppress-revision-legacy": "$1 je tajno {{GENDER:$2|promenio|promenila}} vidljivost izmena na stranici $3",
        "revdelete-content-hid": "sadržaj je sakriven",
        "revdelete-summary-hid": "opis izmene je sakriven",
        "logentry-import-upload": "$1 je {{GENDER:$2|uvezao|uvezla}} $3 otpremanjem datoteke",
        "logentry-import-upload-details": "$1 je {{GENDER:$2|uvezao|uvezla}} $3 otpremanjem datoteke ($4 {{PLURAL:$4|izmena|izmene|izmena}})",
        "logentry-import-interwiki": "$1 je {{GENDER:$2|uvezao|uvezla}} $3 s drugog vikija",
-       "logentry-import-interwiki-details": "$1 је {{GENDER:$2|увезао|увезла}} $3 из $5 ($4 {{PLURAL:$4|1=измена|измене|измена}})",
+       "logentry-import-interwiki-details": "$1 je {{GENDER:$2|uvezao|uvezla}} $3 iz $5 ($4 {{PLURAL:$4|1=izmena|izmene|izmena}})",
        "logentry-merge-merge": "$1 je {{GENDER:$2|spojio|spojila}} $3 u $4 (sve do izmene $5)",
        "logentry-move-move": "$1 je {{GENDER:$2|premestio|premestila}} stranicu $3 na $4",
        "logentry-move-move-noredirect": "$1 je {{GENDER:$2|premestio|premestila}} stranicu $3 na $4 bez ostavljanja preusmerenja",
        "logentry-move-move_redir": "$1 je {{GENDER:$2|premestio|premestila}} stranicu $3 na $4 preko preusmerenja",
-       "logentry-move-move_redir-noredirect": "$1 je {{GENDER:|premestio|premestila}} stranicu $3 na $4 preko preusmerenja bez ostavljanja preusmerenja",
+       "logentry-move-move_redir-noredirect": "$1 je {{GENDER:$2|premestio|premestila}} stranicu $3 na $4 preko preusmerenja bez ostavljanja preusmerenja",
        "logentry-patrol-patrol": "$1 je {{GENDER:$2|označio|označila}} izmenu $4 stranice $3 kao patroliranu",
        "logentry-patrol-patrol-auto": "$1 je automatski {{GENDER:$2|označio|označila}} izmenu $4 stranice $3 kao patroliranu",
        "logentry-newusers-newusers": "$1 je {{GENDER:$2|otvorio|otvorila}} korisnički nalog",
        "logentry-newusers-create": "$1 je {{GENDER:$2|otvorio|otvorila}} korisnički nalog",
        "logentry-newusers-create2": "$1 je {{GENDER:$2|otvorio|otvorila}} korisnički nalog $3",
-       "logentry-newusers-byemail": "$1 je {{GENDER:$2|otvorio|otvorila}} korisnički nalog $3 i lozinka je poslata na imejl",
+       "logentry-newusers-byemail": "$1 je {{GENDER:$2|napravio|napravila}} korisnički nalog $3 i lozinka je poslata na imejl",
        "logentry-newusers-autocreate": "Korisnički nalog $1 je automatski {{GENDER:$2|otvoren}}",
-       "logentry-protect-move_prot": "$1 je {{GENDER:$2|premestio|premestila}} postavke zaštite sa $4 na $3",
+       "logentry-protect-move_prot": "$1 je {{GENDER:$2|premestio|premestila}} podešavanja zaštite sa $4 na $3",
        "logentry-protect-unprotect": "$1 je {{GENDER:$2|skinuo|skinula}} zaštitu sa stranice $3",
        "logentry-protect-protect": "$1 je {{GENDER:$2|zaštitio|zaštitila}} $3 $4",
        "logentry-protect-protect-cascade": "$1 je {{GENDER:$2|zaštitio|zaštitila}} $3 $4 [prenosiva zaštita]",
        "logentry-protect-modify-cascade": "$1 je {{GENDER:$2|promenio|promenila}} stepen zaštite za $3 $4 [prenosiva zaštita]",
        "logentry-rights-rights": "$1 je {{GENDER:$2|promenio|promenila}} članstvo grupe za {{GENDER:$6|$3}} iz $4 u $5",
        "logentry-rights-rights-legacy": "$1 je {{GENDER:$2|promenio|promenila}} članstvo grupe za $3",
-       "logentry-rights-autopromote": "$1 je automatski {{GENDER:$1|unapređen|unapređena}} iz $4 u $5",
+       "logentry-rights-autopromote": "$1 je automatski {{GENDER:$2|unapređen|unapređena}} iz $4 u $5",
        "logentry-upload-upload": "$1 je {{GENDER:$2|otpremio|otpremila}} $3",
        "logentry-upload-overwrite": "$1 je {{GENDER:$2|otpremio|otpremila}} novu verziju $3",
        "logentry-upload-revert": "$1 je {{GENDER:$2|otpremio|otpremila}} $3",
        "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": "Urađeno",
-       "feedback-external-bug-report-button": "Prijavi bag",
+       "feedback-external-bug-report-button": "Prijavi grešku",
+       "feedback-dialog-title": "Slanje povratne informacije",
        "feedback-error1": "Greška: neprepoznat rezultat od API-ja",
        "feedback-error2": "Greška: uređivanje nije uspelo",
        "feedback-error3": "Greška: nema odgovora od API-ja",
        "feedback-termsofuse": "Prihvatam da pošaljem povratne informacije u skladu sa uslovima korišćenja.",
        "feedback-thanks": "Hvala! Vaša povratna informacija je postavljena na stranicu „[$2 $1]“.",
        "feedback-thanks-title": "Hvala vam!",
+       "feedback-useragent": "Korisnički agent:",
        "searchsuggest-search": "Pretraga",
        "searchsuggest-containing": "sadrži...",
        "api-error-badtoken": "Unutrašnja greška: neispravan žeton.",
        "api-error-emptypage": "Stvaranje novih praznih stranica nije dozvoljeno.",
        "api-error-publishfailed": "Unutrašnja greška: server nije uspeo da objavi privremenu datoteku.",
        "api-error-stashfailed": "Unutrašnja greška: server ne može da sačuva 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|sekund|sekunda|sekundi}}",
        "duration-minutes": "$1 {{PLURAL:$1|minut|minuta|minuta}}",
        "limitreport-expensivefunctioncount": "Broj „skupih” funkcija analizatora",
        "limitreport-unstrip-depth": "Unstrip dubina rekurzije",
        "limitreport-unstrip-size": "Unstrip veličina nakon proširenja",
+       "limitreport-unstrip-size-value": "$1/$2 {{PLURAL:$2|bajt|bajta|bajtova}}",
        "expandtemplates": "Zamena šablona",
-       "expand_templates_intro": "Ova posebna stranica uzima tekst i menja sve šablone u njemu rekurzivno.\nTakođe menja funkcije parsera kao što je <code><nowiki>{{</nowiki>#language:…}}</code> i promenljive kao što je <code><nowiki>{{</nowiki>CURRENTDAY}}</code>.\nZapravo praktično sve što se nalazi između vitičastih zagrada.",
+       "expand_templates_intro": "Ova posebna stranica uzima vikitekst i menja sve šablone u njemu rekurzivno.\nTakođe menja funkcije parsera kao što je <code><nowiki>{{</nowiki>#language:…}}</code> i promenljive kao što je <code><nowiki>{{</nowiki>CURRENTDAY}}</code>. \nZapravo praktično sve što se nalazi između vitičastih zagrada.",
        "expand_templates_title": "Naziv konteksta; za {{STRANICA}} itd.:",
-       "expand_templates_input": "Unos:",
+       "expand_templates_input": "Unos vikiteksta:",
        "expand_templates_output": "Rezultat",
        "expand_templates_xml_output": "XML izlaz",
        "expand_templates_html_output": "Sirov HTML izlaz",
        "expand_templates_generate_xml": "Prikaži XML stablo",
        "expand_templates_generate_rawhtml": "Prikaži sirov HTML",
        "expand_templates_preview": "Pretpregled",
+       "pagelanguage": "Promeni jezik stranice",
        "pagelang-name": "Stranica",
        "pagelang-language": "Jezik",
+       "pagelang-use-default": "Koristi podrazumevani jezik",
        "pagelang-select-lang": "Izaberi jezik",
+       "pagelang-reason": "Razlog",
        "pagelang-submit": "Pošalji",
+       "pagelang-nonexistent-page": "Stranica $1 ne postoji.",
+       "pagelang-unchanged-language": "Stranica $1  je već postavljena na jezik $2.",
+       "pagelang-db-failed": "Baza podataka nije uspela promeniti jezik stranice.",
        "right-pagelang": "menjanje jezika stranice",
        "action-pagelang": "promenu jezika stranice",
+       "log-name-pagelang": "Dnevnik promene jezika",
+       "log-description-pagelang": "Ovo je dnevnik izmena u jezicima stranica.",
        "logentry-pagelang-pagelang": "$1 je {{GENDER:$2|promenio|promenila}} jezik stranice $3 iz $4 u $5.",
+       "default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (omogućena)",
        "mediastatistics": "Statistika datoteka",
        "mediastatistics-summary": "Statistike o tipovima poslatih datoteka. Ovde su uračunate samo najnovije verzije datoteka. Stare ili obrisane verzije nisu uračunate.",
+       "mediastatistics-nbytes": "{{PLURAL:$1|$1 bajt|$1 bajta|$1 bajtova}} ($2; $3%)",
+       "mediastatistics-bytespertype": "Ukupna veličina datoteke ovog odeljka: {{PLURAL:$1|$1 bajt|$1 bajta|$1 bajtova}} ($2; $3%).",
+       "mediastatistics-allbytes": "Ukupna veličina svih datoteka: {{PLURAL:$1|$1 bajt|$1 bajta|$1 bajtova}} ($2).",
        "mediastatistics-table-mimetype": "MIME tip",
        "mediastatistics-table-extensions": "Moguće ekstenzije",
        "mediastatistics-table-count": "Broj datoteka",
        "mediastatistics-header-executable": "Izvršne",
        "mediastatistics-header-archive": "Kompresovane",
        "mediastatistics-header-total": "Sve datoteke",
+       "json-warn-trailing-comma": "$1 {{PLURAL:$1|prateća tačka je uklonjena|prateće tačke su uklonjene|pratećih tački je uklonjeno}} iz JSON-a",
+       "json-error-unknown": "Dogodio se problem s JSON-om. Greška: $1",
+       "json-error-depth": "Prekoračena je najveća dubina",
+       "json-error-state-mismatch": "Nevalidan ili pokvareni JSON",
+       "json-error-ctrl-char": "Greška kontrolnog simbola, moguće je da je neispravno enkodiran",
        "json-error-syntax": "Greška u sintaksi",
+       "json-error-utf8": "Malformirani UTF-8 znaci, moguće je da su neispravno enkodirani",
+       "json-error-recursion": "Jedna ili više rekurzivnih referenci u vrednosti koju treba enkodirati.",
+       "json-error-inf-or-nan": "Jedna ili više NAN ili INF vrednosti u vrednosti koju treba enkodirati",
+       "json-error-unsupported-type": "Data je vrednos vrste koja se ne može enkodirati",
        "headline-anchor-title": "Veza do ovog odeljka",
        "special-characters-group-latin": "Latinica",
        "special-characters-group-latinextended": "Proširena latinica",
        "special-characters-group-thai": "Tajlandski",
        "special-characters-group-lao": "Laoski",
        "special-characters-group-khmer": "Kmerski",
+       "special-characters-group-canadianaboriginal": "Kanadski aboridžinski",
+       "special-characters-title-endash": "crtica",
+       "special-characters-title-emdash": "duga crtica",
+       "special-characters-title-minus": "minus",
        "mw-widgets-dateinput-no-date": "Datum nije izabran",
        "mw-widgets-dateinput-placeholder-day": "GGGG-MM-DD",
        "mw-widgets-dateinput-placeholder-month": "GGGG-MM",
+       "mw-widgets-mediasearch-input-placeholder": "Pretražite datoteke",
+       "mw-widgets-mediasearch-noresults": "Nema rezultata.",
        "mw-widgets-titleinput-description-new-page": "stranica još uvek ne postoji",
        "mw-widgets-titleinput-description-redirect": "preusmerava na $1",
+       "mw-widgets-categoryselector-add-category-placeholder": "Dodaj kategoriju...",
        "mw-widgets-usersmultiselect-placeholder": "Dodaj još...",
+       "date-range-from": "Od datuma:",
+       "date-range-to": "Do datuma:",
+       "sessionprovider-generic": "$1 sesije",
+       "sessionprovider-mediawiki-session-cookiesessionprovider": "sesije sa kolačićima",
+       "sessionprovider-nocookies": "Kolačići su možda onemogućeni. Uverite se da su kolačići omogućeni i počnite ponovo.",
        "randomrootpage": "Slučajna korenska stranica",
+       "log-action-filter-block": "Tip blokiranja:",
+       "log-action-filter-contentmodel": "Tip promene modela sadržaja:",
+       "log-action-filter-delete": "Tip brisanja:",
+       "log-action-filter-import": "Tip uvoza:",
+       "log-action-filter-managetags": "Tip uređivanja oznaka:",
+       "log-action-filter-move": "Tip premeštanja:",
+       "log-action-filter-newusers": "Tip novog naloga:",
+       "log-action-filter-patrol": "Tip patroliranja:",
+       "log-action-filter-protect": "Tip zaključavanja:",
+       "log-action-filter-rights": "Tip promene korisničkih prava:",
+       "log-action-filter-suppress": "Vrsta skrivanja:",
+       "log-action-filter-upload": "Tip otpremanja:",
        "log-action-filter-all": "Sve",
+       "log-action-filter-block-block": "blokiranje",
+       "log-action-filter-block-reblock": "izmena blokiranja",
+       "log-action-filter-block-unblock": "deblokiranje",
+       "log-action-filter-contentmodel-change": "Izmena modela sadržaja",
+       "log-action-filter-contentmodel-new": "Nova stranica s nestandardnim modelom sadržaja",
+       "log-action-filter-delete-delete": "brisanje stranice",
+       "log-action-filter-delete-delete_redir": "presnimavanje preusmerenja",
+       "log-action-filter-delete-restore": "vraćanje stranice",
+       "log-action-filter-delete-event": "brisanje unosa u dnevnicima",
+       "log-action-filter-delete-revision": "brisanje izmene",
+       "log-action-filter-import-interwiki": "Međuviki uvoz",
+       "log-action-filter-import-upload": "Uvoz postavljanjem XML-a",
+       "log-action-filter-managetags-create": "nova oznaka",
+       "log-action-filter-managetags-delete": "brisanje oznake",
+       "log-action-filter-managetags-activate": "aktiviranje oznake",
+       "log-action-filter-managetags-deactivate": "deaktiviranje oznake",
+       "log-action-filter-move-move": "premeštanje bez presnimavanja preusmerenja",
        "log-action-filter-move-move_redir": "premeštanje sa presnimavanjem preusmerenja",
+       "log-action-filter-newusers-create": "otvorio anoniman korisnik",
+       "log-action-filter-newusers-create2": "otvorio registrovan korisnik",
+       "log-action-filter-newusers-autocreate": "automatski otvoren",
+       "log-action-filter-patrol-patrol": "ručno",
+       "log-action-filter-patrol-autopatrol": "automatsko",
+       "log-action-filter-protect-protect": "zaključavanje",
+       "log-action-filter-protect-modify": "izmena zaključavanja",
+       "log-action-filter-protect-unprotect": "uklanjanje zaključavanja",
        "log-action-filter-protect-move_prot": "premeštanje zaštite",
+       "log-action-filter-rights-rights": "ručno",
+       "log-action-filter-rights-autopromote": "automatski",
+       "log-action-filter-suppress-event": "Skrivanje unosa u dnevniku",
+       "log-action-filter-suppress-revision": "Skrivanje izmene",
+       "log-action-filter-suppress-delete": "Skrivanje stranice",
+       "log-action-filter-suppress-block": "Skrivanje korisnika blokiranjem",
+       "log-action-filter-suppress-reblock": "Skrivanje korisnika ponovnim blokiranjem",
        "log-action-filter-upload-upload": "novo otpremanje",
+       "log-action-filter-upload-overwrite": "promena postojećeg",
+       "authmanager-authn-not-in-progress": "Autentifikacija nije u toku ili je došlo do gubitka podataka o sesiji. Počnite ispočetka.",
+       "authmanager-authn-no-primary": "Ne mogu da proverim pružene akreditive.",
+       "authmanager-authn-no-local-user": "Pruženi akreditivi nisu povezani ni sa jednim korisnikom na ovom vikiju.",
+       "authmanager-authn-no-local-user-link": "Pruženi su ispravni akreditivi, ali nisu povezani ni s jednim korisnikom na ovom vikiju. Prijavite se na neki drugi način ili napravite novi korisnički nalog, što će Vam dati mogućnost da povežete prethodne akreditive na novi nalog.",
+       "authmanager-authn-autocreate-failed": "Ne mogu da automatski napravim lokalni nalog: $1",
+       "authmanager-change-not-supported": "Ne mogu da promenim pružene akreditive jer ih ništa ne bi koristilo.",
+       "authmanager-create-disabled": "Onemogućeno pravljenje naloga.",
+       "authmanager-create-from-login": "Popunite polja da biste napravili nalog.",
+       "authmanager-create-not-in-progress": "Pravljenje naloga nije u toku ili su podaci o sesiji izgubljeni. Počnite ispočetka.",
+       "authmanager-create-no-primary": "Ne mogu da iskoristim pružene akreditive za pravljenje 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 autentifikaciju je odbio promenu lozinke.",
+       "authmanager-authplugin-create-fail": "Dodatak za autentifikaciju je odbio pravljenje naloga.",
+       "authmanager-authplugin-setpass-denied": "Dodatak za autentifikaciju ne dozvoljava menjanje loziku.",
+       "authmanager-authplugin-setpass-bad-domain": "Neispravan domen.",
+       "authmanager-autocreate-noperm": "Automatsko pravljenje naloga nije dozvoljeno.",
+       "authmanager-userdoesnotexist": "Korisnički nalog „$1“ nije otvoren.",
+       "authmanager-username-help": "Korisničko ime za autentifikaciju.",
+       "authmanager-password-help": "Lozinka za autentifikaciju.",
+       "authmanager-domain-help": "Domen za spoljašnju autentifikaciju.",
+       "authmanager-retype-help": "Ponovite lozinku da bi ste potvrdili.",
        "authmanager-email-label": "Imejl",
        "authmanager-email-help": "Imejl adresa",
-       "changecredentials": "Promjena akreditiva",
+       "authmanager-realname-label": "Pravo ime",
+       "authmanager-realname-help": "Pravo ime korisnika",
+       "authmanager-provider-password": "Autentifikacija lozinkom",
+       "authmanager-provider-password-domain": "Autentifikacija lozinkom i domenom",
+       "authmanager-provider-temporarypassword": "Privremena lozinka",
+       "authprovider-confirmlink-option": "$1 ($2)",
+       "authprovider-confirmlink-request-label": "Računi koji se trebaju povezati",
+       "authprovider-confirmlink-success-line": "$1: Uspešno povezano.",
+       "authprovider-confirmlink-failed": "Ne mogu da povežem nalog u potpunosti: $1",
+       "authprovider-confirmlink-ok-help": "Nastavite nakon prikazivanja poruka za neuspešno povezivanje.",
+       "authprovider-resetpass-skip-label": "Preskoči",
+       "authprovider-resetpass-skip-help": "Preskočite resetovanje lozinke.",
+       "authform-nosession-login": "Autentifikacija je uspela, ali Vaš pregledač ne može da „zapamti” da ste prijavljeni.\n\n$1",
+       "authform-nosession-signup": "Nalog je napravljen, ali Vaš pregledač ne može da „zapamti” da ste prijavljeni.\n\n$1",
+       "authform-newtoken": "Nedostaje žeton. $1",
+       "authform-notoken": "Nedostaje žeton",
+       "authform-wrongtoken": "Pogrešan žeton",
+       "specialpage-securitylevel-not-allowed-title": "Nije dozvoljeno",
+       "specialpage-securitylevel-not-allowed": "Žao nam je, nije Vam dozvoljeno da koristite ovu stranicu jer ne mogu da potvrdim Vaš identitet.",
+       "authpage-cannot-login": "Ne mogu započeti prijavu.",
+       "authpage-cannot-login-continue": "Ne mogu da nastavim prijavljivanje. Vaša sesija je najverovatnije istekla.",
+       "authpage-cannot-create": "Ne mogu započeti stvaranje naloga.",
+       "authpage-cannot-link": "Ne mogu započeti spajanje naloga.",
+       "cannotauth-not-allowed-title": "Pristup je odbijen",
+       "cannotauth-not-allowed": "Nije Vam dozvoljeno da koristite ovu stranicu",
+       "changecredentials": "Promena akreditiva",
+       "changecredentials-submit": "Promeni",
+       "changecredentials-invalidsubpage": "„$1“ nije ispravna vrsta akreditiva.",
+       "changecredentials-success": "Vaši akreditivi su promenjeni.",
        "removecredentials": "Uklanjanje akreditiva",
-       "gotointerwiki-external": "Upravo ćete da napustite projekat {{SITENAME}} da biste na zasebnom veb-sajtu posetili [[$2]].\n\n'''[$1 Produži na $1]'''"
+       "removecredentials-submit": "Uklanjanje akreditiva",
+       "removecredentials-invalidsubpage": "„$1“ nije ispravna vrsta akreditiva.",
+       "removecredentials-success": "Vaši akreditivi su uklonjeni.",
+       "credentialsform-provider": "Vrsta akreditiva:",
+       "credentialsform-account": "Naziv naloga:",
+       "cannotlink-no-provider-title": "Nema naloga za povezivanje",
+       "cannotlink-no-provider": "Nema naloga za povezivanje.",
+       "linkaccounts": "Poveži naloge",
+       "linkaccounts-success-text": "Nalog je povezan.",
+       "linkaccounts-submit": "Poveži naloge",
+       "unlinkaccounts": "Objedini naloge",
+       "unlinkaccounts-success": "Nalog je objedinjen.",
+       "userjsispublic": "Napomena: JavaScript podstranice ne bi trebale sadržavati poverljive informacije budući da su vidljive drugim korisnicima.",
+       "usercssispublic": "Napomena: CSS podstranice ne bi trebale sadržavati poverljive informacije budući da su vidljive drugim korisnicima.",
+       "restrictionsfield-badip": "Neispravna IP adresa ili opseg: $1",
+       "restrictionsfield-label": "Dozvoljeni IP-opsezi:",
+       "edit-error-short": "Greška: $1",
+       "edit-error-long": "Greške:\n\n$1",
+       "revid": "izmena $1",
+       "pageid": "ID stranice: $1",
+       "rawhtml-notallowed": "&lt;html&gt; tagovi ne mogu da se koriste van normalnih stranica.",
+       "gotointerwiki": "Napuštam projekat {{SITENAME}}",
+       "gotointerwiki-invalid": "Odabrani naslov je nevalidan.",
+       "gotointerwiki-external": "Upravo ćete da napustite projekat {{SITENAME}} da biste na zasebnom veb-sajtu posetili [[$2]].\n\n'''[$1 Produži na $1]'''",
+       "undelete-cantedit": "Ne možete povratiti ovu stranicu jer nemate dozvolu da je uređujete.",
+       "undelete-cantcreate": "Ne možete povratiti ovu stranicu jer nema postojeće stranice sa ovim imenom i nemate dozvolu da napravite ovu stranicu.",
+       "pagedata-title": "Podaci stranice",
+       "pagedata-not-acceptable": "Nije pronađen odgovarajući oblik. Podržane MIME-vrste: $1",
+       "pagedata-bad-title": "Nevalidan naslov: $1."
 }
index 7d99603..15a7147 100644 (file)
        "sp-contributions-submit": "Suku",
        "whatlinkshere": "San e miti kon dyaso",
        "whatlinkshere-title": "Papira di e sori go na $1",
-       "linkshere-2": "Den papira disi e miti go na '''$1''':",
-       "nolinkshere-2": "No wan papira e miti kon na '''$1'''.",
+       "linkshere": "Den papira disi e miti go na '''$1''':",
+       "nolinkshere": "No wan papira e miti kon na '''$2'''.",
        "isredirect": "papira fu drai go",
        "istemplate": "poti leki wan template",
        "whatlinkshere-prev": "{{PLURAL:$1|a wan|den $1}} di psa",
index 78536c6..83390c7 100644 (file)
        "whatlinkshere": "Links ap disse Siede",
        "whatlinkshere-title": "Sieden, do der ap \"$1\" linkje",
        "whatlinkshere-page": "Siede:",
-       "linkshere-2": "Do foulgjende Sieden ferwiese hierhäär:  '''$1''': <br /><small>(Moonige Sieden wäide eventuell moorfooldich liested, konnen in säildene Falle oawers uk miste. Dät kumt fon oolde Failere in dän Software häär, man skoadet fääre niks.)</small>",
-       "nolinkshere-2": "Naan Artikkel ferwiest hierhäär: '''$1'''.",
-       "nolinkshere-ns-2": "Neen Siede ferlinket ap '''„$1“''' in dän wäälde Noomensruum.",
+       "linkshere": "Do foulgjende Sieden ferwiese hierhäär:  '''$1''': <br /><small>(Moonige Sieden wäide eventuell moorfooldich liested, konnen in säildene Falle oawers uk miste. Dät kumt fon oolde Failere in dän Software häär, man skoadet fääre niks.)</small>",
+       "nolinkshere": "Naan Artikkel ferwiest hierhäär: '''$2'''.",
+       "nolinkshere-ns": "Neen Siede ferlinket ap '''„$2“''' in dän wäälde Noomensruum.",
        "isredirect": "Fäärelaitengs-Siede",
        "istemplate": "Foarloagenienbiendenge",
        "isimage": "Doatäilink",
        "markedaspatrollederror-noautopatrol": "Et is nit ferlööwed, oaine Beoarbaidengen as kontrollierd tou markierjen.",
        "patrol-log-page": "Kontrol-Logbouk",
        "patrol-log-header": "Dit is dät Kontroll-Logbouk.",
-       "log-show-hide-patrol": "Kontroll-Logbouk $1",
        "deletedrevision": "Oolde Version $1 läsked",
        "filedeleteerror-short": "Failer bie dät Doatäi-Läskjen: $1",
        "filedeleteerror-long": "Bie dät Doatäi-Läskjen wuuden Failere fääststoald:\n\n$1",
index f76272f..f32cb6a 100644 (file)
        "whatlinkshere": "Мынта ссылкалар",
        "whatlinkshere-title": "«$1» питкә йебәргән питләр",
        "whatlinkshere-page": "Пит:",
-       "linkshere-2": "''$1''' питкә киләсе питләр тайанатылар:",
-       "nolinkshere-2": "$1 питкә пер питтән тә ссылка йуҡ.",
+       "linkshere": "''$1''' питкә киләсе питләр тайанатылар:",
+       "nolinkshere": "$2 питкә пер питтән тә ссылка йуҡ.",
        "isredirect": "йусыҡлау пит",
        "istemplate": "ҡушылыу",
        "isimage": "файллы ссылка",
index 0e93458..bcf7bc5 100644 (file)
        "subject-preview": "Pramidang subyék:",
        "previewerrortext": "Aya éror nalika nyobaan nyawang robahan anjeun.",
        "blockedtitle": "Pamaké dipeungpeuk",
-       "blockedtext": "'''Ngaran pamaké atawa alamat IP anjeun dipeungpeuk.'''\n\nDipeungpeuk ku $1.\nAlesanana ''$2''.\n\n* Mimiti dipeungpeuk : $8\n* dipeungpeuk kadaluarsa dina: $6\n* Sasaran nudipeungpeuk : $7\n\nAnjeun bisa nepungan $1 atawa salasahiji [[{{MediaWiki:Grouppage-sysop}}|kuncén]] séjén pikeun nyawalakeun hal ieu.\n'''Catet''': yén anjeun teu bisa maké fungsi \"surélékan pamaké ieu\" mun anjeun teu ngadaptarkeun alamat surélék nu sah kana [[Special:Preferences|préferénsi pamaké]] anjeun.\n\nAlamat IP anjeun $3 jeung ID na #$5.\nLampirkeun informasi ieu dina unggal ''query'' anjeun.",
+       "blockedtext": "<strong>Ngaran pamaké atawa alamat IP anjeun dipeungpeuk.</strong>\n\nDipeungpeuk ku $1.\nAlesanana <em>$2</em>.\n\n* Mimiti dipeungpeuk: $8\n* Anggeusan dipeungpeuk: $6\n* Sasaran anu dipeungpeuk: $7\n\nAnjeun bisa ngontak $1 atawa [[{{MediaWiki:Grouppage-sysop}}|kuncén]] lianna pikeun nyawalakeun ieu hal.\nAnjeun teu bisa maké fitur \"{{int:emailuser}}\" mun anjeun teu ngadaptarkeun alamat surélék nu sah dina [[Special:Preferences|préferénsi akun]] anjeun sarta henteu dipeungpeuk tina migunakeun éta fitur.\nAlamat IP anjeun $3, kalayan ID peungpeukna #$5.\nLampirkeun informasi ieu dina unggal kueri anjeun.",
        "autoblockedtext": "Alamat IP anjeun otomatis dipeungpeuk sabab dipaké ku pamaké séjén nu geus dipeungpeuk ku $1, kalawan alesan:\n\n:''$2''\n\n*Mimiti dipeungpeuk: $8\n*Kadaluwarsa peungpeuk: $6\n*Sasaran peungpeuk: $7\n\nAnjeun bisa nepungan $1 atawa [[{{MediaWiki:Grouppage-sysop}}|kuncé]] lianna pikeun ngabadamikeun ieu peungpeukan.\n\nCatet yén anjeun moal bisa migunakeun fitur \"surélékan ieu pamaké\" mun alamat surélék anu didaptarkeun dina [[Special:Preferences|préferénsi pamaké]]na teu sah, sarta teu dipeungpeuk tina migunakeun ieu fitur.\n\nAlamat IP Anjeun ayeuna nyaéta $3, sarta ID peungpeukan anjeun #$5.\nMangga sebatkeun éta ID dina pamundut-pamundut anjeun.",
        "blockednoreason": "taya alesan",
        "whitelistedittext": "Anjeun kudu asup $1 sangkan bisa ngédit.",
        "recentchangeslinked-feed": "Parobahan nu patali",
        "recentchangeslinked-toolbox": "Parobahan nu patali",
        "recentchangeslinked-title": "Parobahan patali ka \"$1\"",
-       "recentchangeslinked-summary": "Ieu kaca husus ngabéréndélkeun parobahan anyar anu numbu ti kaca husus (atawa uesi katagori husus). Kaca anu [[Special:Watchlist|diawaskeun]] némbongan '''kandel'''.",
+       "recentchangeslinked-summary": "Asupkeun ngaran kaca pikeun nempo parobahan anu nutumbu ka atawa ti éta kaca. (Pikeun nempo anggota kategori, asupkeun {{ns:category}}:Ngaran kategori). Parobahan kaca-kaca anu [[Special:Watchlist|diawaskeun]] némbongan <strong>kandel</strong>.",
        "recentchangeslinked-page": "Ngaran kaca:",
        "recentchangeslinked-to": "Témbongkeun parobahan ka kaca-kaca nu ditumbukeun ka kaca nu dimaksud",
        "recentchanges-page-added-to-category": "[[:$1]] ditambahkeun kana kategori",
        "filehist-comment": "Kamandang",
        "imagelinks": "Pamakéan berkas",
        "linkstoimage": "Kaca ieu  {{PLURAL:$1|numbu|$1 numbu}} ka gambar ieu :",
-       "linkstoimage-more": "Leuwih ti $1 {{PLURAL:$1|kaca nutumbu|kaca nutumbu}} ka ieu berkas.\nBéréndélan di handap némbongkeun {{PLURAL:$1|tutumbu kaca kahiji|$1 tutumbu kaca}} ka ieu berkas hungkul.\n[[Special:WhatLinksHere/$2|Béréndélan lengkepna]] aya.",
+       "linkstoimage-more": "Leuwih ti $1 {{PLURAL:$1|kaca nutumbu|kaca nutumbu}} ka ieu berkas.\nBéréndélan di handap némbongkeun {{PLURAL:$1|tutumbu kaca kahiji|$1 tutumbu kaca kahiji}} ka ieu berkas hungkul.\n[[Special:WhatLinksHere/$2|Béréndélan lengkepna]] ogé aya.",
        "nolinkstoimage": "Teu aya kaca anu nutumbu ka ieu berkas.",
        "morelinkstoimage": "Témbong [[Special:WhatLinksHere/$1|tutumbu lianna]] ka ieu berkas.",
        "linkstoimage-redirect": "$1 (pangalihan berkas) $2",
        "unwatchthispage": "Eureun ngawaskeun",
        "notanarticle": "Sanés kaca eusi",
        "notvisiblerev": "Révisi geus dihapus",
-       "watchlist-details": "Aya {{PLURAL:$1|$1 kaca|$1 kaca}} dina daptar awaseun (pleus kaca obrolanna).",
+       "watchlist-details": "Aya {{PLURAL:$1|$1 kaca|$1 kaca}} dina Awaseun anjeun (kaasup kaca obrolan).",
        "wlheader-enotif": "Iber surélék diaktifkeun.",
-       "wlheader-showupdated": "Kaca nu robah ti panungtungan anjeun sindang ditémbongkeun kalawan '''kandel'''",
-       "wlnote": "Di handap ieu mangrupa $1 {{PLURAL:$1|robahan|robahan}} ahir salila '''$2''' jam.",
+       "wlheader-showupdated": "Kaca nu robah ti panungtungan anjeun sindang ditémbongkeun <strong>kandel</strong>.",
+       "wlnote": "Di handap ieu mangrupa {{PLURAL:$1|robahan|robahan}} <strong>$1</strong> panungtung salila {{PLURAL:$2|jam|<strong>$2</strong> jam}}, ti $3, $4.",
        "wlshowlast": "Témbongkeun $1 jam $2 poé panungtung",
        "watchlist-hide": "Sumputkeun",
        "watchlist-submit": "Témbongkeun",
        "whatlinkshere": "Anu nutumbu ka dieu",
        "whatlinkshere-title": "Kaca anu nutumbu ka \"$1\"",
        "whatlinkshere-page": "Kaca:",
-       "linkshere-2": "Kaca di handap ieu numbu ka '''$1''':",
-       "nolinkshere-2": "Euweuh kaca anu nutumbu ka <strong>$1</strong>.",
-       "nolinkshere-ns-2": "Euweuh kaca anu nutumbu ka <strong>$1</strong> dina ruang-nama anu dipilih.",
+       "linkshere": "Kaca di handap ieu numbu ka '''$1''':",
+       "nolinkshere": "Euweuh kaca anu nutumbu ka <strong>$2</strong>.",
+       "nolinkshere-ns": "Euweuh kaca anu nutumbu ka <strong>$2</strong> dina ruang-nama anu dipilih.",
        "isredirect": "Kaca alihan",
        "istemplate": "ku citakan",
        "isimage": "tutumbu berkas",
        "pageinfo-few-visiting-watchers": "Rék aya atawa henteuna pamariksa kaca nu nyorang éditan kiwari",
        "pageinfo-redirects-name": "Jumlah pindahan ka ieu kaca",
        "pageinfo-subpages-name": "Nomor subkaca ieu kaca",
+       "pageinfo-subpages-value": "$1 ($2 {{PLURAL:$2|pindahan|pindahan}}; $3 {{PLURAL:$3|non-pindahan|non-pindahan}})",
        "pageinfo-firstuser": "Panyieun kaca",
        "pageinfo-firsttime": "Tanggal panyieunan kaca",
        "pageinfo-lastuser": "Pangédit panungtung",
        "markedaspatrollederrornotify": "Nandaan minangka kaawas gagal.",
        "patrol-log-page": "Log patroli",
        "patrol-log-header": "Ieu minangka log pikeun révisi nu geus diroris.",
-       "log-show-hide-patrol": "$1 log rorisan",
-       "log-show-hide-tag": "log tag $1",
        "confirm-markpatrolled-button": "Heug",
        "confirm-markpatrolled-top": "Tandaan révisi $3 ti $2 minangka kaawas?",
        "deletedrevision": "Révisi heubeul nu dihapus $1",
index 3765b04..27fc910 100644 (file)
        "customcssprotected": "Du har inte behörighet att redigera denna CSS-sida eftersom den innehåller en annan användares personliga inställningar.",
        "customjsonprotected": "Du har inte behörighet att redigera denna JSON-sida eftersom den innehåller en annan användares personliga inställningar.",
        "customjsprotected": "Du har inte behörighet att redigera denna JavaScript-sida eftersom den innehåller en annan användares personliga inställningar.",
+       "sitecssprotected": "Du har inte behörighet att redigera denna CSS-sida eftersom den kan påverka alla besökare",
+       "sitejsonprotected": "Du har inte behörighet att redigera denna JSON-sida eftersom den kan påverka alla besökare",
+       "sitejsprotected": "Du har inte behörighet att redigera denna JavaScript-sida eftersom den kan påverka alla besökare",
        "mycustomcssprotected": "Du har inte behörighet att redigera denna CSS-sida.",
        "mycustomjsonprotected": "Du har inte behörighet att redigera denna JSON-sida.",
        "mycustomjsprotected": "Du har inte behörighet att redigera denna JavaScript-sida.",
        "resetpass-submit-loggedin": "Ändra lösenord",
        "resetpass-submit-cancel": "Avbryt",
        "resetpass-wrong-oldpass": "Ogiltigt tillfälligt eller nuvarande lösenord.\nDu kanske redan har lyckats ändra ditt lösenord eller begärt ett nytt tillfälligt lösenord.",
-       "resetpass-recycled": "Var god Ã¥terställ ditt lösenord till någonting annat än ditt aktuella lösenord.",
+       "resetpass-recycled": "Var god Ã¤ndra ditt lösenord till någonting annat än ditt aktuella lösenord.",
        "resetpass-temp-emailed": "Du loggade in med en temporär kod som skickats via e-post.\nFör att slutföra inloggningen måste du ange ett nytt lösenord här:",
        "resetpass-temp-password": "Tillfälligt lösenord:",
        "resetpass-abort-generic": "Lösenordsändring av har avbrutits av ett tillägg.",
        "resetpass-expired": "Ditt lösenord har gått ut. Var god ange ett nytt lösenord för att logga in.",
-       "resetpass-expired-soft": "Ditt lösenord har gÃ¥tt ut och behöver Ã¥terställas. Var god välj ett nytt lösenord nu eller klicka pÃ¥ \"{{int:authprovider-resetpass-skip-label}}\" för att Ã¥terställa det senare.",
-       "resetpass-validity-soft": "Ditt lösenord Ã¤r ogiltigt: $1\n\nVar god välj ett nytt lösenord nu eller klicka pÃ¥ \"{{int:authprovider-resetpass-skip-label}}\" för att Ã¥terställa det senare.",
+       "resetpass-expired-soft": "Ditt lösenord har gÃ¥tt ut och behöver Ã¤ndras. Var god välj ett nytt lösenord nu eller klicka pÃ¥ \"{{int:authprovider-resetpass-skip-label}}\" för att Ã¤ndra det senare.",
+       "resetpass-validity-soft": "Ditt lösenord Ã¤r ogiltigt: $1\n\nVar god välj ett nytt lösenord nu eller klicka pÃ¥ \"{{int:authprovider-resetpass-skip-label}}\" för att Ã¤ndra det senare.",
        "passwordreset": "Återställ lösenord",
        "passwordreset-text-one": "Fyll i detta formulär för att återställa ditt lösenord.",
        "passwordreset-text-many": "{{PLURAL:$1|Fyll i ett av fälten för att få ett tillfälligt lösenord via e-post.}}",
        "converter-manual-rule-error": "Fel upptäcktes i manuell språkkonverteringsregel",
        "undo-success": "Redigeringen kan göras ogjord.\nVar god och kontrollera jämförelsen nedan för att bekräfta att detta är vad du avser att göra, och spara sedan ändringarna nedan för att göra redigeringen ogjord.",
        "undo-failure": "Redigeringen kunde inte göras ogjord på grund av konflikt med mellanliggande redigeringar.",
+       "undo-main-slot-only": "Redigeringen kunde inte göras ogjord eftersom den omfattar innehåll utanför huvudplatsen.",
        "undo-norev": "Redigeringen kan inte göras ogjord eftersom den inte finns eller har raderats.",
        "undo-nochange": "Det verkar som att redigeringen redan har blivit ogjord.",
        "undo-summary": "Gör version $1 av [[Special:Contributions/$2|$2]] ([[User talk:$2|diskussion]]) ogjord",
        "diff-paragraph-moved-toold": "Avsnittet flyttades. Klicka för att hoppa till den gamla platsen.",
        "difference-missing-revision": "Det gick inte att hitta {{PLURAL:$2|en version|$2 versioner}} av den här differensen ($1).\n\nDetta beror oftast på att du har försökt följa en utgången difflänk till en sida som har raderats.\nMer detaljerad information finns i [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} raderingsloggen].",
        "searchresults": "Sökresultat",
+       "search-filter-title-prefix": "Sök endast på sidor vars titel börjar med \"$1\"",
+       "search-filter-title-prefix-reset": "Sök på alla sidor",
        "searchresults-title": "Sökresultat för \"$1\"",
        "titlematches": "Träffar i sidtitlar",
        "textmatches": "Artikeltexter som matchar sökningen",
        "group-autoconfirmed": "Automatiskt bekräftade användare",
        "group-bot": "Robotar",
        "group-sysop": "Administratörer",
+       "group-interface-admin": "Gränssnittsadministratörer",
        "group-bureaucrat": "Byråkrater",
        "group-suppress": "Censorer",
        "group-all": "(alla)",
        "group-autoconfirmed-member": "{{GENDER:$1|bekräftad användare}}",
        "group-bot-member": "{{GENDER:$1|robot}}",
        "group-sysop-member": "{{GENDER:$1|administratör}}",
+       "group-interface-admin-member": "{{GENDER:$1|gränssnittsadministratörer}}",
        "group-bureaucrat-member": "{{GENDER:$1|byråkrat}}",
        "group-suppress-member": "{{GENDER:$1|censor}}",
        "grouppage-user": "{{ns:project}}:Användare",
        "grouppage-autoconfirmed": "{{ns:project}}:Bekräftade användare",
        "grouppage-bot": "{{ns:project}}:Robotar",
        "grouppage-sysop": "{{ns:project}}:Administratörer",
+       "grouppage-interface-admin": "{{ns:project}}:Gränssnittsadministratörer",
        "grouppage-bureaucrat": "{{ns:project}}:Byråkrater",
        "grouppage-suppress": "{{ns:project}}:Censur",
        "right-read": "Se sidor",
        "right-editusercss": "Redigera andra användares CSS-filer",
        "right-edituserjson": "Redigera andra användares JSON-filer",
        "right-edituserjs": "Redigera andra användares JavaScript-filer",
+       "right-editsitecss": "Redigera CSS för hela webbplatsen",
+       "right-editsitejson": "Redigera JSON för hela webbplatsen",
+       "right-editsitejs": "Redigera JavaScript för hela webbplatsen",
        "right-editmyusercss": "Redigera din egen användares CSS-filer",
        "right-editmyuserjson": "Redigera dina egna JSON-filer",
        "right-editmyuserjs": "Redigera din egen användares JavaScript-filer",
        "grant-createaccount": "Skapa konton",
        "grant-createeditmovepage": "Skapa, redigera och flytta sidor",
        "grant-delete": "Radera sidor, revideringar och loggposter",
-       "grant-editinterface": "Redigera CSS/JSON/Javascript för MediaWiki-namnrymden och -användare",
+       "grant-editinterface": "Redigera JSON för MediaWiki-namnrymden och hela webbplatsen/användare",
        "grant-editmycssjs": "Redigera din egen CSS/JSON/JavaScript",
        "grant-editmyoptions": "Redigera dina användarinställningar",
        "grant-editmywatchlist": "Redigera din bevakningslista",
+       "grant-editsiteconfig": "Redigera CSS/JS för hela webbplatsen och användare",
        "grant-editpage": "Redigera befintliga sidor",
        "grant-editprotected": "Redigera skyddade sidor",
        "grant-highvolume": "Hög volymsredigering",
        "rcfilters-other-review-tools": "Andra granskningsverktyg",
        "rcfilters-group-results-by-page": "Gruppera resultat efter sida",
        "rcfilters-activefilters": "Aktiva filter",
+       "rcfilters-activefilters-hide": "Dölj",
+       "rcfilters-activefilters-show": "Visa",
+       "rcfilters-activefilters-hide-tooltip": "Dölj området för aktiva filter",
+       "rcfilters-activefilters-show-tooltip": "Visa området för aktiva filter",
        "rcfilters-advancedfilters": "Avancerade filter",
        "rcfilters-limit-title": "Resultat att visa",
        "rcfilters-limit-and-date-label": "$1 {{PLURAL:$1|ändring|ändringar}}, $2",
        "rcfilters-days-show-hours": "$1 {{PLURAL:$1|timme|timmar}}",
        "rcfilters-highlighted-filters-list": "Markerade: $1",
        "rcfilters-quickfilters": "Sparade filter",
-       "rcfilters-quickfilters-placeholder-title": "Inga filter har sparats ännu",
+       "rcfilters-quickfilters-placeholder-title": "Inga filter har ännu sparats",
        "rcfilters-quickfilters-placeholder-description": "För att spara dina filterinställningar och återanvända dem senare, klicka på bokmärkesikonen under \"Aktiva filter\" nedan.",
        "rcfilters-savedqueries-defaultlabel": "Sparade filter",
        "rcfilters-savedqueries-rename": "Döp om",
        "rcfilters-savedqueries-setdefault": "Ange som standard",
        "rcfilters-savedqueries-unsetdefault": "Ta bort som standard",
-       "rcfilters-savedqueries-remove": "Ta bort",
+       "rcfilters-savedqueries-remove": "Radera",
        "rcfilters-savedqueries-new-name-label": "Namn",
        "rcfilters-savedqueries-new-name-placeholder": "Beskriv syftet med filtret",
        "rcfilters-savedqueries-apply-label": "Skapa filter",
        "rcfilters-empty-filter": "Inga aktiva filter. Alla bidrag visas.",
        "rcfilters-filterlist-title": "Filter",
        "rcfilters-filterlist-whatsthis": "Hur fungerar dessa?",
-       "rcfilters-filterlist-feedbacklink": "Berätta vad du tycker om dessa (nya) filtreringsverktyg",
+       "rcfilters-filterlist-feedbacklink": "Berätta vad du tycker om dessa filtreringsverktyg",
        "rcfilters-highlightbutton-title": "Markera resultat",
        "rcfilters-highlightmenu-title": "Välj en färg",
        "rcfilters-highlightmenu-help": "Välj en färg att markera denna egenskap",
        "rcfilters-watchlist-showupdated": "Sidor som har ändrats sedan ditt senaste besök visas i <strong>fetstil</strong> med färgmarkering.",
        "rcfilters-preference-label": "Dölj den förbättrade versionen av Senaste ändringar",
        "rcfilters-preference-help": "Stänger det nydesignade gränssnittet från 2017 och alla verktyg som lades till från och med då.",
+       "rcfilters-watchlist-preference-label": "Dölj det förbättrade versionen av bevakningslistan",
+       "rcfilters-watchlist-preference-help": "Rullar tillbaka det omdesignade gränssnittet från 2017 och alla verktyg som lades till då och efteråt.",
        "rcfilters-filter-showlinkedfrom-label": "Visa ändringar på sidor som länkas från",
        "rcfilters-filter-showlinkedfrom-option-label": "<strong>Sidor som länkas från</strong> den valda sidan",
        "rcfilters-filter-showlinkedto-label": "Visa ändringar på sidor som länkar till",
        "uploadstash-zero-length": "Filens längd är noll.",
        "invalid-chunk-offset": "Ogiltig segmentsförskjutning",
        "img-auth-accessdenied": "Åtkomst nekad",
-       "img-auth-nopathinfo": "PATH_INFO saknas.\nDin server är inte inställd för att ge denna information.\nDen kan vara CGI-baserad och stöder inte img_auth.\n[https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization Se bildbehörighet.]",
+       "img-auth-nopathinfo": "Sökvägsinformation saknas.\nDin server måste vara inställd för att ge variablerna REQUEST_URI och/eller PATH_INFO.\nOm den är det, försök att aktivera $wgUsePathInfo.\n[https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization Se bildbehörighet.]",
        "img-auth-notindir": "Den önskade sökvägen finns inte i den inställda uppladdningskatalogen.",
        "img-auth-badtitle": "Kan inte skapa en giltig titel från \"$1\"",
        "img-auth-nologinnWL": "Du är inte inloggad och \"$1\" finns inte i vitlistan.",
        "http-timed-out": "HTTP-begäran avbröts.",
        "http-curl-error": "Fel vid hämtning av URL: $1",
        "http-bad-status": "Det uppstod ett problem under HTTP-begäran: $1 $2",
+       "http-internal-error": "Internt HTTP-fel.",
        "upload-curl-error6": "URL:en kunde inte nås",
        "upload-curl-error6-text": "Den angivna URL:en kunde inte nås. Kontrollera att den är korrekt och att webbplatsern fungerar.",
        "upload-curl-error28": "Timeout för uppladdningen",
        "speciallogtitlelabel": "Mål (titel eller {{ns:user}}:användarnamn för användare):",
        "log": "Loggar",
        "logeventslist-submit": "Visa",
-       "all-logs-page": "Alla publika loggar",
+       "logeventslist-more-filters": "Visa ytterligare loggar:",
+       "logeventslist-patrol-log": "Patrulleringslogg",
+       "logeventslist-tag-log": "Märkeslogg",
+       "all-logs-page": "Alla offentliga loggar",
        "alllogstext": "Kombinerad visning av alla tillgängliga loggar för {{SITENAME}}.\nDu kan avgränsa sökningen och få färre träffar genom att ange typ av logg, användarnamn (skiftlägeskänsligt), eller berörd sida (också skiftlägeskänsligt).",
        "logempty": "Inga matchande träffar i loggen.",
        "log-title-wildcard": "Sök efter sidtitlar som börjar med texten",
        "dellogpage": "Raderingslogg",
        "dellogpagetext": "Nedan listas de senaste raderingarna.",
        "deletionlog": "raderingslogg",
+       "log-name-create": "Sidskapandelogg",
+       "log-description-create": "Nedan listas de senaste skapade sidorna.",
+       "logentry-create-create": "$1 {{GENDER:$2|skapade}} sidan $3",
        "reverted": "Återgått till tidigare version",
        "deletecomment": "Anledning:",
        "deleteotherreason": "Annan/ytterligare anledning:",
        "uctop": "(senaste)",
        "month": "Från månad (och tidigare):",
        "year": "Från år (och tidigare):",
+       "date": "Från datum (och tidigare):",
        "sp-contributions-newbies": "Visa endast bidrag från nya konton",
        "sp-contributions-newbies-sub": "Från nya konton",
        "sp-contributions-newbies-title": "Bidrag från nya konton",
        "whatlinkshere": "Vad som länkar hit",
        "whatlinkshere-title": "Sidor som länkar till \"$1\"",
        "whatlinkshere-page": "Sida:",
-       "linkshere-2": "Följande sidor länkar till <strong>$1</strong>:",
-       "nolinkshere-2": "Inga sidor länkar till <strong>$1</strong>.",
-       "nolinkshere-ns-2": "Inga sidor i den angivna namnrymden länkar till <strong>$1</strong>.",
+       "linkshere": "Följande sidor länkar till <strong>$1</strong>:",
+       "nolinkshere": "Inga sidor länkar till <strong>$2</strong>.",
+       "nolinkshere-ns": "Inga sidor i den angivna namnrymden länkar till <strong>$2</strong>.",
        "isredirect": "omdirigeringssida",
        "istemplate": "inkluderad som mall",
        "isimage": "fillänk",
        "markedaspatrollederrornotify": "Markering som patrullerad misslyckades.",
        "patrol-log-page": "Patrulleringslogg",
        "patrol-log-header": "Detta är en logg över patrullerade sidversioner.",
-       "log-show-hide-patrol": "$1 patrulleringslogg",
-       "log-show-hide-tag": "$1 märkeslogg",
        "confirm-markpatrolled-button": "OK",
        "confirm-markpatrolled-top": "Markera sidversionen $3 av $2 som patrullerad?",
        "deletedrevision": "Raderade gammal sidversion $1",
        "exif-copyrighted-false": "Upphovsrättsstatus inte angivet",
        "exif-photometricinterpretation-0": "Svartvitt (vit är 0)",
        "exif-photometricinterpretation-1": "Svart och vit (svart är 0)",
+       "exif-photometricinterpretation-3": "Palett",
+       "exif-photometricinterpretation-4": "Genomskinlighetsmask",
+       "exif-photometricinterpretation-5": "Separerad (förmodligen CMYK)",
        "exif-unknowndate": "Okänt datum",
        "exif-orientation-1": "Normal",
        "exif-orientation-2": "Spegelvänd horisontellt",
        "tag-mw-undo": "Ångra",
        "tag-mw-undo-description": "Redigeringar som ångrar föregående redigeringar med ångralänken",
        "tags-title": "Märken",
-       "tags-intro": "Denna sida listar de taggar som mjukvaran kan markera en redigering med, och deras betydelse.",
+       "tags-intro": "Denna sida listar de märken som programvaran kan markera en redigering med, samt deras betydelse.",
        "tags-tag": "Märkesnamn",
        "tags-display-header": "Utseende på listor över ändringar",
        "tags-description-header": "Full beskrivning av betydelse",
        "passwordpolicies-policy-passwordcannotmatchusername": "Lösenordet kan inte vara likadant som användarnamnet",
        "passwordpolicies-policy-passwordcannotmatchblacklist": "Lösenordet kan inte matcha specifikt svartlistade lösenord",
        "passwordpolicies-policy-maximalpasswordlength": "Lösenordet måste vara högst $1 {{PLURAL:$1|tecken}} långt",
-       "passwordpolicies-policy-passwordcannotbepopular": "Lösenordet kan inte vara {{PLURAL:$1|det populäraste lösenordet|i listan över de $1 populäraste lösenorden}}"
+       "passwordpolicies-policy-passwordcannotbepopular": "Lösenordet kan inte vara {{PLURAL:$1|det populäraste lösenordet|i listan över de $1 populäraste lösenorden}}",
+       "easydeflate-invaliddeflate": "Innehåll som tillhandahålls är inte helt komprimerat"
 }
index ae02942..083df6b 100644 (file)
@@ -19,7 +19,8 @@
                        "Kwisha",
                        "Macofe",
                        "Muddyb",
-                       "Fitoschido"
+                       "Fitoschido",
+                       "Rance"
                ]
        },
        "tog-underline": "Wekea mstari viungo:",
        "editundo": "tengua",
        "diff-empty": "(Hakuna tofauti)",
        "searchresults": "Matokeo ya utafutaji",
+       "search-filter-title-prefix": "Kutafuta katika kurasa zenye kichwa kianzacho na \"$1\" pekee",
+       "search-filter-title-prefix-reset": "Tafuta kurasa zote",
        "searchresults-title": "Matokeo ya utafutaji kwa ajili ya \"$1\"",
        "titlematches": "Kurasa zinazo majina yenye maneno ya ulizo",
        "textmatches": "Kurasa zinazo maandishi yenye maneno ya ulizo",
        "specialloguserlabel": "Mtendaji:",
        "speciallogtitlelabel": "Kusudio (jina la ukurasa au mtumiaji):",
        "log": "Kumbukumbu",
+       "logeventslist-more-filters": "Onyesha taarifa za ziada",
        "all-logs-page": "Kumbukumbu zote zilizo wazi",
        "alllogstext": "Hapa panaonyeshwa kumbukumbu zote za {{SITENAME}} kwa pamoja.\nUnaweza kuona baadhi yao tu kwa kuchagua aina fulani ya kumbukumbu, jina la mtumiaji fulani (zingatia herufi kubwa na ndogo), au jina la ukurasa fulani (zingatia herufi kubwa na ndogo).",
        "logempty": "Vitu vyenye vipengele hivi havipo kwenye kumbukumbu.",
        "whatlinkshere": "Viungo viungavyo ukurasa huu",
        "whatlinkshere-title": "Kurasa zilizounganishwa na \"$1\"",
        "whatlinkshere-page": "Ukurasa:",
-       "linkshere-2": "Kurasa zifuatazo zimeunganishwa na '''$1''':",
-       "nolinkshere-2": "Hakuna kurasa zilizounganishwa na '''$1'''.",
-       "nolinkshere-ns-2": "!!FUZZY!!!!FUZZY!!Hakuna kurasa zilizounganishwa na '''$1''' katika eneo la wiki lililochaguliwa.",
+       "linkshere": "Kurasa zifuatazo zimeunganishwa na '''$1''':",
+       "nolinkshere": "Hakuna kurasa zilizounganishwa na '''$2'''.",
+       "nolinkshere-ns": "Hakuna kurasa zilizounganishwa na '''$2''' katika eneo la wiki lililochaguliwa.",
        "isredirect": "elekeza ukurasa",
        "istemplate": "jumuisho",
        "isimage": "kiungo cha faili",
index a393e81..2b44968 100644 (file)
@@ -20,7 +20,9 @@
                        "Macofe",
                        "Uostofchuodnego",
                        "Przem(1)s",
-                       "Fitoschido"
+                       "Fitoschido",
+                       "Matěj Suchánek",
+                       "Vlad5250"
                ]
        },
        "tog-underline": "Podsztrychniyniy linkōw:",
        "right-editprotected": "Sprowjej zawarte zajty (ze zawarćym kaskadowym)",
        "right-editinterface": "Sprowjej interfejs użytkowńika",
        "right-editusercss": "Sprowjej pliki CSS inkszych użytkowńikůw",
+       "right-edituserjson": "Sprowjej pliki JSON inkšych užytkowńikůw",
        "right-edituserjs": "Sprowjej pliki JS inkšych užytkowńikůw",
        "right-rollback": "Rewert drap sprawjyńo uostatńygo użytkowńika kery sprowjoł dano zajta",
        "right-markbotedits": "Uoznocz rewertowane sprawjyńo kej sprawjyńo botůw",
        "listusers": "Lista užytkowńikůw",
        "listusers-editsonly": "Pokoż yno użytkowńikůw kere majům sprowjyńa",
        "usereditcount": "$1 {{PLURAL:$1|sprowjyńe|sprowjyńa|sprowjyń}}",
-       "usercreated": "{{GENDER:$3:Utworzono}} $1 uo $2",
+       "usercreated": "{{GENDER:$3|Utworzono}} $1 uo $2",
        "newpages": "Nowe zajty",
        "newpages-username": "Mjano użytkowńika:",
        "ancientpages": "Nojstarše artikle",
        "whatlinkshere": "Co sam linkuje",
        "whatlinkshere-title": "Zajty, kere linkujům na \"$1\"",
        "whatlinkshere-page": "Zajta:",
-       "linkshere-2": "Nastympůjůnce zajty sóm adrésůwane do '''$1''':",
-       "nolinkshere-2": "Żodno zajta ńy je adrésowana do '''$1'''.",
-       "nolinkshere-ns-2": "Žodno zajta ńy je adresowano do '''$1''' we wybrany přestřyni mjan.",
+       "linkshere": "Nastympůjůnce zajty sóm adrésůwane do '''$1''':",
+       "nolinkshere": "Żodno zajta ńy je adrésowana do '''$2'''.",
+       "nolinkshere-ns": "Žodno zajta ńy je adresowano do '''$2''' we wybrany přestřyni mjan.",
        "isredirect": "překerowujůnca zajta",
        "istemplate": "dołůnczony muster",
        "isimage": "Link do plika",
        "markedaspatrollederror-noautopatrol": "Ńy moš uprawńyń wymaganych do uoznačańo swojich sprawjyń kej „sprawdzůne”.",
        "patrol-log-page": "Dźynńik patrolowańo",
        "patrol-log-header": "Půniżej je dźeńńik patrolowańo zajtůw.",
-       "log-show-hide-patrol": "$1 rejer sprawdzańo",
        "deletedrevision": "Wyćepano popředńy wersyje $1",
        "filedeleteerror-short": "Feler při wyćepywańu plika $1",
        "filedeleteerror-long": "Wystůmpiuy felery při wyćepywańu pliku:\n\n$1",
index b2ffaad..f92970e 100644 (file)
@@ -52,7 +52,8 @@
                        "Info-farmer",
                        "Rakeshonwiki",
                        "Kaartic",
-                       "Fitoschido"
+                       "Fitoschido",
+                       "Matěj Suchánek"
                ]
        },
        "tog-underline": "அடிக்கோடிட்டத்தை இணை:",
        "nmembers": "$1 {{PLURAL:$1|உறுப்பினர்|உறுப்பினர்கள்}}",
        "nmemberschanged": "$1 → $2 {{PLURAL:$2|உறுப்பினர்|உறுப்பினர்கள்}}",
        "nrevisions": "{{PLURAL:$1|ஒரு திருத்தம்|$1 திருத்தங்கள்}}",
-       "nimagelinks": "$1 {{PLURAL:$!|பக்கத்தில்|பக்கங்களில்}} பயன்படுத்தப்பட்டது",
+       "nimagelinks": "$1 {{PLURAL:$1|பக்கத்தில்|பக்கங்களில்}} பயன்படுத்தப்பட்டது",
        "ntransclusions": "$1 {{PLURAL:$1|பக்கத்தில்|பக்கங்களில்}} பயன்படுத்தப்பட்டது",
        "specialpage-empty": "இந்தப் புகாருக்குகந்த முடிவுகள் எதுவுமில்லை.",
        "lonelypages": "உறவிலிப் பக்கங்கள்",
        "whatlinkshere": "இப்பக்கத்தை இணைத்தவை",
        "whatlinkshere-title": "\"$1\" பக்கத்துக்கு இணைக்கப்பட்டவை",
        "whatlinkshere-page": "பக்கம்:",
-       "linkshere-2": "'''$1''' பின்வரும் பக்கங்களில் இப்பக்கம் இணைக்கப்பட்டுள்ளது:",
-       "nolinkshere-2": "'''$1''' எந்தப் பக்கத்திலும் இந்தப் பக்கம் இணைக்கப்படவில்லை.",
-       "nolinkshere-ns-2": "தெரிவு செய்யப்பட்ட பெயர்வெளியில் '''$1''' பக்கத்துக்கு இணைக்கப்பட்ட பக்கங்கள் எதுவுமில்லை.",
+       "linkshere": "'''$1''' பின்வரும் பக்கங்களில் இப்பக்கம் இணைக்கப்பட்டுள்ளது:",
+       "nolinkshere": "'''$2''' எந்தப் பக்கத்திலும் இந்தப் பக்கம் இணைக்கப்படவில்லை.",
+       "nolinkshere-ns": "தெரிவு செய்யப்பட்ட பெயர்வெளியில் '''$2''' பக்கத்துக்கு இணைக்கப்பட்ட பக்கங்கள் எதுவுமில்லை.",
        "isredirect": "வழிமாற்றுப் பக்கம்",
        "istemplate": "உள்ளிடப்பட்டுள்ளது",
        "isimage": "கோப்பு இணைப்பு",
        "markedaspatrollederrornotify": "சுற்றுக்காவல் தோல்வியடைந்ததாக குறிக்கப்பட்டது.",
        "patrol-log-page": "சுற்றுக்காவல் பதிகை",
        "patrol-log-header": "இது ரோந்து செய்யப்பட்ட  பரிசீலனைகளுக்கான  குறிப்பேடு.",
-       "log-show-hide-patrol": "$1 ரோந்து குறிப்பேடு",
-       "log-show-hide-tag": "$1 அடையாள பதிவு",
        "confirm-markpatrolled-button": "சரி",
        "deletedrevision": "பழைய திருத்தம் $1 நீக்கப்பட்டது",
        "filedeleteerror-short": "பின்வரும் கோப்பை நீக்குவதில் தவறு: $1",
index 1abd0a4..6bfb7e7 100644 (file)
        "whatlinkshere": "Aniy p’ubuy tay lpgan sqaniy",
        "whatlinkshere-title": "Aniy ’mubuy sa zngayan tay \"$1\"",
        "whatlinkshere-page": "Zngayan",
-       "linkshere-2": "Zngayan tay suruw qaniy ga aniy p’ubuy sa <strong>$1</strong>:",
-       "nolinkshere-2": "Ungat zngazyan ’mubuy squw <strong>$1</strong>.",
+       "linkshere": "Zngayan tay suruw qaniy ga aniy p’ubuy sa <strong>$1</strong>:",
+       "nolinkshere": "Ungat zngazyan ’mubuy squw <strong>$2</strong>.",
        "isredirect": "t’ringun pawsa’ sa zngayan",
        "istemplate": "’nagal sa",
        "isimage": "’ubuy sa biru’ na ana nanu’ zayzyuwaw",
        "markaspatrolleddiff": "Sinbbaq sa wayal gawzyagan mita’",
        "markedaspatrolled": "Sinbbaq sa wayal gawzyagan mita’",
        "patrol-log-page": "Inblaq gmawzyaw mita’ binrwan",
-       "log-show-hide-patrol": "$1 inblaq gmawzyaw mita’ binrwan",
-       "log-show-hide-tag": "$1 bniru’ sa lalu’ na qinlah",
        "confirm-markpatrolled-button": "Wal balay",
        "previousdiff": "← Smural sinr’zyut miru’",
        "nextdiff": "Giqas hazi’ sinr’zyut→",
index 581b6af..fd2c5d3 100644 (file)
        "whatlinkshere": "ಇಡೆ ವಾ ಪುಟೊ ಕೊಂಡಿ ಕೊರ್ಪುಂಡು",
        "whatlinkshere-title": "\"$1\" ಕ್ಕ್ ಸಂಪರ್ಕ ಕೊರ್ಪಿನ ಪುಟೊಕುಲು",
        "whatlinkshere-page": "ಪುಟೊ:",
-       "linkshere-2": "</strong>$1<strong>ಗ್ ಈ ತಿರ್ತ್‍ದ ಪುಟೊಕುಲು ಕೊಂಡಿ ಕೊರ್ಪುಂಡು.",
-       "nolinkshere-2": "'''$1''' ಗ್ ವಾ ಪುಟೊಕುಲೆಡ್ಲಾ ಲಿಂಕ್ ಇಜ್ಜಿ.",
+       "linkshere": "</strong>$1<strong>ಗ್ ಈ ತಿರ್ತ್‍ದ ಪುಟೊಕುಲು ಕೊಂಡಿ ಕೊರ್ಪುಂಡು.",
+       "nolinkshere": "'''$2''' ಗ್ ವಾ ಪುಟೊಕುಲೆಡ್ಲಾ ಲಿಂಕ್ ಇಜ್ಜಿ.",
        "isredirect": "ಪಿರ ನಿರ್ದೇಶನೊದ ಪುಟೊ",
        "istemplate": "ಸೇರಾವುನೆ",
        "isimage": "ಫೈಲ್‍ದ ಕೊಂಡಿ",
index ad2fb34..83a75b2 100644 (file)
        "tog-newpageshidepatrolled": "కొత్త పేజీల జాబితా నుంచి నిఘా ఉన్న పేజీలను దాచు",
        "tog-hidecategorization": "పేజీ వర్గీకరణను దాచు",
        "tog-extendwatchlist": "కేవలం ఇటీవలి మార్పులే కాక, మార్పులన్నీ చూపించటానికి నా వీక్షణా జాబితాను పెద్దది చేయి",
-       "tog-usenewrc": "ఇటీవలి మార్పులు మరియు వీక్షణ జాబితాలలో మార్పులను పేజీ వారీగా చూపించు",
+       "tog-usenewrc": "ఇటీవలి మార్పులు, వీక్షణ జాబితాలలో మార్పులను పేజీ వారీగా చూపించు",
        "tog-numberheadings": "శీర్షికలకు అప్రమేయంగా వరుస సంఖ్యలు చేర్చు",
        "tog-showtoolbar": "దిద్దుబాటు పనిముట్ల పట్టీని చూపించు",
        "tog-editondblclick": "డబుల్‌ క్లిక్కు చేసినప్పుడు పేజీని మార్చు",
        "tog-editsectiononrightclick": "విభాగాల శీర్షికల మీద కుడినొక్కుతో విభాగపు దిద్దుబాటును చేతనం చేయి",
-       "tog-watchcreations": "నేను సృష్టించే పేజీలను మరియు దస్త్రాలను నా వీక్షణ జాబితాకు చేర్చు",
-       "tog-watchdefault": "నేను మార్చే పేజీలను మరియు దస్త్రాలను నా వీక్షణ జాబితాకు చేర్చు",
-       "tog-watchmoves": "నేను తరలించిన పేజీలను మరియు దస్త్రాలను నా వీక్షణ జాబితాకు చేర్చు",
-       "tog-watchdeletion": "నేను తొలగించిన పేజీలను మరియు దస్త్రాలను నా వీక్షణ జాబితాకు చేర్చు",
+       "tog-watchcreations": "నేను సృష్టించే పేజీలను, దస్త్రాలనూ నా వీక్షణ జాబితాకు చేర్చు",
+       "tog-watchdefault": "నేను మార్చే పేజీలను, దస్త్రాలనూ నా వీక్షణ జాబితాకు చేర్చు",
+       "tog-watchmoves": "నేను తరలించిన పేజీలను, దస్త్రాలనూ నా వీక్షణ జాబితాకు చేర్చు",
+       "tog-watchdeletion": "నేను తొలగించిన పేజీలను, దస్త్రాలనూ నా వీక్షణ జాబితాకు చేర్చు",
        "tog-watchuploads": "నేను ఎక్కించే కొత్త దస్త్రాలను నా వీక్షణ జాబితాకు చేర్చు",
        "tog-watchrollback": "నేను పునస్స్థాపించిన పేజీలను నా వీక్షణ జాబితాకు జోడించు",
        "tog-minordefault": "అప్రమేయంగా నా మార్పులను చిన్న మార్పులుగా గుర్తించు",
        "tog-previewonfirst": "మొదటి  దిద్దుబాటు చేసినపుడు వ్యాసపు మునుచూపు చూపించు",
        "tog-enotifwatchlistpages": "నా వీక్షణాజాబితా లోని పేజీ లేదా దస్త్రం మారినపుడు నాకు ఈ-మెయిలు పంపు",
        "tog-enotifusertalkpages": "నా చర్చా పేజీలో మార్పులు జరిగినపుడు నాకు ఈ-మెయిలు పంపు",
-       "tog-enotifminoredits": "పేజీలు మరియు దస్త్రాలలో జరిగే చిన్న మార్పులకు కూడా నాకు ఈ-మెయిలును పంపు",
+       "tog-enotifminoredits": "పేజీలు, దస్త్రాలలో జరిగే చిన్న మార్పులకు కూడా నాకు ఈ-మెయిలును పంపు",
        "tog-enotifrevealaddr": "గమనింపు మెయిళ్ళలో నా ఈ-మెయిలు చిరునామాను చూపించు",
        "tog-shownumberswatching": "వీక్షకుల సంఖ్యను చూపు",
        "tog-oldsig": "మీ ప్రస్తుత సంతకం:",
        "tog-fancysig": "సంతకాన్ని వికీపాఠ్యంగా తీసుకో (ఆటోమెటిక్‌ లింకు లేకుండా)",
-       "tog-uselivepreview": "తాà°\9cà°¾ à°®à±\81à°¨à±\81à°\9cà±\82à°ªà±\81à°¨à±\81 à°µà°¾à°¡ు",
+       "tog-uselivepreview": "à°ªà±\87à°\9cà±\80ని à°®à°³à±\8dà°³à±\80 à°²à±\8bà°¡à±\81 à°\9aà±\86à°¯à±\8dà°¯à°\95à±\81à°\82à°¡à°¾ à°®à±\81à°¨à±\81à°\9cà±\82à°ªà±\81లనà±\81 à°\9aà±\82పిà°\82à°\9aు",
        "tog-forceeditsummary": "దిద్దుబాటు సారాంశం ఖాళీగా ఉంటే ఆ విషయాన్ని నాకు సూచించు",
        "tog-watchlisthideown": "నా మార్పులను వీక్షణా జాబితాలో చూపించొద్దు",
        "tog-watchlisthidebots": "బాట్లు చేసిన మార్పులను నా వీక్షణా జాబితాలో చూపించొద్దు",
        "mypage": "పుట",
        "mytalk": "చర్చ",
        "anontalk": "చర్చ",
-       "navigation": "మారà±\8dà°\97దరà±\8dà°¶à°\95à°\82",
+       "navigation": "మారà±\8dà°\97à°¸à±\82à°\9aà±\80",
        "and": "&#32;మరియు",
        "faq": "తరచూ అడిగే ప్రశ్నలు",
        "actions": "పనులు",
        "print": "ముద్రించు",
        "view": "చూపు",
        "view-foreign": "$1 లో చూడండి",
-       "edit": "సవరిà°\82చు",
+       "edit": "మారà±\8dచు",
        "edit-local": "స్థానిక వివరణని మార్చు",
        "create": "సృష్టించు",
        "create-local": "స్థానిక వివరణను చేర్చు",
        "views": "చూపులు",
        "toolbox": "పనిముట్లు",
        "tool-link-userrights": "{{GENDER:$1|వాడుకరి}} గుంపులను మార్చు",
-       "tool-link-userrights-readonly": "{{GENDER:$1|వాడà±\81à°\95à°°à°¿}} à°\97à±\81à°\82à°ªà±\81లనà±\81 à°\9aà±\82à°¡à°\82à°¡à°¿",
+       "tool-link-userrights-readonly": "{{GENDER:$1|వాడà±\81à°\95à°°à°¿}} à°\97à±\81à°\82à°ªà±\81లనà±\81 à°\9aà±\82à°¡à°¡à°\82",
        "tool-link-emailuser": "ఈ {{GENDER:$1|వాడుకరికి}} ఈమెయిలు పంపు",
        "imagepage": "ఫైలు పేజీని చూడండి",
        "mediawikipage": "సందేశం పేజీని చూడండి",
        "lastmodifiedat": "ఈ పేజీలో చివరి మార్పు $1న $2కు జరిగింది.",
        "viewcount": "ఈ పేజీ {{PLURAL:$1|ఒక్క సారి|$1 సార్లు}} దర్శించబడింది.",
        "protectedpage": "సంరక్షణలోని పేజీ",
-       "jumpto": "à°\87à°\95à±\8dà°\95à°¡à°¿à°\95à°¿ à°\97à±\86à°\82à°¤ు:",
+       "jumpto": "à°\87à°\95à±\8dà°\95à°¡à°¿à°\95à°¿ à°¦à±\82à°\95ు:",
        "jumptonavigation": "మార్గసూచీ",
        "jumptosearch": "వెతుకు",
        "view-pool-error": "క్షమించండి, ప్రస్తుతం సర్వర్లన్నీ ఓవర్‌లోడ్ అయిఉన్నాయి.\nచాలామంది వాడుకరులు ఈ పేజీని చూస్తున్నారు.\nఈ పేజీని వీక్షించడానికి కొద్దిసేపు నిరీక్షించండి.\n\n$1",
        "nospecialpagetext": "<strong>మీరు అడిగిన ప్రత్యేకపేజీ సరైనది కాదు.</strong>\n\nసరైన ప్రత్యేకపేజీల జాబితా [[Special:SpecialPages|{{int:specialpages}}]] వద్ద ఉంది.",
        "error": "లోపం",
        "databaseerror": "డేటాబేసు లోపం",
-       "databaseerror-text": "డేటాబేసు క్వెరీ లోపం దొర్లింది.\nసాఫ్టువేరులోని ఉన్న దోషానికి ఇది సూచిక కావచ్చు.",
+       "databaseerror-text": "డేటాబేసు క్వెరీ లోపం దొర్లింది.\nసాఫ్టువేరులో ఉన్న దోషానికి ఇది సూచిక కావచ్చు.",
        "databaseerror-textcl": "డేటాబేసు క్వెరీ లోపం దొర్లింది.",
        "databaseerror-query": "క్వెరీ: $1",
        "databaseerror-function": "ఫంక్షన్: $1",
        "readonly": "డేటాబేసు లాక్‌చెయ్యబడింది",
        "enterlockreason": "డేటాబేసుకు వేయబోతున్న లాకుకు కారణం తెలుపండి, దానితోపాటే ఎంతసమయం తరువాత ఆ లాకు తీసేస్తారో కూడా తెలుపండి",
        "readonlytext": "ప్రస్తుతం కొత్త ఎంట్రీలు, మార్పుచేర్పులు చెయ్యకుండా డేటాబేసు లాకు చేయబడింది. మామూలుగా జరిగే నిర్వహణ కొరకు ఇది జరిగి ఉండవచ్చు. అది పూర్తి కాగానే తిరిగి మామూలుగా పనిచేస్తుంది.\n\nదీనిని లాకు చేసిన నిర్వాహకుడు ఇలా తెలియజేస్తున్నాడు: $1",
-       "missing-article": "\"$1\" $2 à°\85à°¨à±\87 à°ªà±\87à°\9cà±\80 à°¯à±\8aà°\95à±\8dà°\95 à°ªà°¾à° à±\8dà°¯à°\82 à°¡à±\87à°\9fాబà±\87à°¸à±\81à°²à±\8b à°¦à±\8aà°°à°\95à°²à±\87à°¦à±\81.\n\nà°\95ాలà°\82 à°\9aà±\86à°²à±\8dలిన à°¤à±\87à°¡à°¾ à°\95à±\8bà°¸à°\82 à°\9aà±\82సినపà±\81à°¡à±\81à°\97ానà±\80, à°¤à±\8aà°²à°\97à°¿à°\82à°\9aà°¿à°¨ à°ªà±\87à°\9cà±\80 à°\9aà°°à°¿à°¤à°\82 à°\95à±\8bà°¸à°\82 à°\9aà±\82సినపà±\81à°¡à±\81à°\97ానà±\80 à°\87ది à°¸à°¾à°§à°¾à°°à°£à°\82à°\97à°¾ à°\9cà°°à±\81à°\97à±\81à°¤à±\81à°\82ది.\n\nà°\92à°\95à°µà±\87à°³ à°\85లా à°\95à°¾à°\95à°ªà±\8bà°¤à±\87, à°®à±\80à°°à±\8b à°¬à°\97à±\8dâ\80\8cà°¨à±\81 à°\95à°¨à±\81à°\95à±\8dà°\95à±\81à°¨à±\8dà°¨à°\9fà±\8dà°\9fà±\87.\nà°\88 URLà°¨à±\81 à°¸à±\82à°\9aà°¿à°¸à±\8dà°¤à±\82, à°¦à±\80à°¨à±\8dని à°\93 [[Special:ListUsers/sysop|నిరà±\8dవాహà°\95à±\81నిà°\95à°¿]] à°¤à±\86లియà°\9cà±\87à°¯à°\82à°¡à°¿.",
+       "missing-article": "\"$1\" $2 అనే పేజీ పాఠ్యం డేటాబేసులో దొరకలేదు.\n\nకాలం చెల్లిన తేడా కోసం చూసినపుడుగానీ, తొలగించిన పేజీ చరితం కోసం చూసినపుడుగానీ ఇది సాధారణంగా జరుగుతుంది.\n\nఒకవేళ అలా కాకపోతే, మీరో బగ్‌ను కనుక్కున్నట్టే.\nఈ URLను సూచిస్తూ, దీన్ని ఓ [[Special:ListUsers/sysop|నిర్వాహకునికి]] తెలియజేయండి.",
        "missingarticle-rev": "(కూర్పు#: $1)",
        "missingarticle-diff": "(తేడా: $1, $2)",
        "readonly_lag": "అనుచర (స్లేవ్) డేటాబేసు సర్వర్లు, ప్రధాన (మాస్టరు) సర్వరును అందుకునేందుకుగాను, డేటాబేసు ఆటోమాటిక్‌గా లాకు అయింది.",
        "delete-hook-aborted": "తొలగింపును హుక్ ఆపేసింది.\nవివరణ ఏమీ ఇవ్వలేదు.",
        "no-null-revision": "\"$1\" పేజీకి కొత్త శూన్య కూర్పు (నల్ రివిజన్) ను సృష్టించలేకపోయాం",
        "badtitle": "తప్పు శీర్షిక",
-       "badtitletext": "à°®à±\80à°°à±\81 à°\95à±\8bà°°à°¿à°¨ à°ªà±\87à°\9cà±\80 à°¯à±\8aà°\95à±\8dà°\95 à°ªà±\87à°°à±\81 à°\9aà±\86à°²à±\8dలనిది, à°\96ాళà±\80à°\97à°¾ à°\89à°\82ది, à°²à±\87దా à°¤à°ªà±\8dà°ªà±\81 à°²à°¿à°\82à°\95à±\81à°¤à±\8b à°\95à±\82à°¡à°¿à°¨ à°\85à°\82తరà±\8dవిà°\95à±\80 à°²à±\87దా à°\85à°\82తర-భాషా à°¶à±\80à°°à±\8dà°·à°¿à°\95 à°\85యివà±\81à°\82డాలి.\nà°¶à±\80à°°à±\8dà°·à°¿à°\95లలà±\8b à°\89పయà±\8bà°\97à°¿à°\82à°\9aà°\95à±\82డని à°\85à°\95à±\8dషరాలà±\81 à°¦à°¾à°¨à°¿à°²à±\8b à°\89à°\82à°¡à°¿à°µà±\81à°\82à°¡à±\8aà°\9aà±\8dà°\9aà±\81.",
+       "badtitletext": "మీరు కోరిన పేజీ పేరు చెల్లనిది, ఖాళీగా ఉంది, లేదా తప్పు లింకుతో కూడిన అంతర్వికీ లేదా అంతర-భాషా శీర్షిక అయివుండాలి.\nశీర్షికలలో ఉపయోగించకూడని అక్షరాలు దానిలో ఉండివుండొచ్చు.",
        "title-invalid-empty": "కోరబడిన పేజీ శీర్షిక ఖాళీగా ఉంది లేదా కేవలం పేరుబరి పేరు కలిగి ఉంది.",
        "title-invalid-utf8": "కోరిన పేజీ శీర్షికలో చెల్లని UTF-8 అక్షరాలున్నాయి.",
        "title-invalid-interwiki": "మీరడిగిన పేజీ శీర్షికలో అంతర వికీ లంకె ఉంది, కానీ అది నిషిద్ధం.",
        "perfcachedts": "కింది సమాచారం ముందే సేకరించి పెట్టుకున్నది. దీన్ని $1న చివరిసారిగా తాజాకరించారు. ఈ కాషెలో గరిష్టంగా {{PLURAL:$4|ఒక్క ఫలితం ఉంది|$4 ఫలితాలు ఉన్నాయి}}.",
        "querypage-no-updates": "ప్రస్తుతం ఈ పేజీకి తాజాకరణలని అచేతనం చేసారు.\nఇక్కడున్న డేటా కూడా ప్రస్తుతం తాజాకరించబడదు.",
        "viewsource": "మూలాన్ని చూపించు",
-       "viewsource-title": "$1 à°¯à±\8aà°\95à±\8dà°\95 సోర్సు చూడండి",
+       "viewsource-title": "$1 à°ªà±\87à°\9cà±\80 సోర్సు చూడండి",
        "actionthrottled": "కార్యాన్ని ఆపేసారు",
        "actionthrottledtext": "దుశ్చర్యను నిరోధించేందుకు గాను, తక్కువ సమయంలో మరీ ఎక్కువ సార్లు ఈ పని చేయకుండా పరిమితి విధించాం. మీరు దాన్ని అధిగమించారు. కొద్ది నిమిషాలు ఆగి మరలా ప్రయత్నించండి.",
        "protectedpagetext": "ఈ పేజీలో మార్పులు వగైరాలు చెయ్యకుండా ఉండేందుకు గాను, సంరక్షించబడింది.",
        "viewsourcetext": "మీరీ పేజీ సోర్సును చూడవచ్చు, కాపీ చేసుకోవచ్చు.",
-       "viewyourtext": "à°\88 à°ªà±\87à°\9cà±\80à°²à±\8b <strong>à°®à±\80à°°à±\81 à°\9aà±\87సిన à°®à°¾à°°à±\8dà°ªà±\81à°²</strong> à°¯à±\8aà°\95à±\8dà°\95 à°®à±\82లానà±\8dని à°\9aà±\82à°¡à°µà°\9aà±\8dà°\9aà±\81, à°\95ాపà±\80చేసుకోవచ్చు.",
+       "viewyourtext": "à°\88 à°ªà±\87à°\9cà±\80à°²à±\8b <strong>à°®à±\80à°°à±\81 à°\9aà±\87సిన à°®à°¾à°°à±\8dà°ªà±\81à°²</strong> à°®à±\82లానà±\8dని à°\9aà±\82à°¡à°µà°\9aà±\8dà°\9aà±\81, à°\95ాపà±\80 చేసుకోవచ్చు.",
        "protectedinterface": "ఈ పేజీ, ఈ వికీ యొక్క సాఫ్టువేరు ఇంటరుఫేసుకు చెందిన టెక్స్టును అందిస్తుంది. దుశ్చర్యల నివారణ కోసమై దీన్ని సంరక్షించాం. వికీలన్నిటిలోను అనువాదాలను చేర్చాలన్నా, మార్చాలన్నా మీడియావికీ స్థానికీకరణ ప్రాజెక్టైన [https://translatewiki.net/ translatewiki.net] ను వాడండి.",
        "editinginterface": "<strong>హెచ్చరిక:</strong> సాఫ్టువేరుకు ఇంటరుఫేసు టెక్స్టును అందించేందుకు పనికొచ్చే పేజీని మీరు సరిదిద్దుతున్నారు.\nఈ పేజీలో చేసే మార్పుల వల్ల ఇతర వాడుకరులకు కనబడే ఇంటరుఫేసు ప్రభావితమౌతుంది.",
        "translateinterface": "అన్ని వికీలలో కనిపించేలా అనువాదాలు చేర్చాలన్నా, మార్చాలన్నా, దయచేసి [https://translatewiki.net/ translatewiki.net] ను వాడండి. ఇది మీడియావికీ స్థానికీకరణ ప్రాజెక్టు.",
        "namespaceprotected": "'''$1''' నేంస్పేసులో మార్పులు చేయటానికి మీకు అనుమతి లేదు.",
        "customcssprotected": "ఈ CSS పేజీని మార్చేందుకు మీకు అనుమతి లేదు. ఎందుకంటే వేరే వాడుకరి యొక్క వ్యక్తిగత సెట్టింగులు అందులో ఉన్నాయి.",
        "customjsprotected": "ఈ JavaScript పేజీని మార్చేందుకు మీకు అనుమతి లేదు. ఎందుకంటే వేరే వాడుకరి యొక్క వ్యక్తిగత సెట్టింగులు అందులో ఉన్నాయి.",
+       "sitecssprotected": "ఈ CSS లో మీరు చేసే మార్పు మొత్తం సందర్శకులందరినీ ప్రభావితం చేసే అవకాశం ఉంది కాబట్టి ఆ అనుమతి మీకు లేదు.",
+       "sitejsonprotected": "ఈ JSON లో మీరు చేసే మార్పు మొత్తం సందర్శకులందరినీ ప్రభావితం చేసే అవకాశం ఉంది కాబట్టి ఆ అనుమతి మీకు లేదు.",
+       "sitejsprotected": "ఈ JavaScript లో మీరు చేసే మార్పు మొత్తం సందర్శకులందరినీ ప్రభావితం చేసే అవకాశం ఉంది కాబట్టి ఆ అనుమతి మీకు లేదు.",
        "mycustomcssprotected": "ఈ CSS పేజీని సవరించేందుకు మీకు అనుమతి లేదు.",
+       "mycustomjsonprotected": "ఈ JSON పేజీని సవరించేందుకు మీకు అనుమతి లేదు.",
        "mycustomjsprotected": "ఈ జావాస్క్రిప్టు పేజీని సవరించేందుకు మీకు అనుమతి లేదు.",
        "myprivateinfoprotected": "మీ అంతరంగిక సమాచారాన్ని సవరించేందుకు మీకు అనుమతి లేదు.",
        "mypreferencesprotected": "మీ అభీష్టాలను సవరించేందుకు మీకు అనుమతి లేదు.",
        "loginerror": "లాగిన్ లోపం",
        "createacct-error": "ఖాతా సృష్టించడంలో లోపం",
        "createaccounterror": "ఖాతాను సృష్టించలేకపోయాం: $1",
-       "nocookiesnew": "ఖాతాని సృష్టించాం, కానీ మీరు ఇంకా లోనికి ప్రవేశించలేదు.\nవాడుకరుల ప్రవేశానికి {{SITENAME}} కూకీలను వాడుతుంది.\nమీరు కూకీలని అచేతనం చేసివున్నారు.\nదయచేసి వాటిని చేతనంచేసి, మీ కొత్త వాడుకరి పేరు మరియు సంకేతపదాలతో లోనికి ప్రవేశించండి.",
+       "nocookiesnew": "ఖాతాని సృష్టించాం, కానీ మీరు ఇంకా లోనికి ప్రవేశించలేదు.\nవాడుకరుల ప్రవేశానికి {{SITENAME}} కూకీలను వాడుతుంది.\nమీరు కూకీలని అచేతనం చేసివున్నారు.\nదయచేసి వాటిని చేతనంచేసి, మీ కొత్త వాడుకరి పేరు, సంకేతపదాలతో లోనికి ప్రవేశించండి.",
        "nocookieslogin": "వాడుకరుల ప్రవేశానికై {{SITENAME}} కూకీలను వాడుతుంది.\nమీరు కుకీలని అచేతనం చేసివున్నారు.\nవాటిని చేతనంచేసి ప్రయత్నించండి.",
        "nocookiesfornew": "మూలాన్ని కనుక్కోలేకపోయాం కాబట్టి, ఈ వాడుకరి ఖాతాను సృష్టించలేకపోయాం.\nమీ కంప్యూటర్లో కూకీలు చేతనమై ఉన్నాయని నిశ్చయించుకొని, ఈ పేజీని తిరిగి లోడు చేసి, మళ్ళీ ప్రయత్నించండి.",
        "createacct-loginerror": "ఖాతా విజయవంతంగా సృష్టించబడింది, కానీ ఆటోమాటిగ్గా లాగిన్ అవలేరు.  స్వయంగా మీరే [[Special:UserLogin|లాగినవండి]].",
        "nosuchusershort": "\"$1\" పేరుతో వాడుకరి ఎవరూ లేరు. పేరు సరి చూసుకోండి.",
        "nouserspecified": "వాడుకరి పేరును తప్పనిసరిగా ఇవ్వాలి.",
        "login-userblocked": "ఈ వాడుకరిని నిరోధించారు. ప్రవేశానికి అనుమతి లేదు.",
-       "wrongpassword": "à°\88 à°¸à°\82à°\95à±\87తపదà°\82 à°¸à°°à±\88నది à°\95ాదà±\81. à°¦à°¯à°\9aà±\87సి à°®à°³à±\8dà°²à±\80 ప్రయత్నించండి.",
+       "wrongpassword": "వాడà±\81à°\95à°°à°¿ à°ªà±\87à°°à±\81 à°²à±\87దా à°¸à°\82à°\95à±\87తపదà°\82 à°¤à°ªà±\8dà°ªà±\81à°\97à°¾ à°\87à°\9aà±\8dà°\9aారà±\81.\nదయà°\9aà±\87సి à°®à°°à±\8bసారి ప్రయత్నించండి.",
        "wrongpasswordempty": "ఖాళీ సంకేతపదం ఇచ్చారు. మళ్ళీ ప్రయత్నించండి.",
        "passwordtooshort": "సంకేతపదం కనీసం {{PLURAL:$1|1 అక్షరం|$1 అక్షరాల}} నిడివి ఉండాలి.",
        "passwordtoolong": "సంకేతపదం పొడవు {{PLURAL:$1|1 అక్షరం|$1 అక్షరాల}} కన్నా ఎక్కువ ఉండకూడదు.",
-       "passwordtoopopular": "మామà±\82à°²à±\81à°\97à°¾ à°µà°¾à°¡à±\87 à°¸à°\82à°\95à±\87తపదాలనà±\81 à°µà°¾à°¡à±\87 à°µà±\80à°²à±\8dà°²à±\87à°¦à±\81. à°®à°°à°¿à°\82à°¤ à°µà°¿à°¶à°¿ష్టమైన సంకేతపదాన్ని ఎంచుకోండి.",
+       "passwordtoopopular": "సాధారణà°\82à°\97à°¾ à°µà°¾à°¡à±\87 à°¸à°\82à°\95à±\87తపదాలనà±\81 à°µà°¾à°¡à±\87 à°µà±\80à°²à±\8dà°²à±\87à°¦à±\81. à°\8aహిà°\82à°\9aడానిà°\95à°¿ à°\95ష్టమైన సంకేతపదాన్ని ఎంచుకోండి.",
        "password-name-match": "మీ సంకేతపదం మీ వాడుకరిపేరుకి భిన్నంగా ఉండాలి.",
-       "password-login-forbidden": "ఈ వాడుకరిపేరు మరియు సంకేతపదాలను ఉపయోగించడం నిషిద్ధం.",
+       "password-login-forbidden": "ఈ వాడుకరిపేరు, సంకేతపదాలను ఉపయోగించడం నిషిద్ధం.",
        "mailmypassword": "సంకేతపదాన్ని మార్చు",
        "passwordremindertitle": "{{SITENAME}} కోసం కొత్త తాత్కాలిక సంకేతపదం",
-       "passwordremindertext": "{{SITENAME}} ($4) à°²à±\8b à°\95à±\8aà°¤à±\8dà°¤ à°¸à°\82à°\95à±\87తపదà°\82 à°ªà°\82పిà°\82à°\9aమని à°\8eవరà±\8b (బహà±\81à°¶ à°®à±\80à°°à±\87, à°\90.à°ªà±\80. à°\9aà°¿à°°à±\81నామా $1 à°¨à±\81à°\82à°¡à°¿) à°\85à°¡à°¿à°\97ారà±\81. à°µà°¾à°¡à±\81à°\95à°°à°¿ \"$2\" à°\95à±\8aà°°à°\95à±\81 \"$3\" à°\85à°¨à±\87 à°¤à°¾à°¤à±\8dà°\95ాలిà°\95 à°¸à°\82à°\95à±\87తపదà°\82 à°¸à°¿à°¦à±\8dà°§à°\82à°\9aà±\87సి à°\89à°\82à°\9aà°¾à°\82. à°®à±\80 à°\89à°¦à±\8dà°¦à±\87à°¶à°\82 à°\85à°¦à±\87 à°\85యితà±\87, à°\87à°ªà±\8dà°ªà±\81à°¡à±\81 à°®à±\80à°°à±\81 à°¸à±\88à°\9fà±\81à°²à±\8bనిà°\95à°¿ à°ªà±\8dà°°à°µà±\87శిà°\82à°\9aà°¿ à°\95à±\8aà°¤à±\8dà°¤ à°¸à°\82à°\95à±\87తపదానà±\8dని à°\8eà°\82à°\9aà±\81à°\95à±\8bà°µà°\9aà±\8dà°\9aà±\81. à°®à±\80 à°¤à°¾à°¤à±\8dà°\95ాలిà°\95 à°¸à°\82à°\95à±\87తపదà°\82 {{PLURAL:$5|ఒక రోజు|$5 రోజుల}}లో కాలంచెల్లుతుంది.\n\nఒకవేళ ఈ అభ్యర్థన మీరుకాక మరెవరో చేసారనుకున్నా లేదా మీ సంకేతపదం మీకు గుర్తుకువచ్చి దాన్ని మార్చకూడదు అనుకుంటున్నా, ఈ సందేశాన్ని విస్మరించి మీ పాత సంకేతపదాన్ని వాడడం కొనసాగించవచ్చు.",
+       "passwordremindertext": "{{SITENAME}} ($4) à°\95à±\8bà°¸à°\82 à°\95à±\8aà°¤à±\8dà°¤ à°¸à°\82à°\95à±\87తపదà°\82 à°ªà°\82పిà°\82à°\9aమని à°\8eవరà±\8b (à°\90.à°ªà±\80. à°\9aà°¿à°°à±\81నామా $1 à°¨à±\81à°\82à°¡à°¿) à°\85à°¡à°¿à°\97ారà±\81. à°µà°¾à°¡à±\81à°\95à°°à°¿ \"$2\" à°\95à±\8aà°°à°\95à±\81 \"$3\" à°\85à°¨à±\87 à°¤à°¾à°¤à±\8dà°\95ాలిà°\95 à°¸à°\82à°\95à±\87తపదà°\82 à°¸à°¿à°¦à±\8dà°§à°\82à°\9aà±\87సి à°\89à°\82à°\9aà°¾à°\82. à°®à±\80 à°\89à°¦à±\8dà°¦à±\87à°¶à°\82 à°\85à°¦à±\87 à°\85యితà±\87, à°\87à°ªà±\8dà°ªà±\81à°¡à±\81 à°®à±\80à°°à±\81 à°¸à±\88à°\9fà±\81à°²à±\8bనిà°\95à°¿ à°ªà±\8dà°°à°µà±\87శిà°\82à°\9aà°¿ à°\95à±\8aà°¤à±\8dà°¤ à°¸à°\82à°\95à±\87తపదానà±\8dని à°\8eà°\82à°\9aà±\81à°\95à±\8bవాలి. à°®à±\80 à°¤à°¾à°¤à±\8dà°\95ాలిà°\95 à°¸à°\82à°\95à±\87తపదానిà°\95à°¿ {{PLURAL:$5|ఒక రోజు|$5 రోజుల}}లో కాలంచెల్లుతుంది.\n\nఒకవేళ ఈ అభ్యర్థన మీరుకాక మరెవరో చేసారనుకున్నా లేదా మీ సంకేతపదం మీకు గుర్తుకువచ్చి దాన్ని మార్చకూడదు అనుకుంటున్నా, ఈ సందేశాన్ని విస్మరించి మీ పాత సంకేతపదాన్ని వాడడం కొనసాగించవచ్చు.",
        "noemail": "వాడుకరి \"$1\" కు ఈమెయిలు చిరునామా నమోదయి లేదు.",
        "noemailcreate": "మీరు సరైన ఈమెయిల్ చిరునామాని ఇవ్వాలి",
        "passwordsent": "\"$1\" కొరకు నమోదైన ఈ-మెయిలు చిరునామాకి కొత్త సంకేతపదాన్ని పంపించాం.\nఅది అందిన తర్వాత ప్రవేశించి చూడండి.",
        "botpasswords-insert-failed": "బాట్ పేరు \"$1\"ను చేర్చలేకపోయాం. దీన్ని ఇంతకు ముందే చేర్చారా ఏంటి?",
        "botpasswords-update-failed": "బాట్ పేరు \"$1\" ను తాజాకరించలేకపోయాం. దీన్ని తొలగించారా?",
        "botpasswords-created-title": "బాట్ సంకేతపదాన్ని సృష్టించాం",
-       "botpasswords-created-body": "వాడుకరి \"$2\" కు చెందిన \"$1\" అనే బాట్‌కు బాట్ సంకేతపదాన్ని సృష్టించాం.",
+       "botpasswords-created-body": "{{GENDER:$2|వాడుకరి}} \"$2\" కు చెందిన \"$1\" అనే బాట్‌కు బాట్ సంకేతపదాన్ని సృష్టించాం.",
        "botpasswords-updated-title": "బాట్ సంకేతపదాన్ని తాజాకరించాం",
-       "botpasswords-updated-body": "వాడుకరి \"$2\" కు చెందిన \"$1\" అనే బాట్‌ యొక్క బాట్ సంకేతపదాన్ని తాజాకరించాం.",
+       "botpasswords-updated-body": "{{GENDER:$2|వాడుకరి}} \"$2\" కు చెందిన \"$1\" అనే బాట్‌ యొక్క బాట్ సంకేతపదాన్ని తాజాకరించాం.",
        "botpasswords-deleted-title": "బాట్ సంకేతపదాన్ని తొలగించాం",
-       "botpasswords-deleted-body": "వాడుకరి \"$2\" కు చెందిన \"$1\" అనే బాట్‌ యొక్క బాట్ సంకేతపదాన్ని తొలగించాం.",
+       "botpasswords-deleted-body": "{{GENDER:$2|వాడుకరి}} \"$2\" కు చెందిన \"$1\" అనే బాట్‌ యొక్క బాట్ సంకేతపదాన్ని తొలగించాం.",
        "botpasswords-newpassword": "<strong>$1</strong> తో లాగినయేందుకు కొత్త సంకేతపదం <strong>$2</strong>. <em>భావి ఉపయోగం కోసం దీన్ని జాగ్రత్త చేసుకోండి.</em><br> (లాగిన్ పేరుగా వాడుకరిపేరే ఉండాల్సిన పాత బాట్‌ల విషయంలో <strong>$3</strong> ను వాడుకరిపేరుగాను, <strong>$4</strong> ను సంకేతపదంగానూ వాడుకోవచ్చు.)",
+       "botpasswords-invalid-name": "ఇచ్చిన వాడుకరిపేరులో బాట్ సంకేతపదం సెపరేటరు (\"$1\") లేదు.",
        "botpasswords-not-exist": "వాడుకరి \"$1\" కి \"$2\" అనే బాట్ సంకేతపదం లేదు.",
+       "botpasswords-needs-reset": "{{GENDER:$1|వాడుకరి}}కి చెందిన బాట్ పేరు, \"$2\", యొక్క బాట్ సంకేతపదాన్ని- \"$1\" - మార్చాలి.",
        "resetpass_forbidden": "సంకేతపదాలను మార్చటం కుదరదు",
        "resetpass_forbidden-reason": "సంకేతపదాలు మార్చజాలరు: $1",
        "resetpass-no-info": "ఈ పేజీని నేరుగా చూడటానికి మీరు లాగినయి వుండాలి.",
        "resetpass-submit-loggedin": "సంకేతపదాన్ని మార్చు",
        "resetpass-submit-cancel": "రద్దుచేయి",
        "resetpass-wrong-oldpass": "తప్పుడు తాత్కాలిక లేదా ప్రస్తుత సంకేతపదం.\nమీరు మీ సంకేతపదాన్ని ఇప్పటికే మార్చుకొని ఉండవచ్చు లేదా కొత్త తాత్కాలిక సంకేతపదం కోసం అభ్యర్థించి ఉండవచ్చు.",
-       "resetpass-recycled": "à°®à±\80 à°ªà±\8dà°°à°¸à±\8dà°¤à±\81à°¤ à°¸à°\82à°\95à±\87తపదానà±\8dని à°µà±\87à°°à±\87 à°¸à°\82à°\95à±\87తపదà°\82à°¤à±\8b à°®à°¾à°°à±\8dà°\9aà±\81à°\95à±\8bà°\82à°¡à°¿",
+       "resetpass-recycled": "à°ªà±\8dà°°à°¸à±\8dà°¤à±\81à°¤ à°¸à°\82à°\95à±\87తపదà°\82 à°\95à°\82à°\9fà±\87 à°­à°¿à°¨à±\8dనమà±\88à°¨ à°¦à°¾à°¨à°¿à°¤à±\8b à°¸à°\82à°\95à±\87తపదానà±\8dని à°®à°¾à°°à±\8dà°\9aà±\81à°\95à±\8bà°\82à°¡à°¿.",
        "resetpass-temp-emailed": "మీరు మీ ఈమెయిలుకు పంపించిన తాత్కాలిక కోడుతో లాగినయ్యారు. లాగిన్ను పూర్తి చేసేందుకు, ఇక్కడ మీరు తప్పనిసరిగా సంకేతపదం మార్చుకోవాలి:",
        "resetpass-temp-password": "తాత్కాలిక సంకేతపదం:",
        "resetpass-abort-generic": "ఓ పొడిగింత (ఎక్స్టెన్‍షన్) సంకేతపదం మార్పిడిని ఆపేసింది.",
        "resetpass-expired": "మీ సంకేతపదానికి కాలం చెల్లింది. కొత్త సంకేతపదం ఇచ్చి లాగినవండి.",
-       "resetpass-expired-soft": "à°®à±\80 à°¸à°\82à°\95à±\87తపదానిà°\95à°¿ à°\95ాలà°\82 à°\9aà±\86à°²à±\8dలిà°\82ది, à°\95ాబà°\9fà±\8dà°\9fà°¿ à°\95à±\8aà°¤à±\8dతది à°\87à°µà±\8dవాలి. à°\95à±\8aà°¤à±\8dతది à°\87à°ªà±\8dà°ªà±\81à°¡à±\87 à°\87à°µà±\8dà°µà°\82à°¡à°¿ à°²à±\87దా \"{{int:authprovider-resetpass-skip-label}}\" à°¨à±\8aà°\95à±\8dà°\95à°¿, à°¤à°°à±\81వాత à°®à°¾à°°à±\8dà°\9aà±\81à°\95à±\8bà°\82à°¡à°¿.",
-       "resetpass-validity-soft": "à°®à±\80 à°¸à°\82à°\95à±\87తపదానిà°\95à°¿ à°\95ాలà°\82 à°\9aà±\86à°²à±\8dలిà°\82ది:$1\nà°\95à±\8aà°¤à±\8dతది à°\87à°ªà±\8dà°ªà±\81à°¡à±\87 à°\8eà°\82à°\9aà±\81à°\95à±\8bà°\82à°¡à°¿, à°²à±\87దా \"{{int:authprovider-resetpass-skip-label}}\" à°¨à±\8aà°\95à±\8dà°\95à°¿, à°¤à°°à±\81వాత à°®à°¾à°°à±\8dà°\9aà±\81à°\95à±\8bà°\82à°¡à°¿.",
+       "resetpass-expired-soft": "à°®à±\80 à°¸à°\82à°\95à±\87తపదానిà°\95à°¿ à°\95ాలà°\82 à°\9aà±\86à°²à±\8dలిà°\82ది, à°\95ాబà°\9fà±\8dà°\9fà°¿ à°¦à°¾à°¨à±\8dని à°®à°¾à°°à±\8dà°\9aాలి. à°\95à±\8aà°¤à±\8dతదానà±\8dని à°\87à°ªà±\8dà°ªà±\81à°¡à±\87 à°\8eà°\82à°\9aà±\81à°\95à±\8bà°\82à°¡à°¿ à°²à±\87దా \"{{int:authprovider-resetpass-skip-label}}\" à°¨à±\8aà°\95à±\8dà°\95à°¿, à°¤à°°à±\81వాత à°®à°¾à°°à±\8dà°\9aà±\81à°\95à±\8bà°µà°\9aà±\8dà°\9aà±\81.",
+       "resetpass-validity-soft": "à°®à±\80 à°¸à°\82à°\95à±\87తపదà°\82 à°¸à°°à±\88నది à°\95ాదà±\81:$1\nà°\95à±\8aà°¤à±\8dతది à°\87à°ªà±\8dà°ªà±\81à°¡à±\87 à°\8eà°\82à°\9aà±\81à°\95à±\8bà°\82à°¡à°¿, à°²à±\87దా \"{{int:authprovider-resetpass-skip-label}}\" à°¨à±\8aà°\95à±\8dà°\95à°¿, à°¤à°°à±\81వాత à°®à°¾à°°à±\8dà°\9aà±\81à°\95à±\8bà°µà°\9aà±\8dà°\9aà±\81.",
        "passwordreset": "సంకేతపదాన్ని మార్చుకోండి",
        "passwordreset-text-one": "ఈమెయిలు ద్వారా తాత్కాలిక సంకేతపదాన్ని పొందేందుకు ఈ ఫారమును నింపండి.",
        "passwordreset-text-many": "{{PLURAL:$1|ఈమెయిలు ద్వారా తాత్కాలిక సంకేతపదాన్ని పొందేందుకు ఏదో ఒక ఫీల్డును నింపండి.}}",
        "savechanges": "మార్పులను భద్రపరచు",
        "publishpage": "పేజీని ప్రచురించు",
        "publishchanges": "మార్పులను ప్రచురించు",
+       "savearticle-start": "పేజీని భద్రపరచు",
+       "savechanges-start": "మార్పులను భద్రపరచు…",
+       "publishpage-start": "పేజీని ప్రచురించు…",
+       "publishchanges-start": "మార్పులను ప్రచురించు…",
        "preview": "మునుజూపు",
        "showpreview": "మునుజూపు చూపు",
        "showdiff": "తేడాలను చూపించు",
        "anonpreviewwarning": "<em>మీరు లాగినవలేదు. భద్రపరిస్తే ఈ పేజీ యొక్క దిద్దుబాటు చరిత్రలో మీ ఐపీ చిరునామా నమోదవుతుంది.</em>",
        "missingsummary": "<strong>గుర్తు చేస్తున్నాం:</strong> మీరు దిద్దుబాటు సారాంశమేమీ ఇవ్వలేదు. పేజీని మళ్ళీ భద్రపరచమని చెబితే సారాంశమేమీ లేకుండానే దిద్దుబాటును భద్రపరుస్తాం.",
        "selfredirect": "<strong>హెచ్చరిక:</strong> మీరు ఈ పేజీని దానికే దారిమార్పు చేస్తున్నారు. బహుశా మీరు తప్పు దారిమార్పును సూచించి ఉండవచ్చు, లేదా మీరు తప్పుడు పేజీని మారుస్తున్నారు. \nమీరు \"$1\" ను నొక్కితే దారిమార్పు పేజీ ఖచ్చితంగా సృష్టించబడుతుంది.",
-       "missingcommenttext": "à°\95à°¿à°\82à°¦ à°\93 à°µà±\8dయాà°\96à±\8dà°¯ à°°à°¾à°¯ండి.",
+       "missingcommenttext": "à°\92à°\95 à°µà±\8dయాà°\96à±\8dయనà±\81 à°\87à°µà±\8dà°µండి.",
        "missingcommentheader": "<strong>గుర్తు చేస్తున్నాం:</strong> ఈ వ్యాఖ్యకు మీరు విషయం పెట్టలేదు.\n\"$1\"ని మళ్ళీ నొక్కితే, అది లేకుండానే మీ మార్పును భద్రపరుస్తాం.",
        "summary-preview": "దిద్దుబాటు సారాంశం మునుజూపు:",
        "subject-preview": "విషయపు మునుజూపు:",
        "previewerrortext": "మీ మార్పులు మునుజూపు చూపడంలో లోపం దొర్లింది.",
        "blockedtitle": "వాడుకరి నిరోధించబడ్డారు",
-       "blockedtext": "<strong>మీ వాడుకరి పేరు లేదా ఐ.పీ. చిరునామా నిరోధించబడింది.</strong>\n\nనిరోధించినది $1.\nఅందుకు ఇచ్చిన కారణం: <em>$2</em>.\n\n* నిరోధం మొదలైన సమయం: $8\n* నిరోధించిన కాలం: $6\n* నిరోధానికి గురైనవారు: $7\n\nఈ నిరోధంపై చర్చించేందుకు మీరు $1 ను గాని, మరెవరైనా [[{{MediaWiki:Grouppage-sysop}}|నిర్వాహకులను]] గాని సంప్రదించవచ్చు.\nమీ [[Special:Preferences|ఖాతా అభిరుచులలో]] సరైన ఈ-మెయిలు చిరునామా ఇచ్చివుండకపోయినా లేదా మిమ్మల్ని  'ఈ వాడుకరికి ఈ-మెయిలు పంపు' సౌలభ్యాన్ని వాడుకోవడం నుండి నిరోధించివున్నా మీరు ఈమెయిలు ద్వారా సంప్రదించలేరు.\nమీ ప్రస్తుత ఐ.పీ. చిరునామా $3, మరియు నిరోధపు ID #$5.\nమీ సంప్రదింపులన్నిటిలోనూ వీటిని పేర్కొనండి.",
-       "autoblockedtext": "మీ ఐపీ చిరునామా ఆటోమాటిగ్గా నిరోధించబడింది. ఎందుకంటే ఇదే ఐపీ చిరునామాని ఓ నిరోధిత వాడుకరి ఉపయోగించారు. ఆ వాడుకరిని $1 నిరోధించారు.\nఅందుకు ఇచ్చిన కారణం ఇదీ:\n\n:<em>$2</em>\n\n* నిరోధం మొదలైన సమయం: $8\n* నిరోధించిన కాలం: $6\n* ఉద్దేశించిన నిరోధిత వాడుకరి: $7\n\nఈ నిరోధం గురించి చర్చించేందుకు మీరు $1 ను గానీ, లేదా ఇతర [[{{MediaWiki:Grouppage-sysop}}|నిర్వాహకులను]] గానీ సంప్రదించండి.\n\nమీ [[Special:Preferences|అభిరుచులలో]] సరైన ఈమెయిలు ఐడీని ఇచ్చి ఉంటే తప్ప, మీరు \"ఈ సభ్యునికి మెయిలు పంపు\" అనే అంశాన్ని వాడజాలరని గమనించండి. ఆ సౌలభ్యాన్ని వాడటం నుండి మిమ్మల్ని నిరోధించలేదు.\n\nమీ ప్రస్తుత ఐపీ చిరునామా $3, మరియు నిరోధపు ఐడీ: $5.\nమీ సంప్రదింపులన్నిటిలోను అన్ని పై వివరాలను ఉదహరించండి.",
+       "blockedtext": "<strong>మీ వాడుకరిపేరును లేదా ఐ.పి. చిరునామాను నిరోధించారు.</strong>\n\nనిరోధించినవారు $1.\nఅందుకు వారు ఇచ్చిన కారణం: <em>$2</em>.\n\n* నిరోధం మొదలైన సమయం: $8\n* నిరోధించిన కాలం: $6\n* నిరోధానికి గురైనవారు: $7\n\nఈ నిరోధంపై చర్చించేందుకు మీరు $1 ను గాని, మరెవరైనా [[{{MediaWiki:Grouppage-sysop}}|నిర్వాహకుని]] గాని సంప్రదించవచ్చు.\nమీ [[Special:Preferences|ఖాతా అభిరుచులలో]] సరైన ఈ-మెయిలు చిరునామా ఇచ్చివుండకపోయినా లేదా మిమ్మల్ని 'ఈ వాడుకరికి ఈ-మెయిలు పంపు' సౌలభ్యాన్ని వాడుకోవడం నుండి నిరోధించివున్నా మీరు ఈమెయిలు ద్వారా సంప్రదించలేరు.\nమీ ప్రస్తుత ఐ.పీ. చిరునామా $3, నిరోధపు ID #$5.\nమీ సంప్రదింపులన్నిటిలోనూ పై వివరాలను పేర్కొనండి.",
+       "autoblockedtext": "మీ ఐపీ చిరునామా ఆటోమాటిగ్గా నిరోధించబడింది. ఎందుకంటే ఇదే ఐపీ చిరునామాని ఓ నిరోధిత వాడుకరి ఉపయోగించారు. ఆ వాడుకరిని $1 నిరోధించారు.\nఅందుకు ఇచ్చిన కారణం ఇదీ:\n\n:<em>$2</em>\n\n* నిరోధం మొదలైన సమయం: $8\n* నిరోధించిన కాలం: $6\n* ఉద్దేశించిన నిరోధిత వాడుకరి: $7\n\nఈ నిరోధం గురించి చర్చించేందుకు మీరు $1 ను గానీ, లేదా ఇతర [[{{MediaWiki:Grouppage-sysop}}|నిర్వాహకులను]] గానీ సంప్రదించండి.\n\nమీ [[Special:Preferences|అభిరుచులలో]] సరైన ఈమెయిలు ఐడీని ఇచ్చి ఉంటే తప్ప, మీరు \"ఈ వాడుకరికి ఈమెయిలు పంపు\" అనే అంశాన్ని వాడజాలరని గమనించండి. ఆ సౌలభ్యాన్ని వాడటం నుండి మిమ్మల్ని నిరోధించలేదు.\n\nమీ ప్రస్తుత ఐపీ చిరునామా $3, నిరోధపు ఐడీ: $5.\nమీ సంప్రదింపులన్నిటిలోను అన్ని పై వివరాలను ఉదహరించండి.",
+       "systemblockedtext": "మీడియావికీ మీ వాడుకరిపేరు లేదా ఐపీ అడ్రసును ఆటోమాటిగ్గా నిరోధించింది.\nఅందుకు ఇచ్చిన కారణం:\n\n:<em>$2</em>\n\n* నిరోధం మొదలైన సమయం: $8\n* నిరోధం ముగిసే సమయం: $6\n* నిరోధానికి గురైనవారు: $7\n\nమీ ప్రస్తుత ఐపీ అడ్రసు $3.\nమీ సంప్రదింపులన్నిటిలోనూ పై వివరాలను పేర్కొనండి.",
        "blockednoreason": "కారణమేమీ ఇవ్వలేదు",
        "whitelistedittext": "పుటలలో మార్పులు చెయ్యడానికి $1.",
        "confirmedittext": "పేజీల్లో మార్పులు చేసేముందు మీ ఈమెయిలు చిరునామాను ధృవీకరించాలి. [[Special:Preferences|మీ అభిరుచుల]]లో మీ ఈమెయిలు చిరునామా రాసి, ధృవీకరించండి.",
        "userjspreview": "<strong>గుర్తుంచుకోండి, మీరింకా మీ వాడుకరి జావాస్క్రిప్ట్&zwnj;ను భద్రపరచలేదు, కేవలం పరీక్షిస్తున్నారు/సరిచూస్తున్నారు!</strong>",
        "sitecsspreview": "'''మీరు చూస్తున్నది ఈ CSS మునుజూపును మాత్రమేనని గుర్తుంచుకోండి.'''\n'''దీన్నింకా భద్రపరచలేదు!'''",
        "sitejspreview": "'''మీరు చూస్తున్నది ఈ JavaScript మునుజూపును మాత్రమేనని గుర్తుంచుకోండి.''' \n'''దీన్నింకా భద్రపరచలేదు!'''",
-       "userinvalidconfigtitle": "<strong>హెచ్చరిక:</strong> \"$1\" అనే రూపు లేదు.\nఅభిమత .css మరియు .js పుటల శీర్షికలు ఇంగ్లీషు చిన్నబడి అక్షరాల లోనే ఉండాలని గుర్తుంచుకోండి, ఉదాహరణకు ఇలా {{ns:user}}:Foo/vector.css అంతేగానీ, {{ns:user}}:Foo/Vector.css ఇలా కాదు.",
+       "userinvalidconfigtitle": "<strong>హెచ్చరిక:</strong> \"$1\" అనే రూపు లేదు.\nఅభిమత .css, .js పుటల శీర్షికలు ఇంగ్లీషు చిన్నబడి అక్షరాల లోనే ఉంటాయి. ఉదాహరణ: {{ns:user}}:Foo/vector.css. అంతేగానీ, {{ns:user}}:Foo/Vector.css ఇలా కాదు.",
        "updated": "(నవీకరించబడింది)",
        "note": "<strong>గమనిక:</strong>",
        "previewnote": "<strong>ఇది మునుజూపు మాత్రమేనని గుర్తుంచుకోండి.</strong>\nమీ మార్పులు ఇంకా భద్రమవ్వలేదు!",
        "permissionserrors": "అనుమతి లోపం",
        "permissionserrorstext": "కింద పేర్కొన్న {{PLURAL:$1|కారణం|కారణాల}} మూలంగా, ఆ పని చెయ్యడానికి మీకు అనుమతిలేదు:",
        "permissionserrorstext-withaction": "ఈ క్రింది {{PLURAL:$1|కారణం|కారణాల}} వల్ల, $2 అనుమతి మీకు లేదు:",
-       "recreate-moveddeleted-warn": "<strong>హెచ్చరిక: ఇంతకు మునుపు ఒకసారి తొలగించిన పేజీని మళ్లీ సృష్టిద్దామని మీరు ప్రయత్నిస్తున్నారు.</strong>\n\nఈ పేజీపై మార్పులు చేసేముందు, అవి ఇక్కడ ఉండతగినవేనా కాదా అని ఒకసారి ఆలోచించండి.\nమీ సౌలభ్యం కొరకు ఈ పేజీ యొక్క తొలగింపు మరియు తరలింపు చిట్టా ఇక్కడ ఇచ్చాము:",
+       "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దాన్ని తొలగించినట్టున్నారు.",
        "postedit-confirmation-created": "పేజీ సృష్టించబడినది.",
        "postedit-confirmation-restored": "పేజీని పునస్థాపించాం.",
        "postedit-confirmation-saved": "మీ మార్పు భద్రమయ్యింది.",
+       "postedit-confirmation-published": "మీ మార్పు ప్రచురితమయ్యింది.",
        "edit-already-exists": "కొత్త పేజీని సృష్టించలేకపోయాం.\nఅది ఇప్పటికే ఉంది.",
        "defaultmessagetext": "అప్రమేయ సందేశపు పాఠ్యం",
        "content-failed-to-parse": "$1 మోడల్ కొరకు $2 పాఠ్యాన్ని పార్స్ చెయ్యలేకపోయాం: $3",
        "content-model-css": "CSS",
        "content-json-empty-object": "ఖాళీ అంశం",
        "content-json-empty-array": "ఖాళీ అరే",
+       "duplicate-args-warning": "<strong>హెచ్చరిక:</strong> [[:$1]], \"$3\" పరామితికి ఒకటి కంటే ఎక్కువ విలువలు ఇచ్చి [[:$2]] ను పిలుస్తోంది. చిట్టచివరిగా ఇచ్చిన విలువను మాత్రమే వాడుతాం.",
+       "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:$2|పిలుపు|పిలుపులు}} $2 కంటే తక్కువ ఉండాలి,  ప్రస్తుతం {{PLURAL:$1|$1 పిలుపు ఉంది|$1  పిలుపులు ఉన్నాయి}}.",
        "expensive-parserfunction-category": "పార్సరు సందేశాలు అధికంగా ఉన్న పేజీలు",
        "post-expand-template-inclusion-warning": "<strong>హెచ్చరిక:</strong> మూస ఇముడ్పు సైజు చాలా పెద్దదిగా ఉంది.\nకొన్ని మూసలు ఇమడ్చబడవు.",
        "post-expand-template-argument-warning": "<strong>హెచ్చరిక:</strong> చాల పెద్ద సైజున్న మూస ఆర్గ్యుమెంటు, కనీసం ఒకటి, ఈ పేజీలో ఉంది.\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": "నోడ్-కౌంటును మించిన పేజీలు",
        "rev-showdeleted": "చూపించు",
        "revisiondelete": "కూర్పులను తొలగించు/తొలగింపును రద్దుచెయ్యి",
        "revdelete-nooldid-title": "తప్పుడు లక్ష్యపు కూర్పు",
-       "revdelete-nooldid-text": "à°\88 à°ªà°¨à°¿ à°\8f à°\95à±\82à°°à±\8dà°ªà±\81 à°²à±\87దా à°\95à±\82à°°à±\8dà°ªà±\81à°² à°®à±\80à°¦ à°\9aà±\86à°¯à±\8dయాలà±\8b à°®à±\80à°°à±\81 à°¸à±\82à°\9aà°¿à°\82à°\9aà°²à±\87à°¦à±\81, à°²à±\87దా à°®à±\80à°°à±\81 à°¸à±\82à°\9aà°¿à°\82à°\9aà°¿à°¨ à°\95à±\82à°°à±\8dà°ªà±\81 à°²à±\87à°¦à±\81, లేదా ప్రస్తుత కూర్పునే దాచాలని ప్రయత్నిస్తున్నారు.",
+       "revdelete-nooldid-text": "à°\88 à°ªà°¨à°¿ à°\8f à°\95à±\82à°°à±\8dà°ªà±\81 à°®à±\80à°¦ à°\9aà±\86à°¯à±\8dయాలà±\8b à°®à±\80à°°à±\81 à°¸à±\82à°\9aà°¿à°\82à°\9aà°²à±\87à°¦à±\81. à°²à±\87దా à°®à±\80à°°à±\81 à°¸à±\82à°\9aà°¿à°\82à°\9aà°¿à°¨ à°\95à±\82à°°à±\8dà°ªà±\81 à°\89నిà°\95à°¿à°²à±\8bà°¨à±\87 à°²à±\87à°¦à±\81. లేదా ప్రస్తుత కూర్పునే దాచాలని ప్రయత్నిస్తున్నారు.",
        "revdelete-no-file": "పేర్కొన్న ఫైలు ఉనికిలో లేదు.",
        "revdelete-show-file-confirm": "మీరు నిజంగానే \"<nowiki>$1</nowiki>\"  ఫైలు యొక్క $2 $3 నాటి తొలగించిన కూర్పుని చూడాలనుకుంటున్నారా?",
        "revdelete-show-file-submit": "అవును",
        "revdelete-text-text": "తొలగించిన కూర్పులు పేజీ చరిత్రలో కనిపిస్తూనే ఉంటాయి. కానీ వాటి విషయసంగ్రహంలోని భాగాలు అందరికీ కనిపించవు.",
        "revdelete-text-file": "తొలగించిన ఫైలు కూర్పులు పేజీ చరిత్రలో కనిపిస్తూనే ఉంటాయి. కానీ వాటి విషయసంగ్రహంలోని భాగాలు అందరికీ కనిపించవు.",
        "logdelete-text": "తొలగించిన ఘటనలు లాగ్‍లో కనిపిస్తూనే ఉంటాయి. కానీ వాటి విషయసంగ్రహంలోని భాగాలు అందరికీ కనిపించవు.",
-       "revdelete-text-others": "{{SITENAME}} లోని ఇతర నిర్వాహకులు దాచిన విషయాన్ని చూడగలరు. వేరే నిబంధనలేమీ విధించకపోతే, ఇదే ఇంటరుఫేసు ద్వారా వారు ఈ తొలగింపును రద్దు చేయనూ గలరు.",
+       "revdelete-text-others": "ఇతర నిర్వాహకులు దాచిన పాఠ్యాన్ని చూడగలరు. వేరే నిబంధనలేమీ విధించకపోతే, ఇదే ఇంటరుఫేసు ద్వారా వారు ఈ తొలగింపును రద్దు చేయనూ గలరు.",
        "revdelete-confirm": "మీరు దీన్ని చేయగోరుతున్నారనీ, దీని పర్యవసానాలు మీకు తెలుసుననీ, దీన్ని సంబంధిత [[{{MediaWiki:Policy-url}}|విధానం]] ప్రకారమే చేస్తున్నారనీ నిర్ధారించండి.",
        "revdelete-suppress-text": "అణచివేతను కింది సందర్భాలలో <strong>మాత్రమే</strong> వాడాలి:\n* బురదజల్లే ధోరణిలో ఉన్న సమాచారం\n* అనుచితమైన వ్యక్తిగత సమాచారం\n*<em>ఇంటి చిరునామాలు, టెలిఫోను నంబర్లు, జాతీయ ఐడీ నంబర్లు, వగైరాలు</em>",
        "revdelete-legend": "సందర్శక నిబంధనలు అమర్చు",
        "revdelete-unsuppress": "పునస్థాపిత కూర్పులపై నిబంధనలను తీసివెయ్యి",
        "revdelete-log": "కారణం:",
        "revdelete-submit": "ఎంచుకున్న {{PLURAL:$1|కూర్పుకు|కూర్పులకు}} ఆపాదించు",
-       "revdelete-success": "à°\95à±\82à°°à±\8dà°ªà±\81 à°\95నబడà±\87 à°µà°¿à°§à°¾à°¨à°¾à°¨à±\8dని à°\9cయపà±\8dà°°à°¦à°\82à°\97à°¾ à°¤à°¾à°\9cà°¾à°\95à°°à°¿à°\82à°\9aà°¾à°\82.",
+       "revdelete-success": "కూర్పు కనబడే విధానాన్ని తాజాకరించాం.",
        "revdelete-failure": "కూర్పు కనబడే పద్ధతిని తాజాపరచలేకపోయాం:\n$1",
-       "logdelete-success": "à°\98à°\9fà°¨ à°\95నబడà±\87 à°µà°¿à°§à°¾à°¨à°¾à°¨à±\8dని à°\9cయపà±\8dà°°à°¦à°\82à°\97à°¾ à°\85మరà±\8dà°\9aాం.",
+       "logdelete-success": "లాà°\97à±\8d à°\95నబడà±\87 à°µà°¿à°§à°¾à°¨à°¾à°¨à±\8dని à°¸à±\86à°\9fà±\8d à°\9aà±\87à°¸ాం.",
        "logdelete-failure": "'''చిట్టా కనబడే పద్ధతిని అమర్చలేకపోయాం:'''\n$1",
        "revdel-restore": "దృశ్యతని మార్చు",
        "pagehist": "పేజీ చరిత్ర",
        "mergehistory-go": "విలీనం చెయ్యదగ్గ దిద్దుబాట్లను చూపించు",
        "mergehistory-submit": "కూర్పులను విలీనం చెయ్యి",
        "mergehistory-empty": "ఏ కూర్పులనూ విలీనం చెయ్యలేము.",
-       "mergehistory-done": "$1 యొక్క $3 {{PLURAL:$3|కూర్పును|కూర్పులను}} [[:$2]] లోనికి విలీనం {{PLURAL:$3|చేసాం|చేసాం}}.",
+       "mergehistory-done": "$1 యొక్క $3 {{PLURAL:$3|కూర్పును|కూర్పులను}} [[:$2]] లోనికి విలీనం {{PLURAL:$3|చేసాం}}.",
        "mergehistory-fail": "చరితాన్ని విలీనం చెయ్యలేకపోయాం. పేజీని, సమయాలను సరిచూసుకోండి.",
        "mergehistory-fail-bad-timestamp": "కాలముద్ర చెల్లదు.",
        "mergehistory-fail-invalid-source": "మూలపు పేజీ సరైనది కాదు.",
        "mergehistory-fail-invalid-dest": "లక్ష్యిత పేజీ సరైనది కాదు.",
        "mergehistory-fail-permission": "చరిత్ర విలీనానికి సరిపడా అనుమతులు లేవు.",
        "mergehistory-fail-self-merge": "మూలం, లక్ష్యం పేజీలు ఒకటే.",
+       "mergehistory-fail-toobig": "తరలింపు పరిమితి ఐన $1 {{PLURAL:$1|కూర్పు|కూర్పుల}}కు మించిన సంఖ్యలో  తరలించాల్సి వస్తోంది కాబట్టి, చరిత్ర విలీనాన్ని చెయ్యలేకున్నాం.",
        "mergehistory-no-source": "మూలం పేజీ, $1 లేదు.",
        "mergehistory-no-destination": "గమ్యం పేజీ, $1 లేదు.",
        "mergehistory-invalid-source": "మూలం పేజీకి సరైన పేరు ఉండాలి.",
        "mergehistory-invalid-destination": "గమ్యం పేజీకి సరైన పేరు ఉండాలి.",
        "mergehistory-autocomment": "[[:$1]]ని [[:$2]] లోనికి విలీనం చేసారు",
        "mergehistory-comment": "[[:$1]]ని [[:$2]] లోనికి విలీనం చేసారు: $3",
-       "mergehistory-same-destination": "మూల మరియు గమ్యస్థాన పేజీలు ఒకటే కాకూడదు",
+       "mergehistory-same-destination": "మూల, గమ్యస్థాన పేజీలు ఒకటే కాకూడదు",
        "mergehistory-reason": "కారణం:",
        "mergelog": "విలీనాల చిట్టా",
        "revertmerge": "విలీనాన్ని రద్దుచెయ్యి",
        "mergelogpagetext": "ఒక పేజీ చరితాన్ని మరో పేజీ చరితం లోకి ఇటీవల చేసిన విలీనాల జాబితా ఇది.",
        "history-title": "\"$1\" యొక్క కూర్పుల చరిత్ర",
        "difference-title": "\"$1\" యొక్క కూర్పుల మధ్య తేడాలు",
-       "difference-title-multipage": "\"$1\" మరియు \"$2\" పేజీల మధ్య తేడా",
+       "difference-title-multipage": "\"$1\", \"$2\" పేజీల మధ్య తేడా",
        "difference-multipage": "(పేజీల మధ్య తేడా)",
        "lineno": "పంక్తి $1:",
        "compareselectedversions": "ఎంచుకున్న సంచికలను పోల్చిచూడు",
        "diff-multi-sameuser": "(ఇదే వాడుకరి యొక్క {{PLURAL:$1|ఒక మధ్యంతర కూర్పును|$1 మధ్యంతర కూర్పులను}} చూపించలేదు)",
        "diff-multi-otherusers": "({{PLURAL:$2|మరో వాడుకరి|$2 వాడుకరుల}} యొక్క {{PLURAL:$1|ఒక మధ్యంతర కూర్పును|$1 మధ్యంతర కూర్పులను}} చూపించలేదు)",
        "diff-multi-manyusers": "$2 కంటే ఎక్కువ ({{PLURAL:$2|ఒక వాడుకరి|వాడుకరుల}} యొక్క {{PLURAL:$1|ఒక మధ్యంతర కూర్పును|$1 మధ్యంతర కూర్పులను}} చూపించట్లేదు)",
+       "diff-paragraph-moved-tonew": "పేరాగ్రాఫును తరలించాం. కొత్త స్థానానికి వెళ్ళేందుకు నొక్కండి.",
+       "diff-paragraph-moved-toold": "పేరాగ్రాఫును తరలించాం. పాత స్థానానికి వెళ్ళేందుకు నొక్కండి.",
        "difference-missing-revision": "ఈ తేడా ($1) యొక్క {{PLURAL:$2|ఒక కూర్పు|$2 కూర్పులు}} {{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": "పేజిలోని పాఠం సరిపోలింది",
        "showingresultsinrange": "#<strong>$2</strong> నుండి  #<strong>$3</strong> వరకు ఉన్న ఫలితాల శ్రేణి నుండి {{PLURAL:$1|<strong>ఒక్క</strong> ఫలితం|<strong>$1</strong> ఫలితాల}} వరకు కింద చూపించాం.",
        "search-showingresults": "{{PLURAL:$4|<strong>$3</strong>{{PLURAL:$3|కి|లో}} <strong>$1</strong> ఫలితం|<strong>$3</strong>లో <strong>$1 - $2</strong> ఫలితాలు}}",
        "search-nonefound": "మీ ప్రశ్నకి సరిపోలిన ఫలితాలేమీ లేవు.",
+       "search-nonefound-thiswiki": "మీ అన్విష్టానికి (అన్వేషక పదం) సరిపడే ఫలితాలు ఈ సైటులో లేవు.",
        "powersearch-legend": "నిశితమైన అన్వేషణ",
        "powersearch-ns": "ఈ పేరుబరుల్లో వెతుకు:",
        "powersearch-togglelabel": "ఎంచుకోండి:",
        "stub-threshold-disabled": "అచేతనం",
        "recentchangesdays": "ఇటీవలి మార్పులు లో చూపించవలసిన రోజులు:",
        "recentchangesdays-max": "గరిష్ఠంగా $1 {{PLURAL:$1|రోజు|రోజులు}}",
-       "recentchangescount": "అప్రమేయంగా చూపించాల్సిన దిద్దుబాట్ల సంఖ్య:",
-       "prefs-help-recentchangescount": "à°\87ది à°\87à°\9fà±\80వలి à°®à°¾à°°à±\8dà°ªà±\81à°²à±\81, à°ªà±\87à°\9cà±\80 à°\9aà°°à°¿à°¤à±\8dà°°à°²à±\81, à°®à°°à°¿à°¯à±\81 à°\9aà°¿à°\9fà±\8dà°\9fాలà°\95à±\81 à°µà°°à±\8dతిసà±\8dà°¤à±\81à°\82ది.",
-       "prefs-help-watchlist-token2": "మీ వీక్షణజాబితా యొక్క జాలవడ్డింపుకు చెందిన రహస్య తాళమిది.\nఈ తాళం తెలిసిన ఎవరైనా మీ వీక్షణజాబితాను చదవగలుగుతారు. అందుచేత దీన్ని ఎవరికీ ఇవ్వకండి.\n[[Special:ResetTokens|దాన్ని మార్చాలంటే ఇక్కడ నొక్కండి]].",
+       "recentchangescount": "à°\87à°\9fà±\80వలి à°®à°¾à°°à±\8dà°ªà±\81లలà±\8b, à°ªà±\87à°\9cà±\80 à°\9aà°°à°¿à°¤à±\8dరలలà±\8b, à°\9aà°¿à°\9fà±\8dà°\9fాలలà±\8b à°\85à°ªà±\8dà°°à°®à±\87à°¯à°\82à°\97à°¾ à°\9aà±\82పిà°\82à°\9aాలà±\8dసిన à°¦à°¿à°¦à±\8dà°¦à±\81బాà°\9fà±\8dà°² à°¸à°\82à°\96à±\8dà°¯:",
+       "prefs-help-recentchangescount": "à°\97à°°à°¿à°·à±\8dà°  à°¸à°\82à°\96à±\8dà°¯: 1000",
+       "prefs-help-watchlist-token2": "మీ వీక్షణజాబితా యొక్క జాలవడ్డింపుకు చెందిన రహస్య తాళమిది.\nఈ తాళం తెలిసిన ఎవరైనా మీ వీక్షణజాబితాను చదవగలుగుతారు. అందుచేత దీన్ని ఎవరికీ ఇవ్వకండి.\nఅవసరమైతే [[Special:ResetTokens|దాన్ని మార్చుకోవచ్చు]].",
        "savedprefs": "మీ అభిరుచులను భద్రపరిచాం.",
        "savedrights": "{{GENDER:$1|$1}} వాడుకరి గుంపులు భద్రమయ్యాయి.",
        "timezonelegend": "కాల మండలం:",
        "timezoneregion-europe": "ఐరోపా",
        "timezoneregion-indian": "హిందూ మహాసముద్రం",
        "timezoneregion-pacific": "పసిఫిక్ మహాసముద్రం",
-       "allowemail": "ఇతర వాడుకరుల నుండి ఈ-మెయిళ్ళను రానివ్వు",
+       "allowemail": "ఇతర వాడుకరులను నాకు ఈ-మెయిలు చెయ్యనివ్వు",
+       "email-allow-new-users-label": "సరికొత్త వాడుకరుల నుండి ఈమెయిళ్ళను రానివ్వు",
+       "email-blacklist-label": "ఈ వాడుకరుల నుండి ఈమెయిళ్ళను రానీయకు:",
        "prefs-searchoptions": "వెతుకులాట",
        "prefs-namespaces": "పేరుబరులు",
        "default": "అప్రమేయం",
        "prefs-files": "ఫైళ్ళు",
        "prefs-custom-css": "ప్రత్యేక CSS",
        "prefs-custom-js": "ప్రత్యేక JS",
-       "prefs-common-config": "అన్ని రూపులలోనూ ఉన్న CSS/JS:",
+       "prefs-common-config": "అన్ని రూపులలోనూ ఉన్న CSS/JSON/JavaScript:",
        "prefs-reset-intro": "ఈ పేజీలో, మీ అభిరుచులను సైటు డిఫాల్టు విలువలకు మార్చుకోవచ్చు. మళ్ళీ వెనక్కి తీసుకుపోలేరు.",
        "prefs-emailconfirm-label": "ఈ-మెయిల్ నిర్ధారణ:",
        "youremail": "ఈమెయిలు:",
        "yourvariant": "విషయపు భాషా వైవిధ్యం:",
        "prefs-help-variant": "ఈ వికీ లోని విషయపు పేజీలను చూపించడానికి మీ అభిమత వైవిధ్యం లేదా ఆర్ధోగ్రఫీ.",
        "yournick": "కొత్త సంతకం:",
-       "prefs-help-signature": "చర్చా పేజీల లోని వ్యాఖ్యలకు \"<nowiki>~~~~</nowiki>\"తో సంతకం చేస్తే అది మీ సంతకం మరియు కాలముద్రగా మారుతుంది.",
+       "prefs-help-signature": "చర్చా పేజీల లోని వ్యాఖ్యలకు \"<nowiki>~~~~</nowiki>\"తో సంతకం చేస్తే అది మీ సంతకం, కాలముద్రగా మారుతుంది.",
        "badsig": "సంతకం చెల్లనిది.\nHTML ట్యాగులను ఒకసారి సరిచూసుకోండి.",
        "badsiglength": "మీ సంతకం చాలా పెద్దగా ఉంది.\nఇది తప్పనిసరిగా $1 {{PLURAL:$1|అక్షరం|అక్షరాల}} లోపులోనే ఉండాలి.",
        "yourgender": "మిమ్మల్ని మీరు ఎలా వర్ణించుకుంటారు?",
        "prefs-dateformat": "తేదీ ఆకృతి",
        "prefs-timeoffset": "సమయపు తేడా",
        "prefs-advancedediting": "సాధారణ ఎంపికలు",
+       "prefs-developertools": "డెవలపర్ల పనిముట్లు",
        "prefs-editor": "రచయిత",
        "prefs-preview": "మునుజూపు",
        "prefs-advancedrc": "ఉన్నత ఎంపికలు",
+       "prefs-opt-out": "మెరుగుదలల నుండి తప్పుకోండి",
        "prefs-advancedrendering": "ఉన్నత ఎంపికలు",
        "prefs-advancedsearchoptions": "ఉన్నత ఎంపికలు",
        "prefs-advancedwatchlist": "ఉన్నత ఎంపికలు",
        "editinguser": "{{GENDER:$1|user}} వాడుకరి హక్కులను మారుస్తున్నారు <strong>[[User:$1|$1]]</strong> $2",
        "viewinguserrights": "{{GENDER:$1|వాడుకరి}} <strong>[[User:$1|$1]]</strong> హక్కులను చూస్తున్నారు $2",
        "userrights-editusergroup": "{{GENDER:$1|వాడుకరి}} సమూహాలను మార్చండి",
-       "userrights-viewusergroup": "{{GENDER:$1|వాడà±\81à°\95à°°à°¿}} à°\97à±\81à°\82à°ªà±\81లనà±\81 à°\9aà±\82à°¡à°\82à°¡à°¿",
+       "userrights-viewusergroup": "{{GENDER:$1|వాడà±\81à°\95à°°à°¿}} à°\97à±\81à°\82à°ªà±\81లనà±\81 à°\9aà±\82à°¡à°¡à°\82",
        "saveusergroups": "{{GENDER:$1|వాడుకరి}} గుంపులను భద్రపరచు",
        "userrights-groupsmember": "సభ్యులు:",
        "userrights-groupsmember-auto": "సంభావిత సభ్యులు:",
        "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\" గుంపుకు ఇచ్చిన కాలం తీరిపోయే వ్యవధి గతకాలంలో ఉంది.",
+       "userrights-cannot-shorten-expiry": "\"$1\" గుంపులో సభ్యత్వాన్ని మీరు ముందుకు జరపజాలరు. ఈ గుంపును చేర్చే తీసివేసే అనుమతులు గల వాడుకరులు మాత్రమే ముగింపు కాలాలను ముందుకు జరపగలరు.",
        "userrights-conflict": "వాడుకరి హక్కుల మార్పులలో ఘర్షణ! మీ మార్పులను సమీక్షించి, నిర్ధారించండి.",
        "group": "గుంపు:",
        "group-user": "వాడుకరులు",
        "group-autoconfirmed": "ఆటోమాటిగ్గా నిర్ధారించబడిన వాడుకరులు",
        "group-bot": "బాట్‌లు",
        "group-sysop": "నిర్వాహకులు",
+       "group-interface-admin": "ఇంటర్‌ఫేసు నిర్వాహకులు",
        "group-bureaucrat": "అధికారులు",
-       "group-suppress": " పూర్తి తొలగింపుదారులు",
+       "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": "పూర్తి   తొలగింపు",
+       "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-deletelogentry": "లాగ్ ఎంట్రీలను తొలగించడం, తొలగింపులను రద్దు చెయ్యడం",
        "right-deleterevision": "పేజీల ప్రత్యేకించిన కూర్పులను తొలగించు, తొలగింపును నివారించు",
        "right-deletedhistory": "తొలగింపులను, వాటి పాఠ్యం లేకుండా, చరితంలో చూడు",
-       "right-deletedtext": "తొలగించిన పాఠ్యాన్ని మరియు తొలగించిన కూర్పుల మధ్య మార్పలని చూడగలగడం",
+       "right-deletedtext": "తొలగించిన పాఠ్యాన్ని, తొలగించిన కూర్పుల మధ్య మార్పులనూ చూడగలగడం",
        "right-browsearchive": "తొలగించిన పేజీల్లో వెతకడం",
        "right-undelete": "పేజీ తొలగింపును రద్దు చెయ్యి",
-       "right-suppressrevision": "నిరà±\8dవాహà°\95à±\81à°²à°\95à±\81 à°\95నబడà°\95à±\81à°\82à°¡à°¾ à°\89à°¨à±\8dà°¨ à°\95à±\82à°°à±\8dà°ªà±\81లనà±\81 à°¸à°®à±\80à°\95à±\8dà°·à°¿à°\82à°\9aà°¿ à°ªà±\81నసà±\8dథాపిà°\82à°\9aడం",
+       "right-suppressrevision": "à°ªà±\87à°\9cà±\80à°\95à°¿ à°\9aà±\86à°\82దిన à°¨à°¿à°°à±\8dà°£à±\80à°¤ à°\95à±\82à°°à±\8dà°ªà±\81లనà±\81 à°\8eవరà±\88నా à°µà°¾à°¡à±\81à°\95à°°à°¿à°\95à°¿ à°\95నబడà±\87లా à°\9aà±\86à°¯à±\8dయడà°\82, à°¦à°¾à°\9aà°¡à°\82, à°¬à°¯à°\9fà°ªà±\86à°\9fà±\8dà°\9fడం",
        "right-viewsuppressed": "ఏ వాడుకరి నుండైనా వీక్షణ సంస్కరణలు దాయబడ్డాయి",
        "right-suppressionlog": "గోప్యంగా ఉన్న లాగ్‌లను చూడడం",
        "right-block": "దిద్దుబాటు చెయ్యకుండా ఇతర వాడుకరులను నిరోధించగలగడం",
-       "right-blockemail": "à°\88à°®à±\86యిలà±\81 à°ªà°\82à°ªà°\95à±\81à°\82à°¡à°¾ à°¸à°­à±\8dà°¯à±\81ని నిరోధించు",
-       "right-hideuser": "à°ªà±\8dà°°à°\9cà°²à°\95à±\81 à°\95నబడà°\95à±\81à°\82à°¡à°¾ à°\9aà±\87సి, à°¸à°­à±\8dయనామానà±\8dని నిరోధించు",
+       "right-blockemail": "à°\88à°®à±\86యిలà±\81 à°ªà°\82à°ªà°\95à±\81à°\82à°¡à°¾ à°µà°¾à°¡à±\81à°\95à°°à°¿ని నిరోధించు",
+       "right-hideuser": "బయà°\9fà°¿à°\95à°¿ à°\95నబడà°\95à±\81à°\82à°¡à°¾ à°\9aà±\87సి, à°µà°¾à°¡à±\81à°\95à°°à°¿à°ªà±\87à°°à±\81à°¨à±\81 నిరోధించు",
        "right-ipblock-exempt": "ఐపీ నిరోధాలు, ఆటో నిరోధాలు, శ్రేణి నిరోధాలను తప్పించు",
        "right-unblockself": "స్వీయ అనిరోధం",
        "right-protect": "సంరక్షణ స్థాయిలను మార్చు, కాస్కేడ్-రక్షిత పేజీలలో దిద్దుబాటు చెయ్యి",
        "right-editcontentmodel": "పేజీ యొక్క కంటెంటు మోడలును సవరించు",
        "right-editinterface": "యూజరు ఇంటరుఫేసులో దిద్దుబాటు చెయ్యి",
        "right-editusercss": "ఇతర వాడుకరుల CSS ఫైళ్ళలో దిద్దుబాటు చెయ్యడం",
+       "right-edituserjson": "ఇతర వాడుకరుల JSON ఫైళ్ళను దిద్దడం",
        "right-edituserjs": "ఇతర వాడుకరుల JS ఫైళ్ళలో దిద్దుబాటు చెయ్యడం",
+       "right-editsitecss": "సైటువ్యాప్త CSS ను దిద్దడం",
+       "right-editsitejson": "సైటువ్యాప్త JSON ను దిద్దడం",
+       "right-editsitejs": "సైటువ్యాప్త JavaScript ను దిద్దడం",
        "right-editmyusercss": "మీ స్వంత వాడుకరి CSS ఫైళ్ళను సరిదిద్దండి",
+       "right-editmyuserjson": "మీ స్వంత JSON ను దిద్దడం",
        "right-editmyuserjs": "మీ స్వంత JavaScript దస్త్రాలను మార్చండి",
-       "right-viewmywatchlist": "à°®à±\80 à°¸à±\8dà°µà°\82à°¤ à°µà±\80à°\95à±\8dà°·à°£à°\9cాబితానà±\81 à°\9aà±\82à°¡à°\82à°¡à°¿",
-       "right-editmywatchlist": "à°®à±\80 à°¸à±\8dà°µà°\82à°¤ à°µà±\80à°\95à±\8dà°·à°£à°\9cాబితానà±\81 à°®à°¾à°°à±\8dà°\9aà±\81à°\95à±\8bà°\82à°¡à°¿. ఈ హక్కు లేకపోయినా, కొన్ని చర్యల ద్వారా పేజీలు జాబితాకు చేరుతాయని గమనించండి.",
+       "right-viewmywatchlist": "à°®à±\80 à°¸à±\8dà°µà°\82à°¤ à°µà±\80à°\95à±\8dà°·à°£à°\9cాబితానà±\81 à°\9aà±\82à°¡à°¡à°\82",
+       "right-editmywatchlist": "à°®à±\80 à°¸à±\8dà°µà°\82à°¤ à°µà±\80à°\95à±\8dà°·à°£à°\9cాబితానà±\81 à°®à°¾à°°à±\8dà°\9aà±\81à°\95à±\8bవడà°\82. ఈ హక్కు లేకపోయినా, కొన్ని చర్యల ద్వారా పేజీలు జాబితాకు చేరుతాయని గమనించండి.",
        "right-viewmyprivateinfo": "మీ స్వంత గోపనీయ డేటాను చూడండి (ఉదా: ఈమెయిలు చిరునామా, అసలు పేరు)",
-       "right-editmyprivateinfo": "à°®à±\80 à°¸à±\8dà°µà°\82à°¤ à°\97à±\8bపనà±\80à°¯ à°¡à±\87à°\9fానà±\81 à°®à°¾à°°à±\8dà°\9aà±\81à°\95à±\8bà°\82à°¡à°¿ (ఉదా: ఈమెయిలు చిరునామా, అసలు పేరు)",
-       "right-editmyoptions": "à°®à±\80 à°¸à±\8dà°µà°\82à°¤ à°\85à°­à°¿à°°à±\81à°\9aà±\81లనà±\81 à°®à°¾à°°à±\8dà°\9aà±\81à°\95à±\8bà°\82à°¡à°¿",
+       "right-editmyprivateinfo": "à°®à±\80 à°¸à±\8dà°µà°\82à°¤ à°\97à±\8bపనà±\80à°¯ à°¡à±\87à°\9fానà±\81 à°®à°¾à°°à±\8dà°\9aà±\81à°\95à±\8bవడà°\82 (ఉదా: ఈమెయిలు చిరునామా, అసలు పేరు)",
+       "right-editmyoptions": "à°®à±\80 à°¸à±\8dà°µà°\82à°¤ à°\85à°­à°¿à°°à±\81à°\9aà±\81లనà±\81 à°®à°¾à°°à±\8dà°\9aà±\81à°\95à±\8bవడà°\82",
        "right-rollback": "ఒకానొక పేజీలో చివరి దిద్దుబాటు చేసిన వాడుకరి చేసిన దిద్దుబాట్లను రద్దుచేయడం",
        "right-markbotedits": "వెనక్కి తెచ్చిన దిద్దుబాట్లను బాట్ దిద్దుబాట్లుగా గుర్తించు",
        "right-noratelimit": "రేటు పరిమితులు ప్రభావం చూపవు",
        "right-siteadmin": "డేటాబేసును లాక్, అన్‌లాక్ చెయ్యి",
        "right-override-export-depth": "5 లింకుల లోతు వరకు ఉన్న పేజీలతో సహా, పేజీలను ఎగుమతి చెయ్యి",
        "right-sendemail": "ఇతర వాడుకరులకు ఈ-మెయిలు పంపించడం",
-       "right-managechangetags": "డేటాబేసులో [[Special:Tags|ట్యాగుల]]ను సృష్టించడం, తొలగించడం",
+       "right-managechangetags": "[[Special:Tags|ట్యాగుల]]ను సృష్టించడం, (అ)చేతనం చెయ్యడం",
        "right-applychangetags": "తన మార్పులతో [[Special:Tags|ట్యాగుల]]ను ఆపాదించడం",
        "right-changetags": "విడి కూర్పులకు, చిట్టా పద్దులకు ఏవైనా [[Special:Tags|ట్యాగుల]]ను చేర్చడం, తొలగించడం",
-       "right-deletechangetags": "[[ప్రత్యేక:Tags|ట్యాగులను]] డేటాబేసు నుండి తొలగించు",
+       "right-deletechangetags": "[[Special:Tags|ట్యాగులను]] డేటాబేసు నుండి తొలగించు",
        "grant-generic": "\"$1\" హక్కుల కట్ట",
+       "grant-group-page-interaction": "పేజీలతో సంప్రదించడం",
+       "grant-group-file-interaction": "మీడియాతో సంప్రదించడం",
+       "grant-group-watchlist-interaction": "మీ వీక్షణ జాబితాతో సంప్రదించడం",
        "grant-group-email": "ఈమెయిలు పంపించడం",
+       "grant-group-high-volume": "అధిక మొత్తంలో పనులను చెయ్యడం",
+       "grant-group-customization": "కస్టమైజేషన్, అభిరుచులు",
        "grant-group-administration": "నిర్వాహక చర్యలు చేపట్టడం",
        "grant-group-private-information": "మీ గోపనీయ డేటాను చూడడం",
+       "grant-group-other": "ఇతరత్రా కార్యకలాపం",
+       "grant-blockusers": "వాడుకరుల నిరోధం, విడుదల",
        "grant-createaccount": "ఖాతాల సృష్టి",
        "grant-createeditmovepage": "పేజీల సృష్టి, దిద్దుబాటు, తరలింపు",
        "grant-delete": "పేజీలు, కూర్పులు, లాగ్ ఎంట్రీల తొలగింపు",
-       "grant-editinterface": "MediaWiki à°ªà±\87à°°à±\81బరిలà±\8bà°¨à±\81, à°µà°¾à°¡à±\81à°\95à°°à°¿ CSS/JavaScript à°\95à±\82 à°¦à°¿à°¦à±\8dà°¦à±\81బాà°\9fà±\8dà°²à±\81.",
-       "grant-editmycssjs": "వాడà±\81à°\95à°°à°¿ CSS/JavaScript à°¦à°¿à°¦à±\8dà°¦à±\81బాà°\9fà±\81",
+       "grant-editinterface": "MediaWiki à°ªà±\87à°°à±\81బరిలà±\8bà°¨à±\81, à°¸à±\88à°\9fà±\81à°µà±\8dయాపà±\8dà°¤/వాడà±\81à°\95à°°à°¿ JSON à°\95à±\82 à°¦à°¿à°¦à±\8dà°¦à±\81బాà°\9fà±\8dà°²à±\81 à°\9aà±\86à°¯à±\8dయడà°\82",
+       "grant-editmycssjs": "à°®à±\80 à°µà°¾à°¡à±\81à°\95à°°à°¿ CSS/JSON/JavaScript à°¦à°¿à°¦à±\8dదడà°\82",
        "grant-editmyoptions": "మీ అభిరుచుల దిద్దుబాటు",
        "grant-editmywatchlist": "మీ వీక్షణజాబితా దిద్దుబాటు",
+       "grant-editsiteconfig": "సైటువ్యాప్త/వాడుకరి CSS/JS దిద్దడం",
        "grant-editpage": "ఉనికిలో ఉన్న పేజీల దిద్దుబాటు",
        "grant-editprotected": "సంరక్షిత పేజీల్లో దిద్దుబాట్లు",
        "grant-highvolume": "అధిక మొత్తంలో దిద్దుబాట్లు",
        "grant-basic": "ప్రాథమిక హక్కులు",
        "grant-viewdeleted": "తొలగించిన దస్త్రాలు, పేజీలను చూడడం",
        "grant-viewmywatchlist": "మీ వీక్షణజాబితాను చూడడం",
+       "grant-viewrestrictedlogs": "నిరోధిత చిట్టా పద్దులను చూపించు",
        "newuserlogpage": "కొత్త వాడుకరుల చిట్టా",
        "newuserlogpagetext": "ఇది వాడుకరి నమోదుల చిట్టా.",
        "rightslog": "వాడుకరుల హక్కుల మార్పుల చిట్టా",
        "action-createtalk": "ఈ చర్చాపేజీని సృష్టించే",
        "action-createaccount": "ఈ వాడుకరి ఖాతాని సృష్టించే",
        "action-autocreateaccount": "ఈ బయటి వాడుకరి ఖాతాను ఆటోమాటిగ్గా సృష్టించే",
-       "action-history": "à°\88 à°ªà±\87à°\9cà±\80 à°¯à±\8aà°\95à±\8dà°\95 à°\9aà°°à°¿à°¤à±\8dరని à°\9aà±\82à°¡à°\82à°¡à°¿",
+       "action-history": "à°\88 à°ªà±\87à°\9cà±\80 à°¯à±\8aà°\95à±\8dà°\95 à°\9aà°°à°¿à°¤à±\8dరని à°\9aà±\82à°¸à±\87",
        "action-minoredit": "ఈ మార్పుని చిన్నదిగా గుర్తించే",
        "action-move": "ఈ పేజీని తరలించే",
        "action-move-subpages": "ఈ పేజీని, దీని ఉపపేజీలనూ తరలించే",
        "action-sendemail": "ఈమెయిళ్ళు పంపించే",
        "action-editmyoptions": "మీ అభిరుచులను మార్చుకునే",
        "action-editmywatchlist": "మీ వీక్షణ జాబితాను సరిదిద్దండి",
-       "action-viewmywatchlist": "à°®à±\80 à°µà±\80à°\95à±\8dà°·à°£ à°\9cాబితానà±\81 à°\9aà±\82à°¡à°\82à°¡à°¿",
-       "action-viewmyprivateinfo": "à°®à±\80 à°\97à±\8bపనà±\80à°¯ à°¸à°®à°¾à°\9aారానà±\8dని à°\9aà±\82à°¡à°\82à°¡à°¿",
+       "action-viewmywatchlist": "à°®à±\80 à°µà±\80à°\95à±\8dà°·à°£ à°\9cాబితానà±\81 à°\9aà±\82à°¸à±\87",
+       "action-viewmyprivateinfo": "à°®à±\80 à°\97à±\8bపనà±\80à°¯ à°¸à°®à°¾à°\9aారానà±\8dని à°\9aà±\82à°¸à±\87",
        "action-editmyprivateinfo": "మీ గోపనీయ సమాచారాన్ని సరిదిద్దండి",
        "action-editcontentmodel": "పేజీ యొక్క కంటెంటు మోడలును సవరించే",
        "action-managechangetags": "ట్యాగులను చేర్చే, (అ)చేతనం చేసే",
        "recentchanges-legend": "ఇటీవలి మార్పుల ఎంపికలు",
        "recentchanges-summary": "వికీలో ఇటీవలే జరిగిన మార్పులను ఈ పేజీలో గమనించవచ్చు.",
        "recentchanges-noresult": "ఈ నియమాలకు సరిపోలే మార్పులు ఇచ్చిన కాలంలో లేవు.",
+       "recentchanges-timeout": "వెతుకులాట సమయం అయిపోయింది. వేరే వెతుకులాట పరామితులతో తిరిగి ప్రయత్నించండి.",
+       "recentchanges-network": "సాంకేతిక లోపం కారణంగా, ఫలితాలనేమీ తేలేకపోయాం. పేజీని రిఫ్రెష్ చేసి చూడండి.",
+       "recentchanges-notargetpage": "పైన ఒక పేజీ పేరు ఏదైనా ఇచ్చి, ఆ పేజీకి సంబంధించిన మార్పులను చూడండి.",
        "recentchanges-feed-description": "ఈ ఫీడు ద్వారా వికీలో జరుగుతున్న మార్పుల గురించి ఎప్పటికప్పుడు సమాచారాన్ని పొందండి.",
        "recentchanges-label-newpage": "ఈ మార్పు కొత్త పేజీని సృష్టించింది",
        "recentchanges-label-minor": "ఇది ఒక చిన్న మార్పు",
        "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-empty-filter": "చేతనంగా ఉన్న వడపోతకాలేమీ లేవు. మార్పుచేర్పు లన్నిటినీ చూపించాం.",
        "rcfilters-filterlist-title": "వడపోతలు",
        "rcfilters-filterlist-whatsthis": "ఇవి ఎలా పనిచేస్తాయి?",
-       "rcfilters-filterlist-feedbacklink": "ఈ (కొత్త) వడపోత పరికరాలు ఎలా ఉన్నాయో మాకు చెప్పండి",
+       "rcfilters-filterlist-feedbacklink": "ఈ వడపోత పరికరాలు ఎలా ఉన్నాయో మాకు చెప్పండి",
        "rcfilters-highlightbutton-title": "ఫలితాలను హైలైటు చెయ్యి",
        "rcfilters-highlightmenu-title": "ఒక రంగును ఎంచుకోండి",
        "rcfilters-highlightmenu-help": "ఈ లక్షణాన్ని హైలైటు చేసేందుకు ఓ రంగును ఎంచుకోండి",
        "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-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-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-filtergroup-significance": "ప్రాముఖ్యం",
        "rcfilters-filter-minor-label": "చిన్న మార్పులు",
        "rcfilters-filter-minor-description": "రచయిత చిన్నవిగా గుర్తు పెట్టిన దిద్దుబాట్లు.",
        "minoreditletter": "చి",
        "newpageletter": "కొ",
        "boteditletter": "బా",
-       "number_of_watching_users_pageview": "[à°µà±\80à°\95à±\8dà°·à°¿à°¸à±\8dà°¤à±\81à°¨à±\8dà°¨ à°¸à°­à±\8dà°¯ులు: {{PLURAL:$1|ఒక్కరు|$1}}]",
+       "number_of_watching_users_pageview": "[à°µà±\80à°\95à±\8dà°·à°¿à°¸à±\8dà°¤à±\81à°¨à±\8dà°¨ à°µà°¾à°¡à±\81à°\95à°°ులు: {{PLURAL:$1|ఒక్కరు|$1}}]",
        "rc-change-size-new": "మార్పు తర్వాత $1 {{PLURAL:$1|బైటు|బైట్లు}}",
        "newsectionsummary": "/* $1 */ కొత్త విభాగం",
        "rc-enhanced-expand": "వివరాలను చూపించు",
        "upload_directory_missing": "ఎక్కింపు డైరెక్టరీ ($1) కనబడలేదు. పైగా వెబ్ సర్వర్ దాన్ని సృష్టించలేకపోయింది.",
        "upload_directory_read_only": "ఎక్కింపు డైరెక్టరీ ($1), వెబ్‌సర్వరు రాసేందుకు అనుకూలంగా లేదు.",
        "uploaderror": "ఎక్కింపు లోపం",
-       "upload-recreate-warning": "<strong>హెచ్చరిక: ఆ పేరుతో ఉన్న దస్త్రాన్ని తరలించడం లేదా తొలగించడం జరిగింది.</strong>\n\nమీ సౌకర్యం కోసం ఈ పేజీ యొక్క తొలగింపు మరియు తరలింపు చిట్టాని ఇక్కడ ఇస్తున్నాం:",
-       "uploadtext": "దస్త్రాలను ఎక్కించడానికి ఈ కింది ఫారాన్ని ఉపయోగించండి.\nగతంలో ఎక్కించిన దస్త్రాలను చూడడానికి లేదా వెతకడానికి [[Special:FileList|ఎక్కించిన దస్త్రాల యొక్క జాబితా]]కు వెళ్ళండి, (పునః)ఎక్కింపులు [[Special:Log/upload|ఎక్కింపుల చిట్టా]] లోనూ తొలగింపులు [[Special:Log/delete|తొలగింపుల చిట్టా]] లోనూ కూడా నమోదవుతాయి.\n\nఒక దస్త్రాన్ని ఏదైనా పుటలో చేర్చడానికి, కింద చూపిన వాటిలో ఏదేనీ విధంగా లింకుని వాడండి:\n* దస్త్రపు పూర్తి కూర్పుని వాడడానికి '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:File.jpg]]</nowiki></code>'''\n* ఎడమ వైపు మార్జినులో 200 పిక్సెళ్ళ వెడల్పుగల బొమ్మ  మరియు 'ప్రత్యామ్నాయ పాఠ్యం' అన్న వివరణతో గల పెట్టె కోసం  '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:File.png|200px|thumb|left|ప్రత్యామ్నాయ పాఠ్యం]]</nowiki></code>'''\n* దస్త్రాన్ని చూపించకుండా నేరుగా లింకు ఇవ్వడానికి '''<code><nowiki>[[</nowiki>{{ns:media}}<nowiki>:File.ogg]]</nowiki></code>'''",
+       "upload-recreate-warning": "<strong>హెచ్చరిక: ఆ పేరుతో ఉన్న దస్త్రాన్ని తరలించడం లేదా తొలగించడం జరిగింది.</strong>\n\nమీ సౌకర్యం కోసం ఈ పేజీకి చెందిన తొలగింపు, తరలింపు చిట్టాలను ఇక్కడ ఇస్తున్నాం:",
+       "uploadtext": "దస్త్రాలను ఎక్కించడానికి ఈ కింది ఫారాన్ని ఉపయోగించండి.\nగతంలో ఎక్కించిన దస్త్రాలను చూడడానికి లేదా వెతకడానికి [[Special:FileList|ఎక్కించిన దస్త్రాల యొక్క జాబితా]]కు వెళ్ళండి, (పునః)ఎక్కింపులు [[Special:Log/upload|ఎక్కింపుల చిట్టా]] లోనూ తొలగింపులు [[Special:Log/delete|తొలగింపుల చిట్టా]] లోనూ కూడా నమోదవుతాయి.\n\nఒక దస్త్రాన్ని ఏదైనా పుటలో చేర్చడానికి, కింద చూపిన వాటిలో ఏదేనీ విధంగా లింకుని వాడండి:\n* దస్త్రపు పూర్తి కూర్పుని వాడడానికి '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:File.jpg]]</nowiki></code>'''\n* ఎడమ వైపు మార్జినులో 200 పిక్సెళ్ళ వెడల్పుగల బొమ్మ, 'ప్రత్యామ్నాయ పాఠ్యం' అన్న వివరణతో గల పెట్టె కోసం '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:File.png|200px|thumb|left|ప్రత్యామ్నాయ పాఠ్యం]]</nowiki></code>'''\n* దస్త్రాన్ని చూపించకుండా నేరుగా లింకు ఇవ్వడానికి '''<code><nowiki>[[</nowiki>{{ns:media}}<nowiki>:File.ogg]]</nowiki></code>'''",
        "upload-permitted": "అనుమతించబడిన ఫైలు {{PLURAL:$2|రకం|రకాలు}}: $1.",
        "upload-preferred": "అనుమతించే ఫైలు {{PLURAL:$2|రకం|రకాలు}}: $1.",
        "upload-prohibited": "నిషేధించబడిన ఫైలు {{PLURAL:$2|రకం|రకాలు}}: $1.",
        "badfilename": "ఫైలు పేరు \"$1\"కి మార్చబడినది.",
        "filetype-mime-mismatch": "దస్త్రపు ఎక్స్టెన్షను \".$1\", ఆ దస్త్రం యొక్క MIME రకం ($2) తో సరిపోలలేదు.",
        "filetype-badmime": "\"$1\" MIME రకం ఉన్న ఫైళ్ళను ఎగుమతికి అనుమతించం.",
-       "filetype-bad-ie-mime": "à°\88 à°«à±\88à°²à±\81ని à°\8eà°\97à±\81మతి à°\9aà±\87యలà±\87à°°à±\81. à°\8eà°\82à°¦à±\81à°\95à°\82à°\9fà±\87 à°\87à°\82à°\9fà°°à±\8dà°¨à±\86à°\9fà±\8d à°\8eà°\95à±\8dà°¸à±\8dâ\80\8cà°ªà±\8dà°²à±\8bà°°à°°à±\8d à°¦à±\80à°¨à±\8dని \"$1\" à°\97à°¾ à°\9aà±\82పిసà±\8dà°¤à±\81à°\82ది. à°\87ది à°\85à°¨à±\81మతి à°²à±\87ని à°®à°°à°¿à°¯à±\81 à°ªà±\8dరమాదà°\95à°°à°®à±\88à°¨ à°«à±\88à°²à±\81 à°°à°\95à°\82.",
+       "filetype-bad-ie-mime": "à°\88 à°«à±\88à°²à±\81ని à°\8eà°\97à±\81మతి à°\9aà±\87యలà±\87à°°à±\81. à°\8eà°\82à°¦à±\81à°\95à°\82à°\9fà±\87 à°\87à°\82à°\9fà°°à±\8dà°¨à±\86à°\9fà±\8d à°\8eà°\95à±\8dà°¸à±\8dâ\80\8cà°ªà±\8dà°²à±\8bà°°à°°à±\8d à°¦à±\80à°¨à±\8dని \"$1\" à°\97à°¾ à°\9aà±\82పిసà±\8dà°¤à±\81à°\82ది. à°\88 à°«à±\88à°²à±\81 à°°à°\95à°\82 à°\85à°¨à±\81మతి à°²à±\87నిది, à°ªà±\8dరమాదà°\95à°°à°®à±\88నదà±\80à°¨à±\81.",
        "filetype-unwanted-type": "<strong>\".$1\"</strong> అనేది అవాంఛిత ఫైలు రకం.\n$2 {{PLURAL:$3|అనేది వాడదగ్గ ఫైలు రకం|అనేవి వాడదగ్గ ఫైలు రకాలు}}.",
        "filetype-banned-type": "'''\".$1\"''' {{PLURAL:$4|అనేది అనుమతించబడిన ఫైలు రకం కాదు|అనేవి అనుమతించబడిన ఫైలు రకాలు కాదు}}.\nఅనుమతించబడిన {{PLURAL:$3|ఫైలు రకం|ఫైలు రకాలు}} $2.",
        "filetype-missing": "ఫైలుకి ఎక్స్టెన్షను (\".jpg\" లాంటిది) లేదు.",
        "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": "పూర్తయ్యింది",
        "uploadstash-badtoken": "ఆ చర్య విఫలమైంది. బహుశా మీ ఎడిటింగు అనుమతులకు కాలం చెల్లిందేమో. మళ్ళీ ప్రయత్నించండి.",
        "uploadstash-errclear": "ఫైళ్ళ తీసివేత విఫలమైంది.",
        "uploadstash-refresh": "దస్త్రాల జాబిజాను తాజాకరించు",
+       "uploadstash-thumbnail": "నఖచిత్రం చూడండి",
+       "uploadstash-file-too-large": "$1 బైట్ల కంటే పెద్ద ఫైలును భద్రపరచలేం.",
+       "uploadstash-not-logged-in": "వాడుకరి ఎవరూ లాగినై లేరు. దస్త్రాలు వాడుకరులకు చెంది ఉండాలి",
+       "uploadstash-wrong-owner": "ఈ దస్త్రం ($1) ప్రస్తుత వాడుకరికి చెందినది కాదు.",
+       "uploadstash-no-such-key": "అలాంటి కీ ($1) లేనే లేదు. కాబట్టి తీసెయ్యలేం.",
+       "uploadstash-zero-length": "దస్త్రం పొడవు సున్నా.",
        "invalid-chunk-offset": "చెల్లని చంక్ ఆఫ్‍సెట్",
        "img-auth-accessdenied": "అనుమతిని నిరాకరించారు",
        "img-auth-nopathinfo": "PATH_INFO లేదు.\nమీ సర్వరు ఈ సమాచారాన్ని పంపించేందుకు అనువుగా అమర్చి లేదు.\nఅది CGI ఆధారితమై ఉండొచ్చు. అంచేత img_auth కు అనుకూలంగా లేదు.\nhttps://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization చూడండి.",
        "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": "ఇచ్చిన URL కు వెళ్ళలేకపోయాం. URL సరైనదేనని, సైటు పనిచేస్తూనే ఉన్నదనీ నిర్ధారించుకోండి.",
        "upload-curl-error28": "ఎక్కింపు కాలాతీతం",
        "listfiles_size": "పరిమాణం",
        "listfiles_description": "వివరణ",
        "listfiles_count": "కూర్పులు",
-       "listfiles-show-all": "à°¬à±\8aà°®à±\8dమల à°ªà°¾à°¤ à°\95à±\82à°°à±\8dà°ªà±\81లనà±\81 à°\95à°²à±\81à°ªà±\81",
+       "listfiles-show-all": "à°¬à±\8aà°®à±\8dమల à°ªà°¾à°¤ à°\95à±\82à°°à±\8dà°ªà±\81లతà±\8b à°¸à°¹à°¾",
        "listfiles-latestversion": "ప్రస్తుత కూర్పు",
        "listfiles-latestversion-yes": "అవును",
        "listfiles-latestversion-no": "కాదు",
        "filerevert-submit": "వెనక్కు తీసుకువెళ్ళు",
        "filerevert-success": "<strong>[[Media:$1|$1]]</strong> ను  [$4 $2 $3 నాటి కూర్పు]కు తీసుకువెళ్ళాం.",
        "filerevert-badversion": "మీరిచ్చిన టైముస్టాంపుతో ఈ ఫైలుకు స్థానిక కూర్పేమీ లేదు.",
+       "filerevert-identical": "దస్రపు ప్రస్తుత కూర్పు, ఎంచుకున్నదీ రెండూ సరిగ్గా ఒకేలా ఉన్నాయి.",
        "filedelete": "$1ని తొలగించు",
        "filedelete-legend": "ఫైలుని తొలగించు",
        "filedelete-intro": "మీరు <strong>[[Media:$1|$1]]</strong> ఫైలును దాని చరిత్రతో సహా తొలగించబోతున్నారు.",
        "filedelete-maintenance": "నిర్వహణ సందర్భంగా ఫైళ్ళ తొలగింపు, పునస్థాపనలను తాత్కాలికంగా అచేతనం చేసాం.",
        "filedelete-maintenance-title": "దస్త్రాన్ని తొలగించలేకపోయాం",
        "mimesearch": "బొమ్మల మెటాడేటా(MIME)ను వెతకండి",
-       "mimesearch-summary": "ఈ పేజీ MIME-రకాన్ననుసరించి ఫైళ్ళను వడగట్టేందుకు దోహదం చేస్తుంది. Input: contenttype/subtype, ఉదా. <code>బొమ్మ/jpeg</code>.",
+       "mimesearch-summary": "ఈ పేజీ MIME-రకాన్ననుసరించి ఫైళ్ళను వడగట్టేందుకు దోహదం చేస్తుంది. Input: contenttype/subtype or contenttype/* ఉదా. <code>బొమ్మ/jpeg</code>.",
        "mimetype": "MIME రకం:",
        "download": "డౌన్‌లోడు",
        "unwatchedpages": "వీక్షణలో లేని పేజీలు",
        "pageswithprop-legend": "ఒక పేజీ లక్షణం కలిగిన పేజీలు",
        "pageswithprop-text": "ఫలానా పేజీ లక్షణం కలిగిన పేజీల జాబితాను ఈ పేజీలో చూడవచ్చు.",
        "pageswithprop-prop": "లక్షణం పేరు:",
+       "pageswithprop-reverse": "విలోమంగా పేర్చు",
        "pageswithprop-submit": "వెళ్ళు",
        "pageswithprop-prophidden-long": "long text లక్షణం విలువ దాచబడింది ($1)",
        "pageswithprop-prophidden-binary": "binary లక్షణం విలువ దాచబడింది ($1)",
        "doubleredirects": "జంట దారిమార్పులు",
-       "doubleredirectstext": "ఇతర దారిమార్పు పుటలకి తీసుకెళ్ళే దారిమార్పులని ఈ పుట చూపిస్తుంది.\nప్రతీ వరుసలో మొదటి మరియు రెండవ దారిమార్పులకు లంకెలు, ఆలానే రెండవ దారిమార్పు పుట యొక్క లక్ష్యం ఉన్నాయి. సాధారణంగా ఈ రెండవ దారిమార్పు యొక్క లక్ష్యమే \"అసలైనది\", అదే మొదటి దారిమార్పు యొక్క లక్ష్యంగా ఉండాలి.\n<del>కొట్టివేయబడిన</del> పద్దులు పరిష్కరించబడ్డవి.",
-       "double-redirect-fixed-move": "[[$1]]ని తరలించారు, అది ప్రస్తుతం [[$2]]కి దారిమార్పు.",
-       "double-redirect-fixed-maintenance": "[[$1]] à°\95à±\81 à°\9cమిలి à°¦à°¾à°°à°¿à°®à°¾à°°à±\8dà°ªà±\81à°¨à±\81 [[$2]] à°\95à±\81 à°\85à°ªà±\8dà°°à°®à±\87à°¯ంగా సరిచేస్తున్నాం.",
+       "doubleredirectstext": "ఇతర దారిమార్పు పుటలకి తీసుకెళ్ళే దారిమార్పులని ఈ పుట చూపిస్తుంది.\nప్రతీ వరుసలో మొదటి, రెండవ దారిమార్పులకు లంకెలు, ఆలానే రెండవ దారిమార్పు పుట యొక్క లక్ష్యం ఉన్నాయి. సాధారణంగా ఈ రెండవ దారిమార్పు యొక్క లక్ష్యమే \"అసలైనది\", అదే మొదటి దారిమార్పు యొక్క లక్ష్యంగా ఉండాలి.\n<del>కొట్టివేయబడిన</del> పద్దులు పరిష్కరించబడ్డవి.",
+       "double-redirect-fixed-move": "[[$1]]ని తరలించారు.\nదాన్ని ఆటోమేటిగ్గా తాజాకరించాం. ప్రస్తుతం అది [[$2]]కి దారిమార్పు చేస్తోంది.",
+       "double-redirect-fixed-maintenance": "[[$1]] à°¨à±\81à°\82à°¡à°¿ [[$2]] à°\95à±\81 à°\9cమిలి à°¦à°¾à°°à°¿à°®à°¾à°°à±\8dà°ªà±\81à°¨à±\81 à°\86à°\9fà±\8bమాà°\9fà°¿à°\97à±\8dà°\97à°¾ à°¨à°¿à°°à±\8dవహణలà±\8b à°­à°¾à°\97ంగా సరిచేస్తున్నాం.",
        "double-redirect-fixer": "దారిమార్పు సరిద్దువారు",
        "brokenredirects": "తెగిపోయిన దారిమార్పులు",
        "brokenredirectstext": "కింది దారిమార్పులు ఉనికిలోనే లేని పేజీలకు వెళ్తున్నాయి:",
        "deadendpages": "అగాధ (డెడ్ఎండ్) పేజీలు",
        "deadendpagestext": "కింది పేజీల నుండి ఈ వికీ లోని ఏ ఇతర పేజీకీ లింకులు లేవు.",
        "protectedpages": "సంరక్షిత పేజీలు",
+       "protectedpages-filters": "వడపోతలు:",
        "protectedpages-indef": "అనంత సంరక్షణ మాత్రమే",
        "protectedpages-summary": "ప్రస్తుతం సంరక్షణలో ఉన్న పేజీల జాబితాను ఈ పేజీ చూపిస్తుంది. అసలు సృష్టించకుండా సంరక్షించబడిన పేజీశీర్షికల కోసం [[{{#special:ProtectedTitles}}|{{int:protectedtitles}}]] చూడండి.",
        "protectedpages-cascade": "కాస్కేడింగు రక్షణలు మాత్రమే",
        "protectedpages-performer": "రక్షించబడే వాడుకరి",
        "protectedpages-params": "సంరక్షణ పరామితులు",
        "protectedpages-reason": "కారణం",
+       "protectedpages-submit": "పేజీలను చూపించు",
        "protectedpages-unknown-timestamp": "తెలియని",
        "protectedpages-unknown-performer": "తెలియని వాడుకరి",
        "protectedtitles": "సంరక్షిత శీర్షికలు",
        "protectedtitles-summary": "యీ పేజీలో ప్రస్తుతం సృష్టించకుండా నిరోధించబడ్డ శీర్ణికలన్నీ పొందుపరచబడ్డాయి. సంరక్షించబడ్ద పేజీలకోసం యిక్కడ చూడండి: [[{{#special:ProtectedPages}}|{{int:protectedpages}}]].",
        "protectedtitlesempty": "ఈ పరామితులతో ప్రస్తుతం శీర్షికలేమీ సరక్షించబడి లేవు.",
+       "protectedtitles-submit": "శీర్షికలను చూపించు",
        "listusers": "వాడుకరుల జాబితా",
        "listusers-editsonly": "మార్పులు చేసిన వాడుకరులను మాత్రమే చూపించు",
        "listusers-creationsort": "చేరిన తేదీ క్రమంలో చూపించు",
        "ancientpages": "పాత పేజీలు",
        "move": "తరలించు",
        "movethispage": "ఈ పేజీని తరలించు",
-       "unusedimagestext": "ఈ క్రింది ఫైళ్ళు ఉన్నాయి కానీ వాటిని ఏ పేజీలోనూ ఉపయోగించట్లేదు.\nఇతర వెబ్ సైట్లు సూటి URL ద్వారా ఇక్కడి ఫైళ్ళకు లింకు ఇవ్వవచ్చు, మరియు ఆవిధంగా క్రియాశీలంగా వాడుకలో ఉన్నప్పటికీ అటువంటివి ఈ జాబితాలో చేరి ఉండవచ్చునని గమనించండి.",
+       "unusedimagestext": "ఈ క్రింది ఫైళ్ళు ఉన్నాయి కానీ వాటిని ఏ పేజీలోనూ ఉపయోగించట్లేదు.\nఇతర వెబ్ సైట్లు సూటి URL ద్వారా ఇక్కడి ఫైళ్ళకు లింకు ఇవ్వవచ్చు. ఆ విధంగా క్రియాశీలంగా వాడుకలో ఉన్నప్పటికీ, అటువంటివి ఈ జాబితాలో చేరి ఉండవచ్చునని గమనించండి.",
        "unusedcategoriestext": "కింది వర్గాలకు పేజీలైతే ఉన్నాయి గానీ, వీటిని వ్యాసాలు గానీ, ఇతర వర్గాలు గానీ ఉపయోగించడం లేదు.",
        "notargettitle": "గమ్యం లేదు",
-       "notargettext": "à°\88 à°ªà°¨à°¿ à°\8f à°ªà±\87à°\9cà±\80 à°²à±\87దా à°¸à°­à±\8dà°¯à±\81à°¨ిపై జరగాలనే గమ్యాన్ని మీరు సూచించలేదు.",
+       "notargettext": "à°\88 à°ªà°¨à°¿ à°\8f à°ªà±\87à°\9cà±\80 à°²à±\87దా à°µà°¾à°¡à±\81à°\95à°°ిపై జరగాలనే గమ్యాన్ని మీరు సూచించలేదు.",
        "nopagetitle": "అలాంటి పేజీ లేదు",
        "nopagetext": "మీరు అడిగిన పేజీ లేదు",
        "pager-newer-n": "{{PLURAL:$1|1 కొత్తది|$1 కొత్తవి}}",
        "apisandbox-dynamic-parameters-add-label": "పరామితిని చేర్చు:",
        "apisandbox-dynamic-parameters-add-placeholder": "పరామితి పేరు",
        "apisandbox-dynamic-error-exists": "\"$1\" అనే పరామితి ఇప్పటికే ఉంది.",
+       "apisandbox-add-multi": "చేర్చు",
        "apisandbox-results": "ఫలితాలు",
        "apisandbox-request-url-label": "అభ్యర్థన URL:",
        "apisandbox-request-time": "అభ్యర్ధన సమయం: {{PLURAL:$1|$1 మి.సె.}}",
        "activeusers-intro": "ఇది గత $1 {{PLURAL:$1|రోజులో|రోజులలో}} ఏదైనా కార్యకలాపం చేసిన వాడుకరుల జాబితా.",
        "activeusers-count": "గడచిన {{PLURAL:$3|ఒక రోజు|$3 రోజుల}}లో $1 {{PLURAL:$1|చర్య|చర్యలు}}",
        "activeusers-from": "వాడుకరులను ఇక్కడ నుండి చూపించు:",
+       "activeusers-groups": "ఈ గుంపులకు చెందిన వాడుకరులను చూపించు:",
+       "activeusers-excludegroups": "ఈ గుంపులకు చెందిన వాడుకరులను చూపించవద్దు:",
        "activeusers-noresult": "వాడుకరులెవరూ లేరు.",
        "activeusers-submit": "చేతనంగా ఉన్న వాడుకరులను చూపించు",
        "listgrouprights": "వాడుకరి గుంపుల హక్కులు",
        "trackingcategories-msg": "పహారా కాయు వర్గము",
        "trackingcategories-name": "సందేశం పేరు",
        "trackingcategories-desc": "వర్గపు చేర్పు క్రైటేరియా",
+       "post-expand-template-argument-category-desc": "ఓ మూస పరామితిని విస్తరించాక (మూడు మీసాల బ్రాకెట్ల మధ్య ఉన్నవి, ఇలా: <code>{{{Foo}}}</code>), ఈ పేజీ <code>$wgMaxArticleSize</code> కంటే పెద్దదిగా ఉంది.",
+       "expensive-parserfunction-category-desc": "ఈ పేజీ ఖరీదైన పార్సరు ఫంక్షన్లు చాలా వాటిని వాడుతోంది (<code>#ifexist</code> లాంటివి). [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgExpensiveParserFunctionLimit Manual:$wgExpensiveParserFunctionLimit] చూడండి.",
        "broken-file-category-desc": "ఈ పుటలో విరిగిన దస్త్ర లంకె ఉన్నది (దస్త్రం ఉనికిలో లేనప్పుడు దస్త్రానికి ఎంబెడ్ చేయు లంకె).",
        "trackingcategories-nodesc": "వివరణ లేదు.",
        "trackingcategories-disabled": "వర్గం అచేతనమై ఉంది",
        "mailnologin": "పంపించవలసిన చిరునామా లేదు",
-       "mailnologintext": "à°\87తరà±\81à°²à°\95à±\81 à°\88-à°®à±\86యిలà±\81 à°ªà°\82పిà°\82à°\9aాలà°\82à°\9fà±\87, à°®à±\80à°°à±\81 [[Special:UserLogin|లాà°\97à°¿à°¨à±\8dâ\80\8c]] à°\85యి à°\89à°\82డాలి, à°®à°°à°¿à°¯à±\81 à°®à±\80 [[Special:Preferences|à°\85à°­à°¿à°°à±\81à°\9aà±\81à°²]]à°²à±\8b à°¸à°°à±\88à°¨ à°\88-à°®à±\86యిలà±\81 à°\9aà°¿à°°à±\81నామా à°\87à°\9aà±\8dà°\9aà°¿ à°\89à°\82డాలి.",
+       "mailnologintext": "ఇతరులకు ఈ-మెయిలు పంపించాలంటే, మీరు [[Special:UserLogin|లాగిన్‌]] అయి ఉండాలి, మీ [[Special:Preferences|అభిరుచుల]]లో సరైన ఈ-మెయిలు చిరునామా ఇచ్చి ఉండాలి.",
        "emailuser": "ఈ వాడుకరికి ఈ-మెయిలుని పంపించండి",
        "emailuser-title-target": "ఈ {{GENDER:$1|వాడుకరికి}} ఈమెయిలు పంపించండి",
        "emailuser-title-notarget": "వాడుకరికి ఈమెయిలు పంపించండి",
        "dellogpage": "తొలగింపుల చిట్టా",
        "dellogpagetext": "ఇది ఇటీవలి తుడిచివేతల జాబితా.",
        "deletionlog": "తొలగింపుల చిట్టా",
+       "log-name-create": "పేజీల సృష్టి చిట్టా",
+       "log-description-create": "ఇటీవల సృష్టించిన కొత్త పేజీల జాబితా ఇది.",
+       "logentry-create-create": "$3 పేజీని $1 {{GENDER:$2|సృష్టించారు}}",
        "reverted": "పాత కూర్పుకు తీసుకువెళ్ళాం.",
        "deletecomment": "కారణం:",
        "deleteotherreason": "ఇతర/అదనపు కారణం:",
        "delete-toobig": "ఈ పేజీకి $1 {{PLURAL:$1|కూర్పుకు|కూర్పులకు}} మించిన, చాలా పెద్ద దిద్దుబాటు చరితం ఉంది. {{SITENAME}}కు అడ్డంకులు కలగడాన్ని నివారించేందుకు గాను, అలాంటి పెద్ద పేజీల తొలగింపును నియంత్రించాం.",
        "delete-warning-toobig": "ఈ పేజీకి $1 {{PLURAL:$1|కూర్పుకు|కూర్పులకు}} మించిన, చాలా పెద్ద దిద్దుబాటు చరితం ఉంది. దాన్ని తొలగిస్తే {{SITENAME}}కి చెందిన డేటాబేసు కార్యాలకు ఆటంకం కలగొచ్చు; అప్రమత్తతో ముందుకుసాగండి.",
        "deleteprotected": "ఈ పేజీ సంరక్షణలో ఉంది కనుక మీరు తొలగించలేరు.",
-       "deleting-backlinks-warning": "'''హెచ్చరిక:''' మీరు తొలగించబోతున్న పేజీకి [[Special:WhatLinksHere/{{FULLPAGENAME}}|ఇతర పేజీల]] నుండి లింకులు ఉన్నాయి లేదా ఇక్కడ నుండి ట్రాన్స్‍క్లూడు అవుతున్నాయి.",
+       "deleting-backlinks-warning": "<strong>హెచ్చరిక:</strong> మీరు తొలగించబోతున్న పేజీకి [[Special:WhatLinksHere/{{FULLPAGENAME}}|ఇతర పేజీల]] నుండి లింకులు ఉన్నాయి. లేదా ఇతర పేజీల్లో అది ట్రాన్స్‍క్లూడు అవుతోంది.",
+       "deleting-subpages-warning": "<strong>హెచ్చరిక:</strong> మీరు తొలగించబోతున్న పేజీకి [[Special:PrefixIndex/{{FULLPAGENAME}}/|{{PLURAL:$1|ఒక ఉపపేజీ ఉంది|$1 ఉపపేజీలున్నాయి|51=50 కి పైగా ఉపపేజీలున్నాయి}}]].",
        "rollback": "దిద్దుబాట్లను రద్దుచేయి",
        "rollbacklink": "రద్దుచేయి",
        "rollbacklinkcount": "$1 {{PLURAL:$1|మార్పును|మార్పులను}} రద్దుచేయి",
        "rollbacklinkcount-morethan": "$1 కంటే ఎక్కువ {{PLURAL:$1|మార్పును|మార్పులను}} రద్దుచేయి",
        "rollbackfailed": "రద్దుచేయటం విఫలమైంది",
+       "rollback-missingrevision": "కూర్పు డేటాను లోడు చెయ్యలేకపోయాం.",
        "cantrollback": "రచనను వెనక్కి తీసుకువెళ్ళలేము; ఈ పేజీకి ఇదొక్కటే రచన.",
        "alreadyrolled": "[[:$1]]లో [[User:$2|$2]] ([[User talk:$2|చర్చ]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]) చేసిన చివరి మార్పును రద్దు చెయ్యలేము;\nమరెవరో ఆ పేజీని వెనక్కి మళ్ళించారు, లేదా మార్చారు.\n\nచివరి మార్పులు చేసినవారు: [[User:$3|$3]] ([[User talk:$3|చర్చ]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).",
        "editcomment": "దిద్దుబాటు సారాశం: <em>$1</em>.",
-       "revertpage": "[[Special:Contributions/$2|$2]] ([[User talk:$2|చర్చ]]) చేసిన మార్పులను [[User:$1|$1]] యొక్క చివరి కూర్పు వరకు తిప్పికొట్టారు.",
-       "revertpage-nouser": "దాచబడిన వాడుకరి చేసిన మార్పులను [[User:$1|$1]] యొక్క చివరి కూర్పుకి తిప్పికొట్టారు",
-       "rollback-success": "$1 చేసిన దిద్దుబాట్లను వెనక్కు తీసుకెళ్ళాం; తిరిగి $2 చేసిన చివరి కూర్పుకు మార్చాం.",
+       "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 మార్పులు చూపించు]",
        "sessionfailure-title": "సెషను వైఫల్యం",
-       "sessionfailure": "మీ ప్రవేశపు సెషనుతో ఏదో సమస్య ఉన్నట్లుంది;\nసెషను హైజాకు కాకుండా ఈ చర్యను రద్దు చేసాం.\n\"back\" కొట్టి, ఎక్కడి నుండి వచ్చారో ఆ పేజీని మళ్ళీ లోడు చేసి, తిరిగి ప్రయత్నించండి.",
+       "sessionfailure": "మీ లాగిన్ సెషనుతో ఏదో సమస్య ఉన్నట్లుంది;\nసెషను హైజాకు కాకుండా ఈ చర్యను రద్దు చేసాం.\nఫారమును తిరిగి సమర్పించండి.",
+       "changecontentmodel": "పేజీ కంటెంటు మోడలును మార్చు",
        "changecontentmodel-legend": "కంటెంటు మోడల్‌ మార్పు",
        "changecontentmodel-title-label": "పేజీ శీర్షిక",
        "changecontentmodel-model-label": "కొత్త కంటెంటు మోడల్",
        "undeletehistorynoadmin": "ఈ పుటని తొలగించివున్నారు.\nతొలగింపునకు కారణం, తొలగింపునకు క్రితం ఈ పుటకి మార్పులు చేసిన వాడుకరుల వివరాలతో సహా, ఈ కింద సారాంశంలో చూపబడింది.\nతొలగించిన కూర్పులలోని వాస్తవ పాఠ్యం నిర్వాహకులకు మాత్రమే అందుబాటులో ఉంటుంది.",
        "undelete-revision": "$1 యొక్క తొలగించబడిన కూర్పు (చివరగా $4 నాడు, $5కి $3 మార్చారు):",
        "undeleterevision-missing": "తప్పుడు లేదా తప్పిపోయిన కూర్పు. మీరు నొక్కింది తప్పుడు లింకు కావచ్చు, లేదా భాండాగారం నుండి కూర్పు పునఃస్థాపించబడి లేదా తొలగించబడి ఉండవచ్చు.",
+       "undeleterevision-duplicate-revid": "{{PLURAL:$1|ఒక కూర్పు|$1 కూర్పుల}}ను పునస్థాపించలేకపోయాం. ఎందుకంటే {{PLURAL:$1|దాని|వాటి}} <code>rev_id</code> ఈసరికే వినియోగంలో ఉంది.",
        "undelete-nodiff": "గత కూర్పులేమీ లేవు.",
        "undeletebtn": "పునఃస్థాపించు",
        "undeletelink": "చూడండి/పునస్థాపించండి",
        "undelete-search-title": "తొలగించిన పేజీల అన్వేషణ",
        "undelete-search-box": "తొలగించిన పేజీలను వెతుకు",
        "undelete-search-prefix": "దీనితో మొదలయ్యే పేజీలు చూపించు:",
+       "undelete-search-full": "ఇవి ఉన్న పేజీ శీర్షికలను చూపించు:",
        "undelete-search-submit": "వెతుకు",
        "undelete-no-results": "తొలగింపు సంగ్రహాల్లో దీనిని పోలిన పేజీలు లేవు.",
        "undelete-filename-mismatch": "$1 టైమ్‌స్టాంపు కలిగిన ఫైలుకూర్పు తొలగింపును రద్దు చెయ్యలేకపోయాం: ఫైలుపేరు సరిపోలలేదు",
        "namespace": "పేరుబరి:",
        "invert": "ఎంపికను తిరగవెయ్యి",
        "tooltip-invert": "ఎంచుకున్న పేరుబరి (చెక్ చేసి ఉంటే అనుబంధ పేరుబరి కూడా) లోని పేజీల్లో జరిగిన మార్పులను దాచేందుకు ఈ పెట్టెను చెక్ చెయ్యండి",
+       "tooltip-whatlinkshere-invert": "ఎంచుకున్న పేరుబరి లోని పేజీల నుండి వచ్చే లింకులను దాచేందుకు ఈ పెట్టెను చెక్ చెయ్యండి.",
        "namespace_association": "సంబంధిత పేరుబరి",
        "tooltip-namespace_association": "ఎంచుకున్న పేరుబరికి చెందిన చర్చ లేదా విషయం పేరుబరిని కూడా ఎంచుకునేందుకు ఈ పెట్టెను చెక్ చెయ్యండి.",
        "blanknamespace": "(మొదటి)",
        "contributions": "{{GENDER:$1|వాడుకరి}} రచనలు",
-       "contributions-title": "$1 à°¯à±\8aà°\95à±\8dà°\95 à°®à°¾à°°à±\8dà°ªà±\81à°²à±\81-చేర్పులు",
+       "contributions-title": "$1 à°®à°¾à°°à±\8dà°ªà±\81చేర్పులు",
        "mycontris": "నా మార్పులు",
        "anoncontribs": "మార్పుచేర్పులు",
        "contribsub2": "{{GENDER:$3|$1}} ($2) కొరకు",
        "uctop": "(ప్రస్తుత)",
        "month": "ఈ నెల నుండి (అంతకు ముందువి):",
        "year": "ఈ సంవత్సరం నుండి (అంతకు ముందువి):",
+       "date": "ఈ తేదీవి (అంతకు ముందువీ):",
        "sp-contributions-newbies": "కొత్త ఖాతాల యొక్క రచనలని మాత్రమే చూపించు",
        "sp-contributions-newbies-sub": "కొత్త ఖాతాల కోసం",
        "sp-contributions-newbies-title": "కొత్త ఖాతాల వాడుకరుల మార్పుచేర్పులు",
        "sp-contributions-uploads": "ఎక్కింపులు",
        "sp-contributions-logs": "చిట్టాలు",
        "sp-contributions-talk": "చర్చ",
-       "sp-contributions-userrights": "వాడుకరి హక్కుల నిర్వహణ",
+       "sp-contributions-userrights": "{{GENDER:$1|వాడుకరి}} హక్కుల నిర్వహణ",
        "sp-contributions-blocked-notice": "ఈ వాడుకరిపై ప్రస్తుతం నిరోధం ఉంది.\nనిరోధపు చిట్టాలోని చివరి పద్దుని మీ సమాచారంకోసం ఇస్తున్నాం:",
        "sp-contributions-blocked-notice-anon": "ఈ ఐపీ చిరునామాపై ప్రస్తుతం నిరోధం ఉంది.\nనిరోధపు చిట్టాలోని చివరి పద్దుని మీ సమాచారంకోసం ఇస్తున్నాం:",
        "sp-contributions-search": "రచనల కోసం అన్వేషణ",
        "sp-contributions-newonly": "పేజీని సృష్టించిన మార్పులను మాత్రమే చూపించు",
        "sp-contributions-hideminor": "చిన్న మార్పులను దాచు",
        "sp-contributions-submit": "వెతుకు",
+       "sp-contributions-outofrange": "ఫలితాలేమీ చూపించలేక పోయాం. అడిగిన IP శ్రేణి CIDR పరిమితి అయిన /$1 కంటే పెద్దదిగా ఉంది.",
        "whatlinkshere": "ఇక్కడికి లింకైనవి",
        "whatlinkshere-title": "\"$1\"కి లింకున్న పుటలు",
        "whatlinkshere-page": "పేజీ:",
-       "linkshere-2": "కింది పేజీల నుండి <strong>$1</strong>కు లింకులు ఉన్నాయి:",
-       "nolinkshere-2": "'''$1'''కు ఏ పేజీ నుండీ లింకు లేదు.",
-       "nolinkshere-ns-2": "'''$1''' పేజీకి లింకయ్యే పేజీలు ఎంచుకున్న నేంస్పేసులో లేవు.",
+       "linkshere": "కింది పేజీల నుండి <strong>$1</strong>కు లింకులు ఉన్నాయి:",
+       "nolinkshere": "'''$2'''కు ఏ పేజీ నుండీ లింకు లేదు.",
+       "nolinkshere-ns": "'''$2''' పేజీకి లింకయ్యే పేజీలు ఎంచుకున్న నేంస్పేసులో లేవు.",
        "isredirect": "దారిమార్పు పుట",
        "istemplate": "పేజీకి జతపరిచారు",
        "isimage": "దస్త్రపు లంకె",
        "ipbcreateaccount": "ఖాతా సృష్టిని నివారించు",
        "ipbemailban": "వాడుకరిని ఈ-మెయిల్ చెయ్యకుండా నివారించు",
        "ipbenableautoblock": "ఈ వాడుకరి వాడిన చివరి ఐపీ అడ్రసును, అలాగే ఆ తరువాత వాడే అడ్రసులను కూడా ఆటోమాటిగ్గా నిరోధించు",
-       "ipbsubmit": "à°\88 à°¸à°­à±\8dà°¯à±\81ని నిరోధించు",
+       "ipbsubmit": "à°\88 à°µà°¾à°¡à±\81à°\95à°°à°¿ని నిరోధించు",
        "ipbother": "వేరే గడువు",
        "ipboptions": "2 గంటలు:2 hours,ఒక రోజు:1 day,3 రోజులు:3 days,ఒక వారం:1 week,2 వారాలు:2 weeks,ఒక నెల:1 month,3 నెలలు:3 months,6 నెలలు:6 months,ఒక సంవత్సరం:1 year,ఎప్పటికీ:infinite",
-       "ipbhidename": "మార్పులు మరియు జాబితాల నుండి ఈ వాడుకరిపేరుని దాచు",
-       "ipbwatchuser": "à°\88 à°¸à°­à±\8dà°¯à±\81ని à°¸à°­à±\8dà°¯à±\81à°¨ి పేజీ, చర్చాపేజీలను వీక్షణలో ఉంచు",
+       "ipbhidename": "మార్పులు, జాబితాల నుండి ఈ వాడుకరిపేరుని దాచు",
+       "ipbwatchuser": "à°\88 à°µà°¾à°¡à±\81à°\95à°°à°¿ à°µà°¾à°¡à±\81à°\95à°°ి పేజీ, చర్చాపేజీలను వీక్షణలో ఉంచు",
        "ipb-disableusertalk": "నిరోధంలో ఉండగా ఈ వాడుకరి తన స్వంత చర్చ పేజీలో మార్పుచేర్పులు చెయ్యకుండా నిరోధించు",
        "ipb-change-block": "ఈ అమరికలతో వాడుకరిని పునర్నిరోధించు",
        "ipb-confirm": "నిరోధాన్ని ధృవపరచండి",
        "ipb-blocklist-contribs": "{{GENDER:$1|$1}} మార్పులు-చేర్పులు",
        "ipb-blocklist-duration-left": "ఇంకా $1 మిగిలి ఉంది.",
        "unblockip": "వాడుకరిపై నిరోధాన్ని తొలగించు",
-       "unblockiptext": "à°\95à°¿à°\82ది à°«à°¾à°°à°\82 à°\89పయà±\8bà°\97à°¿à°\82à°\9aà°¿, à°¨à°¿à°°à±\8bధిà°\82à°\9aబడిన à°\90.à°ªà±\80. à°\9aà°¿à°°à±\81నామా à°²à±\87దా à°¸à°­à±\8dà°¯à±\81à°¨ికి తిరిగి రచనలు చేసే అధికారం ఇవ్వవచ్చు.",
+       "unblockiptext": "à°\95à°¿à°\82ది à°«à°¾à°°à°\82 à°\89పయà±\8bà°\97à°¿à°\82à°\9aà°¿, à°¨à°¿à°°à±\8bధిà°\82à°\9aబడిన à°\90.à°ªà±\80. à°\9aà°¿à°°à±\81నామా à°²à±\87దా à°µà°¾à°¡à±\81à°\95à°°ికి తిరిగి రచనలు చేసే అధికారం ఇవ్వవచ్చు.",
        "ipusubmit": "ఈ నిరోధాన్ని తొలగించు",
        "unblocked": "[[User:$1|$1]]పై నిరోధం తొలగించబడింది",
        "unblocked-range": "$1 పై నిరోధాన్ని తీసేసాం",
        "unblocked-id": "$1 అనే నిరోధాన్ని తొలగించాం",
        "unblocked-ip": "[[Special:Contributions/$1|$1]] పైనున్న నిరోధాన్ని ఎత్తివేసాం.",
        "blocklist": "నిరోధిత వాడుకరులు",
+       "autoblocklist": "ఆటోబ్లాకులు",
        "autoblocklist-submit": "వెతుకు",
+       "autoblocklist-legend": "ఆటోబ్లాకుల జాబితా",
+       "autoblocklist-localblocks": "స్థానిక {{PLURAL:$1|ఆటోబ్లాకు|ఆటోబ్లాకులు}}",
+       "autoblocklist-total-autoblocks": "ఆటోబ్లాకుల మొత్తం సంఖ్య: $1",
+       "autoblocklist-empty": "ఆటోబ్లాకుల జాబితా ఖాళీగా ఉంది.",
+       "autoblocklist-otherblocks": "ఇతర {{PLURAL:$1|ఆటోబ్లాకు|ఆటోబ్లాకులు}}",
        "ipblocklist": "నిరోధించబడిన వాడుకరులు",
        "ipblocklist-legend": "నిరోధించబడిన వాడుకరిని వెతకండి",
        "blocklist-userblocks": "ఖాతా నిరోధాలను దాచు",
        "emailblock": "ఈ-మెయిలుని నిరోధించాం",
        "blocklist-nousertalk": "తమ చర్చాపేజీని మార్చలేరు",
        "ipblocklist-empty": "నిరోధపు జాబితా ఖాళీగా ఉంది.",
-       "ipblocklist-no-results": "à°®à±\80à°°à°¡à°¿à°\97à°¿à°¨ à°\90à°ªà±\80 à°\85à°¡à±\8dà°°à°¸à±\81 à°²à±\87దా à°¸à°­à±\8dయనామానà±\8dని నిరోధించలేదు.",
+       "ipblocklist-no-results": "à°®à±\80à°°à°¡à°¿à°\97à°¿à°¨ à°\90à°ªà±\80 à°\85à°¡à±\8dà°°à°¸à±\81 à°²à±\87దా à°µà°¾à°¡à±\81à°\95à°°à°¿à°ªà±\87à°°à±\81à°¨à±\81 నిరోధించలేదు.",
        "blocklink": "నిరోధించు",
        "unblocklink": "నిరోధాన్ని ఎత్తివేయి",
        "change-blocklink": "నిరోధాన్ని మార్చండి",
        "ipbnounblockself": "మిమ్మల్ని మీరే అనిరోధించుకునే అనుమతి మీకు లేదు",
        "lockdb": "డాటాబేసును లాక్‌ చెయ్యి",
        "unlockdb": "డాటాబేసుకి తాళంతియ్యి",
-       "lockdbtext": "à°¡à°¾à°\9fాబà±\87à°¸à±\81à°¨à±\81 à°²à°¾à°\95à±\8dâ\80\8c à°\9aà±\86à°¯à±\8dయడà°\82 à°µà°²à°¨ à°¸à°­à±\8dà°¯ులు పేజీలు మార్చడం, అభిరుచులు మార్చడం, వీక్షణ జాబితాను మార్చడం వంటి డాటాబేసు ఆధారిత పనులు చెయ్యలేరు. మీరు చెయ్యదలచినది ఇదేనని, మీ పని కాగానే తిరిగి డాటాబేసును ప్రారంభిస్తాననీ ధృవీకరించండి.",
+       "lockdbtext": "à°¡à°¾à°\9fాబà±\87à°¸à±\81à°¨à±\81 à°²à°¾à°\95à±\8dâ\80\8c à°\9aà±\86à°¯à±\8dయడà°\82 à°µà°²à°¨ à°µà°¾à°¡à±\81à°\95à°°ులు పేజీలు మార్చడం, అభిరుచులు మార్చడం, వీక్షణ జాబితాను మార్చడం వంటి డాటాబేసు ఆధారిత పనులు చెయ్యలేరు. మీరు చెయ్యదలచినది ఇదేనని, మీ పని కాగానే తిరిగి డాటాబేసును ప్రారంభిస్తాననీ ధృవీకరించండి.",
        "unlockdbtext": "డేటాబేసుకు తాళం తీసేసిన తరువాత, వాడుకరులందరూ పేజీలను మార్చటం మొదలు పెట్టగలరు,\nతమ అభిరుచులను మార్చుకోగలరు, వీక్షణా జాబితాకు పేజీలను కలుపుకోగలరు తీసివేయనూగలరు,\nఅంతేకాక డేటాబేసులో మార్పులు చేయగలిగే ఇంకొన్ని పనులు కూడా చేయవచ్చు.\nమీరు చేయదలుచుకుంది ఇదేనాకాదా అని ఒకసారి నిర్ధారించండి.",
        "lockconfirm": "అవును, డేటాబేసును లాకు చెయ్యాలని నిజంగానే అనుకుంటున్నాను.",
        "unlockconfirm": "అవును, నేను నిజంగానే డాటాబేసుకి తాళం తియ్యాలనుకుంటున్నాను.",
        "lockdbsuccesstext": "డాటాబేసు లాకయింది.<br />పని పూర్తి కాగానే లాకు తియ్యడం మర్చిపోకండి.",
        "unlockdbsuccesstext": "డాటాబేసుకి తాళం తీసాం.",
        "lockfilenotwritable": "డేటాబేసుకు తాళంవేయగల ఫైలులో రాయలేకపోతున్నాను.  డేటాబేసుకు తాళంవేయటానికిగానీ లేదా తీసేయటానికిగానీ, వెబ్‌సర్వరులో ఉన్న ఈ ఫైలులో రాయగలగాలి.",
+       "databaselocked": "డేటాబేసుకు ఈసరికే తాళం వేసి ఉంది.",
        "databasenotlocked": "డేటాబేసు లాకవలేదు.",
        "lockedbyandtime": "($2 న $3 వద్ద {{GENDER:$1|$1}} ద్వారా)",
        "move-page": "$1 తరలింపు",
        "movetalk": "కూడా వున్న చర్చ పేజీని తరలించు",
        "move-subpages": "ఉపపేజీలను ($1 వరకు) తరలించు",
        "move-talk-subpages": "చర్చా పేజీ యొక్క ఉపపేజీలను ($1 వరకు) తరలించు",
-       "movepage-page-exists": "$1 అనే పేజీ ఈపాటికే ఉంది మరియు దాన్ని ఆటోమెటిగ్గా ఈ పేజీతో మార్చివేయలేరు.",
+       "movepage-page-exists": "$1 అనే పేజీ ఈపాటికే ఉంది. దాన్ని ఆటోమెటిగ్గా ఈ పేజీతో తిరగ రాయలేరు.",
        "movepage-page-moved": "$1 అనే పేజీని $2 కి తరలించాం.",
        "movepage-page-unmoved": "$1 అనే పేజీని $2 కి తరలించలేకపోయాము.",
        "movepage-max-pages": "$1 యొక్క గరిష్ఠ పరిమితి {{PLURAL:$1|పేజీ|పేజీలు}} వరకు తరలించడమైనది. ఇక ఆటోమాటిగ్గా తరలించము.",
        "delete_and_move_text": "గమ్యపు పేజీ \"[[:$1]]\" ఇప్పటికే ఉనికిలో ఉంది. \nప్రస్తుత తరలింపుకు వీలుగా దాన్ని తొలగించేయమంటారా?",
        "delete_and_move_confirm": "అవును, పేజీని తొలగించు",
        "delete_and_move_reason": "\"[[$1]]\"ను తరలించడానికి వీలుగా తొలగించారు",
-       "selfmove": "మూలం, గమ్యం పేర్లు ఒకటే; పేజీని దాని పైకే తరలించడం కుదరదు.",
+       "selfmove": " శీర్షిక ఒకటే;\nపేజీని దాని పైకే తరలించడం కుదరదు.",
        "immobile-source-namespace": "\"$1\" పేరుబరిలోని పేజీలను తరలించలేరు",
        "immobile-target-namespace": "\"$1\" పేరుబరిలోనికి పేజీలను తరలించలేరు",
        "immobile-target-namespace-iw": "పేజీని తరలించడానికి అంతర్వికీ లింకు సరైన లక్ష్యం కాదు.",
        "fix-double-redirects": "పాత పేజీని సూచిస్తున్న దారిమార్పులను తాజాకరించు",
        "move-leave-redirect": "పాత పేజీని దారిమార్పుగా ఉంచు",
        "protectedpagemovewarning": "'''హెచ్చరిక:''' ఈ పేజీని సంరక్షించారు కనుక నిర్వాహక హక్కులు కలిగిన వాడుకరులు మాత్రమే దీన్ని తరలించగలరు.\nమీ సమాచారం కోసం చివరి చిట్టా పద్దుని ఇక్కడ ఇస్తున్నాం:",
-       "semiprotectedpagemovewarning": "'''గమనిక:''' ఈ పేజీని సంరక్షించారు కనుక నమోదైన వాడుకరులు మాత్రమే దీన్ని తరలించగలరు.\nమీ సమాచారం కోసం చివరి చిట్టా పద్దుని ఇక్కడ ఇస్తున్నాం:",
+       "semiprotectedpagemovewarning": "<strong>గమనిక:</strong> ఈ పేజీని సంరక్షించారు కనుక ఆటోకన్ఫర్మ్‌డ్ వాడుకరులు మాత్రమే దీన్ని తరలించగలరు.\nమీ సమాచారం కోసం చివరి చిట్టా పద్దుని ఇక్కడ ఇస్తున్నాం:",
        "move-over-sharedrepo": "[[:$1]] సామూహిక నిక్షేపంలో ఉంది. ఈ పేరుకు మరొక ఫైలును తరలిస్తే అది ఆ సామూహిక ఫైలును ఓవర్‌రైడు చేస్తుంది.",
        "file-exists-sharedrepo": "ఎంచుకున్న ఫైలు పేరు ఇప్పటికే సామాన్య భాండాగారంలో వాడుకలో ఉంది.\nదయచేసి మరొక పేరుని ఎంచుకోండి.",
        "export": "పేజీల ఎగుమతి",
-       "exporttext": "ఎంచుకున్న పేజీ లేదా పేజీలలోని వ్యాసం మరియు పేజీ చరితం లను XML లో ఎగుమతి చేసుకోవచ్చు. MediaWiki ని ఉపయోగించి Special:Import page ద్వారా దీన్ని వేరే వికీ లోకి దిగుమతి చేసుకోవచ్చు.\n\nపేజీలను ఎగుమతి చేసందుకు, కింద ఇచ్చిన టెక్స్టు బాక్సులో పేజీ పేర్లను లైనుకో పేరు చొప్పున ఇవ్వండి. ప్రస్తుత కూర్పుతో పాటు పాత కూర్పులు కూడా కావాలా, లేక ప్రస్తుత కూర్పు మాత్రమే చాలా అనే విషయం కూడా ఇవ్వవచ్చు.\n\nరెండో పద్ధతిలో అయితే, పేజీ యొక్క లింకును కూడా వాడవచ్చు. ఉదాహరణకు, \"[[{{MediaWiki:Mainpage}}]]\" కోసమైతే [[{{#Special:Export}}/{{MediaWiki:Mainpage}}]] అని ఇవ్వవచ్చు.",
+       "exporttext": "ఎంచుకున్న పేజీ లేదా పేజీలలోని వ్యాసం, పేజీ చరితాలను XML లో ఎగుమతి చేసుకోవచ్చు. MediaWiki ని ఉపయోగించి [[Special:Import|Import page]] ద్వారా దీన్ని వేరే వికీలోకి దిగుమతి చేసుకోవచ్చు.\n\nపేజీలను ఎగుమతి చేసేందుకు, కింద ఇచ్చిన టెక్స్టు బాక్సులో పేజీ పేర్లను లైనుకో పేరు చొప్పున ఇవ్వండి. ప్రస్తుత కూర్పుతో పాటు పాత కూర్పులు కూడా కావాలా, లేక ప్రస్తుత కూర్పు మాత్రమే చాలా అనే విషయం కూడా ఇవ్వవచ్చు.\n\nరెండో పద్ధతిలో అయితే, పేజీ లింకును కూడా వాడవచ్చు. ఉదాహరణకు, \"[[{{MediaWiki:Mainpage}}]]\" కోసమైతే [[{{#Special:Export}}/{{MediaWiki:Mainpage}}]] అని ఇవ్వవచ్చు.",
        "exportall": "పేజీలన్నిటినీ ఎగుమతి చెయ్యి",
        "exportcuronly": "ప్రస్తుత కూర్పు మాత్రమే, పూర్తి చరితం వద్దు",
        "exportnohistory": "----\n'''గమనిక:''' ఈ ఫారాన్ని ఉపయోగించి పేజీలయొక్క పూర్తి చరిత్రను ఎగుమతి చేయడాన్ని సర్వరుపై వత్తిడి పెరిగిన కారణంగా ప్రస్తుతం నిలిపివేశారు.",
        "thumbnail_dest_directory": "గమ్యస్థానంలో డైరెక్టరీని సృష్టించలేకపోయాం",
        "thumbnail_image-type": "ఈ బొమ్మ రకానికి మద్దతు లేదు",
        "thumbnail_gd-library": "అసంపూర్ణ GD సంచయపు ఏర్పాటు: $1 ఫంక్షను లేదు.",
+       "thumbnail_image-size-zero": "బొమ్మ దస్త్రపు పరిమాణం సున్నా అనుకుంటాను.",
        "thumbnail_image-missing": "ఫైలు తప్పిపోయినట్లున్నది: $1",
        "thumbnail_image-failure-limit": "ఈ థంబ్‍నెయిల్‍ను రెండరు చెయ్యడానికి చాలా ఎక్కువ విఫలయత్నాలు ($1 లేదా అంతకంటే ఎక్కువ) జరిగాయి. కాస్తాగి మళ్ళీ ప్రయత్నించండి.",
        "import": "పేజీలను దిగుమతి చేసుకోండి",
        "import-mapping-namespace": "పేరుబరికి దిగుమతించు:",
        "import-mapping-subpage": "దిగువ పేర్కొన్న పేజీ యొక్క ఉప పేజీలుగా దిగుమతించు:",
        "import-upload-filename": "పైలుపేరు:",
+       "import-upload-username-prefix": "అంతర్వికీ ఆదిపదం:",
+       "import-assign-known-users": "సూచించిన వాడుకరి స్థానికంగా ఉంటే దిద్దుబాట్లను ఆ వాడుకరికే ఆపాదించు",
        "import-comment": "వ్యాఖ్య:",
        "importtext": "[[Special:Export|ఎగుమతి ఉపకరణాన్ని]] ఉపయోగించి, ఈ ఫైలుని  మూల వికీ నుంచి ఎగుమతి చెయ్యండి.\nదాన్ని మీ కంప్యూటర్లో భద్రపరచి, ఆపై ఇక్కడికి ఎక్కించండి.",
        "importstart": "పేజీలను దిగుమతి చేస్తున్నాం...",
        "tooltip-pt-mycontris": "{{GENDER:|మీ}} మార్పుచేర్పుల జాబితా",
        "tooltip-pt-anoncontribs": "ఈ IP అడ్రసు నుండి చేసిన దిద్దుబాట్ల జాబితా",
        "tooltip-pt-login": "మిమ్మల్ని లాగినవమని ప్రోత్సహిస్తున్నాం; కానీ అది తప్పనిసరేమీ కాదు.",
+       "tooltip-pt-login-private": "ఈ వికీని వాడాలంటే మీరు లాగినై ఉండాలి.",
        "tooltip-pt-logout": "లాగౌటవండి",
        "tooltip-pt-createaccount": "మీరొక ఖాతాని సృష్టించుకొని ప్రవేశించటాన్ని సమర్ధిస్తున్నాము; కానీ, అది అవసరం కాదు, ఐచ్ఛికం మాత్రమే.",
        "tooltip-ca-talk": "విషయపు పేజీ గురించి చర్చ",
        "pageinfo-robot-index": "అనుమతించబడింది",
        "pageinfo-robot-noindex": "అనుమతించబడలేదు",
        "pageinfo-watchers": "పేజీ గమనింపుదారుల సంఖ్య",
+       "pageinfo-visiting-watchers": "ఈ పేజీలో ఇటీవల జరిగిన దిద్దుబాట్లను చూసిన వీక్షకుల సంఖ్య",
        "pageinfo-few-watchers": "$1 {{PLURAL:$1|వీక్షకుడి|వీక్షకుల}} కంటే తక్కువ",
        "pageinfo-redirects-name": "ఈ పేజీకి ఉన్న దారిమార్పుల సంఖ్య",
        "pageinfo-subpages-name": "ఈ పేజీకి ఉన్న ఉపపేజీల సంఖ్య",
        "pageinfo-protect-cascading-yes": "అవును",
        "pageinfo-protect-cascading-from": "సంరక్షణ ఇక్కడినుంచి వ్యాపిస్తుంది",
        "pageinfo-category-info": "వర్గపు సమాచారం",
-       "pageinfo-category-total": "à°®à±\8aà°¤à±\8dà°¤à°\82 à°¸à°­à±\8dà°¯ుల సంఖ్య",
+       "pageinfo-category-total": "à°®à±\8aà°¤à±\8dà°¤à°\82 à°µà°¾à°¡à±\81à°\95à°°ుల సంఖ్య",
        "pageinfo-category-pages": "పేజీల సంఖ్య",
        "pageinfo-category-subcats": "ఉపవర్గాల సంఖ్య",
        "pageinfo-category-files": "దస్త్రాల సంఖ్య",
        "markedaspatrollednotify": "$1 లో చేసిన ఈ మార్పు పర్యవేక్షణలో ఉన్నట్టుగా గుర్తించబడింది.",
        "patrol-log-page": "నిఘా చిట్టా",
        "patrol-log-header": "ఇది పర్యవేక్షించిన కూర్పుల చిట్టా.",
-       "log-show-hide-patrol": "$1 పర్యవేక్షణ చిట్టా",
-       "log-show-hide-tag": "ట్యాగుల చిట్టాను $1",
        "confirm-markpatrolled-button": "సరే",
        "deletedrevision": "పాత సంచిక $1 తొలగించబడినది.",
        "filedeleteerror-short": "ఫైలు తొలగించడంలో పొరపాటు: $1",
        "svg-long-error": "చెల్లని SVG దస్త్రం: $1",
        "show-big-image": "అసలు దస్త్రం",
        "show-big-image-preview": "ఈ మునుజూపు పరిమాణం: $1.",
+       "show-big-image-preview-differ": "ఈ ఫైలు $2 కు చెందిన ఈ మునుజూపు $3 పరిమాణం: $1.",
        "show-big-image-other": "ఇతర {{PLURAL:$2|వైశాల్యం|వైశాల్యాలు}}: $1.",
        "show-big-image-size": "$1 × $2 పిక్సెళ్ళు",
        "file-info-gif-looped": "లూపులో పడింది",
        "newimages-summary": "ఇటీవలే ఎగుమతైన ఫైళ్ళను ఈ ప్రత్యేక పేజీ చూపిస్తుంది.",
        "newimages-legend": "పడపోత",
        "newimages-label": "ఫైలుపేరు (లేదా దానిలోని భాగం):",
+       "newimages-user": "ఐపీ చిరునామా లేదా వాడుకరి పేరు",
+       "newimages-newbies": "కొత్త ఖాతాల రచనలని మాత్రమే చూపించు",
        "newimages-showbots": "బాట్లు చేసిన అప్లోడ్లు చూపించు",
+       "newimages-mediatype": "మాధ్యమ రకం:",
        "noimages": "చూసేందుకు ఏమీ లేదు.",
        "ilsubmit": "వెతుకు",
        "bydate": "తేదీ వారీగ",
        "exif-samplesperpixel": "కాంపొనెంట్ల సంఖ్య",
        "exif-planarconfiguration": "డాటా అమరిక",
        "exif-ycbcrsubsampling": "Y, C ల ఉప నమూనా నిష్పత్తి",
-       "exif-ycbcrpositioning": "Y మరియు C స్థానాలు",
+       "exif-ycbcrpositioning": "Y, C స్థానాలు",
        "exif-xresolution": "క్షితిజసమాంతర స్పష్టత",
        "exif-yresolution": "లంబ స్పష్టత",
        "exif-stripoffsets": "బొమ్మ డేటా ఉన్న స్థలం",
        "exif-whitepoint": "శ్వేతబిందు వర్ణోగ్రత (క్రొమాటిసిటీ)",
        "exif-primarychromaticities": "ప్రైమారిటీల వర్ణోగ్రతలు",
        "exif-ycbcrcoefficients": "వర్ణస్థల మార్పు మాత్రిక స్థానసూచికలు",
-       "exif-referenceblackwhite": "నలుపు మరియు తెలుపు సూచీ విలువల యొక్క జత",
-       "exif-datetime": "ఫైలు మార్చిన తేదీ మరియు సమయం",
+       "exif-referenceblackwhite": "నలుపు, తెలుపు సూచీ విలువల జత",
+       "exif-datetime": "ఫైలు మార్చిన తేదీ, సమయం",
        "exif-imagedescription": "బొమ్మ శీర్షిక",
        "exif-make": "కేమెరా తయారీదారు",
        "exif-model": "కేమెరా మోడల్",
        "exif-compression-1": "కుదించని",
        "exif-copyrighted-true": "నకలుహక్కులుకలది",
        "exif-copyrighted-false": "కాపీహక్కుల స్థితి అమర్చలేదు",
-       "exif-photometricinterpretation-1": "నలà±\81à°ªà±\81 à°®à°°à°¿à°¯à±\81 à°¤à±\86à°²à±\81à°\97à±\81 (నలà±\81à°ªà±\81à°\95à°¿ 0)",
+       "exif-photometricinterpretation-1": "నలుపు తెలుగు (నలుపుకి 0)",
        "exif-unknowndate": "అజ్ఞాత తేదీ",
        "exif-orientation-1": "సాధారణ",
        "exif-orientation-2": "క్షితిజ సమాంతరంగా తిరగేసాం",
        "exif-gpsdop-poor": "బాగా లేదు ($1)",
        "exif-objectcycle-a": "ఉదయం మాత్రమే",
        "exif-objectcycle-p": "సాయంత్రం మాత్రమే",
-       "exif-objectcycle-b": "à°\89దయమà±\82 à°®à°°à°¿à°¯à±\81 à°¸à°¾à°¯à°\82à°¤à±\8dà°°à°®à±\82",
+       "exif-objectcycle-b": "ఉదయము సాయంత్రమూ",
        "exif-gpsdirection-t": "వాస్తవ దిశ",
        "exif-gpsdirection-m": "అయస్కాంత దిశ",
        "exif-ycbcrpositioning-1": "మధ్యగతం చేయబడిన",
        "exif-dc-type": "మీడియా యొక్క రకము",
        "exif-rating-rejected": "తిరస్కరించబడింది",
        "exif-isospeedratings-overflow": "65535 కంటే ఎక్కువ",
-       "exif-iimcategory-ace": "కళలు, సంస్కృతి మరియు వినోదం",
-       "exif-iimcategory-clj": "నేరము మరియు చట్టము",
-       "exif-iimcategory-dis": "విపత్తులు మరియు ప్రమాదాలు",
-       "exif-iimcategory-fin": "ఆర్ధికం మరియు వ్యాపారం",
+       "exif-iimcategory-ace": "కళలు, సంస్కృతి, వినోదం",
+       "exif-iimcategory-clj": "నేరము, చట్టమూ",
+       "exif-iimcategory-dis": "విపత్తులు, ప్రమాదాలు",
+       "exif-iimcategory-fin": "ఆర్ధికం, వాణిజ్యం",
        "exif-iimcategory-edu": "విద్య",
        "exif-iimcategory-evn": "పర్యావరణం",
        "exif-iimcategory-hth": "ఆరోగ్యం",
        "exif-iimcategory-hum": "మానవీయ ఆసక్తి",
        "exif-iimcategory-lab": "కృషి",
-       "exif-iimcategory-lif": "జీవనశైలి మరియు కాలక్షేపం",
+       "exif-iimcategory-lif": "జీవనశైలి, కాలక్షేపం",
        "exif-iimcategory-pol": "రాజకీయాలు",
-       "exif-iimcategory-rel": "మతం మరియు విశ్వాసం",
-       "exif-iimcategory-sci": "వైజ్ఞానికం మరియు సాంకేతికం",
+       "exif-iimcategory-rel": "మతం, విశ్వాసం",
+       "exif-iimcategory-sci": "వైజ్ఞానికం, సాంకేతికం",
        "exif-iimcategory-soi": "సాంఘిక సమస్యలు",
        "exif-iimcategory-spo": "క్రీడలు",
-       "exif-iimcategory-war": "యుద్ధం, సంఘర్షణలు మరియు అనిశ్చితి",
+       "exif-iimcategory-war": "యుద్ధం, సంఘర్షణ, అల్లర్లు",
        "exif-iimcategory-wea": "వాతావరణం",
        "exif-urgency-normal": "సాధారణం ($1)",
        "exif-urgency-low": "తక్కువ ($1)",
        "confirmemail_success": "మీ ఈ-మెయిలు చిరునామా ధృవీకరించబడింది.\nఇక [[Special:UserLogin|లోనికి ప్రవేశించి]] వికీని అస్వాదించండి.",
        "confirmemail_loggedin": "మీ ఈ-మెయిలు చిరునామా ఇప్పుడు రూఢి అయింది.",
        "confirmemail_subject": "{{SITENAME}} ఈ-మెయిలు చిరునామా ధృవీకరణ",
-       "confirmemail_body": "$1 ఐపీ చిరునామా నుండి ఎవరో, బహుశా మీరే,\n{{SITENAME}}లో \"$2\" అనే ఖాతాని ఈ ఈ-మెయిలు చిరునామాతో నమోదుచేసుకున్నారు.\n\nఆ ఖాతా నిజంగా మీదే అని నిర్ధారించేందుకు మరియు {{SITENAME}}లో ఈ-మెయిలు సౌలభ్యాలని\nచేతనం చేసుకునేందుకు, ఈ లంకెని మీ విహారిణిలో తెరవండి:\n\n$3\n\nఒకవేళ ఆ ఖాతా మీది *కాకపోతే*, ఈ-మెయిలు చిరునామా నిర్ధారణని రద్దుచేసేందుకు ఈ లంకెని అనుసరించండి:\n\n$5\n\nఈ నిర్ధారణా సంకేతం $4కి కాలంచెల్లుతుంది.",
+       "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_invalidated": "ఈ-మెయిలు చిరునామా నిర్ధారణని రద్దుచేసాం",
        "invalidateemail": "ఈ-మెయిలు నిర్ధారణని రద్దుచేయండి",
        "version-poweredby-others": "ఇతరులు",
        "version-poweredby-translators": "translatewiki.net అనువాదకులు",
        "version-credits-summary": "కింది వ్యక్తులు [[Special:Version|MediaWiki]] కి చేసిన సేవకుగాను, వారిని గుర్తించదలచాం.",
-       "version-license-info": "à°®à±\80డియావిà°\95à±\80 à°\85à°¨à±\8dనది à°¸à±\8dà°µà±\87à°\9aà±\8dà°\9bà°¾ à°®à±\83à°¦à±\82à°ªà°\95à°°à°£à°\82; మీరు దీన్ని పునఃపంపిణీ చేయవచ్చు మరియు/లేదా ఫ్రీ సాఫ్ట్&zwnj;వేర్ ఫౌండేషన్ ప్రచురించిన గ్నూ జనరల్ పబ్లిక్ లైసెస్సు వెర్షను 2 లేదా (మీ ఎంపిక ప్రకారం) అంతకంటే కొత్త వెర్షను యొక్క నియమాలకు లోబడి మార్చుకోవచ్చు.\n\nమీడియావికీ ప్రజోపయోగ ఆకాంక్షతో పంపిణీ చేయబడుతుంది, కానీ ఎటువంటి వారంటీ లేకుండా; కనీసం ఏదైనా ప్రత్యేక ఉద్దేశానికి సరిపడుతుందని గానీ లేదా వస్తుత్వం యొక్క అంతర్నిహిత వారంటీ లేకుండా. మరిన్ని వివరాలకు గ్నూ జనరల్ పబ్లిక్ లైసెన్సుని చూడండి.\n\nఈ ఉపకరణంతో పాటు మీకు [{{SERVER}}{{SCRIPTPATH}}/COPYING గ్నూ జనరల్ పబ్లిక్ లైసెన్సు  యొక్క ఒక కాపీ] అందివుండాలి; లేకపోతే, Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA అన్న చిరునామాకి వ్రాయండి లేదా [//www.gnu.org/licenses/old-licenses/gpl-2.0.html జాలం లోనే చదవండి].",
+       "version-license-info": "à°®à±\80డియావిà°\95à±\80 à°\85à°¨à±\8dనది à°¸à±\8dà°µà±\87à°\9aà±\8dà°\9bà°¾ à°¸à°¾à°«à±\8dà°\9fà±\81à°µà±\87à°°à±\81; మీరు దీన్ని పునఃపంపిణీ చేయవచ్చు మరియు/లేదా ఫ్రీ సాఫ్ట్&zwnj;వేర్ ఫౌండేషన్ ప్రచురించిన గ్నూ జనరల్ పబ్లిక్ లైసెస్సు వెర్షను 2 లేదా (మీ ఎంపిక ప్రకారం) అంతకంటే కొత్త వెర్షను యొక్క నియమాలకు లోబడి మార్చుకోవచ్చు.\n\nమీడియావికీ ప్రజోపయోగ ఆకాంక్షతో పంపిణీ చేయబడుతుంది, కానీ ఎటువంటి వారంటీ లేకుండా; కనీసం ఏదైనా ప్రత్యేక ఉద్దేశానికి సరిపడుతుందని గానీ లేదా వస్తుత్వం యొక్క అంతర్నిహిత వారంటీ లేకుండా. మరిన్ని వివరాలకు గ్నూ జనరల్ పబ్లిక్ లైసెన్సుని చూడండి.\n\nఈ ఉపకరణంతో పాటు మీకు [{{SERVER}}{{SCRIPTPATH}}/COPYING గ్నూ జనరల్ పబ్లిక్ లైసెన్సు  యొక్క ఒక కాపీ] అందివుండాలి; లేకపోతే, Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA అన్న చిరునామాకి వ్రాయండి లేదా [//www.gnu.org/licenses/old-licenses/gpl-2.0.html జాలం లోనే చదవండి].",
        "version-software": "స్థాపిత మృదూపకరణాలు",
        "version-software-product": "ప్రోడక్టు",
        "version-software-version": "వెర్షను",
        "specialpages-group-maintenance": "నిర్వహణా నివేదికలు",
        "specialpages-group-other": "ఇతర ప్రత్యేక పేజీలు",
        "specialpages-group-login": "లాగినవండి / ఖాతా సృష్టించుకోండి",
-       "specialpages-group-changes": "ఇటీవలి మార్పులు మరియు దినచర్యలు",
-       "specialpages-group-media": "మాధà±\8dయమ à°¨à°¿à°µà±\87దిà°\95à°²à±\81 à°®à°°à°¿à°¯à±\81 à°\8eà°\97à±\81మతులు",
+       "specialpages-group-changes": "ఇటీవలి మార్పులు, చిట్టాలు",
+       "specialpages-group-media": "à°®à±\80డియా à°¨à°¿à°µà±\87దిà°\95à°²à±\81, à°\8eà°\95à±\8dà°\95à°¿à°\82à°ªులు",
        "specialpages-group-users": "వాడుకరులు, హక్కులు",
        "specialpages-group-highuse": "అధిక వాడుక పేజీలు",
        "specialpages-group-pages": "పేజీల జాబితాలు",
        "specialpages-group-pagetools": "పేజీ పనిముట్లు",
-       "specialpages-group-wiki": "డాటా మరియు పనిముట్లు",
+       "specialpages-group-wiki": "డాటా, పనిముట్లు",
        "specialpages-group-redirects": "ప్రత్యేక పేజీల దారిమార్పులు",
        "specialpages-group-spam": "స్పామ్ పనిముట్లు",
        "specialpages-group-developer": "వికాసకుల పనిముట్లు",
        "tag-filter": "[[Special:Tags|ట్యాగుల]] వడపోత:",
        "tag-filter-submit": "వడపోయి",
        "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|ట్యాగు|ట్యాగులు}}]]: $2)",
+       "tag-mw-new-redirect": "కొత్త దారిమార్పు",
        "tag-mw-blank": "తుడిచివేత",
        "tag-mw-blank-description": "పేజీని తుడిచివేసే దిద్దుబాట్లు",
        "tags-title": "టాగులు",
-       "tags-intro": "à°\88 à°ªà±\87à°\9cà±\80 à°®à±\83à°¦à±\82à°ªà°\95à°°à°£à°\82 à°®à°¾à°°à±\8dà°ªà±\81à°²à°\95à±\81 à°\87à°\9aà±\8dà°\9aà±\87 à°\9fà±\8dయాà°\97à±\81లనà±\81, à°®à°°à°¿à°¯à±\81 à°µà°¾à°\9fà°¿ à°\85à°°à±\8dధాలనà±\81 చూపిస్తుంది.",
+       "tags-intro": "మారà±\8dà°ªà±\81à°\9aà±\87à°°à±\8dà°ªà±\81à°²à°\95à±\81 à°¸à°¾à°«à±\8dà°\9fà±\81à°µà±\87à°°à±\81 à°\87à°\9aà±\8dà°\9aà±\87 à°\9fà±\8dయాà°\97à±\81లనà±\81, à°µà°¾à°\9fà°¿ à°\85à°°à±\8dధాలనà±\82 à°\88 à°ªà±\87à°\9cà±\80 చూపిస్తుంది.",
        "tags-tag": "ట్యాగు పేరు",
        "tags-display-header": "మార్పుల జాబితాలో కనపించు రీతి",
        "tags-description-header": "అర్థం యొక్క పూర్తి వివరణ",
        "tags-create-reason": "కారణం:",
        "tags-create-submit": "సృష్టించు",
        "tags-create-no-name": "ట్యాగు పేరును తప్పకుండా ఇవ్వాలి.",
+       "tags-create-invalid-chars": "ట్యాగు పేర్లలో కామాలు (<code>,</code>), పైపులు (<code>|</code>), ఫార్వర్డ్ స్లాషులూ (<code>/</code>) ఉండకూడదు.",
+       "tags-create-invalid-title-chars": "పేజీ శీర్షికల్లో వాడకూడని క్యారెక్టర్లను ట్యాగు పేర్లలోనూ ఉండకూడదు.",
        "tags-create-already-exists": "\"$1\" ట్యాగు ఇప్పటికే ఉంది.",
+       "tags-create-warnings-above": "\"$1\" ట్యాగును సృష్టించబోగా కింది {{PLURAL:$2|హెచ్చరిక ఎదురైంది|హెచ్చరికలు ఎదురయ్యాయి}}:",
+       "tags-create-warnings-below": "ట్యాగు సృష్టించడానికి ముందుకెళ్తారా?",
        "tags-delete-title": "ట్యాగును తొలగించు",
        "tags-delete-explanation-initial": "మీరు \"$1\" ట్యాగును డేటాబేసు నుండి తొలగించబోతున్నారు.",
+       "tags-delete-explanation-in-use": "ప్రస్తుతం దీన్ని వర్తింపజేసిన {{PLURAL:$2|$2 కూర్పు లేదా చిట్టా పద్దు|మొత్తం $2 కూర్పులు లేదా చిట్టా పద్దుల}} నుండి తీసివేస్తాం.",
+       "tags-delete-explanation-warning": "ఈ చర్య <strong>రద్దు కాదు</strong>. డేటాబేసు నిర్వాహకులు కూడా <strong>వెనక్కి తిప్పలేరు</strong>. మీరు తొలగించదలచిన ట్యాగు ఇదేనని నిర్ధారించుకోండి.",
+       "tags-delete-explanation-active": "<strong>\"$1\" ట్యాగు చేతనంగానే ఉంది. భవిష్యత్తులో దాన్ని వాడవచ్చు కూడా.</strong> ఇది జరక్కుండా ఉండేందుకు, ఈ ట్యాగును ఎక్కడైతే వాడే అవకాశం ఉందో, అక్కడ దాన్ని అచేతనం చెయ్యండి.",
        "tags-delete-reason": "కారణం:",
+       "tags-delete-submit": "ఈ ట్యాగును వెనక్కి తీసుకోలేని విధంగా తొలగించు",
+       "tags-delete-not-allowed": "ఏదైనా పొడిగింత నిర్వచించిన ట్యాగులను, ఆ పొడిగింత అనుమతిస్తే తప్ప తొలగించలేరు.",
        "tags-delete-not-found": "\"$1\" అనే ట్యాగు లేదు.",
+       "tags-delete-too-many-uses": "\"$1\" ట్యాగు $2 కంటే ఎక్కువ {{PLURAL:$2|కూర్పుకు|కూర్పులకు}} వర్తింపజేసి ఉంది. అంటే దాన్ని తొలగించలేరని అర్థం.",
+       "tags-delete-warnings-after-delete": "\"$1\" ట్యాగును ను తొలగించాం. కానీ కింది {{PLURAL:$2|హెచ్చరిక ఎదురైంది|హెచ్చరికలు ఎదురయ్యాయి}}:",
+       "tags-delete-no-permission": "మార్పు ట్యాగులను తొలగించే అనుమతి మీకు లేదు.",
+       "tags-activate-title": "ట్యాగును చేతనం చేయి",
+       "tags-activate-question": "\"$1\" ట్యాగును మీరు చేతనం చెయ్యబోతున్నారు.",
        "tags-activate-reason": "కారణం:",
+       "tags-activate-not-allowed": "\"$1\" ట్యాగును చేతనం చెయ్యడం కుదరలేదు.",
        "tags-activate-not-found": "\"$1\" అనే ట్యాగు లేదు.",
        "tags-activate-submit": "చేతనంచేయి",
        "tags-deactivate-title": "ట్యాగును అచేతనం చేయి",
        "tags-deactivate-not-allowed": "\"$1\" ట్యాగును అచేతనం చేయడం సాధ్యం కాదు.",
        "tags-deactivate-submit": "అచేతనం చేయి",
        "tags-apply-no-permission": "మీ మార్పులతో పాటు వాటికి ట్యాగులను ఆపాదించే అనుమతి మీకు లేదు.",
+       "tags-apply-blocked": "{{GENDER:$1|మీరు}} నిరోధంలో ఉండగా మీ మార్పులతో పాటు మార్పు ట్యాగులను అమలు చెయ్యడం కుదరదు.",
        "tags-apply-not-allowed-one": "\"$1\" ట్యాగును మానవీయంగా ఆపాదించలేరు.",
-       "tags-apply-not-allowed-multi": "ఈ {{PLURAL:$2|ట్యాగును|ట్యాగులను}} మానవీయంగా ఆపాదించడానికి అనుమతించరు:",
+       "tags-apply-not-allowed-multi": "ఈ {{PLURAL:$2|ట్యాగును|ట్యాగులను}} మానవీయంగా ఆపాదించడానికి అనుమతి లేదు:$1",
+       "tags-update-no-permission": "కూర్పులు లేదా చిట్టా లోని అంశాలకు మార్పు ట్యాగులను మార్చే, తీసేసే అనుమతి మీకు లేదు",
+       "tags-update-blocked": "{{GENDER:$1|మీరు}} నిరోధంలో ఉండగా మీ మార్పులతో పాటు మార్పు ట్యాగులను చేర్చడం, తీసెయ్యడం కుదరదు.",
+       "tags-update-add-not-allowed-one": "\"$1\" ట్యాగును మానవికంగా చేర్చే అనుమతి లేదు.",
+       "tags-update-add-not-allowed-multi": "కింది {{PLURAL:$2|ట్యాగును|ట్యాగులను}} మానవికంగా చేర్చే అనుమతి లేదు: $1",
+       "tags-update-remove-not-allowed-one": "\"$1\" ట్యాగును తీసేసే అనుమతి లేదు.",
+       "tags-update-remove-not-allowed-multi": "కింది {{PLURAL:$2|ట్యాగును|ట్యాగులను}} మానవికంగా తీసేసే అనుమతి లేదు: $1",
        "tags-edit-title": "ట్యాగులను సవరించు",
        "tags-edit-manage-link": "ట్యాగులను నిర్వహించండి",
+       "tags-edit-revision-selected": "[[:$2]] కు చెందిన {{PLURAL:$1|ఎంచుకున్న కూర్పు|ఎంచుకున్న కూర్పులు}}:",
+       "tags-edit-logentry-selected": "{{PLURAL:$1|ఎంచుకున్న చిట్టా ఘటన|ఎంచుకున్న చిట్టా ఘటనలు}}:",
+       "tags-edit-revision-legend": "{{PLURAL:$1|ఈ కూర్పు|మొత్తం $1 కూర్పుల}}కు ట్యాగులను చేర్చడం/తొలగించడం",
+       "tags-edit-logentry-legend": "ఈ {{PLURAL:$1|ఈ చిట్టా పద్దు|మొత్తం $1 చిట్టా పద్దుల}}కు ట్యాగులను చేర్చడం/తొలగించడం",
        "tags-edit-existing-tags": "ప్రస్తుత ట్యాగులు:",
        "tags-edit-existing-tags-none": "<em>ఏమీలేవు</em>",
        "tags-edit-new-tags": "కొత్త ట్యాగులు:",
        "tags-edit-add": "ఈ ట్యాగులను చేర్చు:",
        "tags-edit-remove": "ఈ ట్యాగులను తొలగించు:",
+       "tags-edit-remove-all-tags": "(ట్యాగులన్నిటినీ తొలగించు)",
+       "tags-edit-chosen-placeholder": "కొన్ని ట్యాగులను ఎంచుకోండి",
+       "tags-edit-chosen-no-results": "దానికి సరిపడే ట్యాగులేమీ కనబడలేదు",
        "tags-edit-reason": "కారణం:",
+       "tags-edit-revision-submit": "{{PLURAL:$1|ఈ కూర్పుకు|$1 కూర్పులకు}} మార్పులను వర్తింపజేయి",
+       "tags-edit-logentry-submit": "{{PLURAL:$1|ఈ చిట్టా పద్దుకు|$1 చిట్టా పద్దులకు}} మార్పులను వర్తింపజేయి",
        "tags-edit-success": "మార్పులు ఆపాదించబడ్డాయి.",
+       "tags-edit-failure": "మార్పులను వర్తింపజేయలేక పోయాం:\n$1",
+       "tags-edit-none-selected": "చేర్చడానికి/తీసెయ్యడానికి కనీసం ఒక్క ట్యాగునైనా ఎంచుకోండి",
        "comparepages": "పుటల పోలిక",
        "compare-page1": "పుట 1",
        "compare-page2": "పుట 2",
        "compare-title-not-exists": "మీరు పేర్కొన్న శీర్షిక లేనే లేదు.",
        "compare-revision-not-exists": "మీరు పేర్కొన్న కూర్పు లేనే లేదు.",
        "diff-form": "తేడాలు",
+       "diff-form-oldid": "పాత కూర్పు ID (ఐచ్ఛికం)",
+       "diff-form-submit": "తేడాలను చూపించు",
+       "permanentlink": "స్థిర లంకె",
+       "permanentlink-revid": "కూర్పు ID",
+       "permanentlink-submit": "కూర్పుకు వెళ్ళు",
        "dberr-problems": "క్షమించండి! ఈ సైటు సాంకేతిక సమస్యలని ఎదుర్కొంటుంది.",
        "dberr-again": "కొన్ని నిమిషాలాగి మళ్ళీ ప్రయత్నించండి.",
        "dberr-info": "(డేటాబేసును చేరలేకున్నాం: $1)",
        "htmlform-date-invalid": "మీరిచ్చిన విలువ ఆమోదిత తేదీ రూపంలో లేదు. YYYY-MM-DD ఆకృతిని వాడి చూడండి.",
        "htmlform-time-invalid": "మీరిచ్చిన విలువ ఆమోదిత సమయం రూపంలో లేదు. HH:MM:SS ఆకృతిని వాడి చూడండి.",
        "htmlform-datetime-invalid": "మీరిచ్చిన విలువ ఆమోదిత తేదీ, సమయం రూపంలో లేదు. YYYY-MM-DD HH:MM:SS ఆకృతిని వాడి చూడండి.",
+       "htmlform-date-toolow": "మీరిచ్చిన విలువ అత్యంత పాత తేదీ, $1 కన్నా ముందుది.",
+       "htmlform-date-toohigh": "మీరిచ్చిన విలువ అత్యంత ఇటీవలి తేదీ, $1 కన్నా తరువాతది.",
+       "htmlform-time-toolow": "మీరిచ్చిన విలువ అత్యంత పాత సమయం, $1 కన్నా ముందుది.",
+       "htmlform-time-toohigh": "మీరిచ్చిన విలువ అత్యంత ఇటీవలి సమయం, $1 కన్నా తరువాతది.",
+       "htmlform-datetime-toolow": "మీరిచ్చిన విలువ అత్యంత పాత తేదీ, సమయం - $1 - కన్నా ముందుది.",
+       "htmlform-datetime-toohigh": "మీరిచ్చిన విలువ అత్యంత ఇటీవలి తేదీ, సమయం - $1 - కన్నా తరువాతది.",
        "htmlform-title-badnamespace": "[[:$1]], \"{{ns:$2}}\" పేరుబరిలో లేదు.",
        "htmlform-title-not-creatable": "\"$1\" అనే పేజీ పేరు సృష్టించదగ్గది కాదు",
        "htmlform-title-not-exists": "$1 ఉనికిలో లేదు.",
        "log-name-managetags": "ట్యాగు నిర్వహణ చిట్టా",
        "log-description-managetags": "ఈ పేజీ [[Special:Tags|ట్యాగులకు]] సంబంధించిన నిర్వహణ పనులను చూపిస్తుంది. నిర్వాహకులు మానవికంగా చేసిన పనులు మాత్రమే ఈ లాగ్‌లో ఉంటాయి; వికీ సాఫ్టువేరు, ఈ లాగ్‌లో నమోదు కాకుండానే కొత్త ట్యాగులను సృష్టించడం, తొలగించడం చేయవచ్చు.",
        "logentry-managetags-create": "\"$4\" ట్యాగును $1 {{GENDER:$2|సృష్టించారు}}",
+       "logentry-managetags-delete": "\"$4\" ట్యాగును $1 {{GENDER:$2|తొలగించారు}} ($5 {{PLURAL:$5|కూర్పు లేదా చిట్టా పద్దు|కూర్పులు లేదా చిట్టా పద్దుల}} నుండి తీసివేసారు)",
+       "logentry-managetags-activate": "\"$4\" ట్యాగును $1, వాడుకరులు, బాట్‌ల వాడుక కొరకు {{GENDER:$2|చేతనం చేసారు}}",
+       "logentry-managetags-deactivate": "\"$4\" ట్యాగును $1, వాడుకరులు, బాట్‌ల వాడుక కొరకు {{GENDER:$2|అచేతనం చేసారు}}",
        "log-name-tag": "ట్యాగుల చిట్టా",
+       "log-description-tag": "వాడుకరులు కూర్పులకు, చిట్టా పద్దులకూ [[Special:Tags|ట్యాగులను]] ఎప్పుడు చేర్చారో, తీసివేసారో ఈ పేజీలో చూడవచ్చు. పేజీలో దిద్దుబాట్లు, తొలగింపులు వగైరా చర్యలు జరిగినపుడు జరిగే ట్యాగు చర్యలను ఇది చూపించదు.",
+       "logentry-tag-update-add-revision": "$1, $3 పేజీకి చెందిన $4 కూర్పుకు $6 {{PLURAL:$7|ట్యాగు|ట్యాగుల}}ను {{GENDER:$2|చేర్చారు}}",
+       "logentry-tag-update-add-logentry": "$1, $3 పేజీకి చెందిన $5 చిట్టా పద్దుకు $6 {{PLURAL:$7|ట్యాగు|ట్యాగుల}}ను {{GENDER:$2|చేర్చారు}}",
+       "logentry-tag-update-remove-revision": "$1, $3 పేజీకి చెందిన $4 కూర్పు నుండి $8 {{PLURAL:$9|ట్యాగు|ట్యాగుల}}ను {{GENDER:$2|తీసివేసారు}}",
+       "logentry-tag-update-remove-logentry": "$1, $3 పేజీకి చెందిన $5 చిట్టా పద్దు నుండి $8 {{PLURAL:$9|ట్యాగు|ట్యాగుల}}ను {{GENDER:$2|తీసివేసారు}}",
+       "logentry-tag-update-revision": "$1 $3 పేజీకి చెందిన $4 కూర్పు ట్యాగులను {{GENDER:$2|తాజాకరించారు}}; ($6 ను {{PLURAL:$7|చేర్చారు}}; $8 ను {{PLURAL:$9|తీసివేసారు}})",
+       "logentry-tag-update-logentry": "$1, $3 పేజీకి చెందిన $5 చిట్టా పద్దు ట్యాగులను {{GENDER:$2|తాజాకరించారు}} ($6 ను {{PLURAL:$7|చేర్చారు}}; $8 ను {{PLURAL:$9|తీసివేసారు}})",
        "rightsnone": "(ఏమీలేవు)",
        "rightslogentry-temporary-group": "$1 (తాత్కాలికం, $2 వరకు)",
        "feedback-adding": "ఫీడ్‍బ్యాకును పేజీలోకి చేరుస్తున్నాం...",
        "searchsuggest-search": "{{SITENAME}}‌లో వెతకండి",
        "searchsuggest-containing": "కలిగియున్న...",
        "api-error-badtoken": "అంతర్గత లోపం: చెడు టోకెన్.",
-       "api-error-emptypage": "à°\95à±\8aà°¤à±\8dà°¤ à°®à°°à°¿à°¯à±\81 à°\96ాళà±\80 పేజీలను సృష్టించడానికి అనుమతి లేదు.",
+       "api-error-emptypage": "à°\96ాళà±\80 à°\95à±\8aà°¤à±\8dà°¤పేజీలను సృష్టించడానికి అనుమతి లేదు.",
        "api-error-publishfailed": "అంతర్గత లోపం: తాత్కాలిక ఫైలును ప్రచురించడంలో సర్వరు విఫలమైంది.",
        "api-error-stashfailed": "అంతర్గత లోపం: తాత్కాలిక దస్త్రాన్ని భద్రపరచడంలో సేవకి విఫలమైంది.",
        "api-error-unknown-warning": "తెలియని హెచ్చరిక: \"$1\".",
        "limitreport-templateargumentsize-value": "$1/$2 {{PLURAL:$2|బైటు|బైట్లు}}",
        "limitreport-expansiondepth": "గరిష్ట విస్తరణ లోతు",
        "limitreport-expensivefunctioncount": "ఖరీదైన పార్సర్ ఫంక్షన్ల సంఖ్య",
+       "limitreport-unstrip-size-value": "$1/$2 {{PLURAL:$2|బైటు|బైట్లు}}",
        "expandtemplates": "మూసలను విస్తరించు",
        "expand_templates_intro": "ఈ ప్రత్యేక పేజీ మీరిచ్చిన మూసలను పూర్తిగా విస్తరించి, చూపిస్తుంది. ఇది <code><nowiki>{{</nowiki>#language:...}}</code> వంటి పార్సరు ఫంక్షన్లను, <code><nowiki>{{</nowiki>CURRENTDAY}}</code> వంటి చరరాశులను (వేరియబుల్) కూడా విస్తరిస్తుంది. \nనిజానికి ఇది మీసాల బ్రాకెట్లలో ఉన్న ప్రతీదాన్నీ విస్తరిస్తుంది.",
        "expand_templates_title": "{{FULLPAGENAME}} మొదలగు వాటి కొరకు సందర్భ శీర్షిక:",
        "mw-widgets-titleinput-description-redirect": "$1 కు దారిమార్పు",
        "mw-widgets-categoryselector-add-category-placeholder": "ఓ వర్గాన్ని చేర్చండి...",
        "mw-widgets-usersmultiselect-placeholder": "మరిన్ని చేర్చండి...",
+       "date-range-from": "తేదీ నుండి",
+       "date-range-to": "తేదీ వరకు",
        "sessionprovider-generic": "$1 సెషన్లు",
        "sessionprovider-mediawiki-session-cookiesessionprovider": "కూకీ-ఆధారిత సెషన్లు",
        "log-action-filter-block": "నిరోధపు రకం:",
+       "log-action-filter-delete": "తొలగింపు రకం:",
+       "log-action-filter-move": "తరలింపు రకం:",
        "log-action-filter-all": "అన్నీ",
        "log-action-filter-managetags-create": "ట్యాగు సృష్టి",
        "log-action-filter-managetags-delete": "ట్యాగు తొలగింపు",
        "log-action-filter-managetags-activate": "ట్యాగు చేతనం",
        "log-action-filter-managetags-deactivate": "ట్యాగు అచేతనం",
+       "log-action-filter-protect-protect": "సంరక్షణ",
+       "log-action-filter-upload-upload": "కొత్త ఎక్కింపు",
        "authmanager-userdoesnotexist": "వాడుకరి ఖాతా \"$1\" నమోదయి లేదు.",
        "authmanager-userlogin-remembermypassword-help": "సెషను ముగిసిన తరువాత కూడా సంకేతపదాన్ని గుర్తుంచుకోమంటారా",
        "authmanager-username-help": "ధ్రువీకరణ కోసం వాడుకరిపేరు.",
        "authprovider-resetpass-skip-label": "దాటవేయి",
        "cannotauth-not-allowed-title": "అనుమతి నిరాకరించబడింది",
        "cannotauth-not-allowed": "ఈ పేజీ వాడుకునే అనుమతి మీకు లేదు",
+       "changecredentials": "యోగ్యతలను మార్చుకోవడం",
+       "changecredentials-submit": "యోగ్యతలను మార్చుకోవడం",
        "changecredentials-invalidsubpage": "$1 సరైన అర్హత కాదు",
        "changecredentials-success": "మీ అర్హతలను మార్చాం.",
        "removecredentials": "అర్హతలను తీసివెయ్యి",
        "restrictionsfield-badip": "అసంబద్ధమైన ఐపీ అడ్రసు లేదా శ్రేణి: $1",
        "restrictionsfield-label": "అనుమతించబడ్డ ఐపీ శ్రేణులు:",
        "restrictionsfield-help": "వరుసకొక్క ఐపీ అడ్రసు లేదా CIDR శ్రేణి. ప్రతీ ఒక్కదాన్నీ చేతనం చేసేందుకు, వాడండి:<pre>0.0.0.0/0\n::/0</pre>",
+       "edit-error-short": "లోపం: $1",
+       "edit-error-long": "లోపాలు:\n\n$1",
        "revid": "కూర్పు $1",
-       "pageid": "పేజీ ఐడీ $1"
+       "pageid": "పేజీ ఐడీ $1",
+       "gotointerwiki": "{{SITENAME}} ను వీడిపోతున్నారు",
+       "gotointerwiki-invalid": "ఇచ్చిన శీర్షిక సరైనది కాదు.",
+       "gotointerwiki-external": "మీరు {{SITENAME}} ను వదలి [[$2]] కు వెళ్తున్నారు. అది వేరే సైటు.\n\n'''[$1 $1 కు తీసుకుపో]'''",
+       "undelete-cantedit": "ఈ పేజీ తొలగింపును రద్దు చెయ్యలేరు. ఎందుకంటే ఈ పేజీలో మార్పుచేర్పులు చేసే అనుమతి మీకు లేదు.",
+       "undelete-cantcreate": "ఈ పేజీ తొలగింపును రద్దు చెయ్యలేరు. ఎందుకంటే ఈ పేరుతో పేజీ లేదు, దాన్ని సృష్టించే అనుమతి మీకు లేదు.",
+       "pagedata-title": "పేజీ డేటా",
+       "pagedata-bad-title": "చెల్లని శీర్షిక: $1.",
+       "passwordpolicies": "సంకేతపదపు విధానాలు",
+       "passwordpolicies-summary": "ఈ వికీలో నిర్వ్చించిన వాడుకరి గుంపులకు వర్తించే సంకేతపద విధానాల జాబితా ఇది.",
+       "passwordpolicies-group": "సమూహం",
+       "passwordpolicies-policies": "విధానాలు",
+       "passwordpolicies-policy-minimalpasswordlength": "సంకేతపదం కనీసం $1 {{PLURAL:$1|క్యారెక్టరు|క్యారెక్టర్ల}} పొడవు ఉండాలి",
+       "passwordpolicies-policy-minimumpasswordlengthtologin": "లాగినవ్వాలంటే సంకేతపదం కనీసం $1 {{PLURAL:$1|క్యారెక్టరు|క్యారెక్టర్ల}} పొడవు ఉండాలి",
+       "passwordpolicies-policy-passwordcannotmatchusername": "సంకేతపదం, వాడుకరిపేరూ ఒకటే ఉండే వీల్లేదు.",
+       "passwordpolicies-policy-passwordcannotmatchblacklist": "సంకేతపదం నిషేధించిన సంకేతపదాలతో సరిపోలరాదు",
+       "passwordpolicies-policy-maximalpasswordlength": "సంకేతపదం $1 {{PLURAL:$1|క్యారెక్టరు|క్యారెక్టర్ల}} పొడవు కంటే తక్కువ ఉండాలి",
+       "passwordpolicies-policy-passwordcannotbepopular": "సంకేతపదం {{PLURAL:$1|ప్రజాదరణ పొందిన సంకేతపదం కారాదు|ప్రజాదరణ పొందిన $1 సంకేతపదాల్లో ఉండరాదు}}"
 }
index 56000b2..8c7b63a 100644 (file)
@@ -5,7 +5,8 @@
                        "Nemo bis",
                        "Reedy",
                        "아라",
-                       "Matma Rex"
+                       "Matma Rex",
+                       "Raphael Merx"
                ]
        },
        "tog-underline": "Subliña ligasaun sira:",
        "recentchanges-label-newpage": "Pájina foun",
        "recentchanges-label-minor": "Ne'e mudansa ki'ik",
        "recentchanges-label-bot": "Edita husi prosesu automátiku (\"bot\")",
+       "rcfilters-activefilters-hide": "Subar",
+       "rcfilters-activefilters-show": "Hatudu",
+       "rcfilters-savedqueries-remove": "Hapus",
        "rcshowhideminor": "$1 muda ki-ki'ik",
        "rcshowhideminor-show": "Hatudu",
        "rcshowhidebots": "$1 bot sira",
        "whatlinkshere": "Artigu sira ne'ebé bá iha ne'e",
        "whatlinkshere-title": "Pájina sira ne'ebé bá \"$1\".",
        "whatlinkshere-page": "Pájina:",
-       "linkshere-2": "Pájina sira ne'e link ba '''$1''':",
+       "linkshere": "Pájina sira ne'e link ba '''$1''':",
        "isimage": "ligasaun ba fixeiru",
        "whatlinkshere-prev": "{{PLURAL:$1|oinmai|oinmai $1}}",
        "whatlinkshere-next": "{{PLURAL:$1|molok|molok $1}}",
index c7931cf..5a70fa6 100644 (file)
        "whatlinkshere": "Пайвандҳои дар ин сахифа",
        "whatlinkshere-title": "Саҳифаҳое ки ба $1 пайванд доранд",
        "whatlinkshere-page": "Саҳифа:",
-       "linkshere-2": "Саҳифаҳои зерин ба '''$1''' пайванданд:",
-       "nolinkshere-2": "Ягон саҳифа ба '''$1''' пайванд нест.",
-       "nolinkshere-ns-2": "Ҳеҷ саҳифа аз фазоиноми интихобшуда ба '''$1''' пайванд надорад.",
+       "linkshere": "Саҳифаҳои зерин ба '''$1''' пайванданд:",
+       "nolinkshere": "Ягон саҳифа ба '''$2''' пайванд нест.",
+       "nolinkshere-ns": "Ҳеҷ саҳифа аз фазоиноми интихобшуда ба '''$2''' пайванд надорад.",
        "isredirect": "саҳифаи тағйири масир",
        "istemplate": "истифодашуда дар саҳифа",
        "isimage": "пайванд ба парванда",
index 129b5a4..7839f18 100644 (file)
        "whatlinkshere": "Pajvandhoi dar in saxifa",
        "whatlinkshere-title": "Sahifahoe ki ba $1 pajvand dorand",
        "whatlinkshere-page": "Sahifa:",
-       "linkshere-2": "Sahifahoi zerin ba '''$1''' pajvandand:",
-       "nolinkshere-2": "Jagon sahifa ba '''$1''' pajvand nest.",
-       "nolinkshere-ns-2": "Heç sahifa az fazoinomi intixobşuda ba '''$1''' pajvand nadorad.",
+       "linkshere": "Sahifahoi zerin ba '''$1''' pajvandand:",
+       "nolinkshere": "Jagon sahifa ba '''$2''' pajvand nest.",
+       "nolinkshere-ns": "Heç sahifa az fazoinomi intixobşuda ba '''$2''' pajvand nadorad.",
        "isredirect": "sahifai taƣjiri masir",
        "istemplate": "istifodaşuda dar sahifa",
        "isimage": "pajvandi aks",
index 9671e93..6043bae 100644 (file)
        "whatlinkshere": "หน้าที่ลิงก์มา",
        "whatlinkshere-title": "หน้าที่ลิงก์มา \"$1\"",
        "whatlinkshere-page": "หน้า:",
-       "linkshere-2": "หน้าต่อไปนี้ลิงก์มา <strong>$1</strong>:",
-       "nolinkshere-2": "ไม่มีหน้าใดลิงก์มา <strong>$1</strong>",
-       "nolinkshere-ns-2": "ไม่มีหน้าใดลิงก์มา <strong>$1</strong> ในเนมสเปซที่เลือก",
+       "linkshere": "หน้าต่อไปนี้ลิงก์มา <strong>$1</strong>:",
+       "nolinkshere": "ไม่มีหน้าใดลิงก์มา <strong>$2</strong>",
+       "nolinkshere-ns": "ไม่มีหน้าใดลิงก์มา <strong>$2</strong> ในเนมสเปซที่เลือก",
        "isredirect": "หน้าเปลี่ยนทาง",
        "istemplate": "โดยใช้แม่แบบ",
        "isimage": "ลิงก์ไฟล์",
        "markedaspatrollederrornotify": "การทำเครื่องหมายว่าตรวจสอบแล้วล้มเหลว",
        "patrol-log-page": "ปูมการตรวจสอบ",
        "patrol-log-header": "หน้านี้คือปูมรุ่นการแก้ไขที่กำหนดว่าตรวจสอบแล้ว",
-       "log-show-hide-patrol": "$1 ปูมการตรวจสอบ",
-       "log-show-hide-tag": "$1ปูมป้ายระบุ",
        "confirm-markpatrolled-button": "ตกลง",
        "confirm-markpatrolled-top": "ทำเครื่องหมายรุ่น $3 ของ $2 ว่าตรวจสอบแล้วหรือไม่",
        "deletedrevision": "รุ่นเก่าที่ถูกลบ $1",
index 6d99da1..eff94a5 100644 (file)
        "whatlinkshere": "Şu ýere çykgytlar",
        "whatlinkshere-title": "\"$1\" makalasyna çykgyt berýän sahypalar",
        "whatlinkshere-page": "Sahypa:",
-       "linkshere-2": "'''$1''' sahypasyna çykgyt berýän sahypalar:",
-       "nolinkshere-2": "'''$1''' sahypasyna çykgyt berýän sahypa ýok.",
-       "nolinkshere-ns-2": "Saýlanyp alynan at giňişliginde hiçbir sahypa '''$1''' sahypasyna çykgyt bermeýär.",
+       "linkshere": "'''$1''' sahypasyna çykgyt berýän sahypalar:",
+       "nolinkshere": "'''$2''' sahypasyna çykgyt berýän sahypa ýok.",
+       "nolinkshere-ns": "Saýlanyp alynan at giňişliginde hiçbir sahypa '''$2''' sahypasyna çykgyt bermeýär.",
        "isredirect": "gönükdirme sahypasy",
        "istemplate": "atanaklaýyn girizme",
        "isimage": "faýl çykgydy",
        "markedaspatrollederror-noautopatrol": "Öz üýtgeşmeleriňizi patrullyk edilen diýip bellemekligiňize rugsat berilmeýär.",
        "patrol-log-page": "Patrullyk gündeligi",
        "patrol-log-header": "Bu patrullyk edilen wersiýalaryň gündeligidir.",
-       "log-show-hide-patrol": "Patrullyk gündeligini $1",
        "deletedrevision": "$1 köne wersiýasy öçürildi.",
        "filedeleteerror-short": "Faýl öçürmek säwligi: $1",
        "filedeleteerror-long": "Faýl öçürilýän mahaly säwlikler ýüze çykdy:\n\n$1",
index d3c3087..f8d296b 100644 (file)
        "redirectedfrom": "(Nakaturo mula sa $1)",
        "redirectpagesub": "Pahinang panuro",
        "redirectto": "Papuntahin sa:",
-       "lastmodifiedat": "Huling binago ang pahinang ito noong $1 ng $2.",
+       "lastmodifiedat": "Huling binago ang pahinang ito noong $1, noong $2.",
        "viewcount": "Namataan ang pahinang ito nang {{PLURAL:$1|isang|$1}} beses.",
        "protectedpage": "Pahinang nakasanggalang",
        "jumpto": "Tumalon sa:",
        "nstab-media": "Pahina ng midya",
        "nstab-special": "Natatanging pahina",
        "nstab-project": "Pahina ng proyekto",
-       "nstab-image": "File",
+       "nstab-image": "Talaksan",
        "nstab-mediawiki": "Mensahe",
        "nstab-template": "Padron",
        "nstab-help": "Pahina ng tulong",
        "createacct-another-username-ph": "Ilagay ang Pangalan",
        "yourpassword": "Password:",
        "userlogin-yourpassword": "Password",
-       "userlogin-yourpassword-ph": "Ipasok ang iyong password",
-       "createacct-yourpassword-ph": "Ilagay ang password",
+       "userlogin-yourpassword-ph": "Ipasok ang iyong hudyat",
+       "createacct-yourpassword-ph": "Ilagay ang hudyat",
        "yourpasswordagain": "Password mo uli:",
-       "createacct-yourpasswordagain": "Tiyakin ang password",
-       "createacct-yourpasswordagain-ph": "Muling ilagay ang password",
-       "userlogin-remembermypassword": "Panatilihin akong naka-login",
+       "createacct-yourpasswordagain": "Tiyakin ang hudyat",
+       "createacct-yourpasswordagain-ph": "Muling ilagay ang hudyat",
+       "userlogin-remembermypassword": "Panatilihin akong nakalagda",
        "userlogin-signwithsecure": "Gumamit ng ligtas na koneksyon",
        "cannotlogin-title": "Hindi maka-log in",
        "cannotlogin-text": "Imposible and pag-log in.",
        "logout": "Umalis sa pagkaka-login",
        "userlogout": "Umalis sa pagkaka-login",
        "notloggedin": "Hindi naka-login",
-       "userlogin-noaccount": "Wala ka pa bang account?",
+       "userlogin-noaccount": "Wala ka pa bang kuwenta?",
        "userlogin-joinproject": "Sumali sa {{SITENAME}}",
        "createaccount": "Lumikha ng account",
-       "userlogin-resetpassword-link": "Nakalimutan ba ang iyong password?",
-       "userlogin-helplink2": "Tulong sa pag-login",
+       "userlogin-resetpassword-link": "Nakalimutan ba ang iyong hudyat?",
+       "userlogin-helplink2": "Tulong sa paglagda",
        "userlogin-loggedin": "Naka-login ka na bilang {{GENDER:$1|$1}}. Gamitin ang form sa ibaba upang maka-login bilang ibang tagagamit o user.",
        "userlogin-reauth": "Kailangan mong mag-log in muli para mapatunayan na ikaw si {{GENDER:$1|$1}}.",
        "userlogin-createanother": "Lumikha ng iba pang account",
        "createacct-emailrequired": "Direksiyong e-liham:",
-       "createacct-emailoptional": "Email (hindi kailangan)",
-       "createacct-email-ph": "Ipasok ang iyong email address",
+       "createacct-emailoptional": "Direksiyong e-liham (hindi kailangan)",
+       "createacct-email-ph": "Ipasok ang iyong direksiyong e-liham",
        "createacct-another-email-ph": "Ipasok ang email address",
        "createaccountmail": "Gumamit ng pansamantalang random na password at ipadala ito sa email na nakasaad sa ibaba",
        "createaccountmail-help": "Maaaring magamit para gumawa ng account para sa isang tao ng hindi nalalaman ang password.",
        "createacct-reason": "Dahilan",
        "createacct-reason-ph": "Bakit ka gagawa ng isa pang account?",
        "createacct-reason-help": "Mensaheng ipinapakita sa listahan ng paggawa ng account",
-       "createacct-submit": "Likhain ang iyong account",
+       "createacct-submit": "Likhain ang iyong kuwenta",
        "createacct-another-submit": "Lumikha ng account",
        "createacct-continue-submit": "Ituloy ang paggawa ng account",
        "createacct-another-continue-submit": "Ituloy ang paggawa ng account",
        "loginlanguagelabel": "Wika: $1",
        "suspicious-userlogout": "Tinanggihan ang inyong kahilingang umalis sa pagkalagda dahil tila ito ay ipinadala ng sirang pambasa-basa o apoderadong pambaon (''caching proxy'')",
        "createacct-another-realname-tip": "Hindi kinakailangan ang tunay na pangalan.\nKung nais mo na ibigay ito, gagamitin ito para sa pagbibigay ng atribusyon para sa kanilang gawa.",
-       "pt-login": "Mag-login",
-       "pt-login-button": "Mag-login",
+       "pt-login": "Lumagda",
+       "pt-login-button": "Lumagda",
        "pt-login-continue-button": "Magpatuloy sa paglagda",
-       "pt-createaccount": "Lumikha ng account",
+       "pt-createaccount": "Lumikha ng kuwenta",
        "pt-userlogout": "Umalis sa pagkakatala",
        "php-mail-error-unknown": "Hindi malamang kamalian sa tungkulin ng liham ng PHP ()",
        "user-mail-no-addy": "Sinubukang magpadala ng e-liham na walang tirahan na para sa e-liham.",
        "resetpass-expired": "Paso na ang iyong password. Pakipalit ng bagong password upang maka-login.",
        "resetpass-expired-soft": "Napaso na ang iyong password at kailangan i-reset. Pumili ng bagong password o i-klik ang \"{{int:authprovider-resetpass-skip-label}}\" upang i-reset sa ibang pagkakataon.",
        "resetpass-validity-soft": "Hindi matanggap ang iyong password: $1\n\nPumili ng bagong password ngayon, o i-klik ang \"{{int:authprovider-resetpass-skip-label}}\" para i-reset ito sa ibang pagkakataon.",
-       "passwordreset": "Muling pagtatakda ng password",
+       "passwordreset": "Muling pagtatakda ng hudyat",
        "passwordreset-text-one": "Ikumpleto ang form na ito upang makatanggap ng pansamantalang password sa pamamagitan ng email.",
        "passwordreset-text-many": "{{PLURAL:$1|Ipasok sa isa sa mga field upang makatanggap ng isang pansamantalang password sa pamamagitan ng email.}}",
        "passwordreset-disabled": "Hindi pinagagana sa wiking ito ang muling mga pagtatakda ng password.",
        "nowiki_sample": "Isingit ang hindi nakapormat na teksto dito",
        "nowiki_tip": "Balewalain ang pormat na pangwiki",
        "image_sample": "Halimbawa.jpg",
-       "image_tip": "File na naka-embed",
+       "image_tip": "Talaksang nakabaon",
        "media_sample": "Halimbawa.ogg",
-       "media_tip": "Link ng file",
+       "media_tip": "Kawing ng talaksan",
        "sig_tip": "Lagda mo na may tatak ng oras",
        "hr_tip": "Pahalagang na guhit (gamitin nang madalang)",
        "summary": "Buod:",
        "summary-preview": "Paunang tingin sa buod:",
        "subject-preview": "Paunang tingin sa paksa:",
        "blockedtitle": "Hinarang ang tagagamit",
-       "blockedtext": "'''Hinarang/hinadlangan ang iyong pangalan ng tagagamit o direksiyong IP.'''\n\nGinawa ni $1 ang pagharang/paghadlang.\nIto ang ibinigay na dahilan: ''$2''.\n\n* Simula ng pagharang/paghadlang: $8\n* Katapusan ng pagharang/paghadlang: $6\n* Ang hinarang/hinadlangan ay si: $7\n\nMaaari kang makipag-ugnayan kay $1 o sa ibang [[{{MediaWiki:Grouppage-sysop}}|tagapangasiwa]] upang pagusapan ang pagharang/paghadlang na ito.\nHindi mo magagamit ang kasangkapang-katangiang 'magpadala ng e-liham sa tagagamit' hangga't hindi tinutukoy ang isang tanggap na direksiyong e-liham sa iyong [[Special:Preferences|mga kagustuhan]] at hindi ka pa hinaharangan/hinahadlangan sa paggamit nito.\nAng kasalukuyan mong direksiyong IP ay $3, at ang ID ng pagharang/paghadlang ay #$5.\nPakisama ang lahat ng mga detalye sa anumang mga pagtatanong na ginagawa/gagawin mo.",
+       "blockedtext": "<strong>Hinarang ang iyong pangalan ng tagagamit o direksiyong IP.</strong>\n\nGinawa ni $1 ang pagharang.\nIto ang ibinigay na dahilan: ''<em>$2</em>''.\n\n* Simula ng pagharang: $8\n* Katapusan ng pagharang: $6\n* Ang balak iharang: $7\n\nMaaari kang makipag-ugnayan kay $1 o sa ibang [[{{MediaWiki:Grouppage-sysop}}|tagapangasiwa]] upang pagusapan ang pagharang na ito.\nHindi mo magagamit ang kagamitang \"{{int:emailuser}}\" maliban kung may isang tanggap na direksiyong e-liham na nakatukoy sa iyong [[Special:Preferences|mga kagustuhan]] at hindi ka pa hinaharangan sa paggamit nito.\nAng kasalukuyan mong direksiyong IP ay $3, at ang ID ng pagharang ay #$5.\nPakisama ang lahat ng mga detalye sa anumang mga pagtatanong na ginagawa o gagawin mo.",
        "autoblockedtext": "Kusang hinadlangan/hinarang ang direksiyong IP mo dahil ginamit ito ng ibang tagagamit, na hinadlangan/hinarang ni $1.\nAng ibinigay na dahilan ay:\n\n:''$2''\n\n* Simula ng pagharang: $8\n* Katapusan ng pagharang: $6\n* Ang hinadlangang ay si: $7\n\nMaaari kang makipagugnayan kay $1 o sa isa sa iba pang [[{{MediaWiki:Grouppage-sysop}}|mga tagapangasiwa]] para pagusapan ang paghadlang/pagharang.\n\nPakitandaang hindi mo maaaring gamitin ang kasangkapang-katangiang \"padalhan ng e-liham ang tagagamit na ito\" maliban na lamang kung mayroon kang nakatalang tanggap na direksiyong e-liham sa iyong [[Special:Preferences|mga kagustuhan]] at hindi ka hinadlangan sa paggamit nito.\n\nAng kasalukuyan mong direksiyong IP ay $3, at ang ID ng pagharang ay #$5.\nPakisama ang lahat ng mga detalyeng nasa itaas sa anumang pagtatanong na gagawin mo.",
        "blockednoreason": "walang binigay na dahilan",
        "whitelistedittext": "Kailangan mong $1 para makapagbago ng mga pahina.",
        "semiprotectedpagewarning": "'''Paunawa: Ikinandado ang pahinang ito upang mga nakatalang tagagamit lamang ang makakapagbago nito.'''\nAng pinakahuling entrada sa talaan ay ibinigay sa baba para sa iyong pagsasangguni:",
        "cascadeprotectedwarning": "'''Babala:''' Ikinandado ang pahinang ito upang tanging mga tagagamit na may mga karapatang pang-''sysop'' lamang ang makapagbago nito, dahil kabilang ito sa sumusunod na mga {{PLURAL:$1|pahinang|mga pahinang}} may baita-baitang na panananggalang:",
        "titleprotectedwarning": "'''Babala:  Ikinandado ang pahinang ito upang [[Special:ListGroupRights|partikular na mga karapatan]] ang kakailanganin upang mailikha ito.'''\nAng pinakahuling entrada sa talaan ay ibinigay sa baba para sa inyong pagsasangguni:",
-       "templatesused": "{{PLURAL:$1|Padron|Mga padron}} na ginagamit sa pahinang ito:",
-       "templatesusedpreview": "{{PLURAL:$1|Suleras|Mga suleras}} na ginagamit sa paunang-tinging ito:",
+       "templatesused": "{{PLURAL:$1|Padrong|Mga padrong}} ginagamit sa pahinang ito:",
+       "templatesusedpreview": "{{PLURAL:$1|Padrong|Mga padrong}} ginagamit sa paunang-tinging ito:",
        "templatesusedsection": "{{PLURAL:$1|Suleras|Mga suleras}} na ginamit sa seksyong ito:",
        "template-protected": "(nakasanggalang)",
        "template-semiprotected": "(bahagyang nakasanggalang)",
        "nocreate-loggedin": "Wala kang pahintulot para lumikha ng bagong mga pahina.",
        "sectioneditnotsupported-title": "Hindi sinusuportahan ang pagpapatnugot ng seksyon",
        "sectioneditnotsupported-text": "Hindi sinusuportahan ang pagpapatnugot ng seksyon sa pahinang ito.",
-       "permissionserrors": "Mga kamalian sa mga pahintulot",
+       "permissionserrors": "Kamalian sa pahintulot",
        "permissionserrorstext": "Wala kang pahintulot na gawin iyan, dahil sa sumusunod na {{PLURAL:$1|dahilan|mga dahilan}}:",
        "permissionserrorstext-withaction": "Wala kang pahintulot na $2, dahil sa sumusunod na {{PLURAL:$1|dahilan|mga dahilan}}:",
        "recreate-moveddeleted-warn": "'''Babala: Muli mong nililikha ang isang pahinang binura na dati.'''\n\nDapat mong isaalang-alang kung nararapat bang ipagpatuloy ang pagbago sa pahinang ito.\nAng tala ng pagbubura at paglilipat para sa pahinang ito ay ibinigay dito para sa kaginhawaan:",
        "compareselectedversions": "Paghambingin ang mga napiling bersyon",
        "showhideselectedversions": "Ipakita/itago ang napiling mga bersyon",
        "editundo": "ibalik",
+       "diff-empty": "(Walang pagkakaiba)",
        "diff-multi-manyusers": "({{PLURAL:$1|Isang panggitnang pagbabago|$1 panggitnang mga pagbabago}} ng {{PLURAL:$2|isang tagagamit|$2 mga tagagamit}} ang hindi ipinapakikita.)",
        "difference-missing-revision": "Hindi natagpuan ang {{PLURAL:$2|isang rebisyon|$2 mga rebisyon}} ng kaibahang ($1) ito.\n\nKaraniwang itong isinanhi ng pagsunod sa isang wala na sa panahong kawing sa pagkakaiba na papunta sa isang pahinang nabura na.\nMatatagpuan ang mga detalye sa loob ng [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} talaan ng pagbura].",
        "searchresults": "Kinalabasan/Resulta ng paghahanap",
        "searchprofile-advanced-tooltip": "Hanapin sa pinasadyang mga espasyo ng pangalan",
        "search-result-size": "$1 ({{PLURAL:$2|1 salita|$2 salita}})",
        "search-result-category-size": "{{PLURAL:$1|isang kasapi|$1 mga kasapi}} ({{PLURAL:$2|isang subkategorya|$2 mga subkategorya}}, {{PLURAL:$3|isang talaksan|$3 mga talaksan}})",
-       "search-redirect": "(Nakaturo mula sa $1)",
+       "search-redirect": "(pagkarga mula sa $1)",
        "search-section": "(seksyong $1)",
+       "search-file-match": "(tugma sa nilalaman ng talaksan)",
        "search-suggest": "Ito ba ang ibig mong sabihin: $1",
        "search-interwiki-caption": "Kapatid na mga proyekto",
        "search-interwiki-default": "$1 mga resulta:",
        "recentchangeslinked-summary": "Ito ang tala ng mga pagbabagong ginawa kamakailan sa mga pahinang naka-link mula sa isang tinukoy na pahina (o sa mga kasapi ng isang tinukoy na kategorya). <strong>Makapal na teksto</strong> ang mga pahinang [[Special:Watchlist|iyong mga binabantayan]].",
        "recentchangeslinked-page": "Pangalan ng pahina:",
        "recentchangeslinked-to": "Ipakita ang mga pagbabago sa mga pahinang nakaugnay sa isang binigay na pahina sa halip",
-       "upload": "Mag-upload ng file",
+       "upload": "Magkarga ng talaksan",
        "uploadbtn": "Mag-upload ng file",
        "reuploaddesc": "Kanselahin/Iurong ang pagkarga at magbalik sa pormularyo ng pagkakarga",
        "upload-tryagain": "Ipasa ang binagong paglalarawan ng talaksan",
        "http-timed-out": "Huminto ang kahilingang HTTP.",
        "http-curl-error": "Kamalian sa pagsalok ng URL: $1",
        "http-bad-status": "Nagkaroon ng suliranin habang hinihiling ang HTTP na: $1 $2",
+       "http-internal-error": "Kamaliang panloob ng HTTP.",
        "upload-curl-error6": "Hindi marating ang URL",
        "upload-curl-error6-text": "Hindi marating ang ibinigay na URL.\nPakisuring muli kung tama ang URL at kung buhay ang sityo/sayt.",
        "upload-curl-error28": "Pahinga sa pagkakarga",
        "upload_source_file": " (isang talaksan sa iyong kompyuter)",
        "listfiles-summary": "Ipinapakita ng natatanging pahinang ito ang lahat ng naikargang mga talaksan.\nKapag sinala ng tagagamit, tanging mga talaksan lang kung saan nagkarga ang tagagamit na iyan ng pinaka kamakailang bersiyon ng talaksan ang ipinapakita.",
        "listfiles_search_for": "Hanapin ang pangalan ng midya:",
-       "imgfile": "file",
+       "imgfile": "talaksan",
        "listfiles": "Talaan ng file",
        "listfiles_thumb": "Kagyat",
        "listfiles_date": "Petsa",
        "listfiles_count": "Mga bersiyon",
        "listfiles-latestversion-yes": "Oo",
        "listfiles-latestversion-no": "Hindi",
-       "file-anchor-link": "File",
-       "filehist": "Kasaysayan ng file",
+       "file-anchor-link": "Talaksan",
+       "filehist": "Kasaysayan ng talaksan",
        "filehist-help": "Pindutin ang isang petsa/oras para makita ang anyo ng talaksan noong panahong iyon.",
        "filehist-deleteall": "burahin lahat",
        "filehist-deleteone": "burahin",
        "filehist-revert": "ibalik",
        "filehist-current": "kasalukuyan",
        "filehist-datetime": "Petsa/Oras",
-       "filehist-thumb": "Thumbnail",
+       "filehist-thumb": "Kagyat",
        "filehist-thumbtext": "Kagyat (''thumbnail'') para sa bersyon mula noong $1",
        "filehist-nothumb": "Walang kagyat (''thumbnail'')",
        "filehist-user": "Tagagamit",
-       "filehist-dimensions": "Mga sukat",
+       "filehist-dimensions": "Sukat",
        "filehist-filesize": "Sukat ng talaksan",
        "filehist-comment": "Komento",
-       "imagelinks": "Paggamit ng file",
+       "imagelinks": "Paggamit ng talaksan",
        "linkstoimage": "Nakakawing ang sumusunod na {{PLURAL:$1|pahina|$1 pahina}} sa talaksang ito:",
        "linkstoimage-more": "Mahigit sa $1 {{PLURAL:$1|pahina|mga pahina}} ang nakakawing sa talaksang ito.\nIpinapakita sa sumusunod na talaan ang {{PLURAL:$1|unang pahina lamang|unang $1 mga pahina lamang}} na nakakawing sa talaksang ito.\nMayroong makukuhang [[Special:WhatLinksHere/$2|buong talaan]].",
        "nolinkstoimage": "Walang pahinang nakakawing sa talaksang ito.",
        "watchlist-details": "{{PLURAL:$1|$1 pahinang|$1 mga pahinang}} nasa iyong talaan ng mga binabantayan, hindi binibilang ang mga pahina ng usapan.",
        "wlheader-enotif": "Umiiral ang pagpapahayag sa pamamagitan ng e-liham.",
        "wlheader-showupdated": "Ipinapakitang may '''makakapal na mga panitik''' ang nabagong/binagong mga pahina mula pa noong huli mong pagdalaw sa kanila",
-       "wlnote": "Nasa ibaba ang {{PLURAL:$1|pinakahuling pagbabago|pinakahuling '''$1''' mga pagbabago}} sa loob ng huling {{PLURAL:$2|oras|'''$2''' mga oras}}, magmula noong $3 sa ganap na ika-$4.",
-       "wlshowlast": "Ipakita ang huling $1 mga oras $2 mga araw",
+       "wlnote": "Nasa ibaba ang {{PLURAL:$1|pinakahuling pagbabago|pinakahuling <strong>$1</strong> pagbabago}} sa loob ng huling {{PLURAL:$2|oras|<strong>$2</strong> oras}}, magmula noong $3 sa ganap na $4.",
+       "wlshowlast": "Ipakita ang huling $1 oras, $2 araw",
        "watchlist-hide": "Itago",
        "wlshowhideminor": "mga maliliit na edit",
        "wlshowhidebots": "mga bot",
        "actioncomplete": "Naisakatuparan na ang gawain",
        "actionfailed": "Hindi nagtagumpay ang galaw",
        "deletedtext": "Nabura na ang \"$1\".  Tingnan ang $2 para sa talaan ng kamakailan lamang na mga pagbubura.",
-       "dellogpage": "Talaan ng pagbubura",
+       "dellogpage": "Talaan ng pagbura",
        "dellogpagetext": "Nasa ibaba ang isang talaan ng pinakakamailan lamang na mga pagbubura.",
        "deletionlog": "tala ng pagbubura",
        "reverted": "Ibinalik sa mas sinaunang pagbabago",
        "minimum-size": "Pinakamaliit na sukat",
        "maximum-size": "Pinakamalaking sukat",
        "pagesize": "(mga byte)",
-       "restriction-edit": "Pagpatnugot",
+       "restriction-edit": "Pagbabago",
        "restriction-move": "Ilipat",
        "restriction-create": "Likhain",
        "restriction-upload": "Magkarga",
        "namespace": "Ngalan-espasyo:",
        "invert": "Baligtarin and pinili",
        "tooltip-invert": "Tsekan ang kahong ito upang ikubli ang mga pagbabago sa mga pahina sa loob ng napiling mga puwang ng pangalan (at ang kaugnay na puwang ng pangalan kung may tsek)",
-       "namespace_association": "Kaugnay na mga puwang na pampangalan",
+       "namespace_association": "Kaugnay na ngalan-espasyo",
        "tooltip-namespace_association": "Tsekan ang kahong ito upang maisama ang puwang na pampangalan ng usapan o paksa na may kaugnayan sa napiling puwang na pampangalan",
        "blanknamespace": "(Pangunahin)",
        "contributions": "Mga ambag ng {{GENDER:$1|tagagamit}}",
        "sp-contributions-blocked-notice": "Kasalukuyang hinarang ang tagagamit na ito.\nAng pinakahuling entrada sa talaan  ng pagharang ay ibinigay sa ibaba para sa pagsangguni:",
        "sp-contributions-blocked-notice-anon": "Kasalukuyang hinarang ang adres ng IP na ito.\nAng pinakahuling entrada sa talaan  ng pagharang ay ibinigay sa ibaba para sa pagsangguni:",
        "sp-contributions-search": "Maghanap ng ambag",
-       "sp-contributions-username": "IP Address o bansag:",
+       "sp-contributions-username": "Direksyong IP o pangalan ng tagagamit:",
        "sp-contributions-toponly": "Ipakita lang ang mga pamamatnugot na mga huling rebisyon",
        "sp-contributions-newonly": "Ipakita lang ang mga pamamatnugot na mga nalikhang pahina",
        "sp-contributions-submit": "Hanapin",
        "whatlinkshere": "Mga nakaturo dito",
        "whatlinkshere-title": "Mga pahinang kumakawing sa $1",
        "whatlinkshere-page": "Pahina:",
-       "linkshere-2": "Nakakawing ang sumusunod na mga pahina sa '''$1''':",
-       "nolinkshere-2": "Walang pahinang nakakawing sa '''$1'''.",
-       "nolinkshere-ns-2": "Walang pahinang nakakawing sa '''$1''' mula sa loob ng napiling espasyo ng pangalan.",
+       "linkshere": "Nakakawing ang sumusunod na mga pahina sa '''$1''':",
+       "nolinkshere": "Walang pahinang nakakawing sa '''$2'''.",
+       "nolinkshere-ns": "Walang pahinang nakakawing sa '''$2''' mula sa loob ng napiling espasyo ng pangalan.",
        "isredirect": "pahinang panturo/panuto",
        "istemplate": "pagsasali",
        "isimage": "link ng file",
        "whatlinkshere-hideredirs": "$1 ang mga pagpapapunta sa ibang pahina",
        "whatlinkshere-hidetrans": "$1 ang mga paglipat-sali (transklusyon)",
        "whatlinkshere-hidelinks": "$1 ang mga kawing",
-       "whatlinkshere-hideimages": "$1 kawing ng/sa talaksan",
+       "whatlinkshere-hideimages": "$1 kawing sa talaksan",
        "whatlinkshere-filters": "Mga pansala",
        "autoblockid": "Kusang harangin ang #$1",
        "block": "Harangin ang tagagamit",
        "tooltip-pt-anoncontribs": "Mga tala ng binago ng IP address na ito",
        "tooltip-pt-login": "Hinihikayat kang lumagda; gayunpaman, hindi ito kinakailangan.",
        "tooltip-pt-logout": "Umalis sa pagkaka-login",
-       "tooltip-pt-createaccount": "Hinihikayat kang lumikha ng kuwenta at lumigda; gayunpaman, hindi ito kinakailangan",
+       "tooltip-pt-createaccount": "Hinihikayat kang lumikha ng kuwenta at lumagda; gayunpaman, hindi ito kinakailangan",
        "tooltip-ca-talk": "Usapan tungkol sa nilalaman ng pahinang ito",
        "tooltip-ca-edit": "Baguhin ang pahinang ito",
        "tooltip-ca-addsection": "Magsimula ng bagong seksiyon",
        "tooltip-search": "Maghanap sa {{SITENAME}}",
        "tooltip-search-go": "Puntahan ang isang pahina na may ganitong tumpak na pangalan",
        "tooltip-search-fulltext": "Hanapin ang mga pahina para sa tekstong ito",
-       "tooltip-p-logo": "Unang Pahina",
+       "tooltip-p-logo": "Dalawin ang unang pahina",
        "tooltip-n-mainpage": "Dalawin ang Unang Pahina",
        "tooltip-n-mainpage-description": "Dalawin ang unang pahina",
        "tooltip-n-portal": "Hinggil sa proyekto, ano ang magagawa mo, saan matatagpuan ang mga bagay-bagay",
-       "tooltip-n-currentevents": "Maghanap ng sanligang impormasyon hinggil sa mga kasalukuyang kaganapan",
-       "tooltip-n-recentchanges": "Ang tala ng mga kamakailang pagbabago sa loob ng wiki.",
+       "tooltip-n-currentevents": "Maghanap ng saligang impormasyon hinggil sa mga kasalukuyang kaganapan",
+       "tooltip-n-recentchanges": "Isang tala ng mga kamakailang pagbabago sa loob ng wiki.",
        "tooltip-n-randompage": "Magkarga ng anumang pahina",
-       "tooltip-n-help": "Pook kung saan ito matutuklasan.",
+       "tooltip-n-help": "Pook kung saan ito matutuklasan",
        "tooltip-t-whatlinkshere": "Tala ng lahat ng pahina ng mga wiking nakakawing dito",
        "tooltip-t-recentchangeslinked": "Kamakailang mga pagbabago na nakakawing mula sa pahinang ito",
        "tooltip-feed-rss": "Subo/Kargang RSS para sa pahinang ito",
        "tooltip-feed-atom": "Sindikasyong Atom para sa pahinang ito",
        "tooltip-t-contributions": "Listahan ng mga ambag ng {{GENDER:$1|tagagamit na ito}}",
-       "tooltip-t-emailuser": "Magpadala ng isang e-liham sa tagagamit na ito",
-       "tooltip-t-upload": "Mag-upload ng mga file",
+       "tooltip-t-emailuser": "Magpadala ng e-liham sa {{GENDER:$1|tagagamit na ito}}",
+       "tooltip-t-upload": "Magkarga ng mga talaksan",
        "tooltip-t-specialpages": "Tala ng lahat ng mga natatanging pahina",
        "tooltip-t-print": "Bersiyong maililimbag ng pahinang ito",
        "tooltip-t-permalink": "Palagiang link sa bersyong ito ng pahina",
        "pageinfo-title": "Kabatiran para sa \"$1\"",
        "pageinfo-not-current": "Maaari lamang ipakita ang impormasyon para sa kasalukuyang rebisyon.",
        "pageinfo-header-basic": "Saligang kabatiran",
-       "pageinfo-header-edits": "Kasaysayan ng pamamatnugot",
-       "pageinfo-header-restrictions": "Pruteksiyon ng pahina",
+       "pageinfo-header-edits": "Kasaysayan ng pagbabago",
+       "pageinfo-header-restrictions": "Pagsanggalang ng pahina",
        "pageinfo-header-properties": "Mga kaarian ng pahina",
        "pageinfo-display-title": "Pamagat na ipinapakita",
        "pageinfo-default-sort": "Likas na nakatakdang susi ng pag-uuri",
        "pageinfo-length": "Haba ng pahina (na nasa mga byte)",
        "pageinfo-article-id": "ID ng pahina",
-       "pageinfo-robot-policy": "Katayuan ng makinang panghanap",
-       "pageinfo-robot-index": "Matataluntunan",
+       "pageinfo-language": "Wika ng nilalaman ng pahina",
+       "pageinfo-content-model": "Modelo ng nilalaman ng pahina",
+       "pageinfo-robot-policy": "Pagtatalatuntunang gawa ng robot",
+       "pageinfo-robot-index": "Pinapayagan",
        "pageinfo-robot-noindex": "Hindi pinayagan",
        "pageinfo-watchers": "Bilang ng mga nagbabantay ng pahina",
-       "pageinfo-redirects-name": "Napapapunta sa pahinang ito",
+       "pageinfo-redirects-name": "Bilang ng mga pagkarga sa pahinang ito",
        "pageinfo-redirects-value": "$1",
        "pageinfo-subpages-name": "Mga kabahaging pahina ng pahinang ito",
        "pageinfo-subpages-value": "$1 ($2 {{PLURAL:$2|pagpapapunta sa ibang pahina|mga pagpapapunta sa ibang pahina}}; $3 {{PLURAL:$3|hindi pagpapapunta sa ibang pahina|mga hindi pagpapapunta sa ibang pahina}})",
        "pageinfo-firstuser": "Tagapaglikha ng pahina",
        "pageinfo-firsttime": "Petsa ng paglikha ng pahina",
        "pageinfo-lastuser": "Pinakahuling patnugot",
-       "pageinfo-lasttime": "Petsa ng pinakahuling pagpatnugot",
-       "pageinfo-edits": "Kabuuang bilang ng mga pamamatnugot",
+       "pageinfo-lasttime": "Petsa ng pinakahuling pagbabago",
+       "pageinfo-edits": "Kabuuang bilang ng mga pagbabago",
        "pageinfo-authors": "Kabuuang bilang ng magkakabukod na mga may-akda",
-       "pageinfo-recent-edits": "Kamakailang bilang ng mga pamamatnugot (sa loob ng huling $1)",
+       "pageinfo-recent-edits": "Kamakailang bilang ng mga pagbabago (sa loob ng huling $1)",
        "pageinfo-recent-authors": "Kamakailang bilang ng magkakabukod na mga may-akda",
-       "pageinfo-magic-words": "{{PLURAL:$1|Salita|Mga salita}}ng mahiwaga ($1)",
+       "pageinfo-magic-words": "{{PLURAL:$1|Salitang|Mga salitang}} mahiwaga ($1)",
        "pageinfo-hidden-categories": "Nakatagong {{PLURAL:$1|kategorya|mga kategorya}} ($1)",
-       "pageinfo-templates": "{{PLURAL:$1|Suleras|Mga suleras}} ($1) na nasa transklusyon (kasama sa maraming mga lugar)",
+       "pageinfo-templates": "{{PLURAL:$1|Padrong nasa transklusyon|Mga padrong nasa transklusyon}} ($1)",
        "pageinfo-toolboxlink": "Impormasyon ng pahina",
+       "pageinfo-contentpage": "Binibilang bilang pahina ng nilalaman",
+       "pageinfo-contentpage-yes": "Oo",
        "markaspatrolleddiff": "Tatakan bilang napatrolya na",
        "markaspatrolledtext": "Tatakan ang pahinang ito bilang napatrolya na",
        "markedaspatrolled": "Tatakan bilang napatrolya na",
        "markedaspatrollederror": "Hindi matatakan bilang napatrolya na",
        "markedaspatrollederrortext": "Kailangang tukuyin mo ang isang pagbabago para matatakan ito bilang napatrolya na.",
        "markedaspatrollederror-noautopatrol": "Wala kang pahintulot para tatakan ang ginawa mong mga pagbabago bilang napatrolya na.",
-       "patrol-log-page": "Tala ng Pagpapatrolya",
+       "patrol-log-page": "Tala ng pagpapatrolya",
        "patrol-log-header": "Tala ito ng mga pagbabagong napatrolya na.",
-       "log-show-hide-patrol": "$1 tala ng pagpatrolya",
        "deletedrevision": "Binurang lumang pagbabago $1",
        "filedeleteerror-short": "Kamalian sa pagbubura ng talaksan: $1",
        "filedeleteerror-long": "Nakaranas ng mga kamalian habang binubura ang talaksan:\n\n$1",
        "file-nohires": "Walang makuhang mas mataas na resolusyon (kalinawan).",
        "svg-long-desc": "Talaksang SVG, nasa mga bilang na $1 × $2 mga piksel, sukat ng talaksan: $3",
        "svg-long-desc-animated": "Animadong talaksang SVG, nasa mga bilang na $1 × $2 mga piksel, sukat ng talaksan: $3",
-       "show-big-image": "Orihinal na file",
+       "show-big-image": "Orihinal na talaksan",
        "show-big-image-preview": "Sukat ng paunang-tingin na ito: $1.",
        "show-big-image-other": "Ibang {{PLURAL:$2|resolusyon|mga resolusyon}}: $1.",
        "show-big-image-size": "$1 x $2 mga piksel",
        "metadata-help": "Naglalaman ang talaksang ito ng karagdagang kabatiran na maaaring idinagdag mula sa isang kamerang dihital o iskaner na ginamit para likhain o para maging dihital ito.\nKapag nabago ang talaksan mula sa anyong orihinal nito, may ilang detalyeng hindi ganap na maipapakita ang nabagong talaksan.",
        "metadata-expand": "Ipakita ang karugtong na mga detalye",
        "metadata-collapse": "Itago ang karugtong na mga detalye",
-       "metadata-fields": "Ang mga hanay ng pook ng metadato ng larawan na nakatala sa mensaheng ito ay masasama sa ipinapakitang pahina ng larawan kapag tumiklop ang tabla ng metadato.\nLikas na nakatakdang itago ang iba pa.\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": "Ang mga hanay ng pook ng metadatos ng larawan na nakatala sa mensaheng ito ay masasama sa ipinapakitang pahina ng larawan kapag tumiklop ang tabla ng metadatos.\nLikas na nakatakdang itago ang iba pa.\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": "'''$2:''' $1",
        "metadata-langitem-default": "$1",
        "exif-imagewidth": "Lapad",
        "exif-ycbcrsubsampling": "Halimbawang bahagi ng rata (''ratio'') ng Y sa C",
        "exif-ycbcrpositioning": "Pagkakaposisyon ng Y at C",
        "exif-xresolution": "Pahalang na resolusyon (kalinawan)",
-       "exif-yresolution": "Bertikal (patayo) na resolusyon/kalinawan",
+       "exif-yresolution": "Patayo na resolusyon (kalinawan)",
        "exif-stripoffsets": "Lokasyon ng dato ng larawan",
        "exif-rowsperstrip": "Bilang ng pahalang na hanay bawat manipis na piraso",
        "exif-stripbytecounts": "Mga byte ng bawat siniksik na piraso",
        "exif-software": "Ginamit na sopwer",
        "exif-artist": "May-akda",
        "exif-copyright": "May-hawak ng karapatang-ari (kopirayt)",
-       "exif-exifversion": "Bersyong Exif",
+       "exif-exifversion": "Bersiyong Exif",
        "exif-flashpixversion": "Bersyon ng sinusuportahang Flashpix",
        "exif-colorspace": "Espasyo ng kulay",
        "exif-componentsconfiguration": "Kahulugan ng bawat komponente",
        "version-entrypoints-header-url": "URL",
        "version-entrypoints-articlepath": "[https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgArticlePath Landas ng artikulo]",
        "version-entrypoints-scriptpath": "[https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgScriptPath Landas ng panitik]",
+       "redirect-submit": "Pumunta",
+       "redirect-value": "Halaga:",
+       "redirect-user": "ID ng tagagamit",
+       "redirect-page": "ID ng pahina",
+       "redirect-revision": "Rebisyon ng pahina",
+       "redirect-file": "Pangalan ng talaksan",
        "fileduplicatesearch": "Maghanap ng kaparehong mga talaksan",
        "fileduplicatesearch-summary": "Maghanap ng mga kaparehong mga talaksan sa baba ng kanyang halaga ng ''hash''.",
        "fileduplicatesearch-filename": "Pangalan ng file:",
        "intentionallyblankpage": "Sinadyang walang laman ang pahinang ito",
        "external_image_whitelist": "  #Pabayaang talagang ganito lang ang hanay na ito<pre>\n#Ilagay ang mga piraso ng karaniwang pagpapahayag (ang bahagi lang na napupunta sa pagitan ng //) sa ibaba\n#Tutugmaan ang mga ito ng mga URL ng panlabas (mainit na kawing) na mga larawan\n#Ang mga magtutugma ay ipapakita bilang mga larawan, kung hindi bilang isang kawing lamang patungo sa larawan ang ipapakita\n#Ituturing bilang mga kumento ang mga hanay na nagsisimula sa #\n\n#Ilagay sa ibabaw ng hanay na ito ang mga piraso ng karaniwang pagpapahayag.  Pabayaang ganito lang talaga ang hanay na ito</pre>",
        "tags": "Tanggap na mga tatak ng pagbabago",
-       "tag-filter": "Pansala ng [[Special:Tags|tatak]]:",
+       "tag-filter": "Pansala ng [[Special:Tags|etiketa]]:",
        "tag-filter-submit": "Pansala",
        "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|Tatak|Mga tatak}}]]: $2)",
        "tags-title": "Mga tatak",
        "tags-source-header": "Pinagmulan",
        "tags-hitcount-header": "Natatakang mga pagbabago",
        "tags-actions-header": "Mga hakbang",
+       "tags-active-yes": "Oo",
+       "tags-active-no": "Hindi",
        "tags-source-none": "Hindi na ginagamit pa",
        "tags-edit": "baguhin",
        "tags-delete": "Burahin",
        "htmlform-selectorother-other": "Iba pa",
        "htmlform-title-not-exists": "Hindi nairal ang $1.",
        "logentry-delete-delete": "{{GENDER:$2|Binura}} ni $1 ang pahinang $3",
-       "logentry-delete-restore": "Ibinalik ni $1 ang pahinang $3",
+       "logentry-delete-restore": "{{GENDER:$2|Ibinalik}} ni $1 ang pahinang \"$3\" ($4)",
        "logentry-delete-event": "Binago ni $1 ang antas ng pagkanatatanaw ng {{PLURAL:$5|isang pangyayari sa talaan|$5 mga pangyayari sa talaan}} sa $3: $4",
-       "logentry-delete-revision": "Binago ni $1 ang antas ng pagtanaw sa {{PLURAL:$5|isang rebisyon|$5 mga rebisyon}} sa pahinang $3: $4",
+       "logentry-delete-revision": "{{GENDER:$2|Binago}} ni $1 ang antas ng pagtanaw sa {{PLURAL:$5|isang rebisyon|$5 mga rebisyon}} sa pahinang \"$3\": $4",
        "logentry-delete-event-legacy": "Binago ni $1 ang antas ng pagtanaw sa mga pangyayari sa talaan sa $3",
        "logentry-delete-revision-legacy": "Binago ni $1 ang antas ng pagtanaw sa mga rebisyong nasa pahinang $3",
        "logentry-suppress-delete": "Sinupil ni $1 ang pahinang $3",
        "revdelete-unrestricted": "tinanggal ang mga pagbabawal para sa mga tagapangasiwa",
        "logentry-move-move": "{{GENDER:$2|Inilipat}} ni $1 ang pahinang $3 papunta sa $4",
        "logentry-move-move-noredirect": "{{GENDER:$2|Inilipat}} ni $1 ang pahinang $3 papunta sa $4 na hindi nag-iiwan ng ibang kapupuntahan",
-       "logentry-move-move_redir": "Inilipat ni $1 ang pahinang $3 papunta sa $4 na nasa ibayo ng ibang kapupuntahan",
+       "logentry-move-move_redir": "{{GENDER:$2|Inilipat}} ni $1 ang pahinang \"$3\" sa \"$4\" sa ibayo ng pagkarga",
        "logentry-move-move_redir-noredirect": "Inilipat ni $1 ang pahinang $3 papunta sa $4 sa ibabaw ng isang pagpapunta sa iba na hindi nag-iiwan ng isang pagpapapunta sa iba",
        "logentry-patrol-patrol": "Minarkahan ni $1 ang rebisyong $4 ng pahinang $3 bilang napatrolya na",
        "logentry-patrol-patrol-auto": "Kusang minarkahan ni $1 ang rebisyong $4 ng pahinang $3 bilang napatrolya na",
index fe377e5..5831241 100644 (file)
        "whatlinkshere": "Сәбонон ијо",
        "whatlinkshere-title": "Сәһифон, сәбон вардән бә \"$1\"",
        "whatlinkshere-page": "Сәһифә:",
-       "linkshere-2": "Ым сәһифон сәбон вардән ијо ''$1''':",
-       "nolinkshere-2": "Бә ым сәһифә ҹо сәһифонку сәбонон нин '''$1'''.",
+       "linkshere": "Ым сәһифон сәбон вардән ијо ''$1''':",
+       "nolinkshere": "Бә ым сәһифә ҹо сәһифонку сәбонон нин '''$2'''.",
        "isredirect": "унвони дәгиш кардә сәһифәје",
        "istemplate": "әловә",
        "isimage": "фајлинә сәбон",
index c9a65d6..422b905 100644 (file)
        "sp-contributions-talk": "Alea",
        "whatlinkshere": "Ngaahi fehokotaki ki heni",
        "whatlinkshere-page": "Peesi:",
-       "linkshere-2": "!!FUZZY!!ʻOku fehokotaki ki heni ʻa e ngaahi peesi:",
-       "nolinkshere-2": "!!FUZZY!!ʻOku ʻikai ha ngaahi kupu fehokotaki ki heni.",
+       "linkshere": "ʻOku fehokotaki ki heni ʻa e ngaahi peesi:",
+       "nolinkshere": "ʻOku ʻikai ha ngaahi kupu fehokotaki ki heni.",
        "isredirect": "Peesi leʻei",
        "istemplate": "kātoi",
        "whatlinkshere-links": "← fehokotaki",
index fcbe9af..196f1f0 100644 (file)
        "tog-watchlisthideminor": "Küçük düzenlemeleri izleme listesinde gizle",
        "tog-watchlisthideliu": "Oturum açmış kullanıcıların düzenlemelerini izleme listesinde gizle",
        "tog-watchlistreloadautomatically": "Her süzgeç değişikliği olduğunda izleme listesini otomatik olarak yeniden yükle (JavaScript gerekir)",
+       "tog-watchlistunwatchlinks": "Değişiklik içeren izleme sayfalarına doğrudan izle/izleme işareti ({{int:Watchlist-unwatch}}/{{int:Watchlist-unwatch-undo}}) ekle (Geçiş işlevi için JavaScript gereklidir)",
        "tog-watchlisthideanons": "Anonim kullanıcıların düzenlemelerini izleme listesinde gizle",
        "tog-watchlisthidepatrolled": "Devriyenin gördüğü düzenlemeleri izleme listesinde gizle",
        "tog-watchlisthidecategorization": "Sayfa kategorilendirmesini gizle",
        "cascadeprotected": "Bu sayfa değişiklik yapılması engellenmiştir, çünkü  \"kademeli\" seçeneği aktif hale getirilerek koruma altına alınan {{PLURAL:$1|sayfada|sayfalarda}} kullanılmaktadır:\n$2",
        "namespaceprotected": "'''$1''' alandındaki sayfaları düzenlemeye izniniz bulunmamaktadır.",
        "customcssprotected": "Bu sayfayı değiştirmeye yetkiniz bulunmamaktadır, çünkü bu sayfa başka bir kullanıcının kişisel ayarlarını içermektedir.",
+       "customjsonprotected": "Başka bir kullanıcının kişisel ayarlarını içerdiği için bu JSON sayfasını düzenleme izniniz yok.",
        "customjsprotected": "Bu Java Script sayfasını değiştirmeye yetkiniz bulunmamaktadır, çünkü bu sayfa başka bir kullanıcının kişisel ayarlarını içermektedir.",
        "mycustomcssprotected": "Bu CSS sayfasını değiştirmeye yetkiniz yok.",
+       "mycustomjsonprotected": "Bu JSON sayfasını düzenleme izniniz yok.",
        "mycustomjsprotected": "Bu JavaScript sayfasını değiştirmeye yetkiniz yok.",
        "myprivateinfoprotected": "Sizin özel bilgilerinizi düzenleme yetkiniz yok.",
        "mypreferencesprotected": "Tercihlerinizi düzenlemek için yetkiniz yok.",
        "wrongpasswordempty": "Boş parola girdiniz. Lütfen tekrar deneyiniz.",
        "passwordtooshort": "Parolalar en az {{PLURAL:$1|1 karakter|$1 karakter}} uzunluğunda olmalı.",
        "passwordtoolong": "Parolalar $1 karakterden uzun olamaz.",
-       "passwordtoopopular": "Sıklıkla seçilen parolalar kullanılamaz. Lütfen daha özgün bir parola belirleyin.",
+       "passwordtoopopular": "Yaygın olarak seçilen şifreler kullanılamaz. Lütfen tahmin edilmesi daha zor bir şifre seçin.",
        "password-name-match": "Parolanız kullanıcı adınızdan farklı olmalıdır.",
        "password-login-forbidden": "Bu kullanıcı adı ve parolanın kullanımı yasaklanmıştır.",
        "mailmypassword": "Parolayı sıfırla",
        "passwordremindertitle": "{{SITENAME}} için yeni geçici parola",
-       "passwordremindertext": "Birisi (muhtemelen siz, $1 IP adresinden) {{SITENAME}} ($4) için yeni bir parola gönderilmesi istedi. \"$2\" kullanıcısına geçici olarak \"$3\" parolası oluşturuldu. Eğer bu sizin isteğiniz ise, oturum açıp yeni bir parola oluşturmanız gerekmektedir. Geçici parolanızın süresi {{PLURAL:$5|1 gün|$5 gün}} içinde dolacaktır.\n\nParola değişimini siz istemediyseniz veya parolanızı hatırladıysanız ve artık parolanızı değiştirmek istemiyorsanız; bu mesajı önemsemeyerek eski parolanızı kullanmaya devam edebilirsiniz.",
+       "passwordremindertext": "Birisi ($1 IP adresinden) {{SITENAME}} ($4) için yeni bir parola gönderilmesi istedi. \"$2\" kullanıcısına geçici olarak \"$3\" parolası oluşturuldu. Eğer bu sizin isteğiniz ise, oturum açıp yeni bir parola oluşturmanız gerekmektedir. Geçici parolanızın süresi {{PLURAL:$5|1 gün|$5 gün}} içinde dolacaktır.\n\nParola değişimini siz istemediyseniz veya parolanızı hatırladıysanız ve artık parolanızı değiştirmek istemiyorsanız; bu mesajı önemsemeyerek eski parolanızı kullanmaya devam edebilirsiniz.",
        "noemail": "\"$1\" adlı kullanıcıya kayıtlı bir e-posta adresi yok.",
        "noemailcreate": "Geçerli bir e-posta adresi sağlamalısınız",
        "passwordsent": "\"$1\" adına kayıtlı e-posta adresine yeni bir parola gönderildi. Oturumu, lütfen, iletiyi aldıktan sonra açın.",
        "botpasswords-label-delete": "Sil",
        "botpasswords-label-resetpassword": "Parolayı sıfırla",
        "botpasswords-label-grants": "Geçerli ayrıcalıklar:",
+       "botpasswords-help-grants": "Hibeler, kullanıcı hesabınızın sahip olduğu haklara erişim izni verir. Burada bir hibe sağlamak, kullanıcı hesabınızın sahip olamayacağı herhangi bir haklara erişim sağlamaz. Daha fazla bilgi için [[Special:ListGrants|hibe tablosuna]] bakınız.",
        "botpasswords-label-grants-column": "Verilen",
        "botpasswords-bad-appid": "Bot ismi \"$1\" geçerli değil.",
        "botpasswords-insert-failed": "Bot adı \"$1\" eklenemedi. Zaten eklenmiş olmalı?",
        "botpasswords-update-failed": "Bot ismini \"$1\" olarak güncelleme başarısız oldu. Silinmiş olabilir mi?",
        "botpasswords-created-title": "Bot parolası oluşturuldu",
-       "botpasswords-created-body": "\"$2\" adlı kullanıcının \"$1\" adlı botu için bot parolası oluşturuldu.",
+       "botpasswords-created-body": "\"$2\" adlı {{GENDER:$2|kullanıcının}} \"$1\" adlı botu için bot parolası oluşturuldu.",
        "botpasswords-updated-title": "Bot parolası güncellendi",
-       "botpasswords-updated-body": "\"$2\" adlı kullanıcının \"$1\" adlı botunun bot parolası güncellendi.",
+       "botpasswords-updated-body": "\"$2\" adlı {{GENDER:$2|kullanıcının}} \"$1\" adlı botunun bot parolası güncellendi.",
        "botpasswords-deleted-title": "Bot parolası silindi",
-       "botpasswords-deleted-body": "\"$2\" adlı kullanıcının \"$1\" adlı botunun bot parolası silindi.",
-       "botpasswords-newpassword": "<strong>$1</strong> ile oturum açmak için yeni şifre: <strong>$2</strong>. <em>İlerde başvurmak için lütfen kaydedin.</em>",
+       "botpasswords-deleted-body": "\"$2\" adlı {{GENDER:$2|kullanıcının}} \"$1\" adlı botunun bot parolası silindi.",
+       "botpasswords-newpassword": "<strong>$1</strong> ile giriş yapılan yeni parola: <strong>$2</strong>. <em>Lütfen bunu ileride başvurmak için kaydedin.<em> <br> (Kullanıcı adının, nihai kullanıcı adıyla aynı olmasını gerektiren eski botlar için kullanıcı adı olarak <strong>$3</strong> ve şifre olarak da <strong>$4</strong> kullanabilirsiniz.)",
        "botpasswords-no-provider": "BotPasswordsSessionProvider kullanılamaz.",
        "botpasswords-restriction-failed": "Bot parolası kısıtlamaları bu oturum açma işlemini önlemektedir.",
        "botpasswords-invalid-name": "Belirtilen kullanıcı adı bot parolası ayırıcısı içermiyor (\"$1\").",
+       "botpasswords-not-exist": "\"$1\" kullanıcısının \"$2\" adında bir bot şifresine sahip değil.",
        "botpasswords-needs-reset": "\"$1\" {{GENDER:$1|kullanıcısına}} ait \"$2\" adlı bot için bot parolası sıfırlanmalı.",
        "resetpass_forbidden": "Parolalar değiştirilememektedir",
        "resetpass_forbidden-reason": "Parolalar değiştirilemez: $1",
        "resetpass-temp-password": "Geçici parola:",
        "resetpass-abort-generic": "Parola değişikliği bir uzantı tarafından iptal edildi.",
        "resetpass-expired": "Parolanızın süresi bitti. Lütfen, giriş için yeni bir parola oluşturun.",
-       "resetpass-expired-soft": "Parolanızın süresi bitti ve değiştirilmesi gerekiyor. Lütfen, yeni bir parola seçin veya daha sonra oluşturmak için \"{{int:authprovider-resetpass-skip-label}}\" butonuna tıklayın.",
-       "resetpass-validity-soft": "Parolanız geçerli değil: $1\n\nLütfen yeni bir şifre belirleyin ya da daha sonra sıfırlamak için \"{{int:authprovider-resetpass-skip-label}}\" bağlantısını tıklayın.",
+       "resetpass-expired-soft": "Parolanızın süresi bitti ve değiştirilmesi gerekiyor. Lütfen, yeni bir parola seçin veya daha sonra değiştirmek için \"{{int:authprovider-resetpass-skip-label}}\" düğmesine tıklayın.",
+       "resetpass-validity-soft": "Parolanız geçerli değil: $1\n\nLütfen yeni bir şifre belirleyin ya da daha sonra değiştirmek için \"{{int:authprovider-resetpass-skip-label}}\" bağlantısını tıklayın.",
        "passwordreset": "Parola sıfırlama",
        "passwordreset-text-one": "Parolanızı sıfırlamak için bu formu doldurun.",
        "passwordreset-text-many": "{{PLURAL:$1|E-posta ile geçici bir parola almak için alanlardan birini doldurun.}}",
        "passwordreset-emailelement": "Kullanıcı adı: \n$1\n\nGeçici şifre: \n$2",
        "passwordreset-emailsentemail": "Eğer bu e-posta adresi hesabınızın bağlı olduğu adres ise, bir parola sıfırlama e-postası gönderilecektir.",
        "passwordreset-emailsentusername": "Eğer bu e-posta adresi hesabınızın bağlı olduğu adres ise, bir parola sıfırlama e-postası gönderilecektir.",
+       "passwordreset-nocaller": "Bir ziyaretçi sağlanmalıdır",
+       "passwordreset-nosuchcaller": "Ziyaretçi mevcut değil: $1",
+       "passwordreset-ignored": "Şifre sıfırlama işlenmedi. Belki de herhangi bir sağlayıcı yapılandırılmadı?",
        "passwordreset-invalidemail": "Geçersiz e-posta adresi",
        "passwordreset-nodata": "Ne bir kullanıcı adı ne de bir e-posta adresi verildi.",
        "changeemail": "E-posta adresini değiştir veya çıkar",
        "savechanges": "Değişiklikleri kaydet",
        "publishpage": "Sayfayı yayımla",
        "publishchanges": "Değişiklikleri yayımla",
+       "savearticle-start": "Sayfayı kaydet...",
+       "savechanges-start": "Değişiklikleri kaydet...",
+       "publishpage-start": "Sayfayı yayımla...",
+       "publishchanges-start": "Değişiklikleri yayımla...",
        "preview": "Önizleme",
        "showpreview": "Önizlemeyi göster",
        "showdiff": "Değişiklikleri göster",
        "previewerrortext": "Yaptığınız değişikliklerin önizlemesi sırasında bir hata oluştu.",
        "blockedtitle": "Kullanıcı erişimi engellendi.",
        "blockedtext": "<strong>Kullanıcı adı veya IP adresiniz engellenmiştir.</strong>\n\nSizi engelleyen hizmetli: $1.<br />\nEngelleme sebebi: <em>$2</em>.\n\n* Engellenmenin başlangıcı: $8\n* Engellenmenin bitişi: $6\n* Engellenme süresi: $7\n\nBelirtilen nedene göre engellenmenizin uygun olmadığını düşünüyorsanız, $1 ya da başka bir [[{{MediaWiki:Grouppage-sysop}}|hizmetli]] ile bu durumu görüşebilirsiniz. [[Special:Preferences|Tercihlerim]] kısmında geçerli bir e-posta adresi girmediyseniz \"Kullanıcıya e-posta gönder\" özelliğini kullanamazsınız, tercihlerinize e-posta adresinizi eklediğinizde e-posta gönderme hakkına sahip olacaksınız.\n<br />Şu anki IP adresiniz $3, engellenme numaranız #$5.\n<br />Bir hizmetliden durumunuz hakkında bilgi almak istediğinizde veya herhangi bir sorguda bu bilgiler gerekecektir, lütfen not ediniz.",
-       "autoblockedtext": "IP adresiniz otomatik olarak engellendi, çünkü $1 tarafından engellenmiş başka bir kullanıcı tarafından kullanılmaktaydı.\nBelirtilen sebep şudur:\n\n:''$2''\n\n* Engellemenin başlangıcı: $8\n* Engellemenin bitişi: $6\n* Bloke edilmesi istenen: $7\n\nEngelleme hakkında tartışmak için $1 ile veya diğer [[{{MediaWiki:Grouppage-sysop}}|hizmetlilerden]] biriyle irtibata geçebilirsiniz.\n\nNot, [[Special:Preferences|kullanıcı tercihlerinize]] geçerli bir e-posta adresi kaydetmediyseniz  \"kullanıcıya e-posta gönder\" özelliğinden faydalanamayabilirsiniz ve bu özelliği kullanmaktan engellenmediniz.\n\nŞu anki IP numaranız $3 ve engellenme ID'niz #$5.\nLütfen yapacağınız herhangi bir sorguda yukarıdaki bütün detayları bulundurun.",
+       "autoblockedtext": "IP adresiniz otomatik olarak engellendi, çünkü $1 tarafından engellenmiş başka bir kullanıcı tarafından kullanılmaktaydı.\nBelirtilen sebep şudur:\n\n:<em>$2</em>\n\n* Engellemenin başlangıcı: $8\n* Engellemenin bitişi: $6\n* Bloke edilmesi istenen: $7\n\nEngelleme hakkında tartışmak için $1 ile veya diğer [[{{MediaWiki:Grouppage-sysop}}|hizmetlilerden]] biriyle irtibata geçebilirsiniz.\n\nNot, [[Special:Preferences|kullanıcı tercihlerinize]] geçerli bir e-posta adresi kaydetmediyseniz  \"{{int:emailuser}}\" özelliğinden faydalanamayabilirsiniz ve bu özelliği kullanmaktan engellenmediniz.\n\nŞu anki IP numaranız $3 ve engellenme ID'niz #$5.\nLütfen yapacağınız herhangi bir sorguda yukarıdaki bütün detayları bulundurun.",
+       "systemblockedtext": "Kullanıcı adınız veya IP adresiniz MediaWiki tarafından otomatik olarak engellendi.\nSebebi:\n\n:<em>$2</em>\n\n* Engelin başlangıcı: $8\n* Engelin süresi: $6\n* Engellenmesi istenen: $7\n\nMevcut IP adresiniz $3.\nLütfen yukarıdaki tüm ayrıntıları, yaptığınız sorgularda belirtin.",
        "blockednoreason": "sebep verilmedi",
        "whitelistedittext": "Değişiklik yapabilmek için $1.",
        "confirmedittext": "Sayfa değiştirmeden önce e-posta adresinizi onaylamalısınız. Lütfen [[Special:Preferences|tercihler]] kısmından e-postanızı ekleyin ve onaylayın.",
        "blocked-notice-logextract": "Bu kullanıcı şuanda engellenmiş.\nSon engelleme günlüğü girdisi referans için aşağıda sağlanmıştır:",
        "clearyourcache": "<strong>Note:</strong> Kaydettikten sonra değişiklikleri görmek için tarayıcınızın önbelleğini temizlemeniz gerekebilir.\n* <strong>Firefox / Safari:</strong> <em>Shift</em> tuşuna basılıyken <em>Yeniden yükle</em>'ye tıklayın ya da <em>Ctrl-F5</em> ya da <em>Ctrl-R</em> yapın (Mac için <em>⌘-R</em>).\n* <strong>Google Chrome:</strong> <em>Ctrl-Shift-R</em>'ye basın. (Mac için <em>⌘-Shift-R</em>)\n* <strong>Internet Explorer:</strong> <em>Ctrl</em> basılıyken <em>Yenile</em>'ye tıklayın ya da <em>Ctrl-F5</em> yapın.\n* <strong>Opera:</strong> <em>Araçlar → Tercihler</em>'den önbelliği temizleyin.",
        "usercssyoucanpreview": "'''İpucu:''' Kaydetmeden önce \"{{int:showpreview}}\"e tıklayarak yeni CSSinizi deneyin.",
+       "userjsonyoucanpreview": "<strong>İpucu:</strong> kaydetmeden önce yeni JSON'unuzu test etmek için \"{{int:showpreview}}\" butonunu kullanın.",
        "userjsyoucanpreview": "'''İpucu:''' Kaydetmeden önce \"{{int:showpreview}}\"e tıklayarak yeni JavaScript'inizi test edin.",
        "usercsspreview": "'''Sadece kullanıcı CSS dosyanızın önizlemesini görüyorsun.''' '''Kullanıcı CSS dosyası henüz kaydolmadı!'''",
+       "userjsonpreview": "<strong>Sadece kullanıcı JSON yapılandırmanızı test ettiğiniz/önizleme yaptığınızı unutmayın.\nHenüz kaydedilmedi!</strong>",
        "userjspreview": "'''Sadece test ediyorsun ya da önizleme görüyorsun - kullanıcı JavaScript'i henüz kaydolmadı.'''",
        "sitecsspreview": "'''Sadece kullanıcı CSS dosyanızın önizlemesini görüyorsunuz.''' \n'''Henüz kaydedilmedi!'''",
+       "sitejsonpreview": "<strong>Sadece bu JSON yapılandırmasını önizlediğinizi unutmayın.\nHenüz kaydedilmedi!</strong>",
        "sitejspreview": "'''Sadece kullanıcı JavaScript kod dosyanızın önizlemesini görüyorsunuz.''' \n'''Henüz kaydedilmedi!'''",
-       "userinvalidconfigtitle": "'''Uyarı:''' \"$1\" adında bir tema yoktur. Özel .css ve .js sayfalarının adlarını küçük harf ile yazın, örneğin;  \"{{ns:user}}:Örnek/Vector.css\" yerine \"{{ns:user}}:Örnek/vector.css\" yazın.",
+       "userinvalidconfigtitle": "<strong>Uyarı:</strong> \"$1\" adında bir tema yoktur. Özel .css, .json ve .js sayfalarının adlarını küçük harf ile yazın, örneğin;  \"{{ns:user}}:Örnek/Vector.css\" yerine \"{{ns:user}}:Örnek/vector.css\" yazın.",
        "updated": "(Güncellendi)",
        "note": "'''Not: '''",
        "previewnote": "'''Bunun yalnızca bir ön izleme olduğunu unutmayın.'''\nYaptığınız değişiklikler henüz kaydedilmedi!",
        "continue-editing": "Düzenlemeye devam et",
        "previewconflict": "Bu önizleme metin düzenleme kutucuğunun üstünde, maddenin eğer değişikliklerinizi kaydetmeyi seçerseniz nasıl görüneceğini yansıtır.",
        "session_fail_preview": "Özür dileriz. Oturum verisi kaybından dolayı değişikliğinizi kaydedemedik.\n\nOturumunuzu kapatmış olabilirsiniz. <strong>Lütfen oturumunuzun açık olduğunu doğrulayıp tekrar deneyiniz</strong>.\nEğer sorun devam ederse, [[Special:UserLogout|oturumu kapatıp]] tekrar giriş yapmayı deneyin ve tarayıcınızın bu siteden çerezlere izin verip vermediğini kontrol edin.",
-       "session_fail_preview_html": "'''Üzgünüz! Oturum verisinin kaybolmasından dolayı düzenlemenizi işleme geçiremeyeceğiz.'''\n\n''Çünkü {{SITENAME}} sitesinde raw HTML etkindir, önizleme JavaScript saldırılarına önlem olarak gizlenmiştir.''\n\n'''Eğer bu haklı bir düzenleme girişimiyse, lütfen yeniden deneyin. Eğer hala çalışmazsa, [[Special:UserLogout|çıkış yapıp]] yeniden oturum açmayı deneyin.'''",
+       "session_fail_preview_html": "Üzgünüz! Düzenleme işleminiz, oturum verisi kaybı nedeniyle işlenemedi.\n\n<em>{{SITENAME}} sayfasında ham HTML özelliği etkin olduğundan önizleme, JavaScript saldırılarına karşı bir önlem olarak gizlenir.</em>\n\n<strong>Bu yasal bir düzenleme girişimi ise lütfen tekrar deneyin.</strong>\nHâlâ çalışmıyorsa [[Special:UserLogout|çıkış yapmayı]] ve ardından tekrar giriş yapmayı deneyin ve tarayıcınızın bu sitedeki çerezlere izin verdiğini kontrol edin.",
        "token_suffix_mismatch": "'''Değişikliğiniz geri çevrildi çünkü alıcınız düzenleme kutucuğundaki noktalama işaretlerini bozdu.\nDeğişikliğiniz, sayfa metninde bozulmayı önlemek için geri çevrildi.\nEğer sorunlu bir web-tabanlı anonim proksi servisi kullanıyorsanız bu olay bazen gerçekleşebilir.'''",
        "edit_form_incomplete": "'''Değişiklik formu için bazı sunuculara erişilemedi; yaptığınız değişiklikler bozulmamıştır, gözden geçirip tekrar deneyiniz.'''",
        "editing": "\"$1\" sayfasını değiştirmektesiniz",
        "yourtext": "Sizin metniniz",
        "storedversion": "Kaydedilmiş metin",
        "editingold": "'''Uyarı: Sayfanın eski bir sürümünde değişiklik yapmaktasınız.'''\nKaydettiğinizde bu tarihli sürümden günümüze kadar olan değişiklikler yok olacaktır.",
+       "unicode-support-fail": "Görünüşe göre tarayıcınız Unicode'u desteklemiyor. Sayfaları düzenlemek için bu desteğe ihtiyacınız var. Bundan ötürü düzenlemeniz kaydedilmedi.",
        "yourdiff": "Karşılaştırma",
        "copyrightwarning": "'''Lütfen dikkat:''' {{SITENAME}} sitesine yapılan bütün katkılar $2 sözleşmesi kapsamındadır (ayrıntılar için $1'a bakınız).\nYaptığınız katkının başka katılımcılar tarafından acımasızca değiştirilmesini ve sınırsızca başka yerlere dağıtılmasını istemiyorsanız, katkıda bulunmayınız.<br />\nAyrıca buraya katkıda bulunarak, bu katkının kendiniz tarafından yazıldığına ya da kamuya açık bir kaynaktan ya da başka bir özgür/ücretsiz kaynaktan kopyalandığına güvence vermiş oluyorsunuz. '''Buraya, telif sahibinin izni olmadan telif hakkı ile korunan eserleri eklemeyiz! '''",
        "copyrightwarning2": "Lütfen, {{SITENAME}} sitesine bulunacağınız tüm katkıların diğer üyeler tarafından düzenlenebileceğini, değiştirilebileceğini ya da silinebileceğini hatırlayın. Yazılarınızın merhametsizce değiştirilebilmesine rıza göstermiyorsanız buraya katkıda bulunmayın. <br />\nAyrıca bu ekleyeceğiniz yazıyı sizin yazdığınızı ya da serbest kopyalama izni veren bir kaynaktan kopyaladığınızı bize taahhüt etmektesiniz (ayrıntılar için referans: $1).",
        "editpage-cannot-use-custom-model": "Bu sayfanın içerik modeli değiştirilemez.",
        "longpageerror": "'''Hata: Girdiğiniz metnin uzunluğu kabul edilebilir en fazla uzunluk olan {{PLURAL:$2|bir kilobayt|$2 kilobayt}}tan fazladır ve {{PLURAL:$1|bir kilobayt|$1 kilobayt}} büyüklüğündedir.'''\nDeğişikliğiniz kaydedilemez.",
-       "readonlywarning": "'''Uyarı: Bakım nedeniyle veritabanı şu anda kilitlenmiştir. Bu yüzden şu anda düzenlemelerinizi kaydetmek mümkün değildir.''' \nYaptığınız düzenlemeleri daha sonra kaydetmek isterseniz, yaptığınız düzenlemeleri bir metin dosyasına ya da herhangi bir şeye kopyala yapıştır yaparak saklayınız.\n\nKilitlemeyi yapan yetkili şu açıklamayı eklemiştir: $1",
+       "readonlywarning": "<strong>Uyarı: Bakım nedeniyle veritabanı şu anda kilitlenmiştir. Bu yüzden şu anda düzenlemelerinizi kaydetmek mümkün değildir.</strong> \nYaptığınız düzenlemeleri daha sonra kaydetmek isterseniz, yaptığınız düzenlemeleri bir metin dosyasına ya da herhangi bir şeye kopyala yapıştır yaparak saklayınız.\n\nKilitlemeyi yapan sistem yetkilisi şu açıklamayı eklemiştir: $1",
        "protectedpagewarning": "'''Uyarı: Bu sayfa koruma altına alınmıştır ve yalnızca hizmetli olanlar tarafından değiştirilebilir.'''\nSon günlük girdisi referans amaçlı aşağıda verilmiştir:",
-       "semiprotectedpagewarning": "'''Not:''' Bu sayfa sadece kayıtlı kullanıcı olanlar tarafından değiştirilebilir.\nSon günlük girdisi referans amaçlı aşağıda verilmiştir:",
-       "cascadeprotectedwarning": "'''UYARI:''' Bu sayfa sadece hizmetlilik yetkileri olan kullanıcıların değişiklik yapabileceği şekilde koruma altına alınmıştır. Çünkü  \"kademeli\" seçeneği aktif hale getirilerek koruma altına alınan {{PLURAL:$1|sayfada|sayfada}} kullanılmaktadır:",
+       "semiprotectedpagewarning": "<strong>Not:</strong> Bu sayfa sadece otomatik onaylanmış kullanıcılar tarafından değiştirilebilir.\nSon günlük girdisi referans amaçlı aşağıda verilmiştir:",
+       "cascadeprotectedwarning": "<strong>Uyarı:</strong> Bu sayfa, yalnızca [[Special:ListGroupRights|belirli haklara]] sahip kullanıcıların bunu düzenleyebilmesi için korunmuştur çünkü \"kademeli\" seçeneği aktif hale getirilerek koruma altına alınan {{PLURAL:$1|sayfada|sayfada}} kullanılmaktadır:",
        "titleprotectedwarning": "'''Uyarı: Bu sayfa [[Special:ListGroupRights|özel hakları]] olanların oluşturabilmeleri için kilitlenmiştir.'''\nSon günlük girdisi referans amaçlı aşağıda verilmiştir:",
        "templatesused": "Bu sayfada kullanılan {{PLURAL:$1|şablon|şablonlar}}:",
        "templatesusedpreview": "Bu önizlemede kullanılan {{PLURAL:$1|şablon|şablonlar}}:",
        "permissionserrors": "İzin hatası",
        "permissionserrorstext": "Aşağıdaki {{PLURAL:$1|sebep|sebepler}}den dolayı, bunu yapmaya yetkiniz yok:",
        "permissionserrorstext-withaction": "Aşağıdaki {{PLURAL:$1|neden|nedenler}}den dolayı $2 yetkiniz yok:",
+       "contentmodelediterror": "Bu revizyonu, içerik modeli <code>$1</code> olduğu için düzenleyemezsiniz. <code>$2</code> sayfasının güncel içerik modelinden farklıdır",
        "recreate-moveddeleted-warn": "<strong>Uyarı: Daha önceden silinmiş bir sayfayı tekrar oluşturuyorsunuz.</strong>\n\nBu sayfayı düzenlemeye devam etmenin uygun olup olmadığını düşünmelisiniz.\nBu sayfanın silme ve taşıma günlüğü kolaylık için burada verilmiştir:",
        "moveddeleted-notice": "Bu sayfa silinmiş.\nSayfanın silme, koruma ve taşıma kaydı referans için aşağıda verilmiştir.",
+       "moveddeleted-notice-recent": "Üzgünüz, bu sayfa yakın zamanda silinmiştir (son 24 saat içinde).\nSayfa için silme, koruma ve taşıma kaydı referans amacıyla aşağıda verilmiştir.",
        "log-fulllog": "Tam günlüğü gör",
        "edit-hook-aborted": "Değişiklik çengelle durduruldu.\nBir açıklama verilmedi.",
        "edit-gone-missing": "Sayfa güncellenemiyor.\nSilinmiş görünüyor.",
        "postedit-confirmation-created": "Sayfa oluşturuldu.",
        "postedit-confirmation-restored": "Sayfa geri yüklendi.",
        "postedit-confirmation-saved": "Değişikliğiniz kaydedildi.",
+       "postedit-confirmation-published": "Değişikliğiniz yayımlandı.",
        "edit-already-exists": "Yeni sayfa oluşturulamıyor.\nSayfa zaten mevcut.",
        "defaultmessagetext": "Varsayılan mesaj metni",
        "content-failed-to-parse": "$1 modeli için $2 içerik türü çözümlenemedi: $3",
        "invalid-content-data": "Geçersiz içerik verisi",
        "content-not-allowed-here": "\"$1\" içeriğine, [[$2]] sayfasında izin verilmemekte.",
        "editwarning-warning": "Bu sayfadan ayrılmak yaptığınız herhangi bir değişikliği kaybetmenize sebep olabilir.\nEğer giriş yaptıysanız, bu uyarıyı, tercihlerinizin \"{{int:prefs-editing}}\" bölümünde devre dışı bırakabilirsiniz.",
+       "editpage-invalidcontentmodel-title": "İçerik modeli desteklenmiyor",
        "editpage-invalidcontentmodel-text": "\"$1\" içerik modeli desteklenmemektedir.",
        "editpage-notsupportedcontentformat-title": "İçerik biçimi desteklenmiyor",
        "editpage-notsupportedcontentformat-text": "$1 içerik biçimi $2 içerik modeli tarafından desteklenmiyor.",
        "content-model-css": "CSS",
        "content-json-empty-object": "Boş nesne",
        "content-json-empty-array": "Boş dizi",
+       "deprecated-self-close-category": "Kendiliğinden geçersiz HTML etiketlerini kullanan sayfalar",
+       "deprecated-self-close-category-desc": "Sayfa, <code>&lt;b/></code> veya <code>&lt;span/></code> gibi kendiliğinden geçersiz HTML etiketleri içeriyor. Bunların davranışları yakında HTML5 belirtimiyle tutarlı olacak şekilde değişecektir, bu nedenle wikitext'deki kullanımları, kullanımdan kaldırılır.",
        "duplicate-args-warning": "<strong>Uyarı:</strong>[[:$1]] [[:$2]] şablonunu \"$3\" parametresi için birden fazla değerle çağırıyor. Sadece sağlanan son değer kullanılacak.",
        "duplicate-args-category": "Yinelenen şablon değişkenleri kullanan sayfalar",
        "duplicate-args-category-desc": "Sayfada içeren şablonları çağırmak için bu terimler kullanılır <code><nowiki>{{foo|bar=1|bar=2}}</nowiki></code> or <code><nowiki>{{foo|bar|1=baz}}</nowiki></code>.",
        "post-expand-template-argument-warning": "'''Uyarı:''' Bu sayfa çok fazla genişleme boyutuna sahip en az bir şablon değişkeni içeriyor.\nBu değişkenler atlandı.",
        "post-expand-template-argument-category": "Geçersiz şablon değiştirgenleri içeren sayfalar",
        "parser-template-loop-warning": "Şablon düğümü tespit edildi: [[$1]]",
+       "template-loop-category": "Şablon döngülü sayfalar",
+       "template-loop-category-desc": "Sayfa bir şablon döngüsü içermektedir. Örneğin, kendini sürekli olarak çağıran bir şablon.",
+       "template-loop-warning": "<strong>Uyarı:</strong> Bu sayfa, bir şablon döngüsüne (sonsuz yinelemeli çağrı) neden olan [[:$1]] şablonunu çağırmaktadır.",
        "parser-template-recursion-depth-warning": "Şablon özyineleme yoğunluğu sınırı aşıldı ($1)",
        "language-converter-depth-warning": "Dil çevirici derinlik sınırı aşıldı ($1)",
        "node-count-exceeded-category": "Düğüm sayısı aşılan sayfalar",
        "expansion-depth-exceeded-warning": "Sayfa genişletme derinliği aşıldı",
        "parser-unstrip-loop-warning": "Yineleme döngüsü algılandı",
        "unstrip-depth-warning": "($1) yineleme sınırı aşıldı",
+       "unstrip-depth-category": "Sızıntı derinliği sınırının aşıldığı sayfalar",
        "converter-manual-rule-error": "Elle yapılandırma dil dönüşüm kuralı hatası tespit edildi",
        "undo-success": "Bu değişiklik geri alınabilir. Lütfen aşağıdaki karşılaştırmayı kontrol edin, gerçekten bu değişikliği yapmak istediğinizden emin olun ve sayfayı kaydederek bir önceki değişikliği geriye alın.",
        "undo-failure": "Değişikliklerin çakışması nedeniyle geri alma işlemi başarısız oldu.",
+       "undo-main-slot-only": "Düzenleme, ana alanın dışındaki içeriği içerdiği için geri alınamaz.",
        "undo-norev": "Değişiklik geri alınamaz çünkü ya silinmiş ya da varolmamaktadır.",
        "undo-nochange": "Düzeltme zaten geri alınmış.",
        "undo-summary": "$1 değişikliği [[Special:Contributions/$2|$2]] ([[User talk:$2|mesaj]]) tarafından geri alındı.",
        "diff-multi-sameuser": "(Aynı kullanıcının {{PLURAL:$1|aradaki bir diğer değişikliği|aradaki diğer $1 değişikliği}} gösterilmiyor)",
        "diff-multi-otherusers": "({{PLURAL:$2|Bir diğer kullanıcıdan|$2 kullanıcıdan}} {{PLURAL:$1|bir ara revizyon|$1 ara revizyon}} gösterilmiyor)",
        "diff-multi-manyusers": "($2 kullancıdan fazla {{PLURAL:$2|kullanıcı|kullanıcı}} tarafından yapılan {{PLURAL:$1|bir ara revizyon|$1 ara revizyon}} gösterilmiyor)",
+       "diff-paragraph-moved-tonew": "Paragraf taşındı. Yeni yere gitmek için tıklayın.",
+       "diff-paragraph-moved-toold": "Paragraf taşındı. Eski yere gitmek için tıklayın.",
        "difference-missing-revision": "Bu farkın {{PLURAL:$2|bir revizyonu|$2 revizyonu}} ($1) {{PLURAL:$2|bulunamadı|bulunamadı}}.\n\nBu genellikle, silinen bir sayfaya olan eski tarihli bir fark sayfasına bağlantılardan dolayı olur.\nAyrıntılar [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} silme günlüğünde] bulunabilir.",
        "searchresults": "Arama sonuçları",
+       "search-filter-title-prefix": "Sadece başlığı \"$1\" ile başlayan sayfalarda arama",
+       "search-filter-title-prefix-reset": "Tüm sayfalarda ara",
        "searchresults-title": "\"$1\" için arama sonuçları",
        "titlematches": "Madde adı eşleşiyor",
        "textmatches": "Sayfa metni eşleşiyor",
        "prefs-watchlist-edits": "İzleme listesinde gösterilecek en fazla değişiklik sayısı:",
        "prefs-watchlist-edits-max": "En fazla sayı: 1000",
        "prefs-watchlist-token": "İzleme listesi anahtarı:",
+       "prefs-watchlist-managetokens": "Anahtarları yönet",
        "prefs-misc": "Diğer ayarlar",
        "prefs-resetpass": "Parolayı değiştir",
        "prefs-changeemail": "E-posta adresini değiştir veya kaldır",
        "stub-threshold-disabled": "Devre dışı",
        "recentchangesdays": "Son değişikliklerde gösterilecek günler:",
        "recentchangesdays-max": "(en fazla $1 {{PLURAL:$1|gün|gün}})",
-       "recentchangescount": "Varsayılan olarak gösterilecek değişiklik sayısı:",
-       "prefs-help-recentchangescount": "Bu, son değişiklikleri, sayfa geçmişlerini ve günlükleri içerir.",
-       "prefs-help-watchlist-token2": "Bu izleme listenizin gizli anahtarıdır. Anahtarı bilen herkes izleme listenizi görebilir. Bu nedenle kimseyle paylaşmayın. [[Special:ResetTokens|Bu anahtarı sıfırlamak isterseniz buraya tıklayın]].",
+       "recentchangescount": "Son değişiliklerde, sayfa geçmişlerinde ve günlüklerde varsayılan olarak gösterilecek değişiklik sayısı:",
+       "prefs-help-recentchangescount": "Azami sayı: 1000",
+       "prefs-help-watchlist-token2": "Bu izleme listenizin gizli anahtarıdır.\nAnahtarı bilen herkes izleme listenizi görebilir, bu nedenle kimseyle paylaşmayın.\nEğer isterseniz, [[Special:ResetTokens|sıfırlayabilirsiniz]].",
+       "prefs-help-tokenmanagement": "Hesabınızın izleme listenizdeki web akışına erişebilecek gizli anahtarını görebilir ve sıfırlayabilirsiniz. Anahtarı bilen herkes izleme listenizi okuyabilecek, bu yüzden paylaşmayın.",
        "savedprefs": "Tercihleriniz kaydedildi.",
        "savedrights": "{{GENDER:$1|$1}} için kullanıcı grupları kaydedildi.",
        "timezonelegend": "Zaman dilimi:",
        "timezoneregion-indian": "Hint Okyanusu",
        "timezoneregion-pacific": "Pasifik Okyanusu",
        "allowemail": "Diğer kullanıcıların bana e-posta gönderebilmesine izin ver",
+       "email-allow-new-users-label": "Yepyeni kullanıcılardan e-postalara izin ver",
        "email-blacklist-label": "Şu kullanıcıların bana e-posta göndermesine izin verme:",
        "prefs-searchoptions": "Arama",
        "prefs-namespaces": "İsim alanları",
        "default": "varsayılan",
        "prefs-files": "Dosyalar",
        "prefs-custom-css": "Özel CSS",
+       "prefs-custom-json": "Özel JSON",
        "prefs-custom-js": "Özel JS",
-       "prefs-common-config": "Tüm temalar için paylaşılan CSS/JS:",
+       "prefs-common-config": "Tüm temalar için paylaşılan CSS/JSON/Javascript:",
        "prefs-reset-intro": "Bu sayfayı tercihlerinizi site varsayılanına döndürmek için kullanabilirsiniz. Bu geri alınamaz.",
        "prefs-emailconfirm-label": "E-posta doğrulaması:",
        "youremail": "E-posta:",
        "prefs-dateformat": "Tarih biçemi",
        "prefs-timeoffset": "Saat farkı",
        "prefs-advancedediting": "Genel seçenekler",
+       "prefs-developertools": "Geliştirici araçları",
        "prefs-editor": "Editör",
        "prefs-preview": "Önizleme",
        "prefs-advancedrc": "Gelişmiş seçenekler",
+       "prefs-opt-out": "İyileştirmeleri devre dışı bırak",
        "prefs-advancedrendering": "Gelişmiş seçenekler",
        "prefs-advancedsearchoptions": "Gelişmiş seçenekler",
        "prefs-advancedwatchlist": "Gelişmiş seçenekler",
        "userrights-user-editname": "Kullanıcı adı giriniz:",
        "editusergroup": "Kullanıcı gruplarını gör",
        "editinguser": "<strong>'''[[User:$1|$1]]'''</strong> $2 kullanıcısının yetkileri değiştiriliyor",
+       "viewinguserrights": "<strong>[[User:$1|$1]]</strong> $2 kullanıcısının {{GENDER:$1|kullanıcı}} haklarını görüntüleme",
        "userrights-editusergroup": "{{GENDER:$1|Kullanıcı}} gruplarını düzenle",
        "userrights-viewusergroup": "{{GENDER:$1|Kullanıcı}} gruplarını gör",
        "saveusergroups": "{{GENDER:$1|Kullanıcı}} gruplarını kaydet",
        "userrights-groupsmember": "İçinde olduğu gruplar:",
        "userrights-groupsmember-auto": "Saklı olarak içinde olduğu gruplar:",
        "userrights-groupsmember-type": "$1",
-       "userrights-groups-help": "Bu kullanıcının içinde olduğu grupları değiştirebilirsiniz:\n* Seçili bir kutu, kullanıcının o gruba dahil olduğunu anlatır.\n* Seçilmemiş bir kutu, kullanıcının o gruba dahil olmadığını anlatır.\n* *, grubu bir kez ekledikten sonra kaldıramayacağınızı veya tam tersi kaldırdıktan sonra ekleyemeyeceğiniz belirtir.\n* #, grubun sona erme zamanını yalnızca öne çekebileceğinizi, ileri alamayacağınızı belirtir.",
+       "userrights-groups-help": "Bu kullanıcının içinde olduğu grupları değiştirebilirsiniz:\n* Seçili bir kutu, kullanıcının o gruba dahil olduğunu anlatır.\n* Seçilmemiş bir kutu, kullanıcının o gruba dahil olmadığını anlatır.\n* *, grubu bir kez ekledikten sonra kaldıramayacağınızı veya tam tersi kaldırdıktan sonra ekleyemeyeceğiniz belirtir.\n* #, grup üyeliğinin sona erme zamanını yalnızca öne çekebileceğinizi, ileri alamayacağınızı belirtir.",
        "userrights-reason": "Neden:",
        "userrights-no-interwiki": "Diğer vikilerdeki kullanıcıların izinlerini değiştirmeye yetkiniz yok.",
        "userrights-nodatabase": "$1 veritabanı mevcut veya bölgesel değil",
        "userrights-expiry-existing": "Mevcut bitiş süresi: $2 $3",
        "userrights-expiry-othertime": "Diğer süre:",
        "userrights-expiry-options": "1 gün:1 day,1 hafta:1 week,1 ay:1 month,3 ay:3 months,6 ay:6 months,1 yıl:1 year",
+       "userrights-invalid-expiry": "\"$1\" grubunun süre sonu geçersiz.",
        "userrights-expiry-in-past": "\"$1\" grubunun bitiş süresi geçmişte.",
+       "userrights-cannot-shorten-expiry": "Üyelik süresinin sona ermesini \"$1\" grubunda ileriye taşıyamazsınız. Yalnızca bu grubu ekleme ve kaldırma izni olan kullanıcılar, sürenin dolduğu süreyi getirebilir.",
        "userrights-conflict": "Kullanıcı hakları değişikliklerinde çakışma! Lütfen değişikliklerinizi gözden geçirin ve onaylayın.",
        "group": "Grup:",
        "group-user": "Kullanıcılar",
        "right-editcontentmodel": "Sayfanın içerik modelini düzenle",
        "right-editinterface": "Kullanıcı arayüzünü değiştirmek",
        "right-editusercss": "Diğer kullanıcıların CSS dosyalarında değişiklik yap",
+       "right-edituserjson": "Diğer kullanıcıların JSON dosyalarını düzenle",
        "right-edituserjs": "Diğer kullanıcıların JS dosyalarında değişiklik yap",
        "right-editmyusercss": "Kendi kullanıcı CSS dosyaları düzenle",
+       "right-editmyuserjson": "Kendi kullanıcı JSON dosyalarını düzenle",
        "right-editmyuserjs": "Kendi kullanıcı JavaScript dosyalarını düzenle",
        "right-viewmywatchlist": "Kendi izleme listeni gör",
        "right-editmywatchlist": "Kendi izleme listeni düzenle. Not, bazı eylemler bu yetki olmadan da sayfa ekleyebilir.",
        "right-siteadmin": "Veritabanını kilitle ve kilidi aç",
        "right-override-export-depth": "Sayfaları, derinlik 5'e kadar bağlantılı sayfalarla beraber, dışa aktar",
        "right-sendemail": "Diğer kullanıcılara e-posta gönder",
-       "right-managechangetags": "Veritabanında [[Special:Tags|etiket]] oluşturma veya silme",
+       "right-managechangetags": "[[Special:Tags|Etiket]] oluşturma ve (de)aktive etme",
        "right-applychangetags": "Değişiklikleriyle beraber [[Special:Tags|etiketleri]] uygula",
        "right-changetags": "Tekil sürümler ve günlük kayıtlarına rastgele [[Special:Tags|etiket]] ekleme veya çıkarma",
+       "right-deletechangetags": "Veritabanından [[Special:Tags|etiketleri]] silin",
+       "grant-generic": "\"$1\" hak paketi",
+       "grant-group-page-interaction": "Sayfalarla etkileşim kur",
+       "grant-group-file-interaction": "Medya ile etkileşim kur",
+       "grant-group-watchlist-interaction": "İzleme listenle etkileşim kur",
        "grant-group-email": "E-posta gönder",
+       "grant-group-customization": "Özelleştirme ve tercihler",
+       "grant-group-private-information": "Sizinle ilgili özel verilere erişme",
+       "grant-group-other": "Çeşitli aktivite",
+       "grant-blockusers": "Kullanıcıları engelle ve engeli kaldır",
+       "grant-createaccount": "Hesap oluştur",
        "grant-createeditmovepage": "Sayfaları oluşturma, düzenleme ve taşıma",
-       "grant-editmycssjs": "Kullanıcı CSS/JavaScript'ini düzenle",
+       "grant-delete": "Sayfaları, sürümleri ve günlük girdileri sil",
+       "grant-editinterface": "MediaWiki alanadını ve kullanıcı CSS/JSON/JavaScript'ini düzenle",
+       "grant-editmycssjs": "Kullanıcı CSS/JSON/JavaScript'ini düzenle",
        "grant-editmyoptions": "Kullanıcı tercihlerini Düzenle",
        "grant-editmywatchlist": "İzleme listeni düzenle",
+       "grant-editpage": "Mevcut sayfaları düzenle",
        "grant-editprotected": "Korumalı sayfaları Düzenle",
+       "grant-highvolume": "Yüksek hacimli düzenleme",
+       "grant-oversight": "Kullanıcıları gizle ve sürümleri durdur",
        "grant-patrol": "Sayfadaki değişiklikleri incele",
+       "grant-privateinfo": "Özel bilgilere eriş",
+       "grant-protect": "Sayfaları koru ve korumasını kaldır",
        "grant-sendemail": "Diğer kullanıcılara e-posta gönder",
        "grant-uploadeditmovefile": "Dosya yükle, yenisiyle değiştir ve taşı",
        "grant-uploadfile": "Dosya yükle",
        "recentchanges-legend": "Son değişiklikler seçenekleri",
        "recentchanges-summary": "Vikide yapılan en son değişiklikleri bu sayfadan izleyin.",
        "recentchanges-noresult": "Belirtilen kriterlere uyan herhangi bir değişiklik bulunamadı.",
+       "recentchanges-timeout": "Bu arama zaman aşımına uğradı. Farklı arama parametrelerini denemek isteyebilirsiniz.",
+       "recentchanges-network": "Teknik bir hatadan dolayı sonuç yüklenemedi. Lütfen sayfayı yenilemeyi deneyin.",
+       "recentchanges-notargetpage": "Bu sayfa ile ilgili değişiklikleri görmek için yukarıdaya bir sayfa adı girin.",
        "recentchanges-feed-description": "Bu beslemede, viki'de yapılan en son değişiklikleri takip edin.",
        "recentchanges-label-newpage": "Bu değişiklikle yeni bir sayfa oluşturuldu",
        "recentchanges-label-minor": "Bu küçük bir değişiklik",
        "recentchanges-legend-heading": "<strong>Gösterge:</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (ayrıca [[Special:NewPages|yeni sayfalar listesine]] bakınız)",
        "recentchanges-submit": "Göster",
+       "rcfilters-tag-remove": "'$1' kaldır",
        "rcfilters-legend-heading": "<strong>Kısaltmalar listesi:</strong>",
        "rcfilters-other-review-tools": "Diğer inceleme araçları",
        "rcfilters-group-results-by-page": "Sayfalandırılmış grup sonuçları",
        "rcfilters-activefilters": "Etkin süzgeçler",
+       "rcfilters-activefilters-hide": "Gizle",
+       "rcfilters-activefilters-show": "Göster",
+       "rcfilters-activefilters-hide-tooltip": "Etkin Filtreler alanını gizle",
+       "rcfilters-activefilters-show-tooltip": "Etkin Filtreler alanını göster",
        "rcfilters-advancedfilters": "Gelişmiş süzgeçler",
        "rcfilters-limit-title": "Gösterilecek sonuçlar",
        "rcfilters-limit-and-date-label": "$1 değişiklik, $2",
        "rcfilters-hours-title": "Son saatler",
        "rcfilters-days-show-days": "$1 gün",
        "rcfilters-days-show-hours": "$1 saat",
+       "rcfilters-highlighted-filters-list": "Vurgulanan: $1",
        "rcfilters-quickfilters": "Kaydedilmiş süzgeçler",
        "rcfilters-quickfilters-placeholder-title": "Henüz hiçbir süzgeç kaydedilmedi",
        "rcfilters-quickfilters-placeholder-description": "Süzgeç ayarlarınızı kaydetmek ve sonrasında bunları kullanmak için, aşağıda Aktif Süzgeçler alanındaki yer imi simgesine tıklayın.",
        "rcfilters-savedqueries-rename": "Yeniden adlandır",
        "rcfilters-savedqueries-setdefault": "Varsayılan olarak belirle",
        "rcfilters-savedqueries-unsetdefault": "Varsayılan olmaktan çıkar",
-       "rcfilters-savedqueries-remove": "Kaldır",
+       "rcfilters-savedqueries-remove": "Sil",
        "rcfilters-savedqueries-new-name-label": "Ad",
        "rcfilters-savedqueries-new-name-placeholder": "Süzgecin amacını tanımlayın",
        "rcfilters-savedqueries-apply-label": "Süzgeç oluştur",
+       "rcfilters-savedqueries-apply-and-setdefault-label": "Varsayılan filtre oluştur",
+       "rcfilters-savedqueries-cancel-label": "İptal",
        "rcfilters-savedqueries-add-new-title": "Mevcut süzgeç ayarlarını kaydet",
+       "rcfilters-savedqueries-already-saved": "Bu filtreler zaten kaydedildi. Yeni bir Kayıtlı Filtre oluşturmak için ayarlarınızı değiştirin.",
        "rcfilters-restore-default-filters": "Varsayılan süzgeçleri geri getir",
        "rcfilters-clear-all-filters": "Tüm süzgeçleri temizle",
        "rcfilters-show-new-changes": "Yeni değişiklikleri görüntüle",
        "rcfilters-empty-filter": "Etkin süzgeç bulunmuyor. Tüm katkıları gösteriliyor.",
        "rcfilters-filterlist-title": "Süzgeçler",
        "rcfilters-filterlist-whatsthis": "Bunlar nasıl çalışır?",
-       "rcfilters-filterlist-feedbacklink": "Bu (yeni) süzgeç araçları konusunda ne düşündüğünüzü bize bildirin",
+       "rcfilters-filterlist-feedbacklink": "Bu süzgeç araçları konusunda ne düşündüğünüzü bize bildirin",
        "rcfilters-highlightbutton-title": "Sonuçları vurgula",
        "rcfilters-highlightmenu-title": "Bir renk seçin",
        "rcfilters-highlightmenu-help": "Bu özelliği vurgulamak için bir renk seçin",
        "rcfilters-filterlist-noresults": "Süzgeç bulunamadı",
        "rcfilters-noresults-conflict": "Arama kriterleri çelişkili olduğu için hiçbir sonuç bulunamadı",
-       "rcfilters-filtergroup-authorship": "Düzenleme sahipliği",
+       "rcfilters-state-message-subset": "Buu filtrenin etkisi yok çünkü sonuçları aşağıdaki, daha geniş {{PLURAL:$2|filtreye|filtrelere}} dahil edilmiştir (ayırt etmek için vurgulamayı deneyin): $1",
+       "rcfilters-state-message-fullcoverage": "Bu gruptaki tüm filtreleri seçmek, hiçbirini seçmemekle aynıdır; bu nedenle bu filtrenin etkisi yoktur. Grup şunları içerir: $1",
+       "rcfilters-filtergroup-authorship": "Katkı sahipliği",
        "rcfilters-filter-editsbyself-label": "Senin değişiklikleriniz",
        "rcfilters-filter-editsbyself-description": "Kendi katkılarınız.",
        "rcfilters-filter-editsbyother-label": "Başkalarının düzenlemeleri",
        "rcfilters-filter-editsbyother-description": "Kendi düzenlemeleriniz hariç bütün düzenlemeler.",
-       "rcfilters-filtergroup-userExpLevel": "Deneyim düzeyi (yalnızca kayıtlı kullanıcılar için)",
+       "rcfilters-filtergroup-userExpLevel": "Kullanıcı kaydı ve deneyim",
        "rcfilters-filter-user-experience-level-registered-label": "Kayıtlı",
        "rcfilters-filter-user-experience-level-registered-description": "Oturum açmış editörler.",
        "rcfilters-filter-user-experience-level-unregistered-label": "Kayıtlı olmayan",
        "rcfilters-filter-user-experience-level-newcomer-label": "Yeni gelenler",
        "rcfilters-filter-user-experience-level-newcomer-description": "10'dan az düzenlemesi veya 4 günden az etkinliği olan kayıtlı kullanıcılar.",
        "rcfilters-filter-user-experience-level-learner-label": "Öğreniciler",
-       "rcfilters-filter-user-experience-level-learner-description": "\"Yeni gelenler\"den daha fazla gün boyunca etkinlik ve daha fazla düzenleme, ancak \"Deneyimli kullanıcılar\"dan daha az etkinlik ve düzenleme.",
+       "rcfilters-filter-user-experience-level-learner-description": "Deneyimi \"Yeni gelenler\" ve \"Deneyimli kullanıcılar\" arasındaki editörler.",
        "rcfilters-filter-user-experience-level-experienced-label": "Deneyimli kullanıcılar",
-       "rcfilters-filter-user-experience-level-experienced-description": "30'dan fazla gün etkinlik ve 500'den fazla düzenleme.",
+       "rcfilters-filter-user-experience-level-experienced-description": "30'dan fazla gün etkinliğe ve 500'den fazla düzenlemeye sahip kayıtlı editörler.",
        "rcfilters-filtergroup-automated": "Otomatikleştirilmiş katkılar",
        "rcfilters-filter-bots-label": "Bot",
        "rcfilters-filter-bots-description": "Otomatikleştirilmiş araçlar tarafından yapılan düzenlemeler.",
        "rcfilters-filter-humans-label": "İnsan (bot değil)",
        "rcfilters-filter-humans-description": "İnsan editörler tarafından yapılan düzenlemeler.",
        "rcfilters-filtergroup-reviewstatus": "İnceleme durumu",
+       "rcfilters-filter-reviewstatus-unpatrolled-description": "Devriye onayından el ile ya da otomatik olarak geçmemiş düzenlemeler.",
        "rcfilters-filter-reviewstatus-unpatrolled-label": "Devriye onayından geçmemiş",
+       "rcfilters-filter-reviewstatus-manual-description": "Devriye onayından el ile geçmiş düzenlemeler.",
        "rcfilters-filtergroup-significance": "Önem",
        "rcfilters-filter-minor-label": "Küçük düzenlemeler",
        "rcfilters-filter-minor-description": "Yazarın küçük olarak etiketlediği düzenlemeler.",
        "rcfilters-filter-major-label": "Küçük olmayan düzenlemeler",
        "rcfilters-filter-major-description": "Küçük olarak etiketlenmemiş düzenlemeler.",
+       "rcfilters-filtergroup-watchlist": "İzlenen sayfalar",
        "rcfilters-filter-watchlist-watched-label": "İzleme listesinde",
+       "rcfilters-filter-watchlist-watched-description": "İzleme listenizdeki sayfalarda değişiklikler.",
+       "rcfilters-filter-watchlist-watchednew-label": "Yeni İzleme listesi değişiklikleri",
+       "rcfilters-filter-watchlist-watchednew-description": "Değişiklikler gerçekleştiğinden beri ziyaret etmediğiniz izleme listenizdeki sayfalarda yapılan değişiklikler.",
        "rcfilters-filter-watchlist-notwatched-label": "İzleme listesinde değil",
+       "rcfilters-filter-watchlist-notwatched-description": "İzleme listenizdeki sayfalardaki değişiklikler hariç her şey.",
        "rcfilters-filtergroup-watchlistactivity": "İzleme listesi faaliyetleri",
        "rcfilters-filter-watchlistactivity-unseen-label": "Görülmemiş değişiklikler",
+       "rcfilters-filter-watchlistactivity-unseen-description": "Değişiklikler gerçekleştiğinden beri ziyaret etmediğiniz sayfalardaki değişiklikler.",
        "rcfilters-filter-watchlistactivity-seen-label": "Görülmüş değişiklikler",
        "rcfilters-filtergroup-changetype": "Değişiklik türü",
        "rcfilters-filter-pageedits-label": "Sayfa düzenlemeleri",
        "rcfilters-filter-categorization-description": "Kategorilere eklenen veya kaldırılan sayfaların kayıtları.",
        "rcfilters-filter-logactions-label": "Günlüğü tutulan işlemler",
        "rcfilters-filter-logactions-description": "Hizmetli işlemleri, hesap oluşturmalar, sayfa silmeler, yüklemeler...",
+       "rcfilters-filtergroup-lastRevision": "En son sürümler",
        "rcfilters-filter-lastrevision-label": "Son revizyon",
+       "rcfilters-filter-lastrevision-description": "Bir sayfadaki en yeni değişiklik.",
        "rcfilters-filter-previousrevision-label": "Son revizyon değil",
        "rcfilters-filter-excluded": "Hariç",
        "rcfilters-exclude-button-off": "Seçileni hariç tut",
        "rcfilters-exclude-button-on": "Seçilen hariç",
        "rcfilters-view-tags": "Etiketli düzenlemeler",
+       "rcfilters-view-namespaces-tooltip": "Sonuçları ad alanına göre filtrele",
+       "rcfilters-view-tags-tooltip": "Sonuçları düzenleme etiketlerini kullanarak filtrele",
+       "rcfilters-view-return-to-default-tooltip": "Ana filtre menüsüne dön",
+       "rcfilters-view-tags-help-icon-tooltip": "Etiketli düzenlemeler hakkında daha fazla bilgi edin",
        "rcfilters-liveupdates-button": "Canlı güncelleme",
        "rcfilters-liveupdates-button-title-on": "Canlı güncellemeyi kapat",
        "rcfilters-liveupdates-button-title-off": "Yeni değişiklikleri yapıldıkları anda görüntüleyin",
-       "rcfilters-watchlist-markseen-button": "Tüm değişiklileri görüldü olarak işaretle",
+       "rcfilters-watchlist-markseen-button": "Tüm değişiklikleri görüldü olarak işaretle",
+       "rcfilters-watchlist-edit-watchlist-button": "İzlenen sayfaların listesini düzenle",
+       "rcfilters-watchlist-showupdated": "Gerçekleştirilen değişikliklerden bu yana ziyaret etmediğiniz sayfalarda yapılan değişiklikler <strong>koyu</strong> renktedir.",
+       "rcfilters-preference-label": "Son Değişikliklerin geliştirilmiş sürümünü gizle",
+       "rcfilters-watchlist-preference-label": "İzleme Listesinin geliştirilmiş sürümünü gizle",
        "rcfilters-target-page-placeholder": "Bir sayfa (ya da kategori) adı girin",
        "rcnotefrom": "<strong>$3, $4</strong> tarihinden itibaren yapılan {{PLURAL:$5|değişiklik|değişiklik}} aşağıdadır (<strong>$1</strong> tarhine kadar olanlar gösterilmektedir).",
        "rclistfrom": "$3 $2 tarihinden itibaren yeni değişiklikleri göster",
        "apisandbox-submit": "İstek yap",
        "apisandbox-reset": "Temizle",
        "apisandbox-retry": "Tekrar dene",
+       "apisandbox-no-parameters": "Bu API modülünde parametre yok.",
        "apisandbox-helpurls": "Yardım bağlantıları",
        "apisandbox-examples": "Örnekler",
+       "apisandbox-dynamic-parameters": "Ek parametreler",
        "apisandbox-dynamic-parameters-add-label": "Parametre ekle:",
        "apisandbox-dynamic-parameters-add-placeholder": "Parametre adı",
+       "apisandbox-deprecated-parameters": "Onaylanmamış parametreler",
+       "apisandbox-fetch-token": "Anahtarı otomatik olarak doldur",
+       "apisandbox-add-multi": "Ekle",
+       "apisandbox-submit-invalid-fields-title": "Bazı alanlar geçersiz",
+       "apisandbox-submit-invalid-fields-message": "Lütfen işaretli alanları düzeltin ve tekrar deneyin.",
        "apisandbox-results": "Sonuçlar",
+       "apisandbox-sending-request": "API isteği gönderiliyor...",
+       "apisandbox-loading-results": "API sonuçları alınıyor...",
+       "apisandbox-results-error": "API sorgusu yanıtı yüklenirken bir hata oluştu: $1.",
        "apisandbox-request-url-label": "İstek URL:",
        "apisandbox-request-time": "İstek zamanı: $1",
        "apisandbox-continue": "Devam et",
        "speciallogtitlelabel": "Hedef (başlık ya da kullanıcı için {{ns:user}}:kullanıcıadı):",
        "log": "Günlükler",
        "logeventslist-submit": "Göster",
+       "logeventslist-more-filters": "Daha fazla süzgeç:",
        "all-logs-page": "Tüm genel günlükler",
        "alllogstext": "{{SITENAME}} için mevcut tüm günlüklerin birleşik gösterimi.\nGünlük tipini, kullanıcı adını (büyük-küçük harf duyarlı), ya da etkilenen sayfayı (yine büyük-küçük harf duyarlı) seçerek görünümü daraltabilirsiniz.",
        "logempty": "Kayıtlarda eşleşen bilgi yok.",
        "uctop": "(son)",
        "month": "Bu aya kadar (ve önceki aylar):",
        "year": "Bu yıla kadar (ve önceki yıllar):",
+       "date": "Şu tarihe kadar:",
        "sp-contributions-newbies": "Sadece yeni kullanıcıların katkılarını göster",
        "sp-contributions-newbies-sub": "Yeni kullanıcılar için",
        "sp-contributions-newbies-title": "Yeni hesaplar için kullanıcı katkıları",
        "whatlinkshere": "Sayfaya bağlantılar",
        "whatlinkshere-title": "\"$1\" sayfasına bağlantı veren sayfalar",
        "whatlinkshere-page": "Sayfa:",
-       "linkshere-2": "'''$1''' sayfasına bağlantısı olan sayfalar:",
-       "nolinkshere-2": "'''$1''' sayfasına bağlantı veren sayfa yok.",
-       "nolinkshere-ns-2": "Seçilen ad alanında hiçbir sayfa '''$1''' sayfasına bağlanmıyor.",
+       "linkshere": "'''$1''' sayfasına bağlantısı olan sayfalar:",
+       "nolinkshere": "'''$1''' sayfasına bağlantı veren sayfa yok.",
+       "nolinkshere-ns": "Seçilen ad alanında hiçbir sayfa '''$2''' sayfasına bağlanmıyor.",
        "isredirect": "yönlendirme sayfası",
        "istemplate": "dönüştürülme",
        "isimage": "dosya bağlantısı",
        "markedaspatrollederrornotify": "Kontrol edildi olarak işaretleme başarısız oldu.",
        "patrol-log-page": "Devriye günlüğü",
        "patrol-log-header": "Bu gözlenmiş revizyonların günlüğüdür.",
-       "log-show-hide-patrol": "Gözetim günlüğünü $1",
-       "log-show-hide-tag": "Etiket günlüğünü $1",
        "deletedrevision": "$1 sayılı eski sürüm silindi.",
        "filedeleteerror-short": "$1 dosyanın silinmesinde hata oldu",
        "filedeleteerror-long": "Dosyayı silerken hatalarla karşılaşıldı:\n\n$1",
        "newimages-legend": "Filtre",
        "newimages-label": "Dosya adı (ya da bir parçası):",
        "newimages-showbots": "Bot yüklemelerini göster",
+       "newimages-hidepatrolled": "Denetlenmiş yüklemeleri gizle",
        "noimages": "Görecek bir şey yok.",
        "ilsubmit": "Ara",
        "bydate": "kronolojik sırayla",
        "mw-widgets-titleinput-description-new-page": "sayfa henüz mevcut değil",
        "mw-widgets-titleinput-description-redirect": "$1'e yönlendirildi",
        "mw-widgets-categoryselector-add-category-placeholder": "Bir kategori ekle...",
+       "mw-widgets-usersmultiselect-placeholder": "Daha fazla ekle...",
        "date-range-from": "Şu tarihten:",
        "date-range-to": "Bu güne kadar:",
        "sessionprovider-mediawiki-session-cookiesessionprovider": "çerez tabanlı oturumlar",
index be26c1f..2251da3 100644 (file)
        "whatlinkshere": "Asirwoṭo biFaṭaṭe",
        "whatlinkshere-title": "Faṭoṭe dkitte Asiruṭo 3am\"$1\"",
        "whatlinkshere-page": "Faṭo",
-       "linkshere-2": "aFaṭoṭani masre ne 3am '''$1''':",
-       "nolinkshere-2": "Layto Faṭoṭe dkitte Asiruṭo 3am '''$1'''.",
+       "linkshere": "aFaṭoṭani masre ne 3am '''$1''':",
+       "nolinkshere": "Layto Faṭoṭe dkitte Asiruṭo 3am '''$1'''.",
        "isredirect": "redirect page",
        "istemplate": "transclusion",
        "isimage": "Asiruṭo duFayl",
index b541bc6..7068765 100644 (file)
        "whatlinkshere": "Leswi khwekelaka laha",
        "whatlinkshere-title": "Matluka lama khwekelaka eka $1",
        "whatlinkshere-page": "Tluka:",
-       "linkshere-2": "Matluka lama landzelaka makhwekela eka '''$1''':",
-       "nolinkshere-2": "Kuhava matluka lama khwekelaka eka  '''$1'''.",
+       "linkshere": "Matluka lama landzelaka makhwekela eka '''$1''':",
+       "nolinkshere": "Kuhava matluka lama khwekelaka eka  '''$1'''.",
        "isredirect": "Tluka ro kongomisa",
        "istemplate": "Swisivela ndhzawu",
        "isimage": "Xikhwekerisi xa fayili",
index 1a68426..ea93a9f 100644 (file)
        "tog-enotifwatchlistpages": "Күзәтү исемлегемдәге бит яки файл үзгәртелү турында электрон почтага хәбәр җибәрелсен",
        "tog-enotifusertalkpages": "Бәхәс битем үзгәртелү турында электрон почтага хәбәр җибәрелсен",
        "tog-enotifminoredits": "Кече үзгәртүләр турында да электрон почтага хәбәр җибәрелсен",
-       "tog-enotifrevealaddr": "Ð¥Ó\99бÓ\99Ñ\80лÓ\99Ñ\80дÓ\99 e-mail адресым күрсәтелсен",
+       "tog-enotifrevealaddr": "Ð¥Ó\99бÓ\99Ñ\80намÓ\99дÓ\99 Ð¼Ð¸Ð½ÐµÐ¼ Ð¿Ð¾Ñ\87Ñ\82а адресым күрсәтелсен",
        "tog-shownumberswatching": "Битне күзәтү исемлекләренә өстәгән кулланучылар санын күрсәтелсен",
        "tog-oldsig": "Хәзерге имзагыз:",
        "tog-fancysig": "Имзаның шәхси вики-билгеләмәсе (автоматик сылтамасыз)",
-       "tog-uselivepreview": "Тиз карап алуны куллану",
+       "tog-uselivepreview": "Ð\91иÑ\82не Ñ\8fңаÑ\80Ñ\82мÑ\8bйÑ\87а Ñ\82из карап алуны куллану",
        "tog-forceeditsummary": "Үзгәртүләрне тасвирлау юлы тутырылмаган булса, кисәтү",
        "tog-watchlisthideown": "Минем үзгәртүләрем күзәтү исемлегеннән яшерелсен",
        "tog-watchlisthidebots": "Бот үзгәртүләре күзәтү исемлегеннән яшерелсен",
        "virus-scanfailed": "сканерлау хатасы ($1 коды)",
        "virus-unknownscanner": "билгесез антивирус:",
        "logouttext": "<strong>Сез хисап язмагыздан чыктыгыз.</strong>\n\nКайбер битләр Сез кергән кебек күрсәтелергә мөмкин. Моны бетерү өчен браузер кэшын чистартыгыз.",
+       "cannotlogoutnow-title": "Хәзер үк чыгып булмый",
        "welcomeuser": "Рәхим итегез, $1!",
        "yourname": "Кулланучы исеме:",
        "userlogin-yourname": "Кулланучы исеме",
        "createacct-yourpasswordagain-ph": "Серсүзне кабаттан кертегез",
        "userlogin-remembermypassword": "Системада калырга",
        "userlogin-signwithsecure": "Якланган кушылу",
+       "cannotlogin-title": "Чыгып булмый",
+       "cannotlogin-text": "Системага керү мөмкин түгел.",
+       "cannotloginnow-title": "Хәзер үк кереп булмый",
        "yourdomainname": "Доменыгыз:",
        "password-change-forbidden": "Сез бу викидә серсүзне үзгәртә алмыйсыз.",
        "externaldberror": "Тышкы мәгълүмат базасы ярдәмендә аутентификация үткәндә хата чыкты, яисә тышкы хисап язмагызга үзгәрешләр кертү хокукыгыз юк.",
        "nosuchusershort": "$1 исемле кулланучы юк. Язылышыгызны тикшерегез.",
        "nouserspecified": "Сез теркәү исмегезне күрсәтергә тиешсез.",
        "login-userblocked": "Бу кулланучы тыелды. Керү тыелган.",
-       "wrongpassword": "ЯзÑ\8bлган Ñ\81еÑ\80Ñ\81үз Ð´Ó©Ñ\80еÑ\81 Ñ\82үгел. Ð¢Ð°Ð³Ñ\8bн Ð±ÐµÑ\80 Ñ\82апкÑ\8bÑ\80 Ñ\81Ñ\8bнагыз.",
+       "wrongpassword": "СеÑ\80Ñ\81үз Ñ\8fиÑ\81Ó\99 ÐºÑ\83лланÑ\83Ñ\87Ñ\8b Ð¸Ñ\81еме Ð´Ó©Ñ\80еÑ\81 Ñ\82үгел. Ð¯Ò£Ð°Ð´Ð°Ð½ Ò\97Ñ\8bеп ÐºÐ°Ñ\80агыз.",
        "wrongpasswordempty": "Серсүз юлы буш булырга тиеш түгел.",
        "passwordtooshort": "Сезсүз кимендә $1 {{PLURAL:$1|символдан}} торырга тиеш.",
        "password-name-match": "Кертелгән серсүз кулланучы исеменнән аерылырга тиеш.",
        "nowiki_tip": "Вики-форматлауны исәпкә алмау",
        "image_sample": "Мисал.jpg",
        "image_tip": "Куелган файл",
+       "media_sample": "Мисал.ogg",
        "media_tip": "Файлга сылтама",
        "sig_tip": "Имза һәм вакыт",
        "hr_tip": "Горизонталь сызык (еш кулланмагыз)",
        "savechanges": "Үзгәртүләрне саклау",
        "publishpage": "Бит ясау",
        "publishchanges": "Битне бастыру",
+       "savearticle-start": "Битне саклау...",
+       "savechanges-start": "Үзгәртүләрне саклау...",
+       "publishpage-start": "Битне бастыру...",
+       "publishchanges-start": "Төзәтмәләрне бастыру...",
        "preview": "Алдан карау",
        "showpreview": "Алдан карау",
        "showdiff": "Кертелгән үзгәртүләр",
        "anoneditwarning": "<strong>Игътибар!</strong> Сез сайтта теркәлмәдегез. Әгәрдә сез нинди дә булсә төзәтмәләр яисә үзгәртүләр кертсәгез, сезнең IP-адрес башка кулланучыларга да билгеле булачак. Сайтка <strong>[$1 керсәгез]</strong> яисә <strong>[$2 кулланучы язмасын төзесәгез]</strong>, сез керткән үзгәртүләр сезнең кулланучы язмагызга бәйләнгән булачак, шулай ук башка мөмкинлекләр дә туачак.",
        "anonpreviewwarning": "''Сез системада теркәлмәдегез.Сезнең тарафтан эшләнгән барлык үзгәртүләр дә сезнең IP-юлламагызны саклауга китерә.''",
        "missingsummary": "'''Искәртү.''' Сез үзгәртүгә кыскача тасвирлау язмадыгыз. Сез «Битне саклау» төймәсенә тагын бер тапкыр бассагыз, үзгәртүләр тасвирламасыз сакланачак.",
-       "missingcommenttext": "Ð\90Ñ\81ка Ñ\82аÑ\81виÑ\80лама язуыгыз сорала.",
+       "missingcommenttext": "Ð\9aомменÑ\82 язуыгыз сорала.",
        "missingcommentheader": "<strong>Искәртү:</strong> Сез шәрехнең темасын күрсәтмәгәнсез.\n«$1» төймәсенә кабат бассагыз, үзгәртүләр темасыз язылачак.",
        "summary-preview": "Төзәтмәләрне карап чыгу:",
        "subject-preview": "Башисемне алдан карау:",
        "blockedtitle": "Кулланучы тыелды",
-       "blockedtext": "'''Сезнең хисап язмагыз яки IP адресыгыз тыелган.'''\n\nТыючы идарәче: $1.\nКүрсәтелгән сәбәп: ''$2''.\n\n* Тыю башланган вакыт: $8\n* Тыю ахыры: $6\n* Тыелулар саны: $7\n\nСез $1 яки башка [[{{MediaWiki:Grouppage-sysop}}|идарәчегә]] тыю буенча сорауларыгызны җибәрә аласыз.\nИсегездә тотыгыз: әгәр сез теркәлмәгән һәм электрон почта адресыгызны дәлилләмәгән булсагыз ([[Special:Preferences|дәлилләү өчен шәхси көйләүләр монда]]), идарәчегә хат җибәрә алмыйсыз. Шулай ук тыю вакытында сезнең хат җибәрү мөмкинлегегезне чикләгән булырга да мөмкиннәр.\nСезнең IP адресы — $3, тыю идентификаторы — #$5.\nХатларда бу мәгълүматны күрсәтергә онытмагыз.",
+       "blockedtext": "<strong>Сезнең хисап язмагыз яки IP адресыгыз тыелган.</strong>\n\nТыючы идарәче: $1.\nКүрсәтелгән сәбәп: <em>$2</em>.\n\n* Тыю башланган вакыт: $8\n* Тыю ахыры: $6\n* Тыелулар саны: $7\n\nСез $1 яки башка [[{{MediaWiki:Grouppage-sysop}}|идарәчегә]] тыю буенча сорауларыгызны җибәрә аласыз.\nИсегездә тотыгыз: әгәр сез теркәлмәгән һәм электрон почта адресыгызны [[Special:Preferences|көйләнмәләрдә]] дәлилләмәгән булсагыз, сез бирелгән «{{int:emailuser}}» мөмкинчелекне куллана алмаячаксыз. Шулай ук тыю вакытында сезнең хат җибәрү мөмкинлегегезне чикләгән булырга да мөмкиннәр.\nСезнең IP адресыгыз — $3, тыю таныклыгы — $5.\nЗинһар, хатларда бу мәгълүматны күрсәтергә онытмагыз.",
        "autoblockedtext": "Сезнең IP адресыгыз, аның тыелган кулланучы тарафыннан кулланылуы сәбәпле, автомат рәвештә тыелды.\nУл кулланучыны тыючы идарәче: $1. Күрсәтелгән сәбәп:\n\n:''$2''\n\n* Тыю башланган вакыт: $8\n* Тыю ахыры: $6\n* Тыелулар саны: $7\n\nСез $1 яки башка [[{{MediaWiki:Grouppage-sysop}}|идарәчегә]] тыю буенча сорауларыгызны җибәрә аласыз.\nИсегездә тотыгыз: әгәр сез теркәлмәгән һәм электрон почта адресыгызны дәлилләмәгән булсагыз ([[Special:Preferences|дәлилләү өчен шәхси көйләүләр монда]]), идарәчегә хат җибәрә алмыйсыз. Шулай ук тыю вакытында сезнең хат җибәрү мөмкинлегегезне чикләгән булырга да мөмкиннәр.\nСезнең IP адресы — $3, тыю идентификаторы — #$5.\nХатларда бу мәгълүматны күрсәтергә онытмагыз.",
        "blockednoreason": "сәбәп күрсәтелмәгән",
        "whitelistedittext": "Сез битләрне үзгәртү өчен $1 тиеш.",
        "search-interwiki-caption": "Тугандаш проектлар нәтиҗәсе",
        "search-interwiki-default": "$1 нәтиҗә:",
        "search-interwiki-more": "(тагын)",
+       "search-interwiki-more-results": "күбрәк нәтиҗәләр",
        "search-relatedarticle": "Бәйле",
        "searchrelated": "бәйле",
        "searchall": "барлык",
        "prefs-watchlist-edits": "Киңәйтелгән күзәтү исемлегендә күрсәтелүче төзәтмәләрнең максималь саны:",
        "prefs-watchlist-edits-max": "Максимум сан: 1000",
        "prefs-watchlist-token": "Күзәтү исемлеге токены:",
+       "prefs-watchlist-managetokens": "Токеннар беләр идарә итү",
        "prefs-misc": "Башка көйләнмәләр",
        "prefs-resetpass": "Серсүзне үзгәртү",
        "prefs-changeemail": "Электрон әрҗә адресын үзгәртү яисә бетерү",
+       "prefs-setemail": "Электрон почта адресын көйләү",
        "prefs-email": "E-mail көйләнмәләре",
        "prefs-rendering": "Күренеш",
        "saveprefs": "Саклау",
        "searchresultshead": "Эзләү",
        "stub-threshold": "Ясалма сылтамаларның бизәлеше буенча чикләүләр ($1):",
        "stub-threshold-sample-link": "мисал",
-       "stub-threshold-disabled": "ЯбÑ\8bлган",
+       "stub-threshold-disabled": "СүнгÓ\99н",
        "recentchangesdays": "Соңгы үзгәртүләрне күрсәтүче көннәр саны:",
        "recentchangesdays-max": "(иң күбе $1 {{PLURAL:$1|көн}})",
        "recentchangescount": "Төп буларак кулланучы үзгәртүләр саны:",
-       "prefs-help-recentchangescount": "Үз өченә үзгәртүләрне, битләрнең тарихын һәм язлу көндәлеген дә кертә.",
+       "prefs-help-recentchangescount": "Максимум сан: 1000",
        "prefs-help-watchlist-token2": "Бу сезнең кузәтү исемлеге өчен ясалган веб-агымының серле ачкычы.\nАны белгән һәркем сезнең күзәтү исемлегегезне карый ала, шуңа да башкаларга аны күрсәтмәгез. [[Special:ResetTokens|Ачкычны ташларга теләсәгез, әлеге юрамага басыгыз]].",
        "savedprefs": "Көйләнмәләрегез сакланды.",
        "timezonelegend": "Сәгать поясы:",
        "timezoneregion-europe": "Аурупа",
        "timezoneregion-indian": "Һинд океаны",
        "timezoneregion-pacific": "Тын океан",
-       "allowemail": "Ð\91аÑ\88ка ÐºÑ\83лланÑ\83Ñ\87Ñ\8bлаÑ\80дан Ñ\85аÑ\82лаÑ\80 Ð°Ð»Ñ\8bÑ\80га Ñ\80Ó©Ñ\85Ñ\81Ó\99Ñ\82 Ð¸Ñ\82елÑ\81ен",
+       "allowemail": "Ð\91аÑ\88ка ÐºÑ\83лланÑ\83Ñ\87Ñ\8bлаÑ\80га Ð¼Ð¸Ò£Ð° Ñ\85аÑ\82лаÑ\80 Ñ\8fзаÑ\80га Ñ\80Ó©Ñ\85Ñ\81Ó\99Ñ\82 Ð¸Ñ\82Ò¯",
        "prefs-searchoptions": "Эзләү",
        "prefs-namespaces": "Исемнәр мәйданы",
        "default": "килешү буенча",
        "prefs-files": "Файллар",
        "prefs-custom-css": "Шәхси CSS",
+       "prefs-custom-json": "Кулланма JSON",
        "prefs-custom-js": "Шәхси JS",
-       "prefs-common-config": "Барлык бизәлешләр өчен гомуми CSS/JS:",
+       "prefs-common-config": "Барлык бизәлешләр өчен гомуми CSS/JSON/JavaScript:",
        "prefs-reset-intro": "Бу бит сезнең көйләнмәләрегезне бетерү өчен кулланыла. Бу эшне башкару нәтиҗәсендә сез яңадан үз көйләнмәләрне яңадан кайтара алмыйсыз.",
        "prefs-emailconfirm-label": "E-mail раслау",
        "youremail": "Электрон почта:",
        "username": "{{GENDER:$1|Кулланучы исеме}}:",
        "prefs-memberingroups": "{{PLURAL:$1|Төркем}} {{GENDER:$2|әгъзасы}}:",
        "prefs-memberingroups-type": "$1",
+       "group-membership-link-with-expiry": "$1 ($2 кадәр)",
        "prefs-registration": "Теркәлү вакыты:",
        "prefs-registration-date-time": "$1",
        "yourrealname": "Чын исем:",
        "prefs-dateformat": "Вакытың форматы",
        "prefs-timeoffset": "Вакыт билгеләнеше",
        "prefs-advancedediting": "Гомуми көйләүләр",
+       "prefs-developertools": "Девелопер кораллары",
        "prefs-editor": "Мөхәррир",
        "prefs-preview": "Алдан карау",
        "prefs-advancedrc": "Киңәйтелгән көйләүләр",
        "userrights-changeable-col": "Сезнең тарафтан үзгәртелми торган төркемнәр",
        "userrights-unchangeable-col": "Сезнең тарафтан үзгәртелми торган төркемнәр",
        "userrights-irreversible-marker": "$1*",
+       "userrights-expiry": "Бетә:",
+       "userrights-expiry-othertime": "Башка вакыт:",
+       "userrights-expiry-options": "1 көн:1 day,1 атна:1 week,1 ай:1 month,3 ай:3 months,6 ай:6 months,1 ел:1 year",
        "userrights-conflict": "Кулланучы хокукларын үзгәртү конфликты! Төзәтмәләрегезне тикшерегез, аннары кабатлагыз.",
        "group": "Төркем:",
        "group-user": "Кулланучылар",
        "recentchanges-legend-heading": "<strong>Аңлатма:</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (шулай ук [[Special:NewPages|яңа битләр исемлеген]] карагыз)",
        "recentchanges-submit": "Күрсәт",
+       "rcfilters-legend-heading": "<strong>Кыскартулар тезмәсе:&nbsp;</strong>",
        "rcfilters-activefilters": "Актив фильтрлар",
        "rcfilters-limit-title": "Күрсәтү өчен үзгәртүләр",
        "rcfilters-days-title": "Соңгы көннәр",
        "rcfilters-hours-title": "Соңгы сәгатьләр",
-       "rcfilters-days-show-days": "$1 көн",
-       "rcfilters-days-show-hours": "$1 сәгать",
+       "rcfilters-days-show-days": "$1 {{PLURAL:$1|көн}}",
+       "rcfilters-days-show-hours": "$1 {{PLURAL:$1|сәгать}}",
        "rcfilters-quickfilters": "Сакланган фильтрлар",
+       "rcfilters-quickfilters-placeholder-title": "Әлегә сакланылган фильтрлар юк",
+       "rcfilters-savedqueries-remove": "Бетерү",
+       "rcfilters-savedqueries-new-name-label": "Исем",
+       "rcfilters-savedqueries-cancel-label": "Баш тарту",
        "rcfilters-savedqueries-add-new-title": "Хәзерге фильтр көйләнмәләрен саклау",
        "rcfilters-clear-all-filters": "Барлык филтерләрне чистарту",
        "rcfilters-search-placeholder": "Фильтрланы соңгы үзгәртү (карау яисә кертүне башлау)",
-       "rcfilters-filterlist-feedbacklink": "Яңа (бета) фильтрләр турында фикер калдыру",
+       "rcfilters-filterlist-feedbacklink": "Әлеге фильтрлау кораллары турында турында фикер калдырыгыз",
        "rcfilters-filtergroup-authorship": "Үзгәртүләрнең авторлыгы",
        "rcfilters-filter-editsbyself-label": "Сезнең үзгәртүләр",
        "rcfilters-filter-editsbyself-description": "Сезнең кертемегез.",
        "rcfilters-filter-editsbyother-label": "Башка кулланучыларның үзгәртүләре",
-       "rcfilters-filter-user-experience-level-registered-label": "Теркәлгән",
+       "rcfilters-filter-user-experience-level-registered-label": "Теркәлүчеләр",
        "rcfilters-filter-user-experience-level-registered-description": "Теркәлгән мөхәррирләр.",
        "rcfilters-filter-user-experience-level-unregistered-label": "Теркәлмәгәннәр",
        "rcfilters-filter-user-experience-level-unregistered-description": "Системага кермәгән мөхәррирләр.",
        "rcfilters-filter-user-experience-level-experienced-label": "Тәҗрибәле кулланучылар",
        "rcfilters-filter-user-experience-level-experienced-description": "Төзәтүләре 500 дән күбрәк һәм актив эш көннәре 30 дан артык теркәлгән мөхәррирләр",
        "rcfilters-filtergroup-automated": "Автоматлаштырылган кертем",
+       "rcfilters-filter-bots-label": "Бот",
        "rcfilters-filter-bots-description": "Автоматлаштырылган кораллар ярдәмендә ясалган үзгәртүләр.",
        "rcfilters-filter-humans-label": "Кеше (бот түгел)",
        "rcfilters-filter-humans-description": "Кешеләр ясаган үзгәртүләр.",
+       "rcfilters-filtergroup-reviewstatus": "Тикшерү статусы",
        "rcfilters-filter-minor-label": "Кече үзгәртүләр",
        "rcfilters-filter-minor-description": "«Кече үзгәртү» дип тамгаланган үзгәртүләр",
        "rcfilters-filter-major-label": "Гади үзгәртүләр",
        "rcfilters-filter-previousrevision-description": "«Соңгы юрама» булмаган барлык үзгәртүләр.",
        "rcfilters-view-tags": "Тәгләнгән үзгәртүләр",
        "rcfilters-liveupdates-button": "Автоматик яңарту",
+       "rcfilters-watchlist-markseen-button": "Бар үзгәртүләрне каралган дип билгеләргә",
+       "rcfilters-watchlist-edit-watchlist-button": "Күзәтү исемлегегезне үзгәртү",
        "rcnotefrom": "Астарак <strong>$3, $4</strong> өчен {{PLURAL:$5|үзгәртүләр күрсәтелгән}} (<strong>$1</strong> артык түгел).",
        "rclistfrom": "$3 $2 башлап яңа үзгәртүләрне күрсәт",
        "rcshowhideminor": "кече үзгәртүләрне $1",
        "recentchangeslinked-feed": "Бәйләнешле үзгәртүләр",
        "recentchangeslinked-toolbox": "Бәйләнешле үзгәртүләр",
        "recentchangeslinked-title": "\"$1\" битенә бәйләнешле үзгәртүләр",
-       "recentchangeslinked-summary": "Ð\91Ñ\83 ÐºÒ¯Ñ\80Ñ\81Ó\99Ñ\82елгÓ\99н Ð±Ð¸Ñ\82 Ð±ÐµÐ»Ó\99н Ñ\81Ñ\8bлÑ\82алган (йÓ\99 ÐºÒ¯Ñ\80Ñ\81Ó\99Ñ\82елгÓ\99н Ñ\82Ó©Ñ\80кемгÓ\99 ÐºÐµÑ\80Ñ\82кÓ\99н) Ð±Ð¸Ñ\82лÓ\99Ñ\80нең Ò¯Ð·Ð³Ó\99Ñ\80Ñ\82елмÓ\99лÓ\99Ñ\80е Ð¸Ñ\81емлеге. [[Special:Watchlist|Күзәтү исемлегегезгә]] керә торган битләр '''калын''' итеп күрсәтелгән.",
+       "recentchangeslinked-summary": "Ð\91Ñ\83 Ð±Ð¸Ñ\82Ñ\82Ñ\82Ó\99н Ñ\8fиÑ\81Ó\99 Ð±Ñ\83 Ð±Ð¸Ñ\82кÓ\99 Ñ\81Ñ\8bлÑ\82аган Ð±Ð¸Ñ\82лÓ\99Ñ\80дÓ\99ге Ò¯Ð·Ð³Ó\99Ñ\80Ñ\82мÓ\99ле ÐºÐ°Ñ\80аÑ\83 Ó©Ñ\87ен Ð±Ð¸Ñ\82нең Ð¸Ñ\81емен ÐºÐµÑ\80Ñ\82егез. (Ð\91илгеле Ð±ÐµÑ\80 Ñ\82Ó©Ñ\80кемгÓ\99 ÐºÐ°Ñ\80аган Ð±Ð¸Ñ\82лÓ\99Ñ\80не ÐºÐ°Ñ\80аÑ\83 Ó©Ñ\87ен {{ns:category}}:ТөÑ\80кем Ð¸Ñ\81емен Ñ\8fзÑ\8bгÑ\8bз).[[Special:Watchlist|Күзәтү исемлегегезгә]] керә торган битләр '''калын''' итеп күрсәтелгән.",
        "recentchangeslinked-page": "Битнең исеме:",
        "recentchangeslinked-to": "Моның урынына бу биткә бәйле булган битләрдәге үзгәртүләрне күрсәтү",
        "upload": "Файл йөкләү",
        "filehist-comment": "Искәрмә",
        "imagelinks": "Файлны куллану",
        "linkstoimage": "{{PLURAL:$1|Киләсе $1 бит|Киләсе $1 битләр|}} әлеге файлга сылтама ясый:",
+       "linkstoimage-more": "Бу файлга кимендә $1 {{PLURAL:$1|бит}} сылтама ясый.\nӘлеге исемлектә бу файлга {{PLURAL:$1| $1 сылтама}} китерелгән.\nШулай ук [[Special:WhatLinksHere/$2|тулы исемлекне]] дә карарга мөмкин.",
        "nolinkstoimage": "Бу файлга сылтаган битләр юк.",
        "linkstoimage-redirect": "$1 (файл юнәлтүе) $2",
        "duplicatesoffile": "{{PLURAL:$1|Әлеге $1 файл }} астагы файлның күчерелмәсе булып тора ([[Special:FileDuplicateSearch/$2|тулырак]]):",
        "protect-otherreason-op": "Башка сәбәп",
        "protect-dropdown": "* Гади яклау сәбәпләре\n** вандаллык\n** зур спам\n** кирәксез үзгәртүләр саны\n** популяр бит",
        "protect-edit-reasonlist": "Сәбәпләр исемлеген үзгәртү",
-       "protect-expiry-options": "1 сәгать:1 hour,1 көн:1 day,1 атна:1 week,2 атна:2 weeks,1 ай:1 month,3 ай:3 months,6 ай:6 months,1 ел:1 year,вакытсыз:infinite",
+       "protect-expiry-options": "1 сәгать:1 hour,1 көн:1 day,1 атна:1 week,2 атна:2 weeks,1 ай:1 month,3 ай:3 months,6 ай:6 months,1 ел:1 year,чикләүсез:infinite",
        "restriction-type": "Рөхсәт:",
        "restriction-level": "Мөмкинлек дәрәҗәсе:",
        "minimum-size": "Иң кечкенә зурлык",
        "sp-contributions-username": "Кулланучының IP адресы яки исеме:",
        "sp-contributions-toponly": "Соңгы юрамадагы үзгәртүләр генә күрсәтелсен",
        "sp-contributions-newonly": "Битләр ясау үзгәртмәләрен генә күрсәтү",
+       "sp-contributions-hideminor": "Кече үзгәртүләрне яшерергә",
        "sp-contributions-submit": "Эзләү",
        "whatlinkshere": "Бирегә нәрсә сылтый",
        "whatlinkshere-title": "$1 битенә сылтый торган битләр",
        "whatlinkshere-page": "Бит:",
-       "linkshere-2": "'''$1''' битенә чираттагы битләр сылтый:",
-       "nolinkshere-2": "'''$1''' битенә башка битләр сылтамыйлар.",
+       "linkshere": "'''$1''' битенә чираттагы битләр сылтый:",
+       "nolinkshere": "'''$1''' битенә башка битләр сылтамыйлар.",
        "isredirect": "юнәлтү бите",
        "istemplate": "кертүләр",
        "isimage": "файл сылтамасы",
        "ipbenableautoblock": "Кулланучы кулланган IP адресларын автоматик рәвештә тыю",
        "ipbsubmit": "Бу кулланучыны тыю",
        "ipbother": "Башка вакыт:",
-       "ipboptions": "2 сәгать:2 hours,1 көн:1 day,3 көн:3 days,1 атна:1 week,2 атна:2 weeks,1 ай:1 month,3ай:3 months,6 ай:6 months,1 ел:1 year,чикләнмәгән:infinite",
+       "ipboptions": "2 сәгать:2 hours,1 көн:1 day,3 көн:3 days,1 атна:1 week,2 атна:2 weeks,1 ай:1 month,3ай:3 months,6 ай:6 months,1 ел:1 year,чикләүсез:infinite",
        "ipb-confirm": "Тыюны раслау",
        "badipaddress": "Ялгыш IP адресы",
        "blockipsuccesssub": "Тыю башкарылган",
        "markedaspatrolledtext": "Сайланган [[:$1]] мәкаләсенең әлеге юрамасы тикшерелгән дип тамгаланды.",
        "patrol-log-page": "Тикшерү көндәлеге",
        "patrol-log-header": "Бу тикшерелгән битләрнең көндәлеге.",
-       "log-show-hide-patrol": "$1 тикшерү көндәлеге",
        "confirm-markpatrolled-button": "Ярый",
        "deletedrevision": "$1 битенең иске юрамасы бетерелде",
        "filedeleteerror-short": "Файлны бетерү хатасы: $1",
        "version-libraries-license": "Лицензия",
        "version-libraries-description": "Тасвирлама",
        "version-libraries-authors": "Авторлар",
+       "redirect": "Файл, кулланучы, бит юрама яисә көндәлек таныклыгыннан юнәлтү",
+       "redirect-summary": "Әлеге махсус бит файлга (файл исеменнән), биткә (юрама яисә бит исемлегеннән), кулланучы язмасыннан (кулланучының санлы исемлегеннән) яисә көндәлеген язмасыннан (кондәлек исемлегеннән) юнәлтә. Куллану ысулы: [[{{#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": "Мәгънәсе",
        "htmlform-datetime-placeholder": "ЕЕЕЕ-АА-КК СС:ММ:СС",
        "logentry-delete-delete": "$1 $3 битен {{GENDER:$2|бетерә}}",
        "logentry-delete-restore": "$1 $3 ($4) битен {{GENDER:$2|торгызды}}",
+       "logentry-delete-revision": "$1 $3 битендә {{PLURAL:$5|$5 юрамасының}} күренешен {{GENDER:$2|үзгәртте}}: $4",
        "revdelete-content-hid": "эчтәлек яшерелгән",
        "revdelete-summary-hid": "төзәтмәнең тасвирламасы яшерелгән",
        "revdelete-uname-hid": "кулланучының исеме яшерелгән",
        "special-characters-group-lao": "Лаос",
        "special-characters-group-khmer": "Кһмер",
        "special-characters-group-canadianaboriginal": "Канада иҗек язуы",
+       "mw-widgets-dateinput-no-date": "Дата сайланмаган",
+       "mw-widgets-dateinput-placeholder-day": "ЕЕЕЕ-АА-КК",
+       "mw-widgets-dateinput-placeholder-month": "ЕЕЕЕ-АА",
+       "date-range-from": "Башлангыч дата:",
+       "date-range-to": "Соңгы дата:",
        "randomrootpage": "Очраклы төп бит",
        "log-action-filter-all": "Барысы",
        "log-action-filter-block-block": "Тыю",
index 35aa487..cab0be7 100644 (file)
        "whatlinkshere": "Biregä närsä sıltıy",
        "whatlinkshere-title": "$1 bitenä sıltıy torğan bitlär",
        "whatlinkshere-page": "Bit:",
-       "linkshere-2": "'''$1''' bitenä çirattağı bitlär sıltıy:",
-       "nolinkshere-2": "'''$1''' bitenä başqa bitlär sıltamıylar.",
+       "linkshere": "'''$1''' bitenä çirattağı bitlär sıltıy:",
+       "nolinkshere": "'''$1''' bitenä başqa bitlär sıltamıylar.",
        "isredirect": "yünältü bite",
        "istemplate": "kertülär",
        "isimage": "fayl qullanılışı",
        "markedaspatrolledtext": "Saylanğan [[:$1]] mäqäläseneñ älege yuraması tikşerelgän dip tamğalandı.",
        "patrol-log-page": "Tikşerü köndälege",
        "patrol-log-header": "Bu tikşerelgän bitlärneñ köndälege.",
-       "log-show-hide-patrol": "$1 tikşerü köndälege",
        "deletedrevision": "$1 biteneñ iske yuraması beterelde",
        "filedeleteerror-short": "Faylnı beterü xatası: $1",
        "filedeleteerror-long": "Faylnı beterü waqıtında xatalar çıqtı:\n\n$1",
index d8971d5..712a68b 100644 (file)
        "whatlinkshere": "Аргышкан арыннар",
        "whatlinkshere-title": "«$1» деп арынче айтып турар тускай арыннар",
        "whatlinkshere-page": "Арын:",
-       "linkshere-2": "Адаандагы арыннар бээр «'''$1'''» шөлүдүп турарлар:",
-       "nolinkshere-2": "'''$1''' деп арынче шөлүтткен арыннар чок.",
+       "linkshere": "Адаандагы арыннар бээр «'''$1'''» шөлүдүп турарлар:",
+       "nolinkshere": "'''$1''' деп арынче шөлүтткен арыннар чок.",
        "isredirect": "шиглидер арын",
        "istemplate": "киирткен арыннар",
        "isimage": "файлдың холбаазы",
index c37a572..52519e5 100644 (file)
        "whatlinkshere": "Татчы чӧлсконъёс",
        "whatlinkshere-title": "«$1» вылэ чӧлскись бамъёс",
        "whatlinkshere-page": "Бам:",
-       "linkshere-2": "Та бамъёс <strong>$1</strong> вылэ чӧлско:",
+       "linkshere": "Та бамъёс <strong>$1</strong> вылэ чӧлско:",
        "isredirect": "ыстӥсь бам",
        "istemplate": "пыртон",
        "isimage": "файл линк",
index 0200aee..15bf314 100644 (file)
        "whatlinkshere": "بۇ جايدىكى ئۇلانما",
        "whatlinkshere-title": "\"$1\" بەتكە ئۇلانغان بەتلەر",
        "whatlinkshere-page": "بەت:",
-       "linkshere-2": "تۆۋەندىكى بەتلەر '''$1'''غا ئۇلانغان:",
-       "nolinkshere-2": "'''$1'''غا ئۇلانغان بەت يوق.",
-       "nolinkshere-ns-2": "تاللانغان ئات بوشلۇقىدا '''$1''' غا ئۇلانغان بەت يوق.",
+       "linkshere": "تۆۋەندىكى بەتلەر '''$1'''غا ئۇلانغان:",
+       "nolinkshere": "'''$1'''غا ئۇلانغان بەت يوق.",
+       "nolinkshere-ns": "تاللانغان ئات بوشلۇقىدا '''$2''' غا ئۇلانغان بەت يوق.",
        "isredirect": "قايتا نىشان بەلگىلەنگەن بەت",
        "istemplate": "ئۆز ئىچىگە ئالغان",
        "isimage": "ھۆججەت ئۇلانما",
        "markedaspatrollederrornotify": "چارلىيالمىغانلىق بەلگىسى قويۇلدى.",
        "patrol-log-page": "چارلاش خاتىرىسى",
        "patrol-log-header": "بۇ چارلانغان تۈزىتىلگەن نەشرى.",
-       "log-show-hide-patrol": "$1 چارلاش خاتىرىسى",
        "deletedrevision": "$1 كونا تۈزىتىلگەن نەشرى ئۆچۈرۈلدى",
        "filedeleteerror-short": "ھۆججەت ئۆچۈرۈش خاتالىقى: $1",
        "filedeleteerror-long": "ھۆججەت ئۆچۈرۈۋاتقاندا خاتالىق كۆرۈلدى:\n\n$1",
index c20ce59..bd8a3fb 100644 (file)
@@ -75,7 +75,9 @@
                        "Renamerr",
                        "Avatar6",
                        "Fitoschido",
-                       "Movses"
+                       "Movses",
+                       "Esk78",
+                       "Vlad5250"
                ]
        },
        "tog-underline": "Підкреслювання посилань:",
        "tog-watchlisthideminor": "Приховати незначні редагування у списку спостереження",
        "tog-watchlisthideliu": "Приховати редагування зареєстрованих дописувачів у списку спостереження",
        "tog-watchlistreloadautomatically": "Перезавантажувати список спостереження автоматично кожного разу, коли зміниться фільтр (вимагається JavaScript)",
-       "tog-watchlistunwatchlinks": "Ð\94одаÑ\82и Ð¼Ð¾Ð¶Ð»Ð¸Ð²Ñ\96Ñ\81Ñ\82Ñ\8c Ð´Ð»Ñ\8f Ð²Ð¸ÐºÐ»Ñ\8eÑ\87еннÑ\8f Ñ\81Ñ\82оÑ\80Ñ\96нок Ð¿Ñ\80Ñ\8fмо Ð·Ñ\96 Ñ\81Ñ\82оÑ\80Ñ\96нки Ñ\81пиÑ\81кÑ\83 Ñ\81поÑ\81Ñ\82еÑ\80еженнÑ\8f (потрібен JavaScript для функціонування)",
+       "tog-watchlistunwatchlinks": "Ð\94одаÑ\82и Ð¿Ñ\80Ñ\8fмÑ\96 Ð¼Ð°Ñ\80кеÑ\80и Ð²ÐºÐ»Ñ\8eÑ\87еннÑ\8f/виклÑ\8eÑ\87еннÑ\8f Ð·Ñ\96 Ñ\81пиÑ\81кÑ\83 Ñ\81поÑ\81Ñ\82еÑ\80еженнÑ\8f ({{int:Watchlist-unwatch}}/{{int:Watchlist-unwatch-undo}}) Ð´Ð»Ñ\8f Ñ\81Ñ\82еженнÑ\8f Ð·Ð° Ñ\81Ñ\82оÑ\80Ñ\96нками Ñ\96з Ð·Ð¼Ñ\96нами (потрібен JavaScript для функціонування)",
        "tog-watchlisthideanons": "Приховати редагування анонімних користувачів у списку спостереження",
        "tog-watchlisthidepatrolled": "Приховати відпатрульовані редагування у списку спостереження",
        "tog-watchlisthidecategorization": "Приховати категоризацію сторінок",
        "customcssprotected": "У вас немає дозволу на редагування цієї CSS-сторінки, бо вона містить особисті налаштування іншого користувача.",
        "customjsonprotected": "У Вас немає прав на редагування цієї JSON-сторінки, оскільки вона містить персональні налаштування іншого користувача.",
        "customjsprotected": "У вас немає дозволу на редагування цієї JavaScript-сторінки, бо вона містить особисті налаштування іншого користувача.",
+       "sitecssprotected": "У вас немає дозволу на редагування цієї CSS-сторінки, оскільки її зміни можуть вплинути на всіх відвідувачів цієї вікі.",
+       "sitejsonprotected": "У Вас немає прав на редагування цієї JSON-сторінки, оскільки її зміни можуть вплинути на всіх відвідувачів цієї вікі.",
+       "sitejsprotected": "У вас немає дозволу на редагування цієї JavaScript-сторінки, оскільки її зміни можуть вплинути на всіх відвідувачів цієї вікі.",
        "mycustomcssprotected": "У вас немає дозволу для редагування цієї CSS сторінки.",
        "mycustomjsonprotected": "У Вас немає прав на редагування цієї JSON-сторінки.",
        "mycustomjsprotected": "Ви не маєте дозволу для редагування цієї сторінки JavaScript.",
        "botpasswords-existing": "Існуючі паролі бота",
        "botpasswords-createnew": "Створити новий пароль бота",
        "botpasswords-editexisting": "Редагувати існуючий пароль бота",
+       "botpasswords-label-needsreset": "(необхідно скинути пароль)",
        "botpasswords-label-appid": "Назва бота:",
        "botpasswords-label-create": "Створити",
        "botpasswords-label-update": "Оновити",
        "botpasswords-restriction-failed": "Вхід не було здійснено через обмеження для паролю бота.",
        "botpasswords-invalid-name": "Вказане ім'я користувача не містить роздільник для пароля бота («$1»).",
        "botpasswords-not-exist": "У користувача «$1» нема пароля для бота «$2».",
+       "botpasswords-needs-reset": "Пароль бота з ім'ям «$2» {{GENDER:$1|користувача|користувачки}} «$1» необхідно скинути.",
        "resetpass_forbidden": "Пароль не можна змінити",
        "resetpass_forbidden-reason": "Пароль не можна змінити: $1",
        "resetpass-no-info": "Щоб звертатися безпосередньо до цієї сторінки, вам слід увійти до системи.",
        "resetpass-submit-loggedin": "Змінити пароль",
        "resetpass-submit-cancel": "Скасувати",
        "resetpass-wrong-oldpass": "Неправильний тимчасовий або поточний пароль.\nМожливо, Ви вже змінили пароль або зробили запит на новий тимчасовий пароль.",
-       "resetpass-recycled": "Ð\97мÑ\96нÑ\96Ñ\82Ñ\8c Ñ\81вÑ\96й Ð¿Ð°Ñ\80олÑ\8c Ð½Ð° Ñ\89оÑ\81Ñ\8c Ñ\96нÑ\88е, Ð½Ñ\96ж Ð²аш поточний пароль.",
+       "resetpass-recycled": "Ð\97мÑ\96нÑ\96Ñ\82Ñ\8c Ñ\81вÑ\96й Ð¿Ð°Ñ\80олÑ\8c Ð½Ð° Ñ\89оÑ\81Ñ\8c Ñ\96нÑ\88е, Ð½Ñ\96ж Ð\92аш поточний пароль.",
        "resetpass-temp-emailed": "Ви ввійшли, використовуючи тимчасовий пароль, який отримали електронною поштою. \nДля завершення входу в систему необхідно задати новий пароль:",
        "resetpass-temp-password": "Тимчасовий пароль:",
        "resetpass-abort-generic": "Зміну пароля було перервано розширенням.",
        "resetpass-expired": "Термін дії вашого пароля закінчився. Будь ласка, встановіть новий пароль для входу в систему.",
-       "resetpass-expired-soft": "Термін дії вашого пароля закінчився, і тепер він повинен бути змінений. Будь ласка, виберіть новий пароль або натисніть \"{{int:authprovider-resetpass-skip-label}}\", щоб змінити його пізніше.",
-       "resetpass-validity-soft": "Ваш пароль є некоректним: $1\n\nБудь ласка, виберіть новий пароль або натисніть «{{int:authprovider-resetpass-skip-label}}», щоб скинути його пізніше.",
+       "resetpass-expired-soft": "Термін дії вашого пароля закінчився, і тепер він повинен бути змінений. Будь ласка, виберіть новий пароль або натисніть «{{int:authprovider-resetpass-skip-label}}», щоб змінити його пізніше.",
+       "resetpass-validity-soft": "Ваш пароль є некоректним: $1\n\nБудь ласка, виберіть новий пароль або натисніть «{{int:authprovider-resetpass-skip-label}}», щоб змінити його пізніше.",
        "passwordreset": "Скинути пароль",
        "passwordreset-text-one": "Заповніть цю форму, щоб отримати тимчасовий пароль електронною поштою.",
        "passwordreset-text-many": "{{PLURAL:$1|Заповніть одне з полів для отримання тимчасового пароля електронною поштою.}}",
        "previewerrortext": "Сталася помилка при спробі попереднього перегляду Ваших змін.",
        "blockedtitle": "Користувача заблоковано",
        "blockedtext": "<strong>Ваш обліковий запис або IP-адреса заблоковані.</strong>\n\nБлокування виконане адміністратором $1.\nПричина блокування: <em>$2</em>.\n\n* Початок блокування: $8\n* Закінчення блокування: $6\n* Діапазон блокування: $7\n\nВи можете надіслати листа користувачеві $1 або будь-якому іншому [[{{MediaWiki:Grouppage-sysop}}|адміністратору]], щоб обговорити блокування.\n\nЗверніть увагу, що ви не зможете використати функцію \"{{int:emailuser}}\", якщо ви не зареєстровані або не підтвердили свою електронну адресу в [[Special:Preferences|особистих налаштуваннях]], а також якщо вам було заборонено надсилати листи при блокуванні.\n\nВаша поточна IP-адреса — $3, ідентифікатор блокування — #$5. Будь ласка, зазначайте ці дані у своїх запитах.",
-       "autoblockedtext": "Ð\92аÑ\88а IP-адÑ\80еÑ\81а Ð°Ð²Ñ\82омаÑ\82иÑ\87но Ð·Ð°Ð±Ð»Ð¾ÐºÐ¾Ð²Ð°Ð½Ð° Ñ\83 Ð·Ð²'Ñ\8fзкÑ\83 Ð· Ñ\82им, Ñ\89о Ð²Ð¾Ð½Ð° Ñ\80анÑ\96Ñ\88е Ð²Ð¸ÐºÐ¾Ñ\80иÑ\81Ñ\82овÑ\83валаÑ\81Ñ\8f ÐºÐ¸Ð¼Ð¾Ñ\81Ñ\8c Ñ\96з Ð·Ð°Ð±Ð»Ð¾ÐºÐ¾Ð²Ð°Ð½Ð¸Ñ\85 ÐºÐ¾Ñ\80иÑ\81Ñ\82Ñ\83ваÑ\87Ñ\96в. Ð\90дмÑ\96нÑ\96Ñ\81Ñ\82Ñ\80аÑ\82оÑ\80 ($1), Ñ\89о Ñ\97Ñ\97 Ð·Ð°Ð±Ð»Ð¾ÐºÑ\83вав, Ð·Ð°Ð·Ð½Ð°Ñ\87ив Ð½Ð°Ñ\81Ñ\82Ñ\83пнÑ\83 Ð¿Ñ\80иÑ\87инÑ\83 Ð±Ð»Ð¾ÐºÑ\83ваннÑ\8f:\n\n:''$2''\n\n* Ð\9fоÑ\87аÑ\82ок Ð±Ð»Ð¾ÐºÑ\83ваннÑ\8f: $8\n* Ð\97акÑ\96нÑ\87еннÑ\8f Ð±Ð»Ð¾ÐºÑ\83ваннÑ\8f: $6\n* Ð\91локÑ\83ваннÑ\8f Ð²Ð¸ÐºÐ¾Ð½Ð°Ð²: $7\n\nÐ\92и Ð¼Ð¾Ð¶ÐµÑ\82е Ð½Ð°Ð´Ñ\96Ñ\81лаÑ\82и Ð»Ð¸Ñ\81Ñ\82а ÐºÐ¾Ñ\80иÑ\81Ñ\82Ñ\83ваÑ\87евÑ\96 $1 Ð°Ð±Ð¾ Ð±Ñ\83дÑ\8c\8fкомÑ\83 Ñ\96нÑ\88омÑ\83 [[{{MediaWiki:Grouppage-sysop}}|адмÑ\96нÑ\96Ñ\81Ñ\82Ñ\80аÑ\82оÑ\80Ñ\83]], Ñ\89об Ð¾Ð±Ð³Ð¾Ð²Ð¾Ñ\80иÑ\82и Ð±Ð»Ð¾ÐºÑ\83ваннÑ\8f.\n\nÐ\97веÑ\80нÑ\96Ñ\82Ñ\8c Ñ\83вагÑ\83, Ñ\89о Ð²Ð¸ Ð½Ðµ Ð·Ð¼Ð¾Ð¶ÐµÑ\82е Ð½Ð°Ð´Ñ\96Ñ\81лаÑ\82и Ð»Ð¸Ñ\81Ñ\82а Ð°Ð´Ð¼Ñ\96нÑ\96Ñ\81Ñ\82Ñ\80аÑ\82оÑ\80овÑ\96, Ñ\8fкÑ\89о Ð²Ð¸ Ð½Ðµ Ð·Ð°Ñ\80еÑ\94Ñ\81Ñ\82Ñ\80ованÑ\96 Ñ\83 Ð¿Ñ\80оекÑ\82Ñ\96 Ð°Ð±Ð¾ Ð½Ðµ Ð¿Ñ\96дÑ\82веÑ\80дили Ñ\81воÑ\8e ÐµÐ»ÐµÐºÑ\82Ñ\80оннÑ\83 Ð°Ð´Ñ\80еÑ\81Ñ\83 Ð² [[Special:Preferences|оÑ\81обиÑ\81Ñ\82иÑ\85 Ð½Ð°Ð»Ð°Ñ\88Ñ\82Ñ\83ваннÑ\8fÑ\85]], Ð° Ñ\82акож Ñ\8fкÑ\89о Ð²Ð°Ð¼ Ð±Ñ\83ло Ð·Ð°Ð±Ð¾Ñ\80онено Ð½Ð°Ð´Ñ\81илаÑ\82и Ð»Ð¸Ñ\81Ñ\82и Ð¿Ñ\80и Ð±Ð»Ð¾ÐºÑ\83ваннÑ\96.\n\nÐ\92аÑ\88а Ð¿Ð¾Ñ\82оÑ\87на IP-адÑ\80еÑ\81а â\80\94 $3, Ñ\96денÑ\82иÑ\84Ñ\96каÑ\82оÑ\80 Ð±Ð»Ð¾ÐºÑ\83ваннÑ\8f â\80\94 #$5. Ð\91Ñ\83дÑ\8c Ð»Ð°Ñ\81ка, Ð·Ð°Ð·Ð½Ð°Ñ\87айÑ\82е Ð¹Ð¾Ð³Ð¾ у своїх запитах.",
+       "autoblockedtext": "Ð\92аÑ\88а IP-адÑ\80еÑ\81а Ð°Ð²Ñ\82омаÑ\82иÑ\87но Ð·Ð°Ð±Ð»Ð¾ÐºÐ¾Ð²Ð°Ð½Ð° Ñ\83 Ð·Ð²'Ñ\8fзкÑ\83 Ð· Ñ\82им, Ñ\89о Ð²Ð¾Ð½Ð° Ñ\80анÑ\96Ñ\88е Ð²Ð¸ÐºÐ¾Ñ\80иÑ\81Ñ\82овÑ\83валаÑ\81Ñ\8f ÐºÐ¸Ð¼Ð¾Ñ\81Ñ\8c Ñ\96з ÐºÐ¾Ñ\80иÑ\81Ñ\82Ñ\83ваÑ\87Ñ\96в, Ñ\8fкого Ð·Ð°Ð±Ð»Ð¾ÐºÑ\83вав $1.\nÐ\9fÑ\80иÑ\87ина Ð±Ð»Ð¾ÐºÑ\83ваннÑ\8f Ð±Ð»Ð¾ÐºÑ\83ваннÑ\8f:\n\n:<em>$2</em>\n\n* Ð\9fоÑ\87аÑ\82ок Ð±Ð»Ð¾ÐºÑ\83ваннÑ\8f: $8\n* Ð\97акÑ\96нÑ\87еннÑ\8f Ð±Ð»Ð¾ÐºÑ\83ваннÑ\8f: $6\n* Ð\91локÑ\83ваннÑ\8f Ð²Ð¸ÐºÐ¾Ð½Ð°Ð²: $7\n\nÐ\92и Ð¼Ð¾Ð¶ÐµÑ\82е Ð½Ð°Ð´Ñ\96Ñ\81лаÑ\82и Ð»Ð¸Ñ\81Ñ\82а ÐºÐ¾Ñ\80иÑ\81Ñ\82Ñ\83ваÑ\87евÑ\96 $1 Ð°Ð±Ð¾ Ð±Ñ\83дÑ\8c\8fкомÑ\83 Ñ\96нÑ\88омÑ\83 [[{{MediaWiki:Grouppage-sysop}}|адмÑ\96нÑ\96Ñ\81Ñ\82Ñ\80аÑ\82оÑ\80Ñ\83]], Ñ\89об Ð¾Ð±Ð³Ð¾Ð²Ð¾Ñ\80иÑ\82и Ð±Ð»Ð¾ÐºÑ\83ваннÑ\8f.\n\nÐ\97веÑ\80нÑ\96Ñ\82Ñ\8c Ñ\83вагÑ\83, Ñ\89о Ð²Ð¸ Ð½Ðµ Ð·Ð¼Ð¾Ð¶ÐµÑ\82е Ñ\81коÑ\80иÑ\81Ñ\82аÑ\82иÑ\81Ñ\8f Ñ\84Ñ\83нкÑ\86Ñ\96Ñ\94Ñ\8e \"{{int:emailuser}}\", Ñ\82ак Ñ\8fк Ð½Ðµ Ð¼Ð°Ñ\94Ñ\82е Ð´Ñ\96йÑ\81ноÑ\97 ÐµÐ»ÐµÐºÑ\82Ñ\80онноÑ\97 Ð¿Ð¾Ñ\88Ñ\82и, Ð·Ð°Ñ\80еÑ\94Ñ\81Ñ\82Ñ\80ованоÑ\97 Ð² [[Special:Preferences|оÑ\81обиÑ\81Ñ\82иÑ\85 Ð½Ð°Ð»Ð°Ñ\88Ñ\82Ñ\83ваннÑ\8fÑ\85]], Ð° Ñ\82акож Ñ\8fкÑ\89о Ð²Ð°Ð¼ Ð±Ñ\83ло Ð·Ð°Ð±Ð¾Ñ\80онено Ð½Ð°Ð´Ñ\81илаÑ\82и Ð»Ð¸Ñ\81Ñ\82и Ð¿Ñ\80и Ð±Ð»Ð¾ÐºÑ\83ваннÑ\96.\n\nÐ\92аÑ\88а Ð¿Ð¾Ñ\82оÑ\87на IP-адÑ\80еÑ\81а â\80\94 $3, Ñ\96денÑ\82иÑ\84Ñ\96каÑ\82оÑ\80 Ð±Ð»Ð¾ÐºÑ\83ваннÑ\8f â\80\94 #$5. Ð\91Ñ\83дÑ\8c Ð»Ð°Ñ\81ка, Ð·Ð°Ð·Ð½Ð°Ñ\87айÑ\82е Ñ\86Ñ\96 Ð´Ð°Ð½Ñ\96 у своїх запитах.",
        "systemblockedtext": "Ваше ім'я користувача або IP-адресу було автоматично заблоковано MediaWiki.\nВказана причина:\n\n:<em>$2</em>\n\n* Початок блокування: $8\n* Закінчення блокування: $6\n* Ціль блокування: $7\n\nВаша поточна IP-адреса — $3.\nБудь ласка, додайте всі вказані подробиці до будь-яких запитів, які Ви будете робити.",
        "blockednoreason": "не вказано причини",
        "whitelistedittext": "Ви повинні $1, щоб редагувати сторінки.",
        "longpageerror": "'''Помилка: Поданий вами текст становить $1 {{PLURAL:$1|кілобайт|кілобайти|кілобайтів}}, що більше за встановлену межу у {{PLURAL:$2|кілобайт|кілобайти|кілобайтів}}.'''\nЙого неможливо зберегти.",
        "readonlywarning": "<strong>Попередження: База даних заблокована на обслуговування, тому, на даний момент, ви не можете записати ваші зміни.\n</strong>\nМожливо, вам варто скопіювати текст у файл на вашому комп'ютері й зберегти його на пізніше.\n\nАдміністратор, що заблокував базу даних, залишив наступне пояснення: $1",
        "protectedpagewarning": "'''Попередження: Ця сторінка була захищена від змін так, що тільки користувачі з правами адміністратора можуть її редагувати.'''\nОстанній запис журналу наведений нижче для довідки:",
-       "semiprotectedpagewarning": "'''Зауваження:''' Ця сторінка захищена так, що її можуть редагувати тільки зареєстровані користувачі.\nОстанній запис журналу наведений нижче для довідки:",
+       "semiprotectedpagewarning": "<strong>Зауваження:</strong> Ця сторінка захищена так, що її можуть редагувати тільки зареєстровані користувачі.\nОстанній запис журналу наведений нижче для довідки:",
        "cascadeprotectedwarning": "<strong>Попередження:</strong> Цю сторінку можуть редагувати лише користувачі зі [[Special:ListGroupRights|специфічними правами]], оскільки вона включена на {{PLURAL:$1|1=сторінці|сторінках}}, де встановлено каскадний захист:",
        "titleprotectedwarning": "'''Попередження. Ця сторінка була захищена так, що для її створення потрібні [[Special:ListGroupRights|особливі права]].'''\nОстанній запис журналу наведений нижче для довідки:",
        "templatesused": "{{PLURAL:$1|1=Шаблон, використаний|Шаблони, використані}} на цій сторінці:",
        "converter-manual-rule-error": "Помилка в ручному правилі перетворення мови",
        "undo-success": "Редагування може бути скасовано.\nБудь ласка, перевірте порівняння нижче, щоб впевнитись, що це те, що ви хочете зробити, а потім збережіть зміни, щоб закінчити скасування редагування.",
        "undo-failure": "Неможливо скасувати редагування через несумісність проміжних змін.",
+       "undo-main-slot-only": "Редагування не може бути скасоване, бо воно включає вміст з-за меж основного слоту.",
        "undo-norev": "Редагування не може бути скасоване, бо його не існує або було вилучено.",
        "undo-nochange": "Схоже, редагування вже було скасовано.",
        "undo-summary": "Скасування редагування № $1 користувача [[Special:Contribs/$2|$2]] ([[User talk:$2|обговорення]])",
        "diff-paragraph-moved-toold": "Абзац було переміщено. Натисніть щоб перестрибнути до старого розташування.",
        "difference-missing-revision": "{{PLURAL:$2|$2 версія|$2 версії|$2 версій}} для цього порівняння ($1) не {{PLURAL:$2|1=знайдена|знайдені}}.\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": "Збіги в текстах сторінок",
        "prefs-watchlist-edits": "Максимальна кількість змін, яку можна виводити у списку спостереження:",
        "prefs-watchlist-edits-max": "Максимально: 1000",
        "prefs-watchlist-token": "Токен списку спостереження:",
+       "prefs-watchlist-managetokens": "Управління токенами",
        "prefs-misc": "Інші налаштування",
        "prefs-resetpass": "Змінити пароль",
        "prefs-changeemail": "Змінити або вилучити адресу електронної пошти",
        "recentchangescount": "Кількість редагувань для показу за замовчуванням на сторінках нових редагувань, історій сторінок та в журналах:",
        "prefs-help-recentchangescount": "Максимальна кількість: 1000",
        "prefs-help-watchlist-token2": "Це секретний ключ до веб-каналу вашого списку спостереження.\nБудь-хто, хто його знає, матиме можливість читати ваш список спостереження, тому не поширюйте його.\nЯкщо вам потрібно, [[Special:ResetTokens|ви можете скинути його]].",
+       "prefs-help-tokenmanagement": "Ви можете переглянути і скинути секретний ключ свого облікового запису, який дає доступ до веб-каналу вашого списку спостереження. Кожен, хто його знає, матиме можливість читати ваш список спостереження, тому не поширюйте його.",
        "savedprefs": "Ваші налаштування збережено.",
        "savedrights": "Групи {{GENDER:$1|користувача $1|користувачки $1}} було збережено.",
        "timezonelegend": "Часовий пояс:",
        "prefs-dateformat": "Формат дати",
        "prefs-timeoffset": "Зсув часу",
        "prefs-advancedediting": "Загальні параметри",
+       "prefs-developertools": "Інструменти розробника",
        "prefs-editor": "Редактор",
        "prefs-preview": "Попередній перегляд",
        "prefs-advancedrc": "Розширені налаштування",
        "group-autoconfirmed": "Автопідтверджені користувачі",
        "group-bot": "Боти",
        "group-sysop": "Адміністратори",
+       "group-interface-admin": "Адміністратори інтерфейсу",
        "group-bureaucrat": "Бюрократи",
        "group-suppress": "Подавлювачі",
        "group-all": "(всі)",
        "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-createpage": "створення сторінок (які не є обговореннями)",
        "right-createtalk": "створення обговорень сторінок",
        "right-createaccount": "створення нових облікових записів",
        "right-autocreateaccount": "Автоматичний вхід в систему із зовнішнього облікового запису користувача",
        "right-browsearchive": "пошук вилучених сторінок",
        "right-undelete": "відновлення сторінок",
        "right-suppressrevision": "перегляд, приховування та відновлення конкретних змін сторінок від будь-якого користувача",
-       "right-viewsuppressed": "Ð\9fеÑ\80еглÑ\8fд Ð·Ð¼Ñ\96н, Ð¿Ñ\80иÑ\85оваих від усіх користувачів",
+       "right-viewsuppressed": "пеÑ\80еглÑ\8fд Ð·Ð¼Ñ\96н, Ð¿Ñ\80иÑ\85ованих від усіх користувачів",
        "right-suppressionlog": "перегляд приватних журналів",
        "right-block": "заборона редагувань для інших дописувачів",
        "right-blockemail": "блокування користувача від надсилання електронної пошти",
        "right-protect": "зміна рівнів захисту та редагування каскадно захищених сторінок",
        "right-editprotected": "редагування сторінок з рівнем захисту «{{int:protect-level-sysop}}»",
        "right-editsemiprotected": "редагування сторінок з рівнем захисту «{{int:protect-level-autoconfirmed}}»",
-       "right-editcontentmodel": "Редагувати модель вмісту сторінки",
+       "right-editcontentmodel": "редагування моделі вмісту сторінки",
        "right-editinterface": "редагування інтерфейсу користувача",
        "right-editusercss": "редагування CSS-файлів інших користувачів",
        "right-edituserjson": "редагування JSON-файлів інших користувачів",
        "right-edituserjs": "редагування JS-файлів інших користувачів",
+       "right-editsitecss": "Редагувати загальний CSS",
+       "right-editsitejson": "Редагувати загальний JSON",
+       "right-editsitejs": "Редагувати загальний JavaScript",
        "right-editmyusercss": "редагування власних CSS-файлів користувача",
        "right-editmyuserjson": "редагування власних JSON-файлів користувача",
        "right-editmyuserjs": "редагування власних JavaScript-файлів користувача",
        "right-markbotedits": "позначення відкинутих редагувань як редагування бота",
        "right-noratelimit": "нема обмежень за швидкістю",
        "right-import": "імпорт сторінок з інших вікі",
-       "right-importupload": "Імпорт сторінок через завантаження файлів",
+       "right-importupload": "імпорт сторінок через завантаження файлів",
        "right-patrol": "позначення редагувань патрульованими",
        "right-autopatrol": "автоматичне позначення редагувань патрульованими",
        "right-patrolmarks": "Перегляд патрульованих сторінок у нових редагуваннях",
        "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": "Редагувати Ваш список спостереження",
+       "grant-editsiteconfig": "Редагувати загальний та користувацький CSS/JS",
        "grant-editpage": "Редагувати наявні сторінки",
        "grant-editprotected": "Редагувати захищені сторінки",
        "grant-highvolume": "Редагування у великих обсягах",
        "action-viewmywatchlist": "перегляд власного списку спостереження",
        "action-viewmyprivateinfo": "перегляд своєї приватної інформації",
        "action-editmyprivateinfo": "редагування своєї приватної інформації",
-       "action-editcontentmodel": "редагувати модель вмісту сторінки",
+       "action-editcontentmodel": "редагування моделі вмісту сторінки",
        "action-managechangetags": "створення та (де)активування міток",
        "action-applychangetags": "додавання міток разом зі змінами",
        "action-changetags": "додавання або вилучення будь-яких міток для певних версій сторінок або записів журналів",
        "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-empty-filter": "Без фільтрів. Показано всі зміни.",
        "rcfilters-filterlist-title": "Фільтри",
        "rcfilters-filterlist-whatsthis": "Як це працює?",
-       "rcfilters-filterlist-feedbacklink": "Розкажіть нам, що Ви думаєте про ці (нові) інструменти фільтрування",
+       "rcfilters-filterlist-feedbacklink": "Розкажіть нам, що Ви думаєте про ці інструменти фільтрування",
        "rcfilters-highlightbutton-title": "Виділити результати",
        "rcfilters-highlightmenu-title": "Вибрати колір",
        "rcfilters-highlightmenu-help": "Вибрати колір, щоб виділити цю властивість",
        "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-watchlist-showupdated": "Зміни до сторінок, які Ви не відвідували з моменту здійснення змін, виділені <strong>жирним</strong>, із цілісними маркерами.",
        "rcfilters-preference-label": "Приховати покращену версію Нових редагувань",
        "rcfilters-preference-help": "Скасовує зміну дизайну 2017 року та всі інструменти, додані тоді й пізніше.",
+       "rcfilters-watchlist-preference-label": "Приховати покращену версію Списку спостереження",
+       "rcfilters-watchlist-preference-help": "Відкидає зміну дизайну інтерфейсу 2017 року та всі інструменти додані тоді й пізніше.",
        "rcfilters-filter-showlinkedfrom-label": "Показати зміни на сторінках, на які є посилання з",
        "rcfilters-filter-showlinkedfrom-option-label": "<strong>Сторінки, на які є посилання з</strong> обраної сторінки",
        "rcfilters-filter-showlinkedto-label": "Показати зміни на сторінках, що посилаються сюди",
        "http-timed-out": "Перевищення часу очікування HTTP-запиту.",
        "http-curl-error": "Помилка звертання до URL: $1",
        "http-bad-status": "Під час HTTP-запиту виникла проблема: $1 $2",
+       "http-internal-error": "Внутрішня помилка HTTP.",
        "upload-curl-error6": "Неможливо досягнути вказану адресу.",
        "upload-curl-error6-text": "Неможливо досягнути вказану адресу. Будь-ласка, перевірте, що вказана адреса вірна, а сайт доступний.",
        "upload-curl-error28": "Час виділений на завантаження вичерпано",
        "deadendpages": "Сторінки без посилань",
        "deadendpagestext": "Наступні сторінки не містять посилань на інші сторінки цієї вікі.",
        "protectedpages": "Захищені сторінки",
+       "protectedpages-filters": "Фільтри:",
        "protectedpages-indef": "Тільки безстроково захищені",
        "protectedpages-summary": "На цій сторінці перераховані сторінки, які на цей момент захищені. Список назв, які захищені від створення див.  [[{{#special:ProtectedTitles}}|{{int:protectedtitles}}]].",
        "protectedpages-cascade": "Тільки каскадний захист",
        "protectedtitles-submit": "Показувати заголовки",
        "listusers": "Список користувачів",
        "listusers-editsonly": "Показати лише користувачів, які зробили принаймні одне редагування",
+       "listusers-temporarygroupsonly": "Показувати лише користувачів із тимчасових груп",
        "listusers-creationsort": "Сортувати за датою створення",
        "listusers-desc": "Сортувати за спадним порядком",
        "usereditcount": "$1 {{PLURAL:$1|редагування|редагування|редагувань}}",
        "apisandbox-dynamic-parameters-add-label": "Додати параметр:",
        "apisandbox-dynamic-parameters-add-placeholder": "Назва параметра",
        "apisandbox-dynamic-error-exists": "Параметр з назвою «$1» вже існує.",
+       "apisandbox-templated-parameter-reason": "Цей [[Special:ApiHelp/main#main/templatedparams|шаблонний параметр]] запропонований на основі  {{PLURAL:$1|значення|значень}} з $2.",
        "apisandbox-deprecated-parameters": "Застарілі параметри",
        "apisandbox-fetch-token": "Автозаповнення токена",
+       "apisandbox-add-multi": "Додати",
        "apisandbox-submit-invalid-fields-title": "Деякі поля недійсні",
        "apisandbox-submit-invalid-fields-message": "Будь ласка, виправте відмічені поля і спробуйте знову.",
        "apisandbox-results": "Результати",
        "speciallogtitlelabel": "Ціль (назва сторінки або {{ns:user}}:Ім'я_користувача):",
        "log": "Журнали",
        "logeventslist-submit": "Показати",
+       "logeventslist-more-filters": "Показати додаткові журнали:",
+       "logeventslist-patrol-log": "Журнал патрулювання",
+       "logeventslist-tag-log": "Журнал міток",
        "all-logs-page": "Усі публічні журнали",
        "alllogstext": "Комбінований показ журналів {{grammar:genitive|{{SITENAME}}}}.\nВи можете відфільтрувати результати за типом журналу, іменем користувача (враховується регістр) або зазначеною сторінкою (також враховується регістр).",
        "logempty": "У журналі немає подібних записів.",
        "dellogpage": "Журнал вилучень",
        "dellogpagetext": "Нижче наведений список останніх вилучень.",
        "deletionlog": "журнал вилучень",
+       "log-name-create": "Журнал створення сторінок",
+       "log-description-create": "Нижче наведений список останніх створень сторінок.",
+       "logentry-create-create": "$1 {{GENDER:$2|створив|створила}} сторінку $3",
        "reverted": "Повернуто до більш ранньої версії",
        "deletecomment": "Причина:",
        "deleteotherreason": "Інша/додаткова причина:",
        "anoncontribs": "Внесок",
        "contribsub2": "Для {{GENDER:$3|$1}} ($2)",
        "contributions-userdoesnotexist": "Обліковий запис користувача  «$1» не зареєстровано.",
-       "nocontribs": "РедагÑ\83ванÑ\8c, Ñ\89о Ð·Ð°Ð´Ð¾Ð²Ð¾Ð»Ñ\8cнÑ\8fÑ\8eÑ\82Ñ\8c Ð·Ð°Ð´Ð°Ð½Ð¸Ð¼ Ñ\83мовам не знайдено.",
+       "nocontribs": "РедагÑ\83ванÑ\8c, Ñ\89о Ð²Ñ\96дповÑ\96даÑ\8eÑ\82Ñ\8c Ð·Ð°Ð´Ð°Ð½Ð¸Ð¼ Ñ\83мовам, не знайдено.",
        "uctop": "(поточна)",
        "month": "До місяця (включно):",
        "year": "До року (включно):",
+       "date": "З дати (і раніше):",
        "sp-contributions-newbies": "Показати лише внесок з нових облікових записів",
        "sp-contributions-newbies-sub": "Внесок новачків",
        "sp-contributions-newbies-title": "Внесок з нових облікових записів",
        "whatlinkshere": "Посилання сюди",
        "whatlinkshere-title": "Сторінки, що посилаються на «$1»",
        "whatlinkshere-page": "Сторінка:",
-       "linkshere-2": "Такі сторінки посилаються на '''$1''':",
-       "nolinkshere-2": "На статтю '''$1''' не вказує жодна стаття.",
-       "nolinkshere-ns-2": "У вибраному просторі назв нема сторінок, що посилаються на '''$1'''.",
+       "linkshere": "Такі сторінки посилаються на '''$1''':",
+       "nolinkshere": "На статтю '''$1''' не вказує жодна стаття.",
+       "nolinkshere-ns": "У вибраному просторі назв нема сторінок, що посилаються на '''$2'''.",
        "isredirect": "сторінка-перенаправлення",
        "istemplate": "включення",
        "isimage": "посилання на файл",
        "fix-double-redirects": "Виправити всі перенаправлення на попередню назву",
        "move-leave-redirect": "Залишити перенаправлення",
        "protectedpagemovewarning": "'''Попередження:''' Ця сторінка захищена так, що її можуть перейменовувати тільки адміністратори.\nОстанній запис журналу наведений нижче для довідки:",
-       "semiprotectedpagemovewarning": "'''Зауваження:''' Ця сторінка захищена так, що перейменовувати її можуть тільки зареєстровані користувачі.\nОстанній запис журналу наведений нижче для довідки:",
+       "semiprotectedpagemovewarning": "<strong>Зауваження:</strong> Ця сторінка захищена так, що перемістити її можуть тільки автопідтверджені користувачі.\nОстанній запис журналу наведений нижче для довідки:",
        "move-over-sharedrepo": "У спільному сховищі існує [[:$1]]. Перейменування файлу на цю назву призведе до перекриття файлу зі спільного сховища.",
        "file-exists-sharedrepo": "Обрана назва файлу вже використовується у спільному сховищі.\nБудь ласка, оберіть іншу назву.",
        "export": "Експорт статей",
        "markedaspatrollederrornotify": "Не вдалося поставити позначку про патрулювання.",
        "patrol-log-page": "Журнал патрулювання",
        "patrol-log-header": "Це журнал перевірених змін.",
-       "log-show-hide-patrol": "$1 журнал патрулювання",
-       "log-show-hide-tag": "$1 мітку журналу",
        "confirm-markpatrolled-button": "OK",
        "confirm-markpatrolled-top": "Позначити версію $3 сторінки $2 як відпатрульовану?",
        "deletedrevision": "Вилучена стара версія $1",
        "semicolon-separator": ";&#32;",
        "comma-separator": ",&#32;",
        "colon-separator": ":&#32;",
-       "pipe-separator": "&#32;&#32;",
+       "pipe-separator": "&#32;|&#32;",
        "word-separator": "&#32;",
        "ellipsis": "...",
        "percent": "$1%",
        "version-specialpages": "Спеціальні сторінки",
        "version-parserhooks": "Перехоплювачі синтаксичного аналізатора",
        "version-variables": "Змінні",
+       "version-editors": "Редактори",
        "version-antispam": "Захист від спаму",
        "version-api": "API",
        "version-other": "Інше",
        "pagedata-title": "Дані сторінки",
        "pagedata-text": "Ця сторінка надає сторінкам інтерфейс даних. Будь ласка, вкажіть назву сторінки в URL-адресі, скориставшись синтаксисом підсторінок.\n* Переговори щодо контенту застосовуються на основі прийнятних форматів Вашого клієнта. Це означає, що дані сторінки будуть надані в тому форматі, якому віддає перевагу Ваш клієнт.",
        "pagedata-not-acceptable": "Не знайдено підхожого формату. Підтримувані MIME-типи: $1",
-       "pagedata-bad-title": "Недійсна назва: $1."
+       "pagedata-bad-title": "Недійсна назва: $1.",
+       "unregistered-user-config": "З міркувань безпеки користувальницькі підсторінки JavaScript, CSS та JSON не можуть бути завантажені для незареєстрованих учасників.",
+       "passwordpolicies": "Політика щодо паролів",
+       "passwordpolicies-summary": "Це список ефективних правил щодо паролів для груп користувачів, визначених у цій вікі.",
+       "passwordpolicies-group": "Група",
+       "passwordpolicies-policies": "Політика",
+       "passwordpolicies-policy-minimalpasswordlength": "Пароль має містити принаймні $1 {{PLURAL:$1|символ|символи|символів}}",
+       "passwordpolicies-policy-minimumpasswordlengthtologin": "Пароль має містити принаймні $1 {{PLURAL:$1|символ|символи|символів}} щоб мати можливість увійти до свого облікового запису",
+       "passwordpolicies-policy-passwordcannotmatchusername": "Пароль не може збігатися з назвою облікового запису",
+       "passwordpolicies-policy-passwordcannotmatchblacklist": "Пароль не може збігатися з паролями із чорного списку",
+       "passwordpolicies-policy-maximalpasswordlength": "Пароль повинен бути коротшим $1 {{PLURAL:$1|символа|символів}}",
+       "passwordpolicies-policy-passwordcannotbepopular": "Пароль не може бути {{PLURAL:$1|часто вживаним|будь-яким з $1 часто вживаних паролів}}",
+       "easydeflate-invaliddeflate": "Наданий вміст не стиснений належним чином"
 }
index fa0f81b..4971f0e 100644 (file)
@@ -37,7 +37,9 @@
                        "Zainab Meher",
                        "Sayam Asjad",
                        "Abdulq",
-                       "Fitoschido"
+                       "Fitoschido",
+                       "Dcljr",
+                       "Bukhari"
                ]
        },
        "tog-underline": "ربط کی خط کشیدگی:",
        "listingcontinuesabbrev": "جاری۔",
        "index-category": "فہرست شدہ صفحات",
        "noindex-category": "غیر فہرست شدہ صفحات",
-       "broken-file-category": "فائل کے شکستہ روابط کے حامل صفحات",
+       "broken-file-category": "فائلوں کے شکستہ روابط پر مشتمل صفحات",
        "categoryviewer-pagedlinks": "($1) ($2)",
        "about": "تعارف",
        "article": "صفحہ مواد",
        "jumptonavigation": "رہنمائی",
        "jumptosearch": "تلاش کریں",
        "view-pool-error": "معذرت کے ساتھ، تمام معیلات پر اِس وقت اِضافی بوجھ ہے.\nبہت زیادہ صارفین اِس وقت یہ صفحہ ملاحظہ کرنے کی کوشش کررہے ہیں.\nبرائے مہربانی! صفحہ دیکھنے کیلئے دوبارہ کوشش کرنے سے پہلے ذرا انتظار فرمالیجئے.\n\n$1",
-       "generic-pool-error": "ہم معذرت خواہ ہیں! معیلات (سرورز) پر اِس وقت اِضافی بوجھ ہے.\nصارفین کی کثیر تعداد اِس وقت یہی صفحہ ملاحظہ کرنے کی کوشش کررہی ہے.\nبرائے مہربانی!دوبارہ کوشش کرنے سے پہلے ذرا انتظار فرمائیے.",
+       "generic-pool-error": "ہم معذرت خواہ ہیں، سرور پر اِس وقت اِضافی بوجھ ہے۔\nصارفین کی کثیر تعداد اِس وقت یہی صفحہ ملاحظہ کرنے کی کوشش کر رہی ہے۔\nبرائے مہربانی دوبارہ کوشش کرنے سے پہلے ذرا انتظار فرمائیے۔",
        "pool-timeout": "مقفل کرنے کے لیے انتظار کی مہلت ختم",
        "pool-queuefull": "قطار لگی ہوئی ہے",
        "pool-errorunknown": "نامعلوم خطا",
        "perfcachedts": "ذیل میں درج معلومات کیش (cache) شدہ ہے اور آخری بار اس کی تجدید $1 کو کی گئی تھی۔ کیش (cache) میں زیادہ سے زیادہ {{PLURAL:$4|ایک نتیجہ دستیاب ہے|$4 دستیاب ہیں}}۔",
        "querypage-no-updates": "اِس صفحہ کیلئے بتاریخات فی الحال ناقابل بنائی گئی ہیں.\nیہاں کا ڈیٹا ابھی تازہ نہیں کیا جائے گا.",
        "viewsource": "ماخذ دیکھیں",
-       "viewsource-title": "$1 کا مسودہ دیکھیں",
+       "viewsource-title": "$1 کا مسودہ",
        "actionthrottled": "Action throttled",
        "actionthrottledtext": "ایک ضد سپم معیار کے طور پر آپ کے لیے مختصر وقت میں متعدد دفعہ یہ اقدام کرنے کے لیے حد متعین کی گئی ہے، اور آپ یہ حد پار کرچکے ہیں.\nبراہِ کرم، کچھ منٹس بعد دوبارہ کوشش کریں۔",
        "protectedpagetext": "اس صفحہ کو تدوین سے محفوظ رکھنے کیلیے مقفل کر دیا گیا ہے۔",
        "viewsourcetext": "آپ صرف مسودہ دیکھ سکتے ہیں اور اسکی نقل اتار سکتے ہیں۔",
        "viewyourtext": "آپ اس مواد کو دیکھ سکتے ہیں اور اٹھا (کاپی) سکتے ہیں <strong>آپ کی ترامیم</strong> اس صفحہ پر۔",
-       "protectedinterface": "یہ صفحہ سافٹ ویئر کا انٹرفیس متن فراہم کرتا ہے اور غلط استعمال سے بچنے کے لیے اسے محفوظ رکھا گیا ہے۔\nتمام ویکیوں میں ترجمہ شامل کرنے یا اس میں تبدیلی کرنے کے لیے میڈیاویکی دار الترجمہ [https://translatewiki.net/ translatewiki.net]کو استعمال کریں۔",
+       "protectedinterface": "یہ صفحہ سافٹ ویئر کا انٹرفیس متن فراہم کرتا ہے اور غلط استعمال سے بچنے کے لیے اسے محفوظ رکھا گیا ہے۔\nتمام ویکیوں میں ترجمہ شامل کرنے یا اس میں تبدیلی کرنے کے لیے میڈیاویکی دار الترجمہ [https://translatewiki.net/ translatewiki.net] کو استعمال کریں۔",
        "editinginterface": "<strong>انتباہ:</strong> آپ ایک ایسے صفحے میں ترمیم کر رہے ہیں جو سافٹ ویئر کا انٹرفیس متن فراہم کرتا ہے۔ اس صفحہ میں کی جانے والی ترمیم، دیگر صارفین کے انٹرفیس کو تبدیل کردے گی۔",
        "translateinterface": "تمام ویکیوں میں تراجم کو تبدیل یا شامل کرنے کے لیے  میڈیاویکی کے دار الترجمہ [https://translatewiki.net/ translatewiki.net] کو استعمال کریں۔",
        "cascadeprotected": "درج ذیل محفوظ کردہ {{PLURAL:$1|صفحہ|صفحات}} کی «آبشاری» حفاظت میں شامل ہونے کی وجہ سے یہ صفحہ بھی محفوظ ہے:\n$2",
        "customjsonprotected": "آپ کو اس JSON میں ترمیم کرنے کی اجازت نہیں کیونکہ اس میں کسی دوسرے صارف کی ذاتی ترتیبات موجود ہیں۔",
        "customjsprotected": "آپ کو اس جاوا اسکرپٹ میں ترمیم کرنے کی اجازت نہیں کیونکہ اس میں کسی دوسرے صارف کی ذاتی ترتیبات موجود ہیں۔",
        "mycustomcssprotected": "آپ اس سی ایس ایس (CSS) صفحہ میں ترمیم کرنے کا اختیار نہیں رکھتے۔",
+       "mycustomjsonprotected": "آپ اس صفحہ (جے ایس او این) میں تدوین کرنے کے مجاز نہیں ہیں",
        "mycustomjsprotected": "آپ اس جاوا اسکپرٹ (JavaScript) صفحہ میں ترمیم کرنے کا اختیار نہیں رکھتے۔",
        "myprivateinfoprotected": "آپ ان ذاتی معلوات (private information) میں ترمیم کرنے کا اختیار نہیں رکھتے۔",
        "mypreferencesprotected": "آپ اپنی ان ترجیحات (preferences) میں ترمیم کرنے کا اختیار نہیں رکھتے۔",
        "cannotcreateaccount-title": "کھاتے نہیں بنائے جا سکتے",
        "cannotcreateaccount-text": "اس ویکی پر براہ راست کھاتہ سازی فعال نہیں ہے۔",
        "yourdomainname": "آپکا ڈومین",
-       "password-change-forbidden": "آپ Ø§Ø³ Ù\88Û\8cÚ©Û\8c Ù¾Ø± Ù¾Ø§Ø±Ù\84Ù\81ظ (پاس Ø±Ù\88Ú\88) ØªØ¨Ø¯Û\8cÙ\84 Ù\86Û\81Û\8cÚº Ú©Ø± Ø³Ú©ØªÛ\92",
+       "password-change-forbidden": "آپ Ø§Ø³ Ù\88Û\8cÚ©Û\8c Ù¾Ø± Ù¾Ø§Ø³ Ø±Ù\88Ú\88 ØªØ¨Ø¯Û\8cÙ\84 Ù\86Û\81Û\8cÚº Ú©Ø± Ø³Ú©ØªÛ\92Û\94",
        "externaldberror": "یا تو توثیقی ڈیٹابیس میں خطا واقع ہوئی اور یا آپ کو بیرونی کھاتہ بتاریخ کرنے کی اِجازت نہیں ہے.",
        "login": "داخل ہوں",
        "login-security": "اپنی شناخت کی تصدیق کریں",
        "createacct-benefit-body3": "حالیہ {{PLURAL:$1|مشارکت کنندہ|مشارکت کنندگان}}",
        "badretype": "درج شدہ کلمۂ شناخت اصل سے مطابقت نہیں رکھتا۔",
        "usernameinprogress": "انتظار فرمائیے!<br />\nاس صارف نام سے کھاتہ بننے کا عمل ابھی جاری ہے۔",
-       "userexists": "داخÙ\84 Ú©Ø±Ø¯Û\81 Ø§Ø³Ù\85 ØµØ§Ø±Ù\81 Ù¾Û\81Ù\84Û\92 Ø³Û\92 Ù\85ستعÙ\85Ù\84 Û\81Û\92Û\94\nبراÛ\81Ù\90 Ú©Ø±Ù\85! Ú©Ù\88ئÛ\8c Ø¯Ù\88سرا Ø§Ø³Ù\85 Ù\85Ù\86تخب Ú©Û\8cجئے۔",
+       "userexists": "داخÙ\84 Ú©Ø±Ø¯Û\81 ØµØ§Ø±Ù\81 Ù\86اÙ\85 Ù¾Û\81Ù\84Û\92 Ø³Û\92 Ù\85ستعÙ\85Ù\84 Û\81Û\92Û\94\nبراÛ\81Ù\90 Ù\85Û\81رابÙ\86Û\8c Ú©Ù\88ئÛ\8c Ø¯Ù\88سرا Ù\86اÙ\85 Ù\85Ù\86تخب Ú©Û\8cجÛ\8cے۔",
        "loginerror": "داخلے میں غلطی",
        "createacct-error": "تخلیق کھاتہ میں نقص",
        "createaccounterror": "کھاتہ $1 بنایا نہیں جاسکا",
-       "nocookiesnew": "کھاتۂ صارف بنادیا گیا ہے، لیکن آپ کا داخلہ نہیں ہوا.\nصارفین کے داخلہ کیلئے {{SITENAME}} کوکیز استعمال کرتا ہے.\nآپ کے ہاں کوکیز غیر فعال ہیں.\nبراہِ کرم، انہیں فعال کیجئے، اور پھر اپنے نئے اسمِ صارف اور کلمۂ شناخت کے ساتھ داخل ہوجائیے.",
+       "nocookiesnew": "کھاتۂ صارف بنادیا گیا ہے، لیکن آپ کا داخلہ نہیں ہوا۔\nصارفین کے داخلہ کے لیے {{SITENAME}} کوکیز استعمال کرتا ہے۔\nآپ کے ہاں کوکیز غیر فعال ہیں۔\nبراہِ مہربانی، انہیں فعال کریں، اور پھر اپنے نئے صارف نام اور کلمۂ شناخت (پاسورڈ) کے ساتھ داخل ہو جائیں۔",
        "nocookieslogin": "صارفین کے داخل ہونے کیلئے {{SITENAME}} کوکیز استعمال کرتا ہے.\nآپ کے ہاں کوکیز غیر فعال ہیں.\nانہیں فعال کرنے کے بعد پھر کوشش کیجئے.",
        "nocookiesfornew": "اس صارف نام کا کھاتہ نہیں بن سکا۔ہم اس بات کی وضاحت نہیں کر سکتے (کہ ایسا کیوں ہوا)، براہ مہربانی! آپ\nیقین کر لیں کہ آپ کی کوکیز فعال ہیں، صفحہ تازہ کریں اور پھر کوشش کریں۔",
        "createacct-loginerror": "کھاتہ بن چکا ہے لیکن آپ اس میں خودکار طور پر داخل نہیں ہو سکے۔ براہ کرم [[Special:UserLogin|دستی طور پر داخل ہونے کی کوشش کریں]]۔",
-       "noname": "آپ Ù\86Û\92 ØµØ­Û\8cØ­ Ø§Ø³Ù\85 ØµØ§Ø±Ù\81 Ù\86Û\81Û\8cÚº Ú\86Ù\86ا.",
+       "noname": "آپ Ù\86Û\92 ØµØ­Û\8cØ­ ØµØ§Ø±Ù\81 Ù\86اÙ\85 Ù\86Û\81Û\8cÚº Ú\86Ù\86اÛ\94",
        "loginsuccesstitle": "داخلہ کامیاب",
        "loginsuccess": "'''اب آپ {{SITENAME}} میں بنام \"$1\" داخل ہوچکے ہیں۔'''",
        "nosuchuser": "\"$1\" کے نام سے کوئی صارف موجود نہیں ہے۔\nبراہ کرم ہجوں کو جانچ لیں۔\nنیز اگر آپ چاہیں تو [[Special:CreateAccount|نیا کھاتہ بھی بنا سکتے ہیں]]۔",
        "nosuchusershort": "\"$1\" کے نام سے کوئی صارف موجود نہیں.\nاپنا ہجہ جانچئے.",
-       "nouserspecified": "آپ Ú©Ù\88 Ø§Û\8cÚ© Ø§Ø³Ù\85Ù\90 ØµØ§Ø±Ù\81 Ù\85خصÙ\88ص Ú©Ø±Ù\86ا Û\81Û\92.",
+       "nouserspecified": "آپ Ú©Ù\88 Ø§Û\8cÚ© ØµØ§Ø±Ù\81 Ù\86اÙ\85 Ù\85خصÙ\88ص Ú©Ø±Ù\86ا Û\81Û\92Û\94",
        "login-userblocked": "اِس صارف پر پابندی ہے. داخلِ نوشتہ ہونے کی اجازت نہیں.",
        "wrongpassword": "آپ نے غلط پاس ورڈ یا صارف نام درج کیا ہے۔ براہ مہربانی دوبارہ کوشش کریں۔",
        "wrongpasswordempty": "کلمۂ شناخت ندارد۔ دوبارہ کوشش کریں۔",
-       "passwordtooshort": "آپکا منتخب کردہ پارلفظ مختصر ہے. پارلفظ کم از کم {{PLURAL:$1|1 محرف|$1 محارف}} ہونا چاہئے.",
+       "passwordtooshort": "آپ کا منتخب کردہ پاسورڈ مختصر ہے۔ پاسورڈ کم از کم {{PLURAL:$1|1 حرف|$1 حروف}} پر مشتمل ہونا چاہیے۔",
        "passwordtoolong": "خفیہ رمز (پاس ورڈ) {{PLURAL:$1|1 حرف|$1 حروف}} سے زیادہ طویل نہیں ہو سکتا۔",
-       "passwordtoopopular": "عام طور پر چنا جانے والا خفیہ رمز (پاسورڈ) استعمال نہیں کیا جا سکتا۔ براہ مہربانی آپ کوئی الگ خفیہ رمز استعمال کریں، تا کہ آپ کا کھاتہ محفوظ رہے۔",
-       "password-name-match": "آپکا پارلفظ آپکے اسمِ صارف سے مختلف ہونا چاہئے.",
+       "passwordtoopopular": "متداول پاس ورڈ استعمال نہیں کیا جا سکتا۔ براہ مہربانی آپ کوئی منفرد پاس ورڈ استعمال کریں تاکہ آپ کا کھاتہ محفوظ رہے۔",
+       "password-name-match": "آپ کا پاسورڈ آپ کے صارف نام سے مختلف ہونا چاہیے۔",
        "password-login-forbidden": "اس صارف نام یا کلمۂ شناخت (پاسورڈ) کا استعمال ممنوع ہے",
        "mailmypassword": "پاسورڈ تبدیل کریں",
        "passwordremindertitle": "نیا عارضی کلمۂ شناخت برائے {{SITENAME}}",
-       "passwordremindertext": "(IP Ù¾ØªÛ\81 $1 Ø³Û\92) Ú©Ø³Û\8c (Û\8cا Ø´Ø§Û\8cد Ø¢Ù¾) Ù\86Û\92 {{SITENAME}} ($4)\nÚ©Û\8cÙ\84ئÛ\92 Ù\86ئÛ\8c Ú©Ù\84Ù\85Û\82 Ø´Ù\86اخت Ú©Û\8cÙ\84ئÛ\92 Ø§Ù\84تÙ\85اس Ú©Û\8cا. Ø§Û\8cÚ© Ø¹Ø§Ø±Ø¶Û\8c Ú©Ù\84Ù\85Û\82 Ø´Ù\86اخت \"$3\"\nبرائÛ\92 ØµØ§Ø±Ù\81 \"$2\" ØªØ®Ù\84Û\8cÙ\82 Ú©Û\8cا Ú¯Û\8cا Û\81Û\92. Ø§Ú¯Ø± Û\8cÛ\81 Ø¢Ù¾ Ú©Ø§ Ø§Ø±Ø§Ø¯Û\81 ØªÚ¾Ø§Ø\8c ØªÙ\88 Ø¢Ù¾\nÚ©Ù\88 Ú\86اÛ\81ئÛ\92 Ú©Û\81 Ø¯Ø§Ø®Ù\84Ù\90 Ù\86Ù\88شتÛ\81 Û\81Ù\88Ù\86Û\92 Ú©Û\92 Ø¨Ø¹Ø¯ Ù\86ئÛ\92 Ú©Ù\84Ù\85Û\82 Ø´Ù\86اخت Ú©Ø§ Ø§Ù\86تخاب Ú©Ø±Û\8cÚº.\nآپ Ú©Ø§ Ú©Ù\84Ù\85Û\82 Ø´Ù\86اخت {{PLURAL:$5|اÛ\8cÚ© Ø¯Ù\90Ù\86|$5 Ø¯Ù\90Ù\86}} Ú©Û\92 Ø¨Ø¹Ø¯ Ù\86اکارÛ\81 Û\81Ù\88جائÛ\92 Ú¯Ø§.\n\nاگر Ú©Ø³Û\8c Ø§Ù\8eÙ\88ر Ù\86Û\92 Û\8cÛ\81 Ø§Ù\84تÙ\85اس Ú©Û\8cا Û\81Û\92Ø\8c Û\8cا Ø¢Ù¾ Ú©Ù\88 Ø§Ù¾Ù\86ا Ú©Ù\84Ù\85Û\82 Ø´Ù\86اخت Û\8cاد Ø¢Ú¯Û\8cا Û\81Û\92Ø\8c\nاÙ\88ر Ø¢Ù¾ Ø§Ø³Û\92 ØªØ¨Ø¯Û\8cÙ\84 Ù\86Û\81Û\8cÚº Ú©Ø±Ù\86ا Ú\86اÛ\81تÛ\92Ø\8c ØªÙ\88 Ø¢Ù¾ Û\8cÛ\81 Ù¾Û\8cغاÙ\85 Ù\86ظر Ø§Ù\86داز Ú©Ø±Ø³Ú©ØªÛ\92 Û\81Û\8cÚº Ø§Ù\88ر\nآپÙ\86ا Ù¾Ù\8fراÙ\86ا Ú©Ù\84Ù\85Û\82 Ø´Ù\86اخت Ú©Ø§ Ø§Ø³ØªØ¹Ù\85اÙ\84 Ø¬Ø§Ø±Û\8c Ø±Ú©Ú¾ Ø³Ú©ØªÛ\92 Û\81Û\8cÚº.",
+       "passwordremindertext": "(IP Ù¾ØªÛ\81 $1 Ø³Û\92) Ú©Ø³Û\8c (Û\8cا Ø´Ø§Û\8cد Ø¢Ù¾) Ù\86Û\92 {{SITENAME}} ($4)\nÚ©Û\92 Ù\84Û\8cÛ\92 Ù\86ئÛ\92 Ù¾Ø§Ø³ Ù\88رÚ\88 Ú©Û\8c Ø¯Ø±Ø®Ù\88است Ú©Û\8c Û\81Û\92Û\94 Ù\84Û\81ذا ØµØ§Ø±Ù\81 \"$2\" Ú©Û\92 Ù\84Û\8cÛ\92 Ø§Û\8cÚ© Ø¹Ø§Ø±Ø¶Û\8c Ù¾Ø§Ø³ Ù\88رÚ\88 \"$3\" Ø¨Ù\86ا Ø¯Û\8cا Ú¯Û\8cا Û\81Û\92Û\94\nاگر Û\8cÛ\81 Ø§Ù\82داÙ\85 Ø¨Ø§Ù\84ارادÛ\81 ØªÚ¾Ø§ ØªÙ\88 Ø§Ø¨ Ø¢Ù¾ Ù\84اگ Ø§Ù\86 Û\81Ù\88Ù\86Û\92 Ú©Û\92 Ø¨Ø¹Ø¯ Ù\86Û\8cا Ù¾Ø§Ø³ Ù\88رÚ\88 Ø±Ú©Ú¾Û\8cÚºÛ\94\nآپ Ú©Ø§ Ø¯Ø±Ø¬ Ø¨Ø§Ù\84ا Ø¹Ø§Ø±Ø¶Û\8c Ù¾Ø§Ø³ Ù\88رÚ\88 {{PLURAL:$5|اÛ\8cÚ© Ø¯Ù\90Ù\86|$5 Ø¯Ù\90Ù\86Ù\88Úº}} Ú©Û\92 Ø¨Ø¹Ø¯ Ù\86اکارÛ\81 Û\81Ù\88جائÛ\92 Ú¯Ø§Û\94\n\nاگر Ú©Ø³Û\8c Ø§Ù\8eÙ\88ر Ù\86Û\92 Û\8cÛ\81 Ø¯Ø±Ø®Ù\88است Ú©Û\8c Û\81Û\92Ø\8c Û\8cا Ø¢Ù¾ Ú©Ù\88 Ø§Ù¾Ù\86ا Ù¾Ø§Ø³ Ù\88رÚ\88 Û\8cاد Ø¢Ú¯Û\8cا Û\81Û\92 Ø§Ù\88ر Ø¢Ù¾ Ø§Ø³Û\92 ØªØ¨Ø¯Û\8cÙ\84 Ù\86Û\81Û\8cÚº Ú©Ø±Ù\86ا Ú\86اÛ\81تÛ\92 ØªÙ\88 Ø¢Ù¾ Û\8cÛ\81 Ù¾Û\8cغاÙ\85 Ù\86ظر Ø§Ù\86داز Ú©Ø±Ú©Û\92 Ø§Ù¾Ù\86Û\92 Ù¾Ø±Ø§Ù\86Û\92 Ù¾Ø§Ø³ Ù\88رÚ\88 Ú©Ø§ Ø§Ø³ØªØ¹Ù\85اÙ\84 Ø¬Ø§Ø±Û\8c Ø±Ú©Ú¾ Ø³Ú©ØªÛ\92 Û\81Û\8cÚºÛ\94",
        "noemail": "صارف \"$1\" کیلئے کوئی برقی پتہ درج نہیں کیا گیا.",
        "noemailcreate": "صحیح برقی پتہ مہیّا کریں",
        "passwordsent": "ایک نیا کلمۂ شناخت \"$1\" کے نام سے بننے والی برقی ڈاک کے پتے کیلیے بھیج دیا گیا ہے۔\nجب وہ موصول ہو جاۓ تو براہ کرم اسکے ذریعے دوبارہ داخل ہوں۔",
        "blocked-mailpassword": "آپ کے آئی پی پتے کی ترمیم کاری پر پابندی لگا دی گئی ہے۔ غلط استعمال سے بچنے کے لیے اس آئی پی پتے سے پاس ورڈ کی بازیابی کی اجازت منسوخ کر دی گئی ہے۔",
        "eauthentsent": "ایک تصدیقی برقی خط نامزد کیے گئے برقی پتہ پر ارسال کردیا گیا ہے۔\nآپ کو موصول ہوئے برقی خط میں ہدایات پر عمل کرکے اس بات کی توثیق کرلیں کہ مذکورہ برقی پتہ آپ کا ہی ہے۔",
-       "throttled-mailpassword": "گزشتÛ\81 {{PLURAL:$1|Ú¯Ú¾Ù\86Ù¹Û\92|$1 Ú¯Ú¾Ù\86Ù¹Ù\88Úº}} Ú©Û\92 Ø¯Ù\88راÙ\86 Ù¾Û\81Ù\84Û\92 Ø³Û\92 Û\81Û\8c Ù¾Ø§Ø±Ù\84Ù\81ظ (پاسÙ\88رÚ\88) Ú©Û\8c ØªØ¨Ø¯Û\8cÙ\84Û\8c Ú©Û\92 Ù\84Û\8cÛ\92 Ø¨Ø±Ù\82Û\8c Ø®Ø· Ø¨Ú¾Û\8cجا Ú¯Ù\8aا Û\81Û\92Û\94\nÙ\86اجائز Ø§Ø³ØªØ¹Ù\85اÙ\84 Ú©Û\92 Ø³Ø¯Ù\91باب Ú©Û\8cÙ\84ئÛ\92Ø\8c {{PLURAL:$1|Ú¯Ú¾Ù\86Ù¹Û\81|$1 Ú¯Ú¾Ù\86Ù¹Ù\88Úº}} Ú©Û\92 Ø¯Ù\88راÙ\86 ØµØ±Ù\81 Ø§Û\8cÚ© Ø¨Ø±Ù\82Û\8c Ø®Ø· Ø¨Ú¾Û\8cجا Ø¬Ø§سکتا ہے۔",
+       "throttled-mailpassword": "گزشتÛ\81 {{PLURAL:$1|Ú¯Ú¾Ù\86Ù¹Û\92|$1 Ú¯Ú¾Ù\86Ù¹Ù\88Úº}} Ú©Û\92 Ø¯Ù\88راÙ\86 Ù¾Û\81Ù\84Û\92 Ø³Û\92 Û\81Û\8c Ù¾Ø§Ø³Ù\88رÚ\88 Ú©Û\8c ØªØ¨Ø¯Û\8cÙ\84Û\8c Ú©Û\92 Ù\84Û\8cÛ\92 Ø¨Ø±Ù\82Û\8c Ø®Ø· Ø¨Ú¾Û\8cجا Ú¯Ù\8aا Û\81Û\92Û\94\nÙ\86اجائز Ø§Ø³ØªØ¹Ù\85اÙ\84 Ú©Û\92 Ø³Ø¯Ù\91باب Ú©Û\92 Ù\84Û\8cÛ\92Ø\8c {{PLURAL:$1|Ú¯Ú¾Ù\86Ù¹Û\81|$1 Ú¯Ú¾Ù\86Ù¹Ù\88Úº}} Ú©Û\92 Ø¯Ù\88راÙ\86 ØµØ±Ù\81 Ø§Û\8cÚ© Ø¨Ø±Ù\82Û\8c Ø®Ø· Ø¨Ú¾Û\8cجا Ø¬Ø§ سکتا ہے۔",
        "mailerror": "مسلہ دوران ترسیل خط:$1",
        "acct_creation_throttle_hit": "آپکی آئی پی کے ذریعے اِس ویکی پر آنے والے صارفین نے پچھلے $2 میں {{PLURAL:$1|1 کھاتہ بنایا ہے|$1 کھاتے بنائے ہیں}} جو اس مدت کے لیے کافی ہیں۔\nلہٰذا آپ کی آئی پی استعمال کرنے والے صارفین اِس وقت مزید کھاتے نہیں بنا سکتے۔",
        "emailauthenticated": "آپ کے برقی ڈاک پتہ کی تصدیق مورخہ $2 بوقت $3 بجے ہوئی۔",
        "accountcreated": "تخلیقِ کھاتہ",
        "accountcreatedtext": "[[{{ns:User}}:$1|$1]] ([[{{ns:User talk}}:$1|تبادلۂ خیال]]) کا صارف کھاتہ بن چکا ہے۔",
        "createaccount-title": "کھاتہ سازی برائے {{SITENAME}}",
-       "createaccount-text": "کسی نے {{SITENAME}} ($4) پر \"$2\" کے نام سے اور \"$3\" پارلفظ کے ساتھ آپ کا برقی پتہ استعمال کرتے ہوئے کھاتہ بنایا ہے.\nآپ کو چاہئے کہ ابھی داخلِ نوشتہ ہوکر اپنا پارلفظ تبدیل کردیں.\n\nاگر یہ کھاتہ غلطی سے بنا تھا تو آپ یہ پیغام نظرانداز کرسکتے ہیں.",
+       "createaccount-text": "کسی نے {{SITENAME}} ($4) پر «$2» کے نام سے اور \"$3\" پاسورڈ کے ساتھ آپ کا برقی پتہ استعمال کرتے ہوئے کھاتہ بنایا ہے۔\nآپ کو چاہیے کہ ابھی لاگ ان ہو کر اپنا پاسورڈ تبدیل کر دیں۔\n\nاگر یہ کھاتہ غلطی سے بنا ہے، تو آپ یہ پیغام نظر انداز کر دیں۔",
        "login-throttled": "آپ نے حال ہی میں متعدد مرتبہ لاگ ان ہونے کی کوشش کی ہے۔\nدوبارہ کوشش کرنے سے پہلے $1 انتظار فرمائیے۔",
        "login-abort-generic": "لاگ ان ناکام - منسوخ شد",
        "login-migrated-generic": "آپ کا کھاتہ منتقل کر دیا گیا، اب اس ویکی پر آپ کا صارف نام موجود نہیں۔",
        "user-mail-no-addy": "برقی ڈاک بھیجنے کی کوشش بغیر برقی ڈاک پتہ",
        "user-mail-no-body": "خالی یا بہت ہی مختصر برقی خط بھیجنے کی کوشش",
        "changepassword": "کلمۂ شناخت تبدیل کریں",
-       "resetpass_announce": "آپ ایک برقی ارسال کردہ عارضی رمز (کوڈ) کے ساتھ داخل ہوئے ہیں۔\nداخلِ نوشتہ کے عمل کو مکمل کرنے کیلئے آپ کو یہاں نیا پارلفظ (پاسورڈ) متعین کرنا ہوگا۔",
-       "resetpass_header": "کھاتÛ\81 Ú©Ø§ Ù¾Ø§Ø±Ù\84Ù\81ظ تبدیل کریں",
+       "resetpass_announce": "لاگ ان کے عمل کو مکمل کرنے کے لیے آپ کو نیا پاسورڈ متعین کرنا ہو گا۔",
+       "resetpass_header": "کھاتÛ\81 Ú©Ø§ Ù¾Ø§Ø³Ù\88رÚ\88 تبدیل کریں",
        "oldpassword": "پرانا کلمۂ شناخت:",
        "newpassword": "نیا کلمۂ شناخت",
        "retypenew": "نیا کلمۂ شناخت دوبارہ درج کریں:",
-       "resetpass_submit": "پارÙ\84Ù\81ظ Ø¨Ù\86اؤ Ø§Ù\88ر Ø¯Ø§Ø®Ù\84 Û\81Ù\88جاؤ",
+       "resetpass_submit": "پاسÙ\88رÚ\88 Ø¨Ù\86ائÛ\8cÚº Ø§Ù\88ر Ø¯Ø§Ø®Ù\84 Û\81Ù\88Úº",
        "changepassword-success": "آپ کا پاس ورڈ تبدیل کر دیا گیا!",
        "changepassword-throttled": "آپ نے حال ہی میں متعدد مرتبہ داخل ہونے کی کوشش کی ہے۔\nدوبارہ کوشش کرنے سے پہلے $1 انتظار کریں۔",
        "botpasswords": "روبہ پاس ورڈ",
        "botpasswords-existing": "روبہ کے موجودہ پاس ورڈ",
        "botpasswords-createnew": "روبہ کا نیا پاس ورڈ بنائیں",
        "botpasswords-editexisting": "روبہ کے موجودہ پاس ورڈ میں ترمیم کریں",
+       "botpasswords-label-needsreset": "(پاسورڈ کی ترتیب نو درکار ہے)",
        "botpasswords-label-appid": "روبہ کا نام:",
        "botpasswords-label-create": "تخلیق کریں",
        "botpasswords-label-update": "تجدید کریں",
        "botpasswords-restriction-failed": "روبہ کے پاس ورڈ کی پابندیاں اس لاگ ان سے مانع ہیں۔",
        "botpasswords-invalid-name": "درج کردہ صارف نام میں روبہ کے پاس ورڈ کا فاصل لفظ موجود نہیں ہے (\"$1\")۔",
        "botpasswords-not-exist": "صارف \"$1\" کے پاس \"$2\" کے نام سے روبہ کا پاس ورڈ نہیں ہے۔",
-       "resetpass_forbidden": "پارÙ\84Ù\81ظ ØªØ¨Ø¯Û\8cÙ\84 Ù\86Û\81Û\8cÚº Û\81Ù\88سکتا",
+       "resetpass_forbidden": "پاسÙ\88رÚ\88 ØªØ¨Ø¯Û\8cÙ\84 Ù\86Û\81Û\8cÚº Û\81Ù\88 سکتا",
        "resetpass_forbidden-reason": "پاس ورڈ تبدیل نہیں کیا جا سکتا: $1",
        "resetpass-no-info": "اِس صفحہ تک براہِ راست رسائی کیلئے آپ کو داخلِ نوشتہ ہونا پڑے گا.",
-       "resetpass-submit-loggedin": "پارÙ\84Ù\81ظ Ú©Û\8c ØªØ¨Ø¯Û\8cÙ\84Û\8c",
+       "resetpass-submit-loggedin": "پاسÙ\88رÚ\88 ØªØ¨Ø¯Û\8cÙ\84 Ú©Ø±Û\8cÚº",
        "resetpass-submit-cancel": "منسوخ",
        "resetpass-wrong-oldpass": "عارضی یا موجودہ پاس ورڈ نادرست ہے۔\nشاید آپ نے پہلے ہی اپنا پاس ورڈ تبدیل کر لیا ہے یا نئے عارضی پاس ورڈ کی درخواست کر چکے ہیں۔",
-       "resetpass-recycled": "براہ کرم اپنے موجودہ کلمۂ شناخت (پاسورڈ) سے مختلف کلمۂ شناخت سے بازترتیب (ری‌سیٹ) کریں",
-       "resetpass-temp-emailed": "آپ Ø¹Ø§Ø±Ø¶Û\8c Ø¨Ø±Ù\82Û\8c Ø®Ø· Ø³Û\92 Ø¨Ú¾Û\8cجÛ\92 Ú¯Ø¦Û\92 Ú©Ù\88Ú\88 Ø³Û\92 Ù\84اگ Ø§Ù\86 Û\81Û\8cÚº\nÙ\85Ú©Ù\85Ù\84 Ø·Ù\88ر Ù¾Ø± Ù\84اگ Ø§Ù\86 Û\81Ù\88Ù\86Û\92 Ú©Û\92 Ù\84Û\8cÛ\92 Ø¢Ù¾ Ú©Ù\88 Ù\86Û\8cا Ù¾Ø§Ø³Ù\88رÚ\88 Ø³Û\8cÙ¹ Ú©Ø±Ù\86ا Ù¾Ú\91Û\92 Ú¯Ø§",
-       "resetpass-temp-password": "عارضÛ\8c Ù¾Ø§Ø±Ù\84Ù\81ظ:",
+       "resetpass-recycled": "براہ کرم اپنے موجودہ پاس ورڈ سے مختلف پاس ورڈ رکھیں۔",
+       "resetpass-temp-emailed": "آپ Ø§Û\8cÚ© Ø¨Ø±Ù\82Û\8c Ø§Ø±Ø³Ø§Ù\84 Ú©Ø±Ø¯Û\81 Ø¹Ø§Ø±Ø¶Û\8c Ú©Ù\88Ú\88 Ú©Û\92 Ø³Ø§ØªÚ¾ Ø¯Ø§Ø®Ù\84 Û\81Ù\88ئÛ\92 Û\81Û\8cÚºÛ\94\nÙ\84اگ Ø§Ù\86 Ú©Û\92 Ø¹Ù\85Ù\84 Ú©Ù\88 Ù\85Ú©Ù\85Ù\84 Ú©Ø±Ù\86Û\92 Ú©Û\92 Ù\84Û\8cÛ\92 Ø¢Ù¾ Ú©Ù\88 Û\8cÛ\81اں Ù\86Û\8cا Ù¾Ø§Ø³Ù\88رÚ\88 Ù\85تعÛ\8cÙ\86 (سÛ\8cÙ¹) Ú©Ø±Ù\86ا Û\81Ù\88 Ú¯Ø§Û\94",
+       "resetpass-temp-password": "عارضÛ\8c Ù¾Ø§Ø³Ù\88رÚ\88:",
        "resetpass-abort-generic": "کسی توسیع نے پاس ورڈ کی تبدیلی کو منسوخ کر دیا ہے۔",
        "resetpass-expired": "آپ کے پاس ورد کی مدت ختم ہو چکی ہے۔ داخل ہونے کے لیے براہ کرم نیا پاس ورڈ بنائیں۔",
-       "resetpass-expired-soft": "آپ کے پاس ورڈ کی مدت ختم ہو چکی ہے، لہذا اسے دوبارہ بنانے کی ضرورت ہے۔\nبراہ کرم نیا پاس ورڈ بنائیں، تاہم اگر مستقبل میں اس کی ترتیب نو مقصود ہو تو «{{int:authprovider-resetpass-skip-label}}» پر کلک کریں۔",
-       "resetpass-validity-soft": "آپ کا پاس ورڈ درست نہیں: $1\n\nبراہ کرم نیا پاس ورڈ بنائیں، تاہم اگر مستقبل میں اس کی ترتیب نو مقصود ہو تو «{{int:authprovider-resetpass-skip-label}}» پر کلک کریں۔",
+       "resetpass-expired-soft": "آپ کے پاس ورڈ کی مدت ختم ہو چکی ہے، لہذا اسے دوبارہ بنانے کی ضرورت ہے۔\nبراہ کرم نیا پاس ورڈ بنائیں یا اگر مستقبل میں اس کی ترتیب نو مقصود ہو تو «{{int:authprovider-resetpass-skip-label}}» پر کلک کریں۔",
+       "resetpass-validity-soft": "آپ کا پاس ورڈ درست نہیں: $1\n\nبراہ کرم نیا پاس ورڈ بنائیں یا اگر مستقبل میں اس کی ترتیب نو مقصود ہو تو «{{int:authprovider-resetpass-skip-label}}» پر کلک کریں۔",
        "passwordreset": "پاس ورڈ کی ترتیب نو",
        "passwordreset-text-one": "برقی خط کے ذریعہ عارضی پاس ورڈ حاصل کرنے کے لیے اس فارم کو پُر کریں۔",
        "passwordreset-text-many": "{{PLURAL:$1|برقی خط کے ذریعہ عارضی پاس ورڈ حاصل کرنے کے لیے کسی ایک خانے کو پُر کریں۔}}",
        "passwordreset-disabled": "اس ویکی پر پاس ورڈ کی ترتیب نو کی سہولت فعال نہیں ہے۔",
        "passwordreset-emaildisabled": "اس ویکی پر برقی خط کی سہولت غیر فعال ہیں۔",
-       "passwordreset-username": "اسÙ\85Ù\90 ØµØ§Ø±Ù\81:",
+       "passwordreset-username": "صارÙ\81 Ù\86اÙ\85:",
        "passwordreset-domain": "ساحہ:",
        "passwordreset-email": "برقی ڈاک پتہ:",
        "passwordreset-emailtitle": "{{SITENAME}} کھاتہ کی تفصیلات",
        "subject-preview": "عنوان/شہ سرخی کی نمائش:",
        "previewerrortext": "آپ کی تبدیلیوں کی نمائش دکھانے کے دوران میں کوئی نقص واقع ہو گیا ہے۔",
        "blockedtitle": "صارف مسدود ہے",
-       "blockedtext": "'''آپکا اسمِ صارف یا آئی پی پتہ پر پابندی ہے.'''\n\n$1 نے پابندی لگائی تھی.\nوجہ یہ بتائی گئی کہ ''$2''.\n\n* پابندی کی ابتداء : $8\n* پابندی کا اختتام : $6\n* Intended blockee: $7\n\nآپ $1 یا کسی دوسرے [[{{MediaWiki:Grouppage-sysop}}|منتظم]] سے رابطہ کرکے پابندی پر بات چیت کرسکتے ہیں.\nآپ ‘صارف کو برقی خط ارسال کریں’ کی خاصیت اُس وقت تک استعمال نہیں کرسکتے جب تک آپ اپنے [[Special:Preferences|کھاتہ کے ترجیحات]] میں صحیح برقی پتہ معیّن نہ کریں، اور آپ کو اِسے استعمال کرنے سے پابند نہیں کیا گیا ہے.\nآپکا موجودہ آئی پی پتہ $3 ہے، اور پابندی کی شناخت #$5 ہے.\nبراہِ مہربانی کسی بھی قسم کے استفسار میں درج بالا تمام تفاصیل شامل کریں.",
-       "autoblockedtext": "آپ کے آئی پی پتے پر خودکارانہ طریقہ سے پابندی لگا دی گئی ہے کیونکہ یہ دوسرے صارف نے استعمال کی تھی، جس پر $1 نے پابندی لگائی ہوئی ہے۔\nوجہ یہ بتائی گئی کہ:\n<em>$2</em>\n\n*پابندی کی ابتدا: $8\n*پابندی کا اختتام: $6\n*Intended blockee: $7\n\nآپ $1 سے یا دوسرے [[{{MediaWiki:Grouppage-sysop}}|منتظمین]] سے رابطہ کر کے پابندی پر بات چیت کرسکتے ہیں۔\n\nیاد رکھیں کہ ”صارف کو برقی خط ارسال کریں“ کی خاصیت اُس وقت تک استعمال نہیں کرسکتے جب تک آپ اپنے [[Special:Preferences|کھاتے کی ترجیحات]] میں صحیح برقی پتہ معیّن نہ کریں، اور آپ کو اِسے استعمال کرنے سے پابند نہیں کیا گیا ہے۔\nآپ کا موجودہ آئی پی پتہ $3 ہے، اور پابندی کی شناخت #$5 ہے۔\nبراہِ مہربانی کسی بھی قسم کے استفسار میں درج بالا تمام تفصیل شامل کریں۔",
-       "systemblockedtext": "آپ Ú©Û\92 Ø§Ø³Ù\85 ØµØ§Ø±Ù\81 Û\8cا Ø¢Ø¦Û\8c Ù¾Û\8c Ù¾ØªÛ\92 Ù¾Ø± Ù\85Û\8cÚ\88Û\8cاÙ\88Û\8cÚ©Û\8c Ú©Û\8c Ø¬Ø§Ù\86ب Ø³Û\92 Ø®Ù\88دکاراÙ\86Û\81 Ø·Ø±Û\8cÙ\82Û\92 Ø³Û\92 Ù¾Ø§Ø¨Ù\86دÛ\8c Ù\84گا Ø¯Û\8c Ú¯Ø¦Û\8c Û\81Û\92Û\94\nاÙ\88ر Ù\88جÛ\81 Û\8cÛ\81 Ø¨ØªØ§Ø¦Û\8c Ú¯Ø¦Û\8c Û\81Û\92 Ú©Û\81:\n<em>$2</em>\n\n*پابÙ\86دÛ\8c Ú©Û\8c Ø§Ø¨ØªØ¯Ø§: $8\n*پابÙ\86دÛ\8c Ú©Ø§ Ø§Ø®ØªØªØ§Ù\85: $6\n*Intended blockee: $7\n\nآپ Ú©Ø§ Ù\85Ù\88جÙ\88دÛ\81 Ø¢Ø¦Û\8c Ù¾Û\8c Ù¾ØªÛ\81 $3 Û\81Û\92Û\94\nبراÛ\81Ù\90 Ù\85Û\81رباÙ\86Û\8c Ú©Ø³Û\8c Ø¨Ú¾Û\8c Ù\82سÙ\85 Ú©Û\92 Ø§Ø³ØªÙ\81سار Ù\85Û\8cÚº Ø¯Ø±Ø¬ Ø¨Ø§Ù\84ا ØªÙ\85اÙ\85 ØªÙ\81صÛ\8cÙ\84 شامل کریں۔",
+       "blockedtext": "<strong>آپ کے صارف نام یا آئی پی پتہ پر پابندی لگائی جا چکی ہے۔</strong>\n\n$1 نے پابندی عائد کی اور یہ وجہ درج کی: <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:<em>$2</em>\n\n*پابندی کی ابتدا: $8\n*پابندی کا اختتام: $6\n*ممنوع صارف: $7\n\nآپ $1 سے یا دوسرے [[{{MediaWiki:Grouppage-sysop}}|منتظمین]] سے رابطہ کر کے اس پابندی پر گفت و شنید کر سکتے ہیں۔\n\nیاد رکھیں کہ «{{int:emailuser}}» کی خاصیت اُس وقت تک استعمال نہیں کرسکتے جب تک آپ اپنے [[Special:Preferences|کھاتے کی ترجیحات]] میں صحیح برقی پتہ درج نہ کریں اور آپ کو اِسے استعمال کرنے سے روک نہ دیا گیا ہو۔\n\nآپ کا موجودہ آئی پی پتہ $3 ہے، اور پابندی کی شناخت #$5 ہے۔\nبراہِ مہربانی کسی بھی قسم کے استفسار میں درج بالا تمام تفصیلات شامل کریں۔",
+       "systemblockedtext": "آپ Ú©Û\92 ØµØ§Ø±Ù\81 Ù\86اÙ\85 Û\8cا Ø¢Ø¦Û\8c Ù¾Û\8c Ù¾ØªÛ\92 Ù¾Ø± Ù\85Û\8cÚ\88Û\8cاÙ\88Û\8cÚ©Û\8c Ú©Û\8c Ø¬Ø§Ù\86ب Ø³Û\92 Ø®Ù\88دکار Ø·Ø±Û\8cÙ\82Û\92 Ø³Û\92 Ù¾Ø§Ø¨Ù\86دÛ\8c Ù\84گا Ø¯Û\8c Ú¯Ø¦Û\8c Û\81Û\92Û\94\nاÙ\88ر Ù\88جÛ\81 Û\8cÛ\81 Ø¯Ø±Ø¬ Ú©Û\8c Ú¯Ø¦Û\8c Û\81Û\92 Ú©Û\81:\n<em>$2</em>\n\n*پابÙ\86دÛ\8c Ú©Û\8c Ø§Ø¨ØªØ¯Ø§: $8\n*پابÙ\86دÛ\8c Ú©Ø§ Ø§Ø®ØªØªØ§Ù\85: $6\n*Ù\85Ù\85Ù\86Ù\88ع ØµØ§Ø±Ù\81: $7\n\nآپ Ú©Ø§ Ù\85Ù\88جÙ\88دÛ\81 Ø¢Ø¦Û\8c Ù¾Û\8c Ù¾ØªÛ\81 $3 Û\81Û\92Û\94\nبراÛ\81Ù\90 Ù\85Û\81رباÙ\86Û\8c Ú©Ø³Û\8c Ø¨Ú¾Û\8c Ù\82سÙ\85 Ú©Û\92 Ø§Ø³ØªÙ\81سار Ù\85Û\8cÚº Ø¯Ø±Ø¬ Ø¨Ø§Ù\84ا ØªÙ\85اÙ\85 ØªÙ\81صÛ\8cÙ\84ات شامل کریں۔",
        "blockednoreason": "کوئی وجہ نہیں دی گئی",
        "whitelistedittext": "ترمیم کیلئے $1 ضروری ہے.",
        "confirmedittext": "صفحات میں ترمیم کرنے سے پہلے آپ اپنے برقی پتہ کی تصدیق کریں.\nبرائے مہربانی! اپنی [[Special:Preferences|ترجیحات]] کے ذریعے اپنا برقی پتہ کا تعیّن اور تصدیق کیجئے.",
        "userjspreview": "<strong>یاد رہے کہ اس وقت آپ اپنی جاوا اسکرپٹ کی محض نمائش دیکھ/جانچ رہے ہیں، یہ اب تک محفوظ نہیں ہوئی ہے!</strong>",
        "sitecsspreview": "<strong>یاد رہے کہ اس وقت آپ اس سی ایس کی محض نمائش دیکھ رہے ہیں، یہ اب تک محفوظ نہیں ہوئی ہے!</strong>",
        "sitejspreview": "<strong>یاد رہے کہ اس وقت آپ اس جاوا اسکرپٹ کوڈ کی محض نمائش دیکھ رہے ہیں، یہ اب تک محفوظ نہیں ہوئی ہے!</strong>",
-       "userinvalidconfigtitle": "<strong>انتباہ:</strong> یہاں «$1» نام سے کوئی پوشاک موجود نہیں۔ شخصی .css اور .js کے صفحات اپنے عنوان میں چھوٹے حروف استعمال کرتے ہیں، مثلاً {{ns:user}}:Foo/Vector.css کی بجائے {{ns:user}}:Foo/vector.css",
+       "userinvalidconfigtitle": "<strong>انتباہ:</strong> یہاں «$1» نام سے کوئی پوشاک موجود نہیں۔ شخصی .css، .json اور .js کے صفحات اپنے عنوان میں چھوٹے حروف استعمال کرتے ہیں، مثلاً {{ns:user}}:Foo/Vector.css کی بجائے {{ns:user}}:Foo/vector.css",
        "updated": "(اپ ڈیٹڈ)",
        "note": "'''نوٹ:'''",
-       "previewnote": "'''یاد رکھیں، یہ صرف نمائش ہے ۔آپ کی ترامیم ابھی محفوظ نہیں کی گئیں۔'''",
+       "previewnote": "<strong>یاد رکھیں، یہ صرف نمائش ہے۔</strong>\nآپ کی ترامیم ابھی محفوظ نہیں کی گئیں!",
        "continue-editing": "خانہ ترمیم میں جائیں",
        "previewconflict": "اس نمائش میں خانہ ترمیم کے اوپر موجود متن جس انداز میں ظاہر ہو رہا ہے، محفوظ کرنے کے بعد اسی طرح نظر آئے گا۔",
        "session_fail_preview": "معذرت! نشست کے مواد میں خامی کی وجہ سے آپ کی  ترمیم مکمل نہیں ہو سکی۔\n\nشاید آپ اپنے کھاتے سے خارج ہو گئے ہیں۔ <strong>براہ کرم اس بات کی تصدیق کر لیں کہ آپ داخل ہیں اور دوبارہ کوشش کریں۔</strong> اگر آپ کو پھر بھی مشکل پیش آرہی ہو تو ایک بار [[Special:UserLogout|خارج ہو کر]] واپس داخل ہو جائیں اور اپنے براؤزر کو جانچ لیں کہ آیا وہ اس سائٹ کی کوکیز اخذ کر رہا ہے یا نہیں۔",
        "session_fail_preview_html": "معاف کیجیے گا!سیشن ڈاٹا کے نقصان کی وجہ سے ہم آپ کی تبدیلی نافذنہیں کرسکتے.\n<em>چونکہ{{SITENAME}}نے نامکملHTMLکوفعال کررکھاہے,اس لئےنمائش کوجاوااسکرپٹ کےحملوں سےحفاظت کےلئےپوشیدہ کردیاگیاہے.</em>\n<strong>اگرتبدیلی کی یہ جدوجہدقانونی ہےتوبرائےمہربانی دوبارہ کوشش کریں.<strong>\nاگراس کےبعدبھی کام نہ کرے تو[[Special:UserLogout|logging out]]لاگ آؤٹ ہوکردوبارہ لاگ ان کیجیے.اورجانچ کیجیے کہ آپ کابراؤزراس سائٹ کےکوکیزکی اجأزت دیتاہےیانہیں.",
        "token_suffix_mismatch": "<strong>آپ کی ترمیم رد کردی گئی ہے کیونکہ آپ کے اسامی نے ٹوکن ترمیم میں رموزو اوقاف علامتوں کی دھجیاں اڑا دی تھیں۔</strong>\n\nترمیم صفحے کے متن میں خرابی سے روکنے کے لیے رد کی گئی ہے۔\nیہ بعض دفعہ تب ہوتا ہے جب آپ buggy ویب پر مبنی نامعلوم پروکسی سروس کا استعمال کررہے ہوں۔",
        "edit_form_incomplete": "<strong>خانہ ترمیم سے کچھ حصے سرور تک نہیں پہنچ سکے ہیں؛ براہ کرم اپنی ترامیم کو دوبارہ جانچ لیں کہ آیا وہ برقرار ہیں یا نہیں اور دوبارہ کوشش کریں۔</strong>",
-       "editing": "آپ \"$1\" میں ترمیم کر رہے ہیں۔",
+       "editing": "آپ «$1» میں ترمیم کر رہے ہیں",
        "creating": "زیر تخلیق $1",
        "editingsection": "«$1» کے قطعہ کی ترمیم",
-       "editingcomment": "زیرترمیم $1 (نیا قطعہ)",
+       "editingcomment": "زیر ترمیم $1 (نیا قطعہ)",
        "editconflict": "تنازع ترمیم:$1",
        "explainconflict": "آپکی تدوین شروع ہونے کے بعد شاید کسی نے یہ صفحہ تبدیل کردیا ہے.\nبالائی خانۂ متن میں صفحہ کا موجودہ مواد ہے.\nآپ کی تبدیلیاں نچلے متن خانہ میں دکھائی گئی ہیں.\nآپ کو اپنی تبدیلیاں موجودہ متن میں ضم کرنا ہوں گی.\n\"محفوظ\" کا بٹن ٹک کرنے سے '''صرف''' بالائی متن محفوظ ہوگا.",
        "yourtext": "آپ کی تحریر",
        "longpageerror": "<strong>خطا: آپ کا درج کردہ متن {{PLURAL:$1|ایک کلو بائٹ|$1 کلو بائٹز}} لمبا ہے، جو کم سے کم {{PLURAL:$2|ایک کلو بائٹ|$2 کلو بائٹز}} سے زیادہ ہے۔</strong>\nاسے محفوظ نہیں کیا جاسکتا۔",
        "readonlywarning": "<strong>انتباہ: انتظامی نگہداشت کی خاطر ڈیٹابیس کو مقفل کر دیا گیا ہے، لہذا اس وقت آپ اپنی ترامیم کو محفوظ نہیں کر سکتے۔</strong>\nآپ اپنی تحریر کو کسی ٹیکسٹ فائل میں محفوظ کر سکتے ہیں تاکہ وہ ضائع نہ ہو اور آئندہ اسے استعمال کیا جا سکے۔\n\nانتظامیہ کی جانب سے مقفل کرنے کی حسب ذیل وجہ بیان کی گئی ہے:\n\n$1",
        "protectedpagewarning": "<strong>انتباہ: اس صفحہ میں ترمیم کاری کو مقفل کر دیا گیا ہے اور محض انتظامی اختیارات کے حامل صارفین ہی اس میں ترمیم کر سکتے ہیں۔</strong>\nحوالہ کے لیے ذیل میں نوشتہ جاتی اندراج فراہم کیا گیا ہے:",
-       "semiprotectedpagewarning": "<strong>اطÙ\84اع:</strong> Ø§Ø³ ØµÙ\81Ø­Û\81 Ú©Ù\88 Ù\85Ø­Ù\81Ù\88ظ Ú©Ø± Ø¯Û\8cا Ú¯Û\8cا Û\81Û\92Ø\8c Ù\84Û\81ذا Ø§Ø¨ Ø§Ø³ Ù\85Û\8cÚº Ù\85حض Ø§Ù\86دراج شدہ صارفین ہی ترمیم کر سکتے ہیں۔\nحوالہ کے لیے ذیل میں نوشتہ کا تازہ ترین اندراج درج ہے:",
+       "semiprotectedpagewarning": "<strong>اطÙ\84اع:</strong> Ø§Ø³ ØµÙ\81Ø­Û\81 Ú©Ù\88 Ù\85Ø­Ù\81Ù\88ظ Ú©Ø± Ø¯Û\8cا Ú¯Û\8cا Û\81Û\92Ø\8c Ù\84Û\81ذا Ø§Ø¨ Ø§Ø³ Ù\85Û\8cÚº Ù\85حض Ø®Ù\88د ØªÙ\88Ø«Û\8cÙ\82 شدہ صارفین ہی ترمیم کر سکتے ہیں۔\nحوالہ کے لیے ذیل میں نوشتہ کا تازہ ترین اندراج درج ہے:",
        "cascadeprotectedwarning": "<strong>انتباہ:</strong> اس صفحہ میں ترمیم کاری کو محفوظ کر دیا گیا ہے اور محض [[Special:ListGroupRights|انتظامی اختیارات]] کے حامل صارفین ہی اس میں ترمیم کر سکتے ہیں۔ اسے محفوظ کرنے کی وجہ یہ ہے کہ پیش نظر صفحہ درج ذیل محفوظ {{PLURAL:$1|صفحہ|صفحات}} کی آبشاری حفاظت میں شامل ہے:",
        "titleprotectedwarning": "<strong>انتباہ: اس صفحہ کو محفوظ کر دیا گیا ہے، چنانچہ اسے تخلیق کرنے کے لیے [[Special:ListGroupRights|خصوصی اختیارات]] درکار ہونگے۔</strong>\nحوالہ کے لیے ذیل میں نوشتہ کا تازہ ترین اندراج موجود ہے:",
        "templatesused": "اِس صفحہ پر مستعمل {{PLURAL:$1|سانچہ|سانچے}}:",
        "permissionserrorstext": "درج ذیل {{PLURAL:$1|وجہ|وجوہات}} کی بنا پر آپ کو ایسا کرنے کی اجازت نہیں ہے:",
        "permissionserrorstext-withaction": "درج ذیل {{PLURAL:$1|وجہ|وجوہات}} کی بنا پر آپ کو $2  کی اجازت نہیں ہے:",
        "contentmodelediterror": "آپ اس نسخے میں ترمیم نہیں کر سکتے کیونکہ اس کے مواد کا ماڈل ‌‌<code>$1</code> ہے جو اس صفحہ کے مواد کے موجودہ ماڈل <code>$2</code> سے مختلف ہے۔",
-       "recreate-moveddeleted-warn": "''' انتباہ: آپ ایک گزشتہ حذف شدہ صفحہ دوبارہ تخلیق کررہے ہیں. '''\n\nآپ کو اِس بات پر غور کرنا چاہئے کہ آیا اِس صفحہ کی تدوین جاری رکھنا موزوں ہے یا نہیں.\nصفحہ کا نوشتۂ حذف شدگی و منتقلی یہاں سہولت کی خاطر مہیّا کیا جارہا ہے:",
+       "recreate-moveddeleted-warn": "<strong>انتباہ: آپ ایک گزشتہ حذف شدہ صفحہ دوبارہ تخلیق کر رہے ہیں۔</strong>\n\nآپ کو اِس بات پر غور کرنا چاہیے کہ آیا اِس صفحہ کی تدوین جاری رکھنا موزوں ہے یا نہیں۔\nصفحہ کا نوشتۂ حذف شدگی و منتقلی یہاں سہولت کی خاطر مہیّا کیا جا رہا ہے:",
        "moveddeleted-notice": "اس صفحہ کو حذف کر دیا گیا ہے۔\nحوالہ کے لیے ذیل میں اس صفحہ کا نوشتہ حذف شدگی اور نوشتہ منتقلی درج ہے۔",
        "moveddeleted-notice-recent": "معذرت، اس صفحہ کو حال ہی میں حذف کیا گیا ہے (گزشتہ چوبیس گھنٹوں میں)۔\nحوالہ کے لیے ذیل میں اس صفحہ کا نوشتہ حذف اور نوشتہ منتقلی موجود ہے۔",
-       "log-fulllog": "پورا نوشتہ دیکھئے",
+       "log-fulllog": "پورا نوشتہ دیکھیے",
        "edit-hook-aborted": "کسی رکاوٹ کی وجہ سے ترمیم کاری منسوخ کر دی گئی ہے۔\nاور کوئی وضاحت نہیں دی گئی۔",
        "edit-gone-missing": "صفحہ تجدید نہیں کیا جاسکتا.\nلگتا ہے یہ حذف ہوچکا ہے.",
        "edit-conflict": "تنازعۂ تدوین.",
        "revdelete-hide-image": "فائل کے مشمولات چھپائیں",
        "revdelete-hide-name": "ہدف اور پیرامیٹرز کو چھپائیں",
        "revdelete-hide-comment": "ترمیمی تبصرہ چھپاؤ",
-       "revdelete-hide-user": "ترمیم کار کا اسمِ صارف / آئی.پی پتہ چُھپاؤ",
+       "revdelete-hide-user": "ترمیم کنندہ کا صارف نام/آئی پی پتہ چھپائیں",
        "revdelete-hide-restricted": "منتظمین اور دیگر صارفین سے معلومات کو پوشیدہ کریں",
        "revdelete-radio-same": "(تبدیل مت کرو)",
        "revdelete-radio-set": "پوشیدہ",
        "prefs-email": "برقی خط کے اختیارات",
        "prefs-rendering": "ظاہریت",
        "saveprefs": "محفوظ",
-       "restoreprefs": "تمام ابتدائی ترتیبات کو بحال کریں",
+       "restoreprefs": "تمام ابتدائی ترتیبات (تمام خانوں میں) کو بحال کریں",
        "prefs-editing": "ترمیم کاری",
        "searchresultshead": "تلاش",
        "stub-threshold": "نامکمل ربط کے فارمیٹ کی حد ($1):",
        "stub-threshold-disabled": "غیر فعال",
        "recentchangesdays": "حالیہ تبدیلیوں میں دکھائے جانے والے ایّام:",
        "recentchangesdays-max": "زیادہ سے زیادہ $1 {{PLURAL:$1|دن}}",
-       "recentchangescount": "دکھائی جانے والی ترامیم کی تعداد:",
-       "prefs-help-recentchangescount": "اÙ\90س Ù\85Û\8cÚº Ø­Ø§Ù\84Û\8cÛ\81 ØªØ¨Ø¯Û\8cÙ\84Û\8cاںØ\8c ØªØ§Ø±Û\8cØ®Ú\86Û\92 Ø§Ù\88ر Ù\86Ù\88شتÛ\81 Ø¬Ø§Øª Ø´Ø§Ù\85Ù\84 Û\81Û\8cÚºÛ\94",
+       "recentchangescount": "حاÙ\84Û\8cÛ\81 ØªØ¨Ø¯Û\8cÙ\84Û\8cÙ\88ÚºØ\8c ØªØ§Ø±Û\8cØ®Ú\86Ù\88Úº Ø§Ù\88ر Ù\86Ù\88شتÙ\88Úº Ù\85Û\8cÚº Ø¯Ú©Ú¾Ø§Ø¦Û\8c Ø¬Ø§Ù\86Û\92 Ù\88اÙ\84Û\8c ØªØ±Ø§Ù\85Û\8cÙ\85 Ú©Û\8c ØªØ¹Ø¯Ø§Ø¯:",
+       "prefs-help-recentchangescount": "زÛ\8cادÛ\81 Ø³Û\92 Ø²Û\8cادÛ\81 ØªØ¹Ø¯Ø§Ø¯: 1000",
        "prefs-help-watchlist-token2": "یہ آپ کی زیر نظر فہرست کے ویب فیڈ کی خفیہ کلید ہے۔\nاسے خفیہ رکھیں، تاکہ کوئی دوسرا شخص آپ کی زیر نظر فہرست نہ دیکھ سکے۔\nاگر آپ کو کلید تبدیل کرنی ہو تو [[Special:ResetTokens|یہاں کلک کریں]]۔",
        "savedprefs": "آپ کی ترجیحات محفوظ ہوگئیں۔",
        "savedrights": "{{GENDER:$1|$1}} کے اختیارات محفوظ ہو گئے۔",
        "prefs-files": "فائلیں",
        "prefs-custom-css": "شخصی سی ایس ایس",
        "prefs-custom-js": "شخصی جاوا اسکرپٹ",
-       "prefs-common-config": "جملہ پوشاکوں کے لیے مشترکہ سی ایس ایس/جاوا اسکرپٹ:",
+       "prefs-common-config": "جملہ پوشاکوں کے لیے مشترکہ سی ایس ایس/جے سن/جاوا اسکرپٹ:",
        "prefs-reset-intro": "آپ اس صفحہ کے ذریعہ اپنی موجودہ ترجیحات کو سائٹ کی ابتدائی ترتیبات کے مطابق ڈھال سکتے ہیں۔\nلیکن اسے واپس نہیں پھیرا جا سکتا۔",
        "prefs-emailconfirm-label": "برقی خط کی تصدیق:",
        "youremail": "برقی خط:",
        "yournick": "شخصی دستخط:",
        "prefs-help-signature": "تبادلۂ خیال صفحات پر تبصرہ تحریر کرنے کے بعد یہ \"<nowiki>~~~~</nowiki>\" علامتیں درج کرنی چاہئیں، یہ علامتیں از خود آپ کے دستخط اور وقت میں تبدیل ہو جائیں گی۔",
        "badsig": "ناقص خام دستخط.\nHTML tags جانچئے.",
-       "badsiglength": "آپ کا دستخط کافی طویل ہے.\nیہ $1 {{PLURAL:$1|حرف|حروف}} سے زیادہ نہیں ہونا چاہئے.",
+       "badsiglength": "آپ کا دستخط کافی طویل ہے۔\nیہ $1 {{PLURAL:$1|حرف|حروف}} سے زیادہ نہیں ہونا چاہیے۔",
        "yourgender": "جنس:",
        "gender-unknown": "اگر ممکن ہو تو آپ کے تذکرہ کے وقت سافٹ ویئر غیر جانبدار جنسی الفاظ استعمال کرے گا",
        "gender-male": "مرد",
        "prefs-dateformat": "تاریخ کی ترتیب",
        "prefs-timeoffset": "وقت کی ترتیب",
        "prefs-advancedediting": "اعلی اختیارات",
+       "prefs-developertools": "آلات ترقی دہندہ",
        "prefs-editor": "خانہ ترمیم",
        "prefs-preview": "نمائش",
        "prefs-advancedrc": "اضافی اختیارات",
        "prefs-tabs-navigation-hint": "نکتہ: مختلف خانوں میں جانے کے لیے آپ دائیں اور بائیں کی جہت نما کلیدیں استعمال کر سکتے ہیں۔",
        "userrights": "حقوق صارف",
        "userrights-lookup-user": "صارف کا انتخاب کریں",
-       "userrights-user-editname": "کوئی اسم‌صارف داخل کیجئے:",
+       "userrights-user-editname": "صارف نام درج کیجیے:",
        "editusergroup": "حلقہ ہائے صارف دکھائیں",
        "editinguser": "{{GENDER:$1|صارف}} <strong>[[User:$1|$1]]</strong> $2 کے اختیارات میں تبدیلی",
        "viewinguserrights": "{{GENDER:$1|صارف}} <strong>[[User:$1|$1]]</strong> $2 کے اختیارات میں تبدیلی",
        "grant-createaccount": "کھاتہ سازی",
        "grant-createeditmovepage": "تخلیق، ترمیم و منتقلی صفحات",
        "grant-delete": "صفحات، اندراجات نوشتہ اور نسخوں کی حذف شدگی",
-       "grant-editinterface": "صارف کی سی ایس ایس/جاوا اسکرپٹ اور میڈیاویکی نام فضا میں ترمیم",
-       "grant-editmycssjs": "اپنی سی ایس ایس/جاوا اسکرپٹ میں ترمیم",
+       "grant-editinterface": "صارف کی سی ایس ایس/جے سن/جاوا اسکرپٹ اور میڈیاویکی نام فضا میں ترمیم",
+       "grant-editmycssjs": "اپنی سی ایس ایس/جے سن/جاوا اسکرپٹ میں ترمیم",
        "grant-editmyoptions": "اپنی ترجیحات میں ترمیم",
        "grant-editmywatchlist": "اپنی زیرنظر فہرست میں ترمیم",
        "grant-editpage": "موجودہ صفحات میں ترمیم",
        "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",
        "rcfilters-savedqueries-rename": "نام کی تبدیلی",
        "rcfilters-savedqueries-setdefault": "طے شدہ طور پر محفوظ کریں",
        "rcfilters-savedqueries-unsetdefault": "طے شدہ طور پر ہٹائیں",
-       "rcfilters-savedqueries-remove": "ہٹائیں",
+       "rcfilters-savedqueries-remove": "حذف",
        "rcfilters-savedqueries-new-name-label": "نام",
        "rcfilters-savedqueries-new-name-placeholder": "فلٹر کا مقصد واضح کریں",
        "rcfilters-savedqueries-apply-label": "فلٹر بنائیں",
        "rcfilters-empty-filter": "کوئی فلٹر فعال نہیں ہے چنانچہ تمام شراکتیں دکھائی جا رہی ہیں۔",
        "rcfilters-filterlist-title": "فلٹروں کی فہرست",
        "rcfilters-filterlist-whatsthis": "یہ کام کیسے کرتے ہیں؟",
-       "rcfilters-filterlist-feedbacklink": "ان (نئے) فلٹر آلات کے متعلق ہمیں اپنے تاثرات سے آگاہ کریں",
+       "rcfilters-filterlist-feedbacklink": "ان فلٹر آلات کے متعلق ہمیں اپنے تاثرات سے آگاہ کریں",
        "rcfilters-highlightbutton-title": "نتائج کو نمایاں کریں",
        "rcfilters-highlightmenu-title": "رنگ پسند کریں",
        "rcfilters-highlightmenu-help": "اس خاصیت کو نمایاں کرنے کے لیے کوئی رنگ پسند کریں",
        "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": "ترامیم جنہیں صارفین نے معمولی قرار دیا",
        "rclinks": "آخری $2 روز میں ہونے والی $1 تبدیلیوں کا مشاہدہ کریں",
        "diff": "فرق",
        "hist": "تاریخچہ",
-       "hide": "Ú\86Ú¾Ù\80پائÛ\8cÚº",
+       "hide": "چھپائیں",
        "show": "دکھائیں",
        "minoreditletter": "م",
        "newpageletter": "نیا ..",
        "recentchangeslinked-feed": "متعلقہ تبدیلیاں",
        "recentchangeslinked-toolbox": "متعلقہ تبدیلیاں",
        "recentchangeslinked-title": "\"$1\" سے متعلقہ تبدیلیاں",
-       "recentchangeslinked-summary": "یہ ان تبدیلیوں کی فہرست ہے جو حال ہی میں کسی مخصوص صفحہ سے مربوط صفحات (یا مخصوص زمرہ کے اراکین) میں کی گئی ہیں۔\n\n[[Special:Watchlist|آپ کی زیر نظر فہرست]] میں یہ صفحات <strong>جلی</strong نظر آئیں گےـ",
+       "recentchangeslinked-summary": "یہ ان تبدیلیوں کی فہرست ہے جو حال ہی میں کسی مخصوص صفحہ سے مربوط صفحات (یا مخصوص زمرہ کے اراکین) میں کی گئی ہیں۔\n\n[[Special:Watchlist|آپ کی زیر نظر فہرست]] میں یہ صفحات <strong>جلی</strong> نظر آئیں گےـ",
        "recentchangeslinked-page": "صفحہ کا نام:",
        "recentchangeslinked-to": "اس کی بجائے درج کردہ صفحہ سے مربوط صفحات کی تبدیلیاں دکھائیں",
        "recentchanges-page-added-to-category": "[[:$1]] کو زمرہ میں شامل کیا گیا",
        "enotif_subject_moved": "{{SITENAME}} میں صفحہ $1 کو $2 نے {{GENDER:$2|منتقل کیا}}",
        "enotif_subject_restored": "{{SITENAME}} میں صفحہ $1 کو $2 نے {{GENDER:$2|بحال کیا}}",
        "enotif_subject_changed": "{{SITENAME}} کے صفحہ $1 میں $2 نے {{GENDER:$2|تبدیلی کی}}",
-       "enotif_body_intro_deleted": "{{SITENAME}} میں صفحہ $1 کو بتاریخ $PAGEEDITDATE صارف $2 نے {{GENDER:$2|حذف کر دیا}} ہے، ملاحظہ فرمائیں $3۔",
+       "enotif_body_intro_deleted": "{{SITENAME}} میں صفحہ $1 کو بتاریخ $PAGEEDITDATE صارف $2 نے {{GENDER:$2|حذف کر دیا}} ہے، ملاحظہ فرمائیں $3 ۔",
        "enotif_body_intro_created": "{{SITENAME}} میں صفحہ $1 کو بتاریخ $PAGEEDITDATE صارف $2 نے {{GENDER:$2|تخلیق کیا}}، موجودہ نسخہ دیکھنے کے لیے $3 ملاحظہ فرمائیں۔",
        "enotif_body_intro_moved": "{{SITENAME}} میں صفحہ $1 کو بتاریخ $PAGEEDITDATE صارف $2 نے {{GENDER:$2|منتقل کر دیا}} ہے، موجودہ نسخہ دیکھنے کے لیے $3 ملاحظہ فرمائیں۔",
        "enotif_body_intro_restored": "{{SITENAME}} میں صفحہ $1 کو بتاریخ $PAGEEDITDATE صارف $2 نے {{GENDER:$2|بحال کیا}}، موجودہ نسخہ دیکھنے کے لیے $3 ملاحظہ فرمائیں۔",
        "deletepage": "حذف کریں",
        "confirm": "یقین",
        "excontent": "'$1':مواد تھا",
-       "excontentauthor": "حذف شدہ مواد: «$1» اور صرف «[[Special:Contributions/$2|$2]]» ([[User talk:$2|تبادلۂ خیال]]) نے اس میں ترمیم کی",
+       "excontentauthor": "مواد «$1» تھا اور صرف «[[Special:Contributions/$2|$2]]» ([[User talk:$2|تبادلۂ خیال]]) نے اس میں ترمیم کی تھی",
        "exbeforeblank": "خالی کرنے سے قبل موجود مواد: «$1»",
        "delete-confirm": "حذف ''$1''",
        "delete-legend": "حذف",
        "rollback-success": "{{GENDER:$3|$1}} کی ترامیم واپس پھیر دی گئیں؛\nصفحہ واپس {{GENDER:$4|$2}} کی آخری ترمیم کی جانب منتقل کر دیا گیا۔",
        "rollback-success-notify": "$1 کی ترامیم واپس پھیر دی گئیں؛\nصفحہ واپس $2 کی آخری ترمیم کی جانب منتقل کر دیا گیا۔ [$3 تبدیلیاں دکھائیں]",
        "sessionfailure-title": "نشست میں خامی",
+       "sessionfailure": "معلوم ہوتا ہے کہ آپ کی لاگ ان نشست میں کوئی مسئلہ درپیش ہے؛\nاس صورت میں نشست کے اغوا کا خدشہ ہوتا ہے، چنانچہ پیش بندی کے طور پر آپ کے اقدام کو مسترد کر دیا گیا ہے۔\nبراہ کرم دوبارہ کوشش کریں۔",
        "changecontentmodel": "صفحہ کے مواد کے ماڈل میں تبدیلی کریں",
        "changecontentmodel-legend": "مواد کے ماڈل کو تبدیل کریں",
        "changecontentmodel-title-label": "صفحہ کا عنوان",
        "protectedarticle": "\"[[$1]]\" کومحفوظ کردیا",
        "modifiedarticleprotection": "«[[$1]]» کا درجہ حفاظت تبدیل کیا",
        "unprotectedarticle": "«[[$1]]» کو غیر محفوظ کیا",
-       "movedarticleprotection": "نے \"[[$2]]\" کا درجہ حفاظت \"[[$1]]\" کی جانب منتقل کیا",
+       "movedarticleprotection": "نے «[[$2]]» کا درجہ حفاظت «[[$1]]» کی جانب منتقل کیا",
        "protectedarticle-comment": "«[[$1]]» کو {{GENDER:$2|محفوظ کیا}}",
        "modifiedarticleprotection-comment": "«[[$1]]» کا {{GENDER:$2|درجہ حفاظت تبدیل کیا}}",
        "unprotectedarticle-comment": "«[[$1]]» کو {{GENDER:$2|غیر محفوظ کیا}}",
        "uctop": "(موجودہ نسخہ)",
        "month": "مہینہ (اور اُس سے قبل):",
        "year": "سال (اور اُس سے قبل):",
+       "date": "تاریخ سے (اور اس سے قبل)",
        "sp-contributions-newbies": "محض جدید صارفین کی شراکتیں دکھائیں",
        "sp-contributions-newbies-sub": "جدید صارفین کے",
        "sp-contributions-newbies-title": "جدید صارفین کی شراکتیں",
        "whatlinkshere": "مربوط صفحات",
        "whatlinkshere-title": "«$1» سے مربوط صفحات",
        "whatlinkshere-page": "صفحہ:",
-       "linkshere-2": "<strong>$1</strong> سے درج ذیل صفحات مربوط ہیں:",
-       "nolinkshere-2": "<strong>$1</strong> سے کوئی صفحہ مربوط نہیں ہے۔",
-       "nolinkshere-ns-2": "منتخب نام فضا میں <strong>$1</strong> سے مربوط کوئی صفحہ نہیں ہے۔",
+       "linkshere": "<strong>$1</strong> سے درج ذیل صفحات مربوط ہیں:",
+       "nolinkshere": "<strong>$1</strong> سے کوئی صفحہ مربوط نہیں ہے۔",
+       "nolinkshere-ns": "منتخب نام فضا میں <strong>$2</strong> سے مربوط کوئی صفحہ نہیں ہے۔",
        "isredirect": "رجوع مکرر صفحہ",
        "istemplate": "شامل شدہ",
        "isimage": "فائل کا ربط",
        "ipaddressorusername": "آئی پی پتہ یا صارف نام:",
        "ipbexpiry": "وقت اختتام:",
        "ipbreason": "وجہ:",
-       "ipbreason-dropdown": "* عمومی وجوہات پابندی\n** غلط معلومات کا اندراج\n** صفحات سے متن کا مٹانا\n** بیرونی روابط میں بے کار روابط کی فاضل کاری\n** صفحات میں لغو چیزوں کا اندراج\n** بدتمیزی/بداخلاقی\n** متعدد کھاتوں کا استعمال\n** ناقابلِ قبول اسمِ صارف",
+       "ipbreason-dropdown": "* پابندی کی عام وجوہات\n** غلط معلومات کا اندراج\n** صفحات سے متن کا مٹانا\n** بیرونی روابط میں بے کار روابط کی فاضل کاری\n** صفحات میں لغو چیزوں کا اندراج\n** بدتمیزی/بداخلاقی\n** متعدد کھاتوں کا استعمال\n** ناقابلِ قبول صارف نام",
        "ipb-hardblock": "اس آئی پی پتے سے داخل شدہ صارفین کو ترمیم کاری سے باز رکھیں",
        "ipbcreateaccount": "کھاتہ سازی سے باز رکھیں",
        "ipbemailban": "برقی خط بھیجنے سے باز رکھیں",
        "fix-double-redirects": "اصل عنوان کی جانب موجود تمام رجوع مکررات کو بھی تازہ کریں",
        "move-leave-redirect": "پیچھے رجوع مکرر بنائیں",
        "protectedpagemovewarning": "<strong>انتباہ:</strong> اس صفحہ کو محفوظ کر دیا گیا ہے اور اب محض منتظمین ہی اسے منتقل کر سکتے ہیں۔\nحوالہ کے لیے نوشتہ کا جدید اندراج ذیل میں درج ہے:",
-       "semiprotectedpagemovewarning": "<strong>اطلاع:</strong> یہ صفحہ نیم محفوظ ہے اور اسے محض مندرج صارفین ہی منتقل کر سکتے ہیں۔\nذیل میں حوالہ کے لیے نوشتہ کا تازہ ترین اندراج موجود ہے:",
+       "semiprotectedpagemovewarning": "<strong>اطلاع:</strong> یہ صفحہ نیم محفوظ ہے اور اسے محض خود توثیق شدہ صارفین ہی منتقل کر سکتے ہیں۔\nذیل میں حوالہ کے لیے نوشتہ کا تازہ ترین اندراج موجود ہے:",
        "move-over-sharedrepo": "[[:$1]] ایک مشترکہ ذخیرے میں موجود ہے۔ چنانچہ اس عنوان کی جانب کسی فائل کو منتقل کرنے پر مشترکہ فائل منسوخ ہو جائے گی۔",
        "file-exists-sharedrepo": "فائل کا منتخب کردہ نام ایک مشترکہ ذخیرے میں پہلے ہی سے زیر استعمال ہے۔\nبراہ کرم کوئی دوسرا نام درج کریں۔",
        "export": "برآمد صفحات",
        "tooltip-recreate": "حذف شدہ صفحہ ہونے کے باوجود اسے دوبارہ تخلیق کریں",
        "tooltip-upload": "اپلوڈ کریں",
        "tooltip-rollback": "پچھلے صارف کی کی گئی اِس صفحے پر استرجع شدہ ترامیم کو ایک کلِک میں واپس کریں",
-       "tooltip-undo": "''استرجع'' اس ترمیم کو پچھلی ترمیم کے جانب واپس کردیگا اور نمائشی انداز میں خانہ ترمیم کھول دے گا۔ آپ مختصراً سبب بیان کرنے کے بھی مجاز ہونگے۔",
+       "tooltip-undo": "«استرجع» اس ترمیم کو پچھلی ترمیم کے جانب واپس کر دے گا اور نمائشی انداز میں خانہ ترمیم کھول دے گا۔ آپ مختصراً سبب بیان کرنے کے بھی مجاز ہوں گے۔",
        "tooltip-preferences-save": "ترجیحات محفوظ کریں",
        "tooltip-summary": "مختصر خلاصہ درج کریں",
        "common.css": "body,\ntextarea {\n    font-family: Amiri;\n}",
        "markedaspatrollederrornotify": "بطور مراجعت نشان زد نہیں کیا جا سکا۔",
        "patrol-log-page": "نوشتہ مراجعت",
        "patrol-log-header": "ذیل میں مراجعت شدہ ترامیم کا نوشتہ ہے۔",
-       "log-show-hide-patrol": "$1 نوشتہ مراجعت",
-       "log-show-hide-tag": "$1 نوشتہ ٹیگ",
        "confirm-markpatrolled-button": "ٹھیک ہے",
        "confirm-markpatrolled-top": "$2 کے نسخہ $3 کو بطور مراجعت شدہ نشان زد کریں؟",
        "deletedrevision": "حذف شدہ پرانی ترمیم $1۔",
        "table_pager_limit_label": "فی صفحہ اندراج:",
        "table_pager_limit_submit": "چلیں",
        "table_pager_empty": "کوئی نتیجہ برآمد نہیں ہوا",
-       "autosumm-blank": "صفحہ خالی کیا",
+       "autosumm-blank": "صفحو خالي ڪيو",
        "autosumm-replace": "\"$1\" سے مواد کی تبدیلی",
        "autoredircomment": "[[$1]] سے رجوع مکرر",
        "autosumm-removed-redirect": "[[$1]] سے رجوع مکرر ہٹایا",
        "specialpages-group-media": "میڈیا رپورٹیں اور اپلوڈ کردہ",
        "specialpages-group-users": "صارفین اور اختیارات",
        "specialpages-group-highuse": "کثیر مستعمل صفحات",
-       "specialpages-group-pages": "فہارست صفحات",
+       "specialpages-group-pages": "صفحات کی فہرستیں",
        "specialpages-group-pagetools": "آلات صفحہ",
        "specialpages-group-wiki": "ڈیٹا اور آلات",
        "specialpages-group-redirects": "رجوع مکرر کے حامل خصوصی صفحات",
index 71afccf..2b71087 100644 (file)
        "whatlinkshere": "Bogʻliq sahifalar",
        "whatlinkshere-title": "„$1“ga bogʻlangan sahifalar",
        "whatlinkshere-page": "Sahifa:",
-       "linkshere-2": "Quyidagi sahifalar '''$1''' sahifasiga bogʻlangan:",
-       "nolinkshere-2": "'''$1''' sahifasiga hech qaysi sahifa bog‘lanmagan.",
-       "nolinkshere-ns-2": "Tanlangan nomfazoda '''$1'''ga bog‘langan sahifalar mavjud emas.",
+       "linkshere": "Quyidagi sahifalar '''$1''' sahifasiga bogʻlangan:",
+       "nolinkshere": "'''$1''' sahifasiga hech qaysi sahifa bog‘lanmagan.",
+       "nolinkshere-ns": "Tanlangan nomfazoda '''$2'''ga bog‘langan sahifalar mavjud emas.",
        "isredirect": "yoʻnaltiruvchi sahifa",
        "istemplate": "qoʻshimcha",
        "isimage": "faylli havola",
index a8e9b38..8a52c64 100644 (file)
        "actionthrottled": "Asion ritardà",
        "actionthrottledtext": "Come misura de sicuresa contro e o spam, l'esecusion de alcune asion e a xè limità a on numaro masimo de volte en on determinà periodo de tenpo, limite che en questo caso xè sta superà. Se prega de riprovare tra qualche minuto.",
        "protectedpagetext": "Sta pàjina ła xe stà proteta de modo che nisun posa canbiarla o far altre operasion.",
-       "viewsourcetext": "Se pole vardar e copiar el testo de sta pagina:",
+       "viewsourcetext": "Te poli vardar e copiar el testo de sta pagina.",
        "viewyourtext": "Xè posibile vedàre e copiare el codexe sorzente de le '''to modifighe''' a sta pajina:",
        "protectedinterface": "Sta pàjina ła gà drento un testo de l'interfacia utente del software de sto sito, quindi la xe proteta parché nisuni ła strusie.\nPar xontar o modifegar tradusion par tute łe wiki doparar [https://translatewiki.net/ translatewiki.net], el projeto de locałixasion de MediaWiki.",
        "editinginterface": "'''Ocio:''' El testo de sta pàjina el fa parte de l'interfacia utente del sito. Tute łe modifeghe aportae a sta pajina se riflete so i mesaji visuałixà par tuti i utenti so sta wiki.\nPar xontare o modifegar łe tradusion vałide so tute łe wiki, considera ła posibiłità de doparar [https://translatewiki.net/wiki/Main_Page?setlang=vec translatewiki.net], el projeto MediaWiki par ła localixasion.",
        "permissionserrorstext": "Nò se dispone dei parmesi nesessari ad eseguir l'asion richiesta, par {{PLURAL:$1|el seguente motivo|i seguenti motivi}}:",
        "permissionserrorstext-withaction": "Nò se dispone dei parmesi nesesari par $2, par {{PLURAL:$1|el seguente modivo|i seguenti modivi}}:",
        "recreate-moveddeleted-warn": "'''Ocio: te stè par ricrear na pagina zà scancelà precedentemente.'''\n\nPar piaser assicùrete che sia dal bon el caso de 'ndar vanti a modificar sta pagina.\nL'elenco de i relativi spostamenti e scancelazion el vien riportà qua de seguito par comodità:",
-       "moveddeleted-notice": "Sta pagina la xe stà scancelà.\nL'elenco dei so spostamenti e scancelassion el vien riportà qua soto par informassion.",
+       "moveddeleted-notice": "Sta pagina la xe stà scancelà.\nL'elenco dei so spostamenti, protesion e scancelassion te lo cati qua soto par informassion.",
        "log-fulllog": "Varda registro conpleto",
        "edit-hook-aborted": "Modifica abortìa da parte de l'hook.\nNo xe stà dà nissuna spiegazion in merito.",
        "edit-gone-missing": "No se riesse a agiornar la pàxena.\nPararìa che la sìpia stà scancelà.",
        "page_first": "prima",
        "page_last": "ultima",
        "histlegend": "Confronto tra version: segna le casèle de le version che te voli confrontar e struca Invio o el boton in fondo.\n\nLegenda: '''({{int:cur}})''' = difarense co l'ultima version, '''({{int:last}})''' = difarense co la version subito prima, '''{{int:minoreditletter}}''' = canbiamento picenin",
-       "history-fieldset-title": "Ruma in te la storia",
+       "history-fieldset-title": "Ruma in te le revision",
        "history-show-deleted": "Solo quei scancelà",
        "histfirst": "pi vecia",
        "histlast": "pi nova",
        "editundo": "tira indrìo",
        "diff-empty": "(Nissuna difarensa)",
        "diff-multi-sameuser": "({{PLURAL:$1|Una revision intermedia|$1 revision intermedie}} del stesso utente mia mostrà)",
+       "diff-multi-otherusers": "({{PLURAL:$1|Na version intermedia|$1 version intermedie}} de {{PLURAL:$2|n'altro utente|$2 utenti}} mia mostrà)",
        "diff-multi-manyusers": "({{PLURAL:$1|Una revision intermedia|$1 revision intermedie}} de pi de {{PLURAL:$2|un utente|$2 utenti}} mia mostrà)",
        "difference-missing-revision": "{{PLURAL:$2|Na version|$2 version}} de sta difarensa ($1) {{PLURAL:$2|nó ła xe sta trovà|nó łe xe stae trovae}}.\n\nCuesto se verifega de sołito seguendo un ligamente vecio de un dif a na pàjina scansełà.\nI detaji i pol esar catai inte'l [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} registro de łe scansełasion].",
        "searchresults": "Risultati de la riserca",
        "search-redirect": "(rimando da $1)",
        "search-section": "(sesion $1)",
        "search-category": "(categoria $1)",
+       "search-file-match": "(catà drento el file)",
        "search-suggest": "Sercavito forsi: $1",
        "search-interwiki-caption": "Projeti fradei",
        "search-interwiki-default": "Risultati da $1:",
        "recentchanges": "Ultimi canbiamenti",
        "recentchanges-legend": "Prefarense par i ultimi canbiamenti",
        "recentchanges-summary": "Qua se vede i ultimi canbiamenti fati a sto sito.",
+       "recentchanges-noresult": "No gò catà nissuna modifica in sto periodo co sti criteri de riserca.",
        "recentchanges-feed-description": "Tien tracia dei ultimi canbiamenti fati a sto sito",
        "recentchanges-label-newpage": "Sta modifica la ga creà na pagina nova",
        "recentchanges-label-minor": "Sto qua el xe un canbiamento picenin",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (varda anca [[Special:NewPages|l'elenco de le pagine nove]])",
        "rcfilters-filter-reviewstatus-manual-label": "Verificà manualmente",
        "rcfilters-filter-reviewstatus-auto-label": "Verificà en automatico.",
-       "rcnotefrom": "Qui di seguito sono elencate le modifiche da '''$2''' (fino a '''$1''').",
+       "rcnotefrom": "Qua de soto {{PLURAL:$5|xe mostrà la modifica fata|xe mostrà le modifiche fate }} da <strong>$3, $4</strong> (se ghe ne vede fin a <strong>$1</strong>).",
        "rclistfrom": "Mostra i canbiamenti fati da ƚe $2 del $3",
        "rcshowhideminor": "$1 i canbiamenti picenini",
        "rcshowhideminor-show": "Mostra",
        "recentchangeslinked-feed": "Canbiamenti ligà a sta pagina",
        "recentchangeslinked-toolbox": "Canbiamenti ligà a sta pagina",
        "recentchangeslinked-title": "Canbiamenti ligà a \"$1\"",
-       "recentchangeslinked-summary": "Sti qua i xe i canbiamenti fati ultimamente a pagine pontà da na pagina indicà da ti (o a pagine de na categoria indicà da ti).\nLe pagine [[Special:Watchlist|tegnùe d'ocio]] le xe in '''grosso'''.",
+       "recentchangeslinked-summary": "Scrivi el nome de na pagina pa' védar i canbiamenti fati a le pagine pontà da ela. (Pa' védar le pagine de na categoria, scrivi {{ns:category}}:Nome de la categoria). I canbiamenti a le pagine [[Special:Watchlist|tegnùe d'ocio]] i xe in <strong>groso</strong>.",
        "recentchangeslinked-page": "Nome de la pagina:",
        "recentchangeslinked-to": "Mostra solo i canbiamenti a le pagine ligà a quela indicà",
        "upload": "Carga un file",
        "booksources-invalid-isbn": "El nùmaro ISBN inserìo no'l xe mia valido: controla de novo se te lo ghè copià justo da la fonte originale.",
        "magiclink-tracking-isbn": "Pàgine che dòpara coƚegamenti magisi ISBN",
        "specialloguserlabel": "Asion efetuà da:",
-       "speciallogtitlelabel": "Asion efetuà so:",
+       "speciallogtitlelabel": "Asion efetuà so (titolo de la pagina o {{ns:user}}:nome utente):",
        "log": "Registri",
        "all-logs-page": "Tuti i registri pùblici",
        "alllogstext": "Vixualixazion unificà de tuti i registri disponibili de {{SITENAME}}.\nTe podi restrénzar i criteri de riçerca selezionando el tipo de registro, el nome utente, o la pàxena interessà (ocio che sti ultimi du i distingue tra majuscolo e minuscolo).",
        "unwatchthispage": "Desmeti de tegner d'ocio",
        "notanarticle": "Sta pagina no la xè na pagina de contenuto",
        "notvisiblerev": "La revision la xe stà scancelà",
-       "watchlist-details": "Te sì drio tegner d'ocio {{PLURAL:$1|una pagina (e la so pagina de discussion)|$1 pagine (e le so pagine de discussion)}}.",
+       "watchlist-details": "Te sì drio tegner d'ocio {{PLURAL:$1|una pagina|$1 pagine}} (più le pagine de discussion).",
        "wlheader-enotif": "Xe ativà la notifica via e-mail.",
-       "wlheader-showupdated": "Le pagine che xe stà canbià da la to ultima visita le xe segnà in '''grosso'''",
-       "wlnote": "Cuà soto te cati {{PLURAL:$1|'l ultimo canbiamento|i ultimi '''$1''' canbiamenti}} inte {{PLURAL:$2|l'ultema ora|łe ultime '''$2''' ore}}; i dati i xe axornai a łe $4 del $3.",
+       "wlheader-showupdated": "Le pagine che xe stà canbià da l'ultima olta che te le ghè viste, a le xe segnà in <strong>groso</strong>.",
+       "wlnote": "Cuà soto te cati {{PLURAL:$1|'l ultimo canbiamento|i ultimi <strong>$1</strong> canbiamenti}} inte {{PLURAL:$2|l'ultema ora|łe ultime <strong>$2</strong> ore}}; i dati i xe axornai a łe $4 del $3.",
        "wlshowlast": "Mostra le ultime $1 ore $2 zorni",
        "watchlist-options": "Inpostassion de le pagine tegnùe d'ocio",
        "watching": "Taco a tegner d'ocio...",
        "whatlinkshere": "Punta qua",
        "whatlinkshere-title": "Pagine che ponta a ''$1''",
        "whatlinkshere-page": "Pagina:",
-       "linkshere-2": "Ste pagine qua le ponta a '''$1''':",
-       "nolinkshere-2": "Nissuna pagina la contien colegamenti che punta a '''$1'''.",
-       "nolinkshere-ns-2": "No ghe xe pagine che punta a '''$1''' nel namespace selezionà.",
+       "linkshere": "Ste pagine qua le ponta a '''$1''':",
+       "nolinkshere": "Nissuna pagina la contien colegamenti che punta a '''$1'''.",
+       "nolinkshere-ns": "No ghe xe pagine che punta a '''$2''' nel namespace selezionà.",
        "isredirect": "Pagina de rimando",
        "istemplate": "inclusion",
        "isimage": "colegamento verso file",
        "tooltip-feed-rss": "Feed RSS par sta pagina",
        "tooltip-feed-atom": "Feed Atom par sta pagina",
        "tooltip-t-contributions": "La lista de i contribui de {{GENDER:$1|sto|sta}} utente",
-       "tooltip-t-emailuser": "Invia on mesajo e-mail a sto utente",
+       "tooltip-t-emailuser": "Màndeghe na e-mail a {{GENDER:$1|sto utente qua}}",
        "tooltip-t-upload": "Carga file",
        "tooltip-t-specialpages": "Lista de tute le pagine speciali",
        "tooltip-t-print": "Version stanpabile de sta pagina",
        "pageinfo-length": "Longhessa de la pagina (in byte)",
        "pageinfo-article-id": "ID de la pagina",
        "pageinfo-language": "Lengua del contenuto de la pagina",
-       "pageinfo-robot-policy": "Stato par i motori de riserca",
+       "pageinfo-content-model": "Modèl del contegnùo de la pagina",
+       "pageinfo-robot-policy": "Indexixasion par i robot",
        "pageinfo-robot-index": "Parmesso",
        "pageinfo-robot-noindex": "Vietà",
        "pageinfo-watchers": "Nùmaro de utenti che tien d'ocio sta pagina",
        "pageinfo-few-watchers": "Manco de $1 {{PLURAL:$1|oservador|oservadori}}",
-       "pageinfo-redirects-name": "Rimandi verso sta pagina",
+       "pageinfo-redirects-name": "Nùmaro de rimandi verso sta pagina",
        "pageinfo-subpages-name": "Sotopagine de sta pagina",
        "pageinfo-subpages-value": "$1 ($2 {{PLURAL:$2|rimandi}}; $3 {{PLURAL:$3|no rimandi}})",
        "pageinfo-firstuser": "Creador de sta pagina",
        "markedaspatrollederrornotify": "Eror durante ła verifega.",
        "patrol-log-page": "Modifiche verificàe",
        "patrol-log-header": "Qua de sèvito xe elencàe le verifiche de le modifiche.",
-       "log-show-hide-patrol": "$1 el registro dei canbiamenti verificài",
        "deletedrevision": "Vecia version scancełà $1",
        "filedeleteerror-short": "Eror ne la scancelazion del file: $1",
        "filedeleteerror-long": "Se gà verificà dei eror nel tentativo de scancelar el file:\n\n$1",
        "watchlistedit-raw-added": "Xe stà zontà {{PLURAL:$1|una pagina|$1 pagine}}:",
        "watchlistedit-raw-removed": "Xe stà eliminà {{PLURAL:$1|una pagina|$1 pagine}}:",
        "watchlistedit-clear-titles": "Pagine:",
+       "watchlisttools-clear": "Desvoda la lista dei tegnùi d'ocio",
        "watchlisttools-view": "Varda i canbiamenti",
        "watchlisttools-edit": "Varda e canbia le pagine tegnùe d'ocio",
        "watchlisttools-raw": "Canbia la lista in formato testo",
        "version-libraries-license": "Licensa",
        "version-libraries-description": "Descrision",
        "version-libraries-authors": "Autori",
-       "redirect": "Rimando par file, utente, pagina o ID de version.",
+       "redirect": "Rimando par file, utente, pagina, revision o registro",
        "redirect-summary": "Sta pagina speciale la rimanda a un file (dato el nome del file), a na pagina (dato l'ID de la revision), o a na pagina utente (dato l'ID de l'utente).",
        "redirect-submit": "Và",
        "redirect-lookup": "Ciave de riserca:",
        "redirect-value": "Valor:",
        "redirect-user": "ID utente",
+       "redirect-page": "ID de la pagina",
        "redirect-revision": "Revision de la pagina",
        "redirect-file": "Nome del file",
        "redirect-not-exists": "Valor mia catà",
        "htmlform-yes": "Sì",
        "htmlform-chosen-placeholder": "Selessiona na opzione",
        "logentry-delete-delete": "$1 {{GENDER:$2|el|la}} ga scansełà ła pajina $3",
-       "logentry-delete-restore": "$1 {{GENDER:$2|el|la}} ga ripristinà \"$3\"",
+       "logentry-delete-restore": "$1 {{GENDER:$2|el|la}} ga ripristinà $3 ($4)",
        "logentry-delete-event": "$1 {{GENDER:$2|el|la}} ga canbià ła vixibiłità de {{PLURAL:$5|n'asion del registro|$5 asion del registro}} de \"$3\": $4",
        "logentry-delete-revision": "$1 {{GENDER:$2|el|la}} ga canbià ła vixibiłità de {{PLURAL:$5|na revixion|$5 revixion}} de ła pajina\"$3\": $4",
        "logentry-delete-event-legacy": "$1 {{GENDER:$2|el|la}} ga canbià ła vixibiłità de calche asion del registro de \"$3\"",
        "logentry-rights-rights-legacy": "$1 {{GENDER:$2|el|la}} ga canbià l'apartenensa a grupi de $3",
        "logentry-rights-autopromote": "$1 {{GENDER:$2|el|la}} xe stà automategamente promoso/a da $4 a $5",
        "logentry-upload-upload": "$1 {{GENDER:$2|el|la}} gà cargà $3",
+       "logentry-upload-overwrite": "$1 {{GENDER:$2|el|la}} gà cargà na version nova de $3.",
        "rightsnone": "(nissun)",
        "feedback-adding": "Inserimento del feedback inte ła pàjina...",
        "feedback-back": "Indrìo",
        "mw-widgets-dateinput-placeholder-day": "AAAA-MM-GG",
        "mw-widgets-dateinput-placeholder-month": "AAAA-MM",
        "mw-widgets-titleinput-description-redirect": "rimando a $1",
-       "randomrootpage": "Pagina raìsa caxuale"
+       "randomrootpage": "Pagina raìsa a ocio"
 }
index 28e0f1d..b55152f 100644 (file)
        "whatlinkshere": "Kosketused - nakhu",
        "whatlinkshere-title": "Lehtpoled, kudambad kosketadas \"$1\"-lehtpolen",
        "whatlinkshere-page": "Lehtpol’:",
-       "linkshere-2": "Nened lehtpoled kosketadas '''$1''':",
-       "nolinkshere-2": "'''$1'''-lehtpol't ei kosketa ni üks' lehtpol'.",
-       "nolinkshere-ns-2": "'''$1'''-lehtpol't ei kosketa ni üks' lehtpol' valitud nimiavarudes.",
+       "linkshere": "Nened lehtpoled kosketadas '''$1''':",
+       "nolinkshere": "'''$1'''-lehtpol't ei kosketa ni üks' lehtpol'.",
+       "nolinkshere-ns": "'''$2'''-lehtpol't ei kosketa ni üks' lehtpol' valitud nimiavarudes.",
        "isredirect": "Oigendai lehtpol'",
        "istemplate": "mülütand",
        "isimage": "Kosketuz failale",
        "markedaspatrollederror-noautopatrol": "Teile ei sa znamoita ičetoi toižetusid kut patruliruidud.",
        "patrol-log-page": "Patruliruindan aigkirj",
        "patrol-log-header": "Nece om patruliruidud versijoiden aiglehtez.",
-       "log-show-hide-patrol": "$1 patruliruindan aigkirj",
        "deletedrevision": "$1-lehtpolen vanh versii om čutud",
        "filedeleteerror-short": "Failan čudandan petuz: $1",
        "filedeleteerror-long": "Necen failan heitmižen aigan ozaižihe petused:\n\n$1",
index 4f95d36..a40a8ff 100644 (file)
@@ -79,7 +79,7 @@
        "tog-watchlisthideminor": "Ẩn các sửa đổi nhỏ khỏi danh sách theo dõi",
        "tog-watchlisthideliu": "Ẩn sửa đổi của thành viên đã đăng nhập khỏi danh sách theo dõi",
        "tog-watchlistreloadautomatically": "Tự động tải lại danh sách theo dõi khi nào bộ lọc được thay đổi (cần JavaScript)",
-       "tog-watchlistunwatchlinks": "Thêm liên kết ngừng theo dõi/theo dõi trực tiếp vào mục trong danh sách theo dõi (cần JavaScript để bật/tắt)",
+       "tog-watchlistunwatchlinks": "Thêm nút ngừng theo dõi/theo dõi ({{int:Watchlist-unwatch}}/{{int:Watchlist-unwatch-undo}}) trực tiếp vào trang theo dõi có thay đổi (cần JavaScript để bật/tắt)",
        "tog-watchlisthideanons": "Ẩn sửa đổi của người dùng vô danh khỏi danh sách theo dõi",
        "tog-watchlisthidepatrolled": "Ẩn sửa đổi đã tuần tra trong danh sách theo dõi",
        "tog-watchlisthidecategorization": "Ẩn việc xếp thể loại",
        "cascadeprotected": "Trang này đã bị khóa không cho sửa đổi, vì nó được nhúng vào {{PLURAL:$1|trang|những trang}} đã bị khóa với tùy chọn “khóa theo tầng” được kích hoạt:\n$2",
        "namespaceprotected": "Bạn không có quyền sửa các trang trong không gian tên '''$1'''.",
        "customcssprotected": "Bạn không có quyền sửa đổi trang CSS này vì nó chứa các tùy chọn cá nhân của một thành viên khác.",
+       "customjsonprotected": "Bạn không có quyền sửa đổi trang JSON này vì nó chứa các tùy chọn cá nhân của một thành viên khác.",
        "customjsprotected": "Bạn không có quyền sửa đổi trang JavaScript này vì nó chứa các tùy chọn cá nhân của một thành viên khác.",
        "mycustomcssprotected": "Bạn không có quyền sửa đổi trang CSS này.",
+       "mycustomjsonprotected": "Bạn không có quyền sửa đổi trang JSON này.",
        "mycustomjsprotected": "Bạn không có quyền sửa đổi trang JavaScript này.",
        "myprivateinfoprotected": "Bạn không có quyền sửa đổi thông tin cá nhân của bạn.",
        "mypreferencesprotected": "Bạn không có quyền thay đổi tùy chọn của bạn.",
        "password-login-forbidden": "Tên đăng nhập và mật khẩu này đã bị cấm không được sử dụng.",
        "mailmypassword": "Tái tạo mật khẩu",
        "passwordremindertitle": "Mật khẩu tạm thời cho {{SITENAME}}",
-       "passwordremindertext": "Ai đó (có thể là bạn, có địa chỉ IP $1) đã yêu cầu chúng tôi gửi mật khẩu mới của {{SITENAME}} ($4). Chúng tôi đã tạo một mật khẩu tạm “$3” cho thành viên “$2”. Nếu bạn chính là người đã yêu cầu mật khẩu, bạn cần phải đăng nhập và thay đổi mật khẩu ngay bây giờ. Mật khẩu tạm sẽ hết hạn trong vòng {{PLURAL:$5|một ngày|$5 ngày}}.\n\nNếu bạn không yêu cầu gửi mật khẩu mới, hoặc bạn đã nhớ ra mật khẩu cũ của mình và không còn muốn đổi nó nữa, bạn có thể bỏ qua bức thư này và tiếp tục sử dụng mật khẩu cũ của bạn.",
+       "passwordremindertext": "Ai đó (có địa chỉ IP $1) đã yêu cầu chúng tôi gửi mật khẩu mới của {{SITENAME}} ($4). Chúng tôi đã tạo một mật khẩu tạm “$3” cho thành viên “$2”. Nếu bạn chính là người đã yêu cầu mật khẩu, bạn cần phải đăng nhập và thay đổi mật khẩu ngay bây giờ. Mật khẩu tạm sẽ hết hạn trong vòng {{PLURAL:$5|một ngày|$5 ngày}}.\n\nNếu bạn không yêu cầu gửi mật khẩu mới, hoặc bạn đã nhớ ra mật khẩu cũ của mình và không còn muốn đổi nó nữa, bạn có thể bỏ qua bức thư này và tiếp tục sử dụng mật khẩu cũ của bạn.",
        "noemail": "Thành viên “$1” không ghi thư điện tử.",
        "noemailcreate": "Bạn cần cung cấp một địa chỉ thư điện tử hợp lệ",
        "passwordsent": "Mật khẩu mới đã được gửi tới thư điện tử của thành viên “$1”. Xin đăng nhập lại sau khi nhận thư.",
        "botpasswords-existing": "Mật khẩu bot hiện tại",
        "botpasswords-createnew": "Tạo một mật khẩu mới bot",
        "botpasswords-editexisting": "Chỉnh sửa một mật khẩu hiện tại của bot",
+       "botpasswords-label-needsreset": "(mật khẩu cần được đặt lại)",
        "botpasswords-label-appid": "Tên bot:",
        "botpasswords-label-create": "Tạo",
        "botpasswords-label-update": "Cập nhật",
        "botpasswords-label-grants": "Các quyền có liên quan:",
        "botpasswords-help-grants": "Các lượt cấp phép cho phép truy cập các quyền lợi mà tài khoản của bạn đã có. Việc cấp phép tại đây không có cho phép truy cập quyền nào mà tài khoản của bạn thường không có. Xem thêm thông tin trong [[Special:ListGrants|bảng cấp phép]].",
        "botpasswords-label-grants-column": "Cấp quyền",
-       "botpasswords-bad-appid": "Bot có tên \"$1\" không hợp lệ.",
+       "botpasswords-bad-appid": "Tên bot “$1” không hợp lệ.",
        "botpasswords-insert-failed": "Không thể thêm tên bot \"$1\". Nó đã được thêm vào chưa?",
        "botpasswords-update-failed": "Không thể khi cập nhật bot có tên “$1”. Có phải nó đã bị xóa?",
        "botpasswords-created-title": "Mật khẩu bot đã được tạo",
-       "botpasswords-created-body": "Đã tạo mật khẩu cho bot tên \"$1\" của {{GENDER:$2|thành viên}} \"$2\".",
+       "botpasswords-created-body": "Đã tạo mật khẩu cho bot tên “$1” của thành viên “$2”.",
        "botpasswords-updated-title": "Mật khẩu Bot đã được cập nhật",
-       "botpasswords-updated-body": "Đã cập nhật mật khẩu cho bot tên \"$1\" của {{GENDER:$2|thành viên}} \"$2\".",
+       "botpasswords-updated-body": "Đã cập nhật mật khẩu cho bot tên “$1” của thành viên “$2”.",
        "botpasswords-deleted-title": "Mật khẩu bot đã bị xóa",
-       "botpasswords-deleted-body": "Đã xóa mật khẩu cho bot tên \"$1\" của {{GENDER:$2|thành viên}} \"$2\".",
+       "botpasswords-deleted-body": "Đã xóa mật khẩu cho bot tên “$1” của thành viên “$2”.",
        "botpasswords-newpassword": "Mật khẩu mới để đăng nhập như <strong>$1</strong> là <strong>$2</strong>. <em>Xin hãy ghi lại mật khẩu này để mai mốt tham khảo.</em> <br> (Các bot cũ cần tên đăng nhập khớp với tên người dùng cuối cùng có thể sử  dụng tên người dùng <strong>$3</strong> và mật khẩu <strong>$4</strong>.)",
        "botpasswords-no-provider": "BotPasswordsSessionProvider không có sẵn.",
        "botpasswords-restriction-failed": "Mật khẩu bot giới hạn ngăn chặn đăng nhập này.",
        "botpasswords-invalid-name": "Tên người dùng đã chỉ định không chứa dấu tách mật khẩu bot (\"$1\").",
        "botpasswords-not-exist": "Người dùng \"$1\" không có mật khẩu bot có tên \"$2\".",
+       "botpasswords-needs-reset": "Mật khẩu bot của bot tên “$2” của người dùng “$1” cần được đặt lại.",
        "resetpass_forbidden": "Không được đổi mật khẩu",
        "resetpass_forbidden-reason": "Không thể đổi mật khẩu: $1",
        "resetpass-no-info": "Bạn phải đăng nhập mới có thể truy cập trực tiếp trang này.",
        "resetpass-submit-loggedin": "Thay đổi mật khẩu",
        "resetpass-submit-cancel": "Hủy bỏ",
        "resetpass-wrong-oldpass": "Mật khẩu tạm hoặc mật khẩu hiện thời không hợp lệ.\nCó thể bạn đã thay đổi mật khẩu của mình hoặc đã yêu cầu cung cấp một mật khẩu tạm mới.",
-       "resetpass-recycled": "Xin vui lòng chọn một mật khẩu khác với mật khẩu hiện tại.",
+       "resetpass-recycled": "Xin vui lòng thay đổi mật khẩu của bạn thành mật khẩu khác.",
        "resetpass-temp-emailed": "Bạn đã đăng nhập bằng mật khẩu tạm gửi qua thư điện tử. Để hoàn tất việc đăng nhập, bạn phải tạo lại mật khẩu mới tại đây:",
        "resetpass-temp-password": "Mật khẩu tạm:",
        "resetpass-abort-generic": "Một phần mở rộng đã hủy bỏ tác vụ thay đổi mật khẩu.",
        "resetpass-expired": "Mật khẩu của bạn đã hết hạn. Xin vui lòng tạo lại mật khẩu mới để đăng nhập.",
-       "resetpass-expired-soft": "Mật khẩu của bạn đã hết hạn và cần được đặt lại. Xin vui lòng chọn một mật khẩu mới lúc bây giờ hoặc bấm “{{int:authprovider-resetpass-skip-label}}” để đặt lại sau.",
-       "resetpass-validity-soft": "Mật khẩu của bạn không hợp lệ: $1\n\nXin hãy chọn mật khẩu mới bây giờ hoặc bấm “{{int:authprovider-resetpass-skip-label}}” để đặt lại sau.",
+       "resetpass-expired-soft": "Mật khẩu của bạn đã hết hạn và cần được thay đổi. Xin vui lòng thay đổi mật khẩu mới lúc bây giờ hoặc bấm “{{int:authprovider-resetpass-skip-label}}” để thay đổi sau.",
+       "resetpass-validity-soft": "Mật khẩu của bạn không hợp lệ: $1\n\nXin hãy chọn mật khẩu mới bây giờ hoặc bấm “{{int:authprovider-resetpass-skip-label}}” để thay đổi sau.",
        "passwordreset": "Tái tạo mật khẩu",
        "passwordreset-text-one": "Hãy điền mẫu đơn này để tái tạo mật khẩu.",
        "passwordreset-text-many": "Điền vào {{PLURAL:$1}}một hộp sau để nhận một mật khẩu tạm thời qua thư điện tử.",
        "savechanges": "Lưu các thay đổi",
        "publishpage": "Đăng trang",
        "publishchanges": "Đăng thay đổi",
-       "savearticle-start": "Lưu trang...",
-       "savechanges-start": "Lưu thay đổi...",
-       "publishpage-start": "Đăng trang...",
-       "publishchanges-start": "Đăng thay đổi...",
+       "savearticle-start": "Lưu trang",
+       "savechanges-start": "Lưu các thay đổi…",
+       "publishpage-start": "Đăng trang",
+       "publishchanges-start": "Đăng các thay đổi…",
        "preview": "Xem trước",
        "showpreview": "Xem trước",
        "showdiff": "Xem thay đổi",
        "subject-preview": "Xem trước đề mục:",
        "previewerrortext": "Có lỗi xảy ra khi xem trước những thay đổi của bạn.",
        "blockedtitle": "Thành viên bị cấm",
-       "blockedtext": "'''Tên người dùng hoặc địa chỉ IP của bạn đã bị cấm.'''\n\nNgười thực hiện cấm là $1.\nLý do được cung cấp là ''$2''.\n\n* Bắt đầu cấm: $8\n* Kết thúc cấm: $6\n* Mục tiêu cấm: $7\n\nBạn có thể liên hệ với $1 hoặc một [[{{MediaWiki:Grouppage-sysop}}|bảo quản viên]] khác để thảo luận về việc cấm.\nBạn không thể sử dụng tính năng “gửi thư cho người này” trừ khi bạn đã ghi một địa chỉ thư điện tử hợp lệ trong [[Special:Preferences|tùy chọn tài khoản]] và bạn không bị khóa chức năng đó.\nĐịa chỉ IP hiện tại của bạn là $3, và mã số cấm là #$5.\nXin hãy ghi kèm tất cả các thông tin trên vào thư yêu cầu của bạn.",
-       "autoblockedtext": "Địa chỉ IP của bạn đã bị tự động cấm vì một người nào đó đã sử dụng nó, $1 là thành viên đã thực hiện cấm.\nLý do được cung cấp là:\n\n:''$2''\n\n* Bắt đầu cấm: $8\n* Kết thúc cấm: $6\n* Mục tiêu cấm: $7\n\nBạn có thể liên hệ với $1 hoặc một trong số các\n[[{{MediaWiki:Grouppage-sysop}}|bảo quản viên]] khác để thảo luận về việc cấm.\n\nChú ý rằng bạn sẽ không dùng được chức năng “gửi thư cho người này” trừ khi bạn đã ghi một địa chỉ thư điện tử hợp lệ trong [[Special:Preferences|tùy chọn]] và bạn không bị cấm dùng chức năng đó.\n\nĐịa chỉ IP hiện tại của bạn là $3, mã số cấm là $5.\nXin hãy ghi kèm tất cả các chi tiết trên vào thư yêu cầu của bạn.",
+       "blockedtext": "<strong>Tên người dùng hoặc địa chỉ IP của bạn đã bị cấm.</strong>\n\nNgười thực hiện cấm là $1.\nLý do được cung cấp là <em>$2</em>.\n\n* Bắt đầu cấm: $8\n* Kết thúc cấm: $6\n* Mục tiêu cấm: $7\n\nBạn có thể liên hệ với $1 hoặc một [[{{MediaWiki:Grouppage-sysop}}|bảo quản viên]] khác để thảo luận về việc cấm.\nBạn không thể sử dụng tính năng “{{int:emailuser}}” trừ khi bạn đã ghi một địa chỉ thư điện tử hợp lệ trong [[Special:Preferences|tùy chọn tài khoản]] và bạn không bị khóa chức năng đó.\nĐịa chỉ IP hiện tại của bạn là $3, và mã số cấm là #$5.\nXin hãy ghi kèm tất cả các thông tin trên vào thư yêu cầu của bạn.",
+       "autoblockedtext": "Địa chỉ IP của bạn đã bị tự động cấm vì một người nào đó đã sử dụng nó, $1 là thành viên đã thực hiện cấm.\nLý do được cung cấp là:\n\n:<em>$2</em>\n\n* Bắt đầu cấm: $8\n* Kết thúc cấm: $6\n* Mục tiêu cấm: $7\n\nBạn có thể liên hệ với $1 hoặc một trong số các\n[[{{MediaWiki:Grouppage-sysop}}|bảo quản viên]] khác để thảo luận về việc cấm.\n\nChú ý rằng bạn sẽ không dùng được chức năng “{{int:emailuser}}” trừ khi bạn đã ghi một địa chỉ thư điện tử hợp lệ trong [[Special:Preferences|tùy chọn]] và bạn không bị cấm dùng chức năng đó.\n\nĐịa chỉ IP hiện tại của bạn là $3, mã số cấm là $5.\nXin hãy ghi kèm tất cả các chi tiết trên vào thư yêu cầu của bạn.",
        "systemblockedtext": "Tên người dùng hoặc địa chỉ IP của bạn bị MediaWiki cấm tự động.\nLý do được cung cấp là:\n\n:<em>$2</em>\n\n* Bắt đầu cấm: $8\n* Kết thúc cấm: $6\n* Mục tiêu cấm: $7\n\nĐịa chỉ IP hiện tại của bạn là $3.\nXin vui lòng bao gồm tất cả các chi tiết bên trên khi nào hỏi về tác vụ này.",
        "blockednoreason": "không đưa ra lý do",
        "whitelistedittext": "Bạn phải $1 để sửa trang.",
        "blocked-notice-logextract": "Người dùng này hiện đang bị cấm sửa đổi. Nhật trình cấm gần nhất được ghi ở dưới để tiện theo dõi:",
        "clearyourcache": "<strong>Chú ý:</strong> Sau khi lưu trang, có thể bạn sẽ phải xóa bộ nhớ đệm của trình duyệt để xem các thay đổi.\n* <strong>Firefox / Safari:</strong> Nhấn giữ phím <em>Shift</em> trong khi nhấn <em>Tải lại</em> (<em>Reload</em>), hoặc nhấn tổ hợp <em>Ctrl-F5</em> hay <em>Ctrl-R</em> (⌘R trên Mac)\n* <strong>Google Chrome:</strong> Nhấn tổ hợp <em>Ctrl-Shift-R</em> (⇧⌘R trên Mac)\n* <strong>Internet Explorer:</strong> Nhấn giữ phím <em>Ctrl</em> trong khi nhấn <em>Làm tươi</em>, hoặc nhấn tổ hợp <em>Ctrl-F5</em>\n* <strong>Opera:</strong> Mở <em>Menu → Cài đặt</em> (<em>Opera → Tùy chỉnh</em> trên Mac), mở tab <em>Quyền riêng tư & bảo mật</em>, bấm <em>Xóa dữ liệu duyệt web</em> và đánh hộp kiểm <em>Hình ảnh và tệp trong cache</em>.",
        "usercssyoucanpreview": "'''Mẹo:''' Sử dụng nút “{{int:showpreview}}” để kiểm thử bản CSS của bạn trước khi lưu trang.",
+       "userjsonyoucanpreview": "'''Mẹo:''' Sử dụng nút “{{int:showpreview}}” để kiểm thử bản JSON của bạn trước khi lưu trang.",
        "userjsyoucanpreview": "'''Mẹo:''' Sử dụng nút “{{int:showpreview}}” để kiểm thử bản JS của bạn trước khi lưu trang.",
        "usercsspreview": "'''Hãy nhớ rằng bạn chỉ đang xem trước trang CSS cá nhân của bạn.\nNó chưa được lưu!'''",
+       "userjsonpreview": "<strong>Nhớ rằng bạn chỉ đang kiểm thử/xem trước cấu hình JSON, nó chưa được lưu!</strong>",
        "userjspreview": "'''Nhớ rằng bạn chỉ đang kiểm thử/xem trước trang JavaScript, nó chưa được lưu!'''",
        "sitecsspreview": "'''Nhớ rằng bạn chỉ đang xem trước bản CSS này.'''\n'''Nó chưa được lưu!'''",
+       "sitejsonpreview": "<strong>Nhớ rằng bạn chỉ đang xem trước cấu hình JSON này.\nNó chưa được lưu!</strong>",
        "sitejspreview": "'''Nhớ rằng bạn chỉ đang xem trước bản JavaScript này.\n'''Nó chưa được lưu!'''",
-       "userinvalidconfigtitle": "'''Cảnh báo:''' Không có skin “$1”. Hãy nhớ rằng các trang .css và .js tùy chỉnh sử dụng tiêu đề chữ thường, như {{ns:user}}:Ví&nbsp;dụ/vector.css chứ không phải {{ns:user}}:Ví&nbsp;dụ/Vector.css.",
+       "userinvalidconfigtitle": "<strong>Cảnh báo:</strong> Không có skin “$1”. Các trang .css, .json, và .js tùy chỉnh sử dụng tiêu đề chữ thường, như {{ns:user}}:Ví&nbsp;dụ/vector.css chứ không phải {{ns:user}}:Ví&nbsp;dụ/Vector.css.",
        "updated": "(Cập nhật)",
        "note": "'''Ghi chú:'''",
        "previewnote": "'''Đây chỉ mới là bản xem trước.'''\nCác thay đổi của bạn vẫn chưa được lưu!",
        "longpageerror": "'''Lỗi: Văn bạn mà bạn muốn lưu dài $1 kilôbyte, dài hơn độ dài tối đa cho phép $2 kilôbyte.'''\nKhông thể lưu trang.",
        "readonlywarning": "<strong>CẢNH BÁO: Cơ sở dữ liệu đã bị khóa để bảo dưỡng, do đó bạn không thể lưu các sửa đổi của mình. Bạn nên cắt-dán đoạn bạn vừa sửa vào một tập tin và lưu nó lại để sửa đổi sau này.</strong>\n\nQuản trị viên hệ thống khi khóa dữ liệu đã đưa ra lý do: $1",
        "protectedpagewarning": "'''Cảnh báo: Trang này đã bị khóa và chỉ có các thành viên có quyền quản lý mới có thể sửa được.'''\nThông tin mới nhất trong nhật trình được ghi dưới đây để tiện theo dõi:",
-       "semiprotectedpagewarning": "'''Lưu ý:''' Trang này đã bị khóa nên chỉ có các thành viên có tài khoản mới có thể sửa đổi được.\nThông tin mới nhất trong nhật trình được ghi dưới đây để tiện theo dõi:",
+       "semiprotectedpagewarning": "<strong>Lưu ý:</strong> Trang này đã bị khóa nên chỉ có các thành viên tự xác nhận có thể sửa đổi được.\nThông tin mới nhất trong nhật trình được ghi dưới đây để tiện theo dõi:",
        "cascadeprotectedwarning": "'''Cảnh báo:''' Trang này đã bị khóa, chỉ có thành viên có [[Special:ListGroupRights|quyền quản lý]] mới có thể sửa đổi, vì nó được nhúng vào {{PLURAL:$1|trang|những trang}} bị khóa theo tầng sau:",
        "titleprotectedwarning": "'''Cảnh báo:  Trang này đã bị khóa và bạn phải có một số [[Special:ListGroupRights|quyền nhất định]] mới có thể tạo trang.'''\nThông tin mới nhất trong nhật trình được ghi dưới đây để tiện theo dõi:",
        "templatesused": "{{PLURAL:$1|Bản mẫu|Các bản mẫu}} dùng trong trang này:",
        "diff-multi-sameuser": "(Không hiển thị {{PLURAL:$1||$1}} phiên bản của cùng người dùng ở giữa)",
        "diff-multi-otherusers": "(Không hiển thị {{PLURAL:$1||$1}} phiên bản của {{PLURAL:$2|một người dùng khác|$2 người dùng}} ở giữa)",
        "diff-multi-manyusers": "(Không hiển thị {{PLURAL:$1||$1}} phiên bản của hơn $2 thành viên ở giữa)",
+       "diff-paragraph-moved-tonew": "Đoạn văn được chuyển đến vị trí mới. Nhấn chuột để nhảy tới vị trí mới.",
+       "diff-paragraph-moved-toold": "Đoạn văn được chuyển từ vị trí khác. Nhấn chuột để nhảy tới vị trí cũ.",
        "difference-missing-revision": "Không tìm thấy {{PLURAL:$2|một phiên bản|$2 phiên bản}} trong khác biệt này ($1).\n\nLỗi này thường xuất hiện đối khi theo dõi liên kết lỗi thời đến khác biệt giữa các bản của trang đã bị xóa.\nXem chi tiết trong [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} nhật trình xóa].",
        "searchresults": "Kết quả tìm kiếm",
+       "search-filter-title-prefix": "Chỉ có tìm trong các trang có tên bắt đầu với “$1”",
+       "search-filter-title-prefix-reset": "Tìm kiếm tất cả các trang",
        "searchresults-title": "Kết quả tìm kiếm “$1”",
        "titlematches": "Đề mục tương tự",
        "textmatches": "Câu chữ tương tự",
        "stub-threshold-disabled": "Tắt",
        "recentchangesdays": "Số ngày hiển thị trong thay đổi gần đây:",
        "recentchangesdays-max": "(tối đa $1 ngày)",
-       "recentchangescount": "Số sửa đổi hiển thị mặc định:",
-       "prefs-help-recentchangescount": "Số này bao gồm các thay đổi gần đây, lịch sử trang, và nhật trình.",
+       "recentchangescount": "Số sửa đổi để hiển thị trong thay đổi gần đây, lịch sử trang, và nhật trình theo mặc định:",
+       "prefs-help-recentchangescount": "Con số tối đa: 1.000",
        "prefs-help-watchlist-token2": "Đây là chìa khóa bí mật cho nguồn cấp dữ liệu danh sách theo dõi của bạn.\nBất cứ ai biết nó sẽ có thể để đọc danh sách theo dõi của bạn, vì vậy đừng chia sẻ nó.\nNếu cần, [[Special:ResetTokens|bạn có thể thiết lập lại nó]].",
        "savedprefs": "Đã lưu các tùy chọn cá nhân.",
        "savedrights": "Đã lưu các nhóm người dùng của {{GENDER:$1}}$1.",
        "default": "mặc định",
        "prefs-files": "Tập tin",
        "prefs-custom-css": "sửa CSS",
+       "prefs-custom-json": "JSON tùy biến",
        "prefs-custom-js": "sửa JS",
-       "prefs-common-config": "CSS/JavaScript chung cho mọi giao diện:",
+       "prefs-common-config": "CSS/JSON/JavaScript chung cho mọi giao diện:",
        "prefs-reset-intro": "Có thể mặc định lại toàn bộ tùy chọn dùng trang này. Điều này không thể hoàn tác.",
        "prefs-emailconfirm-label": "Xác nhận thư điện tử:",
        "youremail": "Thư điện tử:",
        "prefs-editor": "Trình soạn",
        "prefs-preview": "Xem trước",
        "prefs-advancedrc": "Tùy chọn nâng cao",
+       "prefs-opt-out": "Quyết định không sử dụng các cải thiện",
        "prefs-advancedrendering": "Tùy chọn nâng cao",
        "prefs-advancedsearchoptions": "Tùy chọn nâng cao",
        "prefs-advancedwatchlist": "Tùy chọn nâng cao",
        "right-editcontentmodel": "Sửa kiểu nội dung của trang",
        "right-editinterface": "Sửa giao diện người dùng",
        "right-editusercss": "Sửa tập tin CSS của người dùng khác",
+       "right-edituserjson": "Sửa tập tin JSON của người dùng khác",
        "right-edituserjs": "Sửa đổi tập tin JavaScript của người dùng khác",
        "right-editmyusercss": "Sửa đổi tập tin CSS cá nhân của mình",
+       "right-editmyuserjson": "Sửa đổi tập tin JSON cá nhân của mình",
        "right-editmyuserjs": "Sửa đổi tập tin JavaScript cá nhân của mình",
        "right-viewmywatchlist": "Xem danh sách theo dõi của mình",
        "right-editmywatchlist": "Sửa đổi danh sách theo dõi của mình – một số tác vụ có thể thêm trang vào danh sách bất chấp quyền này",
        "grant-createaccount": "Mở tài khoản",
        "grant-createeditmovepage": "Tạo, sửa đổi, và di chuyển trang",
        "grant-delete": "Xóa trang, phiên bản, và mục nhật trình",
-       "grant-editinterface": "Sửa không gian tên MediaWiki và CSS/JavaScript cá nhân",
-       "grant-editmycssjs": "Sửa đổi CSS/JavaScript cá nhân của bạn",
+       "grant-editinterface": "Sửa không gian tên MediaWiki và CSS/JSON/JavaScript cá nhân",
+       "grant-editmycssjs": "Sửa đổi CSS/JSON/JavaScript cá nhân của bạn",
        "grant-editmyoptions": "Sửa đổi tùy chọn cá nhân của bạn",
        "grant-editmywatchlist": "Sửa danh sách theo dõi của bạn",
        "grant-editpage": "Sửa đổi các trang đã tồn tại",
        "rcfilters-other-review-tools": "Công cụ duyệt khác",
        "rcfilters-group-results-by-page": "Nhóm kết quả theo trang",
        "rcfilters-activefilters": "Bộ lọc hiện hành",
+       "rcfilters-activefilters-hide": "Ẩn",
+       "rcfilters-activefilters-show": "Hiện",
+       "rcfilters-activefilters-hide-tooltip": "Ẩn phần Bộ lọc kích hoạt",
+       "rcfilters-activefilters-show-tooltip": "Hiện phần Bộ lọc kích hoạt",
        "rcfilters-advancedfilters": "Bộ lọc nâng cao",
        "rcfilters-limit-title": "Số kết quả hiển thị",
        "rcfilters-limit-and-date-label": "$1 thay đổi, $2",
+       "rcfilters-date-popup-title": "Thời gian tìm kiếm",
        "rcfilters-days-title": "Những ngày gần đây",
        "rcfilters-hours-title": "Số giờ gần đây",
        "rcfilters-days-show-days": "$1 ngày",
        "rcfilters-savedqueries-rename": "Đổi tên",
        "rcfilters-savedqueries-setdefault": "Đặt làm mặc định",
        "rcfilters-savedqueries-unsetdefault": "Loại bỏ mặc định",
-       "rcfilters-savedqueries-remove": "Loại bỏ",
+       "rcfilters-savedqueries-remove": "Xóa",
        "rcfilters-savedqueries-new-name-label": "Tên",
        "rcfilters-savedqueries-new-name-placeholder": "Miêu tả mục đích của bộ lọc",
        "rcfilters-savedqueries-apply-label": "Tạo bộ lọc",
        "rcfilters-savedqueries-apply-and-setdefault-label": "Tạo bộ lọc mặc định",
        "rcfilters-savedqueries-cancel-label": "Hủy bỏ",
        "rcfilters-savedqueries-add-new-title": "Lưu thiết lập bộ lọc hiện tại",
+       "rcfilters-savedqueries-already-saved": "Đã lưu các bộ lọc này rồi. Thay đổi tùy chọn để tạo một Bộ lọc đã lưu mới.",
        "rcfilters-restore-default-filters": "Mặc định lại các bộ lọc",
        "rcfilters-clear-all-filters": "Xóa sạch các bộ lọc",
        "rcfilters-show-new-changes": "Xem các thay đổi mới nhất",
-       "rcfilters-search-placeholder": "Lọc các thay đổi gần đây (duyệt hoặc bắt đầu đánh chữ)",
+       "rcfilters-search-placeholder": "Lọc các thay đổi gần đây (sử dụng trình đơn hoặc tìm tên bộ lọc)",
        "rcfilters-invalid-filter": "Bộ lọc không hợp lệ",
        "rcfilters-empty-filter": "Không có bộ lọc hiện hành. Tất cả các đóng góp được hiển thị.",
        "rcfilters-filterlist-title": "Bộ lọc",
        "rcfilters-filterlist-whatsthis": "Chúng hoạt động làm sao?",
-       "rcfilters-filterlist-feedbacklink": "Cho chúng tôi biết bạn cảm thấy sao về các công cụ bộ lọc mới này",
+       "rcfilters-filterlist-feedbacklink": "Hãy cho chúng tôi biết bạn cảm thấy sao về các công cụ bộ lọc này",
        "rcfilters-highlightbutton-title": "Làm nổi bật kết quả",
        "rcfilters-highlightmenu-title": "Chọn màu",
        "rcfilters-highlightmenu-help": "Chọn màu để làm nổi bật thuộc tính này",
        "rcfilters-filter-user-experience-level-unregistered-label": "Vô danh",
        "rcfilters-filter-user-experience-level-unregistered-description": "Người dùng chưa đăng nhập.",
        "rcfilters-filter-user-experience-level-newcomer-label": "Người mới đến",
-       "rcfilters-filter-user-experience-level-newcomer-description": "Người dùng đã đăng nhập có ít hơn 10 sửa đổi  4 ngày hoạt động.",
+       "rcfilters-filter-user-experience-level-newcomer-description": "Người dùng đã đăng nhập có ít hơn 10 sửa đổi hoặc 4 ngày hoạt động.",
        "rcfilters-filter-user-experience-level-learner-label": "Người đang tập",
        "rcfilters-filter-user-experience-level-learner-description": "Người dùng đã đăng nhập có nhiều kinh nghiệm hơn “Người mới đến” mà ít hơn “Người có kinh nghiệm”.",
        "rcfilters-filter-user-experience-level-experienced-label": "Người có kinh nghiệm",
        "rcfilters-filter-humans-label": "Con người (không phải bot)",
        "rcfilters-filter-humans-description": "Các sửa đổi của người thật.",
        "rcfilters-filtergroup-reviewstatus": "Tình trạng tuần tra",
+       "rcfilters-filter-reviewstatus-unpatrolled-description": "Các sửa đổi không được đánh dấu tuần tra thủ công hoặc tự động.",
        "rcfilters-filter-reviewstatus-unpatrolled-label": "Chưa được tuần tra",
+       "rcfilters-filter-reviewstatus-manual-description": "Các sửa đổi được đánh dấu tuần tra thủ công.",
+       "rcfilters-filter-reviewstatus-manual-label": "Đánh dấu tuần tra thủ công",
+       "rcfilters-filter-reviewstatus-auto-description": "Sửa đổi của người dùng nâng cao được đánh dấu tuần tra tự động.",
+       "rcfilters-filter-reviewstatus-auto-label": "Tự đánh dấu tuần tra",
        "rcfilters-filtergroup-significance": "Sự quan trọng",
        "rcfilters-filter-minor-label": "Sửa đổi nhỏ",
        "rcfilters-filter-minor-description": "Các sửa đổi được tác giả đánh dấu là nhỏ.",
        "rcfilters-watchlist-edit-watchlist-button": "Sửa danh sách trang theo dõi",
        "rcfilters-watchlist-showupdated": "Thay đổi mới trên các trang kể lần cuối bạn xem trang được in <strong>đậm</strong> và có dấu tô màu.",
        "rcfilters-preference-label": "Ẩn phiên bản cải tiến của trang Thay đổi Gần đây",
+       "rcfilters-preference-help": "Hủy bỏ thiết kế lại giao diện năm 2017 và tất cả các công cụ được thêm từ lúc đó trở về nay.",
+       "rcfilters-watchlist-preference-label": "Ẩn danh sách theo dõi cải thiện",
+       "rcfilters-watchlist-preference-help": "Hủy bỏ thiết kế lại giao diện năm 2017 và tất cả các công cụ được thêm từ lúc đó trở về nay.",
+       "rcfilters-filter-showlinkedfrom-label": "Xem các thay đổi tại trang có liên kết từ",
+       "rcfilters-filter-showlinkedfrom-option-label": "<strong>Trang có liên kết từ</strong> trang được chọn",
+       "rcfilters-filter-showlinkedto-label": "Xem các thay đổi tại trang có liên kết đến",
+       "rcfilters-filter-showlinkedto-option-label": "<strong>Trang có liên kết đến</strong> trang được chọn",
        "rcfilters-target-page-placeholder": "Nhập tên trang (hoặc thể loại)",
        "rcnotefrom": "Dưới đây là {{PLURAL:$5|thay đổi duy nhất|các thay đổi}} từ <strong>$3 $4</strong> (hiển thị tối đa <strong>$1</strong> thay đổi).",
        "rclistfromreset": "Đặt lại lựa chọn ngày",
        "recentchangeslinked-feed": "Thay đổi liên quan",
        "recentchangeslinked-toolbox": "Thay đổi liên quan",
        "recentchangeslinked-title": "Thay đổi liên quan tới “$1”",
-       "recentchangeslinked-summary": "Nhập tên trang để xem các thay đổi được thực hiện tại những trang được liên kết với trang đó. (Để xem các trang được xếp vào một thể loại nào đó, nhập Thể loại:Tên thể loại). Các thay đổi được thực hiện tại trang trong [[Special:Watchlist|danh sách bạn theo dõi]] được '''tô đậm'''.",
+       "recentchangeslinked-summary": "Nhập tên trang để xem các thay đổi được thực hiện tại những trang được liên kết với trang đó. (Để xem các trang được xếp vào một thể loại nào đó, nhập {{ns:category}}:Tên thể loại). Các thay đổi được thực hiện tại trang trong [[Special:Watchlist|danh sách bạn theo dõi]] được '''tô đậm'''.",
        "recentchangeslinked-page": "Tên trang:",
        "recentchangeslinked-to": "Hiện thay đổi tại những trang có liên kết đến trang này thay thế",
        "recentchanges-page-added-to-category": "[[:$1]] được xếp vào thể loại",
        "uploadbtn": "Tải tập tin lên",
        "reuploaddesc": "Hủy tác vụ tải và quay lại mẫu tải tập tin lên",
        "upload-tryagain": "Lưu miêu tả tập tin được sửa đổi",
+       "upload-tryagain-nostash": "Gửi lại tập tin được tải lên lại và miêu tả được sửa đổi",
        "uploadnologin": "Chưa đăng nhập",
        "uploadnologintext": "Bạn phải $1 để tải tập tin lên.",
        "upload_directory_missing": "Thư mục tải lên ($1) không có hoặc máy chủ web không thể tạo được.",
        "uploaded-script-svg": "Tìm thấy phần tử “$1” có khả năng chạy kịch bản trong tập tin SVG được tải lên.",
        "uploaded-hostile-svg": "Tìm thấy CSS nguy hiểm trong phần tử style của tập tin SVG được tải lên.",
        "uploaded-event-handler-on-svg": "Không cho phép đặt thuộc tính xử lý sự kiện <code>$1=\"$2\"</code> trong tập tin SVG.",
-       "uploaded-href-attribute-svg": "Các đặc tính href trong tập tin SVG chỉ được phép dẫn đến các trang http:// hoặc https://, nhưng gặp phải <code>&lt;$1 $2=\"$3\"&gt;</code>.",
+       "uploaded-href-attribute-svg": "Phần tử <a> chỉ có thể liên kết (đặc tính href) đến đích data: (tập tin nhúng), http:// hay https://, hoặc mảnh (#, cùng trang). Đối với các phần tử khác như <image>, chỉ cho phép data: và mảnh. Hãy thử nhúng hình ảnh khi xuất hình SVG. Đã tìm thấy <code>&lt;$1 $2=\"$3\"&gt;</code>.",
        "uploaded-href-unsafe-target-svg": "Tìm thấy href đến đích URI data: không an toàn <code>&lt;$1 $2=\"$3\"&gt;</code> trong tập tin SVG được tải lên.",
        "uploaded-animate-svg": "Tìm thấy thẻ “animate” có thể thay đổi href qua thuộc tính “from” <code>&lt;$1 $2=\"$3\"&gt;</code> trong tập tin SVG được tải lên.",
        "uploaded-setting-event-handler-svg": "Đã ngăn cản việc đặt thuộc tính xử lý sự kiện khi tìm thấy <code>&lt;$1 $2=\"$3\"&gt;</code> trong tập tin SVG được tải lên.",
        "lockmanager-fail-closelock": "Không thể đóng tập tin khóa cho “$1”.",
        "lockmanager-fail-deletelock": "Không thể xóa tập tin khóa cho “$1”.",
        "lockmanager-fail-acquirelock": "Không thể lấy khóa cho “$1”.",
-       "lockmanager-fail-openlock": "Không thể mở tập tin khóa cho “$1”.",
+       "lockmanager-fail-openlock": "Không thể mở tập tin khóa cho “$1”. Hãy chắc chắn rằng thư mục tải lên được cấu hình đàng hoàng và máy chủ Web được phép ghi vào thư mục đó. Xem thêm chi tiết tại https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgUploadDirectory.",
        "lockmanager-fail-releaselock": "Không thể thả khóa cho “$1”.",
        "lockmanager-fail-db-bucket": "Không thể liên lạc với đủ cơ sở dữ liệu khóa trong nhóm $1.",
        "lockmanager-fail-db-release": "Không thể thả các chìa khóa trên cơ sở dữ liệu $1.",
        "uploadstash-bad-path-invalid": "Đường dẫn không hợp lệ.",
        "uploadstash-bad-path-unknown-type": "Loại không xác định \"$1\".",
        "uploadstash-bad-path-unrecognized-thumb-name": "Tên hình thu nhỏ không nhận dạng được.",
+       "uploadstash-bad-path-no-handler": "Không tìm thấy trình xử lý kiểu MIME $1 của tập tin $2.",
+       "uploadstash-bad-path-bad-format": "Chìa khóa “$1” không tuân theo định dạng.",
        "uploadstash-file-not-found-no-thumb": "Không thể tải hình thu nhỏ.",
+       "uploadstash-file-not-found-no-local-path": "Không tìm thấy đường dẫn trên máy cho hình nhỏ.",
        "uploadstash-file-not-found-no-object": "Không tạo được đối tượng tập tin cục bộ cho hình thu nhỏ.",
        "uploadstash-file-not-found-no-remote-thumb": "Nạp hình thu nhỏ thất bại: $1\nURL = $2",
+       "uploadstash-file-not-found-missing-content-type": "Thiếu đầu đề kiểu-nội-dung (content-type).",
+       "uploadstash-file-not-found-not-exists": "Không tìm thấy đường dẫn hoặc không phải là tập tin thuần túy.",
+       "uploadstash-file-too-large": "Không thể phục vụ tập tin lớn hơn $1 byte.",
        "uploadstash-not-logged-in": "Người dùng chưa đăng nhập, các tập tin phải do người dùng đã đăng nhập tải lên.",
-       "uploadstash-no-such-key": "Khoá không tồn tại ($1), không thể xoá.",
+       "uploadstash-wrong-owner": "Tập tin này ($1) không phải do người dùng hiện tại tải lên.",
+       "uploadstash-no-such-key": "Khóa không tồn tại ($1), không thể xóa.",
+       "uploadstash-no-extension": "Phần mở rộng không có giá trị.",
        "uploadstash-zero-length": "Tập tin có dung lượng bằng không.",
        "invalid-chunk-offset": "Khúc lệch (chunk offset) không hợp lệ",
        "img-auth-accessdenied": "Không cho phép truy cập",
        "http-timed-out": "Hết thời gian yêu cầu HTTP.",
        "http-curl-error": "Có lỗi khi truy xuất URL: $1",
        "http-bad-status": "Có vấn đề khi yêu cầu HTTP: $1 $2",
+       "http-internal-error": "Lỗi nội bộ HTTP.",
        "upload-curl-error6": "Không thể truy cập URL",
        "upload-curl-error6-text": "Không thể truy cập URL mà bạn đưa vào. Xin hãy kiểm tra xem URL có đúng không và website vẫn còn hoạt động.",
        "upload-curl-error28": "Quá thời gian tải lên cho phép",
        "doubleredirects": "Đổi hướng kép",
        "doubleredirectstext": "Trang này liệt kê các trang đổi hướng đến một trang đổi hướng khác.\nMỗi hàng có chứa các liên kết đến trang đổi hướng thứ nhất và thứ hai, cũng như mục tiêu của trang đổi hướng thứ hai, thường là trang đích “thực sự”, là nơi mà trang đổi hướng đầu tiên nên trỏ đến.\nCác mục <del>bị gạch bỏ</del> là các trang đã được sửa.",
        "double-redirect-fixed-move": "[[$1]] đã được đổi tên.\nNó được cập nhật tự động và giờ là trang đổi hướng đến [[$2]].",
-       "double-redirect-fixed-maintenance": "Tự động giải quyết đổi hướng kép từ [[$1]] đến [[$2]] trong một công việc bảo trì.",
+       "double-redirect-fixed-maintenance": "Tự động giải quyết đổi hướng kép từ [[$1]] đến [[$2]] trong một công việc bảo trì",
        "double-redirect-fixer": "Người sửa trang đổi hướng",
        "brokenredirects": "Đổi hướng sai",
        "brokenredirectstext": "Các trang đổi hướng sau đây liên kết đến trang không tồn tại:",
        "deadendpages": "Trang đường cùng",
        "deadendpagestext": "Các trang này không có liên kết đến trang khác trong {{SITENAME}}.",
        "protectedpages": "Trang bị khóa",
+       "protectedpages-filters": "Bộ lọc:",
        "protectedpages-indef": "Chỉ hiển thị khóa vô hạn",
        "protectedpages-summary": "Danh sách này liệt kê các trang hiện đang bị khóa. Xem danh sách các tên trang bị khóa không được tạo ra tại [[{{#special:ProtectedTitles}}|{{int:protectedtitles}}]].",
        "protectedpages-cascade": "Chỉ hiển thị khóa theo tầng",
        "protectedtitles-submit": "Xem các tên trang",
        "listusers": "Danh sách thành viên",
        "listusers-editsonly": "Chỉ hiện thành viên có tham gia sửa đổi",
+       "listusers-temporarygroupsonly": "Chỉ xem những người dùng trong nhóm người dùng tạm",
        "listusers-creationsort": "Xếp theo ngày khởi tạo",
        "listusers-desc": "Sắp xếp thứ tự giảm dần",
        "usereditcount": "$1 sửa đổi",
        "apisandbox-dynamic-parameters-add-label": "Thêm tham số:",
        "apisandbox-dynamic-parameters-add-placeholder": "Tên tham số",
        "apisandbox-dynamic-error-exists": "Một tham số có tên \"$1\" đã tồn tại.",
+       "apisandbox-templated-parameter-reason": "[[Special:ApiHelp/main#main/templatedparams|Tham số mẫu]] này được cung cấp theo {{PLURAL:$1|giá trị|các giá trị}} của $2.",
        "apisandbox-deprecated-parameters": "Tham số bị phản đối",
        "apisandbox-fetch-token": "Tự động điền token này",
+       "apisandbox-add-multi": "Thêm",
        "apisandbox-submit-invalid-fields-title": "Một số field là không hợp lệ",
        "apisandbox-submit-invalid-fields-message": "Xin vui lòng sửa các miền được đánh dấu và thử lại.",
        "apisandbox-results": "Kết quả",
        "speciallogtitlelabel": "Mục tiêu (tiêu đề hoặc {{ns:user}}:Tên-người-dùng đối với người dùng):",
        "log": "Nhật trình",
        "logeventslist-submit": "Xem",
+       "logeventslist-more-filters": "Hiện thêm nhật trình:",
+       "logeventslist-patrol-log": "Nhật trình tuần tra",
+       "logeventslist-tag-log": "Nhật trình thẻ đánh dấu",
        "all-logs-page": "Tất cả các nhật trình công khai",
        "alllogstext": "Hiển thị tất cả các nhật trình đang có của {{SITENAME}} chung với nhau.\nBạn có thể thu hẹp kết quả bằng cách chọn loại nhật trình, tên thành viên (phân biệt chữ hoa-chữ thường), hoặc các trang bị ảnh hưởng (cũng phân biệt chữ hoa-chữ thường).",
        "logempty": "Không có mục nào khớp với từ khóa.",
        "dellogpage": "Nhật trình xóa",
        "dellogpagetext": "Dưới đây là danh sách các trang bị xóa gần đây nhất.",
        "deletionlog": "nhật trình xóa",
+       "log-name-create": "Nhật trình tạo trang",
+       "log-description-create": "Dưới đây là danh sách các trang được tạo gần đây nhất.",
+       "logentry-create-create": "$1 {{GENDER:$2|đã tạo}} trang $3",
        "reverted": "Đã hồi phục một phiên bản cũ",
        "deletecomment": "Lý do:",
        "deleteotherreason": "Lý do khác/bổ sung:",
        "rollback-success": "Đã hủy sửa đổi của {{GENDER:$3}}$1;\nquay về phiên bản cuối của {{GENDER:$4}}$2.",
        "rollback-success-notify": "Đã hủy sửa đổi của $1;\nquay về phiên bản cuối của $2. [$3 Xem thay đổi]",
        "sessionfailure-title": "Phiên thất bại",
-       "sessionfailure": "Dường như có trục trặc với phiên đăng nhập của bạn; thao tác này đã bị hủy để tránh việc cướp quyền đăng nhập. Xin hãy nhấn nút “Back”, tải lại trang đó, rồi thử lại.",
+       "sessionfailure": "Dường như có trục trặc với phiên đăng nhập của bạn; thao tác này đã bị hủy để tránh việc cướp quyền đăng nhập. Xin hãy gửi lại biểu mẫu.",
        "changecontentmodel": "Thay đổi kiểu nội dung của một trang",
        "changecontentmodel-legend": "Thay đổi kiểu nội dung",
        "changecontentmodel-title-label": "Tên trang",
        "uctop": "(hiện tại)",
        "month": "Từ tháng (trở về trước):",
        "year": "Từ năm (trở về trước):",
+       "date": "Từ ngày (trở về trước):",
        "sp-contributions-newbies": "Chỉ hiển thị đóng góp của tài khoản mới",
        "sp-contributions-newbies-sub": "Các thành viên mới",
        "sp-contributions-newbies-title": "Đóng góp của các thành viên mới",
        "sp-contributions-newonly": "Chỉ hiện các sửa đổi tạo trang",
        "sp-contributions-hideminor": "Ẩn các sửa đổi nhỏ",
        "sp-contributions-submit": "Tìm kiếm",
+       "sp-contributions-outofrange": "Không thể hiển thị kết quả cho dải địa chỉ IP quá giới hạn CIDR là /$1.",
        "whatlinkshere": "Các liên kết đến đây",
        "whatlinkshere-title": "Các trang liên kết đến “$1”",
        "whatlinkshere-page": "Trang:",
-       "linkshere-2": "Các trang sau liên kết đến '''$1''':",
-       "nolinkshere-2": "Không có trang nào liên kết đến '''$1'''.",
-       "nolinkshere-ns-2": "Không có trang nào liên kết đến '''$1''' trong không gian tên đã chọn.",
+       "linkshere": "Các trang sau liên kết đến '''$1''':",
+       "nolinkshere": "Không có trang nào liên kết đến '''$1'''.",
+       "nolinkshere-ns": "Không có trang nào liên kết đến '''$2''' trong không gian tên đã chọn.",
        "isredirect": "trang đổi hướng",
        "istemplate": "được nhúng vào",
        "isimage": "liên kết tập tin",
        "ipb_blocked_as_range": "Lỗi: Địa chỉ IP $1 không bị cấm trực tiếp và do đó không thể bỏ cấm. Tuy nhiên, nó bị cấm do là một bộ phận của dải IP $2, bạn có thể bỏ cấm dải này.",
        "ip_range_invalid": "Dải IP không hợp lệ.",
        "ip_range_toolarge": "Không được phép cấm dải IP lớn hơn /$1.",
+       "ip_range_exceeded": "Dải địa chỉ IP này vượt quá dải tối đa. Dải được cho phép: /$1.",
+       "ip_range_toolow": "Không cho phép dải địa chỉ IP trên thực tế.",
        "proxyblocker": "Cấm proxy",
        "proxyblockreason": "Địa chỉ IP của bạn đã bị cấm vì là proxy mở. Xin hãy liên hệ nhà cung cấp dịch vụ Internet hoặc bộ phận hỗ trợ kỹ thuật của bạn và thông báo với họ về vấn đề an ninh nghiêm trọng này.",
        "sorbsreason": "Địa chỉ IP của bạn bị liệt kê là một proxy mở trong DNSBL mà {{SITENAME}} đang sử dụng.",
        "fix-double-redirects": "Cập nhật tất cả các trang đổi hướng chỉ đến tựa đề cũ",
        "move-leave-redirect": "Để lại trang đổi hướng",
        "protectedpagemovewarning": "'''Cảnh báo:''' Trang này đã bị khóa nên chỉ có các thành viên có quyền quản lý mới có thể di chuyển được.\nThông tin mới nhất trong nhật trình được ghi dưới đây để tiện theo dõi:",
-       "semiprotectedpagemovewarning": "'''Lưu ý:''' Trang này đã bị khóa nên chỉ có các thành viên có tài khoản mới có thể di chuyển được.\nThông tin mới nhất trong nhật trình được ghi dưới đây để tiện theo dõi:",
+       "semiprotectedpagemovewarning": "<strong>Lưu ý:</strong> Trang này đã bị khóa nên chỉ có các thành viên tự xác nhận có thể di chuyển được.\nThông tin mới nhất trong nhật trình được ghi dưới đây để tiện theo dõi:",
        "move-over-sharedrepo": "[[:$1]] đã tồn tại trong kho dùng chung. Nếu đổi tên tập tin thành tên này thì sẽ ghi đè lên tập tin dùng chung.",
        "file-exists-sharedrepo": "Bạn đã chọn tên tập tin trùng với tập tin nằm trong kho dùng chung.\nXin hãy chọn tên khác.",
        "export": "Xuất các trang",
        "group-bot.css": "/* Mã CSS tại đây sẽ chỉ ảnh hưởng đến các bot */",
        "group-sysop.css": "/* Mã CSS tại đây sẽ chỉ ảnh hưởng đến các bảo quản viên */",
        "group-bureaucrat.css": "/* Mã CSS tại đây sẽ chỉ ảnh hưởng đến các hành chính viên */",
+       "common.json": "/* Bất kỳ mã JSON ở đây sẽ được tải cho tất cả các thành viên khi tải một trang nào đó lên. */",
        "common.js": "/* Bất kỳ mã JavaScript ở đây sẽ được tải cho tất cả các thành viên khi tải một trang nào đó lên. */",
        "group-autoconfirmed.js": "/* Mã JavaScript tại đây sẽ chỉ được tải cho các thành viên tự động xác nhận */",
        "group-user.js": "/* Mã JavaScript tại đây sẽ chỉ được tải cho các thành viên có tài khoản */",
        "markedaspatrollederrornotify": "Đánh dấu tuần tra bị thất bại.",
        "patrol-log-page": "Nhật trình tuần tra",
        "patrol-log-header": "Đây là nhật trình tuần tra phiên bản.",
-       "log-show-hide-patrol": "$1 nhật trình tuần tra",
-       "log-show-hide-tag": "Nhật trình đánh dấu $1",
        "confirm-markpatrolled-button": "OK",
        "confirm-markpatrolled-top": "Đánh dấu tuần tra phiên bản $3 của $2?",
        "deletedrevision": "Đã xóa phiên bản cũ $1",
        "autosumm-blank": "Đã tẩy trống trang",
        "autosumm-replace": "Đã thay thế cả nội dung bằng “$1”",
        "autoredircomment": "Đổi hướng đến [[$1]]",
-       "autosumm-removed-redirect": "X đổi hướng đến trang [[$1]]",
-       "autosumm-changed-redirect-target": "Thay đổi trang đích của đổi hướng từ [[$1]] sang [[S2]]",
+       "autosumm-removed-redirect": "Xóa đổi hướng đến trang [[$1]]",
+       "autosumm-changed-redirect-target": "Thay đổi trang đích của đổi hướng từ [[$1]] sang [[$2]]",
        "autosumm-new": "Tạo trang mới với nội dung “$1”",
        "autosumm-newblank": "Đã tạo trang trống",
        "size-bytes": "$1 byte",
        "watchlistedit-clear-titles": "Các tiêu đề:",
        "watchlistedit-clear-submit": "Xóa sạch danh sách theo dõi (không thể lùi lại!)",
        "watchlistedit-clear-done": "Đã xóa sạch danh sách theo dõi của bạn.",
-       "watchlistedit-clear-jobqueue": "Danh sách theo dõi của bạn đang bị x. Quá trình này có thể tốn một khoảng thời gian!",
+       "watchlistedit-clear-jobqueue": "Danh sách theo dõi của bạn đang bị xóa. Quá trình này có thể tốn một khoảng thời gian!",
        "watchlistedit-clear-removed": "$1 tựa đề đã được xóa khỏi danh sách:",
        "watchlistedit-too-many": "Danh sách có quá nhiều trang để hiển thị.",
        "watchlisttools-clear": "Xóa sạch danh sách theo dõi",
        "version-specialpages": "Trang đặc biệt",
        "version-parserhooks": "Hook trong bộ xử lý",
        "version-variables": "Biến",
+       "version-editors": "Trình soạn",
        "version-antispam": "Chống spam",
        "version-other": "Phần mở rộng khác",
        "version-mediahandlers": "Bộ xử lý phương tiện",
        "version-poweredby-others": "những người khác",
        "version-poweredby-translators": "các biên dịch viên translatewiki.net",
        "version-credits-summary": "Chúng tôi muốn công nhận những người sau đã đóng góp vào [[Special:Version|MediaWiki]].",
-       "version-license-info": "MediaWiki là phần mềm tự do; bạn được phép tái phân phối và/hoặc sửa đổi nó theo những điều khoản của Giấy phép Công cộng GNU do Quỹ Phần mềm Tự do xuất bản; phiên bản 2 hay bất kỳ phiên bản nào mới hơn nào của Giấy phép.\n\nMediaWiki được phân phối với hy vọng rằng nó sẽ hữu ích, nhưng '''không có bất kỳ một bảo đảm nào cả''', ngay cả những bảo đảm ngụ ý cho '''các mục đích thương mại''' hoặc cho '''một mục đích đặc biệt nào đó'''. Xem Giấy phép Công cộng GNU để biết thêm chi tiết.\n\nCó lẽ bạn đã nhận [{{SERVER}}{{SCRIPTPATH}}/COPYING bản sao Giấy phép Công cộng GNU] đi kèm với tác phẩm này; nếu không, hãy viết thư đến:\n Free Software Foundation, Inc.\n 51 Franklin St., Fifth Floor\n Boston, MA 02110-1301\n USA\nhoặc [//www.gnu.org/licenses/old-licenses/gpl-2.0.html đọc nó trực tuyến].",
+       "version-license-info": "MediaWiki là phần mềm tự do; bạn được phép tái phân phối và/hoặc sửa đổi nó theo những điều khoản của Giấy phép Công cộng GNU do Quỹ Phần mềm Tự do xuất bản; phiên bản 2 hay bất kỳ phiên bản nào mới hơn nào của Giấy phép.\n\nMediaWiki được phân phối với hy vọng rằng nó sẽ hữu ích, nhưng <em>KHÔNG CÓ BẤT KỲ MỘT BAO ĐẢM NÀO CẢ</em>, ngay cả những bảo đảm ngụ ý cho <strong>CÁC MỤC ĐÍCH THƯƠNG MẠI</strong> hoặc cho <strong>MỘT MỤC ĐÍCH ĐẶC BIỆT NÀO ĐÓ</strong>. Xem Giấy phép Công cộng GNU để biết thêm chi tiết.\n\nCó lẽ bạn đã nhận [{{SERVER}}{{SCRIPTPATH}}/COPYING bản sao Giấy phép Công cộng GNU] đi kèm với tác phẩm này; nếu không, hãy viết thư đến:\n Free Software Foundation, Inc.\n 51 Franklin St., Fifth Floor\n Boston, MA 02110-1301\n USA\nhoặc [//www.gnu.org/licenses/old-licenses/gpl-2.0.html đọc nó trực tuyến].",
        "version-software": "Phần mềm được cài đặt",
        "version-software-product": "Phần mềm",
        "version-software-version": "Phiên bản",
        "tag-mw-contentmodelchange-description": "Sửa đổi [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:ChangeContentModel thay đổi kiểu nội dung] của trang",
        "tag-mw-new-redirect": "Trang đổi hướng mới",
        "tag-mw-new-redirect-description": "Các sửa đổi tạo ra trang đổi hướng mới hoặc biến một trang thành trang đổi hướng.",
-       "tag-mw-removed-redirect": "X đổi hướng",
+       "tag-mw-removed-redirect": "Xóa đổi hướng",
        "tag-mw-removed-redirect-description": "Các thay đổi biến một trang đổi hướng thành trang không đổi hướng",
        "tag-mw-changed-redirect-target": "Thay đổi trang đích của đổi hướng",
        "tag-mw-changed-redirect-target-description": "Các thay đổi làm thay đổi trang đích của một trang đổi hướng",
        "tag-mw-blank": "Tẩy trống trang",
-       "tag-mw-blank-description": "Các sửa đổi tẩy trống (x trắng) một trang",
+       "tag-mw-blank-description": "Các sửa đổi tẩy trống (xóa trắng) một trang",
        "tag-mw-replace": "Thay thế nội dung",
        "tag-mw-replace-description": "Các sửa đổi thay đổi trên 90% nội dung của một trang",
        "tag-mw-rollback": "Lùi tất cả",
        "limitreport-templateargumentsize-value": "$1/$2 byte",
        "limitreport-expansiondepth": "Độ sâu bung cao nhất",
        "limitreport-expensivefunctioncount": "Số lời gọi hàm cú pháp cần mức độ xử lý cao",
+       "limitreport-unstrip-size-value": "$1/$2 byte",
        "expandtemplates": "Bung bản mẫu",
-       "expand_templates_intro": "Trang đặc biệt này sẽ nhận vào văn bản và bung tất cả các bản mẫu trong nó ra một cách đệ quy cho đến hết. Nó cũng bung cả những hàm cú pháp như <code><nowiki>{{</nowiki>#language:…}}</code>, và những biến số như <code><nowiki>{{</nowiki>CURRENTDAY}}</code>. Thực ra nó bung các dữ liệu bình thường đặt trong ngoặc móc.",
+       "expand_templates_intro": "Trang đặc biệt này sẽ nhận vào mã wiki và bung tất cả các bản mẫu trong nó ra một cách đệ quy cho đến hết. Nó cũng bung cả những hàm cú pháp như <code><nowiki>{{</nowiki>#language:…}}</code>, và những biến số như <code><nowiki>{{</nowiki>CURRENTDAY}}</code>. Thực ra nó bung các dữ liệu bình thường đặt trong ngoặc móc.",
        "expand_templates_title": "Tên của trang văn cảnh (để phân tích {{FULLPAGENAME}} v.v.):",
-       "expand_templates_input": "Mã nguồn để bung:",
+       "expand_templates_input": "Mã wiki để bung:",
        "expand_templates_output": "Kết quả",
        "expand_templates_xml_output": "Xuất XML",
        "expand_templates_html_output": "Mã nguồn HTML thô",
        "expand_templates_preview": "Xem trước",
        "expand_templates_preview_fail_html": "<em>{{SITENAME}} cho phép mã nguồn HTML thô và dữ liệu phiên bị mất, nên bản xem trước bị ẩn để tránh tấn công JavaScript.</em>\n\n<strong>Nếu bạn thực sự muốn xem trước mã nguồn này, xin hãy thử lại nữa.</strong>\nNếu vẫn không được, hãy thử [[Special:UserLogout|đăng xuất]] rồi đăng nhập lại, và kiểm tra rằng trình duyệt của bạn cho phép các cookie của trang Web này.",
        "expand_templates_preview_fail_html_anon": "<em>{{SITENAME}} cho phép mã nguồn HTML thô và dữ liệu phiên bị mất, nên bản xem trước bị ẩn để tránh tấn công JavaScript.</em>\n\n<strong>Nếu bạn thực sự muốn xem trước mã nguồn này, xin hãy thử lại nữa.</strong>\nNếu vẫn không được, hãy [[Special:UserLogin|đăng nhập]] và thử lại lần nữa.",
-       "expand_templates_input_missing": "Bạn phải cung cấp văn bản nhập.",
+       "expand_templates_input_missing": "Bạn phải cung cấp mã wiki đầu vào.",
        "pagelanguage": "Thay đổi ngôn ngữ của trang",
        "pagelang-name": "Trang",
        "pagelang-language": "Ngôn ngữ",
        "unlinkaccounts-success": "Đã gỡ liên kết tài khoản.",
        "authenticationdatachange-ignored": "Tác vụ thay đổi dữ liệu xác thực không được xử lý. Có lẽ nhà cung cấp chưa được cấu hình?",
        "userjsispublic": "Xin lưu ý: Các trang con JavaScript không nên chứa dữ liệu bí mật, vì những người dùng khác có thể xem các trang này.",
+       "userjsonispublic": "Xin lưu ý: Các trang con JSON không nên chứa tin mật vì mọi người có thể xem trang.",
        "usercssispublic": "Xin lưu ý: Các trang con CSS không nên chứa dữ liệu bí mật, vì những người dùng khác có thể xem các trang này.",
        "restrictionsfield-badip": "Địa chỉ hoặc dải IP không hợp lệ: $1.",
        "restrictionsfield-label": "Các dải IP được cho phép:",
        "pagedata-title": "Dữ liệu về trang",
        "pagedata-text": "Trang này cung cấp giao diện dữ liệu cho các trang. Xin hãy cung cấp tên trang trong URL dùng cú pháp trang con.\n* Chế độ đàm phán nội dung được áp dụng tùy theo đầu đề Accept (chấp nhận) của trình khách của bạn. Điều này có nghĩa rằng dữ liệu trang được cung cấp dưới định dạng thích hợp nhất đối với trình khác của bạn.",
        "pagedata-not-acceptable": "Không tìm thấy định dạng phù hợp. Các kiểu MIME được hỗ trợ: $1",
-       "pagedata-bad-title": "Tiêu đề không hợp lệ: $1."
+       "pagedata-bad-title": "Tiêu đề không hợp lệ: $1.",
+       "unregistered-user-config": "Vì lý do bảo mật, các trang con JavaScript, CSS, và JSON của trang cá nhân không được tải cho những người dùng chưa đăng nhập.",
+       "passwordpolicies": "Quy định mật khẩu",
+       "passwordpolicies-summary": "Bảng này cho biết các quy định mật khẩu được áp dùng vào các nhóm người dùng được cấu hình tại wiki này.",
+       "passwordpolicies-group": "Nhóm",
+       "passwordpolicies-policies": "Quy định",
+       "passwordpolicies-policy-minimalpasswordlength": "Mật khẩu phải có ít nhất $1 ký tự",
+       "passwordpolicies-policy-minimumpasswordlengthtologin": "Mật khẩu phải có ít nhất $1 ký tự để cho bạn đăng nhập",
+       "passwordpolicies-policy-passwordcannotmatchusername": "Mật khẩu không thể khớp với tên người dùng",
+       "passwordpolicies-policy-passwordcannotmatchblacklist": "Mật khẩu không thể khớp với các mật khẩu trong danh sách đen",
+       "passwordpolicies-policy-maximalpasswordlength": "Mật khẩu không thể vượt quá $1 ký tự",
+       "passwordpolicies-policy-passwordcannotbepopular": "Mật khẩu không thể {{PLURAL:$1|là mật khẩu phổ biến nhất|xuất hiện trong danh sách $1 mật khẩu phổ biến nhất}}"
 }
index 6fa865f..de0422e 100644 (file)
        "whatlinkshere": "Linggs af däj Saidn",
        "whatlinkshere-title": "Sajdn, di af „$1“ fârwajsn",
        "whatlinkshere-page": "Sajdn:",
-       "linkshere-2": "Dii afgfiirdn sajdn fârwajsn af ''„$1“''':",
-       "nolinkshere-2": "Ka Seidn verlingt af '''„$1“'''.",
+       "linkshere": "Dii afgfiirdn sajdn fârwajsn af ''„$1“''':",
+       "nolinkshere": "Ka Seidn verlingt af '''„$1“'''.",
        "isredirect": "Wajdârlajdungssajdn",
        "istemplate": "Foorlaachn-ajbindung",
        "isimage": "Daddeilink",
index 3526cd8..60d1098 100644 (file)
        "whatlinkshere": "Yüms isio",
        "whatlinkshere-title": "Pads ad \"$1\" yumöls",
        "whatlinkshere-page": "Pad:",
-       "linkshere-2": "Pads sököl payümons ko '''$1''':",
-       "nolinkshere-2": "Pads nonik peyümons lü '''$1'''.",
-       "nolinkshere-ns-2": "Pads nonik yumons lü pad: '''$1''' in nemaspad pevälöl.",
+       "linkshere": "Pads sököl payümons ko '''$1''':",
+       "nolinkshere": "Pads nonik peyümons lü '''$1'''.",
+       "nolinkshere-ns": "Pads nonik yumons lü pad: '''$2''' in nemaspad pevälöl.",
        "isredirect": "lüodükömapad",
        "istemplate": "ninükam",
        "isimage": "yüm ragiva",
        "markedaspatrollederror-noautopatrol": "No dalol zepön votükamis lönik ola.",
        "patrol-log-page": "Jenotalised zepamas",
        "patrol-log-header": "Is lisedons revids pezepöl.",
-       "log-show-hide-patrol": "Jenotalised Zepamas: $1",
        "deletedrevision": "Fomam büik: $1 pemoükon.",
        "filedeleteerror-short": "Pöl pö moükam ragiva: $1",
        "filedeleteerror-long": "Pöls petuvons dü moükam ragiva:\n\n$1",
index 97d736b..18ea783 100644 (file)
        "whatlinkshere": "Linkid tänne",
        "whatlinkshere-title": "Cüľľed, kummad näütellä cüľľelle \"$1\"",
        "whatlinkshere-page": "Cülci:",
-       "linkshere-2": "Vahtiaavilt cülciilt on linkki cüľľelle '''$1''':",
-       "nolinkshere-2": "Mitäid eb viitata '''$1-sõ'''",
+       "linkshere": "Vahtiaavilt cülciilt on linkki cüľľelle '''$1''':",
+       "nolinkshere": "Mitäid eb viitata '''$1-sõ'''",
        "isredirect": "mešaituzcülci",
        "istemplate": "sisällütüz šabloonii",
        "isimage": "kuvalinkki",
index fbac9a3..0c2b2dd 100644 (file)
        "whatlinkshere": "Siiäq näütäjäq lingiq",
        "whatlinkshere-title": "Leheq, miä näütäseq lehe \"$1\" pääle",
        "whatlinkshere-page": "Leht:",
-       "linkshere-2": "Lehe <b>$1</b> pääle näütäseq lingiq lehti päält:",
-       "nolinkshere-2": "Lehe <b>$1</b> pääle näütä-i linke ütegi lehe päält.",
-       "nolinkshere-ns-2": "Valitun nimeruumin näütä-i ütegi lehe päält linke lehe '''$1''' pääle.",
+       "linkshere": "Lehe <b>$1</b> pääle näütäseq lingiq lehti päält:",
+       "nolinkshere": "Lehe <b>$1</b> pääle näütä-i linke ütegi lehe päält.",
+       "nolinkshere-ns": "Valitun nimeruumin näütä-i ütegi lehe päält linke lehe '''$2''' pääle.",
        "isredirect": "ümbresaatmislehekülg",
        "istemplate": "pruugit näüdüssen",
        "isimage": "teedüstülink",
index 20a8a69..dfd60de 100644 (file)
@@ -8,7 +8,8 @@
                        "아라",
                        "Macofe",
                        "Matma Rex",
-                       "Reptilien.19831209BE1"
+                       "Reptilien.19831209BE1",
+                       "Matěj Suchánek"
                ]
        },
        "tog-underline": "Sorlignî les loyéns:",
@@ -17,7 +18,7 @@
        "tog-newpageshidepatrolled": "Èn nén mostrer el djivêye des novelès pådjes les cenes dedja patrouyeyes",
        "tog-hidecategorization": "Èn nén mostrer les categorijhaedjes des pådjes",
        "tog-extendwatchlist": "Ragrandi l' djivêye po mostrer tos les candjmints, nén seulmint les dierins",
-       "tog-usenewrc": "Relére par pådje dins les dierins candjmints et l' djivêye des shuvous (i fåt JavaScript)",
+       "tog-usenewrc": "Rashonner par pådje dins les dierins candjmints et l' djivêye des shuvous (i fåt JavaScript)",
        "tog-numberheadings": "Limerotaedje otomatike des tites",
        "tog-showtoolbar": "Mostrer l' bår d' usteyes e môde candjmint",
        "tog-editondblclick": "Candjî les pådjes avou on dobe-clitch",
@@ -36,7 +37,7 @@
        "tog-enotifminoredits": "M' emiler eto po les ptits candjmints des pådjes u des fitchîs",
        "tog-enotifrevealaddr": "Mostrer mi adresse emile dins les emiles di notifiaedje",
        "tog-shownumberswatching": "Mostrer l' nombe d' uzeus ki shuvèt l' pådje",
-       "tog-oldsig": "Siné pol moumint:",
+       "tog-oldsig": "Siné pol moumint :",
        "tog-fancysig": "Sinateure avou do tecse wiki (sins loyén otomatike)",
        "tog-uselivepreview": "Eployî l' préveyaedje abeye",
        "tog-forceeditsummary": "M' advierti cwand dji lai vude on rascourti",
        "tog-watchlisthideliu": "Èn nén mostrer les candjmints fwait pa des uzeus edjîstrés",
        "tog-watchlisthideanons": "Èn nén mostrer les candjmints fwait pa des uzeus anonimes",
        "tog-watchlisthidepatrolled": "Èn nén mostrer les candjmints ddja patrouyîs",
+       "tog-watchlisthidecategorization": "Catchî l' categorijhaedje des pådjes",
        "tog-ccmeonemails": "M' evoyî ene copeye des emiles ki dj' evoye ås ôtes",
        "tog-diffonly": "Èn nén håyner l' contnou del pådje pa dzo l' pådje des diferinces",
        "tog-showhiddencats": "Mostrer les categoreyes mucheyes",
        "tog-norollbackdiff": "Èn nén håyner les diferinces après on disfijhaedje",
        "tog-useeditwarning": "M' advierti cwand dji cwite ene pådje k' a des candjmints nén schapés",
+       "tog-prefershttps": "Todi eployî on seur raloyaedje cwand dji so elodjî",
        "underline-always": "Tofer",
        "underline-never": "Måy",
-       "underline-default": "Valixhance do betchteu",
+       "underline-default": "Valixhance del pea u do betchteu",
        "editfont-style": "Stîle del fonte pol boesse di tecse",
+       "editfont-sansserif": "Fonte Sans-serif",
+       "editfont-serif": "Fonte Serif",
        "sunday": "dimegne",
        "monday": "londi",
        "tuesday": "mårdi",
        "searcharticle": "Potchî",
        "history": "Istwere del pådje",
        "history_short": "Istwere",
+       "history_small": "Istwere",
        "updatedmarker": "candjî dispoy mi dierinne vizite",
        "printableversion": "Modêye sicrirece-amiståve",
        "permalink": "Hårdêye viè cisse modêye ci",
        "view": "Vey",
        "view-foreign": "Vey so $1",
        "edit": "Candjî",
+       "edit-local": "Candjî l' discrijhaedje locå",
        "create": "Ahiver",
+       "create-local": "Radjouter on discrijhaedje locå",
        "delete": "Disfacer",
        "undelete_short": "Rapexhî {{PLURAL:$1|on candjmint|$1 candjmints}}",
        "viewdeleted_short": "Vey {{PLURAL:$1|on candjmint disfacé|$1 candjmints disfacés}}",
        "copyrightpage": "{{ns:project}}:Abondroets",
        "currentevents": "Actouwålités",
        "currentevents-url": "Project:Actouwålités",
+       "disclaimers": "Adviertances",
+       "disclaimerpage": "Project: Djeneråles adviertances",
        "edithelp": "Aidance",
        "helppage-top-gethelp": "Aidance",
        "mainpage": "Mwaisse pådje",
        "mainpage-description": "Mwaisse pådje",
        "portal": "Inte di nozôtes",
        "portal-url": "Project:Inte di nozôtes",
+       "privacy": "Politike des scretès dinêyes",
+       "privacypage": "Project: Politike des scretès dinêyes",
        "badaccess": "Åk n' a nén stî avou les permissions",
        "badaccess-groups": "L' accion ki vos avoz dmandé est limitêye ås uzeus {{PLURAL:$2|do groupe|des groupes}}: $1.",
        "versionrequired": "I vs fåt l' modêye $1 di MediaWiki",
        "perfcachedts": "Les dnêyes ki shuvèt c' est ene copeye e muchete, ey elle ont stî metowes a djoû pol dierin côp li $1. Li muchete a-st on macsimom {{PLURAL:$4|d' on rzultat|di $4 rizultats}}.",
        "viewsource": "Vey côde sourdant",
        "viewsource-title": "Côde sourdant di «$1»",
-       "viewsourcetext": "Loukîz li contnou d' l’ årtike, et s’ li rcopyî si vos vloz, por vos bouter dsu foû des fyis:",
-       "protectedinterface": "Cisse pådje ci dene on tecse d' eterface pol programe, eyet elle a stî protedjeye po s' waeranti siconte des abus.",
+       "viewsourcetext": "Vos ploz rwaitî et rcopyî li contnou di cisse pådje ci.",
+       "viewyourtext": "Vos ploz rwaitî et rcopyî li contnou d' <strong>vosse ovraedje</strong> so cisse pådje ci.",
+       "protectedinterface": "Cisse pådje ci dene on tecse d' eterface pol programe, eyet elle a stî protedjeye po s' waeranti siconte des abus. Po radjouter u candjî des ratournaedjes so tos les wikis, i vos fåt eployî [https://translatewiki.net/ translatewiki.net], li pordjet d' ratournaedje coinrece da MediaWiki.",
        "editinginterface": "<strong>Asteme:</strong> Vos estoz ki candje ene pådje eployeye po fé l' tecse po l' eterface do programe.\nLes candjmints ki vos frîz vont candjî l' rivnance di l' eterface po ls ôtes uzeus do wiki.",
+       "translateinterface": "Po radjouter u candjî des ratournaedjes so tos les wikis, eployîz [https://translatewiki.net/ translatewiki.net], li pordjet d' ratournaedje coinrece da MediaWiki.",
        "cascadeprotected": "Cisse pådje ci a stî protedjeye siconte des candjmints, pask' ele est eploye ådvins {{PLURAL:$1|del pådje shuvante k' est protedjeye|des pådjes shuvantes ki sont protedjeyes}} avou l' tchuze «e cascåde» en alaedje:\n$2",
        "logouttext": "<strong>Vos vs avoz dislodjî.</strong>\n\nNotez ki des pådjes k' i gn a si pôrént continouwer a vey come si vos estîz elodjî, disk' a tant ki vos vudrîz l' muchete di vosse betchteu waibe.",
        "welcomeuser": "Bénvnowe, $1!",
        "page_first": "prumî",
        "page_last": "dierin",
        "histlegend": "Tchoezi les modêyes a comparer: clitchîz so les botons radio des deus modêyes\nki vos vloz comparer et s' tchôkîz sol tape «enter» ou clitchîz sol\nboton do dzo.<br />\nLedjinde: '''({{int:cur}})''' = diferince avou l' modêye d' asteure, '''({{int:last}})''' = diferince avou l' modêye di dvant, '''{{int:minoreditletter}}''' = pitit candjmint d' rén do tot.",
-       "history-fieldset-title": "Naivyî l' istwere des candjmints",
+       "history-fieldset-title": "Cachî dins l' istwere des candjmints",
        "history-show-deleted": "Disfacés seulmint",
-       "histfirst": "li pus vî",
-       "histlast": "li dierin",
+       "histfirst": "les pus vîs",
+       "histlast": "les dierins",
        "historysize": "({{PLURAL:$1|1 octet|$1 octets}})",
        "historyempty": "(vude)",
        "history-feed-title": "Istwere des modêyes",
        "saveusergroups": "Schaper les groupes d' uzeus",
        "userrights-groupsmember": "Mimbe di:",
        "userrights-groupsmember-auto": "Mimbe implicite di:",
-       "userrights-groups-help": "Vos ploz candjî les groupes ki {{GENDER:$1|cist uzeu|ciste uzeuse}} apårtént:\n* Ene boesse clitcheye c' est k' {{GENDER:$|il|elle}} est mimbe do groupe.\n* Ene boesse disclitcheye c' est k' {{GENDER:$|i|ele}} n' end est nén mimbe.\n* Ene sitoele (*) mostere k' on n' pout nén rsaetchî l' groupe on côp k' il a stî radjouté, ou årvierdimint.",
+       "userrights-groups-help": "Vos ploz candjî les groupes ki {{GENDER:$1|cist uzeu|ciste uzeuse}} apårtént:\n* Ene boesse clitcheye c' est k' {{GENDER:$1|il|elle}} est mimbe do groupe.\n* Ene boesse disclitcheye c' est k' {{GENDER:$1|i|ele}} n' end est nén mimbe.\n* Ene sitoele (*) mostere k' on n' pout nén rsaetchî l' groupe on côp k' il a stî radjouté, ou årvierdimint.",
        "userrights-reason": "Råjhon:",
        "userrights-no-interwiki": "Vos n' avoz nén les permissions po candjî les droets des uzeus so ds ôtes wikis.",
        "userrights-nodatabase": "Li båze di dnêyes «$1» n' egzistêye nén ou n' est nén locåle.",
        "recentchanges-legend-heading": "<strong>Ledjinde:</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (vey eto l' [[Special:NewPages|djivêye des nouvès pådjes]])",
        "recentchanges-submit": "Vey",
-       "rcnotefrom": "Chal pa dzo les candjmints dispoy li '''$2''' (disk' a '''$1''' di mostrés).",
+       "rcnotefrom": "Chal pa dzo {{PLURAL:$5|li candjmint fwait|les candjmints fwaits}} dispoy li <strong>$3, $4</strong> (afitchîs disk a <strong>$1</strong>).",
        "rclistfrom": "Mostrer les candjmints k' i gn a yeu a pårti do $3 $2",
        "rcshowhideminor": "$1 candjmints mineurs",
        "rcshowhideminor-show": "Mostrer",
        "recentchangeslinked-feed": "Candjmints aloyîs",
        "recentchangeslinked-toolbox": "Candjmints aloyîs",
        "recentchangeslinked-title": "Candjmints aloyîs a «$1»",
-       "recentchangeslinked-summary": "Çouchal c' est ene djivêye des candjmints k' ont stî fwaits dierinnmint a des pådjes aloyeyes a pårti d' ene pådje dinêye (ou mimbes d' ene categoreye dinêye).\nLes pådjes ki [[Special:Watchlist|vos shuvoz]] sont-st e '''cråssès letes'''.",
+       "recentchangeslinked-summary": "Intrez on no d' pådje po vey les candjmints k' ont stî fwaits dierinnmint a des pådjes aloyeyes a pårti u viè cisse pådje ci (po vey les mimbes d' ene categoreye dinêye, intrez {{ns:category}}:No del categoreye). Les pådjes ki [[Special:Watchlist|vos shuvoz]] et k' ont stî candjeyes sont-st e <strong>cråssès letes</strong>.",
        "recentchangeslinked-page": "No del pådje:",
        "recentchangeslinked-to": "Mostere les candjmints des pådjes avou on loyén viè l' pådje dinêye purade k' å rviè",
        "upload": "Eberweter on fitchî",
        "contributions-title": "Djivêye des ovraedjes di l' {{GENDER:$1|uzeu|uzeuse}} $1",
        "mycontris": "Mi ovraedje",
        "anoncontribs": "Mi ovraedje",
-       "contribsub2": "Po l' uzeu $1 ($2)",
+       "contribsub2": "Po {{GENDER:$3|$1}} ($2)",
        "nocontribs": "Nou candjmint di trové ki corespondreut a ç' critere la.",
        "uctop": "(dierinne)",
        "month": "dispu l' moes (et pus timpe)",
        "whatlinkshere": "Pådjes ki loynut chal",
        "whatlinkshere-title": "Pådjes ki loynut aviè «$1»",
        "whatlinkshere-page": "Pådje:",
-       "linkshere-2": "Les pådjes ki shuvèt ont des loyéns viè '''$1''':",
-       "nolinkshere-2": "Nole pådje avou des loyéns viè '''$1'''.",
+       "linkshere": "Les pådjes ki shuvèt ont des loyéns viè '''$1''':",
+       "nolinkshere": "Nole pådje avou des loyéns viè '''$1'''.",
        "isredirect": "pådje di redjiblaedje",
        "isimage": "loyén viè l' fitchî",
        "whatlinkshere-prev": "{{PLURAL:$1|di dvant|$1 di dvant}}",
index 7f8ae9a..2d5c8ad 100644 (file)
        "recentchangeslinked-feed": "Mga may kalabotan nga binag-o",
        "recentchangeslinked-toolbox": "Mga may kalabotan nga binag-o",
        "recentchangeslinked-title": "Mga pagbag-o kasumpay ha ''$1''",
-       "recentchangeslinked-summary": "Ini nga taramdan hin pagbag-o nga lab-as nga hinimo ha mga pakli nga nakasumpay tikang a naka-specifico nga pakli (o ha api han uska specifico nga kaarangay).\nMga pakli ha [[Special:Watchlist|imo angay timan-an]] in naka-'''bold'''.",
+       "recentchangeslinked-summary": "Ibutang an ngaran han pakli basi maipakita an mga pakli nga nakasumapy pakadto o pakadi hinin nga pakli. (Basi makit-an an mga api hini nga kaarangay, ibutang an {{ns:category}}:Ngaran han kaarangay). An mga binalyuan ha mga pakli ha [[Special:Watchlist|your Watchlist]] nakasurat nga <strong>madakmol</strong>.",
        "recentchangeslinked-page": "Ngaran han pakli:",
        "recentchangeslinked-to": "Igpakita lugod an mga pagbabag-o han mga pakli nga nahisumpay ha ginhatag nga pakli",
        "upload": "Pagkarga hin file",
        "whatlinkshere": "Mga nasumpay dinhi",
        "whatlinkshere-title": "Mga pakli nga nasumpay ngadto ha \"$1\"",
        "whatlinkshere-page": "Pakli:",
-       "linkshere-2": "An masunod nga mga pakli in nasumpay ha '''$1''':",
-       "nolinkshere-2": "Waray mga pakli nga nasumpay ha '''$1'''",
+       "linkshere": "An masunod nga mga pakli in nasumpay ha '''$1''':",
+       "nolinkshere": "Waray mga pakli nga nasumpay ha '''$1'''",
        "isredirect": "Redirek nga pakli",
        "istemplate": "transklusyon",
        "isimage": "sumpay han fayl",
        "markedaspatrollederror": "Diri nakakamarka komo ginpatrolya na",
        "patrol-log-page": "Talaan han pagpatrolya",
        "patrol-log-header": "Ini in uska talaan hin mga ginpatrolya nga mga rebisyon.",
-       "log-show-hide-patrol": "$1 talaan hin pagpatrolya",
        "deletedrevision": "Ginpara an daan nga rebisyon $1",
        "filedeleteerror-short": "Nagsayop ha pagpara han paypay: $1",
        "filedeleteerror-long": "Mga sayop nga ginengkwentro samtang nagpapara hin paypay:\n\n$1",
index 80f245a..f9dc81b 100644 (file)
        "whatlinkshere": "Xët yi mu lëkkalool",
        "whatlinkshere-title": "Xët yi lëkkalook wii « $1 »",
        "whatlinkshere-page": "Xët :",
-       "linkshere-2": "Xët yii ci suuf am nañ ab lëkkalekaay buy jëm <b>$1</b> :",
-       "nolinkshere-2": "Amul wenn xët wu lëkkalook wii <b>$1</b>.",
-       "nolinkshere-ns-2": "Amul wenn xët wu lëkkalook wii '''$1''' ci barabu tur bi nga tànn.",
+       "linkshere": "Xët yii ci suuf am nañ ab lëkkalekaay buy jëm <b>$1</b> :",
+       "nolinkshere": "Amul wenn xët wu lëkkalook wii <b>$1</b>.",
+       "nolinkshere-ns": "Amul wenn xët wu lëkkalook wii '''$2''' ci barabu tur bi nga tànn.",
        "isredirect": "Xëtu jubluwaat",
        "istemplate": "mboole",
        "isimage": "lëkkalekaayu dencukaay bi",
index 0136f2e..c1642fa 100644 (file)
        "whatlinkshere": "链进来点啥",
        "whatlinkshere-title": "链接到“$1”个页面",
        "whatlinkshere-page": "页面:",
-       "linkshere-2": "下头个页链到$1:",
-       "nolinkshere-2": "呒不页面链到<strong>$1</strong>。",
+       "linkshere": "下头个页链到$1:",
+       "nolinkshere": "呒不页面链到<strong>$1</strong>。",
        "isredirect": "转戳页",
        "istemplate": "包括",
        "isimage": "文件鏈接",
index 8fb37e0..5709fc5 100644 (file)
        "whatlinkshere": "Эн һазрур заалһуд",
        "whatlinkshere-title": "«$1» гидг нерәдлһтә халхд заалдг халхс",
        "whatlinkshere-page": "Халх:",
-       "linkshere-2": "Тер халхс '''$1''' халхд заалдг:",
+       "linkshere": "Тер халхс '''$1''' халхд заалдг:",
        "isredirect": "авч оддг халх",
        "istemplate": "оруллһн",
        "isimage": "зургин  заалһ",
index 1930403..0dd1dcf 100644 (file)
        "whatlinkshere": "სოვრეშე რე თე ხასჷლა წურაფილი",
        "whatlinkshere-title": "ხასჷლეფი, ნამუთ გინორცხილ რე $1-შა",
        "whatlinkshere-page": "ხასჷლა:",
-       "linkshere-2": "გეჸვენჯ ხასჷლეფი გინარცხუაფუ '''$1'''-ეფს",
-       "nolinkshere-2": "ნამთინ ხასილა ვა რე გინორცხილ '''$1'''-შა.",
+       "linkshere": "გეჸვენჯ ხასჷლეფი გინარცხუაფუ '''$1'''-ეფს",
+       "nolinkshere": "ნამთინ ხასილა ვა რე გინორცხილ '''$1'''-შა.",
        "isredirect": "გინოწურაფაშ ხასჷლა",
        "istemplate": "ტრანსკლუზია",
        "isimage": "ფაილიშ რცხი",
index 200fc66..4d3ec30 100644 (file)
        "resetpass-submit-loggedin": "טוישן פאסווארט",
        "resetpass-submit-cancel": "אַנולירן",
        "resetpass-wrong-oldpass": "אומגילטיג צײַטווײַליק אדער לויפֿיק פאַסווארט.\nאיר האט מעגלעך שוין געטוישט אייער פאַסווארט אדער געבעטן א נײַ  צײַטווײַליק פאַסווארט.",
-       "resetpass-recycled": "×\96ײַ×\98 ×\90×\96×\95×\99 ×\92×\95×\98 ×©×\98×¢×\98×\9c ×\90×\99רע ×¤×\90ס×\95×\95×\90ר×\98 ×¦×\95 ×¢×¤×¢×¡ ×\90× ×\93ערש ×¤×\95× ×¢×\9d ×\9c×\95×\99פ×\99ק×\9f ×¤×\90ס×\95×\95×\90רט.",
+       "resetpass-recycled": "×\96×\99×\99×\98 ×\90Ö·×\96×\95×\99 ×\92×\95×\98, ×\91×\99×\99×\98 ×\90×\99×\99ער ×¤Ö¼×\90ַס×\95×\95×\90ָר×\98 ×\90×\95×\99×£ ×¢×¤Ö¼×¢×¡ ×\90Ö·× ×\93ערש ×¤×\95×\9f ×\9c×\95×\99פ×\99ק×\9f ×¤Ö¼×\90ַס×\95×\95×\90Ö¸רט.",
        "resetpass-temp-emailed": "איר האט זיך ארי לאגירת מיט א פראוויזארישן קאד געשיקט דורכן ע־פאסט. כדי שליסן דאס ארײַנלאגירן, דארט איר שטעלן א נײַ פאסווארט דא.",
        "resetpass-temp-password": "צײַטווייליק פאַסווארט:",
        "resetpass-abort-generic": "פאסווארט ענדערונג איז מבוטל געווארן דורך א פארברייטערונג.",
        "resetpass-expired": "אירע פאסווארט איז אויסגעגאנגען. זײַט אזוי גוט שטעלט א נײַ פאסווארט כדי ארײַנלאגירן.",
-       "resetpass-expired-soft": "×\90ײַער ×¤×\90ס×\95×\95×\90ר×\98 ×\90×\99×\96 ×\90×\95×\99ס×\92×¢×\92×\90× ×\92×¢×\9f ×\90×\95×\9f ×\93×\90רף ×\95×\95ער×\9f ×¦×\95ר×\99ק×\92עש×\98×¢×\9c×\98. ×\96ײַ×\98 ×\90×\96×\95×\99 ×\92×\95×\98 ×§×\9c×\95×\99×\91×\98 ×\90 × ×²Ö· ×¤×\90ס×\95×\95×\90ר×\98 ×\90צ×\99× ×\93, ×\90×\93ער ×§×\9c×\99ק×\98 \"{{int:authprovider-resetpass-skip-label}}\" ×\9b×\93×\99 ×¢×¡ ×¦×\95ר×\99קש×\98×¢×\9c×\9f ×©×¤עטער.",
-       "resetpass-validity-soft": "×\90ײַער ×¤×\90ס×\95×\95×\90ר×\98 ×\90×\99×\96 × ×\99ש×\98 ×\92×\99×\9c×\98×\99ק: $1\n\n×\96ײַ×\98 ×\90×\96×\95×\99 ×\92×\95×\98 ×§×\9c×\95×\99×\91×\98 ×\90 × ×²Ö· ×¤×\90ס×\95×\95×\90ר×\98 ×\90צ×\99× ×\93, ×\90×\93ער ×§×\9c×\99ק×\98 \"{{int:authprovider-resetpass-skip-label}}\" ×\9b×\93×\99 ×¢×¡ ×¦×\95ר×\99קש×\98×¢×\9c×\9f ×©×¤עטער.",
+       "resetpass-expired-soft": "×\90×\99×\99ער ×¤Ö¼×\90ַס×\95×\95×\90ָר×\98 ×\90×\99×\96 ×\90×\95×\99ס×\92×¢×\92×\90Ö·× ×\92×¢×\9f ×\90×\95×\9f ×\93×\90ַרף ×¦×\95ר×\99ק×\92עש×\98×¢×\9c×\98 ×\95×\95ער×\9f. ×\96×\99×\99×\98 ×\90Ö·×\96×\95×\99 ×\92×\95×\98, ×§×\9c×\99×\99×\91×\98 ×\90Ö· × ×\99×\99 ×¤Ö¼×\90ַס×\95×\95×\90ָר×\98 ×\90ַצ×\99× ×\93, ×\90Ö¸×\93ער ×§×\9c×\99ק×\98 \"{{int:authprovider-resetpass-skip-label}}\" ×\9b×\93×\99 ×¦×\95 ×\91×\99×\99×\98×\9f ×¢×¡ ×©×¤Ö¼עטער.",
+       "resetpass-validity-soft": "×\90×\99×\99ער ×¤Ö¼×\90ַס×\95×\95×\90ָר×\98 ×\90×\99×\96 × ×\99×\98 ×\92×\99×\9c×\98×\99ק: $1\n\n×\96×\99×\99×\98 ×\90Ö·×\96×\95×\99 ×\92×\95×\98 ×§×\9c×\99×\99×\91×\98 ×\90Ö· × ×\99×\99 ×¤Ö¼×\90ַס×\95×\95×\90ָר×\98 ×\90ַצ×\99× ×\93, ×\90Ö¸×\93ער ×§×\9c×\99ק×\98 \"{{int:authprovider-resetpass-skip-label}}\" ×\9b×\93×\99 ×¦×\95 ×\91×\99×\99×\98×\9f ×¢×¡ ×©×¤Ö¼עטער.",
        "passwordreset": "צוריקשטעלן פאַסווארט",
        "passwordreset-text-one": "דערגאַנצט די פאָרעם צוריקצושטעלן אײַער פאַסווארט.",
        "passwordreset-text-many": "{{PLURAL:$1|דערגאַנצט איינע פֿון די פֿעלדער כדי צו באקומען א פראוויזאריש פאַסווארט דור כן פאסט.}}",
        "previewerrortext": "א פעלער האט פאסירט ביים פרובירן פארויסקוקן אײַערע ענדערונגען.",
        "blockedtitle": "באַניצער איז בלאקירט",
        "blockedtext": "'''אייער באניצער נאמען אדער IP אדרעס איז געווארן בלאקירט.'''\n\nדעם בלאק האט $1 געמאכט פון וועגן ''$2''.\n\n* בלאקירן הייבט אן: $8\n* בלאקירן גייט אויס: $6\n* בלאק מכוון צו: $7\n\nאיר קענט זיך ווענדן צו $1 אדער צו אנדערע [[{{MediaWiki:Grouppage-sysop}}|אדמיניסטראטארן]] אדורכצורעדן דעם בלאק.\n\nגיט אכט אז איר קענט נישט ניצן די \"שיקט דעם באניצער א ע-פאסט\" אייגנקייט אויב האט איר נישט איינגעשטעלט אין אייערע [[Special:Preferences|קונטע פרעפערענצן]] א גילטיקן בליצפאסט אדרעסדאס אדער איר זענט בלאקירט פון שיקן בליצפאסט.\n\nאייער IP אדרעס איז $3, און דער בלאק האט נומער #$5. ביטע שיקט איינעם פון די צוויי (אדער זיי ביידע) ווען איר ווענדט זיך צו די אדמיניסטראטורן.",
-       "autoblockedtext": "אײַער [[IP אדרעס|אײַ־פּי־אַדרעס]] איז בלאָקירט געװאָרן אױטאָמאַטיש, צוליב דעם װאָס אַן אַנדער באַניצער װאָס איז בלאָקירט געװאָרן דורך $1 האָט זיך געניצט דעם דאָזיקן אײַ־פּי.\nדי אורזאַך פֿון דער בלאָקירונג איז:\n\n:'''$2'''\n\n* אנהייב פון דער בלאקירונג: $8\n* ענדע פון דער בלאָקירונג: $6\n* וועמען בלאקירט: ִ$7\n\nאיר קענט זיך פֿאַרבינדן דורכן בליצבריװ מיט $1 אָדער מיט יעדן אַנדערן [[{{MediaWiki:Grouppage-sysop}}|סיסאָפּ]] צו דיסקוטירן װעגן דער בלאָקירונג.\n\nאױב האָט איר ניט אַרײַנגעקלאַפּט אײַער בליצפּאָסט־אַדרעס אין אײַערע [[Special:Preferences|פּרעפֿערענצן]] אדער איר זענט בלאקירט פון שיקן בליצפאסט, קענט איר זיך ''נישט'' ניצן די אפציע \"שיקט דעם באניצער אן ע-פאסט\".\n\nאייער יעצטיגער IP אדרעס איז $3, און דער בלאָקירונג־נומער איז #$5.\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, און דער בלאָקירונג־נומער איז #$5.\nביטע צײכנט עס אָן בשעת איר װענדט זיך צו די סיסאָפּן.",
        "blockednoreason": "קיין טעם נישט געגעבן",
        "whitelistedittext": "איר ברויכט צו $1 צו ענדערן בלעטער.",
        "confirmedittext": "אויף אייך ליגט קודם די פֿליכט צו באשטעטיגן אייער ע־פאסט אדרעס איידער איר רעדאַקטירט בלעטער.\nביטע שטעלט און באשטעטיגט אייער ע־פאסט אדרעס דורך אייערע [[Special:Preferences|באַניצער פרעפֿערענצן]] .",
        "rcfilters-savedqueries-defaultlabel": "אױפֿגעהיטענע פֿילטערס",
        "rcfilters-savedqueries-rename": "ענדערן נאמען",
        "rcfilters-savedqueries-setdefault": "האלטן ווי גרונט",
-       "rcfilters-savedqueries-remove": "×\90ר×\90פנע×\9e×¢ן",
+       "rcfilters-savedqueries-remove": "×\90×\95×\99ס×\9eעקן",
        "rcfilters-savedqueries-new-name-label": "נאָמען",
        "rcfilters-savedqueries-apply-label": "שאפן פילטער",
        "rcfilters-savedqueries-cancel-label": "אַנולירן",
        "rcfilters-empty-filter": "קיין אַקטיווע פילטערס. אלע ביישטייערונגען געוויזן.",
        "rcfilters-filterlist-title": "פֿילטערס",
        "rcfilters-filterlist-whatsthis": "ווי ארבעט דאס?",
+       "rcfilters-filterlist-feedbacklink": "זאָגט אונדז וואָס איז אייער מיינונג בנוגע פילטער אינסטרומענטן",
        "rcfilters-highlightbutton-title": "ארויסשטאַרצן רעזולטאַטן",
        "rcfilters-highlightmenu-title": "אויסקלויבן א קאליר",
        "rcfilters-filterlist-noresults": "קיין פֿילטערס נישט געטראפֿן",
        "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": "רעדאקטירונגען וואס דער שרייבער האט מארקירט פֿארמינערט.",
        "rcfilters-filter-watchlist-watched-label": "אויף דער אויפֿפאַסונג ליסטע",
        "rcfilters-filter-watchlist-notwatched-label": "נישט אויף דער אויפֿפאַסונג ליסטע",
        "rcfilters-filtergroup-changetype": "טיפ ענדערונג",
        "rcfilters-filter-previousrevision-label": "נישט די לעצטע ווערסיעס",
        "rcfilters-filter-excluded": "אויסגעשלאסן",
        "rcfilters-tag-prefix-namespace-inverted": "<strong>:נישט</strong> $1",
+       "rcfilters-exclude-button-off": "אויסשליסן געוויילטע",
        "rcfilters-view-tags": "מאַרקירטע רעדאַקטירונגען",
        "rcfilters-liveupdates-button": "לעבעדיקע דערהיינטיקונגען",
        "rcfilters-target-page-placeholder": "אײַנגעבן א בלאטנאמען (אדער קאטעגאריע)",
        "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]] צוגעלייגט צו קאטעגאריע",
        "apisandbox-retry": "פרובירן נאכאמאל",
        "apisandbox-helpurls": "הילף לינקען",
        "apisandbox-examples": "ביישפילן",
+       "apisandbox-dynamic-parameters-add-label": "צולייגן פאראמעטער:",
+       "apisandbox-dynamic-parameters-add-placeholder": "פאראמעטער נאמען",
+       "apisandbox-dynamic-error-exists": "ס׳איז שוין פֿאראן א פאראמעטער מיטן נאמען \"$1.",
+       "apisandbox-deprecated-parameters": "פֿארעלטערטע פאראמעטערס",
+       "apisandbox-add-multi": "צולייגן",
+       "apisandbox-submit-invalid-fields-title": "טייל פֿעלדער זענען אומגילטיק",
        "apisandbox-results": "רעזולטאטן",
+       "apisandbox-continue": "פֿארזעצן",
+       "apisandbox-continue-clear": "רייניקן",
+       "apisandbox-multivalue-all-namespaces": "$1 (אלע נאמענטיילן)",
+       "apisandbox-multivalue-all-values": "$1 (אלע ווערטן)",
        "booksources": "דרויסנדיגע ליטעראַטור ISBN",
        "booksources-search-legend": "זוכן פאר דרויסנדע ביכער מקורות",
        "booksources-search": "זוכן",
        "logempty": "נישטא קיין פאַסנדיקע זאכן אין לאג.",
        "log-title-wildcard": "זוכן טיטלען וואס הייבן אָן מיט דעם טעקסט",
        "showhideselectedlogentries": "ווײַזן/באַהאַלטן געקליבענע לאגבוך אקציעס",
+       "checkbox-select": "אויסוויילן: $1",
        "checkbox-all": "אַלע",
        "checkbox-none": "קיינע",
        "checkbox-invert": "אומקערן",
        "whatlinkshere": "װאָס פֿאַרבינדט אַהער",
        "whatlinkshere-title": "בלעטער וואס פֿארבינדן צו $1",
        "whatlinkshere-page": "בלאַט:",
-       "linkshere-2": "די פאלגנדע בלעטער פארבינדן צום בלאט '''$1''':",
-       "nolinkshere-2": "קיין שום בלאט פארבינדט נישט צו '''$1'''.",
-       "nolinkshere-ns-2": "קיין בלעטער פֿאַרבינדן נישט צו '''$1''' אינעם אויסגעקליבענעם נאמענטייל.",
+       "linkshere": "די פאָלגנדיקע בלעטער פאַרבינדן צום בלאַט '''$1''':",
+       "nolinkshere": "קיין שום בלאַט פאַרבינדט נישט צו '''$1'''.",
+       "nolinkshere-ns": "קיין בלעטער פאַרבינדן נישט צו <strong>$2</strong> אינעם אויסגעקליבענעם נאָמענטייל.",
        "isredirect": "ווײַטערפירן בלאט",
        "istemplate": "אײַנשליסן",
        "isimage": "!טעקע לינק",
        "unblocked-id": "בלאק $1 איז געווארן אַראָפגענומען.",
        "unblocked-ip": "[[Special:Contributions/$1|$1]] איז געווארן אויפבלאקירט.",
        "blocklist": "בלאקירטע באַניצער",
+       "autoblocklist-submit": "זוכן",
        "ipblocklist": "בלאקירטע באַניצער",
        "ipblocklist-legend": "געפֿינען א בלאקירטן באניצער",
        "blocklist-userblocks": "באהאלטן קאנטע בלאקן",
        "unlockdbsuccesssub": "דאטנבאזע שלאס אראפגענומען",
        "lockdbsuccesstext": "די דאטנבאזע איז געשלאסן .<br />\nגעדענקט [[Special:UnlockDB|אוועקנעמען דעם שלאס ]] ווען אייער אויפהאלטונד איז געענדיקט.",
        "unlockdbsuccesstext": "די דאַטנבאַזע איז געווארן אויפֿגעשלאסן",
+       "databaselocked": "די דאַטנבאַזע איז שוין פֿאַרשלאסן.",
        "databasenotlocked": "די דאַטנבאַזע איז נישט פֿאַרשלאסן.",
        "lockedbyandtime": "(דורך $1 אום $2 בײַ $3)",
        "move-page": "באַוועגן $1",
        "cant-move-to-user-page": "איר זענט נישט דערלויבט צו באַוועגן א בלאַט צו א באַניצער בלאַט (אַחוץ צו א באַניצער אונטערבלאַט).",
        "cant-move-category-page": "איר זענט נישט דערלויבט צו באוועגן קאטעגאריע בלעטער.",
        "cant-move-to-category-page": "איר זענט נישט ערלויבט צו באוועגן א בלאט צו קאטעגאריע־בלאט.",
+       "cant-move-subpages": "איר זענט נישט דערלויבט צו באוועגן אונטערבלעטער.",
+       "namespace-nosubpages": "נאמענטייל \"$1\" ערלויבט נישט קיין אונטערבלעטער.",
        "newtitle": "נייע קעפל:",
        "move-watch": "אויפֿפאַסן אויף דעם בלאַט",
        "movepagebtn": "באַוועגן בלאַט",
        "pageinfo-language": "בלאט אינהאלט שפראך",
        "pageinfo-language-change": "ענדערן",
        "pageinfo-content-model": "בלאט אינהאלט מאדעל",
+       "pageinfo-content-model-change": "טוישן",
        "pageinfo-robot-policy": "אינדעקסירן דורך ראבאטן",
        "pageinfo-robot-index": "דערלויבט",
        "pageinfo-robot-noindex": "נישט דערלויבט",
        "markedaspatrollednotify": "די ענדערונג צו $1 איז געווארן מארקירט ווי קאנטראלירט.",
        "markedaspatrollederrornotify": "מארקירן ווי קאנטראלירט דורכגעפאלן.",
        "patrol-log-page": "פאטראלירן לאג-בוך",
-       "patrol-log-header": "דאס איז א לאג-בוך פון פאַטראליטע רעוויזיעס.",
-       "log-show-hide-patrol": "$1 פאַטראלירן לאג-בוך",
-       "log-show-hide-tag": "$1 טאג־לאגבוך",
+       "patrol-log-header": "דאס איז א לאג-בוך פון פאַטראלירטע רעוויזיעס.",
+       "confirm-markpatrolled-button": "יאָ",
        "confirm-markpatrolled-top": "מארקירן $3 פון $2 ווי קאנטראלירט?",
        "deletedrevision": "אויסגעמעקט אלטע ווערסיע $1.",
        "filedeleteerror-short": "גרייז ביים אויסמעקן טעקע: $1",
        "newimages-legend": "פֿילטער",
        "newimages-label": "טעקע נאָמען (אדער אַ טײל דערפֿון):",
        "newimages-showbots": "ווײַזן ארויפלאדן פון באטן",
+       "newimages-mediatype": "מעדיע־טיפ:",
        "noimages": "נישטא קיין בילדער.",
        "ilsubmit": "זוכן",
        "bydate": "לויטן דאטום",
        "log-action-filter-protect-unprotect": "אראפנעמען שיץ",
        "authmanager-userdoesnotexist": "באניצער קאנטע \"$1\" איז נישט איינגעשריבן.",
        "authmanager-realname-label": "עכטער נאָמען",
+       "authprovider-resetpass-skip-label": "איבערהיפן",
        "revid": "רעוויזיע $1"
 }
index 0618976..7ad682b 100644 (file)
@@ -9,7 +9,8 @@
                        "Macofe",
                        "Matma Rex",
                        "Wikicology",
-                       "Fitoschido"
+                       "Fitoschido",
+                       "Olaniyan Olushola"
                ]
        },
        "tog-underline": "Ìfàlàsábẹ́ àwọn àjápọ̀:",
        "recentchanges": "Àwọn àtúnṣe tuntun",
        "recentchanges-legend": "Àwọn àṣàyàn fún àtúnṣe tuntun",
        "recentchanges-summary": "Ẹ tẹ̀ lé àwọn àtúnṣe tuntun sí wiki lórí ojúewé yìí.",
+       "recentchanges-noresult": "Kò sì áwọ́n iyipada ni akókò yì ti o ba àwon ìlànà yí mu.",
        "recentchanges-feed-description": "Ẹ tẹ̀ lé àwọn àtúnṣe àìpẹ́ ọjọ́ sí wiki nínú àkótán feed yìí.",
        "recentchanges-label-newpage": "Àtúnṣe yìí dá ojúewé tuntun",
        "recentchanges-label-minor": "Àtùnṣe kékeré nìyí",
        "whatlinkshere": "Ìjápọ̀ mọ́ ojúewé yí",
        "whatlinkshere-title": "Àwọn ojúewé tó jápọ̀ mọ́ \"$1\"",
        "whatlinkshere-page": "Ojúewé:",
-       "linkshere-2": "Àwọn ojúewé wọ̀nyí jápọ̀ mọ́ '''$1''':",
-       "nolinkshere-2": "Kò sí ojúewé tó jápọ̀ mọ́ '''$1'''.",
-       "nolinkshere-ns-2": "Kò sí ojúewé kankan tó jápọ̀ mọ́ '''$1''' nínú orúkọàyè yíyàn.",
+       "linkshere": "Àwọn ojúewé wọ̀nyí jápọ̀ mọ́ '''$1''':",
+       "nolinkshere": "Kò sí ojúewé tó jápọ̀ mọ́ '''$1'''.",
+       "nolinkshere-ns": "Kò sí ojúewé kankan tó jápọ̀ mọ́ '''$2''' nínú orúkọàyè yíyàn.",
        "isredirect": "àtúnjúwe ojúewé",
        "istemplate": "ìkómọ́ra",
        "isimage": "ìjápọ̀ fáìlì",
        "markedaspatrollederrornotify": "Ìkùnà ìṣàmìsí bíi sísọ́.",
        "patrol-log-page": "Àkọọ́lẹ̀ ìsọ́",
        "patrol-log-header": "Àkọọ́lẹ̀ àwọn àtúnyẹ̀wò sísọ́ nì yí.",
-       "log-show-hide-patrol": "$1 àkọọ́lẹ̀ ìsọ́",
        "confirm-markpatrolled-button": "OK",
        "deletedrevision": "Àtúnyẹ̀wò àtijọ́ píparẹ́ $1",
        "filedeleteerror-short": "Àsìṣe ìparẹ́ fáílì: $1",
index b7c88ff..9cf7059 100644 (file)
@@ -33,7 +33,9 @@
                        "Asdfugil",
                        "Deryck Chan",
                        "Hello903hello",
-                       "Fitoschido"
+                       "Fitoschido",
+                       "Kanashimi",
+                       "Roy17"
                ]
        },
        "tog-underline": "連結加底線:",
        "cascadeprotected": "呢一版已經保護咗唔能夠編輯,因為佢係響以下嘅{{PLURAL:$1|一|幾}}頁度包含咗,當中啟用咗\"連串\"保護選項來保護嗰一版: $2",
        "namespaceprotected": "你無權編輯響'''$1'''空間名裏面嘅呢一版。",
        "customcssprotected": "你無權改呢版CSS,因為佢包含其他用戶嘅個人設定。",
+       "customjsonprotected": "你無權改呢版JSON,因為佢包含其他用戶嘅個人設定。",
        "customjsprotected": "你無權改呢版JavaScript,因為佢包含其他用戶嘅個人設定。",
        "mycustomcssprotected": "你無權改呢版CSS。",
+       "mycustomjsonprotected": "你無權改呢版JSON。",
        "mycustomjsprotected": "你無權改呢版JavaScript。",
        "myprivateinfoprotected": "你無權改呢版你嘅私人資料。",
        "mypreferencesprotected": "你無權改呢版你嘅個人設定。",
        "botpasswords-deleted-body": "{{GENDER:$2|用戶}}「$2」嘅機械人「$1」嘅密碼已經剷走咗。",
        "botpasswords-restriction-failed": "機械人密碼限制令到呢次簽到失敗。",
        "botpasswords-invalid-name": "呢個用戶名無機械人密碼分隔字(「$1」)",
+       "botpasswords-not-exist": "用戶「$1」無叫做「$2」嘅機械人密碼。",
+       "botpasswords-needs-reset": "{{GENDER:$1|用戶}}「$1」嘅機械人「$2」嘅密碼一定要重新改。",
        "resetpass_forbidden": "唔可以更改密碼",
        "resetpass_forbidden-reason": "改唔到密碼:$1",
        "resetpass-no-info": "你一定要登入咗去直接入來呢一版。",
        "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-soft": "你個密碼無效: $1\n\n請揀個新密碼,或者去\"{{int:authprovider-resetpass-skip-label}}\" 轉頭再設過。",
        "passwordreset": "密碼重設",
        "passwordreset-text-one": "填好呢份表格去申請將臨時密碼經電郵送畀你。",
        "subject-preview": "主題預覽:",
        "previewerrortext": "預覽你嘅修改嗰陣出錯。",
        "blockedtitle": "用戶已經封鎖",
-       "blockedtext": "你嘅用戶名或者 IP 位址已經被 $1 封咗。\n\n呢次封鎖係由$1所封嘅。當中嘅原因係''$2''。\n\n* 呢次封鎖嘅開始時間係:$8\n* 呢次封鎖嘅到期時間係:$6\n* 對於被封鎖者:$7\n\n你可以聯絡 $1 或者其他嘅[[{{MediaWiki:Grouppage-sysop}}|管理員]],討論呢次封鎖。\n除非你已經響你嘅[[Special:Preferences|戶口喜好設定]]入面設定咗有效嘅電郵地址,否則你係唔可以用「電郵呢個用戶」嘅功能。當設定咗一個有效嘅電郵地址之後,呢個功能係唔會封鎖嘅。\n\n你現時嘅 IP 位址係 $3 ,而個封鎖 ID 係 #$5。 請你喺你嘅查詢都註明以上封鎖嘅資料。",
-       "autoblockedtext": "你嘅IP地址已經被自動封鎖,由於之前嘅另一位用戶係畀$1封咗。\n而封鎖嘅原因係:\n\n:''$2''\n\n* 呢次封鎖嘅開始時間係:$8\n* 呢次封鎖嘅到期時間係:$6\n* 對於被封鎖者:$7\n\n你可以聯絡 $1 或者其他嘅[[{{MediaWiki:Grouppage-sysop}}|管理員]],討論呢次封鎖。\n\n除非你已經響你嘅[[Special:Preferences|戶口喜好設定]]入面設定咗有效嘅電郵地址,否則你係唔可以用「電郵呢個用戶」嘅功能。當設定咗一個有效嘅電郵地址之後,呢個功能係唔會封鎖嘅。\n\n你現時用緊嘅 IP 地址係 $3,個封鎖 ID 係 #$5。 請喺你嘅查詢都註明呢個封鎖上面嘅資料。",
+       "blockedtext": "<strong>你嘅用戶名或者IP地址已經俾人封咗。</strong>\n\n呢次封鎖係由$1所封嘅。\n俾咗嘅原因係<em>$2</em>。\n\n* 呢次封鎖嘅開始時間係:$8\n* 呢次封鎖嘅到期時間係:$6\n* 被封鎖者:$7\n\n你可以聯絡 $1 或者其他嘅[[{{MediaWiki:Grouppage-sysop}}|管理員]]討論呢次封鎖。\n除非你已經響你嘅[[Special:Preferences|戶口喜好設定]]入面設定咗有效嘅電郵地址,否則你係唔可以用「{{int:emailuser}}」嘅功能。當設定咗一個有效嘅電郵地址之後,呢個功能係唔會被封鎖嘅。\n你現時嘅IP地址係 $3 ,而個封鎖ID係 #$5。\n請喺你嘅查詢都註明以上封鎖嘅資料。",
+       "autoblockedtext": "你嘅IP地址已經被自動封鎖,原因係之前嘅另一位用戶係畀$1封咗。\n而封鎖嘅原因係:\n\n:''$2''\n\n* 呢次封鎖嘅開始時間係:$8\n* 呢次封鎖嘅到期時間係:$6\n* 對於被封鎖者:$7\n\n你可以聯絡 $1 或者其他嘅[[{{MediaWiki:Grouppage-sysop}}|管理員]],討論呢次封鎖。\n\n除非你已經響你嘅[[Special:Preferences|戶口喜好設定]]入面設定咗有效嘅電郵地址,否則你係唔可以用「電郵呢個用戶」嘅功能。當設定咗一個有效嘅電郵地址之後,呢個功能係唔會封鎖嘅。\n\n你現時用緊嘅 IP 地址係 $3,個封鎖 ID 係 #$5。 請喺你嘅查詢都註明呢個封鎖上面嘅資料。",
        "systemblockedtext": "你嘅用戶名或者IP地址已經俾MediaWiki自動封鎖。\n封鎖原因係:\n\n:<em>$2</em>\n\n* 開始時間:$8\n* 到期時間:$6\n* 目標用戶:$7\n\n你而家嘅IP地址係$3。\n當你作出任何查詢嘅時候,請包含以上所有資料。",
        "blockednoreason": "無原因畀低",
        "whitelistedittext": "你需要$1去編輯呢頁。",
        "post-expand-template-argument-warning": "警告: 呢一版有最少一個模參數有太大嘅擴展大細。\n呢啲參數會被略過。",
        "post-expand-template-argument-category": "包含住略過模參數嘅版",
        "parser-template-loop-warning": "已偵測迴模: [[$1]]",
+       "template-loop-category": "有循環模嘅頁",
        "parser-template-recursion-depth-warning": "迴模深度限制超過咗 ($1)",
        "language-converter-depth-warning": "字體變換器深度限制超過咗 ($1)",
        "node-count-exceeded-category": "有頁面超出咗指定數",
        "prefs-dateformat": "日期格式",
        "prefs-timeoffset": "時間偏移",
        "prefs-advancedediting": "普通選項",
+       "prefs-developertools": "開發者工具",
        "prefs-editor": "編輯",
        "prefs-preview": "預覽",
        "prefs-advancedrc": "進階選項",
        "right-editcontentmodel": "改版面嘅內容模型",
        "right-editinterface": "編輯用戶界面",
        "right-editusercss": "編輯其他用戶嘅CSS檔",
+       "right-edituserjson": "編輯其他用戶嘅JSON檔",
        "right-edituserjs": "編輯其他用戶嘅JavaScript檔",
-       "right-editmyusercss": "編輯戶口嘅CSS文件",
-       "right-editmyuserjs": "編輯戶口嘅JavaScript文件",
+       "right-editmyusercss": "編輯你自己嘅用戶CSS檔",
+       "right-editmyuserjson": "編輯你自己嘅用戶JSON檔",
+       "right-editmyuserjs": "編輯你自己嘅用戶JavaScript檔",
        "right-viewmywatchlist": "睇你自己嘅監視一覽",
        "right-viewmyprivateinfo": "睇下個人信息(例如電郵或真名)",
        "right-editmyprivateinfo": "修改個人信息(例如電郵或真名)",
        "right-sendemail": "寄電郵畀其他用戶",
        "right-managechangetags": "開同(取消)啟用[[Special:Tags|標籤]]",
        "right-applychangetags": "套用[[Special:Tags|標籤]]到某個人嘅改動",
+       "right-deletechangetags": "由資料庫刪[[Special:Tags|標籤]]",
+       "grant-generic": "「$1」權限組合",
        "grant-group-page-interaction": "同版面互動",
        "grant-group-file-interaction": "同傳媒互動",
        "grant-group-watchlist-interaction": "同監視清單互動",
        "grant-group-email": "送電郵",
+       "grant-group-high-volume": "執行大量活動",
        "grant-group-customization": "自訂同設定",
        "grant-group-administration": "做管理行動",
        "grant-group-private-information": "存取你嘅私隱資料",
        "grant-editmywatchlist": "改你嘅監視清單",
        "grant-editpage": "改已經有嘅版",
        "grant-editprotected": "改保護咗嘅版",
+       "grant-highvolume": "大量編輯",
+       "grant-oversight": "收埋用戶同禁止顯示修訂",
+       "grant-sendemail": "寄電郵畀其他用戶",
        "grant-uploadfile": "上載新檔案",
        "grant-basic": "基本權利",
+       "grant-viewdeleted": "睇刪咗嘅檔同頁",
        "grant-viewmywatchlist": "睇你嘅監視清單",
        "newuserlogpage": "使用者開戶記錄",
        "newuserlogpagetext": "呢個係一個使用者開戶嘅日誌",
        "action-editcontentmodel": "改頁面內容模型",
        "action-managechangetags": "從數據庫開或刪走啲符",
        "action-applychangetags": "套用標籤到你嘅改動",
+       "action-purge": "清呢版個快取版本",
        "nchanges": "$1次更改",
        "enhancedrc-since-last-visit": "{{PLURAL:$1|你上次嚟之後}}有 $1 個",
        "enhancedrc-history": "歷史",
        "recentchanges-label-unpatrolled": "呢次編輯重未巡查過",
        "recentchanges-label-plusminus": "頁面位元組大細變化",
        "recentchanges-legend-heading": "<strong>標記:</strong>",
-       "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (睇埋[[Special:NewPages|新開版]])",
+       "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (睇埋[[Special:NewPages|新版一覽]])",
        "recentchanges-submit": "顯示",
        "rcfilters-tag-remove": "剷走 $1",
        "rcfilters-legend-heading": "<strong>縮寫一覽:</strong>",
        "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",
        "rcfilters-savedqueries-rename": "改名",
        "rcfilters-savedqueries-setdefault": "設做預設",
        "rcfilters-savedqueries-unsetdefault": "唔再設做預設",
-       "rcfilters-savedqueries-remove": "拎走",
+       "rcfilters-savedqueries-remove": "",
        "rcfilters-savedqueries-new-name-label": "名",
        "rcfilters-savedqueries-new-name-placeholder": "形容篩選條件嘅用途",
        "rcfilters-savedqueries-apply-label": "開個新嘅篩選條件",
        "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": "作者話程度細嘅修改。",
        "whatlinkshere": "有乜嘢連結來呢度",
        "whatlinkshere-title": "連到「$1」嘅頁",
        "whatlinkshere-page": "頁:",
-       "linkshere-2": "呢啲頁連結到'''$1''':",
-       "nolinkshere-2": "無一頁連結到'''$1'''。",
-       "nolinkshere-ns-2": "響已經揀咗嘅空間名無嘢連結到'''$1'''。",
+       "linkshere": "呢啲頁連結到'''$1''':",
+       "nolinkshere": "無一頁連結到'''$1'''。",
+       "nolinkshere-ns": "響已經揀咗嘅空間名無嘢連結到'''$2'''。",
        "isredirect": "跳轉頁",
        "istemplate": "包含",
        "isimage": "檔案連結",
        "markedaspatrollederrornotify": "標做睇過失敗。",
        "patrol-log-page": "巡查日誌",
        "patrol-log-header": "呢個係已經巡查過嘅日誌。",
-       "log-show-hide-patrol": "$1巡查紀錄",
        "confirm-markpatrolled-button": "好",
        "deletedrevision": "刪除咗$1嘅舊有修訂",
        "filedeleteerror-short": "刪除檔案出錯: $1",
        "watchlistedit-normal-legend": "響監視清單度拎走",
        "watchlistedit-normal-explain": "響你張監視清單度嘅標題響下面度顯示。要拎走一個標題,響佢前面剔一剔,跟住要撳『{{int:Watchlistedit-normal-submit}}』。你亦都可以[[Special:EditWatchlist/raw|編輯原始清單]]。",
        "watchlistedit-normal-submit": "拎走標題",
-       "watchlistedit-normal-done": "$1個標題已經響你嘅監視清單度拎走咗:",
+       "watchlistedit-normal-done": "響你嘅監視清單,拎走咗$1個標題:",
        "watchlistedit-raw-title": "編輯原始監視清單",
        "watchlistedit-raw-legend": "編輯原始監視清單",
        "watchlistedit-raw-explain": "你張監視清單嘅標題響下面度顯示,同時亦都可以透過編輯呢個表去加入同埋拎走標題;一行一個標題。當完成咗之後,撳{{int:Watchlistedit-raw-submit}}。你亦都可以去用[[Special:EditWatchlist|標準編輯器]]。",
        "authmanager-email-help": "電郵地址",
        "authmanager-realname-label": "真名",
        "authmanager-realname-help": "用戶嘅真名",
-       "authprovider-resetpass-skip-label": "跳過"
+       "authprovider-resetpass-skip-label": "跳過",
+       "passwordpolicies": "密碼政策",
+       "passwordpolicies-summary": "爾度係對爾個wiki定義咗嘅用戶組來講有效嘅密碼政策一覽。",
+       "passwordpolicies-group": "組",
+       "passwordpolicies-policies": "政策",
+       "passwordpolicies-policy-minimalpasswordlength": "密碼一定要有至少$1個{{PLURAL:$1|字元}}長",
+       "passwordpolicies-policy-minimumpasswordlengthtologin": "密碼一定要有至少$1個{{PLURAL:$1|字元}}長先可以簽到",
+       "passwordpolicies-policy-passwordcannotmatchusername": "密碼唔可以同用戶名一樣",
+       "passwordpolicies-policy-passwordcannotmatchblacklist": "密碼唔可以同列入咗黑名單嘅密碼一樣",
+       "passwordpolicies-policy-maximalpasswordlength": "密碼一定要短過$1個{{PLURAL:$1|字元}}長",
+       "passwordpolicies-policy-passwordcannotbepopular": "密碼唔可以{{PLURAL:$1|係最常見嘅密碼|喺最常見嘅$1個密碼一覽度}}"
 }
index a545f62..a26730f 100644 (file)
        "whatlinkshere": "Links nae deze bladzie",
        "whatlinkshere-title": "Pagina's die verwiez'n nir \"$1\"",
        "whatlinkshere-page": "Pagina:",
-       "linkshere-2": "De volhende pagina's verwieze nir '''$1''':",
-       "nolinkshere-2": "Hin enkele pagina verwies nir '''$1'''.",
+       "linkshere": "De volhende pagina's verwieze nir '''$1''':",
+       "nolinkshere": "Hin enkele pagina verwies nir '''$1'''.",
        "isredirect": "deurverwiespagina",
        "istemplate": "ingevoegd as sjabloon",
        "isimage": "bestandsverwiezienge",
index d72a4e9..7b7da4b 100644 (file)
@@ -7,16 +7,41 @@
                        "Mdb897",
                        "YesIn",
                        "ⵕⴰⵊⵉ",
-                       "Brahim-essaidi"
+                       "Brahim-essaidi",
+                       "Ya2sine"
                ]
        },
        "tog-underline": "ⵉⵣⵔⵉⵔⴳ ⴷⴷⵓ ⵓⵙⵖⵏ",
        "tog-hideminor": "ⵙⵙⵏⵜⵍ ⵜⵉⵙⵏⴼⵉⵍⵉⵏ ⵜⵉⵎⵥⵥⴰⵏⵉⵏ ⵙⴳ ⵉⵙⵏⴼⵍⵏ ⵉⵏⴳⴳⵓⵔⴰ",
+       "tog-hidepatrolled": "ⵙⵙⵏⵜⵍ ⵉⵙⵏⵉⴼⵉⵍⵏ ⵎⵉ ⵉⵜⵜⵓⴳⴰ ⵓⵣⵣⵔⴰⵢ ⴳ ⵉⵙⵏⵉⴼⵉⵍⵏ ⵉⵎⴳⴳⵓⵔⴰ",
+       "tog-newpageshidepatrolled": "ⵙⵙⵏⵜⵍ ⵜⴰⵙⵏⵉⵡⵉⵏ ⵎⵉ ⵉⵜⵜⵓⴳⴰ ⵓⵣⵣⵔⴰⵢ ⴳ ⵜⵍⴳⴰⵎⵜ ⵏ ⵜⴰⵙⵏⵉⵡⵉⵏ ⵜⵉⵎⴰⵢⵏⵓⵜⵉⵏ",
        "tog-hidecategorization": "ⵙⵙⵏⵜⵍ ⴰⵙⵎⵉⵍ ⵏ ⵜⴰⵙⵏⵉⵡⵉⵏ",
+       "tog-extendwatchlist": "ⵙⵙⵉⵔⵉⵡ ⵜⴰⵍⴳⴰⵎⵜ ⵏ ⵓⴹⴼⴼⵓⵔ ⴰⴼⴰⴷ ⴰⴷ ⵜⵙⴽⵏⴷ ⵉⵙⵏⵉⴼⵉⵍⵏ ⴰⴽⴽ ⵓⵔ ⴷ ⵖⴰⵙ ⵉⵎⴳⴳⵓⵔⴰ",
+       "tog-usenewrc": "ⵙⵎⵓⵏ ⵉⵙⵏⴼⵍⵏ ⴷ ⵜⴰⵙⵏⴰ ⵏⵙⵏ ⴳ ⵉⵙⵏⴼⵍⵏ ⵉⵎⴳⴳⵓⵔⴰ ⴷ ⵜⴰⵍⴳⴰⵎⵜ ⵏ ⵓⴹⴼⵓⵔ",
+       "tog-numberheadings": "ⴰⵙⵓⵟⵟⵏ ⴰⵡⵓⵔⵎⴰⵏ ⵏ ⵉⵣⵡⵍⴰⵏ",
+       "tog-showtoolbar": "ⵙⴽⵏ ⵜⴰⵙⵙⴼⵉⴼⵜ ⵏ ⵉⵎⴰⵙⵙⵏ ⵏ ⵓⵥⵔⴰⴳ",
+       "tog-editondblclick": "ⵙⵏⴼⵍ ⵜⴰⵙⵏⵉⵡⵉⵏ ⵙ ⵙⵉⵏ ⵉⴽⵍⵉⴽⵉⵜⵏ",
+       "tog-editsectiononrightclick": "ⵙⵙⵔⵎⴷ ⴰⵙⵏⴼⵍ ⵏ ⵜⵣⵓⵏⵉⵡⵉⵏ ⵙ ⵢⴰⵏ ⵓⴽⵍⵉⴽⵉ ⵖⴼ ⵉⵣⵡⵍⴰⵏ ⵏ ⵜⵣⵓⵏⵉ",
+       "tog-watchcreations": "ⵔⵏⵓ ⵖⵔ ⵜⴳⵍⴰⵎⵜ ⵉⵏⵓ ⵏ ⵓⴹⴼⴼⵓⵔ ⵜⴰⵙⵏⵉⵡⵉⵏ ⵏⵏⴰ ⵙⴽⵔⵖ ⴷ ⵉⴼⵓⵢⵍⴰ ⵏⵏⴰ ⴷ ⵙⴽⵛⵎⵖ",
+       "tog-watchdefault": "ⵔⵏⵓ ⵉ ⵜⵍⴳⴰⵎⵜ ⵉⵏⵓ ⵏ ⵓⴹⴼⴼⵓⵔ ⵜⴰⵙⵏⵉⵡⵉⵏ ⴷ ⵉⴼⵓⵢⵍⴰ ⵏⵏⴰ ⵙⵏⴼⴰⵍⵖ",
+       "tog-watchmoves": "ⵔⵏⵓ ⵜⴰⵙⵏⵉⵡⵉⵏ ⴷ ⵉⴼⵓⵢⵍⴰ ⵏⵏⴰ ⵙⵎⵓⵜⵜⵉⵖ ⵉ ⵜⵍⴳⴰⵎⵜ ⵉⵏⵓ ⵏ ⵓⴹⴼⴼⵓⵔ",
+       "tog-watchdeletion": "ⵔⵏⵓ ⵉ ⵜⴰⵙⵏⴰ ⵉⵏⵓ ⵏ ⵓⴹⴼⴼⵓⵔ ⵜⴰⵙⵏⵉⵡⵉⵏ ⴷ ⵉⴼⵓⵢⵍⴰ ⵏⵏⴰ ⴽⴽⵙⵖ",
+       "tog-watchuploads": "ⵔⵏⵓ ⵉⴼⵓⵢⵍⴰ ⵉⵎⴰⵢⵏⵓⵜⵏ ⵏⵏⴰ ⴷ ⵙⴽⵛⵎⵖ ⵉ ⵜⵍⴳⴰⵎⵜ ⵉⵏⵓ ⵏ ⵓⴹⴼⴼⵓⵔ",
+       "tog-watchrollback": "ⵔⵏⵓ ⵜⴰⵙⵏⵉⵡⵉⵏ ⵍⵍⵉ ⵅⴼ ⵙⴽⵔⵖ ⴰⵡⵔⵔⵉ ⵉ ⵜⵍⴳⴰⵎⵜ ⵏ ⵓⴹⴼⴼⵓⵔ ⵉⵏⵓ",
        "tog-minordefault": "ⵕⵛⵎ ⵎⴰⵕⵕⴰ ⵉⵙⵏⴼⵍⵏ ⵎⵥⵥⵉⵢⵏⵉⵏ ⵙ ⵓⵡⵏⵓⵍ",
+       "tog-previewontop": "ⵙⴽⵏ ⴰⴱⵔⵉⴼⵢⵓ ⵉⴳⴳⵉ ⵏ ⵓⴷⵖⴰⵔ ⵏ ⵓⵙⵏⴼⵍ",
+       "tog-previewonfirst": "ⵙⴽⵏ ⴰⴱⵔⵉⴱⵢⵓ ⴳ ⵓⵙⵏⴼⵍ ⵉⵣⵡⴰⵔⵏ",
+       "tog-enotifwatchlistpages": "ⴰⵣⵏ ⵢⵉ ⵏⵏ ⴳ ⵉⵎⴰⵢⵍ ⴰⴽⵓⴷ ⵏⵏⴰ ⵜⵡⴰⵙⵙⵏⴼⵍ ⴽⵔⴰ ⵏ ⵜⴰⵙⵏⴰ ⵏⵖ ⴰⴼⴰⵢⵍⵓ ⵉⵍⵍⴰⵏ ⴳ ⵜⵍⴳⴰⵎⵜ ⵏ ⵓⴹⴼⴼⵓⵔ ⵉⵏⵓ",
+       "tog-enotifusertalkpages": "ⴰⵣⵏ ⵢⵢⵉ ⵏⵏ ⵉⵎⴰⵢⵍ ⴰⴽⵓⴷ ⵏⵏⴰ ⵜⵡⴰⵙⵙⵏⴼⵍ ⵜⴰⵙⵏⴰ ⵏ ⵓⵎⵙⴰⵡⴰⵍ ⵉⵏⵓ",
+       "tog-enotifminoredits": "ⴰⵣⵏ ⵢⵢⵉ ⵏⵏ ⴰⵍⵜⵓ ⵉⵎⴰⵢⵍ ⵅⴼ ⵉⵙⵏⴼⵍⵏ ⵉⵎⵣⵢⴰⵏⵏ ⵏ ⵜⴰⵙⵏⵉⵡⵉⵏ ⴷ ⵉⴼⴰⵢⵍⵓⵜⵏ",
+       "tog-oldsig": "ⴰⵙⴳⵎⴹ ⵏⵏⴽ ⵏ ⴷⵖⵉⴽⴽ",
+       "tog-watchlisthideown": "ⵙⵙⵏⵜⵍ ⵉⵙⵏⵉⴼⵉⵍⵏ ⵉⵏⵓ ⵙⴳ ⵜⵍⴳⴰⵎⵜ ⵏ ⵓⴹⴼⴼⵓⵔ",
+       "tog-watchlisthidebots": "ⵙⵙⵏⵜⵍ ⵉⵙⵏⵉⴼⵉⵍⵏ ⵏ ⵉⵔⵓⴱⵓⵜⵏ ⵙⴳ ⵜⵍⴳⴰⵎⵜ ⵏ ⵓⴹⴼⴼⵓⵔ",
+       "tog-watchlisthideminor": "ⵙⵙⵏⵜⵍ ⵉⵙⵏⵉⴼⵉⵍⵏ ⵉⵎⵥⵢⴰⵏⴻⵏ ⵙⴳ ⵜⵍⴳⴰⵎⵜ ⵏ ⵓⴹⴼⴼⵓⵔ",
        "tog-ccmeonemails": "ⴰⵣⵏ ⵉⵢⵉ ⴷ ⵜⵓⵏⵖⵉⵍⵉⵏ ⵏ ⵉⵎⴰⵢⵍⵏ ⵏⵏⴰ ⵓⵣⵏⵖ ⵉ ⵉⵎⵙⵙⵎⵔⵙⵏ ⵢⴰⴹⵏ",
        "tog-diffonly": "ⴰⴷ ⵓⵔ ⵜⵙⵙⴽⴷ ⵜⵓⵎⴰⵢⵜ ⵏ ⵜⴰⵙⵏⴰ ⴷⴷⵓ ⵉⵎⵣⴰⵔⴰⵢⵏ",
        "tog-showhiddencats": "ⵙⴽⵏ ⵜⴰⴳⴳⴰⵢⵉⵏ ⵉⵜⵜⵓⵃⴹⴰⵏ",
+       "underline-always": "ⴽⵓ ⴰⵙⵙ",
        "underline-never": "ⵓⵙⴰⵔ",
        "sunday": "ⴰⵙⴰⵎⴰⵙ",
        "monday": "ⴰⵢⵏⴰⵙ",
        "sat": "ⴰⵙⴹ",
        "january": "ⵉⵏⵏⴰⵢⵔ",
        "february": "ⴱⵕⴰⵢⵕ",
-       "march": "âµ\8eâ´°âµ\95âµ\9a",
+       "march": "âµ\8eâ´°âµ\94âµ\99",
        "april": "ⵉⴱⵔⵉⵔ",
        "may_long": "ⵎⴰⵢⵢⵓ",
        "june": "ⵢⵓⵏⵢⵓ",
        "july": "ⵢⵓⵍⵢⵓⵣ",
        "august": "ⵖⵓⵛⵜ",
        "september": "ⵛⵓⵜⴰⵏⴱⵉⵔ",
-       "october": "â´½âµ\9câµ\93â´±âµ\94",
+       "october": "â´½âµ\9fâµ\93â´±âµ\95",
        "november": "ⵏⵓⵡⴰⵏⴱⵉⵔ",
        "december": "ⴷⵓⵊⴰⵏⴱⵉⵔ",
        "january-gen": "ⵉⵏⵏⴰⵢⵔ",
@@ -58,8 +83,8 @@
        "december-gen": "ⴷⵓⵊⴰⵏⴱⵉⵔ",
        "jan": "ⵉⵏⵏ",
        "feb": "ⴱⵕⴰ",
-       "mar": "âµ\8eâ´°âµ\95",
-       "apr": "âµ\89â´±âµ\94",
+       "mar": "âµ\8eâ´°âµ\94",
+       "apr": "â´±âµ\95â´°",
        "may": "ⵎⴰⵢ",
        "jun": "ⵢⵓⵏ",
        "jul": "ⵢⵓⵍ",
        "period-pm": "ⵣⵡ",
        "pagecategories": "{{PLURAL:$1|ⴰⵙⵎⵉⵍ|ⵉⵙⵎⵉⵍⵏ}}",
        "category_header": "Tasniwin g usmil \"$1\"",
-       "subcategories": "âµ\89â´·âµ\93âµ\99âµ\8eâµ\89âµ\8dⵏ",
+       "subcategories": "âµ\9câµ\89â´·âµ\93ⴳⴳⴰⵢâµ\89ⵏ",
        "category-media-header": "ⵎⵉⴷⵢⴰ ⴳ ⵓⵙⵎⵉⵍ \"$1\"",
        "category-empty": "<em>ⵜⴰⴳⴳⴰⵢⵜ ⴰⴷ ⵓⵔ ⴷⵉⴳⵙ ⴰⵡⴷ ⴽⵔⴰ ⵏ ⵎⵉⴷⵢⴰ ⵏⵖ ⵜⴰⵙⵏⵉⵡⵉⵏ ⵖⵉⵍⴰⴷ.</em>",
        "hidden-categories": "{{PLURAL:$1|ⴰⵙⵎⵉⵍ ⵉⵎⵎⵏⵜⵍⵏ|ⵉⵙⵎⵉⵍⵏ ⵎⵎⵏⵜⵍⵏⵉⵏ}}",
        "hidden-category-category": "ⵜⴰⴳⴳⴰⵢⵉⵏ ⵉⵜⵜⵓⵏⵜⴰⵍⵏ",
        "category-subcat-count": "{{PLURAL:$2|ⴰⵙⵎⵉⵍ ⴰⴷ ⴷⵉⴳⵙ ⵖⴰⵙ ⵉⴷⵓⵙⵎⵉⵍⵏ ⴰⴷ.|ⴰⵙⵎⵉⵍ ⴰⴷ ⴷⵉⴳⵙ {{PLURAL:$1|ⴰⴷⵓⵙⵎⵉⵍ ⴰⴷ |$1 ⵉⴷⵓⵙⵎⵉⵍⵏ ⴰⴷ}}, ⵙⴳ $2 ⴳ ⵓⵖⵔⵓⴷ.}}",
        "category-article-count": "{{PLURAL:$2|ⴰⵙⵎⵉⵍ ⴰⴷ ⵢⵓⵎⴰ ⵖⴰⵙ ⵜⴰⵙⵏⴰ ⴰⴷ {{PLURAL:$1|ⵜⴰⵙⵏⴰ ⴰⴷ ⵜⵍⵍⴰ|$1 ⵜⴰⵙⵏⵉⵡⵉⵏ ⴰⴷ ⵍⵍⴰⵏⵜ}} ⴳ ⵓⵙⵎⵉⵍ ⴰⴷ, ⵙⴳ $2 ⴳ ⵓⵖⵔⵓⴷ.}}",
+       "category-file-count": "{{PLURAL:$2|ⴰⵙⵎⵉⵍ ⴰⴷ ⵢⵓⵎⵢ ⵖⴰⵙ ⴰⴼⴰⵢⵍⵓ ⴰ.|{{PLURAL:$1|ⴰⴼⴰⵢⵍⵓ|$1 ⵏ ⵉⴼⵓⵢⵍⴰ}} ⴳ ⵓⵙⵎⵉⵍ ⴰ, ⵙⴳ $2 ⴰⵖⵔⵓⴷ.}}",
        "listingcontinuesabbrev": "ⴹⴼⵓⵔ",
+       "noindex-category": "ⵜⴰⵙⵏⵉⵡⵉⵏ ⵎⵉ ⵓⵔ ⵉⵜⵜⵓⴳⵉ ⵓⵙⴳⴱⵔ",
        "broken-file-category": "ⵜⴰⵙⵏⵉⵡⵉⵏ ⴳ ⵍⵍⴰⵏ ⵉⵙⵖⵏⴻⵏ ⵏ ⵉⴼⵓⵢⵍⴰ ⵕⵥⴰⵏⵉⵏ",
        "about": "ⵅⴼ",
        "article": "ⵜⴰⵙⵏⴰ ⵏ ⵜⵓⵎⴰⵢⵜ",
        "navigation": "ⴰⵙⵜⴰⵔⴰ",
        "and": "&#32;ⴷ",
        "faq": "FAQ",
+       "actions": "ⵉⴳⵉⵜⵏ",
        "namespaces": "ⵜⵉⵔⵉⵡⵉⵏ ⵏ ⵉⵙⵎⴰⵡⵏ",
        "variants": "ⵜⵉⵎⵣⴰⵔⴰⵢⵉⵏ",
        "navigation-heading": "ⵓⵎⵓⵖ ⵏ ⵓⵙⵙⴰⵔⴰ",
        "returnto": "ⴰⵖⵓⵍ ⵖⵔ $1.",
        "tagline": "ⵙⴳ {{SITENAME}}",
        "help": "ⵜⵉⵡⵉⵙⵉ",
-       "search": "âµ\94ⵣⵓ",
+       "search": "â´°âµ\94âµ£ⵣⵓ",
        "searchbutton": "ⵔⵣⵓ",
        "go": "ⵔⵣⵓ",
        "searcharticle": "ⴷⴷⵓ",
        "protect_change": "ⵙⵏⴼⵍ",
        "unprotect": "ⵙⵏⴼⵍ ⴰⴼⵔⴰⴳ",
        "newpage": "ⵜⴰⵙⵏⴰ ⵜⴰⵎⴰⵢⵏⵓⵜ",
-       "talkpagelinktext": "ⵎⵙⴰⵡⴰⵍ",
+       "talkpagelinktext": "â´°âµ\8eâµ\99ⴰⵡⴰâµ\8d",
        "specialpage": "ⵜⴰⵙⵏⵉⵡⵉⵏ ⵥⵍⵉⵏⵉⵏ",
        "personaltools": "ⵉⵎⴰⵙⵙⵏ ⵓⴷⵎⴰⵡⴰⵏⵏ",
        "talk": "ⴰⵎⵙⴰⵡⴰⵍ",
        "viewtalkpage": "ⵥⵔ ⴰⵎⵙⴳⴷⴰⵍ",
        "otherlanguages": "ⵙ ⵜⵓⵜⵍⴰⵢⵉⵏ ⵢⴰⴹⵏⵉⵏ",
        "redirectedfrom": "(ⵓⵖⵓⵍ ⵙⴳ $1)",
+       "redirectpagesub": "ⵜⴰⵙⵏⴰ ⵏ ⵓⵙⵡⴰⵍⴰ",
        "redirectto": "ⵙⵏⵉⵍ ⵖⵔ:",
        "lastmodifiedat": "ⵜⵏⵏⴼⵍ ⵜⴰⵙⵏⴰ ⴰ ⵉ ⵜⵉⴽⴽⵍⵜ ⵜⴰⵎⴳⴳⴰⵔⵓⵜ ⴳ $1, ⴳ $2.",
        "protectedpage": "ⵜⴰⵙⵏⴰ ⵉⵜⵜⵓⴼⵔⴰⴳⵏ",
        "jumptosearch": "ⵔⵣⵓ",
        "pool-errorunknown": "ⵜⴰⵣⴳⴰⵍⵜ ⵜⴰⵔⵓⵙⵙⵉⵏⵜ",
        "aboutsite": "ⵖⴼ {{SITENAME}}",
-       "aboutpage": "Project:ⵅⴼ",
+       "aboutpage": "Project:ⵖⴼ",
+       "copyright": "ⵜⵓⵎⴰⵢⵜ ⵜⵍⵍⴰ ⴷⴷⵓ ⵜⵓⵔⴰⴳⵜ $1 ⵖⴰⵙ ⵎⴰ ⵉⵜⵜⵡⴰⴱⴷⴰⵔ ⵓⵏⵎⴳⴰⵍⵏⵏⵙ.",
        "copyrightpage": "{{ns:project}}:ⵉⵣⵔⴼⴰⵏ ⵏ ⵓⵙⵏⵖⵍ",
        "currentevents": "ⵜⵉⵎⵙⴰⵔⵉⵏ ⵜⵉⵎⵉⵔⴰⵏⵉⵏ",
        "currentevents-url": "Project:ⵜⵉⵎⵙⴰⵔⵉⵏ ⵜⵉⵎⵉⵔⴰⵏⵉⵏ",
        "ok": "ⵡⴰⵅⵅⴰ",
        "retrievedfrom": "ⵉⵜⵜⵓⵙⴰⵖⵓⵍ ⵙⴳ $1",
        "youhavenewmessages": "{{PLURAL:$3|ⵖⵓⵔⴽ}} $1 ($2).",
+       "youhavenewmessagesfromusers": "{{PLURAL:$4|ⵉⵍⵍⴰ ⴷⴰⵔⴽ}} $1 ⵙⴳ {{PLURAL:$3|ⵢⴰⵏ ⵓⵎⵙⵙⵎⵔⵙ ⵢⴰⴹⵏ|$3 ⵉⵎⵙⵙⵎⵔⵙⵏ}} ($2).",
        "youhavenewmessagesmanyusers": "ⴷⴰⵔⴽ $1 ⵙⴳ ⵎⵏⵏⴰⵡ ⵉⵎⵙⵙⵎⵔⵙⵏ ($2)",
        "newmessageslinkplural": "{{PLURAL:$1|ⵜⵓⵣⵉⵏⵜ ⵜⴰⵎⴰⵢⵏⵓⵜ|999=ⵜⵓⵣⵉⵏⵉⵏ ⵜⵉⵎⴰⵢⵏⵓⵜⵉⵏ}}",
+       "newmessagesdifflinkplural": "{{PLURAL:$1|ⴰⵙⵏⴼⵍ ⴰⵎⴳⴳⴰⵔⵓ|999=ⵉⵙⵏⵉⴼⵍⵏ ⵉⵎⴳⴳⵓⵔⴰ}}",
        "youhavenewmessagesmulti": "ⵍⵍⴰⵏ ⵖⵓⵔⴽ ⵜⵓⵣⵉⵏⵉⵏ ⵜⵉⵎⴰⵢⵏⵓⵜⵉⵏ ⴳ $1",
        "editsection": "ⵙⵏⴼⵍ",
        "editold": "ⵙⵏⴼⵍ",
        "toc": "ⵜⵓⵎⴰⵢⵉⵏ",
        "showtoc": "ⵙⴽⵏ",
        "hidetoc": "ⵙⵙⵏⵜⵍ",
+       "confirmable-confirm": "ⵉⵙ ⵜⵏⵥⵉⴷ",
        "confirmable-yes": "ⵢⴰⵀ",
        "confirmable-no": "ⵓⵀⵓ",
+       "thisisdeleted": "ⴰⴷ ⵜⵙⴽⵏⴷ ⵏⵖ ⴷ ⴰⴷ ⴷ ⵜⵔⴰⵔⴷ $1?",
        "viewdeleted": "ⵥⵕ $1?",
        "site-atom-feed": "ⴰⵏⴳⵉ ⵏ ⴰⵜⵓⵎ ⵏ $1",
        "page-atom-feed": "ⴰⵏⴳⵉ ⵏ ⴰⵜⵓⵎ ⵏ $1",
        "nstab-category": "ⴰⵙⵎⵉⵍ",
        "mainpage-nstab": "ⵜⴰⵙⵏⴰ ⵏ ⵓⵙⵏⵓⴱⴳ",
        "nosuchspecialpage": "ⴰⵡⴷ ⵢⴰⵜ ⵜⴰⵙⵏⴰ ⵉⵥⵍⵉⵏ.",
-       "nospecialpagetext": "<strong>âµ\9câ´»âµ\9câµ\9câµ\94â´· âµ¢â´°âµ\9c âµ\9câ´°âµ\99âµ\8fâ´° âµ\89âµ¥âµ\8dâµ\89âµ\8f âµ\93âµ\94 âµ\89âµ\85â´·âµ\89âµ\8eâµ\8f</strong>",
+       "nospecialpagetext": "<strong>âµ\9câ´»âµ\9câµ\9câµ\94â´· âµ¢â´°âµ\9c âµ\9câ´°âµ\99âµ\8fâ´° âµ\89âµ¥âµ\8dâµ\89âµ\8f âµ\93âµ\94 âµ\89â´±âµ\93âµ\8fâµ\89âµ\8f</strong>\n\nⵢⴰâµ\9c âµ\9câµ\8dⴳⴰâµ\8eâµ\9c âµ\8f âµ\9câ´°âµ\99âµ\8fâµ\89ⵡâµ\89âµ\8f âµ\89âµ¥âµ\8dâµ\89âµ\8f âµ\94â´°â´· âµ\9câµ\9c âµ\9cⴰⴼⴷ â´³ [[Special:SpecialPages|{{int:specialpages}}]].",
        "error": "ⵜⴰⵣⴳⵍⵜ",
+       "databaseerror-function": "ⵜⴰⵙⵖⵏⵜ: $1",
        "databaseerror-error": "ⵜⴰⵣⴳⵍⵜ: $1",
        "badtitle": "ⴳⴰⵔ ⴰⵣⵡⵍ",
+       "badtitletext": "ⴰⵣⵡⵍ ⵏ ⵜⴰⵙⵏⴰ ⵉⵜⵜⵡⴰⵜⵜⴰⵔⵏ ⵢⴰ ⵓⵔ ⵉⵏⵉⵎ ⵢⴰ ⵢⵓⵔⴰ ⵢⴰ ⵓⵔ ⵢⵉⵍⵉⵖ ⵎⵍⵉⵃ ⵎⴽ ⵉⴳⴰ ⵢⴰⵏ ⵓⵣⵡⵍ ⵉⵙⵎⴰⵏⴻⵏ ⵙⵏⴰⵜ ⵜⵓⵜⵍⴰⵢⵉⵏ ⵏⵖ ⵙⵉⵏ ⵢⵉⵙⵏⴼⴰⵔⵏ. ⵄⵏⵉⵖ ⴷⵉⴳⵙ ⵢⴰⵏ ⵏⵖ ⵎⵏⵏⴰⵡ ⵏ ⵢⵉⵙⴽⴽⵉⵍⵏ ⵙ ⵓⵔ ⵉⵙⵙⵉⵏ ⴰⴷ ⵜⵜⵓⵙⵎⵔⵙⵏ ⴳ ⵢⵉⵣⵡⵍⴰⵏ.",
        "viewsource": "ⵙⴽⵏ ⴰⵙⴰⴳⵎ",
        "viewsource-title": "ⵥⵕ ⴰⵖⴱⴰⵍⵓ ⵉ $1",
        "viewsourcetext": "ⵜⵣⵎⵔⴷ ⴰⴷ ⵜⵥⵔⴷ ⴷ ⴰⴷ ⵜⵙⵙⵏⵖⵍⴷ ⴰⵙⴰⴳⵎ ⵏ ⵜⴰⵙⵏⴰ ⴰⴷ",
+       "exception-nologin": "ⵓⵔ ⵢⵓⴷⵉⴼ",
+       "welcomeuser": "ⴰⵏⵙⵓⴼ, $1!",
+       "yourname": "ⵉⵙⵎ ⵏ ⵓⵙⵎⵔⴰⵙ",
        "userlogin-yourname": "ⵉⵙⵎ ⵏ ⵓⵙⵎⵔⴰⵙ",
        "userlogin-yourname-ph": "ⵙⵙⴽⵛⵎ ⵉⵙⵎ ⵏ ⵓⵏⵙⵙⵎⵔⵙ ⵏⵏⵎ/ⴽ",
+       "createacct-another-username-ph": "ⵙⵙⴽⵛⵎ ⵉⵙⵎ ⵏ ⵓⵏⵙⵙⵎⵔⵙ ⵏⵏⵎ/ⴽ",
        "yourpassword": "ⵜⴰⴳⵓⵔⵉ ⵏ ⵓⵣⵔⴰⵢ",
        "userlogin-yourpassword": "ⵜⴰⴳⵓⵔⵉ ⵏ ⵓⵣⵔⴰⵢ",
        "userlogin-yourpassword-ph": "ⵙⵙⴽⵛⵎ ⵜⴰⴳⵓⵔⵉ ⵏ ⵓⵣⵔⴰⵢ ⵏⵏⴽ",
        "userlogin-joinproject": "ⵍⴽⵎ {{SITENAME}}",
        "createaccount": "ⵔⵥⵎ ⴽⵔⴰ ⵏ ⵓⵎⵉⴹⴰⵏ",
        "userlogin-resetpassword-link": "ⵜⴻⵜⵜⵓⴷ ⵜⴰⴳⵓⵔⵉ ⵏ ⵓⵣⵔⴰⵢ ⵏⵏⵎ/ⴽ?",
+       "userlogin-helplink2": "ⵜⵉⵡⵉⵙⵉ ⴳ ⵓⴽⵛⵛⵓⵎ",
+       "createacct-emailrequired": "ⵉⵎⴰⵢⵍ",
        "createacct-emailoptional": "ⵉⵎⴰⵢⵍ (ⴰⵔⵓⵛⵛⵉⵍ)",
        "createacct-email-ph": "ⵙⵙⴽⵛⵎ ⴰⵏⵙⴰ ⵉⵎⴰⵢⵍ ⵏⵏⴽ",
+       "createacct-another-email-ph": "ⵙⵙⴽⵛⵎ ⴰⵏⵙⴰ ⵉⵎⴰⵢⵍ ⵏⵏⴽ",
+       "createacct-realname": "ⵉⵙⵎ ⵏ ⵜⵉⴷⵜ (‍ⵎ ⵜⵔⵉⵜ)",
        "createacct-reason": "ⵜⴰⵎⵏⵜⵉⵍⵜ",
        "createacct-submit": "ⵔⵥⵎ ⴰⵎⵉⴹⴰⵏ {{GENDER:|ⵏⵏⴽ|ⵏⵏⵎ}}",
+       "createacct-another-submit": "ⵙⵏⴼⵍⵓⵍ ⴰⵎⵉⴹⴰⵏ",
        "createacct-benefit-heading": "{{SITENAME}} ⵜⴻⵜⵜⵓⴽ ⵙⴳ ⵎⵉⴷⴷⵏ ⴰⵎ ⴽⵢⵢⵉⵏ",
        "createacct-benefit-body1": "{{PLURAL:$1|ⴰⵙⵏⴼⵍ|ⵉⵙⵏⴼⴰⵍ}}",
        "createacct-benefit-body2": "{{PLURAL:$1|ⵜⴰⵙⵏⴰ|ⵜⴰⵙⵏⵉⵡⵉⵏ}}",
        "createacct-benefit-body3": "{{PLURAL:$1|ⴰⵏⴰⵎⵓ|ⵉⵏⴰⵎⵓⵜⵏ}} {{PLURAL:$1|ⴰⵎⴳⴳⴰⵔⵓ|ⵉⵎⴳⴳⵓⵔⴰ}}",
+       "mailmypassword": "ⵔⴰⵔ ⴷ ⵜⴰⴳⵓⵔⵉ ⵏ ⵓⵣⵔⴰⵢ",
        "loginlanguagelabel": "ⵜⵓⵜⵍⴰⵢⵜ: $1",
        "pt-login": "ⴽⵛⵎ",
        "pt-login-button": "ⴽⵛⵎ",
        "pt-createaccount": "ⵙⵏⴼⵍⵓⵍ ⴰⵎⵉⴹⴰⵏ",
        "pt-userlogout": "ⴼⴼⵖ",
+       "oldpassword": "ⵜⴰⴳⵓⵔⵉ ⵏ ⵓⵣⵔⴰⵢ ⵜⴰⵇⴱⵓⵔⵜ",
        "newpassword": "ⵜⴰⴳⵓⵔⵉ ⵏ ⵓⵣⵔⴰⵢ ⵜⴰⵎⴰⵢⵏⵓⵜ",
        "botpasswords-label-create": "ⵙⵏⵓⵍⴼⵓ",
+       "botpasswords-label-cancel": "ⵙⵔ",
        "botpasswords-label-delete": "ⴽⴽⵙ",
+       "resetpass-submit-cancel": "ⵙⵔ",
        "passwordreset": "ⵔⴰⵔ ⴷ ⵜⴰⴳⵓⵔⵉ ⵏ ⵓⵣⵔⴰⵢ",
+       "passwordreset-username": "ⵉⵙⵎ ⵏ ⵓⵙⵎⵔⴰⵙ:",
        "changeemail-newemail": "ⵉⵎⴰⵢⵍ ⴰⵎⴰⵢⵏⵓ:",
        "changeemail-none": "(ⵓⵍⴰ ⵢⴰⵏ)",
        "bold_sample": "ⴰⴹⵔⵉⵙ ⴰⵣⵓⵔⴰⵔ",
        "minoredit": "ⵡⴰ ⴷ ⴰⵙⵏⴼⵍ ⵓⵎⵥⵉⵢ",
        "watchthis": "ⵎⵎⴰⵜⵔ ⵜⴰⵙⵏⴰ ⴰⴷ",
        "savearticle": "ⵃⴹⵓ ⵜⴰⵙⵏⴰ",
+       "publishchanges": "ⴼⵙⵔ ⵉⵙⵏⴼⵍⵏ",
+       "savearticle-start": "ⵃⴹⵓ ⵜⴰⵙⵏⴰ",
+       "savechanges-start": "ⵃⴹⵓ ⵉⵙⵏⴼⵍⵏ",
+       "publishpage-start": "ⴼⵙⵔ ⵜⴰⵙⵏⴰ...",
+       "publishchanges-start": "ⴼⵙⵔ ⵉⵙⵏⴼⵓⵍⵏ...",
+       "preview": "ⴰⵣⵔⴰⵙⴽⴰⵏ",
        "showpreview": "ⵙⴽⵏ ⴰⴱⵔⵉⴼⵢⵓ",
        "showdiff": "ⵙⵎⴰⵍ ⵉⵙⵏⴼⵍⵏ",
+       "anoneditwarning": "<strong> ⴰⵡⵢ ⵉⵜⵏⴰⵏ:</strong> ⵓⵔ ⵜⵍⵍⵉⴷ ⴳ ⵓⵣⴷⴰⵢ. ⵜⴰⵏⵙⴰ ⵏⵏⴽ IP ⵔⴰⴷ ⵜⵓⵎⴰⵏ ⵉ ⵎⴷⴷⵏ ⴰⴽⴽ ⵎⴽ ⵜⵙⴽⵔⴷ ⴽⵔⴰ ⵏ ⵢⵉⵙⵏⵉⴼⵉⵍⵏ. ⵎⴽ <strong>[$1 ⵜⵍⵍⵉⴷ ⴳ ⵓⵣⴷⴰⵢ]</strong> ⵏⵖ <strong>[$2 ⵙⴽⵔⴰ ⵢⴰⵏ ⵓⵎⵉⴹⴰⵏ]</strong>, ⵔⴰⴷ ⵜⵜⵢⵉⵖⵉⵏⴻⵏ ⵉⵙⵏⵉⴼⵉⵍⵏ ⵏⵏⴽ ⴷ ⵢⵉⵙⵎ ⵏⵏⴽ(ⵎ) ⵏ ⵓⵏⵙⵙⵎⵔⵙ, ⵙ ⵎⴽⴰ ⵔⴰⴷ ⵖⵓⵔⴽ ⵉⵍⵉⵏ ⵉⴱⵖⵓⵔⵏ ⵢⴰⴹⵏ.",
+       "blockedtext": "<strong>ⵉⵜⵜⵓⴳⴷⴰⵍ ⵓⵎⵉⴹⴰⵏ ⵏⵏⴽ(ⵎ) ⵏⵖ ⴷ ⵜⴰⵏⵙⴰ ⵏⵏⴽ(ⵎ) IP.</strong>\n\nⴰⴳⴷⴷⵓⵍ ⴰⴷ ⵉⵙⴽⵔ ⵜ $1.\nⴰⵙⵔⴰⴳ ⵏ ⵓⴳⴷⴷⵓⵍ ⴷ ⵡⴰ : <em>$2</em>.\n\n* ⴰⵏⵜⵜⵉ ⵏ ⵓⴳⴷⴷⵓⵍ : $8\n* ⵔⴰⴷ ⵉⵇⵇⵉⵎ ⵓⴳⴷⴷⵓⵍ ⴰⴷ ⴰⵔ : $6\n* ⴰⵎⵉⴹⴰⵏ ⵉⵜⵜⵓⴳⴷⴰⵍⵏ : $7.\n\nⵜⵓⴼⵉⴷ ⴰⴷ ⵜⵎⵙⴰⵡⴰⴹⴷ ⴰⴽⴷ $1 ⵏⵖ ⵢⴰⵏ [[{{MediaWiki:Grouppage-sysop}}|administrateur]] ⵢⴰⴹ ⴼⴰⵔ ⴰⴷ ⵜⵎⵙⴳⴷⴰⵍⵎ ⵅⴼ ⵓⵢⴰ.\nⵓⵔ ⵜⵓⴼⵉⴷ ⴰⴷ ⵜⵙⵙⵎⵔⵙⴷ ⵜⴰⵙⵖⵏⵜ  « {{int:emailuser}} » ⵖⴰⵙ ⵎⴽ ⵜⴻⵜⵜⵓⵙⵜⴰⵢ ⵢⴰⵜ ⵜⴰⵙⵏⴰ ⵉⵙⵡⵓⵔⵉⵏ ⴳ [[Special:Preferences|préférences]] ⵏⵏⴽ(ⵎ) ⴷ ⵖⴰⵙ ⵎⴽ ⵓⵔ ⵉⵜⵜⵓⴳⴷⴰⵍ ⵓⵙⵡⵓⵔⵉ ⴰⴷ.\nⵜⴰⵏⵙⴰ ⵏⵏⴽ(ⵎ) IP ⵜⴰⵎⵉⵔⴰⵏⵜ ⵜⴳⴰ ⵜⵜ $3 ⴷ ⵓⵎⵙⵎⴰⴳⵉ ⵏⵏⴽ(ⵎ) ⵏ ⵓⴳⴷⴷⵓⵍ ⵉⴳⴰ ⵜ $5.\nⵎⴽ ⵜⵓⴼⵉⴷ, ⵙⴽⵛⵎ ⵉⵛⵎⵓⵎⵎⴰ ⴰⴽⴽ ⵏ ⵓⴼⵍⵍⴰ ⴳ ⴽⵓ ⵢⴰⵜ ⴳ ⵜⵓⵜⵜⵔⵉⵡⵉⵏ ⵏⵏⴰ ⵜⵙⴽⵔⴷ.",
        "loginreqlink": "ⴽⵛⵎ",
+       "accmailtitle": "ⵜⴰⴳⵓⵔⵉ ⵓⵣⵔⴰⵢ ⵜⴻⵜⵜⵡⴰⵣⵏ",
        "newarticle": "(ⴰⵎⴰⵢⵏⵓ)",
        "newarticletext": "ⵜⴹⴼⴰⵔⴷ ⵢⴰⵏ ⵓⵙⵖⵏ ⵖⵔ ⵢⴰⵜ ⵜⴰⵙⵏⴰ ⵏⵏⴰ ⵓⵔ ⵜⴰ ⵉⵍⵍⵉⵏ. \nⴰⴼⴰⴷ ⴰⴷ ⵜⵙⵏⵓⵍⴼⵓⴷ ⵜⴰⵙⵏⴰ, ⵙⵙⵏⵜⵉ ⵜⵉⵔⵔⴰ ⴳ ⵓⴼⵏⵉⵇ ⴳ ⵉⵣⴷⴷⴰⵔ (ⵥⵔ [$1 ⵜⴰⵙⵏⴰ ⵏ ⵜⵡⵉⵙⵉ] ⵉ ⵡⵓⴳⴳⴰⵔ ⵏ ⵉⵏⵖⵎⵉⵙⵏ). \nⵎⴽ ⵜⵍⵍⵉⴷ ⴷⴰ ⵙ ⵓⵣⴳⴰⵍ, ⴰⴽⵍ ⵖⴼ <strong>ⴰⵖⵓⵍ</strong> ⴳ ⵓⵙⴰⵔⴰ ⵏⵏⴽ.",
+       "anontalkpagetext": "----\n<em>ⵜⵍⵍⵉⴷ ⴳ ⵜⴰⵙⵏ ⵏ ⵓⵎⵙⴰⵡⴰⵍ ⵏ ⵢⴰⵏ ⵓⵏⵙⵙⵎⵔⵙ ⵡⴰⵔⵉⵙⵎ ⵏⵏⴰ ⵜⴰ ⵓⵔ ⵉⵙⴽⵉⵔⵏ ⴰⵎⵉⴹⴰⵏ ⵏⵖ ⵏⵏⴰ ⵜ ⵓⵔ ⵉⵙⵙⵎⵔⵉⵙⵏ</em>.\nⴰⵢⴰ ⴰ ⵖⴼ ⵉⴼⵓⴽⴽ ⴰⴷ ⵏⵙⵙⵎⵔⵙ ⵜⴰⵏⵙⴰ ⵏⵏⵙ IP ⴼⴰⴷ ⴰⴷ ⵜ ⵏⵙⵎⴰⴳⵉ.\nⵢⴰⵜ ⵜⴰⵏⵙⴰ IP ⵥⴹⴰⵔⵏ ⴰⴷ ⵜⵜ ⵙⵙⵓⵔⵏ ⵎⵏⵏⴰⵡ ⵏ ⵉⵏⵙⵙⵎⵔⵙⵏ.\nⵎⴽ ⵜⴳⵉⴷ ⵢⴰⵏ ⵓⵏⵙⵙⵎⵔⵙ ⵡⴰⵔⵉⵙⵎ ⴷ ⴽ ⵜⵖⴹⴼⴷ ⵎⴰⵙ ⴽ ⵡⴰⵜⵙⵏ ⴽⵔⴰ ⵏ ⵉⵅⴼⴰⵡⴰⵍⵏ ⵓⵔ ⵙⵉⴽ ⵉⵥⵍⵉⵏ, ⵜⵓⴼⵉⴷ ⴰⴷ  [[Special:CreateAccount|ⵙⴽⵔ ⵢⴰⵏ ⵓⵎⵉⴹⴰⵏ]] ⵏⵖ ⴷ [[Special:UserLogin|ⴽⵛⵎ]] ⴱⴰⵔ ⴰⴷ ⵜⴰⵏⴼⴷ ⵉ ⴽⵔⴰⵢⴳⴰⵜ ⴰⵎⵔⴽⵙ ⴷ ⵉⵎⴷⵔⴰⵡⵏ ⵢⴰⴹⵏ.",
        "noarticletext": "ⵓⵔ ⵉⵍⵍⵉ ⴽⵔⴰ ⵏ ⵓⴹⵔⵉⵙ ⴳ ⵜⴰⵙⵏⴰ ⴰⴷ ⵖⵉⵍⴰ. \nⵜⵣⵎⵔⴷ ⴰⴷ [[Special:Search/{{PAGENAME}}|ⵜⵔⵣⵓⴷ ⵖⴼ ⵓⵣⵡⵍ ⵏⵏⵙ]] ⴳ ⵜⴰⵙⵏⵉⵡⵉⵏ ⵢⴰⴹⵏ, <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} ⵔⵣⵓ ⵖⴼ logs ⵖⵔⵙ ⵉⵇⵇⵏⴻⵏ],\nⵏⵖ [{{fullurl:{{FULLPAGENAME}}|action=edit}} ⵙⵏⵓⵍⴼⵓ ⵜⴰⵙⵏⴰ]</span>.",
        "noarticletext-nopermission": "ⴷⵖⵉ ⵓⵔ ⵉⵍⵍⵉ ⴰⵡⴷ ⴽⵔⴰ ⵏ ⵓⴹⵔⵉⵚ ⴳ ⵜⴰⵙⵏⴰ ⴰ.\nⵜⵣⵎⵔⴷ ⴰⴷ [[Special:Search/{{PAGENAME}}|ⵜⵔⵣⵓⴷ ⵖⴼ ⵓⵣⵡⵍ ⵏⵏⵙ]] ⴳ ⵜⴰⵙⵏⵉⵡⵉⵏ ⵢⴰⴹⵏⵉⵏ, ⵏⵖ <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} ⵔⵣⵓ ⵖⴼ ⵉⵣⵎⵎⴻⵎⵏ ⵉⵣⴷⵉⵏ]</span>, ⵎⴰⵛⴰ ⵓⵔ ⴷⴰⵔⴽ ⵜⵓⵔⴰⴳⵜ ⴰⴷ ⵜⵙⵏⵓⵍⴼⵓⴷ ⵜⴰⵙⵏⴰ ⴰ.",
        "userpage-userdoesnotexist-view": "ⴰⵎⵉⴹⴰⵏ ⵏ ⵓⵎⵙⵙⵎⵔⵙ $1 ⵓⵔ ⵉⵜⵜⵓⵣⵎⵎⴻⵎ.",
+       "clearyourcache": "<strong>ⵜⴰⵎⴰⵡⵜ :</strong> ⴷⴼⴼⵉⵔ ⴰⴷ ⵜⵙⴽⵍⵙⵍ ⵉⵙⵏⵉⴼⵉⵍⵏ ⵏⵏⴽ (ⵎ), ⵄⵏⵉⵖ ⵉⵇⵇⴰⵏ ⴷ ⴰⴷ ⵜⵙⵙⴽⵜⵔⴷ ⵜⵉⵏⵏⵓⵜⵍⴰ ⵏ ⵓⵎⵙⵜⴰⵔⴰ ⴰⴼⴰⴷ ⴰ ⵜⵥⵔⴷ ⵉⵙⵏⵉⴼⵉⵍⵏ.\n* <strong>ⴼⴰⵔⴼⵓⴽⵙ / ⵙⴰⴼⴰⵔⵉ :</strong> ⴰⵊⵊ ⴰⴹⴰⴹ ⵖⴼ ⵜⵙⴰⵔⵓⵜ  <em>Maj</em> (<em>Shift</em>) ⵜⴰⴷⵔⴷ ⵉ ⵜⵙⴰⵔⵓⵜ <em>Actualiser</em> ⵏⵖ ⴰⴷⴷ ⵉ <em>Ctrl-F5</em> ⵏⵖ <em>Ctrl-R</em> (<em>⌘-R</em> ⵖⴼ Mac) \n* <strong>ⴳⵓⴳⵍ ⴽⵔⵓⵎ :</strong> ⴰⴷⴷ ⵉ <em>Ctrl-Maj-R</em> (<em>⌘-Shift-R</em> ⴳ Mac) \n* <strong>ⴰⵏⵜⵉⵔⵏⵉⵜ ⵉⴽⵙⴱⵍⵓⵔⴻⵔ :</strong> ⴰⵊⵊ ⴰⴹⴰⴹ ⵖⴼ ⵜⵙⴰⵔⵓⵜ <em>Ctrl</em> ⵜⴰⴽⵍⴷ ⵜⵙⴰⵔⵓⵜ <em>Actualiser</em> ⵏⵖ ⵜⵓⴽⵍⴷ <em>Ctrl-F5</em> \n* <strong>ⵓⴱⵉⵔⴰ :</strong> ⴷⴷⵓ ⵖⵔ <em>ⵓⵎⵓⵖ → ⵜⵉⵙⵖⴰⵍ</em> (<em>ⵓⴱⵉⵔⴰ → ⵉⵙⵏⵢⵉⴼⵏ</em> ⵖⴼ Mac) ⵙⴰⴽⵉⵏ <em>ⵜⵓⵥⵍⵉⵢⵉⵏ ⴷ ⵜⵖⵍⵙⵜ → ⵙⴼⴹ ⵉⵙⴼⴽⴰ ⵏ ⵓⵙⴼⵓⴽⴽⵔ → ⵜⵓⴳⵏⵉⵡⵉⵏ ⴷ ⵉⴼⵓⵢⵍⴰ ⵉⵍⵍⴰⵏ ⴳ ⵜⵉⵏⵏⵓⵜⵍⴰ</em>.",
+       "previewnote": "<strong>ⴽⵜⵉ ⴷ ⵎⴰⵙ ⵓⵔ ⵜⴳⵉ ⵖⴰⵙ ⴰⵣⵔⵙⴽⴰⵏ.</strong>\nⵉⵙⵏⵉⴼⵉⵍⵏ ⵏⵏⴽ ⵓⵔ ⵜⴰ ⵜⵜⵓⵙⴽⵍⴰⵙⵏ!",
        "continue-editing": "ⴷⴷⵓ ⵙ ⴰⵏⵙⴰ ⵏ ⵓⵙⵏⴼⵍ",
        "editing": "ⴰⵙⵏⴼⵍ ⵏ $1",
        "creating": "ⴰⵙⵏⵓⵍⴼⵓ ⵏ $1",
        "editingsection": "ⵙⵏⴼⵍ ⴰⴳⵣⵣⵓⵎ $1",
-       "templatesused": "{{PLURAL:$1|ⵜⴰⵙⴽⴽⴰ|ⵜⴰⵙⴽⴽⵉⵡⵉⵏ}} {{PLURAL:$1|ⵉⵜⵜⵓⵙⵎⵔⵙⵏ|ⵜⵜⵓⵙⵎⵔⵙⵏⵉⵏ}} ⴳ ⵜⴰⵙⵏⴰ ⴰⴷ:",
+       "yourtext": "ⴰⴹⵕⵉⵙ ⵏⵏⴽ/ⵎ",
+       "templatesused": "{{PLURAL:$1|ⴰⵍⴱⵓⴹ|ⴰⵍⴱⵓⴹⵏ}} {{PLURAL:$1|ⵉⵜⵜⵓⵙⵎⵔⵙⵏ|ⵜⵜⵓⵙⵎⵔⵙⵏⵉⵏ}} ⴳ ⵜⴰⵙⵏⴰ ⴰⴷ:",
+       "templatesusedpreview": "{{PLURAL:$1|ⴰⵍⴱⵓⴹ|ⴰⵍⴱⵓⴹⵏ}} {{PLURAL:$1|ⵉⵜⵜⵓⵙⵎⵔⵙⵏ|ⵜⵜⵓⵙⵎⵔⵙⵏⵉⵏ}} ⴳ ⵜⴰⵙⵏⴰ ⴰⴷ:",
        "template-protected": "(ⵉⵜⵜⵢⴰⵔⴰⵢ)",
        "template-semiprotected": "(ⵜⵎⵃⴹⴰ ⵙ ⵓⴳⵣⵎⴰⵏ)",
        "hiddencategories": "ⵜⴰⵙⵏⴰ ⴰ ⴷ ⴰⴳⵎⴰⵎ ⵏ {{PLURAL:$1|1 ⵏⵜⵍ ⴰⵙⵎⵉⵍ|$1 ⵏⵜⵍ ⵉⵙⵎⵉⵍⵏ}}:",
+       "permissionserrors": "ⴰⵙⵙⵓⵔⴳ ⵉⵣⴳⵜ",
        "permissionserrorstext-withaction": "ⵓⵔ ⴷⴰⵔⴽ ⵜⵓⵔⴰⴳⵜ ⴰⴼⴰⴷ ⴰⴷ $2, ⵙ {{PLURAL:$1|reason|reasons}}:",
+       "recreate-moveddeleted-warn": "<strong>ⴰⵡⵢ ⵉⵜⵏⴰⵏ : ⵀⴰⵜ ⴰⵔ ⵜⵙⴽⴰⵔⴷ ⵢⴰⵜ ⵜⴰⵙⵏⴰ ⵏⵏⴰ ⵜⵜ ⵏⵏ ⵉⴽⴽⴰⵏ ⵜⴻⵜⵜⵡⴰⴽⴽⵙ.</strong>\n\nⵏⵥⵉ ⴳ ⵉⵙ ⵉⵙⵙⵏ ⴰⴷ ⵜⵙⵎⴷⴻⴷ ⴳ ⵉⵙⵏⵉⴼⵉⵍⵏ ⵖⴼ ⵜⴰⵙⵏⴰ ⴰⴷ. \nⵜⵉⵎⵙⵙⴽⵜⵉⵜⵉⵏ ⵏ ⵜⵓⴽⴽⵙⵉⵡⵉⵏ ⴷ ⵉⵙⵎⵓⵜⵜⵓⵢⵏ ⵏ ⵜⴰⵙⵏⴰ ⴰⴷ, ⵍⵍⴰⵏⵜ ⴷⴰ ⵉ ⵓⵙⵏⵖⵎⵙ :",
+       "moveddeleted-notice": "ⵜⴰⵙⵏⴰ ⴰⴷ ⵜⴻⵜⵜⵡⴰⴽⴽⵙ.\nⵜⵉⵎⵙⵙⴽⵜⵉⵜⵉⵏ ⵏ ⵜⵓⴽⴽⵙⵉⵡⵉⵏ, ⵉⴼⵔⴰⴳⵏ ⴷ ⵉⵙⵎⵓⵜⵜⵓⵢⵏ ⵉⵜⵜⵓⴳⴰⵏ ⵉ ⵜⴰⵙⵏⴰ ⵜⵜⵓⵙⴽⴰⵏⴻⵏ ⴳ ⵢⵉⵣⴷⴰⵔ ⴰⵎ ⵉⵙⴰⵖⵓⵍⵏ.",
        "content-model-wikitext": "wikitext",
+       "content-model-javascript": "JavaScript",
+       "undo-failure": "ⴰⵙⵏⴼⵍ ⴰⴷ ⵓⵔ ⵢⴰⵍⵍⴼⵓⵙ ⴰⴷ ⴷ ⵉⵡⵔⵔⵉ ⵙ ⵓⵙⵔⴰⴳ ⵏ ⵓⵎⵎⵔⵡⴰⵢ ⴰⴽⴷ ⴽⵔ ⵏ ⵉⵙⵏⵉⴼⵉⵍⵏ ⵉⵎⵏⵏⵓⵎⵙⵏ.",
+       "viewpagelogs": "ⵙⴽⵏ ⵉⵖⵎⵉⵙⵏ ⵏ ⵜⴰⵙⵏⴰ ⴰⴷ",
        "currentrev-asof": "ⴰⵣⵣⵔⴰⵢ ⴰⵎⴳⴳⴰⵔⵓ ⴳ $1",
        "revisionasof": "ⵜⵓⵏⵖⵉⵍⵜ ⵏ $1",
+       "revision-info": "ⴰⵣⵣⵔⴰⵢ ⵏ $1 ⵉⵙⴽⵔ {{GENDER:$6|$2}}$7",
        "previousrevision": "ⵜⵓⵏⵖⵉⵍⵜ ⵜⴰⵇⴱⵓⵔⵜ",
        "nextrevision": "ⴰⵣⵣⵔⴰⵢ ⴰⵎⴰⵢⵏⵓ",
        "currentrevisionlink": "ⴰⵣⵣⵔⴰⵢ ⴰⵎⴳⴳⴰⵔⵓ",
        "cur": "ⵎⵔⵏ",
        "last": "ⵓⵣⵡⵔ",
+       "page_last": "ⴰⵎⴳⴳⴰⵔⵓ",
+       "histlegend": "ⴰⵙⵜⴰⵢ ⵏ ⵓⵎⵣⴰⵔⴰⵢ : ⵔⵛⵎ ⵜⴰⵏⴽⵓⵍⵉⵏ ⵏ ⵜⵓⵏⵖⵉⵍⵉⵏ ⵏⵏⴰ ⵜⵔⵉⴷ ⴰⴷ ⵜⵙⵎⵣⴰⵣⴰⵍⴷ ⵜⴰⴷⵔⴷ ⵉ ⴰⴽⵎ ⵏⵖ ⵉ ⵜⵙⴰⵔⵓⵜ ⵏ ⵢⵉⵣⴷⴰⵔ.<br />\nⵜⴰⴱⴰⴷⵓⵜ : <strong>({{int:cur}})</strong> = ⴰⵎⵣⴰⵔⴰⵢ ⴰⴽⴷ ⵜⵓⵏⵖⵉⵍⵜ ⵜⴰⵎⴳⴳⴰⵔⵓⵜ, <strong>({{int:last}})</strong> = ⴰⵎⵣⴰⵔⴰⵢ ⴰⴽⴷ ⵜⵓⵏⵖⵉⵍⵜ ⵉⵣⵔⵉⵏ, <strong>{{int:minoreditletter}}</strong> = ⵉⵙⵏⵉⴼⵉⵍⵏ ⵉⵎⵥⵥⵉⵢⵏ.",
        "history-fieldset-title": "ⵔⵣⵓ ⵖⴼ ⵉⵣⵣⵔⴰⵢⵏ",
        "histfirst": "ⴰⵇⴱⵓⵔ",
        "histlast": "ⴰⵎⴰⵢⵏⵓ",
        "history-feed-title": "ⴰⵎⵣⵔⵓⵢ ⵏ ⵓⵣⵣⵔⴰⵢ",
        "history-feed-description": "ⴰⵎⵣⵔⵓⵢ ⵏ ⵓⵣⵣⵔⴰⵢ ⵉ ⵜⴰⵙⵏⴰ ⴰⴷ ⴳ ⵡⵉⴽⵉ",
        "history-feed-item-nocomment": "$1 ⵖⵔ $2",
+       "rev-delundel": "ⵙⴽⵏ/ⵙⵙⵏⵜⵍ",
+       "rev-showdeleted": "ⵙⴽⵏ",
        "revdelete-show-file-submit": "ⵢⴰⵀ",
        "revdelete-log": "ⵜⴰⵎⵏⵜⵉⵍⵜ:",
        "mergehistory-reason": "ⵜⴰⵎⵏⵜⵉⵍⵜ:",
+       "mergelog": "ⵜⴰⵎⵙⵙⴽⵜⵉⵜ ⵏ ⵓⵙⵎⵔⴽⵙ",
        "history-title": "ⴰⵎⵣⵔⵓⵢ ⵏ ⵓⵣⵣⵔⴰⵢ ⵏ \"$1\"",
        "difference-title": "ⴰⵎⵣⴰⵔⴰⵢ ⴳⵔ ⵉⵣⵣⵔⴰⵢⵏ ⵏ $1",
        "lineno": "ⵉⵣⵔⵉⵔⵉ $1:",
        "compareselectedversions": "ⵙⵎⵣⴰⵣⴰⵍ ⵉⵣⵣⵔⴰⵢⵏ ⵉⵜⵜⵓⵙⵜⴰⵢⵏ",
        "editundo": "ⵙⵔ",
        "diff-empty": "(ⵓⵔ ⵉⵍⵍⵉ ⵓⵎⵣⴰⵔⴰⵢ)",
+       "diff-multi-sameuser": "({{PLURAL:$1|ⴽⵔⴰ ⵏ ⵓⵣⵣⵔⴰⵢ ⵉⵏⵏⵓⵎⵎⵙⵏ ⵉⵙⴽⵔ ⵓⵏⵙⵙⵎⵔⵙ ⵉⴳⴰⵏ ⵢⴰⵏ ⵓⵔ ⵜⴻⵜⵜⵓⵙⴽⴰⵏ|$1 ⴽⵔⴰ ⵏ ⵉⵣⵣⵔⴰⵢⵏ ⵉⵏⵏⵓⵎⵎⵙⵏ ⵉⵙⴽⵔ ⵓⵏⵙⵙⵎⵔⵙ ⵉⴳⴰⵏ ⵢⴰⵏ ⵓⵔ ⵜⵜⵓⵙⴽⴰⵏⴻⵏⵜ}})",
+       "diff-multi-otherusers": "({{PLURAL:$1|ⵢⴰⵏ ⵓⵣⵣⵔⴰⵢ ⴰⵎⵏⵏⵓⵎⵎⵙ|$1 ⵏ ⵉⵣⵣⵔⴰⵢⵏ ⵉⵎⵏⵏⵓⵎⵎⵙⵏ}} ⵏ {{PLURAL:$2|ⵢⴰⵏ ⵓⵏⵙⵙⵎⵔⵙ ⵢⴰⴹⵏ|$2 ⵏ ⵉⵏⵙⵙⵎⵔⵙⵏ}} ⵓⵔ ⵉⵜⵜⵓⵙⴽⴰⵏⴻⵏ).",
        "searchresults": "ⵜⵉⵢⴰⴼⵓⵜⵉⵏ ⵏ ⵓⵔⵣⵣⵓ",
        "searchresults-title": "ⵜⵉⵢⴰⴼⵓⵜⵉⵏ ⵏ ⵓⵔⵣⵣⵓ ⵖⴼ \"$1\"",
        "prevn": "{{PLURAL:$1|$1}} ⵉⵎⵣⵡⵓⵔⴰ",
        "nextn": "{{PLURAL:$1|$1}} ⴰⵎⴹⴼⵉⵔ",
+       "prevn-title": "$1 {{PLURAL:$1|ⵜⴰⵢⴰⴼⵓⵜ ⵉⵣⵔⵉⵏ|ⵜⵉⵢⴰⴼⵓⵜⵉⵏ ⵣⵔⵉⵏⵉⵏ}}",
        "nextn-title": "$1 ⵏ {{PLURAL:$1|ⵜⴰⵢⴼⵓⵜ|ⵜⵉⵢⴰⴼⵓⵜⵉⵏ}} ⵢⴰⴹⵏ",
        "shown-title": "ⵙⵎⴰⵍ $1 {{PLURAL:$1|ⵜⵢⴰⴼⵓⵜ|ⵜⵢⴰⴼⵓⵜⵉⵏ}} ⵉ ⵜⴰⵙⵏⴰ",
        "viewprevnext": "ⵥⵕ ($1 {{int:pipe-separator}} $2) ($3)",
+       "searchmenu-exists": "<strong>ⵜⵍⵍⴰ ⵢⴰⵜ ⵜⴰⵙⵏⴰ ⵉⴳⴰⵏ ⵙ ⵢⵉⵙⵎ \"[[:$1]]\" ⴳ ⵡⵉⴽⵉ ⴰⴷ.</strong>{{PLURAL:$2|0=|ⵥⵔ ⴰⵍⵜⵓ ⵜⵉⵢⴰⴼⵓⵜⵉⵏ ⵏ ⵓⵔⵣⵣⵓ ⵜⵜⵢⴰⴼⴰⵏⵉⵏ.}}",
        "searchmenu-new": "<strong>ⵙⵏⵓⵍⴼⵓ ⵜⴰⵙⵏⴰ \"[[:$1]]\" ⴳ ⵓⵡⵉⴽⵉ ⴰⴷ!</strong> {{PLURAL:$2|0=|ⵥⵔ ⴰⵍⵜⵓ ⵜⴰⵙⵏⴰ ⵏⵏⴰ ⵢⵓⴼⴰ ⵓⵔⵣⵣⵓ ⵏⵏⴽ.|ⵥⵔ ⴰⵍⵜⵓ ⵜⵉⵢⴰⴼⵓⵜⵉⵏ ⵏ ⵓⵔⵣⵣⵓ.}}",
        "searchprofile-articles": "ⵜⴰⵙⵏⵉⵡⵉⵏ ⵏ ⵜⵓⵎⴰⵢⵜ",
        "searchprofile-images": "ⵎⵓⵍⵜⵉⵎⵉⴷⵢⴰ",
        "searchprofile-everything-tooltip": "ⵔⵣⵓ ⴳ ⵜⵓⵎⴰⵢⵜ ⴰⴽⴽⵯ (ⵓⵍⴰ ⴳ ⵜⴰⵙⵏⵉⵡⵉⵏ ⵏ ⵓⵎⵙⴰⵡⴰⵍ)",
        "searchprofile-advanced-tooltip": "ⵔⵣⵓ ⴳ ⵜⵉⵔⵉⵡⵉⵏ ⵏ ⵉⵙⵎⴰⵡⵏ ⵉⵜⵡⴰⵏⵉⵎⴰⵏ",
        "search-result-size": "$1 ({{PLURAL:$2|1 ⵜⴳⵓⵔⵉ|$2 ⵜⴳⵓⵔⵉⵡⵉⵏ}})",
+       "search-result-category-size": "{{PLURAL:$1|ⵢⴰⵏ ⵓⴳⵎⴰⵎ|$1 ⵏ ⵉⴳⵎⴰⵎⵏ}} ({{PLURAL:$2|ⵢⴰⵏ ⵓⴷⵓⵙⵎⵉⵍ|$2 ⵏ ⵉⴷⵓⵙⵎⵉⵍⵏ}}, {{PLURAL:$3|ⵢⴰⵏ ⵓⴼⴰⵢⵍⵓ|$3 ⵏ ⵉⴼⵓⵢⵍⴰ}})",
        "search-redirect": "(ⵓⵖⵓⵍ ⵙⴳ $1)",
        "search-section": "(ⴰⵙⴱⴹⵓ $1)",
+       "search-file-match": "(ⵉⵎⵙⴰⵙⴰ ⴷ ⵜⵓⵎⴰⵢⵜ ⵏ ⵓⴼⴰⵢⵍⵓ)",
        "search-suggest": "ⵉⵙ ⵜⵅⵙⴷ ⴰⴷ ⵜⵉⵏⵉⴷ: $1",
        "search-interwiki-more": "(ⵓⴳⴳⴰⵔ)",
-       "searchall": "ⴰⴽⴽ",
+       "searchall": "ⵎⴰⵕⵕⴰ",
+       "search-showingresults": "{{PLURAL:$4|ⵜⴰⵢⴰⴼⵓⵜ <strong>$1</strong> ⵙⴳ <strong>$3</strong>|ⵜⵉⵢⴰⴼⵓⵜⵉⵏ <strong>$1 ⴳ $2</strong> ⵙⴳ <strong>$3</strong>}}",
        "search-nonefound": "ⵓⵔ ⵍⵍⵉⵏⵜ ⵜⵢⴰⴼⵓⵜⵉⵏ ⵉⵎⵙⴰⵙⴰⵏ ⴷ ⵓⵙⵓⵜⵔ.",
+       "powersearch-toggleall": "ⵎⴰⵕⵕⴰ",
        "mypreferences": "ⵉⵙⵎⵏⵢⵉⴼⵏ",
        "prefs-watchlist-days": "ⵓⵙⵙⴰⵏ ⵜⵓⵙⴽⵏⵉⵏ ⴳ ⵓⵎⵓⵖ ⵓⵙⵎⵓⵇⵇⵍ",
        "recentchangesdays": "ⵓⵙⵙⴰⵏ ⵜⵓⵙⴽⵏⵉⵏ ⴳ ⵉⵙⵏⴼⵉⵍⵏ ⵉⵎⴳⴳⵓⵔⴰ",
        "email": "ⵉⵎⴰⵢⵍ",
        "prefs-signature": "ⴰⵙⴳⵎⴹ",
        "userrights-reason": "ⵜⴰⵎⵏⵜⵉⵍⵜ:",
+       "group-bot": "ⵉⵔⵓⴱⵓⵜⵏ",
        "group-sysop": "ⵉⵏⵎⵀⴰⵍⵏ",
+       "group-all": "(ⵎⴰⵕⵕⴰ)",
+       "grouppage-bot": "{{ns:project}}:ⵉⵔⵓⴱⵓⵜⵏ",
+       "grouppage-sysop": "{{ns:project}}:ⵉⵎⵙⵙⵓⴳⵓⵔⵏ",
        "right-edit": "ⵙⵏⴼⵍ ⵜⴰⵙⵏⵉⵡⵉⵏ",
        "right-upload": "ⵙⴽⵜⵔ ⵉⴼⴰⵢⵍⵓⵜⵏ",
        "right-upload_by_url": "ⵙⴽⵜⵔ ⴰⴼⴰⵢⵍⵓ ⵙⴳ URL",
        "right-writeapi": "ⴰⵙⵙⵎⵔⵙ ⵏ API ⵉ ⵜⵉⵔⵔⴰ",
        "right-delete": "ⴽⴽⵙ ⵜⴰⵙⵏⵉⵡⵉⵏ",
        "newuserlogpage": "ⴰⵔⵔⴰ ⵏ ⵉⵙⵏⴼⴰⵍⵏ ⵏ ⵉⵎⵉⴹⴰⵏⴻⵏ ⵏ ⵉⵙⵙⵎⵔⴰⵙⵏ",
+       "rightslog": "ⵜⴰⵎⵙⵙⴽⵜⵉⵜ ⵏ ⵢⵉⵣⵔⴼⴰⵏ ⵏ ⵢⵉⵏⵙⵙⵔⵎⴰⵙⵏ",
        "action-edit": "ⵙⵏⴼⵍ ⵜⴰⵙⵏⴰ ⴰ",
        "action-createpage": "ⵙⵏⵓⵍⴼⵓ ⵜⴰⵙⵏⴰ ⴰ",
        "action-createaccount": "ⵙⴽⵔ ⴰⵎⵉⴹⴰⵏ ⴰⴷ ⵏ ⵓⵏⵙⵙⵎⵔⵙ",
        "recentchanges": "ⵉⵙⵏⴼⵍⵏ ⵉⵎⴳⴳⵓⵔⴰ",
        "recentchanges-legend": "ⵜⵉⴷⵖⵔⵉⵏ ⵏ ⵉⵙⵏⴼⵍⵏ ⵉⵎⴳⴳⵓⵔⴰ",
        "recentchanges-summary": "ⴹⴼⵔ ⵉⵙⵏⵉⴼⵉⵍⵏ ⵉⵎⴳⴳⵓⵔⴰ ⴰⴽⴽ ⵖⴼ ⵓⵡⵉⴽⵉ ⴷⴳ ⵜⴰⵙⵏⴰ ⴰⴷ.",
+       "recentchanges-noresult": "ⵓⵔ ⵍⵍⵉⵏ ⵉⵙⵏⵉⴼⵉⵍⵏ ⵉⵎⵙⴰⵙⴰⵏ ⴷ ⵉⵙⴼⵔⴰⵏⴻⵏ ⴳ ⵜⵉⵣⵉ ⵉⵜⵜⵓⴼⴽⴰⵏ.",
+       "recentchanges-feed-description": "ⴹⴼⵔ ⵉⵙⵏⵉⴼⵉⵍⵏ ⵉⵎⴳⴳⵓⵔⴰ ⴰⴽⴽ ⵖⴼ ⵓⵡⵉⴽⵉ ⴷⴳ ⵜⴰⵙⵏⴰ ⴰⴷ.",
        "recentchanges-label-newpage": "ⵉⵙⵏⴼⵍⵓⵍ ⵓⵙⵏⴼⵍ ⴰ ⵢⴰⵜ ⵜⴰⵙⵏⴰ ⵜⴰⵎⴰⵢⵏⵓⵜ",
        "recentchanges-label-minor": "ⵡⴰ ⴷ ⴰⵙⵏⴼⵍ ⵓⵎⵥⵉⵢ",
        "recentchanges-label-bot": "ⴰⵙⵏⴼⵍ ⴰⴷ ⵉⵜⵡⴰⵙⴽⴰⵔ ⵙ ⵓⴱⵓⵜ",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (ⵥⵔ ⴰⵍⵜⵓ [[Special:NewPages|ⵜⴰⵍⴳⴰⵎⵜ ⵏ ⵜⴰⵙⵏⵉⵡⵉⵏ ⵜⵉⵎⴰⵢⵏⵓⵜⵉⵏ]])",
        "rcfilters-days-title": "ⵓⵙⵙⴰⵏ ⵉⵎⴳⴳⵓⵔⴰ",
        "rcfilters-days-show-days": "$1 ⵏ {{PLURAL:$1|ⵡⴰⵙⵙ|ⵡⵓⵙⵙⴰⵏ}}",
+       "rcnotefrom": "ⴳ ⵢⵉⵣⴷⴰⵔ {{PLURAL:$5|ⴰⵙⵏⴼⵍ ⵉⵜⵜⵓⵙⴽⴰⵔⵏ|ⵉⵙⵏⵉⴼⵉⵍⵏ ⵉⵜⵜⵓⵙⴽⴰⵔⵏ}} ⵙⴳ <strong>$3, $4</strong> (ⵉⵜⵜⵓⵙⴽⴰⵏⴻⵏ ⴰⵔ <strong>$1</strong>).",
        "rclistfrom": "ⵙⴽⵏ ⵉⵙⵏⴼⵍⵏ ⵉⵎⴰⵢⵏⵓⵜⵏ ⵙⴳ $2,$3",
        "rcshowhideminor": "$1 ⵉⵙⵏⴼⴰⵍ ⵓⵎⵥⵉⵢⵏ",
        "rcshowhideminor-show": "ⵙⴽⵏ",
        "rcshowhideanons": "$1 ⵉⵏⵙⵙⵎⵔⵙⵏ ⵉⵔⵓⵙⵙⵉⵏⵏ",
        "rcshowhideanons-show": "ⵙⴽⵏ",
        "rcshowhideanons-hide": "ⵙⵙⵏⵜⵍ",
+       "rcshowhidepatr": "$1 ⵉⵙⵏⴼⵍⵏ ⵜⵜⵡⴰⵃⴹⴰⵏⵉⵏ",
        "rcshowhidemine": "$1 ⵉⵙⵏⴼⴰⵍ ⵉⵏⵓ",
        "rcshowhidemine-show": "ⵙⴽⵏ",
        "rcshowhidemine-hide": "ⵙⵙⵏⵜⵍ",
        "newpageletter": "ⵎⵢⵏ",
        "boteditletter": "ⴱⵓⵜ",
        "rc-change-size-new": "$1 {{PLURAL:$1|ⴱⴰⵢⵜ|ⵉⴷ ⴱⴰⵢⵜ}} ⴷⴼⴼⵉⵔ ⵏ ⵓⵙⵏⴼⵍ",
+       "rc-old-title": "ⵜⴻⵜⵜⵢⴰⵙⴽⴰⵔ ⵜⵉⵣⵡⵓⵔⵉ ⵙ ⵓⵣⵡⵍ $1",
        "recentchangeslinked": "ⵉⵙⵏⴼⴰⵍ ⵏⵏⴰ ⵖⵓⵔ ⴰⵙⵙⴰⵖ",
        "recentchangeslinked-feed": "ⵉⵙⵏⴼⵍⵏ ⵇⵇⵏⵏⵉⵏ",
        "recentchangeslinked-toolbox": "ⵉⵙⵏⴼⵍⵏ ⵇⵇⵏⵏⵉⵏ",
        "recentchangeslinked-title": "ⵉⵙⵏⴼⵍⵏ ⵇⵇⵏⵏⵉⵏ ⵙ $1",
-       "recentchangeslinked-summary": "âµ\99â´½âµ\9bâµ\8e âµ\89âµ\99âµ\8e âµ\8f âµ\9câ´°âµ\99âµ\8fâ´° âµ\83âµ\8eâ´° â´°â´· âµ\9câµ£âµ\94â´· âµ\89âµ\99âµ\8fⴼⴰâµ\8dâµ\8f âµ\89âµ\8eâ´°âµ¢âµ\8fâµ\93âµ\9câµ\8f â´³ âµ\9câ´°âµ\99âµ\8fâµ\89ⵡâµ\89âµ\8f âµ\99â´³ âµ\8fâµ\96 âµ\96âµ\94 âµ\9câ´°âµ\99âµ\8fâ´° â´°â´· (âµ\83âµ\8eâ´° â´°â´· âµ\9câµ£âµ\94â´· âµ\89â´³âµ\8eâ´°âµ\8eâµ\8f âµ\8f â´½âµ\94â´° âµ\8f âµ\93âµ\99âµ\8eâµ\89âµ\8d, âµ\99â´½âµ\9bâµ\8e â´°âµ\99âµ\8eâµ\89âµ\8d: âµ\89âµ\99âµ\8e âµ\8f âµ\93âµ\99âµ\8eâµ\89âµ\8d). âµ\89âµ\99âµ\8fâ´¼âµ\8dâµ\8f âµ\8f âµ\9câ´°âµ\99âµ\8fâµ\89ⵡâµ\89âµ\8f âµ\89âµ\8dâµ\8dâ´°âµ\8f â´³ [[Special:Watchlist|âµ\9câ´°âµ\8dⴳⴰâµ\8eâµ\9c âµ\8f âµ\93ⴹⴼⴼâµ\93âµ\94 ⵏⴽ]] ⵔⴰⴷ ⵜⵢⴰⵔⴰⵏ ⵙ <strong>ⵓⵣⵓⵔⴰⵔ</strong>",
+       "recentchangeslinked-summary": "âµ\99â´½âµ\9bâµ\8e âµ\89âµ\99âµ\8e âµ\8f âµ\9câ´°âµ\99âµ\8fâ´° âµ\83âµ\8eâ´° â´°â´· âµ\9câµ£âµ\94â´· âµ\89âµ\99âµ\8fâµ\89â´¼âµ\89âµ\8dâµ\8f âµ\89âµ\8eâ´°âµ¢âµ\8fâµ\93âµ\9câµ\8f â´³ âµ\9câ´°âµ\99âµ\8fâµ\89ⵡâµ\89âµ\8f âµ\89âµ\9câµ\9cⴰⵡâµ\89âµ\8f âµ\99â´³ âµ\8fâµ\96 âµ\96âµ\94 âµ\9câ´°âµ\99âµ\8fâ´° â´°â´· (ⴼⴰâµ\94 â´°â´· âµ\9câµ¥âµ\94â´· âµ\89â´³âµ\8eâ´°âµ\8eâµ\8f âµ\8f â´½âµ\94â´° âµ\8f âµ\93âµ\99âµ\8eâµ\89âµ\8d, âµ\99â´½âµ\9bâµ\8e â´°âµ\99âµ\8eâµ\89âµ\8d: âµ\89âµ\99âµ\8e âµ\8f âµ\93âµ\99âµ\8eâµ\89âµ\8d). âµ\89âµ\99âµ\8fâµ\89â´¼âµ\89âµ\8dâµ\8f âµ\8f âµ\9câ´°âµ\99âµ\8fâµ\89ⵡâµ\89âµ\8f âµ\89âµ\8dâµ\8dâ´°âµ\8f â´³ [[Special:Watchlist|âµ\9câ´°âµ\8dⴳⴰâµ\8eâµ\9c âµ\8f âµ\93ⴹⴼⴼâµ\93âµ\94 âµ\8fⵏⴽ]] ⵔⴰⴷ ⵜⵢⴰⵔⴰⵏ ⵙ <strong>ⵓⵣⵓⵔⴰⵔ</strong>",
        "recentchangeslinked-page": "ⵉⵙⵎ ⵏ ⵜⴰⵙⵏⴰ:",
        "recentchangeslinked-to": "ⵙⵎⴰⵍ ⵉⵙⵏⴼⵍⵏ ⵏ ⵜⴰⵙⵏⵉⵡⵉⵏ ⵉⵣⴷⵉⵏ ⴷ ⵜⴰⵙⵏⴰ ⵉⵜⵜⵓⴼⴽⴰⵏ ⴱⵍⴰ ⴰⴽⴽⵯ ⵎⴽ ⴰⴷ",
        "upload": "ⵙⴽⵜⵔ ⴰⴼⴰⵢⵍⵓ",
        "uploadbtn": "ⵙⴽⵜⵔ ⴰⴼⴰⵢⵍⵓ",
+       "uploadlogpage": "ⵜⵉⵎⵙⵙⴽⵜⵉⵏ ⵏ ⵓⵙⵙⴽⵜⵔ",
        "filedesc": "ⴰⵙⴳⵣⵍ",
        "upload-form-label-infoform-name": "ⵉⵙⵎ",
        "upload-form-label-usage-filename": "ⵉⵙⵎ ⵏ ⵓⴼⴰⵢⵍⵓ",
        "upload-form-label-infoform-date": "ⴰⵙⴰⴽⵓⴷ",
+       "license": "ⵜⵓⵔⴰⴳⵜ",
        "license-header": "ⵜⵓⵔⴰⴳⵜ",
        "listfiles-delete": "ⴽⴽⵙ",
        "imgfile": "ⴰⴼⴰⵢⵍⵓ",
        "file-anchor-link": "ⴰⴼⴰⵢⵍⵓ",
        "filehist": "ⴰⵎⵣⵔⵓⵢ ⵏ ⵓⴼⴰⵢⵍⵓ",
        "filehist-help": "ⴰⴷⵔ ⵖⴼ ⵓⵙⴰⴽⵓⴷ/ⴰⴽⵓⴷ ⵃⵎⴰ ⴰⴷ ⵜⵥⵔⴷ ⴰⵙⴷⴰⵡ ⵎⴰⵎⴽ ⵢⴰⴷⵍⵍⵉ ⵉⴳⴰ ⴰⵇⵓⴷ ⴰⵏ.",
+       "filehist-deleteall": "ⴽⴽⵙ ⵎⴰⵕⵕⴰ",
        "filehist-deleteone": "ⴽⴽⵙ",
+       "filehist-revert": "ⵔⴰⵔ ⴷ",
        "filehist-current": "ⴰⵎⵉⵔⴰⵏ",
        "filehist-datetime": "ⴰⵙⴰⴽⵓⴷ/ⴰⴽⵓⴷ",
-       "filehist-thumb": "âµ\9câ´°âµ\9bâµ\8fⵢⴰâµ\8dâµ\9c",
+       "filehist-thumb": "âµ\9cⴰⵡâµ\8dâ´°â´¼âµ\9c âµ\8eⵥⵥâµ\89âµ¢âµ\8f",
        "filehist-thumbtext": "ⵜⴰⵛⵏⵢⴰⵍⵜ ⵏ ⵜⵓⵏⵖⵉⵍⵜ ⴳ $1",
+       "filehist-nothumb": "ⵓⵔ ⵉⵍⵍⵉ ⵓⵙⵎⵥⵉⵢ",
        "filehist-user": "ⴰⵙⵎⵔⴰⵙ",
        "filehist-dimensions": "ⵉⵎⵏⴰⴷⵏ",
        "filehist-comment": "ⴰⵖⴼⴰⵡⴰⵍ",
        "imagelinks": "ⴰⵙⵎⵔⵙ ⵏ ⵓⴼⴰⵢⵍⵓ",
        "linkstoimage": "{{PLURAL:$1|ⵉⵣⴷⴰⵢⵏ ⵏ ⵜⵙⵏⴰ|$1 ⴰⵣⴷⴰⵢ ⵏ ⵜⵙⵏⴰ}} ⵖⵔ ⵓⴼⴰⵢⵍⵓ ⴰⴷ:",
+       "linkstoimage-more": "ⵓⴳⴳⴰⵔ ⵏ {{PLURAL:$1|ⵢⴰⵜ ⵜⴰⵙⵏⴰ ⴰⵢⴷ ⵉⵙⵙⵎⵔⴰⵙⵏ| $1 ⵏ ⵜⴰⵙⵏⵉⵡⵉⵏ ⴰⵢⴷ ⵉⵙⵙⵎⵔⴰⵙⵏ}} ⴰⴼⴰⵢⵍⵓ ⴰⴷ.\nⵜⵙⴽⴰⵏ ⵜⵍⴳⴰⵎⵜ ⴰⴷ ⵖⴰⵙ {{PLURAL:$1|ⵜⴰⵙⵏⴰ ⵜⴰⵎⵣⵡⴰⵔⵓⵜ  ⵉⵙⵙⵎⵔⴰⵙⵏ $1 ⵜⴰⵙⵏⵉⵡⵉⵏ ⵜⵉⵎⵣⵡⴰⵔⴰ ⵉⵙⵙⵎⵔⴰⵙⵏ}} ⴰⴼⴰⵢⵍⵓ ⴰⴷ.\nⵜⵍⵍⴰ ⵢⴰⵜ [[Special:WhatLinksHere/$2|ⵜⴰⵍⴳⴰⵎⵜ ⵉⵎⴷⵏ]].",
        "nolinkstoimage": "ⵓⵔ ⵍⵍⵉⵏⵜ ⵜⴰⵙⵏⵉⵡⵉⵏ ⵏⵏⴰ ⵉⵇⵇⵏⴻⵏ ⵖⵔ ⵓⴼⴰⵢⵍⵓ ⴰ.",
+       "linkstoimage-redirect": "$1 (ⴰⵙⵡⴰⵍⴰ ⵏ ⵓⴼⴰⵢⵍⵓ) $2",
        "sharedupload-desc-here": "ⴰⵙⴷⴰⵡ ⴰⴷ ⵙⴳ $1 ⵉⵥⴹⴰⵔ ⴰ ⵉⵜⵜⵡⴰⵙⵎⵔⵙ ⴳ ⵉⵙⵏⵜⴰⵢⵏ ⵢⴰⴹⵏ.\nⴰⵙⵏⵓⵎⵎⵍ ⵏⵙ ⴳ [$2 ⵜⴰⵙⵏⴰ ⵏⵙ ⵏ ⵓⵙⵏⵓⵎⵎⵍ] ⵜⵡⴰⵙⵎⴰⵍ ⵙⴰⴷⵓ.",
        "filepage-nofile": "ⵓⵔ ⵓⴼⴰⵢⵍⵓ ⵙ ⵢⵉⵙⵎ ⴰ.",
        "upload-disallowed-here": "ⵓⵔ ⵜⵓⴼⵉⵜ ⴰ ⵜⵙⵎⵎⵙⴽⵍⴷ ⴰⵙⴷⴰⵡ ⴰⴷ.",
        "filedelete-submit": "ⴽⴽⵙ",
        "download": "ⴰⴳⵎ",
        "randompage": "ⵜⴰⵙⵏⴰ ⵜⴰⴷⵀⵎⴰⵙⵜ",
+       "randomincategory-submit": "ⴷⴷⵓ",
        "statistics": "ⴰⵙⵏⵎⴽⵜⴰ",
        "statistics-pages": "ⵜⴰⵙⵏⵉⵡⵉⵏ",
+       "pageswithprop-submit": "ⴷⴷⵓ",
+       "double-redirect-fixer": "ⴰⵎⵙⵙⵖⵜⵉ ⵏ ⵓⵎⵙⵡⴰⵍⴰ",
        "brokenredirects-edit": "ⵙⵏⴼⵍ",
        "brokenredirects-delete": "ⴽⴽⵙ",
        "withoutinterwiki-legend": "ⴰⵣⵡⵉⵔ",
        "listusers": "ⵓⵎⵓⵖ ⵏ ⵓⵏⵙⵙⵎⵔⵙ",
        "newpages": "ⵜⴰⵙⵏⵉⵡⵉⵏ ⵜⵉⵎⴰⵢⵏⵓⵜⵉⵏ",
        "move": "ⵙⵎⵓⵜⵜⵉ",
+       "pager-newer-n": "{{PLURAL:$1|1 ⴰⵎⴰⵢⵏⵓ ⴰⴽⴽ|$1 ⴰⵎⴰⵢⵏⵓ ⴰⴽⴽ}}",
+       "pager-older-n": "{{PLURAL:$1|1 ⴰⵣⴰⵢⴽⵓ ⴰⴽⴽ|$1 ⴰⵣⴰⵢⴽⵓ ⴰⴽⴽ}}",
        "apisandbox-examples": "ⵉⵎⴷⵢⴰⵜⵏ",
        "booksources": "ⵉⵙⵓⴳⴰⵎ ⵏ ⵓⴷⵍⵉⵙ",
        "booksources-search-legend": "ⵔⵣⵓ ⵅⴼ ⵉⴷⵍⵉⵙⵏ ⵏ ⵓⵙⴰⴳⵎ",
        "booksources-search": "ⵔⵣⵓ",
+       "specialloguserlabel": "ⴰⵎⵙⴽⴰⵔ:",
+       "speciallogtitlelabel": "ⴰⵙⴰⵖⴷ (ⴰⵣⵡⵍ ⵏⵖ {{ns:user}}:ⵉⵙⵎ ⵏ ⵓⵏⵙⵙⵔⵙ) :",
        "log": "ⵉⵣⵎⵎⴻⵎⵏ",
-       "allpages": "ⵎⴰⵕⵕⴰ ⵜⴰⵙⵏⵉⵡⵉⵏ",
+       "all-logs-page": "ⵜⵉⵎⵙⵙⴽⵜⵉⵜⵉⵏ ⴰⴽⴽ ⵜⵉⵣⴰⵢⵣⵉⵏ",
+       "alllogstext": "ⴰⵙⴽⴰⵏ ⵉⵎⵎⵔⴽⵙⵏ ⵏ ⵜⵎⵙⵙⴽⵜⵉⵜⵉⵏ ⴰⴽⴽ ⵉⵍⵍⴰⵏ ⴳ {{SITENAME}}.\nⵜⵓⴼⵉⴷ ⴰⴷ ⵜⵙⵏⵏⵥⵍⵉⴷ ⴰⵙⴽⴰⵏ ⵙ ⵓⵙⵜⴰⵢ ⵏ ⵡⴰⵏⴰⵡ ⵏ ⵜⵎⵙⵙⴽⵜⵉⵜ, ⵉⵙⵎ ⵏ ⵓⵏⵙⵙⵎⵔⵙ ⵏⵖ ⵜⴰⵙⵏⴰ ⵉⴳⴰ ⵡⴰⴷⴷⴰⴷ (ⵙⵉⵏ ⵉⵎⴳⴳⵓⵔⴰ ⴰⴷ ⵇⵇⵏⴻⵏ ⵖⵔ ⵓⵙⵎⵉⵍ).",
+       "logempty": "ⵓⵔ ⵜⵍⵍⵉ ⴰⵡⴷ ⵢⴰⵜ ⵜⵎⵀⵍⵜ ⵉⵎⵙⴰⵙⴰⵏ ⴳ ⵜⵎⵙⵙⴽⵜⵉⵜⵉⵏ.",
+       "checkbox-all": "ⵎⴰⵕⵕⴰ",
+       "allpages": "ⵜⴰⵙⵏⵉⵡⵉⵏ ⴰⴽⴽ",
        "allarticles": "ⵜⴰⵙⵏⵉⵡⵉⵏ ⴰⴽⴽ",
        "allpagessubmit": "ⴷⴷⵓ",
        "allpages-hide-redirects": "ⵙⵙⵏⵜⵍ ⵉⵙⵡⴰⵍⴰⵜⵏ",
        "categories": "ⵉⵙⵎⵉⵍⵏ",
        "sp-deletedcontributions-contribs": "ⵜⵓⵎⵓⵜⵉⵏ",
        "listgrouprights-members": "ⵜⴰⵍⴳⴰⵎⵜ ⵏ ⵉⴳⵎⴰⵎⵏ",
+       "listgrouprights-addgroup-all": "ⵔⵏⵓ ⵎⴰⵕⵕⴰ ⵜⵉⵔⴰⴱⴱⵓⵜⵉⵏ",
+       "listgrouprights-removegroup-all": "ⴽⴽⵙ ⵎⴰⵕⵕⴰ ⵜⵉⵔⴰⴱⴱⵓⵜⵉⵏ",
+       "emailuser": "ⴰⵣⵏ ⵉⵎⴰⵢⵍ ⵉ ⵓⵏⵙⵙⵎⵔⵙ ⴰ",
+       "emailmessage": "ⵜⵓⵣⵉⵏⵜ:",
        "usermessage-editor": "ⵓⴷⵓⵙ ⵏ ⵓⵎⵢⴰⵣⴰⵏ",
        "watchlist": "ⵜⴰⵍⴳⴰⵎⵜ ⵏ ⵓⴹⴼⴼⵓⵔ",
        "mywatchlist": "ⵜⴰⵍⴳⴰⵎⵜ ⵏ ⵓⴹⴼⴼⵓⵔ",
        "watchlistfor2": "ⵉ $1 $2",
        "watch": "ⵥⵕ",
+       "unwatch": "ⴽⴽⵙ ⴰⴹⴼⴼⵓⵔ",
+       "watchlist-details": "{{PLURAL:$1|$1 ⵜⴰⵙⵏⴰ|$1 ⵏ ⵜⴰⵙⵏⵉⵡⵉⵏ}} ⴳ ⵜⵍⴳⴰⵎⵜ ⵏ ⵓⴹⴼⴼⵓⵔ ⵏⵏⴽ (ⴰⴽⴷ ⵜⴰⵙⵏⵉⵡⵉⵏ ⵏ ⵓⵎⵙⴰⵡⴰⵍ).",
+       "wlheader-showupdated": "ⵜⴰⵙⵏⵉⵡⵉⵏ ⵏⵏⴰ ⵉⵜⵜⵓⵙⵏⴼⵍⵏ ⵙⴳ ⵜⵔⵣⴼⵜ ⵏⵏⴳ ⵜⴰⵎⴳⴳⴰⵔⵓⵜ ⵜⵜⵓⵙⴽⴰⵏⴻⵏⵜ ⵙ  <strong>ⴰⵣⵓⵔⴰⵔ</strong>.",
+       "wlnote": "ⴳ ⵓⴼⵍⵍⴰ, {{PLURAL:$1|ⵢⵓⵎⴰⵏ ⵓⵙⵏⴼⵍ ⴰⵎⴳⴳⴰⵔⵓ ⵉⵜⵜⵡⴰⵙⴽⴰⵔⵏ|ⵓⵎⴰⵏⴻⵏ <strong>$1</strong> ⵏ ⵉⵙⵏⵉⴼⵉⵍⵏ ⵉⵎⴳⴳⵓⵔⴰ ⵉⵜⵜⵢⴰⵙⴽⴰⵔⵏ}} {{PLURAL:$2|ⵢⴰⵜ ⵜⵙⵔⴰⴳⵜ ⴰⵢⴰ|ⵢⴰⵏ <strong>$2</strong> ⵏ ⵜⵙⵔⴰⴳⵉⵏ ⴰⵢⴰ}}, ⴰⵔ $3, $4.",
        "wlshowlast": "ⵙⴽⵏ $1 ⵜⴰⵙⵔⴰⴳⵉⵏ $2 ⵓⵙⵙⴰⵏ ⵉⵎⴳⴳⵓⵔⴰ",
        "watchlist-options": "ⵜⵉⴷⵖⵔⵉⵏ ⵏ ⵜⵍⴳⴰⵎⵜ ⵏ ⵓⴹⴼⴼⵓⵔ",
        "enotif_reset": "ⴷⵔⵣ ⵜⴰⵙⵏⵉⵡⵉⵏ ⴰⴽⴽ ⵏⵏⴰ ⵜⵔⵣⴼⴷ",
        "deletepage": "ⴽⴽⵙ ⵜⴰⵙⵏⴰ",
        "delete-confirm": "ⴽⴽⵙ \"$1\"",
        "delete-legend": "ⴽⴽⵙ",
+       "dellogpage": "ⵜⴰⵎⵙⵙⴽⵜⵉⵜ ⵏ ⵜⵓⴽⴽⵙⴰ",
        "deletecomment": "ⵜⴰⵎⵏⵜⵉⵍⵜ:",
        "rollbacklink": "ⵔⴰⵔ",
+       "rollbacklinkcount": "ⵔⴰⵔ ⴷ $1 {{PLURAL:$1|ⴰⵙⵏⴼⵍ|ⵉⵙⵏⵉⴼⵉⵍⵏ}}",
        "changecontentmodel-reason-label": "ⵜⴰⵎⵏⵜⵉⵍⵜ:",
+       "protectlogpage": "ⵜⴰⵎⵙⵙⴽⵜⵉⵜ ⵏ ⵓⴼⵔⴰⴳ",
        "protectedarticle": "ⵉⵎⵃⴹⵉ \"[[$1]]\"",
+       "modifiedarticleprotection": "ⵉⵙⵏⴼⵍ ⴰⵙⵡⵉⵔ ⵏ ⵓⴼⵔⴰⴳ ⵉ \"[[$1]]\"",
        "protectcomment": "ⵜⴰⵎⵏⵜⵉⵍⵜ:",
        "protect-default": "ⴰⵊⵊ ⵉⵎⵙⵙⵎⵔⵙⵏ ⴰⴽⴽⵯ",
        "restriction-edit": "ⵙⵏⴼⵍ",
        "mycontris": "ⵜⵓⵎⵓⵜⵉⵏ",
        "anoncontribs": "ⵜⵓⵎⵓⵜⵉⵏ",
        "contribsub2": "ⵉ {{GENDER:$3|$1}} ($2)",
+       "nocontribs": "ⴰⵡⴷ ⵢⴰⵏ ⵓⵙⵏⴼⵍ ⵉⵎⵙⴰⵙⴰⵏ ⴷ ⵉⵙⴼⵔⴰⵏⴻⵏ ⴰⴷ ⵓⵔ ⵉⵜⵜⵢⴰⴼⴰ.",
        "uctop": "(ⴰⵎⵉⵔⴰⵏ)",
        "month": "ⵙⴳ ⵡⴰⵢⵢⵓⵔ (and earlier):",
        "year": "ⵙⴳ ⵓⵙⴳⴳⵯⴰⵙ (and earlier):",
        "sp-contributions-newbies": "ⵙⴽⵏ ⵜⵓⵎⵓⵜⵉⵏ ⵏ ⵉⵎⵉⴹⴰⵏ ⵉⵎⴰⵢⵏⵓⵜⵏ ⴽⴰⵏ",
+       "sp-contributions-blocklog": "ⵜⴰⵎⵙⵙⴽⵜⵉⵜ ⵏ ⵓⴳⴷⴷⵓⵍ",
        "sp-contributions-uploads": "ⵉⵙⴽⵜⴰⵔⵏ",
+       "sp-contributions-logs": "ⵜⵉⵎⵙⵙⴽⵜⵉⵢⵉⵏ",
        "sp-contributions-talk": "ⵎⵙⴰⵡⴰⵍ",
        "sp-contributions-search": "ⵔⵣⵓ ⵖⴼ ⵜⵓⵎⵓⵜⵉⵏ",
        "sp-contributions-username": "ⵜⴰⵏⵙⴰ ⵏ IP ⵏⵖ ⵉⵙⵎ ⵓⵎⵔⵉⵙ:",
        "whatlinkshere": "ⵎⴰ ⴰⵢⴷ ⵉⵇⵇⵏⵏ ⵙ ⴷⴰ",
        "whatlinkshere-title": "ⵜⴰⵙⵏⵉⵡⵉⵏ ⵉⵣⴷⵉⵏ ⵖⵔ $1",
        "whatlinkshere-page": "ⵜⴰⵙⵏⴰ:",
-       "linkshere-2": "ⵜⴰⵙⵏⵉⵡⵉⵏ ⴰⴷ ⵣⴷⵉⵏ ⵖⵔ <strong>$1</strong>:",
-       "nolinkshere-2": "ⵓⵔ ⵍⵍⵉⵏ ⵜⴰⵙⵏⵉⵡⵉⵏ ⵉⵣⴷⵉⵏ ⵖⵔ <strong>$1</strong>",
+       "linkshere": "ⵜⴰⵙⵏⵉⵡⵉⵏ ⴰⴷ ⵣⴷⵉⵏ ⵖⵔ <strong>$1</strong>:",
+       "nolinkshere": "ⵓⵔ ⵍⵍⵉⵏ ⵜⴰⵙⵏⵉⵡⵉⵏ ⵉⵣⴷⵉⵏ ⵖⵔ <strong>$2</strong>",
        "isredirect": "ⵙⵡⴰⵍⴰ ⵜⴰⵙⵏⴰ",
        "istemplate": "ⴰⵙⵙⵓⵎⵢ",
        "isimage": "ⴰⵙⵖⵓⵏ ⵏ ⵓⴼⴰⵢⵍⵓ",
+       "whatlinkshere-prev": "{{PLURAL:$1|ⵜⵉⵎⵣⵔⴰⵢⵉⵏ|$1 ⵜⵉⵎⵣⵔⴰⵢⵉⵏ}}",
+       "whatlinkshere-next": "{{PLURAL:$1|ⵜⵉⵏⴹⴼⵔⵜ|$1 ⵜⵉⵏⴹⴼⴰⵔⵉⵏ}}",
        "whatlinkshere-links": "← ⵉⵙⵖⵓⵏⴻⵏ",
+       "whatlinkshere-hideredirs": "$1 ⵉⵙⵡⴰⵍⴰⵜⵏ",
        "whatlinkshere-hidetrans": "$1 ⵉⵙⵙⵓⵎⵢⵏ",
        "whatlinkshere-hidelinks": "$1 ⵉⵙⵖⵓⵏⴻⵏ",
        "whatlinkshere-hideimages": "$1 ⵉⵣⴷⴰⵢⵏ ⵖⵔ ⵓⴼⵉⵍⵢⵓ",
        "whatlinkshere-filters": "ⵜⵉⵙⵜⵜⴰⵢⵉⵏ",
+       "whatlinkshere-submit": "ⴷⴷⵓ",
        "ipbreason": "ⵜⴰⵎⵏⵜⵉⵍⵜ:",
-       "ipboptions": "2 âµ\9câµ\99âµ\94â´°â´³âµ\89âµ\8f:2 âµ\9câµ\99âµ\94â´°â´³âµ\89âµ\8f,1 âµ¡â´°âµ\99âµ\99:1 âµ¡â´°âµ\99âµ\99,3 âµ¡âµ\93âµ\99âµ\99â´°âµ\8f:3 âµ¡âµ\93âµ\99âµ\99â´°âµ\8f,1 âµ\89âµ\8eâ´°âµ\8dâ´°âµ\99âµ\99:1 âµ\89âµ\8eâ´°âµ\8dâ´°âµ\99âµ\99,2 âµ\89âµ\8eâ´°âµ\8dâ´°âµ\99âµ\99âµ\8f:2 âµ\89âµ\8eâ´°âµ\8dâ´°âµ\99âµ\99âµ\8f,1 âµ¡â´°âµ¢âµ¢âµ\93âµ\94:1 âµ¡â´°âµ¢âµ¢âµ\93âµ\94,3 âµ\89ⵢⵢâµ\89âµ\94âµ\8f:3 âµ\89ⵢⵢâµ\89âµ\94âµ\8f,6 âµ\89ⵢⵢâµ\89âµ\94âµ\8f:6 âµ\89ⵢⵢâµ\89âµ\94âµ\8f,1 âµ\93âµ\99ⴳⴳⴰâµ\99:1 âµ\93âµ\99ⴳⴳⴰâµ\99,â´°âµ\94âµ\93âµ\99âµ\8eâµ\89âµ\8d:â´°âµ\94âµ\93âµ\99âµ\8eâµ\89âµ\8d",
+       "ipboptions": "2 âµ\8f âµ\9câµ\99âµ\94â´°â´³âµ\89âµ\8f:2 hours,1 âµ¡â´°âµ\99âµ\99:1 day,3 âµ\8f âµ¡âµ\93âµ\99âµ\99â´°âµ\8f:3 days,1 âµ\89âµ\8eâ´°âµ\8dâ´°âµ\99âµ\99:1 week,2 âµ\8f âµ\89âµ\8eâ´°âµ\8dâ´°âµ\99âµ\99âµ\8f:2 weeks,1 âµ¡â´°âµ¢âµ¢âµ\93âµ\94:1 month,3 âµ\8f âµ¡â´°âµ¢âµ¢âµ\93âµ\94âµ\8f:3 months,6 âµ\8f âµ¡â´°âµ¢âµ¢âµ\93âµ\94âµ\8f:6 months,1 âµ\93âµ\99ⴳⴳⵯⴰâµ\99:1 year,â´°âµ\94âµ\93âµ\8eâµ\8eâµ\89â´·:infinite",
        "blocklist-reason": "ⵜⴰⵎⵏⵜⵉⵍⵜ",
+       "infiniteblock": "ⴰⵔⵓⵎⵎⵉⴷ",
        "blocklink": "ⴳⴷⵍ",
        "contribslink": "ⵜⵓⵎⵓⵜⵉⵏ",
+       "blocklogpage": "ⵜⴰⵎⵙⵙⴽⵜⵉⵜ ⵏ ⵓⴳⴷⴷⵓⵍ",
+       "blocklogentry": "ⵉⴳⴷⵍ [[$1]] ⴰⵔ $2 $3",
+       "reblock-logentry": "ⵉⵙⵏⴼⵍ ⵜⵉⵙⵖⴰⵍ ⵏ ⵓⴳⴷⴷⵓⵍ ⵏ [[$1]] ⴷ ⵔⴰⴷ ⵉⵙⵔ ⴳ $2 $3",
+       "block-log-flags-nocreate": "ⴰⵙⵏⵓⵍⴼⵓ ⵏ ⵓⵎⵉⴹⴰⵏ ⵉⵜⵜⵡⴰⵙⴱⴷⴷ",
+       "proxyblocker": "ⴰⵎⴳⴷⴰⵍ ⵏ ⵓⴱⵔⵓⴽⵙⵉ",
+       "movelogpage": "ⵜⴰⵎⵙⵙⴽⵜⵉⵜ ⵏ ⵓⵙⵎⵓⵜⵜⵢ",
        "movereason": "ⵜⴰⵎⵏⵜⵉⵍⵜ:",
        "delete_and_move_confirm": "ⵢⴰⵀ, ⴽⴽⵙ ⵜⴰⵙⵏⴰ",
        "export": "ⵙⵙⵓⴼⵖ ⵜⴰⵙⵏⵉⵡⵉⵏ",
        "allmessagesname": "ⵉⵙⵎ",
+       "allmessages-filter-all": "ⵎⴰⵕⵕⴰ",
        "allmessages-language": "ⵜⵓⵜⵍⴰⵢⵜ:",
        "allmessages-filter-translate": "ⵙⵙⵓⵖⵍ",
        "thumbnail-more": "ⵙⵙⵉⵎⵖⵓⵔ",
+       "importlogpage": "ⵜⴰⵎⵙⵙⴽⵜⵉⵜ ⵏ ⵉⵙⴽⵛⵓⵎⵏ",
        "tooltip-pt-userpage": "ⵜⴰⵙⵏⴰ ⵏ ⵓⵙⵎⵔⴰⵙ {{GENDER:|ⵏⵏⴽ|ⵏⵏⵎ}}",
        "tooltip-pt-mytalk": "ⵜⴰⵙⵏⴰ {{GENDER:|ⵏⵏⴽ|ⵏⵏⵎ}} ⵏ ⵓⵎⵙⴰⵡⴰⵍ",
        "tooltip-pt-preferences": "ⵉⵙⵎⵏⵢⵉⴼⵏ {{GENDER:|ⵏⵏⴽ|ⵏⵏⵎ}}",
        "tooltip-n-currentevents": "ⴰⴼ ⵓⴳⴳⴰⵔ ⵏ ⵉⵏⵖⵎⵉⵙⵏ ⵖⴼ ⵜⵉⵎⵙⴰⵔⵉⵏ ⵜⵉⵎⵉⵔⴰⵏⵉⵏ",
        "tooltip-n-recentchanges": "ⵢⴰⵜ ⵜⵍⴳⴰⵎⵜ ⵏ ⵉⵙⵏⴼⵍⵏ ⵉⵎⴳⴳⵓⵔⴰ ⴳ ⵡⵉⴽⵉ",
        "tooltip-n-randompage": "ⵣⴷⵎ ⵜⴰⵙⵏⴰ ⵜⴰⴷⵀⵎⴰⵙⵜ",
-       "tooltip-n-help": "The place to find out",
+       "tooltip-n-help": "ⴰⴷⵖⴰⵔ ⴳ ⵜⴻⵜⵜⴰⴼⴰⴷ",
        "tooltip-t-whatlinkshere": "ⵓⵎⵓⵖ ⵏ ⵎⴰⵕⵕ ⵜⴰⵙⵏⵉⵡⵉⵏ ⵏ ⵡⵉⴽⵉ ⵉⵣⴷⵉⵏ ⵉ ⴷⴰ",
        "tooltip-t-recentchangeslinked": "ⵉⵙⵏⴼⵍⵏ ⵉⵏⴳⴳⵓⵔⴰ ⴳ ⵜⴰⵙⵏⵉⵡⵉⵏ ⵉⵣⴷⵉⵏ ⵖⵔ ⵜⴰⵙⵏⴰ ⴰ",
        "tooltip-feed-atom": "ⴰⵏⴳⵉ ⵏ ⴰⵜⵓⵎ ⵏ ⵜⴰⵙⵏⴰ ⴰⴷ",
        "tooltip-compareselectedversions": "ⵥⵔ ⴰⵎⵣⴰⵔⴰⵢ ⴳⵔ ⵙⵉⵏ ⵉⵣⵣⵔⴰⵢⵏ ⵉⵜⵜⵓⵙⵜⴰⵢⵏ ⵏ ⵜⴰⵙⵏⴰ ⴰⴷ",
        "tooltip-watch": "ⵔⵏⵓ ⵜⴰⵙⵏⴰ ⴰ ⵉ ⵜⵍⴳⴰⵎⵜ ⵏ ⵓⴹⴼⴼⵓⵔ {{GENDER:|ⵏⵏⴽ|ⵏⵏⵎ}}",
        "tooltip-rollback": "\"ⵔⴰⵔ\" ⵙⵙⵔ ⴰⵙⵏⴼⵍ ⵏⵖ ⵉⵙⵏⴼⴰⵍⵏ ⵏ ⵓⵎⴰⴷⵔⴰⵡ ⴰⵎⴳⴳⴰⵔⵓ ⴳ ⵜⴰⵙⵏⴰ ⴷ ⵙ ⵢⴰⵏ ⵓⴽⵍⵉⴽ",
+       "tooltip-undo": "\"ⵙⵔ\" ⴰⴷ ⵜⵔⴰⵔⴷ ⴰⵙⵏⴼⵍ ⴰ ⵜⵏⵏⵓⵔⵥⵎⴷ ⵜⴰⵍⵖⴰ ⵏ ⵓⵙⵏⴼⵍ ⴳ ⵜⵎⵓⵖⵍⵉ ⵜⴰⵣⵔⴰⵙⴽⴰⵏⵜ. ⵢⴰⵍⵍⴼⵓⵙ ⴰⴷ ⵜⵔⵏⵓⴷ ⴽⵔⴰ ⵏ ⵓⵙⵔⴰⴳ ⴳ ⵓⵙⴳⵣⵍ.",
        "tooltip-summary": "ⴰⵔⴰ ⴽⵔⴰ ⵏ ⵓⵙⴳⵣⵍ ⵎⵥⵥⵉⵢⵏ",
        "simpleantispam-label": "ⵜⵉⵎⵏⵥⵉⵜ ⵎⴳⵍ-ⴳⴰⵔⴰⵙⵎⵔⴰⵔⴰ.\nⴰⴷ <strong>ⵓⵔ</strong> ⵜⵣⵎⵎⴻⵎⴷ ⴰⵎⵢⴰ ⴳ ⵖⵉ!",
        "pageinfo-title": "ⵉⵏⵖⵎⵉⵙⵏ ⵖⴼ $1",
        "pageinfo-header-basic": "ⵉⵏⵖⵎⵉⵙⵏ ⵏ ⵜⵙⵉⵍⴰ",
        "pageinfo-header-edits": "ⵙⵏⴼⵍ ⴰⵎⵣⵔⵓⵢ",
        "pageinfo-header-restrictions": "ⴰⴼⵔⴰⴳ ⵏ ⵜⴰⵙⵏⴰ",
+       "pageinfo-header-properties": "ⵜⵉⵖⴰⵔⵉⵡⵉⵏ ⵏ ⵜⴰⵙⵏⴰ",
        "pageinfo-display-title": "ⵙⴽⵏ ⴰⵣⵡⵍ",
+       "pageinfo-default-sort": "ⵜⴰⵙⴰⵔⵓⵜ ⵏ ⵓⵏⵎⴰⵍⴰ ⵙ ⵓⵡⵏⵓⵍ",
+       "pageinfo-length": "ⵜⵉⴷⴷⵉ ⵏ ⵜⴰⵙⵏⴰ (ⵙ ⵓⴱⴰⵢⵜ)",
        "pageinfo-article-id": "ID ⵏ ⵜⴰⵙⵏⴰ",
        "pageinfo-language": "ⵜⵓⵜⵍⴰⵢⵜ ⵏ ⵜⵙⵏⴰ",
+       "pageinfo-content-model": "ⴰⵎⵓⴷⵎ ⵏ ⵜⵓⵎⴰⵢⵜ ⵏ ⵜⴰⵙⵏⴰ",
+       "pageinfo-robot-policy": "ⴰⵙⴳⴱⵔ ⵙ ⵉⵔⵓⴱⵓⵜⵏ",
        "pageinfo-robot-index": "ⵉⵜⵜⵓⴼⵔⴰⴳ",
        "pageinfo-robot-noindex": "ⵓⵔ ⵉⵜⵜⵓⴼⵔⴰⴳ",
        "pageinfo-watchers": "ⵓⵟⵟⵓⵏ ⵏ ⵉⵎⵥⵕⴰⵢⵏ ⵏ ⵜⴰⵙⵏⴰ",
        "pageinfo-few-watchers": "ⴷⵔⵓⵙ ⵅⴼ $1 {{PLURAL:$1|ⴰⵎⴰⵏⵏⴰⵢ|ⵉⵎⴰⵏⵏⴰⵢⵏ}}",
        "pageinfo-redirects-name": "ⵓⵟⵟⵓⵏ ⵏ ⵉⵙⵡⴰⵍⴰⵜⵏ ⵖⵔ ⵜⴰⵙⵏⴰ ⴰⴷ",
        "pageinfo-subpages-name": "ⵓⵟⵟⵓⵏ ⵏ ⵜⴷⵓⵙⵏⵉⵡⵉⵏ ⵏ ⵜⴰⵙⵏⴰ ⴰⴷ",
+       "pageinfo-subpages-value": "$1 ($2 {{PLURAL:$2|ⴰⵙⵡⴰⵍⴰ|ⵉⵙⵡⴰⵍⴰⵜⵏ}}; $3 {{PLURAL:$3|ⴰⵔⵙⵡⴰⵍⴰ|ⵉⵔⵙⵡⴰⵍⴰⵜⵏ}})",
        "pageinfo-firstuser": "ⴰⵎⵙⵏⵓⵍⴼⵓ ⵏ ⵜⴰⵙⵏⴰ",
        "pageinfo-firsttime": "ⴰⵙⴰⴽⵓⴷ ⵏ ⵓⵙⵏⴼⵍⵓⵍ ⵏ ⵜⴰⵙⵏⴰ",
        "pageinfo-lastuser": "ⴰⵎⵙⵏⴼⵍ ⴰⵎⴳⴳⴰⵔⵓ",
        "pageinfo-lasttime": "ⴰⵙⴰⴽⵓⴷ ⵏ ⵓⵙⵏⴼⵍ ⴰⵎⴳⴳⴰⵔⵓ",
        "pageinfo-edits": "ⵎⴰⵕⵕⴰ ⵓⵟⵟⵓⵏ ⵏ ⵉⵙⵏⴼⴰⵍⵏ",
        "pageinfo-authors": "ⵓⵟⵟⵓⵏ ⴰⵎⵖⵔⵓⴷ ⵏ ⵉⵎⴰⵔⴰⵜⵏ ⵉⵎⵢⴰⵍⵍⴰⵏ",
+       "pageinfo-recent-edits": "ⵓⵟⵟⵓⵏ ⵏ ⵉⵙⵏⴼⵍⵏ ⵉⵏⴳⴳⵓⵔⴰ (ⴳ $1 ⴳⴳⵔⴰⵏⵉⵏ)",
+       "pageinfo-recent-authors": "ⵓⵟⵟⵓⵏ ⵏ ⵉⵎⴰⵔⴰⵜⵏ ⵉⵎⴳⴳⵓⵔⴰ ⵉⵎⵢⴰⵍⵍⴰⵏ",
        "pageinfo-magic-words": "ⵉⵎⴽⵓⵔⴰⵔⵏ {{PLURAL:$1|ⵜⴰⴳⵓⵔⵉ|ⵜⵉⴳⵓⵔⵉⵡⵉⵏ}} ($1)",
        "pageinfo-hidden-categories": "ⵏⵜⵍ {{PLURAL:$1|ⴰⵙⵎⵉⵍ|ⵉⵙⵎⵉⵍⵏ}}($1)",
+       "pageinfo-templates": "{{PLURAL:$1|ⵡⴰⵍⴱⵓⴹ ⵢⴰⵎⵓⵏ|ⵏ ⵡⴰⵍⴱⵓⴹⵏ ⵢⴰⵎⵓⵏ}} ($1)",
        "pageinfo-toolboxlink": "ⴰⵏⵖⵎⵉⵙ ⵖⴼ ⵜⴰⵙⵏⴰ",
        "pageinfo-contentpage": "ⵉⵜⵜⵓⵙⵉⴹⵏ ⴰⵎ ⵜⴰⵙⵏⴰ ⵏ ⵜⵓⵎⴰⵢⵜ",
        "pageinfo-contentpage-yes": "ⵢⴰⵀ",
        "pageinfo-protect-cascading-yes": "ⵢⴰⵀ",
+       "patrol-log-page": "ⵜⴰⵎⵙⵙⴽⵜⵉⵜ ⵏ ⵓⵣⵣⵔⴰⵢ",
        "previousdiff": "ⴰⵙⵏⴼⵍ ⴰⵎⴳⴳⴰⵔⵓ",
        "nextdiff": "ⴰⵙⵏⴼⵍ ⴰⵎⴰⵢⵏⵓ",
+       "widthheightpage": "$1 × $2, $3 {{PLURAL:$3|ⵜⴰⵙⵏⴰ|ⵜⴰⵙⵏⵉⵡⵉⵏ}}",
        "file-info-size": "$1 × $2 ⵉⴷ ⴱⵉⴽⵙⵍ, ⵜⵉⴷⴷⵉ ⵏ ⵓⴼⴰⵢⵍⵓ: $3, ⴰⵏⴰⵡ MIME: $4",
+       "file-info-size-pages": "$1 × $2 ⴱⵉⴽⵙⵉⵍ, ⵜⵉⴷⴷⵉ ⵏ ⵓⴼⴰⵢⵍⵓ: $3, ⴰⵏⴰⵡ ⵏ MIME: $4, $5 {{PLURAL:$5|ⵜⴰⵙⵏⴰ|ⵜⴰⵙⵏⵉⵡⵉⵏ}}",
+       "file-nohires": "ⵓⵔ ⵜⵍⵍⵉ ⵜⵙⴷⴷⵉ ⵉⵎⵇⵇⵓⵔⵏ ⵓⴳⴳⴰⵔ",
        "svg-long-desc": "ⴰⴼⴰⵢⵍⵓ SVG, ⵙ $1 × $2 ⵉⴷ ⴱⵉⴽⵙⵍ, ⵜⵉⴷⴷⵉ ⵏ ⵓⴼⴰⵢⵍⵓ: $3",
        "show-big-image": "ⴰⴼⴰⵢⵍⵓ ⴰⵙⴰⵍⴰⵏ",
        "show-big-image-preview": "ⵜⴰⵙⵎⴽⵜⴰ ⵏ ⵓⵣⵔⵉⵣⵡⴰⵔ ⴰⴷ: $1.",
        "exif-xresolution": "ⵜⵉⵙⴷⴷⵉ ⵜⴰⵛⴰⵛⴼⴰⵍⵜ",
        "exif-yresolution": "ⵜⵉⵙⴷⴷⵉ ⵜⴰⴱⴷⴷⴰⵢⵜ",
        "exif-datetime": "ⴰⵙⴰⴽⵓⴷ ⴷ ⵡⴰⴽⵓⴷ ⵏ ⵓⵙⵏⴼⵍ ⵏ ⵓⴼⴰⵢⵍⵓ",
+       "exif-make": "ⴰⵎⴽⵓⵏ ⵏ ⵜⵎⵙⵙⵓⵍⴰⴼⵜ",
        "exif-model": "ⴰⵏⴰⵡ ⵏ ⵜⵙⵡⵍⴰⴼⵜ",
        "exif-software": "ⴰⵙⵖⵥⴰⵏ ⵉⵜⵜⵓⵙⵎⵔⵙⵏ",
+       "exif-exifversion": "ⵜⴰⵎⵓⵖⵍⵉ Exif",
        "exif-colorspace": "ⵜⵉⵔⵉⵡⵜ ⵏ ⵓⴽⵍⵓ",
        "exif-datetimeoriginal": "ⴰⵙⴰⴽⵓⴷ ⴷ ⵜⵉⵣⵉ ⵏ ⵓⵙⴽⴽⵉⵔ ⵏ ⵉⵙⴼⴽⴰ",
        "exif-datetimedigitized": "ⴰⵙⴰⴽⵓⴷ ⴷ ⵜⵉⵣⵉ ⵏ ⵓⵙⵓⵟⵟⵏ",
        "exif-dc-contributor": "ⵉⵏⴰⵎⵓⵜⵏ",
        "exif-iimcategory-edu": "ⴰⵙⴳⵎⵉ",
        "exif-iimcategory-hth": "ⵜⴰⴷⵓⵙⵉ",
-       "namespacesall": "ⴰⴽⴽⵯ",
+       "namespacesall": "âµ\8eâ´°âµ\95âµ\95â´°",
        "monthsall": "ⵎⴰⵕⵕⴰ",
        "confirm_purge_button": "ⵡⴰⵅⵅⴰ",
        "confirm-watch-button": "ⵡⴰⵅⵅⴰ",
        "imgmultigo": "ⴷⴷⵓ!",
        "imgmultigoto": "ⴷⴷⵓ ⵖⵔ ⵜⴰⵙⵏⴰ ⴰⴷ $1",
        "img-lang-default": "(ⵜⵓⵜⵍⴰⵢⵜ ⵙ ⵓⵡⵏⵓⵍ)",
+       "img-lang-go": "ⴷⴷⵓ",
+       "table_pager_limit_submit": "ⴷⴷⵓ",
+       "watchlistedit-clear-explain": "ⵎⴰⵕⵕⴰ",
        "watchlisttools-clear": "ⵙⴼⴹ ⵜⴰⵍⴳⴰⵎⵜ ⵏ ⵓⴹⴼⴼⵓⵔ",
        "watchlisttools-view": "ⵙⴽⵏ ⵉⵙⵏⵉⴼⵉⵍⵏ ⴷ ⵢⵓⵙⴰⵏ",
        "watchlisttools-edit": "ⵥⵕ ⴷ ⵜⵙⵏⴼⵍⴷ ⵜⴰⵍⴳⴰⵎⵜ ⵏ ⵓⴹⴼⴼⵓⵔ",
+       "watchlisttools-raw": "ⵙⵏⴼⵍ ⵜⴰⵍⴳⴰⵎⵜ ⵏ ⵓⵙⵎⵉⵜⵔ ⴰⵎⵙⴰⵔⵉ",
+       "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|ⴰⵎⵙⴰⵡⴰⵍ]])",
+       "version-poweredby-translators": "ⵉⵎⵙⵖⵓⵍⵏ ⵏ translatewiki.net",
+       "redirect": "ⵙⵡⴰⵍⴰ ⵙ ID ⵏ ⵓⴼⴰⵢⵍⵓ, ⴰⵏⵙⵙⵎⵔⵙ, ⵜⴰⵙⵏⴰ, ⴰⵣⵣⵔⴰⵢ ⵏⵖ ⵜⴰⵎⵙⵙⴽⵜⵉⵜ",
+       "redirect-summary": "ⵜⴰⵙⵏⴰ ⴰⴷ ⵉⵥⵍⵉⵏ ⵜⵙⵡⴰⵍⴰ ⵖⵔ  ⵢⴰⵏ ⵓⴼⴰⵢⵍⵓ (ⵉⵜⵜⵓⴼⴽⴰ ⵢⵉⵙⵎ ⵏ ⴼⴰⵢⵍⵓ), ⵢⴰⵜ ⵜⴰⵙⵏⴰ (ID ⵏ ⵓⵣⵣⵔⴰⵢ ⵏⵖ ⵏ ⵜⴰⵙⵏⴰ ⵉⵜⵜⵓⴼⴽⴰⵏ), ⵢⴰⵜ ⵜⴰⵙⵏⴰ ⵏ ⵓⵏⵙⵙⵎⵔⵙ (ⴰⵎⵙⵎⴰⴳⵉ ⵓⵎⴹⵉⵏ ⵏ ⵓⵏⵙⵙⵎⵔⵙ ⵉⵜⵜⵓⴼⴽⴰ), ⵏⵖ ⵢⴰⵜ ⵜⵓⴷⵉⴼⵜ ⵏ ⵜⵎⵙⵙⴽⵜⵉⵜ  (ID ⵏ ⵜⵎⵙⵙⴽⵜⵉⵜ ⵉⵜⵜⵓⴼⴽⴰ). ⴰⵙⵙⵎⵔⵙ : [[{{#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": "ⴰⵣⴰⵍ",
        "redirect-user": "ID ⵏ ⵓⵎⵙⵙⵎⵔⵙ",
        "redirect-page": "ID ⵏ ⵜⴰⵙⵏⴰ",
        "tags-active-no": "ⵓⵀⵓ",
        "tags-edit": "ⵙⵏⴼⵍ",
        "tags-delete": "ⴽⴽⵙ",
+       "tags-hitcount": "$1 {{PLURAL:$1|ⵓⵙⵏⴼⵍ|ⵉⵙⵏⴼⵉⵍⵏ}}",
        "tags-create-reason": "ⵜⴰⵎⵏⵜⵉⵍⵜ:",
        "tags-delete-reason": "ⵜⴰⵎⵏⵜⵉⵍⵜ:",
        "tags-activate-reason": "ⵜⴰⵎⵏⵜⵉⵍⵜ:",
        "htmlform-no": "ⵓⵀⵓ",
        "htmlform-yes": "ⵢⴰⵀ",
        "logentry-delete-delete": "$1 {{GENDER:$2|ⵉⴽⴽⵙ|ⵜⴽⴽⵙ}} ⵜⴰⵙⵏⴰ $3",
+       "logentry-delete-restore": "$1 {{GENDER:$2|ⵉⵔⵓⵔ ⴷ|ⵜⵔⵓⵔ ⴷ}} ⵜⴰⵙⵏⴰ $3 ($4)",
+       "logentry-delete-revision": "$1 {{GENDER:$2|ⵉⵙⵏⴼⵍ}} ⴰⵍⵍⴼⵓⵙ ⵏ ⵡⵓⵎⴰⵏ {{PLURAL:$5|ⵏ ⵢⴰⵏ ⵓⵣⵣⵔⴰⵢ|ⵏ $5 ⵏ ⵉⵣⵣⵔⴰⵢⵏ}} ⴳ ⵜⴰⵙⵏⴰ $3 : $4",
        "revdelete-content-hid": "ⵜⴻⵜⵜⵓⵏⵜⴰⵍ ⵜⵓⵎⴰⵢⵜ",
        "logentry-move-move": "$1 {{GENDER:$2|ⵉⵙⵎⵓⵜⵜⵉ|ⵜⵙⵎⵓⵜⵜⵉ}} ⵜⴰⵙⵏⴰ ⵙⴳ $3 ⵖⵔ $4",
        "logentry-move-move-noredirect": "{{GENDER:$2|ⵉⵙⵎⵓⵜⵜⵉ}} $1 ⵜⴰⵙⵏⴰ $3 ⵖⵔ $4 ⵎⵉⵏ ⴰⴷ ⵉⴼⵍ redirect",
+       "logentry-move-move_redir": "{{GENDER:$2|ⵉⵙⵎⵓⵜⵜⵉ|ⵜⵙⵎⵓⵜⵜⵉ}} $1 ⵜⴰⵙⵏⴰ $3 ⵖⵔ $4 ⵏⵏⵉⴳ ⵏ ⵓⵙⵡⴰⵍⴰ",
+       "logentry-patrol-patrol-auto": "$1 {{GENDER:$2 ⵉⵔⵛⵎ ⵜⵜ ⵙ ⵜⵡⵓⵔⵎⴰⵏⵜ}} ⴰⵣⵣⵔⴰⵢ $4 ⵏ ⵜⴰⵙⵏⴰ $3 ⵎⴰⵙ ⵜⴻⵜⵜⵓⵖⵔⴰ ⵉ ⵜⵉⴽⴽⵍⵜ ⵢⴰⴹⵏ",
        "logentry-newusers-create": "{{GENDER:$2|ⵉⵙⵏⴼⵍ ⵓⵏⵙⵙⵎⵔⵙ|ⵜⵙⵏⴼⵍ ⵜⵏⵙⵙⵎⵔⵙⵜ}} $1 ⴰⵎⵉⴹⴰⵏ ⵏⵙ",
+       "logentry-newusers-autocreate": "ⵉⵜⵜⵡⴰⵙⵏⵓⵍⴼⴰ ⵓⵎⵉⴹⴰⵏ ⵏ {{GENDER:$2|ⵓⵎⵙⵙⵎⵔⵙ|ⵜⵎⵙⵙⵎⵔⵙⵜ}} $1 ⵙ ⵓⵡⵔⵎⴰⵏ",
        "logentry-upload-upload": "{{GENDER:$2|ⵉⵙⴽⵜⵔ|ⵜⵙⴽⵜⵔ}} $1 $3",
+       "logentry-upload-overwrite": "{{GENDER:$2|ⵉⵙⴽⵜⵔ|ⵜⵙⴽⵜⵔ}} $1 ⵢⴰⵜ ⵜⵎⵓⵖⵍⵉ ⵜⴰⵎⴰⵢⵏⵓⵜ ⵏ $3",
        "rightsnone": "(ⵓⵍⴰ ⵢⴰⵏ)",
+       "feedback-message": "ⵜⵓⵣⵉⵏⵜ:",
        "feedback-thanks-title": "ⵜⴰⵏⵎⵎⵉⵔⵜ!",
        "searchsuggest-search": "ⵔⵣⵓ ⴳ {{SITENAME}}",
        "duration-days": "$1 ⵏ {{PLURAL:$1|ⵡⴰⵙⵙ|ⵡⵓⵙⵙⴰⵏ}}",
        "pagelang-name": "ⵜⴰⵙⵏⴰ",
        "pagelang-language": "ⵜⵓⵜⵍⴰⵢⵜ",
        "right-pagelang": "ⵙⵏⴼⵍ ⵜⵓⵜⵍⴰⵢⵜ ⵏ ⵜⴰⵙⵏⴰ",
+       "mediastatistics-header-total": "ⵎⴰⵕⵕⴰ ⵉⴼⵓⵍⵢⴰ",
+       "randomrootpage": "ⵜⴰⵙⵏⴰ ⴰⵥⵓⵔ ⵜⴰⵡⴳⴰⵛⵓⵔⵜ",
+       "log-action-filter-all": "ⵎⴰⵕⵕⴰ",
+       "authmanager-authplugin-setpass-denied": "ⵎⴰⵕⵕⴰ",
        "authmanager-email-label": "ⵉⵎⴰⵢⵍ",
        "authmanager-realname-label": "ⵉⵙⵎ ⴰⵎⴷⴷⴰⵜ",
        "authmanager-realname-help": "ⵉⵙⵎ ⴰⵎⴷⴷⴰⵜ ⵏ ⵓⵏⵙⵙⵔⵎⵙ",
index f81d57a..3f2dbc6 100644 (file)
                        "逆襲的天邪鬼",
                        "WhitePhosphorus",
                        "A2093064",
-                       "EagerLin"
+                       "EagerLin",
+                       "Deathkon",
+                       "RyRubyy",
+                       "Wxyveronica",
+                       "夢蝶葬花"
                ]
        },
        "tog-underline": "链接下划线:",
        "nonwrite-api-promise-error": "“Promise-Non-Write-API-Action”HTTP报头已发送,但请求是一个API编写模块。",
        "internalerror": "内部错误",
        "internalerror_info": "内部错误:$1",
-       "internalerror-fatal-exception": "类型“$1”的致命错误",
+       "internalerror-fatal-exception": "类型“$1”的致命例外",
        "filecopyerror": "无法将文件“$1”复制到“$2”。",
        "filerenameerror": "无法将文件“$1”重命名为“$2”。",
        "filedeleteerror": "无法删除文件“$1”。",
        "customcssprotected": "您没有权限编辑此CSS页面,因为它包含另一位用户的个人设置。",
        "customjsonprotected": "您没有权限编辑此JSON页面,因为它包含另一位用户的个人设置。",
        "customjsprotected": "您没有权限编辑此JavaScript页面,因为它包含另一位用户的个人设置。",
+       "sitecssprotected": "您无权编辑此CSS页面,因为它可能会影响所有访问者",
+       "sitejsonprotected": "您无权编辑此JSON页面,因为它可能会影响所有访问者",
+       "sitejsprotected": "您无权编辑此JavaScript页面,因为它可能会影响所有访问者",
        "mycustomcssprotected": "您没有权限编辑这个 CSS 页面。",
        "mycustomjsonprotected": "您没有权限编辑这个JSON页面。",
        "mycustomjsprotected": "您没有权限编辑这个 JavaScript 页面。",
        "noemailcreate": "您需要提供一个有效的电子邮件地址",
        "passwordsent": "用户\"$1\"的新密码已经寄往所登记的电子邮件地址。\n请在收到后再登录。",
        "blocked-mailpassword": "您的IP地址被禁止编辑,为预防滥用,也不允许从该IP地址使用密码恢复功能。",
-       "eauthentsent": "一封确认信已经发送至您设定的邮件地址。\n在任何其他邮件发送至您的账户前,您将不得不根据邮件中的指示,确认那个账户确实是您的。",
+       "eauthentsent": "一封确认信已经发送至您设定的邮件地址。\n在任何其他邮件发送至您的账户前,您将需要根据邮件中的指示,确认那个账户确实是您的。",
        "throttled-mailpassword": "密码提醒已在最近$1小时内发送。为了安全起见,在每$1小时内只能发送一个密码提醒。",
        "mailerror": "发送邮件错误:$1",
        "acct_creation_throttle_hit": "使用您的IP地址访问本wiki的访客在过去$2中创建了{{PLURAL:$1|$1个账户}},达到了这段时间所允许的最大值。因此,使用该IP地址的访客现在不能再创建账户。",
        "resetpass-submit-loggedin": "更改密码",
        "resetpass-submit-cancel": "取消",
        "resetpass-wrong-oldpass": "临时密码或当前密码无效。您可能已经更改了您的密码,或者请求了新的临时密码。",
-       "resetpass-recycled": "请重置您的密码为与当前密码不同的密码。",
+       "resetpass-recycled": "请将您的密码更改成与当前密码不同的密码。",
        "resetpass-temp-emailed": "您使用了通过电子邮件发送的临时密码登录。要完成登录,您必须在此设置一个新密码:",
        "resetpass-temp-password": "临时密码:",
        "resetpass-abort-generic": "密码更改已经被扩展程序中止。",
        "resetpass-expired": "您的密码已经到期。请设置新登录密码。",
-       "resetpass-expired-soft": "您的密码已经到期,需要重置。请现在更换新密码,或单击“{{int:authprovider-resetpass-skip-label}}”以稍后重置。",
-       "resetpass-validity-soft": "您的密码无效:$1\n\n请选择一个新密码,或单击“{{int:authprovider-resetpass-skip-label}}”以稍后重置。",
+       "resetpass-expired-soft": "您的密码已经到期,需要更改。请现在更换新密码,或单击“{{int:authprovider-resetpass-skip-label}}”以稍后更改。",
+       "resetpass-validity-soft": "您的密码无效:$1\n\n请选择一个新密码,或单击“{{int:authprovider-resetpass-skip-label}}”以稍后更改。",
        "passwordreset": "重置密码",
        "passwordreset-text-one": "请完成此表单来通过电子邮件接收临时密码。",
        "passwordreset-text-many": "{{PLURAL:$1|填写其中一个字段以通过电子邮件接收临时密码。}}",
        "converter-manual-rule-error": "在手动语言转换规则中检测到错误",
        "undo-success": "该编辑可以被撤销。请检查下面的对比以核实您想要撤销的内容,然后保存下面的更改以完成撤销。",
        "undo-failure": "因存在冲突的中间编辑,本编辑不能撤销。",
+       "undo-main-slot-only": "编辑无法撤销,因为其涉及主位置以外的内容。",
        "undo-norev": "该编辑无法撤消,因为它不存在或已被删除。",
        "undo-nochange": "这次编辑似乎已被撤销。",
        "undo-summary": "撤销[[Special:Contributions/$2|$2]]([[User talk:$2|讨论]])的版本$1",
        "diff-paragraph-moved-toold": "段落已移动。点击跳到旧位置。",
        "difference-missing-revision": "此差异对比的{{PLURAL:$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": "页面内容匹配",
        "group-autoconfirmed": "自动确认用户",
        "group-bot": "机器人",
        "group-sysop": "管理员",
+       "group-interface-admin": "界面管理员",
        "group-bureaucrat": "行政员",
        "group-suppress": "Flow监督员",
        "group-all": "(所有)",
        "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|Flow监督员}}",
        "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-editusercss": "编辑其他用户的CSS文件",
        "right-edituserjson": "编辑其他用户的JSON文件",
        "right-edituserjs": "编辑其他用户的JavaScript文件",
+       "right-editsitecss": "编辑全站CSS",
+       "right-editsitejson": "编辑全站JSON",
+       "right-editsitejs": "编辑全站JavaScript",
        "right-editmyusercss": "编辑您的用户CSS文件",
        "right-editmyuserjson": "编辑您的用户JSON文件",
        "right-editmyuserjs": "编辑您的用户JavaScript文件",
        "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-savedqueries-rename": "重命名",
        "rcfilters-savedqueries-setdefault": "设置为默认",
        "rcfilters-savedqueries-unsetdefault": "移除为默认",
-       "rcfilters-savedqueries-remove": "除",
+       "rcfilters-savedqueries-remove": "除",
        "rcfilters-savedqueries-new-name-label": "名称",
        "rcfilters-savedqueries-new-name-placeholder": "描述过滤器目的",
        "rcfilters-savedqueries-apply-label": "创建过滤器",
        "rcfilters-empty-filter": "没有应用的过滤器。所有贡献都已显示。",
        "rcfilters-filterlist-title": "过滤器",
        "rcfilters-filterlist-whatsthis": "这些是怎样工作的?",
-       "rcfilters-filterlist-feedbacklink": "告诉我们您对这些(新)过滤工具有什么想法",
+       "rcfilters-filterlist-feedbacklink": "告诉我们您对这些过滤工具有什么想法",
        "rcfilters-highlightbutton-title": "高亮结果",
        "rcfilters-highlightmenu-title": "选择颜色",
        "rcfilters-highlightmenu-help": "选择颜色来高亮该属性",
        "rcfilters-watchlist-showupdated": "自更改发生以来,对您尚未访问的页面做出的更改以<strong>粗体</strong>显示,并带有实心圆形标记。",
        "rcfilters-preference-label": "隐藏改进的最近更改版本",
        "rcfilters-preference-help": "返回到2017年界面重新设计版,并重新添加这以后新增的工具。",
+       "rcfilters-watchlist-preference-label": "隐藏改进的监视列表版本",
+       "rcfilters-watchlist-preference-help": "回退2017年界面再设计,以及所有自此开始添加的工具。",
        "rcfilters-filter-showlinkedfrom-label": "显示链接自该页面的页面上的更改",
        "rcfilters-filter-showlinkedfrom-option-label": "<strong>链接自</strong>选定页面的页面",
        "rcfilters-filter-showlinkedto-label": "显示链接到该页面的页面上的更改",
        "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": "无法访问提供的URL。请检查该URL是否正确,及其网站是否在线。",
        "upload-curl-error28": "上传超时",
        "speciallogtitlelabel": "目标(标题,或对于用户使用{{ns:user}}:用户名):",
        "log": "日志",
        "logeventslist-submit": "显示",
+       "logeventslist-more-filters": "显示更多日志:",
+       "logeventslist-patrol-log": "巡查日志",
+       "logeventslist-tag-log": "标签日志",
        "all-logs-page": "所有公开日志",
        "alllogstext": "所有{{SITENAME}}公开日志的联合展示。您可以通过选择日志类型、输入用户名(区分大小写)或相关页面(区分大小写)筛选日志条目。",
        "logempty": "在日志中不存在匹配项。",
        "dellogpage": "删除日志",
        "dellogpagetext": "下面是最近的删除的列表。",
        "deletionlog": "删除日志",
+       "log-name-create": "页面创建日志",
+       "log-description-create": "下方是最近的页面创建列表。",
+       "logentry-create-create": "$1{{GENDER:$2|创建了}}页面$3",
        "reverted": "恢复到较早的版本",
        "deletecomment": "原因:",
        "deleteotherreason": "其他/附加原因:",
        "uctop": "(当前)",
        "month": "截止月份:",
        "year": "截止年份:",
+       "date": "起始日期(及更早):",
        "sp-contributions-newbies": "只显示新账户的贡献",
        "sp-contributions-newbies-sub": "新账户的贡献",
        "sp-contributions-newbies-title": "新账户的用户贡献",
        "whatlinkshere": "链入页面",
        "whatlinkshere-title": "链接至“$1”的页面",
        "whatlinkshere-page": "页面:",
-       "linkshere-2": "以下页面链接至<strong>$1</strong>:",
-       "nolinkshere-2": "没有页面链接至<strong>$1</strong>。",
-       "nolinkshere-ns-2": "在所选的名字空间内没有页面链接到<strong>$1</strong>。",
+       "linkshere": "以下页面链接至<strong>$2</strong>:",
+       "nolinkshere": "没有页面链接至<strong>$2</strong>。",
+       "nolinkshere-ns": "在所选的名字空间内没有页面链接到<strong>$2</strong>。",
        "isredirect": "重定向页面",
        "istemplate": "嵌入",
        "isimage": "文件链接",
        "markedaspatrollederrornotify": "标记为已巡查失败。",
        "patrol-log-page": "巡查日志",
        "patrol-log-header": "这是已巡查版本的日志。",
-       "log-show-hide-patrol": "$1巡查纪录",
-       "log-show-hide-tag": "$1标签日志",
        "confirm-markpatrolled-button": "确定",
        "confirm-markpatrolled-top": "将$2的修订版本$3标记为已巡查么?",
        "deletedrevision": "已删除旧版本$1",
        "exif-photometricinterpretation-1": "黑白(黑为0)",
        "exif-photometricinterpretation-4": "透明遮罩",
        "exif-photometricinterpretation-5": "分隔(可能是CMYK)",
+       "exif-photometricinterpretation-9": "CIE L*a*b*(ICC编码)",
+       "exif-photometricinterpretation-10": "CIE L*a*b*(ITU编码)",
        "exif-photometricinterpretation-32803": "色彩滤镜矩阵",
+       "exif-photometricinterpretation-34892": "线性原始",
        "exif-unknowndate": "未知日期",
        "exif-orientation-1": "标准",
        "exif-orientation-2": "水平翻转",
        "watchlistedit-clear-done": "您的监视列表已清空。",
        "watchlistedit-clear-jobqueue": "您的监视列表正在清空。这需要花一些时间!",
        "watchlistedit-clear-removed": "$1个标题已移除:",
-       "watchlistedit-too-many": "这里显示了太多页面。",
+       "watchlistedit-too-many": "页面太多,无法显示。",
        "watchlisttools-clear": "清空监视列表",
        "watchlisttools-view": "查看相关更改",
        "watchlisttools-edit": "查看并编辑监视列表",
index 0809fc0..05e95c6 100644 (file)
@@ -97,7 +97,9 @@
                        "和平至上",
                        "Sanmosa",
                        "Dongzn",
-                       "Shangkuanlc"
+                       "Shangkuanlc",
+                       "Kanashimi",
+                       "Hello903hello"
                ]
        },
        "tog-underline": "底線標示連結:",
        "tog-watchlisthidebots": "隱藏監視清單中機器人的編輯",
        "tog-watchlisthideminor": "隱藏監視清單中的次要修訂",
        "tog-watchlisthideliu": "隱藏監視清單中已登入使用者的編輯",
-       "tog-watchlistreloadautomatically": "查詢條件變更時自動重新讀取監視清單(需要使用 JavaScript)",
-       "tog-watchlistunwatchlinks": "為帶有變更的監試頁面添加直接(取消)監視標記({{int:Watchlist-unwatch}}/{{int:Watchlist-unwatch-undo}}),需要 JavaScript 來打開功能",
+       "tog-watchlistreloadautomatically": "篩選條件變更時自動重新讀取監視清單(需要使用 JavaScript)",
+       "tog-watchlistunwatchlinks": "為有更改的監視頁面添加直接(取消)監視標記({{int:Watchlist-unwatch}}/{{int:Watchlist-unwatch-undo}},需要JavaScript才能開啟功能)",
        "tog-watchlisthideanons": "隱藏監視清單中匿名使用者的編輯",
        "tog-watchlisthidepatrolled": "隱藏監視清單中已巡查的編輯",
        "tog-watchlisthidecategorization": "隱藏頁面分類",
        "fri": "五",
        "sat": "六",
        "january": "1月",
-       "february": "月",
-       "march": "月",
-       "april": "月",
-       "may_long": "月",
-       "june": "月",
-       "july": "月",
-       "august": "月",
-       "september": "月",
-       "october": "月",
-       "november": "十一月",
+       "february": "2月",
+       "march": "3月",
+       "april": "4月",
+       "may_long": "5月",
+       "june": "6月",
+       "july": "7月",
+       "august": "8月",
+       "september": "9月",
+       "october": "10月",
+       "november": "11月",
        "december": "12月",
        "january-gen": "一月",
        "february-gen": "二月",
        "helppage-top-gethelp": "說明",
        "mainpage": "首頁",
        "mainpage-description": "首頁",
-       "policy-url": "Project:Policy",
+       "policy-url": "Project:方針",
        "portal": "社群入口",
        "portal-url": "Project:社群入口",
        "privacy": "隱私政策",
        "customcssprotected": "您並沒有權限編輯此 CSS 頁面,因為此頁面包含了其他使用者的個人設定。",
        "customjsonprotected": "您沒有權限編輯此JSON頁面,因為此頁面包含了其他使用者的個人設定。",
        "customjsprotected": "您並沒有權限編輯此 JavaScript 頁面,因為此頁面包含了其他使用者的個人設定。",
+       "sitecssprotected": "您沒有權限來編輯此 CSS 頁面,因為這會影響到所有的網站訪客",
+       "sitejsonprotected": "您沒有權限來編輯此 JSON 頁面,因為這會影響到所有的網站訪客",
+       "sitejsprotected": "您沒有權限來編輯此 JavaScript 頁面,因為這會影響到所有的網站訪客",
        "mycustomcssprotected": "您沒有權限編輯此 CSS 頁面。",
        "mycustomjsonprotected": "您沒有權限編輯此 JSON 頁面。",
        "mycustomjsprotected": "您沒有權限編輯此 JavaScript 頁面。",
        "resetpass-submit-loggedin": "變更密碼",
        "resetpass-submit-cancel": "取消",
        "resetpass-wrong-oldpass": "無效的臨時或現有密碼。\n您可能已經變更了密碼,或者已經請求一個新的臨時密碼。",
-       "resetpass-recycled": "請重設您的密碼為一個與目前不同的密碼。",
+       "resetpass-recycled": "請將您的密碼更改成與目前內容不同的密碼。",
        "resetpass-temp-emailed": "您使用臨時電子郵件傳送的密碼登入。\n要完成登入,您必須在這裡設定一個新密碼:",
        "resetpass-temp-password": "臨時密碼:",
        "resetpass-abort-generic": "擴充套件已中止了變更密碼的操作。",
        "resetpass-expired": "您的密碼已過期。請設定一個新的密碼以登入。",
-       "resetpass-expired-soft": "您的密碼已過期,需要重新設定。請現在設定您的新密碼,或點選 \"{{int:authprovider-resetpass-skip-label}}\" 稍後再重設。",
-       "resetpass-validity-soft": "您的密碼無效:$1 \n\n請現在設定您的新密碼,或點選 \"{{int:authprovider-resetpass-skip-label}}\" 稍後再重設。",
+       "resetpass-expired-soft": "您的密碼已過期,需要作出更改。請現在設定您的新密碼,或點選 \"{{int:authprovider-resetpass-skip-label}}\" 來事後更改。",
+       "resetpass-validity-soft": "您的密碼無效:$1 \n\n請現在設定您的新密碼,或點選 \"{{int:authprovider-resetpass-skip-label}}\" 來事後更改。",
        "passwordreset": "重新設定密碼",
        "passwordreset-text-one": "完成此表單,透過電子郵件傳送臨時密碼以重新設定您的密碼。",
        "passwordreset-text-many": "{{PLURAL:$1|填寫其中一個欄位以透過電子郵件接收臨時密碼。}}",
        "converter-manual-rule-error": "手動語言轉換規則時偵測到錯誤",
        "undo-success": "此編輯可以被還原。\n請檢查以下比較表,確認您是否要還原,然後儲存以下變更以完成編輯還原。",
        "undo-failure": "由於編輯的修訂間有衝突,此編輯不能還原。",
+       "undo-main-slot-only": "編輯無法還原,因為有包含到在主分配之外的內容。",
        "undo-norev": "此編輯不存在或已被刪除,無法還原。",
        "undo-nochange": "此編輯已被還原。",
        "undo-summary": "取消由 [[Special:Contributions/$2|$2]] ([[User talk:$2|對話]]) 所作出的修訂 $1",
        "revdelete-text-file": "已刪除的檔案版本仍會出現於檔案歷史中,但內容將不開放存取。",
        "logdelete-text": "已刪除的日誌活動仍會出現於日誌中,但其部分內容將不會向公眾開放存取。",
        "revdelete-text-others": "若未設定額外條件,其他管理員仍有權限檢視與取消刪除隱藏的內容。",
-       "revdelete-confirm": "è«\8b確èª\8dæ\82¨æ\98¯å\90¦æ\98\8eç\99½æ­¤å\8b\95ä½\9cæ\9c\83é\80 æ\88\90ç\9a\84å¾\8cæ\9e\9cï¼\8c以å\8f\8aæ\82¨æ\89\80å\81\9aç\9a\84å\8b\95ä½\9cæ\98¯å\90¦ç¬¦å\90\88[[{{MediaWiki:Policy-url}}|æ\94¿ç­\96]]規範。",
+       "revdelete-confirm": "è«\8b確èª\8dæ\82¨æ\98¯å\90¦æ\98\8eç\99½æ­¤å\8b\95ä½\9cæ\9c\83é\80 æ\88\90ç\9a\84å¾\8cæ\9e\9cï¼\8c以å\8f\8aæ\82¨æ\89\80å\81\9aç\9a\84å\8b\95ä½\9cæ\98¯å\90¦ç¬¦å\90\88[[{{MediaWiki:Policy-url}}|æ\96¹é\87\9d]]規範。",
        "revdelete-suppress-text": "禁止顯示應<strong>只有</strong>在下述情形時使用:\n* 潛在誹謗的資訊\n* 不恰當的個人資料\n*: <em>住家地址、電話號碼、身分證號碼等。</em>",
        "revdelete-legend": "設定顯示限制",
        "revdelete-hide-text": "修訂文字",
        "diff-paragraph-moved-toold": "段落已被移動。點擊來跳至舊的位置。",
        "difference-missing-revision": "查無此差異 ($1) 中的{{PLURAL:$2|1 次修訂|$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": "頁面內容符合",
        "userrights-cannot-shorten-expiry": "您無法提前群組 \"$1\" 中成員的期限。只有擁有新增與移除此群組權限的使用者可以將期限提前。",
        "userrights-conflict": "使用者權限變更發生衝突!請檢閱並確認你的變更。",
        "group": "群組:",
-       "group-user": "用戶",
+       "group-user": "使用者",
        "group-autoconfirmed": "自動確認的使用者",
        "group-bot": "機器人",
        "group-sysop": "管理員",
+       "group-interface-admin": "介面管理員",
        "group-bureaucrat": "行政員",
        "group-suppress": "監督員",
        "group-all": "(全部)",
        "group-autoconfirmed-member": "自動確認使用者",
        "group-bot-member": "機器人",
        "group-sysop-member": "{{GENDER:$1|管理員}}",
+       "group-interface-admin-member": "{{GENDER:$1|介面管理員}}",
        "group-bureaucrat-member": "行政員",
        "group-suppress-member": "{{GENDER:$1|監督員}}",
-       "grouppage-user": "{{ns:project}}:用戶",
+       "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-editusercss": "編輯其他使用者的 CSS 檔",
        "right-edituserjson": "編輯其他使用者的 JSON 檔",
        "right-edituserjs": "編輯其他使用者的 JavaScript 檔",
+       "right-editsitecss": "編輯全站CSS",
+       "right-editsitejson": "編輯全站JSON",
+       "right-editsitejs": "編輯全站JavaScript",
        "right-editmyusercss": "編輯自己的使用者 CSS 檔",
        "right-editmyuserjson": "編輯您自己的使用者 JSON 檔",
        "right-editmyuserjs": "編輯自己的使用者 JavaScript 檔",
        "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-createaccount": "建立帳號",
        "grant-createeditmovepage": "建立、編輯與移動頁面",
        "grant-delete": "刪除頁面、修訂與日誌記錄",
-       "grant-editinterface": "編輯 MediaWiki 命名空間與使用者 CSS/JSON/JavaScript",
+       "grant-editinterface": "編輯 MediaWiki 命名空間與站台範圍/使用者 JSON",
        "grant-editmycssjs": "編輯您的使用者 CSS/JSON/JavaScript",
        "grant-editmyoptions": "編輯您的使用者偏好設定",
        "grant-editmywatchlist": "編輯您的監視清單",
+       "grant-editsiteconfig": "編輯站台範圍與使用者 CSS/JS",
        "grant-editpage": "編輯現有的頁面",
        "grant-editprotected": "編輯受保護的頁面",
        "grant-highvolume": "大量編輯",
        "rcfilters-legend-heading": "<strong>縮寫列表:</strong>",
        "rcfilters-other-review-tools": "其他檢閱工具",
        "rcfilters-group-results-by-page": "按頁面分組結果",
-       "rcfilters-activefilters": "使用的篩選器",
-       "rcfilters-advancedfilters": "進階查詢條件",
+       "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-show-days": "$1{{PLURAL:$1|天}}",
        "rcfilters-days-show-hours": "$1{{PLURAL:$1|小時}}",
        "rcfilters-highlighted-filters-list": "已明顯標示:$1",
-       "rcfilters-quickfilters": "儲存的查詢條件",
+       "rcfilters-quickfilters": "儲存的篩選條件",
        "rcfilters-quickfilters-placeholder-title": "尚未保存過濾器",
-       "rcfilters-quickfilters-placeholder-description": "要儲存您的篩選器設定並供以後重新使用,點選下方啟用的篩選器區域之內的書籤圖示。",
+       "rcfilters-quickfilters-placeholder-description": "要儲存您的篩選設定並供以後重新使用,點選下方啟用的篩選區域之內的書籤圖示。",
        "rcfilters-savedqueries-defaultlabel": "已儲存的查詢條件",
        "rcfilters-savedqueries-rename": "重新命名",
        "rcfilters-savedqueries-setdefault": "設為預設",
        "rcfilters-savedqueries-unsetdefault": "取消設為預設",
-       "rcfilters-savedqueries-remove": "除",
+       "rcfilters-savedqueries-remove": "除",
        "rcfilters-savedqueries-new-name-label": "名稱",
-       "rcfilters-savedqueries-new-name-placeholder": "說明查詢條件的用途",
+       "rcfilters-savedqueries-new-name-placeholder": "說明篩選條件的用途",
        "rcfilters-savedqueries-apply-label": "建立查詢條件",
-       "rcfilters-savedqueries-apply-and-setdefault-label": "建立預設過濾器",
+       "rcfilters-savedqueries-apply-and-setdefault-label": "建立預設篩選",
        "rcfilters-savedqueries-cancel-label": "取消",
-       "rcfilters-savedqueries-add-new-title": "儲存目前的過濾器設定",
-       "rcfilters-savedqueries-already-saved": "這些過濾已被儲存。變更您的設定,來建立新的已儲存過濾。",
+       "rcfilters-savedqueries-add-new-title": "儲存目前的篩選設定",
+       "rcfilters-savedqueries-already-saved": "這些篩選已被儲存。變更您的設定,來建立新的已儲存篩選。",
        "rcfilters-restore-default-filters": "還原預設過濾條件",
-       "rcfilters-clear-all-filters": "清除所有過濾條件",
+       "rcfilters-clear-all-filters": "清除所有篩選條件",
        "rcfilters-show-new-changes": "檢視最新變更",
-       "rcfilters-search-placeholder": "過濾變更(使用選單或搜尋過濾名稱)",
-       "rcfilters-invalid-filter": "無效的過濾條件",
+       "rcfilters-search-placeholder": "篩選變更(使用選單或搜尋篩選名稱)",
+       "rcfilters-invalid-filter": "無效的篩選條件",
        "rcfilters-empty-filter": "沒有使用中的過濾條件。已顯示所有的貢獻。",
-       "rcfilters-filterlist-title": "過濾條件",
+       "rcfilters-filterlist-title": "篩選",
        "rcfilters-filterlist-whatsthis": "這些是怎樣工作的?",
-       "rcfilters-filterlist-feedbacklink": "告訴我們您對這些(新)過濾工具有什麼想法",
+       "rcfilters-filterlist-feedbacklink": "告訴我們您對這些篩選工具有什麼想法",
        "rcfilters-highlightbutton-title": "明顯標示結果",
        "rcfilters-highlightmenu-title": "選擇顏色",
        "rcfilters-highlightmenu-help": "選擇要明顯標示此屬性的色彩",
-       "rcfilters-filterlist-noresults": "查無過濾條件",
+       "rcfilters-filterlist-noresults": "查無篩選條件",
        "rcfilters-noresults-conflict": "因搜尋條件衝突,查無結果",
-       "rcfilters-state-message-subset": "此過濾條件沒有效果,因其結果包含了以下範圍更廣的{{PLURAL:$2|過濾條件|過濾條件}}其中之一 (嘗試以明顯標示來區別它):$1",
-       "rcfilters-state-message-fullcoverage": "選擇在此群組中的所有過濾條件與沒選擇時相同,代表此過濾條件沒有效果。群組包含了:$1",
+       "rcfilters-state-message-subset": "此篩選條件沒有效果,因其結果包含了以下範圍更廣的{{PLURAL:$2|篩選條件|篩選條件}}其中之一(嘗試以明顯標示來區別它):$1",
+       "rcfilters-state-message-fullcoverage": "選擇在此群組中的所有篩選條件與沒選擇時相同,代表此篩選條件沒有效果。群組包含了:$1",
        "rcfilters-filtergroup-authorship": "貢獻的作者",
        "rcfilters-filter-editsbyself-label": "您的編輯",
        "rcfilters-filter-editsbyself-description": "您的貢獻",
        "rcfilters-filter-categorization-description": "從分類中添加或移除頁面的記錄。",
        "rcfilters-filter-logactions-label": "日誌動作",
        "rcfilters-filter-logactions-description": "管理動作、帳號建立、頁面刪除、上傳…",
-       "rcfilters-hideminor-conflicts-typeofchange-global": "\"次要編輯\" 過濾條件與一個或多個變更類型過濾條件衝突,因為某些變更類型無法指定為 \"次要\"。衝突的過濾條件已在上方使用的過濾條件區域中標示。",
-       "rcfilters-hideminor-conflicts-typeofchange": "某些變更類型無法指定為 \"次要\",所以此過濾條件與以下變更類型的過濾條件衝突:$1",
+       "rcfilters-hideminor-conflicts-typeofchange-global": "\"次要編輯\" 過濾條件與一個或多個變更類型篩選條件衝突,因為某些變更類型無法指定為 \"次要\"。衝突的篩選條件已在上方使用的篩選條件區域中標示。",
+       "rcfilters-hideminor-conflicts-typeofchange": "某些變更類型無法指定為 \"次要\",所以此篩選條件與以下變更類型的篩選條件衝突:$1",
        "rcfilters-typeofchange-conflicts-hideminor": "此變更類型過濾條件與 \"次要編輯\" 過濾條件衝突,某些變更類型無法指定為 \"次要\"。",
        "rcfilters-filtergroup-lastRevision": "最新修訂版本",
        "rcfilters-filter-lastrevision-label": "最新修訂版本",
        "rcfilters-exclude-button-off": "排除選項",
        "rcfilters-exclude-button-on": "排除所選",
        "rcfilters-view-tags": "標記的編輯",
-       "rcfilters-view-namespaces-tooltip": "按命名空間過濾結果",
+       "rcfilters-view-namespaces-tooltip": "按命名空間篩選結果",
        "rcfilters-view-tags-tooltip": "按編輯標籤過濾結果",
-       "rcfilters-view-return-to-default-tooltip": "返回主過濾選單",
+       "rcfilters-view-return-to-default-tooltip": "返回主篩選選單",
        "rcfilters-view-tags-help-icon-tooltip": "了解更多關於標記編輯的資訊",
        "rcfilters-liveupdates-button": "動態更新",
        "rcfilters-liveupdates-button-title-on": "關閉動態更新",
        "rcfilters-watchlist-edit-watchlist-button": "編輯您的監視頁面列表",
        "rcfilters-watchlist-showupdated": "自更改發生以來,對您尚未訪問的頁面做出的更改以<strong>粗體</strong>顯示,並帶有實心圓形標記。",
        "rcfilters-preference-label": "隱藏改善的最近變更版本",
-       "rcfilters-preference-help": "返回到2017年介面重新設計版,並重新新增這以後增加的工具。",
+       "rcfilters-preference-help": "返回到 2017 年的重新設計介面,並添加此後的所有工具。",
+       "rcfilters-watchlist-preference-label": "隱藏監視清單的改善版本",
+       "rcfilters-watchlist-preference-help": "返回到 2017 年的重新設計介面,並添加此後的所有工具。",
        "rcfilters-filter-showlinkedfrom-label": "顯示連結自此頁面的頁面上的變更",
        "rcfilters-filter-showlinkedfrom-option-label": "<strong>連結自</strong>指定頁面的頁面",
        "rcfilters-filter-showlinkedto-label": "顯示連結到該頁面的頁面上的更改",
        "uploaded-wrong-setting-svg": "於已上傳的 SVG 檔案中找到 <code>&lt;set to=\"$1\"&gt;</code>,已禁止使用 \"set\" 標籤加入 remote/data/script 目標至任何屬性。",
        "uploaded-setting-handler-svg": "於已上傳的 SVG 檔案中找到 <code>$1=\"$2\"</code>,已禁止 SVG 使用 remote/data/script 設定 \"handler\" 屬性。",
        "uploaded-remote-url-svg": "於已上傳的 SVG 檔案中找到 <code>$1=\"$2\"</code>,已禁止 SVG 使用任何遠端 URL 設定樣式。",
-       "uploaded-image-filter-svg": "於已上傳的 SVG 檔案中找到圖片過濾器使用 URL:<code>&lt;$1 $2=\"$3\"&gt;</code>。",
+       "uploaded-image-filter-svg": "於已上傳的 SVG 檔案中找到以 URL 形式的圖片篩選:<code>&lt;$1 $2=\"$3\"&gt;</code>。",
        "uploadscriptednamespace": "此 SVG 檔案使用了非法的命名空間 \"<nowiki>$1</nowiki>\"。",
        "uploadinvalidxml": "無法解析已上傳檔案中的 XML。",
        "uploadvirus": "該檔案含有病毒!\n詳細資料:$1",
        "uploadstash-zero-length": "檔案長度為零。",
        "invalid-chunk-offset": "無效區塊位置",
        "img-auth-accessdenied": "拒絕存取",
-       "img-auth-nopathinfo": "缺少 PATH_INFO 參數。\n您安裝的伺服器未傳遞此資訊,\n您可能使用 CGI 為基礎的伺服器,且不支援 img_auth 功能。\n請參考 https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization。",
+       "img-auth-nopathinfo": "缺少路徑資訊。\n您的伺服器必須設定來傳遞 REQUEST_URI 以及/或 PATH_INFO 變數。\n若已如此,請嘗試啟動 $wgUsePathInfo。\n請參考 https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization。",
        "img-auth-notindir": "已設定的上傳目錄清單中不存在您指定的路徑。",
        "img-auth-badtitle": "無法使用 \"$1\" 建立有效的標題。",
        "img-auth-nologinnWL": "您尚未登入,且 \"$1\" 並未在允許清單上。",
        "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": "無法連線至指定的 URL 。\n請重新檢查 URL 是否正確,且確認網站是否正常運作。",
        "upload-curl-error28": "上傳逾時",
        "listfiles_thumb": "縮圖",
        "listfiles_date": "日期",
        "listfiles_name": "名稱",
-       "listfiles_user": "用戶",
+       "listfiles_user": "使用者",
        "listfiles_size": "大小",
        "listfiles_description": "描述",
        "listfiles_count": "版本",
        "filehist-thumb": "縮圖",
        "filehist-thumbtext": "於 $1 版本的縮圖",
        "filehist-nothumb": "沒有縮圖",
-       "filehist-user": "用戶",
+       "filehist-user": "使用者",
        "filehist-dimensions": "尺寸",
        "filehist-filesize": "檔案大小",
        "filehist-comment": "備註",
        "filedelete-maintenance": "維護期間檔案刪除和還原暫停使用。",
        "filedelete-maintenance-title": "無法刪除檔案",
        "mimesearch": "MIME 搜尋",
-       "mimesearch-summary": "本頁面可搜尋檔案的 MIME 類型。\n輸入格式:內容類型/子類型 或 內容類型/*,如 <code>image/jpeg</code>。",
+       "mimesearch-summary": "本頁面可篩選檔案的 MIME 類型。\n輸入格式:內容類型/子類型 或 內容類型/*,如 <code>image/jpeg</code>。",
        "mimetype": "MIME 類型:",
        "download": "下載",
        "unwatchedpages": "未監視的頁面",
        "speciallogtitlelabel": "目標 (標題或以 {{ns:user}}:使用者 表示使用者):",
        "log": "日誌",
        "logeventslist-submit": "顯示",
+       "logeventslist-more-filters": "顯示額外日誌:",
+       "logeventslist-patrol-log": "巡查日誌",
+       "logeventslist-tag-log": "標籤日誌",
        "all-logs-page": "所有公開日誌",
        "alllogstext": "合併顯示所有 {{SITENAME}} 中所有類型的日誌。\n您可以點選下拉式選單選擇日誌的類型,指定使用者名稱 (區分大小寫) 或影響的頁面 (區分大小寫)。",
        "logempty": "無符合條件的日誌。",
        "unwatching": "正在停止監視...",
        "watcherrortext": "變更 \"$1\" 的監視清單設定時發生錯誤。",
        "enotif_reset": "標記所有頁面為已檢視",
-       "enotif_impersonal_salutation": "{{SITENAME}}用戶",
+       "enotif_impersonal_salutation": "{{SITENAME}}使用者",
        "enotif_subject_deleted": "{{SITENAME}} $2 已刪除頁面 $1",
        "enotif_subject_created": "{{SITENAME}} $2 已建立頁面 $1",
        "enotif_subject_moved": "{{SITENAME}} $2 已移動頁面 $1",
        "dellogpage": "刪除日誌",
        "dellogpagetext": "以下為最近刪除記錄的清單。",
        "deletionlog": "刪除日誌",
+       "log-name-create": "頁面建立日誌",
+       "log-description-create": "以下為最近頁面建立的清單。",
+       "logentry-create-create": "$1 {{GENDER:$2|已建立}}頁面 $3",
        "reverted": "還原到較早的版本",
        "deletecomment": "原因:",
        "deleteotherreason": "其它/額外的原因:",
        "undeletehistory": "若您還原該頁面,所有的修訂歷史也會一併還原。\n若刪除之後已有使用相同名稱建立的新頁面,還原的修訂歷史會出現在此頁面之前的歷史中。",
        "undeleterevdel": "若最新頁面或檔案修訂被部份刪除,將無法執行取消刪除的動作。\n這種情況您必須取消勾選或取消隱藏已刪除的最新修訂。",
        "undeletehistorynoadmin": "已刪除此頁面。\n以下摘要顯示刪除原因與刪除前所有編輯過此頁面的使用者詳細資料。\n這些已刪除的實際文字修訂僅對管理員可用。",
-       "undelete-revision": "被 $3 刪除的 $1 (於 $4 $5) 修訂:",
+       "undelete-revision": "$1由$3(於$4 $5)所編輯的已刪除修訂版本",
        "undeleterevision-missing": "無效或遺失的修訂。\n您可能使用了錯誤的連結,或該修訂已從封存中還原或刪除。",
        "undeleterevision-duplicate-revid": "無法還原 {{PLURAL:$1|1 個修訂|$1 修訂}},因{{PLURAL:$1|修訂的|修訂的}} <code>rev_id</code> 已在使用中。",
        "undelete-nodiff": "查無先前的修訂。",
        "uctop": "(目前)",
        "month": "截止月份:",
        "year": "截止年份:",
+       "date": "開始日期(更早之前):",
        "sp-contributions-newbies": "僅顯示新帳號的貢獻",
        "sp-contributions-newbies-sub": "新帳號的貢獻",
        "sp-contributions-newbies-title": "新帳號的使用者貢獻",
        "whatlinkshere": "連結至此的頁面",
        "whatlinkshere-title": "連結至「$1」的頁面",
        "whatlinkshere-page": "頁面:",
-       "linkshere-2": "以下頁面連結至 <strong>$1</strong>:",
-       "nolinkshere-2": "沒有頁面連結至 <strong>$1</strong>。",
-       "nolinkshere-ns-2": "已選擇的命名空間中沒有頁面連結到 $1。",
+       "linkshere": "以下頁面連結至 <strong>$1</strong>:",
+       "nolinkshere": "沒有頁面連結至 <strong>$1</strong>。",
+       "nolinkshere-ns": "已選擇的命名空間中沒有頁面連結到 <strong>$2</strong>。",
        "isredirect": "重新導向頁面",
        "istemplate": "引用",
        "isimage": "檔案連結",
        "whatlinkshere-hidetrans": "$1 引用",
        "whatlinkshere-hidelinks": "$1 連結",
        "whatlinkshere-hideimages": "$1 檔案連結",
-       "whatlinkshere-filters": "篩選",
+       "whatlinkshere-filters": "篩選",
        "whatlinkshere-submit": "前往",
        "autoblockid": "自動封鎖 #$1",
        "block": "封鎖使用者",
        "ipboptions": "2 小時:2 hours,1 天:1 day,3 天:3 days,1 週:1 week,2 週:2 weeks,1 個月:1 month,3 個月:3 months,6 個月:6 months,1 年:1 year,無限期:infinite",
        "ipbhidename": "在編輯及清單中隱藏使用者名稱",
        "ipbwatchuser": "監視這位使用者的使用者頁面及其對話頁面",
-       "ipb-disableusertalk": "阻止此使用者在封鎖期間編輯自己的對話頁面",
+       "ipb-disableusertalk": "禁止使用者在封鎖期間編輯自己的對話頁面",
        "ipb-change-block": "使用現有設定重新封鎖使用者",
        "ipb-confirm": "確認封鎖",
        "badipaddress": "無效的 IP 位址",
        "allmessages-filter-unmodified": "未修改",
        "allmessages-filter-all": "全部",
        "allmessages-filter-modified": "已修改",
-       "allmessages-prefix": "依字首搜尋:",
+       "allmessages-prefix": "依字首篩選:",
        "allmessages-language": "語言:",
        "allmessages-filter-submit": "執行",
        "allmessages-filter-translate": "翻譯",
        "pageinfo-category-pages": "頁面數量",
        "pageinfo-category-subcats": "子分類數量",
        "pageinfo-category-files": "檔案數量",
-       "pageinfo-user-id": "用戶ID",
+       "pageinfo-user-id": "使用者 ID",
        "pageinfo-file-hash": "雜湊值",
        "markaspatrolleddiff": "標記為已巡查",
        "markaspatrolledtext": "標記此頁面為已巡查",
        "markedaspatrollederrornotify": "標記為已巡查失敗。",
        "patrol-log-page": "巡查日誌",
        "patrol-log-header": "這是已巡查的修訂版本的日誌。",
-       "log-show-hide-patrol": "$1 巡查日誌",
-       "log-show-hide-tag": "$1 標籤日誌",
        "confirm-markpatrolled-button": "確定",
        "confirm-markpatrolled-top": "標記 $2 的修訂 $3 為已巡查?",
        "deletedrevision": "已刪除舊修訂 $1",
        "watchlistedit-clear-done": "已清空您的監視清單。",
        "watchlistedit-clear-jobqueue": "您的監視列表正在清空。這需要花一些時間!",
        "watchlistedit-clear-removed": "已移除 $1 個標題:",
-       "watchlistedit-too-many": "太多要在此處顯示的頁面。",
+       "watchlistedit-too-many": "頁面太多,無法顯示。",
        "watchlisttools-clear": "清空監視清單",
        "watchlisttools-view": "檢視相關變更",
        "watchlisttools-edit": "檢視並編輯監視清單",
        "redirect-submit": "執行",
        "redirect-lookup": "查詢:",
        "redirect-value": "值:",
-       "redirect-user": "用戶ID",
+       "redirect-user": "使用者ID",
        "redirect-page": "頁面 ID",
        "redirect-revision": "頁面修訂 ID",
        "redirect-file": "檔案名稱",
        "tags-delete-title": "刪除標籤",
        "tags-delete-explanation-initial": "您正要從資料庫刪除標籤 \"$1\"。",
        "tags-delete-explanation-in-use": "標籤會自目前正在使用的{{PLURAL:$2| $2 個修訂或日誌項目| $2 修訂或日誌項目}}中移除。",
-       "tags-delete-explanation-warning": "此動作是 <strong>無法還原的</strong> 且 <strong>無法取消的</strong>,即使是資料庫管理者也無法。 請確認您要刪除的標題。",
+       "tags-delete-explanation-warning": "此動作是<strong>不可逆轉的</strong>且<strong>無法取消的</strong>,即使是資料庫管理員也無法。請確認您要刪除的標籤。",
        "tags-delete-explanation-active": "<strong>標籤 \"$1\" 尚在使用,無法刪除。</strong> 要停止標籤使用,請至套用該標籤的頁面,並於該處將標籤停用。",
        "tags-delete-reason": "原因:",
-       "tags-delete-submit": "無法取消刪除此標籤",
+       "tags-delete-submit": "不可逆轉地刪除此標籤",
        "tags-delete-not-allowed": "無法刪除由擴充套件定義的標籤,除非該擴充套件允許。",
        "tags-delete-not-found": "標籤 \"$1\" 不存在。",
        "tags-delete-too-many-uses": "標籤 \"$1\" 會套用至 $2 筆以上的{{PLURAL:$2|修訂|修訂}},這代表該標籤將無法刪除。",
        "passwordpolicies-policy-passwordcannotmatchusername": "密碼不可以和使用者名稱相同",
        "passwordpolicies-policy-passwordcannotmatchblacklist": "密碼不可以同於被列入黑名單的特定密碼",
        "passwordpolicies-policy-maximalpasswordlength": "密碼必須小於 $1 個{{PLURAL:$1|字元|字元}}長度",
-       "passwordpolicies-policy-passwordcannotbepopular": "密碼不可以是{{PLURAL:$1|常用密碼內容|在清單中的編號 $1 常用密碼}}"
+       "passwordpolicies-policy-passwordcannotbepopular": "密碼不可以是{{PLURAL:$1|常用密碼內容|在清單中的編號 $1 常用密碼}}",
+       "easydeflate-invaliddeflate": "提供的內容未被正常的壓縮"
 }
index 131172a..4b15837 100644 (file)
@@ -14,7 +14,9 @@
                        "Justincheng12345",
                        "LNDDYL",
                        "Liuxinyu970226",
-                       "Quest for Truth"
+                       "Quest for Truth",
+                       "Wxyveronica",
+                       "和平至上"
                ]
        },
        "tog-watchlisthidebots": "隱藏監視清單中機械人的編輯",
        "october": "十月",
        "november": "十一月",
        "december": "十二月",
+       "jan": "1月",
+       "feb": "2月",
+       "mar": "3月",
+       "apr": "4月",
+       "may": "5月",
+       "jun": "6月",
+       "jul": "7月",
+       "aug": "8月",
+       "sep": "9月",
+       "oct": "10月",
+       "nov": "11月",
+       "dec": "12月",
        "mytalk": "我的討論頁",
+       "navigation": "導覽",
+       "namespaces": "命名空間",
+       "variants": "變體",
+       "navigation-heading": "導覽菜單",
        "tagline": "從 {{SITENAME}}",
+       "help": "說明",
        "search": "搜尋",
+       "searchbutton": "搜尋",
+       "searcharticle": "執行",
        "printableversion": "可打印版",
        "permalink": "靜態連結",
        "print": "打印",
+       "edit": "編輯",
+       "talkpagelinktext": "對話",
        "specialpage": "特殊頁面",
+       "personaltools": "個人工具",
+       "talk": "討論",
+       "views": "檢視",
+       "toolbox": "工具",
        "jumpto": "跳到:",
+       "jumptonavigation": "導覽",
        "jumptosearch": "搜尋",
+       "aboutsite": "關於 {{SITENAME}}",
        "aboutpage": "Project:關於我們",
+       "disclaimers": "免責聲明",
+       "disclaimerpage": "本專案:一般免責聲明",
+       "mainpage": "首頁",
        "privacy": "私隱政策",
        "privacypage": "Project:私隱政策",
+       "retrievedfrom": "取自 \"$1\"",
+       "editsection": "編輯",
+       "editsectionhint": "編輯章節:$1",
+       "site-atom-feed": "$1 Atom摘要",
        "red-link-title": "$1 (頁面不存在)",
        "nstab-user": "用戶頁面",
        "nstab-special": "特殊頁面",
        "nstab-template": "模板",
+       "mainpage-nstab": "首頁",
        "editinginterface": "<strong>警告:</strong>您正在編輯的頁面文字是用來作為軟件介面使用。更改此頁面將會影響其他用戶在此 Wiki 上看到的用戶介面。",
        "yourname": "用戶名稱:",
        "userlogin-yourname": "用戶名稱",
        "nav-login-createaccount": "登入/創造帳戶",
        "wrongpassword": "您輸入的密碼有錯誤,請再試一次。",
+       "pt-login": "登入",
+       "pt-createaccount": "建立賬號",
        "botpasswords": "機械人密碼",
        "botpasswords-summary": "<em>機械人密碼</em>可在不使用帳號的主要登入密碼情況下,允許透過 API 存取使用者帳號。使用機械人密碼登入的使用者權限或會有所限制。\n\n若你並非必須設定此密碼,你便不應使用此功能。任何人都不會索取你的機械人密碼。",
        "botpasswords-disabled": "機械人密碼已停用。",
        "rcshowhidebots": "$1機械人的編輯",
        "rcshowhideliu": "$1 已註冊的用戶",
        "rcshowhideanons": "$1 匿名用戶",
+       "rc-change-size-new": "變更後為$1{{PLURAL:$1|}}",
        "upload": "上載檔案",
        "listfiles_user": "用戶",
        "filehist-user": "用戶",
        "checkbox-select": "選擇: $1",
        "emailusername": "用戶名稱:",
        "wlshowhidebots": "機械人",
+       "blanknamespace": "(主要)",
        "blockip": "封鎖{{GENDER:$1|用戶}}",
        "contribslink": "貢獻",
        "blocklogtext": "這是用戶的封禁與解禁操作的日誌記錄。\n自動封禁的 IP 位址不予包含。\n請參考 [[Special:BlockList|封禁清單]] 以檢視目前的封禁。",
+       "tooltip-pt-login": "我們建議您登入,但這並非必要",
+       "tooltip-pt-createaccount": "我們建議您建立一個賬號并登入,但這並非必要",
        "tooltip-search": "搜尋 {{SITENAME}}",
        "tooltip-search-go": "若是真有其頁,則進入相同名字的頁面",
        "tooltip-search-fulltext": "在此頁面內搜尋此文字",
+       "tooltip-p-logo": "前往首頁",
        "tooltip-n-mainpage": "回到首頁",
        "tooltip-n-mainpage-description": "回到首頁",
+       "tooltip-n-recentchanges": "wiki近期變更清單",
        "tooltip-n-randompage": "跳到一個隨機抽取的頁面",
+       "tooltip-n-help": "尋求說明",
        "tooltip-t-contributions": "此用戶的貢獻清單",
        "tooltip-t-upload": "上載檔案",
+       "tooltip-t-specialpages": "特殊頁面總清單",
        "tooltip-t-print": "這個頁面的可打印版本",
        "tooltip-ca-nstab-user": "檢視用戶頁面",
+       "pageinfo-toolboxlink": "頁面資訊",
        "newimages-showbots": "顯示機械人上傳的檔案",
        "exif-rowsperstrip": "每帶行數",
        "redirect-user": "用戶 ID",
        "specialpages": "特殊頁面",
        "tags-source-manual": "由使用者與機械人手動套用",
-       "logentry-managetags-activate": "$1{{GENDER:$2|已啟用}}標籤「$4」供使用者與機械人使用"
+       "logentry-managetags-activate": "$1{{GENDER:$2|已啟用}}標籤「$4」供使用者與機械人使用",
+       "searchsuggest-search": "搜尋{{SITENAME}}"
 }
index 9ad5951..93260fe 100644 (file)
@@ -73,3 +73,5 @@ $magicWords = [
        'special'                   => [ '0', 'цастәи', 'служебная', 'special' ],
        'index'                     => [ '1', '__АИНДЕКС__', '__ИНДЕКС__', '__INDEX__' ],
 ];
+
+$linkTrail = '/^([a-zабвгҕдежзӡикқҟлмнопҧрстҭуфхҳцҵчҷҽҿшыҩџьә]+)(.*)$/sDu';
index d82cde7..5c69ac3 100644 (file)
@@ -194,5 +194,5 @@ $specialPageAliases = [
 # South Africa uses space for thousands and comma for decimal
 # Reference: AWS Reël 7.4 p. 52, 2002 edition
 # glibc is wrong in this respect in some versions
-$separatorTransformTable = [ ',' => "\xc2\xa0", '.' => ',' ];
+$separatorTransformTable = [ ',' => "\u{00A0}", '.' => ',' ];
 $linkTrail = "/^([a-z]+)(.*)$/sD";
index ea807fd..c54c613 100644 (file)
@@ -65,7 +65,7 @@ $dateFormats = [
 
 # Per discussion on https://translatewiki.net/wiki/Thread:Support/Customization_of number format
 $separatorTransformTable = [
-       ',' => "\xc2\xa0", # nbsp
+       ',' => "\u{00A0}", # nbsp
        '.' => ','
 ];
 
index ee2bbb3..00295fe 100644 (file)
@@ -233,7 +233,7 @@ $dateFormats = [
 ];
 
 $separatorTransformTable = [
-       ',' => "\xc2\xa0", # nbsp
+       ',' => "\u{00A0}", # nbsp
        '.' => ','
 ];
 $minimumGroupingDigits = 2;
index 383a3cd..5c49964 100644 (file)
@@ -217,5 +217,5 @@ $bookstoreList = [
 
 $linkTrail = '/^([a-zабвгдежзийклмнопрстуфхцчшщъыьэюя]+)(.*)$/sDu';
 
-$separatorTransformTable = [ ',' => "\xc2\xa0", '.' => ',' ];
+$separatorTransformTable = [ ',' => "\u{00A0}", '.' => ',' ];
 $minimumGroupingDigits = 2;
index d7614cc..2aef1ed 100644 (file)
@@ -164,5 +164,5 @@ $dateFormats = [
        'dmy both' => 'j M Y "da" H:i',
 ];
 
-$separatorTransformTable = [ ',' => "\xc2\xa0", '.' => ',' ];
+$separatorTransformTable = [ ',' => "\u{00A0}", '.' => ',' ];
 $linkTrail = "/^((?:c\'h|C\'H|C\'h|c’h|C’H|C’h|[a-zA-ZàâçéèêîôûäëïöüùñÇÉÂÊÎÔÛÄËÏÖÜÀÈÙÑ])+)(.*)$/sDu";
diff --git a/languages/messages/MessagesBtm.php b/languages/messages/MessagesBtm.php
new file mode 100644 (file)
index 0000000..c2d1d6c
--- /dev/null
@@ -0,0 +1,11 @@
+<?php
+/** Mandailing (Batak Mandailing)
+ *
+ * To improve a translation please visit https://translatewiki.net
+ *
+ * @ingroup Language
+ * @file
+ *
+ */
+
+$fallback = 'id';
index affcc83..6a2e41d 100644 (file)
@@ -383,4 +383,4 @@ $bookstoreList = [
 # Písmena, která se mají objevit jako část odkazu ve formě '[[jazyk]]y' atd:
 $linkTrail = '/^([a-záčďéěíňóřšťúůýž]+)(.*)$/sDu';
 
-$separatorTransformTable = [ ',' => "\xc2\xa0", '.' => ',' ];
+$separatorTransformTable = [ ',' => "\u{00A0}", '.' => ',' ];
index 0ce25e2..2e96cc8 100644 (file)
@@ -275,7 +275,7 @@ $magicWords = [
        'url_query'                 => [ '0', 'INFORMPETO', 'QUERY' ],
 ];
 
-$separatorTransformTable = [ ',' => "\xc2\xa0", '.' => ',' ];
+$separatorTransformTable = [ ',' => "\u{00A0}", '.' => ',' ];
 
 $datePreferences = false;
 $defaultDateFormat = 'dmy';
index e0676a6..0d8258e 100644 (file)
@@ -302,7 +302,7 @@ $dateFormats = [
        'dmy both' => 'H:i j M Y',
 ];
 
-$separatorTransformTable = [ ',' => "\xc2\xa0", '.' => ',' ];
+$separatorTransformTable = [ ',' => "\u{00A0}", '.' => ',' ];
 $minimumGroupingDigits = 2;
 
 $linkTrail = '/^([a-záéíóúñ]+)(.*)$/sDu';
index d2f8f32..63365fd 100644 (file)
@@ -258,7 +258,7 @@ $magicWords = [
        'formatdate'                => [ '0', 'kuupäevavormindus', 'formatdate', 'dateformat' ],
 ];
 
-$separatorTransformTable = [ ',' => "\xc2\xa0", '.' => ',' ];
+$separatorTransformTable = [ ',' => "\u{00A0}", '.' => ',' ];
 $minimumGroupingDigits = 2;
 
 $linkTrail = '/^([äöõšüža-z]+)(.*)$/sDu';
index b019fd6..5fbc47b 100644 (file)
@@ -245,7 +245,7 @@ $magicWords = [
        'protectionlevel'           => [ '1', 'SUOJAUSTASO', 'PROTECTIONLEVEL' ],
 ];
 
-$separatorTransformTable = [ ',' => "\xc2\xa0", '.' => ',' ];
+$separatorTransformTable = [ ',' => "\u{00A0}", '.' => ',' ];
 
 $datePreferences = [
        'default',
index 3e3cf80..9844a5e 100644 (file)
@@ -316,4 +316,4 @@ $dateFormats = [
        'ymd both' => 'Y F j à H:i',
 ];
 
-$separatorTransformTable = [ ',' => "\xc2\xa0", '.' => ',' ];
+$separatorTransformTable = [ ',' => "\u{00A0}", '.' => ',' ];
index 0ac1caf..fc160b4 100644 (file)
@@ -301,4 +301,4 @@ $dateFormats = [
        'ymd both' => 'Y F j "a" H:i',
 ];
 
-$separatorTransformTable = [ ',' => "\xc2\xa0", '.' => ',' ];
+$separatorTransformTable = [ ',' => "\u{00A0}", '.' => ',' ];
index 9846686..717538b 100644 (file)
@@ -104,4 +104,4 @@ $dateFormats = [
        'dmy both' => 'j "di" M Y "a lis" H:i',
 ];
 
-$separatorTransformTable = [ ',' => "\xc2\xa0", '.' => ',' ];
+$separatorTransformTable = [ ',' => "\u{00A0}", '.' => ',' ];
index 7fcfad8..6cab75d 100644 (file)
@@ -40,7 +40,7 @@ $namespaceAliases = [
 ];
 
 $fallback8bitEncoding = "iso8859-2";
-$separatorTransformTable = [ ',' => "\xc2\xa0", '.' => ',' ];
+$separatorTransformTable = [ ',' => "\u{00A0}", '.' => ',' ];
 
 $specialPageAliases = [
        'Activeusers'               => [ 'Aktív_felhasználók', 'Aktív_szerkesztők' ],
index 34306d3..1eeaa60 100644 (file)
@@ -9,7 +9,7 @@
  */
 
 $separatorTransformTable = [
-       ',' => "\xc2\xa0", # nbsp
+       ',' => "\u{00A0}", # nbsp
        '.' => ','
 ];
 $minimumGroupingDigits = 2;
index c3a2905..3192e2a 100644 (file)
@@ -8,7 +8,7 @@
  *
  */
 
-$separatorTransformTable = [ ',' => "\xc2\xa0", '.' => ',' ];
+$separatorTransformTable = [ ',' => "\u{00A0}", '.' => ',' ];
 
 $namespaceNames = [
        NS_MEDIA            => 'Multimedia',
index e73a2fc..fdbce22 100644 (file)
@@ -32,7 +32,7 @@ $namespaceAliases = [
        'Discussioni_immagine' => NS_FILE_TALK,
 ];
 
-$separatorTransformTable = [ ',' => "\xc2\xa0", '.' => ',' ];
+$separatorTransformTable = [ ',' => "\u{00A0}", '.' => ',' ];
 
 $dateFormats = [
        'mdy time' => 'H:i',
index 2c7cb9e..397af46 100644 (file)
@@ -11,7 +11,7 @@
 $fallback = 'kk-latn, kk-cyrl';
 
 $separatorTransformTable = [
-       ',' => "\xc2\xa0",
+       ',' => "\u{00A0}",
        '.' => ',',
 ];
 $minimumGroupingDigits = 2;
index c559d02..aeaa06a 100644 (file)
@@ -19,7 +19,7 @@
  */
 
 $separatorTransformTable = [
-       ',' => "\xc2\xa0",
+       ',' => "\u{00A0}",
        '.' => ',',
 ];
 $minimumGroupingDigits = 2;
index 36e8ecb..9c2b84e 100644 (file)
@@ -15,7 +15,7 @@
 $fallback = 'kk-cyrl';
 
 $separatorTransformTable = [
-       ',' => "\xc2\xa0",
+       ',' => "\u{00A0}",
        '.' => ',',
 ];
 
index 42cc676..5db2062 100644 (file)
@@ -78,6 +78,7 @@ $specialPageAliases = [
        'Allpages'                  => [ '모든문서' ],
        'ApiHelp'                   => [ 'Api도움말' ],
        'Ancientpages'              => [ '오래된문서' ],
+       'AutoblockList'             => [ '자동차단목록' ],
        'Badtitle'                  => [ '잘못된제목', '인식불가제목', '잘못된이름', '인식불가이름' ],
        'Blankpage'                 => [ '빈문서' ],
        'Block'                     => [ '차단', 'IP차단', '사용자차단' ],
@@ -113,7 +114,7 @@ $specialPageAliases = [
        'LinkSearch'                => [ '링크검색', '링크찾기' ],
        'Listadmins'                => [ '관리자', '관리자목록' ],
        'Listbots'                  => [ '봇', '봇목록' ],
-       'Listfiles'                 => [ '파일', '그림', '파일목록', '그림목록' ],
+       'Listfiles'                 => [ '파일목록', '그림목록', '파일', '그림' ],
        'Listgrouprights'           => [ '사용자권한목록', '사용자권한', '권한목록' ],
        'Listgrants'                => [ '권한부여목록' ],
        'Listredirects'             => [ '넘겨주기목록' ],
@@ -142,7 +143,9 @@ $specialPageAliases = [
        'Newimages'                 => [ '새파일', '새그림' ],
        'Newpages'                  => [ '새문서' ],
        'PagesWithProp'             => [ '속성별문서' ],
+       'PageData'                  => [ '문서데이터' ],
        'PageLanguage'              => [ '문서언어' ],
+       'PasswordPolicies'          => [ '비밀번호정책' ],
        'PasswordReset'             => [ '비밀번호재설정', '비밀번호초기화' ],
        'PermanentLink'             => [ '고유링크', '영구링크' ],
        'Preferences'               => [ '환경설정' ],
index 291ed14..c96c94d 100644 (file)
@@ -94,7 +94,7 @@ $namespaceAliases = [
        'Katejorije_Klaaf'      => NS_CATEGORY_TALK,
 ];
 
-$separatorTransformTable = [ ',' => "\xc2\xa0", '.' => ',' ];
+$separatorTransformTable = [ ',' => "\u{00A0}", '.' => ',' ];
 $minimumGroupingDigits = 2;
 
 $linkTrail = '/^([äöüėëijßəğåůæœça-z]+)(.*)$/sDu';
index 1fa3e11..e6bedd0 100644 (file)
@@ -51,7 +51,7 @@ $namespaceAliases = [
        'Disputatio_Imaginis' => NS_FILE_TALK,
 ];
 
-$separatorTransformTable = [ ',' => "\xc2\xa0" ];
+$separatorTransformTable = [ ',' => "\u{00A0}" ];
 
 $dateFormats = [
        'mdy time' => 'H:i',
index 9b4aa82..ae72fac 100644 (file)
@@ -12,7 +12,7 @@
 $fallback = 'ru';
 
 $separatorTransformTable = [
-       ',' => "\xc2\xa0", # nbsp
+       ',' => "\u{00A0}", # nbsp
        '.' => ','
 ];
 
index 6a71ca7..a92dc02 100644 (file)
@@ -19,4 +19,4 @@ $namespaceGenderAliases = [];
 $linkPrefixExtension = true;
 
 # Same as the French (T10485)
-$separatorTransformTable = [ ',' => "\xc2\xa0", '.' => ',' ];
+$separatorTransformTable = [ ',' => "\u{00A0}", '.' => ',' ];
index b79f9d8..68d41c0 100644 (file)
@@ -171,7 +171,7 @@ $magicWords = [
 ];
 
 $fallback8bitEncoding = 'windows-1257';
-$separatorTransformTable = [ ',' => "\xc2\xa0", '.' => ',' ];
+$separatorTransformTable = [ ',' => "\u{00A0}", '.' => ',' ];
 
 $dateFormats = [
        'ymd time' => 'H:i',
index 4c75a51..6d8e198 100644 (file)
@@ -29,7 +29,7 @@
 
 /**
  * @copyright Copyright © 2006, Niklas Laxström
- * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ * @license GPL-2.0-or-later
  */
 
 $linkTrail = '/^([a-zA-ZĀāČčĒēĢģĪīĶķĻļŅņŠšŪūŽž]+)(.*)$/sDu';
@@ -63,7 +63,7 @@ $namespaceGenderAliases = [
        NS_USER_TALK => [ 'male' => 'Dalībnieka_diskusija', 'female' => 'Dalībnieces_diskusija' ]
 ];
 
-$separatorTransformTable = [ ',' => "\xc2\xa0", '.' => ',' ];
+$separatorTransformTable = [ ',' => "\u{00A0}", '.' => ',' ];
 
 /**
  * A list of date format preference keys, which can be selected in user
diff --git a/languages/messages/MessagesMni.php b/languages/messages/MessagesMni.php
new file mode 100644 (file)
index 0000000..1641c2a
--- /dev/null
@@ -0,0 +1,9 @@
+<?php
+/** Manipuri/Meitei (মেইতেই লোন্)
+ *
+ * To improve a translation please visit https://translatewiki.net
+ *
+ * @ingroup Language
+ * @file
+ *
+ */
index b51839d..c172d08 100644 (file)
@@ -323,6 +323,6 @@ $digitTransformTable = [
        '9' => '९', # &#x096f;
 ];
 
-$linkTrail = "/^([\xE0\xA4\x80-\xE0\xA5\xA3\xE0\xA5\xB1-\xE0\xA5\xBF\xEF\xBB\xBF\xE2\x80\x8D]+)(.*)$/sDu";
+$linkTrail = "/^([\u{0900}-\u{0963}\u{0971}-\u{097F}\u{FEFF}\u{200D}]+)(.*)$/sDu";
 
 $digitGroupingPattern = "##,##,###";
index 66f0527..002dcac 100644 (file)
@@ -82,7 +82,7 @@ $namespaceAliases = [
        'Bildediskusjon' => NS_FILE_TALK,
 ];
 
-$separatorTransformTable = [ ',' => "\xc2\xa0", '.' => ',' ];
+$separatorTransformTable = [ ',' => "\u{00A0}", '.' => ',' ];
 $linkTrail = '/^([æøåa-z]+)(.*)$/sDu';
 
 $datePreferenceMigrationMap = [
index 7572c67..9107b9a 100644 (file)
@@ -35,8 +35,8 @@
  */
 
 /**
- * @license http://www.gnu.org/copyleft/fdl.html GNU Free Documentation License
- * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License
+ * @license GFDL-1.3-or-later
+ * @license GPL-2.0-or-later
  *
  * @see https://meta.wikimedia.org/w/index.php?title=LanguageNn.php&action=history
  * @see https://nn.wikipedia.org/w/index.php?title=Brukar:Dittaeva/LanguageNn.php&action=history
@@ -317,7 +317,7 @@ $specialPageAliases = [
 ];
 
 $separatorTransformTable = [
-       ',' => "\xc2\xa0",
+       ',' => "\u{00A0}",
        '.' => ','
 ];
 $linkTrail = '/^([æøåa-z]+)(.*)$/sDu';
index eb8ed88..16edc8e 100644 (file)
@@ -286,6 +286,6 @@ $dateFormats = [
        'oc normal both' => 'j F "de" Y "a" H.i',
 ];
 
-$separatorTransformTable = [ ',' => "\xc2\xa0", '.' => ',' ];
+$separatorTransformTable = [ ',' => "\u{00A0}", '.' => ',' ];
 
 $linkTrail = "/^([a-zàâçéèêîôû]+)(.*)$/sDu";
index 1af008f..dcc9a44 100644 (file)
@@ -121,7 +121,7 @@ $dateFormats = [
 $fallback8bitEncoding = 'iso-8859-2';
 
 $separatorTransformTable = [
-       ',' => "\xc2\xa0", // T4749
+       ',' => "\u{00A0}", // T4749
        '.' => ','
 ];
 $minimumGroupingDigits = 2;
index 78503cc..f57f322 100644 (file)
@@ -110,7 +110,7 @@ $dateFormats = [
        'dmy both' => 'H\hi\m\i\n \d\e j \d\e F \d\e Y',
 ];
 
-$separatorTransformTable = [ ',' => "\xc2\xa0", '.' => ',' ];
+$separatorTransformTable = [ ',' => "\u{00A0}", '.' => ',' ];
 $linkTrail = '/^([áâãàéêẽçíòóôõq̃úüűũa-z]+)(.*)$/sDu'; # T23168, T29633
 
 $specialPageAliases = [
index 61625e1..499e936 100644 (file)
@@ -120,7 +120,7 @@ $dateFormats = [
 
 ];
 
-$separatorTransformTable = [ ',' => "\xc2\xa0", '.' => ',' ];
+$separatorTransformTable = [ ',' => "\u{00A0}", '.' => ',' ];
 
 $specialPageAliases = [
        'Activeusers'               => [ 'Usuários_ativos' ],
index 1abecad..b513648 100644 (file)
@@ -417,7 +417,7 @@ $bookstoreList = [
 ];
 
 $separatorTransformTable = [
-       ',' => "\xc2\xa0", # nbsp
+       ',' => "\u{00A0}", # nbsp
        '.' => ','
 ];
 $minimumGroupingDigits = 2;
index aa5fdeb..81a8a14 100644 (file)
@@ -92,92 +92,92 @@ $namespaceAliases = [
 ];
 
 $specialPageAliases = [
-       'Allmessages'               => [ 'सर्वप्रणाली-संदेश' ],
-       'Allpages'                  => [ 'सर्वपृष्टानि' ],
-       'Ancientpages'              => [ 'पूर्वतनपृष्टानि' ],
-       'Blankpage'                 => [ 'रिक्तपृष्ठ' ],
-       'Block'                     => [ 'सदस्यप्रतिबन्ध' ],
-       'Booksources'               => [ 'पुस्तकस्रोत' ],
-       'BrokenRedirects'           => [ 'खण्डीतपुनर्निर्देशन' ],
-       'Categories'                => [ 'वर्गः' ],
-       'ChangePassword'            => [ 'सङ्केतशब्दपुन:प्रयुक्ता' ],
-       'Confirmemail'              => [ 'विपत्रपुष्टिकृते' ],
-       'Contributions'             => [ 'योगदानम्' ],
-       'CreateAccount'             => [ 'सृज्उपयोजकसंज्ञा' ],
-       'Deadendpages'              => [ 'निराग्रपृष्टानि' ],
-       'DeletedContributions'      => [ 'परित्यागितयोगदान' ],
-       'DoubleRedirects'           => [ 'पुनर्निर्देशनद्वंद्व' ],
-       'Emailuser'                 => [ 'विपत्रयोजक' ],
-       'ExpandTemplates'           => [ 'बिंबधरविस्तारकरोसि' ],
-       'Export'                    => [ 'निर्यात' ],
-       'Fewestrevisions'           => [ 'स्वल्पपरिवर्तन' ],
-       'FileDuplicateSearch'       => [ 'अनुकृतसंचिकाशोध' ],
-       'Filepath'                  => [ 'संचिकापथ' ],
-       'Import'                    => [ 'आयात' ],
-       'Invalidateemail'           => [ 'अमान्यविपत्र' ],
-       'BlockList'                 => [ 'प्रतिबन्धसूची' ],
-       'LinkSearch'                => [ 'सम्बन्धन्‌शोध' ],
-       'Listadmins'                => [ 'प्रचालकसूची' ],
-       'Listbots'                  => [ 'स्वयंअनुकृसूची' ],
-       'Listfiles'                 => [ 'चित्रसूची', 'संचिकासूचि' ],
-       'Listgrouprights'           => [ 'गटअधिकारसूची' ],
-       'Listredirects'             => [ 'विचालन्‌सूची' ],
-       'Listusers'                 => [ 'सदस्यासूची' ],
-       'Lockdb'                    => [ 'विदाद्वारंबन्ध्' ],
-       'Log'                       => [ 'अङ्कन' ],
-       'Lonelypages'               => [ 'अकलपृष्टानि' ],
-       'Longpages'                 => [ 'दीर्घपृष्टानि' ],
-       'MergeHistory'              => [ 'इतिहाससंयोग' ],
-       'MIMEsearch'                => [ 'विविधामाप_(माईम)_शोधसि' ],
-       'Mostcategories'            => [ 'अधिकतमवर्ग' ],
-       'Mostimages'                => [ 'अधिकतमसम्भन्दिन्_संचिका' ],
-       'Mostlinked'                => [ 'अधिकतमसम्भन्दिन्_पृष्टानि', 'अधिकतमसम्भन्दिन्' ],
-       'Mostlinkedcategories'      => [ 'अधिकतमसम्भन्दिन्_वर्ग' ],
-       'Mostlinkedtemplates'       => [ 'अधिकतमसम्भन्दिन्_फलकानि' ],
-       'Mostrevisions'             => [ 'अधिकतमपरिवर्तन' ],
-       'Movepage'                  => [ 'पृष्ठस्थानान्तर' ],
-       'Mycontributions'           => [ 'मदीययोगदानम्' ],
-       'Mypage'                    => [ 'मम_पृष्टम्' ],
-       'Mytalk'                    => [ 'मदीयसंवादम्' ],
-       'Newimages'                 => [ 'नूतनसंचिका', 'नूतनचित्रानि' ],
-       'Newpages'                  => [ 'नूतनपृष्टानि' ],
-       'PasswordReset'             => [ 'सङ्केतशब्दपुन:प्रयु्क्ता' ],
+       'Allmessages'               => [ 'सरà¥\8dवसनà¥\8dदà¥\87शाà¤\83', 'सरà¥\8dवपà¥\8dरणालà¥\80-सà¤\82दà¥\87श' ],
+       'Allpages'                  => [ 'सरà¥\8dवपà¥\83षà¥\8dठानि', 'सरà¥\8dवपà¥\83षà¥\8dà¤\9fानि' ],
+       'Ancientpages'              => [ 'पà¥\81रातनपà¥\83षà¥\8dठानि', 'पà¥\82रà¥\8dवतनपà¥\83षà¥\8dà¤\9fानि' ],
+       'Blankpage'                 => [ 'रिक्तपृष्ठानि', 'रिक्तपृष्ठ' ],
+       'Block'                     => [ 'पà¥\8dरतिबनà¥\8dधà¤\83', 'सदसà¥\8dयपà¥\8dरतिबनà¥\8dध' ],
+       'Booksources'               => [ 'पुस्तकस्रोतांसि', 'पुस्तकस्रोत' ],
+       'BrokenRedirects'           => [ 'भà¤\97à¥\8dनानि_à¤\85नà¥\81पà¥\8dरà¥\87षणानि', 'à¤\96णà¥\8dडà¥\80तपà¥\81नरà¥\8dनिरà¥\8dदà¥\87शन' ],
+       'Categories'                => [ 'वरà¥\8dà¤\97ाà¤\83', 'वरà¥\8dà¤\97à¤\83' ],
+       'ChangePassword'            => [ 'à¤\95à¥\82à¤\9fशबà¥\8dदà¤\83_परिवरà¥\8dतà¥\8dयतामà¥\8d', 'सà¤\99à¥\8dà¤\95à¥\87तशबà¥\8dदपà¥\81न:पà¥\8dरयà¥\81à¤\95à¥\8dता' ],
+       'Confirmemail'              => [ 'विपतà¥\8dरà¤\82_पà¥\81षà¥\8dà¤\9fà¥\8dयतामà¥\8d', 'विपतà¥\8dरपà¥\81षà¥\8dà¤\9fिà¤\95à¥\83तà¥\87' ],
+       'Contributions'             => [ 'यà¥\8bà¤\97दानानि', 'यà¥\8bà¤\97दानमà¥\8d' ],
+       'CreateAccount'             => [ 'लà¥\87à¤\96ा_सà¥\83à¤\9cà¥\8dयतामà¥\8d', 'सà¥\83à¤\9cà¥\8dà¤\89पयà¥\8bà¤\9cà¤\95सà¤\82à¤\9cà¥\8dà¤\9eा' ],
+       'Deadendpages'              => [ 'मà¥\83तानि_पà¥\83षà¥\8dठानि', 'निराà¤\97à¥\8dरपà¥\83षà¥\8dà¤\9fानि' ],
+       'DeletedContributions'      => [ 'à¤\85पाà¤\95à¥\83तानि_यà¥\8bà¤\97दानानि', 'परितà¥\8dयाà¤\97ितयà¥\8bà¤\97दान' ],
+       'DoubleRedirects'           => [ 'दà¥\8dवà¥\88धपà¥\81नरà¥\8dनिरà¥\8dदà¥\87शनमà¥\8d', 'पà¥\81नरà¥\8dनिरà¥\8dदà¥\87शनदà¥\8dवà¤\82दà¥\8dव' ],
+       'Emailuser'                 => [ 'विपतà¥\8dरपà¥\8dरयà¥\8bà¤\95à¥\8dता', 'विपतà¥\8dरयà¥\8bà¤\9cà¤\95' ],
+       'ExpandTemplates'           => [ 'फलà¤\95ानि_विसà¥\8dतà¥\80रà¥\8dयनà¥\8dतामà¥\8d', 'बिà¤\82बधरविसà¥\8dतारà¤\95रà¥\8bसि' ],
+       'Export'                    => [ 'निरà¥\8dयापयतà¥\81', 'निरà¥\8dयात' ],
+       'Fewestrevisions'           => [ 'सà¥\8dवलà¥\8dपतमपरिवरà¥\8dतानानि', 'सà¥\8dवलà¥\8dपपरिवरà¥\8dतन' ],
+       'FileDuplicateSearch'       => [ 'समानसà¤\9eà¥\8dà¤\9aिà¤\95ानà¥\8dवà¥\87षणमà¥\8d', 'à¤\85नà¥\81à¤\95à¥\83तसà¤\82à¤\9aिà¤\95ाशà¥\8bध' ],
+       'Filepath'                  => [ 'सà¤\9eà¥\8dà¤\9aिà¤\95ापथà¤\83', 'सà¤\82à¤\9aिà¤\95ापथ' ],
+       'Import'                    => [ 'à¤\86यापयतà¥\81', 'à¤\86यात' ],
+       'Invalidateemail'           => [ 'विपतà¥\8dरà¥\87ऽमानà¥\8dयमà¥\8d', 'à¤\85मानà¥\8dयविपतà¥\8dर' ],
+       'BlockList'                 => [ 'पà¥\8dरतिबनà¥\8dधावलिà¤\83', 'पà¥\8dरतिबनà¥\8dधसà¥\82à¤\9aà¥\80' ],
+       'LinkSearch'                => [ 'परिसनà¥\8dधà¥\87à¤\83_à¤\85नà¥\8dवà¥\87षणमà¥\8d', 'समà¥\8dबनà¥\8dधनà¥\8dâ\80\8cशà¥\8bध' ],
+       'Listadmins'                => [ 'पà¥\8dरबनà¥\8dधà¤\95ावलिà¤\83', 'पà¥\8dरà¤\9aालà¤\95सà¥\82à¤\9aà¥\80' ],
+       'Listbots'                  => [ 'बà¥\89à¤\9fसà¥\82à¤\9aà¥\80', 'सà¥\8dवयà¤\82à¤\85नà¥\81à¤\95à¥\83सà¥\82à¤\9aà¥\80' ],
+       'Listfiles'                 => [ 'सà¤\9eà¥\8dà¤\9aिà¤\95ावलिà¤\83', 'à¤\9aितà¥\8dरसà¥\82à¤\9aà¥\80', 'सà¤\82à¤\9aिà¤\95ासà¥\82à¤\9aि' ],
+       'Listgrouprights'           => [ 'समà¥\82हाधिà¤\95ारावलिà¤\83', 'à¤\97à¤\9fà¤\85धिà¤\95ारसà¥\82à¤\9aà¥\80' ],
+       'Listredirects'             => [ 'à¤\85नà¥\81पà¥\8dरà¥\87षितावलिà¤\83', 'विà¤\9aालनà¥\8dâ\80\8cसà¥\82à¤\9aà¥\80' ],
+       'Listusers'                 => [ 'सदसà¥\8dयावलिà¤\83', 'सदसà¥\8dयासà¥\82à¤\9aà¥\80' ],
+       'Lockdb'                    => [ 'दतà¥\8dताà¤\82शà¤\95à¥\80लनमà¥\8d', 'विदादà¥\8dवारà¤\82बनà¥\8dधà¥\8d' ],
+       'Log'                       => [ 'सà¤\82रà¤\95à¥\8dषितावलिà¤\83', 'à¤\85à¤\99à¥\8dà¤\95न' ],
+       'Lonelypages'               => [ 'à¤\8fà¤\95ाà¤\95िपà¥\83षà¥\8dठानि', 'à¤\85à¤\95लपà¥\83षà¥\8dà¤\9fानि' ],
+       'Longpages'                 => [ 'दà¥\80रà¥\8dà¤\98पà¥\83षà¥\8dठानि', 'दà¥\80रà¥\8dà¤\98पà¥\83षà¥\8dà¤\9fानि' ],
+       'MergeHistory'              => [ 'à¤\87तिहासविलयà¤\83', 'à¤\87तिहाससà¤\82यà¥\8bà¤\97' ],
+       'MIMEsearch'                => [ 'MIME_अन्वेषणम्', 'विविधामाप_(माईम)_शोधसि' ],
+       'Mostcategories'            => [ 'अधिकतमवर्गाः', 'अधिकतमवर्ग' ],
+       'Mostimages'                => [ 'à¤\85धिà¤\95तमसà¤\9eà¥\8dà¤\9aिà¤\95ाà¤\83', 'à¤\85धिà¤\95तमसमà¥\8dभनà¥\8dदिनà¥\8d_सà¤\82à¤\9aिà¤\95ा' ],
+       'Mostlinked'                => [ 'à¤\85धिà¤\95तमपरिसनà¥\8dधितमà¥\8d', 'à¤\85धिà¤\95तमसमà¥\8dभनà¥\8dदिनà¥\8d_पà¥\83षà¥\8dà¤\9fानि', 'à¤\85धिà¤\95तमसमà¥\8dभनà¥\8dदिनà¥\8d' ],
+       'Mostlinkedcategories'      => [ 'à¤\85धिà¤\95तमपरिसनà¥\8dधितवरà¥\8dà¤\97ाà¤\83', 'à¤\85धिà¤\95तमसमà¥\8dभनà¥\8dदिनà¥\8d_वरà¥\8dà¤\97' ],
+       'Mostlinkedtemplates'       => [ 'à¤\85धिà¤\95तमपरिसनà¥\8dधितफलà¤\95ानि', 'à¤\85धिà¤\95तमसमà¥\8dभनà¥\8dदिनà¥\8d_फलà¤\95ानि' ],
+       'Mostrevisions'             => [ 'à¤\85धिà¤\95तमसà¤\82सà¥\8dà¤\95रणानि', 'à¤\85धिà¤\95तमपरिवरà¥\8dतन' ],
+       'Movepage'                  => [ 'पृष्ठस्थानान्तरणम्', 'पृष्ठस्थानान्तर' ],
+       'Mycontributions'           => [ 'मम_यà¥\8bà¤\97दानानि', 'मदà¥\80ययà¥\8bà¤\97दानमà¥\8d' ],
+       'Mypage'                    => [ 'मम_पà¥\83षà¥\8dठमà¥\8d', 'मम_पà¥\83षà¥\8dà¤\9fमà¥\8d' ],
+       'Mytalk'                    => [ 'मम_समà¥\8dभाषणमà¥\8d', 'मदà¥\80यसà¤\82वादमà¥\8d' ],
+       'Newimages'                 => [ 'नवà¥\80नà¤\9aितà¥\8dराणि', 'नà¥\82तनसà¤\82à¤\9aिà¤\95ा', 'नà¥\82तनà¤\9aितà¥\8dरानि' ],
+       'Newpages'                  => [ 'नवà¥\80नपà¥\83षà¥\8dठानि', 'नà¥\82तनपà¥\83षà¥\8dà¤\9fानि' ],
+       'PasswordReset'             => [ 'à¤\95à¥\82à¤\9fशबà¥\8dदसà¥\8dय_पà¥\81नसà¥\8dसà¥\8dथापनमà¥\8d', 'सà¤\99à¥\8dà¤\95à¥\87तशबà¥\8dदपà¥\81न:पà¥\8dरयà¥\81à¥\8dà¤\95à¥\8dता' ],
        'Preferences'               => [ 'इष्टतमानि' ],
-       'Prefixindex'               => [ 'उपसर्गअनुक्रमणी' ],
-       'Protectedpages'            => [ 'सुरक्षितपृष्टानि' ],
-       'Protectedtitles'           => [ 'सुरक्षितशिर्षकम्' ],
-       'Randompage'                => [ 'अविशीष्टपृष्ठम्' ],
-       'RandomInCategory'          => [ 'अविशिष्टवर्ग' ],
-       'Randomredirect'            => [ 'अविशीष्टविचालन्‌' ],
-       'Recentchanges'             => [ 'नवीनतम_परिवर्तन' ],
-       'Recentchangeslinked'       => [ 'नवीनतमसम्भन्दिन_परिवर्त' ],
-       'Revisiondelete'            => [ 'आवृत्तीपरित्याग' ],
-       'Search'                    => [ 'शोध' ],
-       'Shortpages'                => [ 'लघुपृष्टानि' ],
-       'Specialpages'              => [ 'विशेषपृष्टानि' ],
-       'Statistics'                => [ 'सांख्यिकी' ],
-       'Uncategorizedcategories'   => [ 'अवर्गीकृतवर्ग' ],
-       'Uncategorizedimages'       => [ 'अवर्गीकृतसंचिका', 'अवर्गीकृतचित्रानि' ],
-       'Uncategorizedpages'        => [ 'अवर्गीकृतपृष्टानि' ],
+       'Prefixindex'               => [ 'à¤\89पसरà¥\8dà¤\97ानà¥\81à¤\95à¥\8dरमणà¥\80', 'à¤\89पसरà¥\8dà¤\97à¤\85नà¥\81à¤\95à¥\8dरमणà¥\80' ],
+       'Protectedpages'            => [ 'सà¥\81रà¤\95à¥\8dषितपà¥\83षà¥\8dठानि', 'सà¥\81रà¤\95à¥\8dषितपà¥\83षà¥\8dà¤\9fानि' ],
+       'Protectedtitles'           => [ 'सà¥\81रà¤\95à¥\8dषितशà¥\80रà¥\8dषà¤\95ाणि', 'सà¥\81रà¤\95à¥\8dषितशिरà¥\8dषà¤\95मà¥\8d' ],
+       'Randompage'                => [ 'यादà¥\83à¤\9aà¥\8dà¤\9bिà¤\95पà¥\83षà¥\8dठमà¥\8d', 'à¤\85विशà¥\80षà¥\8dà¤\9fपà¥\83षà¥\8dठमà¥\8d' ],
+       'RandomInCategory'          => [ 'वरà¥\8dà¤\97à¥\87_यादà¥\83à¤\9aà¥\8dà¤\9bिà¤\95मà¥\8d', 'à¤\85विशिषà¥\8dà¤\9fवरà¥\8dà¤\97' ],
+       'Randomredirect'            => [ 'यादà¥\83à¤\9aà¥\8dà¤\9bिà¤\95ानà¥\81पà¥\8dरà¥\87षितमà¥\8d', 'à¤\85विशà¥\80षà¥\8dà¤\9fविà¤\9aालनà¥\8dâ\80\8c' ],
+       'Recentchanges'             => [ 'नà¥\82तनपरिवरà¥\8dतनानि', 'नवà¥\80नतम_परिवरà¥\8dतन' ],
+       'Recentchangeslinked'       => [ 'नà¥\82तनपरिवरà¥\8dतनानाà¤\82_परिसनà¥\8dधयà¤\83', 'नवà¥\80नतमसमà¥\8dभनà¥\8dदिन_परिवरà¥\8dत' ],
+       'Revisiondelete'            => [ 'सà¤\82सà¥\8dà¤\95रणापाà¤\95रणमà¥\8d', 'à¤\86वà¥\83तà¥\8dतà¥\80परितà¥\8dयाà¤\97' ],
+       'Search'                    => [ 'à¤\85नà¥\8dवà¥\87षणमà¥\8d', 'शà¥\8bध' ],
+       'Shortpages'                => [ 'लà¤\98à¥\81पà¥\83षà¥\8dठानि', 'लà¤\98à¥\81पà¥\83षà¥\8dà¤\9fानि' ],
+       'Specialpages'              => [ 'विशà¥\87षपà¥\83षà¥\8dठानि', 'विशà¥\87षपà¥\83षà¥\8dà¤\9fानि' ],
+       'Statistics'                => [ 'साà¤\99à¥\8dà¤\96à¥\8dयिà¤\95à¥\80', 'साà¤\82à¤\96à¥\8dयिà¤\95à¥\80' ],
+       'Uncategorizedcategories'   => [ 'अवर्गीकृतवर्गाः', 'अवर्गीकृतवर्ग' ],
+       'Uncategorizedimages'       => [ 'à¤\85वरà¥\8dà¤\97à¥\80à¤\95à¥\83तà¤\9aितà¥\8dराणि', 'à¤\85वरà¥\8dà¤\97à¥\80à¤\95à¥\83तसà¤\82à¤\9aिà¤\95ा', 'à¤\85वरà¥\8dà¤\97à¥\80à¤\95à¥\83तà¤\9aितà¥\8dरानि' ],
+       'Uncategorizedpages'        => [ 'à¤\85वरà¥\8dà¤\97à¥\80à¤\95à¥\83तपà¥\83षà¥\8dठानि', 'à¤\85वरà¥\8dà¤\97à¥\80à¤\95à¥\83तपà¥\83षà¥\8dà¤\9fानि' ],
        'Uncategorizedtemplates'    => [ 'अवर्गीकृतफलकानि' ],
-       'Undelete'                  => [ 'प्रत्यादिश्_परित्याग' ],
-       'Unlockdb'                  => [ 'विवृतविदाद्वारंतालक' ],
-       'Unusedcategories'          => [ 'अप्रयूक्तवर्ग' ],
-       'Unusedimages'              => [ 'अप्रयूक्तसंचिका' ],
-       'Unusedtemplates'           => [ 'अप्रयूक्तबिंबधर' ],
-       'Unwatchedpages'            => [ 'अनिरिक्षीतपृष्ठ' ],
-       'Upload'                    => [ 'भारंन्यस्यति' ],
-       'Userlogin'                 => [ 'सदस्यप्रवेशन' ],
-       'Userlogout'                => [ 'सदस्यबहिर्गमन' ],
-       'Userrights'                => [ 'योजकआधिकार' ],
-       'Version'                   => [ 'आवृत्ती' ],
-       'Wantedcategories'          => [ 'प्रार्थितवर्ग' ],
-       'Wantedfiles'               => [ 'प्रार्थितसंचिका' ],
-       'Wantedpages'               => [ 'प्रार्थितपृष्टानि' ],
-       'Wantedtemplates'           => [ 'प्रार्थितफलकानि' ],
-       'Watchlist'                 => [ 'निरीक्षा_सूची' ],
-       'Whatlinkshere'             => [ 'किमपृष्ठ_सम्बद्धंकरोति' ],
-       'Withoutinterwiki'          => [ 'आन्तरविकिहीन' ],
+       'Undelete'                  => [ 'पà¥\81नसà¥\8dसà¥\8dथापनमà¥\8d', 'पà¥\8dरतà¥\8dयादिशà¥\8d_परितà¥\8dयाà¤\97' ],
+       'Unlockdb'                  => [ 'दतà¥\8dताà¤\82शà¥\8bदà¥\8dà¤\98ाà¤\9fनमà¥\8d', 'विवà¥\83तविदादà¥\8dवारà¤\82तालà¤\95' ],
+       'Unusedcategories'          => [ 'à¤\85पà¥\8dरयà¥\81à¤\95à¥\8dतवरà¥\8dà¤\97ाà¤\83', 'à¤\85पà¥\8dरयà¥\82à¤\95à¥\8dतवरà¥\8dà¤\97' ],
+       'Unusedimages'              => [ 'à¤\85पà¥\8dरयà¥\81à¤\95à¥\8dतà¤\9aितà¥\8dराणि', 'à¤\85पà¥\8dरयà¥\82à¤\95à¥\8dतसà¤\82à¤\9aिà¤\95ा' ],
+       'Unusedtemplates'           => [ 'à¤\85पà¥\8dरयà¥\81à¤\95à¥\8dतफलà¤\95ानि', 'à¤\85पà¥\8dरयà¥\82à¤\95à¥\8dतबिà¤\82बधर' ],
+       'Unwatchedpages'            => [ 'à¤\85निरà¥\80à¤\95à¥\8dषितपà¥\83षà¥\8dठानि', 'à¤\85निरिà¤\95à¥\8dषà¥\80तपà¥\83षà¥\8dठ' ],
+       'Upload'                    => [ 'à¤\89पारà¥\8bपणमà¥\8d', 'भारà¤\82नà¥\8dयसà¥\8dयति' ],
+       'Userlogin'                 => [ 'सदसà¥\8dयपà¥\8dरवà¥\87शà¤\83', 'सदसà¥\8dयपà¥\8dरवà¥\87शन' ],
+       'Userlogout'                => [ 'सदसà¥\8dयनिरà¥\8dà¤\97मनमà¥\8d', 'सदसà¥\8dयबहिरà¥\8dà¤\97मन' ],
+       'Userrights'                => [ 'सदसà¥\8dयाधिà¤\95ाराà¤\83', 'यà¥\8bà¤\9cà¤\95à¤\86धिà¤\95ार' ],
+       'Version'                   => [ 'सà¤\82सà¥\8dà¤\95रणमà¥\8d', 'à¤\86वà¥\83तà¥\8dतà¥\80' ],
+       'Wantedcategories'          => [ 'वाà¤\9eà¥\8dà¤\9bितवरà¥\8dà¤\97ाà¤\83', 'पà¥\8dरारà¥\8dथितवरà¥\8dà¤\97' ],
+       'Wantedfiles'               => [ 'वाà¤\9eà¥\8dà¤\9bितसà¤\9eà¥\8dà¤\9aिà¤\95ाà¤\83', 'पà¥\8dरारà¥\8dथितसà¤\82à¤\9aिà¤\95ा' ],
+       'Wantedpages'               => [ 'वाà¤\9eà¥\8dà¤\9bितपà¥\83षà¥\8dठानि', 'पà¥\8dरारà¥\8dथितपà¥\83षà¥\8dà¤\9fानि' ],
+       'Wantedtemplates'           => [ 'वाà¤\9eà¥\8dà¤\9bितफलà¤\95ानि', 'पà¥\8dरारà¥\8dथितफलà¤\95ानि' ],
+       'Watchlist'                 => [ 'निरीक्षा_सूची', 'निरीक्षासूचिः' ],
+       'Whatlinkshere'             => [ 'à¤\95िमतà¥\8dर_सà¤\81लà¥\8dलà¤\97à¥\8dनमà¥\8d', 'à¤\95िमपà¥\83षà¥\8dठ_समà¥\8dबदà¥\8dधà¤\82à¤\95रà¥\8bति' ],
+       'Withoutinterwiki'          => [ 'à¤\85नà¥\8dतरà¥\8dविà¤\95िपरिसनà¥\8dधिहà¥\80नमà¥\8d', 'à¤\86नà¥\8dतरविà¤\95िहà¥\80न' ],
 ];
 
 $magicWords = [
diff --git a/languages/messages/MessagesSat.php b/languages/messages/MessagesSat.php
new file mode 100644 (file)
index 0000000..4ae1d9d
--- /dev/null
@@ -0,0 +1,29 @@
+<?php
+/** Santali (sat)
+ *
+ * To improve a translation please visit https://translatewiki.net
+ *
+ * @ingroup Language
+ * @file
+ *
+ */
+
+$namespaceNames = [
+       NS_MEDIA            => 'ᱢᱤᱰᱤᱭᱟ',
+       NS_SPECIAL          => 'ᱟᱥᱚᱠᱟᱭ',
+       NS_MAIN             => 'ᱢᱩᱬᱩᱛ',
+       NS_TALK             => 'ᱜᱟᱞᱢᱟᱨᱟᱣ',
+       NS_USER             => 'ᱵᱮᱵᱷᱟᱨᱤᱭᱟᱹ',
+       NS_USER_TALK        => 'ᱵᱮᱵᱷᱟᱨᱤᱭᱟᱹ_ᱜᱟᱞᱢᱟᱨᱟᱣ',
+       NS_PROJECT_TALK     => '$1_ᱢᱤᱰᱤᱭᱟᱣᱤᱠᱤ',
+       NS_FILE             => 'ᱨᱮᱫ',
+       NS_FILE_TALK        => 'ᱨᱮᱫ_ᱜᱟᱞᱢᱟᱨᱟᱣ',
+       NS_MEDIAWIKI        => 'ᱢᱤᱰᱤᱭᱟᱣᱤᱠᱤ',
+       NS_MEDIAWIKI_TALK   => 'ᱢᱤᱰᱤᱭᱟᱣᱤᱠᱤ_ᱜᱟᱞᱢᱟᱨᱟᱣ',
+       NS_TEMPLATE         => 'ᱪᱷᱟᱸᱪ',
+       NS_TEMPLATE_TALK    => 'ᱪᱷᱟᱸᱪ_ᱜᱟᱞᱢᱟᱨᱟᱣ',
+       NS_HELP             => 'ᱜᱚᱸᱲᱚᱸ',
+       NS_HELP_TALK        => 'ᱜᱚᱸᱲᱚᱸ_ᱜᱟᱞᱢᱟᱨᱟᱣ',
+       NS_CATEGORY         => 'ᱛᱷᱚᱠ',
+       NS_CATEGORY_TALK    => 'ᱛᱷᱚᱠ_ᱜᱟᱞᱢᱟᱨᱟᱣ',
+];
index 8e1d476..4859719 100644 (file)
@@ -134,6 +134,6 @@ $magicWords = [
        'img_link'                  => [ '1', 'liŋka=$1', 'link=$1' ],
 ];
 
-$separatorTransformTable = [ ',' => "\xc2\xa0", '.' => ',' ];
+$separatorTransformTable = [ ',' => "\u{00A0}", '.' => ',' ];
 
 $linkTrail = '/^(:?[a-zàáâçčʒǯđðéèêëǧǥȟíìîïıǩŋñóòôõßšŧúùûýÿüžþæøåäö]+)(.*)$/sDu';
index 0399bfa..847a13d 100644 (file)
@@ -285,7 +285,7 @@ $namespaceGenderAliases = [
 ];
 
 $separatorTransformTable = [
-       ',' => "\xc2\xa0",
+       ',' => "\u{00A0}",
        '.' => ','
 ];
 
index d2ce357..5511dab 100644 (file)
@@ -321,7 +321,7 @@ $magicWords = [
 
 $linkTrail = '/^([a-zåäöéÅÄÖÉ]+)(.*)$/sDu';
 $separatorTransformTable = [
-       ',' => "\xc2\xa0", // T4749
+       ',' => "\u{00A0}", // T4749
        '.' => ','
 ];
 
index f089896..48a96c4 100644 (file)
@@ -80,6 +80,6 @@ $magicWords = [
        'url_wiki'                  => [ '0', 'விக்கி', 'WIKI' ],
 ];
 
-$linkTrail = "/^([\xE0\xAE\x80-\xE0\xAF\xBF]+)(.*)$/sDu";
+$linkTrail = "/^([\u{0B80}-\u{0BFF}]+)(.*)$/sDu";
 
 $digitGroupingPattern = "##,##,###";
index 4f385cf..47bc707 100644 (file)
@@ -144,6 +144,6 @@ $magicWords = [
        'special'                   => [ '0', 'ప్రత్యేక', 'special' ],
 ];
 
-$linkTrail = "/^([\xE0\xB0\x81-\xE0\xB1\xAF]+)(.*)$/sDu";
+$linkTrail = "/^([\u{0C01}-\u{0C6F}]+)(.*)$/sDu";
 
 $digitGroupingPattern = "##,##,###";
index 46d5dcb..cdfe308 100644 (file)
@@ -44,4 +44,4 @@ $namespaceGenderAliases = [];
 
 $linkTrail = '/^([a-zа-яёӝӟӥӧӵ]+)(.*)$/sDu';
 $fallback8bitEncoding = 'windows-1251';
-$separatorTransformTable = [ ',' => "\xc2\xa0", '.' => ',' ];
+$separatorTransformTable = [ ',' => "\u{00A0}", '.' => ',' ];
index 68d37c9..2b68572 100644 (file)
@@ -55,7 +55,7 @@
  */
 
 $separatorTransformTable = [
-       ',' => "\xc2\xa0", # nbsp
+       ',' => "\u{00A0}", # nbsp
        '.' => ','
 ];
 $minimumGroupingDigits = 2;
index 19ece46..dc8ad55 100644 (file)
@@ -357,7 +357,7 @@ $magicWords = [
 ];
 
 # LinkTrail for Urdu language
-$linkTrail = "/^([ابپتٹثجچحخدڈذر​ڑ​زژسشصضطظعغفقکگل​م​نوؤہھیئےآأءۃ]+)(.*)$/sDu";
+$linkTrail = "/^([ابپتٹثجچحخدڈذر​ڑ​زژسشصضطظعغفقکگل​م​نںوؤہھیئےآأءۃ]+)(.*)$/sDu";
 
 $defaultDateFormat = 'dmy';
 
index 53d8efa..1720545 100644 (file)
@@ -121,5 +121,5 @@ $dateFormats = [
  */
 $separatorTransformTable = [
        '.' => ',',
-       ',' => "\xc2\xa0", # nbsp
+       ',' => "\u{00A0}", # nbsp
 ];
index 68f3ae7..f42dd8c 100644 (file)
@@ -79,7 +79,7 @@ $specialPageAliases = [
 # definixha del cogne po les limeros
 # (number format definition)
 # en: 12,345.67 -> wa: 12 345,67
-$separatorTransformTable = [ ',' => "\xc2\xa0", '.' => ',' ];
+$separatorTransformTable = [ ',' => "\u{00A0}", '.' => ',' ];
 
 # $linkTrail = '/^([a-zåâêîôûçéèA-ZÅÂÊÎÔÛÇÉÈ]+)(.*)$/sDu';
 $linkTrail = '/^([a-zåâêîôûçéè]+)(.*)$/sDu';
diff --git a/languages/messages/MessagesZgh.php b/languages/messages/MessagesZgh.php
new file mode 100644 (file)
index 0000000..720b591
--- /dev/null
@@ -0,0 +1,11 @@
+<?php
+/** Standard Moroccan Amazigh (ⵜⴰⵎⴰⵣⵉⵖⵜ ⵜⴰⵏⴰⵡⴰⵢⵜ / tamaziɣt tanawayt)
+ *
+ * To improve a translation please visit https://translatewiki.net
+ *
+ * @ingroup Language
+ * @file
+ *
+ */
+
+$fallback = 'kab';
index 13fee9c..c4a7594 100644 (file)
@@ -202,6 +202,11 @@ abstract class Maintenance {
 
        /**
         * Do the actual work. All child classes will need to implement this
+        *
+        * @return bool|null|void True for success, false for failure. Not returning
+        *   a value, or returning null, is also interpreted as success. Returning
+        *   false for failure will cause doMaintenance.php to exit the process
+        *   with a non-zero exit status.
         */
        abstract public function execute();
 
@@ -248,7 +253,7 @@ abstract class Maintenance {
         * this will return an array.
         *
         * @param string $name The name of the param
-        * @param mixed $default Anything you want, default null
+        * @param mixed|null $default Anything you want, default null
         * @return mixed
         */
        protected function getOption( $name, $default = null ) {
@@ -304,7 +309,7 @@ abstract class Maintenance {
        /**
         * Get an argument.
         * @param int $argId The integer value (from zero) for the arg
-        * @param mixed $default The default if it doesn't exist
+        * @param mixed|null $default The default if it doesn't exist
         * @return mixed
         */
        protected function getArg( $argId = 0, $default = null ) {
@@ -354,7 +359,7 @@ abstract class Maintenance {
 
        /**
         * Return input from stdin.
-        * @param int $len The number of bytes to read. If null, just return the handle.
+        * @param int|null $len The number of bytes to read. If null, just return the handle.
         *   Maintenance::STDIN_ALL returns the full length
         * @return mixed
         */
@@ -383,7 +388,7 @@ abstract class Maintenance {
         * Throw some output to the user. Scripts can call this with no fears,
         * as we handle all --quiet stuff here
         * @param string $out The text to show to the user
-        * @param mixed $channel Unique identifier for the channel. See function outputChanneled.
+        * @param mixed|null $channel Unique identifier for the channel. See function outputChanneled.
         */
        protected function output( $out, $channel = null ) {
                // This is sometimes called very early, before Setup.php is included.
@@ -459,7 +464,7 @@ abstract class Maintenance {
         * same channel are concatenated, but any intervening messages in another
         * channel start a new line.
         * @param string $msg The message without trailing newline
-        * @param string $channel Channel identifier or null for no
+        * @param string|null $channel Channel identifier or null for no
         *     channel. Channel comparison uses ===.
         */
        public function outputChanneled( $msg, $channel = null ) {
@@ -533,6 +538,7 @@ abstract class Maintenance {
                if ( $this->getDbType() > 0 ) {
                        $this->addOption( 'dbuser', 'The DB user to use for this script', false, true );
                        $this->addOption( 'dbpass', 'The password to use for this script', false, true );
+                       $this->addOption( 'dbgroupdefault', 'The default DB group to use.', false, true );
                }
 
                # Save additional script dependant options to display
@@ -655,7 +661,7 @@ abstract class Maintenance {
         * Run a child maintenance script. Pass all of the current arguments
         * to it.
         * @param string $maintClass A name of a child maintenance class
-        * @param string $classFile Full path of where the child is
+        * @param string|null $classFile Full path of where the child is
         * @return Maintenance
         */
        public function runChild( $maintClass, $classFile = null ) {
@@ -916,9 +922,9 @@ abstract class Maintenance {
         * $mOptions becomes an array with keys set to the option names
         * $mArgs becomes a zero-based array containing the non-option arguments
         *
-        * @param string $self The name of the script, if any
-        * @param array $opts An array of options, in form of key=>value
-        * @param array $args An array of command line arguments
+        * @param string|null $self The name of the script, if any
+        * @param array|null $opts An array of options, in form of key=>value
+        * @param array|null $args An array of command line arguments
         */
        public function loadParamsAndArgs( $self = null, $opts = null, $args = null ) {
                # If we were given opts or args, set those and return early
@@ -1113,7 +1119,7 @@ abstract class Maintenance {
         */
        public function finalSetup() {
                global $wgCommandLineMode, $wgShowSQLErrors, $wgServer;
-               global $wgDBadminuser, $wgDBadminpassword;
+               global $wgDBadminuser, $wgDBadminpassword, $wgDBDefaultGroup;
                global $wgDBuser, $wgDBpassword, $wgDBservers, $wgLBFactoryConf;
 
                # Turn off output buffering again, it might have been turned on in the settings files
@@ -1135,6 +1141,11 @@ abstract class Maintenance {
                if ( $this->mDbPass ) {
                        $wgDBadminpassword = $this->mDbPass;
                }
+               if ( $this->hasOption( 'dbgroupdefault' ) ) {
+                       $wgDBDefaultGroup = $this->getOption( 'dbgroupdefault', null );
+
+                       MediaWikiServices::getInstance()->getDBLoadBalancerFactory()->destroy();
+               }
 
                if ( $this->getDbType() == self::DB_ADMIN && isset( $wgDBadminuser ) ) {
                        $wgDBuser = $wgDBadminuser;
@@ -1595,6 +1606,9 @@ abstract class Maintenance {
                if ( wfIsWindows() ) {
                        return $default;
                }
+               if ( Shell::isDisabled() ) {
+                       return $default;
+               }
                // It's possible to get the screen size with VT-100 terminal escapes,
                // but reading the responses is not possible without setting raw mode
                // (unless you want to require the user to press enter), and that
index 409afb5..9bab37c 100644 (file)
@@ -28,7 +28,7 @@ require_once __DIR__ . '/Maintenance.php';
  *
  * @since 1.28
  */
-class AddRFCAndPMIDInterwiki extends LoggedUpdateMaintenance {
+class AddRFCandPMIDInterwiki extends LoggedUpdateMaintenance {
        public function __construct() {
                parent::__construct();
                $this->addDescription( 'Add RFC and PMID to the interwiki database table' );
@@ -91,5 +91,5 @@ class AddRFCAndPMIDInterwiki extends LoggedUpdateMaintenance {
        }
 }
 
-$maintClass = AddRFCAndPMIDInterwiki::class;
+$maintClass = AddRFCandPMIDInterwiki::class;
 require_once RUN_MAINTENANCE_IF_MAIN;
index 4953343..b0ee966 100644 (file)
@@ -11,7 +11,7 @@ require_once $basePath . '/maintenance/Maintenance.php';
  *
  * @since 1.29
  *
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
  * @author Florian Schmidt
  */
 class AddSite extends Maintenance {
diff --git a/maintenance/archives/patch-archive-ar_rev_id-unique.sql b/maintenance/archives/patch-archive-ar_rev_id-unique.sql
new file mode 100644 (file)
index 0000000..0f07627
--- /dev/null
@@ -0,0 +1,4 @@
+-- T193180: ar_rev_id should be unique
+
+CREATE UNIQUE INDEX /*i*/ar_revid_uniq ON /*_*/archive (ar_rev_id);
+DROP INDEX /*i*/ar_revid ON /*_*/archive;
diff --git a/maintenance/archives/patch-interwiki-fix-pk.sql b/maintenance/archives/patch-interwiki-fix-pk.sql
new file mode 100644 (file)
index 0000000..f0e3ede
--- /dev/null
@@ -0,0 +1 @@
+ALTER TABLE /*_*/interwiki DROP KEY /*i*/iw_prefix, ADD PRIMARY KEY (iw_prefix);
diff --git a/maintenance/archives/patch-logging-drop-type-action-index.sql b/maintenance/archives/patch-logging-drop-type-action-index.sql
new file mode 100644 (file)
index 0000000..4b34bb8
--- /dev/null
@@ -0,0 +1 @@
+DROP INDEX /*i*/type_action ON /*_*/logging;
\ No newline at end of file
diff --git a/maintenance/archives/patch-logging-log-type-action-index.sql b/maintenance/archives/patch-logging-log-type-action-index.sql
new file mode 100644 (file)
index 0000000..cda55fe
--- /dev/null
@@ -0,0 +1 @@
+CREATE INDEX /*i*/log_type_action ON /*_*/logging(log_type, log_action, log_timestamp);
diff --git a/maintenance/archives/patch-logging-type-action-index.sql b/maintenance/archives/patch-logging-type-action-index.sql
deleted file mode 100644 (file)
index 5edc61a..0000000
+++ /dev/null
@@ -1 +0,0 @@
-CREATE INDEX /*i*/type_action ON /*_*/logging(log_type, log_action, log_timestamp);
diff --git a/maintenance/archives/patch-page_props-fix-pk.sql b/maintenance/archives/patch-page_props-fix-pk.sql
new file mode 100644 (file)
index 0000000..6cbf50b
--- /dev/null
@@ -0,0 +1 @@
+ALTER TABLE /*_*/page_props DROP KEY /*i*/pp_page_propname, ADD PRIMARY KEY (pp_page,pp_propname);
diff --git a/maintenance/archives/patch-protected_titles-fix-pk.sql b/maintenance/archives/patch-protected_titles-fix-pk.sql
new file mode 100644 (file)
index 0000000..fd4146d
--- /dev/null
@@ -0,0 +1 @@
+ALTER TABLE /*_*/protected_titles DROP KEY /*i*/pt_namespace_title, ADD PRIMARY KEY (pt_namespace,pt_title);
diff --git a/maintenance/archives/patch-site_identifiers-fix-pk.sql b/maintenance/archives/patch-site_identifiers-fix-pk.sql
new file mode 100644 (file)
index 0000000..05f7931
--- /dev/null
@@ -0,0 +1 @@
+ALTER TABLE /*_*/site_identifiers DROP KEY /*i*/site_ids_type, ADD PRIMARY KEY (si_type,si_key);
index 0fdd417..6eeb81b 100644 (file)
@@ -76,7 +76,7 @@ class BackupDumper extends Maintenance {
        private $stubText = false; // include rev_text_id instead of text; for 2-pass dump
 
        /**
-        * @param array $args For backward compatibility
+        * @param array|null $args For backward compatibility
         */
        function __construct( $args = null ) {
                parent::__construct();
@@ -142,7 +142,7 @@ class BackupDumper extends Maintenance {
                        require_once $file;
                }
                $register = [ $class, 'register' ];
-               call_user_func_array( $register, [ $this ] );
+               $register( $this );
        }
 
        function execute() {
index a12cda7..bf7a22d 100644 (file)
@@ -220,7 +220,7 @@ SPARQL;
        ) {
                $tables = [ 'recentchanges', 'page_props', 'category' ];
                if ( $extra_tables ) {
-                       $tables += $extra_tables;
+                       $tables = array_merge( $tables, $extra_tables );
                }
                $it = new BatchRowIterator( $dbr,
                        $tables,
index 546825b..2b47056 100644 (file)
@@ -37,7 +37,7 @@ require_once __DIR__ . '/cleanupTable.inc';
  *
  * @ingroup Maintenance
  */
-class CapsCleanup extends TableCleanup {
+class CleanupCaps extends TableCleanup {
 
        private $user;
        private $namespace;
@@ -86,7 +86,7 @@ class CapsCleanup extends TableCleanup {
                $target = Title::makeTitle( $row->page_namespace, $upper );
                if ( $target->exists() ) {
                        // Prefix "CapsCleanup" to bypass the conflict
-                       $target = Title::newFromText( __CLASS__ . '/' . $display );
+                       $target = Title::newFromText( 'CapsCleanup/' . $display );
                }
                $ok = $this->movePage(
                        $current,
@@ -169,5 +169,5 @@ class CapsCleanup extends TableCleanup {
        }
 }
 
-$maintClass = CapsCleanup::class;
+$maintClass = CleanupCaps::class;
 require_once RUN_MAINTENANCE_IF_MAIN;
index fbdc7c2..90364e2 100644 (file)
@@ -32,7 +32,7 @@ require_once __DIR__ . '/cleanupTable.inc';
  *
  * @ingroup Maintenance
  */
-class ImageCleanup extends TableCleanup {
+class CleanupImages extends TableCleanup {
        protected $defaultParams = [
                'table' => 'image',
                'conds' => [],
@@ -220,5 +220,5 @@ class ImageCleanup extends TableCleanup {
        }
 }
 
-$maintClass = ImageCleanup::class;
+$maintClass = CleanupImages::class;
 require_once RUN_MAINTENANCE_IF_MAIN;
index 54ed3aa..b933434 100644 (file)
@@ -123,15 +123,9 @@ TEXT
        protected function cleanupTable( $tableParams ) {
                $table = $tableParams[0];
                $prefix = $tableParams[1];
-               $idField = isset( $tableParams['idField'] ) ?
-                       $tableParams['idField'] :
-                       "{$prefix}_id";
-               $nsField = isset( $tableParams['nsField'] ) ?
-                       $tableParams['nsField'] :
-                       "{$prefix}_namespace";
-               $titleField = isset( $tableParams['titleField'] ) ?
-                       $tableParams['titleField'] :
-                       "{$prefix}_title";
+               $idField = $tableParams['idField'] ?? "{$prefix}_id";
+               $nsField = $tableParams['nsField'] ?? "{$prefix}_namespace";
+               $titleField = $tableParams['titleField'] ?? "{$prefix}_title";
 
                $this->outputStatus( "Looking for invalid $titleField entries in $table...\n" );
 
index 038b28c..24ca86d 100644 (file)
@@ -53,9 +53,14 @@ class CleanupSpam extends Maintenance {
                $wgUser->addGroup( 'bot' );
 
                $spec = $this->getArg();
-               $like = LinkFilter::makeLikeArray( $spec );
-               if ( !$like ) {
-                       $this->fatalError( "Not a valid hostname specification: $spec" );
+
+               $likes = [];
+               foreach ( [ 'http://', 'https://' ] as $prot ) {
+                       $like = LinkFilter::makeLikeArray( $spec, $prot );
+                       if ( !$like ) {
+                               $this->fatalError( "Not a valid hostname specification: $spec" );
+                       }
+                       $likes[$prot] = $like;
                }
 
                if ( $this->hasOption( 'all' ) ) {
@@ -63,15 +68,24 @@ class CleanupSpam extends Maintenance {
                        $this->output( "Finding spam on " . count( $wgLocalDatabases ) . " wikis\n" );
                        $found = false;
                        foreach ( $wgLocalDatabases as $wikiID ) {
+                               /** @var $dbr Database */
                                $dbr = $this->getDB( DB_REPLICA, [], $wikiID );
 
-                               $count = $dbr->selectField( 'externallinks', 'COUNT(*)',
-                                       [ 'el_index' . $dbr->buildLike( $like ) ], __METHOD__ );
-                               if ( $count ) {
-                                       $found = true;
-                                       $cmd = wfShellWikiCmd( "$IP/maintenance/cleanupSpam.php",
-                                               [ '--wiki', $wikiID, $spec ] );
-                                       passthru( "$cmd | sed 's/^/$wikiID:  /'" );
+                               foreach ( $likes as $like ) {
+                                       $count = $dbr->selectField(
+                                               'externallinks',
+                                               'COUNT(*)',
+                                               [ 'el_index' . $dbr->buildLike( $like ) ],
+                                               __METHOD__
+                                       );
+                                       if ( $count ) {
+                                               $found = true;
+                                               $cmd = wfShellWikiCmd(
+                                                       "$IP/maintenance/cleanupSpam.php",
+                                                       [ '--wiki', $wikiID, $spec ]
+                                               );
+                                               passthru( "$cmd | sed 's/^/$wikiID:  /'" );
+                                       }
                                }
                        }
                        if ( $found ) {
@@ -82,13 +96,21 @@ class CleanupSpam extends Maintenance {
                } else {
                        // Clean up spam on this wiki
 
+                       $count = 0;
+                       /** @var $dbr Database */
                        $dbr = $this->getDB( DB_REPLICA );
-                       $res = $dbr->select( 'externallinks', [ 'DISTINCT el_from' ],
-                               [ 'el_index' . $dbr->buildLike( $like ) ], __METHOD__ );
-                       $count = $dbr->numRows( $res );
-                       $this->output( "Found $count articles containing $spec\n" );
-                       foreach ( $res as $row ) {
-                               $this->cleanupArticle( $row->el_from, $spec );
+                       foreach ( $likes as $prot => $like ) {
+                               $res = $dbr->select(
+                                       'externallinks',
+                                       [ 'DISTINCT el_from' ],
+                                       [ 'el_index' . $dbr->buildLike( $like ) ],
+                                       __METHOD__
+                               );
+                               $count = $dbr->numRows( $res );
+                               $this->output( "Found $count articles containing $spec\n" );
+                               foreach ( $res as $row ) {
+                                       $this->cleanupArticle( $row->el_from, $spec, $prot );
+                               }
                        }
                        if ( $count ) {
                                $this->output( "Done\n" );
@@ -96,7 +118,13 @@ class CleanupSpam extends Maintenance {
                }
        }
 
-       private function cleanupArticle( $id, $domain ) {
+       /**
+        * @param int $id
+        * @param string $domain
+        * @param string $protocol
+        * @throws MWException
+        */
+       private function cleanupArticle( $id, $domain, $protocol ) {
                $title = Title::newFromID( $id );
                if ( !$title ) {
                        $this->error( "Internal error: no page for ID $id" );
@@ -109,7 +137,7 @@ class CleanupSpam extends Maintenance {
                $currentRevId = $rev->getId();
 
                while ( $rev && ( $rev->isDeleted( Revision::DELETED_TEXT )
-                       || LinkFilter::matchEntry( $rev->getContent( Revision::RAW ), $domain ) )
+                       || LinkFilter::matchEntry( $rev->getContent( Revision::RAW ), $domain, $protocol ) )
                ) {
                        $rev = $rev->getPrevious();
                }
index 5b441f9..234e1b1 100644 (file)
@@ -38,6 +38,7 @@ class TitleCleanup extends TableCleanup {
        public function __construct() {
                parent::__construct();
                $this->addDescription( 'Script to clean up broken, unparseable titles' );
+               $this->batchSize = 1000;
        }
 
        /**
index 61cd9c2..d255348 100644 (file)
@@ -33,7 +33,7 @@ require_once __DIR__ . '/Maintenance.php';
  *
  * @ingroup Maintenance
  */
-class UploadStashCleanup extends Maintenance {
+class CleanupUploadStash extends Maintenance {
 
        public function __construct() {
                parent::__construct();
@@ -152,5 +152,5 @@ class UploadStashCleanup extends Maintenance {
        }
 }
 
-$maintClass = UploadStashCleanup::class;
+$maintClass = CleanupUploadStash::class;
 require_once RUN_MAINTENANCE_IF_MAIN;
index 64d39dd..5e3aee7 100644 (file)
@@ -36,7 +36,7 @@ require_once __DIR__ . '/cleanupTable.inc';
  *
  * @ingroup Maintenance
  */
-class WatchlistCleanup extends TableCleanup {
+class CleanupWatchlist extends TableCleanup {
        protected $defaultParams = [
                'table' => 'watchlist',
                'index' => [ 'wl_user', 'wl_namespace', 'wl_title' ],
@@ -95,5 +95,5 @@ class WatchlistCleanup extends TableCleanup {
        }
 }
 
-$maintClass = WatchlistCleanup::class;
+$maintClass = CleanupWatchlist::class;
 require_once RUN_MAINTENANCE_IF_MAIN;
index 3c7ffba..3374893 100644 (file)
@@ -337,9 +337,7 @@ class CopyFileBackend extends Maintenance {
                $dPathSha1 = sha1( $dPath );
                if ( $this->statCache !== null ) {
                        // All dst files are already in stat cache
-                       $dstStat = isset( $this->statCache[$dPathSha1] )
-                               ? $this->statCache[$dPathSha1]
-                               : false;
+                       $dstStat = $this->statCache[$dPathSha1] ?? false;
                } else {
                        $dstStat = $dst->getFileStat( [ 'src' => $dPath ] );
                }
index d3efca6..2072d7b 100644 (file)
@@ -31,7 +31,7 @@ require_once __DIR__ . '/Maintenance.php';
  * @ingroup Maintenance
  */
 class CreateAndPromote extends Maintenance {
-       private static $permitRoles = [ 'sysop', 'bureaucrat', 'bot' ];
+       private static $permitRoles = [ 'sysop', 'bureaucrat', 'interface-admin', 'bot' ];
 
        public function __construct() {
                parent::__construct();
index ef5a30d..de611ec 100644 (file)
@@ -35,7 +35,7 @@ require_once __DIR__ . '/Maintenance.php';
  * @since 1.27
  * @ingroup Maintenance
  */
-class GenerateCommonPassword extends Maintenance {
+class CreateCommonPasswordCdb extends Maintenance {
        public function __construct() {
                global $IP;
                parent::__construct();
@@ -114,5 +114,5 @@ class GenerateCommonPassword extends Maintenance {
        }
 }
 
-$maintClass = GenerateCommonPassword::class;
+$maintClass = CreateCommonPasswordCdb::class;
 require_once RUN_MAINTENANCE_IF_MAIN;
index c1935a7..82bb928 100644 (file)
@@ -31,8 +31,7 @@ class DeleteAutoPatrolLogs extends Maintenance {
                $this->addOption( 'dry-run', 'Print debug info instead of actually deleting' );
                $this->addOption(
                        'check-old',
-                       'Check old patrol logs (for deleting old format autopatrols).' .
-                               'Note that this will not delete rows older than 2011 (MediaWiki 1.18).'
+                       'Check old patrol logs (for deleting old format autopatrols).'
                );
                $this->addOption(
                        'before',
@@ -156,17 +155,27 @@ class DeleteAutoPatrolLogs extends Maintenance {
                $autopatrols = [];
                foreach ( $result as $row ) {
                        $last = $row->log_id;
-                       Wikimedia\suppressWarnings();
-                       $params = unserialize( $row->log_params );
-                       Wikimedia\restoreWarnings();
+                       $logEntry = DatabaseLogEntry::newFromRow( $row );
+                       $params = $logEntry->getParameters();
+                       if ( !is_array( $params ) ) {
+                               continue;
+                       }
 
-                       // Skipping really old rows, before 2011
-                       if ( !is_array( $params ) || !array_key_exists( '6::auto', $params ) ) {
+                       // This logic belongs to PatrolLogFormatter::getMessageKey
+                       // and LogFormatter::extractParameters the 'auto' value is logically presented as key [5].
+                       // For legacy case the logical key is index + 3, meaning [2].
+                       // For the modern case, the logical key is index - 1 meaning [6].
+                       if ( array_key_exists( '6::auto', $params ) ) {
+                               // Between 2011-2016 autopatrol logs
+                               $auto = $params['6::auto'] === true;
+                       } elseif ( $logEntry->isLegacy() === true && array_key_exists( 2, $params ) ) {
+                               // Pre-2011 autopatrol logs
+                               $auto = $params[2] === '1';
+                       } else {
                                continue;
                        }
 
-                       $auto = $params['6::auto'];
-                       if ( $auto ) {
+                       if ( $auto === true ) {
                                $autopatrols[] = $row->log_id;
                        }
                }
index f3fb32c..1f1a4c7 100644 (file)
@@ -91,7 +91,7 @@ $maintenance->checkRequiredExtensions();
 $maintenance->setAgentAndTriggers();
 
 // Do the work
-$maintenance->execute();
+$success = $maintenance->execute();
 
 // Potentially debug globals
 $maintenance->globals();
@@ -111,3 +111,8 @@ if ( isset( $lbFactory ) ) {
        $lbFactory->commitMasterChanges( 'doMaintenance' );
        $lbFactory->shutdown( $lbFactory::SHUTDOWN_NO_CHRONPROT );
 }
+
+// Exit with an error status if execute() returned false
+if ( $success === false ) {
+       exit( 1 );
+}
index 59a6b51..95dd4da 100644 (file)
@@ -100,7 +100,7 @@ class TextPassDumper extends BackupDumper {
        protected $db;
 
        /**
-        * @param array $args For backward compatibility
+        * @param array|null $args For backward compatibility
         */
        function __construct( $args = null ) {
                parent::__construct();
index 4bfc574..b4df20f 100644 (file)
@@ -29,7 +29,7 @@ require_once __DIR__ . '/Maintenance.php';
  *
  * @ingroup Maintenance
  */
-class UploadDumper extends Maintenance {
+class DumpUploads extends Maintenance {
        public function __construct() {
                parent::__construct();
                $this->addDescription( 'Generates list of uploaded files which can be fed to tar or similar.
@@ -124,5 +124,5 @@ By default, outputs relative paths against the parent directory of $wgUploadDire
        }
 }
 
-$maintClass = UploadDumper::class;
+$maintClass = DumpUploads::class;
 require_once RUN_MAINTENANCE_IF_MAIN;
index 736b12b..4456c75 100644 (file)
@@ -9,7 +9,7 @@ require_once $basePath . '/maintenance/Maintenance.php';
  *
  * @since 1.25
  *
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
  * @author Daniel Kinzler
  */
 class ExportSites extends Maintenance {
index a60942f..a04de08 100644 (file)
@@ -29,7 +29,7 @@ require_once __DIR__ . '/Maintenance.php';
  *
  * @ingroup Maintenance
  */
-class TestFileOpPerformance extends Maintenance {
+class FileOpPerfTest extends Maintenance {
        public function __construct() {
                parent::__construct();
                $this->addDescription( 'Test fileop performance' );
@@ -141,5 +141,5 @@ class TestFileOpPerformance extends Maintenance {
        }
 }
 
-$maintClass = TestFileOpPerformance::class;
+$maintClass = FileOpPerfTest::class;
 require_once RUN_MAINTENANCE_IF_MAIN;
index ae2ee42..d4f9c2d 100644 (file)
@@ -59,7 +59,7 @@ class DeprecatedInterfaceFinder extends FileAwareNodeVisitor {
                // Sort results by version, then by filename, then by name.
                foreach ( $this->foundNodes as $version => &$nodes ) {
                        uasort( $nodes, function ( $a, $b ) {
-                               return ( $a['filename'] . $a['name'] ) < ( $b['filename'] . $b['name'] ) ? -1 : 1;
+                               return ( $a['filename'] . $a['name'] ) <=> ( $b['filename'] . $b['name'] );
                        } );
                }
                ksort( $this->foundNodes );
index dbaeb86..3d34be1 100644 (file)
@@ -28,7 +28,7 @@ require_once __DIR__ . '/Maintenance.php';
  *
  * @ingroup Maintenance
  */
-class MaintenanceFormatInstallDoc extends Maintenance {
+class FormatInstallDoc extends Maintenance {
        function __construct() {
                parent::__construct();
                $this->addArg( 'path', 'The file name to format', false );
@@ -72,5 +72,5 @@ class MaintenanceFormatInstallDoc extends Maintenance {
        }
 }
 
-$maintClass = MaintenanceFormatInstallDoc::class;
+$maintClass = FormatInstallDoc::class;
 require_once RUN_MAINTENANCE_IF_MAIN;
index 5a2c6c7..ff3e2fc 100644 (file)
@@ -177,7 +177,7 @@ class GenerateSitemap extends Maintenance {
        public function execute() {
                $this->setNamespacePriorities();
                $this->url_limit = 50000;
-               $this->size_limit = pow( 2, 20 ) * 10;
+               $this->size_limit = ( 2 ** 20 ) * 10;
 
                # Create directory if needed
                $fspath = $this->getOption( 'fspath', getcwd() );
@@ -276,9 +276,7 @@ class GenerateSitemap extends Maintenance {
         * @return string
         */
        function priority( $namespace ) {
-               return isset( $this->priorities[$namespace] )
-                       ? $this->priorities[$namespace]
-                       : $this->guessPriority( $namespace );
+               return $this->priorities[$namespace] ?? $this->guessPriority( $namespace );
        }
 
        /**
@@ -541,7 +539,7 @@ class GenerateSitemap extends Maintenance {
         */
        function generateLimit( $namespace ) {
                // T19961: make a title with the longest possible URL in this namespace
-               $title = Title::makeTitle( $namespace, str_repeat( "\xf0\xa8\xae\x81", 63 ) . "\xe5\x96\x83" );
+               $title = Title::makeTitle( $namespace, str_repeat( "\u{28B81}", 63 ) . "\u{5583}" );
 
                $this->limit = [
                        strlen( $this->openFile() ),
index c0c6284..554e373 100644 (file)
@@ -30,7 +30,7 @@ use MediaWiki\MediaWikiServices;
  *
  * @ingroup Maintenance
  */
-class GetSlaveServer extends Maintenance {
+class GetReplicaServer extends Maintenance {
        public function __construct() {
                parent::__construct();
                $this->addOption( "group", "Query group to check specifically" );
@@ -53,5 +53,5 @@ class GetSlaveServer extends Maintenance {
        }
 }
 
-$maintClass = GetSlaveServer::class;
+$maintClass = GetReplicaServer::class;
 require_once RUN_MAINTENANCE_IF_MAIN;
index be6cc05..6859eb4 100644 (file)
@@ -9,7 +9,7 @@ require_once $basePath . '/maintenance/Maintenance.php';
  *
  * @since 1.25
  *
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
  * @author Daniel Kinzler
  */
 class ImportSites extends Maintenance {
index 5f87e16..039666b 100644 (file)
@@ -56,7 +56,7 @@ wikidata|https://www.wikidata.org/wiki/$1|0|https://www.wikidata.org/w/api.php
 wikif1|http://www.wikif1.org/$1|0|
 wikihow|https://www.wikihow.com/$1|0|https://www.wikihow.com/api.php
 wikinfo|http://wikinfo.co/English/index.php/$1|0|
-wikimedia|https://wikimediafoundation.org/wiki/$1|0|https://wikimediafoundation.org/w/api.php
+wikimedia|https://foundation.wikimedia.org/wiki/$1|0|https://foundation.wikimedia.org/w/api.php
 wikinews|https://en.wikinews.org/wiki/$1|0|https://en.wikinews.org/w/api.php
 wikipedia|https://en.wikipedia.org/wiki/$1|0|https://en.wikipedia.org/w/api.php
 wikiquote|https://en.wikiquote.org/wiki/$1|0|https://en.wikiquote.org/w/api.php
index 9e6072b..68ebedf 100644 (file)
@@ -58,7 +58,7 @@ REPLACE INTO /*$wgDBprefix*/interwiki (iw_prefix,iw_url,iw_local,iw_api) VALUES
 ('wikif1','http://www.wikif1.org/$1',0,''),
 ('wikihow','https://www.wikihow.com/$1',0,'https://www.wikihow.com/api.php'),
 ('wikinfo','http://wikinfo.co/English/index.php/$1',0,''),
-('wikimedia','https://wikimediafoundation.org/wiki/$1',0,'https://wikimediafoundation.org/w/api.php'),
+('wikimedia','https://foundation.wikimedia.org/wiki/$1',0,'https://foundation.wikimedia.org/w/api.php'),
 ('wikinews','https://en.wikinews.org/wiki/$1',0,'https://en.wikinews.org/w/api.php'),
 ('wikipedia','https://en.wikipedia.org/wiki/$1',0,'https://en.wikipedia.org/w/api.php'),
 ('wikiquote','https://en.wikiquote.org/wiki/$1',0,'https://en.wikiquote.org/w/api.php'),
index 4c02998..2c7cd68 100644 (file)
                        mw.config = new mw.Map();
                }
        </script>
+       <script src="modules/src/startup/mediawiki.js"></script>
+       <script src="modules/src/startup/mediawiki.requestIdleCallback.js"></script>
        <script src="modules/lib/jquery/jquery.js"></script>
-       <script src="modules/src/mediawiki/mediawiki.js"></script>
-       <script src="modules/src/mediawiki/mediawiki.errorLogger.js"></script>
+       <script src="modules/src/mediawiki.base/mediawiki.base.js"></script>
+       <script src="modules/src/mediawiki.base/mediawiki.errorLogger.js"></script>
        <script src="modules/lib/oojs/oojs.jquery.js"></script>
        <script src="modules/lib/oojs-ui/oojs-ui-core.js"></script>
        <script src="modules/lib/oojs-ui/oojs-ui-widgets.js"></script>
index aec9252..d30a077 100644 (file)
@@ -71,7 +71,7 @@ class GenerateCollationData extends Maintenance {
                $ucdallURL = "https://www.unicode.org/Public/<Unicode version>/ucdxml/ucd.all.grouped.zip";
 
                if ( !$allkeysPresent || !$ucdallPresent ) {
-                       $icuVersion = IcuCollation::getICUVersion();
+                       $icuVersion = INTL_ICU_VERSION;
                        $unicodeVersion = IcuCollation::getUnicodeVersionForICU();
 
                        $error = "";
@@ -88,16 +88,7 @@ class GenerateCollationData extends Maintenance {
                        }
 
                        $versionKnown = false;
-                       if ( !$icuVersion ) {
-                               // Unknown version - either very old intl,
-                               // or PHP < 5.3.7 which does not expose this information
-                               $error .= "As MediaWiki could not determine the version of ICU library used by your PHP's "
-                                       . "intl extension it can't suggest which file version to download. "
-                                       . "This can be caused by running a very old version of intl or PHP < 5.3.7. "
-                                       . "If you are sure everything is all right, find out the ICU version "
-                                       . "by running phpinfo(), check what is the Unicode version it is using "
-                                       . "at http://site.icu-project.org/download, then try finding appropriate data file(s) at:";
-                       } elseif ( version_compare( $icuVersion, "4.0", "<" ) ) {
+                       if ( version_compare( $icuVersion, "4.0", "<" ) ) {
                                // Extra old version
                                $error .= "You are using outdated version of ICU ($icuVersion), intended for "
                                        . ( $unicodeVersion ? "Unicode $unicodeVersion" : "an unknown version of Unicode" )
index b8b2b8e..fad35cb 100644 (file)
@@ -28,6 +28,11 @@ require_once __DIR__ . '/../Maintenance.php';
  *
  * This data file is used after normalizing to NFC.
  *
+ * Example usage:
+ *
+ *    curl 'https://unicode.org/Public/6.0.0/ucd/UnicodeData.txt' > /tmp/UnicodeData.txt
+ *    php generateNormalizerDataAr.php --unicode-data-file /tmp/UnicodeData.txt
+ *
  * @ingroup MaintenanceLanguage
  */
 class GenerateNormalizerDataAr extends Maintenance {
@@ -35,7 +40,7 @@ class GenerateNormalizerDataAr extends Maintenance {
                parent::__construct();
                $this->addDescription( 'Generate the normalizer data file for Arabic' );
                $this->addOption( 'unicode-data-file', 'The local location of the data file ' .
-                       'from https://unicode.org/Public/UNIDATA/UnicodeData.txt', false, true );
+                       'from https://unicode.org/Public/6.0.0/ucd/UnicodeData.txt', false, true );
        }
 
        public function getDbType() {
@@ -122,7 +127,11 @@ class GenerateNormalizerDataAr extends Maintenance {
                }
 
                global $IP;
-               file_put_contents( "$IP/serialized/normalize-ar.ser", serialize( $pairs ) );
+               file_put_contents( "$IP/languages/data/normalize-ar.php", wfMakeStaticArrayFile(
+                       $pairs,
+                       'File created by generateNormalizerDataAr.php'
+               ) );
+
                echo "ar: " . count( $pairs ) . " pairs written.\n";
        }
 }
index 0bb491f..5b75d8b 100644 (file)
@@ -61,7 +61,11 @@ class GenerateNormalizerDataMl extends Maintenance {
                }
 
                global $IP;
-               file_put_contents( "$IP/serialized/normalize-ml.ser", serialize( $pairs ) );
+               file_put_contents( "$IP/languages/data/normalize-ml.php", wfMakeStaticArrayFile(
+                       $pairs,
+                       'File created by generateNormalizerDataMl.php'
+               ) );
+
                echo "ml: " . count( $pairs ) . " pairs written.\n";
        }
 }
index c8fb629..c6a5c68 100644 (file)
@@ -508,18 +508,18 @@ class Languages {
                $this->loadGeneralMessages();
                $this->loadMessages( $code );
                $wrongChars = [
-                       '[LRM]' => "\xE2\x80\x8E",
-                       '[RLM]' => "\xE2\x80\x8F",
-                       '[LRE]' => "\xE2\x80\xAA",
-                       '[RLE]' => "\xE2\x80\xAB",
-                       '[POP]' => "\xE2\x80\xAC",
-                       '[LRO]' => "\xE2\x80\xAD",
-                       '[RLO]' => "\xE2\x80\xAB",
-                       '[ZWSP]' => "\xE2\x80\x8B",
-                       '[NBSP]' => "\xC2\xA0",
-                       '[WJ]' => "\xE2\x81\xA0",
-                       '[BOM]' => "\xEF\xBB\xBF",
-                       '[FFFD]' => "\xEF\xBF\xBD",
+                       '[LRM]' => "\u{200E}",
+                       '[RLM]' => "\u{200F}",
+                       '[LRE]' => "\u{202A}",
+                       '[RLE]' => "\u{202B}",
+                       '[POP]' => "\u{202C}",
+                       '[LRO]' => "\u{202D}",
+                       '[RLO]' => "\u{202B}",
+                       '[ZWSP]' => "\u{200B}",
+                       '[NBSP]' => "\u{00A0}",
+                       '[WJ]' => "\u{2060}",
+                       '[BOM]' => "\u{FEFF}",
+                       '[FFFD]' => "\u{FFFD}",
                ];
                $wrongRegExp = '/(' . implode( '|', array_values( $wrongChars ) ) . ')/sDu';
                $wrongCharsMessages = [];
index 4098e0c..264ef5b 100644 (file)
@@ -42,7 +42,7 @@ class ListVariants extends Maintenance {
                $variants = [];
                foreach ( LanguageConverter::$languagesWithVariants as $langCode ) {
                        $lang = Language::factory( $langCode );
-                       if ( count( $lang->getVariants() ) > 1 ) {
+                       if ( $lang->hasVariants() ) {
                                $variants += array_flip( $lang->getVariants() );
                                $variantLangs[$langCode] = $lang->getVariants();
                        }
index 784ba0e..e70060e 100644 (file)
@@ -30,7 +30,7 @@ require_once __DIR__ . '/commandLine.inc';
 
 $debug = isset( $options['debug'] );
 $help = isset( $options['help'] );
-$cache = isset( $options['cache'] ) ? $options['cache'] : null;
+$cache = $options['cache'] ?? null;
 
 if ( $help ) {
        mccShowUsage();
index b26ad44..ad524a7 100644 (file)
@@ -4,8 +4,8 @@
 -- T167246. Add an `actor` table and various columns (and temporary tables) to reference it.
 
 CREATE TABLE /*_*/actor (
-  actor_id bigint unsigned NOT NULL CONSTRAINT PK_actor PRIMARY KEY IDENTITY(0,1),
-  actor_user int unsigned,
+  actor_id bigint NOT NULL CONSTRAINT PK_actor PRIMARY KEY IDENTITY(0,1),
+  actor_user int,
   actor_name nvarchar(255) NOT NULL
 );
 CREATE UNIQUE INDEX /*i*/actor_user ON /*_*/actor (actor_user);
@@ -15,10 +15,10 @@ CREATE UNIQUE INDEX /*i*/actor_name ON /*_*/actor (actor_name);
 INSERT INTO /*_*/actor (actor_name) VALUES ('##Anonymous##');
 
 CREATE TABLE /*_*/revision_actor_temp (
-  revactor_rev int unsigned NOT NULL CONSTRAINT FK_revactor_rev FOREIGN KEY REFERENCES /*_*/revision(rev_id) ON DELETE CASCADE,
-  revactor_actor bigint unsigned NOT NULL,
+  revactor_rev int NOT NULL CONSTRAINT FK_revactor_rev FOREIGN KEY REFERENCES /*_*/revision(rev_id) ON DELETE CASCADE,
+  revactor_actor bigint NOT NULL,
   revactor_timestamp varchar(14) NOT NULL CONSTRAINT DF_revactor_timestamp DEFAULT '',
-  revactor_page int unsigned NOT NULL,
+  revactor_page int NOT NULL,
   CONSTRAINT PK_revision_actor_temp PRIMARY KEY (revactor_rev, revactor_actor)
 );
 CREATE UNIQUE INDEX /*i*/revactor_rev ON /*_*/revision_actor_temp (revactor_rev);
@@ -26,28 +26,28 @@ CREATE INDEX /*i*/actor_timestamp ON /*_*/revision_actor_temp (revactor_actor,re
 CREATE INDEX /*i*/page_actor_timestamp ON /*_*/revision_actor_temp (revactor_page,revactor_actor,revactor_timestamp);
 
 ALTER TABLE /*_*/archive ADD CONSTRAINT DF_ar_user_text DEFAULT '' FOR ar_user_text;
-ALTER TABLE /*_*/archive ADD ar_actor bigint unsigned NOT NULL CONSTRAINT DF_ar_actor DEFAULT 0;
+ALTER TABLE /*_*/archive ADD ar_actor bigint NOT NULL CONSTRAINT DF_ar_actor DEFAULT 0;
 CREATE INDEX /*i*/ar_actor_timestamp ON /*_*/archive (ar_actor,ar_timestamp);
 
-ALTER TABLE /*_*/ipblocks ADD ipb_by_actor bigint unsigned NOT NULL CONSTRAINT DF_ipb_by_actor DEFAULT 0;
+ALTER TABLE /*_*/ipblocks ADD ipb_by_actor bigint NOT NULL CONSTRAINT DF_ipb_by_actor DEFAULT 0;
 
 ALTER TABLE /*_*/image ADD CONSTRAINT DF_img_user_text DEFAULT '' FOR img_user_text;
-ALTER TABLE /*_*/image ADD img_actor bigint unsigned NOT NULL CONSTRAINT DF_img_actor DEFAULT 0;
+ALTER TABLE /*_*/image ADD img_actor bigint NOT NULL CONSTRAINT DF_img_actor DEFAULT 0;
 CREATE INDEX /*i*/img_actor_timestamp ON /*_*/image (img_actor, img_timestamp);
 
 ALTER TABLE /*_*/oldimage ADD CONSTRAINT DF_oi_user_text DEFAULT '' FOR oi_user_text;
-ALTER TABLE /*_*/oldimage ADD oi_actor bigint unsigned NOT NULL CONSTRAINT DF_oi_actor DEFAULT 0;
+ALTER TABLE /*_*/oldimage ADD oi_actor bigint NOT NULL CONSTRAINT DF_oi_actor DEFAULT 0;
 CREATE INDEX /*i*/oi_actor_timestamp ON /*_*/oldimage (oi_actor,oi_timestamp);
 
 ALTER TABLE /*_*/filearchive ADD CONSTRAINT DF_fa_user_text DEFAULT '' FOR fa_user_text;
-ALTER TABLE /*_*/filearchive ADD fa_actor bigint unsigned NOT NULL CONSTRAINT DF_fa_actor DEFAULT 0;
+ALTER TABLE /*_*/filearchive ADD fa_actor bigint NOT NULL CONSTRAINT DF_fa_actor DEFAULT 0;
 CREATE INDEX /*i*/fa_actor_timestamp ON /*_*/filearchive (fa_actor,fa_timestamp);
 
 ALTER TABLE /*_*/recentchanges ADD CONSTRAINT DF_rc_user_text DEFAULT '' FOR rc_user_text;
-ALTER TABLE /*_*/recentchanges ADD rc_actor bigint unsigned NOT NULL CONSTRAINT DF_rc_actor DEFAULT 0;
+ALTER TABLE /*_*/recentchanges ADD rc_actor bigint NOT NULL CONSTRAINT DF_rc_actor DEFAULT 0;
 CREATE INDEX /*i*/rc_ns_actor ON /*_*/recentchanges (rc_namespace, rc_actor);
 CREATE INDEX /*i*/rc_actor ON /*_*/recentchanges (rc_actor, rc_timestamp);
 
-ALTER TABLE /*_*/logging ADD log_actor bigint unsigned NOT NULL CONSTRAINT DF_log_actor DEFAULT 0;
+ALTER TABLE /*_*/logging ADD log_actor bigint NOT NULL CONSTRAINT DF_log_actor DEFAULT 0;
 CREATE INDEX /*i*/actor_time ON /*_*/logging (log_actor, log_timestamp);
 CREATE INDEX /*i*/log_actor_type_time ON /*_*/logging (log_actor, log_type, log_timestamp);
index f4c2a90..c532082 100644 (file)
@@ -4,7 +4,7 @@
 -- T166732. Add a `comment` table and various columns (and temporary tables) to reference it.
 
 CREATE TABLE /*_*/comment (
-  comment_id bigint unsigned NOT NULL PRIMARY KEY IDENTITY(0,1),
+  comment_id bigint NOT NULL PRIMARY KEY IDENTITY(0,1),
   comment_hash INT NOT NULL,
   comment_text nvarchar(max) NOT NULL,
   comment_data nvarchar(max)
@@ -17,15 +17,15 @@ INSERT INTO /*_*/comment (comment_hash, comment_text) VALUES (-1, '** dummy **')
 
 CREATE TABLE /*_*/revision_comment_temp (
   revcomment_rev INT NOT NULL CONSTRAINT FK_revcomment_rev FOREIGN KEY REFERENCES /*_*/revision(rev_id) ON DELETE CASCADE,
-  revcomment_comment_id bigint unsigned NOT NULL CONSTRAINT FK_revcomment_comment_id FOREIGN KEY REFERENCES /*_*/comment(comment_id),
+  revcomment_comment_id bigint NOT NULL CONSTRAINT FK_revcomment_comment_id FOREIGN KEY REFERENCES /*_*/comment(comment_id),
   CONSTRAINT PK_revision_comment_temp PRIMARY KEY (revcomment_rev, revcomment_comment_id)
 );
 CREATE UNIQUE INDEX /*i*/revcomment_rev ON /*_*/revision_comment_temp (revcomment_rev);
 
 
 CREATE TABLE /*_*/image_comment_temp (
-  imgcomment_name nvarchar(255) NOT NULL CONSTRAINT FK_imgcomment_name FOREIGN KEY REFERENCES /*_*/image(imgcomment_name) ON DELETE CASCADE,
-  imgcomment_description_id bigint unsigned NOT NULL CONSTRAINT FK_imgcomment_description_id FOREIGN KEY REFERENCES /*_*/comment(comment_id),
+  imgcomment_name nvarchar(255) NOT NULL CONSTRAINT FK_imgcomment_name FOREIGN KEY REFERENCES /*_*/image(img_name) ON DELETE CASCADE,
+  imgcomment_description_id bigint NOT NULL CONSTRAINT FK_imgcomment_description_id FOREIGN KEY REFERENCES /*_*/comment(comment_id),
   CONSTRAINT PK_image_comment_temp PRIMARY KEY (imgcomment_name, imgcomment_description_id)
 );
 CREATE UNIQUE INDEX /*i*/imgcomment_name ON /*_*/image_comment_temp (imgcomment_name);
@@ -34,24 +34,24 @@ CREATE UNIQUE INDEX /*i*/imgcomment_name ON /*_*/image_comment_temp (imgcomment_
 ALTER TABLE /*_*/revision ADD CONSTRAINT DF_rev_comment DEFAULT '' FOR rev_comment;
 
 ALTER TABLE /*_*/archive ADD CONSTRAINT DF_ar_comment DEFAULT '' FOR ar_comment;
-ALTER TABLE /*_*/archive ADD ar_comment_id bigint unsigned NOT NULL CONSTRAINT DF_ar_comment_id DEFAULT 0 CONSTRAINT FK_ar_comment_id FOREIGN KEY REFERENCES /*_*/comment(comment_id);
+ALTER TABLE /*_*/archive ADD ar_comment_id bigint NOT NULL CONSTRAINT DF_ar_comment_id DEFAULT 0 CONSTRAINT FK_ar_comment_id FOREIGN KEY REFERENCES /*_*/comment(comment_id);
 
 ALTER TABLE /*_*/ipblocks ADD CONSTRAINT DF_ipb_reason DEFAULT '' FOR ipb_reason;
-ALTER TABLE /*_*/ipblocks ADD ipb_reason_id bigint unsigned NOT NULL CONSTRAINT DF_ipb_reason_id DEFAULT 0 CONSTRAINT FK_ipb_reason_id FOREIGN KEY REFERENCES /*_*/comment(comment_id);
+ALTER TABLE /*_*/ipblocks ADD ipb_reason_id bigint NOT NULL CONSTRAINT DF_ipb_reason_id DEFAULT 0 CONSTRAINT FK_ipb_reason_id FOREIGN KEY REFERENCES /*_*/comment(comment_id);
 
 ALTER TABLE /*_*/image ADD CONSTRAINT DF_img_description DEFAULT '' FOR img_description;
 
 ALTER TABLE /*_*/oldimage ADD CONSTRAINT DF_oi_description DEFAULT '' FOR oi_description;
-ALTER TABLE /*_*/oldimage ADD oi_description_id bigint unsigned NOT NULL CONSTRAINT DF_oi_description_id DEFAULT 0 CONSTRAINT FK_oi_description_id FOREIGN KEY REFERENCES /*_*/comment(comment_id);
+ALTER TABLE /*_*/oldimage ADD oi_description_id bigint NOT NULL CONSTRAINT DF_oi_description_id DEFAULT 0 CONSTRAINT FK_oi_description_id FOREIGN KEY REFERENCES /*_*/comment(comment_id);
 
 ALTER TABLE /*_*/filearchive ADD CONSTRAINT DF_fa_deleted_reason DEFAULT '' FOR fa_deleted_reason;
-ALTER TABLE /*_*/filearchive ADD fa_deleted_reason_id bigint unsigned NOT NULL CONSTRAINT DF_fa_deleted_reason_id DEFAULT 0 CONSTRAINT FK_fa_deleted_reason_id FOREIGN KEY REFERENCES /*_*/comment(comment_id);
+ALTER TABLE /*_*/filearchive ADD fa_deleted_reason_id bigint NOT NULL CONSTRAINT DF_fa_deleted_reason_id DEFAULT 0 CONSTRAINT FK_fa_deleted_reason_id FOREIGN KEY REFERENCES /*_*/comment(comment_id);
 ALTER TABLE /*_*/filearchive ADD CONSTRAINT DF_fa_description DEFAULT '' FOR fa_description;
-ALTER TABLE /*_*/filearchive ADD fa_description_id bigint unsigned NOT NULL CONSTRAINT DF_fa_description_id DEFAULT 0 CONSTRAINT FK_fa_description_id FOREIGN KEY REFERENCES /*_*/comment(comment_id);
+ALTER TABLE /*_*/filearchive ADD fa_description_id bigint NOT NULL CONSTRAINT DF_fa_description_id DEFAULT 0 CONSTRAINT FK_fa_description_id FOREIGN KEY REFERENCES /*_*/comment(comment_id);
 
-ALTER TABLE /*_*/recentchanges ADD rc_comment_id bigint unsigned NOT NULL CONSTRAINT DF_rc_comment_id DEFAULT 0 CONSTRAINT FK_rc_comment_id FOREIGN KEY REFERENCES /*_*/comment(comment_id);
+ALTER TABLE /*_*/recentchanges ADD rc_comment_id bigint NOT NULL CONSTRAINT DF_rc_comment_id DEFAULT 0 CONSTRAINT FK_rc_comment_id FOREIGN KEY REFERENCES /*_*/comment(comment_id);
 
-ALTER TABLE /*_*/logging ADD log_comment_id bigint unsigned NOT NULL CONSTRAINT DF_log_comment_id DEFAULT 0 CONSTRAINT FK_log_comment_id FOREIGN KEY REFERENCES /*_*/comment(comment_id);
+ALTER TABLE /*_*/logging ADD log_comment_id bigint NOT NULL CONSTRAINT DF_log_comment_id DEFAULT 0 CONSTRAINT FK_log_comment_id FOREIGN KEY REFERENCES /*_*/comment(comment_id);
 
 ALTER TABLE /*_*/protected_titles ADD CONSTRAINT DF_pt_reason DEFAULT '' FOR pt_reason;
-ALTER TABLE /*_*/protected_titles ADD pt_reason_id bigint unsigned NOT NULL CONSTRAINT DF_pt_reason_id DEFAULT 0 CONSTRAINT FK_pt_reason_id FOREIGN KEY REFERENCES /*_*/comment(comment_id);
+ALTER TABLE /*_*/protected_titles ADD pt_reason_id bigint NOT NULL CONSTRAINT DF_pt_reason_id DEFAULT 0 CONSTRAINT FK_pt_reason_id FOREIGN KEY REFERENCES /*_*/comment(comment_id);
index c5b079a..a899f27 100644 (file)
@@ -5,17 +5,17 @@
 CREATE TABLE /*_*/content (
 
   -- ID of the content object
-  content_id bigint unsigned NOT NULL CONSTRAINT PK_content PRIMARY KEY IDENTITY,
+  content_id bigint NOT NULL CONSTRAINT PK_content PRIMARY KEY IDENTITY,
 
   -- Nominal size of the content object (not necessarily of the serialized blob)
-  content_size int unsigned NOT NULL,
+  content_size int NOT NULL,
 
   -- Nominal hash of the content object (not necessarily of the serialized blob)
   content_sha1 varchar(32) NOT NULL,
 
   -- reference to model_id
-  content_model smallint unsigned NOT NULL CONSTRAINT FK_content_content_models FOREIGN KEY REFERENCES /*_*/content_models(model_id),
+  content_model smallint NOT NULL CONSTRAINT FK_content_content_models FOREIGN KEY REFERENCES /*_*/content_models(model_id),
 
   -- URL-like address of the content blob
   content_address nvarchar(255) NOT NULL
-);
\ No newline at end of file
+);
diff --git a/maintenance/mssql/archives/patch-interwiki-pk.sql b/maintenance/mssql/archives/patch-interwiki-pk.sql
new file mode 100644 (file)
index 0000000..e989c44
--- /dev/null
@@ -0,0 +1,2 @@
+DROP INDEX IF EXISTS /*i*/iw_prefix ON /*_*/interwiki;
+ALTER TABLE /*_*/interwiki ADD CONSTRAINT PK_interwiki PRIMARY KEY(iw_prefix);
\ No newline at end of file
diff --git a/maintenance/mssql/archives/patch-page_props-pk.sql b/maintenance/mssql/archives/patch-page_props-pk.sql
new file mode 100644 (file)
index 0000000..0615440
--- /dev/null
@@ -0,0 +1,2 @@
+DROP INDEX IF EXISTS /*i*/pp_page_propname ON /*_*/page_props;
+ALTER TABLE /*_*/page_props ADD CONSTRAINT PK_page_props PRIMARY KEY(pp_page,pp_propname);
\ No newline at end of file
diff --git a/maintenance/mssql/archives/patch-protected_titles-pk.sql b/maintenance/mssql/archives/patch-protected_titles-pk.sql
new file mode 100644 (file)
index 0000000..17e059e
--- /dev/null
@@ -0,0 +1,2 @@
+DROP INDEX IF EXISTS /*i*/pt_namespace_title ON /*_*/protected_titles;
+ALTER TABLE /*_*/protected_titles ADD CONSTRAINT PK_protected_titles PRIMARY KEY(pt_namespace,pt_title);
\ No newline at end of file
diff --git a/maintenance/mssql/archives/patch-site_identifiers-pk.sql b/maintenance/mssql/archives/patch-site_identifiers-pk.sql
new file mode 100644 (file)
index 0000000..fa12f70
--- /dev/null
@@ -0,0 +1,2 @@
+DROP INDEX IF EXISTS /*i*/site_ids_type ON /*_*/site_identifiers;
+ALTER TABLE /*_*/site_identifiers ADD CONSTRAINT PK_site_identifiers PRIMARY KEY(si_type, si_key);
\ No newline at end of file
index e9ec7c3..2fc615e 100644 (file)
@@ -6,17 +6,17 @@
 CREATE TABLE /*_*/slots (
 
   -- reference to rev_id
-  slot_revision_id bigint unsigned NOT NULL,
+  slot_revision_id bigint NOT NULL,
 
   -- reference to role_id
-  slot_role_id smallint unsigned NOT NULL CONSTRAINT FK_slots_slot_role FOREIGN KEY REFERENCES slot_roles(role_id),
+  slot_role_id smallint NOT NULL CONSTRAINT FK_slots_slot_role FOREIGN KEY REFERENCES slot_roles(role_id),
 
   -- reference to content_id
-  slot_content_id bigint unsigned NOT NULL CONSTRAINT FK_slots_content_id FOREIGN KEY REFERENCES content(content_id),
+  slot_content_id bigint NOT NULL CONSTRAINT FK_slots_content_id FOREIGN KEY REFERENCES content(content_id),
 
   -- The revision ID of the revision that originated the slot's content.
   -- To find revisions that changed slots, look for slot_origin = slot_revision_id.
-  slot_origin bigint unsigned NOT NULL,
+  slot_origin bigint NOT NULL,
 
   CONSTRAINT PK_slots PRIMARY KEY (slot_revision_id, slot_role_id)
 );
index fbe207d..f040c15 100644 (file)
@@ -61,8 +61,8 @@ INSERT INTO /*_*/mwuser (user_name) VALUES ('##Anonymous##');
 -- can refer to the user table directly.
 --
 CREATE TABLE /*_*/actor (
-  actor_id bigint unsigned NOT NULL CONSTRAINT PK_actor PRIMARY KEY IDENTITY(0,1),
-  actor_user int unsigned,
+  actor_id bigint NOT NULL CONSTRAINT PK_actor PRIMARY KEY IDENTITY(0,1),
+  actor_user int,
   actor_name nvarchar(255) NOT NULL
 );
 CREATE UNIQUE INDEX /*i*/actor_user ON /*_*/actor (actor_user);
@@ -144,7 +144,7 @@ CREATE TABLE /*_*/bot_passwords (
 -- the same comment_text and comment_data.
 --
 CREATE TABLE /*_*/comment (
-  comment_id bigint unsigned NOT NULL PRIMARY KEY IDENTITY(0,1),
+  comment_id bigint NOT NULL PRIMARY KEY IDENTITY(0,1),
   comment_hash INT NOT NULL,
   comment_text nvarchar(max) NOT NULL,
   comment_data nvarchar(max)
@@ -225,16 +225,16 @@ ALTER TABLE /*_*/page ADD CONSTRAINT FK_page_latest_page_id FOREIGN KEY (page_la
 --
 CREATE TABLE /*_*/revision_comment_temp (
   revcomment_rev INT NOT NULL CONSTRAINT FK_revcomment_rev FOREIGN KEY REFERENCES /*_*/revision(rev_id) ON DELETE CASCADE,
-  revcomment_comment_id bigint unsigned NOT NULL CONSTRAINT FK_revcomment_comment_id FOREIGN KEY REFERENCES /*_*/comment(comment_id),
+  revcomment_comment_id bigint NOT NULL CONSTRAINT FK_revcomment_comment_id FOREIGN KEY REFERENCES /*_*/comment(comment_id),
   CONSTRAINT PK_revision_comment_temp PRIMARY KEY (revcomment_rev, revcomment_comment_id)
 );
 CREATE UNIQUE INDEX /*i*/revcomment_rev ON /*_*/revision_comment_temp (revcomment_rev);
 
 CREATE TABLE /*_*/revision_actor_temp (
-  revactor_rev int unsigned NOT NULL CONSTRAINT FK_revactor_rev FOREIGN KEY REFERENCES /*_*/revision(rev_id) ON DELETE CASCADE,
-  revactor_actor bigint unsigned NOT NULL,
+  revactor_rev int NOT NULL CONSTRAINT FK_revactor_rev FOREIGN KEY REFERENCES /*_*/revision(rev_id) ON DELETE CASCADE,
+  revactor_actor bigint NOT NULL,
   revactor_timestamp varchar(14) NOT NULL CONSTRAINT DF_revactor_timestamp DEFAULT '',
-  revactor_page int unsigned NOT NULL,
+  revactor_page int NOT NULL,
   CONSTRAINT PK_revision_actor_temp PRIMARY KEY (revactor_rev, revactor_actor)
 );
 CREATE UNIQUE INDEX /*i*/revactor_rev ON /*_*/revision_actor_temp (revactor_rev);
@@ -271,10 +271,10 @@ CREATE TABLE /*_*/archive (
    ar_namespace SMALLINT NOT NULL DEFAULT 0,
    ar_title NVARCHAR(255) NOT NULL DEFAULT '',
    ar_comment NVARCHAR(255) NOT NULL CONSTRAINT DF_ar_comment DEFAULT '',
-   ar_comment_id bigint unsigned NOT NULL CONSTRAINT DF_ar_comment_id DEFAULT 0 CONSTRAINT FK_ar_comment_id FOREIGN KEY REFERENCES /*_*/comment(comment_id),
+   ar_comment_id bigint NOT NULL CONSTRAINT DF_ar_comment_id DEFAULT 0 CONSTRAINT FK_ar_comment_id FOREIGN KEY REFERENCES /*_*/comment(comment_id),
    ar_user INT CONSTRAINT ar_user__user_id__fk FOREIGN KEY REFERENCES /*_*/mwuser(user_id),
    ar_user_text NVARCHAR(255) NOT NULL CONSTRAINT DF_ar_user_text DEFAULT '',
-   ar_actor bigint unsigned NOT NULL CONSTRAINT DF_ar_actor DEFAULT 0,
+   ar_actor bigint NOT NULL CONSTRAINT DF_ar_actor DEFAULT 0,
    ar_timestamp varchar(14) NOT NULL default '',
    ar_minor_edit BIT NOT NULL DEFAULT 0,
    ar_rev_id INT NOT NULL, -- NOT a FK, the row gets deleted from revision and moved here
@@ -290,34 +290,30 @@ CREATE TABLE /*_*/archive (
 CREATE INDEX /*i*/name_title_timestamp ON /*_*/archive (ar_namespace,ar_title,ar_timestamp);
 CREATE INDEX /*i*/ar_usertext_timestamp ON /*_*/archive (ar_user_text,ar_timestamp);
 CREATE INDEX /*i*/ar_actor_timestamp ON /*_*/archive (ar_actor,ar_timestamp);
-CREATE INDEX /*i*/ar_revid ON /*_*/archive (ar_rev_id);
+CREATE UNIQUE INDEX /*i*/ar_revid_uniq ON /*_*/archive (ar_rev_id);
 
 
 --
--- Slots represent an n:m relation between revisions and content objects.
--- A content object can have a specific "role" in one or more revisions.
--- Each revision can have multiple content objects, each having a different role.
+-- Normalization table for role names
 --
-CREATE TABLE /*_*/slots (
-
-  -- reference to rev_id
-  slot_revision_id bigint unsigned NOT NULL,
-
-  -- reference to role_id
-  slot_role_id smallint unsigned NOT NULL CONSTRAINT FK_slots_slot_role FOREIGN KEY REFERENCES slot_roles(role_id),
-
-  -- reference to content_id
-  slot_content_id bigint unsigned NOT NULL CONSTRAINT FK_slots_content_id FOREIGN KEY REFERENCES content(content_id),
+CREATE TABLE /*_*/slot_roles (
+  role_id smallint NOT NULL CONSTRAINT PK_slot_roles PRIMARY KEY IDENTITY,
+  role_name nvarchar(64) NOT NULL
+);
 
-  -- The revision ID of the revision that originated the slot's content.
-  -- To find revisions that changed slots, look for slot_origin = slot_revision_id.
-  slot_origin bigint NOT NULL,
+-- Index for looking of the internal ID of for a name
+CREATE UNIQUE INDEX /*i*/role_name ON /*_*/slot_roles (role_name);
 
-  CONSTRAINT PK_slots PRIMARY KEY (slot_revision_id, slot_role_id)
+--
+-- Normalization table for content model names
+--
+CREATE TABLE /*_*/content_models (
+  model_id smallint NOT NULL CONSTRAINT PK_content_models PRIMARY KEY IDENTITY,
+  model_name nvarchar(64) NOT NULL
 );
 
--- Index for finding revisions that modified a specific slot
-CREATE INDEX /*i*/slot_revision_origin_role ON /*_*/slots (slot_revision_id, slot_origin, slot_role_id);
+-- Index for looking of the internal ID of for a name
+CREATE UNIQUE INDEX /*i*/model_name ON /*_*/content_models (model_name);
 
 --
 -- The content table represents content objects. It's primary purpose is to provide the necessary
@@ -326,42 +322,46 @@ CREATE INDEX /*i*/slot_revision_origin_role ON /*_*/slots (slot_revision_id, slo
 CREATE TABLE /*_*/content (
 
   -- ID of the content object
-  content_id bigint unsigned NOT NULL CONSTRAINT PK_content PRIMARY KEY IDENTITY,
+  content_id bigint NOT NULL CONSTRAINT PK_content PRIMARY KEY IDENTITY,
 
   -- Nominal size of the content object (not necessarily of the serialized blob)
-  content_size int unsigned NOT NULL,
+  content_size int NOT NULL,
 
   -- Nominal hash of the content object (not necessarily of the serialized blob)
   content_sha1 varchar(32) NOT NULL,
 
   -- reference to model_id
-  content_model smallint unsigned NOT NULL CONSTRAINT FK_content_content_models FOREIGN KEY REFERENCES /*_*/content_models(model_id),
+  content_model smallint NOT NULL CONSTRAINT FK_content_content_models FOREIGN KEY REFERENCES /*_*/content_models(model_id),
 
   -- URL-like address of the content blob
   content_address nvarchar(255) NOT NULL
 );
 
 --
--- Normalization table for role names
+-- Slots represent an n:m relation between revisions and content objects.
+-- A content object can have a specific "role" in one or more revisions.
+-- Each revision can have multiple content objects, each having a different role.
 --
-CREATE TABLE /*_*/slot_roles (
-  role_id smallint NOT NULL CONSTRAINT PK_slot_roles PRIMARY KEY IDENTITY,
-  role_name nvarchar(64) NOT NULL
-);
+CREATE TABLE /*_*/slots (
 
--- Index for looking of the internal ID of for a name
-CREATE UNIQUE INDEX /*i*/role_name ON /*_*/slot_roles (role_name);
+  -- reference to rev_id
+  slot_revision_id bigint NOT NULL,
 
---
--- Normalization table for content model names
---
-CREATE TABLE /*_*/content_models (
-  model_id smallint NOT NULL CONSTRAINT PK_content_models PRIMARY KEY IDENTITY,
-  model_name nvarchar(64) NOT NULL
+  -- reference to role_id
+  slot_role_id smallint NOT NULL CONSTRAINT FK_slots_slot_role FOREIGN KEY REFERENCES slot_roles(role_id),
+
+  -- reference to content_id
+  slot_content_id bigint NOT NULL CONSTRAINT FK_slots_content_id FOREIGN KEY REFERENCES content(content_id),
+
+  -- The revision ID of the revision that originated the slot's content.
+  -- To find revisions that changed slots, look for slot_origin = slot_revision_id.
+  slot_origin bigint NOT NULL,
+
+  CONSTRAINT PK_slots PRIMARY KEY (slot_revision_id, slot_role_id)
 );
 
--- Index for looking of the internal ID of for a name
-CREATE UNIQUE INDEX /*i*/model_name ON /*_*/content_models (model_name);
+-- Index for finding revisions that modified a specific slot
+CREATE INDEX /*i*/slot_revision_origin_role ON /*_*/slots (slot_revision_id, slot_origin, slot_role_id);
 
 
 --
@@ -643,7 +643,7 @@ CREATE TABLE /*_*/ipblocks (
   ipb_by int REFERENCES /*_*/mwuser(user_id) ON DELETE CASCADE,
 
   -- Actor ID who made the block.
-  ipb_by_actor bigint unsigned NOT NULL CONSTRAINT DF_ipb_by_actor DEFAULT 0,
+  ipb_by_actor bigint NOT NULL CONSTRAINT DF_ipb_by_actor DEFAULT 0,
 
   -- User name of blocker
   ipb_by_text nvarchar(255) NOT NULL default '',
@@ -653,7 +653,7 @@ CREATE TABLE /*_*/ipblocks (
 
   -- Key to comment_id. Text comment made by blocker.
   -- ("DEFAULT 0" is temporary, signaling that ipb_reason should be used)
-  ipb_reason_id bigint unsigned NOT NULL CONSTRAINT DF_ipb_reason_id DEFAULT 0 CONSTRAINT FK_ipb_reason_id FOREIGN KEY REFERENCES /*_*/comment(comment_id),
+  ipb_reason_id bigint NOT NULL CONSTRAINT DF_ipb_reason_id DEFAULT 0 CONSTRAINT FK_ipb_reason_id FOREIGN KEY REFERENCES /*_*/comment(comment_id),
 
   -- Creation (or refresh) date in standard YMDHMS form.
   -- IP blocks expire automatically.
@@ -756,7 +756,7 @@ CREATE TABLE /*_*/image (
   -- user_id and user_name of uploader.
   img_user int REFERENCES /*_*/mwuser(user_id) ON DELETE SET NULL,
   img_user_text nvarchar(255) NOT NULL CONSTRAINT DF_img_user_text DEFAULT '',
-  img_actor bigint unsigned NOT NULL CONSTRAINT DF_img_actor DEFAULT 0,
+  img_actor bigint NOT NULL CONSTRAINT DF_img_actor DEFAULT 0,
 
   -- Time of the upload.
   img_timestamp nvarchar(14) NOT NULL default '',
@@ -787,8 +787,8 @@ CREATE INDEX /*i*/img_media_mime ON /*_*/image (img_media_type,img_major_mime,im
 -- will be merged back into image in the future.
 --
 CREATE TABLE /*_*/image_comment_temp (
-  imgcomment_name nvarchar(255) NOT NULL CONSTRAINT FK_imgcomment_name FOREIGN KEY REFERENCES /*_*/image(imgcomment_name) ON DELETE CASCADE,
-  imgcomment_description_id bigint unsigned NOT NULL CONSTRAINT FK_imgcomment_description_id FOREIGN KEY REFERENCES /*_*/comment(comment_id),
+  imgcomment_name nvarchar(255) NOT NULL CONSTRAINT FK_imgcomment_name FOREIGN KEY REFERENCES /*_*/image(img_name) ON DELETE CASCADE,
+  imgcomment_description_id bigint NOT NULL CONSTRAINT FK_imgcomment_description_id FOREIGN KEY REFERENCES /*_*/comment(comment_id),
   CONSTRAINT PK_image_comment_temp PRIMARY KEY (imgcomment_name, imgcomment_description_id)
 );
 CREATE UNIQUE INDEX /*i*/imgcomment_name ON /*_*/image_comment_temp (imgcomment_name);
@@ -814,10 +814,10 @@ CREATE TABLE /*_*/oldimage (
   oi_height int NOT NULL default 0,
   oi_bits int NOT NULL default 0,
   oi_description nvarchar(255) NOT NULL CONSTRAINT DF_oi_description DEFAULT '',
-  oi_description_id bigint unsigned NOT NULL CONSTRAINT DF_oi_description_id DEFAULT 0 CONSTRAINT FK_oi_description_id FOREIGN KEY REFERENCES /*_*/comment(comment_id),
+  oi_description_id bigint NOT NULL CONSTRAINT DF_oi_description_id DEFAULT 0 CONSTRAINT FK_oi_description_id FOREIGN KEY REFERENCES /*_*/comment(comment_id),
   oi_user int REFERENCES /*_*/mwuser(user_id),
   oi_user_text nvarchar(255) NOT NULL CONSTRAINT DF_oi_user_text DEFAULT '',
-  oi_actor bigint unsigned NOT NULL CONSTRAINT DF_oi_actor DEFAULT 0,
+  oi_actor bigint NOT NULL CONSTRAINT DF_oi_actor DEFAULT 0,
   oi_timestamp varchar(14) NOT NULL default '',
 
   oi_metadata varbinary(max) NOT NULL,
@@ -866,7 +866,7 @@ CREATE TABLE /*_*/filearchive (
   fa_deleted_user int,
   fa_deleted_timestamp varchar(14) default '',
   fa_deleted_reason nvarchar(max) CONSTRAINT DF_fa_deleted_reason DEFAULT '',
-  fa_deleted_reason_id bigint unsigned NOT NULL CONSTRAINT DF_fa_deleted_reason_id DEFAULT 0 CONSTRAINT FK_fa_deleted_reason_id FOREIGN KEY REFERENCES /*_*/comment(comment_id),
+  fa_deleted_reason_id bigint NOT NULL CONSTRAINT DF_fa_deleted_reason_id DEFAULT 0 CONSTRAINT FK_fa_deleted_reason_id FOREIGN KEY REFERENCES /*_*/comment(comment_id),
 
   -- Duped fields from image
   fa_size int default 0,
@@ -878,10 +878,10 @@ CREATE TABLE /*_*/filearchive (
   fa_major_mime varchar(16) not null default 'unknown',
   fa_minor_mime nvarchar(100) default 'unknown',
   fa_description nvarchar(255) CONSTRAINT DF_fa_description DEFAULT '',
-  fa_description_id bigint unsigned NOT NULL CONSTRAINT DF_fa_description DEFAULT 0 CONSTRAINT FK_fa_description FOREIGN KEY REFERENCES /*_*/comment(comment_id),
+  fa_description_id bigint NOT NULL CONSTRAINT DF_fa_description_id DEFAULT 0 CONSTRAINT FK_fa_description_id FOREIGN KEY REFERENCES /*_*/comment(comment_id),
   fa_user int default 0 REFERENCES /*_*/mwuser(user_id) ON DELETE SET NULL,
   fa_user_text nvarchar(255) CONSTRAINT DF_fa_user_text DEFAULT '',
-  fa_actor bigint unsigned NOT NULL CONSTRAINT DF_fa_actor DEFAULT 0,
+  fa_actor bigint NOT NULL CONSTRAINT DF_fa_actor DEFAULT 0,
   fa_timestamp varchar(14) default '',
 
   -- Visibility of deleted revisions, bitfield
@@ -976,7 +976,7 @@ CREATE TABLE /*_*/recentchanges (
   -- As in revision
   rc_user int NOT NULL default 0 CONSTRAINT rc_user__user_id__fk FOREIGN KEY REFERENCES /*_*/mwuser(user_id),
   rc_user_text nvarchar(255) NOT NULL CONSTRAINT DF_rc_user_text DEFAULT '',
-  rc_actor bigint unsigned NOT NULL CONSTRAINT DF_rc_actor DEFAULT 0,
+  rc_actor bigint NOT NULL CONSTRAINT DF_rc_actor DEFAULT 0,
 
   -- When pages are renamed, their RC entries do _not_ change.
   rc_namespace int NOT NULL default 0,
@@ -984,7 +984,7 @@ CREATE TABLE /*_*/recentchanges (
 
   -- as in revision...
   rc_comment nvarchar(255) NOT NULL default '',
-  rc_comment_id bigint unsigned NOT NULL CONSTRAINT DF_rc_comment_id DEFAULT 0 CONSTRAINT FK_rc_comment_id FOREIGN KEY REFERENCES /*_*/comment(comment_id),
+  rc_comment_id bigint NOT NULL CONSTRAINT DF_rc_comment_id DEFAULT 0 CONSTRAINT FK_rc_comment_id FOREIGN KEY REFERENCES /*_*/comment(comment_id),
   rc_minor bit NOT NULL default 0,
 
   -- Edits by user accounts with the 'bot' rights key are
@@ -1098,7 +1098,7 @@ CREATE UNIQUE INDEX /*i*/si_page ON /*_*/searchindex (si_page);
 --
 CREATE TABLE /*_*/interwiki (
   -- The interwiki prefix, (e.g. "Meatball", or the language prefix "de")
-  iw_prefix nvarchar(32) NOT NULL,
+  iw_prefix nvarchar(32) NOT NULL CONSTRAINT PK_interwiki PRIMARY KEY,
 
   -- The URL of the wiki, with "$1" as a placeholder for an article name.
   -- Any spaces in the name will be transformed to underscores before
@@ -1119,9 +1119,6 @@ CREATE TABLE /*_*/interwiki (
   iw_trans bit NOT NULL default 0
 );
 
-CREATE UNIQUE INDEX /*i*/iw_prefix ON /*_*/interwiki (iw_prefix);
-
-
 --
 -- Used for caching expensive grouped queries
 --
@@ -1183,7 +1180,7 @@ CREATE TABLE /*_*/logging (
   log_user_text nvarchar(255) NOT NULL default '',
 
   -- The actor who performed this action
-  log_actor bigint unsigned NOT NULL CONSTRAINT DF_log_actor DEFAULT 0,
+  log_actor bigint NOT NULL CONSTRAINT DF_log_actor DEFAULT 0,
 
   -- Key to the page affected. Where a user is the target,
   -- this will point to the user page.
@@ -1196,7 +1193,7 @@ CREATE TABLE /*_*/logging (
 
   -- Key to comment_id. Comment summarizing the change.
   -- ("DEFAULT 0" is temporary, signaling that log_comment should be used)
-  log_comment_id bigint unsigned NOT NULL CONSTRAINT DF_log_comment_id DEFAULT 0 CONSTRAINT FK_log_comment_id FOREIGN KEY REFERENCES /*_*/comment(comment_id),
+  log_comment_id bigint NOT NULL CONSTRAINT DF_log_comment_id DEFAULT 0 CONSTRAINT FK_log_comment_id FOREIGN KEY REFERENCES /*_*/comment(comment_id),
 
   -- miscellaneous parameters:
   -- LF separated list (old system) or serialized PHP array (new system)
@@ -1212,7 +1209,7 @@ CREATE INDEX /*i*/page_time ON /*_*/logging (log_namespace, log_title, log_times
 CREATE INDEX /*i*/times ON /*_*/logging (log_timestamp);
 CREATE INDEX /*i*/log_user_type_time ON /*_*/logging (log_user, log_type, log_timestamp);
 CREATE INDEX /*i*/log_page_id_time ON /*_*/logging (log_page,log_timestamp);
-CREATE INDEX /*i*/type_action ON /*_*/logging (log_type, log_action, log_timestamp);
+CREATE INDEX /*i*/log_type_action ON /*_*/logging (log_type, log_action, log_timestamp);
 CREATE INDEX /*i*/log_user_text_type_time ON /*_*/logging (log_user_text, log_type, log_timestamp);
 CREATE INDEX /*i*/log_user_text_time ON /*_*/logging (log_user_text, log_timestamp);
 CREATE INDEX /*i*/actor_time ON /*_*/logging (log_actor, log_timestamp);
@@ -1361,13 +1358,13 @@ CREATE TABLE /*_*/protected_titles (
   pt_title nvarchar(255) NOT NULL,
   pt_user int REFERENCES /*_*/mwuser(user_id) ON DELETE SET NULL,
   pt_reason nvarchar(255) CONSTRAINT DF_pt_reason DEFAULT '',
-  pt_reason_id bigint unsigned NOT NULL CONSTRAINT DF_pt_reason_id DEFAULT 0 CONSTRAINT FK_pt_reason_id FOREIGN KEY REFERENCES /*_*/comment(comment_id),
+  pt_reason_id bigint NOT NULL CONSTRAINT DF_pt_reason_id DEFAULT 0 CONSTRAINT FK_pt_reason_id FOREIGN KEY REFERENCES /*_*/comment(comment_id),
   pt_timestamp varchar(14) NOT NULL,
   pt_expiry varchar(14) NOT NULL,
-  pt_create_perm nvarchar(60) NOT NULL
+  pt_create_perm nvarchar(60) NOT NULL,
+  CONSTRAINT PK_protected_titles PRIMARY KEY(pt_namespace,pt_title)
 );
 
-CREATE UNIQUE INDEX /*i*/pt_namespace_title ON /*_*/protected_titles (pt_namespace,pt_title);
 CREATE INDEX /*i*/pt_timestamp ON /*_*/protected_titles (pt_timestamp);
 
 
@@ -1376,10 +1373,10 @@ CREATE TABLE /*_*/page_props (
   pp_page int NOT NULL REFERENCES /*_*/page(page_id) ON DELETE CASCADE,
   pp_propname nvarchar(60) NOT NULL,
   pp_value nvarchar(max) NOT NULL,
-  pp_sortkey float DEFAULT NULL
+  pp_sortkey float DEFAULT NULL,
+  CONSTRAINT PK_page_props PRIMARY KEY(pp_page,pp_propname)
 );
 
-CREATE UNIQUE INDEX /*i*/pp_page_propname ON /*_*/page_props (pp_page,pp_propname);
 CREATE UNIQUE INDEX /*i*/pp_propname_page ON /*_*/page_props (pp_propname,pp_page);
 CREATE UNIQUE INDEX /*i*/pp_propname_sortkey_page ON /*_*/page_props (pp_propname,pp_sortkey,pp_page);
 
@@ -1520,9 +1517,10 @@ CREATE TABLE /*_*/site_identifiers (
   si_type                    nvarchar(32)       NOT NULL,
 
   -- local key value, ie 'en' or 'wiktionary'
-  si_key                     nvarchar(32)       NOT NULL
+  si_key                     nvarchar(32)       NOT NULL,
+
+  CONSTRAINT PK_site_identifiers PRIMARY KEY(si_type, si_key)
 );
 
-CREATE UNIQUE INDEX /*i*/site_ids_type ON /*_*/site_identifiers (si_type, si_key);
 CREATE INDEX /*i*/site_ids_site ON /*_*/site_identifiers (si_site);
 CREATE INDEX /*i*/site_ids_key ON /*_*/site_identifiers (si_key);
diff --git a/maintenance/mysql.php b/maintenance/mysql.php
new file mode 100644 (file)
index 0000000..1b575bb
--- /dev/null
@@ -0,0 +1,190 @@
+<?php
+/**
+ * Execute the MySQL client binary, connecting to the wiki's DB.
+ * Note that this will not do table prefixing or variable substitution.
+ * To safely run schema patches, use sql.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
+ */
+
+use MediaWiki\Shell\Shell;
+use MediaWiki\MediaWikiServices;
+
+require_once __DIR__ . '/Maintenance.php';
+
+/**
+ * @ingroup Maintenance
+ */
+class MysqlMaintenance extends Maintenance {
+       public function __construct() {
+               parent::__construct();
+               $this->addDescription( "Execute the MySQL client binary. " .
+                       "Non-option arguments will be passed through to mysql." );
+               $this->addOption( 'write', 'Connect to the master database', false, false );
+               $this->addOption( 'group', 'Specify query group', false, false );
+               $this->addOption( 'host', 'Connect to a specific MySQL server', false, true );
+               $this->addOption( 'list-hosts', 'List the available DB hosts', false, false );
+               $this->addOption( 'cluster', 'Use an external cluster by name', false, true );
+               $this->addOption( 'wikidb',
+                       'The database wiki ID to use if not the current one', false, true );
+
+               // Fake argument for help message
+               $this->addArg( '-- mysql_option ...', 'Options to pass to mysql', false );
+       }
+
+       public function execute() {
+               $dbName = $this->getOption( 'wikidb', false );
+               $lbf = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
+               if ( $this->hasOption( 'cluster' ) ) {
+                       try {
+                               $lb = $lbf->getExternalLB( $this->getOption( 'cluster' ) );
+                       } catch ( InvalidArgumentException $e ) {
+                               $this->error( "Error: invalid cluster" );
+                               exit( 1 );
+                       }
+               } else {
+                       $lb = $lbf->getMainLB( $dbName );
+               }
+               if ( $this->hasOption( 'list-hosts' ) ) {
+                       $serverCount = $lb->getServerCount();
+                       for ( $index = 0; $index < $serverCount; ++$index ) {
+                               echo $lb->getServerName( $index ) . "\n";
+                       }
+                       exit( 0 );
+               }
+               if ( $this->hasOption( 'host' ) ) {
+                       $host = $this->getOption( 'host' );
+                       $serverCount = $lb->getServerCount();
+                       for ( $index = 0; $index < $serverCount; ++$index ) {
+                               $serverInfo = $lb->getServerInfo( $index );
+
+                               if ( $lb->getServerName( $index ) === $host ) {
+                                       break;
+                               }
+                       }
+                       if ( $index >= $serverCount ) {
+                               $this->error( "Error: Host not configured: \"$host\"" );
+                               exit( 1 );
+                       }
+               } elseif ( $this->hasOption( 'write' ) ) {
+                       $index = $lb->getWriterIndex();
+               } else {
+                       $group = $this->getOption( 'group', false );
+                       $index = $lb->getReaderIndex( $group, $dbName );
+                       if ( $index === false ) {
+                               $this->error( "Error: unable to get reader index" );
+                               exit( 1 );
+                       }
+               }
+
+               if ( $lb->getServerType( $index ) !== 'mysql' ) {
+                       $this->error( "Error: this script only works with MySQL/MariaDB" );
+                       exit( 1 );
+               }
+
+               $status = $this->runMysql( $lb->getServerInfo( $index ), $dbName );
+               exit( $status );
+       }
+
+       /**
+        * Run the mysql client for the given server info
+        *
+        * @param array $info
+        * @param string|false The DB name, or false to use the main wiki DB
+        *
+        * @return The desired exit status
+        */
+       private function runMysql( $info, $dbName ) {
+               // Write the password to an option file to avoid disclosing it to other
+               // processes running on the system
+               $tmpFile = TempFSFile::factory( 'mw-mysql', 'ini' );
+               chmod( $tmpFile->getPath(), 0600 );
+               file_put_contents( $tmpFile->getPath(), "[client]\npassword={$info['password']}\n" );
+
+               // stdin/stdout need to be the actual file descriptors rather than
+               // PHP's pipe wrappers so that mysql can use them as an interactive
+               // terminal.
+               $desc = [
+                       0 => STDIN,
+                       1 => STDOUT,
+                       2 => STDERR,
+               ];
+
+               // Split host and port as in DatabaseMysqli::mysqlConnect()
+               $realServer = $info['host'];
+               $hostAndPort = IP::splitHostAndPort( $realServer );
+               $socket = false;
+               $port = false;
+               if ( $hostAndPort ) {
+                       $realServer = $hostAndPort[0];
+                       if ( $hostAndPort[1] ) {
+                               $port = $hostAndPort[1];
+                       }
+               } 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];
+               }
+
+               if ( $dbName === false ) {
+                       $dbName = $info['dbname'];
+               }
+
+               $args = [
+                       'mysql',
+                       "--defaults-extra-file={$tmpFile->getPath()}",
+                       "--user={$info['user']}",
+                       "--database={$dbName}",
+               ];
+               if ( $socket !== false ) {
+                       $args[] = "--socket={$socket}";
+               } else {
+                       $args[] = "--host={$realServer}";
+               }
+               if ( $port !== false ) {
+                       $args[] = "--port={$port}";
+               }
+
+               $args = array_merge( $args, $this->mArgs );
+
+               // Ignore SIGINT if possible, otherwise the wrapper terminates when the user presses
+               // ctrl-C to kill a query.
+               if ( function_exists( 'pcntl_signal' ) ) {
+                       pcntl_signal( SIGINT, SIG_IGN );
+               }
+
+               $pipes = [];
+               $proc = proc_open( Shell::escape( $args ), $desc, $pipes );
+               if ( $proc === false ) {
+                       $this->error( "Unable to execute mysql" );
+                       return 1;
+               }
+               $ret = proc_close( $proc );
+               if ( $ret === -1 ) {
+                       $this->error( "proc_close() returned -1" );
+                       return 1;
+               }
+               return $ret;
+       }
+}
+
+$maintClass = MysqlMaintenance::class;
+require_once RUN_MAINTENANCE_IF_MAIN;
index 3c83921..71241e7 100644 (file)
@@ -37,7 +37,7 @@ use Wikimedia\Rdbms\IMaintainableDatabase;
  *
  * @ingroup Maintenance
  */
-class NamespaceConflictChecker extends Maintenance {
+class NamespaceDupes extends Maintenance {
 
        /**
         * @var IMaintainableDatabase
@@ -161,17 +161,8 @@ class NamespaceConflictChecker extends Maintenance {
                // break the tie by sorting by name
                $origSpaces = $spaces;
                uksort( $spaces, function ( $a, $b ) use ( $origSpaces ) {
-                       if ( $origSpaces[$a] < $origSpaces[$b] ) {
-                               return -1;
-                       } elseif ( $origSpaces[$a] > $origSpaces[$b] ) {
-                               return 1;
-                       } elseif ( $a < $b ) {
-                               return -1;
-                       } elseif ( $a > $b ) {
-                               return 1;
-                       } else {
-                               return 0;
-                       }
+                       return $origSpaces[$a] <=> $origSpaces[$b]
+                               ?: $a <=> $b;
                } );
 
                $ok = true;
@@ -616,5 +607,5 @@ class NamespaceConflictChecker extends Maintenance {
        }
 }
 
-$maintClass = NamespaceConflictChecker::class;
+$maintClass = NamespaceDupes::class;
 require_once RUN_MAINTENANCE_IF_MAIN;
index 93c7531..8a33888 100644 (file)
@@ -36,29 +36,29 @@ CREATE UNIQUE INDEX &mw_prefix.revactor_rev ON &mw_prefix.revision_actor_temp (r
 CREATE INDEX &mw_prefix.actor_timestamp ON &mw_prefix.revision_actor_temp (revactor_actor,revactor_timestamp);
 CREATE INDEX &mw_prefix.page_actor_timestamp ON &mw_prefix.revision_actor_temp (revactor_page,revactor_actor,revactor_timestamp);
 
-ALTER TABLE &mw_prefix.archive ALTER COLUMN ar_user_text VARCHAR2(255) NULL;
-ALTER TABLE &mw_prefix.archive ADD COLUMN ar_actor NUMBER DEFAULT 0 NOT NULL;
+ALTER TABLE &mw_prefix.archive MODIFY ( ar_user_text NULL );
+ALTER TABLE &mw_prefix.archive ADD ( ar_actor NUMBER DEFAULT 0 NOT NULL );
 CREATE INDEX &mw_prefix.ar_actor_timestamp ON &mw_prefix.archive (ar_actor,ar_timestamp);
 
-ALTER TABLE &mw_prefix.ipblocks ADD COLUMN ipb_by_actor NUMBER DEFUALT 0 NOT NULL;
+ALTER TABLE &mw_prefix.ipblocks ADD ( ipb_by_actor NUMBER DEFAULT 0 NOT NULL );
 
-ALTER TABLE &mw_prefix.image ALTER COLUMN img_user_text VARCHAR2(255) NULL;
-ALTER TABLE &mw_prefix.image ADD COLUMN img_actor NUMBER DEFAULT 0 NOT NULL;
+ALTER TABLE &mw_prefix.image MODIFY ( img_user_text NULL );
+ALTER TABLE &mw_prefix.image ADD ( img_actor NUMBER DEFAULT 0 NOT NULL );
 CREATE INDEX &mw_prefix.img_actor_timestamp ON &mw_prefix.image (img_actor, img_timestamp);
 
-ALTER TABLE &mw_prefix.oldimage ALTER COLUMN oi_user_text VARCHAR2(255) NULL;
-ALTER TABLE &mw_prefix.oldimage ADD COLUMN oi_actor NUMBER DEFAULT 0 NOT NULL;
+ALTER TABLE &mw_prefix.oldimage MODIFY ( oi_user_text NULL );
+ALTER TABLE &mw_prefix.oldimage ADD ( oi_actor NUMBER DEFAULT 0 NOT NULL );
 CREATE INDEX &mw_prefix.oi_actor_timestamp ON &mw_prefix.oldimage (oi_actor,oi_timestamp);
 
-ALTER TABLE &mw_prefix.filearchive ALTER COLUMN fa_user_text VARCHAR2(255) NULL;
-ALTER TABLE &mw_prefix.filearchive ADD COLUMN fa_actor NUMBER DEFAULT 0 NOT NULL;
+ALTER TABLE &mw_prefix.filearchive MODIFY ( fa_user_text NULL );
+ALTER TABLE &mw_prefix.filearchive ADD ( fa_actor NUMBER DEFAULT 0 NOT NULL );
 CREATE INDEX &mw_prefix.fa_actor_timestamp ON &mw_prefix.filearchive (fa_actor,fa_timestamp);
 
-ALTER TABLE &mw_prefix.recentchanges ALTER COLUMN rc_user_text VARCHAR2(255) NULL;
-ALTER TABLE &mw_prefix.recentchanges ADD COLUMN rc_actor NUMBER DEFAULT 0 NOT NULL;
+ALTER TABLE &mw_prefix.recentchanges MODIFY ( rc_user_text NULL );
+ALTER TABLE &mw_prefix.recentchanges ADD ( rc_actor NUMBER DEFAULT 0 NOT NULL );
 CREATE INDEX &mw_prefix.rc_ns_actor ON &mw_prefix.recentchanges (rc_namespace, rc_actor);
 CREATE INDEX &mw_prefix.rc_actor ON &mw_prefix.recentchanges (rc_actor, rc_timestamp);
 
-ALTER TABLE &mw_prefix.logging ADD COLUMN log_actor NUMBER DEFAULT 0 NOT NULL;
+ALTER TABLE &mw_prefix.logging ADD ( log_actor NUMBER DEFAULT 0 NOT NULL );
 CREATE INDEX &mw_prefix.actor_time ON &mw_prefix.logging (log_actor, log_timestamp);
 CREATE INDEX &mw_prefix.log_actor_type_time ON &mw_prefix.logging (log_actor, log_type, log_timestamp);
diff --git a/maintenance/oracle/archives/patch-archive-ar_rev_id-unique.sql b/maintenance/oracle/archives/patch-archive-ar_rev_id-unique.sql
new file mode 100644 (file)
index 0000000..c1cccc2
--- /dev/null
@@ -0,0 +1,6 @@
+-- T193180: ar_rev_id should be unique
+
+define mw_prefix='{$wgDBprefix}';
+
+CREATE UNIQUE INDEX &mw_prefix.archive_i04 ON &mw_prefix.archive (ar_rev_id);
+DROP INDEX &mw_prefix.archive_i03;
index cfe944f..cdab291 100644 (file)
@@ -43,26 +43,26 @@ ALTER TABLE &mw_prefix.image_comment_temp ADD CONSTRAINT &mw_prefix.image_commen
 CREATE UNIQUE INDEX &mw_prefix.imgcomment_name ON &mw_prefix.image_comment_temp (imgcomment_name);
 
 
-ALTER TABLE &mw_prefix.archive ADD COLUMN ar_comment_id NUMBER DEFAULT 0 NOT NULL;
+ALTER TABLE &mw_prefix.archive ADD ( ar_comment_id NUMBER DEFAULT 0 NOT NULL );
 ALTER TABLE &mw_prefix.archive ADD CONSTRAINT &mw_prefix.archive_fk2 FOREIGN KEY (ar_comment_id) REFERENCES &mw_prefix."COMMENT"(comment_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED;
 
-ALTER TABLE &mw_prefix.ipblocks ALTER COLUMN ipb_reason VARCHAR2(255) NULL;
-ALTER TABLE &mw_prefix.ipblocks ADD COLUMN ipb_reason_id NUMBER DEFAULT 0 NOT NULL;
+ALTER TABLE &mw_prefix.ipblocks MODIFY ( ipb_reason NULL );
+ALTER TABLE &mw_prefix.ipblocks ADD ( ipb_reason_id NUMBER DEFAULT 0 NOT NULL );
 ALTER TABLE &mw_prefix.ipblocks ADD CONSTRAINT &mw_prefix.ipblocks_fk3 FOREIGN KEY (ipb_reason_id) REFERENCES &mw_prefix."COMMENT"(comment_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED;
 
-ALTER TABLE &mw_prefix.oldimage ADD COLUMN oi_description_id NUMBER DEFAULT 0 NOT NULL;
+ALTER TABLE &mw_prefix.oldimage ADD ( oi_description_id NUMBER DEFAULT 0 NOT NULL );
 ALTER TABLE &mw_prefix.oldimage ADD CONSTRAINT &mw_prefix.oldimage_fk3 FOREIGN KEY (oi_description_id) REFERENCES &mw_prefix."COMMENT"(comment_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED;
 
-ALTER TABLE &mw_prefix.filearchive ADD COLUMN fa_deleted_reason_id NUMBER DEFAULT 0 NOT NULL;
-ALTER TABLE &mw_prefix.filearchive ADD COLUMN fa_description_id NUMBER DEFAULT 0 NOT NULL;
+ALTER TABLE &mw_prefix.filearchive ADD ( fa_deleted_reason_id NUMBER DEFAULT 0 NOT NULL );
+ALTER TABLE &mw_prefix.filearchive ADD ( fa_description_id NUMBER DEFAULT 0 NOT NULL );
 ALTER TABLE &mw_prefix.filearchive ADD CONSTRAINT &mw_prefix.filearchive_fk3 FOREIGN KEY (fa_deleted_reason_id) REFERENCES &mw_prefix."COMMENT"(comment_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED;
 ALTER TABLE &mw_prefix.filearchive ADD CONSTRAINT &mw_prefix.filearchive_fk4 FOREIGN KEY (fa_description_id) REFERENCES &mw_prefix."COMMENT"(comment_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED;
 
-ALTER TABLE &mw_prefix.recentchanges ADD COLUMN rc_comment_id NUMBER DEFAULT 0 NOT NULL;
+ALTER TABLE &mw_prefix.recentchanges ADD ( rc_comment_id NUMBER DEFAULT 0 NOT NULL );
 ALTER TABLE &mw_prefix.recentchanges ADD CONSTRAINT &mw_prefix.recentchanges_fk3 FOREIGN KEY (rc_comment_id) REFERENCES &mw_prefix."COMMENT"(comment_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED;
 
-ALTER TABLE &mw_prefix.logging ADD COLUMN log_comment_id NUMBER DEFAULT 0 NOT NULL;
+ALTER TABLE &mw_prefix.logging ADD ( log_comment_id NUMBER DEFAULT 0 NOT NULL );
 ALTER TABLE &mw_prefix.logging ADD CONSTRAINT &mw_prefix.logging_fk2 FOREIGN KEY (log_comment_id) REFERENCES &mw_prefix."COMMENT"(comment_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED;
 
-ALTER TABLE &mw_prefix.protected_titles ADD COLUMN pt_reason_id NUMBER DEFAULT 0 NOT NULL;
+ALTER TABLE &mw_prefix.protected_titles ADD ( pt_reason_id NUMBER DEFAULT 0 NOT NULL );
 ALTER TABLE &mw_prefix.protected_titles ADD CONSTRAINT &mw_prefix.protected_titles_fk1 FOREIGN KEY (pt_reason_id) REFERENCES &mw_prefix."COMMENT"(comment_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED;
index 6e36752..b5e423d 100644 (file)
@@ -271,7 +271,7 @@ ALTER TABLE &mw_prefix.archive ADD CONSTRAINT &mw_prefix.archive_fk2 FOREIGN KEY
 CREATE INDEX &mw_prefix.archive_i01 ON &mw_prefix.archive (ar_namespace,ar_title,ar_timestamp);
 CREATE INDEX &mw_prefix.archive_i02 ON &mw_prefix.archive (ar_user_text,ar_timestamp);
 CREATE INDEX &mw_prefix.ar_actor_timestamp ON &mw_prefix.archive (ar_actor,ar_timestamp);
-CREATE INDEX &mw_prefix.archive_i03 ON &mw_prefix.archive (ar_rev_id);
+CREATE UNIQUE INDEX &mw_prefix.archive_i04 ON &mw_prefix.archive (ar_rev_id);
 /*$mw$*/
 CREATE TRIGGER &mw_prefix.archive_seq_trg BEFORE INSERT ON &mw_prefix.archive
        FOR EACH ROW WHEN (new.ar_id IS NULL)
@@ -496,7 +496,7 @@ CREATE TABLE &mw_prefix.ipblocks (
   ipb_user              NUMBER      DEFAULT 0 NOT  NULL,
   ipb_by                NUMBER      DEFAULT 0 NOT NULL,
   ipb_by_text           VARCHAR2(255)      NULL,
-  ipb_by_actor          NUMBER      DEFUALT 0 NOT NULL,
+  ipb_by_actor          NUMBER      DEFAULT 0 NOT NULL,
   ipb_reason            VARCHAR2(255)      NULL,
   ipb_reason_id         NUMBER DEFAULT 0 NOT NULL,
   ipb_timestamp         TIMESTAMP(6) WITH TIME ZONE  NOT NULL,
index 7acf6d8..d7decc1 100644 (file)
@@ -108,13 +108,20 @@ class Orphans extends Maintenance {
                        foreach ( $result as $row ) {
                                $comment = $commentStore->getComment( 'rev_comment', $row )->text;
                                if ( $comment !== '' ) {
-                                       $comment = '(' . $wgContLang->truncate( $comment, 40 ) . ')';
+                                       $comment = '(' . $wgContLang->truncateForVisual( $comment, 40 ) . ')';
                                }
-                               $this->output( sprintf( "%10d %10d %14s %20s %s\n",
+                               $rev_user_text = $wgContLang->truncateForVisual( $row->rev_user_text, 20 );
+                               # pad $rev_user_text to 20 characters.  Note that this may
+                               # yield poor results if $rev_user_text contains combining
+                               # or half-width characters.  Alas.
+                               if ( mb_strlen( $rev_user_text ) < 20 ) {
+                                       $rev_user_text = str_repeat( ' ', 20 - mb_strlen( $rev_user_text ) );
+                               }
+                               $this->output( sprintf( "%10d %10d %14s %s %s\n",
                                        $row->rev_id,
                                        $row->rev_page,
                                        $row->rev_timestamp,
-                                       $wgContLang->truncate( $row->rev_user_text, 17 ),
+                                       $rev_user_text,
                                        $comment ) );
                                if ( $fix ) {
                                        $dbw->delete( 'revision', [ 'rev_id' => $row->rev_id ] );
index b87a716..cf2fe54 100644 (file)
@@ -46,7 +46,7 @@
  * @file
  * @ingroup Maintenance
  * @author Antoine Musso <hashar at free dot fr>
- * @license GNU General Public License 2.0 or later
+ * @license GPL-2.0-or-later
  */
 
 require_once __DIR__ . '/Maintenance.php';
diff --git a/maintenance/populateChangeTagDef.php b/maintenance/populateChangeTagDef.php
new file mode 100644 (file)
index 0000000..707eb29
--- /dev/null
@@ -0,0 +1,198 @@
+<?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
+ */
+
+require_once __DIR__ . '/Maintenance.php';
+
+/**
+ * Populate and improve accuracy of change_tag_def statistics.
+ *
+ * @ingroup Maintenance
+ */
+class PopulateChangeTagDef extends Maintenance {
+       /** @var Wikimedia\Rdbms\ILBFactory */
+       protected $lbFactory;
+
+       public function __construct() {
+               parent::__construct();
+               $this->addDescription( 'Populate and improve accuracy of change_tag_def statistics' );
+               $this->addOption( 'dry-run', 'Print debug info instead of actually deleting' );
+               $this->setBatchSize( 1000 );
+               $this->addOption(
+                       'sleep',
+                       'Sleep time (in seconds) between every batch',
+                       false,
+                       true
+               );
+       }
+
+       public function execute() {
+               global $wgChangeTagsSchemaMigrationStage;
+               $this->lbFactory = MediaWiki\MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
+               $this->setBatchSize( $this->getOption( 'batch-size', $this->getBatchSize() ) );
+
+               $this->countDown( 5 );
+               if ( $wgChangeTagsSchemaMigrationStage < MIGRATION_NEW ) {
+                       $this->updateCountTag();
+                       $this->backpopulateChangeTagId();
+               } else {
+                       $this->updateCountTagId();
+               }
+
+               // TODO: Implement
+               // $this->cleanZeroCountRows();
+       }
+
+       private function updateCountTagId() {
+               $dbr = $this->lbFactory->getMainLB()->getConnection( DB_REPLICA );
+
+               // This query can be pretty expensive, don't run it on master
+               $res = $dbr->select(
+                       'change_tag',
+                       [ 'ct_tag_id', 'hitcount' => 'count(*)' ],
+                       [],
+                       __METHOD__,
+                       [ 'GROUP BY' => 'ct_tag_id' ]
+               );
+
+               $dbw = $this->lbFactory->getMainLB()->getConnection( DB_MASTER );
+
+               foreach ( $res as $row ) {
+                       if ( !$row->ct_tag_id ) {
+                               continue;
+                       }
+
+                       if ( $this->hasOption( 'dry-run' ) ) {
+                               $this->output( 'This row will be updated: ' . implode( ', ', $row ) . "\n" );
+                               continue;
+                       }
+
+                       $dbw->update(
+                               'change_tag_def',
+                               [ 'ctd_count' => $row->hitcount ],
+                               [ 'ctd_id' => $row->ct_tag_id ],
+                               __METHOD__
+                       );
+               }
+               $this->lbFactory->waitForReplication();
+       }
+
+       private function updateCountTag() {
+               $dbr = $this->lbFactory->getMainLB()->getConnection( DB_REPLICA );
+
+               // This query can be pretty expensive, don't run it on master
+               $res = $dbr->select(
+                       'change_tag',
+                       [ 'ct_tag', 'hitcount' => 'count(*)' ],
+                       [],
+                       __METHOD__,
+                       [ 'GROUP BY' => 'ct_tag' ]
+               );
+
+               $dbw = $this->lbFactory->getMainLB()->getConnection( DB_MASTER );
+
+               foreach ( $res as $row ) {
+                       // Hygiene check
+                       if ( !$row->ct_tag ) {
+                               continue;
+                       }
+
+                       if ( $this->hasOption( 'dry-run' ) ) {
+                               $this->output( 'This row will be updated: ' . $row->ct_tag . $row->hitcount . "\n" );
+                               continue;
+                       }
+
+                       $dbw->upsert(
+                               'change_tag_def',
+                               [
+                                       'ctd_name' => $row->ct_tag,
+                                       'ctd_user_defined' => 0,
+                                       'ctd_count' => $row->hitcount
+                               ],
+                               [ 'ctd_name' ],
+                               [ 'ctd_count' => $row->hitcount ],
+                               __METHOD__
+                       );
+               }
+               $this->lbFactory->waitForReplication();
+       }
+
+       private function backpopulateChangeTagId() {
+               $dbr = $this->lbFactory->getMainLB()->getConnection( DB_REPLICA );
+               $changeTagDefs = $dbr->select(
+                       'change_tag_def',
+                       [ 'ctd_name', 'ctd_id' ],
+                       [],
+                       __METHOD__,
+                       [ 'ORDER BY' => 'ctd_id' ]
+               );
+
+               foreach ( $changeTagDefs as $row ) {
+                       $this->backpopulateChangeTagPerTag( $row->ctd_name, $row->ctd_id );
+               }
+       }
+
+       private function backpopulateChangeTagPerTag( $tagName, $tagId ) {
+               $dbr = $this->lbFactory->getMainLB()->getConnection( DB_REPLICA );
+               $dbw = $this->lbFactory->getMainLB()->getConnection( DB_MASTER );
+               $sleep = (int)$this->getOption( 'sleep', 10 );
+               $lastId = 0;
+               $this->output( "Starting to add ct_tag_id = {$tagId} for ct_tag = {$tagName}\n" );
+               while ( true ) {
+                       // Given that indexes might not be there, it's better to use replica
+                       $ids = $dbr->selectFieldValues(
+                               'change_tag',
+                               'ct_id',
+                               [ 'ct_tag' => $tagName, 'ct_tag_id' => null, 'ct_id > ' . $lastId ],
+                               __METHOD__,
+                               [ 'LIMIT' => $this->getBatchSize(), 'ORDER BY' => 'ct_id' ]
+                       );
+
+                       if ( !$ids ) {
+                               break;
+                       }
+                       $lastId = end( $ids );
+
+                       if ( $this->hasOption( 'dry-run' ) ) {
+                               $this->output(
+                                       "These ids will be changed to have \"{$tagId}\" as tag id: " . implode( ', ', $ids ) . "\n"
+                               );
+                               continue;
+                       } else {
+                               $this->output( "Updating ct_tag_id = {$tagId} up to row ct_id = {$lastId}\n" );
+                       }
+
+                       $dbw->update(
+                               'change_tag',
+                               [ 'ct_tag_id' => $tagId ],
+                               [ 'ct_id' => $ids ],
+                               __METHOD__
+                       );
+
+                       $this->lbFactory->waitForReplication();
+                       if ( $sleep > 0 ) {
+                               sleep( $sleep );
+                       }
+               }
+
+               $this->output( "Finished adding ct_tag_id = {$tagId} for ct_tag = {$tagName}\n" );
+       }
+
+}
+
+$maintClass = PopulateChangeTagDef::class;
+require_once RUN_MAINTENANCE_IF_MAIN;
diff --git a/maintenance/populateContentTables.php b/maintenance/populateContentTables.php
new file mode 100644 (file)
index 0000000..20d6b8b
--- /dev/null
@@ -0,0 +1,337 @@
+<?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
+ */
+
+use MediaWiki\MediaWikiServices;
+use MediaWiki\Storage\NameTableStore;
+use MediaWiki\Storage\SqlBlobStore;
+use Wikimedia\Assert\Assert;
+use Wikimedia\Rdbms\IDatabase;
+use Wikimedia\Rdbms\ResultWrapper;
+
+require_once __DIR__ . '/Maintenance.php';
+
+/**
+ * Populate the content and slot tables.
+ * @since 1.32
+ */
+class PopulateContentTables extends Maintenance {
+
+       /** @var IDatabase */
+       private $dbw;
+
+       /** @var NameTableStore */
+       private $contentModelStore;
+
+       /** @var int */
+       private $mainRoleId;
+
+       /** @var array|null Map "{$modelId}:{$address}" to content_id */
+       private $contentRowMap = null;
+
+       private $count = 0, $totalCount = 0;
+
+       public function __construct() {
+               parent::__construct();
+
+               $this->addDescription( 'Populate content and slot tables' );
+               $this->addOption( 'table', 'revision or archive table, or `all` to populate both', false,
+                       true );
+               $this->addOption( 'reuse-content',
+                       'Reuse content table rows when the address and model are the same. '
+                       . 'This will increase the script\'s time and memory usage, perhaps significantly.',
+                       false, false );
+               $this->setBatchSize( 500 );
+       }
+
+       private function initServices() {
+               $this->dbw = $this->getDB( DB_MASTER );
+               $this->contentModelStore = MediaWikiServices::getInstance()->getContentModelStore();
+               $this->mainRoleId = MediaWikiServices::getInstance()->getSlotRoleStore()->acquireId( 'main' );
+       }
+
+       public function execute() {
+               global $wgMultiContentRevisionSchemaMigrationStage;
+
+               $t0 = microtime( true );
+
+               if ( ( $wgMultiContentRevisionSchemaMigrationStage & SCHEMA_COMPAT_WRITE_NEW ) === 0 ) {
+                       $this->writeln(
+                               '...cannot update while \$wgMultiContentRevisionSchemaMigrationStage '
+                               . 'does not have the SCHEMA_COMPAT_WRITE_NEW bit set.'
+                       );
+                       return false;
+               }
+
+               $this->initServices();
+
+               if ( $this->getOption( 'reuse-content', false ) ) {
+                       $this->loadContentMap();
+               }
+
+               foreach ( $this->getTables() as $table ) {
+                       $this->populateTable( $table );
+               }
+
+               $elapsed = microtime( true ) - $t0;
+               $this->writeln( "Done. Processed $this->totalCount rows in $elapsed seconds" );
+               return true;
+       }
+
+       /**
+        * @return string[]
+        */
+       private function getTables() {
+               $table = $this->getOption( 'table', 'all' );
+               $validTableOptions = [ 'all', 'revision', 'archive' ];
+
+               if ( !in_array( $table, $validTableOptions ) ) {
+                       $this->fatalError( 'Invalid table. Must be either `revision` or `archive` or `all`' );
+               }
+
+               if ( $table === 'all' ) {
+                       $tables = [ 'revision', 'archive' ];
+               } else {
+                       $tables = [ $table ];
+               }
+
+               return $tables;
+       }
+
+       private function loadContentMap() {
+               $t0 = microtime( true );
+               $this->writeln( "Loading existing content table rows..." );
+               $this->contentRowMap = [];
+               $dbr = $this->getDB( DB_REPLICA );
+               $from = false;
+               while ( true ) {
+                       $res = $dbr->select(
+                               'content',
+                               [ 'content_id', 'content_address', 'content_model' ],
+                               $from ? "content_id > $from" : '',
+                               __METHOD__,
+                               [ 'ORDER BY' => 'content_id', 'LIMIT' => $this->getBatchSize() ]
+                       );
+                       if ( !$res || !$res->numRows() ) {
+                               break;
+                       }
+                       foreach ( $res as $row ) {
+                               $from = $row->content_id;
+                               $this->contentRowMap["{$row->content_model}:{$row->content_address}"] = $row->content_id;
+                       }
+               }
+               $elapsed = microtime( true ) - $t0;
+               $this->writeln( "Loaded " . count( $this->contentRowMap ) . " rows in $elapsed seconds" );
+       }
+
+       /**
+        * @param string $table
+        */
+       private function populateTable( $table ) {
+               $t0 = microtime( true );
+               $this->count = 0;
+               $this->writeln( "Populating $table..." );
+
+               if ( $table === 'revision' ) {
+                       $idField = 'rev_id';
+                       $tables = [ 'revision', 'slots', 'page' ];
+                       $fields = [
+                               'rev_id',
+                               'len' => 'rev_len',
+                               'sha1' => 'rev_sha1',
+                               'text_id' => 'rev_text_id',
+                               'content_model' => 'rev_content_model',
+                               'namespace' => 'page_namespace',
+                               'title' => 'page_title',
+                       ];
+                       $joins = [
+                               'slots' => [ 'LEFT JOIN', 'rev_id=slot_revision_id' ],
+                               'page' => [ 'LEFT JOIN', 'rev_page=page_id' ],
+                       ];
+               } else {
+                       $idField = 'ar_rev_id';
+                       $tables = [ 'archive', 'slots' ];
+                       $fields = [
+                               'rev_id' => 'ar_rev_id',
+                               'len' => 'ar_len',
+                               'sha1' => 'ar_sha1',
+                               'text_id' => 'ar_text_id',
+                               'content_model' => 'ar_content_model',
+                               'namespace' => 'ar_namespace',
+                               'title' => 'ar_title',
+                       ];
+                       $joins = [
+                               'slots' => [ 'LEFT JOIN', 'ar_rev_id=slot_revision_id' ],
+                       ];
+               }
+
+               $minmax = $this->dbw->selectRow(
+                       $table,
+                       [ 'min' => "MIN( $idField )", 'max' => "MAX( $idField )" ],
+                       '',
+                       __METHOD__
+               );
+               if ( !$minmax || !is_numeric( $minmax->min ) || !is_numeric( $minmax->max ) ) {
+                       // No rows?
+                       $minmax = (object)[ 'min' => 1, 'max' => 0 ];
+               }
+
+               $batchSize = $this->getBatchSize();
+
+               for ( $startId = $minmax->min; $startId <= $minmax->max; $startId += $batchSize ) {
+                       $endId = min( $startId + $batchSize - 1, $minmax->max );
+                       $rows = $this->dbw->select(
+                               $tables,
+                               $fields,
+                               [
+                                       "$idField >= $startId",
+                                       "$idField <= $endId",
+                                       'slot_revision_id IS NULL',
+                               ],
+                               __METHOD__,
+                               [ 'ORDER BY' => 'rev_id' ],
+                               $joins
+                       );
+                       if ( $rows->numRows() !== 0 ) {
+                               $this->populateContentTablesForRowBatch( $rows, $startId, $table );
+                       }
+
+                       $elapsed = microtime( true ) - $t0;
+                       $this->writeln(
+                               "... $table processed up to revision id $endId of {$minmax->max}"
+                               . " ($this->count rows in $elapsed seconds)"
+                       );
+               }
+
+               $elapsed = microtime( true ) - $t0;
+               $this->writeln( "Done populating $table table. Processed $this->count rows in $elapsed seconds" );
+       }
+
+       /**
+        * @param ResultWrapper $rows
+        * @param int $startId
+        * @param string $table
+        * @return int|null
+        */
+       private function populateContentTablesForRowBatch( ResultWrapper $rows, $startId, $table ) {
+               $this->beginTransaction( $this->dbw, __METHOD__ );
+
+               if ( $this->contentRowMap === null ) {
+                       $map = [];
+               } else {
+                       $map = &$this->contentRowMap;
+               }
+               $contentKeys = [];
+
+               try {
+                       // Step 1: Figure out content rows needing insertion.
+                       $contentRows = [];
+                       foreach ( $rows as $row ) {
+                               $revisionId = $row->rev_id;
+
+                               Assert::invariant( $revisionId !== null, 'rev_id must not be null' );
+
+                               $modelId = $this->contentModelStore->acquireId( $this->getContentModel( $row ) );
+                               $address = SqlBlobStore::makeAddressFromTextId( $row->text_id );
+
+                               $key = "{$modelId}:{$address}";
+                               $contentKeys[$revisionId] = $key;
+
+                               if ( !isset( $map[$key] ) ) {
+                                       $map[$key] = false;
+                                       $contentRows[] = [
+                                               'content_size' => (int)$row->len,
+                                               'content_sha1' => $row->sha1,
+                                               'content_model' => $modelId,
+                                               'content_address' => $address,
+                                       ];
+                               }
+                       }
+
+                       // Step 2: Insert them, then read them back in for use in the next step.
+                       if ( $contentRows ) {
+                               $id = $this->dbw->selectField( 'content', 'MAX(content_id)', '', __METHOD__ );
+                               $this->dbw->insert( 'content', $contentRows, __METHOD__ );
+                               $res = $this->dbw->select(
+                                       'content',
+                                       [ 'content_id', 'content_model', 'content_address' ],
+                                       'content_id > ' . (int)$id,
+                                       __METHOD__
+                               );
+                               foreach ( $res as $row ) {
+                                       $key = $row->content_model . ':' . $row->content_address;
+                                       $map[$key] = $row->content_id;
+                               }
+                       }
+
+                       // Step 3: Insert the slot rows.
+                       $slotRows = [];
+                       foreach ( $rows as $row ) {
+                               $revisionId = $row->rev_id;
+                               $contentId = $map[$contentKeys[$revisionId]] ?? false;
+                               if ( $contentId === false ) {
+                                       throw new \RuntimeException( "Content row for $revisionId not found after content insert" );
+                               }
+                               $slotRows[] = [
+                                       'slot_revision_id' => $revisionId,
+                                       'slot_role_id' => $this->mainRoleId,
+                                       'slot_content_id' => $contentId,
+                                       // There's no way to really know the previous revision, so assume no inheriting.
+                                       // rev_parent_id can get changed on undeletions, and deletions can screw up
+                                       // rev_timestamp ordering.
+                                       'slot_origin' => $revisionId,
+                               ];
+                       }
+                       $this->dbw->insert( 'slots', $slotRows, __METHOD__ );
+                       $this->count += count( $slotRows );
+                       $this->totalCount += count( $slotRows );
+               } catch ( \Exception $e ) {
+                       $this->rollbackTransaction( $this->dbw, __METHOD__ );
+                       $this->fatalError( "Failed to populate content table $table row batch starting at $startId "
+                               . "due to exception: " . $e->__toString() );
+               }
+
+               $this->commitTransaction( $this->dbw, __METHOD__ );
+       }
+
+       /**
+        * @param \stdClass $row
+        * @return string
+        */
+       private function getContentModel( $row ) {
+               if ( isset( $row->content_model ) ) {
+                       return $row->content_model;
+               }
+
+               $title = Title::makeTitle( $row->namespace, $row->title );
+
+               return ContentHandler::getDefaultModelFor( $title );
+       }
+
+       /**
+        * @param string $msg
+        */
+       private function writeln( $msg ) {
+               $this->output( "$msg\n" );
+       }
+}
+
+$maintClass = 'PopulateContentTables';
+require_once RUN_MAINTENANCE_IF_MAIN;
index 1b05e1e..acc66c5 100644 (file)
@@ -24,6 +24,8 @@
  * @author Katie Filbert < aude.wiki@gmail.com >
  */
 
+use MediaWiki\MediaWikiServices;
+
 require_once __DIR__ . '/Maintenance.php';
 
 class PopulateInterwiki extends Maintenance {
@@ -119,6 +121,7 @@ TEXT
                        }
                }
 
+               $lookup = MediaWikiServices::getInstance()->getInterwikiLookup();
                foreach ( $data as $d ) {
                        $prefix = $d['prefix'];
 
@@ -142,7 +145,7 @@ TEXT
                                );
                        }
 
-                       Interwiki::invalidateCache( $prefix );
+                       $lookup->invalidateCache( $prefix );
                }
 
                $this->output( "Interwiki links are populated.\n" );
diff --git a/maintenance/postgres/archives/patch-interwiki-pk.sql b/maintenance/postgres/archives/patch-interwiki-pk.sql
new file mode 100644 (file)
index 0000000..85f6b7b
--- /dev/null
@@ -0,0 +1,3 @@
+ALTER TABLE interwiki
+ DROP CONSTRAINT interwiki_iw_prefix_key,
+ ADD PRIMARY KEY (iw_prefix);
\ No newline at end of file
diff --git a/maintenance/postgres/archives/patch-protected_titles-pk.sql b/maintenance/postgres/archives/patch-protected_titles-pk.sql
new file mode 100644 (file)
index 0000000..17615c7
--- /dev/null
@@ -0,0 +1,2 @@
+DROP INDEX protected_titles_unique;
+ALTER TABLE protected_titles ADD PRIMARY KEY (pt_namespace, pt_title);
\ No newline at end of file
diff --git a/maintenance/postgres/archives/patch-site_identifiers-pk.sql b/maintenance/postgres/archives/patch-site_identifiers-pk.sql
new file mode 100644 (file)
index 0000000..d5c49ee
--- /dev/null
@@ -0,0 +1,2 @@
+DROP INDEX si_type_key;
+ALTER TABLE site_identifiers ADD PRIMARY KEY (si_type,si_key);
\ No newline at end of file
index cf0eb2f..adf2688 100644 (file)
@@ -233,7 +233,6 @@ CREATE TABLE page_props (
   pp_sortkey   FLOAT
 );
 ALTER TABLE page_props ADD CONSTRAINT page_props_pk PRIMARY KEY (pp_page,pp_propname);
-CREATE INDEX page_props_propname ON page_props (pp_propname);
 CREATE UNIQUE INDEX pp_propname_page ON page_props (pp_propname,pp_page);
 CREATE INDEX pp_propname_sortkey_page ON page_props (pp_propname, pp_sortkey, pp_page) WHERE (pp_sortkey IS NOT NULL);
 
@@ -263,6 +262,7 @@ ALTER SEQUENCE archive_ar_id_seq OWNED BY archive.ar_id;
 CREATE INDEX archive_name_title_timestamp ON archive (ar_namespace,ar_title,ar_timestamp);
 CREATE INDEX archive_user_text            ON archive (ar_user_text);
 CREATE INDEX archive_actor                ON archive (ar_actor);
+CREATE UNIQUE INDEX ar_revid_uniq ON archive (ar_rev_id);
 
 
 CREATE TABLE slots (
@@ -605,7 +605,7 @@ CREATE INDEX wl_user_notificationtimestamp ON watchlist (wl_user, wl_notificatio
 
 
 CREATE TABLE interwiki (
-  iw_prefix  TEXT      NOT NULL  UNIQUE,
+  iw_prefix  TEXT      NOT NULL  PRIMARY KEY,
   iw_url     TEXT      NOT NULL,
   iw_local   SMALLINT  NOT NULL,
   iw_trans   SMALLINT  NOT NULL  DEFAULT 0,
@@ -682,6 +682,7 @@ CREATE INDEX logging_page_id_time ON logging (log_page, log_timestamp);
 CREATE INDEX logging_user_text_type_time ON logging (log_user_text, log_type, log_timestamp);
 CREATE INDEX logging_user_text_time ON logging (log_user_text, log_timestamp);
 CREATE INDEX logging_actor_time ON logging (log_actor, log_timestamp);
+CREATE INDEX logging_type_action ON logging (log_type, log_action, log_timestamp);
 
 CREATE TABLE log_search (
   ls_field   TEXT     NOT NULL,
@@ -776,10 +777,10 @@ CREATE TABLE protected_titles (
   pt_reason_id   INTEGER     NOT NULL DEFAULT 0,
   pt_timestamp   TIMESTAMPTZ NOT NULL,
   pt_expiry      TIMESTAMPTZ     NULL,
-  pt_create_perm TEXT        NOT NULL DEFAULT ''
-);
-CREATE UNIQUE INDEX protected_titles_unique ON protected_titles(pt_namespace, pt_title);
+  pt_create_perm TEXT        NOT NULL DEFAULT '',
 
+  PRIMARY KEY (pt_namespace, pt_title)
+);
 
 CREATE TABLE updatelog (
   ul_key TEXT NOT NULL PRIMARY KEY,
@@ -892,8 +893,9 @@ CREATE INDEX site_forward ON sites (site_forward);
 CREATE TABLE site_identifiers (
   si_site   INTEGER NOT NULL,
   si_type   TEXT    NOT NULL,
-  si_key    TEXT    NOT NULL
+  si_key    TEXT    NOT NULL,
+
+  PRIMARY KEY (si_type, si_key)
 );
-CREATE UNIQUE INDEX si_type_key ON site_identifiers (si_type, si_key);
 CREATE INDEX si_site ON site_identifiers (si_site);
 CREATE INDEX si_key ON site_identifiers (si_key);
index df1403c..d72b98a 100644 (file)
@@ -46,8 +46,8 @@ class PurgePage extends Maintenance {
                }
        }
 
-       private function purge( $title ) {
-               $title = Title::newFromText( $title );
+       private function purge( $titleText ) {
+               $title = Title::newFromText( $titleText );
 
                if ( is_null( $title ) ) {
                        $this->error( 'Invalid page title' );
@@ -67,9 +67,9 @@ class PurgePage extends Maintenance {
                }
 
                if ( $page->doPurge() ) {
-                       $this->output( "Purged\n" );
+                       $this->output( "Purged {$titleText}\n" );
                } else {
-                       $this->error( "Purge failed" );
+                       $this->error( "Purge failed for {$titleText}" );
                }
        }
 }
index 4458901..d90a4a7 100644 (file)
@@ -20,7 +20,7 @@
  * @file
  * @ingroup Maintenance
  * @author Rob Church <robchur@gmail.com>
- * @license GNU General Public Licence 2.0 or later
+ * @license GPL-2.0-or-later
  */
 
 use Wikimedia\Rdbms\IDatabase;
index a259484..d86c8ed 100644 (file)
@@ -269,7 +269,7 @@ class RebuildRecentchanges extends Maintenance {
         * Rebuild pass 3: Insert `recentchanges` entries for action logs.
         */
        private function rebuildRecentChangesTablePass3( ILBFactory $lbFactory ) {
-               global $wgLogTypes, $wgLogRestrictions;
+               global $wgLogRestrictions;
 
                $dbw = $this->getDB( DB_MASTER );
                $commentStore = CommentStore::getStore();
@@ -296,7 +296,7 @@ class RebuildRecentchanges extends Maintenance {
                                'log_timestamp < ' . $dbw->addQuotes( $dbw->timestamp( $this->cutoffTo ) ),
                                // Some logs don't go in RC since they are private.
                                // @FIXME: core/extensions also have spammy logs that don't go in RC.
-                               'log_type' => array_diff( $wgLogTypes, array_keys( $wgLogRestrictions ) ),
+                               'log_type' => array_diff( LogPage::validTypes(), array_keys( $wgLogRestrictions ) ),
                        ],
                        __METHOD__,
                        [ 'ORDER BY' => 'log_timestamp DESC' ],
index 49f1cd1..9ca4e98 100644 (file)
@@ -21,6 +21,7 @@
  * @ingroup Maintenance
  */
 
+use MediaWiki\MediaWikiServices;
 use Wikimedia\Rdbms\IDatabase;
 
 require_once __DIR__ . '/Maintenance.php';
@@ -258,7 +259,7 @@ class RefreshLinks extends Maintenance {
        public static function fixLinksFromArticle( $id, $ns = false ) {
                $page = WikiPage::newFromID( $id );
 
-               LinkCache::singleton()->clear();
+               MediaWikiServices::getInstance()->getLinkCache()->clear();
 
                if ( $page === null ) {
                        return;
index e066300..3fa30cb 100644 (file)
@@ -75,12 +75,12 @@ class RemoveUnusedAccounts extends Maintenance {
                        # group or if it's touched within the $touchedSeconds seconds.
                        $instance = User::newFromId( $row->user_id );
                        if ( count( array_intersect( $instance->getEffectiveGroups(), $excludedGroups ) ) == 0
-                               && $this->isInactiveAccount( $row->user_id, $row->actor_id, true )
+                               && $this->isInactiveAccount( $row->user_id, $row->actor_id ?? null, true )
                                && wfTimestamp( TS_UNIX, $row->user_touched ) < wfTimestamp( TS_UNIX, time() - $touchedSeconds )
                        ) {
                                # Inactive; print out the name and flag it
                                $delUser[] = $row->user_id;
-                               if ( $row->actor_id ) {
+                               if ( isset( $row->actor_id ) && $row->actor_id ) {
                                        $delActor[] = $row->actor_id;
                                }
                                $this->output( $row->user_name . "\n" );
@@ -138,7 +138,7 @@ class RemoveUnusedAccounts extends Maintenance {
         * (No edits, no deleted edits, no log entries, no current/old uploads)
         *
         * @param int $id User's ID
-        * @param int $actor User's actor ID
+        * @param int|null $actor User's actor ID
         * @param bool $master Perform checking on the master
         * @return bool
         */
index af8a280..73bc4d9 100644 (file)
@@ -50,7 +50,7 @@ class RenameDbPrefix extends Maintenance {
                } else {
                        // Use nice safe, sane, prefixes
                        preg_match( '/^[a-zA-Z]+_$/', $this->getOption( 'old' ), $m );
-                       $old = isset( $m[0] ) ? $m[0] : false;
+                       $old = $m[0] ?? false;
                }
                // Allow for no new prefix
                if ( $this->getOption( 'new', 0 ) === '0' ) {
@@ -58,7 +58,7 @@ class RenameDbPrefix extends Maintenance {
                } else {
                        // Use nice safe, sane, prefixes
                        preg_match( '/^[a-zA-Z]+_$/', $this->getOption( 'new' ), $m );
-                       $new = isset( $m[0] ) ? $m[0] : false;
+                       $new = $m[0] ?? false;
                }
 
                if ( $old === false || $new === false ) {
diff --git a/maintenance/resetAuthenticationThrottle.php b/maintenance/resetAuthenticationThrottle.php
new file mode 100644 (file)
index 0000000..9760c42
--- /dev/null
@@ -0,0 +1,152 @@
+<?php
+/**
+ * Reset login/signup throttling for a specified user and/or IP.
+ *
+ * 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
+ */
+
+use MediaWiki\Auth\AuthManager;
+use MediaWiki\Auth\Throttler;
+use MediaWiki\Logger\LoggerFactory;
+
+require_once __DIR__ . '/Maintenance.php';
+
+/**
+ * Reset login/signup throttling for a specified user and/or IP.
+ *
+ * @ingroup Maintenance
+ * @since 1.32
+ */
+class ResetAuthenticationThrottle extends Maintenance {
+
+       public function __construct() {
+               parent::__construct();
+               $this->addDescription( 'Reset login/signup throttling for a specified user and/or IP. '
+                       . "\n\n"
+                       . 'When resetting signup only, provide the IP. When resetting login (or both), provide '
+                       . 'both username (as entered in login screen) and IP. An easy way to obtain them is '
+                       . "the 'throttler' log channel." );
+               $this->addOption( 'login', 'Reset login throttle' );
+               $this->addOption( 'signup', 'Reset account creation throttle' );
+               $this->addOption( 'user', 'Username to reset', false, true );
+               $this->addOption( 'ip', 'IP to reset', false, true );
+       }
+
+       public function execute() {
+               $forLogin = (bool)$this->getOption( 'login' );
+               $forSignup = (bool)$this->getOption( 'signup' );
+               $username = $this->getOption( 'user' );
+               $ip = $this->getOption( 'ip' );
+
+               if ( !$forLogin && !$forSignup ) {
+                       $this->fatalError( 'At least one of --login and --signup is required!' );
+               } elseif ( $forLogin && ( $ip === null || $username === null ) ) {
+                       $this->fatalError( '--usename and --ip are both required when using --login!' );
+               } elseif ( $forSignup && $ip === null ) {
+                       $this->fatalError( '--ip is required when using --signup!' );
+               } elseif ( $ip !== null && !IP::isValid( $ip ) ) {
+                       $this->fatalError( "Not a valid IP: $ip" );
+               }
+
+               if ( $forLogin ) {
+                       $this->clearLoginThrottle( $username, $ip );
+               }
+               if ( $forSignup ) {
+                       $this->clearSignupThrottle( $ip );
+               }
+
+               LoggerFactory::getInstance( 'throttler' )->notice( 'Manually cleared {type} throttle', [
+                       'type' => implode( ' and ', array_filter( [
+                               $forLogin ? 'login' : null,
+                               $forSignup ? 'signup' : null,
+                       ] ) ),
+                       'username' => $username,
+                       'ipKey' => $ip,
+               ] );
+       }
+
+       /**
+        * @param string|null $rawUsername
+        * @param string|null $ip
+        */
+       protected function clearLoginThrottle( $rawUsername, $ip ) {
+               $this->output( 'Clearing login throttle... ' );
+
+               $passwordAttemptThrottle = $this->getConfig()->get( 'PasswordAttemptThrottle' );
+               if ( !$passwordAttemptThrottle ) {
+                       $this->output( "none set\n" );
+                       return;
+               }
+
+               $throttler = new Throttler( $passwordAttemptThrottle, [
+                       'type' => 'password',
+                       'cache' => ObjectCache::getLocalClusterInstance(),
+               ] );
+               if ( $rawUsername !== null ) {
+                       $usernames = AuthManager::singleton()->normalizeUsername( $rawUsername );
+                       if ( !$usernames ) {
+                               $this->fatalError( "Not a valid username: $rawUsername" );
+                       }
+               } else {
+                       $usernames = [ null ];
+               }
+               foreach ( $usernames as $username ) {
+                       $throttler->clear( $username, $ip );
+               }
+
+               $botPasswordThrottler = new Throttler( $passwordAttemptThrottle, [
+                       'type' => 'botpassword',
+                       'cache' => ObjectCache::getLocalClusterInstance(),
+               ] );
+               $botPasswordThrottler->clear( $username, $ip );
+
+               $this->output( "done\n" );
+       }
+
+       /**
+        * @param string $ip
+        */
+       protected function clearSignupThrottle( $ip ) {
+               $this->output( 'Clearing signup throttle... ' );
+
+               $accountCreationThrottle = $this->getConfig()->get( 'AccountCreationThrottle' );
+               if ( !is_array( $accountCreationThrottle ) ) {
+                       $accountCreationThrottle = [ [
+                               'count' => $accountCreationThrottle,
+                               'seconds' => 86400,
+                       ] ];
+               }
+               if ( !$accountCreationThrottle ) {
+                       $this->output( "none set\n" );
+                       return;
+               }
+               $throttler = new Throttler( $accountCreationThrottle, [
+                       'type' => 'acctcreate',
+                       'cache' => ObjectCache::getLocalClusterInstance(),
+               ] );
+
+               $throttler->clear( null, $ip );
+
+               $this->output( "done\n" );
+       }
+
+}
+
+$maintClass = ResetAuthenticationThrottle::class;
+require_once RUN_MAINTENANCE_IF_MAIN;
index f99bb7d..fd7b860 100755 (executable)
@@ -38,9 +38,9 @@ fi
 
 # Copy file(s)
 rsync --force ./node_modules/oojs/dist/oojs.jquery.js "$REPO_DIR/$TARGET_DIR"
-rsync --force ./node_modules/oojs/dist/AUTHORS.txt "$REPO_DIR/$TARGET_DIR"
-rsync --force ./node_modules/oojs/dist/LICENSE-MIT "$REPO_DIR/$TARGET_DIR"
-rsync --force ./node_modules/oojs/dist/README.md "$REPO_DIR/$TARGET_DIR"
+rsync --force ./node_modules/oojs/AUTHORS.txt "$REPO_DIR/$TARGET_DIR"
+rsync --force ./node_modules/oojs/LICENSE-MIT "$REPO_DIR/$TARGET_DIR"
+rsync --force ./node_modules/oojs/README.md "$REPO_DIR/$TARGET_DIR"
 
 # Clean up temporary area
 rm -rf "$NPM_DIR"
index 64eca95..39a5c5f 100644 (file)
@@ -32,7 +32,7 @@ use Wikimedia\Rdbms\IDatabase;
  *
  * @ingroup Maintenance
  */
-class BatchedQueryRunner extends Maintenance {
+class RunBatchedQuery extends Maintenance {
        public function __construct() {
                parent::__construct();
                $this->addDescription(
@@ -111,5 +111,5 @@ class BatchedQueryRunner extends Maintenance {
        }
 }
 
-$maintClass = BatchedQueryRunner::class;
+$maintClass = RunBatchedQuery::class;
 require_once RUN_MAINTENANCE_IF_MAIN;
index c8a8a45..a67417f 100644 (file)
@@ -67,8 +67,12 @@ class MediaWikiShell extends Maintenance {
                // add this after initializing the code cleaner so all the default passes get added first
                $traverser->addVisitor( new CodeCleanerGlobalsPass() );
 
-               $config = new \Psy\Configuration( [ 'codeCleaner' => $codeCleaner ] );
+               $config = new \Psy\Configuration();
+               $config->setCodeCleaner( $codeCleaner );
                $config->setUpdateCheck( \Psy\VersionUpdater\Checker::NEVER );
+               // prevent https://github.com/bobthecow/psysh/issues/443 when using sudo -E
+               $config->setRuntimeDir( wfTempDir() );
+
                $shell = new \Psy\Shell( $config );
                if ( $this->hasOption( 'd' ) ) {
                        $this->setupLegacy();
index 08f009b..1adb13e 100644 (file)
@@ -26,7 +26,7 @@
  * @author Brion Vibber
  * @author Rob Church <robchur@gmail.com>
  *
- * @license GNU General Public License 2.0 or later
+ * @license GPL-2.0-or-later
  */
 
 require_once __DIR__ . '/Maintenance.php';
index d9a018e..714726a 100644 (file)
@@ -300,7 +300,7 @@ CREATE INDEX /*i*/times ON /*_*/logging (log_timestamp);
 CREATE INDEX /*i*/log_user_type_time ON /*_*/logging (log_user, log_type, log_timestamp);
 CREATE INDEX /*i*/log_actor_type_time ON /*_*/logging (log_actor, log_type, log_timestamp);
 CREATE INDEX /*i*/log_page_id_time ON /*_*/logging (log_page,log_timestamp);
-CREATE INDEX /*i*/type_action ON /*_*/logging (log_type, log_action, log_timestamp);
+CREATE INDEX /*i*/log_type_action ON /*_*/logging (log_type, log_action, log_timestamp);
 CREATE INDEX /*i*/log_user_text_type_time ON /*_*/logging (log_user_text, log_type, log_timestamp);
 CREATE INDEX /*i*/log_user_text_time ON /*_*/logging (log_user_text, log_timestamp);
 
diff --git a/maintenance/sqlite/archives/patch-archive-ar_rev_id-unique.sql b/maintenance/sqlite/archives/patch-archive-ar_rev_id-unique.sql
new file mode 100644 (file)
index 0000000..9677dbb
--- /dev/null
@@ -0,0 +1,4 @@
+-- T193180: ar_rev_id should be unique
+
+CREATE UNIQUE INDEX /*i*/ar_revid_uniq ON /*_*/archive (ar_rev_id);
+DROP INDEX /*i*/ar_revid;
diff --git a/maintenance/sqlite/archives/patch-interwiki-fix-pk.sql b/maintenance/sqlite/archives/patch-interwiki-fix-pk.sql
new file mode 100644 (file)
index 0000000..f25f54c
--- /dev/null
@@ -0,0 +1,29 @@
+CREATE TABLE /*_*/interwiki_tmp (
+  -- The interwiki prefix, (e.g. "Meatball", or the language prefix "de")
+  iw_prefix varchar(32) NOT NULL PRIMARY KEY,
+
+  -- The URL of the wiki, with "$1" as a placeholder for an article name.
+  -- Any spaces in the name will be transformed to underscores before
+  -- insertion.
+  iw_url blob NOT NULL,
+
+  -- The URL of the file api.php
+  iw_api blob NOT NULL,
+
+  -- The name of the database (for a connection to be established with LBFactory::getMainLB( 'wikiid' ))
+  iw_wikiid varchar(64) NOT NULL,
+
+  -- A boolean value indicating whether the wiki is in this project
+  -- (used, for example, to detect redirect loops)
+  iw_local bool NOT NULL,
+
+  -- Boolean value indicating whether interwiki transclusions are allowed.
+  iw_trans tinyint NOT NULL default 0
+) /*$wgDBTableOptions*/;
+
+INSERT INTO /*_*/interwiki_tmp
+       SELECT * FROM /*_*/interwiki;
+
+DROP TABLE /*_*/interwiki;
+
+ALTER TABLE /*_*/interwiki_tmp RENAME TO /*_*/interwiki;
diff --git a/maintenance/sqlite/archives/patch-page_props-fix-pk.sql b/maintenance/sqlite/archives/patch-page_props-fix-pk.sql
new file mode 100644 (file)
index 0000000..3a40d86
--- /dev/null
@@ -0,0 +1,18 @@
+CREATE TABLE /*_*/page_props_tmp (
+  pp_page int NOT NULL,
+  pp_propname varbinary(60) NOT NULL,
+  pp_value blob NOT NULL,
+  pp_sortkey float DEFAULT NULL,
+
+  PRIMARY KEY (pp_page,pp_propname)
+) /*$wgDBTableOptions*/;
+
+INSERT INTO /*_*/page_props_tmp
+       SELECT * FROM /*_*/page_props;
+
+DROP TABLE /*_*/page_props;
+
+ALTER TABLE /*_*/page_props_tmp RENAME TO /*_*/page_props;
+
+CREATE UNIQUE INDEX /*i*/pp_propname_page ON /*_*/page_props (pp_propname,pp_page);
+CREATE UNIQUE INDEX /*i*/pp_propname_sortkey_page ON /*_*/page_props (pp_propname,pp_sortkey,pp_page);
\ No newline at end of file
diff --git a/maintenance/sqlite/archives/patch-protected_titles-fix-pk.sql b/maintenance/sqlite/archives/patch-protected_titles-fix-pk.sql
new file mode 100644 (file)
index 0000000..0832214
--- /dev/null
@@ -0,0 +1,21 @@
+CREATE TABLE /*_*/protected_titles_tmp (
+  pt_namespace int NOT NULL,
+  pt_title varchar(255) binary NOT NULL,
+  pt_user int unsigned NOT NULL,
+  pt_reason varbinary(767) default '', -- Deprecated.
+  pt_reason_id bigint unsigned NOT NULL DEFAULT 0, -- ("DEFAULT 0" is temporary, signaling that pt_reason should be used)
+  pt_timestamp binary(14) NOT NULL,
+  pt_expiry varbinary(14) NOT NULL default '',
+  pt_create_perm varbinary(60) NOT NULL,
+
+  PRIMARY KEY (pt_namespace,pt_title)
+) /*$wgDBTableOptions*/;
+
+INSERT INTO /*_*/protected_titles_tmp
+       SELECT * FROM /*_*/protected_titles;
+
+DROP TABLE /*_*/protected_titles;
+
+ALTER TABLE /*_*/protected_titles_tmp RENAME TO /*_*/protected_titles;
+
+CREATE INDEX /*i*/pt_timestamp ON /*_*/protected_titles (pt_timestamp);
diff --git a/maintenance/sqlite/archives/patch-site_identifiers-fix-pk.sql b/maintenance/sqlite/archives/patch-site_identifiers-fix-pk.sql
new file mode 100644 (file)
index 0000000..7ceadb7
--- /dev/null
@@ -0,0 +1,22 @@
+CREATE TABLE /*_*/site_identifiers_tmp (
+  -- Key on site.site_id
+  si_site                    INT UNSIGNED        NOT NULL,
+
+  -- local key type, ie 'interwiki' or 'langlink'
+  si_type                    varbinary(32)       NOT NULL,
+
+  -- local key value, ie 'en' or 'wiktionary'
+  si_key                     varbinary(32)       NOT NULL,
+
+  PRIMARY KEY (si_type, si_key)
+) /*$wgDBTableOptions*/;
+
+INSERT INTO /*_*/site_identifiers_tmp
+       SELECT * FROM /*_*/site_identifiers;
+
+DROP TABLE /*_*/site_identifiers;
+
+ALTER TABLE /*_*/site_identifiers_tmp RENAME TO /*_*/site_identifiers;
+
+CREATE INDEX /*i*/site_ids_site ON /*_*/site_identifiers (si_site);
+CREATE INDEX /*i*/site_ids_key ON /*_*/site_identifiers (si_key);
\ No newline at end of file
index bd0556a..0ec24af 100644 (file)
@@ -502,7 +502,7 @@ class CheckStorage {
        function importRevision( &$revision, &$importer ) {
                $id = $revision->getID();
                $content = $revision->getContent( Revision::RAW );
-               $id = $id ? $id : '';
+               $id = $id ?: '';
 
                if ( $content === null ) {
                        echo "Revision $id is broken, we have no content available\n";
index 9bb554c..639ef58 100644 (file)
@@ -43,7 +43,7 @@ if ( !defined( 'MEDIAWIKI' ) ) {
        } else {
                $maxID = $dbw->selectField( 'text', 'MAX(old_id)', '', $fname );
        }
-       $minID = isset( $options['s'] ) ? $options['s'] : 1;
+       $minID = $options['s'] ?? 1;
 
        moveToExternal( $cluster, $maxID, $minID );
 }
index 49b8e0a..7f36442 100644 (file)
@@ -24,6 +24,7 @@
 
 use MediaWiki\Logger\LegacyLogger;
 use MediaWiki\MediaWikiServices;
+use Wikimedia\Rdbms\IDatabase;
 
 $optionsWithArgs = RecompressTracked::getOptionsWithArgs();
 require __DIR__ . '/../commandLine.inc';
@@ -226,7 +227,7 @@ class RecompressTracked {
                }
                $cmd .= ' --child' .
                        ' --wiki ' . wfEscapeShellArg( wfWikiID() ) .
-                       ' ' . call_user_func_array( 'wfEscapeShellArg', $this->destClusters );
+                       ' ' . wfEscapeShellArg( ...$this->destClusters );
 
                $this->replicaPipes = $this->replicaProcs = [];
                for ( $i = 0; $i < $this->numProcs; $i++ ) {
@@ -426,12 +427,12 @@ class RecompressTracked {
                                $args = array_slice( $ids, 0, $this->orphanBatchSize );
                                $ids = array_slice( $ids, $this->orphanBatchSize );
                                array_unshift( $args, 'doOrphanList' );
-                               call_user_func_array( [ $this, 'dispatch' ], $args );
+                               $this->dispatch( ...$args );
                        }
                        if ( count( $ids ) ) {
                                $args = $ids;
                                array_unshift( $args, 'doOrphanList' );
-                               call_user_func_array( [ $this, 'dispatch' ], $args );
+                               $this->dispatch( ...$args );
                        }
 
                        $this->report( 'orphans', $i, $numOrphans );
@@ -640,7 +641,7 @@ class RecompressTracked {
        /**
         * Gets a DB master connection for the given external cluster name
         * @param string $cluster
-        * @return Database
+        * @return IDatabase
         */
        function getExtDB( $cluster ) {
                $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
index 9ba3d1b..af9dd08 100644 (file)
@@ -31,7 +31,7 @@ class StorageTypeStats extends Maintenance {
                        exit( 1 );
                }
 
-               $binSize = intval( pow( 10, floor( log10( $endId ) ) - 3 ) );
+               $binSize = intval( 10 ** ( floor( log10( $endId ) ) - 3 ) );
                if ( $binSize < 100 ) {
                        $binSize = 100;
                }
index c3ed4fc..7cac728 100644 (file)
@@ -45,7 +45,7 @@ if ( isset( $options['limit'] ) ) {
        $limit = 1000;
        $untilHappy = true;
 }
-$type = isset( $options['type'] ) ? $options['type'] : ConcatenatedGzipHistoryBlob::class;
+$type = $options['type'] ?? ConcatenatedGzipHistoryBlob::class;
 
 $dbr = $this->getDB( DB_REPLICA );
 $revQuery = Revision::getQueryInfo( [ 'page', 'text' ] );
index 36b6f5b..2dd48ca 100644 (file)
@@ -122,7 +122,7 @@ class TrackBlobs {
                return [
                        'cluster' => $m[1],
                        'id' => intval( $m[2] ),
-                       'hash' => isset( $m[3] ) ? $m[3] : null
+                       'hash' => $m[3] ?? null
                ];
        }
 
index 53c1529..b503bba 100644 (file)
@@ -667,7 +667,7 @@ CREATE INDEX /*i*/ar_actor_timestamp ON /*_*/archive (ar_actor,ar_timestamp);
 
 -- Index for linking archive rows with tables that normally link with revision
 -- rows, such as change_tag.
-CREATE INDEX /*i*/ar_revid ON /*_*/archive (ar_rev_id);
+CREATE UNIQUE INDEX /*i*/ar_revid_uniq ON /*_*/archive (ar_rev_id);
 
 --
 -- Slots represent an n:m relation between revisions and content objects.
@@ -1529,7 +1529,7 @@ CREATE FULLTEXT INDEX /*i*/si_text ON /*_*/searchindex (si_text);
 --
 CREATE TABLE /*_*/interwiki (
   -- The interwiki prefix, (e.g. "Meatball", or the language prefix "de")
-  iw_prefix varchar(32) NOT NULL,
+  iw_prefix varchar(32) NOT NULL PRIMARY KEY,
 
   -- The URL of the wiki, with "$1" as a placeholder for an article name.
   -- Any spaces in the name will be transformed to underscores before
@@ -1550,8 +1550,6 @@ CREATE TABLE /*_*/interwiki (
   iw_trans tinyint NOT NULL default 0
 ) /*$wgDBTableOptions*/;
 
-CREATE UNIQUE INDEX /*i*/iw_prefix ON /*_*/interwiki (iw_prefix);
-
 
 --
 -- Used for caching expensive grouped queries
@@ -1658,7 +1656,7 @@ CREATE INDEX /*i*/log_actor_type_time ON /*_*/logging (log_actor, log_type, log_
 CREATE INDEX /*i*/log_page_id_time ON /*_*/logging (log_page,log_timestamp);
 
 -- Special:Log action filter
-CREATE INDEX /*i*/type_action ON /*_*/logging (log_type, log_action, log_timestamp);
+CREATE INDEX /*i*/log_type_action ON /*_*/logging (log_type, log_action, log_timestamp);
 
 -- Special:Log filter by type and anonymous performer
 CREATE INDEX /*i*/log_user_text_type_time ON /*_*/logging (log_user_text, log_type, log_timestamp);
@@ -1807,10 +1805,11 @@ CREATE TABLE /*_*/protected_titles (
   pt_reason_id bigint unsigned NOT NULL DEFAULT 0, -- ("DEFAULT 0" is temporary, signaling that pt_reason should be used)
   pt_timestamp binary(14) NOT NULL,
   pt_expiry varbinary(14) NOT NULL default '',
-  pt_create_perm varbinary(60) NOT NULL
+  pt_create_perm varbinary(60) NOT NULL,
+
+  PRIMARY KEY (pt_namespace,pt_title)
 ) /*$wgDBTableOptions*/;
 
-CREATE UNIQUE INDEX /*i*/pt_namespace_title ON /*_*/protected_titles (pt_namespace,pt_title);
 CREATE INDEX /*i*/pt_timestamp ON /*_*/protected_titles (pt_timestamp);
 
 
@@ -1819,10 +1818,11 @@ CREATE TABLE /*_*/page_props (
   pp_page int NOT NULL,
   pp_propname varbinary(60) NOT NULL,
   pp_value blob NOT NULL,
-  pp_sortkey float DEFAULT NULL
+  pp_sortkey float DEFAULT NULL,
+
+  PRIMARY KEY (pp_page,pp_propname)
 ) /*$wgDBTableOptions*/;
 
-CREATE UNIQUE INDEX /*i*/pp_page_propname ON /*_*/page_props (pp_page,pp_propname);
 CREATE UNIQUE INDEX /*i*/pp_propname_page ON /*_*/page_props (pp_propname,pp_page);
 CREATE UNIQUE INDEX /*i*/pp_propname_sortkey_page ON /*_*/page_props (pp_propname,pp_sortkey,pp_page);
 
@@ -1962,10 +1962,11 @@ CREATE TABLE /*_*/site_identifiers (
   si_type                    varbinary(32)       NOT NULL,
 
   -- local key value, ie 'en' or 'wiktionary'
-  si_key                     varbinary(32)       NOT NULL
+  si_key                     varbinary(32)       NOT NULL,
+
+  PRIMARY KEY (si_type, si_key)
 ) /*$wgDBTableOptions*/;
 
-CREATE UNIQUE INDEX /*i*/site_ids_type ON /*_*/site_identifiers (si_type, si_key);
 CREATE INDEX /*i*/site_ids_site ON /*_*/site_identifiers (si_site);
 CREATE INDEX /*i*/site_ids_key ON /*_*/site_identifiers (si_key);
 
index d88d5e9..0670454 100644 (file)
@@ -187,13 +187,7 @@ TEXT
                                }
                                # cl_type will be wrong for lots of pages if cl_collation is 0,
                                # so let's update it while we're here.
-                               if ( $title->getNamespace() == NS_CATEGORY ) {
-                                       $type = 'subcat';
-                               } elseif ( $title->getNamespace() == NS_FILE ) {
-                                       $type = 'file';
-                               } else {
-                                       $type = 'page';
-                               }
+                               $type = MWNamespace::getCategoryLinkType( $title->getNamespace() );
                                $newSortKey = $collation->getSortKey(
                                        $title->getCategorySortkey( $prefix ) );
                                if ( $verboseStats ) {
index 1491e62..01aace0 100644 (file)
@@ -51,7 +51,7 @@ class UpdateSpecialPages extends Maintenance {
 
                foreach ( QueryPage::getPages() as $page ) {
                        list( $class, $special ) = $page;
-                       $limit = isset( $page[2] ) ? $page[2] : null;
+                       $limit = $page[2] ?? null;
 
                        # --list : just show the name of pages
                        if ( $this->hasOption( 'list' ) ) {
@@ -84,7 +84,7 @@ class UpdateSpecialPages extends Maintenance {
                                if ( $queryPage->isExpensive() ) {
                                        $t1 = microtime( true );
                                        # Do the query
-                                       $num = $queryPage->recache( $limit === null ? $wgQueryCacheLimit : $limit );
+                                       $num = $queryPage->recache( $limit ?? $wgQueryCacheLimit );
                                        $t2 = microtime( true );
                                        if ( $num === false ) {
                                                $this->output( "FAILED: database error\n" );
index 1f23b1a..070fad8 100644 (file)
@@ -5,18 +5,19 @@
     "qunit": "grunt qunit",
     "doc": "jsduck",
     "postdoc": "grunt copy:jsduck",
-    "selenium": "./tests/selenium/selenium.sh",
+    "selenium": "bash ./tests/selenium/selenium.sh",
     "selenium-test": "wdio ./tests/selenium/wdio.conf.js"
   },
   "devDependencies": {
     "deepmerge": "1.3.2",
-    "eslint": "4.9.0",
-    "eslint-config-wikimedia": "0.5.0",
-    "grunt": "1.0.1",
+    "eslint": "5.0.1",
+    "eslint-config-wikimedia": "0.6.0",
+    "eslint-plugin-qunit": "3.2.1",
+    "grunt": "1.0.3",
     "grunt-banana-checker": "0.6.0",
     "grunt-contrib-copy": "1.0.0",
-    "grunt-contrib-watch": "1.0.1",
-    "grunt-eslint": "20.1.0",
+    "grunt-contrib-watch": "1.1.0",
+    "grunt-eslint": "21.0.0",
     "grunt-jsonlint": "1.1.0",
     "grunt-karma": "2.0.0",
     "grunt-stylelint": "0.10.0",
index ca8c1bb..8bd37dd 100644 (file)
@@ -291,24 +291,26 @@ function compare_point( profile_point $a, profile_point $b ) {
        global $sort;
 
        switch ( $sort ) {
+               // Sorted ascending:
                case 'name':
                        return strcmp( $a->name(), $b->name() );
+               // Sorted descending:
                case 'time':
-                       return $a->time() > $b->time() ? -1 : 1;
+                       return $b->time() <=> $a->time();
                case 'memory':
-                       return $a->memory() > $b->memory() ? -1 : 1;
+                       return $b->memory() <=> $a->memory();
                case 'count':
-                       return $a->count() > $b->count() ? -1 : 1;
+                       return $b->count() <=> $a->count();
                case 'time_per_call':
-                       return $a->timePerCall() > $b->timePerCall() ? -1 : 1;
+                       return $b->timePerCall() <=> $a->timePerCall();
                case 'memory_per_call':
-                       return $a->memoryPerCall() > $b->memoryPerCall() ? -1 : 1;
+                       return $b->memoryPerCall() <=> $a->memoryPerCall();
                case 'calls_per_req':
-                       return $a->callsPerRequest() > $b->callsPerRequest() ? -1 : 1;
+                       return $b->callsPerRequest() <=> $a->callsPerRequest();
                case 'time_per_req':
-                       return $a->timePerRequest() > $b->timePerRequest() ? -1 : 1;
+                       return $b->timePerRequest() <=> $a->timePerRequest();
                case 'memory_per_req':
-                       return $a->memoryPerRequest() > $b->memoryPerRequest() ? -1 : 1;
+                       return $b->memoryPerRequest() <=> $a->memoryPerRequest();
        }
 }
 
@@ -394,8 +396,8 @@ if ( isset( $_REQUEST['filter'] ) ) {
                return htmlspecialchars(
                        '?' .
                                wfArrayToCgi( [
-                                       'filter' => $_filter ? $_filter : $filter,
-                                       'sort' => $_sort ? $_sort : $sort,
+                                       'filter' => $_filter ?: $filter,
+                                       'sort' => $_sort ?: $sort,
                                        'expand' => implode( ',', array_keys( $_expand ) )
                                ] )
                );
index 56dfaf9..c63eb96 100644 (file)
@@ -58,9 +58,6 @@ return [
        'user.options' => [ 'class' => ResourceLoaderUserOptionsModule::class ],
        'user.tokens' => [ 'class' => ResourceLoaderUserTokensModule::class ],
 
-       // Scripts for the dynamic language specific data, like grammar forms.
-       'mediawiki.language.data' => [ 'class' => ResourceLoaderLanguageDataModule::class ],
-
        /* MediaWiki base skinning modules */
 
        /**
@@ -84,8 +81,7 @@ return [
         *     The highest level, this stylesheet contains extra common styles for classes like
         *     .firstHeading, #contentSub, et cetera which are not outputted by MediaWiki but are common
         *     to skins like MonoBook, Vector, etc... Essentially this level is for styles that are
-        *     common to MonoBook clones. And since practically every skin that currently exists within
-        *     core is a MonoBook clone, all our core skins currently use this level.
+        *     common to MonoBook clones.
         *
         * These modules are typically loaded by addModuleStyles(), which has absolutely no concept of
         * dependency management. As a result they contain duplicate stylesheet references instead of
@@ -115,6 +111,10 @@ return [
        'jquery.makeCollapsible.styles' => [
                'targets' => [ 'desktop', 'mobile' ],
                'class' => ResourceLoaderLessVarFileModule::class,
+               'lessMessages' => [
+                       'collapsible-collapse',
+                       'collapsible-expand',
+               ],
                'styles' => [
                        'resources/src/jquery/jquery.makeCollapsible.styles.less',
                ],
@@ -224,6 +224,7 @@ return [
                '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' ],
        ],
@@ -317,17 +318,10 @@ return [
                'styles' => 'resources/src/jquery.tablesorter/jquery.tablesorter.less',
                'messages' => [ 'sort-descending', 'sort-ascending' ],
                'dependencies' => [
-                       'jquery.tablesorter.styles',
                        'mediawiki.RegExp',
                        'mediawiki.language.months',
                ],
        ],
-       'jquery.tablesorter.styles' => [
-               'targets' => [ 'desktop', 'mobile' ],
-               'styles' => [
-                       'resources/src/jquery/jquery.tablesorter.styles.less',
-               ],
-       ],
        'jquery.textSelection' => [
                'scripts' => 'resources/src/jquery/jquery.textSelection.js',
                'dependencies' => 'jquery.client',
@@ -708,12 +702,6 @@ return [
                'group' => 'jquery.ui',
        ],
 
-       /* json2 */
-       'json' => [
-               'deprecated' => 'Use of the "json" module is deprecated since MediaWiki 1.29.0',
-               'targets' => [ 'desktop', 'mobile' ],
-       ],
-
        /* Moment.js */
 
        'moment' => [
@@ -845,15 +833,12 @@ return [
 
        /* MediaWiki */
 
-       'mediawiki' => [
-               'class' => ResourceLoaderRawFileModule::class,
+       'mediawiki.base' => [
                // Keep in sync with maintenance/jsduck/eg-iframe.html
                'scripts' => [
-                       'resources/src/mediawiki/mediawiki.js',
-                       'resources/src/mediawiki/mediawiki.requestIdleCallback.js',
-                       'resources/src/mediawiki/mediawiki.errorLogger.js',
+                       'resources/src/mediawiki.base/mediawiki.errorLogger.js',
+                       'resources/src/mediawiki.base/mediawiki.base.js',
                ],
-               'debugScripts' => 'resources/src/mediawiki/mediawiki.log.js',
                'targets' => [ 'desktop', 'mobile' ],
        ],
        'mediawiki.apihelp' => [
@@ -1047,12 +1032,6 @@ return [
                ],
                'targets' => [ 'desktop', 'mobile' ],
        ],
-       'mediawiki.hidpi' => [
-               'scripts' => 'resources/src/mediawiki.hidpi/hidpi.js',
-               'dependencies' => 'jquery.hidpi',
-               'skipFunction' => 'resources/src/mediawiki.hidpi/skip.js',
-               'targets' => [ 'desktop', 'mobile' ],
-       ],
        'mediawiki.hlist' => [
                'targets' => [ 'desktop', 'mobile' ],
                'styles' => [
@@ -1349,6 +1328,18 @@ return [
                'messages' => [ 'showtoc', 'hidetoc' ],
                'targets' => [ 'desktop', 'mobile' ],
        ],
+       'mediawiki.toc.styles' => [
+               'class' => ResourceLoaderLessVarFileModule::class,
+               'lessMessages' => [ 'hidetoc', 'showtoc' ],
+               'styles' => [
+                       'resources/src/mediawiki.toc.styles/common.css',
+                       'resources/src/mediawiki.toc.styles/screen.less'
+                               => [ 'media' => 'screen' ],
+                       'resources/src/mediawiki.toc.styles/print.css'
+                               => [ 'media' => 'print' ],
+               ],
+               'targets' => [ 'desktop', 'mobile' ],
+       ],
        'mediawiki.Uri' => [
                'scripts' => 'resources/src/mediawiki.Uri/Uri.js',
                'templates' => [
@@ -1579,7 +1570,9 @@ return [
        /* MediaWiki Language */
 
        'mediawiki.language' => [
+               'class' => ResourceLoaderLanguageDataModule::class,
                'scripts' => [
+                       'resources/src/mediawiki.language/mediawiki.language.init.js',
                        'resources/src/mediawiki.language/mediawiki.language.js',
                        'resources/src/mediawiki.language/mediawiki.language.numbers.js',
                        'resources/src/mediawiki.language/mediawiki.language.fallback.js',
@@ -1597,10 +1590,8 @@ return [
                        'sl' => 'resources/src/mediawiki.language/languages/sl.js',
                ],
                'dependencies' => [
-                       'mediawiki.language.data',
                        'mediawiki.cldr',
                ],
-               'targets' => [ 'desktop', 'mobile' ],
                'messages' => [
                        'and',
                        'comma-separator',
@@ -1624,11 +1615,6 @@ return [
                'targets' => [ 'desktop', 'mobile' ],
        ],
 
-       'mediawiki.language.init' => [
-               'scripts' => 'resources/src/mediawiki.language/mediawiki.language.init.js',
-               'targets' => [ 'desktop', 'mobile' ],
-       ],
-
        'mediawiki.jqueryMsg' => [
                // Add data for mediawiki.jqueryMsg, such as allowed tags
                'class' => ResourceLoaderJqueryMsgModule::class,
@@ -1704,7 +1690,6 @@ return [
                'dependencies' => [
                        'jquery.accessKeyLabel',
                        'jquery.checkboxShiftClick',
-                       'jquery.mw-jump',
                ],
                'targets' => [ 'desktop', 'mobile' ],
        ],
@@ -1838,6 +1823,7 @@ return [
                        'resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.SaveFiltersPopupButtonWidget.js',
                        'resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FormWrapperWidget.js',
                        'resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterItemHighlightButton.js',
+                       'resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.HighlightPopupWidget.js',
                        'resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.HighlightColorPickerWidget.js',
                        'resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.LiveUpdateButtonWidget.js',
                        'resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.MarkSeenButtonWidget.js',
@@ -1891,6 +1877,10 @@ return [
                'messages' => [
                        'rcfilters-tag-remove',
                        'rcfilters-activefilters',
+                       'rcfilters-activefilters-hide',
+                       'rcfilters-activefilters-show',
+                       'rcfilters-activefilters-hide-tooltip',
+                       'rcfilters-activefilters-show-tooltip',
                        'rcfilters-advancedfilters',
                        'rcfilters-group-results-by-page',
                        'rcfilters-limit-title',
@@ -1990,6 +1980,7 @@ return [
                        'resources/src/mediawiki.special/comparepages.less',
                        'resources/src/mediawiki.special/edittags.css',
                        'resources/src/mediawiki.special/movePage.css',
+                       'resources/src/mediawiki.special/newpages.less',
                        'resources/src/mediawiki.special/pagesWithProp.css',
                        'resources/src/mediawiki.special/upload.css',
                        'resources/src/mediawiki.special/userrights.css',
@@ -2198,7 +2189,7 @@ return [
        ],
        'mediawiki.special.preferences.styles.ooui' => [
                'targets' => [ 'desktop', 'mobile' ],
-               'styles' => 'resources/src/mediawiki.special.preferences.styles.ooui.css',
+               'styles' => 'resources/src/mediawiki.special.preferences.styles.ooui.less',
        ],
        'mediawiki.special.recentchanges' => [
                'scripts' => 'resources/src/mediawiki.special.recentchanges.js',
@@ -2642,7 +2633,7 @@ return [
        ],
        'mediawiki.widgets.CategoryMultiselectWidget' => [
                'scripts' => [
-                       'resources/src/mediawiki.widgets/mw.widgets.CategoryCapsuleItemWidget.js',
+                       'resources/src/mediawiki.widgets/mw.widgets.CategoryTagItemWidget.js',
                        'resources/src/mediawiki.widgets/mw.widgets.CategoryMultiselectWidget.js',
                ],
                'dependencies' => [
@@ -2767,12 +2758,6 @@ return [
                ],
        ],
 
-       /* dom-level2-shim */
-       'dom-level2-shim' => [
-               'deprecated' => 'Use of the "dom-level2-shim" module is deprecated since MediaWiki 1.29.0',
-               'targets' => [ 'desktop', 'mobile' ],
-       ],
-
        /**
         * html5shiv
         *
@@ -2788,6 +2773,25 @@ return [
                'raw' => true,
        ],
 
+       /* EasyDeflate */
+
+       'easy-deflate.core' => [
+               'scripts' => [ 'resources/lib/easy-deflate/easydeflate.js' ],
+               'targets' => [ 'desktop', 'mobile' ],
+       ],
+
+       'easy-deflate.deflate' => [
+               'scripts' => [ 'resources/lib/easy-deflate/deflate.js' ],
+               'dependencies' => [ 'easy-deflate.core' ],
+               'targets' => [ 'desktop', 'mobile' ],
+       ],
+
+       'easy-deflate.inflate' => [
+               'scripts' => [ 'resources/lib/easy-deflate/inflate.js' ],
+               'dependencies' => [ 'easy-deflate.core' ],
+               'targets' => [ 'desktop', 'mobile' ],
+       ],
+
        /* OOjs */
        'oojs' => [
                'scripts' => [
diff --git a/resources/lib/easy-deflate/README.md b/resources/lib/easy-deflate/README.md
new file mode 100644 (file)
index 0000000..9b3d07e
--- /dev/null
@@ -0,0 +1,38 @@
+Modified version of Easy-Deflate https://github.com/Jacob-Christian-Munch-Andersen/Easy-Deflate
+
+This version: https://github.com/edg2s/Easy-Deflate
+
+* Added semi-colons to easydeflate.js so it can be minified
+* Namespaced functions inside global EasyDeflate object
+* Base64 lib replaced with one with detailed license info
+
+Modifications by Ed Sanders, Public Domain.
+
+Easy-Deflate
+============
+
+Library for compressing and decompressing strings in JavaScript, feature full Unicode support and is compatible with most browsers.
+
+Use:
+====
+Copy the script inclusion from demo.html.<br>
+Call EasyDeflate.deflate(foo) in order to compress a string.<br>
+Call EasyDeflate.inflate(bar) in order to decompress a string compressed in this manner.<br>
+Both functions return a string, or null in case of illegal input.
+
+The compression works by first UTF-8 encoding the input, then compressing it to a raw deflate stream. The stream is then base64 encoded, and finally the identifier "rawdeflate," is prepended.
+
+Credits:
+========
+Gildas Lormeau made the JavaScript conversion of a Deflate utility: https://github.com/gildas-lormeau/zip.js<br>
+Jacob Christian Munch-Andersen made this package in order to make simple use easier and compatible with older browsers.
+
+The following shims are included:<br>
+es5-shim by Kristopher Michael Kowal https://github.com/kriskowal/es5-shim<br>
+JSON 3 by Kit Cambridge http://bestiejs.github.com/json3/<br>
+Typed arrays light shim by Jacob Christian Munch-Andersen https://github.com/Jacob-Christian-Munch-Andersen/Typed-arrays-light-shim<br>
+<s>base64 by Yaffle https://gist.github.com/1284012</s>
+
+License:
+========
+Main packages come with a BSD licence, the shims, except for base64 that include no license text, each has a permissive license.
diff --git a/resources/lib/easy-deflate/deflate.js b/resources/lib/easy-deflate/deflate.js
new file mode 100644 (file)
index 0000000..665bfb1
--- /dev/null
@@ -0,0 +1,2088 @@
+/*
+ Copyright (c) 2013 Gildas Lormeau. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright 
+ notice, this list of conditions and the following disclaimer in 
+ the documentation and/or other materials provided with the distribution.
+
+ 3. The names of the authors may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+ INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This program is based on JZlib 1.0.2 ymnk, JCraft,Inc.
+ * JZlib is based on zlib-1.1.3, so all credit should go authors
+ * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu)
+ * and contributors of zlib.
+ */
+
+(function(obj) {
+
+       // Global
+
+       var MAX_BITS = 15;
+       var D_CODES = 30;
+       var BL_CODES = 19;
+
+       var LENGTH_CODES = 29;
+       var LITERALS = 256;
+       var L_CODES = (LITERALS + 1 + LENGTH_CODES);
+       var HEAP_SIZE = (2 * L_CODES + 1);
+
+       var END_BLOCK = 256;
+
+       // Bit length codes must not exceed MAX_BL_BITS bits
+       var MAX_BL_BITS = 7;
+
+       // repeat previous bit length 3-6 times (2 bits of repeat count)
+       var REP_3_6 = 16;
+
+       // repeat a zero length 3-10 times (3 bits of repeat count)
+       var REPZ_3_10 = 17;
+
+       // repeat a zero length 11-138 times (7 bits of repeat count)
+       var REPZ_11_138 = 18;
+
+       // The lengths of the bit length codes are sent in order of decreasing
+       // probability, to avoid transmitting the lengths for unused bit
+       // length codes.
+
+       var Buf_size = 8 * 2;
+
+       // JZlib version : "1.0.2"
+       var Z_DEFAULT_COMPRESSION = -1;
+
+       // compression strategy
+       var Z_FILTERED = 1;
+       var Z_HUFFMAN_ONLY = 2;
+       var Z_DEFAULT_STRATEGY = 0;
+
+       var Z_NO_FLUSH = 0;
+       var Z_PARTIAL_FLUSH = 1;
+       var Z_FULL_FLUSH = 3;
+       var Z_FINISH = 4;
+
+       var Z_OK = 0;
+       var Z_STREAM_END = 1;
+       var Z_NEED_DICT = 2;
+       var Z_STREAM_ERROR = -2;
+       var Z_DATA_ERROR = -3;
+       var Z_BUF_ERROR = -5;
+
+       // Tree
+
+       // see definition of array dist_code below
+       var _dist_code = [ 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+                       10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+                       12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+                       13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+                       14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+                       14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+                       15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, 18, 18, 19, 19,
+                       20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+                       24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+                       26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+                       27, 27, 27, 27, 27, 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+                       28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 29,
+                       29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+                       29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 ];
+
+       function Tree() {
+               var that = this;
+
+               // dyn_tree; // the dynamic tree
+               // max_code; // largest code with non zero frequency
+               // stat_desc; // the corresponding static tree
+
+               // Compute the optimal bit lengths for a tree and update the total bit
+               // length
+               // for the current block.
+               // IN assertion: the fields freq and dad are set, heap[heap_max] and
+               // above are the tree nodes sorted by increasing frequency.
+               // OUT assertions: the field len is set to the optimal bit length, the
+               // array bl_count contains the frequencies for each bit length.
+               // The length opt_len is updated; static_len is also updated if stree is
+               // not null.
+               function gen_bitlen(s) {
+                       var tree = that.dyn_tree;
+                       var stree = that.stat_desc.static_tree;
+                       var extra = that.stat_desc.extra_bits;
+                       var base = that.stat_desc.extra_base;
+                       var max_length = that.stat_desc.max_length;
+                       var h; // heap index
+                       var n, m; // iterate over the tree elements
+                       var bits; // bit length
+                       var xbits; // extra bits
+                       var f; // frequency
+                       var overflow = 0; // number of elements with bit length too large
+
+                       for (bits = 0; bits <= MAX_BITS; bits++)
+                               s.bl_count[bits] = 0;
+
+                       // In a first pass, compute the optimal bit lengths (which may
+                       // overflow in the case of the bit length tree).
+                       tree[s.heap[s.heap_max] * 2 + 1] = 0; // root of the heap
+
+                       for (h = s.heap_max + 1; h < HEAP_SIZE; h++) {
+                               n = s.heap[h];
+                               bits = tree[tree[n * 2 + 1] * 2 + 1] + 1;
+                               if (bits > max_length) {
+                                       bits = max_length;
+                                       overflow++;
+                               }
+                               tree[n * 2 + 1] = bits;
+                               // We overwrite tree[n*2+1] which is no longer needed
+
+                               if (n > that.max_code)
+                                       continue; // not a leaf node
+
+                               s.bl_count[bits]++;
+                               xbits = 0;
+                               if (n >= base)
+                                       xbits = extra[n - base];
+                               f = tree[n * 2];
+                               s.opt_len += f * (bits + xbits);
+                               if (stree)
+                                       s.static_len += f * (stree[n * 2 + 1] + xbits);
+                       }
+                       if (overflow === 0)
+                               return;
+
+                       // This happens for example on obj2 and pic of the Calgary corpus
+                       // Find the first bit length which could increase:
+                       do {
+                               bits = max_length - 1;
+                               while (s.bl_count[bits] === 0)
+                                       bits--;
+                               s.bl_count[bits]--; // move one leaf down the tree
+                               s.bl_count[bits + 1] += 2; // move one overflow item as its brother
+                               s.bl_count[max_length]--;
+                               // The brother of the overflow item also moves one step up,
+                               // but this does not affect bl_count[max_length]
+                               overflow -= 2;
+                       } while (overflow > 0);
+
+                       for (bits = max_length; bits !== 0; bits--) {
+                               n = s.bl_count[bits];
+                               while (n !== 0) {
+                                       m = s.heap[--h];
+                                       if (m > that.max_code)
+                                               continue;
+                                       if (tree[m * 2 + 1] != bits) {
+                                               s.opt_len += (bits - tree[m * 2 + 1]) * tree[m * 2];
+                                               tree[m * 2 + 1] = bits;
+                                       }
+                                       n--;
+                               }
+                       }
+               }
+
+               // Reverse the first len bits of a code, using straightforward code (a
+               // faster
+               // method would use a table)
+               // IN assertion: 1 <= len <= 15
+               function bi_reverse(code, // the value to invert
+               len // its bit length
+               ) {
+                       var res = 0;
+                       do {
+                               res |= code & 1;
+                               code >>>= 1;
+                               res <<= 1;
+                       } while (--len > 0);
+                       return res >>> 1;
+               }
+
+               // Generate the codes for a given tree and bit counts (which need not be
+               // optimal).
+               // IN assertion: the array bl_count contains the bit length statistics for
+               // the given tree and the field len is set for all tree elements.
+               // OUT assertion: the field code is set for all tree elements of non
+               // zero code length.
+               function gen_codes(tree, // the tree to decorate
+               max_code, // largest code with non zero frequency
+               bl_count // number of codes at each bit length
+               ) {
+                       var next_code = []; // next code value for each
+                       // bit length
+                       var code = 0; // running code value
+                       var bits; // bit index
+                       var n; // code index
+                       var len;
+
+                       // The distribution counts are first used to generate the code values
+                       // without bit reversal.
+                       for (bits = 1; bits <= MAX_BITS; bits++) {
+                               next_code[bits] = code = ((code + bl_count[bits - 1]) << 1);
+                       }
+
+                       // Check that the bit counts in bl_count are consistent. The last code
+                       // must be all ones.
+                       // Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
+                       // "inconsistent bit counts");
+                       // Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
+
+                       for (n = 0; n <= max_code; n++) {
+                               len = tree[n * 2 + 1];
+                               if (len === 0)
+                                       continue;
+                               // Now reverse the bits
+                               tree[n * 2] = bi_reverse(next_code[len]++, len);
+                       }
+               }
+
+               // Construct one Huffman tree and assigns the code bit strings and lengths.
+               // Update the total bit length for the current block.
+               // IN assertion: the field freq is set for all tree elements.
+               // OUT assertions: the fields len and code are set to the optimal bit length
+               // and corresponding code. The length opt_len is updated; static_len is
+               // also updated if stree is not null. The field max_code is set.
+               that.build_tree = function(s) {
+                       var tree = that.dyn_tree;
+                       var stree = that.stat_desc.static_tree;
+                       var elems = that.stat_desc.elems;
+                       var n, m; // iterate over heap elements
+                       var max_code = -1; // largest code with non zero frequency
+                       var node; // new node being created
+
+                       // Construct the initial heap, with least frequent element in
+                       // heap[1]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
+                       // heap[0] is not used.
+                       s.heap_len = 0;
+                       s.heap_max = HEAP_SIZE;
+
+                       for (n = 0; n < elems; n++) {
+                               if (tree[n * 2] !== 0) {
+                                       s.heap[++s.heap_len] = max_code = n;
+                                       s.depth[n] = 0;
+                               } else {
+                                       tree[n * 2 + 1] = 0;
+                               }
+                       }
+
+                       // The pkzip format requires that at least one distance code exists,
+                       // and that at least one bit should be sent even if there is only one
+                       // possible code. So to avoid special checks later on we force at least
+                       // two codes of non zero frequency.
+                       while (s.heap_len < 2) {
+                               node = s.heap[++s.heap_len] = max_code < 2 ? ++max_code : 0;
+                               tree[node * 2] = 1;
+                               s.depth[node] = 0;
+                               s.opt_len--;
+                               if (stree)
+                                       s.static_len -= stree[node * 2 + 1];
+                               // node is 0 or 1 so it does not have extra bits
+                       }
+                       that.max_code = max_code;
+
+                       // The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
+                       // establish sub-heaps of increasing lengths:
+
+                       for (n = Math.floor(s.heap_len / 2); n >= 1; n--)
+                               s.pqdownheap(tree, n);
+
+                       // Construct the Huffman tree by repeatedly combining the least two
+                       // frequent nodes.
+
+                       node = elems; // next internal node of the tree
+                       do {
+                               // n = node of least frequency
+                               n = s.heap[1];
+                               s.heap[1] = s.heap[s.heap_len--];
+                               s.pqdownheap(tree, 1);
+                               m = s.heap[1]; // m = node of next least frequency
+
+                               s.heap[--s.heap_max] = n; // keep the nodes sorted by frequency
+                               s.heap[--s.heap_max] = m;
+
+                               // Create a new node father of n and m
+                               tree[node * 2] = (tree[n * 2] + tree[m * 2]);
+                               s.depth[node] = Math.max(s.depth[n], s.depth[m]) + 1;
+                               tree[n * 2 + 1] = tree[m * 2 + 1] = node;
+
+                               // and insert the new node in the heap
+                               s.heap[1] = node++;
+                               s.pqdownheap(tree, 1);
+                       } while (s.heap_len >= 2);
+
+                       s.heap[--s.heap_max] = s.heap[1];
+
+                       // At this point, the fields freq and dad are set. We can now
+                       // generate the bit lengths.
+
+                       gen_bitlen(s);
+
+                       // The field len is now set, we can generate the bit codes
+                       gen_codes(tree, that.max_code, s.bl_count);
+               };
+
+       }
+
+       Tree._length_code = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16,
+                       16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+                       20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+                       22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+                       24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+                       25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+                       26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 ];
+
+       Tree.base_length = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 0 ];
+
+       Tree.base_dist = [ 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384,
+                       24576 ];
+
+       // Mapping from a distance to a distance code. dist is the distance - 1 and
+       // must not have side effects. _dist_code[256] and _dist_code[257] are never
+       // used.
+       Tree.d_code = function(dist) {
+               return ((dist) < 256 ? _dist_code[dist] : _dist_code[256 + ((dist) >>> 7)]);
+       };
+
+       // extra bits for each length code
+       Tree.extra_lbits = [ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0 ];
+
+       // extra bits for each distance code
+       Tree.extra_dbits = [ 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13 ];
+
+       // extra bits for each bit length code
+       Tree.extra_blbits = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7 ];
+
+       Tree.bl_order = [ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 ];
+
+       // StaticTree
+
+       function StaticTree(static_tree, extra_bits, extra_base, elems, max_length) {
+               var that = this;
+               that.static_tree = static_tree;
+               that.extra_bits = extra_bits;
+               that.extra_base = extra_base;
+               that.elems = elems;
+               that.max_length = max_length;
+       }
+
+       StaticTree.static_ltree = [ 12, 8, 140, 8, 76, 8, 204, 8, 44, 8, 172, 8, 108, 8, 236, 8, 28, 8, 156, 8, 92, 8, 220, 8, 60, 8, 188, 8, 124, 8, 252, 8, 2, 8,
+                       130, 8, 66, 8, 194, 8, 34, 8, 162, 8, 98, 8, 226, 8, 18, 8, 146, 8, 82, 8, 210, 8, 50, 8, 178, 8, 114, 8, 242, 8, 10, 8, 138, 8, 74, 8, 202, 8, 42,
+                       8, 170, 8, 106, 8, 234, 8, 26, 8, 154, 8, 90, 8, 218, 8, 58, 8, 186, 8, 122, 8, 250, 8, 6, 8, 134, 8, 70, 8, 198, 8, 38, 8, 166, 8, 102, 8, 230, 8,
+                       22, 8, 150, 8, 86, 8, 214, 8, 54, 8, 182, 8, 118, 8, 246, 8, 14, 8, 142, 8, 78, 8, 206, 8, 46, 8, 174, 8, 110, 8, 238, 8, 30, 8, 158, 8, 94, 8,
+                       222, 8, 62, 8, 190, 8, 126, 8, 254, 8, 1, 8, 129, 8, 65, 8, 193, 8, 33, 8, 161, 8, 97, 8, 225, 8, 17, 8, 145, 8, 81, 8, 209, 8, 49, 8, 177, 8, 113,
+                       8, 241, 8, 9, 8, 137, 8, 73, 8, 201, 8, 41, 8, 169, 8, 105, 8, 233, 8, 25, 8, 153, 8, 89, 8, 217, 8, 57, 8, 185, 8, 121, 8, 249, 8, 5, 8, 133, 8,
+                       69, 8, 197, 8, 37, 8, 165, 8, 101, 8, 229, 8, 21, 8, 149, 8, 85, 8, 213, 8, 53, 8, 181, 8, 117, 8, 245, 8, 13, 8, 141, 8, 77, 8, 205, 8, 45, 8,
+                       173, 8, 109, 8, 237, 8, 29, 8, 157, 8, 93, 8, 221, 8, 61, 8, 189, 8, 125, 8, 253, 8, 19, 9, 275, 9, 147, 9, 403, 9, 83, 9, 339, 9, 211, 9, 467, 9,
+                       51, 9, 307, 9, 179, 9, 435, 9, 115, 9, 371, 9, 243, 9, 499, 9, 11, 9, 267, 9, 139, 9, 395, 9, 75, 9, 331, 9, 203, 9, 459, 9, 43, 9, 299, 9, 171, 9,
+                       427, 9, 107, 9, 363, 9, 235, 9, 491, 9, 27, 9, 283, 9, 155, 9, 411, 9, 91, 9, 347, 9, 219, 9, 475, 9, 59, 9, 315, 9, 187, 9, 443, 9, 123, 9, 379,
+                       9, 251, 9, 507, 9, 7, 9, 263, 9, 135, 9, 391, 9, 71, 9, 327, 9, 199, 9, 455, 9, 39, 9, 295, 9, 167, 9, 423, 9, 103, 9, 359, 9, 231, 9, 487, 9, 23,
+                       9, 279, 9, 151, 9, 407, 9, 87, 9, 343, 9, 215, 9, 471, 9, 55, 9, 311, 9, 183, 9, 439, 9, 119, 9, 375, 9, 247, 9, 503, 9, 15, 9, 271, 9, 143, 9,
+                       399, 9, 79, 9, 335, 9, 207, 9, 463, 9, 47, 9, 303, 9, 175, 9, 431, 9, 111, 9, 367, 9, 239, 9, 495, 9, 31, 9, 287, 9, 159, 9, 415, 9, 95, 9, 351, 9,
+                       223, 9, 479, 9, 63, 9, 319, 9, 191, 9, 447, 9, 127, 9, 383, 9, 255, 9, 511, 9, 0, 7, 64, 7, 32, 7, 96, 7, 16, 7, 80, 7, 48, 7, 112, 7, 8, 7, 72, 7,
+                       40, 7, 104, 7, 24, 7, 88, 7, 56, 7, 120, 7, 4, 7, 68, 7, 36, 7, 100, 7, 20, 7, 84, 7, 52, 7, 116, 7, 3, 8, 131, 8, 67, 8, 195, 8, 35, 8, 163, 8,
+                       99, 8, 227, 8 ];
+
+       StaticTree.static_dtree = [ 0, 5, 16, 5, 8, 5, 24, 5, 4, 5, 20, 5, 12, 5, 28, 5, 2, 5, 18, 5, 10, 5, 26, 5, 6, 5, 22, 5, 14, 5, 30, 5, 1, 5, 17, 5, 9, 5,
+                       25, 5, 5, 5, 21, 5, 13, 5, 29, 5, 3, 5, 19, 5, 11, 5, 27, 5, 7, 5, 23, 5 ];
+
+       StaticTree.static_l_desc = new StaticTree(StaticTree.static_ltree, Tree.extra_lbits, LITERALS + 1, L_CODES, MAX_BITS);
+
+       StaticTree.static_d_desc = new StaticTree(StaticTree.static_dtree, Tree.extra_dbits, 0, D_CODES, MAX_BITS);
+
+       StaticTree.static_bl_desc = new StaticTree(null, Tree.extra_blbits, 0, BL_CODES, MAX_BL_BITS);
+
+       // Deflate
+
+       var MAX_MEM_LEVEL = 9;
+       var DEF_MEM_LEVEL = 8;
+
+       function Config(good_length, max_lazy, nice_length, max_chain, func) {
+               var that = this;
+               that.good_length = good_length;
+               that.max_lazy = max_lazy;
+               that.nice_length = nice_length;
+               that.max_chain = max_chain;
+               that.func = func;
+       }
+
+       var STORED = 0;
+       var FAST = 1;
+       var SLOW = 2;
+       var config_table = [ new Config(0, 0, 0, 0, STORED), new Config(4, 4, 8, 4, FAST), new Config(4, 5, 16, 8, FAST), new Config(4, 6, 32, 32, FAST),
+                       new Config(4, 4, 16, 16, SLOW), new Config(8, 16, 32, 32, SLOW), new Config(8, 16, 128, 128, SLOW), new Config(8, 32, 128, 256, SLOW),
+                       new Config(32, 128, 258, 1024, SLOW), new Config(32, 258, 258, 4096, SLOW) ];
+
+       var z_errmsg = [ "need dictionary", // Z_NEED_DICT
+       // 2
+       "stream end", // Z_STREAM_END 1
+       "", // Z_OK 0
+       "", // Z_ERRNO (-1)
+       "stream error", // Z_STREAM_ERROR (-2)
+       "data error", // Z_DATA_ERROR (-3)
+       "", // Z_MEM_ERROR (-4)
+       "buffer error", // Z_BUF_ERROR (-5)
+       "",// Z_VERSION_ERROR (-6)
+       "" ];
+
+       // block not completed, need more input or more output
+       var NeedMore = 0;
+
+       // block flush performed
+       var BlockDone = 1;
+
+       // finish started, need only more output at next deflate
+       var FinishStarted = 2;
+
+       // finish done, accept no more input or output
+       var FinishDone = 3;
+
+       // preset dictionary flag in zlib header
+       var PRESET_DICT = 0x20;
+
+       var INIT_STATE = 42;
+       var BUSY_STATE = 113;
+       var FINISH_STATE = 666;
+
+       // The deflate compression method
+       var Z_DEFLATED = 8;
+
+       var STORED_BLOCK = 0;
+       var STATIC_TREES = 1;
+       var DYN_TREES = 2;
+
+       var MIN_MATCH = 3;
+       var MAX_MATCH = 258;
+       var MIN_LOOKAHEAD = (MAX_MATCH + MIN_MATCH + 1);
+
+       function smaller(tree, n, m, depth) {
+               var tn2 = tree[n * 2];
+               var tm2 = tree[m * 2];
+               return (tn2 < tm2 || (tn2 == tm2 && depth[n] <= depth[m]));
+       }
+
+       function Deflate() {
+
+               var that = this;
+               var strm; // pointer back to this zlib stream
+               var status; // as the name implies
+               // pending_buf; // output still pending
+               var pending_buf_size; // size of pending_buf
+               // pending_out; // next pending byte to output to the stream
+               // pending; // nb of bytes in the pending buffer
+               var method; // STORED (for zip only) or DEFLATED
+               var last_flush; // value of flush param for previous deflate call
+
+               var w_size; // LZ77 window size (32K by default)
+               var w_bits; // log2(w_size) (8..16)
+               var w_mask; // w_size - 1
+
+               var window;
+               // Sliding window. Input bytes are read into the second half of the window,
+               // and move to the first half later to keep a dictionary of at least wSize
+               // bytes. With this organization, matches are limited to a distance of
+               // wSize-MAX_MATCH bytes, but this ensures that IO is always
+               // performed with a length multiple of the block size. Also, it limits
+               // the window size to 64K, which is quite useful on MSDOS.
+               // To do: use the user input buffer as sliding window.
+
+               var window_size;
+               // Actual size of window: 2*wSize, except when the user input buffer
+               // is directly used as sliding window.
+
+               var prev;
+               // Link to older string with same hash index. To limit the size of this
+               // array to 64K, this link is maintained only for the last 32K strings.
+               // An index in this array is thus a window index modulo 32K.
+
+               var head; // Heads of the hash chains or NIL.
+
+               var ins_h; // hash index of string to be inserted
+               var hash_size; // number of elements in hash table
+               var hash_bits; // log2(hash_size)
+               var hash_mask; // hash_size-1
+
+               // Number of bits by which ins_h must be shifted at each input
+               // step. It must be such that after MIN_MATCH steps, the oldest
+               // byte no longer takes part in the hash key, that is:
+               // hash_shift * MIN_MATCH >= hash_bits
+               var hash_shift;
+
+               // Window position at the beginning of the current output block. Gets
+               // negative when the window is moved backwards.
+
+               var block_start;
+
+               var match_length; // length of best match
+               var prev_match; // previous match
+               var match_available; // set if previous match exists
+               var strstart; // start of string to insert
+               var match_start; // start of matching string
+               var lookahead; // number of valid bytes ahead in window
+
+               // Length of the best match at previous step. Matches not greater than this
+               // are discarded. This is used in the lazy match evaluation.
+               var prev_length;
+
+               // To speed up deflation, hash chains are never searched beyond this
+               // length. A higher limit improves compression ratio but degrades the speed.
+               var max_chain_length;
+
+               // Attempt to find a better match only when the current match is strictly
+               // smaller than this value. This mechanism is used only for compression
+               // levels >= 4.
+               var max_lazy_match;
+
+               // Insert new strings in the hash table only if the match length is not
+               // greater than this length. This saves time but degrades compression.
+               // max_insert_length is used only for compression levels <= 3.
+
+               var level; // compression level (1..9)
+               var strategy; // favor or force Huffman coding
+
+               // Use a faster search when the previous match is longer than this
+               var good_match;
+
+               // Stop searching when current match exceeds this
+               var nice_match;
+
+               var dyn_ltree; // literal and length tree
+               var dyn_dtree; // distance tree
+               var bl_tree; // Huffman tree for bit lengths
+
+               var l_desc = new Tree(); // desc for literal tree
+               var d_desc = new Tree(); // desc for distance tree
+               var bl_desc = new Tree(); // desc for bit length tree
+
+               // that.heap_len; // number of elements in the heap
+               // that.heap_max; // element of largest frequency
+               // The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
+               // The same heap array is used to build all trees.
+
+               // Depth of each subtree used as tie breaker for trees of equal frequency
+               that.depth = [];
+
+               var l_buf; // index for literals or lengths */
+
+               // Size of match buffer for literals/lengths. There are 4 reasons for
+               // limiting lit_bufsize to 64K:
+               // - frequencies can be kept in 16 bit counters
+               // - if compression is not successful for the first block, all input
+               // data is still in the window so we can still emit a stored block even
+               // when input comes from standard input. (This can also be done for
+               // all blocks if lit_bufsize is not greater than 32K.)
+               // - if compression is not successful for a file smaller than 64K, we can
+               // even emit a stored file instead of a stored block (saving 5 bytes).
+               // This is applicable only for zip (not gzip or zlib).
+               // - creating new Huffman trees less frequently may not provide fast
+               // adaptation to changes in the input data statistics. (Take for
+               // example a binary file with poorly compressible code followed by
+               // a highly compressible string table.) Smaller buffer sizes give
+               // fast adaptation but have of course the overhead of transmitting
+               // trees more frequently.
+               // - I can't count above 4
+               var lit_bufsize;
+
+               var last_lit; // running index in l_buf
+
+               // Buffer for distances. To simplify the code, d_buf and l_buf have
+               // the same number of elements. To use different lengths, an extra flag
+               // array would be necessary.
+
+               var d_buf; // index of pendig_buf
+
+               // that.opt_len; // bit length of current block with optimal trees
+               // that.static_len; // bit length of current block with static trees
+               var matches; // number of string matches in current block
+               var last_eob_len; // bit length of EOB code for last block
+
+               // Output buffer. bits are inserted starting at the bottom (least
+               // significant bits).
+               var bi_buf;
+
+               // Number of valid bits in bi_buf. All bits above the last valid bit
+               // are always zero.
+               var bi_valid;
+
+               // number of codes at each bit length for an optimal tree
+               that.bl_count = [];
+
+               // heap used to build the Huffman trees
+               that.heap = [];
+
+               dyn_ltree = [];
+               dyn_dtree = [];
+               bl_tree = [];
+
+               function lm_init() {
+                       var i;
+                       window_size = 2 * w_size;
+
+                       head[hash_size - 1] = 0;
+                       for (i = 0; i < hash_size - 1; i++) {
+                               head[i] = 0;
+                       }
+
+                       // Set the default configuration parameters:
+                       max_lazy_match = config_table[level].max_lazy;
+                       good_match = config_table[level].good_length;
+                       nice_match = config_table[level].nice_length;
+                       max_chain_length = config_table[level].max_chain;
+
+                       strstart = 0;
+                       block_start = 0;
+                       lookahead = 0;
+                       match_length = prev_length = MIN_MATCH - 1;
+                       match_available = 0;
+                       ins_h = 0;
+               }
+
+               function init_block() {
+                       var i;
+                       // Initialize the trees.
+                       for (i = 0; i < L_CODES; i++)
+                               dyn_ltree[i * 2] = 0;
+                       for (i = 0; i < D_CODES; i++)
+                               dyn_dtree[i * 2] = 0;
+                       for (i = 0; i < BL_CODES; i++)
+                               bl_tree[i * 2] = 0;
+
+                       dyn_ltree[END_BLOCK * 2] = 1;
+                       that.opt_len = that.static_len = 0;
+                       last_lit = matches = 0;
+               }
+
+               // Initialize the tree data structures for a new zlib stream.
+               function tr_init() {
+
+                       l_desc.dyn_tree = dyn_ltree;
+                       l_desc.stat_desc = StaticTree.static_l_desc;
+
+                       d_desc.dyn_tree = dyn_dtree;
+                       d_desc.stat_desc = StaticTree.static_d_desc;
+
+                       bl_desc.dyn_tree = bl_tree;
+                       bl_desc.stat_desc = StaticTree.static_bl_desc;
+
+                       bi_buf = 0;
+                       bi_valid = 0;
+                       last_eob_len = 8; // enough lookahead for inflate
+
+                       // Initialize the first block of the first file:
+                       init_block();
+               }
+
+               // Restore the heap property by moving down the tree starting at node k,
+               // exchanging a node with the smallest of its two sons if necessary,
+               // stopping
+               // when the heap property is re-established (each father smaller than its
+               // two sons).
+               that.pqdownheap = function(tree, // the tree to restore
+               k // node to move down
+               ) {
+                       var heap = that.heap;
+                       var v = heap[k];
+                       var j = k << 1; // left son of k
+                       while (j <= that.heap_len) {
+                               // Set j to the smallest of the two sons:
+                               if (j < that.heap_len && smaller(tree, heap[j + 1], heap[j], that.depth)) {
+                                       j++;
+                               }
+                               // Exit if v is smaller than both sons
+                               if (smaller(tree, v, heap[j], that.depth))
+                                       break;
+
+                               // Exchange v with the smallest son
+                               heap[k] = heap[j];
+                               k = j;
+                               // And continue down the tree, setting j to the left son of k
+                               j <<= 1;
+                       }
+                       heap[k] = v;
+               };
+
+               // Scan a literal or distance tree to determine the frequencies of the codes
+               // in the bit length tree.
+               function scan_tree(tree,// the tree to be scanned
+               max_code // and its largest code of non zero frequency
+               ) {
+                       var n; // iterates over all tree elements
+                       var prevlen = -1; // last emitted length
+                       var curlen; // length of current code
+                       var nextlen = tree[0 * 2 + 1]; // length of next code
+                       var count = 0; // repeat count of the current code
+                       var max_count = 7; // max repeat count
+                       var min_count = 4; // min repeat count
+
+                       if (nextlen === 0) {
+                               max_count = 138;
+                               min_count = 3;
+                       }
+                       tree[(max_code + 1) * 2 + 1] = 0xffff; // guard
+
+                       for (n = 0; n <= max_code; n++) {
+                               curlen = nextlen;
+                               nextlen = tree[(n + 1) * 2 + 1];
+                               if (++count < max_count && curlen == nextlen) {
+                                       continue;
+                               } else if (count < min_count) {
+                                       bl_tree[curlen * 2] += count;
+                               } else if (curlen !== 0) {
+                                       if (curlen != prevlen)
+                                               bl_tree[curlen * 2]++;
+                                       bl_tree[REP_3_6 * 2]++;
+                               } else if (count <= 10) {
+                                       bl_tree[REPZ_3_10 * 2]++;
+                               } else {
+                                       bl_tree[REPZ_11_138 * 2]++;
+                               }
+                               count = 0;
+                               prevlen = curlen;
+                               if (nextlen === 0) {
+                                       max_count = 138;
+                                       min_count = 3;
+                               } else if (curlen == nextlen) {
+                                       max_count = 6;
+                                       min_count = 3;
+                               } else {
+                                       max_count = 7;
+                                       min_count = 4;
+                               }
+                       }
+               }
+
+               // Construct the Huffman tree for the bit lengths and return the index in
+               // bl_order of the last bit length code to send.
+               function build_bl_tree() {
+                       var max_blindex; // index of last bit length code of non zero freq
+
+                       // Determine the bit length frequencies for literal and distance trees
+                       scan_tree(dyn_ltree, l_desc.max_code);
+                       scan_tree(dyn_dtree, d_desc.max_code);
+
+                       // Build the bit length tree:
+                       bl_desc.build_tree(that);
+                       // opt_len now includes the length of the tree representations, except
+                       // the lengths of the bit lengths codes and the 5+5+4 bits for the
+                       // counts.
+
+                       // Determine the number of bit length codes to send. The pkzip format
+                       // requires that at least 4 bit length codes be sent. (appnote.txt says
+                       // 3 but the actual value used is 4.)
+                       for (max_blindex = BL_CODES - 1; max_blindex >= 3; max_blindex--) {
+                               if (bl_tree[Tree.bl_order[max_blindex] * 2 + 1] !== 0)
+                                       break;
+                       }
+                       // Update opt_len to include the bit length tree and counts
+                       that.opt_len += 3 * (max_blindex + 1) + 5 + 5 + 4;
+
+                       return max_blindex;
+               }
+
+               // Output a byte on the stream.
+               // IN assertion: there is enough room in pending_buf.
+               function put_byte(p) {
+                       that.pending_buf[that.pending++] = p;
+               }
+
+               function put_short(w) {
+                       put_byte(w & 0xff);
+                       put_byte((w >>> 8) & 0xff);
+               }
+
+               function putShortMSB(b) {
+                       put_byte((b >> 8) & 0xff);
+                       put_byte((b & 0xff) & 0xff);
+               }
+
+               function send_bits(value, length) {
+                       var val, len = length;
+                       if (bi_valid > Buf_size - len) {
+                               val = value;
+                               // bi_buf |= (val << bi_valid);
+                               bi_buf |= ((val << bi_valid) & 0xffff);
+                               put_short(bi_buf);
+                               bi_buf = val >>> (Buf_size - bi_valid);
+                               bi_valid += len - Buf_size;
+                       } else {
+                               // bi_buf |= (value) << bi_valid;
+                               bi_buf |= (((value) << bi_valid) & 0xffff);
+                               bi_valid += len;
+                       }
+               }
+
+               function send_code(c, tree) {
+                       var c2 = c * 2;
+                       send_bits(tree[c2] & 0xffff, tree[c2 + 1] & 0xffff);
+               }
+
+               // Send a literal or distance tree in compressed form, using the codes in
+               // bl_tree.
+               function send_tree(tree,// the tree to be sent
+               max_code // and its largest code of non zero frequency
+               ) {
+                       var n; // iterates over all tree elements
+                       var prevlen = -1; // last emitted length
+                       var curlen; // length of current code
+                       var nextlen = tree[0 * 2 + 1]; // length of next code
+                       var count = 0; // repeat count of the current code
+                       var max_count = 7; // max repeat count
+                       var min_count = 4; // min repeat count
+
+                       if (nextlen === 0) {
+                               max_count = 138;
+                               min_count = 3;
+                       }
+
+                       for (n = 0; n <= max_code; n++) {
+                               curlen = nextlen;
+                               nextlen = tree[(n + 1) * 2 + 1];
+                               if (++count < max_count && curlen == nextlen) {
+                                       continue;
+                               } else if (count < min_count) {
+                                       do {
+                                               send_code(curlen, bl_tree);
+                                       } while (--count !== 0);
+                               } else if (curlen !== 0) {
+                                       if (curlen != prevlen) {
+                                               send_code(curlen, bl_tree);
+                                               count--;
+                                       }
+                                       send_code(REP_3_6, bl_tree);
+                                       send_bits(count - 3, 2);
+                               } else if (count <= 10) {
+                                       send_code(REPZ_3_10, bl_tree);
+                                       send_bits(count - 3, 3);
+                               } else {
+                                       send_code(REPZ_11_138, bl_tree);
+                                       send_bits(count - 11, 7);
+                               }
+                               count = 0;
+                               prevlen = curlen;
+                               if (nextlen === 0) {
+                                       max_count = 138;
+                                       min_count = 3;
+                               } else if (curlen == nextlen) {
+                                       max_count = 6;
+                                       min_count = 3;
+                               } else {
+                                       max_count = 7;
+                                       min_count = 4;
+                               }
+                       }
+               }
+
+               // Send the header for a block using dynamic Huffman trees: the counts, the
+               // lengths of the bit length codes, the literal tree and the distance tree.
+               // IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
+               function send_all_trees(lcodes, dcodes, blcodes) {
+                       var rank; // index in bl_order
+
+                       send_bits(lcodes - 257, 5); // not +255 as stated in appnote.txt
+                       send_bits(dcodes - 1, 5);
+                       send_bits(blcodes - 4, 4); // not -3 as stated in appnote.txt
+                       for (rank = 0; rank < blcodes; rank++) {
+                               send_bits(bl_tree[Tree.bl_order[rank] * 2 + 1], 3);
+                       }
+                       send_tree(dyn_ltree, lcodes - 1); // literal tree
+                       send_tree(dyn_dtree, dcodes - 1); // distance tree
+               }
+
+               // Flush the bit buffer, keeping at most 7 bits in it.
+               function bi_flush() {
+                       if (bi_valid == 16) {
+                               put_short(bi_buf);
+                               bi_buf = 0;
+                               bi_valid = 0;
+                       } else if (bi_valid >= 8) {
+                               put_byte(bi_buf & 0xff);
+                               bi_buf >>>= 8;
+                               bi_valid -= 8;
+                       }
+               }
+
+               // Send one empty static block to give enough lookahead for inflate.
+               // This takes 10 bits, of which 7 may remain in the bit buffer.
+               // The current inflate code requires 9 bits of lookahead. If the
+               // last two codes for the previous block (real code plus EOB) were coded
+               // on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode
+               // the last real code. In this case we send two empty static blocks instead
+               // of one. (There are no problems if the previous block is stored or fixed.)
+               // To simplify the code, we assume the worst case of last real code encoded
+               // on one bit only.
+               function _tr_align() {
+                       send_bits(STATIC_TREES << 1, 3);
+                       send_code(END_BLOCK, StaticTree.static_ltree);
+
+                       bi_flush();
+
+                       // Of the 10 bits for the empty block, we have already sent
+                       // (10 - bi_valid) bits. The lookahead for the last real code (before
+                       // the EOB of the previous block) was thus at least one plus the length
+                       // of the EOB plus what we have just sent of the empty static block.
+                       if (1 + last_eob_len + 10 - bi_valid < 9) {
+                               send_bits(STATIC_TREES << 1, 3);
+                               send_code(END_BLOCK, StaticTree.static_ltree);
+                               bi_flush();
+                       }
+                       last_eob_len = 7;
+               }
+
+               // Save the match info and tally the frequency counts. Return true if
+               // the current block must be flushed.
+               function _tr_tally(dist, // distance of matched string
+               lc // match length-MIN_MATCH or unmatched char (if dist==0)
+               ) {
+                       var out_length, in_length, dcode;
+                       that.pending_buf[d_buf + last_lit * 2] = (dist >>> 8) & 0xff;
+                       that.pending_buf[d_buf + last_lit * 2 + 1] = dist & 0xff;
+
+                       that.pending_buf[l_buf + last_lit] = lc & 0xff;
+                       last_lit++;
+
+                       if (dist === 0) {
+                               // lc is the unmatched char
+                               dyn_ltree[lc * 2]++;
+                       } else {
+                               matches++;
+                               // Here, lc is the match length - MIN_MATCH
+                               dist--; // dist = match distance - 1
+                               dyn_ltree[(Tree._length_code[lc] + LITERALS + 1) * 2]++;
+                               dyn_dtree[Tree.d_code(dist) * 2]++;
+                       }
+
+                       if ((last_lit & 0x1fff) === 0 && level > 2) {
+                               // Compute an upper bound for the compressed length
+                               out_length = last_lit * 8;
+                               in_length = strstart - block_start;
+                               for (dcode = 0; dcode < D_CODES; dcode++) {
+                                       out_length += dyn_dtree[dcode * 2] * (5 + Tree.extra_dbits[dcode]);
+                               }
+                               out_length >>>= 3;
+                               if ((matches < Math.floor(last_lit / 2)) && out_length < Math.floor(in_length / 2))
+                                       return true;
+                       }
+
+                       return (last_lit == lit_bufsize - 1);
+                       // We avoid equality with lit_bufsize because of wraparound at 64K
+                       // on 16 bit machines and because stored blocks are restricted to
+                       // 64K-1 bytes.
+               }
+
+               // Send the block data compressed using the given Huffman trees
+               function compress_block(ltree, dtree) {
+                       var dist; // distance of matched string
+                       var lc; // match length or unmatched char (if dist === 0)
+                       var lx = 0; // running index in l_buf
+                       var code; // the code to send
+                       var extra; // number of extra bits to send
+
+                       if (last_lit !== 0) {
+                               do {
+                                       dist = ((that.pending_buf[d_buf + lx * 2] << 8) & 0xff00) | (that.pending_buf[d_buf + lx * 2 + 1] & 0xff);
+                                       lc = (that.pending_buf[l_buf + lx]) & 0xff;
+                                       lx++;
+
+                                       if (dist === 0) {
+                                               send_code(lc, ltree); // send a literal byte
+                                       } else {
+                                               // Here, lc is the match length - MIN_MATCH
+                                               code = Tree._length_code[lc];
+
+                                               send_code(code + LITERALS + 1, ltree); // send the length
+                                               // code
+                                               extra = Tree.extra_lbits[code];
+                                               if (extra !== 0) {
+                                                       lc -= Tree.base_length[code];
+                                                       send_bits(lc, extra); // send the extra length bits
+                                               }
+                                               dist--; // dist is now the match distance - 1
+                                               code = Tree.d_code(dist);
+
+                                               send_code(code, dtree); // send the distance code
+                                               extra = Tree.extra_dbits[code];
+                                               if (extra !== 0) {
+                                                       dist -= Tree.base_dist[code];
+                                                       send_bits(dist, extra); // send the extra distance bits
+                                               }
+                                       } // literal or match pair ?
+
+                                       // Check that the overlay between pending_buf and d_buf+l_buf is
+                                       // ok:
+                               } while (lx < last_lit);
+                       }
+
+                       send_code(END_BLOCK, ltree);
+                       last_eob_len = ltree[END_BLOCK * 2 + 1];
+               }
+
+               // Flush the bit buffer and align the output on a byte boundary
+               function bi_windup() {
+                       if (bi_valid > 8) {
+                               put_short(bi_buf);
+                       } else if (bi_valid > 0) {
+                               put_byte(bi_buf & 0xff);
+                       }
+                       bi_buf = 0;
+                       bi_valid = 0;
+               }
+
+               // Copy a stored block, storing first the length and its
+               // one's complement if requested.
+               function copy_block(buf, // the input data
+               len, // its length
+               header // true if block header must be written
+               ) {
+                       bi_windup(); // align on byte boundary
+                       last_eob_len = 8; // enough lookahead for inflate
+
+                       if (header) {
+                               put_short(len);
+                               put_short(~len);
+                       }
+
+                       that.pending_buf.set(window.subarray(buf, buf + len), that.pending);
+                       that.pending += len;
+               }
+
+               // Send a stored block
+               function _tr_stored_block(buf, // input block
+               stored_len, // length of input block
+               eof // true if this is the last block for a file
+               ) {
+                       send_bits((STORED_BLOCK << 1) + (eof ? 1 : 0), 3); // send block type
+                       copy_block(buf, stored_len, true); // with header
+               }
+
+               // Determine the best encoding for the current block: dynamic trees, static
+               // trees or store, and output the encoded block to the zip file.
+               function _tr_flush_block(buf, // input block, or NULL if too old
+               stored_len, // length of input block
+               eof // true if this is the last block for a file
+               ) {
+                       var opt_lenb, static_lenb;// opt_len and static_len in bytes
+                       var max_blindex = 0; // index of last bit length code of non zero freq
+
+                       // Build the Huffman trees unless a stored block is forced
+                       if (level > 0) {
+                               // Construct the literal and distance trees
+                               l_desc.build_tree(that);
+
+                               d_desc.build_tree(that);
+
+                               // At this point, opt_len and static_len are the total bit lengths
+                               // of
+                               // the compressed block data, excluding the tree representations.
+
+                               // Build the bit length tree for the above two trees, and get the
+                               // index
+                               // in bl_order of the last bit length code to send.
+                               max_blindex = build_bl_tree();
+
+                               // Determine the best encoding. Compute first the block length in
+                               // bytes
+                               opt_lenb = (that.opt_len + 3 + 7) >>> 3;
+                               static_lenb = (that.static_len + 3 + 7) >>> 3;
+
+                               if (static_lenb <= opt_lenb)
+                                       opt_lenb = static_lenb;
+                       } else {
+                               opt_lenb = static_lenb = stored_len + 5; // force a stored block
+                       }
+
+                       if ((stored_len + 4 <= opt_lenb) && buf != -1) {
+                               // 4: two words for the lengths
+                               // The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
+                               // Otherwise we can't have processed more than WSIZE input bytes
+                               // since
+                               // the last block flush, because compression would have been
+                               // successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
+                               // transform a block into a stored block.
+                               _tr_stored_block(buf, stored_len, eof);
+                       } else if (static_lenb == opt_lenb) {
+                               send_bits((STATIC_TREES << 1) + (eof ? 1 : 0), 3);
+                               compress_block(StaticTree.static_ltree, StaticTree.static_dtree);
+                       } else {
+                               send_bits((DYN_TREES << 1) + (eof ? 1 : 0), 3);
+                               send_all_trees(l_desc.max_code + 1, d_desc.max_code + 1, max_blindex + 1);
+                               compress_block(dyn_ltree, dyn_dtree);
+                       }
+
+                       // The above check is made mod 2^32, for files larger than 512 MB
+                       // and uLong implemented on 32 bits.
+
+                       init_block();
+
+                       if (eof) {
+                               bi_windup();
+                       }
+               }
+
+               function flush_block_only(eof) {
+                       _tr_flush_block(block_start >= 0 ? block_start : -1, strstart - block_start, eof);
+                       block_start = strstart;
+                       strm.flush_pending();
+               }
+
+               // Fill the window when the lookahead becomes insufficient.
+               // Updates strstart and lookahead.
+               //
+               // IN assertion: lookahead < MIN_LOOKAHEAD
+               // OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
+               // At least one byte has been read, or avail_in === 0; reads are
+               // performed for at least two bytes (required for the zip translate_eol
+               // option -- not supported here).
+               function fill_window() {
+                       var n, m;
+                       var p;
+                       var more; // Amount of free space at the end of the window.
+
+                       do {
+                               more = (window_size - lookahead - strstart);
+
+                               // Deal with !@#$% 64K limit:
+                               if (more === 0 && strstart === 0 && lookahead === 0) {
+                                       more = w_size;
+                               } else if (more == -1) {
+                                       // Very unlikely, but possible on 16 bit machine if strstart ==
+                                       // 0
+                                       // and lookahead == 1 (input done one byte at time)
+                                       more--;
+
+                                       // If the window is almost full and there is insufficient
+                                       // lookahead,
+                                       // move the upper half to the lower one to make room in the
+                                       // upper half.
+                               } else if (strstart >= w_size + w_size - MIN_LOOKAHEAD) {
+                                       window.set(window.subarray(w_size, w_size + w_size), 0);
+
+                                       match_start -= w_size;
+                                       strstart -= w_size; // we now have strstart >= MAX_DIST
+                                       block_start -= w_size;
+
+                                       // Slide the hash table (could be avoided with 32 bit values
+                                       // at the expense of memory usage). We slide even when level ==
+                                       // 0
+                                       // to keep the hash table consistent if we switch back to level
+                                       // > 0
+                                       // later. (Using level 0 permanently is not an optimal usage of
+                                       // zlib, so we don't care about this pathological case.)
+
+                                       n = hash_size;
+                                       p = n;
+                                       do {
+                                               m = (head[--p] & 0xffff);
+                                               head[p] = (m >= w_size ? m - w_size : 0);
+                                       } while (--n !== 0);
+
+                                       n = w_size;
+                                       p = n;
+                                       do {
+                                               m = (prev[--p] & 0xffff);
+                                               prev[p] = (m >= w_size ? m - w_size : 0);
+                                               // If n is not on any hash chain, prev[n] is garbage but
+                                               // its value will never be used.
+                                       } while (--n !== 0);
+                                       more += w_size;
+                               }
+
+                               if (strm.avail_in === 0)
+                                       return;
+
+                               // If there was no sliding:
+                               // strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
+                               // more == window_size - lookahead - strstart
+                               // => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
+                               // => more >= window_size - 2*WSIZE + 2
+                               // In the BIG_MEM or MMAP case (not yet supported),
+                               // window_size == input_size + MIN_LOOKAHEAD &&
+                               // strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
+                               // Otherwise, window_size == 2*WSIZE so more >= 2.
+                               // If there was sliding, more >= WSIZE. So in all cases, more >= 2.
+
+                               n = strm.read_buf(window, strstart + lookahead, more);
+                               lookahead += n;
+
+                               // Initialize the hash value now that we have some input:
+                               if (lookahead >= MIN_MATCH) {
+                                       ins_h = window[strstart] & 0xff;
+                                       ins_h = (((ins_h) << hash_shift) ^ (window[strstart + 1] & 0xff)) & hash_mask;
+                               }
+                               // If the whole input has less than MIN_MATCH bytes, ins_h is
+                               // garbage,
+                               // but this is not important since only literal bytes will be
+                               // emitted.
+                       } while (lookahead < MIN_LOOKAHEAD && strm.avail_in !== 0);
+               }
+
+               // Copy without compression as much as possible from the input stream,
+               // return
+               // the current block state.
+               // This function does not insert new strings in the dictionary since
+               // uncompressible data is probably not useful. This function is used
+               // only for the level=0 compression option.
+               // NOTE: this function should be optimized to avoid extra copying from
+               // window to pending_buf.
+               function deflate_stored(flush) {
+                       // Stored blocks are limited to 0xffff bytes, pending_buf is limited
+                       // to pending_buf_size, and each stored block has a 5 byte header:
+
+                       var max_block_size = 0xffff;
+                       var max_start;
+
+                       if (max_block_size > pending_buf_size - 5) {
+                               max_block_size = pending_buf_size - 5;
+                       }
+
+                       // Copy as much as possible from input to output:
+                       while (true) {
+                               // Fill the window as much as possible:
+                               if (lookahead <= 1) {
+                                       fill_window();
+                                       if (lookahead === 0 && flush == Z_NO_FLUSH)
+                                               return NeedMore;
+                                       if (lookahead === 0)
+                                               break; // flush the current block
+                               }
+
+                               strstart += lookahead;
+                               lookahead = 0;
+
+                               // Emit a stored block if pending_buf will be full:
+                               max_start = block_start + max_block_size;
+                               if (strstart === 0 || strstart >= max_start) {
+                                       // strstart === 0 is possible when wraparound on 16-bit machine
+                                       lookahead = (strstart - max_start);
+                                       strstart = max_start;
+
+                                       flush_block_only(false);
+                                       if (strm.avail_out === 0)
+                                               return NeedMore;
+
+                               }
+
+                               // Flush if we may have to slide, otherwise block_start may become
+                               // negative and the data will be gone:
+                               if (strstart - block_start >= w_size - MIN_LOOKAHEAD) {
+                                       flush_block_only(false);
+                                       if (strm.avail_out === 0)
+                                               return NeedMore;
+                               }
+                       }
+
+                       flush_block_only(flush == Z_FINISH);
+                       if (strm.avail_out === 0)
+                               return (flush == Z_FINISH) ? FinishStarted : NeedMore;
+
+                       return flush == Z_FINISH ? FinishDone : BlockDone;
+               }
+
+               function longest_match(cur_match) {
+                       var chain_length = max_chain_length; // max hash chain length
+                       var scan = strstart; // current string
+                       var match; // matched string
+                       var len; // length of current match
+                       var best_len = prev_length; // best match length so far
+                       var limit = strstart > (w_size - MIN_LOOKAHEAD) ? strstart - (w_size - MIN_LOOKAHEAD) : 0;
+                       var _nice_match = nice_match;
+
+                       // Stop when cur_match becomes <= limit. To simplify the code,
+                       // we prevent matches with the string of window index 0.
+
+                       var wmask = w_mask;
+
+                       var strend = strstart + MAX_MATCH;
+                       var scan_end1 = window[scan + best_len - 1];
+                       var scan_end = window[scan + best_len];
+
+                       // The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of
+                       // 16.
+                       // It is easy to get rid of this optimization if necessary.
+
+                       // Do not waste too much time if we already have a good match:
+                       if (prev_length >= good_match) {
+                               chain_length >>= 2;
+                       }
+
+                       // Do not look for matches beyond the end of the input. This is
+                       // necessary
+                       // to make deflate deterministic.
+                       if (_nice_match > lookahead)
+                               _nice_match = lookahead;
+
+                       do {
+                               match = cur_match;
+
+                               // Skip to next match if the match length cannot increase
+                               // or if the match length is less than 2:
+                               if (window[match + best_len] != scan_end || window[match + best_len - 1] != scan_end1 || window[match] != window[scan]
+                                               || window[++match] != window[scan + 1])
+                                       continue;
+
+                               // The check at best_len-1 can be removed because it will be made
+                               // again later. (This heuristic is not always a win.)
+                               // It is not necessary to compare scan[2] and match[2] since they
+                               // are always equal when the other bytes match, given that
+                               // the hash keys are equal and that HASH_BITS >= 8.
+                               scan += 2;
+                               match++;
+
+                               // We check for insufficient lookahead only every 8th comparison;
+                               // the 256th check will be made at strstart+258.
+                               do {
+                               } while (window[++scan] == window[++match] && window[++scan] == window[++match] && window[++scan] == window[++match]
+                                               && window[++scan] == window[++match] && window[++scan] == window[++match] && window[++scan] == window[++match]
+                                               && window[++scan] == window[++match] && window[++scan] == window[++match] && scan < strend);
+
+                               len = MAX_MATCH - (strend - scan);
+                               scan = strend - MAX_MATCH;
+
+                               if (len > best_len) {
+                                       match_start = cur_match;
+                                       best_len = len;
+                                       if (len >= _nice_match)
+                                               break;
+                                       scan_end1 = window[scan + best_len - 1];
+                                       scan_end = window[scan + best_len];
+                               }
+
+                       } while ((cur_match = (prev[cur_match & wmask] & 0xffff)) > limit && --chain_length !== 0);
+
+                       if (best_len <= lookahead)
+                               return best_len;
+                       return lookahead;
+               }
+
+               // Compress as much as possible from the input stream, return the current
+               // block state.
+               // This function does not perform lazy evaluation of matches and inserts
+               // new strings in the dictionary only for unmatched strings or for short
+               // matches. It is used only for the fast compression options.
+               function deflate_fast(flush) {
+                       // short hash_head = 0; // head of the hash chain
+                       var hash_head = 0; // head of the hash chain
+                       var bflush; // set if current block must be flushed
+
+                       while (true) {
+                               // Make sure that we always have enough lookahead, except
+                               // at the end of the input file. We need MAX_MATCH bytes
+                               // for the next match, plus MIN_MATCH bytes to insert the
+                               // string following the next match.
+                               if (lookahead < MIN_LOOKAHEAD) {
+                                       fill_window();
+                                       if (lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
+                                               return NeedMore;
+                                       }
+                                       if (lookahead === 0)
+                                               break; // flush the current block
+                               }
+
+                               // Insert the string window[strstart .. strstart+2] in the
+                               // dictionary, and set hash_head to the head of the hash chain:
+                               if (lookahead >= MIN_MATCH) {
+                                       ins_h = (((ins_h) << hash_shift) ^ (window[(strstart) + (MIN_MATCH - 1)] & 0xff)) & hash_mask;
+
+                                       // prev[strstart&w_mask]=hash_head=head[ins_h];
+                                       hash_head = (head[ins_h] & 0xffff);
+                                       prev[strstart & w_mask] = head[ins_h];
+                                       head[ins_h] = strstart;
+                               }
+
+                               // Find the longest match, discarding those <= prev_length.
+                               // At this point we have always match_length < MIN_MATCH
+
+                               if (hash_head !== 0 && ((strstart - hash_head) & 0xffff) <= w_size - MIN_LOOKAHEAD) {
+                                       // To simplify the code, we prevent matches with the string
+                                       // of window index 0 (in particular we have to avoid a match
+                                       // of the string with itself at the start of the input file).
+                                       if (strategy != Z_HUFFMAN_ONLY) {
+                                               match_length = longest_match(hash_head);
+                                       }
+                                       // longest_match() sets match_start
+                               }
+                               if (match_length >= MIN_MATCH) {
+                                       // check_match(strstart, match_start, match_length);
+
+                                       bflush = _tr_tally(strstart - match_start, match_length - MIN_MATCH);
+
+                                       lookahead -= match_length;
+
+                                       // Insert new strings in the hash table only if the match length
+                                       // is not too large. This saves time but degrades compression.
+                                       if (match_length <= max_lazy_match && lookahead >= MIN_MATCH) {
+                                               match_length--; // string at strstart already in hash table
+                                               do {
+                                                       strstart++;
+
+                                                       ins_h = ((ins_h << hash_shift) ^ (window[(strstart) + (MIN_MATCH - 1)] & 0xff)) & hash_mask;
+                                                       // prev[strstart&w_mask]=hash_head=head[ins_h];
+                                                       hash_head = (head[ins_h] & 0xffff);
+                                                       prev[strstart & w_mask] = head[ins_h];
+                                                       head[ins_h] = strstart;
+
+                                                       // strstart never exceeds WSIZE-MAX_MATCH, so there are
+                                                       // always MIN_MATCH bytes ahead.
+                                               } while (--match_length !== 0);
+                                               strstart++;
+                                       } else {
+                                               strstart += match_length;
+                                               match_length = 0;
+                                               ins_h = window[strstart] & 0xff;
+
+                                               ins_h = (((ins_h) << hash_shift) ^ (window[strstart + 1] & 0xff)) & hash_mask;
+                                               // If lookahead < MIN_MATCH, ins_h is garbage, but it does
+                                               // not
+                                               // matter since it will be recomputed at next deflate call.
+                                       }
+                               } else {
+                                       // No match, output a literal byte
+
+                                       bflush = _tr_tally(0, window[strstart] & 0xff);
+                                       lookahead--;
+                                       strstart++;
+                               }
+                               if (bflush) {
+
+                                       flush_block_only(false);
+                                       if (strm.avail_out === 0)
+                                               return NeedMore;
+                               }
+                       }
+
+                       flush_block_only(flush == Z_FINISH);
+                       if (strm.avail_out === 0) {
+                               if (flush == Z_FINISH)
+                                       return FinishStarted;
+                               else
+                                       return NeedMore;
+                       }
+                       return flush == Z_FINISH ? FinishDone : BlockDone;
+               }
+
+               // Same as above, but achieves better compression. We use a lazy
+               // evaluation for matches: a match is finally adopted only if there is
+               // no better match at the next window position.
+               function deflate_slow(flush) {
+                       // short hash_head = 0; // head of hash chain
+                       var hash_head = 0; // head of hash chain
+                       var bflush; // set if current block must be flushed
+                       var max_insert;
+
+                       // Process the input block.
+                       while (true) {
+                               // Make sure that we always have enough lookahead, except
+                               // at the end of the input file. We need MAX_MATCH bytes
+                               // for the next match, plus MIN_MATCH bytes to insert the
+                               // string following the next match.
+
+                               if (lookahead < MIN_LOOKAHEAD) {
+                                       fill_window();
+                                       if (lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
+                                               return NeedMore;
+                                       }
+                                       if (lookahead === 0)
+                                               break; // flush the current block
+                               }
+
+                               // Insert the string window[strstart .. strstart+2] in the
+                               // dictionary, and set hash_head to the head of the hash chain:
+
+                               if (lookahead >= MIN_MATCH) {
+                                       ins_h = (((ins_h) << hash_shift) ^ (window[(strstart) + (MIN_MATCH - 1)] & 0xff)) & hash_mask;
+                                       // prev[strstart&w_mask]=hash_head=head[ins_h];
+                                       hash_head = (head[ins_h] & 0xffff);
+                                       prev[strstart & w_mask] = head[ins_h];
+                                       head[ins_h] = strstart;
+                               }
+
+                               // Find the longest match, discarding those <= prev_length.
+                               prev_length = match_length;
+                               prev_match = match_start;
+                               match_length = MIN_MATCH - 1;
+
+                               if (hash_head !== 0 && prev_length < max_lazy_match && ((strstart - hash_head) & 0xffff) <= w_size - MIN_LOOKAHEAD) {
+                                       // To simplify the code, we prevent matches with the string
+                                       // of window index 0 (in particular we have to avoid a match
+                                       // of the string with itself at the start of the input file).
+
+                                       if (strategy != Z_HUFFMAN_ONLY) {
+                                               match_length = longest_match(hash_head);
+                                       }
+                                       // longest_match() sets match_start
+
+                                       if (match_length <= 5 && (strategy == Z_FILTERED || (match_length == MIN_MATCH && strstart - match_start > 4096))) {
+
+                                               // If prev_match is also MIN_MATCH, match_start is garbage
+                                               // but we will ignore the current match anyway.
+                                               match_length = MIN_MATCH - 1;
+                                       }
+                               }
+
+                               // If there was a match at the previous step and the current
+                               // match is not better, output the previous match:
+                               if (prev_length >= MIN_MATCH && match_length <= prev_length) {
+                                       max_insert = strstart + lookahead - MIN_MATCH;
+                                       // Do not insert strings in hash table beyond this.
+
+                                       // check_match(strstart-1, prev_match, prev_length);
+
+                                       bflush = _tr_tally(strstart - 1 - prev_match, prev_length - MIN_MATCH);
+
+                                       // Insert in hash table all strings up to the end of the match.
+                                       // strstart-1 and strstart are already inserted. If there is not
+                                       // enough lookahead, the last two strings are not inserted in
+                                       // the hash table.
+                                       lookahead -= prev_length - 1;
+                                       prev_length -= 2;
+                                       do {
+                                               if (++strstart <= max_insert) {
+                                                       ins_h = (((ins_h) << hash_shift) ^ (window[(strstart) + (MIN_MATCH - 1)] & 0xff)) & hash_mask;
+                                                       // prev[strstart&w_mask]=hash_head=head[ins_h];
+                                                       hash_head = (head[ins_h] & 0xffff);
+                                                       prev[strstart & w_mask] = head[ins_h];
+                                                       head[ins_h] = strstart;
+                                               }
+                                       } while (--prev_length !== 0);
+                                       match_available = 0;
+                                       match_length = MIN_MATCH - 1;
+                                       strstart++;
+
+                                       if (bflush) {
+                                               flush_block_only(false);
+                                               if (strm.avail_out === 0)
+                                                       return NeedMore;
+                                       }
+                               } else if (match_available !== 0) {
+
+                                       // If there was no match at the previous position, output a
+                                       // single literal. If there was a match but the current match
+                                       // is longer, truncate the previous match to a single literal.
+
+                                       bflush = _tr_tally(0, window[strstart - 1] & 0xff);
+
+                                       if (bflush) {
+                                               flush_block_only(false);
+                                       }
+                                       strstart++;
+                                       lookahead--;
+                                       if (strm.avail_out === 0)
+                                               return NeedMore;
+                               } else {
+                                       // There is no previous match to compare with, wait for
+                                       // the next step to decide.
+
+                                       match_available = 1;
+                                       strstart++;
+                                       lookahead--;
+                               }
+                       }
+
+                       if (match_available !== 0) {
+                               bflush = _tr_tally(0, window[strstart - 1] & 0xff);
+                               match_available = 0;
+                       }
+                       flush_block_only(flush == Z_FINISH);
+
+                       if (strm.avail_out === 0) {
+                               if (flush == Z_FINISH)
+                                       return FinishStarted;
+                               else
+                                       return NeedMore;
+                       }
+
+                       return flush == Z_FINISH ? FinishDone : BlockDone;
+               }
+
+               function deflateReset(strm) {
+                       strm.total_in = strm.total_out = 0;
+                       strm.msg = null; //
+                       
+                       that.pending = 0;
+                       that.pending_out = 0;
+
+                       status = BUSY_STATE;
+
+                       last_flush = Z_NO_FLUSH;
+
+                       tr_init();
+                       lm_init();
+                       return Z_OK;
+               }
+
+               that.deflateInit = function(strm, _level, bits, _method, memLevel, _strategy) {
+                       if (!_method)
+                               _method = Z_DEFLATED;
+                       if (!memLevel)
+                               memLevel = DEF_MEM_LEVEL;
+                       if (!_strategy)
+                               _strategy = Z_DEFAULT_STRATEGY;
+
+                       // byte[] my_version=ZLIB_VERSION;
+
+                       //
+                       // if (!version || version[0] != my_version[0]
+                       // || stream_size != sizeof(z_stream)) {
+                       // return Z_VERSION_ERROR;
+                       // }
+
+                       strm.msg = null;
+
+                       if (_level == Z_DEFAULT_COMPRESSION)
+                               _level = 6;
+
+                       if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || _method != Z_DEFLATED || bits < 9 || bits > 15 || _level < 0 || _level > 9 || _strategy < 0
+                                       || _strategy > Z_HUFFMAN_ONLY) {
+                               return Z_STREAM_ERROR;
+                       }
+
+                       strm.dstate = that;
+
+                       w_bits = bits;
+                       w_size = 1 << w_bits;
+                       w_mask = w_size - 1;
+
+                       hash_bits = memLevel + 7;
+                       hash_size = 1 << hash_bits;
+                       hash_mask = hash_size - 1;
+                       hash_shift = Math.floor((hash_bits + MIN_MATCH - 1) / MIN_MATCH);
+
+                       window = new Uint8Array(w_size * 2);
+                       prev = [];
+                       head = [];
+
+                       lit_bufsize = 1 << (memLevel + 6); // 16K elements by default
+
+                       // We overlay pending_buf and d_buf+l_buf. This works since the average
+                       // output size for (length,distance) codes is <= 24 bits.
+                       that.pending_buf = new Uint8Array(lit_bufsize * 4);
+                       pending_buf_size = lit_bufsize * 4;
+
+                       d_buf = Math.floor(lit_bufsize / 2);
+                       l_buf = (1 + 2) * lit_bufsize;
+
+                       level = _level;
+
+                       strategy = _strategy;
+                       method = _method & 0xff;
+
+                       return deflateReset(strm);
+               };
+
+               that.deflateEnd = function() {
+                       if (status != INIT_STATE && status != BUSY_STATE && status != FINISH_STATE) {
+                               return Z_STREAM_ERROR;
+                       }
+                       // Deallocate in reverse order of allocations:
+                       that.pending_buf = null;
+                       head = null;
+                       prev = null;
+                       window = null;
+                       // free
+                       that.dstate = null;
+                       return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;
+               };
+
+               that.deflateParams = function(strm, _level, _strategy) {
+                       var err = Z_OK;
+
+                       if (_level == Z_DEFAULT_COMPRESSION) {
+                               _level = 6;
+                       }
+                       if (_level < 0 || _level > 9 || _strategy < 0 || _strategy > Z_HUFFMAN_ONLY) {
+                               return Z_STREAM_ERROR;
+                       }
+
+                       if (config_table[level].func != config_table[_level].func && strm.total_in !== 0) {
+                               // Flush the last buffer:
+                               err = strm.deflate(Z_PARTIAL_FLUSH);
+                       }
+
+                       if (level != _level) {
+                               level = _level;
+                               max_lazy_match = config_table[level].max_lazy;
+                               good_match = config_table[level].good_length;
+                               nice_match = config_table[level].nice_length;
+                               max_chain_length = config_table[level].max_chain;
+                       }
+                       strategy = _strategy;
+                       return err;
+               };
+
+               that.deflateSetDictionary = function(strm, dictionary, dictLength) {
+                       var length = dictLength;
+                       var n, index = 0;
+
+                       if (!dictionary || status != INIT_STATE)
+                               return Z_STREAM_ERROR;
+
+                       if (length < MIN_MATCH)
+                               return Z_OK;
+                       if (length > w_size - MIN_LOOKAHEAD) {
+                               length = w_size - MIN_LOOKAHEAD;
+                               index = dictLength - length; // use the tail of the dictionary
+                       }
+                       window.set(dictionary.subarray(index, index + length), 0);
+
+                       strstart = length;
+                       block_start = length;
+
+                       // Insert all strings in the hash table (except for the last two bytes).
+                       // s->lookahead stays null, so s->ins_h will be recomputed at the next
+                       // call of fill_window.
+
+                       ins_h = window[0] & 0xff;
+                       ins_h = (((ins_h) << hash_shift) ^ (window[1] & 0xff)) & hash_mask;
+
+                       for (n = 0; n <= length - MIN_MATCH; n++) {
+                               ins_h = (((ins_h) << hash_shift) ^ (window[(n) + (MIN_MATCH - 1)] & 0xff)) & hash_mask;
+                               prev[n & w_mask] = head[ins_h];
+                               head[ins_h] = n;
+                       }
+                       return Z_OK;
+               };
+
+               that.deflate = function(_strm, flush) {
+                       var i, header, level_flags, old_flush, bstate;
+
+                       if (flush > Z_FINISH || flush < 0) {
+                               return Z_STREAM_ERROR;
+                       }
+
+                       if (!_strm.next_out || (!_strm.next_in && _strm.avail_in !== 0) || (status == FINISH_STATE && flush != Z_FINISH)) {
+                               _strm.msg = z_errmsg[Z_NEED_DICT - (Z_STREAM_ERROR)];
+                               return Z_STREAM_ERROR;
+                       }
+                       if (_strm.avail_out === 0) {
+                               _strm.msg = z_errmsg[Z_NEED_DICT - (Z_BUF_ERROR)];
+                               return Z_BUF_ERROR;
+                       }
+
+                       strm = _strm; // just in case
+                       old_flush = last_flush;
+                       last_flush = flush;
+
+                       // Write the zlib header
+                       if (status == INIT_STATE) {
+                               header = (Z_DEFLATED + ((w_bits - 8) << 4)) << 8;
+                               level_flags = ((level - 1) & 0xff) >> 1;
+
+                               if (level_flags > 3)
+                                       level_flags = 3;
+                               header |= (level_flags << 6);
+                               if (strstart !== 0)
+                                       header |= PRESET_DICT;
+                               header += 31 - (header % 31);
+
+                               status = BUSY_STATE;
+                               putShortMSB(header);
+                       }
+
+                       // Flush as much pending output as possible
+                       if (that.pending !== 0) {
+                               strm.flush_pending();
+                               if (strm.avail_out === 0) {
+                                       // console.log(" avail_out==0");
+                                       // Since avail_out is 0, deflate will be called again with
+                                       // more output space, but possibly with both pending and
+                                       // avail_in equal to zero. There won't be anything to do,
+                                       // but this is not an error situation so make sure we
+                                       // return OK instead of BUF_ERROR at next call of deflate:
+                                       last_flush = -1;
+                                       return Z_OK;
+                               }
+
+                               // Make sure there is something to do and avoid duplicate
+                               // consecutive
+                               // flushes. For repeated and useless calls with Z_FINISH, we keep
+                               // returning Z_STREAM_END instead of Z_BUFF_ERROR.
+                       } else if (strm.avail_in === 0 && flush <= old_flush && flush != Z_FINISH) {
+                               strm.msg = z_errmsg[Z_NEED_DICT - (Z_BUF_ERROR)];
+                               return Z_BUF_ERROR;
+                       }
+
+                       // User must not provide more input after the first FINISH:
+                       if (status == FINISH_STATE && strm.avail_in !== 0) {
+                               _strm.msg = z_errmsg[Z_NEED_DICT - (Z_BUF_ERROR)];
+                               return Z_BUF_ERROR;
+                       }
+
+                       // Start a new block or continue the current one.
+                       if (strm.avail_in !== 0 || lookahead !== 0 || (flush != Z_NO_FLUSH && status != FINISH_STATE)) {
+                               bstate = -1;
+                               switch (config_table[level].func) {
+                               case STORED:
+                                       bstate = deflate_stored(flush);
+                                       break;
+                               case FAST:
+                                       bstate = deflate_fast(flush);
+                                       break;
+                               case SLOW:
+                                       bstate = deflate_slow(flush);
+                                       break;
+                               default:
+                               }
+
+                               if (bstate == FinishStarted || bstate == FinishDone) {
+                                       status = FINISH_STATE;
+                               }
+                               if (bstate == NeedMore || bstate == FinishStarted) {
+                                       if (strm.avail_out === 0) {
+                                               last_flush = -1; // avoid BUF_ERROR next call, see above
+                                       }
+                                       return Z_OK;
+                                       // If flush != Z_NO_FLUSH && avail_out === 0, the next call
+                                       // of deflate should use the same flush parameter to make sure
+                                       // that the flush is complete. So we don't have to output an
+                                       // empty block here, this will be done at next call. This also
+                                       // ensures that for a very small output buffer, we emit at most
+                                       // one empty block.
+                               }
+
+                               if (bstate == BlockDone) {
+                                       if (flush == Z_PARTIAL_FLUSH) {
+                                               _tr_align();
+                                       } else { // FULL_FLUSH or SYNC_FLUSH
+                                               _tr_stored_block(0, 0, false);
+                                               // For a full flush, this empty block will be recognized
+                                               // as a special marker by inflate_sync().
+                                               if (flush == Z_FULL_FLUSH) {
+                                                       // state.head[s.hash_size-1]=0;
+                                                       for (i = 0; i < hash_size/*-1*/; i++)
+                                                               // forget history
+                                                               head[i] = 0;
+                                               }
+                                       }
+                                       strm.flush_pending();
+                                       if (strm.avail_out === 0) {
+                                               last_flush = -1; // avoid BUF_ERROR at next call, see above
+                                               return Z_OK;
+                                       }
+                               }
+                       }
+
+                       if (flush != Z_FINISH)
+                               return Z_OK;
+                       return Z_STREAM_END;
+               };
+       }
+
+       // ZStream
+
+       function ZStream() {
+               var that = this;
+               that.next_in_index = 0;
+               that.next_out_index = 0;
+               // that.next_in; // next input byte
+               that.avail_in = 0; // number of bytes available at next_in
+               that.total_in = 0; // total nb of input bytes read so far
+               // that.next_out; // next output byte should be put there
+               that.avail_out = 0; // remaining free space at next_out
+               that.total_out = 0; // total nb of bytes output so far
+               // that.msg;
+               // that.dstate;
+       }
+
+       ZStream.prototype = {
+               deflateInit : function(level, bits) {
+                       var that = this;
+                       that.dstate = new Deflate();
+                       if (!bits)
+                               bits = MAX_BITS;
+                       return that.dstate.deflateInit(that, level, bits);
+               },
+
+               deflate : function(flush) {
+                       var that = this;
+                       if (!that.dstate) {
+                               return Z_STREAM_ERROR;
+                       }
+                       return that.dstate.deflate(that, flush);
+               },
+
+               deflateEnd : function() {
+                       var that = this;
+                       if (!that.dstate)
+                               return Z_STREAM_ERROR;
+                       var ret = that.dstate.deflateEnd();
+                       that.dstate = null;
+                       return ret;
+               },
+
+               deflateParams : function(level, strategy) {
+                       var that = this;
+                       if (!that.dstate)
+                               return Z_STREAM_ERROR;
+                       return that.dstate.deflateParams(that, level, strategy);
+               },
+
+               deflateSetDictionary : function(dictionary, dictLength) {
+                       var that = this;
+                       if (!that.dstate)
+                               return Z_STREAM_ERROR;
+                       return that.dstate.deflateSetDictionary(that, dictionary, dictLength);
+               },
+
+               // Read a new buffer from the current input stream, update the
+               // total number of bytes read. All deflate() input goes through
+               // this function so some applications may wish to modify it to avoid
+               // allocating a large strm->next_in buffer and copying from it.
+               // (See also flush_pending()).
+               read_buf : function(buf, start, size) {
+                       var that = this;
+                       var len = that.avail_in;
+                       if (len > size)
+                               len = size;
+                       if (len === 0)
+                               return 0;
+                       that.avail_in -= len;
+                       buf.set(that.next_in.subarray(that.next_in_index, that.next_in_index + len), start);
+                       that.next_in_index += len;
+                       that.total_in += len;
+                       return len;
+               },
+
+               // Flush as much pending output as possible. All deflate() output goes
+               // through this function so some applications may wish to modify it
+               // to avoid allocating a large strm->next_out buffer and copying into it.
+               // (See also read_buf()).
+               flush_pending : function() {
+                       var that = this;
+                       var len = that.dstate.pending;
+
+                       if (len > that.avail_out)
+                               len = that.avail_out;
+                       if (len === 0)
+                               return;
+
+                       // if (that.dstate.pending_buf.length <= that.dstate.pending_out || that.next_out.length <= that.next_out_index
+                       // || that.dstate.pending_buf.length < (that.dstate.pending_out + len) || that.next_out.length < (that.next_out_index +
+                       // len)) {
+                       // console.log(that.dstate.pending_buf.length + ", " + that.dstate.pending_out + ", " + that.next_out.length + ", " +
+                       // that.next_out_index + ", " + len);
+                       // console.log("avail_out=" + that.avail_out);
+                       // }
+
+                       that.next_out.set(that.dstate.pending_buf.subarray(that.dstate.pending_out, that.dstate.pending_out + len), that.next_out_index);
+
+                       that.next_out_index += len;
+                       that.dstate.pending_out += len;
+                       that.total_out += len;
+                       that.avail_out -= len;
+                       that.dstate.pending -= len;
+                       if (that.dstate.pending === 0) {
+                               that.dstate.pending_out = 0;
+                       }
+               }
+       };
+
+       // Deflater
+
+       function Deflater(level) {
+               var that = this;
+               var z = new ZStream();
+               var bufsize = 512;
+               var flush = Z_NO_FLUSH;
+               var buf = new Uint8Array(bufsize);
+
+               if (typeof level == "undefined")
+                       level = Z_DEFAULT_COMPRESSION;
+               z.deflateInit(level);
+               z.next_out = buf;
+
+               that.append = function(data, onprogress) {
+                       var err, buffers = [], lastIndex = 0, bufferIndex = 0, bufferSize = 0, array;
+                       if (!data.length)
+                               return;
+                       z.next_in_index = 0;
+                       z.next_in = data;
+                       z.avail_in = data.length;
+                       do {
+                               z.next_out_index = 0;
+                               z.avail_out = bufsize;
+                               err = z.deflate(flush);
+                               if (err != Z_OK)
+                                       throw "deflating: " + z.msg;
+                               if (z.next_out_index)
+                                       if (z.next_out_index == bufsize)
+                                               buffers.push(new Uint8Array(buf));
+                                       else
+                                               buffers.push(new Uint8Array(buf.subarray(0, z.next_out_index)));
+                               bufferSize += z.next_out_index;
+                               if (onprogress && z.next_in_index > 0 && z.next_in_index != lastIndex) {
+                                       onprogress(z.next_in_index);
+                                       lastIndex = z.next_in_index;
+                               }
+                       } while (z.avail_in > 0 || z.avail_out === 0);
+                       array = new Uint8Array(bufferSize);
+                       buffers.forEach(function(chunk) {
+                               array.set(chunk, bufferIndex);
+                               bufferIndex += chunk.length;
+                       });
+                       return array;
+               };
+               that.flush = function() {
+                       var err, buffers = [], bufferIndex = 0, bufferSize = 0, array;
+                       do {
+                               z.next_out_index = 0;
+                               z.avail_out = bufsize;
+                               err = z.deflate(Z_FINISH);
+                               if (err != Z_STREAM_END && err != Z_OK)
+                                       throw "deflating: " + z.msg;
+                               if (bufsize - z.avail_out > 0)
+                                       buffers.push(new Uint8Array(buf.subarray(0, z.next_out_index)));
+                               bufferSize += z.next_out_index;
+                       } while (z.avail_in > 0 || z.avail_out === 0);
+                       z.deflateEnd();
+                       array = new Uint8Array(bufferSize);
+                       buffers.forEach(function(chunk) {
+                               array.set(chunk, bufferIndex);
+                               bufferIndex += chunk.length;
+                       });
+                       return array;
+               };
+       }
+
+       var deflater;
+
+       if (obj.zip)
+               obj.zip.Deflater = Deflater;
+       else {
+               deflater = new Deflater();
+               obj.addEventListener("message", function(event) {
+                       var message = event.data;
+                       if (message.init) {
+                               deflater = new Deflater(message.level);
+                               obj.postMessage({
+                                       oninit : true
+                               });
+                       }
+                       if (message.append)
+                               obj.postMessage({
+                                       onappend : true,
+                                       data : deflater.append(message.data, function(current) {
+                                               obj.postMessage({
+                                                       progress : true,
+                                                       current : current
+                                               });
+                                       })
+                               });
+                       if (message.flush)
+                               obj.postMessage({
+                                       onflush : true,
+                                       data : deflater.flush()
+                               });
+               }, false);
+       }
+
+})(EasyDeflate);
diff --git a/resources/lib/easy-deflate/easydeflate.js b/resources/lib/easy-deflate/easydeflate.js
new file mode 100644 (file)
index 0000000..342229e
--- /dev/null
@@ -0,0 +1,219 @@
+/**\r
+Copyright (c) 2013, Specialisterne.\r
+http://specialisterne.com/dk/\r
+All rights reserved.\r
+Authors:\r
+Jacob Christian Munch-Andersen\r
+\r
+Redistribution and use in source and binary forms, with or without\r
+modification, are permitted provided that the following conditions are met:\r
+\r
+1. Redistributions of source code must retain the above copyright notice, this\r
+   list of conditions and the following disclaimer.\r
+2. Redistributions in binary form must reproduce the above copyright notice,\r
+   this list of conditions and the following disclaimer in the documentation\r
+   and/or other materials provided with the distribution.\r
+\r
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND\r
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\r
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR\r
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\r
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\r
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+**/\r
+// For information and latest version see: https://github.com/Jacob-Christian-Munch-Andersen/Easy-Deflate\r
+(function(){\r
+\r
+var zip={};\r
+function UTF8encode(str){\r
+       var out=[];\r
+       var a;\r
+       var c,c2;\r
+       for(a=0;a<str.length;a++){\r
+               c=str.charCodeAt(a);\r
+               if(c<128){\r
+                       out.push(c);\r
+               }\r
+               else if(c<2048){\r
+                       out.push((c >> 6)+192);\r
+                       out.push((c & 63)+128);\r
+               }\r
+               else if(c<65536){\r
+                       if(c>=0xD800 && c<0xDC00){\r
+                               a++;\r
+                               if(a>=str.length){\r
+                                       return null;\r
+                               }\r
+                               c2=str.charCodeAt(a);\r
+                               if(c2>=0xDC00 && c2<0xE000){\r
+                                       c=65536+(c-0xD800)*1024+c2-0xDC00;\r
+                                       out.push((c >> 18)+240);\r
+                                       out.push(((c >> 12) & 63)+128);\r
+                                       out.push(((c >> 6) & 63)+128);\r
+                                       out.push((c & 63)+128);\r
+                               }\r
+                               else{\r
+                                       return null;\r
+                               }\r
+                       }\r
+                       else if(c>=0xDC00 && c<0xE000){\r
+                               return null;\r
+                       }\r
+                       else{\r
+                               out.push((c >> 12)+224);\r
+                               out.push(((c >> 6) & 63)+128);\r
+                               out.push((c & 63)+128);\r
+                       }\r
+               }\r
+               else{\r
+                       return null;\r
+               }\r
+       }\r
+       return new Uint8Array(out);\r
+}\r
+function UTF8decodeA(arrarr){\r
+       var result="";\r
+       var intermediate;\r
+       var minvalue;\r
+       var missing=0;\r
+       var a,b;\r
+       var arr;\r
+       var c;\r
+       var lower,upper;\r
+       for(a=0;a<arrarr.length;a++){\r
+               arr=arrarr[a];\r
+               for(b=0;b<arr.length;b++){\r
+                       c=arr[b];\r
+                       if(missing){\r
+                               if(c>127 && c<192){\r
+                                       intermediate=intermediate*64+c-128;\r
+                                       missing--;\r
+                                       if(!missing){\r
+                                               if(intermediate>=minvalue){\r
+                                                       if(intermediate>=65536){\r
+                                                               if(intermediate>0x10FFFF){\r
+                                                                       return null;\r
+                                                               }\r
+                                                               upper=(intermediate-65536)>>10;\r
+                                                               lower=intermediate%1024;\r
+                                                               result+=String.fromCharCode(upper+0xD800,lower+0xDC00);\r
+                                                       }\r
+                                                       else{\r
+                                                               result+=String.fromCharCode(intermediate);\r
+                                                       }\r
+                                               }\r
+                                               else{\r
+                                                       return null;\r
+                                               }\r
+                                       }\r
+                               }\r
+                               else{\r
+                                       return null;\r
+                               }\r
+                       }\r
+                       else if(c<128){\r
+                               result+=String.fromCharCode(c);\r
+                       }\r
+                       else if(c>191 && c<248){\r
+                               if(c<224){\r
+                                       intermediate=c-192;\r
+                                       minvalue=128;\r
+                                       missing=1;\r
+                               }\r
+                               else if(c<240){\r
+                                       intermediate=c-224;\r
+                                       minvalue=2048;\r
+                                       missing=2;\r
+                               }\r
+                               else{\r
+                                       intermediate=c-240;\r
+                                       minvalue=65536;\r
+                                       missing=3;\r
+                               }\r
+                       }\r
+                       else{\r
+                               return null;\r
+                       }\r
+               }\r
+       }\r
+       if(missing){\r
+               return null;\r
+       }\r
+       return result;\r
+}\r
+function deflate(str){\r
+       var a,c;\r
+       var readlen=50000;\r
+       var resulta=[];\r
+       var results="";\r
+       var b,d;\r
+       var zipper=new zip.Deflater(9);\r
+       for(a=0;a<str.length;a+=readlen){\r
+               d=UTF8encode(str.substr(a,readlen));\r
+               if(d===null){ //This error may be due to a 4 byte charachter being split, retry with a string that is 1 longer to fix it.\r
+                       d=UTF8encode(str.substr(a,readlen+1));\r
+                       a+=1;\r
+                       if(d===null){\r
+                               return null;\r
+                       }\r
+               }\r
+               b=zipper.append(d);\r
+               if(b.length!==0){\r
+                       resulta.push(b);\r
+               }\r
+       }\r
+       b=zipper.flush();\r
+       if(b.length!==0){\r
+               resulta.push(b);\r
+       }\r
+       for(a=0;a<resulta.length;a++){\r
+               for(c=0;c<resulta[a].length;c++){\r
+                       results+=String.fromCharCode(resulta[a][c]);\r
+               }\r
+       }\r
+       return "rawdeflate,"+btoa(results);\r
+}\r
+function inflate(dfl){\r
+       var unzipper=new zip.Inflater();\r
+       var resulta=[];\r
+       var dfls;\r
+       var a,c;\r
+       var b,d;\r
+       if(dfl.slice(0,11)!="rawdeflate,"){\r
+               return null;\r
+       }\r
+       try{\r
+               dfls=atob(dfl.slice(11));\r
+       }\r
+       catch(e){\r
+               return null;\r
+       }\r
+       try{\r
+               for(a=0;a<dfls.length;a+=50000){\r
+                       b=new Uint8Array(Math.min(50000,dfls.length-a));\r
+                       for(c=0;c<b.length;c++){\r
+                               b[c]=dfls.charCodeAt(c+a);\r
+                       }\r
+                       d=unzipper.append(b);\r
+                       if(d.length){\r
+                               resulta.push(d);\r
+                       }\r
+               }\r
+               return UTF8decodeA(resulta);\r
+       }\r
+       catch(e){\r
+               return null;\r
+       }\r
+}\r
+\r
+window.EasyDeflate = {\r
+       'zip': zip,\r
+       'inflate': inflate,\r
+       'deflate': deflate\r
+};\r
+\r
+})();
\ No newline at end of file
diff --git a/resources/lib/easy-deflate/inflate.js b/resources/lib/easy-deflate/inflate.js
new file mode 100644 (file)
index 0000000..22f83fc
--- /dev/null
@@ -0,0 +1,2163 @@
+/*
+ Copyright (c) 2013 Gildas Lormeau. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright 
+ notice, this list of conditions and the following disclaimer in 
+ the documentation and/or other materials provided with the distribution.
+
+ 3. The names of the authors may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+ INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This program is based on JZlib 1.0.2 ymnk, JCraft,Inc.
+ * JZlib is based on zlib-1.1.3, so all credit should go authors
+ * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu)
+ * and contributors of zlib.
+ */
+
+(function(obj) {
+
+       // Global
+       var MAX_BITS = 15;
+
+       var Z_OK = 0;
+       var Z_STREAM_END = 1;
+       var Z_NEED_DICT = 2;
+       var Z_STREAM_ERROR = -2;
+       var Z_DATA_ERROR = -3;
+       var Z_MEM_ERROR = -4;
+       var Z_BUF_ERROR = -5;
+
+       var inflate_mask = [ 0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff, 0x000001ff, 0x000003ff,
+                       0x000007ff, 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff ];
+
+       var MANY = 1440;
+
+       // JZlib version : "1.0.2"
+       var Z_NO_FLUSH = 0;
+       var Z_FINISH = 4;
+
+       // InfTree
+       var fixed_bl = 9;
+       var fixed_bd = 5;
+
+       var fixed_tl = [ 96, 7, 256, 0, 8, 80, 0, 8, 16, 84, 8, 115, 82, 7, 31, 0, 8, 112, 0, 8, 48, 0, 9, 192, 80, 7, 10, 0, 8, 96, 0, 8, 32, 0, 9, 160, 0, 8, 0,
+                       0, 8, 128, 0, 8, 64, 0, 9, 224, 80, 7, 6, 0, 8, 88, 0, 8, 24, 0, 9, 144, 83, 7, 59, 0, 8, 120, 0, 8, 56, 0, 9, 208, 81, 7, 17, 0, 8, 104, 0, 8, 40,
+                       0, 9, 176, 0, 8, 8, 0, 8, 136, 0, 8, 72, 0, 9, 240, 80, 7, 4, 0, 8, 84, 0, 8, 20, 85, 8, 227, 83, 7, 43, 0, 8, 116, 0, 8, 52, 0, 9, 200, 81, 7, 13,
+                       0, 8, 100, 0, 8, 36, 0, 9, 168, 0, 8, 4, 0, 8, 132, 0, 8, 68, 0, 9, 232, 80, 7, 8, 0, 8, 92, 0, 8, 28, 0, 9, 152, 84, 7, 83, 0, 8, 124, 0, 8, 60,
+                       0, 9, 216, 82, 7, 23, 0, 8, 108, 0, 8, 44, 0, 9, 184, 0, 8, 12, 0, 8, 140, 0, 8, 76, 0, 9, 248, 80, 7, 3, 0, 8, 82, 0, 8, 18, 85, 8, 163, 83, 7,
+                       35, 0, 8, 114, 0, 8, 50, 0, 9, 196, 81, 7, 11, 0, 8, 98, 0, 8, 34, 0, 9, 164, 0, 8, 2, 0, 8, 130, 0, 8, 66, 0, 9, 228, 80, 7, 7, 0, 8, 90, 0, 8,
+                       26, 0, 9, 148, 84, 7, 67, 0, 8, 122, 0, 8, 58, 0, 9, 212, 82, 7, 19, 0, 8, 106, 0, 8, 42, 0, 9, 180, 0, 8, 10, 0, 8, 138, 0, 8, 74, 0, 9, 244, 80,
+                       7, 5, 0, 8, 86, 0, 8, 22, 192, 8, 0, 83, 7, 51, 0, 8, 118, 0, 8, 54, 0, 9, 204, 81, 7, 15, 0, 8, 102, 0, 8, 38, 0, 9, 172, 0, 8, 6, 0, 8, 134, 0,
+                       8, 70, 0, 9, 236, 80, 7, 9, 0, 8, 94, 0, 8, 30, 0, 9, 156, 84, 7, 99, 0, 8, 126, 0, 8, 62, 0, 9, 220, 82, 7, 27, 0, 8, 110, 0, 8, 46, 0, 9, 188, 0,
+                       8, 14, 0, 8, 142, 0, 8, 78, 0, 9, 252, 96, 7, 256, 0, 8, 81, 0, 8, 17, 85, 8, 131, 82, 7, 31, 0, 8, 113, 0, 8, 49, 0, 9, 194, 80, 7, 10, 0, 8, 97,
+                       0, 8, 33, 0, 9, 162, 0, 8, 1, 0, 8, 129, 0, 8, 65, 0, 9, 226, 80, 7, 6, 0, 8, 89, 0, 8, 25, 0, 9, 146, 83, 7, 59, 0, 8, 121, 0, 8, 57, 0, 9, 210,
+                       81, 7, 17, 0, 8, 105, 0, 8, 41, 0, 9, 178, 0, 8, 9, 0, 8, 137, 0, 8, 73, 0, 9, 242, 80, 7, 4, 0, 8, 85, 0, 8, 21, 80, 8, 258, 83, 7, 43, 0, 8, 117,
+                       0, 8, 53, 0, 9, 202, 81, 7, 13, 0, 8, 101, 0, 8, 37, 0, 9, 170, 0, 8, 5, 0, 8, 133, 0, 8, 69, 0, 9, 234, 80, 7, 8, 0, 8, 93, 0, 8, 29, 0, 9, 154,
+                       84, 7, 83, 0, 8, 125, 0, 8, 61, 0, 9, 218, 82, 7, 23, 0, 8, 109, 0, 8, 45, 0, 9, 186, 0, 8, 13, 0, 8, 141, 0, 8, 77, 0, 9, 250, 80, 7, 3, 0, 8, 83,
+                       0, 8, 19, 85, 8, 195, 83, 7, 35, 0, 8, 115, 0, 8, 51, 0, 9, 198, 81, 7, 11, 0, 8, 99, 0, 8, 35, 0, 9, 166, 0, 8, 3, 0, 8, 131, 0, 8, 67, 0, 9, 230,
+                       80, 7, 7, 0, 8, 91, 0, 8, 27, 0, 9, 150, 84, 7, 67, 0, 8, 123, 0, 8, 59, 0, 9, 214, 82, 7, 19, 0, 8, 107, 0, 8, 43, 0, 9, 182, 0, 8, 11, 0, 8, 139,
+                       0, 8, 75, 0, 9, 246, 80, 7, 5, 0, 8, 87, 0, 8, 23, 192, 8, 0, 83, 7, 51, 0, 8, 119, 0, 8, 55, 0, 9, 206, 81, 7, 15, 0, 8, 103, 0, 8, 39, 0, 9, 174,
+                       0, 8, 7, 0, 8, 135, 0, 8, 71, 0, 9, 238, 80, 7, 9, 0, 8, 95, 0, 8, 31, 0, 9, 158, 84, 7, 99, 0, 8, 127, 0, 8, 63, 0, 9, 222, 82, 7, 27, 0, 8, 111,
+                       0, 8, 47, 0, 9, 190, 0, 8, 15, 0, 8, 143, 0, 8, 79, 0, 9, 254, 96, 7, 256, 0, 8, 80, 0, 8, 16, 84, 8, 115, 82, 7, 31, 0, 8, 112, 0, 8, 48, 0, 9,
+                       193, 80, 7, 10, 0, 8, 96, 0, 8, 32, 0, 9, 161, 0, 8, 0, 0, 8, 128, 0, 8, 64, 0, 9, 225, 80, 7, 6, 0, 8, 88, 0, 8, 24, 0, 9, 145, 83, 7, 59, 0, 8,
+                       120, 0, 8, 56, 0, 9, 209, 81, 7, 17, 0, 8, 104, 0, 8, 40, 0, 9, 177, 0, 8, 8, 0, 8, 136, 0, 8, 72, 0, 9, 241, 80, 7, 4, 0, 8, 84, 0, 8, 20, 85, 8,
+                       227, 83, 7, 43, 0, 8, 116, 0, 8, 52, 0, 9, 201, 81, 7, 13, 0, 8, 100, 0, 8, 36, 0, 9, 169, 0, 8, 4, 0, 8, 132, 0, 8, 68, 0, 9, 233, 80, 7, 8, 0, 8,
+                       92, 0, 8, 28, 0, 9, 153, 84, 7, 83, 0, 8, 124, 0, 8, 60, 0, 9, 217, 82, 7, 23, 0, 8, 108, 0, 8, 44, 0, 9, 185, 0, 8, 12, 0, 8, 140, 0, 8, 76, 0, 9,
+                       249, 80, 7, 3, 0, 8, 82, 0, 8, 18, 85, 8, 163, 83, 7, 35, 0, 8, 114, 0, 8, 50, 0, 9, 197, 81, 7, 11, 0, 8, 98, 0, 8, 34, 0, 9, 165, 0, 8, 2, 0, 8,
+                       130, 0, 8, 66, 0, 9, 229, 80, 7, 7, 0, 8, 90, 0, 8, 26, 0, 9, 149, 84, 7, 67, 0, 8, 122, 0, 8, 58, 0, 9, 213, 82, 7, 19, 0, 8, 106, 0, 8, 42, 0, 9,
+                       181, 0, 8, 10, 0, 8, 138, 0, 8, 74, 0, 9, 245, 80, 7, 5, 0, 8, 86, 0, 8, 22, 192, 8, 0, 83, 7, 51, 0, 8, 118, 0, 8, 54, 0, 9, 205, 81, 7, 15, 0, 8,
+                       102, 0, 8, 38, 0, 9, 173, 0, 8, 6, 0, 8, 134, 0, 8, 70, 0, 9, 237, 80, 7, 9, 0, 8, 94, 0, 8, 30, 0, 9, 157, 84, 7, 99, 0, 8, 126, 0, 8, 62, 0, 9,
+                       221, 82, 7, 27, 0, 8, 110, 0, 8, 46, 0, 9, 189, 0, 8, 14, 0, 8, 142, 0, 8, 78, 0, 9, 253, 96, 7, 256, 0, 8, 81, 0, 8, 17, 85, 8, 131, 82, 7, 31, 0,
+                       8, 113, 0, 8, 49, 0, 9, 195, 80, 7, 10, 0, 8, 97, 0, 8, 33, 0, 9, 163, 0, 8, 1, 0, 8, 129, 0, 8, 65, 0, 9, 227, 80, 7, 6, 0, 8, 89, 0, 8, 25, 0, 9,
+                       147, 83, 7, 59, 0, 8, 121, 0, 8, 57, 0, 9, 211, 81, 7, 17, 0, 8, 105, 0, 8, 41, 0, 9, 179, 0, 8, 9, 0, 8, 137, 0, 8, 73, 0, 9, 243, 80, 7, 4, 0, 8,
+                       85, 0, 8, 21, 80, 8, 258, 83, 7, 43, 0, 8, 117, 0, 8, 53, 0, 9, 203, 81, 7, 13, 0, 8, 101, 0, 8, 37, 0, 9, 171, 0, 8, 5, 0, 8, 133, 0, 8, 69, 0, 9,
+                       235, 80, 7, 8, 0, 8, 93, 0, 8, 29, 0, 9, 155, 84, 7, 83, 0, 8, 125, 0, 8, 61, 0, 9, 219, 82, 7, 23, 0, 8, 109, 0, 8, 45, 0, 9, 187, 0, 8, 13, 0, 8,
+                       141, 0, 8, 77, 0, 9, 251, 80, 7, 3, 0, 8, 83, 0, 8, 19, 85, 8, 195, 83, 7, 35, 0, 8, 115, 0, 8, 51, 0, 9, 199, 81, 7, 11, 0, 8, 99, 0, 8, 35, 0, 9,
+                       167, 0, 8, 3, 0, 8, 131, 0, 8, 67, 0, 9, 231, 80, 7, 7, 0, 8, 91, 0, 8, 27, 0, 9, 151, 84, 7, 67, 0, 8, 123, 0, 8, 59, 0, 9, 215, 82, 7, 19, 0, 8,
+                       107, 0, 8, 43, 0, 9, 183, 0, 8, 11, 0, 8, 139, 0, 8, 75, 0, 9, 247, 80, 7, 5, 0, 8, 87, 0, 8, 23, 192, 8, 0, 83, 7, 51, 0, 8, 119, 0, 8, 55, 0, 9,
+                       207, 81, 7, 15, 0, 8, 103, 0, 8, 39, 0, 9, 175, 0, 8, 7, 0, 8, 135, 0, 8, 71, 0, 9, 239, 80, 7, 9, 0, 8, 95, 0, 8, 31, 0, 9, 159, 84, 7, 99, 0, 8,
+                       127, 0, 8, 63, 0, 9, 223, 82, 7, 27, 0, 8, 111, 0, 8, 47, 0, 9, 191, 0, 8, 15, 0, 8, 143, 0, 8, 79, 0, 9, 255 ];
+       var fixed_td = [ 80, 5, 1, 87, 5, 257, 83, 5, 17, 91, 5, 4097, 81, 5, 5, 89, 5, 1025, 85, 5, 65, 93, 5, 16385, 80, 5, 3, 88, 5, 513, 84, 5, 33, 92, 5,
+                       8193, 82, 5, 9, 90, 5, 2049, 86, 5, 129, 192, 5, 24577, 80, 5, 2, 87, 5, 385, 83, 5, 25, 91, 5, 6145, 81, 5, 7, 89, 5, 1537, 85, 5, 97, 93, 5,
+                       24577, 80, 5, 4, 88, 5, 769, 84, 5, 49, 92, 5, 12289, 82, 5, 13, 90, 5, 3073, 86, 5, 193, 192, 5, 24577 ];
+
+       // Tables for deflate from PKZIP's appnote.txt.
+       var cplens = [ // Copy lengths for literal codes 257..285
+       3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 ];
+
+       // see note #13 above about 258
+       var cplext = [ // Extra bits for literal codes 257..285
+       0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112 // 112==invalid
+       ];
+
+       var cpdist = [ // Copy offsets for distance codes 0..29
+       1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577 ];
+
+       var cpdext = [ // Extra bits for distance codes
+       0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13 ];
+
+       // If BMAX needs to be larger than 16, then h and x[] should be uLong.
+       var BMAX = 15; // maximum bit length of any code
+
+       function InfTree() {
+               var that = this;
+
+               var hn; // hufts used in space
+               var v; // work area for huft_build
+               var c; // bit length count table
+               var r; // table entry for structure assignment
+               var u; // table stack
+               var x; // bit offsets, then code stack
+
+               function huft_build(b, // code lengths in bits (all assumed <=
+               // BMAX)
+               bindex, n, // number of codes (assumed <= 288)
+               s, // number of simple-valued codes (0..s-1)
+               d, // list of base values for non-simple codes
+               e, // list of extra bits for non-simple codes
+               t, // result: starting table
+               m, // maximum lookup bits, returns actual
+               hp,// space for trees
+               hn,// hufts used in space
+               v // working area: values in order of bit length
+               ) {
+                       // Given a list of code lengths and a maximum table size, make a set of
+                       // tables to decode that set of codes. Return Z_OK on success,
+                       // Z_BUF_ERROR
+                       // if the given code set is incomplete (the tables are still built in
+                       // this
+                       // case), Z_DATA_ERROR if the input is invalid (an over-subscribed set
+                       // of
+                       // lengths), or Z_MEM_ERROR if not enough memory.
+
+                       var a; // counter for codes of length k
+                       var f; // i repeats in table every f entries
+                       var g; // maximum code length
+                       var h; // table level
+                       var i; // counter, current code
+                       var j; // counter
+                       var k; // number of bits in current code
+                       var l; // bits per table (returned in m)
+                       var mask; // (1 << w) - 1, to avoid cc -O bug on HP
+                       var p; // pointer into c[], b[], or v[]
+                       var q; // points to current table
+                       var w; // bits before this table == (l * h)
+                       var xp; // pointer into x
+                       var y; // number of dummy codes added
+                       var z; // number of entries in current table
+
+                       // Generate counts for each bit length
+
+                       p = 0;
+                       i = n;
+                       do {
+                               c[b[bindex + p]]++;
+                               p++;
+                               i--; // assume all entries <= BMAX
+                       } while (i !== 0);
+
+                       if (c[0] == n) { // null input--all zero length codes
+                               t[0] = -1;
+                               m[0] = 0;
+                               return Z_OK;
+                       }
+
+                       // Find minimum and maximum length, bound *m by those
+                       l = m[0];
+                       for (j = 1; j <= BMAX; j++)
+                               if (c[j] !== 0)
+                                       break;
+                       k = j; // minimum code length
+                       if (l < j) {
+                               l = j;
+                       }
+                       for (i = BMAX; i !== 0; i--) {
+                               if (c[i] !== 0)
+                                       break;
+                       }
+                       g = i; // maximum code length
+                       if (l > i) {
+                               l = i;
+                       }
+                       m[0] = l;
+
+                       // Adjust last length count to fill out codes, if needed
+                       for (y = 1 << j; j < i; j++, y <<= 1) {
+                               if ((y -= c[j]) < 0) {
+                                       return Z_DATA_ERROR;
+                               }
+                       }
+                       if ((y -= c[i]) < 0) {
+                               return Z_DATA_ERROR;
+                       }
+                       c[i] += y;
+
+                       // Generate starting offsets into the value table for each length
+                       x[1] = j = 0;
+                       p = 1;
+                       xp = 2;
+                       while (--i !== 0) { // note that i == g from above
+                               x[xp] = (j += c[p]);
+                               xp++;
+                               p++;
+                       }
+
+                       // Make a table of values in order of bit lengths
+                       i = 0;
+                       p = 0;
+                       do {
+                               if ((j = b[bindex + p]) !== 0) {
+                                       v[x[j]++] = i;
+                               }
+                               p++;
+                       } while (++i < n);
+                       n = x[g]; // set n to length of v
+
+                       // Generate the Huffman codes and for each, make the table entries
+                       x[0] = i = 0; // first Huffman code is zero
+                       p = 0; // grab values in bit order
+                       h = -1; // no tables yet--level -1
+                       w = -l; // bits decoded == (l * h)
+                       u[0] = 0; // just to keep compilers happy
+                       q = 0; // ditto
+                       z = 0; // ditto
+
+                       // go through the bit lengths (k already is bits in shortest code)
+                       for (; k <= g; k++) {
+                               a = c[k];
+                               while (a-- !== 0) {
+                                       // here i is the Huffman code of length k bits for value *p
+                                       // make tables up to required level
+                                       while (k > w + l) {
+                                               h++;
+                                               w += l; // previous table always l bits
+                                               // compute minimum size table less than or equal to l bits
+                                               z = g - w;
+                                               z = (z > l) ? l : z; // table size upper limit
+                                               if ((f = 1 << (j = k - w)) > a + 1) { // try a k-w bit table
+                                                       // too few codes for
+                                                       // k-w bit table
+                                                       f -= a + 1; // deduct codes from patterns left
+                                                       xp = k;
+                                                       if (j < z) {
+                                                               while (++j < z) { // try smaller tables up to z bits
+                                                                       if ((f <<= 1) <= c[++xp])
+                                                                               break; // enough codes to use up j bits
+                                                                       f -= c[xp]; // else deduct codes from patterns
+                                                               }
+                                                       }
+                                               }
+                                               z = 1 << j; // table entries for j-bit table
+
+                                               // allocate new table
+                                               if (hn[0] + z > MANY) { // (note: doesn't matter for fixed)
+                                                       return Z_DATA_ERROR; // overflow of MANY
+                                               }
+                                               u[h] = q = /* hp+ */hn[0]; // DEBUG
+                                               hn[0] += z;
+
+                                               // connect to last table, if there is one
+                                               if (h !== 0) {
+                                                       x[h] = i; // save pattern for backing up
+                                                       r[0] = /* (byte) */j; // bits in this table
+                                                       r[1] = /* (byte) */l; // bits to dump before this table
+                                                       j = i >>> (w - l);
+                                                       r[2] = /* (int) */(q - u[h - 1] - j); // offset to this table
+                                                       hp.set(r, (u[h - 1] + j) * 3);
+                                                       // to
+                                                       // last
+                                                       // table
+                                               } else {
+                                                       t[0] = q; // first table is returned result
+                                               }
+                                       }
+
+                                       // set up table entry in r
+                                       r[1] = /* (byte) */(k - w);
+                                       if (p >= n) {
+                                               r[0] = 128 + 64; // out of values--invalid code
+                                       } else if (v[p] < s) {
+                                               r[0] = /* (byte) */(v[p] < 256 ? 0 : 32 + 64); // 256 is
+                                               // end-of-block
+                                               r[2] = v[p++]; // simple code is just the value
+                                       } else {
+                                               r[0] = /* (byte) */(e[v[p] - s] + 16 + 64); // non-simple--look
+                                               // up in lists
+                                               r[2] = d[v[p++] - s];
+                                       }
+
+                                       // fill code-like entries with r
+                                       f = 1 << (k - w);
+                                       for (j = i >>> w; j < z; j += f) {
+                                               hp.set(r, (q + j) * 3);
+                                       }
+
+                                       // backwards increment the k-bit code i
+                                       for (j = 1 << (k - 1); (i & j) !== 0; j >>>= 1) {
+                                               i ^= j;
+                                       }
+                                       i ^= j;
+
+                                       // backup over finished tables
+                                       mask = (1 << w) - 1; // needed on HP, cc -O bug
+                                       while ((i & mask) != x[h]) {
+                                               h--; // don't need to update q
+                                               w -= l;
+                                               mask = (1 << w) - 1;
+                                       }
+                               }
+                       }
+                       // Return Z_BUF_ERROR if we were given an incomplete table
+                       return y !== 0 && g != 1 ? Z_BUF_ERROR : Z_OK;
+               }
+
+               function initWorkArea(vsize) {
+                       var i;
+                       if (!hn) {
+                               hn = []; // []; //new Array(1);
+                               v = []; // new Array(vsize);
+                               c = new Int32Array(BMAX + 1); // new Array(BMAX + 1);
+                               r = []; // new Array(3);
+                               u = new Int32Array(BMAX); // new Array(BMAX);
+                               x = new Int32Array(BMAX + 1); // new Array(BMAX + 1);
+                       }
+                       if (v.length < vsize) {
+                               v = []; // new Array(vsize);
+                       }
+                       for (i = 0; i < vsize; i++) {
+                               v[i] = 0;
+                       }
+                       for (i = 0; i < BMAX + 1; i++) {
+                               c[i] = 0;
+                       }
+                       for (i = 0; i < 3; i++) {
+                               r[i] = 0;
+                       }
+                       // for(int i=0; i<BMAX; i++){u[i]=0;}
+                       u.set(c.subarray(0, BMAX), 0);
+                       // for(int i=0; i<BMAX+1; i++){x[i]=0;}
+                       x.set(c.subarray(0, BMAX + 1), 0);
+               }
+
+               that.inflate_trees_bits = function(c, // 19 code lengths
+               bb, // bits tree desired/actual depth
+               tb, // bits tree result
+               hp, // space for trees
+               z // for messages
+               ) {
+                       var result;
+                       initWorkArea(19);
+                       hn[0] = 0;
+                       result = huft_build(c, 0, 19, 19, null, null, tb, bb, hp, hn, v);
+
+                       if (result == Z_DATA_ERROR) {
+                               z.msg = "oversubscribed dynamic bit lengths tree";
+                       } else if (result == Z_BUF_ERROR || bb[0] === 0) {
+                               z.msg = "incomplete dynamic bit lengths tree";
+                               result = Z_DATA_ERROR;
+                       }
+                       return result;
+               };
+
+               that.inflate_trees_dynamic = function(nl, // number of literal/length codes
+               nd, // number of distance codes
+               c, // that many (total) code lengths
+               bl, // literal desired/actual bit depth
+               bd, // distance desired/actual bit depth
+               tl, // literal/length tree result
+               td, // distance tree result
+               hp, // space for trees
+               z // for messages
+               ) {
+                       var result;
+
+                       // build literal/length tree
+                       initWorkArea(288);
+                       hn[0] = 0;
+                       result = huft_build(c, 0, nl, 257, cplens, cplext, tl, bl, hp, hn, v);
+                       if (result != Z_OK || bl[0] === 0) {
+                               if (result == Z_DATA_ERROR) {
+                                       z.msg = "oversubscribed literal/length tree";
+                               } else if (result != Z_MEM_ERROR) {
+                                       z.msg = "incomplete literal/length tree";
+                                       result = Z_DATA_ERROR;
+                               }
+                               return result;
+                       }
+
+                       // build distance tree
+                       initWorkArea(288);
+                       result = huft_build(c, nl, nd, 0, cpdist, cpdext, td, bd, hp, hn, v);
+
+                       if (result != Z_OK || (bd[0] === 0 && nl > 257)) {
+                               if (result == Z_DATA_ERROR) {
+                                       z.msg = "oversubscribed distance tree";
+                               } else if (result == Z_BUF_ERROR) {
+                                       z.msg = "incomplete distance tree";
+                                       result = Z_DATA_ERROR;
+                               } else if (result != Z_MEM_ERROR) {
+                                       z.msg = "empty distance tree with lengths";
+                                       result = Z_DATA_ERROR;
+                               }
+                               return result;
+                       }
+
+                       return Z_OK;
+               };
+
+       }
+
+       InfTree.inflate_trees_fixed = function(bl, // literal desired/actual bit depth
+       bd, // distance desired/actual bit depth
+       tl,// literal/length tree result
+       td// distance tree result
+       ) {
+               bl[0] = fixed_bl;
+               bd[0] = fixed_bd;
+               tl[0] = fixed_tl;
+               td[0] = fixed_td;
+               return Z_OK;
+       };
+
+       // InfCodes
+
+       // waiting for "i:"=input,
+       // "o:"=output,
+       // "x:"=nothing
+       var START = 0; // x: set up for LEN
+       var LEN = 1; // i: get length/literal/eob next
+       var LENEXT = 2; // i: getting length extra (have base)
+       var DIST = 3; // i: get distance next
+       var DISTEXT = 4;// i: getting distance extra
+       var COPY = 5; // o: copying bytes in window, waiting
+       // for space
+       var LIT = 6; // o: got literal, waiting for output
+       // space
+       var WASH = 7; // o: got eob, possibly still output
+       // waiting
+       var END = 8; // x: got eob and all data flushed
+       var BADCODE = 9;// x: got error
+
+       function InfCodes() {
+               var that = this;
+
+               var mode; // current inflate_codes mode
+
+               // mode dependent information
+               var len = 0;
+
+               var tree; // pointer into tree
+               var tree_index = 0;
+               var need = 0; // bits needed
+
+               var lit = 0;
+
+               // if EXT or COPY, where and how much
+               var get = 0; // bits to get for extra
+               var dist = 0; // distance back to copy from
+
+               var lbits = 0; // ltree bits decoded per branch
+               var dbits = 0; // dtree bits decoder per branch
+               var ltree; // literal/length/eob tree
+               var ltree_index = 0; // literal/length/eob tree
+               var dtree; // distance tree
+               var dtree_index = 0; // distance tree
+
+               // Called with number of bytes left to write in window at least 258
+               // (the maximum string length) and number of input bytes available
+               // at least ten. The ten bytes are six bytes for the longest length/
+               // distance pair plus four bytes for overloading the bit buffer.
+
+               function inflate_fast(bl, bd, tl, tl_index, td, td_index, s, z) {
+                       var t; // temporary pointer
+                       var tp; // temporary pointer
+                       var tp_index; // temporary pointer
+                       var e; // extra bits or operation
+                       var b; // bit buffer
+                       var k; // bits in bit buffer
+                       var p; // input data pointer
+                       var n; // bytes available there
+                       var q; // output window write pointer
+                       var m; // bytes to end of window or read pointer
+                       var ml; // mask for literal/length tree
+                       var md; // mask for distance tree
+                       var c; // bytes to copy
+                       var d; // distance back to copy from
+                       var r; // copy source pointer
+
+                       var tp_index_t_3; // (tp_index+t)*3
+
+                       // load input, output, bit values
+                       p = z.next_in_index;
+                       n = z.avail_in;
+                       b = s.bitb;
+                       k = s.bitk;
+                       q = s.write;
+                       m = q < s.read ? s.read - q - 1 : s.end - q;
+
+                       // initialize masks
+                       ml = inflate_mask[bl];
+                       md = inflate_mask[bd];
+
+                       // do until not enough input or output space for fast loop
+                       do { // assume called with m >= 258 && n >= 10
+                               // get literal/length code
+                               while (k < (20)) { // max bits for literal/length code
+                                       n--;
+                                       b |= (z.read_byte(p++) & 0xff) << k;
+                                       k += 8;
+                               }
+
+                               t = b & ml;
+                               tp = tl;
+                               tp_index = tl_index;
+                               tp_index_t_3 = (tp_index + t) * 3;
+                               if ((e = tp[tp_index_t_3]) === 0) {
+                                       b >>= (tp[tp_index_t_3 + 1]);
+                                       k -= (tp[tp_index_t_3 + 1]);
+
+                                       s.window[q++] = /* (byte) */tp[tp_index_t_3 + 2];
+                                       m--;
+                                       continue;
+                               }
+                               do {
+
+                                       b >>= (tp[tp_index_t_3 + 1]);
+                                       k -= (tp[tp_index_t_3 + 1]);
+
+                                       if ((e & 16) !== 0) {
+                                               e &= 15;
+                                               c = tp[tp_index_t_3 + 2] + (/* (int) */b & inflate_mask[e]);
+
+                                               b >>= e;
+                                               k -= e;
+
+                                               // decode distance base of block to copy
+                                               while (k < (15)) { // max bits for distance code
+                                                       n--;
+                                                       b |= (z.read_byte(p++) & 0xff) << k;
+                                                       k += 8;
+                                               }
+
+                                               t = b & md;
+                                               tp = td;
+                                               tp_index = td_index;
+                                               tp_index_t_3 = (tp_index + t) * 3;
+                                               e = tp[tp_index_t_3];
+
+                                               do {
+
+                                                       b >>= (tp[tp_index_t_3 + 1]);
+                                                       k -= (tp[tp_index_t_3 + 1]);
+
+                                                       if ((e & 16) !== 0) {
+                                                               // get extra bits to add to distance base
+                                                               e &= 15;
+                                                               while (k < (e)) { // get extra bits (up to 13)
+                                                                       n--;
+                                                                       b |= (z.read_byte(p++) & 0xff) << k;
+                                                                       k += 8;
+                                                               }
+
+                                                               d = tp[tp_index_t_3 + 2] + (b & inflate_mask[e]);
+
+                                                               b >>= (e);
+                                                               k -= (e);
+
+                                                               // do the copy
+                                                               m -= c;
+                                                               if (q >= d) { // offset before dest
+                                                                       // just copy
+                                                                       r = q - d;
+                                                                       if (q - r > 0 && 2 > (q - r)) {
+                                                                               s.window[q++] = s.window[r++]; // minimum
+                                                                               // count is
+                                                                               // three,
+                                                                               s.window[q++] = s.window[r++]; // so unroll
+                                                                               // loop a
+                                                                               // little
+                                                                               c -= 2;
+                                                                       } else {
+                                                                               s.window.set(s.window.subarray(r, r + 2), q);
+                                                                               q += 2;
+                                                                               r += 2;
+                                                                               c -= 2;
+                                                                       }
+                                                               } else { // else offset after destination
+                                                                       r = q - d;
+                                                                       do {
+                                                                               r += s.end; // force pointer in window
+                                                                       } while (r < 0); // covers invalid distances
+                                                                       e = s.end - r;
+                                                                       if (c > e) { // if source crosses,
+                                                                               c -= e; // wrapped copy
+                                                                               if (q - r > 0 && e > (q - r)) {
+                                                                                       do {
+                                                                                               s.window[q++] = s.window[r++];
+                                                                                       } while (--e !== 0);
+                                                                               } else {
+                                                                                       s.window.set(s.window.subarray(r, r + e), q);
+                                                                                       q += e;
+                                                                                       r += e;
+                                                                                       e = 0;
+                                                                               }
+                                                                               r = 0; // copy rest from start of window
+                                                                       }
+
+                                                               }
+
+                                                               // copy all or what's left
+                                                               if (q - r > 0 && c > (q - r)) {
+                                                                       do {
+                                                                               s.window[q++] = s.window[r++];
+                                                                       } while (--c !== 0);
+                                                               } else {
+                                                                       s.window.set(s.window.subarray(r, r + c), q);
+                                                                       q += c;
+                                                                       r += c;
+                                                                       c = 0;
+                                                               }
+                                                               break;
+                                                       } else if ((e & 64) === 0) {
+                                                               t += tp[tp_index_t_3 + 2];
+                                                               t += (b & inflate_mask[e]);
+                                                               tp_index_t_3 = (tp_index + t) * 3;
+                                                               e = tp[tp_index_t_3];
+                                                       } else {
+                                                               z.msg = "invalid distance code";
+
+                                                               c = z.avail_in - n;
+                                                               c = (k >> 3) < c ? k >> 3 : c;
+                                                               n += c;
+                                                               p -= c;
+                                                               k -= c << 3;
+
+                                                               s.bitb = b;
+                                                               s.bitk = k;
+                                                               z.avail_in = n;
+                                                               z.total_in += p - z.next_in_index;
+                                                               z.next_in_index = p;
+                                                               s.write = q;
+
+                                                               return Z_DATA_ERROR;
+                                                       }
+                                               } while (true);
+                                               break;
+                                       }
+
+                                       if ((e & 64) === 0) {
+                                               t += tp[tp_index_t_3 + 2];
+                                               t += (b & inflate_mask[e]);
+                                               tp_index_t_3 = (tp_index + t) * 3;
+                                               if ((e = tp[tp_index_t_3]) === 0) {
+
+                                                       b >>= (tp[tp_index_t_3 + 1]);
+                                                       k -= (tp[tp_index_t_3 + 1]);
+
+                                                       s.window[q++] = /* (byte) */tp[tp_index_t_3 + 2];
+                                                       m--;
+                                                       break;
+                                               }
+                                       } else if ((e & 32) !== 0) {
+
+                                               c = z.avail_in - n;
+                                               c = (k >> 3) < c ? k >> 3 : c;
+                                               n += c;
+                                               p -= c;
+                                               k -= c << 3;
+
+                                               s.bitb = b;
+                                               s.bitk = k;
+                                               z.avail_in = n;
+                                               z.total_in += p - z.next_in_index;
+                                               z.next_in_index = p;
+                                               s.write = q;
+
+                                               return Z_STREAM_END;
+                                       } else {
+                                               z.msg = "invalid literal/length code";
+
+                                               c = z.avail_in - n;
+                                               c = (k >> 3) < c ? k >> 3 : c;
+                                               n += c;
+                                               p -= c;
+                                               k -= c << 3;
+
+                                               s.bitb = b;
+                                               s.bitk = k;
+                                               z.avail_in = n;
+                                               z.total_in += p - z.next_in_index;
+                                               z.next_in_index = p;
+                                               s.write = q;
+
+                                               return Z_DATA_ERROR;
+                                       }
+                               } while (true);
+                       } while (m >= 258 && n >= 10);
+
+                       // not enough input or output--restore pointers and return
+                       c = z.avail_in - n;
+                       c = (k >> 3) < c ? k >> 3 : c;
+                       n += c;
+                       p -= c;
+                       k -= c << 3;
+
+                       s.bitb = b;
+                       s.bitk = k;
+                       z.avail_in = n;
+                       z.total_in += p - z.next_in_index;
+                       z.next_in_index = p;
+                       s.write = q;
+
+                       return Z_OK;
+               }
+
+               that.init = function(bl, bd, tl, tl_index, td, td_index) {
+                       mode = START;
+                       lbits = /* (byte) */bl;
+                       dbits = /* (byte) */bd;
+                       ltree = tl;
+                       ltree_index = tl_index;
+                       dtree = td;
+                       dtree_index = td_index;
+                       tree = null;
+               };
+
+               that.proc = function(s, z, r) {
+                       var j; // temporary storage
+                       var tindex; // temporary pointer
+                       var e; // extra bits or operation
+                       var b = 0; // bit buffer
+                       var k = 0; // bits in bit buffer
+                       var p = 0; // input data pointer
+                       var n; // bytes available there
+                       var q; // output window write pointer
+                       var m; // bytes to end of window or read pointer
+                       var f; // pointer to copy strings from
+
+                       // copy input/output information to locals (UPDATE macro restores)
+                       p = z.next_in_index;
+                       n = z.avail_in;
+                       b = s.bitb;
+                       k = s.bitk;
+                       q = s.write;
+                       m = q < s.read ? s.read - q - 1 : s.end - q;
+
+                       // process input and output based on current state
+                       while (true) {
+                               switch (mode) {
+                               // waiting for "i:"=input, "o:"=output, "x:"=nothing
+                               case START: // x: set up for LEN
+                                       if (m >= 258 && n >= 10) {
+
+                                               s.bitb = b;
+                                               s.bitk = k;
+                                               z.avail_in = n;
+                                               z.total_in += p - z.next_in_index;
+                                               z.next_in_index = p;
+                                               s.write = q;
+                                               r = inflate_fast(lbits, dbits, ltree, ltree_index, dtree, dtree_index, s, z);
+
+                                               p = z.next_in_index;
+                                               n = z.avail_in;
+                                               b = s.bitb;
+                                               k = s.bitk;
+                                               q = s.write;
+                                               m = q < s.read ? s.read - q - 1 : s.end - q;
+
+                                               if (r != Z_OK) {
+                                                       mode = r == Z_STREAM_END ? WASH : BADCODE;
+                                                       break;
+                                               }
+                                       }
+                                       need = lbits;
+                                       tree = ltree;
+                                       tree_index = ltree_index;
+
+                                       mode = LEN;
+                               case LEN: // i: get length/literal/eob next
+                                       j = need;
+
+                                       while (k < (j)) {
+                                               if (n !== 0)
+                                                       r = Z_OK;
+                                               else {
+
+                                                       s.bitb = b;
+                                                       s.bitk = k;
+                                                       z.avail_in = n;
+                                                       z.total_in += p - z.next_in_index;
+                                                       z.next_in_index = p;
+                                                       s.write = q;
+                                                       return s.inflate_flush(z, r);
+                                               }
+                                               n--;
+                                               b |= (z.read_byte(p++) & 0xff) << k;
+                                               k += 8;
+                                       }
+
+                                       tindex = (tree_index + (b & inflate_mask[j])) * 3;
+
+                                       b >>>= (tree[tindex + 1]);
+                                       k -= (tree[tindex + 1]);
+
+                                       e = tree[tindex];
+
+                                       if (e === 0) { // literal
+                                               lit = tree[tindex + 2];
+                                               mode = LIT;
+                                               break;
+                                       }
+                                       if ((e & 16) !== 0) { // length
+                                               get = e & 15;
+                                               len = tree[tindex + 2];
+                                               mode = LENEXT;
+                                               break;
+                                       }
+                                       if ((e & 64) === 0) { // next table
+                                               need = e;
+                                               tree_index = tindex / 3 + tree[tindex + 2];
+                                               break;
+                                       }
+                                       if ((e & 32) !== 0) { // end of block
+                                               mode = WASH;
+                                               break;
+                                       }
+                                       mode = BADCODE; // invalid code
+                                       z.msg = "invalid literal/length code";
+                                       r = Z_DATA_ERROR;
+
+                                       s.bitb = b;
+                                       s.bitk = k;
+                                       z.avail_in = n;
+                                       z.total_in += p - z.next_in_index;
+                                       z.next_in_index = p;
+                                       s.write = q;
+                                       return s.inflate_flush(z, r);
+
+                               case LENEXT: // i: getting length extra (have base)
+                                       j = get;
+
+                                       while (k < (j)) {
+                                               if (n !== 0)
+                                                       r = Z_OK;
+                                               else {
+
+                                                       s.bitb = b;
+                                                       s.bitk = k;
+                                                       z.avail_in = n;
+                                                       z.total_in += p - z.next_in_index;
+                                                       z.next_in_index = p;
+                                                       s.write = q;
+                                                       return s.inflate_flush(z, r);
+                                               }
+                                               n--;
+                                               b |= (z.read_byte(p++) & 0xff) << k;
+                                               k += 8;
+                                       }
+
+                                       len += (b & inflate_mask[j]);
+
+                                       b >>= j;
+                                       k -= j;
+
+                                       need = dbits;
+                                       tree = dtree;
+                                       tree_index = dtree_index;
+                                       mode = DIST;
+                               case DIST: // i: get distance next
+                                       j = need;
+
+                                       while (k < (j)) {
+                                               if (n !== 0)
+                                                       r = Z_OK;
+                                               else {
+
+                                                       s.bitb = b;
+                                                       s.bitk = k;
+                                                       z.avail_in = n;
+                                                       z.total_in += p - z.next_in_index;
+                                                       z.next_in_index = p;
+                                                       s.write = q;
+                                                       return s.inflate_flush(z, r);
+                                               }
+                                               n--;
+                                               b |= (z.read_byte(p++) & 0xff) << k;
+                                               k += 8;
+                                       }
+
+                                       tindex = (tree_index + (b & inflate_mask[j])) * 3;
+
+                                       b >>= tree[tindex + 1];
+                                       k -= tree[tindex + 1];
+
+                                       e = (tree[tindex]);
+                                       if ((e & 16) !== 0) { // distance
+                                               get = e & 15;
+                                               dist = tree[tindex + 2];
+                                               mode = DISTEXT;
+                                               break;
+                                       }
+                                       if ((e & 64) === 0) { // next table
+                                               need = e;
+                                               tree_index = tindex / 3 + tree[tindex + 2];
+                                               break;
+                                       }
+                                       mode = BADCODE; // invalid code
+                                       z.msg = "invalid distance code";
+                                       r = Z_DATA_ERROR;
+
+                                       s.bitb = b;
+                                       s.bitk = k;
+                                       z.avail_in = n;
+                                       z.total_in += p - z.next_in_index;
+                                       z.next_in_index = p;
+                                       s.write = q;
+                                       return s.inflate_flush(z, r);
+
+                               case DISTEXT: // i: getting distance extra
+                                       j = get;
+
+                                       while (k < (j)) {
+                                               if (n !== 0)
+                                                       r = Z_OK;
+                                               else {
+
+                                                       s.bitb = b;
+                                                       s.bitk = k;
+                                                       z.avail_in = n;
+                                                       z.total_in += p - z.next_in_index;
+                                                       z.next_in_index = p;
+                                                       s.write = q;
+                                                       return s.inflate_flush(z, r);
+                                               }
+                                               n--;
+                                               b |= (z.read_byte(p++) & 0xff) << k;
+                                               k += 8;
+                                       }
+
+                                       dist += (b & inflate_mask[j]);
+
+                                       b >>= j;
+                                       k -= j;
+
+                                       mode = COPY;
+                               case COPY: // o: copying bytes in window, waiting for space
+                                       f = q - dist;
+                                       while (f < 0) { // modulo window size-"while" instead
+                                               f += s.end; // of "if" handles invalid distances
+                                       }
+                                       while (len !== 0) {
+
+                                               if (m === 0) {
+                                                       if (q == s.end && s.read !== 0) {
+                                                               q = 0;
+                                                               m = q < s.read ? s.read - q - 1 : s.end - q;
+                                                       }
+                                                       if (m === 0) {
+                                                               s.write = q;
+                                                               r = s.inflate_flush(z, r);
+                                                               q = s.write;
+                                                               m = q < s.read ? s.read - q - 1 : s.end - q;
+
+                                                               if (q == s.end && s.read !== 0) {
+                                                                       q = 0;
+                                                                       m = q < s.read ? s.read - q - 1 : s.end - q;
+                                                               }
+
+                                                               if (m === 0) {
+                                                                       s.bitb = b;
+                                                                       s.bitk = k;
+                                                                       z.avail_in = n;
+                                                                       z.total_in += p - z.next_in_index;
+                                                                       z.next_in_index = p;
+                                                                       s.write = q;
+                                                                       return s.inflate_flush(z, r);
+                                                               }
+                                                       }
+                                               }
+
+                                               s.window[q++] = s.window[f++];
+                                               m--;
+
+                                               if (f == s.end)
+                                                       f = 0;
+                                               len--;
+                                       }
+                                       mode = START;
+                                       break;
+                               case LIT: // o: got literal, waiting for output space
+                                       if (m === 0) {
+                                               if (q == s.end && s.read !== 0) {
+                                                       q = 0;
+                                                       m = q < s.read ? s.read - q - 1 : s.end - q;
+                                               }
+                                               if (m === 0) {
+                                                       s.write = q;
+                                                       r = s.inflate_flush(z, r);
+                                                       q = s.write;
+                                                       m = q < s.read ? s.read - q - 1 : s.end - q;
+
+                                                       if (q == s.end && s.read !== 0) {
+                                                               q = 0;
+                                                               m = q < s.read ? s.read - q - 1 : s.end - q;
+                                                       }
+                                                       if (m === 0) {
+                                                               s.bitb = b;
+                                                               s.bitk = k;
+                                                               z.avail_in = n;
+                                                               z.total_in += p - z.next_in_index;
+                                                               z.next_in_index = p;
+                                                               s.write = q;
+                                                               return s.inflate_flush(z, r);
+                                                       }
+                                               }
+                                       }
+                                       r = Z_OK;
+
+                                       s.window[q++] = /* (byte) */lit;
+                                       m--;
+
+                                       mode = START;
+                                       break;
+                               case WASH: // o: got eob, possibly more output
+                                       if (k > 7) { // return unused byte, if any
+                                               k -= 8;
+                                               n++;
+                                               p--; // can always return one
+                                       }
+
+                                       s.write = q;
+                                       r = s.inflate_flush(z, r);
+                                       q = s.write;
+                                       m = q < s.read ? s.read - q - 1 : s.end - q;
+
+                                       if (s.read != s.write) {
+                                               s.bitb = b;
+                                               s.bitk = k;
+                                               z.avail_in = n;
+                                               z.total_in += p - z.next_in_index;
+                                               z.next_in_index = p;
+                                               s.write = q;
+                                               return s.inflate_flush(z, r);
+                                       }
+                                       mode = END;
+                               case END:
+                                       r = Z_STREAM_END;
+                                       s.bitb = b;
+                                       s.bitk = k;
+                                       z.avail_in = n;
+                                       z.total_in += p - z.next_in_index;
+                                       z.next_in_index = p;
+                                       s.write = q;
+                                       return s.inflate_flush(z, r);
+
+                               case BADCODE: // x: got error
+
+                                       r = Z_DATA_ERROR;
+
+                                       s.bitb = b;
+                                       s.bitk = k;
+                                       z.avail_in = n;
+                                       z.total_in += p - z.next_in_index;
+                                       z.next_in_index = p;
+                                       s.write = q;
+                                       return s.inflate_flush(z, r);
+
+                               default:
+                                       r = Z_STREAM_ERROR;
+
+                                       s.bitb = b;
+                                       s.bitk = k;
+                                       z.avail_in = n;
+                                       z.total_in += p - z.next_in_index;
+                                       z.next_in_index = p;
+                                       s.write = q;
+                                       return s.inflate_flush(z, r);
+                               }
+                       }
+               };
+
+               that.free = function() {
+                       // ZFREE(z, c);
+               };
+
+       }
+
+       // InfBlocks
+
+       // Table for deflate from PKZIP's appnote.txt.
+       var border = [ // Order of the bit length code lengths
+       16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 ];
+
+       var TYPE = 0; // get type bits (3, including end bit)
+       var LENS = 1; // get lengths for stored
+       var STORED = 2;// processing stored block
+       var TABLE = 3; // get table lengths
+       var BTREE = 4; // get bit lengths tree for a dynamic
+       // block
+       var DTREE = 5; // get length, distance trees for a
+       // dynamic block
+       var CODES = 6; // processing fixed or dynamic block
+       var DRY = 7; // output remaining window bytes
+       var DONELOCKS = 8; // finished last block, done
+       var BADBLOCKS = 9; // ot a data error--stuck here
+
+       function InfBlocks(z, w) {
+               var that = this;
+
+               var mode = TYPE; // current inflate_block mode
+
+               var left = 0; // if STORED, bytes left to copy
+
+               var table = 0; // table lengths (14 bits)
+               var index = 0; // index into blens (or border)
+               var blens; // bit lengths of codes
+               var bb = [ 0 ]; // bit length tree depth
+               var tb = [ 0 ]; // bit length decoding tree
+
+               var codes = new InfCodes(); // if CODES, current state
+
+               var last = 0; // true if this block is the last block
+
+               var hufts = new Int32Array(MANY * 3); // single malloc for tree space
+               var check = 0; // check on output
+               var inftree = new InfTree();
+
+               that.bitk = 0; // bits in bit buffer
+               that.bitb = 0; // bit buffer
+               that.window = new Uint8Array(w); // sliding window
+               that.end = w; // one byte after sliding window
+               that.read = 0; // window read pointer
+               that.write = 0; // window write pointer
+
+               that.reset = function(z, c) {
+                       if (c)
+                               c[0] = check;
+                       // if (mode == BTREE || mode == DTREE) {
+                       // }
+                       if (mode == CODES) {
+                               codes.free(z);
+                       }
+                       mode = TYPE;
+                       that.bitk = 0;
+                       that.bitb = 0;
+                       that.read = that.write = 0;
+               };
+
+               that.reset(z, null);
+
+               // copy as much as possible from the sliding window to the output area
+               that.inflate_flush = function(z, r) {
+                       var n;
+                       var p;
+                       var q;
+
+                       // local copies of source and destination pointers
+                       p = z.next_out_index;
+                       q = that.read;
+
+                       // compute number of bytes to copy as far as end of window
+                       n = /* (int) */((q <= that.write ? that.write : that.end) - q);
+                       if (n > z.avail_out)
+                               n = z.avail_out;
+                       if (n !== 0 && r == Z_BUF_ERROR)
+                               r = Z_OK;
+
+                       // update counters
+                       z.avail_out -= n;
+                       z.total_out += n;
+
+                       // copy as far as end of window
+                       z.next_out.set(that.window.subarray(q, q + n), p);
+                       p += n;
+                       q += n;
+
+                       // see if more to copy at beginning of window
+                       if (q == that.end) {
+                               // wrap pointers
+                               q = 0;
+                               if (that.write == that.end)
+                                       that.write = 0;
+
+                               // compute bytes to copy
+                               n = that.write - q;
+                               if (n > z.avail_out)
+                                       n = z.avail_out;
+                               if (n !== 0 && r == Z_BUF_ERROR)
+                                       r = Z_OK;
+
+                               // update counters
+                               z.avail_out -= n;
+                               z.total_out += n;
+
+                               // copy
+                               z.next_out.set(that.window.subarray(q, q + n), p);
+                               p += n;
+                               q += n;
+                       }
+
+                       // update pointers
+                       z.next_out_index = p;
+                       that.read = q;
+
+                       // done
+                       return r;
+               };
+
+               that.proc = function(z, r) {
+                       var t; // temporary storage
+                       var b; // bit buffer
+                       var k; // bits in bit buffer
+                       var p; // input data pointer
+                       var n; // bytes available there
+                       var q; // output window write pointer
+                       var m; // bytes to end of window or read pointer
+
+                       var i;
+
+                       // copy input/output information to locals (UPDATE macro restores)
+                       // {
+                       p = z.next_in_index;
+                       n = z.avail_in;
+                       b = that.bitb;
+                       k = that.bitk;
+                       // }
+                       // {
+                       q = that.write;
+                       m = /* (int) */(q < that.read ? that.read - q - 1 : that.end - q);
+                       // }
+
+                       // process input based on current state
+                       // DEBUG dtree
+                       while (true) {
+                               switch (mode) {
+                               case TYPE:
+
+                                       while (k < (3)) {
+                                               if (n !== 0) {
+                                                       r = Z_OK;
+                                               } else {
+                                                       that.bitb = b;
+                                                       that.bitk = k;
+                                                       z.avail_in = n;
+                                                       z.total_in += p - z.next_in_index;
+                                                       z.next_in_index = p;
+                                                       that.write = q;
+                                                       return that.inflate_flush(z, r);
+                                               }
+                                               n--;
+                                               b |= (z.read_byte(p++) & 0xff) << k;
+                                               k += 8;
+                                       }
+                                       t = /* (int) */(b & 7);
+                                       last = t & 1;
+
+                                       switch (t >>> 1) {
+                                       case 0: // stored
+                                               // {
+                                               b >>>= (3);
+                                               k -= (3);
+                                               // }
+                                               t = k & 7; // go to byte boundary
+
+                                               // {
+                                               b >>>= (t);
+                                               k -= (t);
+                                               // }
+                                               mode = LENS; // get length of stored block
+                                               break;
+                                       case 1: // fixed
+                                               // {
+                                               var bl = []; // new Array(1);
+                                               var bd = []; // new Array(1);
+                                               var tl = [ [] ]; // new Array(1);
+                                               var td = [ [] ]; // new Array(1);
+
+                                               InfTree.inflate_trees_fixed(bl, bd, tl, td);
+                                               codes.init(bl[0], bd[0], tl[0], 0, td[0], 0);
+                                               // }
+
+                                               // {
+                                               b >>>= (3);
+                                               k -= (3);
+                                               // }
+
+                                               mode = CODES;
+                                               break;
+                                       case 2: // dynamic
+
+                                               // {
+                                               b >>>= (3);
+                                               k -= (3);
+                                               // }
+
+                                               mode = TABLE;
+                                               break;
+                                       case 3: // illegal
+
+                                               // {
+                                               b >>>= (3);
+                                               k -= (3);
+                                               // }
+                                               mode = BADBLOCKS;
+                                               z.msg = "invalid block type";
+                                               r = Z_DATA_ERROR;
+
+                                               that.bitb = b;
+                                               that.bitk = k;
+                                               z.avail_in = n;
+                                               z.total_in += p - z.next_in_index;
+                                               z.next_in_index = p;
+                                               that.write = q;
+                                               return that.inflate_flush(z, r);
+                                       }
+                                       break;
+                               case LENS:
+
+                                       while (k < (32)) {
+                                               if (n !== 0) {
+                                                       r = Z_OK;
+                                               } else {
+                                                       that.bitb = b;
+                                                       that.bitk = k;
+                                                       z.avail_in = n;
+                                                       z.total_in += p - z.next_in_index;
+                                                       z.next_in_index = p;
+                                                       that.write = q;
+                                                       return that.inflate_flush(z, r);
+                                               }
+                                               n--;
+                                               b |= (z.read_byte(p++) & 0xff) << k;
+                                               k += 8;
+                                       }
+
+                                       if ((((~b) >>> 16) & 0xffff) != (b & 0xffff)) {
+                                               mode = BADBLOCKS;
+                                               z.msg = "invalid stored block lengths";
+                                               r = Z_DATA_ERROR;
+
+                                               that.bitb = b;
+                                               that.bitk = k;
+                                               z.avail_in = n;
+                                               z.total_in += p - z.next_in_index;
+                                               z.next_in_index = p;
+                                               that.write = q;
+                                               return that.inflate_flush(z, r);
+                                       }
+                                       left = (b & 0xffff);
+                                       b = k = 0; // dump bits
+                                       mode = left !== 0 ? STORED : (last !== 0 ? DRY : TYPE);
+                                       break;
+                               case STORED:
+                                       if (n === 0) {
+                                               that.bitb = b;
+                                               that.bitk = k;
+                                               z.avail_in = n;
+                                               z.total_in += p - z.next_in_index;
+                                               z.next_in_index = p;
+                                               that.write = q;
+                                               return that.inflate_flush(z, r);
+                                       }
+
+                                       if (m === 0) {
+                                               if (q == that.end && that.read !== 0) {
+                                                       q = 0;
+                                                       m = /* (int) */(q < that.read ? that.read - q - 1 : that.end - q);
+                                               }
+                                               if (m === 0) {
+                                                       that.write = q;
+                                                       r = that.inflate_flush(z, r);
+                                                       q = that.write;
+                                                       m = /* (int) */(q < that.read ? that.read - q - 1 : that.end - q);
+                                                       if (q == that.end && that.read !== 0) {
+                                                               q = 0;
+                                                               m = /* (int) */(q < that.read ? that.read - q - 1 : that.end - q);
+                                                       }
+                                                       if (m === 0) {
+                                                               that.bitb = b;
+                                                               that.bitk = k;
+                                                               z.avail_in = n;
+                                                               z.total_in += p - z.next_in_index;
+                                                               z.next_in_index = p;
+                                                               that.write = q;
+                                                               return that.inflate_flush(z, r);
+                                                       }
+                                               }
+                                       }
+                                       r = Z_OK;
+
+                                       t = left;
+                                       if (t > n)
+                                               t = n;
+                                       if (t > m)
+                                               t = m;
+                                       that.window.set(z.read_buf(p, t), q);
+                                       p += t;
+                                       n -= t;
+                                       q += t;
+                                       m -= t;
+                                       if ((left -= t) !== 0)
+                                               break;
+                                       mode = last !== 0 ? DRY : TYPE;
+                                       break;
+                               case TABLE:
+
+                                       while (k < (14)) {
+                                               if (n !== 0) {
+                                                       r = Z_OK;
+                                               } else {
+                                                       that.bitb = b;
+                                                       that.bitk = k;
+                                                       z.avail_in = n;
+                                                       z.total_in += p - z.next_in_index;
+                                                       z.next_in_index = p;
+                                                       that.write = q;
+                                                       return that.inflate_flush(z, r);
+                                               }
+
+                                               n--;
+                                               b |= (z.read_byte(p++) & 0xff) << k;
+                                               k += 8;
+                                       }
+
+                                       table = t = (b & 0x3fff);
+                                       if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29) {
+                                               mode = BADBLOCKS;
+                                               z.msg = "too many length or distance symbols";
+                                               r = Z_DATA_ERROR;
+
+                                               that.bitb = b;
+                                               that.bitk = k;
+                                               z.avail_in = n;
+                                               z.total_in += p - z.next_in_index;
+                                               z.next_in_index = p;
+                                               that.write = q;
+                                               return that.inflate_flush(z, r);
+                                       }
+                                       t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);
+                                       if (!blens || blens.length < t) {
+                                               blens = []; // new Array(t);
+                                       } else {
+                                               for (i = 0; i < t; i++) {
+                                                       blens[i] = 0;
+                                               }
+                                       }
+
+                                       // {
+                                       b >>>= (14);
+                                       k -= (14);
+                                       // }
+
+                                       index = 0;
+                                       mode = BTREE;
+                               case BTREE:
+                                       while (index < 4 + (table >>> 10)) {
+                                               while (k < (3)) {
+                                                       if (n !== 0) {
+                                                               r = Z_OK;
+                                                       } else {
+                                                               that.bitb = b;
+                                                               that.bitk = k;
+                                                               z.avail_in = n;
+                                                               z.total_in += p - z.next_in_index;
+                                                               z.next_in_index = p;
+                                                               that.write = q;
+                                                               return that.inflate_flush(z, r);
+                                                       }
+                                                       n--;
+                                                       b |= (z.read_byte(p++) & 0xff) << k;
+                                                       k += 8;
+                                               }
+
+                                               blens[border[index++]] = b & 7;
+
+                                               // {
+                                               b >>>= (3);
+                                               k -= (3);
+                                               // }
+                                       }
+
+                                       while (index < 19) {
+                                               blens[border[index++]] = 0;
+                                       }
+
+                                       bb[0] = 7;
+                                       t = inftree.inflate_trees_bits(blens, bb, tb, hufts, z);
+                                       if (t != Z_OK) {
+                                               r = t;
+                                               if (r == Z_DATA_ERROR) {
+                                                       blens = null;
+                                                       mode = BADBLOCKS;
+                                               }
+
+                                               that.bitb = b;
+                                               that.bitk = k;
+                                               z.avail_in = n;
+                                               z.total_in += p - z.next_in_index;
+                                               z.next_in_index = p;
+                                               that.write = q;
+                                               return that.inflate_flush(z, r);
+                                       }
+
+                                       index = 0;
+                                       mode = DTREE;
+                               case DTREE:
+                                       while (true) {
+                                               t = table;
+                                               if (!(index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))) {
+                                                       break;
+                                               }
+
+                                               var j, c;
+
+                                               t = bb[0];
+
+                                               while (k < (t)) {
+                                                       if (n !== 0) {
+                                                               r = Z_OK;
+                                                       } else {
+                                                               that.bitb = b;
+                                                               that.bitk = k;
+                                                               z.avail_in = n;
+                                                               z.total_in += p - z.next_in_index;
+                                                               z.next_in_index = p;
+                                                               that.write = q;
+                                                               return that.inflate_flush(z, r);
+                                                       }
+                                                       n--;
+                                                       b |= (z.read_byte(p++) & 0xff) << k;
+                                                       k += 8;
+                                               }
+
+                                               // if (tb[0] == -1) {
+                                               // System.err.println("null...");
+                                               // }
+
+                                               t = hufts[(tb[0] + (b & inflate_mask[t])) * 3 + 1];
+                                               c = hufts[(tb[0] + (b & inflate_mask[t])) * 3 + 2];
+
+                                               if (c < 16) {
+                                                       b >>>= (t);
+                                                       k -= (t);
+                                                       blens[index++] = c;
+                                               } else { // c == 16..18
+                                                       i = c == 18 ? 7 : c - 14;
+                                                       j = c == 18 ? 11 : 3;
+
+                                                       while (k < (t + i)) {
+                                                               if (n !== 0) {
+                                                                       r = Z_OK;
+                                                               } else {
+                                                                       that.bitb = b;
+                                                                       that.bitk = k;
+                                                                       z.avail_in = n;
+                                                                       z.total_in += p - z.next_in_index;
+                                                                       z.next_in_index = p;
+                                                                       that.write = q;
+                                                                       return that.inflate_flush(z, r);
+                                                               }
+                                                               n--;
+                                                               b |= (z.read_byte(p++) & 0xff) << k;
+                                                               k += 8;
+                                                       }
+
+                                                       b >>>= (t);
+                                                       k -= (t);
+
+                                                       j += (b & inflate_mask[i]);
+
+                                                       b >>>= (i);
+                                                       k -= (i);
+
+                                                       i = index;
+                                                       t = table;
+                                                       if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || (c == 16 && i < 1)) {
+                                                               blens = null;
+                                                               mode = BADBLOCKS;
+                                                               z.msg = "invalid bit length repeat";
+                                                               r = Z_DATA_ERROR;
+
+                                                               that.bitb = b;
+                                                               that.bitk = k;
+                                                               z.avail_in = n;
+                                                               z.total_in += p - z.next_in_index;
+                                                               z.next_in_index = p;
+                                                               that.write = q;
+                                                               return that.inflate_flush(z, r);
+                                                       }
+
+                                                       c = c == 16 ? blens[i - 1] : 0;
+                                                       do {
+                                                               blens[i++] = c;
+                                                       } while (--j !== 0);
+                                                       index = i;
+                                               }
+                                       }
+
+                                       tb[0] = -1;
+                                       // {
+                                       var bl_ = []; // new Array(1);
+                                       var bd_ = []; // new Array(1);
+                                       var tl_ = []; // new Array(1);
+                                       var td_ = []; // new Array(1);
+                                       bl_[0] = 9; // must be <= 9 for lookahead assumptions
+                                       bd_[0] = 6; // must be <= 9 for lookahead assumptions
+
+                                       t = table;
+                                       t = inftree.inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), blens, bl_, bd_, tl_, td_, hufts, z);
+
+                                       if (t != Z_OK) {
+                                               if (t == Z_DATA_ERROR) {
+                                                       blens = null;
+                                                       mode = BADBLOCKS;
+                                               }
+                                               r = t;
+
+                                               that.bitb = b;
+                                               that.bitk = k;
+                                               z.avail_in = n;
+                                               z.total_in += p - z.next_in_index;
+                                               z.next_in_index = p;
+                                               that.write = q;
+                                               return that.inflate_flush(z, r);
+                                       }
+                                       codes.init(bl_[0], bd_[0], hufts, tl_[0], hufts, td_[0]);
+                                       // }
+                                       mode = CODES;
+                               case CODES:
+                                       that.bitb = b;
+                                       that.bitk = k;
+                                       z.avail_in = n;
+                                       z.total_in += p - z.next_in_index;
+                                       z.next_in_index = p;
+                                       that.write = q;
+
+                                       if ((r = codes.proc(that, z, r)) != Z_STREAM_END) {
+                                               return that.inflate_flush(z, r);
+                                       }
+                                       r = Z_OK;
+                                       codes.free(z);
+
+                                       p = z.next_in_index;
+                                       n = z.avail_in;
+                                       b = that.bitb;
+                                       k = that.bitk;
+                                       q = that.write;
+                                       m = /* (int) */(q < that.read ? that.read - q - 1 : that.end - q);
+
+                                       if (last === 0) {
+                                               mode = TYPE;
+                                               break;
+                                       }
+                                       mode = DRY;
+                               case DRY:
+                                       that.write = q;
+                                       r = that.inflate_flush(z, r);
+                                       q = that.write;
+                                       m = /* (int) */(q < that.read ? that.read - q - 1 : that.end - q);
+                                       if (that.read != that.write) {
+                                               that.bitb = b;
+                                               that.bitk = k;
+                                               z.avail_in = n;
+                                               z.total_in += p - z.next_in_index;
+                                               z.next_in_index = p;
+                                               that.write = q;
+                                               return that.inflate_flush(z, r);
+                                       }
+                                       mode = DONELOCKS;
+                               case DONELOCKS:
+                                       r = Z_STREAM_END;
+
+                                       that.bitb = b;
+                                       that.bitk = k;
+                                       z.avail_in = n;
+                                       z.total_in += p - z.next_in_index;
+                                       z.next_in_index = p;
+                                       that.write = q;
+                                       return that.inflate_flush(z, r);
+                               case BADBLOCKS:
+                                       r = Z_DATA_ERROR;
+
+                                       that.bitb = b;
+                                       that.bitk = k;
+                                       z.avail_in = n;
+                                       z.total_in += p - z.next_in_index;
+                                       z.next_in_index = p;
+                                       that.write = q;
+                                       return that.inflate_flush(z, r);
+
+                               default:
+                                       r = Z_STREAM_ERROR;
+
+                                       that.bitb = b;
+                                       that.bitk = k;
+                                       z.avail_in = n;
+                                       z.total_in += p - z.next_in_index;
+                                       z.next_in_index = p;
+                                       that.write = q;
+                                       return that.inflate_flush(z, r);
+                               }
+                       }
+               };
+
+               that.free = function(z) {
+                       that.reset(z, null);
+                       that.window = null;
+                       hufts = null;
+                       // ZFREE(z, s);
+               };
+
+               that.set_dictionary = function(d, start, n) {
+                       that.window.set(d.subarray(start, start + n), 0);
+                       that.read = that.write = n;
+               };
+
+               // Returns true if inflate is currently at the end of a block generated
+               // by Z_SYNC_FLUSH or Z_FULL_FLUSH.
+               that.sync_point = function() {
+                       return mode == LENS ? 1 : 0;
+               };
+
+       }
+
+       // Inflate
+
+       // preset dictionary flag in zlib header
+       var PRESET_DICT = 0x20;
+
+       var Z_DEFLATED = 8;
+
+       var METHOD = 0; // waiting for method byte
+       var FLAG = 1; // waiting for flag byte
+       var DICT4 = 2; // four dictionary check bytes to go
+       var DICT3 = 3; // three dictionary check bytes to go
+       var DICT2 = 4; // two dictionary check bytes to go
+       var DICT1 = 5; // one dictionary check byte to go
+       var DICT0 = 6; // waiting for inflateSetDictionary
+       var BLOCKS = 7; // decompressing blocks
+       var DONE = 12; // finished check, done
+       var BAD = 13; // got an error--stay here
+
+       var mark = [ 0, 0, 0xff, 0xff ];
+
+       function Inflate() {
+               var that = this;
+
+               that.mode = 0; // current inflate mode
+
+               // mode dependent information
+               that.method = 0; // if FLAGS, method byte
+
+               // if CHECK, check values to compare
+               that.was = [ 0 ]; // new Array(1); // computed check value
+               that.need = 0; // stream check value
+
+               // if BAD, inflateSync's marker bytes count
+               that.marker = 0;
+
+               // mode independent information
+               that.wbits = 0; // log2(window size) (8..15, defaults to 15)
+
+               // this.blocks; // current inflate_blocks state
+
+               function inflateReset(z) {
+                       if (!z || !z.istate)
+                               return Z_STREAM_ERROR;
+
+                       z.total_in = z.total_out = 0;
+                       z.msg = null;
+                       z.istate.mode = BLOCKS;
+                       z.istate.blocks.reset(z, null);
+                       return Z_OK;
+               }
+
+               that.inflateEnd = function(z) {
+                       if (that.blocks)
+                               that.blocks.free(z);
+                       that.blocks = null;
+                       // ZFREE(z, z->state);
+                       return Z_OK;
+               };
+
+               that.inflateInit = function(z, w) {
+                       z.msg = null;
+                       that.blocks = null;
+
+                       // set window size
+                       if (w < 8 || w > 15) {
+                               that.inflateEnd(z);
+                               return Z_STREAM_ERROR;
+                       }
+                       that.wbits = w;
+
+                       z.istate.blocks = new InfBlocks(z, 1 << w);
+
+                       // reset state
+                       inflateReset(z);
+                       return Z_OK;
+               };
+
+               that.inflate = function(z, f) {
+                       var r;
+                       var b;
+
+                       if (!z || !z.istate || !z.next_in)
+                               return Z_STREAM_ERROR;
+                       f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK;
+                       r = Z_BUF_ERROR;
+                       while (true) {
+                               // System.out.println("mode: "+z.istate.mode);
+                               switch (z.istate.mode) {
+                               case METHOD:
+
+                                       if (z.avail_in === 0)
+                                               return r;
+                                       r = f;
+
+                                       z.avail_in--;
+                                       z.total_in++;
+                                       if (((z.istate.method = z.read_byte(z.next_in_index++)) & 0xf) != Z_DEFLATED) {
+                                               z.istate.mode = BAD;
+                                               z.msg = "unknown compression method";
+                                               z.istate.marker = 5; // can't try inflateSync
+                                               break;
+                                       }
+                                       if ((z.istate.method >> 4) + 8 > z.istate.wbits) {
+                                               z.istate.mode = BAD;
+                                               z.msg = "invalid window size";
+                                               z.istate.marker = 5; // can't try inflateSync
+                                               break;
+                                       }
+                                       z.istate.mode = FLAG;
+                               case FLAG:
+
+                                       if (z.avail_in === 0)
+                                               return r;
+                                       r = f;
+
+                                       z.avail_in--;
+                                       z.total_in++;
+                                       b = (z.read_byte(z.next_in_index++)) & 0xff;
+
+                                       if ((((z.istate.method << 8) + b) % 31) !== 0) {
+                                               z.istate.mode = BAD;
+                                               z.msg = "incorrect header check";
+                                               z.istate.marker = 5; // can't try inflateSync
+                                               break;
+                                       }
+
+                                       if ((b & PRESET_DICT) === 0) {
+                                               z.istate.mode = BLOCKS;
+                                               break;
+                                       }
+                                       z.istate.mode = DICT4;
+                               case DICT4:
+
+                                       if (z.avail_in === 0)
+                                               return r;
+                                       r = f;
+
+                                       z.avail_in--;
+                                       z.total_in++;
+                                       z.istate.need = ((z.read_byte(z.next_in_index++) & 0xff) << 24) & 0xff000000;
+                                       z.istate.mode = DICT3;
+                               case DICT3:
+
+                                       if (z.avail_in === 0)
+                                               return r;
+                                       r = f;
+
+                                       z.avail_in--;
+                                       z.total_in++;
+                                       z.istate.need += ((z.read_byte(z.next_in_index++) & 0xff) << 16) & 0xff0000;
+                                       z.istate.mode = DICT2;
+                               case DICT2:
+
+                                       if (z.avail_in === 0)
+                                               return r;
+                                       r = f;
+
+                                       z.avail_in--;
+                                       z.total_in++;
+                                       z.istate.need += ((z.read_byte(z.next_in_index++) & 0xff) << 8) & 0xff00;
+                                       z.istate.mode = DICT1;
+                               case DICT1:
+
+                                       if (z.avail_in === 0)
+                                               return r;
+                                       r = f;
+
+                                       z.avail_in--;
+                                       z.total_in++;
+                                       z.istate.need += (z.read_byte(z.next_in_index++) & 0xff);
+                                       z.istate.mode = DICT0;
+                                       return Z_NEED_DICT;
+                               case DICT0:
+                                       z.istate.mode = BAD;
+                                       z.msg = "need dictionary";
+                                       z.istate.marker = 0; // can try inflateSync
+                                       return Z_STREAM_ERROR;
+                               case BLOCKS:
+
+                                       r = z.istate.blocks.proc(z, r);
+                                       if (r == Z_DATA_ERROR) {
+                                               z.istate.mode = BAD;
+                                               z.istate.marker = 0; // can try inflateSync
+                                               break;
+                                       }
+                                       if (r == Z_OK) {
+                                               r = f;
+                                       }
+                                       if (r != Z_STREAM_END) {
+                                               return r;
+                                       }
+                                       r = f;
+                                       z.istate.blocks.reset(z, z.istate.was);
+                                       z.istate.mode = DONE;
+                               case DONE:
+                                       return Z_STREAM_END;
+                               case BAD:
+                                       return Z_DATA_ERROR;
+                               default:
+                                       return Z_STREAM_ERROR;
+                               }
+                       }
+               };
+
+               that.inflateSetDictionary = function(z, dictionary, dictLength) {
+                       var index = 0;
+                       var length = dictLength;
+                       if (!z || !z.istate || z.istate.mode != DICT0)
+                               return Z_STREAM_ERROR;
+
+                       if (length >= (1 << z.istate.wbits)) {
+                               length = (1 << z.istate.wbits) - 1;
+                               index = dictLength - length;
+                       }
+                       z.istate.blocks.set_dictionary(dictionary, index, length);
+                       z.istate.mode = BLOCKS;
+                       return Z_OK;
+               };
+
+               that.inflateSync = function(z) {
+                       var n; // number of bytes to look at
+                       var p; // pointer to bytes
+                       var m; // number of marker bytes found in a row
+                       var r, w; // temporaries to save total_in and total_out
+
+                       // set up
+                       if (!z || !z.istate)
+                               return Z_STREAM_ERROR;
+                       if (z.istate.mode != BAD) {
+                               z.istate.mode = BAD;
+                               z.istate.marker = 0;
+                       }
+                       if ((n = z.avail_in) === 0)
+                               return Z_BUF_ERROR;
+                       p = z.next_in_index;
+                       m = z.istate.marker;
+
+                       // search
+                       while (n !== 0 && m < 4) {
+                               if (z.read_byte(p) == mark[m]) {
+                                       m++;
+                               } else if (z.read_byte(p) !== 0) {
+                                       m = 0;
+                               } else {
+                                       m = 4 - m;
+                               }
+                               p++;
+                               n--;
+                       }
+
+                       // restore
+                       z.total_in += p - z.next_in_index;
+                       z.next_in_index = p;
+                       z.avail_in = n;
+                       z.istate.marker = m;
+
+                       // return no joy or set up to restart on a new block
+                       if (m != 4) {
+                               return Z_DATA_ERROR;
+                       }
+                       r = z.total_in;
+                       w = z.total_out;
+                       inflateReset(z);
+                       z.total_in = r;
+                       z.total_out = w;
+                       z.istate.mode = BLOCKS;
+                       return Z_OK;
+               };
+
+               // Returns true if inflate is currently at the end of a block generated
+               // by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
+               // implementation to provide an additional safety check. PPP uses
+               // Z_SYNC_FLUSH
+               // but removes the length bytes of the resulting empty stored block. When
+               // decompressing, PPP checks that at the end of input packet, inflate is
+               // waiting for these length bytes.
+               that.inflateSyncPoint = function(z) {
+                       if (!z || !z.istate || !z.istate.blocks)
+                               return Z_STREAM_ERROR;
+                       return z.istate.blocks.sync_point();
+               };
+       }
+
+       // ZStream
+
+       function ZStream() {
+       }
+
+       ZStream.prototype = {
+               inflateInit : function(bits) {
+                       var that = this;
+                       that.istate = new Inflate();
+                       if (!bits)
+                               bits = MAX_BITS;
+                       return that.istate.inflateInit(that, bits);
+               },
+
+               inflate : function(f) {
+                       var that = this;
+                       if (!that.istate)
+                               return Z_STREAM_ERROR;
+                       return that.istate.inflate(that, f);
+               },
+
+               inflateEnd : function() {
+                       var that = this;
+                       if (!that.istate)
+                               return Z_STREAM_ERROR;
+                       var ret = that.istate.inflateEnd(that);
+                       that.istate = null;
+                       return ret;
+               },
+
+               inflateSync : function() {
+                       var that = this;
+                       if (!that.istate)
+                               return Z_STREAM_ERROR;
+                       return that.istate.inflateSync(that);
+               },
+               inflateSetDictionary : function(dictionary, dictLength) {
+                       var that = this;
+                       if (!that.istate)
+                               return Z_STREAM_ERROR;
+                       return that.istate.inflateSetDictionary(that, dictionary, dictLength);
+               },
+               read_byte : function(start) {
+                       var that = this;
+                       return that.next_in.subarray(start, start + 1)[0];
+               },
+               read_buf : function(start, size) {
+                       var that = this;
+                       return that.next_in.subarray(start, start + size);
+               }
+       };
+
+       // Inflater
+
+       function Inflater() {
+               var that = this;
+               var z = new ZStream();
+               var bufsize = 512;
+               var flush = Z_NO_FLUSH;
+               var buf = new Uint8Array(bufsize);
+               var nomoreinput = false;
+
+               z.inflateInit();
+               z.next_out = buf;
+
+               that.append = function(data, onprogress) {
+                       var err, buffers = [], lastIndex = 0, bufferIndex = 0, bufferSize = 0, array;
+                       if (data.length === 0)
+                               return;
+                       z.next_in_index = 0;
+                       z.next_in = data;
+                       z.avail_in = data.length;
+                       do {
+                               z.next_out_index = 0;
+                               z.avail_out = bufsize;
+                               if ((z.avail_in === 0) && (!nomoreinput)) { // if buffer is empty and more input is available, refill it
+                                       z.next_in_index = 0;
+                                       nomoreinput = true;
+                               }
+                               err = z.inflate(flush);
+                               if (nomoreinput && (err == Z_BUF_ERROR))
+                                       return -1;
+                               if (err != Z_OK && err != Z_STREAM_END)
+                                       throw "inflating: " + z.msg;
+                               if ((nomoreinput || err == Z_STREAM_END) && (z.avail_in == data.length))
+                                       return -1;
+                               if (z.next_out_index)
+                                       if (z.next_out_index == bufsize)
+                                               buffers.push(new Uint8Array(buf));
+                                       else
+                                               buffers.push(new Uint8Array(buf.subarray(0, z.next_out_index)));
+                               bufferSize += z.next_out_index;
+                               if (onprogress && z.next_in_index > 0 && z.next_in_index != lastIndex) {
+                                       onprogress(z.next_in_index);
+                                       lastIndex = z.next_in_index;
+                               }
+                       } while (z.avail_in > 0 || z.avail_out === 0);
+                       array = new Uint8Array(bufferSize);
+                       buffers.forEach(function(chunk) {
+                               array.set(chunk, bufferIndex);
+                               bufferIndex += chunk.length;
+                       });
+                       return array;
+               };
+               that.flush = function() {
+                       z.inflateEnd();
+               };
+       }
+
+       var inflater;
+
+       if (obj.zip)
+               obj.zip.Inflater = Inflater;
+       else {
+               inflater = new Inflater();
+               obj.addEventListener("message", function(event) {
+                       var message = event.data;
+
+                       if (message.append)
+                               obj.postMessage({
+                                       onappend : true,
+                                       data : inflater.append(message.data, function(current) {
+                                               obj.postMessage({
+                                                       progress : true,
+                                                       current : current
+                                               });
+                                       })
+                               });
+                       if (message.flush) {
+                               inflater.flush();
+                               obj.postMessage({
+                                       onflush : true
+                               });
+                       }
+               }, false);
+       }
+
+})(EasyDeflate);
index 144fea7..a87b958 100644 (file)
@@ -1,4 +1,117 @@
 # OOUI Release History
+## v0.27.5 / 2018-07-11
+### Deprecations
+* [DEPRECATING CHANGE] CapsuleMultiselectWidget: Deprecate widget (Volker E.)
+
+### Styles
+* CheckboxInputWidget, RadioInputWidget: Use `display: inline-block` in all themes (Bartosz Dziewoński)
+* MessageDialog: Replace special button treatment with framed buttons (Volker E.)
+* WikimediaUI theme: Apply new `ease-out` variable to dialogs (Volker E.)
+* WikimediaUI theme: Replace and remove cubic bezier `transition` option (Volker E.)
+* WikimediaUI theme: Replace hard-coded value with var (Volker E.)
+* Apex theme: Make button faux 3D effect more subtle (Volker E.)
+* Apex theme: Restore space between inline FieldLayout field and label (Bartosz Dziewoński)
+* Apex theme: Unify `border` values (Volker E.)
+* Apex theme: Unify close `border-radius` values (Volker E.)
+
+### Code
+* Add taint annotations for phan-taint-check (Brian Wolff)
+* Ensure window ready process runs after window is made visible (Bartosz Dziewoński)
+* FieldLayout: Avoid unclickable gap between widget and label in 'inline' align (Bartosz Dziewoński)
+* IndexLayout (TabPanelLayouts): Apply correct ARIA roles & attributes (Volker E.)
+* MenuSelectWidget: Remove checks for unchanged input from updateItemVisibility() (Bartosz Dziewoński)
+* build: Update eslint config to 0.6.0 (Ed Sanders)
+
+
+## v0.27.4 / 2018-06-27
+### Styles
+* icons: Add destructive variant for subtract icon (Sam Wilson)
+* WikimediaUI theme: Remove some unused CSS (Bartosz Dziewoński)
+* Apex theme: Actually display the icon of MenuToolGroup tools (Bartosz Dziewoński)
+* Apex theme: Don't hide icons in elements nested in selected MenuOptionWidget (Bartosz Dziewoński)
+* Apex theme: Fix placement of icon in DecoratedOptionWidget (Bartosz Dziewoński)
+
+### Code
+* Allow JS/PHP comparison tests for FieldLayout 'help' config option (Bartosz Dziewoński)
+* Avoid mentioning 'iconTitle' config option in doc examples (Bartosz Dziewoński)
+* Dialog: Create getActionWidget(Config) to simplify customisation (Ed Sanders)
+* FieldLayout: Add `for` attribute to inline help label (Prateek Saxena)
+* FieldLayout: Reduce clutter in initialization function (Prateek Saxena)
+* Follow-up I90a0a787: Add 'helpInline' to PHP FieldLayout (Ed Sanders)
+* IconElement/IndicatorElement: Reduce specificity of basic styles (Bartosz Dziewoński)
+* MenuSelectWidget: Move 'highlight first item' to end of operation (Moriel Schottlender)
+* PopupWidget: Add setter for $autoCloseIgnore (Roan Kattouw)
+* PopupWidget: Allow automatic width (not hardcoded) (Bartosz Dziewoński)
+* PopupWidget: Listen to 'click' for 'mousedown' events in iOS (Moriel Schottlender)
+* ProcessDialog: Use cached value of isMobile (Ed Sanders)
+* Refactor how we apply `display: none` to unused icons and indicators (Bartosz Dziewoński)
+* WindowManager: Only set `aria-hidden="true"` for modal managers (Bartosz Dziewoński)
+* build: Exclude 'demos/vendor' from stylelint (Volker E.)
+* build: Fix 'copy:fastcomposerdemos' task (Bartosz Dziewoński)
+* styles: Remove proprietary IE 8 & 9 `-ms-filter` properties (Volker E.)
+* themes: Improve top `padding` and `line-height` in MessageDialogs (Volker E.)
+
+
+## v0.27.3 / 2018-06-07 (special release)
+### Styles
+* ActionFieldLayout: Improve `z-index` overrides on focus/hover (Bartosz Dziewoński)
+* WikimediaUI theme: Remove label baseline dissonance (Volker E.)
+* WikimediaUI theme: Reset SelectFileWidget's LabelElement-label (Volker E.)
+
+### Code
+* PopupButtonWidget: Remove `aria-haspopup` attribute (Volker E.)
+
+
+## v0.27.2 / 2018-06-05
+### Features
+* Allow passing config objects to OO.ui.infuse (Ed Sanders)
+* FieldLayout: Add 'helpInline' config (Prateek Saxena)
+* LookupElement: Allow menu config to be passed in (Ed Sanders)
+* MenuSelectWidget: Support starting positions other than 'below' (Ed Sanders)
+* MenuTagMultiselectWidget: Allow icons in dropdown menus (Volker E.)
+* TagMultiselectWidget: Make sure 'fixed' items can't be removed (Moriel Schottlender)
+
+### Styles
+* ActionFieldLayout: Visually combine inputs and their buttons (Volker E.)
+* MenuLayout: Avoid `transition: all`, be precise (Bartosz Dziewoński)
+* icons: Make bold-cyrl-palochka.svg perfectly symmetrical (Bartosz Dziewoński)
+* WikimediaUI theme: Apply distinct “pill” appearance to tags (Volker E.)
+* WikimediaUI theme: Improve TagMultiselect spacing & distance code (Volker E.)
+* WikimediaUI theme: Move label `line-height` to LabelElement (Volker E.)
+* WikimediaUI theme: Reduce `line-height` varieties across widgets (Volker E.)
+* WikimediaUI theme: Use 'progressive' icons for pressed/selected MenuOptionWidget (Bartosz Dziewoński)
+* Apex theme: Remove vertical padding from label widget (Ed Sanders)
+
+
+## v0.27.1 / 2018-05-29
+### Deprecations
+* [DEPRECATING CHANGE] Toolbar: Add a required 'name' property to toolgroup configs (Ed Sanders)
+
+### Styles
+* Add bold icon for Chechen language (Ed Sanders)
+* FieldLayout: Give help icon space when align=left (Prateek Saxena)
+* MenuSelectWidget: Allow dropdown menus to be larger than their handles (Ed Sanders)
+* themes: Clarify and align focus on TabselectWidget's selected tab (Volker E.)
+* WikimediaUI theme: Replace fixed value with dedicated LESS var (Volker E.)
+* WikimediaUI theme: Align DecoratedOptionWidget's icon opacity to other widgets (Volker E.)
+* WikimediaUI theme: Fix PopupButtonWidget position (Volker E.)
+* WikimediaUI theme: Fix regression on Safari bug (Volker E.)
+* WikimediaUI theme: Fix unbalanced focus state in action toolbar (Volker E.)
+* Apex theme: Reduce accumulated white-space in form fields (Volker E.)
+
+### Code
+* Don't auto-focus a booklet layout page when scrolling (Ed Sanders)
+* OutlineControlsWidget: Remove 'add' icon (Bartosz Dziewoński)
+* PopupToolGroup: Allow tabbing to the tools in the popup again (Bartosz Dziewoński)
+* PopupToolGroup: Fix disappearing dropdown on very narrow screens (Bartosz Dziewoński)
+* Toolbar: Remove unused .groups property (Ed Sanders)
+* Toolbar: Rename a variable from 'group' to 'groupConfig' (Ed Sanders)
+* build: Amend 'grunt-svgmin' options and re-crush SVGs (Volker E.)
+* build: Updating mediawiki/mediawiki-codesniffer to 19.0.0 (libraryupgrader)
+* build: Use .map.json extension for source maps (Bartosz Dziewoński)
+* demos: Remove deprecated 'comment' icon (Volker E.)
+
+
 ## v0.27.0 / 2018-05-08
 ### Breaking changes
 * [BREAKING CHANGE] GroupElement: Remove getItem(s)FromData (Prateek Saxena)
index ed56521..14990f9 100644 (file)
@@ -2,7 +2,8 @@
        "@metadata": {
                "authors": [
                        "Naudefj",
-                       "Fwolff"
+                       "Fwolff",
+                       "Fitoschido"
                ]
        },
        "ooui-outline-control-move-down": "Skuif item af",
@@ -20,5 +21,6 @@
        "ooui-selectfile-button-select": "Kies 'n lêer",
        "ooui-selectfile-not-supported": "Lêers kan nie gekies word nie",
        "ooui-selectfile-placeholder": "Geen lêer is gekies nie",
-       "ooui-selectfile-dragdrop-placeholder": "Laat val die lêer hier"
+       "ooui-selectfile-dragdrop-placeholder": "Laat val die lêer hier",
+       "ooui-field-help": "Hulp"
 }
index ad2995a..ce7f999 100644 (file)
@@ -13,7 +13,8 @@
                        "Abanima",
                        "محمد أحمد عبد الفتاح",
                        "Hiba Alshawi",
-                       "Meno25"
+                       "Meno25",
+                       "ديفيد"
                ]
        },
        "ooui-outline-control-move-down": "انقل العنصر للأسفل",
@@ -32,5 +33,6 @@
        "ooui-selectfile-button-select": "اختر ملفا",
        "ooui-selectfile-not-supported": "اختيار الملفات غير مدعوم",
        "ooui-selectfile-placeholder": "لم يتم اختيار أي ملف",
-       "ooui-selectfile-dragdrop-placeholder": "اترك الملف هنا"
+       "ooui-selectfile-dragdrop-placeholder": "اترك الملف هنا",
+       "ooui-field-help": "مساعدة"
 }
index 623892d..b62f8f3 100644 (file)
@@ -22,5 +22,6 @@
        "ooui-selectfile-button-select": "Seleicionar un ficheru",
        "ooui-selectfile-not-supported": "Nun hai encontu pa la seleición de ficheros",
        "ooui-selectfile-placeholder": "Nun se seleicionó nengún ficheru",
-       "ooui-selectfile-dragdrop-placeholder": "Soltar el ficheru equí"
+       "ooui-selectfile-dragdrop-placeholder": "Soltar el ficheru equí",
+       "ooui-field-help": "Ayuda"
 }
index 40a6efd..59415a2 100644 (file)
@@ -25,5 +25,6 @@
        "ooui-selectfile-button-select": "Абраць файл",
        "ooui-selectfile-not-supported": "Выбар файлу не падтрымліваецца",
        "ooui-selectfile-placeholder": "Ніводзін файл не абраны",
-       "ooui-selectfile-dragdrop-placeholder": "Перацягніце файл сюды"
+       "ooui-selectfile-dragdrop-placeholder": "Перацягніце файл сюды",
+       "ooui-field-help": "Дапамога"
 }
index 3ae0ec9..afa1672 100644 (file)
@@ -25,5 +25,6 @@
        "ooui-selectfile-button-select": "Избиране на файл",
        "ooui-selectfile-not-supported": "Избраният файл не се поддържа",
        "ooui-selectfile-placeholder": "Не е избран файл",
-       "ooui-selectfile-dragdrop-placeholder": "Пуснете файла тук"
+       "ooui-selectfile-dragdrop-placeholder": "Пуснете файла тук",
+       "ooui-field-help": "Помощ"
 }
index 273b7db..90f96f9 100644 (file)
@@ -9,7 +9,8 @@
                        "Sayak Sarkar",
                        "Aftabuzzaman",
                        "RYasmeen (WMF)",
-                       "NahidSultan"
+                       "NahidSultan",
+                       "আফতাবুজ্জামান"
                ]
        },
        "ooui-outline-control-move-down": "আইটেম নিচে স্থানান্তর",
index 1383d9a..498d133 100644 (file)
@@ -24,5 +24,6 @@
        "ooui-selectfile-button-select": "Diuzañ ur restr",
        "ooui-selectfile-not-supported": "N'eo ket skoret an diuzañ restroù",
        "ooui-selectfile-placeholder": "N'eus bet diuzet restr ebet",
-       "ooui-selectfile-dragdrop-placeholder": "Lezel ar restr amañ"
+       "ooui-selectfile-dragdrop-placeholder": "Lezel ar restr amañ",
+       "ooui-field-help": "Skoazell"
 }
index 96d782e..e1d8753 100644 (file)
@@ -13,7 +13,8 @@
                        "Davidpar",
                        "Maceleiro",
                        "Kippelboy",
-                       "Macofe"
+                       "Macofe",
+                       "Fitoschido"
                ]
        },
        "ooui-outline-control-move-down": "Baixa l'element",
@@ -22,6 +23,7 @@
        "ooui-toolbar-more": "Més",
        "ooui-toolgroup-expand": "Més",
        "ooui-toolgroup-collapse": "Menys",
+       "ooui-item-remove": "Suprimeix",
        "ooui-dialog-message-accept": "D'acord",
        "ooui-dialog-message-reject": "Cancel·la",
        "ooui-dialog-process-error": "Alguna cosa no ha funcionat",
@@ -31,5 +33,6 @@
        "ooui-selectfile-button-select": "Seleccioneu un fitxer",
        "ooui-selectfile-not-supported": "El tipus de fitxer no és compatible",
        "ooui-selectfile-placeholder": "No s'ha seleccionat cap fitxer",
-       "ooui-selectfile-dragdrop-placeholder": "Deseu els arxius aquí"
+       "ooui-selectfile-dragdrop-placeholder": "Deseu els arxius aquí",
+       "ooui-field-help": "Ajuda"
 }
index 8e3d1af..5b78b1f 100644 (file)
@@ -32,5 +32,6 @@
        "ooui-selectfile-button-select": "Vybrat soubor",
        "ooui-selectfile-not-supported": "Výběr souboru není podporován",
        "ooui-selectfile-placeholder": "Nebyl vybrán žádný soubor",
-       "ooui-selectfile-dragdrop-placeholder": "Umístěte soubor sem"
+       "ooui-selectfile-dragdrop-placeholder": "Umístěte soubor sem",
+       "ooui-field-help": "Pomoc"
 }
index a9eea8a..2b01df9 100644 (file)
@@ -29,5 +29,6 @@
        "ooui-selectfile-button-select": "Eine Datei auswählen",
        "ooui-selectfile-not-supported": "Die Dateiauswahl wird nicht unterstützt",
        "ooui-selectfile-placeholder": "Keine Datei ausgewählt",
-       "ooui-selectfile-dragdrop-placeholder": "Dateien hier ablegen"
+       "ooui-selectfile-dragdrop-placeholder": "Dateien hier ablegen",
+       "ooui-field-help": "Hilfe"
 }
index 55d1e8b..bbc5d64 100644 (file)
@@ -29,5 +29,6 @@
        "ooui-selectfile-button-select": "Επιλέξτε ένα αρχείο",
        "ooui-selectfile-not-supported": "Επιλογή αρχείου δεν υποστηρίζεται",
        "ooui-selectfile-placeholder": "Κανένα αρχείο δεν είναι επιλεγμένο",
-       "ooui-selectfile-dragdrop-placeholder": "Σύρετε το αρχείο εδώ"
+       "ooui-selectfile-dragdrop-placeholder": "Σύρετε το αρχείο εδώ",
+       "ooui-field-help": "Βοήθεια"
 }
index ff2a2b3..d27da01 100644 (file)
@@ -6,7 +6,8 @@
                        "Shirayuki",
                        "Yekrats",
                        "Kvardek du",
-                       "Psychoslave"
+                       "Psychoslave",
+                       "Fitoschido"
                ]
        },
        "ooui-outline-control-move-down": "Movi eron suben",
@@ -24,5 +25,6 @@
        "ooui-selectfile-button-select": "Elekti dosieron",
        "ooui-selectfile-not-supported": "Dosieroselekto ne estas subtenata.",
        "ooui-selectfile-placeholder": "Vi ne selektis dosieron",
-       "ooui-selectfile-dragdrop-placeholder": "Ĵetu dosieron ĉi tie."
+       "ooui-selectfile-dragdrop-placeholder": "Ĵetu dosieron ĉi tie.",
+       "ooui-field-help": "Helpo"
 }
index 7873c95..35943b0 100644 (file)
@@ -34,5 +34,6 @@
        "ooui-selectfile-button-select": "Selecciona un archivo",
        "ooui-selectfile-not-supported": "No se admite la selección de archivos",
        "ooui-selectfile-placeholder": "Ningún archivo seleccionado",
-       "ooui-selectfile-dragdrop-placeholder": "Suelta el archivo aquí"
+       "ooui-selectfile-dragdrop-placeholder": "Suelta el archivo aquí",
+       "ooui-field-help": "Ayuda"
 }
index c715ae6..f87d11f 100644 (file)
@@ -6,7 +6,8 @@
                        "Xabier Armendaritz",
                        "Subi",
                        "Sator",
-                       "Mikel Ibaiba"
+                       "Mikel Ibaiba",
+                       "Fitoschido"
                ]
        },
        "ooui-outline-control-move-down": "Mugitu itema beherantz",
@@ -25,5 +26,6 @@
        "ooui-selectfile-button-select": "Fitxategi bat aukeratu",
        "ooui-selectfile-not-supported": "Fitxategi aukeraketa ez da onartzen",
        "ooui-selectfile-placeholder": "Ez da fitxategirik hautatu",
-       "ooui-selectfile-dragdrop-placeholder": "Fitxategia hemen utzi"
+       "ooui-selectfile-dragdrop-placeholder": "Fitxategia hemen utzi",
+       "ooui-field-help": "Laguntza"
 }
index 8aa519b..e6e4463 100644 (file)
@@ -14,7 +14,8 @@
                        "Alirezaaa",
                        "Leyth",
                        "الناز",
-                       "فلورانس"
+                       "فلورانس",
+                       "Alireza Ivaz"
                ]
        },
        "ooui-outline-control-move-down": "انتقال مورد به پایین",
@@ -33,5 +34,6 @@
        "ooui-selectfile-button-select": "یک فایل انتخاب کنید",
        "ooui-selectfile-not-supported": "انتخاب پرونده پشتیبانی نمی‌شود",
        "ooui-selectfile-placeholder": "هیچ پرونده‌ای انتخاب نشده است",
-       "ooui-selectfile-dragdrop-placeholder": "فایل را اینجا رها کنید"
+       "ooui-selectfile-dragdrop-placeholder": "فایل را اینجا رها کنید",
+       "ooui-field-help": "راهنما"
 }
index 4f46aef..4c38f00 100644 (file)
@@ -14,7 +14,8 @@
                        "Skalman",
                        "Stryn",
                        "VezonThunder",
-                       "Alluk."
+                       "Alluk.",
+                       "Pyscowicz"
                ]
        },
        "ooui-outline-control-move-down": "Siirrä kohdetta alaspäin",
@@ -33,5 +34,6 @@
        "ooui-selectfile-button-select": "Valitse tiedosto",
        "ooui-selectfile-not-supported": "Tiedoston valitsemista ei tueta",
        "ooui-selectfile-placeholder": "Tiedostoa ei ole valittu",
-       "ooui-selectfile-dragdrop-placeholder": "Pudota tiedosto tähän"
+       "ooui-selectfile-dragdrop-placeholder": "Pudota tiedosto tähän",
+       "ooui-field-help": "Ohje"
 }
index 1c004d4..a426875 100644 (file)
@@ -49,5 +49,6 @@
        "ooui-selectfile-button-select": "Sélectionner un fichier",
        "ooui-selectfile-not-supported": "La sélection de fichier n’est pas prise en charge",
        "ooui-selectfile-placeholder": "Aucun fichier sélectionné",
-       "ooui-selectfile-dragdrop-placeholder": "Déposer le fichier ici"
+       "ooui-selectfile-dragdrop-placeholder": "Déposer le fichier ici",
+       "ooui-field-help": "Aide"
 }
index 2c3cce3..22174f7 100644 (file)
@@ -5,7 +5,8 @@
                        "Kscanne",
                        "Toliño",
                        "Elisardojm",
-                       "Banjo"
+                       "Banjo",
+                       "Fitoschido"
                ]
        },
        "ooui-outline-control-move-down": "Mover o elemento abaixo",
@@ -24,5 +25,6 @@
        "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",
-       "ooui-selectfile-dragdrop-placeholder": "Solte un ficheiro aquí"
+       "ooui-selectfile-dragdrop-placeholder": "Solte un ficheiro aquí",
+       "ooui-field-help": "Axuda"
 }
index ca0f1b4..9fcf139 100644 (file)
@@ -1,7 +1,8 @@
 {
        "@metadata": {
                "authors": [
-                       "Marwan Mohamad"
+                       "Marwan Mohamad",
+                       "Fitoschido"
                ]
        },
        "ooui-outline-control-move-down": "Heyiya botu ode tibawa",
@@ -19,5 +20,6 @@
        "ooui-selectfile-button-select": "Tulawota berkas tuwawu",
        "ooui-selectfile-not-supported": "Berkas tilulawoto ja motuhatawa",
        "ooui-selectfile-placeholder": "Diya'a berkas u letulawoto",
-       "ooui-selectfile-dragdrop-placeholder": "Dutuwa berkas teeya"
+       "ooui-selectfile-dragdrop-placeholder": "Dutuwa berkas teeya",
+       "ooui-field-help": "Wubodu"
 }
index 0864ed9..e40820d 100644 (file)
@@ -31,5 +31,6 @@
        "ooui-selectfile-button-select": "נא לבחור קובץ",
        "ooui-selectfile-not-supported": "בחירת קבצים אינה נתמכת",
        "ooui-selectfile-placeholder": "לא נבחר שום קובץ",
-       "ooui-selectfile-dragdrop-placeholder": "נא לשחרר את הקובץ כאן"
+       "ooui-selectfile-dragdrop-placeholder": "נא לשחרר את הקובץ כאן",
+       "ooui-field-help": "עזרה"
 }
index 4eae569..90bb1a6 100644 (file)
@@ -24,5 +24,6 @@
        "ooui-selectfile-button-select": "Odaberi datoteku",
        "ooui-selectfile-not-supported": "Izbor datoteke nije podržan",
        "ooui-selectfile-placeholder": "Datoteka nije označena",
-       "ooui-selectfile-dragdrop-placeholder": "Povucite datoteku ovdje"
+       "ooui-selectfile-dragdrop-placeholder": "Povucite datoteku ovdje",
+       "ooui-field-help": "Pomoć"
 }
index 3814ba2..5a0d3e4 100644 (file)
@@ -22,5 +22,6 @@
        "ooui-selectfile-button-select": "Velja skrá",
        "ooui-selectfile-not-supported": "Skráar val er ekki stutt.",
        "ooui-selectfile-placeholder": "Engin skrá er valin",
-       "ooui-selectfile-dragdrop-placeholder": "Slepptu skránni hérna"
+       "ooui-selectfile-dragdrop-placeholder": "Slepptu skránni hérna",
+       "ooui-field-help": "Hjálp"
 }
index a301b66..e90d4cf 100644 (file)
@@ -35,5 +35,6 @@
        "ooui-selectfile-button-select": "Seleziona un file",
        "ooui-selectfile-not-supported": "La selezione del file non è supportata",
        "ooui-selectfile-placeholder": "Nessun file è selezionato",
-       "ooui-selectfile-dragdrop-placeholder": "Posiziona i file qui"
+       "ooui-selectfile-dragdrop-placeholder": "Posiziona i file qui",
+       "ooui-field-help": "Aiuto"
 }
index 1c3f9c3..08cea4b 100644 (file)
@@ -10,7 +10,8 @@
                        "Sujiniku",
                        "Translatealcd",
                        "Otokoume",
-                       "Rxy"
+                       "Rxy",
+                       "S2KTS"
                ]
        },
        "ooui-outline-control-move-down": "項目を下に移動させる",
@@ -29,5 +30,6 @@
        "ooui-selectfile-button-select": "ファイルを選択",
        "ooui-selectfile-not-supported": "ファイルの選択はサポートされていません",
        "ooui-selectfile-placeholder": "ファイルが選択されていません",
-       "ooui-selectfile-dragdrop-placeholder": "ファイルをここにドロップ"
+       "ooui-selectfile-dragdrop-placeholder": "ファイルをここにドロップ",
+       "ooui-field-help": "ヘルプ"
 }
index 0f924e4..c8f71d3 100644 (file)
@@ -21,5 +21,6 @@
        "ooui-selectfile-button-select": "ជ្រើសរើសឯកសារ",
        "ooui-selectfile-not-supported": "ការជ្រើសរើសឯកសារមិនអាចប្រើបានទេ",
        "ooui-selectfile-placeholder": "គ្មានឯកសារណាមួយត្រូវបានជ្រើសរើស",
-       "ooui-selectfile-dragdrop-placeholder": "ទម្លាក់ឯកសារនៅទីនេះ"
+       "ooui-selectfile-dragdrop-placeholder": "ទម្លាក់ឯកសារនៅទីនេះ",
+       "ooui-field-help": "ជំនួយ"
 }
index dc3c84a..2adf18c 100644 (file)
@@ -30,5 +30,6 @@
        "ooui-selectfile-button-select": "파일을 선택하세요",
        "ooui-selectfile-not-supported": "파일 선택은 지원하지 않습니다",
        "ooui-selectfile-placeholder": "선택한 파일 없음",
-       "ooui-selectfile-dragdrop-placeholder": "여기에 파일을 놓으세요"
+       "ooui-selectfile-dragdrop-placeholder": "여기에 파일을 놓으세요",
+       "ooui-field-help": "도움말"
 }
index 7a9b2d2..9b161e9 100644 (file)
@@ -1,7 +1,8 @@
 {
        "@metadata": {
                "authors": [
-                       "Jdforrester"
+                       "Jdforrester",
+                       "Fitoschido"
                ]
        },
        "ooui-toolbar-more": "Plus",
@@ -11,5 +12,6 @@
        "ooui-dialog-message-reject": "Dimittere",
        "ooui-dialog-process-dismiss": "Dimittere",
        "ooui-dialog-process-retry": "Retemptare",
-       "ooui-dialog-process-continue": "Pergere"
+       "ooui-dialog-process-continue": "Pergere",
+       "ooui-field-help": "Auxilium"
 }
index 3deee0d..0d30583 100644 (file)
@@ -26,5 +26,6 @@
        "ooui-selectfile-button-select": "E Fichier eraussichen",
        "ooui-selectfile-not-supported": "D'Eraussiche vu Fichiere gëtt net ënnerstëtzt.",
        "ooui-selectfile-placeholder": "Et ass kee Fichier erausgesicht",
-       "ooui-selectfile-dragdrop-placeholder": "Fichier hei ofleeën"
+       "ooui-selectfile-dragdrop-placeholder": "Fichier hei ofleeën",
+       "ooui-field-help": "Hëllef"
 }
index 6423c75..103dff7 100644 (file)
@@ -24,5 +24,6 @@
        "ooui-selectfile-button-select": "Izvēlies failu",
        "ooui-selectfile-not-supported": "Failu izvēle nav atbalstīta",
        "ooui-selectfile-placeholder": "Nav izvēlēts neviens fails",
-       "ooui-selectfile-dragdrop-placeholder": "Nomet failu šeit"
+       "ooui-selectfile-dragdrop-placeholder": "Nomet failu šeit",
+       "ooui-field-help": "Palīdzība"
 }
index 722b3e2..4c6967b 100644 (file)
@@ -1,7 +1,8 @@
 {
        "@metadata": {
                "authors": [
-                       "Jagwar"
+                       "Jagwar",
+                       "Fitoschido"
                ]
        },
        "ooui-outline-control-move-down": "Hampidina ilay zavatra",
@@ -19,5 +20,6 @@
        "ooui-selectfile-button-select": "Misafidia rakitra iray",
        "ooui-selectfile-not-supported": "Tsy zaka ny fisafidiana rakitra",
        "ooui-selectfile-placeholder": "Tsy misy rakitra voafidy",
-       "ooui-selectfile-dragdrop-placeholder": "Hametraka rakitra eto"
+       "ooui-selectfile-dragdrop-placeholder": "Hametraka rakitra eto",
+       "ooui-field-help": "Fanoroana"
 }
index 23d0776..8de0d80 100644 (file)
@@ -22,5 +22,6 @@
        "ooui-selectfile-button-select": "Одберете податотека",
        "ooui-selectfile-not-supported": "Изборот на податотеки не е поддржан",
        "ooui-selectfile-placeholder": "Немате одбрано податотека",
-       "ooui-selectfile-dragdrop-placeholder": "Тука пуштете ја податотеката"
+       "ooui-selectfile-dragdrop-placeholder": "Тука пуштете ја податотеката",
+       "ooui-field-help": "Помош"
 }
index 9649b2e..aba355a 100644 (file)
@@ -14,6 +14,7 @@
        "ooui-toolbar-more": "കൂടുതൽ",
        "ooui-toolgroup-expand": "കൂടുതൽ",
        "ooui-toolgroup-collapse": "കുറച്ച്",
+       "ooui-item-remove": "നീക്കം ചെയ്യുക",
        "ooui-dialog-message-accept": "ശരി",
        "ooui-dialog-message-reject": "റദ്ദാക്കുക",
        "ooui-dialog-process-error": "എന്തോ പ്രശ്നമുണ്ടായി",
@@ -23,5 +24,6 @@
        "ooui-selectfile-button-select": "പ്രമാണം തിരഞ്ഞെടുക്കുക",
        "ooui-selectfile-not-supported": "പ്രമാണം തിരഞ്ഞെടുക്കൽ പിന്തുണയ്ക്കുന്നില്ല",
        "ooui-selectfile-placeholder": "പ്രമാണങ്ങൾ ഒന്നും തിരഞ്ഞെടുത്തിട്ടില്ല",
-       "ooui-selectfile-dragdrop-placeholder": "പ്രമാണം ഇവിടെ ഇടുക"
+       "ooui-selectfile-dragdrop-placeholder": "പ്രമാണം ഇവിടെ ഇടുക",
+       "ooui-field-help": "സഹായം"
 }
index 9c20ba3..de8c5bb 100644 (file)
@@ -8,7 +8,8 @@
                        "Njardarlogar",
                        "Jdforrester",
                        "Apple farmer",
-                       "Jon Harald Søby"
+                       "Jon Harald Søby",
+                       "Orf3us"
                ]
        },
        "ooui-outline-control-move-down": "Flytt ned",
@@ -27,5 +28,6 @@
        "ooui-selectfile-button-select": "Velg en fil",
        "ooui-selectfile-not-supported": "Filvalg er ikke støttet",
        "ooui-selectfile-placeholder": "Ingen fil er valgt",
-       "ooui-selectfile-dragdrop-placeholder": "Slipp fil her"
+       "ooui-selectfile-dragdrop-placeholder": "Slipp fil her",
+       "ooui-field-help": "Hjelp"
 }
index 694eb3c..c6fd278 100644 (file)
@@ -37,5 +37,6 @@
        "ooui-selectfile-button-select": "Selecteer een bestand",
        "ooui-selectfile-not-supported": "Selectie van een bestand wordt niet ondersteund",
        "ooui-selectfile-placeholder": "Er is geen bestand geselecteerd",
-       "ooui-selectfile-dragdrop-placeholder": "Sleep hier een bestand heen"
+       "ooui-selectfile-dragdrop-placeholder": "Sleep hier een bestand heen",
+       "ooui-field-help": "Hulp"
 }
index eaf0b1a..affc066 100644 (file)
@@ -17,7 +17,8 @@
                        "Matik7",
                        "Gloria sah",
                        "Andrzej aa",
-                       "The Polish"
+                       "The Polish",
+                       "Railfail536"
                ]
        },
        "ooui-outline-control-move-down": "Przesuń w dół",
@@ -36,5 +37,6 @@
        "ooui-selectfile-button-select": "Wybierz plik",
        "ooui-selectfile-not-supported": "Wybór pliku nie jest obsługiwany",
        "ooui-selectfile-placeholder": "Nie wybrano pliku",
-       "ooui-selectfile-dragdrop-placeholder": "Upuść plik tutaj"
+       "ooui-selectfile-dragdrop-placeholder": "Upuść plik tutaj",
+       "ooui-field-help": "Pomoc"
 }
index aa8904e..11c5ff3 100644 (file)
@@ -32,5 +32,6 @@
        "ooui-selectfile-button-select": "Selecionar um arquivo",
        "ooui-selectfile-not-supported": "O selecionamento de arquivos não é suportado",
        "ooui-selectfile-placeholder": "Nenhum arquivo selecionado",
-       "ooui-selectfile-dragdrop-placeholder": "Arraste o arquivo para cá"
+       "ooui-selectfile-dragdrop-placeholder": "Arraste o arquivo para cá",
+       "ooui-field-help": "Ajuda"
 }
index 246d9c2..7117cd9 100644 (file)
@@ -11,7 +11,8 @@
                        "Luckas",
                        "Vitorvicentevalente",
                        "SandroHc",
-                       "Jkb8"
+                       "Jkb8",
+                       "Athena in Wonderland"
                ]
        },
        "ooui-outline-control-move-down": "Mover item para baixo",
@@ -30,5 +31,6 @@
        "ooui-selectfile-button-select": "Selecionar ficheiro",
        "ooui-selectfile-not-supported": "A seleção de ficheiros não é suportada",
        "ooui-selectfile-placeholder": "Nenhum ficheiro selecionado",
-       "ooui-selectfile-dragdrop-placeholder": "Soltar ficheiro aqui"
+       "ooui-selectfile-dragdrop-placeholder": "Soltar ficheiro aqui",
+       "ooui-field-help": "Ajuda"
 }
index ebc6961..6c879fd 100644 (file)
@@ -38,5 +38,5 @@
        "ooui-selectfile-not-supported": "Label for the file selection widget if file selection is not supported",
        "ooui-selectfile-placeholder": "Label for the file selection widget when no file is currently selected",
        "ooui-selectfile-dragdrop-placeholder": "Label for the file selection widget's drop target",
-       "ooui-field-help": "Label for the help icon attached to a form field"
+       "ooui-field-help": "Label for the help icon attached to a form field\n{{Identical|Help}}"
 }
index cb0b2c3..6a91da2 100644 (file)
@@ -2,11 +2,13 @@
        "@metadata": {
                "authors": [
                        "AlimanRuna",
-                       "Jduranboger"
+                       "Jduranboger",
+                       "Fitoschido"
                ]
        },
        "ooui-outline-control-move-down": "Qallawata uraykuchiy",
        "ooui-outline-control-move-up": "Qallawata huqariy",
        "ooui-outline-control-remove": "P'anqa sutikunata qichuy",
-       "ooui-toolbar-more": "Aswan"
+       "ooui-toolbar-more": "Aswan",
+       "ooui-field-help": "Yanapa"
 }
index eac47ec..f396902 100644 (file)
@@ -20,5 +20,6 @@
        "ooui-selectfile-button-select": "Scacchie 'nu file",
        "ooui-selectfile-not-supported": "'U scacchiamende d'u file non g'è supportate",
        "ooui-selectfile-placeholder": "Nisciune file scacchiate",
-       "ooui-selectfile-dragdrop-placeholder": "Scitte 'u file aqquà"
+       "ooui-selectfile-dragdrop-placeholder": "Scitte 'u file aqquà",
+       "ooui-field-help": "Aijute"
 }
index 6b22fd8..8ca3205 100644 (file)
@@ -18,7 +18,8 @@
                        "Умар",
                        "Камалист",
                        "Meshkov.a",
-                       "Mailman"
+                       "Mailman",
+                       "Stjn"
                ]
        },
        "ooui-outline-control-move-down": "Переместить элемент вниз",
@@ -37,5 +38,6 @@
        "ooui-selectfile-button-select": "Выберите файл",
        "ooui-selectfile-not-supported": "Выбор файла не поддерживается",
        "ooui-selectfile-placeholder": "Не выбран файл",
-       "ooui-selectfile-dragdrop-placeholder": "Перетащите файл сюда"
+       "ooui-selectfile-dragdrop-placeholder": "Перетащите файл сюда",
+       "ooui-field-help": "Справка"
 }
index 8deb477..6de4f7a 100644 (file)
@@ -23,5 +23,6 @@
        "ooui-selectfile-button-select": "Vybrať súbor",
        "ooui-selectfile-not-supported": "Výber súboru nie je podporovaný",
        "ooui-selectfile-placeholder": "Nie je vybraný žiadny súbor",
-       "ooui-selectfile-dragdrop-placeholder": "Sem umiestni súbor"
+       "ooui-selectfile-dragdrop-placeholder": "Sem umiestni súbor",
+       "ooui-field-help": "Pomoc"
 }
index 8e79e94..8e13549 100644 (file)
@@ -4,7 +4,8 @@
                        "Dbc334",
                        "Eleassar",
                        "Pinky sl",
-                       "Yerpo"
+                       "Yerpo",
+                       "Upwinxp"
                ]
        },
        "ooui-outline-control-move-down": "Prestavi predmet nižje",
@@ -23,5 +24,6 @@
        "ooui-selectfile-button-select": "Izberite datoteko",
        "ooui-selectfile-not-supported": "Izbira datoteke ni podprta",
        "ooui-selectfile-placeholder": "Nobena datoteka ni izbrana",
-       "ooui-selectfile-dragdrop-placeholder": "Tukaj spustite datoteko"
+       "ooui-selectfile-dragdrop-placeholder": "Tukaj spustite datoteko",
+       "ooui-field-help": "Pomoč"
 }
index de1ee47..5d233a5 100644 (file)
@@ -6,12 +6,13 @@
                        "Милан Јелисавчић",
                        "Zoranzoki21",
                        "Obsuser",
-                       "Prevodim"
+                       "Prevodim",
+                       "BadDog"
                ]
        },
-       "ooui-outline-control-move-down": "Премести ставку надоле",
-       "ooui-outline-control-move-up": "Премести ставку нагоре",
-       "ooui-outline-control-remove": "Уклони ставку",
+       "ooui-outline-control-move-down": "Преместите ставку надоле",
+       "ooui-outline-control-move-up": "Преместите ставку нагоре",
+       "ooui-outline-control-remove": "Уклоните ставку",
        "ooui-toolbar-more": "Више",
        "ooui-toolgroup-expand": "Више",
        "ooui-toolgroup-collapse": "Мање",
index 9ac281e..c49b392 100644 (file)
@@ -32,5 +32,6 @@
        "ooui-selectfile-button-select": "Välj en fil",
        "ooui-selectfile-not-supported": "Filval stöds inte",
        "ooui-selectfile-placeholder": "Ingen fil är vald",
-       "ooui-selectfile-dragdrop-placeholder": "Släpp filen här"
+       "ooui-selectfile-dragdrop-placeholder": "Släpp filen här",
+       "ooui-field-help": "Hjälp"
 }
index 3e88da5..f2122fe 100644 (file)
@@ -27,5 +27,6 @@
        "ooui-selectfile-button-select": "దస్త్రాన్ని ఎంచుకో",
        "ooui-selectfile-not-supported": "దస్త్రపు ఎంపిక అందుబాటులో లేదు",
        "ooui-selectfile-placeholder": "ఏ దస్త్రము ఎంపిక చేయలేదు",
-       "ooui-selectfile-dragdrop-placeholder": "దస్త్రాన్ని ఇక్కడ పడేయండి"
+       "ooui-selectfile-dragdrop-placeholder": "దస్త్రాన్ని ఇక్కడ పడేయండి",
+       "ooui-field-help": "సహాయం"
 }
index 626fb5f..36adc50 100644 (file)
@@ -19,7 +19,7 @@
        "ooui-outline-control-move-down": "Ögeyi aşağı taşı",
        "ooui-outline-control-move-up": "Ögeyi yukarı taşı",
        "ooui-outline-control-remove": "Ögeyi kaldır",
-       "ooui-toolbar-more": "Daha",
+       "ooui-toolbar-more": "Daha fazla",
        "ooui-toolgroup-expand": "Dahası",
        "ooui-toolgroup-collapse": "Daha az",
        "ooui-item-remove": "Kaldır",
@@ -32,5 +32,6 @@
        "ooui-selectfile-button-select": "Dosya seç",
        "ooui-selectfile-not-supported": "Dosya seçimi desteklenmiyor",
        "ooui-selectfile-placeholder": "Herhangi bir dosya seçilmedi",
-       "ooui-selectfile-dragdrop-placeholder": "Dosyayı buraya aç"
+       "ooui-selectfile-dragdrop-placeholder": "Dosyayı buraya aç",
+       "ooui-field-help": "Yardım"
 }
index 55fec13..d5c312d 100644 (file)
@@ -17,7 +17,8 @@
                        "Ата",
                        "Piramidion",
                        "A1",
-                       "Dars"
+                       "Dars",
+                       "Esk78"
                ]
        },
        "ooui-outline-control-move-down": "Перемістити елемент униз",
@@ -36,5 +37,6 @@
        "ooui-selectfile-button-select": "Оберіть файл",
        "ooui-selectfile-not-supported": "Вибір файлу не підтримується",
        "ooui-selectfile-placeholder": "Жодного файлу не вибрано",
-       "ooui-selectfile-dragdrop-placeholder": "Помістіть файл сюди"
+       "ooui-selectfile-dragdrop-placeholder": "Помістіть файл сюди",
+       "ooui-field-help": "Допомога"
 }
index ddd27c5..4a1685b 100644 (file)
@@ -3,7 +3,8 @@
                "authors": [
                        "Candalua",
                        "GatoSelvadego",
-                       "Gloria sah"
+                       "Gloria sah",
+                       "Fitoschido"
                ]
        },
        "ooui-outline-control-move-down": "Sposta in baso",
@@ -18,5 +19,6 @@
        "ooui-dialog-process-retry": "Proa da novo",
        "ooui-dialog-process-continue": "Và vanti",
        "ooui-selectfile-button-select": "Siegli un file",
-       "ooui-selectfile-dragdrop-placeholder": "Mola zo el file chì rento"
+       "ooui-selectfile-dragdrop-placeholder": "Mola zo el file chì rento",
+       "ooui-field-help": "Ajuto"
 }
index b271403..1664d9b 100644 (file)
@@ -24,5 +24,6 @@
        "ooui-selectfile-button-select": "Chọn tập tin",
        "ooui-selectfile-not-supported": "Không hỗ trợ việc chọn tập tin",
        "ooui-selectfile-placeholder": "Không có tập tin nào được chọn",
-       "ooui-selectfile-dragdrop-placeholder": "Thả tập tin vào đây"
+       "ooui-selectfile-dragdrop-placeholder": "Thả tập tin vào đây",
+       "ooui-field-help": "Trợ giúp"
 }
index a3e637d..ca3c3be 100644 (file)
@@ -37,5 +37,6 @@
        "ooui-selectfile-button-select": "选择一个文件",
        "ooui-selectfile-not-supported": "不支持文件选择器",
        "ooui-selectfile-placeholder": "没有选定文件",
-       "ooui-selectfile-dragdrop-placeholder": "将文件拖动至此"
+       "ooui-selectfile-dragdrop-placeholder": "将文件拖动至此",
+       "ooui-field-help": "帮助"
 }
index 127f483..1e05886 100644 (file)
@@ -16,7 +16,8 @@
                        "Cwlin0416",
                        "LNDDYL",
                        "Shangkuanlc",
-                       "A2093064"
+                       "A2093064",
+                       "Kly"
                ]
        },
        "ooui-outline-control-move-down": "項目下移",
@@ -35,5 +36,6 @@
        "ooui-selectfile-button-select": "選擇一個檔案",
        "ooui-selectfile-not-supported": "無法支援所選擇的檔案",
        "ooui-selectfile-placeholder": "尚未選擇檔案",
-       "ooui-selectfile-dragdrop-placeholder": "拖曳檔案到此處"
+       "ooui-selectfile-dragdrop-placeholder": "拖曳檔案到此處",
+       "ooui-field-help": "說明"
 }
index 042d609..dd3e191 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOUI v0.27.0
+ * OOUI v0.27.5
  * https://www.mediawiki.org/wiki/OOUI
  *
  * Copyright 2011–2018 OOUI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2018-05-09T00:44:45Z
+ * Date: 2018-07-11T18:13:04Z
  */
 ( function ( OO ) {
 
@@ -42,4 +42,4 @@ OO.ui.theme = new OO.ui.ApexTheme();
 
 }( OO ) );
 
-//# sourceMappingURL=oojs-ui-apex.js.map
\ No newline at end of file
+//# sourceMappingURL=oojs-ui-apex.js.map.json
\ No newline at end of file
diff --git a/resources/lib/oojs-ui/oojs-ui-apex.js.map b/resources/lib/oojs-ui/oojs-ui-apex.js.map
deleted file mode 100644 (file)
index f509343..0000000
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"sources":["../src/intro.js.txt","../src/themes/apex/ApexTheme.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,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,aAAa,EAAE,CAAC,CAAC;AAC5C,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AACrC,EAAE;AACF;AACA,EAAE,CAAC,KAAK,CAAC,EAAE;AACX;AACA,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE;AAChD;AACA,EAAE,CAAC,OAAO,CAAC,EAAE;AACb;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,SAAS,CAAC,2BAA2B,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACrE,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,SAAS,GAAG;;AC1BpC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE","file":"oojs-ui-apex.js","sourcesContent":["( function ( OO ) {\n\n'use strict';\n","/**\n * @class\n * @extends OO.ui.Theme\n *\n * @constructor\n */\nOO.ui.ApexTheme = function OoUiApexTheme() {\n\t// Parent constructor\n\tOO.ui.ApexTheme.parent.call( this );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.ApexTheme, OO.ui.Theme );\n\n/* Methods */\n\n/**\n * @inheritdoc\n */\nOO.ui.ApexTheme.prototype.getDialogTransitionDuration = function () {\n\treturn 250;\n};\n\n/* Instantiation */\n\nOO.ui.theme = new OO.ui.ApexTheme();\n","}( OO ) );\n"]}
\ No newline at end of file
diff --git a/resources/lib/oojs-ui/oojs-ui-apex.js.map.json b/resources/lib/oojs-ui/oojs-ui-apex.js.map.json
new file mode 100644 (file)
index 0000000..f509343
--- /dev/null
@@ -0,0 +1 @@
+{"version":3,"sources":["../src/intro.js.txt","../src/themes/apex/ApexTheme.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,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,aAAa,EAAE,CAAC,CAAC;AAC5C,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AACrC,EAAE;AACF;AACA,EAAE,CAAC,KAAK,CAAC,EAAE;AACX;AACA,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE;AAChD;AACA,EAAE,CAAC,OAAO,CAAC,EAAE;AACb;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,SAAS,CAAC,2BAA2B,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACrE,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,SAAS,GAAG;;AC1BpC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE","file":"oojs-ui-apex.js","sourcesContent":["( function ( OO ) {\n\n'use strict';\n","/**\n * @class\n * @extends OO.ui.Theme\n *\n * @constructor\n */\nOO.ui.ApexTheme = function OoUiApexTheme() {\n\t// Parent constructor\n\tOO.ui.ApexTheme.parent.call( this );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.ApexTheme, OO.ui.Theme );\n\n/* Methods */\n\n/**\n * @inheritdoc\n */\nOO.ui.ApexTheme.prototype.getDialogTransitionDuration = function () {\n\treturn 250;\n};\n\n/* Instantiation */\n\nOO.ui.theme = new OO.ui.ApexTheme();\n","}( OO ) );\n"]}
\ No newline at end of file
index 7a4c0fe..909e524 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOUI v0.27.0
+ * OOUI v0.27.5
  * https://www.mediawiki.org/wiki/OOUI
  *
  * Copyright 2011–2018 OOUI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2018-05-09T00:44:50Z
+ * Date: 2018-07-11T18:13:08Z
  */
 .oo-ui-element-hidden {
   display: none !important;
@@ -49,7 +49,7 @@
 .oo-ui-buttonElement > .oo-ui-buttonElement-button {
   color: #333;
   position: relative;
-  border-radius: 4px;
+  border-radius: 3px;
 }
 .oo-ui-buttonElement > .oo-ui-buttonElement-button:focus {
   outline: 0;
   box-shadow: none;
 }
 .oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-indicatorElement:not( .oo-ui-iconElement ):not( .oo-ui-labelElement ) > .oo-ui-buttonElement-button {
-  border-radius: 4px;
+  border-radius: 3px;
 }
 .oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-indicatorElement:not( .oo-ui-iconElement ):not( .oo-ui-labelElement ) > .oo-ui-buttonElement-button:focus {
   box-shadow: 0 0 2px 2px #ace;
   color: #ccc;
 }
 .oo-ui-buttonElement-framed > .oo-ui-buttonElement-button {
+  background-color: #ebebeb;
+  background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #fafafa), color-stop(100%, #ddd));
+  background-image: -webkit-linear-gradient(top, #fafafa 0, #ddd 100%);
+  background-image: -moz-linear-gradient(top, #fafafa 0, #ddd 100%);
+  background-image: linear-gradient(to bottom, #fafafa 0, #ddd 100%);
+  border: 1px solid #ccc;
   padding: 0.234375em 0.78125em;
   text-shadow: 0 1px 1px rgba(255, 255, 255, 0.5);
-  border: 1px #c9c9c9 solid;
   -webkit-transition: border-color 100ms ease;
   -moz-transition: border-color 100ms ease;
   transition: border-color 100ms ease;
-  background-color: #eeeeee;
-  background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #fff), color-stop(100%, #ddd));
-  background-image: -webkit-linear-gradient(top, #fff 0, #ddd 100%);
-  background-image: -moz-linear-gradient(top, #fff 0, #ddd 100%);
-  background-image: linear-gradient(to bottom, #fff 0, #ddd 100%);
-  -ms-filter: "progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffffff', endColorstr='#ffdddddd' )";
 }
 .oo-ui-buttonElement-framed > .oo-ui-buttonElement-button:hover {
   border-color: #aaa;
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active,
 .oo-ui-buttonElement-framed.oo-ui-buttonElement-active > .oo-ui-buttonElement-button,
 .oo-ui-buttonElement-framed.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
-  box-shadow: inset 0 1px 4px 0 rgba(0, 0, 0, 0.07);
+  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%);
   color: #000;
-  border-color: #c9c9c9;
-  background-color: #eeeeee;
-  background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #ddd), color-stop(100%, #fff));
-  background-image: -webkit-linear-gradient(top, #ddd 0, #fff 100%);
-  background-image: -moz-linear-gradient(top, #ddd 0, #fff 100%);
-  background-image: linear-gradient(to bottom, #ddd 0, #fff 100%);
-  -ms-filter: "progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffdddddd', endColorstr='#ffffffff' )";
+  border-color: #ccc;
+  box-shadow: inset 0 1px 4px 0 rgba(0, 0, 0, 0.07);
 }
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active:focus,
 .oo-ui-buttonElement-framed.oo-ui-buttonElement-active > .oo-ui-buttonElement-button:focus,
   background-image: -webkit-linear-gradient(top, #eaf4fa 0, #b0d9ee 100%);
   background-image: -moz-linear-gradient(top, #eaf4fa 0, #b0d9ee 100%);
   background-image: linear-gradient(to bottom, #eaf4fa 0, #b0d9ee 100%);
-  -ms-filter: "progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffeaf4fa', endColorstr='#ffb0d9ee' )";
 }
 .oo-ui-buttonElement-framed.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button:hover {
   border-color: #9dc2d4;
   background-image: -webkit-linear-gradient(top, #b0d9ee 0, #eaf4fa 100%);
   background-image: -moz-linear-gradient(top, #b0d9ee 0, #eaf4fa 100%);
   background-image: linear-gradient(to bottom, #b0d9ee 0, #eaf4fa 100%);
-  -ms-filter: "progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffb0d9ee', endColorstr='#ffeaf4fa' )";
 }
 .oo-ui-buttonElement-framed.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button {
   color: #d45353;
 .oo-ui-floatableElement {
   position: absolute;
 }
-.oo-ui-iconElement .oo-ui-iconElement-icon,
-.oo-ui-iconElement.oo-ui-iconElement-icon {
+.oo-ui-iconElement-icon {
   background-size: contain;
   background-position: center center;
   background-repeat: no-repeat;
   min-height: 20px;
   height: 100%;
 }
-.oo-ui-iconElement .oo-ui-iconElement-icon,
-.oo-ui-iconElement.oo-ui-iconElement-icon {
+.oo-ui-iconElement-noIcon {
+  display: none;
+}
+.oo-ui-iconElement-icon {
   position: static;
   top: auto;
   width: 1.5625em;
   margin: 0.15625em;
   opacity: 0.8;
 }
-.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator,
-.oo-ui-indicatorElement.oo-ui-indicatorElement-indicator {
+.oo-ui-indicatorElement-indicator {
   background-size: contain;
   background-position: center center;
   background-repeat: no-repeat;
   min-height: 12px;
   height: 100%;
 }
-.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator,
-.oo-ui-indicatorElement.oo-ui-indicatorElement-indicator {
+.oo-ui-indicatorElement-noIndicator {
+  display: none;
+}
+.oo-ui-indicatorElement-indicator {
   position: static;
   top: auto;
   height: 0.9375em;
 }
 .oo-ui-fieldLayout {
   display: block;
-  margin-top: 1em;
+  margin-top: 0.75em;
 }
 .oo-ui-fieldLayout:before,
 .oo-ui-fieldLayout:after {
   padding-top: 0.5em;
 }
 .oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline {
-  margin-top: 1.25em;
+  margin-top: 1em;
 }
 .oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-fieldLayout-body {
   max-width: 50em;
 }
 .oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline.oo-ui-labelElement > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-header {
-  padding: 0.25em 0 0.25em 0.5em;
+  padding-left: 0.5em;
+  text-indent: -1em;
+}
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline.oo-ui-labelElement > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-header > * {
+  text-indent: 0;
+}
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline.oo-ui-labelElement > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-header > .oo-ui-labelElement-label {
+  padding-left: 1em;
 }
 .oo-ui-fieldLayout:first-child {
   margin-top: 0;
 }
 .oo-ui-fieldLayout.oo-ui-fieldLayout-align-top.oo-ui-labelElement > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-header {
   max-width: 50em;
-  padding: 0.5em 0;
+  margin-bottom: 0.25em;
 }
 .oo-ui-fieldLayout.oo-ui-fieldLayout-align-top .oo-ui-fieldLayout-help,
 .oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline .oo-ui-fieldLayout-help {
   display: table-cell;
   vertical-align: middle;
 }
-.oo-ui-actionFieldLayout-input {
-  padding-right: 1em;
-}
 .oo-ui-actionFieldLayout-button {
   width: 1%;
   white-space: nowrap;
 .oo-ui-actionFieldLayout.oo-ui-fieldLayout-align-top {
   max-width: 50em;
 }
+.oo-ui-actionFieldLayout .oo-ui-actionFieldLayout-input .oo-ui-widget:not( .oo-ui-textInputWidget ) {
+  margin-right: 1em;
+}
+.oo-ui-actionFieldLayout .oo-ui-actionFieldLayout-input .oo-ui-widget.oo-ui-textInputWidget > .oo-ui-inputWidget-input {
+  border-radius: 3px 0 0 3px;
+  position: relative;
+}
+.oo-ui-actionFieldLayout .oo-ui-actionFieldLayout-button .oo-ui-buttonElement-framed > .oo-ui-buttonElement-button {
+  border-radius: 0 3px 3px 0;
+  margin-left: -1px;
+}
+.oo-ui-actionFieldLayout .oo-ui-actionFieldLayout-input > .oo-ui-textInputWidget > .oo-ui-inputWidget-input:hover,
+.oo-ui-actionFieldLayout .oo-ui-actionFieldLayout-input > .oo-ui-textInputWidget > .oo-ui-inputWidget-input:hover ~ *,
+.oo-ui-actionFieldLayout .oo-ui-actionFieldLayout-input > .oo-ui-textInputWidget > .oo-ui-inputWidget-input:focus,
+.oo-ui-actionFieldLayout .oo-ui-actionFieldLayout-input > .oo-ui-textInputWidget > .oo-ui-inputWidget-input:focus ~ * {
+  z-index: 1;
+}
+.oo-ui-actionFieldLayout .oo-ui-actionFieldLayout-button > .oo-ui-buttonElement > .oo-ui-buttonElement-button:hover,
+.oo-ui-actionFieldLayout .oo-ui-actionFieldLayout-button > .oo-ui-buttonElement > .oo-ui-buttonElement-button:focus {
+  z-index: 1;
+}
 .oo-ui-fieldsetLayout {
   position: relative;
   min-width: 0;
@@ -588,20 +611,6 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
 .oo-ui-horizontalLayout > .oo-ui-widget {
   margin-bottom: 0.5em;
 }
-.oo-ui-widget .oo-ui-iconElement-icon,
-.oo-ui-widget .oo-ui-indicatorElement-indicator,
-.oo-ui-widget.oo-ui-iconElement .oo-ui-widget .oo-ui-iconElement-icon,
-.oo-ui-widget.oo-ui-indicatorElement .oo-ui-widget .oo-ui-indicatorElement-indicator {
-  display: none;
-}
-.oo-ui-widget.oo-ui-iconElement .oo-ui-iconElement-icon,
-.oo-ui-widget.oo-ui-iconElement > * > .oo-ui-iconElement-icon,
-.oo-ui-widget.oo-ui-iconElement .oo-ui-iconElement .oo-ui-iconElement-icon,
-.oo-ui-widget.oo-ui-indicatorElement > .oo-ui-indicatorElement-indicator,
-.oo-ui-widget.oo-ui-indicatorElement > * > .oo-ui-indicatorElement-indicator,
-.oo-ui-widget.oo-ui-indicatorElement .oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
-  display: block;
-}
 .oo-ui-optionWidget {
   position: relative;
   display: block;
@@ -639,16 +648,17 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
 .oo-ui-decoratedOptionWidget {
   padding: 0.5em 2em 0.5em 3em;
 }
-.oo-ui-decoratedOptionWidget.oo-ui-iconElement .oo-ui-iconElement-icon,
-.oo-ui-decoratedOptionWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
+.oo-ui-decoratedOptionWidget .oo-ui-iconElement-icon,
+.oo-ui-decoratedOptionWidget .oo-ui-indicatorElement-indicator {
   position: absolute;
   top: 0;
   height: 100%;
 }
-.oo-ui-decoratedOptionWidget.oo-ui-iconElement .oo-ui-iconElement-icon {
+.oo-ui-decoratedOptionWidget .oo-ui-iconElement-icon {
   left: 0.5em;
+  margin: 0;
 }
-.oo-ui-decoratedOptionWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
+.oo-ui-decoratedOptionWidget .oo-ui-indicatorElement-indicator {
   right: 0.5em;
 }
 .oo-ui-decoratedOptionWidget.oo-ui-widget-disabled .oo-ui-iconElement-icon,
@@ -682,14 +692,15 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
 }
 .oo-ui-labelWidget {
   display: inline-block;
-  padding: 0.5em 0;
+}
+.oo-ui-labelWidget.oo-ui-inline-help {
+  display: block;
+  color: #595959;
+  font-size: 0.9375em;
 }
 .oo-ui-iconWidget {
-  display: inline-block;
   vertical-align: middle;
   line-height: 2.5em;
-}
-.oo-ui-iconWidget.oo-ui-iconElement.oo-ui-iconElement-icon {
   display: inline-block;
   position: static;
   top: auto;
@@ -700,12 +711,9 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   opacity: 0.2;
 }
 .oo-ui-indicatorWidget {
-  display: inline-block;
   vertical-align: middle;
   line-height: 2.5em;
   margin: 0.46875em;
-}
-.oo-ui-indicatorWidget.oo-ui-indicatorElement.oo-ui-indicatorElement-indicator {
   display: inline-block;
   position: static;
   top: auto;
@@ -723,7 +731,7 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
 .oo-ui-buttonGroupWidget {
   display: inline-block;
   white-space: nowrap;
-  border-radius: 4px;
+  border-radius: 3px;
   margin-right: 0.5em;
   z-index: 0;
   position: relative;
@@ -745,13 +753,13 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   margin-left: -1px;
 }
 .oo-ui-buttonGroupWidget .oo-ui-buttonElement-framed:first-child .oo-ui-buttonElement-button {
-  border-bottom-left-radius: 4px;
-  border-top-left-radius: 4px;
+  border-bottom-left-radius: 3px;
+  border-top-left-radius: 3px;
   margin-left: 0;
 }
 .oo-ui-buttonGroupWidget .oo-ui-buttonElement-framed:last-child .oo-ui-buttonElement-button {
-  border-bottom-right-radius: 4px;
-  border-top-right-radius: 4px;
+  border-bottom-right-radius: 3px;
+  border-top-right-radius: 3px;
 }
 .oo-ui-buttonGroupWidget.oo-ui-widget-enabled .oo-ui-buttonElement.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active {
   z-index: 1;
@@ -846,7 +854,7 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
 .oo-ui-popupWidget-popup {
   background-color: #fff;
   border: 1px solid #ccc;
-  border-radius: 0.25em;
+  border-radius: 3px;
   box-shadow: 0 0.15em 0.5em 0 rgba(0, 0, 0, 0.2);
 }
 .oo-ui-popupWidget-anchored-top {
@@ -961,7 +969,10 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   border: 0;
   padding: 0;
 }
-.oo-ui-checkboxInputWidget .oo-ui-checkboxInputWidget-checkIcon.oo-ui-iconElement-icon {
+.oo-ui-checkboxInputWidget {
+  display: inline-block;
+}
+.oo-ui-checkboxInputWidget-checkIcon {
   display: none;
 }
 .oo-ui-checkboxMultiselectInputWidget .oo-ui-fieldLayout {
@@ -1001,8 +1012,8 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   padding: 0.5em;
   font-size: inherit;
   font-family: inherit;
-  border: 1px solid rgba(0, 0, 0, 0.1);
-  border-radius: 0.25em;
+  border: #ccc;
+  border-radius: 3px;
 }
 .oo-ui-dropdownInputWidget option {
   font-size: inherit;
@@ -1011,11 +1022,11 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   padding: 0.5em 1em;
 }
 .oo-ui-dropdownInputWidget.oo-ui-widget-enabled select:hover {
-  border-color: rgba(0, 0, 0, 0.2);
+  border-color: #aaa;
 }
 .oo-ui-dropdownInputWidget.oo-ui-widget-enabled select:focus {
-  outline: 0;
   border-color: #ace;
+  outline: 0;
   box-shadow: 0 0 2px 2px #ace;
 }
 .oo-ui-dropdownInputWidget.oo-ui-widget-disabled select {
@@ -1023,6 +1034,9 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   border-color: #ddd;
   background-color: #f3f3f3;
 }
+.oo-ui-radioInputWidget {
+  display: inline-block;
+}
 .oo-ui-radioSelectInputWidget .oo-ui-fieldLayout {
   margin-top: 0;
 }
@@ -1109,14 +1123,14 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
 }
 .oo-ui-textInputWidget input,
 .oo-ui-textInputWidget textarea {
-  padding: 0.546875em 0.5em 0.625em 0.5em;
-  font-size: inherit;
-  font-family: inherit;
   background-color: #fff;
   color: #000;
   border: 1px solid #ccc;
+  border-radius: 3px;
+  padding: 0.546875em 0.5em 0.625em 0.5em;
   box-shadow: 0 0 0 #fff, inset 0 0.1em 0.2em #ddd;
-  border-radius: 0.25em;
+  font-size: inherit;
+  font-family: inherit;
   -webkit-transition: border-color 250ms ease, box-shadow 250ms ease;
   -moz-transition: border-color 250ms ease, box-shadow 250ms ease;
   transition: border-color 250ms ease, box-shadow 250ms ease;
@@ -1229,7 +1243,7 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   margin-top: -1px;
   margin-bottom: -1px;
   border: 1px solid #ccc;
-  border-radius: 0 0 0.25em 0.25em;
+  border-radius: 0 0 3px 3px;
   box-shadow: 0 0.15em 1em 0 rgba(0, 0, 0, 0.2);
 }
 .oo-ui-menuSelectWidget.oo-ui-clippableElement-clippable {
@@ -1238,7 +1252,7 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
 .oo-ui-menuSelectWidget-invisible {
   display: none;
 }
-.oo-ui-menuOptionWidget.oo-ui-optionWidget .oo-ui-iconElement-icon.oo-ui-menuOptionWidget-checkIcon {
+.oo-ui-menuOptionWidget .oo-ui-menuOptionWidget-checkIcon {
   display: none;
 }
 .oo-ui-menuOptionWidget.oo-ui-optionWidget > .oo-ui-indicatorElement-indicator {
@@ -1247,18 +1261,11 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
 .oo-ui-menuOptionWidget.oo-ui-optionWidget-selected {
   background-color: transparent;
 }
-.oo-ui-menuOptionWidget.oo-ui-optionWidget-selected.oo-ui-optionWidget .oo-ui-iconElement-icon {
+.oo-ui-menuOptionWidget.oo-ui-optionWidget-selected > .oo-ui-iconElement-icon {
   display: none;
 }
-.oo-ui-menuOptionWidget.oo-ui-optionWidget-selected.oo-ui-optionWidget .oo-ui-iconElement-icon.oo-ui-menuOptionWidget-checkIcon {
+.oo-ui-menuOptionWidget.oo-ui-optionWidget-selected .oo-ui-menuOptionWidget-checkIcon {
   display: block;
-  position: absolute;
-  left: 0.5em;
-  top: 0;
-  min-width: 20px;
-  width: 1.5625em;
-  min-height: 20px;
-  height: 100%;
 }
 .oo-ui-menuOptionWidget.oo-ui-optionWidget-highlighted,
 .oo-ui-menuOptionWidget.oo-ui-optionWidget-highlighted.oo-ui-optionWidget-selected {
@@ -1304,11 +1311,11 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
 }
 .oo-ui-dropdownWidget-handle {
   height: 2.5em;
-  border: 1px solid rgba(0, 0, 0, 0.1);
-  border-radius: 0.25em;
+  border: 1px solid #ccc;
+  border-radius: 3px;
 }
 .oo-ui-dropdownWidget-handle:hover {
-  border-color: rgba(0, 0, 0, 0.2);
+  border-color: #aaa;
 }
 .oo-ui-dropdownWidget-handle:focus {
   outline: 0;
@@ -1410,11 +1417,7 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   visibility: visible;
   margin: 0.775em;
 }
-.oo-ui-comboBoxInputWidget-php .oo-ui-indicatorWidget.oo-ui-indicatorElement.oo-ui-indicatorElement-indicator {
-  display: block;
-  position: absolute;
-  top: 0;
-  height: 100%;
+.oo-ui-comboBoxInputWidget-php .oo-ui-indicatorWidget {
   right: 0;
   max-height: 2.5em;
   margin: 0;
@@ -1475,7 +1478,7 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   max-width: 50em;
   background-color: #fff;
   border: 1px solid #ccc;
-  border-radius: 0.25em;
+  border-radius: 3px;
   overflow: hidden;
 }
 .oo-ui-progressBarWidget-bar {
@@ -1489,7 +1492,6 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   background-image: -webkit-linear-gradient(top, #eaf4fa 0, #b0d9ee 100%);
   background-image: -moz-linear-gradient(top, #eaf4fa 0, #b0d9ee 100%);
   background-image: linear-gradient(to bottom, #eaf4fa 0, #b0d9ee 100%);
-  -ms-filter: "progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffeaf4fa', endColorstr='#ffb0d9ee' )";
 }
 .oo-ui-progressBarWidget-indeterminate .oo-ui-progressBarWidget-bar {
   -webkit-animation: oo-ui-progressBarWidget-slide 2s infinite linear;
index 05ce9a3..a9ec014 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOUI v0.27.0
+ * OOUI v0.27.5
  * https://www.mediawiki.org/wiki/OOUI
  *
  * Copyright 2011–2018 OOUI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2018-05-09T00:44:50Z
+ * Date: 2018-07-11T18:13:08Z
  */
 /**
  * WikimediaUI Base v0.10.0
 .oo-ui-floatableElement {
   position: absolute;
 }
-.oo-ui-iconElement .oo-ui-iconElement-icon,
-.oo-ui-iconElement.oo-ui-iconElement-icon {
+.oo-ui-iconElement-icon {
   background-size: contain;
   background-position: center center;
   background-repeat: no-repeat;
   min-height: 20px;
   height: 100%;
 }
-.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator,
-.oo-ui-indicatorElement.oo-ui-indicatorElement-indicator {
+.oo-ui-iconElement-noIcon {
+  display: none;
+}
+.oo-ui-indicatorElement-indicator {
   background-size: contain;
   background-position: center center;
   background-repeat: no-repeat;
   min-height: 12px;
   height: 100%;
 }
+.oo-ui-indicatorElement-noIndicator {
+  display: none;
+}
 .oo-ui-labelElement .oo-ui-labelElement-label,
 .oo-ui-labelElement.oo-ui-labelElement-label {
   -webkit-box-sizing: border-box;
   -moz-box-sizing: border-box;
   box-sizing: border-box;
 }
+.oo-ui-labelElement .oo-ui-labelElement-label {
+  line-height: 1.42857143em;
+}
 .oo-ui-labelElement .oo-ui-labelElement-label-highlight {
   font-weight: bold;
 }
 .oo-ui-fieldLayout.oo-ui-labelElement > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-header {
   padding-bottom: 0.28571429em;
 }
-.oo-ui-fieldLayout.oo-ui-labelElement > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-header > .oo-ui-labelElement-label {
-  line-height: 1.4;
-}
 .oo-ui-fieldLayout.oo-ui-labelElement.oo-ui-fieldLayout-align-top > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-header,
 .oo-ui-fieldLayout.oo-ui-labelElement.oo-ui-fieldLayout-align-inline > .oo-ui-fieldLayout-body {
   max-width: 50em;
 }
 .oo-ui-fieldLayout.oo-ui-labelElement.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-header,
 .oo-ui-fieldLayout.oo-ui-labelElement.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-header {
-  width: 35%;
-  margin-right: 5%;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  width: 40%;
+  padding-right: 2.64285714em;
 }
 .oo-ui-fieldLayout.oo-ui-labelElement.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-header > .oo-ui-labelElement-label,
 .oo-ui-fieldLayout.oo-ui-labelElement.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-header > .oo-ui-labelElement-label {
 .oo-ui-fieldLayout.oo-ui-labelElement.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-help,
 .oo-ui-fieldLayout.oo-ui-labelElement.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-help {
   margin-right: 0;
-  margin-left: -2.29em;
+  margin-left: -2.35714286em;
 }
 .oo-ui-fieldLayout.oo-ui-labelElement.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field,
 .oo-ui-fieldLayout.oo-ui-labelElement.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field {
   padding-top: 0;
   padding-bottom: 0;
   padding-left: 0.42857143em;
+  text-indent: -0.42857143em;
+}
+.oo-ui-fieldLayout.oo-ui-labelElement.oo-ui-fieldLayout-align-inline > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-header > * {
+  text-indent: 0;
+}
+.oo-ui-fieldLayout.oo-ui-labelElement.oo-ui-fieldLayout-align-inline > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-header > .oo-ui-labelElement-label {
+  padding-left: 0.42857143em;
 }
 .oo-ui-fieldLayout .oo-ui-fieldLayout-help {
   margin-right: 0;
   margin-right: 0;
 }
 .oo-ui-fieldLayout .oo-ui-fieldLayout-help .oo-ui-buttonElement-button {
-  padding-top: 1.57142857em;
+  padding-top: 1.42857143em;
+  padding-right: 0;
 }
 .oo-ui-fieldLayout.oo-ui-fieldLayout-align-top .oo-ui-fieldLayout-help,
 .oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline .oo-ui-fieldLayout-help {
-  margin-top: -0.14285714em;
+  margin-top: -0.42857143em;
   margin-right: -0.57142857em;
   margin-left: 0;
 }
 }
 .oo-ui-fieldLayout-messages .oo-ui-labelWidget {
   display: table-cell;
-  padding: 1px 0 1px 0.42857143em;
-  line-height: 1.4;
+  padding-left: 0.42857143em;
   vertical-align: middle;
 }
 .oo-ui-fieldLayout-disabled > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-header > .oo-ui-labelElement-label {
   display: table-cell;
   vertical-align: middle;
 }
-.oo-ui-actionFieldLayout-input {
-  padding-right: 1em;
-}
 .oo-ui-actionFieldLayout-button {
   width: 1%;
   white-space: nowrap;
 .oo-ui-actionFieldLayout.oo-ui-fieldLayout-align-top {
   max-width: 50em;
 }
+.oo-ui-actionFieldLayout .oo-ui-actionFieldLayout-input .oo-ui-widget:not( .oo-ui-textInputWidget ) {
+  margin-right: 0.57142857em;
+}
+.oo-ui-actionFieldLayout .oo-ui-actionFieldLayout-input .oo-ui-widget.oo-ui-textInputWidget > .oo-ui-inputWidget-input {
+  border-radius: 2px 0 0 2px;
+  position: relative;
+}
+.oo-ui-actionFieldLayout .oo-ui-actionFieldLayout-button .oo-ui-buttonElement-framed > .oo-ui-buttonElement-button {
+  border-radius: 0 2px 2px 0;
+  margin-left: -1px;
+}
 .oo-ui-actionFieldLayout .oo-ui-actionFieldLayout-button .oo-ui-buttonElement-frameless {
   margin-left: 0.14285714em;
 }
+.oo-ui-actionFieldLayout .oo-ui-actionFieldLayout-input > .oo-ui-textInputWidget > .oo-ui-inputWidget-input:hover,
+.oo-ui-actionFieldLayout .oo-ui-actionFieldLayout-input > .oo-ui-textInputWidget > .oo-ui-inputWidget-input:hover ~ *,
+.oo-ui-actionFieldLayout .oo-ui-actionFieldLayout-input > .oo-ui-textInputWidget > .oo-ui-inputWidget-input:focus,
+.oo-ui-actionFieldLayout .oo-ui-actionFieldLayout-input > .oo-ui-textInputWidget > .oo-ui-inputWidget-input:focus ~ * {
+  z-index: 1;
+}
+.oo-ui-actionFieldLayout .oo-ui-actionFieldLayout-button > .oo-ui-buttonElement > .oo-ui-buttonElement-button:hover,
+.oo-ui-actionFieldLayout .oo-ui-actionFieldLayout-button > .oo-ui-buttonElement > .oo-ui-buttonElement-button:focus {
+  z-index: 1;
+}
 .oo-ui-fieldsetLayout {
   position: relative;
   min-width: 0;
@@ -665,11 +697,9 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   margin-bottom: 0.5em;
   font-size: 1.14285714em;
   font-weight: bold;
-  line-height: 1.4;
 }
 .oo-ui-fieldsetLayout.oo-ui-iconElement > .oo-ui-fieldsetLayout-header > .oo-ui-labelElement-label {
   padding-left: 1.625em;
-  line-height: 1.5;
 }
 .oo-ui-fieldsetLayout .oo-ui-fieldsetLayout-help {
   margin-right: 0;
@@ -682,7 +712,8 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   margin-right: -0.57142857em;
 }
 .oo-ui-fieldsetLayout .oo-ui-fieldsetLayout-help .oo-ui-buttonElement-button {
-  padding-top: 1.57142857em;
+  padding-top: 1.42857143em;
+  padding-right: 0;
 }
 .oo-ui-formLayout + .oo-ui-fieldsetLayout,
 .oo-ui-formLayout + .oo-ui-formLayout {
@@ -736,20 +767,6 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
 .oo-ui-horizontalLayout > .oo-ui-widget {
   margin-bottom: 0.5em;
 }
-.oo-ui-widget .oo-ui-iconElement-icon,
-.oo-ui-widget .oo-ui-indicatorElement-indicator,
-.oo-ui-widget.oo-ui-iconElement .oo-ui-widget .oo-ui-iconElement-icon,
-.oo-ui-widget.oo-ui-indicatorElement .oo-ui-widget .oo-ui-indicatorElement-indicator {
-  display: none;
-}
-.oo-ui-widget.oo-ui-iconElement .oo-ui-iconElement-icon,
-.oo-ui-widget.oo-ui-iconElement > * > .oo-ui-iconElement-icon,
-.oo-ui-widget.oo-ui-iconElement .oo-ui-iconElement .oo-ui-iconElement-icon,
-.oo-ui-widget.oo-ui-indicatorElement > .oo-ui-indicatorElement-indicator,
-.oo-ui-widget.oo-ui-indicatorElement > * > .oo-ui-indicatorElement-indicator,
-.oo-ui-widget.oo-ui-indicatorElement .oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
-  display: block;
-}
 .oo-ui-optionWidget {
   position: relative;
   display: block;
@@ -766,9 +783,6 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   text-overflow: ellipsis;
   overflow: hidden;
 }
-.oo-ui-optionWidget .oo-ui-labelElement-label {
-  line-height: 1.6;
-}
 .oo-ui-optionWidget-selected .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
   opacity: 1;
 }
@@ -782,7 +796,7 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
 .oo-ui-decoratedOptionWidget.oo-ui-iconElement {
   padding-left: 2.64285714em;
 }
-.oo-ui-decoratedOptionWidget.oo-ui-iconElement .oo-ui-iconElement-icon {
+.oo-ui-decoratedOptionWidget .oo-ui-iconElement-icon {
   left: 0.78571429em;
 }
 .oo-ui-decoratedOptionWidget .oo-ui-labelElement-label {
@@ -791,9 +805,20 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
 .oo-ui-decoratedOptionWidget.oo-ui-indicatorElement {
   padding-right: 2.28571429em;
 }
-.oo-ui-decoratedOptionWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
+.oo-ui-decoratedOptionWidget .oo-ui-indicatorElement-indicator {
   right: 0.85714286em;
 }
+.oo-ui-decoratedOptionWidget.oo-ui-widget-enabled:hover .oo-ui-iconElement-icon,
+.oo-ui-decoratedOptionWidget.oo-ui-widget-enabled:hover .oo-ui-indicatorElement-indicator {
+  opacity: 0.73;
+}
+.oo-ui-decoratedOptionWidget.oo-ui-widget-enabled .oo-ui-iconElement-icon,
+.oo-ui-decoratedOptionWidget.oo-ui-widget-enabled .oo-ui-indicatorElement-indicator {
+  opacity: 0.87;
+  -webkit-transition: opacity 100ms;
+  -moz-transition: opacity 100ms;
+  transition: opacity 100ms;
+}
 .oo-ui-decoratedOptionWidget.oo-ui-widget-disabled .oo-ui-iconElement-icon,
 .oo-ui-decoratedOptionWidget.oo-ui-widget-disabled .oo-ui-indicatorElement-indicator {
   opacity: 0.51;
@@ -829,12 +854,14 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
 .oo-ui-labelWidget {
   display: inline-block;
 }
+.oo-ui-labelWidget.oo-ui-inline-help {
+  display: block;
+  color: #54595d;
+  font-size: 0.92857143em;
+}
 .oo-ui-iconWidget {
-  display: inline-block;
   vertical-align: middle;
   line-height: 2.5;
-}
-.oo-ui-iconWidget.oo-ui-iconElement.oo-ui-iconElement-icon {
   display: inline-block;
   position: static;
   top: auto;
@@ -844,12 +871,9 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   opacity: 0.51;
 }
 .oo-ui-indicatorWidget {
-  display: inline-block;
   vertical-align: middle;
   line-height: 2.5;
   margin: 0.42857143em;
-}
-.oo-ui-indicatorWidget.oo-ui-indicatorElement.oo-ui-indicatorElement-indicator {
   display: inline-block;
   position: static;
   top: auto;
@@ -1083,7 +1107,7 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   right: 0;
 }
 .oo-ui-popupWidget-body {
-  line-height: 1.4;
+  line-height: 1.42857143em;
 }
 .oo-ui-popupWidget-body-padded {
   margin: 0.64285714em 0.85714286em 0.57142857em;
@@ -1114,10 +1138,10 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   padding: 0;
 }
 .oo-ui-checkboxInputWidget {
+  display: inline-block;
   position: relative;
   line-height: 1.42857143em;
   white-space: nowrap;
-  display: inline-block;
 }
 .oo-ui-checkboxInputWidget * {
   font: inherit;
@@ -1138,15 +1162,13 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   -webkit-box-sizing: border-box;
   -moz-box-sizing: border-box;
   box-sizing: border-box;
+  position: absolute;
   left: 0;
   width: 1.42857143em;
   height: 1.42857143em;
   border: 1px solid #72777d;
   border-radius: 2px;
 }
-.oo-ui-checkboxInputWidget [type='checkbox'] + span.oo-ui-iconWidget.oo-ui-iconElement.oo-ui-iconElement-icon {
-  position: absolute;
-}
 .oo-ui-checkboxInputWidget [type='checkbox']:checked + span {
   background-size: 1em 1em;
 }
@@ -1159,9 +1181,9 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
 }
 .oo-ui-checkboxInputWidget.oo-ui-widget-enabled [type='checkbox'] + span {
   cursor: pointer;
-  -webkit-transition: background-color 100ms, background-size 100ms, border-color 100ms, box-shadow 100ms;
-  -moz-transition: background-color 100ms, background-size 100ms, border-color 100ms, box-shadow 100ms;
-  transition: background-color 100ms, background-size 100ms, border-color 100ms, box-shadow 100ms;
+  -webkit-transition: background-color 100ms, border-color 100ms, box-shadow 100ms;
+  -moz-transition: background-color 100ms, border-color 100ms, box-shadow 100ms;
+  transition: background-color 100ms, border-color 100ms, box-shadow 100ms;
 }
 .oo-ui-checkboxInputWidget.oo-ui-widget-enabled [type='checkbox']:focus + span {
   border-color: #36c;
@@ -1196,9 +1218,6 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
 .oo-ui-checkboxMultiselectInputWidget .oo-ui-fieldLayout {
   margin-top: 0.28571429em;
 }
-.oo-ui-checkboxMultiselectInputWidget .oo-ui-fieldLayout .oo-ui-fieldLayout-body .oo-ui-labelElement-label {
-  line-height: 1.5;
-}
 .oo-ui-dropdownInputWidget {
   position: relative;
   vertical-align: middle;
@@ -1284,10 +1303,10 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   border-color: #c8ccd1;
 }
 .oo-ui-radioInputWidget {
+  display: inline-block;
   position: relative;
   line-height: 1.42857143em;
   white-space: nowrap;
-  display: inline-block;
 }
 .oo-ui-radioInputWidget * {
   font: inherit;
@@ -1371,9 +1390,6 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
 .oo-ui-radioSelectInputWidget .oo-ui-fieldLayout {
   margin-top: 0.28571429em;
 }
-.oo-ui-radioSelectInputWidget .oo-ui-fieldLayout .oo-ui-fieldLayout-body .oo-ui-labelElement-label {
-  line-height: 1.5;
-}
 .oo-ui-textInputWidget {
   position: relative;
   vertical-align: middle;
@@ -1468,7 +1484,7 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   line-height: 1.07142857em;
 }
 .oo-ui-textInputWidget textarea {
-  line-height: 1.275;
+  line-height: 1.286;
 }
 .oo-ui-textInputWidget .oo-ui-pendingElement-pending {
   background-color: transparent;
@@ -1476,9 +1492,9 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
 .oo-ui-textInputWidget.oo-ui-widget-enabled input,
 .oo-ui-textInputWidget.oo-ui-widget-enabled textarea {
   box-shadow: inset 0 0 0 1px transparent;
-  -webkit-transition: border-color 200ms cubic-bezier(0.4, 0.55, 0.55, 1), box-shadow 200ms cubic-bezier(0.4, 0.55, 0.55, 1);
-  -moz-transition: border-color 200ms cubic-bezier(0.4, 0.55, 0.55, 1), box-shadow 200ms cubic-bezier(0.4, 0.55, 0.55, 1);
-  transition: border-color 200ms cubic-bezier(0.4, 0.55, 0.55, 1), box-shadow 200ms cubic-bezier(0.4, 0.55, 0.55, 1);
+  -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 {
@@ -1613,7 +1629,7 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   -moz-transition: background-color 100ms, color 100ms;
   transition: background-color 100ms, color 100ms;
 }
-.oo-ui-menuOptionWidget.oo-ui-optionWidget .oo-ui-iconElement-icon.oo-ui-menuOptionWidget-checkIcon {
+.oo-ui-menuOptionWidget-checkIcon {
   display: none;
 }
 .oo-ui-menuOptionWidget.oo-ui-optionWidget-highlighted {
@@ -1818,11 +1834,7 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   border-top-left-radius: 0;
   border-bottom-left-radius: 0;
 }
-.oo-ui-comboBoxInputWidget-php .oo-ui-indicatorWidget.oo-ui-indicatorElement.oo-ui-indicatorElement-indicator {
-  display: block;
-  position: absolute;
-  top: 0;
-  height: 100%;
+.oo-ui-comboBoxInputWidget-php .oo-ui-indicatorWidget {
   right: 0.85714286em;
   margin: 0;
 }
@@ -1871,7 +1883,6 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   white-space: normal;
 }
 .oo-ui-checkboxMultioptionWidget.oo-ui-labelElement .oo-ui-labelElement-label {
-  line-height: 1.5;
   padding-left: 0.42857143em;
 }
 .oo-ui-checkboxMultioptionWidget .oo-ui-checkboxInputWidget {
@@ -1889,9 +1900,9 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
 }
 .oo-ui-progressBarWidget-bar {
   height: 1em;
-  -webkit-transition: width 200ms;
-  -moz-transition: width 200ms;
-  transition: width 200ms;
+  -webkit-transition: width 100ms;
+  -moz-transition: width 100ms;
+  transition: width 100ms;
 }
 .oo-ui-progressBarWidget-indeterminate .oo-ui-progressBarWidget-bar {
   -webkit-animation: oo-ui-progressBarWidget-slide 2s infinite linear;
index 68efe07..cf48c5b 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOUI v0.27.0
+ * OOUI v0.27.5
  * https://www.mediawiki.org/wiki/OOUI
  *
  * Copyright 2011–2018 OOUI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2018-05-09T00:44:45Z
+ * Date: 2018-07-11T18:13:04Z
  */
 ( function ( OO ) {
 
@@ -333,11 +333,12 @@ OO.ui.now = Date.now || function () {
  *
  * @param {string|HTMLElement|jQuery} idOrNode
  *   A DOM id (if a string) or node for the widget to infuse.
+ * @param {Object} [config] Configuration options
  * @return {OO.ui.Element}
  *   The `OO.ui.Element` corresponding to this (infusable) document node.
  */
-OO.ui.infuse = function ( idOrNode ) {
-       return OO.ui.Element.static.infuse( idOrNode );
+OO.ui.infuse = function ( idOrNode, config ) {
+       return OO.ui.Element.static.infuse( idOrNode, config );
 };
 
 ( function () {
@@ -685,14 +686,15 @@ OO.ui.Element.static.tagName = 'div';
  *
  * @param {string|HTMLElement|jQuery} idOrNode
  *   A DOM id (if a string) or node for the widget to infuse.
+ * @param {Object} [config] Configuration options
  * @return {OO.ui.Element}
  *   The `OO.ui.Element` corresponding to this (infusable) document node.
  *   For `Tag` objects emitted on the HTML side (used occasionally for content)
  *   the value returned is a newly-created Element wrapping around the existing
  *   DOM node.
  */
-OO.ui.Element.static.infuse = function ( idOrNode ) {
-       var obj = OO.ui.Element.static.unsafeInfuse( idOrNode, false );
+OO.ui.Element.static.infuse = function ( idOrNode, config ) {
+       var obj = OO.ui.Element.static.unsafeInfuse( idOrNode, config, false );
        // Verify that the type matches up.
        // FIXME: uncomment after T89721 is fixed, see T90929.
        /*
@@ -709,12 +711,13 @@ OO.ui.Element.static.infuse = function ( idOrNode ) {
  *
  * @private
  * @param {string|HTMLElement|jQuery} idOrNode
- * @param {jQuery.Promise|boolean} domPromise A promise that will be resolved
+ * @param {Object} [config] Configuration options
+ * @param {jQuery.Promise} [domPromise] A promise that will be resolved
  *     when the top-level widget of this infusion is inserted into DOM,
- *     replacing the original node; or false for top-level invocation.
+ *     replacing the original node; only used internally.
  * @return {OO.ui.Element}
  */
-OO.ui.Element.static.unsafeInfuse = function ( idOrNode, domPromise ) {
+OO.ui.Element.static.unsafeInfuse = function ( idOrNode, config, domPromise ) {
        // look for a cached result of a previous infusion.
        var id, $elem, error, data, cls, parts, parent, obj, top, state, infusedChildren;
        if ( typeof idOrNode === 'string' ) {
@@ -772,7 +775,7 @@ OO.ui.Element.static.unsafeInfuse = function ( idOrNode, domPromise ) {
        }
        if ( data._ === 'Tag' ) {
                // Special case: this is a raw Tag; wrap existing node, don't rebuild.
-               return new OO.ui.Element( { $element: $elem } );
+               return new OO.ui.Element( $.extend( {}, config, { $element: $elem } ) );
        }
        parts = data._.split( '.' );
        cls = OO.getProp.apply( OO, [ window ].concat( parts ) );
@@ -796,7 +799,7 @@ OO.ui.Element.static.unsafeInfuse = function ( idOrNode, domPromise ) {
                throw new Error( 'Unknown widget type: id: ' + id + ', class: ' + data._ );
        }
 
-       if ( domPromise === false ) {
+       if ( !domPromise ) {
                top = $.Deferred();
                domPromise = top.promise();
        }
@@ -807,7 +810,7 @@ OO.ui.Element.static.unsafeInfuse = function ( idOrNode, domPromise ) {
                var infused;
                if ( OO.isPlainObject( value ) ) {
                        if ( value.tag ) {
-                               infused = OO.ui.Element.static.unsafeInfuse( value.tag, 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' ) || [] );
@@ -825,7 +828,7 @@ OO.ui.Element.static.unsafeInfuse = function ( idOrNode, domPromise ) {
        state = cls.static.gatherPreInfuseState( $elem[ 0 ], data );
        // rebuild widget
        // eslint-disable-next-line new-cap
-       obj = new cls( data );
+       obj = new cls( $.extend( {}, config, data ) );
        // If anyone is holding a reference to the old DOM element,
        // let's allow them to OO.ui.infuse() it and do what they expect, see T105828.
        // Do not use jQuery.data(), as using it on detached nodes leaks memory in 1.x line by design.
@@ -2669,6 +2672,7 @@ OO.ui.mixin.IconElement.prototype.setIconElement = function ( $icon ) {
 
        this.$icon = $icon
                .addClass( 'oo-ui-iconElement-icon' )
+               .toggleClass( 'oo-ui-iconElement-noIcon', !this.icon )
                .toggleClass( 'oo-ui-icon-' + this.icon, !!this.icon );
        if ( this.iconTitle !== null ) {
                this.$icon.attr( 'title', this.iconTitle );
@@ -2703,6 +2707,9 @@ OO.ui.mixin.IconElement.prototype.setIcon = function ( icon ) {
        }
 
        this.$element.toggleClass( 'oo-ui-iconElement', !!this.icon );
+       if ( this.$icon ) {
+               this.$icon.toggleClass( 'oo-ui-iconElement-noIcon', !this.icon );
+       }
        this.updateThemeClasses();
 
        return this;
@@ -2840,6 +2847,7 @@ OO.ui.mixin.IndicatorElement.prototype.setIndicatorElement = function ( $indicat
 
        this.$indicator = $indicator
                .addClass( 'oo-ui-indicatorElement-indicator' )
+               .toggleClass( 'oo-ui-indicatorElement-noIndicator', !this.indicator )
                .toggleClass( 'oo-ui-indicator-' + this.indicator, !!this.indicator );
        if ( this.indicatorTitle !== null ) {
                this.$indicator.attr( 'title', this.indicatorTitle );
@@ -2870,6 +2878,9 @@ OO.ui.mixin.IndicatorElement.prototype.setIndicator = function ( indicator ) {
        }
 
        this.$element.toggleClass( 'oo-ui-indicatorElement', !!this.indicator );
+       if ( this.$indicator ) {
+               this.$indicator.toggleClass( 'oo-ui-indicatorElement-noIndicator', !this.indicator );
+       }
        this.updateThemeClasses();
 
        return this;
@@ -3602,7 +3613,7 @@ OO.ui.mixin.AccessKeyedElement.prototype.formatTitleWithAccessKey = function ( t
  *     var button = new OO.ui.ButtonWidget( {
  *         label: 'Button with Icon',
  *         icon: 'trash',
- *         iconTitle: 'Remove'
+ *         title: 'Remove'
  *     } );
  *     $( 'body' ).append( button.$element );
  *
@@ -3907,7 +3918,7 @@ OO.ui.ButtonGroupWidget.prototype.simulateLabelClick = function () {
  *     // An icon widget with a label
  *     var myIcon = new OO.ui.IconWidget( {
  *         icon: 'help',
- *         iconTitle: 'Help'
+ *         title: 'Help'
  *      } );
  *      // Create a label.
  *      var iconLabel = new OO.ui.LabelWidget( {
@@ -4118,7 +4129,7 @@ OO.ui.LabelWidget.static.tagName = 'label';
  *
  *     MessageDialog.prototype.initialize = function () {
  *         MessageDialog.parent.prototype.initialize.apply( this, arguments );
- *         this.content = new OO.ui.PanelLayout( { $: this.$, padded: true } );
+ *         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.$body.append( this.content.$element );
  *     };
@@ -5071,8 +5082,8 @@ OO.ui.mixin.ClippableElement.prototype.clip = function () {
  *
  * @constructor
  * @param {Object} [config] Configuration options
- * @cfg {number} [width=320] Width of popup in pixels
- * @cfg {number} [height] Height of popup in pixels. Omit to use the automatic height.
+ * @cfg {number|null} [width=320] Width of popup in pixels. Pass `null` to use automatic width.
+ * @cfg {number|null} [height=null] Height of popup in pixels. Pass `null` to use automatic height.
  * @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
@@ -5137,19 +5148,18 @@ OO.ui.PopupWidget = function OoUiPopupWidget( config ) {
        this.$container = config.$container;
        this.containerPadding = config.containerPadding !== undefined ? config.containerPadding : 10;
        this.autoClose = !!config.autoClose;
-       this.$autoCloseIgnore = config.$autoCloseIgnore;
        this.transitionTimeout = null;
        this.anchored = false;
-       this.width = config.width !== undefined ? config.width : 320;
-       this.height = config.height !== undefined ? config.height : null;
        this.onMouseDownHandler = this.onMouseDown.bind( this );
        this.onDocumentKeyDownHandler = this.onDocumentKeyDown.bind( this );
 
        // Initialization
+       this.setSize( config.width, config.height );
        this.toggleAnchor( config.anchor === undefined || config.anchor );
        this.setAlignment( config.align || 'center' );
        this.setPosition( config.position || 'below' );
        this.setAutoFlip( config.autoFlip === undefined || config.autoFlip );
+       this.setAutoCloseIgnore( config.$autoCloseIgnore );
        this.$body.addClass( 'oo-ui-popupWidget-body' );
        this.$anchor.addClass( 'oo-ui-popupWidget-anchor' );
        this.$popup
@@ -5231,6 +5241,13 @@ OO.ui.PopupWidget.prototype.onMouseDown = function ( e ) {
 OO.ui.PopupWidget.prototype.bindMouseDownListener = function () {
        // Capture clicks outside popup
        this.getElementWindow().addEventListener( 'mousedown', this.onMouseDownHandler, true );
+       // We add 'click' event because iOS safari needs to respond to this event.
+       // We can't use 'touchstart' (as is usually the equivalent to 'mousedown') because
+       // then it will trigger when scrolling. While iOS Safari has some reported behavior
+       // of occasionally not emitting 'click' properly, that event seems to be the standard
+       // that it should be emitting, so we add it to this and will operate the event handler
+       // on whichever of these events was triggered first
+       this.getElementDocument().addEventListener( 'click', this.onMouseDownHandler, true );
 };
 
 /**
@@ -5251,6 +5268,7 @@ OO.ui.PopupWidget.prototype.onCloseButtonClick = function () {
  */
 OO.ui.PopupWidget.prototype.unbindMouseDownListener = function () {
        this.getElementWindow().removeEventListener( 'mousedown', this.onMouseDownHandler, true );
+       this.getElementDocument().removeEventListener( 'click', this.onMouseDownHandler, true );
 };
 
 /**
@@ -5447,13 +5465,13 @@ OO.ui.PopupWidget.prototype.toggle = function ( show ) {
  *
  * Changing the size may also change the popup's position depending on the alignment.
  *
- * @param {number} width Width in pixels
- * @param {number} height Height in pixels
+ * @param {number|null} [width=320] Width in pixels. Pass `null` to use automatic width.
+ * @param {number|null} [height=null] Height in pixels. Pass `null` to use automatic height.
  * @param {boolean} [transition=false] Use a smooth transition
  * @chainable
  */
 OO.ui.PopupWidget.prototype.setSize = function ( width, height, transition ) {
-       this.width = width;
+       this.width = width !== undefined ? width : 320;
        this.height = height !== undefined ? height : null;
        if ( this.isVisible() ) {
                this.updateDimensions( transition );
@@ -5543,7 +5561,7 @@ OO.ui.PopupWidget.prototype.computePosition = function () {
        // Set height and width before we do anything else, since it might cause our measurements
        // to change (e.g. due to scrollbars appearing or disappearing), and it also affects centering
        this.$popup.css( {
-               width: this.width,
+               width: this.width !== null ? this.width : 'auto',
                height: this.height !== null ? this.height : 'auto'
        } );
 
@@ -5560,7 +5578,7 @@ OO.ui.PopupWidget.prototype.computePosition = function () {
        near = vertical ? 'top' : 'left';
        far = vertical ? 'bottom' : 'right';
        sizeProp = vertical ? 'Height' : 'Width';
-       popupSize = vertical ? ( this.height || this.$popup.height() ) : this.width;
+       popupSize = vertical ? ( this.height || this.$popup.height() ) : ( this.width || this.$popup.width() );
 
        this.setAnchorEdge( anchorEdgeMap[ popupPosition ] );
        this.horizontalPosition = vertical ? popupPosition : hPosMap[ align ];
@@ -5715,6 +5733,17 @@ OO.ui.PopupWidget.prototype.setAutoFlip = function ( autoFlip ) {
        }
 };
 
+/**
+ * Set which elements will not close the popup when clicked.
+ *
+ * For auto-closing popups, clicks on these elements will not cause the popup to auto-close.
+ *
+ * @param {jQuery} $autoCloseIgnore Elements to ignore for auto-closing
+ */
+OO.ui.PopupWidget.prototype.setAutoCloseIgnore = function ( $autoCloseIgnore ) {
+       this.$autoCloseIgnore = $autoCloseIgnore;
+};
+
 /**
  * Get an ID of the body element, this can be used as the
  * `aria-describedby` attribute for an input field.
@@ -5819,8 +5848,7 @@ OO.ui.PopupButtonWidget = function OoUiPopupButtonWidget( config ) {
 
        // Initialization
        this.$element
-               .addClass( 'oo-ui-popupButtonWidget' )
-               .attr( 'aria-haspopup', 'true' );
+               .addClass( 'oo-ui-popupButtonWidget' );
        this.popup.$element
                .addClass( 'oo-ui-popupButtonWidget-popup' )
                .toggleClass( 'oo-ui-popupButtonWidget-framed-popup', this.isFramed() )
@@ -7281,6 +7309,11 @@ OO.ui.MenuSelectWidget = function OoUiMenuSelectWidget( config ) {
        OO.ui.mixin.ClippableElement.call( this, $.extend( {}, config, { $clippable: this.$group } ) );
        OO.ui.mixin.FloatableElement.call( this, config );
 
+       // Initial vertical positions other than 'center' will result in
+       // the menu being flipped if there is not enough space in the container.
+       // Store the original position so we know what to reset to.
+       this.originalVerticalPosition = this.verticalPosition;
+
        // Properties
        this.autoHide = config.autoHide === undefined || !!config.autoHide;
        this.hideOnChoose = config.hideOnChoose === undefined || !!config.hideOnChoose;
@@ -7320,6 +7353,21 @@ OO.mixinClass( OO.ui.MenuSelectWidget, OO.ui.mixin.FloatableElement );
  * The menu is ready: it is visible and has been positioned and clipped.
  */
 
+/* Static properties */
+
+/**
+ * Positions to flip to if there isn't room in the container for the
+ * menu in a specific direction.
+ *
+ * @property {Object.<string,string>}
+ */
+OO.ui.MenuSelectWidget.static.flippedPositions = {
+       below: 'above',
+       above: 'below',
+       top: 'bottom',
+       bottom: 'top'
+};
+
 /* Methods */
 
 /**
@@ -7382,8 +7430,7 @@ OO.ui.MenuSelectWidget.prototype.onKeyDown = function ( e ) {
  * @protected
  */
 OO.ui.MenuSelectWidget.prototype.updateItemVisibility = function () {
-       var i, item, visible, section, sectionEmpty, filter, exactFilter,
-               firstItemFound = false,
+       var i, item, items, visible, section, sectionEmpty, filter, exactFilter,
                anyVisible = false,
                len = this.items.length,
                showAll = !this.isVisible(),
@@ -7392,7 +7439,6 @@ OO.ui.MenuSelectWidget.prototype.updateItemVisibility = function () {
        if ( this.$input && this.filterFromInput ) {
                filter = showAll ? null : this.getItemMatcher( this.$input.val() );
                exactFilter = this.getItemMatcher( this.$input.val(), true );
-
                // Hide non-matching options, and also hide section headers if all options
                // in their section are hidden.
                for ( i = 0; i < len; i++ ) {
@@ -7410,11 +7456,6 @@ OO.ui.MenuSelectWidget.prototype.updateItemVisibility = function () {
                                anyVisible = anyVisible || visible;
                                sectionEmpty = sectionEmpty && !visible;
                                item.toggle( visible );
-                               if ( this.highlightOnFilter && visible && !firstItemFound ) {
-                                       // Highlight the first item in the list
-                                       this.highlightItem( item );
-                                       firstItemFound = true;
-                               }
                        }
                }
                // Process the final section
@@ -7427,6 +7468,20 @@ OO.ui.MenuSelectWidget.prototype.updateItemVisibility = function () {
                }
 
                this.$element.toggleClass( 'oo-ui-menuSelectWidget-invisible', !anyVisible );
+
+               if ( this.highlightOnFilter ) {
+                       // Highlight the first item on the list
+                       item = null;
+                       items = this.getItems();
+                       for ( i = 0; i < items.length; i++ ) {
+                               if ( items[ i ].isVisible() ) {
+                                       item = items[ i ];
+                                       break;
+                               }
+                       }
+                       this.highlightItem( item );
+               }
+
        }
 
        // Reevaluate clipping
@@ -7551,7 +7606,7 @@ OO.ui.MenuSelectWidget.prototype.clearItems = function () {
  * @inheritdoc
  */
 OO.ui.MenuSelectWidget.prototype.toggle = function ( visible ) {
-       var change, belowHeight, aboveHeight;
+       var change, originalHeight, flippedHeight;
 
        visible = ( visible === undefined ? !this.visible : !!visible ) && !!this.items.length;
        change = visible !== this.isVisible();
@@ -7561,15 +7616,10 @@ OO.ui.MenuSelectWidget.prototype.toggle = function ( visible ) {
                this.warnedUnattached = true;
        }
 
-       if ( change ) {
-               if ( visible && ( this.width || this.$floatableContainer ) ) {
-                       this.setIdealSize( this.width || this.$floatableContainer.width() );
-               }
-               if ( visible ) {
-                       // Reset position before showing the popup again. It's possible we no longer need to flip
-                       // (e.g. if the user scrolled).
-                       this.setVerticalPosition( 'below' );
-               }
+       if ( change && visible ) {
+               // Reset position before showing the popup again. It's possible we no longer need to flip
+               // (e.g. if the user scrolled).
+               this.setVerticalPosition( this.originalVerticalPosition );
        }
 
        // Parent method
@@ -7577,22 +7627,42 @@ OO.ui.MenuSelectWidget.prototype.toggle = function ( visible ) {
 
        if ( change ) {
                if ( visible ) {
+
+                       if ( this.width ) {
+                               this.setIdealSize( this.width );
+                       } else if ( this.$floatableContainer ) {
+                               this.$clippable.css( 'width', 'auto' );
+                               this.setIdealSize(
+                                       this.$floatableContainer[ 0 ].offsetWidth > this.$clippable[ 0 ].offsetWidth ?
+                                               // Dropdown is smaller than handle so expand to width
+                                               this.$floatableContainer[ 0 ].offsetWidth :
+                                               // Dropdown is larger than handle so auto size
+                                               'auto'
+                               );
+                               this.$clippable.css( 'width', '' );
+                       }
+
                        this.togglePositioning( !!this.$floatableContainer );
                        this.toggleClipping( true );
 
                        this.bindKeyDownListener();
                        this.bindKeyPressListener();
 
-                       if ( this.isClippedVertically() || this.isFloatableOutOfView() ) {
-                               // If opening the menu downwards causes it to be clipped, flip it to open upwards instead
-                               belowHeight = this.$element.height();
-                               this.setVerticalPosition( 'above' );
+                       if (
+                               ( this.isClippedVertically() || this.isFloatableOutOfView() ) &&
+                               this.originalVerticalPosition !== 'center'
+                       ) {
+                               // If opening the menu in one direction causes it to be clipped, flip it
+                               originalHeight = this.$element.height();
+                               this.setVerticalPosition(
+                                       this.constructor.static.flippedPositions[ this.originalVerticalPosition ]
+                               );
                                if ( this.isClippedVertically() || this.isFloatableOutOfView() ) {
-                                       // If opening upwards also causes it to be clipped, flip it to open in whichever direction
+                                       // If flipping also causes it to be clipped, open in whichever direction
                                        // we have more space
-                                       aboveHeight = this.$element.height();
-                                       if ( aboveHeight < belowHeight ) {
-                                               this.setVerticalPosition( 'below' );
+                                       flippedHeight = this.$element.height();
+                                       if ( originalHeight > flippedHeight ) {
+                                               this.setVerticalPosition( this.originalVerticalPosition );
                                        }
                                }
                        }
@@ -11249,7 +11319,14 @@ OO.ui.ComboBoxInputWidget.prototype.setOptions = function ( options ) {
  * - **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.
+ * Help text can either be:
+ *
+ * - 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 espose 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.
  *
  * [1]: https://www.mediawiki.org/wiki/OOUI/Layouts/Fields_and_Fieldsets
@@ -11262,15 +11339,25 @@ OO.ui.ComboBoxInputWidget.prototype.setOptions = function ( options ) {
  * @constructor
  * @param {OO.ui.Widget} fieldWidget Field widget
  * @param {Object} [config] Configuration options
- * @cfg {string} [align='left'] Alignment of the label: 'left', 'right', 'top' or 'inline'
- * @cfg {Array} [errors] Error messages about the widget, which will be displayed below the widget.
+ * @cfg {string} [align='left'] Alignment of the label: 'left', 'right', 'top'
+ *  or 'inline'
+ * @cfg {Array} [errors] Error messages about 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.
+ * @cfg {Array} [notices] Notices about the widget, which will be displayed
+ *  below the widget.
  *  The array may contain strings or OO.ui.HtmlSnippet instances.
- * @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.
+ *  These are more visible than `help` messages when `helpInline` is set, and so
+ *  might be good for transient messages.
+ * @cfg {string|OO.ui.HtmlSnippet} [help] Help text. When help text is specified
+ *  and `helpInline` is `false`, a "help" icon will appear in the upper-right
+ *  corner of the rendered field; clicking it will display the text in a popup.
+ *  If `helpInline` is `true`, then a subtle description will be shown after the
+ *  label.
+ * @cfg {boolean} [helpInline=false] Whether or not the help should be inline,
+ *  or shown when the "help" icon is clicked.
+ * @cfg {jQuery} [$overlay] Passed to OO.ui.PopupButtonWidget for help popup, if
+ * `help` is given.
  *  See <https://www.mediawiki.org/wiki/OOUI/Concepts#Overlays>.
  *
  * @throws {Error} An error is thrown if no widget is specified
@@ -11288,7 +11375,7 @@ OO.ui.FieldLayout = function OoUiFieldLayout( fieldWidget, config ) {
        }
 
        // Configuration initialization
-       config = $.extend( { align: 'left' }, config );
+       config = $.extend( { align: 'left', helpInline: false }, config );
 
        // Parent constructor
        OO.ui.FieldLayout.parent.call( this, config );
@@ -11308,49 +11395,29 @@ OO.ui.FieldLayout = function OoUiFieldLayout( fieldWidget, config ) {
        this.$header = $( '<span>' );
        this.$body = $( '<div>' );
        this.align = null;
-       if ( config.help ) {
-               this.popupButtonWidget = new OO.ui.PopupButtonWidget( {
-                       $overlay: config.$overlay,
-                       popup: {
-                               padded: true
-                       },
-                       classes: [ 'oo-ui-fieldLayout-help' ],
-                       framed: false,
-                       icon: 'info',
-                       label: OO.ui.msg( 'ooui-field-help' )
-               } );
-               if ( config.help instanceof OO.ui.HtmlSnippet ) {
-                       this.popupButtonWidget.getPopup().$body.html( config.help.toString() );
-               } else {
-                       this.popupButtonWidget.getPopup().$body.text( config.help );
-               }
-               this.$help = this.popupButtonWidget.$element;
-       } else {
-               this.$help = $( [] );
-       }
+       this.helpInline = config.helpInline;
 
        // Events
        this.fieldWidget.connect( this, { disable: 'onFieldDisable' } );
 
        // Initialization
-       if ( config.help ) {
-               // Set the 'aria-describedby' attribute on the fieldWidget
-               // Preference given to an input or a button
-               (
-                       this.fieldWidget.$input ||
-                       this.fieldWidget.$button ||
-                       this.fieldWidget.$element
-               ).attr(
-                       'aria-describedby',
-                       this.popupButtonWidget.getPopup().getBodyId()
-               );
-       }
+       this.$help = config.help ?
+               this.createHelpElement( config.help, config.$overlay ) :
+               $( [] );
        if ( this.fieldWidget.getInputId() ) {
                this.$label.attr( 'for', this.fieldWidget.getInputId() );
+               if ( this.helpInline ) {
+                       this.$help.attr( 'for', this.fieldWidget.getInputId() );
+               }
        } else {
                this.$label.on( 'click', function () {
                        this.fieldWidget.simulateLabelClick();
                }.bind( this ) );
+               if ( this.helpInline ) {
+                       this.$help.on( 'click', function () {
+                               this.fieldWidget.simulateLabelClick();
+                       }.bind( this ) );
+               }
        }
        this.$element
                .addClass( 'oo-ui-fieldLayout' )
@@ -11450,15 +11517,26 @@ OO.ui.FieldLayout.prototype.setAlignment = function ( value ) {
                        value = 'top';
                }
                // Reorder elements
-               if ( value === 'top' ) {
-                       this.$header.append( this.$help, this.$label );
-                       this.$body.append( this.$header, this.$field );
-               } else if ( value === 'inline' ) {
-                       this.$header.append( this.$help, this.$label );
-                       this.$body.append( this.$field, this.$header );
+
+               if ( this.helpInline ) {
+                       if ( value === 'inline' ) {
+                               this.$header.append( this.$label, this.$help );
+                               this.$body.append( this.$field, this.$header );
+                       } else {
+                               this.$header.append( this.$label, this.$help );
+                               this.$body.append( this.$header, this.$field );
+                       }
                } else {
-                       this.$header.append( this.$label );
-                       this.$body.append( this.$header, this.$help, this.$field );
+                       if ( value === 'top' ) {
+                               this.$header.append( this.$help, this.$label );
+                               this.$body.append( this.$header, this.$field );
+                       } else if ( value === 'inline' ) {
+                               this.$header.append( this.$help, this.$label );
+                               this.$body.append( this.$field, this.$header );
+                       } else {
+                               this.$header.append( this.$label );
+                               this.$body.append( this.$header, this.$help, this.$field );
+                       }
                }
                // Set classes. The following classes can be used here:
                // * oo-ui-fieldLayout-align-left
@@ -11540,6 +11618,56 @@ OO.ui.FieldLayout.prototype.formatTitleWithAccessKey = function ( title ) {
        return title;
 };
 
+/**
+ * Creates and returns the help element. Also sets the `aria-describedby`
+ * attribute on the main element of the `fieldWidget`.
+ *
+ * @private
+ * @param {string|OO.ui.HtmlSnippet} [help] Help text.
+ * @param {jQuery} [$overlay] Passed to OO.ui.PopupButtonWidget for help popup.
+ * @return {jQuery} The element that should become `this.$help`.
+ */
+OO.ui.FieldLayout.prototype.createHelpElement = function ( help, $overlay ) {
+       var helpId, helpWidget;
+
+       if ( this.helpInline ) {
+               helpWidget = new OO.ui.LabelWidget( {
+                       label: help,
+                       classes: [ 'oo-ui-inline-help' ]
+               } );
+
+               helpId = helpWidget.getElementId();
+       } else {
+               helpWidget = new OO.ui.PopupButtonWidget( {
+                       $overlay: $overlay,
+                       popup: {
+                               padded: true
+                       },
+                       classes: [ 'oo-ui-fieldLayout-help' ],
+                       framed: false,
+                       icon: 'info',
+                       label: OO.ui.msg( 'ooui-field-help' )
+               } );
+               if ( help instanceof OO.ui.HtmlSnippet ) {
+                       helpWidget.getPopup().$body.html( help.toString() );
+               } else {
+                       helpWidget.getPopup().$body.text( help );
+               }
+
+               helpId = helpWidget.getPopup().getBodyId();
+       }
+
+       // Set the 'aria-describedby' attribute on the fieldWidget
+       // Preference given to an input or a button
+       (
+               this.fieldWidget.$input ||
+               this.fieldWidget.$button ||
+               this.fieldWidget.$element
+       ).attr( 'aria-describedby', helpId );
+
+       return helpWidget.$element;
+};
+
 /**
  * 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}),
@@ -12342,4 +12470,4 @@ OO.ui.NumberInputWidget.prototype.setDisabled = function ( disabled ) {
 
 }( OO ) );
 
-//# sourceMappingURL=oojs-ui-core.js.map
\ No newline at end of file
+//# sourceMappingURL=oojs-ui-core.js.map.json
\ No newline at end of file
diff --git a/resources/lib/oojs-ui/oojs-ui-core.js.map b/resources/lib/oojs-ui/oojs-ui-core.js.map
deleted file mode 100644 (file)
index ffbba44..0000000
+++ /dev/null
@@ -1 +0,0 @@
-{"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/IconElement.js","../src/mixins/IndicatorElement.js","../src/mixins/LabelElement.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 * @return {OO.ui.Element}\n *   The `OO.ui.Element` corresponding to this (infusable) document node.\n */\nOO.ui.infuse = function ( idOrNode ) {\n\treturn OO.ui.Element.static.infuse( idOrNode );\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 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};\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 *         $( '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 *         $( '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 ( $.isFunction( msg ) ) {\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$( '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.$ = $;\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.join( ' ' ) );\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 * @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 ) {\n\tvar obj = OO.ui.Element.static.unsafeInfuse( idOrNode, false );\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 {jQuery.Promise|boolean} 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; or false for top-level invocation.\n * @return {OO.ui.Element}\n */\nOO.ui.Element.static.unsafeInfuse = function ( idOrNode, 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( { $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 === false ) {\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, 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( 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 jQuery ) {\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 dir=\"rtl\" style=\"font-size: 14px; width: 1px; height: 1px; position: absolute; top: -1000px; overflow: scroll\">A</div>' ),\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$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\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 */\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 */\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 */\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 ( $.isFunction( this[ methods[ i ] ] ) ) {\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 */\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 * 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 */\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 */\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.join( ' ' ) )\n\t\t.addClass( classes.on.join( ' ' ) );\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 *     var button2 = new OO.ui.ButtonWidget( {\n *         label: 'second',\n *         tabIndex: 2\n *     } );\n *     var button3 = new OO.ui.ButtonWidget( {\n *         label: 'third',\n *         tabIndex: 3\n *     } );\n *     var button4 = new OO.ui.ButtonWidget( {\n *         label: 'first',\n *         tabIndex: 1\n *     } );\n *     $( '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 */\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 */\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 */\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 */\nOO.ui.mixin.TabIndexedElement.prototype.focus = function () {\n\tif ( !this.isDisabled() ) {\n\t\tthis.$tabIndexed.focus();\n\t}\n\treturn this;\n};\n\n/**\n * Blur this element.\n *\n * @chainable\n */\nOO.ui.mixin.TabIndexedElement.prototype.blur = function () {\n\tthis.$tabIndexed.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 accessibility.\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.onMouseUpHandler = this.onMouseUp.bind( this );\n\tthis.onMouseDownHandler = this.onMouseDown.bind( this );\n\tthis.onKeyDownHandler = this.onKeyDown.bind( this );\n\tthis.onKeyUpHandler = this.onKeyUp.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 */\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.onMouseUpHandler, 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 mouse up events.\n *\n * @protected\n * @param {MouseEvent} e Mouse up event\n */\nOO.ui.mixin.ButtonElement.prototype.onMouseUp = 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.onMouseUpHandler, true );\n};\n\n/**\n * Handles mouse click events.\n *\n * @protected\n * @param {jQuery.Event} e Mouse click event\n * @fires click\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.onKeyUpHandler, true );\n};\n\n/**\n * Handles key up events.\n *\n * @protected\n * @param {KeyboardEvent} e Key up event\n */\nOO.ui.mixin.ButtonElement.prototype.onKeyUp = 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.onKeyUpHandler, true );\n};\n\n/**\n * Handles key press events.\n *\n * @protected\n * @param {jQuery.Event} e Key press event\n * @fires click\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 */\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 */\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 */\nOO.ui.mixin.GroupElement.prototype.addItems = function ( items, index ) {\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 */\nOO.ui.mixin.GroupElement.prototype.removeItems = function ( items ) {\n\tvar i, len, item, index;\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 */\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 * 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// 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-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 */\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\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 */\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\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// 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-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 */\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\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 */\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\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 * 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 */\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\n\t// Initialization\n\tthis.setLabel( config.label || this.constructor.static.label );\n\tthis.setLabelElement( config.$label || $( '<span>' ) );\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 */\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 jQuery ) && 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 );\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 */\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 jQuery ) {\n\t\tthis.$label.empty().append( label );\n\t} else {\n\t\tthis.$label.empty();\n\t}\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 *     var button2 = new OO.ui.ButtonWidget( {\n *         label: 'Destructive',\n *         flags: 'destructive'\n *     } );\n *     $( '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} ).join( ' ' );\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 * @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.join( ' ' ) );\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 * @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.join( ' ' ) )\n\t\t\t.removeClass( remove.join( ' ' ) );\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 *     $( '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 */\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 */\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` 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 *     $( '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 'accesskeyes' 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 */\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 *         iconTitle: 'Remove'\n *     } );\n *     $( '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 */\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 */\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 */\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 */\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 *     // Example: 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 *     var button2 = new OO.ui.ButtonWidget( {\n *         label: 'Add item'\n *     });\n *     var buttonGroup = new OO.ui.ButtonGroupWidget( {\n *         items: [button1, button2]\n *     } );\n *     $( 'body' ).append( buttonGroup.$element );\n *\n * @class\n * @extends OO.ui.Widget\n * @mixins OO.ui.mixin.GroupElement\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\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 );\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 */\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 icon widget with a label\n *     var myIcon = new OO.ui.IconWidget( {\n *         icon: 'help',\n *         iconTitle: 'Help'\n *      } );\n *      // Create a label.\n *      var iconLabel = new OO.ui.LabelWidget( {\n *          label: 'Help'\n *      } );\n *      $( '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.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.FlaggedElement.call( this, $.extend( {}, config, { $flagged: this.$element } ) );\n\n\t// Initialization\n\tthis.$element.addClass( 'oo-ui-iconWidget' );\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.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 *     // Example of an indicator widget\n *     var indicator1 = new OO.ui.IndicatorWidget( {\n *         indicator: 'required'\n *     } );\n *\n *     // Create a fieldset layout to add a label\n *     var fieldset = new OO.ui.FieldsetLayout();\n *     fieldset.addItems( [\n *         new OO.ui.FieldLayout( indicator1, { label: 'A required indicator:' } )\n *     ] );\n *     $( '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 *\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\n\t// Initialization\n\tthis.$element.addClass( 'oo-ui-indicatorWidget' );\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 );\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 *     // Examples of LabelWidgets\n *     var label1 = new OO.ui.LabelWidget( {\n *         label: 'plaintext label'\n *     } );\n *     var label2 = new OO.ui.LabelWidget( {\n *         label: $( '<a href=\"default.html\">jQuery label</a>' )\n *     } );\n *     // Create a fieldset layout with fields for each example\n *     var fieldset = new OO.ui.FieldsetLayout();\n *     fieldset.addItems( [\n *         new OO.ui.FieldLayout( label1 ),\n *         new OO.ui.FieldLayout( label2 )\n *     ] );\n *     $( '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( { $: this.$, 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 *     $( '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 */\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 */\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, algining 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 */\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\tthis.needsCustomPosition =\n\t\t\tthis.verticalPostion !== 'below' ||\n\t\t\tthis.horizontalPosition !== 'start' ||\n\t\t\t!OO.ui.contains( this.$floatableContainer[ 0 ], this.$floatable[ 0 ] );\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 */\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\tif ( !this.needsCustomPosition ) {\n\t\treturn this;\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 */\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 */\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\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\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] [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 popup widget.\n *     var popup = new OO.ui.PopupWidget( {\n *         $content: $( '<p>Hi there!</p>' ),\n *         padded: true,\n *         width: 300\n *     } );\n *\n *     $( '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} [width=320] Width of popup in pixels\n * @cfg {number} [height] Height of popup in pixels. Omit to use the 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.$autoCloseIgnore = config.$autoCloseIgnore;\n\tthis.transitionTimeout = null;\n\tthis.anchored = false;\n\tthis.width = config.width !== undefined ? config.width : 320;\n\tthis.height = config.height !== undefined ? config.height : null;\n\tthis.onMouseDownHandler = this.onMouseDown.bind( this );\n\tthis.onDocumentKeyDownHandler = this.onDocumentKeyDown.bind( this );\n\n\t// Initialization\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.$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 jQuery ) {\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 mouse down events.\n *\n * @private\n * @param {MouseEvent} e Mouse down event\n */\nOO.ui.PopupWidget.prototype.onMouseDown = 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 mouse down listener.\n *\n * @private\n */\nOO.ui.PopupWidget.prototype.bindMouseDownListener = function () {\n\t// Capture clicks outside popup\n\tthis.getElementWindow().addEventListener( 'mousedown', this.onMouseDownHandler, 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 mouse down listener.\n *\n * @private\n */\nOO.ui.PopupWidget.prototype.unbindMouseDownListener = function () {\n\tthis.getElementWindow().removeEventListener( 'mousedown', this.onMouseDownHandler, true );\n};\n\n/**\n * Handles 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 key down listener.\n *\n * @private\n */\nOO.ui.PopupWidget.prototype.bindKeyDownListener = function () {\n\tthis.getElementWindow().addEventListener( 'keydown', this.onDocumentKeyDownHandler, true );\n};\n\n/**\n * Unbind key down listener.\n *\n * @private\n */\nOO.ui.PopupWidget.prototype.unbindKeyDownListener = function () {\n\tthis.getElementWindow().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 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.bindMouseDownListener();\n\t\t\t\tthis.bindKeyDownListener();\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.unbindMouseDownListener();\n\t\t\t\tthis.unbindKeyDownListener();\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} width Width in pixels\n * @param {number} height Height in pixels\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;\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,\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;\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 * 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 *     // Example of a popup button.\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 *     $( '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\t\t.attr( 'aria-haspopup', 'true' );\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 */\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 */\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 *\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\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 );\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 */\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 */\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 */\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 *     // Example of 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 *     $( '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.onMouseUpHandler = this.onMouseUp.bind( this );\n\tthis.onMouseMoveHandler = this.onMouseMove.bind( this );\n\tthis.onKeyDownHandler = this.onKeyDown.bind( this );\n\tthis.onKeyPressHandler = this.onKeyPress.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.focus();\n\t}\n};\n\n/**\n * Handle mouse down events.\n *\n * @private\n * @param {jQuery.Event} e Mouse down event\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.onMouseUpHandler, true );\n\t\t\tthis.getElementDocument().addEventListener( 'mousemove', this.onMouseMoveHandler, true );\n\t\t}\n\t}\n\treturn false;\n};\n\n/**\n * Handle mouse up events.\n *\n * @private\n * @param {MouseEvent} e Mouse up event\n */\nOO.ui.SelectWidget.prototype.onMouseUp = 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.onMouseUpHandler, true );\n\tthis.getElementDocument().removeEventListener( 'mousemove', this.onMouseMoveHandler, true );\n\n\treturn false;\n};\n\n/**\n * Handle mouse move events.\n *\n * @private\n * @param {MouseEvent} e Mouse move event\n */\nOO.ui.SelectWidget.prototype.onMouseMove = 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 */\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 */\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 key down events.\n *\n * @protected\n * @param {KeyboardEvent} e Key down event\n */\nOO.ui.SelectWidget.prototype.onKeyDown = 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.unbindKeyDownListener();\n\t\t\t\tthis.unbindKeyPressListener();\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 key down listener.\n *\n * @protected\n */\nOO.ui.SelectWidget.prototype.bindKeyDownListener = function () {\n\tthis.getElementWindow().addEventListener( 'keydown', this.onKeyDownHandler, true );\n};\n\n/**\n * Unbind key down listener.\n *\n * @protected\n */\nOO.ui.SelectWidget.prototype.unbindKeyDownListener = function () {\n\tthis.getElementWindow().removeEventListener( 'keydown', this.onKeyDownHandler, 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 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 */\nOO.ui.SelectWidget.prototype.onKeyPress = 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\tif ( String.fromCodePoint ) {\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} 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\tif ( s.normalize ) {\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\tif ( matchText.normalize ) {\n\t\t\tmatchText = matchText.normalize();\n\t\t}\n\t\treturn re.test( matchText );\n\t};\n};\n\n/**\n * Bind key press listener.\n *\n * @protected\n */\nOO.ui.SelectWidget.prototype.bindKeyPressListener = function () {\n\tthis.getElementWindow().addEventListener( 'keypress', this.onKeyPressHandler, true );\n};\n\n/**\n * Unbind 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.unbindKeyPressListener = function () {\n\tthis.getElementWindow().removeEventListener( 'keypress', this.onKeyPressHandler, 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 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 */\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 */\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 */\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 */\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 */\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 */\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 */\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 */\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 */\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 * Currently this is just used to set `aria-activedescendant` 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 *     $( '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 myDropdown = 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 *     $( 'body' ).append( myDropdown.$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.CapsuleMultiselectWidget CapsuleMultiselectWidget}\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 * @cfg {number} [width] Width of the menu\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// 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};\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/* 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.onKeyDown = 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.onKeyDown.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.onKeyDown.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, visible, section, sectionEmpty, filter, exactFilter,\n\t\tfirstItemFound = false,\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\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\tif ( this.highlightOnFilter && visible && !firstItemFound ) {\n\t\t\t\t\t// Highlight the first item in the list\n\t\t\t\t\tthis.highlightItem( item );\n\t\t\t\t\tfirstItemFound = true;\n\t\t\t\t}\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\tthis.$element.toggleClass( 'oo-ui-menuSelectWidget-invisible', !anyVisible );\n\t}\n\n\t// Reevaluate clipping\n\tthis.clip();\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.MenuSelectWidget.prototype.bindKeyDownListener = function () {\n\tif ( this.$input ) {\n\t\tthis.$input.on( 'keydown', this.onKeyDownHandler );\n\t} else {\n\t\tOO.ui.MenuSelectWidget.parent.prototype.bindKeyDownListener.call( this );\n\t}\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.MenuSelectWidget.prototype.unbindKeyDownListener = function () {\n\tif ( this.$input ) {\n\t\tthis.$input.off( 'keydown', this.onKeyDownHandler );\n\t} else {\n\t\tOO.ui.MenuSelectWidget.parent.prototype.unbindKeyDownListener.call( this );\n\t}\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.MenuSelectWidget.prototype.bindKeyPressListener = 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.bindKeyPressListener.call( this );\n\t}\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.MenuSelectWidget.prototype.unbindKeyPressListener = 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.unbindKeyPressListener.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 */\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, belowHeight, aboveHeight;\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 ) {\n\t\tif ( visible && ( this.width || this.$floatableContainer ) ) {\n\t\t\tthis.setIdealSize( this.width || this.$floatableContainer.width() );\n\t\t}\n\t\tif ( visible ) {\n\t\t\t// Reset position before showing the popup again. It's possible we no longer need to flip\n\t\t\t// (e.g. if the user scrolled).\n\t\t\tthis.setVerticalPosition( 'below' );\n\t\t}\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\t\t\tthis.togglePositioning( !!this.$floatableContainer );\n\t\t\tthis.toggleClipping( true );\n\n\t\t\tthis.bindKeyDownListener();\n\t\t\tthis.bindKeyPressListener();\n\n\t\t\tif ( this.isClippedVertically() || this.isFloatableOutOfView() ) {\n\t\t\t\t// If opening the menu downwards causes it to be clipped, flip it to open upwards instead\n\t\t\t\tbelowHeight = this.$element.height();\n\t\t\t\tthis.setVerticalPosition( 'above' );\n\t\t\t\tif ( this.isClippedVertically() || this.isFloatableOutOfView() ) {\n\t\t\t\t\t// If opening upwards also causes it to be clipped, flip it to open in whichever direction\n\t\t\t\t\t// we have more space\n\t\t\t\t\taboveHeight = this.$element.height();\n\t\t\t\t\tif ( aboveHeight < belowHeight ) {\n\t\t\t\t\t\tthis.setVerticalPosition( 'below' );\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.unbindKeyDownListener();\n\t\t\tthis.unbindKeyPressListener();\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 *     // Example: 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 *     $( '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 = $( '<span>' );\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.onKeyPressHandler,\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\trole: 'combobox',\n\t\t\t'aria-owns': this.menu.getElementId(),\n\t\t\t'aria-autocomplete': 'list'\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 jQuery ) {\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\tthis.$handle.attr(\n\t\t'aria-expanded',\n\t\tthis.$element.hasClass( 'oo-ui-dropdownWidget-open' ).toString()\n\t);\n};\n\n/**\n * Handle mouse click events.\n *\n * @private\n * @param {jQuery.Event} e Mouse click event\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 */\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 *\n *     var option2 = new OO.ui.RadioOptionWidget( {\n *         data: 'b',\n *         label: 'Unselected radio option'\n *     } );\n *\n *     var 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 *     $( '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.bindKeyDownListener.bind( this ),\n\t\tblur: this.unbindKeyDownListener.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_Multioptions\n *\n * @class\n * @extends OO.ui.Widget\n * @mixins OO.ui.mixin.ItemWidget\n * @mixins OO.ui.mixin.LabelElement\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\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 );\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 */\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 *\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\n\t// Events\n\tthis.aggregate( { change: 'select' } );\n\t// This is mostly for compatibility with CapsuleMultiselectWidget... 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 );\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 */\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 */\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 *\n *     var option2 = new OO.ui.CheckboxMultioptionWidget( {\n *         data: 'b',\n *         label: 'Unselected checkbox'\n *     } );\n *\n *     var multiselect=new OO.ui.CheckboxMultiselectWidget( {\n *         items: [ option1, option2 ]\n *      } );\n *\n *     $( '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 */\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, {label: 'Determinate', align: 'top'}),\n *        new OO.ui.FieldLayout( progressBar2, {label: 'Indeterminate', align: 'top'})\n *     ] );\n *     $( '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 */\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 */\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 */\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 'hidden'-type 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 *     $( '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.TitledElement\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\tOO.ui.mixin.TitledElement.call( this, $.extend( {}, config, { $titled: this.$input } ) );\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.TitledElement );\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 */\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 */\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 *     var checkbox2=new OO.ui.CheckboxInputWidget( {\n *         value: 'b'\n *     } );\n *     var checkbox3=new OO.ui.CheckboxInputWidget( {\n *         value:'c',\n *         disabled: true\n *     } );\n *     // Create a fieldset layout with fields for each checkbox.\n *     var 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 *     $( '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 */\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.$input.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 the same configuration options.\n *\n *     @example\n *     // Example: A DropdownInputWidget with three options\n *     var dropdownInput = new OO.ui.DropdownInputWidget( {\n *         options: [\n *             { data: 'a', label: 'First' },\n *             { data: 'b', label: 'Second'},\n *             { data: 'c', label: 'Third' }\n *         ]\n *     } );\n *     $( '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 `{ data: …, label: … }`\n * @cfg {Object} [dropdown] Configuration options for {@link OO.ui.DropdownWidget DropdownWidget}\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( config.dropdown );\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};\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 */\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 * intialized yet.\n *\n * @param {Object[]} options Array of menu options in the format `{ data: …, label: … }`\n * @private\n */\nOO.ui.DropdownInputWidget.prototype.setOptionsData = function ( options ) {\n\tvar\n\t\toptionWidgets,\n\t\twidget = this;\n\n\tthis.optionsDirty = true;\n\n\toptionWidgets = options.map( function ( opt ) {\n\t\tvar optValue;\n\n\t\tif ( opt.optgroup !== undefined ) {\n\t\t\treturn widget.createMenuSectionOptionWidget( opt.optgroup );\n\t\t}\n\n\t\toptValue = widget.cleanUpValue( opt.data );\n\t\treturn widget.createMenuOptionWidget(\n\t\t\toptValue,\n\t\t\topt.label !== undefined ? opt.label : optValue\n\t\t);\n\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\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 *     $( '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 */\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.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 the same configuration options.\n *\n *     @example\n *     // Example: 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 *     $( '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 */\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 *     // Example: 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 *     $( '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 */\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 *     // Example of a text input widget\n *     var textInput = new OO.ui.TextInputWidget( {\n *         value: 'Text input'\n *     } )\n *     $( '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\tif ( config.multiline ) {\n\t\tOO.ui.warnDeprecation( 'TextInputWidget: config.multiline is deprecated. Use the MultilineTextInputWidget instead. See T130434.' );\n\t\treturn new OO.ui.MultilineTextInputWidget( config );\n\t}\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.styleHeight = 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 */\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 */\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 */\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 */\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 */\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 */\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 */\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 */\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 */\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 */\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 && $.isFunction( result.promise ) ) {\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 */\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 */\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 */\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 * @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 * @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\tconfig.multiline = false;\n\t// Parent constructor\n\tOO.ui.MultilineTextInputWidget.parent.call( this, config );\n\n\t// Properties\n\tthis.multiline = true;\n\tthis.autosize = !!config.autosize;\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.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 ( this.multiline && 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 * @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 supports multiple lines.\n *\n * @return {boolean}\n */\nOO.ui.MultilineTextInputWidget.prototype.isMultiline = function () {\n\treturn !!this.multiline;\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 *     // Example: 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 *     $( '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 *     $( '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\tindicator: 'down',\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\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 * @inheritdoc\n */\nOO.ui.ComboBoxInputWidget.prototype.setDisabled = function ( disabled ) {\n\t// Parent method\n\tOO.ui.ComboBoxInputWidget.parent.prototype.setDisabled.call( this, disabled );\n\n\tif ( this.dropdownButton ) {\n\t\tthis.dropdownButton.setDisabled( this.isDisabled() );\n\t}\n\tif ( this.menu ) {\n\t\tthis.menu.setDisabled( this.isDisabled() );\n\t}\n\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 */\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 is accessed via a help icon that appears in the upper right corner of the rendered field layout.\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' or 'inline'\n * @cfg {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 * @cfg {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 * @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 *\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' }, 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\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-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} );\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// Events\n\tthis.fieldWidget.connect( this, { disable: 'onFieldDisable' } );\n\n\t// Initialization\n\tif ( config.help ) {\n\t\t// Set the 'aria-describedby' attribute on the fieldWidget\n\t\t// Preference given to an input or a button\n\t\t(\n\t\t\tthis.fieldWidget.$input ||\n\t\t\tthis.fieldWidget.$button ||\n\t\t\tthis.fieldWidget.$element\n\t\t).attr(\n\t\t\t'aria-describedby',\n\t\t\tthis.popupButtonWidget.getPopup().getBodyId()\n\t\t);\n\t}\n\tif ( this.fieldWidget.getInputId() ) {\n\t\tthis.$label.attr( 'for', this.fieldWidget.getInputId() );\n\t} else {\n\t\tthis.$label.on( 'click', function () {\n\t\t\tthis.fieldWidget.simulateLabelClick();\n\t\t}.bind( this ) );\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 */\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\t\tif ( value === 'top' ) {\n\t\t\tthis.$header.append( this.$help, this.$label );\n\t\t\tthis.$body.append( this.$header, this.$field );\n\t\t} else if ( value === 'inline' ) {\n\t\t\tthis.$header.append( this.$help, this.$label );\n\t\t\tthis.$body.append( this.$field, this.$header );\n\t\t} else {\n\t\t\tthis.$header.append( this.$label );\n\t\t\tthis.$body.append( this.$header, this.$help, this.$field );\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 */\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 */\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 * 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 *     $( '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 *     $( '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} );\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 *     $( '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 */\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 *     $( '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 *     $( '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 *     // Example: A NumberInputWidget.\n *     var numberInput = new OO.ui.NumberInputWidget( {\n *         label: 'NumberInputWidget',\n *         input: { value: 5 },\n *         min: 1,\n *         max: 10\n *     } );\n *     $( '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 {@link OO.ui.ButtonWidget decrementing button widget}.\n * @cfg {Object} [plusButton] Configuration options to pass to the {@link OO.ui.ButtonWidget incrementing button widget}.\n * @cfg {boolean} [allowInteger=false] Whether the field accepts only integer values.\n * @cfg {number} [min=-Infinity] Minimum allowed value\n * @cfg {number} [max=Infinity] Maximum allowed value\n * @cfg {number} [step=1] Delta when using the buttons or up/down arrow keys\n * @cfg {number|null} [pageStep] Delta when using the page-up/page-down keys. Defaults to 10 times #step.\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\tallowInteger: false,\n\t\tmin: -Infinity,\n\t\tmax: Infinity,\n\t\tstep: 1,\n\t\tpageStep: null,\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\tthis.setAllowInteger( config.allowInteger || config.isInteger );\n\tthis.setRange( config.min, config.max );\n\tthis.setStep( config.step, config.pageStep );\n\t// Set the validation method after we set allowInteger 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/**\n * Set whether only integers are allowed\n *\n * @param {boolean} flag\n */\nOO.ui.NumberInputWidget.prototype.setAllowInteger = function ( flag ) {\n\tthis.allowInteger = !!flag;\n\tthis.setValidityFlag();\n};\n// Backward compatibility\nOO.ui.NumberInputWidget.prototype.setIsInteger = OO.ui.NumberInputWidget.prototype.setAllowInteger;\n\n/**\n * Get whether only integers are allowed\n *\n * @return {boolean} Flag value\n */\nOO.ui.NumberInputWidget.prototype.getAllowInteger = function () {\n\treturn this.allowInteger;\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} step Normal step\n * @param {number|null} pageStep Page step. If null, 10 * step will be used.\n */\nOO.ui.NumberInputWidget.prototype.setStep = function ( step, pageStep ) {\n\tif ( step <= 0 ) {\n\t\tthrow new Error( 'Step value must be positive' );\n\t}\n\tif ( pageStep === null ) {\n\t\tpageStep = step * 10;\n\t} else if ( pageStep <= 0 ) {\n\t\tthrow new Error( 'Page step value must be positive' );\n\t}\n\tthis.step = step;\n\tthis.pageStep = pageStep;\n\tthis.$input.attr( 'step', this.step );\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[]} Step and page step\n */\nOO.ui.NumberInputWidget.prototype.getStep = function () {\n\treturn [ this.step, this.pageStep ];\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.allowInteger ) {\n\t\t\tn = Math.round( n );\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.allowInteger && Math.floor( n ) !== n ) {\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.step );\n};\n\n/**\n * Handle mouse wheel events.\n *\n * @private\n * @param {jQuery.Event} event\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.step );\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 */\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.step );\n\t\t\t\treturn false;\n\t\t\tcase OO.ui.Keys.DOWN:\n\t\t\t\tthis.adjustValue( -this.step );\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
diff --git a/resources/lib/oojs-ui/oojs-ui-core.js.map.json b/resources/lib/oojs-ui/oojs-ui-core.js.map.json
new file mode 100644 (file)
index 0000000..540b2ef
--- /dev/null
@@ -0,0 +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/IconElement.js","../src/mixins/IndicatorElement.js","../src/mixins/LabelElement.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":";;;;;;;;;;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,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC;AACnE,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG;AACX;AACA,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC;AACrB;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC;AACrB,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACd,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AACd,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AACd,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;AACZ,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;AACV,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;AACX,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;AACR,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;AACV,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;AACX,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;AACT,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;AACV,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AACR,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;AACZ,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC;AACd,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;AACZ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;AACX,CAAC,KAAK,CAAC,CAAC,EAAE;AACV,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK;AACjC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC;AACrB,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;AACtB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACT,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACX,CAAC,KAAK,CAAC,CAAC,CAAC;AACT,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC;AACrB,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;AACpB;AACA,GAAG;AACH,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO;AACnC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE;AACtB,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACvC,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,GAAG;AACnB,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC;AAClC,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,SAAS,CAAC;AACpC,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE;AAC1D,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI;AAC3C,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,SAAS;AACzC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,kBAAkB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AAClD,CAAC,GAAG,CAAC,QAAQ,CAAC;AACd,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE;AAC1B;AACA,CAAC,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS;AACtC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AAC1B,EAAE,MAAM,CAAC,KAAK,CAAC;AACf,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO;AACnC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE;AACR,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;AAC3D,EAAE,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE;AACtC,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO;AACvC,EAAE,EAAE,OAAO,CAAC,OAAO,GAAG,OAAO,GAAG,MAAM,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACrD,GAAG,MAAM,CAAC,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE;AACnD,EAAE,CAAC,CAAC,EAAE,MAAM;AACZ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACN,EAAE,MAAM,CAAC,KAAK,CAAC;AACf,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC;AACvE,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AAC5C,EAAE,MAAM,CAAC,IAAI,CAAC;AACd,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,SAAS,CAAC;AAC/D,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI;AACnC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC1C,EAAE,MAAM,CAAC,IAAI,CAAC;AACd,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,SAAS;AAC9C,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG;AAC9D,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC;AAC3D,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,WAAW,GAAG;AAC3C,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC1F,EAAE,MAAM,CAAC,IAAI,CAAC;AACd,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI;AACtD,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AAC9F,EAAE,MAAM,CAAC,IAAI,CAAC;AACd,CAAC,CAAC;AACF;AACA,CAAC,MAAM,CAAC,KAAK,CAAC;AACd,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK;AACzB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE;AACpD,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,SAAS;AAChD,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK;AAC5E,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AAC1D,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE;AAC1B,EAAE,EAAE,CAAC,CAAC,mBAAmB,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI;AACtD,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,kBAAkB;AAC5C,EAAE,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,SAAS;AACnC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,eAAe,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,EAAE;AAC9F;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AACnB,EAAE,CAAC,mBAAmB,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,mBAAmB,CAAC,EAAE;AAC9E,CAAC,CAAC;AACF;AACA,CAAC,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACzC,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE;AACxB,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,kBAAkB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC5C,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACtB,GAAG,MAAM,CAAC,KAAK,CAAC;AAChB,EAAE,CAAC;AACH,CAAC,CAAC,CAAC,EAAE;AACL,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC;AACnB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC;AACtD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC;AAC5F,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,UAAU,CAAC,EAAE;AAC5F,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC;AACvF,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ;AACrE,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACtC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE;AACjB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC;AACnD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI;AACnE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ;AAC9F,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK;AACtF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,KAAK;AAC9B,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AACxD,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC;AACnB;AACA,CAAC,EAAE,CAAC,SAAS,CAAC,QAAQ;AACtB,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACrB,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE;AACrB,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ;AACvB,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,GAAG;AAClC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAClD,EAAE,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE;AACpB,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACtB,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE;AACtB,EAAE,CAAC;AACH,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,QAAQ,CAAC,QAAQ;AACrB,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACzB,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,EAAE;AACzB,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ;AAC3B,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AACtB,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE;AACrB,CAAC,CAAC;AACF;AACA,CAAC,MAAM,CAAC,SAAS,CAAC;AAClB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI;AACnD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,QAAQ;AACzE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI;AAC/E,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC,WAAW,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE;AAC/E,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI;AAC9C,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW;AAC9H,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK;AAC5D,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,SAAS,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;AACtE,CAAC,GAAG,CAAC,CAAC,CAAC;AACP,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACtC,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE;AAC9B,CAAC,CAAC;AACF,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AACjD,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC3G,GAAG,MAAM,CAAC,IAAI,CAAC;AACf,EAAE,CAAC;AACH,CAAC,CAAC;AACF,CAAC,MAAM,CAAC,KAAK,CAAC;AACd,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG;AAC3E,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG;AAC5E,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG;AACxE,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC;AACzC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,GAAG,YAAY,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE;AACrD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,QAAQ;AAC9C,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,YAAY;AACvD,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI;AACvD,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,QAAQ;AACxC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AACrD,CAAC,GAAG,CAAC,OAAO,CAAC;AACb,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACrB,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;AACrB,GAAG,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;AACpB,GAAG,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACxB,IAAI,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;AACnB,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AACvB,KAAK,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE;AACjC,IAAI,CAAC;AACL,GAAG,EAAE;AACL,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AAChC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE;AAC/B,EAAE,CAAC;AACH,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAC3B,GAAG,YAAY,CAAC,CAAC,OAAO,CAAC,EAAE;AAC3B,GAAG,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,EAAE;AACvC,EAAE,CAAC;AACH,CAAC,EAAE;AACH,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;AAChD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,OAAO;AAClC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AAC9C,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AAC/D,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO;AACxC,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,EAAE;AAC1B,CAAC,CAAC;AACF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI;AAC9E,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,IAAI;AAC7E,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC;AAC5D,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG;AAC5E,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ;AAC3E,CAAC,CAAC,CAAC,SAAS,CAAC;AACb,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,QAAQ;AAC9C,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,YAAY;AAC/D,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,QAAQ;AACxC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAC1C,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC;AAC5B,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;AACf,EAAE,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACrB,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;AAClB,GAAG,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,GAAG;AAC1B,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE;AAC/B,EAAE,EAAE;AACJ,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACrB,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG;AAClE,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,QAAQ;AACtE,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AACtE,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE;AACjE,EAAE,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;AAClE,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE;AACpD,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;AACjB,EAAE,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;AACnB,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACzB,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE;AAChE,GAAG,EAAE,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;AACnE,GAAG,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG;AACjE,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,UAAU,CAAC,QAAQ,EAAE;AACjE,GAAG,YAAY,CAAC,CAAC,OAAO,CAAC,EAAE;AAC3B,GAAG,GAAG,GAAG;AACT,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AAC1B,GAAG,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,EAAE;AAC1C,EAAE,CAAC;AACH,CAAC,EAAE;AACH,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO;AACrE,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK;AAC3E,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACrC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,GAAG,OAAO,GAAG;AAC7B,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE;AACxE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,cAAc,CAAC;AAC1B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,IAAI;AACxD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,QAAQ;AAC9C,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC;AAC7D,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO;AACjD,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC;AAC1B,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,aAAa,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC;AACzE,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAC9C,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,EAAE;AACxD,EAAE;AACF;AACA,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACf,CAAC,GAAG;AACJ,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG;AAC7D,EAAE,CAAC;AACH,EAAE,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ;AAC5F,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC;AACzB,EAAE,CAAC;AACH,EAAE,CAAC,CAAC,CAAC,OAAO;AACZ,EAAE,EAAE;AACJ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AACjB,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK;AACpE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;AACrD,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK;AAClE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE;AACjD,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI;AACzD,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE;AAC/C,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,KAAK;AAClF,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE;AAC9B,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK;AACnF,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,EAAE;AAClC,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK;AACrF,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC,CAAC,KAAK,EAAE;AACrC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI;AACzE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;AAC/B,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,MAAM;AACjE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE;AACrC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,MAAM;AACjE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;AACzC,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW;AAC/C,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,EAAE;AACtD,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM;AAClF,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE;AAC3C,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM;AAClG,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE;AAC3C,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ;AACxF,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE;AAC7C,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM;AAC7D,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE;AACnD,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS;AAC3E,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,EAAE;AACrE,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,QAAQ;AAC3E,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,EAAE;AACvD,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM;AACtD,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;AAC1D,CAAC,EAAE;AACH;AACA,CAAC,GAAG;AACJ,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC;AAC5B,EAAE,CAAC;AACH,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC;AACtG,EAAE,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC;AACnG,EAAE,CAAC,CAAC,WAAW,CAAC,eAAe,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE;AAClG,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC;AACrD,EAAE,CAAC;AACH,EAAE,CAAC,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,UAAU,CAAC,EAAE;AAC7F,EAAE,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,MAAM,CAAC,OAAO;AACnG,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC;AAC3G,EAAE,CAAC,CAAC,OAAO,CAAC;AACZ,EAAE,CAAC;AACH,EAAE,CAAC,KAAK,CAAC,OAAO;AAChB,EAAE,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;AAC5B,EAAE,CAAC,SAAS,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,GAAG;AAC/C,EAAE,CAAC,SAAS,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE;AACxD,EAAE,CAAC,SAAS,WAAW,CAAC,CAAC,CAAC,GAAG;AAC7B,EAAE,CAAC;AACH,EAAE,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAC/D,EAAE,CAAC,SAAS,WAAW,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE;AACjG,EAAE,CAAC,KAAK,CAAC;AACT,EAAE,CAAC;AACH,EAAE,CAAC,KAAK,EAAE,IAAI,GAAG,IAAI,CAAC,CAAC,WAAW,CAAC,EAAE,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC;AACvD,EAAE,CAAC,SAAS,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,oBAAoB,CAAC;AAC1F,EAAE,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE;AACvF,EAAE,CAAC,SAAS,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,OAAO;AAC1F,EAAE,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC;AACjC,EAAE,CAAC,SAAS,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC;AAC/B,EAAE,CAAC;AACH,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM;AAC7D,EAAE,CAAC,SAAS,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC;AAC9C,EAAE,CAAC,aAAa,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE;AACjE,EAAE,CAAC,aAAa,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC;AAC7B,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE;AAChB,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE;AAClD,EAAE,CAAC;AACH,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,IAAI;AAC/C,EAAE,CAAC,SAAS,EAAE,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE;AACnC,EAAE,CAAC,SAAS,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC;AAC9C,EAAE,CAAC,aAAa,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE;AACjE,EAAE,CAAC,aAAa,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC;AAC7B,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE;AAChB,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE;AAClD,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE;AACZ,EAAE,CAAC;AACH,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG;AACnC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,UAAU;AACjD,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,WAAW;AACnE,EAAE,EAAE;AACJ,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AAC/B,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,EAAE;AAChC,GAAG,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE;AACvD,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;AACtC,GAAG,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,YAAY;AAC7B,GAAG,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAClE,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE;AAC9B,IAAI,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AACrE,GAAG,CAAC,CAAC,EAAE;AACP,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;AACV,GAAG,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK;AAC7C,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI;AAC7B,EAAE,CAAC;AACH,EAAE,MAAM,CAAC,OAAO,CAAC;AACjB,CAAC,EAAE;AACH,GAAG,CAAC,EAAE;AACN;AACA,GAAG;AACH,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC;AAC3D,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC;AAChG,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG;AAClC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,UAAU;AAChD,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ;AAC9E,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC9B,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;AACtB,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACrB,EAAE,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE;AACxC,CAAC,EAAE;AACH,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC;AACrB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC;AAC7F,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI;AACjE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,OAAO;AACpC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AACrC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC7B,EAAE,MAAM,CAAC,GAAG,GAAG;AACf,CAAC,CAAC;AACF,CAAC,MAAM,CAAC,GAAG,CAAC;AACZ,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG;AACtB,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC;AACpB,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AACpC,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG;AAC/C,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC;AAC1B;AACA,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAChD,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC;AACxD,CAAC,CAAC;AACF;AACA,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC;AACtB,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,EAAE;AACnF,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE;AAC1F,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC;AACpD,CAAC,EAAE;AACH;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AACpB,EAAE,MAAM,CAAC,IAAI,CAAC;AACd,CAAC,CAAC;AACF;AACA,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AACnD,EAAE,EAAE,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,GAAG,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAChE,GAAG,MAAM,CAAC,IAAI,CAAC;AACf,EAAE,CAAC;AACH,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG;AACzB,CAAC,EAAE,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACvE,EAAE,MAAM,CAAC,IAAI,CAAC;AACd,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACtE,EAAE,MAAM,CAAC,IAAI,CAAC;AACd,CAAC,CAAC;AACF;AACA,CAAC,MAAM,CAAC,KAAK,CAAC;AACd,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC;AAC3C,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE;AAC7D,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG;AAC7D,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC;AACnC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI;AAC9D,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC;AACtD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM;AAC/C,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC9B,CAAC,MAAM,CAAC,KAAK,CAAC;AACd,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG;AACjG,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,KAAK;AACnG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC;AACjF,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,YAAY;AAClG,CAAC,CAAC,KAAK,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC;AAC/D,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,kBAAkB,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACxC,CAAC,MAAM,CAAC,CAAC;AACT,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;AACT,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;AACX,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;AACZ,EAAE,IAAI,CAAC,CAAC,CAAC;AACT,CAAC,EAAE;AACH,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE;AACnG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE;AAC/D,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI;AACxC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACvC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC;AAChC,EAAE,EAAE,CAAC,EAAE,EAAE,cAAc,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,EAAE;AAC1E,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,cAAc,CAAC,EAAE;AAC9C,CAAC,CAAC;AACF,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,EAAE,cAAc,CAAC;AAC9B,EAAE;;AC7iBF,GAAG;AACH,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC;AACnB,CAAC,EAAE;AACH;AACA,GAAG;AACH,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC;AAC7B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE;AACxE,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE;AAC3E,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW;AACxE,CAAC,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC;AAC7D,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG;;ACfjB,GAAG;AACH,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,QAAQ;AAC/F,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM;AAC5G,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC;AAClD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,QAAQ;AACZ,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO;AACjD,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK;AACvG,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC;AAC3G,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC;AACnB,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,oBAAoB,CAAC,UAAU;AACpF,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC;AACrE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM;AACtC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE;AAC/E,CAAC,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC;AAC9E,CAAC,CAAC,EAAE,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC;AACjE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE;AACrE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC;AACxF,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE;AAC7G,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC;AACxD,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAChD,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACtB,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC;AAC9B,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,aAAa,CAAC,cAAc;AAChC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG;AACvB;AACA,CAAC,EAAE,CAAC,UAAU;AACd,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE;AACZ,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC;AACvB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;AACrB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC;AACzB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE;AACnC,EAAE,EAAE,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE;AACnD,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC;AAC1B;AACA,CAAC,EAAE,CAAC,cAAc;AAClB,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACzC,EAAE,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;AACvD,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AACnB,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE;AACjC,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACrB,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE;AACpC,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AACxB,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE;AAChE,EAAE,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK;AACpE,EAAE,EAAE,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC;AACnC,EAAE,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC5D,GAAG,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;AACjC,IAAI,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC,IAAI,CAAC;AAC3D,IAAI,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,EAAE;AACxC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;AACjD,IAAI,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC;AACvB,IAAI,MAAM,CAAC,CAAC,CAAC,QAAQ,GAAG;AACxB,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AAC7C,IAAI,MAAM,CAAC,CAAC,EAAE,OAAO,CAAC;AACtB,GAAG,CAAC;AACJ,GAAG,MAAM,CAAC,CAAC,CAAC;AACZ,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE;AACR,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;AACzB,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC;AAC1D,EAAE,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE;AAC1C,CAAC,CAAC;AACF,EAAE;AACF;AACA,EAAE,CAAC,KAAK,CAAC,EAAE;AACX;AACA,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE;AAC9B;AACA,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE;AACvB;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC;AAChD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC,UAAU,CAAC;AAC3E,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM;AACV,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC;AACrB,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE;AACrC;AACA,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE;AACpB;AACA,GAAG;AACH,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO;AACrE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,cAAc,CAAC;AAC7B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,QAAQ;AAC9C,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC;AAC7D,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO;AACjD,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC;AAC1B,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,aAAa,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC;AACzE,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC;AAC/E,CAAC,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ;AAC/E,CAAC,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAC7D,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,EAAE;AACxE,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;AACpC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC;AACvD,CAAC,EAAE;AACH,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC3C,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,EAAE;AAC/C,CAAC,CAAC;AACF,CAAC,EAAE;AACH,CAAC,MAAM,CAAC,GAAG,CAAC;AACZ,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,cAAc,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;AACtE,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC;AACxE,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,QAAQ;AAC9C,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO;AACjD,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ;AACvE,CAAC,CAAC,KAAK,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC;AACvE,CAAC,CAAC,KAAK,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC;AACzD,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC;AAC1B,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;AAC/E,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC;AACpD,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,eAAe,CAAC;AAClF,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;AACtC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC;AAChB,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE;AAC7C,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACT,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE;AACxB,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE;AAC1B,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACvB,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;AACvC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;AAC3C,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AAC/C,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC;AACpD,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;AACV,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE;AAC9B,EAAE,CAAC;AACH,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,EAAE;AAC3B,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC;AAChC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC;AACjC,CAAC,CAAC;AACF,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,EAAE;AACrC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACd,EAAE,EAAE,CAAC,MAAM,CAAC;AACZ,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACxB,GAAG,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE;AACnD,EAAE,CAAC;AACH,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;AACrB,GAAG,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC;AACpF,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AACvE,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM;AAC9F,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE;AACrE,GAAG,eAAe,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,EAAE;AAC3D,GAAG,EAAE,CAAC,CAAC,CAAC,eAAe,CAAC,EAAE,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACrD,IAAI,eAAe,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAChD,KAAK,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AAC7E,KAAK,UAAU,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE;AACvE,IAAI,CAAC,CAAC,EAAE;AACR,GAAG,CAAC;AACJ,EAAE,CAAC;AACH,EAAE,MAAM,CAAC,IAAI,CAAC;AACd,CAAC,CAAC;AACF,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE;AAClC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACf,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE;AACrD,CAAC,CAAC;AACF,CAAC,GAAG,CAAC,CAAC;AACN,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,EAAE;AAC5B,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAChB,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AACd,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC7B,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE;AAC3D,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AAC1B,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC;AACxE,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;AAC1E,CAAC,CAAC;AACF,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,EAAE;AAC7B,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE;AAC1D,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AAC3B,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;AAC7E,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,QAAQ;AACxD,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC;AACrB;AACA,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AACjC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AACnC,GAAG,EAAE,CAAC,IAAI;AACV,GAAG,KAAK,CAAC;AACT,EAAE,CAAC;AACH;AACA,EAAE,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC;AACzB,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AAClC,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;AAC7E,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;AACrB,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,QAAQ,GAAG;AACrB,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,GAAG;AAC7B,CAAC,CAAC;AACF,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK;AACrD,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,QAAQ;AAC1B,CAAC,eAAe,CAAC,CAAC,CAAC,GAAG;AACtB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAC5D,EAAE,GAAG,CAAC,OAAO,CAAC;AACd,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACpC,GAAG,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AACrB,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,UAAU,CAAC,EAAE;AACjF,IAAI,eAAe,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,EAAE;AACpC,IAAI,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS;AAC5B,IAAI,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,eAAe,CAAC,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE;AAC1G,IAAI,OAAO,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,EAAE;AAC3D,IAAI,MAAM,CAAC,OAAO,CAAC;AACnB,GAAG,CAAC;AACJ,GAAG,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AACpC,IAAI,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE;AAC/C,GAAG,CAAC;AACJ,EAAE,CAAC;AACH,CAAC,CAAC,CAAC,EAAE;AACL,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG;AAC3C,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE;AACzD,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC;AAClF,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE;AAC7D,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM;AAClB,CAAC,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG;AACpC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;AAC/C,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC;AAC5D,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC;AAC/E,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC;AAC/F,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,GAAG,EAAE,OAAO,CAAC;AACvC,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;AAC1C,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AACb,EAAE,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC;AACjG,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;AAC1C,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC3C,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,GAAG,EAAE,OAAO,CAAC,EAAE;AACrC,EAAE,CAAC;AACH,EAAE,GAAG,CAAC,OAAO,GAAG;AAChB,CAAC,CAAC;AACF,CAAC,GAAG,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,EAAE;AAC1C,CAAC,GAAG,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,eAAe,CAAC,EAAE;AAC/D,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO;AACpE,CAAC,GAAG,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE;AACtC,CAAC,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG;AACpE,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE;AACjE,CAAC,MAAM,CAAC,GAAG,CAAC;AACZ,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC;AACtE,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI;AAClG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG;AAC9F,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC;AACxD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC,CAAC,IAAI;AAC5B,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM;AACzB,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC;AACnB,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACpE,CAAC,MAAM,CAAC,MAAM,CAAC;AACf,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI;AACpG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,aAAa,CAAC;AAC9F,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,cAAc,CAAC;AACvC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI;AAC9F,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,qBAAqB,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,OAAO;AAC/F,CAAC,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE;AAC1C,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC,CAAC,IAAI;AAC5B,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM;AACzB,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC;AACnB,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACzD,CAAC,MAAM,CAAC,GAAG;AACX,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC;AACpD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM;AACV,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE;AAC1F,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE;AAChG,CAAC,CAAC,GAAG,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM;AACrB,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ;AAC3C,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAChE,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AAC/B,EAAE,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE;AACxC,CAAC,CAAC;AACF;AACA,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,EAAE;AAC/C;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACjB,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;AAC5B,CAAC,CAAC;AACF;AACA,CAAC,MAAM,CAAC,OAAO,CAAC;AAChB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC;AAClC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM;AACV,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG;AACrF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM;AAC9C,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AACrD,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ;AAC5F,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,aAAa,CAAC,CAAC,CAAC,EAAE;AACjD,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO;AACjD,EAAE,GAAG,CAAC,OAAO,CAAC,EAAE;AAChB,EAAE,EAAE,CAAC,WAAW;AAChB,EAAE,GAAG,CAAC,aAAa,CAAC,EAAE;AACtB,EAAE,EAAE,CAAC,MAAM;AACX,EAAE,GAAG,CAAC,QAAQ,CAAC,EAAE;AACjB,EAAE,EAAE,CAAC,YAAY;AACjB,EAAE,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE;AACnD,EAAE,IAAI,CAAC;AACP,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,QAAQ,CAAC;AAC5C,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM;AACV,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG;AACpF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,MAAM;AACjC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AACnD,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,EAAE;AACnC,CAAC,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC;AACxB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,QAAQ,CAAC;AAC/C,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM;AACV,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG;AACvF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC;AACzD,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AAChD,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC;AAClB;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAC/B,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE;AACjB,CAAC,CAAC;AACF,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC;AAC7C,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC;AACpC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACxB,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAChB,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC;AACtB,EAAE,CAAC;AACH,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC;AACjB,CAAC,CAAC;AACF,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE;AACpC,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC;AACrC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC;AAC9C,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM;AACV,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK;AACjD,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK;AACzD,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,UAAU;AACjE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,UAAU;AACrE,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACrE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC;AACjC;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AACb,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;AACd,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACjB,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE;AAC/B,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAC9B,EAAE,MAAM,CAAC,MAAM,CAAC;AAChB,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO;AACtB,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,oBAAoB,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE;AAChE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AACnD,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAC7C,GAAG,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE;AACvB,GAAG,KAAK,CAAC;AACT,EAAE,CAAC;AACH,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,WAAW,CAAC,UAAU,CAAC,MAAM,CAAC,MAAM;AACxC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACf,EAAE,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,qBAAqB,GAAG;AACvC,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC;AAC3B,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC;AACzB,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AACtB,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,EAAE;AAC9C,EAAE,CAAC;AACH,CAAC,CAAC;AACF,CAAC,MAAM,CAAC,MAAM,CAAC;AACf,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC;AACvC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI;AAC/F,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC;AAC3C,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM;AACV,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG;AACzD,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE;AACzE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU;AACvF,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAC3E,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC;AACvB,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,GAAG;AAC1B,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,GAAG;AAC/B,EAAE,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE;AACjD,EAAE,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE;AAC/C;AACA,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,EAAE;AAClE,CAAC,KAAK,CAAC,CAAC,CAAC,eAAe,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;AAC/C,EAAE,MAAM,CAAC,CAAC,CAAC,eAAe,CAAC,WAAW,CAAC,YAAY,CAAC;AACpD,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAClB,GAAG,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE;AACzE,EAAE,CAAC;AACH,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG;AACnC,EAAE,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC;AAC7B,EAAE,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC;AAC3B,EAAE,eAAe,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC;AACzC,CAAC,CAAC;AACF,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC;AAC5B,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC;AAC1B,CAAC,MAAM,CAAC,GAAG,CAAC;AACZ,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC;AAC5B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM;AACV,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO;AAC7C,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,UAAU;AACzF,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AACnD,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,aAAa,CAAC;AAC5B,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC;AACxB,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE;AAC3C,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE;AAChB,EAAE,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AACtF,EAAE,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AACzF,EAAE,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAC/F,EAAE,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAC5F;AACA,CAAC,MAAM,CAAC,CAAC;AACT,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC;AACX,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC;AACb,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC;AACjB,EAAE,KAAK,CAAC,CAAC,KAAK;AACd,CAAC,EAAE;AACH,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,CAAC;AAC1C,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM;AACV,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO;AACpD,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,UAAU;AACjG,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AACtD,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;AACf,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC;AACxC,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC;AACxB;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;AAClD,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE;AAClB,EAAE,MAAM,CAAC,CAAC;AACV,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE;AACrD,GAAG,MAAM,CAAC,CAAC,CAAC;AACZ,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,GAAG;AAC1B,IAAI,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,UAAU,EAAE;AAC3B,GAAG,EAAE;AACL,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE;AACtC,GAAG,IAAI,CAAC,CAAC,CAAC;AACV,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC;AACX,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC;AACZ,IAAI,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,WAAW,GAAG;AAC/B,IAAI,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,UAAU,EAAE;AAC5B,GAAG,CAAC;AACJ,EAAE,EAAE;AACJ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACT,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE;AAChB,EAAE,MAAM,CAAC,CAAC;AACV,GAAG,OAAO,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE;AAClC,GAAG,MAAM,CAAC,CAAC,CAAC;AACZ,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,GAAG;AACzB,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,EAAE;AAC1B,GAAG,EAAE;AACL,GAAG,SAAS,CAAC,CAAC,CAAC;AACf,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,WAAW,CAAC;AAC7C,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,YAAY;AAC/C,GAAG,EAAE;AACL,GAAG,IAAI,CAAC,CAAC,EAAE,CAAC,qBAAqB,EAAE;AACnC,EAAE,EAAE;AACJ,CAAC,CAAC;AACF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC;AAC9E,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE;AACnE,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC;AAC3E,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE;AACvF,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU;AACvF,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC;AACvD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM;AACV,CAAC,CAAC,CAAC,CAAC,MAAM;AACV,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO;AACpD,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC;AAClD,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC;AACtG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,EAAE;AAC9E,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC;AACtG,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,EAAE;AAC/E,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACpD,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC;AAC1B;AACA,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;AAClB,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE;AACpJ,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE;AAC3B;AACA,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE;AAC9B,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACjC,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC,MAAM;AACpB,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE;AAC7B,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;AACV,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;AAC1B,GAAG,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACpC,IAAI,EAAE,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,KAAK;AACzB,IAAI,aAAa,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;AAC/B,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC;AACX,IAAI,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,IAAI;AAC9B,IAAI,aAAa,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE;AAC9B,GAAG,CAAC;AACJ,EAAE,CAAC;AACH,EAAE,CAAC,OAAO,CAAC,MAAM,GAAG;AACpB,CAAC,CAAC;AACF;AACA,CAAC,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AACtC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;AAClC,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE;AACnC,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,aAAa,CAAC,eAAe,CAAC;AAC5C,GAAG,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC;AAClE,GAAG,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;AACjF,GAAG,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO;AACpD,GAAG,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE;AAC3D;AACA,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AAC9B,GAAG,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClC,IAAI,IAAI,GAAG;AACX,GAAG,CAAC;AACJ,GAAG,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;AACvC,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC;AAC7B,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;AAC9C,IAAI,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,WAAW,CAAC;AAC9D,GAAG,CAAC;AACJ,EAAE,CAAC;AACH;AACA,EAAE,MAAM,CAAC,UAAU,CAAC;AACpB,CAAC,EAAE;AACH,GAAG,CAAC,EAAE;AACN;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC;AAC/D,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG;AAChG,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK;AACjG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,eAAe,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC;AACpE,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM;AAC7D,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM;AACV,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG;AACrE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,WAAW,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,eAAe,CAAC;AACzF,CAAC,CAAC,KAAK,SAAS,CAAC,EAAE,CAAC,OAAO;AAC3B,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,wBAAwB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AACjE,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC;AACrB;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AAC/C,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC;AAC/B,EAAE,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC;AAC7B,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;AACrB;AACA,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE;AACjE,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;AAC9E,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC7C,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;AAC9B,GAAG,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;AACpC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;AACV,GAAG,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,eAAe,EAAE;AAC/C,EAAE,CAAC;AACH,CAAC,CAAC;AACF;AACA,CAAC,MAAM,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,EAAE;AACpD,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC;AACpC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI;AAChG,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,wBAAwB,EAAE;AACvE,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM;AACV,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,GAAG;AACnE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM;AAC9F,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,SAAS;AACrD,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,6BAA6B,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AACjF,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;AACZ,EAAE,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,GAAG;AAC5F,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC;AACrF,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE;AACzC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,GAAG;AAC7B;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAChD,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE;AACtC,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,KAAK;AACjG,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC;AAC/F,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACpC,EAAE,MAAM,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC,EAAE,CAAC,EAAE;AAC7C,CAAC,CAAC;AACF;AACA,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAC3B,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC/D,GAAG,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE;AACvB,EAAE,CAAC;AACH,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC;AACnB,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AACjB,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;AACnC,GAAG,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE;AAC9F,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG;AACjG,GAAG,EAAE,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM;AAC1F,GAAG,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC;AACjG,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG;AACtC,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;AAC9C,IAAI,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE;AACxB,GAAG,CAAC;AACJ,EAAE,CAAC;AACH,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,GAAG;AAC7B,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI;AAC7D,CAAC,MAAM,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC,EAAE,CAAC,EAAE;AAC5C,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;AAC5B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM;AACV,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI;AACtD,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO;AACjD,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,KAAK;AAC3E,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI;AACzF,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,UAAU;AAChC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,QAAQ;AAC9E,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAC/D,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,UAAU,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,iBAAiB,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,MAAM,CAAC;AAClG,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,GAAG;AAC1B;AACA,CAAC,EAAE,CAAC,aAAa,CAAC,cAAc;AAChC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG;AACvB;AACA,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG;AACjB,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE;AACxE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE;AAC7B,CAAC,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC,EAAE;AAC9C,CAAC,mBAAmB,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,SAAS,CAAC,EAAE;AACvD,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE;AACrC;AACA,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS;AAC5D,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACvC,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI;AAC1D,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC;AACd,GAAG,GAAG,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,GAAG,CAAC;AACnC,GAAG,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC;AACjE,GAAG,IAAI,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC;AACrC,GAAG,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,KAAK;AAC7D,EAAE,EAAE;AACJ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACT,EAAE,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW;AACjF,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC;AACd,GAAG,GAAG,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,mBAAmB,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;AACxG,GAAG,MAAM,CAAC,CAAC,mBAAmB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,mBAAmB,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,mBAAmB,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC;AACvJ,GAAG,IAAI,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,mBAAmB,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;AAC5G,GAAG,KAAK,CAAC,CAAC,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,mBAAmB,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,mBAAmB,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,KAAK;AACjJ,EAAE,EAAE;AACJ,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACvD,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC3B,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,mBAAmB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC;AACxE,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACzD,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,mBAAmB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE;AACtG,EAAE,CAAC;AACH,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACvD,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC5B,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,mBAAmB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC;AAC3E,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACzD,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,mBAAmB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE;AACxG,EAAE,CAAC;AACH,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,aAAa,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACxC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE;AAC1G,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACvC,GAAG,QAAQ,CAAC,OAAO,GAAG;AACtB,GAAG,IAAI,GAAG;AACV,EAAE,CAAC,CAAC,EAAE;AACN,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACT,EAAE,QAAQ,CAAC,OAAO,GAAG;AACrB,CAAC,CAAC;AACF,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,GAAG;AAC3B,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO;AAClG,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;AAC3D,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,IAAI;AAClG,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,IAAI;AAClG,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;AACpG,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;AACzC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM;AACV,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE;AAClE,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAC7D,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG;AAC/C,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ;AACxB,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC;AAC5B,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC;AAC1B,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ;AACvB,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;AAC1B,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,EAAE;AAC9B,EAAE,EAAE,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,EAAE;AAClC,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM;AAChB,CAAC,IAAI,CAAC,EAAE,CAAC,YAAY,CAAC;AACtB,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ;AACzB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAClD,EAAE,EAAE,CAAC,WAAW,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;AAC/B,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC;AAC7D,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC;AAC5B,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;AAC1B,EAAE;AACF;AACA,EAAE,CAAC,OAAO,CAAC,EAAE;AACb;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC;AACnC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,UAAU;AAC1E,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO;AACjB,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACpD,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC;AACpD;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC;AACnC,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;AACtB,EAAE,IAAI,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE;AACrE,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE;AAC9B,CAAC,CAAC;AACF;AACA,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC;AAC/B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO;AACvC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACjD,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC;AACrB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC;AACpB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,IAAI;AAC/B,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC/C,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;AAClB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC;AACpB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI;AACnC,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACrD,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AAClB,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC;AACzC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE;AACrB,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AACxD,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;AACrB,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE;AAChC,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;AAChG,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC;AACxB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC;AACnB,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACpD,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACjC,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,EAAE,CAAC,EAAE;AACjD,CAAC,CAAC;AACF,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC;AACvB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC;AACjD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK;AACtE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS;AAC9C,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AACzD,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;AACZ,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;AACd;AACA,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE;AAC5D,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AACpD,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC/C,GAAG,OAAO,GAAG;AACb,EAAE,CAAC;AACH,CAAC,CAAC;AACF;AACA,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC;AACnC,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC;AACrC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC;AACxF,CAAC,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,UAAU,CAAC,GAAG;AACnF,CAAC,CAAC,GAAG,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW;AACjF,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC1D,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC,IAAI,CAAC,EAAE;AAC/C,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC;AACzB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC;AACnE,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI;AACjC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAClD,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC;AACxC,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG;AAC9C,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG;AACvD,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACzD,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC,CAAC,IAAI,CAAC,kBAAkB,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;AACpE,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC;AACxB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC,QAAQ,CAAC,MAAM;AACzC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC1D,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO;AAC3F,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE;AAC1D,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC;AACtB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,MAAM;AACjC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACxD,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE;AACxD,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC;AACpC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,SAAS;AACrD,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,oCAAoC,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC5E,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,6BAA6B,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;AACjF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC;AAC3B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI;AACtE,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACvD,CAAC,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC;AAC1B,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC;AAC3B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI;AAC3E,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAC9D,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC;AAC3B,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;AAC5B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO;AACjD,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,QAAQ;AAC9E,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,qBAAqB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACrE,CAAC,EAAE,CAAC,CAAC;AACL,EAAE,CAAC,IAAI,CAAC,iBAAiB,EAAE,CAAC,EAAE;AAC9B,EAAE,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,EAAE;AACtB,EAAE,CAAC,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,eAAe,GAAG,SAAS,EAAE,CAAC,CAAC;AACnE,CAAC,CAAC,CAAC,CAAC;AACJ,EAAE,MAAM,CAAC,EAAE,QAAQ,GAAG,OAAO,GAAG;AAChC,CAAC,CAAC;AACF,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE;AAC1E,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC;AAC1D,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM;AAChG,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,oBAAoB,CAAC;AAClC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK;AACxB,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,qBAAqB,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC7D,EAAE;;ACt9BF,GAAG;AACH,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO;AACxE,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM;AACtE,CAAC,CAAC,CAAC,MAAM,CAAC;AACV,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,OAAO;AACzC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AACzD,CAAC,EAAE,CAAC,UAAU;AACd,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC;AACxB,EAAE;AACF;AACA,EAAE,CAAC,KAAK,CAAC,EAAE;AACX;AACA,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,EAAE;AAClC;AACA,EAAE,CAAC,OAAO,CAAC,EAAE;AACb;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;AACpB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC;AAC3C,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACpD,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC;AACrB,EAAE;;AC5BF,GAAG;AACH,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG;AACvG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC;AAC1G,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,cAAc,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,EAAE;AAC/H,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,EAAE;AACrH,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,gBAAgB,EAAE,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC;AACpI,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,QAAQ;AACZ,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO;AACzB,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,YAAY;AAC1B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO;AACjD,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAC9C,CAAC,EAAE,CAAC,aAAa,CAAC,cAAc;AAChC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG;AACvB;AACA,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AAC1C;AACA,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY;AACtB,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AAC9B;AACA,CAAC,EAAE,CAAC,cAAc;AAClB,CAAC,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE;AAC1C,EAAE;AACF;AACA,EAAE,CAAC,KAAK,CAAC,EAAE;AACX;AACA,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE;AAC/C,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,YAAY,CAAC,EAAE;;AChC/C,GAAG;AACH,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI;AACjF,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC;AACpF,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;AAC/D,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,QAAQ;AACZ,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO;AACzB,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,YAAY;AAC1B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO;AACjD,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK;AAChG,CAAC,CAAC,EAAE,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC;AACnC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAC9C,CAAC,EAAE,CAAC,UAAU,CAAC,MAAM;AACrB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE;AAClD;AACA,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AAC1C;AACA,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY;AACtB,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AAC9B;AACA,CAAC,EAAE,CAAC,UAAU;AACd,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC;AACtB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC;AACzB;AACA,CAAC,EAAE,CAAC,cAAc;AAClB,CAAC,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE;AAC1C,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC,EAAE;AACvC,EAAE;AACF;AACA,EAAE,CAAC,KAAK,CAAC,EAAE;AACX;AACA,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE;AAC/C,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,YAAY,CAAC,EAAE;AAC/C;AACA,EAAE,CAAC,MAAM,CAAC,EAAE;AACZ;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO;AACjB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO;AAC7E,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,GAAG,EAAE,CAAC,MAAM,EAAE;AACpC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,QAAQ;AAC/C,CAAC,EAAE;AACH;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM;AAChB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC;AACzE,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO;AAC7C,CAAC,EAAE;AACH;AACA,EAAE,CAAC,OAAO,CAAC,EAAE;AACb;AACA,GAAG;AACH,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC;AACnC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,QAAQ;AACvC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACjD,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC;AACtB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC;AAC1C,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC;AACpG,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM;AAC3C,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AAC5D,CAAC,GAAG,CAAC,UAAU,CAAC;AAChB;AACA,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC;AAC5B,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,GAAG;AAChC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;AACzC,EAAE,IAAI,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,UAAU,CAAC,EAAE;AACnE,EAAE,IAAI,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,UAAU,CAAC,EAAE;AACnE,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE,CAAC,EAAE;AAC/D,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,UAAU,CAAC,EAAE;AACrC,EAAE,IAAI,CAAC,kBAAkB,GAAG;AAC5B,CAAC,CAAC;AACF,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,UAAU,CAAC;AAC/B;AACA,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC;AAClE,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACrD,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE;AACnC,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,EAAE;AACnG,CAAC,CAAC,CAAC,KAAK,CAAC;AACT,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,kBAAkB,CAAC,MAAM;AAChG,CAAC,CAAC,CAAC,OAAO,CAAC;AACX,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO;AACxD,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACjD,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC;AAC/F,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE;AACpG,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC;AAClE,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,iBAAiB,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC;AACnG,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC;AAC1C,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM;AAC5F,CAAC,CAAC,CAAC,QAAQ,CAAC;AACZ,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACzD,EAAE;;ACjIF,GAAG;AACH,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC;AACf,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,QAAQ;AACZ,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,EAAE,CAAC,CAAC;AACpC,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC,GAAG;AAC/B,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,0BAA0B,CAAC,EAAE;AAC9F,EAAE;AACF;AACA,EAAE,CAAC,KAAK,CAAC,EAAE;AACX;AACA,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE;AAC5B;AACA,EAAE,CAAC,OAAO,CAAC,EAAE;AACb;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;AACnD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC;AACjG,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC;AACtD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO;AAClE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK;AACvF,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACvD,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE;AAC5B,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC;AAC5C,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC;AAC9F,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,OAAO;AACrE,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AACnE,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE;AACzB,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,OAAO,CAAC,EAAE;AAC9C;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;AACvB,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE;AAC7C,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;AAC5B,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,SAAS,CAAC,EAAE;AAClD,CAAC,CAAC;AACF;AACA,CAAC,CAAC,QAAQ;AACV,EAAE,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACzC,EAAE,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;AACtC,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,0BAA0B,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAChE,CAAC,GAAG,CAAC,CAAC,CAAC;AACP,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAC1D,EAAE,IAAI,CAAC,oBAAoB,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;AAC7D,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK;AACnB,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC,GAAG;AAC/B,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,oBAAoB,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC;AAC7D,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,yBAAyB,CAAC;AAC1F,CAAC,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC;AAC9B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,OAAO;AACrE,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,yBAAyB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AACxE,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AACjG,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE;AACvF,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAChE,EAAE,MAAM,CAAC;AACT,CAAC,CAAC;AACF,CAAC,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,EAAE;AAC1C,CAAC,IAAI,CAAC,mCAAmC,GAAG;AAC5C,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO;AAC1E,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,GAAG;AACvE,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC;AAC9B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC,YAAY;AACvD,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,2BAA2B,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACjE,CAAC,MAAM,CAAC,CAAC,CAAC;AACV,EAAE;;AC/FF,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,iBAAiB,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC,EAAE;AAC/F,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG;AAClG,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC;AACvF,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,CAAC,OAAO;AACf,CAAC,CAAC,KAAK,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,KAAK;AAChE,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC;AACzC,CAAC,CAAC,KAAK,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC;AAC9C,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE;AAC3B,CAAC,CAAC,SAAS,QAAQ,CAAC,CAAC,CAAC;AACtB,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACX,CAAC,CAAC,KAAK,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC;AAC9C,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE;AAC3B,CAAC,CAAC,SAAS,QAAQ,CAAC,CAAC,CAAC;AACtB,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACX,CAAC,CAAC,KAAK,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC;AAC9C,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,KAAK,EAAE;AAC1B,CAAC,CAAC,SAAS,QAAQ,CAAC,CAAC,CAAC;AACtB,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACX,CAAC,CAAC,KAAK,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC;AAC9C,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,KAAK,EAAE;AAC1B,CAAC,CAAC,SAAS,QAAQ,CAAC,CAAC,CAAC;AACtB,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACX,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE;AACpG,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,QAAQ;AACZ,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO;AACjD,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC;AAClG,CAAC,CAAC,EAAE,GAAG,CAAC,aAAa,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,QAAQ;AAClI,CAAC,CAAC,EAAE,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC;AAChD,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,UAAU;AAC5G,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;AACtG,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC;AACvD,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC,CAAC,QAAQ,CAAC,0BAA0B,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAC/E,CAAC,EAAE,CAAC,aAAa,CAAC,cAAc;AAChC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE;AAC9C;AACA,CAAC,EAAE,CAAC,UAAU;AACd,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC;AACzB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC;AACtB;AACA,CAAC,EAAE,CAAC,MAAM;AACV,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,0BAA0B,CAAC,CAAC,CAAC,CAAC,EAAE;AACjE;AACA,CAAC,EAAE,CAAC,cAAc;AAClB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE;AACrC,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC,MAAM,EAAE,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE;AAClE,EAAE;AACF;AACA,EAAE,CAAC,KAAK,CAAC,EAAE;AACX;AACA,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,iBAAiB,CAAC,EAAE;AAC9C;AACA,EAAE,CAAC,OAAO,CAAC,EAAE;AACb;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,aAAa,CAAC;AAC9D,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,OAAO;AACrF,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AAC5F,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC;AACtE,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,aAAa;AACjF,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,iBAAiB,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;AACzF,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC;AAC9B,CAAC,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,UAAU;AAC1C,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,EAAE;AAC1B,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,UAAU;AACnC,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC;AAChC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC;AAC1B,CAAC,MAAM,CAAC,IAAI,CAAC,cAAc,GAAG;AAC9B,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC;AACjC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,QAAQ;AACjF,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,iBAAiB,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AAC7E,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACnE;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AACpC,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC;AAC3B,EAAE,IAAI,CAAC,cAAc,GAAG;AACxB,CAAC,CAAC;AACF;AACA,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;AACtE,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC;AAClB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,iBAAiB,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACtE,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC;AAC1B,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACjC,GAAG,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ;AACzC,GAAG,IAAI,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;AAC3B,IAAI,QAAQ,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC;AACrD,IAAI,EAAE,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI;AAClC,IAAI,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ;AACtE,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,UAAU,GAAG,QAAQ,EAAE;AACjD,GAAG,CAAC,CAAC,EAAE;AACP,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;AACV,GAAG,IAAI,EAAE,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE;AAC3D,EAAE,CAAC;AACH,CAAC,CAAC;AACF,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC;AACzB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,QAAQ;AAChD,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,iBAAiB,CAAC,SAAS,CAAC,0BAA0B,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAClF,CAAC,IAAI,CAAC,cAAc,GAAG;AACvB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC;AACjC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,KAAK;AACvC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,iBAAiB,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACnE,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC;AACtB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC;AAC/F,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE;AACjF,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC;AAC/C,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO;AACxD,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,iBAAiB,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAClE,CAAC,GAAG,CAAC,EAAE,CAAC;AACR;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC;AAC3B,EAAE,MAAM,CAAC,IAAI,CAAC;AACd,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACnD,EAAE,MAAM,CAAC,IAAI,CAAC;AACd,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE;AACpC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AAC1B,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,GAAG;AACjC,EAAE,IAAI,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE;AACpC,CAAC,CAAC;AACF;AACA,CAAC,MAAM,CAAC,EAAE,CAAC;AACX,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI;AAC7D,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,GAAG,QAAQ;AACzE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE;AAC3E,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI;AACxB,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC;AACpB,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,iBAAiB,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAC9E,CAAC,GAAG;AACJ,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE;AACpF,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,WAAW,GAAG;AAClD;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;AAClE,EAAE,MAAM,CAAC,IAAI,CAAC;AACd,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACjD,EAAE,MAAM,CAAC,IAAI,CAAC;AACd,CAAC,CAAC;AACF,CAAC,MAAM,CAAC,KAAK,CAAC;AACd,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC;AACtB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,iBAAiB,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC7D,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC;AAC5B,EAAE,IAAI,EAAE,UAAU,CAAC,KAAK,GAAG;AAC3B,CAAC,CAAC;AACF,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC;AACrB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,iBAAiB,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC5D,CAAC,IAAI,EAAE,UAAU,CAAC,IAAI,GAAG;AACzB,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM;AAC3B,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,iBAAiB,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC1E,CAAC,IAAI,CAAC,KAAK,GAAG;AACd,EAAE;;ACzNF,GAAG;AACH,CAAC,CAAC,CAAC,aAAa,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS;AAC7F,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC;AAC/E,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC;AAC9D,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,oBAAoB,CAAC,OAAO;AAChF,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,QAAQ;AACZ,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO;AACjD,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC;AACnE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG;AACpF,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK;AAC9D,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,sBAAsB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACvE,CAAC,EAAE,CAAC,aAAa,CAAC,cAAc;AAChC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG;AACvB;AACA,CAAC,EAAE,CAAC,UAAU;AACd,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;AACrB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;AACpB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC;AAC5D,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AACrD,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AACzD,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AACrD,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AACjD,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AACjD,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AACvD;AACA,CAAC,EAAE,CAAC,cAAc;AAClB,CAAC,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,EAAE;AACjD,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE;AACnE,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE;AACvD,EAAE;AACF;AACA,EAAE,CAAC,KAAK,CAAC,EAAE;AACX;AACA,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,EAAE;AAC1C;AACA,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE;AACvB;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC;AAC5B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC;AACxG,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,gBAAgB,CAAC,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,kBAAkB,CAAC,kBAAkB,CAAC;AAChI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;AACxG,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC;AACjB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM;AACV,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC;AACtB,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,MAAM,CAAC,2BAA2B,CAAC,CAAC,CAAC,IAAI,CAAC;AACpE;AACA,EAAE,CAAC,MAAM,CAAC,EAAE;AACZ;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC;AACjE,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK;AACf,CAAC,EAAE;AACH;AACA,EAAE,CAAC,OAAO,CAAC,EAAE;AACb;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC;AAC1B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE;AACtF,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO;AAC5F,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC;AAC7E,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM;AACnD,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAC7E,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;AACtB,EAAE,IAAI,EAAE,MAAM;AACd,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC;AAC/C,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;AAClC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;AACV,IAAI,SAAS,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC;AACvC,IAAI,OAAO,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC;AACnC,IAAI,KAAK,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC;AAC/B,IAAI,QAAQ,CAAC,CAAC,IAAI,CAAC,iBAAiB;AACpC,GAAG,CAAC,CAAC,EAAE;AACP,CAAC,CAAC;AACF;AACA,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM;AACvB,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC;AAC3C,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;AACR,GAAG,SAAS,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC;AACtC,GAAG,OAAO,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC;AAClC,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC;AAC9B,GAAG,QAAQ,CAAC,CAAC,IAAI,CAAC,iBAAiB;AACnC,EAAE,CAAC,CAAC,EAAE;AACN;AACA,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM;AAC5D,CAAC,EAAE,CAAC,CAAC,WAAW,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS;AAChD,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC9D,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE;AACxC,CAAC,CAAC;AACF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC;AAC7B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK;AAC3C,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAClE,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClE,EAAE,MAAM,CAAC;AACT,CAAC,CAAC;AACF,CAAC,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,EAAE;AACzD,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG;AAC7F,CAAC,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK;AACrC,CAAC,IAAI,CAAC,kBAAkB,GAAG,gBAAgB,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,EAAE;AACtF,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,UAAU,CAAC,SAAS;AACpE,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,2BAA2B,CAAC,CAAC,CAAC,CAAC;AAC7D,EAAE,MAAM,CAAC,KAAK,CAAC;AACf,CAAC,CAAC;AACF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC;AAC3B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK;AACvC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAChE,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClE,EAAE,MAAM,CAAC;AACT,CAAC,CAAC;AACF,CAAC,IAAI,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,EAAE;AAC5D,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI;AAC9D,CAAC,IAAI,CAAC,kBAAkB,GAAG,mBAAmB,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,EAAE;AACzF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC;AAC9B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK;AAC5C,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK;AACf,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC9D,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACnE,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC/B,GAAG,MAAM,CAAC,KAAK,CAAC;AAChB,EAAE,CAAC;AACH,CAAC,CAAC;AACF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC;AAC3B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK;AACzC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAChE,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC/F,EAAE,MAAM,CAAC;AACT,CAAC,CAAC;AACF,CAAC,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,EAAE;AACzD,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG;AACzF,CAAC,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK;AACrC,CAAC,IAAI,CAAC,kBAAkB,GAAG,gBAAgB,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,EAAE;AAClF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC;AACzB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK;AACxC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC9D,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC/F,EAAE,MAAM,CAAC;AACT,CAAC,CAAC;AACF,CAAC,IAAI,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,EAAE;AAC5D,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI;AAC5D,CAAC,IAAI,CAAC,kBAAkB,GAAG,mBAAmB,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,EAAE;AACrF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC;AAC5B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK;AAC1C,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK;AACf,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACjE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAChG,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC/B,GAAG,MAAM,CAAC,KAAK,CAAC;AAChB,EAAE,CAAC;AACH,CAAC,CAAC;AACF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC;AAC/B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM;AACrC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC5D,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC;AACpB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC;AAChH,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM;AAC/D,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACxE,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC;AACzD,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAChC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC;AACvB,EAAE,IAAI,EAAE,OAAO;AACf,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,SAAS,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;AAC3D,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,EAAE;AACxD,EAAE,IAAI,CAAC,kBAAkB,GAAG;AAC5B,CAAC,CAAC;AACF;AACA,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;AACjC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC;AAClC,CAAC,CAAC;AACF,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,kBAAkB,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ;AAC7E,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,kBAAkB,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE;AAC9E,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI;AAClG,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM;AAC5C,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACpE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC;AACvB,CAAC,IAAI,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE;AACxE,CAAC,IAAI,CAAC,kBAAkB,GAAG;AAC3B,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM;AAChC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM;AACzC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC5D,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC;AACpB,EAAE;;ACjQF,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,EAAE;AAC7F,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,QAAQ;AAC5F,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC;AACzE,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE;AAC9E,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM;AAC3D,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,QAAQ;AACZ,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,WAAW;AACzB,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO;AACjD,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,aAAa;AAC3F,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,GAAG,GAAG;AAC/D,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,qBAAqB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACrE,CAAC,EAAE,CAAC,aAAa,CAAC,cAAc;AAChC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG;AACvB;AACA,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY;AACtB,CAAC,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AACrC;AACA,CAAC,EAAE,CAAC,UAAU;AACd,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;AACpB;AACA,CAAC,EAAE,CAAC,cAAc;AAClB,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE;AACvD,EAAE;AACF;AACA,EAAE,CAAC,KAAK,CAAC,EAAE;AACX;AACA,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,WAAW,CAAC,EAAE;AAC1D;AACA,EAAE,CAAC,MAAM,CAAC,EAAE;AACZ;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM;AAChB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC;AACpE,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK;AAC9D,CAAC,EAAE;AACH;AACA,EAAE,CAAC,OAAO,CAAC,EAAE;AACb;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC;AACzB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC;AACxE,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK;AACjD,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAC1E,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;AACZ;AACA,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;AACtB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AACvD,EAAE,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,EAAE;AACjD,CAAC,CAAC;AACF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC;AAC5B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC;AACzF,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,iBAAiB,CAAC,MAAM,CAAC;AACrC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG;AAC/C,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM;AAChF,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACzE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;AAClB,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE;AAC5B;AACA,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AACvD,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE;AACzB,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAChD,GAAG,MAAM,CAAC,IAAI,CAAC;AACf,EAAE,CAAC;AACH,CAAC,CAAC;AACF;AACA,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC;AAC5B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,gBAAgB,CAAC,MAAM,CAAC,OAAO,CAAC;AAC3H,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG;AAC/C,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI;AACvD,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAC1E,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;AAClB,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE;AAC5B,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG;AACb;AACA,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AACvD,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE;AACzB,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAChD,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AACtB,EAAE,CAAC;AACH,CAAC,CAAC;AACF;AACA,CAAC,MAAM,CAAC,KAAK,CAAC;AACd,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC;AAC1B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,SAAS;AACpG,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE;AACnI,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK;AACvE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK;AACvD,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACzE,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM;AAChB,CAAC,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,EAAE;AAC9D;AACA,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,EAAE;AACxC,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AAC5E,CAAC,EAAE,CAAC,kBAAkB,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK;AACjG,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,EAAE;AAC5C;AACA,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM;AAChB,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,EAAE;AAC5E;AACA,CAAC,MAAM,CAAC,QAAQ,CAAC;AACjB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAC1E,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,EAAE;AAC9B,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,EAAE;AACxC;AACA,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM;AAChB,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,EAAE;AACvE;AACA,CAAC,MAAM,CAAC,KAAK,CAAC;AACd,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK;AACjC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM;AACnD,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,KAAK;AACxC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACxF,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACxE,EAAE,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,UAAU,EAAE,OAAO,CAAC,EAAE;AAC5C,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC5B,EAAE,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,UAAU,EAAE,OAAO,CAAC,EAAE;AAC7C,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACT,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,UAAU,EAAE,OAAO,CAAC,EAAE;AAC7D,CAAC,CAAC;AACF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC;AAC3C,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC;AACpF,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,OAAO,CAAC;AACxF,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM;AAC7D,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACrE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC;AACzB;AACA,CAAC,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ;AAClC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAClD,EAAE,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE;AACpB,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE;AACrC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACvB,GAAG,IAAI,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,EAAE;AAChC,GAAG,IAAI,EAAE,OAAO,CAAC,MAAM,GAAG;AAC1B,EAAE,CAAC;AACH,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM;AAChB,CAAC,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,EAAE;AAC1D;AACA,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,EAAE;AACxC,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC;AAClC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC;AACpF,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC;AAC9E,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC7D,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;AACZ;AACA,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ;AAC5B,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AACvD,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,eAAe,CAAC,CAAC,IAAI,CAAC,EAAE;AAC1C,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,MAAM,GAAG;AACpC,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM;AAChB,CAAC,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AAClD;AACA,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,EAAE;AACxC,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;;AC7NF,GAAG;AACH,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC;AACrE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI;AACnF,CAAC,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG;AACnF,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK;AAC5D,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC;AAC3B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,WAAW,CAAC,KAAK;AACvF,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,QAAQ;AACZ,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO;AACjD,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,OAAO,CAAC;AACjG,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,IAAI,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI;AACnG,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC;AACjG,CAAC,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC;AAChD,CAAC,CAAC;AACF,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAC9C,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,GAAG,GAAG;AACxB,CAAC,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK;AAChF,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,OAAO;AAC3B,CAAC,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM;AACjD,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO;AACvC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;AACvG,CAAC,CAAC,EAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI;AAClF,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK;AACtG,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC;AAC3B,CAAC,CAAC;AACF,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC;AAC3B,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AACxD,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC;AAC9F,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,WAAW,CAAC,KAAK;AACvF,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK;AAC5G,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC;AAC9E,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACnE,CAAC,EAAE,CAAC,aAAa,CAAC,cAAc;AAChC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG;AACvB;AACA,CAAC,EAAE,CAAC,UAAU;AACd,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AACnB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AAClB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC;AACvB;AACA,CAAC,EAAE,CAAC,cAAc;AAClB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE;AAC7D,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE;AAC5E,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE;AACtD,EAAE;AACF;AACA,EAAE,CAAC,KAAK,CAAC,EAAE;AACX;AACA,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE;AACxC;AACA,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE;AACvB;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI;AACtG,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE;AACrF,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC;AAC1F,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC;AAC1B,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AACxD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,IAAI,CAAC;AACnF,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM;AACV,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC;AAC5B,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AAC3C;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;AAC9F,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC;AAC5D,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,EAAE,CAAC,IAAI,CAAC;AAClF,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM;AACV,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;AACnC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC;AAChD;AACA,EAAE,CAAC,OAAO,CAAC,EAAE;AACb;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,aAAa;AAChG,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI;AAC5F,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO;AAC/F,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC;AACvD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI;AAC/C,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACvE,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;AACpB,EAAE,IAAI,EAAE,IAAI;AACZ,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACnE,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AAC1B,CAAC,CAAC;AACF;AACA,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI;AACnB,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC;AACvC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACxD,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,EAAE;AACzD,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACjC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE;AAC7C,CAAC,CAAC;AACF;AACA,CAAC,IAAI,CAAC,kBAAkB,GAAG;AAC3B,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC;AACtF,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO;AAC1F,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC;AAClB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK;AACjG,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC;AACnD,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAC/D,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACvF,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AAC5E;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAC5B,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;AACrB,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAC9B,IAAI,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;AACxD,GAAG,CAAC;AACJ,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACzB,IAAI,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE;AAChD,GAAG,CAAC;AACJ,EAAE,CAAC;AACH,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AACnB,CAAC,CAAC;AACF;AACA,CAAC,IAAI,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,EAAE;AAC/D,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;AACpB,EAAE,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;AACnE,CAAC,CAAC;AACF,CAAC,IAAI,CAAC,kBAAkB,GAAG;AAC3B;AACA,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC;AACtD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC;AAChF,CAAC,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC;AAC/D,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AACzE,CAAC,SAAS,CAAC,CAAC;AACZ,EAAE,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAChG,GAAG,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACxC;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AACtC,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;AAC7B,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;AACrB,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACnC,IAAI,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,SAAS,CAAC,EAAE;AAC1C,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC;AACX,IAAI,IAAI,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACrC,GAAG,CAAC;AACJ,EAAE,CAAC;AACH,CAAC,CAAC;AACF;AACA,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC;AACrC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI;AAC7B,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACzD,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;AAClB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC;AAC7F,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI;AACnC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC9D,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC;AACvB,EAAE;;AChMF,GAAG;AACH,CAAC,CAAC,CAAC,gBAAgB,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,SAAS,CAAC;AAC/E,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC;AACrE,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE;AACnF,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC;AAC7E,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM;AACnF,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE;AAC9E,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG;AACnE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE;AACzC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,WAAW,CAAC,UAAU;AAC5F,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,QAAQ;AACZ,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO;AACjD,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,IAAI;AACjF,CAAC,CAAC,EAAE,aAAa,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,IAAI,GAAG;AAClF,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,GAAG;AACtF,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ;AAClF,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC;AACnB,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,WAAW,CAAC,UAAU;AAC5F,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC;AACrF,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI;AAC3F,CAAC,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC;AACjC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,CAAC,QAAQ,CAAC,yBAAyB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAC7E,CAAC,EAAE,CAAC,aAAa,CAAC,cAAc;AAChC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG;AACvB;AACA,CAAC,EAAE,CAAC,UAAU;AACd,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC;AACxB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC;AACvB,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC;AAC5B;AACA,CAAC,EAAE,CAAC,cAAc;AAClB,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE;AAC5E,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,cAAc,CAAC,EAAE;AAC3F,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,MAAM,EAAE,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE;AAChE,EAAE;AACF;AACA,EAAE,CAAC,KAAK,CAAC,EAAE;AACX;AACA,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,EAAE;AAC7C;AACA,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE;AACvB;AACA,GAAG;AACH,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,GAAG;AAC7D,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,EAAE,CAAC,IAAI,CAAC;AAClF,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM;AACV,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC;AAC1B,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC;AACrD;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC;AAC3F,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,cAAc,CAAC,aAAa,CAAC,EAAE,CAAC,IAAI,CAAC;AACrG,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM;AACV,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;AACnC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC;AAC1D;AACA,EAAE,CAAC,OAAO,CAAC,EAAE;AACb;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC;AAC7B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC;AACzF,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,SAAS;AACzD,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AACtF,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;AACzB,EAAE,IAAI,EAAE,SAAS;AACjB,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;AACvF,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AAC1B,CAAC,CAAC;AACF;AACA,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS;AAC7B,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC,CAAC;AACjD,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,WAAW,EAAE,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;AACvE,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE;AACxE,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACtC,EAAE,IAAI,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,EAAE;AACvD,CAAC,CAAC;AACF;AACA,CAAC,IAAI,CAAC,kBAAkB,GAAG;AAC3B,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC;AAC3H,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,SAAS;AACxF,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AAC9E,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AACzF;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AACtC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;AAC1B,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACnC,IAAI,IAAI,EAAE,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE;AACvE,GAAG,CAAC;AACJ,GAAG,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAC9B,IAAI,IAAI,EAAE,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE;AAC/D,GAAG,CAAC;AACJ,EAAE,CAAC;AACH,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;AAC7B,CAAC,CAAC;AACF;AACA,CAAC,IAAI,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,EAAE,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE;AACzE,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;AACzB,EAAE,IAAI,EAAE,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,WAAW,EAAE,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE;AACvF,CAAC,CAAC;AACF,CAAC,IAAI,CAAC,kBAAkB,GAAG;AAC3B;AACA,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC;AAC3B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC;AACzE,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,cAAc,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE;AACtG,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,SAAS,CAAC,KAAK;AAClC,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;AACxF,CAAC,cAAc,CAAC,CAAC;AACjB,EAAE,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC/G,GAAG,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAC7C;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;AAChD,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,cAAc,CAAC;AACvC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;AAC1B,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACxC,IAAI,IAAI,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,cAAc,CAAC,EAAE;AACpD,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC;AACX,IAAI,IAAI,EAAE,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AAC1C,GAAG,CAAC;AACJ,EAAE,CAAC;AACH,CAAC,CAAC;AACF;AACA,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,GAAG;AACrE,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS;AAC9C,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACnE,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC;AACvB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC;AAC3B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC;AACzE,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI;AACxC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACxE,CAAC,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC;AAC5B,EAAE;;AC7KF,GAAG;AACH,CAAC,CAAC,CAAC,YAAY,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK;AAC5E,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,OAAO,CAAC;AACvD,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC;AACtE,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,WAAW,CAAC,MAAM;AACxF,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,QAAQ;AACZ,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO;AACjD,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,IAAI;AACzE,CAAC,CAAC,EAAE,aAAa,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,IAAI,GAAG;AAC9E,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,SAAS;AACrG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM;AACnG,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC;AAC9E,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,WAAW,CAAC,MAAM;AACzF,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,qBAAqB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACrE,CAAC,EAAE,CAAC,aAAa,CAAC,cAAc;AAChC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG;AACvB;AACA,CAAC,EAAE,CAAC,UAAU;AACd,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;AACpB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;AACnB;AACA,CAAC,EAAE,CAAC,cAAc;AAClB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;AAChE,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE;AACxD,EAAE;AACF;AACA,EAAE,CAAC,KAAK,CAAC,EAAE;AACX;AACA,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE;AACzC;AACA,EAAE,CAAC,MAAM,CAAC,EAAE;AACZ;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW;AACrB,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK;AACxB,CAAC,EAAE;AACH;AACA,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE;AACvB;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI;AACzF,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI;AAChF,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC;AACvE,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM;AACV,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;AACnC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;AAC7C;AACA,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE;AACpB;AACA,GAAG;AACH,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI;AAChE,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI;AAC5B,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI;AACtC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,GAAG,OAAO;AACvF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK;AAC1D,CAAC,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,WAAW,CAAC,IAAI;AAC1C,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AACpF,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC;AACnB,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACd,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE;AAC1B;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AACjB,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC;AACrB,EAAE,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC;AACtB,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AACzD,GAAG,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC7D,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;AACf,GAAG,CAAC;AACJ,EAAE,CAAC;AACH,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACT,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,EAAE;AAC7D,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACxC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AACvB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACT,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC;AACjB,GAAG,QAAQ,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;AACtD,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;AAChB,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC;AACrD,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;AACzD,GAAG,QAAQ,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACjE,EAAE,EAAE;AACJ,CAAC,CAAC;AACF,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,QAAQ,GAAG;AAC3B,EAAE;AACF;AACA,EAAE,CAAC,OAAO,CAAC,EAAE;AACb;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC;AACzB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC;AACzF,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK;AACjD,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAC1E,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;AACrB,EAAE,IAAI,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,GAAG;AAChE,CAAC,CAAC;AACF;AACA,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE;AAC7D,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE;AACpC,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC;AACjB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI;AAClG,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,GAAG;AACrC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;AACnH,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK;AAC9B,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAClE,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;AACzE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;AAC1K;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAC9B,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;AACtB,GAAG,IAAI,CAAC,eAAe,CAAC,CAAC,KAAK,CAAC,EAAE;AACjC,EAAE,CAAC;AACH,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC;AACrB,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,EAAE;AAC7B,CAAC,CAAC;AACF;AACA,CAAC,IAAI,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,EAAE,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE;AACjE;AACA,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,KAAK;AACvD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG;AACzC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS;AACvD,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,GAAG,OAAO;AACvF,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AAC5F,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE;AACxF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC;AACjB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;AAC5F,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK;AAC9B,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC3D,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC;AACnB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC;AAChC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,eAAe,CAAC;AAC1F,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;AACjG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK;AAC9B,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACzE,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;AACnC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACjC,GAAG,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK;AACnE,GAAG,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE;AAChC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;AACV,GAAG,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,EAAE;AAC7B,EAAE,CAAC;AACH,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;AACnD,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,EAAE;AACvC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACxC,EAAE,IAAI,EAAE,KAAK,CAAC,KAAK,GAAG,MAAM,CAAC,CAAC,KAAK,CAAC,EAAE;AACtC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACT,EAAE,IAAI,EAAE,KAAK,CAAC,KAAK,GAAG;AACtB,CAAC,CAAC;AACF,EAAE;;AC7LF,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG;AACjF,CAAC,CAAC,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ;AACtF,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;AAChF,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG;AACnF,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,aAAa,CAAC;AAChC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC;AAC9E,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,WAAW,GAAG,EAAE,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;AACxH,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,WAAW,GAAG,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC;AACrG,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC;AAClD,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,CAAC,OAAO;AACf,CAAC,CAAC,KAAK,EAAE,CAAC,cAAc,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK;AAC5E,CAAC,CAAC,KAAK,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC;AAC9C,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,WAAW,EAAE;AAChC,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC;AAC/B,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACX,CAAC,CAAC,KAAK,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC;AAC9C,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,WAAW,EAAE;AAChC,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC;AAC/B,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACX,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE;AAChE,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,aAAa,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,GAAG,CAAC,EAAE,IAAI,GAAG;AAClJ,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC;AAC7E,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO;AAC5D,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,QAAQ;AACZ,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO;AACjD,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC;AAC7G,CAAC,CAAC,EAAE,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC;AACpG,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO;AAC7D,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC;AAC5D,CAAC,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE;AACxF,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC;AACjG,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC,QAAQ,CAAC,uBAAuB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACzE,CAAC,EAAE,CAAC,aAAa,CAAC,cAAc;AAChC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG;AACvB;AACA,CAAC,EAAE,CAAC,UAAU;AACd,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG;AACjB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;AACtB;AACA,CAAC,EAAE,CAAC,cAAc;AAClB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;AAC/B,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE;AAC5D,EAAE;AACF;AACA,EAAE,CAAC,MAAM,CAAC,EAAE;AACZ;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI;AACd,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC;AAC5F,CAAC,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG;AACjF,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC;AACpB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS;AACjG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC;AAC9D,CAAC,EAAE;AACH;AACA,EAAE,CAAC,OAAO,CAAC,EAAE;AACb;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC;AAC3B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC;AAC9G,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC;AAC3F,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO;AAC1D,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AAChF,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACpE,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AACxC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;AACjB;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;AACvB,EAAE,IAAI,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC,UAAU,CAAC,EAAE;AAC1C,CAAC,CAAC;AACF;AACA,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,UAAU,CAAC,EAAE;AACjD,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC;AACtC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI;AACpC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG;AACpC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClE,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG;AAC5E,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE;AAC7C,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC;AAClC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,KAAK;AAChC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC7D,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG;AAC5E,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE;AACxC,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC;AACnB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC/D,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC;AACrB,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG;AACf,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG;AACd,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,GAAG;AACxC;AACA,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAC7B,EAAE,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC;AACjC,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;AAC1B,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,EAAE;AAC5B,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,EAAE;AAC3B,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;AACvB,EAAE,IAAI,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;AAClD,CAAC,CAAC;AACF;AACA,CAAC,IAAI,CAAC,kBAAkB,GAAG;AAC3B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,EAAE;AAC9B;AACA,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC;AACzB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,MAAM,GAAG,MAAM,EAAE,MAAM,CAAC,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC;AAC/F,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM;AAC/F,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,KAAK,GAAG;AAC3C,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACpE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC;AAC7B,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG;AACf,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG;AACX,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG;AACd,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,GAAG;AACxC;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;AACnC,EAAE,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC;AAClC,EAAE,EAAE,CAAC,GAAG;AACR,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC/B,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAC9B,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,EAAE;AACzB,EAAE,CAAC;AACH,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACvC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AACnD,GAAG,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE;AACrB,GAAG,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC;AAClC,GAAG,EAAE,CAAC,GAAG;AACT,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC/B,IAAI,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAC3B,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAC9B,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,EAAE;AAC1B,GAAG,CAAC;AACJ,EAAE,CAAC;AACH,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC1C,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACzB,GAAG,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC;AAClC,GAAG,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACzB,IAAI,EAAE,CAAC,GAAG;AACV,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAChC,KAAK,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAC5B,KAAK,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAC/B,KAAK,GAAG,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,EAAE;AAC3B,IAAI,CAAC;AACL,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC;AACX,IAAI,EAAE,CAAC,MAAM;AACb,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC/B,KAAK,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;AAC7B,KAAK,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,EAAE;AAC/B,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,EAAE;AAC9B,IAAI,CAAC;AACL,GAAG,CAAC;AACJ,EAAE,CAAC;AACH,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;AACvB,EAAE,IAAI,EAAE,OAAO;AACf,GAAG,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC/B,GAAG,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;AACtC,CAAC,CAAC;AACF;AACA,CAAC,IAAI,CAAC,kBAAkB,GAAG;AAC3B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,EAAE;AAC9B;AACA,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;;AC7MF,GAAG;AACH,CAAC,CAAC,CAAC,aAAa,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC;AAC5E,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK;AAC9E,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC;AACvE,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,CAAC,OAAO;AACf,CAAC,CAAC,KAAK,EAAE,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG;AAC3D,CAAC,CAAC,KAAK,EAAE,CAAC,YAAY,CAAC,KAAK;AAC5B,CAAC,CAAC,KAAK,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC;AAC7C,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE;AACtC,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;AACjC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACX,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE;AAC7C,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,QAAQ;AACZ,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO;AACjD,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,OAAO,CAAC;AACjF,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,aAAa,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG;AAClF,CAAC,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC;AACjC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE;AACpF,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC;AACjG,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,sBAAsB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACvE,CAAC,EAAE,CAAC,aAAa,CAAC,cAAc;AAChC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG;AACvB;AACA,CAAC,EAAE,CAAC,UAAU;AACd,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;AACrB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;AACnB;AACA,CAAC,EAAE,CAAC,cAAc;AAClB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;AAC5F,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE;AAC1D,EAAE;AACF;AACA,EAAE,CAAC,KAAK,CAAC,EAAE;AACX;AACA,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,EAAE;AAC1C;AACA,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE;AACvB;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ;AACzG,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC;AACrD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM;AACV,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;AACnC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;AAC9C;AACA,EAAE,CAAC,OAAO,CAAC,EAAE;AACb;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC;AAC1B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC;AACpH,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC;AAChH,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa;AAC7E,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAC7E,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;AACtB,EAAE,IAAI,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACrC,CAAC,CAAC;AACF;AACA,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;AACxB,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACpB,EAAE,IAAI,CAAC,WAAW,GAAG;AACrB,CAAC,CAAC;AACF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC;AACb,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK;AACvG,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACnE,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;AACzE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;AACtE;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAC9B,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC;AACrB,EAAE,IAAI,CAAC,WAAW,GAAG;AACrB,CAAC,CAAC;AACF;AACA,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,SAAS,CAAC;AACxE,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC/D,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,GAAG;AAC7B,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;AACtB,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACzB,GAAG,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,kBAAkB;AAC3C,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC,CAAC,CAAC;AACzC,IAAI,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC,KAAK,CAAC,EAAE;AACnD,GAAG,CAAC;AACJ,GAAG,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,EAAE;AACvC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;AACV,GAAG,IAAI,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACtC,EAAE,CAAC;AACH,CAAC,CAAC;AACF,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC;AACb,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,MAAM;AAChC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC5D,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC;AACnB,EAAE;;AC1HF,GAAG;AACH,CAAC,CAAC,CAAC,kBAAkB,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,SAAS,CAAC;AACtF,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK;AAChE,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG;AAC9D,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC;AACpB,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,CAAC,OAAO;AACf,CAAC,CAAC,KAAK,EAAE,CAAC,kBAAkB,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG;AACrE,CAAC,CAAC,KAAK,EAAE,CAAC,YAAY,CAAC,KAAK;AAC5B,CAAC,CAAC,KAAK,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC;AAC7C,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE;AAC1C,CAAC,CAAC,SAAS,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;AACzB,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACX,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE;AAC7C,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,QAAQ;AACZ,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO;AACjD,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,OAAO,CAAC;AAC1F,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,aAAa,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG;AACtF,CAAC,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC;AACjC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE;AACpF,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC;AACvD,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC,CAAC,QAAQ,CAAC,2BAA2B,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACjF,CAAC,EAAE,CAAC,aAAa,CAAC,cAAc;AAChC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG;AACvB;AACA,CAAC,EAAE,CAAC,UAAU;AACd,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC;AAC1B,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC;AACvB;AACA,CAAC,EAAE,CAAC,cAAc;AAClB,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE;AAC/C,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC,MAAM,EAAE,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE;AACpE;AACA,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI;AACjF,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG;AAC3C,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;AAC1B,EAAE,IAAI,CAAC,WAAW,GAAG;AACrB,CAAC,CAAC;AACF,EAAE;AACF;AACA,EAAE,CAAC,KAAK,CAAC,EAAE;AACX;AACA,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,kBAAkB,CAAC,EAAE;AAC/C;AACA,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE;AACvB;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,SAAS,CAAC;AAC7E,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM;AACV,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;AACnC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,kBAAkB,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC;AACvD;AACA,EAAE,CAAC,OAAO,CAAC,EAAE;AACb;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,OAAO,CAAC;AAC/B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,kBAAkB,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC;AACzH,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC;AAChH,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,WAAW,CAAC,CAAC,aAAa;AACvF,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,kBAAkB,CAAC,SAAS,CAAC,qBAAqB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;AAC5F,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC;AAC3B,EAAE,IAAI,EAAE,WAAW,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE;AAC9C,CAAC,CAAC;AACF;AACA,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC;AAClC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AACxB,EAAE,IAAI,EAAE,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE;AACxD,CAAC,CAAC;AACF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC;AACjB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,SAAS;AACzG,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,kBAAkB,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AAChF,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAClF;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AACtC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC;AAC5B,GAAG,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAC9B,IAAI,IAAI,EAAE,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,SAAS,CAAC,EAAE;AACrD,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC;AACX,IAAI,IAAI,EAAE,WAAW,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE;AAChD,GAAG,CAAC;AACJ,EAAE,CAAC;AACH,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;AAC7B;AACA,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,aAAa;AACpC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;AAC3B,GAAG,IAAI,CAAC,WAAW,GAAG;AACtB,EAAE,CAAC;AACH,CAAC,CAAC;AACF;AACA,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC;AACjB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,MAAM;AACpC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,kBAAkB,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACrE,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC;AACvB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC;AACvE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,WAAW,EAAE;AACxD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,SAAS;AAC5D,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC;AACnB,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,kBAAkB,CAAC,SAAS,CAAC,wBAAwB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACxF,CAAC,GAAG,CAAC,SAAS,CAAC;AACf;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC;AAC5B,EAAE,EAAE,CAAC,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ;AAChG,EAAE,MAAM,CAAC,KAAK,CAAC;AACf,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,cAAc,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG;AACnG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,uBAAuB,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,uBAAuB,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC;AACxF,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,uBAAuB,CAAC,iBAAiB,CAAC,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;AACvF,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACT,EAAE,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,GAAG;AAClC,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AACnB,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI;AAClC,CAAC,CAAC;AACF,CAAC,MAAM,CAAC,KAAK,CAAC;AACd,EAAE;;AC9IF,GAAG;AACH,CAAC,CAAC,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC;AACzE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,aAAa,CAAC,OAAO;AACnF,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW;AACzF,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC;AAChB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,oBAAoB;AACxE,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,CAAC,OAAO;AACf,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM;AACzB,CAAC,CAAC,KAAK,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC;AAC7C,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE;AACrC,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,CAAC,KAAK,EAAE;AACzB,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;AAC1B,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACX,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE;AAC7C,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,KAAK,CAAC;AACxE,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM;AACxB,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa;AACpC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW;AAClC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB;AACvC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY;AACnC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa;AACpC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,cAAc;AACrC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,iBAAiB;AACxC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,kBAAkB;AACzC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO;AACjD,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM;AACzE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC;AACtE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC;AAC7E,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC;AACzE,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAC1D,CAAC,EAAE,CAAC,aAAa,CAAC,cAAc;AAChC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG;AACvB;AACA,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AAChD;AACA,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AAChD,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AAC9C,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AACnD,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AAC/C,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;AAC3F,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AACjD,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;AACnG,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;AACrG;AACA,CAAC,EAAE,CAAC,UAAU;AACd,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AAClB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;AACpB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC;AACvB;AACA,CAAC,EAAE,CAAC,MAAM;AACV,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE;AAChD;AACA,CAAC,EAAE,CAAC,cAAc;AAClB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE;AACjE,CAAC,IAAI,EAAE,OAAO;AACd,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC;AACnC,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE;AAC1B,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE;AACjC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE;AAC7B,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE;AACjC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE;AACrC,EAAE;AACF;AACA,EAAE,CAAC,KAAK,CAAC,EAAE;AACX;AACA,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE;AACpD,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,EAAE;AAC/D,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE;AAC7D,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,EAAE;AAClE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE;AAC9D,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,EAAE;AAC/D,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,EAAE;AAChE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,iBAAiB,CAAC,EAAE;AACnE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,kBAAkB,CAAC,EAAE;AACpE;AACA,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE;AACvB;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,MAAM;AACV,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,2BAA2B,CAAC,CAAC,CAAC,KAAK,CAAC;AAC9D;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,MAAM;AACV,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;AAC3C;AACA,EAAE,CAAC,OAAO,CAAC,EAAE;AACb;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC;AAC1B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,QAAQ;AACtC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACpD,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;AAClB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC;AACxB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,MAAM;AACpC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACtD,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC;AACpB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC;AACpC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS;AAClF,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACxD,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC;AACtB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC;AAC1B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM;AAC/D,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAC1D,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AAC/C,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACnD,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AACrB,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAC5B,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AACnB,EAAE,IAAI,CAAC,UAAU,GAAG;AACpB,CAAC,CAAC;AACF;AACA,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE;AAC7D,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC;AAClB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACvD,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC;AAClD,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;AACzC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACT,EAAE,IAAI,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE;AACpC,CAAC,CAAC;AACF;AACA,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC;AACzB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,QAAQ;AAChD,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACtD,CAAC,IAAI,CAAC,UAAU,GAAG;AACnB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC;AACxB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM;AAC/D,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAC9D,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;AACrD;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAChC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC;AACvB,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAC1B,GAAG,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,EAAE;AACzC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;AACV,GAAG,IAAI,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE;AACvC,EAAE,CAAC;AACH,CAAC,CAAC;AACF;AACA,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC;AACpC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS;AAC1F,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AAClE,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC;AAC5D;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AACpC,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC;AAC3B,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AACnB,GAAG,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE;AAC1C,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;AACV,GAAG,IAAI,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE;AACpC,EAAE,CAAC;AACH,CAAC,CAAC;AACF;AACA,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa;AACtD,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS;AACpB,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ;AACnB,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;;AC9NH,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,GAAG;AAC9F,CAAC,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC;AACnG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC;AACvC,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,CAAC,OAAO;AACf,CAAC,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO;AACvD,CAAC,CAAC,KAAK,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAC;AACnD,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE;AACtC,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE;AACxB,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC;AACnB,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,KAAK,CAAC,EAAE,CAAC,EAAE;AAC7D,CAAC,CAAC,aAAa,MAAM,CAAC,CAAC,IAAI,CAAC;AAC5B,CAAC,CAAC,aAAa,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;AAC5B,CAAC,CAAC,SAAS,CAAC;AACZ,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACX,CAAC,CAAC,KAAK,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC;AAC9C,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC;AAC5B,CAAC,CAAC,KAAK,GAAG;AACV,CAAC,CAAC,KAAK,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAC;AACvD,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC;AACpC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACX,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,WAAW,EAAE,OAAO,CAAC,EAAE;AAClD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM;AACxB,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY;AACnC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO;AACjD,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG;AACrD,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAC,QAAQ,CAAC,qBAAqB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACpE,CAAC,EAAE,CAAC,aAAa,CAAC,cAAc;AAChC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG;AACvB;AACA,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AACrD;AACA,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;AAC1F;AACA,CAAC,EAAE,CAAC,cAAc;AAClB,CAAC,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,EAAE;AACrD,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACvC,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;AAChC,CAAC,CAAC;AACF,EAAE;AACF;AACA,EAAE,CAAC,KAAK,CAAC,EAAE;AACX;AACA,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE;AACzD,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE;AACnE;AACA,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE;AACvB;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,MAAM;AACV,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;AAChD;AACA,EAAE,CAAC,OAAO,CAAC,EAAE;AACb;AACA,GAAG;AACH,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM;AACnB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACvD,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC;AAC5B,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC1B,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,GAAG;AAC3B,EAAE,CAAC;AACH,CAAC,CAAC;AACF,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACpE,CAAC,IAAI,CAAC,KAAK,GAAG;AACd,EAAE;;ACnFF,GAAG;AACH,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC;AAC3I,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;AAC3G,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC;AAC/C,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,CAAC,OAAO;AACf,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK;AACrC,CAAC,CAAC,KAAK,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;AAC3C,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE;AACxB,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;AACxB,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE;AACZ,CAAC,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC;AAC1B,CAAC,CAAC,MAAM,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;AAChD,CAAC,CAAC,UAAU,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;AACzB,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE;AACZ,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE;AAClE,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,WAAW,CAAC,KAAK;AACvF,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM;AACxB,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW;AAClC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa;AACpC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,cAAc;AACrC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO;AACjD,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACtD,CAAC,EAAE,CAAC,aAAa,CAAC,cAAc;AAChC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG;AACvB;AACA,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AAC9C;AACA,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;AACxF,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;AAC5F,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;AAC9F;AACA,CAAC,EAAE,CAAC,cAAc;AAClB,CAAC,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE;AAC9C,EAAE;AACF;AACA,EAAE,CAAC,KAAK,CAAC,EAAE;AACX;AACA,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE;AAClD,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE;AAC3D,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,EAAE;AAC7D,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,EAAE;AAC9D;AACA,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE;AACvB;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,MAAM;AACV,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;;ACzDzC,GAAG;AACH,CAAC,CAAC,CAAC,gBAAgB,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI;AAC/F,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE;AAChG,CAAC,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,EAAE;AAC3F,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,CAAC,OAAO;AACf,CAAC,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,MAAM;AACxC,CAAC,CAAC,KAAK,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC;AACpD,CAAC,CAAC,SAAS,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC;AAChC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACX,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK;AACjD,CAAC,CAAC,KAAK,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,GAAG;AACjD,CAAC,CAAC,KAAK,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;AAC3B,CAAC,CAAC,SAAS,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC;AAClF,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACX,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,QAAQ,EAAE,OAAO,CAAC,EAAE;AAC/C,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,WAAW,CAAC,UAAU;AAC5F,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM;AACxB,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB;AACvC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa;AACpC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO;AACjD,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC,QAAQ,CAAC,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAChE,CAAC,EAAE,CAAC,aAAa,CAAC,cAAc;AAChC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG;AACvB;AACA,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AACnD;AACA,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;AAClG,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;AAC5F;AACA,CAAC,EAAE,CAAC,cAAc;AAClB,CAAC,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC,EAAE;AACnD,EAAE;AACF;AACA,EAAE,CAAC,KAAK,CAAC,EAAE;AACX;AACA,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE;AACvD,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,EAAE;AACrE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,EAAE;AAClE;AACA,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE;AACvB;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,MAAM;AACV,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;;ACvD9C,GAAG;AACH,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG;AACtF,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC;AAC5F,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM;AAC/B,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;AAClG,CAAC,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,QAAQ,CAAC;AAC1G,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI;AACtF,CAAC,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC;AACpE,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,KAAK;AACvG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC;AAClD,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,CAAC,OAAO;AACf,CAAC,CAAC,KAAK,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,YAAY;AAClC,CAAC,CAAC,KAAK,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;AAC5C,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC;AACnC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACX,CAAC,CAAC,KAAK,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;AAC5C,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;AAChE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACX,CAAC,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO;AAC/D,CAAC,CAAC,KAAK,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,GAAG;AACjD,CAAC,CAAC,KAAK,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;AAC3B,CAAC,CAAC,SAAS,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,EAAE;AAC3C,CAAC,CAAC,SAAS,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC;AAC1C,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACX,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,QAAQ,EAAE,OAAO,CAAC,EAAE;AAC/C,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM;AACxB,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY;AACnC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa;AACpC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO;AACjD,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC;AAC/F,CAAC,CAAC,EAAE,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC;AAC5D,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACxD,CAAC,EAAE,CAAC,aAAa,CAAC,cAAc;AAChC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG;AACvB;AACA,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AAC/C;AACA,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;AAC1F,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AAChD;AACA,CAAC,EAAE,CAAC,UAAU;AACd,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;AAC3B;AACA,CAAC,EAAE,CAAC,cAAc;AAClB,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACpB,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC;AAClC,GAAG,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC,EAAE;AACxD,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;AACV,GAAG,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACzC,IAAI,IAAI,CAAC,KAAK,CAAC,kBAAkB,GAAG;AACpC,GAAG,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;AACpB,EAAE,CAAC;AACH,CAAC,CAAC;AACF,CAAC,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,EAAE;AAC/C,EAAE;AACF;AACA,EAAE,CAAC,KAAK,CAAC,EAAE;AACX;AACA,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE;AACnD,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE;AAC7D,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,EAAE;AAC9D;AACA,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE;AACvB;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,MAAM;AACV,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE;;AC9E3C,GAAG;AACH,CAAC,CAAC,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,SAAS;AAC1G,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO;AACxG,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK;AAC3G,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE;AAC9D,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI;AAC9H,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI;AACvH,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC;AACtB,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,CAAC,OAAO;AACf,CAAC,CAAC,KAAK,QAAQ,CAAC,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACzC,CAAC,CAAC,SAAS,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AACrD,CAAC,CAAC,KAAK,CAAC;AACR,CAAC,CAAC,KAAK,EAAE,CAAC,YAAY,CAAC,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,EAAE;AAC7D,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,eAAe,EAAE;AACrD,CAAC,CAAC,KAAK,aAAa,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AACvC,CAAC,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE;AAC/D,CAAC,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;AAC7C,CAAC,CAAC,KAAK,EAAE;AACT,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,aAAa,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACzD,CAAC,CAAC,SAAS,aAAa,CAAC,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,EAAE;AAC9E,CAAC,CAAC,SAAS,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;AACpE,CAAC,CAAC,SAAS,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,GAAG,CAAC,EAAE,CAAC,EAAE;AAC1M,CAAC,CAAC,SAAS,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE;AACtD,CAAC,CAAC,KAAK,EAAE;AACT,CAAC,CAAC,KAAK,aAAa,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC5D,CAAC,CAAC,SAAS,MAAM,CAAC,GAAG,CAAC;AACtB,CAAC,CAAC,KAAK,CAAC;AACR,CAAC,CAAC,KAAK,aAAa,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACvE,CAAC,CAAC,SAAS,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;AAC7B,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AACrC,CAAC,CAAC,aAAa,MAAM,CAAC,UAAU,GAAG,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,EAAE,WAAW,GAAG;AAC3E,CAAC,CAAC,aAAa,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE;AACzC,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC;AAC5B,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACnC,CAAC,CAAC,iBAAiB,MAAM,CAAC,UAAU,GAAG,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,EAAE,UAAU,GAAG;AAC9E,CAAC,CAAC,aAAa,CAAC,CAAC,EAAE;AACnB,CAAC,CAAC,SAAS,CAAC;AACZ,CAAC,CAAC,SAAS,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,SAAS,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AACvF,CAAC,CAAC,KAAK,EAAE;AACT,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,aAAa,GAAG;AACrD,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,aAAa,EAAE,OAAO,CAAC,EAAE;AACpD,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,aAAa,GAAG;AACxC,CAAC,CAAC,KAAK,aAAa,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;AAC9C,CAAC,CAAC,KAAK,aAAa,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,EAAE;AAC1C,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,QAAQ;AACZ,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO;AACjD,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO;AACjF,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC,QAAQ,CAAC,uBAAuB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACzE,CAAC,EAAE,CAAC,aAAa,CAAC,cAAc;AAChC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG;AACvB;AACA,CAAC,EAAE,CAAC,UAAU;AACd,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;AACtB;AACA,CAAC,EAAE,CAAC,cAAc;AAClB,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE;AAC5D,EAAE;AACF;AACA,EAAE,CAAC,KAAK,CAAC,EAAE;AACX;AACA,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,EAAE;AAC3C;AACA,EAAE,CAAC,OAAO,CAAC,EAAE;AACb;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,EAAE;AAC3D,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC;AAC1D,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AAChF,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;AACvB,EAAE,IAAI,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,EAAE;AAC9D,CAAC,CAAC;AACF;AACA,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;AAC1B,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC1B,EAAE,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,EAAE;AAC3D,CAAC,CAAC;AACF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC;AAClC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO;AACvC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC9D,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC;AACvB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI;AAC/F,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE;AAC3E,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAChE,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC5B,EAAE,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,EAAE;AAC3D,EAAE,IAAI,CAAC,kBAAkB,GAAG;AAC5B,CAAC,CAAC;AACF,CAAC,IAAI,CAAC,OAAO,GAAG;AAChB;AACA,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI;AAC/F,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE;AAC3E,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC/D,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC5B,EAAE,IAAI,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,EAAE;AAC9D,EAAE,IAAI,CAAC,kBAAkB,GAAG;AAC5B,CAAC,CAAC;AACF,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;AAChD;AACA,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;;ACnIF,GAAG;AACH,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,SAAS;AAChG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE;AAChE,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,aAAa,CAAC,UAAU,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG;AACnG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI;AACjG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC;AAC9C,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG;AAClG,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,iBAAiB,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM;AAClG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC;AAC/D,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,QAAQ;AACZ,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO;AACjD,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,OAAO;AAC9F,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,kBAAkB,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE;AACnE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,gBAAgB,EAAE,KAAK,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC;AACpF,CAAC,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,kBAAkB,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI;AAC5F,CAAC,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,kBAAkB,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI;AAC5F,CAAC,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI;AACjE,CAAC,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI;AAC1E,CAAC,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,MAAM;AAC3E,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,kBAAkB,EAAE,KAAK,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC;AACxF,CAAC,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,kBAAkB,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI;AAC7F,CAAC,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,kBAAkB,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI;AAC3F,CAAC,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI;AACnG,CAAC,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI;AAC7F,CAAC,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,MAAM;AAC7E,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS;AACjG,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI;AAClB,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,CAAC,QAAQ,CAAC,yBAAyB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAC7E,CAAC,EAAE,CAAC,aAAa,CAAC,cAAc;AAChC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG;AACvB;AACA,CAAC,EAAE,CAAC,UAAU;AACd,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC;AACxB,CAAC,IAAI,EAAE,kBAAkB,CAAC,CAAC,CAAC,IAAI,CAAC;AACjC,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC;AAC9B,CAAC,IAAI,EAAE,0BAA0B,CAAC,CAAC,CAAC,IAAI,CAAC;AACzC,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,CAAC,KAAK,CAAC;AACjC,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AAC5D,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AAClE;AACA,CAAC,EAAE,CAAC,cAAc;AAClB,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC,MAAM,EAAE,kBAAkB,CAAC,EAAE;AAC1D,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,MAAM,EAAE,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE;AAChE,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,MAAM,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AAChE,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC,MAAM,CAAC,kBAAkB,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACpE,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC,MAAM,CAAC,iBAAiB,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,iBAAiB,CAAC;AACrG,EAAE;AACF;AACA,EAAE,CAAC,OAAO,CAAC,EAAE;AACb;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC;AACzB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC;AACzF,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS;AACvD,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AACtF,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;AACzB,EAAE,IAAI,EAAE,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC,EAAE;AACpE,EAAE,IAAI,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE;AAC/C,CAAC,CAAC;AACF;AACA,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC,EAAE;AAC7E,CAAC,IAAI,CAAC,QAAQ,GAAG;AACjB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,SAAS,CAAC;AAC3B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,SAAS,CAAC;AACtE,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,kBAAkB,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK;AACvF,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,SAAS,CAAC,qBAAqB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC;AACjG,CAAC,IAAI,EAAE,kBAAkB,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC;AAChD,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;AACzB,EAAE,IAAI,CAAC,QAAQ,GAAG;AAClB,CAAC,CAAC;AACF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC;AACnD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC;AACzE,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AACpF,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACpF,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE;AACxE,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AAC5C,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,QAAQ,CAAC;AACnC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;AAC1B,GAAG,IAAI,CAAC,QAAQ,GAAG;AACnB,EAAE,CAAC;AACH,CAAC,CAAC;AACF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC;AACrD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC;AACzE,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,SAAS,CAAC,qBAAqB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AACtF,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACpF,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE;AAC1E,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AAC9C,EAAE,IAAI,CAAC,kBAAkB,CAAC,CAAC,CAAC,QAAQ,CAAC;AACrC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;AAC1B,GAAG,IAAI,CAAC,QAAQ,GAAG;AACnB,EAAE,CAAC;AACH,CAAC,CAAC;AACF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC;AACtB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC;AACzF,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM;AACpE,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;AACrF,CAAC,GAAG,CAAC,4BAA4B,CAAC;AAClC;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,kBAAkB,CAAC,CAAC,CAAC,CAAC;AACvD,EAAE,MAAM,CAAC,IAAI,CAAC;AACd,CAAC,CAAC;AACF;AACA,CAAC,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC;AAC7E;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,iBAAiB,EAAE,CAAC,CAAC,CAAC,CAAC;AAC5E,EAAE,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC,gBAAgB,CAAC,iBAAiB,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,EAAE;AACtI,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,IAAI,CAAC;AAC/B,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;AAC1C,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC;AACjC;AACA,EAAE,IAAI,CAAC,mBAAmB,CAAC,CAAC;AAC5B,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACtC,GAAG,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACzC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,IAAI,EAAE,kBAAkB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;AAC1E;AACA,EAAE,4BAA4B,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,6BAA6B,CAAC,CAAC,IAAI,EAAE,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;AACrH,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM;AACtE,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,eAAe,CAAC;AACtD,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,4BAA4B,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC/D,GAAG,4BAA4B,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,4BAA4B,CAAC,EAAE;AACjG,EAAE,CAAC;AACH;AACA,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;AACtB,GAAG,IAAI,EAAE,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC,EAAE;AACxD,GAAG,IAAI,EAAE,eAAe,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,8BAA8B,CAAC,EAAE;AAC7E;AACA,GAAG,IAAI,EAAE,0BAA0B,CAAC,CAAC,CAAC,EAAE,CAAC,4BAA4B,CAAC,EAAE;AACxE,GAAG,IAAI,EAAE,0BAA0B,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,wBAAwB,CAAC,EAAE;AAClF;AACA,GAAG,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAO;AACpC,GAAG,IAAI,CAAC,QAAQ,GAAG;AACnB,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;AACV,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC,CAAC,CAAC;AACjC,IAAI,IAAI,EAAE,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,8BAA8B,CAAC,EAAE;AAC/E,IAAI,IAAI,EAAE,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC;AACjC,GAAG,CAAC;AACJ;AACA,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,0BAA0B,CAAC,CAAC,CAAC,CAAC;AAC5C,IAAI,IAAI,EAAE,0BAA0B,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,wBAAwB,CAAC,EAAE;AACpF,IAAI,IAAI,EAAE,0BAA0B,CAAC,CAAC,CAAC,IAAI,CAAC;AAC5C,GAAG,CAAC;AACJ;AACA,GAAG,IAAI,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE;AAC3D,EAAE,CAAC;AACH,CAAC,CAAC;AACF;AACA,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC;AACpG,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO;AAC3B,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS;AAC7B,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC;AACpB,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AAChG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,CAAC,eAAe,CAAC,CAAC,kBAAkB,CAAC,CAAC,gBAAgB,CAAC,CAAC,iBAAiB,CAAC;AAClG,EAAE,iBAAiB,CAAC,CAAC,eAAe,CAAC,CAAC,eAAe,CAAC;AACtD,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE;AAC1C;AACA,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,qBAAqB,GAAG;AAClD,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACpC,EAAE,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,kBAAkB,GAAG;AAC/C,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC;AACd,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;AACV,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;AACX,GAAG,KAAK,CAAC,CAAC,QAAQ,CAAC,eAAe,CAAC,WAAW,CAAC;AAC/C,GAAG,MAAM,CAAC,CAAC,QAAQ,CAAC,eAAe,CAAC,YAAY;AAChD,EAAE,EAAE;AACJ,EAAE,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,eAAe,CAAC,GAAG,CAAC;AACtC,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC;AACxC,EAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,eAAe,CAAC,KAAK,CAAC;AAC1C,EAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,eAAe,CAAC,MAAM,CAAC;AAC5C,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACT,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,qBAAqB,GAAG;AACrD,CAAC,CAAC;AACF;AACA,CAAC,eAAe,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC;AACnF,CAAC,kBAAkB,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC;AAC5F,CAAC,gBAAgB,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC;AACtF,CAAC,iBAAiB,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC;AACzF,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AAC7B,EAAE,iBAAiB,CAAC,CAAC,CAAC,iBAAiB,CAAC;AACxC,EAAE,eAAe,CAAC,CAAC,CAAC,gBAAgB,CAAC;AACrC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACT,EAAE,iBAAiB,CAAC,CAAC,CAAC,gBAAgB,CAAC;AACvC,EAAE,eAAe,CAAC,CAAC,CAAC,iBAAiB,CAAC;AACtC,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC;AAClE,EAAE,MAAM,CAAC,KAAK,CAAC;AACf,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;AAC/D,EAAE,MAAM,CAAC,KAAK,CAAC;AACf,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC;AACpE,EAAE,MAAM,CAAC,KAAK,CAAC;AACf,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;AACjE,EAAE,MAAM,CAAC,KAAK,CAAC;AACf,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC;AAC1E,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,OAAO,CAAC;AACrF,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE;AAC7E,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC;AACrE,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC;AACzE,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI;AAC7C,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC3E,CAAC,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC;AAChC,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC;AAC9C,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC;AAClF,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC/D,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;AAC3B,EAAE,MAAM,CAAC,IAAI,CAAC;AACd,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE;AACR,EAAE,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC;AAC9C,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG;AAC5C,EAAE,IAAI,CAAC,iBAAiB,EAAE,CAAC,EAAE,CAAC,CAAC;AAC/B,GAAG,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM;AAClD,GAAG,IAAI,EAAE,0BAA0B,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC,EAAE;AACvE,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG;AAC3C,GAAG,EAAE,QAAQ,CAAC,CAAC,IAAI,CAAC,kBAAkB,GAAG,CAAC,IAAI,EAAE,0BAA0B,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACjF,EAAE,CAAC;AACH,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACN,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG;AACnF,EAAE,MAAM,CAAC,IAAI,CAAC;AACd,CAAC,CAAC;AACF;AACA,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,IAAI,EAAE,kBAAkB,CAAC,CAAC,IAAI,EAAE,0BAA0B,CAAC,EAAE;AAC7I,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC;AACjC,EAAE,IAAI,EAAE,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE;AACrD,EAAE,MAAM,CAAC,IAAI,CAAC;AACd,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACT,EAAE,IAAI,EAAE,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE;AACxD,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC;AACnC,EAAE,MAAM,CAAC,IAAI,CAAC;AACd,CAAC,CAAC;AACF;AACA,CAAC,IAAI,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC,EAAE;AAC/C;AACA,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC;AAC/D,CAAC,EAAE,CAAC,CAAC,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,EAAE;AAChG,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,EAAE;AAC/C,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI;AAClG,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC;AAC1D,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACnB,EAAE,IAAI,CAAC,IAAI,GAAG;AACd,CAAC,CAAC;AACF;AACA,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,kBAAkB;AAC7F,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC;AAClG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,WAAW,CAAC,KAAK,CAAC;AAC9F,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE;AACpG,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACtE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,WAAW,CAAC,CAAC,WAAW,CAAC,CAAC,YAAY,CAAC;AACpD,EAAE,oBAAoB,CAAC,CAAC,kBAAkB,CAAC,CAAC,SAAS,CAAC,CAAC,UAAU,CAAC;AAClE,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE;AACxD,EAAE,SAAS,CAAC,CAAC,CAAC,IAAI,EAAE,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE;AAC1D,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,EAAE,SAAS,CAAC,YAAY,GAAG;AACjD;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACpC,EAAE,EAAE,CAAC,GAAG,CAAC,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,KAAK,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG;AACrF,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;AACnD,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,aAAa,CAAC,IAAI,CAAC,EAAE;AAC7D,CAAC,CAAC;AACF,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE;AACrC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE;AAC9G,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE;AAC9G;AACA,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,EAAE;AACvF,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,EAAE;AAC3F,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC;AACtG,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,UAAU;AAC7B,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;AACpE,CAAC,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACpG;AACA,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,mBAAmB,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM;AAC7F,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM;AAC9B,CAAC,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;AACxB,EAAE,IAAI,EAAE,kBAAkB,CAAC,MAAM,EAAE,CAAC,CAAC;AACrC,EAAE,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC,IAAI,EAAE,kBAAkB,CAAC,CAAC,CAAC,YAAY,CAAC,EAAE;AACtF,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,kBAAkB,CAAC,WAAW,GAAG;AACjF,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,kBAAkB,CAAC,UAAU,GAAG;AAChF,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC;AACnF,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,KAAK,CAAC;AACjF;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AAC3C,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC;AACnC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AAClD,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC;AACjE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AAChD,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC;AAChC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;AACnD,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC;AACpE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;AACnD,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;AACjC,GAAG,CAAC,CAAC,IAAI,EAAE,kBAAkB,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACxE,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;AAC9C,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,YAAY,CAAC,KAAK,CAAC;AAClC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AACpD,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC;AAClC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AACpD,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,YAAY,CAAC,KAAK,CAAC;AACpC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AAClD,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC;AAChC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;AACrD,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;AACnC,GAAG,CAAC,CAAC,IAAI,EAAE,kBAAkB,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,SAAS,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACtE,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AACpC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AAC9B,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;AACjI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;AACV,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;AAC9B,EAAE,CAAC;AACH,EAAE,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC;AACtB,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AAClC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AAC9B,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;AAC5B,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;AACV,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;AAC/H,EAAE,CAAC;AACH,EAAE,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC;AACpB,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ;AAC/B,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAC3B,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,SAAS,CAAC;AAC1B,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAC9B,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,SAAS,CAAC;AAC7B,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAC5B,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC;AAC5B,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAC7B,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,UAAU,CAAC;AAC7B,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,MAAM;AAChC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAC9B,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,oBAAoB,CAAC;AACxC,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AAC7B,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAC7B,GAAG,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,kBAAkB,CAAC;AACrC,EAAE,CAAC;AACH,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACT,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAC9B,GAAG,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAAC;AACtC,EAAE,CAAC;AACH,CAAC,CAAC;AACF;AACA,CAAC,MAAM,CAAC,MAAM,CAAC;AACf,EAAE;;ACpaF,GAAG;AACH,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC;AACnE,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI;AAClE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK;AACpE,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC;AACtB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,EAAE,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,GAAG;AACnF,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,kBAAkB,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC;AACrF,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI;AACtF,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,EAAE,SAAS,CAAC,GAAG,CAAC,EAAE,kBAAkB,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC;AACrF,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,kBAAkB,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ;AAChG,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC;AAC9B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,QAAQ;AACZ,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO;AACjD,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,OAAO;AAC1F,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,kBAAkB,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,kBAAkB,CAAC;AAC9F,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,SAAS;AAC5B,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,CAAC,QAAQ,CAAC,yBAAyB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAC7E,CAAC,EAAE,CAAC,aAAa,CAAC,cAAc;AAChC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG;AACvB;AACA,CAAC,EAAE,CAAC,UAAU;AACd,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC;AACxB,CAAC,IAAI,EAAE,kBAAkB,CAAC,CAAC,CAAC,IAAI,CAAC;AACjC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC;AACvB,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC,KAAK,CAAC;AAClC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC,KAAK,CAAC;AAChC,CAAC,IAAI,EAAE,4BAA4B,CAAC,CAAC,CAAC,IAAI,CAAC;AAC3C,CAAC,IAAI,EAAE,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC;AAChC,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC;AAC9B,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC;AACxB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC;AACzB,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AACxD,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AAC9D;AACA,CAAC,EAAE,CAAC,cAAc;AAClB,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC,CAAC,CAAC;AACpC,EAAE,IAAI,CAAC,qBAAqB,CAAC,CAAC,MAAM,EAAE,kBAAkB,CAAC,EAAE;AAC3D,CAAC,CAAC;AACF,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,MAAM,EAAE,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE;AAChE,EAAE;AACF;AACA,EAAE,CAAC,OAAO,CAAC,EAAE;AACb;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC;AACzB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC;AACzF,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS;AACvD,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AACtF,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;AACzB,EAAE,IAAI,EAAE,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC,EAAE;AACpE,EAAE,IAAI,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE;AACjF,EAAE,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;AACpE,CAAC,CAAC;AACF;AACA,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC,EAAE;AAC7E,CAAC,IAAI,CAAC,IAAI,GAAG;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,SAAS,CAAC;AAC3B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC;AAC5F,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC;AACtF,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,SAAS,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC;AACjE,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,kBAAkB,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK;AACvF,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,SAAS,CAAC,qBAAqB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC;AACjG,CAAC,IAAI,EAAE,kBAAkB,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC;AAChD,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;AACzB,EAAE,IAAI,CAAC,IAAI,GAAG;AACd,CAAC,CAAC;AACF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC;AACnB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC;AACtF,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM;AAC9D,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AAC/E,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC;AACjE;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,iBAAiB,EAAE,CAAC,CAAC,CAAC,CAAC;AACzE,EAAE,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC,gBAAgB,CAAC,cAAc,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,EAAE;AACnI,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,IAAI,CAAC;AAC/B,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AACpC,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC;AAC3B,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AACnB,GAAG,IAAI,EAAE,4BAA4B,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,oCAAoC,EAAE,CAAC,EAAE;AACzF,GAAG,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK;AAC1F,GAAG,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,eAAe;AACvE,GAAG,IAAI,EAAE,iBAAiB,CAAC,CAAC,CAAC,IAAI,EAAE,4BAA4B,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AACpF,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,4BAA4B,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC/E,IAAI,IAAI,EAAE,4BAA4B,CAAC;AACvC,GAAG,IAAI,EAAE,iBAAiB,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,wBAAwB,CAAC,EAAE;AACzE,GAAG,IAAI,EAAE,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC,CAAC;AACvD,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,8BAA8B,CAAC,EAAE;AACzD,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO;AAChC,GAAG,IAAI,CAAC,IAAI,GAAG;AACf,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;AACV,GAAG,IAAI,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;AACzB,IAAI,KAAK,CAAC,CAAC,GAAG;AACd,IAAI,MAAM,CAAC,CAAC,GAAG;AACf,IAAI,QAAQ,CAAC,CAAC,GAAG;AACjB,IAAI,SAAS,CAAC,CAAC,GAAG;AAClB,IAAI,SAAS,CAAC,CAAC,GAAG;AAClB,IAAI,SAAS,CAAC,CAAC,EAAE;AACjB,GAAG,CAAC,CAAC,EAAE;AACP,GAAG,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;AACrE;AACA,GAAG,IAAI,EAAE,4BAA4B,CAAC,CAAC,CAAC,IAAI,CAAC;AAC7C,GAAG,IAAI,EAAE,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,wBAAwB,CAAC,EAAE;AAC1E,GAAG,IAAI,EAAE,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC;AAClC,GAAG,IAAI,EAAE,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,8BAA8B,CAAC,EAAE;AAC9E,GAAG,IAAI,EAAE,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC;AAChC,EAAE,CAAC;AACH,CAAC,CAAC;AACF;AACA,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC;AACpG,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI;AAChE,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACjE,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC;AACtB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC;AACpG,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO;AACzD,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAChE,CAAC,MAAM,CAAC,IAAI,CAAC,mBAAmB,CAAC,EAAE,CAAC,IAAI,CAAC,iBAAiB,CAAC;AAC3D,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC;AAC1F,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO;AACzD,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,SAAS,CAAC,qBAAqB,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC5E,CAAC,MAAM,CAAC,IAAI,CAAC,mBAAmB,CAAC;AACjC,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC;AAC3F,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO;AACzD,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC1E,CAAC,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC;AAC/B,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC;AAClG,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM;AAC5F,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM;AAC9F,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAClF,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC;AACzB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC;AAC3B;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AACxB,EAAE,EAAE,CAAC,MAAM,CAAC,UAAU;AACtB,EAAE,IAAI,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;AAC1D,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,UAAU;AACjE,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE;AAC1F,CAAC,CAAC,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC;AAC9E,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,gBAAgB,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,KAAK;AACvF,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,GAAG;AACpF,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,aAAa,CAAC;AAC/E,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC,GAAG;AAChG,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,IAAI,GAAG;AAC/D,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC;AAChE,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC;AACrC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,SAAS,CAAC,uBAAuB,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC9E,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AACzF,EAAE,MAAM,CAAC,CAAC,KAAK,EAAE;AACjB,CAAC,CAAC;AACF,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE;AACf,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE;AAC1F,CAAC,CAAC,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC;AAC9E,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,gBAAgB,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,KAAK;AACxF,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG;AACpF,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,aAAa,CAAC;AAC/E,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC,GAAG;AAChG,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,IAAI,GAAG;AAC/D,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC;AAC3C,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC;AACrC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,SAAS,CAAC,qBAAqB,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC5E,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,IAAI,CAAC,eAAe,GAAG,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAC1F,EAAE,MAAM,CAAC,CAAC,MAAM,EAAE;AAClB,CAAC,CAAC;AACF,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE;AACd,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM;AAClG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC;AAC7C,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE;AAC/F,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC;AACvE,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;AAC5F,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI;AAChG,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC;AAC7E,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC3D,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,UAAU,CAAC,CAAC,eAAe,CAAC;AAC9C,EAAE,YAAY,CAAC,CAAC,aAAa,CAAC,CAAC,YAAY,CAAC,CAAC,aAAa,CAAC;AAC3D,EAAE,YAAY,CAAC,CAAC,aAAa,CAAC,CAAC,SAAS,CAAC,CAAC,UAAU,CAAC;AACrD,EAAE,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC,aAAa,CAAC;AAC1D,EAAE,SAAS,CAAC,CAAC,kBAAkB,CAAC,CAAC,oBAAoB,CAAC;AACtD,EAAE,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG;AACzF,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE;AACpF,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;AAC9B,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;AACb;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AACxB,EAAE,EAAE,CAAC,IAAI,EAAE,4BAA4B,CAAC,GAAG,CAAC,IAAI,EAAE,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI;AAClG,EAAE,MAAM,CAAC,IAAI,CAAC;AACd,CAAC,CAAC;AACF;AACA,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACpC,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG;AACf,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;AACrC,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE;AACxC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE;AAC9C,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE;AAC3C,EAAE,MAAM,CAAC,GAAG,CAAC;AACb,CAAC,CAAC;AACF;AACA,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,kBAAkB,GAAG;AAC9C;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,4BAA4B,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC/D,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,EAAE,4BAA4B,CAAC,CAAC,CAAC,CAAC,EAAE,aAAa,CAAC,IAAI,CAAC,EAAE;AAC9E,EAAE,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC;AAC/D,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC;AAClB,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;AACV,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;AACX,GAAG,KAAK,CAAC,CAAC,QAAQ,CAAC,eAAe,CAAC,WAAW,CAAC;AAC/C,GAAG,MAAM,CAAC,CAAC,QAAQ,CAAC,eAAe,CAAC,YAAY;AAChD,EAAE,EAAE;AACJ,EAAE,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC,eAAe,CAAC,GAAG,CAAC;AAC1C,EAAE,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC;AAC5C,EAAE,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC,eAAe,CAAC,KAAK,CAAC;AAC9C,EAAE,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC,eAAe,CAAC,MAAM,CAAC;AAChD,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACT,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,EAAE,4BAA4B,CAAC;AACjD,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,qBAAqB,GAAG;AACxD,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM;AAChC,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE;AAC9C,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,MAAM;AAChC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE;AAC1C,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,EAAE;AAC/E,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,EAAE;AACnF,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC,oBAAoB,CAAC;AAC7C,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AAC7B,EAAE,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,kBAAkB,CAAC;AAC1C,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACT,EAAE,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAAC;AAC3C,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,SAAS;AAC3B,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC;AAC5B,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC;AAC7B,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC;AAC9B,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC;AAC/B;AACA,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,kBAAkB,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,CAAC;AACrD;AACA,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,SAAS,CAAC,WAAW,GAAG;AACnE,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,SAAS,CAAC,UAAU,GAAG;AAChE;AACA,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,qBAAqB,GAAG;AAC/C,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM;AAC/B,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE;AACrC;AACA,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE;AAChG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC;AACjG,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,uBAAuB,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AACpD,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC;AACpC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACT,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,YAAY,CAAC,KAAK,CAAC;AACtC,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,qBAAqB,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;AACnD,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC;AAClC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACT,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC;AACxC,CAAC,CAAC;AACF;AACA,CAAC,aAAa,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,YAAY,CAAC,CAAC,QAAQ,CAAC,EAAE;AAC5D;AACA,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE;AACxE,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE;AACzE,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,GAAG,CAAC,KAAK,CAAC;AAC3F,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,YAAY,CAAC;AACvC,EAAE,QAAQ,CAAC,eAAe,CAAC,WAAW,CAAC,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,eAAe,CAAC,KAAK,CAAC,EAAE;AACxF,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,aAAa,CAAC;AACzC,EAAE,QAAQ,CAAC,eAAe,CAAC,YAAY,CAAC,CAAC,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,eAAe,CAAC,KAAK,CAAC,EAAE;AACxF,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE;AACvD,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE;AAC1D,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,EAAE;AACtD,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,EAAE;AACxD,CAAC,SAAS,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,YAAY,CAAC;AACzC,CAAC,UAAU,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,aAAa,CAAC;AAC5C;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AACnB,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC;AACzG,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,oBAAoB,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC;AAChG,EAAE,IAAI,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE;AAC/C,EAAE,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM;AACzD,EAAE,IAAI,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;AACxB,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,EAAE;AACtC,GAAG,QAAQ,CAAC,CAAC,EAAE;AACf,EAAE,CAAC,CAAC,EAAE;AACN,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACT,EAAE,IAAI,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;AACxB,GAAG,SAAS,CAAC,CAAC,GAAG;AACjB,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,GAAG;AAChC,GAAG,QAAQ,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC;AACxC,EAAE,CAAC,CAAC,EAAE;AACN,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;AACpB,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC;AACzG,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,oBAAoB,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC;AAChG,EAAE,IAAI,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE;AAC/C,EAAE,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM;AACzD,EAAE,IAAI,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;AACxB,GAAG,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,EAAE;AACxC,GAAG,SAAS,CAAC,CAAC,EAAE;AAChB,EAAE,CAAC,CAAC,EAAE;AACN,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACT,EAAE,IAAI,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;AACxB,GAAG,SAAS,CAAC,CAAC,GAAG;AACjB,GAAG,MAAM,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,GAAG;AAClC,GAAG,SAAS,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC;AAC1C,EAAE,CAAC,CAAC,EAAE;AACN,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,UAAU;AAC5D,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACjG,EAAE,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;AACpE,CAAC,CAAC;AACF;AACA,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC,SAAS,CAAC;AACtC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC,UAAU,CAAC;AACrC;AACA,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;;ACvYF,GAAG;AACH,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC,UAAU,CAAC;AAC3F,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC;AACtE,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC;AAC1F,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,WAAW,CAAC,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC;AAC7F,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,CAAC,OAAO;AACf,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC;AACzB,CAAC,CAAC,KAAK,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;AAC3C,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC,EAAE;AAC7C,CAAC,CAAC,SAAS,MAAM,CAAC,CAAC,IAAI,CAAC;AACxB,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,GAAG;AACrB,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACX,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE;AAC5C,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE;AAChE,CAAC,CAAC,KAAK,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE;AAC5B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM;AAC1D,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM;AACxB,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY;AACnC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB;AACvC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB;AACvC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO;AACjD,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC;AAC/F,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC;AACnG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK;AACvE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE,KAAK,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,kBAAkB;AAC/F,CAAC,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,kBAAkB,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM;AAC7F,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,kBAAkB;AACnC,CAAC,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,kBAAkB,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM;AAC3F,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,kBAAkB;AACnC,CAAC,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,kBAAkB,CAAC,CAAC,MAAM,CAAC,MAAM;AAC7F,CAAC,CAAC,YAAY,QAAQ,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,kBAAkB;AACjF,CAAC,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,kBAAkB,CAAC,CAAC,MAAM,CAAC,MAAM;AAC5F,CAAC,CAAC,YAAY,UAAU,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,kBAAkB;AACnF,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,kBAAkB;AAC/E,CAAC,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC;AACtG,CAAC,CAAC,cAAc,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC;AAC5E,CAAC,CAAC,cAAc,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,QAAQ,CAAC;AACzF,CAAC,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC;AACzG,CAAC,CAAC,eAAe,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC;AAC7E,CAAC,CAAC,eAAe,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,QAAQ,CAAC;AACxF,CAAC,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM;AACrG,CAAC,CAAC,YAAY,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,kBAAkB,CAAC;AAClE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,GAAG;AACnE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,GAAG;AACpE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,aAAa,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO;AAC9F,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG;AAC7F,CAAC,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ;AAC3D,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,SAAS,CAAC;AAC/F,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC;AACvD,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,gBAAgB;AAC5E,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC;AACpH,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI;AACjE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM;AAClE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC;AACtF,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,eAAe,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC;AACxF,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC;AACpH,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC;AACnB,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,gBAAgB;AAC5E,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,KAAK;AAClG,CAAC,CAAC,EAAE,MAAM,CAAC;AACX,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI;AAChE,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACxD,CAAC,EAAE,CAAC,aAAa,CAAC,cAAc;AAChC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG;AACvB;AACA,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AAC/C;AACA,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,gBAAgB,CAAC,WAAW,CAAC,IAAI,CAAC;AACrE,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE;AAC3B,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE;AAC5B;AACA,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AAC/C,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;AACjE,EAAE,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC;AACzB,EAAE,CAAC,kBAAkB,CAAC,CAAC,IAAI,EAAE,KAAK;AAClC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;AACP,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AACnD;AACA,CAAC,EAAE,CAAC,UAAU;AACd,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE;AAC7B,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,eAAe,EAAE;AAC9D,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,MAAM,EAAE,SAAS,CAAC;AACrC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,MAAM,CAAC,gBAAgB,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAAC;AAC9F,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,SAAS,CAAC;AACrC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC;AAC/B,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC;AACvB,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AACzD,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AACrE;AACA,CAAC,EAAE,CAAC,cAAc;AAClB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE;AAC7C,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE;AACnE,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE;AAC/C,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AAChD,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE;AACtE,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,MAAM,EAAE,eAAe,CAAC,EAAE;AACpD,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,EAAE;AACjD,CAAC,IAAI,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,EAAE;AACrD,CAAC,IAAI,EAAE,KAAK;AACZ,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;AACxC,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE;AACxB,CAAC,IAAI,EAAE,OAAO;AACd,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;AAClC,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE;AACvC,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI;AAC3E,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM;AAC1E,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAC3C,EAAE,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE;AACvC,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACvB,EAAE,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE;AACzD,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACrB,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE;AAChF,EAAE,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,EAAE;AACpE,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;AAC3B,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC;AACxC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,EAAE;AACrD,EAAE,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE;AACpC,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;AACxB,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;AAC7B,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC;AAC1C,GAAG,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE;AAC7B,EAAE,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE;AACrC,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO;AAChG,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,YAAY;AACvF,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK;AAC5D,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC;AACtB,CAAC,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE;AAClD,EAAE;AACF;AACA,EAAE,CAAC,KAAK,CAAC,EAAE;AACX;AACA,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE;AACnD,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE;AAC7D,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,EAAE;AACjE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,EAAE;AACjE;AACA,EAAE,CAAC,MAAM,CAAC,EAAE;AACZ;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK;AACf,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC;AACzE,CAAC,EAAE;AACH;AACA,EAAE,CAAC,OAAO,CAAC,EAAE;AACb;AACA,GAAG;AACH,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC;AAC7B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK;AACzC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC1D,CAAC,EAAE,CAAC,CAAC;AACL,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,EAAE;AACrB,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,eAAe,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC;AACrF,CAAC,CAAC,CAAC,CAAC;AACJ,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,EAAE;AACvB,CAAC,CAAC;AACF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC;AAC5B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC,qBAAqB,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACjE,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK;AAChC,CAAC,IAAI,CAAC,gBAAgB,GAAG,gBAAgB,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,EAAE;AACxF,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC;AAC3E,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,OAAO;AACnF,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ;AACpF,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ;AACtF,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO;AACvF,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK;AACpD,CAAC,IAAI,CAAC,kBAAkB,GAAG,gBAAgB,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,EAAE;AACtF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC;AACrC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC9D,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC;AAC1B,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,EAAE;AACvB,CAAC,CAAC;AACF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC;AAC9B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC,uBAAuB,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACnE,CAAC,IAAI,CAAC,gBAAgB,GAAG,mBAAmB,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,EAAE;AAC3F,CAAC,IAAI,CAAC,kBAAkB,GAAG,mBAAmB,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,EAAE;AACzF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC;AAC3B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK;AAC1C,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAChE,CAAC,EAAE,CAAC,CAAC;AACL,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE;AAClC,EAAE,IAAI,CAAC,SAAS,EAAE;AAClB,CAAC,CAAC,CAAC,CAAC;AACJ,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,EAAE;AACvB,EAAE,CAAC,CAAC,cAAc,GAAG;AACrB,EAAE,CAAC,CAAC,eAAe,GAAG;AACtB,CAAC,CAAC;AACF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC;AAC1B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC/D,CAAC,IAAI,CAAC,gBAAgB,GAAG,gBAAgB,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC,IAAI,CAAC,EAAE;AAC5F,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC;AAC5B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC,qBAAqB,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACjE,CAAC,IAAI,CAAC,gBAAgB,GAAG,mBAAmB,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC,IAAI,CAAC,EAAE;AAC/F,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC;AACtD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM;AACtD,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAC9D,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC;AACrD;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAChC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACf,GAAG,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,EAAE;AAC1D,GAAG,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE;AAC7E,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;AACV,GAAG,IAAI,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,EAAE;AAC7D,GAAG,IAAI,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE;AAChF,EAAE,CAAC;AACH,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC;AACvB,CAAC,CAAC;AACF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;AAC3C,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC;AACzD,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAC/D,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACpE,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE;AACvD,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClC,EAAE,IAAI,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE;AAC/E,CAAC,CAAC;AACF,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC;AACxB,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AACvB,EAAE,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE;AACjE,CAAC,CAAC;AACF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC;AAClC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO;AACtC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACrD,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC;AACtB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO;AAC7F,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC;AAChE,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC,QAAQ,CAAC,EAAE,CAAC,OAAO;AAClG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC;AAChG,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM;AAC5F,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC;AACtF,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK;AACf,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACxD,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC,cAAc,CAAC,CAAC,WAAW,CAAC,CAAC,aAAa,CAAC;AACtE,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC;AACxD;AACA,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,GAAG;AACpC;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,iBAAiB,EAAE,CAAC,CAAC,CAAC,CAAC;AACrE,EAAE,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,EAAE;AACpH,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,IAAI,CAAC;AAC/B,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,kBAAkB,CAAC,EAAE,CAAC,IAAI,CAAC,iBAAiB,EAAE,CAAC,CAAC,CAAC,CAAC;AACvE,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,kBAAkB,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG;AACtE,EAAE,IAAI,CAAC,qBAAqB,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE;AACvD,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AACzC,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI;AAChG,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE;AACjC,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC;AAC7B,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM;AACjB,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AAC9D;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAChB,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,kBAAkB,CAAC,EAAE;AAC/D;AACA,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACf,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AAC1B,IAAI,IAAI,CAAC,qBAAqB,GAAG;AACjC,IAAI,IAAI,CAAC,mBAAmB,GAAG;AAC/B,GAAG,CAAC;AACJ,GAAG,IAAI,CAAC,gBAAgB,GAAG;AAC3B,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,EAAE;AAC/B;AACA,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AACzB,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AAC7E,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,mBAAmB,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,oBAAoB,EAAE,CAAC,CAAC,CAAC,CAAC;AACvE,MAAM,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI;AACnF,MAAM,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO;AACpC,MAAM,YAAY,CAAC,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,MAAM,GAAG;AAC5C,MAAM,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC;AAC/C,MAAM,IAAI,CAAC,QAAQ,GAAG;AACtB,MAAM,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,mBAAmB,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,oBAAoB,EAAE,CAAC,CAAC,CAAC,CAAC;AACxE,OAAO,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,SAAS;AAC3E,OAAO,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK;AAC5B,OAAO,cAAc,CAAC,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,MAAM,GAAG;AAC/C,OAAO,EAAE,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;AAC7C,QAAQ,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC;AACjD,QAAQ,IAAI,CAAC,QAAQ,GAAG;AACxB,OAAO,CAAC;AACR,MAAM,CAAC;AACP,KAAK,CAAC;AACN,IAAI,CAAC;AACL,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AAC9E,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,qBAAqB,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,oBAAoB,EAAE,CAAC,CAAC,CAAC,CAAC;AACzE,MAAM,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI;AACnF,MAAM,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO;AACpC,MAAM,WAAW,CAAC,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,KAAK,GAAG;AAC1C,MAAM,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC;AAC/C,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,UAAU,CAAC;AACpF,MAAM,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC;AAC1F,MAAM,IAAI,CAAC,cAAc,CAAC,CAAC,KAAK,CAAC,EAAE;AACnC,MAAM,IAAI,CAAC,QAAQ,GAAG;AACtB,MAAM,IAAI,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,EAAE;AAClC,MAAM,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,qBAAqB,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,oBAAoB,EAAE,CAAC,CAAC,CAAC,CAAC;AAC1E,OAAO,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,SAAS;AAC3E,OAAO,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK;AAC5B,OAAO,aAAa,CAAC,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,KAAK,GAAG;AAC7C,OAAO,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;AAC3C,QAAQ,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC;AACjD,QAAQ,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,UAAU,CAAC;AACtF,QAAQ,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC;AAC5F,QAAQ,IAAI,CAAC,cAAc,CAAC,CAAC,KAAK,CAAC,EAAE;AACrC,QAAQ,IAAI,CAAC,QAAQ,GAAG;AACxB,QAAQ,IAAI,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,EAAE;AACpC,OAAO,CAAC;AACR,MAAM,CAAC;AACP,KAAK,CAAC;AACN,IAAI,CAAC;AACL,GAAG,CAAC;AACJ;AACA,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACxB,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;AACV,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC,KAAK,CAAC,EAAE;AAChC,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AAC1B,IAAI,IAAI,CAAC,uBAAuB,GAAG;AACnC,IAAI,IAAI,CAAC,qBAAqB,GAAG;AACjC,GAAG,CAAC;AACJ,EAAE,CAAC;AACH,CAAC,CAAC;AACF;AACA,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC;AAC7B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC;AACrF,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC;AACxF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC;AAC5F,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU;AAC9D,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;AAC9E,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC;AAChD,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;AACpD,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC;AAC1B,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC,UAAU,CAAC,EAAE;AACtC,CAAC,CAAC;AACF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC;AAChC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI;AACpG,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,aAAa,CAAC;AAC3B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU;AAC9D,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;AACxE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;AACnB;AACA,CAAC,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW;AAC7C,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,EAAE;AACxC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;AACpB,EAAE,EAAE,CAAC,MAAM,CAAC,UAAU;AACtB,EAAE,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC,EAAE;AAC9D,CAAC,CAAC;AACF;AACA,CAAC,IAAI,CAAC,QAAQ,GAAG;AACjB;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;AACpB,EAAE,EAAE,CAAC,OAAO,CAAC,aAAa,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC,QAAQ;AACvD,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACpD,GAAG,MAAM,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC,EAAE;AACpE,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE;AACX,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACT,EAAE,EAAE,CAAC,OAAO,CAAC,aAAa,CAAC,WAAW;AACtC,EAAE,IAAI,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC,EAAE;AACjE,CAAC,CAAC;AACF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC3D,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,CAAC,UAAU,CAAC,CAAC,SAAS,CAAC;AACnG,EAAE,YAAY,CAAC,CAAC,YAAY,CAAC,CAAC,cAAc,CAAC,CAAC,YAAY,CAAC,CAAC,kBAAkB,CAAC,CAAC,YAAY,CAAC;AAC7F,EAAE,eAAe,CAAC,CAAC,YAAY,CAAC,CAAC,aAAa,CAAC,CAAC,eAAe,CAAC;AAChE,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG;AAChB,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE;AAC3D,EAAE,wBAAwB,CAAC,CAAC,CAAC,CAAC;AAC9B,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,EAAE;AAClB,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,EAAE;AAClB,GAAG,MAAM,CAAC,CAAC,CAAC,KAAK,EAAE;AACnB,GAAG,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;AAClB,EAAE,EAAE;AACJ,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC;AACd,GAAG,GAAG,CAAC,CAAC,CAAC;AACT,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,SAAS,EAAE;AAC9B,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,QAAQ,CAAC;AAC7B,GAAG,EAAE;AACL,GAAG,GAAG,CAAC,CAAC,CAAC;AACT,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,QAAQ,EAAE;AAC7B,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,SAAS,CAAC;AAC9B,GAAG,CAAC;AACJ,EAAE,EAAE;AACJ,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC;AACnB,GAAG,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE;AACnB,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,EAAE;AAChB,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,EAAE;AACjB,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC;AACjB,EAAE,EAAE;AACJ,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;AACb,GAAG,QAAQ,CAAC,CAAC,CAAC,KAAK,EAAE;AACrB,GAAG,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE;AACpB,GAAG,SAAS,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;AAC9C,EAAE,EAAE;AACJ,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;AACb,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,EAAE;AACnB,GAAG,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE;AACpB,GAAG,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC;AACtB,EAAE,EAAE;AACJ;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;AAC1B,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,WAAW;AAC/D,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,oCAAoC,EAAE,CAAC,EAAE;AACrE,CAAC,CAAC;AACF,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE;AAChD;AACA,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY;AAC1F,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC,YAAY,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS;AAC/F,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;AACnB,EAAE,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;AACnD,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACrD,CAAC,CAAC,CAAC,EAAE;AACL;AACA,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC;AAC3D,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC;AACpC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;AAC5B,EAAE,aAAa,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC,aAAa,CAAC,EAAE;AAC5D,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,UAAU;AAC7G,CAAC,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE;AACpE,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE;AACvE,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACxE,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;AAClC,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE;AACrC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE;AAC1C,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,EAAE;AACxG;AACA,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,aAAa,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE;AACtD,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,EAAE;AACvE,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC;AACrE;AACA,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM;AACjB,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,SAAS,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AACtF,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK;AACxF,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;AAC1B,EAAE,CAAC,CAAC,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;AACpD,EAAE,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACpD;AACA,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,kBAAkB,CAAC,GAAG;AACpF,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,EAAE,kBAAkB,CAAC,MAAM,GAAG;AAClD,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,kBAAkB,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI;AAC/F,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,cAAc;AAC/F,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,YAAY,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC;AACnF,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACvB,EAAE,IAAI,EAAE,OAAO,CAAC,YAAY,GAAG,MAAM,GAAG;AACxC;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAC/B,EAAE,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,EAAE;AACtE,EAAE,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AACjD,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACT,EAAE,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAC7C,GAAG,IAAI,EAAE,OAAO,CAAC,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,GAAG,CAAC,EAAE;AAChF,EAAE,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AACjD,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AACvB,EAAE,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,kBAAkB;AACpG,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAClE,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE;AAChF;AACA,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK;AAChG,EAAE,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,KAAK,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,WAAW,CAAC,MAAM;AAC1G,EAAE,UAAU,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE;AACxD,EAAE,YAAY,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE;AACrE,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;AACvD,GAAG,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU;AAClF,GAAG,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC7D,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE;AACzD,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;AAC1E,GAAG,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ;AAC9E,GAAG,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC3D,IAAI,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE;AACrE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;AACV,GAAG,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAAC;AAC1B,EAAE,CAAC;AACH,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACT,EAAE,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAAC;AACzB,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS;AACjE,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC;AACnE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACvB,EAAE,IAAI,EAAE,SAAS,CAAC,MAAM,GAAG;AAC3B,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI;AACtF,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;AAC3D,EAAE,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,kBAAkB,GAAG;AAC/C,EAAE,YAAY,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,EAAE;AAClD,EAAE,YAAY,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC,GAAG,CAAC,EAAE;AAChD,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI;AACjG,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC;AAC7E,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC;AAC5E,CAAC,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACzE,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM;AAC5E,EAAE,kBAAkB,CAAC,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC5D,GAAG,CAAC,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;AACvE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC9E,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG;AAC3E,EAAE,kBAAkB,CAAC,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC3D,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE;AACzE,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AACvB,EAAE,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,kBAAkB;AAC/C,EAAE,YAAY,CAAC,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC;AAC3E;AACA,EAAE,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM;AACxB,EAAE,SAAS,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC;AACpC,EAAE,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,EAAE;AAChC,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM;AAC5B,CAAC,cAAc,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,kBAAkB,CAAC;AACtD;AACA,CAAC,MAAM,CAAC,cAAc,CAAC;AACvB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS;AACtB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE;AAChG,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE;AAC9B,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAC/D,CAAC,EAAE,CAAC,QAAQ,CAAC,SAAS;AACtB,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAClG,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC;AACrB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACT,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE;AACxB,CAAC,CAAC;AACF,CAAC,IAAI,CAAC,QAAQ,GAAG;AACjB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS;AACtB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE;AAClF,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE;AAC9B,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACxD,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC;AACnB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC;AACvC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC;AACjE,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AACjE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC5E,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE;AACrB,CAAC,CAAC;AACF,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC;AAC/B,CAAC,IAAI,CAAC,QAAQ,GAAG;AACjB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC;AACzB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC;AACzD,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACvD,CAAC,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC;AAC3B,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC;AAC3B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,aAAa,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO;AACzF,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG;AAC7F,CAAC,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ;AAC3D,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AACjE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC;AACvB;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AACpC,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC;AAC3B,CAAC,CAAC;AACF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC;AAC5D,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC;AAC5F,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,eAAe,CAAC,QAAQ,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO;AACvE,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;AAChF,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC;AAC1C,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG;AACzD,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC;AACnD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO;AAC9C,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACrD,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE;AAClC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AAC1B,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,GAAG;AACjC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE;AAC9B,CAAC,CAAC;AACF,CAAC,MAAM,CAAC,EAAE,CAAC;AACX,EAAE;;AChsBF,GAAG;AACH,CAAC,CAAC,CAAC,YAAY,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC,MAAM,EAAE;AACjG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI;AACjG,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;AAChG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC;AAC5D,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,QAAQ;AACZ,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO;AACjD,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,aAAa,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK;AACvD,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK;AAC9E,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,qBAAqB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACrE,CAAC,EAAE,CAAC,aAAa,CAAC,cAAc;AAChC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG;AACvB;AACA,CAAC,EAAE,CAAC,UAAU;AACd,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,EAAE,MAAM,CAAC;AAC9C,EAAE,CAAC;AACH,GAAG,SAAS,CAAC,CAAC,IAAI,CAAC;AACnB,GAAG,CAAC,kBAAkB,CAAC,CAAC,IAAI,EAAE,OAAO;AACrC,EAAE,EAAE;AACJ,EAAE,MAAM,CAAC,KAAK,CAAC;AACf,EAAE,CAAC;AACH,GAAG,CAAC,eAAe,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,EAAE,eAAe,CAAC,CAAC;AACvF,EAAE,CAAC;AACH,CAAC,CAAC,CAAC,EAAE;AACL,EAAE;AACF;AACA,EAAE,CAAC,OAAO,CAAC,EAAE;AACb;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC;AACb,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,KAAK,CAAC,MAAM;AAC3C,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC3D,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC;AACnB,EAAE;;ACxCF,GAAG;AACH,CAAC,CAAC,CAAC,kBAAkB,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,WAAW,EAAE;AACjG,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC,OAAO,CAAC;AAC9D,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,CAAC,OAAO;AACf,CAAC,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC;AACpC,CAAC,CAAC,KAAK,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAC;AACvD,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE;AAC9C,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE;AACxB,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC;AACnB,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC,EAAE;AAChE,CAAC,CAAC,aAAa,MAAM,CAAC,CAAC,IAAI,CAAC;AAC5B,CAAC,CAAC,aAAa,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC;AAClC,CAAC,CAAC,SAAS,CAAC;AACZ,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACX,CAAC,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC;AACvC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,WAAW,EAAE,OAAO,CAAC,EAAE;AAClD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY;AAC9B,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY;AACnC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO;AACjD,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK;AAC/G,CAAC,CAAC,EAAE,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,GAAG,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG;AAClH,CAAC,CAAC,EAAE,UAAU,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC;AAC9F,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE;AAChE,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAC,QAAQ,CAAC,qBAAqB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACpE,CAAC,EAAE,CAAC,aAAa,CAAC,cAAc;AAChC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG;AACvB;AACA,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AACrD;AACA,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AAC/C;AACA,CAAC,EAAE,CAAC,UAAU;AACd,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC;AAC7G;AACA,CAAC,EAAE,CAAC,MAAM;AACV,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE;AAC7C;AACA,CAAC,EAAE,CAAC,cAAc;AAClB,CAAC,IAAI,EAAE,OAAO;AACd,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,EAAE;AACzC,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO;AACpB,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC,CAAC;AAC9C,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;AACzE,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,EAAE;AAC9E,CAAC,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE;AAC7C,EAAE;AACF;AACA,EAAE,CAAC,KAAK,CAAC,EAAE;AACX;AACA,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,EAAE;AAC/D,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE;AACnE;AACA,EAAE,CAAC,OAAO,CAAC,EAAE;AACb;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC;AAC5C,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC1D,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG;AACrB,EAAE;;ACrEF,GAAG;AACH,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC;AACzE,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,WAAW,CAAC;AAC/E,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,CAAC,CAAC,CAAC,QAAQ;AACZ,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY;AACnC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO;AACjD,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACnE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AAC/C,EAAE;AACF;AACA,EAAE,CAAC,KAAK,CAAC,EAAE;AACX;AACA,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE;AACnE;AACA,EAAE,CAAC,OAAO,CAAC,EAAE;AACb;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC;AACxC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC;AAC7D,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM;AAC3C,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AACvE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;AACZ;AACA,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM;AACjB,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM;AAClF,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,EAAE;AAC3D;AACA,CAAC,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,WAAW;AAC/F,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACpB,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AACxD,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,cAAc,GAAG;AACpC,EAAE,CAAC;AACH,CAAC,CAAC;AACF;AACA,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;;AC/CF,GAAG;AACH,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC;AAClF,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI;AACxG,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,aAAa,CAAC;AACtC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,WAAW,CAAC;AAChF,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,CAAC,CAAC,CAAC,QAAQ;AACZ,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,mBAAmB,EAAE,CAAC,CAAC;AACzD,CAAC,EAAE;AACH,EAAE;AACF;AACA,EAAE,CAAC,OAAO,CAAC,EAAE;AACb;AACA,GAAG;AACH,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC;AAC/B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,WAAW,CAAC;AAC/D,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,QAAQ;AACvC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC3D,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE;AACxB,EAAE,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,UAAU,EAAE,CAAC,EAAE;AAClF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC;AAC3B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI;AAC3E,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACvE,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM;AACjB,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO;AACvF,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,EAAE;AAC7D;AACA,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM;AACnC,CAAC,IAAI,CAAC,cAAc,GAAG;AACvB;AACA,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;;AC/CF,GAAG;AACH,CAAC,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG;AACxF,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI;AAC3F,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW;AACpG,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,EAAE;AACrE,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,mBAAmB;AACvE,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM;AACxB,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,UAAU;AACjC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY;AACnC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,cAAc;AACrC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,kBAAkB;AACzC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO;AACjD,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAC1D,CAAC,EAAE,CAAC,aAAa,CAAC,cAAc;AAChC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG;AACvB;AACA,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AAChD;AACA,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AACrC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AAC/C,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AACjD,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AACrD;AACA,CAAC,EAAE,CAAC,UAAU;AACd,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC;AACvB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC;AAC1B,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC;AACtB;AACA,CAAC,EAAE,CAAC,cAAc;AAClB,CAAC,IAAI,EAAE,OAAO;AACd,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,EAAE,CAAC,IAAI,CAAC,CAAC;AACrC,EAAE,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO;AACrE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAC3B,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;AAC3B,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;AACnC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC;AACnC,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE;AACzB,EAAE;AACF;AACA,EAAE,CAAC,KAAK,CAAC,EAAE;AACX;AACA,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE;AACpD,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE;AAC5D,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE;AAC9D,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,EAAE;AAChE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,kBAAkB,CAAC,EAAE;AACpE;AACA,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE;AACvB;AACA,GAAG;AACH,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,WAAW,CAAC;AACzD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM;AACV,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC;AACtB,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC;AAC5C;AACA,GAAG;AACH,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,CAAC,cAAc,CAAC;AAC/D,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM;AACV,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC;AACtB,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC;AAC/C;AACA,GAAG;AACH,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC;AACvD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM;AACV,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC;AACtB,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC;AAC3C;AACA,GAAG;AACH,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC;AACtE,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM;AACV,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC;AACtB,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC,CAAC,KAAK,CAAC;AACzD;AACA,EAAE,CAAC,OAAO,CAAC,EAAE;AACb;AACA,GAAG;AACH,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,QAAQ,CAAC;AACvC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU;AACvC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACzD,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,GAAG;AACjF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM;AAChF,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM;AAC7E,CAAC,CAAC,CAAC,EAAE,CAAC,WAAW,CAAC;AAClB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,aAAa;AAC1C,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC5D,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,GAAG;AACpF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM;AAClF,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC;AACxD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS;AACtC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACxD,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,GAAG;AAChF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC;AACnC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ;AACrC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACvD,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC;AACtB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG;AACrE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC;AAC5D,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,WAAW;AACxC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC1D,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC;AACzB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM;AAC9E,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM;AAC5E,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC;AAC3E,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO;AACpC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACtD,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC;AACrB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS;AAClF,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE;AACrG,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC;AACjC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,MAAM;AAC/C,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAC/D,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;AAC5C,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC;AAC1B,EAAE,IAAI,EAAE,OAAO;AACf,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,CAAC;AACvD,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,EAAE;AAC9C,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC;AAClE,GAAG,IAAI,CAAC,qBAAqB,GAAG;AAChC,EAAE,CAAC;AACH,EAAE,IAAI,CAAC,kBAAkB,GAAG;AAC5B,CAAC,CAAC;AACF,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,YAAY;AACnE,CAAC,CAAC,CAAC,aAAa,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG;AAC1D,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE;AAClF,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC;AACjC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,MAAM;AAClD,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAClE,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;AAC/C,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC;AAC7B,EAAE,IAAI,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,EAAE;AACvE,EAAE,IAAI,CAAC,kBAAkB,GAAG;AAC5B,CAAC,CAAC;AACF,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,GAAG;AAClD,CAAC,CAAC,CAAC,YAAY,CAAC,aAAa,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG;AAC3E,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE;AAC1E,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC;AACjC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,MAAM;AAC9C,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAC9D,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AAC3C,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC;AACzB,EAAE,IAAI,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,EAAE;AACnE,EAAE,IAAI,CAAC,kBAAkB,GAAG;AAC5B,CAAC,CAAC;AACF,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC;AAC5C,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,UAAU;AACpE,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC;AACtD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO;AACjE,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACzD,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,GAAG;AAC7B,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,GAAG;AAC/D,EAAE;;AChOF,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;AAClG,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,kBAAkB,CAAC,MAAM,CAAC,OAAO,EAAE;AAC7E,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB;AACnF,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE;AACjB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,qBAAqB,CAAC,CAAC,GAAG,CAAC,IAAI;AACtG,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,EAAE;AACpE,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,CAAC,OAAO;AACf,CAAC,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO;AACvD,CAAC,CAAC,KAAK,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC;AAC7C,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC;AACnB,CAAC,CAAC,aAAa,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC;AACxC,CAAC,CAAC,iBAAiB,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE;AAC7B,CAAC,CAAC,iBAAiB,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,EAAE;AACvC,CAAC,CAAC,aAAa,CAAC,CAAC,EAAE;AACnB,CAAC,CAAC,aAAa,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC;AACxC,CAAC,CAAC,iBAAiB,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE;AAC7B,CAAC,CAAC,iBAAiB,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,EAAE;AACvC,CAAC,CAAC,aAAa,CAAC,CAAC,EAAE;AACnB,CAAC,CAAC,aAAa,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC;AACxC,CAAC,CAAC,iBAAiB,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE;AAC7B,CAAC,CAAC,iBAAiB,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,EAAE;AACzC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,SAAS,CAAC;AACZ,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACX,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE;AAC7C,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,mBAAmB;AACvE,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,QAAQ;AACZ,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM;AACxB,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW;AAClC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO;AACjD,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC;AAChF,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG;AACjF,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC;AAC3D,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,mBAAmB;AACxE,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAC1D,CAAC,EAAE,CAAC,aAAa,CAAC,cAAc;AAChC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG;AACvB;AACA,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AAChD;AACA,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;AACzF;AACA,CAAC,EAAE,CAAC,UAAU;AACd,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC;AACtB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC;AACvB,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AACrD,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AACzD,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AACrD,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AACvD,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,GAAG;AAC1B,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC,IAAI,CAAC;AACjC,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,CAAC;AAC/B;AACA,CAAC,EAAE,CAAC,MAAM;AACV,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;AACtB,EAAE,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC;AACpB,CAAC,CAAC,CAAC,EAAE;AACL,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;AACpB,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AACrC,EAAE,SAAS,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AAC3C,EAAE,SAAS,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AAC3C,EAAE,UAAU,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC;AAC5C,CAAC,CAAC,CAAC,EAAE;AACL;AACA,CAAC,EAAE,CAAC,cAAc;AAClB,CAAC,IAAI,EAAE,OAAO;AACd,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,CAAC;AAChE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE;AAC7B,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE;AACrC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACvC,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;AAChC,CAAC,CAAC;AACF,EAAE;AACF;AACA,EAAE,CAAC,KAAK,CAAC,EAAE;AACX;AACA,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE;AACpD,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE;AAC7D;AACA,EAAE,CAAC,MAAM,CAAC,EAAE;AACZ;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS;AACnB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC;AAC/F,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI;AACzD,CAAC,EAAE;AACH;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK;AACf,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,gBAAgB,CAAC,MAAM,CAAC,GAAG;AAC/F,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC;AAC9B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI;AACrD,CAAC,EAAE;AACH;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM;AAChB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,QAAQ,CAAC,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC;AAC3G,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI;AACtD,CAAC,EAAE;AACH;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM;AAChB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC;AAClF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI;AAC/C,CAAC,EAAE;AACH;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG;AACb,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC;AAC5F,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK;AAClD,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,SAAS,CAAC,KAAK;AACjD,CAAC,EAAE;AACH;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM;AAChB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,UAAU;AAC5F,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC;AAC3B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK;AACpD,CAAC,EAAE;AACH;AACA,EAAE,CAAC,OAAO,CAAC,EAAE;AACb;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM;AACtB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK;AAC9B,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAC3D,CAAC,GAAG,CAAC,IAAI,CAAC;AACV,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC7C,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC;AAC9D,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC;AAC1E,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC,CAAC;AACnC,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,uBAAuB,GAAG;AACzC,EAAE,CAAC;AACH,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACT,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACvC,GAAG,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE;AACtE,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,UAAU,CAAC;AAC1E,GAAG,EAAE,CAAC,aAAa,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;AACjF,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,KAAK,CAAC,EAAE;AACvC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;AACV,GAAG,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,GAAG;AAC7F,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE;AAChG,GAAG,MAAM,CAAC;AACV,EAAE,CAAC;AACH,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACd,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;AAChD,GAAG,IAAI,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,EAAE;AAC9B,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;AACV,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,EAAE;AAC3B,EAAE,CAAC;AACH,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC7C,EAAE,IAAI,EAAE,UAAU,CAAC,KAAK,GAAG;AAC3B,CAAC,CAAC;AACF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC;AAC5B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK;AAC3C,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC3D,CAAC,GAAG,CAAC,IAAI,CAAC;AACV;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACnE,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,EAAE;AAC7B,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,EAAE;AAClC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,CAAC;AACtC,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,EAAE;AAC1B,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC;AACzB,GAAG,IAAI,CAAC,kBAAkB,GAAG,gBAAgB,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,EAAE;AACxF,GAAG,IAAI,CAAC,kBAAkB,GAAG,gBAAgB,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,EAAE;AAC5F,EAAE,CAAC;AACH,CAAC,CAAC;AACF,CAAC,MAAM,CAAC,KAAK,CAAC;AACd,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC;AAC1B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK;AACvC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACzD,CAAC,GAAG,CAAC,IAAI,CAAC;AACV;AACA,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,KAAK,CAAC,EAAE;AAC7B,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AACzB,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,EAAE;AAClC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,CAAC;AACtC,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC;AACzB,EAAE,CAAC;AACH,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AACrF,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,EAAE;AACzB,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE;AACpC,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC;AACxB,CAAC,CAAC;AACF;AACA,CAAC,IAAI,CAAC,kBAAkB,GAAG,mBAAmB,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,EAAE;AACzF,CAAC,IAAI,CAAC,kBAAkB,GAAG,mBAAmB,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,EAAE;AAC7F;AACA,CAAC,MAAM,CAAC,KAAK,CAAC;AACd,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC;AAC5B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK;AACzC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC3D,CAAC,GAAG,CAAC,IAAI,CAAC;AACV;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AAC5C,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,EAAE;AAClC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,CAAC;AACjE,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,EAAE;AAC1B,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC;AACzB,EAAE,CAAC;AACH,CAAC,CAAC;AACF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC;AAC5B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK;AAC3C,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC3D,CAAC,GAAG,CAAC,IAAI,CAAC;AACV,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC;AACnC,EAAE,MAAM,CAAC;AACT,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC;AAC5B,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,EAAE;AAClC,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE;AACrE,CAAC,CAAC;AACF,CAAC,MAAM,CAAC,KAAK,CAAC;AACd,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC;AAC7B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK;AAC3C,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACzD,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC;AAC5B,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,EAAE;AAC7B,CAAC,CAAC;AACF,CAAC,MAAM,CAAC,KAAK,CAAC;AACd,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC;AAC1B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK;AAC1C,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACzD,CAAC,GAAG,CAAC,QAAQ,CAAC;AACd,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC;AAClB,EAAE,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,mBAAmB,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,gBAAgB,GAAG;AACtE;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC;AAChD,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AACxB,GAAG,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC;AACzB,IAAI,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE,CAAC,WAAW,CAAC,WAAW,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;AACxE,KAAK,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC;AAC7E,KAAK,IAAI,CAAC,UAAU,CAAC,CAAC,WAAW,CAAC,EAAE;AACpC,KAAK,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;AACpB,IAAI,CAAC;AACL,IAAI,KAAK,CAAC;AACV,GAAG,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;AACtB,GAAG,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC;AACxB,IAAI,IAAI,CAAC,mBAAmB,GAAG;AAC/B,IAAI,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;AAClE,IAAI,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;AACnB,IAAI,KAAK,CAAC;AACV,GAAG,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC;AACxB,GAAG,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC;AACzB,IAAI,IAAI,CAAC,mBAAmB,GAAG;AAC/B,IAAI,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE;AACjE,IAAI,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;AACnB,IAAI,KAAK,CAAC;AACV,GAAG,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC;AAC1B,GAAG,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC;AACvB,IAAI,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE,CAAC,WAAW,CAAC,WAAW,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;AACxE,KAAK,WAAW,CAAC,cAAc,CAAC,CAAC,KAAK,CAAC,EAAE;AACzC,IAAI,CAAC;AACL,IAAI,IAAI,CAAC,qBAAqB,GAAG;AACjC,IAAI,IAAI,CAAC,sBAAsB,GAAG;AAClC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU;AAC9C,IAAI,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC;AACpB,IAAI,KAAK,CAAC;AACV,EAAE,CAAC;AACH;AACA,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AACnB,GAAG,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;AACrD,IAAI,IAAI,CAAC,aAAa,CAAC,CAAC,QAAQ,CAAC,EAAE;AACnC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC;AACX,IAAI,IAAI,CAAC,UAAU,CAAC,CAAC,QAAQ,CAAC,EAAE;AAChC,GAAG,CAAC;AACJ,GAAG,IAAI,CAAC,kBAAkB,CAAC,CAAC,QAAQ,CAAC,EAAE;AACvC,EAAE,CAAC;AACH;AACA,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AAClB,GAAG,CAAC,CAAC,cAAc,GAAG;AACtB,GAAG,CAAC,CAAC,eAAe,GAAG;AACvB,EAAE,CAAC;AACH,CAAC,CAAC;AACF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC;AAC1B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAChE,CAAC,IAAI,CAAC,gBAAgB,GAAG,gBAAgB,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,EAAE;AACpF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC;AAC5B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,qBAAqB,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAClE,CAAC,IAAI,CAAC,gBAAgB,GAAG,mBAAmB,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,EAAE;AACvF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC;AACrF,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI;AAC5D,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACrE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;AACnB,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,SAAS;AACnG,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC;AAC/C,CAAC,IAAI,CAAC,oBAAoB,GAAG;AAC7B,CAAC,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACjD,EAAE,UAAU,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC3B,GAAG,MAAM,CAAC,oBAAoB,GAAG;AACjC,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE;AACX,CAAC,CAAC,CAAC,EAAE;AACL,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM;AAC7B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAChE,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC;AAClC,EAAE,YAAY,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,EAAE;AAC3C,EAAE,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC,IAAI,CAAC;AAClC,CAAC,CAAC;AACF,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,GAAG;AAC1B,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC;AAC3B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK;AAC3C,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC1D,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC;AACrB;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AACrB,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAC3E,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;AACzF,GAAG,MAAM,CAAC,KAAK,CAAC;AAChB,EAAE,CAAC;AACH,EAAE,MAAM,CAAC;AACT,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;AAC9B,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE;AACzC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACT,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE;AACxC,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC;AAClC,EAAE,YAAY,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,EAAE;AAC3C,CAAC,CAAC;AACF,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE;AACtF;AACA,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,mBAAmB,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,gBAAgB,GAAG;AAC9D;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACnC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG;AACzE,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;AAClC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACf,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE;AACrD,EAAE,CAAC;AACH,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACT,EAAE,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC,CAAC;AAC3B,CAAC,CAAC;AACF;AACA,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,KAAK,CAAC,EAAE;AAC5D,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAClC,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE;AAC5D,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACd,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;AACpE,GAAG,IAAI,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,EAAE;AAC9B,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;AACV,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,EAAE;AAC3B,EAAE,CAAC;AACH,EAAE,IAAI,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,EAAE;AAClC,CAAC,CAAC;AACF;AACA,CAAC,CAAC,CAAC,cAAc,GAAG;AACpB,CAAC,CAAC,CAAC,eAAe,GAAG;AACrB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM;AACxC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK;AAClD,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO;AAC3D,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO;AAChE,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACrE,CAAC,GAAG,CAAC,EAAE,CAAC;AACR;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AACrB,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,GAAG;AACpB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;AAChD,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;AACzF,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACf,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI;AAChB,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;AAC5B,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAC3B,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,GAAG;AACtC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AAC9B,GAAG,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,SAAS,GAAG;AACrC,EAAE,CAAC;AACH,EAAE,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,EAAE;AAC9B,CAAC,EAAE;AACH,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC;AAC3B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACjE,CAAC,IAAI,CAAC,gBAAgB,GAAG,gBAAgB,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,EAAE;AACtF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC;AAC5B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,mBAAmB,EAAE,CAAC,IAAI,CAAC,IAAI;AAC7E,CAAC,CAAC,CAAC,cAAc,CAAC;AAClB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,sBAAsB,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACnE,CAAC,IAAI,CAAC,gBAAgB,GAAG,mBAAmB,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,EAAE;AACzF,CAAC,IAAI,CAAC,mBAAmB,GAAG;AAC5B,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,OAAO;AAC5B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO;AAC3B,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AAC9D,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AAClB,EAAE,IAAI,CAAC,mBAAmB,GAAG;AAC7B,CAAC,CAAC;AACF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;AAC1C,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;AAC1B,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK;AAClF,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC9D,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE;AAC9D,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACvE,EAAE,MAAM,CAAC,IAAI,CAAC;AACd,CAAC,CAAC;AACF,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC;AACrD,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;AACtB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ;AACjF,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC7D,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;AACZ;AACA,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AACvD,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC;AACvC,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE;AAC1B,EAAE,CAAC;AACH,CAAC,CAAC;AACF,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;AACzB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,WAAW;AACvF,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAChE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;AACZ;AACA,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AACvD,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,CAAC;AAC1C,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE;AAC1B,EAAE,CAAC;AACH,CAAC,CAAC;AACF,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC;AACxB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG;AACvE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,QAAQ;AAC7F,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC;AACrC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO;AACtD,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AACnE,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AAC/B,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC;AAC1B,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AAClC,EAAE,IAAI,EAAE,OAAO;AACf,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,CAAC;AACxD,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE;AAC5D,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC;AACzB,CAAC,CAAC;AACF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,WAAW;AACtF,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC;AACnF,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,SAAS;AAC9E,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS;AACnB,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAChE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,WAAW,CAAC;AACzB,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC;AAClB;AACA,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AACvD,EAAE,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC;AACzC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;AAC1D,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC,WAAW,CAAC,EAAE;AACjD,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;AAClB,EAAE,CAAC;AACH,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AACjB,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACf,GAAG,IAAI,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,EAAE;AACzE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;AACV,GAAG,IAAI,EAAE,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,EAAE;AAC1D,EAAE,CAAC;AACH,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,EAAE;AACjC,CAAC,CAAC;AACF;AACA,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC;AAC9B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC;AACrD,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO;AACtF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM;AACjF,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAC5E,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC;AACpB,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;AAC1B,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,EAAE;AAC9C;AACA,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAC9B,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE;AACzB,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,EAAE,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACtF,GAAG,MAAM,CAAC,IAAI,CAAC;AACf,EAAE,CAAC;AACH,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAChB,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;AACf,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,EAAE;AAC/C,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAC/B,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE;AAC1B,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,EAAE,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACvF,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAClB,KAAK,MAAM,CAAC,IAAI,CAAC;AACjB,IAAI,CAAC;AACL,IAAI,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;AACjB,GAAG,CAAC;AACJ,EAAE,CAAC;AACH,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAChB,GAAG,MAAM,CAAC,KAAK,CAAC;AAChB,EAAE,CAAC;AACH,CAAC,CAAC;AACF;AACA,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC;AAC9E,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC;AAClC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC;AACvD,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO;AACtF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM;AAChB,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAC7E,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE;AAC9D,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;AAC/C,EAAE,MAAM,CAAC,IAAI,CAAC,UAAU,GAAG;AAC3B,CAAC,CAAC;AACF,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,aAAa,CAAC,EAAE;AACzC,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,OAAO,CAAC;AACrF,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC;AACjE,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG;AAClF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM;AAChB,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACnE,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,EAAE;AAClD,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;AAC7C,EAAE,MAAM,CAAC,IAAI,CAAC,UAAU,GAAG;AAC3B,CAAC,CAAC;AACF,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,YAAY,CAAC,EAAE;AACxC,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,OAAO,CAAC;AAC1F,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC;AAClC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG;AAC1E,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM;AAChB,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAC7D,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC;AACtB,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC;AAClB;AACA,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AACvD,EAAE,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC;AACtC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AACpD,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,QAAQ,CAAC,EAAE;AAC3C,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;AAClB,EAAE,CAAC;AACH,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AACjB,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;AACzD,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAChB,IAAI,IAAI,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,EAAE;AAC1E,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC;AACX,IAAI,IAAI,EAAE,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,EAAE;AAC3D,GAAG,CAAC;AACJ,EAAE,CAAC;AACH,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE;AAC9B,CAAC,CAAC;AACF;AACA,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC;AACjB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG;AAC/E,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI;AACpG,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC;AACtB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG;AACxE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK;AACf,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAC5D,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC;AACrB,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC;AAClB;AACA,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AACvD,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC;AACrC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AAClD,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,OAAO,CAAC,EAAE;AACzC,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;AAClB,EAAE,CAAC;AACH,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AACjB,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,EAAE;AAC7B,CAAC,CAAC;AACF;AACA,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC;AAClB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM;AAClF,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,gBAAgB,CAAC;AACpG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC;AAC9B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM;AAClG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,KAAK,CAAC;AACxD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM;AAClD,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM;AAChB,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAC7D,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACd,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,EAAE;AAC1B,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE;AAC9B,CAAC,CAAC;AACF;AACA,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC;AACtG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;AACpG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE;AAC9F,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC;AAC/C,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC;AAC/H,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO;AACzF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO;AACjF,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC;AACrE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM;AACjG,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,0BAA0B,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAChG,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AAChC,EAAE,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACpC,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;AAC1B;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;AAC5C,EAAE,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE;AAC5C,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;AACtD,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACT,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC;AACvE,EAAE,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC;AAC1C,EAAE,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AAC1C,CAAC,CAAC;AACF;AACA,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAC9B,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,EAAE;AACjC,EAAE,EAAE,CAAC,CAAC;AACN,GAAG,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,EAAE,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,EAAE;AAC/D,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAChC,EAAE,CAAC,CAAC,CAAC;AACL,GAAG,MAAM,CAAC,IAAI,CAAC;AACf,EAAE,CAAC;AACH,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;AACnD,CAAC,CAAC;AACF,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC;AAC5E,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC;AAC3E,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK;AACtF,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,uBAAuB,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACpE,CAAC,MAAM,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE;AACnD,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE;AACpF,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC;AAC9B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG;AACnD,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK;AACtD,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG;AACb,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACnE,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM;AAChB,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,EAAE;AACvE;AACA,CAAC,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO;AACnD,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE;AAC/F;AACA,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ;AAClF,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI;AACrF,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,OAAO,CAAC;AAClE,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM;AACtD,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM;AAChB,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAC/D,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;AAClB;AACA,CAAC,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO;AAChC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAClD,EAAE,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE;AACpB,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC;AAC5B,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,EAAE;AAC3B,EAAE,CAAC;AACH,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM;AAChB,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,EAAE;AACnE;AACA,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,EAAE;AAC9B;AACA,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC;AACzF,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG;AACvF,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC;AAC3B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM;AAChB,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACvD,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG;AAChC;AACA,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM;AAChB,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AAC3D;AACA,CAAC,EAAE,CAAC,KAAK,CAAC,SAAS;AACnB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,EAAE;AACzB;AACA,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,EAAE;AAC9B;AACA,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC;AAC5F,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;AACpE,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,UAAU;AAC9B,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;AACvE,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC;AAChC,EAAE;;AC73BF,GAAG;AACH,CAAC,CAAC,CAAC,sBAAsB,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,UAAU;AACvF,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,SAAS,EAAE;AACtG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,QAAQ,CAAC,SAAS;AACzF,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG;AAC1E,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,EAAE;AACxC,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,CAAC,OAAO;AACf,CAAC,CAAC,KAAK,EAAE,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM;AAC9C,CAAC,CAAC,KAAK,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC;AAC7C,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC;AACnB,CAAC,CAAC,aAAa,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,qBAAqB,CAAC,CAAC,CAAC;AACjD,CAAC,CAAC,iBAAiB,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE;AAC7B,CAAC,CAAC,iBAAiB,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE;AAC7C,CAAC,CAAC,iBAAiB,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AAC/B,CAAC,CAAC,aAAa,CAAC,CAAC,EAAE;AACnB,CAAC,CAAC,aAAa,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,qBAAqB,CAAC,CAAC,CAAC;AACjD,CAAC,CAAC,iBAAiB,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE;AAC7B,CAAC,CAAC,iBAAiB,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE;AAClD,CAAC,CAAC,iBAAiB,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC;AACpC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,SAAS,CAAC;AACZ,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACX,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE;AAC7C,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,mBAAmB;AACvE,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY;AAC9B,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW;AAClC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB;AACvC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO;AACjD,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,qBAAqB,CAAC,CAAC,CAAC,QAAQ,CAAC,yBAAyB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAC5E,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,qBAAqB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AACzD;AACA,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AAC9C,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AACnD;AACA,CAAC,EAAE,CAAC,cAAc;AAClB,CAAC,IAAI,EAAE,OAAO;AACd,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,qBAAqB,CAAC,CAAC,CAAC;AAC5C,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;AACxB,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE;AAC7B,EAAE;AACF;AACA,EAAE,CAAC,KAAK,CAAC,EAAE;AACX;AACA,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,qBAAqB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,EAAE;AACnE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,qBAAqB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE;AACtE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,qBAAqB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,EAAE;;ACtD3E,GAAG;AACH,CAAC,CAAC,CAAC,gBAAgB,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI;AAC3F,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,GAAG;AACpF,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC;AAClE,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,mBAAmB,CAAC,wBAAwB;AAChG,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,qBAAqB;AACvC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO;AACjD,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC,QAAQ,CAAC,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAClE,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AACpD;AACA,CAAC,EAAE,CAAC,UAAU;AACd,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;AACzC,EAAE,IAAI,CAAC,CAAC,CAAC,KAAK,EAAE;AAChB,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC,CAAC;AACjD,CAAC,CAAC,CAAC,EAAE;AACL;AACA,CAAC,EAAE,CAAC,cAAc;AAClB,CAAC,IAAI,EAAE,OAAO;AACd,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;AACrC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,EAAE;AACxC,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,qBAAqB,CAAC,EAAE;AACvE;AACA,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE;AACvB;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,MAAM;AACV,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC,CAAC,IAAI,CAAC;;ACvC5D,GAAG;AACH,CAAC,CAAC,CAAC,wBAAwB,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO;AAC3H,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,wBAAwB,CAAC,MAAM,CAAC,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,QAAQ,CAAC;AAC3G,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,CAAC,OAAO;AACf,CAAC,CAAC,KAAK,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC;AACnD,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,aAAa,KAAK,CAAC,CAAC,CAAC;AACvB,CAAC,CAAC,iBAAiB,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,uBAAuB,CAAC,CAAC,CAAC;AACvD,CAAC,CAAC,qBAAqB,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;AACpC,CAAC,CAAC,iBAAiB,CAAC,CAAC,EAAE;AACvB,CAAC,CAAC,iBAAiB,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC;AAChD,CAAC,CAAC,qBAAqB,IAAI,CAAC,CAAC,CAAC,KAAK,EAAE;AACrC,CAAC,CAAC,qBAAqB,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC;AAC3C,CAAC,CAAC,iBAAiB,CAAC,CAAC,EAAE;AACvB,CAAC,CAAC,iBAAiB,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC;AAChD,CAAC,CAAC,qBAAqB,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE;AACtC,CAAC,CAAC,qBAAqB,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC;AAC/C,CAAC,CAAC,iBAAiB,CAAC,CAAC,EAAE;AACvB,CAAC,CAAC,iBAAiB,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,uBAAuB,CAAC,CAAC,CAAC;AACvD,CAAC,CAAC,qBAAqB,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;AACpC,CAAC,CAAC,iBAAiB,CAAC,CAAC,EAAE;AACvB,CAAC,CAAC,iBAAiB,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC;AAChD,CAAC,CAAC,qBAAqB,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE;AACpC,CAAC,CAAC,qBAAqB,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;AACpC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC;AACtB,CAAC,CAAC,aAAa,CAAC;AAChB,CAAC,CAAC,SAAS,CAAC;AACZ,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACX,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,UAAU,EAAE,OAAO,CAAC,EAAE;AACjD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,qBAAqB;AACvC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO;AACjD,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,uBAAuB,CAAC,CAAC,CAAC,QAAQ,CAAC,2BAA2B,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAChF,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,uBAAuB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AAC3D;AACA,CAAC,EAAE,CAAC,cAAc;AAClB,CAAC,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,uBAAuB,CAAC,CAAC,CAAC;AAC1D,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE;AACtC,EAAE;AACF;AACA,EAAE,CAAC,KAAK,CAAC,EAAE;AACX;AACA,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,uBAAuB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,qBAAqB,CAAC,EAAE;AAC9E;AACA,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE;AACvB;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,MAAM;AACV,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,uBAAuB,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC;AACxD;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,MAAM;AACV,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,uBAAuB,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC;;AC9D3D,GAAG;AACH,CAAC,CAAC,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG;AAC3F,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC;AAClG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,cAAc,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,mBAAmB,EAAE;AAC1G,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;AAClG,CAAC,CAAC,CAAC,iBAAiB,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,UAAU;AAChF,CAAC,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,MAAM,CAAC;AAChE,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG;AACpG,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;AAC1B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,WAAW,CAAC;AACpD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM;AACtD,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM;AACrD,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM;AACnD,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI;AAC3B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,gBAAgB,CAAC,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC;AAClG,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC;AAC5E,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,mBAAmB;AACvE,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY;AAC9B,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB;AACvC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB;AACvC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO;AACjD,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK;AAClH,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,mBAAmB,CAAC;AACzG,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,aAAa,CAAC;AACvD,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK;AACpG,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,wBAAwB,CAAC,wBAAwB,CAAC;AACnH,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK;AAC5G,CAAC,CAAC,EAAE,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM;AACtG,CAAC,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM;AAC3G,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC;AAC5E,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;AAC3F,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,eAAe,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC;AAC5F,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,CAAC;AACpF,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK;AACrF,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS;AAC/E,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI;AAC1C,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC,QAAQ,CAAC,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAClE,CAAC,EAAE,CAAC,aAAa,CAAC,cAAc;AAChC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG;AACvB;AACA,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AACpD;AACA,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;AAChG,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AACnD;AACA,CAAC,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE;AACjE,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC;AACzE,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC;AAC5D,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC;AACvD;AACA,CAAC,EAAE,CAAC,UAAU;AACd,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC;AACpE,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,YAAY,CAAC;AAChF,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,eAAe,CAAC;AACjD,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;AACzF,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;AAC9D,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC,CAAC,MAAM,EAAE,eAAe,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE;AAC5D,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AACzE,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE;AACzF,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,iBAAiB,CAAC;AACrD,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;AAC3B;AACA,CAAC,EAAE,CAAC,cAAc;AAClB,CAAC,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,EAAE;AACpD,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACvB,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,EAAE;AAClD,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO;AAChG,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,YAAY;AACvF,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK;AAC5D,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC;AACtB,CAAC,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE;AAClD,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,YAAY,CAAC,EAAE;AAC9D,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,EAAE;AACtE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,EAAE;AACtE;AACA,EAAE,CAAC,MAAM,CAAC,EAAE;AACZ;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK;AACf,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC;AACxE,CAAC,EAAE;AACH;AACA,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE;AACvB;AACA,GAAG;AACH,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG;AACpE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC;AAChC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE;AACrC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC;AAClD,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,EAAE;AAChB,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,EAAE;AAChB,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE;AACf,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC;AACd,EAAE;AACF;AACA,EAAE,CAAC,OAAO,CAAC,EAAE;AACb;AACA,GAAG;AACH,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC;AACtC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK;AACzC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACvE,CAAC,EAAE,CAAC,CAAC;AACL,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,EAAE;AACrB,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC;AAClB,GAAG,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,eAAe,CAAC,EAAE,GAAG,GAAG;AACxE,GAAG,CAAC,CAAC,MAAM,CAAC;AACZ,GAAG,IAAI;AACP,EAAE,CAAC;AACH,CAAC,CAAC,CAAC,CAAC;AACJ,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,EAAE;AACvB,CAAC,CAAC;AACF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC7D,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,mBAAmB,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,gBAAgB,GAAG;AACzE;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC;AAChD,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AACxB,GAAG,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC;AACxB,GAAG,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC;AACzB,IAAI,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,QAAQ;AACpF,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;AACzB,KAAK,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE;AACvE,IAAI,CAAC;AACL,IAAI,KAAK,CAAC;AACV,GAAG,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC;AAC1B,GAAG,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC;AACvB,IAAI,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;AACxB,KAAK,WAAW,CAAC,cAAc,CAAC,CAAC,KAAK,CAAC,EAAE;AACzC,IAAI,CAAC;AACL,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,EAAE;AACzB,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,UAAU;AACrD,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAC5C,KAAK,CAAC,CAAC,cAAc,GAAG;AACxB,KAAK,CAAC,CAAC,eAAe,GAAG;AACzB,IAAI,CAAC;AACL,IAAI,KAAK,CAAC;AACV,GAAG,OAAO,CAAC;AACX,IAAI,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE;AACtE,IAAI,MAAM,CAAC;AACX,EAAE,CAAC;AACH,CAAC,CAAC;AACF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,eAAe,CAAC,EAAE,CAAC,OAAO,CAAC;AAC/F,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE;AAC9C,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACrE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC,WAAW,CAAC;AACzE,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC;AACrB,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;AAC1B,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,GAAG;AAC9B,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC;AACrB;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;AAC7C,EAAE,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE;AACrE,EAAE,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,EAAE;AAC/D,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO;AAC5E,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC;AACjC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAC/B,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE;AAC1B,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,EAAE,CAAC,uBAAuB,CAAC,CAAC,CAAC,CAAC;AACzD,IAAI,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AACpB,KAAK,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM;AAC1D,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,YAAY,CAAC,EAAE;AAChD,IAAI,CAAC;AACL,IAAI,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;AACnB,IAAI,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC;AACxB,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;AACrD,IAAI,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE;AACxC,IAAI,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,EAAE;AACnD,IAAI,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE,CAAC,OAAO,CAAC;AACvC,IAAI,YAAY,CAAC,CAAC,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC;AAC5C,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE;AAC3B,GAAG,CAAC;AACJ,EAAE,CAAC;AACH,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO;AAC9B,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AAClB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,YAAY,CAAC,EAAE;AAC9C,EAAE,CAAC;AACH;AACA,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;AACzD,GAAG,IAAI,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;AAC9C,EAAE,CAAC;AACH;AACA,EAAE,IAAI,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,SAAS,EAAE,CAAC,CAAC,UAAU,CAAC,EAAE;AAC/E;AACA,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC;AACjC,GAAG,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI;AAC1C,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AACf,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,GAAG;AAC3B,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AACzC,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC;AACnC,KAAK,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE;AACvB,KAAK,KAAK,CAAC;AACX,IAAI,CAAC;AACL,GAAG,CAAC;AACJ,GAAG,IAAI,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,EAAE;AAC9B,EAAE,CAAC;AACH;AACA,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ;AACvB,CAAC,IAAI,CAAC,IAAI,GAAG;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACpE,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;AACrB,EAAE,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,gBAAgB,CAAC,EAAE;AACrD,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACT,EAAE,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AAC3E,CAAC,CAAC;AACF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,SAAS,CAAC,qBAAqB,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACtE,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;AACrB,EAAE,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,gBAAgB,CAAC,EAAE;AACtD,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACT,EAAE,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AAC7E,CAAC,CAAC;AACF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACrE,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;AACrB,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;AAC/B,GAAG,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,kBAAkB,CAAC,EAAE;AAC9F,GAAG,IAAI,CAAC,oBAAoB,GAAG;AAC/B,EAAE,CAAC;AACH,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACT,EAAE,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AAC5E,CAAC,CAAC;AACF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,SAAS,CAAC,sBAAsB,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACvE,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;AACrB,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;AAC/B,GAAG,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,kBAAkB,CAAC,EAAE;AAC/F,GAAG,IAAI,CAAC,oBAAoB,GAAG;AAC/B,EAAE,CAAC;AACH,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACT,EAAE,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,sBAAsB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AAC9E,CAAC,CAAC;AACF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC;AAClB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC;AAC1G,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ;AAC9G,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC;AACpG,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM;AAClD,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACjE,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AACvE,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;AAC3B,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,EAAE;AACvB,CAAC,CAAC;AACF,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACvE,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM;AACjB,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,EAAE;AAC7E;AACA,CAAC,IAAI,CAAC,oBAAoB,GAAG;AAC7B;AACA,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACnE,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM;AACjB,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,EAAE;AACzE;AACA,CAAC,IAAI,CAAC,oBAAoB,GAAG;AAC7B;AACA,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC3D,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM;AACjB,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AACjE;AACA,CAAC,IAAI,CAAC,oBAAoB,GAAG;AAC7B;AACA,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO;AAC3F,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC;AAChE,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC,QAAQ,CAAC,EAAE,CAAC,OAAO;AACjG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC;AAChG,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM;AAC5F,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC;AACtF,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK;AACf,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AAChE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,cAAc,CAAC,CAAC,aAAa,CAAC;AAC3C;AACA,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;AACxF,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,GAAG;AACvC;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,iBAAiB,EAAE,CAAC,CAAC,CAAC,CAAC;AACxE,EAAE,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,EAAE;AACxH,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,IAAI,CAAC;AAC/B,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AAC3B,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI;AAC3F,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE;AACjC,EAAE,IAAI,CAAC,mBAAmB,CAAC,CAAC,IAAI,CAAC,wBAAwB,CAAC,EAAE;AAC5D,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM;AACjB,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,EAAE;AACtE;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAChB,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AAClB;AACA,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACtB,IAAI,IAAI,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE;AACpC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,kBAAkB,CAAC,CAAC,CAAC,CAAC;AAC3C,IAAI,IAAI,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE;AAC3C,IAAI,IAAI,CAAC,YAAY,CAAC;AACtB,KAAK,IAAI,EAAE,kBAAkB,CAAC,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC;AACnF,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK;AAC3D,MAAM,IAAI,EAAE,kBAAkB,CAAC,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC;AACjD,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI;AACpD,MAAM,CAAC,IAAI,CAAC;AACZ,IAAI,EAAE;AACN,IAAI,IAAI,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE;AACvC,GAAG,CAAC;AACJ;AACA,GAAG,IAAI,CAAC,iBAAiB,CAAC,CAAC,EAAE,IAAI,EAAE,kBAAkB,CAAC,EAAE;AACxD,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,EAAE;AAC/B;AACA,GAAG,IAAI,CAAC,mBAAmB,GAAG;AAC9B,GAAG,IAAI,CAAC,oBAAoB,GAAG;AAC/B;AACA,GAAG,EAAE,CAAC,CAAC;AACP,IAAI,CAAC,CAAC,IAAI,CAAC,mBAAmB,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,oBAAoB,EAAE,CAAC,CAAC,CAAC,EAAE;AACpE,IAAI,IAAI,CAAC,wBAAwB,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC;AAC9C,GAAG,CAAC,CAAC,CAAC;AACN,IAAI,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE;AAC5E,IAAI,cAAc,CAAC,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,MAAM,GAAG;AAC5C,IAAI,IAAI,CAAC,mBAAmB,CAAC;AAC7B,KAAK,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;AAC9E,IAAI,EAAE;AACN,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,mBAAmB,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,oBAAoB,EAAE,CAAC,CAAC,CAAC,CAAC;AACtE,KAAK,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,SAAS;AAC7E,KAAK,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK;AAC1B,KAAK,aAAa,CAAC,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,MAAM,GAAG;AAC5C,KAAK,EAAE,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;AAC5C,MAAM,IAAI,CAAC,mBAAmB,CAAC,CAAC,IAAI,CAAC,wBAAwB,CAAC,EAAE;AAChE,KAAK,CAAC;AACN,IAAI,CAAC;AACL,GAAG,CAAC;AACJ,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO;AACnF,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ;AAC/E;AACA,GAAG,IAAI,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE;AACpD;AACA,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC,CAAC;AACnC,IAAI,IAAI,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC,IAAI,CAAC,gBAAgB,GAAG,YAAY,EAAE,CAAC,EAAE;AAC7F,IAAI,IAAI,CAAC,gBAAgB,GAAG,qBAAqB,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;AACrE,GAAG,CAAC;AACJ;AACA,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI;AACf,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AACzB,IAAI,IAAI,CAAC,kBAAkB,GAAG,gBAAgB,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC,IAAI,CAAC,EAAE;AACrG,GAAG,CAAC;AACJ;AACA,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACxB,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;AACV,GAAG,IAAI,EAAE,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,EAAE;AAC1D,GAAG,IAAI,CAAC,qBAAqB,GAAG;AAChC,GAAG,IAAI,CAAC,sBAAsB,GAAG;AACjC,GAAG,IAAI,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACrD,GAAG,IAAI,CAAC,kBAAkB,GAAG,mBAAmB,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC,IAAI,CAAC,EAAE;AACvG,GAAG,IAAI,CAAC,iBAAiB,CAAC,CAAC,KAAK,CAAC,EAAE;AACnC,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC,KAAK,CAAC,EAAE;AAChC,EAAE,CAAC;AACH,CAAC,CAAC;AACF;AACA,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;;AC1bF,GAAG;AACH,CAAC,CAAC,CAAC,eAAe,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI;AAC/F,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,GAAG,CAAC,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI;AACnG,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;AAC9B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,GAAG;AAC/E,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,OAAO,CAAC;AACrC,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,CAAC,OAAO;AACf,CAAC,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAO;AAC3E,CAAC,CAAC,KAAK,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC;AACjD,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE;AACxD,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,aAAa,KAAK,CAAC,CAAC,CAAC;AACvB,CAAC,CAAC,iBAAiB,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC;AAChD,CAAC,CAAC,qBAAqB,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE;AACjC,CAAC,CAAC,qBAAqB,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC;AACrC,CAAC,CAAC,iBAAiB,CAAC,CAAC,EAAE;AACvB,CAAC,CAAC,iBAAiB,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC;AAChD,CAAC,CAAC,qBAAqB,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE;AACjC,CAAC,CAAC,qBAAqB,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;AACtC,CAAC,CAAC,iBAAiB,CAAC,CAAC,EAAE;AACvB,CAAC,CAAC,iBAAiB,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC;AAChD,CAAC,CAAC,qBAAqB,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE;AACjC,CAAC,CAAC,qBAAqB,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC;AACrC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC;AACtB,CAAC,CAAC,aAAa,CAAC;AAChB,CAAC,CAAC,SAAS,CAAC;AACZ,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACX,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,QAAQ,EAAE,OAAO,CAAC,EAAE;AAC/C,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,QAAQ,CAAC,OAAO,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;AAClD,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,QAAQ,CAAC,OAAO,GAAG,gBAAgB,GAAG,OAAO,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AACtE,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE;AAC9E,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,mBAAmB,CAAC,wBAAwB;AAChG,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM;AACxB,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW;AAClC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB;AACvC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY;AACnC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa;AACpC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,iBAAiB;AACxC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO;AACjD,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;AAC1G,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK;AAC9G,CAAC,CAAC,EAAE,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,GAAG,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG;AACjH,CAAC,CAAC,EAAE,UAAU,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC;AAC7F,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE;AAChE,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAC9D,CAAC,EAAE,CAAC,aAAa,CAAC,cAAc;AAChC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE;AACpD;AACA,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AAClD;AACA,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,iBAAiB,CAAC,WAAW,CAAC,IAAI,CAAC;AACtE,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE;AAC9B,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC;AAC7G;AACA,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AAC9C,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AACnD,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AAC/C,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;AAC1F,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;AACnG;AACA,CAAC,EAAE,CAAC,UAAU;AACd,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;AACpD,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC;AACf,EAAE,CAAC,kBAAkB,CAAC,CAAC,IAAI,EAAE,OAAO;AACpC,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;AACpB;AACA,CAAC,EAAE,CAAC,MAAM;AACV,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;AACnB,EAAE,KAAK,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AACnC,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AACvC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM;AAC1F,EAAE,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC;AACxC,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACvD,CAAC,CAAC,CAAC,EAAE;AACL,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;AAC3B,EAAE,MAAM,CAAC,CAAC,CAAC,YAAY,EAAE;AACzB,EAAE,MAAM,CAAC,CAAC,CAAC,YAAY,CAAC;AACxB,CAAC,CAAC,CAAC,EAAE;AACL;AACA,CAAC,EAAE,CAAC,cAAc;AAClB,CAAC,IAAI,EAAE,MAAM;AACb,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC;AAC5C,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;AACV,GAAG,IAAI,CAAC,CAAC,CAAC,QAAQ,EAAE;AACpB,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,GAAG;AACzC,GAAG,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC,IAAI,CAAC;AAC9B,EAAE,CAAC,CAAC,CAAC;AACL,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE;AACtD,CAAC,IAAI,EAAE,OAAO;AACd,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC;AACrC,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE;AAC1B,CAAC,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE;AAC5C,EAAE;AACF;AACA,EAAE,CAAC,KAAK,CAAC,EAAE;AACX;AACA,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE;AACtD,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE;AAC/D,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,EAAE;AACpE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE;AAChE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,EAAE;AACjE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,iBAAiB,CAAC,EAAE;AACrE;AACA,EAAE,CAAC,OAAO,CAAC,EAAE;AACb;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC;AAChB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM;AAClD,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACtD,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;AAClB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;AAC9B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI;AAC1D,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACjE,CAAC,GAAG,CAAC,aAAa,CAAC;AACnB;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACf,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,EAAE;AACxB,EAAE,MAAM,CAAC;AACT,CAAC,CAAC;AACF;AACA,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,GAAG;AACjC;AACA,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE;AAC9E,CAAC,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACzC,EAAE,aAAa,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,GAAG;AACxC,CAAC,CAAC;AACF;AACA,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,aAAa,CAAC,EAAE;AAChC,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;AAC7B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI;AACpD,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AACtE,CAAC,IAAI,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC,SAAS,CAAC,EAAE;AACrE,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC;AACnB,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE;AAClB,EAAE,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,EAAE,QAAQ,EAAE;AAClE,CAAC,EAAE;AACH,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC;AAC7B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK;AAC5C,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACzD,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACnE,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG;AACrB,CAAC,CAAC;AACF,CAAC,MAAM,CAAC,KAAK,CAAC;AACd,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC;AAC1B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK;AACzC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC3D,CAAC,EAAE,CAAC,CAAC;AACL,EAAE,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,EAAE;AACvB,EAAE,CAAC;AACH,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE;AAClC,GAAG,CAAC;AACJ,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE;AACnC,IAAI,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC,UAAU,CAAC;AACxE,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC;AACtE,IAAI,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE;AACnC,GAAG,CAAC,CAAC,EAAE;AACP,GAAG,CAAC;AACJ,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,EAAE;AAC7B,IAAI,CAAC;AACL,KAAK,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE;AACjC,KAAK,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI;AAChC,IAAI,CAAC;AACL,GAAG,CAAC;AACJ,EAAE,CAAC;AACH,CAAC,CAAC,CAAC,CAAC;AACJ,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG;AACrB,EAAE,MAAM,CAAC,KAAK,CAAC;AACf,CAAC,CAAC;AACF,EAAE;;AChNF,GAAG;AACH,CAAC,CAAC,CAAC,iBAAiB,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC;AACxE,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC;AACzF,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC;AAC7E,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,mBAAmB,CAAC,yBAAyB;AACjG,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY;AAC9B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO;AACjD,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAC,QAAQ,CAAC,qBAAqB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACpE,CAAC,EAAE,CAAC,aAAa,CAAC,cAAc;AAChC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG;AACvB;AACA,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC;AAChF,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;AACjF;AACA,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AACrD;AACA,CAAC,EAAE,CAAC,cAAc;AAClB,CAAC,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,SAAS;AACrD,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,YAAY,CAAC,CAAC,EAAE;AAClD,CAAC,IAAI,EAAE,OAAO;AACd,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAC;AACxC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;AAC1B,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;AAClC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;AAChC,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE;AAClC,EAAE;AACF;AACA,EAAE,CAAC,KAAK,CAAC,EAAE;AACX;AACA,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,EAAE;AAC/D;AACA,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE;AACvB;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,MAAM;AACV,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC;AACrD;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,MAAM;AACV,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC,CAAC,IAAI,CAAC;AAC7D;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,MAAM;AACV,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC;AACjD;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,MAAM;AACV,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE;AACjD;AACA,EAAE,CAAC,OAAO,CAAC,EAAE;AACb;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACpE,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,EAAE;AAC1E;AACA,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,KAAK,CAAC,EAAE;AACjC,CAAC,IAAI,EAAE,OAAO;AACd,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;AAC3C,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE;AACjC;AACA,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AACvE,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,EAAE;AAC7E;AACA,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,EAAE;AAC7C;AACA,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;;ACzFF,GAAG;AACH,CAAC,CAAC,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK;AACtF,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,GAAG,CAAC,iBAAiB,CAAC,QAAQ;AAC5F,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC;AAC3D,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC;AAC5E,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,GAAG;AAC/E,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,sBAAsB,CAAC,OAAO,CAAC;AACxC,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,CAAC,OAAO;AACf,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,YAAY,CAAC;AAChD,CAAC,CAAC,KAAK,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAC;AACnD,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE;AACrB,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC;AACzC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACX,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAC;AACnD,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE;AACrB,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,MAAM,CAAC;AAC3C,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACX,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAC;AACrD,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC;AACtC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE;AACZ,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,MAAM,CAAC;AAC9E,CAAC,CAAC,KAAK,WAAW,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,EAAE;AACzC,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,WAAW,EAAE,OAAO,CAAC,EAAE;AAClD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,mBAAmB;AACvE;AACA,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY;AAC9B,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,iBAAiB;AACxC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO;AACjD,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAC,QAAQ,CAAC,qBAAqB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACpE,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AACrD;AACA,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AACpD;AACA,CAAC,EAAE,CAAC,MAAM;AACV,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;AACpB,EAAE,KAAK,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AAC/C,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC;AAC/C,CAAC,CAAC,CAAC,EAAE;AACL;AACA,CAAC,EAAE,CAAC,cAAc;AAClB,CAAC,IAAI,EAAE,OAAO;AACd,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAC;AACxC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC,EAAE;AAChC,EAAE;AACF;AACA,EAAE,CAAC,KAAK,CAAC,EAAE;AACX;AACA,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,EAAE;AAC/D,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,iBAAiB,CAAC,EAAE;;AC9DxE,GAAG;AACH,CAAC,CAAC,CAAC,kBAAkB,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG;AAC7F,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,kBAAkB,CAAC,GAAG,CAAC,IAAI;AAChG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW;AACpG,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,EAAE;AACrE,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,wBAAwB;AAC5E,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM;AACxB,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,UAAU;AACjC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY;AACnC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO;AACjD,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,SAAS,CAAC,QAAQ;AAC3E,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAC,QAAQ,CAAC,qBAAqB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACpE,CAAC,EAAE,CAAC,aAAa,CAAC,cAAc;AAChC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG;AACvB;AACA,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AACrD;AACA,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AACrC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AAC/C;AACA,CAAC,EAAE,CAAC,UAAU;AACd,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC;AACtB;AACA,CAAC,EAAE,CAAC,cAAc;AAClB,CAAC,IAAI,EAAE,OAAO;AACd,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAC;AACxC,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE;AACzB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE;AACrC,EAAE;AACF;AACA,EAAE,CAAC,KAAK,CAAC,EAAE;AACX;AACA,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE;AACzD,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE;AACjE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE;AACnE;AACA,EAAE,CAAC,MAAM,CAAC,EAAE;AACZ;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM;AAChB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC;AAC3E,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ;AAC/D,CAAC,EAAE;AACH;AACA,EAAE,CAAC,OAAO,CAAC,EAAE;AACb;AACA,GAAG;AACH,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC;AACnC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ;AACrC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC5D,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC;AACtB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS;AAClF,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE;AACrG,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC;AACjC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,MAAM;AAC/C,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACpE,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC;AACjB,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACjC,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC;AACxB,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,EAAE;AAC/B,EAAE,IAAI,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,EAAE;AACzE,CAAC,CAAC;AACF,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;;ACjFF,GAAG;AACH,CAAC,CAAC,CAAC,iBAAiB,CAAC,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AACnE,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,EAAE;AACrG,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,mBAAmB,CAAC,wBAAwB;AAChG,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC,CAAC,CAAC,QAAQ;AACZ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM;AACxB,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW;AAClC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO;AACjD,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,WAAW,CAAC;AAC1F,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAC,QAAQ,CAAC,qBAAqB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACpE,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AACrD;AACA,CAAC,EAAE,CAAC,aAAa,CAAC,cAAc;AAChC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG;AACvB;AACA,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AAC9C;AACA,CAAC,EAAE,CAAC,MAAM;AACV,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE;AACxC,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,aAAa,CAAC,IAAI,CAAC,wBAAwB,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,OAAO;AACnG,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO;AACrD,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;AACxD;AACA,CAAC,EAAE,CAAC,cAAc;AAClB,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACtB,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;AAChC,CAAC,CAAC;AACF,CAAC,IAAI,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC,EAAE;AACzD,CAAC,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAC;AACpD,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE;AACzB,EAAE;AACF;AACA,EAAE,CAAC,KAAK,CAAC,EAAE;AACX;AACA,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE;AACzD,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE;AAClE;AACA,EAAE,CAAC,MAAM,CAAC,EAAE;AACZ;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM;AAChB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,UAAU,CAAC;AACjG,CAAC,EAAE;AACH;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM;AAChB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,UAAU,CAAC;AACpE,CAAC,EAAE;AACH;AACA,EAAE,CAAC,OAAO,CAAC,EAAE;AACb;AACA,GAAG;AACH,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC;AAClC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,GAAG,CAAC,QAAQ,CAAC,OAAO;AACvD,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACnE,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAC9C,EAAE,MAAM,CAAC,IAAI,CAAC,UAAU,GAAG;AAC3B,CAAC,CAAC,CAAC,EAAE;AACL,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC;AAC9C,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,OAAO;AACzD,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC,qBAAqB,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACvE,CAAC,MAAM,CAAC,IAAI,CAAC,iBAAiB,GAAG,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACzD,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;AACnB,CAAC,CAAC,CAAC,EAAE;AACL,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC;AAC9F,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM;AAC3D,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACpE,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACxC,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AAC9C,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,QAAQ,CAAC,EAAE;AAC/B,CAAC,CAAC,CAAC,EAAE;AACL,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC;AAC7F,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,GAAG,MAAM,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM;AAC7D,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAC1E,CAAC,GAAG,CAAC,KAAK,CAAC;AACX,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;AAChB,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACvC,EAAE,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,EAAE;AACzC,CAAC,CAAC,CAAC,EAAE;AACL,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,KAAK,CAAC,EAAE;AAC3B,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;;AChHF,GAAG;AACH,CAAC,CAAC,CAAC,yBAAyB,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC;AAC5E,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,yBAAyB,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC;AACpG,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC;AAC7E,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,mBAAmB,CAAC,yBAAyB;AACjG,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB;AACnC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO;AACjD,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,yBAAyB,CAAC,CAAC,CAAC,QAAQ,CAAC,6BAA6B,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACpF,CAAC,EAAE,CAAC,aAAa,CAAC,cAAc;AAChC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG;AACvB;AACA,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC;AAChF,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,mBAAmB,GAAG;AACjD;AACA,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,yBAAyB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AAC7D;AACA,CAAC,EAAE,CAAC,MAAM;AACV,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;AAClE,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;AAC5D;AACA,CAAC,EAAE,CAAC,cAAc;AAClB,CAAC,IAAI,EAAE,OAAO;AACd,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,yBAAyB,CAAC,CAAC,CAAC;AAChD,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,EAAE;AACrC,EAAE;AACF;AACA,EAAE,CAAC,KAAK,CAAC,EAAE;AACX;AACA,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,yBAAyB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,EAAE;AAC5E;AACA,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE;AACvB;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,MAAM;AACV,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,yBAAyB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE;AACzD;AACA,EAAE,CAAC,OAAO,CAAC,EAAE;AACb;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC;AACzC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,yBAAyB,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC1E,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC,EAAE;AAChD,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,yBAAyB,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAC5E,CAAC,EAAE,CAAC,EAAE,CAAC,yBAAyB,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,EAAE;AAClF,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,KAAK,CAAC,EAAE;AACpC,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,yBAAyB,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AAC/E,CAAC,EAAE,CAAC,EAAE,CAAC,yBAAyB,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,EAAE;AACrF,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,EAAE;AAChD,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC;AACpB,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,yBAAyB,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC/D,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,GAAG;AACvB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC;AAC1B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;AAC1B,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,yBAAyB,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACtE,CAAC,GAAG;AACJ,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,eAAe,GAAG;AACnC,EAAE,QAAQ,CAAC;AACX;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AACtE,EAAE,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,wBAAwB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;AAC1D,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAChF,EAAE,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,wBAAwB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE;AACzD,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AAClB,EAAE,CAAC,CAAC,cAAc,GAAG;AACrB,EAAE,QAAQ,CAAC,KAAK,GAAG;AACnB,CAAC,CAAC;AACF,EAAE;;ACtGF,GAAG;AACH,CAAC,CAAC,CAAC,yBAAyB,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,QAAQ;AAClG,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,yBAAyB,CAAC,CAAC,GAAG;AAC5E,CAAC,CAAC,CAAC,yBAAyB,CAAC,QAAQ,CAAC,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC;AAC9F,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC;AAC5E,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,GAAG;AAC/E,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,8BAA8B,CAAC,OAAO,CAAC;AAChD,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,CAAC,OAAO;AACf,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,yBAAyB,CAAC,IAAI,CAAC,oBAAoB,CAAC;AAChE,CAAC,CAAC,KAAK,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,yBAAyB,CAAC,CAAC,CAAC;AAC3D,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE;AACrB,CAAC,CAAC,SAAS,QAAQ,CAAC,CAAC,IAAI,CAAC;AAC1B,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC;AACrC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACX,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,yBAAyB,CAAC,CAAC,CAAC;AAC3D,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE;AACrB,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC;AACvC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACX,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,yBAAyB,CAAC,CAAC,CAAC;AAC7D,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC;AACtC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE;AACZ,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,WAAW,EAAE,OAAO,CAAC,EAAE;AAClD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,mBAAmB;AACvE,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB;AACnC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO;AACjD,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,yBAAyB,CAAC,CAAC,CAAC,QAAQ,CAAC,6BAA6B,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACpF,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,yBAAyB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AAC7D;AACA,CAAC,EAAE,CAAC,UAAU;AACd,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC;AAC1B;AACA,CAAC,EAAE,CAAC,MAAM;AACV,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;AACtD;AACA,CAAC,EAAE,CAAC,cAAc;AAClB,CAAC,IAAI,EAAE,OAAO;AACd,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,yBAAyB,CAAC,CAAC,EAAE;AACjD,EAAE;AACF;AACA,EAAE,CAAC,KAAK,CAAC,EAAE;AACX;AACA,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,yBAAyB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,EAAE;AAC5E;AACA,EAAE,CAAC,OAAO,CAAC,EAAE;AACb;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC;AACrG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;AACpG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE;AAC9F,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC;AAC/C,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,yBAAyB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC;AAC5I,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO;AACzF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,yBAAyB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM;AAC9G,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,yBAAyB,CAAC,SAAS,CAAC,wBAAwB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AACnG,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AAChC,EAAE,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACpC,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;AAC1B;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACd,EAAE,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE;AAC5C,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;AACtD,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACT,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC;AACvE,EAAE,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC;AAC1C,EAAE,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AAC1C,CAAC,CAAC;AACF;AACA,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAC9B,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,EAAE;AACjC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC;AACrC,GAAG,MAAM,CAAC,IAAI,CAAC;AACf,EAAE,CAAC;AACH,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;AACnD,CAAC,CAAC;AACF,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,UAAU,CAAC;AACrC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;AAC1B,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,yBAAyB,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACpE,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,gBAAgB,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,WAAW,CAAC,CAAC,KAAK,CAAC;AACnF,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,EAAE,WAAW,CAAC;AACnC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,yBAAyB,CAAC,CAAC,CAAC;AAC3E,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE;AACpC;AACA,CAAC,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI;AACnE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AAC1D,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,yBAAyB,CAAC,CAAC,EAAE;AACpE,EAAE,gBAAgB,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE;AACpD,EAAE,eAAe,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE;AAClD,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG;AACjG,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC;AAC3D,EAAE,EAAE,CAAC,CAAC,CAAC,eAAe,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC;AAC/C,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;AACtB,GAAG,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,eAAe,CAAC,EAAE,UAAU,GAAG;AACvD,GAAG,SAAS,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC3D;AACA,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC;AAClG,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AACxE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC;AACrC,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE;AAC5C,IAAI,CAAC;AACL,GAAG,CAAC;AACJ,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG;AAC3F,GAAG,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,SAAS,CAAC,GAAG;AAC3F,GAAG,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG;AAC7F,GAAG,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC;AACnD,GAAG,CAAC,CAAC,cAAc,GAAG;AACtB,GAAG,UAAU,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC5B,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,eAAe,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC;AACnD,KAAK,KAAK,CAAC,CAAC,eAAe,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE;AAC1D,IAAI,CAAC;AACL,GAAG,CAAC,CAAC,EAAE;AACP,EAAE,CAAC;AACH,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAC5B,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC;AAClC,CAAC,CAAC;AACF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM;AACnB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,yBAAyB,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC/D,CAAC,GAAG,CAAC,IAAI,CAAC;AACV,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC;AAC5B,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE;AAClD,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACf,GAAG,IAAI,CAAC,KAAK,GAAG;AAChB,EAAE,CAAC;AACH,CAAC,CAAC;AACF,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,yBAAyB,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC5E,CAAC,IAAI,CAAC,KAAK,GAAG;AACd,EAAE;;AC/JF,GAAG;AACH,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC;AACjF,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,aAAa,CAAC;AAClD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC;AACpF,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS;AAChG,CAAC,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,SAAS,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI;AAC/F,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC;AACzB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,aAAa,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,aAAa,CAAC;AACxG,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,CAAC,OAAO;AACf,CAAC,CAAC,KAAK,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,aAAa,CAAC,QAAQ,CAAC,IAAI,CAAC;AAClE,CAAC,CAAC,KAAK,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAC;AACxD,CAAC,CAAC,SAAS,QAAQ,CAAC,CAAC,EAAE;AACvB,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACX,CAAC,CAAC,KAAK,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,GAAG;AACxD,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,cAAc,CAAC,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI;AACzD,CAAC,CAAC,KAAK,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC;AAC/C,CAAC,CAAC,KAAK,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;AAC3B,CAAC,CAAC,QAAQ,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI;AACrF,CAAC,CAAC,QAAQ,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,GAAG;AACtF,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACX,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,QAAQ,EAAE,OAAO,CAAC,EAAE;AAC/C,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM;AACxB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO;AACjD,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,WAAW,CAAC,EAAE,CAAC,aAAa,EAAE;AAClG,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC;AACtG,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,aAAa,CAAC;AAClD,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAC,QAAQ,CAAC,qBAAqB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACpE,CAAC,EAAE,CAAC,aAAa,CAAC,cAAc;AAChC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG;AACvB;AACA,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AACrD;AACA,CAAC,EAAE,CAAC,UAAU;AACd,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE;AAC1B,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC;AACtB;AACA,CAAC,EAAE,CAAC,cAAc;AAClB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE;AAC7E,CAAC,IAAI,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,EAAE;AACrD,CAAC,IAAI,EAAE,OAAO;AACd,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;AACV,GAAG,IAAI,CAAC,CAAC,CAAC,WAAW,EAAE;AACvB,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;AACtB,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,GAAG;AACvB,EAAE,CAAC,CAAC,CAAC;AACL,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAC;AACxC,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE;AACvB,EAAE;AACF;AACA,EAAE,CAAC,KAAK,CAAC,EAAE;AACX;AACA,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE;AACzD;AACA,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE;AACvB;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,MAAM;AACV,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE;AAC/C;AACA,EAAE,CAAC,OAAO,CAAC,EAAE;AACb;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,aAAa,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE;AACzG,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,OAAO;AAC5C,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC7D,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC;AACtB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,aAAa,CAAC,OAAO,CAAC;AACpF,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,aAAa;AACjF,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AACvE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC;AAC1B;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAC5B,EAAE,IAAI,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;AAChD,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE;AACvD,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACT,EAAE,IAAI,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE;AAC/B,EAAE,IAAI,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE;AAC9C,CAAC,CAAC;AACF,CAAC,IAAI,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,aAAa,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;AAC1F,EAAE;;ACnGF,GAAG;AACH,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,KAAK;AAC7D,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,QAAQ,CAAC,MAAM,EAAE;AACxG,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,MAAM,CAAC,MAAM,EAAE;AAClG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC;AACnF,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM;AAC1D,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,QAAQ;AACZ,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM;AACxB,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,cAAc;AACrC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,iBAAiB;AACxC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa;AACpC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,kBAAkB;AACzC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO;AACjD,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC;AAC1E,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC;AACnD,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,cAAc,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE;AACjE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC;AACxE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK;AACjH,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC;AAC1B,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACxD,CAAC,EAAE,CAAC,aAAa,CAAC,cAAc;AAChC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG;AACvB;AACA,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AAC/C;AACA,CAAC,EAAE,CAAC,UAAU;AACd,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,iBAAiB,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK;AAC9C,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,MAAM,CAAC,EAAE;AAC/D,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG;AACjB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC;AACvC;AACA,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AACjD,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;AAClG,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;AAC1F,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;AACpG;AACA,CAAC,EAAE,CAAC,MAAM;AACV,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;AAC7F;AACA,CAAC,EAAE,CAAC,cAAc;AAClB,CAAC,IAAI,EAAE,KAAK;AACZ,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;AACxC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;AAC9B,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,EAAE;AACzC,CAAC,IAAI,EAAE,OAAO;AACd,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;AAClC,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE;AACzB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;AAC/B,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AACpB,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE;AAC5B,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AACtC,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE;AACpC,CAAC,CAAC;AACF,EAAE;AACF;AACA,EAAE,CAAC,KAAK,CAAC,EAAE;AACX;AACA,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE;AACnD,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,EAAE;AAC/D,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,iBAAiB,CAAC,EAAE;AAClE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,EAAE;AAC9D,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,kBAAkB,CAAC,EAAE;AACnE;AACA,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE;AACpB;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACxE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AAC5E,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,KAAK,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC;AAC7F,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE;AAC9D,CAAC,MAAM,CAAC,MAAM,CAAC;AACf,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAC3E,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AAClF,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAC/C,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,KAAK,CAAC,GAAG,GAAG;AACpC,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO;AAClG,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE;AAC7C,CAAC,CAAC;AACF,CAAC,MAAM,CAAC,KAAK,CAAC;AACd,EAAE;AACF;AACA,EAAE,CAAC,MAAM,CAAC,EAAE;AACZ;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM;AAChB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC;AACjE,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK;AACxB,CAAC,EAAE;AACH;AACA,EAAE,CAAC,OAAO,CAAC,EAAE;AACb;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC;AACrB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE;AAC9F,CAAC,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE;AAC1F,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,OAAO;AAC/C,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,OAAO;AACjC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC3D,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE;AACvB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC;AAC5C,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK;AACzF,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAClD,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;AACnB,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC;AAC5B,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO;AAC1D,EAAE,UAAU,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC3B,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,MAAM,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE;AAC1C,EAAE,CAAC,CAAC,EAAE;AACN,CAAC,CAAC;AACF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC;AAC9B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,KAAK;AAC/B,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACpD,CAAC,EAAE,CAAC,aAAa,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM;AACjG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC;AACjF,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,GAAG;AAC/B,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAC9B,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,EAAE;AACzB,CAAC,CAAC;AACF,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC;AACnB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,cAAc,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC;AACvC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC;AAClE,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AACvD,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,EAAE;AAChC,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC;AAC9B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK;AAClC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM;AAChB,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAC3D,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,KAAK,CAAC,EAAE;AACpC,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,EAAE;AACrE,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC;AACxE,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACrC,EAAE,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,EAAE;AAC3B,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAC9B,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC;AACrB,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE;AACpC,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,EAAE;AAClF,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO;AACjF,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC;AACjE,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AACzC,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;AACjC,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC;AACpD,CAAC,CAAC;AACF,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC;AAC3B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC;AAC9E,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK;AACvC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK;AACpC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAC/D,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAC/C,EAAE,MAAM,CAAC,GAAG;AACZ,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;AACjC,EAAE,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE;AAC7C,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACT,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,EAAE;AACzB,CAAC,CAAC;AACF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAC9D,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,EAAE;AACpE,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;AACrB,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,EAAE;AACpD,CAAC,CAAC;AACF,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC,OAAO,CAAC;AACnD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE;AACrB,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAC1D,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE;AAC9B,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC,qBAAqB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACxE,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,SAAS,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,EAAE;AAC9E,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC;AACtE,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE;AAC/B,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACrB,EAAE,IAAI,CAAC,KAAK,GAAG;AACf,CAAC,CAAC;AACF,EAAE;;ACrPF,GAAG;AACH,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC;AAC1D,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM;AACxB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO;AACjD,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC;AACnD,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC;AAC1E,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAC,QAAQ,CAAC,qBAAqB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACpE,CAAC,EAAE,CAAC,aAAa,CAAC,cAAc;AAChC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE;AACtD;AACA,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AACrD;AACA,CAAC,EAAE,CAAC,cAAc;AAClB,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;AACtB,EAAE,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE;AACjB,EAAE,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;AACtB,EAAE,IAAI,CAAC,CAAC,MAAM,CAAC,IAAI;AACnB,CAAC,CAAC,CAAC,EAAE;AACL,CAAC,IAAI,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE;AAC7C,EAAE;AACF;AACA,EAAE,CAAC,KAAK,CAAC,EAAE;AACX;AACA,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE;AACzD;AACA,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE;AACvB;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,MAAM;AACV,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE;;ACrCjD,GAAG;AACH,CAAC,CAAC,CAAC,iBAAiB,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM;AACnF,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,QAAQ;AAC1F,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE;AAC5F,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG;AACnE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC;AAC9D,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,CAAC,OAAO;AACf,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,iBAAiB,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC;AACtE,CAAC,CAAC,KAAK,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAC;AAClD,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,EAAE;AACjC,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,CAAC,KAAK,EAAE;AACzB,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC;AACzB,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACX,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE;AAC7C,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,aAAa;AACxE,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW;AAC7B,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa;AACpC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW;AAClC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB;AACvC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY;AACnC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa;AACpC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO;AACjD,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE;AACzG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC;AACpG,CAAC,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC,SAAS,CAAC,UAAU,EAAE;AAC/G,CAAC,CAAC,EAAE,GAAG,CAAC,SAAS,CAAC,EAAE,IAAI,CAAC,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI;AACtG,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;AACvF,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAC,QAAQ,CAAC,qBAAqB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACpE,CAAC,EAAE,CAAC,aAAa,CAAC,cAAc;AAChC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,WAAW,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE;AACrE;AACA,CAAC,EAAE,CAAC,GAAG,CAAC,WAAW,CAAC,iBAAiB,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK;AACzD,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;AACvB,EAAE,MAAM,EAAE,KAAK,CAAC,KAAK,GAAG;AACxB,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC;AAC7E,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC;AACvC;AACA,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AACrD;AACA,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;AAC1F,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AAC9C,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AACnD,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AAC/C,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;AAC1F;AACA,CAAC,EAAE,CAAC,cAAc;AAClB,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;AAC7B,EAAE,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE;AACjE,CAAC,CAAC;AACF,CAAC,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,EAAE;AACrD,EAAE;AACF;AACA,EAAE,CAAC,KAAK,CAAC,EAAE;AACX;AACA,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,EAAE;AAC9D,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,EAAE;AACpE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE;AAClE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,EAAE;AACvE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE;AACnE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,EAAE;AACpE;AACA,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE;AACvB;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,MAAM;AACV,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;AAChD;AACA,EAAE,CAAC,OAAO,CAAC,EAAE;AACb;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACzE,CAAC,GAAG,CAAC,IAAI,CAAC;AACV,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE;AAC/F,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE;AACzF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC;AACnB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC;AACnF,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;AACjG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK;AAChC,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACjE,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;AACrC,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,EAAE;AACpC,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;AAC1B,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,MAAM;AACjC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;AACpC,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG;AACd,EAAE,CAAC;AACH;AACA,EAAE,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,EAAE;AAC3B,CAAC,CAAC;AACF;AACA,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,EAAE;AACxE,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC;AAC9B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,WAAW,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE;AAChG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,CAAC,KAAK,CAAC,MAAM,EAAE;AAC7C,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK;AAClC,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACjE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;AAC3B,EAAE,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,EAAE;AACxE,CAAC,CAAC;AACF,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC5D,CAAC,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,KAAK,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK;AAClG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,SAAS,CAAC;AAC9F,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;;AC7IF,GAAG;AACH,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC;AAC9F,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;AAC5E,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC;AACjG,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,EAAE;AACxF,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC;AAC3E,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,CAAC,OAAO;AACf,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM;AAC1E,CAAC,CAAC,KAAK,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,CAAC,CAAC;AACrD,CAAC,CAAC,UAAU,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE;AACvB,CAAC,CAAC,UAAU,QAAQ,CAAC,CAAC,IAAI;AAC1B,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACX,CAAC,CAAC,KAAK,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,CAAC,CAAC;AACrD,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AACrB,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACX,CAAC,CAAC,KAAK,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,CAAC,CAAC;AACrD,CAAC,CAAC,SAAS,KAAK,EAAE,CAAC,EAAE;AACrB,CAAC,CAAC,SAAS,QAAQ,CAAC,CAAC,IAAI;AACzB,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACX,CAAC,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC;AACjE,CAAC,CAAC,KAAK,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC;AACjD,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC;AAC9B,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACX,CAAC,CAAC,KAAK,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;AAC3B,CAAC,CAAC,SAAS,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE;AAC/F,CAAC,CAAC,SAAS,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE;AACjG,CAAC,CAAC,SAAS,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE;AAC/F,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACX,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,QAAQ,EAAE,OAAO,CAAC,EAAE;AAC/C,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM;AAC1D,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW;AAC7B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO;AACjD,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC;AAC3G,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,CAAC,CAAC,QAAQ,CAAC,uBAAuB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACxE,CAAC,EAAE,CAAC,aAAa,CAAC,cAAc;AAChC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG;AACvB;AACA,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AACvD;AACA,CAAC,EAAE,CAAC,UAAU;AACd,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;AACzC,EAAE,IAAI,CAAC,CAAC,CAAC,KAAK,EAAE;AAChB,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,SAAS,CAAC,CAAC,CAAC;AACpD,CAAC,CAAC,CAAC,EAAE;AACL;AACA,CAAC,EAAE,CAAC,cAAc;AAClB,CAAC,IAAI,EAAE,OAAO;AACd,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,CAAC,CAAC;AAC1C,EAAE,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,WAAW,CAAC,KAAK;AACrD,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE;AACrC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE;AAC7E,EAAE;AACF;AACA,EAAE,CAAC,KAAK,CAAC,EAAE;AACX;AACA,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,EAAE;AAChE;AACA,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE;AACvB;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,MAAM;AACV,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;AAClD;AACA,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE;AACpB;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACnF,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,MAAM,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AAC1F,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE;AACjD,CAAC,MAAM,CAAC,KAAK,CAAC;AACd,EAAE;AACF;AACA,EAAE,CAAC,OAAO,CAAC,EAAE;AACb;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACnE,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE;AAClD,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC1D,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;AACnB,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC;AAC5B,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO;AAC1D,EAAE,UAAU,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC3B,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE;AACzD,EAAE,CAAC,CAAC,EAAE;AACN,CAAC,CAAC;AACF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC;AACxC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,QAAQ;AAC7C,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACtE,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC;AACjB,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACjC,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC;AACxB,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE;AAC/C,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE;AACvC,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,EAAE;AAC5F,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO;AACpF,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC;AAC3E,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AAC5C,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC;AACvC,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC;AACzD,CAAC,CAAC;AACF,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,QAAQ,CAAC;AACtC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,QAAQ;AACzC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC9D,CAAC,EAAE,CAAC,aAAa,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM;AACjG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC;AACjF,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE;AAC9C,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AACpC,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,QAAQ,CAAC,EAAE;AAC/B,CAAC,CAAC;AACF,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC;AACtB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACtE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC;AAC5B,EAAE,IAAI,EAAE,KAAK,CAAC,KAAK,GAAG;AACtB,CAAC,CAAC;AACF,CAAC,IAAI,CAAC,KAAK,GAAG;AACd,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,SAAS,CAAC,qBAAqB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAChF,CAAC,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,MAAM,CAAC,SAAS,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,EAAE;AACtF,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC;AAC5E,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE;AACpC,CAAC,CAAC;AACF,EAAE;;ACpKF,GAAG;AACH,CAAC,CAAC,CAAC,mBAAmB,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,cAAc,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI;AAC3F,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK;AACrG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,GAAG;AACxF,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC;AACxC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,MAAM,CAAC,KAAK;AACjG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC;AAChG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,cAAc,CAAC;AAC9F,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,sBAAsB,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC;AAChF,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,CAAC,OAAO;AACf,CAAC,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO;AAC3D,CAAC,CAAC,KAAK,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,CAAC,CAAC;AAC3D,CAAC,CAAC,SAAS,OAAO,CAAC,CAAC,CAAC;AACrB,CAAC,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AAC7C,CAAC,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,GAAG;AAC7C,CAAC,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;AAC5C,CAAC,CAAC,SAAS,CAAC;AACZ,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACX,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,aAAa,EAAE,OAAO,CAAC,EAAE;AACpD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM;AAC1D,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW;AAC7B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO;AACjD,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE;AAC3F,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,cAAc,CAAC;AACjG,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,CAAC,CAAC,QAAQ,CAAC,uBAAuB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACxE,CAAC,EAAE,CAAC,aAAa,CAAC,cAAc;AAChC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG;AACvB;AACA,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC;AAChF,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE;AACnE,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC;AAC3F,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC;AAC3E,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE;AAC7C;AACA,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AACvD;AACA,CAAC,EAAE,CAAC,MAAM;AACV,CAAC,IAAI,CAAC,cAAc,CAAC,OAAO,GAAG,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE;AAC3E;AACA,CAAC,EAAE,CAAC,cAAc;AAClB,CAAC,IAAI,EAAE,OAAO;AACd,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,CAAC,CAAC;AAC1C,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,cAAc,EAAE,OAAO,CAAC,EAAE;AAC1C,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC,IAAI,CAAC,cAAc,EAAE,UAAU,CAAC,EAAE;AAC9D,EAAE;AACF;AACA,EAAE,CAAC,KAAK,CAAC,EAAE;AACX;AACA,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,EAAE;AAChE;AACA,EAAE,CAAC,OAAO,CAAC,EAAE;AACb;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACnE,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE;AACxB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;AAC9B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI;AAC/D,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACtE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE;AAC7C,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACnE,CAAC,GAAG,CAAC,QAAQ,CAAC;AACd,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,KAAK,CAAC,EAAE;AACpC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ;AACvE,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,OAAO,GAAG,gBAAgB,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE;AACtE,EAAE,IAAI,CAAC,cAAc,CAAC,OAAO,GAAG,uBAAuB,GAAG;AAC1D,CAAC,IAAI,CAAC,cAAc,CAAC,OAAO,GAAG,UAAU,CAAC,CAAC,QAAQ,CAAC,EAAE;AACtD,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,GAAG;AAC5C,CAAC,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,EAAE;AACzE,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;AAC3B,EAAE,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC;AAC9D,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC;AAC5C,EAAE,IAAI,CAAC,sBAAsB,GAAG;AAChC,CAAC,CAAC;AACF,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACtE,CAAC,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC,KAAK,CAAC,EAAE;AAC1C,CAAC,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,EAAE;AAC5E,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC;AAC5C,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE;AACxF,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AACvE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,GAAG;AAC7B;AACA,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,OAAO,CAAC,EAAE;AAChC;AACA,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,MAAM,GAAG;AACnF,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC;AAC5F,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,EAAE;AACxB;AACA,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC;AAC9F,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;AAC5F,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC;AAClB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE;AACxF,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AAC3E,CAAC,GAAG;AACJ,EAAE,aAAa,CAAC;AAChB,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;AAChB;AACA,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC;AAC1B;AACA,CAAC,aAAa,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AAChD,EAAE,GAAG,CAAC,QAAQ,CAAC;AACf;AACA,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AACrC,GAAG,MAAM,CAAC,MAAM,CAAC,6BAA6B,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE;AAC/D,EAAE,CAAC;AACH;AACA,EAAE,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;AAC7C,EAAE,MAAM,CAAC,MAAM,CAAC,sBAAsB,CAAC;AACvC,GAAG,QAAQ,CAAC;AACZ,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ;AACjD,EAAE,EAAE;AACJ;AACA,CAAC,CAAC,CAAC,EAAE;AACL;AACA,CAAC,IAAI,CAAC,cAAc,CAAC,OAAO,GAAG,UAAU,GAAG,QAAQ,CAAC,CAAC,aAAa,CAAC,EAAE;AACtE,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;AAC/B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI;AACjC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK;AACnC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,MAAM,CAAC,MAAM;AACjD,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,SAAS,CAAC,sBAAsB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACvF,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC;AACrC,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC;AACb,EAAE,KAAK,CAAC,CAAC,KAAK;AACd,CAAC,CAAC,CAAC,EAAE;AACL,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC;AACvC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK;AAC3C,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,uBAAuB,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM;AACrE,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,SAAS,CAAC,6BAA6B,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACxF,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,uBAAuB,CAAC,CAAC,CAAC;AAC5C,EAAE,KAAK,CAAC,CAAC,KAAK;AACd,CAAC,CAAC,CAAC,EAAE;AACL,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC;AACrF,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC;AAChE,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,SAAS,CAAC,sBAAsB,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC1E,CAAC,GAAG;AACJ,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC;AAClC,EAAE,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC;AACnC,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;AAChB;AACA,CAAC,IAAI,EAAE,KAAK,CAAC,KAAK,GAAG;AACrB;AACA,CAAC,IAAI,CAAC,cAAc,CAAC,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;AAC9E,EAAE,GAAG,CAAC,CAAC,UAAU,CAAC;AAClB;AACA,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,YAAY,CAAC,UAAU,CAAC,EAAE,CAAC,EAAE,CAAC,uBAAuB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACrE,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;AAChC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC,CAAC;AAC5C,IAAI,CAAC,IAAI,CAAC,CAAC,YAAY,CAAC,QAAQ,EAAE,CAAC,EAAE;AACrC;AACA,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO;AACzF,GAAG,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC;AAC7E,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE;AAClF;AACA,GAAG,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE;AAC3C,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;AACV,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC;AAClC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,CAAC,EAAE;AAC9C,GAAG,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE;AACvC,GAAG,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC;AACnC,EAAE,CAAC;AACH,CAAC,CAAC,CAAC,EAAE;AACL;AACA,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC;AAC3B,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACzD,CAAC,IAAI,CAAC,cAAc,CAAC,KAAK,GAAG;AAC7B,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACxD,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,GAAG;AAC5B,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;;AClPF,GAAG;AACH,CAAC,CAAC,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;AACnG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,KAAK,CAAC,MAAM,CAAC;AACpF,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC;AAClG,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,EAAE;AACvD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC;AAC3E,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,CAAC,OAAO;AACf,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM;AACvE,CAAC,CAAC,KAAK,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC;AACjD,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE;AACtB,CAAC,CAAC,SAAS,QAAQ,CAAC,CAAC,IAAI;AACzB,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACX,CAAC,CAAC,KAAK,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC;AACjD,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AACrB,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACX,CAAC,CAAC,KAAK,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC;AACjD,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE;AACtB,CAAC,CAAC,SAAS,QAAQ,CAAC,CAAC,IAAI;AACzB,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACX,CAAC,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;AACrE,CAAC,CAAC,KAAK,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC;AACjD,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC;AAChC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACX,CAAC,CAAC,KAAK,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;AAC3B,CAAC,CAAC,SAAS,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE;AACnF,CAAC,CAAC,SAAS,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE;AACrF,CAAC,CAAC,SAAS,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE;AACnF,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACX,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,QAAQ,EAAE,OAAO,CAAC,EAAE;AAC/C,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM;AAC1D,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW;AAC7B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO;AACjD,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC;AACnH,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC,QAAQ,CAAC,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAClE,CAAC,EAAE,CAAC,aAAa,CAAC,cAAc;AAChC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG;AACvB;AACA,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AACpD;AACA,CAAC,EAAE,CAAC,cAAc;AAClB,CAAC,IAAI,EAAE,OAAO;AACd,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC;AACvC,EAAE,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,WAAW,CAAC,KAAK;AACrD,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE;AAC3B,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE;AAC7E,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,WAAW,CAAC,EAAE;AAC7D;AACA,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE;AACvB;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,MAAM;AACV,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;AAC/C;AACA,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE;AACpB;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAChF,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,MAAM,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AACvF,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE;AACjD,CAAC,MAAM,CAAC,KAAK,CAAC;AACd,EAAE;AACF;AACA,EAAE,CAAC,OAAO,CAAC,EAAE;AACb;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAChE,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AAC/C,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACvD,CAAC,EAAE,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC;AAC7C,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;AAC5C,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,QAAQ;AAC7C,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACnE,CAAC,EAAE,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC;AAC7C,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,EAAE;AACtC,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,EAAE;AAC5F,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO;AACpF,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC;AAC3E,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AAC5C,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,KAAK,CAAC;AAC/B,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC;AACzD,CAAC,CAAC;AACF,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC;AAC1C,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ;AACtC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC3D,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE;AACtC,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACnE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC;AAC5B,EAAE,IAAI,EAAE,KAAK,CAAC,KAAK,GAAG;AACtB,CAAC,CAAC;AACF,CAAC,IAAI,CAAC,KAAK,GAAG;AACd,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,SAAS,CAAC,qBAAqB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAC7E,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,EAAE;AACnF,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC;AAC5E,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE;AACpC,CAAC,CAAC;AACF,EAAE;;AC9IF,GAAG;AACH,CAAC,CAAC,CAAC,sBAAsB,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,iBAAiB,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI;AACpG,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK;AACrG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,GAAG;AACxF,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC;AACxC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC;AAC7E,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,CAAC,OAAO;AACf,CAAC,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,sBAAsB,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO;AAC9D,CAAC,CAAC,KAAK,GAAG,CAAC,gBAAgB,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,sBAAsB,CAAC,CAAC,CAAC;AACjE,CAAC,CAAC,SAAS,OAAO,CAAC,CAAC,CAAC;AACrB,CAAC,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AAC7C,CAAC,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,GAAG;AAC7C,CAAC,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;AAC5C,CAAC,CAAC,SAAS,CAAC;AACZ,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACX,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,gBAAgB,EAAE,OAAO,CAAC,EAAE;AACvD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM;AAC1D,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW;AAC7B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO;AACjD,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE;AAC3F,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,sBAAsB,CAAC,CAAC,CAAC,QAAQ,CAAC,0BAA0B,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAC9E,CAAC,EAAE,CAAC,aAAa,CAAC,cAAc;AAChC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG;AACvB;AACA,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC;AAChF,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,GAAG;AACxD,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC;AAC3F,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG;AAC1E,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE;AAC7C;AACA,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,sBAAsB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AAC1D;AACA,CAAC,EAAE,CAAC,MAAM;AACV,CAAC,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE;AACpE;AACA,CAAC,EAAE,CAAC,cAAc;AAClB,CAAC,IAAI,EAAE,OAAO;AACd,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,sBAAsB,CAAC,CAAC,CAAC;AAC7C,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,iBAAiB,EAAE,OAAO,CAAC,EAAE;AAC7C,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC,IAAI,CAAC,iBAAiB,EAAE,UAAU,CAAC,EAAE;AACjE,EAAE;AACF;AACA,EAAE,CAAC,KAAK,CAAC,EAAE;AACX;AACA,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,sBAAsB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,EAAE;AACnE;AACA,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE;AACpB;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,sBAAsB,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACtF,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,sBAAsB,CAAC,MAAM,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AAC7F,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,EAAE,GAAG,GAAG;AAClG,CAAC,MAAM,CAAC,KAAK,CAAC;AACd,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,sBAAsB,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACnF,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,sBAAsB,CAAC,MAAM,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AACvF,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,GAAG;AAC7C,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC;AACtB,CAAC,MAAM,CAAC,MAAM,CAAC;AACf,EAAE;AACF;AACA,EAAE,CAAC,OAAO,CAAC,EAAE;AACb;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,sBAAsB,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACtE,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ;AACzF,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,YAAY,CAAC,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,YAAY,EAAE;AAC1F,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE;AAC1D,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;AAC9B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI;AAC3D,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,sBAAsB,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACzE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE;AACjC,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,sBAAsB,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACtE,CAAC,GAAG,CAAC,QAAQ,CAAC;AACd,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,KAAK,CAAC,EAAE;AACpC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ;AACvE,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE;AAC/D,EAAE,IAAI,CAAC,iBAAiB,CAAC,uBAAuB,GAAG;AACnD,CAAC,IAAI,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC,QAAQ,CAAC,EAAE;AAC/C,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,GAAG;AAC5C,CAAC,EAAE,CAAC,EAAE,CAAC,sBAAsB,CAAC,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,EAAE;AAC5E,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,sBAAsB,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACzE,CAAC,IAAI,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC,KAAK,CAAC,EAAE;AAC7C,CAAC,EAAE,CAAC,EAAE,CAAC,sBAAsB,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,EAAE;AAC/E,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC;AAC5C,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE;AACxF,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,sBAAsB,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AAC1E,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,GAAG;AAC7B;AACA,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,OAAO,CAAC,EAAE;AAChC;AACA,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,iBAAiB,EAAE;AACzE,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC;AAC5F,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,EAAE;AACxB;AACA,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC;AAC9F,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;AAC5F,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC;AAClB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE;AACxF,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,sBAAsB,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AAC9E,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;AACnB;AACA,CAAC,IAAI,CAAC,iBAAiB;AACvB,EAAE,CAAC,UAAU,EAAE;AACf,EAAE,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AAC5C,GAAG,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;AAClD,GAAG,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAC;AACxC,IAAI,IAAI,CAAC,CAAC,QAAQ,CAAC;AACnB,IAAI,KAAK,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ;AACzD,GAAG,CAAC,CAAC,EAAE;AACP,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE;AACR,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,sBAAsB,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC5D,CAAC,IAAI,CAAC,iBAAiB,CAAC,KAAK,GAAG;AAChC,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,sBAAsB,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC3D,CAAC,IAAI,CAAC,iBAAiB,CAAC,IAAI,GAAG;AAC/B,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;;ACjLF,GAAG;AACH,CAAC,CAAC,CAAC,8BAA8B,CAAC,EAAE,CAAC,CAAC;AACtC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,yBAAyB,CAAC,yBAAyB,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AACjG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;AAChG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,GAAG;AAC7F,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC;AACxC,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,CAAC,OAAO;AACf,CAAC,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,8BAA8B,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO;AACtE,CAAC,CAAC,KAAK,GAAG,CAAC,gBAAgB,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,8BAA8B,CAAC,CAAC,CAAC;AACzE,CAAC,CAAC,SAAS,OAAO,CAAC,CAAC,CAAC;AACrB,CAAC,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AAC7C,CAAC,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,GAAG;AAC7C,CAAC,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;AAC5C,CAAC,CAAC,SAAS,CAAC;AACZ,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACX,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,gBAAgB,EAAE,OAAO,CAAC,EAAE;AACvD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM;AAC1D,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW;AAC7B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO;AACjD,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE;AACxG,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,8BAA8B,CAAC,CAAC,CAAC,QAAQ,CAAC,kCAAkC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAC9F,CAAC,EAAE,CAAC,aAAa,CAAC,cAAc;AAChC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG;AACvB;AACA,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC;AAChF,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,yBAAyB,GAAG;AACxE,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK;AACrD,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC;AAC9B,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC;AAC3F,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG;AAC1E,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE;AAC7C;AACA,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,8BAA8B,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AAClE;AACA,CAAC,EAAE,CAAC,MAAM;AACV,CAAC,IAAI,CAAC,yBAAyB,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,EAAE;AAClF;AACA,CAAC,EAAE,CAAC,cAAc;AAClB,CAAC,IAAI,EAAE,OAAO;AACd,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,8BAA8B,CAAC,CAAC,CAAC;AACrD,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,yBAAyB,EAAE,OAAO,CAAC,EAAE;AACrD,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,oBAAoB,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM;AACpF,CAAC,IAAI,EAAE,KAAK,CAAC,MAAM,GAAG;AACtB,EAAE;AACF;AACA,EAAE,CAAC,KAAK,CAAC,EAAE;AACX;AACA,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,8BAA8B,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,EAAE;AAC3E;AACA,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE;AACpB;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,8BAA8B,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAC9F,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,8BAA8B,CAAC,MAAM,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AACrG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;AAC9F,EAAE,CAAC,OAAO,GAAG,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE;AACzD,CAAC,MAAM,CAAC,KAAK,CAAC;AACd,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,8BAA8B,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAC3F,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,8BAA8B,CAAC,MAAM,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AAC/F,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,GAAG;AAChD,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC;AACtB,CAAC,MAAM,CAAC,MAAM,CAAC;AACf,EAAE;AACF;AACA,EAAE,CAAC,OAAO,CAAC,EAAE;AACb;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,8BAA8B,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC9E,CAAC,EAAE,CAAC,QAAQ,CAAC,MAAM;AACnB,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE;AACxB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,OAAO,CAAC,yBAAyB,CAAC,MAAM,CAAC,MAAM,CAAC;AACnD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,8BAA8B,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACjF,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,yBAAyB,CAAC,qBAAqB,EAAE,CAAC,EAAE;AACzE,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,8BAA8B,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACvE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;AAChG,EAAE,CAAC,OAAO,GAAG,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE;AACzD,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAC9B,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,EAAE;AACzB,CAAC,CAAC;AACF,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC;AACnB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,8BAA8B,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAC9E,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,KAAK,CAAC,EAAE;AACpC,CAAC,IAAI,CAAC,yBAAyB,CAAC,iBAAiB,CAAC,CAAC,KAAK,CAAC,EAAE;AAC3D,CAAC,EAAE,CAAC,EAAE,CAAC,8BAA8B,CAAC,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,EAAE;AACpF,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;AAC3B,EAAE,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC;AAC9D,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC;AAC5C,EAAE,IAAI,CAAC,sBAAsB,GAAG;AAChC,CAAC,CAAC;AACF,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC;AAC3B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK;AACzC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK;AACtC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,8BAA8B,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAClF,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC;AACpB,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG;AAClB,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACjC,EAAE,MAAM,CAAC,UAAU,CAAC;AACpB,CAAC,CAAC;AACF,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AACvC,EAAE,WAAW,CAAC,CAAC;AACf,GAAG,EAAE,CAAC,EAAE,CAAC,8BAA8B,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;AAC/F,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI;AAC3C,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,yBAAyB,CAAC,gBAAgB,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC1E,GAAG,QAAQ,CAAC;AACZ,EAAE,CAAC;AACH,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC,WAAW,CAAC,EAAE;AACjC,CAAC,CAAC;AACF,CAAC,MAAM,CAAC,UAAU,CAAC;AACnB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,8BAA8B,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACjF,CAAC,IAAI,CAAC,yBAAyB,CAAC,WAAW,CAAC,CAAC,KAAK,CAAC,EAAE;AACrD,CAAC,EAAE,CAAC,EAAE,CAAC,8BAA8B,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,EAAE;AACvF,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC;AAC5C,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE;AACrG,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,8BAA8B,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AAClF,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,GAAG;AAC7B;AACA,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,OAAO,CAAC,EAAE;AAChC;AACA,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,yBAAyB,EAAE;AACjF,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC;AACrE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,EAAE;AACxB;AACA,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC;AAC9F,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;AAC5F,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC;AAClB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE;AACxF,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,8BAA8B,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AACtF,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;AACnB;AACA,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC;AAC1B;AACA,CAAC,IAAI,CAAC,yBAAyB;AAC/B,EAAE,CAAC,UAAU,EAAE;AACf,EAAE,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AAC5C,GAAG,GAAG,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,WAAW,CAAC;AACnC,GAAG,QAAQ,CAAC,CAAC;AACb,IAAI,EAAE,CAAC,EAAE,CAAC,8BAA8B,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;AAChG,GAAG,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC;AACnE,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,yBAAyB,CAAC,CAAC,CAAC;AAChD,IAAI,IAAI,CAAC,CAAC,QAAQ,CAAC;AACnB,IAAI,KAAK,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC;AAC1D,IAAI,QAAQ,CAAC,CAAC,WAAW;AACzB,GAAG,CAAC,CAAC,EAAE;AACP,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU;AACpD,GAAG,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE;AACzD,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,EAAE;AACtC,GAAG,MAAM,CAAC,IAAI,CAAC;AACf,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE;AACR,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC;AACrF,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC;AAChE,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,8BAA8B,CAAC,SAAS,CAAC,sBAAsB,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACrF,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC;AACtC;AACA,CAAC,IAAI,CAAC,yBAAyB,CAAC,QAAQ,GAAG,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACvE,EAAE,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO;AACxF,EAAE,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC;AAC5E,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AAChE,EAAE,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC,CAAC,SAAS,CAAC;AAC5C,EAAE,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC,SAAS,CAAC;AACvD,CAAC,CAAC,CAAC,EAAE;AACL;AACA,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC;AAC3B,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,8BAA8B,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACpE,CAAC,IAAI,CAAC,yBAAyB,CAAC,KAAK,GAAG;AACxC,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;;AC7OF,GAAG;AACH,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG;AAC7F,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,UAAU;AAC9F,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,UAAU,EAAE,CAAC,EAAE,CAAC,QAAQ;AAC3G,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC;AAChG,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;AAC9D,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC;AAC1F,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC;AAC3E,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,CAAC,OAAO;AACf,CAAC,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM;AACxC,CAAC,CAAC,KAAK,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC;AACnD,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;AAC9B,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;AACV,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE;AAChD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM;AAC1D,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW;AAC7B,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW;AAClC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB;AACvC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,cAAc;AACrC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY;AACnC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO;AACjD,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC;AACzF,CAAC,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE;AAC/B,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,WAAW,CAAC,IAAI;AAC/C,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC,SAAS,CAAC,EAAE;AACxE,CAAC,CAAC,EAAE,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC;AAC9C,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC;AAClF,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC;AAC/E,CAAC,CAAC;AACF,CAAC,CAAC,EAAE,GAAG,CAAC,WAAW,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI;AAC/F,CAAC,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC9F,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC;AAC5C,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,aAAa,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE;AAC7F,CAAC,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE;AAC1D,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,GAAG;AAC3G,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC;AACzF,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK;AAC5F,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,SAAS,CAAC,CAAC,KAAK;AACtG,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,EAAE;AAClC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACjG,CAAC,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC;AAChG,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG;AAChG,CAAC,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,SAAS;AACnG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC;AACvF,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC,QAAQ,CAAC,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAChE,CAAC,EAAE,CAAC,aAAa,CAAC,cAAc;AAChC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;AACrB,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE;AACf,EAAE,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC;AACxB,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE;AACb;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AAC1B,EAAE,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,wBAAwB,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,EAAE;AACrI,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,wBAAwB,CAAC,CAAC,MAAM,CAAC,EAAE;AACtD,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AACnD;AACA,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AAC9C,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AACnD,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;AAC5F,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AAC/C;AACA,CAAC,EAAE,CAAC,UAAU;AACd,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,EAAE;AACxC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC;AACvB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC;AACvB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC;AACtB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC;AACzB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC;AACzB;AACA,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE;AACvC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE;AAC/C;AACA,CAAC,EAAE,CAAC,MAAM;AACV,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;AAClB,EAAE,QAAQ,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AACzC,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AACjC,EAAE,KAAK,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC;AAClC,CAAC,CAAC,CAAC,EAAE;AACL,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;AACjE,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;AAC3E,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;AAC5D,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE;AACjF;AACA,CAAC,EAAE,CAAC,cAAc;AAClB,CAAC,IAAI,EAAE,OAAO;AACd,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC9E,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE;AACzC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC,EAAE;AACvC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC,EAAE;AACvC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AAC1C,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE;AACxD,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AACxC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE;AACpD,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AAC1B,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE;AAC/C,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACvC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE;AAC5C,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;AACzF,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;AAC/F,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;AACnB,GAAG,YAAY,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC9B,IAAI,IAAI,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,EAAE;AAC7C,GAAG,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AAClB,GAAG,QAAQ,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC1B,IAAI,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG;AAC9F,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;AAC/C,IAAI,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE;AAC9C,GAAG,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC;AACjB,EAAE,CAAC,CAAC,EAAE;AACN,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AACzC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACzE,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACpB,EAAE,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC,IAAI,CAAC;AACpC,EAAE,IAAI,CAAC,2BAA2B,GAAG;AACrC,CAAC,CAAC;AACF,EAAE;AACF;AACA,EAAE,CAAC,KAAK,CAAC,EAAE;AACX;AACA,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,EAAE;AAC5D,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE;AAChE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,EAAE;AACrE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,EAAE;AACnE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE;AACjE;AACA,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE;AACvB;AACA,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC;AACnD,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,KAAK;AACnB,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,GAAG;AACjB,EAAE;AACF;AACA,EAAE,CAAC,MAAM,CAAC,EAAE;AACZ;AACA,GAAG;AACH,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC;AACjF,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK;AACf,CAAC,EAAE;AACH;AACA,EAAE,CAAC,OAAO,CAAC,EAAE;AACb;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC;AACjC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK;AAC3C,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAClE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAC7C,EAAE,IAAI,CAAC,KAAK,GAAG;AACf,EAAE,MAAM,CAAC,KAAK,CAAC;AACf,CAAC,CAAC;AACF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC;AACtC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK;AAC3C,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACvE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAC7C,EAAE,IAAI,CAAC,KAAK,GAAG;AACf,EAAE,MAAM,CAAC,KAAK,CAAC;AACf,CAAC,CAAC;AACF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC;AAC3B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK;AAC1C,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO;AACvC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC7D,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACtC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE;AAC1B,CAAC,CAAC;AACF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC;AACtB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK;AACrC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACtD,CAAC,IAAI,CAAC,eAAe,GAAG;AACxB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC;AACvB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK;AACtC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACvD,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;AACpC,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,EAAE;AAC9E,EAAE,EAAE,CAAC,qBAAqB,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC;AAC1F,EAAE,IAAI,CAAC,eAAe,GAAG;AACzB,CAAC,CAAC;AACF,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,EAAE;AAC9B,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC;AAChC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK;AAC/C,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC/D,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC,KAAK,CAAC;AACpC,CAAC,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,SAAS;AACrF,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC;AACtB,CAAC,IAAI,CAAC,aAAa,GAAG;AACtB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC;AAClC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK;AACxB,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACjE,CAAC,IAAI,CAAC,eAAe,GAAG;AACxB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE;AACrD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC;AACpB,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC1D,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC;AACtB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC;AAC1D,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI;AAC9C,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAClE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC;AACzB,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE;AAC/C,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,QAAQ,CAAC,QAAQ,EAAE;AACpD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC;AACpB,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC1D,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC;AACtB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC;AACzD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ;AAC7C,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAClE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC;AACzB,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AACvB,EAAE,IAAI,EAAE,KAAK;AACb,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,CAAC;AAC5B,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE;AACpC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACvC,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE;AACnC,EAAE,CAAC;AACH,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACT,EAAE,IAAI,EAAE,KAAK;AACb,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,CAAC;AAC7B,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE;AAClC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;AAC7C,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,EAAE;AAC7B,EAAE,CAAC;AACH,CAAC,CAAC;AACF,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC;AACrE,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,2BAA2B;AACpG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC;AACpG,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,gBAAgB,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,eAAe,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG;AAClG,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC;AAC/D,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,SAAS,CAAC,2BAA2B,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC3E,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC,QAAQ,CAAC,CAAC,WAAW,CAAC,CAAC,cAAc,CAAC;AAC7D,EAAE,gBAAgB,CAAC,CAAC,CAAC,MAAM,CAAC,gBAAgB,CAAC,EAAE,CAAC,MAAM,CAAC,sBAAsB,CAAC,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC;AAC5G,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;AAChB;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC;AAC1B,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC;AAC5C;AACA,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,iBAAiB,EAAE,CAAC,CAAC,CAAC,CAAC;AACnC,GAAG,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI;AACjG,GAAG,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,gBAAgB;AAC7F,GAAG,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,KAAK,CAAC;AAC7F,GAAG,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;AAC1B,GAAG,MAAM,CAAC;AACV,EAAE,CAAC;AACH;AACA,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI;AAClC,EAAE,WAAW,CAAC,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE;AACnC,EAAE,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;AACpC,GAAG,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,UAAU,CAAC;AACxC,EAAE,CAAC;AACH;AACA,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM;AAChG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG;AAC9F,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI;AAC3F,EAAE,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE;AAC5F,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC;AACrE;AACA,EAAE,gBAAgB,CAAC,CAAC,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AACnE,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC;AAC1B,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAC7C,IAAI,YAAY,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,YAAY,CAAC;AAC/C,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AACjD,KAAK,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;AAC/C,MAAM,UAAU,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE;AAChC,MAAM,MAAM,CAAC;AACb,KAAK,CAAC;AACN,IAAI,CAAC;AACL,GAAG,CAAC;AACJ,EAAE,CAAC,CAAC,EAAE;AACN;AACA,EAAE,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC1B,GAAG,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AACxD,GAAG,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,iBAAiB,EAAE,CAAC,CAAC,CAAC,CAAC;AACtC,IAAI,MAAM,CAAC,eAAe,GAAG;AAC7B,GAAG,CAAC;AACJ,GAAG,gBAAgB,CAAC,UAAU,GAAG;AACjC,GAAG,MAAM,CAAC,2BAA2B,GAAG;AACxC,EAAE,EAAE;AACJ;AACA,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE;AACxC,EAAE,cAAc,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE;AAC3D,EAAE,gBAAgB,CAAC,OAAO,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;AAClE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACT,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,2BAA2B,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG;AAC9F,EAAE,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,UAAU,CAAC;AAC7F,EAAE,IAAI,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,2BAA2B,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;AACvF,CAAC,CAAC;AACF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACvE,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;AACjD,EAAE,MAAM,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;AACvB,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;AACzB,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE;AAC7B,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACT,EAAE,MAAM,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;AACnE,CAAC,CAAC;AACF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC;AACnD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,OAAO;AAC/C,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC;AACxB,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACnE,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;AACrB,EAAE,CAAC,IAAI,EAAE;AACT,EAAE,CAAC,QAAQ,EAAE;AACb,EAAE,CAAC,KAAK,EAAE;AACV,EAAE,CAAC,GAAG,EAAE;AACR,EAAE,CAAC,MAAM,CAAC;AACV,CAAC,EAAE;AACH,CAAC,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;AAC1E,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC;AAChE,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM;AAC1C,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI;AAC1D,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AACrE,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC;AAC7B,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE;AAC3B;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC;AACjB;AACA,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AACzB,CAAC,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AACjC,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;AAC/B;AACA,CAAC,IAAI,CAAC,KAAK,GAAG;AACd;AACA,CAAC,GAAG,CAAC,CAAC;AACN,EAAE,KAAK,CAAC,iBAAiB,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE;AAC9E,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAChB,EAAE,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC;AACnF,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK;AAClF,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC;AAC7E,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC3D,GAAG,KAAK,CAAC,CAAC,CAAC;AACX,EAAE,CAAC;AACH,CAAC,CAAC;AACF,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM;AAC/E,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO;AAC7D,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACxD,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE;AAC9B,EAAE,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,cAAc,CAAC;AAC/B,EAAE,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC;AAC3B,EAAE,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE;AACxD;AACA,CAAC,MAAM,CAAC,CAAC;AACT,EAAE,IAAI,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC;AAClC,EAAE,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG;AAC/B,CAAC,EAAE;AACH,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC;AAC1C,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG;AACxD,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ;AACtB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,MAAM;AAChC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC9D,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC;AACtC,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC;AAC9C,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACtD,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC,EAAE;AACrD,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC;AACpD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACjE,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE;AAC9B,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC;AAClD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC/D,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC,EAAE;AAClD,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC;AACrC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ;AACjD,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AACtE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC;AAChB,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,GAAG;AAC1B,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,GAAG;AAC1B;AACA,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE;AAC1C,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE;AACxC;AACA,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE;AACzE,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;AAC5C,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AACjD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS;AAClE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS;AAClE,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAC7E,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC;AAChB,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,GAAG;AAC1B,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC;AACtB;AACA,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE;AAC1C,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE;AACxC;AACA,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,KAAK,CAAC,EAAE,aAAa,CAAC,CAAC,GAAG,CAAC,EAAE;AAChD,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,aAAa,CAAC,CAAC,IAAI,CAAC,EAAE;AACxD;AACA,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;AAClD,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC;AAC9B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAC/F,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG;AACpG,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE;AACpC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI;AACnG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC;AACxE,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AACvE,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AACpE,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC;AAC3B,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACT,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK;AACjF,CAAC,CAAC;AACF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC;AACzC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC,UAAU,CAAC,MAAM;AACnE,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AACxE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;AACnB,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAChC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAClB,IAAI,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE;AACjD,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC;AACX,IAAI,MAAM,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,EAAE;AAC/C,GAAG,CAAC;AACJ,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE;AAC1C,EAAE,EAAE;AACJ;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AAC/B,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,EAAE;AACrB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACT,EAAE,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACxC,GAAG,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE;AACnB,EAAE,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAClB,GAAG,OAAO,CAAC,CAAC,KAAK,CAAC,EAAE;AACpB,EAAE,CAAC,CAAC,EAAE;AACN,CAAC,CAAC;AACF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;AACrC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE;AACnF,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC;AAClF,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC;AAC1F,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC3D,CAAC,GAAG,CAAC,MAAM,CAAC;AACZ;AACA,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACpC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAChB,GAAG,MAAM,CAAC,EAAE,QAAQ,GAAG,OAAO,GAAG,OAAO,GAAG;AAC3C,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;AACV,GAAG,MAAM,CAAC,EAAE,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG;AAC1C,EAAE,CAAC;AACH,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO;AACtD,CAAC,EAAE,CAAC,CAAC;AACL,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,aAAa,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE;AACjD,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,CAAC,GAAG,CAAC,KAAK;AAC5C,CAAC,CAAC,CAAC,CAAC;AACJ,EAAE,MAAM,CAAC,eAAe,CAAC,CAAC,KAAK,CAAC,EAAE;AAClC,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK;AAC3D,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AAC3C,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,EAAE;AAC5C,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,UAAU,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACnD,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACrD,IAAI,MAAM,CAAC,eAAe,CAAC,CAAC,KAAK,CAAC,EAAE;AACpC,GAAG,CAAC,CAAC,EAAE;AACP,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;AACV,GAAG,MAAM,CAAC,eAAe,CAAC,CAAC,MAAM,CAAC,EAAE;AACpC,EAAE,CAAC;AACH,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACT,EAAE,MAAM,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE;AACnE,CAAC,CAAC;AACF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,GAAG;AAC/F,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC;AACpE,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;AAC/E,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,aAAa,CAAC;AACpC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACpB,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;AACtF,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC;AACrD,EAAE,IAAI,CAAC,cAAc,GAAG;AACxB,CAAC,CAAC;AACF,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC;AAC3C,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,gBAAgB,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;AACnF,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC;AAClD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC9D,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE;AAC5C;AACA,CAAC,IAAI,EAAE,OAAO;AACd,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC;AACpF,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE;AACvF;AACA,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC;AACtB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC;AACzB,CAAC,IAAI,CAAC,aAAa,GAAG;AACtB;AACA,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC;AAClE,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC7D,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC;AAClC;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;AACpC,EAAE,EAAE,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM;AAClE,EAAE,MAAM,CAAC,IAAI,CAAC;AACd,CAAC,CAAC;AACF;AACA,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACX,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,GAAG;AACtB,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,EAAE;AACpB,CAAC,EAAE;AACH;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACpB,EAAE,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE;AACtC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACT,EAAE,IAAI,EAAE,KAAK,CAAC,MAAM,GAAG;AACvB,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO;AAChC,EAAE,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE;AAC5B,EAAE,MAAM,CAAC;AACT,CAAC,CAAC;AACF;AACA,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE;AACxC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE;AAClD,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE;AAC7D;AACA,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;AACxF,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO;AACzF,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE;AAC3B;AACA,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;;ACtrBF,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,eAAe;AACjC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO;AACjD,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAC,QAAQ,CAAC,qBAAqB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACpE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;AACrB,EAAE,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC;AAChB,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE;AACb;AACA,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AACrD;AACA,CAAC,EAAE,CAAC,MAAM;AACV,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;AACtB,EAAE,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC;AACpB,CAAC,CAAC,CAAC,EAAE;AACL;AACA,CAAC,EAAE,CAAC,cAAc;AAClB,CAAC,IAAI,CAAC,qBAAqB,GAAG;AAC9B,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;AACtB,EAAE,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;AACtB,CAAC,CAAC,CAAC,EAAE;AACL,EAAE;AACF;AACA,EAAE,CAAC,KAAK,CAAC,EAAE;AACX;AACA,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,EAAE;AAClE;AACA,EAAE,CAAC,OAAO,CAAC,EAAE;AACb;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC7D,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE;AACjB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACzE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAC7C,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK;AACzB,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE;AACtB,EAAE,IAAI,CAAC,KAAK,GAAG;AACf,EAAE,MAAM,CAAC,KAAK,CAAC;AACf,CAAC,CAAC;AACF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI;AAChE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG;AACrE,CAAC,CAAC,CAAC,QAAQ,CAAC;AACZ,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC,qBAAqB,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACvE,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC;AAC1E,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,EAAE;AAC5B,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACT,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AAC/B,CAAC,CAAC;AACF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC;AACxB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC1D,CAAC,IAAI,CAAC,qBAAqB,GAAG;AAC9B,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC;AACzB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,QAAQ;AAChD,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC3D,CAAC,IAAI,CAAC,qBAAqB,GAAG;AAC9B,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACpE,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,EAAE;AAC1E,CAAC,IAAI,CAAC,qBAAqB,GAAG;AAC9B,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;;AC5FF,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,eAAe;AACjC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO;AACjD,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE;AACrF,CAAC,CAAC,EAAE,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC;AAChD,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC;AAC1F,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC;AAC1E,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC;AAC3F,CAAC,CAAC,EAAE,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC;AACrF,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,wBAAwB,CAAC,CAAC,CAAC,QAAQ,CAAC,4BAA4B,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAClF,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;AACrB,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AACd,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE;AACb,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC;AAC1B,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,wBAAwB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AAC5D;AACA,CAAC,EAAE,CAAC,UAAU;AACd,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC;AACvB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC;AACnC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG;AAC7D,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE;AAC5E;AACA,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ;AACtB,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AACvB,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK;AAC3B,GAAG,CAAC,KAAK,EAAE;AACX,GAAG,CAAC,WAAW,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AAC9B,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;AACjC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE;AACvC,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,MAAM;AACV,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;AACtB,EAAE,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC;AACpB,CAAC,CAAC,CAAC,EAAE;AACL;AACA,CAAC,EAAE,CAAC,cAAc;AAClB,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACvC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE;AAC1C,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AACvB,EAAE,IAAI,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC,EAAE;AAC5D,EAAE,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC,IAAI,CAAC;AACpC,EAAE,IAAI,CAAC,2BAA2B,GAAG;AACrC,CAAC,CAAC;AACF,EAAE;AACF;AACA,EAAE,CAAC,KAAK,CAAC,EAAE;AACX;AACA,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,wBAAwB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,EAAE;AACzE;AACA,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE;AACpB;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,wBAAwB,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACxF,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,wBAAwB,CAAC,MAAM,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AAC/F,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,EAAE,KAAK,CAAC,SAAS,GAAG;AAC7C,CAAC,MAAM,CAAC,KAAK,CAAC;AACd,EAAE;AACF;AACA,EAAE,CAAC,OAAO,CAAC,EAAE;AACb;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,wBAAwB,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACxE,CAAC,EAAE,CAAC,EAAE,CAAC,wBAAwB,CAAC,MAAM,CAAC,SAAS,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AAC9E,CAAC,IAAI,CAAC,UAAU,GAAG;AACnB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC;AACxB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,wBAAwB,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACjE,CAAC,IAAI,CAAC,UAAU,GAAG;AACnB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,wBAAwB,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACvE,CAAC,EAAE,CAAC,EAAE,CAAC,wBAAwB,CAAC,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AAC7E,CAAC,IAAI,CAAC,UAAU,GAAG;AACnB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK;AACpE,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,wBAAwB,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACtE,CAAC,EAAE,CAAC,CAAC;AACL,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;AACnE,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ;AAChE,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE;AAChB,CAAC,CAAC,CAAC,CAAC;AACJ,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE;AAC1B,CAAC,CAAC;AACF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC;AACnD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC,QAAQ,CAAC,SAAS,EAAE;AAC3E,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM;AAChB,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,wBAAwB,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACnE,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,WAAW,CAAC,CAAC,WAAW,CAAC,CAAC,cAAc,CAAC,CAAC,gBAAgB,CAAC;AAC9E,EAAE,WAAW,CAAC,CAAC,SAAS,CAAC,CAAC,WAAW,CAAC,CAAC,QAAQ,CAAC;AAChD;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AAC7C,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AACxB,GAAG,IAAI,EAAE,KAAK;AACd,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;AAC7B,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AACjC,IAAI,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM;AAC/D,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE;AACxB;AACA,GAAG,IAAI,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE;AACrD;AACA,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,GAAG;AACrC;AACA,GAAG,YAAY,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,YAAY,CAAC;AAChD;AACA,GAAG,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO;AAC9D,GAAG,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE;AACnC,GAAG,WAAW,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,WAAW,GAAG;AAC3C,GAAG,WAAW,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,WAAW,GAAG;AAC3C;AACA,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM;AAC7B,GAAG,IAAI,EAAE,KAAK;AACd,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AACjC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;AAC5B,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE;AACf,GAAG,cAAc,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,WAAW,GAAG;AAC9C;AACA,GAAG,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC;AAC1F,GAAG,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC;AAClF,GAAG,gBAAgB,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,YAAY,CAAC;AACrE,GAAG,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,cAAc,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,gBAAgB,CAAC,EAAE;AAC7E;AACA,GAAG,IAAI,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE;AAClD;AACA,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM;AAC7E,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM;AACvE,GAAG,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG;AAC5F,GAAG,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;AAC1C,IAAI,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,SAAS,CAAC,EAAE;AAC3C,IAAI,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC;AACjC,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE;AAC1B,GAAG,CAAC;AACJ,EAAE,CAAC;AACH,EAAE,WAAW,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC;AAC5E,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;AAC3C,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE;AAC5E,GAAG,EAAE,CAAC,KAAK;AACX,GAAG,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE;AAC9C,GAAG,IAAI,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE;AAClD;AACA,GAAG,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;AACvB,IAAI,IAAI,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,WAAW,CAAC,EAAE;AACjD,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AAC3C,KAAK,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,WAAW,CAAC,EAAE;AAC9C,IAAI,CAAC;AACL,GAAG,CAAC;AACJ;AACA,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC;AAClC,GAAG,IAAI,CAAC,aAAa,GAAG;AACxB,EAAE,CAAC;AACH,CAAC,CAAC;AACF,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,wBAAwB,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACxE,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE;AAC1B,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC;AAC9C,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC;AACpB,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,wBAAwB,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACpE,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC;AACzB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;AACrD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC;AACpB,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,wBAAwB,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACrE,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC;AACxB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,wBAAwB,CAAC,SAAS,CAAC,qBAAqB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACrF,CAAC,EAAE,CAAC,EAAE,CAAC,wBAAwB,CAAC,MAAM,CAAC,SAAS,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,EAAE;AAC3F,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AACvC,EAAE,IAAI,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE;AAC3C,CAAC,CAAC;AACF,EAAE;;AC1NF,GAAG;AACH,CAAC,CAAC,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK;AACzF,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK;AAC5F,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC;AAClG,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI;AAChG,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC;AACpD,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI;AACnG,CAAC,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC;AACjB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC;AAC3F,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG;AAC7F,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC;AAC/B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC;AAC3E,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,EAAE;AACrG,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,CAAC,OAAO;AACf,CAAC,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC;AACzC,CAAC,CAAC,KAAK,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,CAAC,CAAC;AACtD,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE;AAC7B,CAAC,CAAC,SAAS,OAAO,CAAC,CAAC,CAAC;AACrB,CAAC,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE;AACpC,CAAC,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE;AACpC,CAAC,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;AACnC,CAAC,CAAC,SAAS,CAAC;AACZ,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACX,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,QAAQ,EAAE,OAAO,CAAC,EAAE;AAC/C,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,CAAC,OAAO;AACf,CAAC,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC;AACvE,CAAC,CAAC,KAAK,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,CAAC,CAAC;AACtD,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE;AAC7B,CAAC,CAAC,SAAS,OAAO,CAAC,CAAC,CAAC;AACrB,CAAC,CAAC,aAAa,CAAC;AAChB,CAAC,CAAC,iBAAiB,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE;AACpC,CAAC,CAAC,iBAAiB,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;AACtC,CAAC,CAAC,aAAa,EAAE;AACjB,CAAC,CAAC,aAAa,CAAC;AAChB,CAAC,CAAC,iBAAiB,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE;AACpC,CAAC,CAAC,iBAAiB,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;AACtC,CAAC,CAAC,aAAa,EAAE;AACjB,CAAC,CAAC,aAAa,CAAC;AAChB,CAAC,CAAC,iBAAiB,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE;AACpC,CAAC,CAAC,iBAAiB,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;AACxC,CAAC,CAAC,aAAa,CAAC;AAChB,CAAC,CAAC,SAAS,CAAC;AACZ,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACX,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,QAAQ,EAAE,OAAO,CAAC,EAAE;AAC/C,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,mBAAmB,CAAC,wBAAwB;AAChG,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,eAAe;AACjC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO;AACjD,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE;AAC3F,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE;AAC/G,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK;AAC9G,CAAC,CAAC,EAAE,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,GAAG,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG;AACjH,CAAC,CAAC,EAAE,UAAU,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC;AAC7F,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE;AAChE,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,CAAC,CAAC,QAAQ,CAAC,uBAAuB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACxE,CAAC,EAAE,CAAC,aAAa,CAAC,cAAc;AAChC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;AACrB,EAAE,YAAY,CAAC,CAAC,KAAK;AACrB,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE;AACb;AACA,CAAC,EAAE,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC;AACrD,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC;AAC1B;AACA,CAAC,EAAE,CAAC,GAAG,CAAC,WAAW,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,KAAK,CAAC;AAC3D,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;AACvB,EAAE,MAAM,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE;AACrC,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AACvD;AACA,CAAC,EAAE,CAAC,UAAU;AACd,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC;AAC7G,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC;AAChD,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,cAAc,CAAC,CAAC,EAAE;AAC1D,EAAE,SAAS,CAAC,CAAC,CAAC,IAAI,EAAE;AACpB,EAAE,QAAQ,CAAC,CAAC,IAAI,CAAC,QAAQ;AACzB,CAAC,CAAC,CAAC,EAAE;AACL,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,EAAE,MAAM,CAAC;AAClD,EAAE,CAAC;AACH,GAAG,MAAM,CAAC,CAAC,IAAI,CAAC;AAChB,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC;AACf,GAAG,CAAC,kBAAkB,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC;AACtC,GAAG,QAAQ,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE;AAC9B,EAAE,EAAE;AACJ,EAAE,MAAM,CAAC,IAAI;AACb,CAAC,CAAC,CAAC,EAAE;AACL;AACA,CAAC,EAAE,CAAC,MAAM;AACV,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;AACtB,EAAE,MAAM,CAAC,CAAC,CAAC,aAAa,EAAE;AAC1B,EAAE,KAAK,CAAC,CAAC,CAAC,YAAY,CAAC;AACvB,CAAC,CAAC,CAAC,EAAE;AACL,CAAC,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;AACrC,EAAE,KAAK,CAAC,CAAC,CAAC,qBAAqB,CAAC;AAChC,CAAC,CAAC,CAAC,EAAE;AACL,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;AAC3B,EAAE,MAAM,CAAC,CAAC,CAAC,YAAY,EAAE;AACzB,EAAE,GAAG,CAAC,CAAC,CAAC,iBAAiB,EAAE;AAC3B,EAAE,MAAM,CAAC,CAAC,CAAC,iBAAiB,EAAE;AAC9B,EAAE,MAAM,CAAC,CAAC,CAAC,YAAY,CAAC;AACxB,CAAC,CAAC,CAAC,EAAE;AACL;AACA,CAAC,EAAE,CAAC,cAAc;AAClB,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;AACpB,EAAE,IAAI,CAAC,CAAC,CAAC,QAAQ,EAAE;AACnB,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,GAAG;AACxC,EAAE,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC,IAAI,CAAC;AAC7B,CAAC,CAAC,CAAC,EAAE;AACL,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK;AACrD,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AACtC,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE;AACpC,CAAC,CAAC;AACF,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;AAC3B,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC,CAAC;AAChD,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,IAAI,CAAC,cAAc,EAAE,OAAO,CAAC,EAAE;AACvD,CAAC,IAAI,EAAE,OAAO;AACd,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,CAAC,CAAC;AAC1C,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE;AACzB,CAAC,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE;AAC5C,CAAC,IAAI,CAAC,iBAAiB,GAAG;AAC1B,EAAE;AACF;AACA,EAAE,CAAC,KAAK,CAAC,EAAE;AACX;AACA,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,EAAE;AACpE;AACA,EAAE,CAAC,OAAO,CAAC,EAAE;AACb;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC;AAC3B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,MAAM;AAC/C,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC3D,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;AAClB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;AACxC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM;AACpD,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC5D,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC;AAC9B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK;AAClC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACxE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,KAAK,CAAC,EAAE;AACjD;AACA,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,EAAE;AAC/B,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,mBAAmB,EAAE,CAAC,CAAC,CAAC,CAAC;AACzC,EAAE,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,KAAK,CAAC,EAAE;AACnC,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC;AAC5B,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE;AAC3B,CAAC,CAAC;AACF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC;AAC7B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAChE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC;AAC5B,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,EAAE;AAC5B,CAAC,CAAC;AACF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC;AAC9B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,SAAS,CAAC,qBAAqB,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACzE,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG;AACpB,CAAC,IAAI,CAAC,KAAK,GAAG;AACd,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;AAC7B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI;AAC/C,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACtE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE;AACjC,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;AAClC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACrE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,EAAE;AAC3D,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,EAAE;AAC/B,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,mBAAmB,EAAE,CAAC,CAAC,CAAC,CAAC;AACzC,EAAE,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,KAAK,CAAC,EAAE;AACnC,CAAC,CAAC;AACF,CAAC,IAAI,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE;AACrF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;AAC7B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI;AACpD,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AAC3E,CAAC,IAAI,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,IAAI,EAAE,CAAC,SAAS,CAAC,EAAE;AAC1E,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AACzE,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM;AACjB,CAAC,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,EAAE;AAC/E;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;AAC7B,EAAE,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,EAAE;AACvD,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACnB,EAAE,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,EAAE;AAC7C,CAAC,CAAC;AACF;AACA,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC;AAC5C,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE;AACxF,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AACvE,CAAC,IAAI,CAAC,OAAO,EAAE;AACf,EAAE,CAAC,UAAU,EAAE;AACf,EAAE,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AAC5C,GAAG,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC;AACvC,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC;AACnB,IAAI,KAAK,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI;AACzD,GAAG,CAAC,CAAC,EAAE;AACP,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE;AACR;AACA,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;;AC1QF,GAAG;AACH,CAAC,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC;AAC7F,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC;AAC/F,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC;AACxG,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC;AAC5F,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;AACzD,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC;AAC5F,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC;AACnF,CAAC,CAAC,GAAG,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC;AAClE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK;AACjG,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC;AAC5C,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC;AACpF,CAAC,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC;AACvE,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;AAC3B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE;AACrG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC;AACnD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE;AACpG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,EAAE;AACxE,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC;AAC1F,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,oBAAoB;AACxE,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM;AACxB,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY;AACnC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa;AACpC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,WAAW,CAAC,KAAK,CAAC,MAAM;AACjD,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO;AACjD,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,GAAG,CAAC;AAC9E,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC;AACf,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE;AACvE,CAAC,CAAC,EAAE,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC;AAC/B,CAAC,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC;AACjE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS;AAC3E,CAAC,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC;AACrB,CAAC,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC;AACjE,CAAC,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,EAAE;AAChF,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC;AACzC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS;AAChF,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK;AAC7E,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;AAC/E,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG;AAChF,CAAC,CAAC,EAAE,KAAK,CAAC;AACV,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC;AAC9E,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC;AAC7C,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE;AAChF,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC;AACnB,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE;AAChE,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,SAAS;AAC/D,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACrE,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM;AAChE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AACjE,EAAE,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC;AACvB,EAAE,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC;AACnC,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,SAAS;AACpD,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AACnC,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE;AACxC,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,aAAa,CAAC,cAAc;AAChC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE;AACnE;AACA,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AAC/C;AACA,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;AAC7D,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;AACxB,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;AACP,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;AAC1F;AACA,CAAC,EAAE,CAAC,UAAU;AACd,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC;AAChC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG;AAClB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG;AACnB,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE;AACnE,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE;AAC9B,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE;AAC9B,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE;AAC3B,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;AACnB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC;AACrC;AACA,CAAC,EAAE,CAAC,MAAM;AACV,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,EAAE;AACjE;AACA,CAAC,EAAE,CAAC,cAAc;AAClB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;AAC3B,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;AAC1D,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE;AACV,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC;AACvC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,UAAU,EAAE,CAAC,EAAE;AAC3D,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;AAC1B,GAAG,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,UAAU,EAAE,CAAC,EAAE;AAC3D,EAAE,CAAC;AACH,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACT,EAAE,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACxC,GAAG,IAAI,CAAC,WAAW,CAAC,kBAAkB,GAAG;AACzC,EAAE,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;AACnB,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;AAC1B,GAAG,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACxC,IAAI,IAAI,CAAC,WAAW,CAAC,kBAAkB,GAAG;AAC1C,GAAG,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;AACpB,EAAE,CAAC;AACH,CAAC,CAAC;AACF,CAAC,IAAI,EAAE,OAAO;AACd,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;AAClC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,UAAU,EAAE,CAAC,CAAC;AAC7E,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE;AACxB,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,EAAE;AACjD,CAAC,IAAI,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,EAAE;AACrD,CAAC,IAAI,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,EAAE;AACzD,CAAC,IAAI,EAAE,KAAK;AACZ,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;AACxC,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,EAAE;AACvC;AACA,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE;AACvC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE;AACzC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;AACnC,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS;AAC/D,CAAC,IAAI,CAAC,WAAW,GAAG;AACpB,EAAE;AACF;AACA,EAAE,CAAC,KAAK,CAAC,EAAE;AACX;AACA,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE;AACnD,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE;AAC7D,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,EAAE;AAC9D;AACA,EAAE,CAAC,OAAO,CAAC,EAAE;AACb;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;AAC/B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ;AAC3C,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACjE,CAAC,IAAI,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,EAAE;AAClE,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC;AACzC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,MAAM;AACtC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACpD,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC;AACzB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,SAAS,CAAC,CAAC,GAAG;AACrF,CAAC,CAAC,CAAC,CAAC,YAAY,EAAE,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC;AAC7E,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC;AACpB,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACzD,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC;AACvD,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE;AAC5E,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC;AAC3C,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,IAAI;AACzC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC;AACnB,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACnE,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC;AAC/B,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE;AACzB,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AAC1B,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC;AACnF,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACpC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;AAClC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC;AAC9D,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACT,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG;AACb,CAAC,CAAC;AACF,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;AACpD,CAAC,CAAC,QAAQ;AACV,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;AACpC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE;AACpD,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC;AAClB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC;AAChC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC;AAClF,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAC/D,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAC9B,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC;AACtB,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACvE,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;AAClB,EAAE,CAAC;AACH,EAAE,EAAE,CAAC,QAAQ;AACb,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,CAAC;AACtD,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE;AACjB,EAAE,CAAC;AACH,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ;AACrB;AACA,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;AAC1B,GAAG,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;AAC9B,IAAI,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE;AACnD,IAAI,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE;AACnD,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC;AACX,IAAI,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE;AACnD,IAAI,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE;AACnD,GAAG,CAAC;AACJ,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;AACV,GAAG,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AAC3B,IAAI,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE;AACnD,IAAI,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE;AACnD,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;AACrC,IAAI,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE;AACnD,IAAI,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE;AACnD,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC;AACX,IAAI,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE;AACvC,IAAI,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE;AAC/D,GAAG,CAAC;AACJ,EAAE,CAAC;AACH,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC;AACzD,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI;AACnC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC,KAAK;AACpC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC,GAAG;AAClC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC,MAAM;AACrC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACrB,GAAG,IAAI,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE;AACxE,EAAE,CAAC;AACH,EAAE,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE;AAC/D,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC;AACrB,CAAC,CAAC;AACF;AACA,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC;AAClC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC;AACnG,CAAC,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC;AACjE,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAC7D,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,GAAG;AAC9B,CAAC,IAAI,CAAC,cAAc,GAAG;AACvB,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC;AACnC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC;AAC7F,CAAC,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC;AACjE,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AAC/D,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,GAAG;AAChC,CAAC,IAAI,CAAC,cAAc,GAAG;AACvB,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC;AACrD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC1D,CAAC,GAAG,CAAC,CAAC,CAAC;AACP,CAAC,IAAI,EAAE,QAAQ,CAAC,KAAK,GAAG;AACxB;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACnD,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE;AACrC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACT,EAAE,IAAI,EAAE,QAAQ,CAAC,MAAM,GAAG;AAC1B,EAAE,MAAM,CAAC;AACT,CAAC,CAAC;AACF;AACA,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAC9C,EAAE,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;AAC3E,CAAC,CAAC;AACF,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAC7C,EAAE,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;AACzE,CAAC,CAAC;AACF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC;AAClG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE;AAC7B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,SAAS;AAC5D,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC;AACnB,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC,wBAAwB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAC3E,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,wBAAwB,CAAC,CAAC,CAAC,CAAC;AACvE,EAAE,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,wBAAwB,CAAC,CAAC,KAAK,CAAC,EAAE;AAC5D,CAAC,CAAC;AACF,CAAC,MAAM,CAAC,KAAK,CAAC;AACd,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC;AACzE,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE;AACtD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;AACtD,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC;AAC/E,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE;AAChE,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AAC7E,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,UAAU,CAAC;AACxB;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;AACzB,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;AACvC,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC;AACf,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;AACnC,EAAE,CAAC,CAAC,EAAE;AACN;AACA,EAAE,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,YAAY,GAAG;AACrC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACT,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAC;AAC7C,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC;AACtB,GAAG,KAAK,CAAC,CAAC,CAAC;AACX,IAAI,MAAM,CAAC,CAAC,IAAI;AAChB,GAAG,EAAE;AACL,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,EAAE;AACzC,GAAG,MAAM,CAAC,CAAC,KAAK,CAAC;AACjB,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE;AAChB,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;AACxC,EAAE,CAAC,CAAC,EAAE;AACN,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;AAC5C,GAAG,UAAU,CAAC,QAAQ,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,EAAE;AACvD,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;AACV,GAAG,UAAU,CAAC,QAAQ,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AAC5C,EAAE,CAAC;AACH;AACA,EAAE,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,QAAQ,GAAG,SAAS,GAAG;AAC7C,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,WAAW;AAC3D,CAAC,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM;AAC5C,CAAC,CAAC;AACF,EAAE,IAAI,CAAC,WAAW,EAAE,KAAK,CAAC,EAAE;AAC5B,EAAE,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,EAAE;AAC7B,EAAE,IAAI,CAAC,WAAW,EAAE,OAAO;AAC3B,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,MAAM,CAAC,EAAE;AACtC;AACA,CAAC,MAAM,CAAC,UAAU,EAAE,OAAO,CAAC;AAC5B,EAAE;;AC3WF,GAAG;AACH,CAAC,CAAC,CAAC,kBAAkB,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;AAC1G,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,eAAe,GAAG;AACpH,CAAC,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC;AAC3E,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC;AAC7C,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC;AAC5F,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;AACzD,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC;AAC5F,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC;AACnF,CAAC,CAAC,GAAG,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC;AAClE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK;AACjG,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC;AAC5C,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC;AACpF,CAAC,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC;AACvE,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI;AACtH,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC;AACrB,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,CAAC,OAAO;AACf,CAAC,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB;AACzC,CAAC,CAAC,KAAK,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC;AAC3D,CAAC,CAAC,SAAS,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC;AACvC,CAAC,CAAC,aAAa,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC;AAC1C,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE;AACf,CAAC,CAAC,SAAS,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC;AACpC,CAAC,CAAC,aAAa,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;AAC9B,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE;AACf,CAAC,CAAC,SAAS,CAAC;AACZ,CAAC,CAAC,aAAa,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE;AACxE,CAAC,CAAC,aAAa,KAAK,CAAC,CAAC,CAAC,GAAG,EAAE;AAC5B,CAAC,CAAC,aAAa,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC;AACxC,CAAC,CAAC,SAAS,CAAC;AACZ,CAAC,CAAC,KAAK,EAAE;AACT,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,iBAAiB,EAAE,OAAO,CAAC,EAAE;AACxD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW;AAC7B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,WAAW,CAAC,KAAK,CAAC,MAAM;AACjD,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,MAAM;AACzD,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM;AACzB,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAC,QAAQ,CAAC,qBAAqB,CAAC,CAAC,WAAW,CAAC,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAC/F,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM;AAChE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AACjE,EAAE,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC;AACvB,EAAE,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC;AACnC,EAAE,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC;AACrC,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,EAAE;AAClE;AACA,CAAC,EAAE,CAAC,UAAU;AACd,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,YAAY,CAAC;AAClC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE;AAC9B,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE;AACnE;AACA,CAAC,EAAE,CAAC,cAAc;AAClB,CAAC,IAAI,EAAE,OAAO;AACd,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,EAAE;AACzC,CAAC,IAAI,EAAE,MAAM;AACb,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC;AAC/C,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,YAAY,EAAE,OAAO,CAAC,EAAE;AACxC,CAAC,IAAI,EAAE,KAAK;AACZ,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC,CAAC;AAC9C,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,EAAE;AACvC,CAAC,IAAI,EAAE,KAAK;AACZ,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE;AACvC,EAAE;AACF;AACA,EAAE,CAAC,KAAK,CAAC,EAAE;AACX;AACA,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,EAAE;;AC7E9D,GAAG;AACH,CAAC,CAAC,CAAC,eAAe,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,YAAY,EAAE;AACtF,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE;AACzF,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC;AACtE,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,EAAE;AACvD,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,CAAC,OAAO;AACf,CAAC,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM;AACtC,CAAC,CAAC,KAAK,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC;AAChD,CAAC,CAAC,SAAS,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC;AAC5C,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACX,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC;AAChD,CAAC,CAAC,SAAS,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC;AAC5C,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACX,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC;AACjD,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC;AAChD,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACX,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;AAC3B,CAAC,CAAC,SAAS,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;AAC3C,CAAC,CAAC,aAAa,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC;AACjC,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE;AACf,CAAC,CAAC,SAAS,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;AAC3C,CAAC,CAAC,aAAa,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC;AACjC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;AACd,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACX,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,QAAQ,EAAE,OAAO,CAAC,EAAE;AAC/C,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,oBAAoB;AACxE,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM;AACxB,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW;AAClC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY;AACnC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY;AACnC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO;AACjD,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC;AACzI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM;AAC3G,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;AAClG,CAAC,CAAC,EAAE,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC;AACvF,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC;AACjG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE;AAChE,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAC9D,CAAC,EAAE,CAAC,aAAa,CAAC,cAAc;AAChC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG;AACvB;AACA,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AAClD;AACA,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AAC9C,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AAC/C,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AAC/C;AACA,CAAC,EAAE,CAAC,UAAU;AACd,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE;AAChC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACrB,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAC;AACzD,GAAG,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC;AAC7B,GAAG,KAAK,CAAC,CAAC,CAAC;AACX,IAAI,MAAM,CAAC,CAAC,IAAI;AAChB,GAAG,EAAE;AACL,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,EAAE;AAC5C,GAAG,MAAM,CAAC,CAAC,KAAK,CAAC;AACjB,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE;AAChB,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;AACxC,EAAE,CAAC,CAAC,EAAE;AACN,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;AACnD,GAAG,IAAI,CAAC,iBAAiB,CAAC,QAAQ,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,EAAE;AAC1E,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;AACV,GAAG,IAAI,CAAC,iBAAiB,CAAC,QAAQ,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE;AAC/D,EAAE,CAAC;AACH,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,iBAAiB,EAAE,OAAO,CAAC;AAC/C,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACT,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE;AACvB,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,cAAc;AAClB,CAAC,IAAI,EAAE,MAAM;AACb,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC;AAC5C,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE;AACjD,CAAC,IAAI,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,EAAE;AACtD,CAAC,IAAI,EAAE,OAAO;AACd,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC;AACrC,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE;AACxC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACvC,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;AAChC,CAAC,CAAC;AACF,EAAE;AACF;AACA,EAAE,CAAC,KAAK,CAAC,EAAE;AACX;AACA,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE;AACtD,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE;AAC/D,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE;AAChE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE;AAChE;AACA,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE;AACvB;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,MAAM;AACV,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;;AC5GjD,GAAG;AACH,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK;AACjH,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE;AAChH,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC;AACnH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC;AACnF,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,EAAE;AACjG,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,UAAU,EAAE,CAAC,EAAE,IAAI;AAC5F,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE;AAClG,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,OAAO;AAC/F,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG;AACnG,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC;AACtE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,YAAY,CAAC;AACzF,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK;AACzD,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM;AAC1D,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,CAAC,OAAO;AACf,CAAC,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM;AAC/D,CAAC,CAAC,KAAK,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC;AAChD,CAAC,CAAC,SAAS,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC;AAClC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACX,CAAC,CAAC,KAAK,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC;AAChD,CAAC,CAAC,SAAS,WAAW,CAAC,CAAC,CAAC,QAAQ,EAAE;AACnC,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC;AAC3B,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACX,CAAC,CAAC,KAAK,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAC;AAClD,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;AAC1B,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACX,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC;AACjD,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC;AACjC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACX,CAAC,CAAC,KAAK,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;AAC3B,CAAC,CAAC,SAAS,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;AAC3C,CAAC,CAAC,aAAa,KAAK,CAAC,CAAC,CAAC,QAAQ,EAAE;AACjC,CAAC,CAAC,aAAa,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC;AAC3B,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE;AACf,CAAC,CAAC,SAAS,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;AAC3C,CAAC,CAAC,aAAa,KAAK,CAAC,CAAC,CAAC,QAAQ,EAAE;AACjC,CAAC,CAAC,aAAa,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC;AAC3B,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE;AACf,CAAC,CAAC,SAAS,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC;AAC1C,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACX,CAAC,CAAC,KAAK,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;AACzC,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE;AAC/B,CAAC,CAAC,SAAS,MAAM,CAAC,CAAC,EAAE,GAAG,CAAC,WAAW,EAAE;AACtC,CAAC,CAAC,SAAS,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC;AACxB,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;AACV,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE;AAC3C,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM;AACxB,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY;AACnC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO;AACjD,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,SAAS;AACtD,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,SAAS;AACtD,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS;AACxD,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC;AACpF,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACtD,CAAC,GAAG,CAAC,MAAM,CAAC;AACZ;AACA,CAAC,EAAE,CAAC,aAAa,CAAC,cAAc;AAChC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG;AACvB;AACA,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AAC9C;AACA,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;AAC1F;AACA,CAAC,EAAE,CAAC,MAAM;AACV,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;AAC9D;AACA,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI;AAChC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC;AACxB,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC5D,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC;AACzB,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,cAAc;AAClB,CAAC,IAAI,EAAE,OAAO;AACd,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;AACjC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;AACV,GAAG,MAAM,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC;AACzB,GAAG,MAAM,CAAC,CAAC,MAAM,CAAC;AAClB,GAAG,OAAO,CAAC,CAAC,MAAM,CAAC,OAAO;AAC1B,EAAE,CAAC,CAAC,EAAE;AACN,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACvC,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;AAChC,CAAC,CAAC;AACF,EAAE;AACF;AACA,EAAE,CAAC,KAAK,CAAC,EAAE;AACX;AACA,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE;AAClD,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE;AAC5D;AACA,EAAE,CAAC,MAAM,CAAC,EAAE;AACZ;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC;AAC1D,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM;AAChB,CAAC,EAAE;AACH;AACA,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE;AACvB;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,MAAM;AACV,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;AACzC;AACA,EAAE,CAAC,OAAO,CAAC,EAAE;AACb;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;AAC7B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK;AACvC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM;AAChB,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACvD,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC/B,EAAE,MAAM,CAAC,KAAK,CAAC;AACf,CAAC,CAAC;AACF,EAAE;;AClIF,GAAG;AACH,CAAC,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC;AAChH,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,YAAY,EAAE;AACxF,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,CAAC,OAAO;AACf,CAAC,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM;AACnC,CAAC,CAAC,KAAK,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;AAC3C,CAAC,CAAC,SAAS,QAAQ,CAAC,CAAC,KAAK,CAAC;AAC3B,CAAC,CAAC,SAAS,MAAM,CAAC,CAAC,IAAI,CAAC;AACxB,CAAC,CAAC,SAAS,MAAM,CAAC,CAAC,IAAI,CAAC;AACxB,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC,CAAC;AAC3E,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACX,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE;AAC5C,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM;AACxB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO;AACjD,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,SAAS;AAC7D,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC;AAC5F,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC;AACrF,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC;AAC5G,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACxD,CAAC,EAAE,CAAC,aAAa,CAAC,cAAc;AAChC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;AACrB,EAAE,UAAU,CAAC,CAAC,KAAK,CAAC;AACpB,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC;AAChB,EAAE,QAAQ,CAAC,CAAC,IAAI,CAAC;AACjB,EAAE,MAAM,CAAC,CAAC,KAAK;AACf,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE;AACb;AACA,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AAC/C;AACA,CAAC,EAAE,CAAC,cAAc;AAClB,CAAC,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,EAAE;AAC/C,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;AAC3B,EAAE,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC,EAAE;AAC3D,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACvB,EAAE,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,EAAE;AACvD,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AACzB,EAAE,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,EAAE;AACzD,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACvB,EAAE,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,EAAE;AACvD,CAAC,CAAC;AACF,EAAE;AACF;AACA,EAAE,CAAC,KAAK,CAAC,EAAE;AACX;AACA,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE;AACnD;AACA,EAAE,CAAC,OAAO,CAAC,EAAE;AACb;AACA,GAAG;AACH,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM;AACzB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK;AACnF,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACjD,CAAC,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,KAAK,GAAG;AAC9C,EAAE;;ACjEF,GAAG;AACH,CAAC,CAAC,CAAC,gBAAgB,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,GAAG;AACjG,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK;AACnG,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC;AAC/C,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC;AACpF,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,CAAC,OAAO;AACf,CAAC,CAAC,KAAK,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK;AACxD,CAAC,CAAC,KAAK,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC;AACjD,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,CAAC;AACjB,CAAC,CAAC,SAAS,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE;AACvD,CAAC,CAAC,SAAS,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AACzD,CAAC,CAAC,OAAO,CAAC;AACV,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACX,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE;AAC7C,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM;AACxB,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY;AACnC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO;AACjD,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,GAAG,EAAE,CAAC,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC;AAC9F,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC,QAAQ,CAAC,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAClE,CAAC,EAAE,CAAC,aAAa,CAAC,cAAc;AAChC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG;AACvB;AACA,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AACpD;AACA,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;AAC1F;AACA,CAAC,EAAE,CAAC,cAAc;AAClB,CAAC,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,EAAE;AACpD,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACvC,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;AAChC,CAAC,CAAC;AACF,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,MAAM,CAAC,EAAE;AACxD,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE;;AC7ClE,GAAG;AACH,CAAC,CAAC,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK;AACvF,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,OAAO,CAAC;AAC7E,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;AAC3E,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,CAAC,OAAO;AACf,CAAC,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC;AACvC,CAAC,CAAC,KAAK,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAC;AACvD,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,iBAAiB,EAAE;AACtC,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE;AAC/B,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,EAAE;AAClB,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACX,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,WAAW,EAAE,OAAO,CAAC,EAAE;AAClD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,eAAe;AACjC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO;AACjD,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,YAAY,CAAC,MAAM,CAAC,MAAM,EAAE;AAC1H,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,YAAY,CAAC,MAAM,CAAC,MAAM,EAAE;AACzH,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;AACrF,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK;AACtD,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK;AACrD,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI;AAC5E,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC;AACzG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC;AAChF,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAC,QAAQ,CAAC,qBAAqB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACpE,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;AAC1B,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC,EAAE;AAC/C;AACA,CAAC,EAAE,CAAC,aAAa,CAAC,cAAc;AAChC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;AACrB,EAAE,YAAY,CAAC,CAAC,KAAK,CAAC;AACtB,EAAE,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC;AACjB,EAAE,GAAG,CAAC,CAAC,QAAQ,CAAC;AAChB,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;AACV,EAAE,QAAQ,CAAC,CAAC,IAAI,CAAC;AACjB,EAAE,WAAW,CAAC,CAAC,IAAI;AACnB,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE;AACb;AACA,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,aAAa;AAC9B,CAAC,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;AAClC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;AACnB;AACA,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;AAC/D,EAAE,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC;AAChB,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;AACP;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;AAC5B,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,MAAM,CAAC;AACtD,GAAG,CAAC;AACJ,IAAI,QAAQ,CAAC,CAAC,IAAI,CAAC,UAAU,GAAG;AAChC,IAAI,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;AACjB,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC,EAAE;AACvD,IAAI,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC;AACpB,GAAG,EAAE;AACL,GAAG,MAAM,CAAC,WAAW;AACrB,EAAE,CAAC,CAAC,EAAE;AACN,EAAE,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE;AAC1D,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,MAAM,CAAC;AACrD,GAAG,CAAC;AACJ,IAAI,QAAQ,CAAC,CAAC,IAAI,CAAC,UAAU,GAAG;AAChC,IAAI,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;AACjB,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC,EAAE;AACtD,IAAI,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC;AACf,GAAG,EAAE;AACL,GAAG,MAAM,CAAC,UAAU;AACpB,EAAE,CAAC,CAAC,EAAE;AACN,EAAE,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE;AACzD,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,MAAM;AACV,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;AAClB,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AACvC,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,cAAc,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC;AAC9D,CAAC,CAAC,CAAC,EAAE;AACL,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;AAC5B,EAAE,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;AAClC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;AACjC,EAAE,CAAC,CAAC,EAAE;AACN,EAAE,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;AACnC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;AACjC,EAAE,CAAC,CAAC,EAAE;AACN,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK;AACnB,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE;AAC9B,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;AAC5B,EAAE,CAAC,KAAK;AACR,GAAG,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;AACxC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,EAAE;AACvC,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,cAAc;AAClB,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE;AACjE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE;AACzC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE;AAC9C,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK;AACjE,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,eAAe;AACvD,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;AACxD;AACA,CAAC,IAAI,EAAE,OAAO;AACd,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAC;AACxC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,QAAQ,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;AACxE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE;AACpB,EAAE;AACF;AACA,EAAE,CAAC,KAAK,CAAC,EAAE;AACX;AACA,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,EAAE;AAClE;AACA,EAAE,CAAC,OAAO,CAAC,EAAE;AACb;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO;AACxC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI;AACxB,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACvE,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC;AAC5B,CAAC,IAAI,CAAC,eAAe,GAAG;AACxB,EAAE;AACF,EAAE,CAAC,QAAQ,CAAC,aAAa;AACzB,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC,eAAe,CAAC;AACnG;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO;AACxC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK;AAC/B,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACjE,CAAC,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC;AAC1B,EAAE;AACF,EAAE,CAAC,QAAQ,CAAC,aAAa;AACzB,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC,eAAe,CAAC;AACnG;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM;AAClC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK;AAC5C,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK;AAC5C,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AACpE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AACnB,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;AAC5F,CAAC,CAAC;AACF,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;AAChB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;AAChB,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;AACrC,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;AACrC,CAAC,IAAI,CAAC,eAAe,GAAG;AACxB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK;AACxB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM;AAChD,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC1D,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;AAC/B,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM;AAC1B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI;AACnC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC;AAC5E,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AACzE,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACnB,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE;AACnD,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAC3B,EAAE,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;AACvB,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC9B,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE;AACxD,CAAC,CAAC;AACF,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AAClB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC;AAC1B,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;AACvC,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACjE,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AACtB,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE;AAC9F,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,CAAC;AACzE,EAAE,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE;AACxB,CAAC,CAAC;AACF,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,EAAE;AAC9E,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM;AAClC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI;AACxC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACzD,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE;AACrC,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM;AAClD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM;AACpD,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACjE,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,QAAQ,GAAG;AACzB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM;AACjC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM;AAC1C,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACpE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,eAAe,GAAG;AACnC;AACA,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;AAChB,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC9C,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE;AACrD,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACpB,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACR,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACT,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;AAChB,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;AACpD,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;AAC5B,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE;AACvB,EAAE,CAAC;AACH,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACjB,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE;AACrB,CAAC,CAAC;AACF,EAAE;AACF,GAAG;AACH,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK;AACjB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK;AACpC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC;AACpB,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACvE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;AAChB,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AACtB,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,UAAU,GAAG;AAC5B,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACtC,EAAE,MAAM,CAAC,KAAK,CAAC;AACf,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACpD,EAAE,MAAM,CAAC,KAAK,CAAC;AACf,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AACtC,EAAE,MAAM,CAAC,KAAK,CAAC;AACf,CAAC,CAAC;AACF;AACA,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC;AAC7B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAC/B,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AACpE,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;AACrC,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC;AAC7B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK;AAC9B,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAChE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AACf;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC1D,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK;AAC3B,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AACtD,GAAG,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC;AAC7B,EAAE,CAAC;AACH,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACrC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,MAAM,CAAC;AACvC,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAC5C,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,MAAM,CAAC;AACtC,EAAE,CAAC;AACH;AACA,EAAE,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM;AACxB,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;AAC9B,GAAG,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;AAC3C,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,WAAW,CAAC;AAC7C,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;AAClD,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,WAAW,CAAC;AAC5C,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;AACjD,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,UAAU,CAAC;AAC3C,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAC7C,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,MAAM,CAAC;AACxC,GAAG,CAAC;AACJ,EAAE,CAAC;AACH;AACA,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAChB,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC9B,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;AACzC,EAAE,CAAC;AACH;AACA,EAAE,MAAM,CAAC,KAAK,CAAC;AACf,CAAC,CAAC;AACF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC;AAC1B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK;AACzC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC9D,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC;AAC5B,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACtB,GAAG,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;AACtB,IAAI,IAAI,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;AAClC,IAAI,MAAM,CAAC,KAAK,CAAC;AACjB,GAAG,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC;AACxB,IAAI,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;AACnC,IAAI,MAAM,CAAC,KAAK,CAAC;AACjB,GAAG,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC;AAC1B,IAAI,IAAI,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE;AACtC,IAAI,MAAM,CAAC,KAAK,CAAC;AACjB,GAAG,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC;AAC5B,IAAI,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE;AACvC,IAAI,MAAM,CAAC,KAAK,CAAC;AACjB,EAAE,CAAC;AACH,CAAC,CAAC;AACF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AACvE,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM;AACjB,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,EAAE;AAC7E;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;AAC1B,EAAE,IAAI,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,EAAE;AACpD,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;AACzB,EAAE,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,EAAE;AACnD,CAAC,CAAC;AACF;AACA,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;;AC3WF,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE","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 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};\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 *         $( '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 *         $( '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 ( $.isFunction( msg ) ) {\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$( '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.$ = $;\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.join( ' ' ) );\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\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 jQuery ) {\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 dir=\"rtl\" style=\"font-size: 14px; width: 1px; height: 1px; position: absolute; top: -1000px; overflow: scroll\">A</div>' ),\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$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\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 */\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 */\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 */\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 ( $.isFunction( this[ methods[ i ] ] ) ) {\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 */\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 * 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 */\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 */\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.join( ' ' ) )\n\t\t.addClass( classes.on.join( ' ' ) );\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 *     var button2 = new OO.ui.ButtonWidget( {\n *         label: 'second',\n *         tabIndex: 2\n *     } );\n *     var button3 = new OO.ui.ButtonWidget( {\n *         label: 'third',\n *         tabIndex: 3\n *     } );\n *     var button4 = new OO.ui.ButtonWidget( {\n *         label: 'first',\n *         tabIndex: 1\n *     } );\n *     $( '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 */\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 */\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 */\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 */\nOO.ui.mixin.TabIndexedElement.prototype.focus = function () {\n\tif ( !this.isDisabled() ) {\n\t\tthis.$tabIndexed.focus();\n\t}\n\treturn this;\n};\n\n/**\n * Blur this element.\n *\n * @chainable\n */\nOO.ui.mixin.TabIndexedElement.prototype.blur = function () {\n\tthis.$tabIndexed.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 accessibility.\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.onMouseUpHandler = this.onMouseUp.bind( this );\n\tthis.onMouseDownHandler = this.onMouseDown.bind( this );\n\tthis.onKeyDownHandler = this.onKeyDown.bind( this );\n\tthis.onKeyUpHandler = this.onKeyUp.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 */\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.onMouseUpHandler, 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 mouse up events.\n *\n * @protected\n * @param {MouseEvent} e Mouse up event\n */\nOO.ui.mixin.ButtonElement.prototype.onMouseUp = 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.onMouseUpHandler, true );\n};\n\n/**\n * Handles mouse click events.\n *\n * @protected\n * @param {jQuery.Event} e Mouse click event\n * @fires click\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.onKeyUpHandler, true );\n};\n\n/**\n * Handles key up events.\n *\n * @protected\n * @param {KeyboardEvent} e Key up event\n */\nOO.ui.mixin.ButtonElement.prototype.onKeyUp = 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.onKeyUpHandler, true );\n};\n\n/**\n * Handles key press events.\n *\n * @protected\n * @param {jQuery.Event} e Key press event\n * @fires click\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 */\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 */\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 */\nOO.ui.mixin.GroupElement.prototype.addItems = function ( items, index ) {\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 */\nOO.ui.mixin.GroupElement.prototype.removeItems = function ( items ) {\n\tvar i, len, item, index;\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 */\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 * 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// 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 */\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 */\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\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// 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 */\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 */\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\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 * 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 */\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\n\t// Initialization\n\tthis.setLabel( config.label || this.constructor.static.label );\n\tthis.setLabelElement( config.$label || $( '<span>' ) );\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 */\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 jQuery ) && 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 );\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 */\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 jQuery ) {\n\t\tthis.$label.empty().append( label );\n\t} else {\n\t\tthis.$label.empty();\n\t}\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 *     var button2 = new OO.ui.ButtonWidget( {\n *         label: 'Destructive',\n *         flags: 'destructive'\n *     } );\n *     $( '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} ).join( ' ' );\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 * @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.join( ' ' ) );\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 * @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.join( ' ' ) )\n\t\t\t.removeClass( remove.join( ' ' ) );\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 *     $( '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 */\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 */\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` 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 *     $( '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 'accesskeyes' 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 */\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 *     $( '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 */\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 */\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 */\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 */\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 *     // Example: 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 *     var button2 = new OO.ui.ButtonWidget( {\n *         label: 'Add item'\n *     });\n *     var buttonGroup = new OO.ui.ButtonGroupWidget( {\n *         items: [button1, button2]\n *     } );\n *     $( 'body' ).append( buttonGroup.$element );\n *\n * @class\n * @extends OO.ui.Widget\n * @mixins OO.ui.mixin.GroupElement\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\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 );\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 */\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 icon widget with a label\n *     var myIcon = new OO.ui.IconWidget( {\n *         icon: 'help',\n *         title: 'Help'\n *      } );\n *      // Create a label.\n *      var iconLabel = new OO.ui.LabelWidget( {\n *          label: 'Help'\n *      } );\n *      $( '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.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.FlaggedElement.call( this, $.extend( {}, config, { $flagged: this.$element } ) );\n\n\t// Initialization\n\tthis.$element.addClass( 'oo-ui-iconWidget' );\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.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 *     // Example of an indicator widget\n *     var indicator1 = new OO.ui.IndicatorWidget( {\n *         indicator: 'required'\n *     } );\n *\n *     // Create a fieldset layout to add a label\n *     var fieldset = new OO.ui.FieldsetLayout();\n *     fieldset.addItems( [\n *         new OO.ui.FieldLayout( indicator1, { label: 'A required indicator:' } )\n *     ] );\n *     $( '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 *\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\n\t// Initialization\n\tthis.$element.addClass( 'oo-ui-indicatorWidget' );\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 );\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 *     // Examples of LabelWidgets\n *     var label1 = new OO.ui.LabelWidget( {\n *         label: 'plaintext label'\n *     } );\n *     var label2 = new OO.ui.LabelWidget( {\n *         label: $( '<a href=\"default.html\">jQuery label</a>' )\n *     } );\n *     // Create a fieldset layout with fields for each example\n *     var fieldset = new OO.ui.FieldsetLayout();\n *     fieldset.addItems( [\n *         new OO.ui.FieldLayout( label1 ),\n *         new OO.ui.FieldLayout( label2 )\n *     ] );\n *     $( '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 *     $( '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 */\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 */\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, algining 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 */\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\tthis.needsCustomPosition =\n\t\t\tthis.verticalPostion !== 'below' ||\n\t\t\tthis.horizontalPosition !== 'start' ||\n\t\t\t!OO.ui.contains( this.$floatableContainer[ 0 ], this.$floatable[ 0 ] );\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 */\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\tif ( !this.needsCustomPosition ) {\n\t\treturn this;\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 */\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 */\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\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\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] [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 popup widget.\n *     var popup = new OO.ui.PopupWidget( {\n *         $content: $( '<p>Hi there!</p>' ),\n *         padded: true,\n *         width: 300\n *     } );\n *\n *     $( '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.onMouseDownHandler = this.onMouseDown.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 jQuery ) {\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 mouse down events.\n *\n * @private\n * @param {MouseEvent} e Mouse down event\n */\nOO.ui.PopupWidget.prototype.onMouseDown = 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 mouse down listener.\n *\n * @private\n */\nOO.ui.PopupWidget.prototype.bindMouseDownListener = function () {\n\t// Capture clicks outside popup\n\tthis.getElementWindow().addEventListener( 'mousedown', this.onMouseDownHandler, 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.onMouseDownHandler, 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 mouse down listener.\n *\n * @private\n */\nOO.ui.PopupWidget.prototype.unbindMouseDownListener = function () {\n\tthis.getElementWindow().removeEventListener( 'mousedown', this.onMouseDownHandler, true );\n\tthis.getElementDocument().removeEventListener( 'click', this.onMouseDownHandler, true );\n};\n\n/**\n * Handles 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 key down listener.\n *\n * @private\n */\nOO.ui.PopupWidget.prototype.bindKeyDownListener = function () {\n\tthis.getElementWindow().addEventListener( 'keydown', this.onDocumentKeyDownHandler, true );\n};\n\n/**\n * Unbind key down listener.\n *\n * @private\n */\nOO.ui.PopupWidget.prototype.unbindKeyDownListener = function () {\n\tthis.getElementWindow().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 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.bindMouseDownListener();\n\t\t\t\tthis.bindKeyDownListener();\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.unbindMouseDownListener();\n\t\t\t\tthis.unbindKeyDownListener();\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 *     // Example of a popup button.\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 *     $( '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 */\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 */\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 *\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\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 );\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 */\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 */\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 */\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 *     // Example of 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 *     $( '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.onMouseUpHandler = this.onMouseUp.bind( this );\n\tthis.onMouseMoveHandler = this.onMouseMove.bind( this );\n\tthis.onKeyDownHandler = this.onKeyDown.bind( this );\n\tthis.onKeyPressHandler = this.onKeyPress.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.focus();\n\t}\n};\n\n/**\n * Handle mouse down events.\n *\n * @private\n * @param {jQuery.Event} e Mouse down event\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.onMouseUpHandler, true );\n\t\t\tthis.getElementDocument().addEventListener( 'mousemove', this.onMouseMoveHandler, true );\n\t\t}\n\t}\n\treturn false;\n};\n\n/**\n * Handle mouse up events.\n *\n * @private\n * @param {MouseEvent} e Mouse up event\n */\nOO.ui.SelectWidget.prototype.onMouseUp = 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.onMouseUpHandler, true );\n\tthis.getElementDocument().removeEventListener( 'mousemove', this.onMouseMoveHandler, true );\n\n\treturn false;\n};\n\n/**\n * Handle mouse move events.\n *\n * @private\n * @param {MouseEvent} e Mouse move event\n */\nOO.ui.SelectWidget.prototype.onMouseMove = 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 */\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 */\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 key down events.\n *\n * @protected\n * @param {KeyboardEvent} e Key down event\n */\nOO.ui.SelectWidget.prototype.onKeyDown = 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.unbindKeyDownListener();\n\t\t\t\tthis.unbindKeyPressListener();\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 key down listener.\n *\n * @protected\n */\nOO.ui.SelectWidget.prototype.bindKeyDownListener = function () {\n\tthis.getElementWindow().addEventListener( 'keydown', this.onKeyDownHandler, true );\n};\n\n/**\n * Unbind key down listener.\n *\n * @protected\n */\nOO.ui.SelectWidget.prototype.unbindKeyDownListener = function () {\n\tthis.getElementWindow().removeEventListener( 'keydown', this.onKeyDownHandler, 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 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 */\nOO.ui.SelectWidget.prototype.onKeyPress = 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\tif ( String.fromCodePoint ) {\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} 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\tif ( s.normalize ) {\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\tif ( matchText.normalize ) {\n\t\t\tmatchText = matchText.normalize();\n\t\t}\n\t\treturn re.test( matchText );\n\t};\n};\n\n/**\n * Bind key press listener.\n *\n * @protected\n */\nOO.ui.SelectWidget.prototype.bindKeyPressListener = function () {\n\tthis.getElementWindow().addEventListener( 'keypress', this.onKeyPressHandler, true );\n};\n\n/**\n * Unbind 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.unbindKeyPressListener = function () {\n\tthis.getElementWindow().removeEventListener( 'keypress', this.onKeyPressHandler, 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 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 */\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 */\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 */\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 */\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 */\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 */\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 */\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 */\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 */\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 * Currently this is just used to set `aria-activedescendant` 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 *     $( '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 myDropdown = 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 *     $( 'body' ).append( myDropdown.$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.CapsuleMultiselectWidget CapsuleMultiselectWidget}\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 * @cfg {number} [width] Width of the menu\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};\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.onKeyDown = 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.onKeyDown.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.onKeyDown.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\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.bindKeyDownListener = function () {\n\tif ( this.$input ) {\n\t\tthis.$input.on( 'keydown', this.onKeyDownHandler );\n\t} else {\n\t\tOO.ui.MenuSelectWidget.parent.prototype.bindKeyDownListener.call( this );\n\t}\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.MenuSelectWidget.prototype.unbindKeyDownListener = function () {\n\tif ( this.$input ) {\n\t\tthis.$input.off( 'keydown', this.onKeyDownHandler );\n\t} else {\n\t\tOO.ui.MenuSelectWidget.parent.prototype.unbindKeyDownListener.call( this );\n\t}\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.MenuSelectWidget.prototype.bindKeyPressListener = 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.bindKeyPressListener.call( this );\n\t}\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.MenuSelectWidget.prototype.unbindKeyPressListener = 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.unbindKeyPressListener.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 */\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.bindKeyDownListener();\n\t\t\tthis.bindKeyPressListener();\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.unbindKeyDownListener();\n\t\t\tthis.unbindKeyPressListener();\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 *     // Example: 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 *     $( '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 = $( '<span>' );\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.onKeyPressHandler,\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\trole: 'combobox',\n\t\t\t'aria-owns': this.menu.getElementId(),\n\t\t\t'aria-autocomplete': 'list'\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 jQuery ) {\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\tthis.$handle.attr(\n\t\t'aria-expanded',\n\t\tthis.$element.hasClass( 'oo-ui-dropdownWidget-open' ).toString()\n\t);\n};\n\n/**\n * Handle mouse click events.\n *\n * @private\n * @param {jQuery.Event} e Mouse click event\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 */\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 *\n *     var option2 = new OO.ui.RadioOptionWidget( {\n *         data: 'b',\n *         label: 'Unselected radio option'\n *     } );\n *\n *     var 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 *     $( '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.bindKeyDownListener.bind( this ),\n\t\tblur: this.unbindKeyDownListener.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_Multioptions\n *\n * @class\n * @extends OO.ui.Widget\n * @mixins OO.ui.mixin.ItemWidget\n * @mixins OO.ui.mixin.LabelElement\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\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 );\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 */\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 *\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\n\t// Events\n\tthis.aggregate( { change: 'select' } );\n\t// This is mostly for compatibility with CapsuleMultiselectWidget... 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 );\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 */\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 */\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 *\n *     var option2 = new OO.ui.CheckboxMultioptionWidget( {\n *         data: 'b',\n *         label: 'Unselected checkbox'\n *     } );\n *\n *     var multiselect=new OO.ui.CheckboxMultiselectWidget( {\n *         items: [ option1, option2 ]\n *      } );\n *\n *     $( '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 */\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, {label: 'Determinate', align: 'top'}),\n *        new OO.ui.FieldLayout( progressBar2, {label: 'Indeterminate', align: 'top'})\n *     ] );\n *     $( '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 */\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 */\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 */\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 'hidden'-type 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 *     $( '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.TitledElement\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\tOO.ui.mixin.TitledElement.call( this, $.extend( {}, config, { $titled: this.$input } ) );\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.TitledElement );\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 */\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 */\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 *     var checkbox2=new OO.ui.CheckboxInputWidget( {\n *         value: 'b'\n *     } );\n *     var checkbox3=new OO.ui.CheckboxInputWidget( {\n *         value:'c',\n *         disabled: true\n *     } );\n *     // Create a fieldset layout with fields for each checkbox.\n *     var 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 *     $( '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 */\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.$input.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 the same configuration options.\n *\n *     @example\n *     // Example: A DropdownInputWidget with three options\n *     var dropdownInput = new OO.ui.DropdownInputWidget( {\n *         options: [\n *             { data: 'a', label: 'First' },\n *             { data: 'b', label: 'Second'},\n *             { data: 'c', label: 'Third' }\n *         ]\n *     } );\n *     $( '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 `{ data: …, label: … }`\n * @cfg {Object} [dropdown] Configuration options for {@link OO.ui.DropdownWidget DropdownWidget}\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( config.dropdown );\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};\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 */\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 * intialized yet.\n *\n * @param {Object[]} options Array of menu options in the format `{ data: …, label: … }`\n * @private\n */\nOO.ui.DropdownInputWidget.prototype.setOptionsData = function ( options ) {\n\tvar\n\t\toptionWidgets,\n\t\twidget = this;\n\n\tthis.optionsDirty = true;\n\n\toptionWidgets = options.map( function ( opt ) {\n\t\tvar optValue;\n\n\t\tif ( opt.optgroup !== undefined ) {\n\t\t\treturn widget.createMenuSectionOptionWidget( opt.optgroup );\n\t\t}\n\n\t\toptValue = widget.cleanUpValue( opt.data );\n\t\treturn widget.createMenuOptionWidget(\n\t\t\toptValue,\n\t\t\topt.label !== undefined ? opt.label : optValue\n\t\t);\n\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\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 *     $( '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 */\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.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 the same configuration options.\n *\n *     @example\n *     // Example: 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 *     $( '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 */\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 *     // Example: 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 *     $( '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 */\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 *     // Example of a text input widget\n *     var textInput = new OO.ui.TextInputWidget( {\n *         value: 'Text input'\n *     } )\n *     $( '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\tif ( config.multiline ) {\n\t\tOO.ui.warnDeprecation( 'TextInputWidget: config.multiline is deprecated. Use the MultilineTextInputWidget instead. See T130434.' );\n\t\treturn new OO.ui.MultilineTextInputWidget( config );\n\t}\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.styleHeight = 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 */\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 */\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 */\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 */\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 */\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 */\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 */\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 */\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 */\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 */\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 && $.isFunction( result.promise ) ) {\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 */\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 */\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 */\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 * @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 * @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\tconfig.multiline = false;\n\t// Parent constructor\n\tOO.ui.MultilineTextInputWidget.parent.call( this, config );\n\n\t// Properties\n\tthis.multiline = true;\n\tthis.autosize = !!config.autosize;\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.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 ( this.multiline && 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 * @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 supports multiple lines.\n *\n * @return {boolean}\n */\nOO.ui.MultilineTextInputWidget.prototype.isMultiline = function () {\n\treturn !!this.multiline;\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 *     // Example: 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 *     $( '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 *     $( '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\tindicator: 'down',\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\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 * @inheritdoc\n */\nOO.ui.ComboBoxInputWidget.prototype.setDisabled = function ( disabled ) {\n\t// Parent method\n\tOO.ui.ComboBoxInputWidget.parent.prototype.setDisabled.call( this, disabled );\n\n\tif ( this.dropdownButton ) {\n\t\tthis.dropdownButton.setDisabled( this.isDisabled() );\n\t}\n\tif ( this.menu ) {\n\t\tthis.menu.setDisabled( this.isDisabled() );\n\t}\n\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 */\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 espose 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 */\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 === '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 */\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 */\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} );\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 *     $( '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 *     $( '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} );\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 *     $( '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 */\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 *     $( '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 *     $( '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 *     // Example: A NumberInputWidget.\n *     var numberInput = new OO.ui.NumberInputWidget( {\n *         label: 'NumberInputWidget',\n *         input: { value: 5 },\n *         min: 1,\n *         max: 10\n *     } );\n *     $( '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 {@link OO.ui.ButtonWidget decrementing button widget}.\n * @cfg {Object} [plusButton] Configuration options to pass to the {@link OO.ui.ButtonWidget incrementing button widget}.\n * @cfg {boolean} [allowInteger=false] Whether the field accepts only integer values.\n * @cfg {number} [min=-Infinity] Minimum allowed value\n * @cfg {number} [max=Infinity] Maximum allowed value\n * @cfg {number} [step=1] Delta when using the buttons or up/down arrow keys\n * @cfg {number|null} [pageStep] Delta when using the page-up/page-down keys. Defaults to 10 times #step.\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\tallowInteger: false,\n\t\tmin: -Infinity,\n\t\tmax: Infinity,\n\t\tstep: 1,\n\t\tpageStep: null,\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\tthis.setAllowInteger( config.allowInteger || config.isInteger );\n\tthis.setRange( config.min, config.max );\n\tthis.setStep( config.step, config.pageStep );\n\t// Set the validation method after we set allowInteger 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/**\n * Set whether only integers are allowed\n *\n * @param {boolean} flag\n */\nOO.ui.NumberInputWidget.prototype.setAllowInteger = function ( flag ) {\n\tthis.allowInteger = !!flag;\n\tthis.setValidityFlag();\n};\n// Backward compatibility\nOO.ui.NumberInputWidget.prototype.setIsInteger = OO.ui.NumberInputWidget.prototype.setAllowInteger;\n\n/**\n * Get whether only integers are allowed\n *\n * @return {boolean} Flag value\n */\nOO.ui.NumberInputWidget.prototype.getAllowInteger = function () {\n\treturn this.allowInteger;\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} step Normal step\n * @param {number|null} pageStep Page step. If null, 10 * step will be used.\n */\nOO.ui.NumberInputWidget.prototype.setStep = function ( step, pageStep ) {\n\tif ( step <= 0 ) {\n\t\tthrow new Error( 'Step value must be positive' );\n\t}\n\tif ( pageStep === null ) {\n\t\tpageStep = step * 10;\n\t} else if ( pageStep <= 0 ) {\n\t\tthrow new Error( 'Page step value must be positive' );\n\t}\n\tthis.step = step;\n\tthis.pageStep = pageStep;\n\tthis.$input.attr( 'step', this.step );\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[]} Step and page step\n */\nOO.ui.NumberInputWidget.prototype.getStep = function () {\n\treturn [ this.step, this.pageStep ];\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.allowInteger ) {\n\t\t\tn = Math.round( n );\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.allowInteger && Math.floor( n ) !== n ) {\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.step );\n};\n\n/**\n * Handle mouse wheel events.\n *\n * @private\n * @param {jQuery.Event} event\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.step );\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 */\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.step );\n\t\t\t\treturn false;\n\t\t\tcase OO.ui.Keys.DOWN:\n\t\t\t\tthis.adjustValue( -this.step );\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
index af29c74..7ee8cf8 100644 (file)
@@ -1,14 +1,14 @@
 /*!
- * OOUI v0.27.0
+ * OOUI v0.27.5
  * https://www.mediawiki.org/wiki/OOUI
  *
  * Copyright 2011–2018 OOUI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2018-05-09T00:44:50Z
+ * Date: 2018-07-11T18:13:08Z
  */
-.oo-ui-tool.oo-ui-widget > .oo-ui-tool-link > .oo-ui-iconWidget.oo-ui-iconElement-icon.oo-ui-tool-checkIcon {
+.oo-ui-tool > .oo-ui-tool-link > .oo-ui-tool-checkIcon {
   display: none;
 }
 .oo-ui-popupTool-popup .oo-ui-popupWidget-popup,
   margin: 0;
 }
 .oo-ui-toolGroupTool:first-child > .oo-ui-popupToolGroup {
-  border-top-left-radius: 4px;
-  border-bottom-left-radius: 4px;
+  border-top-left-radius: 3px;
+  border-bottom-left-radius: 3px;
 }
 .oo-ui-toolGroupTool:last-child > .oo-ui-popupToolGroup {
-  border-top-right-radius: 4px;
-  border-bottom-right-radius: 4px;
+  border-top-right-radius: 3px;
+  border-bottom-right-radius: 3px;
 }
 .oo-ui-toolGroupTool > .oo-ui-popupToolGroup > .oo-ui-popupToolGroup-handle {
   height: 1.875em;
@@ -43,7 +43,7 @@
   display: inline-block;
   vertical-align: middle;
   margin: 0.375em;
-  border-radius: 4px;
+  border-radius: 3px;
   border: 1px solid transparent;
   -webkit-transition: border-color 250ms ease;
   -moz-transition: border-color 250ms ease;
   border: 1px solid transparent;
 }
 .oo-ui-barToolGroup-tools > .oo-ui-tool:first-child {
-  border-top-left-radius: 4px;
-  border-bottom-left-radius: 4px;
+  border-top-left-radius: 3px;
+  border-bottom-left-radius: 3px;
 }
 .oo-ui-barToolGroup-tools > .oo-ui-tool:last-child {
   margin-right: -1px;
-  border-top-right-radius: 4px;
-  border-bottom-right-radius: 4px;
+  border-top-right-radius: 3px;
+  border-bottom-right-radius: 3px;
 }
 .oo-ui-barToolGroup-tools > .oo-ui-tool > .oo-ui-tool-link {
   height: 1.875em;
   display: inline-block;
   vertical-align: top;
 }
+.oo-ui-barToolGroup-tools > .oo-ui-tool > .oo-ui-tool-link .oo-ui-tool-checkIcon {
+  display: none;
+}
 .oo-ui-barToolGroup-tools > .oo-ui-tool > .oo-ui-tool-link .oo-ui-tool-title {
   line-height: 2.1em;
 }
   background-image: -webkit-linear-gradient(top, #f1f7fb 0, #fff 100%);
   background-image: -moz-linear-gradient(top, #f1f7fb 0, #fff 100%);
   background-image: linear-gradient(to bottom, #f1f7fb 0, #fff 100%);
-  -ms-filter: "progid:DXImageTransform.Microsoft.gradient( startColorstr='#fff1f7fb', endColorstr='#ffffffff' )";
 }
 .oo-ui-barToolGroup-tools.oo-ui-toolGroup-enabled-tools > .oo-ui-tool.oo-ui-tool-active.oo-ui-widget-enabled + .oo-ui-tool-active.oo-ui-widget-enabled {
   border-left-color: rgba(0, 0, 0, 0.1);
   margin-left: -2px;
 }
 .oo-ui-buttonGroupWidget .oo-ui-popupToolGroup:first-child > .oo-ui-popupToolGroup-handle {
-  border-bottom-left-radius: 4px;
-  border-top-left-radius: 4px;
+  border-bottom-left-radius: 3px;
+  border-top-left-radius: 3px;
   margin-left: 0;
 }
 .oo-ui-buttonGroupWidget .oo-ui-popupToolGroup:last-child {
   margin-right: 0.5em;
 }
 .oo-ui-buttonGroupWidget .oo-ui-popupToolGroup:last-child > .oo-ui-popupToolGroup-handle {
-  border-bottom-right-radius: 4px;
-  border-top-right-radius: 4px;
+  border-bottom-right-radius: 3px;
+  border-top-right-radius: 3px;
 }
 .oo-ui-popupToolGroup-handle {
   height: 2.5em;
   background-image: -webkit-linear-gradient(top, #f1f7fb 0, #fff 100%);
   background-image: -moz-linear-gradient(top, #f1f7fb 0, #fff 100%);
   background-image: linear-gradient(to bottom, #f1f7fb 0, #fff 100%);
-  -ms-filter: "progid:DXImageTransform.Microsoft.gradient( startColorstr='#fff1f7fb', endColorstr='#ffffffff' )";
   border-bottom-left-radius: 0;
   border-bottom-right-radius: 0;
   box-shadow: inset 0 0.0875em 0.0875em 0 rgba(0, 0, 0, 0.07);
   background-color: #fff;
   box-shadow: 0 0.3125em 1.25em rgba(0, 0, 0, 0.25);
 }
-.oo-ui-popupToolGroup-tools .oo-ui-tool.oo-ui-widget .oo-ui-tool-link {
+.oo-ui-popupToolGroup-tools .oo-ui-tool-link {
   padding: 0.3125em 0 0.3125em 0.3125em;
 }
-.oo-ui-popupToolGroup-tools .oo-ui-tool.oo-ui-widget .oo-ui-tool-link .oo-ui-iconElement-icon {
+.oo-ui-popupToolGroup-tools .oo-ui-tool-link .oo-ui-iconElement-icon {
   display: table-cell;
   min-width: 1.5625em;
   width: 1.5625em;
   height: 1.5625em;
   vertical-align: middle;
 }
-.oo-ui-popupToolGroup-tools .oo-ui-tool.oo-ui-widget .oo-ui-tool-link .oo-ui-tool-title {
+.oo-ui-popupToolGroup-tools .oo-ui-tool-link .oo-ui-tool-checkIcon {
+  display: none;
+}
+.oo-ui-popupToolGroup-tools .oo-ui-tool-link .oo-ui-tool-title {
   padding-left: 0.5em;
 }
-.oo-ui-popupToolGroup-tools .oo-ui-tool.oo-ui-widget .oo-ui-tool-link .oo-ui-tool-accel,
-.oo-ui-popupToolGroup-tools .oo-ui-tool.oo-ui-widget .oo-ui-tool-link .oo-ui-tool-title {
+.oo-ui-popupToolGroup-tools .oo-ui-tool-link .oo-ui-tool-accel,
+.oo-ui-popupToolGroup-tools .oo-ui-tool-link .oo-ui-tool-title {
   line-height: 2em;
 }
-.oo-ui-popupToolGroup-tools .oo-ui-tool.oo-ui-widget .oo-ui-tool-link .oo-ui-tool-accel {
+.oo-ui-popupToolGroup-tools .oo-ui-tool-link .oo-ui-tool-accel {
   color: #767676;
 }
-.oo-ui-popupToolGroup-tools .oo-ui-tool.oo-ui-widget .oo-ui-tool-link .oo-ui-tool-accel:not( :empty ) {
+.oo-ui-popupToolGroup-tools .oo-ui-tool-link .oo-ui-tool-accel:not( :empty ) {
   padding-left: 3em;
 }
 .oo-ui-listToolGroup-tools .oo-ui-tool {
   background-image: -webkit-linear-gradient(top, #f1f7fb 0, #fff 100%);
   background-image: -moz-linear-gradient(top, #f1f7fb 0, #fff 100%);
   background-image: linear-gradient(to bottom, #f1f7fb 0, #fff 100%);
-  -ms-filter: "progid:DXImageTransform.Microsoft.gradient( startColorstr='#fff1f7fb', endColorstr='#ffffffff' )";
 }
 .oo-ui-listToolGroup-tools .oo-ui-tool-active.oo-ui-widget-enabled + .oo-ui-tool-active.oo-ui-widget-enabled {
   border-top-color: rgba(0, 0, 0, 0.1);
 .oo-ui-menuToolGroup-tools .oo-ui-tool {
   padding: 0 1.25em 0 0.3125em;
 }
-.oo-ui-menuToolGroup-tools .oo-ui-tool.oo-ui-widget > .oo-ui-tool-link > .oo-ui-iconElement-icon {
-  opacity: 0;
-}
-.oo-ui-menuToolGroup-tools .oo-ui-tool.oo-ui-widget > .oo-ui-tool-link > .oo-ui-iconElement-icon.oo-ui-tool-checkIcon {
+.oo-ui-menuToolGroup-tools .oo-ui-tool > .oo-ui-tool-link > .oo-ui-tool-checkIcon {
   display: none;
 }
-.oo-ui-menuToolGroup-tools .oo-ui-tool-active.oo-ui-widget > .oo-ui-tool-link > .oo-ui-iconElement-icon {
+.oo-ui-menuToolGroup-tools .oo-ui-tool-active > .oo-ui-tool-link > .oo-ui-iconElement-icon {
   display: none;
 }
-.oo-ui-menuToolGroup-tools .oo-ui-tool-active.oo-ui-widget > .oo-ui-tool-link > .oo-ui-iconElement-icon.oo-ui-tool-checkIcon {
+.oo-ui-menuToolGroup-tools .oo-ui-tool-active > .oo-ui-tool-link > .oo-ui-tool-checkIcon {
   display: table-cell;
-  opacity: 1;
 }
 .oo-ui-menuToolGroup-tools .oo-ui-tool.oo-ui-widget-enabled:hover {
   background-color: #e1f3ff;
   background-image: -webkit-linear-gradient(top, #fff 0, #f1f7fb 100%);
   background-image: -moz-linear-gradient(top, #fff 0, #f1f7fb 100%);
   background-image: linear-gradient(to bottom, #fff 0, #f1f7fb 100%);
-  -ms-filter: "progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffffff', endColorstr='#fff1f7fb' )";
 }
 .oo-ui-toolbar-position-top > .oo-ui-toolbar-bar {
   border-bottom: 1px solid #ccc;
   background-image: -webkit-linear-gradient(top, #eaf4fa 0, #b0d9ee 100%);
   background-image: -moz-linear-gradient(top, #eaf4fa 0, #b0d9ee 100%);
   background-image: linear-gradient(to bottom, #eaf4fa 0, #b0d9ee 100%);
-  -ms-filter: "progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffeaf4fa', endColorstr='#ffb0d9ee' )";
   border: 1px solid #a6cee1;
 }
 .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:hover {
   background-image: -webkit-linear-gradient(top, #b0d9ee 0, #eaf4fa 100%);
   background-image: -moz-linear-gradient(top, #b0d9ee 0, #eaf4fa 100%);
   background-image: linear-gradient(to bottom, #b0d9ee 0, #eaf4fa 100%);
-  -ms-filter: "progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffb0d9ee', endColorstr='#ffeaf4fa' )";
 }
index d92b296..a2279c2 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOUI v0.27.0
+ * OOUI v0.27.5
  * https://www.mediawiki.org/wiki/OOUI
  *
  * Copyright 2011–2018 OOUI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2018-05-09T00:44:50Z
+ * Date: 2018-07-11T18:13:08Z
  */
 /**
  * WikimediaUI Base v0.10.0
@@ -17,7 +17,7 @@
   -moz-box-sizing: border-box;
   box-sizing: border-box;
 }
-.oo-ui-tool.oo-ui-widget > .oo-ui-tool-link > .oo-ui-iconWidget.oo-ui-iconElement-icon.oo-ui-tool-checkIcon {
+.oo-ui-tool > .oo-ui-tool-link > .oo-ui-tool-checkIcon {
   display: none;
 }
 .oo-ui-tool .oo-ui-tool-link {
 .oo-ui-tool-with-label .oo-ui-tool-link {
   padding: 1em 0.85714286em 0.92857143em 2.64285714em;
 }
-.oo-ui-tool.oo-ui-iconElement .oo-ui-iconElement-icon {
+.oo-ui-tool .oo-ui-iconElement-icon {
   display: block;
   left: 0.78571429em;
 }
-.oo-ui-toolbar-narrow .oo-ui-tool.oo-ui-iconElement .oo-ui-iconElement-icon {
+.oo-ui-toolbar-narrow .oo-ui-tool .oo-ui-iconElement-icon {
   left: 0.71428571em;
 }
 .oo-ui-tool .oo-ui-tool-title {
   border-right: 0;
   border-left: 1px solid #eaecf0;
 }
+.oo-ui-toolbar-actions .oo-ui-toolGroup.oo-ui-barToolGroup {
+  border-right-width: 0;
+}
 .oo-ui-toolGroup.oo-ui-widget-disabled .oo-ui-indicatorElement-indicator,
 .oo-ui-toolGroup.oo-ui-widget-disabled .oo-ui-iconElement-icon {
   opacity: 0.34 !important;
 .oo-ui-barToolGroup-tools > .oo-ui-tool.oo-ui-iconElement.oo-ui-tool-with-label > .oo-ui-tool-link .oo-ui-tool-title {
   display: inline-block;
 }
-.oo-ui-barToolGroup-tools > .oo-ui-tool.iconElement > .oo-ui-tool-link > .oo-ui-iconElement-icon {
-  display: block;
-}
 .oo-ui-barToolGroup-tools > .oo-ui-tool + .oo-ui-tool {
   margin-left: -2px;
 }
   left: 0.78571429em;
 }
 .oo-ui-toolbar-narrow .oo-ui-popupToolGroup-handle .oo-ui-iconElement-icon {
-  left: 0.71428571em;
+  left: 0.64285714em;
 }
 .oo-ui-popupToolGroup-handle .oo-ui-indicatorElement-indicator {
   background-position: center 52%;
 .oo-ui-popupToolGroup.oo-ui-widget-enabled[class*='oo-ui-flaggedElement'] > .oo-ui-popupToolGroup-handle:hover .oo-ui-iconElement-icon {
   opacity: 1;
 }
+.oo-ui-toolbar-actions .oo-ui-popupToolGroup.oo-ui-widget-enabled > .oo-ui-popupToolGroup-handle {
+  border-right: 1px solid transparent;
+  -webkit-transition: border-color 100ms;
+  -moz-transition: border-color 100ms;
+  transition: border-color 100ms;
+}
+.oo-ui-toolbar-actions .oo-ui-popupToolGroup.oo-ui-widget-enabled > .oo-ui-popupToolGroup-handle:hover {
+  border-right-color: #eaecf0;
+}
+.oo-ui-toolbar-actions .oo-ui-popupToolGroup.oo-ui-widget-enabled > .oo-ui-popupToolGroup-handle:active {
+  border-right-color: #eaf3ff;
+}
+.oo-ui-toolbar-actions .oo-ui-popupToolGroup.oo-ui-widget-enabled > .oo-ui-popupToolGroup-handle:focus {
+  border-right-color: #36c;
+}
 .oo-ui-popupToolGroup.oo-ui-popupToolGroup-active > .oo-ui-popupToolGroup-handle {
   background-color: #eaf3ff;
   color: #36c;
   border-color: #36c;
   box-shadow: inset 0 0 0 1px #36c, inset 0 0 0 2px #fff;
 }
-.oo-ui-toolbar-actions > .oo-ui-toolbar:not( :last-child ) {
-  border-right: 1px solid #eaecf0;
-}
index 096c97e..b04dfe3 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOUI v0.27.0
+ * OOUI v0.27.5
  * https://www.mediawiki.org/wiki/OOUI
  *
  * Copyright 2011–2018 OOUI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2018-05-09T00:44:45Z
+ * Date: 2018-07-11T18:13:04Z
  */
 ( function ( OO ) {
 
@@ -317,7 +317,7 @@ OO.ui.Toolbar = function OoUiToolbar( toolFactory, toolGroupFactory, config ) {
        // Properties
        this.toolFactory = toolFactory;
        this.toolGroupFactory = toolGroupFactory;
-       this.groups = [];
+       this.groupsByName = {};
        this.tools = {};
        this.position = config.position || 'top';
        this.$bar = $( '<div>' );
@@ -447,13 +447,15 @@ OO.ui.Toolbar.prototype.initialize = function () {
  * 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
+ * @param {string} [groups.type] Toolgroup type, should exist in the toolgroup factory
  * @param {Array|string} [groups.include] Tools to include in the toolgroup
  * @param {Array|string} [groups.exclude] Tools to exclude from the toolgroup
  * @param {Array|string} [groups.promote] Tools to promote to the beginning of the toolgroup
  * @param {Array|string} [groups.demote] Tools to demote to the end of the toolgroup
  */
 OO.ui.Toolbar.prototype.setup = function ( groups ) {
-       var i, len, type, group,
+       var i, len, type, toolGroup, groupConfig,
                items = [],
                defaultType = 'bar';
 
@@ -462,32 +464,47 @@ OO.ui.Toolbar.prototype.setup = function ( groups ) {
 
        // Build out new groups
        for ( i = 0, len = groups.length; i < len; i++ ) {
-               group = groups[ i ];
-               if ( group.include === '*' ) {
+               groupConfig = groups[ i ];
+               if ( groupConfig.include === '*' ) {
                        // Apply defaults to catch-all groups
-                       if ( group.type === undefined ) {
-                               group.type = 'list';
+                       if ( groupConfig.type === undefined ) {
+                               groupConfig.type = 'list';
                        }
-                       if ( group.label === undefined ) {
-                               group.label = OO.ui.msg( 'ooui-toolbar-more' );
+                       if ( groupConfig.label === undefined ) {
+                               groupConfig.label = OO.ui.msg( 'ooui-toolbar-more' );
                        }
                }
                // Check type has been registered
-               type = this.getToolGroupFactory().lookup( group.type ) ? group.type : defaultType;
-               items.push(
-                       this.getToolGroupFactory().create( type, this, group )
-               );
+               type = this.getToolGroupFactory().lookup( groupConfig.type ) ? groupConfig.type : defaultType;
+               toolGroup = this.getToolGroupFactory().create( type, this, groupConfig );
+               items.push( toolGroup );
+               if ( groupConfig.name ) {
+                       this.groupsByName[ groupConfig.name ] = toolGroup;
+               } else {
+                       // Groups without name are deprecated
+                       OO.ui.warnDeprecation( 'Toolgroups must have a \'name\' property' );
+               }
        }
        this.addItems( items );
 };
 
+/**
+ * Get a toolgroup by name
+ *
+ * @param {string} name Group name
+ * @return {OO.ui.ToolGroup|null} Tool group, or null if none found by that name
+ */
+OO.ui.Toolbar.prototype.getToolGroupByName = function ( name ) {
+       return this.groupsByName[ name ] || null;
+};
+
 /**
  * Remove all tools and toolgroups from the toolbar.
  */
 OO.ui.Toolbar.prototype.reset = function () {
        var i, len;
 
-       this.groups = [];
+       this.groupsByName = {};
        this.tools = {};
        for ( i = 0, len = this.items.length; i < len; i++ ) {
                this.items[ i ].destroy();
@@ -1944,6 +1961,34 @@ OO.ui.PopupToolGroup.prototype.onMouseKeyUp = function ( e ) {
        return OO.ui.PopupToolGroup.parent.prototype.onMouseKeyUp.call( this, e );
 };
 
+/**
+ * @inheritdoc
+ */
+OO.ui.PopupToolGroup.prototype.onMouseKeyDown = function ( e ) {
+       var $focused, $firstFocusable, $lastFocusable;
+       // 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.)
+               $focused = $( document.activeElement );
+               $firstFocusable = OO.ui.findFocusable( this.$group );
+               if ( $focused[ 0 ] === $firstFocusable[ 0 ] && e.shiftKey ) {
+                       this.$handle.focus();
+                       return false;
+               }
+               $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').
+                       // 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.focus();
+                       // Close the popup so that we don't move back inside it (if this is the last group).
+                       this.setActive( false );
+               }
+       }
+       return OO.ui.PopupToolGroup.parent.prototype.onMouseKeyDown.call( this, e );
+};
+
 /**
  * Handle mouse up and key up events.
  *
@@ -1966,12 +2011,20 @@ OO.ui.PopupToolGroup.prototype.onHandleMouseKeyUp = function ( e ) {
  * @param {jQuery.Event} e Mouse down or key down event
  */
 OO.ui.PopupToolGroup.prototype.onHandleMouseKeyDown = function ( e ) {
-       if (
-               !this.isDisabled() &&
-               ( e.which === OO.ui.MouseButtons.LEFT || e.which === OO.ui.Keys.SPACE || e.which === OO.ui.Keys.ENTER )
-       ) {
-               this.setActive( !this.active );
-               return false;
+       var $focusable;
+       if ( !this.isDisabled() ) {
+               // Tab on the handle jumps to the first tool in the group (if the popup is open).
+               if ( e.which === OO.ui.Keys.TAB && !e.shiftKey ) {
+                       $focusable = OO.ui.findFocusable( this.$group );
+                       if ( $focusable.length ) {
+                               $focusable.focus();
+                               return false;
+                       }
+               }
+               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;
+               }
        }
 };
 
@@ -2025,7 +2078,7 @@ OO.ui.PopupToolGroup.prototype.setActive = function ( value ) {
                                this.setHorizontalPosition( 'start' );
 
                                this.$clippable.css( {
-                                       left: -( this.$element.offset().left - containerLeft ),
+                                       'margin-left': -( this.$element.offset().left - containerLeft ),
                                        width: containerWidth
                                } );
                        }
@@ -2430,4 +2483,4 @@ OO.ui.MenuToolGroup.prototype.onUpdateState = function () {
 
 }( OO ) );
 
-//# sourceMappingURL=oojs-ui-toolbars.js.map
\ No newline at end of file
+//# sourceMappingURL=oojs-ui-toolbars.js.map.json
\ No newline at end of file
diff --git a/resources/lib/oojs-ui/oojs-ui-toolbars.js.map b/resources/lib/oojs-ui/oojs-ui-toolbars.js.map
deleted file mode 100644 (file)
index 64e5778..0000000
+++ /dev/null
@@ -1 +0,0 @@
-{"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":";;;;;;;;;;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,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO;AACzF,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG;AAC9G,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,KAAK,CAAC;AACpD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,OAAO;AACnH,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM;AAC9G,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC;AACxB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,UAAU,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC;AACvH,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC;AAC7G,CAAC,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE;AAClH,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC;AAC3D,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI;AAC5F,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE;AAChG,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO;AAChG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE;AAChG,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,WAAW,CAAC,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC;AAClF,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,aAAa,CAAC,MAAM,EAAE;AACzD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC;AAClD,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,CAAC,OAAO;AACf,CAAC,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO;AAC9B,CAAC,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO;AAC5B,CAAC,CAAC,KAAK,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,GAAG;AACjD,CAAC,CAAC,KAAK,GAAG,CAAC,gBAAgB,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,GAAG;AAC3D,CAAC,CAAC,KAAK,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,WAAW,CAAC,CAAC,gBAAgB,CAAC,EAAE;AACxE,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI;AAC5E,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,EAAE;AACxD,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO;AACnE,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI;AACnD,CAAC,CAAC,KAAK,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;AAC9B,CAAC,CAAC,SAAS,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,EAAE;AACtD,CAAC,CAAC,KAAK,CAAC;AACR,CAAC,CAAC,KAAK,EAAE,CAAC,YAAY,CAAC,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE;AACjD,CAAC,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG;AACnG,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE;AAC1D,CAAC,CAAC,KAAK,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE;AACzC,CAAC,CAAC,KAAK,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE;AACzC,CAAC,CAAC,KAAK,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK;AAC7C,CAAC,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,OAAO,EAAE;AACnF,CAAC,CAAC,KAAK,UAAU,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACpD,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE;AAChD,CAAC,CAAC,SAAS,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE;AAC7D,CAAC,CAAC,SAAS,IAAI,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,EAAE;AACnC,CAAC,CAAC,KAAK,EAAE;AACT,CAAC,CAAC,KAAK,UAAU,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG;AAC3D,CAAC,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO;AAC1E,CAAC,CAAC,KAAK,WAAW,CAAC,QAAQ,CAAC,CAAC,UAAU,CAAC,EAAE;AAC1C,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI;AAC3D,CAAC,CAAC,KAAK,QAAQ,CAAC,YAAY,EAAE,CAAC,CAAC;AAChC,CAAC,CAAC,SAAS,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,EAAE;AACxD,CAAC,CAAC,KAAK,CAAC;AACR,CAAC,CAAC,KAAK,EAAE,CAAC,YAAY,CAAC,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE;AACnD,CAAC,CAAC,KAAK,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;AAC7C,CAAC,CAAC,KAAK,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;AAC7C,CAAC,CAAC,KAAK,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,EAAE;AACrD,CAAC,CAAC,KAAK,YAAY,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACtD,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE;AAClD,CAAC,CAAC,SAAS,IAAI,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,EAAE;AACnC,CAAC,CAAC,KAAK,EAAE;AACT,CAAC,CAAC,KAAK,YAAY,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG;AAC7D,CAAC,CAAC,KAAK,WAAW,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,EAAE;AAC5C,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI;AAC3D,CAAC,CAAC,KAAK,QAAQ,CAAC,SAAS,EAAE,CAAC,CAAC;AAC7B,CAAC,CAAC,SAAS,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,EAAE;AACrD,CAAC,CAAC,KAAK,CAAC;AACR,CAAC,CAAC,KAAK,EAAE,CAAC,YAAY,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE;AAChD,CAAC,CAAC,KAAK,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE;AACvC,CAAC,CAAC,KAAK,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;AAC1C,CAAC,CAAC,KAAK,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE;AAC7C,CAAC,CAAC,KAAK,SAAS,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACnD,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE;AACpD,CAAC,CAAC,SAAS,IAAI,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,EAAE;AACnC,CAAC,CAAC,KAAK,EAAE;AACT,CAAC,CAAC,KAAK,SAAS,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG;AAC1D,CAAC,CAAC,KAAK,WAAW,CAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,EAAE;AACzC,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AAC/F,CAAC,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE;AAC9C,CAAC,CAAC,KAAK,QAAQ,CAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAC/C,CAAC,CAAC,SAAS,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;AACtE,CAAC,CAAC,aAAa,MAAM,CAAC,CAAC,IAAI,CAAC;AAC5B,CAAC,CAAC,aAAa,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE;AAC7B,CAAC,CAAC,aAAa,IAAI,CAAC,CAAC,IAAI;AACzB,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;AAC3B,CAAC,CAAC,SAAS,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,GAAG,CAAC,EAAE,CAAC,EAAE;AAC7D,CAAC,CAAC,KAAK,CAAC;AACR,CAAC,CAAC,KAAK,EAAE,CAAC,YAAY,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE;AACpD,CAAC,CAAC,KAAK,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;AACrC,CAAC,CAAC,KAAK,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;AACrC,CAAC,CAAC,KAAK,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;AACtC,CAAC,CAAC,KAAK,WAAW,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,EAAE;AACxC,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;AACnG,CAAC,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE;AAC7D,CAAC,CAAC,KAAK,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;AACvB,CAAC,CAAC,SAAS,CAAC;AACZ,CAAC,CAAC,aAAa,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC;AAC5E,CAAC,CAAC,aAAa,IAAI,CAAC,CAAC,CAAC,GAAG,EAAE;AAC3B,CAAC,CAAC,aAAa,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;AAC5C,CAAC,CAAC,SAAS,EAAE;AACb,CAAC,CAAC,SAAS,CAAC;AACZ,CAAC,CAAC,aAAa,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC;AAC3F,CAAC,CAAC,aAAa,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE;AAC5B,CAAC,CAAC,aAAa,SAAS,CAAC,CAAC,CAAC,IAAI,EAAE;AACjC,CAAC,CAAC,aAAa,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE;AAC7B,CAAC,CAAC,aAAa,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;AAC/C,CAAC,CAAC,SAAS,CAAC;AACZ,CAAC,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,SAAS;AACnG,CAAC,CAAC,SAAS,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC;AAClG,CAAC,CAAC,SAAS,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE;AAC9F,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACX,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ;AACxE,CAAC,CAAC,KAAK,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;AAC3C,CAAC,CAAC,SAAS,QAAQ,CAAC,CAAC,KAAK,CAAC;AAC3B,CAAC,CAAC,SAAS,MAAM,CAAC,CAAC,IAAI;AACvB,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACX,CAAC,CAAC,KAAK,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;AAClD,CAAC,CAAC,SAAS,QAAQ,CAAC,CAAC,KAAK,CAAC;AAC3B,CAAC,CAAC,SAAS,MAAM,CAAC,CAAC,IAAI;AACvB,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACX,CAAC,CAAC,KAAK,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC;AAC7B,CAAC,CAAC,SAAS,OAAO,EAAE,OAAO,CAAC;AAC5B,CAAC,CAAC,SAAS,YAAY,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AAChD,CAAC,CAAC,KAAK,EAAE;AACT,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE;AAC5C,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;AACpG,CAAC,CAAC,KAAK,EAAE,CAAC,QAAQ,CAAC;AACnB,CAAC,CAAC,KAAK,OAAO,CAAC,UAAU,GAAG;AAC5B,CAAC,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,EAAE;AACrC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;AAClG,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,WAAW,CAAC,CAAC,KAAK,EAAE;AAClD,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,CAAC,OAAO;AACf,CAAC,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO;AAC5B,CAAC,CAAC,KAAK,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,GAAG;AACjD,CAAC,CAAC,KAAK,GAAG,CAAC,gBAAgB,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,GAAG;AAC3D,CAAC,CAAC,KAAK,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,WAAW,CAAC,CAAC,gBAAgB,CAAC,EAAE;AACxE,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI;AAC5E,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,EAAE;AACxD,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO;AACnE,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI;AACnD,CAAC,CAAC,KAAK,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;AAC9B,CAAC,CAAC,SAAS,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,EAAE;AACtD,CAAC,CAAC,KAAK,CAAC;AACR,CAAC,CAAC,KAAK,EAAE,CAAC,YAAY,CAAC,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE;AACjD,CAAC,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG;AACnG,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE;AAC1D,CAAC,CAAC,KAAK,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE;AACzC,CAAC,CAAC,KAAK,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE;AACzC,CAAC,CAAC,KAAK,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK;AAC7C,CAAC,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,OAAO,EAAE;AACnF,CAAC,CAAC,KAAK,UAAU,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACpD,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE;AAChD,CAAC,CAAC,SAAS,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE;AAC7D,CAAC,CAAC,SAAS,IAAI,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,EAAE;AACnC,CAAC,CAAC,KAAK,EAAE;AACT,CAAC,CAAC,KAAK,UAAU,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG;AAC3D,CAAC,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO;AAC1E,CAAC,CAAC,KAAK,WAAW,CAAC,QAAQ,CAAC,CAAC,UAAU,CAAC,EAAE;AAC1C,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI;AAC3D,CAAC,CAAC,KAAK,QAAQ,CAAC,YAAY,EAAE,CAAC,CAAC;AAChC,CAAC,CAAC,SAAS,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,EAAE;AACxD,CAAC,CAAC,SAAS,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC;AACrC,CAAC,CAAC,KAAK,CAAC;AACR,CAAC,CAAC,KAAK,EAAE,CAAC,YAAY,CAAC,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE;AACnD,CAAC,CAAC,KAAK,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;AAC7C,CAAC,CAAC,KAAK,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;AAC7C,CAAC,CAAC,KAAK,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,EAAE;AACrD,CAAC,CAAC,KAAK,YAAY,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACtD,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE;AAClD,CAAC,CAAC,SAAS,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK;AACnD,CAAC,CAAC,SAAS,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC;AAClD,CAAC,CAAC,SAAS,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE;AAC/C,CAAC,CAAC,SAAS,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK;AACtC,CAAC,CAAC,SAAS,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,EAAE;AAC9C,CAAC,CAAC,KAAK,EAAE;AACT,CAAC,CAAC,KAAK,YAAY,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG;AAC7D,CAAC,CAAC,KAAK,WAAW,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,EAAE;AAC5C,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI;AAC3D,CAAC,CAAC,KAAK,QAAQ,CAAC,SAAS,EAAE,CAAC,CAAC;AAC7B,CAAC,CAAC,SAAS,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,EAAE;AACrD,CAAC,CAAC,SAAS,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC;AACrC,CAAC,CAAC,KAAK,CAAC;AACR,CAAC,CAAC,KAAK,EAAE,CAAC,YAAY,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE;AAChD,CAAC,CAAC,KAAK,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE;AACvC,CAAC,CAAC,KAAK,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;AAC1C,CAAC,CAAC,KAAK,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE;AAC7C,CAAC,CAAC,KAAK,SAAS,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACnD,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE;AACpD,CAAC,CAAC,SAAS,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK;AACnD,CAAC,CAAC,SAAS,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC;AAClD,CAAC,CAAC,SAAS,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE;AAC/C,CAAC,CAAC,SAAS,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK;AACtC,CAAC,CAAC,SAAS,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,EAAE;AAC9C,CAAC,CAAC,KAAK,EAAE;AACT,CAAC,CAAC,KAAK,SAAS,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG;AAC1D,CAAC,CAAC,KAAK,WAAW,CAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,EAAE;AACzC,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AAC/F,CAAC,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC;AAC3F,CAAC,CAAC,KAAK,QAAQ,CAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAC/C,CAAC,CAAC,SAAS,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;AACtE,CAAC,CAAC,aAAa,MAAM,CAAC,CAAC,IAAI,CAAC;AAC5B,CAAC,CAAC,aAAa,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE;AAC7B,CAAC,CAAC,aAAa,IAAI,CAAC,CAAC,IAAI;AACzB,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;AAC3B,CAAC,CAAC,SAAS,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,GAAG,CAAC,EAAE,CAAC,EAAE;AAC7D,CAAC,CAAC,KAAK,CAAC;AACR,CAAC,CAAC,KAAK,EAAE,CAAC,YAAY,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE;AACpD,CAAC,CAAC,KAAK,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;AACrC,CAAC,CAAC,KAAK,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;AACrC,CAAC,CAAC,KAAK,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;AACtC,CAAC,CAAC,KAAK,WAAW,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,EAAE;AACxC,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;AACnG,CAAC,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE;AAC7D,CAAC,CAAC,KAAK,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;AACvB,CAAC,CAAC,SAAS,CAAC;AACZ,CAAC,CAAC,aAAa,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC;AAC5E,CAAC,CAAC,aAAa,IAAI,CAAC,CAAC,CAAC,GAAG,EAAE;AAC3B,CAAC,CAAC,aAAa,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;AAC5C,CAAC,CAAC,SAAS,EAAE;AACb,CAAC,CAAC,SAAS,CAAC;AACZ,CAAC,CAAC,aAAa,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC;AAC3F,CAAC,CAAC,aAAa,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC;AAChE,CAAC,CAAC,aAAa,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE;AAC5B,CAAC,CAAC,aAAa,SAAS,CAAC,CAAC,CAAC,IAAI,EAAE;AACjC,CAAC,CAAC,aAAa,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;AAC/C,CAAC,CAAC,SAAS,CAAC;AACZ,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACX,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ;AACxE,CAAC,CAAC,KAAK,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;AAC3C,CAAC,CAAC,SAAS,QAAQ,CAAC,CAAC,KAAK,CAAC;AAC3B,CAAC,CAAC,SAAS,MAAM,CAAC,CAAC,IAAI;AACvB,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACX,CAAC,CAAC,KAAK,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;AAClD,CAAC,CAAC,SAAS,QAAQ,CAAC,CAAC,KAAK,CAAC;AAC3B,CAAC,CAAC,SAAS,MAAM,CAAC,CAAC,IAAI;AACvB,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACX,CAAC,CAAC,KAAK,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC;AAC7B,CAAC,CAAC,SAAS,OAAO,EAAE,OAAO,CAAC;AAC5B,CAAC,CAAC,SAAS,YAAY,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AAChD,CAAC,CAAC,KAAK,EAAE;AACT,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE;AAC5C,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;AACpG,CAAC,CAAC,KAAK,EAAE,CAAC,QAAQ,CAAC;AACnB,CAAC,CAAC,KAAK,OAAO,CAAC,UAAU,GAAG;AAC5B,CAAC,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,EAAE;AACrC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO;AACzB,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,YAAY;AAC1B,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY;AACnC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK;AACpE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,gBAAgB,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU;AACnF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO;AACjD,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ;AACzG,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE;AAC3G,CAAC,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC;AAChB,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC,OAAO,CAAC;AAC9G,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC;AACrD,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE;AAChE,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,WAAW,CAAC,CAAC,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAC/E,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM;AAChE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AACjE,EAAE,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC;AACvB,EAAE,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC;AACnC,EAAE,gBAAgB,CAAC,CAAC,CAAC,MAAM,CAAC,gBAAgB,CAAC;AAC7C,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,aAAa,CAAC,cAAc;AAChC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG;AACvB;AACA,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AAC3C;AACA,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY;AACtB,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AAC9B,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AAC/C;AACA,CAAC,EAAE,CAAC,UAAU;AACd,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC;AAChC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,gBAAgB,CAAC;AAC1C,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG;AAClB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG;AACjB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE;AAC1C,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE;AAC1B,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE;AAC9B,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE;AAC7B,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC;AAC1B,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC;AAC7B,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AAC/D,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,iBAAiB,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC;AAC7G;AACA,CAAC,EAAE,CAAC,MAAM;AACV,CAAC,IAAI,EAAE,OAAO;AACd,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AAC3D,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;AAC9D;AACA,CAAC,EAAE,CAAC,cAAc;AAClB,CAAC,IAAI,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE;AAC/C,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AACxB,EAAE,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE;AACxE,CAAC,CAAC;AACF,CAAC,IAAI,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE;AACjD,CAAC,IAAI,EAAE,GAAG;AACV,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;AAClC,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,IAAI,GAAG,EAAE,CAAC,EAAE;AAC3D,CAAC,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM;AAC/E,CAAC,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE;AACvG,CAAC,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE;AACtC,EAAE;AACF;AACA,EAAE,CAAC,KAAK,CAAC,EAAE;AACX;AACA,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE;AAChD,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,YAAY,CAAC,EAAE;AAChD,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE;AACzD;AACA,EAAE,CAAC,MAAM,CAAC,EAAE;AACZ;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW;AACrB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,GAAG;AACrG,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;AACnG,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,CAAC;AACrB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,UAAU;AACxD,CAAC,EAAE;AACH;AACA,EAAE,CAAC,OAAO,CAAC,EAAE;AACb;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC;AACxB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,OAAO;AAC3C,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACtD,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC;AACzB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC;AAC7B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,OAAO;AACzC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC3D,CAAC,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC;AAC9B,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC;AAC7B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK;AAC3C,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACxD,CAAC,GAAG,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE;AACtE,EAAE,CAAC,sBAAsB,CAAC,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE;AACrE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,oBAAoB,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACtG,EAAE,MAAM,CAAC,KAAK,CAAC;AACf,CAAC,CAAC;AACF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC;AAC9B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK;AAC9C,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACtD,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,WAAW,CAAC;AAC/C,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE;AACzB,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,EAAE,CAAC,IAAI,CAAC,kBAAkB,EAAE;AACzD,CAAC,EAAE;AACH,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM;AAClF,CAAC,CAAC,CAAC,KAAK,CAAC;AACT,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC,MAAM;AAC7C,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC1D,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACvC,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC;AACvF,CAAC,CAAC;AACF,CAAC,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC;AAC7B,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC;AAC7E,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC;AACjG,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAClD,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;AAC3B,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC;AAC1B,EAAE,EAAE,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,qBAAqB,CAAC,EAAE;AAC1E,EAAE,IAAI,CAAC,cAAc,GAAG;AACxB,CAAC,CAAC;AACF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC;AACtB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;AACzF,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,GAAG,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,IAAI,EAAE;AACpH,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM;AAC/F,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,UAAU,CAAC;AACnG,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,cAAc;AACzE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS;AAC3E,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS;AAC7E,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS;AAC5F,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS;AACpF,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACrD,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC;AACzB,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG;AACb,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE;AACtB;AACA,CAAC,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM;AAC3B,CAAC,IAAI,CAAC,KAAK,GAAG;AACd;AACA,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM;AACxB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AACnD,EAAE,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE;AACtB,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AAChC,GAAG,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM;AACxC,GAAG,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AACpC,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;AACxB,GAAG,CAAC;AACJ,GAAG,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AACrC,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE;AACnD,GAAG,CAAC;AACJ,EAAE,CAAC;AACH,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU;AACnC,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,mBAAmB,GAAG,MAAM,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC;AACpF,EAAE,KAAK,CAAC,IAAI,CAAC;AACb,GAAG,IAAI,CAAC,mBAAmB,GAAG,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC;AACzD,EAAE,EAAE;AACJ,CAAC,CAAC;AACF,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,EAAE;AACxB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC;AACpD,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC7C,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;AACZ;AACA,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG;AAClB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG;AACjB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AACvD,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,GAAG;AAC5B,CAAC,CAAC;AACF,CAAC,IAAI,CAAC,UAAU,GAAG;AACnB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC;AACvB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,IAAI;AACvG,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC;AACrD,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC/C,CAAC,EAAE,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,qBAAqB,CAAC,EAAE;AAC1E,CAAC,IAAI,CAAC,KAAK,GAAG;AACd,CAAC,IAAI,EAAE,OAAO,CAAC,MAAM,GAAG;AACxB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC;AAClC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC;AACxE,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI;AAC7C,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS;AACtC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAC7D,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,EAAE;AAC5B,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC;AACtC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO;AAC3C,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACzD,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACrC,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC;AAC/B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO;AAC3C,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACzD,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE;AACrC,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC;AAClC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE;AAC5F,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK;AAC7G,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC;AAC5F,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI;AAC7C,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC,SAAS;AACjE,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC1D,CAAC,MAAM,CAAC,SAAS,CAAC;AAClB,EAAE;;ACzhBF,GAAG;AACH,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,UAAU,EAAE,CAAC,UAAU,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,QAAQ,EAAE;AACtG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK;AAC1G,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,OAAO,EAAE;AAC9G,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC;AACrC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC;AAClD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,aAAa,CAAC;AAC3B,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,QAAQ,CAAC;AACtB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,aAAa,EAAE;AAC5E,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,aAAa,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG;AAC9G,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC;AAC3F,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,EAAE;AAC7E,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ;AACpD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,QAAQ;AACZ,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM;AACxB,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW;AAClC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,cAAc;AACrC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,iBAAiB;AACxC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,SAAS;AACrC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO;AACjD,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;AACrH,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC;AAC5D,CAAC,CAAC;AACF,CAAC,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG;AACtG,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;AACrI,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC;AAC7F,CAAC,CAAC;AACF,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE,CAAC,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,GAAG;AAC3G,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,WAAW,CAAC;AAC9H,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,kBAAkB,CAAC,kBAAkB,CAAC,CAAC,MAAM,CAAC;AAC9J,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACrD,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM;AAChE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AAC/D,EAAE,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;AACrB,EAAE,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC;AAC/B,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,aAAa,CAAC,cAAc;AAChC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG;AACvB;AACA,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AACxC;AACA,CAAC,EAAE,CAAC,UAAU;AACd,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;AAC5B,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,GAAG;AAC5C,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC;AACrB,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE;AAC7B,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE;AAC7B,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE;AACzB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;AACnB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;AACzC,EAAE,IAAI,CAAC,CAAC,CAAC,KAAK,EAAE;AAChB,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;AACrC,CAAC,CAAC,CAAC,EAAE;AACL;AACA,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AAC9C,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AACjD,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;AACjG;AACA,CAAC,EAAE,CAAC,MAAM;AACV,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,EAAE;AAChE;AACA,CAAC,EAAE,CAAC,cAAc;AAClB,CAAC,IAAI,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE;AAC5C,CAAC,IAAI,EAAE,KAAK;AACZ,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;AACjC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;AACV,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC;AACtE,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO;AACzD,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE;AACd,GAAG,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;AACb,EAAE,CAAC,CAAC,EAAE;AACN,CAAC,IAAI,EAAE,IAAI;AACX,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;AAChC,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AAC1E,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE;AAC5B,CAAC,IAAI,EAAE,OAAO;AACd,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,CAAC;AAC7B,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;AAC3B,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,uBAAuB,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC3G,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,uBAAuB,CAAC,CAAC;AAC1F,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE;AACxB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;AAChE,EAAE;AACF;AACA,EAAE,CAAC,KAAK,CAAC,EAAE;AACX;AACA,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE;AAC5C,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE;AACrD,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,EAAE;AACxD,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,iBAAiB,CAAC,EAAE;AAC3D;AACA,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE;AACvB;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,MAAM;AACV,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;AACnC;AACA,GAAG;AACH,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC;AACzB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC,GAAG;AACjH,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,UAAU,CAAC;AAChD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,QAAQ;AACZ,CAAC,CAAC,CAAC,CAAC,MAAM;AACV,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC;AACrB,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG;AAC5B;AACA,GAAG;AACH,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC;AAC9B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE;AAClG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE;AACvC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,QAAQ;AACZ,CAAC,CAAC,CAAC,CAAC,MAAM;AACV,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC;AACrB,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG;AAC7B;AACA,GAAG;AACH,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC;AAC7I,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,QAAQ;AACZ,CAAC,CAAC,CAAC,CAAC,MAAM;AACV,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC;AAC9B,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG;AAC7B;AACA,GAAG;AACH,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC;AACnG,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC;AAC9E,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM;AACV,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC;AACtB,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,uBAAuB,CAAC,CAAC,CAAC,KAAK,CAAC;AAClD;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,aAAa,CAAC;AAC9C,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AAC3F,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI;AAC/E,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM;AACV,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC;AACtB,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC;AAC3C;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC;AAC1C,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK;AACjF,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI;AAClG,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE;AAC3C,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM;AACV,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC;AACtB,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC;AACxC;AACA,GAAG;AACH,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;AACpD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE;AAC3F,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,cAAc;AAChG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,SAAS,CAAC;AAC/E,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM;AACV,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK;AACpC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI;AAC/C,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAClD,CAAC,MAAM,CAAC,KAAK,CAAC;AACd,EAAE;AACF;AACA,EAAE,CAAC,OAAO,CAAC,EAAE;AACb;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG;AACzE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,WAAW,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG;AAChF,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI;AAC3F,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,WAAW,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;AACjG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE;AACxD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC;AAC7E,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM;AACV,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,CAAC,CAAC,CAAC,QAAQ;AACZ,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC;AAC1C;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC;AAC1F,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC;AACzC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC;AAC7E,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM;AACV,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,CAAC,CAAC,CAAC,QAAQ;AACZ,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC;AACrC;AACA,GAAG;AACH,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC;AAC/B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,aAAa,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,OAAO;AACpG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC;AACjG,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM;AACnC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC7C,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC;AACpB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC;AAC3C,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI;AAClG,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC;AACzB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM;AACjD,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACrD,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC;AACvB,CAAC,IAAI,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE;AAC/D,CAAC,IAAI,CAAC,kBAAkB,GAAG;AAC3B,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC;AACvB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI;AAC5E,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACpD,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,EAAE;AACxC,CAAC,IAAI,CAAC,WAAW,GAAG;AACpB,CAAC,MAAM,CAAC,IAAI,CAAC;AACb,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC;AACvB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,IAAI;AAC9B,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC7C,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC;AACnB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC;AAChC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI;AACzC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC5C,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC;AACrC,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC;AACpB,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAChD,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,MAAM,CAAC,aAAa,CAAC;AACrE,EAAE,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,MAAM,CAAC,aAAa,CAAC;AAClE,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE;AAC1E,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG;AACpB;AACA,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE;AAChC,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,EAAE;AAC3B;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAC9E,EAAE,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE;AAClC,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACpE,EAAE,YAAY,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,EAAE;AAC7B,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAC7B,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;AACvD,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACT,EAAE,IAAI,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACnC,CAAC,CAAC;AACF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC;AAChB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC;AAC9E,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;AACvD,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC5C,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,EAAE;AACjC,CAAC,IAAI,EAAE,OAAO,CAAC,MAAM,GAAG;AACxB,EAAE;;AC7TF,GAAG;AACH,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE;AAC3G,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,IAAI,EAAE;AAChI,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,UAAU;AACvG,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,SAAS,CAAC,OAAO,EAAE;AAC5F,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,SAAS;AACjG,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC;AACnG,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC;AAC3E,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,OAAO,CAAC;AACzG,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,EAAE;AACvD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ;AACpD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,QAAQ;AACZ,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM;AACxB,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY;AACnC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,OAAO;AACjC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO;AACjD,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC;AACtF,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC;AACxF,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC;AACvG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC;AAC/F,CAAC,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS;AACnF,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE;AAChD,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAC7D,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM;AAChE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AAC7D,EAAE,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC;AACnB,EAAE,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;AAC3B,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,aAAa,CAAC,cAAc;AAChC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG;AACvB;AACA,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AAC7C;AACA,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AAC/C;AACA,CAAC,EAAE,CAAC,UAAU;AACd,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC;AACxB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG;AACjB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;AACrB,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC;AAC3B,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG;AACrC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG;AACrC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG;AACrC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG;AACnC,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AAC3E;AACA,CAAC,EAAE,CAAC,MAAM;AACV,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;AAClB,EAAE,SAAS,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AAC9C,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AAC1C,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AAC5C,EAAE,KAAK,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AACxC,EAAE,KAAK,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AAC5C,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AACzC,EAAE,SAAS,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AAChD,EAAE,QAAQ,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC;AAC5C,CAAC,CAAC,CAAC,EAAE;AACL,CAAC,IAAI,CAAC,OAAO,CAAC,cAAc,GAAG,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,EAAE;AACtF,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE;AAC9C,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;AACtB,EAAE,WAAW,CAAC,CAAC,CAAC,cAAc,EAAE;AAChC,EAAE,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;AACtB,CAAC,CAAC,CAAC,EAAE;AACL;AACA,CAAC,EAAE,CAAC,cAAc;AAClB,CAAC,IAAI,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE;AACjD,CAAC,IAAI,EAAE,OAAO;AACd,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC;AAChC,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE;AACzB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,EAAE;AACrC,CAAC,IAAI,CAAC,QAAQ,GAAG;AACjB,EAAE;AACF;AACA,EAAE,CAAC,KAAK,CAAC,EAAE;AACX;AACA,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE;AACjD,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE;AAC3D;AACA,EAAE,CAAC,MAAM,CAAC,EAAE;AACZ;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM;AAChB,CAAC,EAAE;AACH;AACA,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE;AACvB;AACA,GAAG;AACH,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC;AAC3B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM;AACV,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC;AACtB,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC;AAC7C;AACA,GAAG;AACH,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC;AACxC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO;AAClF,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG;AAC/F,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,kBAAkB,CAAC,kBAAkB,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,EAAE;AAC5F,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG;AACnG,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM;AACV,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC;AACtB,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC;AAC7C;AACA,GAAG;AACH,CAAC,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ;AAClE,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM;AACV,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC;AACtB,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC;AAC1C;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,QAAQ;AACZ,CAAC,CAAC,CAAC,CAAC,MAAM;AACV,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC;AACrB,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AACnC;AACA,EAAE,CAAC,OAAO,CAAC,EAAE;AACb;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACpD,CAAC,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,EAAE;AAClG,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACxD,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC;AACjC;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;AAC7C,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAClD,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE;AAC1B,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC;AAC9B,IAAI,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC;AACxB,IAAI,KAAK,CAAC;AACV,GAAG,CAAC;AACJ,EAAE,CAAC;AACH,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,WAAW,CAAC;AAClC,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,EAAE;AAC1E,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC;AACzB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,UAAU;AAC9B,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;AAC/D,CAAC,IAAI,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC,UAAU,CAAC,EAAE;AACzE,CAAC,IAAI,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,UAAU,CAAC,EAAE;AACzE,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC;AACzC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK;AACvD,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC3D,CAAC,EAAE,CAAC,CAAC;AACL,EAAE,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,EAAE;AACvB,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AACzG,CAAC,CAAC,CAAC,CAAC;AACJ,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,EAAE;AAC1C,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AACvB,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,EAAE;AAClC,GAAG,IAAI,CAAC,kBAAkB,GAAG,gBAAgB,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC,IAAI,CAAC,EAAE;AACnG,GAAG,IAAI,CAAC,kBAAkB,GAAG,gBAAgB,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC,IAAI,CAAC,EAAE;AACjG,GAAG,MAAM,CAAC,KAAK,CAAC;AAChB,EAAE,CAAC;AACH,CAAC,CAAC;AACF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC;AAC9C,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK;AAC/D,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACjE,CAAC,IAAI,CAAC,kBAAkB,GAAG,mBAAmB,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC,IAAI,CAAC,EAAE;AACpG,CAAC,IAAI,CAAC,kBAAkB,GAAG,mBAAmB,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC,IAAI,CAAC,EAAE;AAClG,CAAC,EAAE,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE;AAChG,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC;AAC/F,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE;AACxB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC;AACrC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK;AAC/D,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACzD,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,EAAE;AACrC;AACA,CAAC,EAAE,CAAC,CAAC;AACL,EAAE,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;AAChE,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AACzG,CAAC,CAAC,CAAC,CAAC;AACJ,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ,GAAG;AAC1B,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;AACtB,EAAE,CAAC,CAAC,cAAc,GAAG;AACrB,EAAE,CAAC,CAAC,eAAe,GAAG;AACtB,CAAC,CAAC;AACF;AACA,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;AACrB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC;AACtC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK;AACpD,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC7D,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,EAAE;AACrC;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAC/C,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,EAAE;AACjC,CAAC,CAAC;AACF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC;AACpC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK;AAClD,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC3D,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,EAAE;AACrC;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAC/C,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,EAAE;AAClC,CAAC,CAAC;AACF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;AAC1C,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI;AAChG,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC;AACtC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;AAC1B,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK;AAC3D,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC3D,CAAC,GAAG,CAAC,IAAI,CAAC;AACV,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE;AACtD;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACtB,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE;AAC7C,CAAC,CAAC;AACF;AACA,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AACjD,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC;AACxC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC;AAClG,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,QAAQ;AAC5C,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,UAAU;AAC7C,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI;AAC7C,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,SAAS,CAAC,qBAAqB,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC/D,CAAC,IAAI,CAAC,QAAQ,GAAG;AACjB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC;AAC/C,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS;AAC9D,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACpD,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC;AACrB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,aAAa,CAAC;AAC/C,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAClD,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC;AACxB,EAAE,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,cAAc,GAAG;AAC9C,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG;AACb,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG;AACX,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG;AACd,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,cAAc,GAAG,QAAQ,CAAC;AAChD,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM;AACxD,EAAE,EAAE;AACJ;AACA,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK;AAChC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AACjD,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE;AACnB,EAAE,EAAE,CAAC,CAAC;AACN,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM;AACjB,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;AAChC,GAAG,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK;AACnD,GAAG,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACjE,EAAE,CAAC,CAAC,CAAC;AACL,GAAG,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM;AAC9F,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;AAC3F,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACrC,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,EAAE;AAC7B,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACjB,IAAI,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG;AACzC,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AACjE,IAAI,IAAI,CAAC,WAAW,GAAG;AACvB,GAAG,CAAC;AACJ,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,EAAE;AACpC,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AACpB,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACxB,EAAE,CAAC;AACH,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM;AAC1C,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAC7B,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACzB,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,GAAG;AAChC,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;AAClD,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;AACrC,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,EAAE;AAC7B,EAAE,CAAC;AACH,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACvB,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,EAAE;AAC7B,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK;AAC1B,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACpB,EAAE,IAAI,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE;AACvD,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACT,EAAE,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE;AACpD,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC;AACxD,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,EAAE;AACtB,CAAC,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK;AACtC,CAAC,IAAI,CAAC,cAAc,GAAG;AACvB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC;AACrB,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACjD,CAAC,GAAG,CAAC,IAAI,CAAC;AACV;AACA,CAAC,IAAI,CAAC,UAAU,GAAG;AACnB,CAAC,IAAI,CAAC,OAAO,CAAC,cAAc,GAAG,UAAU,CAAC,CAAC,IAAI,CAAC,EAAE;AAClD,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAC7B,EAAE,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;AACjD,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,EAAE,UAAU,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,GAAG;AAClD,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,EAAE;AAC5B,CAAC,CAAC;AACF,CAAC,IAAI,EAAE,OAAO,CAAC,MAAM,GAAG;AACxB,EAAE;;AC5XF,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,UAAU,EAAE;AAClH,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,cAAc,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,GAAG;AACpG,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC;AACxF,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,EAAE;AACvG,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ;AACpD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO;AACtB,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,eAAe,EAAE,CAAC,CAAC;AAChD,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AACvC,EAAE;AACF;AACA,EAAE,CAAC,KAAK,CAAC,EAAE;AACX;AACA,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE;AACjD;AACA,EAAE,CAAC,OAAO,CAAC,EAAE;AACb;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO;AAC7B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM;AAC1E,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM;AAC1E,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM;AAC1E,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM;AACxE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK;AACnC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACvF,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC;AACzC,EAAE,IAAI,CAAC,CAAC,CAAC,GAAG;AACZ,EAAE,IAAI,CAAC,CAAC,CAAC,GAAG;AACZ;AACA,CAAC,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK;AAC3C,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,qBAAqB,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE;AACzF;AACA,CAAC,EAAE,CAAC,SAAS;AACb,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE;AAC1C,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE;AACxC;AACA,CAAC,EAAE,CAAC,IAAI;AACR,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AACrD,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACjC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;AAC9B,EAAE,CAAC;AACH,CAAC,CAAC;AACF;AACA,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE;AAClD,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC;AAC3D,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG;AAC3F,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC;AAClB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,IAAI,GAAG;AACpG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG;AACnG,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE;AACnD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,GAAG;AAChG,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM;AAC5B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU;AAC9F,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS;AACnG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC;AACvE,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,KAAK;AAC5D,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,KAAK;AACnF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK;AAClD,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACrE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC;AAC9B,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG;AACb;AACA,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC;AACzE;AACA,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AACvD,EAAE,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE;AACzB,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AACvB,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AAClC,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,EAAE;AACjC,IAAI,EAAE,CAAC,CAAC;AACR,KAAK,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO;AAC7D,KAAK,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC,EAAE;AACrC,KAAK,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK;AAClC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAC/B,IAAI,CAAC,CAAC,CAAC;AACP,KAAK,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AACxB,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,MAAM,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAC1B,KAAK,CAAC;AACN,IAAI,CAAC;AACL,GAAG,CAAC;AACJ,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;AACV,GAAG,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK;AACtD,GAAG,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;AACpC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AAC1B,GAAG,CAAC;AACJ,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACpC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACvB,KAAK,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AACpC,MAAM,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,EAAE;AACnC,MAAM,EAAE,CAAC,CAAC;AACV,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK;AAC3C,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE;AAC1C,OAAO,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO;AAC/D,OAAO,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,EAAE;AACpC,OAAO,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK;AACpC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACjC,MAAM,CAAC,CAAC,CAAC;AACT,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AAC1B,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACpB,QAAQ,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAC5B,OAAO,CAAC;AACR,MAAM,CAAC;AACP,KAAK,CAAC;AACN,IAAI,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK;AACtE,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAChE,KAAK,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;AAC7B,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,MAAM,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAC/B,KAAK,CAAC;AACN,IAAI,CAAC;AACL,GAAG,CAAC;AACJ,EAAE,CAAC;AACH,CAAC,CAAC;AACF,CAAC,MAAM,CAAC,KAAK,CAAC;AACd,EAAE;;ACtIF,GAAG;AACH,CAAC,CAAC,CAAC,kBAAkB,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI;AACrG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE;AACtG,CAAC,CAAC,CAAC,OAAO,CAAC;AACX,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,aAAa,CAAC,CAAC,EAAE,GAAG,EAAE;AACrD,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,cAAc,CAAC,CAAC,EAAE,IAAI,EAAE;AACxD,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,cAAc,CAAC,CAAC,EAAE,IAAI,EAAE;AACxD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC;AACrD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,EAAE;AACvG,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ;AACpD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO;AACtB,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,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC;AAC1B,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW;AACtB,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AACzB;AACA,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,iBAAiB,GAAG;AAC9D;AACA,CAAC,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,UAAU;AAC/B,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AACvD,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;AACvC,CAAC,CAAC;AACF,EAAE;AACF;AACA,EAAE,CAAC,KAAK,CAAC,EAAE;AACX;AACA,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE;AACtD;AACA,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE;AACpB;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,YAAY,CAAC;AACjE,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,QAAQ,GAAG,CAAC,OAAO,CAAC,OAAO;AACvC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC/D,CAAC,MAAM,CAAC,CAAC;AACT,EAAE,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC;AACrB,EAAE,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC;AACtB,EAAE,EAAE,CAAC,EAAE,CAAC,aAAa;AACrB,CAAC,EAAE;AACH,EAAE;;ACjDF,GAAG;AACH,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU;AAC/H,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO;AACxJ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC;AACzF,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ;AACvE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC;AACzB,CAAC,CAAC,KAAK,QAAQ,CAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAC/C,CAAC,CAAC,QAAQ,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;AACrE,CAAC,CAAC,YAAY,MAAM,CAAC,CAAC,IAAI,CAAC;AAC3B,CAAC,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE;AAC5B,CAAC,CAAC,YAAY,IAAI,CAAC,CAAC,IAAI;AACxB,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;AAC1B,CAAC,CAAC,QAAQ,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,GAAG,CAAC,EAAE,CAAC,EAAE;AAC5D,CAAC,CAAC,KAAK,EAAE;AACT,CAAC,CAAC,KAAK,EAAE,CAAC,YAAY,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE;AACpD,CAAC,CAAC,KAAK,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;AACrC,CAAC,CAAC,KAAK,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;AACrC,CAAC,CAAC,KAAK,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;AACtC,CAAC,CAAC,KAAK,WAAW,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,EAAE;AACxC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK;AACzH,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,EAAE;AAC5E,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ;AACpD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,QAAQ;AACZ,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI;AACtB,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY;AACnC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,SAAS;AACrC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO;AACjD,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAC/D,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM;AAChE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AAC/D,EAAE,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;AACrB,EAAE,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC;AAC/B,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,EAAE;AACxD;AACA,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AAC/C;AACA,CAAC,EAAE,CAAC,MAAM;AACV,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,EAAE;AACzD;AACA,CAAC,EAAE,CAAC,cAAc;AAClB,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,SAAS,CAAC,UAAU,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AAC5F,CAAC,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE;AAC7C,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE;AACzD,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE;AACpD,EAAE;AACF;AACA,EAAE,CAAC,KAAK,CAAC,EAAE;AACX;AACA,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE;AAC/C,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE;AAC3D;AACA,EAAE,CAAC,OAAO,CAAC,EAAE;AACb;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC;AAClC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAClD,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC;AAC5B,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG;AACtB,CAAC,CAAC;AACF,CAAC,MAAM,CAAC,KAAK,CAAC;AACd,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC;AAC1C,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACvD,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC;AACzC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS;AAC7B,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AAClE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,SAAS,CAAC,EAAE;AAC7B,EAAE;;AC5FF,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC;AAC5F,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,UAAU,EAAE,CAAC,GAAG,CAAC,aAAa,CAAC,GAAG,CAAC,YAAY,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI;AACjG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI;AAC/F,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC;AAChG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE,CAAC,QAAQ,CAAC;AACtC,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC;AACrG,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,QAAQ,CAAC,YAAY,EAAE,CAAC,CAAC;AAChC,CAAC,CAAC,SAAS,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,EAAE;AACxD,CAAC,CAAC,KAAK,EAAE;AACT,CAAC,CAAC,KAAK,EAAE,CAAC,YAAY,CAAC,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,EAAE;AAC5D,CAAC,CAAC,KAAK,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;AAC7C,CAAC,CAAC,KAAK,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,EAAE;AACrD,CAAC,CAAC,KAAK,YAAY,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;AAC1C,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,CAAC,QAAQ,EAAE;AAC5B,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,aAAa,EAAE;AAClC,CAAC,CAAC,SAAS,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC;AAChD,CAAC,CAAC,KAAK,EAAE;AACT,CAAC,CAAC,KAAK,WAAW,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,EAAE;AAC5C,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,EAAE;AAC7E,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE;AAC9E,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,aAAa;AAClE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,GAAG,WAAW,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM;AAChD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,QAAQ;AACZ,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI;AACtB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,SAAS;AACrC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO;AACjD,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACvE,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM;AAChE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AAC/D,EAAE,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;AACrB,EAAE,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC;AAC/B,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,EAAE;AAC5D;AACA,CAAC,EAAE,CAAC,UAAU;AACd,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE;AAC/E;AACA,CAAC,EAAE,CAAC,MAAM;AACV,CAAC,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,EAAE;AACxE;AACA,CAAC,EAAE,CAAC,cAAc;AAClB,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,GAAG;AACrB,CAAC,IAAI,EAAE,OAAO;AACd,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC;AACpC,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,cAAc,EAAE,OAAO,CAAC,EAAE;AAC1C,EAAE;AACF;AACA,EAAE,CAAC,KAAK,CAAC,EAAE;AACX;AACA,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE;AACnD;AACA,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE;AACvB;AACA,GAAG;AACH,CAAC,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC;AAC3B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,aAAa,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK;AAC7F,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;AACtF,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC;AACxF,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,EAAE;AACpC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG;AAC5C;AACA,EAAE,CAAC,OAAO,CAAC,EAAE;AACb;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC;AAClC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACtD,CAAC,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE;AAC9D,CAAC,MAAM,CAAC,KAAK,CAAC;AACd,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,WAAW,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC;AACvE,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,QAAQ;AAChD,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AAC1E,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,QAAQ,CAAC,EAAE;AAC9B,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC;AAC1C,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC3D,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,EAAE;AACzB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,aAAa,CAAC;AAC9E,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,GAAG;AACjH,CAAC,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC;AACrB,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC;AAChC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAChE,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AAC/B,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM;AACvC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AACpC,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE;AAClD,EAAE,CAAC;AACH,CAAC,CAAC;AACF;AACA,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,mBAAmB,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,EAAE;AACjF,EAAE;;AC5HF,GAAG;AACH,CAAC,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;AAC9F,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,aAAa,CAAC;AACjH,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,aAAa,GAAG,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,GAAG;AACrG,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI;AACvG,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC;AACZ,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE;AACvG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;AACV,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,CAAC,OAAO;AACf,CAAC,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK;AAClD,CAAC,CAAC,KAAK,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,GAAG;AACjD,CAAC,CAAC,KAAK,GAAG,CAAC,gBAAgB,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,GAAG;AAC3D,CAAC,CAAC,KAAK,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,WAAW,CAAC,CAAC,gBAAgB,CAAC,EAAE;AACxE,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI;AAC5E,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,EAAE;AAClF,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO;AACnE,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI;AACnD,CAAC,CAAC,KAAK,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;AAC9B,CAAC,CAAC,SAAS,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,EAAE;AACtD,CAAC,CAAC,KAAK,CAAC;AACR,CAAC,CAAC,KAAK,EAAE,CAAC,YAAY,CAAC,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE;AACjD,CAAC,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG;AACnG,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE;AAC1D,CAAC,CAAC,KAAK,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE;AACzC,CAAC,CAAC,KAAK,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE;AACzC,CAAC,CAAC,KAAK,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK;AAC7C,CAAC,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,OAAO,EAAE;AACnF,CAAC,CAAC,KAAK,UAAU,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACpD,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE;AAChD,CAAC,CAAC,SAAS,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE;AAC7D,CAAC,CAAC,SAAS,IAAI,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,EAAE;AACnC,CAAC,CAAC,KAAK,EAAE;AACT,CAAC,CAAC,KAAK,UAAU,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG;AAC3D,CAAC,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO;AAC1E,CAAC,CAAC,KAAK,WAAW,CAAC,QAAQ,CAAC,CAAC,UAAU,CAAC,EAAE;AAC1C,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AAC/F,CAAC,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE;AAC9C,CAAC,CAAC,KAAK,QAAQ,CAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAC/C,CAAC,CAAC,SAAS,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;AACtE,CAAC,CAAC,aAAa,MAAM,CAAC,CAAC,IAAI,CAAC;AAC5B,CAAC,CAAC,aAAa,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE;AAC7B,CAAC,CAAC,aAAa,IAAI,CAAC,CAAC,IAAI;AACzB,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;AAC3B,CAAC,CAAC,SAAS,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,GAAG,CAAC,EAAE,CAAC,EAAE;AAC7D,CAAC,CAAC,KAAK,CAAC;AACR,CAAC,CAAC,KAAK,EAAE,CAAC,YAAY,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE;AACpD,CAAC,CAAC,KAAK,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;AACrC,CAAC,CAAC,KAAK,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;AACrC,CAAC,CAAC,KAAK,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;AACtC,CAAC,CAAC,KAAK,WAAW,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,EAAE;AACxC,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;AACnG,CAAC,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE;AAC7D,CAAC,CAAC,KAAK,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;AACvB,CAAC,CAAC,SAAS,CAAC;AACZ,CAAC,CAAC,aAAa,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI;AAC9D,CAAC,CAAC,aAAa,IAAI,CAAC,CAAC,CAAC,GAAG,EAAE;AAC3B,CAAC,CAAC,aAAa,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;AAC5C,CAAC,CAAC,SAAS,CAAC;AACZ,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACX,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ;AACxE,CAAC,CAAC,KAAK,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;AAC3C,CAAC,CAAC,SAAS,QAAQ,CAAC,CAAC,KAAK,CAAC;AAC3B,CAAC,CAAC,SAAS,MAAM,CAAC,CAAC,IAAI;AACvB,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACX,CAAC,CAAC,KAAK,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;AAClD,CAAC,CAAC,SAAS,QAAQ,CAAC,CAAC,KAAK,CAAC;AAC3B,CAAC,CAAC,SAAS,MAAM,CAAC,CAAC,IAAI;AACvB,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACX,CAAC,CAAC,KAAK,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC;AAC7B,CAAC,CAAC,SAAS,OAAO,EAAE,OAAO,CAAC;AAC5B,CAAC,CAAC,SAAS,YAAY,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AAChD,CAAC,CAAC,KAAK,EAAE;AACT,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE;AAC5C,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;AACpG,CAAC,CAAC,KAAK,EAAE,CAAC,QAAQ,CAAC;AACnB,CAAC,CAAC,KAAK,OAAO,CAAC,UAAU,GAAG;AAC5B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE;AACjH,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,EAAE;AACvG,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ;AACpD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS;AAC3B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,OAAO;AACjC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO;AACjD,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACnE,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM;AAChE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AAC7D,EAAE,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC;AACnB,EAAE,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;AAC3B,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,EAAE;AACzD;AACA,CAAC,EAAE,CAAC,cAAc;AAClB,CAAC,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE;AAChD,CAAC,IAAI,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE;AACpD,EAAE;AACF;AACA,EAAE,CAAC,KAAK,CAAC,EAAE;AACX;AACA,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE;AACvD;AACA,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE;AACvB;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,MAAM;AACV,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC;AAC/C;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,MAAM;AACV,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC;AAC/C;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,MAAM;AACV,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE;;ACvIvC,GAAG;AACH,CAAC,CAAC,CAAC,cAAc,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,aAAa,CAAC;AAClG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE;AAC9G,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC;AAC3G,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,QAAQ;AACZ,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS;AAC3B,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW;AAClC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB;AACvC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY;AACnC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa;AACpC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,cAAc;AACrC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB;AACvC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB;AACvC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,iBAAiB;AACxC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,OAAO;AACjC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO;AACjD,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK;AACjE,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACvE,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM;AAChE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AAC7D,EAAE,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC;AACnB,EAAE,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;AAC3B,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,aAAa,CAAC,cAAc;AAChC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;AACrB,EAAE,SAAS,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS;AAClH,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE;AACb;AACA,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,EAAE;AAC3D;AACA,CAAC,EAAE,CAAC,UAAU;AACd,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC;AACrB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC;AACvB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AAC/C,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE;AAC9B;AACA,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AAC9C,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AACnD,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AAC/C,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AAChD,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE;AACjD,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;AAChG,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;AACjE,EAAE,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC;AAC1B,EAAE,CAAC,kBAAkB,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC;AACpC,EAAE,iBAAiB,CAAC,CAAC,KAAK,CAAC;AAC3B,EAAE,gBAAgB,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;AAC1E,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;AACP,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;AACnG;AACA,CAAC,EAAE,CAAC,MAAM;AACV,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;AACnB,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AAClD,EAAE,KAAK,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AAC9C,EAAE,SAAS,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AACpD,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC;AAC/C,CAAC,CAAC,CAAC,EAAE;AACL;AACA,CAAC,EAAE,CAAC,cAAc;AAClB,CAAC,IAAI,EAAE,MAAM;AACb,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC;AAC5C,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;AAC3B,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE;AACtD,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC;AAC3E,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE;AACnF,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,KAAK,CAAC,WAAW,CAAC;AAC5C,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AACrC,EAAE,IAAI,EAAE,KAAK;AACb,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;AAC1B,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC;AAC9C,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;AAC1B,GAAG,EAAE;AACL,CAAC,CAAC;AACF,CAAC,IAAI,EAAE,OAAO;AACd,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC;AACrC,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE;AAC3B,CAAC,IAAI,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,EAAE;AACtD,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE;AAC5C,EAAE;AACF;AACA,EAAE,CAAC,KAAK,CAAC,EAAE;AACX;AACA,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE;AACzD,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE;AAC/D,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,EAAE;AACpE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE;AAChE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,EAAE;AACjE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,EAAE;AAClE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,EAAE;AACpE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,EAAE;AACpE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,iBAAiB,CAAC,EAAE;AACrE;AACA,EAAE,CAAC,OAAO,CAAC,EAAE;AACb;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC1D,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM;AACjB,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,EAAE;AAC5E;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,iBAAiB,EAAE,CAAC,CAAC,CAAC,CAAC;AACvD,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,EAAE;AAC1B,CAAC,CAAC;AACF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC;AAC3B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;AACjG,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK;AAC/D,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACxD,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE;AAC7B,CAAC,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO;AAC9D,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAChF,EAAE,MAAM,CAAC;AACT,CAAC,CAAC;AACF,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACpF,EAAE,MAAM,CAAC;AACT,CAAC,CAAC;AACF,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,EAAE;AACzB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC9D,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,QAAQ;AAC1D,CAAC,EAAE,CAAC,CAAC;AACL,EAAE,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;AACpF,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AACzG,CAAC,CAAC,CAAC,CAAC;AACJ,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,EAAE;AAC1B,CAAC,CAAC;AACF,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE;AAC3E,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC;AACrC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK;AACnD,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACpE,CAAC,EAAE,CAAC,CAAC;AACL,EAAE,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,EAAE;AACvB,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AACzG,CAAC,CAAC,CAAC,CAAC;AACJ,EAAE,MAAM,CAAC,KAAK,CAAC;AACf,CAAC,CAAC;AACF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC;AACzC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,SAAS;AACb,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK;AACvD,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACtE,CAAC,EAAE,CAAC,CAAC;AACL,EAAE,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,EAAE;AACvB,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AACzG,CAAC,CAAC,CAAC,CAAC;AACJ,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE;AACjC,EAAE,MAAM,CAAC,KAAK,CAAC;AACf,CAAC,CAAC;AACF,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC;AACrC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM;AACzC,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACvD,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC;AACpB,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC;AAC7B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO;AAC3F,CAAC,CAAC,CAAC,YAAY,CAAC;AAChB,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG;AACjD,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAC/D,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,aAAa,CAAC;AACnC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC;AACjB,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAC/B,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC;AACtB,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAChB,GAAG,IAAI,CAAC,kBAAkB,GAAG,gBAAgB,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,EAAE;AACrF,GAAG,IAAI,CAAC,kBAAkB,GAAG,gBAAgB,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,EAAE;AACnF;AACA,GAAG,IAAI,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE;AACrC,GAAG,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,EAAE;AAC3D,GAAG,IAAI,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE;AAC/D,GAAG,IAAI,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,EAAE;AAClC,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,EAAE;AAC/B;AACA,GAAG,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK;AAC/C,GAAG,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACzC;AACA,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,qBAAqB,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,oBAAoB,EAAE,CAAC,CAAC,CAAC,CAAC;AACvE,IAAI,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO;AACxF,IAAI,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE;AACxC,GAAG,CAAC;AACJ,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,qBAAqB,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,oBAAoB,EAAE,CAAC,CAAC,CAAC,CAAC;AACvE,IAAI,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS;AAC/F,IAAI,cAAc,CAAC,CAAC,CAAC,IAAI,EAAE,4BAA4B,CAAC,KAAK,GAAG;AAChE,IAAI,aAAa,CAAC,CAAC,CAAC,IAAI,EAAE,4BAA4B,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC;AAC1F,KAAK,CAAC,CAAC,CAAC;AACR,KAAK,IAAI,EAAE,4BAA4B,CAAC,MAAM,GAAG,IAAI,CAAC;AACtD;AACA,IAAI,IAAI,CAAC,cAAc,CAAC,CAAC,KAAK,CAAC,EAAE;AACjC,IAAI,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AAC1C;AACA,IAAI,IAAI,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;AAC1B,KAAK,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,EAAE;AAC5D,KAAK,KAAK,CAAC,CAAC,cAAc;AAC1B,IAAI,CAAC,CAAC,EAAE;AACR,GAAG,CAAC;AACJ,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;AACV,GAAG,IAAI,CAAC,kBAAkB,GAAG,mBAAmB,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,EAAE;AACxF,GAAG,IAAI,CAAC,kBAAkB,GAAG,mBAAmB,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,EAAE;AACtF,GAAG,IAAI,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,EAAE;AAC9D,GAAG,IAAI,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE;AAClE,GAAG,IAAI,CAAC,iBAAiB,CAAC,CAAC,KAAK,CAAC,EAAE;AACnC,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC,KAAK,CAAC,EAAE;AAChC,EAAE,CAAC;AACH,EAAE,IAAI,CAAC,kBAAkB,GAAG;AAC5B,CAAC,CAAC;AACF,EAAE;;ACnPF,GAAG;AACH,CAAC,CAAC,CAAC,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;AAC/F,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,aAAa,CAAC;AACjH,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,YAAY,GAAG,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,SAAS;AAC9G,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,UAAU;AAClH,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC;AACpD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,IAAI;AAChH,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO;AACjH,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC;AACpC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,cAAc,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,OAAO;AAC3H,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,GAAG,CAAC,IAAI;AACvH,CAAC,CAAC,CAAC,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE;AACvG,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,CAAC,OAAO;AACf,CAAC,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,aAAa;AACpC,CAAC,CAAC,KAAK,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,GAAG;AACjD,CAAC,CAAC,KAAK,GAAG,CAAC,gBAAgB,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,GAAG;AAC3D,CAAC,CAAC,KAAK,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,WAAW,CAAC,CAAC,gBAAgB,CAAC,EAAE;AACxE,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK;AAC1C,CAAC,CAAC,KAAK,QAAQ,CAAC,YAAY,EAAE,CAAC,CAAC;AAChC,CAAC,CAAC,SAAS,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,EAAE;AACxD,CAAC,CAAC,KAAK,CAAC;AACR,CAAC,CAAC,KAAK,EAAE,CAAC,YAAY,CAAC,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE;AACnD,CAAC,CAAC,KAAK,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;AAC7C,CAAC,CAAC,KAAK,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;AAC7C,CAAC,CAAC,KAAK,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,EAAE;AACrD,CAAC,CAAC,KAAK,YAAY,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACtD,CAAC,CAAC,SAAS,IAAI,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,EAAE;AACnC,CAAC,CAAC,KAAK,EAAE;AACT,CAAC,CAAC,KAAK,YAAY,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG;AAC7D,CAAC,CAAC,KAAK,WAAW,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,EAAE;AAC5C,CAAC,CAAC,KAAK,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI;AAC3D,CAAC,CAAC,KAAK,QAAQ,CAAC,SAAS,EAAE,CAAC,CAAC;AAC7B,CAAC,CAAC,SAAS,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,EAAE;AACrD,CAAC,CAAC,KAAK,CAAC;AACR,CAAC,CAAC,KAAK,EAAE,CAAC,YAAY,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE;AAChD,CAAC,CAAC,KAAK,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE;AACvC,CAAC,CAAC,KAAK,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE;AACxC,CAAC,CAAC,KAAK,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE;AACnD,CAAC,CAAC,KAAK,SAAS,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACnD,CAAC,CAAC,SAAS,IAAI,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,EAAE;AACnC,CAAC,CAAC,KAAK,EAAE;AACT,CAAC,CAAC,KAAK,SAAS,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG;AAC1D,CAAC,CAAC,KAAK,WAAW,CAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,EAAE;AACzC,CAAC,CAAC,KAAK,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;AACvB,CAAC,CAAC,SAAS,CAAC;AACZ,CAAC,CAAC,aAAa,EAAE,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC;AACpD,CAAC,CAAC,aAAa,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE;AAC5B,CAAC,CAAC,aAAa,KAAK,CAAC,CAAC,CAAC,aAAa,EAAE;AACtC,CAAC,CAAC,aAAa,IAAI,CAAC,CAAC,CAAC,QAAQ,EAAE;AAChC,CAAC,CAAC,aAAa,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE;AACvG,CAAC,CAAC,aAAa,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,EAAE;AAC5C,CAAC,CAAC,aAAa,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AAChD,CAAC,CAAC,aAAa,aAAa,CAAC,CAAC,EAAE,KAAK,EAAE;AACvC,CAAC,CAAC,SAAS,CAAC;AACZ,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACX,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ;AACxE,CAAC,CAAC,KAAK,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;AAC3C,CAAC,CAAC,SAAS,QAAQ,CAAC,CAAC,KAAK,CAAC;AAC3B,CAAC,CAAC,SAAS,MAAM,CAAC,CAAC,IAAI;AACvB,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACX,CAAC,CAAC,KAAK,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC;AAC7B,CAAC,CAAC,SAAS,OAAO,EAAE,OAAO;AAC3B,CAAC,CAAC,KAAK,EAAE;AACT,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE;AAC5C,CAAC,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC;AACnG,CAAC,CAAC,KAAK,OAAO,CAAC,UAAU,GAAG;AAC5B,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,EAAE;AACvG,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ;AACpD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc;AAChC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,OAAO;AACjC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO;AACjD,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,WAAW,CAAC,KAAK;AACxG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,EAAE;AACnG,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI;AACnG,CAAC,CAAC,EAAE,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,SAAS,CAAC;AACnG,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE;AAC9E,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,WAAW,CAAC;AAC5G,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC;AAC3G,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI;AACvG,CAAC,CAAC,EAAE,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS;AAC1G,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC;AACnG,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACrE,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM;AAChE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AAC7D,EAAE,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC;AACnB,EAAE,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;AAC3B,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,aAAa,CAAC,cAAc;AAChC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG;AACvB;AACA,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC;AAC7E,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC;AAC3C,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC;AACvC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC;AACzE,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,GAAG;AAC5B;AACA,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,EAAE;AAC1D;AACA,CAAC,EAAE,CAAC,cAAc;AAClB,CAAC,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,EAAE;AACjD,CAAC,IAAI,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,EAAE;AACrD,EAAE;AACF;AACA,EAAE,CAAC,KAAK,CAAC,EAAE;AACX;AACA,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,EAAE;AAC7D;AACA,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE;AACvB;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,MAAM;AACV,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;AACzC;AACA,EAAE,CAAC,OAAO,CAAC,EAAE;AACb;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACtD,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,GAAG;AAChC;AACA,CAAC,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE;AAC5D;AACA,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,KAAK;AACxC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AAC1C,EAAE,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC;AACrC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AAC/C,EAAE,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC,qBAAqB,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE;AAC1F,CAAC,CAAC;AACF;AACA,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,GAAG;AAC5B,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAC1D,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AACzD,GAAG,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;AAClE,EAAE,CAAC;AACH,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK;AAC9C,CAAC,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,qBAAqB,IAAI,OAAO,CAAC,EAAE;AAC7D;AACA,CAAC,IAAI,CAAC,qBAAqB,GAAG,MAAM,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE;AAC3E,CAAC,IAAI,CAAC,sBAAsB,GAAG;AAC/B,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK;AAC9C,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI;AAC5C,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,SAAS,CAAC,qBAAqB,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACnE,CAAC,GAAG,CAAC,kBAAkB,CAAC;AACxB,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AAC/C,EAAE,kBAAkB,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACpC,GAAG,kBAAkB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,EAAE;AACtD,EAAE,EAAE;AACJ;AACA,EAAE,EAAE,CAAC,YAAY,CAAC,CAAC,kBAAkB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE;AACpD;AACA,EAAE,kBAAkB,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACvD,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC;AACtD,GAAG,IAAI,CAAC,SAAS,CAAC,sBAAsB,GAAG;AAC3C,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,EAAE;AAC3B,EAAE,EAAE;AACJ,EAAE,kBAAkB,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC5D,GAAG,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC,cAAc,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC;AAC7E,EAAE,EAAE;AACJ;AACA,EAAE,kBAAkB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE;AAChD;AACA,EAAE,IAAI,CAAC,kBAAkB,CAAC,CAAC,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,EAAE;AAC3D,CAAC,CAAC;AACF,CAAC,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC;AAChC,EAAE;AACF;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC7D,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK;AACvE,CAAC,EAAE,CAAC,CAAC;AACL,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE;AAClE,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AACzG,CAAC,CAAC,CAAC,CAAC;AACJ,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,cAAc,CAAC,CAAC,KAAK;AAClG,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,cAAc,CAAC,QAAQ,CAAC;AAChG,EAAE,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE;AAClF,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACT,EAAE,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE;AAC3E,CAAC,CAAC;AACF,EAAE;AACF;AACA,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,SAAS,CAAC,sBAAsB,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACpE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC;AAClB;AACA,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;AAC5C,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE;AAC/C,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACT,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;AAC/C,CAAC,CAAC;AACF;AACA,CAAC,IAAI,CAAC,qBAAqB,EAAE;AAC7B,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC;AAClB,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE;AAChG;AACA,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAClE,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE;AACrD,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO;AACxD,CAAC,IAAI,CAAC,IAAI,GAAG;AACb,EAAE;;AClOF,GAAG;AACH,CAAC,CAAC,CAAC,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;AAC/F,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,YAAY,CAAC;AAC/G,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,aAAa,GAAG,CAAC,cAAc,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,EAAE;AAC9G,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG;AACvG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC;AACzG,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC;AACrG,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,cAAc,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO;AACrG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC;AACb,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,CAAC,OAAO;AACf,CAAC,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,aAAa;AACpC,CAAC,CAAC,KAAK,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,GAAG;AACjD,CAAC,CAAC,KAAK,GAAG,CAAC,gBAAgB,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,GAAG;AAC3D,CAAC,CAAC,KAAK,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,WAAW,CAAC,CAAC,gBAAgB,CAAC,EAAE;AACxE,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI;AAC5E,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,EAAE;AAC7G,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO;AACnE,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,QAAQ,CAAC,YAAY,EAAE,CAAC,CAAC;AAChC,CAAC,CAAC,SAAS,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,EAAE;AACxD,CAAC,CAAC,SAAS,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC;AACrC,CAAC,CAAC,KAAK,CAAC;AACR,CAAC,CAAC,KAAK,EAAE,CAAC,YAAY,CAAC,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE;AACnD,CAAC,CAAC,KAAK,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;AAC7C,CAAC,CAAC,KAAK,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;AAC7C,CAAC,CAAC,KAAK,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,EAAE;AACrD,CAAC,CAAC,KAAK,YAAY,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACtD,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE;AAClD,CAAC,CAAC,SAAS,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK;AACnD,CAAC,CAAC,SAAS,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC;AAClD,CAAC,CAAC,SAAS,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE;AAC/C,CAAC,CAAC,SAAS,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK;AACtC,CAAC,CAAC,SAAS,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,EAAE;AAC9C,CAAC,CAAC,KAAK,EAAE;AACT,CAAC,CAAC,KAAK,YAAY,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG;AAC7D,CAAC,CAAC,KAAK,WAAW,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,EAAE;AAC5C,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,QAAQ,CAAC,SAAS,EAAE,CAAC,CAAC;AAC7B,CAAC,CAAC,SAAS,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,EAAE;AACrD,CAAC,CAAC,SAAS,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC;AACrC,CAAC,CAAC,KAAK,CAAC;AACR,CAAC,CAAC,KAAK,EAAE,CAAC,YAAY,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE;AAChD,CAAC,CAAC,KAAK,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE;AACvC,CAAC,CAAC,KAAK,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;AAC1C,CAAC,CAAC,KAAK,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE;AAC7C,CAAC,CAAC,KAAK,SAAS,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACnD,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE;AACpD,CAAC,CAAC,SAAS,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK;AACnD,CAAC,CAAC,SAAS,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC;AAClD,CAAC,CAAC,SAAS,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE;AAC/C,CAAC,CAAC,SAAS,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK;AACtC,CAAC,CAAC,SAAS,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,EAAE;AAC9C,CAAC,CAAC,KAAK,EAAE;AACT,CAAC,CAAC,KAAK,SAAS,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG;AAC1D,CAAC,CAAC,KAAK,WAAW,CAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,EAAE;AACzC,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;AACnG,CAAC,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE;AAC7D,CAAC,CAAC,KAAK,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;AACvB,CAAC,CAAC,SAAS,CAAC;AACZ,CAAC,CAAC,aAAa,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE;AAC5B,CAAC,CAAC,aAAa,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,EAAE;AACvD,CAAC,CAAC,aAAa,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,KAAK,EAAE;AACrD,CAAC,CAAC,aAAa,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;AAC/C,CAAC,CAAC,SAAS,CAAC;AACZ,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACX,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ;AACxE,CAAC,CAAC,KAAK,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;AAC3C,CAAC,CAAC,SAAS,QAAQ,CAAC,CAAC,KAAK,CAAC;AAC3B,CAAC,CAAC,SAAS,MAAM,CAAC,CAAC,IAAI;AACvB,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACX,CAAC,CAAC,KAAK,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;AAClD,CAAC,CAAC,SAAS,QAAQ,CAAC,CAAC,KAAK,CAAC;AAC3B,CAAC,CAAC,SAAS,MAAM,CAAC,CAAC,IAAI;AACvB,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;AACX,CAAC,CAAC,KAAK,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC;AAC7B,CAAC,CAAC,SAAS,OAAO,EAAE,OAAO,CAAC;AAC5B,CAAC,CAAC,SAAS,YAAY,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AAChD,CAAC,CAAC,KAAK,EAAE;AACT,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE;AAC5C,CAAC,CAAC;AACF,CAAC,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;AACpG,CAAC,CAAC,KAAK,EAAE,CAAC,QAAQ,CAAC;AACnB,CAAC,CAAC,KAAK,OAAO,CAAC,UAAU,GAAG;AAC5B,CAAC,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,EAAE;AACrC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE;AAChH,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE;AACxG,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ;AACpD,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,KAAK;AACT,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc;AAChC,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,WAAW;AACf,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,OAAO;AACjC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,OAAO;AACjD,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACrE,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM;AAChE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AAC7D,EAAE,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC;AACnB,EAAE,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;AAC3B,CAAC,CAAC;AACF;AACA,CAAC,EAAE,CAAC,aAAa,CAAC,cAAc;AAChC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG;AACvB;AACA,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW;AACtB,CAAC,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,EAAE;AAC1D;AACA,CAAC,EAAE,CAAC,MAAM;AACV,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,EAAE;AAChE;AACA,CAAC,EAAE,CAAC,cAAc;AAClB,CAAC,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,EAAE;AACjD,CAAC,IAAI,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,EAAE;AACrD,EAAE;AACF;AACA,EAAE,CAAC,KAAK,CAAC,EAAE;AACX;AACA,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,EAAE;AAC7D;AACA,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE;AACvB;AACA,GAAG;AACH,CAAC,CAAC,CAAC,CAAC,MAAM;AACV,CAAC,CAAC,CAAC,CAAC,UAAU;AACd,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;AACzC;AACA,EAAE,CAAC,OAAO,CAAC,EAAE;AACb;AACA,GAAG;AACH,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC;AAC1C,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG;AAChG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC;AAC1F,CAAC,CAAC;AACF,CAAC,CAAC,CAAC,CAAC,OAAO;AACX,CAAC,EAAE;AACH,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC3D,CAAC,GAAG,CAAC,IAAI,CAAC;AACV,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG;AAClB;AACA,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAC7B,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC;AACxC,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE;AACpD,EAAE,CAAC;AACH,CAAC,CAAC;AACF;AACA,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;AACjD,EAAE;;AC7JF,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE","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 *     $( '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 *     $( '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.groups = [];\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/* 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 */\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 {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, group,\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\tgroup = groups[ i ];\n\t\tif ( group.include === '*' ) {\n\t\t\t// Apply defaults to catch-all groups\n\t\t\tif ( group.type === undefined ) {\n\t\t\t\tgroup.type = 'list';\n\t\t\t}\n\t\t\tif ( group.label === undefined ) {\n\t\t\t\tgroup.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( group.type ) ? group.type : defaultType;\n\t\titems.push(\n\t\t\tthis.getToolGroupFactory().create( type, this, group )\n\t\t);\n\t}\n\tthis.addItems( items );\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.groups = [];\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 */\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.onCapturedMouseKeyUpHandler = this.onCapturedMouseKeyUp.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/* 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 */\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.onCapturedMouseKeyUpHandler, true );\n\t\t\tthis.getElementDocument().addEventListener( 'keyup', this.onCapturedMouseKeyUpHandler, true );\n\t\t\treturn false;\n\t\t}\n\t}\n};\n\n/**\n * Handle captured 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.onCapturedMouseKeyUp = function ( e ) {\n\tthis.getElementDocument().removeEventListener( 'mouseup', this.onCapturedMouseKeyUpHandler, true );\n\tthis.getElementDocument().removeEventListener( 'keyup', this.onCapturedMouseKeyUpHandler, 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/**\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.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};\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, { disable: 'onToolGroupDisable' } );\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 *     $( '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\tthis.onBlurHandler = this.onBlur.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 focus being lost.\n *\n * The event is actually generated from a mouseup/keyup, so it is not a normal blur event object.\n *\n * @protected\n * @param {MouseEvent|KeyboardEvent} e Mouse up or key up event\n */\nOO.ui.PopupToolGroup.prototype.onBlur = 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( 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 * Handle mouse up and key up events.\n *\n * @protected\n * @param {jQuery.Event} e Mouse up or key up event\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 */\nOO.ui.PopupToolGroup.prototype.onHandleMouseKeyDown = 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.setActive( !this.active );\n\t\treturn false;\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 */\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.onBlurHandler, true );\n\t\t\tthis.getElementDocument().addEventListener( 'keyup', this.onBlurHandler, 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\tleft: -( 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.onBlurHandler, true );\n\t\t\tthis.getElementDocument().removeEventListener( 'keyup', this.onBlurHandler, 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.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 *     $( '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 *     $( '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
diff --git a/resources/lib/oojs-ui/oojs-ui-toolbars.js.map.json b/resources/lib/oojs-ui/oojs-ui-toolbars.js.map.json
new file mode 100644 (file)
index 0000000..62c9195
--- /dev/null
@@ -0,0 +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 *     $( '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 *     $( '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.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/* 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 */\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}\n\tthis.addItems( items );\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 */\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.onCapturedMouseKeyUpHandler = this.onCapturedMouseKeyUp.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/* 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 */\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.onCapturedMouseKeyUpHandler, true );\n\t\t\tthis.getElementDocument().addEventListener( 'keyup', this.onCapturedMouseKeyUpHandler, true );\n\t\t\treturn false;\n\t\t}\n\t}\n};\n\n/**\n * Handle captured 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.onCapturedMouseKeyUp = function ( e ) {\n\tthis.getElementDocument().removeEventListener( 'mouseup', this.onCapturedMouseKeyUpHandler, true );\n\tthis.getElementDocument().removeEventListener( 'keyup', this.onCapturedMouseKeyUpHandler, 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/**\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.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};\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, { disable: 'onToolGroupDisable' } );\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 *     $( '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\tthis.onBlurHandler = this.onBlur.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 focus being lost.\n *\n * The event is actually generated from a mouseup/keyup, so it is not a normal blur event object.\n *\n * @protected\n * @param {MouseEvent|KeyboardEvent} e Mouse up or key up event\n */\nOO.ui.PopupToolGroup.prototype.onBlur = 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( 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.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.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 */\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 */\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.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 */\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.onBlurHandler, true );\n\t\t\tthis.getElementDocument().addEventListener( 'keyup', this.onBlurHandler, 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.onBlurHandler, true );\n\t\t\tthis.getElementDocument().removeEventListener( 'keyup', this.onBlurHandler, 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.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 *     $( '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 *     $( '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
index 03a0d41..ee0b6d2 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOUI v0.27.0
+ * OOUI v0.27.5
  * https://www.mediawiki.org/wiki/OOUI
  *
  * Copyright 2011–2018 OOUI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2018-05-09T00:44:50Z
+ * Date: 2018-07-11T18:13:08Z
  */
 .oo-ui-draggableElement-handle:not( .oo-ui-draggableElement-undraggable ).oo-ui-widget {
   cursor: move;
 }
 .oo-ui-menuLayout > .oo-ui-menuLayout-menu,
 .oo-ui-menuLayout > .oo-ui-menuLayout-content {
-  -webkit-transition: all 200ms ease;
-  -moz-transition: all 200ms ease;
-  transition: all 200ms ease;
+  -webkit-transition: height 200ms ease, width 200ms ease, top 200ms ease, left 200ms ease, right 200ms ease, bottom 200ms ease;
+  -moz-transition: height 200ms ease, width 200ms ease, top 200ms ease, left 200ms ease, right 200ms ease, bottom 200ms ease;
+  transition: height 200ms ease, width 200ms ease, top 200ms ease, left 200ms ease, right 200ms ease, bottom 200ms ease;
 }
 .oo-ui-menuLayout > .oo-ui-menuLayout-menu {
   height: 18em;
 .oo-ui-buttonSelectWidget {
   display: inline-block;
   white-space: nowrap;
-  border-radius: 4px;
+  border-radius: 3px;
   margin-right: 0.5em;
   z-index: 0;
   position: relative;
   margin-left: -1px;
 }
 .oo-ui-buttonSelectWidget .oo-ui-buttonOptionWidget:first-child .oo-ui-buttonElement-button {
-  border-bottom-left-radius: 4px;
-  border-top-left-radius: 4px;
+  border-bottom-left-radius: 3px;
+  border-top-left-radius: 3px;
   margin-left: 0;
 }
 .oo-ui-buttonSelectWidget .oo-ui-buttonOptionWidget:last-child .oo-ui-buttonElement-button {
-  border-bottom-right-radius: 4px;
-  border-top-right-radius: 4px;
+  border-bottom-right-radius: 3px;
+  border-top-right-radius: 3px;
 }
 .oo-ui-buttonSelectWidget.oo-ui-widget-enabled:focus .oo-ui-buttonOptionWidget.oo-ui-optionWidget-selected .oo-ui-buttonElement-button {
   border-color: #ace;
   box-sizing: border-box;
   -webkit-transform: translateZ(0);
   transform: translateZ(0);
-  height: 2em;
+  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%);
   width: 4em;
+  height: 2em;
+  margin-right: 0.5em;
+  border: 1px;
   border-radius: 1em;
   box-shadow: 0 0 0 #fff, inset 0 0.1em 0.2em #ddd;
-  border: 1px solid #ccc;
-  margin-right: 0.5em;
-  background-color: #eeeeee;
-  background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #ddd), color-stop(100%, #fff));
-  background-image: -webkit-linear-gradient(top, #ddd 0, #fff 100%);
-  background-image: -moz-linear-gradient(top, #ddd 0, #fff 100%);
-  background-image: linear-gradient(to bottom, #ddd 0, #fff 100%);
-  -ms-filter: "progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffdddddd', endColorstr='#ffffffff' )";
 }
 .oo-ui-toggleSwitchWidget.oo-ui-widget-enabled {
   cursor: pointer;
   border-color: #ace;
 }
 .oo-ui-toggleSwitchWidget-grip {
+  background-color: #ebebeb;
+  background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #fafafa), color-stop(100%, #ddd));
+  background-image: -webkit-linear-gradient(top, #fafafa 0, #ddd 100%);
+  background-image: -moz-linear-gradient(top, #fafafa 0, #ddd 100%);
+  background-image: linear-gradient(to bottom, #fafafa 0, #ddd 100%);
   top: 0.25em;
   left: 0.25em;
   width: 1.5em;
   height: 1.5em;
   margin-top: -1px;
+  border: 1px solid #ccc;
   border-radius: 1em;
   box-shadow: 0 0.1em 0.25em rgba(0, 0, 0, 0.1);
-  border: 1px #c9c9c9 solid;
   -webkit-transition: left 250ms ease, margin-left 250ms ease;
   -moz-transition: left 250ms ease, margin-left 250ms ease;
   transition: left 250ms ease, margin-left 250ms ease;
-  background-color: #eeeeee;
-  background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #fff), color-stop(100%, #ddd));
-  background-image: -webkit-linear-gradient(top, #fff 0, #ddd 100%);
-  background-image: -moz-linear-gradient(top, #fff 0, #ddd 100%);
-  background-image: linear-gradient(to bottom, #fff 0, #ddd 100%);
-  -ms-filter: "progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffffff', endColorstr='#ffdddddd' )";
 }
 .oo-ui-toggleSwitchWidget-glow {
   position: absolute;
   background-image: -webkit-linear-gradient(top, #b0d9ee 0, #eaf4fa 100%);
   background-image: -moz-linear-gradient(top, #b0d9ee 0, #eaf4fa 100%);
   background-image: linear-gradient(to bottom, #b0d9ee 0, #eaf4fa 100%);
-  -ms-filter: "progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffb0d9ee', endColorstr='#ffeaf4fa' )";
   -webkit-touch-callout: none;
   -webkit-user-select: none;
   -moz-user-select: none;
   margin-right: 0;
 }
 .oo-ui-selectFileWidget-selectButton > .oo-ui-buttonElement-button {
-  border-radius: 0 0.25em 0.25em 0;
+  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 {
 .oo-ui-selectFileWidget-info {
   height: 2.4em;
   background-color: #fff;
-  border: 1px solid rgba(0, 0, 0, 0.1);
-  border-radius: 0.25em 0 0 0.25em;
+  border: 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 {
 .oo-ui-selectFileWidget-dropTarget {
   background-color: #fff;
   border: 1px solid #aaa;
+  border-radius: 3px;
   vertical-align: middle;
-  border-radius: 0.25em;
 }
 .oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-selectButton > .oo-ui-buttonElement-button {
-  border-radius: 0.25em;
+  border-radius: 3px;
 }
 .oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-label {
   line-height: 1.4;
   text-shadow: 0 1px 1px rgba(255, 255, 255, 0.5);
 }
 .oo-ui-outlineControlsWidget {
-  overflow: hidden;
   background-color: #fff;
 }
 .oo-ui-outlineControlsWidget-items,
   -moz-box-sizing: border-box;
   box-sizing: border-box;
 }
-.oo-ui-outlineControlsWidget > .oo-ui-iconElement-icon {
-  float: left;
-  background-position: right center;
-}
 .oo-ui-outlineControlsWidget-items {
   float: left;
 }
   margin: 0 !important;
   /* stylelint-disable-line declaration-no-important */
 }
-.oo-ui-outlineControlsWidget > .oo-ui-iconElement-icon {
-  height: 2.5em;
-  opacity: 0.2;
-}
 .oo-ui-tabSelectWidget {
   text-align: left;
   overflow-x: auto;
   background-color: #eee;
   box-shadow: inset 0 -0.015em 0.1em rgba(0, 0, 0, 0.1);
 }
+.oo-ui-tabSelectWidget.oo-ui-widget-enabled:focus {
+  outline: 0;
+}
 .oo-ui-tabOptionWidget {
   display: inline-block;
   -webkit-box-sizing: border-box;
 .oo-ui-tabOptionWidget.oo-ui-widget-enabled.oo-ui-optionWidget-selected:hover {
   background-color: #fff;
 }
+.oo-ui-tabSelectWidget.oo-ui-widget-enabled:focus .oo-ui-tabOptionWidget.oo-ui-widget-enabled.oo-ui-optionWidget-selected {
+  box-shadow: 0 0 2px 2px #ace;
+}
 .oo-ui-tagMultiselectWidget {
   display: inline-block;
   position: relative;
   margin-right: 0.5em;
   padding: 0.15em 0.25em;
   border: 1px solid rgba(0, 0, 0, 0.1);
-  border-radius: 0.25em;
+  border-radius: 3px;
   -webkit-box-sizing: border-box;
   -moz-box-sizing: border-box;
   box-sizing: border-box;
   display: inline-block;
   cursor: default;
   white-space: nowrap;
+  background-color: #ebebeb;
+  background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #fafafa), color-stop(100%, #ddd));
+  background-image: -webkit-linear-gradient(top, #fafafa 0, #ddd 100%);
+  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;
-  vertical-align: middle;
-  padding: 0 0.4em;
-  margin: 0.1em;
   height: 1.7em;
-  line-height: 1.7em;
-  background-color: #eeeeee;
-  background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #fff), color-stop(100%, #ddd));
-  background-image: -webkit-linear-gradient(top, #fff 0, #ddd 100%);
-  background-image: -moz-linear-gradient(top, #fff 0, #ddd 100%);
-  background-image: linear-gradient(to bottom, #fff 0, #ddd 100%);
-  -ms-filter: "progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffffff', endColorstr='#ffdddddd' )";
+  margin: 0.1em;
   border: 1px solid #ccc;
-  color: #333;
-  border-radius: 0.25em;
+  border-radius: 3px;
+  padding: 0 0.4em;
+  line-height: 1.7em;
+  vertical-align: middle;
 }
 .oo-ui-tagItemWidget.oo-ui-labelElement .oo-ui-labelElement-label {
   display: inline-block;
 }
 .oo-ui-capsuleMultiselectWidget-handle {
   background-color: #fff;
-  cursor: text;
-  min-height: 2.4em;
-  margin-right: 0.5em;
-  padding: 0.15em 0.25em;
-  border: 1px solid rgba(0, 0, 0, 0.1);
-  border-radius: 0.25em;
   -webkit-box-sizing: border-box;
   -moz-box-sizing: border-box;
   box-sizing: border-box;
+  min-height: 2.4em;
+  margin-right: 0.5em;
+  border: #ccc;
+  border-radius: 3px;
+  padding: 0.15em 0.25em;
+  cursor: text;
 }
 .oo-ui-capsuleMultiselectWidget-handle:last-child {
   margin-right: 0;
   margin: 0 0.775em;
 }
 .oo-ui-capsuleMultiselectWidget.oo-ui-widget-enabled:hover .oo-ui-capsuleMultiselectWidget-handle {
-  border-color: rgba(0, 0, 0, 0.2);
+  border-color: #aaa;
 }
 .oo-ui-capsuleMultiselectWidget.oo-ui-widget-enabled.oo-ui-capsuleMultiselectWidget-open .oo-ui-capsuleMultiselectWidget-handle {
   border-color: #ace;
   display: inline-block;
   cursor: default;
   white-space: nowrap;
+  background-color: #ebebeb;
+  background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #fafafa), color-stop(100%, #ddd));
+  background-image: -webkit-linear-gradient(top, #fafafa 0, #ddd 100%);
+  background-image: -moz-linear-gradient(top, #fafafa 0, #ddd 100%);
+  background-image: linear-gradient(to bottom, #fafafa 0, #ddd 100%);
   width: auto;
   max-width: 100%;
   -webkit-box-sizing: border-box;
   margin: 0.1em;
   height: 1.7em;
   line-height: 1.7em;
-  background-color: #eeeeee;
-  background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #fff), color-stop(100%, #ddd));
-  background-image: -webkit-linear-gradient(top, #fff 0, #ddd 100%);
-  background-image: -moz-linear-gradient(top, #fff 0, #ddd 100%);
-  background-image: linear-gradient(to bottom, #fff 0, #ddd 100%);
-  -ms-filter: "progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffffff', endColorstr='#ffdddddd' )";
-  border: 1px solid #ccc;
   color: #333;
-  border-radius: 0.25em;
+  border: 1px solid #ccc;
+  border-radius: 3px;
 }
 .oo-ui-capsuleItemWidget.oo-ui-labelElement .oo-ui-labelElement-label {
   display: inline-block;
index 92b279d..e87e965 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOUI v0.27.0
+ * OOUI v0.27.5
  * https://www.mediawiki.org/wiki/OOUI
  *
  * Copyright 2011–2018 OOUI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2018-05-09T00:44:50Z
+ * Date: 2018-07-11T18:13:08Z
  */
 /**
  * WikimediaUI Base v0.10.0
 }
 .oo-ui-menuLayout > .oo-ui-menuLayout-menu,
 .oo-ui-menuLayout > .oo-ui-menuLayout-content {
-  -webkit-transition: all 200ms ease;
-  -moz-transition: all 200ms ease;
-  transition: all 200ms ease;
+  -webkit-transition: height 200ms ease, width 200ms ease, top 200ms ease, left 200ms ease, right 200ms ease, bottom 200ms ease;
+  -moz-transition: height 200ms ease, width 200ms ease, top 200ms ease, left 200ms ease, right 200ms ease, bottom 200ms ease;
+  transition: height 200ms ease, width 200ms ease, top 200ms ease, left 200ms ease, right 200ms ease, bottom 200ms ease;
 }
 .oo-ui-menuLayout > .oo-ui-menuLayout-menu {
   height: 18em;
   padding-top: 0.57142857em;
   padding-left: 0.57142857em;
   padding-bottom: 0.5em;
-  line-height: 1.07142857em;
   white-space: nowrap;
 }
+.oo-ui-selectFileWidget.oo-ui-labelElement .oo-ui-selectFileWidget-label {
+  line-height: 1.07142857em;
+}
 .oo-ui-selectFileWidget-fileName {
   display: block;
   overflow: hidden;
   border-radius: 2px;
 }
 .oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-label {
-  line-height: 1.4;
   overflow: inherit;
   white-space: normal;
 }
 .oo-ui-selectFileWidget-empty.oo-ui-widget-enabled.oo-ui-selectFileWidget-dropTarget {
   background-color: #fff;
   border-style: dashed;
-  -webkit-transition: background-color 200ms cubic-bezier(0.4, 0.55, 0.55, 1), color 200ms cubic-bezier(0.4, 0.55, 0.55, 1), border-color 200ms cubic-bezier(0.4, 0.55, 0.55, 1);
-  -moz-transition: background-color 200ms cubic-bezier(0.4, 0.55, 0.55, 1), color 200ms cubic-bezier(0.4, 0.55, 0.55, 1), border-color 200ms cubic-bezier(0.4, 0.55, 0.55, 1);
-  transition: background-color 200ms cubic-bezier(0.4, 0.55, 0.55, 1), color 200ms cubic-bezier(0.4, 0.55, 0.55, 1), border-color 200ms cubic-bezier(0.4, 0.55, 0.55, 1);
+  -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 {
   border-color: #72777d;
   left: 4.429em;
 }
 .oo-ui-outlineControlsWidget {
-  overflow: hidden;
   background-color: #fff;
 }
 .oo-ui-outlineControlsWidget-items,
   -moz-box-sizing: border-box;
   box-sizing: border-box;
 }
-.oo-ui-outlineControlsWidget > .oo-ui-iconElement-icon {
-  float: left;
-  background-position: right center;
-}
 .oo-ui-outlineControlsWidget-items {
   float: left;
 }
   margin: 0 !important;
   /* stylelint-disable-line declaration-no-important */
 }
-.oo-ui-outlineControlsWidget > .oo-ui-iconElement-icon {
-  height: 2.28571429em;
-  opacity: 0.2;
-}
 .oo-ui-tabSelectWidget {
   text-align: left;
   overflow-x: auto;
   overflow-y: hidden;
   background-color: #eaecf0;
 }
+.oo-ui-tabSelectWidget.oo-ui-widget-enabled:focus {
+  outline: 0;
+}
 .oo-ui-tabOptionWidget {
   display: inline-block;
   -webkit-box-sizing: border-box;
   border-width: 1px 1px 0 1px;
   border-top-left-radius: 2px;
   border-top-right-radius: 2px;
-  padding: 0.57142857em 0.92857143em 0.5em;
+  padding: 0 0.57142857em;
   font-weight: bold;
   line-height: 1;
-  -webkit-transition: background-color 100ms, color 100ms;
-  -moz-transition: background-color 100ms, color 100ms;
-  transition: background-color 100ms, color 100ms;
+  -webkit-transition: background-color 100ms, color 100ms, border-color 100ms;
+  -moz-transition: background-color 100ms, color 100ms, border-color 100ms;
+  transition: background-color 100ms, color 100ms, border-color 100ms;
 }
 .oo-ui-tabOptionWidget.oo-ui-optionWidget-selected {
   background-color: #fff;
   color: #000;
 }
+.oo-ui-tabOptionWidget.oo-ui-optionWidget-selected .oo-ui-labelElement-label {
+  border-bottom-color: #fff;
+}
 .oo-ui-tabOptionWidget .oo-ui-labelElement-label {
+  border-bottom: 2px solid transparent;
+  padding: 0.57142857em 0.35714286em 0.35714286em;
   line-height: 1.07142857em;
+  -webkit-transition: border-color 100ms;
+  -moz-transition: border-color 100ms;
+  transition: border-color 100ms;
 }
 .oo-ui-tabOptionWidget.oo-ui-widget-enabled:hover {
   background-color: rgba(255, 255, 255, 0.3);
 .oo-ui-tabOptionWidget.oo-ui-widget-enabled.oo-ui-optionWidget-selected:hover {
   background-color: #fff;
 }
+.oo-ui-tabSelectWidget.oo-ui-widget-enabled:focus .oo-ui-tabOptionWidget.oo-ui-widget-enabled.oo-ui-optionWidget-selected .oo-ui-labelElement-label {
+  border-bottom-color: #36c;
+}
 .oo-ui-tagMultiselectWidget {
   display: inline-block;
   position: relative;
   width: 100%;
   max-width: 50em;
+  vertical-align: top;
 }
 .oo-ui-tagMultiselectWidget-handle {
   width: 100%;
   margin-right: 0.5em;
   border: 1px solid #a2a9b1;
   border-radius: 2px;
-  padding: 0 0.57142857em 0.28571429em;
+  padding: 0 0.57142857em;
   line-height: 1;
 }
 .oo-ui-tagMultiselectWidget-handle:last-child {
 .oo-ui-tagMultiselectWidget-handle > .oo-ui-tagMultiselectWidget-content > input {
   background-color: transparent;
   color: #000;
-  margin: 0.42857143em 0 0 0.35714286em;
   border: 0;
-  padding: 0;
+  padding: 0.57142857em 0 0.5em 0.35714286em;
   font-family: inherit;
   font-size: inherit;
-  line-height: 1.42857143em;
-  vertical-align: middle;
+  line-height: 1.07142857em;
+  vertical-align: top;
 }
 .oo-ui-tagMultiselectWidget-handle > .oo-ui-tagMultiselectWidget-content > input::-webkit-input-placeholder {
   color: #72777d;
 .oo-ui-tagMultiselectWidget-handle > .oo-ui-tagMultiselectWidget-content .oo-ui-tagMultiselectWidget-group:empty + input {
   margin-left: 0;
 }
+.oo-ui-tagMultiselectWidget-handle .oo-ui-tagMultiselectWidget-group {
+  display: inline-block;
+  max-width: 100%;
+  margin-top: 0.28571429em;
+  margin-left: -0.14285714em;
+}
 .oo-ui-tagMultiselectWidget.oo-ui-iconElement .oo-ui-tagMultiselectWidget-handle {
   padding-left: 2.02857143em;
 }
 }
 .oo-ui-tagMultiselectWidget.oo-ui-widget-enabled .oo-ui-tagMultiselectWidget-handle {
   background-color: #fff;
-  -webkit-transition: border-color 200ms cubic-bezier(0.4, 0.55, 0.55, 1), box-shadow 200ms cubic-bezier(0.4, 0.55, 0.55, 1);
-  -moz-transition: border-color 200ms cubic-bezier(0.4, 0.55, 0.55, 1), box-shadow 200ms cubic-bezier(0.4, 0.55, 0.55, 1);
-  transition: border-color 200ms cubic-bezier(0.4, 0.55, 0.55, 1), box-shadow 200ms cubic-bezier(0.4, 0.55, 0.55, 1);
+  -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-tagMultiselectWidget.oo-ui-widget-enabled.oo-ui-tagMultiselectWidget-inlined:hover .oo-ui-tagMultiselectWidget-handle {
   border-color: #72777d;
   width: auto;
   max-width: 100%;
   height: 1.57142857em;
-  margin: 0.28571429em 0.28571429em 0 0;
+  margin: 0 0.28571429em 0.28571429em 0;
   border: 1px solid #a2a9b1;
-  border-radius: 2px;
-  padding: 0 0.28571429em;
+  border-radius: 1.57142857em;
+  padding: 0 0.42857143em;
   line-height: 1.57142857em;
   vertical-align: middle;
 }
 }
 .oo-ui-tagItemWidget.oo-ui-widget-enabled:not( .oo-ui-tagItemWidget-fixed ) {
   background-color: #f8f9fa;
-  padding-right: 1.5em;
+  padding-right: 1.64285714em;
 }
 .oo-ui-tagItemWidget.oo-ui-widget-enabled.oo-ui-flaggedElement-invalid {
   border-color: #d33;
   border-color: #d33;
   box-shadow: inset 0 0 0 1px #d33;
 }
-.oo-ui-tagItemWidget.oo-ui-widget-enabled > .oo-ui-labelElement-label {
-  margin-top: -1px;
-}
 .oo-ui-tagItemWidget.oo-ui-widget-enabled > .oo-ui-buttonElement {
   display: block;
   position: absolute;
 }
 .oo-ui-tagItemWidget.oo-ui-widget-enabled .oo-ui-buttonElement-button {
   border: 0;
+  border-radius: 1.57142857em;
   padding-top: 1.42857143em;
   padding-left: 1.42857143em;
+  -webkit-transition: background-color 100ms;
+  -moz-transition: background-color 100ms;
+  transition: background-color 100ms;
+}
+.oo-ui-tagItemWidget.oo-ui-widget-enabled .oo-ui-buttonElement-button:hover {
+  background-color: #fff;
+}
+.oo-ui-tagItemWidget.oo-ui-widget-enabled .oo-ui-buttonElement-button:active {
+  background-color: #c8ccd1;
 }
 .oo-ui-tagItemWidget.oo-ui-widget-enabled .oo-ui-buttonElement-button .oo-ui-icon-close {
   left: 0.28571429em;
-  min-width: 14px;
-  width: 1em;
+  min-width: 12px;
+  width: 0.85714286em;
 }
 .oo-ui-tagItemWidget.oo-ui-widget-enabled .oo-ui-buttonElement-button .oo-ui-labelElement-label,
 .oo-ui-tagItemWidget.oo-ui-widget-enabled .oo-ui-buttonElement-button .oo-ui-indicatorElement-indicator {
   position: relative;
   width: 100%;
   max-width: 50em;
+  vertical-align: top;
 }
 .oo-ui-capsuleMultiselectWidget-handle {
   width: 100%;
   margin-right: 0.5em;
   border: 1px solid #a2a9b1;
   border-radius: 2px;
-  padding: 0 0.57142857em 0.28571429em;
+  padding: 0 0.57142857em;
   line-height: 1;
 }
 .oo-ui-capsuleMultiselectWidget-handle:last-child {
   background-color: transparent;
   color: #000;
   border: 0;
-  margin: 0.42857143em 0 0 0.35714286em;
-  padding: 0;
+  padding: 0.57142857em 0 0.5em;
   font-family: inherit;
   font-size: inherit;
-  line-height: 1.42857143em;
-  vertical-align: middle;
+  line-height: 1.07142857em;
+  vertical-align: top;
 }
 .oo-ui-capsuleMultiselectWidget-handle > .oo-ui-capsuleMultiselectWidget-content > input::-webkit-input-placeholder {
   color: #72777d;
 .oo-ui-capsuleMultiselectWidget-handle > .oo-ui-capsuleMultiselectWidget-content .oo-ui-capsuleMultiselectWidget-group:empty + input {
   margin-left: 0;
 }
+.oo-ui-capsuleMultiselectWidget-handle .oo-ui-capsuleMultiselectWidget-group {
+  display: inline-block;
+  max-width: 100%;
+  margin-top: 0.28571429em;
+  margin-left: -0.14285714em;
+}
 .oo-ui-capsuleMultiselectWidget.oo-ui-iconElement .oo-ui-capsuleMultiselectWidget-handle {
   padding-left: 2.64285714em;
 }
 .oo-ui-capsuleMultiselectWidget.oo-ui-widget-enabled .oo-ui-capsuleMultiselectWidget-handle {
   background-color: #fff;
   cursor: text;
-  -webkit-transition: border-color 200ms cubic-bezier(0.4, 0.55, 0.55, 1), box-shadow 200ms cubic-bezier(0.4, 0.55, 0.55, 1);
-  -moz-transition: border-color 200ms cubic-bezier(0.4, 0.55, 0.55, 1), box-shadow 200ms cubic-bezier(0.4, 0.55, 0.55, 1);
-  transition: border-color 200ms cubic-bezier(0.4, 0.55, 0.55, 1), box-shadow 200ms cubic-bezier(0.4, 0.55, 0.55, 1);
+  -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-capsuleMultiselectWidget.oo-ui-widget-enabled:hover .oo-ui-capsuleMultiselectWidget-handle {
   border-color: #72777d;
   width: auto;
   max-width: 100%;
   height: 1.57142857em;
-  margin: 0.28571429em 0.28571429em 0 0;
+  margin: 0 0.28571429em 0.28571429em 0;
   border: 1px solid #a2a9b1;
-  border-radius: 2px;
-  padding: 0 0.28571429em;
+  border-radius: 1.57142857em;
+  padding: 0 0.42857143em;
   line-height: 1.57142857em;
   vertical-align: middle;
 }
 .oo-ui-capsuleItemWidget.oo-ui-widget-enabled {
   background-color: #f8f9fa;
   color: #222;
-  padding-right: 1.5em;
+  padding-right: 1.64285714em;
   -webkit-transition: background-color 100ms, color 100ms, border-color 100ms, box-shadow 100ms;
   -moz-transition: background-color 100ms, color 100ms, border-color 100ms, box-shadow 100ms;
   transition: background-color 100ms, color 100ms, border-color 100ms, box-shadow 100ms;
   box-shadow: inset 0 0 0 1px #36c;
   outline: 0;
 }
-.oo-ui-capsuleItemWidget.oo-ui-widget-enabled > .oo-ui-labelElement-label {
-  margin-top: -1px;
-}
 .oo-ui-capsuleItemWidget.oo-ui-widget-enabled > .oo-ui-buttonElement {
   display: block;
   position: absolute;
 }
 .oo-ui-capsuleItemWidget.oo-ui-widget-enabled .oo-ui-buttonElement-button {
   border: 0;
+  border-radius: 1.57142857em;
   padding-top: 1.42857143em;
   padding-left: 1.42857143em;
+  -webkit-transition: background-color 100ms;
+  -moz-transition: background-color 100ms;
+  transition: background-color 100ms;
+}
+.oo-ui-capsuleItemWidget.oo-ui-widget-enabled .oo-ui-buttonElement-button:hover {
+  background-color: #fff;
+}
+.oo-ui-capsuleItemWidget.oo-ui-widget-enabled .oo-ui-buttonElement-button:active {
+  background-color: #c8ccd1;
 }
 .oo-ui-capsuleItemWidget.oo-ui-widget-enabled .oo-ui-buttonElement-button .oo-ui-icon-close {
   left: 0.28571429em;
-  min-width: 14px;
-  width: 1em;
+  min-width: 12px;
+  width: 0.85714286em;
 }
 .oo-ui-capsuleItemWidget.oo-ui-widget-enabled .oo-ui-buttonElement-button .oo-ui-labelElement-label,
 .oo-ui-capsuleItemWidget.oo-ui-widget-enabled .oo-ui-buttonElement-button .oo-ui-indicatorElement-indicator {
index 5b0b64a..fd4739f 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOUI v0.27.0
+ * OOUI v0.27.5
  * https://www.mediawiki.org/wiki/OOUI
  *
  * Copyright 2011–2018 OOUI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2018-05-09T00:44:45Z
+ * Date: 2018-07-11T18:13:04Z
  */
 ( function ( OO ) {
 
@@ -631,6 +631,7 @@ OO.ui.mixin.RequestManager.prototype.getRequestCacheDataFromResponse = null;
  * @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.
  *  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
@@ -645,11 +646,11 @@ OO.ui.mixin.LookupElement = function OoUiMixinLookupElement( config ) {
 
        // Properties
        this.$overlay = ( config.$overlay === true ? OO.ui.getDefaultOverlay() : config.$overlay ) || this.$element;
-       this.lookupMenu = new OO.ui.MenuSelectWidget( {
+       this.lookupMenu = new OO.ui.MenuSelectWidget( $.extend( {
                widget: this,
                input: this,
                $floatableContainer: config.$container || this.$element
-       } );
+       }, config.menu ) );
 
        this.allowSuggestionsWhenEmpty = config.allowSuggestionsWhenEmpty || false;
 
@@ -1002,7 +1003,9 @@ OO.ui.TabPanelLayout = function OoUiTabPanelLayout( name, config ) {
        this.active = false;
 
        // Initialization
-       this.$element.addClass( 'oo-ui-tabPanelLayout' );
+       this.$element
+               .addClass( 'oo-ui-tabPanelLayout' )
+               .attr( 'role', 'tabpanel' );
 };
 
 /* Setup */
@@ -1084,6 +1087,10 @@ OO.ui.TabPanelLayout.prototype.setTabItem = function ( tabItem ) {
  * @chainable
  */
 OO.ui.TabPanelLayout.prototype.setupTabItem = function () {
+       this.$element.attr( 'aria-labelledby', this.tabItem.getElementId() );
+
+       this.tabItem.$element.attr( 'aria-controls', this.getElementId() );
+
        if ( this.label ) {
                this.tabItem.setLabel( this.label );
        }
@@ -1893,8 +1900,9 @@ OO.ui.BookletLayout.prototype.onStackLayoutSet = function ( page ) {
        } else {
                promise = $.Deferred().resolve();
        }
-       // Focus the first element on the newly selected panel
-       if ( this.autoFocus && !OO.ui.isMobile() ) {
+       // Focus the first element on the newly selected panel.
+       // Don't focus if the page was set by scrolling.
+       if ( this.autoFocus && !OO.ui.isMobile() && !this.scrolling ) {
                promise.done( function () {
                        layout.focus();
                } );
@@ -3032,7 +3040,6 @@ OO.ui.ToggleSwitchWidget.prototype.simulateLabelClick = function () {
  * @class
  * @extends OO.ui.Widget
  * @mixins OO.ui.mixin.GroupElement
- * @mixins OO.ui.mixin.IconElement
  *
  * @constructor
  * @param {OO.ui.OutlineSelectWidget} outline Outline to control
@@ -3049,14 +3056,13 @@ OO.ui.OutlineControlsWidget = function OoUiOutlineControlsWidget( outline, confi
        }
 
        // Configuration initialization
-       config = $.extend( { icon: 'add' }, config );
+       config = config || {};
 
        // Parent constructor
        OO.ui.OutlineControlsWidget.parent.call( this, config );
 
        // Mixin constructors
        OO.ui.mixin.GroupElement.call( this, config );
-       OO.ui.mixin.IconElement.call( this, config );
 
        // Properties
        this.outline = outline;
@@ -3102,7 +3108,6 @@ OO.ui.OutlineControlsWidget = function OoUiOutlineControlsWidget( outline, confi
 
 OO.inheritClass( OO.ui.OutlineControlsWidget, OO.ui.Widget );
 OO.mixinClass( OO.ui.OutlineControlsWidget, OO.ui.mixin.GroupElement );
-OO.mixinClass( OO.ui.OutlineControlsWidget, OO.ui.mixin.IconElement );
 
 /* Events */
 
@@ -3530,7 +3535,9 @@ OO.ui.TabOptionWidget = function OoUiTabOptionWidget( config ) {
        OO.ui.TabOptionWidget.parent.call( this, config );
 
        // Initialization
-       this.$element.addClass( 'oo-ui-tabOptionWidget' );
+       this.$element
+               .addClass( 'oo-ui-tabOptionWidget' )
+               .attr( 'role', 'tab' );
 };
 
 /* Setup */
@@ -3571,7 +3578,9 @@ OO.ui.TabSelectWidget = function OoUiTabSelectWidget( config ) {
        } );
 
        // Initialization
-       this.$element.addClass( 'oo-ui-tabSelectWidget' );
+       this.$element
+               .addClass( 'oo-ui-tabSelectWidget' )
+               .attr( 'role', 'tablist' );
 };
 
 /* Setup */
@@ -3592,6 +3601,7 @@ OO.mixinClass( OO.ui.TabSelectWidget, OO.ui.mixin.TabIndexedElement );
  *
  * @constructor
  * @param {Object} [config] Configuration options
+ * @deprecated
  */
 OO.ui.CapsuleItemWidget = function OoUiCapsuleItemWidget( config ) {
        // Configuration initialization
@@ -3750,6 +3760,7 @@ OO.ui.CapsuleItemWidget.prototype.onKeyDown = function ( e ) {
  *  the containing `<div>` and has a larger area. By default, the menu uses
  *  relative positioning.
  *  See <https://www.mediawiki.org/wiki/OOUI/Concepts#Overlays>.
+ * @deprecated
  */
 OO.ui.CapsuleMultiselectWidget = function OoUiCapsuleMultiselectWidget( config ) {
        var $tabFocus;
@@ -3877,6 +3888,9 @@ OO.ui.CapsuleMultiselectWidget = function OoUiCapsuleMultiselectWidget( config )
        }.bind( this ) );
 
        this.onMenuItemsChange();
+
+       // Deprecation warning
+       OO.ui.warnDeprecation( 'CapsuleMultiselectWidget: Deprecated widget. Use TagMultiselectWidget instead. See T183299.' );
 };
 
 /* Setup */
@@ -4682,7 +4696,7 @@ OO.ui.TagItemWidget.prototype.setDisabled = function ( state ) {
  * @fires remove
  */
 OO.ui.TagItemWidget.prototype.remove = function () {
-       if ( !this.isDisabled() ) {
+       if ( !this.isDisabled() && !this.isFixed() ) {
                this.emit( 'remove' );
        }
 };
@@ -5127,7 +5141,7 @@ OO.ui.TagMultiselectWidget.prototype.doInputBackspace = function ( e, withMetaKe
                items = this.getItems();
                item = items[ items.length - 1 ];
 
-               if ( !item.isDisabled() ) {
+               if ( !item.isDisabled() && !item.isFixed() ) {
                        this.removeItems( [ item ] );
                        // If Ctrl/Cmd was pressed, delete item entirely.
                        // Otherwise put it into the text field for editing.
@@ -5786,7 +5800,7 @@ OO.ui.PopupTagMultiselectWidget.prototype.addTagByPopupValue = function ( data,
  *     var widget = new OO.ui.MenuTagMultiselectWidget( {
  *         inputPosition: 'outline',
  *         options: [
- *            { data: 'option1', label: 'Option 1' },
+ *            { data: 'option1', label: 'Option 1', icon: 'tag' },
  *            { data: 'option2', label: 'Option 2' },
  *            { data: 'option3', label: 'Option 3' },
  *         ],
@@ -6012,7 +6026,7 @@ OO.ui.MenuTagMultiselectWidget.prototype.createMenuWidget = function ( menuConfi
 OO.ui.MenuTagMultiselectWidget.prototype.addOptions = function ( menuOptions ) {
        var widget = this,
                items = menuOptions.map( function ( obj ) {
-                       return widget.createMenuOptionWidget( obj.data, obj.label );
+                       return widget.createMenuOptionWidget( obj.data, obj.label, obj.icon );
                } );
 
        this.menu.addItems( items );
@@ -6023,12 +6037,14 @@ OO.ui.MenuTagMultiselectWidget.prototype.addOptions = function ( menuOptions ) {
  *
  * @param {string} data Item data
  * @param {string} [label] Item label
+ * @param {string} [icon] Symbolic icon name
  * @return {OO.ui.OptionWidget} Option widget
  */
-OO.ui.MenuTagMultiselectWidget.prototype.createMenuOptionWidget = function ( data, label ) {
+OO.ui.MenuTagMultiselectWidget.prototype.createMenuOptionWidget = function ( data, label, icon ) {
        return new OO.ui.MenuOptionWidget( {
                data: data,
-               label: label || data
+               label: label || data,
+               icon: icon
        } );
 };
 
@@ -6712,4 +6728,4 @@ OO.ui.SearchWidget.prototype.getResults = function () {
 
 }( OO ) );
 
-//# sourceMappingURL=oojs-ui-widgets.js.map
\ No newline at end of file
+//# sourceMappingURL=oojs-ui-widgets.js.map.json
\ No newline at end of file
diff --git a/resources/lib/oojs-ui/oojs-ui-widgets.js.map b/resources/lib/oojs-ui/oojs-ui-widgets.js.map
deleted file mode 100644 (file)
index 20eb859..0000000
+++ /dev/null
@@ -1 +0,0 @@
-{"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/CapsuleItemWidget.js","../src/widgets/CapsuleMultiselectWidget.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 */\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 {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( {\n\t\twidget: this,\n\t\tinput: this,\n\t\t$floatableContainer: config.$container || this.$element\n\t} );\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 */\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 */\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 */\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} );\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 */\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.addClass( 'oo-ui-tabPanelLayout' );\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 */\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 */\nOO.ui.TabPanelLayout.prototype.setupTabItem = function () {\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 */\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 */\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 continously\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 *     $( '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\tconfig = $.extend( { scrollable: true }, 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 */\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 * @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 * @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 * @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 * 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 = new OO.ui.MenuLayout( {\n *         position: 'top'\n *     } ),\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.$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 *     $( '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 *         height: 200px;\n *         width: 200px;\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 {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.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\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 */\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 */\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 * 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 *     $( '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.$content.append( this.stackLayout.$element );\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.$menu.append( this.outlinePanel.$element );\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\tif ( this.autoFocus && !OO.ui.isMobile() ) {\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 */\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}, 200 );\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 */\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 */\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 */\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 * Select the first selectable page.\n *\n * @chainable\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 *     $( '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.$content.append( this.stackLayout.$element );\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.$menu.append( this.tabPanel.$element );\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 */\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 */\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 */\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\ttabPanel = this.tabPanels[ name ],\n\t\tpreviousTabPanel = this.currentTabPanelName && this.tabPanels[ this.currentTabPanelName ];\n\n\tif ( name !== this.currentTabPanelName ) {\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 */\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 *\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// 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 );\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 */\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 *     var toggleButton2 = new OO.ui.ToggleButtonWidget( {\n *         label: 'Toggle Button on',\n *         value: true\n *     } );\n *     // Append the buttons to the DOM.\n *     $( '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.TitledElement\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.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\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};\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.TitledElement );\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 *     var toggleSwitch2 = new OO.ui.ToggleSwitchWidget( {\n *         value: true\n *     } );\n *\n *     // Create a FieldsetLayout to layout and label switches\n *     var fieldset = new OO.ui.FieldsetLayout( {\n *        label: 'Toggle switches'\n *     } );\n *     fieldset.addItems( [\n *         new OO.ui.FieldLayout( toggleSwitch1, { label: 'Off', align: 'top' } ),\n *         new OO.ui.FieldLayout( toggleSwitch2, { label: 'On', align: 'top' } )\n *     ] );\n *     $( '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 */\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 */\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 * @mixins OO.ui.mixin.IconElement\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 = $.extend( { icon: 'add' }, 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\tOO.ui.mixin.IconElement.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 );\nOO.mixinClass( OO.ui.OutlineControlsWidget, OO.ui.mixin.IconElement );\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 */\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 */\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 */\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.bindKeyDownListener.bind( this ),\n\t\tblur: this.unbindKeyDownListener.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 * @mixins OO.ui.mixin.TitledElement\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\tOO.ui.mixin.TitledElement.call( this, $.extend( {}, config, { $titled: this.$button } ) );\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};\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 );\nOO.mixinClass( OO.ui.ButtonOptionWidget, OO.ui.mixin.TitledElement );\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 *     // Example: 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 *\n *     var option2 = new OO.ui.ButtonOptionWidget( {\n *         data: 2,\n *         label: 'Option 2',\n *         title: 'Button option 2'\n *     } );\n *\n *     var option3 = new OO.ui.ButtonOptionWidget( {\n *         data: 3,\n *         label: 'Option 3',\n *         title: 'Button option 3'\n *     } );\n *\n *     var buttonSelect=new OO.ui.ButtonSelectWidget( {\n *         items: [ option1, option2, option3 ]\n *     } );\n *     $( '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.bindKeyDownListener.bind( this ),\n\t\tblur: this.unbindKeyDownListener.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.addClass( 'oo-ui-tabOptionWidget' );\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.bindKeyDownListener.bind( this ),\n\t\tblur: this.unbindKeyDownListener.bind( this )\n\t} );\n\n\t// Initialization\n\tthis.$element.addClass( 'oo-ui-tabSelectWidget' );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.TabSelectWidget, OO.ui.SelectWidget );\nOO.mixinClass( OO.ui.TabSelectWidget, OO.ui.mixin.TabIndexedElement );\n","/**\n * CapsuleItemWidgets are used within a {@link OO.ui.CapsuleMultiselectWidget\n * CapsuleMultiselectWidget} 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 *\n * @constructor\n * @param {Object} [config] Configuration options\n */\nOO.ui.CapsuleItemWidget = function OoUiCapsuleItemWidget( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.CapsuleItemWidget.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\n\t// Events\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} ).on( 'click', this.onCloseClick.bind( this ) );\n\n\tthis.on( 'disable', function ( disabled ) {\n\t\tthis.closeButton.setDisabled( disabled );\n\t}.bind( this ) );\n\n\t// Initialization\n\tthis.$element\n\t\t.on( {\n\t\t\tclick: this.onClick.bind( this ),\n\t\t\tkeydown: this.onKeyDown.bind( this )\n\t\t} )\n\t\t.addClass( 'oo-ui-capsuleItemWidget' )\n\t\t.append( this.$label, this.closeButton.$element );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.CapsuleItemWidget, OO.ui.Widget );\nOO.mixinClass( OO.ui.CapsuleItemWidget, OO.ui.mixin.ItemWidget );\nOO.mixinClass( OO.ui.CapsuleItemWidget, OO.ui.mixin.LabelElement );\nOO.mixinClass( OO.ui.CapsuleItemWidget, OO.ui.mixin.FlaggedElement );\nOO.mixinClass( OO.ui.CapsuleItemWidget, OO.ui.mixin.TabIndexedElement );\n\n/* Methods */\n\n/**\n * Handle close icon clicks\n */\nOO.ui.CapsuleItemWidget.prototype.onCloseClick = function () {\n\tvar element = this.getElementGroup();\n\n\tif ( element && $.isFunction( element.removeItems ) ) {\n\t\telement.removeItems( [ this ] );\n\t\telement.focus();\n\t}\n};\n\n/**\n * Handle click event for the entire capsule\n */\nOO.ui.CapsuleItemWidget.prototype.onClick = function () {\n\tvar element = this.getElementGroup();\n\n\tif ( !this.isDisabled() && element && $.isFunction( element.editItem ) ) {\n\t\telement.editItem( this );\n\t}\n};\n\n/**\n * Handle keyDown event for the entire capsule\n *\n * @param {jQuery.Event} e Key down event\n */\nOO.ui.CapsuleItemWidget.prototype.onKeyDown = function ( e ) {\n\tvar element = this.getElementGroup();\n\n\tif ( e.keyCode === OO.ui.Keys.BACKSPACE || e.keyCode === OO.ui.Keys.DELETE ) {\n\t\telement.removeItems( [ this ] );\n\t\telement.focus();\n\t\treturn false;\n\t} else if ( e.keyCode === OO.ui.Keys.ENTER ) {\n\t\telement.editItem( this );\n\t\treturn false;\n\t} else if ( e.keyCode === OO.ui.Keys.LEFT ) {\n\t\telement.getPreviousItem( this ).focus();\n\t} else if ( e.keyCode === OO.ui.Keys.RIGHT ) {\n\t\telement.getNextItem( this ).focus();\n\t}\n};\n","/**\n * CapsuleMultiselectWidgets are something like a {@link OO.ui.ComboBoxInputWidget combo box widget}\n * that allows for selecting multiple values.\n *\n * For more information about menus and options, please see the [OOUI documentation on MediaWiki][1].\n *\n *     @example\n *     // Example: A CapsuleMultiselectWidget.\n *     var capsule = new OO.ui.CapsuleMultiselectWidget( {\n *         label: 'CapsuleMultiselectWidget',\n *         selected: [ 'Option 1', 'Option 3' ],\n *         menu: {\n *             items: [\n *                 new OO.ui.MenuOptionWidget( {\n *                     data: 'Option 1',\n *                     label: 'Option One'\n *                 } ),\n *                 new OO.ui.MenuOptionWidget( {\n *                     data: 'Option 2',\n *                     label: 'Option Two'\n *                 } ),\n *                 new OO.ui.MenuOptionWidget( {\n *                     data: 'Option 3',\n *                     label: 'Option Three'\n *                 } ),\n *                 new OO.ui.MenuOptionWidget( {\n *                     data: 'Option 4',\n *                     label: 'Option Four'\n *                 } ),\n *                 new OO.ui.MenuOptionWidget( {\n *                     data: 'Option 5',\n *                     label: 'Option Five'\n *                 } )\n *             ]\n *         }\n *     } );\n *     $( 'body' ).append( capsule.$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.Widget\n * @mixins OO.ui.mixin.GroupElement\n * @mixins OO.ui.mixin.PopupElement\n * @mixins OO.ui.mixin.TabIndexedElement\n * @mixins OO.ui.mixin.IndicatorElement\n * @mixins OO.ui.mixin.IconElement\n * @uses OO.ui.CapsuleItemWidget\n * @uses OO.ui.MenuSelectWidget\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {string} [placeholder] Placeholder text\n * @cfg {boolean} [allowArbitrary=false] Allow data items to be added even if not present in the menu.\n * @cfg {boolean} [allowDuplicates=false] Allow duplicate items to be added.\n * @cfg {Object} [menu] (required) Configuration options to pass to the\n *  {@link OO.ui.MenuSelectWidget menu select widget}.\n * @cfg {Object} [popup] Configuration options to pass to the {@link OO.ui.PopupWidget popup widget}.\n *  If specified, this popup will be shown instead of the menu (but the menu\n *  will still be used for item labels and allowArbitrary=false). The widgets\n *  in the popup should use {@link #addItemsFromData} or {@link #addItems} as necessary.\n * @cfg {jQuery} [$overlay=this.$element] Render the menu or popup into a separate layer.\n *  This configuration is useful in cases where the expanded menu is larger than\n *  its containing `<div>`. The specified overlay layer is usually on top of\n *  the containing `<div>` and has a larger area. By default, the menu uses\n *  relative positioning.\n *  See <https://www.mediawiki.org/wiki/OOUI/Concepts#Overlays>.\n */\nOO.ui.CapsuleMultiselectWidget = function OoUiCapsuleMultiselectWidget( config ) {\n\tvar $tabFocus;\n\n\t// Parent constructor\n\tOO.ui.CapsuleMultiselectWidget.parent.call( this, config );\n\n\t// Configuration initialization\n\tconfig = $.extend( {\n\t\tallowArbitrary: false,\n\t\tallowDuplicates: false\n\t}, config );\n\n\t// Properties (must be set before mixin constructor calls)\n\tthis.$handle = $( '<div>' );\n\tthis.$input = config.popup ? null : $( '<input>' );\n\tif ( config.placeholder !== undefined && config.placeholder !== '' ) {\n\t\tthis.$input.attr( 'placeholder', config.placeholder );\n\t}\n\n\t// Mixin constructors\n\tOO.ui.mixin.GroupElement.call( this, config );\n\tif ( config.popup ) {\n\t\tconfig.popup = $.extend( {}, config.popup, {\n\t\t\talign: 'forwards',\n\t\t\tanchor: false\n\t\t} );\n\t\tOO.ui.mixin.PopupElement.call( this, config );\n\t\t$tabFocus = $( '<span>' );\n\t\tOO.ui.mixin.TabIndexedElement.call( this, $.extend( {}, config, { $tabIndexed: $tabFocus } ) );\n\t} else {\n\t\tthis.popup = null;\n\t\t$tabFocus = null;\n\t\tOO.ui.mixin.TabIndexedElement.call( this, $.extend( {}, config, { $tabIndexed: this.$input } ) );\n\t}\n\tOO.ui.mixin.IndicatorElement.call( this, config );\n\tOO.ui.mixin.IconElement.call( this, config );\n\n\t// Properties\n\tthis.$content = $( '<div>' );\n\tthis.allowArbitrary = config.allowArbitrary;\n\tthis.allowDuplicates = config.allowDuplicates;\n\tthis.$overlay = ( config.$overlay === true ? OO.ui.getDefaultOverlay() : config.$overlay ) || this.$element;\n\tthis.menu = new OO.ui.MenuSelectWidget( $.extend(\n\t\t{\n\t\t\twidget: this,\n\t\t\t$input: this.$input,\n\t\t\t$floatableContainer: this.$element,\n\t\t\tfilterFromInput: true,\n\t\t\tdisabled: this.isDisabled()\n\t\t},\n\t\tconfig.menu\n\t) );\n\n\t// Events\n\tif ( this.popup ) {\n\t\t$tabFocus.on( {\n\t\t\tfocus: this.focus.bind( this )\n\t\t} );\n\t\tthis.popup.$element.on( 'focusout', this.onPopupFocusOut.bind( this ) );\n\t\tif ( this.popup.$autoCloseIgnore ) {\n\t\t\tthis.popup.$autoCloseIgnore.on( 'focusout', this.onPopupFocusOut.bind( this ) );\n\t\t}\n\t\tthis.popup.connect( this, {\n\t\t\ttoggle: function ( visible ) {\n\t\t\t\t$tabFocus.toggle( !visible );\n\t\t\t}\n\t\t} );\n\t} else {\n\t\tthis.$input.on( {\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.onKeyDown.bind( this ),\n\t\t\tkeypress: this.onKeyPress.bind( this )\n\t\t} );\n\t}\n\tthis.menu.connect( this, {\n\t\tchoose: 'onMenuChoose',\n\t\ttoggle: 'onMenuToggle',\n\t\tadd: 'onMenuItemsChange',\n\t\tremove: 'onMenuItemsChange'\n\t} );\n\tthis.$handle.on( {\n\t\tmousedown: this.onMouseDown.bind( this )\n\t} );\n\n\t// Initialization\n\tif ( this.$input ) {\n\t\tthis.$input.prop( 'disabled', this.isDisabled() );\n\t\tthis.$input.attr( {\n\t\t\trole: 'combobox',\n\t\t\t'aria-owns': this.menu.getElementId(),\n\t\t\t'aria-autocomplete': 'list'\n\t\t} );\n\t}\n\tif ( config.data ) {\n\t\tthis.setItemsFromData( config.data );\n\t}\n\tthis.$content.addClass( 'oo-ui-capsuleMultiselectWidget-content' )\n\t\t.append( this.$group );\n\tthis.$group.addClass( 'oo-ui-capsuleMultiselectWidget-group' );\n\tthis.$handle.addClass( 'oo-ui-capsuleMultiselectWidget-handle' )\n\t\t.append( this.$indicator, this.$icon, this.$content );\n\tthis.$element.addClass( 'oo-ui-capsuleMultiselectWidget' )\n\t\t.append( this.$handle );\n\tif ( this.popup ) {\n\t\tthis.popup.$element.addClass( 'oo-ui-capsuleMultiselectWidget-popup' );\n\t\tthis.$content.append( $tabFocus );\n\t\tthis.$overlay.append( this.popup.$element );\n\t} else {\n\t\tthis.$content.append( this.$input );\n\t\tthis.$overlay.append( this.menu.$element );\n\t}\n\tif ( $tabFocus ) {\n\t\t$tabFocus.addClass( 'oo-ui-capsuleMultiselectWidget-focusTrap' );\n\t}\n\n\t// Input size needs to be calculated after everything else is rendered\n\tsetTimeout( function () {\n\t\tif ( this.$input ) {\n\t\t\tthis.updateInputSize();\n\t\t}\n\t}.bind( this ) );\n\n\tthis.onMenuItemsChange();\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.CapsuleMultiselectWidget, OO.ui.Widget );\nOO.mixinClass( OO.ui.CapsuleMultiselectWidget, OO.ui.mixin.GroupElement );\nOO.mixinClass( OO.ui.CapsuleMultiselectWidget, OO.ui.mixin.PopupElement );\nOO.mixinClass( OO.ui.CapsuleMultiselectWidget, OO.ui.mixin.TabIndexedElement );\nOO.mixinClass( OO.ui.CapsuleMultiselectWidget, OO.ui.mixin.IndicatorElement );\nOO.mixinClass( OO.ui.CapsuleMultiselectWidget, OO.ui.mixin.IconElement );\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 {Mixed[]} datas Data of the now-selected items\n */\n\n/**\n * @event resize\n *\n * A resize event is emitted when the widget's dimensions change to accomodate newly added items or\n * current user input.\n */\n\n/* Methods */\n\n/**\n * Construct a OO.ui.CapsuleItemWidget (or a subclass thereof) from given label and data.\n * May return `null` if the given label and data are not valid.\n *\n * @protected\n * @param {Mixed} data Custom data of any type.\n * @param {string} label The label text.\n * @return {OO.ui.CapsuleItemWidget|null}\n */\nOO.ui.CapsuleMultiselectWidget.prototype.createItemWidget = function ( data, label ) {\n\tif ( label === '' ) {\n\t\treturn null;\n\t}\n\treturn new OO.ui.CapsuleItemWidget( { data: data, label: label } );\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.CapsuleMultiselectWidget.prototype.getInputId = function () {\n\tif ( !this.$input ) {\n\t\treturn null;\n\t}\n\treturn OO.ui.mixin.TabIndexedElement.prototype.getInputId.call( this );\n};\n\n/**\n * Get the data of the items in the capsule\n *\n * @return {Mixed[]}\n */\nOO.ui.CapsuleMultiselectWidget.prototype.getItemsData = function () {\n\treturn this.getItems().map( function ( item ) {\n\t\treturn item.data;\n\t} );\n};\n\n/**\n * Set the items in the capsule by providing data\n *\n * @chainable\n * @param {Mixed[]} datas\n * @return {OO.ui.CapsuleMultiselectWidget}\n */\nOO.ui.CapsuleMultiselectWidget.prototype.setItemsFromData = function ( datas ) {\n\tvar widget = this,\n\t\tmenu = this.menu,\n\t\titems = this.getItems();\n\n\t$.each( datas, function ( i, data ) {\n\t\tvar j, label,\n\t\t\titem = menu.findItemFromData( data );\n\n\t\tif ( item ) {\n\t\t\tlabel = item.label;\n\t\t} else if ( widget.allowArbitrary ) {\n\t\t\tlabel = String( data );\n\t\t} else {\n\t\t\treturn;\n\t\t}\n\n\t\titem = null;\n\t\tfor ( j = 0; j < items.length; j++ ) {\n\t\t\tif ( items[ j ].data === data && items[ j ].label === label ) {\n\t\t\t\titem = items[ j ];\n\t\t\t\titems.splice( j, 1 );\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tif ( !item ) {\n\t\t\titem = widget.createItemWidget( data, label );\n\t\t}\n\t\tif ( item ) {\n\t\t\twidget.addItems( [ item ], i );\n\t\t}\n\t} );\n\n\tif ( items.length ) {\n\t\twidget.removeItems( items );\n\t}\n\n\treturn this;\n};\n\n/**\n * Add items to the capsule by providing their data\n *\n * @chainable\n * @param {Mixed[]} datas\n * @return {OO.ui.CapsuleMultiselectWidget}\n */\nOO.ui.CapsuleMultiselectWidget.prototype.addItemsFromData = function ( datas ) {\n\tvar widget = this,\n\t\tmenu = this.menu,\n\t\titems = [];\n\n\t$.each( datas, function ( i, data ) {\n\t\tvar item;\n\n\t\tif ( !widget.findItemFromData( data ) || widget.allowDuplicates ) {\n\t\t\titem = menu.findItemFromData( data );\n\t\t\tif ( item ) {\n\t\t\t\titem = widget.createItemWidget( data, item.label );\n\t\t\t} else if ( widget.allowArbitrary ) {\n\t\t\t\titem = widget.createItemWidget( data, String( data ) );\n\t\t\t}\n\t\t\tif ( item ) {\n\t\t\t\titems.push( item );\n\t\t\t}\n\t\t}\n\t} );\n\n\tif ( items.length ) {\n\t\tthis.addItems( items );\n\t}\n\n\treturn this;\n};\n\n/**\n * Add items to the capsule by providing a label\n *\n * @param {string} label\n * @return {boolean} Whether the item was added or not\n */\nOO.ui.CapsuleMultiselectWidget.prototype.addItemFromLabel = function ( label ) {\n\tvar item, items;\n\titem = this.menu.getItemFromLabel( label, true );\n\tif ( item ) {\n\t\tthis.addItemsFromData( [ item.data ] );\n\t\treturn true;\n\t} else if ( this.allowArbitrary ) {\n\t\titems = this.getItems();\n\t\tthis.addItemsFromData( [ label ] );\n\t\treturn !OO.compare( this.getItems(), items );\n\t}\n\treturn false;\n};\n\n/**\n * Remove items by data\n *\n * @chainable\n * @param {Mixed[]} datas\n * @return {OO.ui.CapsuleMultiselectWidget}\n */\nOO.ui.CapsuleMultiselectWidget.prototype.removeItemsFromData = function ( datas ) {\n\tvar widget = this,\n\t\titems = [];\n\n\t$.each( datas, function ( i, data ) {\n\t\tvar item = widget.findItemFromData( data );\n\t\tif ( item ) {\n\t\t\titems.push( item );\n\t\t}\n\t} );\n\n\tif ( items.length ) {\n\t\tthis.removeItems( items );\n\t}\n\n\treturn this;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.CapsuleMultiselectWidget.prototype.addItems = function ( items ) {\n\tvar same, i, l,\n\t\toldItems = this.items.slice();\n\n\tOO.ui.mixin.GroupElement.prototype.addItems.call( this, items );\n\n\tif ( this.items.length !== oldItems.length ) {\n\t\tsame = false;\n\t} else {\n\t\tsame = true;\n\t\tfor ( i = 0, l = oldItems.length; same && i < l; i++ ) {\n\t\t\tsame = same && this.items[ i ] === oldItems[ i ];\n\t\t}\n\t}\n\tif ( !same ) {\n\t\tthis.emit( 'change', this.getItemsData() );\n\t\tthis.updateInputSize();\n\t}\n\n\treturn this;\n};\n\n/**\n * Removes the item from the list and copies its label to `this.$input`.\n *\n * @param {Object} item\n */\nOO.ui.CapsuleMultiselectWidget.prototype.editItem = function ( item ) {\n\tthis.addItemFromLabel( this.$input.val() );\n\tthis.clearInput();\n\tthis.$input.val( item.label );\n\tthis.updateInputSize();\n\tthis.focus();\n\tthis.menu.updateItemVisibility(); // Hack, we shouldn't be calling this method directly\n\tthis.removeItems( [ item ] );\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.CapsuleMultiselectWidget.prototype.removeItems = function ( items ) {\n\tvar same, i, l,\n\t\toldItems = this.items.slice();\n\n\tOO.ui.mixin.GroupElement.prototype.removeItems.call( this, items );\n\n\tif ( this.items.length !== oldItems.length ) {\n\t\tsame = false;\n\t} else {\n\t\tsame = true;\n\t\tfor ( i = 0, l = oldItems.length; same && i < l; i++ ) {\n\t\t\tsame = same && this.items[ i ] === oldItems[ i ];\n\t\t}\n\t}\n\tif ( !same ) {\n\t\tthis.emit( 'change', this.getItemsData() );\n\t\tthis.updateInputSize();\n\t}\n\n\treturn this;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.CapsuleMultiselectWidget.prototype.clearItems = function () {\n\tif ( this.items.length ) {\n\t\tOO.ui.mixin.GroupElement.prototype.clearItems.call( this );\n\t\tthis.emit( 'change', this.getItemsData() );\n\t\tthis.updateInputSize();\n\t}\n\treturn this;\n};\n\n/**\n * Given an item, returns the item after it. If its the last item,\n * returns `this.$input`. If no item is passed, returns the very first\n * item.\n *\n * @param {OO.ui.CapsuleItemWidget} [item]\n * @return {OO.ui.CapsuleItemWidget|jQuery|boolean}\n */\nOO.ui.CapsuleMultiselectWidget.prototype.getNextItem = function ( item ) {\n\tvar itemIndex;\n\n\tif ( item === undefined ) {\n\t\treturn this.items[ 0 ];\n\t}\n\n\titemIndex = this.items.indexOf( item );\n\tif ( itemIndex < 0 ) { // Item not in list\n\t\treturn false;\n\t} else if ( itemIndex === this.items.length - 1 ) { // Last item\n\t\treturn this.$input;\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 its the first item,\n * returns `this.$input`. If no item is passed, returns the very last\n * item.\n *\n * @param {OO.ui.CapsuleItemWidget} [item]\n * @return {OO.ui.CapsuleItemWidget|jQuery|boolean}\n */\nOO.ui.CapsuleMultiselectWidget.prototype.getPreviousItem = function ( item ) {\n\tvar itemIndex;\n\n\tif ( item === undefined ) {\n\t\treturn this.items[ this.items.length - 1 ];\n\t}\n\n\titemIndex = this.items.indexOf( item );\n\tif ( itemIndex < 0 ) { // Item not in list\n\t\treturn false;\n\t} else if ( itemIndex === 0 ) { // First item\n\t\treturn this.$input;\n\t} else {\n\t\treturn this.items[ itemIndex - 1 ];\n\t}\n};\n\n/**\n * Get the capsule widget's menu.\n *\n * @return {OO.ui.MenuSelectWidget} Menu widget\n */\nOO.ui.CapsuleMultiselectWidget.prototype.getMenu = function () {\n\treturn this.menu;\n};\n\n/**\n * Handle focus events\n *\n * @private\n * @param {jQuery.Event} event\n */\nOO.ui.CapsuleMultiselectWidget.prototype.onInputFocus = function () {\n\tif ( !this.isDisabled() ) {\n\t\tthis.updateInputSize();\n\t\tthis.menu.toggle( true );\n\t}\n};\n\n/**\n * Handle blur events\n *\n * @private\n * @param {jQuery.Event} event\n */\nOO.ui.CapsuleMultiselectWidget.prototype.onInputBlur = function () {\n\tthis.addItemFromLabel( this.$input.val() );\n\tthis.clearInput();\n};\n\n/**\n * Handles popup focus out events.\n *\n * @private\n * @param {jQuery.Event} e Focus out event\n */\nOO.ui.CapsuleMultiselectWidget.prototype.onPopupFocusOut = function () {\n\tvar widget = this.popup;\n\n\tsetTimeout( function () {\n\t\tif (\n\t\t\twidget.isVisible() &&\n\t\t\t!OO.ui.contains( widget.$element.add( widget.$autoCloseIgnore ).get(), document.activeElement, true )\n\t\t) {\n\t\t\twidget.toggle( false );\n\t\t}\n\t} );\n};\n\n/**\n * Handle mouse down events.\n *\n * @private\n * @param {jQuery.Event} e Mouse down event\n */\nOO.ui.CapsuleMultiselectWidget.prototype.onMouseDown = function ( e ) {\n\tif ( e.which === OO.ui.MouseButtons.LEFT ) {\n\t\tthis.focus();\n\t\treturn false;\n\t} else {\n\t\tthis.updateInputSize();\n\t}\n};\n\n/**\n * Handle key press events.\n *\n * @private\n * @param {jQuery.Event} e Key press event\n */\nOO.ui.CapsuleMultiselectWidget.prototype.onKeyPress = function ( e ) {\n\tif ( !this.isDisabled() ) {\n\t\tif ( e.which === OO.ui.Keys.ESCAPE ) {\n\t\t\tthis.clearInput();\n\t\t\treturn false;\n\t\t}\n\n\t\tif ( !this.popup ) {\n\t\t\tthis.menu.toggle( true );\n\t\t\tif ( e.which === OO.ui.Keys.ENTER ) {\n\t\t\t\tif ( this.addItemFromLabel( this.$input.val() ) ) {\n\t\t\t\t\tthis.clearInput();\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// Make sure the input gets resized.\n\t\t\tsetTimeout( this.updateInputSize.bind( this ), 0 );\n\t\t}\n\t}\n};\n\n/**\n * Handle key down events.\n *\n * @private\n * @param {jQuery.Event} e Key down event\n */\nOO.ui.CapsuleMultiselectWidget.prototype.onKeyDown = function ( e ) {\n\tif (\n\t\t!this.isDisabled() &&\n\t\tthis.$input.val() === '' &&\n\t\tthis.items.length\n\t) {\n\t\t// 'keypress' event is not triggered for Backspace\n\t\tif ( e.keyCode === OO.ui.Keys.BACKSPACE ) {\n\t\t\tif ( e.metaKey || e.ctrlKey ) {\n\t\t\t\tthis.removeItems( this.items.slice( -1 ) );\n\t\t\t} else {\n\t\t\t\tthis.editItem( this.items[ this.items.length - 1 ] );\n\t\t\t}\n\t\t\treturn false;\n\t\t} else if ( e.keyCode === OO.ui.Keys.LEFT ) {\n\t\t\tthis.getPreviousItem().focus();\n\t\t} else if ( e.keyCode === OO.ui.Keys.RIGHT ) {\n\t\t\tthis.getNextItem().focus();\n\t\t}\n\t}\n};\n\n/**\n * Update the dimensions of the text input field to encompass all available area.\n *\n * @private\n * @param {jQuery.Event} e Event of some sort\n */\nOO.ui.CapsuleMultiselectWidget.prototype.updateInputSize = function () {\n\tvar $lastItem, direction, contentWidth, currentWidth, bestWidth;\n\tif ( this.$input && !this.isDisabled() ) {\n\t\tthis.$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.val() === '' &&\n\t\t\tthis.$input.attr( 'placeholder' ) !== undefined\n\t\t) {\n\t\t\tthis.$input.val( this.$input.attr( 'placeholder' ) );\n\t\t\tthis.contentWidthWithPlaceholder = this.$input[ 0 ].scrollWidth;\n\t\t\tthis.$input.val( '' );\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[ 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.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 -= 10;\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() - 10;\n\t\t}\n\t\tthis.$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, update menu position and emit 'resize' event.\n *\n * @private\n */\nOO.ui.CapsuleMultiselectWidget.prototype.updateIfHeightChanged = function () {\n\tvar height = this.$element.height();\n\tif ( height !== this.height ) {\n\t\tthis.height = height;\n\t\tthis.menu.position();\n\t\tif ( this.popup ) {\n\t\t\tthis.popup.updateDimensions();\n\t\t}\n\t\tthis.emit( 'resize' );\n\t}\n};\n\n/**\n * Handle menu choose events.\n *\n * @private\n * @param {OO.ui.OptionWidget} item Chosen item\n */\nOO.ui.CapsuleMultiselectWidget.prototype.onMenuChoose = function ( item ) {\n\tif ( item && item.isVisible() ) {\n\t\tthis.addItemsFromData( [ item.getData() ] );\n\t\tthis.clearInput();\n\t}\n};\n\n/**\n * Handle menu toggle events.\n *\n * @private\n * @param {boolean} isVisible Open state of the menu\n */\nOO.ui.CapsuleMultiselectWidget.prototype.onMenuToggle = function ( isVisible ) {\n\tthis.$element.toggleClass( 'oo-ui-capsuleMultiselectWidget-open', isVisible );\n};\n\n/**\n * Handle menu item change events.\n *\n * @private\n */\nOO.ui.CapsuleMultiselectWidget.prototype.onMenuItemsChange = function () {\n\tthis.setItemsFromData( this.getItemsData() );\n\tthis.$element.toggleClass( 'oo-ui-capsuleMultiselectWidget-empty', this.menu.isEmpty() );\n};\n\n/**\n * Clear the input field\n *\n * @private\n */\nOO.ui.CapsuleMultiselectWidget.prototype.clearInput = function () {\n\tif ( this.$input ) {\n\t\tthis.$input.val( '' );\n\t\tthis.updateInputSize();\n\t}\n\tif ( this.popup ) {\n\t\tthis.popup.toggle( false );\n\t}\n\tthis.menu.toggle( false );\n\tthis.menu.selectItem();\n\tthis.menu.highlightItem();\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.CapsuleMultiselectWidget.prototype.setDisabled = function ( disabled ) {\n\tvar i, len;\n\n\t// Parent method\n\tOO.ui.CapsuleMultiselectWidget.parent.prototype.setDisabled.call( this, disabled );\n\n\tif ( this.$input ) {\n\t\tthis.$input.prop( 'disabled', this.isDisabled() );\n\t}\n\tif ( this.menu ) {\n\t\tthis.menu.setDisabled( this.isDisabled() );\n\t}\n\tif ( this.popup ) {\n\t\tthis.popup.setDisabled( this.isDisabled() );\n\t}\n\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/**\n * Focus the widget\n *\n * @chainable\n */\nOO.ui.CapsuleMultiselectWidget.prototype.focus = function () {\n\tif ( !this.isDisabled() ) {\n\t\tif ( this.popup ) {\n\t\t\tthis.popup.setSize( this.$handle.outerWidth() );\n\t\t\tthis.popup.toggle( true );\n\t\t\tOO.ui.findFocusable( this.popup.$element ).focus();\n\t\t} else {\n\t\t\tOO.ui.mixin.TabIndexedElement.prototype.focus.call( this );\n\t\t}\n\t}\n\treturn this;\n};\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 */\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 */\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() ) {\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 *     // Example: A basic 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 *     $( '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 *\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 * \t- inline: The input is invisible, but exists inside the tag list, so\n * \t\tthe user types into the tag groups to add tags.\n * \t- outline: The input is underneath the tag area.\n * \t- 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 {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\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.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\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 widet 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 );\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};\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\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() ) {\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.getData() );\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\tthis.toggleValid( this.checkValidity() );\n\tif ( this.hasInput ) {\n\t\tthis.updateInputSize();\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\tthis.input.setDisabled( !!isDisabled );\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.addTag( val );\n\t\tthis.clearInput();\n\t\tthis.focus();\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 * \t ]\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 ( 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\treturn false;\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 -= 10;\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() - 10;\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 *     // Example: A basic PopupTagMultiselectWidget.\n *     var widget = new OO.ui.PopupTagMultiselectWidget();\n *     $( '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 *     $( '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 */\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\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 *     // Example: A basic MenuTagMultiselectWidget.\n *     var widget = new OO.ui.MenuTagMultiselectWidget( {\n *         inputPosition: 'outline',\n *         options: [\n *            { data: 'option1', label: 'Option 1' },\n *            { data: 'option2', label: 'Option 2' },\n *            { data: 'option3', label: 'Option 3' },\n *         ],\n *         selected: [ 'option1', 'option2' ]\n *     } );\n *     $( '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// 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 * 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\t// Add tag\n\tthis.addTag( menuItem.getData(), menuItem.getLabel() );\n\tif ( this.hasInput && this.clearInputOnChoose ) {\n\t\tthis.input.setValue( '' );\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.selectItem( null );\n\t\tthis.menu.highlightItem( null );\n\t} else {\n\t\tthis.initializeMenuSelection();\n\t}\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 * 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( this.menu.findFirstSelectableItem() );\n\t}\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.MenuTagMultiselectWidget.prototype.addTagFromInput = function () {\n\tvar inputValue = this.input.getValue(),\n\t\tvalidated = false,\n\t\thighlightedItem = this.menu.findHighlightedItem(),\n\t\titem = this.menu.findItemFromData( inputValue );\n\n\tif ( !inputValue ) {\n\t\treturn;\n\t}\n\n\t// Override the parent method so we add from the menu\n\t// rather than directly from the input\n\n\t// Look for a highlighted item first\n\tif ( highlightedItem ) {\n\t\tvalidated = this.addTag( highlightedItem.getData(), highlightedItem.getLabel() );\n\t} else if ( item ) {\n\t\t// Look for the element that fits the data\n\t\tvalidated = this.addTag( item.getData(), item.getLabel() );\n\t} else {\n\t\t// Otherwise, add the tag - the method will only add if the\n\t\t// tag is valid or if invalid tags are allowed\n\t\tvalidated = this.addTag( inputValue );\n\t}\n\n\tif ( validated ) {\n\t\tthis.clearInput();\n\t\tthis.focus();\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 );\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 * @return {OO.ui.OptionWidget} Option widget\n */\nOO.ui.MenuTagMultiselectWidget.prototype.createMenuOptionWidget = function ( data, label ) {\n\treturn new OO.ui.MenuOptionWidget( {\n\t\tdata: data,\n\t\tlabel: label || data\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} and {@link\n * OO.ui.mixin.IndicatorElement indicators}.\n * Please see the [OOUI documentation on MediaWiki] [1] for more information and examples.\n *\n *     @example\n *     // Example of a file select widget\n *     var selectFile = new OO.ui.SelectFileWidget();\n *     $( '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 *\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\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: 'close',\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 );\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 */\nOO.ui.SelectFileWidget.prototype.focus = function () {\n\tthis.selectButton.focus();\n\treturn this;\n};\n\n/**\n * Blur the widget.\n *\n * @chainable\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 */\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 */\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.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 */\nOO.ui.SelectFileWidget.prototype.onDropTargetClick = function () {\n\tif ( this.isSupported && !this.isDisabled() && this.$input ) {\n\t\tthis.$input.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 */\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 */\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
diff --git a/resources/lib/oojs-ui/oojs-ui-widgets.js.map.json b/resources/lib/oojs-ui/oojs-ui-widgets.js.map.json
new file mode 100644 (file)
index 0000000..94507f9
--- /dev/null
@@ -0,0 +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/CapsuleItemWidget.js","../src/widgets/CapsuleMultiselectWidget.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 */\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 */\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 */\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 */\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} );\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 */\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 */\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 */\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 */\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 */\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 continously\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 *     $( '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\tconfig = $.extend( { scrollable: true }, 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 */\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 * @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 * @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 * @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 * 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 = new OO.ui.MenuLayout( {\n *         position: 'top'\n *     } ),\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.$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 *     $( '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 *         height: 200px;\n *         width: 200px;\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 {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.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\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 */\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 */\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 * 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 *     $( '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.$content.append( this.stackLayout.$element );\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.$menu.append( this.outlinePanel.$element );\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 */\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}, 200 );\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 */\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 */\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 */\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 * Select the first selectable page.\n *\n * @chainable\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 *     $( '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.$content.append( this.stackLayout.$element );\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.$menu.append( this.tabPanel.$element );\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 */\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 */\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 */\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\ttabPanel = this.tabPanels[ name ],\n\t\tpreviousTabPanel = this.currentTabPanelName && this.tabPanels[ this.currentTabPanelName ];\n\n\tif ( name !== this.currentTabPanelName ) {\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 */\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 *\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// 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 );\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 */\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 *     var toggleButton2 = new OO.ui.ToggleButtonWidget( {\n *         label: 'Toggle Button on',\n *         value: true\n *     } );\n *     // Append the buttons to the DOM.\n *     $( '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.TitledElement\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.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\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};\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.TitledElement );\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 *     var toggleSwitch2 = new OO.ui.ToggleSwitchWidget( {\n *         value: true\n *     } );\n *\n *     // Create a FieldsetLayout to layout and label switches\n *     var fieldset = new OO.ui.FieldsetLayout( {\n *        label: 'Toggle switches'\n *     } );\n *     fieldset.addItems( [\n *         new OO.ui.FieldLayout( toggleSwitch1, { label: 'Off', align: 'top' } ),\n *         new OO.ui.FieldLayout( toggleSwitch2, { label: 'On', align: 'top' } )\n *     ] );\n *     $( '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 */\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 */\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 */\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 */\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 */\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.bindKeyDownListener.bind( this ),\n\t\tblur: this.unbindKeyDownListener.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 * @mixins OO.ui.mixin.TitledElement\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\tOO.ui.mixin.TitledElement.call( this, $.extend( {}, config, { $titled: this.$button } ) );\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};\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 );\nOO.mixinClass( OO.ui.ButtonOptionWidget, OO.ui.mixin.TitledElement );\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 *     // Example: 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 *\n *     var option2 = new OO.ui.ButtonOptionWidget( {\n *         data: 2,\n *         label: 'Option 2',\n *         title: 'Button option 2'\n *     } );\n *\n *     var option3 = new OO.ui.ButtonOptionWidget( {\n *         data: 3,\n *         label: 'Option 3',\n *         title: 'Button option 3'\n *     } );\n *\n *     var buttonSelect=new OO.ui.ButtonSelectWidget( {\n *         items: [ option1, option2, option3 ]\n *     } );\n *     $( '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.bindKeyDownListener.bind( this ),\n\t\tblur: this.unbindKeyDownListener.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.bindKeyDownListener.bind( this ),\n\t\tblur: this.unbindKeyDownListener.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 * CapsuleItemWidgets are used within a {@link OO.ui.CapsuleMultiselectWidget\n * CapsuleMultiselectWidget} 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 *\n * @constructor\n * @param {Object} [config] Configuration options\n * @deprecated\n */\nOO.ui.CapsuleItemWidget = function OoUiCapsuleItemWidget( config ) {\n\t// Configuration initialization\n\tconfig = config || {};\n\n\t// Parent constructor\n\tOO.ui.CapsuleItemWidget.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\n\t// Events\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} ).on( 'click', this.onCloseClick.bind( this ) );\n\n\tthis.on( 'disable', function ( disabled ) {\n\t\tthis.closeButton.setDisabled( disabled );\n\t}.bind( this ) );\n\n\t// Initialization\n\tthis.$element\n\t\t.on( {\n\t\t\tclick: this.onClick.bind( this ),\n\t\t\tkeydown: this.onKeyDown.bind( this )\n\t\t} )\n\t\t.addClass( 'oo-ui-capsuleItemWidget' )\n\t\t.append( this.$label, this.closeButton.$element );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.CapsuleItemWidget, OO.ui.Widget );\nOO.mixinClass( OO.ui.CapsuleItemWidget, OO.ui.mixin.ItemWidget );\nOO.mixinClass( OO.ui.CapsuleItemWidget, OO.ui.mixin.LabelElement );\nOO.mixinClass( OO.ui.CapsuleItemWidget, OO.ui.mixin.FlaggedElement );\nOO.mixinClass( OO.ui.CapsuleItemWidget, OO.ui.mixin.TabIndexedElement );\n\n/* Methods */\n\n/**\n * Handle close icon clicks\n */\nOO.ui.CapsuleItemWidget.prototype.onCloseClick = function () {\n\tvar element = this.getElementGroup();\n\n\tif ( element && $.isFunction( element.removeItems ) ) {\n\t\telement.removeItems( [ this ] );\n\t\telement.focus();\n\t}\n};\n\n/**\n * Handle click event for the entire capsule\n */\nOO.ui.CapsuleItemWidget.prototype.onClick = function () {\n\tvar element = this.getElementGroup();\n\n\tif ( !this.isDisabled() && element && $.isFunction( element.editItem ) ) {\n\t\telement.editItem( this );\n\t}\n};\n\n/**\n * Handle keyDown event for the entire capsule\n *\n * @param {jQuery.Event} e Key down event\n */\nOO.ui.CapsuleItemWidget.prototype.onKeyDown = function ( e ) {\n\tvar element = this.getElementGroup();\n\n\tif ( e.keyCode === OO.ui.Keys.BACKSPACE || e.keyCode === OO.ui.Keys.DELETE ) {\n\t\telement.removeItems( [ this ] );\n\t\telement.focus();\n\t\treturn false;\n\t} else if ( e.keyCode === OO.ui.Keys.ENTER ) {\n\t\telement.editItem( this );\n\t\treturn false;\n\t} else if ( e.keyCode === OO.ui.Keys.LEFT ) {\n\t\telement.getPreviousItem( this ).focus();\n\t} else if ( e.keyCode === OO.ui.Keys.RIGHT ) {\n\t\telement.getNextItem( this ).focus();\n\t}\n};\n","/**\n * CapsuleMultiselectWidgets are something like a {@link OO.ui.ComboBoxInputWidget combo box widget}\n * that allows for selecting multiple values.\n *\n * For more information about menus and options, please see the [OOUI documentation on MediaWiki][1].\n *\n *     @example\n *     // Example: A CapsuleMultiselectWidget.\n *     var capsule = new OO.ui.CapsuleMultiselectWidget( {\n *         label: 'CapsuleMultiselectWidget',\n *         selected: [ 'Option 1', 'Option 3' ],\n *         menu: {\n *             items: [\n *                 new OO.ui.MenuOptionWidget( {\n *                     data: 'Option 1',\n *                     label: 'Option One'\n *                 } ),\n *                 new OO.ui.MenuOptionWidget( {\n *                     data: 'Option 2',\n *                     label: 'Option Two'\n *                 } ),\n *                 new OO.ui.MenuOptionWidget( {\n *                     data: 'Option 3',\n *                     label: 'Option Three'\n *                 } ),\n *                 new OO.ui.MenuOptionWidget( {\n *                     data: 'Option 4',\n *                     label: 'Option Four'\n *                 } ),\n *                 new OO.ui.MenuOptionWidget( {\n *                     data: 'Option 5',\n *                     label: 'Option Five'\n *                 } )\n *             ]\n *         }\n *     } );\n *     $( 'body' ).append( capsule.$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.Widget\n * @mixins OO.ui.mixin.GroupElement\n * @mixins OO.ui.mixin.PopupElement\n * @mixins OO.ui.mixin.TabIndexedElement\n * @mixins OO.ui.mixin.IndicatorElement\n * @mixins OO.ui.mixin.IconElement\n * @uses OO.ui.CapsuleItemWidget\n * @uses OO.ui.MenuSelectWidget\n *\n * @constructor\n * @param {Object} [config] Configuration options\n * @cfg {string} [placeholder] Placeholder text\n * @cfg {boolean} [allowArbitrary=false] Allow data items to be added even if not present in the menu.\n * @cfg {boolean} [allowDuplicates=false] Allow duplicate items to be added.\n * @cfg {Object} [menu] (required) Configuration options to pass to the\n *  {@link OO.ui.MenuSelectWidget menu select widget}.\n * @cfg {Object} [popup] Configuration options to pass to the {@link OO.ui.PopupWidget popup widget}.\n *  If specified, this popup will be shown instead of the menu (but the menu\n *  will still be used for item labels and allowArbitrary=false). The widgets\n *  in the popup should use {@link #addItemsFromData} or {@link #addItems} as necessary.\n * @cfg {jQuery} [$overlay=this.$element] Render the menu or popup into a separate layer.\n *  This configuration is useful in cases where the expanded menu is larger than\n *  its containing `<div>`. The specified overlay layer is usually on top of\n *  the containing `<div>` and has a larger area. By default, the menu uses\n *  relative positioning.\n *  See <https://www.mediawiki.org/wiki/OOUI/Concepts#Overlays>.\n * @deprecated\n */\nOO.ui.CapsuleMultiselectWidget = function OoUiCapsuleMultiselectWidget( config ) {\n\tvar $tabFocus;\n\n\t// Parent constructor\n\tOO.ui.CapsuleMultiselectWidget.parent.call( this, config );\n\n\t// Configuration initialization\n\tconfig = $.extend( {\n\t\tallowArbitrary: false,\n\t\tallowDuplicates: false\n\t}, config );\n\n\t// Properties (must be set before mixin constructor calls)\n\tthis.$handle = $( '<div>' );\n\tthis.$input = config.popup ? null : $( '<input>' );\n\tif ( config.placeholder !== undefined && config.placeholder !== '' ) {\n\t\tthis.$input.attr( 'placeholder', config.placeholder );\n\t}\n\n\t// Mixin constructors\n\tOO.ui.mixin.GroupElement.call( this, config );\n\tif ( config.popup ) {\n\t\tconfig.popup = $.extend( {}, config.popup, {\n\t\t\talign: 'forwards',\n\t\t\tanchor: false\n\t\t} );\n\t\tOO.ui.mixin.PopupElement.call( this, config );\n\t\t$tabFocus = $( '<span>' );\n\t\tOO.ui.mixin.TabIndexedElement.call( this, $.extend( {}, config, { $tabIndexed: $tabFocus } ) );\n\t} else {\n\t\tthis.popup = null;\n\t\t$tabFocus = null;\n\t\tOO.ui.mixin.TabIndexedElement.call( this, $.extend( {}, config, { $tabIndexed: this.$input } ) );\n\t}\n\tOO.ui.mixin.IndicatorElement.call( this, config );\n\tOO.ui.mixin.IconElement.call( this, config );\n\n\t// Properties\n\tthis.$content = $( '<div>' );\n\tthis.allowArbitrary = config.allowArbitrary;\n\tthis.allowDuplicates = config.allowDuplicates;\n\tthis.$overlay = ( config.$overlay === true ? OO.ui.getDefaultOverlay() : config.$overlay ) || this.$element;\n\tthis.menu = new OO.ui.MenuSelectWidget( $.extend(\n\t\t{\n\t\t\twidget: this,\n\t\t\t$input: this.$input,\n\t\t\t$floatableContainer: this.$element,\n\t\t\tfilterFromInput: true,\n\t\t\tdisabled: this.isDisabled()\n\t\t},\n\t\tconfig.menu\n\t) );\n\n\t// Events\n\tif ( this.popup ) {\n\t\t$tabFocus.on( {\n\t\t\tfocus: this.focus.bind( this )\n\t\t} );\n\t\tthis.popup.$element.on( 'focusout', this.onPopupFocusOut.bind( this ) );\n\t\tif ( this.popup.$autoCloseIgnore ) {\n\t\t\tthis.popup.$autoCloseIgnore.on( 'focusout', this.onPopupFocusOut.bind( this ) );\n\t\t}\n\t\tthis.popup.connect( this, {\n\t\t\ttoggle: function ( visible ) {\n\t\t\t\t$tabFocus.toggle( !visible );\n\t\t\t}\n\t\t} );\n\t} else {\n\t\tthis.$input.on( {\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.onKeyDown.bind( this ),\n\t\t\tkeypress: this.onKeyPress.bind( this )\n\t\t} );\n\t}\n\tthis.menu.connect( this, {\n\t\tchoose: 'onMenuChoose',\n\t\ttoggle: 'onMenuToggle',\n\t\tadd: 'onMenuItemsChange',\n\t\tremove: 'onMenuItemsChange'\n\t} );\n\tthis.$handle.on( {\n\t\tmousedown: this.onMouseDown.bind( this )\n\t} );\n\n\t// Initialization\n\tif ( this.$input ) {\n\t\tthis.$input.prop( 'disabled', this.isDisabled() );\n\t\tthis.$input.attr( {\n\t\t\trole: 'combobox',\n\t\t\t'aria-owns': this.menu.getElementId(),\n\t\t\t'aria-autocomplete': 'list'\n\t\t} );\n\t}\n\tif ( config.data ) {\n\t\tthis.setItemsFromData( config.data );\n\t}\n\tthis.$content.addClass( 'oo-ui-capsuleMultiselectWidget-content' )\n\t\t.append( this.$group );\n\tthis.$group.addClass( 'oo-ui-capsuleMultiselectWidget-group' );\n\tthis.$handle.addClass( 'oo-ui-capsuleMultiselectWidget-handle' )\n\t\t.append( this.$indicator, this.$icon, this.$content );\n\tthis.$element.addClass( 'oo-ui-capsuleMultiselectWidget' )\n\t\t.append( this.$handle );\n\tif ( this.popup ) {\n\t\tthis.popup.$element.addClass( 'oo-ui-capsuleMultiselectWidget-popup' );\n\t\tthis.$content.append( $tabFocus );\n\t\tthis.$overlay.append( this.popup.$element );\n\t} else {\n\t\tthis.$content.append( this.$input );\n\t\tthis.$overlay.append( this.menu.$element );\n\t}\n\tif ( $tabFocus ) {\n\t\t$tabFocus.addClass( 'oo-ui-capsuleMultiselectWidget-focusTrap' );\n\t}\n\n\t// Input size needs to be calculated after everything else is rendered\n\tsetTimeout( function () {\n\t\tif ( this.$input ) {\n\t\t\tthis.updateInputSize();\n\t\t}\n\t}.bind( this ) );\n\n\tthis.onMenuItemsChange();\n\n\t// Deprecation warning\n\tOO.ui.warnDeprecation( 'CapsuleMultiselectWidget: Deprecated widget. Use TagMultiselectWidget instead. See T183299.' );\n};\n\n/* Setup */\n\nOO.inheritClass( OO.ui.CapsuleMultiselectWidget, OO.ui.Widget );\nOO.mixinClass( OO.ui.CapsuleMultiselectWidget, OO.ui.mixin.GroupElement );\nOO.mixinClass( OO.ui.CapsuleMultiselectWidget, OO.ui.mixin.PopupElement );\nOO.mixinClass( OO.ui.CapsuleMultiselectWidget, OO.ui.mixin.TabIndexedElement );\nOO.mixinClass( OO.ui.CapsuleMultiselectWidget, OO.ui.mixin.IndicatorElement );\nOO.mixinClass( OO.ui.CapsuleMultiselectWidget, OO.ui.mixin.IconElement );\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 {Mixed[]} datas Data of the now-selected items\n */\n\n/**\n * @event resize\n *\n * A resize event is emitted when the widget's dimensions change to accomodate newly added items or\n * current user input.\n */\n\n/* Methods */\n\n/**\n * Construct a OO.ui.CapsuleItemWidget (or a subclass thereof) from given label and data.\n * May return `null` if the given label and data are not valid.\n *\n * @protected\n * @param {Mixed} data Custom data of any type.\n * @param {string} label The label text.\n * @return {OO.ui.CapsuleItemWidget|null}\n */\nOO.ui.CapsuleMultiselectWidget.prototype.createItemWidget = function ( data, label ) {\n\tif ( label === '' ) {\n\t\treturn null;\n\t}\n\treturn new OO.ui.CapsuleItemWidget( { data: data, label: label } );\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.CapsuleMultiselectWidget.prototype.getInputId = function () {\n\tif ( !this.$input ) {\n\t\treturn null;\n\t}\n\treturn OO.ui.mixin.TabIndexedElement.prototype.getInputId.call( this );\n};\n\n/**\n * Get the data of the items in the capsule\n *\n * @return {Mixed[]}\n */\nOO.ui.CapsuleMultiselectWidget.prototype.getItemsData = function () {\n\treturn this.getItems().map( function ( item ) {\n\t\treturn item.data;\n\t} );\n};\n\n/**\n * Set the items in the capsule by providing data\n *\n * @chainable\n * @param {Mixed[]} datas\n * @return {OO.ui.CapsuleMultiselectWidget}\n */\nOO.ui.CapsuleMultiselectWidget.prototype.setItemsFromData = function ( datas ) {\n\tvar widget = this,\n\t\tmenu = this.menu,\n\t\titems = this.getItems();\n\n\t$.each( datas, function ( i, data ) {\n\t\tvar j, label,\n\t\t\titem = menu.findItemFromData( data );\n\n\t\tif ( item ) {\n\t\t\tlabel = item.label;\n\t\t} else if ( widget.allowArbitrary ) {\n\t\t\tlabel = String( data );\n\t\t} else {\n\t\t\treturn;\n\t\t}\n\n\t\titem = null;\n\t\tfor ( j = 0; j < items.length; j++ ) {\n\t\t\tif ( items[ j ].data === data && items[ j ].label === label ) {\n\t\t\t\titem = items[ j ];\n\t\t\t\titems.splice( j, 1 );\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tif ( !item ) {\n\t\t\titem = widget.createItemWidget( data, label );\n\t\t}\n\t\tif ( item ) {\n\t\t\twidget.addItems( [ item ], i );\n\t\t}\n\t} );\n\n\tif ( items.length ) {\n\t\twidget.removeItems( items );\n\t}\n\n\treturn this;\n};\n\n/**\n * Add items to the capsule by providing their data\n *\n * @chainable\n * @param {Mixed[]} datas\n * @return {OO.ui.CapsuleMultiselectWidget}\n */\nOO.ui.CapsuleMultiselectWidget.prototype.addItemsFromData = function ( datas ) {\n\tvar widget = this,\n\t\tmenu = this.menu,\n\t\titems = [];\n\n\t$.each( datas, function ( i, data ) {\n\t\tvar item;\n\n\t\tif ( !widget.findItemFromData( data ) || widget.allowDuplicates ) {\n\t\t\titem = menu.findItemFromData( data );\n\t\t\tif ( item ) {\n\t\t\t\titem = widget.createItemWidget( data, item.label );\n\t\t\t} else if ( widget.allowArbitrary ) {\n\t\t\t\titem = widget.createItemWidget( data, String( data ) );\n\t\t\t}\n\t\t\tif ( item ) {\n\t\t\t\titems.push( item );\n\t\t\t}\n\t\t}\n\t} );\n\n\tif ( items.length ) {\n\t\tthis.addItems( items );\n\t}\n\n\treturn this;\n};\n\n/**\n * Add items to the capsule by providing a label\n *\n * @param {string} label\n * @return {boolean} Whether the item was added or not\n */\nOO.ui.CapsuleMultiselectWidget.prototype.addItemFromLabel = function ( label ) {\n\tvar item, items;\n\titem = this.menu.getItemFromLabel( label, true );\n\tif ( item ) {\n\t\tthis.addItemsFromData( [ item.data ] );\n\t\treturn true;\n\t} else if ( this.allowArbitrary ) {\n\t\titems = this.getItems();\n\t\tthis.addItemsFromData( [ label ] );\n\t\treturn !OO.compare( this.getItems(), items );\n\t}\n\treturn false;\n};\n\n/**\n * Remove items by data\n *\n * @chainable\n * @param {Mixed[]} datas\n * @return {OO.ui.CapsuleMultiselectWidget}\n */\nOO.ui.CapsuleMultiselectWidget.prototype.removeItemsFromData = function ( datas ) {\n\tvar widget = this,\n\t\titems = [];\n\n\t$.each( datas, function ( i, data ) {\n\t\tvar item = widget.findItemFromData( data );\n\t\tif ( item ) {\n\t\t\titems.push( item );\n\t\t}\n\t} );\n\n\tif ( items.length ) {\n\t\tthis.removeItems( items );\n\t}\n\n\treturn this;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.CapsuleMultiselectWidget.prototype.addItems = function ( items ) {\n\tvar same, i, l,\n\t\toldItems = this.items.slice();\n\n\tOO.ui.mixin.GroupElement.prototype.addItems.call( this, items );\n\n\tif ( this.items.length !== oldItems.length ) {\n\t\tsame = false;\n\t} else {\n\t\tsame = true;\n\t\tfor ( i = 0, l = oldItems.length; same && i < l; i++ ) {\n\t\t\tsame = same && this.items[ i ] === oldItems[ i ];\n\t\t}\n\t}\n\tif ( !same ) {\n\t\tthis.emit( 'change', this.getItemsData() );\n\t\tthis.updateInputSize();\n\t}\n\n\treturn this;\n};\n\n/**\n * Removes the item from the list and copies its label to `this.$input`.\n *\n * @param {Object} item\n */\nOO.ui.CapsuleMultiselectWidget.prototype.editItem = function ( item ) {\n\tthis.addItemFromLabel( this.$input.val() );\n\tthis.clearInput();\n\tthis.$input.val( item.label );\n\tthis.updateInputSize();\n\tthis.focus();\n\tthis.menu.updateItemVisibility(); // Hack, we shouldn't be calling this method directly\n\tthis.removeItems( [ item ] );\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.CapsuleMultiselectWidget.prototype.removeItems = function ( items ) {\n\tvar same, i, l,\n\t\toldItems = this.items.slice();\n\n\tOO.ui.mixin.GroupElement.prototype.removeItems.call( this, items );\n\n\tif ( this.items.length !== oldItems.length ) {\n\t\tsame = false;\n\t} else {\n\t\tsame = true;\n\t\tfor ( i = 0, l = oldItems.length; same && i < l; i++ ) {\n\t\t\tsame = same && this.items[ i ] === oldItems[ i ];\n\t\t}\n\t}\n\tif ( !same ) {\n\t\tthis.emit( 'change', this.getItemsData() );\n\t\tthis.updateInputSize();\n\t}\n\n\treturn this;\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.CapsuleMultiselectWidget.prototype.clearItems = function () {\n\tif ( this.items.length ) {\n\t\tOO.ui.mixin.GroupElement.prototype.clearItems.call( this );\n\t\tthis.emit( 'change', this.getItemsData() );\n\t\tthis.updateInputSize();\n\t}\n\treturn this;\n};\n\n/**\n * Given an item, returns the item after it. If its the last item,\n * returns `this.$input`. If no item is passed, returns the very first\n * item.\n *\n * @param {OO.ui.CapsuleItemWidget} [item]\n * @return {OO.ui.CapsuleItemWidget|jQuery|boolean}\n */\nOO.ui.CapsuleMultiselectWidget.prototype.getNextItem = function ( item ) {\n\tvar itemIndex;\n\n\tif ( item === undefined ) {\n\t\treturn this.items[ 0 ];\n\t}\n\n\titemIndex = this.items.indexOf( item );\n\tif ( itemIndex < 0 ) { // Item not in list\n\t\treturn false;\n\t} else if ( itemIndex === this.items.length - 1 ) { // Last item\n\t\treturn this.$input;\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 its the first item,\n * returns `this.$input`. If no item is passed, returns the very last\n * item.\n *\n * @param {OO.ui.CapsuleItemWidget} [item]\n * @return {OO.ui.CapsuleItemWidget|jQuery|boolean}\n */\nOO.ui.CapsuleMultiselectWidget.prototype.getPreviousItem = function ( item ) {\n\tvar itemIndex;\n\n\tif ( item === undefined ) {\n\t\treturn this.items[ this.items.length - 1 ];\n\t}\n\n\titemIndex = this.items.indexOf( item );\n\tif ( itemIndex < 0 ) { // Item not in list\n\t\treturn false;\n\t} else if ( itemIndex === 0 ) { // First item\n\t\treturn this.$input;\n\t} else {\n\t\treturn this.items[ itemIndex - 1 ];\n\t}\n};\n\n/**\n * Get the capsule widget's menu.\n *\n * @return {OO.ui.MenuSelectWidget} Menu widget\n */\nOO.ui.CapsuleMultiselectWidget.prototype.getMenu = function () {\n\treturn this.menu;\n};\n\n/**\n * Handle focus events\n *\n * @private\n * @param {jQuery.Event} event\n */\nOO.ui.CapsuleMultiselectWidget.prototype.onInputFocus = function () {\n\tif ( !this.isDisabled() ) {\n\t\tthis.updateInputSize();\n\t\tthis.menu.toggle( true );\n\t}\n};\n\n/**\n * Handle blur events\n *\n * @private\n * @param {jQuery.Event} event\n */\nOO.ui.CapsuleMultiselectWidget.prototype.onInputBlur = function () {\n\tthis.addItemFromLabel( this.$input.val() );\n\tthis.clearInput();\n};\n\n/**\n * Handles popup focus out events.\n *\n * @private\n * @param {jQuery.Event} e Focus out event\n */\nOO.ui.CapsuleMultiselectWidget.prototype.onPopupFocusOut = function () {\n\tvar widget = this.popup;\n\n\tsetTimeout( function () {\n\t\tif (\n\t\t\twidget.isVisible() &&\n\t\t\t!OO.ui.contains( widget.$element.add( widget.$autoCloseIgnore ).get(), document.activeElement, true )\n\t\t) {\n\t\t\twidget.toggle( false );\n\t\t}\n\t} );\n};\n\n/**\n * Handle mouse down events.\n *\n * @private\n * @param {jQuery.Event} e Mouse down event\n */\nOO.ui.CapsuleMultiselectWidget.prototype.onMouseDown = function ( e ) {\n\tif ( e.which === OO.ui.MouseButtons.LEFT ) {\n\t\tthis.focus();\n\t\treturn false;\n\t} else {\n\t\tthis.updateInputSize();\n\t}\n};\n\n/**\n * Handle key press events.\n *\n * @private\n * @param {jQuery.Event} e Key press event\n */\nOO.ui.CapsuleMultiselectWidget.prototype.onKeyPress = function ( e ) {\n\tif ( !this.isDisabled() ) {\n\t\tif ( e.which === OO.ui.Keys.ESCAPE ) {\n\t\t\tthis.clearInput();\n\t\t\treturn false;\n\t\t}\n\n\t\tif ( !this.popup ) {\n\t\t\tthis.menu.toggle( true );\n\t\t\tif ( e.which === OO.ui.Keys.ENTER ) {\n\t\t\t\tif ( this.addItemFromLabel( this.$input.val() ) ) {\n\t\t\t\t\tthis.clearInput();\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// Make sure the input gets resized.\n\t\t\tsetTimeout( this.updateInputSize.bind( this ), 0 );\n\t\t}\n\t}\n};\n\n/**\n * Handle key down events.\n *\n * @private\n * @param {jQuery.Event} e Key down event\n */\nOO.ui.CapsuleMultiselectWidget.prototype.onKeyDown = function ( e ) {\n\tif (\n\t\t!this.isDisabled() &&\n\t\tthis.$input.val() === '' &&\n\t\tthis.items.length\n\t) {\n\t\t// 'keypress' event is not triggered for Backspace\n\t\tif ( e.keyCode === OO.ui.Keys.BACKSPACE ) {\n\t\t\tif ( e.metaKey || e.ctrlKey ) {\n\t\t\t\tthis.removeItems( this.items.slice( -1 ) );\n\t\t\t} else {\n\t\t\t\tthis.editItem( this.items[ this.items.length - 1 ] );\n\t\t\t}\n\t\t\treturn false;\n\t\t} else if ( e.keyCode === OO.ui.Keys.LEFT ) {\n\t\t\tthis.getPreviousItem().focus();\n\t\t} else if ( e.keyCode === OO.ui.Keys.RIGHT ) {\n\t\t\tthis.getNextItem().focus();\n\t\t}\n\t}\n};\n\n/**\n * Update the dimensions of the text input field to encompass all available area.\n *\n * @private\n * @param {jQuery.Event} e Event of some sort\n */\nOO.ui.CapsuleMultiselectWidget.prototype.updateInputSize = function () {\n\tvar $lastItem, direction, contentWidth, currentWidth, bestWidth;\n\tif ( this.$input && !this.isDisabled() ) {\n\t\tthis.$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.val() === '' &&\n\t\t\tthis.$input.attr( 'placeholder' ) !== undefined\n\t\t) {\n\t\t\tthis.$input.val( this.$input.attr( 'placeholder' ) );\n\t\t\tthis.contentWidthWithPlaceholder = this.$input[ 0 ].scrollWidth;\n\t\t\tthis.$input.val( '' );\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[ 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.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 -= 10;\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() - 10;\n\t\t}\n\t\tthis.$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, update menu position and emit 'resize' event.\n *\n * @private\n */\nOO.ui.CapsuleMultiselectWidget.prototype.updateIfHeightChanged = function () {\n\tvar height = this.$element.height();\n\tif ( height !== this.height ) {\n\t\tthis.height = height;\n\t\tthis.menu.position();\n\t\tif ( this.popup ) {\n\t\t\tthis.popup.updateDimensions();\n\t\t}\n\t\tthis.emit( 'resize' );\n\t}\n};\n\n/**\n * Handle menu choose events.\n *\n * @private\n * @param {OO.ui.OptionWidget} item Chosen item\n */\nOO.ui.CapsuleMultiselectWidget.prototype.onMenuChoose = function ( item ) {\n\tif ( item && item.isVisible() ) {\n\t\tthis.addItemsFromData( [ item.getData() ] );\n\t\tthis.clearInput();\n\t}\n};\n\n/**\n * Handle menu toggle events.\n *\n * @private\n * @param {boolean} isVisible Open state of the menu\n */\nOO.ui.CapsuleMultiselectWidget.prototype.onMenuToggle = function ( isVisible ) {\n\tthis.$element.toggleClass( 'oo-ui-capsuleMultiselectWidget-open', isVisible );\n};\n\n/**\n * Handle menu item change events.\n *\n * @private\n */\nOO.ui.CapsuleMultiselectWidget.prototype.onMenuItemsChange = function () {\n\tthis.setItemsFromData( this.getItemsData() );\n\tthis.$element.toggleClass( 'oo-ui-capsuleMultiselectWidget-empty', this.menu.isEmpty() );\n};\n\n/**\n * Clear the input field\n *\n * @private\n */\nOO.ui.CapsuleMultiselectWidget.prototype.clearInput = function () {\n\tif ( this.$input ) {\n\t\tthis.$input.val( '' );\n\t\tthis.updateInputSize();\n\t}\n\tif ( this.popup ) {\n\t\tthis.popup.toggle( false );\n\t}\n\tthis.menu.toggle( false );\n\tthis.menu.selectItem();\n\tthis.menu.highlightItem();\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.CapsuleMultiselectWidget.prototype.setDisabled = function ( disabled ) {\n\tvar i, len;\n\n\t// Parent method\n\tOO.ui.CapsuleMultiselectWidget.parent.prototype.setDisabled.call( this, disabled );\n\n\tif ( this.$input ) {\n\t\tthis.$input.prop( 'disabled', this.isDisabled() );\n\t}\n\tif ( this.menu ) {\n\t\tthis.menu.setDisabled( this.isDisabled() );\n\t}\n\tif ( this.popup ) {\n\t\tthis.popup.setDisabled( this.isDisabled() );\n\t}\n\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/**\n * Focus the widget\n *\n * @chainable\n */\nOO.ui.CapsuleMultiselectWidget.prototype.focus = function () {\n\tif ( !this.isDisabled() ) {\n\t\tif ( this.popup ) {\n\t\t\tthis.popup.setSize( this.$handle.outerWidth() );\n\t\t\tthis.popup.toggle( true );\n\t\t\tOO.ui.findFocusable( this.popup.$element ).focus();\n\t\t} else {\n\t\t\tOO.ui.mixin.TabIndexedElement.prototype.focus.call( this );\n\t\t}\n\t}\n\treturn this;\n};\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 */\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 */\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 *     // Example: A basic 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 *     $( '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 *\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 * \t- inline: The input is invisible, but exists inside the tag list, so\n * \t\tthe user types into the tag groups to add tags.\n * \t- outline: The input is underneath the tag area.\n * \t- 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 {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\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.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\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 widet 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 );\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};\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\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.getData() );\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\tthis.toggleValid( this.checkValidity() );\n\tif ( this.hasInput ) {\n\t\tthis.updateInputSize();\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\tthis.input.setDisabled( !!isDisabled );\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.addTag( val );\n\t\tthis.clearInput();\n\t\tthis.focus();\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 * \t ]\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 ( 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\treturn false;\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 -= 10;\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() - 10;\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 *     // Example: A basic PopupTagMultiselectWidget.\n *     var widget = new OO.ui.PopupTagMultiselectWidget();\n *     $( '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 *     $( '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 */\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\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 *     // Example: 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 *     $( '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// 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 * 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\t// Add tag\n\tthis.addTag( menuItem.getData(), menuItem.getLabel() );\n\tif ( this.hasInput && this.clearInputOnChoose ) {\n\t\tthis.input.setValue( '' );\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.selectItem( null );\n\t\tthis.menu.highlightItem( null );\n\t} else {\n\t\tthis.initializeMenuSelection();\n\t}\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 * 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( this.menu.findFirstSelectableItem() );\n\t}\n};\n\n/**\n * @inheritdoc\n */\nOO.ui.MenuTagMultiselectWidget.prototype.addTagFromInput = function () {\n\tvar inputValue = this.input.getValue(),\n\t\tvalidated = false,\n\t\thighlightedItem = this.menu.findHighlightedItem(),\n\t\titem = this.menu.findItemFromData( inputValue );\n\n\tif ( !inputValue ) {\n\t\treturn;\n\t}\n\n\t// Override the parent method so we add from the menu\n\t// rather than directly from the input\n\n\t// Look for a highlighted item first\n\tif ( highlightedItem ) {\n\t\tvalidated = this.addTag( highlightedItem.getData(), highlightedItem.getLabel() );\n\t} else if ( item ) {\n\t\t// Look for the element that fits the data\n\t\tvalidated = this.addTag( item.getData(), item.getLabel() );\n\t} else {\n\t\t// Otherwise, add the tag - the method will only add if the\n\t\t// tag is valid or if invalid tags are allowed\n\t\tvalidated = this.addTag( inputValue );\n\t}\n\n\tif ( validated ) {\n\t\tthis.clearInput();\n\t\tthis.focus();\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} and {@link\n * OO.ui.mixin.IndicatorElement indicators}.\n * Please see the [OOUI documentation on MediaWiki] [1] for more information and examples.\n *\n *     @example\n *     // Example of a file select widget\n *     var selectFile = new OO.ui.SelectFileWidget();\n *     $( '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 *\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\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: 'close',\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 );\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 */\nOO.ui.SelectFileWidget.prototype.focus = function () {\n\tthis.selectButton.focus();\n\treturn this;\n};\n\n/**\n * Blur the widget.\n *\n * @chainable\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 */\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 */\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.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 */\nOO.ui.SelectFileWidget.prototype.onDropTargetClick = function () {\n\tif ( this.isSupported && !this.isDisabled() && this.$input ) {\n\t\tthis.$input.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 */\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 */\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
index 6e9783c..9c20355 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOUI v0.27.0
+ * OOUI v0.27.5
  * https://www.mediawiki.org/wiki/OOUI
  *
  * Copyright 2011–2018 OOUI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2018-05-09T00:44:45Z
+ * Date: 2018-07-11T18:13:04Z
  */
 ( function ( OO ) {
 
@@ -54,6 +54,7 @@ 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
                        ( OO.ui.Tool && element instanceof OO.ui.Tool ) ||
                        ( OO.ui.ToolGroup && element instanceof OO.ui.ToolGroup );
                if (
@@ -72,9 +73,13 @@ OO.ui.WikimediaUITheme.prototype.getElementClasses = function ( element ) {
                        variants.progressive = element.hasFlag( 'progressive' ) ||
                                // Active tools/toolgroups
                                ( isToolOrGroup && isActive ) ||
-                               // Pressed or selected outline option widgets
+                               // Pressed or selected outline/menu option widgets
                                (
-                                       OO.ui.OutlineOptionWidget && element instanceof OO.ui.OutlineOptionWidget &&
+                                       (
+                                               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 )
+                                       ) &&
                                        ( element.isPressed() || element.isSelected() )
                                );
 
@@ -103,4 +108,4 @@ OO.ui.theme = new OO.ui.WikimediaUITheme();
 
 }( OO ) );
 
-//# sourceMappingURL=oojs-ui-wikimediaui.js.map
\ No newline at end of file
+//# sourceMappingURL=oojs-ui-wikimediaui.js.map.json
\ No newline at end of file
diff --git a/resources/lib/oojs-ui/oojs-ui-wikimediaui.js.map b/resources/lib/oojs-ui/oojs-ui-wikimediaui.js.map
deleted file mode 100644 (file)
index 5d43066..0000000
+++ /dev/null
@@ -1 +0,0 @@
-{"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\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( 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 option widgets\n\t\t\t\t(\n\t\t\t\t\tOO.ui.OutlineOptionWidget && element instanceof OO.ui.OutlineOptionWidget &&\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
diff --git a/resources/lib/oojs-ui/oojs-ui-wikimediaui.js.map.json b/resources/lib/oojs-ui/oojs-ui-wikimediaui.js.map.json
new file mode 100644 (file)
index 0000000..861897a
--- /dev/null
@@ -0,0 +1 @@
+{"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\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
index f75e87b..c48dd3d 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOUI v0.27.0
+ * OOUI v0.27.5
  * https://www.mediawiki.org/wiki/OOUI
  *
  * Copyright 2011–2018 OOUI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2018-05-09T00:44:50Z
+ * Date: 2018-07-11T18:13:08Z
  */
 .oo-ui-actionWidget.oo-ui-pendingElement-pending {
   background-image: /* @embed */ url(themes/wikimediaui/images/textures/pending.gif);
   text-overflow: ellipsis;
 }
 .oo-ui-messageDialog-content .oo-ui-window-body {
-  box-shadow: 0 0 0.33em rgba(0, 0, 0, 0.33);
+  box-shadow: none;
 }
 .oo-ui-messageDialog-title,
 .oo-ui-messageDialog-message {
   display: block;
+  line-height: 1.5em;
   text-align: center;
 }
-.oo-ui-messageDialog-title.oo-ui-labelElement,
-.oo-ui-messageDialog-message.oo-ui-labelElement {
-  padding-top: 0.5em;
-}
 .oo-ui-messageDialog-title {
   font-size: 1.5em;
-  line-height: 1em;
   color: #000;
 }
 .oo-ui-messageDialog-message {
   font-size: 1.1em;
-  line-height: 1.5em;
   color: #666;
   text-align: left;
 }
-.oo-ui-messageDialog-actions-horizontal .oo-ui-actionWidget {
-  border-right: 1px solid #e5e5e5;
-  margin: 0;
+.oo-ui-messageDialog-actions .oo-ui-actionWidget {
+  min-height: 2.5em;
+  margin-right: 0;
 }
-.oo-ui-messageDialog-actions-horizontal .oo-ui-actionWidget:last-child {
-  border-right-width: 0;
+.oo-ui-messageDialog-actions .oo-ui-actionWidget:last-child {
+  margin-right: 0;
 }
-.oo-ui-messageDialog-actions-vertical .oo-ui-actionWidget {
-  border-bottom: 1px solid #e5e5e5;
+.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-labelElement .oo-ui-labelElement-label {
+  line-height: 2.5em;
+  text-align: center;
+}
+.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-progressive .oo-ui-labelElement-label {
+  font-weight: bold;
+}
+.oo-ui-messageDialog-actions-horizontal .oo-ui-actionWidget {
   margin: 0;
 }
-.oo-ui-messageDialog-actions-vertical .oo-ui-actionWidget:last-child {
-  border-bottom-width: 0;
+.oo-ui-messageDialog-actions-horizontal .oo-ui-actionWidget:first-child > .oo-ui-buttonElement-button {
+  border-left-width: 2px;
+  border-left-color: transparent;
+  border-radius: 0 0 0 3px;
 }
-.oo-ui-messageDialog-actions .oo-ui-actionWidget {
-  min-height: 3.4em;
-  margin-right: 0;
+.oo-ui-messageDialog-actions-horizontal .oo-ui-actionWidget:first-child > .oo-ui-buttonElement-button:hover {
+  border-left-color: #aaa;
 }
-.oo-ui-messageDialog-actions .oo-ui-actionWidget:last-child {
-  margin-right: 0;
+.oo-ui-messageDialog-actions-horizontal .oo-ui-actionWidget:first-child > .oo-ui-buttonElement-button:focus {
+  border-left-color: #ace;
 }
-.oo-ui-messageDialog-actions .oo-ui-actionWidget:hover {
-  background-color: rgba(0, 0, 0, 0.05);
+.oo-ui-messageDialog-actions-horizontal .oo-ui-actionWidget:last-child > .oo-ui-buttonElement-button {
+  border-right-width: 2px;
+  border-right-color: transparent;
+  border-radius: 0 0 3px 0;
 }
-.oo-ui-messageDialog-actions .oo-ui-actionWidget:active {
-  background-color: rgba(0, 0, 0, 0.1);
+.oo-ui-messageDialog-actions-horizontal .oo-ui-actionWidget:last-child > .oo-ui-buttonElement-button:hover {
+  border-right-color: #aaa;
 }
-.oo-ui-messageDialog-actions .oo-ui-actionWidget .oo-ui-buttonElement-button {
-  padding: 0;
+.oo-ui-messageDialog-actions-horizontal .oo-ui-actionWidget:last-child > .oo-ui-buttonElement-button:focus {
+  border-right-color: #ace;
 }
-.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-labelElement .oo-ui-labelElement-label {
-  text-align: center;
-  line-height: 3.4em;
+.oo-ui-messageDialog-actions-horizontal .oo-ui-actionWidget:only-child > .oo-ui-buttonElement-button {
+  border-radius: 0 0 3px 3px;
 }
-.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-progressive:hover {
-  background-color: rgba(8, 126, 204, 0.05);
+@supports ( width: calc( 100% + 2px ) ) {
+  .oo-ui-messageDialog-actions-horizontal {
+    width: calc(100% + 2px);
+    margin-left: -1px;
+    margin-right: -1px;
+  }
 }
-.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-progressive:active {
-  background-color: rgba(8, 126, 204, 0.1);
+.oo-ui-messageDialog-actions-vertical .oo-ui-actionWidget {
+  margin: -1px 0 0;
+  border-bottom: 1px solid #e5e5e5;
 }
-.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-progressive .oo-ui-labelElement-label {
-  font-weight: bold;
+.oo-ui-messageDialog-actions-vertical .oo-ui-actionWidget:first-child {
+  margin-top: 0;
 }
-.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-destructive:hover {
-  background-color: rgba(212, 83, 83, 0.05);
+.oo-ui-messageDialog-actions-vertical .oo-ui-actionWidget:last-child {
+  border-bottom-width: 0;
 }
-.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-destructive:active {
-  background-color: rgba(212, 83, 83, 0.1);
+.oo-ui-messageDialog-actions-vertical .oo-ui-actionWidget > .oo-ui-buttonElement-button {
+  border-radius: 0;
+}
+.oo-ui-messageDialog-actions-vertical .oo-ui-actionWidget:last-child > .oo-ui-buttonElement-button {
+  border-radius: 0 0 3px 3px;
 }
 .oo-ui-processDialog-location {
   overflow: hidden;
   padding: 1em;
   border: 1px solid #ff9e9e;
   background-color: #fff7f7;
-  border-radius: 0.25em;
+  border-radius: 3px;
 }
 .oo-ui-windowManager-modal > .oo-ui-dialog {
   position: fixed;
   left: 0;
   padding: 1em;
 }
-.oo-ui-windowManager-modal > .oo-ui-dialog.oo-ui-window-setup > .oo-ui-window-frame {
+.oo-ui-windowManager-modal > .oo-ui-dialog.oo-ui-window-active > .oo-ui-window-frame {
   position: absolute;
   right: 0;
   left: 0;
 .oo-ui-windowManager-modal > .oo-ui-dialog.oo-ui-window-setup {
   opacity: 1;
 }
-.oo-ui-windowManager-modal > .oo-ui-dialog.oo-ui-window-ready > .oo-ui-window-frame {
+.oo-ui-windowManager-modal > .oo-ui-dialog.oo-ui-window-setup > .oo-ui-window-frame {
   opacity: 1;
   -webkit-transform: scale(1);
   -moz-transform: scale(1);
index ad72e90..0421f4a 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOUI v0.27.0
+ * OOUI v0.27.5
  * https://www.mediawiki.org/wiki/OOUI
  *
  * Copyright 2011–2018 OOUI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2018-05-09T00:44:50Z
+ * Date: 2018-07-11T18:13:08Z
  */
 /**
  * WikimediaUI Base v0.10.0
 .oo-ui-messageDialog-title,
 .oo-ui-messageDialog-message {
   display: block;
+  line-height: 1.42857143em;
   text-align: center;
 }
-.oo-ui-messageDialog-title.oo-ui-labelElement,
-.oo-ui-messageDialog-message.oo-ui-labelElement {
-  padding-top: 0.5em;
-}
 .oo-ui-messageDialog-title {
   font-size: 1.5em;
-  line-height: 1;
   color: #000;
 }
 .oo-ui-messageDialog-message {
   font-size: 1.1em;
-  line-height: 1.4;
   color: #222;
   text-align: left;
 }
-.oo-ui-messageDialog-actions-horizontal .oo-ui-actionWidget {
-  border-right: 1px solid #a2a9b1;
-  margin: 0;
-}
-.oo-ui-messageDialog-actions-horizontal .oo-ui-actionWidget:last-child {
-  border-right-width: 0;
-}
-.oo-ui-messageDialog-actions-vertical .oo-ui-actionWidget {
-  border-bottom: 1px solid #a2a9b1;
-  margin: 0;
-}
-.oo-ui-messageDialog-actions-vertical .oo-ui-actionWidget:last-child {
-  border-bottom-width: 0;
-}
 .oo-ui-messageDialog-actions .oo-ui-actionWidget {
-  min-height: 3.14285714em;
+  min-height: 2.85714286em;
   margin-right: 0;
 }
 .oo-ui-messageDialog-actions .oo-ui-actionWidget:last-child {
   padding: 0;
 }
 .oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-labelElement .oo-ui-labelElement-label {
-  line-height: 3.14285714em;
+  line-height: 2.85714286em;
   text-align: center;
 }
-.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-widget-enabled .oo-ui-buttonElement-button:hover {
-  background-color: #f8f9fa;
+.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive .oo-ui-buttonElement-button:active {
+  background-color: rgba(8, 126, 204, 0.1);
 }
-.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-widget-enabled .oo-ui-buttonElement-button:active {
-  background-color: #c8ccd1;
+.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive .oo-ui-buttonElement-button:active {
+  background-color: rgba(212, 83, 83, 0.1);
 }
-.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-widget-enabled .oo-ui-buttonElement-button:focus {
-  box-shadow: inset 0 0 0 1px #36c, 0 0 0 1px #36c;
+.oo-ui-messageDialog-actions-horizontal .oo-ui-actionWidget {
+  border-right: 1px solid #a2a9b1;
+  margin: 0;
 }
-.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive .oo-ui-buttonElement-button:hover {
-  background-color: #eaf3ff;
+.oo-ui-messageDialog-actions-horizontal .oo-ui-actionWidget:first-child > .oo-ui-buttonElement-button {
+  border-radius: 0 0 0 2px;
 }
-.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive .oo-ui-buttonElement-button:active {
-  background-color: rgba(8, 126, 204, 0.1);
+.oo-ui-messageDialog-actions-horizontal .oo-ui-actionWidget:last-child {
+  border-right-width: 0;
 }
-.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive .oo-ui-labelElement-label {
-  font-weight: bold;
+.oo-ui-messageDialog-actions-horizontal .oo-ui-actionWidget:last-child > .oo-ui-buttonElement-button {
+  border-radius: 0 0 2px 0;
 }
-.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive .oo-ui-buttonElement-button:hover {
-  background-color: #fee7e6;
+.oo-ui-messageDialog-actions-horizontal .oo-ui-actionWidget:only-child > .oo-ui-buttonElement-button {
+  border-radius: 0 0 2px 2px;
 }
-.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive .oo-ui-buttonElement-button:active {
-  background-color: rgba(212, 83, 83, 0.1);
+.oo-ui-messageDialog-actions-vertical .oo-ui-actionWidget {
+  border-bottom: 1px solid #a2a9b1;
+  margin: 0;
+}
+.oo-ui-messageDialog-actions-vertical .oo-ui-actionWidget:last-child {
+  border-bottom-width: 0;
+}
+.oo-ui-messageDialog-actions-vertical .oo-ui-actionWidget:last-child > .oo-ui-buttonElement-button {
+  border-radius: 0 0 2px 2px;
 }
 .oo-ui-processDialog-location {
   overflow: hidden;
   left: 0;
   padding: 1em;
 }
-.oo-ui-windowManager-modal > .oo-ui-dialog.oo-ui-window-setup > .oo-ui-window-frame {
+.oo-ui-windowManager-modal > .oo-ui-dialog.oo-ui-window-active > .oo-ui-window-frame {
   position: absolute;
   right: 0;
   left: 0;
 .oo-ui-windowManager-modal > .oo-ui-dialog {
   background-color: rgba(255, 255, 255, 0.5);
   opacity: 0;
-  -webkit-transition: opacity 250ms;
-  -moz-transition: opacity 250ms;
-  transition: opacity 250ms;
+  -webkit-transition: opacity ease-out 250ms;
+  -moz-transition: opacity ease-out 250ms;
+  transition: opacity ease-out 250ms;
 }
 .oo-ui-windowManager-modal > .oo-ui-dialog > .oo-ui-window-frame {
   background-color: #fff;
   -moz-transform: scale(0.5);
   -ms-transform: scale(0.5);
   transform: scale(0.5);
-  -webkit-transition: all 250ms;
-  -moz-transition: all 250ms;
-  transition: all 250ms;
+  -webkit-transition: all ease-out 250ms;
+  -moz-transition: all ease-out 250ms;
+  transition: all ease-out 250ms;
 }
 .oo-ui-windowManager-modal > .oo-ui-dialog.oo-ui-window-setup {
   opacity: 1;
 }
-.oo-ui-windowManager-modal > .oo-ui-dialog.oo-ui-window-ready > .oo-ui-window-frame {
+.oo-ui-windowManager-modal > .oo-ui-dialog.oo-ui-window-setup > .oo-ui-window-frame {
   opacity: 1;
   -webkit-transform: scale(1);
   -moz-transform: scale(1);
index 099539e..01dac10 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOUI v0.27.0
+ * OOUI v0.27.5
  * https://www.mediawiki.org/wiki/OOUI
  *
  * Copyright 2011–2018 OOUI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2018-05-09T00:44:45Z
+ * Date: 2018-07-11T18:13:04Z
  */
 ( function ( OO ) {
 
@@ -1034,8 +1034,10 @@ OO.ui.WindowManager = function OoUiWindowManager( config ) {
        // Initialization
        this.$element
                .addClass( 'oo-ui-windowManager' )
-               .attr( 'aria-hidden', true )
                .toggleClass( 'oo-ui-windowManager-modal', this.modal );
+       if ( this.modal ) {
+               this.$element.attr( 'aria-hidden', true );
+       }
 };
 
 /* Setup */
@@ -1217,7 +1219,7 @@ OO.ui.WindowManager.prototype.getSetupDelay = function () {
  * @return {number} Milliseconds to wait
  */
 OO.ui.WindowManager.prototype.getReadyDelay = function () {
-       return 0;
+       return this.modal ? OO.ui.theme.getDialogTransitionDuration() : 0;
 };
 
 /**
@@ -1240,7 +1242,7 @@ OO.ui.WindowManager.prototype.getHoldDelay = function () {
  * @return {number} Milliseconds to wait
  */
 OO.ui.WindowManager.prototype.getTeardownDelay = function () {
-       return this.modal ? 250 : 0;
+       return this.modal ? OO.ui.theme.getDialogTransitionDuration() : 0;
 };
 
 /**
@@ -1374,7 +1376,6 @@ OO.ui.WindowManager.prototype.openWindow = function ( win, data, lifecycle, comp
                setTimeout( function () {
                        manager.compatOpened = $.Deferred();
                        win.setup( data ).then( function () {
-                               manager.updateWindowSize( win );
                                compatOpening.notify( { state: 'setup' } );
                                setTimeout( function () {
                                        win.ready( data ).then( function () {
@@ -2075,9 +2076,10 @@ OO.ui.Window.prototype.getDir = function () {
 /**
  * Get the 'setup' process.
  *
- * The setup process is used to set up a window for use in a particular context,
- * based on the `data` argument. This method is called during the opening phase of the window’s
- * lifecycle.
+ * The setup process is used to set up a window for use in a particular context, based on the `data`
+ * argument. This method is called during the opening phase of the window’s lifecycle (before the
+ * opening animation). You can add elements to the window in this process or set their default
+ * values.
  *
  * Override this method to add additional steps to the ‘setup’ process the parent method provides
  * using the {@link OO.ui.Process#first first} and {@link OO.ui.Process#next next} methods
@@ -2096,9 +2098,10 @@ OO.ui.Window.prototype.getSetupProcess = function () {
 /**
  * Get the ‘ready’ process.
  *
- * The ready process is used to ready a window for use in a particular
- * context, based on the `data` argument. This method is called during the opening phase of
- * the window’s lifecycle, after the window has been {@link #getSetupProcess setup}.
+ * The ready process is used to ready a window for use in a particular context, based on the `data`
+ * argument. This method is called during the opening phase of the window’s lifecycle, after the
+ * window has been {@link #getSetupProcess setup} (after the opening animation). You can focus
+ * elements in the window in this process, or open their dropdowns.
  *
  * Override this method to add additional steps to the ‘ready’ process the parent method
  * provides using the {@link OO.ui.Process#first first} and {@link OO.ui.Process#next next}
@@ -2114,9 +2117,10 @@ OO.ui.Window.prototype.getReadyProcess = function () {
 /**
  * Get the 'hold' process.
  *
- * The hold process is used to keep a window from being used in a particular context,
- * based on the `data` argument. This method is called during the closing phase of the window’s
- * lifecycle.
+ * The hold process is used to keep a window from being used in a particular context, based on the
+ * `data` argument. This method is called during the closing phase of the window’s lifecycle (before
+ * the closing animation). You can close dropdowns of elements in the window in this process, if
+ * they do not get closed automatically.
  *
  * Override this method to add additional steps to the 'hold' process the parent method provides
  * using the {@link OO.ui.Process#first first} and {@link OO.ui.Process#next next} methods
@@ -2132,9 +2136,10 @@ OO.ui.Window.prototype.getHoldProcess = function () {
 /**
  * Get the ‘teardown’ process.
  *
- * The teardown process is used to teardown a window after use. During teardown,
- * user interactions within the window are conveyed and the window is closed, based on the `data`
- * argument. This method is called during the closing phase of the window’s lifecycle.
+ * The teardown process is used to teardown a window after use. During teardown, user interactions
+ * within the window are conveyed and the window is closed, based on the `data` argument. This
+ * method is called during the closing phase of the window’s lifecycle (after the closing
+ * animation). You can remove elements in the window in this process or clear their values.
  *
  * Override this method to add additional steps to the ‘teardown’ process the parent method provides
  * using the {@link OO.ui.Process#first first} and {@link OO.ui.Process#next next} methods
@@ -2345,8 +2350,8 @@ OO.ui.Window.prototype.close = function ( data ) {
 /**
  * Setup window.
  *
- * This is called by OO.ui.WindowManager during window opening, and should not be called directly
- * by other systems.
+ * This is called by OO.ui.WindowManager during window opening (before the animation), and should
+ * not be called directly by other systems.
  *
  * @param {Object} [data] Window opening data
  * @return {jQuery.Promise} Promise resolved when window is setup
@@ -2360,6 +2365,7 @@ OO.ui.Window.prototype.setup = function ( data ) {
        this.$focusTraps.on( 'focus', this.focusTrapHandler );
 
        return this.getSetupProcess( data ).execute().then( function () {
+               win.updateSize();
                // Force redraw by asking the browser to measure the elements' widths
                win.$element.addClass( 'oo-ui-window-active oo-ui-window-setup' ).width();
                win.$content.addClass( 'oo-ui-window-content-setup' ).width();
@@ -2369,8 +2375,8 @@ OO.ui.Window.prototype.setup = function ( data ) {
 /**
  * Ready window.
  *
- * This is called by OO.ui.WindowManager during window opening, and should not be called directly
- * by other systems.
+ * This is called by OO.ui.WindowManager during window opening (after the animation), and should not
+ * be called directly by other systems.
  *
  * @param {Object} [data] Window opening data
  * @return {jQuery.Promise} Promise resolved when window is ready
@@ -2389,8 +2395,8 @@ OO.ui.Window.prototype.ready = function ( data ) {
 /**
  * Hold window.
  *
- * This is called by OO.ui.WindowManager during window closing, and should not be called directly
- * by other systems.
+ * This is called by OO.ui.WindowManager during window closing (before 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 held
@@ -2408,15 +2414,15 @@ OO.ui.Window.prototype.hold = function ( data ) {
                }
 
                // Force redraw by asking the browser to measure the elements' widths
-               win.$element.removeClass( 'oo-ui-window-ready' ).width();
-               win.$content.removeClass( 'oo-ui-window-content-ready' ).width();
+               win.$element.removeClass( 'oo-ui-window-ready oo-ui-window-setup' ).width();
+               win.$content.removeClass( 'oo-ui-window-content-ready oo-ui-window-content-setup' ).width();
        } );
 };
 
 /**
  * Teardown window.
  *
- * This is called by OO.ui.WindowManager during window closing, and should not be called directly
+ * 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
@@ -2427,8 +2433,8 @@ OO.ui.Window.prototype.teardown = function ( data ) {
 
        return this.getTeardownProcess( data ).execute().then( function () {
                // Force redraw by asking the browser to measure the elements' widths
-               win.$element.removeClass( 'oo-ui-window-active oo-ui-window-setup' ).width();
-               win.$content.removeClass( 'oo-ui-window-content-setup' ).width();
+               win.$element.removeClass( 'oo-ui-window-active' ).width();
+
                win.$focusTraps.off( 'focus', win.focusTrapHandler );
                win.toggle( false );
        } );
@@ -2709,13 +2715,35 @@ OO.ui.Dialog.prototype.initialize = function () {
 OO.ui.Dialog.prototype.getActionWidgets = function ( actions ) {
        var i, len, widgets = [];
        for ( i = 0, len = actions.length; i < len; i++ ) {
-               widgets.push(
-                       new OO.ui.ActionWidget( actions[ i ] )
-               );
+               widgets.push( this.getActionWidget( actions[ i ] ) );
        }
        return widgets;
 };
 
+/**
+ * Get action widget from config
+ *
+ * Override this method to change the action widget class used.
+ *
+ * @param {Object} config Action widget config
+ * @return {OO.ui.ActionWidget} Action widget
+ */
+OO.ui.Dialog.prototype.getActionWidget = function ( config ) {
+       return new OO.ui.ActionWidget( this.getActionWidgetConfig( config ) );
+};
+
+/**
+ * Get action widget config
+ *
+ * Override this method to modify the action widget config
+ *
+ * @param {Object} config Initial action widget config
+ * @return {Object} Action widget config
+ */
+OO.ui.Dialog.prototype.getActionWidgetConfig = function ( config ) {
+       return config;
+};
+
 /**
  * Attach action actions.
  *
@@ -3023,11 +3051,19 @@ OO.ui.MessageDialog.prototype.initialize = function () {
        this.$foot.append( this.$actions );
 };
 
+/**
+ * @inheritdoc
+ */
+OO.ui.MessageDialog.prototype.getActionWidgetConfig = function ( config ) {
+       // Force unframed
+       return $.extend( {}, config, { framed: false } );
+};
+
 /**
  * @inheritdoc
  */
 OO.ui.MessageDialog.prototype.attachActions = function () {
-       var i, len, other, special, others;
+       var i, len, special, others;
 
        // Parent method
        OO.ui.MessageDialog.parent.prototype.attachActions.call( this );
@@ -3037,18 +3073,15 @@ OO.ui.MessageDialog.prototype.attachActions = function () {
 
        if ( special.safe ) {
                this.$actions.append( special.safe.$element );
-               special.safe.toggleFramed( false );
+               special.safe.toggleFramed( true );
        }
-       if ( others.length ) {
-               for ( i = 0, len = others.length; i < len; i++ ) {
-                       other = others[ i ];
-                       this.$actions.append( other.$element );
-                       other.toggleFramed( false );
-               }
+       for ( i = 0, len = others.length; i < len; i++ ) {
+               this.$actions.append( others[ i ].$element );
+               others[ i ].toggleFramed( true );
        }
        if ( special.primary ) {
                this.$actions.append( special.primary.$element );
-               special.primary.toggleFramed( false );
+               special.primary.toggleFramed( true );
        }
 };
 
@@ -3068,7 +3101,7 @@ OO.ui.MessageDialog.prototype.fitActions = function () {
        this.toggleVerticalActionLayout( false );
        for ( i = 0, len = actions.length; i < len; i++ ) {
                action = actions[ i ];
-               if ( action.$element.innerWidth() < action.$label.outerWidth( true ) ) {
+               if ( action.$element[ 0 ].scrollWidth > action.$element[ 0 ].clientWidth ) {
                        this.toggleVerticalActionLayout( true );
                        break;
                }
@@ -3239,26 +3272,23 @@ OO.ui.ProcessDialog.prototype.initialize = function () {
 /**
  * @inheritdoc
  */
-OO.ui.ProcessDialog.prototype.getActionWidgets = function ( actions ) {
-       var i, len, config,
-               isMobile = OO.ui.isMobile(),
-               widgets = [];
-
-       for ( i = 0, len = actions.length; i < len; i++ ) {
-               config = $.extend( { framed: !OO.ui.isMobile() }, actions[ i ] );
-               if ( isMobile &&
-                       ( config.flags === 'back' || ( Array.isArray( config.flags ) && config.flags.indexOf( 'back' ) !== -1 ) )
-               ) {
-                       $.extend( config, {
-                               icon: 'previous',
-                               label: ''
-                       } );
-               }
-               widgets.push(
-                       new OO.ui.ActionWidget( config )
-               );
+OO.ui.ProcessDialog.prototype.getActionWidgetConfig = function ( config ) {
+       var isMobile = OO.ui.isMobile();
+
+       // Default to unframed on mobile
+       config = $.extend( { framed: !isMobile }, config );
+       // Change back buttons to icon only on mobile
+       if (
+               isMobile &&
+               ( config.flags === 'back' || ( Array.isArray( config.flags ) && config.flags.indexOf( 'back' ) !== -1 ) )
+       ) {
+               $.extend( config, {
+                       icon: 'previous',
+                       label: ''
+               } );
        }
-       return widgets;
+
+       return config;
 };
 
 /**
@@ -3575,4 +3605,4 @@ OO.ui.prompt = function ( text, options ) {
 
 }( OO ) );
 
-//# sourceMappingURL=oojs-ui-windows.js.map
\ No newline at end of file
+//# sourceMappingURL=oojs-ui-windows.js.map.json
\ No newline at end of file
diff --git a/resources/lib/oojs-ui/oojs-ui-windows.js.map b/resources/lib/oojs-ui/oojs-ui-windows.js.map
deleted file mode 100644 (file)
index 841b087..0000000
+++ /dev/null
@@ -1 +0,0 @@
-{"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 avaiable 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 *     $( '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 * @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 */\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 */\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 * @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 * @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 widets from the set.\n *\n * To remove only specified actions, use the {@link #method-remove remove} method instead.\n *\n * @chainable\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 */\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 jQuery ? 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 jQuery ?\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 jQuery ? 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 miliseconds 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 && $.isFunction( result.promise ) ) {\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' || $.isFunction( step.promise ) ) {\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 ( $.isFunction( step ) ) {\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 getHoldProces} 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.attr( 'aria-hidden', true )\n\t\t.toggleClass( 'oo-ui-windowManager-modal', this.modal );\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 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 ? 250 : 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/**\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|jQuery.Promise} 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\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\tmanager.updateWindowSize( win );\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|jQuery.Promise} 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 *     $( '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 */\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 */\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.css( {\n\t\t\t\t\toverflow: 'hidden',\n\t\t\t\t\t'margin-right': bodyMargin + scrollWidth\n\t\t\t\t} );\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.css( {\n\t\t\t\toverflow: '',\n\t\t\t\t'margin-right': ''\n\t\t\t} );\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 */\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 = $( '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 */\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 consistitutes 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,\n * based on the `data` argument. This method is called during the opening phase of the window’s\n * lifecycle.\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\n * context, based on the `data` argument. This method is called during the opening phase of\n * the window’s lifecycle, after the window has been {@link #getSetupProcess setup}.\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,\n * based on the `data` argument. This method is called during the closing phase of the window’s\n * lifecycle.\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,\n * user interactions within the window are conveyed and the window is closed, based on the `data`\n * argument. This method is called during the closing phase of the window’s lifecycle.\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 */\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 */\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 */\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 */\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 */\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.focus();\n\t}\n};\n\n/**\n * Open the window.\n *\n * This method is a wrapper around a call to the window manager’s {@link OO.ui.WindowManager#openWindow openWindow}\n * method, which returns a promise resolved when the window is done opening.\n *\n * To customize the window each time it opens, use #getSetupProcess or #getReadyProcess.\n *\n * @param {Object} [data] Window opening data\n * @return {jQuery.Promise} Promise resolved with a value when the window is opened, or rejected\n *  if the window fails to open. When the promise is resolved successfully, the first argument of the\n *  value is a new promise, which is resolved when the window begins closing.\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 * which returns a closing promise resolved when the window is done closing.\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 {jQuery.Promise} Promise resolved when window is closed\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, and should not be called directly\n * 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\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, and should not be called directly\n * 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.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, 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 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' ).width();\n\t\twin.$content.removeClass( 'oo-ui-window-content-ready' ).width();\n\t} );\n};\n\n/**\n * Teardown window.\n *\n * This is called by OO.ui.WindowManager during window closing, 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 oo-ui-window-setup' ).width();\n\t\twin.$content.removeClass( 'oo-ui-window-content-setup' ).width();\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 *     $( '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(\n\t\t\tnew OO.ui.ActionWidget( actions[ i ] )\n\t\t);\n\t}\n\treturn widgets;\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 */\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\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 *     $( '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 */\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.attachActions = function () {\n\tvar i, len, other, 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( false );\n\t}\n\tif ( others.length ) {\n\t\tfor ( i = 0, len = others.length; i < len; i++ ) {\n\t\t\tother = others[ i ];\n\t\t\tthis.$actions.append( other.$element );\n\t\t\tother.toggleFramed( false );\n\t\t}\n\t}\n\tif ( special.primary ) {\n\t\tthis.$actions.append( special.primary.$element );\n\t\tspecial.primary.toggleFramed( false );\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.innerWidth() < action.$label.outerWidth( true ) ) {\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 *     $( '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\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.getActionWidgets = function ( actions ) {\n\tvar i, len, config,\n\t\tisMobile = OO.ui.isMobile(),\n\t\twidgets = [];\n\n\tfor ( i = 0, len = actions.length; i < len; i++ ) {\n\t\tconfig = $.extend( { framed: !OO.ui.isMobile() }, actions[ i ] );\n\t\tif ( isMobile &&\n\t\t\t( config.flags === 'back' || ( Array.isArray( config.flags ) && config.flags.indexOf( 'back' ) !== -1 ) )\n\t\t) {\n\t\t\t$.extend( config, {\n\t\t\t\ticon: 'previous',\n\t\t\t\tlabel: ''\n\t\t\t} );\n\t\t}\n\t\twidgets.push(\n\t\t\tnew OO.ui.ActionWidget( config )\n\t\t);\n\t}\n\treturn widgets;\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 */\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$( '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
diff --git a/resources/lib/oojs-ui/oojs-ui-windows.js.map.json b/resources/lib/oojs-ui/oojs-ui-windows.js.map.json
new file mode 100644 (file)
index 0000000..a1bc41f
--- /dev/null
@@ -0,0 +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 avaiable 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 *     $( '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 * @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 */\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 */\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 * @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 * @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 widets from the set.\n *\n * To remove only specified actions, use the {@link #method-remove remove} method instead.\n *\n * @chainable\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 */\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 jQuery ? 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 jQuery ?\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 jQuery ? 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 miliseconds 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 && $.isFunction( result.promise ) ) {\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' || $.isFunction( step.promise ) ) {\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 ( $.isFunction( step ) ) {\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 getHoldProces} 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/**\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|jQuery.Promise} 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\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|jQuery.Promise} 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 *     $( '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 */\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 */\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.css( {\n\t\t\t\t\toverflow: 'hidden',\n\t\t\t\t\t'margin-right': bodyMargin + scrollWidth\n\t\t\t\t} );\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.css( {\n\t\t\t\toverflow: '',\n\t\t\t\t'margin-right': ''\n\t\t\t} );\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 */\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 = $( '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 */\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 consistitutes 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 */\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 */\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 */\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 */\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 */\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.focus();\n\t}\n};\n\n/**\n * Open the window.\n *\n * This method is a wrapper around a call to the window manager’s {@link OO.ui.WindowManager#openWindow openWindow}\n * method, which returns a promise resolved when the window is done opening.\n *\n * To customize the window each time it opens, use #getSetupProcess or #getReadyProcess.\n *\n * @param {Object} [data] Window opening data\n * @return {jQuery.Promise} Promise resolved with a value when the window is opened, or rejected\n *  if the window fails to open. When the promise is resolved successfully, the first argument of the\n *  value is a new promise, which is resolved when the window begins closing.\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 * which returns a closing promise resolved when the window is done closing.\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 {jQuery.Promise} Promise resolved when window is closed\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.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 *     $( '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 */\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\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 *     $( '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 */\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 *     $( '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\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 */\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$( '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
index f83a326..9d30efb 100644 (file)
@@ -26,6 +26,7 @@
                                "lang": {
                                        "ar": "../wikimediaui/images/icons/bold-arab-ain.svg",
                                        "be": "../wikimediaui/images/icons/bold-cyrl-te.svg",
+                                       "ce": "../wikimediaui/images/icons/bold-cyrl-palochka.svg",
                                        "cs,en,he,ml,pl,sco": "../wikimediaui/images/icons/bold-b.svg",
                                        "da,de,hu,ksh,nn,no,sv": "../wikimediaui/images/icons/bold-f.svg",
                                        "es,gl,pt": "../wikimediaui/images/icons/bold-n.svg",
@@ -49,7 +50,7 @@
                                "lang": {
                                        "ar": "../wikimediaui/images/icons/italic-arab-meem.svg",
                                        "cs,en,fr,he,ml,pl,pt,sco": "../wikimediaui/images/icons/italic-i.svg",
-                                       "be,da,de,fi,ky,nn,no,os,sv,ru,uk": "../wikimediaui/images/icons/italic-k.svg",
+                                       "be,ce,da,de,fi,ky,nn,no,os,sv,ru,uk": "../wikimediaui/images/icons/italic-k.svg",
                                        "es,gl,it,nl": "../wikimediaui/images/icons/italic-c.svg",
                                        "eu": "../wikimediaui/images/icons/italic-e.svg",
                                        "fa": "../wikimediaui/images/icons/italic-arab-keheh-jeem.svg",
index e54ea23..3e07e80 100644 (file)
@@ -43,6 +43,7 @@
                                "lang": {
                                        "ar": "images/icons/bold-arab-ain.svg",
                                        "be": "images/icons/bold-cyrl-te.svg",
+                                       "ce": "images/icons/bold-cyrl-palochka.svg",
                                        "cs,en,he,ml,pl,sco": "images/icons/bold-b.svg",
                                        "da,de,hu,ksh,nn,no,sv": "images/icons/bold-f.svg",
                                        "es,gl,pt": "images/icons/bold-n.svg",
@@ -66,7 +67,7 @@
                                "lang": {
                                        "ar": "images/icons/italic-arab-meem.svg",
                                        "cs,en,fr,he,ml,pl,pt,sco": "images/icons/italic-i.svg",
-                                       "be,da,de,fi,ky,nn,no,os,sv,ru,uk": "images/icons/italic-k.svg",
+                                       "be,ce,da,de,fi,ky,nn,no,os,sv,ru,uk": "images/icons/italic-k.svg",
                                        "es,gl,it,nl": "images/icons/italic-c.svg",
                                        "eu": "images/icons/italic-e.svg",
                                        "fa": "images/icons/italic-arab-keheh-jeem.svg",
index 337e86a..0b09ec1 100644 (file)
                        "deprecated": "Renamed since v0.27.0, use 'pageSettings' instead."
                },
                "subtract": {
-                       "file": "images/icons/subtract.svg"
+                       "file": "images/icons/subtract.svg",
+                       "variants": [ "destructive" ]
                }
        }
 }
diff --git a/resources/lib/oojs-ui/themes/wikimediaui/images/icons/bold-cyrl-palochka-invert.png b/resources/lib/oojs-ui/themes/wikimediaui/images/icons/bold-cyrl-palochka-invert.png
new file mode 100644 (file)
index 0000000..8c1a107
Binary files /dev/null and b/resources/lib/oojs-ui/themes/wikimediaui/images/icons/bold-cyrl-palochka-invert.png differ
diff --git a/resources/lib/oojs-ui/themes/wikimediaui/images/icons/bold-cyrl-palochka-invert.svg b/resources/lib/oojs-ui/themes/wikimediaui/images/icons/bold-cyrl-palochka-invert.svg
new file mode 100644 (file)
index 0000000..133906f
--- /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>bold</title><path d="M14 3v1l-1.7.1-.3.3v11.2l.3.3 1.7.1v1H6v-1l1.7-.1.3-.3V4.4l-.3-.3L6 4V3z"/></g></svg>
\ No newline at end of file
diff --git a/resources/lib/oojs-ui/themes/wikimediaui/images/icons/bold-cyrl-palochka-progressive.png b/resources/lib/oojs-ui/themes/wikimediaui/images/icons/bold-cyrl-palochka-progressive.png
new file mode 100644 (file)
index 0000000..119e655
Binary files /dev/null and b/resources/lib/oojs-ui/themes/wikimediaui/images/icons/bold-cyrl-palochka-progressive.png differ
diff --git a/resources/lib/oojs-ui/themes/wikimediaui/images/icons/bold-cyrl-palochka-progressive.svg b/resources/lib/oojs-ui/themes/wikimediaui/images/icons/bold-cyrl-palochka-progressive.svg
new file mode 100644 (file)
index 0000000..5ecc5fa
--- /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>bold</title><path d="M14 3v1l-1.7.1-.3.3v11.2l.3.3 1.7.1v1H6v-1l1.7-.1.3-.3V4.4l-.3-.3L6 4V3z"/></g></svg>
\ No newline at end of file
diff --git a/resources/lib/oojs-ui/themes/wikimediaui/images/icons/bold-cyrl-palochka.png b/resources/lib/oojs-ui/themes/wikimediaui/images/icons/bold-cyrl-palochka.png
new file mode 100644 (file)
index 0000000..f015dfc
Binary files /dev/null and b/resources/lib/oojs-ui/themes/wikimediaui/images/icons/bold-cyrl-palochka.png differ
diff --git a/resources/lib/oojs-ui/themes/wikimediaui/images/icons/bold-cyrl-palochka.svg b/resources/lib/oojs-ui/themes/wikimediaui/images/icons/bold-cyrl-palochka.svg
new file mode 100644 (file)
index 0000000..fcc4580
--- /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>bold</title><path d="M14 3v1l-1.7.1-.3.3v11.2l.3.3 1.7.1v1H6v-1l1.7-.1.3-.3V4.4l-.3-.3L6 4V3z"/></svg>
\ No newline at end of file
diff --git a/resources/lib/oojs-ui/themes/wikimediaui/images/icons/subtract-destructive.png b/resources/lib/oojs-ui/themes/wikimediaui/images/icons/subtract-destructive.png
new file mode 100644 (file)
index 0000000..75f1666
Binary files /dev/null and b/resources/lib/oojs-ui/themes/wikimediaui/images/icons/subtract-destructive.png differ
diff --git a/resources/lib/oojs-ui/themes/wikimediaui/images/icons/subtract-destructive.svg b/resources/lib/oojs-ui/themes/wikimediaui/images/icons/subtract-destructive.svg
new file mode 100644 (file)
index 0000000..7a048ea
--- /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="#d33"><title>subtract</title><path d="M4 9h12v2H4z"/></g></svg>
\ No newline at end of file
index ec14576..b99230a 100644 (file)
@@ -71,7 +71,7 @@ $ git remote update
 $ git checkout -B release -t origin/master
 
 # Ensure tests pass
-$ npm install && npm test
+$ npm install-test
 
 # Avoid using "npm version patch" because that creates
 # both a commit and a tag, and we shouldn't tag until after
index b51c5d1..3f400cd 100644 (file)
@@ -1,17 +1,18 @@
 /*!
- * OOjs v2.2.0 optimised for jQuery
+ * OOjs v2.2.2 optimised for jQuery
  * https://www.mediawiki.org/wiki/OOjs
  *
  * Copyright 2011-2018 OOjs Team and other contributors.
  * Released under the MIT license
  * https://oojs.mit-license.org
  *
- * Date: 2018-04-03T19:45:13Z
+ * Date: 2018-06-14T20:13:14Z
  */
 ( function ( global ) {
 
 'use strict';
 
+/* exported toString */
 var
        /**
         * Namespace for all classes, static methods and static properties.
@@ -21,8 +22,6 @@ var
        oo = {},
        // Optimisation: Local reference to Object.prototype.hasOwnProperty
        hasOwn = oo.hasOwnProperty,
-       // Marking this as "exported" doesn't work when parserOptions.sourceType is module
-       // eslint-disable-next-line no-unused-vars
        toString = oo.toString;
 
 /* Class Methods */
index 552c0c3..64d394c 100644 (file)
                if ( ts.collationTable ) {
                        // Build array of key names
                        for ( key in ts.collationTable ) {
-                               // Check hasOwn to be safe
-                               if ( ts.collationTable.hasOwnProperty( key ) ) {
-                                       keys.push( mw.RegExp.escape( key ) );
-                               }
+                               keys.push( mw.RegExp.escape( key ) );
                        }
                        if ( keys.length ) {
                                ts.collationRegex = new RegExp( keys.join( '|' ), 'ig' );
index 3bea471..ce24b0d 100644 (file)
@@ -8,10 +8,7 @@ table.jquery-tablesorter {
                cursor: pointer;
                background-repeat: no-repeat;
                background-position: center right;
-               // Note: To avoid reflows, a padding is set in
-               // the jquery.tableSorter.styles module as a render blocking style.
-               // Please do not add any CSS rules here that impact the positioning of the element
-               // e.g. padding, margin, position or float.
+               padding-right: 21px;
        }
 
        th.headerSortUp {
index 2738d1a..186ad17 100644 (file)
                        // we can trim the previous one).
                        // See https://www.w3.org/TR/DOM-Level-3-Events/#events-keyboard-event-order for
                        // the order and characteristics of the key events.
-                       $el.on( eventKeys, function () {
+
+                       function enforceLimit() {
                                var res = trimFn(
                                        prevSafeVal,
                                        this.value,
                                // trimFn to compare the new value to an empty string instead of the
                                // old value, resulting in trimming always from the end (T42850).
                                prevSafeVal = res.newVal;
+                       }
+
+                       $el.on( eventKeys, function ( e ) {
+                               if ( e.type === 'cut' || e.type === 'paste' ) {
+                                       // For 'cut'/'paste', the input value is only updated after the event handlers resolve.
+                                       setTimeout( enforceLimit.bind( this ) );
+                               } else {
+                                       enforceLimit.call( this );
+                               }
                        } );
                } );
        }
index eb42311..082603a 100644 (file)
                options = options || {};
 
                this.each( function () {
-                       var $collapsible, collapseText, expandText, $caption, $toggle, actionHandler, buildDefaultToggleLink,
-                               $toggleLink, $firstItem, collapsibleId, $customTogglers, firstval;
+                       var $collapsible, collapseText, expandText, $caption, $toggle, actionHandler,
+                               buildDefaultToggleLink, $firstItem, collapsibleId, $customTogglers, firstval;
 
                        // Ensure class "mw-collapsible" is present in case .makeCollapsible()
                        // is called on element(s) that don't have it yet.
                                        .attr( {
                                                role: 'button',
                                                tabindex: 0
-                                       } )
-                                       .on( 'click.mw-collapsible keypress.mw-collapsible', actionHandler );
+                                       } );
                        };
 
                        // Check if this element has a custom position for the toggle link
                                        togglingHandler( $( this ), $collapsible, e, opts );
                                };
 
-                               $toggleLink = $customTogglers
-                                       .on( 'click.mw-collapsible keypress.mw-collapsible', actionHandler )
-                                       .prop( 'tabIndex', 0 );
+                               $toggle = $customTogglers;
 
                        } else {
                                // If this is not a custom case, do the default: wrap the
 
                                                // If there is no toggle link, add it to the end of the caption
                                                if ( !$toggle.length ) {
-                                                       $toggleLink = buildDefaultToggleLink().appendTo( $caption );
-                                               } else {
-                                                       $toggleLink = $toggle.on( 'click.mw-collapsible keypress.mw-collapsible', actionHandler )
-                                                               .prop( 'tabIndex', 0 );
+                                                       $toggle = buildDefaultToggleLink().appendTo( $caption );
                                                }
                                        } else {
                                                // The toggle-link will be in one of the cells (td or th) of the first row
 
                                                // If theres no toggle link, add it to the last cell
                                                if ( !$toggle.length ) {
-                                                       $toggleLink = buildDefaultToggleLink().prependTo( $firstItem.eq( -1 ) );
-                                               } else {
-                                                       $toggleLink = $toggle.on( 'click.mw-collapsible keypress.mw-collapsible', actionHandler )
-                                                               .prop( 'tabIndex', 0 );
+                                                       $toggle = buildDefaultToggleLink().prependTo( $firstItem.eq( -1 ) );
                                                }
                                        }
 
                                        $collapsible.find( '> .mw-collapsible-toggle' ).length === 0
                                ) {
                                        // special case of one collapsible in <li> tag
-                                       $toggleLink = buildDefaultToggleLink();
-                                       $collapsible.before( $toggleLink );
+                                       $toggle = buildDefaultToggleLink();
+                                       $collapsible.before( $toggle );
                                } else if ( $collapsible.is( 'ul' ) || $collapsible.is( 'ol' ) ) {
                                        // The toggle-link will be in the first list-item
                                        $firstItem = $collapsible.find( 'li:first' );
                                                if ( firstval === undefined || !firstval || firstval === '-1' || firstval === -1 ) {
                                                        $firstItem.prop( 'value', '1' );
                                                }
-                                               $toggleLink = buildDefaultToggleLink();
-                                               $toggleLink.wrap( '<li class="mw-collapsible-toggle-li"></li>' ).parent().prependTo( $collapsible );
-                                       } else {
-                                               $toggleLink = $toggle.on( 'click.mw-collapsible keypress.mw-collapsible', actionHandler )
-                                                       .prop( 'tabIndex', 0 );
+                                               $toggle = buildDefaultToggleLink();
+                                               $toggle.wrap( '<li class="mw-collapsible-toggle-li"></li>' ).parent().prependTo( $collapsible );
                                        }
 
                                } else { // <div>, <p> etc.
 
                                        // If theres no toggle link, add it
                                        if ( !$toggle.length ) {
-                                               $toggleLink = buildDefaultToggleLink().prependTo( $collapsible );
-                                       } else {
-                                               $toggleLink = $toggle.on( 'click.mw-collapsible keypress.mw-collapsible', actionHandler )
-                                                       .prop( 'tabIndex', 0 );
+                                               $toggle = buildDefaultToggleLink().prependTo( $collapsible );
                                        }
                                }
                        }
 
+                       // Attach event handlers to togglelink
+                       $toggle.on( 'click.mw-collapsible keypress.mw-collapsible', actionHandler )
+                               .prop( 'tabIndex', 0 );
+
                        $( this ).data( 'mw-collapsible', {
                                collapse: function () {
-                                       actionHandler.call( $toggleLink.get( 0 ), null, { wasCollapsed: false } );
+                                       actionHandler.call( $toggle.get( 0 ), null, { wasCollapsed: false } );
                                },
                                expand: function () {
-                                       actionHandler.call( $toggleLink.get( 0 ), null, { wasCollapsed: true } );
+                                       actionHandler.call( $toggle.get( 0 ), null, { wasCollapsed: true } );
                                },
                                toggle: function () {
-                                       actionHandler.call( $toggleLink.get( 0 ), null, null );
+                                       actionHandler.call( $toggle.get( 0 ), null, null );
                                }
                        } );
 
                        if ( options.collapsed || $collapsible.hasClass( 'mw-collapsed' ) ) {
                                // One toggler can hook to multiple elements, and one element can have
                                // multiple togglers. This is the sanest way to handle that.
-                               actionHandler.call( $toggleLink.get( 0 ), null, { wasCollapsed: false } );
+                               actionHandler.call( $toggle.get( 0 ), null, { wasCollapsed: false } );
                        }
 
                } );
diff --git a/resources/src/jquery/jquery.tablesorter.styles.less b/resources/src/jquery/jquery.tablesorter.styles.less
deleted file mode 100644 (file)
index eda939d..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-.client-js {
-       // Reserve space for table sortable controls
-       table.sortable > thead > tr > th:not( .unsortable ) {
-               padding-right: 21px;
-       }
-}
index 7d4ed53..d38adcd 100644 (file)
         * @inheritdoc
         */
        mw.ForeignStructuredUpload.BookletLayout.prototype.getText = function () {
-               var language = mw.config.get( 'wgContentLanguage' );
+               var language = mw.config.get( 'wgContentLanguage' ),
+                       categories = this.categoriesWidget.getItems().map( function ( item ) {
+                               return item.data;
+                       } );
                this.upload.clearDescriptions();
                this.upload.addDescription( language, this.descriptionWidget.getValue() );
                this.upload.setDate( this.dateWidget.getValue() );
                this.upload.clearCategories();
-               this.upload.addCategories( this.categoriesWidget.getItemsData() );
+               this.upload.addCategories( categories );
                return this.upload.getText();
        };
 
                mw.ForeignStructuredUpload.BookletLayout.parent.prototype.clear.call( this );
 
                this.ownWorkCheckbox.setSelected( false );
-               this.categoriesWidget.setItemsFromData( [] );
+               this.categoriesWidget.setValue( [] );
                this.dateWidget.setValue( '' ).setValidityFlag( true );
        };
 
index dcaae3e..c02af98 100644 (file)
                rWhitespace = /[ _\u00A0\u1680\u180E\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]+/g,
 
                // From MediaWikiTitleCodec::splitTitleString() in PHP
-               rStripCharacters = /[\u00AD\u061C\u200E\u200F\u202A-\u202E\u2066-\u2069]/g,
+               rUnicodeBidi = /[\u200E\u200F\u202A-\u202E]/g,
 
                /**
                 * Slightly modified from Flinfo. Credit goes to Lupo and Flominator.
                        namespace = defaultNamespace === undefined ? NS_MAIN : defaultNamespace;
 
                        title = title
-                               // Strip soft hyphens and Unicode directional formatting characters
-                               .replace( rStripCharacters, '' )
+                               // Strip Unicode bidi override characters
+                               .replace( rUnicodeBidi, '' )
                                // Normalise whitespace to underscores and remove duplicates
                                .replace( rWhitespace, '_' )
                                // Trim underscores
                                tiff: 'tif',
                                ogv: 'ogg'
                        };
-               if ( squish.hasOwnProperty( lower ) ) {
+               if ( Object.prototype.hasOwnProperty.call( squish, lower ) ) {
                        return squish[ lower ];
                } else if ( /^[0-9a-z]+$/.test( lower ) ) {
                        return lower;
index 72ce9f0..cb9c286 100644 (file)
@@ -4,9 +4,11 @@
        background-color: #eaecf0;
        background-size: cover;
        background-position: center center;
-       padding: 1.5em;
-       margin: -1.5em;
-       margin-bottom: 1.5em;
+       /* Same as padding on `.oo-ui-bookletLayout-stackLayout > .oo-ui-panelLayout`,
+        * equals 20px at default font size */
+       padding: 1.42857143em;
+       margin: -1.42857143em;
+       margin-bottom: 1.42857143em;
        position: relative;
 }
 
index 7f12835..eb7cff0 100644 (file)
@@ -50,8 +50,6 @@
  * @class mw.Uri
  */
 
-/* eslint-disable no-use-before-define */
-
 ( function ( mw, $ ) {
        var parser, properties;
 
                                        return uri;
                                }
                                href = hrefCur;
+                               // eslint-disable-next-line no-use-before-define
                                uri = new Uri( href );
                                return uri;
                        };
                                        // Copy data over from existing URI object
                                        for ( prop in uri ) {
                                                // Only copy direct properties, not inherited ones
-                                               if ( uri.hasOwnProperty( prop ) ) {
+                                               if ( Object.prototype.hasOwnProperty.call( uri, prop ) ) {
                                                        // Deep copy object properties
                                                        if ( Array.isArray( uri[ prop ] ) || $.isPlainObject( uri[ prop ] ) ) {
                                                                this[ prop ] = $.extend( true, {}, uri[ prop ] );
index 5ae91e8..1be0052 100644 (file)
@@ -1,7 +1,7 @@
 /*!
  * Scripts for pre-emptive edit preparing on action=edit
  */
-/* eslint-disable no-use-before-define */
+
 ( function ( mw, $ ) {
        if ( !mw.config.get( 'wgAjaxEditStash' ) ) {
                return;
                        return;
                }
 
+               // Whether the body text content changed since the last stashEdit()
+               function isTextChanged() {
+                       return lastText !== $text.textSelection( 'getContents' );
+               }
+
+               // Whether the edit summary has changed since the last stashEdit()
+               function isSummaryChanged() {
+                       return lastSummary !== $summary.textSelection( 'getContents' );
+               }
+
                // Send a request to stash the edit to the API.
                // If a request is in progress, abort it since its payload is stale and the API
                // may limit concurrent stash parses.
@@ -43,6 +53,7 @@
                        if ( stashReq ) {
                                if ( lastPriority > priority ) {
                                        // Stash request for summary change should wait on pending text change stash
+                                       // eslint-disable-next-line no-use-before-define
                                        stashReq.then( checkStash );
                                        return;
                                }
                        } );
                }
 
-               // Whether the body text content changed since the last stashEdit()
-               function isTextChanged() {
-                       return lastText !== $text.textSelection( 'getContents' );
-               }
-
-               // Whether the edit summary has changed since the last stashEdit()
-               function isSummaryChanged() {
-                       return lastSummary !== $summary.textSelection( 'getContents' );
-               }
-
                // Check whether text or summary have changed and call stashEdit()
                function checkStash() {
                        if ( !isTextChanged() && !isSummaryChanged() ) {
index db81ff2..1367426 100644 (file)
@@ -60,7 +60,6 @@
 
        // Use buttonElement to include ButtonInputWidget and ButtonWidget
        .editButtons .oo-ui-buttonElement,
-       .cancelLink,
        .editHelp {
                margin-top: 0.5em;
        }
index 0038ed8..51f359c 100644 (file)
         *  each individual request by passing them to #get or #post (or directly #ajax) later on.
         */
        mw.Api = function ( options ) {
-               options = options || {};
+               var defaults = $.extend( {}, options ),
+                       setsUrl = options && options.ajax && options.ajax.url !== undefined;
+
+               defaults.parameters = $.extend( {}, defaultOptions.parameters, defaults.parameters );
+               defaults.ajax = $.extend( {}, defaultOptions.ajax, defaults.ajax );
 
                // Force a string if we got a mw.Uri object
-               if ( options.ajax && options.ajax.url !== undefined ) {
-                       options.ajax.url = String( options.ajax.url );
+               if ( setsUrl ) {
+                       defaults.ajax.url = String( defaults.ajax.url );
+               }
+               if ( defaults.useUS === undefined ) {
+                       defaults.useUS = !setsUrl;
                }
 
-               options = $.extend( { useUS: !options.ajax || !options.ajax.url }, options );
-
-               options.parameters = $.extend( {}, defaultOptions.parameters, options.parameters );
-               options.ajax = $.extend( {}, defaultOptions.ajax, options.ajax );
-
-               this.defaults = options;
+               this.defaults = defaults;
                this.requests = [];
        };
 
index 29bd59a..f343321 100644 (file)
@@ -40,9 +40,7 @@
        function getFirstKey( obj ) {
                var key;
                for ( key in obj ) {
-                       if ( obj.hasOwnProperty( key ) ) {
-                               return key;
-                       }
+                       return key;
                }
        }
 
diff --git a/resources/src/mediawiki.base/mediawiki.base.js b/resources/src/mediawiki.base/mediawiki.base.js
new file mode 100644 (file)
index 0000000..1c3dde6
--- /dev/null
@@ -0,0 +1,645 @@
+/*!
+ * This file is currently loaded as part of the 'mediawiki' module and therefore
+ * concatenated to mediawiki.js and executed at the same time. This file exists
+ * to help prepare for splitting up the 'mediawiki' module.
+ * This effort is tracked at https://phabricator.wikimedia.org/T192623
+ *
+ * In short:
+ *
+ * - mediawiki.js will be reduced to the minimum needed to define mw.loader and
+ *   mw.config, and then moved to its own private "mediawiki.loader" module that
+ *   can be embedded within the StartupModule response.
+ *
+ * - mediawiki.base.js and other files in this directory will remain part of the
+ *   "mediawiki" module, and will remain a default/implicit dependency for all
+ *   regular modules, just like jquery and wikibits already are.
+ */
+/* globals mw */
+( function () {
+       'use strict';
+
+       var slice = Array.prototype.slice,
+               mwLoaderTrack = mw.track,
+               trackCallbacks = $.Callbacks( 'memory' ),
+               trackHandlers = [],
+               hasOwn = Object.prototype.hasOwnProperty;
+
+       /**
+        * Object constructor for messages.
+        *
+        * Similar to the Message class in MediaWiki PHP.
+        *
+        * Format defaults to 'text'.
+        *
+        *     @example
+        *
+        *     var obj, str;
+        *     mw.messages.set( {
+        *         'hello': 'Hello world',
+        *         'hello-user': 'Hello, $1!',
+        *         'welcome-user': 'Welcome back to $2, $1! Last visit by $1: $3'
+        *     } );
+        *
+        *     obj = new mw.Message( mw.messages, 'hello' );
+        *     mw.log( obj.text() );
+        *     // Hello world
+        *
+        *     obj = new mw.Message( mw.messages, 'hello-user', [ 'John Doe' ] );
+        *     mw.log( obj.text() );
+        *     // Hello, John Doe!
+        *
+        *     obj = new mw.Message( mw.messages, 'welcome-user', [ 'John Doe', 'Wikipedia', '2 hours ago' ] );
+        *     mw.log( obj.text() );
+        *     // Welcome back to Wikipedia, John Doe! Last visit by John Doe: 2 hours ago
+        *
+        *     // Using mw.message shortcut
+        *     obj = mw.message( 'hello-user', 'John Doe' );
+        *     mw.log( obj.text() );
+        *     // Hello, John Doe!
+        *
+        *     // Using mw.msg shortcut
+        *     str = mw.msg( 'hello-user', 'John Doe' );
+        *     mw.log( str );
+        *     // Hello, John Doe!
+        *
+        *     // Different formats
+        *     obj = new mw.Message( mw.messages, 'hello-user', [ 'John "Wiki" <3 Doe' ] );
+        *
+        *     obj.format = 'text';
+        *     str = obj.toString();
+        *     // Same as:
+        *     str = obj.text();
+        *
+        *     mw.log( str );
+        *     // Hello, John "Wiki" <3 Doe!
+        *
+        *     mw.log( obj.escaped() );
+        *     // Hello, John &quot;Wiki&quot; &lt;3 Doe!
+        *
+        * @class mw.Message
+        *
+        * @constructor
+        * @param {mw.Map} map Message store
+        * @param {string} key
+        * @param {Array} [parameters]
+        */
+       function Message( map, key, parameters ) {
+               this.format = 'text';
+               this.map = map;
+               this.key = key;
+               this.parameters = parameters === undefined ? [] : slice.call( parameters );
+               return this;
+       }
+
+       Message.prototype = {
+               /**
+                * Get parsed contents of the message.
+                *
+                * The default parser does simple $N replacements and nothing else.
+                * This may be overridden to provide a more complex message parser.
+                * The primary override is in the mediawiki.jqueryMsg module.
+                *
+                * This function will not be called for nonexistent messages.
+                *
+                * @return {string} Parsed message
+                */
+               parser: function () {
+                       return mw.format.apply( null, [ this.map.get( this.key ) ].concat( this.parameters ) );
+               },
+
+               /**
+                * Add (does not replace) parameters for `$N` placeholder values.
+                *
+                * @param {Array} parameters
+                * @return {mw.Message}
+                * @chainable
+                */
+               params: function ( parameters ) {
+                       var i;
+                       for ( i = 0; i < parameters.length; i++ ) {
+                               this.parameters.push( parameters[ i ] );
+                       }
+                       return this;
+               },
+
+               /**
+                * Convert message object to its string form based on current format.
+                *
+                * @return {string} Message as a string in the current form, or `<key>` if key
+                *  does not exist.
+                */
+               toString: function () {
+                       var text;
+
+                       if ( !this.exists() ) {
+                               // Use ⧼key⧽ as text if key does not exist
+                               // Err on the side of safety, ensure that the output
+                               // is always html safe in the event the message key is
+                               // missing, since in that case its highly likely the
+                               // message key is user-controlled.
+                               // '⧼' is used instead of '<' to side-step any
+                               // double-escaping issues.
+                               // (Keep synchronised with Message::toString() in PHP.)
+                               return '⧼' + mw.html.escape( this.key ) + '⧽';
+                       }
+
+                       if ( this.format === 'plain' || this.format === 'text' || this.format === 'parse' ) {
+                               text = this.parser();
+                       }
+
+                       if ( this.format === 'escaped' ) {
+                               text = this.parser();
+                               text = mw.html.escape( text );
+                       }
+
+                       return text;
+               },
+
+               /**
+                * Change format to 'parse' and convert message to string
+                *
+                * If jqueryMsg is loaded, this parses the message text from wikitext
+                * (where supported) to HTML
+                *
+                * Otherwise, it is equivalent to plain.
+                *
+                * @return {string} String form of parsed message
+                */
+               parse: function () {
+                       this.format = 'parse';
+                       return this.toString();
+               },
+
+               /**
+                * Change format to 'plain' and convert message to string
+                *
+                * This substitutes parameters, but otherwise does not change the
+                * message text.
+                *
+                * @return {string} String form of plain message
+                */
+               plain: function () {
+                       this.format = 'plain';
+                       return this.toString();
+               },
+
+               /**
+                * Change format to 'text' and convert message to string
+                *
+                * If jqueryMsg is loaded, {{-transformation is done where supported
+                * (such as {{plural:}}, {{gender:}}, {{int:}}).
+                *
+                * Otherwise, it is equivalent to plain
+                *
+                * @return {string} String form of text message
+                */
+               text: function () {
+                       this.format = 'text';
+                       return this.toString();
+               },
+
+               /**
+                * Change the format to 'escaped' and convert message to string
+                *
+                * This is equivalent to using the 'text' format (see #text), then
+                * HTML-escaping the output.
+                *
+                * @return {string} String form of html escaped message
+                */
+               escaped: function () {
+                       this.format = 'escaped';
+                       return this.toString();
+               },
+
+               /**
+                * Check if a message exists
+                *
+                * @see mw.Map#exists
+                * @return {boolean}
+                */
+               exists: function () {
+                       return this.map.exists( this.key );
+               }
+       };
+
+       /**
+        * @class mw
+        * @singleton
+        */
+
+       /**
+        * @inheritdoc mw.inspect#runReports
+        * @method
+        */
+       mw.inspect = function () {
+               var args = arguments;
+               // Lazy-load
+               mw.loader.using( 'mediawiki.inspect', function () {
+                       mw.inspect.runReports.apply( mw.inspect, args );
+               } );
+       };
+
+       /**
+        * Format a string. Replace $1, $2 ... $N with positional arguments.
+        *
+        * Used by Message#parser().
+        *
+        * @since 1.25
+        * @param {string} formatString Format string
+        * @param {...Mixed} parameters Values for $N replacements
+        * @return {string} Formatted string
+        */
+       mw.format = function ( formatString ) {
+               var parameters = slice.call( arguments, 1 );
+               return formatString.replace( /\$(\d+)/g, function ( str, match ) {
+                       var index = parseInt( match, 10 ) - 1;
+                       return parameters[ index ] !== undefined ? parameters[ index ] : '$' + match;
+               } );
+       };
+
+       // Expose Message constructor
+       mw.Message = Message;
+
+       /**
+        * Get a message object.
+        *
+        * Shortcut for `new mw.Message( mw.messages, key, parameters )`.
+        *
+        * @see mw.Message
+        * @param {string} key Key of message to get
+        * @param {...Mixed} parameters Values for $N replacements
+        * @return {mw.Message}
+        */
+       mw.message = function ( key ) {
+               var parameters = slice.call( arguments, 1 );
+               return new Message( mw.messages, key, parameters );
+       };
+
+       /**
+        * Get a message string using the (default) 'text' format.
+        *
+        * Shortcut for `mw.message( key, parameters... ).text()`.
+        *
+        * @see mw.Message
+        * @param {string} key Key of message to get
+        * @param {...Mixed} parameters Values for $N replacements
+        * @return {string}
+        */
+       mw.msg = function () {
+               return mw.message.apply( mw.message, arguments ).toString();
+       };
+
+       /**
+        * Track an analytic event.
+        *
+        * This method provides a generic means for MediaWiki JavaScript code to capture state
+        * information for analysis. Each logged event specifies a string topic name that describes
+        * the kind of event that it is. Topic names consist of dot-separated path components,
+        * arranged from most general to most specific. Each path component should have a clear and
+        * well-defined purpose.
+        *
+        * Data handlers are registered via `mw.trackSubscribe`, and receive the full set of
+        * events that match their subcription, including those that fired before the handler was
+        * bound.
+        *
+        * @param {string} topic Topic name
+        * @param {Object} [data] Data describing the event, encoded as an object
+        */
+       mw.track = function ( topic, data ) {
+               mwLoaderTrack( topic, data );
+               trackCallbacks.fire( mw.trackQueue );
+       };
+
+       /**
+        * Register a handler for subset of analytic events, specified by topic.
+        *
+        * Handlers will be called once for each tracked event, including any events that fired before the
+        * handler was registered; 'this' is set to a plain object with a 'timeStamp' property indicating
+        * the exact time at which the event fired, a string 'topic' property naming the event, and a
+        * 'data' property which is an object of event-specific data. The event topic and event data are
+        * also passed to the callback as the first and second arguments, respectively.
+        *
+        * @param {string} topic Handle events whose name starts with this string prefix
+        * @param {Function} callback Handler to call for each matching tracked event
+        * @param {string} callback.topic
+        * @param {Object} [callback.data]
+        */
+       mw.trackSubscribe = function ( topic, callback ) {
+               var seen = 0;
+               function handler( trackQueue ) {
+                       var event;
+                       for ( ; seen < trackQueue.length; seen++ ) {
+                               event = trackQueue[ seen ];
+                               if ( event.topic.indexOf( topic ) === 0 ) {
+                                       callback.call( event, event.topic, event.data );
+                               }
+                       }
+               }
+
+               trackHandlers.push( [ handler, callback ] );
+
+               trackCallbacks.add( handler );
+       };
+
+       /**
+        * Stop handling events for a particular handler
+        *
+        * @param {Function} callback
+        */
+       mw.trackUnsubscribe = function ( callback ) {
+               trackHandlers = trackHandlers.filter( function ( fns ) {
+                       if ( fns[ 1 ] === callback ) {
+                               trackCallbacks.remove( fns[ 0 ] );
+                               // Ensure the tuple is removed to avoid holding on to closures
+                               return false;
+                       }
+                       return true;
+               } );
+       };
+
+       // Fire events from before track() triggred fire()
+       trackCallbacks.fire( mw.trackQueue );
+
+       /**
+        * Registry and firing of events.
+        *
+        * MediaWiki has various interface components that are extended, enhanced
+        * or manipulated in some other way by extensions, gadgets and even
+        * in core itself.
+        *
+        * This framework helps streamlining the timing of when these other
+        * code paths fire their plugins (instead of using document-ready,
+        * which can and should be limited to firing only once).
+        *
+        * Features like navigating to other wiki pages, previewing an edit
+        * and editing itself – without a refresh – can then retrigger these
+        * hooks accordingly to ensure everything still works as expected.
+        *
+        * Example usage:
+        *
+        *     mw.hook( 'wikipage.content' ).add( fn ).remove( fn );
+        *     mw.hook( 'wikipage.content' ).fire( $content );
+        *
+        * Handlers can be added and fired for arbitrary event names at any time. The same
+        * event can be fired multiple times. The last run of an event is memorized
+        * (similar to `$(document).ready` and `$.Deferred().done`).
+        * This means if an event is fired, and a handler added afterwards, the added
+        * function will be fired right away with the last given event data.
+        *
+        * Like Deferreds and Promises, the mw.hook object is both detachable and chainable.
+        * Thus allowing flexible use and optimal maintainability and authority control.
+        * You can pass around the `add` and/or `fire` method to another piece of code
+        * without it having to know the event name (or `mw.hook` for that matter).
+        *
+        *     var h = mw.hook( 'bar.ready' );
+        *     new mw.Foo( .. ).fetch( { callback: h.fire } );
+        *
+        * Note: Events are documented with an underscore instead of a dot in the event
+        * name due to jsduck not supporting dots in that position.
+        *
+        * @class mw.hook
+        */
+       mw.hook = ( function () {
+               var lists = {};
+
+               /**
+                * Create an instance of mw.hook.
+                *
+                * @method hook
+                * @member mw
+                * @param {string} name Name of hook.
+                * @return {mw.hook}
+                */
+               return function ( name ) {
+                       var list = hasOwn.call( lists, name ) ?
+                               lists[ name ] :
+                               lists[ name ] = $.Callbacks( 'memory' );
+
+                       return {
+                               /**
+                                * Register a hook handler
+                                *
+                                * @param {...Function} handler Function to bind.
+                                * @chainable
+                                */
+                               add: list.add,
+
+                               /**
+                                * Unregister a hook handler
+                                *
+                                * @param {...Function} handler Function to unbind.
+                                * @chainable
+                                */
+                               remove: list.remove,
+
+                               /**
+                                * Run a hook.
+                                *
+                                * @param {...Mixed} data
+                                * @return {mw.hook}
+                                * @chainable
+                                */
+                               fire: function () {
+                                       return list.fireWith.call( this, null, slice.call( arguments ) );
+                               }
+                       };
+               };
+       }() );
+
+       /**
+        * HTML construction helper functions
+        *
+        *     @example
+        *
+        *     var Html, output;
+        *
+        *     Html = mw.html;
+        *     output = Html.element( 'div', {}, new Html.Raw(
+        *         Html.element( 'img', { src: '<' } )
+        *     ) );
+        *     mw.log( output ); // <div><img src="&lt;"/></div>
+        *
+        * @class mw.html
+        * @singleton
+        */
+       mw.html = ( function () {
+               function escapeCallback( s ) {
+                       switch ( s ) {
+                               case '\'':
+                                       return '&#039;';
+                               case '"':
+                                       return '&quot;';
+                               case '<':
+                                       return '&lt;';
+                               case '>':
+                                       return '&gt;';
+                               case '&':
+                                       return '&amp;';
+                       }
+               }
+
+               return {
+                       /**
+                        * Escape a string for HTML.
+                        *
+                        * Converts special characters to HTML entities.
+                        *
+                        *     mw.html.escape( '< > \' & "' );
+                        *     // Returns &lt; &gt; &#039; &amp; &quot;
+                        *
+                        * @param {string} s The string to escape
+                        * @return {string} HTML
+                        */
+                       escape: function ( s ) {
+                               return s.replace( /['"<>&]/g, escapeCallback );
+                       },
+
+                       /**
+                        * Create an HTML element string, with safe escaping.
+                        *
+                        * @param {string} name The tag name.
+                        * @param {Object} [attrs] An object with members mapping element names to values
+                        * @param {string|mw.html.Raw|mw.html.Cdata|null} [contents=null] The contents of the element.
+                        *
+                        *  - string: Text to be escaped.
+                        *  - null: The element is treated as void with short closing form, e.g. `<br/>`.
+                        *  - this.Raw: The raw value is directly included.
+                        *  - this.Cdata: The raw value is directly included. An exception is
+                        *    thrown if it contains any illegal ETAGO delimiter.
+                        *    See <https://www.w3.org/TR/html401/appendix/notes.html#h-B.3.2>.
+                        * @return {string} HTML
+                        */
+                       element: function ( name, attrs, contents ) {
+                               var v, attrName, s = '<' + name;
+
+                               if ( attrs ) {
+                                       for ( attrName in attrs ) {
+                                               v = attrs[ attrName ];
+                                               // Convert name=true, to name=name
+                                               if ( v === true ) {
+                                                       v = attrName;
+                                                       // Skip name=false
+                                               } else if ( v === false ) {
+                                                       continue;
+                                               }
+                                               s += ' ' + attrName + '="' + this.escape( String( v ) ) + '"';
+                                       }
+                               }
+                               if ( contents === undefined || contents === null ) {
+                                       // Self close tag
+                                       s += '/>';
+                                       return s;
+                               }
+                               // Regular open tag
+                               s += '>';
+                               switch ( typeof contents ) {
+                                       case 'string':
+                                               // Escaped
+                                               s += this.escape( contents );
+                                               break;
+                                       case 'number':
+                                       case 'boolean':
+                                               // Convert to string
+                                               s += String( contents );
+                                               break;
+                                       default:
+                                               if ( contents instanceof this.Raw ) {
+                                                       // Raw HTML inclusion
+                                                       s += contents.value;
+                                               } else if ( contents instanceof this.Cdata ) {
+                                                       // CDATA
+                                                       if ( /<\/[a-zA-z]/.test( contents.value ) ) {
+                                                               throw new Error( 'mw.html.element: Illegal end tag found in CDATA' );
+                                                       }
+                                                       s += contents.value;
+                                               } else {
+                                                       throw new Error( 'mw.html.element: Invalid type of contents' );
+                                               }
+                               }
+                               s += '</' + name + '>';
+                               return s;
+                       },
+
+                       /**
+                        * Wrapper object for raw HTML passed to mw.html.element().
+                        *
+                        * @class mw.html.Raw
+                        * @constructor
+                        * @param {string} value
+                        */
+                       Raw: function ( value ) {
+                               this.value = value;
+                       },
+
+                       /**
+                        * Wrapper object for CDATA element contents passed to mw.html.element()
+                        *
+                        * @class mw.html.Cdata
+                        * @constructor
+                        * @param {string} value
+                        */
+                       Cdata: function ( value ) {
+                               this.value = value;
+                       }
+               };
+       }() );
+
+       /**
+        * Execute a function as soon as one or more required modules are ready.
+        *
+        * Example of inline dependency on OOjs:
+        *
+        *     mw.loader.using( 'oojs', function () {
+        *         OO.compare( [ 1 ], [ 1 ] );
+        *     } );
+        *
+        * Example of inline dependency obtained via `require()`:
+        *
+        *     mw.loader.using( [ 'mediawiki.util' ], function ( require ) {
+        *         var util = require( 'mediawiki.util' );
+        *     } );
+        *
+        * Since MediaWiki 1.23 this also returns a promise.
+        *
+        * Since MediaWiki 1.28 the promise is resolved with a `require` function.
+        *
+        * @member mw.loader
+        * @param {string|Array} dependencies Module name or array of modules names the
+        *  callback depends on to be ready before executing
+        * @param {Function} [ready] Callback to execute when all dependencies are ready
+        * @param {Function} [error] Callback to execute if one or more dependencies failed
+        * @return {jQuery.Promise} With a `require` function
+        */
+       mw.loader.using = function ( dependencies, ready, error ) {
+               var deferred = $.Deferred();
+
+               // Allow calling with a single dependency as a string
+               if ( typeof dependencies === 'string' ) {
+                       dependencies = [ dependencies ];
+               }
+
+               if ( ready ) {
+                       deferred.done( ready );
+               }
+               if ( error ) {
+                       deferred.fail( error );
+               }
+
+               try {
+                       // Resolve entire dependency map
+                       dependencies = mw.loader.resolve( dependencies );
+               } catch ( e ) {
+                       return deferred.reject( e ).promise();
+               }
+
+               mw.loader.enqueue( dependencies, function () {
+                       deferred.resolve( mw.loader.require );
+               }, deferred.reject );
+
+               return deferred.promise();
+       };
+
+       // 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.base/mediawiki.errorLogger.js b/resources/src/mediawiki.base/mediawiki.errorLogger.js
new file mode 100644 (file)
index 0000000..e86aff6
--- /dev/null
@@ -0,0 +1,58 @@
+/**
+ * Try to catch errors in modules which don't do their own error handling.
+ *
+ * @class mw.errorLogger
+ * @singleton
+ */
+( function ( mw ) {
+       'use strict';
+
+       mw.errorLogger = {
+               /**
+                * Fired via mw.track when an error is not handled by local code and is caught by the
+                * window.onerror handler.
+                *
+                * @event global_error
+                * @param {string} errorMessage Error errorMessage.
+                * @param {string} url URL where error was raised.
+                * @param {number} lineNumber Line number where error was raised.
+                * @param {number} [columnNumber] Line number where error was raised. Not all browsers
+                *   support this.
+                * @param {Error|Mixed} [errorObject] The error object. Typically an instance of Error, but anything
+                *   (even a primitive value) passed to a throw clause will end up here.
+                */
+
+               /**
+                * Install a window.onerror handler that will report via mw.track, while preserving
+                * any previous handler.
+                *
+                * @param {Object} window
+                */
+               installGlobalHandler: function ( window ) {
+                       // We will preserve the return value of the previous handler. window.onerror works the
+                       // opposite way than normal event handlers (returning true will prevent the default
+                       // action, returning false will let the browser handle the error normally, by e.g.
+                       // logging to the console), so our fallback old handler needs to return false.
+                       var oldHandler = window.onerror || function () { return false; };
+
+                       /**
+                        * Dumb window.onerror handler which forwards the errors via mw.track.
+                        *
+                        * @param {string} errorMessage
+                        * @param {string} url
+                        * @param {number} lineNumber
+                        * @param {number} [columnNumber]
+                        * @param {Error|Mixed} [errorObject]
+                        * @return {boolean} True to prevent the default action
+                        * @fires global_error
+                        */
+                       window.onerror = function ( errorMessage, url, lineNumber, columnNumber, errorObject ) {
+                               mw.track( 'global.error', { errorMessage: errorMessage, url: url,
+                                       lineNumber: lineNumber, columnNumber: columnNumber, errorObject: errorObject } );
+                               return oldHandler.apply( this, arguments );
+                       };
+               }
+       };
+
+       mw.errorLogger.installGlobalHandler( window );
+}( mediaWiki ) );
index 3f5a5db..37c0fac 100644 (file)
                        };
 
                        for ( id in panes ) {
-                               if ( !panes.hasOwnProperty( id ) ) {
-                                       continue;
-                               }
-
                                $( '<div>' )
                                        .prop( {
                                                className: 'mw-debug-pane',
                                        .appendTo( $table );
 
                                for ( key in data ) {
-                                       if ( !data.hasOwnProperty( key ) ) {
-                                               continue;
-                                       }
-
                                        $( '<tr>' )
                                                .append( $( '<th>' ).text( key ) )
                                                .append( $( '<td>' ).text( data[ key ] ) )
diff --git a/resources/src/mediawiki.hidpi/hidpi.js b/resources/src/mediawiki.hidpi/hidpi.js
deleted file mode 100644 (file)
index ecee450..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-jQuery( function ( $ ) {
-       // Apply hidpi images on DOM-ready
-       // Some may have already partly preloaded at low resolution.
-       $( 'body' ).hidpi();
-} );
diff --git a/resources/src/mediawiki.hidpi/skip.js b/resources/src/mediawiki.hidpi/skip.js
deleted file mode 100644 (file)
index 26b63c7..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-/*!
- * Skip function for mediawiki.hdpi.js.
- */
-return 'srcset' in new Image();
index 61a1c9c..0b56df1 100644 (file)
@@ -6,6 +6,8 @@
 
 @ooui-spacing-medium: 12 / @ooui-font-size-browser / @ooui-font-size-base; // equals `0.8571429em`≈`12px`
 @ooui-spacing-large: 16 / @ooui-font-size-browser / @ooui-font-size-base; // equals `1.1428571em`≈`16px`
+@ooui-padding-horizontal: 12 / @ooui-font-size-browser / @ooui-font-size-base;
+@ooui-padding-vertical: 4 / @ooui-font-size-browser / @ooui-font-size-base; // equals `0.285714em`≈`4px`
 
 .mw-htmlform-ooui-wrapper.oo-ui-panelLayout-padded {
        padding: @ooui-spacing-medium @ooui-spacing-large @ooui-spacing-large;
        }
 
        .mw-htmlform-matrix {
-               border-spacing: 0;
+               border-spacing: 0 2px;
 
                td {
-                       padding: 0.35em 0.7em;
+                       padding: @ooui-padding-vertical @ooui-padding-horizontal;
+                       text-align: center;
                        .transition( background-color 250ms );
+
+                       &:first-child {
+                               text-align: left;
+                       }
                }
 
                tbody tr:nth-child( even ) td {
@@ -40,6 +47,7 @@
 
                tbody tr:first-child td {
                        background-color: #fff;
+                       padding-bottom: 0;
                }
 
                td.first {
index 6478fd9..b30a30e 100644 (file)
@@ -1,5 +1,5 @@
 /*!
- * Tools for inspecting page composition and performance.
+ * The mediawiki.inspect module.
  *
  * @author Ori Livneh
  * @since 1.22
@@ -9,7 +9,19 @@
 
 ( function ( mw, $ ) {
 
-       var inspect,
+       // mw.inspect is a singleton class with static methods
+       // that itself can also be invoked as a function (mediawiki.base/mw#inspect).
+       // In JavaScript, that is implemented by starting with a function,
+       // and subsequently setting additional properties on the function object.
+
+       /**
+        * Tools for inspecting page composition and performance.
+        *
+        * @class mw.inspect
+        * @singleton
+        */
+
+       var inspect = mw.inspect,
                byteLength = require( 'mediawiki.String' ).byteLength,
                hasOwn = Object.prototype.hasOwnProperty;
 
        }
 
        /**
-        * @class mw.inspect
-        * @singleton
+        * Return a map of all dependency relationships between loaded modules.
+        *
+        * @return {Object} Maps module names to objects. Each sub-object has
+        *  two properties, 'requires' and 'requiredBy'.
         */
-       inspect = {
+       inspect.getDependencyGraph = function () {
+               var modules = inspect.getLoadedModules(),
+                       graph = {};
 
-               /**
-                * Return a map of all dependency relationships between loaded modules.
-                *
-                * @return {Object} Maps module names to objects. Each sub-object has
-                *  two properties, 'requires' and 'requiredBy'.
-                */
-               getDependencyGraph: function () {
-                       var modules = inspect.getLoadedModules(),
-                               graph = {};
+               modules.forEach( function ( moduleName ) {
+                       var dependencies = mw.loader.moduleRegistry[ moduleName ].dependencies || [];
 
-                       modules.forEach( function ( moduleName ) {
-                               var dependencies = mw.loader.moduleRegistry[ moduleName ].dependencies || [];
+                       if ( !hasOwn.call( graph, moduleName ) ) {
+                               graph[ moduleName ] = { requiredBy: [] };
+                       }
+                       graph[ moduleName ].requires = dependencies;
 
-                               if ( !hasOwn.call( graph, moduleName ) ) {
-                                       graph[ moduleName ] = { requiredBy: [] };
+                       dependencies.forEach( function ( depName ) {
+                               if ( !hasOwn.call( graph, depName ) ) {
+                                       graph[ depName ] = { requiredBy: [] };
                                }
-                               graph[ moduleName ].requires = dependencies;
-
-                               dependencies.forEach( function ( depName ) {
-                                       if ( !hasOwn.call( graph, depName ) ) {
-                                               graph[ depName ] = { requiredBy: [] };
-                                       }
-                                       graph[ depName ].requiredBy.push( moduleName );
-                               } );
+                               graph[ depName ].requiredBy.push( moduleName );
                        } );
-                       return graph;
-               },
+               } );
+               return graph;
+       };
 
-               /**
-                * Calculate the byte size of a ResourceLoader module.
-                *
-                * @param {string} moduleName The name of the module
-                * @return {number|null} Module size in bytes or null
-                */
-               getModuleSize: function ( moduleName ) {
-                       var module = mw.loader.moduleRegistry[ moduleName ],
-                               args, i, size;
+       /**
+        * Calculate the byte size of a ResourceLoader module.
+        *
+        * @param {string} moduleName The name of the module
+        * @return {number|null} Module size in bytes or null
+        */
+       inspect.getModuleSize = function ( moduleName ) {
+               var module = mw.loader.moduleRegistry[ moduleName ],
+                       args, i, size;
 
-                       if ( module.state !== 'ready' ) {
-                               return null;
-                       }
+               if ( module.state !== 'ready' ) {
+                       return null;
+               }
 
-                       if ( !module.style && !module.script ) {
-                               return 0;
+               if ( !module.style && !module.script ) {
+                       return 0;
+               }
+
+               function getFunctionBody( func ) {
+                       return String( func )
+                               // To ensure a deterministic result, replace the start of the function
+                               // declaration with a fixed string. For example, in Chrome 55, it seems
+                               // V8 seemingly-at-random decides to sometimes put a line break between
+                               // the opening brace and first statement of the function body. T159751.
+                               .replace( /^\s*function\s*\([^)]*\)\s*{\s*/, 'function(){' )
+                               .replace( /\s*}\s*$/, '}' );
+               }
+
+               // Based on the load.php response for this module.
+               // For example: `mw.loader.implement("example", function(){}, {"css":[".x{color:red}"]});`
+               // @see mw.loader.store.set().
+               args = [
+                       moduleName,
+                       module.script,
+                       module.style,
+                       module.messages,
+                       module.templates
+               ];
+               // Trim trailing null or empty object, as load.php would have done.
+               // @see ResourceLoader::makeLoaderImplementScript and ResourceLoader::trimArray.
+               i = args.length;
+               while ( i-- ) {
+                       if ( args[ i ] === null || ( $.isPlainObject( args[ i ] ) && $.isEmptyObject( args[ i ] ) ) ) {
+                               args.splice( i, 1 );
+                       } else {
+                               break;
                        }
+               }
 
-                       function getFunctionBody( func ) {
-                               return String( func )
-                                       // To ensure a deterministic result, replace the start of the function
-                                       // declaration with a fixed string. For example, in Chrome 55, it seems
-                                       // V8 seemingly-at-random decides to sometimes put a line break between
-                                       // the opening brace and first statement of the function body. T159751.
-                                       .replace( /^\s*function\s*\([^)]*\)\s*{\s*/, 'function(){' )
-                                       .replace( /\s*}\s*$/, '}' );
+               size = 0;
+               for ( i = 0; i < args.length; i++ ) {
+                       if ( typeof args[ i ] === 'function' ) {
+                               size += byteLength( getFunctionBody( args[ i ] ) );
+                       } else {
+                               size += byteLength( JSON.stringify( args[ i ] ) );
                        }
+               }
 
-                       // Based on the load.php response for this module.
-                       // For example: `mw.loader.implement("example", function(){}, {"css":[".x{color:red}"]});`
-                       // @see mw.loader.store.set().
-                       args = [
-                               moduleName,
-                               module.script,
-                               module.style,
-                               module.messages,
-                               module.templates
-                       ];
-                       // Trim trailing null or empty object, as load.php would have done.
-                       // @see ResourceLoader::makeLoaderImplementScript and ResourceLoader::trimArray.
-                       i = args.length;
-                       while ( i-- ) {
-                               if ( args[ i ] === null || ( $.isPlainObject( args[ i ] ) && $.isEmptyObject( args[ i ] ) ) ) {
-                                       args.splice( i, 1 );
-                               } else {
-                                       break;
+               return size;
+       };
+
+       /**
+        * Given CSS source, count both the total number of selectors it
+        * contains and the number which match some element in the current
+        * document.
+        *
+        * @param {string} css CSS source
+        * @return {Object} Selector counts
+        * @return {number} return.selectors Total number of selectors
+        * @return {number} return.matched Number of matched selectors
+        */
+       inspect.auditSelectors = function ( css ) {
+               var selectors = { total: 0, matched: 0 },
+                       style = document.createElement( 'style' );
+
+               style.textContent = css;
+               document.body.appendChild( style );
+               $.each( style.sheet.cssRules, function ( index, rule ) {
+                       selectors.total++;
+                       // document.querySelector() on prefixed pseudo-elements can throw exceptions
+                       // in Firefox and Safari. Ignore these exceptions.
+                       // https://bugs.webkit.org/show_bug.cgi?id=149160
+                       // https://bugzilla.mozilla.org/show_bug.cgi?id=1204880
+                       try {
+                               if ( document.querySelector( rule.selectorText ) !== null ) {
+                                       selectors.matched++;
                                }
+                       } catch ( e ) {}
+               } );
+               document.body.removeChild( style );
+               return selectors;
+       };
+
+       /**
+        * Get a list of all loaded ResourceLoader modules.
+        *
+        * @return {Array} List of module names
+        */
+       inspect.getLoadedModules = function () {
+               return mw.loader.getModuleNames().filter( function ( module ) {
+                       return mw.loader.getState( module ) === 'ready';
+               } );
+       };
+
+       /**
+        * Print tabular data to the console, using console.table, console.log,
+        * or mw.log (in declining order of preference).
+        *
+        * @param {Array} data Tabular data represented as an array of objects
+        *  with common properties.
+        */
+       inspect.dumpTable = function ( data ) {
+               try {
+                       // Bartosz made me put this here.
+                       if ( window.opera ) { throw window.opera; }
+                       // Use Function.prototype#call to force an exception on Firefox,
+                       // which doesn't define console#table but doesn't complain if you
+                       // try to invoke it.
+                       // eslint-disable-next-line no-useless-call
+                       console.table.call( console, data );
+                       return;
+               } catch ( e ) {}
+               try {
+                       console.log( JSON.stringify( data, null, 2 ) );
+                       return;
+               } catch ( e ) {}
+               mw.log( data );
+       };
+
+       /**
+        * Generate and print reports.
+        *
+        * When invoked without arguments, prints all available reports.
+        *
+        * @param {...string} [reports] One or more of "size", "css", or "store".
+        */
+       inspect.runReports = function () {
+               var reports = arguments.length > 0 ?
+                       Array.prototype.slice.call( arguments ) :
+                       Object.keys( inspect.reports );
+
+               reports.forEach( function ( name ) {
+                       if ( console.group ) {
+                               console.group( 'mw.inspect ' + name + ' report' );
+                       } else {
+                               console.log( 'mw.inspect ' + name + ' report' );
                        }
+                       inspect.dumpTable( inspect.reports[ name ]() );
+                       if ( console.group ) {
+                               console.groupEnd( 'mw.inspect ' + name + ' report' );
+                       }
+               } );
+       };
 
-                       size = 0;
-                       for ( i = 0; i < args.length; i++ ) {
-                               if ( typeof args[ i ] === 'function' ) {
-                                       size += byteLength( getFunctionBody( args[ i ] ) );
-                               } else {
-                                       size += byteLength( JSON.stringify( args[ i ] ) );
-                               }
+       /**
+        * Perform a string search across the JavaScript and CSS source code
+        * of all loaded modules and return an array of the names of the
+        * modules that matched.
+        *
+        * @param {string|RegExp} pattern String or regexp to match.
+        * @return {Array} Array of the names of modules that matched.
+        */
+       inspect.grep = function ( pattern ) {
+               if ( typeof pattern.test !== 'function' ) {
+                       pattern = new RegExp( mw.RegExp.escape( pattern ), 'g' );
+               }
+
+               return inspect.getLoadedModules().filter( function ( moduleName ) {
+                       var module = mw.loader.moduleRegistry[ moduleName ];
+
+                       // Grep module's JavaScript
+                       if ( $.isFunction( module.script ) && pattern.test( module.script.toString() ) ) {
+                               return true;
                        }
 
-                       return size;
-               },
+                       // Grep module's CSS
+                       if (
+                               $.isPlainObject( module.style ) && Array.isArray( module.style.css ) &&
+                               pattern.test( module.style.css.join( '' ) )
+                       ) {
+                               // Module's CSS source matches
+                               return true;
+                       }
 
-               /**
-                * Given CSS source, count both the total number of selectors it
-                * contains and the number which match some element in the current
-                * document.
-                *
-                * @param {string} css CSS source
-                * @return {Object} Selector counts
-                * @return {number} return.selectors Total number of selectors
-                * @return {number} return.matched Number of matched selectors
-                */
-               auditSelectors: function ( css ) {
-                       var selectors = { total: 0, matched: 0 },
-                               style = document.createElement( 'style' );
-
-                       style.textContent = css;
-                       document.body.appendChild( style );
-                       $.each( style.sheet.cssRules, function ( index, rule ) {
-                               selectors.total++;
-                               // document.querySelector() on prefixed pseudo-elements can throw exceptions
-                               // in Firefox and Safari. Ignore these exceptions.
-                               // https://bugs.webkit.org/show_bug.cgi?id=149160
-                               // https://bugzilla.mozilla.org/show_bug.cgi?id=1204880
-                               try {
-                                       if ( document.querySelector( rule.selectorText ) !== null ) {
-                                               selectors.matched++;
-                                       }
-                               } catch ( e ) {}
-                       } );
-                       document.body.removeChild( style );
-                       return selectors;
-               },
+                       return false;
+               } );
+       };
 
+       /**
+        * @class mw.inspect.reports
+        * @singleton
+        */
+       inspect.reports = {
                /**
-                * Get a list of all loaded ResourceLoader modules.
+                * Generate a breakdown of all loaded modules and their size in
+                * kilobytes. Modules are ordered from largest to smallest.
                 *
-                * @return {Array} List of module names
+                * @return {Object[]} Size reports
                 */
-               getLoadedModules: function () {
-                       return mw.loader.getModuleNames().filter( function ( module ) {
-                               return mw.loader.getState( module ) === 'ready';
+               size: function () {
+                       // Map each module to a descriptor object.
+                       var modules = inspect.getLoadedModules().map( function ( module ) {
+                               return {
+                                       name: module,
+                                       size: inspect.getModuleSize( module )
+                               };
                        } );
-               },
-
-               /**
-                * Print tabular data to the console, using console.table, console.log,
-                * or mw.log (in declining order of preference).
-                *
-                * @param {Array} data Tabular data represented as an array of objects
-                *  with common properties.
-                */
-               dumpTable: function ( data ) {
-                       try {
-                               // Bartosz made me put this here.
-                               if ( window.opera ) { throw window.opera; }
-                               // Use Function.prototype#call to force an exception on Firefox,
-                               // which doesn't define console#table but doesn't complain if you
-                               // try to invoke it.
-                               // eslint-disable-next-line no-useless-call
-                               console.table.call( console, data );
-                               return;
-                       } catch ( e ) {}
-                       try {
-                               console.log( JSON.stringify( data, null, 2 ) );
-                               return;
-                       } catch ( e ) {}
-                       mw.log( data );
-               },
 
-               /**
-                * Generate and print one more reports. When invoked with no arguments,
-                * print all reports.
-                *
-                * @param {...string} [reports] Report names to run, or unset to print
-                *  all available reports.
-                */
-               runReports: function () {
-                       var reports = arguments.length > 0 ?
-                               Array.prototype.slice.call( arguments ) :
-                               $.map( inspect.reports, function ( v, k ) { return k; } );
+                       // Sort module descriptors by size, largest first.
+                       sortByProperty( modules, 'size', true );
 
-                       reports.forEach( function ( name ) {
-                               inspect.dumpTable( inspect.reports[ name ]() );
+                       // Convert size to human-readable string.
+                       modules.forEach( function ( module ) {
+                               module.sizeInBytes = module.size;
+                               module.size = humanSize( module.size );
                        } );
+
+                       return modules;
                },
 
                /**
-                * @class mw.inspect.reports
-                * @singleton
+                * For each module with styles, count the number of selectors, and
+                * count how many match against some element currently in the DOM.
+                *
+                * @return {Object[]} CSS reports
                 */
-               reports: {
-                       /**
-                        * Generate a breakdown of all loaded modules and their size in
-                        * kilobytes. Modules are ordered from largest to smallest.
-                        *
-                        * @return {Object[]} Size reports
-                        */
-                       size: function () {
-                               // Map each module to a descriptor object.
-                               var modules = inspect.getLoadedModules().map( function ( module ) {
-                                       return {
-                                               name: module,
-                                               size: inspect.getModuleSize( module )
-                                       };
-                               } );
+               css: function () {
+                       var modules = [];
 
-                               // Sort module descriptors by size, largest first.
-                               sortByProperty( modules, 'size', true );
+                       inspect.getLoadedModules().forEach( function ( name ) {
+                               var css, stats, module = mw.loader.moduleRegistry[ name ];
 
-                               // Convert size to human-readable string.
-                               modules.forEach( function ( module ) {
-                                       module.sizeInBytes = module.size;
-                                       module.size = humanSize( module.size );
-                               } );
-
-                               return modules;
-                       },
-
-                       /**
-                        * For each module with styles, count the number of selectors, and
-                        * count how many match against some element currently in the DOM.
-                        *
-                        * @return {Object[]} CSS reports
-                        */
-                       css: function () {
-                               var modules = [];
-
-                               inspect.getLoadedModules().forEach( function ( name ) {
-                                       var css, stats, module = mw.loader.moduleRegistry[ name ];
-
-                                       try {
-                                               css = module.style.css.join();
-                                       } catch ( e ) { return; } // skip
-
-                                       stats = inspect.auditSelectors( css );
-                                       modules.push( {
-                                               module: name,
-                                               allSelectors: stats.total,
-                                               matchedSelectors: stats.matched,
-                                               percentMatched: stats.total !== 0 ?
-                                                       ( stats.matched / stats.total * 100 ).toFixed( 2 ) + '%' : null
-                                       } );
+                               try {
+                                       css = module.style.css.join();
+                               } catch ( e ) { return; } // skip
+
+                               stats = inspect.auditSelectors( css );
+                               modules.push( {
+                                       module: name,
+                                       allSelectors: stats.total,
+                                       matchedSelectors: stats.matched,
+                                       percentMatched: stats.total !== 0 ?
+                                               ( stats.matched / stats.total * 100 ).toFixed( 2 ) + '%' : null
                                } );
-                               sortByProperty( modules, 'allSelectors', true );
-                               return modules;
-                       },
-
-                       /**
-                        * Report stats on mw.loader.store: the number of localStorage
-                        * cache hits and misses, the number of items purged from the
-                        * cache, and the total size of the module blob in localStorage.
-                        *
-                        * @return {Object[]} Store stats
-                        */
-                       store: function () {
-                               var raw, stats = { enabled: mw.loader.store.enabled };
-                               if ( stats.enabled ) {
-                                       $.extend( stats, mw.loader.store.stats );
-                                       try {
-                                               raw = localStorage.getItem( mw.loader.store.getStoreKey() );
-                                               stats.totalSizeInBytes = byteLength( raw );
-                                               stats.totalSize = humanSize( byteLength( raw ) );
-                                       } catch ( e ) {}
-                               }
-                               return [ stats ];
-                       }
+                       } );
+                       sortByProperty( modules, 'allSelectors', true );
+                       return modules;
                },
 
                /**
-                * Perform a string search across the JavaScript and CSS source code
-                * of all loaded modules and return an array of the names of the
-                * modules that matched.
+                * Report stats on mw.loader.store: the number of localStorage
+                * cache hits and misses, the number of items purged from the
+                * cache, and the total size of the module blob in localStorage.
                 *
-                * @param {string|RegExp} pattern String or regexp to match.
-                * @return {Array} Array of the names of modules that matched.
+                * @return {Object[]} Store stats
                 */
-               grep: function ( pattern ) {
-                       if ( typeof pattern.test !== 'function' ) {
-                               pattern = new RegExp( mw.RegExp.escape( pattern ), 'g' );
+               store: function () {
+                       var raw, stats = { enabled: mw.loader.store.enabled };
+                       if ( stats.enabled ) {
+                               $.extend( stats, mw.loader.store.stats );
+                               try {
+                                       raw = localStorage.getItem( mw.loader.store.getStoreKey() );
+                                       stats.totalSizeInBytes = byteLength( raw );
+                                       stats.totalSize = humanSize( byteLength( raw ) );
+                               } catch ( e ) {}
                        }
-
-                       return inspect.getLoadedModules().filter( function ( moduleName ) {
-                               var module = mw.loader.moduleRegistry[ moduleName ];
-
-                               // Grep module's JavaScript
-                               if ( $.isFunction( module.script ) && pattern.test( module.script.toString() ) ) {
-                                       return true;
-                               }
-
-                               // Grep module's CSS
-                               if (
-                                       $.isPlainObject( module.style ) && Array.isArray( module.style.css ) &&
-                                       pattern.test( module.style.css.join( '' ) )
-                               ) {
-                                       // Module's CSS source matches
-                                       return true;
-                               }
-
-                               return false;
-                       } );
+                       return [ stats ];
                }
        };
 
                mw.log( 'mw.inspect: reports are not available in debug mode.' );
        }
 
-       mw.inspect = inspect;
-
 }( mediaWiki, jQuery ) );
index d81df65..437800a 100644 (file)
         * e.g.
         *
         *        $.fn.msg = mediaWiki.jqueryMsg.getPlugin( options );
-        *        var userlink = $( '<a>' ).click( function () { alert( "hello!!" ) } );
-        *        $( 'p#headline' ).msg( 'hello-user', userlink );
+        *        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 )
                getAst: function ( key ) {
                        var wikiText;
 
-                       if ( !this.astCache.hasOwnProperty( key ) ) {
+                       if ( !Object.prototype.hasOwnProperty.call( this.astCache, key ) ) {
                                wikiText = this.settings.messages.get( key );
                                if ( typeof wikiText !== 'string' ) {
                                        wikiText = '⧼' + key + '⧽';
                        return oldParser.apply( this );
                }
 
-               if ( !this.map.hasOwnProperty( this.format ) ) {
+               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
         * @return {jQuery}
         */
        mw.Message.prototype.parseDom = ( function () {
-               var reusableParent = $( '<div>' );
+               var $wrapper = $( '<div>' );
                return function () {
-                       return reusableParent.msg( this.key, this.parameters ).contents().detach();
+                       return $wrapper.msg( this.key, this.parameters ).contents().detach();
                };
        }() );
 
index 077473b..34add28 100644 (file)
@@ -13,8 +13,8 @@
        mw.language = {
                /**
                 * Language-related data (keyed by language, contains instances of mw.Map).
-                * Loaded dynamically (see ResourceLoaderLanguageDataModule class in PHP, registered
-                * as mediawiki.language.data on the client).
+                *
+                * Exported dynamically by the ResourceLoaderLanguageDataModule class in PHP.
                 *
                 * To set data:
                 *
index 267210c..f4194d3 100644 (file)
                for ( i = 0; i < arguments.length; i++ ) {
                        table = arguments[ i ];
                        for ( key in table ) {
-                               if ( table.hasOwnProperty( key ) ) {
-                                       // The thousand separator should be deleted
-                                       flipped[ table[ key ] ] = key === ',' ? '' : key;
-                               }
+                               // The thousand separator should be deleted
+                               flipped[ table[ key ] ] = key === ',' ? '' : key;
                        }
                }
 
                        if ( transformTable ) {
                                convertedNumber = '';
                                for ( i = 0; i < numberString.length; i++ ) {
-                                       if ( transformTable.hasOwnProperty( numberString[ i ] ) ) {
+                                       if ( Object.prototype.hasOwnProperty.call( transformTable, numberString[ i ] ) ) {
                                                convertedNumber += transformTable[ numberString[ i ] ];
                                        } else {
                                                convertedNumber += numberString[ i ];
index 64870fd..eafa13d 100644 (file)
@@ -16,7 +16,6 @@
 .catlinks,
 .magnify,
 .mw-cite-backlink,
-.mw-jump,
 .mw-editsection,
 .mw-editsection-like,
 .mw-hidden-catlinks,
@@ -27,7 +26,6 @@
 /* Various content ids, in alphabetical order */
 #column-one,
 #footer-places,
-#jump-to-nav,
 #mw-navigation,
 #siteNotice,
 /* Deprecated, changed in core */
index b95a436..ac65ac7 100644 (file)
@@ -215,7 +215,7 @@ table.toc td {
 }
 
 /* preference page with js-genrated toc */
-/* TODO: Delete #preftoc when Special:Preference's non-OOUI mode is disabled */
+/* TODO: Delete #preftoc when Special:Preferences's non-OOUI mode is disabled */
 #preftoc {
        float: left;
        margin: 1em 1em 1em 1em;
index 0f84ff1..83e0d8a 100644 (file)
@@ -697,14 +697,6 @@ table.floatleft {
        unicode-bidi: embed;
 }
 
-/* Accessibility */
-.mw-jump,
-#jump-to-nav {
-       overflow: hidden;
-       height: 0;
-       zoom: 1; /* http://webaim.org/techniques/skipnav/#iequirk */
-}
-
 /* Print footer should be hidden by default in screen. */
 .printfooter {
        display: none;
@@ -716,8 +708,7 @@ table.floatleft {
        z-index: 99;
 }
 
-.mw-editsection,
-#jump-to-nav {
+.mw-editsection {
        -moz-user-select: none;
        -webkit-user-select: none;
        -ms-user-select: none;
index 53dccc2..55be237 100644 (file)
@@ -1,6 +1,6 @@
 // Common Less mixin library for MediaWiki
 //
-// By default the folder containing this file is included in $wgResourceLoaderLESSImportPaths,
+// By default the folder containing this file is included in the LESS import paths,
 // which makes this file importable by all less files via `@import 'mediawiki.mixins';`.
 //
 // The mixins included below are considered a public interface for MediaWiki extensions.
index 9448ab8..ff27c58 100644 (file)
@@ -7,6 +7,8 @@
 ( function ( mw, $ ) {
        var $galleries,
                bound = false,
+               lastWidth = window.innerWidth,
+               justifyNeeded = false,
                // Is there a better way to detect a touchscreen? Current check taken from stack overflow.
                isTouchScreen = !!( window.ontouchstart !== undefined ||
                        window.DocumentTouch !== undefined && document instanceof window.DocumentTouch
         */
        function justify() {
                var lastTop,
-                       $img,
-                       imgWidth,
-                       imgHeight,
-                       captionWidth,
                        rows = [],
                        $gallery = $( this );
 
                $gallery.children( 'li.gallerybox' ).each( function () {
-                       // Math.floor to be paranoid if things are off by 0.00000000001
-                       var top = Math.floor( $( this ).position().top ),
+                       var $img, imgWidth, imgHeight, outerWidth, captionWidth,
+                               // Math.floor, to be paranoid if things are off by 0.00000000001
+                               top = Math.floor( $( this ).position().top ),
                                $this = $( this );
 
                        if ( top !== lastTop ) {
-                               rows[ rows.length ] = [];
+                               rows.push( [] );
                                lastTop = top;
                        }
 
                        }
 
                        captionWidth = $this.children().children( 'div.gallerytextwrapper' ).width();
-                       rows[ rows.length - 1 ][ rows[ rows.length - 1 ].length ] = {
+                       outerWidth = $this.outerWidth();
+                       rows[ rows.length - 1 ].push( {
                                $elm: $this,
-                               width: $this.outerWidth(),
+                               width: outerWidth,
                                imgWidth: imgWidth,
-                               // XXX: can divide by 0 ever happen?
+                               // FIXME: Deal with devision by 0.
                                aspect: imgWidth / imgHeight,
                                captionWidth: captionWidth,
                                height: imgHeight
-                       };
+                       } );
 
                        // Save all boundaries so we can restore them on window resize
                        $this.data( 'imgWidth', imgWidth );
                        $this.data( 'imgHeight', imgHeight );
-                       $this.data( 'width', $this.outerWidth() );
+                       $this.data( 'width', outerWidth );
                        $this.data( 'captionWidth', captionWidth );
                } );
 
                                        $innerDiv = $outerDiv.children( 'div' ).first();
                                        $imageDiv = $innerDiv.children( 'div.thumb' );
                                        $imageElm = $imageDiv.find( 'img' ).first();
-                                       imageElm = $imageElm.length ? $imageElm[ 0 ] : null;
                                        $caption = $outerDiv.find( 'div.gallerytextwrapper' );
 
                                        // Since we are going to re-adjust the height, the vertical
                                                $caption.width( curRow[ j ].captionWidth + ( newWidth - curRow[ j ].imgWidth ) );
                                        }
 
-                                       if ( imageElm ) {
-                                               // We don't always have an img, e.g. in the case of an invalid file.
+                                       // We don't always have an img, e.g. in the case of an invalid file.
+                                       if ( $imageElm[ 0 ] ) {
+                                               imageElm = $imageElm[ 0 ];
                                                imageElm.width = newWidth;
                                                imageElm.height = preferredHeight;
                                        } else {
        }
 
        function handleResizeStart() {
+               // Only do anything if window width changed. We don't care about the height.
+               if ( lastWidth === window.innerWidth ) {
+                       return;
+               }
+
+               justifyNeeded = true;
+               // Temporarily set min-height, so that content following the gallery is not reflowed twice
+               $galleries.css( 'min-height', function () {
+                       return $( this ).height();
+               } );
                $galleries.children( 'li.gallerybox' ).each( function () {
                        var imgWidth = $( this ).data( 'imgWidth' ),
                                imgHeight = $( this ).data( 'imgHeight' ),
                        $( this ).find( 'div.gallerytextwrapper' ).width( captionWidth );
 
                        $imageElm = $( this ).find( 'img' ).first();
-                       imageElm = $imageElm.length ? $imageElm[ 0 ] : null;
-                       if ( imageElm ) {
+                       if ( $imageElm[ 0 ] ) {
+                               imageElm = $imageElm[ 0 ];
                                imageElm.width = imgWidth;
                                imageElm.height = imgHeight;
                        } else {
        }
 
        function handleResizeEnd() {
-               $galleries.each( justify );
+               // If window width never changed during the resize, don't do anything.
+               if ( justifyNeeded ) {
+                       justifyNeeded = false;
+                       lastWidth = window.innerWidth;
+                       $galleries
+                               // Remove temporary min-height
+                               .css( 'min-height', '' )
+                               // Recalculate layout
+                               .each( justify );
+               }
        }
 
        mw.hook( 'wikipage.content' ).add( function ( $content ) {
                } else {
                        // Note use of just `a`, not `a.image`, since we also want this to trigger if a link
                        // within the caption text receives focus.
-                       // This is based on code from the 'jquery.mw-jump' module.
                        $content.find( 'ul.mw-gallery-packed-hover li.gallerybox' ).on( 'focus blur', 'a', function ( e ) {
                                // Confusingly jQuery leaves e.type as focusout for delegated blur events
                                var gettingFocus = e.type !== 'blur' && e.type !== 'focusout';
index 06c34a5..1823ef0 100644 (file)
@@ -2,8 +2,6 @@
  * Implement AJAX navigation for multi-page images so the user may browse without a full page reload.
  */
 
-/* eslint-disable no-use-before-define */
-
 ( function ( mw, $ ) {
        var jqXhr, $multipageimage, $spinner,
                cache = {},
@@ -86,6 +84,7 @@
                        // Replace table contents
                        $multipageimage.empty().append( $contents.clone() );
 
+                       // eslint-disable-next-line no-use-before-define
                        bindPageNavigation( $multipageimage );
 
                        // Fire hook because the page's content has changed
index 5b41876..2002b9f 100644 (file)
 
                actionPaths = mw.config.get( 'wgActionPaths' );
                for ( key in actionPaths ) {
-                       if ( actionPaths.hasOwnProperty( key ) ) {
-                               parts = actionPaths[ key ].split( '$1' );
-                               parts = parts.map( mw.RegExp.escape );
-                               m = new RegExp( parts.join( '(.+)' ) ).exec( url );
-                               if ( m && m[ 1 ] ) {
-                                       return key;
-                               }
-
+                       parts = actionPaths[ key ].split( '$1' );
+                       parts = parts.map( mw.RegExp.escape );
+                       m = new RegExp( parts.join( '(.+)' ) ).exec( url );
+                       if ( m && m[ 1 ] ) {
+                               return key;
                        }
                }
 
index d1e40ca..63b0b03 100644 (file)
@@ -20,7 +20,7 @@
         * @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] If set, highlight this filter by default with this color
+        * @cfg {string} [defaultHighlightColor=null] If set, highlight this filter by default with this color
         */
        mw.rcfilters.dm.ItemModel = function MwRcfiltersDmItemModel( param, config ) {
                config = config || {};
@@ -41,7 +41,7 @@
 
                // Highlight
                this.cssClass = config.cssClass;
-               this.highlightColor = config.defaultHighlightColor;
+               this.highlightColor = config.defaultHighlightColor || null;
        };
 
        /* Initialization */
                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;
index cd3f684..52438ca 100644 (file)
@@ -15,6 +15,8 @@
         * @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
                this.savedQueriesPreferenceName = config.savedQueriesPreferenceName;
                this.daysPreferenceName = config.daysPreferenceName;
                this.limitPreferenceName = config.limitPreferenceName;
+               this.collapsedPreferenceName = config.collapsedPreferenceName;
                this.normalizeTarget = !!config.normalizeTarget;
 
                this.requestCounter = {};
                this.baseFilterState = {};
                this.uriProcessor = null;
-               this.initializing = false;
+               this.initialized = false;
                this.wereSavedQueriesSaved = false;
 
                this.prevLoggedItems = [];
                        }
                }
 
-               // Check whether we need to load defaults.
-               // We do this by checking whether the current URI query
-               // contains any parameters recognized by the system.
-               // If it does, we load the given state.
-               // If it doesn't, we have no values at all, and we assume
-               // the user loads the base-page and we load defaults.
-               // Defaults should only be applied on load (if necessary)
-               // or on request
-               this.initializing = true;
-
                if ( defaultSavedQueryExists ) {
                        // This came from the server, meaning that we have a default
                        // saved query, but the server could not load it, probably because
                        );
                }
 
-               this.initializing = false;
+               this.initialized = true;
                this.switchView( 'default' );
 
                this.pollingRate = mw.config.get( 'StructuredChangeFiltersLiveUpdatePollingRate' );
                }
        };
 
+       /**
+        * Check if the controller has finished initializing.
+        * @return {boolean} Controller is initialized
+        */
+       mw.rcfilters.Controller.prototype.isInitialized = function () {
+               return this.initialized;
+       };
+
        /**
         * Extracts information from the changes list DOM
         *
                this.updateNumericPreference( 'usenewrc', Number( newValue ) );
        };
 
+       /**
+        * Update the collapsed state value
+        *
+        * @param {boolean} isCollapsed Filter area is collapsed
+        */
+       mw.rcfilters.Controller.prototype.updateCollapsedState = function ( isCollapsed ) {
+               this.updateNumericPreference( this.collapsedPreferenceName, Number( isCollapsed ) );
+       };
+
        /**
         * Update a numeric preference with a new value
         *
index d181532..c918df8 100644 (file)
@@ -15,6 +15,8 @@
                                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 ),
@@ -25,6 +27,7 @@
                                                savedQueriesPreferenceName: savedQueriesPreferenceName,
                                                daysPreferenceName: daysPreferenceName,
                                                limitPreferenceName: limitPreferenceName,
+                                               collapsedPreferenceName: activeFiltersCollapsedName,
                                                normalizeTarget: specialPage === 'Recentchangeslinked'
                                        }
                                );
                                savedQueriesModel,
                                changesListModel,
                                {
+                                       $wrapper: $( 'body' ),
                                        $topSection: $topSection,
                                        $filtersContainer: $( '.rcfilters-container' ),
                                        $changesListContainer: $( '.mw-changeslist, .mw-changeslist-empty' ),
-                                       $formContainer: $initialFieldset
+                                       $formContainer: $initialFieldset,
+                                       collapsed: initialCollapsedState
                                }
                        );
 
index d4ce55d..9101fba 100644 (file)
@@ -5,7 +5,9 @@
 @rcfilters-spinner-size: 12px;
 @rcfilters-head-min-height: 210px;
 @rcfilters-head-margin-bottom: 20px;
-@rcfilters-wl-head-min-height: 300px;
+@rcfilters-wl-head-min-height: 295px;
+@rcfilters-head-min-height-collapsed: 130px;
+@rcfilters-wl-head-min-height-collapsed: 220px;
 
 // Corrections for the standard special page
 .client-js {
        // On the watchlist, reserve a bit more
        .mw-special-Watchlist .rcfilters-head {
                min-height: @rcfilters-wl-head-min-height;
+
+       }
+
+       .mw-rcfilters-collapsed {
+               .rcfilters-head {
+                       min-height: @rcfilters-head-min-height-collapsed;
+               }
+
+               // On the watchlist, reserve a bit more
+               &.mw-special-Watchlist .rcfilters-head {
+                       min-height: @rcfilters-wl-head-min-height-collapsed;
+               }
        }
 
        .mw-recentchanges-toplinks {
                }
        }
 
+       .mw-rcfilters-ui-highlights {
+               display: none;
+       }
+
        .mw-changeslist {
                // Reserve space for the highlight circles
                ul,
                left: 50%;
                // Make sure the middle of the spinner is centered, rather than its left edge
                margin-left: -3 * @rcfilters-spinner-size / 2;
-
-               opacity: 0.8;
                white-space: nowrap;
 
                & .rcfilters-spinner-bounce,
                &:before,
                &:after {
                        content: '';
-                       display: inline-block;
+                       background-color: @colorGray7;
+                       display: block;
+                       float: left;
                        width: @rcfilters-spinner-size;
                        height: @rcfilters-spinner-size;
-                       background-color: @colorGray12;
                        border-radius: 100%;
-                       .animation( rcfiltersBouncedelay 1.5s ease-in-out -0.16s infinite both );
+                       .animation( rcfiltersBouncedelay 1600ms ease-in-out -160ms infinite both );
                }
 
                &:before {
-                       .animation-delay( -0.33s );
+                       margin-right: 4px;
+                       .animation-delay( -330ms );
                }
 
                &:after {
+                       margin-left: 4px;
                        .animation-delay( 0s );
                }
        }
        body:not( .mw-rcfilters-ui-initialized ) .rcfilters-spinner {
                display: block;
                // When initializing, display the spinner on top of the area where the UI will appear
-               margin-top: -( @rcfilters-head-min-height + @rcfilters-head-margin-bottom ) / 2;
+               margin-top: -( @rcfilters-head-min-height + @rcfilters-head-margin-bottom ) / 1.5;
        }
        body.mw-rcfilters-ui-loading .rcfilters-spinner {
                display: block;
                // When loading new results, display the spinner on top of the results area
-               margin-top: 2em;
+               margin-top: -( @rcfilters-head-min-height + @rcfilters-head-margin-bottom ) / 8;
        }
 
        #contentSub,
                display: none;
        }
 
+       // Why does rcfilters have a copy of this?
+       // TODO: Remove per T195256.
        #jump-to-nav {
                margin-top: -0.5em;
                margin-bottom: 0.5em;
        // space. This makes the min-height trick work better.
        .watchlistDetails {
                float: left;
+               // The 20em should match the min-width we are setting up
+               // for the .mw-rcfilters-ui-watchlistTopSectionWidget-editWatchlistButton
+               // in mw.rcfilters.ui.WatchlistTopSectionWidget.less
+               width: ~'calc( 100% - 20em )';
        }
 }
 
 
 @-webkit-keyframes rcfiltersBouncedelay {
        0%,
-       80%,
+       50%, // equals 800ms
        100% {
-               -webkit-transform: scale( 0.7 );
-               transform: scale( 0.7 );
+               -webkit-transform: scale( 0.625 );
        }
-       40% {
-               background-color: @colorGray10;
+       20% { // equals 320ms
+               opacity: 0.87;
                -webkit-transform: scale( 1 );
-               transform: scale( 1 );
        }
 }
 
 @-moz-keyframes rcfiltersBouncedelay {
        0%,
-       80%,
+       50%,
        100% {
-               -moz-transform: scale( 0.7 );
-               transform: scale( 0.7 );
+               -moz-transform: scale( 0.625 );
        }
-       40% {
-               background-color: @colorGray10;
-               -moz-transform: scale( 0.7 );
-               transform: scale( 1 );
+       20% {
+               opacity: 0.87;
+               -moz-transform: scale( 1 );
        }
 }
 
 @keyframes rcfiltersBouncedelay {
        0%,
-       80%,
+       50%,
        100% {
-               transform: scale( 0.7 );
+               transform: scale( 0.625 );
        }
-       40% {
-               background-color: @colorGray10;
+       20% { // equals 320ms
+               opacity: 0.87;
                transform: scale( 1 );
        }
 }
index 790e015..daa7a91 100644 (file)
 // so it is before the rest of the rule; we need the li& to be in
 // between the wrapper scope and the color-cX class, which doesn't
 // work if the rules are inside the above widget LESS scope
-.highlight-changesListWrapperWidget( @bgcolor ) {
+.highlight-results( @bgcolor ) {
        .mw-rcfilters-ui-changesListWrapperWidget li&,
        .mw-rcfilters-ui-changesListWrapperWidget & tr:first-child,
-       .mw-rcfilters-ui-changesListWrapperWidget tr&.mw-rcfilters-ui-changesListWrapperWidget-enhanced-toplevel:not( .mw-rcfilters-ui-changesListWrapperWidget-enhanced-grey ) td:not( :nth-child( -n+2 ) ),
-       .mw-rcfilters-ui-changesListWrapperWidget tr&.mw-rcfilters-ui-changesListWrapperWidget-enhanced-nested:not( .mw-rcfilters-ui-changesListWrapperWidget-enhanced-grey ) td:not( :nth-child( -n+4 ) ) {
+       .mw-rcfilters-ui-changesListWrapperWidget tr&.mw-rcfilters-ui-highlights-enhanced-toplevel:not( .mw-rcfilters-ui-changesListWrapperWidget-enhanced-grey ) td:not( :nth-child( -n+2 ) ),
+       .mw-rcfilters-ui-changesListWrapperWidget tr&.mw-rcfilters-ui-highlights-enhanced-nested:not( .mw-rcfilters-ui-changesListWrapperWidget-enhanced-grey ) td:not( :nth-child( -n+4 ) ) {
                background-color: @bgcolor;
        }
 }
 
        // Two colors
        @{highlight-color-class-var} when ( @color3 = false ) and ( @color4 = false ) and not ( @color1 = false ), ( @color2 = false ) {
-               .highlight-changesListWrapperWidget( tint( average( @@c1var, @@c2var ), 50% ) );
+               .highlight-results( tint( average( @@c1var, @@c2var ), 50% ) );
        }
        // Three colors
        @{highlight-color-class-var}.mw-rcfilters-highlight-color-@{color3} when ( @color4 = false ) and not ( @color3 = false ) {
                @c3var: ~'highlight-@{color3}';
-               .highlight-changesListWrapperWidget( tint( mix( @@c1var, average( @@c2var, @@c3var ), 33% ), 30% ) );
+               .highlight-results( tint( mix( @@c1var, average( @@c2var, @@c3var ), 33% ), 30% ) );
        }
 
        // Four colors
        @{highlight-color-class-var}.mw-rcfilters-highlight-color-@{color3}.mw-rcfilters-highlight-color-@{color4} when not ( @color4 = false ) {
                @c3var: ~'highlight-@{color3}';
                @c4var: ~'highlight-@{color4}';
-               .highlight-changesListWrapperWidget( tint( mix( @@c1var, mix( @@c2var, average( @@c3var, @@c4var ), 25% ), 25% ), 25% ) );
+               .highlight-results( tint( mix( @@c1var, mix( @@c2var, average( @@c3var, @@c4var ), 25% ), 25% ), 25% ) );
        }
 }
index 5f6fbea..920fec3 100644 (file)
@@ -1,4 +1,5 @@
 @import 'mw.rcfilters.mixins';
+@import 'mw.rcfilters.variables';
 
 .mw-rcfilters-ui-changesListWrapperWidget {
        ul {
@@ -8,59 +9,65 @@
                        list-style: none;
                }
        }
+}
 
-       // Make more specific for the overrides
-       div&-highlights {
+// Make more specific for the overrides
+div.mw-rcfilters-ui-highlights {
+       body.mw-rcfilters-ui-initialized & {
                display: inline-block;
+       }
 
-               &-color {
-                       &-none {
-                               display: inline-block;
-                               .mw-changeslist-watchedseen & {
-                                       .mw-rcfilters-ui-changesListWrapperWidget.mw-rcfilters-ui-changesListWrapperWidget-highlighted & {
-                                               .mw-rcfilters-mixin-circle( @highlight-none, @result-circle-diameter, 0, true, @highlight-grey, true );
-                                       }
-
-                                       .mw-rcfilters-ui-changesListWrapperWidget:not( .mw-rcfilters-ui-changesListWrapperWidget-highlighted ) & {
-                                               .mw-rcfilters-mixin-circle( @highlight-none, @result-circle-diameter, 0, true, @highlight-bluedot, true );
-                                       }
+       &-color {
+               &-none {
+                       display: inline-block;
+                       .mw-changeslist-watchedseen & {
+                               .mw-rcfilters-ui-changesListWrapperWidget.mw-rcfilters-ui-changesListWrapperWidget-highlighted & {
+                                       .mw-rcfilters-mixin-circle( @highlight-none, @result-circle-diameter, 0, true, @highlight-grey, true );
                                }
 
-                               .mw-changeslist-watchedunseen & {
-                                       .mw-rcfilters-ui-changesListWrapperWidget.mw-rcfilters-ui-changesListWrapperWidget-highlighted & {
-                                               .mw-rcfilters-mixin-circle( @highlight-grey, @result-circle-diameter, 0, true, @highlight-grey );
-                                       }
+                               .mw-rcfilters-ui-changesListWrapperWidget:not( .mw-rcfilters-ui-changesListWrapperWidget-highlighted ) & {
+                                       .mw-rcfilters-mixin-circle( @highlight-none, @result-circle-diameter, 0, true, @highlight-bluedot, true );
+                               }
+                       }
 
-                                       .mw-rcfilters-ui-changesListWrapperWidget:not( .mw-rcfilters-ui-changesListWrapperWidget-highlighted ) & {
-                                               .mw-rcfilters-mixin-circle( @highlight-bluedot, @result-circle-diameter, 0, true, @highlight-bluedot );
-                                       }
+                       .mw-changeslist-watchedunseen & {
+                               .mw-rcfilters-ui-changesListWrapperWidget.mw-rcfilters-ui-changesListWrapperWidget-highlighted & {
+                                       .mw-rcfilters-mixin-circle( @highlight-grey, @result-circle-diameter, 0, true, @highlight-grey );
                                }
 
+                               .mw-rcfilters-ui-changesListWrapperWidget:not( .mw-rcfilters-ui-changesListWrapperWidget-highlighted ) & {
+                                       .mw-rcfilters-mixin-circle( @highlight-bluedot, @result-circle-diameter, 0, true, @highlight-bluedot );
+                               }
                        }
 
-                       // Watchlist unseen highlighted fixes
-                       // Seen (empty circle)
-                       // There's no need to correct 'unseen' because that would be
-                       // a filled colorful circle, which is the regular rendering
-                       .mw-changeslist-watchedseen &-c1 {
-                               .mw-rcfilters-mixin-circle( @highlight-c1, @result-circle-diameter, 0, true, @highlight-c1, true );
-                       }
+               }
 
-                       .mw-changeslist-watchedseen &-c2 {
-                               .mw-rcfilters-mixin-circle( @highlight-c2, @result-circle-diameter, 0, true, @highlight-c2, true );
-                       }
+               // Watchlist unseen highlighted fixes
+               // Seen (empty circle)
+               // There's no need to correct 'unseen' because that would be
+               // a filled colorful circle, which is the regular rendering
+               .mw-changeslist-watchedseen &-c1 {
+                       .mw-rcfilters-mixin-circle( @highlight-c1, @result-circle-diameter, 0, true, @highlight-c1, true );
+               }
 
-                       .mw-changeslist-watchedseen &-c3 {
-                               .mw-rcfilters-mixin-circle( @highlight-c3, @result-circle-diameter, 0, true, @highlight-c3, true );
-                       }
+               .mw-changeslist-watchedseen &-c2 {
+                       .mw-rcfilters-mixin-circle( @highlight-c2, @result-circle-diameter, 0, true, @highlight-c2, true );
+               }
 
-                       .mw-changeslist-watchedseen &-c4 {
-                               .mw-rcfilters-mixin-circle( @highlight-c4, @result-circle-diameter, 0, true, @highlight-c4, true );
-                       }
+               .mw-changeslist-watchedseen &-c3 {
+                       .mw-rcfilters-mixin-circle( @highlight-c3, @result-circle-diameter, 0, true, @highlight-c3, true );
+               }
 
-                       .mw-changeslist-watchedseen &-c5 {
-                               .mw-rcfilters-mixin-circle( @highlight-c5, @result-circle-diameter, 0, true, @highlight-c5, true );
-                       }
+               .mw-changeslist-watchedseen &-c4 {
+                       .mw-rcfilters-mixin-circle( @highlight-c4, @result-circle-diameter, 0, true, @highlight-c4, true );
                }
+
+               .mw-changeslist-watchedseen &-c5 {
+                       .mw-rcfilters-mixin-circle( @highlight-c5, @result-circle-diameter, 0, true, @highlight-c5, true );
+               }
+       }
+
+       .mw-rcfilters-ui-changesListWrapperWidget & > div {
+               margin-right: @result-circle-margin;
        }
 }
index e9e331b..e0c3c8b 100644 (file)
                        width: 100%;
                }
        }
+}
 
-       &-highlights {
-               display: none;
-               padding: 0 @result-circle-general-margin 0 0;
-               text-align: right;
-               // The width is 5 circles times their diameter + individual margin
-               // and then plus the general margin
-               width: ~'calc( ( @{result-circle-diameter} + @{result-circle-margin} ) * 5 )';
-               // And we want to shift the entire block to the left of the li
-               position: relative;
-               // Negative left margin of width + padding
-               margin-left: ~'calc( ( @{result-circle-diameter} + @{result-circle-margin} ) * -5 - @{result-circle-general-margin} )';
-
-               .mw-rcfilters-ui-changesListWrapperWidget-highlighted & {
-                       display: inline-block;
-               }
+.mw-rcfilters-ui-highlights {
+       display: none;
+       padding: 0 @result-circle-general-margin 0 0;
+       // The width is 5 circles times their diameter + individual margin
+       // and then plus the general margin
+       width: ~'calc( ( @{result-circle-diameter} + @{result-circle-margin} ) * 5 )';
+       // And we want to shift the entire block to the left of the li
+       position: relative;
+       // Negative left margin of width + padding
+       margin-left: ~'calc( ( @{result-circle-diameter} + @{result-circle-margin} ) * -5 - @{result-circle-general-margin} )';
 
-               // This needs to be very specific, since these are
-               // position rules that should apply to all overrides
-               .mw-rcfilters-ui-changesListWrapperWidget .mw-rcfilters-ui-changesListWrapperWidget-highlights > div&-circle {
-                       .box-sizing( border-box );
-                       margin-right: @result-circle-margin;
-                       vertical-align: middle;
-                       // This is to make the dots appear at the center of the
-                       // text itself; it's a horrendous hack and blame JamesF for it.
-                       margin-top: -2px;
-               }
+       .mw-rcfilters-ui-changesListWrapperWidget-highlighted & {
+               display: inline-block;
+       }
 
-               &-color {
+       > div {
+               .box-sizing( border-box );
+               margin-right: @result-circle-margin;
+               vertical-align: middle;
+               // This is to make the dots appear at the center of the
+               // text itself; it's a horrendous hack and blame JamesF for it.
+               margin-top: -2px;
+               float: right;
+       }
 
-                       &-none {
-                               .mw-rcfilters-mixin-circle( @highlight-none, @result-circle-diameter, 0, true );
-                               display: inline-block;
+       &-color {
+               &-none {
+                       .mw-rcfilters-mixin-circle( @highlight-none, @result-circle-diameter, 0, true );
+                       display: inline-block;
 
-                               .mw-rcfilters-highlight-color-c1 &,
-                               .mw-rcfilters-highlight-color-c2 &,
-                               .mw-rcfilters-highlight-color-c3 &,
-                               .mw-rcfilters-highlight-color-c4 &,
-                               .mw-rcfilters-highlight-color-c5 & {
-                                       display: none;
-                               }
+                       .mw-rcfilters-highlight-color-c1 &,
+                       .mw-rcfilters-highlight-color-c2 &,
+                       .mw-rcfilters-highlight-color-c3 &,
+                       .mw-rcfilters-highlight-color-c4 &,
+                       .mw-rcfilters-highlight-color-c5 & {
+                               display: none;
                        }
-                       .result-circle( c1 );
-                       .result-circle( c2 );
-                       .result-circle( c3 );
-                       .result-circle( c4 );
-                       .result-circle( c5 );
                }
+               .result-circle( c1 );
+               .result-circle( c2 );
+               .result-circle( c3 );
+               .result-circle( c4 );
+               .result-circle( c5 );
        }
 }
 
 // One color
 .mw-rcfilters-highlight-color-c1 {
-       .highlight-changesListWrapperWidget( tint( @highlight-c1, 70% ); );
+       .highlight-results( tint( @highlight-c1, 70% ); );
 }
 
 .mw-rcfilters-highlight-color-c2 {
-       .highlight-changesListWrapperWidget( tint( @highlight-c2, 70% ); );
+       .highlight-results( tint( @highlight-c2, 70% ); );
 }
 
 .mw-rcfilters-highlight-color-c3 {
-       .highlight-changesListWrapperWidget( tint( @highlight-c3, 70% ); );
+       .highlight-results( tint( @highlight-c3, 70% ); );
 }
 
 .mw-rcfilters-highlight-color-c4 {
-       .highlight-changesListWrapperWidget( tint( @highlight-c4, 70% ); );
+       .highlight-results( tint( @highlight-c4, 70% ); );
 }
 
 .mw-rcfilters-highlight-color-c5 {
-       .highlight-changesListWrapperWidget( tint( @highlight-c5, 70% ); );
+       .highlight-results( tint( @highlight-c5, 70% ); );
 }
 
 // Two colors
 // a custom color rather than the computed tint
 // see https://phabricator.wikimedia.org/T161267
 .mw-rcfilters-highlight-color-c1.mw-rcfilters-highlight-color-c3 {
-       .highlight-changesListWrapperWidget( @light-green );
+       .highlight-results( @light-green );
 }
 .highlight-color-mix( c1, c4 );
 .highlight-color-mix( c1, c5 );
 
 // Five colors:
 .mw-rcfilters-highlight-color-c1.mw-rcfilters-highlight-color-c2.mw-rcfilters-highlight-color-c3.mw-rcfilters-highlight-color-c4.mw-rcfilters-highlight-color-c5 {
-       .highlight-changesListWrapperWidget( tint( mix( @highlight-c1, mix( @highlight-c2, mix( @highlight-c3, average( @highlight-c4, @highlight-c5 ), 20% ), 20% ), 20% ), 15% ) );
+       .highlight-results( tint( mix( @highlight-c1, mix( @highlight-c2, mix( @highlight-c3, average( @highlight-c4, @highlight-c5 ), 20% ), 20% ), 20% ), 15% ) );
 }
index 148e37b..284d338 100644 (file)
                border-bottom: 0;
                background-color: @colorGray15;
                border-radius: 2px 2px 0 0;
-               padding: 0.6em;
+               padding: 0 0.6em 0.6em 0.6em;
                margin-top: 1em;
                line-height: normal;
        }
 
+       .mw-rcfilters-collapsed & {
+               // Taking from the handle, since border-bottom is set on the
+               // filters view which is hidden when collapsed
+               border-bottom: 1px solid @colorGray10;
+
+               &.mw-rcfilters-ui-filterTagMultiselectWidget.oo-ui-widget-enabled .oo-ui-tagMultiselectWidget-handle {
+                       padding-bottom: 0;
+                       padding-top: 0;
+               }
+
+               .mw-rcfilters-ui-filterTagMultiselectWidget-wrapper-hideshow {
+                       border-left: 1px solid @colorGray10;
+               }
+
+               &.oo-ui-tagMultiselectWidget-outlined {
+                       width: unset;
+                       max-width: 100%;
+               }
+
+               // Hide inner elements
+               .mw-rcfilters-ui-filterTagMultiselectWidget-wrapper-filters,
+               .mw-rcfilters-ui-filterTagMultiselectWidget-views {
+                       display: none;
+               }
+       }
+
        .oo-ui-tagMultiselectWidget.oo-ui-widget-enabled &-animate.oo-ui-tagMultiselectWidget-handle {
                .transition( background-color 500ms ease-out );
        }
                background-color: @background-color-primary;
        }
 
+       &-hideshowButton.oo-ui-buttonElement > .oo-ui-buttonElement-button {
+               // Override the OOUI default for buttons
+               font-weight: normal;
+       }
+
        &-wrapper {
-               .mw-rcfilters-ui-table {
-                       margin-top: 0.3em;
+               &-top {
+                       display: flex;
+                       flex-wrap: nowrap;
+                       justify-content: space-between;
+
+                       &-title {
+                               padding: 0.6em 0; // Same top padding as the handle
+                               flex: 0 0 auto;
+                       }
+                       &-queryName {
+                               flex: 1 1 auto;
+                               padding: 0.6em 0; // Same top padding as the handle
+                               white-space: nowrap;
+                               min-width: 0; // This has to be here to enable the text truncation
+                               overflow: hidden;
+                               text-overflow: ellipsis;
+                       }
+
+                       &-hideshow {
+                               flex: 0 0 auto;
+                               margin-left: 0.5em;
+                               padding-left: 0.5em;
+                       }
                }
 
                &-content {
                        &-title {
                                font-weight: bold;
                                color: @colorGray5;
+                               white-space: nowrap;
                        }
 
                        &-savedQueryTitle {
                                color: @colorGray2;
+                               padding-left: 1em;
                                font-weight: bold;
                                vertical-align: top;
-                               margin-left: 1em;
-                               width: ~'calc( 100% - 10em )';
                                overflow: hidden;
                                text-overflow: ellipsis;
                                white-space: nowrap;
+                               // This is necessary for Firefox to be able to
+                               // truncate the text. Without this rule, the label
+                               // is treated as if it's full-width, and while it is
+                               // being truncated with the overflow:hidden,
+                               // the ellipses isn't showing properly.
+                               // This rule seems to convince Firefox to re-render,
+                               // fix the label's width properly, and add the ellipses
+                               max-width: 100%;
                        }
                }
        }
                                border: 1px solid @colorGray10;
                                border-left-width: 0;
                                border-radius: 0 0 @borderRadius 0;
+                               // Using the 'left' value from
+                               // .oo-ui-buttonElement-frameless.oo-ui-iconElement >
+                               // .oo-ui-buttonElement-button > .oo-ui-iconElement-icon
+                               padding-right: 0.35714286em;
 
                                display: block;
                                text-align: right;
index 72b40fe..1cc48e2 100644 (file)
                .oo-ui-checkboxInputWidget {
                        // Workaround for IE11 rendering issues. T162098
                        display: block;
+                       padding-top: 1em;
+               }
+
+               label {
+                       // Workaround for Chrome browser bug (T199932)
+                       // Override padding rule from FieldLayout
+                       padding-left: 0 !important; /* stylelint-disable-line declaration-no-important */
                }
        }
 
index 1db7c1d..f210a44 100644 (file)
@@ -6,6 +6,8 @@
        &.oo-ui-toggleWidget-on {
                position: relative;
                overflow: hidden;
+               z-index: 0;
+
                &:after {
                        content: '';
                        mix-blend-mode: screen;
index e72fbda..6746237 100644 (file)
@@ -8,7 +8,12 @@
        &-placeholder {
                &-title {
                        font-weight: bold;
-                       margin-bottom: 1em;
+                       margin-bottom: 0.4375em; // 7px / 16
+                       margin-top: 0.1875em; // 3px / 16
+               }
+
+               &-description {
+                       line-height: 1.5em; // 24px / 16
                }
 
                // Extra specificity needed to override OOUI rule that sets white-space: nowrap;
index 4307c6f..52f7ff2 100644 (file)
@@ -7,6 +7,10 @@
 
        &-editWatchlistButton {
                vertical-align: bottom;
+               // Match the width that we are setting up for the loading
+               // of the .watchlistDetails in mw.rcfilters.less
+               min-width: 20em;
+               text-align: right;
 
                // actual button
                .oo-ui-buttonWidget {
index b49a1cb..3a83eec 100644 (file)
                this.changesListViewModel = changesListViewModel;
                this.controller = controller;
                this.highlightClasses = null;
-               this.filtersModelInitialized = false;
 
                // Events
                this.filtersViewModel.connect( this, {
                        itemUpdate: 'onItemUpdate',
-                       highlightChange: 'onHighlightChange',
-                       initialize: 'onFiltersModelInitialize'
+                       highlightChange: 'onHighlightChange'
                } );
                this.changesListViewModel.connect( this, {
                        invalidate: 'onModelInvalidate',
 
        OO.inheritClass( mw.rcfilters.ui.ChangesListWrapperWidget, OO.ui.Widget );
 
-       /**
-        * Respond to filters model initialize event
-        */
-       mw.rcfilters.ui.ChangesListWrapperWidget.prototype.onFiltersModelInitialize = function () {
-               this.filtersModelInitialized = true;
-               // Set up highlight containers. We need to wait for the filters model
-               // to be initialized, so we can make sure we have all the css class definitions
-               // we get from the server with our filters
-               this.setupHighlightContainers( this.$element );
-       };
-
        /**
         * Get all available highlight classes
         *
@@ -98,7 +85,9 @@
         * Respond to a filter item model update
         */
        mw.rcfilters.ui.ChangesListWrapperWidget.prototype.onItemUpdate = function () {
-               if ( this.filtersModelInitialized && this.filtersViewModel.isHighlightEnabled() ) {
+               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();
                }
                                }
                        }
 
-                       // Set up highlight containers
-                       this.setupHighlightContainers( this.$element );
-
                        // Apply highlight
                        this.applyHighlight();
 
                        .fadeIn( 1000 );
        };
 
-       /**
-        * Set up the highlight containers with all color circle indicators.
-        *
-        * @param {jQuery|string} $content The content of the updated changes list
-        */
-       mw.rcfilters.ui.ChangesListWrapperWidget.prototype.setupHighlightContainers = function ( $content ) {
-               var $enhancedTopPageCell, $enhancedNestedPagesCell,
-                       widget = this,
-                       highlightClass = 'mw-rcfilters-ui-changesListWrapperWidget-highlights',
-                       $highlights = $( '<div>' )
-                               .addClass( highlightClass )
-                               .append(
-                                       $( '<div>' )
-                                               .addClass( 'mw-rcfilters-ui-changesListWrapperWidget-highlights-circle' )
-                                               .addClass( 'mw-rcfilters-ui-changesListWrapperWidget-highlights-color-none' )
-                                               .prop( 'data-color', 'none' )
-                               );
-
-               if ( $( '.mw-rcfilters-ui-changesListWrapperWidget-highlights' ).length ) {
-                       // Already set up
-                       return;
-               }
-
-               mw.rcfilters.HighlightColors.forEach( function ( color ) {
-                       $highlights.append(
-                               $( '<div>' )
-                                       .addClass( 'mw-rcfilters-ui-changesListWrapperWidget-highlights-color-' + color )
-                                       .addClass( 'mw-rcfilters-ui-changesListWrapperWidget-highlights-circle' )
-                                       .prop( 'data-color', color )
-                       );
-               } );
-
-               if ( this.inEnhancedMode() ) {
-                       $enhancedTopPageCell = $content.find( 'table.mw-enhanced-rc.mw-collapsible' );
-                       $enhancedNestedPagesCell = $content.find( 'td.mw-enhanced-rc-nested' );
-
-                       // Enhanced RC highlight containers
-                       $content.find( 'table.mw-enhanced-rc tr:first-child' )
-                               .addClass( 'mw-rcfilters-ui-changesListWrapperWidget-enhanced-toplevel' )
-                               .prepend(
-                                       $( '<td>' )
-                                               .append( $highlights.clone() )
-                               );
-
-                       // We are adding and changing cells in a table that, despite having nested rows,
-                       // is actually all one big table. To prevent the highlights cell in the "nested"
-                       // rows from stretching out the cell with the flags and timestamp in the top row,
-                       // we give the latter colspan=2. Then to make things line up again, we add
-                       // an empty <td> to the "nested" rows.
-
-                       // Set colspan=2 on cell with flags and timestamp in top row
-                       $content.find( 'table.mw-enhanced-rc tr:first-child td.mw-enhanced-rc' )
-                               .prop( 'colspan', '2' );
-                       // Add empty <td> to nested rows to compensate
-                       $enhancedNestedPagesCell.parent().prepend( $( '<td>' ) );
-                       // Add highlights cell to nested rows
-                       $enhancedNestedPagesCell
-                               .before(
-                                       $( '<td>' )
-                                               .append( $highlights.clone().addClass( 'mw-enhanced-rc-nested' ) )
-                               );
-
-                       // We need to target the nested rows differently than the top rows so that the
-                       // LESS rules applies correctly. In top rows, the rule should highlight all but
-                       // the first 2 cells td:not( :nth-child( -n+2 ) and the nested rows, the rule
-                       // should highlight all but the first 4 cells td:not( :nth-child( -n+4 )
-                       $enhancedNestedPagesCell
-                               .closest( 'tr' )
-                               .addClass( 'mw-rcfilters-ui-changesListWrapperWidget-enhanced-nested' );
-
-                       // Go over pages that have sub results
-                       // HACK: We really only can collect those by targetting the collapsible class
-                       $enhancedTopPageCell.each( function () {
-                               var collectedClasses,
-                                       $table = $( this );
-
-                               // Go over <tr>s and pick up all recognized classes
-                               collectedClasses = widget.getHighlightClasses().filter( function ( className ) {
-                                       return $table.find( 'tr' ).hasClass( className );
-                               } );
-
-                               $table.find( 'tr:first-child' )
-                                       .addClass( collectedClasses.join( ' ' ) );
-                       } );
-
-                       $content.addClass( 'mw-rcfilters-ui-changesListWrapperWidget-enhancedView' );
-               } else {
-                       // Regular RC
-                       $content.find( 'ul.special li' )
-                               .prepend( $highlights.clone() );
-
-                       $content.removeClass( 'mw-rcfilters-ui-changesListWrapperWidget-enhancedView' );
-               }
-       };
-
        /**
         * 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
index c840d7c..e3de55e 100644 (file)
@@ -7,34 +7,24 @@
         * @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
         */
-       mw.rcfilters.ui.FilterItemHighlightButton = function MwRcfiltersUiFilterItemHighlightButton( controller, model, config ) {
+       mw.rcfilters.ui.FilterItemHighlightButton = function MwRcfiltersUiFilterItemHighlightButton( controller, model, highlightPopup, config ) {
                config = config || {};
 
-               this.colorPickerWidget = new mw.rcfilters.ui.HighlightColorPickerWidget( controller, model );
-
                // Parent
                mw.rcfilters.ui.FilterItemHighlightButton.parent.call( this, $.extend( true, {}, config, {
                        icon: 'highlight',
-                       indicator: 'down',
-                       popup: {
-                               anchor: false,
-                               padded: true,
-                               align: 'backwards',
-                               horizontalPosition: 'end',
-                               $floatableContainer: this.$element,
-                               width: 290,
-                               $content: this.colorPickerWidget.$element
-                       }
+                       indicator: 'down'
                } ) );
 
                this.controller = controller;
                this.model = model;
+               this.popup = highlightPopup;
 
                // Event
                this.model.connect( this, { update: 'updateUiBasedOnModel' } );
-               this.colorPickerWidget.connect( this, { chooseColor: 'onChooseColor' } );
                // This lives inside a MenuOptionWidget, which intercepts mousedown
                // to select the item. We want to prevent that when we click the highlight
                // button
 
        /* Methods */
 
+       mw.rcfilters.ui.FilterItemHighlightButton.prototype.onAction = function () {
+               this.popup.setAssociatedButton( this );
+               this.popup.setFilterItem( this.model );
+
+               // Parent method
+               mw.rcfilters.ui.FilterItemHighlightButton.parent.prototype.onAction.call( this );
+       };
+
        /**
         * Respond to item model update event
         */
@@ -79,8 +77,4 @@
                                );
                } );
        };
-
-       mw.rcfilters.ui.FilterItemHighlightButton.prototype.onChooseColor = function () {
-               this.popup.toggle( false );
-       };
 }( mediaWiki, jQuery ) );
index 926502d..65b4420 100644 (file)
@@ -9,10 +9,11 @@
         * @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
         */
        mw.rcfilters.ui.FilterMenuOptionWidget = function MwRcfiltersUiFilterMenuOptionWidget(
-               controller, filtersViewModel, invertModel, itemModel, config
+               controller, filtersViewModel, invertModel, itemModel, highlightPopup, config
        ) {
                config = config || {};
 
@@ -21,7 +22,7 @@
                this.model = itemModel;
 
                // Parent
-               mw.rcfilters.ui.FilterMenuOptionWidget.parent.call( this, controller, filtersViewModel, this.invertModel, itemModel, config );
+               mw.rcfilters.ui.FilterMenuOptionWidget.parent.call( this, controller, filtersViewModel, this.invertModel, itemModel, highlightPopup, config );
 
                // Event
                this.model.getGroupModel().connect( this, { update: 'onGroupModelUpdate' } );
index 953df5b..6d36c71 100644 (file)
@@ -12,6 +12,9 @@
         * @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
         */
        mw.rcfilters.ui.FilterTagMultiselectWidget = function MwRcfiltersUiFilterTagMultiselectWidget( controller, model, savedQueriesModel, config ) {
                var rcFiltersRow,
                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
                mw.rcfilters.ui.FilterTagMultiselectWidget.parent.call( this, $.extend( true, {
                        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 mw.rcfilters.ui.SaveFiltersPopupButtonWidget(
                                this.controller,
 
                // 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',
                                .append(
                                        $( '<div>' )
                                                .addClass( 'mw-rcfilters-ui-row' )
+                                               .addClass( 'mw-rcfilters-ui-filterTagMultiselectWidget-views' )
                                                .append(
                                                        $( '<div>' )
                                                                .addClass( 'mw-rcfilters-ui-cell' )
 
                // Build the content
                $contentWrapper.append(
-                       title.$element,
-                       this.savedQueryTitle.$element,
                        $( '<div>' )
-                               .addClass( 'mw-rcfilters-ui-table' )
+                               .addClass( 'mw-rcfilters-ui-filterTagMultiselectWidget-wrapper-top' )
                                .append(
-                                       rcFiltersRow
-                               )
+                                       $( '<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
 
        /* Methods */
 
+       /**
+        * Override parent method to avoid unnecessary resize events.
+        */
+       mw.rcfilters.ui.FilterTagMultiselectWidget.prototype.updateIfHeightChanged = function () { };
+
        /**
         * Respond to view select widget choose event
         *
         * @inheritdoc
         */
        mw.rcfilters.ui.FilterTagMultiselectWidget.prototype.onMouseDown = function ( e ) {
-               if ( !this.isDisabled() && e.which === OO.ui.MouseButtons.LEFT ) {
+               if ( !this.collapsed && !this.isDisabled() && e.which === OO.ui.MouseButtons.LEFT ) {
                        this.menu.toggle();
 
                        return false;
         * @inheritdoc
         */
        mw.rcfilters.ui.FilterTagMultiselectWidget.prototype.onChangeTags = function () {
-               // Parent method
-               mw.rcfilters.ui.FilterTagMultiselectWidget.parent.prototype.onChangeTags.call( this );
+               // If initialized, call parent method.
+               if ( this.controller.isInitialized() ) {
+                       mw.rcfilters.ui.FilterTagMultiselectWidget.parent.prototype.onChangeTags.call( this );
+               }
 
                this.emptyFilterMessage.toggle( this.isEmpty() );
        };
                        ) {
                                this.addTag( item.getName(), item.getLabel() );
                        } else {
-                               this.removeTagByData( item.getName() );
+                               // 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() );
+                               }
                        }
                }
 
                        // Remove capsule widgets if they're not selected
                        highlightedItems.forEach( function ( filterItem ) {
                                if ( !filterItem.isSelected() ) {
-                                       this.removeTagByData( filterItem.getName() );
+                                       // 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 ) );
                }
                }
        };
 
+       /**
+        * Respond to hide/show button click
+        */
+       mw.rcfilters.ui.FilterTagMultiselectWidget.prototype.onHideShowButtonClick = function () {
+               this.toggleCollapsed();
+       };
+
+       /**
+        * Toggle the collapsed state of the filters widget
+        *
+        * @param {boolean} isCollapsed Widget is collapsed
+        */
+       mw.rcfilters.ui.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
         */
index dba24fc..a5a8187 100644 (file)
@@ -13,6 +13,9 @@
         * @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
         */
        mw.rcfilters.ui.FilterWrapperWidget = function MwRcfiltersUiFilterWrapperWidget(
                controller, model, savedQueriesModel, changesListModel, config
                this.queriesModel = savedQueriesModel;
                this.changesListModel = changesListModel;
                this.$overlay = config.$overlay || this.$element;
+               this.$wrapper = config.$wrapper || this.$element;
 
                this.filterTagWidget = new mw.rcfilters.ui.FilterTagMultiselectWidget(
                        this.controller,
                        this.model,
                        this.queriesModel,
-                       { $overlay: this.$overlay }
+                       {
+                               $overlay: this.$overlay,
+                               collapsed: config.collapsed,
+                               $wrapper: this.$wrapper
+                       }
                );
 
                this.liveUpdateButton = new mw.rcfilters.ui.LiveUpdateButtonWidget(
index 64a7fcf..fda0772 100644 (file)
@@ -7,10 +7,9 @@
         *
         * @constructor
         * @param {mw.rcfilters.Controller} controller RCFilters controller
-        * @param {mw.rcfilters.dm.FilterItem} model Filter item model
         * @param {Object} [config] Configuration object
         */
-       mw.rcfilters.ui.HighlightColorPickerWidget = function MwRcfiltersUiHighlightColorPickerWidget( controller, model, config ) {
+       mw.rcfilters.ui.HighlightColorPickerWidget = function MwRcfiltersUiHighlightColorPickerWidget( controller, config ) {
                var colors = [ 'none' ].concat( mw.rcfilters.HighlightColors );
                config = config || {};
 
@@ -22,7 +21,6 @@
                } ) );
 
                this.controller = controller;
-               this.model = model;
 
                this.currentSelection = 'none';
                this.buttonSelect = new OO.ui.ButtonSelectWidget( {
                } );
 
                // Event
-               this.model.connect( this, { update: 'updateUiBasedOnModel' } );
                this.buttonSelect.connect( this, { choose: 'onChooseColor' } );
 
-               this.updateUiBasedOnModel();
-
                this.$element
                        .addClass( 'mw-rcfilters-ui-highlightColorPickerWidget' )
                        .append(
 
        /* Methods */
 
+       /**
+        * Bind the color picker to an item
+        * @param {mw.rcfilters.dm.FilterItem} filterItem
+        */
+       mw.rcfilters.ui.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
         */
        mw.rcfilters.ui.HighlightColorPickerWidget.prototype.updateUiBasedOnModel = function () {
-               this.selectColor( this.model.getHighlightColor() || 'none' );
+               this.selectColor( this.filterItem.getHighlightColor() || 'none' );
        };
 
        /**
        mw.rcfilters.ui.HighlightColorPickerWidget.prototype.onChooseColor = function ( button ) {
                var color = button.data;
                if ( color === 'none' ) {
-                       this.controller.clearHighlightColor( this.model.getName() );
+                       this.controller.clearHighlightColor( this.filterItem.getName() );
                } else {
-                       this.controller.setHighlightColor( this.model.getName(), color );
+                       this.controller.setHighlightColor( this.filterItem.getName(), color );
                }
                this.emit( 'chooseColor', color );
        };
diff --git a/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.HighlightPopupWidget.js b/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.HighlightPopupWidget.js
new file mode 100644 (file)
index 0000000..aedecc4
--- /dev/null
@@ -0,0 +1,63 @@
+( function ( mw, $ ) {
+       /**
+        * A popup containing a color picker, for setting highlight colors.
+        *
+        * @extends OO.ui.PopupWidget
+        *
+        * @constructor
+        * @param {mw.rcfilters.Controller} controller RCFilters controller
+        * @param {Object} [config] Configuration object
+        */
+       mw.rcfilters.ui.HighlightPopupWidget = function MwRcfiltersUiHighlightPopupWidget( controller, config ) {
+               config = config || {};
+
+               // Parent
+               mw.rcfilters.ui.HighlightPopupWidget.parent.call( this, $.extend( {
+                       autoClose: true,
+                       anchor: false,
+                       padded: true,
+                       align: 'backwards',
+                       horizontalPosition: 'end',
+                       width: 290
+               }, config ) );
+
+               this.colorPicker = new mw.rcfilters.ui.HighlightColorPickerWidget( controller );
+
+               this.colorPicker.connect( this, { chooseColor: 'onChooseColor' } );
+
+               this.$body.append( this.colorPicker.$element );
+       };
+
+       /* Initialization */
+
+       OO.inheritClass( mw.rcfilters.ui.HighlightPopupWidget, OO.ui.PopupWidget );
+
+       /* 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
+        */
+       mw.rcfilters.ui.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
+        */
+       mw.rcfilters.ui.HighlightPopupWidget.prototype.setFilterItem = function ( item ) {
+               this.colorPicker.setFilterItem( item );
+       };
+
+       /**
+        * When the user chooses a color in the color picker, close the popup.
+        */
+       mw.rcfilters.ui.HighlightPopupWidget.prototype.onChooseColor = function () {
+               this.toggle( false );
+       };
+
+}( mediaWiki, jQuery ) );
index 8c349e5..83d510b 100644 (file)
@@ -9,10 +9,11 @@
         * @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
         */
        mw.rcfilters.ui.ItemMenuOptionWidget = function MwRcfiltersUiItemMenuOptionWidget(
-               controller, filtersViewModel, invertModel, itemModel, config
+               controller, filtersViewModel, invertModel, itemModel, highlightPopup, config
        ) {
                var layout,
                        classes = [],
@@ -55,6 +56,7 @@
                this.highlightButton = new mw.rcfilters.ui.FilterItemHighlightButton(
                        this.controller,
                        this.itemModel,
+                       highlightPopup,
                        {
                                $overlay: config.$overlay || this.$element,
                                title: mw.msg( 'rcfilters-highlightmenu-help' )
index 8002045..eab8499 100644 (file)
@@ -14,6 +14,9 @@
         * @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
         */
        mw.rcfilters.ui.MainWrapperWidget = function MwRcfiltersUiMainWrapperWidget(
                controller, model, savedQueriesModel, changesListModel, config
@@ -31,6 +34,7 @@
                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 mw.rcfilters.ui.SavedLinksListWidget(
                        controller, savedQueriesModel, { $overlay: this.$overlay }
@@ -42,7 +46,9 @@
                        savedQueriesModel,
                        changesListModel,
                        {
-                               $overlay: this.$overlay
+                               $overlay: this.$overlay,
+                               $wrapper: this.$wrapper,
+                               collapsed: config.collapsed
                        }
                );
 
index d968f0c..40b2fcf 100644 (file)
 
                this.menuInitialized = true;
 
+               // Create shared popup for highlight buttons
+               this.highlightPopup = new mw.rcfilters.ui.HighlightPopupWidget( this.controller );
+               this.$overlay.append( this.highlightPopup.$element );
+
                // Count groups per view
                $.each( groups, function ( groupName, groupModel ) {
                        if ( !groupModel.isHidden() ) {
                                                        widget.model,
                                                        widget.model.getInvertModel(),
                                                        filterItem,
+                                                       widget.highlightPopup,
                                                        {
                                                                $overlay: widget.$overlay
                                                        }
         */
        mw.rcfilters.ui.MenuSelectWidget.prototype.onModelInitialize = function () {
                this.menuInitialized = false;
+               // Set timeout for the menu to lazy build.
+               setTimeout( this.lazyMenuCreation.bind( this ) );
        };
 
        /**
index 060ead0..c13c2f7 100644 (file)
@@ -56,7 +56,7 @@
                                } ),
                                new OO.ui.MenuOptionWidget( {
                                        data: 'delete',
-                                       icon: 'close',
+                                       icon: 'trash',
                                        label: mw.msg( 'rcfilters-savedqueries-remove' )
                                } ),
                                new OO.ui.MenuOptionWidget( {
index f62cb97..e9a2b08 100644 (file)
@@ -63,12 +63,6 @@ textarea {
        display: none;
 }
 
-#jump-to-nav {
-       /* Negate #contentSub's margin and replicate it so that the jump to links don't affect the spacing */
-       margin-top: -1.4em;
-       margin-bottom: 1.4em;
-}
-
 #contentSub,
 #contentSub2 {
        font-size: 84%;
index f936658..7c0d232 100644 (file)
                        var apiPromise,
                                deferred = $.Deferred();
 
-                       if ( moduleInfoCache.hasOwnProperty( module ) ) {
+                       if ( Object.prototype.hasOwnProperty.call( moduleInfoCache, module ) ) {
                                return deferred
                                        .resolve( moduleInfoCache[ module ] )
                                        .promise( { abort: function () {} } );
 
                                subpages = page.getSubpages();
                                for ( i = 0; i < subpages.length; i++ ) {
-                                       if ( pages.hasOwnProperty( subpages[ i ].key ) ) {
+                                       if ( Object.prototype.hasOwnProperty.call( pages, subpages[ i ].key ) ) {
                                                checkPages.push( pages[ subpages[ i ].key ] );
                                        }
                                }
                                        if ( page.getSubpages ) {
                                                subpages = page.getSubpages();
                                                for ( j = 0; j < subpages.length; j++ ) {
-                                                       if ( !pages.hasOwnProperty( subpages[ j ].key ) ) {
+                                                       if ( !Object.prototype.hasOwnProperty.call( pages, subpages[ j ].key ) ) {
                                                                subpages[ j ].indentLevel = page.indentLevel + 1;
                                                                pages[ subpages[ j ].key ] = new ApiSandbox.PageLayout( subpages[ j ] );
                                                        }
                                page.getQueryParams( params, displayParams );
                                subpages = page.getSubpages();
                                for ( i = 0; i < subpages.length; i++ ) {
-                                       if ( pages.hasOwnProperty( subpages[ i ].key ) ) {
+                                       if ( Object.prototype.hasOwnProperty.call( pages, subpages[ i ].key ) ) {
                                                checkPages.push( pages[ subpages[ i ].key ] );
                                        }
                                }
 
                                // Force a 'fm' format with wrappedhtml=1, if available
                                if ( params.format !== undefined ) {
-                                       if ( availableFormats.hasOwnProperty( params.format + 'fm' ) ) {
+                                       if ( Object.prototype.hasOwnProperty.call( availableFormats, params.format + 'fm' ) ) {
                                                params.format = params.format + 'fm';
                                        }
                                        if ( params.format.substr( -2 ) === 'fm' ) {
 
                                subpages = page.getSubpages();
                                for ( i = 0; i < subpages.length; i++ ) {
-                                       if ( pages.hasOwnProperty( subpages[ i ].key ) ) {
+                                       if ( Object.prototype.hasOwnProperty.call( pages, subpages[ i ].key ) ) {
                                                checkPages.push( pages[ subpages[ i ].key ] );
                                        }
                                }
                                page.apiCheckValid();
                                subpages = page.getSubpages();
                                for ( i = 0; i < subpages.length; i++ ) {
-                                       if ( pages.hasOwnProperty( subpages[ i ].key ) ) {
+                                       if ( Object.prototype.hasOwnProperty.call( pages, subpages[ i ].key ) ) {
                                                checkPages.push( pages[ subpages[ i ].key ] );
                                        }
                                }
                                                }
                                        }
                                        if ( params ) {
-                                               tmp.widget.setApiValue( params.hasOwnProperty( name ) ? params[ name ] : undefined );
+                                               tmp.widget.setApiValue( Object.prototype.hasOwnProperty.call( params, name ) ? params[ name ] : undefined );
                                        }
                                } else {
                                        newVars = {};
                                        buttons = [],
                                        filterFmModules = function ( v ) {
                                                return v.substr( -2 ) !== 'fm' ||
-                                                       !availableFormats.hasOwnProperty( v.substr( 0, v.length - 2 ) );
+                                                       !Object.prototype.hasOwnProperty.call( availableFormats, v.substr( 0, v.length - 2 ) );
                                        };
 
                                // This is something of a hack. We always want the 'format' and
                        this.loadFromQueryParams = params;
                } else {
                        $.each( this.widgets, function ( name, widget ) {
-                               var v = params.hasOwnProperty( name ) ? params[ name ] : undefined;
+                               var v = Object.prototype.hasOwnProperty.call( params, name ) ? params[ name ] : undefined;
                                widget.setApiValue( v );
                        } );
                        this.updateTemplatedParameters( params );
index 65860ea..1b37ec3 100644 (file)
@@ -54,3 +54,9 @@
 .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 f65a257..6558bda 100644 (file)
@@ -1,12 +1,38 @@
 ( function ( mw, $ ) {
+
+       // Return a promise that is resolved when the element is blurred (loses focus).
+       // If it already is blurred, resolved immediately.
+       function whenBlurred( $elem ) {
+               var deferred = $.Deferred();
+               if ( $elem.is( ':focus' ) ) {
+                       $elem.one( 'blur', deferred.resolve );
+               } else {
+                       deferred.resolve();
+               }
+               return deferred.promise();
+       }
+
        $( function () {
-               var startInput = mw.widgets.DateInputWidget.static.infuse( 'mw-date-start' ),
-                       endInput = mw.widgets.DateInputWidget.static.infuse( 'mw-date-end' );
+               var startReady, endReady;
+
+               // Do not infuse the date input while it has user focus.
+               // This is especially important on Firefox, where hiding the native date input while the native
+               // date picker is open will cause the date picker to remain visible (but non-functional), but
+               // not replacing the interface while the user is working with it is probably a good idea anyway.
+               startReady = whenBlurred( $( '#mw-date-start .oo-ui-inputWidget-input' ) ).then( function () {
+                       return mw.widgets.DateInputWidget.static.infuse( 'mw-date-start' );
+               } );
+               endReady = whenBlurred( $( '#mw-date-end .oo-ui-inputWidget-input' ) ).then( function () {
+                       return mw.widgets.DateInputWidget.static.infuse( 'mw-date-end' );
+               } );
 
-               startInput.on( 'deactivate', function ( userSelected ) {
-                       if ( userSelected ) {
-                               endInput.focus();
-                       }
+               $.when( startReady, endReady ).then( function ( startInput, endInput ) {
+                       startInput.on( 'deactivate', function ( userSelected ) {
+                               if ( userSelected ) {
+                                       endInput.focus();
+                               }
+                       } );
                } );
        } );
+
 }( mediaWiki, jQuery ) );
index 40c9df9..11ed425 100644 (file)
@@ -8,18 +8,12 @@
                $preferences = $( '#preferences' );
 
                // Make sure the accessibility tip is selectable so that screen reader users take notice,
-               // but hide it per default to reduce interface clutter. Also make sure it becomes visible
-               // when selected. Similar to jquery.mw-jump
+               // but hide it by default to reduce visual clutter.
+               // Make sure it becomes visible when focused.
                $( '<div>' ).addClass( 'mw-navigation-hint' )
                        .text( mw.msg( 'prefs-tabs-navigation-hint' ) )
                        .attr( 'tabIndex', 0 )
-                       .on( 'focus blur', function ( e ) {
-                               if ( e.type === 'blur' || e.type === 'focusout' ) {
-                                       $( this ).css( 'height', '0' );
-                               } else {
-                                       $( this ).css( 'height', 'auto' );
-                               }
-                       } ).prependTo( '#mw-content-text' );
+                       .prependTo( '#mw-content-text' );
 
                tabs = new OO.ui.IndexLayout( {
                        expanded: false,
index 33b630a..bdcfb79 100644 (file)
@@ -25,7 +25,6 @@
 
 /*
  * Hide, but keep accessible for screen-readers.
- * Like .mw-jump, #jump-to-nav from shared.css
  */
 .client-js .mw-navigation-hint {
        overflow: hidden;
diff --git a/resources/src/mediawiki.special.preferences.styles.ooui.css b/resources/src/mediawiki.special.preferences.styles.ooui.css
deleted file mode 100644 (file)
index a72186b..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
-/* Reuses colors from mediawiki.legacy/shared.css */
-.mw-email-not-authenticated .oo-ui-labelWidget,
-.mw-email-none .oo-ui-labelWidget {
-       border: 1px solid #fde29b;
-       background-color: #fdf1d1;
-       color: #000;
-       padding: 0.5em;
-}
-/* Authenticated email field has its own class too. Unstyled by default */
-/*
-.mw-email-authenticated .oo-ui-labelWidget { }
-*/
-
-/* This is needed because add extra buttons in a weird way */
-.mw-prefs-buttons .mw-htmlform-submit-buttons {
-       margin: 0;
-       display: inline;
-}
-
-.mw-prefs-buttons {
-       margin-top: 1em;
-}
-
-#prefcontrol {
-       margin-right: 0.5em;
-}
-
-/*
- * Hide, but keep accessible for screen-readers.
- * Like .mw-jump, #jump-to-nav from shared.css
- */
-.client-js .mw-navigation-hint {
-       overflow: hidden;
-       height: 0;
-       zoom: 1;
-}
-
-/* Override OOUI styles so that dropdowns near the bottom of the form don't get clipped,
- * e.g.'Appearance' / 'Threshold for stub link formatting'. This is hacky and bad, it would be
- * better solved by setting overlays for the widgets, but we can't do it from PHP... */
-#preferences .oo-ui-panelLayout {
-       position: static;
-       overflow: visible;
-       -webkit-transform: none;
-       transform: none;
-}
-
-#preferences .oo-ui-menuLayout .oo-ui-panelLayout-framed .oo-ui-panelLayout-framed {
-       border-width: 0;
-       border-radius: 0;
-       box-shadow: none;
-       padding-left: 0;
-       padding-right: 0;
-}
-
-.mw-prefs-faketabs > .oo-ui-menuLayout > .oo-ui-menuLayout-menu a {
-       color: inherit;
-       text-decoration: none;
-}
-
-/* Adjust the borders when JS is disabled: frame each prefsection instead of the
- * whole tabLayout wrapper */
-.client-nojs #preferences .oo-ui-menuLayout .oo-ui-panelLayout-framed .oo-ui-panelLayout-framed {
-       border-color: #c8ccd1;
-       border-width: 1px 0 0;
-}
-
-.client-nojs .mw-prefs-faketabs {
-       border-width: 0;
-       border-radius: 0;
-       box-shadow: none;
-}
-
-.client-nojs .mw-prefs-faketabs > .oo-ui-menuLayout > .oo-ui-menuLayout-content > .oo-ui-stackLayout {
-       margin-bottom: 1em;
-}
-
-/* Hide the tab menu when JS is disabled as we can't use this feature */
-.client-nojs .mw-prefs-faketabs > .oo-ui-menuLayout > .oo-ui-menuLayout-menu {
-       display: none;
-}
-
-.client-nojs #preferences .oo-ui-panelLayout-framed .oo-ui-panelLayout-framed:last-child {
-       padding-bottom: 0;
-       margin-bottom: 0;
-}
-
-/* Hide top level legends when JS is enabled, as they will not be visible
- * when the real tabLayout is built */
-.client-js #preferences .oo-ui-tabPanelLayout > fieldset > legend {
-       display: none;
-}
-
-.client-js #preferences .oo-ui-tabPanelLayout {
-       padding-top: 0.5em;
-}
-
-.client-js #preferences .oo-ui-panelLayout-framed .oo-ui-panelLayout-framed {
-       margin-left: 0;
-       margin-bottom: 0;
-       padding: 0;
-       border-width: 0;
-       border-radius: 0;
-       box-shadow: none;
-}
-
-.client-js #preferences > .oo-ui-panelLayout > .oo-ui-fieldsetLayout > .oo-ui-fieldsetLayout-header {
-       margin-bottom: 1em;
-}
-
-/* Make the "Basic information" section more compact */
-/* OOUI's `align: 'left'` for FieldLayouts sucks, so we do our own */
-#mw-htmlform-info > .oo-ui-fieldLayout-align-top > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-header {
-       width: 20%;
-       display: inline-block;
-       vertical-align: middle;
-       padding: 0;
-}
-
-#mw-htmlform-info > .oo-ui-fieldLayout-align-top .oo-ui-fieldLayout-help {
-       margin-right: 0;
-}
-
-#mw-htmlform-info > .oo-ui-fieldLayout.oo-ui-fieldLayout-align-top > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field {
-       width: 80%;
-       display: inline-block;
-       vertical-align: middle;
-}
-
-/* Expand the dropdown and textfield of "Time zone" field to the */
-/* usual maximum width and display them on separate lines. */
-#wpTimeCorrection .oo-ui-dropdownInputWidget,
-#wpTimeCorrection .oo-ui-textInputWidget {
-       display: block;
-       max-width: 50em;
-}
-
-#wpTimeCorrection .oo-ui-textInputWidget {
-       margin-top: 0.5em;
-}
-
-/* HACK: expand width of gadget descriptions.
- * This should be moved to the Gadgets extension */
-#mw-htmlform-gadgets .oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-fieldLayout-body {
-       max-width: none;
-}
diff --git a/resources/src/mediawiki.special.preferences.styles.ooui.less b/resources/src/mediawiki.special.preferences.styles.ooui.less
new file mode 100644 (file)
index 0000000..fac53f3
--- /dev/null
@@ -0,0 +1,157 @@
+@import 'mediawiki.mixins';
+
+/* Reuses colors from mediawiki.legacy/shared.css */
+.mw-email-not-authenticated .oo-ui-labelWidget,
+.mw-email-none .oo-ui-labelWidget {
+       background-color: #fdf1d1;
+       color: #000;
+       border: 1px solid #fde29b;
+       padding: 0.5em;
+}
+/* Authenticated email field has its own class too. Unstyled by default */
+/*
+.mw-email-authenticated .oo-ui-labelWidget { }
+*/
+
+/* This is needed because add extra buttons in a weird way */
+.mw-prefs-buttons .mw-htmlform-submit-buttons {
+       display: inline;
+       margin: 0;
+}
+
+.mw-prefs-buttons {
+       margin-top: 1em;
+}
+
+#prefcontrol {
+       margin-right: 0.5em;
+}
+
+/*
+ * Hide, but keep accessible for screen-readers.
+ */
+.client-js .mw-navigation-hint:not( :focus ) {
+       .mixin-screen-reader-text;
+}
+
+/* Override OOUI styles so that dropdowns near the bottom of the form don't get clipped,
+ * e.g.'Appearance' / 'Threshold for stub link formatting'. This is hacky and bad, it would be
+ * better solved by setting overlays for the widgets, but we can't do it from PHP... */
+#preferences .oo-ui-panelLayout {
+       position: static;
+       overflow: visible;
+       .transform( none );
+}
+
+#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;
+}
+
+.mw-prefs-faketabs > .oo-ui-menuLayout > .oo-ui-menuLayout-menu a {
+       color: inherit;
+       text-decoration: none;
+}
+
+/* Disabled JavaScript */
+.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 {
+               border-width: 0;
+               border-radius: 0;
+               .box-shadow( none );
+
+               > .oo-ui-menuLayout > .oo-ui-menuLayout-content > .oo-ui-stackLayout {
+                       margin-bottom: 1em;
+               }
+
+               /* Hide the tab menu when JS is disabled as we can't use this feature */
+               > .oo-ui-menuLayout > .oo-ui-menuLayout-menu {
+                       display: none;
+               }
+       }
+}
+
+/* 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 {
+       .oo-ui-tabPanelLayout {
+               padding-top: 0.5em;
+
+               & > 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 > .oo-ui-fieldsetLayout > .oo-ui-fieldsetLayout-header {
+               margin-bottom: 1em;
+       }
+}
+
+/* Make the "Basic information" section more compact */
+/* OOUI's `align: 'left'` for FieldLayouts sucks, so we do our own */
+#mw-htmlform-info {
+       > .oo-ui-fieldLayout-align-top > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-header {
+               display: inline-block;
+               width: 20%;
+               padding: 0;
+               vertical-align: middle;
+       }
+
+       > .oo-ui-fieldLayout-align-top .oo-ui-fieldLayout-help {
+               margin-right: 0;
+       }
+
+       > .oo-ui-fieldLayout.oo-ui-fieldLayout-align-top > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field {
+               display: inline-block;
+               width: 80%;
+               vertical-align: middle;
+       }
+}
+
+/* Expand the dropdown and textfield of "Time zone" field to the */
+/* usual maximum width and display them on separate lines. */
+#wpTimeCorrection .oo-ui-dropdownInputWidget,
+#wpTimeCorrection .oo-ui-textInputWidget {
+       display: block;
+       max-width: 50em;
+}
+
+#wpTimeCorrection .oo-ui-textInputWidget {
+       margin-top: 0.5em;
+}
+
+/* HACK: expand width of gadget descriptions.
+ * This should be moved to the Gadgets extension */
+#mw-htmlform-gadgets .oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-fieldLayout-body {
+       max-width: none;
+}
index 0d97d68..598b8f8 100644 (file)
@@ -27,8 +27,8 @@
                $fieldsets.children( 'legend' ).addClass( 'mainLegend' );
 
                // Make sure the accessibility tip is selectable so that screen reader users take notice,
-               // but hide it per default to reduce interface clutter. Also make sure it becomes visible
-               // when selected. Similar to jquery.mw-jump
+               // but hide it by default to reduce visual clutter.
+               // Make sure it becomes visible when focused.
                $( '<div>' ).addClass( 'mw-navigation-hint' )
                        .text( mw.msg( 'prefs-tabs-navigation-hint' ) )
                        .attr( 'tabIndex', 0 )
index 144659a..da54ad2 100644 (file)
@@ -37,7 +37,7 @@
                                clearTimeout( this.timeoutID );
                        }
                        // Check response cache
-                       if ( this.responseCache.hasOwnProperty( this.nameToCheck ) ) {
+                       if ( Object.prototype.hasOwnProperty.call( this.responseCache, this.nameToCheck ) ) {
                                this.setWarning( this.responseCache[ this.nameToCheck ] );
                                return;
                        }
                        var template = $element.val(),
                                $spinner;
 
-                       if ( this.responseCache.hasOwnProperty( template ) ) {
+                       if ( Object.prototype.hasOwnProperty.call( this.responseCache, template ) ) {
                                this.showPreview( this.responseCache[ template ], $previewContainer );
                                return;
                        }
diff --git a/resources/src/mediawiki.special/newpages.less b/resources/src/mediawiki.special/newpages.less
new file mode 100644 (file)
index 0000000..bac0846
--- /dev/null
@@ -0,0 +1,15 @@
+/*!
+ * Styling for Special:NewPages
+ */
+
+// 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`
+
+@ooui-spacing-medium: 12 / @ooui-font-size-browser / @ooui-font-size-base; // equals `0.8571429em`≈`12px`
+@ooui-spacing-large: 16 / @ooui-font-size-browser / @ooui-font-size-base; // equals `1.1428571em`≈`16px`
+
+.mw-htmlform-ooui .mw-htmlform-field-HTMLSizeFilterField,
+.mw-htmlform-ooui .mw-htmlform-submit-buttons + div {
+       margin-top: @ooui-spacing-medium;
+}
diff --git a/resources/src/mediawiki.toc.styles/common.css b/resources/src/mediawiki.toc.styles/common.css
new file mode 100644 (file)
index 0000000..31a8826
--- /dev/null
@@ -0,0 +1,6 @@
+/* This style is loaded on all media. */
+
+/* Hide the content of the TOC when the checkbox is checked. */
+.toctogglecheckbox:checked ~ ul {
+       display: none;
+}
diff --git a/resources/src/mediawiki.toc.styles/print.css b/resources/src/mediawiki.toc.styles/print.css
new file mode 100644 (file)
index 0000000..e905dbe
--- /dev/null
@@ -0,0 +1,4 @@
+/* Hide the complete TOC on print when the TOC is hidden. */
+.toctogglecheckbox:checked + .toctitle {
+       display: none;
+}
diff --git a/resources/src/mediawiki.toc.styles/screen.less b/resources/src/mediawiki.toc.styles/screen.less
new file mode 100644 (file)
index 0000000..5137c76
--- /dev/null
@@ -0,0 +1,58 @@
+/* This style adds a toggle button with internationalized message for the TOC. */
+
+/* When the browser supports :checked then overwrite the style="display:none" and make the /*
+/* checkbox invisible on another way to allow to focus the checkbox with keyboard. */
+:not( :checked ) > .toctogglecheckbox {
+       display: inline !important; /* stylelint-disable-line declaration-no-important */
+       position: absolute;
+       opacity: 0;
+}
+
+.toctogglespan {
+       font-size: 94%;
+}
+
+/* IE8 does not support :checked and therefor it does not support the hiding at all. */
+/* The selector ":not( :checked ) >" prevents that the useless brackets are shown on IE8. */
+:not( :checked ) > .toctogglespan:before {
+       content: ' [';
+}
+
+:not( :checked ) > .toctogglespan:after {
+       content: ']';
+}
+
+/* Make the label look like a link. */
+.toctogglelabel {
+       cursor: pointer;
+       color: #0645ad;
+}
+
+.toctogglelabel:hover {
+       text-decoration: underline;
+}
+
+/* Show a focus ring around the label when focusing the invisible checkbox. */
+/* This simulates that the label is in focus. */
+.toctogglecheckbox:focus + .toctitle .toctogglelabel {
+       text-decoration: underline;
+       outline: dotted 1px; /* Firefox style for focus */
+       outline: auto -webkit-focus-ring-color; /* Webkit style for focus */
+}
+
+/* Change the text of the button based on the state of the checkbox. */
+.toctogglecheckbox:checked + .toctitle .toctogglelabel:after {
+       content: '@{msg-showtoc}';
+}
+
+.toctogglecheckbox:not( :checked ) + .toctitle .toctogglelabel:after {
+       content: '@{msg-hidetoc}';
+}
+
+/*
+Cached: https://phabricator.wikimedia.org/T195053#4417392
+Can be cleared at least one week after the above comment
+*/
+.toctogglespan ~ .toctoggle {
+       display: none;
+}
index 5e10a5b..4c201a6 100644 (file)
@@ -6,6 +6,7 @@
                $content.find( '.toc' ).addBack( '.toc' ).each( function () {
                        var hideToc,
                                $this = $( this ),
+                               $tocToggleCheckbox = $this.children( '.toctogglecheckbox' ),
                                $tocTitle = $this.find( '.toctitle' ),
                                $tocToggleLink = $this.find( '.togglelink' ),
                                $tocList = $this.find( 'ul' ).eq( 0 );
@@ -27,7 +28,7 @@
 
                        // Only add it if there is a complete TOC and it doesn't
                        // have a toggle added already
-                       if ( $tocTitle.length && $tocList.length && !$tocToggleLink.length ) {
+                       if ( !$tocToggleCheckbox.length && $tocTitle.length && $tocList.length && !$tocToggleLink.length ) {
                                hideToc = mw.cookie.get( 'hidetoc' ) === '1';
 
                                $tocToggleLink = $( '<a role="button" tabindex="0" class="togglelink"></a>' )
index 0c13daf..a1646a8 100644 (file)
 }
 
 // We use the `:not` selector to cancel out styling on IE 8 and below
-// We also disable this styling on JavaScript disabled devices. This fixes the issue with
-// Opera Mini where checking/unchecking doesn't apply styling but potentially leaves other
-// more capable browsers with unstyled checkboxes.
-.client-js .mw-ui-checkbox:not( #noop ) {
+// Note: This may be broken on older Opera Mini devices.
+.mw-ui-checkbox:not( #noop ) {
        display: table;
        // Position relatively so we can make use of absolute pseudo elements
        position: relative;
index bbfd528..4b8b1ee 100644 (file)
@@ -103,7 +103,6 @@ textarea.mw-ui-input {
 // <button class="mw-ui-button mw-ui-progressive">Submit</button>
 //
 // Styleguide 1.2.
-input[ type='number' ],
 .mw-ui-input-inline {
        display: inline-block;
        width: auto;
index e2bbd68..bac0674 100644 (file)
                 *  corresponding call to set().
                 */
                clear: function ( visibleTimeoutId ) {
-                       if ( activeTimeouts.hasOwnProperty( visibleTimeoutId ) ) {
+                       if ( Object.prototype.hasOwnProperty.call( activeTimeouts, visibleTimeoutId ) ) {
                                activeTimeouts[ visibleTimeoutId ]();
                        }
                }
index ff0630f..601d916 100644 (file)
@@ -63,7 +63,7 @@
 @padding-start-input-text-icon-label: 32 / @oo-ui-font-size-browser / @oo-ui-font-size-base;
 
 @border-base: 1px solid #a2a9b1;
-@border-color-base--disabled: @color-base--disabled;
+@border-color-base--disabled: #c8ccd1;
 @border-color-base--active: #72777d;
 @border-color-input--hover: @border-color-base--active;
 @border-color-erroneous: @color-erroneous;
diff --git a/resources/src/mediawiki.widgets/mw.widgets.CategoryCapsuleItemWidget.js b/resources/src/mediawiki.widgets/mw.widgets.CategoryCapsuleItemWidget.js
deleted file mode 100644 (file)
index 17da7d8..0000000
+++ /dev/null
@@ -1,207 +0,0 @@
-/*!
- * MediaWiki Widgets - CategoryCapsuleItemWidget class.
- *
- * @copyright 2011-2015 MediaWiki Widgets Team and others; see AUTHORS.txt
- * @license The MIT License (MIT); see LICENSE.txt
- */
-( function ( $, mw ) {
-
-       var hasOwn = Object.prototype.hasOwnProperty;
-
-       /**
-        * @class mw.widgets.PageExistenceCache
-        * @private
-        * @param {mw.Api} [api]
-        */
-       function PageExistenceCache( api ) {
-               this.api = api || new mw.Api();
-               this.processExistenceCheckQueueDebounced = OO.ui.debounce( this.processExistenceCheckQueue );
-               this.currentRequest = null;
-               this.existenceCache = {};
-               this.existenceCheckQueue = {};
-       }
-
-       /**
-        * Check for existence of pages in the queue.
-        *
-        * @private
-        */
-       PageExistenceCache.prototype.processExistenceCheckQueue = function () {
-               var queue, titles,
-                       cache = this;
-               if ( this.currentRequest ) {
-                       // Don't fire off a million requests at the same time
-                       this.currentRequest.always( function () {
-                               cache.currentRequest = null;
-                               cache.processExistenceCheckQueueDebounced();
-                       } );
-                       return;
-               }
-               queue = this.existenceCheckQueue;
-               this.existenceCheckQueue = {};
-               titles = Object.keys( queue ).filter( function ( title ) {
-                       if ( hasOwn.call( cache.existenceCache, title ) ) {
-                               queue[ title ].resolve( cache.existenceCache[ title ] );
-                       }
-                       return !hasOwn.call( cache.existenceCache, title );
-               } );
-               if ( !titles.length ) {
-                       return;
-               }
-               this.currentRequest = this.api.get( {
-                       formatversion: 2,
-                       action: 'query',
-                       prop: [ 'info' ],
-                       titles: titles
-               } ).done( function ( response ) {
-                       var
-                               normalized = {},
-                               pages = {};
-                       $.each( response.query.normalized || [], function ( index, data ) {
-                               normalized[ data.fromencoded ? decodeURIComponent( data.from ) : data.from ] = data.to;
-                       } );
-                       $.each( response.query.pages, function ( index, page ) {
-                               pages[ page.title ] = !page.missing;
-                       } );
-                       titles.forEach( function ( title ) {
-                               var normalizedTitle = title;
-                               while ( hasOwn.call( normalized, normalizedTitle ) ) {
-                                       normalizedTitle = normalized[ normalizedTitle ];
-                               }
-                               cache.existenceCache[ title ] = pages[ normalizedTitle ];
-                               queue[ title ].resolve( cache.existenceCache[ title ] );
-                       } );
-               } );
-       };
-
-       /**
-        * Register a request to check whether a page exists.
-        *
-        * @private
-        * @param {mw.Title} title
-        * @return {jQuery.Promise} Promise resolved with true if the page exists or false otherwise
-        */
-       PageExistenceCache.prototype.checkPageExistence = function ( title ) {
-               var key = title.getPrefixedText();
-               if ( !hasOwn.call( this.existenceCheckQueue, key ) ) {
-                       this.existenceCheckQueue[ key ] = $.Deferred();
-               }
-               this.processExistenceCheckQueueDebounced();
-               return this.existenceCheckQueue[ key ].promise();
-       };
-
-       /**
-        * @class mw.widgets.ForeignTitle
-        * @private
-        * @extends mw.Title
-        *
-        * @constructor
-        * @param {string} title
-        * @param {number} [namespace]
-        */
-       function ForeignTitle( title, namespace ) {
-               // We only need to handle categories here... but we don't know the target language.
-               // So assume that any namespace-like prefix is the 'Category' namespace...
-               title = title.replace( /^(.+?)_*:_*(.*)$/, 'Category:$2' ); // HACK
-               ForeignTitle.parent.call( this, title, namespace );
-       }
-       OO.inheritClass( ForeignTitle, mw.Title );
-       ForeignTitle.prototype.getNamespacePrefix = function () {
-               // We only need to handle categories here...
-               return 'Category:'; // HACK
-       };
-
-       /**
-        * Category selector capsule item widget. Extends OO.ui.CapsuleItemWidget with the ability to link
-        * to the given page, and to show its existence status (i.e., whether it is a redlink).
-        *
-        * @class mw.widgets.CategoryCapsuleItemWidget
-        * @uses mw.Api
-        * @extends OO.ui.CapsuleItemWidget
-        *
-        * @constructor
-        * @param {Object} config Configuration options
-        * @cfg {mw.Title} title Page title to use (required)
-        * @cfg {string} [apiUrl] API URL, if not the current wiki's API
-        */
-       mw.widgets.CategoryCapsuleItemWidget = function MWWCategoryCapsuleItemWidget( config ) {
-               var widget = this;
-               // Parent constructor
-               mw.widgets.CategoryCapsuleItemWidget.parent.call( this, $.extend( {
-                       data: config.title.getMainText(),
-                       label: config.title.getMainText()
-               }, config ) );
-
-               // Properties
-               this.title = config.title;
-               this.apiUrl = config.apiUrl || '';
-               this.$link = $( '<a>' )
-                       .text( this.label )
-                       .attr( 'target', '_blank' )
-                       .on( 'click', function ( e ) {
-                               // CapsuleMultiselectWidget really wants to prevent you from clicking the link, don't let it
-                               e.stopPropagation();
-                       } );
-
-               // Initialize
-               this.setMissing( false );
-               this.$label.replaceWith( this.$link );
-               this.setLabelElement( this.$link );
-
-               if ( !this.constructor.static.pageExistenceCaches[ this.apiUrl ] ) {
-                       this.constructor.static.pageExistenceCaches[ this.apiUrl ] =
-                               new PageExistenceCache( new mw.ForeignApi( this.apiUrl ) );
-               }
-               this.constructor.static.pageExistenceCaches[ this.apiUrl ]
-                       .checkPageExistence( new ForeignTitle( this.title.getPrefixedText() ) )
-                       .done( function ( exists ) {
-                               widget.setMissing( !exists );
-                       } );
-       };
-
-       /* Setup */
-
-       OO.inheritClass( mw.widgets.CategoryCapsuleItemWidget, OO.ui.CapsuleItemWidget );
-
-       /* Static Properties */
-
-       /**
-        * Map of API URLs to PageExistenceCache objects.
-        *
-        * @static
-        * @inheritable
-        * @property {Object}
-        */
-       mw.widgets.CategoryCapsuleItemWidget.static.pageExistenceCaches = {
-               '': new PageExistenceCache()
-       };
-
-       /* Methods */
-
-       /**
-        * Update label link href and CSS classes to reflect page existence status.
-        *
-        * @private
-        * @param {boolean} missing Whether the page is missing (does not exist)
-        */
-       mw.widgets.CategoryCapsuleItemWidget.prototype.setMissing = function ( missing ) {
-               var
-                       title = new ForeignTitle( this.title.getPrefixedText() ), // HACK
-                       prefix = this.apiUrl.replace( '/w/api.php', '' ); // HACK
-
-               this.missing = missing;
-
-               if ( !missing ) {
-                       this.$link
-                               .attr( 'href', prefix + title.getUrl() )
-                               .attr( 'title', title.getPrefixedText() )
-                               .removeClass( 'new' );
-               } else {
-                       this.$link
-                               .attr( 'href', prefix + title.getUrl( { action: 'edit', redlink: 1 } ) )
-                               .attr( 'title', mw.msg( 'red-link-title', title.getPrefixedText() ) )
-                               .addClass( 'new' );
-               }
-       };
-
-}( jQuery, mediaWiki ) );
index 354fcd9..c506379 100644 (file)
@@ -9,7 +9,7 @@
                NS_CATEGORY = mw.config.get( 'wgNamespaceIds' ).category;
 
        /**
-        * Category selector widget. Displays an OO.ui.CapsuleMultiselectWidget
+        * Category selector widget. Displays an OO.ui.MenuTagMultiselectWidget
         * and autocompletes with available categories.
         *
         *     mw.loader.using( 'mediawiki.widgets.CategoryMultiselectWidget', function () {
@@ -27,7 +27,7 @@
         *
         * @class mw.widgets.CategoryMultiselectWidget
         * @uses mw.Api
-        * @extends OO.ui.CapsuleMultiselectWidget
+        * @extends OO.ui.MenuTagMultiselectWidget
         * @mixins OO.ui.mixin.PendingElement
         *
         * @constructor
@@ -62,7 +62,7 @@
                OO.ui.mixin.PendingElement.call( this, $.extend( {}, config, { $pending: this.$handle } ) );
 
                // Event handler to call the autocomplete methods
-               this.$input.on( 'change input cut paste', OO.ui.debounce( this.updateMenuItems.bind( this ), 100 ) );
+               this.input.$input.on( 'change input cut paste', OO.ui.debounce( this.updateMenuItems.bind( this ), 100 ) );
 
                // Initialize
                this.api = config.api || new mw.Api();
@@ -71,7 +71,7 @@
 
        /* Setup */
 
-       OO.inheritClass( mw.widgets.CategoryMultiselectWidget, OO.ui.CapsuleMultiselectWidget );
+       OO.inheritClass( mw.widgets.CategoryMultiselectWidget, OO.ui.MenuTagMultiselectWidget );
        OO.mixinClass( mw.widgets.CategoryMultiselectWidget, OO.ui.mixin.PendingElement );
 
        /* Methods */
         */
        mw.widgets.CategoryMultiselectWidget.prototype.updateMenuItems = function () {
                this.getMenu().clearItems();
-               this.getNewMenuItems( this.$input.val() ).then( function ( items ) {
+               this.getNewMenuItems( this.input.$input.val() ).then( function ( items ) {
                        var existingItems, filteredItems,
                                menu = this.getMenu();
 
                        // Never show the menu if the input lost focus in the meantime
-                       if ( !this.$input.is( ':focus' ) ) {
+                       if ( !this.input.$input.is( ':focus' ) ) {
                                return;
                        }
 
        /**
         * @inheritdoc
         */
-       mw.widgets.CategoryMultiselectWidget.prototype.createItemWidget = function ( data ) {
+       mw.widgets.CategoryMultiselectWidget.prototype.createTagItemWidget = function ( data ) {
                var title = mw.Title.makeTitle( NS_CATEGORY, data );
-               if ( !title ) {
-                       return null;
-               }
-               return new mw.widgets.CategoryCapsuleItemWidget( {
+
+               return new mw.widgets.CategoryTagItemWidget( {
                        apiUrl: this.api.apiUrl || undefined,
                        title: title
                } );
         */
        mw.widgets.CategoryMultiselectWidget.prototype.findItemFromData = function ( data ) {
                // This is a bit of a hack... We have to canonicalize the data in the same way that
-               // #createItemWidget and CategoryCapsuleItemWidget will do, otherwise we won't find duplicates.
+               // #createItemWidget and CategoryTagItemWidget will do, otherwise we won't find duplicates.
                var title = mw.Title.makeTitle( NS_CATEGORY, data );
                if ( !title ) {
                        return null;
diff --git a/resources/src/mediawiki.widgets/mw.widgets.CategoryTagItemWidget.js b/resources/src/mediawiki.widgets/mw.widgets.CategoryTagItemWidget.js
new file mode 100644 (file)
index 0000000..f0b2d44
--- /dev/null
@@ -0,0 +1,209 @@
+/*!
+ * MediaWiki Widgets - CategoryTagItemWidget class.
+ *
+ * @copyright 2011-2015 MediaWiki Widgets Team and others; see AUTHORS.txt
+ * @license The MIT License (MIT); see LICENSE.txt
+ */
+( function ( $, mw ) {
+
+       var hasOwn = Object.prototype.hasOwnProperty;
+
+       /**
+        * @class mw.widgets.PageExistenceCache
+        * @private
+        * @param {mw.Api} [api]
+        */
+       function PageExistenceCache( api ) {
+               this.api = api || new mw.Api();
+               this.processExistenceCheckQueueDebounced = OO.ui.debounce( this.processExistenceCheckQueue );
+               this.currentRequest = null;
+               this.existenceCache = {};
+               this.existenceCheckQueue = {};
+       }
+
+       /**
+        * Check for existence of pages in the queue.
+        *
+        * @private
+        */
+       PageExistenceCache.prototype.processExistenceCheckQueue = function () {
+               var queue, titles,
+                       cache = this;
+               if ( this.currentRequest ) {
+                       // Don't fire off a million requests at the same time
+                       this.currentRequest.always( function () {
+                               cache.currentRequest = null;
+                               cache.processExistenceCheckQueueDebounced();
+                       } );
+                       return;
+               }
+               queue = this.existenceCheckQueue;
+               this.existenceCheckQueue = {};
+               titles = Object.keys( queue ).filter( function ( title ) {
+                       if ( hasOwn.call( cache.existenceCache, title ) ) {
+                               queue[ title ].resolve( cache.existenceCache[ title ] );
+                       }
+                       return !hasOwn.call( cache.existenceCache, title );
+               } );
+               if ( !titles.length ) {
+                       return;
+               }
+               this.currentRequest = this.api.get( {
+                       formatversion: 2,
+                       action: 'query',
+                       prop: [ 'info' ],
+                       titles: titles
+               } ).done( function ( response ) {
+                       var
+                               normalized = {},
+                               pages = {};
+                       $.each( response.query.normalized || [], function ( index, data ) {
+                               normalized[ data.fromencoded ? decodeURIComponent( data.from ) : data.from ] = data.to;
+                       } );
+                       $.each( response.query.pages, function ( index, page ) {
+                               pages[ page.title ] = !page.missing;
+                       } );
+                       titles.forEach( function ( title ) {
+                               var normalizedTitle = title;
+                               while ( hasOwn.call( normalized, normalizedTitle ) ) {
+                                       normalizedTitle = normalized[ normalizedTitle ];
+                               }
+                               cache.existenceCache[ title ] = pages[ normalizedTitle ];
+                               queue[ title ].resolve( cache.existenceCache[ title ] );
+                       } );
+               } );
+       };
+
+       /**
+        * Register a request to check whether a page exists.
+        *
+        * @private
+        * @param {mw.Title} title
+        * @return {jQuery.Promise} Promise resolved with true if the page exists or false otherwise
+        */
+       PageExistenceCache.prototype.checkPageExistence = function ( title ) {
+               var key = title.getPrefixedText();
+               if ( !hasOwn.call( this.existenceCheckQueue, key ) ) {
+                       this.existenceCheckQueue[ key ] = $.Deferred();
+               }
+               this.processExistenceCheckQueueDebounced();
+               return this.existenceCheckQueue[ key ].promise();
+       };
+
+       /**
+        * @class mw.widgets.ForeignTitle
+        * @private
+        * @extends mw.Title
+        *
+        * @constructor
+        * @param {string} title
+        * @param {number} [namespace]
+        */
+       function ForeignTitle( title, namespace ) {
+               // We only need to handle categories here... but we don't know the target language.
+               // So assume that any namespace-like prefix is the 'Category' namespace...
+               title = title.replace( /^(.+?)_*:_*(.*)$/, 'Category:$2' ); // HACK
+               ForeignTitle.parent.call( this, title, namespace );
+       }
+       OO.inheritClass( ForeignTitle, mw.Title );
+       ForeignTitle.prototype.getNamespacePrefix = function () {
+               // We only need to handle categories here...
+               return 'Category:'; // HACK
+       };
+
+       /**
+        * Category selector capsule item widget. Extends OO.ui.CapsuleItemWidget with the ability to link
+        * to the given page, and to show its existence status (i.e., whether it is a redlink).
+        *
+        * @class mw.widgets.CategoryTagItemWidget
+        * @uses mw.Api
+        * @extends OO.ui.TagItemWidget
+        *
+        * @constructor
+        * @param {Object} config Configuration options
+        * @cfg {mw.Title} title Page title to use (required)
+        * @cfg {string} [apiUrl] API URL, if not the current wiki's API
+        */
+       mw.widgets.CategoryTagItemWidget = function MWWCategoryTagItemWidget( config ) {
+               var widget = this;
+               // Parent constructor
+               mw.widgets.CategoryTagItemWidget.parent.call( this, $.extend( {
+                       data: config.title.getMainText(),
+                       label: config.title.getMainText()
+               }, config ) );
+
+               // Properties
+               this.title = config.title;
+               this.apiUrl = config.apiUrl || '';
+               this.$link = $( '<a>' )
+                       .text( this.label )
+                       .attr( 'target', '_blank' )
+                       .on( 'click', function ( e ) {
+                               // TagMultiselectWidget really wants to prevent you from clicking the link, don't let it
+                               e.stopPropagation();
+                       } );
+
+               // Initialize
+               this.setMissing( false );
+               this.$label.replaceWith( this.$link );
+               this.setLabelElement( this.$link );
+
+               if ( !this.constructor.static.pageExistenceCaches[ this.apiUrl ] ) {
+                       this.constructor.static.pageExistenceCaches[ this.apiUrl ] =
+                               new PageExistenceCache( new mw.ForeignApi( this.apiUrl ) );
+               }
+               this.constructor.static.pageExistenceCaches[ this.apiUrl ]
+                       .checkPageExistence( new ForeignTitle( this.title.getPrefixedText() ) )
+                       .done( function ( exists ) {
+                               widget.setMissing( !exists );
+                       } );
+       };
+
+       /* Setup */
+
+       OO.inheritClass( mw.widgets.CategoryTagItemWidget, OO.ui.TagItemWidget );
+
+       /* Static Properties */
+
+       /**
+        * Map of API URLs to PageExistenceCache objects.
+        *
+        * @static
+        * @inheritable
+        * @property {Object}
+        */
+       mw.widgets.CategoryTagItemWidget.static.pageExistenceCaches = {
+               '': new PageExistenceCache()
+       };
+
+       /* Methods */
+
+       /**
+        * Update label link href and CSS classes to reflect page existence status.
+        *
+        * @private
+        * @param {boolean} missing Whether the page is missing (does not exist)
+        */
+       mw.widgets.CategoryTagItemWidget.prototype.setMissing = function ( missing ) {
+               var
+                       title = new ForeignTitle( this.title.getPrefixedText() ), // HACK
+                       prefix = this.apiUrl.replace( '/w/api.php', '' ); // HACK
+
+               this.missing = missing;
+
+               if ( !missing ) {
+                       this.$link
+                               .attr( 'href', prefix + title.getUrl() )
+                               .attr( 'title', title.getPrefixedText() )
+                               .removeClass( 'new' );
+               } else {
+                       this.$link
+                               .attr( 'href', prefix + title.getUrl( { action: 'edit', redlink: 1 } ) )
+                               .attr( 'title', mw.msg( 'red-link-title', title.getPrefixedText() ) )
+                               .addClass( 'new' );
+               }
+       };
+
+       // For backwards compatibility. See T183299.
+       mw.widgets.CategoryCapsuleItemWidget = mw.widgets.CategoryTagItemWidget;
+}( jQuery, mediaWiki ) );
index 2bbeabf..6ee9595 100644 (file)
@@ -26,8 +26,8 @@
         * @cfg {boolean} [showMissing=true] Show missing pages
         * @cfg {boolean} [addQueryInput=true] Add exact user's input query to results
         * @cfg {boolean} [excludeCurrentPage] Exclude the current page from suggestions
-        * @cfg {boolean} [validateTitle=true] Whether the input must be a valid title (if set to true,
-        *  the widget will marks itself red for invalid inputs, including an empty query).
+        * @cfg {boolean} [validateTitle=true] Whether the input must be a valid title
+        * @cfg {boolean} [required=false] Whether the input must not be empty
         * @cfg {Object} [cache] Result cache which implements a 'set' method, taking keyed values as an argument
         * @cfg {mw.Api} [api] API object to use, creates a default mw.Api instance if not specified
         */
                var api = this.getApi(),
                        cache = this.constructor.static.interwikiPrefixesPromiseCache,
                        key = api.defaults.ajax.url;
-               if ( !cache.hasOwnProperty( key ) ) {
+               if ( !Object.prototype.hasOwnProperty.call( cache, key ) ) {
                        cache[ key ] = api.get( {
                                action: 'query',
                                meta: 'siteinfo',
         * @return {boolean} The query is valid
         */
        mw.widgets.TitleWidget.prototype.isQueryValid = function () {
-               return this.validateTitle ? !!this.getMWTitle() : true;
+               if ( !this.validateTitle ) {
+                       return true;
+               }
+               if ( !this.required && this.getQueryValue() === '' ) {
+                       return true;
+               }
+               return !!this.getMWTitle();
        };
 
 }( jQuery, mediaWiki ) );
diff --git a/resources/src/mediawiki/mediawiki.errorLogger.js b/resources/src/mediawiki/mediawiki.errorLogger.js
deleted file mode 100644 (file)
index e86aff6..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/**
- * Try to catch errors in modules which don't do their own error handling.
- *
- * @class mw.errorLogger
- * @singleton
- */
-( function ( mw ) {
-       'use strict';
-
-       mw.errorLogger = {
-               /**
-                * Fired via mw.track when an error is not handled by local code and is caught by the
-                * window.onerror handler.
-                *
-                * @event global_error
-                * @param {string} errorMessage Error errorMessage.
-                * @param {string} url URL where error was raised.
-                * @param {number} lineNumber Line number where error was raised.
-                * @param {number} [columnNumber] Line number where error was raised. Not all browsers
-                *   support this.
-                * @param {Error|Mixed} [errorObject] The error object. Typically an instance of Error, but anything
-                *   (even a primitive value) passed to a throw clause will end up here.
-                */
-
-               /**
-                * Install a window.onerror handler that will report via mw.track, while preserving
-                * any previous handler.
-                *
-                * @param {Object} window
-                */
-               installGlobalHandler: function ( window ) {
-                       // We will preserve the return value of the previous handler. window.onerror works the
-                       // opposite way than normal event handlers (returning true will prevent the default
-                       // action, returning false will let the browser handle the error normally, by e.g.
-                       // logging to the console), so our fallback old handler needs to return false.
-                       var oldHandler = window.onerror || function () { return false; };
-
-                       /**
-                        * Dumb window.onerror handler which forwards the errors via mw.track.
-                        *
-                        * @param {string} errorMessage
-                        * @param {string} url
-                        * @param {number} lineNumber
-                        * @param {number} [columnNumber]
-                        * @param {Error|Mixed} [errorObject]
-                        * @return {boolean} True to prevent the default action
-                        * @fires global_error
-                        */
-                       window.onerror = function ( errorMessage, url, lineNumber, columnNumber, errorObject ) {
-                               mw.track( 'global.error', { errorMessage: errorMessage, url: url,
-                                       lineNumber: lineNumber, columnNumber: columnNumber, errorObject: errorObject } );
-                               return oldHandler.apply( this, arguments );
-                       };
-               }
-       };
-
-       mw.errorLogger.installGlobalHandler( window );
-}( mediaWiki ) );
diff --git a/resources/src/mediawiki/mediawiki.js b/resources/src/mediawiki/mediawiki.js
deleted file mode 100644 (file)
index 702c18d..0000000
+++ /dev/null
@@ -1,2811 +0,0 @@
-/**
- * Base library for MediaWiki.
- *
- * Exposed globally as `mediaWiki` with `mw` as shortcut.
- *
- * @class mw
- * @alternateClassName mediaWiki
- * @singleton
- */
-
-/* global mwNow */
-/* eslint-disable no-use-before-define */
-
-( function ( $ ) {
-       'use strict';
-
-       var mw, StringSet, log,
-               hasOwn = Object.prototype.hasOwnProperty,
-               slice = Array.prototype.slice,
-               trackCallbacks = $.Callbacks( 'memory' ),
-               trackHandlers = [],
-               trackQueue = [];
-
-       /**
-        * FNV132 hash function
-        *
-        * This function implements the 32-bit version of FNV-1.
-        * It is equivalent to hash( 'fnv132', ... ) in PHP, except
-        * its output is base 36 rather than hex.
-        * See <https://en.wikipedia.org/wiki/FNV_hash_function>
-        *
-        * @private
-        * @param {string} str String to hash
-        * @return {string} hash as an seven-character base 36 string
-        */
-       function fnv132( str ) {
-               /* eslint-disable no-bitwise */
-               var hash = 0x811C9DC5,
-                       i;
-
-               for ( i = 0; i < str.length; i++ ) {
-                       hash += ( hash << 1 ) + ( hash << 4 ) + ( hash << 7 ) + ( hash << 8 ) + ( hash << 24 );
-                       hash ^= str.charCodeAt( i );
-               }
-
-               hash = ( hash >>> 0 ).toString( 36 );
-               while ( hash.length < 7 ) {
-                       hash = '0' + hash;
-               }
-
-               return hash;
-               /* eslint-enable no-bitwise */
-       }
-
-       function defineFallbacks() {
-               // <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set>
-               StringSet = window.Set || ( function () {
-                       /**
-                        * @private
-                        * @class
-                        */
-                       function StringSet() {
-                               this.set = {};
-                       }
-                       StringSet.prototype.add = function ( value ) {
-                               this.set[ value ] = true;
-                       };
-                       StringSet.prototype.has = function ( value ) {
-                               return hasOwn.call( this.set, value );
-                       };
-                       return StringSet;
-               }() );
-       }
-
-       /**
-        * Create an object that can be read from or written to via methods that allow
-        * interaction both with single and multiple properties at once.
-        *
-        * @private
-        * @class mw.Map
-        *
-        * @constructor
-        * @param {boolean} [global=false] Whether to synchronise =values to the global
-        *  window object (for backwards-compatibility with mw.config; T72470). Values are
-        *  copied in one direction only. Changes to globals do not reflect in the map.
-        */
-       function Map( global ) {
-               this.values = {};
-               if ( global === true ) {
-                       // Override #set to also set the global variable
-                       this.set = function ( selection, value ) {
-                               var s;
-                               if ( arguments.length > 1 ) {
-                                       if ( typeof selection !== 'string' ) {
-                                               return false;
-                                       }
-                                       setGlobalMapValue( this, selection, value );
-                                       return true;
-                               }
-                               if ( typeof selection === 'object' ) {
-                                       for ( s in selection ) {
-                                               setGlobalMapValue( this, s, selection[ s ] );
-                                       }
-                                       return true;
-                               }
-                               return false;
-                       };
-               }
-       }
-
-       /**
-        * Alias property to the global object.
-        *
-        * @private
-        * @static
-        * @param {mw.Map} map
-        * @param {string} key
-        * @param {Mixed} value
-        */
-       function setGlobalMapValue( map, key, value ) {
-               map.values[ key ] = value;
-               log.deprecate(
-                       window,
-                       key,
-                       value,
-                       // Deprecation notice for mw.config globals (T58550, T72470)
-                       map === mw.config && 'Use mw.config instead.'
-               );
-       }
-
-       Map.prototype = {
-               constructor: Map,
-
-               /**
-                * Get the value of one or more keys.
-                *
-                * If called with no arguments, all values are returned.
-                *
-                * @param {string|Array} [selection] Key or array of keys to retrieve values for.
-                * @param {Mixed} [fallback=null] Value for keys that don't exist.
-                * @return {Mixed|Object|null} If selection was a string, returns the value,
-                *  If selection was an array, returns an object of key/values.
-                *  If no selection is passed, a new object with all key/values is returned.
-                */
-               get: function ( selection, fallback ) {
-                       var results, i;
-                       fallback = arguments.length > 1 ? fallback : null;
-
-                       if ( Array.isArray( selection ) ) {
-                               results = {};
-                               for ( i = 0; i < selection.length; i++ ) {
-                                       if ( typeof selection[ i ] === 'string' ) {
-                                               results[ selection[ i ] ] = hasOwn.call( this.values, selection[ i ] ) ?
-                                                       this.values[ selection[ i ] ] :
-                                                       fallback;
-                                       }
-                               }
-                               return results;
-                       }
-
-                       if ( typeof selection === 'string' ) {
-                               return hasOwn.call( this.values, selection ) ?
-                                       this.values[ selection ] :
-                                       fallback;
-                       }
-
-                       if ( selection === undefined ) {
-                               results = {};
-                               for ( i in this.values ) {
-                                       results[ i ] = this.values[ i ];
-                               }
-                               return results;
-                       }
-
-                       // Invalid selection key
-                       return fallback;
-               },
-
-               /**
-                * Set one or more key/value pairs.
-                *
-                * @param {string|Object} selection Key to set value for, or object mapping keys to values
-                * @param {Mixed} [value] Value to set (optional, only in use when key is a string)
-                * @return {boolean} True on success, false on failure
-                */
-               set: function ( selection, value ) {
-                       var s;
-                       // Use `arguments.length` because `undefined` is also a valid value.
-                       if ( arguments.length > 1 ) {
-                               if ( typeof selection !== 'string' ) {
-                                       return false;
-                               }
-                               this.values[ selection ] = value;
-                               return true;
-                       }
-                       if ( typeof selection === 'object' ) {
-                               for ( s in selection ) {
-                                       this.values[ s ] = selection[ s ];
-                               }
-                               return true;
-                       }
-                       return false;
-               },
-
-               /**
-                * Check if one or more keys exist.
-                *
-                * @param {Mixed} selection Key or array of keys to check
-                * @return {boolean} True if the key(s) exist
-                */
-               exists: function ( selection ) {
-                       var i;
-                       if ( Array.isArray( selection ) ) {
-                               for ( i = 0; i < selection.length; i++ ) {
-                                       if ( typeof selection[ i ] !== 'string' || !hasOwn.call( this.values, selection[ i ] ) ) {
-                                               return false;
-                                       }
-                               }
-                               return true;
-                       }
-                       return typeof selection === 'string' && hasOwn.call( this.values, selection );
-               }
-       };
-
-       /**
-        * Object constructor for messages.
-        *
-        * Similar to the Message class in MediaWiki PHP.
-        *
-        * Format defaults to 'text'.
-        *
-        *     @example
-        *
-        *     var obj, str;
-        *     mw.messages.set( {
-        *         'hello': 'Hello world',
-        *         'hello-user': 'Hello, $1!',
-        *         'welcome-user': 'Welcome back to $2, $1! Last visit by $1: $3'
-        *     } );
-        *
-        *     obj = new mw.Message( mw.messages, 'hello' );
-        *     mw.log( obj.text() );
-        *     // Hello world
-        *
-        *     obj = new mw.Message( mw.messages, 'hello-user', [ 'John Doe' ] );
-        *     mw.log( obj.text() );
-        *     // Hello, John Doe!
-        *
-        *     obj = new mw.Message( mw.messages, 'welcome-user', [ 'John Doe', 'Wikipedia', '2 hours ago' ] );
-        *     mw.log( obj.text() );
-        *     // Welcome back to Wikipedia, John Doe! Last visit by John Doe: 2 hours ago
-        *
-        *     // Using mw.message shortcut
-        *     obj = mw.message( 'hello-user', 'John Doe' );
-        *     mw.log( obj.text() );
-        *     // Hello, John Doe!
-        *
-        *     // Using mw.msg shortcut
-        *     str = mw.msg( 'hello-user', 'John Doe' );
-        *     mw.log( str );
-        *     // Hello, John Doe!
-        *
-        *     // Different formats
-        *     obj = new mw.Message( mw.messages, 'hello-user', [ 'John "Wiki" <3 Doe' ] );
-        *
-        *     obj.format = 'text';
-        *     str = obj.toString();
-        *     // Same as:
-        *     str = obj.text();
-        *
-        *     mw.log( str );
-        *     // Hello, John "Wiki" <3 Doe!
-        *
-        *     mw.log( obj.escaped() );
-        *     // Hello, John &quot;Wiki&quot; &lt;3 Doe!
-        *
-        * @class mw.Message
-        *
-        * @constructor
-        * @param {mw.Map} map Message store
-        * @param {string} key
-        * @param {Array} [parameters]
-        */
-       function Message( map, key, parameters ) {
-               this.format = 'text';
-               this.map = map;
-               this.key = key;
-               this.parameters = parameters === undefined ? [] : slice.call( parameters );
-               return this;
-       }
-
-       Message.prototype = {
-               /**
-                * Get parsed contents of the message.
-                *
-                * The default parser does simple $N replacements and nothing else.
-                * This may be overridden to provide a more complex message parser.
-                * The primary override is in the mediawiki.jqueryMsg module.
-                *
-                * This function will not be called for nonexistent messages.
-                *
-                * @return {string} Parsed message
-                */
-               parser: function () {
-                       return mw.format.apply( null, [ this.map.get( this.key ) ].concat( this.parameters ) );
-               },
-
-               // eslint-disable-next-line valid-jsdoc
-               /**
-                * Add (does not replace) parameters for `$N` placeholder values.
-                *
-                * @param {Array} parameters
-                * @chainable
-                */
-               params: function ( parameters ) {
-                       var i;
-                       for ( i = 0; i < parameters.length; i++ ) {
-                               this.parameters.push( parameters[ i ] );
-                       }
-                       return this;
-               },
-
-               /**
-                * Convert message object to its string form based on current format.
-                *
-                * @return {string} Message as a string in the current form, or `<key>` if key
-                *  does not exist.
-                */
-               toString: function () {
-                       var text;
-
-                       if ( !this.exists() ) {
-                               // Use ⧼key⧽ as text if key does not exist
-                               // Err on the side of safety, ensure that the output
-                               // is always html safe in the event the message key is
-                               // missing, since in that case its highly likely the
-                               // message key is user-controlled.
-                               // '⧼' is used instead of '<' to side-step any
-                               // double-escaping issues.
-                               // (Keep synchronised with Message::toString() in PHP.)
-                               return '⧼' + mw.html.escape( this.key ) + '⧽';
-                       }
-
-                       if ( this.format === 'plain' || this.format === 'text' || this.format === 'parse' ) {
-                               text = this.parser();
-                       }
-
-                       if ( this.format === 'escaped' ) {
-                               text = this.parser();
-                               text = mw.html.escape( text );
-                       }
-
-                       return text;
-               },
-
-               /**
-                * Change format to 'parse' and convert message to string
-                *
-                * If jqueryMsg is loaded, this parses the message text from wikitext
-                * (where supported) to HTML
-                *
-                * Otherwise, it is equivalent to plain.
-                *
-                * @return {string} String form of parsed message
-                */
-               parse: function () {
-                       this.format = 'parse';
-                       return this.toString();
-               },
-
-               /**
-                * Change format to 'plain' and convert message to string
-                *
-                * This substitutes parameters, but otherwise does not change the
-                * message text.
-                *
-                * @return {string} String form of plain message
-                */
-               plain: function () {
-                       this.format = 'plain';
-                       return this.toString();
-               },
-
-               /**
-                * Change format to 'text' and convert message to string
-                *
-                * If jqueryMsg is loaded, {{-transformation is done where supported
-                * (such as {{plural:}}, {{gender:}}, {{int:}}).
-                *
-                * Otherwise, it is equivalent to plain
-                *
-                * @return {string} String form of text message
-                */
-               text: function () {
-                       this.format = 'text';
-                       return this.toString();
-               },
-
-               /**
-                * Change the format to 'escaped' and convert message to string
-                *
-                * This is equivalent to using the 'text' format (see #text), then
-                * HTML-escaping the output.
-                *
-                * @return {string} String form of html escaped message
-                */
-               escaped: function () {
-                       this.format = 'escaped';
-                       return this.toString();
-               },
-
-               /**
-                * Check if a message exists
-                *
-                * @see mw.Map#exists
-                * @return {boolean}
-                */
-               exists: function () {
-                       return this.map.exists( this.key );
-               }
-       };
-
-       defineFallbacks();
-
-       /* eslint-disable no-console */
-       log = ( function () {
-               /**
-                * Write a verbose message to the browser's console in debug mode.
-                *
-                * This method is mainly intended for verbose logging. It is a no-op in production mode.
-                * In ResourceLoader debug mode, it will use the browser's console if available, with
-                * fallback to creating a console interface in the DOM and logging messages there.
-                *
-                * See {@link mw.log} for other logging methods.
-                *
-                * @member mw
-                * @param {...string} msg Messages to output to console.
-                */
-               var log = function () {},
-                       console = window.console;
-
-               // Note: Keep list of methods in sync with restoration in mediawiki.log.js
-               // when adding or removing mw.log methods below!
-
-               /**
-                * Collection of methods to help log messages to the console.
-                *
-                * @class mw.log
-                * @singleton
-                */
-
-               /**
-                * Write a message to the browser console's warning channel.
-                *
-                * This method is a no-op in browsers that don't implement the Console API.
-                *
-                * @param {...string} msg Messages to output to console
-                */
-               log.warn = console && console.warn && Function.prototype.bind ?
-                       Function.prototype.bind.call( console.warn, console ) :
-                       $.noop;
-
-               /**
-                * Write a message to the browser console's error channel.
-                *
-                * Most browsers also print a stacktrace when calling this method if the
-                * argument is an Error object.
-                *
-                * This method is a no-op in browsers that don't implement the Console API.
-                *
-                * @since 1.26
-                * @param {Error|...string} msg Messages to output to console
-                */
-               log.error = console && console.error && Function.prototype.bind ?
-                       Function.prototype.bind.call( console.error, console ) :
-                       $.noop;
-
-               /**
-                * Create a property on a host object that, when accessed, will produce
-                * a deprecation warning in the console.
-                *
-                * @param {Object} obj Host object of deprecated property
-                * @param {string} key Name of property to create in `obj`
-                * @param {Mixed} val The value this property should return when accessed
-                * @param {string} [msg] Optional text to include in the deprecation message
-                * @param {string} [logName=key] Optional custom name for the feature.
-                *  This is used instead of `key` in the message and `mw.deprecate` tracking.
-                */
-               log.deprecate = !Object.defineProperty ? function ( obj, key, val ) {
-                       obj[ key ] = val;
-               } : function ( obj, key, val, msg, logName ) {
-                       var logged = new StringSet();
-                       logName = logName || key;
-                       msg = 'Use of "' + logName + '" is deprecated.' + ( msg ? ( ' ' + msg ) : '' );
-                       function uniqueTrace() {
-                               var trace = new Error().stack;
-                               if ( logged.has( trace ) ) {
-                                       return false;
-                               }
-                               logged.add( trace );
-                               return true;
-                       }
-                       // Support: Safari 5.0
-                       // Throws "not supported on DOM Objects" for Node or Element objects (incl. document)
-                       // Safari 4.0 doesn't have this method, and it was fixed in Safari 5.1.
-                       try {
-                               Object.defineProperty( obj, key, {
-                                       configurable: true,
-                                       enumerable: true,
-                                       get: function () {
-                                               if ( uniqueTrace() ) {
-                                                       mw.track( 'mw.deprecate', logName );
-                                                       mw.log.warn( msg );
-                                               }
-                                               return val;
-                                       },
-                                       set: function ( newVal ) {
-                                               if ( uniqueTrace() ) {
-                                                       mw.track( 'mw.deprecate', logName );
-                                                       mw.log.warn( msg );
-                                               }
-                                               val = newVal;
-                                       }
-                               } );
-                       } catch ( err ) {
-                               obj[ key ] = val;
-                       }
-               };
-
-               return log;
-       }() );
-       /* eslint-enable no-console */
-
-       /**
-        * @class mw
-        */
-       mw = {
-               redefineFallbacksForTest: function () {
-                       if ( !window.QUnit ) {
-                               throw new Error( 'Reset not allowed outside unit tests' );
-                       }
-                       defineFallbacks();
-               },
-
-               /**
-                * Get the current time, measured in milliseconds since January 1, 1970 (UTC).
-                *
-                * On browsers that implement the Navigation Timing API, this function will produce floating-point
-                * values with microsecond precision that are guaranteed to be monotonic. On all other browsers,
-                * it will fall back to using `Date`.
-                *
-                * @return {number} Current time
-                */
-               now: mwNow,
-               // mwNow is defined in startup.js
-
-               /**
-                * Format a string. Replace $1, $2 ... $N with positional arguments.
-                *
-                * Used by Message#parser().
-                *
-                * @since 1.25
-                * @param {string} formatString Format string
-                * @param {...Mixed} parameters Values for $N replacements
-                * @return {string} Formatted string
-                */
-               format: function ( formatString ) {
-                       var parameters = slice.call( arguments, 1 );
-                       return formatString.replace( /\$(\d+)/g, function ( str, match ) {
-                               var index = parseInt( match, 10 ) - 1;
-                               return parameters[ index ] !== undefined ? parameters[ index ] : '$' + match;
-                       } );
-               },
-
-               /**
-                * Track an analytic event.
-                *
-                * This method provides a generic means for MediaWiki JavaScript code to capture state
-                * information for analysis. Each logged event specifies a string topic name that describes
-                * the kind of event that it is. Topic names consist of dot-separated path components,
-                * arranged from most general to most specific. Each path component should have a clear and
-                * well-defined purpose.
-                *
-                * Data handlers are registered via `mw.trackSubscribe`, and receive the full set of
-                * events that match their subcription, including those that fired before the handler was
-                * bound.
-                *
-                * @param {string} topic Topic name
-                * @param {Object} [data] Data describing the event, encoded as an object
-                */
-               track: function ( topic, data ) {
-                       trackQueue.push( { topic: topic, timeStamp: mw.now(), data: data } );
-                       trackCallbacks.fire( trackQueue );
-               },
-
-               /**
-                * Register a handler for subset of analytic events, specified by topic.
-                *
-                * Handlers will be called once for each tracked event, including any events that fired before the
-                * handler was registered; 'this' is set to a plain object with a 'timeStamp' property indicating
-                * the exact time at which the event fired, a string 'topic' property naming the event, and a
-                * 'data' property which is an object of event-specific data. The event topic and event data are
-                * also passed to the callback as the first and second arguments, respectively.
-                *
-                * @param {string} topic Handle events whose name starts with this string prefix
-                * @param {Function} callback Handler to call for each matching tracked event
-                * @param {string} callback.topic
-                * @param {Object} [callback.data]
-                */
-               trackSubscribe: function ( topic, callback ) {
-                       var seen = 0;
-                       function handler( trackQueue ) {
-                               var event;
-                               for ( ; seen < trackQueue.length; seen++ ) {
-                                       event = trackQueue[ seen ];
-                                       if ( event.topic.indexOf( topic ) === 0 ) {
-                                               callback.call( event, event.topic, event.data );
-                                       }
-                               }
-                       }
-
-                       trackHandlers.push( [ handler, callback ] );
-
-                       trackCallbacks.add( handler );
-               },
-
-               /**
-                * Stop handling events for a particular handler
-                *
-                * @param {Function} callback
-                */
-               trackUnsubscribe: function ( callback ) {
-                       trackHandlers = trackHandlers.filter( function ( fns ) {
-                               if ( fns[ 1 ] === callback ) {
-                                       trackCallbacks.remove( fns[ 0 ] );
-                                       // Ensure the tuple is removed to avoid holding on to closures
-                                       return false;
-                               }
-                               return true;
-                       } );
-               },
-
-               // Expose Map constructor
-               Map: Map,
-
-               // Expose Message constructor
-               Message: Message,
-
-               /**
-                * Map of configuration values.
-                *
-                * Check out [the complete list of configuration values](https://www.mediawiki.org/wiki/Manual:Interface/JavaScript#mw.config)
-                * on mediawiki.org.
-                *
-                * If `$wgLegacyJavaScriptGlobals` is true, this Map will add its values to the
-                * global `window` object.
-                *
-                * @property {mw.Map} config
-                */
-               // Dummy placeholder later assigned in ResourceLoaderStartUpModule
-               config: null,
-
-               /**
-                * Empty object for third-party libraries, for cases where you don't
-                * want to add a new global, or the global is bad and needs containment
-                * or wrapping.
-                *
-                * @property
-                */
-               libs: {},
-
-               /**
-                * Access container for deprecated functionality that can be moved from
-                * from their legacy location and attached to this object (e.g. a global
-                * function that is deprecated and as stop-gap can be exposed through here).
-                *
-                * This was reserved for future use but never ended up being used.
-                *
-                * @deprecated since 1.22 Let deprecated identifiers keep their original name
-                *  and use mw.log#deprecate to create an access container for tracking.
-                * @property
-                */
-               legacy: {},
-
-               /**
-                * Store for messages.
-                *
-                * @property {mw.Map}
-                */
-               messages: new Map(),
-
-               /**
-                * Store for templates associated with a module.
-                *
-                * @property {mw.Map}
-                */
-               templates: new Map(),
-
-               /**
-                * Get a message object.
-                *
-                * Shortcut for `new mw.Message( mw.messages, key, parameters )`.
-                *
-                * @see mw.Message
-                * @param {string} key Key of message to get
-                * @param {...Mixed} parameters Values for $N replacements
-                * @return {mw.Message}
-                */
-               message: function ( key ) {
-                       var parameters = slice.call( arguments, 1 );
-                       return new Message( mw.messages, key, parameters );
-               },
-
-               /**
-                * Get a message string using the (default) 'text' format.
-                *
-                * Shortcut for `mw.message( key, parameters... ).text()`.
-                *
-                * @see mw.Message
-                * @param {string} key Key of message to get
-                * @param {...Mixed} parameters Values for $N replacements
-                * @return {string}
-                */
-               msg: function () {
-                       return mw.message.apply( mw.message, arguments ).toString();
-               },
-
-               // Expose mw.log
-               log: log,
-
-               /**
-                * Client for ResourceLoader server end point.
-                *
-                * This client is in charge of maintaining the module registry and state
-                * machine, initiating network (batch) requests for loading modules, as
-                * well as dependency resolution and execution of source code.
-                *
-                * For more information, refer to
-                * <https://www.mediawiki.org/wiki/ResourceLoader/Features>
-                *
-                * @class mw.loader
-                * @singleton
-                */
-               loader: ( function () {
-
-                       /**
-                        * Fired via mw.track on various resource loading errors.
-                        *
-                        * @event resourceloader_exception
-                        * @param {Error|Mixed} e The error that was thrown. Almost always an Error
-                        *   object, but in theory module code could manually throw something else, and that
-                        *   might also end up here.
-                        * @param {string} [module] Name of the module which caused the error. Omitted if the
-                        *   error is not module-related or the module cannot be easily identified due to
-                        *   batched handling.
-                        * @param {string} source Source of the error. Possible values:
-                        *
-                        *   - style: stylesheet error (only affects old IE where a special style loading method
-                        *     is used)
-                        *   - load-callback: exception thrown by user callback
-                        *   - module-execute: exception thrown by module code
-                        *   - resolve: failed to sort dependencies for a module in mw.loader.load
-                        *   - store-eval: could not evaluate module code cached in localStorage
-                        *   - store-localstorage-init: localStorage or JSON parse error in mw.loader.store.init
-                        *   - store-localstorage-json: JSON conversion error in mw.loader.store.set
-                        *   - store-localstorage-update: localStorage or JSON conversion error in mw.loader.store.update
-                        */
-
-                       /**
-                        * Fired via mw.track on resource loading error conditions.
-                        *
-                        * @event resourceloader_assert
-                        * @param {string} source Source of the error. Possible values:
-                        *
-                        *   - bug-T59567: failed to cache script due to an Opera function -> string conversion
-                        *     bug; see <https://phabricator.wikimedia.org/T59567> for details
-                        */
-
-                       /**
-                        * Mapping of registered modules.
-                        *
-                        * See #implement and #execute for exact details on support for script, style and messages.
-                        *
-                        * Format:
-                        *
-                        *     {
-                        *         'moduleName': {
-                        *             // From mw.loader.register()
-                        *             'version': '########' (hash)
-                        *             'dependencies': ['required.foo', 'bar.also', ...]
-                        *             'group': 'somegroup', (or) null
-                        *             'source': 'local', (or) 'anotherwiki'
-                        *             'skip': 'return !!window.Example', (or) null
-                        *             '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', ... }
-                        *         }
-                        *     }
-                        *
-                        * State machine:
-                        *
-                        * - `registered`:
-                        *    The module is known to the system but not yet required.
-                        *    Meta data is registered via mw.loader#register. Calls to that method are
-                        *    generated server-side by the startup module.
-                        * - `loading`:
-                        *    The module was required through mw.loader (either directly or as dependency of
-                        *    another module). The client will fetch module contents from the server.
-                        *    The contents are then stashed in the registry via mw.loader#implement.
-                        * - `loaded`:
-                        *    The module has been loaded from the server and stashed via mw.loader#implement.
-                        *    If the module has no more dependencies in-flight, the module will be executed
-                        *    immediately. Otherwise execution is deferred, controlled via #handlePending.
-                        * - `executing`:
-                        *    The module is being executed.
-                        * - `ready`:
-                        *    The module has been successfully executed.
-                        * - `error`:
-                        *    The module (or one of its dependencies) produced an error during execution.
-                        * - `missing`:
-                        *    The module was registered client-side and requested, but the server denied knowledge
-                        *    of the module's existence.
-                        *
-                        * @property
-                        * @private
-                        */
-                       var registry = {},
-                               // Mapping of sources, keyed by source-id, values are strings.
-                               //
-                               // Format:
-                               //
-                               //     {
-                               //         'sourceId': 'http://example.org/w/load.php'
-                               //     }
-                               //
-                               sources = {},
-
-                               // For queueModuleScript()
-                               handlingPendingRequests = false,
-                               pendingRequests = [],
-
-                               // List of modules to be loaded
-                               queue = [],
-
-                               /**
-                                * List of callback jobs waiting for modules to be ready.
-                                *
-                                * Jobs are created by #enqueue() and run by #handlePending().
-                                *
-                                * Typically when a job is created for a module, the job's dependencies contain
-                                * both the required module and all its recursive dependencies.
-                                *
-                                * Format:
-                                *
-                                *     {
-                                *         'dependencies': [ module names ],
-                                *         'ready': Function callback
-                                *         'error': Function callback
-                                *     }
-                                *
-                                * @property {Object[]} jobs
-                                * @private
-                                */
-                               jobs = [],
-
-                               /**
-                                * For #addEmbeddedCSS() and #addLink()
-                                *
-                                * @private
-                                * @property {HTMLElement|null} marker
-                                */
-                               marker = document.querySelector( 'meta[name="ResourceLoaderDynamicStyles"]' ),
-
-                               // For addEmbeddedCSS()
-                               cssBuffer = '',
-                               cssBufferTimer = null,
-                               cssCallbacks = [],
-                               rAF = window.requestAnimationFrame || setTimeout;
-
-                       /**
-                        * Create a new style element and add it to the DOM.
-                        *
-                        * @private
-                        * @param {string} text CSS text
-                        * @param {Node|null} [nextNode] The element where the style tag
-                        *  should be inserted before
-                        * @return {HTMLElement} Reference to the created style element
-                        */
-                       function newStyleTag( text, nextNode ) {
-                               var el = document.createElement( 'style' );
-                               el.appendChild( document.createTextNode( text ) );
-                               if ( nextNode && nextNode.parentNode ) {
-                                       nextNode.parentNode.insertBefore( el, nextNode );
-                               } else {
-                                       document.head.appendChild( el );
-                               }
-                               return el;
-                       }
-
-                       /**
-                        * Add a bit of CSS text to the current browser page.
-                        *
-                        * The CSS will be appended to an existing ResourceLoader-created `<style>` tag
-                        * or create a new one based on whether the given `cssText` is safe for extension.
-                        *
-                        * @private
-                        * @param {string} [cssText=cssBuffer] If called without cssText,
-                        *  the internal buffer will be inserted instead.
-                        * @param {Function} [callback]
-                        */
-                       function addEmbeddedCSS( cssText, callback ) {
-                               function fireCallbacks() {
-                                       var i,
-                                               oldCallbacks = cssCallbacks;
-                                       // Reset cssCallbacks variable so it's not polluted by any calls to
-                                       // addEmbeddedCSS() from one of the callbacks (T105973)
-                                       cssCallbacks = [];
-                                       for ( i = 0; i < oldCallbacks.length; i++ ) {
-                                               oldCallbacks[ i ]();
-                                       }
-                               }
-
-                               if ( callback ) {
-                                       cssCallbacks.push( callback );
-                               }
-
-                               // Yield once before creating the <style> tag. This lets multiple stylesheets
-                               // accumulate into one buffer, allowing us to reduce how often new stylesheets
-                               // are inserted in the browser. Appending a stylesheet and waiting for the
-                               // browser to repaint is fairly expensive. (T47810)
-                               if ( cssText ) {
-                                       // Don't extend the buffer if the item needs its own stylesheet.
-                                       // Keywords like `@import` are only valid at the start of a stylesheet (T37562).
-                                       if ( !cssBuffer || cssText.slice( 0, '@import'.length ) !== '@import' ) {
-                                               // Linebreak for somewhat distinguishable sections
-                                               cssBuffer += '\n' + cssText;
-                                               if ( !cssBufferTimer ) {
-                                                       cssBufferTimer = rAF( function () {
-                                                               // Wrap in anonymous function that takes no arguments
-                                                               // Support: Firefox < 13
-                                                               // Firefox 12 has non-standard behaviour of passing a number
-                                                               // as first argument to a setTimeout callback.
-                                                               // http://benalman.com/news/2009/07/the-mysterious-firefox-settime/
-                                                               addEmbeddedCSS();
-                                                       } );
-                                               }
-                                               return;
-                                       }
-
-                               // This is a scheduled flush for the buffer
-                               } else {
-                                       cssBufferTimer = null;
-                                       cssText = cssBuffer;
-                                       cssBuffer = '';
-                               }
-
-                               newStyleTag( cssText, marker );
-
-                               fireCallbacks();
-                       }
-
-                       /**
-                        * @private
-                        * @param {Array} modules List of module names
-                        * @return {string} Hash of concatenated version hashes.
-                        */
-                       function getCombinedVersion( modules ) {
-                               var hashes = modules.map( function ( module ) {
-                                       return registry[ module ].version;
-                               } );
-                               return fnv132( hashes.join( '' ) );
-                       }
-
-                       /**
-                        * Determine whether all dependencies are in state 'ready', which means we may
-                        * execute the module or job now.
-                        *
-                        * @private
-                        * @param {Array} 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++ ) {
-                                       if ( mw.loader.getState( modules[ i ] ) !== 'ready' ) {
-                                               return false;
-                                       }
-                               }
-                               return true;
-                       }
-
-                       /**
-                        * Determine whether all dependencies are in state 'ready', which means we may
-                        * execute the module or job now.
-                        *
-                        * @private
-                        * @param {Array} modules Names of modules to be checked
-                        * @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++ ) {
-                                       state = mw.loader.getState( modules[ i ] );
-                                       if ( state === 'error' || state === 'missing' ) {
-                                               return true;
-                                       }
-                               }
-                               return false;
-                       }
-
-                       /**
-                        * A module has entered state 'ready', 'error', or 'missing'. Automatically update
-                        * pending jobs and modules that depend upon this module. If the given module failed,
-                        * propagate the 'error' state up the dependency tree. Otherwise, go ahead and execute
-                        * all jobs/modules now having their dependencies satisfied.
-                        *
-                        * Jobs that depend on a failed module, will have their error callback ran (if any).
-                        *
-                        * @private
-                        * @param {string} module Name of module that entered one of the states 'ready', 'error', or 'missing'.
-                        */
-                       function handlePending( module ) {
-                               var j, job, hasErrors, m, stateChange;
-
-                               if ( registry[ module ].state === 'error' || registry[ module ].state === 'missing' ) {
-                                       // If the current module failed, mark all dependent modules also as failed.
-                                       // Iterate until steady-state to propagate the error state upwards in the
-                                       // dependency tree.
-                                       do {
-                                               stateChange = false;
-                                               for ( m in registry ) {
-                                                       if ( registry[ m ].state !== 'error' && registry[ m ].state !== 'missing' ) {
-                                                               if ( anyFailed( registry[ m ].dependencies ) ) {
-                                                                       registry[ m ].state = 'error';
-                                                                       stateChange = true;
-                                                               }
-                                                       }
-                                               }
-                                       } while ( stateChange );
-                               }
-
-                               // Execute all jobs whose dependencies are either all satisfied or contain at least one failed module.
-                               for ( j = 0; j < jobs.length; j++ ) {
-                                       hasErrors = anyFailed( jobs[ j ].dependencies );
-                                       if ( hasErrors || allReady( jobs[ j ].dependencies ) ) {
-                                               // All dependencies satisfied, or some have errors
-                                               job = jobs[ j ];
-                                               jobs.splice( j, 1 );
-                                               j -= 1;
-                                               try {
-                                                       if ( hasErrors ) {
-                                                               if ( typeof job.error === 'function' ) {
-                                                                       job.error( new Error( 'Module ' + module + ' has failed dependencies' ), [ module ] );
-                                                               }
-                                                       } else {
-                                                               if ( typeof job.ready === 'function' ) {
-                                                                       job.ready();
-                                                               }
-                                                       }
-                                               } catch ( e ) {
-                                                       // A user-defined callback raised an exception.
-                                                       // Swallow it to protect our state machine!
-                                                       mw.track( 'resourceloader.exception', { exception: e, module: module, source: 'load-callback' } );
-                                               }
-                                       }
-                               }
-
-                               if ( registry[ module ].state === 'ready' ) {
-                                       // The current module became 'ready'. Set it in the module store, and recursively execute all
-                                       // dependent modules that are loaded and now have all dependencies satisfied.
-                                       mw.loader.store.set( module, registry[ module ] );
-                                       for ( m in registry ) {
-                                               if ( registry[ m ].state === 'loaded' && allReady( registry[ m ].dependencies ) ) {
-                                                       execute( m );
-                                               }
-                                       }
-                               }
-                       }
-
-                       /**
-                        * Resolve dependencies and detect circular references.
-                        *
-                        * @private
-                        * @param {string} module Name of the top-level module whose dependencies shall be
-                        *  resolved and sorted.
-                        * @param {Array} resolved Returns a topological sort of the given module and its
-                        *  dependencies, such that later modules depend on earlier modules. The array
-                        *  contains the module names. If the array contains already some module names,
-                        *  this function appends its result to the pre-existing array.
-                        * @param {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
-                        */
-                       function sortDependencies( module, resolved, unresolved ) {
-                               var i, deps, skip;
-
-                               if ( !hasOwn.call( registry, module ) ) {
-                                       throw new Error( 'Unknown dependency: ' + module );
-                               }
-
-                               if ( registry[ module ].skip !== null ) {
-                                       // eslint-disable-next-line no-new-func
-                                       skip = new Function( registry[ module ].skip );
-                                       registry[ module ].skip = null;
-                                       if ( skip() ) {
-                                               registry[ module ].skipped = true;
-                                               registry[ module ].dependencies = [];
-                                               registry[ module ].state = 'ready';
-                                               handlePending( module );
-                                               return;
-                                       }
-                               }
-
-                               if ( resolved.indexOf( module ) !== -1 ) {
-                                       // Module already resolved; nothing to do
-                                       return;
-                               }
-                               // Create unresolved if not passed in
-                               if ( !unresolved ) {
-                                       unresolved = new StringSet();
-                               }
-                               // Tracks down dependencies
-                               deps = registry[ module ].dependencies;
-                               for ( i = 0; i < deps.length; i++ ) {
-                                       if ( resolved.indexOf( deps[ i ] ) === -1 ) {
-                                               if ( unresolved.has( deps[ i ] ) ) {
-                                                       throw new Error( mw.format(
-                                                               'Circular reference detected: $1 -> $2',
-                                                               module,
-                                                               deps[ i ]
-                                                       ) );
-                                               }
-
-                                               unresolved.add( module );
-                                               sortDependencies( deps[ i ], resolved, unresolved );
-                                       }
-                               }
-                               resolved.push( module );
-                       }
-
-                       /**
-                        * Get names of module that a module depends on, in their proper dependency order.
-                        *
-                        * @private
-                        * @param {string[]} modules Array of string module names
-                        * @return {Array} List of dependencies, including 'module'.
-                        * @throws {Error} If an unregistered module or a dependency loop is encountered
-                        */
-                       function resolve( modules ) {
-                               var i, resolved = [];
-                               for ( i = 0; i < modules.length; i++ ) {
-                                       sortDependencies( modules[ i ], resolved );
-                               }
-                               return resolved;
-                       }
-
-                       /**
-                        * Like #resolve(), except it will silently ignore modules that
-                        * are missing or have missing dependencies.
-                        *
-                        * @private
-                        * @param {string[]} modules Array of string module names
-                        * @return {Array} List of dependencies.
-                        */
-                       function resolveStubbornly( modules ) {
-                               var i, saved, resolved = [];
-                               for ( i = 0; i < modules.length; i++ ) {
-                                       saved = resolved.slice();
-                                       try {
-                                               sortDependencies( modules[ i ], resolved );
-                                       } catch ( err ) {
-                                               // This module is unknown or has unknown dependencies.
-                                               // Undo any incomplete resolutions made and keep going.
-                                               resolved = saved;
-                                               mw.track( 'resourceloader.exception', {
-                                                       exception: err,
-                                                       source: 'resolve'
-                                               } );
-                                       }
-                               }
-                               return resolved;
-                       }
-
-                       /**
-                        * Load and execute a script.
-                        *
-                        * @private
-                        * @param {string} src URL to script, will be used as the src attribute in the script tag
-                        * @param {Function} [callback] Callback to run after request resolution
-                        */
-                       function addScript( src, callback ) {
-                               var script = document.createElement( 'script' );
-                               script.src = src;
-                               script.onload = script.onerror = function () {
-                                       if ( script.parentNode ) {
-                                               script.parentNode.removeChild( script );
-                                       }
-                                       script = null;
-                                       if ( callback ) {
-                                               callback();
-                                               callback = null;
-                                       }
-                               };
-                               document.head.appendChild( script );
-                       }
-
-                       /**
-                        * Queue the loading and execution of a script for a particular module.
-                        *
-                        * @private
-                        * @param {string} src URL of the script
-                        * @param {string} moduleName Name of currently executing module
-                        * @param {Function} callback Callback to run after addScript() resolution
-                        */
-                       function queueModuleScript( src, moduleName, callback ) {
-                               pendingRequests.push( function () {
-                                       if ( hasOwn.call( registry, moduleName ) ) {
-                                               // Emulate runScript() part of execute()
-                                               window.require = mw.loader.require;
-                                               window.module = registry[ moduleName ].module;
-                                       }
-                                       addScript( src, function () {
-                                               // 'module.exports' should not persist after the file is executed to
-                                               // avoid leakage to unrelated code. 'require' should be kept, however,
-                                               // as asynchronous access to 'require' is allowed and expected. (T144879)
-                                               delete window.module;
-                                               callback();
-                                               // Start the next one (if any)
-                                               if ( pendingRequests[ 0 ] ) {
-                                                       pendingRequests.shift()();
-                                               } else {
-                                                       handlingPendingRequests = false;
-                                               }
-                                       } );
-                               } );
-                               if ( !handlingPendingRequests && pendingRequests[ 0 ] ) {
-                                       handlingPendingRequests = true;
-                                       pendingRequests.shift()();
-                               }
-                       }
-
-                       /**
-                        * Utility function for execute()
-                        *
-                        * @ignore
-                        * @param {string} [media] Media attribute
-                        * @param {string} url URL
-                        */
-                       function addLink( media, url ) {
-                               var el = document.createElement( 'link' );
-
-                               el.rel = 'stylesheet';
-                               if ( media && media !== 'all' ) {
-                                       el.media = media;
-                               }
-                               // If you end up here from an IE exception "SCRIPT: Invalid property value.",
-                               // see #addEmbeddedCSS, T33676, T43331, and T49277 for details.
-                               el.href = url;
-
-                               if ( marker && marker.parentNode ) {
-                                       marker.parentNode.insertBefore( el, marker );
-                               } else {
-                                       document.head.appendChild( el );
-                               }
-                       }
-
-                       /**
-                        * @private
-                        * @param {string} code JavaScript code
-                        */
-                       function domEval( code ) {
-                               var script = document.createElement( 'script' );
-                               script.text = code;
-                               document.head.appendChild( script );
-                               script.parentNode.removeChild( script );
-                       }
-
-                       /**
-                        * Executes a loaded module, making it ready to use
-                        *
-                        * @private
-                        * @param {string} module Module name to execute
-                        */
-                       function execute( module ) {
-                               var key, value, media, i, urls, cssHandle, checkCssHandles, runScript,
-                                       cssHandlesRegistered = false;
-
-                               if ( !hasOwn.call( registry, module ) ) {
-                                       throw new Error( 'Module has not been registered yet: ' + module );
-                               }
-                               if ( registry[ module ].state !== 'loaded' ) {
-                                       throw new Error( 'Module in state "' + registry[ module ].state + '" may not be executed: ' + module );
-                               }
-
-                               registry[ module ].state = 'executing';
-
-                               runScript = function () {
-                                       var script, markModuleReady, nestedAddScript;
-
-                                       script = registry[ module ].script;
-                                       markModuleReady = function () {
-                                               registry[ module ].state = 'ready';
-                                               handlePending( module );
-                                       };
-                                       nestedAddScript = function ( arr, callback, i ) {
-                                               // Recursively call queueModuleScript() in its own callback
-                                               // for each element of arr.
-                                               if ( i >= arr.length ) {
-                                                       // We're at the end of the array
-                                                       callback();
-                                                       return;
-                                               }
-
-                                               queueModuleScript( arr[ i ], module, function () {
-                                                       nestedAddScript( arr, callback, i + 1 );
-                                               } );
-                                       };
-
-                                       try {
-                                               if ( Array.isArray( script ) ) {
-                                                       nestedAddScript( script, markModuleReady, 0 );
-                                               } else if ( typeof script === 'function' ) {
-                                                       // Pass jQuery twice so that the signature of the closure which wraps
-                                                       // the script can bind both '$' and 'jQuery'.
-                                                       script( $, $, mw.loader.require, registry[ module ].module );
-                                                       markModuleReady();
-
-                                               } else if ( typeof script === 'string' ) {
-                                                       // Site and user modules are legacy scripts that run in the global scope.
-                                                       // This is transported as a string instead of a function to avoid needing
-                                                       // to use string manipulation to undo the function wrapper.
-                                                       domEval( script );
-                                                       markModuleReady();
-
-                                               } else {
-                                                       // Module without script
-                                                       markModuleReady();
-                                               }
-                                       } catch ( e ) {
-                                               // Use mw.track instead of mw.log because these errors are common in production mode
-                                               // (e.g. undefined variable), and mw.log is only enabled in debug mode.
-                                               registry[ module ].state = 'error';
-                                               mw.track( 'resourceloader.exception', { exception: e, module: module, source: 'module-execute' } );
-                                               handlePending( module );
-                                       }
-                               };
-
-                               // Add localizations to message system
-                               if ( registry[ module ].messages ) {
-                                       mw.messages.set( registry[ module ].messages );
-                               }
-
-                               // Initialise templates
-                               if ( registry[ module ].templates ) {
-                                       mw.templates.set( module, registry[ module ].templates );
-                               }
-
-                               // Make sure we don't run the scripts until all stylesheet insertions have completed.
-                               ( function () {
-                                       var pending = 0;
-                                       checkCssHandles = function () {
-                                               // cssHandlesRegistered ensures we don't take off too soon, e.g. when
-                                               // one of the cssHandles is fired while we're still creating more handles.
-                                               if ( cssHandlesRegistered && pending === 0 && runScript ) {
-                                                       if ( module === 'user' ) {
-                                                               // Implicit dependency on the site module. Not real dependency because
-                                                               // it should run after 'site' regardless of whether it succeeds or fails.
-                                                               mw.loader.using( [ 'site' ] ).always( runScript );
-                                                       } else {
-                                                               runScript();
-                                                       }
-                                                       runScript = undefined; // Revoke
-                                               }
-                                       };
-                                       cssHandle = function () {
-                                               var check = checkCssHandles;
-                                               pending++;
-                                               return function () {
-                                                       if ( check ) {
-                                                               pending--;
-                                                               check();
-                                                               check = undefined; // Revoke
-                                                       }
-                                               };
-                                       };
-                               }() );
-
-                               // Process styles (see also mw.loader.implement)
-                               // * back-compat: { <media>: css }
-                               // * back-compat: { <media>: [url, ..] }
-                               // * { "css": [css, ..] }
-                               // * { "url": { <media>: [url, ..] } }
-                               if ( registry[ module ].style ) {
-                                       for ( key in registry[ module ].style ) {
-                                               value = registry[ module ].style[ key ];
-                                               media = undefined;
-
-                                               if ( key !== 'url' && key !== 'css' ) {
-                                                       // Backwards compatibility, key is a media-type
-                                                       if ( typeof value === 'string' ) {
-                                                               // back-compat: { <media>: css }
-                                                               // Ignore 'media' because it isn't supported (nor was it used).
-                                                               // Strings are pre-wrapped in "@media". The media-type was just ""
-                                                               // (because it had to be set to something).
-                                                               // This is one of the reasons why this format is no longer used.
-                                                               addEmbeddedCSS( value, cssHandle() );
-                                                       } else {
-                                                               // back-compat: { <media>: [url, ..] }
-                                                               media = key;
-                                                               key = 'bc-url';
-                                                       }
-                                               }
-
-                                               // Array of css strings in key 'css',
-                                               // or back-compat array of urls from media-type
-                                               if ( Array.isArray( value ) ) {
-                                                       for ( i = 0; i < value.length; i++ ) {
-                                                               if ( key === 'bc-url' ) {
-                                                                       // back-compat: { <media>: [url, ..] }
-                                                                       addLink( media, value[ i ] );
-                                                               } else if ( key === 'css' ) {
-                                                                       // { "css": [css, ..] }
-                                                                       addEmbeddedCSS( value[ i ], cssHandle() );
-                                                               }
-                                                       }
-                                               // Not an array, but a regular object
-                                               // Array of urls inside media-type key
-                                               } else if ( typeof value === 'object' ) {
-                                                       // { "url": { <media>: [url, ..] } }
-                                                       for ( media in value ) {
-                                                               urls = value[ media ];
-                                                               for ( i = 0; i < urls.length; i++ ) {
-                                                                       addLink( media, urls[ i ] );
-                                                               }
-                                                       }
-                                               }
-                                       }
-                               }
-
-                               // Kick off.
-                               cssHandlesRegistered = true;
-                               checkCssHandles();
-                       }
-
-                       /**
-                        * Add one or more modules to the module load queue.
-                        *
-                        * See also #work().
-                        *
-                        * @private
-                        * @param {string|string[]} dependencies Module name or array of string module names
-                        * @param {Function} [ready] Callback to execute when all dependencies are ready
-                        * @param {Function} [error] Callback to execute when any dependency fails
-                        */
-                       function enqueue( dependencies, ready, error ) {
-                               // Allow calling by single module name
-                               if ( typeof dependencies === 'string' ) {
-                                       dependencies = [ dependencies ];
-                               }
-
-                               // Add ready and error callbacks if they were given
-                               if ( ready !== undefined || error !== undefined ) {
-                                       jobs.push( {
-                                               // Narrow down the list to modules that are worth waiting for
-                                               dependencies: dependencies.filter( function ( module ) {
-                                                       var state = mw.loader.getState( module );
-                                                       return state === 'registered' || state === 'loaded' || state === 'loading' || state === 'executing';
-                                               } ),
-                                               ready: ready,
-                                               error: error
-                                       } );
-                               }
-
-                               dependencies.forEach( function ( module ) {
-                                       var state = mw.loader.getState( module );
-                                       // Only queue modules that are still in the initial 'registered' state
-                                       // (not ones already loading, ready or error).
-                                       if ( state === 'registered' && queue.indexOf( module ) === -1 ) {
-                                               // Private modules must be embedded in the page. Don't bother queuing
-                                               // these as the server will deny them anyway (T101806).
-                                               if ( registry[ module ].group === 'private' ) {
-                                                       registry[ module ].state = 'error';
-                                                       handlePending( module );
-                                                       return;
-                                               }
-                                               queue.push( module );
-                                       }
-                               } );
-
-                               mw.loader.work();
-                       }
-
-                       function sortQuery( o ) {
-                               var key,
-                                       sorted = {},
-                                       a = [];
-
-                               for ( key in o ) {
-                                       a.push( key );
-                               }
-                               a.sort();
-                               for ( key = 0; key < a.length; key++ ) {
-                                       sorted[ a[ key ] ] = o[ a[ key ] ];
-                               }
-                               return sorted;
-                       }
-
-                       /**
-                        * Converts a module map of the form `{ foo: [ 'bar', 'baz' ], bar: [ 'baz, 'quux' ] }`
-                        * to a query string of the form `foo.bar,baz|bar.baz,quux`.
-                        *
-                        * See `ResourceLoader::makePackedModulesString()` in PHP, of which this is a port.
-                        * On the server, unpacking is done by `ResourceLoaderContext::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
-                        * to decide when to split the requests due to url size.
-                        *
-                        * @private
-                        * @param {Object} moduleMap Module map
-                        * @return {Object}
-                        * @return {string} return.str Module query string
-                        * @return {Array} return.list List of module names in matching order
-                        */
-                       function buildModulesString( moduleMap ) {
-                               var p, prefix,
-                                       str = [],
-                                       list = [];
-
-                               function restore( suffix ) {
-                                       return p + suffix;
-                               }
-
-                               for ( prefix in moduleMap ) {
-                                       p = prefix === '' ? '' : prefix + '.';
-                                       str.push( p + moduleMap[ prefix ].join( ',' ) );
-                                       list.push.apply( list, moduleMap[ prefix ].map( restore ) );
-                               }
-                               return {
-                                       str: str.join( '|' ),
-                                       list: list
-                               };
-                       }
-
-                       /**
-                        * Resolve indexed dependencies.
-                        *
-                        * ResourceLoader uses an optimization to save space which replaces module names in
-                        * dependency lists with the index of that module within the array of module
-                        * registration data if it exists. The benefit is a significant reduction in the data
-                        * size of the startup module. This function changes those dependency lists back to
-                        * arrays of strings.
-                        *
-                        * @private
-                        * @param {Array} modules Modules array
-                        */
-                       function resolveIndexedDependencies( modules ) {
-                               var i, j, deps;
-                               function resolveIndex( dep ) {
-                                       return typeof dep === 'number' ? modules[ dep ][ 0 ] : dep;
-                               }
-                               for ( i = 0; i < modules.length; i++ ) {
-                                       deps = modules[ i ][ 2 ];
-                                       if ( deps ) {
-                                               for ( j = 0; j < deps.length; j++ ) {
-                                                       deps[ j ] = resolveIndex( deps[ j ] );
-                                               }
-                                       }
-                               }
-                       }
-
-                       /**
-                        * Create network requests for a batch of modules.
-                        *
-                        * This is an internal method for #work(). This must not be called directly
-                        * unless the modules are already registered, and no request is in progress,
-                        * and the module state has already been set to `loading`.
-                        *
-                        * @private
-                        * @param {string[]} batch
-                        */
-                       function batchRequest( batch ) {
-                               var reqBase, splits, maxQueryLength, b, bSource, bGroup, bSourceGroup,
-                                       source, group, i, modules, sourceLoadScript,
-                                       currReqBase, currReqBaseLength, moduleMap, currReqModules, l,
-                                       lastDotIndex, prefix, suffix, bytesAdded;
-
-                               /**
-                                * Start the currently drafted request to the server.
-                                *
-                                * @ignore
-                                */
-                               function doRequest() {
-                                       // Optimisation: Inherit (Object.create), not copy ($.extend)
-                                       var query = Object.create( currReqBase ),
-                                               packed = buildModulesString( moduleMap );
-                                       query.modules = packed.str;
-                                       // The packing logic can change the effective order, even if the input was
-                                       // sorted. As such, the call to getCombinedVersion() must use this
-                                       // effective order, instead of currReqModules, as otherwise the combined
-                                       // version will not match the hash expected by the server based on
-                                       // combining versions from the module query string in-order. (T188076)
-                                       query.version = getCombinedVersion( packed.list );
-                                       query = sortQuery( query );
-                                       addScript( sourceLoadScript + '?' + $.param( query ) );
-                               }
-
-                               if ( !batch.length ) {
-                                       return;
-                               }
-
-                               // Always order modules alphabetically to help reduce cache
-                               // misses for otherwise identical content.
-                               batch.sort();
-
-                               // Query parameters common to all requests
-                               reqBase = {
-                                       skin: mw.config.get( 'skin' ),
-                                       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 = {};
-                               for ( b = 0; b < batch.length; b++ ) {
-                                       bSource = registry[ batch[ b ] ].source;
-                                       bGroup = registry[ batch[ b ] ].group;
-                                       if ( !hasOwn.call( splits, bSource ) ) {
-                                               splits[ bSource ] = {};
-                                       }
-                                       if ( !hasOwn.call( splits[ bSource ], bGroup ) ) {
-                                               splits[ bSource ][ bGroup ] = [];
-                                       }
-                                       bSourceGroup = splits[ bSource ][ bGroup ];
-                                       bSourceGroup.push( batch[ b ] );
-                               }
-
-                               for ( source in splits ) {
-
-                                       sourceLoadScript = sources[ source ];
-
-                                       for ( group in splits[ source ] ) {
-
-                                               // Cache access to currently selected list of
-                                               // modules for this group from this source.
-                                               modules = splits[ source ][ group ];
-
-                                               // Query parameters common to requests for this module group
-                                               // Optimisation: Inherit (Object.create), not copy ($.extend)
-                                               currReqBase = Object.create( reqBase );
-                                               // User modules require a user name in the query string.
-                                               if ( group === 'user' && mw.config.get( 'wgUserName' ) !== null ) {
-                                                       currReqBase.user = mw.config.get( 'wgUserName' );
-                                               }
-
-                                               // In addition to currReqBase, doRequest() will also add 'modules' and 'version'.
-                                               // > '&modules='.length === 9
-                                               // > '&version=1234567'.length === 16
-                                               // > 9 + 16 = 25
-                                               currReqBaseLength = $.param( currReqBase ).length + 25;
-
-                                               // We may need to split up the request to honor the query string length limit,
-                                               // so build it piece by piece.
-                                               l = currReqBaseLength;
-                                               moduleMap = {}; // { prefix: [ suffixes ] }
-                                               currReqModules = [];
-
-                                               for ( i = 0; i < modules.length; i++ ) {
-                                                       // Determine how many bytes this module would add to the query string
-                                                       lastDotIndex = modules[ i ].lastIndexOf( '.' );
-                                                       // If lastDotIndex is -1, substr() returns an empty string
-                                                       prefix = modules[ i ].substr( 0, lastDotIndex );
-                                                       suffix = modules[ i ].slice( lastDotIndex + 1 );
-                                                       bytesAdded = hasOwn.call( moduleMap, prefix ) ?
-                                                               suffix.length + 3 : // '%2C'.length == 3
-                                                               modules[ i ].length + 3; // '%7C'.length == 3
-
-                                                       // 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 ) {
-                                                               // Dispatch what we've got...
-                                                               doRequest();
-                                                               // .. and start again.
-                                                               l = currReqBaseLength;
-                                                               moduleMap = {};
-                                                               currReqModules = [];
-
-                                                               mw.track( 'resourceloader.splitRequest', { maxQueryLength: maxQueryLength } );
-                                                       }
-                                                       if ( !hasOwn.call( moduleMap, prefix ) ) {
-                                                               moduleMap[ prefix ] = [];
-                                                       }
-                                                       l += bytesAdded;
-                                                       moduleMap[ prefix ].push( suffix );
-                                                       currReqModules.push( modules[ i ] );
-                                               }
-                                               // If there's anything left in moduleMap, request that too
-                                               if ( currReqModules.length ) {
-                                                       doRequest();
-                                               }
-                                       }
-                               }
-                       }
-
-                       /**
-                        * @private
-                        * @param {string[]} implementations Array containing pieces of JavaScript code in the
-                        *  form of calls to mw.loader#implement().
-                        * @param {Function} cb Callback in case of failure
-                        * @param {Error} cb.err
-                        */
-                       function asyncEval( implementations, cb ) {
-                               if ( !implementations.length ) {
-                                       return;
-                               }
-                               mw.requestIdleCallback( function () {
-                                       try {
-                                               domEval( implementations.join( ';' ) );
-                                       } catch ( err ) {
-                                               cb( err );
-                                       }
-                               } );
-                       }
-
-                       /**
-                        * Make a versioned key for a specific module.
-                        *
-                        * @private
-                        * @param {string} module Module name
-                        * @return {string|null} Module key in format '`[name]@[version]`',
-                        *  or null if the module does not exist
-                        */
-                       function getModuleKey( module ) {
-                               return hasOwn.call( registry, module ) ?
-                                       ( module + '@' + registry[ module ].version ) : null;
-                       }
-
-                       /**
-                        * @private
-                        * @param {string} key Module name or '`[name]@[version]`'
-                        * @return {Object}
-                        */
-                       function splitModuleKey( key ) {
-                               var index = key.indexOf( '@' );
-                               if ( index === -1 ) {
-                                       return {
-                                               name: key,
-                                               version: ''
-                                       };
-                               }
-                               return {
-                                       name: key.slice( 0, index ),
-                                       version: key.slice( index + 1 )
-                               };
-                       }
-
-                       /* Public Members */
-                       return {
-                               /**
-                                * The module registry is exposed as an aid for debugging and inspecting page
-                                * state; it is not a public interface for modifying the registry.
-                                *
-                                * @see #registry
-                                * @property
-                                * @private
-                                */
-                               moduleRegistry: registry,
-
-                               /**
-                                * @inheritdoc #newStyleTag
-                                * @method
-                                */
-                               addStyleTag: newStyleTag,
-
-                               /**
-                                * Start loading of all queued module dependencies.
-                                *
-                                * @protected
-                                */
-                               work: function () {
-                                       var q, batch, implementations, sourceModules;
-
-                                       batch = [];
-
-                                       // Appends a list of modules from the queue to the batch
-                                       for ( q = 0; q < queue.length; q++ ) {
-                                               // Only load modules which are registered
-                                               if ( hasOwn.call( registry, queue[ q ] ) && registry[ queue[ q ] ].state === 'registered' ) {
-                                                       // Prevent duplicate entries
-                                                       if ( batch.indexOf( queue[ q ] ) === -1 ) {
-                                                               batch.push( queue[ q ] );
-                                                               // Mark registered modules as loading
-                                                               registry[ queue[ q ] ].state = 'loading';
-                                                       }
-                                               }
-                                       }
-
-                                       // Now that the queue has been processed into a batch, clear the queue.
-                                       // This MUST happen before we initiate any eval or network request. Otherwise,
-                                       // it is possible for a cached script to instantly trigger the same work queue
-                                       // again; all before we've cleared it causing each request to include modules
-                                       // which are already loaded.
-                                       queue = [];
-
-                                       if ( !batch.length ) {
-                                               return;
-                                       }
-
-                                       mw.loader.store.init();
-                                       if ( mw.loader.store.enabled ) {
-                                               implementations = [];
-                                               sourceModules = [];
-                                               batch = batch.filter( function ( module ) {
-                                                       var implementation = mw.loader.store.get( module );
-                                                       if ( implementation ) {
-                                                               implementations.push( implementation );
-                                                               sourceModules.push( module );
-                                                               return false;
-                                                       }
-                                                       return true;
-                                               } );
-                                               asyncEval( implementations, function ( err ) {
-                                                       var failed;
-                                                       // Not good, the cached mw.loader.implement calls failed! This should
-                                                       // never happen, barring ResourceLoader bugs, browser bugs and PEBKACs.
-                                                       // Depending on how corrupt the string is, it is likely that some
-                                                       // modules' implement() succeeded while the ones after the error will
-                                                       // never run and leave their modules in the 'loading' state forever.
-                                                       mw.loader.store.stats.failed++;
-
-                                                       // Since this is an error not caused by an individual module but by
-                                                       // something that infected the implement call itself, don't take any
-                                                       // risks and clear everything in this cache.
-                                                       mw.loader.store.clear();
-
-                                                       mw.track( 'resourceloader.exception', { exception: err, source: 'store-eval' } );
-                                                       // Re-add the failed ones that are still pending back to the batch
-                                                       failed = sourceModules.filter( function ( module ) {
-                                                               return registry[ module ].state === 'loading';
-                                                       } );
-                                                       batchRequest( failed );
-                                               } );
-                                       }
-
-                                       batchRequest( batch );
-                               },
-
-                               /**
-                                * Register a source.
-                                *
-                                * The #work() method will use this information to split up requests by source.
-                                *
-                                *     mw.loader.addSource( 'mediawikiwiki', '//www.mediawiki.org/w/load.php' );
-                                *
-                                * @param {string|Object} id Source ID, or object mapping ids to load urls
-                                * @param {string} loadUrl Url to a load.php end point
-                                * @throws {Error} If source id is already registered
-                                */
-                               addSource: function ( id, loadUrl ) {
-                                       var source;
-                                       // Allow multiple additions
-                                       if ( typeof id === 'object' ) {
-                                               for ( source in id ) {
-                                                       mw.loader.addSource( source, id[ source ] );
-                                               }
-                                               return;
-                                       }
-
-                                       if ( hasOwn.call( sources, id ) ) {
-                                               throw new Error( 'source already registered: ' + id );
-                                       }
-
-                                       sources[ id ] = loadUrl;
-                               },
-
-                               /**
-                                * Register a module, letting the system know about it and its properties.
-                                *
-                                * The startup modules contain calls to this method.
-                                *
-                                * When using multiple module registration by passing an array, dependencies that
-                                * are specified as references to modules within the array will be resolved before
-                                * the modules are registered.
-                                *
-                                * @param {string|Array} module Module name or array of arrays, each containing
-                                *  a list of arguments compatible with this method
-                                * @param {string|number} version Module version hash (falls backs to empty string)
-                                *  Can also be a number (timestamp) for compatibility with MediaWiki 1.25 and earlier.
-                                * @param {string|Array} dependencies One string or array of strings of module
-                                *  names on which this module depends.
-                                * @param {string} [group=null] Group which the module is in
-                                * @param {string} [source='local'] Name of the source
-                                * @param {string} [skip=null] Script body of the skip function
-                                */
-                               register: function ( module, version, dependencies, group, source, skip ) {
-                                       var i, deps;
-                                       // Allow multiple registration
-                                       if ( typeof module === 'object' ) {
-                                               resolveIndexedDependencies( module );
-                                               for ( i = 0; i < module.length; i++ ) {
-                                                       // module is an array of module names
-                                                       if ( typeof module[ i ] === 'string' ) {
-                                                               mw.loader.register( module[ i ] );
-                                                       // module is an array of arrays
-                                                       } else if ( typeof module[ i ] === 'object' ) {
-                                                               mw.loader.register.apply( mw.loader, module[ i ] );
-                                                       }
-                                               }
-                                               return;
-                                       }
-                                       if ( hasOwn.call( registry, module ) ) {
-                                               throw new Error( 'module already registered: ' + module );
-                                       }
-                                       if ( typeof dependencies === 'string' ) {
-                                               // A single module name
-                                               deps = [ dependencies ];
-                                       } else if ( typeof dependencies === 'object' ) {
-                                               // Array of module names
-                                               deps = dependencies;
-                                       }
-                                       // List the module as registered
-                                       registry[ module ] = {
-                                               // Exposed to execute() for mw.loader.implement() closures.
-                                               // Import happens via require().
-                                               module: {
-                                                       exports: {}
-                                               },
-                                               version: version !== undefined ? String( version ) : '',
-                                               dependencies: deps || [],
-                                               group: typeof group === 'string' ? group : null,
-                                               source: typeof source === 'string' ? source : 'local',
-                                               state: 'registered',
-                                               skip: typeof skip === 'string' ? skip : null
-                                       };
-                               },
-
-                               /**
-                                * Implement a module given the components that make up the module.
-                                *
-                                * When #load() or #using() requests one or more modules, the server
-                                * response contain calls to this function.
-                                *
-                                * @param {string} module Name of module and current module version. Formatted
-                                *  as '`[name]@[version]`". This version should match the requested version
-                                *  (from #batchRequest and #registry). This avoids race conditions (T117587).
-                                *  For back-compat with MediaWiki 1.27 and earlier, the version may be omitted.
-                                * @param {Function|Array|string} [script] Function with module code, list of URLs
-                                *  to load via `<script src>`, or string of module code for `$.globalEval()`.
-                                * @param {Object} [style] Should follow one of the following patterns:
-                                *
-                                *     { "css": [css, ..] }
-                                *     { "url": { <media>: [url, ..] } }
-                                *
-                                * And for backwards compatibility (needs to be supported forever due to caching):
-                                *
-                                *     { <media>: css }
-                                *     { <media>: [url, ..] }
-                                *
-                                * The reason css strings are not concatenated anymore is T33676. We now check
-                                * whether it's safe to extend the stylesheet.
-                                *
-                                * @protected
-                                * @param {Object} [messages] List of key/value pairs to be added to mw#messages.
-                                * @param {Object} [templates] List of key/value pairs to be added to mw#templates.
-                                */
-                               implement: function ( module, script, style, messages, templates ) {
-                                       var split = splitModuleKey( module ),
-                                               name = split.name,
-                                               version = split.version;
-                                       // Automatically register module
-                                       if ( !hasOwn.call( registry, name ) ) {
-                                               mw.loader.register( name );
-                                       }
-                                       // Check for duplicate implementation
-                                       if ( hasOwn.call( registry, name ) && registry[ name ].script !== undefined ) {
-                                               throw new Error( 'module already implemented: ' + name );
-                                       }
-                                       if ( version ) {
-                                               // Without this reset, if there is a version mismatch between the
-                                               // requested and received module version, then mw.loader.store would
-                                               // cache the response under the requested key. Thus poisoning the cache
-                                               // indefinitely with a stale value. (T117587)
-                                               registry[ name ].version = version;
-                                       }
-                                       // Attach components
-                                       registry[ name ].script = script || null;
-                                       registry[ name ].style = style || null;
-                                       registry[ name ].messages = messages || null;
-                                       registry[ name ].templates = templates || null;
-                                       // The module may already have been marked as erroneous
-                                       if ( registry[ name ].state !== 'error' && registry[ name ].state !== 'missing' ) {
-                                               registry[ name ].state = 'loaded';
-                                               if ( allReady( registry[ name ].dependencies ) ) {
-                                                       execute( name );
-                                               }
-                                       }
-                               },
-
-                               /**
-                                * Execute a function as soon as one or more required modules are ready.
-                                *
-                                * Example of inline dependency on OOjs:
-                                *
-                                *     mw.loader.using( 'oojs', function () {
-                                *         OO.compare( [ 1 ], [ 1 ] );
-                                *     } );
-                                *
-                                * Example of inline dependency obtained via `require()`:
-                                *
-                                *     mw.loader.using( [ 'mediawiki.util' ], function ( require ) {
-                                *         var util = require( 'mediawiki.util' );
-                                *     } );
-                                *
-                                * Since MediaWiki 1.23 this also returns a promise.
-                                *
-                                * Since MediaWiki 1.28 the promise is resolved with a `require` function.
-                                *
-                                * @param {string|Array} dependencies Module name or array of modules names the
-                                *  callback depends on to be ready before executing
-                                * @param {Function} [ready] Callback to execute when all dependencies are ready
-                                * @param {Function} [error] Callback to execute if one or more dependencies failed
-                                * @return {jQuery.Promise} With a `require` function
-                                */
-                               using: function ( dependencies, ready, error ) {
-                                       var deferred = $.Deferred();
-
-                                       // Allow calling with a single dependency as a string
-                                       if ( typeof dependencies === 'string' ) {
-                                               dependencies = [ dependencies ];
-                                       }
-
-                                       if ( ready ) {
-                                               deferred.done( ready );
-                                       }
-                                       if ( error ) {
-                                               deferred.fail( error );
-                                       }
-
-                                       try {
-                                               // Resolve entire dependency map
-                                               dependencies = resolve( dependencies );
-                                       } catch ( e ) {
-                                               return deferred.reject( e ).promise();
-                                       }
-                                       if ( allReady( dependencies ) ) {
-                                               // Run ready immediately
-                                               deferred.resolve( mw.loader.require );
-                                       } else if ( anyFailed( dependencies ) ) {
-                                               // Execute error immediately if any dependencies have errors
-                                               deferred.reject(
-                                                       new Error( 'One or more dependencies failed to load' ),
-                                                       dependencies
-                                               );
-                                       } else {
-                                               // Not all dependencies are ready, add to the load queue
-                                               enqueue( dependencies, function () {
-                                                       deferred.resolve( mw.loader.require );
-                                               }, deferred.reject );
-                                       }
-
-                                       return deferred.promise();
-                               },
-
-                               /**
-                                * Load an external script or one or more modules.
-                                *
-                                * This method takes a list of unrelated modules. Use cases:
-                                *
-                                * - A web page will be composed of many different widgets. These widgets independently
-                                *   queue their ResourceLoader modules (`OutputPage::addModules()`). If any of them
-                                *   have problems, or are no longer known (e.g. cached HTML), the other modules
-                                *   should still be loaded.
-                                * - This method is used for preloading, which must not throw. Later code that
-                                *   calls #using() will handle the error.
-                                *
-                                * @param {string|Array} modules Either the name of a module, array of modules,
-                                *  or a URL of an external script or style
-                                * @param {string} [type='text/javascript'] MIME type to use if calling with a URL of an
-                                *  external script or style; acceptable values are "text/css" and
-                                *  "text/javascript"; if no type is provided, text/javascript is assumed.
-                                */
-                               load: function ( modules, type ) {
-                                       var filtered, l;
-
-                                       // Allow calling with a url or single dependency as a string
-                                       if ( typeof modules === 'string' ) {
-                                               // "https://example.org/x.js", "http://example.org/x.js", "//example.org/x.js", "/x.js"
-                                               if ( /^(https?:)?\/?\//.test( modules ) ) {
-                                                       if ( type === 'text/css' ) {
-                                                               l = document.createElement( 'link' );
-                                                               l.rel = 'stylesheet';
-                                                               l.href = modules;
-                                                               document.head.appendChild( l );
-                                                               return;
-                                                       }
-                                                       if ( type === 'text/javascript' || type === undefined ) {
-                                                               addScript( modules );
-                                                               return;
-                                                       }
-                                                       // Unknown type
-                                                       throw new Error( 'invalid type for external url, must be text/css or text/javascript. not ' + type );
-                                               }
-                                               // Called with single module
-                                               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 );
-                                       // If all modules are ready, or if any modules have errors, nothing to be done.
-                                       if ( allReady( filtered ) || anyFailed( filtered ) ) {
-                                               return;
-                                       }
-                                       if ( filtered.length === 0 ) {
-                                               return;
-                                       }
-                                       // Some modules are not yet ready, add to module load queue.
-                                       enqueue( filtered, undefined, undefined );
-                               },
-
-                               /**
-                                * Change the state of one or more modules.
-                                *
-                                * @param {string|Object} module Module name or object of module name/state pairs
-                                * @param {string} state State name
-                                */
-                               state: function ( module, state ) {
-                                       var m;
-
-                                       if ( typeof module === 'object' ) {
-                                               for ( m in module ) {
-                                                       mw.loader.state( m, module[ m ] );
-                                               }
-                                               return;
-                                       }
-                                       if ( !hasOwn.call( registry, module ) ) {
-                                               mw.loader.register( module );
-                                       }
-                                       registry[ module ].state = state;
-                                       if ( state === 'ready' || state === 'error' || state === 'missing' ) {
-                                               // Make sure pending modules depending on this one get executed if their
-                                               // dependencies are now fulfilled!
-                                               handlePending( module );
-                                       }
-                               },
-
-                               /**
-                                * Get the version of a module.
-                                *
-                                * @param {string} module Name of module
-                                * @return {string|null} The version, or null if the module (or its version) is not
-                                *  in the registry.
-                                */
-                               getVersion: function ( module ) {
-                                       return hasOwn.call( registry, module ) ? registry[ module ].version : null;
-                               },
-
-                               /**
-                                * Get the state of a module.
-                                *
-                                * @param {string} module Name of module
-                                * @return {string|null} The state, or null if the module (or its state) is not
-                                *  in the registry.
-                                */
-                               getState: function ( module ) {
-                                       return hasOwn.call( registry, module ) ? registry[ module ].state : null;
-                               },
-
-                               /**
-                                * Get the names of all registered modules.
-                                *
-                                * @return {Array}
-                                */
-                               getModuleNames: function () {
-                                       return Object.keys( registry );
-                               },
-
-                               /**
-                                * Get the exported value of a module.
-                                *
-                                * This static method is publicly exposed for debugging purposes
-                                * only and must not be used in production code. In production code,
-                                * please use the dynamically provided `require()` function instead.
-                                *
-                                * In case of lazy-loaded modules via mw.loader#using(), the returned
-                                * Promise provides the function, see #using() for examples.
-                                *
-                                * @private
-                                * @since 1.27
-                                * @param {string} moduleName Module name
-                                * @return {Mixed} Exported value
-                                */
-                               require: function ( moduleName ) {
-                                       var state = mw.loader.getState( moduleName );
-
-                                       // Only ready modules can be required
-                                       if ( state !== 'ready' ) {
-                                               // Module may've forgotten to declare a dependency
-                                               throw new Error( 'Module "' + moduleName + '" is not loaded.' );
-                                       }
-
-                                       return registry[ moduleName ].module.exports;
-                               },
-
-                               /**
-                                * @inheritdoc mw.inspect#runReports
-                                * @method
-                                */
-                               inspect: function () {
-                                       var args = slice.call( arguments );
-                                       mw.loader.using( 'mediawiki.inspect', function () {
-                                               mw.inspect.runReports.apply( mw.inspect, args );
-                                       } );
-                               },
-
-                               /**
-                                * On browsers that implement the localStorage API, the module store serves as a
-                                * smart complement to the browser cache. Unlike the browser cache, the module store
-                                * can slice a concatenated response from ResourceLoader into its constituent
-                                * modules and cache each of them separately, using each module's versioning scheme
-                                * to determine when the cache should be invalidated.
-                                *
-                                * @singleton
-                                * @class mw.loader.store
-                                */
-                               store: {
-                                       // Whether the store is in use on this page.
-                                       enabled: null,
-
-                                       // Modules whose string representation exceeds 100 kB are
-                                       // ineligible for storage. See bug T66721.
-                                       MODULE_SIZE_MAX: 100 * 1000,
-
-                                       // The contents of the store, mapping '[name]@[version]' keys
-                                       // to module implementations.
-                                       items: {},
-
-                                       // Cache hit stats
-                                       stats: { hits: 0, misses: 0, expired: 0, failed: 0 },
-
-                                       /**
-                                        * Construct a JSON-serializable object representing the content of the store.
-                                        *
-                                        * @return {Object} Module store contents.
-                                        */
-                                       toJSON: function () {
-                                               return { items: mw.loader.store.items, vary: mw.loader.store.getVary() };
-                                       },
-
-                                       /**
-                                        * Get the localStorage key for the entire module store. The key references
-                                        * $wgDBname to prevent clashes between wikis which share a common host.
-                                        *
-                                        * @return {string} localStorage item key
-                                        */
-                                       getStoreKey: function () {
-                                               return 'MediaWikiModuleStore:' + mw.config.get( 'wgDBname' );
-                                       },
-
-                                       /**
-                                        * Get a key on which to vary the module cache.
-                                        *
-                                        * @return {string} String of concatenated vary conditions.
-                                        */
-                                       getVary: function () {
-                                               return [
-                                                       mw.config.get( 'skin' ),
-                                                       mw.config.get( 'wgResourceLoaderStorageVersion' ),
-                                                       mw.config.get( 'wgUserLanguage' )
-                                               ].join( ':' );
-                                       },
-
-                                       /**
-                                        * Initialize the store.
-                                        *
-                                        * Retrieves store from localStorage and (if successfully retrieved) decoding
-                                        * the stored JSON value to a plain object.
-                                        *
-                                        * The try / catch block is used for JSON & localStorage feature detection.
-                                        * See the in-line documentation for Modernizr's localStorage feature detection
-                                        * code for a full account of why we need a try / catch:
-                                        * <https://github.com/Modernizr/Modernizr/blob/v2.7.1/modernizr.js#L771-L796>.
-                                        */
-                                       init: function () {
-                                               var raw, data;
-
-                                               if ( mw.loader.store.enabled !== null ) {
-                                                       // Init already ran
-                                                       return;
-                                               }
-
-                                               if (
-                                                       // Disabled because localStorage quotas are tight and (in Firefox's case)
-                                                       // shared by multiple origins.
-                                                       // See T66721, and <https://bugzilla.mozilla.org/show_bug.cgi?id=1064466>.
-                                                       /Firefox|Opera/.test( navigator.userAgent ) ||
-
-                                                       // Disabled by configuration.
-                                                       !mw.config.get( 'wgResourceLoaderStorageEnabled' )
-                                               ) {
-                                                       // Clear any previous store to free up space. (T66721)
-                                                       mw.loader.store.clear();
-                                                       mw.loader.store.enabled = false;
-                                                       return;
-                                               }
-                                               if ( mw.config.get( 'debug' ) ) {
-                                                       // Disable module store in debug mode
-                                                       mw.loader.store.enabled = false;
-                                                       return;
-                                               }
-
-                                               try {
-                                                       raw = localStorage.getItem( mw.loader.store.getStoreKey() );
-                                                       // If we get here, localStorage is available; mark enabled
-                                                       mw.loader.store.enabled = true;
-                                                       data = JSON.parse( raw );
-                                                       if ( data && typeof data.items === 'object' && data.vary === mw.loader.store.getVary() ) {
-                                                               mw.loader.store.items = data.items;
-                                                               return;
-                                                       }
-                                               } catch ( e ) {
-                                                       mw.track( 'resourceloader.exception', { exception: e, source: 'store-localstorage-init' } );
-                                               }
-
-                                               if ( raw === undefined ) {
-                                                       // localStorage failed; disable store
-                                                       mw.loader.store.enabled = false;
-                                               } else {
-                                                       mw.loader.store.update();
-                                               }
-                                       },
-
-                                       /**
-                                        * Retrieve a module from the store and update cache hit stats.
-                                        *
-                                        * @param {string} module Module name
-                                        * @return {string|boolean} Module implementation or false if unavailable
-                                        */
-                                       get: function ( module ) {
-                                               var key;
-
-                                               if ( !mw.loader.store.enabled ) {
-                                                       return false;
-                                               }
-
-                                               key = getModuleKey( module );
-                                               if ( key in mw.loader.store.items ) {
-                                                       mw.loader.store.stats.hits++;
-                                                       return mw.loader.store.items[ key ];
-                                               }
-                                               mw.loader.store.stats.misses++;
-                                               return false;
-                                       },
-
-                                       /**
-                                        * Stringify a module and queue it for storage.
-                                        *
-                                        * @param {string} module Module name
-                                        * @param {Object} descriptor The module's descriptor as set in the registry
-                                        * @return {boolean} Module was set
-                                        */
-                                       set: function ( module, descriptor ) {
-                                               var args, key, src;
-
-                                               if ( !mw.loader.store.enabled ) {
-                                                       return false;
-                                               }
-
-                                               key = getModuleKey( module );
-
-                                               if (
-                                                       // Already stored a copy of this exact version
-                                                       key in mw.loader.store.items ||
-                                                       // Module failed to load
-                                                       descriptor.state !== 'ready' ||
-                                                       // Unversioned, private, or site-/user-specific
-                                                       !descriptor.version ||
-                                                       descriptor.group === 'private' ||
-                                                       descriptor.group === 'user' ||
-                                                       // Partial descriptor
-                                                       // (e.g. skipped module, or style module with state=ready)
-                                                       [ descriptor.script, descriptor.style, descriptor.messages,
-                                                               descriptor.templates ].indexOf( undefined ) !== -1
-                                               ) {
-                                                       // Decline to store
-                                                       return false;
-                                               }
-
-                                               try {
-                                                       args = [
-                                                               JSON.stringify( key ),
-                                                               typeof descriptor.script === 'function' ?
-                                                                       String( descriptor.script ) :
-                                                                       JSON.stringify( descriptor.script ),
-                                                               JSON.stringify( descriptor.style ),
-                                                               JSON.stringify( descriptor.messages ),
-                                                               JSON.stringify( descriptor.templates )
-                                                       ];
-                                                       // Attempted workaround for a possible Opera bug (bug T59567).
-                                                       // This regex should never match under sane conditions.
-                                                       if ( /^\s*\(/.test( args[ 1 ] ) ) {
-                                                               args[ 1 ] = 'function' + args[ 1 ];
-                                                               mw.track( 'resourceloader.assert', { source: 'bug-T59567' } );
-                                                       }
-                                               } catch ( e ) {
-                                                       mw.track( 'resourceloader.exception', { exception: e, source: 'store-localstorage-json' } );
-                                                       return false;
-                                               }
-
-                                               src = 'mw.loader.implement(' + args.join( ',' ) + ');';
-                                               if ( src.length > mw.loader.store.MODULE_SIZE_MAX ) {
-                                                       return false;
-                                               }
-                                               mw.loader.store.items[ key ] = src;
-                                               mw.loader.store.update();
-                                               return true;
-                                       },
-
-                                       /**
-                                        * Iterate through the module store, removing any item that does not correspond
-                                        * (in name and version) to an item in the module registry.
-                                        *
-                                        * @return {boolean} Store was pruned
-                                        */
-                                       prune: function () {
-                                               var key, module;
-
-                                               if ( !mw.loader.store.enabled ) {
-                                                       return false;
-                                               }
-
-                                               for ( key in mw.loader.store.items ) {
-                                                       module = key.slice( 0, key.indexOf( '@' ) );
-                                                       if ( getModuleKey( module ) !== key ) {
-                                                               mw.loader.store.stats.expired++;
-                                                               delete mw.loader.store.items[ key ];
-                                                       } else if ( mw.loader.store.items[ key ].length > mw.loader.store.MODULE_SIZE_MAX ) {
-                                                               // This value predates the enforcement of a size limit on cached modules.
-                                                               delete mw.loader.store.items[ key ];
-                                                       }
-                                               }
-                                               return true;
-                                       },
-
-                                       /**
-                                        * Clear the entire module store right now.
-                                        */
-                                       clear: function () {
-                                               mw.loader.store.items = {};
-                                               try {
-                                                       localStorage.removeItem( mw.loader.store.getStoreKey() );
-                                               } catch ( ignored ) {}
-                                       },
-
-                                       /**
-                                        * Sync in-memory store back to localStorage.
-                                        *
-                                        * This function debounces updates. When called with a flush already pending,
-                                        * the call is coalesced into the pending update. The call to
-                                        * localStorage.setItem will be naturally deferred until the page is quiescent.
-                                        *
-                                        * Because localStorage is shared by all pages from the same origin, if multiple
-                                        * pages are loaded with different module sets, the possibility exists that
-                                        * modules saved by one page will be clobbered by another. But the impact would
-                                        * be minor and the problem would be corrected by subsequent page views.
-                                        *
-                                        * @method
-                                        */
-                                       update: ( function () {
-                                               var hasPendingWrite = false;
-
-                                               function flushWrites() {
-                                                       var data, key;
-                                                       if ( !hasPendingWrite || !mw.loader.store.enabled ) {
-                                                               return;
-                                                       }
-
-                                                       mw.loader.store.prune();
-                                                       key = mw.loader.store.getStoreKey();
-                                                       try {
-                                                               // Replacing the content of the module store might fail if the new
-                                                               // contents would exceed the browser's localStorage size limit. To
-                                                               // avoid clogging the browser with stale data, always remove the old
-                                                               // value before attempting to set the new one.
-                                                               localStorage.removeItem( key );
-                                                               data = JSON.stringify( mw.loader.store );
-                                                               localStorage.setItem( key, data );
-                                                       } catch ( e ) {
-                                                               mw.track( 'resourceloader.exception', { exception: e, source: 'store-localstorage-update' } );
-                                                       }
-
-                                                       hasPendingWrite = false;
-                                               }
-
-                                               return function () {
-                                                       if ( !hasPendingWrite ) {
-                                                               hasPendingWrite = true;
-                                                               mw.requestIdleCallback( flushWrites );
-                                                       }
-                                               };
-                                       }() )
-                               }
-                       };
-               }() ),
-
-               /**
-                * HTML construction helper functions
-                *
-                *     @example
-                *
-                *     var Html, output;
-                *
-                *     Html = mw.html;
-                *     output = Html.element( 'div', {}, new Html.Raw(
-                *         Html.element( 'img', { src: '<' } )
-                *     ) );
-                *     mw.log( output ); // <div><img src="&lt;"/></div>
-                *
-                * @class mw.html
-                * @singleton
-                */
-               html: ( function () {
-                       function escapeCallback( s ) {
-                               switch ( s ) {
-                                       case '\'':
-                                               return '&#039;';
-                                       case '"':
-                                               return '&quot;';
-                                       case '<':
-                                               return '&lt;';
-                                       case '>':
-                                               return '&gt;';
-                                       case '&':
-                                               return '&amp;';
-                               }
-                       }
-
-                       return {
-                               /**
-                                * Escape a string for HTML.
-                                *
-                                * Converts special characters to HTML entities.
-                                *
-                                *     mw.html.escape( '< > \' & "' );
-                                *     // Returns &lt; &gt; &#039; &amp; &quot;
-                                *
-                                * @param {string} s The string to escape
-                                * @return {string} HTML
-                                */
-                               escape: function ( s ) {
-                                       return s.replace( /['"<>&]/g, escapeCallback );
-                               },
-
-                               /**
-                                * Create an HTML element string, with safe escaping.
-                                *
-                                * @param {string} name The tag name.
-                                * @param {Object} [attrs] An object with members mapping element names to values
-                                * @param {string|mw.html.Raw|mw.html.Cdata|null} [contents=null] The contents of the element.
-                                *
-                                *  - string: Text to be escaped.
-                                *  - null: The element is treated as void with short closing form, e.g. `<br/>`.
-                                *  - this.Raw: The raw value is directly included.
-                                *  - this.Cdata: The raw value is directly included. An exception is
-                                *    thrown if it contains any illegal ETAGO delimiter.
-                                *    See <https://www.w3.org/TR/html401/appendix/notes.html#h-B.3.2>.
-                                * @return {string} HTML
-                                */
-                               element: function ( name, attrs, contents ) {
-                                       var v, attrName, s = '<' + name;
-
-                                       if ( attrs ) {
-                                               for ( attrName in attrs ) {
-                                                       v = attrs[ attrName ];
-                                                       // Convert name=true, to name=name
-                                                       if ( v === true ) {
-                                                               v = attrName;
-                                                       // Skip name=false
-                                                       } else if ( v === false ) {
-                                                               continue;
-                                                       }
-                                                       s += ' ' + attrName + '="' + this.escape( String( v ) ) + '"';
-                                               }
-                                       }
-                                       if ( contents === undefined || contents === null ) {
-                                               // Self close tag
-                                               s += '/>';
-                                               return s;
-                                       }
-                                       // Regular open tag
-                                       s += '>';
-                                       switch ( typeof contents ) {
-                                               case 'string':
-                                                       // Escaped
-                                                       s += this.escape( contents );
-                                                       break;
-                                               case 'number':
-                                               case 'boolean':
-                                                       // Convert to string
-                                                       s += String( contents );
-                                                       break;
-                                               default:
-                                                       if ( contents instanceof this.Raw ) {
-                                                               // Raw HTML inclusion
-                                                               s += contents.value;
-                                                       } else if ( contents instanceof this.Cdata ) {
-                                                               // CDATA
-                                                               if ( /<\/[a-zA-z]/.test( contents.value ) ) {
-                                                                       throw new Error( 'mw.html.element: Illegal end tag found in CDATA' );
-                                                               }
-                                                               s += contents.value;
-                                                       } else {
-                                                               throw new Error( 'mw.html.element: Invalid type of contents' );
-                                                       }
-                                       }
-                                       s += '</' + name + '>';
-                                       return s;
-                               },
-
-                               /**
-                                * Wrapper object for raw HTML passed to mw.html.element().
-                                *
-                                * @class mw.html.Raw
-                                * @constructor
-                                * @param {string} value
-                                */
-                               Raw: function ( value ) {
-                                       this.value = value;
-                               },
-
-                               /**
-                                * Wrapper object for CDATA element contents passed to mw.html.element()
-                                *
-                                * @class mw.html.Cdata
-                                * @constructor
-                                * @param {string} value
-                                */
-                               Cdata: function ( value ) {
-                                       this.value = value;
-                               }
-                       };
-               }() ),
-
-               // Skeleton user object, extended by the 'mediawiki.user' module.
-               /**
-                * @class mw.user
-                * @singleton
-                */
-               user: {
-                       /**
-                        * @property {mw.Map}
-                        */
-                       options: new Map(),
-                       /**
-                        * @property {mw.Map}
-                        */
-                       tokens: new Map()
-               },
-
-               // OOUI widgets specific to MediaWiki
-               widgets: {},
-
-               /**
-                * Registry and firing of events.
-                *
-                * MediaWiki has various interface components that are extended, enhanced
-                * or manipulated in some other way by extensions, gadgets and even
-                * in core itself.
-                *
-                * This framework helps streamlining the timing of when these other
-                * code paths fire their plugins (instead of using document-ready,
-                * which can and should be limited to firing only once).
-                *
-                * Features like navigating to other wiki pages, previewing an edit
-                * and editing itself – without a refresh – can then retrigger these
-                * hooks accordingly to ensure everything still works as expected.
-                *
-                * Example usage:
-                *
-                *     mw.hook( 'wikipage.content' ).add( fn ).remove( fn );
-                *     mw.hook( 'wikipage.content' ).fire( $content );
-                *
-                * Handlers can be added and fired for arbitrary event names at any time. The same
-                * event can be fired multiple times. The last run of an event is memorized
-                * (similar to `$(document).ready` and `$.Deferred().done`).
-                * This means if an event is fired, and a handler added afterwards, the added
-                * function will be fired right away with the last given event data.
-                *
-                * Like Deferreds and Promises, the mw.hook object is both detachable and chainable.
-                * Thus allowing flexible use and optimal maintainability and authority control.
-                * You can pass around the `add` and/or `fire` method to another piece of code
-                * without it having to know the event name (or `mw.hook` for that matter).
-                *
-                *     var h = mw.hook( 'bar.ready' );
-                *     new mw.Foo( .. ).fetch( { callback: h.fire } );
-                *
-                * Note: Events are documented with an underscore instead of a dot in the event
-                * name due to jsduck not supporting dots in that position.
-                *
-                * @class mw.hook
-                */
-               hook: ( function () {
-                       var lists = {};
-
-                       /**
-                        * Create an instance of mw.hook.
-                        *
-                        * @method hook
-                        * @member mw
-                        * @param {string} name Name of hook.
-                        * @return {mw.hook}
-                        */
-                       return function ( name ) {
-                               var list = hasOwn.call( lists, name ) ?
-                                       lists[ name ] :
-                                       lists[ name ] = $.Callbacks( 'memory' );
-
-                               return {
-                                       /**
-                                        * Register a hook handler
-                                        *
-                                        * @param {...Function} handler Function to bind.
-                                        * @chainable
-                                        */
-                                       add: list.add,
-
-                                       /**
-                                        * Unregister a hook handler
-                                        *
-                                        * @param {...Function} handler Function to unbind.
-                                        * @chainable
-                                        */
-                                       remove: list.remove,
-
-                                       // eslint-disable-next-line valid-jsdoc
-                                       /**
-                                        * Run a hook.
-                                        *
-                                        * @param {...Mixed} data
-                                        * @chainable
-                                        */
-                                       fire: function () {
-                                               return list.fireWith.call( this, null, slice.call( arguments ) );
-                                       }
-                               };
-                       };
-               }() )
-       };
-
-       // Alias $j to jQuery for backwards compatibility
-       // @deprecated since 1.23 Use $ or jQuery instead
-       mw.log.deprecate( window, '$j', $, 'Use $ or jQuery instead.' );
-
-       /**
-        * Log a message to window.console, if possible.
-        *
-        * Useful to force logging of some errors that are otherwise hard to detect (i.e., this logs
-        * also in production mode). Gets console references in each invocation instead of caching the
-        * reference, so that debugging tools loaded later are supported (e.g. Firebug Lite in IE).
-        *
-        * @private
-        * @param {string} topic Stream name passed by mw.track
-        * @param {Object} data Data passed by mw.track
-        * @param {Error} [data.exception]
-        * @param {string} data.source Error source
-        * @param {string} [data.module] Name of module which caused the error
-        */
-       function logError( topic, data ) {
-               /* eslint-disable no-console */
-               var msg,
-                       e = data.exception,
-                       source = data.source,
-                       module = data.module,
-                       console = window.console;
-
-               if ( console && console.log ) {
-                       msg = ( e ? 'Exception' : 'Error' ) + ' in ' + source;
-                       if ( module ) {
-                               msg += ' in module ' + module;
-                       }
-                       msg += ( e ? ':' : '.' );
-                       console.log( msg );
-
-                       // If we have an exception object, log it to the warning channel to trigger
-                       // proper stacktraces in browsers that support it.
-                       if ( e && console.warn ) {
-                               console.warn( e );
-                       }
-               }
-               /* eslint-enable no-console */
-       }
-
-       // Subscribe to error streams
-       mw.trackSubscribe( 'resourceloader.exception', logError );
-       mw.trackSubscribe( 'resourceloader.assert', logError );
-
-       // Attach to window and globally alias
-       window.mw = window.mediaWiki = mw;
-}( jQuery ) );
diff --git a/resources/src/mediawiki/mediawiki.log.js b/resources/src/mediawiki/mediawiki.log.js
deleted file mode 100644 (file)
index a3f3c68..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-/*!
- * This file is concatenated to mediawiki.js in debug mode.
- *
- * See Resources.php.
- *
- * @author Michael Dale <mdale@wikimedia.org>
- * @author Trevor Parscal <tparscal@wikimedia.org>
- */
-( function ( mw ) {
-       /* global console */
-       /* eslint-disable no-console */
-       var original = mw.log;
-
-       // Replace the mw.log() no-op defined in mediawiki.js, with
-       // a function that logs to console.log (if available).
-       if ( window.console && console.log && console.log.apply ) {
-               mw.log = function () {
-                       console.log.apply( console, arguments );
-               };
-               // Re-attach original sub methods
-               mw.log.warn = original.warn;
-               mw.log.error = original.error;
-               mw.log.deprecate = original.deprecate;
-       }
-}( mediaWiki ) );
diff --git a/resources/src/mediawiki/mediawiki.requestIdleCallback.js b/resources/src/mediawiki/mediawiki.requestIdleCallback.js
deleted file mode 100644 (file)
index 650092b..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-( function ( mw ) {
-       var maxBusy = 50;
-
-       mw.requestIdleCallbackInternal = function ( callback ) {
-               setTimeout( function () {
-                       var start = mw.now();
-                       callback( {
-                               didTimeout: false,
-                               timeRemaining: function () {
-                                       return Math.max( 0, maxBusy - ( mw.now() - start ) );
-                               }
-                       } );
-               }, 1 );
-       };
-
-       /**
-        * Schedule a deferred task to run in the background.
-        *
-        * This allows code to perform tasks in the main thread without impacting
-        * time-critical operations such as animations and response to input events.
-        *
-        * Basic logic is as follows:
-        *
-        * - User input event should be acknowledged within 100ms per [RAIL].
-        * - Idle work should be grouped in blocks of upto 50ms so that enough time
-        *   remains for the event handler to execute and any rendering to take place.
-        * - Whenever a native event happens (e.g. user input), the deadline for any
-        *   running idle callback drops to 0.
-        * - As long as the deadline is non-zero, other callbacks pending may be
-        *   executed in the same idle period.
-        *
-        * See also:
-        *
-        * - <https://developer.mozilla.org/en-US/docs/Web/API/Window/requestIdleCallback>
-        * - <https://w3c.github.io/requestidlecallback/>
-        * - <https://developers.google.com/web/updates/2015/08/using-requestidlecallback>
-        * [RAIL]: https://developers.google.com/web/fundamentals/performance/rail
-        *
-        * @member mw
-        * @param {Function} callback
-        * @param {Object} [options]
-        * @param {number} [options.timeout] If set, the callback will be scheduled for
-        *  immediate execution after this amount of time (in milliseconds) if it didn't run
-        *  by that time.
-        */
-       mw.requestIdleCallback = window.requestIdleCallback ?
-               window.requestIdleCallback.bind( window ) : // Bind because it throws TypeError if context is not window
-               mw.requestIdleCallbackInternal;
-       // Note: Polyfill was previously disabled due to
-       // https://bugs.chromium.org/p/chromium/issues/detail?id=647870
-       // See also <http://codepen.io/Krinkle/full/XNGEvv>
-}( mediaWiki ) );
diff --git a/resources/src/startup.js b/resources/src/startup.js
deleted file mode 100644 (file)
index 41bcbaa..0000000
+++ /dev/null
@@ -1,164 +0,0 @@
-/**
- * This file is where we decide whether to initialise the Grade A run-time.
- *
- * - Beware: This file MUST parse without errors on even the most ancient of browsers!
- * - Beware: Do not call mwNow before the isCompatible() check.
- */
-
-/* global mw, mwNow, isCompatible, $VARS, $CODE */
-
-// Define now() here to ensure valid comparison with mediaWikiLoadEnd (T153819).
-window.mwNow = ( function () {
-       var perf = window.performance,
-               navStart = perf && perf.timing && perf.timing.navigationStart;
-       return navStart && typeof perf.now === 'function' ?
-               function () { return navStart + perf.now(); } :
-               function () { return Date.now(); };
-}() );
-
-/**
- * See <https://www.mediawiki.org/wiki/Compatibility#Browsers>
- *
- * Capabilities required for modern run-time:
- * - ECMAScript 5
- * - DOM Level 4 & Selectors API Level 1
- * - HTML5 & Web Storage
- * - DOM Level 2 Events
- *
- * Browsers we support in our modern run-time (Grade A):
- * - Chrome 13+
- * - IE 11+
- * - Firefox 4+
- * - Safari 5+
- * - Opera 15+
- * - Mobile Safari 6.0+ (iOS 6+)
- * - Android 4.1+
- *
- * Browsers we support in our no-javascript run-time (Grade C):
- * - Chrome 1+
- * - IE 6+
- * - Firefox 3+
- * - Safari 3+
- * - Opera 15+
- * - Mobile Safari 5.0+ (iOS 4+)
- * - Android 2.0+
- * - WebOS < 1.5
- * - PlayStation
- * - Symbian-based browsers
- * - NetFront-based browser
- * - Opera Mini
- * - Nokia's Ovi Browser
- * - MeeGo's browser
- * - Google Glass
- * - UC Mini (speed mode on)
- *
- * Other browsers that pass the check are considered Grade X.
- *
- * @param {string} [str] User agent, defaults to navigator.userAgent
- * @return {boolean} User agent is compatible with MediaWiki JS
- */
-window.isCompatible = function ( str ) {
-       var ua = str || navigator.userAgent;
-       return !!(
-               // https://caniuse.com/#feat=es5
-               // https://caniuse.com/#feat=use-strict
-               // https://caniuse.com/#feat=json / https://phabricator.wikimedia.org/T141344#2784065
-               ( function () {
-                       'use strict';
-                       return !this && !!Function.prototype.bind && !!window.JSON;
-               }() ) &&
-
-               // https://caniuse.com/#feat=queryselector
-               'querySelector' in document &&
-
-               // https://caniuse.com/#feat=namevalue-storage
-               // https://developer.blackberry.com/html5/apis/v1_0/localstorage.html
-               // https://blog.whatwg.org/this-week-in-html-5-episode-30
-               'localStorage' in window &&
-
-               // https://caniuse.com/#feat=addeventlistener
-               'addEventListener' in window &&
-
-               // Hardcoded exceptions for browsers that pass the requirement but we don't want to
-               // support in the modern run-time.
-               // Note: Please extend the regex instead of adding new ones
-               !(
-                       ua.match( /MSIE 10|webOS\/1\.[0-4]|SymbianOS|Series60|NetFront|Opera Mini|S40OviBrowser|MeeGo|Android.+Glass|^Mozilla\/5\.0 .+ Gecko\/$|googleweblight/ ) ||
-                       ua.match( /PlayStation/i )
-               )
-       );
-};
-
-// Conditional script injection
-( function () {
-       var NORLQ, script;
-       if ( !isCompatible() ) {
-               // Undo class swapping in case of an unsupported browser.
-               // See ResourceLoaderClientHtml::getDocumentAttributes().
-               document.documentElement.className = document.documentElement.className
-                       .replace( /(^|\s)client-js(\s|$)/, '$1client-nojs$2' );
-
-               NORLQ = window.NORLQ || [];
-               while ( NORLQ.length ) {
-                       NORLQ.shift()();
-               }
-               window.NORLQ = {
-                       push: function ( fn ) {
-                               fn();
-                       }
-               };
-
-               // Clear and disable the other queue
-               window.RLQ = {
-                       // No-op
-                       push: function () {}
-               };
-
-               return;
-       }
-
-       /**
-        * The $CODE and $VARS placeholders are substituted in ResourceLoaderStartUpModule.php.
-        */
-       function startUp() {
-               mw.config = new mw.Map( $VARS.wgLegacyJavaScriptGlobals );
-
-               $CODE.registrations();
-
-               mw.config.set( $VARS.configuration );
-
-               // Must be after mw.config.set because these callbacks may use mw.loader which
-               // needs to have values 'skin', 'debug' etc. from mw.config.
-               // eslint-disable-next-line vars-on-top
-               var RLQ = window.RLQ || [];
-               while ( RLQ.length ) {
-                       RLQ.shift()();
-               }
-               window.RLQ = {
-                       push: function ( fn ) {
-                               fn();
-                       }
-               };
-
-               // Clear and disable the other queue
-               window.NORLQ = {
-                       // No-op
-                       push: function () {}
-               };
-       }
-
-       window.mediaWikiLoadStart = mwNow();
-       if ( window.performance && performance.mark ) {
-               performance.mark( 'mwStartup' );
-       }
-       script = document.createElement( 'script' );
-       script.src = $VARS.baseModulesUri;
-       script.onload = function () {
-               // Clean up
-               script.onload = null;
-               script = null;
-               // Callback
-               startUp();
-       };
-       document.head.appendChild( script );
-}() );
diff --git a/resources/src/startup/mediawiki.js b/resources/src/startup/mediawiki.js
new file mode 100644 (file)
index 0000000..8d42c0f
--- /dev/null
@@ -0,0 +1,2273 @@
+/**
+ * Base library for MediaWiki.
+ *
+ * Exposed globally as `mediaWiki` with `mw` as shortcut.
+ *
+ * @class mw
+ * @alternateClassName mediaWiki
+ * @singleton
+ */
+
+( function () {
+       'use strict';
+
+       var mw, StringSet, log,
+               hasOwn = Object.prototype.hasOwnProperty,
+               trackQueue = [];
+
+       /**
+        * FNV132 hash function
+        *
+        * This function implements the 32-bit version of FNV-1.
+        * It is equivalent to hash( 'fnv132', ... ) in PHP, except
+        * its output is base 36 rather than hex.
+        * See <https://en.wikipedia.org/wiki/FNV_hash_function>
+        *
+        * @private
+        * @param {string} str String to hash
+        * @return {string} hash as an seven-character base 36 string
+        */
+       function fnv132( str ) {
+               /* eslint-disable no-bitwise */
+               var hash = 0x811C9DC5,
+                       i;
+
+               for ( i = 0; i < str.length; i++ ) {
+                       hash += ( hash << 1 ) + ( hash << 4 ) + ( hash << 7 ) + ( hash << 8 ) + ( hash << 24 );
+                       hash ^= str.charCodeAt( i );
+               }
+
+               hash = ( hash >>> 0 ).toString( 36 );
+               while ( hash.length < 7 ) {
+                       hash = '0' + hash;
+               }
+
+               return hash;
+               /* eslint-enable no-bitwise */
+       }
+
+       function defineFallbacks() {
+               // <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set>
+               StringSet = window.Set || ( function () {
+                       /**
+                        * @private
+                        * @class
+                        */
+                       function StringSet() {
+                               this.set = {};
+                       }
+                       StringSet.prototype.add = function ( value ) {
+                               this.set[ value ] = true;
+                       };
+                       StringSet.prototype.has = function ( value ) {
+                               return hasOwn.call( this.set, value );
+                       };
+                       return StringSet;
+               }() );
+       }
+
+       /**
+        * Alias property to the global object.
+        *
+        * @private
+        * @static
+        * @member mw.Map
+        * @param {mw.Map} map
+        * @param {string} key
+        * @param {Mixed} value
+        */
+       function setGlobalMapValue( map, key, value ) {
+               map.values[ key ] = value;
+               log.deprecate(
+                       window,
+                       key,
+                       value,
+                       // Deprecation notice for mw.config globals (T58550, T72470)
+                       map === mw.config && 'Use mw.config instead.'
+               );
+       }
+
+       /**
+        * Log a message to window.console, if possible.
+        *
+        * Useful to force logging of some errors that are otherwise hard to detect (i.e., this logs
+        * also in production mode). Gets console references in each invocation instead of caching the
+        * reference, so that debugging tools loaded later are supported (e.g. Firebug Lite in IE).
+        *
+        * @private
+        * @param {string} topic Stream name passed by mw.track
+        * @param {Object} data Data passed by mw.track
+        * @param {Error} [data.exception]
+        * @param {string} data.source Error source
+        * @param {string} [data.module] Name of module which caused the error
+        */
+       function logError( topic, data ) {
+               /* eslint-disable no-console */
+               var msg,
+                       e = data.exception,
+                       source = data.source,
+                       module = data.module,
+                       console = window.console;
+
+               if ( console && console.log ) {
+                       msg = ( e ? 'Exception' : 'Error' ) + ' in ' + source;
+                       if ( module ) {
+                               msg += ' in module ' + module;
+                       }
+                       msg += ( e ? ':' : '.' );
+                       console.log( msg );
+
+                       // If we have an exception object, log it to the warning channel to trigger
+                       // proper stacktraces in browsers that support it.
+                       if ( e && console.warn ) {
+                               console.warn( e );
+                       }
+               }
+               /* eslint-enable no-console */
+       }
+
+       /**
+        * Create an object that can be read from or written to via methods that allow
+        * interaction both with single and multiple properties at once.
+        *
+        * @private
+        * @class mw.Map
+        *
+        * @constructor
+        * @param {boolean} [global=false] Whether to synchronise =values to the global
+        *  window object (for backwards-compatibility with mw.config; T72470). Values are
+        *  copied in one direction only. Changes to globals do not reflect in the map.
+        */
+       function Map( global ) {
+               this.values = {};
+               if ( global === true ) {
+                       // Override #set to also set the global variable
+                       this.set = function ( selection, value ) {
+                               var s;
+                               if ( arguments.length > 1 ) {
+                                       if ( typeof selection !== 'string' ) {
+                                               return false;
+                                       }
+                                       setGlobalMapValue( this, selection, value );
+                                       return true;
+                               }
+                               if ( typeof selection === 'object' ) {
+                                       for ( s in selection ) {
+                                               setGlobalMapValue( this, s, selection[ s ] );
+                                       }
+                                       return true;
+                               }
+                               return false;
+                       };
+               }
+       }
+
+       Map.prototype = {
+               constructor: Map,
+
+               /**
+                * Get the value of one or more keys.
+                *
+                * If called with no arguments, all values are returned.
+                *
+                * @param {string|Array} [selection] Key or array of keys to retrieve values for.
+                * @param {Mixed} [fallback=null] Value for keys that don't exist.
+                * @return {Mixed|Object|null} If selection was a string, returns the value,
+                *  If selection was an array, returns an object of key/values.
+                *  If no selection is passed, a new object with all key/values is returned.
+                */
+               get: function ( selection, fallback ) {
+                       var results, i;
+                       fallback = arguments.length > 1 ? fallback : null;
+
+                       if ( Array.isArray( selection ) ) {
+                               results = {};
+                               for ( i = 0; i < selection.length; i++ ) {
+                                       if ( typeof selection[ i ] === 'string' ) {
+                                               results[ selection[ i ] ] = hasOwn.call( this.values, selection[ i ] ) ?
+                                                       this.values[ selection[ i ] ] :
+                                                       fallback;
+                                       }
+                               }
+                               return results;
+                       }
+
+                       if ( typeof selection === 'string' ) {
+                               return hasOwn.call( this.values, selection ) ?
+                                       this.values[ selection ] :
+                                       fallback;
+                       }
+
+                       if ( selection === undefined ) {
+                               results = {};
+                               for ( i in this.values ) {
+                                       results[ i ] = this.values[ i ];
+                               }
+                               return results;
+                       }
+
+                       // Invalid selection key
+                       return fallback;
+               },
+
+               /**
+                * Set one or more key/value pairs.
+                *
+                * @param {string|Object} selection Key to set value for, or object mapping keys to values
+                * @param {Mixed} [value] Value to set (optional, only in use when key is a string)
+                * @return {boolean} True on success, false on failure
+                */
+               set: function ( selection, value ) {
+                       var s;
+                       // Use `arguments.length` because `undefined` is also a valid value.
+                       if ( arguments.length > 1 ) {
+                               if ( typeof selection !== 'string' ) {
+                                       return false;
+                               }
+                               this.values[ selection ] = value;
+                               return true;
+                       }
+                       if ( typeof selection === 'object' ) {
+                               for ( s in selection ) {
+                                       this.values[ s ] = selection[ s ];
+                               }
+                               return true;
+                       }
+                       return false;
+               },
+
+               /**
+                * Check if one or more keys exist.
+                *
+                * @param {Mixed} selection Key or array of keys to check
+                * @return {boolean} True if the key(s) exist
+                */
+               exists: function ( selection ) {
+                       var i;
+                       if ( Array.isArray( selection ) ) {
+                               for ( i = 0; i < selection.length; i++ ) {
+                                       if ( typeof selection[ i ] !== 'string' || !hasOwn.call( this.values, selection[ i ] ) ) {
+                                               return false;
+                                       }
+                               }
+                               return true;
+                       }
+                       return typeof selection === 'string' && hasOwn.call( this.values, selection );
+               }
+       };
+
+       defineFallbacks();
+
+       /* eslint-disable no-console */
+       log = ( function () {
+               /**
+                * Write a verbose message to the browser's console in debug mode.
+                *
+                * This method is mainly intended for verbose logging. It is a no-op in production mode.
+                * In ResourceLoader debug mode, it will use the browser's console if available, with
+                * fallback to creating a console interface in the DOM and logging messages there.
+                *
+                * See {@link mw.log} for other logging methods.
+                *
+                * @member mw
+                * @param {...string} msg Messages to output to console.
+                */
+               var log = function () {},
+                       console = window.console;
+
+               // Note: Keep list of methods in sync with restoration in mediawiki.log.js
+               // when adding or removing mw.log methods below!
+
+               /**
+                * Collection of methods to help log messages to the console.
+                *
+                * @class mw.log
+                * @singleton
+                */
+
+               /**
+                * Write a message to the browser console's warning channel.
+                *
+                * This method is a no-op in browsers that don't implement the Console API.
+                *
+                * @param {...string} msg Messages to output to console
+                */
+               log.warn = console && console.warn && Function.prototype.bind ?
+                       Function.prototype.bind.call( console.warn, console ) :
+                       function () {};
+
+               /**
+                * Write a message to the browser console's error channel.
+                *
+                * Most browsers also print a stacktrace when calling this method if the
+                * argument is an Error object.
+                *
+                * This method is a no-op in browsers that don't implement the Console API.
+                *
+                * @since 1.26
+                * @param {...Mixed} msg Messages to output to console
+                */
+               log.error = console && console.error && Function.prototype.bind ?
+                       Function.prototype.bind.call( console.error, console ) :
+                       function () {};
+
+               /**
+                * Create a property on a host object that, when accessed, will produce
+                * a deprecation warning in the console.
+                *
+                * @param {Object} obj Host object of deprecated property
+                * @param {string} key Name of property to create in `obj`
+                * @param {Mixed} val The value this property should return when accessed
+                * @param {string} [msg] Optional text to include in the deprecation message
+                * @param {string} [logName=key] Optional custom name for the feature.
+                *  This is used instead of `key` in the message and `mw.deprecate` tracking.
+                */
+               log.deprecate = !Object.defineProperty ? function ( obj, key, val ) {
+                       obj[ key ] = val;
+               } : function ( obj, key, val, msg, logName ) {
+                       var logged = new StringSet();
+                       logName = logName || key;
+                       msg = 'Use of "' + logName + '" is deprecated.' + ( msg ? ( ' ' + msg ) : '' );
+                       function uniqueTrace() {
+                               var trace = new Error().stack;
+                               if ( logged.has( trace ) ) {
+                                       return false;
+                               }
+                               logged.add( trace );
+                               return true;
+                       }
+                       // Support: Safari 5.0
+                       // Throws "not supported on DOM Objects" for Node or Element objects (incl. document)
+                       // Safari 4.0 doesn't have this method, and it was fixed in Safari 5.1.
+                       try {
+                               Object.defineProperty( obj, key, {
+                                       configurable: true,
+                                       enumerable: true,
+                                       get: function () {
+                                               if ( uniqueTrace() ) {
+                                                       mw.track( 'mw.deprecate', logName );
+                                                       mw.log.warn( msg );
+                                               }
+                                               return val;
+                                       },
+                                       set: function ( newVal ) {
+                                               if ( uniqueTrace() ) {
+                                                       mw.track( 'mw.deprecate', logName );
+                                                       mw.log.warn( msg );
+                                               }
+                                               val = newVal;
+                                       }
+                               } );
+                       } catch ( err ) {
+                               obj[ key ] = val;
+                       }
+               };
+
+               return log;
+       }() );
+       /* eslint-enable no-console */
+
+       /**
+        * @class mw
+        */
+       mw = {
+               redefineFallbacksForTest: function () {
+                       if ( !window.QUnit ) {
+                               throw new Error( 'Reset not allowed outside unit tests' );
+                       }
+                       defineFallbacks();
+               },
+
+               /**
+                * Get the current time, measured in milliseconds since January 1, 1970 (UTC).
+                *
+                * On browsers that implement the Navigation Timing API, this function will produce floating-point
+                * values with microsecond precision that are guaranteed to be monotonic. On all other browsers,
+                * it will fall back to using `Date`.
+                *
+                * @return {number} Current time
+                */
+               now: ( function () {
+                       var perf = window.performance,
+                               navStart = perf && perf.timing && perf.timing.navigationStart;
+                       return navStart && typeof perf.now === 'function' ?
+                               function () { return navStart + perf.now(); } :
+                               function () { return Date.now(); };
+               }() ),
+
+               /**
+                * List of all analytic events emitted so far.
+                *
+                * @private
+                * @property {Array}
+                */
+               trackQueue: trackQueue,
+
+               track: function ( topic, data ) {
+                       trackQueue.push( { topic: topic, timeStamp: mw.now(), data: data } );
+                       // The base module extends this method to fire events here
+               },
+
+               /**
+                * Track an early error event via mw.track and send it to the window console.
+                *
+                * @private
+                * @param {string} topic Topic name
+                * @param {Object} data Data describing the event, encoded as an object; see mw#logError
+                */
+               trackError: function ( topic, data ) {
+                       mw.track( topic, data );
+                       logError( topic, data );
+               },
+
+               // Expose Map constructor
+               Map: Map,
+
+               /**
+                * Map of configuration values.
+                *
+                * Check out [the complete list of configuration values](https://www.mediawiki.org/wiki/Manual:Interface/JavaScript#mw.config)
+                * on mediawiki.org.
+                *
+                * If `$wgLegacyJavaScriptGlobals` is true, this Map will add its values to the
+                * global `window` object.
+                *
+                * @property {mw.Map} config
+                */
+               // Dummy placeholder later assigned in ResourceLoaderStartUpModule
+               config: null,
+
+               /**
+                * Empty object for third-party libraries, for cases where you don't
+                * want to add a new global, or the global is bad and needs containment
+                * or wrapping.
+                *
+                * @property
+                */
+               libs: {},
+
+               /**
+                * Access container for deprecated functionality that can be moved from
+                * from their legacy location and attached to this object (e.g. a global
+                * function that is deprecated and as stop-gap can be exposed through here).
+                *
+                * This was reserved for future use but never ended up being used.
+                *
+                * @deprecated since 1.22 Let deprecated identifiers keep their original name
+                *  and use mw.log#deprecate to create an access container for tracking.
+                * @property
+                */
+               legacy: {},
+
+               /**
+                * Store for messages.
+                *
+                * @property {mw.Map}
+                */
+               messages: new Map(),
+
+               /**
+                * Store for templates associated with a module.
+                *
+                * @property {mw.Map}
+                */
+               templates: new Map(),
+
+               // Expose mw.log
+               log: log,
+
+               /**
+                * Client for ResourceLoader server end point.
+                *
+                * This client is in charge of maintaining the module registry and state
+                * machine, initiating network (batch) requests for loading modules, as
+                * well as dependency resolution and execution of source code.
+                *
+                * For more information, refer to
+                * <https://www.mediawiki.org/wiki/ResourceLoader/Features>
+                *
+                * @class mw.loader
+                * @singleton
+                */
+               loader: ( function () {
+
+                       /**
+                        * Fired via mw.track on various resource loading errors.
+                        *
+                        * @event resourceloader_exception
+                        * @param {Error|Mixed} e The error that was thrown. Almost always an Error
+                        *   object, but in theory module code could manually throw something else, and that
+                        *   might also end up here.
+                        * @param {string} [module] Name of the module which caused the error. Omitted if the
+                        *   error is not module-related or the module cannot be easily identified due to
+                        *   batched handling.
+                        * @param {string} source Source of the error. Possible values:
+                        *
+                        *   - style: stylesheet error (only affects old IE where a special style loading method
+                        *     is used)
+                        *   - load-callback: exception thrown by user callback
+                        *   - module-execute: exception thrown by module code
+                        *   - resolve: failed to sort dependencies for a module in mw.loader.load
+                        *   - store-eval: could not evaluate module code cached in localStorage
+                        *   - store-localstorage-init: localStorage or JSON parse error in mw.loader.store.init
+                        *   - store-localstorage-json: JSON conversion error in mw.loader.store.set
+                        *   - store-localstorage-update: localStorage or JSON conversion error in mw.loader.store.update
+                        */
+
+                       /**
+                        * Fired via mw.track on resource loading error conditions.
+                        *
+                        * @event resourceloader_assert
+                        * @param {string} source Source of the error. Possible values:
+                        *
+                        *   - bug-T59567: failed to cache script due to an Opera function -> string conversion
+                        *     bug; see <https://phabricator.wikimedia.org/T59567> for details
+                        */
+
+                       /**
+                        * Mapping of registered modules.
+                        *
+                        * See #implement and #execute for exact details on support for script, style and messages.
+                        *
+                        * Format:
+                        *
+                        *     {
+                        *         'moduleName': {
+                        *             // From mw.loader.register()
+                        *             'version': '########' (hash)
+                        *             'dependencies': ['required.foo', 'bar.also', ...]
+                        *             'group': 'somegroup', (or) null
+                        *             'source': 'local', (or) 'anotherwiki'
+                        *             'skip': 'return !!window.Example', (or) null
+                        *             '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', ... }
+                        *         }
+                        *     }
+                        *
+                        * State machine:
+                        *
+                        * - `registered`:
+                        *    The module is known to the system but not yet required.
+                        *    Meta data is registered via mw.loader#register. Calls to that method are
+                        *    generated server-side by the startup module.
+                        * - `loading`:
+                        *    The module was required through mw.loader (either directly or as dependency of
+                        *    another module). The client will fetch module contents from the server.
+                        *    The contents are then stashed in the registry via mw.loader#implement.
+                        * - `loaded`:
+                        *    The module has been loaded from the server and stashed via mw.loader#implement.
+                        *    If the module has no more dependencies in-flight, the module will be executed
+                        *    immediately. Otherwise execution is deferred, controlled via #handlePending.
+                        * - `executing`:
+                        *    The module is being executed.
+                        * - `ready`:
+                        *    The module has been successfully executed.
+                        * - `error`:
+                        *    The module (or one of its dependencies) produced an error during execution.
+                        * - `missing`:
+                        *    The module was registered client-side and requested, but the server denied knowledge
+                        *    of the module's existence.
+                        *
+                        * @property
+                        * @private
+                        */
+                       var registry = {},
+                               // Mapping of sources, keyed by source-id, values are strings.
+                               //
+                               // Format:
+                               //
+                               //     {
+                               //         'sourceId': 'http://example.org/w/load.php'
+                               //     }
+                               //
+                               sources = {},
+
+                               // For queueModuleScript()
+                               handlingPendingRequests = false,
+                               pendingRequests = [],
+
+                               // List of modules to be loaded
+                               queue = [],
+
+                               /**
+                                * List of callback jobs waiting for modules to be ready.
+                                *
+                                * Jobs are created by #enqueue() and run by #handlePending().
+                                *
+                                * Typically when a job is created for a module, the job's dependencies contain
+                                * both the required module and all its recursive dependencies.
+                                *
+                                * Format:
+                                *
+                                *     {
+                                *         'dependencies': [ module names ],
+                                *         'ready': Function callback
+                                *         'error': Function callback
+                                *     }
+                                *
+                                * @property {Object[]} jobs
+                                * @private
+                                */
+                               jobs = [],
+
+                               /**
+                                * For #addEmbeddedCSS() and #addLink()
+                                *
+                                * @private
+                                * @property {HTMLElement|null} marker
+                                */
+                               marker = document.querySelector( 'meta[name="ResourceLoaderDynamicStyles"]' ),
+
+                               // For addEmbeddedCSS()
+                               cssBuffer = '',
+                               cssBufferTimer = null,
+                               cssCallbacks = [],
+                               rAF = window.requestAnimationFrame || setTimeout;
+
+                       /**
+                        * Create a new style element and add it to the DOM.
+                        *
+                        * @private
+                        * @param {string} text CSS text
+                        * @param {Node|null} [nextNode] The element where the style tag
+                        *  should be inserted before
+                        * @return {HTMLElement} Reference to the created style element
+                        */
+                       function newStyleTag( text, nextNode ) {
+                               var el = document.createElement( 'style' );
+                               el.appendChild( document.createTextNode( text ) );
+                               if ( nextNode && nextNode.parentNode ) {
+                                       nextNode.parentNode.insertBefore( el, nextNode );
+                               } else {
+                                       document.head.appendChild( el );
+                               }
+                               return el;
+                       }
+
+                       /**
+                        * Add a bit of CSS text to the current browser page.
+                        *
+                        * The CSS will be appended to an existing ResourceLoader-created `<style>` tag
+                        * or create a new one based on whether the given `cssText` is safe for extension.
+                        *
+                        * @private
+                        * @param {string} [cssText=cssBuffer] If called without cssText,
+                        *  the internal buffer will be inserted instead.
+                        * @param {Function} [callback]
+                        */
+                       function addEmbeddedCSS( cssText, callback ) {
+                               function fireCallbacks() {
+                                       var i,
+                                               oldCallbacks = cssCallbacks;
+                                       // Reset cssCallbacks variable so it's not polluted by any calls to
+                                       // addEmbeddedCSS() from one of the callbacks (T105973)
+                                       cssCallbacks = [];
+                                       for ( i = 0; i < oldCallbacks.length; i++ ) {
+                                               oldCallbacks[ i ]();
+                                       }
+                               }
+
+                               if ( callback ) {
+                                       cssCallbacks.push( callback );
+                               }
+
+                               // Yield once before creating the <style> tag. This lets multiple stylesheets
+                               // accumulate into one buffer, allowing us to reduce how often new stylesheets
+                               // are inserted in the browser. Appending a stylesheet and waiting for the
+                               // browser to repaint is fairly expensive. (T47810)
+                               if ( cssText ) {
+                                       // Don't extend the buffer if the item needs its own stylesheet.
+                                       // Keywords like `@import` are only valid at the start of a stylesheet (T37562).
+                                       if ( !cssBuffer || cssText.slice( 0, '@import'.length ) !== '@import' ) {
+                                               // Linebreak for somewhat distinguishable sections
+                                               cssBuffer += '\n' + cssText;
+                                               if ( !cssBufferTimer ) {
+                                                       cssBufferTimer = rAF( function () {
+                                                               // Wrap in anonymous function that takes no arguments
+                                                               // Support: Firefox < 13
+                                                               // Firefox 12 has non-standard behaviour of passing a number
+                                                               // as first argument to a setTimeout callback.
+                                                               // http://benalman.com/news/2009/07/the-mysterious-firefox-settime/
+                                                               addEmbeddedCSS();
+                                                       } );
+                                               }
+                                               return;
+                                       }
+
+                               // This is a scheduled flush for the buffer
+                               } else {
+                                       cssBufferTimer = null;
+                                       cssText = cssBuffer;
+                                       cssBuffer = '';
+                               }
+
+                               newStyleTag( cssText, marker );
+
+                               fireCallbacks();
+                       }
+
+                       /**
+                        * @private
+                        * @param {Array} modules List of module names
+                        * @return {string} Hash of concatenated version hashes.
+                        */
+                       function getCombinedVersion( modules ) {
+                               var hashes = modules.map( function ( module ) {
+                                       return registry[ module ].version;
+                               } );
+                               return fnv132( hashes.join( '' ) );
+                       }
+
+                       /**
+                        * Determine whether all dependencies are in state 'ready', which means we may
+                        * execute the module or job now.
+                        *
+                        * @private
+                        * @param {Array} 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++ ) {
+                                       if ( mw.loader.getState( modules[ i ] ) !== 'ready' ) {
+                                               return false;
+                                       }
+                               }
+                               return true;
+                       }
+
+                       /**
+                        * Determine whether all dependencies are in state 'ready', which means we may
+                        * execute the module or job now.
+                        *
+                        * @private
+                        * @param {Array} modules Names of modules to be checked
+                        * @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++ ) {
+                                       state = mw.loader.getState( modules[ i ] );
+                                       if ( state === 'error' || state === 'missing' ) {
+                                               return true;
+                                       }
+                               }
+                               return false;
+                       }
+
+                       /**
+                        * A module has entered state 'ready', 'error', or 'missing'. Automatically update
+                        * pending jobs and modules that depend upon this module. If the given module failed,
+                        * propagate the 'error' state up the dependency tree. Otherwise, go ahead and execute
+                        * all jobs/modules now having their dependencies satisfied.
+                        *
+                        * Jobs that depend on a failed module, will have their error callback ran (if any).
+                        *
+                        * @private
+                        * @param {string} module Name of module that entered one of the states 'ready', 'error', or 'missing'.
+                        */
+                       function handlePending( module ) {
+                               var j, job, hasErrors, m, stateChange;
+
+                               if ( registry[ module ].state === 'error' || registry[ module ].state === 'missing' ) {
+                                       // If the current module failed, mark all dependent modules also as failed.
+                                       // Iterate until steady-state to propagate the error state upwards in the
+                                       // dependency tree.
+                                       do {
+                                               stateChange = false;
+                                               for ( m in registry ) {
+                                                       if ( registry[ m ].state !== 'error' && registry[ m ].state !== 'missing' ) {
+                                                               if ( anyFailed( registry[ m ].dependencies ) ) {
+                                                                       registry[ m ].state = 'error';
+                                                                       stateChange = true;
+                                                               }
+                                                       }
+                                               }
+                                       } while ( stateChange );
+                               }
+
+                               // Execute all jobs whose dependencies are either all satisfied or contain at least one failed module.
+                               for ( j = 0; j < jobs.length; j++ ) {
+                                       hasErrors = anyFailed( jobs[ j ].dependencies );
+                                       if ( hasErrors || allReady( jobs[ j ].dependencies ) ) {
+                                               // All dependencies satisfied, or some have errors
+                                               job = jobs[ j ];
+                                               jobs.splice( j, 1 );
+                                               j -= 1;
+                                               try {
+                                                       if ( hasErrors ) {
+                                                               if ( typeof job.error === 'function' ) {
+                                                                       job.error( new Error( 'Module ' + module + ' has failed dependencies' ), [ module ] );
+                                                               }
+                                                       } else {
+                                                               if ( typeof job.ready === 'function' ) {
+                                                                       job.ready();
+                                                               }
+                                                       }
+                                               } catch ( e ) {
+                                                       // A user-defined callback raised an exception.
+                                                       // Swallow it to protect our state machine!
+                                                       mw.trackError( 'resourceloader.exception', {
+                                                               exception: e,
+                                                               module: module,
+                                                               source: 'load-callback'
+                                                       } );
+                                               }
+                                       }
+                               }
+
+                               if ( registry[ module ].state === 'ready' ) {
+                                       // The current module became 'ready'. Set it in the module store, and recursively execute all
+                                       // dependent modules that are loaded and now have all dependencies satisfied.
+                                       mw.loader.store.set( module, registry[ module ] );
+                                       for ( m in registry ) {
+                                               if ( registry[ m ].state === 'loaded' && allReady( registry[ m ].dependencies ) ) {
+                                                       // eslint-disable-next-line no-use-before-define
+                                                       execute( m );
+                                               }
+                                       }
+                               }
+                       }
+
+                       /**
+                        * Resolve dependencies and detect circular references.
+                        *
+                        * @private
+                        * @param {string} module Name of the top-level module whose dependencies shall be
+                        *  resolved and sorted.
+                        * @param {Array} resolved Returns a topological sort of the given module and its
+                        *  dependencies, such that later modules depend on earlier modules. The array
+                        *  contains the module names. If the array contains already some module names,
+                        *  this function appends its result to the pre-existing array.
+                        * @param {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
+                        */
+                       function sortDependencies( module, resolved, unresolved ) {
+                               var i, deps, skip;
+
+                               if ( !hasOwn.call( registry, module ) ) {
+                                       throw new Error( 'Unknown dependency: ' + module );
+                               }
+
+                               if ( registry[ module ].skip !== null ) {
+                                       // eslint-disable-next-line no-new-func
+                                       skip = new Function( registry[ module ].skip );
+                                       registry[ module ].skip = null;
+                                       if ( skip() ) {
+                                               registry[ module ].skipped = true;
+                                               registry[ module ].dependencies = [];
+                                               registry[ module ].state = 'ready';
+                                               handlePending( module );
+                                               return;
+                                       }
+                               }
+
+                               if ( resolved.indexOf( module ) !== -1 ) {
+                                       // Module already resolved; nothing to do
+                                       return;
+                               }
+                               // Create unresolved if not passed in
+                               if ( !unresolved ) {
+                                       unresolved = new StringSet();
+                               }
+                               // Tracks down dependencies
+                               deps = registry[ module ].dependencies;
+                               for ( i = 0; i < deps.length; i++ ) {
+                                       if ( resolved.indexOf( deps[ i ] ) === -1 ) {
+                                               if ( unresolved.has( deps[ i ] ) ) {
+                                                       throw new Error(
+                                                               'Circular reference detected: ' + module + ' -> ' + deps[ i ]
+                                                       );
+                                               }
+
+                                               unresolved.add( module );
+                                               sortDependencies( deps[ i ], resolved, unresolved );
+                                       }
+                               }
+                               resolved.push( module );
+                       }
+
+                       /**
+                        * Get names of module that a module depends on, in their proper dependency order.
+                        *
+                        * @private
+                        * @param {string[]} modules Array of string module names
+                        * @return {Array} List of dependencies, including 'module'.
+                        * @throws {Error} If an unregistered module or a dependency loop is encountered
+                        */
+                       function resolve( modules ) {
+                               var i, resolved = [];
+                               for ( i = 0; i < modules.length; i++ ) {
+                                       sortDependencies( modules[ i ], resolved );
+                               }
+                               return resolved;
+                       }
+
+                       /**
+                        * Like #resolve(), except it will silently ignore modules that
+                        * are missing or have missing dependencies.
+                        *
+                        * @private
+                        * @param {string[]} modules Array of string module names
+                        * @return {Array} List of dependencies.
+                        */
+                       function resolveStubbornly( modules ) {
+                               var i, saved, resolved = [];
+                               for ( i = 0; i < modules.length; i++ ) {
+                                       saved = resolved.slice();
+                                       try {
+                                               sortDependencies( modules[ i ], resolved );
+                                       } catch ( err ) {
+                                               // This module is unknown or has unknown dependencies.
+                                               // Undo any incomplete resolutions made and keep going.
+                                               resolved = saved;
+                                               mw.trackError( 'resourceloader.exception', {
+                                                       exception: err,
+                                                       source: 'resolve'
+                                               } );
+                                       }
+                               }
+                               return resolved;
+                       }
+
+                       /**
+                        * Load and execute a script.
+                        *
+                        * @private
+                        * @param {string} src URL to script, will be used as the src attribute in the script tag
+                        * @param {Function} [callback] Callback to run after request resolution
+                        */
+                       function addScript( src, callback ) {
+                               var script = document.createElement( 'script' );
+                               script.src = src;
+                               script.onload = script.onerror = function () {
+                                       if ( script.parentNode ) {
+                                               script.parentNode.removeChild( script );
+                                       }
+                                       script = null;
+                                       if ( callback ) {
+                                               callback();
+                                               callback = null;
+                                       }
+                               };
+                               document.head.appendChild( script );
+                       }
+
+                       /**
+                        * Queue the loading and execution of a script for a particular module.
+                        *
+                        * @private
+                        * @param {string} src URL of the script
+                        * @param {string} moduleName Name of currently executing module
+                        * @param {Function} callback Callback to run after addScript() resolution
+                        */
+                       function queueModuleScript( src, moduleName, callback ) {
+                               pendingRequests.push( function () {
+                                       if ( hasOwn.call( registry, moduleName ) ) {
+                                               // Emulate runScript() part of execute()
+                                               window.require = mw.loader.require;
+                                               window.module = registry[ moduleName ].module;
+                                       }
+                                       addScript( src, function () {
+                                               // 'module.exports' should not persist after the file is executed to
+                                               // avoid leakage to unrelated code. 'require' should be kept, however,
+                                               // as asynchronous access to 'require' is allowed and expected. (T144879)
+                                               delete window.module;
+                                               callback();
+                                               // Start the next one (if any)
+                                               if ( pendingRequests[ 0 ] ) {
+                                                       pendingRequests.shift()();
+                                               } else {
+                                                       handlingPendingRequests = false;
+                                               }
+                                       } );
+                               } );
+                               if ( !handlingPendingRequests && pendingRequests[ 0 ] ) {
+                                       handlingPendingRequests = true;
+                                       pendingRequests.shift()();
+                               }
+                       }
+
+                       /**
+                        * Utility function for execute()
+                        *
+                        * @ignore
+                        * @param {string} [media] Media attribute
+                        * @param {string} url URL
+                        */
+                       function addLink( media, url ) {
+                               var el = document.createElement( 'link' );
+
+                               el.rel = 'stylesheet';
+                               if ( media && media !== 'all' ) {
+                                       el.media = media;
+                               }
+                               // If you end up here from an IE exception "SCRIPT: Invalid property value.",
+                               // see #addEmbeddedCSS, T33676, T43331, and T49277 for details.
+                               el.href = url;
+
+                               if ( marker && marker.parentNode ) {
+                                       marker.parentNode.insertBefore( el, marker );
+                               } else {
+                                       document.head.appendChild( el );
+                               }
+                       }
+
+                       /**
+                        * @private
+                        * @param {string} code JavaScript code
+                        */
+                       function domEval( code ) {
+                               var script = document.createElement( 'script' );
+                               script.text = code;
+                               document.head.appendChild( script );
+                               script.parentNode.removeChild( script );
+                       }
+
+                       /**
+                        * Add one or more modules to the module load queue.
+                        *
+                        * See also #work().
+                        *
+                        * @private
+                        * @param {string|string[]} dependencies Module name or array of string module names
+                        * @param {Function} [ready] Callback to execute when all dependencies are ready
+                        * @param {Function} [error] Callback to execute when any dependency fails
+                        */
+                       function enqueue( dependencies, ready, error ) {
+                               // Allow calling by single module name
+                               if ( typeof dependencies === 'string' ) {
+                                       dependencies = [ dependencies ];
+                               }
+
+                               if ( allReady( dependencies ) ) {
+                                       // Run ready immediately
+                                       if ( ready !== undefined ) {
+                                               ready();
+                                       }
+
+                                       return;
+                               }
+
+                               if ( anyFailed( dependencies ) ) {
+                                       if ( error !== undefined ) {
+                                               // Execute error immediately if any dependencies have errors
+                                               error(
+                                                       new Error( 'One or more dependencies failed to load' ),
+                                                       dependencies
+                                               );
+                                       }
+
+                                       return;
+                               }
+
+                               // Not all dependencies are ready, add to the load queue...
+
+                               // Add ready and error callbacks if they were given
+                               if ( ready !== undefined || error !== undefined ) {
+                                       jobs.push( {
+                                               // Narrow down the list to modules that are worth waiting for
+                                               dependencies: dependencies.filter( function ( module ) {
+                                                       var state = mw.loader.getState( module );
+                                                       return state === 'registered' || state === 'loaded' || state === 'loading' || state === 'executing';
+                                               } ),
+                                               ready: ready,
+                                               error: error
+                                       } );
+                               }
+
+                               dependencies.forEach( function ( module ) {
+                                       var state = mw.loader.getState( module );
+                                       // Only queue modules that are still in the initial 'registered' state
+                                       // (not ones already loading, ready or error).
+                                       if ( state === 'registered' && queue.indexOf( module ) === -1 ) {
+                                               // Private modules must be embedded in the page. Don't bother queuing
+                                               // these as the server will deny them anyway (T101806).
+                                               if ( registry[ module ].group === 'private' ) {
+                                                       registry[ module ].state = 'error';
+                                                       handlePending( module );
+                                                       return;
+                                               }
+                                               queue.push( module );
+                                       }
+                               } );
+
+                               mw.loader.work();
+                       }
+
+                       /**
+                        * Executes a loaded module, making it ready to use
+                        *
+                        * @private
+                        * @param {string} module Module name to execute
+                        */
+                       function execute( module ) {
+                               var key, value, media, i, urls, cssHandle, checkCssHandles, runScript,
+                                       cssHandlesRegistered = false;
+
+                               if ( !hasOwn.call( registry, module ) ) {
+                                       throw new Error( 'Module has not been registered yet: ' + module );
+                               }
+                               if ( registry[ module ].state !== 'loaded' ) {
+                                       throw new Error( 'Module in state "' + registry[ module ].state + '" may not be executed: ' + module );
+                               }
+
+                               registry[ module ].state = 'executing';
+
+                               runScript = function () {
+                                       var script, markModuleReady, nestedAddScript;
+
+                                       script = registry[ module ].script;
+                                       markModuleReady = function () {
+                                               registry[ module ].state = 'ready';
+                                               handlePending( module );
+                                       };
+                                       nestedAddScript = function ( arr, callback, i ) {
+                                               // Recursively call queueModuleScript() in its own callback
+                                               // for each element of arr.
+                                               if ( i >= arr.length ) {
+                                                       // We're at the end of the array
+                                                       callback();
+                                                       return;
+                                               }
+
+                                               queueModuleScript( arr[ i ], module, function () {
+                                                       nestedAddScript( arr, callback, i + 1 );
+                                               } );
+                                       };
+
+                                       try {
+                                               if ( Array.isArray( script ) ) {
+                                                       nestedAddScript( script, markModuleReady, 0 );
+                                               } else if ( typeof script === 'function' ) {
+                                                       // Pass jQuery twice so that the signature of the closure which wraps
+                                                       // the script can bind both '$' and 'jQuery'.
+                                                       script( window.$, window.$, mw.loader.require, registry[ module ].module );
+                                                       markModuleReady();
+
+                                               } else if ( typeof script === 'string' ) {
+                                                       // Site and user modules are legacy scripts that run in the global scope.
+                                                       // This is transported as a string instead of a function to avoid needing
+                                                       // to use string manipulation to undo the function wrapper.
+                                                       domEval( script );
+                                                       markModuleReady();
+
+                                               } else {
+                                                       // Module without script
+                                                       markModuleReady();
+                                               }
+                                       } catch ( e ) {
+                                               // Use mw.track instead of mw.log because these errors are common in production mode
+                                               // (e.g. undefined variable), and mw.log is only enabled in debug mode.
+                                               registry[ module ].state = 'error';
+                                               mw.trackError( 'resourceloader.exception', {
+                                                       exception: e, module:
+                                                       module, source: 'module-execute'
+                                               } );
+                                               handlePending( module );
+                                       }
+                               };
+
+                               // Add localizations to message system
+                               if ( registry[ module ].messages ) {
+                                       mw.messages.set( registry[ module ].messages );
+                               }
+
+                               // Initialise templates
+                               if ( registry[ module ].templates ) {
+                                       mw.templates.set( module, registry[ module ].templates );
+                               }
+
+                               // Make sure we don't run the scripts until all stylesheet insertions have completed.
+                               ( function () {
+                                       var pending = 0;
+                                       checkCssHandles = function () {
+                                               var ex, dependencies;
+                                               // cssHandlesRegistered ensures we don't take off too soon, e.g. when
+                                               // one of the cssHandles is fired while we're still creating more handles.
+                                               if ( cssHandlesRegistered && pending === 0 && runScript ) {
+                                                       if ( module === 'user' ) {
+                                                               // Implicit dependency on the site module. Not real dependency because
+                                                               // it should run after 'site' regardless of whether it succeeds or fails.
+                                                               // Note: This is a simplified version of mw.loader.using(), inlined here
+                                                               // as using() depends on jQuery (T192623).
+                                                               try {
+                                                                       dependencies = resolve( [ 'site' ] );
+                                                               } catch ( e ) {
+                                                                       ex = e;
+                                                                       runScript();
+                                                               }
+                                                               if ( ex === undefined ) {
+                                                                       enqueue( dependencies, runScript, runScript );
+                                                               }
+                                                       } else {
+                                                               runScript();
+                                                       }
+                                                       runScript = undefined; // Revoke
+                                               }
+                                       };
+                                       cssHandle = function () {
+                                               var check = checkCssHandles;
+                                               pending++;
+                                               return function () {
+                                                       if ( check ) {
+                                                               pending--;
+                                                               check();
+                                                               check = undefined; // Revoke
+                                                       }
+                                               };
+                                       };
+                               }() );
+
+                               // Process styles (see also mw.loader.implement)
+                               // * back-compat: { <media>: css }
+                               // * back-compat: { <media>: [url, ..] }
+                               // * { "css": [css, ..] }
+                               // * { "url": { <media>: [url, ..] } }
+                               if ( registry[ module ].style ) {
+                                       for ( key in registry[ module ].style ) {
+                                               value = registry[ module ].style[ key ];
+                                               media = undefined;
+
+                                               if ( key !== 'url' && key !== 'css' ) {
+                                                       // Backwards compatibility, key is a media-type
+                                                       if ( typeof value === 'string' ) {
+                                                               // back-compat: { <media>: css }
+                                                               // Ignore 'media' because it isn't supported (nor was it used).
+                                                               // Strings are pre-wrapped in "@media". The media-type was just ""
+                                                               // (because it had to be set to something).
+                                                               // This is one of the reasons why this format is no longer used.
+                                                               addEmbeddedCSS( value, cssHandle() );
+                                                       } else {
+                                                               // back-compat: { <media>: [url, ..] }
+                                                               media = key;
+                                                               key = 'bc-url';
+                                                       }
+                                               }
+
+                                               // Array of css strings in key 'css',
+                                               // or back-compat array of urls from media-type
+                                               if ( Array.isArray( value ) ) {
+                                                       for ( i = 0; i < value.length; i++ ) {
+                                                               if ( key === 'bc-url' ) {
+                                                                       // back-compat: { <media>: [url, ..] }
+                                                                       addLink( media, value[ i ] );
+                                                               } else if ( key === 'css' ) {
+                                                                       // { "css": [css, ..] }
+                                                                       addEmbeddedCSS( value[ i ], cssHandle() );
+                                                               }
+                                                       }
+                                               // Not an array, but a regular object
+                                               // Array of urls inside media-type key
+                                               } else if ( typeof value === 'object' ) {
+                                                       // { "url": { <media>: [url, ..] } }
+                                                       for ( media in value ) {
+                                                               urls = value[ media ];
+                                                               for ( i = 0; i < urls.length; i++ ) {
+                                                                       addLink( media, urls[ i ] );
+                                                               }
+                                                       }
+                                               }
+                                       }
+                               }
+
+                               // Kick off.
+                               cssHandlesRegistered = true;
+                               checkCssHandles();
+                       }
+
+                       function sortQuery( o ) {
+                               var key,
+                                       sorted = {},
+                                       a = [];
+
+                               for ( key in o ) {
+                                       a.push( key );
+                               }
+                               a.sort();
+                               for ( key = 0; key < a.length; key++ ) {
+                                       sorted[ a[ key ] ] = o[ a[ key ] ];
+                               }
+                               return sorted;
+                       }
+
+                       /**
+                        * Converts a module map of the form `{ foo: [ 'bar', 'baz' ], bar: [ 'baz, 'quux' ] }`
+                        * to a query string of the form `foo.bar,baz|bar.baz,quux`.
+                        *
+                        * See `ResourceLoader::makePackedModulesString()` in PHP, of which this is a port.
+                        * On the server, unpacking is done by `ResourceLoaderContext::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
+                        * to decide when to split the requests due to url size.
+                        *
+                        * @private
+                        * @param {Object} moduleMap Module map
+                        * @return {Object}
+                        * @return {string} return.str Module query string
+                        * @return {Array} return.list List of module names in matching order
+                        */
+                       function buildModulesString( moduleMap ) {
+                               var p, prefix,
+                                       str = [],
+                                       list = [];
+
+                               function restore( suffix ) {
+                                       return p + suffix;
+                               }
+
+                               for ( prefix in moduleMap ) {
+                                       p = prefix === '' ? '' : prefix + '.';
+                                       str.push( p + moduleMap[ prefix ].join( ',' ) );
+                                       list.push.apply( list, moduleMap[ prefix ].map( restore ) );
+                               }
+                               return {
+                                       str: str.join( '|' ),
+                                       list: list
+                               };
+                       }
+
+                       /**
+                        * Resolve indexed dependencies.
+                        *
+                        * ResourceLoader uses an optimization to save space which replaces module names in
+                        * dependency lists with the index of that module within the array of module
+                        * registration data if it exists. The benefit is a significant reduction in the data
+                        * size of the startup module. This function changes those dependency lists back to
+                        * arrays of strings.
+                        *
+                        * @private
+                        * @param {Array} modules Modules array
+                        */
+                       function resolveIndexedDependencies( modules ) {
+                               var i, j, deps;
+                               function resolveIndex( dep ) {
+                                       return typeof dep === 'number' ? modules[ dep ][ 0 ] : dep;
+                               }
+                               for ( i = 0; i < modules.length; i++ ) {
+                                       deps = modules[ i ][ 2 ];
+                                       if ( deps ) {
+                                               for ( j = 0; j < deps.length; j++ ) {
+                                                       deps[ j ] = resolveIndex( deps[ j ] );
+                                               }
+                                       }
+                               }
+                       }
+
+                       /**
+                        * @private
+                        * @param {Object} params Map of parameter names to values
+                        * @return {string}
+                        */
+                       function makeQueryString( params ) {
+                               return Object.keys( params ).map( function ( key ) {
+                                       return encodeURIComponent( key ) + '=' + encodeURIComponent( params[ key ] );
+                               } ).join( '&' );
+                       }
+
+                       /**
+                        * Create network requests for a batch of modules.
+                        *
+                        * This is an internal method for #work(). This must not be called directly
+                        * unless the modules are already registered, and no request is in progress,
+                        * and the module state has already been set to `loading`.
+                        *
+                        * @private
+                        * @param {string[]} batch
+                        */
+                       function batchRequest( batch ) {
+                               var reqBase, splits, maxQueryLength, b, bSource, bGroup, bSourceGroup,
+                                       source, group, i, modules, sourceLoadScript,
+                                       currReqBase, currReqBaseLength, moduleMap, currReqModules, l,
+                                       lastDotIndex, prefix, suffix, bytesAdded;
+
+                               /**
+                                * Start the currently drafted request to the server.
+                                *
+                                * @ignore
+                                */
+                               function doRequest() {
+                                       // Optimisation: Inherit (Object.create), not copy ($.extend)
+                                       var query = Object.create( currReqBase ),
+                                               packed = buildModulesString( moduleMap );
+                                       query.modules = packed.str;
+                                       // The packing logic can change the effective order, even if the input was
+                                       // sorted. As such, the call to getCombinedVersion() must use this
+                                       // effective order, instead of currReqModules, as otherwise the combined
+                                       // version will not match the hash expected by the server based on
+                                       // combining versions from the module query string in-order. (T188076)
+                                       query.version = getCombinedVersion( packed.list );
+                                       query = sortQuery( query );
+                                       addScript( sourceLoadScript + '?' + makeQueryString( query ) );
+                               }
+
+                               if ( !batch.length ) {
+                                       return;
+                               }
+
+                               // Always order modules alphabetically to help reduce cache
+                               // misses for otherwise identical content.
+                               batch.sort();
+
+                               // Query parameters common to all requests
+                               reqBase = {
+                                       skin: mw.config.get( 'skin' ),
+                                       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 = {};
+                               for ( b = 0; b < batch.length; b++ ) {
+                                       bSource = registry[ batch[ b ] ].source;
+                                       bGroup = registry[ batch[ b ] ].group;
+                                       if ( !hasOwn.call( splits, bSource ) ) {
+                                               splits[ bSource ] = {};
+                                       }
+                                       if ( !hasOwn.call( splits[ bSource ], bGroup ) ) {
+                                               splits[ bSource ][ bGroup ] = [];
+                                       }
+                                       bSourceGroup = splits[ bSource ][ bGroup ];
+                                       bSourceGroup.push( batch[ b ] );
+                               }
+
+                               for ( source in splits ) {
+
+                                       sourceLoadScript = sources[ source ];
+
+                                       for ( group in splits[ source ] ) {
+
+                                               // Cache access to currently selected list of
+                                               // modules for this group from this source.
+                                               modules = splits[ source ][ group ];
+
+                                               // Query parameters common to requests for this module group
+                                               // Optimisation: Inherit (Object.create), not copy ($.extend)
+                                               currReqBase = Object.create( reqBase );
+                                               // User modules require a user name in the query string.
+                                               if ( group === 'user' && mw.config.get( 'wgUserName' ) !== null ) {
+                                                       currReqBase.user = mw.config.get( 'wgUserName' );
+                                               }
+
+                                               // In addition to currReqBase, doRequest() will also add 'modules' and 'version'.
+                                               // > '&modules='.length === 9
+                                               // > '&version=1234567'.length === 16
+                                               // > 9 + 16 = 25
+                                               currReqBaseLength = makeQueryString( currReqBase ).length + 25;
+
+                                               // We may need to split up the request to honor the query string length limit,
+                                               // so build it piece by piece.
+                                               l = currReqBaseLength;
+                                               moduleMap = {}; // { prefix: [ suffixes ] }
+                                               currReqModules = [];
+
+                                               for ( i = 0; i < modules.length; i++ ) {
+                                                       // Determine how many bytes this module would add to the query string
+                                                       lastDotIndex = modules[ i ].lastIndexOf( '.' );
+                                                       // If lastDotIndex is -1, substr() returns an empty string
+                                                       prefix = modules[ i ].substr( 0, lastDotIndex );
+                                                       suffix = modules[ i ].slice( lastDotIndex + 1 );
+                                                       bytesAdded = hasOwn.call( moduleMap, prefix ) ?
+                                                               suffix.length + 3 : // '%2C'.length == 3
+                                                               modules[ i ].length + 3; // '%7C'.length == 3
+
+                                                       // 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 ) {
+                                                               // Dispatch what we've got...
+                                                               doRequest();
+                                                               // .. and start again.
+                                                               l = currReqBaseLength;
+                                                               moduleMap = {};
+                                                               currReqModules = [];
+
+                                                               mw.track( 'resourceloader.splitRequest', { maxQueryLength: maxQueryLength } );
+                                                       }
+                                                       if ( !hasOwn.call( moduleMap, prefix ) ) {
+                                                               moduleMap[ prefix ] = [];
+                                                       }
+                                                       l += bytesAdded;
+                                                       moduleMap[ prefix ].push( suffix );
+                                                       currReqModules.push( modules[ i ] );
+                                               }
+                                               // If there's anything left in moduleMap, request that too
+                                               if ( currReqModules.length ) {
+                                                       doRequest();
+                                               }
+                                       }
+                               }
+                       }
+
+                       /**
+                        * @private
+                        * @param {string[]} implementations Array containing pieces of JavaScript code in the
+                        *  form of calls to mw.loader#implement().
+                        * @param {Function} cb Callback in case of failure
+                        * @param {Error} cb.err
+                        */
+                       function asyncEval( implementations, cb ) {
+                               if ( !implementations.length ) {
+                                       return;
+                               }
+                               mw.requestIdleCallback( function () {
+                                       try {
+                                               domEval( implementations.join( ';' ) );
+                                       } catch ( err ) {
+                                               cb( err );
+                                       }
+                               } );
+                       }
+
+                       /**
+                        * Make a versioned key for a specific module.
+                        *
+                        * @private
+                        * @param {string} module Module name
+                        * @return {string|null} Module key in format '`[name]@[version]`',
+                        *  or null if the module does not exist
+                        */
+                       function getModuleKey( module ) {
+                               return hasOwn.call( registry, module ) ?
+                                       ( module + '@' + registry[ module ].version ) : null;
+                       }
+
+                       /**
+                        * @private
+                        * @param {string} key Module name or '`[name]@[version]`'
+                        * @return {Object}
+                        */
+                       function splitModuleKey( key ) {
+                               var index = key.indexOf( '@' );
+                               if ( index === -1 ) {
+                                       return {
+                                               name: key,
+                                               version: ''
+                                       };
+                               }
+                               return {
+                                       name: key.slice( 0, index ),
+                                       version: key.slice( index + 1 )
+                               };
+                       }
+
+                       /* Public Members */
+                       return {
+                               /**
+                                * The module registry is exposed as an aid for debugging and inspecting page
+                                * state; it is not a public interface for modifying the registry.
+                                *
+                                * @see #registry
+                                * @property
+                                * @private
+                                */
+                               moduleRegistry: registry,
+
+                               /**
+                                * @inheritdoc #newStyleTag
+                                * @method
+                                */
+                               addStyleTag: newStyleTag,
+
+                               enqueue: enqueue,
+
+                               resolve: resolve,
+
+                               /**
+                                * Start loading of all queued module dependencies.
+                                *
+                                * @protected
+                                */
+                               work: function () {
+                                       var q, batch, implementations, sourceModules;
+
+                                       batch = [];
+
+                                       // Appends a list of modules from the queue to the batch
+                                       for ( q = 0; q < queue.length; q++ ) {
+                                               // Only load modules which are registered
+                                               if ( hasOwn.call( registry, queue[ q ] ) && registry[ queue[ q ] ].state === 'registered' ) {
+                                                       // Prevent duplicate entries
+                                                       if ( batch.indexOf( queue[ q ] ) === -1 ) {
+                                                               batch.push( queue[ q ] );
+                                                               // Mark registered modules as loading
+                                                               registry[ queue[ q ] ].state = 'loading';
+                                                       }
+                                               }
+                                       }
+
+                                       // Now that the queue has been processed into a batch, clear the queue.
+                                       // This MUST happen before we initiate any eval or network request. Otherwise,
+                                       // it is possible for a cached script to instantly trigger the same work queue
+                                       // again; all before we've cleared it causing each request to include modules
+                                       // which are already loaded.
+                                       queue = [];
+
+                                       if ( !batch.length ) {
+                                               return;
+                                       }
+
+                                       mw.loader.store.init();
+                                       if ( mw.loader.store.enabled ) {
+                                               implementations = [];
+                                               sourceModules = [];
+                                               batch = batch.filter( function ( module ) {
+                                                       var implementation = mw.loader.store.get( module );
+                                                       if ( implementation ) {
+                                                               implementations.push( implementation );
+                                                               sourceModules.push( module );
+                                                               return false;
+                                                       }
+                                                       return true;
+                                               } );
+                                               asyncEval( implementations, function ( err ) {
+                                                       var failed;
+                                                       // Not good, the cached mw.loader.implement calls failed! This should
+                                                       // never happen, barring ResourceLoader bugs, browser bugs and PEBKACs.
+                                                       // Depending on how corrupt the string is, it is likely that some
+                                                       // modules' implement() succeeded while the ones after the error will
+                                                       // never run and leave their modules in the 'loading' state forever.
+                                                       mw.loader.store.stats.failed++;
+
+                                                       // Since this is an error not caused by an individual module but by
+                                                       // something that infected the implement call itself, don't take any
+                                                       // risks and clear everything in this cache.
+                                                       mw.loader.store.clear();
+
+                                                       mw.trackError( 'resourceloader.exception', {
+                                                               exception: err,
+                                                               source: 'store-eval'
+                                                       } );
+                                                       // Re-add the failed ones that are still pending back to the batch
+                                                       failed = sourceModules.filter( function ( module ) {
+                                                               return registry[ module ].state === 'loading';
+                                                       } );
+                                                       batchRequest( failed );
+                                               } );
+                                       }
+
+                                       batchRequest( batch );
+                               },
+
+                               /**
+                                * Register a source.
+                                *
+                                * The #work() method will use this information to split up requests by source.
+                                *
+                                *     mw.loader.addSource( 'mediawikiwiki', '//www.mediawiki.org/w/load.php' );
+                                *
+                                * @param {string|Object} id Source ID, or object mapping ids to load urls
+                                * @param {string} loadUrl Url to a load.php end point
+                                * @throws {Error} If source id is already registered
+                                */
+                               addSource: function ( id, loadUrl ) {
+                                       var source;
+                                       // Allow multiple additions
+                                       if ( typeof id === 'object' ) {
+                                               for ( source in id ) {
+                                                       mw.loader.addSource( source, id[ source ] );
+                                               }
+                                               return;
+                                       }
+
+                                       if ( hasOwn.call( sources, id ) ) {
+                                               throw new Error( 'source already registered: ' + id );
+                                       }
+
+                                       sources[ id ] = loadUrl;
+                               },
+
+                               /**
+                                * Register a module, letting the system know about it and its properties.
+                                *
+                                * The startup modules contain calls to this method.
+                                *
+                                * When using multiple module registration by passing an array, dependencies that
+                                * are specified as references to modules within the array will be resolved before
+                                * the modules are registered.
+                                *
+                                * @param {string|Array} module Module name or array of arrays, each containing
+                                *  a list of arguments compatible with this method
+                                * @param {string|number} version Module version hash (falls backs to empty string)
+                                *  Can also be a number (timestamp) for compatibility with MediaWiki 1.25 and earlier.
+                                * @param {string|Array} dependencies One string or array of strings of module
+                                *  names on which this module depends.
+                                * @param {string} [group=null] Group which the module is in
+                                * @param {string} [source='local'] Name of the source
+                                * @param {string} [skip=null] Script body of the skip function
+                                */
+                               register: function ( module, version, dependencies, group, source, skip ) {
+                                       var i, deps;
+                                       // Allow multiple registration
+                                       if ( typeof module === 'object' ) {
+                                               resolveIndexedDependencies( module );
+                                               for ( i = 0; i < module.length; i++ ) {
+                                                       // module is an array of module names
+                                                       if ( typeof module[ i ] === 'string' ) {
+                                                               mw.loader.register( module[ i ] );
+                                                       // module is an array of arrays
+                                                       } else if ( typeof module[ i ] === 'object' ) {
+                                                               mw.loader.register.apply( mw.loader, module[ i ] );
+                                                       }
+                                               }
+                                               return;
+                                       }
+                                       if ( hasOwn.call( registry, module ) ) {
+                                               throw new Error( 'module already registered: ' + module );
+                                       }
+                                       if ( typeof dependencies === 'string' ) {
+                                               // A single module name
+                                               deps = [ dependencies ];
+                                       } else if ( typeof dependencies === 'object' ) {
+                                               // Array of module names
+                                               deps = dependencies;
+                                       }
+                                       // List the module as registered
+                                       registry[ module ] = {
+                                               // Exposed to execute() for mw.loader.implement() closures.
+                                               // Import happens via require().
+                                               module: {
+                                                       exports: {}
+                                               },
+                                               version: version !== undefined ? String( version ) : '',
+                                               dependencies: deps || [],
+                                               group: typeof group === 'string' ? group : null,
+                                               source: typeof source === 'string' ? source : 'local',
+                                               state: 'registered',
+                                               skip: typeof skip === 'string' ? skip : null
+                                       };
+                               },
+
+                               /**
+                                * Implement a module given the components that make up the module.
+                                *
+                                * When #load() or #using() requests one or more modules, the server
+                                * response contain calls to this function.
+                                *
+                                * @param {string} module Name of module and current module version. Formatted
+                                *  as '`[name]@[version]`". This version should match the requested version
+                                *  (from #batchRequest and #registry). This avoids race conditions (T117587).
+                                *  For back-compat with MediaWiki 1.27 and earlier, the version may be omitted.
+                                * @param {Function|Array|string} [script] Function with module code, list of URLs
+                                *  to load via `<script src>`, or string of module code for `$.globalEval()`.
+                                * @param {Object} [style] Should follow one of the following patterns:
+                                *
+                                *     { "css": [css, ..] }
+                                *     { "url": { <media>: [url, ..] } }
+                                *
+                                * And for backwards compatibility (needs to be supported forever due to caching):
+                                *
+                                *     { <media>: css }
+                                *     { <media>: [url, ..] }
+                                *
+                                * The reason css strings are not concatenated anymore is T33676. We now check
+                                * whether it's safe to extend the stylesheet.
+                                *
+                                * @protected
+                                * @param {Object} [messages] List of key/value pairs to be added to mw#messages.
+                                * @param {Object} [templates] List of key/value pairs to be added to mw#templates.
+                                */
+                               implement: function ( module, script, style, messages, templates ) {
+                                       var split = splitModuleKey( module ),
+                                               name = split.name,
+                                               version = split.version;
+                                       // Automatically register module
+                                       if ( !hasOwn.call( registry, name ) ) {
+                                               mw.loader.register( name );
+                                       }
+                                       // Check for duplicate implementation
+                                       if ( hasOwn.call( registry, name ) && registry[ name ].script !== undefined ) {
+                                               throw new Error( 'module already implemented: ' + name );
+                                       }
+                                       if ( version ) {
+                                               // Without this reset, if there is a version mismatch between the
+                                               // requested and received module version, then mw.loader.store would
+                                               // cache the response under the requested key. Thus poisoning the cache
+                                               // indefinitely with a stale value. (T117587)
+                                               registry[ name ].version = version;
+                                       }
+                                       // Attach components
+                                       registry[ name ].script = script || null;
+                                       registry[ name ].style = style || null;
+                                       registry[ name ].messages = messages || null;
+                                       registry[ name ].templates = templates || null;
+                                       // The module may already have been marked as erroneous
+                                       if ( registry[ name ].state !== 'error' && registry[ name ].state !== 'missing' ) {
+                                               registry[ name ].state = 'loaded';
+                                               if ( allReady( registry[ name ].dependencies ) ) {
+                                                       execute( name );
+                                               }
+                                       }
+                               },
+
+                               /**
+                                * Load an external script or one or more modules.
+                                *
+                                * This method takes a list of unrelated modules. Use cases:
+                                *
+                                * - A web page will be composed of many different widgets. These widgets independently
+                                *   queue their ResourceLoader modules (`OutputPage::addModules()`). If any of them
+                                *   have problems, or are no longer known (e.g. cached HTML), the other modules
+                                *   should still be loaded.
+                                * - This method is used for preloading, which must not throw. Later code that
+                                *   calls #using() will handle the error.
+                                *
+                                * @param {string|Array} modules Either the name of a module, array of modules,
+                                *  or a URL of an external script or style
+                                * @param {string} [type='text/javascript'] MIME type to use if calling with a URL of an
+                                *  external script or style; acceptable values are "text/css" and
+                                *  "text/javascript"; if no type is provided, text/javascript is assumed.
+                                */
+                               load: function ( modules, type ) {
+                                       var filtered, l;
+
+                                       // Allow calling with a url or single dependency as a string
+                                       if ( typeof modules === 'string' ) {
+                                               // "https://example.org/x.js", "http://example.org/x.js", "//example.org/x.js", "/x.js"
+                                               if ( /^(https?:)?\/?\//.test( modules ) ) {
+                                                       if ( type === 'text/css' ) {
+                                                               l = document.createElement( 'link' );
+                                                               l.rel = 'stylesheet';
+                                                               l.href = modules;
+                                                               document.head.appendChild( l );
+                                                               return;
+                                                       }
+                                                       if ( type === 'text/javascript' || type === undefined ) {
+                                                               addScript( modules );
+                                                               return;
+                                                       }
+                                                       // Unknown type
+                                                       throw new Error( 'invalid type for external url, must be text/css or text/javascript. not ' + type );
+                                               }
+                                               // Called with single module
+                                               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 );
+                               },
+
+                               /**
+                                * Change the state of one or more modules.
+                                *
+                                * @param {string|Object} module Module name or object of module name/state pairs
+                                * @param {string} state State name
+                                */
+                               state: function ( module, state ) {
+                                       var m;
+
+                                       if ( typeof module === 'object' ) {
+                                               for ( m in module ) {
+                                                       mw.loader.state( m, module[ m ] );
+                                               }
+                                               return;
+                                       }
+                                       if ( !hasOwn.call( registry, module ) ) {
+                                               mw.loader.register( module );
+                                       }
+                                       registry[ module ].state = state;
+                                       if ( state === 'ready' || state === 'error' || state === 'missing' ) {
+                                               // Make sure pending modules depending on this one get executed if their
+                                               // dependencies are now fulfilled!
+                                               handlePending( module );
+                                       }
+                               },
+
+                               /**
+                                * Get the version of a module.
+                                *
+                                * @param {string} module Name of module
+                                * @return {string|null} The version, or null if the module (or its version) is not
+                                *  in the registry.
+                                */
+                               getVersion: function ( module ) {
+                                       return hasOwn.call( registry, module ) ? registry[ module ].version : null;
+                               },
+
+                               /**
+                                * Get the state of a module.
+                                *
+                                * @param {string} module Name of module
+                                * @return {string|null} The state, or null if the module (or its state) is not
+                                *  in the registry.
+                                */
+                               getState: function ( module ) {
+                                       return hasOwn.call( registry, module ) ? registry[ module ].state : null;
+                               },
+
+                               /**
+                                * Get the names of all registered modules.
+                                *
+                                * @return {Array}
+                                */
+                               getModuleNames: function () {
+                                       return Object.keys( registry );
+                               },
+
+                               /**
+                                * Get the exported value of a module.
+                                *
+                                * This static method is publicly exposed for debugging purposes
+                                * only and must not be used in production code. In production code,
+                                * please use the dynamically provided `require()` function instead.
+                                *
+                                * In case of lazy-loaded modules via mw.loader#using(), the returned
+                                * Promise provides the function, see #using() for examples.
+                                *
+                                * @private
+                                * @since 1.27
+                                * @param {string} moduleName Module name
+                                * @return {Mixed} Exported value
+                                */
+                               require: function ( moduleName ) {
+                                       var state = mw.loader.getState( moduleName );
+
+                                       // Only ready modules can be required
+                                       if ( state !== 'ready' ) {
+                                               // Module may've forgotten to declare a dependency
+                                               throw new Error( 'Module "' + moduleName + '" is not loaded.' );
+                                       }
+
+                                       return registry[ moduleName ].module.exports;
+                               },
+
+                               /**
+                                * On browsers that implement the localStorage API, the module store serves as a
+                                * smart complement to the browser cache. Unlike the browser cache, the module store
+                                * can slice a concatenated response from ResourceLoader into its constituent
+                                * modules and cache each of them separately, using each module's versioning scheme
+                                * to determine when the cache should be invalidated.
+                                *
+                                * @singleton
+                                * @class mw.loader.store
+                                */
+                               store: {
+                                       // Whether the store is in use on this page.
+                                       enabled: null,
+
+                                       // Modules whose string representation exceeds 100 kB are
+                                       // ineligible for storage. See bug T66721.
+                                       MODULE_SIZE_MAX: 100 * 1000,
+
+                                       // The contents of the store, mapping '[name]@[version]' keys
+                                       // to module implementations.
+                                       items: {},
+
+                                       // Cache hit stats
+                                       stats: { hits: 0, misses: 0, expired: 0, failed: 0 },
+
+                                       /**
+                                        * Construct a JSON-serializable object representing the content of the store.
+                                        *
+                                        * @return {Object} Module store contents.
+                                        */
+                                       toJSON: function () {
+                                               return { items: mw.loader.store.items, vary: mw.loader.store.getVary() };
+                                       },
+
+                                       /**
+                                        * Get the localStorage key for the entire module store. The key references
+                                        * $wgDBname to prevent clashes between wikis which share a common host.
+                                        *
+                                        * @return {string} localStorage item key
+                                        */
+                                       getStoreKey: function () {
+                                               return 'MediaWikiModuleStore:' + mw.config.get( 'wgDBname' );
+                                       },
+
+                                       /**
+                                        * Get a key on which to vary the module cache.
+                                        *
+                                        * @return {string} String of concatenated vary conditions.
+                                        */
+                                       getVary: function () {
+                                               return [
+                                                       mw.config.get( 'skin' ),
+                                                       mw.config.get( 'wgResourceLoaderStorageVersion' ),
+                                                       mw.config.get( 'wgUserLanguage' )
+                                               ].join( ':' );
+                                       },
+
+                                       /**
+                                        * Initialize the store.
+                                        *
+                                        * Retrieves store from localStorage and (if successfully retrieved) decoding
+                                        * the stored JSON value to a plain object.
+                                        *
+                                        * The try / catch block is used for JSON & localStorage feature detection.
+                                        * See the in-line documentation for Modernizr's localStorage feature detection
+                                        * code for a full account of why we need a try / catch:
+                                        * <https://github.com/Modernizr/Modernizr/blob/v2.7.1/modernizr.js#L771-L796>.
+                                        */
+                                       init: function () {
+                                               var raw, data;
+
+                                               if ( mw.loader.store.enabled !== null ) {
+                                                       // Init already ran
+                                                       return;
+                                               }
+
+                                               if (
+                                                       // Disabled because localStorage quotas are tight and (in Firefox's case)
+                                                       // shared by multiple origins.
+                                                       // See T66721, and <https://bugzilla.mozilla.org/show_bug.cgi?id=1064466>.
+                                                       /Firefox|Opera/.test( navigator.userAgent ) ||
+
+                                                       // Disabled by configuration.
+                                                       !mw.config.get( 'wgResourceLoaderStorageEnabled' )
+                                               ) {
+                                                       // Clear any previous store to free up space. (T66721)
+                                                       mw.loader.store.clear();
+                                                       mw.loader.store.enabled = false;
+                                                       return;
+                                               }
+                                               if ( mw.config.get( 'debug' ) ) {
+                                                       // Disable module store in debug mode
+                                                       mw.loader.store.enabled = false;
+                                                       return;
+                                               }
+
+                                               try {
+                                                       raw = localStorage.getItem( mw.loader.store.getStoreKey() );
+                                                       // If we get here, localStorage is available; mark enabled
+                                                       mw.loader.store.enabled = true;
+                                                       data = JSON.parse( raw );
+                                                       if ( data && typeof data.items === 'object' && data.vary === mw.loader.store.getVary() ) {
+                                                               mw.loader.store.items = data.items;
+                                                               return;
+                                                       }
+                                               } catch ( e ) {
+                                                       mw.trackError( 'resourceloader.exception', {
+                                                               exception: e,
+                                                               source: 'store-localstorage-init'
+                                                       } );
+                                               }
+
+                                               if ( raw === undefined ) {
+                                                       // localStorage failed; disable store
+                                                       mw.loader.store.enabled = false;
+                                               } else {
+                                                       mw.loader.store.update();
+                                               }
+                                       },
+
+                                       /**
+                                        * Retrieve a module from the store and update cache hit stats.
+                                        *
+                                        * @param {string} module Module name
+                                        * @return {string|boolean} Module implementation or false if unavailable
+                                        */
+                                       get: function ( module ) {
+                                               var key;
+
+                                               if ( !mw.loader.store.enabled ) {
+                                                       return false;
+                                               }
+
+                                               key = getModuleKey( module );
+                                               if ( key in mw.loader.store.items ) {
+                                                       mw.loader.store.stats.hits++;
+                                                       return mw.loader.store.items[ key ];
+                                               }
+                                               mw.loader.store.stats.misses++;
+                                               return false;
+                                       },
+
+                                       /**
+                                        * Stringify a module and queue it for storage.
+                                        *
+                                        * @param {string} module Module name
+                                        * @param {Object} descriptor The module's descriptor as set in the registry
+                                        * @return {boolean} Module was set
+                                        */
+                                       set: function ( module, descriptor ) {
+                                               var args, key, src;
+
+                                               if ( !mw.loader.store.enabled ) {
+                                                       return false;
+                                               }
+
+                                               key = getModuleKey( module );
+
+                                               if (
+                                                       // Already stored a copy of this exact version
+                                                       key in mw.loader.store.items ||
+                                                       // Module failed to load
+                                                       descriptor.state !== 'ready' ||
+                                                       // Unversioned, private, or site-/user-specific
+                                                       !descriptor.version ||
+                                                       descriptor.group === 'private' ||
+                                                       descriptor.group === 'user' ||
+                                                       // Partial descriptor
+                                                       // (e.g. skipped module, or style module with state=ready)
+                                                       [ descriptor.script, descriptor.style, descriptor.messages,
+                                                               descriptor.templates ].indexOf( undefined ) !== -1
+                                               ) {
+                                                       // Decline to store
+                                                       return false;
+                                               }
+
+                                               try {
+                                                       args = [
+                                                               JSON.stringify( key ),
+                                                               typeof descriptor.script === 'function' ?
+                                                                       String( descriptor.script ) :
+                                                                       JSON.stringify( descriptor.script ),
+                                                               JSON.stringify( descriptor.style ),
+                                                               JSON.stringify( descriptor.messages ),
+                                                               JSON.stringify( descriptor.templates )
+                                                       ];
+                                                       // Attempted workaround for a possible Opera bug (bug T59567).
+                                                       // This regex should never match under sane conditions.
+                                                       if ( /^\s*\(/.test( args[ 1 ] ) ) {
+                                                               args[ 1 ] = 'function' + args[ 1 ];
+                                                               mw.trackError( 'resourceloader.assert', { source: 'bug-T59567' } );
+                                                       }
+                                               } catch ( e ) {
+                                                       mw.trackError( 'resourceloader.exception', {
+                                                               exception: e,
+                                                               source: 'store-localstorage-json'
+                                                       } );
+                                                       return false;
+                                               }
+
+                                               src = 'mw.loader.implement(' + args.join( ',' ) + ');';
+                                               if ( src.length > mw.loader.store.MODULE_SIZE_MAX ) {
+                                                       return false;
+                                               }
+                                               mw.loader.store.items[ key ] = src;
+                                               mw.loader.store.update();
+                                               return true;
+                                       },
+
+                                       /**
+                                        * Iterate through the module store, removing any item that does not correspond
+                                        * (in name and version) to an item in the module registry.
+                                        *
+                                        * @return {boolean} Store was pruned
+                                        */
+                                       prune: function () {
+                                               var key, module;
+
+                                               if ( !mw.loader.store.enabled ) {
+                                                       return false;
+                                               }
+
+                                               for ( key in mw.loader.store.items ) {
+                                                       module = key.slice( 0, key.indexOf( '@' ) );
+                                                       if ( getModuleKey( module ) !== key ) {
+                                                               mw.loader.store.stats.expired++;
+                                                               delete mw.loader.store.items[ key ];
+                                                       } else if ( mw.loader.store.items[ key ].length > mw.loader.store.MODULE_SIZE_MAX ) {
+                                                               // This value predates the enforcement of a size limit on cached modules.
+                                                               delete mw.loader.store.items[ key ];
+                                                       }
+                                               }
+                                               return true;
+                                       },
+
+                                       /**
+                                        * Clear the entire module store right now.
+                                        */
+                                       clear: function () {
+                                               mw.loader.store.items = {};
+                                               try {
+                                                       localStorage.removeItem( mw.loader.store.getStoreKey() );
+                                               } catch ( ignored ) {}
+                                       },
+
+                                       /**
+                                        * Sync in-memory store back to localStorage.
+                                        *
+                                        * This function debounces updates. When called with a flush already pending,
+                                        * the call is coalesced into the pending update. The call to
+                                        * localStorage.setItem will be naturally deferred until the page is quiescent.
+                                        *
+                                        * Because localStorage is shared by all pages from the same origin, if multiple
+                                        * pages are loaded with different module sets, the possibility exists that
+                                        * modules saved by one page will be clobbered by another. But the impact would
+                                        * be minor and the problem would be corrected by subsequent page views.
+                                        *
+                                        * @method
+                                        */
+                                       update: ( function () {
+                                               var hasPendingWrite = false;
+
+                                               function flushWrites() {
+                                                       var data, key;
+                                                       if ( !hasPendingWrite || !mw.loader.store.enabled ) {
+                                                               return;
+                                                       }
+
+                                                       mw.loader.store.prune();
+                                                       key = mw.loader.store.getStoreKey();
+                                                       try {
+                                                               // Replacing the content of the module store might fail if the new
+                                                               // contents would exceed the browser's localStorage size limit. To
+                                                               // avoid clogging the browser with stale data, always remove the old
+                                                               // value before attempting to set the new one.
+                                                               localStorage.removeItem( key );
+                                                               data = JSON.stringify( mw.loader.store );
+                                                               localStorage.setItem( key, data );
+                                                       } catch ( e ) {
+                                                               mw.trackError( 'resourceloader.exception', {
+                                                                       exception: e,
+                                                                       source: 'store-localstorage-update'
+                                                               } );
+                                                       }
+
+                                                       hasPendingWrite = false;
+                                               }
+
+                                               return function () {
+                                                       if ( !hasPendingWrite ) {
+                                                               hasPendingWrite = true;
+                                                               mw.requestIdleCallback( flushWrites );
+                                                       }
+                                               };
+                                       }() )
+                               }
+                       };
+               }() ),
+
+               // Skeleton user object, extended by the 'mediawiki.user' module.
+               /**
+                * @class mw.user
+                * @singleton
+                */
+               user: {
+                       /**
+                        * @property {mw.Map}
+                        */
+                       options: new Map(),
+                       /**
+                        * @property {mw.Map}
+                        */
+                       tokens: new Map()
+               },
+
+               // OOUI widgets specific to MediaWiki
+               widgets: {}
+
+       };
+
+       // Attach to window and globally alias
+       window.mw = window.mediaWiki = mw;
+}() );
diff --git a/resources/src/startup/mediawiki.log.js b/resources/src/startup/mediawiki.log.js
new file mode 100644 (file)
index 0000000..a3f3c68
--- /dev/null
@@ -0,0 +1,25 @@
+/*!
+ * This file is concatenated to mediawiki.js in debug mode.
+ *
+ * See Resources.php.
+ *
+ * @author Michael Dale <mdale@wikimedia.org>
+ * @author Trevor Parscal <tparscal@wikimedia.org>
+ */
+( function ( mw ) {
+       /* global console */
+       /* eslint-disable no-console */
+       var original = mw.log;
+
+       // Replace the mw.log() no-op defined in mediawiki.js, with
+       // a function that logs to console.log (if available).
+       if ( window.console && console.log && console.log.apply ) {
+               mw.log = function () {
+                       console.log.apply( console, arguments );
+               };
+               // Re-attach original sub methods
+               mw.log.warn = original.warn;
+               mw.log.error = original.error;
+               mw.log.deprecate = original.deprecate;
+       }
+}( mediaWiki ) );
diff --git a/resources/src/startup/mediawiki.requestIdleCallback.js b/resources/src/startup/mediawiki.requestIdleCallback.js
new file mode 100644 (file)
index 0000000..650092b
--- /dev/null
@@ -0,0 +1,52 @@
+( function ( mw ) {
+       var maxBusy = 50;
+
+       mw.requestIdleCallbackInternal = function ( callback ) {
+               setTimeout( function () {
+                       var start = mw.now();
+                       callback( {
+                               didTimeout: false,
+                               timeRemaining: function () {
+                                       return Math.max( 0, maxBusy - ( mw.now() - start ) );
+                               }
+                       } );
+               }, 1 );
+       };
+
+       /**
+        * Schedule a deferred task to run in the background.
+        *
+        * This allows code to perform tasks in the main thread without impacting
+        * time-critical operations such as animations and response to input events.
+        *
+        * Basic logic is as follows:
+        *
+        * - User input event should be acknowledged within 100ms per [RAIL].
+        * - Idle work should be grouped in blocks of upto 50ms so that enough time
+        *   remains for the event handler to execute and any rendering to take place.
+        * - Whenever a native event happens (e.g. user input), the deadline for any
+        *   running idle callback drops to 0.
+        * - As long as the deadline is non-zero, other callbacks pending may be
+        *   executed in the same idle period.
+        *
+        * See also:
+        *
+        * - <https://developer.mozilla.org/en-US/docs/Web/API/Window/requestIdleCallback>
+        * - <https://w3c.github.io/requestidlecallback/>
+        * - <https://developers.google.com/web/updates/2015/08/using-requestidlecallback>
+        * [RAIL]: https://developers.google.com/web/fundamentals/performance/rail
+        *
+        * @member mw
+        * @param {Function} callback
+        * @param {Object} [options]
+        * @param {number} [options.timeout] If set, the callback will be scheduled for
+        *  immediate execution after this amount of time (in milliseconds) if it didn't run
+        *  by that time.
+        */
+       mw.requestIdleCallback = window.requestIdleCallback ?
+               window.requestIdleCallback.bind( window ) : // Bind because it throws TypeError if context is not window
+               mw.requestIdleCallbackInternal;
+       // Note: Polyfill was previously disabled due to
+       // https://bugs.chromium.org/p/chromium/issues/detail?id=647870
+       // See also <http://codepen.io/Krinkle/full/XNGEvv>
+}( mediaWiki ) );
diff --git a/resources/src/startup/startup.js b/resources/src/startup/startup.js
new file mode 100644 (file)
index 0000000..7a50d94
--- /dev/null
@@ -0,0 +1,157 @@
+/**
+ * This file is where we decide whether to initialise the Grade A run-time.
+ *
+ * - Beware: This file MUST parse without errors on even the most ancient of browsers!
+ */
+
+/* global mw, isCompatible, $VARS, $CODE */
+
+/**
+ * See <https://www.mediawiki.org/wiki/Compatibility#Browsers>
+ *
+ * Capabilities required for modern run-time:
+ * - ECMAScript 5
+ * - DOM Level 4 & Selectors API Level 1
+ * - HTML5 & Web Storage
+ * - DOM Level 2 Events
+ *
+ * Browsers we support in our modern run-time (Grade A):
+ * - Chrome 13+
+ * - IE 11+
+ * - Firefox 4+
+ * - Safari 5+
+ * - Opera 15+
+ * - Mobile Safari 6.0+ (iOS 6+)
+ * - Android 4.1+
+ *
+ * Browsers we support in our no-javascript run-time (Grade C):
+ * - Chrome 1+
+ * - IE 6+
+ * - Firefox 3+
+ * - Safari 3+
+ * - Opera 15+
+ * - Mobile Safari 5.0+ (iOS 4+)
+ * - Android 2.0+
+ * - WebOS < 1.5
+ * - PlayStation
+ * - Symbian-based browsers
+ * - NetFront-based browser
+ * - Opera Mini
+ * - Nokia's Ovi Browser
+ * - MeeGo's browser
+ * - Google Glass
+ * - UC Mini (speed mode on)
+ *
+ * Other browsers that pass the check are considered Grade X.
+ *
+ * @param {string} [str] User agent, defaults to navigator.userAgent
+ * @return {boolean} User agent is compatible with MediaWiki JS
+ */
+window.isCompatible = function ( str ) {
+       var ua = str || navigator.userAgent;
+       return !!(
+               // https://caniuse.com/#feat=es5
+               // https://caniuse.com/#feat=use-strict
+               // https://caniuse.com/#feat=json / https://phabricator.wikimedia.org/T141344#2784065
+               ( function () {
+                       'use strict';
+                       return !this && !!Function.prototype.bind && !!window.JSON;
+               }() ) &&
+
+               // https://caniuse.com/#feat=queryselector
+               'querySelector' in document &&
+
+               // https://caniuse.com/#feat=namevalue-storage
+               // https://developer.blackberry.com/html5/apis/v1_0/localstorage.html
+               // https://blog.whatwg.org/this-week-in-html-5-episode-30
+               'localStorage' in window &&
+
+               // https://caniuse.com/#feat=addeventlistener
+               'addEventListener' in window &&
+
+               // Hardcoded exceptions for browsers that pass the requirement but we don't want to
+               // support in the modern run-time.
+               // Note: Please extend the regex instead of adding new ones
+               !(
+                       ua.match( /MSIE 10|webOS\/1\.[0-4]|SymbianOS|Series60|NetFront|Opera Mini|S40OviBrowser|MeeGo|Android.+Glass|^Mozilla\/5\.0 .+ Gecko\/$|googleweblight/ ) ||
+                       ua.match( /PlayStation/i )
+               )
+       );
+};
+
+// Conditional script injection
+( function () {
+       var NORLQ, script;
+       if ( !isCompatible() ) {
+               // Undo class swapping in case of an unsupported browser.
+               // See ResourceLoaderClientHtml::getDocumentAttributes().
+               document.documentElement.className = document.documentElement.className
+                       .replace( /(^|\s)client-js(\s|$)/, '$1client-nojs$2' );
+
+               NORLQ = window.NORLQ || [];
+               while ( NORLQ.length ) {
+                       NORLQ.shift()();
+               }
+               window.NORLQ = {
+                       push: function ( fn ) {
+                               fn();
+                       }
+               };
+
+               // Clear and disable the other queue
+               window.RLQ = {
+                       // No-op
+                       push: function () {}
+               };
+
+               return;
+       }
+
+       /**
+        * The $CODE and $VARS placeholders are substituted in ResourceLoaderStartUpModule.php.
+        */
+       function startUp() {
+               mw.config = new mw.Map( $VARS.wgLegacyJavaScriptGlobals );
+
+               $CODE.registrations();
+
+               mw.config.set( $VARS.configuration );
+
+               // Must be after mw.config.set because these callbacks may use mw.loader which
+               // needs to have values 'skin', 'debug' etc. from mw.config.
+               // eslint-disable-next-line vars-on-top
+               var RLQ = window.RLQ || [];
+               while ( RLQ.length ) {
+                       RLQ.shift()();
+               }
+               window.RLQ = {
+                       push: function ( fn ) {
+                               fn();
+                       }
+               };
+
+               // Clear and disable the other queue
+               window.NORLQ = {
+                       // No-op
+                       push: function () {}
+               };
+       }
+
+       if ( window.performance && performance.mark ) {
+               performance.mark( 'mwStartup' );
+       }
+
+       // This embeds mediawiki.js, which defines 'mw' and 'mw.loader'.
+       $CODE.defineLoader();
+
+       script = document.createElement( 'script' );
+       script.src = $VARS.baseModulesUri;
+       script.onload = function () {
+               // Clean up
+               script.onload = null;
+               script = null;
+               // Callback
+               startUp();
+       };
+       document.head.appendChild( script );
+}() );
index d9d58dd..33b9f02 100644 (file)
@@ -1,4 +1,3 @@
-/UnicodeData.txt
 /allkeys.txt
 /ucd.all.grouped.xml
 /ucd.all.grouped.zip
index 0a04d85..09369ef 100644 (file)
@@ -1,4 +1,4 @@
-SPECIAL_TARGETS=normalize-ar.ser normalize-ml.ser first-letters-root.ser
+SPECIAL_TARGETS=first-letters-root.ser
 ALL_TARGETS=$(SPECIAL_TARGETS)
 DIST_TARGETS=$(SPECIAL_TARGETS)
 UNICODE_VERSION=6.0.0
@@ -13,18 +13,9 @@ dist: $(DIST_TARGETS)
 clean:
        rm -f $(ALL_TARGETS)
 
-normalize-ar.ser: UnicodeData.txt
-       php ../maintenance/language/generateNormalizerDataAr.php
-
-normalize-ml.ser:
-       php ../maintenance/language/generateNormalizerDataMl.php
-
 first-letters-root.ser: allkeys.txt ucd.all.grouped.xml
        php ../maintenance/language/generateCollationData.php
 
-UnicodeData.txt:
-       wget https://www.unicode.org/Public/$(UNICODE_VERSION)/ucd/UnicodeData.txt
-
 allkeys.txt:
        wget https://www.unicode.org/Public/UCA/$(UNICODE_VERSION)/allkeys.txt
 
diff --git a/serialized/normalize-ar.ser b/serialized/normalize-ar.ser
deleted file mode 100644 (file)
index 2a7f122..0000000
+++ /dev/null
@@ -1 +0,0 @@
-a:731:{s:3:"ﭐ";s:2:"ٱ";s:3:"ﭑ";s:2:"ٱ";s:3:"ﭒ";s:2:"ٻ";s:3:"ﭓ";s:2:"ٻ";s:3:"ﭔ";s:2:"ٻ";s:3:"ﭕ";s:2:"ٻ";s:3:"ﭖ";s:2:"پ";s:3:"ﭗ";s:2:"پ";s:3:"ﭘ";s:2:"پ";s:3:"ﭙ";s:2:"پ";s:3:"ﭚ";s:2:"ڀ";s:3:"ﭛ";s:2:"ڀ";s:3:"ﭜ";s:2:"ڀ";s:3:"ﭝ";s:2:"ڀ";s:3:"ﭞ";s:2:"ٺ";s:3:"ﭟ";s:2:"ٺ";s:3:"ﭠ";s:2:"ٺ";s:3:"ﭡ";s:2:"ٺ";s:3:"ﭢ";s:2:"ٿ";s:3:"ﭣ";s:2:"ٿ";s:3:"ﭤ";s:2:"ٿ";s:3:"ﭥ";s:2:"ٿ";s:3:"ﭦ";s:2:"ٹ";s:3:"ﭧ";s:2:"ٹ";s:3:"ﭨ";s:2:"ٹ";s:3:"ﭩ";s:2:"ٹ";s:3:"ﭪ";s:2:"ڤ";s:3:"ﭫ";s:2:"ڤ";s:3:"ﭬ";s:2:"ڤ";s:3:"ﭭ";s:2:"ڤ";s:3:"ﭮ";s:2:"ڦ";s:3:"ﭯ";s:2:"ڦ";s:3:"ﭰ";s:2:"ڦ";s:3:"ﭱ";s:2:"ڦ";s:3:"ﭲ";s:2:"ڄ";s:3:"ﭳ";s:2:"ڄ";s:3:"ﭴ";s:2:"ڄ";s:3:"ﭵ";s:2:"ڄ";s:3:"ﭶ";s:2:"ڃ";s:3:"ﭷ";s:2:"ڃ";s:3:"ﭸ";s:2:"ڃ";s:3:"ﭹ";s:2:"ڃ";s:3:"ﭺ";s:2:"چ";s:3:"ﭻ";s:2:"چ";s:3:"ﭼ";s:2:"چ";s:3:"ﭽ";s:2:"چ";s:3:"ﭾ";s:2:"ڇ";s:3:"ﭿ";s:2:"ڇ";s:3:"ﮀ";s:2:"ڇ";s:3:"ﮁ";s:2:"ڇ";s:3:"ﮂ";s:2:"ڍ";s:3:"ﮃ";s:2:"ڍ";s:3:"ﮄ";s:2:"ڌ";s:3:"ﮅ";s:2:"ڌ";s:3:"ﮆ";s:2:"ڎ";s:3:"ﮇ";s:2:"ڎ";s:3:"ﮈ";s:2:"ڈ";s:3:"ﮉ";s:2:"ڈ";s:3:"ﮊ";s:2:"ژ";s:3:"ﮋ";s:2:"ژ";s:3:"ﮌ";s:2:"ڑ";s:3:"ﮍ";s:2:"ڑ";s:3:"ﮎ";s:2:"ک";s:3:"ﮏ";s:2:"ک";s:3:"ﮐ";s:2:"ک";s:3:"ﮑ";s:2:"ک";s:3:"ﮒ";s:2:"گ";s:3:"ﮓ";s:2:"گ";s:3:"ﮔ";s:2:"گ";s:3:"ﮕ";s:2:"گ";s:3:"ﮖ";s:2:"ڳ";s:3:"ﮗ";s:2:"ڳ";s:3:"ﮘ";s:2:"ڳ";s:3:"ﮙ";s:2:"ڳ";s:3:"ﮚ";s:2:"ڱ";s:3:"ﮛ";s:2:"ڱ";s:3:"ﮜ";s:2:"ڱ";s:3:"ﮝ";s:2:"ڱ";s:3:"ﮞ";s:2:"ں";s:3:"ﮟ";s:2:"ں";s:3:"ﮠ";s:2:"ڻ";s:3:"ﮡ";s:2:"ڻ";s:3:"ﮢ";s:2:"ڻ";s:3:"ﮣ";s:2:"ڻ";s:3:"ﮤ";s:2:"ۀ";s:3:"ﮥ";s:2:"ۀ";s:3:"ﮦ";s:2:"ہ";s:3:"ﮧ";s:2:"ہ";s:3:"ﮨ";s:2:"ہ";s:3:"ﮩ";s:2:"ہ";s:3:"ﮪ";s:2:"ھ";s:3:"ﮫ";s:2:"ھ";s:3:"ﮬ";s:2:"ھ";s:3:"ﮭ";s:2:"ھ";s:3:"ﮮ";s:2:"ے";s:3:"ﮯ";s:2:"ے";s:3:"ﮰ";s:2:"ۓ";s:3:"ﮱ";s:2:"ۓ";s:3:"ﯓ";s:2:"ڭ";s:3:"ﯔ";s:2:"ڭ";s:3:"ﯕ";s:2:"ڭ";s:3:"ﯖ";s:2:"ڭ";s:3:"ﯗ";s:2:"ۇ";s:3:"ﯘ";s:2:"ۇ";s:3:"ﯙ";s:2:"ۆ";s:3:"ﯚ";s:2:"ۆ";s:3:"ﯛ";s:2:"ۈ";s:3:"ﯜ";s:2:"ۈ";s:3:"ﯝ";s:2:"ٷ";s:3:"ﯞ";s:2:"ۋ";s:3:"ﯟ";s:2:"ۋ";s:3:"ﯠ";s:2:"ۅ";s:3:"ﯡ";s:2:"ۅ";s:3:"ﯢ";s:2:"ۉ";s:3:"ﯣ";s:2:"ۉ";s:3:"ﯤ";s:2:"ې";s:3:"ﯥ";s:2:"ې";s:3:"ﯦ";s:2:"ې";s:3:"ﯧ";s:2:"ې";s:3:"ﯨ";s:2:"ى";s:3:"ﯩ";s:2:"ى";s:3:"ﯪ";s:4:"ئا";s:3:"ﯫ";s:4:"ئا";s:3:"ﯬ";s:4:"ئە";s:3:"ﯭ";s:4:"ئە";s:3:"ﯮ";s:4:"ئو";s:3:"ﯯ";s:4:"ئو";s:3:"ﯰ";s:4:"ئۇ";s:3:"ﯱ";s:4:"ئۇ";s:3:"ﯲ";s:4:"ئۆ";s:3:"ﯳ";s:4:"ئۆ";s:3:"ﯴ";s:4:"ئۈ";s:3:"ﯵ";s:4:"ئۈ";s:3:"ﯶ";s:4:"ئې";s:3:"ﯷ";s:4:"ئې";s:3:"ﯸ";s:4:"ئې";s:3:"ﯹ";s:4:"ئى";s:3:"ﯺ";s:4:"ئى";s:3:"ﯻ";s:4:"ئى";s:3:"ﯼ";s:2:"ی";s:3:"ﯽ";s:2:"ی";s:3:"ﯾ";s:2:"ی";s:3:"ﯿ";s:2:"ی";s:3:"ﰀ";s:4:"ئج";s:3:"ﰁ";s:4:"ئح";s:3:"ﰂ";s:4:"ئم";s:3:"ﰃ";s:4:"ئى";s:3:"ﰄ";s:4:"ئي";s:3:"ﰅ";s:4:"بج";s:3:"ﰆ";s:4:"بح";s:3:"ﰇ";s:4:"بخ";s:3:"ﰈ";s:4:"بم";s:3:"ﰉ";s:4:"بى";s:3:"ﰊ";s:4:"بي";s:3:"ﰋ";s:4:"تج";s:3:"ﰌ";s:4:"تح";s:3:"ﰍ";s:4:"تخ";s:3:"ﰎ";s:4:"تم";s:3:"ﰏ";s:4:"تى";s:3:"ﰐ";s:4:"تي";s:3:"ﰑ";s:4:"ثج";s:3:"ﰒ";s:4:"ثم";s:3:"ﰓ";s:4:"ثى";s:3:"ﰔ";s:4:"ثي";s:3:"ﰕ";s:4:"جح";s:3:"ﰖ";s:4:"جم";s:3:"ﰗ";s:4:"حج";s:3:"ﰘ";s:4:"حم";s:3:"ﰙ";s:4:"خج";s:3:"ﰚ";s:4:"خح";s:3:"ﰛ";s:4:"خم";s:3:"ﰜ";s:4:"سج";s:3:"ﰝ";s:4:"سح";s:3:"ﰞ";s:4:"سخ";s:3:"ﰟ";s:4:"سم";s:3:"ﰠ";s:4:"صح";s:3:"ﰡ";s:4:"صم";s:3:"ﰢ";s:4:"ضج";s:3:"ﰣ";s:4:"ضح";s:3:"ﰤ";s:4:"ضخ";s:3:"ﰥ";s:4:"ضم";s:3:"ﰦ";s:4:"طح";s:3:"ﰧ";s:4:"طم";s:3:"ﰨ";s:4:"ظم";s:3:"ﰩ";s:4:"عج";s:3:"ﰪ";s:4:"عم";s:3:"ﰫ";s:4:"غج";s:3:"ﰬ";s:4:"غم";s:3:"ﰭ";s:4:"فج";s:3:"ﰮ";s:4:"فح";s:3:"ﰯ";s:4:"فخ";s:3:"ﰰ";s:4:"فم";s:3:"ﰱ";s:4:"فى";s:3:"ﰲ";s:4:"في";s:3:"ﰳ";s:4:"قح";s:3:"ﰴ";s:4:"قم";s:3:"ﰵ";s:4:"قى";s:3:"ﰶ";s:4:"قي";s:3:"ﰷ";s:4:"كا";s:3:"ﰸ";s:4:"كج";s:3:"ﰹ";s:4:"كح";s:3:"ﰺ";s:4:"كخ";s:3:"ﰻ";s:4:"كل";s:3:"ﰼ";s:4:"كم";s:3:"ﰽ";s:4:"كى";s:3:"ﰾ";s:4:"كي";s:3:"ﰿ";s:4:"لج";s:3:"ﱀ";s:4:"لح";s:3:"ﱁ";s:4:"لخ";s:3:"ﱂ";s:4:"لم";s:3:"ﱃ";s:4:"لى";s:3:"ﱄ";s:4:"لي";s:3:"ﱅ";s:4:"مج";s:3:"ﱆ";s:4:"مح";s:3:"ﱇ";s:4:"مخ";s:3:"ﱈ";s:4:"مم";s:3:"ﱉ";s:4:"مى";s:3:"ﱊ";s:4:"مي";s:3:"ﱋ";s:4:"نج";s:3:"ﱌ";s:4:"نح";s:3:"ﱍ";s:4:"نخ";s:3:"ﱎ";s:4:"نم";s:3:"ﱏ";s:4:"نى";s:3:"ﱐ";s:4:"ني";s:3:"ﱑ";s:4:"هج";s:3:"ﱒ";s:4:"هم";s:3:"ﱓ";s:4:"هى";s:3:"ﱔ";s:4:"هي";s:3:"ﱕ";s:4:"يج";s:3:"ﱖ";s:4:"يح";s:3:"ﱗ";s:4:"يخ";s:3:"ﱘ";s:4:"يم";s:3:"ﱙ";s:4:"يى";s:3:"ﱚ";s:4:"يي";s:3:"ﱛ";s:4:"ذٰ";s:3:"ﱜ";s:4:"رٰ";s:3:"ﱝ";s:4:"ىٰ";s:3:"ﱞ";s:5:" ٌّ";s:3:"ﱟ";s:5:" ٍّ";s:3:"ﱠ";s:5:" َّ";s:3:"ﱡ";s:5:" ُّ";s:3:"ﱢ";s:5:" ِّ";s:3:"ﱣ";s:5:" ّٰ";s:3:"ﱤ";s:4:"ئر";s:3:"ﱥ";s:4:"ئز";s:3:"ﱦ";s:4:"ئم";s:3:"ﱧ";s:4:"ئن";s:3:"ﱨ";s:4:"ئى";s:3:"ﱩ";s:4:"ئي";s:3:"ﱪ";s:4:"بر";s:3:"ﱫ";s:4:"بز";s:3:"ﱬ";s:4:"بم";s:3:"ﱭ";s:4:"بن";s:3:"ﱮ";s:4:"بى";s:3:"ﱯ";s:4:"بي";s:3:"ﱰ";s:4:"تر";s:3:"ﱱ";s:4:"تز";s:3:"ﱲ";s:4:"تم";s:3:"ﱳ";s:4:"تن";s:3:"ﱴ";s:4:"تى";s:3:"ﱵ";s:4:"تي";s:3:"ﱶ";s:4:"ثر";s:3:"ﱷ";s:4:"ثز";s:3:"ﱸ";s:4:"ثم";s:3:"ﱹ";s:4:"ثن";s:3:"ﱺ";s:4:"ثى";s:3:"ﱻ";s:4:"ثي";s:3:"ﱼ";s:4:"فى";s:3:"ﱽ";s:4:"في";s:3:"ﱾ";s:4:"قى";s:3:"ﱿ";s:4:"قي";s:3:"ﲀ";s:4:"كا";s:3:"ﲁ";s:4:"كل";s:3:"ﲂ";s:4:"كم";s:3:"ﲃ";s:4:"كى";s:3:"ﲄ";s:4:"كي";s:3:"ﲅ";s:4:"لم";s:3:"ﲆ";s:4:"لى";s:3:"ﲇ";s:4:"لي";s:3:"ﲈ";s:4:"ما";s:3:"ﲉ";s:4:"مم";s:3:"ﲊ";s:4:"نر";s:3:"ﲋ";s:4:"نز";s:3:"ﲌ";s:4:"نم";s:3:"ﲍ";s:4:"نن";s:3:"ﲎ";s:4:"نى";s:3:"ﲏ";s:4:"ني";s:3:"ﲐ";s:4:"ىٰ";s:3:"ﲑ";s:4:"ير";s:3:"ﲒ";s:4:"يز";s:3:"ﲓ";s:4:"يم";s:3:"ﲔ";s:4:"ين";s:3:"ﲕ";s:4:"يى";s:3:"ﲖ";s:4:"يي";s:3:"ﲗ";s:4:"ئج";s:3:"ﲘ";s:4:"ئح";s:3:"ﲙ";s:4:"ئخ";s:3:"ﲚ";s:4:"ئم";s:3:"ﲛ";s:4:"ئه";s:3:"ﲜ";s:4:"بج";s:3:"ﲝ";s:4:"بح";s:3:"ﲞ";s:4:"بخ";s:3:"ﲟ";s:4:"بم";s:3:"ﲠ";s:4:"به";s:3:"ﲡ";s:4:"تج";s:3:"ﲢ";s:4:"تح";s:3:"ﲣ";s:4:"تخ";s:3:"ﲤ";s:4:"تم";s:3:"ﲥ";s:4:"ته";s:3:"ﲦ";s:4:"ثم";s:3:"ﲧ";s:4:"جح";s:3:"ﲨ";s:4:"جم";s:3:"ﲩ";s:4:"حج";s:3:"ﲪ";s:4:"حم";s:3:"ﲫ";s:4:"خج";s:3:"ﲬ";s:4:"خم";s:3:"ﲭ";s:4:"سج";s:3:"ﲮ";s:4:"سح";s:3:"ﲯ";s:4:"سخ";s:3:"ﲰ";s:4:"سم";s:3:"ﲱ";s:4:"صح";s:3:"ﲲ";s:4:"صخ";s:3:"ﲳ";s:4:"صم";s:3:"ﲴ";s:4:"ضج";s:3:"ﲵ";s:4:"ضح";s:3:"ﲶ";s:4:"ضخ";s:3:"ﲷ";s:4:"ضم";s:3:"ﲸ";s:4:"طح";s:3:"ﲹ";s:4:"ظم";s:3:"ﲺ";s:4:"عج";s:3:"ﲻ";s:4:"عم";s:3:"ﲼ";s:4:"غج";s:3:"ﲽ";s:4:"غم";s:3:"ﲾ";s:4:"فج";s:3:"ﲿ";s:4:"فح";s:3:"ﳀ";s:4:"فخ";s:3:"ﳁ";s:4:"فم";s:3:"ﳂ";s:4:"قح";s:3:"ﳃ";s:4:"قم";s:3:"ﳄ";s:4:"كج";s:3:"ﳅ";s:4:"كح";s:3:"ﳆ";s:4:"كخ";s:3:"ﳇ";s:4:"كل";s:3:"ﳈ";s:4:"كم";s:3:"ﳉ";s:4:"لج";s:3:"ﳊ";s:4:"لح";s:3:"ﳋ";s:4:"لخ";s:3:"ﳌ";s:4:"لم";s:3:"ﳍ";s:4:"له";s:3:"ﳎ";s:4:"مج";s:3:"ﳏ";s:4:"مح";s:3:"ﳐ";s:4:"مخ";s:3:"ﳑ";s:4:"مم";s:3:"ﳒ";s:4:"نج";s:3:"ﳓ";s:4:"نح";s:3:"ﳔ";s:4:"نخ";s:3:"ﳕ";s:4:"نم";s:3:"ﳖ";s:4:"نه";s:3:"ﳗ";s:4:"هج";s:3:"ﳘ";s:4:"هم";s:3:"ﳙ";s:4:"هٰ";s:3:"ﳚ";s:4:"يج";s:3:"ﳛ";s:4:"يح";s:3:"ﳜ";s:4:"يخ";s:3:"ﳝ";s:4:"يم";s:3:"ﳞ";s:4:"يه";s:3:"ﳟ";s:4:"ئم";s:3:"ﳠ";s:4:"ئه";s:3:"ﳡ";s:4:"بم";s:3:"ﳢ";s:4:"به";s:3:"ﳣ";s:4:"تم";s:3:"ﳤ";s:4:"ته";s:3:"ﳥ";s:4:"ثم";s:3:"ﳦ";s:4:"ثه";s:3:"ﳧ";s:4:"سم";s:3:"ﳨ";s:4:"سه";s:3:"ﳩ";s:4:"شم";s:3:"ﳪ";s:4:"شه";s:3:"ﳫ";s:4:"كل";s:3:"ﳬ";s:4:"كم";s:3:"ﳭ";s:4:"لم";s:3:"ﳮ";s:4:"نم";s:3:"ﳯ";s:4:"نه";s:3:"ﳰ";s:4:"يم";s:3:"ﳱ";s:4:"يه";s:3:"ﳲ";s:6:"ـَّ";s:3:"ﳳ";s:6:"ـُّ";s:3:"ﳴ";s:6:"ـِّ";s:3:"ﳵ";s:4:"طى";s:3:"ﳶ";s:4:"طي";s:3:"ﳷ";s:4:"عى";s:3:"ﳸ";s:4:"عي";s:3:"ﳹ";s:4:"غى";s:3:"ﳺ";s:4:"غي";s:3:"ﳻ";s:4:"سى";s:3:"ﳼ";s:4:"سي";s:3:"ﳽ";s:4:"شى";s:3:"ﳾ";s:4:"شي";s:3:"ﳿ";s:4:"حى";s:3:"ﴀ";s:4:"حي";s:3:"ﴁ";s:4:"جى";s:3:"ﴂ";s:4:"جي";s:3:"ﴃ";s:4:"خى";s:3:"ﴄ";s:4:"خي";s:3:"ﴅ";s:4:"صى";s:3:"ﴆ";s:4:"صي";s:3:"ﴇ";s:4:"ضى";s:3:"ﴈ";s:4:"ضي";s:3:"ﴉ";s:4:"شج";s:3:"ﴊ";s:4:"شح";s:3:"ﴋ";s:4:"شخ";s:3:"ﴌ";s:4:"شم";s:3:"ﴍ";s:4:"شر";s:3:"ﴎ";s:4:"سر";s:3:"ﴏ";s:4:"صر";s:3:"ﴐ";s:4:"ضر";s:3:"ﴑ";s:4:"طى";s:3:"ﴒ";s:4:"طي";s:3:"ﴓ";s:4:"عى";s:3:"ﴔ";s:4:"عي";s:3:"ﴕ";s:4:"غى";s:3:"ﴖ";s:4:"غي";s:3:"ﴗ";s:4:"سى";s:3:"ﴘ";s:4:"سي";s:3:"ﴙ";s:4:"شى";s:3:"ﴚ";s:4:"شي";s:3:"ﴛ";s:4:"حى";s:3:"ﴜ";s:4:"حي";s:3:"ﴝ";s:4:"جى";s:3:"ﴞ";s:4:"جي";s:3:"ﴟ";s:4:"خى";s:3:"ﴠ";s:4:"خي";s:3:"ﴡ";s:4:"صى";s:3:"ﴢ";s:4:"صي";s:3:"ﴣ";s:4:"ضى";s:3:"ﴤ";s:4:"ضي";s:3:"ﴥ";s:4:"شج";s:3:"ﴦ";s:4:"شح";s:3:"ﴧ";s:4:"شخ";s:3:"ﴨ";s:4:"شم";s:3:"ﴩ";s:4:"شر";s:3:"ﴪ";s:4:"سر";s:3:"ﴫ";s:4:"صر";s:3:"ﴬ";s:4:"ضر";s:3:"ﴭ";s:4:"شج";s:3:"ﴮ";s:4:"شح";s:3:"ﴯ";s:4:"شخ";s:3:"ﴰ";s:4:"شم";s:3:"ﴱ";s:4:"سه";s:3:"ﴲ";s:4:"شه";s:3:"ﴳ";s:4:"طم";s:3:"ﴴ";s:4:"سج";s:3:"ﴵ";s:4:"سح";s:3:"ﴶ";s:4:"سخ";s:3:"ﴷ";s:4:"شج";s:3:"ﴸ";s:4:"شح";s:3:"ﴹ";s:4:"شخ";s:3:"ﴺ";s:4:"طم";s:3:"ﴻ";s:4:"ظم";s:3:"ﴼ";s:4:"اً";s:3:"ﴽ";s:4:"اً";s:3:"ﵐ";s:6:"تجم";s:3:"ﵑ";s:6:"تحج";s:3:"ﵒ";s:6:"تحج";s:3:"ﵓ";s:6:"تحم";s:3:"ﵔ";s:6:"تخم";s:3:"ﵕ";s:6:"تمج";s:3:"ﵖ";s:6:"تمح";s:3:"ﵗ";s:6:"تمخ";s:3:"ﵘ";s:6:"جمح";s:3:"ﵙ";s:6:"جمح";s:3:"ﵚ";s:6:"حمي";s:3:"ﵛ";s:6:"حمى";s:3:"ﵜ";s:6:"سحج";s:3:"ﵝ";s:6:"سجح";s:3:"ﵞ";s:6:"سجى";s:3:"ﵟ";s:6:"سمح";s:3:"ﵠ";s:6:"سمح";s:3:"ﵡ";s:6:"سمج";s:3:"ﵢ";s:6:"سمم";s:3:"ﵣ";s:6:"سمم";s:3:"ﵤ";s:6:"صحح";s:3:"ﵥ";s:6:"صحح";s:3:"ﵦ";s:6:"صمم";s:3:"ﵧ";s:6:"شحم";s:3:"ﵨ";s:6:"شحم";s:3:"ﵩ";s:6:"شجي";s:3:"ﵪ";s:6:"شمخ";s:3:"ﵫ";s:6:"شمخ";s:3:"ﵬ";s:6:"شمم";s:3:"ﵭ";s:6:"شمم";s:3:"ﵮ";s:6:"ضحى";s:3:"ﵯ";s:6:"ضخم";s:3:"ﵰ";s:6:"ضخم";s:3:"ﵱ";s:6:"طمح";s:3:"ﵲ";s:6:"طمح";s:3:"ﵳ";s:6:"طمم";s:3:"ﵴ";s:6:"طمي";s:3:"ﵵ";s:6:"عجم";s:3:"ﵶ";s:6:"عمم";s:3:"ﵷ";s:6:"عمم";s:3:"ﵸ";s:6:"عمى";s:3:"ﵹ";s:6:"غمم";s:3:"ﵺ";s:6:"غمي";s:3:"ﵻ";s:6:"غمى";s:3:"ﵼ";s:6:"فخم";s:3:"ﵽ";s:6:"فخم";s:3:"ﵾ";s:6:"قمح";s:3:"ﵿ";s:6:"قمم";s:3:"ﶀ";s:6:"لحم";s:3:"ﶁ";s:6:"لحي";s:3:"ﶂ";s:6:"لحى";s:3:"ﶃ";s:6:"لجج";s:3:"ﶄ";s:6:"لجج";s:3:"ﶅ";s:6:"لخم";s:3:"ﶆ";s:6:"لخم";s:3:"ﶇ";s:6:"لمح";s:3:"ﶈ";s:6:"لمح";s:3:"ﶉ";s:6:"محج";s:3:"ﶊ";s:6:"محم";s:3:"ﶋ";s:6:"محي";s:3:"ﶌ";s:6:"مجح";s:3:"ﶍ";s:6:"مجم";s:3:"ﶎ";s:6:"مخج";s:3:"ﶏ";s:6:"مخم";s:3:"ﶒ";s:6:"مجخ";s:3:"ﶓ";s:6:"همج";s:3:"ﶔ";s:6:"همم";s:3:"ﶕ";s:6:"نحم";s:3:"ﶖ";s:6:"نحى";s:3:"ﶗ";s:6:"نجم";s:3:"ﶘ";s:6:"نجم";s:3:"ﶙ";s:6:"نجى";s:3:"ﶚ";s:6:"نمي";s:3:"ﶛ";s:6:"نمى";s:3:"ﶜ";s:6:"يمم";s:3:"ﶝ";s:6:"يمم";s:3:"ﶞ";s:6:"بخي";s:3:"ﶟ";s:6:"تجي";s:3:"ﶠ";s:6:"تجى";s:3:"ﶡ";s:6:"تخي";s:3:"ﶢ";s:6:"تخى";s:3:"ﶣ";s:6:"تمي";s:3:"ﶤ";s:6:"تمى";s:3:"ﶥ";s:6:"جمي";s:3:"ﶦ";s:6:"جحى";s:3:"ﶧ";s:6:"جمى";s:3:"ﶨ";s:6:"سخى";s:3:"ﶩ";s:6:"صحي";s:3:"ﶪ";s:6:"شحي";s:3:"ﶫ";s:6:"ضحي";s:3:"ﶬ";s:6:"لجي";s:3:"ﶭ";s:6:"لمي";s:3:"ﶮ";s:6:"يحي";s:3:"ﶯ";s:6:"يجي";s:3:"ﶰ";s:6:"يمي";s:3:"ﶱ";s:6:"ممي";s:3:"ﶲ";s:6:"قمي";s:3:"ﶳ";s:6:"نحي";s:3:"ﶴ";s:6:"قمح";s:3:"ﶵ";s:6:"لحم";s:3:"ﶶ";s:6:"عمي";s:3:"ﶷ";s:6:"كمي";s:3:"ﶸ";s:6:"نجح";s:3:"ﶹ";s:6:"مخي";s:3:"ﶺ";s:6:"لجم";s:3:"ﶻ";s:6:"كمم";s:3:"ﶼ";s:6:"لجم";s:3:"ﶽ";s:6:"نجح";s:3:"ﶾ";s:6:"جحي";s:3:"ﶿ";s:6:"حجي";s:3:"ﷀ";s:6:"مجي";s:3:"ﷁ";s:6:"فمي";s:3:"ﷂ";s:6:"بحي";s:3:"ﷃ";s:6:"كمم";s:3:"ﷄ";s:6:"عجم";s:3:"ﷅ";s:6:"صمم";s:3:"ﷆ";s:6:"سخي";s:3:"ﷇ";s:6:"نجي";s:3:"ﷰ";s:6:"صلے";s:3:"ﷱ";s:6:"قلے";s:3:"ﷲ";s:8:"الله";s:3:"ﷳ";s:8:"اكبر";s:3:"ﷴ";s:8:"محمد";s:3:"ﷵ";s:8:"صلعم";s:3:"ﷶ";s:8:"رسول";s:3:"ﷷ";s:8:"عليه";s:3:"ﷸ";s:8:"وسلم";s:3:"ﷹ";s:6:"صلى";s:3:"ﷺ";s:33:"صلى الله عليه وسلم";s:3:"ﷻ";s:15:"جل جلاله";s:3:"﷼";s:8:"ریال";s:3:"ﹰ";s:3:" ً";s:3:"ﹱ";s:4:"ـً";s:3:"ﹲ";s:3:" ٌ";s:3:"ﹴ";s:3:" ٍ";s:3:"ﹶ";s:3:" َ";s:3:"ﹷ";s:4:"ـَ";s:3:"ﹸ";s:3:" ُ";s:3:"ﹹ";s:4:"ـُ";s:3:"ﹺ";s:3:" ِ";s:3:"ﹻ";s:4:"ـِ";s:3:"ﹼ";s:3:" ّ";s:3:"ﹽ";s:4:"ـّ";s:3:"ﹾ";s:3:" ْ";s:3:"ﹿ";s:4:"ـْ";s:3:"ﺀ";s:2:"ء";s:3:"ﺁ";s:2:"آ";s:3:"ﺂ";s:2:"آ";s:3:"ﺃ";s:2:"أ";s:3:"ﺄ";s:2:"أ";s:3:"ﺅ";s:2:"ؤ";s:3:"ﺆ";s:2:"ؤ";s:3:"ﺇ";s:2:"إ";s:3:"ﺈ";s:2:"إ";s:3:"ﺉ";s:2:"ئ";s:3:"ﺊ";s:2:"ئ";s:3:"ﺋ";s:2:"ئ";s:3:"ﺌ";s:2:"ئ";s:3:"ﺍ";s:2:"ا";s:3:"ﺎ";s:2:"ا";s:3:"ﺏ";s:2:"ب";s:3:"ﺐ";s:2:"ب";s:3:"ﺑ";s:2:"ب";s:3:"ﺒ";s:2:"ب";s:3:"ﺓ";s:2:"ة";s:3:"ﺔ";s:2:"ة";s:3:"ﺕ";s:2:"ت";s:3:"ﺖ";s:2:"ت";s:3:"ﺗ";s:2:"ت";s:3:"ﺘ";s:2:"ت";s:3:"ﺙ";s:2:"ث";s:3:"ﺚ";s:2:"ث";s:3:"ﺛ";s:2:"ث";s:3:"ﺜ";s:2:"ث";s:3:"ﺝ";s:2:"ج";s:3:"ﺞ";s:2:"ج";s:3:"ﺟ";s:2:"ج";s:3:"ﺠ";s:2:"ج";s:3:"ﺡ";s:2:"ح";s:3:"ﺢ";s:2:"ح";s:3:"ﺣ";s:2:"ح";s:3:"ﺤ";s:2:"ح";s:3:"ﺥ";s:2:"خ";s:3:"ﺦ";s:2:"خ";s:3:"ﺧ";s:2:"خ";s:3:"ﺨ";s:2:"خ";s:3:"ﺩ";s:2:"د";s:3:"ﺪ";s:2:"د";s:3:"ﺫ";s:2:"ذ";s:3:"ﺬ";s:2:"ذ";s:3:"ﺭ";s:2:"ر";s:3:"ﺮ";s:2:"ر";s:3:"ﺯ";s:2:"ز";s:3:"ﺰ";s:2:"ز";s:3:"ﺱ";s:2:"س";s:3:"ﺲ";s:2:"س";s:3:"ﺳ";s:2:"س";s:3:"ﺴ";s:2:"س";s:3:"ﺵ";s:2:"ش";s:3:"ﺶ";s:2:"ش";s:3:"ﺷ";s:2:"ش";s:3:"ﺸ";s:2:"ش";s:3:"ﺹ";s:2:"ص";s:3:"ﺺ";s:2:"ص";s:3:"ﺻ";s:2:"ص";s:3:"ﺼ";s:2:"ص";s:3:"ﺽ";s:2:"ض";s:3:"ﺾ";s:2:"ض";s:3:"ﺿ";s:2:"ض";s:3:"ﻀ";s:2:"ض";s:3:"ﻁ";s:2:"ط";s:3:"ﻂ";s:2:"ط";s:3:"ﻃ";s:2:"ط";s:3:"ﻄ";s:2:"ط";s:3:"ﻅ";s:2:"ظ";s:3:"ﻆ";s:2:"ظ";s:3:"ﻇ";s:2:"ظ";s:3:"ﻈ";s:2:"ظ";s:3:"ﻉ";s:2:"ع";s:3:"ﻊ";s:2:"ع";s:3:"ﻋ";s:2:"ع";s:3:"ﻌ";s:2:"ع";s:3:"ﻍ";s:2:"غ";s:3:"ﻎ";s:2:"غ";s:3:"ﻏ";s:2:"غ";s:3:"ﻐ";s:2:"غ";s:3:"ﻑ";s:2:"ف";s:3:"ﻒ";s:2:"ف";s:3:"ﻓ";s:2:"ف";s:3:"ﻔ";s:2:"ف";s:3:"ﻕ";s:2:"ق";s:3:"ﻖ";s:2:"ق";s:3:"ﻗ";s:2:"ق";s:3:"ﻘ";s:2:"ق";s:3:"ﻙ";s:2:"ك";s:3:"ﻚ";s:2:"ك";s:3:"ﻛ";s:2:"ك";s:3:"ﻜ";s:2:"ك";s:3:"ﻝ";s:2:"ل";s:3:"ﻞ";s:2:"ل";s:3:"ﻟ";s:2:"ل";s:3:"ﻠ";s:2:"ل";s:3:"ﻡ";s:2:"م";s:3:"ﻢ";s:2:"م";s:3:"ﻣ";s:2:"م";s:3:"ﻤ";s:2:"م";s:3:"ﻥ";s:2:"ن";s:3:"ﻦ";s:2:"ن";s:3:"ﻧ";s:2:"ن";s:3:"ﻨ";s:2:"ن";s:3:"ﻩ";s:2:"ه";s:3:"ﻪ";s:2:"ه";s:3:"ﻫ";s:2:"ه";s:3:"ﻬ";s:2:"ه";s:3:"ﻭ";s:2:"و";s:3:"ﻮ";s:2:"و";s:3:"ﻯ";s:2:"ى";s:3:"ﻰ";s:2:"ى";s:3:"ﻱ";s:2:"ي";s:3:"ﻲ";s:2:"ي";s:3:"ﻳ";s:2:"ي";s:3:"ﻴ";s:2:"ي";s:3:"ﻵ";s:4:"لآ";s:3:"ﻶ";s:4:"لآ";s:3:"ﻷ";s:4:"لأ";s:3:"ﻸ";s:4:"لأ";s:3:"ﻹ";s:4:"لإ";s:3:"ﻺ";s:4:"لإ";s:3:"ﻻ";s:4:"لا";s:3:"ﻼ";s:4:"لا";}
\ No newline at end of file
diff --git a/serialized/normalize-ml.ser b/serialized/normalize-ml.ser
deleted file mode 100644 (file)
index b27a217..0000000
+++ /dev/null
@@ -1 +0,0 @@
-a:6:{s:9:"ണ്‍";s:3:"ൺ";s:9:"ന്‍";s:3:"ൻ";s:9:"ര്‍";s:3:"ർ";s:9:"ല്‍";s:3:"ൽ";s:9:"ള്‍";s:3:"ൾ";s:9:"ക്‍";s:3:"ൿ";}
\ No newline at end of file
index abf718d..0cb042a 100644 (file)
@@ -67,6 +67,7 @@ $wgAutoloadClasses += [
        'HamcrestPHPUnitIntegration' => "$testDir/phpunit/HamcrestPHPUnitIntegration.php",
 
        # tests/phpunit/includes
+       'PageArchiveTestBase' => "$testDir/phpunit/includes/page/PageArchiveTestBase.php",
        'RevisionDbTestBase' => "$testDir/phpunit/includes/RevisionDbTestBase.php",
        'RevisionTestModifyableContent' => "$testDir/phpunit/includes/RevisionTestModifyableContent.php",
        'RevisionTestModifyableContentHandler' => "$testDir/phpunit/includes/RevisionTestModifyableContentHandler.php",
@@ -108,6 +109,10 @@ $wgAutoloadClasses += [
        # tests/phpunit/includes/db
        'DatabaseTestHelper' => "$testDir/phpunit/includes/db/DatabaseTestHelper.php",
 
+       # tests/phpunit/includes/debug
+       'TestDeprecatedClass' => "$testDir/phpunit/includes/debug/TestDeprecatedClass.php",
+       'TestDeprecatedSubclass' => "$testDir/phpunit/includes/debug/TestDeprecatedSubclass.php",
+
        # tests/phpunit/includes/diff
        'FakeDiffOp' => "$testDir/phpunit/includes/diff/FakeDiffOp.php",
 
@@ -149,8 +154,14 @@ $wgAutoloadClasses += [
        'SpecialPageExecutor' => "$testDir/phpunit/includes/specials/SpecialPageExecutor.php",
 
        # tests/phpunit/includes/Storage
+       'MediaWiki\Tests\Storage\McrSchemaDetection' => "$testDir/phpunit/includes/Storage/McrSchemaDetection.php",
+       'MediaWiki\Tests\Storage\McrSchemaOverride' => "$testDir/phpunit/includes/Storage/McrSchemaOverride.php",
+       'MediaWiki\Tests\Storage\McrWriteBothSchemaOverride' => "$testDir/phpunit/includes/Storage/McrWriteBothSchemaOverride.php",
+       'MediaWiki\Tests\Storage\McrReadNewSchemaOverride' => "$testDir/phpunit/includes/Storage/McrReadNewSchemaOverride.php",
        'MediaWiki\Tests\Storage\RevisionSlotsTest' => "$testDir/phpunit/includes/Storage/RevisionSlotsTest.php",
        'MediaWiki\Tests\Storage\RevisionRecordTests' => "$testDir/phpunit/includes/Storage/RevisionRecordTests.php",
+       'MediaWiki\Tests\Storage\RevisionStoreDbTestBase' => "$testDir/phpunit/includes/Storage/RevisionStoreDbTestBase.php",
+       'MediaWiki\Tests\Storage\PreMcrSchemaOverride' => "$testDir/phpunit/includes/Storage/PreMcrSchemaOverride.php",
 
        # tests/phpunit/languages
        'LanguageClassesTestCase' => "$testDir/phpunit/languages/LanguageClassesTestCase.php",
@@ -181,6 +192,10 @@ $wgAutoloadClasses += [
                => "$testDir/phpunit/mocks/session/DummySessionBackend.php",
        'DummySessionProvider' => "$testDir/phpunit/mocks/session/DummySessionProvider.php",
        'MockMessageLocalizer' => "$testDir/phpunit/mocks/MockMessageLocalizer.php",
+       'MockCompletionSearchEngine' => "$testDir/phpunit/mocks/search/MockCompletionSearchEngine.php",
+       'MockSearchEngine' => "$testDir/phpunit/mocks/search/MockSearchEngine.php",
+       'MockSearchResultSet' => "$testDir/phpunit/mocks/search/MockSearchResultSet.php",
+       'MockSearchResult' => "$testDir/phpunit/mocks/search/MockSearchResult.php",
 
        # tests/suites
        'ParserTestFileSuite' => "$testDir/phpunit/suites/ParserTestFileSuite.php",
index 1e008ee..4730005 100644 (file)
@@ -16,7 +16,9 @@ class FirejailCommandIntegrationTest extends PHPUnit\Framework\TestCase {
 
        public function setUp() {
                parent::setUp();
-               if ( Shell::command( 'which', 'firejail' )->execute()->getExitCode() ) {
+               if ( Shell::isDisabled() ) {
+                       $this->markTestSkipped( 'shelling out is disabled' );
+               } elseif ( Shell::command( 'which', 'firejail' )->execute()->getExitCode() ) {
                        $this->markTestSkipped( 'firejail not installed' );
                } elseif ( wfIsWindows() ) {
                        $this->markTestSkipped( 'test supports POSIX environments only' );
index f68f595..2089f64 100644 (file)
@@ -41,7 +41,8 @@ class DbTestRecorder extends TestRecorder {
                        || !$this->db->tableExists( 'testitem' )
                ) {
                        print "WARNING> `testrun` table not found in database. Trying to create table.\n";
-                       $this->db->sourceFile( $this->db->patchPath( 'patch-testrun.sql' ) );
+                       $updater = DatabaseUpdater::newForDB( $this->db );
+                       $this->db->sourceFile( $updater->patchPath( $this->db, 'patch-testrun.sql' ) );
                        echo "OK, resuming.\n";
                }
 
index 73d4a47..eede54e 100644 (file)
@@ -31,10 +31,10 @@ class DjVuSupport {
        public function __construct() {
                global $wgDjvuRenderer, $wgDjvuDump, $wgDjvuToXML, $wgFileExtensions, $wgDjvuTxt;
 
-               $wgDjvuRenderer = $wgDjvuRenderer ? $wgDjvuRenderer : '/usr/bin/ddjvu';
-               $wgDjvuDump = $wgDjvuDump ? $wgDjvuDump : '/usr/bin/djvudump';
-               $wgDjvuToXML = $wgDjvuToXML ? $wgDjvuToXML : '/usr/bin/djvutoxml';
-               $wgDjvuTxt = $wgDjvuTxt ? $wgDjvuTxt : '/usr/bin/djvutxt';
+               $wgDjvuRenderer = $wgDjvuRenderer ?: '/usr/bin/ddjvu';
+               $wgDjvuDump = $wgDjvuDump ?: '/usr/bin/djvudump';
+               $wgDjvuToXML = $wgDjvuToXML ?: '/usr/bin/djvutoxml';
+               $wgDjvuTxt = $wgDjvuTxt ?: '/usr/bin/djvutxt';
 
                if ( !in_array( 'djvu', $wgFileExtensions ) ) {
                        $wgFileExtensions[] = 'djvu';
index 08ec9f6..26e4e9f 100644 (file)
@@ -116,6 +116,30 @@ class ParserTestRunner {
         */
        private $normalizationFunctions = [];
 
+       /**
+        * Run disabled parser tests
+        * @var bool
+        */
+       private $runDisabled;
+
+       /**
+        * Run tests intended only for parsoid
+        * @var bool
+        */
+       private $runParsoid;
+
+       /**
+        * Disable parse on article insertion
+        * @var bool
+        */
+       private $disableSaveParse;
+
+       /**
+        * Reuse upload directory
+        * @var bool
+        */
+       private $keepUploads;
+
        /**
         * @param TestRecorder $recorder
         * @param array $options
@@ -143,12 +167,13 @@ class ParserTestRunner {
 
                $this->keepUploads = !empty( $options['keep-uploads'] );
 
-               $this->fileBackendName = isset( $options['file-backend'] ) ?
-                       $options['file-backend'] : false;
+               $this->fileBackendName = $options['file-backend'] ?? false;
 
                $this->runDisabled = !empty( $options['run-disabled'] );
                $this->runParsoid = !empty( $options['run-parsoid'] );
 
+               $this->disableSaveParse = !empty( $options['disable-save-parse'] );
+
                $this->tidySupport = new TidySupport( !empty( $options['use-tidy-config'] ) );
                if ( !$this->tidySupport->isEnabled() ) {
                        $this->recorder->warning(
@@ -465,7 +490,7 @@ class ParserTestRunner {
                        if ( is_int( $name ) ) {
                                $value();
                        } else {
-                               $saved[$name] = isset( $GLOBALS[$name] ) ? $GLOBALS[$name] : null;
+                               $saved[$name] = $GLOBALS[$name] ?? null;
                                $GLOBALS[$name] = $value;
                        }
                }
@@ -537,7 +562,7 @@ class ParserTestRunner {
         * @return bool
         */
        public function isSetupDone( $funcName ) {
-               return isset( $this->setupDone[$funcName] ) ? $this->setupDone[$funcName] : false;
+               return $this->setupDone[$funcName] ?? false;
        }
 
        /**
@@ -774,7 +799,7 @@ class ParserTestRunner {
        /**
         * Get a Parser object
         *
-        * @param string $preprocessor
+        * @param string|null $preprocessor
         * @return Parser
         */
        function getParser( $preprocessor = null ) {
@@ -829,8 +854,15 @@ class ParserTestRunner {
                        $titleText = 'Parser test';
                }
 
+               if ( isset( $opts['maxincludesize'] ) ) {
+                       $options->setMaxIncludeSize( $opts['maxincludesize'] );
+               }
+               if ( isset( $opts['maxtemplatedepth'] ) ) {
+                       $options->setMaxTemplateDepth( $opts['maxtemplatedepth'] );
+               }
+
                $local = isset( $opts['local'] );
-               $preprocessor = isset( $opts['preprocessor'] ) ? $opts['preprocessor'] : null;
+               $preprocessor = $opts['preprocessor'] ?? null;
                $parser = $this->getParser( $preprocessor );
                $title = Title::newFromText( $titleText );
 
@@ -1083,6 +1115,11 @@ class ParserTestRunner {
                        'wgFragmentMode' => [ 'legacy' ],
                ];
 
+               $nonIncludable = self::getOptionValue( 'wgNonincludableNamespaces', $opts, false );
+               if ( $nonIncludable !== false ) {
+                       $setup['wgNonincludableNamespaces'] = [ $nonIncludable ];
+               }
+
                if ( $config ) {
                        $configLines = explode( "\n", $config );
 
@@ -1115,7 +1152,7 @@ class ParserTestRunner {
                $lang->resetNamespaces();
                $setup['wgContLang'] = $lang;
                $reset = function () {
-                       MagicWord::clearCache();
+                       MediaWikiServices::getInstance()->resetServiceForTesting( 'MagicWordFactory' );
                        $this->resetTitleServices();
                };
                $setup[] = $reset;
@@ -1173,7 +1210,8 @@ class ParserTestRunner {
                        'site_stats', 'ipblocks', 'image', 'oldimage',
                        'recentchanges', 'watchlist', 'interwiki', 'logging', 'log_search',
                        'querycache', 'objectcache', 'job', 'l10n_cache', 'redirect', 'querycachetwo',
-                       'archive', 'user_groups', 'page_props', 'category'
+                       'archive', 'user_groups', 'page_props', 'category',
+                       'slots', 'content', 'slot_roles', 'content_models',
                ];
 
                if ( $wgCommentTableSchemaMigrationStage >= MIGRATION_WRITE_BOTH ) {
@@ -1212,7 +1250,7 @@ class ParserTestRunner {
         * For best performance, call this once only for all tests. However, it can
         * be called at the start of each test if more isolation is desired.
         *
-        * @todo: This is basically an unrefactored copy of
+        * @todo This is basically an unrefactored copy of
         * MediaWikiTestCase::setupAllTestDBs. They should be factored out somehow.
         *
         * Do not call this function from a MediaWikiTestCase subclass, since
@@ -1253,6 +1291,7 @@ class ParserTestRunner {
                $this->dbClone = new CloneDatabase( $this->db, $this->listTables(), $prefix );
                $this->dbClone->useTemporaryTables( $temporary );
                $this->dbClone->cloneTableStructure();
+               CloneDatabase::changePrefix( $prefix );
 
                if ( $dbType == 'oracle' ) {
                        $this->db->query( 'BEGIN FILL_WIKI_INFO; END;' );
@@ -1270,7 +1309,7 @@ class ParserTestRunner {
 
                // Wipe some DB query result caches on setup and teardown
                $reset = function () {
-                       LinkCache::singleton()->clear();
+                       MediaWikiServices::getInstance()->getLinkCache()->clear();
 
                        // Clear the message cache
                        MessageCache::singleton()->clear();
@@ -1439,7 +1478,6 @@ class ParserTestRunner {
                $this->checkSetupDone( 'setupDatabase' );
 
                $this->dbClone->destroy();
-               $this->databaseSetupDone = false;
 
                if ( $this->useTemporaryTables ) {
                        if ( $this->db->getType() == 'sqlite' ) {
@@ -1639,11 +1677,15 @@ class ParserTestRunner {
                        );
                }
 
-               // Use mock parser, to make debugging of actual parser tests simpler.
+               // Optionally use mock parser, to make debugging of actual parser tests simpler.
                // But initialise the MessageCache clone first, don't let MessageCache
                // get a reference to the mock object.
-               MessageCache::singleton()->getParser();
-               $restore = $this->executeSetupSnippets( [ 'wgParser' => new ParserTestMockParser ] );
+               if ( $this->disableSaveParse ) {
+                       MessageCache::singleton()->getParser();
+                       $restore = $this->executeSetupSnippets( [ 'wgParser' => new ParserTestMockParser ] );
+               } else {
+                       $restore = false;
+               }
                try {
                        $status = $page->doEditContent(
                                $newContent,
@@ -1651,7 +1693,9 @@ class ParserTestRunner {
                                EDIT_NEW | EDIT_INTERNAL
                        );
                } finally {
-                       $restore();
+                       if ( $restore ) {
+                               $restore();
+                       }
                }
 
                if ( !$status->isOK() ) {
index 6a423d5..e1d943f 100644 (file)
@@ -62,6 +62,8 @@ class ParserTestsMaintenance extends Maintenance {
                        'be used.', false, true );
                $this->addOption( 'run-disabled', 'run disabled tests' );
                $this->addOption( 'run-parsoid', 'run parsoid tests (normally disabled)' );
+               $this->addOption( 'disable-save-parse', 'Don\'t run the parser when ' .
+                       'inserting articles into the database' );
                $this->addOption( 'dwdiff', 'Use dwdiff to display diff output' );
                $this->addOption( 'mark-ws', 'Mark whitespace in diffs by replacing it with symbols' );
                $this->addOption( 'norm', 'Apply a comma-separated list of normalization functions to ' .
@@ -180,6 +182,7 @@ class ParserTestsMaintenance extends Maintenance {
                        'keep-uploads' => $this->hasOption( 'keep-uploads' ),
                        'run-disabled' => $this->hasOption( 'run-disabled' ),
                        'run-parsoid' => $this->hasOption( 'run-parsoid' ),
+                       'disable-save-parse' => $this->hasOption( 'disable-save-parse' ),
                        'use-tidy-config' => $this->hasOption( 'use-tidy-config' ),
                        'file-backend' => $this->getOption( 'file-backend' ),
                        'upload-dir' => $this->getOption( 'upload-dir' ),
index d17fbbe..b151002 100644 (file)
@@ -62,6 +62,12 @@ Template:Foo
 FOO
 !!endarticle
 
+!! article
+Template:redirect to foo
+!! text
+#REDIRECT [[Template:Foo]]
+!! endarticle
+
 !! article
 Template:Blank
 !! text
@@ -109,6 +115,14 @@ Template:echo
 {{{1}}}
 !! endarticle
 
+!! article
+Template:echo3
+!! text
+{{{1}}}
+{{{1}}}
+{{{1}}}
+!! endarticle
+
 // For Serbian; localize Template namespace
 !! article
 Шаблон:Echo
@@ -128,6 +142,12 @@ Template:echo_with_div
 <div>{{{1}}}</div>
 !! endarticle
 
+!! article
+Template:echo with depth
+!! text
+{{echo|{{{1}}}}}
+!! endarticle
+
 !! article
 Template:blank_param
 !! text
@@ -237,7 +257,7 @@ Weirdo titles!
 !!article
 Template:Bullet
 !!text
-* Bar
+*Bar
 !!endarticle
 
 !!article
@@ -307,23 +327,31 @@ This is a simple paragraph.
 !! test
 Paragraphs with extra newline spacing
 !! wikitext
-foo
+a
 
-bar
+b (+2 nls)
 
 
-baz
+c (+3 nls)
+
 
 
+d (+4 nls)
 
-booz
+
+
+
+e (+5 nls)
 !! html
-<p>foo
-</p><p>bar
+<p>a
+</p><p>b (+2 nls)
 </p><p><br />
-baz
+c (+3 nls)
+</p><p><br />
+</p><p>d (+4 nls)
 </p><p><br />
-</p><p>booz
+</p><p><br />
+e (+5 nls)
 </p>
 !! end
 
@@ -495,7 +523,6 @@ Extra newlines followed by heading
 a
 
 
-
 =b=
 [[a]]
 
@@ -514,19 +541,89 @@ a
 !! end
 
 !! test
-Extra newlines between heading and content are swallowed
+Extra newlines between heading and content are swallowed (Parsoid does not)
 !! wikitext
 =b=
 
 
 
 [[a]]
-!! html
+!! html/php+tidy
 <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>
 <p><a href="/index.php?title=A&amp;action=edit&amp;redlink=1" class="new" title="A (page does not exist)">a</a>
 </p>
+!! html/parsoid
+<h1 id="b">b</h1>
+<p>
+<br></p>
+
+<p><a rel="mw:WikiLink" href="./A" title="A">a</a></p>
+!! end
+
+!! test
+Extra new lines before and after lists are preserved
+!! wikitext
+a
+
+
+*b
+
+
+c
+!! html/php+tidy
+<p>a
+</p><p><br />
+</p>
+<ul><li>b</li></ul>
+<p><br />
+c
+</p>
+!! html/parsoid
+<p>a</p>
+<p>
+<br></p>
+<ul><li>b</li></ul>
+<p>
+<br>
+c</p>
 !! end
 
+# Parsoid regression test
+!!test
+Multiple newlines after tables are converted to p-br-p tags
+!!options
+parsoid=wt2html,wt2wt
+!!wikitext
+{|
+|x
+|}
+
+
+
+
+=b=
+!!html/php+tidy
+<table>
+<tbody><tr>
+<td>x
+</td></tr></tbody></table>
+<p><br />
+</p><p><br />
+</p>
+<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>
+!!html/parsoid
+<table>
+<tbody>
+<tr>
+<td>x</td>
+</tr>
+</tbody>
+</table>
+<p><br/></p>
+<p><br/></p>
+<h1 id="b">b</h1>
+!!end
+
 !! test
 Heading with line break in nowiki
 !! options
@@ -1297,7 +1394,7 @@ Non-word characters don't terminate tag names (T19663, T42670, T54022)
 <s.foo> doesn't terminate </s.foo>
 
 <sub-ID#1>
-!! html
+!! html/php
 <p>&lt;blockquote|&gt;a&lt;/blockquote&gt;
 </p><p>&lt;b→&gt; doesn't terminate &lt;/b→&gt;
 </p><p>&lt;bä&gt; doesn't terminate &lt;/bä&gt;
@@ -1360,12 +1457,10 @@ parsoid=wt2html
 </b>
 
 <s.foo>s</s>
-!! html/php+tidy
+!! html+tidy
 <p class="mw-empty-elt">
 </p><p>&lt;s.foo&gt;s
 </p>
-!! html/parsoid
-<p>&lt;s.foo&gt;s</p>
 !! end
 
 ###
@@ -1825,6 +1920,39 @@ b
 </p>
 !! end
 
+!! test
+post-expand include size being exceeded
+!! options
+maxincludesize=20
+!! wikitext
+{{echo3|1234567890}}
+!! html
+<p><a href="/wiki/Template:Echo3" title="Template:Echo3">Template:Echo3</a><!-- WARNING: template omitted, post-expand include size too large -->
+</p>
+!! end
+
+!! test
+max template depth being reached
+!! options
+maxtemplatedepth=1
+!! wikitext
+{{echo with depth|too deep!}}
+!! html
+<p><span class="error">Template recursion depth limit exceeded (1)</span>
+</p>
+!! end
+
+!! test
+multiple templates that are redirects
+!! wikitext
+{{redirect to foo}}
+{{redirect to foo}}
+!! html
+<p>FOO
+FOO
+</p>
+!! end
+
 !! test
 Multiple comments should still parse as SOL-transparent
 !! options
@@ -1891,22 +2019,18 @@ a <div>foo</div>
 </p>
 !! end
 
-# Remex wraps empty tag runs with p-tags.
-# Parsoid strips them out during p-wrapping.
 !! test
 No p-wrappable content
+!! options
+parsoid=wt2html,html2html
 !! wikitext
 <span><div>x</div></span>
 <span><s><div>x</div></s></span>
 <small><em></em></small><span><s><div>x</div></s></span>
-!! html/php+tidy
+!! html+tidy
 <span><div>x</div></span>
 <span><s><div>x</div></s></span>
 <p><small><em></em></small></p><span><s><div>x</div></s></span>
-!! html/parsoid
-<span><div>x</div></span>
-<span><s><div>x</div></s></span>
-<small><em></em></small><span><s><div>x</div></s></span>
 !! end
 
 # T177612: Parsoid-only test
@@ -1922,6 +2046,8 @@ x
 
 !! test
 Block tag on one line (<blockquote>)
+!! options
+parsoid=wt2html,html2html
 !! wikitext
 a <blockquote>foo</blockquote>
 
@@ -1953,6 +2079,8 @@ b </p><div>foo</div>
 
 !! test
 Block tag on both lines (<blockquote>)
+!! options
+parsoid=wt2html,html2html
 !! wikitext
 a <blockquote>foo</blockquote>
 
@@ -1992,12 +2120,6 @@ x </p><div>foo</div><p> z
 </p>
 !! end
 
-# The difference between Parsoid & Remex here
-# is because of Parsoid's Tidy-emulation code
-# for p-wrapping. We'll start work to remove this
-# emulation code in Parsoid sooner than later.
-# Remex wraps empty tag runs with p-tags.
-# Parsoid strips them out in a separate pass.
 !! test
 Empty lines between lines with block tags
 !! wikitext
@@ -2142,6 +2264,99 @@ hi
 <link rel="mw:PageProp/Category" href="./Category:Ho" />
 !! end
 
+!! test
+Paragraph wrapping following unclosed table
+!! options
+parsoid=wt2html,html2html
+!! wikitext
+{|
+|-
+
+{|
+| x
+|}
+
+a
+
+b
+
+c
+!! html/php+tidy
+<table>
+
+
+</table><table>
+<tbody><tr>
+<td>x
+</td></tr></tbody></table>
+<p>a
+</p><p>b
+</p><p>c
+</p>
+!! html/parsoid
+<table data-parsoid='{"autoInsertedEnd":true}'>
+<tbody><tr class="mw-empty-elt" data-parsoid='{"startTagSrc":"|-"}'></tr>
+
+</tbody></table><table>
+<tbody><tr data-parsoid='{"autoInsertedStart":true}'><td>x</td></tr>
+</tbody></table>
+
+<p>a</p>
+
+<p>b</p>
+
+<p>c</p>
+!! end
+
+!! test
+Paragraph wrapping suppressed in html p
+!! options
+parsoid=wt2html,html2html
+!! wikitext
+<p>
+
+
+hi
+
+
+
+</p>
+!! html/php+tidy
+<p>
+
+
+hi
+
+
+
+</p>
+!! html/parsoid
+<p data-parsoid='{"stx":"html"}'>
+
+
+hi
+
+
+
+</p>
+!! end
+
+!! test
+Dangling table row doesn't prevent p-wrapping
+!! options
+parsoid=wt2html,html2html
+!! wikitext
+{|
+| hi
+|-
+|} ho
+!! html/parsoid
+<table>
+<tbody><tr><td>hi</td></tr>
+<tr class="mw-empty-elt"></tr>
+</tbody></table><p> ho</p>
+!! end
+
 ###
 ### Preformatted text
 ###
@@ -2279,6 +2494,8 @@ Bar
 
 !! test
 T17491: <ins>/<del> in blockquote
+!! options
+parsoid=wt2html
 !! wikitext
 <blockquote>
 Foo <del>bar</del> <ins>baz</ins> quux
@@ -2289,10 +2506,17 @@ Foo <del>bar</del> <ins>baz</ins> quux
 </p>
 </blockquote>
 
+!! html+tidy
+<blockquote>
+<p>Foo <del>bar</del> <ins>baz</ins> quux
+</p>
+</blockquote>
 !! end
 
 !! test
 T17491: <ins>/<del> in blockquote (2)
+!! options
+parsoid=wt2html
 !! wikitext
 <blockquote>Foo <del>bar</del> <ins>baz</ins> quux
 </blockquote>
@@ -2301,7 +2525,7 @@ T17491: <ins>/<del> in blockquote (2)
 </blockquote>
 
 !! html+tidy
-<blockquote><p>Foo </p><del>bar</del> <ins>baz</ins><p> quux
+<blockquote><p>Foo <del>bar</del> <ins>baz</ins> quux
 </p></blockquote>
 !! end
 
@@ -2626,6 +2850,7 @@ Barack Obama <President> of the United States
 </p>
 !! end
 
+## Remex doesn't account for fostered content.
 !! test
 Handle broken pre-like tags (T66025)
 !! options
@@ -2642,12 +2867,9 @@ parsoid=wt2html
 <pre>x</pre>
 &lt;pre <table></table>
 !! html/parsoid
-<pre about="#mwt1" typeof="mw:Transclusion mw:Extension/pre" data-parsoid='{"a":{"&lt;pre":null},"sa":{"&lt;pre":""},"stx":"html","pi":[[{"k":"1"}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"&lt;pre &lt;pre>x&lt;/pre>"}},"i":0}}]}'>x</pre>
+<pre typeof="mw:Transclusion mw:Extension/pre" about="#mwt2" data-parsoid='{"stx":"html","a":{"&lt;pre":null},"sa":{"&lt;pre":""},"pi":[[{"k":"1"}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"&lt;pre &lt;pre>x&lt;/pre>"}},"i":0}}]}'>x</pre>
 
-
-<p>&lt;pre </p>
-
-<table></table>
+<p data-parsoid='{"fostered":true,"autoInsertedEnd":true,"autoInsertedStart":true}'>&lt;pre </p><table data-parsoid='{"stx":"html"}'></table>
 !! end
 
 !! test
 
 !! end
 
-!!test
-3a. Indent-Pre and block tags (single-line html)
+!! test
+2h. Indent pre in tables
+!! options
+parsoid=wt2html,html2html
 !! wikitext
- a <p> foo </p>
- b <div> foo </div>
- c <blockquote> foo </blockquote>
- <span> foo </span>
-!! html
- a <p> foo </p>
- b <div> foo </div>
- c <blockquote> foo </blockquote>
-<pre><span> foo </span>
-</pre>
-!! html/parsoid
- <p>a </p><p data-parsoid='{"stx":"html"}'> foo </p>
- <p>b </p><div data-parsoid='{"stx":"html"}'> foo </div>
- <p>c </p><blockquote data-parsoid='{"stx":"html"}'> foo </blockquote>
-<pre><span> foo </span>
+{|
+ !
+ foo
+ !
+ bar
+ |-
+ |
+ baz
+ {{!}}
+ bam
+ |}
+!! html/php
+<table>
+<tr>
+<th>
+<pre>foo
 </pre>
-!! html/php+tidy
-<p> a </p><p> foo </p><p>
- b </p><div> foo </div><p>
- c </p><blockquote><p> foo </p></blockquote>
-<pre><span> foo </span>
+</th>
+<th>
+<pre>bar
 </pre>
+</th></tr>
+<tr>
+<td>
+<pre>baz
+</pre>
+</td>
+<td>
+<pre>bam
+</pre>
+</td></tr></table>
+
+!! html/parsoid
+<table>
+ <tbody><tr><th>
+<pre>foo</pre>
+</th><th>
+<pre>bar</pre>
+</th></tr><tr>
+ <td>
+<pre>baz</pre>
+</td><td data-parsoid='{"startTagSrc":"{{!}}"}'>
+<pre>bam</pre>
+</td></tr></tbody></table>
 !! end
 
-!!test
-3b. Indent-Pre and block tags (multi-line html)
+!! test
+3a. Indent-Pre and block tags (single-line html)
+!! options
+parsoid=wt2html,html2html
 !! wikitext
- a <span>foo</span>
+ a <p> foo </p>
  b <div> foo </div>
+ c <blockquote> foo </blockquote>
+ <span> foo </span>
 !! html
+ a <p> foo </p>
+ b <div> foo </div>
+ c <blockquote> foo </blockquote>
+<pre><span> foo </span>
+</pre>
+!! html/php+tidy
+<p> a </p><p> foo </p><p>
+ b </p><div> foo </div><p>
+ c </p><blockquote><p> foo </p></blockquote>
+<pre><span> foo </span>
+</pre>
+!! html/parsoid
+<p> a </p><p data-parsoid='{"stx":"html"}'> foo </p><p>
+ b </p><div data-parsoid='{"stx":"html"}'> foo </div><p>
+ c </p><blockquote data-parsoid='{"stx":"html"}'><p> foo </p></blockquote>
+<pre><span data-parsoid='{"stx":"html"}'> foo </span></pre>
+!! end
+
+!! test
+3b. Indent-Pre and block tags (multi-line html)
+!! wikitext
+ a <span>foo</span>
+<!-- comment --> b <div> foo </div>
+!! html/php
 <pre>a <span>foo</span>
 </pre>
  b <div> foo </div>
 
 !! html/parsoid
 <pre>a <span data-parsoid='{"stx":"html"}'>foo</span></pre>
- b <div data-parsoid='{"stx":"html"}'> foo </div>
+<!-- comment --> <p>b </p><div data-parsoid='{"stx":"html"}'> foo </div>
 !! html/php+tidy
 <pre>a <span>foo</span>
 </pre><p>
  b </p><div> foo </div>
-!!end
+!! end
 
 !!test
 3c. Indent-Pre and block tags (pre-content on separate line)
@@ -3370,17 +3644,17 @@ foo
 
 !! test
 4. Indent-Pre and extension tags
+!! options
+parsoid=wt2html,html2html
 !! wikitext
  a <tag />
-!! html/php
- a <pre>
-NULL
+!! html/php+tidy
+<p> a </p><pre>NULL
 array (
 )
 </pre>
-
 !! html/parsoid
- a <pre typeof="mw:Extension/tag" about="#mwt2" data-parsoid='{}' data-mw='{"name":"tag","attrs":{},"body":null}'></pre>
+<p> a </p><pre typeof="mw:Extension/tag" about="#mwt2" data-mw='{"name":"tag","attrs":{},"body":null}'></pre>
 !! end
 
 !! test
@@ -3702,7 +3976,7 @@ Simple definition
 !! wikitext
 ;name :Definition
 !! html
-<dl><dt>name&#160;</dt>
+<dl><dt>name</dt>
 <dd>Definition</dd></dl>
 
 !! end
@@ -3731,7 +4005,7 @@ Definition list with URL link
 !! wikitext
 ;http://example.com/ :definition
 !! html
-<dl><dt><a rel="nofollow" class="external free" href="http://example.com/">http://example.com/</a>&#160;</dt>
+<dl><dt><a rel="nofollow" class="external free" href="http://example.com/">http://example.com/</a></dt>
 <dd>definition</dd></dl>
 
 !! end
@@ -3749,7 +4023,7 @@ Definition list with bracketed URL link
 !! test
 Definition list with wikilink containing colon
 !! wikitext
-; [[Help:FAQ]]:The least-read page on Wikipedia
+;[[Help:FAQ]]:The least-read page on Wikipedia
 !! 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>
@@ -3760,19 +4034,19 @@ Definition list with wikilink containing colon
 !! test
 Definition list with news link containing colon
 !! wikitext
-;news:alt.wikipedia.roxThis isn't even a real newsgroup!
+;news:alt.wikipedia.rox :This isn't even a real newsgroup!
 !! 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>
+<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
 
 !! test
 Malformed definition list with colon
 !! wikitext
-;  news:alt.wikipedia.rox -- don't crash or enter an infinite loop
+;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>
 
@@ -3783,7 +4057,7 @@ Definition lists: colon in external link text
 !! wikitext
 ;[http://www.wikipedia2.org/ Wikipedia :The Next Generation] :OK, I made that up
 !! html
-<dl><dt><a rel="nofollow" class="external text" href="http://www.wikipedia2.org/">Wikipedia&#160;:The Next Generation</a>&#160;</dt>
+<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
@@ -3802,7 +4076,7 @@ Definition lists: self-closed tag
 !! wikitext
 ;one<br/>two :two-line fun
 !! html
-<dl><dt>one<br />two&#160;</dt>
+<dl><dt>one<br />two</dt>
 <dd>two-line fun</dd></dl>
 
 !! end
@@ -3822,7 +4096,7 @@ Definition lists: excess closed tags
 !! wikitext
 ;one</b>two :bad tag fun
 !! html/php+tidy
-<dl><dt>onetwo&#160;</dt>
+<dl><dt>onetwo</dt>
 <dd>bad tag fun</dd></dl>
 !! html/parsoid
 <dl>
@@ -3859,7 +4133,7 @@ Definition and unordered list using wiki syntax nested in unordered list using h
 </li></ul>
 !! html
 <ul><li>
-<dl><dt>term&#160;</dt>
+<dl><dt>term</dt>
 <dd>description</dd></dl>
 <ul><li>unordered</li></ul>
 </li></ul>
@@ -4004,6 +4278,8 @@ should be left alone</p>
 
 !! test
 Definition Lists: Hacky use to indent tables, with comment before table
+!!options
+parsoid=wt2html
 !! wikitext
 ::<!-- foo -->{|
 |foo
@@ -4019,7 +4295,7 @@ Definition Lists: Hacky use to indent tables, with comment before table
 !! test
 Definition Lists: Hacky use to indent tables (WS-insensitive)
 !! wikitext
-: {|
+:{|
 |a
 |} 
 !! html/php
@@ -4029,9 +4305,9 @@ Definition Lists: Hacky use to indent tables (WS-insensitive)
 </td></tr></table></dd></dl>
 
 !! html/parsoid
-<dl><dd> <table>
+<dl><dd><table>
 <tbody><tr><td>a</td></tr>
-</tbody></table> </dd></dl>
+</tbody></table></dd></dl>
 !! end
 
 ## The PHP parser treats : items (dd) without a corresponding ; item (dt)
@@ -4257,9 +4533,9 @@ Definition Lists: Mixed Lists: Test 4
 *;d1 :d2
 *;d3 :d4
 !! html
-<ul><li><dl><dt>d1&#160;</dt>
+<ul><li><dl><dt>d1</dt>
 <dd>d2</dd>
-<dt>d3&#160;</dt>
+<dt>d3</dt>
 <dd>d4</dd></dl></li></ul>
 
 !! end
@@ -4318,7 +4594,7 @@ Definition Lists: Mixed Lists: Test 9
 !! wikitext
 *;foo :bar
 !! html
-<ul><li><dl><dt>foo&#160;</dt>
+<ul><li><dl><dt>foo</dt>
 <dd>bar</dd></dl></li></ul>
 
 !! end
@@ -4329,7 +4605,7 @@ Definition Lists: Mixed Lists: Test 10
 !! wikitext
 *#;foo :bar
 !! html
-<ul><li><ol><li><dl><dt>foo&#160;</dt>
+<ul><li><ol><li><dl><dt>foo</dt>
 <dd>bar</dd></dl></li></ol></li></ul>
 
 !! end
@@ -4362,15 +4638,15 @@ Definition Lists: Mixed Lists: Test 12
 *#*#;*;;foo :bar
 *#*#;boo :baz
 !! html/php
-<ul><li><ol><li><ul><li><ol><li><dl><dt>foo&#160;</dt>
+<ul><li><ol><li><ul><li><ol><li><dl><dt>foo</dt>
 <dd><ul><li><dl><dt><dl><dt>bar</dt></dl></dd></dl></li></ul></dd></dl>
-<dl><dt>boo&#160;</dt>
+<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&#160;</dt>
+<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>
-<dl><dt>boo&#160;</dt>
+<dl><dt>boo</dt>
 <dd>baz</dd></dl></li></ol></li></ul>
 !! html/parsoid
 <ul>
@@ -4388,12 +4664,12 @@ Definition Lists: Mixed Lists: Test 12
 <dl>
 <dt>
 <dl>
-<dt>foo<span typeof="mw:Placeholder" data-parsoid='{"src":" "}'>&nbsp;</span></dt>
+<dt>foo</dt>
 <dd data-parsoid='{"stx":"row"}'>bar</dd>
 </dl></dt>
 </dl></li>
 </ul></dt>
-<dt>boo<span typeof="mw:Placeholder" data-parsoid='{"src":" "}'>&nbsp;</span></dt>
+<dt>boo</dt>
 <dd data-parsoid='{"stx":"row"}'>baz</dd>
 </dl></li>
 </ol></li>
@@ -4402,6 +4678,18 @@ Definition Lists: Mixed Lists: Test 12
 </ul>
 !! end
 
+!! test
+Definition Lists: Mixed Lists: Test 13
+!! wikitext
+*#*#;*;;foo : bar
+*#*#;boo : baz
+!! html+tidy
+<ul><li><ol><li><ul><li><ol><li><dl><dt>foo&#160;</dt>
+<dd><ul><li><dl><dt><dl><dt>bar</dt></dl></dt></dl></li></ul></dd></dl></li></ol></li></ul>
+<dl><dt>boo&#160;</dt>
+<dd>baz</dd></dl></li></ol></li></ul>
+!! end
+
 # FIXME: Maybe get rid of this test?
 # From whitelist:
 # * The test is wrong, there are two colons where there should be :;
@@ -4411,7 +4699,7 @@ Definition Lists: Weird Ones: Test 1
 !! wikitext
 *#;*::;;foo :bar (who uses this?)
 !! html/php+tidy
-<ul><li><ol><li><dl><dt>foo&#160;</dt>
+<ul><li><ol><li><dl><dt>foo</dt>
 <dd><ul><li><dl><dd><dl><dd><dl><dt><dl><dt>bar (who uses this?)</dt></dl></dt></dl></dd></dl></dd></dl></li></ul></dd></dl></li></ol></li></ul>
 !! html/parsoid
 <ul>
@@ -4429,7 +4717,7 @@ Definition Lists: Weird Ones: Test 1
 <dl>
 <dt>
 <dl>
-<dt>foo<span typeof="mw:DisplaySpace mw:Placeholder" data-parsoid='{"src":" ","isDisplayHack":true}'> </span></dt>
+<dt>foo</dt>
 <dd data-parsoid='{"stx":"row"}'>bar (who uses this?)</dd>
 </dl></dt>
 </dl></dd>
@@ -4967,7 +5255,7 @@ URL in text: [http://example.com http://example.com]
 <p>URL in text: <a rel="nofollow" class="external text" href="http://example.com">http://example.com</a>
 </p>
 !! html/parsoid
-<p>URL in text: <a rel="mw:ExtLink" class="external free" href="http://example.com">http://example.com</a></p>
+<p>URL in text: <a rel="mw:ExtLink" class="external text" href="http://example.com">http://example.com</a></p>
 !! end
 
 !! test
@@ -5610,7 +5898,7 @@ Examples from RFC 2732, section 2:
 !! 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>
 
-<p>Examples from <a href="https://tools.ietf.org/html/rfc2373" rel="mw:ExtLink" class="external text">RFC 2373</a>, section 2.2:</p>
+<p>Examples from <a href="https://tools.ietf.org/html/rfc2373" rel="mw:ExtLink" class="external mw-magiclink">RFC 2373</a>, section 2.2:</p>
 <ul><li><a rel="mw:ExtLink" class="external free" href="http://[1080::8:800:200C:417A]/unicast">http://[1080::8:800:200C:417A]/unicast</a></li>
 <li><a rel="mw:ExtLink" class="external free" href="http://[FF01::101]/multicast">http://[FF01::101]/multicast</a></li>
 <li><a rel="mw:ExtLink" class="external free" href="http://[::1]/loopback">http://[::1]/loopback</a></li>
@@ -5618,7 +5906,7 @@ Examples from RFC 2732, section 2:
 <li><a rel="mw:ExtLink" class="external free" href="http://[::13.1.68.3]/ipv4compat">http://[::13.1.68.3]/ipv4compat</a></li>
 <li><a rel="mw:ExtLink" class="external free" href="http://[::FFFF:129.144.52.38]/ipv4compat">http://[::FFFF:129.144.52.38]/ipv4compat</a></li></ul>
 
-<p>Examples from <a href="https://tools.ietf.org/html/rfc2732" rel="mw:ExtLink" class="external text">RFC 2732</a>, section 2:</p>
+<p>Examples from <a href="https://tools.ietf.org/html/rfc2732" rel="mw:ExtLink" class="external mw-magiclink">RFC 2732</a>, section 2:</p>
 <ul><li><a rel="mw:ExtLink" class="external free" href="http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html">http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html</a></li>
 <li><a rel="mw:ExtLink" class="external free" href="http://[1080:0:0:0:8:800:200C:417A]/index.html">http://[1080:0:0:0:8:800:200C:417A]/index.html</a></li>
 <li><a rel="mw:ExtLink" class="external free" href="http://[3ffe:2a00:100:7031::1]">http://[3ffe:2a00:100:7031::1]</a></li>
@@ -5674,7 +5962,7 @@ Examples from RFC 2732, section 2:
 !! html/parsoid
 <p><a rel="mw:ExtLink" class="external text" href="http://[2404:130:0:1000::187:2]/index.php">test</a></p>
 
-<p>Examples from <a href="https://tools.ietf.org/html/rfc2373" rel="mw:ExtLink" class="external text">RFC 2373</a>, section 2.2:</p>
+<p>Examples from <a href="https://tools.ietf.org/html/rfc2373" rel="mw:ExtLink" class="external mw-magiclink">RFC 2373</a>, section 2.2:</p>
 <ul><li><a rel="mw:ExtLink" class="external text" href="http://[1080::8:800:200C:417A]">unicast</a></li>
 <li><a rel="mw:ExtLink" class="external text" href="http://[FF01::101]">multicast</a></li>
 <li><a rel="mw:ExtLink" class="external text" href="http://[::1]/">loopback</a></li>
@@ -5682,7 +5970,7 @@ Examples from RFC 2732, section 2:
 <li><a rel="mw:ExtLink" class="external text" href="http://[::13.1.68.3]">ipv4compat</a></li>
 <li><a rel="mw:ExtLink" class="external text" href="http://[::FFFF:129.144.52.38]">ipv4compat</a></li></ul>
 
-<p>Examples from <a href="https://tools.ietf.org/html/rfc2732" rel="mw:ExtLink" class="external text">RFC 2732</a>, section 2:</p>
+<p>Examples from <a href="https://tools.ietf.org/html/rfc2732" rel="mw:ExtLink" class="external mw-magiclink">RFC 2732</a>, section 2:</p>
 <ul><li><a rel="mw:ExtLink" class="external text" href="http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html">1</a></li>
 <li><a rel="mw:ExtLink" class="external text" href="http://[1080:0:0:0:8:800:200C:417A]/index.html">2</a></li>
 <li><a rel="mw:ExtLink" class="external text" href="http://[3ffe:2a00:100:7031::1]">3</a></li>
@@ -6032,7 +6320,7 @@ A table with nothing but a caption
 A table with caption with default-spaced attributes and a table row
 !! wikitext
 {|
-|+ style="color: red;" | caption1
+|+ style="color: red;" |caption1
 |-
 |foo
 |}
@@ -6316,8 +6604,8 @@ Accept "!!" in table data of mixed wikitext / html syntax
 Accept empty attributes in td/th cells (td/th cells starting with leading ||)
 !! wikitext
 {|
-!| h1
-|| a
+!|h1
+||a
 |}
 !! html
 <table>
@@ -6462,9 +6750,9 @@ Invalid attributes in table cell (T3830)
 Table cell attributes: Pipes protected by nowikis should be treated as a plain character
 !! wikitext
 {|
-| title="foo" |bar
-| title="foo<nowiki>|</nowiki>" |bar
-| title="foo<nowiki>|</nowiki>" bar
+|title="foo" |bar
+|title="foo<nowiki>|</nowiki>" |bar
+|title="foo<nowiki>|</nowiki>" bar
 |}
 !! html/php
 <table>
@@ -6577,7 +6865,7 @@ parsoid=wt2html,html2html
 <p>ho"&gt;ha&lt;/div&gt;
 </p>
 !! html/parsoid
-<span typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"ho\">ha&lt;/div>"}},"i":0}}]}'>ho">ha</span>
+<p about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"ho\">ha&lt;/div>"}},"i":0}}]}'>ho">ha</p>
 !! end
 
 !! test
@@ -6646,8 +6934,8 @@ parsoid={
 |}
 !! wikitext/edited
 {| <span>boo</span> style='border:1px solid black'
-|  <span>boo</span> style='color:blue'  |abc
-|<span>boo</span> style='color:blue'|xyz
+|  <span>boo</span> style='color:blue'  | abc
+|<span>boo</span> style='color:blue'| xyz
 |}
 !! end
 
@@ -6899,7 +7187,7 @@ b
 Table cell with a single comment
 !! wikitext
 {|
-| <!-- c1 -->
+|<!-- c1 -->
 |a
 |}
 !! html
@@ -7039,10 +7327,11 @@ Wikitext table with html-syntax row
 <td>foo</td></tr></tbody></table>
 !! end
 
+## Remex doesn't account for fostered content.
 !! test
 Fostered content in tables: Plain text
 !! options
-parsoid=wt2html,html2html
+parsoid=wt2html
 !! wikitext
 {|
 |-
 a
 <table></table>
 !! html/parsoid
-<p data-parsoid='{"fostered":true,"autoInsertedEnd":true}'>a</p><table>
-<tbody><tr data-parsoid='{"startTagSrc":"|-","autoInsertedEnd":true}'>
-
-</tr></tbody></table>
+<p data-parsoid='{"fostered":true,"autoInsertedEnd":true,"autoInsertedStart":true}'>
+a</p>
+<table>
+<tbody><tr class="mw-empty-elt" data-parsoid='{"startTagSrc":"|-"}'></tr></tbody></table>
 !! end
 
 !! test
@@ -7158,18 +7447,6 @@ parsoid=html2wt
 '''quux'''
 !! end
 
-!! test
-Parsoid: newline inducing block nodes don't suppress <nowiki>
-!! options
-parsoid=html2wt
-!! html/parsoid
- a<h1>foo</h1>
-!! wikitext
-<nowiki> </nowiki>a
-
-= foo =
-!! end
-
 !! test
 Parsoid: Row-syntax table headings followed by comment & table cells
 !! options
@@ -7191,8 +7468,8 @@ parsoid=wt2html,wt2wt
 
 !! html/parsoid
 <table>
-<tbody><tr><th> foo </th><th> bar
-<!-- foo -->  </th><td> baz </td><td> quux</td></tr>
+<tbody><tr><th>foo</th><th>bar
+<!-- foo --></th><td> baz </td><td>quux</td></tr>
 </tbody></table>
 !! end
 
@@ -7237,6 +7514,22 @@ parsoid=wt2html
 </tbody></table>
 !! end
 
+!! test
+Table with missing opening <tr> tag
+!! options
+parsoid=wt2html,wt2wt
+!! wikitext
+<table>
+<td>foo</td>
+</tr>
+</table>
+!! html+tidy
+<table>
+<tbody><tr><td>foo</td>
+</tr>
+</tbody></table>
+!! end
+
 # T137406: Whitespace in the HTML
 !! test
 1. Generate correct wikitext for tables with thead/tbody/tfoot
@@ -7324,97 +7617,6 @@ parsoid=html2wt
 |}
 !! end
 
-!! test
-Testing serialization after deletion in references
-!! options
-parsoid={
-  "modes": ["wt2wt"],
-  "changes": [
-    ["#x", "remove"]
-  ]
-}
-!! wikitext
-hi <ref><div id="x">ho</div></ref>
-
-<references />
-!! wikitext/edited
-hi <ref></ref>
-
-<references />
-!! end
-
-!!test
-Testing serialization after deletion of table cells
-!!options
-parsoid={
-  "modes": ["wt2wt", "selser"],
-  "changes": [
-    ["#x", "remove"]
-  ]
-}
-!!wikitext
-{|
-!h1 !!h2 !!h3
-| id="x" |c1 {{!}}{{!}}{{!}}c2 |||c3
-|}
-!! wikitext/edited
-{|
-!h1 !!h2 !!h3
-|c2 |||c3
-|}
-!!end
-
-!! test
-Testing selser after addition of new row before first row (T125419)
-!! options
-parsoid={
-  "modes": ["wt2wt", "selser"],
-  "changes": [
-    [ "tr", "before", "<tr><td>X</td></tr>" ]
-  ]
-}
-!! wikitext
-{|
-|a
-|}
-!! wikitext/edited
-{|
-|X
-|-
-|a
-|}
-!! end
-
-!! test
-Serialize new table rows in a HTML table using HTML tags
-!! options
-parsoid={
-  "modes": ["wt2wt", "selser"],
-  "changes": [
-    [ "tr", "before", "<tr><td>X</td></tr>" ]
-  ]
-}
-!! wikitext
-<table><tr><td>a</td></tr></table>
-!! wikitext/edited
-<table><tr><td>X</td></tr><tr><td>a</td></tr></table>
-!! end
-
-!! test
-Serialize new table cells in a HTML row using HTML tags
-!! options
-parsoid={
-  "modes": ["wt2wt", "selser"],
-  "changes": [
-    [ "td", "before", "<td>X</td>" ]
-  ]
-}
-!! wikitext
-<table><tr><td>a</td></tr></table>
-!! wikitext/edited
-<table><tr><td>X</td><td>a</td></tr></table>
-!! end
-
 !! test
 Wikitext tables can be nested inside HTML tables
 !! options
@@ -7437,56 +7639,6 @@ parsoid=html2wt
 </table>
 !! end
 
-!! test
-Serialize wikitext list items as HTML list items when embedded in a HTML list
-!! options
-parsoid=html2wt
-!! html
-<ul data-parsoid='{"stx": "html"}'>
-<li data-parsoid='{}'>a</li>
-<li>b</li>
-</ul>
-!! wikitext
-<ul>
-<li>a</li>
-<li>b</li>
-</ul>
-!! end
-
-# SSS FIXME: Is this actually a good thing given the
-# odd nested list output that is generated by MW?
-# <ul><li>foo<ul>..</ul></li></ul> instead of
-# <ul><li>foo</li><ul>..</ul></ul>
-!! test
-Wikitext lists can be nested inside HTML lists
-!! options
-parsoid=html2wt
-!! html
-<ul data-parsoid='{"stx": "html"}'>
-<li data-parsoid='{"stx": "html"}'>a
-<ul><li>b</li></ul>
-</li>
-</ul>
-
-<ul data-parsoid='{"stx": "html"}'>
-<li>x
-<ul><li>y</li></ul>
-</li>
-</ul>
-!! wikitext
-<ul>
-<li>a
-* b
-</li>
-</ul>
-
-<ul>
-<li>x
-* y
-</li>
-</ul>
-!! end
-
 ###
 ### Internal links
 ###
@@ -8997,6 +9149,14 @@ parsoid=wt2html,wt2wt
 <p><a rel="mw:WikiLink" href="./Constructor:foo" title="Constructor:foo" data-parsoid='{"stx":"simple","a":{"href":"./Constructor:foo"},"sa":{"href":"constructor:foo"}}'>constructor:foo</a></p>
 !! end
 
+!! test
+Template parameter named "constructor"
+!! wikitext
+{{echo|  constructor =  |hi}}
+!! html/parsoid
+<p about="#mwt1" typeof="mw:Transclusion" data-parsoid='{"pi":[[{"k":"constructor","named":true,"spc":["  "," ","","  "]},{"k":"1"}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"hi"},"constructor":{"wt":""}},"i":0}}]}'>hi</p>
+!! end
+
 !! article
 ko:
 !! text
@@ -9718,9 +9878,19 @@ parsoid
 !! end
 
 !! test
-2. Lists with start-of-line-transparent tokens before bullets: Template close
+Nested lists 10 (list and span siblings: wt2wt regression)
 !! wikitext
-*foo {{echo|bar
+*a <span>x</span>
+**b <span>y</span>
+!! html/parsoid
+<ul><li>a <span>x</span>
+<ul><li>b <span>y</span></li></ul></li></ul>
+!! end
+
+!! test
+2. Lists with start-of-line-transparent tokens before bullets: Template close
+!! wikitext
+*foo {{echo|bar
 }}*baz
 !! html
 <ul><li>foo bar</li>
@@ -9789,7 +9959,7 @@ List interrupted by empty line or heading
 
 !!end
 
-!!test
+!! test
 Multiple list tags generated by templates
 !! wikitext
 {{echo|<li>}}a
@@ -9802,6 +9972,7 @@ Multiple list tags generated by templates
 </li>
 </li>
 
+
 !! html+tidy
 <li>a
 </li><li>b
@@ -9811,7 +9982,44 @@ Multiple list tags generated by templates
 <li about="#mwt1" typeof="mw:Transclusion" data-parsoid='{"stx":"html","autoInsertedEnd":true,"dsr":[0,44,null,null],"pi":[[{"k":"1"}],[{"k":"1"}],[{"k":"1"}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"&lt;li>"}},"i":0}},"a\n",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"&lt;li>"}},"i":1}},"b\n",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"&lt;li>"}},"i":2}},"c"]}'>a
 </li><li about="#mwt1">b
 </li><li about="#mwt1" data-parsoid='{"stx":"html","autoInsertedEnd":true,"dsr":[null,44,null,0]}'>c</li>
-!!end
+!! end
+
+!! test
+Multiple newlines in between HTML list items don't induce paragraph wrapping
+!! wikitext
+<ul>
+<li>hi</li>
+
+
+
+
+<li>ho</li>
+</ul>
+
+<dl>
+<dt>hi</dt>
+<dd>ho<div>123</div>
+</dd>
+
+
+</dl>
+!! html/php+tidy
+<ul>
+<li>hi</li>
+
+
+
+
+<li>ho</li>
+</ul>
+<dl>
+<dt>hi</dt>
+<dd>ho<div>123</div>
+</dd>
+
+
+</dl>
+!! end
 
 !!test
 Single-comment whitespace lines dont break lists, and neither do multi-comment whitespace lines
@@ -9920,7 +10128,7 @@ parsoid
 !! test
 Parsoid: Test of whitespace serialization with Templated bullets
 !! options
-parsoid
+parsoid=wt2html
 !! wikitext
 * {{bullet}}
 !! html/parsoid
@@ -9957,6 +10165,8 @@ Unbalanced closing block tags break a list
 
 !! test
 Unbalanced closing non-block tags don't break a list
+!! options
+parsoid=wt2html,html2html
 !! wikitext
 <span>
 *a</span><span>
@@ -9967,12 +10177,9 @@ Unbalanced closing non-block tags don't break a list
 <ul><li>a<span></span></li>
 <li>b</li></ul>
 !! html/parsoid
-<span>
-<ul>
-<li>a<span></span></li>
-<li>b</li>
-</ul>
-</span>
+<p><span data-parsoid='{"stx":"html","autoInsertedEnd":true}'></span></p>
+<ul><li>a<span data-parsoid='{"stx":"html","autoInsertedEnd":true}'></span></li>
+<li>b</li></ul>
 !! end
 
 # Parsoid does some post-dom-building cleanup
@@ -9993,14 +10200,7 @@ parsoid=wt2html,wt2wt,html2html
 !! end
 
 # Output is ugly because of all the misnested tag fixups.
-# Remex is wrapping p-tags around empty elements.
-# Parsoid has special-case handling of this pattern of
-# wrapping lists in formatting tags.
-# FIXME: Should we remove this code from Parsoid? Or add
-# special support in Remex? If the latter, maybe just wait
-# for Parsoid to become the default parser.
-# See T70395.
-!!test
+!! test
 1. List embedded in a formatting tag
 !! wikitext
 <small>
@@ -10011,17 +10211,13 @@ parsoid=wt2html,wt2wt,html2html
 </small></p><small><ul><li>foo</li></ul></small><small></small><p><small></small>
 </p>
 !! html/parsoid
-<small>
-<ul>
-<li>foo</li>
-</ul>
-</small>
-!!end
+<p><small data-parsoid='{"stx":"html","autoInsertedEnd":true}'></small></p><small data-parsoid='{"stx":"html","autoInsertedEnd":true,"autoInsertedStart":true}'>
+<ul><li data-parsoid='{}'>foo</li></ul></small>
+<p><small data-parsoid='{"stx":"html","autoInsertedStart":true}'></small></p>
+!! end
 
-# Output is ugly because of all the misnested tag fixups
-# Remex is wrapping p-tags around empty elements.
-# Parsoid has code that strips useless p-tags.
-!!test
+# Output is ugly because of all the misnested tag fixups.
+!! test
 2. List embedded in a formatting tag in a misnested way
 !! wikitext
 <small>
@@ -10032,28 +10228,9 @@ parsoid=wt2html,wt2wt,html2html
 </small></p><small></small><ul><small><li>a</li>
 </small><li><small>b</small></li></ul>
 !! html/parsoid
-<small></small>
-<ul><small>
-<li>a</li>
-</small>
-<li><small>b</small></li>
-</ul>
-!!end
-
-!! test
-Table with missing opening <tr> tag
-!! options
-parsoid=wt2html,wt2wt
-!! wikitext
-<table>
-<td>foo</td>
-</tr>
-</table>
-!! html+tidy
-<table>
-<tbody><tr><td>foo</td>
-</tr>
-</tbody></table>
+<p><small data-parsoid='{"stx":"html","autoInsertedEnd":true}'></small></p><p></p>
+<ul><small data-parsoid='{"stx":"html","autoInsertedEnd":true,"autoInsertedStart":true}'><li>a</li></small>
+<li><small data-parsoid='{"stx":"html","autoInsertedStart":true}'>b</small></li></ul>
 !! end
 
 ###
@@ -10909,7 +11086,7 @@ RFC 822
 <p><a class="external mw-magiclink-rfc" rel="nofollow" href="https://tools.ietf.org/html/rfc822">RFC 822</a>
 </p>
 !! html/parsoid
-<p><a href="https://tools.ietf.org/html/rfc822" rel="mw:ExtLink" class="external text">RFC 822</a></p>
+<p><a href="https://tools.ietf.org/html/rfc822" rel="mw:ExtLink" class="external mw-magiclink">RFC 822</a></p>
 !! end
 
 !! test
@@ -10920,7 +11097,7 @@ This is RFC 822 but thisRFC 822 is not RFC 822linked.
 <p>This is <a class="external mw-magiclink-rfc" rel="nofollow" href="https://tools.ietf.org/html/rfc822">RFC 822</a> but thisRFC 822 is not RFC 822linked.
 </p>
 !! html/parsoid
-<p>This is <a href="https://tools.ietf.org/html/rfc822" rel="mw:ExtLink" class="external text">RFC 822</a> but thisRFC 822 is not RFC 822linked.</p>
+<p>This is <a href="https://tools.ietf.org/html/rfc822" rel="mw:ExtLink" class="external mw-magiclink">RFC 822</a> but thisRFC 822 is not RFC 822linked.</p>
 !! end
 
 !! test
@@ -10935,7 +11112,7 @@ RFC
 822
 </p>
 !! html/parsoid
-<p><a href="https://tools.ietf.org/html/rfc822" rel="mw:ExtLink" class="external text">RFC <span typeof="mw:Entity" data-parsoid='{"src":"&amp;nbsp;","srcContent":" "}'> </span><span typeof="mw:Entity" data-parsoid='{"src":"&amp;#160;","srcContent":" "}'> </span><span typeof="mw:Entity" data-parsoid='{"src":"&amp;#0160;","srcContent":" "}'> </span><span typeof="mw:Entity" data-parsoid='{"src":"&amp;#xA0;","srcContent":" "}'> </span><span typeof="mw:Entity" data-parsoid='{"src":"&amp;#Xa0;","srcContent":" "}'> </span> 822</a>
+<p><a href="https://tools.ietf.org/html/rfc822" rel="mw:ExtLink" class="external mw-magiclink">RFC <span typeof="mw:Entity" data-parsoid='{"src":"&amp;nbsp;","srcContent":" "}'> </span><span typeof="mw:Entity" data-parsoid='{"src":"&amp;#160;","srcContent":" "}'> </span><span typeof="mw:Entity" data-parsoid='{"src":"&amp;#0160;","srcContent":" "}'> </span><span typeof="mw:Entity" data-parsoid='{"src":"&amp;#xA0;","srcContent":" "}'> </span><span typeof="mw:Entity" data-parsoid='{"src":"&amp;#Xa0;","srcContent":" "}'> </span> 822</a>
 RFC
 822</p>
 !! end
@@ -10993,7 +11170,7 @@ PMID 1234
 <p><a class="external mw-magiclink-pmid" rel="nofollow" href="//www.ncbi.nlm.nih.gov/pubmed/1234?dopt=Abstract">PMID 1234</a>
 </p>
 !! html/parsoid
-<p><a href="//www.ncbi.nlm.nih.gov/pubmed/1234?dopt=Abstract" rel="mw:ExtLink" class="external text">PMID 1234</a></p>
+<p><a href="//www.ncbi.nlm.nih.gov/pubmed/1234?dopt=Abstract" rel="mw:ExtLink" class="external mw-magiclink">PMID 1234</a></p>
 !! end
 
 !! test
@@ -11004,7 +11181,7 @@ This is PMID 1234 but thisPMID 1234 is not PMID 1234linked.
 <p>This is <a class="external mw-magiclink-pmid" rel="nofollow" href="//www.ncbi.nlm.nih.gov/pubmed/1234?dopt=Abstract">PMID 1234</a> but thisPMID 1234 is not PMID 1234linked.
 </p>
 !! html/parsoid
-<p>This is <a href="//www.ncbi.nlm.nih.gov/pubmed/1234?dopt=Abstract" rel="mw:ExtLink" class="external text">PMID 1234</a> but thisPMID 1234 is not PMID 1234linked.</p>
+<p>This is <a href="//www.ncbi.nlm.nih.gov/pubmed/1234?dopt=Abstract" rel="mw:ExtLink" class="external mw-magiclink">PMID 1234</a> but thisPMID 1234 is not PMID 1234linked.</p>
 !! end
 
 !! test
@@ -11019,7 +11196,7 @@ PMID
 1234
 </p>
 !! html/parsoid
-<p><a href="//www.ncbi.nlm.nih.gov/pubmed/1234?dopt=Abstract" rel="mw:ExtLink" class="external text">PMID <span typeof="mw:Entity" data-parsoid='{"src":"&amp;nbsp;","srcContent":" "}'> </span><span typeof="mw:Entity" data-parsoid='{"src":"&amp;#160;","srcContent":" "}'> </span><span typeof="mw:Entity" data-parsoid='{"src":"&amp;#0160;","srcContent":" "}'> </span><span typeof="mw:Entity" data-parsoid='{"src":"&amp;#xA0;","srcContent":" "}'> </span><span typeof="mw:Entity" data-parsoid='{"src":"&amp;#Xa0;","srcContent":" "}'> </span> 1234</a>
+<p><a href="//www.ncbi.nlm.nih.gov/pubmed/1234?dopt=Abstract" rel="mw:ExtLink" class="external mw-magiclink">PMID <span typeof="mw:Entity" data-parsoid='{"src":"&amp;nbsp;","srcContent":" "}'> </span><span typeof="mw:Entity" data-parsoid='{"src":"&amp;#160;","srcContent":" "}'> </span><span typeof="mw:Entity" data-parsoid='{"src":"&amp;#0160;","srcContent":" "}'> </span><span typeof="mw:Entity" data-parsoid='{"src":"&amp;#xA0;","srcContent":" "}'> </span><span typeof="mw:Entity" data-parsoid='{"src":"&amp;#Xa0;","srcContent":" "}'> </span> 1234</a>
 PMID
 1234</p>
 !! end
@@ -11504,6 +11681,17 @@ Template from main namespace
 </p>
 !! end
 
+!! test
+Template from non-includable namespace
+!! options
+wgNonincludableNamespaces=10
+!! wikitext
+{{echo|uh oh!}}
+!! html
+<p><a href="/wiki/Template:Echo" title="Template:Echo">Template:Echo</a>
+</p>
+!! end
+
 !! article
 Template:table
 !! text
@@ -12730,16 +12918,20 @@ Templates: Block Tags: 2. Back-to-back template uses
 
 !!end
 
-# This is an edge case relating to paragraph wrapping.
-!!test
+## Parsoid drops empty elements in templates.
+!! test
 Templates: Correctly encapsulate templates producing </p> tag without a corresponding <p> tag
 !! wikitext
 {{echo|a
 b</p>}}
+!! html/php+tidy
+<p>a
+</p><p>
+b</p><p class="mw-empty-elt"></p>
 !! html/parsoid
-<p about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"a\nb&lt;/p>"}},"i":0}}]}'>a
-b</p>
-!!end
+<p about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"a\nb&lt;/p>"}},"i":0}}]}'>a</p><span about="#mwt1">
+</span><p about="#mwt1">b</p>
+!! end
 
 !!test
 Templates: Links: 1. Simple example
@@ -12920,6 +13112,24 @@ Templates: Support for templates generating attributes and content
 </tbody></table>
 !!end
 
+!! article
+Template:attribute_from_template
+!! text
+class="123"
+!! endarticle
+
+!! test
+Table cell with attribute before expanded attribute
+!! wikitext
+{|
+| align="center" {{attribute_from_template}} |456
+|}
+!! html/parsoid
+<table>
+<tbody><tr><td align="center" class="123" about="#mwt2" typeof="mw:ExpandedAttrs" data-mw='{"attribs":[[{"txt":"class","html":"&lt;span about=\"#mwt1\" typeof=\"mw:Transclusion\" data-parsoid=&apos;{\"pi\":[[]],\"dsr\":[20,47,null,null]}&apos; data-mw=&apos;{\"parts\":[{\"template\":{\"target\":{\"wt\":\"attribute_from_template\",\"href\":\"./Template:Attribute_from_template\"},\"params\":{},\"i\":0}}]}&apos;>class=\"123\"&lt;/span>"},{"html":""}]]}'>456</td></tr>
+</tbody></table>
+!! end
+
 !! test
 1. Entities and nowikis inside templated attributes should be handled correctly
 !! wikitext
@@ -13090,13 +13300,14 @@ parsoid=wt2html,wt2wt
 <link rel="mw:PageProp/Category" href="./Category:Bar1"><link rel="mw:PageProp/Category" href="./Category:Bar2"><table><tbody><tr><td>foo</td></tr></tbody></table>
 !!end
 
-!!test
+## Remex doesn't account for fostered content.
+!! test
 Templates: Wiki Tables: 1a. Fostering of entire template content
 !! wikitext
 {|
 {{echo|a}}
 |}
-!! html
+!! html/php
 <table>
 a
 <tr><td></td></tr></table>
 a
 <table><tbody><tr><td></td></tr></tbody></table>
 !! html/parsoid
-<p about="#mwt2" typeof="mw:Transclusion" data-parsoid='{"fostered":true,"autoInsertedEnd":true,"firstWikitextNode":"TABLE","pi":[[{"k":"1"}]]}' data-mw='{"parts":["{|\n",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"a"}},"i":0}},"\n|}"]}'>a</p><table about="#mwt2">
+<p about="#mwt2" typeof="mw:Transclusion" data-parsoid='{"fostered":true,"autoInsertedEnd":true,"autoInsertedStart":true,"firstWikitextNode":"TABLE","pi":[[{"k":"1"}]]}' data-mw='{"parts":["{|\n",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"a"}},"i":0}},"\n|}"]}'>a</p><table about="#mwt2">
 
 </table>
 !! end
@@ -13142,14 +13353,15 @@ foo
 </table>
 !! end
 
-!!test
+## Remex doesn't account for fostered content.
+!! test
 Templates: Wiki Tables: 2. Fostering of partial template content
 !! wikitext
 {|
 {{echo|a
 <div>b</div>}}
 |}
-!! html
+!! html/php
 <table>
 a
 <div>b</div>
 <div>b</div><table>
 <tbody><tr><td></td></tr></tbody></table>
 !! html/parsoid
-<p about="#mwt2" typeof="mw:Transclusion" data-parsoid='{"fostered":true,"autoInsertedEnd":true,"firstWikitextNode":"TABLE","pi":[[{"k":"1"}]]}' data-mw='{"parts":["{|\n",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"a\n&lt;div>b&lt;/div>"}},"i":0}},"\n|}"]}'>a</p><div about="#mwt2">b</div><table about="#mwt2">
+<p about="#mwt2" typeof="mw:Transclusion" data-parsoid='{"fostered":true,"autoInsertedEnd":true,"autoInsertedStart":true,"firstWikitextNode":"TABLE","pi":[[{"k":"1"}]]}' data-mw='{"parts":["{|\n",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"a\n&lt;div>b&lt;/div>"}},"i":0}},"\n|}"]}'>a</p><div about="#mwt2">b</div><table about="#mwt2">
 
 
 </table>
@@ -13225,20 +13437,20 @@ Templates: Wiki Tables: 6. Templated tags, templated td-tags
 ## a <meta> marker tag for <ref> tags and they are expanded
 ## much later. We are verifying that this <meta> tag usage
 ## doesn't prevent foster parenting.
-!!test
+!! test
 Templates: Wiki Tables: 7. Fosterable <ref>s should get fostered
-!!wikitext
+!! wikitext
 {{PartialTable}}<ref>foo</ref>
 |}
 
 <references />
-!!html/parsoid
-<sup about="#mwt2" class="mw-ref" id="cite_ref-1" rel="dc:references" typeof="mw:Transclusion  mw:Extension/ref" data-mw='{"parts":[{"template":{"target":{"wt":"PartialTable","href":"./Template:PartialTable"},"params":{},"i":0}},"&lt;ref>foo&lt;/ref>\n|}"]}'><a href="./Main_Page#cite_note-1"><span class="mw-reflink-text">[1]</span></a></sup><table about="#mwt2">
+!! html/parsoid
+<p about="#mwt2" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"PartialTable","href":"./Template:PartialTable"},"params":{},"i":0}},"&lt;ref>foo&lt;/ref>\n|}"]}'><sup about="#mwt3" class="mw-ref" id="cite_ref-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-1"},"attrs":{}}'><a href="./Main_Page#cite_note-1" style="counter-reset: mw-Ref 1;"><span class="mw-reflink-text">[1]</span></a></sup></p><table about="#mwt2">
 <tbody>
 </tbody></table>
 
-<ol class="mw-references references" typeof="mw:Extension/references" about="#mwt4" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-1" id="cite_note-1"><a href="./Main_Page#cite_ref-1" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-1" class="mw-reference-text">foo</span></li></ol>
-!!end
+<ol class="mw-references references" typeof="mw:Extension/references" about="#mwt5" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-1" id="cite_note-1"><a href="./Main_Page#cite_ref-1" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-1" class="mw-reference-text">foo</span></li></ol>
+!! end
 
 !! test
 Templates: Wiki Tables: 8. Fosterable meta-tags should get fostered
@@ -13407,6 +13619,19 @@ Parser Functions: 2. Nested use (only outermost should be marked up)
 </p>
 !!end
 
+## Note that the templates inside the references are not wrapped
+!! test
+Template nested in extension tag in template
+!! wikitext
+{{echo|hi<ref>[[ho|{{echo|hi}}]]</ref>}}
+{{echo|hi<ref>[http://test.com?q={{echo|ho}}]</ref>}}
+<references />
+!! html/parsoid
+<p><span about="#mwt2" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"hi&lt;ref>[[ho|{{echo|hi}}]]&lt;/ref>"}},"i":0}}]}'>hi</span><sup about="#mwt2" class="mw-ref" id="cite_ref-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-1"},"attrs":{}}'><a href="./Main_Page#cite_note-1" style="counter-reset: mw-Ref 1;"><span class="mw-reflink-text">[1]</span></a></sup>
+<span about="#mwt7" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"hi&lt;ref>[http://test.com?q={{echo|ho}}]&lt;/ref>"}},"i":0}}]}'>hi</span><sup about="#mwt7" class="mw-ref" id="cite_ref-2" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-2"},"attrs":{}}'><a href="./Main_Page#cite_note-2" style="counter-reset: mw-Ref 2;"><span class="mw-reflink-text">[2]</span></a></sup></p>
+<ol class="mw-references references" typeof="mw:Extension/references" about="#mwt10" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-1" id="cite_note-1"><a href="./Main_Page#cite_ref-1" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-1" class="mw-reference-text"><a rel="mw:WikiLink" href="./Ho" title="Ho" data-parsoid='{"stx":"piped","a":{"href":"./Ho"},"sa":{"href":"ho"}}'>hi</a></span></li><li about="#cite_note-2" id="cite_note-2"><a href="./Main_Page#cite_ref-2" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-2" class="mw-reference-text"><a typeof="mw:ExpandedAttrs" about="#mwt11" rel="mw:ExtLink" class="external autonumber" href="http://test.com?q=ho" data-mw='{"attribs":[[{"txt":"href"},{"html":"http://test.com?q=ho"}]]}'></a></span></li></ol>
+!! end
+
 ###
 ### Pre-save transform tests
 ###
@@ -14353,8 +14578,8 @@ thumbsize=220
 </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</p>
-<p>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></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>
 !! end
 
 !! test
@@ -14752,6 +14977,25 @@ Image with nested tables in caption
 </figcaption></figure>
 !! end
 
+!! test
+Image with heading and horizontal rule in caption
+!! wikitext
+[[File:Foobar.jpg|thumb|
+===Testing===
+123
+--------------
+]]
+!! 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" 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>
+123
+<hr data-parsoid='{"extra_dashes":10}'/>
+</figcaption></figure>
+!! end
+
 ###################
 # Conflicting image format options.
 # First option specified should 'win'.
@@ -15063,7 +15307,7 @@ T3887: A RFC with a thumbnail
 <div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></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 text">RFC 12354</a></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>This is <a href="https://tools.ietf.org/html/rfc12354" rel="mw:ExtLink" class="external mw-magiclink">RFC 12354</a></figcaption></figure>
 !! end
 
 !! test
@@ -15400,8 +15644,7 @@ Parsoid-specific image handling - simple image with size and middle alignment
 !! end
 
 !! test
-Parsoid-specific image handling - simple image with size, middle alignment,
-non-standard namespace alias
+Parsoid-specific image handling - simple image with size, middle alignment, non-standard namespace alias
 !! options
 parsoid=wt2wt,wt2html,html2html
 !! wikitext
@@ -15411,8 +15654,7 @@ parsoid=wt2wt,wt2html,html2html
 !! end
 
 !! test
-Parsoid-specific image handling - simple image with size and middle alignment
-(existing content)
+Parsoid-specific image handling - simple image with size and middle alignment (existing content)
 !! wikitext
 [[File:Foobar.jpg|50px|middle]]
 !! html/parsoid
@@ -15420,8 +15662,7 @@ Parsoid-specific image handling - simple image with size and middle alignment
 !! end
 
 !! test
-Parsoid-specific image handling - simple image with size and middle alignment
-and non-standard namespace name
+Parsoid-specific image handling - simple image with size and middle alignment and non-standard namespace name
 !! options
 parsoid=wt2html,wt2wt,html2html
 !! wikitext
@@ -15448,41 +15689,46 @@ Parsoid-specific image handling - simple image with border and size spec
 
 !! test
 Parsoid-specific image handling - thumbnail with halign, valign, and caption
+!! options
+parsoid=wt2html,html2html
 !! wikitext
 [[File:Foobar.jpg|left|baseline|thumb|caption content]]
 !! html/parsoid
-<figure class="mw-default-size mw-halign-left mw-valign-baseline" 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 content</figcaption></figure>
+<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 content</figcaption></figure>
 !! end
 
 !! test
-Parsoid-specific image handling - thumbnail with halign, valign, and caption
-(existing content)
+Parsoid-specific image handling - thumbnail with halign, valign, and caption (existing content)
+!! options
+parsoid=wt2html,html2html
 !! wikitext
 [[File:Foobar.jpg|thumb|left|baseline|caption content]]
 !! html/parsoid
-<figure class="mw-default-size mw-halign-left mw-valign-baseline" typeof="mw:Image/Thumb" data-parsoid='{"optList":[{"ck":"thumbnail","ak":"thumb"},{"ck":"left","ak":"left"},{"ck":"baseline","ak":"baseline"},{"ck":"caption","ak":"caption content"}]}'><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 content</figcaption></figure>
+<figure class="mw-default-size mw-halign-left" typeof="mw:Image/Thumb" data-parsoid='{"optList":[{"ck":"thumbnail","ak":"thumb"},{"ck":"left","ak":"left"},{"ck":"baseline","ak":"baseline"},{"ck":"caption","ak":"caption content"}]}'><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 content</figcaption></figure>
 !! end
 
 !! test
 Parsoid-specific image handling - thumbnail with specific size, halign, valign, and caption
+!! options
+parsoid=wt2html,html2html
 !! wikitext
 [[Image:Foobar.jpg|right|middle|thumb|50x50px|caption]]
 !! html/parsoid
-<figure class="mw-halign-right mw-valign-middle" 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>caption</figcaption></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/50px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="6" width="50"/></a><figcaption>caption</figcaption></figure>
 !! end
 
 !! test
-Parsoid-specific image handling - thumbnail with specific size, halign,
-valign, and caption (existing content)
+Parsoid-specific image handling - thumbnail with specific size, halign, valign, and caption (existing content)
+!! options
+parsoid=wt2html,html2html
 !! wikitext
 [[File:Foobar.jpg|thumb|50x50px|right|middle|caption]]
 !! html/parsoid
-<figure class="mw-halign-right mw-valign-middle" typeof="mw:Image/Thumb" data-parsoid='{"optList":[{"ck":"thumbnail","ak":"thumb"},{"ck":"width","ak":"50x50px"},{"ck":"right","ak":"right"},{"ck":"middle","ak":"middle"},{"ck":"caption","ak":"caption"}],"size":"50x50"}'><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/50px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="6" width="50" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"6","width":"50"},"sa":{"resource":"File:Foobar.jpg"}}'/></a><figcaption>caption</figcaption></figure>
+<figure class="mw-halign-right" typeof="mw:Image/Thumb" data-parsoid='{"optList":[{"ck":"thumbnail","ak":"thumb"},{"ck":"width","ak":"50x50px"},{"ck":"right","ak":"right"},{"ck":"middle","ak":"middle"},{"ck":"caption","ak":"caption"}],"size":"50x50"}'><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/50px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="6" width="50" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"6","width":"50"},"sa":{"resource":"File:Foobar.jpg"}}'/></a><figcaption>caption</figcaption></figure>
 !! end
 
 !! test
-Parsoid-specific image handling - framed image with specific size and caption
-(size is ignored)
+Parsoid-specific image handling - framed image with specific size and caption (size is ignored)
 !! options
 parsoid=wt2html,wt2wt,html2html
 !! wikitext
@@ -15492,14 +15738,13 @@ parsoid=wt2html,wt2wt,html2html
 !! end
 
 !! test
-Parsoid-specific image handling - framed image with specific size, halign, valign, and caption
-(size is ignored)
+Parsoid-specific image handling - framed image with specific size, halign, valign, and caption (size is ignored)
 !! options
-parsoid=wt2html,wt2wt,html2html
+parsoid=wt2html,html2html
 !! wikitext
 [[File:Foobar.jpg|left|baseline|frame|500x50px|caption]]
 !! html/parsoid
-<figure class="mw-halign-left mw-valign-baseline" 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-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>caption</figcaption></figure>
 !! end
 
 !! test
@@ -16042,33 +16287,49 @@ parsoid=wt2html
 !! test
 3. Categories and newlines: newline suppression for last list item should RT properly
 !! wikitext
-* a
-* b 
+*a
+*b
    
 [[Category:Foo]]
    
 [[Category:Bar]]
 [[Category:Baz]]
+
+:c
+
+[[Category:C]]
+
+;d
+
+[[Category:D]]
 !! html/parsoid
-<ul><li> a</li>
-<li> b</li></ul> 
+<ul><li>a</li>
+<li>b</li></ul>
    
-<link rel="mw:PageProp/Category" href="./Category:Foo" data-parsoid='{"stx":"simple","a":{"href":"./Category:Foo"},"sa":{"href":"Category:Foo"}}'/>
+<link rel="mw:PageProp/Category" href="./Category:Foo"/>
    
-<link rel="mw:PageProp/Category" href="./Category:Bar" data-parsoid='{"stx":"simple","a":{"href":"./Category:Bar"},"sa":{"href":"Category:Bar"}}'/>
-<link rel="mw:PageProp/Category" href="./Category:Baz" data-parsoid='{"stx":"simple","a":{"href":"./Category:Baz"},"sa":{"href":"Category:Baz"}}'/>
+<link rel="mw:PageProp/Category" href="./Category:Bar"/>
+<link rel="mw:PageProp/Category" href="./Category:Baz"/>
+
+<dl><dd>c</dd></dl>
+
+<link rel="mw:PageProp/Category" href="./Category:C"/>
+
+<dl><dt>d</dt></dl>
+
+<link rel="mw:PageProp/Category" href="./Category:D"/>
 !! end
 
 !! test
 4. Categories and newlines: newline suppression for last list item should RT properly
 !! wikitext
-* a
-**** b
+*a
+****b
 
 [[Category:Foo]]
 !! html/parsoid
-<ul><li> a
-<ul><li><ul><li><ul><li> b</li></ul></li></ul></li></ul></li></ul>
+<ul><li>a
+<ul><li><ul><li><ul><li>b</li></ul></li></ul></li></ul></li></ul>
 
 <link rel="mw:PageProp/Category" href="./Category:Foo" data-parsoid='{"stx":"simple","a":{"href":"./Category:Foo"},"sa":{"href":"Category:Foo"}}'/>
 !! end
@@ -16079,18 +16340,18 @@ parsoid=wt2html
 !! options
 parsoid=wt2html
 !! wikitext
-* a
-** b
+*a
+**b
 [[Category:Foo]]
-* c
-** d
+*c
+**d
 [[Category:Foo]]
 !! html/parsoid
-<ul><li> a
-<ul><li> b
+<ul><li>a
+<ul><li>b
 <link rel="mw:PageProp/Category" href="./Category:Foo" data-parsoid='{"stx":"simple","a":{"href":"./Category:Foo"},"sa":{"href":"Category:Foo"}}'/></li></ul></li>
-<li> c
-<ul><li> d</li></ul></li></ul>
+<li>c
+<ul><li>d</li></ul></li></ul>
 <link rel="mw:PageProp/Category" href="./Category:Foo" data-parsoid='{"stx":"simple","a":{"href":"./Category:Foo"},"sa":{"href":"Category:Foo"}}'/>
 !! end
 
@@ -16103,9 +16364,9 @@ parsoid=wt2html
 !! options
 parsoid=wt2html
 !! wikitext
-* a [[Category:Foo]]
+*a [[Category:Foo]]
 !! html/parsoid
-<ul><li>a <link rel="mw:PageProp/Category" href="./Category:Foo" data-parsoid='{"stx":"simple","a":{"href":"./Category:Foo"},"sa":{"href":"Category:Foo"}}'/></li></ul>
+<ul><li>a<link rel="mw:PageProp/Category" href="./Category:Foo" data-parsoid='{"stx":"simple","a":{"href":"./Category:Foo"},"sa":{"href":"Category:Foo"}}'/></li></ul>
 !! end
 
 # This test also demonstrates because of newline+category tunneling
@@ -16114,23 +16375,23 @@ parsoid=wt2html
 !! test
 7. Categories and newlines: migrateTrailingCategories dom pass should leave template content alone
 !! wikitext
-* {{echo|a
+*{{echo|a
 [[Category:Foo]]}}
 !! html/parsoid
-<ul><li> <span about="#mwt1" typeof="mw:Transclusion" data-parsoid='{"pi":[[{"k":"1"}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"a\n[[Category:Foo]]"}},"i":0}}]}'>a
+<ul><li><span about="#mwt1" typeof="mw:Transclusion" data-parsoid='{"pi":[[{"k":"1"}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"a\n[[Category:Foo]]"}},"i":0}}]}'>a
 </span><link rel="mw:PageProp/Category" href="./Category:Foo" about="#mwt1" data-parsoid='{"stx":"simple","a":{"href":"./Category:Foo"},"sa":{"href":"Category:Foo"}}'/></li></ul>
 !! end
 
 !! test
 8. Categories and newlines: migrateTrailingCategories dom pass should not get tripped by intervening templates
 !! wikitext
-* a
+*a
 
 {{echo|[[Category:Foo]]
 [[Category:Bar]]}}
 [[Category:Baz]]
 !! html/parsoid
-<ul><li> a</li></ul>
+<ul><li>a</li></ul>
 
 <link rel="mw:PageProp/Category" href="./Category:Foo" about="#mwt1" typeof="mw:Transclusion" data-parsoid='{"stx":"simple","a":{"href":"./Category:Foo"},"sa":{"href":"Category:Foo"},"pi":[[{"k":"1"}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"[[Category:Foo]]\n[[Category:Bar]]"}},"i":0}}]}'/><span about="#mwt1">
 </span><link rel="mw:PageProp/Category" href="./Category:Bar" about="#mwt1" data-parsoid='{"stx":"simple","a":{"href":"./Category:Bar"},"sa":{"href":"Category:Bar"}}'/>
@@ -16138,7 +16399,21 @@ parsoid=wt2html
 !! end
 
 !! test
-9. Categories and newlines: should behave properly with linkprefix (T87753)
+Categories and newlines: migrateTrailingCategories dom pass should not get tripped by comments and whitespace
+!! wikitext
+*a
+
+[[Category:Bar]]<!--boo1--> <!--boo2-->
+[[Category:Baz]]<!--boo3--> <!--boo4-->
+!! html/parsoid
+<ul><li>a</li></ul>
+
+<link rel="mw:PageProp/Category" href="./Category:Bar"/><!--boo1--> <!--boo2-->
+<link rel="mw:PageProp/Category" href="./Category:Baz"/><!--boo3--> <!--boo4-->
+!! end
+
+!! test
+Categories and newlines: should behave properly with linkprefix (T87753)
 !! options
 language=ar
 !! wikitext
@@ -16158,7 +16433,7 @@ foo bar</p>
 !! end
 
 !! test
-10. No regressions on internal links following category (T174639)
+No regressions on internal links following category (T174639)
 !! options
 parsoid=wt2html,html2html
 !! wikitext
@@ -16390,7 +16665,7 @@ Section headings with TOC
 Some text
 ===Another headline===
 !! html
-<div id="toc" class="toc"><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2></div>
+<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>
 <li class="toclevel-1 tocsection-1"><a href="#Headline_1"><span class="tocnumber">1</span> <span class="toctext">Headline 1</span></a>
 <ul>
@@ -16433,7 +16708,7 @@ __FORCETOC__
 ==Headline 2==
 ==Headline==
 !! html/php
-<div id="toc" class="toc"><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2></div>
+<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>
 <li class="toclevel-1 tocsection-1"><a href="#Headline_2"><span class="tocnumber">1</span> <span class="toctext">Headline 2</span></a></li>
 <li class="toclevel-1 tocsection-2"><a href="#Headline"><span class="tocnumber">2</span> <span class="toctext">Headline</span></a></li>
@@ -16467,7 +16742,7 @@ parsoid=wt2html
 =========Level 9 Heading=========
 ==========Level 10 Heading==========
 !! html/php
-<div id="toc" class="toc"><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2></div>
+<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>
 <li class="toclevel-1 tocsection-1"><a href="#Level_1_Heading"><span class="tocnumber">1</span> <span class="toctext">Level 1 Heading</span></a>
 <ul>
@@ -16531,7 +16806,7 @@ TOC regression (T11764)
 ==title 2==
 ===title 2.1===
 !! html
-<div id="toc" class="toc"><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2></div>
+<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>
 <li class="toclevel-1 tocsection-1"><a href="#title_1"><span class="tocnumber">1</span> <span class="toctext">title 1</span></a>
 <ul>
@@ -16566,7 +16841,7 @@ TOC for heading containing <span id="..."></span> (T96153)
 __FORCETOC__
 ==<span id="old-anchor"></span>New title==
 !! html/php
-<div id="toc" class="toc"><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2></div>
+<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>
 <li class="toclevel-1 tocsection-1"><a href="#New_title"><span class="tocnumber">1</span> <span class="toctext">New title</span></a></li>
 </ul>
@@ -16588,7 +16863,7 @@ wgMaxTocLevel=3
 ==title 2==
 ===title 2.1===
 !! html
-<div id="toc" class="toc"><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2></div>
+<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>
 <li class="toclevel-1 tocsection-1"><a href="#title_1"><span class="tocnumber">1</span> <span class="toctext">title 1</span></a>
 <ul>
@@ -16624,7 +16899,7 @@ wgMaxTocLevel=3
 ====Section 1.1.1.1====
 ==Section 2==
 !! html
-<div id="toc" class="toc"><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2></div>
+<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>
 <li class="toclevel-1 tocsection-1"><a href="#Section_1"><span class="tocnumber">1</span> <span class="toctext">Section 1</span></a>
 <ul>
@@ -16717,7 +16992,7 @@ __TOC__
 ===title 1.1===
 ==title 2==
 !! html
-<div id="toc" class="toc"><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2></div>
+<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>
 <li class="toclevel-1 tocsection-1"><a href="#title_1"><span class="tocnumber">1</span> <span class="toctext">title 1</span></a>
 <ul>
@@ -16793,7 +17068,7 @@ section 5
 !! html/php
 <p>The tooltips shall not show entities to the user (ie. be double escaped)
 </p>
-<div id="toc" class="toc"><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2></div>
+<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>
 <li class="toclevel-1 tocsection-1"><a href="#text_.3E_text"><span class="tocnumber">1</span> <span class="toctext">text &gt; text</span></a></li>
 <li class="toclevel-1 tocsection-2"><a href="#text_.3C_text"><span class="tocnumber">2</span> <span class="toctext">text &lt; text</span></a></li>
@@ -16869,7 +17144,7 @@ section 6
 !! html/php
 <p>Id should not contain + for spaces
 </p>
-<div id="toc" class="toc"><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2></div>
+<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>
 <li class="toclevel-1 tocsection-1"><a href="#Space_between_Text"><span class="tocnumber">1</span> <span class="toctext">Space between Text</span></a></li>
 <li class="toclevel-1 tocsection-2"><a href="#Space-Entity_between_Text"><span class="tocnumber">2</span> <span class="toctext">Space-Entity&#32;between&#32;Text</span></a></li>
@@ -16945,7 +17220,7 @@ parsoid=wt2html,wt2wt,html2html
 =''italic'' heading==
 ==''italic'' heading=
 !! html/php
-<div id="toc" class="toc"><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2></div>
+<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>
 <li class="toclevel-1 tocsection-1"><a href="#foo.3D"><span class="tocnumber">1</span> <span class="toctext">foo=</span></a></li>
 <li class="toclevel-1 tocsection-2"><a href="#.3Dfoo"><span class="tocnumber">2</span> <span class="toctext">=foo</span></a></li>
@@ -16980,7 +17255,7 @@ HTML headers vs TOC (T25393)
 ==Header 2.2==
 __NOEDITSECTION__
 !! html/php
-<div id="toc" class="toc"><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2></div>
+<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>
 <li class="toclevel-1"><a href="#Header_1"><span class="tocnumber">1</span> <span class="toctext">Header 1</span></a>
 <ul>
@@ -17454,6 +17729,8 @@ Media link with text
 # Parsoid & Remex fix the p-wrapping since they operate on the DOM.
 !! test
 Media link with nasty text
+!! options
+parsoid=wt2html,html2html
 !! wikitext
 [[Media:Foobar.jpg|Safe Link<div style=display:none>" onmouseover="alert(document.cookie)" onfoo="</div>]]
 !! html/php
@@ -17462,8 +17739,7 @@ Media link with nasty text
 !! 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
-<p><a rel="mw:MediaLink" href="//example.com/images/3/3a/Foobar.jpg" title="Foobar.jpg" data-parsoid='{"autoInsertedEnd":true}'>Safe Link</a></p><div style="display:none" data-parsoid='{"stx":"html"}'><a rel="mw:MediaLink" href="//example.com/images/3/3a/Foobar.jpg" title="Foobar.jpg" data-parsoid='{"autoInsertedEnd":true,"autoInsertedStart":true}'>" onmouseover="alert(document.cookie)" onfoo="</a></div>
-
+<p><a rel="mw:MediaLink" href="//example.com/images/3/3a/Foobar.jpg" title="Foobar.jpg">Safe Link</a></p><a rel="mw:MediaLink" href="//example.com/images/3/3a/Foobar.jpg" title="Foobar.jpg"><div style="display:none" data-parsoid='{"stx":"html"}'>" onmouseover="alert(document.cookie)" onfoo="</div></a>
 !! end
 
 !! test
@@ -18177,6 +18453,8 @@ array (
 
 !! test
 Parser hook: nested tags
+!! options
+parsoid=wt2html
 !! wikitext
 <tag><tag></tag></tag>
 !! html/php
@@ -18186,8 +18464,14 @@ array (
 )
 </pre>&lt;/tag&gt;
 
+!! html/php+tidy
+<pre>'<tag>'
+array (
+)
+</tag></pre><p>&lt;/tag&gt;
+</p>
 !! html/parsoid
-<pre typeof="mw:Extension/tag" data-mw='{"name":"tag","attrs":{},"body":{"extsrc":"&lt;tag>"}}' data-parsoid='{}' about="#mwt2"></pre>&lt;/tag>
+<pre typeof="mw:Extension/tag" about="#mwt2" data-mw='{"name":"tag","attrs":{},"body":{"extsrc":"&lt;tag>"}}'></pre><p>&lt;/tag></p>
 !! end
 
 !! test
@@ -18263,7 +18547,7 @@ array (
 </pre>text
 
 !! html/parsoid
-<pre typeof="mw:Extension/tag" data-mw='{"name":"tag","attrs":{"foo":"bar"},"body":null}' data-parsoid='{}' about="#mwt2"></pre>text
+<pre typeof="mw:Extension/tag" about="#mwt2" data-mw='{"name":"tag","attrs":{"foo":"bar"},"body":null}'></pre><p>text</p>
 !! end
 
 ## </tag> should be output literally since there is no matching tag that begins it
@@ -18395,8 +18679,6 @@ Nested template calls
 ### Sanitizer
 ###
 
-# Remex wraps empty tag runs with p-tags.
-# Parsoid strips them out during p-wrapping.
 !! test
 Sanitizer: Closing of open tags
 !! wikitext
@@ -18404,7 +18686,7 @@ Sanitizer: Closing of open tags
 !! html/php+tidy
 <p><s></s></p><table></table>
 !! html/parsoid
-<s></s><table></table>
+<p><s data-parsoid='{"stx":"html"}'></s></p><table data-parsoid='{"stx":"html"}'></table>
 !! end
 
 !! test
@@ -18422,10 +18704,9 @@ Sanitizer: Closing of closed but not open tags
 parsoid=wt2html
 !! wikitext
 </s>
-!! html/php+tidy
+!! html+tidy
 <p class="mw-empty-elt">
 </p>
-!! html/parsoid
 !! end
 
 !! test
@@ -18630,7 +18911,7 @@ Punctuation: CSS ! important (T13874; with space after)
 !! wikitext
 <div style="width:50% ! important">important</div>
 !! html
-<div style="width:50% ! important">important</div>
+<div style="width:50%&#32;! important">important</div>
 
 !!end
 
@@ -18906,7 +19187,7 @@ Fuzz testing: Parser14
 http://__TOC__
 !! html/php
 <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>
-http://<div id="toc" class="toc"><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2></div>
+http://<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>
 <li class="toclevel-1 tocsection-1"><a href="#onmouseover.3D"><span class="tocnumber">1</span> <span class="toctext">onmouseover=</span></a></li>
 </ul>
@@ -18915,7 +19196,7 @@ http://<div id="toc" class="toc"><div class="toctitle" lang="en" dir="ltr"><h2>C
 
 !! 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"><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2></div>
+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>
 <ul>
 <li class="toclevel-1 tocsection-1"><a href="#onmouseover.3D"><span class="tocnumber">1</span> <span class="toctext">onmouseover=</span></a></li>
 </ul>
@@ -19002,7 +19283,8 @@ http://===r:::https://b
 
 !! end
 
-# Known to produce bad XML for now
+## Remex doesn't account for fostered content.
+## Known to produce bad XML for now
 !! test
 Fuzz testing: Parser24
 !! options
@@ -19029,14 +19311,27 @@ MOVE YOUR MOUSE CURSOR OVER THIS TEXT
 </tr>
 </table>
 
-!! html/parsoid
-<p data-parsoid='{"fostered":true,"autoInsertedEnd":true}'>{{{|
-<u class="|" data-parsoid='{"stx":"html","a":{"{{{{SSSll!!!!!!!VVVV)]]][[Special:*xxxxxxx--":null},"sa":{"{{{{SSSll!!!!!!!VVVV)]]][[Special:*xxxxxxx--":""},"autoInsertedEnd":true}'><meta typeof="mw:Includes/NoInclude" data-parsoid='{"src":"&lt;noinclude>"}'/>}}}} >
-<br style="onmouseover='alert(document.cookie);' " data-parsoid='{"stx":"html","selfClose":true}'/></u></p><p data-parsoid='{"fostered":true,"autoInsertedEnd":true}'><u class="|" data-parsoid='{"stx":"html","a":{"{{{{SSSll!!!!!!!VVVV)]]][[Special:*xxxxxxx--":null},"sa":{"{{{{SSSll!!!!!!!VVVV)]]][[Special:*xxxxxxx--":""},"autoInsertedEnd":true,"autoInsertedStart":true}'>MOVE YOUR MOUSE CURSOR OVER THIS TEXT</u></p><table data-parsoid='{"autoInsertedEnd":true}'>
+!! html/php+tidy
 
+{{{|
+<u class="&#124;">}}}} &gt;
+<br style="onmouseover=&#39;alert(document.cookie);&#39;" />
 
+MOVE YOUR MOUSE CURSOR OVER THIS TEXT
+</u><table><tbody><tr>
+<td>
+</td>
+</tr>
+</tbody></table><p><u class="&#124;">
+</u></p>
+!! html/parsoid
+<p data-parsoid='{"fostered":true,"autoInsertedEnd":true,"autoInsertedStart":true}'>
+{{{|
+<u class="|" data-parsoid='{"stx":"html","a":{"{{{{SSSll!!!!!!!VVVV)]]][[Special:*xxxxxxx--":null},"sa":{"{{{{SSSll!!!!!!!VVVV)]]][[Special:*xxxxxxx--":""},"autoInsertedEnd":true}'><meta typeof="mw:Includes/NoInclude" data-parsoid='{"src":"&lt;noinclude>"}'/>}}}} >
+<br style="onmouseover='alert(document.cookie);' " data-parsoid='{"stx":"html","selfClose":true}'/>
 
-<tbody><tr data-parsoid='{"autoInsertedEnd":true,"autoInsertedStart":true}'><td data-parsoid='{"autoInsertedEnd":true}'></td></tr></tbody></table>
+MOVE YOUR MOUSE CURSOR OVER THIS TEXT</u></p>
+<table data-parsoid='{"autoInsertedEnd":true}'><tbody><tr data-parsoid='{"autoInsertedStart":true}'><td></td></tr></tbody></table>
 !! end
 
 # Note: the current result listed for this is not what the original one was,
@@ -19228,6 +19523,10 @@ New wiki paragraph
 <p><b>Bold paragraph
 </p><p>New wiki paragraph</b>
 </p>
+!! html/php+tidy
+<p><b>Bold paragraph
+</b></p><p><b>New wiki paragraph
+</b></p>
 !! html/parsoid
 <p><b>Bold paragraph</b>
 </p><p>New wiki paragraph
@@ -20177,7 +20476,7 @@ parsoid=wt2html
 '''''
 !! html/php
 !! html/parsoid
-<b><i></i></b>
+<p><b><i></i></b></p>
 !! end
 
 # same html as previous, but wikitext adjusted to match parsoid html2wt
@@ -20946,6 +21245,25 @@ File:Foobar.jpg
 </ul>
 !! end
 
+!! test
+Serialize gallery image captions on a line
+!! options
+parsoid={
+  "modes": ["html2wt"],
+  "nativeGallery": true
+}
+!! 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;"><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"><p>hi</p><p>ho</p></div></li>
+<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">hi<br />ho</div></li>
+</ul>
+!! wikitext
+<gallery>
+File:Foobar.jpg| hi  ho 
+File:Foobar.jpg|hi<br />ho
+</gallery>
+!! end
+
 !! test
 HTML Hex character encoding (spells the word "JavaScript")
 !! options
@@ -21105,18 +21423,22 @@ T24905: <abbr> followed by ISBN followed by </a>
 Double RFC
 !! wikitext
 RFC RFC 1234
-!! html
+!! html/php
 <p>RFC <a class="external mw-magiclink-rfc" rel="nofollow" href="https://tools.ietf.org/html/rfc1234">RFC 1234</a>
 </p>
+!! html/parsoid
+<p>RFC <a href="https://tools.ietf.org/html/rfc1234" rel="mw:ExtLink" class="external mw-magiclink">RFC 1234</a></p>
 !! end
 
 !! test
 Double RFC with a wiki link
 !! wikitext
 RFC [[RFC 1234]]
-!! html
+!! html/php
 <p>RFC <a href="/index.php?title=RFC_1234&amp;action=edit&amp;redlink=1" class="new" title="RFC 1234 (page does not exist)">RFC 1234</a>
 </p>
+!! html/parsoid
+<p>RFC <a rel="mw:WikiLink" href="./RFC_1234" title="RFC 1234">RFC 1234</a></p>
 !! end
 
 !! test
@@ -21127,7 +21449,7 @@ RFC   983&#x20;987
 <p><a class="external mw-magiclink-rfc" rel="nofollow" href="https://tools.ietf.org/html/rfc983">RFC 983</a>&#x20;987
 </p>
 !! html/parsoid
-<p><a href="https://tools.ietf.org/html/rfc983" rel="mw:ExtLink" class="external text" data-parsoid='{"stx":"magiclink"}'>RFC   983</a><span typeof="mw:Entity" data-parsoid='{"src":"&amp;#x20;","srcContent":" "}'> </span>987</p>
+<p><a href="https://tools.ietf.org/html/rfc983" rel="mw:ExtLink" class="external mw-magiclink" data-parsoid='{"stx":"magiclink"}'>RFC   983</a><span typeof="mw:Entity" data-parsoid='{"src":"&amp;#x20;","srcContent":" "}'> </span>987</p>
 !! end
 
 !! test
@@ -21372,21 +21694,21 @@ parsoid=wt2html
 !! test
 Definition list code coverage
 !! wikitext
-;title   : def
-;title : def
-;title: def
+;title   :def
+;title :def
+;title:def
 !! html/php
-<dl><dt>title  &#160;</dt>
+<dl><dt>title</dt>
 <dd>def</dd>
-<dt>title&#160;</dt>
+<dt>title</dt>
 <dd>def</dd>
 <dt>title</dt>
 <dd>def</dd></dl>
 
 !! html/parsoid
-<dl><dt>title  <span typeof="mw:Placeholder"> </span></dt><dd> def</dd>
-<dt>title<span typeof="mw:Placeholder"> </span></dt><dd> def</dd>
-<dt>title</dt><dd> def</dd></dl>
+<dl><dt>title   </dt><dd>def</dd>
+<dt>title </dt><dd>def</dd>
+<dt>title</dt><dd>def</dd></dl>
 !! end
 
 !! test
@@ -21464,7 +21786,7 @@ Out-of-order TOC heading levels
 =====5=====
 ==2==
 !! html
-<div id="toc" class="toc"><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2></div>
+<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>
 <li class="toclevel-1 tocsection-1"><a href="#2"><span class="tocnumber">1</span> <span class="toctext">2</span></a>
 <ul>
@@ -21939,11 +22261,11 @@ conversion:
 
 ==Latinski==
 !! html/php
-<h2><span id="-.7BNaslov.7D-"></span><span class="mw-headline" id="-{Naslov}-">Naslov</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="Уреди одељак „Naslov“">уреди</a><span class="mw-editsection-bracket">]</span></span></h2>
+<h2><span id="-.7BNaslov.7D-"></span><span class="mw-headline" id="-{Naslov}-">Naslov</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="Уредите одељак „Naslov“">уреди</a><span class="mw-editsection-bracket">]</span></span></h2>
 <p>Ноте тхат евен ан унпротецтед хеадлине ИД ис нот аффецтед бy лангуаге
 цонверсион:
 </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>
+<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>
@@ -22508,11 +22830,11 @@ language=zh variant=zh-cn
 <span>ad
 </span></div></span></div></span>
 !! html/parsoid
-<p><span data-parsoid='{"stx":"html","autoInsertedEnd":true}'>a</span></p><div typeof="mw:LanguageVariant" data-mw-variant='{"disabled":{"t":"b&lt;div data-parsoid=&#39;{\"stx\":\"html\",\"autoInsertedEnd\":true,\"dsr\":[10,16,5,0]}&#39;>c&lt;/div>"}}'></div><p>d</p>
+<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
 
-<p><span data-parsoid='{"stx":"html","autoInsertedEnd":true}'>a</span></p><div typeof="mw:LanguageVariant" data-mw-variant='{"filter":{"l":["zh","zh-hans","zh-hant"],"t":"b&lt;div data-parsoid=&#39;{\"stx\":\"html\",\"autoInsertedEnd\":true,\"dsr\":[50,56,5,0]}&#39;>c&lt;/div>"}}'></div><p>d</p>
+<span data-parsoid='{"stx":"html","autoInsertedEnd":true}'>a<div typeof="mw:LanguageVariant" data-mw-variant='{"filter":{"l":["zh","zh-hans","zh-hant"],"t":"b&lt;div data-parsoid=&apos;{\"stx\":\"html\",\"autoInsertedEnd\":true,\"dsr\":[50,56,5,0]}&apos;>c&lt;/div>"}}'></div>d
 
-<p><span data-parsoid='{"stx":"html","autoInsertedEnd":true}'>a<meta typeof="mw:LanguageVariant" data-mw-variant='{"add":true,"oneway":[{"f":"0","l":"zh-cn","t":"x&lt;span data-parsoid=&#39;{\"stx\":\"html\",\"autoInsertedEnd\":true,\"dsr\":[82,89,6,0]}&#39;>y&lt;/span>"},{"f":"0","l":"zh-tw","t":"b&lt;div data-parsoid=&#39;{\"stx\":\"html\",\"autoInsertedEnd\":true,\"dsr\":[100,106,5,0]}&#39;>c&lt;/div>"}]}'/>d</span></p>
+<p><span data-parsoid='{"stx":"html","autoInsertedEnd":true}'>a<meta typeof="mw:LanguageVariant" data-mw-variant='{"add":true,"oneway":[{"f":"0","l":"zh-cn","t":"x&lt;span data-parsoid=&apos;{\"stx\":\"html\",\"autoInsertedEnd\":true,\"dsr\":[82,89,6,0]}&apos;>y&lt;/span>"},{"f":"0","l":"zh-tw","t":"b&lt;div data-parsoid=&apos;{\"stx\":\"html\",\"autoInsertedEnd\":true,\"dsr\":[100,106,5,0]}&apos;>c&lt;/div>"}]}'/>d</span></p></span></span>
 !! end
 
 !! test
@@ -22634,8 +22956,8 @@ gopher://www.google.com
 !! html/parsoid
 <p><a rel="mw:ExtLink" class="external free" href="http://www.google.com">http://www.google.com</a>
 <a rel="mw:ExtLink" class="external free" href="gopher://www.google.com">gopher://www.google.com</a>
-<a rel="mw:ExtLink" class="external free" href="http://www.google.com">http://www.google.com</a>
-<a rel="mw:ExtLink" class="external free" href="gopher://www.google.com">gopher://www.google.com</a>
+<a rel="mw:ExtLink" class="external text" href="http://www.google.com">http://www.google.com</a>
+<a rel="mw:ExtLink" class="external text" href="gopher://www.google.com">gopher://www.google.com</a>
 <a rel="mw:ExtLink" class="external text" href="https://www.google.com">irc://www.google.com</a>
 <a rel="mw:ExtLink" class="external text" href="ftp://www.google.com">www.google.com/ftp://dir</a>
 <a rel="mw:ExtLink" class="external text" href="//www.google.com">www.google.com</a></p>
@@ -22711,7 +23033,7 @@ language=sr
 !! wikitext
 [[Датотека: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" 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>
+<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" 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>
@@ -22796,10 +23118,8 @@ language=zh variant=zh-cn
 <dt>-{zh-cn:AAA</dt></b></dl><p><b>
 </b></p>
 !! html/parsoid
-<dl><dt data-parsoid='{"dsr":[0,11,1,0]}'><b data-parsoid='{"stx":"html","autoInsertedEnd":true}'>foo:bar</b></dt><b data-parsoid='{"stx":"html","autoInsertedEnd":true,"autoInsertedStart":true}'>
-<dt data-parsoid='{"dsr":[12,20,1,0]}'>-{zh-cn</dt>
-<dd data-parsoid='{"stx":"row","dsr":[20,24,1,0]}'>AAA</dd>
-</b></dl>
+<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>
 !! end
 
 !! test
@@ -23164,7 +23484,6 @@ Line two
 !! end
 
 # doBlockLevels screws up this output and Remex cleans up as much as it can.
-# Parsoid seems to do a better job here since its p-wrapper is probably smarter.
 !! test
 Nesting tags, paragraphs on lines which begin with <div>
 !! wikitext
@@ -23175,15 +23494,15 @@ B</strong>
 </strong></p><strong></strong><p><strong>B</strong>
 </p>
 !! html/parsoid
-<div></div>
-<p><strong>A
-B</strong>
-</p>
+<div data-parsoid='{"stx":"html"}'></div><p><strong data-parsoid='{"stx":"html","autoInsertedEnd":true}'>A</strong></p>
+<p><strong data-parsoid='{"stx":"html","autoInsertedStart":true}'>B</strong></p>
 !! end
 
 # T8200: <blockquote> should behave like <div> with respect to line breaks
 !! test
 T8200: paragraphs inside blockquotes (no extra line breaks)
+!! options
+parsoid=wt2html,html2html
 !! wikitext
 <blockquote>Line one
 
@@ -23199,6 +23518,8 @@ Line two</p></blockquote>
 
 !! test
 T8200: paragraphs inside blockquotes (extra line break on open)
+!! options
+parsoid=wt2html,html2html
 !! wikitext
 <blockquote>
 Line one
@@ -23217,9 +23538,10 @@ Line two</blockquote>
 Line two</p></blockquote>
 !! end
 
-# Parsoid's output is broken on this because of Tidy-compatibility cruft
 !! test
 T8200: paragraphs inside blockquotes (extra line break on close)
+!! options
+parsoid=wt2html,html2html
 !! wikitext
 <blockquote>Line one
 
@@ -23255,7 +23577,12 @@ Line two
 
 !! end
 
-# FIXME: Why does/should the blockquote+div combo suppress p-wrapping here?
+## This is a corner case interaction between the paragraph wrapping in the
+## php parser's BlockLevelPass and Remex.  `doBlockLevels` has a notion of
+## some tags which close paragraphs (and thus prevent wrapping on their line),
+## of which "div" is one, but do p-wrapping inside them.  These are referred
+## to as "never suppressing".  Remex, for its part, doesn't traverse into
+## "div"s to p-wrap.  Hence, we only get this partial wrapping.
 !! test
 Paragraphs inside blockquotes/divs (no extra line breaks)
 !! wikitext
@@ -23893,7 +24220,7 @@ Play a bit with r67090 and T5158
 <div style="width:50% !important">&#160;</div>
 <div style="width:50% !important">&#160;</div>
 <div style="width:50% !important">&#160;</div>
-<div style="border&#160;: solid;">&#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>
@@ -23904,10 +24231,42 @@ Play a bit with r67090 and T5158
 !! end
 
 !! test
-HTML5 data attributes
+French spaces in wikitext
 !! wikitext
-<span data-foo="bar">Baz</span>
-<p data-abc-def_hij="">Quuz</p>
+foo ! bar ? bat 50 % is less than 75 %.
+
+Hello : this ; is « something ‹ else › again »
+!! html
+<p>foo&#160;! bar&#160;? bat 50&#160;% is less than 75&#160;%.
+</p><p>Hello&#160;: this&#160;; is «&#160;something ‹&#160;else&#160;› again&#160;»
+</p>
+!! end
+
+# It would be reasonable for Parsoid and PHP to differ here.
+# The PHP behavior is arguably a bug.
+!! test
+Corner case: french spaces in definition list
+!! wikitext
+;foo : bar
+!! html+tidy
+<dl><dt>foo&#160;</dt>
+<dd>bar</dd></dl>
+!! end
+
+!! test
+T5158: Test for French spaces in attributes
+!! wikitext
+<br style=" clear : both ; " />
+!! html/php
+<p><br style="clear&#32;: both&#32;;" />
+</p>
+!! end
+
+!! test
+HTML5 data attributes
+!! wikitext
+<span data-foo="bar">Baz</span>
+<p data-abc-def_hij="">Quuz</p>
 !! html/php
 <p><span data-foo="bar">Baz</span>
 </p>
@@ -24097,7 +24456,7 @@ title=[[Main Page]]
 __TOC__
 ==''Lost'' episodes==
 !! html/php
-<div id="toc" class="toc"><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2></div>
+<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>
 <li class="toclevel-1 tocsection-1"><a href="#Lost_episodes"><span class="tocnumber">1</span> <span class="toctext"><i>Lost</i> episodes</span></a></li>
 </ul>
@@ -24118,7 +24477,7 @@ title=[[Main Page]]
 __TOC__
 =='''should be bold''' then normal text==
 !! html/php
-<div id="toc" class="toc"><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2></div>
+<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>
 <li class="toclevel-1 tocsection-1"><a href="#should_be_bold_then_normal_text"><span class="tocnumber">1</span> <span class="toctext"><b>should be bold</b> then normal text</span></a></li>
 </ul>
@@ -24139,7 +24498,7 @@ title=[[Main Page]]
 __TOC__
 ==Image [[Image:foobar.jpg]]==
 !! html/php
-<div id="toc" class="toc"><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2></div>
+<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>
 <li class="toclevel-1 tocsection-1"><a href="#Image"><span class="tocnumber">1</span> <span class="toctext">Image</span></a></li>
 </ul>
@@ -24160,7 +24519,7 @@ title=[[Main Page]]
 __TOC__
 ==<blockquote>Quote</blockquote>==
 !! html/php
-<div id="toc" class="toc"><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2></div>
+<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>
 <li class="toclevel-1 tocsection-1"><a href="#Quote"><span class="tocnumber">1</span> <span class="toctext">Quote</span></a></li>
 </ul>
@@ -24169,7 +24528,7 @@ __TOC__
 <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"><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2></div>
+<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>
 <li class="toclevel-1 tocsection-1"><a href="#Quote"><span class="tocnumber">1</span> <span class="toctext">Quote</span></a></li>
 </ul>
@@ -24178,7 +24537,7 @@ __TOC__
 <h2><span class="mw-headline" id="Quote"><blockquote><p>Quote</p></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/parsoid
 <meta property="mw:PageProp/toc" data-parsoid='{}'/>
-<h2 id="Quote" data-parsoid='{}'><blockquote>Quote</blockquote></h2>
+<h2 id="Quote" data-parsoid='{}'><blockquote><p>Quote</p></blockquote></h2>
 !! end
 
 !! test
@@ -24193,7 +24552,7 @@ __TOC__
 <small>Hanc marginis exiguitas non caperet.</small>
 QED
 !! html/php
-<div id="toc" class="toc"><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2></div>
+<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>
 <li class="toclevel-1 tocsection-1"><a href="#Proof:_2_&lt;_3"><span class="tocnumber">1</span> <span class="toctext">Proof: 2 &lt; 3</span></a></li>
 </ul>
@@ -24218,7 +24577,7 @@ __TOC__
 
 ==<i>Foo</i> <blockquote>Bar</blockquote>==
 !! html/php
-<div id="toc" class="toc"><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2></div>
+<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>
 <li class="toclevel-1 tocsection-1"><a href="#Foo_Bar"><span class="tocnumber">1</span> <span class="toctext"><i>Foo</i> <b>Bar</b></span></a></li>
 <li class="toclevel-1 tocsection-2"><a href="#Foo_Bar_2"><span class="tocnumber">2</span> <span class="toctext"><i>Foo</i> Bar</span></a></li>
@@ -24229,7 +24588,7 @@ __TOC__
 <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"><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2></div>
+<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>
 <li class="toclevel-1 tocsection-1"><a href="#Foo_Bar"><span class="tocnumber">1</span> <span class="toctext"><i>Foo</i> <b>Bar</b></span></a></li>
 <li class="toclevel-1 tocsection-2"><a href="#Foo_Bar_2"><span class="tocnumber">2</span> <span class="toctext"><i>Foo</i> Bar</span></a></li>
@@ -24242,7 +24601,7 @@ __TOC__
 <meta property="mw:PageProp/toc" data-parsoid='{}'/>
 <h2 id="Foo_Bar" data-parsoid='{}'><i data-parsoid='{"stx":"html"}'>Foo</i> <b data-parsoid='{"stx":"html"}'>Bar</b></h2>
 
-<h2 id="Foo_Bar_2" data-parsoid='{}'><i data-parsoid='{"stx":"html"}'>Foo</i> <blockquote>Bar</blockquote></h2>
+<h2 id="Foo_Bar_2" data-parsoid='{}'><i data-parsoid='{"stx":"html"}'>Foo</i> <blockquote><p>Bar</p></blockquote></h2>
 !! end
 
 # Don't expect Parsoid to roundtrip this until the php parser comes closer to
@@ -24257,7 +24616,7 @@ __TOC__
 
 ==<sup class="a > b">Evilbye</sup>==
 !! html/php
-<div id="toc" class="toc"><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2></div>
+<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>
 <li class="toclevel-1 tocsection-1"><a href="#Hello"><span class="tocnumber">1</span> <span class="toctext"><sup>Hello</sup></span></a></li>
 <li class="toclevel-1 tocsection-2"><a href="#b.22.3EEvilbye"><span class="tocnumber">2</span> <span class="toctext"><sup> b"&gt;Evilbye</sup></span></a></li>
@@ -24288,7 +24647,7 @@ __TOC__
 
 ==<span dir="ltr" style="font-style: italic">Attributes after dir on these span tags must be deleted from the TOC</span>==
 !! html/php
-<div id="toc" class="toc"><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2></div>
+<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>
 <li class="toclevel-1 tocsection-1"><a href="#C.2B.2B"><span class="tocnumber">1</span> <span class="toctext"><span dir="ltr">C++</span></span></a></li>
 <li class="toclevel-1 tocsection-2"><a href="#.D7.96.D7.91.D7.A0.D7.92.21"><span class="tocnumber">2</span> <span class="toctext"><span dir="rtl">זבנג!</span></span></a></li>
@@ -24319,7 +24678,7 @@ T74884: bdi element in ToC
 __TOC__
 ==<bdi>test</bdi>==
 !! html/php
-<div id="toc" class="toc"><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2></div>
+<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>
 <li class="toclevel-1 tocsection-1"><a href="#test"><span class="tocnumber">1</span> <span class="toctext"><bdi>test</bdi></span></a></li>
 </ul>
@@ -24338,7 +24697,7 @@ T35715: s/strike element in ToC
 __TOC__
 ==<s>test</s> test <strike>test</strike>==
 !! html/php
-<div id="toc" class="toc"><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2></div>
+<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>
 <li class="toclevel-1 tocsection-1"><a href="#test_test_test"><span class="tocnumber">1</span> <span class="toctext"><s>test</s> test <strike>test</strike></span></a></li>
 </ul>
@@ -24351,13 +24710,34 @@ __TOC__
 <h2 id="test_test_test" data-parsoid='{}'><s>test</s> test <strike>test</strike></h2>
 !! end
 
+!! test
+T198618: style element in ToC
+!! options
+styletag=1
+!! wikitext
+__TOC__
+==<style>.foo {}</style>Style<style>.bar {}</style>==
+!! html/php
+<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>
+<li class="toclevel-1 tocsection-1"><a href="#Style"><span class="tocnumber">1</span> <span class="toctext">Style</span></a></li>
+</ul>
+</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>.foo {}</style>Style<style>.bar {}</style></h2>
+!! end
+
 !! test
 Empty <p> tag in TOC, removed by Sanitizer (T92892)
 !! wikitext
 __TOC__
 ==x==
 !! html/php
-<div id="toc" class="toc"><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2></div>
+<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>
 <li class="toclevel-1 tocsection-1"><a href="#x"><span class="tocnumber">1</span> <span class="toctext">x</span></a></li>
 </ul>
@@ -24585,6 +24965,17 @@ abc
 <span typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"padright:","function":"padright"},"params":{"1":{"wt":"3"},"2":{"wt":"abcde"}},"i":0}}]}'>abc</span></p>
 !! end
 
+!! test
+Padleft and padright with non-numerical length (T180403)
+!! wikitext
+{{padleft:abcdef|junk}}
+{{padright:abcdef|junk}}
+!! html/php
+<p>abcdef
+abcdef
+</p>
+!! end
+
 !!test
 Special parser function
 !! wikitext
@@ -24681,13 +25072,13 @@ parsoid=wt2html,wt2wt
 #### Parsoid-specific functionality tests
 #### -----------------------------------------------------------------
 
-# T65642/T68749: Formatting elt fixup around images is cleaned up.
+# T65642/T68749: Formatting elt fixup around images.
 # We know wt2wt will fail, but we expect selser to pass.
 # Due to the nature of our testing, wt2wt and selser tests will enter the
 # blacklist and we'll catch selser regressions based on changes to the
 # blacklist entries for selser tests.
 !! test
-1. Bad treebuilder fixup of formatting elt is cleaned up
+1. Treebuilder fixup of formatting elt
 !! options
 parsoid=wt2html,wt2wt
 !! wikitext
@@ -24697,50 +25088,63 @@ parsoid=wt2html,wt2wt
 [[Image:Foobar.jpg|right|Test]]
 </small>
 |}
+!! html/php+tidy
+<table>
+<tbody><tr>
+<td>
+<p><small>
+</small></p><small>
+<div class="floatright"><a href="/wiki/File:Foobar.jpg" class="image" title="Test"><img alt="Test" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a></div>
+</small><p><small></small>
+</p>
+</td></tr></tbody></table>
 !! html/parsoid
 <table>
 <tbody><tr><td>
-<small>
-<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>Test</figcaption></figure>
-</small>
-</td></tr>
+<p><small data-parsoid='{"stx":"html","autoInsertedEnd":true}'></small></p><small data-parsoid='{"stx":"html","autoInsertedEnd":true,"autoInsertedStart":true}'>
+<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>Test</figcaption></figure></small>
+<p><small data-parsoid='{"stx":"html","autoInsertedStart":true}'></small></p></td></tr>
 </tbody></table>
 !! end
 
 !! test
-2. Bad treebuilder fixup of formatting elt is cleaned up
+2. Treebuilder fixup of formatting elt
 !! options
 parsoid=wt2html,wt2wt
 !! wikitext
 '''foo[[File:Foobar.jpg|thumb|caption]]bar'''
 
 <small>[[Image:Foobar.jpg|right|300px]]</small>
+!! html/php+tidy
+<p><b>foo</b></p><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" 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><p><b>bar</b>
+</p><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" 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>
 !! 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>
 
-<p><b>foo</b></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><b>caption</b></figcaption></figure>
-<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>
 !! end
 
 !! test
-3. Bad treebuilder fixup of formatting elt is cleaned up
+3. Treebuilder fixup of formatting elt
 !! options
 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" 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>
-<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><small><b>caption</b></small></figcaption></figure>
-<p><small><b>bar</b></small></p>
+<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
 
 !! test
-4. Bad treebuilder fixup of formatting elt is cleaned up: formatting tags around captionless images are ignored
+4. Treebuilder fixup of formatting elt: formatting tags around captionless images
 !! options
 parsoid=wt2html,wt2wt
 !! wikitext
 '''<small>[[Image:Foobar.jpg|right|300px]]</small>'''
+!! 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" 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>
 !! end
@@ -24806,9 +25210,9 @@ Empty LI and TR nodes should be stripped from template content
 !! test
 Empty LI and TR nodes should not be stripped from top-level content
 !! wikitext
-* a
+*a
 *
-* b
+*b
 
 {|
 |-
@@ -24817,9 +25221,9 @@ Empty LI and TR nodes should not be stripped from top-level content
 |}
 !! html/parsoid
 <ul>
-<li> a</li>
+<li>a</li>
 <li class='mw-empty-elt'></li>
-<li> b</li>
+<li>b</li>
 </ul>
 <table>
 <tbody>
@@ -25736,6 +26140,65 @@ parsoid=html2wt
 
 !! end
 
+!! test
+Tables: 5. Empty table cells should get whitespace to avoid need for nowikis
+!! options
+parsoid=html2wt
+!! html/parsoid
+<table><tr><td></td><td align="center" data-parsoid='{"stx":"row"}'></td><td data-parsoid='{"stx":"row"}'></td></tr></table>
+
+<table><tr><td></td><td align="center"></td><td></td></tr></table>
+
+<table><tr><td></td><td align="center" data-parsoid='{"stx":"row", "startTagSrc":"{{!}}{{!}}"}'></td><td data-parsoid='{"stx":"row"}'></td></tr></table>
+
+<table><tr><th></th><th align="center" data-parsoid='{"stx":"row"}'></th><th data-parsoid='{"stx":"row"}'></th></tr></table>
+!! wikitext
+{|
+| || align="center" | ||
+|}
+
+{|
+|
+| align="center" |
+|
+|}
+
+{|
+| {{!}}{{!}} align="center" | ||
+|}
+
+{|
+! !! align="center" | !!
+|}
+!! html/php+tidy
+<table>
+<tbody><tr>
+<td></td>
+<td align="center"></td>
+<td>
+</td></tr></tbody></table>
+<table>
+<tbody><tr>
+<td>
+</td>
+<td align="center">
+</td>
+<td>
+</td></tr></tbody></table>
+<table>
+<tbody><tr>
+<td></td>
+<td align="center"></td>
+<td>
+</td></tr></tbody></table>
+<table>
+<tbody><tr>
+<th></th>
+<th align="center"></th>
+<th>
+</th></tr></tbody></table>
+!! end
+
 !! test
 T97430: Don't emit empty nowiki pairs around marker meta tags
 !! options
@@ -26265,8 +26728,6 @@ bar <span><nowiki>[[foo]]</nowiki></span>
 !!end
 
 #### ----------------------- PRE --------------------------
-#### 1. Leading whitespace in SOL context should be escaped
-#### ------------------------------------------------------
 !! test
 1. Leading whitespace in SOL context should be escaped
 !! options
@@ -26379,7 +26840,7 @@ parsoid=html2wt
  ==foo==
 !! end
 
-!!test
+!! test
 T95794: nowiki escaping should account for leading space at start-of-line in an indent-pre block
 !! options
 parsoid=html2wt
@@ -26393,6 +26854,51 @@ parsoid=html2wt
  * bar
 !! end
 
+!! test
+Whitespace scrubbing in SOL position should account for SOL-sensitive wikitext markup
+!! options
+parsoid = {
+  "modes": ["html2wt"],
+  "scrubWikitext": true
+}
+!! html/parsoid
+<p> foo</p>
+<p> %foo</p>
+<p> *foo</p>
+<p> #foo</p>
+<p> =foo=</p>
+<p><link rel="mw:PageProp/Category" href="./Category:Foo" data-parsoid="{}"> *foo</p>
+<p> <link rel="mw:PageProp/Category" href="./Category:Foo" data-parsoid="{}">*foo</p>
+<p> <!--boo-->*foo</p>
+<p><!--boo--> *foo</p>
+<p><!--a--> <!--b--> <!--c--> <!--d--> <!--e--> foo</p>
+<p><!--a--> <!--b--> <!--c--> <!--d--> <!--e--> *foo</p>
+!! wikitext
+foo
+
+%foo
+
+<nowiki/>*foo
+
+<nowiki/>#foo
+
+<nowiki/>=foo=
+
+[[Category:Foo]]
+<nowiki/>*foo
+
+ [[Category:Foo]]
+<nowiki>*</nowiki>foo
+
+<nowiki/><!--boo-->*foo
+
+<!--boo--><nowiki/>*foo
+
+<!--a--><!--b--><!--c--><!--d--><!--e-->foo
+
+<!--a--><nowiki/><!--b--><!--c--><!--d--><!--e-->*foo
+!! end
+
 #### --------------- Behavior Switches --------------------
 
 !! test
@@ -26508,6 +27014,18 @@ parsoid=html2wt
 baz<nowiki></ref></nowiki>
 !! end
 
+!! test
+Parsoid: newline inducing block nodes don't suppress <nowiki>
+!! options
+parsoid=html2wt
+!! html/parsoid
+ a<h1>foo</h1>
+!! wikitext
+<nowiki> </nowiki>a
+
+= foo =
+!! end
+
 #### --------------- Others ---------------
 !! test
 Escaping nowikis
@@ -26959,87 +27477,91 @@ Encapsulate protected attributes from wt
 <div typeof="mw:placeholder stuff" data-mw="whoo" data-parsoid="weird" data-parsoid-other="no" about="time" rel="mw:true">foo</div>
 
 {| typeof="mw:placeholder stuff" data-mw="whoo" data-parsoid="weird" data-parsoid-other="no" about="time" rel="mw:true"
-| ok
+|ok
 |}
 !! html/parsoid
 <div data-x-typeof="mw:placeholder stuff" data-x-data-mw="whoo" data-x-data-parsoid="weird" data-x-data-parsoid-other="no" data-x-about="time" data-x-rel="mw:true">foo</div>
 
 <table data-x-typeof="mw:placeholder stuff" data-x-data-mw="whoo" data-x-data-parsoid="weird" data-x-data-parsoid-other="no" data-x-about="time" data-x-rel="mw:true">
-<tbody><tr><td data-parsoid='{"autoInsertedEnd":true}'> ok</td></tr>
+<tbody><tr><td data-parsoid='{"autoInsertedEnd":true}'>ok</td></tr>
 </tbody></table>
 !!end
 
 ## Currently the p-wrapper is fragile in how it adds / removes transformations.
 ## Having nested or stray pre tags results in the attempt to add duplicates,
 ## causing an assertion fail. This test tries to prevent that situation.
-!!test
+!! test
 Ensure ParagraphWrapper can deal with stray closing pre tags
-!!options
+!! options
 parsoid=wt2html
 !! wikitext
 plain text</pre>
 !! html/parsoid
-plain text
-!!end
+<p>plain text</p>
+!! end
 
-!!test
+## Remex doesn't account for fostered content.
+!! test
 1. Ensure fostered text content is wrapped in element nodes
-!!options
+!! options
 parsoid=wt2html
 !! wikitext
 <table>hi</table><table>ho</table>
+!! html/php+tidy
+hi<table></table>ho<table></table>
 !! html/parsoid
-<p>hi</p>
-<table></table>
-<p>ho</p>
-<table></table>
-!!end
+<p data-parsoid='{"fostered":true,"autoInsertedEnd":true,"autoInsertedStart":true}'>hi</p><table data-parsoid='{"stx":"html"}'></table><p data-parsoid='{"fostered":true,"autoInsertedEnd":true,"autoInsertedStart":true}'>ho</p><table data-parsoid='{"stx":"html"}'></table>
+!! end
 
-!!test
+## Remex doesn't account for fostered content.
+!! test
 2. Ensure fostered text content is wrapped in element nodes (traps regressions around fostered marker on the element getting lost)
-!!options
+!! options
 parsoid=wt2html,wt2wt
 !! wikitext
 <table>
 <tr> || ||
 <td> a
 </table>
+!! html/php+tidy
+ || ||
+<table>
+<tbody><tr><td> a
+</td></tr></tbody></table>
 !! html/parsoid
-<p> || ||
-</p><table>
-<tbody><tr><td> a</td></tr>
-</tbody></table>
-!!end
+<p data-parsoid='{"fostered":true,"autoInsertedEnd":true,"autoInsertedStart":true}'> || ||</p>
+<table data-parsoid='{"stx":"html"}'>
+<tbody><tr data-parsoid='{"stx":"html","autoInsertedEnd":true}'><td data-parsoid='{"stx":"html","autoInsertedEnd":true}'> a
+</td></tr></tbody></table>
+!! end
 
-!!test
+## Remex doesn't account for fostered content.
+!! test
 Encapsulation properly handles null DSR information from foster box
-!!options
+!! options
 parsoid=wt2html,wt2wt
 !! wikitext
 {{echo|<table>foo<tr><td>bar</td></tr></table>}}
 !! html/parsoid
-<span typeof="mw:Transclusion" data-mw="{&quot;parts&quot;:[{&quot;template&quot;:{&quot;target&quot;:{&quot;wt&quot;:&quot;echo&quot;,&quot;href&quot;:&quot;./Template:Echo&quot;},&quot;params&quot;:{&quot;1&quot;:{&quot;wt&quot;:&quot;<table>foo<tr><td>bar</td></tr></table>&quot;}},&quot;i&quot;:0}}]}">foo</span><table><tbody><tr><td>bar</td></tr></tbody></table>
-!!end
+<p about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"&lt;table>foo&lt;tr>&lt;td>bar&lt;/td>&lt;/tr>&lt;/table>"}},"i":0}}]}'>foo</p><table about="#mwt1" data-parsoid='{"stx":"html"}'><tbody><tr><td>bar</td></tr></tbody></table>
+!! end
 
-!!test
+## Remex doesn't account for fostered content.
+!! test
 1. Encapsulate foster-parented transclusion content
-!!options
+!! options
 parsoid=wt2wt,wt2html
 !! wikitext
 <table>{{echo|foo<tr><td>bar</td></tr>}}</table>
+!! html/php+tidy
+foo<table><tbody><tr><td>bar</td></tr></tbody></table>
 !! html/parsoid
-<p typeof="mw:Transclusion" data-mw="{&quot;parts&quot;:[&quot;<table>&quot;,{&quot;template&quot;:{&quot;target&quot;:{&quot;wt&quot;:&quot;echo&quot;,&quot;href&quot;:&quot;./Template:Echo&quot;},&quot;params&quot;:{&quot;1&quot;:{&quot;wt&quot;:&quot;foo<tr><td>bar</td></tr>&quot;}},&quot;i&quot;:0}},&quot;</table>&quot;]}">foo</p><table>
-<tbody>
-<tr>
-<td>bar</td>
-</tr>
-</tbody>
-</table>
-!!end
+<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":"foo&lt;tr>&lt;td>bar&lt;/td>&lt;/tr>"}},"i":0}},"&lt;/table>"]}'>foo</p><table about="#mwt2" data-parsoid='{"stx":"html"}'><tbody><tr><td>bar</td></tr></tbody></table>
+!! end
 
-!!test
+!! test
 2. Encapsulate foster-parented transclusion content
-!!options
+!! options
 parsoid=wt2wt,wt2html
 !! wikitext
 <table><div>{{echo|foo}}</div><tr><td>bar</td></tr></table>
@@ -27052,11 +27574,11 @@ parsoid=wt2wt,wt2html
 </tr>
 </tbody>
 </table>
-!!end
+!! end
 
-!!test
+!! test
 3. Encapsulate foster-parented transclusion content
-!!options
+!! options
 parsoid=wt2wt,wt2html
 !! wikitext
 <table><div><p>{{echo|foo</p></div><tr><td>}}bar</td></tr></table>
@@ -27071,11 +27593,11 @@ parsoid=wt2wt,wt2html
 </tr>
 </tbody>
 </table>
-!!end
+!! end
 
-!!test
+!! test
 4. Encapsulate foster-parented transclusion content
-!!options
+!! options
 parsoid=wt2wt,wt2html
 !! wikitext
 <table><div><p>{{echo|foo</p></div><tr><td>}}bar</td></tr></table>
@@ -27090,52 +27612,35 @@ parsoid=wt2wt,wt2html
 </tr>
 </tbody>
 </table>
-!!end
+!! end
 
-!!test
+## Remex doesn't account for fostered content.
+!! test
 5. Encapsulate foster-parented transclusion content
 !!options
 parsoid=wt2wt,wt2html
 !! wikitext
 <table><tr><td><div><p>{{echo|foo</p></div></td>foo}}</tr></table>
+!! html/php+tidy
+foo<table><tbody><tr><td><div><p>foo</p></div></td></tr></tbody></table>
 !! html/parsoid
-<p typeof="mw:Transclusion" data-mw="{&quot;parts&quot;:[&quot;<table><tr><td><div><p>&quot;,{&quot;template&quot;:{&quot;target&quot;:{&quot;wt&quot;:&quot;echo&quot;,&quot;href&quot;:&quot;./Template:Echo&quot;},&quot;params&quot;:{&quot;1&quot;:{&quot;wt&quot;:&quot;foo</p></div></td>foo&quot;}},&quot;i&quot;:0}},&quot;</tr></table>&quot;]}">foo</p>
-<table>
-<tbody>
-<tr>
-<td>
-<div>
-<p>foo</p>
-</div>
-</td>
-</tr>
-</tbody>
-</table>
-!!end
+<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>&lt;tr>&lt;td>&lt;div>&lt;p>",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"foo&lt;/p>&lt;/div>&lt;/td>foo"}},"i":0}},"&lt;/tr>&lt;/table>"]}'>foo</p><table about="#mwt2" data-parsoid='{"stx":"html"}'><tbody><tr><td><div><p>foo</p></div></td></tr></tbody></table>
+!! end
 
-!!test
+## Remex doesn't account for fostered content.
+!! test
 6. Encapsulate foster-parented transclusion content
-!!options
+!! options
 parsoid=wt2wt,wt2html
 !! wikitext
 <table><tr><td><div><p>{{echo|foo</p></div></td>foo</tr></table>}}<p>ok</p>
+!! html/php+tidy
+foo<table><tbody><tr><td><div><p>foo</p></div></td></tr></tbody></table><p>ok</p>
 !! html/parsoid
-<p typeof="mw:Transclusion" data-mw="{&quot;parts&quot;:[&quot;<table><tr><td><div><p>&quot;,{&quot;template&quot;:{&quot;target&quot;:{&quot;wt&quot;:&quot;echo&quot;,&quot;href&quot;:&quot;./Template:Echo&quot;},&quot;params&quot;:{&quot;1&quot;:{&quot;wt&quot;:&quot;foo</p></div></td>foo</tr></table>&quot;}},&quot;i&quot;:0}}]}">foo</p>
-<table>
-<tbody>
-<tr>
-<td>
-<div>
-<p>foo</p>
-</div>
-</td>
-</tr>
-</tbody>
-</table>
-<p>ok</p>
-!!end
+<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>&lt;tr>&lt;td>&lt;div>&lt;p>",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"foo&lt;/p>&lt;/div>&lt;/td>foo&lt;/tr>&lt;/table>"}},"i":0}}]}'>foo</p><table about="#mwt2" data-parsoid='{"stx":"html"}'><tbody><tr><td><div><p>foo</p></div></td></tr></tbody></table><p data-parsoid='{"stx":"html"}'>ok</p>
+!! end
 
-!!test
+!! test
 7. Encapsulate foster-parented transclusion content
 !!options
 parsoid=wt2wt,wt2html
@@ -27150,13 +27655,14 @@ parsoid=wt2wt,wt2html
 </tr>
 </tbody>
 </table>
-!!end
+!! end
 
+## Remex doesn't account for fostered content.
 # Note that the wt is broken on purpose: the = should be {{=}} if you
 # don't want it to be a template parameter key.
-!!test
+!! test
 8. Encapsulate foster-parented transclusion content
-!!options
+!! options
 parsoid=wt2wt,wt2html
 !! wikitext
 {{echo|a
@@ -27164,30 +27670,37 @@ parsoid=wt2wt,wt2html
 |-
 |b
 |}
-!! html/parsoid
-<p typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"a\n"}},"i":0}}]}'>a</p>
-<span> </span>
-<p typeof="mw:Transclusion" data-mw='{"parts":["{|",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"style":{"wt":"&#39;color:red&#39;"}},"i":0}},"\n|-\n|b\n|}"]}'>{{{1}}}</p>
+!! html/php+tidy
+<p>a
+</p>
 <table>
-<tbody>
-<tr>
-<td>b</td>
-</tr>
-</tbody>
-</table>
-!!end
 
-!!test
+<tbody><tr>
+<td>b
+</td></tr></tbody></table>
+!! html/parsoid
+<p about="#mwt1" typeof="mw:Transclusion" data-parsoid='{"pi":[[{"k":"1"}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"a\n"}},"i":0}}]}'>a</p><span about="#mwt1">
+</span><p about="#mwt3" typeof="mw:Transclusion" data-parsoid='{"fostered":true,"autoInsertedEnd":true,"autoInsertedStart":true,"firstWikitextNode":"TABLE","pi":[[{"k":"style","named":true}]]}' data-mw='{"parts":["{|",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"style":{"wt":"&apos;color:red&apos;"}},"i":0}},"\n|-\n|b\n|}"]}'>{{{1}}}</p><table about="#mwt3">
+<tbody><tr>
+<td>b
+</td></tr></tbody></table>
+!! end
+
+## Remex doesn't account for fostered content.
+!! test
 9. Encapsulate foster-parented transclusion content
 !!options
 parsoid=wt2wt,wt2html
 !! wikitext
 <table>{{echo|hi</table>hello}}
+!! html/php+tidy
+hi<table></table><p>hello
+</p>
 !! html/parsoid
-<p about="#mwt2" typeof="mw:Transclusion" data-mw='{"parts":["&lt;table>",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"hi&lt;/table>hello"}},"i":0}}]}' data-parsoid='{"fostered":true,"autoInsertedEnd":true,"autoInsertedStart":true,"pi":[[{"k":"1"}]]}'>hi</p><table about="#mwt2" data-parsoid='{"stx":"html"}'></table><p about="#mwt2">hello</p>
-!!end
+<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
 
-!!test
+!! test
 Table in fosterable position
 !!options
 parsoid=wt2html
@@ -27205,7 +27718,7 @@ parsoid=wt2html
 
 <table>
 </table>
-!!end
+!! end
 
 # Parsoid only for T66747
 !! test
@@ -27850,7 +28363,7 @@ parsoid={
 
 == hi pal ==
 
-<!--foo-->  [[Category:A3]]
+<!--foo-->[[Category:A3]]
 
 == how goes it ==
 
@@ -28174,7 +28687,7 @@ parsoid={
 !! html/parsoid
 <a rel="mw:WikiLink" href="./Football"><i>Foot</i></a><a rel="mw:WikiLink" href="./Football"><i>ball</i></a>
 !! wikitext
-[[Football|''Football'']]
+''[[Football]]''
 !! end
 
 !! test
@@ -28190,6 +28703,98 @@ parsoid={
 [[Football|Foot]][[Football|ball]]
 !! end
 
+!! test
+1. Move format tags outside of WikiLink
+!! options
+parsoid={
+  "modes": ["html2wt"],
+  "scrubWikitext": true
+}
+!! html/parsoid
+<a rel="mw:WikiLink" href="./Football"><i>Football</i></a>
+<a rel="mw:WikiLink" href="./Football"><i><b>Football</b></i></a>
+<a rel="mw:WikiLink" href="./Football"><u><i><b>Football</b></i></u></a>
+!! wikitext
+''[[Football]]''
+'''''[[Football]]'''''
+<u>'''''[[Football]]'''''</u>
+!! end
+
+!! test
+2. Move format tags outside of WikiLink with mergable A tags
+!! options
+parsoid={
+  "modes": ["html2wt"],
+  "scrubWikitext": true
+}
+!! html/parsoid
+<a rel="mw:WikiLink" href="./Football"><i><b>Foot</b></i></a><a rel="mw:WikiLink" href="./Football"><i><b>ball</b></i></a>
+!! wikitext
+'''''[[Football]]'''''
+!! end
+
+!! test
+3. Move format tags outside of WikiLink while preserving formats already outside WikiLink
+!! options
+parsoid={
+  "modes": ["html2wt"],
+  "scrubWikitext": true
+}
+!! html/parsoid
+<font color="red"><a rel="mw:WikiLink" href="./Foo" title="Foo" class="mw-redirect"><u><b>Foo</b></u></a></font>
+!! wikitext
+<font color="red"><u>'''[[Foo]]'''</u></font>
+!! end
+
+!! test
+4. Do not move format tags outside of WikiLink which includes attributes color, style and class
+!! options
+parsoid={
+  "modes": ["html2wt"],
+  "scrubWikitext": true
+}
+!! html/parsoid
+<a rel="mw:WikiLink" href="./Foo" title="Foo" class="mw-redirect"><font color="red">Foo</font></a>
+<a rel="mw:WikiLink" href="./Foo" title="Foo" class="mw-redirect"><span style="color: blue; font-size: 46px;">Foo></span></a>
+<a rel="mw:WikiLink" href="./Foo" title="Foo" class="mw-redirect"><span class="Bar">Foo</span></a>
+!! wikitext
+[[Foo|<font color="red">Foo</font>]]
+[[Foo|<span style="color: blue; font-size: 46px;">Foo></span>]]
+[[Foo|<span class="Bar">Foo</span>]]
+!! end
+
+!! test
+5. T194083 Regression test: Manual edit test that also enables scrubWikitext to move format tags outside wikilinks
+!! options
+parsoid={
+  "modes": ["selser"],
+  "scrubWikitext": true,
+  "changes": [
+    ["a", "html", "<i>Foo</i>"]
+  ]
+}
+!! wikitext
+[[Foo]]
+!! wikitext/edited
+''[[Foo]]''
+!! end
+
+!! test
+6. Regression test: Manual edit test to ensure diff markers are not lost
+!! options
+parsoid={
+  "modes": ["selser"],
+  "scrubWikitext": true,
+  "changes": [
+    ["i", "wrap", "<a href='./Foo' rel='mw:WikiLink'></a>"]
+  ]
+}
+!! wikitext
+''Foo''
+!! wikitext/edited
+''[[Foo]]''
+!! end
+
 #------------------------------
 # End of tag minimization tests
 #------------------------------
@@ -28429,8 +29034,8 @@ Magic links inside image captions (autolinked)
 <div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div><a href="/wiki/Special:BookSources/123456789X" class="internal mw-magiclink-isbn">ISBN 123456789x</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>
-<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="https://tools.ietf.org/html/rfc1234" rel="mw:ExtLink" class="external text">RFC 1234</a></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><a href="//www.ncbi.nlm.nih.gov/pubmed/1234?dopt=Abstract" rel="mw:ExtLink" class="external text">PMID 1234</a></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><a href="https://tools.ietf.org/html/rfc1234" rel="mw:ExtLink" class="external mw-magiclink">RFC 1234</a></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><a href="//www.ncbi.nlm.nih.gov/pubmed/1234?dopt=Abstract" rel="mw:ExtLink" class="external mw-magiclink">PMID 1234</a></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><a href="./Special:BookSources/123456789X" rel="mw:WikiLink">ISBN 123456789x</a></figcaption></figure>
 !! end
 
@@ -28495,8 +29100,7 @@ parsoid=html2wt,wt2wt
 |<small>-</small>
 |<br />
 -
-|<br />
--
+|<br />-
 |}
 !! html/php+tidy
 <table>
@@ -28517,9 +29121,7 @@ parsoid=html2wt,wt2wt
 <p>-
 </p>
 </td>
-<td><br />
-<p>-
-</p>
+<td><br />-
 </td></tr></tbody></table>
 !! end
 
@@ -28643,6 +29245,147 @@ parsoid=html2wt
 <div id="hello">ok</div>
 !! end
 
+!! test
+Testing serialization after deletion in references
+!! options
+parsoid={
+  "modes": ["wt2wt"],
+  "changes": [
+    ["#x", "remove"]
+  ]
+}
+!! wikitext
+hi <ref><div id="x">ho</div></ref>
+
+<references />
+!! wikitext/edited
+hi <ref></ref>
+
+<references />
+!! end
+
+!!test
+Testing serialization after deletion of table cells
+!!options
+parsoid={
+  "modes": ["wt2wt", "selser"],
+  "changes": [
+    ["#x", "remove"]
+  ]
+}
+!!wikitext
+{|
+!h1 !!h2 !!h3
+| id="x" |c1 {{!}}{{!}}{{!}}c2 |||c3
+|}
+!! wikitext/edited
+{|
+!h1!!h2!!h3
+|c2|||c3
+|}
+!!end
+
+!! test
+Testing selser after addition of new row before first row (T125419)
+!! options
+parsoid={
+  "modes": ["wt2wt", "selser"],
+  "changes": [
+    [ "tr", "before", "<tr><td>X</td></tr>" ]
+  ]
+}
+!! wikitext
+{|
+|a
+|}
+!! wikitext/edited
+{|
+|X
+|-
+|a
+|}
+!! end
+
+!! test
+Serialize new table rows in a HTML table using HTML tags
+!! options
+parsoid={
+  "modes": ["wt2wt", "selser"],
+  "changes": [
+    [ "tr", "before", "<tr><td>X</td></tr>" ]
+  ]
+}
+!! wikitext
+<table><tr><td>a</td></tr></table>
+!! wikitext/edited
+<table><tr><td>X</td></tr><tr><td>a</td></tr></table>
+!! end
+
+!! test
+Serialize new table cells in a HTML row using HTML tags
+!! options
+parsoid={
+  "modes": ["wt2wt", "selser"],
+  "changes": [
+    [ "td", "before", "<td>X</td>" ]
+  ]
+}
+!! wikitext
+<table><tr><td>a</td></tr></table>
+!! wikitext/edited
+<table><tr><td>X</td><td>a</td></tr></table>
+!! end
+
+!! test
+Serialize wikitext list items as HTML list items when embedded in a HTML list
+!! options
+parsoid=html2wt
+!! html
+<ul data-parsoid='{"stx": "html"}'>
+<li data-parsoid='{}'>a</li>
+<li>b</li>
+</ul>
+!! wikitext
+<ul>
+<li>a</li>
+<li>b</li>
+</ul>
+!! end
+
+# SSS FIXME: Is this actually a good thing given the
+# odd nested list output that is generated by MW?
+# <ul><li>foo<ul>..</ul></li></ul> instead of
+# <ul><li>foo</li><ul>..</ul></ul>
+!! test
+Wikitext lists can be nested inside HTML lists
+!! options
+parsoid=html2wt
+!! html
+<ul data-parsoid='{"stx": "html"}'>
+<li data-parsoid='{"stx": "html"}'>a
+<ul><li>b</li></ul>
+</li>
+</ul>
+
+<ul data-parsoid='{"stx": "html"}'>
+<li>x
+<ul><li>y</li></ul>
+</li>
+</ul>
+!! wikitext
+<ul>
+<li>a
+* b
+</li>
+</ul>
+
+<ul>
+<li>x
+* y
+</li>
+</ul>
+!! end
+
 !! test
 WTS change modes
 !! options
@@ -28805,7 +29548,7 @@ foo {{echo|<span>bar</span> [[Category:baz]]}} bar
 # of the categories in wikitext
 # Do not remove these characters in edits.
 #
-# As part of the serialization, these Unicode directional formatting characters will get stripped.
+# As part of the serialization, these bidi characters will get stripped.
 !! test
 RTL (\u200f) and LTR (\u200e) markers around category tags should be stripped
 !! options
@@ -28880,7 +29623,7 @@ parsoid={
 !! html/parsoid
 <h2> <link href="./Category:A2" rel="mw:PageProp/Category" />ok</h2>
 !! wikitext
- [[Category:A2]]
+[[Category:A2]]
 
 == ok ==
 !! end
@@ -28948,7 +29691,7 @@ parsoid={
 !! html/parsoid
 <h2>foo<br/>bar</h2>
 !! wikitext
-== foo<br /> bar ==
+== foo<br />bar ==
 !! end
 
 !! test
@@ -29937,7 +30680,7 @@ wgFragmentMode=[ 'html5', 'legacy' ]
 [[#啤酒]] [[#%E5%95%A4%E9%85%92]]
 
 !! html/php
-<div id="toc" class="toc"><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2></div>
+<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>
 <li class="toclevel-1 tocsection-1"><a href="#Foo_bar"><span class="tocnumber">1</span> <span class="toctext">Foo bar</span></a></li>
 <li class="toclevel-1 tocsection-2"><a href="#foo_Bar_2"><span class="tocnumber">2</span> <span class="toctext">foo Bar</span></a></li>
@@ -30003,7 +30746,7 @@ wgFragmentMode=[ 'legacy', 'html5' ]
 [[#啤酒]] [[#%E5%95%A4%E9%85%92]]
 
 !! html/php
-<div id="toc" class="toc"><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2></div>
+<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>
 <li class="toclevel-1 tocsection-1"><a href="#Foo_bar"><span class="tocnumber">1</span> <span class="toctext">Foo bar</span></a></li>
 <li class="toclevel-1 tocsection-2"><a href="#foo_Bar_2"><span class="tocnumber">2</span> <span class="toctext">foo Bar</span></a></li>
@@ -30051,7 +30794,7 @@ wgFragmentMode=[ 'html5' ]
 [[#啤酒]] [[#%E5%95%A4%E9%85%92]]
 
 !! html/php
-<div id="toc" class="toc"><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2></div>
+<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>
 <li class="toclevel-1 tocsection-1"><a href="#Foo_bar"><span class="tocnumber">1</span> <span class="toctext">Foo bar</span></a></li>
 <li class="toclevel-1 tocsection-2"><a href="#foo_Bar_2"><span class="tocnumber">2</span> <span class="toctext">foo Bar</span></a></li>
@@ -30623,10 +31366,16 @@ headings, and cells. HTML versions of the same should preserve whitespace.
 ##########################################################################
 !! test
 Trim whitespace in wikitext headings, list items, table captions, headings, and cells
+!! options
+parsoid={
+       "modes": ["wt2html"],
+       "preserveIEW": true
+}
 !! wikitext
 __NOTOC__
 ==    <!--c1-->  <!--c2--> Spaces   <!--c3--> <!--c4-->  ==
-==             <!--c2-->       <!--c2--> Tabs          <!--c3--><!--c4-->      ==
+==             <!--c1-->       <!--c2--> Tabs          <!--c3--><!--c4-->      ==
+== <!--Headings with fallback ids--> Личная жизнь ==
 *     <!--c1-->   <!--c2-->  List item <!--c3--> <!--c4-->
 ; <!--term to define--> term : <!--term's definition--> definition
 {|
@@ -30646,6 +31395,7 @@ __NOTOC__
 !! html/php+tidy
 <h2><span class="mw-headline" id="Spaces">Spaces</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: Spaces">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
 <h2><span class="mw-headline" id="Tabs">Tabs</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: Tabs">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
+<h2><span class="mw-headline" id=".D0.9B.D0.B8.D1.87.D0.BD.D0.B0.D1.8F_.D0.B6.D0.B8.D0.B7.D0.BD.D1.8C">Личная жизнь</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>
 <ul><li>List item</li></ul>
 <dl><dt>term&#160;</dt>
 <dd>definition</dd></dl>
@@ -30672,11 +31422,37 @@ __NOTOC__
 <td>Table Cell 1</td>
 <td>Table Cell 2
 </td></tr></tbody></table> foo</dd></dl>
+!! html/parsoid
+<meta property="mw:PageProp/notoc">
+<h2 id="Spaces"><!--c1--><!--c2-->Spaces<!--c3--><!--c4--></h2>
+<h2 id="Tabs"><!--c1--><!--c2-->Tabs<!--c3--><!--c4--></h2>
+<h2 id="Личная_жизнь"><span id=".D0.9B.D0.B8.D1.87.D0.BD.D0.B0.D1.8F_.D0.B6.D0.B8.D0.B7.D0.BD.D1.8C" typeof="mw:FallbackId"></span><!--Headings with fallback ids-->Личная жизнь</h2>
+<ul><li><!--c1--><!--c2-->List item<!--c3--><!--c4--></li></ul>
+<dl><dt><!--term to define-->term&nbsp;</dt><dd><!--term's definition-->definition</dd></dl>
+<table>
+<caption><!--c1--><!--c2-->Table Caption<!--c3--><!--c4--></caption>
+<tbody><tr>
+<th><!--c1--><!--c2-->Table Heading 1<!--c3--><!--c4--></th><th>Table Heading 2<!--c5--></th></tr>
+<tr>
+<td><!--c1--><!--c2-->Table Cell 1<!--c3--><!--c4--></td><td>Table Cell 2<!--c5--></td></tr>
+<tr>
+<td>class="foo"</td><td><!--c1--><!--c2-->Table Cell 3<!--c3--><!--c4--></td></tr>
+<tr>
+<td><!--c1-->testing <a rel="mw:WikiLink" href="./One" title="One">two</a> <!--c2--> | <!--c3--> some content</td></tr>
+</tbody></table>
+<dl><dd><table>
+  <tbody><tr><td><!--c1--><!--c2-->Table Cell 1<!--c3--><!--c4--></td><td>Table Cell 2<!--c5--></td></tr>
+  </tbody></table> foo<!--c1--></dd></dl>
 !! end
 
 # Looks like <caption> is not accepted in HTML
 !! test
 Do not trim whitespace in HTML headings, list items, table captions, headings, and cells
+!! options
+parsoid={
+       "modes": ["wt2html"],
+       "preserveIEW": true
+}
 !! wikitext
 __NOTOC__
 <h2>    <!--c1-->   <!--c2--> Heading    <!--c3--> <!--c4-->  </h2>
@@ -30692,10 +31468,23 @@ __NOTOC__
 <tbody><tr><th>   Table Heading   </th><th></th></tr>
 <tr><td>   Table Cell   </td><th></th></tr>
 </tbody></table>
+!! html/parsoid
+<meta property="mw:PageProp/notoc"/>
+<h2 id="Heading">    <!--c1-->   <!--c2--> Heading    <!--c3--> <!--c4-->  </h2>
+<ul><li>     <!--c1-->   <!--c2-->  List item <!--c3--> <!--c4-->  </li></ul>
+<table>
+<tbody><tr><th> <!--c1--> <!--c2--> Table Heading <!--c3--> <!--c4--> </th><th></th></tr>
+<tr><td> <!--c1--> <!--c2--> Table Cell <!--c3--> <!--c4--> </td><th></th></tr>
+</tbody></table>
 !! end
 
 !! test
 Do not trim whitespace in links and quotes
+!! options
+parsoid={
+       "modes": ["wt2html"],
+       "preserveIEW": true
+}
 !! wikitext
 foo ''  <!--c1--> italic <!--c2-->   '' and '''  <!--c3-->  bold  <!--c4-->  '''
 [[Foo|  some text  ]]
@@ -30703,6 +31492,9 @@ foo ''  <!--c1--> italic <!--c2-->   '' and '''  <!--c3-->  bold  <!--c4-->  '''
 <p>foo <i>   italic    </i> and <b>    bold    </b>
 <a href="/wiki/Foo" title="Foo">  some text  </a>
 </p>
+!! html/parsoid
+<p>foo <i>  <!--c1--> italic <!--c2-->   </i> and <b>  <!--c3-->  bold  <!--c4-->  </b>
+<a rel="mw:WikiLink" href="./Foo" title="Foo">  some text  </a></p>
 !! end
 
 !! test
@@ -30811,27 +31603,3 @@ header
 *foo
 footer
 !! end
-
-!! test
-Check soft hyphens as entities (&shy;) in displaytitle (T66528)
-!! options
-showtitle
-title=[[Lopadotemachoselachogaleokranioleipsanodrimhypotrimmatosilphioparaomelitokatakechymenokichlepikossyphophattoperisteralektryonoptekephalliokigklopeleiolagoiosiraiobaphetraganopterygon]]
-!! wikitext
-{{DISPLAYTITLE:Lopado&shy;temacho&shy;selacho&shy;galeo&shy;kranio&shy;leipsano&shy;drim&shy;hypo&shy;trimmato&shy;silphio&shy;parao&shy;melito&shy;katakechy&shy;meno&shy;kichl&shy;epi&shy;kossypho&shy;phatto&shy;perister&shy;alektryon&shy;opte&shy;kephallio&shy;kigklo&shy;peleio&shy;lagoio&shy;siraio&shy;baphe&shy;tragano&shy;pterygon}}
-!! html/php
-Lopado&#173;temacho&#173;selacho&#173;galeo&#173;kranio&#173;leipsano&#173;drim&#173;hypo&#173;trimmato&#173;silphio&#173;parao&#173;melito&#173;katakechy&#173;meno&#173;kichl&#173;epi&#173;kossypho&#173;phatto&#173;perister&#173;alektryon&#173;opte&#173;kephallio&#173;kigklo&#173;peleio&#173;lagoio&#173;siraio&#173;baphe&#173;tragano&#173;pterygon
-
-!! end
-
-!! test
-Check soft hyphens as Unicode characters (U+00AD) in displaytitle (T66528)
-!! options
-showtitle
-title=[[Lopadotemachoselachogaleokranioleipsanodrimhypotrimmatosilphioparaomelitokatakechymenokichlepikossyphophattoperisteralektryonoptekephalliokigklopeleiolagoiosiraiobaphetraganopterygon]]
-!! wikitext
-{{DISPLAYTITLE:Lopado­temacho­selacho­galeo­kranio­leipsano­drim­hypo­trimmato­silphio­parao­melito­katakechy­meno­kichl­epi­kossypho­phatto­perister­alektryon­opte­kephallio­kigklo­peleio­lagoio­siraio­baphe­tragano­pterygon}}
-!! html/php
-Lopado­temacho­selacho­galeo­kranio­leipsano­drim­hypo­trimmato­silphio­parao­melito­katakechy­meno­kichl­epi­kossypho­phatto­perister­alektryon­opte­kephallio­kigklo­peleio­lagoio­siraio­baphe­tragano­pterygon
-
-!! end
index bd0461a..bcb3379 100644 (file)
@@ -48,10 +48,8 @@ return [
                        'maintenance/cleanupTable.inc',
                        'maintenance/CodeCleanerGlobalsPass.inc',
                        'maintenance/commandLine.inc',
-                       'maintenance/importImages.inc',
                        'maintenance/sqlite.inc',
                        'maintenance/userDupes.inc',
-                       'maintenance/userOptions.inc',
                        'maintenance/language/checkLanguage.inc',
                        'maintenance/language/languages.inc',
                ]
@@ -307,8 +305,6 @@ return [
                "PhanDeprecatedProperty",
                // approximate error count: 17
                "PhanNonClassMethodCall",
-               // approximate error count: 11
-               "PhanParamReqAfterOpt",
                // approximate error count: 888
                "PhanParamSignatureMismatch",
                // approximate error count: 7
@@ -331,10 +327,6 @@ return [
                "PhanTypeMismatchArgument",
                // approximate error count: 13
                "PhanTypeMismatchArgumentInternal",
-               // approximate error count: 6
-               "PhanTypeMismatchDeclaredParam",
-               // approximate error count: 111
-               "PhanTypeMismatchDeclaredParamNullable",
                // approximate error count: 5
                "PhanTypeMismatchDimAssignment",
                // approximate error count: 2
index a27e9f9..db75bc0 100644 (file)
@@ -178,6 +178,55 @@ abstract class MediaWikiTestCase extends PHPUnit\Framework\TestCase {
                return self::getTestUser( [ 'sysop', 'bureaucrat' ] );
        }
 
+       /**
+        * Returns a WikiPage representing an existing page.
+        *
+        * @since 1.32
+        *
+        * @param Title|string|null $title
+        * @return WikiPage
+        * @throws MWException
+        */
+       protected function getExistingTestPage( $title = null ) {
+               $title = ( $title === null ) ? 'UTPage' : $title;
+               $title = is_string( $title ) ? Title::newFromText( $title ) : $title;
+               $page = WikiPage::factory( $title );
+
+               if ( !$page->exists() ) {
+                       $user = self::getTestSysop()->getUser();
+                       $page->doEditContent(
+                               new WikitextContent( 'UTContent' ),
+                               'UTPageSummary',
+                               EDIT_NEW | EDIT_SUPPRESS_RC,
+                               false,
+                               $user
+                       );
+               }
+
+               return $page;
+       }
+
+       /**
+        * Returns a WikiPage representing a non-existing page.
+        *
+        * @since 1.32
+        *
+        * @param Title|string|null $title
+        * @return WikiPage
+        * @throws MWException
+        */
+       protected function getNonexistingTestPage( $title = null ) {
+               $title = ( $title === null ) ? 'UTPage-' . rand( 0, 100000 ) : $title;
+               $title = is_string( $title ) ? Title::newFromText( $title ) : $title;
+               $page = WikiPage::factory( $title );
+
+               if ( $page->exists() ) {
+                       $page->doDeleteArticle( 'Testing' );
+               }
+
+               return $page;
+       }
+
        /**
         * Prepare service configuration for unit testing.
         *
@@ -402,10 +451,6 @@ abstract class MediaWikiTestCase extends PHPUnit\Framework\TestCase {
                        if ( !self::$dbSetup ) {
                                $this->setupAllTestDBs();
                                $this->addCoreDBData();
-
-                               if ( ( $this->db->getType() == 'oracle' || !self::$useTemporaryTables ) && self::$reuseDB ) {
-                                       $this->resetDB( $this->db, $this->tablesUsed );
-                               }
                        }
 
                        // TODO: the DB setup should be done in setUpBeforeClass(), so the test DB
@@ -413,6 +458,7 @@ abstract class MediaWikiTestCase extends PHPUnit\Framework\TestCase {
                        // This would also remove the need for the HACK that is oncePerClass().
                        if ( $this->oncePerClass() ) {
                                $this->setUpSchema( $this->db );
+                               $this->resetDB( $this->db, $this->tablesUsed );
                                $this->addDBDataOnce();
                        }
 
@@ -669,7 +715,7 @@ abstract class MediaWikiTestCase extends PHPUnit\Framework\TestCase {
         *
         * @param array|string $pairs Key to the global variable, or an array
         *  of key/value pairs.
-        * @param mixed $value Value to set the global to (ignored
+        * @param mixed|null $value Value to set the global to (ignored
         *  if an array is given as first argument).
         *
         * @note To allow changes to global variables to take effect on global service instances,
@@ -837,7 +883,8 @@ abstract class MediaWikiTestCase extends PHPUnit\Framework\TestCase {
         *
         * @since 1.27
         *
-        * @param Config $configOverrides Configuration overrides for the new MediaWikiServices instance.
+        * @param Config|null $configOverrides Configuration overrides for the new MediaWikiServices
+        *        instance.
         * @param callable[] $services An associative array of services to re-define. Keys are service
         *        names, values are callables.
         *
@@ -917,7 +964,7 @@ abstract class MediaWikiTestCase extends PHPUnit\Framework\TestCase {
         *   in which case the next two parameters are ignored; or a single string
         *   identifying a group, to use with the next two parameters.
         * @param string|null $newKey
-        * @param mixed $newValue
+        * @param mixed|null $newValue
         */
        public function setGroupPermissions( $newPerms, $newKey = null, $newValue = null ) {
                global $wgGroupPermissions;
@@ -950,13 +997,12 @@ abstract class MediaWikiTestCase extends PHPUnit\Framework\TestCase {
                $singletons = $wrappedProvider->singletons;
                if ( $provider instanceof MonologSpi ) {
                        if ( !isset( $this->loggers[$channel] ) ) {
-                               $this->loggers[$channel] = isset( $singletons['loggers'][$channel] )
-                                       ? $singletons['loggers'][$channel] : null;
+                               $this->loggers[$channel] = $singletons['loggers'][$channel] ?? null;
                        }
                        $singletons['loggers'][$channel] = $logger;
                } elseif ( $provider instanceof LegacySpi ) {
                        if ( !isset( $this->loggers[$channel] ) ) {
-                               $this->loggers[$channel] = isset( $singletons[$channel] ) ? $singletons[$channel] : null;
+                               $this->loggers[$channel] = $singletons[$channel] ?? null;
                        }
                        $singletons[$channel] = $logger;
                } else {
@@ -998,7 +1044,16 @@ abstract class MediaWikiTestCase extends PHPUnit\Framework\TestCase {
         * @since 1.18
         */
        public function dbPrefix() {
-               return $this->db->getType() == 'oracle' ? self::ORA_DB_PREFIX : self::DB_PREFIX;
+               return self::getTestPrefixFor( $this->db );
+       }
+
+       /**
+        * @param IDatabase $db
+        * @return string
+        * @since 1.32
+        */
+       public static function getTestPrefixFor( IDatabase $db ) {
+               return $db->getType() == 'oracle' ? self::ORA_DB_PREFIX : self::DB_PREFIX;
        }
 
        /**
@@ -1027,15 +1082,17 @@ abstract class MediaWikiTestCase extends PHPUnit\Framework\TestCase {
         * Should be called from addDBData().
         *
         * @since 1.25 ($namespace in 1.28)
-        * @param string|title $pageName Page name or title
+        * @param string|Title $pageName Page name or title
         * @param string $text Page's content
-        * @param int $namespace Namespace id (name cannot already contain namespace)
+        * @param int|null $namespace Namespace id (name cannot already contain namespace)
+        * @param User|null $user If null, static::getTestSysop()->getUser() is used.
         * @return array Title object and page id
         */
        protected function insertPage(
                $pageName,
                $text = 'Sample page for unit test.',
-               $namespace = null
+               $namespace = null,
+               User $user = null
        ) {
                if ( is_string( $pageName ) ) {
                        $title = Title::newFromText( $pageName, $namespace );
@@ -1043,7 +1100,9 @@ abstract class MediaWikiTestCase extends PHPUnit\Framework\TestCase {
                        $title = $pageName;
                }
 
-               $user = static::getTestSysop()->getUser();
+               if ( !$user ) {
+                       $user = static::getTestSysop()->getUser();
+               }
                $comment = __METHOD__ . ': Sample page for unit test.';
 
                $page = WikiPage::factory( $title );
@@ -1085,7 +1144,10 @@ abstract class MediaWikiTestCase extends PHPUnit\Framework\TestCase {
        public function addDBData() {
        }
 
-       private function addCoreDBData() {
+       /**
+        * @since 1.32
+        */
+       protected function addCoreDBData() {
                if ( $this->db->getType() == 'oracle' ) {
                        # Insert 0 user to prevent FK violations
                        # Anonymous user
@@ -1174,33 +1236,95 @@ abstract class MediaWikiTestCase extends PHPUnit\Framework\TestCase {
        }
 
        /**
-        * Setups a database with the given prefix.
+        * Prepares the given database connection for usage in the context of usage tests.
+        * This sets up clones database tables and changes the table prefix as appropriate.
+        * If the database connection already has cloned tables, calling this method has no
+        * effect. The tables are not re-cloned or reset in that case.
+        *
+        * @param IMaintainableDatabase $db
+        */
+       protected function prepareConnectionForTesting( IMaintainableDatabase $db ) {
+               if ( !self::$dbSetup ) {
+                       throw new LogicException(
+                               'Cannot use prepareConnectionForTesting()'
+                               . ' if the test case is not defined to use the database!'
+                       );
+               }
+
+               if ( isset( $db->_originalTablePrefix ) ) {
+                       // The DB connection was already prepared for testing.
+                       return;
+               }
+
+               $testPrefix = self::getTestPrefixFor( $db );
+               $oldPrefix = $db->tablePrefix();
+
+               $tablesCloned = self::listTables( $db );
+
+               if ( $oldPrefix === $testPrefix ) {
+                       // The database connection already has the test prefix, but presumably not
+                       // the cloned tables. This is the typical case, since the LBFactory will
+                       // have the prefix set during testing, but LoadBalancers will still return
+                       // connections that don't have the cloned table structure.
+                       $oldPrefix = self::$oldTablePrefix;
+               }
+
+               $dbClone = new CloneDatabase( $db, $tablesCloned, $testPrefix, $oldPrefix );
+               $dbClone->useTemporaryTables( self::$useTemporaryTables );
+
+               $db->_originalTablePrefix = $oldPrefix;
+
+               if ( ( $db->getType() == 'oracle' || !self::$useTemporaryTables ) && self::$reuseDB ) {
+                       throw new LogicException( 'Cannot clone database tables' );
+               } else {
+                       $dbClone->cloneTableStructure();
+               }
+       }
+
+       /**
+        * Setups a database with cloned tables using the given prefix.
         *
         * If reuseDB is true and certain conditions apply, it will just change the prefix.
         * Otherwise, it will clone the tables and change the prefix.
         *
-        * Clones all tables in the given database (whatever database that connection has
-        * open), to versions with the test prefix.
-        *
         * @param IMaintainableDatabase $db Database to use
-        * @param string $prefix Prefix to use for test tables
+        * @param string|null $prefix Prefix to use for test tables. If not given, the prefix is determined
+        *        automatically for $db.
         * @return bool True if tables were cloned, false if only the prefix was changed
         */
-       protected static function setupDatabaseWithTestPrefix( IMaintainableDatabase $db, $prefix ) {
-               $tablesCloned = self::listTables( $db );
-               $dbClone = new CloneDatabase( $db, $tablesCloned, $prefix );
-               $dbClone->useTemporaryTables( self::$useTemporaryTables );
-
-               $db->_originalTablePrefix = $db->tablePrefix();
+       protected static function setupDatabaseWithTestPrefix(
+               IMaintainableDatabase $db,
+               $prefix = null
+       ) {
+               if ( $prefix === null ) {
+                       $prefix = self::getTestPrefixFor( $db );
+               }
 
                if ( ( $db->getType() == 'oracle' || !self::$useTemporaryTables ) && self::$reuseDB ) {
-                       CloneDatabase::changePrefix( $prefix );
-
+                       $db->tablePrefix( $prefix );
                        return false;
-               } else {
+               }
+
+               if ( !isset( $db->_originalTablePrefix ) ) {
+                       $oldPrefix = $db->tablePrefix();
+
+                       if ( $oldPrefix === $prefix ) {
+                               // table already has the correct prefix, but presumably no cloned tables
+                               $oldPrefix = self::$oldTablePrefix;
+                       }
+
+                       $db->tablePrefix( $oldPrefix );
+                       $tablesCloned = self::listTables( $db );
+                       $dbClone = new CloneDatabase( $db, $tablesCloned, $prefix, $oldPrefix );
+                       $dbClone->useTemporaryTables( self::$useTemporaryTables );
+
                        $dbClone->cloneTableStructure();
-                       return true;
+
+                       $db->tablePrefix( $prefix );
+                       $db->_originalTablePrefix = $oldPrefix;
                }
+
+               return true;
        }
 
        /**
@@ -1219,6 +1343,10 @@ abstract class MediaWikiTestCase extends PHPUnit\Framework\TestCase {
                if ( self::isUsingExternalStoreDB() ) {
                        self::setupExternalStoreTestDBs( $testPrefix );
                }
+
+               // NOTE: Change the prefix in the LBFactory and $wgDBprefix, to prevent
+               // *any* database connections to operate on live data.
+               CloneDatabase::changePrefix( $testPrefix );
        }
 
        /**
@@ -1273,19 +1401,12 @@ abstract class MediaWikiTestCase extends PHPUnit\Framework\TestCase {
        /**
         * Clones the External Store database(s) for testing
         *
-        * @param string $testPrefix Prefix for test tables
+        * @param string|null $testPrefix Prefix for test tables. Will be determined automatically
+        *        if not given.
         */
-       protected static function setupExternalStoreTestDBs( $testPrefix ) {
+       protected static function setupExternalStoreTestDBs( $testPrefix = null ) {
                $connections = self::getExternalStoreDatabaseConnections();
                foreach ( $connections as $dbw ) {
-                       // Hack: cloneTableStructure sets $wgDBprefix to the unit test
-                       // prefix,.  Even though listTables now uses tablePrefix, that
-                       // itself is populated from $wgDBprefix by default.
-
-                       // We have to set it back, or we won't find the original 'blobs'
-                       // table to copy.
-
-                       $dbw->tablePrefix( self::$oldTablePrefix );
                        self::setupDatabaseWithTestPrefix( $dbw, $testPrefix );
                }
        }
@@ -1339,8 +1460,10 @@ abstract class MediaWikiTestCase extends PHPUnit\Framework\TestCase {
        /**
         * @throws LogicException if the given database connection is not a set up to use
         * mock tables.
+        *
+        * @since 1.31 this is no longer private.
         */
-       private function ensureMockDatabaseConnection( IDatabase $db ) {
+       protected function ensureMockDatabaseConnection( IDatabase $db ) {
                if ( $db->tablePrefix() !== $this->dbPrefix() ) {
                        throw new LogicException(
                                'Trying to delete mock tables, but table prefix does not indicate a mock database.'
@@ -1374,7 +1497,7 @@ abstract class MediaWikiTestCase extends PHPUnit\Framework\TestCase {
        }
 
        /**
-        * Undoes the dpecified schema overrides..
+        * Undoes the specified schema overrides..
         * Called once per test class, just before addDataOnce().
         *
         * @param IMaintainableDatabase $db
@@ -1384,7 +1507,7 @@ abstract class MediaWikiTestCase extends PHPUnit\Framework\TestCase {
                $this->ensureMockDatabaseConnection( $db );
 
                $oldOverrides = $oldOverrides + self::$schemaOverrideDefaults;
-               $originalTables = $this->listOriginalTables( $db );
+               $originalTables = $this->listOriginalTables( $db, 'unprefixed' );
 
                // Drop tables that need to be restored or removed.
                $tablesToDrop = array_merge( $oldOverrides['create'], $oldOverrides['alter'] );
@@ -1410,8 +1533,7 @@ abstract class MediaWikiTestCase extends PHPUnit\Framework\TestCase {
         */
        private function setUpSchema( IMaintainableDatabase $db ) {
                // Undo any active overrides.
-               $oldOverrides = isset( $db->_schemaOverrides ) ? $db->_schemaOverrides
-                       : self::$schemaOverrideDefaults;
+               $oldOverrides = $db->_schemaOverrides ?? self::$schemaOverrideDefaults;
 
                if ( $oldOverrides['alter'] || $oldOverrides['create'] || $oldOverrides['drop'] ) {
                        $this->undoSchemaOverrides( $db, $oldOverrides );
@@ -1446,7 +1568,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 );
+               $originalTables = $this->listOriginalTables( $db, 'unprefixed' );
                $tablesToDrop = array_intersect( $originalTables, $overrides['create'] );
 
                if ( $tablesToDrop ) {
@@ -1491,7 +1613,7 @@ abstract class MediaWikiTestCase extends PHPUnit\Framework\TestCase {
                        if ( $tbl === 'page' ) {
                                // Forget about the pages since they don't
                                // exist in the DB.
-                               LinkCache::singleton()->clear();
+                               MediaWikiServices::getInstance()->getLinkCache()->clear();
                        }
                }
        }
@@ -1500,14 +1622,25 @@ abstract class MediaWikiTestCase extends PHPUnit\Framework\TestCase {
         * Lists all tables in the live database schema.
         *
         * @param IMaintainableDatabase $db
+        * @param string $prefix Either 'prefixed' or 'unprefixed'
         * @return array
         */
-       private function listOriginalTables( IMaintainableDatabase $db ) {
+       private function listOriginalTables( IMaintainableDatabase $db, $prefix = 'prefixed' ) {
                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;
        }
 
@@ -1526,7 +1659,7 @@ abstract class MediaWikiTestCase extends PHPUnit\Framework\TestCase {
                        throw new LogicException( 'No original table prefix know, cannot restore tables!' );
                }
 
-               $originalTables = $this->listOriginalTables( $db );
+               $originalTables = $this->listOriginalTables( $db, 'unprefixed' );
                $tables = array_intersect( $tables, $originalTables );
 
                $dbClone = new CloneDatabase( $db, $tables, $db->tablePrefix(), $db->_originalTablePrefix );
@@ -1544,8 +1677,10 @@ abstract class MediaWikiTestCase extends PHPUnit\Framework\TestCase {
        private function resetDB( $db, $tablesUsed ) {
                if ( $db ) {
                        $userTables = [ 'user', 'user_groups', 'user_properties', 'actor' ];
-                       $pageTables = [ 'page', 'revision', 'ip_changes', 'revision_comment_temp',
-                               'revision_actor_temp', 'comment' ];
+                       $pageTables = [
+                               'page', 'revision', 'ip_changes', 'revision_comment_temp', 'comment', 'archive',
+                               'revision_actor_temp', 'slots', 'content', 'content_models', 'slot_roles',
+                       ];
                        $coreDBDataTables = array_merge( $userTables, $pageTables );
 
                        // If any of the user or page tables were marked as used, we should clear all of them.
@@ -1557,6 +1692,19 @@ abstract class MediaWikiTestCase extends PHPUnit\Framework\TestCase {
                                $tablesUsed = array_unique( array_merge( $tablesUsed, $pageTables ) );
                        }
 
+                       // Postgres, Oracle, and MSSQL all use mwuser/pagecontent
+                       // instead of user/text. But Postgres does not remap the
+                       // table name in tableExists(), so we mark the real table
+                       // names as being used.
+                       if ( $db->getType() === 'postgres' ) {
+                               if ( in_array( 'user', $tablesUsed ) ) {
+                                       $tablesUsed[] = 'mwuser';
+                               }
+                               if ( in_array( 'text', $tablesUsed ) ) {
+                                       $tablesUsed[] = 'pagecontent';
+                               }
+                       }
+
                        $truncate = in_array( $db->getType(), [ 'oracle', 'mysql' ] );
                        foreach ( $tablesUsed as $tbl ) {
                                // TODO: reset interwiki table to its original content.
@@ -1582,7 +1730,7 @@ abstract class MediaWikiTestCase extends PHPUnit\Framework\TestCase {
                                if ( $tbl === 'page' ) {
                                        // Forget about the pages since they don't
                                        // exist in the DB.
-                                       LinkCache::singleton()->clear();
+                                       MediaWikiServices::getInstance()->getLinkCache()->clear();
                                }
                        }
 
@@ -1637,6 +1785,29 @@ abstract class MediaWikiTestCase extends PHPUnit\Framework\TestCase {
                return $tables;
        }
 
+       /**
+        * Copy test data from one database connection to another.
+        *
+        * This should only be used for small data sets.
+        *
+        * @param IDatabase $source
+        * @param IDatabase $target
+        */
+       public function copyTestData( IDatabase $source, IDatabase $target ) {
+               $tables = self::listOriginalTables( $source, 'unprefixed' );
+
+               foreach ( $tables as $table ) {
+                       $res = $source->select( $table, '*', [], __METHOD__ );
+                       $allRows = [];
+
+                       foreach ( $res as $row ) {
+                               $allRows[] = (array)$row;
+                       }
+
+                       $target->insert( $table, $allRows, __METHOD__, [ 'IGNORE' ] );
+               }
+       }
+
        /**
         * @throws MWException
         * @since 1.18
@@ -1821,7 +1992,7 @@ abstract class MediaWikiTestCase extends PHPUnit\Framework\TestCase {
                uasort(
                        $array,
                        function ( $a, $b ) {
-                               return serialize( $a ) > serialize( $b ) ? 1 : -1;
+                               return serialize( $a ) <=> serialize( $b );
                        }
                );
        }
@@ -2044,4 +2215,41 @@ abstract class MediaWikiTestCase extends PHPUnit\Framework\TestCase {
                }
                self::assertEquals( file_get_contents( $fileName ), $actualData, $msg );
        }
+
+       /**
+        * Edits or creates a page/revision
+        * @param string $pageName Page title
+        * @param string $text Content of the page
+        * @param string $summary Optional summary string for the revision
+        * @param int $defaultNs Optional namespace id
+        * @return array Array as returned by WikiPage::doEditContent()
+        */
+       protected function editPage( $pageName, $text, $summary = '', $defaultNs = NS_MAIN ) {
+               $title = Title::newFromText( $pageName, $defaultNs );
+               $page = WikiPage::factory( $title );
+
+               return $page->doEditContent( ContentHandler::makeContent( $text, $title ), $summary );
+       }
+
+       /**
+        * Revision-deletes a revision.
+        *
+        * @param Revision|int $rev Revision to delete
+        * @param array $value Keys are Revision::DELETED_* flags.  Values are 1 to set the bit, 0 to
+        *   clear, -1 to leave alone.  (All other values also clear the bit.)
+        * @param string $comment Deletion comment
+        */
+       protected function revisionDelete(
+               $rev, array $value = [ Revision::DELETED_TEXT => 1 ], $comment = ''
+       ) {
+               if ( is_int( $rev ) ) {
+                       $rev = Revision::newFromId( $rev );
+               }
+               RevisionDeleter::createList(
+                       'revision', RequestContext::getMain(), $rev->getTitle(), [ $rev->getId() ]
+               )->setVisibility( [
+                       'value' => $value,
+                       'comment' => $comment,
+               ] );
+       }
 }
index f0c78ec..cadd0ff 100644 (file)
@@ -143,7 +143,7 @@ class ResourceLoaderTestModule extends ResourceLoaderModule {
        }
 
        public function shouldEmbedModule( ResourceLoaderContext $context ) {
-               return $this->shouldEmbed !== null ? $this->shouldEmbed : parent::shouldEmbedModule( $context );
+               return $this->shouldEmbed ?? parent::shouldEmbedModule( $context );
        }
 
        public function enableModuleContentVersion() {
diff --git a/tests/phpunit/data/autoloader/psr4/TestFooBar.php b/tests/phpunit/data/autoloader/psr4/TestFooBar.php
new file mode 100644 (file)
index 0000000..4a2e11f
--- /dev/null
@@ -0,0 +1,6 @@
+<?php
+
+namespace Test\MediaWiki\AutoLoader;
+
+class TestFooBar {
+}
diff --git a/tests/phpunit/data/registration/autoload_namespaces.json b/tests/phpunit/data/registration/autoload_namespaces.json
new file mode 100644 (file)
index 0000000..19c502c
--- /dev/null
@@ -0,0 +1,7 @@
+{
+       "manifest_version": 2,
+       "name": "WithAutoloadNamespaces",
+       "AutoloadNamespaces": {
+               "Test\\MediaWiki\\AutoLoader\\": "../autoloader/psr4/"
+       }
+}
diff --git a/tests/phpunit/data/registration/duplicate_keys.json b/tests/phpunit/data/registration/duplicate_keys.json
new file mode 100644 (file)
index 0000000..40f2f7e
--- /dev/null
@@ -0,0 +1,4 @@
+{
+       "name": "FooBar",
+       "name": "Test"
+}
index ad16c5e..cfad069 100644 (file)
@@ -1,4 +1,12 @@
 {
        "name": "FooBar",
-       "manifest_version": 1
+       "attributes": {
+               "FooBar": {
+                       "Attr": [ "test" ]
+               },
+               "NotLoaded": {
+                       "Attr": [ "test2" ]
+               }
+       },
+       "manifest_version": 2
 }
diff --git a/tests/phpunit/data/xmp/1.result.php b/tests/phpunit/data/xmp/1.result.php
deleted file mode 100644 (file)
index c91fe29..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-<?php
-
-$result = [ 'xmp-exif' =>
-       [
-               'DigitalZoomRatio' => '0/10',
-               'Flash' => '9'
-       ]
-];
diff --git a/tests/phpunit/data/xmp/1.xmp b/tests/phpunit/data/xmp/1.xmp
deleted file mode 100644 (file)
index 66e1542..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core
- 4.1.3-c001 49.282696, Mon Apr 02 2007 21:16:10        "> 
-<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> 
-<rdf:Description
- rdf:about=""
- xmlns:exif="http://ns.adobe.com/exif/1.0/"
- exif:DigitalZoomRatio="0/10">
-<exif:Flash rdf:parseType='Resource'>
-<exif:Fired>True</exif:Fired> <exif:Return>0</exif:Return> <exif:Mode>1</exif:Mode> <exif:Function>False</exif:Function> <exif:RedEyeMode>False</exif:RedEyeMode></exif:Flash> </rdf:Description> </rdf:RDF> </x:xmpmeta>           
-
-<?xpacket end="w"?>
diff --git a/tests/phpunit/data/xmp/2.result.php b/tests/phpunit/data/xmp/2.result.php
deleted file mode 100644 (file)
index c91fe29..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-<?php
-
-$result = [ 'xmp-exif' =>
-       [
-               'DigitalZoomRatio' => '0/10',
-               'Flash' => '9'
-       ]
-];
diff --git a/tests/phpunit/data/xmp/2.xmp b/tests/phpunit/data/xmp/2.xmp
deleted file mode 100644 (file)
index 0fa6a89..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core
- 4.1.3-c001 49.282696, Mon Apr 02 2007 21:16:10        "> 
-<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> 
-<rdf:Description
- rdf:about=""
- xmlns:exif="http://ns.adobe.com/exif/1.0/"
- exif:DigitalZoomRatio="0/10">
-<exif:Flash>
-<rdf:Description exif:Return="0">
-<exif:Fired>True</exif:Fired> <exif:Mode>1</exif:Mode> <exif:Function>False</exif:Function> <exif:RedEyeMode>False</exif:RedEyeMode></rdf:Description></exif:Flash> </rdf:Description> </rdf:RDF> </x:xmpmeta>           
-
-<?xpacket end="w"?>
diff --git a/tests/phpunit/data/xmp/3-invalid.result.php b/tests/phpunit/data/xmp/3-invalid.result.php
deleted file mode 100644 (file)
index 701661f..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-<?php
-
-$result = [ 'xmp-exif' =>
-       [
-               'DigitalZoomRatio' => '0/10',
-       ]
-];
diff --git a/tests/phpunit/data/xmp/3-invalid.xmp b/tests/phpunit/data/xmp/3-invalid.xmp
deleted file mode 100644 (file)
index 2425e25..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core
- 4.1.3-c001 49.282696, Mon Apr 02 2007 21:16:10        "> 
-<!--
-This file has an invalid flash compoenent (one of the values are a qualifier)
--->
-<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> 
-<rdf:Description
- rdf:about=""
- xmlns:exif="http://ns.adobe.com/exif/1.0/"
->
-<exif:DigitalZoomRatio>
-
-<rdf:Description>
-<rdf:value>
-0/10
-</rdf:value>
-<exif:foobarbaz>fred</exif:foobarbaz>
-
-</rdf:Description>
-
-</exif:DigitalZoomRatio>
-
-<exif:Flash>
-<rdf:Description exif:Return="0">
-<exif:Mode><rdf:Description>
-<rdf:value>1</rdf:value>
-<exif:Fired>False</exif:Fired> <!-- qualifier. should be ignored-->
-</rdf:Description>
-</exif:Mode> <exif:Function>False</exif:Function> <exif:RedEyeMode>False</exif:RedEyeMode></rdf:Description></exif:Flash> </rdf:Description> </rdf:RDF> </x:xmpmeta>           
-
-<?xpacket end="w"?>
diff --git a/tests/phpunit/data/xmp/3.result.php b/tests/phpunit/data/xmp/3.result.php
deleted file mode 100644 (file)
index c91fe29..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-<?php
-
-$result = [ 'xmp-exif' =>
-       [
-               'DigitalZoomRatio' => '0/10',
-               'Flash' => '9'
-       ]
-];
diff --git a/tests/phpunit/data/xmp/3.xmp b/tests/phpunit/data/xmp/3.xmp
deleted file mode 100644 (file)
index 2cf1988..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core
- 4.1.3-c001 49.282696, Mon Apr 02 2007 21:16:10        "> 
-<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> 
-<rdf:Description
- rdf:about=""
- xmlns:exif="http://ns.adobe.com/exif/1.0/"
->
-<exif:DigitalZoomRatio>
-
-<rdf:Description>
-<rdf:value>
-0/10
-</rdf:value>
-<exif:foobarbaz>fred</exif:foobarbaz>
-
-</rdf:Description>
-
-</exif:DigitalZoomRatio>
-
-<exif:Flash>
-<rdf:Description exif:Return="0">
-<exif:Fired>True</exif:Fired> 
-<exif:Mode><rdf:Description>
-<rdf:value>1</rdf:value>
-<exif:Fired>False</exif:Fired> <!-- qualifier. should be ignored-->
-</rdf:Description>
-</exif:Mode> <exif:Function>False</exif:Function> <exif:RedEyeMode>False</exif:RedEyeMode></rdf:Description></exif:Flash> </rdf:Description> </rdf:RDF> </x:xmpmeta>           
-
-<?xpacket end="w"?>
diff --git a/tests/phpunit/data/xmp/4.result.php b/tests/phpunit/data/xmp/4.result.php
deleted file mode 100644 (file)
index 701661f..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-<?php
-
-$result = [ 'xmp-exif' =>
-       [
-               'DigitalZoomRatio' => '0/10',
-       ]
-];
diff --git a/tests/phpunit/data/xmp/4.xmp b/tests/phpunit/data/xmp/4.xmp
deleted file mode 100644 (file)
index 29eb614..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core
- 4.1.3-c001 49.282696, Mon Apr 02 2007 21:16:10        "> 
-<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
-<!-- Valid output is just the DigitalZoomRatio
-as the flash is a qualifier
---> 
-<rdf:Description
- rdf:about=""
- xmlns:exif="http://ns.adobe.com/exif/1.0/">
- <exif:DigitalZoomRatio>
-<rdf:Description>
-<rdf:value>
-0/10
-</rdf:value>
-<exif:Flash rdf:parseType='Resource'>
-<exif:Fired>True</exif:Fired> <exif:Return>0</exif:Return> <exif:Mode>1</exif:Mode> <exif:Function>False</exif:Function> <exif:RedEyeMode>False</exif:RedEyeMode></exif:Flash>
-</rdf:Description>
-</exif:DigitalZoomRatio>
-</rdf:Description> </rdf:RDF> </x:xmpmeta>
-
-
-<?xpacket end="w"?>
diff --git a/tests/phpunit/data/xmp/5.result.php b/tests/phpunit/data/xmp/5.result.php
deleted file mode 100644 (file)
index 701661f..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-<?php
-
-$result = [ 'xmp-exif' =>
-       [
-               'DigitalZoomRatio' => '0/10',
-       ]
-];
diff --git a/tests/phpunit/data/xmp/5.xmp b/tests/phpunit/data/xmp/5.xmp
deleted file mode 100644 (file)
index 3cc61d6..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core
- 4.1.3-c001 49.282696, Mon Apr 02 2007 21:16:10        "> 
-<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> 
-<rdf:Description
- rdf:about=""
- xmlns:exif="http://ns.adobe.com/exif/1.0/">
- <exif:DigitalZoomRatio>
-<rdf:Description rdf:value="0/10">
-<exif:Flash rdf:parseType='Resource'>
-<exif:Fired>True</exif:Fired> <exif:Return>0</exif:Return> <exif:Mode>1</exif:Mode> <exif:Function>False</exif:Function> <exif:RedEyeMode>False</exif:RedEyeMode></exif:Flash>
-</rdf:Description>
-</exif:DigitalZoomRatio>
-</rdf:Description> </rdf:RDF> </x:xmpmeta>
-
-
-<?xpacket end="w"?>
diff --git a/tests/phpunit/data/xmp/6.result.php b/tests/phpunit/data/xmp/6.result.php
deleted file mode 100644 (file)
index c91fe29..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-<?php
-
-$result = [ 'xmp-exif' =>
-       [
-               'DigitalZoomRatio' => '0/10',
-               'Flash' => '9'
-       ]
-];
diff --git a/tests/phpunit/data/xmp/6.xmp b/tests/phpunit/data/xmp/6.xmp
deleted file mode 100644 (file)
index f435ab2..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core
- 4.1.3-c001 49.282696, Mon Apr 02 2007 21:16:10        "> 
-<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> 
-<rdf:Description
- rdf:about=""
- xmlns:exif="http://ns.adobe.com/exif/1.0/">
-<exif:DigitalZoomRatio>
-0/10
-</exif:DigitalZoomRatio>
-</rdf:Description>
-<rdf:Description
- rdf:about=""
- xmlns:exif="http://ns.adobe.com/exif/1.0/">
-
-<exif:Flash rdf:parseType='Resource'>
-<exif:Fired>True</exif:Fired> <exif:Return>0</exif:Return> <exif:Mode>1</exif:Mode> <exif:Function>False</exif:Function> <exif:RedEyeMode>False</exif:RedEyeMode></exif:Flash> </rdf:Description> </rdf:RDF> </x:xmpmeta>           
-
-<?xpacket end="w"?>
diff --git a/tests/phpunit/data/xmp/7.result.php b/tests/phpunit/data/xmp/7.result.php
deleted file mode 100644 (file)
index ad88df3..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-<?php
-$result = [
-       'xmp-exif' =>
-       [
-               'CameraOwnerName' => 'Me!',
-       ],
-       'xmp-general' =>
-       [
-               'LicenseUrl' => 'http://creativecommons.com/cc-by-2.9',
-               'ImageDescription' =>
-               [
-                       'x-default' => 'Test image for the cc: xmp: xmpRights: namespaces in xmp',
-                       '_type' => 'lang',
-               ],
-               'ObjectName' =>
-               [
-                       'x-default' => 'xmp core/xmp rights/cc ns test',
-                       '_type' => 'lang',
-               ],
-               'DateTimeDigitized' => '2005:04:03',
-               'Software' => 'The one true editor: Vi (ok i used gimp)',
-               'Identifier' =>
-               [
-                       0 => 'http://example.com/identifierurl',
-                       1 => 'urn:sha1:342524abcdef',
-                       '_type' => 'ul',
-               ],
-               'Label' => 'Test image',
-               'DateTimeMetadata' => '2011:05:12',
-               'DateTime' => '2007:03:04 06:34:10',
-               'Nickname' => 'My little xmp test image',
-               'Rating' => '5',
-               'RightsCertificate' => 'http://example.com/rights-certificate/',
-               'Copyrighted' => 'True',
-               'CopyrightOwner' =>
-               [
-                       0 => 'Bawolff is copyright owner',
-                       '_type' => 'ul',
-               ],
-               'UsageTerms' =>
-               [
-                       'x-default' => 'do whatever you want',
-                       'en-gb' => 'Do whatever you want in british english',
-                       '_type' => 'lang',
-               ],
-               'WebStatement' => 'http://example.com/web_statement',
-       ],
-       'xmp-deprecated' =>
-       [
-               'Identifier' => 'http://example.com/identifierurl/wrong',
-       ],
-];
diff --git a/tests/phpunit/data/xmp/7.xmp b/tests/phpunit/data/xmp/7.xmp
deleted file mode 100644 (file)
index e18e13d..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-<?xpacket begin='' id='W5M0MpCehiHzreSzNTczkc9d'?>
-<x:xmpmeta xmlns:x='adobe:ns:meta/' x:xmptk='Image::ExifTool 7.30'>
-<rdf:RDF xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'>
-
- <rdf:Description rdf:about=''
-  xmlns:aux='http://ns.adobe.com/exif/1.0/aux/'>
-  <aux:OwnerName>Me!</aux:OwnerName>
- </rdf:Description>
-
- <rdf:Description rdf:about=''
-  xmlns:cc='http://creativecommons.org/ns#'>
-  <cc:license>http://creativecommons.com/cc-by-2.9</cc:license>
- </rdf:Description>
-
- <rdf:Description rdf:about=''
-  xmlns:dc='http://purl.org/dc/elements/1.1/'>
-  <dc:description>
-   <rdf:Alt>
-    <rdf:li xml:lang='x-default'>Test image for the cc: xmp: xmpRights: namespaces in xmp</rdf:li>
-   </rdf:Alt>
-  </dc:description>
-  <dc:identifier>http://example.com/identifierurl/wrong</dc:identifier>
-  <dc:title>
-   <rdf:Alt>
-    <rdf:li xml:lang='x-default'>xmp core/xmp rights/cc ns test</rdf:li>
-   </rdf:Alt>
-  </dc:title>
- </rdf:Description>
-
- <rdf:Description rdf:about=''
-  xmlns:xmp='http://ns.adobe.com/xap/1.0/'>
-  <xmp:CreateDate>2005-04-03</xmp:CreateDate>
-  <xmp:CreatorTool>The one true editor: Vi (ok i used gimp)</xmp:CreatorTool>
-  <xmp:Identifier>
-   <rdf:Bag>
-    <rdf:li>http://example.com/identifierurl
-</rdf:li>
-    <rdf:li>urn:sha1:342524abcdef</rdf:li>
-   </rdf:Bag>
-  </xmp:Identifier>
-  <xmp:Label>Test image</xmp:Label>
-  <xmp:MetadataDate>2011-05-12</xmp:MetadataDate>
-  <xmp:ModifyDate>2007-03-04T12:34:10-06:00</xmp:ModifyDate>
-  <xmp:Nickname>My little xmp test image</xmp:Nickname>
-  <xmp:Rating>7</xmp:Rating>
- </rdf:Description>
-
- <rdf:Description rdf:about=''
-  xmlns:xmpRights='http://ns.adobe.com/xap/1.0/rights/'>
-  <xmpRights:Certificate>http://example.com/rights-certificate/</xmpRights:Certificate>
-  <xmpRights:Marked>True</xmpRights:Marked>
-  <xmpRights:Owner>
-   <rdf:Bag>
-    <rdf:li>Bawolff is copyright owner</rdf:li>
-   </rdf:Bag>
-  </xmpRights:Owner>
-  <xmpRights:UsageTerms>
-   <rdf:Alt>
-    <rdf:li xml:lang='x-default'>do whatever you want</rdf:li>
-    <rdf:li xml:lang='en-GB'>Do whatever you want in british english</rdf:li>
-   </rdf:Alt>
-  </xmpRights:UsageTerms>
-  <xmpRights:WebStatement>http://example.com/web_statement</xmpRights:WebStatement>
- </rdf:Description>
-</rdf:RDF>
-</x:xmpmeta>
-<?xpacket end='r'?>
diff --git a/tests/phpunit/data/xmp/README b/tests/phpunit/data/xmp/README
deleted file mode 100644 (file)
index bd94917..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-This directory contains a bunch of XMP files
-as well as a bunch of php files containing what the
-parsed version of the XMP looks like.
diff --git a/tests/phpunit/data/xmp/bag-for-seq.result.php b/tests/phpunit/data/xmp/bag-for-seq.result.php
deleted file mode 100644 (file)
index 3d8eeb0..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-<?php
-
-$result = [
-       'xmp-general' => [
-               'Artist' => [
-                       '_type' => 'ul',
-                       0 => 'The author',
-               ]
-       ]
-];
diff --git a/tests/phpunit/data/xmp/bag-for-seq.xmp b/tests/phpunit/data/xmp/bag-for-seq.xmp
deleted file mode 100644 (file)
index c6ed5b7..0000000
+++ /dev/null
@@ -1 +0,0 @@
-<?xpacket begin=""?> <x:xmpmeta xmlns:x="adobe:ns:meta/"> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:dc="http://purl.org/dc/elements/1.1/"> <dc:creator> <rdf:Bag> <rdf:li>The author</rdf:li> </rdf:Bag> </dc:creator> </rdf:Description> </rdf:RDF> </x:xmpmeta>
diff --git a/tests/phpunit/data/xmp/doctype-included.result.php b/tests/phpunit/data/xmp/doctype-included.result.php
deleted file mode 100644 (file)
index d4ac654..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-<?php
-
-$result = [];
diff --git a/tests/phpunit/data/xmp/doctype-included.xmp b/tests/phpunit/data/xmp/doctype-included.xmp
deleted file mode 100644 (file)
index 8c94675..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?> <!DOCTYPE x:xmpmeta [ <!ENTITY lol "lollollollollollollollollollollol"> ]>
-<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core
- 4.1.3-c001 49.282696, Mon Apr 02 2007 21:16:10        ">
-<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
-<rdf:Description
- rdf:about=""
- xmlns:exif="http://ns.adobe.com/exif/1.0/"
- exif:DigitalZoomRatio="0/10">
-<exif:Flash rdf:parseType='Resource'>
-<exif:Fired>True</exif:Fired> <exif:Return>0</exif:Return> <exif:Mode>1</exif:Mode> <exif:Function>False</exif:Function> <exif:RedEyeMode>False</exif:RedEyeMode></exif:Flash> </rdf:Description> </rdf:RDF> </x:xmpmeta>
-
-<?xpacket end="w"?>
diff --git a/tests/phpunit/data/xmp/doctype-not-included.xmp b/tests/phpunit/data/xmp/doctype-not-included.xmp
deleted file mode 100644 (file)
index 9a40b4b..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core
- 4.1.3-c001 49.282696, Mon Apr 02 2007 21:16:10        ">
-<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
-<rdf:Description
- rdf:about=""
- xmlns:exif="http://ns.adobe.com/exif/1.0/"
- exif:DigitalZoomRatio="0/10">
-<exif:Flash rdf:parseType='Resource'>
-<exif:Fired>True</exif:Fired> <exif:Return>0</exif:Return> <exif:Mode>1</exif:Mode> <exif:Function>False</exif:Function> <exif:RedEyeMode>False</exif:RedEyeMode></exif:Flash> </rdf:Description> </rdf:RDF> </x:xmpmeta>
-
-<?xpacket end="w"?>
diff --git a/tests/phpunit/data/xmp/flash.result.php b/tests/phpunit/data/xmp/flash.result.php
deleted file mode 100644 (file)
index 3150d5c..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-<?php
-
-$result = [ 'xmp-exif' =>
-       [
-               'DigitalZoomRatio' => '0/10',
-               'Flash' => '127'
-       ]
-];
diff --git a/tests/phpunit/data/xmp/flash.xmp b/tests/phpunit/data/xmp/flash.xmp
deleted file mode 100644 (file)
index b1373cc..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core
- 4.1.3-c001 49.282696, Mon Apr 02 2007 21:16:10        "> 
-<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> 
-<rdf:Description
- rdf:about=""
- xmlns:exif="http://ns.adobe.com/exif/1.0/"
- exif:DigitalZoomRatio="0/10">
-<exif:Flash rdf:parseType='Resource'>
-<exif:Fired>True</exif:Fired> <exif:Return>3</exif:Return> <exif:Mode>3</exif:Mode> <exif:Function>True</exif:Function> <exif:RedEyeMode>True</exif:RedEyeMode></exif:Flash> </rdf:Description> </rdf:RDF> </x:xmpmeta>           
-
-<?xpacket end="w"?>
diff --git a/tests/phpunit/data/xmp/gps.result.php b/tests/phpunit/data/xmp/gps.result.php
deleted file mode 100644 (file)
index 6bc35f5..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-<?php
-
-$result = [ 'xmp-exif' =>
-       [
-               'GPSAltitude' => -3.14159265301,
-               'GPSDOP' => '5/1',
-               'GPSLatitude' => 88.51805555,
-               'GPSLongitude' => -21.12356945,
-               'GPSVersionID' => '2.2.0.0'
-       ]
-];
diff --git a/tests/phpunit/data/xmp/gps.xmp b/tests/phpunit/data/xmp/gps.xmp
deleted file mode 100644 (file)
index e52d2c8..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xpacket begin='' id='W5M0MpCehiHzreSzNTczkc9d'?>
-<x:xmpmeta xmlns:x='adobe:ns:meta/' x:xmptk='Image::ExifTool 7.30'>
-<rdf:RDF xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'>
-
- <rdf:Description rdf:about=''
-  xmlns:exif='http://ns.adobe.com/exif/1.0/'>
-  <exif:GPSAltitude>103993/33102</exif:GPSAltitude>
-  <exif:GPSAltitudeRef>1</exif:GPSAltitudeRef>
-  <exif:GPSDOP>5/1</exif:GPSDOP>
-  <exif:GPSLatitude>88,31.083333N</exif:GPSLatitude>
-  <exif:GPSLongitude>21,7.414167W</exif:GPSLongitude>
-  <exif:GPSVersionID>2.2.0.0</exif:GPSVersionID>
- </rdf:Description>
-
-</rdf:RDF>
-</x:xmpmeta>
-<?xpacket end='w'?>
diff --git a/tests/phpunit/data/xmp/invalid-child-not-struct.result.php b/tests/phpunit/data/xmp/invalid-child-not-struct.result.php
deleted file mode 100644 (file)
index 701661f..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-<?php
-
-$result = [ 'xmp-exif' =>
-       [
-               'DigitalZoomRatio' => '0/10',
-       ]
-];
diff --git a/tests/phpunit/data/xmp/invalid-child-not-struct.xmp b/tests/phpunit/data/xmp/invalid-child-not-struct.xmp
deleted file mode 100644 (file)
index 6aa0c10..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core
- 4.1.3-c001 49.282696, Mon Apr 02 2007 21:16:10        "> 
-<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> 
-<rdf:Description
- rdf:about=""
- xmlns:exif="http://ns.adobe.com/exif/1.0/"
- exif:DigitalZoomRatio="0/10">
-<exif:Fired>True</exif:Fired> <exif:Return>0</exif:Return> <exif:Mode>1</exif:Mode> <exif:Function>False</exif:Function> <exif:RedEyeMode>False</exif:RedEyeMode>
-
- </rdf:Description> </rdf:RDF> </x:xmpmeta>           
-
-<?xpacket end="w"?>
diff --git a/tests/phpunit/data/xmp/no-namespace.result.php b/tests/phpunit/data/xmp/no-namespace.result.php
deleted file mode 100644 (file)
index 8e33102..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-<?php
-
-$result = [ 'xmp-exif' =>
-       [
-               'FNumber' => '28/10',
-       ]
-];
diff --git a/tests/phpunit/data/xmp/no-namespace.xmp b/tests/phpunit/data/xmp/no-namespace.xmp
deleted file mode 100644 (file)
index 7d6cdb2..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
-<!-- Testing it handles random non-namespaced properties in files ok.
-     Some older photoshop's did not include the rdf: prefix on about. -->
-<rdf:Description
- about=""
- rdf:about=""
- xmlns:exif="http://ns.adobe.com/exif/1.0/"
- exif:FNumber="28/10">
-</rdf:Description>
-</rdf:RDF>
-<?xpacket end="w"?>
diff --git a/tests/phpunit/data/xmp/no-recognized-props.result.php b/tests/phpunit/data/xmp/no-recognized-props.result.php
deleted file mode 100644 (file)
index 824a242..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-<?php
-$result = [];
diff --git a/tests/phpunit/data/xmp/no-recognized-props.xmp b/tests/phpunit/data/xmp/no-recognized-props.xmp
deleted file mode 100644 (file)
index 54e8090..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> 
-<rdf:Description
- rdf:about=""
- xmlns:exif="http://ns.adobe.com/exif/1.0/not-exif-namespace"
- exif:FNumber="2/10">
-</rdf:Description>
-</rdf:RDF>
-<?xpacket end="w"?>
diff --git a/tests/phpunit/data/xmp/utf16BE.result.php b/tests/phpunit/data/xmp/utf16BE.result.php
deleted file mode 100644 (file)
index 5e876d9..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-<?php
-
-$result = [
-       'xmp-exif' =>
-               [
-                       'DigitalZoomRatio' => '0/10',
-               ],
-       'xmp-general' =>
-               [
-                       'Label' => '􊯍'
-               ],
-];
diff --git a/tests/phpunit/data/xmp/utf16BE.xmp b/tests/phpunit/data/xmp/utf16BE.xmp
deleted file mode 100644 (file)
index 0cf60d6..0000000
Binary files a/tests/phpunit/data/xmp/utf16BE.xmp and /dev/null differ
diff --git a/tests/phpunit/data/xmp/utf16LE.result.php b/tests/phpunit/data/xmp/utf16LE.result.php
deleted file mode 100644 (file)
index 5e876d9..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-<?php
-
-$result = [
-       'xmp-exif' =>
-               [
-                       'DigitalZoomRatio' => '0/10',
-               ],
-       'xmp-general' =>
-               [
-                       'Label' => '􊯍'
-               ],
-];
diff --git a/tests/phpunit/data/xmp/utf16LE.xmp b/tests/phpunit/data/xmp/utf16LE.xmp
deleted file mode 100644 (file)
index 66d71f4..0000000
Binary files a/tests/phpunit/data/xmp/utf16LE.xmp and /dev/null differ
diff --git a/tests/phpunit/data/xmp/utf32BE.result.php b/tests/phpunit/data/xmp/utf32BE.result.php
deleted file mode 100644 (file)
index 5e876d9..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-<?php
-
-$result = [
-       'xmp-exif' =>
-               [
-                       'DigitalZoomRatio' => '0/10',
-               ],
-       'xmp-general' =>
-               [
-                       'Label' => '􊯍'
-               ],
-];
diff --git a/tests/phpunit/data/xmp/utf32BE.xmp b/tests/phpunit/data/xmp/utf32BE.xmp
deleted file mode 100644 (file)
index 06afdf9..0000000
Binary files a/tests/phpunit/data/xmp/utf32BE.xmp and /dev/null differ
diff --git a/tests/phpunit/data/xmp/utf32LE.result.php b/tests/phpunit/data/xmp/utf32LE.result.php
deleted file mode 100644 (file)
index 5e876d9..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-<?php
-
-$result = [
-       'xmp-exif' =>
-               [
-                       'DigitalZoomRatio' => '0/10',
-               ],
-       'xmp-general' =>
-               [
-                       'Label' => '􊯍'
-               ],
-];
diff --git a/tests/phpunit/data/xmp/utf32LE.xmp b/tests/phpunit/data/xmp/utf32LE.xmp
deleted file mode 100644 (file)
index bf2097f..0000000
Binary files a/tests/phpunit/data/xmp/utf32LE.xmp and /dev/null differ
diff --git a/tests/phpunit/data/xmp/xmpExt.result.php b/tests/phpunit/data/xmp/xmpExt.result.php
deleted file mode 100644 (file)
index c91fe29..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-<?php
-
-$result = [ 'xmp-exif' =>
-       [
-               'DigitalZoomRatio' => '0/10',
-               'Flash' => '9'
-       ]
-];
diff --git a/tests/phpunit/data/xmp/xmpExt.xmp b/tests/phpunit/data/xmp/xmpExt.xmp
deleted file mode 100644 (file)
index da0383f..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core
- 4.1.3-c001 49.282696, Mon Apr 02 2007 21:16:10        "> 
-<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> 
-<rdf:Description
- rdf:about=""
- xmlns:exif="http://ns.adobe.com/exif/1.0/"
- xmlns:xmpNote="http://ns.adobe.com/xmp/note/"
- exif:DigitalZoomRatio="0/10"
- xmpNote:HasExtendedXMP="28C74E0AC2D796886759006FBE2E57B7">
-<exif:Flash rdf:parseType='Resource'>
-<exif:Fired>True</exif:Fired> <exif:Return>0</exif:Return> <exif:Mode>1</exif:Mode> <exif:Function>False</exif:Function> <exif:RedEyeMode>False</exif:RedEyeMode></exif:Flash> </rdf:Description> </rdf:RDF> </x:xmpmeta>           
-
-<?xpacket end="w"?>
diff --git a/tests/phpunit/data/xmp/xmpExt2.xmp b/tests/phpunit/data/xmp/xmpExt2.xmp
deleted file mode 100644 (file)
index 060abb2..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> 
-<rdf:Description
- rdf:about=""
- xmlns:exif="http://ns.adobe.com/exif/1.0/"
- exif:FNumber="2/10">
-</rdf:Description>
-</rdf:RDF>
-<?xpacket end="w"?>
diff --git a/tests/phpunit/documentation/ReleaseNotesTest.php b/tests/phpunit/documentation/ReleaseNotesTest.php
new file mode 100644 (file)
index 0000000..4de071d
--- /dev/null
@@ -0,0 +1,54 @@
+<?php
+
+/**
+ * James doesn't like having to manually fix these things.
+ */
+class ReleaseNotesTest extends MediaWikiTestCase {
+       /**
+        * Verify that at least one Release Notes file exists, have content, and
+        * aren't overly long.
+        *
+        * @group documentation
+        * @coversNothing
+        */
+       public function testReleaseNotesFilesExistAndAreNotMalformed() {
+               global $wgVersion, $IP;
+
+               $notesFiles = glob( "$IP/RELEASE-NOTES-*" );
+
+               $this->assertGreaterThanOrEqual(
+                       1,
+                       count( $notesFiles ),
+                       'Repo has at least one Release Notes file.'
+               );
+
+               $versionParts = explode( '.', explode( '-', $wgVersion )[0] );
+               $this->assertContains(
+                       "$IP/RELEASE-NOTES-$versionParts[0].$versionParts[1]",
+                       $notesFiles,
+                       'Repo has a Release Notes file for the current $wgVersion.'
+               );
+
+               foreach ( $notesFiles as $index => $fileName ) {
+                       $file = file( $fileName, FILE_IGNORE_NEW_LINES );
+
+                       $this->assertFalse(
+                               !$file,
+                               "Release Notes file '$fileName' is inaccessible."
+                       );
+
+                       $lines = count( $file );
+
+                       for ( $i = 0; $i < $lines; $i++ ) {
+                               $line = $file[$i];
+
+                               $this->assertLessThanOrEqual(
+                                       // FILE_IGNORE_NEW_LINES drops the \n at the EOL, so max length is 80 not 81.
+                                       80,
+                                       strlen( $line ),
+                                       "Release notes file '$fileName' line $i is longer than 80 chars:\n\t'$line'"
+                               );
+                       }
+               }
+       }
+}
index 1b0c848..d28be7a 100644 (file)
@@ -470,16 +470,17 @@ class ActorMigrationTest extends MediaWikiLangTestCase {
                }
 
                $stages = [
-                       MIGRATION_OLD => [ MIGRATION_OLD, MIGRATION_WRITE_NEW ],
-                       MIGRATION_WRITE_BOTH => [ MIGRATION_OLD, MIGRATION_NEW ],
-                       MIGRATION_WRITE_NEW => [ MIGRATION_WRITE_BOTH, MIGRATION_NEW ],
-                       MIGRATION_NEW => [ MIGRATION_WRITE_BOTH, MIGRATION_NEW ],
+                       MIGRATION_OLD => [ MIGRATION_OLD, MIGRATION_WRITE_BOTH, MIGRATION_WRITE_NEW ],
+                       MIGRATION_WRITE_BOTH => [ MIGRATION_OLD, MIGRATION_WRITE_BOTH, MIGRATION_WRITE_NEW,
+                               MIGRATION_NEW ],
+                       MIGRATION_WRITE_NEW => [ MIGRATION_WRITE_BOTH, MIGRATION_WRITE_NEW, MIGRATION_NEW ],
+                       MIGRATION_NEW => [ MIGRATION_WRITE_BOTH, MIGRATION_WRITE_NEW, MIGRATION_NEW ],
                ];
 
                $nameKey = $key . '_text';
                $actorKey = $key === 'ipb_by' ? 'ipb_by_actor' : substr( $key, 0, -5 ) . '_actor';
 
-               foreach ( $stages as $writeStage => $readRange ) {
+               foreach ( $stages as $writeStage => $possibleReadStages ) {
                        if ( $key === 'ipb_by' ) {
                                $extraFields['ipb_address'] = __CLASS__ . "#$writeStage";
                        }
@@ -512,7 +513,7 @@ class ActorMigrationTest extends MediaWikiLangTestCase {
                                $callback( $id, $extraFields );
                        }
 
-                       for ( $readStage = $readRange[0]; $readStage <= $readRange[1]; $readStage++ ) {
+                       foreach ( $possibleReadStages as $readStage ) {
                                $r = $this->makeMigration( $readStage );
 
                                $queryInfo = $r->getJoin( $key );
diff --git a/tests/phpunit/includes/AutoLoaderTest.php b/tests/phpunit/includes/AutoLoaderTest.php
new file mode 100644 (file)
index 0000000..af6911d
--- /dev/null
@@ -0,0 +1,64 @@
+<?php
+
+/**
+ * @covers AutoLoader
+ */
+class AutoLoaderTest extends MediaWikiTestCase {
+
+       private $oldPsr4;
+
+       protected function setUp() {
+               parent::setUp();
+
+               // Fancy dance to trigger a rebuild of AutoLoader::$autoloadLocalClassesLower
+               $this->mergeMwGlobalArrayValue( 'wgAutoloadLocalClasses', [
+                       'TestAutoloadedLocalClass' =>
+                               __DIR__ . '/../data/autoloader/TestAutoloadedLocalClass.php',
+                       'TestAutoloadedCamlClass' =>
+                               __DIR__ . '/../data/autoloader/TestAutoloadedCamlClass.php',
+                       'TestAutoloadedSerializedClass' =>
+                               __DIR__ . '/../data/autoloader/TestAutoloadedSerializedClass.php',
+               ] );
+               AutoLoader::resetAutoloadLocalClassesLower();
+
+               $this->mergeMwGlobalArrayValue( 'wgAutoloadClasses', [
+                       'TestAutoloadedClass' => __DIR__ . '/../data/autoloader/TestAutoloadedClass.php',
+               ] );
+
+               $this->oldPsr4 = AutoLoader::$psr4Namespaces;
+               AutoLoader::$psr4Namespaces['Test\\MediaWiki\\AutoLoader\\'] =
+                       __DIR__ . '/../data/autoloader/psr4';
+       }
+
+       protected function tearDown() {
+               AutoLoader::$psr4Namespaces = $this->oldPsr4;
+               parent::tearDown();
+       }
+
+       public function testCoreClass() {
+               $this->assertTrue( class_exists( 'TestAutoloadedLocalClass' ) );
+       }
+
+       public function testExtensionClass() {
+               $this->assertTrue( class_exists( 'TestAutoloadedClass' ) );
+       }
+
+       public function testWrongCaseClass() {
+               $this->setMwGlobals( 'wgAutoloadAttemptLowercase', true );
+
+               $this->assertTrue( class_exists( 'testautoLoadedcamlCLASS' ) );
+       }
+
+       public function testWrongCaseSerializedClass() {
+               $this->setMwGlobals( 'wgAutoloadAttemptLowercase', true );
+
+               $dummyCereal = 'O:29:"testautoloadedserializedclass":0:{}';
+               $uncerealized = unserialize( $dummyCereal );
+               $this->assertFalse( $uncerealized instanceof __PHP_Incomplete_Class,
+                       "unserialize() can load classes case-insensitively." );
+       }
+
+       public function testPsr4() {
+               $this->assertTrue( class_exists( 'Test\\MediaWiki\\AutoLoader\\TestFooBar' ) );
+       }
+}
index a510897..c41361c 100644 (file)
@@ -367,13 +367,14 @@ class CommentStoreTest extends MediaWikiLangTestCase {
                ];
 
                $stages = [
-                       MIGRATION_OLD => [ MIGRATION_OLD, MIGRATION_WRITE_NEW ],
-                       MIGRATION_WRITE_BOTH => [ MIGRATION_OLD, MIGRATION_NEW ],
-                       MIGRATION_WRITE_NEW => [ MIGRATION_WRITE_BOTH, MIGRATION_NEW ],
-                       MIGRATION_NEW => [ MIGRATION_WRITE_BOTH, MIGRATION_NEW ],
+                       MIGRATION_OLD => [ MIGRATION_OLD, MIGRATION_WRITE_BOTH, MIGRATION_WRITE_NEW ],
+                       MIGRATION_WRITE_BOTH => [ MIGRATION_OLD, MIGRATION_WRITE_BOTH, MIGRATION_WRITE_NEW,
+                               MIGRATION_NEW ],
+                       MIGRATION_WRITE_NEW => [ MIGRATION_WRITE_BOTH, MIGRATION_WRITE_NEW, MIGRATION_NEW ],
+                       MIGRATION_NEW => [ MIGRATION_WRITE_BOTH, MIGRATION_WRITE_NEW, MIGRATION_NEW ],
                ];
 
-               foreach ( $stages as $writeStage => $readRange ) {
+               foreach ( $stages as $writeStage => $possibleReadStages ) {
                        if ( $key === 'ipb_reason' ) {
                                $extraFields['ipb_address'] = __CLASS__ . "#$writeStage";
                        }
@@ -406,7 +407,7 @@ class CommentStoreTest extends MediaWikiLangTestCase {
                                $callback( $id );
                        }
 
-                       for ( $readStage = $readRange[0]; $readStage <= $readRange[1]; $readStage++ ) {
+                       foreach ( $possibleReadStages as $readStage ) {
                                $rstore = $this->makeStore( $readStage );
 
                                $fieldRow = $this->db->selectRow(
@@ -460,13 +461,14 @@ class CommentStoreTest extends MediaWikiLangTestCase {
                ];
 
                $stages = [
-                       MIGRATION_OLD => [ MIGRATION_OLD, MIGRATION_WRITE_NEW ],
-                       MIGRATION_WRITE_BOTH => [ MIGRATION_OLD, MIGRATION_NEW ],
-                       MIGRATION_WRITE_NEW => [ MIGRATION_WRITE_BOTH, MIGRATION_NEW ],
-                       MIGRATION_NEW => [ MIGRATION_WRITE_BOTH, MIGRATION_NEW ],
+                       MIGRATION_OLD => [ MIGRATION_OLD, MIGRATION_WRITE_BOTH, MIGRATION_WRITE_NEW ],
+                       MIGRATION_WRITE_BOTH => [ MIGRATION_OLD, MIGRATION_WRITE_BOTH, MIGRATION_WRITE_NEW,
+                               MIGRATION_NEW ],
+                       MIGRATION_WRITE_NEW => [ MIGRATION_WRITE_BOTH, MIGRATION_WRITE_NEW, MIGRATION_NEW ],
+                       MIGRATION_NEW => [ MIGRATION_WRITE_BOTH, MIGRATION_WRITE_NEW, MIGRATION_NEW ],
                ];
 
-               foreach ( $stages as $writeStage => $readRange ) {
+               foreach ( $stages as $writeStage => $possibleReadStages ) {
                        if ( $key === 'ipb_reason' ) {
                                $extraFields['ipb_address'] = __CLASS__ . "#$writeStage";
                        }
@@ -499,7 +501,7 @@ class CommentStoreTest extends MediaWikiLangTestCase {
                                $callback( $id );
                        }
 
-                       for ( $readStage = $readRange[0]; $readStage <= $readRange[1]; $readStage++ ) {
+                       foreach ( $possibleReadStages as $readStage ) {
                                $rstore = $this->makeStoreWithKey( $readStage, $key );
 
                                $fieldRow = $this->db->selectRow(
index 3f24030..c383be6 100644 (file)
@@ -92,6 +92,12 @@ class ContentSecurityPolicyTest extends MediaWikiTestCase {
                // @codingStandardsIgnoreStart Generic.Files.LineLength
                return [
                        [ false, '', '', '' ],
+                       [
+                               [ 'useNonces' => false ],
+                               "script-src 'unsafe-eval' 'self' 'unsafe-inline' sister-site.somewhere.com *.wikipedia.org; default-src * data: blob:; style-src * data: blob: 'unsafe-inline'; report-uri /w/api.php?action=cspreport&format=json&",
+                               "script-src 'unsafe-eval' 'self' 'unsafe-inline' sister-site.somewhere.com *.wikipedia.org; default-src * data: blob:; style-src * data: blob: 'unsafe-inline'; report-uri /w/api.php?action=cspreport&format=json&reportonly=1&",
+                               "script-src 'unsafe-eval' 'self' sister-site.somewhere.com *.wikipedia.org; default-src * data: blob:; style-src * data: blob: 'unsafe-inline'"
+                       ],
                        [
                                true,
                                "script-src 'unsafe-eval' 'self' 'nonce-secret' 'unsafe-inline' sister-site.somewhere.com *.wikipedia.org; default-src * data: blob:; style-src * data: blob: 'unsafe-inline'; report-uri /w/api.php?action=cspreport&format=json&",
@@ -283,14 +289,14 @@ class ContentSecurityPolicyTest extends MediaWikiTestCase {
 
        /**
         * @dataProvider providerCSPIsEnabled
-        * @covers ContentSecurityPolicy::isEnabled
+        * @covers ContentSecurityPolicy::isNonceRequired
         */
        public function testCSPIsEnabled( $main, $reportOnly, $expected ) {
                global $wgCSPReportOnlyHeader, $wgCSPHeader;
                global $wgCSPHeader;
                $oldReport = wfSetVar( $wgCSPReportOnlyHeader, $reportOnly );
                $oldMain = wfSetVar( $wgCSPHeader, $main );
-               $res = ContentSecurityPolicy::isEnabled( RequestContext::getMain()->getConfig() );
+               $res = ContentSecurityPolicy::isNonceRequired( RequestContext::getMain()->getConfig() );
                wfSetVar( $wgCSPReportOnlyHeader, $oldReport );
                wfSetVar( $wgCSPHeader, $oldMain );
                $this->assertEquals( $res, $expected );
@@ -305,6 +311,9 @@ class ContentSecurityPolicyTest extends MediaWikiTestCase {
                        [ false, [], true ],
                        [ [], false, true ],
                        [ [ 'default-src' => [ 'foo.example.com' ] ], false, true ],
+                       [ [ 'useNonces' => false ], [ 'useNonces' => false ], false ],
+                       [ [ 'useNonces' => true ], [ 'useNonces' => false ], true ],
+                       [ [ 'useNonces' => false ], [ 'useNonces' => true ], true ],
                ];
        }
 }
index 8f0826b..036b618 100644 (file)
@@ -16,11 +16,12 @@ class EditPageTest extends MediaWikiLangTestCase {
 
                parent::setUp();
 
+               $this->setContentLang( $wgContLang );
+
                $this->setMwGlobals( [
                        'wgExtraNamespaces' => $wgExtraNamespaces,
                        'wgNamespaceContentModels' => $wgNamespaceContentModels,
                        'wgContentHandlers' => $wgContentHandlers,
-                       'wgContLang' => $wgContLang,
                ] );
 
                $wgExtraNamespaces[12312] = 'Dummy';
index 75ebd31..94de088 100644 (file)
@@ -1,5 +1,7 @@
 <?php
 
+use MediaWiki\MediaWikiServices;
+
 /**
  * Parser-related tests that don't suit for parserTests.txt
  *
@@ -17,7 +19,7 @@ class ExtraParserTest extends MediaWikiTestCase {
 
                $contLang = Language::factory( 'en' );
                $this->setMwGlobals( [
-                       'wgShowDBErrorBacktrace' => true,
+                       'wgShowExceptionDetails' => true,
                        'wgCleanSignatures' => true,
                ] );
                $this->setUserLang( 'en' );
@@ -28,7 +30,7 @@ class ExtraParserTest extends MediaWikiTestCase {
                $this->options->setTemplateCallback( [ __CLASS__, 'statelessFetchTemplate' ] );
                $this->parser = new Parser;
 
-               MagicWord::clearCache();
+               MediaWikiServices::getInstance()->resetServiceForTesting( 'MagicWordFactory' );
        }
 
        /**
diff --git a/tests/phpunit/includes/GlobalFunctions/WfExpandUrlTest.php b/tests/phpunit/includes/GlobalFunctions/WfExpandUrlTest.php
new file mode 100644 (file)
index 0000000..f008830
--- /dev/null
@@ -0,0 +1,153 @@
+<?php
+/**
+ * @group GlobalFunctions
+ * @covers ::wfExpandUrl
+ */
+class WfExpandUrlTest extends MediaWikiTestCase {
+       /**
+        * @dataProvider provideExpandableUrls
+        */
+       public function testWfExpandUrl( $fullUrl, $shortUrl, $defaultProto,
+               $server, $canServer, $httpsMode, $httpsPort, $message
+       ) {
+               // Fake $wgServer, $wgCanonicalServer and $wgRequest->getProtocol()
+               // fake edit to fake globals
+               $this->setMwGlobals( [
+                       'wgServer' => $server,
+                       'wgCanonicalServer' => $canServer,
+                       'wgRequest' => new FauxRequest( [], false, null, $httpsMode ? 'https' : 'http' ),
+                       'wgHttpsPort' => $httpsPort
+               ] );
+
+               $this->assertEquals( $fullUrl, wfExpandUrl( $shortUrl, $defaultProto ), $message );
+       }
+
+       /**
+        * Provider of URL examples for testing wfExpandUrl()
+        *
+        * @return array
+        */
+       public static function provideExpandableUrls() {
+               $modes = [ 'http', 'https' ];
+               $servers = [
+                       'http' => 'http://example.com',
+                       'https' => 'https://example.com',
+                       'protocol-relative' => '//example.com'
+               ];
+               $defaultProtos = [
+                       'http' => PROTO_HTTP,
+                       'https' => PROTO_HTTPS,
+                       'protocol-relative' => PROTO_RELATIVE,
+                       'current' => PROTO_CURRENT,
+                       'canonical' => PROTO_CANONICAL
+               ];
+
+               $retval = [];
+               foreach ( $modes as $mode ) {
+                       $httpsMode = $mode == 'https';
+                       foreach ( $servers as $serverDesc => $server ) {
+                               foreach ( $modes as $canServerMode ) {
+                                       $canServer = "$canServerMode://example2.com";
+                                       foreach ( $defaultProtos as $protoDesc => $defaultProto ) {
+                                               $retval[] = [
+                                                       'http://example.com', 'http://example.com',
+                                                       $defaultProto, $server, $canServer, $httpsMode, 443,
+                                                       "Testing fully qualified http URLs (no need to expand) "
+                                                               . "(defaultProto: $protoDesc , wgServer: $server, "
+                                                               . "wgCanonicalServer: $canServer, current request protocol: $mode )"
+                                               ];
+                                               $retval[] = [
+                                                       'https://example.com', 'https://example.com',
+                                                       $defaultProto, $server, $canServer, $httpsMode, 443,
+                                                       "Testing fully qualified https URLs (no need to expand) "
+                                                               . "(defaultProto: $protoDesc , wgServer: $server, "
+                                                               . "wgCanonicalServer: $canServer, current request protocol: $mode )"
+                                               ];
+                                               # Would be nice to support this, see fixme on wfExpandUrl()
+                                               $retval[] = [
+                                                       "wiki/FooBar", 'wiki/FooBar',
+                                                       $defaultProto, $server, $canServer, $httpsMode, 443,
+                                                       "Test non-expandable relative URLs (defaultProto: $protoDesc, "
+                                                               . "wgServer: $server, wgCanonicalServer: $canServer, "
+                                                               . "current request protocol: $mode )"
+                                               ];
+
+                                               // Determine expected protocol
+                                               if ( $protoDesc == 'protocol-relative' ) {
+                                                       $p = '';
+                                               } elseif ( $protoDesc == 'current' ) {
+                                                       $p = "$mode:";
+                                               } elseif ( $protoDesc == 'canonical' ) {
+                                                       $p = "$canServerMode:";
+                                               } else {
+                                                       $p = $protoDesc . ':';
+                                               }
+                                               // Determine expected server name
+                                               if ( $protoDesc == 'canonical' ) {
+                                                       $srv = $canServer;
+                                               } elseif ( $serverDesc == 'protocol-relative' ) {
+                                                       $srv = $p . $server;
+                                               } else {
+                                                       $srv = $server;
+                                               }
+
+                                               $retval[] = [
+                                                       "$p//wikipedia.org", '//wikipedia.org',
+                                                       $defaultProto, $server, $canServer, $httpsMode, 443,
+                                                       "Test protocol-relative URL (defaultProto: $protoDesc, "
+                                                               . "wgServer: $server, wgCanonicalServer: $canServer, "
+                                                               . "current request protocol: $mode )"
+                                               ];
+                                               $retval[] = [
+                                                       "$srv/wiki/FooBar",
+                                                       '/wiki/FooBar',
+                                                       $defaultProto,
+                                                       $server,
+                                                       $canServer,
+                                                       $httpsMode,
+                                                       443,
+                                                       "Testing expanding URL beginning with / (defaultProto: $protoDesc, "
+                                                               . "wgServer: $server, wgCanonicalServer: $canServer, "
+                                                               . "current request protocol: $mode )"
+                                               ];
+                                       }
+                               }
+                       }
+               }
+
+               // Don't add HTTPS port to foreign URLs
+               $retval[] = [
+                       'https://foreign.example.com/foo',
+                       'https://foreign.example.com/foo',
+                       PROTO_HTTPS,
+                       '//wiki.example.com',
+                       'http://wiki.example.com',
+                       'https',
+                       111,
+                       "Don't add HTTPS port to foreign URLs"
+               ];
+               $retval[] = [
+                       'https://foreign.example.com:222/foo',
+                       'https://foreign.example.com:222/foo',
+                       PROTO_HTTPS,
+                       '//wiki.example.com',
+                       'http://wiki.example.com',
+                       'https',
+                       111,
+                       "Don't overwrite HTTPS port of foreign URLs"
+               ];
+               // Do add HTTPS port to local URLs
+               $retval[] = [
+                       'https://wiki.example.com:111/foo',
+                       '/foo',
+                       PROTO_HTTPS,
+                       '//wiki.example.com',
+                       'http://wiki.example.com',
+                       'https',
+                       111,
+                       "Do add HTTPS port to protocol-relative URLs"
+               ];
+
+               return $retval;
+       }
+}
index 1011a37..bc930be 100644 (file)
@@ -5,8 +5,9 @@
  * @covers ::wfArrayFilter
  * @covers ::wfArrayFilterByKey
  */
-class WfArrayFilterTest extends \PHPUnit\Framework\TestCase {
+class WfArrayFilterTest extends MediaWikiTestCase {
        public function testWfArrayFilter() {
+               $this->hideDeprecated( 'wfArrayFilter' );
                $arr = [ 'a' => 1, 'b' => 2, 'c' => 3 ];
                $filtered = wfArrayFilter( $arr, function ( $val, $key ) {
                        return $key !== 'b';
@@ -27,6 +28,7 @@ class WfArrayFilterTest extends \PHPUnit\Framework\TestCase {
        }
 
        public function testWfArrayFilterByKey() {
+               $this->hideDeprecated( 'wfArrayFilterByKey' );
                $arr = [ 'a' => 1, 'b' => 2, 'c' => 3 ];
                $filtered = wfArrayFilterByKey( $arr, function ( $key ) {
                        return $key !== 'b';
diff --git a/tests/phpunit/includes/GlobalFunctions/wfExpandUrlTest.php b/tests/phpunit/includes/GlobalFunctions/wfExpandUrlTest.php
deleted file mode 100644 (file)
index 1cd320f..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-<?php
-/**
- * @group GlobalFunctions
- * @covers ::wfExpandUrl
- */
-class WfExpandUrlTest extends MediaWikiTestCase {
-       /**
-        * @dataProvider provideExpandableUrls
-        */
-       public function testWfExpandUrl( $fullUrl, $shortUrl, $defaultProto,
-               $server, $canServer, $httpsMode, $message
-       ) {
-               // Fake $wgServer, $wgCanonicalServer and $wgRequest->getProtocol()
-               $this->setMwGlobals( [
-                       'wgServer' => $server,
-                       'wgCanonicalServer' => $canServer,
-                       'wgRequest' => new FauxRequest( [], false, null, $httpsMode ? 'https' : 'http' )
-               ] );
-
-               $this->assertEquals( $fullUrl, wfExpandUrl( $shortUrl, $defaultProto ), $message );
-       }
-
-       /**
-        * Provider of URL examples for testing wfExpandUrl()
-        *
-        * @return array
-        */
-       public static function provideExpandableUrls() {
-               $modes = [ 'http', 'https' ];
-               $servers = [
-                       'http' => 'http://example.com',
-                       'https' => 'https://example.com',
-                       'protocol-relative' => '//example.com'
-               ];
-               $defaultProtos = [
-                       'http' => PROTO_HTTP,
-                       'https' => PROTO_HTTPS,
-                       'protocol-relative' => PROTO_RELATIVE,
-                       'current' => PROTO_CURRENT,
-                       'canonical' => PROTO_CANONICAL
-               ];
-
-               $retval = [];
-               foreach ( $modes as $mode ) {
-                       $httpsMode = $mode == 'https';
-                       foreach ( $servers as $serverDesc => $server ) {
-                               foreach ( $modes as $canServerMode ) {
-                                       $canServer = "$canServerMode://example2.com";
-                                       foreach ( $defaultProtos as $protoDesc => $defaultProto ) {
-                                               $retval[] = [
-                                                       'http://example.com', 'http://example.com',
-                                                       $defaultProto, $server, $canServer, $httpsMode,
-                                                       "Testing fully qualified http URLs (no need to expand) "
-                                                               . "(defaultProto: $protoDesc , wgServer: $server, "
-                                                               . "wgCanonicalServer: $canServer, current request protocol: $mode )"
-                                               ];
-                                               $retval[] = [
-                                                       'https://example.com', 'https://example.com',
-                                                       $defaultProto, $server, $canServer, $httpsMode,
-                                                       "Testing fully qualified https URLs (no need to expand) "
-                                                               . "(defaultProto: $protoDesc , wgServer: $server, "
-                                                               . "wgCanonicalServer: $canServer, current request protocol: $mode )"
-                                               ];
-                                               # Would be nice to support this, see fixme on wfExpandUrl()
-                                               $retval[] = [
-                                                       "wiki/FooBar", 'wiki/FooBar',
-                                                       $defaultProto, $server, $canServer, $httpsMode,
-                                                       "Test non-expandable relative URLs (defaultProto: $protoDesc, "
-                                                               . "wgServer: $server, wgCanonicalServer: $canServer, "
-                                                               . "current request protocol: $mode )"
-                                               ];
-
-                                               // Determine expected protocol
-                                               if ( $protoDesc == 'protocol-relative' ) {
-                                                       $p = '';
-                                               } elseif ( $protoDesc == 'current' ) {
-                                                       $p = "$mode:";
-                                               } elseif ( $protoDesc == 'canonical' ) {
-                                                       $p = "$canServerMode:";
-                                               } else {
-                                                       $p = $protoDesc . ':';
-                                               }
-                                               // Determine expected server name
-                                               if ( $protoDesc == 'canonical' ) {
-                                                       $srv = $canServer;
-                                               } elseif ( $serverDesc == 'protocol-relative' ) {
-                                                       $srv = $p . $server;
-                                               } else {
-                                                       $srv = $server;
-                                               }
-
-                                               $retval[] = [
-                                                       "$p//wikipedia.org", '//wikipedia.org',
-                                                       $defaultProto, $server, $canServer, $httpsMode,
-                                                       "Test protocol-relative URL (defaultProto: $protoDesc, "
-                                                               . "wgServer: $server, wgCanonicalServer: $canServer, "
-                                                               . "current request protocol: $mode )"
-                                               ];
-                                               $retval[] = [
-                                                       "$srv/wiki/FooBar",
-                                                       '/wiki/FooBar',
-                                                       $defaultProto,
-                                                       $server,
-                                                       $canServer,
-                                                       $httpsMode,
-                                                       "Testing expanding URL beginning with / (defaultProto: $protoDesc, "
-                                                               . "wgServer: $server, wgCanonicalServer: $canServer, "
-                                                               . "current request protocol: $mode )"
-                                               ];
-                                       }
-                               }
-                       }
-               }
-
-               return $retval;
-       }
-}
index 09c1040..5d9f63d 100644 (file)
@@ -33,9 +33,7 @@ class WfUrlencodeTest extends MediaWikiTestCase {
                $expected = $this->extractExpect( $server, $expectations );
 
                // save up global
-               $old = isset( $_SERVER['SERVER_SOFTWARE'] )
-                       ? $_SERVER['SERVER_SOFTWARE']
-                       : null;
+               $old = $_SERVER['SERVER_SOFTWARE'] ?? null;
                $_SERVER['SERVER_SOFTWARE'] = $server;
                wfUrlencode( null );
 
index efe92ec..c1efc7f 100644 (file)
@@ -33,6 +33,12 @@ class HooksTest extends MediaWikiTestCase {
                                'changed-static',
                                'original'
                        ],
+                       [
+                               'Class::method static call as array',
+                               [ [ 'NothingClass::someStatic' ] ],
+                               'changed-static',
+                               'original'
+                       ],
                        [ 'Global function', [ 'NothingFunction' ], 'changed-func', 'original' ],
                        [ 'Global function with data', [ 'NothingFunctionData', 'data' ], 'data', 'original' ],
                        [ 'Closure', [ function ( &$foo, $bar ) {
@@ -81,10 +87,50 @@ class HooksTest extends MediaWikiTestCase {
                $this->assertSame( $expectedBar, $bar, $msg );
        }
 
+       /**
+        * @covers Hooks::getHandlers
+        */
+       public function testGetHandlers() {
+               global $wgHooks;
+
+               $this->assertSame(
+                       [],
+                       Hooks::getHandlers( 'MediaWikiHooksTest001' ),
+                       'No hooks registered'
+               );
+
+               $a = new NothingClass();
+               $b = new NothingClass();
+
+               $wgHooks['MediaWikiHooksTest001'][] = $a;
+
+               $this->assertSame(
+                       [ $a ],
+                       Hooks::getHandlers( 'MediaWikiHooksTest001' ),
+                       'Hook registered by $wgHooks'
+               );
+
+               Hooks::register( 'MediaWikiHooksTest001', $b );
+               $this->assertSame(
+                       [ $b, $a ],
+                       Hooks::getHandlers( 'MediaWikiHooksTest001' ),
+                       'Hooks::getHandlers() should return hooks registered via wgHooks as well as Hooks::register'
+               );
+
+               Hooks::clear( 'MediaWikiHooksTest001' );
+               unset( $wgHooks['MediaWikiHooksTest001'] );
+
+               Hooks::register( 'MediaWikiHooksTest001', $b );
+               $this->assertSame(
+                       [ $b ],
+                       Hooks::getHandlers( 'MediaWikiHooksTest001' ),
+                       'Hook registered by Hook::register'
+               );
+       }
+
        /**
         * @covers Hooks::isRegistered
         * @covers Hooks::register
-        * @covers Hooks::getHandlers
         * @covers Hooks::run
         * @covers Hooks::callHook
         */
@@ -151,6 +197,56 @@ class HooksTest extends MediaWikiTestCase {
                $this->assertSame( 'original', $foo, 'Hooks abort after a false return.' );
        }
 
+       /**
+        * @covers Hooks::run
+        */
+       public function testNullReturn() {
+               Hooks::register( 'MediaWikiHooksTest001', function ( &$foo ) {
+                       return;
+               } );
+               Hooks::register( 'MediaWikiHooksTest001', function ( &$foo ) {
+                       $foo = 'test';
+
+                       return true;
+               } );
+               $foo = 'original';
+               Hooks::run( 'MediaWikiHooksTest001', [ &$foo ] );
+               $this->assertSame( 'test', $foo, 'Hooks continue after a null return.' );
+       }
+
+       /**
+        * @covers Hooks::callHook
+        */
+       public function testCallHook_FalseHook() {
+               Hooks::register( 'MediaWikiHooksTest001', false );
+               Hooks::register( 'MediaWikiHooksTest001', function ( &$foo ) {
+                       $foo = 'test';
+
+                       return true;
+               } );
+               $foo = 'original';
+               Hooks::run( 'MediaWikiHooksTest001', [ &$foo ] );
+               $this->assertSame( 'test', $foo, 'Hooks that are falsey are skipped.' );
+       }
+
+       /**
+        * @covers Hooks::callHook
+        * @expectedException MWException
+        */
+       public function testCallHook_UnknownDatatype() {
+               Hooks::register( 'MediaWikiHooksTest001', 12345 );
+               Hooks::run( 'MediaWikiHooksTest001' );
+       }
+
+       /**
+        * @covers Hooks::callHook
+        * @expectedException PHPUnit_Framework_Error_Deprecated
+        */
+       public function testCallHook_Deprecated() {
+               Hooks::register( 'MediaWikiHooksTest001', 'NothingClass::someStatic' );
+               Hooks::run( 'MediaWikiHooksTest001', [], '1.31' );
+       }
+
        /**
         * @covers Hooks::runWithoutAbort
         * @covers Hooks::callHook
index 6695fce..3c8fa25 100644 (file)
@@ -331,7 +331,7 @@ class HtmlTest extends MediaWikiTestCase {
                );
 
                $this->assertEquals(
-                       '<label for="mw-test-namespace">Select a namespace:</label>&#160;' .
+                       '<label for="mw-test-namespace">Select a namespace:</label>' . "\u{00A0}" .
                                '<select id="mw-test-namespace" name="wpNamespace">' . "\n" .
                                '<option value="all">all</option>' . "\n" .
                                '<option value="0">(Main)</option>' . "\n" .
@@ -359,7 +359,7 @@ class HtmlTest extends MediaWikiTestCase {
                );
 
                $this->assertEquals(
-                       '<label for="namespace">Select a namespace:</label>&#160;' .
+                       '<label for="namespace">Select a namespace:</label>' . "\u{00A0}" .
                                '<select id="namespace" name="namespace">' . "\n" .
                                '<option value="0">(Main)</option>' . "\n" .
                                '<option value="1">Talk</option>' . "\n" .
@@ -676,7 +676,7 @@ class HtmlTest extends MediaWikiTestCase {
                        $ret[] = [
                                $case[0],
                                $case[1], $case[2],
-                               isset( $case[3] ) ? $case[3] : ''
+                               $case[3] ?? ''
                        ];
                }
 
index f9e2cc1..4c508e3 100644 (file)
@@ -1,6 +1,5 @@
 <?php
 
-use MediaWiki\MediaWikiServices;
 
 /**
  * @group Database
@@ -370,6 +369,7 @@ class LinkerTest extends MediaWikiLangTestCase {
         * @dataProvider provideLinkBeginHook
         */
        public function testLinkBeginHook( $callback, $expected ) {
+               $this->hideDeprecated( 'LinkBegin hook (used in hook-LinkBegin-closure)' );
                $this->setMwGlobals( [
                        'wgArticlePath' => '/wiki/$1',
                        'wgServer' => '//example.org',
@@ -417,6 +417,7 @@ class LinkerTest extends MediaWikiLangTestCase {
         * @dataProvider provideLinkEndHook
         */
        public function testLinkEndHook( $callback, $expected ) {
+               $this->hideDeprecated( 'LinkEnd hook (used in hook-LinkEnd-closure)' );
                $this->setMwGlobals( [
                        'wgArticlePath' => '/wiki/$1',
                ] );
@@ -427,54 +428,4 @@ class LinkerTest extends MediaWikiLangTestCase {
                $out = Linker::link( $title );
                $this->assertEquals( $expected, $out );
        }
-
-       /**
-        * @covers Linker::getLinkColour
-        */
-       public function testGetLinkColour() {
-               $this->hideDeprecated( 'Linker::getLinkColour' );
-               $linkCache = MediaWikiServices::getInstance()->getLinkCache();
-               $foobarTitle = Title::makeTitle( NS_MAIN, 'FooBar' );
-               $redirectTitle = Title::makeTitle( NS_MAIN, 'Redirect' );
-               $userTitle = Title::makeTitle( NS_USER, 'Someuser' );
-               $linkCache->addGoodLinkObj(
-                       1, // id
-                       $foobarTitle,
-                       10, // len
-                       0 // redir
-               );
-               $linkCache->addGoodLinkObj(
-                       2, // id
-                       $redirectTitle,
-                       10, // len
-                       1 // redir
-               );
-
-               $linkCache->addGoodLinkObj(
-                       3, // id
-                       $userTitle,
-                       10, // len
-                       0 // redir
-               );
-
-               $this->assertEquals(
-                       '',
-                       Linker::getLinkColour( $foobarTitle, 0 )
-               );
-
-               $this->assertEquals(
-                       'stub',
-                       Linker::getLinkColour( $foobarTitle, 20 )
-               );
-
-               $this->assertEquals(
-                       'mw-redirect',
-                       Linker::getLinkColour( $redirectTitle, 0 )
-               );
-
-               $this->assertEquals(
-                       '',
-                       Linker::getLinkColour( $userTitle, 20 )
-               );
-       }
 }
index 15e2def..1b91a87 100644 (file)
@@ -575,4 +575,34 @@ class MWNamespaceTest extends MediaWikiTestCase {
        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 03588ae..4189e93 100644 (file)
@@ -5,12 +5,15 @@ use MediaWiki\Interwiki\InterwikiLookup;
 use MediaWiki\Linker\LinkRenderer;
 use MediaWiki\Linker\LinkRendererFactory;
 use MediaWiki\MediaWikiServices;
+use MediaWiki\Preferences\PreferencesFactory;
 use MediaWiki\Services\DestructibleService;
 use MediaWiki\Services\SalvageableService;
 use MediaWiki\Services\ServiceDisabledException;
 use MediaWiki\Shell\CommandFactory;
 use MediaWiki\Storage\BlobStore;
 use MediaWiki\Storage\BlobStoreFactory;
+use MediaWiki\Storage\NameTableStore;
+use MediaWiki\Storage\RevisionFactory;
 use MediaWiki\Storage\RevisionLookup;
 use MediaWiki\Storage\RevisionStore;
 use MediaWiki\Storage\SqlBlobStore;
@@ -304,8 +307,6 @@ class MediaWikiServicesTest extends MediaWikiTestCase {
 
        public function provideGetService() {
                // NOTE: This should list all service getters defined in ServiceWiring.php.
-               // NOTE: For every test case defined here there should be a corresponding
-               // test case defined in provideGetters().
                return [
                        'BootstrapConfig' => [ 'BootstrapConfig', Config::class ],
                        'ConfigFactory' => [ 'ConfigFactory', ConfigFactory::class ],
@@ -313,6 +314,8 @@ class MediaWikiServicesTest extends MediaWikiTestCase {
                        'SiteStore' => [ 'SiteStore', SiteStore::class ],
                        'SiteLookup' => [ 'SiteLookup', SiteLookup::class ],
                        'StatsdDataFactory' => [ 'StatsdDataFactory', IBufferingStatsdDataFactory::class ],
+                       'PerDbNameStatsdDataFactory' =>
+                               [ 'PerDbNameStatsdDataFactory', IBufferingStatsdDataFactory::class ],
                        'InterwikiLookup' => [ 'InterwikiLookup', InterwikiLookup::class ],
                        'EventRelayerGroup' => [ 'EventRelayerGroup', EventRelayerGroup::class ],
                        'SearchEngineFactory' => [ 'SearchEngineFactory', SearchEngineFactory::class ],
@@ -346,8 +349,23 @@ class MediaWikiServicesTest extends MediaWikiTestCase {
                        '_SqlBlobStore' => [ '_SqlBlobStore', SqlBlobStore::class ],
                        'RevisionStore' => [ 'RevisionStore', RevisionStore::class ],
                        'RevisionLookup' => [ 'RevisionLookup', RevisionLookup::class ],
+                       'RevisionFactory' => [ 'RevisionFactory', RevisionFactory::class ],
+                       'ContentModelStore' => [ 'ContentModelStore', NameTableStore::class ],
+                       'SlotRoleStore' => [ 'SlotRoleStore', NameTableStore::class ],
                        'HttpRequestFactory' => [ 'HttpRequestFactory', HttpRequestFactory::class ],
                        'CommentStore' => [ 'CommentStore', CommentStore::class ],
+                       'ChangeTagDefStore' => [ 'ChangeTagDefStore', NameTableStore::class ],
+                       'ConfiguredReadOnlyMode' => [ 'ConfiguredReadOnlyMode', ConfiguredReadOnlyMode::class ],
+                       'ReadOnlyMode' => [ 'ReadOnlyMode', ReadOnlyMode::class ],
+                       'UploadRevisionImporter' => [ 'UploadRevisionImporter', UploadRevisionImporter::class ],
+                       'OldRevisionImporter' => [ 'OldRevisionImporter', OldRevisionImporter::class ],
+                       'WikiRevisionOldRevisionImporterNoUpdates' =>
+                               [ 'WikiRevisionOldRevisionImporterNoUpdates', ImportableOldRevisionImporter::class ],
+                       'ExternalStoreFactory' => [ 'ExternalStoreFactory', ExternalStoreFactory::class ],
+                       'PreferencesFactory' => [ 'PreferencesFactory', PreferencesFactory::class ],
+                       'ActorMigration' => [ 'ActorMigration', ActorMigration::class ],
+                       'ConfigRepository' => [ 'ConfigRepository', \MediaWiki\Config\ConfigRepository::class ],
+                       'MagicWordFactory' => [ 'MagicWordFactory', MagicWordFactory::class ],
                ];
        }
 
@@ -376,4 +394,15 @@ class MediaWikiServicesTest extends MediaWikiTestCase {
                }
        }
 
+       public function testDefaultServiceWiringServicesHaveTests() {
+               global $IP;
+               $testedServices = array_keys( $this->provideGetService() );
+               $allServices = array_keys( include $IP . '/includes/ServiceWiring.php' );
+               $this->assertEquals(
+                       [],
+                       array_diff( $allServices, $testedServices ),
+                       'The following services have not been added to MediaWikiServicesTest::provideGetService'
+               );
+       }
+
 }
index a8d1e33..d79d2cf 100644 (file)
@@ -1,6 +1,8 @@
 <?php
 
 class MediaWikiTest extends MediaWikiTestCase {
+       private $oldServer, $oldGet, $oldPost;
+
        protected function setUp() {
                parent::setUp();
 
@@ -11,6 +13,18 @@ class MediaWikiTest extends MediaWikiTestCase {
                        'wgArticlePath' => '/wiki/$1',
                        'wgActionPaths' => [],
                ] );
+
+               // phpcs:disable MediaWiki.Usage.SuperGlobalsUsage.SuperGlobals
+               $this->oldServer = $_SERVER;
+               $this->oldGet = $_GET;
+               $this->oldPost = $_POST;
+       }
+
+       protected function tearDown() {
+               parent::tearDown();
+               $_SERVER = $this->oldServer;
+               $_GET = $this->oldGet;
+               $_POST = $this->oldPost;
        }
 
        public static function provideTryNormaliseRedirect() {
@@ -113,6 +127,13 @@ class MediaWikiTest extends MediaWikiTestCase {
                                'title' => 'Foo_Bar',
                                'redirect' => false,
                        ],
+                       [
+                               // Path with double slash prefix (T100782)
+                               'url' => 'http://example.org//wiki/Double_slash',
+                               'query' => [],
+                               'title' => 'Double_slash',
+                               'redirect' => false,
+                       ],
                ];
        }
 
@@ -122,11 +143,13 @@ class MediaWikiTest extends MediaWikiTestCase {
         */
        public function testTryNormaliseRedirect( $url, $query, $title, $expectedRedirect = false ) {
                // Set SERVER because interpolateTitle() doesn't use getRequestURL(),
-               // whereas tryNormaliseRedirect does().
+               // whereas tryNormaliseRedirect does(). Also, using WebRequest allows
+               // us to test some quirks in that class.
                $_SERVER['REQUEST_URI'] = $url;
+               $_POST = [];
+               $_GET = $query;
+               $req = new WebRequest;
 
-               $req = new FauxRequest( $query );
-               $req->setRequestURL( $url );
                // This adds a virtual 'title' query parameter. Normally called from Setup.php
                $req->interpolateTitle();
 
@@ -154,4 +177,53 @@ class MediaWikiTest extends MediaWikiTestCase {
                        $context->getOutput()->getRedirect()
                );
        }
+
+       /**
+        * Test a post-send job can not set cookies (T191537).
+        */
+       public function testPostSendJobDoesNotSetCookie() {
+               // Prevent updates from running
+               $this->setMwGlobals( 'wgCommandLineMode', false );
+
+               $response = new WebResponse;
+
+               // A job that attempts to set a cookie
+               $jobHasRun = false;
+               DeferredUpdates::addCallableUpdate( function () use ( $response, &$jobHasRun ) {
+                       $jobHasRun = true;
+                       $response->setCookie( 'JobCookie', 'yes' );
+                       $response->header( 'Foo: baz' );
+               } );
+
+               $hookWasRun = false;
+               $this->setTemporaryHook( 'WebResponseSetCookie', function () use ( &$hookWasRun ) {
+                       $hookWasRun = true;
+                       return true;
+               } );
+
+               $logger = new TestLogger();
+               $logger->setCollect( true );
+               $this->setLogger( 'cookie', $logger );
+               $this->setLogger( 'header', $logger );
+
+               $mw = new MediaWiki();
+               $mw->doPostOutputShutdown();
+               // restInPeace() might have been registered to a callback of
+               // register_postsend_function() and thus can not be triggered from
+               // PHPUnit.
+               if ( $jobHasRun === false ) {
+                       $mw->restInPeace();
+               }
+
+               $this->assertTrue( $jobHasRun, 'post-send job has run' );
+               $this->assertFalse( $hookWasRun,
+                       'post-send job must not trigger WebResponseSetCookie hook' );
+               $this->assertEquals(
+                       [
+                               [ 'info', 'ignored post-send cookie {cookie}' ],
+                               [ 'info', 'ignored post-send header {header}' ],
+                       ],
+                       $logger->getBuffer()
+               );
+       }
 }
diff --git a/tests/phpunit/includes/MultiHttpClientTest.php b/tests/phpunit/includes/MultiHttpClientTest.php
new file mode 100644 (file)
index 0000000..7073b71
--- /dev/null
@@ -0,0 +1,168 @@
+<?php
+
+/**
+ * Tests for MultiHttpClient
+ *
+ * The urls herein are not actually called, because we mock the return results.
+ *
+ * @covers MultiHttpClient
+ */
+class MultiHttpClientTest extends MediaWikiTestCase {
+       protected $client;
+
+       protected function setUp() {
+               parent::setUp();
+               $client = $this->getMockBuilder( MultiHttpClient::class )
+                       ->setConstructorArgs( [ [] ] )
+                       ->setMethods( [ 'isCurlEnabled' ] )->getMock();
+               $client->method( 'isCurlEnabled' )->willReturn( false );
+               $this->client = $client;
+       }
+
+       private function getHttpRequest( $statusValue, $statusCode, $headers = [] ) {
+               $httpRequest = $this->getMockBuilder( PhpHttpRequest::class )
+                       ->setConstructorArgs( [ '', [] ] )
+                       ->getMock();
+               $httpRequest->expects( $this->any() )
+                       ->method( 'execute' )
+                       ->willReturn( Status::wrap( $statusValue ) );
+               $httpRequest->expects( $this->any() )
+                       ->method( 'getResponseHeaders' )
+                       ->willReturn( $headers );
+               $httpRequest->expects( $this->any() )
+                               ->method( 'getStatus' )
+                               ->willReturn( $statusCode );
+               return $httpRequest;
+       }
+
+       private function mockHttpRequestFactory( $httpRequest ) {
+               $factory = $this->getMockBuilder( MediaWiki\Http\HttpRequestFactory::class )
+                       ->getMock();
+               $factory->expects( $this->any() )
+                       ->method( 'create' )
+                       ->willReturn( $httpRequest );
+               return $factory;
+       }
+
+       /**
+        * Test call of a single url that should succeed
+        */
+       public function testMultiHttpClientSingleSuccess() {
+               // Mock success
+               $httpRequest = $this->getHttpRequest( StatusValue::newGood( 200 ), 200 );
+               $this->setService( 'HttpRequestFactory', $this->mockHttpRequestFactory( $httpRequest ) );
+
+               list( $rcode, $rdesc, /* $rhdrs */, $rbody, $rerr ) = $this->client->run( [
+                       'method' => 'GET',
+                       'url' => "http://example.test",
+               ] );
+
+               $this->assertEquals( 200, $rcode );
+       }
+
+       /**
+        * Test call of a single url that should not exist, and therefore fail
+        */
+       public function testMultiHttpClientSingleFailure() {
+               // Mock an invalid tld
+               $httpRequest = $this->getHttpRequest(
+                       StatusValue::newFatal( 'http-invalid-url', 'http://www.example.test' ), 0 );
+               $this->setService( 'HttpRequestFactory', $this->mockHttpRequestFactory( $httpRequest ) );
+
+               list( $rcode, $rdesc, /* $rhdrs */, $rbody, $rerr ) = $this->client->run( [
+                       'method' => 'GET',
+                       'url' => "http://www.example.test",
+               ] );
+
+               $failure = $rcode < 200 || $rcode >= 400;
+               $this->assertTrue( $failure );
+       }
+
+       /**
+        * Test call of multiple urls that should all succeed
+        */
+       public function testMultiHttpClientMultipleSuccess() {
+               // Mock success
+               $httpRequest = $this->getHttpRequest( StatusValue::newGood( 200 ), 200 );
+               $this->setService( 'HttpRequestFactory', $this->mockHttpRequestFactory( $httpRequest ) );
+
+               $reqs = [
+                       [
+                               'method' => 'GET',
+                               'url' => 'http://example.test',
+                       ],
+                       [
+                               'method' => 'GET',
+                               'url' => 'https://get.test',
+                       ],
+               ];
+               $responses = $this->client->runMulti( $reqs );
+               foreach ( $responses as $response ) {
+                       list( $rcode, $rdesc, /* $rhdrs */, $rbody, $rerr ) = $response['response'];
+                       $this->assertEquals( 200, $rcode );
+               }
+       }
+
+       /**
+        * Test call of multiple urls that should all fail
+        */
+       public function testMultiHttpClientMultipleFailure() {
+               // Mock page not found
+               $httpRequest = $this->getHttpRequest(
+                       StatusValue::newFatal( "http-bad-status", 404, 'Not Found' ), 404 );
+               $this->setService( 'HttpRequestFactory', $this->mockHttpRequestFactory( $httpRequest ) );
+
+               $reqs = [
+                       [
+                               'method' => 'GET',
+                               'url' => 'http://example.test/12345',
+                       ],
+                       [
+                               'method' => 'GET',
+                               'url' => 'http://example.test/67890' ,
+                       ]
+               ];
+               $responses = $this->client->runMulti( $reqs );
+               foreach ( $responses as $response ) {
+                       list( $rcode, $rdesc, /* $rhdrs */, $rbody, $rerr ) = $response['response'];
+                       $failure = $rcode < 200 || $rcode >= 400;
+                       $this->assertTrue( $failure );
+               }
+       }
+
+       /**
+        * Test of response header handling
+        */
+       public function testMultiHttpClientHeaders() {
+               // Represenative headers for typical requests, per MWHttpRequest::getResponseHeaders()
+               $headers = [
+                       'content-type' => [
+                               'text/html; charset=utf-8',
+                       ],
+                       'date' => [
+                               'Wed, 18 Jul 2018 14:52:41 GMT',
+                       ],
+                       'set-cookie' => [
+                               'COUNTRY=NAe6; expires=Wed, 25-Jul-2018 14:52:41 GMT; path=/; domain=.example.test',
+                               'LAST_NEWS=1531925562; expires=Thu, 18-Jul-2019 14:52:41 GMT; path=/; domain=.example.test',
+                       ]
+               ];
+
+               // Mock success with specific headers
+               $httpRequest = $this->getHttpRequest( StatusValue::newGood( 200 ), 200, $headers );
+               $this->setService( 'HttpRequestFactory', $this->mockHttpRequestFactory( $httpRequest ) );
+
+               list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $this->client->run( [
+                       'method' => 'GET',
+                       'url' => 'http://example.test',
+               ] );
+
+               $this->assertEquals( 200, $rcode );
+               $this->assertEquals( count( $headers ), count( $rhdrs ) );
+               foreach ( $headers as $name => $values ) {
+                       $value = implode( ', ', $values );
+                       $this->assertArrayHasKey( $name, $rhdrs );
+                       $this->assertEquals( $value, $rhdrs[$name] );
+               }
+       }
+}
index 73447c9..efd61a7 100644 (file)
@@ -3,29 +3,71 @@
 use Wikimedia\TestingAccessWrapper;
 
 /**
- *
  * @author Matthew Flaschen
  *
  * @group Database
  * @group Output
- *
- * @todo factor tests in this class into providers and test methods
  */
 class OutputPageTest extends MediaWikiTestCase {
        const SCREEN_MEDIA_QUERY = 'screen and (min-width: 982px)';
        const SCREEN_ONLY_MEDIA_QUERY = 'only screen and (min-width: 982px)';
 
+       /**
+        * @dataProvider provideRedirect
+        *
+        * @covers OutputPage::__construct
+        * @covers OutputPage::redirect
+        * @covers OutputPage::getRedirect
+        */
+       public function testRedirect( $url, $code = null ) {
+               $op = $this->newInstance();
+               if ( isset( $code ) ) {
+                       $op->redirect( $url, $code );
+               } else {
+                       $op->redirect( $url );
+               }
+               $expectedUrl = str_replace( "\n", '', $url );
+               $this->assertSame( $expectedUrl, $op->getRedirect() );
+               $this->assertSame( $expectedUrl, $op->mRedirect );
+               $this->assertSame( $code ?? '302', $op->mRedirectCode );
+       }
+
+       public function provideRedirect() {
+               return [
+                       [ 'http://example.com' ],
+                       [ 'http://example.com', '400' ],
+                       [ 'http://example.com', 'squirrels!!!' ],
+                       [ "a\nb" ],
+               ];
+       }
+
+       /**
+        * @covers OutputPage::setCopyrightUrl
+        * @covers OutputPage::getHeadLinksArray
+        */
+       public function testSetCopyrightUrl() {
+               $op = $this->newInstance();
+               $op->setCopyrightUrl( 'http://example.com' );
+
+               $this->assertSame(
+                       Html::element( 'link', [ 'rel' => 'license', 'href' => 'http://example.com' ] ),
+                       $op->getHeadLinksArray()['copyright']
+               );
+       }
+
+       // @todo How to test setStatusCode?
+
        /**
         * @covers OutputPage::addMeta
         * @covers OutputPage::getMetaTags
         * @covers OutputPage::getHeadLinksArray
         */
        public function testMetaTags() {
-               $outputPage = $this->newInstance();
-               $outputPage->addMeta( 'http:expires', '0' );
-               $outputPage->addMeta( 'keywords', 'first' );
-               $outputPage->addMeta( 'keywords', 'second' );
-               $outputPage->addMeta( 'og:title', 'Ta-duh' );
+               $op = $this->newInstance();
+               $op->addMeta( 'http:expires', '0' );
+               $op->addMeta( 'keywords', 'first' );
+               $op->addMeta( 'keywords', 'second' );
+               $op->addMeta( 'og:title', 'Ta-duh' );
 
                $expected = [
                        [ 'http:expires', '0' ],
@@ -33,9 +75,9 @@ class OutputPageTest extends MediaWikiTestCase {
                        [ 'keywords', 'second' ],
                        [ 'og:title', 'Ta-duh' ],
                ];
-               $this->assertSame( $expected, $outputPage->getMetaTags() );
+               $this->assertSame( $expected, $op->getMetaTags() );
 
-               $links = $outputPage->getHeadLinksArray();
+               $links = $op->getHeadLinksArray();
                $this->assertContains( '<meta http-equiv="expires" content="0"/>', $links );
                $this->assertContains( '<meta name="keywords" content="first"/>', $links );
                $this->assertContains( '<meta name="keywords" content="second"/>', $links );
@@ -44,84 +86,317 @@ class OutputPageTest extends MediaWikiTestCase {
        }
 
        /**
-        * @covers OutputPage::setIndexPolicy
-        * @covers OutputPage::setFollowPolicy
+        * @covers OutputPage::addLink
+        * @covers OutputPage::getLinkTags
         * @covers OutputPage::getHeadLinksArray
         */
-       public function testRobotsPolicies() {
-               $outputPage = $this->newInstance();
-               $outputPage->setIndexPolicy( 'noindex' );
-               $outputPage->setFollowPolicy( 'nofollow' );
+       public function testAddLink() {
+               $op = $this->newInstance();
 
-               $links = $outputPage->getHeadLinksArray();
-               $this->assertContains( '<meta name="robots" content="noindex,nofollow"/>', $links );
+               $links = [
+                       [],
+                       [ 'rel' => 'foo', 'href' => 'http://example.com' ],
+               ];
+
+               foreach ( $links as $link ) {
+                       $op->addLink( $link );
+               }
+
+               $this->assertSame( $links, $op->getLinkTags() );
+
+               $result = $op->getHeadLinksArray();
+
+               foreach ( $links as $link ) {
+                       $this->assertContains( Html::element( 'link', $link ), $result );
+               }
        }
 
        /**
-        * Tests a particular case of transformCssMedia, using the given input, globals,
-        * expected return, and message
+        * @covers OutputPage::setCanonicalUrl
+        * @covers OutputPage::getCanonicalUrl
+        * @covers OutputPage::getHeadLinksArray
+        */
+       public function testSetCanonicalUrl() {
+               $op = $this->newInstance();
+               $op->setCanonicalUrl( 'http://example.comm' );
+               $op->setCanonicalUrl( 'http://example.com' );
+
+               $this->assertSame( 'http://example.com', $op->getCanonicalUrl() );
+
+               $headLinks = $op->getHeadLinksArray();
+
+               $this->assertContains( Html::element( 'link', [
+                       'rel' => 'canonical', 'href' => 'http://example.com'
+               ] ), $headLinks );
+
+               $this->assertNotContains( Html::element( 'link', [
+                       'rel' => 'canonical', 'href' => 'http://example.comm'
+               ] ), $headLinks );
+       }
+
+       /**
+        * @covers OutputPage::addScript
+        */
+       public function testAddScript() {
+               $op = $this->newInstance();
+               $op->addScript( 'some random string' );
+
+               $this->assertContains( "\nsome random string\n", "\n" . $op->getBottomScripts() . "\n" );
+       }
+
+       /**
+        * @covers OutputPage::addScriptFile
+        */
+       public function testAddScriptFile() {
+               $op = $this->newInstance();
+               $op->addScriptFile( '/somescript.js' );
+               $op->addScriptFile( '//example.com/somescript.js' );
+
+               $this->assertContains(
+                       "\n" . Html::linkedScript( '/somescript.js', $op->getCSPNonce() ) .
+                               Html::linkedScript( '//example.com/somescript.js', $op->getCSPNonce() ) . "\n",
+                       "\n" . $op->getBottomScripts() . "\n"
+               );
+       }
+
+       /**
+        * Test that addScriptFile() throws due to deprecation.
         *
-        * Asserts that $expectedReturn is returned.
+        * @covers OutputPage::addScriptFile
+        */
+       public function testAddDeprecatedScriptFileWarning() {
+               $this->setExpectedException( PHPUnit_Framework_Error_Deprecated::class,
+                       'Use of OutputPage::addScriptFile was deprecated in MediaWiki 1.24.' );
+
+               $op = $this->newInstance();
+               $op->addScriptFile( 'ignored-script.js' );
+       }
+
+       /**
+        * Test the actual behavior of the method (in the case where it doesn't throw, e.g., in
+        * production).  Since it threw an exception once in this file, it won't when we call it again.
         *
-        * options['printableQuery'] - value of query string for printable, or omitted for none
-        * options['handheldQuery'] - value of query string for handheld, or omitted for none
-        * options['media'] - passed into the method under the same name
-        * options['expectedReturn'] - expected return value
-        * options['message'] - PHPUnit message for assertion
+        * @covers OutputPage::addScriptFile
+        */
+       public function testAddDeprecatedScriptFileNoOp() {
+               $op = $this->newInstance();
+               $op->addScriptFile( 'ignored-script.js' );
+
+               $this->assertNotContains( 'ignored-script.js', '' . $op->getBottomScripts() );
+       }
+
+       /**
+        * @covers OutputPage::addInlineScript
+        */
+       public function testAddInlineScript() {
+               $op = $this->newInstance();
+               $op->addInlineScript( 'let foo = "bar";' );
+               $op->addInlineScript( 'alert( foo );' );
+
+               $this->assertContains(
+                       "\n" . Html::inlineScript( "\nlet foo = \"bar\";\n", $op->getCSPNonce() ) . "\n" .
+                               Html::inlineScript( "\nalert( foo );\n", $op->getCSPNonce() ) . "\n",
+                       "\n" . $op->getBottomScripts() . "\n"
+               );
+       }
+
+       // @todo How to test filterModules(), warnModuleTargetFilter(), getModules(), etc.?
+
+       /**
+        * @covers OutputPage::getTarget
+        * @covers OutputPage::setTarget
+        */
+       public function testSetTarget() {
+               $op = $this->newInstance();
+               $op->setTarget( 'foo' );
+
+               $this->assertSame( 'foo', $op->getTarget() );
+               // @todo What else?  Test some actual effect?
+       }
+
+       // @todo How to test addContentOverride(Callback)?
+
+       /**
+        * @covers OutputPage::getHeadItemsArray
+        * @covers OutputPage::addHeadItem
+        * @covers OutputPage::addHeadItems
+        * @covers OutputPage::hasHeadItem
+        */
+       public function testHeadItems() {
+               $op = $this->newInstance();
+               $op->addHeadItem( 'a', 'b' );
+               $op->addHeadItems( [ 'c' => '<d>&amp;', 'e' => 'f', 'a' => 'q' ] );
+               $op->addHeadItem( 'e', 'g' );
+               $op->addHeadItems( 'x' );
+
+               $this->assertSame( [ 'a' => 'q', 'c' => '<d>&amp;', 'e' => 'g', 'x' ],
+                       $op->getHeadItemsArray() );
+
+               $this->assertTrue( $op->hasHeadItem( 'a' ) );
+               $this->assertTrue( $op->hasHeadItem( 'c' ) );
+               $this->assertTrue( $op->hasHeadItem( 'e' ) );
+               $this->assertTrue( $op->hasHeadItem( '0' ) );
+
+               $this->assertContains( "\nq\n<d>&amp;\ng\nx\n",
+                       '' . $op->headElement( $op->getContext()->getSkin() ) );
+       }
+
+       /**
+        * @covers OutputPage::addBodyClasses
+        */
+       public function testAddBodyClasses() {
+               $op = $this->newInstance();
+               $op->addBodyClasses( 'a' );
+               $op->addBodyClasses( 'mediawiki' );
+               $op->addBodyClasses( 'b c' );
+               $op->addBodyClasses( [ 'd', 'e' ] );
+               $op->addBodyClasses( 'a' );
+
+               $this->assertContains( '"a mediawiki b c d e ltr',
+                       '' . $op->headElement( $op->getContext()->getSkin() ) );
+       }
+
+       /**
+        * @covers OutputPage::setArticleBodyOnly
+        * @covers OutputPage::getArticleBodyOnly
+        */
+       public function testArticleBodyOnly() {
+               $op = $this->newInstance();
+               $this->assertFalse( $op->getArticleBodyOnly() );
+
+               $op->setArticleBodyOnly( true );
+               $this->assertTrue( $op->getArticleBodyOnly() );
+
+               $op->addHTML( '<b>a</b>' );
+
+               $this->assertSame( '<b>a</b>', $op->output( true ) );
+       }
+
+       /**
+        * @covers OutputPage::setProperty
+        * @covers OutputPage::getProperty
+        */
+       public function testProperties() {
+               $op = $this->newInstance();
+
+               $this->assertNull( $op->getProperty( 'foo' ) );
+
+               $op->setProperty( 'foo', 'bar' );
+               $op->setProperty( 'baz', 'quz' );
+
+               $this->assertSame( 'bar', $op->getProperty( 'foo' ) );
+               $this->assertSame( 'quz', $op->getProperty( 'baz' ) );
+       }
+
+       /**
+        * @dataProvider provideCheckLastModified
         *
-        * @param array $args Key-value array of arguments as shown above
+        * @covers OutputPage::checkLastModified
+        * @covers OutputPage::getCdnCacheEpoch
         */
-       protected function assertTransformCssMediaCase( $args ) {
-               $queryData = [];
-               if ( isset( $args['printableQuery'] ) ) {
-                       $queryData['printable'] = $args['printableQuery'];
+       public function testCheckLastModified(
+               $timestamp, $ifModifiedSince, $expected, $config = [], $callback = null
+       ) {
+               $request = new FauxRequest();
+               if ( $ifModifiedSince ) {
+                       if ( is_numeric( $ifModifiedSince ) ) {
+                               // Unix timestamp
+                               $ifModifiedSince = date( 'D, d M Y H:i:s', $ifModifiedSince ) . ' GMT';
+                       }
+                       $request->setHeader( 'If-Modified-Since', $ifModifiedSince );
                }
 
-               if ( isset( $args['handheldQuery'] ) ) {
-                       $queryData['handheld'] = $args['handheldQuery'];
+               if ( !isset( $config['CacheEpoch'] ) ) {
+                       // Make sure it's not too recent
+                       $config['CacheEpoch'] = '20000101000000';
                }
 
-               $fauxRequest = new FauxRequest( $queryData, false );
-               $this->setMwGlobals( [
-                       'wgRequest' => $fauxRequest,
-               ] );
+               $op = $this->newInstance( $config, $request );
 
-               $actualReturn = OutputPage::transformCssMedia( $args['media'] );
-               $this->assertSame( $args['expectedReturn'], $actualReturn, $args['message'] );
+               if ( $callback ) {
+                       $callback( $op, $this );
+               }
+
+               // Avoid a complaint about not being able to disable compression
+               Wikimedia\suppressWarnings();
+               try {
+                       $this->assertEquals( $expected, $op->checkLastModified( $timestamp ) );
+               } finally {
+                       Wikimedia\restoreWarnings();
+               }
+       }
+
+       public function provideCheckLastModified() {
+               $lastModified = time() - 3600;
+               return [
+                       'Timestamp 0' =>
+                               [ '0', $lastModified, false ],
+                       'Timestamp Unix epoch' =>
+                               [ '19700101000000', $lastModified, false ],
+                       'Timestamp same as If-Modified-Since' =>
+                               [ $lastModified, $lastModified, true ],
+                       'Timestamp one second after If-Modified-Since' =>
+                               [ $lastModified + 1, $lastModified, false ],
+                       'No If-Modified-Since' =>
+                               [ $lastModified + 1, null, false ],
+                       'Malformed If-Modified-Since' =>
+                               [ $lastModified + 1, 'GIBBERING WOMBATS !!!', false ],
+                       'Non-standard IE-style If-Modified-Since' =>
+                               [ $lastModified, date( 'D, d M Y H:i:s', $lastModified ) . ' GMT; length=5202',
+                                       true ],
+                       // @todo Should we fix this behavior to match the spec?  Probably no reason to.
+                       'If-Modified-Since not per spec but we accept it anyway because strtotime does' =>
+                               [ $lastModified, "@$lastModified", true ],
+                       '$wgCachePages = false' =>
+                               [ $lastModified, $lastModified, false, [ 'CachePages' => false ] ],
+                       '$wgCacheEpoch' =>
+                               [ $lastModified, $lastModified, false,
+                                       [ 'CacheEpoch' => wfTimestamp( TS_MW, $lastModified + 1 ) ] ],
+                       'Recently-touched user' =>
+                               [ $lastModified, $lastModified, false, [],
+                               function ( $op ) {
+                                       $op->getContext()->setUser( $this->getTestUser()->getUser() );
+                               } ],
+                       'After Squid expiry' =>
+                               [ $lastModified, $lastModified, false,
+                                       [ 'UseSquid' => true, 'SquidMaxage' => 3599 ] ],
+                       'Hook allows cache use' =>
+                               [ $lastModified + 1, $lastModified, true, [],
+                               function ( $op, $that ) {
+                                       $that->setTemporaryHook( 'OutputPageCheckLastModified',
+                                               function ( &$modifiedTimes ) {
+                                                       $modifiedTimes = [ 1 ];
+                                               }
+                                       );
+                               } ],
+                       'Hooks prohibits cache use' =>
+                               [ $lastModified, $lastModified, false, [],
+                               function ( $op, $that ) {
+                                       $that->setTemporaryHook( 'OutputPageCheckLastModified',
+                                               function ( &$modifiedTimes ) {
+                                                       $modifiedTimes = [ max( $modifiedTimes ) + 1 ];
+                                               }
+                                       );
+                               } ],
+               ];
        }
 
        /**
-        * Tests print requests
-        * @covers OutputPage::transformCssMedia
+        * @dataProvider provideCdnCacheEpoch
+        *
+        * @covers OutputPage::getCdnCacheEpoch
         */
-       public function testPrintRequests() {
-               $this->assertTransformCssMediaCase( [
-                       'printableQuery' => '1',
-                       'media' => 'screen',
-                       'expectedReturn' => null,
-                       'message' => 'On printable request, screen returns null'
-               ] );
-
-               $this->assertTransformCssMediaCase( [
-                       'printableQuery' => '1',
-                       'media' => self::SCREEN_MEDIA_QUERY,
-                       'expectedReturn' => null,
-                       'message' => 'On printable request, screen media query returns null'
-               ] );
-
-               $this->assertTransformCssMediaCase( [
-                       'printableQuery' => '1',
-                       'media' => self::SCREEN_ONLY_MEDIA_QUERY,
-                       'expectedReturn' => null,
-                       'message' => 'On printable request, screen media query with only returns null'
-               ] );
+       public function testCdnCacheEpoch( $params ) {
+               $out = TestingAccessWrapper::newFromObject( $this->newInstance() );
+               $reqTime = strtotime( $params['reqTime'] );
+               $pageTime = strtotime( $params['pageTime'] );
+               $actual = max( $pageTime, $out->getCdnCacheEpoch( $reqTime, $params['maxAge'] ) );
 
-               $this->assertTransformCssMediaCase( [
-                       'printableQuery' => '1',
-                       'media' => 'print',
-                       'expectedReturn' => '',
-                       'message' => 'On printable request, media print returns empty string'
-               ] );
+               $this->assertEquals(
+                       $params['expect'],
+                       gmdate( DateTime::ATOM, $actual ),
+                       'cdn epoch'
+               );
        }
 
        public static function provideCdnCacheEpoch() {
@@ -149,229 +424,405 @@ class OutputPageTest extends MediaWikiTestCase {
                ];
        }
 
+       // @todo How to test setLastModified?
+
        /**
-        * @dataProvider provideCdnCacheEpoch
-        * @covers OutputPage::getCdnCacheEpoch
+        * @covers OutputPage::setRobotPolicy
+        * @covers OutputPage::getHeadLinksArray
         */
-       public function testCdnCacheEpoch( $params ) {
-               $out = TestingAccessWrapper::newFromObject( $this->newInstance() );
-               $reqTime = strtotime( $params['reqTime'] );
-               $pageTime = strtotime( $params['pageTime'] );
-               $actual = max( $pageTime, $out->getCdnCacheEpoch( $reqTime, $params['maxAge'] ) );
+       public function testSetRobotPolicy() {
+               $op = $this->newInstance();
+               $op->setRobotPolicy( 'noindex, nofollow' );
 
-               $this->assertEquals(
-                       $params['expect'],
-                       gmdate( DateTime::ATOM, $actual ),
-                       'cdn epoch'
+               $links = $op->getHeadLinksArray();
+               $this->assertContains( '<meta name="robots" content="noindex,nofollow"/>', $links );
+       }
+
+       /**
+        * @covers OutputPage::setIndexPolicy
+        * @covers OutputPage::setFollowPolicy
+        * @covers OutputPage::getHeadLinksArray
+        */
+       public function testSetIndexFollowPolicies() {
+               $op = $this->newInstance();
+               $op->setIndexPolicy( 'noindex' );
+               $op->setFollowPolicy( 'nofollow' );
+
+               $links = $op->getHeadLinksArray();
+               $this->assertContains( '<meta name="robots" content="noindex,nofollow"/>', $links );
+       }
+
+       private function extractHTMLTitle( OutputPage $op ) {
+               $html = $op->headElement( $op->getContext()->getSkin() );
+
+               // OutputPage should always output the title in a nice format such that regexes will work
+               // fine.  If it doesn't, we'll fail the tests.
+               preg_match_all( '!<title>(.*?)</title>!', $html, $matches );
+
+               $this->assertLessThanOrEqual( 1, count( $matches[1] ), 'More than one <title>!' );
+
+               if ( !count( $matches[1] ) ) {
+                       return null;
+               }
+
+               return $matches[1][0];
+       }
+
+       /**
+        * Shorthand for getting the text of a message, in content language.
+        */
+       private static function getMsgText( $op, ...$msgParams ) {
+               return $op->msg( ...$msgParams )->inContentLanguage()->text();
+       }
+
+       /**
+        * @covers OutputPage::setHTMLTitle
+        * @covers OutputPage::getHTMLTitle
+        */
+       public function testHTMLTitle() {
+               $op = $this->newInstance();
+
+               // Default
+               $this->assertSame( '', $op->getHTMLTitle() );
+               $this->assertSame( '', $op->getPageTitle() );
+               $this->assertSame(
+                       $this->getMsgText( $op, 'pagetitle', '' ),
+                       $this->extractHTMLTitle( $op )
                );
+
+               // Set to string
+               $op->setHTMLTitle( 'Potatoes will eat me' );
+
+               $this->assertSame( 'Potatoes will eat me', $op->getHTMLTitle() );
+               $this->assertSame( 'Potatoes will eat me', $this->extractHTMLTitle( $op ) );
+               // Shouldn't have changed the page title
+               $this->assertSame( '', $op->getPageTitle() );
+
+               // Set to message
+               $msg = $op->msg( 'mainpage' );
+
+               $op->setHTMLTitle( $msg );
+               $this->assertSame( $msg->text(), $op->getHTMLTitle() );
+               $this->assertSame( $msg->text(), $this->extractHTMLTitle( $op ) );
+               $this->assertSame( '', $op->getPageTitle() );
        }
 
        /**
-        * Tests screen requests, without either query parameter set
-        * @covers OutputPage::transformCssMedia
+        * @covers OutputPage::setRedirectedFrom
         */
-       public function testScreenRequests() {
-               $this->assertTransformCssMediaCase( [
-                       'media' => 'screen',
-                       'expectedReturn' => 'screen',
-                       'message' => 'On screen request, screen media type is preserved'
-               ] );
+       public function testSetRedirectedFrom() {
+               $op = $this->newInstance();
 
-               $this->assertTransformCssMediaCase( [
-                       'media' => 'handheld',
-                       'expectedReturn' => 'handheld',
-                       'message' => 'On screen request, handheld media type is preserved'
-               ] );
+               $op->setRedirectedFrom( Title::newFromText( 'Talk:Some page' ) );
+               $this->assertSame( 'Talk:Some_page', $op->getJSVars()['wgRedirectedFrom'] );
+       }
 
-               $this->assertTransformCssMediaCase( [
-                       'media' => self::SCREEN_MEDIA_QUERY,
-                       'expectedReturn' => self::SCREEN_MEDIA_QUERY,
-                       'message' => 'On screen request, screen media query is preserved.'
-               ] );
+       /**
+        * @covers OutputPage::setPageTitle
+        * @covers OutputPage::getPageTitle
+        */
+       public function testPageTitle() {
+               // We don't test the actual HTML output anywhere, because that's up to the skin.
+               $op = $this->newInstance();
 
-               $this->assertTransformCssMediaCase( [
-                       'media' => self::SCREEN_ONLY_MEDIA_QUERY,
-                       'expectedReturn' => self::SCREEN_ONLY_MEDIA_QUERY,
-                       'message' => 'On screen request, screen media query with only is preserved.'
-               ] );
+               // Test default
+               $this->assertSame( '', $op->getPageTitle() );
+               $this->assertSame( '', $op->getHTMLTitle() );
 
-               $this->assertTransformCssMediaCase( [
-                       'media' => 'print',
-                       'expectedReturn' => 'print',
-                       'message' => 'On screen request, print media type is preserved'
-               ] );
+               // Test set to plain text
+               $op->setPageTitle( 'foobar' );
+
+               $this->assertSame( 'foobar', $op->getPageTitle() );
+               // HTML title should change as well
+               $this->assertSame( $this->getMsgText( $op, 'pagetitle', 'foobar' ), $op->getHTMLTitle() );
+
+               // Test set to text with good and bad HTML.  We don't try to be comprehensive here, that
+               // belongs in Sanitizer tests.
+               $op->setPageTitle( '<script>a</script>&amp;<i>b</i>' );
+
+               $this->assertSame( '&lt;script&gt;a&lt;/script&gt;&amp;<i>b</i>', $op->getPageTitle() );
+               $this->assertSame(
+                       $this->getMsgText( $op, 'pagetitle', '<script>a</script>&b' ),
+                       $op->getHTMLTitle()
+               );
+
+               // Test set to message
+               $text = $this->getMsgText( $op, 'mainpage' );
+
+               $op->setPageTitle( $op->msg( 'mainpage' )->inContentLanguage() );
+               $this->assertSame( $text, $op->getPageTitle() );
+               $this->assertSame( $this->getMsgText( $op, 'pagetitle', $text ), $op->getHTMLTitle() );
        }
 
        /**
-        * Tests handheld behavior
-        * @covers OutputPage::transformCssMedia
+        * @covers OutputPage::setTitle
         */
-       public function testHandheld() {
-               $this->assertTransformCssMediaCase( [
-                       'handheldQuery' => '1',
-                       'media' => 'handheld',
-                       'expectedReturn' => '',
-                       'message' => 'On request with handheld querystring and media is handheld, returns empty string'
+       public function testSetTitle() {
+               $op = $this->newInstance();
+
+               $this->assertSame( 'My test page', $op->getTitle()->getPrefixedText() );
+
+               $op->setTitle( Title::newFromText( 'Another test page' ) );
+
+               $this->assertSame( 'Another test page', $op->getTitle()->getPrefixedText() );
+       }
+
+       /**
+        * @covers OutputPage::setSubtitle
+        * @covers OutputPage::clearSubtitle
+        * @covers OutputPage::addSubtitle
+        * @covers OutputPage::getSubtitle
+        */
+       public function testSubtitle() {
+               $op = $this->newInstance();
+
+               $this->assertSame( '', $op->getSubtitle() );
+
+               $op->addSubtitle( '<b>foo</b>' );
+
+               $this->assertSame( '<b>foo</b>', $op->getSubtitle() );
+
+               $op->addSubtitle( $op->msg( 'mainpage' )->inContentLanguage() );
+
+               $this->assertSame(
+                       "<b>foo</b><br />\n\t\t\t\t" . $this->getMsgText( $op, 'mainpage' ),
+                       $op->getSubtitle()
+               );
+
+               $op->setSubtitle( 'There can be only one' );
+
+               $this->assertSame( 'There can be only one', $op->getSubtitle() );
+
+               $op->clearSubtitle();
+
+               $this->assertSame( '', $op->getSubtitle() );
+       }
+
+       /**
+        * @dataProvider provideBacklinkSubtitle
+        *
+        * @covers OutputPage::buildBacklinkSubtitle
+        */
+       public function testBuildBacklinkSubtitle( Title $title, $query, $contains, $notContains ) {
+               $this->editPage( 'Page 1', '' );
+               $this->editPage( 'Page 2', '#REDIRECT [[Page 1]]' );
+
+               $str = OutputPage::buildBacklinkSubtitle( $title, $query )->text();
+
+               foreach ( $contains as $substr ) {
+                       $this->assertContains( $substr, $str );
+               }
+
+               foreach ( $notContains as $substr ) {
+                       $this->assertNotContains( $substr, $str );
+               }
+       }
+
+       /**
+        * @dataProvider provideBacklinkSubtitle
+        *
+        * @covers OutputPage::addBacklinkSubtitle
+        * @covers OutputPage::getSubtitle
+        */
+       public function testAddBacklinkSubtitle( Title $title, $query, $contains, $notContains ) {
+               $this->editPage( 'Page 1', '' );
+               $this->editPage( 'Page 2', '#REDIRECT [[Page 1]]' );
+
+               $op = $this->newInstance();
+               $op->addBacklinkSubtitle( $title, $query );
+
+               $str = $op->getSubtitle();
+
+               foreach ( $contains as $substr ) {
+                       $this->assertContains( $substr, $str );
+               }
+
+               foreach ( $notContains as $substr ) {
+                       $this->assertNotContains( $substr, $str );
+               }
+       }
+
+       public function provideBacklinkSubtitle() {
+               $page1 = Title::newFromText( 'Page 1' );
+               $page2 = Title::newFromText( 'Page 2' );
+
+               return [
+                       [ $page1, [], [ 'Page 1' ], [ 'redirect', 'Page 2' ] ],
+                       [ $page2, [], [ 'redirect=no' ], [ 'Page 1' ] ],
+                       [ $page1, [ 'action' => 'edit' ], [ 'action=edit' ], [] ],
+                       // @todo Anything else to test?
+               ];
+       }
+
+       /**
+        * @covers OutputPage::addCategoryLinks
+        * @covers OutputPage::getCategories
+        */
+       public function testGetCategories() {
+               $fakeResultWrapper = new FakeResultWrapper( [
+                       (object)[
+                               'pp_value' => 1,
+                               'page_title' => 'Test'
+                       ],
+                       (object)[
+                               'page_title' => 'Test2'
+                       ]
                ] );
+               $op = $this->getMockBuilder( OutputPage::class )
+                       ->setConstructorArgs( [ new RequestContext() ] )
+                       ->setMethods( [ 'addCategoryLinksToLBAndGetResult' ] )
+                       ->getMock();
+               $op->expects( $this->any() )
+                       ->method( 'addCategoryLinksToLBAndGetResult' )
+                       ->will( $this->returnValue( $fakeResultWrapper ) );
 
-               $this->assertTransformCssMediaCase( [
-                       'handheldQuery' => '1',
-                       'media' => 'screen',
-                       'expectedReturn' => null,
-                       'message' => 'On request with handheld querystring and media is screen, returns null'
+               $op->addCategoryLinks( [
+                       'Test' => 'Test',
+                       'Test2' => 'Test2',
                ] );
+               $this->assertEquals( [ 0 => 'Test', '1' => 'Test2' ], $op->getCategories() );
+               $this->assertEquals( [ 0 => 'Test2' ], $op->getCategories( 'normal' ) );
+               $this->assertEquals( [ 0 => 'Test' ], $op->getCategories( 'hidden' ) );
        }
 
-       public static function provideTransformFilePath() {
-               $baseDir = dirname( __DIR__ ) . '/data/media';
+       /**
+        * @covers OutputPage::haveCacheVaryCookies
+        */
+       public function testHaveCacheVaryCookies() {
+               $request = new FauxRequest();
+               $context = new RequestContext();
+               $context->setRequest( $request );
+               $op = new OutputPage( $context );
+
+               // No cookies are set.
+               $this->assertFalse( $op->haveCacheVaryCookies() );
+
+               // 'Token' is present but empty, so it shouldn't count.
+               $request->setCookie( 'Token', '' );
+               $this->assertFalse( $op->haveCacheVaryCookies() );
+
+               // 'Token' present and nonempty.
+               $request->setCookie( 'Token', '123' );
+               $this->assertTrue( $op->haveCacheVaryCookies() );
+       }
+
+       /**
+        * @dataProvider provideVaryHeaders
+        *
+        * @covers OutputPage::addVaryHeader
+        * @covers OutputPage::getVaryHeader
+        * @covers OutputPage::getKeyHeader
+        */
+       public function testVaryHeaders( $calls, $vary, $key ) {
+               // get rid of default Vary fields
+               $op = $this->getMockBuilder( OutputPage::class )
+                       ->setConstructorArgs( [ new RequestContext() ] )
+                       ->setMethods( [ 'getCacheVaryCookies' ] )
+                       ->getMock();
+               $op->expects( $this->any() )
+                       ->method( 'getCacheVaryCookies' )
+                       ->will( $this->returnValue( [] ) );
+               TestingAccessWrapper::newFromObject( $op )->mVaryHeader = [];
+
+               foreach ( $calls as $call ) {
+                       call_user_func_array( [ $op, 'addVaryHeader' ], $call );
+               }
+               $this->assertEquals( $vary, $op->getVaryHeader(), 'Vary:' );
+               $this->assertEquals( $key, $op->getKeyHeader(), 'Key:' );
+       }
+
+       public function provideVaryHeaders() {
+               // note: getKeyHeader() automatically adds Vary: Cookie
                return [
-                       // File that matches basePath, and exists. Hash found and appended.
-                       [
-                               'baseDir' => $baseDir, 'basePath' => '/w',
-                               '/w/test.jpg',
-                               '/w/test.jpg?edcf2'
-                       ],
-                       // File that matches basePath, but not found on disk. Empty query.
-                       [
-                               'baseDir' => $baseDir, 'basePath' => '/w',
-                               '/w/unknown.png',
-                               '/w/unknown.png?'
-                       ],
-                       // File not matching basePath. Ignored.
-                       [
-                               'baseDir' => $baseDir, 'basePath' => '/w',
-                               '/files/test.jpg'
-                       ],
-                       // Empty string. Ignored.
-                       [
-                               'baseDir' => $baseDir, 'basePath' => '/w',
-                               '',
-                               ''
-                       ],
-                       // Similar path, but with domain component. Ignored.
-                       [
-                               'baseDir' => $baseDir, 'basePath' => '/w',
-                               '//example.org/w/test.jpg'
-                       ],
-                       [
-                               'baseDir' => $baseDir, 'basePath' => '/w',
-                               'https://example.org/w/test.jpg'
-                       ],
-                       // Unrelated path with domain component. Ignored.
-                       [
-                               'baseDir' => $baseDir, 'basePath' => '/w',
-                               'https://example.org/files/test.jpg'
+                       [ // single header
+                               [
+                                       [ 'Cookie' ],
+                               ],
+                               'Vary: Cookie',
+                               'Key: Cookie',
                        ],
-                       [
-                               'baseDir' => $baseDir, 'basePath' => '/w',
-                               '//example.org/files/test.jpg'
+                       [ // non-unique headers
+                               [
+                                       [ 'Cookie' ],
+                                       [ 'Accept-Language' ],
+                                       [ 'Cookie' ],
+                               ],
+                               'Vary: Cookie, Accept-Language',
+                               'Key: Cookie,Accept-Language',
                        ],
-                       // Unrelated path with domain, and empty base path (root mw install). Ignored.
-                       [
-                               'baseDir' => $baseDir, 'basePath' => '',
-                               'https://example.org/files/test.jpg'
+                       [ // two headers with single options
+                               [
+                                       [ 'Cookie', [ 'param=phpsessid' ] ],
+                                       [ 'Accept-Language', [ 'substr=en' ] ],
+                               ],
+                               'Vary: Cookie, Accept-Language',
+                               'Key: Cookie;param=phpsessid,Accept-Language;substr=en',
                        ],
-                       [
-                               'baseDir' => $baseDir, 'basePath' => '',
-                               // T155310
-                               '//example.org/files/test.jpg'
+                       [ // one header with multiple options
+                               [
+                                       [ 'Cookie', [ 'param=phpsessid', 'param=userId' ] ],
+                               ],
+                               'Vary: Cookie',
+                               'Key: Cookie;param=phpsessid;param=userId',
                        ],
-                       // Check UploadPath before ResourceBasePath (T155146)
-                       [
-                               'baseDir' => dirname( $baseDir ), 'basePath' => '',
-                               'uploadDir' => $baseDir, 'uploadPath' => '/images',
-                               '/images/test.jpg',
-                               '/images/test.jpg?edcf2'
+                       [ // Duplicate option
+                               [
+                                       [ 'Cookie', [ 'param=phpsessid' ] ],
+                                       [ 'Cookie', [ 'param=phpsessid' ] ],
+                                       [ 'Accept-Language', [ 'substr=en', 'substr=en' ] ],
+                               ],
+                               'Vary: Cookie, Accept-Language',
+                               'Key: Cookie;param=phpsessid,Accept-Language;substr=en',
+                       ],
+                       [ // Same header, different options
+                               [
+                                       [ 'Cookie', [ 'param=phpsessid' ] ],
+                                       [ 'Cookie', [ 'param=userId' ] ],
+                               ],
+                               'Vary: Cookie',
+                               'Key: Cookie;param=phpsessid;param=userId',
                        ],
                ];
        }
 
        /**
-        * @dataProvider provideTransformFilePath
-        * @covers OutputPage::transformFilePath
-        * @covers OutputPage::transformResourcePath
+        * @dataProvider provideLinkHeaders
+        *
+        * @covers OutputPage::addLinkHeader
+        * @covers OutputPage::getLinkHeader
         */
-       public function testTransformResourcePath( $baseDir, $basePath, $uploadDir = null,
-               $uploadPath = null, $path = null, $expected = null
-       ) {
-               if ( $path === null ) {
-                       // Skip optional $uploadDir and $uploadPath
-                       $path = $uploadDir;
-                       $expected = $uploadPath;
-                       $uploadDir = "$baseDir/images";
-                       $uploadPath = "$basePath/images";
-               }
-               $this->setMwGlobals( 'IP', $baseDir );
-               $conf = new HashConfig( [
-                       'ResourceBasePath' => $basePath,
-                       'UploadDirectory' => $uploadDir,
-                       'UploadPath' => $uploadPath,
-               ] );
+       public function testLinkHeaders( $headers, $result ) {
+               $op = $this->newInstance();
 
-               Wikimedia\suppressWarnings();
-               $actual = OutputPage::transformResourcePath( $conf, $path );
-               Wikimedia\restoreWarnings();
+               foreach ( $headers as $header ) {
+                       $op->addLinkHeader( $header );
+               }
 
-               $this->assertEquals( $expected ?: $path, $actual );
+               $this->assertEquals( $result, $op->getLinkHeader() );
        }
 
-       public static function provideMakeResourceLoaderLink() {
-               // phpcs:disable Generic.Files.LineLength
+       public function provideLinkHeaders() {
                return [
-                       // Single only=scripts load
-                       [
-                               [ '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");'
-                                       . "});</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"/>'
-                       ],
-                       // Private embed (only=scripts)
                        [
-                               [ 'test.quux', ResourceLoaderModule::TYPE_SCRIPTS ],
-                               "<script nonce=\"secret\">(window.RLQ=window.RLQ||[]).push(function(){"
-                                       . "mw.test.baz({token:123});\nmw.loader.state({\"test.quux\":\"ready\"});"
-                                       . "});</script>"
-                       ],
-                       // Load private module (combined)
-                       [
-                               [ 'test.quux', ResourceLoaderModule::TYPE_COMBINED ],
-                               "<script nonce=\"secret\">(window.RLQ=window.RLQ||[]).push(function(){"
-                                       . "mw.loader.implement(\"test.quux@1ev0ijv\",function($,jQuery,require,module){"
-                                       . "mw.test.baz({token:123});},{\"css\":[\".mw-icon{transition:none}"
-                                       . "\"]});});</script>"
-                       ],
-                       // Load no modules
-                       [
-                               [ [], ResourceLoaderModule::TYPE_COMBINED ],
-                               '',
+                               [],
+                               false
                        ],
-                       // 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>'
+                               [ '<https://foo/bar.jpg>;rel=preload;as=image' ],
+                               'Link: <https://foo/bar.jpg>;rel=preload;as=image',
                        ],
-                       // Load two modules in separate groups
                        [
-                               [ [ 'test.group.foo', 'test.group.bar' ], ResourceLoaderModule::TYPE_COMBINED ],
-                               "<script nonce=\"secret\">(window.RLQ=window.RLQ||[]).push(function(){"
-                                       . 'mw.loader.load("http://127.0.0.1:8080/w/load.php?debug=false\u0026lang=en\u0026modules=test.group.bar\u0026skin=fallback");'
-                                       . 'mw.loader.load("http://127.0.0.1:8080/w/load.php?debug=false\u0026lang=en\u0026modules=test.group.foo\u0026skin=fallback");'
-                                       . "});</script>"
+                               [ '<https://foo/bar.jpg>;rel=preload;as=image','<https://foo/baz.jpg>;rel=preload;as=image' ],
+                               'Link: <https://foo/bar.jpg>;rel=preload;as=image,<https://foo/baz.jpg>;rel=preload;as=image',
                        ],
                ];
-               // phpcs:enable
        }
 
        /**
         * See ResourceLoaderClientHtmlTest for full coverage.
         *
         * @dataProvider provideMakeResourceLoaderLink
+        *
         * @covers OutputPage::makeResourceLoaderLink
         */
        public function testMakeResourceLoaderLink( $args, $expectedHtml ) {
@@ -428,38 +879,54 @@ class OutputPageTest extends MediaWikiTestCase {
                $this->assertEquals( $expectedHtml, $actualHtml );
        }
 
-       public static function provideBuildExemptModules() {
+       public static function provideMakeResourceLoaderLink() {
                // phpcs:disable Generic.Files.LineLength
                return [
-                       'empty' => [
-                               'exemptStyleModules' => [],
-                               '<meta name="ResourceLoaderDynamicStyles" content=""/>',
+                       // Single only=scripts load
+                       [
+                               [ '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");'
+                                       . "});</script>"
                        ],
-                       'empty sets' => [
-                               'exemptStyleModules' => [ 'site' => [], 'noscript' => [], 'private' => [], 'user' => [] ],
-                               '<meta name="ResourceLoaderDynamicStyles" content=""/>',
+                       // 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"/>'
                        ],
-                       '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"/>',
+                       // Private embed (only=scripts)
+                       [
+                               [ 'test.quux', ResourceLoaderModule::TYPE_SCRIPTS ],
+                               "<script nonce=\"secret\">(window.RLQ=window.RLQ||[]).push(function(){"
+                                       . "mw.test.baz({token:123});\nmw.loader.state({\"test.quux\":\"ready\"});"
+                                       . "});</script>"
                        ],
-                       '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=1e9z0ox"/>',
+                       // Load private module (combined)
+                       [
+                               [ 'test.quux', ResourceLoaderModule::TYPE_COMBINED ],
+                               "<script nonce=\"secret\">(window.RLQ=window.RLQ||[]).push(function(){"
+                                       . "mw.loader.implement(\"test.quux@1ev0ijv\",function($,jQuery,require,module){"
+                                       . "mw.test.baz({token:123});},{\"css\":[\".mw-icon{transition:none}"
+                                       . "\"]});});</script>"
                        ],
-                       'custom modules' => [
-                               'exemptStyleModules' => [
-                                       'site' => [ 'site.styles', 'example.site.a', 'example.site.b' ],
-                                       '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=1e9z0ox"/>',
+                       // Load no modules
+                       [
+                               [ [], ResourceLoaderModule::TYPE_COMBINED ],
+                               '',
+                       ],
+                       // noscript group
+                       [
+                               [ 'test.noscript', ResourceLoaderModule::TYPE_STYLES ],
+                               '<noscript><link rel="stylesheet" href="http://127.0.0.1:8080/w/load.php?debug=false&amp;lang=en&amp;modules=test.noscript&amp;only=styles&amp;skin=fallback"/></noscript>'
+                       ],
+                       // Load two modules in separate groups
+                       [
+                               [ [ 'test.group.foo', 'test.group.bar' ], ResourceLoaderModule::TYPE_COMBINED ],
+                               "<script nonce=\"secret\">(window.RLQ=window.RLQ||[]).push(function(){"
+                                       . 'mw.loader.load("http://127.0.0.1:8080/w/load.php?debug=false\u0026lang=en\u0026modules=test.group.bar\u0026skin=fallback");'
+                                       . 'mw.loader.load("http://127.0.0.1:8080/w/load.php?debug=false\u0026lang=en\u0026modules=test.group.foo\u0026skin=fallback");'
+                                       . "});</script>"
                        ],
                ];
                // phpcs:enable
@@ -467,6 +934,7 @@ class OutputPageTest extends MediaWikiTestCase {
 
        /**
         * @dataProvider provideBuildExemptModules
+        *
         * @covers OutputPage::buildExemptModules
         */
        public function testBuildExemptModules( array $exemptStyleModules, $expect ) {
@@ -482,14 +950,14 @@ class OutputPageTest extends MediaWikiTestCase {
                $ctx = new RequestContext();
                $ctx->setSkin( SkinFactory::getDefaultInstance()->makeSkin( 'fallback' ) );
                $ctx->setLanguage( 'en' );
-               $outputPage = $this->getMockBuilder( OutputPage::class )
+               $op = $this->getMockBuilder( OutputPage::class )
                        ->setConstructorArgs( [ $ctx ] )
                        ->setMethods( [ 'buildCssLinksArray' ] )
                        ->getMock();
-               $outputPage->expects( $this->any() )
+               $op->expects( $this->any() )
                        ->method( 'buildCssLinksArray' )
                        ->willReturn( [] );
-               $rl = $outputPage->getResourceLoader();
+               $rl = $op->getResourceLoader();
                $rl->setMessageBlobStore( new NullMessageBlobStore() );
 
                // Register custom modules
@@ -499,174 +967,269 @@ class OutputPageTest extends MediaWikiTestCase {
                        'example.user' => new ResourceLoaderTestModule( [ 'group' => 'user' ] ),
                ] );
 
-               $outputPage = TestingAccessWrapper::newFromObject( $outputPage );
-               $outputPage->rlExemptStyleModules = $exemptStyleModules;
+               $op = TestingAccessWrapper::newFromObject( $op );
+               $op->rlExemptStyleModules = $exemptStyleModules;
                $this->assertEquals(
                        $expect,
-                       strval( $outputPage->buildExemptModules() )
+                       strval( $op->buildExemptModules() )
                );
        }
 
+       public static function provideBuildExemptModules() {
+               // phpcs:disable Generic.Files.LineLength
+               return [
+                       'empty' => [
+                               'exemptStyleModules' => [],
+                               '<meta name="ResourceLoaderDynamicStyles" content=""/>',
+                       ],
+                       'empty sets' => [
+                               'exemptStyleModules' => [ 'site' => [], 'noscript' => [], 'private' => [], 'user' => [] ],
+                               '<meta name="ResourceLoaderDynamicStyles" content=""/>',
+                       ],
+                       '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"/>',
+                       ],
+                       '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=1e9z0ox"/>',
+                       ],
+                       'custom modules' => [
+                               'exemptStyleModules' => [
+                                       'site' => [ 'site.styles', 'example.site.a', 'example.site.b' ],
+                                       '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=1e9z0ox"/>',
+                       ],
+               ];
+               // phpcs:enable
+       }
+
        /**
-        * @dataProvider provideVaryHeaders
-        * @covers OutputPage::addVaryHeader
-        * @covers OutputPage::getVaryHeader
-        * @covers OutputPage::getKeyHeader
+        * @dataProvider provideTransformFilePath
+        * @covers OutputPage::transformFilePath
+        * @covers OutputPage::transformResourcePath
         */
-       public function testVaryHeaders( $calls, $vary, $key ) {
-               // get rid of default Vary fields
-               $outputPage = $this->getMockBuilder( OutputPage::class )
-                       ->setConstructorArgs( [ new RequestContext() ] )
-                       ->setMethods( [ 'getCacheVaryCookies' ] )
-                       ->getMock();
-               $outputPage->expects( $this->any() )
-                       ->method( 'getCacheVaryCookies' )
-                       ->will( $this->returnValue( [] ) );
-               TestingAccessWrapper::newFromObject( $outputPage )->mVaryHeader = [];
-
-               foreach ( $calls as $call ) {
-                       call_user_func_array( [ $outputPage, 'addVaryHeader' ], $call );
+       public function testTransformResourcePath( $baseDir, $basePath, $uploadDir = null,
+               $uploadPath = null, $path = null, $expected = null
+       ) {
+               if ( $path === null ) {
+                       // Skip optional $uploadDir and $uploadPath
+                       $path = $uploadDir;
+                       $expected = $uploadPath;
+                       $uploadDir = "$baseDir/images";
+                       $uploadPath = "$basePath/images";
                }
-               $this->assertEquals( $vary, $outputPage->getVaryHeader(), 'Vary:' );
-               $this->assertEquals( $key, $outputPage->getKeyHeader(), 'Key:' );
+               $this->setMwGlobals( 'IP', $baseDir );
+               $conf = new HashConfig( [
+                       'ResourceBasePath' => $basePath,
+                       'UploadDirectory' => $uploadDir,
+                       'UploadPath' => $uploadPath,
+               ] );
+
+               // Some of these paths don't exist and will cause warnings
+               Wikimedia\suppressWarnings();
+               $actual = OutputPage::transformResourcePath( $conf, $path );
+               Wikimedia\restoreWarnings();
+
+               $this->assertEquals( $expected ?: $path, $actual );
        }
 
-       public function provideVaryHeaders() {
-               // note: getKeyHeader() automatically adds Vary: Cookie
+       public static function provideTransformFilePath() {
+               $baseDir = dirname( __DIR__ ) . '/data/media';
                return [
-                       [ // single header
-                               [
-                                       [ 'Cookie' ],
-                               ],
-                               'Vary: Cookie',
-                               'Key: Cookie',
+                       // File that matches basePath, and exists. Hash found and appended.
+                       [
+                               'baseDir' => $baseDir, 'basePath' => '/w',
+                               '/w/test.jpg',
+                               '/w/test.jpg?edcf2'
                        ],
-                       [ // non-unique headers
-                               [
-                                       [ 'Cookie' ],
-                                       [ 'Accept-Language' ],
-                                       [ 'Cookie' ],
-                               ],
-                               'Vary: Cookie, Accept-Language',
-                               'Key: Cookie,Accept-Language',
+                       // File that matches basePath, but not found on disk. Empty query.
+                       [
+                               'baseDir' => $baseDir, 'basePath' => '/w',
+                               '/w/unknown.png',
+                               '/w/unknown.png?'
                        ],
-                       [ // two headers with single options
-                               [
-                                       [ 'Cookie', [ 'param=phpsessid' ] ],
-                                       [ 'Accept-Language', [ 'substr=en' ] ],
-                               ],
-                               'Vary: Cookie, Accept-Language',
-                               'Key: Cookie;param=phpsessid,Accept-Language;substr=en',
+                       // File not matching basePath. Ignored.
+                       [
+                               'baseDir' => $baseDir, 'basePath' => '/w',
+                               '/files/test.jpg'
                        ],
-                       [ // one header with multiple options
-                               [
-                                       [ 'Cookie', [ 'param=phpsessid', 'param=userId' ] ],
-                               ],
-                               'Vary: Cookie',
-                               'Key: Cookie;param=phpsessid;param=userId',
+                       // Empty string. Ignored.
+                       [
+                               'baseDir' => $baseDir, 'basePath' => '/w',
+                               '',
+                               ''
                        ],
-                       [ // Duplicate option
-                               [
-                                       [ 'Cookie', [ 'param=phpsessid' ] ],
-                                       [ 'Cookie', [ 'param=phpsessid' ] ],
-                                       [ 'Accept-Language', [ 'substr=en', 'substr=en' ] ],
-                               ],
-                               'Vary: Cookie, Accept-Language',
-                               'Key: Cookie;param=phpsessid,Accept-Language;substr=en',
+                       // Similar path, but with domain component. Ignored.
+                       [
+                               'baseDir' => $baseDir, 'basePath' => '/w',
+                               '//example.org/w/test.jpg'
                        ],
-                       [ // Same header, different options
-                               [
-                                       [ 'Cookie', [ 'param=phpsessid' ] ],
-                                       [ 'Cookie', [ 'param=userId' ] ],
-                               ],
-                               'Vary: Cookie',
-                               'Key: Cookie;param=phpsessid;param=userId',
+                       [
+                               'baseDir' => $baseDir, 'basePath' => '/w',
+                               'https://example.org/w/test.jpg'
+                       ],
+                       // Unrelated path with domain component. Ignored.
+                       [
+                               'baseDir' => $baseDir, 'basePath' => '/w',
+                               'https://example.org/files/test.jpg'
+                       ],
+                       [
+                               'baseDir' => $baseDir, 'basePath' => '/w',
+                               '//example.org/files/test.jpg'
+                       ],
+                       // Unrelated path with domain, and empty base path (root mw install). Ignored.
+                       [
+                               'baseDir' => $baseDir, 'basePath' => '',
+                               'https://example.org/files/test.jpg'
+                       ],
+                       [
+                               'baseDir' => $baseDir, 'basePath' => '',
+                               // T155310
+                               '//example.org/files/test.jpg'
+                       ],
+                       // Check UploadPath before ResourceBasePath (T155146)
+                       [
+                               'baseDir' => dirname( $baseDir ), 'basePath' => '',
+                               'uploadDir' => $baseDir, 'uploadPath' => '/images',
+                               '/images/test.jpg',
+                               '/images/test.jpg?edcf2'
                        ],
                ];
        }
 
        /**
-        * @covers OutputPage::haveCacheVaryCookies
+        * Tests a particular case of transformCssMedia, using the given input, globals,
+        * expected return, and message
+        *
+        * Asserts that $expectedReturn is returned.
+        *
+        * options['printableQuery'] - value of query string for printable, or omitted for none
+        * options['handheldQuery'] - value of query string for handheld, or omitted for none
+        * options['media'] - passed into the method under the same name
+        * options['expectedReturn'] - expected return value
+        * options['message'] - PHPUnit message for assertion
+        *
+        * @param array $args Key-value array of arguments as shown above
         */
-       public function testHaveCacheVaryCookies() {
-               $request = new FauxRequest();
-               $context = new RequestContext();
-               $context->setRequest( $request );
-               $outputPage = new OutputPage( $context );
+       protected function assertTransformCssMediaCase( $args ) {
+               $queryData = [];
+               if ( isset( $args['printableQuery'] ) ) {
+                       $queryData['printable'] = $args['printableQuery'];
+               }
 
-               // No cookies are set.
-               $this->assertFalse( $outputPage->haveCacheVaryCookies() );
+               if ( isset( $args['handheldQuery'] ) ) {
+                       $queryData['handheld'] = $args['handheldQuery'];
+               }
 
-               // 'Token' is present but empty, so it shouldn't count.
-               $request->setCookie( 'Token', '' );
-               $this->assertFalse( $outputPage->haveCacheVaryCookies() );
+               $fauxRequest = new FauxRequest( $queryData, false );
+               $this->setMwGlobals( [
+                       'wgRequest' => $fauxRequest,
+               ] );
 
-               // 'Token' present and nonempty.
-               $request->setCookie( 'Token', '123' );
-               $this->assertTrue( $outputPage->haveCacheVaryCookies() );
+               $actualReturn = OutputPage::transformCssMedia( $args['media'] );
+               $this->assertSame( $args['expectedReturn'], $actualReturn, $args['message'] );
        }
 
        /**
-        * @covers OutputPage::addCategoryLinks
-        * @covers OutputPage::getCategories
+        * Tests print requests
+        *
+        * @covers OutputPage::transformCssMedia
         */
-       public function testGetCategories() {
-               $fakeResultWrapper = new FakeResultWrapper( [
-                       (object)[
-                               'pp_value' => 1,
-                               'page_title' => 'Test'
-                       ],
-                       (object)[
-                               'page_title' => 'Test2'
-                       ]
+       public function testPrintRequests() {
+               $this->assertTransformCssMediaCase( [
+                       'printableQuery' => '1',
+                       'media' => 'screen',
+                       'expectedReturn' => null,
+                       'message' => 'On printable request, screen returns null'
                ] );
-               $outputPage = $this->getMockBuilder( OutputPage::class )
-                       ->setConstructorArgs( [ new RequestContext() ] )
-                       ->setMethods( [ 'addCategoryLinksToLBAndGetResult' ] )
-                       ->getMock();
-               $outputPage->expects( $this->any() )
-                       ->method( 'addCategoryLinksToLBAndGetResult' )
-                       ->will( $this->returnValue( $fakeResultWrapper ) );
 
-               $outputPage->addCategoryLinks( [
-                       'Test' => 'Test',
-                       'Test2' => 'Test2',
+               $this->assertTransformCssMediaCase( [
+                       'printableQuery' => '1',
+                       'media' => self::SCREEN_MEDIA_QUERY,
+                       'expectedReturn' => null,
+                       'message' => 'On printable request, screen media query returns null'
+               ] );
+
+               $this->assertTransformCssMediaCase( [
+                       'printableQuery' => '1',
+                       'media' => self::SCREEN_ONLY_MEDIA_QUERY,
+                       'expectedReturn' => null,
+                       'message' => 'On printable request, screen media query with only returns null'
+               ] );
+
+               $this->assertTransformCssMediaCase( [
+                       'printableQuery' => '1',
+                       'media' => 'print',
+                       'expectedReturn' => '',
+                       'message' => 'On printable request, media print returns empty string'
                ] );
-               $this->assertEquals( [ 0 => 'Test', '1' => 'Test2' ], $outputPage->getCategories() );
-               $this->assertEquals( [ 0 => 'Test2' ], $outputPage->getCategories( 'normal' ) );
-               $this->assertEquals( [ 0 => 'Test' ], $outputPage->getCategories( 'hidden' ) );
        }
 
        /**
-        * @dataProvider provideLinkHeaders
-        * @covers OutputPage::addLinkHeader
-        * @covers OutputPage::getLinkHeader
+        * Tests screen requests, without either query parameter set
+        *
+        * @covers OutputPage::transformCssMedia
         */
-       public function testLinkHeaders( $headers, $result ) {
-               $outputPage = $this->newInstance();
+       public function testScreenRequests() {
+               $this->assertTransformCssMediaCase( [
+                       'media' => 'screen',
+                       'expectedReturn' => 'screen',
+                       'message' => 'On screen request, screen media type is preserved'
+               ] );
 
-               foreach ( $headers as $header ) {
-                       $outputPage->addLinkHeader( $header );
-               }
+               $this->assertTransformCssMediaCase( [
+                       'media' => 'handheld',
+                       'expectedReturn' => 'handheld',
+                       'message' => 'On screen request, handheld media type is preserved'
+               ] );
+
+               $this->assertTransformCssMediaCase( [
+                       'media' => self::SCREEN_MEDIA_QUERY,
+                       'expectedReturn' => self::SCREEN_MEDIA_QUERY,
+                       'message' => 'On screen request, screen media query is preserved.'
+               ] );
+
+               $this->assertTransformCssMediaCase( [
+                       'media' => self::SCREEN_ONLY_MEDIA_QUERY,
+                       'expectedReturn' => self::SCREEN_ONLY_MEDIA_QUERY,
+                       'message' => 'On screen request, screen media query with only is preserved.'
+               ] );
 
-               $this->assertEquals( $result, $outputPage->getLinkHeader() );
+               $this->assertTransformCssMediaCase( [
+                       'media' => 'print',
+                       'expectedReturn' => 'print',
+                       'message' => 'On screen request, print media type is preserved'
+               ] );
        }
 
-       public function provideLinkHeaders() {
-               return [
-                       [
-                               [],
-                               false
-                       ],
-                       [
-                               [ '<https://foo/bar.jpg>;rel=preload;as=image' ],
-                               'Link: <https://foo/bar.jpg>;rel=preload;as=image',
-                       ],
-                       [
-                               [ '<https://foo/bar.jpg>;rel=preload;as=image','<https://foo/baz.jpg>;rel=preload;as=image' ],
-                               'Link: <https://foo/bar.jpg>;rel=preload;as=image,<https://foo/baz.jpg>;rel=preload;as=image',
-                       ],
-               ];
+       /**
+        * Tests handheld behavior
+        *
+        * @covers OutputPage::transformCssMedia
+        */
+       public function testHandheld() {
+               $this->assertTransformCssMediaCase( [
+                       'handheldQuery' => '1',
+                       'media' => 'handheld',
+                       'expectedReturn' => '',
+                       'message' => 'On request with handheld querystring and media is handheld, returns empty string'
+               ] );
+
+               $this->assertTransformCssMediaCase( [
+                       'handheldQuery' => '1',
+                       'media' => 'screen',
+                       'expectedReturn' => null,
+                       'message' => 'On request with handheld querystring and media is screen, returns null'
+               ] );
        }
 
        /**
@@ -748,22 +1311,31 @@ class OutputPageTest extends MediaWikiTestCase {
        /**
         * @return OutputPage
         */
-       private function newInstance( $config = [] ) {
+       private function newInstance( $config = [], WebRequest $request = null ) {
                $context = new RequestContext();
 
-               $context->setConfig( new HashConfig( $config + [
-                       'AppleTouchIcon' => false,
-                       'DisableLangConversion' => true,
-                       'EnableCanonicalServerLink' => false,
-                       'Favicon' => false,
-                       'Feed' => false,
-                       'LanguageCode' => false,
-                       'ReferrerPolicy' => false,
-                       'RightsPage' => false,
-                       'RightsUrl' => false,
-                       'UniversalEditButton' => false,
+               $context->setConfig( new MultiConfig( [
+                       new HashConfig( $config + [
+                               'AppleTouchIcon' => false,
+                               'DisableLangConversion' => true,
+                               'EnableCanonicalServerLink' => false,
+                               'Favicon' => false,
+                               'Feed' => false,
+                               'LanguageCode' => false,
+                               'ReferrerPolicy' => false,
+                               'RightsPage' => false,
+                               'RightsUrl' => false,
+                               'UniversalEditButton' => false,
+                       ] ),
+                       $context->getConfig()
                ] ) );
 
+               $context->setTitle( Title::newFromText( 'My test page' ) );
+
+               if ( $request ) {
+                       $context->setRequest( $request );
+               }
+
                return new OutputPage( $context );
        }
 }
diff --git a/tests/phpunit/includes/PageArchiveTest.php b/tests/phpunit/includes/PageArchiveTest.php
deleted file mode 100644 (file)
index 623d4a6..0000000
+++ /dev/null
@@ -1,265 +0,0 @@
-<?php
-
-/**
- * Test class for page archiving.
- *
- * @group ContentHandler
- * @group Database
- * ^--- important, causes temporary tables to be used instead of the real database
- *
- * @group medium
- * ^--- important, causes tests not to fail with timeout
- */
-class PageArchiveTest extends MediaWikiTestCase {
-
-       /**
-        * @var PageArchive $archivedPage
-        */
-       private $archivedPage;
-
-       /**
-        * A logged out user who edited the page before it was archived.
-        * @var string $ipEditor
-        */
-       private $ipEditor;
-
-       /**
-        * Revision ID of the IP edit
-        * @var int $ipRevId
-        */
-       private $ipRevId;
-
-       function __construct( $name = null, array $data = [], $dataName = '' ) {
-               parent::__construct( $name, $data, $dataName );
-
-               $this->tablesUsed = array_merge(
-                       $this->tablesUsed,
-                       [
-                               'page',
-                               'revision',
-                               'ip_changes',
-                               'text',
-                               'archive',
-                               'recentchanges',
-                               'logging',
-                               'page_props',
-                       ]
-               );
-       }
-
-       protected function setUp() {
-               parent::setUp();
-
-               $this->setMwGlobals( 'wgCommentTableSchemaMigrationStage', MIGRATION_OLD );
-               $this->setMwGlobals( 'wgActorTableSchemaMigrationStage', MIGRATION_OLD );
-               $this->overrideMwServices();
-
-               // First create our dummy page
-               $page = Title::newFromText( 'PageArchiveTest_thePage' );
-               $page = new WikiPage( $page );
-               $content = ContentHandler::makeContent(
-                       'testing',
-                       $page->getTitle(),
-                       CONTENT_MODEL_WIKITEXT
-               );
-               $page->doEditContent( $content, 'testing', EDIT_NEW );
-
-               // Insert IP revision
-               $this->ipEditor = '2600:387:ed7:947e:8c16:a1ad:dd34:1dd7';
-               $rev = new Revision( [
-                       'text' => 'Lorem Ipsum',
-                       'comment' => 'just a test',
-                       'page' => $page->getId(),
-                       'user_text' => $this->ipEditor,
-               ] );
-               $dbw = wfGetDB( DB_MASTER );
-               $this->ipRevId = $rev->insertOn( $dbw );
-
-               // Delete the page
-               $page->doDeleteArticleReal( 'Just a test deletion' );
-
-               $this->archivedPage = new PageArchive( $page->getTitle() );
-       }
-
-       /**
-        * @covers PageArchive::undelete
-        * @covers PageArchive::undeleteRevisions
-        */
-       public function testUndeleteRevisions() {
-               // First make sure old revisions are archived
-               $dbr = wfGetDB( DB_REPLICA );
-               $arQuery = Revision::getArchiveQueryInfo();
-               $res = $dbr->select(
-                       $arQuery['tables'],
-                       $arQuery['fields'],
-                       [ 'ar_rev_id' => $this->ipRevId ],
-                       __METHOD__,
-                       [],
-                       $arQuery['joins']
-               );
-               $row = $res->fetchObject();
-               $this->assertEquals( $this->ipEditor, $row->ar_user_text );
-
-               // Should not be in revision
-               $res = $dbr->select( 'revision', '1', [ 'rev_id' => $this->ipRevId ] );
-               $this->assertFalse( $res->fetchObject() );
-
-               // Should not be in ip_changes
-               $res = $dbr->select( 'ip_changes', '1', [ 'ipc_rev_id' => $this->ipRevId ] );
-               $this->assertFalse( $res->fetchObject() );
-
-               // Restore the page
-               $this->archivedPage->undelete( [] );
-
-               // Should be back in revision
-               $revQuery = Revision::getQueryInfo();
-               $res = $dbr->select(
-                       $revQuery['tables'],
-                       $revQuery['fields'],
-                       [ 'rev_id' => $this->ipRevId ],
-                       __METHOD__,
-                       [],
-                       $revQuery['joins']
-               );
-               $row = $res->fetchObject();
-               $this->assertEquals( $this->ipEditor, $row->rev_user_text );
-
-               // Should be back in ip_changes
-               $res = $dbr->select( 'ip_changes', [ 'ipc_hex' ], [ 'ipc_rev_id' => $this->ipRevId ] );
-               $row = $res->fetchObject();
-               $this->assertEquals( IP::toHex( $this->ipEditor ), $row->ipc_hex );
-       }
-
-       /**
-        * @covers PageArchive::listRevisions
-        */
-       public function testListRevisions() {
-               $this->setMwGlobals( 'wgCommentTableSchemaMigrationStage', MIGRATION_OLD );
-               $this->overrideMwServices();
-
-               $revisions = $this->archivedPage->listRevisions();
-               $this->assertEquals( 2, $revisions->numRows() );
-
-               // Get the rows as arrays
-               $row1 = (array)$revisions->current();
-               $row2 = (array)$revisions->next();
-               // Unset the timestamps (we assume they will be right...
-               $this->assertInternalType( 'string', $row1['ar_timestamp'] );
-               $this->assertInternalType( 'string', $row2['ar_timestamp'] );
-               unset( $row1['ar_timestamp'] );
-               unset( $row2['ar_timestamp'] );
-
-               $this->assertEquals(
-                       [
-                               'ar_minor_edit' => '0',
-                               'ar_user' => '0',
-                               'ar_user_text' => '2600:387:ed7:947e:8c16:a1ad:dd34:1dd7',
-                               'ar_actor' => null,
-                               'ar_len' => '11',
-                               'ar_deleted' => '0',
-                               'ar_rev_id' => '3',
-                               'ar_sha1' => '0qdrpxl537ivfnx4gcpnzz0285yxryy',
-                               'ar_page_id' => '2',
-                               'ar_comment_text' => 'just a test',
-                               'ar_comment_data' => null,
-                               'ar_comment_cid' => null,
-                               'ar_content_format' => null,
-                               'ar_content_model' => null,
-                               'ts_tags' => null,
-                               'ar_id' => '2',
-                               'ar_namespace' => '0',
-                               'ar_title' => 'PageArchiveTest_thePage',
-                               'ar_text_id' => '3',
-                               'ar_parent_id' => '2',
-                       ],
-                       $row1
-               );
-               $this->assertEquals(
-                       [
-                               'ar_minor_edit' => '0',
-                               'ar_user' => '0',
-                               'ar_user_text' => '127.0.0.1',
-                               'ar_actor' => null,
-                               'ar_len' => '7',
-                               'ar_deleted' => '0',
-                               'ar_rev_id' => '2',
-                               'ar_sha1' => 'pr0s8e18148pxhgjfa0gjrvpy8fiyxc',
-                               'ar_page_id' => '2',
-                               'ar_comment_text' => 'testing',
-                               'ar_comment_data' => null,
-                               'ar_comment_cid' => null,
-                               'ar_content_format' => null,
-                               'ar_content_model' => null,
-                               'ts_tags' => null,
-                               'ar_id' => '1',
-                               'ar_namespace' => '0',
-                               'ar_title' => 'PageArchiveTest_thePage',
-                               'ar_text_id' => '2',
-                               'ar_parent_id' => '0',
-                       ],
-                       $row2
-               );
-       }
-
-       /**
-        * @covers PageArchive::listPagesBySearch
-        */
-       public function testListPagesBySearch() {
-               $pages = PageArchive::listPagesBySearch( 'PageArchiveTest_thePage' );
-               $this->assertSame( 1, $pages->numRows() );
-
-               $page = (array)$pages->current();
-
-               $this->assertSame(
-                       [
-                               'ar_namespace' => '0',
-                               'ar_title' => 'PageArchiveTest_thePage',
-                               'count' => '2',
-                       ],
-                       $page
-               );
-       }
-
-       /**
-        * @covers PageArchive::listPagesBySearch
-        */
-       public function testListPagesByPrefix() {
-               $pages = PageArchive::listPagesByPrefix( 'PageArchiveTest' );
-               $this->assertSame( 1, $pages->numRows() );
-
-               $page = (array)$pages->current();
-
-               $this->assertSame(
-                       [
-                               'ar_namespace' => '0',
-                               'ar_title' => 'PageArchiveTest_thePage',
-                               'count' => '2',
-                       ],
-                       $page
-               );
-       }
-
-       /**
-        * @covers PageArchive::getTextFromRow
-        */
-       public function testGetTextFromRow() {
-               $row = (object)[ 'ar_text_id' => 2 ];
-               $text = $this->archivedPage->getTextFromRow( $row );
-               $this->assertSame( 'testing', $text );
-       }
-
-       /**
-        * @covers PageArchive::getLastRevisionText
-        */
-       public function testGetLastRevisionText() {
-               $text = $this->archivedPage->getLastRevisionText();
-               $this->assertSame( 'Lorem Ipsum', $text );
-       }
-
-       /**
-        * @covers PageArchive::isDeleted
-        */
-       public function testIsDeleted() {
-               $this->assertTrue( $this->archivedPage->isDeleted() );
-       }
-}
index fc6a70b..d891675 100644 (file)
@@ -19,133 +19,295 @@ class PathRouterTest extends MediaWikiTestCase {
                $this->basicRouter = $router;
        }
 
-       /**
-        * Test basic path parsing
-        */
-       public function testBasic() {
-               $matches = $this->basicRouter->parse( "/wiki/Foo" );
-               $this->assertEquals( $matches, [ 'title' => "Foo" ] );
-       }
+       public static function provideParse() {
+               $tests = [
+                       // Basic path parsing
+                       'Basic path parsing' => [
+                               "/wiki/$1",
+                               "/wiki/Foo",
+                               [ 'title' => "Foo" ]
+                       ],
+                       //
+                       'Loose path auto-$1: /$1' => [
+                               "/",
+                               "/Foo",
+                               [ 'title' => "Foo" ]
+                       ],
+                       'Loose path auto-$1: /wiki' => [
+                               "/wiki",
+                               "/wiki/Foo",
+                               [ 'title' => "Foo" ]
+                       ],
+                       'Loose path auto-$1: /wiki/' => [
+                               "/wiki/",
+                               "/wiki/Foo",
+                               [ 'title' => "Foo" ]
+                       ],
+                       // Ensure that path is based on specificity, not order
+                       'Order, /$1 added first' => [
+                               [ "/$1", "/a/$1", "/b/$1" ],
+                               "/a/Foo",
+                               [ 'title' => "Foo" ]
+                       ],
+                       'Order, /$1 added last' => [
+                               [ "/b/$1", "/a/$1", "/$1" ],
+                               "/a/Foo",
+                               [ 'title' => "Foo" ]
+                       ],
+                       // Handling of key based arrays with a url parameter
+                       'Key based array' => [
+                               [ [
+                                       'path' => [ 'edit' => "/edit/$1" ],
+                                       'params' => [ 'action' => '$key' ],
+                               ] ],
+                               "/edit/Foo",
+                               [ 'title' => "Foo", 'action' => 'edit' ]
+                       ],
+                       // Additional parameter
+                       'Basic $2' => [
+                               [ [
+                                       'path' => '/$2/$1',
+                                       'params' => [ 'test' => '$2' ]
+                               ] ],
+                               "/asdf/Foo",
+                               [ 'title' => "Foo", 'test' => 'asdf' ]
+                       ],
+               ];
+               // Shared patterns for restricted value parameter tests
+               $restrictedPatterns = [
+                       [
+                               'path' => '/$2/$1',
+                               'params' => [ 'test' => '$2' ],
+                               'options' => [ '$2' => [ 'a', 'b' ] ]
+                       ],
+                       [
+                               'path' => '/$2/$1',
+                               'params' => [ 'test2' => '$2' ],
+                               'options' => [ '$2' => 'c' ]
+                       ],
+                       '/$1'
+               ];
+               $tests += [
+                       // Restricted value parameter tests
+                       'Restricted 1' => [
+                               $restrictedPatterns,
+                               "/asdf/Foo",
+                               [ 'title' => "asdf/Foo" ]
+                       ],
+                       'Restricted 2' => [
+                               $restrictedPatterns,
+                               "/a/Foo",
+                               [ 'title' => "Foo", 'test' => 'a' ]
+                       ],
+                       'Restricted 3' => [
+                               $restrictedPatterns,
+                               "/c/Foo",
+                               [ 'title' => "Foo", 'test2' => 'c' ]
+                       ],
 
-       /**
-        * Test loose path auto-$1
-        */
-       public function testLoose() {
-               $router = new PathRouter;
-               $router->add( "/" ); # Should be the same as "/$1"
-               $matches = $router->parse( "/Foo" );
-               $this->assertEquals( $matches, [ 'title' => "Foo" ] );
+                       // Callback test
+                       'Callback' => [
+                               [ [
+                                       'path' => "/$1",
+                                       'params' => [ 'a' => 'b', 'data:foo' => 'bar' ],
+                                       'options' => [ 'callback' => [ __CLASS__, 'callbackForTest' ] ]
+                               ] ],
+                               '/Foo',
+                               [
+                                       'title' => "Foo",
+                                       'x' => 'Foo',
+                                       'a' => 'b',
+                                       'foo' => 'bar'
+                               ]
+                       ],
 
-               $router = new PathRouter;
-               $router->add( "/wiki" ); # Should be the same as /wiki/$1
-               $matches = $router->parse( "/wiki/Foo" );
-               $this->assertEquals( $matches, [ 'title' => "Foo" ] );
+                       // Test to ensure that matches are not made if a parameter expects nonexistent input
+                       'Fail' => [
+                               [ [
+                                       'path' => "/wiki/$1",
+                                       'params' => [ 'title' => "$1$2" ],
+                               ] ],
+                               "/wiki/A",
+                               []
+                       ],
 
-               $router = new PathRouter;
-               $router->add( "/wiki/" ); # Should be the same as /wiki/$1
-               $matches = $router->parse( "/wiki/Foo" );
-               $this->assertEquals( $matches, [ 'title' => "Foo" ] );
-       }
+                       // Make sure the router handles titles like Special:Recentchanges correctly
+                       'Special title' => [
+                               "/wiki/$1",
+                               "/wiki/Special:Recentchanges",
+                               [ 'title' => "Special:Recentchanges" ]
+                       ],
 
-       /**
-        * Test to ensure that path is based on specifity, not order
-        */
-       public function testOrder() {
-               $router = new PathRouter;
-               $router->add( "/$1" );
-               $router->add( "/a/$1" );
-               $router->add( "/b/$1" );
-               $matches = $router->parse( "/a/Foo" );
-               $this->assertEquals( $matches, [ 'title' => "Foo" ] );
+                       // Make sure the router decodes urlencoding properly
+                       'URL encoding' => [
+                               "/wiki/$1",
+                               "/wiki/Title_With%20Space",
+                               [ 'title' => "Title_With Space" ]
+                       ],
 
-               $router = new PathRouter;
-               $router->add( "/b/$1" );
-               $router->add( "/a/$1" );
-               $router->add( "/$1" );
-               $matches = $router->parse( "/a/Foo" );
-               $this->assertEquals( $matches, [ 'title' => "Foo" ] );
-       }
+                       // Double slash and dot expansion
+                       'Double slash in prefix' => [
+                               '/wiki/$1',
+                               '//wiki/Foo',
+                               [ 'title' => 'Foo' ]
+                       ],
+                       'Double slash at start of $1' => [
+                               '/wiki/$1',
+                               '/wiki//Foo',
+                               [ 'title' => '/Foo' ]
+                       ],
+                       'Double slash in middle of $1' => [
+                               '/wiki/$1',
+                               '/wiki/.hack//SIGN',
+                               [ 'title' => '.hack//SIGN' ]
+                       ],
+                       'Dots removed 1' => [
+                               '/wiki/$1',
+                               '/x/../wiki/Foo',
+                               [ 'title' => 'Foo' ]
+                       ],
+                       'Dots removed 2' => [
+                               '/wiki/$1',
+                               '/./wiki/Foo',
+                               [ 'title' => 'Foo' ]
+                       ],
+                       'Dots retained 1' => [
+                               '/wiki/$1',
+                               '/wiki/../wiki/Foo',
+                               [ 'title' => '../wiki/Foo' ]
+                       ],
+                       'Dots retained 2' => [
+                               '/wiki/$1',
+                               '/wiki/./Foo',
+                               [ 'title' => './Foo' ]
+                       ],
+                       'Triple slash' => [
+                               '/wiki/$1',
+                               '///wiki/Foo',
+                               [ 'title' => 'Foo' ]
+                       ],
+                       // '..' only traverses one slash, see e.g. RFC 3986
+                       'Dots traversing double slash 1' => [
+                               '/wiki/$1',
+                               '/a//b/../../wiki/Foo',
+                               []
+                       ],
+                       'Dots traversing double slash 2' => [
+                               '/wiki/$1',
+                               '/a//b/../../../wiki/Foo',
+                               [ 'title' => 'Foo' ]
+                       ],
+               ];
 
-       /**
-        * Test the handling of key based arrays with a url parameter
-        */
-       public function testKeyParameter() {
-               $router = new PathRouter;
-               $router->add( [ 'edit' => "/edit/$1" ], [ 'action' => '$key' ] );
-               $matches = $router->parse( "/edit/Foo" );
-               $this->assertEquals( $matches, [ 'title' => "Foo", 'action' => 'edit' ] );
-       }
+               // Make sure the router doesn't break on special characters like $ used in regexp replacements
+               foreach ( [ "$", "$1", "\\", "\\$1" ] as $char ) {
+                       $tests["Regexp character $char"] = [
+                               "/wiki/$1",
+                               "/wiki/$char",
+                               [ 'title' => "$char" ]
+                       ];
+               }
 
-       /**
-        * Test the handling of $2 inside paths
-        */
-       public function testAdditionalParameter() {
-               // Basic $2
-               $router = new PathRouter;
-               $router->add( '/$2/$1', [ 'test' => '$2' ] );
-               $matches = $router->parse( "/asdf/Foo" );
-               $this->assertEquals( $matches, [ 'title' => "Foo", 'test' => 'asdf' ] );
-       }
+               $tests += [
+                       // Make sure the router handles characters like +&() properly
+                       "Special characters" => [
+                               "/wiki/$1",
+                               "/wiki/Plus+And&Dollar\\Stuff();[]{}*",
+                               [ 'title' => "Plus+And&Dollar\\Stuff();[]{}*" ],
+                       ],
 
-       /**
-        * Test additional restricted value parameter
-        */
-       public function testRestrictedValue() {
-               $router = new PathRouter;
-               $router->add( '/$2/$1',
-                       [ 'test' => '$2' ],
-                       [ '$2' => [ 'a', 'b' ] ]
-               );
-               $router->add( '/$2/$1',
-                       [ 'test2' => '$2' ],
-                       [ '$2' => 'c' ]
-               );
-               $router->add( '/$1' );
+                       // Make sure the router handles unicode characters correctly
+                       "Unicode 1" => [
+                               "/wiki/$1",
+                               "/wiki/Spécial:Modifications_récentes" ,
+                               [ 'title' => "Spécial:Modifications_récentes" ],
+                       ],
 
-               $matches = $router->parse( "/asdf/Foo" );
-               $this->assertEquals( $matches, [ 'title' => "asdf/Foo" ] );
+                       "Unicode 2" => [
+                               "/wiki/$1",
+                               "/wiki/Sp%C3%A9cial:Modifications_r%C3%A9centes",
+                               [ 'title' => "Spécial:Modifications_récentes" ],
+                       ]
+               ];
 
-               $matches = $router->parse( "/a/Foo" );
-               $this->assertEquals( $matches, [ 'title' => "Foo", 'test' => 'a' ] );
+               // Ensure the router doesn't choke on long paths.
+               $lorem = "Lorem_ipsum_dolor_sit_amet,_consectetur_adipisicing_elit,_sed_do_eiusmod_" .
+                       "tempor_incididunt_ut_labore_et_dolore_magna_aliqua._Ut_enim_ad_minim_veniam,_quis_" .
+                        "nostrud_exercitation_ullamco_laboris_nisi_ut_aliquip_ex_ea_commodo_consequat._" .
+                        "Duis_aute_irure_dolor_in_reprehenderit_in_voluptate_velit_esse_cillum_dolore_" .
+                        "eu_fugiat_nulla_pariatur._Excepteur_sint_occaecat_cupidatat_non_proident,_sunt_" .
+                        "in_culpa_qui_officia_deserunt_mollit_anim_id_est_laborum.";
 
-               $matches = $router->parse( "/c/Foo" );
-               $this->assertEquals( $matches, [ 'title' => "Foo", 'test2' => 'c' ] );
-       }
+               $tests += [
+                       "Long path" => [
+                               "/wiki/$1",
+                               "/wiki/$lorem",
+                               [ 'title' => $lorem ]
+                       ],
 
-       public function callbackForTest( &$matches, $data ) {
-               $matches['x'] = $data['$1'];
-               $matches['foo'] = $data['foo'];
-       }
+                       // Ensure that the php passed site of parameter values are not urldecoded
+                       "Pattern urlencoding" => [
+                               [ [ 'path' => "/wiki/$1", 'params' => [ 'title' => '%20:$1' ] ] ],
+                               "/wiki/Foo",
+                               [ 'title' => '%20:Foo' ]
+                       ],
 
-       public function testCallback() {
-               $router = new PathRouter;
-               $router->add( "/$1",
-                       [ 'a' => 'b', 'data:foo' => 'bar' ],
-                       [ 'callback' => [ $this, 'callbackForTest' ] ]
-               );
-               $matches = $router->parse( '/Foo' );
-               $this->assertEquals( $matches, [
-                       'title' => "Foo",
-                       'x' => 'Foo',
-                       'a' => 'b',
-                       'foo' => 'bar'
-               ] );
+                       // Ensure that raw parameter values do not have any variable replacements or urldecoding
+                       "Raw param value" => [
+                               [ [ 'path' => "/wiki/$1", 'params' => [ 'title' => [ 'value' => 'bar%20$1' ] ] ] ],
+                               "/wiki/Foo",
+                               [ 'title' => 'bar%20$1' ]
+                       ]
+               ];
+
+               return $tests;
        }
 
        /**
-        * Test to ensure that matches are not made if a parameter expects nonexistent input
+        * Test path parsing
+        * @dataProvider provideParse
         */
-       public function testFail() {
+       public function testParse( $patterns, $path, $expected ) {
+               $patterns = (array)$patterns;
+
                $router = new PathRouter;
-               $router->add( "/wiki/$1", [ 'title' => "$1$2" ] );
-               $matches = $router->parse( "/wiki/A" );
-               $this->assertEquals( [], $matches );
+               foreach ( $patterns as $pattern ) {
+                       if ( is_array( $pattern ) ) {
+                               $router->add( $pattern['path'], $pattern['params'] ?? [],
+                                       $pattern['options'] ?? [] );
+                       } else {
+                               $router->add( $pattern );
+                       }
+               }
+               $matches = $router->parse( $path );
+               $this->assertEquals( $matches, $expected );
+       }
+
+       public static function callbackForTest( &$matches, $data ) {
+               $matches['x'] = $data['$1'];
+               $matches['foo'] = $data['foo'];
+       }
+
+       public static function provideWeight() {
+               return [
+                       [ '/Foo', [ 'title' => 'Foo' ] ],
+                       [ '/Bar', [ 'ping' => 'pong' ] ],
+                       [ '/Baz', [ 'marco' => 'polo' ] ],
+                       [ '/asdf-foo', [ 'title' => 'qwerty-foo' ] ],
+                       [ '/qwerty-bar', [ 'title' => 'asdf-bar' ] ],
+                       [ '/a/Foo', [ 'title' => 'Foo' ] ],
+                       [ '/asdf/Foo', [ 'title' => 'Foo' ] ],
+                       [ '/qwerty/Foo', [ 'title' => 'Foo', 'qwerty' => 'qwerty' ] ],
+                       [ '/baz/Foo', [ 'title' => 'Foo', 'unrestricted' => 'baz' ] ],
+                       [ '/y/Foo', [ 'title' => 'Foo', 'restricted-to-y' => 'y' ] ],
+               ];
        }
 
        /**
         * Test to ensure weight of paths is handled correctly
+        * @dataProvider provideWeight
         */
-       public function testWeight() {
+       public function testWeight( $path, $expected ) {
                $router = new PathRouter;
                $router->addStrict( "/Bar", [ 'ping' => 'pong' ] );
                $router->add( "/asdf-$1", [ 'title' => 'qwerty-$1' ] );
@@ -158,112 +320,6 @@ class PathRouterTest extends MediaWikiTestCase {
                $router->add( [ 'qwerty' => "/qwerty/$1" ], [ 'qwerty' => '$key' ] );
                $router->add( "/$2/$1", [ 'restricted-to-y' => '$2' ], [ '$2' => 'y' ] );
 
-               foreach (
-                       [
-                               '/Foo' => [ 'title' => 'Foo' ],
-                               '/Bar' => [ 'ping' => 'pong' ],
-                               '/Baz' => [ 'marco' => 'polo' ],
-                               '/asdf-foo' => [ 'title' => 'qwerty-foo' ],
-                               '/qwerty-bar' => [ 'title' => 'asdf-bar' ],
-                               '/a/Foo' => [ 'title' => 'Foo' ],
-                               '/asdf/Foo' => [ 'title' => 'Foo' ],
-                               '/qwerty/Foo' => [ 'title' => 'Foo', 'qwerty' => 'qwerty' ],
-                               '/baz/Foo' => [ 'title' => 'Foo', 'unrestricted' => 'baz' ],
-                               '/y/Foo' => [ 'title' => 'Foo', 'restricted-to-y' => 'y' ],
-                       ] as $path => $result
-               ) {
-                       $this->assertEquals( $router->parse( $path ), $result );
-               }
-       }
-
-       /**
-        * Make sure the router handles titles like Special:Recentchanges correctly
-        */
-       public function testSpecial() {
-               $matches = $this->basicRouter->parse( "/wiki/Special:Recentchanges" );
-               $this->assertEquals( $matches, [ 'title' => "Special:Recentchanges" ] );
-       }
-
-       /**
-        * Make sure the router decodes urlencoding properly
-        */
-       public function testUrlencoding() {
-               $matches = $this->basicRouter->parse( "/wiki/Title_With%20Space" );
-               $this->assertEquals( $matches, [ 'title' => "Title_With Space" ] );
-       }
-
-       public static function provideRegexpChars() {
-               return [
-                       [ "$" ],
-                       [ "$1" ],
-                       [ "\\" ],
-                       [ "\\$1" ],
-               ];
-       }
-
-       /**
-        * Make sure the router doesn't break on special characters like $ used in regexp replacements
-        * @dataProvider provideRegexpChars
-        */
-       public function testRegexpChars( $char ) {
-               $matches = $this->basicRouter->parse( "/wiki/$char" );
-               $this->assertEquals( $matches, [ 'title' => "$char" ] );
-       }
-
-       /**
-        * Make sure the router handles characters like +&() properly
-        */
-       public function testCharacters() {
-               $matches = $this->basicRouter->parse( "/wiki/Plus+And&Dollar\\Stuff();[]{}*" );
-               $this->assertEquals( $matches, [ 'title' => "Plus+And&Dollar\\Stuff();[]{}*" ] );
-       }
-
-       /**
-        * Make sure the router handles unicode characters correctly
-        * @depends testSpecial
-        * @depends testUrlencoding
-        * @depends testCharacters
-        */
-       public function testUnicode() {
-               $matches = $this->basicRouter->parse( "/wiki/Spécial:Modifications_récentes" );
-               $this->assertEquals( $matches, [ 'title' => "Spécial:Modifications_récentes" ] );
-
-               $matches = $this->basicRouter->parse( "/wiki/Sp%C3%A9cial:Modifications_r%C3%A9centes" );
-               $this->assertEquals( $matches, [ 'title' => "Spécial:Modifications_récentes" ] );
-       }
-
-       /**
-        * Ensure the router doesn't choke on long paths.
-        */
-       public function testLength() {
-               // phpcs:disable Generic.Files.LineLength
-               $matches = $this->basicRouter->parse(
-                       "/wiki/Lorem_ipsum_dolor_sit_amet,_consectetur_adipisicing_elit,_sed_do_eiusmod_tempor_incididunt_ut_labore_et_dolore_magna_aliqua._Ut_enim_ad_minim_veniam,_quis_nostrud_exercitation_ullamco_laboris_nisi_ut_aliquip_ex_ea_commodo_consequat._Duis_aute_irure_dolor_in_reprehenderit_in_voluptate_velit_esse_cillum_dolore_eu_fugiat_nulla_pariatur._Excepteur_sint_occaecat_cupidatat_non_proident,_sunt_in_culpa_qui_officia_deserunt_mollit_anim_id_est_laborum."
-               );
-               $this->assertEquals(
-                       $matches,
-                       [ 'title' => "Lorem_ipsum_dolor_sit_amet,_consectetur_adipisicing_elit,_sed_do_eiusmod_tempor_incididunt_ut_labore_et_dolore_magna_aliqua._Ut_enim_ad_minim_veniam,_quis_nostrud_exercitation_ullamco_laboris_nisi_ut_aliquip_ex_ea_commodo_consequat._Duis_aute_irure_dolor_in_reprehenderit_in_voluptate_velit_esse_cillum_dolore_eu_fugiat_nulla_pariatur._Excepteur_sint_occaecat_cupidatat_non_proident,_sunt_in_culpa_qui_officia_deserunt_mollit_anim_id_est_laborum." ]
-               );
-               // phpcs:enable
-       }
-
-       /**
-        * Ensure that the php passed site of parameter values are not urldecoded
-        */
-       public function testPatternUrlencoding() {
-               $router = new PathRouter;
-               $router->add( "/wiki/$1", [ 'title' => '%20:$1' ] );
-               $matches = $router->parse( "/wiki/Foo" );
-               $this->assertEquals( $matches, [ 'title' => '%20:Foo' ] );
-       }
-
-       /**
-        * Ensure that raw parameter values do not have any variable replacements or urldecoding
-        */
-       public function testRawParamValue() {
-               $router = new PathRouter;
-               $router->add( "/wiki/$1", [ 'title' => [ 'value' => 'bar%20$1' ] ] );
-               $matches = $router->parse( "/wiki/Foo" );
-               $this->assertEquals( $matches, [ 'title' => 'bar%20$1' ] );
+               $this->assertEquals( $router->parse( $path ), $expected );
        }
 }
index ed34a8a..3bde5de 100644 (file)
@@ -211,7 +211,7 @@ class PrefixSearchTest extends MediaWikiLangTestCase {
        public function testSearch( array $case ) {
                $this->searchProvision( null );
 
-               $namespaces = isset( $case['namespaces'] ) ? $case['namespaces'] : [];
+               $namespaces = $case['namespaces'] ?? [];
 
                if ( wfGetDB( DB_REPLICA )->getType() === 'postgres' ) {
                        // Postgres will sort lexicographically on utf8 code units (" " before "/")
@@ -235,7 +235,7 @@ class PrefixSearchTest extends MediaWikiLangTestCase {
        public function testSearchWithOffset( array $case ) {
                $this->searchProvision( null );
 
-               $namespaces = isset( $case['namespaces'] ) ? $case['namespaces'] : [];
+               $namespaces = $case['namespaces'] ?? [];
 
                $searcher = new StringPrefixSearch;
                $results = $searcher->search( $case['query'], 3, $namespaces, 1 );
diff --git a/tests/phpunit/includes/RevisionContentHandlerDbTest.php b/tests/phpunit/includes/RevisionContentHandlerDbTest.php
deleted file mode 100644 (file)
index fa0153d..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-<?php
-
-/**
- * @group Database
- * @group medium
- * @group ContentHandler
- */
-class RevisionContentHandlerDbTest extends RevisionDbTestBase {
-
-       protected function getContentHandlerUseDB() {
-               return true;
-       }
-
-}
index 5de34d1..e17f855 100644 (file)
@@ -43,9 +43,25 @@ abstract class RevisionDbTestBase extends MediaWikiTestCase {
                );
        }
 
+       protected function addCoreDBData() {
+               // Blank out. This would fail with a modified schema, and we don't need it.
+       }
+
+       /**
+        * @return int
+        */
+       abstract protected function getMcrMigrationStage();
+
+       /**
+        * @return string[]
+        */
+       abstract protected function getMcrTablesToReset();
+
        protected function setUp() {
                global $wgContLang;
 
+               $this->tablesUsed += $this->getMcrTablesToReset();
+
                parent::setUp();
 
                $this->mergeMwGlobalArrayValue(
@@ -72,11 +88,17 @@ abstract class RevisionDbTestBase extends MediaWikiTestCase {
                );
 
                $this->setMwGlobals( 'wgContentHandlerUseDB', $this->getContentHandlerUseDB() );
+               $this->setMwGlobals(
+                       'wgMultiContentRevisionSchemaMigrationStage',
+                       $this->getMcrMigrationStage()
+               );
 
                MWNamespace::clearCaches();
                // Reset namespace cache
                $wgContLang->resetNamespaces();
 
+               $this->overrideMwServices();
+
                if ( !$this->testPage ) {
                        /**
                         * We have to create a new page for each subclass as the page creation may result
@@ -244,7 +266,6 @@ abstract class RevisionDbTestBase extends MediaWikiTestCase {
                        [
                                'rev_id',
                                'rev_page',
-                               'rev_text_id',
                                'rev_minor_edit',
                                'rev_deleted',
                                'rev_len',
@@ -255,7 +276,6 @@ abstract class RevisionDbTestBase extends MediaWikiTestCase {
                        [ [
                                strval( $rev->getId() ),
                                strval( $this->testPage->getId() ),
-                               strval( $textId ),
                                '0',
                                '0',
                                '13',
@@ -265,19 +285,52 @@ abstract class RevisionDbTestBase extends MediaWikiTestCase {
                );
        }
 
+       public function provideInsertOn_exceptionOnIncomplete() {
+               $content = new TextContent( '' );
+               $user = User::newFromName( 'Foo' );
+
+               yield 'no parent' => [
+                       [
+                               'content' => $content,
+                               'comment' => 'test',
+                               'user' => $user,
+                       ],
+                       IncompleteRevisionException::class,
+                       "rev_page field must not be 0!"
+               ];
+
+               yield 'no comment' => [
+                       [
+                               'content' => $content,
+                               'page' => 7,
+                               'user' => $user,
+                       ],
+                       IncompleteRevisionException::class,
+                       "comment must not be NULL!"
+               ];
+
+               yield 'no content' => [
+                       [
+                               'comment' => 'test',
+                               'page' => 7,
+                               'user' => $user,
+                       ],
+                       IncompleteRevisionException::class,
+                       "Uninitialized field: content_address" // XXX: message may change
+               ];
+       }
+
        /**
+        * @dataProvider provideInsertOn_exceptionOnIncomplete
         * @covers Revision::insertOn
         */
-       public function testInsertOn_exceptionOnNoPage() {
+       public function testInsertOn_exceptionOnIncomplete( $array, $expException, $expMessage ) {
                // If an ExternalStore is set don't use it.
                $this->setMwGlobals( 'wgDefaultExternalStore', false );
-               $this->setExpectedException(
-                       IncompleteRevisionException::class,
-                       "rev_page field must not be 0!"
-               );
+               $this->setExpectedException( $expException, $expMessage );
 
                $title = Title::newFromText( 'Nonexistant-' . __METHOD__ );
-               $rev = new Revision( [], 0, $title );
+               $rev = new Revision( $array, 0, $title );
 
                $rev->insertOn( wfGetDB( DB_MASTER ) );
        }
@@ -392,6 +445,9 @@ abstract class RevisionDbTestBase extends MediaWikiTestCase {
                        $services->getService( '_SqlBlobStore' ),
                        $services->getMainWANObjectCache(),
                        $services->getCommentStore(),
+                       $services->getContentModelStore(),
+                       $services->getSlotRoleStore(),
+                       $this->getMcrMigrationStage(),
                        $services->getActorMigration()
                );
 
@@ -897,7 +953,7 @@ abstract class RevisionDbTestBase extends MediaWikiTestCase {
                $rev = new Revision( [
                        'page' => $this->testPage->getId(),
                        'content_model' => $this->testPage->getContentModel(),
-                       'text_id' => 123456789, // not in the test DB
+                       'id' => 123456789, // not in the test DB
                ] );
 
                Wikimedia\suppressWarnings(); // bad text_id will trigger a warning.
@@ -1346,6 +1402,7 @@ abstract class RevisionDbTestBase extends MediaWikiTestCase {
         */
        public function testNewKnownCurrent() {
                // Setup the services
+               $this->resetGlobalServices();
                $cache = new WANObjectCache( [ 'cache' => new HashBagOStuff() ] );
                $this->setService( 'MainWANObjectCache', $cache );
                $db = wfGetDB( DB_MASTER );
@@ -1355,7 +1412,8 @@ abstract class RevisionDbTestBase extends MediaWikiTestCase {
                $rev = $this->testPage->getRevision();
 
                // Clear any previous cache for the revision during creation
-               $key = $cache->makeGlobalKey( 'revision-row-1.29',
+               $key = $cache->makeGlobalKey(
+                       RevisionStore::ROW_CACHE_KEY,
                        $db->getDomainID(),
                        $rev->getPage(),
                        $rev->getId()
diff --git a/tests/phpunit/includes/RevisionMcrDbTest.php b/tests/phpunit/includes/RevisionMcrDbTest.php
new file mode 100644 (file)
index 0000000..3c30efe
--- /dev/null
@@ -0,0 +1,27 @@
+<?php
+use MediaWiki\Tests\Storage\McrSchemaOverride;
+
+/**
+ * Tests Revision against the MCR DB schema after schema migration.
+ *
+ * @covers Revision
+ *
+ * @group Revision
+ * @group Storage
+ * @group ContentHandler
+ * @group Database
+ * @group medium
+ */
+class RevisionMcrDbTest extends RevisionDbTestBase {
+
+       use McrSchemaOverride;
+
+       public function setUp() {
+               parent::setUp();
+       }
+
+       protected function getContentHandlerUseDB() {
+               return true;
+       }
+
+}
diff --git a/tests/phpunit/includes/RevisionMcrReadNewDbTest.php b/tests/phpunit/includes/RevisionMcrReadNewDbTest.php
new file mode 100644 (file)
index 0000000..1054b7d
--- /dev/null
@@ -0,0 +1,23 @@
+<?php
+use MediaWiki\Tests\Storage\McrReadNewSchemaOverride;
+
+/**
+ * Tests Revision against the intermediate MCR DB schema for use during schema migration.
+ *
+ * @covers Revision
+ *
+ * @group Revision
+ * @group Storage
+ * @group ContentHandler
+ * @group Database
+ * @group medium
+ */
+class RevisionMcrReadNewDbTest extends RevisionDbTestBase {
+
+       use McrReadNewSchemaOverride;
+
+       protected function getContentHandlerUseDB() {
+               return true;
+       }
+
+}
diff --git a/tests/phpunit/includes/RevisionMcrWriteBothDbTest.php b/tests/phpunit/includes/RevisionMcrWriteBothDbTest.php
new file mode 100644 (file)
index 0000000..436b379
--- /dev/null
@@ -0,0 +1,23 @@
+<?php
+use MediaWiki\Tests\Storage\McrWriteBothSchemaOverride;
+
+/**
+ * Tests Revision against the intermediate MCR DB schema for use during schema migration.
+ *
+ * @covers Revision
+ *
+ * @group Revision
+ * @group Storage
+ * @group ContentHandler
+ * @group Database
+ * @group medium
+ */
+class RevisionMcrWriteBothDbTest extends RevisionDbTestBase {
+
+       use McrWriteBothSchemaOverride;
+
+       protected function getContentHandlerUseDB() {
+               return true;
+       }
+
+}
diff --git a/tests/phpunit/includes/RevisionNoContentHandlerDbTest.php b/tests/phpunit/includes/RevisionNoContentHandlerDbTest.php
deleted file mode 100644 (file)
index c980a48..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-<?php
-
-/**
- * @group Database
- * @group medium
- * @group ContentHandler
- */
-class RevisionNoContentHandlerDbTest extends RevisionDbTestBase {
-
-       protected function getContentHandlerUseDB() {
-               return false;
-       }
-
-}
diff --git a/tests/phpunit/includes/RevisionNoContentModelDbTest.php b/tests/phpunit/includes/RevisionNoContentModelDbTest.php
new file mode 100644 (file)
index 0000000..7923b22
--- /dev/null
@@ -0,0 +1,23 @@
+<?php
+use MediaWiki\Tests\Storage\PreMcrSchemaOverride;
+
+/**
+ * Tests Revision against the pre-MCR, pre ContentHandler DB schema.
+ *
+ * @covers Revision
+ *
+ * @group Revision
+ * @group Storage
+ * @group ContentHandler
+ * @group Database
+ * @group medium
+ */
+class RevisionNoContentModelDbTest extends RevisionDbTestBase {
+
+       use PreMcrSchemaOverride;
+
+       protected function getContentHandlerUseDB() {
+               return false;
+       }
+
+}
diff --git a/tests/phpunit/includes/RevisionPreMcrDbTest.php b/tests/phpunit/includes/RevisionPreMcrDbTest.php
new file mode 100644 (file)
index 0000000..90f1140
--- /dev/null
@@ -0,0 +1,23 @@
+<?php
+use MediaWiki\Tests\Storage\PreMcrSchemaOverride;
+
+/**
+ * Tests Revision against the pre-MCR DB schema.
+ *
+ * @covers Revision
+ *
+ * @group Revision
+ * @group Storage
+ * @group ContentHandler
+ * @group Database
+ * @group medium
+ */
+class RevisionPreMcrDbTest extends RevisionDbTestBase {
+
+       use PreMcrSchemaOverride;
+
+       protected function getContentHandlerUseDB() {
+               return true;
+       }
+
+}
index ab067a4..7ef1182 100644 (file)
@@ -17,6 +17,11 @@ use Wikimedia\Rdbms\LoadBalancer;
  */
 class RevisionTest extends MediaWikiTestCase {
 
+       public function setUp() {
+               parent::setUp();
+               $this->setMwGlobals( 'wgMultiContentRevisionSchemaMigrationStage', MIGRATION_OLD );
+       }
+
        public function provideConstructFromArray() {
                yield 'with text' => [
                        [
@@ -154,16 +159,15 @@ class RevisionTest extends MediaWikiTestCase {
                                'content' => new WikitextContent( 'GOAT' ),
                                'text_id' => 'someid',
                        ],
-                       new MWException( "Text already stored in external store (id someid), " .
-                               "can't serialize content object" )
+                       new MWException( 'Text already stored in external store (id someid),' )
                ];
                yield 'with bad content object (class)' => [
                        [ 'content' => new stdClass() ],
-                       new MWException( 'content field must contain a Content object.' )
+                       new MWException( 'content field must contain a Content object' )
                ];
                yield 'with bad content object (string)' => [
                        [ 'content' => 'ImAGoat' ],
-                       new MWException( 'content field must contain a Content object.' )
+                       new MWException( 'content field must contain a Content object' )
                ];
                yield 'bad row format' => [
                        'imastring, not a row',
@@ -439,6 +443,31 @@ class RevisionTest extends MediaWikiTestCase {
                $this->testGetRevisionText( $expected, $rowData );
        }
 
+       public function provideGetRevisionTextWithZlibExtension_badData() {
+               yield 'Generic gzip test' => [
+                       'This is a small goat of revision text.',
+                       [
+                               'old_flags' => 'gzip',
+                               'old_text' => 'DEAD BEEF',
+                       ],
+               ];
+       }
+
+       /**
+        * @covers Revision::getRevisionText
+        * @dataProvider provideGetRevisionTextWithZlibExtension_badData
+        */
+       public function testGetRevisionWithZlibExtension_badData( $expected, $rowData ) {
+               $this->checkPHPExtension( 'zlib' );
+               Wikimedia\suppressWarnings();
+               $this->assertFalse(
+                       Revision::getRevisionText(
+                               (object)$rowData
+                       )
+               );
+               Wikimedia\suppressWarnings( true );
+       }
+
        private function getWANObjectCache() {
                return new WANObjectCache( [ 'cache' => new HashBagOStuff() ] );
        }
@@ -488,6 +517,9 @@ class RevisionTest extends MediaWikiTestCase {
                        $this->getBlobStore(),
                        $cache,
                        MediaWikiServices::getInstance()->getCommentStore(),
+                       MediaWikiServices::getInstance()->getContentModelStore(),
+                       MediaWikiServices::getInstance()->getSlotRoleStore(),
+                       MIGRATION_OLD,
                        MediaWikiServices::getInstance()->getActorMigration()
                );
                return $blobStore;
@@ -802,6 +834,7 @@ class RevisionTest extends MediaWikiTestCase {
        public function testGetRevisionText_external_returnsFalseWhenNotEnoughUrlParts(
                $text
        ) {
+               Wikimedia\suppressWarnings();
                $this->assertFalse(
                        Revision::getRevisionText(
                                (object)[
@@ -810,6 +843,7 @@ class RevisionTest extends MediaWikiTestCase {
                                ]
                        )
                );
+               Wikimedia\suppressWarnings( true );
        }
 
        /**
@@ -861,7 +895,12 @@ class RevisionTest extends MediaWikiTestCase {
                        )
                );
 
-               $cacheKey = $cache->makeKey( 'revisiontext', 'textid', 'tt:7777' );
+               $cacheKey = $cache->makeGlobalKey(
+                       'BlobStore',
+                       'address',
+                       $lb->getLocalDomainID(),
+                       'tt:7777'
+               );
                $this->assertSame( 'AAAABBAAA', $cache->get( $cacheKey ) );
        }
 
@@ -1156,12 +1195,62 @@ class RevisionTest extends MediaWikiTestCase {
                $revisionStore = $this->getRevisionStore();
                $revisionStore->setContentHandlerUseDB( $globals['wgContentHandlerUseDB'] );
                $this->setService( 'RevisionStore', $revisionStore );
-               $this->assertEquals(
-                       $expected,
-                       Revision::getArchiveQueryInfo()
+
+               $queryInfo = Revision::getArchiveQueryInfo();
+
+               $this->assertArrayEqualsIgnoringIntKeyOrder(
+                       $expected['tables'],
+                       $queryInfo['tables']
+               );
+               $this->assertArrayEqualsIgnoringIntKeyOrder(
+                       $expected['fields'],
+                       $queryInfo['fields']
+               );
+               $this->assertArrayEqualsIgnoringIntKeyOrder(
+                       $expected['joins'],
+                       $queryInfo['joins']
                );
        }
 
+       /**
+        * Assert that the two arrays passed are equal, ignoring the order of the values that integer
+        * keys.
+        *
+        * Note: Failures of this assertion can be slightly confusing as the arrays are actually
+        * split into a string key array and an int key array before assertions occur.
+        *
+        * @param array $expected
+        * @param array $actual
+        */
+       private function assertArrayEqualsIgnoringIntKeyOrder( array $expected, array $actual ) {
+               $this->objectAssociativeSort( $expected );
+               $this->objectAssociativeSort( $actual );
+
+               // Separate the int key values from the string key values so that assertion failures are
+               // easier to understand.
+               $expectedIntKeyValues = [];
+               $actualIntKeyValues = [];
+
+               // Remove all int keys and re add them at the end after sorting by value
+               // This will result in all int keys being in the same order with same ints at the end of
+               // the array
+               foreach ( $expected as $key => $value ) {
+                       if ( is_int( $key ) ) {
+                               unset( $expected[$key] );
+                               $expectedIntKeyValues[] = $value;
+                       }
+               }
+               foreach ( $actual as $key => $value ) {
+                       if ( is_int( $key ) ) {
+                               unset( $actual[$key] );
+                               $actualIntKeyValues[] = $value;
+                       }
+               }
+
+               $this->assertArrayEquals( $expected, $actual, false, true );
+               $this->assertArrayEquals( $expectedIntKeyValues, $actualIntKeyValues, false, true );
+       }
+
        public function provideGetQueryInfo() {
                yield 'wgContentHandlerUseDB false, opts none' => [
                        [
@@ -1391,9 +1480,19 @@ class RevisionTest extends MediaWikiTestCase {
                $revisionStore->setContentHandlerUseDB( $globals['wgContentHandlerUseDB'] );
                $this->setService( 'RevisionStore', $revisionStore );
 
-               $this->assertEquals(
-                       $expected,
-                       Revision::getQueryInfo( $options )
+               $queryInfo = Revision::getQueryInfo( $options );
+
+               $this->assertArrayEqualsIgnoringIntKeyOrder(
+                       $expected['tables'],
+                       $queryInfo['tables']
+               );
+               $this->assertArrayEqualsIgnoringIntKeyOrder(
+                       $expected['fields'],
+                       $queryInfo['fields']
+               );
+               $this->assertArrayEqualsIgnoringIntKeyOrder(
+                       $expected['joins'],
+                       $queryInfo['joins']
                );
        }
 
index 4747466..22495d0 100644 (file)
@@ -16,9 +16,8 @@ class SampleTest extends MediaWikiLangTestCase {
 
                // This sets the globals and will restore them automatically
                // after each test.
+               $this->setContentLang( 'en' );
                $this->setMwGlobals( [
-                       'wgContLang' => Language::factory( 'en' ),
-                       'wgLanguageCode' => 'en',
                        'wgCapitalLinks' => true,
                ] );
        }
diff --git a/tests/phpunit/includes/Storage/DerivedPageDataUpdaterTest.php b/tests/phpunit/includes/Storage/DerivedPageDataUpdaterTest.php
new file mode 100644 (file)
index 0000000..3a1f078
--- /dev/null
@@ -0,0 +1,746 @@
+<?php
+
+namespace MediaWiki\Tests\Storage;
+
+use CommentStoreComment;
+use Content;
+use LinksUpdate;
+use MediaWiki\MediaWikiServices;
+use MediaWiki\Storage\DerivedPageDataUpdater;
+use MediaWiki\Storage\MutableRevisionRecord;
+use MediaWiki\Storage\MutableRevisionSlots;
+use MediaWiki\Storage\RevisionRecord;
+use MediaWiki\Storage\RevisionSlotsUpdate;
+use MediaWiki\Storage\SlotRecord;
+use MediaWikiTestCase;
+use Title;
+use User;
+use Wikimedia\TestingAccessWrapper;
+use WikiPage;
+use WikitextContent;
+
+/**
+ * @group Database
+ *
+ * @covers MediaWiki\Storage\DerivedPageDataUpdater
+ */
+class DerivedPageDataUpdaterTest extends MediaWikiTestCase {
+
+       /**
+        * @param string $title
+        *
+        * @return Title
+        */
+       private function getTitle( $title ) {
+               return Title::makeTitleSafe( $this->getDefaultWikitextNS(), $title );
+       }
+
+       /**
+        * @param string|Title $title
+        *
+        * @return WikiPage
+        */
+       private function getPage( $title ) {
+               $title = ( $title instanceof Title ) ? $title : $this->getTitle( $title );
+
+               return WikiPage::factory( $title );
+       }
+
+       /**
+        * @param string|Title|WikiPage $page
+        *
+        * @return DerivedPageDataUpdater
+        */
+       private function getDerivedPageDataUpdater( $page, RevisionRecord $rec = null ) {
+               if ( is_string( $page ) || $page instanceof Title ) {
+                       $page = $this->getPage( $page );
+               }
+
+               $page = TestingAccessWrapper::newFromObject( $page );
+               return $page->getDerivedDataUpdater( null, $rec );
+       }
+
+       /**
+        * Creates a revision in the database.
+        *
+        * @param WikiPage $page
+        * @param $summary
+        * @param null|string|Content $content
+        *
+        * @return RevisionRecord|null
+        */
+       private function createRevision( WikiPage $page, $summary, $content = null ) {
+               $user = $this->getTestUser()->getUser();
+               $comment = CommentStoreComment::newUnsavedComment( $summary );
+
+               if ( !$content instanceof Content ) {
+                       $content = new WikitextContent( $content ?? $summary );
+               }
+
+               $this->getDerivedPageDataUpdater( $page ); // flush cached instance before.
+
+               $updater = $page->newPageUpdater( $user );
+               $updater->setContent( 'main', $content );
+               $rev = $updater->saveRevision( $comment );
+
+               $this->getDerivedPageDataUpdater( $page ); // flush cached instance after.
+               return $rev;
+       }
+
+       // TODO: test setArticleCountMethod() and isCountable();
+       // TODO: test isRedirect() and wasRedirect()
+
+       /**
+        * @covers \MediaWiki\Storage\DerivedPageDataUpdater::getCanonicalParserOptions()
+        */
+       public function testGetCanonicalParserOptions() {
+               global $wgContLang;
+
+               $user = $this->getTestUser()->getUser();
+               $page = $this->getPage( __METHOD__ );
+
+               $parentRev = $this->createRevision( $page, 'first' );
+
+               $mainContent = new WikitextContent( 'Lorem ipsum' );
+
+               $update = new RevisionSlotsUpdate();
+               $update->modifyContent( 'main', $mainContent );
+               $updater = $this->getDerivedPageDataUpdater( $page );
+               $updater->prepareContent( $user, $update, false );
+
+               $options1 = $updater->getCanonicalParserOptions();
+               $this->assertSame( $wgContLang, $options1->getUserLangObj() );
+
+               $speculativeId = call_user_func( $options1->getSpeculativeRevIdCallback(), $page->getTitle() );
+               $this->assertSame( $parentRev->getId() + 1, $speculativeId );
+
+               $rev = $this->makeRevision(
+                       $page->getTitle(),
+                       $update,
+                       $user,
+                       $parentRev->getId() + 7,
+                       $parentRev->getId()
+               );
+               $updater->prepareUpdate( $rev );
+
+               $options2 = $updater->getCanonicalParserOptions();
+               $this->assertNotSame( $options1, $options2 );
+
+               $currentRev = call_user_func( $options2->getCurrentRevisionCallback(), $page->getTitle() );
+               $this->assertSame( $rev->getId(), $currentRev->getId() );
+       }
+
+       /**
+        * @covers \MediaWiki\Storage\DerivedPageDataUpdater::grabCurrentRevision()
+        * @covers \MediaWiki\Storage\DerivedPageDataUpdater::pageExisted()
+        */
+       public function testGrabCurrentRevision() {
+               $page = $this->getPage( __METHOD__ );
+
+               $updater0 = $this->getDerivedPageDataUpdater( $page );
+               $this->assertNull( $updater0->grabCurrentRevision() );
+               $this->assertFalse( $updater0->pageExisted() );
+
+               $rev1 = $this->createRevision( $page, 'first' );
+               $updater1 = $this->getDerivedPageDataUpdater( $page );
+               $this->assertSame( $rev1->getId(), $updater1->grabCurrentRevision()->getId() );
+               $this->assertFalse( $updater0->pageExisted() );
+               $this->assertTrue( $updater1->pageExisted() );
+
+               $rev2 = $this->createRevision( $page, 'second' );
+               $updater2 = $this->getDerivedPageDataUpdater( $page );
+               $this->assertSame( $rev1->getId(), $updater1->grabCurrentRevision()->getId() );
+               $this->assertSame( $rev2->getId(), $updater2->grabCurrentRevision()->getId() );
+       }
+
+       /**
+        * @covers \MediaWiki\Storage\DerivedPageDataUpdater::prepareContent()
+        * @covers \MediaWiki\Storage\DerivedPageDataUpdater::isContentPrepared()
+        * @covers \MediaWiki\Storage\DerivedPageDataUpdater::pageExisted()
+        * @covers \MediaWiki\Storage\DerivedPageDataUpdater::isCreation()
+        * @covers \MediaWiki\Storage\DerivedPageDataUpdater::isChange()
+        * @covers \MediaWiki\Storage\DerivedPageDataUpdater::getSlots()
+        * @covers \MediaWiki\Storage\DerivedPageDataUpdater::getRawSlot()
+        * @covers \MediaWiki\Storage\DerivedPageDataUpdater::getRawContent()
+        * @covers \MediaWiki\Storage\DerivedPageDataUpdater::getModifiedSlotRoles()
+        * @covers \MediaWiki\Storage\DerivedPageDataUpdater::getTouchedSlotRoles()
+        * @covers \MediaWiki\Storage\DerivedPageDataUpdater::getSlotParserOutput()
+        * @covers \MediaWiki\Storage\DerivedPageDataUpdater::getCanonicalParserOutput()
+        */
+       public function testPrepareContent() {
+               $user = $this->getTestUser()->getUser();
+               $updater = $this->getDerivedPageDataUpdater( __METHOD__ );
+
+               $this->assertFalse( $updater->isContentPrepared() );
+
+               // TODO: test stash
+               // TODO: MCR: Test multiple slots. Test slot removal.
+               $mainContent = new WikitextContent( 'first [[main]] ~~~' );
+               $auxContent = new WikitextContent( 'inherited ~~~ content' );
+               $auxSlot = SlotRecord::newSaved(
+                       10, 7, 'tt:7',
+                       SlotRecord::newUnsaved( 'aux', $auxContent )
+               );
+
+               $update = new RevisionSlotsUpdate();
+               $update->modifyContent( 'main', $mainContent );
+               $update->modifySlot( SlotRecord::newInherited( $auxSlot ) );
+               // TODO: MCR: test removing slots!
+
+               $updater->prepareContent( $user, $update, false );
+
+               // second be ok to call again with the same params
+               $updater->prepareContent( $user, $update, false );
+
+               $this->assertNull( $updater->grabCurrentRevision() );
+               $this->assertTrue( $updater->isContentPrepared() );
+               $this->assertFalse( $updater->isUpdatePrepared() );
+               $this->assertFalse( $updater->pageExisted() );
+               $this->assertTrue( $updater->isCreation() );
+               $this->assertTrue( $updater->isChange() );
+               $this->assertTrue( $updater->isContentPublic() );
+
+               $this->assertEquals( [ 'main', 'aux' ], $updater->getSlots()->getSlotRoles() );
+               $this->assertEquals( [ 'main' ], array_keys( $updater->getSlots()->getOriginalSlots() ) );
+               $this->assertEquals( [ 'aux' ], array_keys( $updater->getSlots()->getInheritedSlots() ) );
+               $this->assertEquals( [ 'main', 'aux' ], $updater->getModifiedSlotRoles() );
+               $this->assertEquals( [ 'main', 'aux' ], $updater->getTouchedSlotRoles() );
+
+               $mainSlot = $updater->getRawSlot( 'main' );
+               $this->assertInstanceOf( SlotRecord::class, $mainSlot );
+               $this->assertNotContains( '~~~', $mainSlot->getContent()->serialize(), 'PST should apply.' );
+               $this->assertContains( $user->getName(), $mainSlot->getContent()->serialize() );
+
+               $auxSlot = $updater->getRawSlot( 'aux' );
+               $this->assertInstanceOf( SlotRecord::class, $auxSlot );
+               $this->assertContains( '~~~', $auxSlot->getContent()->serialize(), 'No PST should apply.' );
+
+               $mainOutput = $updater->getCanonicalParserOutput();
+               $this->assertContains( 'first', $mainOutput->getText() );
+               $this->assertContains( '<a ', $mainOutput->getText() );
+               $this->assertNotEmpty( $mainOutput->getLinks() );
+
+               $canonicalOutput = $updater->getCanonicalParserOutput();
+               $this->assertContains( 'first', $canonicalOutput->getText() );
+               $this->assertContains( '<a ', $canonicalOutput->getText() );
+               $this->assertNotEmpty( $canonicalOutput->getLinks() );
+       }
+
+       /**
+        * @covers \MediaWiki\Storage\DerivedPageDataUpdater::prepareContent()
+        * @covers \MediaWiki\Storage\DerivedPageDataUpdater::pageExisted()
+        * @covers \MediaWiki\Storage\DerivedPageDataUpdater::isCreation()
+        * @covers \MediaWiki\Storage\DerivedPageDataUpdater::isChange()
+        */
+       public function testPrepareContentInherit() {
+               $user = $this->getTestUser()->getUser();
+               $page = $this->getPage( __METHOD__ );
+
+               $mainContent1 = new WikitextContent( 'first [[main]] ~~~' );
+               $mainContent2 = new WikitextContent( 'second' );
+
+               $this->createRevision( $page, 'first', $mainContent1 );
+
+               $update = new RevisionSlotsUpdate();
+               $update->modifyContent( 'main', $mainContent1 );
+               $updater1 = $this->getDerivedPageDataUpdater( $page );
+               $updater1->prepareContent( $user, $update, false );
+
+               $this->assertNotNull( $updater1->grabCurrentRevision() );
+               $this->assertTrue( $updater1->isContentPrepared() );
+               $this->assertTrue( $updater1->pageExisted() );
+               $this->assertFalse( $updater1->isCreation() );
+               $this->assertFalse( $updater1->isChange() );
+
+               // TODO: MCR: test inheritance from parent
+               $update = new RevisionSlotsUpdate();
+               $update->modifyContent( 'main', $mainContent2 );
+               $updater2 = $this->getDerivedPageDataUpdater( $page );
+               $updater2->prepareContent( $user, $update, false );
+
+               $this->assertFalse( $updater2->isCreation() );
+               $this->assertTrue( $updater2->isChange() );
+       }
+
+       // TODO: test failure of prepareContent() when called again...
+       // - with different user
+       // - with different update
+       // - after calling prepareUpdate()
+
+       /**
+        * @covers \MediaWiki\Storage\DerivedPageDataUpdater::prepareUpdate()
+        * @covers \MediaWiki\Storage\DerivedPageDataUpdater::isUpdatePrepared()
+        * @covers \MediaWiki\Storage\DerivedPageDataUpdater::isCreation()
+        * @covers \MediaWiki\Storage\DerivedPageDataUpdater::getSlots()
+        * @covers \MediaWiki\Storage\DerivedPageDataUpdater::getRawSlot()
+        * @covers \MediaWiki\Storage\DerivedPageDataUpdater::getRawContent()
+        * @covers \MediaWiki\Storage\DerivedPageDataUpdater::getModifiedSlotRoles()
+        * @covers \MediaWiki\Storage\DerivedPageDataUpdater::getTouchedSlotRoles()
+        * @covers \MediaWiki\Storage\DerivedPageDataUpdater::getSlotParserOutput()
+        * @covers \MediaWiki\Storage\DerivedPageDataUpdater::getCanonicalParserOutput()
+        */
+       public function testPrepareUpdate() {
+               $page = $this->getPage( __METHOD__ );
+
+               $mainContent1 = new WikitextContent( 'first [[main]] ~~~' );
+               $rev1 = $this->createRevision( $page, 'first', $mainContent1 );
+               $updater1 = $this->getDerivedPageDataUpdater( $page, $rev1 );
+
+               $options = []; // TODO: test *all* the options...
+               $updater1->prepareUpdate( $rev1, $options );
+
+               $this->assertTrue( $updater1->isUpdatePrepared() );
+               $this->assertTrue( $updater1->isContentPrepared() );
+               $this->assertTrue( $updater1->isCreation() );
+               $this->assertTrue( $updater1->isChange() );
+               $this->assertTrue( $updater1->isContentPublic() );
+
+               $this->assertEquals( [ 'main' ], $updater1->getSlots()->getSlotRoles() );
+               $this->assertEquals( [ 'main' ], array_keys( $updater1->getSlots()->getOriginalSlots() ) );
+               $this->assertEquals( [], array_keys( $updater1->getSlots()->getInheritedSlots() ) );
+               $this->assertEquals( [ 'main' ], $updater1->getModifiedSlotRoles() );
+               $this->assertEquals( [ 'main' ], $updater1->getTouchedSlotRoles() );
+
+               // TODO: MCR: test multiple slots, test slot removal!
+
+               $this->assertInstanceOf( SlotRecord::class, $updater1->getRawSlot( 'main' ) );
+               $this->assertNotContains( '~~~~', $updater1->getRawContent( 'main' )->serialize() );
+
+               $mainOutput = $updater1->getCanonicalParserOutput();
+               $this->assertContains( 'first', $mainOutput->getText() );
+               $this->assertContains( '<a ', $mainOutput->getText() );
+               $this->assertNotEmpty( $mainOutput->getLinks() );
+
+               $canonicalOutput = $updater1->getCanonicalParserOutput();
+               $this->assertContains( 'first', $canonicalOutput->getText() );
+               $this->assertContains( '<a ', $canonicalOutput->getText() );
+               $this->assertNotEmpty( $canonicalOutput->getLinks() );
+
+               $mainContent2 = new WikitextContent( 'second' );
+               $rev2 = $this->createRevision( $page, 'second', $mainContent2 );
+               $updater2 = $this->getDerivedPageDataUpdater( $page, $rev2 );
+
+               $options = []; // TODO: test *all* the options...
+               $updater2->prepareUpdate( $rev2, $options );
+
+               $this->assertFalse( $updater2->isCreation() );
+               $this->assertTrue( $updater2->isChange() );
+
+               $canonicalOutput = $updater2->getCanonicalParserOutput();
+               $this->assertContains( 'second', $canonicalOutput->getText() );
+       }
+
+       /**
+        * @covers \MediaWiki\Storage\DerivedPageDataUpdater::prepareUpdate()
+        */
+       public function testPrepareUpdateReusesParserOutput() {
+               $user = $this->getTestUser()->getUser();
+               $page = $this->getPage( __METHOD__ );
+
+               $mainContent1 = new WikitextContent( 'first [[main]] ~~~' );
+
+               $update = new RevisionSlotsUpdate();
+               $update->modifyContent( 'main', $mainContent1 );
+               $updater = $this->getDerivedPageDataUpdater( $page );
+               $updater->prepareContent( $user, $update, false );
+
+               $mainOutput = $updater->getSlotParserOutput( 'main' );
+               $canonicalOutput = $updater->getCanonicalParserOutput();
+
+               $rev = $this->createRevision( $page, 'first', $mainContent1 );
+
+               $options = []; // TODO: test *all* the options...
+               $updater->prepareUpdate( $rev, $options );
+
+               $this->assertTrue( $updater->isUpdatePrepared() );
+               $this->assertTrue( $updater->isContentPrepared() );
+
+               $this->assertSame( $mainOutput, $updater->getSlotParserOutput( 'main' ) );
+               $this->assertSame( $canonicalOutput, $updater->getCanonicalParserOutput() );
+       }
+
+       /**
+        * @covers \MediaWiki\Storage\DerivedPageDataUpdater::prepareUpdate()
+        * @covers \MediaWiki\Storage\DerivedPageDataUpdater::getSlotParserOutput()
+        */
+       public function testPrepareUpdateOutputReset() {
+               $user = $this->getTestUser()->getUser();
+               $page = $this->getPage( __METHOD__ );
+
+               $mainContent1 = new WikitextContent( 'first --{{REVISIONID}}--' );
+
+               $update = new RevisionSlotsUpdate();
+               $update->modifyContent( 'main', $mainContent1 );
+               $updater = $this->getDerivedPageDataUpdater( $page );
+               $updater->prepareContent( $user, $update, false );
+
+               $mainOutput = $updater->getSlotParserOutput( 'main' );
+               $canonicalOutput = $updater->getCanonicalParserOutput();
+
+               // prevent optimization on matching speculative ID
+               $mainOutput->setSpeculativeRevIdUsed( 0 );
+               $canonicalOutput->setSpeculativeRevIdUsed( 0 );
+
+               $rev = $this->createRevision( $page, 'first', $mainContent1 );
+
+               $options = []; // TODO: test *all* the options...
+               $updater->prepareUpdate( $rev, $options );
+
+               $this->assertTrue( $updater->isUpdatePrepared() );
+               $this->assertTrue( $updater->isContentPrepared() );
+
+               // ParserOutput objects should have been flushed.
+               $this->assertNotSame( $mainOutput, $updater->getSlotParserOutput( 'main' ) );
+               $this->assertNotSame( $canonicalOutput, $updater->getCanonicalParserOutput() );
+
+               $html = $updater->getCanonicalParserOutput()->getText();
+               $this->assertContains( '--' . $rev->getId() . '--', $html );
+
+               // TODO: MCR: ensure that when the main slot uses {{REVISIONID}} but another slot is
+               // updated, the main slot is still re-rendered!
+       }
+
+       // TODO: test failure of prepareUpdate() when called again with a different revision
+       // TODO: test failure of prepareUpdate() on inconsistency with prepareContent.
+
+       /**
+        * @covers \MediaWiki\Storage\DerivedPageDataUpdater::getPreparedEdit()
+        */
+       public function testGetPreparedEditAfterPrepareContent() {
+               $user = $this->getTestUser()->getUser();
+
+               $mainContent = new WikitextContent( 'first [[main]] ~~~' );
+               $update = new RevisionSlotsUpdate();
+               $update->modifyContent( 'main', $mainContent );
+
+               $updater = $this->getDerivedPageDataUpdater( __METHOD__ );
+               $updater->prepareContent( $user, $update, false );
+
+               $canonicalOutput = $updater->getCanonicalParserOutput();
+
+               $preparedEdit = $updater->getPreparedEdit();
+               $this->assertSame( $canonicalOutput->getCacheTime(), $preparedEdit->timestamp );
+               $this->assertSame( $canonicalOutput, $preparedEdit->output );
+               $this->assertSame( $mainContent, $preparedEdit->newContent );
+               $this->assertSame( $updater->getRawContent( 'main' ), $preparedEdit->pstContent );
+               $this->assertSame( $updater->getCanonicalParserOptions(), $preparedEdit->popts );
+               $this->assertSame( null, $preparedEdit->revid );
+       }
+
+       /**
+        * @covers \MediaWiki\Storage\DerivedPageDataUpdater::getPreparedEdit()
+        */
+       public function testGetPreparedEditAfterPrepareUpdate() {
+               $page = $this->getPage( __METHOD__ );
+
+               $mainContent = new WikitextContent( 'first [[main]] ~~~' );
+               $update = new MutableRevisionSlots();
+               $update->setContent( 'main', $mainContent );
+
+               $rev = $this->createRevision( $page, __METHOD__ );
+
+               $updater = $this->getDerivedPageDataUpdater( $page );
+               $updater->prepareUpdate( $rev );
+
+               $canonicalOutput = $updater->getCanonicalParserOutput();
+
+               $preparedEdit = $updater->getPreparedEdit();
+               $this->assertSame( $canonicalOutput->getCacheTime(), $preparedEdit->timestamp );
+               $this->assertSame( $canonicalOutput, $preparedEdit->output );
+               $this->assertSame( $updater->getRawContent( 'main' ), $preparedEdit->pstContent );
+               $this->assertSame( $updater->getCanonicalParserOptions(), $preparedEdit->popts );
+               $this->assertSame( $rev->getId(), $preparedEdit->revid );
+       }
+
+       public function testGetSecondaryDataUpdatesAfterPrepareContent() {
+               $user = $this->getTestUser()->getUser();
+               $page = $this->getPage( __METHOD__ );
+               $this->createRevision( $page, __METHOD__ );
+
+               $mainContent1 = new WikitextContent( 'first' );
+
+               $update = new RevisionSlotsUpdate();
+               $update->modifyContent( 'main', $mainContent1 );
+               $updater = $this->getDerivedPageDataUpdater( $page );
+               $updater->prepareContent( $user, $update, false );
+
+               $dataUpdates = $updater->getSecondaryDataUpdates();
+
+               // TODO: MCR: assert updates from all slots!
+               $this->assertNotEmpty( $dataUpdates );
+
+               $linksUpdates = array_filter( $dataUpdates, function ( $du ) {
+                       return $du instanceof LinksUpdate;
+               } );
+               $this->assertCount( 1, $linksUpdates );
+       }
+
+       /**
+        * Creates a dummy revision object without touching the database.
+        *
+        * @param Title $title
+        * @param RevisionSlotsUpdate $update
+        * @param User $user
+        * @param string $comment
+        * @param int $id
+        * @param int $parentId
+        *
+        * @return MutableRevisionRecord
+        */
+       private function makeRevision(
+               Title $title,
+               RevisionSlotsUpdate $update,
+               User $user,
+               $comment,
+               $id,
+               $parentId = 0
+       ) {
+               $rev = new MutableRevisionRecord( $title );
+
+               $rev->applyUpdate( $update );
+               $rev->setUser( $user );
+               $rev->setComment( CommentStoreComment::newUnsavedComment( $comment ) );
+               $rev->setId( $id );
+               $rev->setPageId( $title->getArticleID() );
+               $rev->setParentId( $parentId );
+
+               return $rev;
+       }
+
+       public function provideIsReusableFor() {
+               $title = Title::makeTitleSafe( NS_MAIN, __METHOD__ );
+
+               $user1 = User::newFromName( 'Alice' );
+               $user2 = User::newFromName( 'Bob' );
+
+               $content1 = new WikitextContent( 'one' );
+               $content2 = new WikitextContent( 'two' );
+
+               $update1 = new RevisionSlotsUpdate();
+               $update1->modifyContent( 'main', $content1 );
+
+               $update1b = new RevisionSlotsUpdate();
+               $update1b->modifyContent( 'xyz', $content1 );
+
+               $update2 = new RevisionSlotsUpdate();
+               $update2->modifyContent( 'main', $content2 );
+
+               $rev1 = $this->makeRevision( $title, $update1, $user1, 'rev1', 11 );
+               $rev1b = $this->makeRevision( $title, $update1b, $user1, 'rev1', 11 );
+
+               $rev2 = $this->makeRevision( $title, $update2, $user1, 'rev2', 12 );
+               $rev2x = $this->makeRevision( $title, $update2, $user2, 'rev2', 12 );
+               $rev2y = $this->makeRevision( $title, $update2, $user1, 'rev2', 122 );
+
+               yield 'any' => [
+                       '$prepUser' => null,
+                       '$prepRevision' => null,
+                       '$prepUpdate' => null,
+                       '$forUser' => null,
+                       '$forRevision' => null,
+                       '$forUpdate' => null,
+                       '$forParent' => null,
+                       '$isReusable' => true,
+               ];
+               yield 'for any' => [
+                       '$prepUser' => $user1,
+                       '$prepRevision' => $rev1,
+                       '$prepUpdate' => $update1,
+                       '$forUser' => null,
+                       '$forRevision' => null,
+                       '$forUpdate' => null,
+                       '$forParent' => null,
+                       '$isReusable' => true,
+               ];
+               yield 'unprepared' => [
+                       '$prepUser' => null,
+                       '$prepRevision' => null,
+                       '$prepUpdate' => null,
+                       '$forUser' => $user1,
+                       '$forRevision' => $rev1,
+                       '$forUpdate' => $update1,
+                       '$forParent' => 0,
+                       '$isReusable' => true,
+               ];
+               yield 'match prepareContent' => [
+                       '$prepUser' => $user1,
+                       '$prepRevision' => null,
+                       '$prepUpdate' => $update1,
+                       '$forUser' => $user1,
+                       '$forRevision' => null,
+                       '$forUpdate' => $update1,
+                       '$forParent' => 0,
+                       '$isReusable' => true,
+               ];
+               yield 'match prepareUpdate' => [
+                       '$prepUser' => null,
+                       '$prepRevision' => $rev1,
+                       '$prepUpdate' => null,
+                       '$forUser' => $user1,
+                       '$forRevision' => $rev1,
+                       '$forUpdate' => null,
+                       '$forParent' => 0,
+                       '$isReusable' => true,
+               ];
+               yield 'match all' => [
+                       '$prepUser' => $user1,
+                       '$prepRevision' => $rev1,
+                       '$prepUpdate' => $update1,
+                       '$forUser' => $user1,
+                       '$forRevision' => $rev1,
+                       '$forUpdate' => $update1,
+                       '$forParent' => 0,
+                       '$isReusable' => true,
+               ];
+               yield 'mismatch prepareContent update' => [
+                       '$prepUser' => $user1,
+                       '$prepRevision' => null,
+                       '$prepUpdate' => $update1,
+                       '$forUser' => $user1,
+                       '$forRevision' => null,
+                       '$forUpdate' => $update1b,
+                       '$forParent' => 0,
+                       '$isReusable' => false,
+               ];
+               yield 'mismatch prepareContent user' => [
+                       '$prepUser' => $user1,
+                       '$prepRevision' => null,
+                       '$prepUpdate' => $update1,
+                       '$forUser' => $user2,
+                       '$forRevision' => null,
+                       '$forUpdate' => $update1,
+                       '$forParent' => 0,
+                       '$isReusable' => false,
+               ];
+               yield 'mismatch prepareContent parent' => [
+                       '$prepUser' => $user1,
+                       '$prepRevision' => null,
+                       '$prepUpdate' => $update1,
+                       '$forUser' => $user1,
+                       '$forRevision' => null,
+                       '$forUpdate' => $update1,
+                       '$forParent' => 7,
+                       '$isReusable' => false,
+               ];
+               yield 'mismatch prepareUpdate revision update' => [
+                       '$prepUser' => null,
+                       '$prepRevision' => $rev1,
+                       '$prepUpdate' => null,
+                       '$forUser' => null,
+                       '$forRevision' => $rev1b,
+                       '$forUpdate' => null,
+                       '$forParent' => 0,
+                       '$isReusable' => false,
+               ];
+               yield 'mismatch prepareUpdate revision user' => [
+                       '$prepUser' => null,
+                       '$prepRevision' => $rev2,
+                       '$prepUpdate' => null,
+                       '$forUser' => null,
+                       '$forRevision' => $rev2x,
+                       '$forUpdate' => null,
+                       '$forParent' => 0,
+                       '$isReusable' => false,
+               ];
+               yield 'mismatch prepareUpdate revision id' => [
+                       '$prepUser' => null,
+                       '$prepRevision' => $rev2,
+                       '$prepUpdate' => null,
+                       '$forUser' => null,
+                       '$forRevision' => $rev2y,
+                       '$forUpdate' => null,
+                       '$forParent' => 0,
+                       '$isReusable' => false,
+               ];
+       }
+
+       /**
+        * @dataProvider provideIsReusableFor
+        * @covers \MediaWiki\Storage\DerivedPageDataUpdater::isReusableFor()
+        *
+        * @param User|null $prepUser
+        * @param RevisionRecord|null $prepRevision
+        * @param RevisionSlotsUpdate|null $prepUpdate
+        * @param User|null $forUser
+        * @param RevisionRecord|null $forRevision
+        * @param RevisionSlotsUpdate|null $forUpdate
+        * @param int|null $forParent
+        * @param bool $isReusable
+        */
+       public function testIsReusableFor(
+               User $prepUser = null,
+               RevisionRecord $prepRevision = null,
+               RevisionSlotsUpdate $prepUpdate = null,
+               User $forUser = null,
+               RevisionRecord $forRevision = null,
+               RevisionSlotsUpdate $forUpdate = null,
+               $forParent = null,
+               $isReusable = null
+       ) {
+               $updater = $this->getDerivedPageDataUpdater( __METHOD__ );
+
+               if ( $prepUpdate ) {
+                       $updater->prepareContent( $prepUser, $prepUpdate, false );
+               }
+
+               if ( $prepRevision ) {
+                       $updater->prepareUpdate( $prepRevision );
+               }
+
+               $this->assertSame(
+                       $isReusable,
+                       $updater->isReusableFor( $forUser, $forRevision, $forUpdate, $forParent )
+               );
+       }
+
+       /**
+        * @covers \MediaWiki\Storage\DerivedPageDataUpdater::doUpdates()
+        */
+       public function testDoUpdates() {
+               $page = $this->getPage( __METHOD__ );
+
+               $mainContent1 = new WikitextContent( 'first [[main]]' );
+               $rev = $this->createRevision( $page, 'first', $mainContent1 );
+               $pageId = $page->getId();
+               $oldStats = $this->db->selectRow( 'site_stats', '*', '1=1' );
+
+               $updater = $this->getDerivedPageDataUpdater( $page, $rev );
+               $updater->setArticleCountMethod( 'link' );
+
+               $options = []; // TODO: test *all* the options...
+               $updater->prepareUpdate( $rev, $options );
+
+               $updater->doUpdates();
+
+               // links table update
+               $linkCount = $this->db->selectRowCount( 'pagelinks', '*', [ 'pl_from' => $pageId ] );
+               $this->assertSame( 1, $linkCount );
+
+               $pageLinksRow = $this->db->selectRow( 'pagelinks', '*', [ 'pl_from' => $pageId ] );
+               $this->assertInternalType( 'object', $pageLinksRow );
+               $this->assertSame( 'Main', $pageLinksRow->pl_title );
+
+               // parser cache update
+               $pcache = MediaWikiServices::getInstance()->getParserCache();
+               $cached = $pcache->get( $page, $updater->getCanonicalParserOptions() );
+               $this->assertInternalType( 'object', $cached );
+               $this->assertSame( $updater->getCanonicalParserOutput(), $cached );
+
+               // site stats
+               $stats = $this->db->selectRow( 'site_stats', '*', '1=1' );
+               $this->assertSame( $oldStats->ss_total_pages + 1, (int)$stats->ss_total_pages );
+               $this->assertSame( $oldStats->ss_total_edits + 1, (int)$stats->ss_total_edits );
+               $this->assertSame( $oldStats->ss_good_articles + 1, (int)$stats->ss_good_articles );
+
+               // TODO: MCR: test data updates for additional slots!
+               // TODO: test update for edit without page creation
+               // TODO: test message cache purge
+               // TODO: test module cache purge
+               // TODO: test CDN purge
+               // TODO: test newtalk update
+               // TODO: test search update
+               // TODO: test site stats good_articles while turning the page into (or back from) a redir.
+               // TODO: test category membership update (with setRcWatchCategoryMembership())
+       }
+
+}
diff --git a/tests/phpunit/includes/Storage/McrReadNewRevisionStoreDbTest.php b/tests/phpunit/includes/Storage/McrReadNewRevisionStoreDbTest.php
new file mode 100644 (file)
index 0000000..cbae4c7
--- /dev/null
@@ -0,0 +1,252 @@
+<?php
+namespace MediaWiki\Tests\Storage;
+
+use CommentStoreComment;
+use MediaWiki\MediaWikiServices;
+use MediaWiki\Storage\RevisionRecord;
+use MediaWiki\Storage\SlotRecord;
+use TextContent;
+use Title;
+use WikitextContent;
+
+/**
+ * Tests RevisionStore against the intermediate MCR DB schema for use during schema migration.
+ *
+ * @covers \MediaWiki\Storage\RevisionStore
+ *
+ * @group RevisionStore
+ * @group Storage
+ * @group Database
+ * @group medium
+ */
+class McrReadNewRevisionStoreDbTest extends RevisionStoreDbTestBase {
+
+       use McrReadNewSchemaOverride;
+
+       protected function assertRevisionExistsInDatabase( RevisionRecord $rev ) {
+               $numberOfSlots = count( $rev->getSlotRoles() );
+
+               // new schema is written
+               $this->assertSelect(
+                       'slots',
+                       [ 'count(*)' ],
+                       [ 'slot_revision_id' => $rev->getId() ],
+                       [ [ (string)$numberOfSlots ] ]
+               );
+
+               $store = MediaWikiServices::getInstance()->getRevisionStore();
+               $revQuery = $store->getSlotsQueryInfo( [ 'content' ] );
+
+               $this->assertSelect(
+                       $revQuery['tables'],
+                       [ 'count(*)' ],
+                       [
+                               'slot_revision_id' => $rev->getId(),
+                       ],
+                       [ [ (string)$numberOfSlots ] ],
+                       [],
+                       $revQuery['joins']
+               );
+
+               // Legacy schema is still being written
+               $this->assertSelect(
+                       [ 'revision', 'text' ],
+                       [ 'count(*)' ],
+                       [ 'rev_id' => $rev->getId(), 'rev_text_id > 0' ],
+                       [ [ 1 ] ],
+                       [],
+                       [ 'text' => [ 'INNER JOIN', [ 'rev_text_id = old_id' ] ] ]
+               );
+
+               parent::assertRevisionExistsInDatabase( $rev );
+       }
+
+       /**
+        * @param SlotRecord $a
+        * @param SlotRecord $b
+        */
+       protected function assertSameSlotContent( SlotRecord $a, SlotRecord $b ) {
+               parent::assertSameSlotContent( $a, $b );
+
+               // Assert that the same content ID has been used
+               $this->assertSame( $a->getContentId(), $b->getContentId() );
+       }
+
+       public function provideInsertRevisionOn_successes() {
+               foreach ( parent::provideInsertRevisionOn_successes() as $case ) {
+                       yield $case;
+               }
+
+               yield 'Multi-slot revision insertion' => [
+                       [
+                               'content' => [
+                                       'main' => new WikitextContent( 'Chicken' ),
+                                       'aux' => new TextContent( 'Egg' ),
+                               ],
+                               'page' => true,
+                               'comment' => $this->getRandomCommentStoreComment(),
+                               'timestamp' => '20171117010101',
+                               'user' => true,
+                       ],
+               ];
+       }
+
+       public function provideNewNullRevision() {
+               foreach ( parent::provideNewNullRevision() as $case ) {
+                       yield $case;
+               }
+
+               yield [
+                       Title::newFromText( 'UTPage_notAutoCreated' ),
+                       [
+                               'content' => [
+                                       'main' => new WikitextContent( 'Chicken' ),
+                                       'aux' => new WikitextContent( 'Omelet' ),
+                               ],
+                       ],
+                       CommentStoreComment::newUnsavedComment( __METHOD__ . ' comment multi' ),
+               ];
+       }
+
+       public function testGetQueryInfo_NoSlotDataJoin() {
+               $store = MediaWikiServices::getInstance()->getRevisionStore();
+               $queryInfo = $store->getQueryInfo();
+
+               // with the new schema enabled, query info should not join the main slot info
+               $this->assertFalse( array_key_exists( 'a_slot_data', $queryInfo['tables'] ) );
+               $this->assertFalse( array_key_exists( 'a_slot_data', $queryInfo['joins'] ) );
+       }
+
+       public function provideGetArchiveQueryInfo() {
+               yield [
+                       [
+                               'tables' => [
+                                       'archive',
+                               ],
+                               'fields' => array_merge(
+                                       $this->getDefaultArchiveFields( false ),
+                                       [
+                                               'ar_comment_text' => 'ar_comment',
+                                               'ar_comment_data' => 'NULL',
+                                               'ar_comment_cid' => 'NULL',
+                                               'ar_user_text' => 'ar_user_text',
+                                               'ar_user' => 'ar_user',
+                                               'ar_actor' => 'NULL',
+                                       ]
+                               ),
+                               'joins' => [
+                               ],
+                       ]
+               ];
+       }
+
+       public function provideGetQueryInfo() {
+               // TODO: more option variations
+               yield [
+                       [ 'page', 'user' ],
+                       [
+                               'tables' => [
+                                       'revision',
+                                       'page',
+                                       'user',
+                               ],
+                               'fields' => array_merge(
+                                       $this->getDefaultQueryFields( false ),
+                                       $this->getCommentQueryFields(),
+                                       $this->getActorQueryFields(),
+                                       [
+                                               'page_namespace',
+                                               'page_title',
+                                               'page_id',
+                                               'page_latest',
+                                               'page_is_redirect',
+                                               'page_len',
+                                               'user_name',
+                                       ]
+                               ),
+                               'joins' => [
+                                       'page' => [ 'INNER JOIN', [ 'page_id = rev_page' ] ],
+                                       'user' => [ 'LEFT JOIN', [ 'rev_user != 0', 'user_id = rev_user' ] ],
+                               ],
+                       ]
+               ];
+       }
+
+       public function provideGetSlotsQueryInfo() {
+               yield [
+                       [],
+                       [
+                               'tables' => [
+                                       'slots',
+                                       'slot_roles',
+                               ],
+                               'fields' => array_merge(
+                                       [
+                                               'slot_revision_id',
+                                               'slot_content_id',
+                                               'slot_origin',
+                                               'role_name',
+                                       ]
+                               ),
+                               'joins' => [
+                                       'slot_roles' => [ 'INNER JOIN', [ 'slot_role_id = role_id' ] ],
+                               ],
+                       ]
+               ];
+               yield [
+                       [ 'content' ],
+                       [
+                               'tables' => [
+                                       'slots',
+                                       'slot_roles',
+                                       'content',
+                                       'content_models',
+                               ],
+                               'fields' => array_merge(
+                                       [
+                                               'slot_revision_id',
+                                               'slot_content_id',
+                                               'slot_origin',
+                                               'role_name',
+                                               'content_size',
+                                               'content_sha1',
+                                               'content_address',
+                                               'model_name',
+                                       ]
+                               ),
+                               'joins' => [
+                                       'slot_roles' => [ 'INNER JOIN', [ 'slot_role_id = role_id' ] ],
+                                       'content' => [ 'INNER JOIN', [ 'slot_content_id = content_id' ] ],
+                                       'content_models' => [ 'INNER JOIN', [ 'content_model = model_id' ] ],
+                               ],
+                       ]
+               ];
+       }
+
+       public function provideNewMutableRevisionFromArray() {
+               foreach ( parent::provideNewMutableRevisionFromArray() as $case ) {
+                       yield $case;
+               }
+
+               yield 'Basic array, multiple roles' => [
+                       [
+                               'id' => 2,
+                               'page' => 1,
+                               'timestamp' => '20171017114835',
+                               'user_text' => '111.0.1.2',
+                               'user' => 0,
+                               'minor_edit' => false,
+                               'deleted' => 0,
+                               'len' => 29,
+                               'parent_id' => 1,
+                               'sha1' => '89qs83keq9c9ccw9olvvm4oc9oq50ii',
+                               'comment' => 'Goat Comment!',
+                               'content' => [
+                                       'main' => new WikitextContent( 'Söme Cöntent' ),
+                                       'aux' => new TextContent( 'Öther Cöntent' ),
+                               ]
+                       ]
+               ];
+       }
+
+}
diff --git a/tests/phpunit/includes/Storage/McrReadNewSchemaOverride.php b/tests/phpunit/includes/Storage/McrReadNewSchemaOverride.php
new file mode 100644 (file)
index 0000000..1958333
--- /dev/null
@@ -0,0 +1,58 @@
+<?php
+namespace MediaWiki\Tests\Storage;
+
+use Wikimedia\Rdbms\IMaintainableDatabase;
+use MediaWiki\DB\PatchFileLocation;
+
+/**
+ * Trait providing schema overrides that allow tests to run against the intermediate MCR database
+ * schema for use during schema migration.
+ */
+trait McrReadNewSchemaOverride {
+
+       use PatchFileLocation;
+       use McrSchemaDetection;
+
+       /**
+        * @return int
+        */
+       protected function getMcrMigrationStage() {
+               return SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW;
+       }
+
+       /**
+        * @return string[]
+        */
+       protected function getMcrTablesToReset() {
+               return [ 'content', 'content_models', 'slots', 'slot_roles' ];
+       }
+
+       /**
+        * @override MediaWikiTestCase::getSchemaOverrides
+        * @return array[]
+        */
+       protected function getSchemaOverrides( IMaintainableDatabase $db ) {
+               $overrides = [
+                       'scripts' => [],
+                       'drop' => [],
+                       'create' => [],
+                       'alter' => [],
+               ];
+
+               if ( !$this->hasMcrTables( $db ) ) {
+                       $overrides['create'] = [ 'slots', 'content', 'slot_roles', 'content_models', ];
+                       $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' );
+               }
+
+               if ( !$this->hasPreMcrFields( $db ) ) {
+                       $overrides['alter'][] = 'revision';
+                       $overrides['scripts'][] = $this->getSqlPatchPath( $db, 'create-pre-mcr-fields', __DIR__ );
+               }
+
+               return $overrides;
+       }
+
+}
diff --git a/tests/phpunit/includes/Storage/McrRevisionStoreDbTest.php b/tests/phpunit/includes/Storage/McrRevisionStoreDbTest.php
new file mode 100644 (file)
index 0000000..9a118d7
--- /dev/null
@@ -0,0 +1,242 @@
+<?php
+namespace MediaWiki\Tests\Storage;
+
+use CommentStoreComment;
+use MediaWiki\MediaWikiServices;
+use MediaWiki\Storage\RevisionRecord;
+use MediaWiki\Storage\SlotRecord;
+use TextContent;
+use Title;
+use WikitextContent;
+
+/**
+ * Tests RevisionStore against the post-migration MCR DB schema.
+ *
+ * @covers \MediaWiki\Storage\RevisionStore
+ *
+ * @group RevisionStore
+ * @group Storage
+ * @group Database
+ * @group medium
+ */
+class McrRevisionStoreDbTest extends RevisionStoreDbTestBase {
+
+       use McrSchemaOverride;
+
+       protected function assertRevisionExistsInDatabase( RevisionRecord $rev ) {
+               $numberOfSlots = count( $rev->getSlotRoles() );
+
+               // new schema is written
+               $this->assertSelect(
+                       'slots',
+                       [ 'count(*)' ],
+                       [ 'slot_revision_id' => $rev->getId() ],
+                       [ [ (string)$numberOfSlots ] ]
+               );
+
+               $store = MediaWikiServices::getInstance()->getRevisionStore();
+               $revQuery = $store->getSlotsQueryInfo( [ 'content' ] );
+
+               $this->assertSelect(
+                       $revQuery['tables'],
+                       [ 'count(*)' ],
+                       [
+                               'slot_revision_id' => $rev->getId(),
+                       ],
+                       [ [ (string)$numberOfSlots ] ],
+                       [],
+                       $revQuery['joins']
+               );
+
+               parent::assertRevisionExistsInDatabase( $rev );
+       }
+
+       /**
+        * @param SlotRecord $a
+        * @param SlotRecord $b
+        */
+       protected function assertSameSlotContent( SlotRecord $a, SlotRecord $b ) {
+               parent::assertSameSlotContent( $a, $b );
+
+               // Assert that the same content ID has been used
+               $this->assertSame( $a->getContentId(), $b->getContentId() );
+       }
+
+       public function provideInsertRevisionOn_successes() {
+               foreach ( parent::provideInsertRevisionOn_successes() as $case ) {
+                       yield $case;
+               }
+
+               yield 'Multi-slot revision insertion' => [
+                       [
+                               'content' => [
+                                       'main' => new WikitextContent( 'Chicken' ),
+                                       'aux' => new TextContent( 'Egg' ),
+                               ],
+                               'page' => true,
+                               'comment' => $this->getRandomCommentStoreComment(),
+                               'timestamp' => '20171117010101',
+                               'user' => true,
+                       ],
+               ];
+       }
+
+       public function provideNewNullRevision() {
+               foreach ( parent::provideNewNullRevision() as $case ) {
+                       yield $case;
+               }
+
+               yield [
+                       Title::newFromText( 'UTPage_notAutoCreated' ),
+                       [
+                               'content' => [
+                                       'main' => new WikitextContent( 'Chicken' ),
+                                       'aux' => new WikitextContent( 'Omelet' ),
+                               ],
+                       ],
+                       CommentStoreComment::newUnsavedComment( __METHOD__ . ' comment multi' ),
+               ];
+       }
+
+       public function provideNewMutableRevisionFromArray() {
+               foreach ( parent::provideNewMutableRevisionFromArray() as $case ) {
+                       yield $case;
+               }
+
+               yield 'Basic array, multiple roles' => [
+                       [
+                               'id' => 2,
+                               'page' => 1,
+                               'timestamp' => '20171017114835',
+                               'user_text' => '111.0.1.2',
+                               'user' => 0,
+                               'minor_edit' => false,
+                               'deleted' => 0,
+                               'len' => 29,
+                               'parent_id' => 1,
+                               'sha1' => '89qs83keq9c9ccw9olvvm4oc9oq50ii',
+                               'comment' => 'Goat Comment!',
+                               'content' => [
+                                       'main' => new WikitextContent( 'Söme Cöntent' ),
+                                       'aux' => new TextContent( 'Öther Cöntent' ),
+                               ]
+                       ]
+               ];
+       }
+
+       public function testGetQueryInfo_NoSlotDataJoin() {
+               $store = MediaWikiServices::getInstance()->getRevisionStore();
+               $queryInfo = $store->getQueryInfo();
+
+               // with the new schema enabled, query info should not join the main slot info
+               $this->assertFalse( array_key_exists( 'a_slot_data', $queryInfo['tables'] ) );
+               $this->assertFalse( array_key_exists( 'a_slot_data', $queryInfo['joins'] ) );
+       }
+
+       public function provideGetArchiveQueryInfo() {
+               yield [
+                       [
+                               'tables' => [
+                                       'archive',
+                               ],
+                               'fields' => array_merge(
+                                       $this->getDefaultArchiveFields( false ),
+                                       [
+                                               'ar_comment_text' => 'ar_comment',
+                                               'ar_comment_data' => 'NULL',
+                                               'ar_comment_cid' => 'NULL',
+                                               'ar_user_text' => 'ar_user_text',
+                                               'ar_user' => 'ar_user',
+                                               'ar_actor' => 'NULL',
+                                       ]
+                               ),
+                               'joins' => [
+                               ],
+                       ]
+               ];
+       }
+
+       public function provideGetQueryInfo() {
+               // TODO: more option variations
+               yield [
+                       [ 'page', 'user' ],
+                       [
+                               'tables' => [
+                                       'revision',
+                                       'page',
+                                       'user',
+                               ],
+                               'fields' => array_merge(
+                                       $this->getDefaultQueryFields( false ),
+                                       $this->getCommentQueryFields(),
+                                       $this->getActorQueryFields(),
+                                       [
+                                               'page_namespace',
+                                               'page_title',
+                                               'page_id',
+                                               'page_latest',
+                                               'page_is_redirect',
+                                               'page_len',
+                                               'user_name',
+                                       ]
+                               ),
+                               'joins' => [
+                                       'page' => [ 'INNER JOIN', [ 'page_id = rev_page' ] ],
+                                       'user' => [ 'LEFT JOIN', [ 'rev_user != 0', 'user_id = rev_user' ] ],
+                               ],
+                       ]
+               ];
+       }
+
+       public function provideGetSlotsQueryInfo() {
+               yield [
+                       [],
+                       [
+                               'tables' => [
+                                       'slots',
+                                       'slot_roles',
+                               ],
+                               'fields' => array_merge(
+                                       [
+                                               'slot_revision_id',
+                                               'slot_content_id',
+                                               'slot_origin',
+                                               'role_name',
+                                       ]
+                               ),
+                               'joins' => [
+                                       'slot_roles' => [ 'INNER JOIN', [ 'slot_role_id = role_id' ] ],
+                               ],
+                       ]
+               ];
+               yield [
+                       [ 'content' ],
+                       [
+                               'tables' => [
+                                       'slots',
+                                       'slot_roles',
+                                       'content',
+                                       'content_models',
+                               ],
+                               'fields' => array_merge(
+                                       [
+                                               'slot_revision_id',
+                                               'slot_content_id',
+                                               'slot_origin',
+                                               'role_name',
+                                               'content_size',
+                                               'content_sha1',
+                                               'content_address',
+                                               'model_name',
+                                       ]
+                               ),
+                               'joins' => [
+                                       'slot_roles' => [ 'INNER JOIN', [ 'slot_role_id = role_id' ] ],
+                                       'content' => [ 'INNER JOIN', [ 'slot_content_id = content_id' ] ],
+                                       'content_models' => [ 'INNER JOIN', [ 'content_model = model_id' ] ],
+                               ],
+                       ]
+               ];
+       }
+
+}
diff --git a/tests/phpunit/includes/Storage/McrSchemaDetection.php b/tests/phpunit/includes/Storage/McrSchemaDetection.php
new file mode 100644 (file)
index 0000000..c90d428
--- /dev/null
@@ -0,0 +1,42 @@
+<?php
+namespace MediaWiki\Tests\Storage;
+
+use Wikimedia\Rdbms\IDatabase;
+
+/**
+ * Trait providing methods for detecting which MCR schema migration phase the current schema
+ * is compatible with.
+ */
+trait McrSchemaDetection {
+
+       /**
+        * Returns true if MCR-related tables exist in the database.
+        * If yes, the database is compatible with with MIGRATION_NEW.
+        * If hasPreMcrFields() also returns true, the database supports MIGRATION_WRITE_BOTH mode.
+        *
+        * @param IDatabase $db
+        * @return bool
+        */
+       protected function hasMcrTables( IDatabase $db ) {
+               return $db->tableExists( 'slots', __METHOD__ );
+       }
+
+       /**
+        * Returns true if pre-MCR fields still exist in the database.
+        * If yes, the database is compatible with with MIGRATION_OLD mode.
+        * If hasMcrTables() also returns true, the database supports MIGRATION_WRITE_BOTH mode.
+        *
+        * Note that if the database has been updated in MIGRATION_NEW mode,
+        * the rev_text_id field will be 0 for new revisions. This means that
+        * in MIGRATION_OLD mode, reading such revisions will fail, even though
+        * all the necessary fields exist.
+        * This is not relevant for unit tests, since unit tests reset the database content anyway.
+        *
+        * @param IDatabase $db
+        * @return bool
+        */
+       protected function hasPreMcrFields( IDatabase $db ) {
+               return $db->fieldExists( 'revision', 'rev_content_model', __METHOD__ );
+       }
+
+}
diff --git a/tests/phpunit/includes/Storage/McrSchemaOverride.php b/tests/phpunit/includes/Storage/McrSchemaOverride.php
new file mode 100644 (file)
index 0000000..d2f58bf
--- /dev/null
@@ -0,0 +1,59 @@
+<?php
+namespace MediaWiki\Tests\Storage;
+
+use Wikimedia\Rdbms\IMaintainableDatabase;
+use MediaWiki\DB\PatchFileLocation;
+
+/**
+ * Trait providing schema overrides that allow tests to run against the post-migration
+ * MCR database schema.
+ */
+trait McrSchemaOverride {
+
+       use PatchFileLocation;
+       use McrSchemaDetection;
+
+       /**
+        * @return int
+        */
+       protected function getMcrMigrationStage() {
+               return MIGRATION_NEW;
+       }
+
+       /**
+        * @return string[]
+        */
+       protected function getMcrTablesToReset() {
+               return [
+                       'content',
+                       'content_models',
+                       'slots',
+                       'slot_roles',
+               ];
+       }
+
+       protected function getSchemaOverrides( IMaintainableDatabase $db ) {
+               $overrides = [
+                       'scripts' => [],
+                       'drop' => [],
+                       'create' => [],
+                       'alter' => [],
+               ];
+
+               if ( !$this->hasMcrTables( $db ) ) {
+                       $overrides['create'] = [ 'slots', 'content', 'slot_roles', 'content_models', ];
+                       $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' );
+               }
+
+               if ( !$this->hasPreMcrFields( $db ) ) {
+                       $overrides['alter'][] = 'revision';
+                       $overrides['scripts'][] = $this->getSqlPatchPath( $db, 'drop-pre-mcr-fields', __DIR__ );
+               }
+
+               return $overrides;
+       }
+
+}
diff --git a/tests/phpunit/includes/Storage/McrWriteBothRevisionStoreDbTest.php b/tests/phpunit/includes/Storage/McrWriteBothRevisionStoreDbTest.php
new file mode 100644 (file)
index 0000000..9d5dc29
--- /dev/null
@@ -0,0 +1,227 @@
+<?php
+namespace MediaWiki\Tests\Storage;
+
+use InvalidArgumentException;
+use MediaWiki\Storage\RevisionRecord;
+use MediaWiki\Storage\SlotRecord;
+use Revision;
+use WikitextContent;
+
+/**
+ * Tests RevisionStore against the intermediate MCR DB schema for use during schema migration.
+ *
+ * @covers \MediaWiki\Storage\RevisionStore
+ *
+ * @group RevisionStore
+ * @group Storage
+ * @group Database
+ * @group medium
+ */
+class McrWriteBothRevisionStoreDbTest extends RevisionStoreDbTestBase {
+
+       use McrWriteBothSchemaOverride;
+
+       protected function revisionToRow( Revision $rev, $options = [ 'page', 'user', 'comment' ] ) {
+               $row = parent::revisionToRow( $rev, $options );
+
+               $row->rev_text_id = (string)$rev->getTextId();
+               $row->rev_content_format = (string)$rev->getContentFormat();
+               $row->rev_content_model = (string)$rev->getContentModel();
+
+               return $row;
+       }
+
+       protected function assertRevisionExistsInDatabase( RevisionRecord $rev ) {
+               // New schema is being written
+               $this->assertSelect(
+                       'slots',
+                       [ 'count(*)' ],
+                       [ 'slot_revision_id' => $rev->getId() ],
+                       [ [ '1' ] ]
+               );
+
+               $this->assertSelect(
+                       'content',
+                       [ 'count(*)' ],
+                       [ 'content_address' => $rev->getSlot( 'main' )->getAddress() ],
+                       [ [ '1' ] ]
+               );
+
+               // Legacy schema is still being written
+               $this->assertSelect(
+                       [ 'revision', 'text' ],
+                       [ 'count(*)' ],
+                       [ 'rev_id' => $rev->getId(), 'rev_text_id > 0' ],
+                       [ [ 1 ] ],
+                       [],
+                       [ 'text' => [ 'INNER JOIN', [ 'rev_text_id = old_id' ] ] ]
+               );
+
+               parent::assertRevisionExistsInDatabase( $rev );
+       }
+
+       /**
+        * @param SlotRecord $a
+        * @param SlotRecord $b
+        */
+       protected function assertSameSlotContent( SlotRecord $a, SlotRecord $b ) {
+               parent::assertSameSlotContent( $a, $b );
+
+               // Assert that the same content ID has been used
+               if ( $a->hasContentId() && $b->hasContentId() ) {
+                       $this->assertSame( $a->getContentId(), $b->getContentId() );
+               }
+       }
+
+       public function provideGetArchiveQueryInfo() {
+               yield [
+                       [
+                               'tables' => [ 'archive' ],
+                               'fields' => array_merge(
+                                       $this->getDefaultArchiveFields(),
+                                       [
+                                               'ar_comment_text' => 'ar_comment',
+                                               'ar_comment_data' => 'NULL',
+                                               'ar_comment_cid' => 'NULL',
+                                               'ar_user_text' => 'ar_user_text',
+                                               'ar_user' => 'ar_user',
+                                               'ar_actor' => 'NULL',
+                                               'ar_content_format',
+                                               'ar_content_model',
+                                       ]
+                               ),
+                               'joins' => [],
+                       ]
+               ];
+       }
+
+       public function provideGetQueryInfo() {
+               yield [
+                       [],
+                       [
+                               'tables' => [ 'revision' ],
+                               'fields' => array_merge(
+                                       $this->getDefaultQueryFields(),
+                                       $this->getCommentQueryFields(),
+                                       $this->getActorQueryFields(),
+                                       $this->getContentHandlerQueryFields()
+                               ),
+                               'joins' => [],
+                       ]
+               ];
+               yield [
+                       [ 'page', 'user' ],
+                       [
+                               'tables' => [ 'revision', 'page', 'user' ],
+                               'fields' => array_merge(
+                                       $this->getDefaultQueryFields(),
+                                       $this->getCommentQueryFields(),
+                                       $this->getActorQueryFields(),
+                                       $this->getContentHandlerQueryFields(),
+                                       [
+                                               'page_namespace',
+                                               'page_title',
+                                               'page_id',
+                                               'page_latest',
+                                               'page_is_redirect',
+                                               'page_len',
+                                               'user_name',
+                                       ]
+                               ),
+                               'joins' => [
+                                       'page' => [ 'INNER JOIN', [ 'page_id = rev_page' ] ],
+                                       'user' => [ 'LEFT JOIN', [ 'rev_user != 0', 'user_id = rev_user' ] ],
+                               ],
+                       ]
+               ];
+       }
+
+       public function provideGetSlotsQueryInfo() {
+               $db = wfGetDB( DB_REPLICA );
+
+               yield [
+                       [],
+                       [
+                               'tables' => [
+                                       'slots' => 'revision',
+                               ],
+                               'fields' => array_merge(
+                                       [
+                                               'slot_revision_id' => 'slots.rev_id',
+                                               'slot_content_id' => 'NULL',
+                                               'slot_origin' => 'slots.rev_id',
+                                               'role_name' => $db->addQuotes( 'main' ),
+                                       ]
+                               ),
+                               'joins' => [],
+                       ]
+               ];
+               yield [
+                       [ 'content' ],
+                       [
+                               'tables' => [
+                                       'slots' => 'revision',
+                               ],
+                               'fields' => array_merge(
+                                       [
+                                               'slot_revision_id' => 'slots.rev_id',
+                                               'slot_content_id' => 'NULL',
+                                               'slot_origin' => 'slots.rev_id',
+                                               'role_name' => $db->addQuotes( 'main' ),
+                                               'content_size' => 'slots.rev_len',
+                                               'content_sha1' => 'slots.rev_sha1',
+                                               'content_address' => $db->buildConcat( [
+                                                       $db->addQuotes( 'tt:' ), 'slots.rev_text_id' ] ),
+                                               'model_name' => 'slots.rev_content_model',
+                                       ]
+                               ),
+                               'joins' => [],
+                       ]
+               ];
+       }
+
+       public function provideInsertRevisionOn_failures() {
+               foreach ( parent::provideInsertRevisionOn_failures() as $case ) {
+                       yield $case;
+               }
+
+               yield 'slot that is not main slot' => [
+                       [
+                               'content' => [
+                                       'main' => new WikitextContent( 'Chicken' ),
+                                       'lalala' => new WikitextContent( 'Duck' ),
+                               ],
+                               'comment' => $this->getRandomCommentStoreComment(),
+                               'timestamp' => '20171117010101',
+                               'user' => true,
+                       ],
+                       new InvalidArgumentException( 'Only the main slot is supported' )
+               ];
+       }
+
+       public function provideNewMutableRevisionFromArray() {
+               foreach ( parent::provideNewMutableRevisionFromArray() as $case ) {
+                       yield $case;
+               }
+
+               yield 'Basic array, with page & id' => [
+                       [
+                               'id' => 2,
+                               'page' => 1,
+                               'text_id' => 2,
+                               'timestamp' => '20171017114835',
+                               'user_text' => '111.0.1.2',
+                               'user' => 0,
+                               'minor_edit' => false,
+                               'deleted' => 0,
+                               'len' => 46,
+                               'parent_id' => 1,
+                               'sha1' => 'rdqbbzs3pkhihgbs8qf2q9jsvheag5z',
+                               'comment' => 'Goat Comment!',
+                               'content_format' => 'text/x-wiki',
+                               'content_model' => 'wikitext',
+                       ]
+               ];
+       }
+
+}
diff --git a/tests/phpunit/includes/Storage/McrWriteBothSchemaOverride.php b/tests/phpunit/includes/Storage/McrWriteBothSchemaOverride.php
new file mode 100644 (file)
index 0000000..7275f90
--- /dev/null
@@ -0,0 +1,58 @@
+<?php
+namespace MediaWiki\Tests\Storage;
+
+use Wikimedia\Rdbms\IMaintainableDatabase;
+use MediaWiki\DB\PatchFileLocation;
+
+/**
+ * Trait providing schema overrides that allow tests to run against the intermediate MCR database
+ * schema for use during schema migration.
+ */
+trait McrWriteBothSchemaOverride {
+
+       use PatchFileLocation;
+       use McrSchemaDetection;
+
+       /**
+        * @return int
+        */
+       protected function getMcrMigrationStage() {
+               return SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD;
+       }
+
+       /**
+        * @return string[]
+        */
+       protected function getMcrTablesToReset() {
+               return [ 'content', 'content_models', 'slots', 'slot_roles' ];
+       }
+
+       /**
+        * @override MediaWikiTestCase::getSchemaOverrides
+        * @return array[]
+        */
+       protected function getSchemaOverrides( IMaintainableDatabase $db ) {
+               $overrides = [
+                       'scripts' => [],
+                       'drop' => [],
+                       'create' => [],
+                       'alter' => [],
+               ];
+
+               if ( !$this->hasMcrTables( $db ) ) {
+                       $overrides['create'] = [ 'slots', 'content', 'slot_roles', 'content_models', ];
+                       $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' );
+               }
+
+               if ( !$this->hasPreMcrFields( $db ) ) {
+                       $overrides['alter'][] = 'revision';
+                       $overrides['scripts'][] = $this->getSqlPatchPath( $db, 'create-pre-mcr-fields', __DIR__ );
+               }
+
+               return $overrides;
+       }
+
+}
index dd2c4b6..62093f0 100644 (file)
@@ -7,6 +7,7 @@ use InvalidArgumentException;
 use MediaWiki\Storage\MutableRevisionRecord;
 use MediaWiki\Storage\RevisionAccessException;
 use MediaWiki\Storage\RevisionRecord;
+use MediaWiki\Storage\RevisionSlotsUpdate;
 use MediaWiki\Storage\SlotRecord;
 use MediaWiki\User\UserIdentityValue;
 use MediaWikiTestCase;
@@ -209,4 +210,82 @@ class MutableRevisionRecordTest extends MediaWikiTestCase {
                $this->assertSame( $comment, $record->getComment() );
        }
 
+       public function testSimpleGetOriginalAndInheritedSlots() {
+               $record = new MutableRevisionRecord( Title::newFromText( 'Foo' ) );
+               $mainSlot = new SlotRecord(
+                       (object)[
+                               'slot_id' => 1,
+                               'slot_revision_id' => null, // unsaved
+                               'slot_content_id' => 1,
+                               'content_address' => null, // touched
+                               'model_name' => 'x',
+                               'role_name' => 'main',
+                               'slot_origin' => null // touched
+                       ],
+                       new WikitextContent( 'main' )
+               );
+               $auxSlot = new SlotRecord(
+                       (object)[
+                               'slot_id' => 2,
+                               'slot_revision_id' => null, // unsaved
+                               'slot_content_id' => 1,
+                               'content_address' => 'foo', // inherited
+                               'model_name' => 'x',
+                               'role_name' => 'aux',
+                               'slot_origin' => 1 // inherited
+                       ],
+                       new WikitextContent( 'aux' )
+               );
+
+               $record->setSlot( $mainSlot );
+               $record->setSlot( $auxSlot );
+
+               $this->assertSame( [ 'main' ], $record->getOriginalSlots()->getSlotRoles() );
+               $this->assertSame( $mainSlot, $record->getOriginalSlots()->getSlot( 'main' ) );
+
+               $this->assertSame( [ 'aux' ], $record->getInheritedSlots()->getSlotRoles() );
+               $this->assertSame( $auxSlot, $record->getInheritedSlots()->getSlot( 'aux' ) );
+       }
+
+       public function testSimpleremoveSlot() {
+               $record = new MutableRevisionRecord( Title::newFromText( 'Foo' ) );
+
+               $a = new WikitextContent( 'a' );
+               $b = new WikitextContent( 'b' );
+
+               $record->inheritSlot( SlotRecord::newSaved( 7, 3, 'a', SlotRecord::newUnsaved( 'a', $a ) ) );
+               $record->inheritSlot( SlotRecord::newSaved( 7, 4, 'b', SlotRecord::newUnsaved( 'b', $b ) ) );
+
+               $record->removeSlot( 'b' );
+
+               $this->assertTrue( $record->hasSlot( 'a' ) );
+               $this->assertFalse( $record->hasSlot( 'b' ) );
+       }
+
+       public function testApplyUpdate() {
+               $update = new RevisionSlotsUpdate();
+
+               $a = new WikitextContent( 'a' );
+               $b = new WikitextContent( 'b' );
+               $c = new WikitextContent( 'c' );
+               $x = new WikitextContent( 'x' );
+
+               $update->modifyContent( 'b', $x );
+               $update->modifyContent( 'c', $x );
+               $update->removeSlot( 'c' );
+               $update->removeSlot( 'd' );
+
+               $record = new MutableRevisionRecord( Title::newFromText( 'Foo' ) );
+               $record->inheritSlot( SlotRecord::newSaved( 7, 3, 'a', SlotRecord::newUnsaved( 'a', $a ) ) );
+               $record->inheritSlot( SlotRecord::newSaved( 7, 4, 'b', SlotRecord::newUnsaved( 'b', $b ) ) );
+               $record->inheritSlot( SlotRecord::newSaved( 7, 5, 'c', SlotRecord::newUnsaved( 'c', $c ) ) );
+
+               $record->applyUpdate( $update );
+
+               $this->assertEquals( [ 'b' ], array_keys( $record->getOriginalSlots()->getSlots() ) );
+               $this->assertEquals( $a, $record->getSlot( 'a' )->getContent() );
+               $this->assertEquals( $x, $record->getSlot( 'b' )->getContent() );
+               $this->assertFalse( $record->hasSlot( 'c' ) );
+       }
+
 }
index f19be3b..5a83143 100644 (file)
@@ -2,6 +2,7 @@
 
 namespace MediaWiki\Tests\Storage;
 
+use Content;
 use InvalidArgumentException;
 use MediaWiki\Storage\MutableRevisionSlots;
 use MediaWiki\Storage\RevisionAccessException;
@@ -75,6 +76,32 @@ class MutableRevisionSlotsTest extends RevisionSlotsTest {
                $this->assertSame( [ 'main' => $slotB ], $slots->getSlots() );
        }
 
+       /**
+        * @param string $role
+        * @param Content $content
+        * @return SlotRecord
+        */
+       private function newSavedSlot( $role, Content $content ) {
+               return SlotRecord::newSaved( 7, 7, 'xyz', SlotRecord::newUnsaved( $role, $content ) );
+       }
+
+       public function testInheritSlotOverwritesSlot() {
+               $slots = new MutableRevisionSlots();
+               $slotA = SlotRecord::newUnsaved( 'main', new WikitextContent( 'A' ) );
+               $slots->setSlot( $slotA );
+               $slotB = $this->newSavedSlot( 'main', new WikitextContent( 'B' ) );
+               $slotC = $this->newSavedSlot( 'foo', new WikitextContent( 'C' ) );
+               $slots->inheritSlot( $slotB );
+               $slots->inheritSlot( $slotC );
+               $this->assertSame( [ 'main', 'foo' ], $slots->getSlotRoles() );
+               $this->assertNotSame( $slotB, $slots->getSlot( 'main' ) );
+               $this->assertNotSame( $slotC, $slots->getSlot( 'foo' ) );
+               $this->assertTrue( $slots->getSlot( 'main' )->isInherited() );
+               $this->assertTrue( $slots->getSlot( 'foo' )->isInherited() );
+               $this->assertSame( $slotB->getContent(), $slots->getSlot( 'main' )->getContent() );
+               $this->assertSame( $slotC->getContent(), $slots->getSlot( 'foo' )->getContent() );
+       }
+
        public function testSetContentOfExistingSlotOverwritesContent() {
                $slots = new MutableRevisionSlots();
 
@@ -102,4 +129,20 @@ class MutableRevisionSlotsTest extends RevisionSlotsTest {
                $slots->getSlot( 'main' );
        }
 
+       public function testNewFromParentRevisionSlots() {
+               /** @var SlotRecord[] $parentSlots */
+               $parentSlots = [
+                       'some' => $this->newSavedSlot( 'some', new WikitextContent( 'X' ) ),
+                       'other' => $this->newSavedSlot( 'other', new WikitextContent( 'Y' ) ),
+               ];
+               $slots = MutableRevisionSlots::newFromParentRevisionSlots( $parentSlots );
+               $this->assertSame( [ 'some', 'other' ], $slots->getSlotRoles() );
+               $this->assertNotSame( $parentSlots['some'], $slots->getSlot( 'some' ) );
+               $this->assertNotSame( $parentSlots['other'], $slots->getSlot( 'other' ) );
+               $this->assertTrue( $slots->getSlot( 'some' )->isInherited() );
+               $this->assertTrue( $slots->getSlot( 'other' )->isInherited() );
+               $this->assertSame( $parentSlots['some']->getContent(), $slots->getContent( 'some' ) );
+               $this->assertSame( $parentSlots['other']->getContent(), $slots->getContent( 'other' ) );
+       }
+
 }
index 0cd164b..e5104d8 100644 (file)
@@ -83,14 +83,17 @@ class NameTableStoreTest extends MediaWikiTestCase {
                BagOStuff $cacheBag,
                $insertCalls,
                $selectCalls,
-               $normalizationCallback = null
+               $normalizationCallback = null,
+               $insertCallback = null
        ) {
                return new NameTableStore(
                        $this->getMockLoadBalancer( $this->getCallCheckingDb( $insertCalls, $selectCalls ) ),
                        $this->getHashWANObjectCache( $cacheBag ),
                        new NullLogger(),
                        'slot_roles', 'role_id', 'role_name',
-                       $normalizationCallback
+                       $normalizationCallback,
+                       false,
+                       $insertCallback
                );
        }
 
@@ -295,4 +298,18 @@ class NameTableStoreTest extends MediaWikiTestCase {
                $this->assertSame( $barId, $store3->acquireId( 'bar' ) );
        }
 
+       public function testGetAndAcquireIdInsertCallback() {
+               $store = $this->getNameTableSqlStore(
+                       new EmptyBagOStuff(),
+                       1,
+                       1,
+                       null,
+                       function ( $insertFields ) {
+                               $insertFields['role_id'] = 7251;
+                               return $insertFields;
+                       }
+               );
+               $this->assertSame( 7251, $store->acquireId( 'A' ) );
+       }
+
 }
diff --git a/tests/phpunit/includes/Storage/NoContentModelRevisionStoreDbTest.php b/tests/phpunit/includes/Storage/NoContentModelRevisionStoreDbTest.php
new file mode 100644 (file)
index 0000000..1d504de
--- /dev/null
@@ -0,0 +1,191 @@
+<?php
+namespace MediaWiki\Tests\Storage;
+
+use Revision;
+
+/**
+ * Tests RevisionStore against the pre-MCR, pre-ContentHandler DB schema.
+ *
+ * @covers \MediaWiki\Storage\RevisionStore
+ *
+ * @group RevisionStore
+ * @group Storage
+ * @group Database
+ * @group medium
+ */
+class NoContentModelRevisionStoreDbTest extends RevisionStoreDbTestBase {
+
+       use PreMcrSchemaOverride;
+
+       protected function getContentHandlerUseDB() {
+               return false;
+       }
+
+       protected function revisionToRow( Revision $rev, $options = [ 'page', 'user', 'comment' ] ) {
+               $row = parent::revisionToRow( $rev, $options );
+
+               $row->rev_text_id = (string)$rev->getTextId();
+
+               return $row;
+       }
+
+       public function provideGetArchiveQueryInfo() {
+               yield [
+                       [
+                               'tables' => [ 'archive' ],
+                               'fields' => array_merge(
+                                       $this->getDefaultArchiveFields(),
+                                       [
+                                               'ar_comment_text' => 'ar_comment',
+                                               'ar_comment_data' => 'NULL',
+                                               'ar_comment_cid' => 'NULL',
+                                               'ar_user_text' => 'ar_user_text',
+                                               'ar_user' => 'ar_user',
+                                               'ar_actor' => 'NULL',
+                                       ]
+                               ),
+                               'joins' => [],
+                       ]
+               ];
+       }
+
+       public function provideGetQueryInfo() {
+               yield [
+                       [],
+                       [
+                               'tables' => [ 'revision' ],
+                               'fields' => array_merge(
+                                       $this->getDefaultQueryFields(),
+                                       $this->getCommentQueryFields(),
+                                       $this->getActorQueryFields()
+                               ),
+                               'joins' => [],
+                       ]
+               ];
+               yield [
+                       [ 'page' ],
+                       [
+                               'tables' => [ 'revision', 'page' ],
+                               'fields' => array_merge(
+                                       $this->getDefaultQueryFields(),
+                                       $this->getCommentQueryFields(),
+                                       $this->getActorQueryFields(),
+                                       [
+                                               'page_namespace',
+                                               'page_title',
+                                               'page_id',
+                                               'page_latest',
+                                               'page_is_redirect',
+                                               'page_len',
+                                       ]
+                               ),
+                               'joins' => [
+                                       'page' => [ 'INNER JOIN', [ 'page_id = rev_page' ] ],
+                               ],
+                       ]
+               ];
+               yield [
+                       [ 'user' ],
+                       [
+                               'tables' => [ 'revision', 'user' ],
+                               'fields' => array_merge(
+                                       $this->getDefaultQueryFields(),
+                                       $this->getCommentQueryFields(),
+                                       $this->getActorQueryFields(),
+                                       [
+                                               'user_name',
+                                       ]
+                               ),
+                               'joins' => [
+                                       'user' => [ 'LEFT JOIN', [ 'rev_user != 0', 'user_id = rev_user' ] ],
+                               ],
+                       ]
+               ];
+               yield [
+                       [ 'text' ],
+                       [
+                               'tables' => [ 'revision', 'text' ],
+                               'fields' => array_merge(
+                                       $this->getDefaultQueryFields(),
+                                       $this->getCommentQueryFields(),
+                                       $this->getActorQueryFields(),
+                                       [
+                                               'old_text',
+                                               'old_flags',
+                                       ]
+                               ),
+                               'joins' => [
+                                       'text' => [ 'INNER JOIN', [ 'rev_text_id=old_id' ] ],
+                               ],
+                       ]
+               ];
+       }
+
+       public function provideGetSlotsQueryInfo() {
+               $db = wfGetDB( DB_REPLICA );
+
+               yield [
+                       [],
+                       [
+                               'tables' => [
+                                       'slots' => 'revision',
+                               ],
+                               'fields' => array_merge(
+                                       [
+                                               'slot_revision_id' => 'slots.rev_id',
+                                               'slot_content_id' => 'NULL',
+                                               'slot_origin' => 'slots.rev_id',
+                                               'role_name' => $db->addQuotes( 'main' ),
+                                       ]
+                               ),
+                               'joins' => [],
+                       ]
+               ];
+               yield [
+                       [ 'content' ],
+                       [
+                               'tables' => [
+                                       'slots' => 'revision',
+                               ],
+                               'fields' => array_merge(
+                                       [
+                                               'slot_revision_id' => 'slots.rev_id',
+                                               'slot_content_id' => 'NULL',
+                                               'slot_origin' => 'slots.rev_id',
+                                               'role_name' => $db->addQuotes( 'main' ),
+                                               'content_size' => 'slots.rev_len',
+                                               'content_sha1' => 'slots.rev_sha1',
+                                               'content_address' =>
+                                                       $db->buildConcat( [ $db->addQuotes( 'tt:' ), 'slots.rev_text_id' ] ),
+                                               'model_name' => 'NULL',
+                                       ]
+                               ),
+                               'joins' => [],
+                       ]
+               ];
+       }
+
+       public function provideNewMutableRevisionFromArray() {
+               foreach ( parent::provideNewMutableRevisionFromArray() as $case ) {
+                       yield $case;
+               }
+
+               yield 'Basic array, with page & id' => [
+                       [
+                               'id' => 2,
+                               'page' => 1,
+                               'text_id' => 2,
+                               'timestamp' => '20171017114835',
+                               'user_text' => '111.0.1.2',
+                               'user' => 0,
+                               'minor_edit' => false,
+                               'deleted' => 0,
+                               'len' => 46,
+                               'parent_id' => 1,
+                               'sha1' => 'rdqbbzs3pkhihgbs8qf2q9jsvheag5z',
+                               'comment' => 'Goat Comment!',
+                       ]
+               ];
+       }
+
+}
diff --git a/tests/phpunit/includes/Storage/PageUpdaterTest.php b/tests/phpunit/includes/Storage/PageUpdaterTest.php
new file mode 100644 (file)
index 0000000..f01c6ba
--- /dev/null
@@ -0,0 +1,489 @@
+<?php
+
+namespace MediaWiki\Tests\Storage;
+
+use CommentStoreComment;
+use Content;
+use MediaWiki\MediaWikiServices;
+use MediaWiki\Storage\RevisionRecord;
+use MediaWikiTestCase;
+use RecentChange;
+use Revision;
+use TextContent;
+use Title;
+use WikiPage;
+
+/**
+ * @covers \MediaWiki\Storage\PageUpdater
+ * @group Database
+ */
+class PageUpdaterTest extends MediaWikiTestCase {
+
+       private function getDummyTitle( $method ) {
+               return Title::newFromText( $method, $this->getDefaultWikitextNS() );
+       }
+
+       /**
+        * @param int $revId
+        *
+        * @return null|RecentChange
+        */
+       private function getRecentChangeFor( $revId ) {
+               $qi = RecentChange::getQueryInfo();
+               $row = $this->db->selectRow(
+                       $qi['tables'],
+                       $qi['fields'],
+                       [ 'rc_this_oldid' => $revId ],
+                       __METHOD__,
+                       [],
+                       $qi['joins']
+               );
+
+               return $row ? RecentChange::newFromRow( $row ) : null;
+       }
+
+       // TODO: test setAjaxEditStash();
+
+       /**
+        * @covers \MediaWiki\Storage\PageUpdater::saveRevision()
+        * @covers \WikiPage::newPageUpdater()
+        */
+       public function testCreatePage() {
+               $user = $this->getTestUser()->getUser();
+
+               $title = $this->getDummyTitle( __METHOD__ );
+               $page = WikiPage::factory( $title );
+               $updater = $page->newPageUpdater( $user );
+
+               $oldStats = $this->db->selectRow( 'site_stats', '*', '1=1' );
+
+               $this->assertFalse( $updater->wasCommitted(), 'wasCommitted' );
+               $this->assertFalse( $updater->getOriginalRevisionId(), 'getOriginalRevisionId' );
+               $this->assertSame( 0, $updater->getUndidRevisionId(), 'getUndidRevisionId' );
+
+               $updater->addTag( 'foo' );
+               $updater->addTags( [ 'bar', 'qux' ] );
+
+               $tags = $updater->getExplicitTags();
+               sort( $tags );
+               $this->assertSame( [ 'bar', 'foo', 'qux' ], $tags, 'getExplicitTags' );
+
+               // TODO: MCR: test additional slots
+               $content = new TextContent( 'Lorem Ipsum' );
+               $updater->setContent( 'main', $content );
+
+               $parent = $updater->grabParentRevision();
+
+               $this->assertNull( $parent, 'getParentRevision' );
+               $this->assertFalse( $updater->wasCommitted(), 'wasCommitted' );
+
+               // TODO: test that hasEditConflict() grabs the parent revision
+               $this->assertFalse( $updater->hasEditConflict( 0 ), 'hasEditConflict' );
+               $this->assertTrue( $updater->hasEditConflict( 1 ), 'hasEditConflict' );
+
+               // TODO: test failure with EDIT_UPDATE
+               // TODO: test EDIT_MINOR, EDIT_BOT, etc
+               $summary = CommentStoreComment::newUnsavedComment( 'Just a test' );
+               $rev = $updater->saveRevision( $summary );
+
+               $this->assertNotNull( $rev );
+               $this->assertSame( 0, $rev->getParentId() );
+               $this->assertSame( $summary->text, $rev->getComment( RevisionRecord::RAW )->text );
+               $this->assertSame( $user->getName(), $rev->getUser( RevisionRecord::RAW )->getName() );
+
+               $this->assertTrue( $updater->wasCommitted(), 'wasCommitted()' );
+               $this->assertTrue( $updater->wasSuccessful(), 'wasSuccessful()' );
+               $this->assertTrue( $updater->getStatus()->isOK(), 'getStatus()->isOK()' );
+               $this->assertTrue( $updater->isNew(), 'isNew()' );
+               $this->assertFalse( $updater->isUnchanged(), 'isUnchanged()' );
+               $this->assertNotNull( $updater->getNewRevision(), 'getNewRevision()' );
+               $this->assertInstanceOf( Revision::class, $updater->getStatus()->value['revision'] );
+
+               $rev = $updater->getNewRevision();
+               $revContent = $rev->getContent( 'main' );
+               $this->assertSame( 'Lorem Ipsum', $revContent->serialize(), 'revision content' );
+
+               // were the WikiPage and Title objects updated?
+               $this->assertTrue( $page->exists(), 'WikiPage::exists()' );
+               $this->assertTrue( $title->exists(), 'Title::exists()' );
+               $this->assertSame( $rev->getId(), $page->getLatest(), 'WikiPage::getRevision()' );
+               $this->assertNotNull( $page->getRevision(), 'WikiPage::getRevision()' );
+
+               // re-load
+               $page2 = WikiPage::factory( $title );
+               $this->assertTrue( $page2->exists(), 'WikiPage::exists()' );
+               $this->assertSame( $rev->getId(), $page2->getLatest(), 'WikiPage::getRevision()' );
+               $this->assertNotNull( $page2->getRevision(), 'WikiPage::getRevision()' );
+
+               // Check RC entry
+               $rc = $this->getRecentChangeFor( $rev->getId() );
+               $this->assertNotNull( $rc, 'RecentChange' );
+
+               // check site stats - this asserts that derived data updates where run.
+               $stats = $this->db->selectRow( 'site_stats', '*', '1=1' );
+               $this->assertSame( $oldStats->ss_total_pages + 1, (int)$stats->ss_total_pages );
+               $this->assertSame( $oldStats->ss_total_edits + 1, (int)$stats->ss_total_edits );
+
+               // re-edit with same content - should be a "null-edit"
+               $updater = $page->newPageUpdater( $user );
+               $updater->setContent( 'main', $content );
+
+               $summary = CommentStoreComment::newUnsavedComment( 'to to re-edit' );
+               $rev = $updater->saveRevision( $summary );
+               $status = $updater->getStatus();
+
+               $this->assertNull( $rev, 'getNewRevision()' );
+               $this->assertNull( $updater->getNewRevision(), 'getNewRevision()' );
+               $this->assertTrue( $updater->isUnchanged(), 'isUnchanged' );
+               $this->assertTrue( $updater->wasSuccessful(), 'wasSuccessful()' );
+               $this->assertTrue( $status->isOK(), 'getStatus()->isOK()' );
+               $this->assertTrue( $status->hasMessage( 'edit-no-change' ), 'edit-no-change' );
+       }
+
+       /**
+        * @covers \MediaWiki\Storage\PageUpdater::saveRevision()
+        * @covers \WikiPage::newPageUpdater()
+        */
+       public function testUpdatePage() {
+               $user = $this->getTestUser()->getUser();
+
+               $title = $this->getDummyTitle( __METHOD__ );
+               $this->insertPage( $title );
+
+               $page = WikiPage::factory( $title );
+               $parentId = $page->getLatest();
+
+               $updater = $page->newPageUpdater( $user );
+
+               $oldStats = $this->db->selectRow( 'site_stats', '*', '1=1' );
+
+               $updater->setOriginalRevisionId( 7 );
+               $this->assertSame( 7, $updater->getOriginalRevisionId(), 'getOriginalRevisionId' );
+
+               $this->assertFalse( $updater->hasEditConflict( $parentId ), 'hasEditConflict' );
+               $this->assertTrue( $updater->hasEditConflict( $parentId - 1 ), 'hasEditConflict' );
+               $this->assertTrue( $updater->hasEditConflict( 0 ), 'hasEditConflict' );
+
+               // TODO: MCR: test additional slots
+               $updater->setContent( 'main', new TextContent( 'Lorem Ipsum' ) );
+
+               // TODO: test all flags for saveRevision()!
+               $summary = CommentStoreComment::newUnsavedComment( 'Just a test' );
+               $rev = $updater->saveRevision( $summary );
+
+               $this->assertNotNull( $rev );
+               $this->assertSame( $parentId, $rev->getParentId() );
+               $this->assertSame( $summary->text, $rev->getComment( RevisionRecord::RAW )->text );
+               $this->assertSame( $user->getName(), $rev->getUser( RevisionRecord::RAW )->getName() );
+
+               $this->assertTrue( $updater->wasCommitted(), 'wasCommitted()' );
+               $this->assertTrue( $updater->wasSuccessful(), 'wasSuccessful()' );
+               $this->assertTrue( $updater->getStatus()->isOK(), 'getStatus()->isOK()' );
+               $this->assertFalse( $updater->isNew(), 'isNew()' );
+               $this->assertNotNull( $updater->getNewRevision(), 'getNewRevision()' );
+               $this->assertInstanceOf( Revision::class, $updater->getStatus()->value['revision'] );
+               $this->assertFalse( $updater->isUnchanged(), 'isUnchanged()' );
+
+               // TODO: Test null revision (with different user): new revision!
+
+               $rev = $updater->getNewRevision();
+               $revContent = $rev->getContent( 'main' );
+               $this->assertSame( 'Lorem Ipsum', $revContent->serialize(), 'revision content' );
+
+               // were the WikiPage and Title objects updated?
+               $this->assertTrue( $page->exists(), 'WikiPage::exists()' );
+               $this->assertTrue( $title->exists(), 'Title::exists()' );
+               $this->assertSame( $rev->getId(), $page->getLatest(), 'WikiPage::getRevision()' );
+               $this->assertNotNull( $page->getRevision(), 'WikiPage::getRevision()' );
+
+               // re-load
+               $page2 = WikiPage::factory( $title );
+               $this->assertTrue( $page2->exists(), 'WikiPage::exists()' );
+               $this->assertSame( $rev->getId(), $page2->getLatest(), 'WikiPage::getRevision()' );
+               $this->assertNotNull( $page2->getRevision(), 'WikiPage::getRevision()' );
+
+               // Check RC entry
+               $rc = $this->getRecentChangeFor( $rev->getId() );
+               $this->assertNotNull( $rc, 'RecentChange' );
+
+               // re-edit
+               $updater = $page->newPageUpdater( $user );
+               $updater->setContent( 'main', new TextContent( 'dolor sit amet' ) );
+
+               $summary = CommentStoreComment::newUnsavedComment( 're-edit' );
+               $updater->saveRevision( $summary );
+               $this->assertTrue( $updater->wasSuccessful(), 'wasSuccessful()' );
+               $this->assertTrue( $updater->getStatus()->isOK(), 'getStatus()->isOK()' );
+
+               // check site stats - this asserts that derived data updates where run.
+               $stats = $this->db->selectRow( 'site_stats', '*', '1=1' );
+               $this->assertSame( $oldStats->ss_total_pages + 0, (int)$stats->ss_total_pages );
+               $this->assertSame( $oldStats->ss_total_edits + 2, (int)$stats->ss_total_edits );
+       }
+
+       /**
+        * Creates a revision in the database.
+        *
+        * @param WikiPage $page
+        * @param $summary
+        * @param null|string|Content $content
+        *
+        * @return RevisionRecord|null
+        */
+       private function createRevision( WikiPage $page, $summary, $content = null ) {
+               $user = $this->getTestUser()->getUser();
+               $comment = CommentStoreComment::newUnsavedComment( $summary );
+
+               if ( !$content instanceof Content ) {
+                       $content = new TextContent( $content ?? $summary );
+               }
+
+               $updater = $page->newPageUpdater( $user );
+               $updater->setContent( 'main', $content );
+               $rev = $updater->saveRevision( $comment );
+               return $rev;
+       }
+
+       /**
+        * @covers \MediaWiki\Storage\PageUpdater::grabParentRevision()
+        * @covers \MediaWiki\Storage\PageUpdater::saveRevision()
+        */
+       public function testCompareAndSwapFailure() {
+               $user = $this->getTestUser()->getUser();
+
+               $title = $this->getDummyTitle( __METHOD__ );
+
+               // start editing non-existing page
+               $page = WikiPage::factory( $title );
+               $updater = $page->newPageUpdater( $user );
+               $updater->grabParentRevision();
+
+               // create page concurrently
+               $concurrentPage = WikiPage::factory( $title );
+               $this->createRevision( $concurrentPage, __METHOD__ . '-one' );
+
+               // try creating the page - should trigger CAS failure.
+               $summary = CommentStoreComment::newUnsavedComment( 'create?!' );
+               $updater->setContent( 'main', new TextContent( 'Lorem ipsum' ) );
+               $updater->saveRevision( $summary );
+               $status = $updater->getStatus();
+
+               $this->assertFalse( $updater->wasSuccessful(), 'wasSuccessful()' );
+               $this->assertNull( $updater->getNewRevision(), 'getNewRevision()' );
+               $this->assertFalse( $status->isOK(), 'getStatus()->isOK()' );
+               $this->assertTrue( $status->hasMessage( 'edit-already-exists' ), 'edit-conflict' );
+
+               // start editing existing page
+               $page = WikiPage::factory( $title );
+               $updater = $page->newPageUpdater( $user );
+               $updater->grabParentRevision();
+
+               // update page concurrently
+               $concurrentPage = WikiPage::factory( $title );
+               $this->createRevision( $concurrentPage, __METHOD__ . '-two' );
+
+               // try creating the page - should trigger CAS failure.
+               $summary = CommentStoreComment::newUnsavedComment( 'edit?!' );
+               $updater->setContent( 'main', new TextContent( 'dolor sit amet' ) );
+               $updater->saveRevision( $summary );
+               $status = $updater->getStatus();
+
+               $this->assertFalse( $updater->wasSuccessful(), 'wasSuccessful()' );
+               $this->assertNull( $updater->getNewRevision(), 'getNewRevision()' );
+               $this->assertFalse( $status->isOK(), 'getStatus()->isOK()' );
+               $this->assertTrue( $status->hasMessage( 'edit-conflict' ), 'edit-conflict' );
+       }
+
+       /**
+        * @covers \MediaWiki\Storage\PageUpdater::saveRevision()
+        */
+       public function testFailureOnEditFlags() {
+               $user = $this->getTestUser()->getUser();
+
+               $title = $this->getDummyTitle( __METHOD__ );
+
+               // start editing non-existing page
+               $page = WikiPage::factory( $title );
+               $updater = $page->newPageUpdater( $user );
+
+               // update with EDIT_UPDATE flag should fail
+               $summary = CommentStoreComment::newUnsavedComment( 'udpate?!' );
+               $updater->setContent( 'main', new TextContent( 'Lorem ipsum' ) );
+               $updater->saveRevision( $summary, EDIT_UPDATE );
+               $status = $updater->getStatus();
+
+               $this->assertFalse( $updater->wasSuccessful(), 'wasSuccessful()' );
+               $this->assertNull( $updater->getNewRevision(), 'getNewRevision()' );
+               $this->assertFalse( $status->isOK(), 'getStatus()->isOK()' );
+               $this->assertTrue( $status->hasMessage( 'edit-gone-missing' ), 'edit-gone-missing' );
+
+               // create the page
+               $this->createRevision( $page, __METHOD__ );
+
+               // update with EDIT_NEW flag should fail
+               $summary = CommentStoreComment::newUnsavedComment( 'create?!' );
+               $updater = $page->newPageUpdater( $user );
+               $updater->setContent( 'main', new TextContent( 'dolor sit amet' ) );
+               $updater->saveRevision( $summary, EDIT_NEW );
+               $status = $updater->getStatus();
+
+               $this->assertFalse( $updater->wasSuccessful(), 'wasSuccessful()' );
+               $this->assertNull( $updater->getNewRevision(), 'getNewRevision()' );
+               $this->assertFalse( $status->isOK(), 'getStatus()->isOK()' );
+               $this->assertTrue( $status->hasMessage( 'edit-already-exists' ), 'edit-already-exists' );
+       }
+
+       public function provideSetRcPatrolStatus( $patrolled ) {
+               yield [ RecentChange::PRC_UNPATROLLED ];
+               yield [ RecentChange::PRC_AUTOPATROLLED ];
+       }
+
+       /**
+        * @dataProvider provideSetRcPatrolStatus
+        * @covers \MediaWiki\Storage\PageUpdater::setRcPatrolStatus()
+        */
+       public function testSetRcPatrolStatus( $patrolled ) {
+               $revisionStore = MediaWikiServices::getInstance()->getRevisionStore();
+
+               $user = $this->getTestUser()->getUser();
+
+               $title = $this->getDummyTitle( __METHOD__ );
+
+               $page = WikiPage::factory( $title );
+               $updater = $page->newPageUpdater( $user );
+
+               $summary = CommentStoreComment::newUnsavedComment( 'Lorem ipsum ' . $patrolled );
+               $updater->setContent( 'main', new TextContent( 'Lorem ipsum ' . $patrolled ) );
+               $updater->setRcPatrolStatus( $patrolled );
+               $rev = $updater->saveRevision( $summary );
+
+               $rc = $revisionStore->getRecentChange( $rev );
+               $this->assertEquals( $patrolled, $rc->getAttribute( 'rc_patrolled' ) );
+       }
+
+       /**
+        * @covers \MediaWiki\Storage\PageUpdater::inheritSlot()
+        * @covers \MediaWiki\Storage\PageUpdater::setContent()
+        */
+       public function testInheritSlot() {
+               $user = $this->getTestUser()->getUser();
+               $title = $this->getDummyTitle( __METHOD__ );
+               $page = WikiPage::factory( $title );
+
+               $updater = $page->newPageUpdater( $user );
+               $summary = CommentStoreComment::newUnsavedComment( 'one' );
+               $updater->setContent( 'main', new TextContent( 'Lorem ipsum' ) );
+               $rev1 = $updater->saveRevision( $summary, EDIT_NEW );
+
+               $updater = $page->newPageUpdater( $user );
+               $summary = CommentStoreComment::newUnsavedComment( 'two' );
+               $updater->setContent( 'main', new TextContent( 'Foo Bar' ) );
+               $rev2 = $updater->saveRevision( $summary, EDIT_UPDATE );
+
+               $updater = $page->newPageUpdater( $user );
+               $summary = CommentStoreComment::newUnsavedComment( 'three' );
+               $updater->inheritSlot( $rev1->getSlot( 'main' ) );
+               $rev3 = $updater->saveRevision( $summary, EDIT_UPDATE );
+
+               $this->assertNotSame( $rev1->getId(), $rev3->getId() );
+               $this->assertNotSame( $rev2->getId(), $rev3->getId() );
+
+               $main1 = $rev1->getSlot( 'main' );
+               $main3 = $rev3->getSlot( 'main' );
+
+               $this->assertNotSame( $main1->getRevision(), $main3->getRevision() );
+               $this->assertSame( $main1->getAddress(), $main3->getAddress() );
+               $this->assertTrue( $main1->getContent()->equals( $main3->getContent() ) );
+       }
+
+       // TODO: MCR: test adding multiple slots, inheriting parent slots, and removing slots.
+
+       public function testSetUseAutomaticEditSummaries() {
+               $this->setContentLang( 'qqx' );
+               $user = $this->getTestUser()->getUser();
+
+               $title = $this->getDummyTitle( __METHOD__ );
+               $page = WikiPage::factory( $title );
+
+               $updater = $page->newPageUpdater( $user );
+               $updater->setUseAutomaticEditSummaries( true );
+               $updater->setContent( 'main', new TextContent( 'Lorem Ipsum' ) );
+
+               // empty comment triggers auto-summary
+               $summary = CommentStoreComment::newUnsavedComment( '' );
+               $updater->saveRevision( $summary, EDIT_AUTOSUMMARY );
+
+               $rev = $updater->getNewRevision();
+               $comment = $rev->getComment( RevisionRecord::RAW );
+               $this->assertSame( '(autosumm-new: Lorem Ipsum)', $comment->text, 'comment text' );
+
+               // check that this also works when blanking the page
+               $updater = $page->newPageUpdater( $user );
+               $updater->setUseAutomaticEditSummaries( true );
+               $updater->setContent( 'main', new TextContent( '' ) );
+
+               $summary = CommentStoreComment::newUnsavedComment( '' );
+               $updater->saveRevision( $summary, EDIT_AUTOSUMMARY );
+
+               $rev = $updater->getNewRevision();
+               $comment = $rev->getComment( RevisionRecord::RAW );
+               $this->assertSame( '(autosumm-blank)', $comment->text, 'comment text' );
+
+               // check that we can also disable edit-summaries
+               $title2 = $this->getDummyTitle( __METHOD__ . '/2' );
+               $page2 = WikiPage::factory( $title2 );
+
+               $updater = $page2->newPageUpdater( $user );
+               $updater->setUseAutomaticEditSummaries( false );
+               $updater->setContent( 'main', new TextContent( 'Lorem Ipsum' ) );
+
+               $summary = CommentStoreComment::newUnsavedComment( '' );
+               $updater->saveRevision( $summary, EDIT_AUTOSUMMARY );
+
+               $rev = $updater->getNewRevision();
+               $comment = $rev->getComment( RevisionRecord::RAW );
+               $this->assertSame( '', $comment->text, 'comment text should still be lank' );
+
+               // check that we don't do auto.summaries without the EDIT_AUTOSUMMARY flag
+               $updater = $page2->newPageUpdater( $user );
+               $updater->setUseAutomaticEditSummaries( true );
+               $updater->setContent( 'main', new TextContent( '' ) );
+
+               $summary = CommentStoreComment::newUnsavedComment( '' );
+               $updater->saveRevision( $summary, 0 );
+
+               $rev = $updater->getNewRevision();
+               $comment = $rev->getComment( RevisionRecord::RAW );
+               $this->assertSame( '', $comment->text, 'comment text' );
+       }
+
+       public function provideSetUsePageCreationLog() {
+               yield [ true, [ [ 'create', 'create' ] ] ];
+               yield [ false, [] ];
+       }
+
+       /**
+        * @dataProvider provideSetUsePageCreationLog
+        * @param bool $use
+        */
+       public function testSetUsePageCreationLog( $use, $expected ) {
+               $user = $this->getTestUser()->getUser();
+               $title = $this->getDummyTitle( __METHOD__ . ( $use ? '_logged' : '_unlogged' ) );
+               $page = WikiPage::factory( $title );
+
+               $updater = $page->newPageUpdater( $user );
+               $updater->setUsePageCreationLog( $use );
+               $summary = CommentStoreComment::newUnsavedComment( 'cmt' );
+               $updater->setContent( 'main', new TextContent( 'Lorem Ipsum' ) );
+               $updater->saveRevision( $summary, EDIT_NEW );
+
+               $rev = $updater->getNewRevision();
+               $this->assertSelect(
+                       'logging',
+                       [ 'log_type', 'log_action' ],
+                       [ 'log_page' => $rev->getPageId() ],
+                       $expected
+               );
+       }
+
+}
diff --git a/tests/phpunit/includes/Storage/PreMcrRevisionStoreDbTest.php b/tests/phpunit/includes/Storage/PreMcrRevisionStoreDbTest.php
new file mode 100644 (file)
index 0000000..cee5f96
--- /dev/null
@@ -0,0 +1,201 @@
+<?php
+namespace MediaWiki\Tests\Storage;
+
+use InvalidArgumentException;
+use MediaWiki\Storage\RevisionRecord;
+use Revision;
+use WikitextContent;
+
+/**
+ * Tests RevisionStore against the pre-MCR DB schema.
+ *
+ * @covers \MediaWiki\Storage\RevisionStore
+ *
+ * @group RevisionStore
+ * @group Storage
+ * @group Database
+ * @group medium
+ */
+class PreMcrRevisionStoreDbTest extends RevisionStoreDbTestBase {
+
+       use PreMcrSchemaOverride;
+
+       protected function revisionToRow( Revision $rev, $options = [ 'page', 'user', 'comment' ] ) {
+               $row = parent::revisionToRow( $rev, $options );
+
+               $row->rev_text_id = (string)$rev->getTextId();
+               $row->rev_content_format = (string)$rev->getContentFormat();
+               $row->rev_content_model = (string)$rev->getContentModel();
+
+               return $row;
+       }
+
+       protected function assertRevisionExistsInDatabase( RevisionRecord $rev ) {
+               // Legacy schema is still being written
+               $this->assertSelect(
+                       [ 'revision', 'text' ],
+                       [ 'count(*)' ],
+                       [ 'rev_id' => $rev->getId(), 'rev_text_id > 0' ],
+                       [ [ 1 ] ],
+                       [],
+                       [ 'text' => [ 'INNER JOIN', [ 'rev_text_id = old_id' ] ] ]
+               );
+
+               parent::assertRevisionExistsInDatabase( $rev );
+       }
+
+       public function provideGetArchiveQueryInfo() {
+               yield [
+                       [
+                               'tables' => [ 'archive' ],
+                               'fields' => array_merge(
+                                       $this->getDefaultArchiveFields(),
+                                       [
+                                               'ar_comment_text' => 'ar_comment',
+                                               'ar_comment_data' => 'NULL',
+                                               'ar_comment_cid' => 'NULL',
+                                               'ar_user_text' => 'ar_user_text',
+                                               'ar_user' => 'ar_user',
+                                               'ar_actor' => 'NULL',
+                                               'ar_content_format',
+                                               'ar_content_model',
+                                       ]
+                               ),
+                               'joins' => [],
+                       ]
+               ];
+       }
+
+       public function provideGetQueryInfo() {
+               yield [
+                       [],
+                       [
+                               'tables' => [ 'revision' ],
+                               'fields' => array_merge(
+                                       $this->getDefaultQueryFields(),
+                                       $this->getCommentQueryFields(),
+                                       $this->getActorQueryFields(),
+                                       $this->getContentHandlerQueryFields()
+                               ),
+                               'joins' => [],
+                       ]
+               ];
+               yield [
+                       [ 'page', 'user', 'text' ],
+                       [
+                               'tables' => [ 'revision', 'page', 'user', 'text' ],
+                               'fields' => array_merge(
+                                       $this->getDefaultQueryFields(),
+                                       $this->getCommentQueryFields(),
+                                       $this->getActorQueryFields(),
+                                       $this->getContentHandlerQueryFields(),
+                                       [
+                                               'page_namespace',
+                                               'page_title',
+                                               'page_id',
+                                               'page_latest',
+                                               'page_is_redirect',
+                                               'page_len',
+                                               'user_name',
+                                               'old_text',
+                                               'old_flags'
+                                       ]
+                               ),
+                               'joins' => [
+                                       'page' => [ 'INNER JOIN', [ 'page_id = rev_page' ] ],
+                                       'user' => [ 'LEFT JOIN', [ 'rev_user != 0', 'user_id = rev_user' ] ],
+                                       'text' => [ 'INNER JOIN', [ 'rev_text_id=old_id' ] ],
+                               ],
+                       ]
+               ];
+       }
+
+       public function provideGetSlotsQueryInfo() {
+               $db = wfGetDB( DB_REPLICA );
+
+               yield [
+                       [],
+                       [
+                               'tables' => [
+                                       'slots' => 'revision',
+                               ],
+                               'fields' => array_merge(
+                                       [
+                                               'slot_revision_id' => 'slots.rev_id',
+                                               'slot_content_id' => 'NULL',
+                                               'slot_origin' => 'slots.rev_id',
+                                               'role_name' => $db->addQuotes( 'main' ),
+                                       ]
+                               ),
+                               'joins' => [],
+                       ]
+               ];
+               yield [
+                       [ 'content' ],
+                       [
+                               'tables' => [
+                                       'slots' => 'revision',
+                               ],
+                               'fields' => array_merge(
+                                       [
+                                               'slot_revision_id' => 'slots.rev_id',
+                                               'slot_content_id' => 'NULL',
+                                               'slot_origin' => 'slots.rev_id',
+                                               'role_name' => $db->addQuotes( 'main' ),
+                                               'content_size' => 'slots.rev_len',
+                                               'content_sha1' => 'slots.rev_sha1',
+                                               'content_address' =>
+                                                       $db->buildConcat( [ $db->addQuotes( 'tt:' ), 'slots.rev_text_id' ] ),
+                                               'model_name' => 'slots.rev_content_model',
+                                       ]
+                               ),
+                               'joins' => [],
+                       ]
+               ];
+       }
+
+       public function provideInsertRevisionOn_failures() {
+               foreach ( parent::provideInsertRevisionOn_failures() as $case ) {
+                       yield $case;
+               }
+
+               yield 'slot that is not main slot' => [
+                       [
+                               'content' => [
+                                       'main' => new WikitextContent( 'Chicken' ),
+                                       'lalala' => new WikitextContent( 'Duck' ),
+                               ],
+                               'comment' => $this->getRandomCommentStoreComment(),
+                               'timestamp' => '20171117010101',
+                               'user' => true,
+                       ],
+                       new InvalidArgumentException( 'Only the main slot is supported' )
+               ];
+       }
+
+       public function provideNewMutableRevisionFromArray() {
+               foreach ( parent::provideNewMutableRevisionFromArray() as $case ) {
+                       yield $case;
+               }
+
+               yield 'Basic array, with page & id' => [
+                       [
+                               'id' => 2,
+                               'page' => 1,
+                               'text_id' => 2,
+                               'timestamp' => '20171017114835',
+                               'user_text' => '111.0.1.2',
+                               'user' => 0,
+                               'minor_edit' => false,
+                               'deleted' => 0,
+                               'len' => 46,
+                               'parent_id' => 1,
+                               'sha1' => 'rdqbbzs3pkhihgbs8qf2q9jsvheag5z',
+                               'comment' => 'Goat Comment!',
+                               'content_format' => 'text/x-wiki',
+                               'content_model' => 'wikitext',
+                       ]
+               ];
+       }
+
+}
diff --git a/tests/phpunit/includes/Storage/PreMcrSchemaOverride.php b/tests/phpunit/includes/Storage/PreMcrSchemaOverride.php
new file mode 100644 (file)
index 0000000..5d516e8
--- /dev/null
@@ -0,0 +1,54 @@
+<?php
+namespace MediaWiki\Tests\Storage;
+
+use Wikimedia\Rdbms\IMaintainableDatabase;
+use MediaWiki\DB\PatchFileLocation;
+
+/**
+ * Trait providing schema overrides that allow tests to run against the pre-MCR database schema.
+ */
+trait PreMcrSchemaOverride {
+
+       use PatchFileLocation;
+       use McrSchemaDetection;
+
+       /**
+        * @return int
+        */
+       protected function getMcrMigrationStage() {
+               return MIGRATION_OLD;
+       }
+
+       /**
+        * @return string[]
+        */
+       protected function getMcrTablesToReset() {
+               return [];
+       }
+
+       /**
+        * @override MediaWikiTestCase::getSchemaOverrides
+        * @return array[]
+        */
+       protected function getSchemaOverrides( IMaintainableDatabase $db ) {
+               $overrides = [
+                       'scripts' => [],
+                       'drop' => [],
+                       'create' => [],
+                       'alter' => [],
+               ];
+
+               if ( $this->hasMcrTables( $db ) ) {
+                       $overrides['drop'] = [ 'slots', 'content', 'slot_roles', 'content_models', ];
+                       $overrides['scripts'][] = $this->getSqlPatchPath( $db, '/drop-mcr-tables', __DIR__ );
+               }
+
+               if ( !$this->hasPreMcrFields( $db ) ) {
+                       $overrides['alter'][] = 'revision';
+                       $overrides['scripts'][] = $this->getSqlPatchPath( $db, '/create-pre-mcr-fields', __DIR__ );
+               }
+
+               return $overrides;
+       }
+
+}
index 95bba47..52647c2 100644 (file)
@@ -136,9 +136,9 @@ class RevisionSlotsTest extends MediaWikiTestCase {
        }
 
        /**
-        * @covers \MediaWiki\Storage\RevisionSlots::getTouchedSlots
+        * @covers \MediaWiki\Storage\RevisionSlots::getOriginalSlots
         */
-       public function testGetTouchedSlots() {
+       public function testGetOriginalSlots() {
                $mainSlot = SlotRecord::newUnsaved( 'main', new WikitextContent( 'A' ) );
                $auxSlot = SlotRecord::newInherited(
                        SlotRecord::newSaved(
@@ -149,7 +149,7 @@ class RevisionSlotsTest extends MediaWikiTestCase {
                $slotsArray = [ $mainSlot, $auxSlot ];
                $slots = $this->newRevisionSlots( $slotsArray );
 
-               $this->assertEquals( [ 'main' => $mainSlot ], $slots->getTouchedSlots() );
+               $this->assertEquals( [ 'main' => $mainSlot ], $slots->getOriginalSlots() );
        }
 
        public function provideComputeSize() {
@@ -224,4 +224,34 @@ class RevisionSlotsTest extends MediaWikiTestCase {
                $this->assertSame( $same, $b->hasSameContent( $a ) );
        }
 
+       public function provideGetRolesWithDifferentContent() {
+               $fooX = SlotRecord::newUnsaved( 'x', new TextContent( 'Foo' ) );
+               $barZ = SlotRecord::newUnsaved( 'z', new TextContent( 'Bar' ) );
+               $fooY = SlotRecord::newUnsaved( 'y', new TextContent( 'Foo' ) );
+               $barZS = SlotRecord::newSaved( 7, 7, 'xyz', $barZ );
+               $barZ2 = SlotRecord::newUnsaved( 'z', new TextContent( 'Baz' ) );
+
+               $a = $this->newRevisionSlots( [ 'x' => $fooX, 'z' => $barZ ] );
+               $a2 = $this->newRevisionSlots( [ 'x' => $fooX, 'z' => $barZ ] );
+               $a3 = $this->newRevisionSlots( [ 'x' => $fooX, 'z' => $barZS ] );
+               $b = $this->newRevisionSlots( [ 'y' => $fooY, 'z' => $barZ ] );
+               $c = $this->newRevisionSlots( [ 'x' => $fooX, 'z' => $barZ2 ] );
+
+               yield 'same instance' => [ $a, $a, [] ];
+               yield 'same slots' => [ $a, $a2, [] ];
+               yield 'same content' => [ $a, $a3, [] ];
+
+               yield 'different roles' => [ $a, $b, [ 'x', 'y' ] ];
+               yield 'different content' => [ $a, $c, [ 'z' ] ];
+       }
+
+       /**
+        * @dataProvider provideGetRolesWithDifferentContent
+        * @covers \MediaWiki\Storage\RevisionSlots::getRolesWithDifferentContent
+        */
+       public function testGetRolesWithDifferentContent( RevisionSlots $a, RevisionSlots $b, $roles ) {
+               $this->assertArrayEquals( $roles, $a->getRolesWithDifferentContent( $b ) );
+               $this->assertArrayEquals( $roles, $b->getRolesWithDifferentContent( $a ) );
+       }
+
 }
index 5b392c8..07a6971 100644 (file)
@@ -2,6 +2,8 @@
 
 namespace MediaWiki\Tests\Storage;
 
+use Content;
+use MediaWiki\Storage\MutableRevisionSlots;
 use MediaWiki\Storage\RevisionSlots;
 use MediaWiki\Storage\RevisionSlotsUpdate;
 use MediaWiki\Storage\RevisionAccessException;
@@ -41,8 +43,8 @@ class RevisionSlotsUpdateTest extends MediaWikiTestCase {
         *
         * @param RevisionSlots $newSlots
         * @param RevisionSlots $parentSlots
-        * @param $modified
-        * @param $removed
+        * @param string[] $modified
+        * @param string[] $removed
         */
        public function testNewFromRevisionSlots(
                RevisionSlots $newSlots,
@@ -60,6 +62,44 @@ class RevisionSlotsUpdateTest extends MediaWikiTestCase {
                }
        }
 
+       public function provideNewFromContent() {
+               $slotA = SlotRecord::newUnsaved( 'A', new WikitextContent( 'A' ) );
+               $slotB = SlotRecord::newUnsaved( 'B', new WikitextContent( 'B' ) );
+               $slotC = SlotRecord::newUnsaved( 'C', new WikitextContent( 'C' ) );
+
+               $parentSlots = new RevisionSlots( [
+                       'A' => $slotA,
+                       'B' => $slotB,
+                       'C' => $slotC,
+               ] );
+
+               $newContent = [
+                       'A' => new WikitextContent( 'A' ),
+                       'B' => new WikitextContent( 'B2' ),
+               ];
+
+               yield [ $newContent, null, [ 'A', 'B' ] ];
+               yield [ $newContent, $parentSlots, [ 'B' ] ];
+       }
+
+       /**
+        * @dataProvider provideNewFromContent
+        *
+        * @param Content[] $newContent
+        * @param RevisionSlots $parentSlots
+        * @param string[] $modified
+        */
+       public function testNewFromContent(
+               array $newContent,
+               RevisionSlots $parentSlots = null,
+               array $modified = []
+       ) {
+               $update = RevisionSlotsUpdate::newFromContent( $newContent, $parentSlots );
+
+               $this->assertEquals( $modified, $update->getModifiedRoles() );
+               $this->assertEmpty( $update->getRemovedRoles() );
+       }
+
        public function testConstructor() {
                $update = new RevisionSlotsUpdate();
 
@@ -204,4 +244,34 @@ class RevisionSlotsUpdateTest extends MediaWikiTestCase {
                $this->assertSame( $same, $b->hasSameUpdates( $a ) );
        }
 
+       /**
+        * @param string $role
+        * @param Content $content
+        * @return SlotRecord
+        */
+       private function newSavedSlot( $role, Content $content ) {
+               return SlotRecord::newSaved( 7, 7, 'xyz', SlotRecord::newUnsaved( $role, $content ) );
+       }
+
+       public function testApplyUpdate() {
+               /** @var SlotRecord[] $parentSlots */
+               $parentSlots = [
+                       'X' => $this->newSavedSlot( 'X', new WikitextContent( 'X' ) ),
+                       'Y' => $this->newSavedSlot( 'Y', new WikitextContent( 'Y' ) ),
+                       'Z' => $this->newSavedSlot( 'Z', new WikitextContent( 'Z' ) ),
+               ];
+               $slots = MutableRevisionSlots::newFromParentRevisionSlots( $parentSlots );
+               $update = RevisionSlotsUpdate::newFromContent( [
+                       'A' => new WikitextContent( 'A' ),
+                       'Y' => new WikitextContent( 'yyy' ),
+               ] );
+
+               $update->removeSlot( 'Z' );
+
+               $update->apply( $slots );
+               $this->assertSame( [ 'X', 'Y', 'A' ], $slots->getSlotRoles() );
+               $this->assertSame( $update->getModifiedSlot( 'A' ), $slots->getSlot( 'A' ) );
+               $this->assertSame( $update->getModifiedSlot( 'Y' ), $slots->getSlot( 'Y' ) );
+       }
+
 }
diff --git a/tests/phpunit/includes/Storage/RevisionStoreDbTest.php b/tests/phpunit/includes/Storage/RevisionStoreDbTest.php
deleted file mode 100644 (file)
index 2a92956..0000000
+++ /dev/null
@@ -1,1282 +0,0 @@
-<?php
-
-namespace MediaWiki\Tests\Storage;
-
-use CommentStoreComment;
-use Exception;
-use HashBagOStuff;
-use InvalidArgumentException;
-use Language;
-use MediaWiki\Linker\LinkTarget;
-use MediaWiki\MediaWikiServices;
-use MediaWiki\Storage\BlobStoreFactory;
-use MediaWiki\Storage\IncompleteRevisionException;
-use MediaWiki\Storage\MutableRevisionRecord;
-use MediaWiki\Storage\RevisionRecord;
-use MediaWiki\Storage\RevisionStore;
-use MediaWiki\Storage\SlotRecord;
-use MediaWiki\Storage\SqlBlobStore;
-use MediaWikiTestCase;
-use Revision;
-use TestUserRegistry;
-use Title;
-use WANObjectCache;
-use Wikimedia\Rdbms\Database;
-use Wikimedia\Rdbms\DatabaseSqlite;
-use Wikimedia\Rdbms\FakeResultWrapper;
-use Wikimedia\Rdbms\LoadBalancer;
-use Wikimedia\Rdbms\TransactionProfiler;
-use WikiPage;
-use WikitextContent;
-
-/**
- * @group Database
- */
-class RevisionStoreDbTest extends MediaWikiTestCase {
-
-       public function setUp() {
-               parent::setUp();
-               $this->tablesUsed[] = 'archive';
-               $this->tablesUsed[] = 'page';
-               $this->tablesUsed[] = 'revision';
-               $this->tablesUsed[] = 'comment';
-       }
-
-       /**
-        * @return LoadBalancer
-        */
-       private function getLoadBalancerMock( array $server ) {
-               $lb = $this->getMockBuilder( LoadBalancer::class )
-                       ->setMethods( [ 'reallyOpenConnection' ] )
-                       ->setConstructorArgs( [ [ 'servers' => [ $server ] ] ] )
-                       ->getMock();
-
-               $lb->method( 'reallyOpenConnection' )->willReturnCallback(
-                       function ( array $server, $dbNameOverride ) {
-                               return $this->getDatabaseMock( $server );
-                       }
-               );
-
-               return $lb;
-       }
-
-       /**
-        * @return Database
-        */
-       private function getDatabaseMock( array $params ) {
-               $db = $this->getMockBuilder( DatabaseSqlite::class )
-                       ->setMethods( [ 'select', 'doQuery', 'open', 'closeConnection', 'isOpen' ] )
-                       ->setConstructorArgs( [ $params ] )
-                       ->getMock();
-
-               $db->method( 'select' )->willReturn( new FakeResultWrapper( [] ) );
-               $db->method( 'isOpen' )->willReturn( true );
-
-               return $db;
-       }
-
-       public function provideDomainCheck() {
-               yield [ false, 'test', '' ];
-               yield [ 'test', 'test', '' ];
-
-               yield [ false, 'test', 'foo_' ];
-               yield [ 'test-foo_', 'test', 'foo_' ];
-
-               yield [ false, 'dash-test', '' ];
-               yield [ 'dash-test', 'dash-test', '' ];
-
-               yield [ false, 'underscore_test', 'foo_' ];
-               yield [ 'underscore_test-foo_', 'underscore_test', 'foo_' ];
-       }
-
-       /**
-        * @dataProvider provideDomainCheck
-        * @covers \MediaWiki\Storage\RevisionStore::checkDatabaseWikiId
-        */
-       public function testDomainCheck( $wikiId, $dbName, $dbPrefix ) {
-               $this->setMwGlobals(
-                       [
-                               'wgDBname' => $dbName,
-                               'wgDBprefix' => $dbPrefix,
-                       ]
-               );
-
-               $loadBalancer = $this->getLoadBalancerMock(
-                       [
-                               'host' => '*dummy*',
-                               'dbDirectory' => '*dummy*',
-                               'user' => 'test',
-                               'password' => 'test',
-                               'flags' => 0,
-                               'variables' => [],
-                               'schema' => '',
-                               'cliMode' => true,
-                               'agent' => '',
-                               'load' => 100,
-                               'profiler' => null,
-                               'trxProfiler' => new TransactionProfiler(),
-                               'connLogger' => new \Psr\Log\NullLogger(),
-                               'queryLogger' => new \Psr\Log\NullLogger(),
-                               'errorLogger' => function () {
-                               },
-                               'deprecationLogger' => function () {
-                               },
-                               'type' => 'test',
-                               'dbname' => $dbName,
-                               'tablePrefix' => $dbPrefix,
-                       ]
-               );
-               $db = $loadBalancer->getConnection( DB_REPLICA );
-
-               $blobStore = $this->getMockBuilder( SqlBlobStore::class )
-                       ->disableOriginalConstructor()
-                       ->getMock();
-
-               $store = new RevisionStore(
-                       $loadBalancer,
-                       $blobStore,
-                       new WANObjectCache( [ 'cache' => new HashBagOStuff() ] ),
-                       MediaWikiServices::getInstance()->getCommentStore(),
-                       MediaWikiServices::getInstance()->getActorMigration(),
-                       $wikiId
-               );
-
-               $count = $store->countRevisionsByPageId( $db, 0 );
-
-               // Dummy check to make PhpUnit happy. We are really only interested in
-               // countRevisionsByPageId not failing due to the DB domain check.
-               $this->assertSame( 0, $count );
-       }
-
-       private function assertLinkTargetsEqual( LinkTarget $l1, LinkTarget $l2 ) {
-               $this->assertEquals( $l1->getDBkey(), $l2->getDBkey() );
-               $this->assertEquals( $l1->getNamespace(), $l2->getNamespace() );
-               $this->assertEquals( $l1->getFragment(), $l2->getFragment() );
-               $this->assertEquals( $l1->getInterwiki(), $l2->getInterwiki() );
-       }
-
-       private function assertRevisionRecordsEqual( RevisionRecord $r1, RevisionRecord $r2 ) {
-               $this->assertEquals( $r1->getUser()->getName(), $r2->getUser()->getName() );
-               $this->assertEquals( $r1->getUser()->getId(), $r2->getUser()->getId() );
-               $this->assertEquals( $r1->getComment(), $r2->getComment() );
-               $this->assertEquals( $r1->getPageAsLinkTarget(), $r2->getPageAsLinkTarget() );
-               $this->assertEquals( $r1->getTimestamp(), $r2->getTimestamp() );
-               $this->assertEquals( $r1->getVisibility(), $r2->getVisibility() );
-               $this->assertEquals( $r1->getSha1(), $r2->getSha1() );
-               $this->assertEquals( $r1->getParentId(), $r2->getParentId() );
-               $this->assertEquals( $r1->getSize(), $r2->getSize() );
-               $this->assertEquals( $r1->getPageId(), $r2->getPageId() );
-               $this->assertEquals( $r1->getSlotRoles(), $r2->getSlotRoles() );
-               $this->assertEquals( $r1->getWikiId(), $r2->getWikiId() );
-               $this->assertEquals( $r1->isMinor(), $r2->isMinor() );
-               foreach ( $r1->getSlotRoles() as $role ) {
-                       $this->assertSlotRecordsEqual( $r1->getSlot( $role ), $r2->getSlot( $role ) );
-                       $this->assertTrue( $r1->getContent( $role )->equals( $r2->getContent( $role ) ) );
-               }
-               foreach ( [
-                       RevisionRecord::DELETED_TEXT,
-                       RevisionRecord::DELETED_COMMENT,
-                       RevisionRecord::DELETED_USER,
-                       RevisionRecord::DELETED_RESTRICTED,
-               ] as $field ) {
-                       $this->assertEquals( $r1->isDeleted( $field ), $r2->isDeleted( $field ) );
-               }
-       }
-
-       private function assertSlotRecordsEqual( SlotRecord $s1, SlotRecord $s2 ) {
-               $this->assertSame( $s1->getRole(), $s2->getRole() );
-               $this->assertSame( $s1->getModel(), $s2->getModel() );
-               $this->assertSame( $s1->getFormat(), $s2->getFormat() );
-               $this->assertSame( $s1->getSha1(), $s2->getSha1() );
-               $this->assertSame( $s1->getSize(), $s2->getSize() );
-               $this->assertTrue( $s1->getContent()->equals( $s2->getContent() ) );
-
-               $s1->hasRevision() ? $this->assertSame( $s1->getRevision(), $s2->getRevision() ) : null;
-               $s1->hasAddress() ? $this->assertSame( $s1->hasAddress(), $s2->hasAddress() ) : null;
-       }
-
-       private function assertRevisionCompleteness( RevisionRecord $r ) {
-               foreach ( $r->getSlotRoles() as $role ) {
-                       $this->assertSlotCompleteness( $r, $r->getSlot( $role ) );
-               }
-       }
-
-       private function assertSlotCompleteness( RevisionRecord $r, SlotRecord $slot ) {
-               $this->assertTrue( $slot->hasAddress() );
-               $this->assertSame( $r->getId(), $slot->getRevision() );
-       }
-
-       /**
-        * @param mixed[] $details
-        *
-        * @return RevisionRecord
-        */
-       private function getRevisionRecordFromDetailsArray( $title, $details = [] ) {
-               // Convert some values that can't be provided by dataProviders
-               $page = WikiPage::factory( $title );
-               if ( isset( $details['user'] ) && $details['user'] === true ) {
-                       $details['user'] = $this->getTestUser()->getUser();
-               }
-               if ( isset( $details['page'] ) && $details['page'] === true ) {
-                       $details['page'] = $page->getId();
-               }
-               if ( isset( $details['parent'] ) && $details['parent'] === true ) {
-                       $details['parent'] = $page->getLatest();
-               }
-
-               // Create the RevisionRecord with any available data
-               $rev = new MutableRevisionRecord( $title );
-               isset( $details['slot'] ) ? $rev->setSlot( $details['slot'] ) : null;
-               isset( $details['parent'] ) ? $rev->setParentId( $details['parent'] ) : null;
-               isset( $details['page'] ) ? $rev->setPageId( $details['page'] ) : null;
-               isset( $details['size'] ) ? $rev->setSize( $details['size'] ) : null;
-               isset( $details['sha1'] ) ? $rev->setSha1( $details['sha1'] ) : null;
-               isset( $details['comment'] ) ? $rev->setComment( $details['comment'] ) : null;
-               isset( $details['timestamp'] ) ? $rev->setTimestamp( $details['timestamp'] ) : null;
-               isset( $details['minor'] ) ? $rev->setMinorEdit( $details['minor'] ) : null;
-               isset( $details['user'] ) ? $rev->setUser( $details['user'] ) : null;
-               isset( $details['visibility'] ) ? $rev->setVisibility( $details['visibility'] ) : null;
-               isset( $details['id'] ) ? $rev->setId( $details['id'] ) : null;
-
-               return $rev;
-       }
-
-       private function getRandomCommentStoreComment() {
-               return CommentStoreComment::newUnsavedComment( __METHOD__ . '.' . rand( 0, 1000 ) );
-       }
-
-       public function provideInsertRevisionOn_successes() {
-               yield 'Bare minimum revision insertion' => [
-                       Title::newFromText( 'UTPage' ),
-                       [
-                               'slot' => SlotRecord::newUnsaved( 'main', new WikitextContent( 'Chicken' ) ),
-                               'parent' => true,
-                               'comment' => $this->getRandomCommentStoreComment(),
-                               'timestamp' => '20171117010101',
-                               'user' => true,
-                       ],
-               ];
-               yield 'Detailed revision insertion' => [
-                       Title::newFromText( 'UTPage' ),
-                       [
-                               'slot' => SlotRecord::newUnsaved( 'main', new WikitextContent( 'Chicken' ) ),
-                               'parent' => true,
-                               'page' => true,
-                               'comment' => $this->getRandomCommentStoreComment(),
-                               'timestamp' => '20171117010101',
-                               'user' => true,
-                               'minor' => true,
-                               'visibility' => RevisionRecord::DELETED_RESTRICTED,
-                       ],
-               ];
-       }
-
-       /**
-        * @dataProvider provideInsertRevisionOn_successes
-        * @covers \MediaWiki\Storage\RevisionStore::insertRevisionOn
-        */
-       public function testInsertRevisionOn_successes( Title $title, array $revDetails = [] ) {
-               $rev = $this->getRevisionRecordFromDetailsArray( $title, $revDetails );
-
-               $store = MediaWikiServices::getInstance()->getRevisionStore();
-               $return = $store->insertRevisionOn( $rev, wfGetDB( DB_MASTER ) );
-
-               $this->assertLinkTargetsEqual( $title, $return->getPageAsLinkTarget() );
-               $this->assertRevisionRecordsEqual( $rev, $return );
-               $this->assertRevisionCompleteness( $return );
-       }
-
-       /**
-        * @covers \MediaWiki\Storage\RevisionStore::insertRevisionOn
-        */
-       public function testInsertRevisionOn_blobAddressExists() {
-               $title = Title::newFromText( 'UTPage' );
-               $revDetails = [
-                       'slot' => SlotRecord::newUnsaved( 'main', new WikitextContent( 'Chicken' ) ),
-                       'parent' => true,
-                       'comment' => $this->getRandomCommentStoreComment(),
-                       'timestamp' => '20171117010101',
-                       'user' => true,
-               ];
-
-               $store = MediaWikiServices::getInstance()->getRevisionStore();
-
-               // Insert the first revision
-               $revOne = $this->getRevisionRecordFromDetailsArray( $title, $revDetails );
-               $firstReturn = $store->insertRevisionOn( $revOne, wfGetDB( DB_MASTER ) );
-               $this->assertLinkTargetsEqual( $title, $firstReturn->getPageAsLinkTarget() );
-               $this->assertRevisionRecordsEqual( $revOne, $firstReturn );
-
-               // Insert a second revision inheriting the same blob address
-               $revDetails['slot'] = SlotRecord::newInherited( $firstReturn->getSlot( 'main' ) );
-               $revTwo = $this->getRevisionRecordFromDetailsArray( $title, $revDetails );
-               $secondReturn = $store->insertRevisionOn( $revTwo, wfGetDB( DB_MASTER ) );
-               $this->assertLinkTargetsEqual( $title, $secondReturn->getPageAsLinkTarget() );
-               $this->assertRevisionRecordsEqual( $revTwo, $secondReturn );
-
-               // Assert that the same blob address has been used.
-               $this->assertEquals(
-                       $firstReturn->getSlot( 'main' )->getAddress(),
-                       $secondReturn->getSlot( 'main' )->getAddress()
-               );
-               // And that different revisions have been created.
-               $this->assertNotSame(
-                       $firstReturn->getId(),
-                       $secondReturn->getId()
-               );
-       }
-
-       public function provideInsertRevisionOn_failures() {
-               yield 'no slot' => [
-                       Title::newFromText( 'UTPage' ),
-                       [
-                               'comment' => $this->getRandomCommentStoreComment(),
-                               'timestamp' => '20171117010101',
-                               'user' => true,
-                       ],
-                       new InvalidArgumentException( 'At least one slot needs to be defined!' )
-               ];
-               yield 'slot that is not main slot' => [
-                       Title::newFromText( 'UTPage' ),
-                       [
-                               'slot' => SlotRecord::newUnsaved( 'lalala', new WikitextContent( 'Chicken' ) ),
-                               'comment' => $this->getRandomCommentStoreComment(),
-                               'timestamp' => '20171117010101',
-                               'user' => true,
-                       ],
-                       new InvalidArgumentException( 'Only the main slot is supported for now!' )
-               ];
-               yield 'no timestamp' => [
-                       Title::newFromText( 'UTPage' ),
-                       [
-                               'slot' => SlotRecord::newUnsaved( 'main', new WikitextContent( 'Chicken' ) ),
-                               'comment' => $this->getRandomCommentStoreComment(),
-                               'user' => true,
-                       ],
-                       new IncompleteRevisionException( 'timestamp field must not be NULL!' )
-               ];
-               yield 'no comment' => [
-                       Title::newFromText( 'UTPage' ),
-                       [
-                               'slot' => SlotRecord::newUnsaved( 'main', new WikitextContent( 'Chicken' ) ),
-                               'timestamp' => '20171117010101',
-                               'user' => true,
-                       ],
-                       new IncompleteRevisionException( 'comment must not be NULL!' )
-               ];
-               yield 'no user' => [
-                       Title::newFromText( 'UTPage' ),
-                       [
-                               'slot' => SlotRecord::newUnsaved( 'main', new WikitextContent( 'Chicken' ) ),
-                               'comment' => $this->getRandomCommentStoreComment(),
-                               'timestamp' => '20171117010101',
-                       ],
-                       new IncompleteRevisionException( 'user must not be NULL!' )
-               ];
-       }
-
-       /**
-        * @dataProvider provideInsertRevisionOn_failures
-        * @covers \MediaWiki\Storage\RevisionStore::insertRevisionOn
-        */
-       public function testInsertRevisionOn_failures(
-               Title $title,
-               array $revDetails = [],
-               Exception $exception ) {
-               $rev = $this->getRevisionRecordFromDetailsArray( $title, $revDetails );
-
-               $store = MediaWikiServices::getInstance()->getRevisionStore();
-
-               $this->setExpectedException(
-                       get_class( $exception ),
-                       $exception->getMessage(),
-                       $exception->getCode()
-               );
-               $store->insertRevisionOn( $rev, wfGetDB( DB_MASTER ) );
-       }
-
-       public function provideNewNullRevision() {
-               yield [
-                       Title::newFromText( 'UTPage' ),
-                       CommentStoreComment::newUnsavedComment( __METHOD__ . ' comment1' ),
-                       true,
-               ];
-               yield [
-                       Title::newFromText( 'UTPage' ),
-                       CommentStoreComment::newUnsavedComment( __METHOD__ . ' comment2', [ 'a' => 1 ] ),
-                       false,
-               ];
-       }
-
-       /**
-        * @dataProvider provideNewNullRevision
-        * @covers \MediaWiki\Storage\RevisionStore::newNullRevision
-        */
-       public function testNewNullRevision( Title $title, $comment, $minor ) {
-               $store = MediaWikiServices::getInstance()->getRevisionStore();
-               $user = TestUserRegistry::getMutableTestUser( __METHOD__ )->getUser();
-
-               $parent = $store->getRevisionByTitle( $title );
-               $record = $store->newNullRevision(
-                       wfGetDB( DB_MASTER ),
-                       $title,
-                       $comment,
-                       $minor,
-                       $user
-               );
-
-               $this->assertEquals( $title->getNamespace(), $record->getPageAsLinkTarget()->getNamespace() );
-               $this->assertEquals( $title->getDBkey(), $record->getPageAsLinkTarget()->getDBkey() );
-               $this->assertEquals( $comment, $record->getComment() );
-               $this->assertEquals( $minor, $record->isMinor() );
-               $this->assertEquals( $user->getName(), $record->getUser()->getName() );
-               $this->assertEquals( $parent->getId(), $record->getParentId() );
-
-               $parentSlot = $parent->getSlot( 'main' );
-               $slot = $record->getSlot( 'main' );
-
-               $this->assertTrue( $slot->isInherited(), 'isInherited' );
-               $this->assertSame( $parentSlot->getOrigin(), $slot->getOrigin(), 'getOrigin' );
-               $this->assertSame( $parentSlot->getAddress(), $slot->getAddress(), 'getAddress' );
-       }
-
-       /**
-        * @covers \MediaWiki\Storage\RevisionStore::newNullRevision
-        */
-       public function testNewNullRevision_nonExistingTitle() {
-               $store = MediaWikiServices::getInstance()->getRevisionStore();
-               $record = $store->newNullRevision(
-                       wfGetDB( DB_MASTER ),
-                       Title::newFromText( __METHOD__ . '.iDontExist!' ),
-                       CommentStoreComment::newUnsavedComment( __METHOD__ . ' comment' ),
-                       false,
-                       TestUserRegistry::getMutableTestUser( __METHOD__ )->getUser()
-               );
-               $this->assertNull( $record );
-       }
-
-       /**
-        * @covers \MediaWiki\Storage\RevisionStore::getRcIdIfUnpatrolled
-        */
-       public function testGetRcIdIfUnpatrolled_returnsRecentChangesId() {
-               $page = WikiPage::factory( Title::newFromText( 'UTPage' ) );
-               $status = $page->doEditContent( new WikitextContent( __METHOD__ ), __METHOD__ );
-               /** @var Revision $rev */
-               $rev = $status->value['revision'];
-
-               $store = MediaWikiServices::getInstance()->getRevisionStore();
-               $revisionRecord = $store->getRevisionById( $rev->getId() );
-               $result = $store->getRcIdIfUnpatrolled( $revisionRecord );
-
-               $this->assertGreaterThan( 0, $result );
-               $this->assertSame(
-                       $page->getRevision()->getRecentChange()->getAttribute( 'rc_id' ),
-                       $result
-               );
-       }
-
-       /**
-        * @covers \MediaWiki\Storage\RevisionStore::getRcIdIfUnpatrolled
-        */
-       public function testGetRcIdIfUnpatrolled_returnsZeroIfPatrolled() {
-               // This assumes that sysops are auto patrolled
-               $sysop = $this->getTestSysop()->getUser();
-               $page = WikiPage::factory( Title::newFromText( 'UTPage' ) );
-               $status = $page->doEditContent(
-                       new WikitextContent( __METHOD__ ),
-                       __METHOD__,
-                       0,
-                       false,
-                       $sysop
-               );
-               /** @var Revision $rev */
-               $rev = $status->value['revision'];
-
-               $store = MediaWikiServices::getInstance()->getRevisionStore();
-               $revisionRecord = $store->getRevisionById( $rev->getId() );
-               $result = $store->getRcIdIfUnpatrolled( $revisionRecord );
-
-               $this->assertSame( 0, $result );
-       }
-
-       /**
-        * @covers \MediaWiki\Storage\RevisionStore::getRecentChange
-        */
-       public function testGetRecentChange() {
-               $page = WikiPage::factory( Title::newFromText( 'UTPage' ) );
-               $content = new WikitextContent( __METHOD__ );
-               $status = $page->doEditContent( $content, __METHOD__ );
-               /** @var Revision $rev */
-               $rev = $status->value['revision'];
-
-               $store = MediaWikiServices::getInstance()->getRevisionStore();
-               $revRecord = $store->getRevisionById( $rev->getId() );
-               $recentChange = $store->getRecentChange( $revRecord );
-
-               $this->assertEquals( $rev->getId(), $recentChange->getAttribute( 'rc_this_oldid' ) );
-               $this->assertEquals( $rev->getRecentChange(), $recentChange );
-       }
-
-       /**
-        * @covers \MediaWiki\Storage\RevisionStore::getRevisionById
-        */
-       public function testGetRevisionById() {
-               $page = WikiPage::factory( Title::newFromText( 'UTPage' ) );
-               $content = new WikitextContent( __METHOD__ );
-               $status = $page->doEditContent( $content, __METHOD__ );
-               /** @var Revision $rev */
-               $rev = $status->value['revision'];
-
-               $store = MediaWikiServices::getInstance()->getRevisionStore();
-               $revRecord = $store->getRevisionById( $rev->getId() );
-
-               $this->assertSame( $rev->getId(), $revRecord->getId() );
-               $this->assertTrue( $revRecord->getSlot( 'main' )->getContent()->equals( $content ) );
-               $this->assertSame( __METHOD__, $revRecord->getComment()->text );
-       }
-
-       /**
-        * @covers \MediaWiki\Storage\RevisionStore::getRevisionByTitle
-        */
-       public function testGetRevisionByTitle() {
-               $page = WikiPage::factory( Title::newFromText( 'UTPage' ) );
-               $content = new WikitextContent( __METHOD__ );
-               $status = $page->doEditContent( $content, __METHOD__ );
-               /** @var Revision $rev */
-               $rev = $status->value['revision'];
-
-               $store = MediaWikiServices::getInstance()->getRevisionStore();
-               $revRecord = $store->getRevisionByTitle( $page->getTitle() );
-
-               $this->assertSame( $rev->getId(), $revRecord->getId() );
-               $this->assertTrue( $revRecord->getSlot( 'main' )->getContent()->equals( $content ) );
-               $this->assertSame( __METHOD__, $revRecord->getComment()->text );
-       }
-
-       /**
-        * @covers \MediaWiki\Storage\RevisionStore::getRevisionByPageId
-        */
-       public function testGetRevisionByPageId() {
-               $page = WikiPage::factory( Title::newFromText( 'UTPage' ) );
-               $content = new WikitextContent( __METHOD__ );
-               $status = $page->doEditContent( $content, __METHOD__ );
-               /** @var Revision $rev */
-               $rev = $status->value['revision'];
-
-               $store = MediaWikiServices::getInstance()->getRevisionStore();
-               $revRecord = $store->getRevisionByPageId( $page->getId() );
-
-               $this->assertSame( $rev->getId(), $revRecord->getId() );
-               $this->assertTrue( $revRecord->getSlot( 'main' )->getContent()->equals( $content ) );
-               $this->assertSame( __METHOD__, $revRecord->getComment()->text );
-       }
-
-       /**
-        * @covers \MediaWiki\Storage\RevisionStore::getRevisionByTimestamp
-        */
-       public function testGetRevisionByTimestamp() {
-               // Make sure there is 1 second between the last revision and the rev we create...
-               // Otherwise we might not get the correct revision and the test may fail...
-               // :(
-               sleep( 1 );
-               $page = WikiPage::factory( Title::newFromText( 'UTPage' ) );
-               $content = new WikitextContent( __METHOD__ );
-               $status = $page->doEditContent( $content, __METHOD__ );
-               /** @var Revision $rev */
-               $rev = $status->value['revision'];
-
-               $store = MediaWikiServices::getInstance()->getRevisionStore();
-               $revRecord = $store->getRevisionByTimestamp(
-                       $page->getTitle(),
-                       $rev->getTimestamp()
-               );
-
-               $this->assertSame( $rev->getId(), $revRecord->getId() );
-               $this->assertTrue( $revRecord->getSlot( 'main' )->getContent()->equals( $content ) );
-               $this->assertSame( __METHOD__, $revRecord->getComment()->text );
-       }
-
-       private function revisionToRow( Revision $rev ) {
-               $page = WikiPage::factory( $rev->getTitle() );
-
-               return (object)[
-                       'rev_id' => (string)$rev->getId(),
-                       'rev_page' => (string)$rev->getPage(),
-                       'rev_text_id' => (string)$rev->getTextId(),
-                       'rev_timestamp' => (string)$rev->getTimestamp(),
-                       'rev_user_text' => (string)$rev->getUserText(),
-                       'rev_user' => (string)$rev->getUser(),
-                       'rev_minor_edit' => $rev->isMinor() ? '1' : '0',
-                       'rev_deleted' => (string)$rev->getVisibility(),
-                       'rev_len' => (string)$rev->getSize(),
-                       'rev_parent_id' => (string)$rev->getParentId(),
-                       'rev_sha1' => (string)$rev->getSha1(),
-                       'rev_comment_text' => $rev->getComment(),
-                       'rev_comment_data' => null,
-                       'rev_comment_cid' => null,
-                       'rev_content_format' => $rev->getContentFormat(),
-                       'rev_content_model' => $rev->getContentModel(),
-                       'page_namespace' => (string)$page->getTitle()->getNamespace(),
-                       'page_title' => $page->getTitle()->getDBkey(),
-                       'page_id' => (string)$page->getId(),
-                       'page_latest' => (string)$page->getLatest(),
-                       'page_is_redirect' => $page->isRedirect() ? '1' : '0',
-                       'page_len' => (string)$page->getContent()->getSize(),
-                       'user_name' => (string)$rev->getUserText(),
-               ];
-       }
-
-       private function assertRevisionRecordMatchesRevision(
-               Revision $rev,
-               RevisionRecord $record
-       ) {
-               $this->assertSame( $rev->getId(), $record->getId() );
-               $this->assertSame( $rev->getPage(), $record->getPageId() );
-               $this->assertSame( $rev->getTimestamp(), $record->getTimestamp() );
-               $this->assertSame( $rev->getUserText(), $record->getUser()->getName() );
-               $this->assertSame( $rev->getUser(), $record->getUser()->getId() );
-               $this->assertSame( $rev->isMinor(), $record->isMinor() );
-               $this->assertSame( $rev->getVisibility(), $record->getVisibility() );
-               $this->assertSame( $rev->getSize(), $record->getSize() );
-               /**
-                * @note As of MW 1.31, the database schema allows the parent ID to be
-                * NULL to indicate that it is unknown.
-                */
-               $expectedParent = $rev->getParentId();
-               if ( $expectedParent === null ) {
-                       $expectedParent = 0;
-               }
-               $this->assertSame( $expectedParent, $record->getParentId() );
-               $this->assertSame( $rev->getSha1(), $record->getSha1() );
-               $this->assertSame( $rev->getComment(), $record->getComment()->text );
-               $this->assertSame( $rev->getContentFormat(), $record->getContent( 'main' )->getDefaultFormat() );
-               $this->assertSame( $rev->getContentModel(), $record->getContent( 'main' )->getModel() );
-               $this->assertLinkTargetsEqual( $rev->getTitle(), $record->getPageAsLinkTarget() );
-       }
-
-       /**
-        * @covers \MediaWiki\Storage\RevisionStore::newRevisionFromRow
-        * @covers \MediaWiki\Storage\RevisionStore::newRevisionFromRow_1_29
-        */
-       public function testNewRevisionFromRow_anonEdit() {
-               $this->setMwGlobals( 'wgActorTableSchemaMigrationStage', MIGRATION_WRITE_BOTH );
-               $this->overrideMwServices();
-
-               $page = WikiPage::factory( Title::newFromText( 'UTPage' ) );
-               $text = __METHOD__ . 'a-ä';
-               /** @var Revision $rev */
-               $rev = $page->doEditContent(
-                       new WikitextContent( $text ),
-                       __METHOD__ . 'a'
-               )->value['revision'];
-
-               $store = MediaWikiServices::getInstance()->getRevisionStore();
-               $record = $store->newRevisionFromRow(
-                       $this->revisionToRow( $rev ),
-                       [],
-                       $page->getTitle()
-               );
-               $this->assertRevisionRecordMatchesRevision( $rev, $record );
-               $this->assertSame( $text, $rev->getContent()->serialize() );
-       }
-
-       /**
-        * @covers \MediaWiki\Storage\RevisionStore::newRevisionFromRow
-        * @covers \MediaWiki\Storage\RevisionStore::newRevisionFromRow_1_29
-        */
-       public function testNewRevisionFromRow_anonEdit_legacyEncoding() {
-               $this->setMwGlobals( 'wgLegacyEncoding', 'windows-1252' );
-               $this->overrideMwServices();
-               $page = WikiPage::factory( Title::newFromText( 'UTPage' ) );
-               $text = __METHOD__ . 'a-ä';
-               /** @var Revision $rev */
-               $rev = $page->doEditContent(
-                       new WikitextContent( $text ),
-                       __METHOD__. 'a'
-               )->value['revision'];
-
-               $store = MediaWikiServices::getInstance()->getRevisionStore();
-               $record = $store->newRevisionFromRow(
-                       $this->revisionToRow( $rev ),
-                       [],
-                       $page->getTitle()
-               );
-               $this->assertRevisionRecordMatchesRevision( $rev, $record );
-               $this->assertSame( $text, $rev->getContent()->serialize() );
-       }
-
-       /**
-        * @covers \MediaWiki\Storage\RevisionStore::newRevisionFromRow
-        * @covers \MediaWiki\Storage\RevisionStore::newRevisionFromRow_1_29
-        */
-       public function testNewRevisionFromRow_userEdit() {
-               $this->setMwGlobals( 'wgActorTableSchemaMigrationStage', MIGRATION_WRITE_BOTH );
-               $this->overrideMwServices();
-
-               $page = WikiPage::factory( Title::newFromText( 'UTPage' ) );
-               $text = __METHOD__ . 'b-ä';
-               /** @var Revision $rev */
-               $rev = $page->doEditContent(
-                       new WikitextContent( $text ),
-                       __METHOD__ . 'b',
-                       0,
-                       false,
-                       $this->getTestUser()->getUser()
-               )->value['revision'];
-
-               $store = MediaWikiServices::getInstance()->getRevisionStore();
-               $record = $store->newRevisionFromRow(
-                       $this->revisionToRow( $rev ),
-                       [],
-                       $page->getTitle()
-               );
-               $this->assertRevisionRecordMatchesRevision( $rev, $record );
-               $this->assertSame( $text, $rev->getContent()->serialize() );
-       }
-
-       /**
-        * @covers \MediaWiki\Storage\RevisionStore::newRevisionFromArchiveRow
-        */
-       public function testNewRevisionFromArchiveRow() {
-               $store = MediaWikiServices::getInstance()->getRevisionStore();
-               $title = Title::newFromText( __METHOD__ );
-               $text = __METHOD__ . '-bä';
-               $page = WikiPage::factory( $title );
-               /** @var Revision $orig */
-               $orig = $page->doEditContent( new WikitextContent( $text ), __METHOD__ )
-                       ->value['revision'];
-               $page->doDeleteArticle( __METHOD__ );
-
-               $db = wfGetDB( DB_MASTER );
-               $arQuery = $store->getArchiveQueryInfo();
-               $res = $db->select(
-                       $arQuery['tables'], $arQuery['fields'], [ 'ar_rev_id' => $orig->getId() ],
-                       __METHOD__, [], $arQuery['joins']
-               );
-               $this->assertTrue( is_object( $res ), 'query failed' );
-
-               $row = $res->fetchObject();
-               $res->free();
-               $record = $store->newRevisionFromArchiveRow( $row );
-
-               $this->assertRevisionRecordMatchesRevision( $orig, $record );
-               $this->assertSame( $text, $record->getContent( 'main' )->serialize() );
-       }
-
-       /**
-        * @covers \MediaWiki\Storage\RevisionStore::newRevisionFromArchiveRow
-        */
-       public function testNewRevisionFromArchiveRow_legacyEncoding() {
-               $this->setMwGlobals( 'wgLegacyEncoding', 'windows-1252' );
-               $this->overrideMwServices();
-               $store = MediaWikiServices::getInstance()->getRevisionStore();
-               $title = Title::newFromText( __METHOD__ );
-               $text = __METHOD__ . '-bä';
-               $page = WikiPage::factory( $title );
-               /** @var Revision $orig */
-               $orig = $page->doEditContent( new WikitextContent( $text ), __METHOD__ )
-                       ->value['revision'];
-               $page->doDeleteArticle( __METHOD__ );
-
-               $db = wfGetDB( DB_MASTER );
-               $arQuery = $store->getArchiveQueryInfo();
-               $res = $db->select(
-                       $arQuery['tables'], $arQuery['fields'], [ 'ar_rev_id' => $orig->getId() ],
-                       __METHOD__, [], $arQuery['joins']
-               );
-               $this->assertTrue( is_object( $res ), 'query failed' );
-
-               $row = $res->fetchObject();
-               $res->free();
-               $record = $store->newRevisionFromArchiveRow( $row );
-
-               $this->assertRevisionRecordMatchesRevision( $orig, $record );
-               $this->assertSame( $text, $record->getContent( 'main' )->serialize() );
-       }
-
-       /**
-        * @covers \MediaWiki\Storage\RevisionStore::loadRevisionFromId
-        */
-       public function testLoadRevisionFromId() {
-               $title = Title::newFromText( __METHOD__ );
-               $page = WikiPage::factory( $title );
-               /** @var Revision $rev */
-               $rev = $page->doEditContent( new WikitextContent( __METHOD__ ), __METHOD__ )
-                       ->value['revision'];
-
-               $store = MediaWikiServices::getInstance()->getRevisionStore();
-               $result = $store->loadRevisionFromId( wfGetDB( DB_MASTER ), $rev->getId() );
-               $this->assertRevisionRecordMatchesRevision( $rev, $result );
-       }
-
-       /**
-        * @covers \MediaWiki\Storage\RevisionStore::loadRevisionFromPageId
-        */
-       public function testLoadRevisionFromPageId() {
-               $title = Title::newFromText( __METHOD__ );
-               $page = WikiPage::factory( $title );
-               /** @var Revision $rev */
-               $rev = $page->doEditContent( new WikitextContent( __METHOD__ ), __METHOD__ )
-                       ->value['revision'];
-
-               $store = MediaWikiServices::getInstance()->getRevisionStore();
-               $result = $store->loadRevisionFromPageId( wfGetDB( DB_MASTER ), $page->getId() );
-               $this->assertRevisionRecordMatchesRevision( $rev, $result );
-       }
-
-       /**
-        * @covers \MediaWiki\Storage\RevisionStore::loadRevisionFromTitle
-        */
-       public function testLoadRevisionFromTitle() {
-               $title = Title::newFromText( __METHOD__ );
-               $page = WikiPage::factory( $title );
-               /** @var Revision $rev */
-               $rev = $page->doEditContent( new WikitextContent( __METHOD__ ), __METHOD__ )
-                       ->value['revision'];
-
-               $store = MediaWikiServices::getInstance()->getRevisionStore();
-               $result = $store->loadRevisionFromTitle( wfGetDB( DB_MASTER ), $title );
-               $this->assertRevisionRecordMatchesRevision( $rev, $result );
-       }
-
-       /**
-        * @covers \MediaWiki\Storage\RevisionStore::loadRevisionFromTimestamp
-        */
-       public function testLoadRevisionFromTimestamp() {
-               $title = Title::newFromText( __METHOD__ );
-               $page = WikiPage::factory( $title );
-               /** @var Revision $revOne */
-               $revOne = $page->doEditContent( new WikitextContent( __METHOD__ ), __METHOD__ )
-                       ->value['revision'];
-               // Sleep to ensure different timestamps... )(evil)
-               sleep( 1 );
-               /** @var Revision $revTwo */
-               $revTwo = $page->doEditContent( new WikitextContent( __METHOD__ . 'a' ), '' )
-                       ->value['revision'];
-
-               $store = MediaWikiServices::getInstance()->getRevisionStore();
-               $this->assertNull(
-                       $store->loadRevisionFromTimestamp( wfGetDB( DB_MASTER ), $title, '20150101010101' )
-               );
-               $this->assertSame(
-                       $revOne->getId(),
-                       $store->loadRevisionFromTimestamp(
-                               wfGetDB( DB_MASTER ),
-                               $title,
-                               $revOne->getTimestamp()
-                       )->getId()
-               );
-               $this->assertSame(
-                       $revTwo->getId(),
-                       $store->loadRevisionFromTimestamp(
-                               wfGetDB( DB_MASTER ),
-                               $title,
-                               $revTwo->getTimestamp()
-                       )->getId()
-               );
-       }
-
-       /**
-        * @covers \MediaWiki\Storage\RevisionStore::listRevisionSizes
-        */
-       public function testGetParentLengths() {
-               $page = WikiPage::factory( Title::newFromText( __METHOD__ ) );
-               /** @var Revision $revOne */
-               $revOne = $page->doEditContent(
-                       new WikitextContent( __METHOD__ ), __METHOD__
-               )->value['revision'];
-               /** @var Revision $revTwo */
-               $revTwo = $page->doEditContent(
-                       new WikitextContent( __METHOD__ . '2' ), __METHOD__
-               )->value['revision'];
-
-               $store = MediaWikiServices::getInstance()->getRevisionStore();
-               $this->assertSame(
-                       [
-                               $revOne->getId() => strlen( __METHOD__ ),
-                       ],
-                       $store->listRevisionSizes(
-                               wfGetDB( DB_MASTER ),
-                               [ $revOne->getId() ]
-                       )
-               );
-               $this->assertSame(
-                       [
-                               $revOne->getId() => strlen( __METHOD__ ),
-                               $revTwo->getId() => strlen( __METHOD__ ) + 1,
-                       ],
-                       $store->listRevisionSizes(
-                               wfGetDB( DB_MASTER ),
-                               [ $revOne->getId(), $revTwo->getId() ]
-                       )
-               );
-       }
-
-       /**
-        * @covers \MediaWiki\Storage\RevisionStore::getPreviousRevision
-        */
-       public function testGetPreviousRevision() {
-               $page = WikiPage::factory( Title::newFromText( __METHOD__ ) );
-               /** @var Revision $revOne */
-               $revOne = $page->doEditContent(
-                       new WikitextContent( __METHOD__ ), __METHOD__
-               )->value['revision'];
-               /** @var Revision $revTwo */
-               $revTwo = $page->doEditContent(
-                       new WikitextContent( __METHOD__ . '2' ), __METHOD__
-               )->value['revision'];
-
-               $store = MediaWikiServices::getInstance()->getRevisionStore();
-               $this->assertNull(
-                       $store->getPreviousRevision( $store->getRevisionById( $revOne->getId() ) )
-               );
-               $this->assertSame(
-                       $revOne->getId(),
-                       $store->getPreviousRevision( $store->getRevisionById( $revTwo->getId() ) )->getId()
-               );
-       }
-
-       /**
-        * @covers \MediaWiki\Storage\RevisionStore::getNextRevision
-        */
-       public function testGetNextRevision() {
-               $page = WikiPage::factory( Title::newFromText( __METHOD__ ) );
-               /** @var Revision $revOne */
-               $revOne = $page->doEditContent(
-                       new WikitextContent( __METHOD__ ), __METHOD__
-               )->value['revision'];
-               /** @var Revision $revTwo */
-               $revTwo = $page->doEditContent(
-                       new WikitextContent( __METHOD__ . '2' ), __METHOD__
-               )->value['revision'];
-
-               $store = MediaWikiServices::getInstance()->getRevisionStore();
-               $this->assertSame(
-                       $revTwo->getId(),
-                       $store->getNextRevision( $store->getRevisionById( $revOne->getId() ) )->getId()
-               );
-               $this->assertNull(
-                       $store->getNextRevision( $store->getRevisionById( $revTwo->getId() ) )
-               );
-       }
-
-       /**
-        * @covers \MediaWiki\Storage\RevisionStore::getTimestampFromId
-        */
-       public function testGetTimestampFromId_found() {
-               $page = WikiPage::factory( Title::newFromText( 'UTPage' ) );
-               /** @var Revision $rev */
-               $rev = $page->doEditContent( new WikitextContent( __METHOD__ ), __METHOD__ )
-                       ->value['revision'];
-
-               $store = MediaWikiServices::getInstance()->getRevisionStore();
-               $result = $store->getTimestampFromId(
-                       $page->getTitle(),
-                       $rev->getId()
-               );
-
-               $this->assertSame( $rev->getTimestamp(), $result );
-       }
-
-       /**
-        * @covers \MediaWiki\Storage\RevisionStore::getTimestampFromId
-        */
-       public function testGetTimestampFromId_notFound() {
-               $page = WikiPage::factory( Title::newFromText( 'UTPage' ) );
-               /** @var Revision $rev */
-               $rev = $page->doEditContent( new WikitextContent( __METHOD__ ), __METHOD__ )
-                       ->value['revision'];
-
-               $store = MediaWikiServices::getInstance()->getRevisionStore();
-               $result = $store->getTimestampFromId(
-                       $page->getTitle(),
-                       $rev->getId() + 1
-               );
-
-               $this->assertFalse( $result );
-       }
-
-       /**
-        * @covers \MediaWiki\Storage\RevisionStore::countRevisionsByPageId
-        */
-       public function testCountRevisionsByPageId() {
-               $store = MediaWikiServices::getInstance()->getRevisionStore();
-               $page = WikiPage::factory( Title::newFromText( __METHOD__ ) );
-
-               $this->assertSame(
-                       0,
-                       $store->countRevisionsByPageId( wfGetDB( DB_MASTER ), $page->getId() )
-               );
-               $page->doEditContent( new WikitextContent( 'a' ), 'a' );
-               $this->assertSame(
-                       1,
-                       $store->countRevisionsByPageId( wfGetDB( DB_MASTER ), $page->getId() )
-               );
-               $page->doEditContent( new WikitextContent( 'b' ), 'b' );
-               $this->assertSame(
-                       2,
-                       $store->countRevisionsByPageId( wfGetDB( DB_MASTER ), $page->getId() )
-               );
-       }
-
-       /**
-        * @covers \MediaWiki\Storage\RevisionStore::countRevisionsByTitle
-        */
-       public function testCountRevisionsByTitle() {
-               $store = MediaWikiServices::getInstance()->getRevisionStore();
-               $page = WikiPage::factory( Title::newFromText( __METHOD__ ) );
-
-               $this->assertSame(
-                       0,
-                       $store->countRevisionsByTitle( wfGetDB( DB_MASTER ), $page->getTitle() )
-               );
-               $page->doEditContent( new WikitextContent( 'a' ), 'a' );
-               $this->assertSame(
-                       1,
-                       $store->countRevisionsByTitle( wfGetDB( DB_MASTER ), $page->getTitle() )
-               );
-               $page->doEditContent( new WikitextContent( 'b' ), 'b' );
-               $this->assertSame(
-                       2,
-                       $store->countRevisionsByTitle( wfGetDB( DB_MASTER ), $page->getTitle() )
-               );
-       }
-
-       /**
-        * @covers \MediaWiki\Storage\RevisionStore::userWasLastToEdit
-        */
-       public function testUserWasLastToEdit_false() {
-               $sysop = $this->getTestSysop()->getUser();
-               $page = WikiPage::factory( Title::newFromText( 'UTPage' ) );
-               $page->doEditContent( new WikitextContent( __METHOD__ ), __METHOD__ );
-
-               $store = MediaWikiServices::getInstance()->getRevisionStore();
-               $result = $store->userWasLastToEdit(
-                       wfGetDB( DB_MASTER ),
-                       $page->getId(),
-                       $sysop->getId(),
-                       '20160101010101'
-               );
-               $this->assertFalse( $result );
-       }
-
-       /**
-        * @covers \MediaWiki\Storage\RevisionStore::userWasLastToEdit
-        */
-       public function testUserWasLastToEdit_true() {
-               $startTime = wfTimestampNow();
-               $sysop = $this->getTestSysop()->getUser();
-               $page = WikiPage::factory( Title::newFromText( 'UTPage' ) );
-               $page->doEditContent(
-                       new WikitextContent( __METHOD__ ),
-                       __METHOD__,
-                       0,
-                       false,
-                       $sysop
-               );
-
-               $store = MediaWikiServices::getInstance()->getRevisionStore();
-               $result = $store->userWasLastToEdit(
-                       wfGetDB( DB_MASTER ),
-                       $page->getId(),
-                       $sysop->getId(),
-                       $startTime
-               );
-               $this->assertTrue( $result );
-       }
-
-       /**
-        * @covers \MediaWiki\Storage\RevisionStore::getKnownCurrentRevision
-        */
-       public function testGetKnownCurrentRevision() {
-               $page = WikiPage::factory( Title::newFromText( 'UTPage' ) );
-               /** @var Revision $rev */
-               $rev = $page->doEditContent(
-                       new WikitextContent( __METHOD__ . 'b' ),
-                       __METHOD__ . 'b',
-                       0,
-                       false,
-                       $this->getTestUser()->getUser()
-               )->value['revision'];
-
-               $store = MediaWikiServices::getInstance()->getRevisionStore();
-               $record = $store->getKnownCurrentRevision(
-                       $page->getTitle(),
-                       $rev->getId()
-               );
-
-               $this->assertRevisionRecordMatchesRevision( $rev, $record );
-       }
-
-       public function provideNewMutableRevisionFromArray() {
-               yield 'Basic array, with page & id' => [
-                       [
-                               'id' => 2,
-                               'page' => 1,
-                               'text_id' => 2,
-                               'timestamp' => '20171017114835',
-                               'user_text' => '111.0.1.2',
-                               'user' => 0,
-                               'minor_edit' => false,
-                               'deleted' => 0,
-                               'len' => 46,
-                               'parent_id' => 1,
-                               'sha1' => 'rdqbbzs3pkhihgbs8qf2q9jsvheag5z',
-                               'comment' => 'Goat Comment!',
-                               'content_format' => 'text/x-wiki',
-                               'content_model' => 'wikitext',
-                       ]
-               ];
-               yield 'Basic array, content object' => [
-                       [
-                               'id' => 2,
-                               'page' => 1,
-                               'timestamp' => '20171017114835',
-                               'user_text' => '111.0.1.2',
-                               'user' => 0,
-                               'minor_edit' => false,
-                               'deleted' => 0,
-                               'len' => 46,
-                               'parent_id' => 1,
-                               'sha1' => 'rdqbbzs3pkhihgbs8qf2q9jsvheag5z',
-                               'comment' => 'Goat Comment!',
-                               'content' => new WikitextContent( 'Some Content' ),
-                       ]
-               ];
-               yield 'Basic array, serialized text' => [
-                       [
-                               'id' => 2,
-                               'page' => 1,
-                               'timestamp' => '20171017114835',
-                               'user_text' => '111.0.1.2',
-                               'user' => 0,
-                               'minor_edit' => false,
-                               'deleted' => 0,
-                               'len' => 46,
-                               'parent_id' => 1,
-                               'sha1' => 'rdqbbzs3pkhihgbs8qf2q9jsvheag5z',
-                               'comment' => 'Goat Comment!',
-                               'text' => ( new WikitextContent( 'Söme Content' ) )->serialize(),
-                       ]
-               ];
-               yield 'Basic array, serialized text, utf-8 flags' => [
-                       [
-                               'id' => 2,
-                               'page' => 1,
-                               'timestamp' => '20171017114835',
-                               'user_text' => '111.0.1.2',
-                               'user' => 0,
-                               'minor_edit' => false,
-                               'deleted' => 0,
-                               'len' => 46,
-                               'parent_id' => 1,
-                               'sha1' => 'rdqbbzs3pkhihgbs8qf2q9jsvheag5z',
-                               'comment' => 'Goat Comment!',
-                               'text' => ( new WikitextContent( 'Söme Content' ) )->serialize(),
-                               'flags' => 'utf-8',
-                       ]
-               ];
-               yield 'Basic array, with title' => [
-                       [
-                               'title' => Title::newFromText( 'SomeText' ),
-                               'text_id' => 2,
-                               'timestamp' => '20171017114835',
-                               'user_text' => '111.0.1.2',
-                               'user' => 0,
-                               'minor_edit' => false,
-                               'deleted' => 0,
-                               'len' => 46,
-                               'parent_id' => 1,
-                               'sha1' => 'rdqbbzs3pkhihgbs8qf2q9jsvheag5z',
-                               'comment' => 'Goat Comment!',
-                               'content_format' => 'text/x-wiki',
-                               'content_model' => 'wikitext',
-                       ]
-               ];
-               yield 'Basic array, no user field' => [
-                       [
-                               'id' => 2,
-                               'page' => 1,
-                               'text_id' => 2,
-                               'timestamp' => '20171017114835',
-                               'user_text' => '111.0.1.3',
-                               'minor_edit' => false,
-                               'deleted' => 0,
-                               'len' => 46,
-                               'parent_id' => 1,
-                               'sha1' => 'rdqbbzs3pkhihgbs8qf2q9jsvheag5z',
-                               'comment' => 'Goat Comment!',
-                               'content_format' => 'text/x-wiki',
-                               'content_model' => 'wikitext',
-                       ]
-               ];
-       }
-
-       /**
-        * @dataProvider provideNewMutableRevisionFromArray
-        * @covers \MediaWiki\Storage\RevisionStore::newMutableRevisionFromArray
-        */
-       public function testNewMutableRevisionFromArray( array $array ) {
-               $store = MediaWikiServices::getInstance()->getRevisionStore();
-
-               $result = $store->newMutableRevisionFromArray( $array );
-
-               if ( isset( $array['id'] ) ) {
-                       $this->assertSame( $array['id'], $result->getId() );
-               }
-               if ( isset( $array['page'] ) ) {
-                       $this->assertSame( $array['page'], $result->getPageId() );
-               }
-               $this->assertSame( $array['timestamp'], $result->getTimestamp() );
-               $this->assertSame( $array['user_text'], $result->getUser()->getName() );
-               if ( isset( $array['user'] ) ) {
-                       $this->assertSame( $array['user'], $result->getUser()->getId() );
-               }
-               $this->assertSame( (bool)$array['minor_edit'], $result->isMinor() );
-               $this->assertSame( $array['deleted'], $result->getVisibility() );
-               $this->assertSame( $array['len'], $result->getSize() );
-               $this->assertSame( $array['parent_id'], $result->getParentId() );
-               $this->assertSame( $array['sha1'], $result->getSha1() );
-               $this->assertSame( $array['comment'], $result->getComment()->text );
-               if ( isset( $array['content'] ) ) {
-                       $this->assertTrue(
-                               $result->getSlot( 'main' )->getContent()->equals( $array['content'] )
-                       );
-               } elseif ( isset( $array['text'] ) ) {
-                       $this->assertSame( $array['text'], $result->getSlot( 'main' )->getContent()->serialize() );
-               } else {
-                       $this->assertSame(
-                               $array['content_format'],
-                               $result->getSlot( 'main' )->getContent()->getDefaultFormat()
-                       );
-                       $this->assertSame( $array['content_model'], $result->getSlot( 'main' )->getModel() );
-               }
-       }
-
-       /**
-        * @dataProvider provideNewMutableRevisionFromArray
-        * @covers \MediaWiki\Storage\RevisionStore::newMutableRevisionFromArray
-        */
-       public function testNewMutableRevisionFromArray_legacyEncoding( array $array ) {
-               $cache = new WANObjectCache( [ 'cache' => new HashBagOStuff() ] );
-               $lb = MediaWikiServices::getInstance()->getDBLoadBalancer();
-               $blobStore = new SqlBlobStore( $lb, $cache );
-               $blobStore->setLegacyEncoding( 'windows-1252', Language::factory( 'en' ) );
-
-               $factory = $this->getMockBuilder( BlobStoreFactory::class )
-                       ->setMethods( [ 'newBlobStore', 'newSqlBlobStore' ] )
-                       ->disableOriginalConstructor()
-                       ->getMock();
-               $factory->expects( $this->any() )
-                       ->method( 'newBlobStore' )
-                       ->willReturn( $blobStore );
-               $factory->expects( $this->any() )
-                       ->method( 'newSqlBlobStore' )
-                       ->willReturn( $blobStore );
-
-               $this->setService( 'BlobStoreFactory', $factory );
-
-               $this->testNewMutableRevisionFromArray( $array );
-       }
-
-}
diff --git a/tests/phpunit/includes/Storage/RevisionStoreDbTestBase.php b/tests/phpunit/includes/Storage/RevisionStoreDbTestBase.php
new file mode 100644 (file)
index 0000000..110f032
--- /dev/null
@@ -0,0 +1,1726 @@
+<?php
+
+namespace MediaWiki\Tests\Storage;
+
+use CommentStoreComment;
+use Content;
+use Exception;
+use HashBagOStuff;
+use InvalidArgumentException;
+use Language;
+use MediaWiki\Linker\LinkTarget;
+use MediaWiki\MediaWikiServices;
+use MediaWiki\Storage\BlobStoreFactory;
+use MediaWiki\Storage\IncompleteRevisionException;
+use MediaWiki\Storage\MutableRevisionRecord;
+use MediaWiki\Storage\RevisionRecord;
+use MediaWiki\Storage\RevisionStore;
+use MediaWiki\Storage\SlotRecord;
+use MediaWiki\Storage\SqlBlobStore;
+use MediaWikiTestCase;
+use PHPUnit_Framework_MockObject_MockObject;
+use Revision;
+use TestUserRegistry;
+use Title;
+use WANObjectCache;
+use Wikimedia\Rdbms\Database;
+use Wikimedia\Rdbms\DatabaseSqlite;
+use Wikimedia\Rdbms\FakeResultWrapper;
+use Wikimedia\Rdbms\LoadBalancer;
+use Wikimedia\Rdbms\TransactionProfiler;
+use WikiPage;
+use WikitextContent;
+
+/**
+ * @group Database
+ * @group RevisionStore
+ */
+abstract class RevisionStoreDbTestBase extends MediaWikiTestCase {
+
+       /**
+        * @var Title
+        */
+       private $testPageTitle;
+
+       /**
+        * @var WikiPage
+        */
+       private $testPage;
+
+       /**
+        * @return int
+        */
+       abstract protected function getMcrMigrationStage();
+
+       /**
+        * @return bool
+        */
+       protected function getContentHandlerUseDB() {
+               return true;
+       }
+
+       /**
+        * @return string[]
+        */
+       abstract protected function getMcrTablesToReset();
+
+       public function needsDB() {
+               return true;
+       }
+
+       public function setUp() {
+               parent::setUp();
+               $this->tablesUsed[] = 'archive';
+               $this->tablesUsed[] = 'page';
+               $this->tablesUsed[] = 'revision';
+               $this->tablesUsed[] = 'comment';
+
+               $this->tablesUsed += $this->getMcrTablesToReset();
+
+               $this->setMwGlobals(
+                       'wgMultiContentRevisionSchemaMigrationStage',
+                       $this->getMcrMigrationStage()
+               );
+
+               $this->setMwGlobals(
+                       'wgContentHandlerUseDB',
+                       $this->getContentHandlerUseDB()
+               );
+
+               $this->overrideMwServices();
+       }
+
+       protected function addCoreDBData() {
+               // Blank out. This would fail with a modified schema, and we don't need it.
+       }
+
+       /**
+        * @return Title
+        */
+       protected function getTestPageTitle() {
+               if ( $this->testPageTitle ) {
+                       return $this->testPageTitle;
+               }
+
+               $this->testPageTitle = Title::newFromText( 'UTPage-' . __CLASS__ );
+               return $this->testPageTitle;
+       }
+       /**
+        * @return WikiPage
+        */
+       protected function getTestPage() {
+               if ( $this->testPage ) {
+                       return $this->testPage;
+               }
+
+               $title = $this->getTestPageTitle();
+               $this->testPage = WikiPage::factory( $title );
+
+               if ( !$this->testPage->exists() ) {
+                       // Make sure we don't write to the live db.
+                       $this->ensureMockDatabaseConnection( wfGetDB( DB_MASTER ) );
+
+                       $user = static::getTestSysop()->getUser();
+
+                       $this->testPage->doEditContent(
+                               new WikitextContent( 'UTContent-' . __CLASS__ ),
+                               'UTPageSummary-' . __CLASS__,
+                               EDIT_NEW | EDIT_SUPPRESS_RC,
+                               false,
+                               $user
+                       );
+               }
+
+               return $this->testPage;
+       }
+
+       /**
+        * @return LoadBalancer|PHPUnit_Framework_MockObject_MockObject
+        */
+       private function getLoadBalancerMock( array $server ) {
+               $lb = $this->getMockBuilder( LoadBalancer::class )
+                       ->setMethods( [ 'reallyOpenConnection' ] )
+                       ->setConstructorArgs( [ [ 'servers' => [ $server ] ] ] )
+                       ->getMock();
+
+               $lb->method( 'reallyOpenConnection' )->willReturnCallback(
+                       function ( array $server, $dbNameOverride ) {
+                               return $this->getDatabaseMock( $server );
+                       }
+               );
+
+               return $lb;
+       }
+
+       /**
+        * @return Database|PHPUnit_Framework_MockObject_MockObject
+        */
+       private function getDatabaseMock( array $params ) {
+               $db = $this->getMockBuilder( DatabaseSqlite::class )
+                       ->setMethods( [ 'select', 'doQuery', 'open', 'closeConnection', 'isOpen' ] )
+                       ->setConstructorArgs( [ $params ] )
+                       ->getMock();
+
+               $db->method( 'select' )->willReturn( new FakeResultWrapper( [] ) );
+               $db->method( 'isOpen' )->willReturn( true );
+
+               return $db;
+       }
+
+       public function provideDomainCheck() {
+               yield [ false, 'test', '' ];
+               yield [ 'test', 'test', '' ];
+
+               yield [ false, 'test', 'foo_' ];
+               yield [ 'test-foo_', 'test', 'foo_' ];
+
+               yield [ false, 'dash-test', '' ];
+               yield [ 'dash-test', 'dash-test', '' ];
+
+               yield [ false, 'underscore_test', 'foo_' ];
+               yield [ 'underscore_test-foo_', 'underscore_test', 'foo_' ];
+       }
+
+       /**
+        * @dataProvider provideDomainCheck
+        * @covers \MediaWiki\Storage\RevisionStore::checkDatabaseWikiId
+        */
+       public function testDomainCheck( $wikiId, $dbName, $dbPrefix ) {
+               $this->setMwGlobals(
+                       [
+                               'wgDBname' => $dbName,
+                               'wgDBprefix' => $dbPrefix,
+                       ]
+               );
+
+               $loadBalancer = $this->getLoadBalancerMock(
+                       [
+                               'host' => '*dummy*',
+                               'dbDirectory' => '*dummy*',
+                               'user' => 'test',
+                               'password' => 'test',
+                               'flags' => 0,
+                               'variables' => [],
+                               'schema' => '',
+                               'cliMode' => true,
+                               'agent' => '',
+                               'load' => 100,
+                               'profiler' => null,
+                               'trxProfiler' => new TransactionProfiler(),
+                               'connLogger' => new \Psr\Log\NullLogger(),
+                               'queryLogger' => new \Psr\Log\NullLogger(),
+                               'errorLogger' => function () {
+                               },
+                               'deprecationLogger' => function () {
+                               },
+                               'type' => 'test',
+                               'dbname' => $dbName,
+                               'tablePrefix' => $dbPrefix,
+                       ]
+               );
+               $db = $loadBalancer->getConnection( DB_REPLICA );
+
+               /** @var SqlBlobStore $blobStore */
+               $blobStore = $this->getMockBuilder( SqlBlobStore::class )
+                       ->disableOriginalConstructor()
+                       ->getMock();
+
+               $store = new RevisionStore(
+                       $loadBalancer,
+                       $blobStore,
+                       new WANObjectCache( [ 'cache' => new HashBagOStuff() ] ),
+                       MediaWikiServices::getInstance()->getCommentStore(),
+                       MediaWikiServices::getInstance()->getContentModelStore(),
+                       MediaWikiServices::getInstance()->getSlotRoleStore(),
+                       $this->getMcrMigrationStage(),
+                       MediaWikiServices::getInstance()->getActorMigration(),
+                       $wikiId
+               );
+
+               $count = $store->countRevisionsByPageId( $db, 0 );
+
+               // Dummy check to make PhpUnit happy. We are really only interested in
+               // countRevisionsByPageId not failing due to the DB domain check.
+               $this->assertSame( 0, $count );
+       }
+
+       private function assertLinkTargetsEqual( LinkTarget $l1, LinkTarget $l2 ) {
+               $this->assertEquals( $l1->getDBkey(), $l2->getDBkey() );
+               $this->assertEquals( $l1->getNamespace(), $l2->getNamespace() );
+               $this->assertEquals( $l1->getFragment(), $l2->getFragment() );
+               $this->assertEquals( $l1->getInterwiki(), $l2->getInterwiki() );
+       }
+
+       private function assertRevisionRecordsEqual( RevisionRecord $r1, RevisionRecord $r2 ) {
+               $this->assertEquals(
+                       $r1->getPageAsLinkTarget()->getNamespace(),
+                       $r2->getPageAsLinkTarget()->getNamespace()
+               );
+
+               $this->assertEquals(
+                       $r1->getPageAsLinkTarget()->getText(),
+                       $r2->getPageAsLinkTarget()->getText()
+               );
+
+               if ( $r1->getParentId() ) {
+                       $this->assertEquals( $r1->getParentId(), $r2->getParentId() );
+               }
+
+               $this->assertEquals( $r1->getUser()->getName(), $r2->getUser()->getName() );
+               $this->assertEquals( $r1->getUser()->getId(), $r2->getUser()->getId() );
+               $this->assertEquals( $r1->getComment(), $r2->getComment() );
+               $this->assertEquals( $r1->getTimestamp(), $r2->getTimestamp() );
+               $this->assertEquals( $r1->getVisibility(), $r2->getVisibility() );
+               $this->assertEquals( $r1->getSha1(), $r2->getSha1() );
+               $this->assertEquals( $r1->getSize(), $r2->getSize() );
+               $this->assertEquals( $r1->getPageId(), $r2->getPageId() );
+               $this->assertArrayEqualsIgnoringIntKeyOrder( $r1->getSlotRoles(), $r2->getSlotRoles() );
+               $this->assertEquals( $r1->getWikiId(), $r2->getWikiId() );
+               $this->assertEquals( $r1->isMinor(), $r2->isMinor() );
+               foreach ( $r1->getSlotRoles() as $role ) {
+                       $this->assertSlotRecordsEqual( $r1->getSlot( $role ), $r2->getSlot( $role ) );
+                       $this->assertTrue( $r1->getContent( $role )->equals( $r2->getContent( $role ) ) );
+               }
+               foreach ( [
+                       RevisionRecord::DELETED_TEXT,
+                       RevisionRecord::DELETED_COMMENT,
+                       RevisionRecord::DELETED_USER,
+                       RevisionRecord::DELETED_RESTRICTED,
+               ] as $field ) {
+                       $this->assertEquals( $r1->isDeleted( $field ), $r2->isDeleted( $field ) );
+               }
+       }
+
+       private function assertSlotRecordsEqual( SlotRecord $s1, SlotRecord $s2 ) {
+               $this->assertSame( $s1->getRole(), $s2->getRole() );
+               $this->assertSame( $s1->getModel(), $s2->getModel() );
+               $this->assertSame( $s1->getFormat(), $s2->getFormat() );
+               $this->assertSame( $s1->getSha1(), $s2->getSha1() );
+               $this->assertSame( $s1->getSize(), $s2->getSize() );
+               $this->assertTrue( $s1->getContent()->equals( $s2->getContent() ) );
+
+               $s1->hasRevision() ? $this->assertSame( $s1->getRevision(), $s2->getRevision() ) : null;
+               $s1->hasAddress() ? $this->assertSame( $s1->hasAddress(), $s2->hasAddress() ) : null;
+       }
+
+       private function assertRevisionCompleteness( RevisionRecord $r ) {
+               $this->assertTrue( $r->hasSlot( 'main' ) );
+               $this->assertInstanceOf( SlotRecord::class, $r->getSlot( 'main' ) );
+               $this->assertInstanceOf( Content::class, $r->getContent( 'main' ) );
+
+               foreach ( $r->getSlotRoles() as $role ) {
+                       $this->assertSlotCompleteness( $r, $r->getSlot( $role ) );
+               }
+       }
+
+       private function assertSlotCompleteness( RevisionRecord $r, SlotRecord $slot ) {
+               $this->assertTrue( $slot->hasAddress() );
+               $this->assertSame( $r->getId(), $slot->getRevision() );
+
+               $this->assertInstanceOf( Content::class, $slot->getContent() );
+       }
+
+       /**
+        * @param mixed[] $details
+        *
+        * @return RevisionRecord
+        */
+       private function getRevisionRecordFromDetailsArray( $details = [] ) {
+               // Convert some values that can't be provided by dataProviders
+               if ( isset( $details['user'] ) && $details['user'] === true ) {
+                       $details['user'] = $this->getTestUser()->getUser();
+               }
+               if ( isset( $details['page'] ) && $details['page'] === true ) {
+                       $details['page'] = $this->getTestPage()->getId();
+               }
+               if ( isset( $details['parent'] ) && $details['parent'] === true ) {
+                       $details['parent'] = $this->getTestPage()->getLatest();
+               }
+
+               // Create the RevisionRecord with any available data
+               $rev = new MutableRevisionRecord( $this->getTestPageTitle() );
+               isset( $details['slot'] ) ? $rev->setSlot( $details['slot'] ) : null;
+               isset( $details['parent'] ) ? $rev->setParentId( $details['parent'] ) : null;
+               isset( $details['page'] ) ? $rev->setPageId( $details['page'] ) : null;
+               isset( $details['size'] ) ? $rev->setSize( $details['size'] ) : null;
+               isset( $details['sha1'] ) ? $rev->setSha1( $details['sha1'] ) : null;
+               isset( $details['comment'] ) ? $rev->setComment( $details['comment'] ) : null;
+               isset( $details['timestamp'] ) ? $rev->setTimestamp( $details['timestamp'] ) : null;
+               isset( $details['minor'] ) ? $rev->setMinorEdit( $details['minor'] ) : null;
+               isset( $details['user'] ) ? $rev->setUser( $details['user'] ) : null;
+               isset( $details['visibility'] ) ? $rev->setVisibility( $details['visibility'] ) : null;
+               isset( $details['id'] ) ? $rev->setId( $details['id'] ) : null;
+
+               if ( isset( $details['content'] ) ) {
+                       foreach ( $details['content'] as $role => $content ) {
+                               $rev->setContent( $role, $content );
+                       }
+               }
+
+               return $rev;
+       }
+
+       public function provideInsertRevisionOn_successes() {
+               yield 'Bare minimum revision insertion' => [
+                       [
+                               'slot' => SlotRecord::newUnsaved( 'main', new WikitextContent( 'Chicken' ) ),
+                               'page' => true,
+                               'comment' => $this->getRandomCommentStoreComment(),
+                               'timestamp' => '20171117010101',
+                               'user' => true,
+                       ],
+               ];
+               yield 'Detailed revision insertion' => [
+                       [
+                               'slot' => SlotRecord::newUnsaved( 'main', new WikitextContent( 'Chicken' ) ),
+                               'parent' => true,
+                               'page' => true,
+                               'comment' => $this->getRandomCommentStoreComment(),
+                               'timestamp' => '20171117010101',
+                               'user' => true,
+                               'minor' => true,
+                               'visibility' => RevisionRecord::DELETED_RESTRICTED,
+                       ],
+               ];
+       }
+
+       protected function getRandomCommentStoreComment() {
+               return CommentStoreComment::newUnsavedComment( __METHOD__ . '.' . rand( 0, 1000 ) );
+       }
+
+       /**
+        * @dataProvider provideInsertRevisionOn_successes
+        * @covers \MediaWiki\Storage\RevisionStore::insertRevisionOn
+        * @covers \MediaWiki\Storage\RevisionStore::insertSlotRowOn
+        * @covers \MediaWiki\Storage\RevisionStore::insertContentRowOn
+        */
+       public function testInsertRevisionOn_successes(
+               array $revDetails = []
+       ) {
+               $title = $this->getTestPageTitle();
+               $rev = $this->getRevisionRecordFromDetailsArray( $revDetails );
+
+               $this->overrideMwServices();
+               $store = MediaWikiServices::getInstance()->getRevisionStore();
+               $return = $store->insertRevisionOn( $rev, wfGetDB( DB_MASTER ) );
+
+               // is the new revision correct?
+               $this->assertRevisionCompleteness( $return );
+               $this->assertLinkTargetsEqual( $title, $return->getPageAsLinkTarget() );
+               $this->assertRevisionRecordsEqual( $rev, $return );
+
+               // can we load it from the store?
+               $loaded = $store->getRevisionById( $return->getId() );
+               $this->assertRevisionCompleteness( $loaded );
+               $this->assertRevisionRecordsEqual( $return, $loaded );
+
+               // can we find it directly in the database?
+               $this->assertRevisionExistsInDatabase( $return );
+       }
+
+       protected function assertRevisionExistsInDatabase( RevisionRecord $rev ) {
+               $row = $this->revisionToRow( new Revision( $rev ), [] );
+
+               // unset nulled fields
+               unset( $row->rev_content_model );
+               unset( $row->rev_content_format );
+
+               // unset fake fields
+               unset( $row->rev_comment_text );
+               unset( $row->rev_comment_data );
+               unset( $row->rev_comment_cid );
+               unset( $row->rev_comment_id );
+
+               $store = MediaWikiServices::getInstance()->getRevisionStore();
+               $queryInfo = $store->getQueryInfo( [ 'user' ] );
+
+               $row = get_object_vars( $row );
+               $this->assertSelect(
+                       $queryInfo['tables'],
+                       array_keys( $row ),
+                       [ 'rev_id' => $rev->getId() ],
+                       [ array_values( $row ) ],
+                       [],
+                       $queryInfo['joins']
+               );
+       }
+
+       /**
+        * @param SlotRecord $a
+        * @param SlotRecord $b
+        */
+       protected function assertSameSlotContent( SlotRecord $a, SlotRecord $b ) {
+               // Assert that the same blob address has been used.
+               $this->assertSame( $a->getAddress(), $b->getAddress() );
+       }
+
+       /**
+        * @covers \MediaWiki\Storage\RevisionStore::insertRevisionOn
+        */
+       public function testInsertRevisionOn_blobAddressExists() {
+               $title = $this->getTestPageTitle();
+               $revDetails = [
+                       'slot' => SlotRecord::newUnsaved( 'main', new WikitextContent( 'Chicken' ) ),
+                       'parent' => true,
+                       'comment' => $this->getRandomCommentStoreComment(),
+                       'timestamp' => '20171117010101',
+                       'user' => true,
+               ];
+
+               $this->overrideMwServices();
+               $store = MediaWikiServices::getInstance()->getRevisionStore();
+
+               // Insert the first revision
+               $revOne = $this->getRevisionRecordFromDetailsArray( $revDetails );
+               $firstReturn = $store->insertRevisionOn( $revOne, wfGetDB( DB_MASTER ) );
+               $this->assertLinkTargetsEqual( $title, $firstReturn->getPageAsLinkTarget() );
+               $this->assertRevisionRecordsEqual( $revOne, $firstReturn );
+
+               // Insert a second revision inheriting the same blob address
+               $revDetails['slot'] = SlotRecord::newInherited( $firstReturn->getSlot( 'main' ) );
+               $revTwo = $this->getRevisionRecordFromDetailsArray( $revDetails );
+               $secondReturn = $store->insertRevisionOn( $revTwo, wfGetDB( DB_MASTER ) );
+               $this->assertLinkTargetsEqual( $title, $secondReturn->getPageAsLinkTarget() );
+               $this->assertRevisionRecordsEqual( $revTwo, $secondReturn );
+
+               $firstMainSlot = $firstReturn->getSlot( 'main' );
+               $secondMainSlot = $secondReturn->getSlot( 'main' );
+
+               $this->assertSameSlotContent( $firstMainSlot, $secondMainSlot );
+
+               // And that different revisions have been created.
+               $this->assertNotSame( $firstReturn->getId(), $secondReturn->getId() );
+
+               // Make sure the slot rows reference the correct revision
+               $this->assertSame( $firstReturn->getId(), $firstMainSlot->getRevision() );
+               $this->assertSame( $secondReturn->getId(), $secondMainSlot->getRevision() );
+       }
+
+       public function provideInsertRevisionOn_failures() {
+               yield 'no slot' => [
+                       [
+                               'comment' => $this->getRandomCommentStoreComment(),
+                               'timestamp' => '20171117010101',
+                               'user' => true,
+                       ],
+                       new InvalidArgumentException( 'main slot must be provided' )
+               ];
+               yield 'no main slot' => [
+                       [
+                               'slot' => SlotRecord::newUnsaved( 'aux', new WikitextContent( 'Turkey' ) ),
+                               'comment' => $this->getRandomCommentStoreComment(),
+                               'timestamp' => '20171117010101',
+                               'user' => true,
+                       ],
+                       new InvalidArgumentException( 'main slot must be provided' )
+               ];
+               yield 'no timestamp' => [
+                       [
+                               'slot' => SlotRecord::newUnsaved( 'main', new WikitextContent( 'Chicken' ) ),
+                               'comment' => $this->getRandomCommentStoreComment(),
+                               'user' => true,
+                       ],
+                       new IncompleteRevisionException( 'timestamp field must not be NULL!' )
+               ];
+               yield 'no comment' => [
+                       [
+                               'slot' => SlotRecord::newUnsaved( 'main', new WikitextContent( 'Chicken' ) ),
+                               'timestamp' => '20171117010101',
+                               'user' => true,
+                       ],
+                       new IncompleteRevisionException( 'comment must not be NULL!' )
+               ];
+               yield 'no user' => [
+                       [
+                               'slot' => SlotRecord::newUnsaved( 'main', new WikitextContent( 'Chicken' ) ),
+                               'comment' => $this->getRandomCommentStoreComment(),
+                               'timestamp' => '20171117010101',
+                       ],
+                       new IncompleteRevisionException( 'user must not be NULL!' )
+               ];
+       }
+
+       /**
+        * @dataProvider provideInsertRevisionOn_failures
+        * @covers \MediaWiki\Storage\RevisionStore::insertRevisionOn
+        */
+       public function testInsertRevisionOn_failures(
+               array $revDetails = [],
+               Exception $exception
+       ) {
+               $rev = $this->getRevisionRecordFromDetailsArray( $revDetails );
+
+               $store = MediaWikiServices::getInstance()->getRevisionStore();
+
+               $this->setExpectedException(
+                       get_class( $exception ),
+                       $exception->getMessage(),
+                       $exception->getCode()
+               );
+               $store->insertRevisionOn( $rev, wfGetDB( DB_MASTER ) );
+       }
+
+       public function provideNewNullRevision() {
+               yield [
+                       Title::newFromText( 'UTPage_notAutoCreated' ),
+                       [ 'content' => [ 'main' => new WikitextContent( 'Flubber1' ) ] ],
+                       CommentStoreComment::newUnsavedComment( __METHOD__ . ' comment1' ),
+                       true,
+               ];
+               yield [
+                       Title::newFromText( 'UTPage_notAutoCreated' ),
+                       [ 'content' => [ 'main' => new WikitextContent( 'Flubber2' ) ] ],
+                       CommentStoreComment::newUnsavedComment( __METHOD__ . ' comment2', [ 'a' => 1 ] ),
+                       false,
+               ];
+       }
+
+       /**
+        * @dataProvider provideNewNullRevision
+        * @covers \MediaWiki\Storage\RevisionStore::newNullRevision
+        * @covers \MediaWiki\Storage\RevisionStore::findSlotContentId
+        */
+       public function testNewNullRevision( Title $title, $revDetails, $comment, $minor = false ) {
+               $this->overrideMwServices();
+
+               $user = TestUserRegistry::getMutableTestUser( __METHOD__ )->getUser();
+               $page = WikiPage::factory( $title );
+
+               if ( !$page->exists() ) {
+                       $page->doEditContent( new WikitextContent( __METHOD__ ), __METHOD__, EDIT_NEW );
+               }
+
+               $revDetails['page'] = $page->getId();
+               $revDetails['timestamp'] = wfTimestampNow();
+               $revDetails['comment'] = CommentStoreComment::newUnsavedComment( 'Base' );
+               $revDetails['user'] = $user;
+
+               $baseRev = $this->getRevisionRecordFromDetailsArray( $revDetails );
+               $store = MediaWikiServices::getInstance()->getRevisionStore();
+
+               $dbw = wfGetDB( DB_MASTER );
+               $baseRev = $store->insertRevisionOn( $baseRev, $dbw );
+               $page->updateRevisionOn( $dbw, new Revision( $baseRev ), $page->getLatest() );
+
+               $record = $store->newNullRevision(
+                       wfGetDB( DB_MASTER ),
+                       $title,
+                       $comment,
+                       $minor,
+                       $user
+               );
+
+               $this->assertEquals( $title->getNamespace(), $record->getPageAsLinkTarget()->getNamespace() );
+               $this->assertEquals( $title->getDBkey(), $record->getPageAsLinkTarget()->getDBkey() );
+               $this->assertEquals( $comment, $record->getComment() );
+               $this->assertEquals( $minor, $record->isMinor() );
+               $this->assertEquals( $user->getName(), $record->getUser()->getName() );
+               $this->assertEquals( $baseRev->getId(), $record->getParentId() );
+
+               $this->assertArrayEqualsIgnoringIntKeyOrder(
+                       $baseRev->getSlotRoles(),
+                       $record->getSlotRoles()
+               );
+
+               foreach ( $baseRev->getSlotRoles() as $role ) {
+                       $parentSlot = $baseRev->getSlot( $role );
+                       $slot = $record->getSlot( $role );
+
+                       $this->assertTrue( $slot->isInherited(), 'isInherited' );
+                       $this->assertSame( $parentSlot->getOrigin(), $slot->getOrigin(), 'getOrigin' );
+                       $this->assertSameSlotContent( $parentSlot, $slot );
+               }
+       }
+
+       /**
+        * @covers \MediaWiki\Storage\RevisionStore::newNullRevision
+        */
+       public function testNewNullRevision_nonExistingTitle() {
+               $store = MediaWikiServices::getInstance()->getRevisionStore();
+               $record = $store->newNullRevision(
+                       wfGetDB( DB_MASTER ),
+                       Title::newFromText( __METHOD__ . '.iDontExist!' ),
+                       CommentStoreComment::newUnsavedComment( __METHOD__ . ' comment' ),
+                       false,
+                       TestUserRegistry::getMutableTestUser( __METHOD__ )->getUser()
+               );
+               $this->assertNull( $record );
+       }
+
+       /**
+        * @covers \MediaWiki\Storage\RevisionStore::getRcIdIfUnpatrolled
+        */
+       public function testGetRcIdIfUnpatrolled_returnsRecentChangesId() {
+               $page = $this->getTestPage();
+               $status = $page->doEditContent( new WikitextContent( __METHOD__ ), __METHOD__ );
+               /** @var Revision $rev */
+               $rev = $status->value['revision'];
+
+               $store = MediaWikiServices::getInstance()->getRevisionStore();
+               $revisionRecord = $store->getRevisionById( $rev->getId() );
+               $result = $store->getRcIdIfUnpatrolled( $revisionRecord );
+
+               $this->assertGreaterThan( 0, $result );
+               $this->assertSame(
+                       $store->getRecentChange( $revisionRecord )->getAttribute( 'rc_id' ),
+                       $result
+               );
+       }
+
+       /**
+        * @covers \MediaWiki\Storage\RevisionStore::getRcIdIfUnpatrolled
+        */
+       public function testGetRcIdIfUnpatrolled_returnsZeroIfPatrolled() {
+               // This assumes that sysops are auto patrolled
+               $sysop = $this->getTestSysop()->getUser();
+               $page = $this->getTestPage();
+               $status = $page->doEditContent(
+                       new WikitextContent( __METHOD__ ),
+                       __METHOD__,
+                       0,
+                       false,
+                       $sysop
+               );
+               /** @var Revision $rev */
+               $rev = $status->value['revision'];
+
+               $store = MediaWikiServices::getInstance()->getRevisionStore();
+               $revisionRecord = $store->getRevisionById( $rev->getId() );
+               $result = $store->getRcIdIfUnpatrolled( $revisionRecord );
+
+               $this->assertSame( 0, $result );
+       }
+
+       /**
+        * @covers \MediaWiki\Storage\RevisionStore::getRecentChange
+        */
+       public function testGetRecentChange() {
+               $page = $this->getTestPage();
+               $content = new WikitextContent( __METHOD__ );
+               $status = $page->doEditContent( $content, __METHOD__ );
+               /** @var Revision $rev */
+               $rev = $status->value['revision'];
+
+               $store = MediaWikiServices::getInstance()->getRevisionStore();
+               $revRecord = $store->getRevisionById( $rev->getId() );
+               $recentChange = $store->getRecentChange( $revRecord );
+
+               $this->assertEquals( $rev->getId(), $recentChange->getAttribute( 'rc_this_oldid' ) );
+               $this->assertEquals( $rev->getRecentChange(), $recentChange );
+       }
+
+       /**
+        * @covers \MediaWiki\Storage\RevisionStore::getRevisionById
+        */
+       public function testGetRevisionById() {
+               $page = $this->getTestPage();
+               $content = new WikitextContent( __METHOD__ );
+               $status = $page->doEditContent( $content, __METHOD__ );
+               /** @var Revision $rev */
+               $rev = $status->value['revision'];
+
+               $store = MediaWikiServices::getInstance()->getRevisionStore();
+               $revRecord = $store->getRevisionById( $rev->getId() );
+
+               $this->assertSame( $rev->getId(), $revRecord->getId() );
+               $this->assertTrue( $revRecord->getSlot( 'main' )->getContent()->equals( $content ) );
+               $this->assertSame( __METHOD__, $revRecord->getComment()->text );
+       }
+
+       /**
+        * @covers \MediaWiki\Storage\RevisionStore::getRevisionByTitle
+        */
+       public function testGetRevisionByTitle() {
+               $page = $this->getTestPage();
+               $content = new WikitextContent( __METHOD__ );
+               $status = $page->doEditContent( $content, __METHOD__ );
+               /** @var Revision $rev */
+               $rev = $status->value['revision'];
+
+               $store = MediaWikiServices::getInstance()->getRevisionStore();
+               $revRecord = $store->getRevisionByTitle( $page->getTitle() );
+
+               $this->assertSame( $rev->getId(), $revRecord->getId() );
+               $this->assertTrue( $revRecord->getSlot( 'main' )->getContent()->equals( $content ) );
+               $this->assertSame( __METHOD__, $revRecord->getComment()->text );
+       }
+
+       /**
+        * @covers \MediaWiki\Storage\RevisionStore::getRevisionByPageId
+        */
+       public function testGetRevisionByPageId() {
+               $page = $this->getTestPage();
+               $content = new WikitextContent( __METHOD__ );
+               $status = $page->doEditContent( $content, __METHOD__ );
+               /** @var Revision $rev */
+               $rev = $status->value['revision'];
+
+               $store = MediaWikiServices::getInstance()->getRevisionStore();
+               $revRecord = $store->getRevisionByPageId( $page->getId() );
+
+               $this->assertSame( $rev->getId(), $revRecord->getId() );
+               $this->assertTrue( $revRecord->getSlot( 'main' )->getContent()->equals( $content ) );
+               $this->assertSame( __METHOD__, $revRecord->getComment()->text );
+       }
+
+       /**
+        * @covers \MediaWiki\Storage\RevisionStore::getRevisionByTimestamp
+        */
+       public function testGetRevisionByTimestamp() {
+               // Make sure there is 1 second between the last revision and the rev we create...
+               // Otherwise we might not get the correct revision and the test may fail...
+               // :(
+               $page = $this->getTestPage();
+               sleep( 1 );
+               $content = new WikitextContent( __METHOD__ );
+               $status = $page->doEditContent( $content, __METHOD__ );
+               /** @var Revision $rev */
+               $rev = $status->value['revision'];
+
+               $store = MediaWikiServices::getInstance()->getRevisionStore();
+               $revRecord = $store->getRevisionByTimestamp(
+                       $page->getTitle(),
+                       $rev->getTimestamp()
+               );
+
+               $this->assertSame( $rev->getId(), $revRecord->getId() );
+               $this->assertTrue( $revRecord->getSlot( 'main' )->getContent()->equals( $content ) );
+               $this->assertSame( __METHOD__, $revRecord->getComment()->text );
+       }
+
+       protected function revisionToRow( Revision $rev, $options = [ 'page', 'user', 'comment' ] ) {
+               // XXX: the WikiPage object loads another RevisionRecord from the database. Not great.
+               $page = WikiPage::factory( $rev->getTitle() );
+
+               $fields = [
+                       'rev_id' => (string)$rev->getId(),
+                       'rev_page' => (string)$rev->getPage(),
+                       'rev_timestamp' => $this->db->timestamp( $rev->getTimestamp() ),
+                       'rev_user_text' => (string)$rev->getUserText(),
+                       'rev_user' => (string)$rev->getUser(),
+                       'rev_minor_edit' => $rev->isMinor() ? '1' : '0',
+                       'rev_deleted' => (string)$rev->getVisibility(),
+                       'rev_len' => (string)$rev->getSize(),
+                       'rev_parent_id' => (string)$rev->getParentId(),
+                       'rev_sha1' => (string)$rev->getSha1(),
+               ];
+
+               if ( in_array( 'page', $options ) ) {
+                       $fields += [
+                               'page_namespace' => (string)$page->getTitle()->getNamespace(),
+                               'page_title' => $page->getTitle()->getDBkey(),
+                               'page_id' => (string)$page->getId(),
+                               'page_latest' => (string)$page->getLatest(),
+                               'page_is_redirect' => $page->isRedirect() ? '1' : '0',
+                               'page_len' => (string)$page->getContent()->getSize(),
+                       ];
+               }
+
+               if ( in_array( 'user', $options ) ) {
+                       $fields += [
+                               'user_name' => (string)$rev->getUserText(),
+                       ];
+               }
+
+               if ( in_array( 'comment', $options ) ) {
+                       $fields += [
+                               'rev_comment_text' => $rev->getComment(),
+                               'rev_comment_data' => null,
+                               'rev_comment_cid' => null,
+                       ];
+               }
+
+               if ( $rev->getId() ) {
+                       $fields += [
+                               'rev_id' => (string)$rev->getId(),
+                       ];
+               }
+
+               return (object)$fields;
+       }
+
+       private function assertRevisionRecordMatchesRevision(
+               Revision $rev,
+               RevisionRecord $record
+       ) {
+               $this->assertSame( $rev->getId(), $record->getId() );
+               $this->assertSame( $rev->getPage(), $record->getPageId() );
+               $this->assertSame( $rev->getTimestamp(), $record->getTimestamp() );
+               $this->assertSame( $rev->getUserText(), $record->getUser()->getName() );
+               $this->assertSame( $rev->getUser(), $record->getUser()->getId() );
+               $this->assertSame( $rev->isMinor(), $record->isMinor() );
+               $this->assertSame( $rev->getVisibility(), $record->getVisibility() );
+               $this->assertSame( $rev->getSize(), $record->getSize() );
+               /**
+                * @note As of MW 1.31, the database schema allows the parent ID to be
+                * NULL to indicate that it is unknown.
+                */
+               $expectedParent = $rev->getParentId();
+               if ( $expectedParent === null ) {
+                       $expectedParent = 0;
+               }
+               $this->assertSame( $expectedParent, $record->getParentId() );
+               $this->assertSame( $rev->getSha1(), $record->getSha1() );
+               $this->assertSame( $rev->getComment(), $record->getComment()->text );
+               $this->assertSame( $rev->getContentFormat(), $record->getContent( 'main' )->getDefaultFormat() );
+               $this->assertSame( $rev->getContentModel(), $record->getContent( 'main' )->getModel() );
+               $this->assertLinkTargetsEqual( $rev->getTitle(), $record->getPageAsLinkTarget() );
+
+               $revRec = $rev->getRevisionRecord();
+               $revMain = $revRec->getSlot( 'main' );
+               $recMain = $record->getSlot( 'main' );
+
+               $this->assertSame( $revMain->hasOrigin(), $recMain->hasOrigin(), 'hasOrigin' );
+               $this->assertSame( $revMain->hasAddress(), $recMain->hasAddress(), 'hasAddress' );
+               $this->assertSame( $revMain->hasContentId(), $recMain->hasContentId(), 'hasContentId' );
+
+               if ( $revMain->hasOrigin() ) {
+                       $this->assertSame( $revMain->getOrigin(), $recMain->getOrigin(), 'getOrigin' );
+               }
+
+               if ( $revMain->hasAddress() ) {
+                       $this->assertSame( $revMain->getAddress(), $recMain->getAddress(), 'getAddress' );
+               }
+
+               if ( $revMain->hasContentId() ) {
+                       $this->assertSame( $revMain->getContentId(), $recMain->getContentId(), 'getContentId' );
+               }
+       }
+
+       /**
+        * @covers \MediaWiki\Storage\RevisionStore::newRevisionFromRow
+        */
+       public function testNewRevisionFromRow_anonEdit() {
+               $page = $this->getTestPage();
+               $text = __METHOD__ . 'a-ä';
+               /** @var Revision $rev */
+               $rev = $page->doEditContent(
+                       new WikitextContent( $text ),
+                       __METHOD__ . 'a'
+               )->value['revision'];
+
+               $store = MediaWikiServices::getInstance()->getRevisionStore();
+               $record = $store->newRevisionFromRow(
+                       $this->revisionToRow( $rev ),
+                       [],
+                       $page->getTitle()
+               );
+               $this->assertRevisionRecordMatchesRevision( $rev, $record );
+               $this->assertSame( $text, $rev->getContent()->serialize() );
+       }
+
+       /**
+        * @covers \MediaWiki\Storage\RevisionStore::newRevisionFromRow
+        */
+       public function testNewRevisionFromRow_anonEdit_legacyEncoding() {
+               $this->setMwGlobals( 'wgLegacyEncoding', 'windows-1252' );
+               $this->overrideMwServices();
+               $page = $this->getTestPage();
+               $text = __METHOD__ . 'a-ä';
+               /** @var Revision $rev */
+               $rev = $page->doEditContent(
+                       new WikitextContent( $text ),
+                       __METHOD__. 'a'
+               )->value['revision'];
+
+               $store = MediaWikiServices::getInstance()->getRevisionStore();
+               $record = $store->newRevisionFromRow(
+                       $this->revisionToRow( $rev ),
+                       [],
+                       $page->getTitle()
+               );
+               $this->assertRevisionRecordMatchesRevision( $rev, $record );
+               $this->assertSame( $text, $rev->getContent()->serialize() );
+       }
+
+       /**
+        * @covers \MediaWiki\Storage\RevisionStore::newRevisionFromRow
+        */
+       public function testNewRevisionFromRow_userEdit() {
+               $page = $this->getTestPage();
+               $text = __METHOD__ . 'b-ä';
+               /** @var Revision $rev */
+               $rev = $page->doEditContent(
+                       new WikitextContent( $text ),
+                       __METHOD__ . 'b',
+                       0,
+                       false,
+                       $this->getTestUser()->getUser()
+               )->value['revision'];
+
+               $store = MediaWikiServices::getInstance()->getRevisionStore();
+               $record = $store->newRevisionFromRow(
+                       $this->revisionToRow( $rev ),
+                       [],
+                       $page->getTitle()
+               );
+               $this->assertRevisionRecordMatchesRevision( $rev, $record );
+               $this->assertSame( $text, $rev->getContent()->serialize() );
+       }
+
+       /**
+        * @covers \MediaWiki\Storage\RevisionStore::newRevisionFromArchiveRow
+        */
+       public function testNewRevisionFromArchiveRow() {
+               $store = MediaWikiServices::getInstance()->getRevisionStore();
+               $title = Title::newFromText( __METHOD__ );
+               $text = __METHOD__ . '-bä';
+               $page = WikiPage::factory( $title );
+               /** @var Revision $orig */
+               $orig = $page->doEditContent( new WikitextContent( $text ), __METHOD__ )
+                       ->value['revision'];
+               $page->doDeleteArticle( __METHOD__ );
+
+               $db = wfGetDB( DB_MASTER );
+               $arQuery = $store->getArchiveQueryInfo();
+               $res = $db->select(
+                       $arQuery['tables'], $arQuery['fields'], [ 'ar_rev_id' => $orig->getId() ],
+                       __METHOD__, [], $arQuery['joins']
+               );
+               $this->assertTrue( is_object( $res ), 'query failed' );
+
+               $row = $res->fetchObject();
+               $res->free();
+               $record = $store->newRevisionFromArchiveRow( $row );
+
+               $this->assertRevisionRecordMatchesRevision( $orig, $record );
+               $this->assertSame( $text, $record->getContent( 'main' )->serialize() );
+       }
+
+       /**
+        * @covers \MediaWiki\Storage\RevisionStore::newRevisionFromArchiveRow
+        */
+       public function testNewRevisionFromArchiveRow_legacyEncoding() {
+               $this->setMwGlobals( 'wgLegacyEncoding', 'windows-1252' );
+               $this->overrideMwServices();
+               $store = MediaWikiServices::getInstance()->getRevisionStore();
+               $title = Title::newFromText( __METHOD__ );
+               $text = __METHOD__ . '-bä';
+               $page = WikiPage::factory( $title );
+               /** @var Revision $orig */
+               $orig = $page->doEditContent( new WikitextContent( $text ), __METHOD__ )
+                       ->value['revision'];
+               $page->doDeleteArticle( __METHOD__ );
+
+               $db = wfGetDB( DB_MASTER );
+               $arQuery = $store->getArchiveQueryInfo();
+               $res = $db->select(
+                       $arQuery['tables'], $arQuery['fields'], [ 'ar_rev_id' => $orig->getId() ],
+                       __METHOD__, [], $arQuery['joins']
+               );
+               $this->assertTrue( is_object( $res ), 'query failed' );
+
+               $row = $res->fetchObject();
+               $res->free();
+               $record = $store->newRevisionFromArchiveRow( $row );
+
+               $this->assertRevisionRecordMatchesRevision( $orig, $record );
+               $this->assertSame( $text, $record->getContent( 'main' )->serialize() );
+       }
+
+       /**
+        * @covers \MediaWiki\Storage\RevisionStore::insertRevisionOn
+        */
+       public function testInsertRevisionOn_archive() {
+               $store = MediaWikiServices::getInstance()->getRevisionStore();
+               $title = Title::newFromText( __METHOD__ );
+
+               $page = WikiPage::factory( $title );
+               /** @var Revision $origRev */
+               $page->doEditContent( new WikitextContent( "First" ), __METHOD__ . '-first' );
+               $origRev = $page->doEditContent( new WikitextContent( "Foo" ), __METHOD__ )
+                       ->value['revision'];
+               $orig = $origRev->getRevisionRecord();
+               $page->doDeleteArticle( __METHOD__ );
+
+               $db = wfGetDB( DB_MASTER );
+               $arQuery = $store->getArchiveQueryInfo();
+               $row = $db->selectRow(
+                       $arQuery['tables'], $arQuery['fields'], [ 'ar_rev_id' => $orig->getId() ],
+                       __METHOD__, [], $arQuery['joins']
+               );
+
+               $record = $store->newRevisionFromArchiveRow( $row );
+
+               $restored = $store->insertRevisionOn( $record, $db );
+               $this->assertSame( $orig->getPageId(), $restored->getPageId() );
+               $this->assertSame( $orig->getId(), $restored->getId() );
+               $this->assertSame( $orig->getComment()->text, $restored->getComment()->text );
+
+               $origMain = $orig->getSlot( 'main' );
+               $restoredMain = $restored->getSlot( 'main' );
+               $this->assertSame(
+                       $origMain->getOrigin(),
+                       $restoredMain->getOrigin()
+               );
+
+               if ( $origMain->hasContentId() ) {
+                       $this->assertSame(
+                               $origMain->getContentId(),
+                               $restoredMain->getContentId()
+                       );
+               }
+
+               // NOTE: we didn't restore the page row, so we can't use RevisionStore::getRevisionById
+               $this->assertSelect(
+                       'revision',
+                       [ 'rev_id' ],
+                       [ 'rev_id' => $orig->getId() ],
+                       [ [ $orig->getId() ] ]
+               );
+       }
+
+       /**
+        * @covers \MediaWiki\Storage\RevisionStore::loadRevisionFromId
+        */
+       public function testLoadRevisionFromId() {
+               $title = Title::newFromText( __METHOD__ );
+               $page = WikiPage::factory( $title );
+               /** @var Revision $rev */
+               $rev = $page->doEditContent( new WikitextContent( __METHOD__ ), __METHOD__ )
+                       ->value['revision'];
+
+               $store = MediaWikiServices::getInstance()->getRevisionStore();
+               $result = $store->loadRevisionFromId( wfGetDB( DB_MASTER ), $rev->getId() );
+               $this->assertRevisionRecordMatchesRevision( $rev, $result );
+       }
+
+       /**
+        * @covers \MediaWiki\Storage\RevisionStore::loadRevisionFromPageId
+        */
+       public function testLoadRevisionFromPageId() {
+               $title = Title::newFromText( __METHOD__ );
+               $page = WikiPage::factory( $title );
+               /** @var Revision $rev */
+               $rev = $page->doEditContent( new WikitextContent( __METHOD__ ), __METHOD__ )
+                       ->value['revision'];
+
+               $store = MediaWikiServices::getInstance()->getRevisionStore();
+               $result = $store->loadRevisionFromPageId( wfGetDB( DB_MASTER ), $page->getId() );
+               $this->assertRevisionRecordMatchesRevision( $rev, $result );
+       }
+
+       /**
+        * @covers \MediaWiki\Storage\RevisionStore::loadRevisionFromTitle
+        */
+       public function testLoadRevisionFromTitle() {
+               $title = Title::newFromText( __METHOD__ );
+               $page = WikiPage::factory( $title );
+               /** @var Revision $rev */
+               $rev = $page->doEditContent( new WikitextContent( __METHOD__ ), __METHOD__ )
+                       ->value['revision'];
+
+               $store = MediaWikiServices::getInstance()->getRevisionStore();
+               $result = $store->loadRevisionFromTitle( wfGetDB( DB_MASTER ), $title );
+               $this->assertRevisionRecordMatchesRevision( $rev, $result );
+       }
+
+       /**
+        * @covers \MediaWiki\Storage\RevisionStore::loadRevisionFromTimestamp
+        */
+       public function testLoadRevisionFromTimestamp() {
+               $title = Title::newFromText( __METHOD__ );
+               $page = WikiPage::factory( $title );
+               /** @var Revision $revOne */
+               $revOne = $page->doEditContent( new WikitextContent( __METHOD__ ), __METHOD__ )
+                       ->value['revision'];
+               // Sleep to ensure different timestamps... )(evil)
+               sleep( 1 );
+               /** @var Revision $revTwo */
+               $revTwo = $page->doEditContent( new WikitextContent( __METHOD__ . 'a' ), '' )
+                       ->value['revision'];
+
+               $store = MediaWikiServices::getInstance()->getRevisionStore();
+               $this->assertNull(
+                       $store->loadRevisionFromTimestamp( wfGetDB( DB_MASTER ), $title, '20150101010101' )
+               );
+               $this->assertSame(
+                       $revOne->getId(),
+                       $store->loadRevisionFromTimestamp(
+                               wfGetDB( DB_MASTER ),
+                               $title,
+                               $revOne->getTimestamp()
+                       )->getId()
+               );
+               $this->assertSame(
+                       $revTwo->getId(),
+                       $store->loadRevisionFromTimestamp(
+                               wfGetDB( DB_MASTER ),
+                               $title,
+                               $revTwo->getTimestamp()
+                       )->getId()
+               );
+       }
+
+       /**
+        * @covers \MediaWiki\Storage\RevisionStore::listRevisionSizes
+        */
+       public function testGetParentLengths() {
+               $page = WikiPage::factory( Title::newFromText( __METHOD__ ) );
+               /** @var Revision $revOne */
+               $revOne = $page->doEditContent(
+                       new WikitextContent( __METHOD__ ), __METHOD__
+               )->value['revision'];
+               /** @var Revision $revTwo */
+               $revTwo = $page->doEditContent(
+                       new WikitextContent( __METHOD__ . '2' ), __METHOD__
+               )->value['revision'];
+
+               $store = MediaWikiServices::getInstance()->getRevisionStore();
+               $this->assertSame(
+                       [
+                               $revOne->getId() => strlen( __METHOD__ ),
+                       ],
+                       $store->listRevisionSizes(
+                               wfGetDB( DB_MASTER ),
+                               [ $revOne->getId() ]
+                       )
+               );
+               $this->assertSame(
+                       [
+                               $revOne->getId() => strlen( __METHOD__ ),
+                               $revTwo->getId() => strlen( __METHOD__ ) + 1,
+                       ],
+                       $store->listRevisionSizes(
+                               wfGetDB( DB_MASTER ),
+                               [ $revOne->getId(), $revTwo->getId() ]
+                       )
+               );
+       }
+
+       /**
+        * @covers \MediaWiki\Storage\RevisionStore::getPreviousRevision
+        */
+       public function testGetPreviousRevision() {
+               $page = WikiPage::factory( Title::newFromText( __METHOD__ ) );
+               /** @var Revision $revOne */
+               $revOne = $page->doEditContent(
+                       new WikitextContent( __METHOD__ ), __METHOD__
+               )->value['revision'];
+               /** @var Revision $revTwo */
+               $revTwo = $page->doEditContent(
+                       new WikitextContent( __METHOD__ . '2' ), __METHOD__
+               )->value['revision'];
+
+               $store = MediaWikiServices::getInstance()->getRevisionStore();
+               $this->assertNull(
+                       $store->getPreviousRevision( $store->getRevisionById( $revOne->getId() ) )
+               );
+               $this->assertSame(
+                       $revOne->getId(),
+                       $store->getPreviousRevision( $store->getRevisionById( $revTwo->getId() ) )->getId()
+               );
+       }
+
+       /**
+        * @covers \MediaWiki\Storage\RevisionStore::getNextRevision
+        */
+       public function testGetNextRevision() {
+               $page = WikiPage::factory( Title::newFromText( __METHOD__ ) );
+               /** @var Revision $revOne */
+               $revOne = $page->doEditContent(
+                       new WikitextContent( __METHOD__ ), __METHOD__
+               )->value['revision'];
+               /** @var Revision $revTwo */
+               $revTwo = $page->doEditContent(
+                       new WikitextContent( __METHOD__ . '2' ), __METHOD__
+               )->value['revision'];
+
+               $store = MediaWikiServices::getInstance()->getRevisionStore();
+               $this->assertSame(
+                       $revTwo->getId(),
+                       $store->getNextRevision( $store->getRevisionById( $revOne->getId() ) )->getId()
+               );
+               $this->assertNull(
+                       $store->getNextRevision( $store->getRevisionById( $revTwo->getId() ) )
+               );
+       }
+
+       /**
+        * @covers \MediaWiki\Storage\RevisionStore::getTimestampFromId
+        */
+       public function testGetTimestampFromId_found() {
+               $page = $this->getTestPage();
+               /** @var Revision $rev */
+               $rev = $page->doEditContent( new WikitextContent( __METHOD__ ), __METHOD__ )
+                       ->value['revision'];
+
+               $store = MediaWikiServices::getInstance()->getRevisionStore();
+               $result = $store->getTimestampFromId(
+                       $page->getTitle(),
+                       $rev->getId()
+               );
+
+               $this->assertSame( $rev->getTimestamp(), $result );
+       }
+
+       /**
+        * @covers \MediaWiki\Storage\RevisionStore::getTimestampFromId
+        */
+       public function testGetTimestampFromId_notFound() {
+               $page = $this->getTestPage();
+               /** @var Revision $rev */
+               $rev = $page->doEditContent( new WikitextContent( __METHOD__ ), __METHOD__ )
+                       ->value['revision'];
+
+               $store = MediaWikiServices::getInstance()->getRevisionStore();
+               $result = $store->getTimestampFromId(
+                       $page->getTitle(),
+                       $rev->getId() + 1
+               );
+
+               $this->assertFalse( $result );
+       }
+
+       /**
+        * @covers \MediaWiki\Storage\RevisionStore::countRevisionsByPageId
+        */
+       public function testCountRevisionsByPageId() {
+               $store = MediaWikiServices::getInstance()->getRevisionStore();
+               $page = WikiPage::factory( Title::newFromText( __METHOD__ ) );
+
+               $this->assertSame(
+                       0,
+                       $store->countRevisionsByPageId( wfGetDB( DB_MASTER ), $page->getId() )
+               );
+               $page->doEditContent( new WikitextContent( 'a' ), 'a' );
+               $this->assertSame(
+                       1,
+                       $store->countRevisionsByPageId( wfGetDB( DB_MASTER ), $page->getId() )
+               );
+               $page->doEditContent( new WikitextContent( 'b' ), 'b' );
+               $this->assertSame(
+                       2,
+                       $store->countRevisionsByPageId( wfGetDB( DB_MASTER ), $page->getId() )
+               );
+       }
+
+       /**
+        * @covers \MediaWiki\Storage\RevisionStore::countRevisionsByTitle
+        */
+       public function testCountRevisionsByTitle() {
+               $store = MediaWikiServices::getInstance()->getRevisionStore();
+               $page = WikiPage::factory( Title::newFromText( __METHOD__ ) );
+
+               $this->assertSame(
+                       0,
+                       $store->countRevisionsByTitle( wfGetDB( DB_MASTER ), $page->getTitle() )
+               );
+               $page->doEditContent( new WikitextContent( 'a' ), 'a' );
+               $this->assertSame(
+                       1,
+                       $store->countRevisionsByTitle( wfGetDB( DB_MASTER ), $page->getTitle() )
+               );
+               $page->doEditContent( new WikitextContent( 'b' ), 'b' );
+               $this->assertSame(
+                       2,
+                       $store->countRevisionsByTitle( wfGetDB( DB_MASTER ), $page->getTitle() )
+               );
+       }
+
+       /**
+        * @covers \MediaWiki\Storage\RevisionStore::userWasLastToEdit
+        */
+       public function testUserWasLastToEdit_false() {
+               $sysop = $this->getTestSysop()->getUser();
+               $page = $this->getTestPage();
+               $page->doEditContent( new WikitextContent( __METHOD__ ), __METHOD__ );
+
+               $store = MediaWikiServices::getInstance()->getRevisionStore();
+               $result = $store->userWasLastToEdit(
+                       wfGetDB( DB_MASTER ),
+                       $page->getId(),
+                       $sysop->getId(),
+                       '20160101010101'
+               );
+               $this->assertFalse( $result );
+       }
+
+       /**
+        * @covers \MediaWiki\Storage\RevisionStore::userWasLastToEdit
+        */
+       public function testUserWasLastToEdit_true() {
+               $startTime = wfTimestampNow();
+               $sysop = $this->getTestSysop()->getUser();
+               $page = $this->getTestPage();
+               $page->doEditContent(
+                       new WikitextContent( __METHOD__ ),
+                       __METHOD__,
+                       0,
+                       false,
+                       $sysop
+               );
+
+               $store = MediaWikiServices::getInstance()->getRevisionStore();
+               $result = $store->userWasLastToEdit(
+                       wfGetDB( DB_MASTER ),
+                       $page->getId(),
+                       $sysop->getId(),
+                       $startTime
+               );
+               $this->assertTrue( $result );
+       }
+
+       /**
+        * @covers \MediaWiki\Storage\RevisionStore::getKnownCurrentRevision
+        */
+       public function testGetKnownCurrentRevision() {
+               $page = $this->getTestPage();
+               /** @var Revision $rev */
+               $rev = $page->doEditContent(
+                       new WikitextContent( __METHOD__ . 'b' ),
+                       __METHOD__ . 'b',
+                       0,
+                       false,
+                       $this->getTestUser()->getUser()
+               )->value['revision'];
+
+               $store = MediaWikiServices::getInstance()->getRevisionStore();
+               $record = $store->getKnownCurrentRevision(
+                       $page->getTitle(),
+                       $rev->getId()
+               );
+
+               $this->assertRevisionRecordMatchesRevision( $rev, $record );
+       }
+
+       public function provideNewMutableRevisionFromArray() {
+               yield 'Basic array, content object' => [
+                       [
+                               'id' => 2,
+                               'page' => 1,
+                               'timestamp' => '20171017114835',
+                               'user_text' => '111.0.1.2',
+                               'user' => 0,
+                               'minor_edit' => false,
+                               'deleted' => 0,
+                               'len' => 46,
+                               'parent_id' => 1,
+                               'sha1' => 'rdqbbzs3pkhihgbs8qf2q9jsvheag5z',
+                               'comment' => 'Goat Comment!',
+                               'content' => new WikitextContent( 'Some Content' ),
+                       ]
+               ];
+               yield 'Basic array, serialized text' => [
+                       [
+                               'id' => 2,
+                               'page' => 1,
+                               'timestamp' => '20171017114835',
+                               'user_text' => '111.0.1.2',
+                               'user' => 0,
+                               'minor_edit' => false,
+                               'deleted' => 0,
+                               'len' => 46,
+                               'parent_id' => 1,
+                               'sha1' => 'rdqbbzs3pkhihgbs8qf2q9jsvheag5z',
+                               'comment' => 'Goat Comment!',
+                               'text' => ( new WikitextContent( 'Söme Content' ) )->serialize(),
+                       ]
+               ];
+               yield 'Basic array, serialized text, utf-8 flags' => [
+                       [
+                               'id' => 2,
+                               'page' => 1,
+                               'timestamp' => '20171017114835',
+                               'user_text' => '111.0.1.2',
+                               'user' => 0,
+                               'minor_edit' => false,
+                               'deleted' => 0,
+                               'len' => 46,
+                               'parent_id' => 1,
+                               'sha1' => 'rdqbbzs3pkhihgbs8qf2q9jsvheag5z',
+                               'comment' => 'Goat Comment!',
+                               'text' => ( new WikitextContent( 'Söme Content' ) )->serialize(),
+                               'flags' => 'utf-8',
+                       ]
+               ];
+               yield 'Basic array, with title' => [
+                       [
+                               'title' => Title::newFromText( 'SomeText' ),
+                               'timestamp' => '20171017114835',
+                               'user_text' => '111.0.1.2',
+                               'user' => 0,
+                               'minor_edit' => false,
+                               'deleted' => 0,
+                               'len' => 46,
+                               'parent_id' => 1,
+                               'sha1' => 'rdqbbzs3pkhihgbs8qf2q9jsvheag5z',
+                               'comment' => 'Goat Comment!',
+                               'content' => new WikitextContent( 'Some Content' ),
+                       ]
+               ];
+               yield 'Basic array, no user field' => [
+                       [
+                               'id' => 2,
+                               'page' => 1,
+                               'timestamp' => '20171017114835',
+                               'user_text' => '111.0.1.3',
+                               'minor_edit' => false,
+                               'deleted' => 0,
+                               'len' => 46,
+                               'parent_id' => 1,
+                               'sha1' => 'rdqbbzs3pkhihgbs8qf2q9jsvheag5z',
+                               'comment' => 'Goat Comment!',
+                               'content' => new WikitextContent( 'Some Content' ),
+                       ]
+               ];
+       }
+
+       /**
+        * @dataProvider provideNewMutableRevisionFromArray
+        * @covers \MediaWiki\Storage\RevisionStore::newMutableRevisionFromArray
+        */
+       public function testNewMutableRevisionFromArray( array $array ) {
+               $store = MediaWikiServices::getInstance()->getRevisionStore();
+
+               // HACK: if $array['page'] is given, make sure that the page exists
+               if ( isset( $array['page'] ) ) {
+                       $t = Title::newFromID( $array['page'] );
+                       if ( !$t || !$t->exists() ) {
+                               $t = Title::makeTitle( NS_MAIN, __METHOD__ );
+                               $info = $this->insertPage( $t );
+                               $array['page'] = $info['id'];
+                       }
+               }
+
+               $result = $store->newMutableRevisionFromArray( $array );
+
+               if ( isset( $array['id'] ) ) {
+                       $this->assertSame( $array['id'], $result->getId() );
+               }
+               if ( isset( $array['page'] ) ) {
+                       $this->assertSame( $array['page'], $result->getPageId() );
+               }
+               $this->assertSame( $array['timestamp'], $result->getTimestamp() );
+               $this->assertSame( $array['user_text'], $result->getUser()->getName() );
+               if ( isset( $array['user'] ) ) {
+                       $this->assertSame( $array['user'], $result->getUser()->getId() );
+               }
+               $this->assertSame( (bool)$array['minor_edit'], $result->isMinor() );
+               $this->assertSame( $array['deleted'], $result->getVisibility() );
+               $this->assertSame( $array['len'], $result->getSize() );
+               $this->assertSame( $array['parent_id'], $result->getParentId() );
+               $this->assertSame( $array['sha1'], $result->getSha1() );
+               $this->assertSame( $array['comment'], $result->getComment()->text );
+               if ( isset( $array['content'] ) ) {
+                       foreach ( $array['content'] as $role => $content ) {
+                               $this->assertTrue(
+                                       $result->getContent( $role )->equals( $content )
+                               );
+                       }
+               } elseif ( isset( $array['text'] ) ) {
+                       $this->assertSame( $array['text'], $result->getSlot( 'main' )->getContent()->serialize() );
+               } elseif ( isset( $array['content_format'] ) ) {
+                       $this->assertSame(
+                               $array['content_format'],
+                               $result->getSlot( 'main' )->getContent()->getDefaultFormat()
+                       );
+                       $this->assertSame( $array['content_model'], $result->getSlot( 'main' )->getModel() );
+               }
+       }
+
+       /**
+        * @dataProvider provideNewMutableRevisionFromArray
+        * @covers \MediaWiki\Storage\RevisionStore::newMutableRevisionFromArray
+        */
+       public function testNewMutableRevisionFromArray_legacyEncoding( array $array ) {
+               $cache = new WANObjectCache( [ 'cache' => new HashBagOStuff() ] );
+               $lb = MediaWikiServices::getInstance()->getDBLoadBalancer();
+               $blobStore = new SqlBlobStore( $lb, $cache );
+               $blobStore->setLegacyEncoding( 'windows-1252', Language::factory( 'en' ) );
+
+               $factory = $this->getMockBuilder( BlobStoreFactory::class )
+                       ->setMethods( [ 'newBlobStore', 'newSqlBlobStore' ] )
+                       ->disableOriginalConstructor()
+                       ->getMock();
+               $factory->expects( $this->any() )
+                       ->method( 'newBlobStore' )
+                       ->willReturn( $blobStore );
+               $factory->expects( $this->any() )
+                       ->method( 'newSqlBlobStore' )
+                       ->willReturn( $blobStore );
+
+               $this->setService( 'BlobStoreFactory', $factory );
+
+               $this->testNewMutableRevisionFromArray( $array );
+       }
+
+       protected function getDefaultQueryFields( $returnTextIdField = true ) {
+               $fields = [
+                       'rev_id',
+                       'rev_page',
+                       'rev_timestamp',
+                       'rev_minor_edit',
+                       'rev_deleted',
+                       'rev_len',
+                       'rev_parent_id',
+                       'rev_sha1',
+               ];
+               if ( $returnTextIdField ) {
+                       $fields[] = 'rev_text_id';
+               }
+               return $fields;
+       }
+
+       protected function getCommentQueryFields() {
+               return [
+                       'rev_comment_text' => 'rev_comment',
+                       'rev_comment_data' => 'NULL',
+                       'rev_comment_cid' => 'NULL',
+               ];
+       }
+
+       protected function getActorQueryFields() {
+               return [
+                       'rev_user' => 'rev_user',
+                       'rev_user_text' => 'rev_user_text',
+                       'rev_actor' => 'NULL',
+               ];
+       }
+
+       protected function getContentHandlerQueryFields() {
+               return [
+                       'rev_content_format',
+                       'rev_content_model',
+               ];
+       }
+
+       abstract public function provideGetQueryInfo();
+
+       /**
+        * @dataProvider provideGetQueryInfo
+        * @covers \MediaWiki\Storage\RevisionStore::getQueryInfo
+        */
+       public function testGetQueryInfo( $options, $expected ) {
+               $store = MediaWikiServices::getInstance()->getRevisionStore();
+
+               $queryInfo = $store->getQueryInfo( $options );
+
+               $this->assertArrayEqualsIgnoringIntKeyOrder(
+                       $expected['tables'],
+                       $queryInfo['tables']
+               );
+               $this->assertArrayEqualsIgnoringIntKeyOrder(
+                       $expected['fields'],
+                       $queryInfo['fields']
+               );
+               $this->assertArrayEqualsIgnoringIntKeyOrder(
+                       $expected['joins'],
+                       $queryInfo['joins']
+               );
+       }
+
+       protected function getDefaultArchiveFields( $returnTextFields = true ) {
+               $fields = [
+                       'ar_id',
+                       'ar_page_id',
+                       'ar_namespace',
+                       'ar_title',
+                       'ar_rev_id',
+                       'ar_timestamp',
+                       'ar_minor_edit',
+                       'ar_deleted',
+                       'ar_len',
+                       'ar_parent_id',
+                       'ar_sha1',
+               ];
+               if ( $returnTextFields ) {
+                       $fields[] = 'ar_text_id';
+               }
+               return $fields;
+       }
+
+       abstract public function provideGetArchiveQueryInfo();
+
+       /**
+        * @dataProvider provideGetArchiveQueryInfo
+        * @covers \MediaWiki\Storage\RevisionStore::getArchiveQueryInfo
+        */
+       public function testGetArchiveQueryInfo( $expected ) {
+               $store = MediaWikiServices::getInstance()->getRevisionStore();
+
+               $archiveQueryInfo = $store->getArchiveQueryInfo();
+
+               $this->assertArrayEqualsIgnoringIntKeyOrder(
+                       $expected['tables'],
+                       $archiveQueryInfo['tables']
+               );
+
+               $this->assertArrayEqualsIgnoringIntKeyOrder(
+                       $expected['fields'],
+                       $archiveQueryInfo['fields']
+               );
+
+               $this->assertArrayEqualsIgnoringIntKeyOrder(
+                       $expected['joins'],
+                       $archiveQueryInfo['joins']
+               );
+       }
+
+       abstract public function provideGetSlotsQueryInfo();
+
+       /**
+        * @dataProvider provideGetSlotsQueryInfo
+        * @covers \MediaWiki\Storage\RevisionStore::getSlotsQueryInfo
+        */
+       public function testGetSlotsQueryInfo( $options, $expected ) {
+               $store = MediaWikiServices::getInstance()->getRevisionStore();
+
+               $archiveQueryInfo = $store->getSlotsQueryInfo( $options );
+
+               $this->assertArrayEqualsIgnoringIntKeyOrder(
+                       $expected['tables'],
+                       $archiveQueryInfo['tables']
+               );
+
+               $this->assertArrayEqualsIgnoringIntKeyOrder(
+                       $expected['fields'],
+                       $archiveQueryInfo['fields']
+               );
+
+               $this->assertArrayEqualsIgnoringIntKeyOrder(
+                       $expected['joins'],
+                       $archiveQueryInfo['joins']
+               );
+       }
+
+       /**
+        * Assert that the two arrays passed are equal, ignoring the order of the values that integer
+        * keys.
+        *
+        * Note: Failures of this assertion can be slightly confusing as the arrays are actually
+        * split into a string key array and an int key array before assertions occur.
+        *
+        * @param array $expected
+        * @param array $actual
+        */
+       private function assertArrayEqualsIgnoringIntKeyOrder( array $expected, array $actual ) {
+               $this->objectAssociativeSort( $expected );
+               $this->objectAssociativeSort( $actual );
+
+               // Separate the int key values from the string key values so that assertion failures are
+               // easier to understand.
+               $expectedIntKeyValues = [];
+               $actualIntKeyValues = [];
+
+               // Remove all int keys and re add them at the end after sorting by value
+               // This will result in all int keys being in the same order with same ints at the end of
+               // the array
+               foreach ( $expected as $key => $value ) {
+                       if ( is_int( $key ) ) {
+                               unset( $expected[$key] );
+                               $expectedIntKeyValues[] = $value;
+                       }
+               }
+               foreach ( $actual as $key => $value ) {
+                       if ( is_int( $key ) ) {
+                               unset( $actual[$key] );
+                               $actualIntKeyValues[] = $value;
+                       }
+               }
+
+               $this->assertArrayEquals( $expected, $actual, false, true );
+               $this->assertArrayEquals( $expectedIntKeyValues, $actualIntKeyValues, false, true );
+       }
+
+}
index 0295e90..1d6a9a0 100644 (file)
@@ -168,7 +168,9 @@ class RevisionStoreRecordTest extends MediaWikiTestCase {
                $this->assertSame( $user, $rec->getUser( RevisionRecord::RAW ), 'getUser' );
                $this->assertSame( $comment, $rec->getComment(), 'getComment' );
 
+               $this->assertSame( $slots, $rec->getSlots(), 'getSlots' );
                $this->assertSame( $slots->getSlotRoles(), $rec->getSlotRoles(), 'getSlotRoles' );
+               $this->assertSame( $slots->getSlots(), $rec->getSlots()->getSlots(), 'getSlots' );
                $this->assertSame( $wikiId, $rec->getWikiId(), 'getWikiId' );
 
                $this->assertSame( (int)$row->rev_id, $rec->getId(), 'getId' );
index fed9a0c..90bd57a 100644 (file)
@@ -2,17 +2,21 @@
 
 namespace MediaWiki\Tests\Storage;
 
+use CommentStore;
 use HashBagOStuff;
+use InvalidArgumentException;
 use Language;
 use MediaWiki\MediaWikiServices;
 use MediaWiki\Storage\RevisionAccessException;
 use MediaWiki\Storage\RevisionStore;
 use MediaWiki\Storage\SqlBlobStore;
 use MediaWikiTestCase;
+use MWException;
 use Title;
 use WANObjectCache;
 use Wikimedia\Rdbms\Database;
 use Wikimedia\Rdbms\LoadBalancer;
+use Wikimedia\TestingAccessWrapper;
 
 class RevisionStoreTest extends MediaWikiTestCase {
 
@@ -28,11 +32,18 @@ class RevisionStoreTest extends MediaWikiTestCase {
                $blobStore = null,
                $WANObjectCache = null
        ) {
+               global $wgMultiContentRevisionSchemaMigrationStage;
+               // the migration stage should be irrelevant, since all the tests that interact with
+               // the database are in RevisionStoreDbTest, not here.
+
                return new RevisionStore(
-                       $loadBalancer ? $loadBalancer : $this->getMockLoadBalancer(),
-                       $blobStore ? $blobStore : $this->getMockSqlBlobStore(),
-                       $WANObjectCache ? $WANObjectCache : $this->getHashWANObjectCache(),
+                       $loadBalancer ?: $this->getMockLoadBalancer(),
+                       $blobStore ?: $this->getMockSqlBlobStore(),
+                       $WANObjectCache ?: $this->getHashWANObjectCache(),
                        MediaWikiServices::getInstance()->getCommentStore(),
+                       MediaWikiServices::getInstance()->getContentModelStore(),
+                       MediaWikiServices::getInstance()->getSlotRoleStore(),
+                       $wgMultiContentRevisionSchemaMigrationStage,
                        MediaWikiServices::getInstance()->getActorMigration()
                );
        }
@@ -61,271 +72,57 @@ class RevisionStoreTest extends MediaWikiTestCase {
                        ->disableOriginalConstructor()->getMock();
        }
 
-       private function getHashWANObjectCache() {
-               return new WANObjectCache( [ 'cache' => new \HashBagOStuff() ] );
-       }
-
        /**
-        * @covers \MediaWiki\Storage\RevisionStore::getContentHandlerUseDB
-        * @covers \MediaWiki\Storage\RevisionStore::setContentHandlerUseDB
+        * @return \PHPUnit_Framework_MockObject_MockObject|CommentStore
         */
-       public function testGetSetContentHandlerDb() {
-               $store = $this->getRevisionStore();
-               $this->assertTrue( $store->getContentHandlerUseDB() );
-               $store->setContentHandlerUseDB( false );
-               $this->assertFalse( $store->getContentHandlerUseDB() );
-               $store->setContentHandlerUseDB( true );
-               $this->assertTrue( $store->getContentHandlerUseDB() );
-       }
-
-       private function getDefaultQueryFields() {
-               return [
-                       'rev_id',
-                       'rev_page',
-                       'rev_text_id',
-                       'rev_timestamp',
-                       'rev_minor_edit',
-                       'rev_deleted',
-                       'rev_len',
-                       'rev_parent_id',
-                       'rev_sha1',
-               ];
-       }
-
-       private function getCommentQueryFields() {
-               return [
-                       'rev_comment_text' => 'rev_comment',
-                       'rev_comment_data' => 'NULL',
-                       'rev_comment_cid' => 'NULL',
-               ];
+       private function getMockCommentStore() {
+               return $this->getMockBuilder( CommentStore::class )
+                       ->disableOriginalConstructor()->getMock();
        }
 
-       private function getActorQueryFields() {
-               return [
-                       'rev_user' => 'rev_user',
-                       'rev_user_text' => 'rev_user_text',
-                       'rev_actor' => 'NULL',
-               ];
+       private function getHashWANObjectCache() {
+               return new WANObjectCache( [ 'cache' => new \HashBagOStuff() ] );
        }
 
-       private function getContentHandlerQueryFields() {
+       public function provideSetContentHandlerUseDB() {
                return [
-                       'rev_content_format',
-                       'rev_content_model',
-               ];
-       }
-
-       public function provideGetQueryInfo() {
-               yield [
-                       true,
-                       [],
-                       [
-                               'tables' => [ 'revision' ],
-                               'fields' => array_merge(
-                                       $this->getDefaultQueryFields(),
-                                       $this->getCommentQueryFields(),
-                                       $this->getActorQueryFields(),
-                                       $this->getContentHandlerQueryFields()
-                               ),
-                               'joins' => [],
-                       ]
-               ];
-               yield [
-                       false,
-                       [],
-                       [
-                               'tables' => [ 'revision' ],
-                               'fields' => array_merge(
-                                       $this->getDefaultQueryFields(),
-                                       $this->getCommentQueryFields(),
-                                       $this->getActorQueryFields()
-                               ),
-                               'joins' => [],
-                       ]
-               ];
-               yield [
-                       false,
-                       [ 'page' ],
-                       [
-                               'tables' => [ 'revision', 'page' ],
-                               'fields' => array_merge(
-                                       $this->getDefaultQueryFields(),
-                                       $this->getCommentQueryFields(),
-                                       $this->getActorQueryFields(),
-                                       [
-                                               'page_namespace',
-                                               'page_title',
-                                               'page_id',
-                                               'page_latest',
-                                               'page_is_redirect',
-                                               'page_len',
-                                       ]
-                               ),
-                               'joins' => [
-                                       'page' => [ 'INNER JOIN', [ 'page_id = rev_page' ] ],
-                               ],
-                       ]
-               ];
-               yield [
-                       false,
-                       [ 'user' ],
-                       [
-                               'tables' => [ 'revision', 'user' ],
-                               'fields' => array_merge(
-                                       $this->getDefaultQueryFields(),
-                                       $this->getCommentQueryFields(),
-                                       $this->getActorQueryFields(),
-                                       [
-                                               'user_name',
-                                       ]
-                               ),
-                               'joins' => [
-                                       'user' => [ 'LEFT JOIN', [ 'rev_user != 0', 'user_id = rev_user' ] ],
-                               ],
-                       ]
-               ];
-               yield [
-                       false,
-                       [ 'text' ],
-                       [
-                               'tables' => [ 'revision', 'text' ],
-                               'fields' => array_merge(
-                                       $this->getDefaultQueryFields(),
-                                       $this->getCommentQueryFields(),
-                                       $this->getActorQueryFields(),
-                                       [
-                                               'old_text',
-                                               'old_flags',
-                                       ]
-                               ),
-                               'joins' => [
-                                       'text' => [ 'INNER JOIN', [ 'rev_text_id=old_id' ] ],
-                               ],
-                       ]
-               ];
-               yield [
-                       true,
-                       [ 'page', 'user', 'text' ],
-                       [
-                               'tables' => [ 'revision', 'page', 'user', 'text' ],
-                               'fields' => array_merge(
-                                       $this->getDefaultQueryFields(),
-                                       $this->getCommentQueryFields(),
-                                       $this->getActorQueryFields(),
-                                       $this->getContentHandlerQueryFields(),
-                                       [
-                                               'page_namespace',
-                                               'page_title',
-                                               'page_id',
-                                               'page_latest',
-                                               'page_is_redirect',
-                                               'page_len',
-                                               'user_name',
-                                               'old_text',
-                                               'old_flags',
-                                       ]
-                               ),
-                               'joins' => [
-                                       'page' => [ 'INNER JOIN', [ 'page_id = rev_page' ] ],
-                                       'user' => [ 'LEFT JOIN', [ 'rev_user != 0', 'user_id = rev_user' ] ],
-                                       'text' => [ 'INNER JOIN', [ 'rev_text_id=old_id' ] ],
-                               ],
-                       ]
+                       // ContentHandlerUseDB can be true of false pre migration.
+                       [ false, SCHEMA_COMPAT_OLD, false ],
+                       [ true, SCHEMA_COMPAT_OLD, false ],
+                       // During and after migration it can not be false...
+                       [ false, SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD, true ],
+                       [ false, SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW, true ],
+                       [ false, SCHEMA_COMPAT_NEW, true ],
+                       // ...but it can be true.
+                       [ true, SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD, false ],
+                       [ true, SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW, false ],
+                       [ true, SCHEMA_COMPAT_NEW, false ],
                ];
        }
 
        /**
-        * @dataProvider provideGetQueryInfo
-        * @covers \MediaWiki\Storage\RevisionStore::getQueryInfo
+        * @dataProvider provideSetContentHandlerUseDB
+        * @covers \MediaWiki\Storage\RevisionStore::getContentHandlerUseDB
+        * @covers \MediaWiki\Storage\RevisionStore::setContentHandlerUseDB
         */
-       public function testGetQueryInfo( $contentHandlerUseDb, $options, $expected ) {
-               $this->setMwGlobals( 'wgCommentTableSchemaMigrationStage', MIGRATION_OLD );
-               $this->setMwGlobals( 'wgActorTableSchemaMigrationStage', MIGRATION_OLD );
-               $this->overrideMwServices();
-               $store = $this->getRevisionStore();
-               $store->setContentHandlerUseDB( $contentHandlerUseDb );
-               $this->assertEquals( $expected, $store->getQueryInfo( $options ) );
-       }
-
-       private function getDefaultArchiveFields() {
-               return [
-                       'ar_id',
-                       'ar_page_id',
-                       'ar_namespace',
-                       'ar_title',
-                       'ar_rev_id',
-                       'ar_text_id',
-                       'ar_timestamp',
-                       'ar_minor_edit',
-                       'ar_deleted',
-                       'ar_len',
-                       'ar_parent_id',
-                       'ar_sha1',
-               ];
-       }
+       public function testSetContentHandlerUseDB( $contentHandlerDb, $migrationMode, $expectedFail ) {
+               if ( $expectedFail ) {
+                       $this->setExpectedException( MWException::class );
+               }
 
-       /**
-        * @covers \MediaWiki\Storage\RevisionStore::getArchiveQueryInfo
-        */
-       public function testGetArchiveQueryInfo_contentHandlerDb() {
-               $this->setMwGlobals( 'wgCommentTableSchemaMigrationStage', MIGRATION_OLD );
-               $this->setMwGlobals( 'wgActorTableSchemaMigrationStage', MIGRATION_OLD );
-               $this->overrideMwServices();
-               $store = $this->getRevisionStore();
-               $store->setContentHandlerUseDB( true );
-               $this->assertEquals(
-                       [
-                               'tables' => [
-                                       'archive'
-                               ],
-                               'fields' => array_merge(
-                                       $this->getDefaultArchiveFields(),
-                                       [
-                                               'ar_comment_text' => 'ar_comment',
-                                               'ar_comment_data' => 'NULL',
-                                               'ar_comment_cid' => 'NULL',
-                                               'ar_user_text' => 'ar_user_text',
-                                               'ar_user' => 'ar_user',
-                                               'ar_actor' => 'NULL',
-                                               'ar_content_format',
-                                               'ar_content_model',
-                                       ]
-                               ),
-                               'joins' => [],
-                       ],
-                       $store->getArchiveQueryInfo()
+               $store = new RevisionStore(
+                       $this->getMockLoadBalancer(),
+                       $this->getMockSqlBlobStore(),
+                       $this->getHashWANObjectCache(),
+                       $this->getMockCommentStore(),
+                       MediaWikiServices::getInstance()->getContentModelStore(),
+                       MediaWikiServices::getInstance()->getSlotRoleStore(),
+                       $migrationMode,
+                       MediaWikiServices::getInstance()->getActorMigration()
                );
-       }
 
-       /**
-        * @covers \MediaWiki\Storage\RevisionStore::getArchiveQueryInfo
-        */
-       public function testGetArchiveQueryInfo_noContentHandlerDb() {
-               $this->setMwGlobals( 'wgCommentTableSchemaMigrationStage', MIGRATION_OLD );
-               $this->setMwGlobals( 'wgActorTableSchemaMigrationStage', MIGRATION_OLD );
-               $this->overrideMwServices();
-               $store = $this->getRevisionStore();
-               $store->setContentHandlerUseDB( false );
-               $this->assertEquals(
-                       [
-                               'tables' => [
-                                       'archive'
-                               ],
-                               'fields' => array_merge(
-                                       $this->getDefaultArchiveFields(),
-                                       [
-                                               'ar_comment_text' => 'ar_comment',
-                                               'ar_comment_data' => 'NULL',
-                                               'ar_comment_cid' => 'NULL',
-                                               'ar_user_text' => 'ar_user_text',
-                                               'ar_user' => 'ar_user',
-                                               'ar_actor' => 'NULL',
-                                       ]
-                               ),
-                               'joins' => [],
-                       ],
-                       $store->getArchiveQueryInfo()
-               );
+               $store->setContentHandlerUseDB( $contentHandlerDb );
+               $this->assertSame( $contentHandlerDb, $store->getContentHandlerUseDB() );
        }
 
        public function testGetTitle_successFromPageId() {
@@ -610,7 +407,6 @@ class RevisionStoreTest extends MediaWikiTestCase {
         * @dataProvider provideNewRevisionFromRow_legacyEncoding_applied
         *
         * @covers \MediaWiki\Storage\RevisionStore::newRevisionFromRow
-        * @covers \MediaWiki\Storage\RevisionStore::newRevisionFromRow_1_29
         */
        public function testNewRevisionFromRow_legacyEncoding_applied( $encoding, $locale, $row, $text ) {
                $cache = new WANObjectCache( [ 'cache' => new HashBagOStuff() ] );
@@ -632,7 +428,6 @@ class RevisionStoreTest extends MediaWikiTestCase {
 
        /**
         * @covers \MediaWiki\Storage\RevisionStore::newRevisionFromRow
-        * @covers \MediaWiki\Storage\RevisionStore::newRevisionFromRow_1_29
         */
        public function testNewRevisionFromRow_legacyEncoding_ignored() {
                $row = [
@@ -689,4 +484,52 @@ class RevisionStoreTest extends MediaWikiTestCase {
                return (object)$row;
        }
 
+       public function provideMigrationConstruction() {
+               return [
+                       [ SCHEMA_COMPAT_OLD, false ],
+                       [ SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD, false ],
+                       [ SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW, false ],
+                       [ SCHEMA_COMPAT_NEW, false ],
+                       [ SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_BOTH, true ],
+                       [ SCHEMA_COMPAT_WRITE_OLD | SCHEMA_COMPAT_READ_BOTH, true ],
+                       [ SCHEMA_COMPAT_WRITE_NEW | SCHEMA_COMPAT_READ_BOTH, true ],
+               ];
+       }
+
+       /**
+        * @covers \MediaWiki\Storage\RevisionStore::__construct
+        * @dataProvider provideMigrationConstruction
+        */
+       public function testMigrationConstruction( $migration, $expectException ) {
+               if ( $expectException ) {
+                       $this->setExpectedException( InvalidArgumentException::class );
+               }
+               $loadBalancer = $this->getMockLoadBalancer();
+               $blobStore = $this->getMockSqlBlobStore();
+               $cache = $this->getHashWANObjectCache();
+               $commentStore = $this->getMockCommentStore();
+               $contentModelStore = MediaWikiServices::getInstance()->getContentModelStore();
+               $slotRoleStore = MediaWikiServices::getInstance()->getSlotRoleStore();
+               $store = new RevisionStore(
+                       $loadBalancer,
+                       $blobStore,
+                       $cache,
+                       $commentStore,
+                       MediaWikiServices::getInstance()->getContentModelStore(),
+                       MediaWikiServices::getInstance()->getSlotRoleStore(),
+                       $migration,
+                       MediaWikiServices::getInstance()->getActorMigration()
+               );
+               if ( !$expectException ) {
+                       $store = TestingAccessWrapper::newFromObject( $store );
+                       $this->assertSame( $loadBalancer, $store->loadBalancer );
+                       $this->assertSame( $blobStore, $store->blobStore );
+                       $this->assertSame( $cache, $store->cache );
+                       $this->assertSame( $commentStore, $store->commentStore );
+                       $this->assertSame( $contentModelStore, $store->contentModelStore );
+                       $this->assertSame( $slotRoleStore, $store->slotRoleStore );
+                       $this->assertSame( $migration, $store->mcrMigrationStage );
+               }
+       }
+
 }
index feeb538..1aae16d 100644 (file)
@@ -36,6 +36,7 @@ class SlotRecordTest extends MediaWikiTestCase {
                $record = new SlotRecord( $row, new WikitextContent( 'A' ) );
 
                $this->assertTrue( $record->hasAddress() );
+               $this->assertTrue( $record->hasContentId() );
                $this->assertTrue( $record->hasRevision() );
                $this->assertTrue( $record->isInherited() );
                $this->assertSame( 'A', $record->getContent()->getNativeData() );
@@ -59,6 +60,9 @@ class SlotRecordTest extends MediaWikiTestCase {
                        },
                        'slot_revision_id' => '2',
                        'slot_origin' => '2',
+                       'slot_content_id' => function () {
+                               return null;
+                       },
                ] );
 
                $content = function () {
@@ -69,6 +73,7 @@ class SlotRecordTest extends MediaWikiTestCase {
 
                $this->assertTrue( $record->hasAddress() );
                $this->assertTrue( $record->hasRevision() );
+               $this->assertFalse( $record->hasContentId() );
                $this->assertFalse( $record->isInherited() );
                $this->assertSame( 'A', $record->getContent()->getNativeData() );
                $this->assertSame( 1, $record->getSize() );
@@ -77,7 +82,6 @@ class SlotRecordTest extends MediaWikiTestCase {
                $this->assertSame( 2, $record->getRevision() );
                $this->assertSame( 2, $record->getRevision() );
                $this->assertSame( 'tt:456', $record->getAddress() );
-               $this->assertSame( 33, $record->getContentId() );
                $this->assertSame( CONTENT_FORMAT_WIKITEXT, $record->getFormat() );
                $this->assertSame( 'myRole', $record->getRole() );
        }
@@ -86,8 +90,10 @@ class SlotRecordTest extends MediaWikiTestCase {
                $record = SlotRecord::newUnsaved( 'myRole', new WikitextContent( 'A' ) );
 
                $this->assertFalse( $record->hasAddress() );
+               $this->assertFalse( $record->hasContentId() );
                $this->assertFalse( $record->hasRevision() );
                $this->assertFalse( $record->isInherited() );
+               $this->assertFalse( $record->hasOrigin() );
                $this->assertSame( 'A', $record->getContent()->getNativeData() );
                $this->assertSame( 1, $record->getSize() );
                $this->assertNotNull( $record->getSha1() );
@@ -190,6 +196,7 @@ class SlotRecordTest extends MediaWikiTestCase {
                $this->assertSame( $parent->getAddress(), $inherited->getAddress() );
                $this->assertSame( $parent->getContent(), $inherited->getContent() );
                $this->assertTrue( $inherited->isInherited() );
+               $this->assertTrue( $inherited->hasOrigin() );
                $this->assertFalse( $inherited->hasRevision() );
 
                // make sure we didn't mess with the internal state of $parent
@@ -224,8 +231,10 @@ class SlotRecordTest extends MediaWikiTestCase {
                // and content meta-data.
                $saved = SlotRecord::newSaved( 10, 20, 'theNewAddress', $unsaved );
                $this->assertFalse( $saved->isInherited() );
+               $this->assertTrue( $saved->hasOrigin() );
                $this->assertTrue( $saved->hasRevision() );
                $this->assertTrue( $saved->hasAddress() );
+               $this->assertTrue( $saved->hasContentId() );
                $this->assertSame( 'theNewAddress', $saved->getAddress() );
                $this->assertSame( 20, $saved->getContentId() );
                $this->assertSame( 'A', $saved->getContent()->getNativeData() );
@@ -234,6 +243,7 @@ class SlotRecordTest extends MediaWikiTestCase {
 
                // make sure we didn't mess with the internal state of $unsaved
                $this->assertFalse( $unsaved->hasAddress() );
+               $this->assertFalse( $unsaved->hasContentId() );
                $this->assertFalse( $unsaved->hasRevision() );
        }
 
index 07f1f82..b5f7322 100644 (file)
@@ -86,9 +86,9 @@ class SqlBlobStoreTest extends MediaWikiTestCase {
        }
 
        public function provideDecompress() {
-               yield '(no legacy encoding), false in false out' => [ false, false, [], false ];
                yield '(no legacy encoding), empty in empty out' => [ false, '', [], '' ];
                yield '(no legacy encoding), empty in empty out' => [ false, 'A', [], 'A' ];
+               yield '(no legacy encoding), error flag -> false' => [ false, 'X', [ 'error' ], false ];
                yield '(no legacy encoding), string in with gzip flag returns string' => [
                        // gzip string below generated with gzdeflate( 'AAAABBAAA' )
                        false, "sttttr\002\022\000", [ 'gzip' ], 'AAAABBAAA',
@@ -166,6 +166,16 @@ class SqlBlobStoreTest extends MediaWikiTestCase {
                );
        }
 
+       /**
+        * @covers \MediaWiki\Storage\SqlBlobStore::decompressData
+        */
+       public function testDecompressData_InvalidArgumentException() {
+               $store = $this->getBlobStore();
+
+               $this->setExpectedException( InvalidArgumentException::class );
+               $store->decompressData( false, [] );
+       }
+
        /**
         * @covers \MediaWiki\Storage\SqlBlobStore::compressData
         */
diff --git a/tests/phpunit/includes/Storage/create-pre-mcr-fields.sql b/tests/phpunit/includes/Storage/create-pre-mcr-fields.sql
new file mode 100644 (file)
index 0000000..09deb4f
--- /dev/null
@@ -0,0 +1,3 @@
+ALTER TABLE /*_*/revision ADD rev_text_id INTEGER DEFAULT 0;
+ALTER TABLE /*_*/revision  ADD rev_content_model VARBINARY(32) DEFAULT NULL;
+ALTER TABLE /*_*/revision ADD rev_content_format VARBINARY(64) DEFAULT NULL;
diff --git a/tests/phpunit/includes/Storage/drop-mcr-tables.sql b/tests/phpunit/includes/Storage/drop-mcr-tables.sql
new file mode 100644 (file)
index 0000000..bc89edc
--- /dev/null
@@ -0,0 +1,4 @@
+DROP TABLE /*_*/slots;
+DROP TABLE /*_*/content;
+DROP TABLE /*_*/content_models;
+DROP TABLE /*_*/slot_roles;
diff --git a/tests/phpunit/includes/Storage/drop-pre-mcr-fields.sql b/tests/phpunit/includes/Storage/drop-pre-mcr-fields.sql
new file mode 100644 (file)
index 0000000..ddfe756
--- /dev/null
@@ -0,0 +1,3 @@
+ALTER TABLE /*_*/revision DROP COLUMN rev_text_id;
+ALTER TABLE /*_*/revision DROP COLUMN rev_content_model;
+ALTER TABLE /*_*/revision DROP COLUMN rev_content_format;
diff --git a/tests/phpunit/includes/Storage/drop-pre-mcr-fields.sqlite.sql b/tests/phpunit/includes/Storage/drop-pre-mcr-fields.sqlite.sql
new file mode 100644 (file)
index 0000000..ce7a618
--- /dev/null
@@ -0,0 +1,15 @@
+DROP TABLE /*_*/revision;
+
+CREATE TABLE /*_*/revision (
+  rev_id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
+  rev_page INTEGER NOT NULL,
+  rev_comment BLOB NOT NULL,
+  rev_user INTEGER NOT NULL default 0,
+  rev_user_text varchar(255) NOT NULL default '',
+  rev_timestamp blob(14) NOT NULL default '',
+  rev_minor_edit INTEGER NOT NULL default 0,
+  rev_deleted INTEGER NOT NULL default 0,
+  rev_len INTEGER unsigned,
+  rev_parent_id INTEGER default NULL,
+  rev_sha1 varbinary(32) NOT NULL default ''
+) /*$wgDBTableOptions*/;
index 17a4182..e50e1bc 100644 (file)
@@ -38,7 +38,7 @@ class TestLogger extends \Psr\Log\AbstractLogger {
 
        /**
         * @param bool $collect Whether to collect logs. @see setCollect()
-        * @param callable $filter Filter logs before collecting/printing. Signature is
+        * @param callable|null $filter Filter logs before collecting/printing. Signature is
         *  string|null function ( string $message, string $level, array $context );
         * @param bool $collectContext Whether to keep the context passed to log
         *             (since 1.29, @see setCollectContext()).
index 0c178ca..24aee24 100644 (file)
@@ -62,9 +62,7 @@ class TestUserRegistry {
                sort( $groups );
                $key = implode( ',', $groups );
 
-               $testUser = isset( self::$testUsers[$key] )
-                       ? self::$testUsers[$key]
-                       : false;
+               $testUser = self::$testUsers[$key] ?? false;
 
                if ( !$testUser || !$testUser->getUser()->isLoggedIn() ) {
                        $id = self::getNextId();
index 4032b3a..e898c63 100644 (file)
@@ -1,5 +1,7 @@
 <?php
 
+use MediaWiki\MediaWikiServices;
+
 /**
  * @group ContentHandler
  * @group Database
@@ -353,7 +355,7 @@ class TitleMethodsTest extends MediaWikiLangTestCase {
         * @covers Title::clearCaches
         */
        public function testClearCaches() {
-               $linkCache = LinkCache::singleton();
+               $linkCache = MediaWikiServices::getInstance()->getLinkCache();
 
                $title1 = Title::newFromText( 'Foo' );
                $linkCache->addGoodLinkObj( 23, $title1 );
index 4e34244..6600aa2 100644 (file)
@@ -842,18 +842,23 @@ class TitlePermissionTest extends MediaWikiLangTestCase {
         * @covers Title::checkUserBlock
         */
        public function testUserBlock() {
-               global $wgEmailConfirmToEdit, $wgEmailAuthentication;
-               $wgEmailConfirmToEdit = true;
-               $wgEmailAuthentication = true;
+               $this->setMwGlobals( [
+                       'wgEmailConfirmToEdit' => true,
+                       'wgEmailAuthentication' => true,
+               ] );
 
                $this->setUserPerm( [ "createpage", "move" ] );
                $this->setTitle( NS_HELP, "test page" );
 
-               # $short
-               $this->assertEquals( [ [ 'confirmedittext' ] ],
+               # $wgEmailConfirmToEdit only applies to 'edit' action
+               $this->assertEquals( [],
                        $this->title->getUserPermissionsErrors( 'move-target', $this->user ) );
-               $wgEmailConfirmToEdit = false;
-               $this->assertEquals( true, $this->title->userCan( 'move-target', $this->user ) );
+               $this->assertContains( [ 'confirmedittext' ],
+                       $this->title->getUserPermissionsErrors( 'edit', $this->user ) );
+
+               $this->setMwGlobals( 'wgEmailConfirmToEdit', false );
+               $this->assertNotContains( [ 'confirmedittext' ],
+                       $this->title->getUserPermissionsErrors( 'edit', $this->user ) );
 
                # $wgEmailConfirmToEdit && !$user->isEmailConfirmed() && $action != 'createaccount'
                $this->assertEquals( [],
index c81a078..f9ffeae 100644 (file)
@@ -1,5 +1,7 @@
 <?php
 
+use MediaWiki\MediaWikiServices;
+
 /**
  * @group Database
  * @group Title
@@ -674,7 +676,7 @@ class TitleTest extends MediaWikiTestCase {
         */
        public function testExists() {
                $title = Title::makeTitle( NS_PROJECT, 'New page' );
-               $linkCache = LinkCache::singleton();
+               $linkCache = MediaWikiServices::getInstance()->getLinkCache();
 
                $article = new Article( $title );
                $page = $article->getPage();
index 9583921..07c307e 100644 (file)
@@ -123,7 +123,13 @@ class WebRequestTest extends MediaWikiTestCase {
                ];
        }
 
-       protected function mockWebRequest( $data = [] ) {
+       /**
+        * @param array $data Request data
+        * @param array $config
+        *  - float 'requestTime': Mock value for `$_SERVER['REQUEST_TIME_FLOAT']`.
+        * @return WebRequest
+        */
+       protected function mockWebRequest( array $data = [], array $config = [] ) {
                // Cannot use PHPUnit getMockBuilder() as it does not support
                // overriding protected properties afterwards
                $reflection = new ReflectionClass( WebRequest::class );
@@ -133,9 +139,11 @@ class WebRequestTest extends MediaWikiTestCase {
                $prop->setAccessible( true );
                $prop->setValue( $req, $data );
 
-               $prop = $reflection->getProperty( 'requestTime' );
-               $prop->setAccessible( true );
-               $prop->setValue( $req, microtime( true ) );
+               if ( isset( $config['requestTime'] ) ) {
+                       $prop = $reflection->getProperty( 'requestTime' );
+                       $prop->setAccessible( true );
+                       $prop->setValue( $req, $config['requestTime'] );
+               }
 
                return $req;
        }
@@ -144,9 +152,11 @@ class WebRequestTest extends MediaWikiTestCase {
         * @covers WebRequest::getElapsedTime
         */
        public function testGetElapsedTime() {
-               $req = $this->mockWebRequest();
-               $this->assertGreaterThanOrEqual( 0.0, $req->getElapsedTime() );
-               $this->assertEquals( 0.0, $req->getElapsedTime(), '', /*delta*/ 0.2 );
+               $now = microtime( true ) - 10.0;
+               $req = $this->mockWebRequest( [], [ 'requestTime' => $now ] );
+               $this->assertGreaterThanOrEqual( 10.0, $req->getElapsedTime() );
+               // Catch common errors, but don't fail on slow hardware or VMs (T199764).
+               $this->assertEquals( 10.0, $req->getElapsedTime(), '', 60.0 );
        }
 
        /**
index e46fc67..4556473 100644 (file)
@@ -97,8 +97,8 @@ class XmlTest extends MediaWikiTestCase {
         */
        public function testElementEscaping() {
                $this->assertEquals(
-                       '<element>hello &lt;there&gt; you &amp; you</element>',
-                       Xml::element( 'element', null, 'hello <there> you & you' ),
+                       '<element>"hello &lt;there&gt; your\'s &amp; you"</element>',
+                       Xml::element( 'element', null, '"hello <there> your\'s & you"' ),
                        'Element with no attributes and content that needs escaping'
                );
        }
index b96b491..9c8b957 100644 (file)
@@ -6,7 +6,7 @@
  * @group Action
  * @group Database
  *
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
  * @author Thiemo Kreuz
  */
 class ActionTest extends MediaWikiTestCase {
diff --git a/tests/phpunit/includes/actions/WatchActionTest.php b/tests/phpunit/includes/actions/WatchActionTest.php
new file mode 100644 (file)
index 0000000..044c30a
--- /dev/null
@@ -0,0 +1,367 @@
+<?php
+
+/**
+ * @covers WatchAction
+ *
+ * @group Action
+ */
+class WatchActionTest extends MediaWikiTestCase {
+
+       /**
+        * @var WatchAction
+        */
+       private $watchAction;
+
+       /**
+        * @var WikiPage
+        */
+       private $testWikiPage;
+
+       protected function setUp() {
+               parent::setUp();
+
+               $testTitle = Title::newFromText( 'UTTest' );
+               $this->testWikiPage = new WikiPage( $testTitle );
+               $testContext = new DerivativeContext( RequestContext::getMain() );
+               $testContext->setTitle( $testTitle );
+               $this->watchAction = new WatchAction( $this->testWikiPage, $testContext );
+       }
+
+       /**
+        * @throws MWException
+        */
+       protected function tearDown() {
+               parent::tearDown();
+
+               Hooks::clear( 'WatchArticle' );
+               Hooks::clear( 'UnwatchArticle' );
+       }
+
+       /**
+        * @covers WatchAction::getName()
+        */
+       public function testGetName() {
+               $this->assertEquals( 'watch', $this->watchAction->getName() );
+       }
+
+       /**
+        * @covers WatchAction::requiresUnblock()
+        */
+       public function testRequiresUnlock() {
+               $this->assertFalse( $this->watchAction->requiresUnblock() );
+       }
+
+       /**
+        * @covers WatchAction::doesWrites()
+        */
+       public function testDoesWrites() {
+               $this->assertTrue( $this->watchAction->doesWrites() );
+       }
+
+       /**
+        * @covers WatchAction::onSubmit()
+        * @covers WatchAction::doWatch()
+        */
+       public function testOnSubmit() {
+               /** @var Status $actual */
+               $actual = $this->watchAction->onSubmit( [] );
+
+               $this->assertTrue( $actual->isGood() );
+       }
+
+       /**
+        * @covers WatchAction::onSubmit()
+        * @covers WatchAction::doWatch()
+        */
+       public function testOnSubmitHookAborted() {
+               Hooks::register( 'WatchArticle', function () {
+                       return false;
+               } );
+
+               /** @var Status $actual */
+               $actual = $this->watchAction->onSubmit( [] );
+
+               $this->assertInstanceOf( Status::class, $actual );
+               $this->assertTrue( $actual->hasMessage( 'hookaborted' ) );
+       }
+
+       /**
+        * @covers WatchAction::checkCanExecute()
+        */
+       public function testShowUserNotLoggedIn() {
+               $notLoggedInUser = new User();
+               $testContext = new DerivativeContext( $this->watchAction->getContext() );
+               $testContext->setUser( $notLoggedInUser );
+               $watchAction = new WatchAction( $this->testWikiPage, $testContext );
+               $this->setExpectedException( UserNotLoggedIn::class );
+
+               $watchAction->show();
+       }
+
+       /**
+        * @covers WatchAction::checkCanExecute()
+        */
+       public function testShowUserLoggedInNoException() {
+               $loggedInUser = $this->getMock( User::class );
+               $loggedInUser->method( 'isLoggedIn' )->willReturn( true );
+               $testContext = new DerivativeContext( $this->watchAction->getContext() );
+               $testContext->setUser( $loggedInUser );
+               $watchAction = new WatchAction( $this->testWikiPage, $testContext );
+
+               $exception = null;
+               try {
+                       $watchAction->show();
+               } catch ( UserNotLoggedIn $e ) {
+                       $exception = $e;
+               }
+               $this->assertNull( $exception,
+                       'UserNotLoggedIn exception should not be thrown if user is logged in.' );
+       }
+
+       /**
+        * @covers WatchAction::onSuccess()
+        */
+       public function testOnSuccessMainNamespaceTitle() {
+               $testContext = $this->getMock(
+                       DerivativeContext::class,
+                       [ 'msg' ],
+                       [ $this->watchAction->getContext() ]
+               );
+               $testOutput = new OutputPage( $testContext );
+               $testContext->setOutput( $testOutput );
+               $testContext->method( 'msg' )->willReturnCallback( function ( $msgKey ) {
+                       return new RawMessage( $msgKey );
+               } );
+               $watchAction = new WatchAction( $this->testWikiPage, $testContext );
+
+               $watchAction->onSuccess();
+
+               $this->assertEquals( '<p>addedwatchtext
+</p>', $testOutput->getHTML() );
+       }
+
+       /**
+        * @covers WatchAction::onSuccess()
+        */
+       public function testOnSuccessTalkPage() {
+               $testContext = $this->getMock(
+                       DerivativeContext::class,
+                       [],
+                       [ $this->watchAction->getContext() ]
+               );
+               $testOutput = new OutputPage( $testContext );
+               $testContext->method( 'getOutput' )->willReturn( $testOutput );
+               $testContext->method( 'msg' )->willReturnCallback( function ( $msgKey ) {
+                       return new RawMessage( $msgKey );
+               } );
+               $talkPageTitle = Title::newFromText( 'Talk:UTTest' );
+               $testContext->setTitle( $talkPageTitle );
+               $watchAction = new WatchAction( new WikiPage( $talkPageTitle ), $testContext );
+
+               $watchAction->onSuccess();
+
+               $this->assertEquals( '<p>addedwatchtext-talk
+</p>', $testOutput->getHTML() );
+       }
+
+       /**
+        * @covers WatchAction::doWatch()
+        */
+       public function testDoWatchNoCheckRights() {
+               $notPermittedUser = $this->getMock( User::class );
+               $notPermittedUser->method( 'isAllowed' )->willReturn( false );
+
+               $actual = WatchAction::doWatch( $this->testWikiPage->getTitle(), $notPermittedUser, false );
+
+               $this->assertTrue( $actual->isGood() );
+       }
+
+       /**
+        * @covers WatchAction::doWatch()
+        */
+       public function testDoWatchUserNotPermittedStatusNotGood() {
+               $notPermittedUser = $this->getMock( User::class );
+               $notPermittedUser->method( 'isAllowed' )->willReturn( false );
+
+               $actual = WatchAction::doWatch( $this->testWikiPage->getTitle(), $notPermittedUser, true );
+
+               $this->assertFalse( $actual->isGood() );
+       }
+
+       /**
+        * @covers WatchAction::doWatch()
+        */
+       public function testDoWatchCallsUserAddWatch() {
+               $permittedUser = $this->getMock( User::class );
+               $permittedUser->method( 'isAllowed' )->willReturn( true );
+               $permittedUser->expects( $this->once() )
+                       ->method( 'addWatch' )
+                       ->with( $this->equalTo( $this->testWikiPage->getTitle() ), $this->equalTo( true ) );
+
+               $actual = WatchAction::doWatch( $this->testWikiPage->getTitle(), $permittedUser );
+
+               $this->assertTrue( $actual->isGood() );
+       }
+
+       /**
+        * @covers WatchAction::doUnWatch()
+        */
+       public function testDoUnWatchWithoutRights() {
+               $notPermittedUser = $this->getMock( User::class );
+               $notPermittedUser->method( 'isAllowed' )->willReturn( false );
+
+               $actual = WatchAction::doUnWatch( $this->testWikiPage->getTitle(), $notPermittedUser );
+
+               $this->assertFalse( $actual->isGood() );
+       }
+
+       /**
+        * @covers WatchAction::doUnWatch()
+        */
+       public function testDoUnWatchUserHookAborted() {
+               $permittedUser = $this->getMock( User::class );
+               $permittedUser->method( 'isAllowed' )->willReturn( true );
+               Hooks::register( 'UnwatchArticle', function () {
+                       return false;
+               } );
+
+               $status = WatchAction::doUnWatch( $this->testWikiPage->getTitle(), $permittedUser );
+
+               $this->assertFalse( $status->isGood() );
+               $errors = $status->getErrors();
+               $this->assertEquals( 1, count( $errors ) );
+               $this->assertEquals( 'hookaborted', $errors[0]['message'] );
+       }
+
+       /**
+        * @covers WatchAction::doUnWatch()
+        */
+       public function testDoUnWatchCallsUserRemoveWatch() {
+               $permittedUser = $this->getMock( User::class );
+               $permittedUser->method( 'isAllowed' )->willReturn( true );
+               $permittedUser->expects( $this->once() )
+                       ->method( 'removeWatch' )
+                       ->with( $this->equalTo( $this->testWikiPage->getTitle() ) );
+
+               $actual = WatchAction::doUnWatch( $this->testWikiPage->getTitle(), $permittedUser );
+
+               $this->assertTrue( $actual->isGood() );
+       }
+
+       /**
+        * @covers WatchAction::getWatchToken()
+        */
+       public function testGetWatchTokenNormalizesToWatch() {
+               $user = $this->getMock( User::class );
+               $user->expects( $this->once() )
+                       ->method( 'getEditToken' )
+                       ->with( $this->equalTo( 'watch' ) );
+
+               WatchAction::getWatchToken( $this->watchAction->getTitle(), $user, 'INVALID_ACTION' );
+       }
+
+       /**
+        * @covers WatchAction::getWatchToken()
+        */
+       public function testGetWatchTokenProxiesUserGetEditToken() {
+               $user = $this->getMock( User::class );
+               $user->expects( $this->once() )->method( 'getEditToken' );
+
+               WatchAction::getWatchToken( $this->watchAction->getTitle(), $user );
+       }
+
+       /**
+        * @covers WatchAction::getUnwatchToken()
+        */
+       public function testGetUnwatchToken() {
+               $user = $this->getMock( User::class );
+               $user->expects( $this->once() )->method( 'getEditToken' );
+               $this->hideDeprecated( 'WatchAction::getUnwatchToken' );
+
+               WatchAction::getUnWatchToken( $this->watchAction->getTitle(), $user );
+       }
+
+       /**
+        * @covers WatchAction::doWatchOrUnwatch()
+        */
+       public function testDoWatchOrUnwatchUserNotLoggedIn() {
+               $user = $this->getLoggedInIsWatchedUser( false );
+               $user->expects( $this->never() )->method( 'removeWatch' );
+               $user->expects( $this->never() )->method( 'addWatch' );
+
+               $status = WatchAction::doWatchOrUnwatch( true, $this->watchAction->getTitle(), $user );
+
+               $this->assertTrue( $status->isGood() );
+       }
+
+       /**
+        * @covers WatchAction::doWatchOrUnwatch()
+        */
+       public function testDoWatchOrUnwatchSkipsIfAlreadyWatched() {
+               $user = $this->getLoggedInIsWatchedUser();
+               $user->expects( $this->never() )->method( 'removeWatch' );
+               $user->expects( $this->never() )->method( 'addWatch' );
+
+               $status = WatchAction::doWatchOrUnwatch( true, $this->watchAction->getTitle(), $user );
+
+               $this->assertTrue( $status->isGood() );
+       }
+
+       /**
+        * @covers WatchAction::doWatchOrUnwatch()
+        */
+       public function testDoWatchOrUnwatchSkipsIfAlreadyUnWatched() {
+               $user = $this->getLoggedInIsWatchedUser( true, false );
+               $user->expects( $this->never() )->method( 'removeWatch' );
+               $user->expects( $this->never() )->method( 'addWatch' );
+
+               $status = WatchAction::doWatchOrUnwatch( false, $this->watchAction->getTitle(), $user );
+
+               $this->assertTrue( $status->isGood() );
+       }
+
+       /**
+        * @covers WatchAction::doWatchOrUnwatch()
+        */
+       public function testDoWatchOrUnwatchWatchesIfWatch() {
+               $user = $this->getLoggedInIsWatchedUser( true, false );
+               $user->expects( $this->never() )->method( 'removeWatch' );
+               $user->expects( $this->once() )
+                       ->method( 'addWatch' )
+                       ->with( $this->equalTo( $this->testWikiPage->getTitle() ), $this->equalTo( false ) );
+
+               $status = WatchAction::doWatchOrUnwatch( true, $this->watchAction->getTitle(), $user );
+
+               $this->assertTrue( $status->isGood() );
+       }
+
+       /**
+        * @covers WatchAction::doWatchOrUnwatch()
+        */
+       public function testDoWatchOrUnwatchUnwatchesIfUnwatch() {
+               $user = $this->getLoggedInIsWatchedUser();
+               $user->method( 'isAllowed' )->willReturn( true );
+               $user->expects( $this->never() )->method( 'addWatch' );
+               $user->expects( $this->once() )
+                       ->method( 'removeWatch' )
+                       ->with( $this->equalTo( $this->testWikiPage->getTitle() ) );
+
+               $status = WatchAction::doWatchOrUnwatch( false, $this->watchAction->getTitle(), $user );
+
+               $this->assertTrue( $status->isGood() );
+       }
+
+       /**
+        * @param bool $isLoggedIn Whether the user should be "marked" as logged in
+        * @param bool $isWatched The value any call to isWatched should return
+        * @return PHPUnit_Framework_MockObject_MockObject
+        */
+       private function getLoggedInIsWatchedUser( $isLoggedIn = true, $isWatched = true ) {
+               $user = $this->getMock( User::class );
+               $user->method( 'isLoggedIn' )->willReturn( $isLoggedIn );
+               $user->method( 'isWatched' )->willReturn( $isWatched );
+
+               return $user;
+       }
+
+}
index 4e3e3fc..866848b 100644 (file)
@@ -164,10 +164,14 @@ class ApiBaseTest extends ApiTestCase {
        }
 
        public function testGetTitleOrPageIdPageId() {
+               $page = $this->getExistingTestPage();
                $result = ( new MockApi() )->getTitleOrPageId(
-                       [ 'pageid' => Title::newFromText( 'UTPage' )->getArticleId() ] );
+                       [ 'pageid' => $page->getId() ] );
                $this->assertInstanceOf( WikiPage::class, $result );
-               $this->assertSame( 'UTPage', $result->getTitle()->getPrefixedText() );
+               $this->assertSame(
+                       $page->getTitle()->getPrefixedText(),
+                       $result->getTitle()->getPrefixedText()
+               );
        }
 
        public function testGetTitleOrPageIdInvalidPageId() {
@@ -199,10 +203,11 @@ class ApiBaseTest extends ApiTestCase {
        }
 
        public function testGetTitleFromTitleOrPageIdPageId() {
+               $page = $this->getExistingTestPage();
                $result = ( new MockApi() )->getTitleFromTitleOrPageId(
-                       [ 'pageid' => Title::newFromText( 'UTPage' )->getArticleId() ] );
+                       [ 'pageid' => $page->getId() ] );
                $this->assertInstanceOf( Title::class, $result );
-               $this->assertSame( 'UTPage', $result->getPrefixedText() );
+               $this->assertSame( $page->getTitle()->getPrefixedText(), $result->getPrefixedText() );
        }
 
        public function testGetTitleFromTitleOrPageIdInvalidPageId() {
@@ -212,8 +217,45 @@ class ApiBaseTest extends ApiTestCase {
                $mock->getTitleFromTitleOrPageId( [ 'pageid' => 298401643 ] );
        }
 
+       public function testGetParameter() {
+               $mock = $this->getMockBuilder( MockApi::class )
+                       ->setMethods( [ 'getAllowedParams' ] )
+                       ->getMock();
+               $mock->method( 'getAllowedParams' )->willReturn( [
+                       'foo' => [
+                               ApiBase::PARAM_TYPE => [ 'value' ],
+                       ],
+                       'bar' => [
+                               ApiBase::PARAM_TYPE => [ 'value' ],
+                       ],
+               ] );
+               $wrapper = TestingAccessWrapper::newFromObject( $mock );
+
+               $context = new DerivativeContext( $mock );
+               $context->setRequest( new FauxRequest( [ 'foo' => 'bad', 'bar' => 'value' ] ) );
+               $wrapper->mMainModule = new ApiMain( $context );
+
+               // Even though 'foo' is bad, getParameter( 'bar' ) must not fail
+               $this->assertSame( 'value', $wrapper->getParameter( 'bar' ) );
+
+               // But getParameter( 'foo' ) must throw.
+               try {
+                       $wrapper->getParameter( 'foo' );
+                       $this->fail( 'Expected exception not thrown' );
+               } catch ( ApiUsageException $ex ) {
+                       $this->assertTrue( $this->apiExceptionHasCode( $ex, 'unknown_foo' ) );
+               }
+
+               // And extractRequestParams() must throw too.
+               try {
+                       $mock->extractRequestParams();
+                       $this->fail( 'Expected exception not thrown' );
+               } catch ( ApiUsageException $ex ) {
+                       $this->assertTrue( $this->apiExceptionHasCode( $ex, 'unknown_foo' ) );
+               }
+       }
+
        /**
-        * @dataProvider provideGetParameterFromSettings
         * @param string|null $input
         * @param array $paramSettings
         * @param mixed $expected
@@ -221,21 +263,27 @@ class ApiBaseTest extends ApiTestCase {
         *   'parseLimits': true|false
         *   'apihighlimits': true|false
         *   'internalmode': true|false
+        *   'prefix': true|false
         * @param string[] $warnings
         */
-       public function testGetParameterFromSettings(
+       private function doGetParameterFromSettings(
                $input, $paramSettings, $expected, $warnings, $options = []
        ) {
                $mock = new MockApi();
                $wrapper = TestingAccessWrapper::newFromObject( $mock );
+               if ( $options['prefix'] ) {
+                       $wrapper->mModulePrefix = 'my';
+                       $paramName = 'Param';
+               } else {
+                       $paramName = 'myParam';
+               }
 
                $context = new DerivativeContext( $mock );
                $context->setRequest( new FauxRequest(
                        $input !== null ? [ 'myParam' => $input ] : [] ) );
                $wrapper->mMainModule = new ApiMain( $context );
 
-               $parseLimits = isset( $options['parseLimits'] ) ?
-                       $options['parseLimits'] : true;
+               $parseLimits = $options['parseLimits'] ?? true;
 
                if ( !empty( $options['apihighlimits'] ) ) {
                        $context->setUser( self::$users['sysop']->getUser() );
@@ -256,14 +304,14 @@ class ApiBaseTest extends ApiTestCase {
 
                if ( $expected instanceof Exception ) {
                        try {
-                               $wrapper->getParameterFromSettings( 'myParam', $paramSettings,
+                               $wrapper->getParameterFromSettings( $paramName, $paramSettings,
                                        $parseLimits );
                                $this->fail( 'No exception thrown' );
                        } catch ( Exception $ex ) {
                                $this->assertEquals( $expected, $ex );
                        }
                } else {
-                       $result = $wrapper->getParameterFromSettings( 'myParam',
+                       $result = $wrapper->getParameterFromSettings( $paramName,
                                $paramSettings, $parseLimits );
                        if ( isset( $paramSettings[ApiBase::PARAM_TYPE] ) &&
                                $paramSettings[ApiBase::PARAM_TYPE] === 'timestamp' &&
@@ -297,6 +345,28 @@ class ApiBaseTest extends ApiTestCase {
                }
        }
 
+       /**
+        * @dataProvider provideGetParameterFromSettings
+        * @see self::doGetParameterFromSettings()
+        */
+       public function testGetParameterFromSettings_noprefix(
+               $input, $paramSettings, $expected, $warnings, $options = []
+       ) {
+               $options['prefix'] = false;
+               $this->doGetParameterFromSettings( $input, $paramSettings, $expected, $warnings, $options );
+       }
+
+       /**
+        * @dataProvider provideGetParameterFromSettings
+        * @see self::doGetParameterFromSettings()
+        */
+       public function testGetParameterFromSettings_prefix(
+               $input, $paramSettings, $expected, $warnings, $options = []
+       ) {
+               $options['prefix'] = true;
+               $this->doGetParameterFromSettings( $input, $paramSettings, $expected, $warnings, $options );
+       }
+
        public static function provideGetParameterFromSettings() {
                $warnings = [
                        [ 'apiwarn-badutf8', 'myParam' ],
@@ -1183,7 +1253,7 @@ class ApiBaseTest extends ApiTestCase {
                ];
 
                foreach ( $integerTests as $test ) {
-                       $desc = isset( $test[2] ) ? $test[2] : $test[0];
+                       $desc = $test[2] ?? $test[0];
                        $warnings = isset( $test[3] ) ?
                                [ [ 'apiwarn-badutf8', 'myParam' ] ] : [];
                        $returnArray["\"$desc\" as integer"] = [
index ea13a0d..0428335 100644 (file)
@@ -113,7 +113,7 @@ class ApiComparePagesTest extends ApiTestCase {
                                $value = self::$repl[$m[1]];
                        } else {
                                $value = preg_replace_callback( '/{{REPL:(.+?)}}/', function ( $m ) {
-                                       return isset( self::$repl[$m[1]] ) ? self::$repl[$m[1]] : $m[0];
+                                       return self::$repl[$m[1]] ?? $m[0];
                                }, $value );
                        }
                } elseif ( is_array( $value ) || is_object( $value ) ) {
index c196338..4febb46 100644 (file)
@@ -18,11 +18,12 @@ class ApiEditPageTest extends ApiTestCase {
 
                parent::setUp();
 
+               $this->setContentLang( $wgContLang );
+
                $this->setMwGlobals( [
                        'wgExtraNamespaces' => $wgExtraNamespaces,
                        'wgNamespaceContentModels' => $wgNamespaceContentModels,
                        'wgContentHandlers' => $wgContentHandlers,
-                       'wgContLang' => $wgContLang,
                ] );
 
                $wgExtraNamespaces[12312] = 'Dummy';
@@ -733,7 +734,7 @@ class ApiEditPageTest extends ApiTestCase {
                $dbw = wfGetDB( DB_MASTER );
                $dbw->update(
                        'revision',
-                       [ 'rev_timestamp' => wfTimestamp( TS_MW, time() - 86400 ) ],
+                       [ 'rev_timestamp' => $dbw->timestamp( time() - 86400 ) ],
                        [ 'rev_id' => $revId1 ],
                        __METHOD__
                );
index d17334b..20d758e 100644 (file)
@@ -434,6 +434,35 @@ class ApiMainTest extends ApiTestCase {
                }
        }
 
+       /**
+        * Test that 'assert' is processed before module errors
+        */
+       public function testAssertBeforeModule() {
+               // Sanity check that the query without assert throws too-many-titles
+               try {
+                       $this->doApiRequest( [
+                               'action' => 'query',
+                               'titles' => implode( '|', range( 1, ApiBase::LIMIT_SML1 + 1 ) ),
+                       ], null, null, new User );
+                       $this->fail( 'Expected exception not thrown' );
+               } catch ( ApiUsageException $e ) {
+                       $this->assertTrue( self::apiExceptionHasCode( $e, 'too-many-titles' ), 'sanity check' );
+               }
+
+               // Now test that the assert happens first
+               try {
+                       $this->doApiRequest( [
+                               'action' => 'query',
+                               'titles' => implode( '|', range( 1, ApiBase::LIMIT_SML1 + 1 ) ),
+                               'assert' => 'user',
+                       ], null, null, new User );
+                       $this->fail( 'Expected exception not thrown' );
+               } catch ( ApiUsageException $e ) {
+                       $this->assertTrue( self::apiExceptionHasCode( $e, 'assertuserfailed' ),
+                               "Error '{$e->getMessage()}' matched expected 'assertuserfailed'" );
+               }
+       }
+
        /**
         * Test if all classes in the main module manager exists
         */
@@ -491,7 +520,7 @@ class ApiMainTest extends ApiTestCase {
                $module->expects( $this->any() )
                        ->method( 'getConditionalRequestData' )
                        ->will( $this->returnCallback( function ( $condition ) use ( $conditions ) {
-                               return isset( $conditions[$condition] ) ? $conditions[$condition] : null;
+                               return $conditions[$condition] ?? null;
                        } ) );
 
                $ret = $priv->checkConditionalRequestHeaders( $module );
@@ -622,7 +651,7 @@ class ApiMainTest extends ApiTestCase {
                $module->expects( $this->any() )
                        ->method( 'getConditionalRequestData' )
                        ->will( $this->returnCallback( function ( $condition ) use ( $conditions ) {
-                               return isset( $conditions[$condition] ) ? $conditions[$condition] : null;
+                               return $conditions[$condition] ?? null;
                        } ) );
                $priv->mModule = $module;
 
@@ -630,7 +659,7 @@ class ApiMainTest extends ApiTestCase {
 
                foreach ( [ 'Last-Modified', 'ETag' ] as $header ) {
                        $this->assertEquals(
-                               isset( $headers[$header] ) ? $headers[$header] : null,
+                               $headers[$header] ?? null,
                                $response->getHeader( $header ),
                                $header
                        );
@@ -938,8 +967,7 @@ class ApiMainTest extends ApiTestCase {
                $context->setLanguage( 'en' );
                $context->setConfig( new MultiConfig( [
                        new HashConfig( [
-                               'ShowHostnames' => true, 'ShowSQLErrors' => false,
-                               'ShowExceptionDetails' => true, 'ShowDBErrorBacktrace' => true,
+                               'ShowHostnames' => true, 'ShowExceptionDetails' => true,
                        ] ),
                        $context->getConfig()
                ] ) );
@@ -1023,7 +1051,8 @@ class ApiMainTest extends ApiTestCase {
                                                [ 'code' => 'existing-error', 'text' => 'existing error', 'module' => 'main' ],
                                                [
                                                        'code' => 'internal_api_error_DBQueryError',
-                                                       'text' => "[$reqId] Database query error.",
+                                                       'text' => "[$reqId] Exception caught: A database query error has occurred. " .
+                                                               "This may indicate a bug in the software.",
                                                ]
                                        ],
                                        'trace' => $dbtrace,
@@ -1069,4 +1098,21 @@ class ApiMainTest extends ApiTestCase {
                        ],
                ];
        }
+
+       public function testPrinterParameterValidationError() {
+               $api = $this->getNonInternalApiMain( [
+                       'action' => 'query', 'meta' => 'siteinfo', 'format' => 'json', 'formatversion' => 'bogus',
+               ] );
+
+               ob_start();
+               $api->execute();
+               $txt = ob_get_clean();
+
+               // Test that the actual output is valid JSON, not just the format of the ApiResult.
+               $data = FormatJson::decode( $txt, true );
+               $this->assertInternalType( 'array', $data );
+               $this->assertArrayHasKey( 'error', $data );
+               $this->assertArrayHasKey( 'code', $data['error'] );
+               $this->assertSame( 'unknown_formatversion', $data['error']['code'] );
+       }
 }
index c0fecf0..29c7dae 100644 (file)
@@ -40,6 +40,10 @@ class ApiOptionsTest extends MediaWikiLangTestCase {
                $this->mUserMock->expects( $this->any() )
                        ->method( 'getInstanceForUpdate' )->will( $this->returnValue( $this->mUserMock ) );
 
+               // Needs to return something
+               $this->mUserMock->method( 'getOptions' )
+                       ->willReturn( [] );
+
                // Create a new context
                $this->mContext = new DerivativeContext( new RequestContext() );
                $this->mContext->getContext()->setTitle( Title::newFromText( 'Test' ) );
@@ -66,7 +70,7 @@ class ApiOptionsTest extends MediaWikiLangTestCase {
                        $preferences[$k] = [
                                'type' => 'text',
                                'section' => 'test',
-                               'label' => '&#160;',
+                               'label' => "\u{00A0}",
                        ];
                }
 
@@ -81,7 +85,7 @@ class ApiOptionsTest extends MediaWikiLangTestCase {
                                ],
                        ],
                        'section' => 'test',
-                       'label' => '&#160;',
+                       'label' => "\u{00A0}",
                        'prefix' => 'testmultiselect-',
                        'default' => [],
                ];
diff --git a/tests/phpunit/includes/api/ApiQueryPrefixSearchTest.php b/tests/phpunit/includes/api/ApiQueryPrefixSearchTest.php
new file mode 100644 (file)
index 0000000..749f154
--- /dev/null
@@ -0,0 +1,58 @@
+<?php
+
+/**
+ * @group API
+ * @group medium
+ *
+ * @covers ApiQueryPrefixSearch
+ */
+class ApiQueryPrefixSearchTest extends ApiTestCase {
+       const TEST_QUERY = 'unittest';
+
+       public function setUp() {
+               parent::setUp();
+               $this->setMwGlobals( [
+                       'wgSearchType' => MockCompletionSearchEngine::class,
+               ] );
+               MockCompletionSearchEngine::clearMockResults();
+               $results = [];
+               foreach ( range( 0, 10 ) as $i ) {
+                       $title = "Search_Result_$i";
+                       $results[] = $title;
+                       $this->editPage( $title, 'hi there' );
+               }
+               MockCompletionSearchEngine::addMockResults( self::TEST_QUERY, $results );
+       }
+
+       public function offsetContinueProvider() {
+               return [
+                       'no offset' => [ 2, 2, 0, 2 ],
+                       'with offset' => [ 7, 2, 5, 2 ],
+                       'past end, no offset' => [ null, 11, 0, 20 ],
+                       'past end, with offset' => [ null, 5, 6, 10 ],
+               ];
+       }
+
+       /**
+        * @dataProvider offsetContinueProvider
+        */
+       public function testOffsetContinue( $expectedOffset, $expectedResults, $offset, $limit ) {
+               $response = $this->doApiRequest( [
+                       'action' => 'query',
+                       'list' => 'prefixsearch',
+                       'pssearch' => self::TEST_QUERY,
+                       'psoffset' => $offset,
+                       'pslimit' => $limit,
+               ] );
+               $result = $response[0];
+               $this->assertArrayNotHasKey( 'warnings', $result );
+               $suggestions = $result['query']['prefixsearch'];
+               $this->assertCount( $expectedResults, $suggestions );
+               if ( $expectedOffset == null ) {
+                       $this->assertArrayNotHasKey( 'continue', $result );
+               } else {
+                       $this->assertArrayHasKey( 'continue', $result );
+                       $this->assertEquals( $expectedOffset, $result['continue']['psoffset'] );
+               }
+       }
+}
index 5b43dd1..a95d5c1 100644 (file)
@@ -863,6 +863,65 @@ class ApiQueryRecentChangesIntegrationTest extends ApiTestCase {
                );
        }
 
+       public function testTitleParams() {
+               $page1 = new TitleValue( 0, 'ApiQueryRecentChangesIntegrationTestPage' );
+               $page2 = new TitleValue( 1, 'ApiQueryRecentChangesIntegrationTestPage2' );
+               $page3 = new TitleValue( 0, 'ApiQueryRecentChangesIntegrationTestPage3' );
+               $this->doPageEdits(
+                       $this->getLoggedInTestUser(),
+                       [
+                               [
+                                       'target' => $page1,
+                                       'summary' => 'Create the page',
+                               ],
+                               [
+                                       'target' => $page2,
+                                       'summary' => 'Create the page',
+                               ],
+                               [
+                                       'target' => $page3,
+                                       'summary' => 'Create the page',
+                               ],
+                       ]
+               );
+
+               $result = $this->doListRecentChangesRequest(
+                       [
+                               'rctitle' => 'ApiQueryRecentChangesIntegrationTestPage',
+                               'rcprop' => 'title'
+                       ]
+               );
+
+               $result2 = $this->doListRecentChangesRequest(
+                       [
+                               'rctitle' => 'Talk:ApiQueryRecentChangesIntegrationTestPage2',
+                               'rcprop' => 'title'
+                       ]
+               );
+
+               $this->assertEquals(
+                       [
+                               [
+                                       'type' => 'new',
+                                       'ns' => $page1->getNamespace(),
+                                       'title' => $this->getPrefixedText( $page1 )
+                               ],
+                       ],
+                       $this->getItemsFromApiResponse( $result )
+               );
+
+               $this->assertEquals(
+                       [
+                               [
+                                       'type' => 'new',
+                                       'ns' => $page2->getNamespace(),
+                                       'title' => $this->getPrefixedText( $page2 )
+                               ],
+                       ],
+                       $this->getItemsFromApiResponse( $result2 )
+               );
+       }
+
        public function testStartEndParams() {
                $target = new TitleValue( 0, 'ApiQueryRecentChangesIntegrationTestPage' );
                $this->doPageEdit( $this->getLoggedInTestUser(), $target, 'Create the page' );
diff --git a/tests/phpunit/includes/api/ApiQuerySearchTest.php b/tests/phpunit/includes/api/ApiQuerySearchTest.php
new file mode 100644 (file)
index 0000000..0700cf7
--- /dev/null
@@ -0,0 +1,109 @@
+<?php
+
+/**
+ * @group medium
+ * @covers ApiQuerySearch
+ */
+class ApiQuerySearchTest extends ApiTestCase {
+       public function provideSearchResults() {
+               return [
+                       'empty search result' => [ [], [] ],
+                       'has search results' => [
+                               [ 'Zomg' ],
+                               [ $this->mockResult( 'Zomg' ) ],
+                       ],
+                       'filters broken search results' => [
+                               [ 'A', 'B' ],
+                               [
+                                       $this->mockResult( 'a' ),
+                                       $this->mockResult( 'Zomg' )->setBrokenTitle( true ),
+                                       $this->mockResult( 'b' ),
+                               ],
+                       ],
+                       'filters results with missing revision' => [
+                               [ 'B', 'A' ],
+                               [
+                                       $this->mockResult( 'Zomg' )->setMissingRevision( true ),
+                                       $this->mockResult( 'b' ),
+                                       $this->mockResult( 'a' ),
+                               ],
+                       ],
+               ];
+       }
+
+       /**
+        * @dataProvider provideSearchResults
+        */
+       public function testSearchResults( $expect, $hits, array $params = [] ) {
+               MockSearchEngine::addMockResults( 'my query', $hits );
+               list( $response, $request ) = $this->doApiRequest( $params + [
+                       'action' => 'query',
+                       'list' => 'search',
+                       'srsearch' => 'my query',
+               ] );
+               $titles = [];
+               foreach ( $response['query']['search'] as $result ) {
+                       $titles[] = $result['title'];
+               }
+               $this->assertEquals( $expect, $titles );
+       }
+
+       public function provideInterwikiResults() {
+               return [
+                       'empty' => [ [], [] ],
+                       'one wiki response' => [
+                               [ 'utwiki' => [ 'Qwerty' ] ],
+                               [
+                                       SearchResultSet::SECONDARY_RESULTS => [
+                                               'utwiki' => new MockSearchResultSet( [
+                                                       $this->mockResult( 'Qwerty' )->setInterwikiPrefix( 'utwiki' ),
+                                               ] ),
+                                       ],
+                               ]
+                       ],
+               ];
+       }
+
+       /**
+        * @dataProvider provideInterwikiResults
+        */
+       public function testInterwikiResults( $expect, $hits, array $params = [] ) {
+               MockSearchEngine::setMockInterwikiResults( $hits );
+               list( $response, $request ) = $this->doApiRequest( $params + [
+                       'action' => 'query',
+                       'list' => 'search',
+                       'srsearch' => 'my query',
+                       'srinterwiki' => true,
+               ] );
+               if ( !$expect ) {
+                       $this->assertArrayNotHasKey( 'interwikisearch', $response['query'] );
+                       return;
+               }
+               $results = [];
+               $this->assertArrayHasKey( 'interwikisearchinfo', $response['query'] );
+               foreach ( $response['query']['interwikisearch'] as $wiki => $wikiResults ) {
+                       $results[$wiki] = [];
+                       foreach ( $wikiResults as $wikiResult ) {
+                               $results[$wiki][] = $wikiResult['title'];
+                       }
+               }
+               $this->assertEquals( $expect, $results );
+       }
+
+       public function setUp() {
+               parent::setUp();
+               MockSearchEngine::clearMockResults();
+               $this->registerMockSearchEngine();
+       }
+
+       private function registerMockSearchEngine() {
+               $this->setMwGlobals( [
+                       'wgSearchType' => MockSearchEngine::class,
+               ] );
+       }
+
+       private function mockResult( $title ) {
+               return MockSearchResult::newFromtitle( Title::newFromText( $title ) );
+       }
+
+}
index 5f59d6f..6532635 100644 (file)
@@ -89,17 +89,14 @@ class ApiQueryWatchlistIntegrationTest extends ApiTestCase {
                User $patrollingUser
        ) {
                $title = Title::newFromLinkTarget( $target );
+               $summary = CommentStoreComment::newUnsavedComment( trim( $summary ) );
                $page = WikiPage::factory( $title );
-               $status = $page->doEditContent(
-                       ContentHandler::makeContent( $content, $title ),
-                       $summary,
-                       0,
-                       false,
-                       $user
-               );
-               /** @var Revision $rev */
-               $rev = $status->value['revision'];
-               $rc = $rev->getRecentChange();
+
+               $updater = $page->newPageUpdater( $user );
+               $updater->setContent( 'main', ContentHandler::makeContent( $content, $title ) );
+               $rev = $updater->saveRevision( $summary );
+
+               $rc = MediaWikiServices::getInstance()->getRevisionStore()->getRecentChange( $rev );
                $rc->doMarkPatrolled( $patrollingUser, false, [] );
        }
 
index a5ee7dd..0fce35a 100644 (file)
@@ -41,43 +41,6 @@ abstract class ApiTestCase extends MediaWikiLangTestCase {
                parent::tearDown();
        }
 
-       /**
-        * Edits or creates a page/revision
-        * @param string $pageName Page title
-        * @param string $text Content of the page
-        * @param string $summary Optional summary string for the revision
-        * @param int $defaultNs Optional namespace id
-        * @return array Array as returned by WikiPage::doEditContent()
-        */
-       protected function editPage( $pageName, $text, $summary = '', $defaultNs = NS_MAIN ) {
-               $title = Title::newFromText( $pageName, $defaultNs );
-               $page = WikiPage::factory( $title );
-
-               return $page->doEditContent( ContentHandler::makeContent( $text, $title ), $summary );
-       }
-
-       /**
-        * Revision-deletes a revision.
-        *
-        * @param Revision|int $rev Revision to delete
-        * @param array $value Keys are Revision::DELETED_* flags.  Values are 1 to set the bit, 0 to
-        *   clear, -1 to leave alone.  (All other values also clear the bit.)
-        * @param string $comment Deletion comment
-        */
-       protected function revisionDelete(
-               $rev, array $value = [ Revision::DELETED_TEXT => 1 ], $comment = ''
-       ) {
-               if ( is_int( $rev ) ) {
-                       $rev = Revision::newFromId( $rev );
-               }
-               RevisionDeleter::createList(
-                       'revision', RequestContext::getMain(), $rev->getTitle(), [ $rev->getId() ]
-               )->setVisibility( [
-                       'value' => $value,
-                       'comment' => $comment,
-               ] );
-       }
-
        /**
         * Does the API request and returns the result.
         *
index 50a59f9..75e73be 100644 (file)
@@ -105,7 +105,7 @@ class RandomImageGenerator {
         *
         * @param int $number Number of filenames to write
         * @param string $format Optional, must be understood by ImageMagick, such as 'jpg' or 'gif'
-        * @param string $dir Directory, optional (will default to current working directory)
+        * @param string|null $dir Directory, optional (will default to current working directory)
         * @return array Filenames we just wrote
         */
        function writeImages( $number, $format = 'jpg', $dir = null ) {
@@ -187,7 +187,7 @@ class RandomImageGenerator {
                $spec['height'] = mt_rand( $this->minHeight, $this->maxHeight );
                $spec['fill'] = $this->getRandomColor();
 
-               $diagonalLength = sqrt( pow( $spec['width'], 2 ) + pow( $spec['height'], 2 ) );
+               $diagonalLength = sqrt( $spec['width'] ** 2 + $spec['height'] ** 2 );
 
                $draws = [];
                for ( $i = 0; $i <= $this->shapesToDraw; $i++ ) {
index 55f760f..03359f8 100644 (file)
@@ -10,6 +10,13 @@ class ApiFormatBaseTest extends ApiFormatTestBase {
 
        protected $printerName = 'mockbase';
 
+       protected function setUp() {
+               parent::setUp();
+               $this->setMwGlobals( [
+                       'wgServer' => 'http://example.org'
+               ] );
+       }
+
        public function getMockFormatter( ApiMain $main = null, $format, $methods = [] ) {
                if ( $main === null ) {
                        $context = new RequestContext;
@@ -59,7 +66,7 @@ class ApiFormatBaseTest extends ApiFormatTestBase {
                if ( $options['name'] !== 'mockfm' ) {
                        $ct = 'text/x-mock';
                        $file = 'api-result.mock';
-                       $status = isset( $options['status'] ) ? $options['status'] : null;
+                       $status = $options['status'] ?? null;
                } elseif ( isset( $params['wrappedhtml'] ) ) {
                        $ct = 'text/mediawiki-api-prettyprint-wrapped';
                        $file = 'api-result-wrapped.json';
@@ -352,7 +359,7 @@ class ApiFormatBaseTest extends ApiFormatTestBase {
        public function testHtmlHeader( $post, $registerNonHtml, $expect ) {
                $context = new RequestContext;
                $request = new FauxRequest( [ 'a' => 1, 'b' => 2 ], $post );
-               $request->setRequestURL( 'http://example.org/wx/api.php' );
+               $request->setRequestURL( '/wx/api.php' );
                $context->setRequest( $request );
                $context->setLanguage( 'qqx' );
                $main = new ApiMain( $context );
index 4169dab..ca20cb6 100644 (file)
@@ -37,13 +37,13 @@ abstract class ApiFormatTestBase extends MediaWikiTestCase {
                if ( is_string( $options ) ) {
                        $options = [ 'class' => $options ];
                }
-               $printerName = isset( $options['name'] ) ? $options['name'] : $this->printerName;
+               $printerName = $options['name'] ?? $this->printerName;
 
                $context = new RequestContext;
                $context->setRequest( new FauxRequest( $params, true ) );
                $main = new ApiMain( $context );
                if ( isset( $options['class'] ) ) {
-                       $factory = isset( $options['factory'] ) ? $options['factory'] : null;
+                       $factory = $options['factory'] ?? null;
                        $main->getModuleManager()->addModule( $printerName, 'format', $options['class'], $factory );
                }
                $result = $main->getResult();
index 915fb5c..4438332 100644 (file)
@@ -109,7 +109,7 @@ class ApiFormatXmlTest extends ApiFormatTestBase {
                                [ 'xslt' => 'DoesNotExist' ] ],
                        [ [], '<?xml version="1.0"?><api><warnings><xml xml:space="preserve">Stylesheet should be in the MediaWiki namespace.</xml></warnings></api>',
                                [ 'xslt' => 'ApiFormatXmlTest' ] ],
-                       [ [], '<?xml version="1.0"?><api><warnings><xml xml:space="preserve">Stylesheet should have &quot;.xsl&quot; extension.</xml></warnings></api>',
+                       [ [], '<?xml version="1.0"?><api><warnings><xml xml:space="preserve">Stylesheet should have ".xsl" extension.</xml></warnings></api>',
                                [ 'xslt' => 'MediaWiki:ApiFormatXmlTest' ] ],
                        [ [],
                                '<?xml version="1.0"?><?xml-stylesheet href="' .
index d4a5acf..9e7ef99 100644 (file)
@@ -30,7 +30,7 @@ class GenerateRandomImages extends Maintenance {
                ];
                $options = getopt( null, $getOptSpec );
 
-               $format = isset( $options['format'] ) ? $options['format'] : 'jpg';
+               $format = $options['format'] ?? 'jpg';
                unset( $options['format'] );
 
                $number = isset( $options['number'] ) ? intval( $options['number'] ) : 10;
index 38a1d68..1ed5e95 100644 (file)
@@ -26,16 +26,19 @@ class ApiQueryRevisionsTest extends ApiTestCase {
                        'prop' => 'revisions',
                        'titles' => $pageName,
                        'rvprop' => 'content',
+                       'rvslots' => 'main',
                ] );
                $this->assertArrayHasKey( 'query', $apiResult[0] );
                $this->assertArrayHasKey( 'pages', $apiResult[0]['query'] );
                foreach ( $apiResult[0]['query']['pages'] as $page ) {
                        $this->assertArrayHasKey( 'revisions', $page );
                        foreach ( $page['revisions'] as $revision ) {
-                               $this->assertArrayHasKey( 'contentformat', $revision,
+                               $this->assertArrayHasKey( 'slots', $revision );
+                               $this->assertArrayHasKey( 'main', $revision['slots'] );
+                               $this->assertArrayHasKey( 'contentformat', $revision['slots']['main'],
                                        'contentformat should be included when asking content so client knows how to interpret it'
                                );
-                               $this->assertArrayHasKey( 'contentmodel', $revision,
+                               $this->assertArrayHasKey( 'contentmodel', $revision['slots']['main'],
                                        'contentmodel should be included when asking content so client knows how to interpret it'
                                );
                        }
index e7588cb..08af755 100644 (file)
@@ -87,9 +87,9 @@ STR;
         * Checks that the request's result matches the expected results.
         * Assumes no rawcontinue and a complete batch.
         * @param array $values Array is a two element array( request, expected_results )
-        * @param array $session
+        * @param array|null $session
         * @param bool $appendModule
-        * @param User $user
+        * @param User|null $user
         */
        protected function check( $values, array $session = null,
                $appendModule = false, User $user = null
diff --git a/tests/phpunit/includes/api/query/ApiQueryUserContribsTest.php b/tests/phpunit/includes/api/query/ApiQueryUserContribsTest.php
new file mode 100644 (file)
index 0000000..82f3b92
--- /dev/null
@@ -0,0 +1,194 @@
+<?php
+
+/**
+ * @group API
+ * @group Database
+ * @group medium
+ * @covers ApiQueryUserContribs
+ */
+class ApiQueryUserContribsTest extends ApiTestCase {
+       public function addDBDataOnce() {
+               global $wgActorTableSchemaMigrationStage;
+
+               $reset = new \Wikimedia\ScopedCallback( function ( $v ) {
+                       global $wgActorTableSchemaMigrationStage;
+                       $wgActorTableSchemaMigrationStage = $v;
+                       $this->overrideMwServices();
+               }, [ $wgActorTableSchemaMigrationStage ] );
+               $wgActorTableSchemaMigrationStage = MIGRATION_WRITE_BOTH;
+               $this->overrideMwServices();
+
+               $users = [
+                       User::newFromName( '192.168.2.2', false ),
+                       User::newFromName( '192.168.2.1', false ),
+                       User::newFromName( '192.168.2.3', false ),
+                       User::createNew( __CLASS__ . ' B' ),
+                       User::createNew( __CLASS__ . ' A' ),
+                       User::createNew( __CLASS__ . ' C' ),
+                       User::newFromName( 'IW>' . __CLASS__, false ),
+               ];
+
+               $title = Title::newFromText( __CLASS__ );
+               $page = WikiPage::factory( $title );
+               for ( $i = 0; $i < 3; $i++ ) {
+                       foreach ( array_reverse( $users ) as $user ) {
+                               $status = $page->doEditContent(
+                                       ContentHandler::makeContent( "Test revision $user #$i", $title ), 'Test edit', 0, false, $user
+                               );
+                               if ( !$status->isOK() ) {
+                                       $this->fail( "Failed to edit $title: " . $status->getWikiText( false, false, 'en' ) );
+                               }
+                       }
+               }
+       }
+
+       /**
+        * @dataProvider provideSorting
+        * @param int $stage One of the MIGRATION_* constants for $wgActorTableSchemaMigrationStage
+        * @param array $params Extra parameters for the query
+        * @param bool $reverse Reverse order?
+        * @param int $revs Number of revisions to expect
+        */
+       public function testSorting( $stage, $params, $reverse, $revs ) {
+               if ( isset( $params['ucuserprefix'] ) &&
+                       ( $stage === MIGRATION_WRITE_BOTH || $stage === MIGRATION_WRITE_NEW ) &&
+                       $this->db->getType() === 'mysql' && $this->usesTemporaryTables()
+               ) {
+                       // https://bugs.mysql.com/bug.php?id=10327
+                       $this->markTestSkipped( 'MySQL bug 10327 - can\'t reopen temporary tables' );
+               }
+
+               $this->setMwGlobals( 'wgActorTableSchemaMigrationStage', $stage );
+               $this->overrideMwServices();
+
+               if ( isset( $params['ucuserids'] ) ) {
+                       $params['ucuserids'] = implode( '|', array_map( 'User::idFromName', $params['ucuserids'] ) );
+               }
+               if ( isset( $params['ucuser'] ) ) {
+                       $params['ucuser'] = implode( '|', $params['ucuser'] );
+               }
+
+               $sort = 'rsort';
+               if ( $reverse ) {
+                       $params['ucdir'] = 'newer';
+                       $sort = 'sort';
+               }
+
+               $params += [
+                       'action' => 'query',
+                       'list' => 'usercontribs',
+                       'ucprop' => 'ids',
+               ];
+
+               $apiResult = $this->doApiRequest( $params + [ 'uclimit' => 500 ] );
+               $this->assertArrayNotHasKey( 'continue', $apiResult[0] );
+               $this->assertArrayHasKey( 'query', $apiResult[0] );
+               $this->assertArrayHasKey( 'usercontribs', $apiResult[0]['query'] );
+
+               $count = 0;
+               $ids = [];
+               foreach ( $apiResult[0]['query']['usercontribs'] as $page ) {
+                       $count++;
+                       $ids[$page['user']][] = $page['revid'];
+               }
+               $this->assertSame( $revs, $count, 'Expected number of revisions' );
+               foreach ( $ids as $user => $revids ) {
+                       $sorted = $revids;
+                       call_user_func_array( $sort, [ &$sorted ] );
+                       $this->assertSame( $sorted, $revids, "IDs for $user are sorted" );
+               }
+
+               for ( $limit = 1; $limit < $revs; $limit++ ) {
+                       $continue = [];
+                       $count = 0;
+                       $batchedIds = [];
+                       while ( $continue !== null ) {
+                               $apiResult = $this->doApiRequest( $params + [ 'uclimit' => $limit ] + $continue );
+                               $this->assertArrayHasKey( 'query', $apiResult[0], "Batching with limit $limit" );
+                               $this->assertArrayHasKey( 'usercontribs', $apiResult[0]['query'],
+                                       "Batching with limit $limit" );
+                               $continue = $apiResult[0]['continue'] ?? null;
+                               foreach ( $apiResult[0]['query']['usercontribs'] as $page ) {
+                                       $count++;
+                                       $batchedIds[$page['user']][] = $page['revid'];
+                               }
+                               $this->assertLessThanOrEqual( $revs, $count, "Batching with limit $limit" );
+                       }
+                       $this->assertSame( $ids, $batchedIds, "Result set is the same when batching with limit $limit" );
+               }
+       }
+
+       public static function provideSorting() {
+               $users = [ __CLASS__ . ' A', __CLASS__ . ' B', __CLASS__ . ' C' ];
+               $users2 = [ __CLASS__ . ' A', __CLASS__ . ' B', __CLASS__ . ' D' ];
+               $ips = [ '192.168.2.1', '192.168.2.2', '192.168.2.3', '192.168.2.4' ];
+
+               foreach (
+                       [
+                               'old' => MIGRATION_OLD,
+                               'write both' => MIGRATION_WRITE_BOTH,
+                               'write new' => MIGRATION_WRITE_NEW,
+                               'new' => MIGRATION_NEW,
+                       ] as $stageName => $stage
+               ) {
+                       foreach ( [ false, true ] as $reverse ) {
+                               $name = $stageName . ( $reverse ? ', reverse' : '' );
+                               yield "Named users, $name" => [ $stage, [ 'ucuser' => $users ], $reverse, 9 ];
+                               yield "Named users including a no-edit user, $name" => [
+                                       $stage, [ 'ucuser' => $users2 ], $reverse, 6
+                               ];
+                               yield "IP users, $name" => [ $stage, [ 'ucuser' => $ips ], $reverse, 9 ];
+                               yield "All users, $name" => [
+                                       $stage, [ 'ucuser' => array_merge( $users, $ips ) ], $reverse, 18
+                               ];
+                               yield "User IDs, $name" => [ $stage, [ 'ucuserids' => $users ], $reverse, 9 ];
+                               yield "Users by prefix, $name" => [ $stage, [ 'ucuserprefix' => __CLASS__ ], $reverse, 9 ];
+                               yield "IPs by prefix, $name" => [ $stage, [ 'ucuserprefix' => '192.168.2.' ], $reverse, 9 ];
+                       }
+               }
+       }
+
+       /**
+        * @dataProvider provideInterwikiUser
+        * @param int $stage One of the MIGRATION_* constants for $wgActorTableSchemaMigrationStage
+        */
+       public function testInterwikiUser( $stage ) {
+               $this->setMwGlobals( 'wgActorTableSchemaMigrationStage', $stage );
+               $this->overrideMwServices();
+
+               $params = [
+                       'action' => 'query',
+                       'list' => 'usercontribs',
+                       'ucuser' => 'IW>' . __CLASS__,
+                       'ucprop' => 'ids',
+                       'uclimit' => 'max',
+               ];
+
+               $apiResult = $this->doApiRequest( $params );
+               $this->assertArrayNotHasKey( 'continue', $apiResult[0] );
+               $this->assertArrayHasKey( 'query', $apiResult[0] );
+               $this->assertArrayHasKey( 'usercontribs', $apiResult[0]['query'] );
+
+               $count = 0;
+               $ids = [];
+               foreach ( $apiResult[0]['query']['usercontribs'] as $page ) {
+                       $count++;
+                       $this->assertSame( 'IW>' . __CLASS__, $page['user'], 'Correct user returned' );
+                       $ids[] = $page['revid'];
+               }
+               $this->assertSame( 3, $count, 'Expected number of revisions' );
+               $sorted = $ids;
+               rsort( $sorted );
+               $this->assertSame( $sorted, $ids, "IDs are sorted" );
+       }
+
+       public static function provideInterwikiUser() {
+               return [
+                       'old' => [ MIGRATION_OLD ],
+                       'write both' => [ MIGRATION_WRITE_BOTH ],
+                       'write new' => [ MIGRATION_WRITE_NEW ],
+                       'new' => [ MIGRATION_NEW ],
+               ];
+       }
+
+}
diff --git a/tests/phpunit/includes/api/query/ApiQueryUserContributionsTest.php b/tests/phpunit/includes/api/query/ApiQueryUserContributionsTest.php
deleted file mode 100644 (file)
index ca6a929..0000000
+++ /dev/null
@@ -1,194 +0,0 @@
-<?php
-
-/**
- * @group API
- * @group Database
- * @group medium
- * @covers ApiQueryContributions
- */
-class ApiQueryContributionsTest extends ApiTestCase {
-       public function addDBDataOnce() {
-               global $wgActorTableSchemaMigrationStage;
-
-               $reset = new \Wikimedia\ScopedCallback( function ( $v ) {
-                       global $wgActorTableSchemaMigrationStage;
-                       $wgActorTableSchemaMigrationStage = $v;
-                       $this->overrideMwServices();
-               }, [ $wgActorTableSchemaMigrationStage ] );
-               $wgActorTableSchemaMigrationStage = MIGRATION_WRITE_BOTH;
-               $this->overrideMwServices();
-
-               $users = [
-                       User::newFromName( '192.168.2.2', false ),
-                       User::newFromName( '192.168.2.1', false ),
-                       User::newFromName( '192.168.2.3', false ),
-                       User::createNew( __CLASS__ . ' B' ),
-                       User::createNew( __CLASS__ . ' A' ),
-                       User::createNew( __CLASS__ . ' C' ),
-                       User::newFromName( 'IW>' . __CLASS__, false ),
-               ];
-
-               $title = Title::newFromText( __CLASS__ );
-               $page = WikiPage::factory( $title );
-               for ( $i = 0; $i < 3; $i++ ) {
-                       foreach ( array_reverse( $users ) as $user ) {
-                               $status = $page->doEditContent(
-                                       ContentHandler::makeContent( "Test revision $user #$i", $title ), 'Test edit', 0, false, $user
-                               );
-                               if ( !$status->isOK() ) {
-                                       $this->fail( "Failed to edit $title: " . $status->getWikiText( false, false, 'en' ) );
-                               }
-                       }
-               }
-       }
-
-       /**
-        * @dataProvider provideSorting
-        * @param int $stage One of the MIGRATION_* constants for $wgActorTableSchemaMigrationStage
-        * @param array $params Extra parameters for the query
-        * @param bool $reverse Reverse order?
-        * @param int $revs Number of revisions to expect
-        */
-       public function testSorting( $stage, $params, $reverse, $revs ) {
-               if ( isset( $params['ucuserprefix'] ) &&
-                       ( $stage === MIGRATION_WRITE_BOTH || $stage === MIGRATION_WRITE_NEW ) &&
-                       $this->db->getType() === 'mysql' && $this->usesTemporaryTables()
-               ) {
-                       // https://bugs.mysql.com/bug.php?id=10327
-                       $this->markTestSkipped( 'MySQL bug 10327 - can\'t reopen temporary tables' );
-               }
-
-               $this->setMwGlobals( 'wgActorTableSchemaMigrationStage', $stage );
-               $this->overrideMwServices();
-
-               if ( isset( $params['ucuserids'] ) ) {
-                       $params['ucuserids'] = implode( '|', array_map( 'User::idFromName', $params['ucuserids'] ) );
-               }
-               if ( isset( $params['ucuser'] ) ) {
-                       $params['ucuser'] = implode( '|', $params['ucuser'] );
-               }
-
-               $sort = 'rsort';
-               if ( $reverse ) {
-                       $params['ucdir'] = 'newer';
-                       $sort = 'sort';
-               }
-
-               $params += [
-                       'action' => 'query',
-                       'list' => 'usercontribs',
-                       'ucprop' => 'ids',
-               ];
-
-               $apiResult = $this->doApiRequest( $params + [ 'uclimit' => 500 ] );
-               $this->assertArrayNotHasKey( 'continue', $apiResult[0] );
-               $this->assertArrayHasKey( 'query', $apiResult[0] );
-               $this->assertArrayHasKey( 'usercontribs', $apiResult[0]['query'] );
-
-               $count = 0;
-               $ids = [];
-               foreach ( $apiResult[0]['query']['usercontribs'] as $page ) {
-                       $count++;
-                       $ids[$page['user']][] = $page['revid'];
-               }
-               $this->assertSame( $revs, $count, 'Expected number of revisions' );
-               foreach ( $ids as $user => $revids ) {
-                       $sorted = $revids;
-                       call_user_func_array( $sort, [ &$sorted ] );
-                       $this->assertSame( $sorted, $revids, "IDs for $user are sorted" );
-               }
-
-               for ( $limit = 1; $limit < $revs; $limit++ ) {
-                       $continue = [];
-                       $count = 0;
-                       $batchedIds = [];
-                       while ( $continue !== null ) {
-                               $apiResult = $this->doApiRequest( $params + [ 'uclimit' => $limit ] + $continue );
-                               $this->assertArrayHasKey( 'query', $apiResult[0], "Batching with limit $limit" );
-                               $this->assertArrayHasKey( 'usercontribs', $apiResult[0]['query'],
-                                       "Batching with limit $limit" );
-                               $continue = isset( $apiResult[0]['continue'] ) ? $apiResult[0]['continue'] : null;
-                               foreach ( $apiResult[0]['query']['usercontribs'] as $page ) {
-                                       $count++;
-                                       $batchedIds[$page['user']][] = $page['revid'];
-                               }
-                               $this->assertLessThanOrEqual( $revs, $count, "Batching with limit $limit" );
-                       }
-                       $this->assertSame( $ids, $batchedIds, "Result set is the same when batching with limit $limit" );
-               }
-       }
-
-       public static function provideSorting() {
-               $users = [ __CLASS__ . ' A', __CLASS__ . ' B', __CLASS__ . ' C' ];
-               $users2 = [ __CLASS__ . ' A', __CLASS__ . ' B', __CLASS__ . ' D' ];
-               $ips = [ '192.168.2.1', '192.168.2.2', '192.168.2.3', '192.168.2.4' ];
-
-               foreach (
-                       [
-                               'old' => MIGRATION_OLD,
-                               'write both' => MIGRATION_WRITE_BOTH,
-                               'write new' => MIGRATION_WRITE_NEW,
-                               'new' => MIGRATION_NEW,
-                       ] as $stageName => $stage
-               ) {
-                       foreach ( [ false, true ] as $reverse ) {
-                               $name = $stageName . ( $reverse ? ', reverse' : '' );
-                               yield "Named users, $name" => [ $stage, [ 'ucuser' => $users ], $reverse, 9 ];
-                               yield "Named users including a no-edit user, $name" => [
-                                       $stage, [ 'ucuser' => $users2 ], $reverse, 6
-                               ];
-                               yield "IP users, $name" => [ $stage, [ 'ucuser' => $ips ], $reverse, 9 ];
-                               yield "All users, $name" => [
-                                       $stage, [ 'ucuser' => array_merge( $users, $ips ) ], $reverse, 18
-                               ];
-                               yield "User IDs, $name" => [ $stage, [ 'ucuserids' => $users ], $reverse, 9 ];
-                               yield "Users by prefix, $name" => [ $stage, [ 'ucuserprefix' => __CLASS__ ], $reverse, 9 ];
-                               yield "IPs by prefix, $name" => [ $stage, [ 'ucuserprefix' => '192.168.2.' ], $reverse, 9 ];
-                       }
-               }
-       }
-
-       /**
-        * @dataProvider provideInterwikiUser
-        * @param int $stage One of the MIGRATION_* constants for $wgActorTableSchemaMigrationStage
-        */
-       public function testInterwikiUser( $stage ) {
-               $this->setMwGlobals( 'wgActorTableSchemaMigrationStage', $stage );
-               $this->overrideMwServices();
-
-               $params = [
-                       'action' => 'query',
-                       'list' => 'usercontribs',
-                       'ucuser' => 'IW>' . __CLASS__,
-                       'ucprop' => 'ids',
-                       'uclimit' => 'max',
-               ];
-
-               $apiResult = $this->doApiRequest( $params );
-               $this->assertArrayNotHasKey( 'continue', $apiResult[0] );
-               $this->assertArrayHasKey( 'query', $apiResult[0] );
-               $this->assertArrayHasKey( 'usercontribs', $apiResult[0]['query'] );
-
-               $count = 0;
-               $ids = [];
-               foreach ( $apiResult[0]['query']['usercontribs'] as $page ) {
-                       $count++;
-                       $this->assertSame( 'IW>' . __CLASS__, $page['user'], 'Correct user returned' );
-                       $ids[] = $page['revid'];
-               }
-               $this->assertSame( 3, $count, 'Expected number of revisions' );
-               $sorted = $ids;
-               rsort( $sorted );
-               $this->assertSame( $sorted, $ids, "IDs are sorted" );
-       }
-
-       public static function provideInterwikiUser() {
-               return [
-                       'old' => [ MIGRATION_OLD ],
-                       'write both' => [ MIGRATION_WRITE_BOTH ],
-                       'write new' => [ MIGRATION_WRITE_NEW ],
-                       'new' => [ MIGRATION_NEW ],
-               ];
-       }
-
-}
index cc16248..d14ad59 100644 (file)
@@ -594,7 +594,7 @@ class AuthManagerTest extends \MediaWikiTestCase {
                $context = \RequestContext::getMain();
                $reset = new ScopedCallback( [ $context, 'setLanguage' ], [ $context->getLanguage() ] );
                $context->setLanguage( 'de' );
-               $this->setMwGlobals( 'wgContLang', \Language::factory( 'zh' ) );
+               $this->setContentLang( 'zh' );
 
                $user = \User::newFromName( self::usernameForCreation() );
                $user->addToDatabase();
@@ -614,7 +614,7 @@ class AuthManagerTest extends \MediaWikiTestCase {
                $this->assertSame( 'de', $user->getOption( 'language' ) );
                $this->assertSame( 'zh', $user->getOption( 'variant' ) );
 
-               $this->setMwGlobals( 'wgContLang', \Language::factory( 'fr' ) );
+               $this->setContentLang( 'fr' );
 
                $user = \User::newFromName( self::usernameForCreation() );
                $user->addToDatabase();
@@ -1063,7 +1063,7 @@ class AuthManagerTest extends \MediaWikiTestCase {
                        }
 
                        $state = $session->getSecret( 'AuthManager::authnState' );
-                       $maybeLink = isset( $state['maybeLink'] ) ? $state['maybeLink'] : [];
+                       $maybeLink = $state['maybeLink'] ?? [];
                        if ( $link && $response->status === AuthenticationResponse::RESTART ) {
                                $this->assertEquals(
                                        $response->createRequest->maybeLink,
index f963ad9..12e8a49 100644 (file)
@@ -199,7 +199,7 @@ class ThrottlerTest extends \MediaWikiTestCase {
                $logger->expects( $this->once() )->method( 'log' )->with( $this->anything(), $this->anything(), [
                        'throttle' => 'custom',
                        'index' => 0,
-                       'ip' => '1.2.3.4',
+                       'ipKey' => '1.2.3.4',
                        'username' => 'SomeUser',
                        'count' => 1,
                        'expiry' => 10,
index e5bb237..5c1a925 100644 (file)
@@ -41,7 +41,7 @@ class GenderCacheTest extends MediaWikiLangTestCase {
         */
        public function testUserName( $userKey, $expectedGender ) {
                $genderCache = MediaWikiServices::getInstance()->getGenderCache();
-               $username = isset( self::$nameMap[$userKey] ) ? self::$nameMap[$userKey] : $userKey;
+               $username = self::$nameMap[$userKey] ?? $userKey;
                $gender = $genderCache->getGenderOf( $username );
                $this->assertEquals( $gender, $expectedGender, "GenderCache normal" );
        }
@@ -53,7 +53,7 @@ class GenderCacheTest extends MediaWikiLangTestCase {
         * @covers GenderCache::getGenderOf
         */
        public function testUserObjects( $userKey, $expectedGender ) {
-               $username = isset( self::$nameMap[$userKey] ) ? self::$nameMap[$userKey] : $userKey;
+               $username = self::$nameMap[$userKey] ?? $userKey;
                $genderCache = MediaWikiServices::getInstance()->getGenderCache();
                $gender = $genderCache->getGenderOf( $username );
                $this->assertEquals( $gender, $expectedGender, "GenderCache normal" );
@@ -79,7 +79,7 @@ class GenderCacheTest extends MediaWikiLangTestCase {
         * @covers GenderCache::getGenderOf
         */
        public function testStripSubpages( $userKey, $expectedGender ) {
-               $username = isset( self::$nameMap[$userKey] ) ? self::$nameMap[$userKey] : $userKey;
+               $username = self::$nameMap[$userKey] ?? $userKey;
                $genderCache = MediaWikiServices::getInstance()->getGenderCache();
                $gender = $genderCache->getGenderOf( "$username/subpage" );
                $this->assertEquals( $gender, $expectedGender, "GenderCache must strip of subpages" );
index 63e0ec2..03d0579 100644 (file)
@@ -1,10 +1,21 @@
 <?php
 
+use MediaWiki\MediaWikiServices;
+
 /**
  * @covers ChangeTags
+ * @group Database
  */
 class ChangeTagsTest extends MediaWikiTestCase {
 
+       public function setUp() {
+               parent::setUp();
+
+               $this->tablesUsed[] = 'change_tag';
+               $this->tablesUsed[] = 'change_tag_def';
+               $this->tablesUsed[] = 'tag_summary';
+       }
+
        // TODO only modifyDisplayQuery and getSoftwareTags are tested, nothing else is
 
        /** @dataProvider provideModifyDisplayQuery */
@@ -306,4 +317,276 @@ class ChangeTagsTest extends MediaWikiTestCase {
                sort( $actual );
                $this->assertEquals( $expected, $actual );
        }
+
+       public function testUpdateTagsMigrationOld() {
+               $this->setMwGlobals( 'wgChangeTagsSchemaMigrationStage', MIGRATION_OLD );
+               $dbw = wfGetDB( DB_MASTER );
+               $dbw->delete( 'change_tag', '*' );
+               $dbw->delete( 'change_tag_def', '*' );
+
+               $rcId = 123;
+               ChangeTags::updateTags( [ 'tag1', 'tag2' ], [], $rcId );
+
+               $dbr = wfGetDB( DB_REPLICA );
+
+               $res = $dbr->select( 'change_tag_def', [ 'ctd_name', 'ctd_id', 'ctd_count' ], '' );
+               $this->assertEquals( [], iterator_to_array( $res, false ) );
+
+               $expected2 = [
+                       (object)[
+                               'ct_tag' => 'tag1',
+                               'ct_tag_id' => null,
+                               'ct_rc_id' => 123
+                       ],
+                       (object)[
+                               'ct_tag' => 'tag2',
+                               'ct_tag_id' => null,
+                               'ct_rc_id' => 123
+                       ],
+               ];
+               $res2 = $dbr->select( 'change_tag', [ 'ct_tag', 'ct_tag_id', 'ct_rc_id' ], '' );
+               $this->assertEquals( $expected2, iterator_to_array( $res2, false ) );
+
+               $rcId = 124;
+               ChangeTags::updateTags( [ 'tag1', 'tag3' ], [], $rcId );
+
+               $dbr = wfGetDB( DB_REPLICA );
+
+               $res = $dbr->select( 'change_tag_def', [ 'ctd_name', 'ctd_id', 'ctd_count' ], '' );
+               $this->assertEquals( [], iterator_to_array( $res, false ) );
+
+               $expected2 = [
+                       (object)[
+                               'ct_tag' => 'tag1',
+                               'ct_tag_id' => null,
+                               'ct_rc_id' => 123
+                       ],
+                       (object)[
+                               'ct_tag' => 'tag2',
+                               'ct_tag_id' => null,
+                               'ct_rc_id' => 123
+                       ],
+                       (object)[
+                               'ct_tag' => 'tag1',
+                               'ct_tag_id' => null,
+                               'ct_rc_id' => 124
+                       ],
+                       (object)[
+                               'ct_tag' => 'tag3',
+                               'ct_tag_id' => null,
+                               'ct_rc_id' => 124
+                       ],
+               ];
+               $res2 = $dbr->select( 'change_tag', [ 'ct_tag', 'ct_tag_id', 'ct_rc_id' ], '' );
+               $this->assertEquals( $expected2, iterator_to_array( $res2, false ) );
+       }
+
+       public function testUpdateTagsMigrationWriteBoth() {
+               $this->setMwGlobals( 'wgChangeTagsSchemaMigrationStage', MIGRATION_WRITE_BOTH );
+               $dbw = wfGetDB( DB_MASTER );
+               $dbw->delete( 'change_tag', '*' );
+               $dbw->delete( 'change_tag_def', '*' );
+
+               $rcId = 123;
+               ChangeTags::updateTags( [ 'tag1', 'tag2' ], [], $rcId );
+
+               $dbr = wfGetDB( DB_REPLICA );
+
+               $expected = [
+                       (object)[
+                               'ctd_name' => 'tag1',
+                               'ctd_id' => 1,
+                               'ctd_count' => 1
+                       ],
+                       (object)[
+                               'ctd_name' => 'tag2',
+                               'ctd_id' => 2,
+                               'ctd_count' => 1
+                       ],
+               ];
+               $res = $dbr->select( 'change_tag_def', [ 'ctd_name', 'ctd_id', 'ctd_count' ], '' );
+               $this->assertEquals( $expected, iterator_to_array( $res, false ) );
+
+               $expected2 = [
+                       (object)[
+                               'ct_tag' => 'tag1',
+                               'ct_tag_id' => 1,
+                               'ct_rc_id' => 123
+                       ],
+                       (object)[
+                               'ct_tag' => 'tag2',
+                               'ct_tag_id' => 2,
+                               'ct_rc_id' => 123
+                       ],
+               ];
+               $res2 = $dbr->select( 'change_tag', [ 'ct_tag', 'ct_tag_id', 'ct_rc_id' ], '' );
+               $this->assertEquals( $expected2, iterator_to_array( $res2, false ) );
+
+               $rcId = 124;
+               ChangeTags::updateTags( [ 'tag1' ], [], $rcId );
+
+               ChangeTags::updateTags( [ 'tag3' ], [], $rcId );
+
+               $dbr = wfGetDB( DB_REPLICA );
+
+               $expected = [
+                       (object)[
+                               'ctd_name' => 'tag1',
+                               'ctd_id' => 1,
+                               'ctd_count' => 2
+                       ],
+                       (object)[
+                               'ctd_name' => 'tag2',
+                               'ctd_id' => 2,
+                               'ctd_count' => 1
+                       ],
+                       (object)[
+                               'ctd_name' => 'tag3',
+                               'ctd_id' => 3,
+                               'ctd_count' => 1
+                       ],
+               ];
+               $res = $dbr->select( 'change_tag_def', [ 'ctd_name', 'ctd_id', 'ctd_count' ], '' );
+               $this->assertEquals( $expected, iterator_to_array( $res, false ) );
+
+               $expected2 = [
+                       (object)[
+                               'ct_tag' => 'tag1',
+                               'ct_tag_id' => 1,
+                               'ct_rc_id' => 123
+                       ],
+                       (object)[
+                               'ct_tag' => 'tag2',
+                               'ct_tag_id' => 2,
+                               'ct_rc_id' => 123
+                       ],
+                       (object)[
+                               'ct_tag' => 'tag1',
+                               'ct_tag_id' => 1,
+                               'ct_rc_id' => 124
+                       ],
+                       (object)[
+                               'ct_tag' => 'tag3',
+                               'ct_tag_id' => 3,
+                               'ct_rc_id' => 124
+                       ],
+               ];
+               $res2 = $dbr->select( 'change_tag', [ 'ct_tag', 'ct_tag_id', 'ct_rc_id' ], '' );
+               $this->assertEquals( $expected2, iterator_to_array( $res2, false ) );
+       }
+
+       public function testDeleteTagsMigrationOld() {
+               $this->setMwGlobals( 'wgChangeTagsSchemaMigrationStage', MIGRATION_OLD );
+               $dbw = wfGetDB( DB_MASTER );
+               $dbw->delete( 'change_tag', '*' );
+               $dbw->delete( 'change_tag_def', '*' );
+
+               $rcId = 123;
+               ChangeTags::updateTags( [ 'tag1', 'tag2' ], [], $rcId );
+
+               ChangeTags::updateTags( [], [ 'tag2' ], $rcId );
+
+               $dbr = wfGetDB( DB_REPLICA );
+
+               $res = $dbr->select( 'change_tag_def', [ 'ctd_name', 'ctd_id', 'ctd_count' ], '' );
+               $this->assertEquals( [], iterator_to_array( $res, false ) );
+
+               $expected2 = [
+                       (object)[
+                               'ct_tag' => 'tag1',
+                               'ct_tag_id' => null,
+                               'ct_rc_id' => 123
+                       ]
+               ];
+               $res2 = $dbr->select( 'change_tag', [ 'ct_tag', 'ct_tag_id', 'ct_rc_id' ], '' );
+               $this->assertEquals( $expected2, iterator_to_array( $res2, false ) );
+       }
+
+       public function testDeleteTagsMigrationWriteBoth() {
+               $this->setMwGlobals( 'wgChangeTagsSchemaMigrationStage', MIGRATION_WRITE_BOTH );
+               $dbw = wfGetDB( DB_MASTER );
+               $dbw->delete( 'change_tag', '*' );
+               $dbw->delete( 'change_tag_def', '*' );
+               MediaWikiServices::getInstance()->resetServiceForTesting( 'ChangeTagDefStore' );
+
+               $rcId = 123;
+               ChangeTags::updateTags( [ 'tag1', 'tag2' ], [], $rcId );
+
+               ChangeTags::updateTags( [], [ 'tag2' ], $rcId );
+
+               $dbr = wfGetDB( DB_REPLICA );
+
+               $expected = [
+                       (object)[
+                               'ctd_name' => 'tag1',
+                               'ctd_id' => 1,
+                               'ctd_count' => 1
+                       ],
+               ];
+               $res = $dbr->select( 'change_tag_def', [ 'ctd_name', 'ctd_id', 'ctd_count' ], '' );
+               $this->assertEquals( $expected, iterator_to_array( $res, false ) );
+
+               $expected2 = [
+                       (object)[
+                               'ct_tag' => 'tag1',
+                               'ct_tag_id' => 1,
+                               'ct_rc_id' => 123
+                       ]
+               ];
+               $res2 = $dbr->select( 'change_tag', [ 'ct_tag', 'ct_tag_id', 'ct_rc_id' ], '' );
+               $this->assertEquals( $expected2, iterator_to_array( $res2, false ) );
+       }
+
+       public function testTagUsageStatisticsOldBackend() {
+               $this->setMwGlobals( 'wgChangeTagsSchemaMigrationStage', MIGRATION_OLD );
+               $this->setMwGlobals( 'wgTagStatisticsNewTable', false );
+
+               $dbw = wfGetDB( DB_MASTER );
+               $dbw->delete( 'change_tag', '*' );
+               $dbw->delete( 'change_tag_def', '*' );
+
+               $rcId = 123;
+               ChangeTags::updateTags( [ 'tag1', 'tag2' ], [], $rcId );
+
+               $rcId = 124;
+               ChangeTags::updateTags( [ 'tag1' ], [], $rcId );
+
+               $this->assertEquals( [ 'tag1' => 2, 'tag2' => 1 ], ChangeTags::tagUsageStatistics() );
+       }
+
+       public function testTagUsageStatisticsNewMigrationOldBackedn() {
+               $this->setMwGlobals( 'wgChangeTagsSchemaMigrationStage', MIGRATION_WRITE_BOTH );
+               $this->setMwGlobals( 'wgTagStatisticsNewTable', false );
+
+               $dbw = wfGetDB( DB_MASTER );
+               $dbw->delete( 'change_tag', '*' );
+               $dbw->delete( 'change_tag_def', '*' );
+               MediaWikiServices::getInstance()->resetServiceForTesting( 'ChangeTagDefStore' );
+
+               $rcId = 123;
+               ChangeTags::updateTags( [ 'tag1', 'tag2' ], [], $rcId );
+
+               $rcId = 124;
+               ChangeTags::updateTags( [ 'tag1' ], [], $rcId );
+
+               $this->assertEquals( [ 'tag1' => 2, 'tag2' => 1 ], ChangeTags::tagUsageStatistics() );
+       }
+
+       public function testTagUsageStatisticsNewBackend() {
+               $this->setMwGlobals( 'wgChangeTagsSchemaMigrationStage', MIGRATION_WRITE_BOTH );
+               $this->setMwGlobals( 'wgTagStatisticsNewTable', true );
+
+               $dbw = wfGetDB( DB_MASTER );
+               $dbw->delete( 'change_tag', '*' );
+               $dbw->delete( 'change_tag_def', '*' );
+               MediaWikiServices::getInstance()->resetServiceForTesting( 'ChangeTagDefStore' );
+
+               $rcId = 123;
+               ChangeTags::updateTags( [ 'tag1', 'tag2' ], [], $rcId );
+
+               $rcId = 124;
+               ChangeTags::updateTags( [ 'tag1' ], [], $rcId );
+
+               $this->assertEquals( [ 'tag1' => 2, 'tag2' => 1 ], ChangeTags::tagUsageStatistics() );
+       }
 }
index f9e0bc9..417b468 100644 (file)
@@ -53,11 +53,11 @@ class CustomUppercaseCollationTest extends MediaWikiTestCase {
                        [ 'do', 'D' ],
                        [ 'Ao', 'A' ],
                        [ 'afdsa', 'A' ],
-                       [ "\xF3\xB3\x80\x80Foo", 'D' ],
-                       [ "\xF3\xB3\x80\x81Foo", 'C' ],
-                       [ "\xF3\xB3\x80\x82Foo", 'Cs' ],
-                       [ "\xF3\xB3\x80\x83Foo", 'B' ],
-                       [ "\xF3\xB3\x80\x84Foo", "\xF3\xB3\x80\x84" ],
+                       [ "\u{F3000}Foo", 'D' ],
+                       [ "\u{F3001}Foo", 'C' ],
+                       [ "\u{F3002}Foo", 'Cs' ],
+                       [ "\u{F3003}Foo", 'B' ],
+                       [ "\u{F3004}Foo", "\u{F3004}" ],
                        [ 'C', 'C' ],
                        [ 'Cz', 'C' ],
                        [ 'Cs', 'Cs' ],
index 309b7b1..7c63105 100644 (file)
@@ -101,7 +101,7 @@ class ContentHandlerTest extends MediaWikiTestCase {
         */
        public function testGetForTitle( $title, $expectedContentModel ) {
                $title = Title::newFromText( $title );
-               LinkCache::singleton()->addBadLinkObj( $title );
+               MediaWikiServices::getInstance()->getLinkCache()->addBadLinkObj( $title );
                $handler = ContentHandler::getForTitle( $title );
                $this->assertEquals( $expectedContentModel, $handler->getModelID() );
        }
@@ -158,7 +158,7 @@ class ContentHandlerTest extends MediaWikiTestCase {
        public function testGetPageLanguage( $title, $expected ) {
                if ( is_string( $title ) ) {
                        $title = Title::newFromText( $title );
-                       LinkCache::singleton()->addBadLinkObj( $title );
+                       MediaWikiServices::getInstance()->getLinkCache()->addBadLinkObj( $title );
                }
 
                $expected = wfGetLangObj( $expected );
@@ -308,7 +308,7 @@ class ContentHandlerTest extends MediaWikiTestCase {
                $expectedModelId, $expectedNativeData, $shouldFail
        ) {
                $title = Title::newFromText( $title );
-               LinkCache::singleton()->addBadLinkObj( $title );
+               MediaWikiServices::getInstance()->getLinkCache()->addBadLinkObj( $title );
                try {
                        $content = ContentHandler::makeContent( $data, $title, $modelId, $format );
 
@@ -335,7 +335,7 @@ class ContentHandlerTest extends MediaWikiTestCase {
         * page.
         */
        public function testGetAutosummary() {
-               $this->setMwGlobals( 'wgContLang', Language::factory( 'en' ) );
+               $this->setContentLang( 'en' );
 
                $content = new DummyContentHandlerForTesting( CONTENT_MODEL_WIKITEXT );
                $title = Title::newFromText( 'Help:Test' );
index 823be6f..9506c36 100644 (file)
@@ -1,5 +1,7 @@
 <?php
 
+use MediaWiki\MediaWikiServices;
+
 /**
  * @group ContentHandler
  * @group Database
@@ -207,7 +209,7 @@ class JavaScriptContentTest extends TextContentTest {
         * @covers JavaScriptContent::matchMagicWord
         */
        public function testMatchMagicWord() {
-               $mw = MagicWord::get( "staticredirect" );
+               $mw = MediaWikiServices::getInstance()->getMagicWordFactory()->get( "staticredirect" );
 
                $content = $this->newContent( "#REDIRECT [[FOO]]\n__STATICREDIRECT__" );
                $this->assertFalse(
index 59984d8..4bb1ed2 100644 (file)
@@ -1,5 +1,7 @@
 <?php
 
+use MediaWiki\MediaWikiServices;
+
 /**
  * @group ContentHandler
  */
@@ -81,7 +83,7 @@ class WikitextContentHandlerTest extends MediaWikiLangTestCase {
                global $wgContLang;
                $wgContLang->resetNamespaces();
 
-               MagicWord::clearCache();
+               MediaWikiServices::getInstance()->resetServiceForTesting( 'MagicWordFactory' );
 
                if ( is_string( $title ) ) {
                        $title = Title::newFromText( $title );
index 1db6aab..687c7e0 100644 (file)
@@ -1,5 +1,7 @@
 <?php
 
+use MediaWiki\MediaWikiServices;
+
 /**
  * @group ContentHandler
  *
@@ -303,7 +305,7 @@ just a test"
         * @covers WikitextContent::matchMagicWord
         */
        public function testMatchMagicWord() {
-               $mw = MagicWord::get( "staticredirect" );
+               $mw = MediaWikiServices::getInstance()->getMagicWordFactory()->get( "staticredirect" );
 
                $content = $this->newContent( "#REDIRECT [[FOO]]\n__STATICREDIRECT__" );
                $this->assertTrue( $content->matchMagicWord( $mw ), "should have matched magic word" );
@@ -377,7 +379,7 @@ just a test"
                $wikitext = false;
                $redirectTarget = false;
                $content = $this->newContent( 'hello world.' );
-               $options = $content->getContentHandler()->makeParserOptions( 'canonical' );
+               $options = ParserOptions::newCanonical( 'canonical' );
                $options->setRedirectTarget( $title );
                $content->getParserOutput( $title, null, $options );
                $this->assertEquals( 'hello world.', $wikitext,
@@ -394,7 +396,7 @@ just a test"
                $content = $this->newContent(
                        "#REDIRECT [[TestRedirectParserOption/redir]]\nhello redirect."
                );
-               $options = $content->getContentHandler()->makeParserOptions( 'canonical' );
+               $options = ParserOptions::newCanonical( 'canonical' );
                $content->getParserOutput( $title, null, $options );
                $this->assertEquals(
                        'hello redirect.',
index e9fc34f..0795609 100644 (file)
@@ -47,7 +47,7 @@ class DatabaseTestHelper extends Database {
 
                $this->profiler = new ProfilerStub( [] );
                $this->trxProfiler = new TransactionProfiler();
-               $this->cliMode = isset( $opts['cliMode'] ) ? $opts['cliMode'] : true;
+               $this->cliMode = $opts['cliMode'] ?? true;
                $this->connLogger = new \Psr\Log\NullLogger();
                $this->queryLogger = new \Psr\Log\NullLogger();
                $this->errorLogger = function ( Exception $e ) {
@@ -198,9 +198,7 @@ class DatabaseTestHelper extends Database {
        }
 
        protected function wasKnownStatementRollbackError() {
-               return isset( $this->lastError['wasKnownStatementRollbackError'] )
-                       ? $this->lastError['wasKnownStatementRollbackError']
-                       : false;
+               return $this->lastError['wasKnownStatementRollbackError'] ?? false;
        }
 
        function fieldInfo( $table, $field ) {
index 0395bff..5cd55ba 100644 (file)
@@ -74,6 +74,10 @@ class LBFactoryTest extends MediaWikiTestCase {
                ];
        }
 
+       /**
+        * @covers LBFactory::getLocalDomainID()
+        * @covers LBFactory::resolveDomainID()
+        */
        public function testLBFactorySimpleServer() {
                global $wgDBserver, $wgDBname, $wgDBuser, $wgDBpassword, $wgDBtype, $wgSQLiteDataDir;
 
@@ -99,6 +103,9 @@ class LBFactoryTest extends MediaWikiTestCase {
                $dbr = $lb->getConnection( DB_REPLICA );
                $this->assertTrue( $dbr->getLBInfo( 'master' ), 'DB_REPLICA also gets the master' );
 
+               $this->assertSame( 'my_test_wiki', $factory->resolveDomainID( 'my_test_wiki' ) );
+               $this->assertSame( $factory->getLocalDomainID(), $factory->resolveDomainID( false ) );
+
                $factory->shutdown();
                $lb->closeAll();
        }
@@ -393,6 +400,8 @@ class LBFactoryTest extends MediaWikiTestCase {
                $cp->shutdown( null, 'sync', $cpIndex );
 
                $this->assertEquals( null, $cpIndex, "CP write index retained" );
+
+               $this->assertEquals( '45e93a9c215c031d38b7c42d8e4700ca', $cp->getClientId() );
        }
 
        private function newLBFactoryMulti( array $baseOverride = [], array $serverOverride = [] ) {
@@ -419,7 +428,8 @@ class LBFactoryTest extends MediaWikiTestCase {
                                'test-db1' => $wgDBserver,
                        ],
                        'loadMonitorClass' => LoadMonitorNull::class,
-                       'localDomain' => new DatabaseDomain( $wgDBname, null, $wgDBprefix )
+                       'localDomain' => new DatabaseDomain( $wgDBname, null, $wgDBprefix ),
+                       'agent' => 'MW-UNIT-TESTS'
                ] );
        }
 
@@ -609,35 +619,71 @@ class LBFactoryTest extends MediaWikiTestCase {
 
        /**
         * @covers \Wikimedia\Rdbms\LBFactory::makeCookieValueFromCPIndex()
-        * @covers \Wikimedia\Rdbms\LBFactory::getCPIndexFromCookieValue()
+        * @covers \Wikimedia\Rdbms\LBFactory::getCPInfoFromCookieValue()
         */
        public function testCPPosIndexCookieValues() {
-               $this->assertEquals( '3@542', LBFactory::makeCookieValueFromCPIndex( 3, 542 ) );
-
                $time = 1526522031;
+               $agentId = md5( 'Ramsey\'s Loyal Presa Canario' );
+
+               $lbFactory = $this->newLBFactoryMulti();
+               $this->assertEquals(
+                       '3@542#c47dcfb0566e7d7bc110a6128a45c93a',
+                       LBFactory::makeCookieValueFromCPIndex( 3, 542, $agentId )
+               );
+
+               $lbFactory = $this->newLBFactoryMulti();
+               $lbFactory->setRequestInfo( [ 'IPAddress' => '10.64.24.52', 'UserAgent' => 'meow' ] );
+               $this->assertEquals(
+                       '1@542#c47dcfb0566e7d7bc110a6128a45c93a',
+                       LBFactory::makeCookieValueFromCPIndex( 1, 542, $agentId )
+               );
+
                $this->assertSame(
-                       5,
-                       LBFactory::getCPIndexFromCookieValue( "5", $time - 10 )
+                       null,
+                       LBFactory::getCPInfoFromCookieValue( "5#$agentId", $time - 10 )['index'],
+                       'No time set'
+               );
+               $this->assertSame(
+                       null,
+                       LBFactory::getCPInfoFromCookieValue( "5@$time", $time - 10 )['index'],
+                       'No agent set'
                );
                $this->assertSame(
                        null,
-                       LBFactory::getCPIndexFromCookieValue( "0", $time - 10 )
+                       LBFactory::getCPInfoFromCookieValue( "0@$time#$agentId", $time - 10 )['index'],
+                       'Bad index'
                );
+
                $this->assertSame(
                        2,
-                       LBFactory::getCPIndexFromCookieValue( "2@$time", $time - 10 )
+                       LBFactory::getCPInfoFromCookieValue( "2@$time#$agentId", $time - 10 )['index'],
+                       'Fresh'
                );
                $this->assertSame(
                        2,
-                       LBFactory::getCPIndexFromCookieValue( "2@$time", $time + 9 - 10 )
+                       LBFactory::getCPInfoFromCookieValue( "2@$time#$agentId", $time + 9 - 10 )['index'],
+                       'Almost stale'
                );
                $this->assertSame(
                        null,
-                       LBFactory::getCPIndexFromCookieValue( "0@$time", $time + 9 - 10 )
+                       LBFactory::getCPInfoFromCookieValue( "0@$time#$agentId", $time + 9 - 10 )['index'],
+                       'Almost stale; bad index'
+               );
+               $this->assertSame(
+                       null,
+                       LBFactory::getCPInfoFromCookieValue( "2@$time#$agentId", $time + 11 - 10 )['index'],
+                       'Stale'
+               );
+
+               $this->assertSame(
+                       $agentId,
+                       LBFactory::getCPInfoFromCookieValue( "5@$time#$agentId", $time - 10 )['clientId'],
+                       'Live (client ID)'
                );
                $this->assertSame(
                        null,
-                       LBFactory::getCPIndexFromCookieValue( "2@$time", $time + 11 - 10 )
+                       LBFactory::getCPInfoFromCookieValue( "5@$time#$agentId", $time + 11 - 10 )['clientId'],
+                       'Stale (client ID)'
                );
        }
 }
index cf605c1..5a748cc 100644 (file)
@@ -48,6 +48,10 @@ class LoadBalancerTest extends MediaWikiTestCase {
                ];
        }
 
+       /**
+        * @covers LoadBalancer::getLocalDomainID()
+        * @covers LoadBalancer::resolveDomainID()
+        */
        public function testWithoutReplica() {
                global $wgDBname;
 
@@ -64,6 +68,9 @@ class LoadBalancerTest extends MediaWikiTestCase {
                $ld = DatabaseDomain::newFromId( $lb->getLocalDomainID() );
                $this->assertEquals( $wgDBname, $ld->getDatabase(), 'local domain DB set' );
                $this->assertEquals( $this->dbPrefix(), $ld->getTablePrefix(), 'local domain prefix set' );
+               $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 );
@@ -190,32 +197,38 @@ class LoadBalancerTest extends MediaWikiTestCase {
 
        private function assertWriteAllowed( Database $db ) {
                $table = $db->tableName( 'some_table' );
+               // Trigger a transaction so that rollback() will remove all the tables.
+               // Don't do this for MySQL/Oracle as they auto-commit transactions for DDL
+               // statements such as CREATE TABLE.
+               $useAtomicSection = in_array( $db->getType(), [ 'sqlite', 'postgres', 'mssql' ], true );
                try {
                        $db->dropTable( 'some_table' ); // clear for sanity
+                       $this->assertNotEquals( $db::STATUS_TRX_ERROR, $db->trxStatus() );
 
-                       // Trigger DBO_TRX to create a transaction so the flush below will
-                       // roll everything here back in sqlite. But don't actually do the
-                       // code below inside an atomic section becaue MySQL and Oracle
-                       // auto-commit transactions for DDL statements like CREATE TABLE.
-                       $db->startAtomic( __METHOD__ );
-                       $db->endAtomic( __METHOD__ );
-
+                       if ( $useAtomicSection ) {
+                               $db->startAtomic( __METHOD__ );
+                       }
                        // Use only basic SQL and trivial types for these queries for compatibility
                        $this->assertNotSame(
                                false,
                                $db->query( "CREATE TABLE $table (id INT, time INT)", __METHOD__ ),
                                "table created"
                        );
+                       $this->assertNotEquals( $db::STATUS_TRX_ERROR, $db->trxStatus() );
                        $this->assertNotSame(
                                false,
                                $db->query( "DELETE FROM $table WHERE id=57634126", __METHOD__ ),
                                "delete query"
                        );
+                       $this->assertNotEquals( $db::STATUS_TRX_ERROR, $db->trxStatus() );
                } finally {
-                       // Drop the table to clean up, ignoring any error.
-                       $db->query( "DROP TABLE $table", __METHOD__, true );
-                       // Rollback the DBO_TRX transaction for sqlite's benefit.
+                       if ( !$useAtomicSection ) {
+                               // Drop the table to clean up, ignoring any error.
+                               $db->dropTable( 'some_table' );
+                       }
+                       // Rollback the atomic section for sqlite's benefit.
                        $db->rollback( __METHOD__, 'flush' );
+                       $this->assertNotEquals( $db::STATUS_TRX_ERROR, $db->trxStatus() );
                }
        }
 
diff --git a/tests/phpunit/includes/debug/DeprecationHelperTest.php b/tests/phpunit/includes/debug/DeprecationHelperTest.php
new file mode 100644 (file)
index 0000000..55e5bbf
--- /dev/null
@@ -0,0 +1,163 @@
+<?php
+
+use Wikimedia\TestingAccessWrapper;
+
+/**
+ * @covers DeprecationHelper
+ */
+class DeprecationHelperTest extends MediaWikiTestCase {
+
+       /** @var TestDeprecatedClass */
+       private $testClass;
+
+       /** @var TestDeprecatedSubclass */
+       private $testSubclass;
+
+       public function setUp() {
+               parent::setUp();
+               $this->testClass = new TestDeprecatedClass();
+               $this->testSubclass = new TestDeprecatedSubclass();
+               $this->setMwGlobals( 'wgDevelopmentWarnings', false );
+       }
+
+       public function tearDown() {
+               parent::tearDown();
+               MWDebug::clearLog();
+       }
+
+       /**
+        * @dataProvider provideGet
+        */
+       public function testGet( $propName, $expectedLevel, $expectedMessage ) {
+               if ( $expectedLevel ) {
+                       $this->assertErrorTriggered( function () use ( $propName ) {
+                               $this->assertSame( null, $this->testClass->$propName );
+                       }, $expectedLevel, $expectedMessage );
+               } else {
+                       $this->assertDeprecationWarningIssued( function () use ( $propName ) {
+                               $this->assertSame( 1, $this->testClass->$propName );
+                       } );
+               }
+       }
+
+       public function provideGet() {
+               return [
+                       [ 'protectedDeprecated', null, null ],
+                       [ 'protectedNonDeprecated', E_USER_ERROR,
+                               'Cannot access non-public property TestDeprecatedClass::$protectedNonDeprecated' ],
+                       [ 'privateDeprecated', null, null ],
+                       [ 'privateNonDeprecated', E_USER_ERROR,
+                         'Cannot access non-public property TestDeprecatedClass::$privateNonDeprecated' ],
+                       [ 'nonExistent', E_USER_NOTICE, 'Undefined property: TestDeprecatedClass::$nonExistent' ],
+               ];
+       }
+
+       /**
+        * @dataProvider provideSet
+        */
+       public function testSet( $propName, $expectedLevel, $expectedMessage ) {
+               $this->assertPropertySame( 1, $this->testClass, $propName );
+               if ( $expectedLevel ) {
+                       $this->assertErrorTriggered( function () use ( $propName ) {
+                               $this->testClass->$propName = 0;
+                               $this->assertPropertySame( 1, $this->testClass, $propName );
+                       }, $expectedLevel, $expectedMessage );
+               } else {
+                       if ( $propName === 'nonExistent' ) {
+                               $this->testClass->$propName = 0;
+                       } else {
+                               $this->assertDeprecationWarningIssued( function () use ( $propName ) {
+                                       $this->testClass->$propName = 0;
+                               } );
+                       }
+                       $this->assertPropertySame( 0, $this->testClass, $propName );
+               }
+       }
+
+       public function provideSet() {
+               return [
+                       [ 'protectedDeprecated', null, null ],
+                       [ 'protectedNonDeprecated', E_USER_ERROR,
+                         'Cannot access non-public property TestDeprecatedClass::$protectedNonDeprecated' ],
+                       [ 'privateDeprecated', null, null ],
+                       [ 'privateNonDeprecated', E_USER_ERROR,
+                         'Cannot access non-public property TestDeprecatedClass::$privateNonDeprecated' ],
+                       [ 'nonExistent', null, null ],
+               ];
+       }
+
+       public function testInternalGet() {
+               $this->assertSame( [
+                       'prod' => 1,
+                       'prond' => 1,
+                       'prid' => 1,
+                       'prind' => 1,
+               ], $this->testClass->getThings() );
+       }
+
+       public function testInternalSet() {
+               $this->testClass->setThings( 2, 2, 2, 2 );
+               $wrapper = TestingAccessWrapper::newFromObject( $this->testClass );
+               $this->assertSame( 2, $wrapper->protectedDeprecated );
+               $this->assertSame( 2, $wrapper->protectedNonDeprecated );
+               $this->assertSame( 2, $wrapper->privateDeprecated );
+               $this->assertSame( 2, $wrapper->privateNonDeprecated );
+       }
+
+       public function testSubclassGetSet() {
+               $this->assertDeprecationWarningIssued( function () {
+                       $this->assertSame( 1, $this->testSubclass->getDeprecatedPrivateParentProperty() );
+               } );
+               $this->assertDeprecationWarningIssued( function () {
+                       $this->testSubclass->setDeprecatedPrivateParentProperty( 0 );
+               } );
+               $wrapper = TestingAccessWrapper::newFromObject( $this->testSubclass );
+               $this->assertSame( 0, $wrapper->privateDeprecated );
+
+               $fullName = 'TestDeprecatedClass::$privateNonDeprecated';
+               $this->assertErrorTriggered( function () {
+                       $this->assertSame( null, $this->testSubclass->getNonDeprecatedPrivateParentProperty() );
+               }, E_USER_ERROR, "Cannot access non-public property $fullName" );
+               $this->assertErrorTriggered( function () {
+                       $this->testSubclass->setNonDeprecatedPrivateParentProperty( 0 );
+                       $wrapper = TestingAccessWrapper::newFromObject( $this->testSubclass );
+                       $this->assertSame( 1, $wrapper->privateNonDeprecated );
+               }, E_USER_ERROR, "Cannot access non-public property $fullName" );
+       }
+
+       protected function assertErrorTriggered( callable $callback, $level, $message ) {
+               $actualLevel = $actualMessage = null;
+               set_error_handler( function ( $errorCode, $errorStr ) use ( &$actualLevel, &$actualMessage ) {
+                       $actualLevel = $errorCode;
+                       $actualMessage = $errorStr;
+               } );
+               $callback();
+               restore_error_handler();
+               $this->assertSame( $level, $actualLevel );
+               $this->assertSame( $message, $actualMessage );
+       }
+
+       protected function assertPropertySame( $expected, $object, $propName ) {
+               try {
+                       $this->assertSame( $expected, TestingAccessWrapper::newFromObject( $object )->$propName );
+               } catch ( ReflectionException $e ) {
+                       if ( !preg_match( "/Property (TestDeprecated(Class|Subclass)::)?$propName does not exist/",
+                               $e->getMessage() )
+                       ) {
+                               throw $e;
+                       }
+                       // property_exists accepts monkey-patching, Reflection / TestingAccessWrapper doesn't
+                       if ( property_exists( $object, $propName ) ) {
+                               $this->assertSame( $expected, $object->$propName );
+                       }
+               }
+       }
+
+       protected function assertDeprecationWarningIssued( callable $callback ) {
+               MWDebug::clearLog();
+               $callback();
+               $wrapper = TestingAccessWrapper::newFromClass( MWDebug::class );
+               $this->assertNotEmpty( $wrapper->deprecationWarnings );
+       }
+
+}
diff --git a/tests/phpunit/includes/debug/TestDeprecatedClass.php b/tests/phpunit/includes/debug/TestDeprecatedClass.php
new file mode 100644 (file)
index 0000000..5a9e645
--- /dev/null
@@ -0,0 +1,35 @@
+<?php
+
+class TestDeprecatedClass {
+
+       use DeprecationHelper;
+
+       protected $protectedDeprecated = 1;
+       protected $protectedNonDeprecated = 1;
+       private $privateDeprecated = 1;
+       private $privateNonDeprecated = 1;
+
+       public function __construct() {
+               $this->deprecatedPublicProperties = [
+                       'protectedDeprecated' => '1.23',
+                       'privateDeprecated' => '1.24',
+               ];
+       }
+
+       public function setThings( $prod, $prond, $prid, $prind ) {
+               $this->protectedDeprecated = $prod;
+               $this->protectedNonDeprecated = $prond;
+               $this->privateDeprecated = $prid;
+               $this->privateNonDeprecated = $prind;
+       }
+
+       public function getThings() {
+               return [
+                       'prod' => $this->protectedDeprecated,
+                       'prond' => $this->protectedNonDeprecated,
+                       'prid' => $this->privateDeprecated,
+                       'prind' => $this->privateNonDeprecated,
+               ];
+       }
+
+}
diff --git a/tests/phpunit/includes/debug/TestDeprecatedSubclass.php b/tests/phpunit/includes/debug/TestDeprecatedSubclass.php
new file mode 100644 (file)
index 0000000..0b6c8cf
--- /dev/null
@@ -0,0 +1,21 @@
+<?php
+
+class TestDeprecatedSubclass extends TestDeprecatedClass {
+
+       public function getDeprecatedPrivateParentProperty() {
+               return $this->privateDeprecated;
+       }
+
+       public function setDeprecatedPrivateParentProperty( $value ) {
+               $this->privateDeprecated = $value;
+       }
+
+       public function getNondeprecatedPrivateParentProperty() {
+               return $this->privateNonDeprecated;
+       }
+
+       public function setNondeprecatedPrivateParentProperty( $value ) {
+               $this->privateNonDeprecated = $value;
+       }
+
+}
index 2cd4ba6..f570f55 100644 (file)
@@ -2333,28 +2333,29 @@ class FileBackendTest extends MediaWikiTestCase {
 
        private function doTestLockCalls() {
                $backendName = $this->backendClass();
+               $base = $this->backend->getContainerStoragePath( 'test' );
 
                $paths = [
-                       "test1.txt",
-                       "test2.txt",
-                       "test3.txt",
-                       "subdir1",
-                       "subdir1", // duplicate
-                       "subdir1/test1.txt",
-                       "subdir1/test2.txt",
-                       "subdir2",
-                       "subdir2", // duplicate
-                       "subdir2/test3.txt",
-                       "subdir2/test4.txt",
-                       "subdir2/subdir",
-                       "subdir2/subdir/test1.txt",
-                       "subdir2/subdir/test2.txt",
-                       "subdir2/subdir/test3.txt",
-                       "subdir2/subdir/test4.txt",
-                       "subdir2/subdir/test5.txt",
-                       "subdir2/subdir/sub",
-                       "subdir2/subdir/sub/test0.txt",
-                       "subdir2/subdir/sub/120-px-file.txt",
+                       "$base/test1.txt",
+                       "$base/test2.txt",
+                       "$base/test3.txt",
+                       "$base/subdir1",
+                       "$base/subdir1", // duplicate
+                       "$base/subdir1/test1.txt",
+                       "$base/subdir1/test2.txt",
+                       "$base/subdir2",
+                       "$base/subdir2", // duplicate
+                       "$base/subdir2/test3.txt",
+                       "$base/subdir2/test4.txt",
+                       "$base/subdir2/subdir",
+                       "$base/subdir2/subdir/test1.txt",
+                       "$base/subdir2/subdir/test2.txt",
+                       "$base/subdir2/subdir/test3.txt",
+                       "$base/subdir2/subdir/test4.txt",
+                       "$base/subdir2/subdir/test5.txt",
+                       "$base/subdir2/subdir/sub",
+                       "$base/subdir2/subdir/sub/test0.txt",
+                       "$base/subdir2/subdir/sub/120-px-file.txt",
                ];
 
                for ( $i = 0; $i < 25; $i++ ) {
index e20cf94..d7dc411 100644 (file)
@@ -3,9 +3,8 @@
 /**
  * @covers HTMLForm
  *
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
  * @author Gergő Tisza
- * @author Thiemo Mättig
  */
 class HTMLFormTest extends MediaWikiTestCase {
 
@@ -54,4 +53,11 @@ class HTMLFormTest extends MediaWikiTestCase {
                $this->assertContains( ' autocomplete="off"', $form->wrapForm( '' ) );
        }
 
+       public function testGetPreText() {
+               $preText = 'TEST';
+               $form = $this->newInstance();
+               $form->setPreText( $preText );
+               $this->assertSame( $preText, $form->getPreText() );
+       }
+
 }
index 0d41c52..947be75 100644 (file)
@@ -56,8 +56,6 @@ class InterwikiTest extends MediaWikiTestCase {
        }
 
        public function testDatabaseStorage() {
-               $this->markTestSkipped( 'Needs I37b8e8018b3 <https://gerrit.wikimedia.org/r/#/c/270555/>' );
-
                // NOTE: database setup is expensive, so we only do
                //  it once and run all the tests in one go.
                $dewiki = [
@@ -115,7 +113,7 @@ class InterwikiTest extends MediaWikiTestCase {
                $this->assertSame( true, $interwiki->isLocal(), 'isLocal' );
                $this->assertSame( false, $interwiki->isTranscludable(), 'isTranscludable' );
 
-               Interwiki::invalidateCache( 'de' );
+               $interwikiLookup->invalidateCache( 'de' );
                $this->assertNotSame( $interwiki, $interwikiLookup->fetch( 'de' ), 'invalidate cache' );
        }
 
index bf8603d..b2e7ea4 100644 (file)
@@ -5,7 +5,7 @@
  *
  * @group JobQueue
  *
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
  * @author Thiemo Kreuz
  */
 class JobQueueMemoryTest extends PHPUnit\Framework\TestCase {
index 5960a16..1f73324 100644 (file)
@@ -6,7 +6,7 @@
  * @group JobQueue
  * @group Database
  *
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
  * @author Addshore
  */
 class CategoryMembershipChangeJobTest extends MediaWikiTestCase {
index 6ae7d60..27cae8a 100644 (file)
@@ -7,7 +7,7 @@ use MediaWiki\MediaWikiServices;
  * @group JobQueue
  * @group Database
  *
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
  * @author Addshore
  */
 class ClearUserWatchlistJobTest extends MediaWikiTestCase {
index 354dae2..04aecc9 100644 (file)
@@ -19,6 +19,30 @@ class CSSMinTest extends MediaWikiTestCase {
                ] );
        }
 
+       /**
+        * @dataProvider providesReferencedFiles
+        * @covers CSSMin::getLocalFileReferences
+        */
+       public function testGetLocalFileReferences( $input, $expected ) {
+               $output = CSSMin::getLocalFileReferences( $input, '/' );
+               $this->assertEquals(
+                       $expected,
+                       $output,
+                       'getLocalFileReferences() must find the local file properly'
+               );
+       }
+
+       public static function providesReferencedFiles() {
+               // input, array of expected local file names
+               return [
+                       [ 'url("//example.org")', [] ],
+                       [ 'url("https://example.org")', [] ],
+                       [ 'url("#default#")', [] ],
+                       [ 'url("WikiFont-Glyphs.svg#wikiglyph")', [ '/WikiFont-Glyphs.svg' ] ],
+                       [ 'url("#some-anchor")', [] ],
+               ];
+       }
+
        /**
         * @dataProvider provideSerializeStringValue
         * @covers CSSMin::serializeStringValue
@@ -35,7 +59,7 @@ class CSSMinTest extends MediaWikiTestCase {
        public static function provideSerializeStringValue() {
                return [
                        [ 'Hello World!', '"Hello World!"' ],
-                       [ "Null\0Null", "\"Null\xEF\xBF\xBDNull\"" ],
+                       [ "Null\0Null", "\"Null\u{FFFD}Null\"" ],
                        [ '"', '"\\""' ],
                        [ "'", '"\'"' ],
                        [ "\\", '"\\\\"' ],
@@ -43,9 +67,9 @@ class CSSMinTest extends MediaWikiTestCase {
                        [ "Space  tab \t space", '"Space  tab \\9  space"' ],
                        [ "Line\nfeed", '"Line\\a feed"' ],
                        [ "Return\rreturn", '"Return\\d return"' ],
-                       [ "Next\xc2\x85line", "\"Next\xc2\x85line\"" ],
+                       [ "Next\u{0085}line", "\"Next\u{0085}line\"" ],
                        [ "Del\x7fDel", '"Del\\7f Del"' ],
-                       [ "nb\xc2\xa0sp", "\"nb\xc2\xa0sp\"" ],
+                       [ "nb\u{00A0}sp", "\"nb\u{00A0}sp\"" ],
                        [ "AMP&amp;AMP", "\"AMP&amp;AMP\"" ],
                        [ '!"#$%&\'()*+,-./0123456789:;<=>?', '"!\\"#$%&\'()*+,-./0123456789:;<=>?"' ],
                        [ '@[\\]^_`{|}~', '"@[\\\\]^_`{|}~"' ],
@@ -292,6 +316,16 @@ class CSSMinTest extends MediaWikiTestCase {
                                [ 'foo { behavior: url(#default#bar); }', false, '/w/', false ],
                                'foo { behavior: url("#default#bar"); }',
                        ],
+                       [
+                               'Keeps anchors',
+                               [ 'url(#other)', false, '/', false ],
+                               'url("#other")'
+                       ],
+                       [
+                               'Keeps anchors after a path',
+                               [ 'url(images/file.svg#id)', false, '/', false ],
+                               'url("/images/file.svg#id")'
+                       ],
                ];
        }
 
diff --git a/tests/phpunit/includes/libs/EasyDeflateTest.php b/tests/phpunit/includes/libs/EasyDeflateTest.php
new file mode 100644 (file)
index 0000000..da39d48
--- /dev/null
@@ -0,0 +1,64 @@
+<?php
+/**
+ * Copyright (C) 2018 Kunal Mehta <legoktm@member.fsf.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.
+ *
+ */
+
+/**
+ * @covers EasyDeflate
+ */
+class EasyDeflateTest extends PHPUnit\Framework\TestCase {
+
+       public function provideIsDeflated() {
+               return [
+                       [ 'rawdeflate,S8vPT0osAgA=', true ],
+                       [ 'abcdefghijklmnopqrstuvwxyz', false ],
+               ];
+       }
+
+       /**
+        * @dataProvider provideIsDeflated
+        */
+       public function testIsDeflated( $data, $expected ) {
+               $actual = EasyDeflate::isDeflated( $data );
+               $this->assertSame( $expected, $actual );
+       }
+
+       public function provideInflate() {
+               return [
+                       [ 'rawdeflate,S8vPT0osAgA=', true, 'foobar' ],
+                       // Fails base64_decode
+                       [ 'rawdeflate,🌻', false, 'easydeflate-invaliddeflate' ],
+                       // Fails gzinflate
+                       [ 'rawdeflate,S8vPT0dfdAgB=', false, 'easydeflate-invaliddeflate' ],
+               ];
+       }
+
+       /**
+        * @dataProvider provideInflate
+        */
+       public function testInflate( $data, $ok, $value ) {
+               $actual = EasyDeflate::inflate( $data );
+               if ( $ok ) {
+                       $this->assertTrue( $actual->isOK() );
+                       $this->assertSame( $value, $actual->getValue() );
+               } else {
+                       $this->assertFalse( $actual->isOK() );
+                       $this->assertTrue( $actual->hasMessage( $value ) );
+               }
+       }
+}
index ba28828..acaeb02 100644 (file)
@@ -2,44 +2,72 @@
 
 /**
  * @group HashRing
+ * @covers HashRing
  */
 class HashRingTest extends PHPUnit\Framework\TestCase {
 
        use MediaWikiCoversValidator;
 
-       /**
-        * @covers HashRing
-        */
-       public function testHashRing() {
-               $ring = new HashRing( [ 's1' => 1, 's2' => 1, 's3' => 2, 's4' => 2, 's5' => 2, 's6' => 3 ] );
+       public function testHashRingSerialize() {
+               $map = [ 's1' => 3, 's2' => 10, 's3' => 2, 's4' => 10, 's5' => 2, 's6' => 3 ];
+               $ring = new HashRing( $map, 'md5' );
+
+               $serialized = serialize( $ring );
+               $ringRemade = unserialize( $serialized );
+
+               for ( $i = 0; $i < 100; $i++ ) {
+                       $this->assertEquals(
+                               $ring->getLocation( "hello$i" ),
+                               $ringRemade->getLocation( "hello$i" ),
+                               'Items placed at proper locations'
+                       );
+               }
+       }
+
+       public function testHashRingMapping() {
+               // SHA-1 based and weighted
+               $ring = new HashRing(
+                       [ 's1' => 1, 's2' => 1, 's3' => 2, 's4' => 2, 's5' => 2, 's6' => 3, 's7' => 0 ],
+                       'sha1'
+               );
+
+               $this->assertEquals(
+                       [ 's1' => 1, 's2' => 1, 's3' => 2, 's4' => 2, 's5' => 2, 's6' => 3 ],
+                       $ring->getLocationWeights(),
+                       'Normalized location weights'
+               );
 
                $locations = [];
-               for ( $i = 0; $i < 20; $i++ ) {
+               for ( $i = 0; $i < 25; $i++ ) {
                        $locations[ "hello$i"] = $ring->getLocation( "hello$i" );
                }
                $expectedLocations = [
-                       "hello0" => "s5",
+                       "hello0" => "s4",
                        "hello1" => "s6",
-                       "hello2" => "s2",
-                       "hello3" => "s5",
+                       "hello2" => "s3",
+                       "hello3" => "s6",
                        "hello4" => "s6",
                        "hello5" => "s4",
-                       "hello6" => "s5",
+                       "hello6" => "s3",
                        "hello7" => "s4",
-                       "hello8" => "s5",
-                       "hello9" => "s5",
+                       "hello8" => "s3",
+                       "hello9" => "s3",
                        "hello10" => "s3",
-                       "hello11" => "s6",
-                       "hello12" => "s1",
-                       "hello13" => "s3",
-                       "hello14" => "s3",
+                       "hello11" => "s5",
+                       "hello12" => "s4",
+                       "hello13" => "s5",
+                       "hello14" => "s2",
                        "hello15" => "s5",
-                       "hello16" => "s4",
-                       "hello17" => "s6",
-                       "hello18" => "s6",
-                       "hello19" => "s3"
+                       "hello16" => "s6",
+                       "hello17" => "s5",
+                       "hello18" => "s1",
+                       "hello19" => "s1",
+                       "hello20" => "s6",
+                       "hello21" => "s5",
+                       "hello22" => "s3",
+                       "hello23" => "s4",
+                       "hello24" => "s1"
                ];
-
                $this->assertEquals( $expectedLocations, $locations, 'Items placed at proper locations' );
 
                $locations = [];
@@ -48,12 +76,252 @@ class HashRingTest extends PHPUnit\Framework\TestCase {
                }
 
                $expectedLocations = [
-                       "hello0" => [ "s5", "s6" ],
-                       "hello1" => [ "s6", "s4" ],
-                       "hello2" => [ "s2", "s1" ],
-                       "hello3" => [ "s5", "s6" ],
-                       "hello4" => [ "s6", "s4" ],
+                       "hello0" => [ "s4", "s5" ],
+                       "hello1" => [ "s6", "s5" ],
+                       "hello2" => [ "s3", "s1" ],
+                       "hello3" => [ "s6", "s5" ],
+                       "hello4" => [ "s6", "s3" ],
                ];
                $this->assertEquals( $expectedLocations, $locations, 'Items placed at proper locations' );
        }
+
+       /**
+        * @dataProvider providor_getHashLocationWeights
+        */
+       public function testHashRingRatios( $locations, $expectedHits ) {
+               $ring = new HashRing( $locations, 'whirlpool' );
+
+               $locationStats = array_fill_keys( array_keys( $locations ), 0 );
+               for ( $i = 0; $i < 10000; ++$i ) {
+                       ++$locationStats[$ring->getLocation( "key-$i" )];
+               }
+               $this->assertEquals( $expectedHits, $locationStats );
+       }
+
+       public static function providor_getHashLocationWeights() {
+               return [
+                       [
+                               [ 'big' => 10, 'medium' => 5, 'small' => 1 ],
+                               [ 'big' => 6037, 'medium' => 3314, 'small' => 649 ]
+                       ]
+               ];
+       }
+
+       /**
+        * @dataProvider providor_getHashLocationWeights2
+        */
+       public function testHashRingRatios2( $locations, $expected ) {
+               $ring = new HashRing( $locations, 'sha1' );
+               $locationStats = array_fill_keys( array_keys( $locations ), 0 );
+               for ( $i = 0; $i < 1000; ++$i ) {
+                       foreach ( $ring->getLocations( "key-$i", 3 ) as $location ) {
+                               ++$locationStats[$location];
+                       }
+               }
+               $this->assertEquals( $expected, $locationStats );
+       }
+
+       public static function providor_getHashLocationWeights2() {
+               return [
+                       [
+                               [ 'big1' => 10, 'big2' => 10, 'big3' => 10, 'small1' => 1, 'small2' => 1 ],
+                               [ 'big1' => 929, 'big2' => 899, 'big3' => 887, 'small1' => 143, 'small2' => 142 ]
+                       ]
+               ];
+       }
+
+       public function testHashRingEjection() {
+               $map = [ 's1' => 5, 's2' => 5, 's3' => 10, 's4' => 10, 's5' => 5, 's6' => 5 ];
+               $ring = new HashRing( $map, 'md5' );
+
+               $ring->ejectFromLiveRing( 's3', 30 );
+               $ring->ejectFromLiveRing( 's6', 15 );
+
+               $this->assertEquals(
+                       [ 's1' => 5, 's2' => 5, 's4' => 10, 's5' => 5 ],
+                       $ring->getLiveLocationWeights(),
+                       'Live location weights'
+               );
+
+               for ( $i = 0; $i < 100; ++$i ) {
+                       $key = "key-$i";
+
+                       $this->assertNotEquals( 's3', $ring->getLiveLocation( $key ), 'ejected' );
+                       $this->assertNotEquals( 's6', $ring->getLiveLocation( $key ), 'ejected' );
+
+                       if ( !in_array( $ring->getLocation( $key ), [ 's3', 's6' ], true ) ) {
+                               $this->assertEquals(
+                                       $ring->getLocation( $key ),
+                                       $ring->getLiveLocation( $key ),
+                                       "Live ring otherwise matches (#$i)"
+                               );
+                               $this->assertEquals(
+                                       $ring->getLocations( $key, 1 ),
+                                       $ring->getLiveLocations( $key, 1 ),
+                                       "Live ring otherwise matches (#$i)"
+                               );
+                       }
+               }
+       }
+
+       public function testHashRingCollision() {
+               $ring1 = new HashRing( [ 0 => 1, 6497 => 1 ] );
+               $ring2 = new HashRing( [ 6497 => 1, 0 => 1 ] );
+
+               for ( $i = 0; $i < 100; ++$i ) {
+                       $this->assertEquals( $ring1->getLocation( $i ), $ring2->getLocation( $i ) );
+               }
+       }
+
+       public function testHashRingKetamaMode() {
+               // Same as https://github.com/RJ/ketama/blob/master/ketama.servers
+               $map = [
+                       '10.0.1.1:11211' => 600,
+                       '10.0.1.2:11211' => 300,
+                       '10.0.1.3:11211' => 200,
+                       '10.0.1.4:11211' => 350,
+                       '10.0.1.5:11211' => 1000,
+                       '10.0.1.6:11211' => 800,
+                       '10.0.1.7:11211' => 950,
+                       '10.0.1.8:11211' => 100
+               ];
+               $ring = new HashRing( $map, 'md5' );
+               $wrapper = \Wikimedia\TestingAccessWrapper::newFromObject( $ring );
+
+               $ketama_test = function ( $count ) use ( $wrapper ) {
+                       $baseRing = $wrapper->baseRing;
+
+                       $lines = [];
+                       for ( $key = 0; $key < $count; ++$key ) {
+                               $location = $wrapper->getLocation( $key );
+
+                               $itemPos = $wrapper->getItemPosition( $key );
+                               $nodeIndex = $wrapper->findNodeIndexForPosition( $itemPos, $baseRing );
+                               $nodePos = $baseRing[$nodeIndex][HashRing::KEY_POS];
+
+                               $lines[] = sprintf( "%u %u %s\n", $itemPos, $nodePos, $location );
+                       }
+
+                       return "\n" . implode( '', $lines );
+               };
+
+               // Known correct values generated from C code:
+               // https://github.com/RJ/ketama/blob/master/libketama/ketama_test.c
+               $expected = <<<EOT
+
+2216742351 2217271743 10.0.1.1:11211
+943901380 949045552 10.0.1.5:11211
+2373066440 2374693370 10.0.1.6:11211
+2127088620 2130338203 10.0.1.6:11211
+2046197672 2051996197 10.0.1.7:11211
+2134629092 2135172435 10.0.1.1:11211
+470382870 472541453 10.0.1.7:11211
+1608782991 1609789509 10.0.1.3:11211
+2516119753 2520092206 10.0.1.2:11211
+3465331781 3466294492 10.0.1.4:11211
+1749342675 1753760600 10.0.1.5:11211
+1136464485 1137779711 10.0.1.1:11211
+3620997826 3621580689 10.0.1.7:11211
+283385029 285581365 10.0.1.6:11211
+2300818346 2302165654 10.0.1.5:11211
+2132603803 2134614475 10.0.1.8:11211
+2962705863 2969767984 10.0.1.2:11211
+786427760 786565633 10.0.1.5:11211
+4095887727 4096760944 10.0.1.6:11211
+2906459679 2906987515 10.0.1.6:11211
+137884056 138922607 10.0.1.4:11211
+81549628 82491298 10.0.1.6:11211
+3530020790 3530525869 10.0.1.6:11211
+4231817527 4234960467 10.0.1.7:11211
+2011099423 2014738083 10.0.1.7:11211
+107620750 120968799 10.0.1.6:11211
+3979113294 3981926993 10.0.1.4:11211
+273671938 276355738 10.0.1.4:11211
+4032816947 4033300359 10.0.1.5:11211
+464234862 466093615 10.0.1.1:11211
+3007059764 3007671127 10.0.1.5:11211
+542337729 542491760 10.0.1.7:11211
+4040385635 4044064727 10.0.1.5:11211
+3319802648 3320661601 10.0.1.7:11211
+1032153571 1035085391 10.0.1.1:11211
+3543939100 3545608820 10.0.1.5:11211
+3876899353 3885324049 10.0.1.2:11211
+3771318181 3773259708 10.0.1.8:11211
+3457906597 3459285639 10.0.1.5:11211
+3028975062 3031083168 10.0.1.7:11211
+244467158 250943416 10.0.1.5:11211
+1604785716 1609789509 10.0.1.3:11211
+3905343649 3905751132 10.0.1.1:11211
+1713497623 1725056963 10.0.1.5:11211
+1668356087 1668827816 10.0.1.5:11211
+3427369836 3438933308 10.0.1.1:11211
+2515850457 2520092206 10.0.1.2:11211
+3886138983 3887390208 10.0.1.1:11211
+4019334756 4023153300 10.0.1.8:11211
+1170561012 1170785765 10.0.1.7:11211
+1841809344 1848425105 10.0.1.6:11211
+973223976 973369204 10.0.1.1:11211
+358093210 359562433 10.0.1.6:11211
+378350808 380841931 10.0.1.5:11211
+4008477862 4012085095 10.0.1.7:11211
+1027226549 1028630030 10.0.1.6:11211
+2386583967 2387706118 10.0.1.1:11211
+522892146 524831677 10.0.1.7:11211
+3779194982 3788912803 10.0.1.5:11211
+3764731657 3771312500 10.0.1.7:11211
+184756999 187529415 10.0.1.6:11211
+838351231 845886003 10.0.1.3:11211
+2827220548 2828019973 10.0.1.6:11211
+3604721411 3607668249 10.0.1.6:11211
+472866282 475506254 10.0.1.5:11211
+2752268796 2754833471 10.0.1.5:11211
+1791464754 1795042583 10.0.1.7:11211
+3029359475 3031083168 10.0.1.7:11211
+3633378211 3639985542 10.0.1.6:11211
+3148267284 3149217023 10.0.1.6:11211
+163887996 166705043 10.0.1.7:11211
+3642803426 3649125922 10.0.1.7:11211
+3901799218 3902199881 10.0.1.7:11211
+418045394 425867331 10.0.1.6:11211
+346775981 348578169 10.0.1.6:11211
+368352208 372224616 10.0.1.7:11211
+2643711995 2644259911 10.0.1.5:11211
+2032983336 2033860601 10.0.1.6:11211
+3567842357 3572867530 10.0.1.2:11211
+1024982737 1028630030 10.0.1.6:11211
+933966832 938106828 10.0.1.7:11211
+2102520899 2103402846 10.0.1.7:11211
+3537205399 3538094881 10.0.1.7:11211
+2311233534 2314593262 10.0.1.1:11211
+2500514664 2503565236 10.0.1.7:11211
+1091958846 1093484995 10.0.1.6:11211
+3984972691 3987453644 10.0.1.1:11211
+2669994439 2670911201 10.0.1.4:11211
+2846111786 2846115813 10.0.1.5:11211
+1805010806 1808593732 10.0.1.8:11211
+1587024774 1587746378 10.0.1.5:11211
+3214549588 3215619351 10.0.1.2:11211
+1965214866 1970922428 10.0.1.7:11211
+1038671000 1040777775 10.0.1.7:11211
+820820468 823114475 10.0.1.6:11211
+2722835329 2723166435 10.0.1.5:11211
+1602053414 1604196066 10.0.1.5:11211
+1330835426 1335097278 10.0.1.5:11211
+556547565 557075710 10.0.1.4:11211
+2977587884 2978402952 10.0.1.1:11211
+
+EOT;
+
+               $this->assertEquals( $expected, $ketama_test( 100 ), 'Ketama mode (diff check)' );
+
+               // Hash of known correct values from C code
+               $this->assertEquals(
+                       'c69ac9eb7a8a630c0cded201cefeaace',
+                       md5( $ketama_test( 1e5 ) ),
+                       'Ketama mode (large, MD5 check)'
+               );
+
+               // Slower, full upstream MD5 check, manually verified 3/21/2018
+               // $this->assertEquals( '5672b131391f5aa2b280936aec1eea74', md5( $ketama_test( 1e6 ) ) );
+       }
 }
index 03c7b0c..9ec660e 100644 (file)
 
 /**
  * Tests for IEUrlExtension::findIE6Extension
- * @todo tests below for findIE6Extension should be split into...
- *    ...a dataprovider and test method.
  */
 class IEUrlExtensionTest extends PHPUnit\Framework\TestCase {
 
        use MediaWikiCoversValidator;
 
-       /**
-        * @covers IEUrlExtension::findIE6Extension
-        */
-       public function testSimple() {
-               $this->assertEquals(
-                       'y',
-                       IEUrlExtension::findIE6Extension( 'x.y' ),
-                       'Simple extension'
-               );
-       }
-
-       /**
-        * @covers IEUrlExtension::findIE6Extension
-        */
-       public function testSimpleNoExt() {
-               $this->assertEquals(
-                       '',
-                       IEUrlExtension::findIE6Extension( 'x' ),
-                       'No extension'
-               );
-       }
-
-       /**
-        * @covers IEUrlExtension::findIE6Extension
-        */
-       public function testEmpty() {
-               $this->assertEquals(
-                       '',
-                       IEUrlExtension::findIE6Extension( '' ),
-                       'Empty string'
-               );
-       }
-
-       /**
-        * @covers IEUrlExtension::findIE6Extension
-        */
-       public function testQuestionMark() {
-               $this->assertEquals(
-                       '',
-                       IEUrlExtension::findIE6Extension( '?' ),
-                       'Question mark only'
-               );
-       }
-
-       /**
-        * @covers IEUrlExtension::findIE6Extension
-        */
-       public function testExtQuestionMark() {
-               $this->assertEquals(
-                       'x',
-                       IEUrlExtension::findIE6Extension( '.x?' ),
-                       'Extension then question mark'
-               );
-       }
-
-       /**
-        * @covers IEUrlExtension::findIE6Extension
-        */
-       public function testQuestionMarkExt() {
-               $this->assertEquals(
-                       'x',
-                       IEUrlExtension::findIE6Extension( '?.x' ),
-                       'Question mark then extension'
-               );
-       }
-
-       /**
-        * @covers IEUrlExtension::findIE6Extension
-        */
-       public function testInvalidChar() {
-               $this->assertEquals(
-                       '',
-                       IEUrlExtension::findIE6Extension( '.x*' ),
-                       'Extension with invalid character'
-               );
-       }
-
-       /**
-        * @covers IEUrlExtension::findIE6Extension
-        */
-       public function testInvalidCharThenExtension() {
-               $this->assertEquals(
-                       'x',
-                       IEUrlExtension::findIE6Extension( '*.x' ),
-                       'Invalid character followed by an extension'
-               );
-       }
-
-       /**
-        * @covers IEUrlExtension::findIE6Extension
-        */
-       public function testMultipleQuestionMarks() {
-               $this->assertEquals(
-                       'c',
-                       IEUrlExtension::findIE6Extension( 'a?b?.c?.d?e?f' ),
-                       'Multiple question marks'
-               );
-       }
-
-       /**
-        * @covers IEUrlExtension::findIE6Extension
-        */
-       public function testExeException() {
-               $this->assertEquals(
-                       'd',
-                       IEUrlExtension::findIE6Extension( 'a?b?.exe?.d?.e' ),
-                       '.exe exception'
-               );
-       }
-
-       /**
-        * @covers IEUrlExtension::findIE6Extension
-        */
-       public function testExeException2() {
-               $this->assertEquals(
-                       'exe',
-                       IEUrlExtension::findIE6Extension( 'a?b?.exe' ),
-                       '.exe exception 2'
-               );
-       }
-
-       /**
-        * @covers IEUrlExtension::findIE6Extension
-        */
-       public function testHash() {
-               $this->assertEquals(
-                       '',
-                       IEUrlExtension::findIE6Extension( 'a#b.c' ),
-                       'Hash character preceding extension'
-               );
-       }
-
-       /**
-        * @covers IEUrlExtension::findIE6Extension
-        */
-       public function testHash2() {
-               $this->assertEquals(
-                       '',
-                       IEUrlExtension::findIE6Extension( 'a?#b.c' ),
-                       'Hash character preceding extension 2'
-               );
-       }
-
-       /**
-        * @covers IEUrlExtension::findIE6Extension
-        */
-       public function testDotAtEnd() {
-               $this->assertEquals(
-                       '',
-                       IEUrlExtension::findIE6Extension( '.' ),
-                       'Dot at end of string'
-               );
-       }
-
-       /**
-        * @covers IEUrlExtension::findIE6Extension
-        */
-       public function testTwoDots() {
-               $this->assertEquals(
-                       'z',
-                       IEUrlExtension::findIE6Extension( 'x.y.z' ),
-                       'Two dots'
-               );
-       }
-
-       /**
-        * @covers IEUrlExtension::findIE6Extension
-        */
-       public function testScriptQuery() {
-               $this->assertEquals(
-                       'php',
-                       IEUrlExtension::findIE6Extension( 'example.php?foo=a&bar=b' ),
-                       'Script with query'
-               );
-       }
-
-       /**
-        * @covers IEUrlExtension::findIE6Extension
-        */
-       public function testEscapedScriptQuery() {
-               $this->assertEquals(
-                       '',
-                       IEUrlExtension::findIE6Extension( 'example%2Ephp?foo=a&bar=b' ),
-                       'Script with urlencoded dot and query'
-               );
-       }
-
-       /**
-        * @covers IEUrlExtension::findIE6Extension
-        */
-       public function testEscapedScriptQueryDot() {
-               $this->assertEquals(
-                       'y',
-                       IEUrlExtension::findIE6Extension( 'example%2Ephp?foo=a.x&bar=b.y' ),
-                       'Script with urlencoded dot and query with dot'
+       public function provideFindIE6Extension() {
+               return [
+                       // url, expected, message
+                       [ 'x.y', 'y', 'Simple extension' ],
+                       [ 'x', '', 'No extension' ],
+                       [ '', '', 'Empty string' ],
+                       [ '?', '', 'Question mark only' ],
+                       [ '.x?', 'x', 'Extension then question mark' ],
+                       [ '?.x', 'x', 'Question mark then extension' ],
+                       [ '.x*', '', 'Extension with invalid character' ],
+                       [ '*.x', 'x', 'Invalid character followed by an extension' ],
+                       [ 'a?b?.c?.d?e?f', 'c', 'Multiple question marks' ],
+                       [ 'a?b?.exe?.d?.e', 'd', '.exe exception' ],
+                       [ 'a?b?.exe', 'exe', '.exe exception 2' ],
+                       [ 'a#b.c', '', 'Hash character preceding extension' ],
+                       [ 'a?#b.c', '', 'Hash character preceding extension 2' ],
+                       [ '.', '', 'Dot at end of string' ],
+                       [ 'x.y.z', 'z', 'Two dots' ],
+                       [ 'example.php?foo=a&bar=b', 'php', 'Script with query' ],
+                       [ 'example%2Ephp?foo=a&bar=b', '', 'Script with urlencoded dot and query' ],
+                       [ 'example%2Ephp?foo=a.x&bar=b.y', 'y', 'Script with urlencoded dot and query with dot' ],
+               ];
+       }
+
+       /**
+        * @covers IEUrlExtension::findIE6Extension
+        * @dataProvider provideFindIE6Extension
+        */
+       public function testFindIE6Extension( $url, $expected, $message ) {
+               $this->assertEquals(
+                       $expected,
+                       IEUrlExtension::findIE6Extension( $url ),
+                       $message
                );
        }
 }
index 9702c82..9ec53c0 100644 (file)
@@ -325,6 +325,7 @@ class IPTest extends PHPUnit\Framework\TestCase {
                        [ '0.0.0.0', '0.0.0.0' ],
                        [ '0.0.0.0', '00.00.00.00' ],
                        [ '0.0.0.0', '000.000.000.000' ],
+                       [ '0.0.0.0/24', '000.000.000.000/24' ],
                        [ '141.0.11.253', '141.000.011.253' ],
                        [ '1.2.4.5', '1.2.4.5' ],
                        [ '1.2.4.5', '01.02.04.05' ],
index 2a962b7..a06ef62 100644 (file)
@@ -11,11 +11,14 @@ class MapCacheLRUTest extends PHPUnit\Framework\TestCase {
         * @covers MapCacheLRU::toArray()
         * @covers MapCacheLRU::getAllKeys()
         * @covers MapCacheLRU::clear()
+        * @covers MapCacheLRU::getMaxSize()
+        * @covers MapCacheLRU::setMaxSize()
         */
        function testArrayConversion() {
                $raw = [ 'd' => 4, 'c' => 3, 'b' => 2, 'a' => 1 ];
                $cache = MapCacheLRU::newFromArray( $raw, 3 );
 
+               $this->assertEquals( 3, $cache->getMaxSize() );
                $this->assertSame( true, $cache->has( 'a' ) );
                $this->assertSame( true, $cache->has( 'b' ) );
                $this->assertSame( true, $cache->has( 'c' ) );
@@ -43,6 +46,27 @@ class MapCacheLRUTest extends PHPUnit\Framework\TestCase {
                        [],
                        $cache->toArray()
                );
+
+               $cache = MapCacheLRU::newFromArray( [ 'd' => 4, 'c' => 3, 'b' => 2, 'a' => 1 ], 4 );
+               $cache->setMaxSize( 3 );
+               $this->assertSame(
+                       [ 'c' => 3, 'b' => 2, 'a' => 1 ],
+                       $cache->toArray()
+               );
+       }
+
+       /**
+        * @covers MapCacheLRU::serialize()
+        * @covers MapCacheLRU::unserialize()
+        */
+       function testSerialize() {
+               $cache = MapCacheLRU::newFromArray( [ 'd' => 4, 'c' => 3, 'b' => 2, 'a' => 1 ], 10 );
+               $string = serialize( $cache );
+               $ncache = unserialize( $string );
+               $this->assertSame(
+                       [ 'd' => 4, 'c' => 3, 'b' => 2, 'a' => 1 ],
+                       $ncache->toArray()
+               );
        }
 
        /**
@@ -114,4 +138,80 @@ class MapCacheLRUTest extends PHPUnit\Framework\TestCase {
                        $cache->toArray()
                );
        }
+
+       /**
+        * @covers MapCacheLRU::has()
+        * @covers MapCacheLRU::get()
+        * @covers MapCacheLRU::set()
+        */
+       public function testExpiry() {
+               $raw = [ 'a' => 1, 'b' => 2, 'c' => 3 ];
+               $cache = MapCacheLRU::newFromArray( $raw, 3 );
+
+               $now = microtime( true );
+               $cache->setMockTime( $now );
+
+               $cache->set( 'd', 'xxx' );
+               $this->assertTrue( $cache->has( 'd', 30 ) );
+               $this->assertEquals( 'xxx', $cache->get( 'd' ) );
+
+               $now += 29;
+               $this->assertTrue( $cache->has( 'd', 30 ) );
+               $this->assertEquals( 'xxx', $cache->get( 'd' ) );
+               $this->assertEquals( 'xxx', $cache->get( 'd', 30 ) );
+
+               $now += 1.5;
+               $this->assertFalse( $cache->has( 'd', 30 ) );
+               $this->assertEquals( 'xxx', $cache->get( 'd' ) );
+               $this->assertNull( $cache->get( 'd', 30 ) );
+       }
+
+       /**
+        * @covers MapCacheLRU::hasField()
+        * @covers MapCacheLRU::getField()
+        * @covers MapCacheLRU::setField()
+        */
+       public function testFields() {
+               $raw = [ 'a' => 1, 'b' => 2, 'c' => 3 ];
+               $cache = MapCacheLRU::newFromArray( $raw, 3 );
+
+               $now = microtime( true );
+               $cache->setMockTime( $now );
+
+               $cache->setField( 'PMs', 'Tony Blair', 'Labour' );
+               $cache->setField( 'PMs', 'Margaret Thatcher', 'Tory' );
+               $this->assertTrue( $cache->hasField( 'PMs', 'Tony Blair', 30 ) );
+               $this->assertEquals( 'Labour', $cache->getField( 'PMs', 'Tony Blair' ) );
+               $this->assertTrue( $cache->hasField( 'PMs', 'Tony Blair', 30 ) );
+
+               $now += 29;
+               $this->assertTrue( $cache->hasField( 'PMs', 'Tony Blair', 30 ) );
+               $this->assertEquals( 'Labour', $cache->getField( 'PMs', 'Tony Blair' ) );
+               $this->assertEquals( 'Labour', $cache->getField( 'PMs', 'Tony Blair', 30 ) );
+
+               $now += 1.5;
+               $this->assertFalse( $cache->hasField( 'PMs', 'Tony Blair', 30 ) );
+               $this->assertEquals( 'Labour', $cache->getField( 'PMs', 'Tony Blair' ) );
+               $this->assertNull( $cache->getField( 'PMs', 'Tony Blair', 30 ) );
+
+               $this->assertEquals(
+                       [ 'Tony Blair' => 'Labour', 'Margaret Thatcher' => 'Tory' ],
+                       $cache->get( 'PMs' )
+               );
+
+               $cache->set( 'MPs', [
+                       'Edwina Currie' => 1983,
+                       'Neil Kinnock' => 1970
+               ] );
+               $this->assertEquals(
+                       [
+                               'Edwina Currie' => 1983,
+                               'Neil Kinnock' => 1970
+                       ],
+                       $cache->get( 'MPs' )
+               );
+
+               $this->assertEquals( 1983, $cache->getField( 'MPs', 'Edwina Currie' ) );
+               $this->assertEquals( 1970, $cache->getField( 'MPs', 'Neil Kinnock' ) );
+       }
 }
index c8940e5..c9fa320 100644 (file)
@@ -18,7 +18,7 @@ class ProcessCacheLRUTest extends PHPUnit\Framework\TestCase {
         * Compare against an array so we get the cache content difference.
         */
        protected function assertCacheEmpty( $cache, $msg = 'Cache should be empty' ) {
-               $this->assertAttributeEquals( [], 'cache', $cache, $msg );
+               $this->assertEquals( 0, $cache->getEntriesCount(), $msg );
        }
 
        /**
@@ -256,13 +256,11 @@ class ProcessCacheLRUTest extends PHPUnit\Framework\TestCase {
  * Overrides some ProcessCacheLRU methods and properties accessibility.
  */
 class ProcessCacheLRUTestable extends ProcessCacheLRU {
-       public $cache = [];
-
        public function getCache() {
-               return $this->cache;
+               return $this->cache->toArray();
        }
 
        public function getEntriesCount() {
-               return count( $this->cache );
+               return count( $this->cache->toArray() );
        }
 }
index 0ea1328..ccad4a4 100644 (file)
@@ -37,4 +37,77 @@ class XhprofTest extends PHPUnit\Framework\TestCase {
                $enabled->setValue( true );
                $xhprof->getMethod( 'enable' )->invoke( null );
        }
+
+       /**
+        * callAny() calls the first function of the list.
+        *
+        * @covers Xhprof::callAny
+        * @dataProvider provideCallAny
+        */
+       public function testCallAny( array $functions, array $args, $expectedResult ) {
+               $xhprof = new ReflectionClass( Xhprof::class );
+               $callAny = $xhprof->getMethod( 'callAny' );
+               $callAny->setAccessible( true );
+
+               $this->assertEquals( $expectedResult,
+                       $callAny->invoke( null, $functions, $args ) );
+       }
+
+       /**
+        * Data provider for testCallAny().
+       */
+       public function provideCallAny() {
+               return [
+                       [
+                               [ 'wfTestCallAny_func1', 'wfTestCallAny_func2', 'wfTestCallAny_func3' ],
+                               [ 3, 4 ],
+                               12
+                       ],
+                       [
+                               [ 'wfTestCallAny_nosuchfunc1', 'wfTestCallAny_func2', 'wfTestCallAny_func3' ],
+                               [ 3, 4 ],
+                               7
+                       ],
+                       [
+                               [ 'wfTestCallAny_nosuchfunc1', 'wfTestCallAny_nosuchfunc2', 'wfTestCallAny_func3' ],
+                               [ 3, 4 ],
+                               -1
+                       ]
+
+               ];
+       }
+
+       /**
+        * callAny() throws an exception when all functions are unavailable.
+        *
+        * @expectedException        Exception
+        * @expectedExceptionMessage Neither xhprof nor tideways are installed
+        * @covers Xhprof::callAny
+        */
+       public function testCallAnyNoneAvailable() {
+               $xhprof = new ReflectionClass( Xhprof::class );
+               $callAny = $xhprof->getMethod( 'callAny' );
+               $callAny->setAccessible( true );
+
+               $callAny->invoke( $xhprof, [
+                       'wfTestCallAny_nosuchfunc1',
+                       'wfTestCallAny_nosuchfunc2',
+                       'wfTestCallAny_nosuchfunc3'
+               ] );
+       }
+}
+
+/** Test function #1 for XhprofTest::testCallAny */
+function wfTestCallAny_func1( $a, $b ) {
+       return $a * $b;
+}
+
+/** Test function #2 for XhprofTest::testCallAny */
+function wfTestCallAny_func2( $a, $b ) {
+       return $a + $b;
+}
+
+/** Test function #3 for XhprofTest::testCallAny */
+function wfTestCallAny_func3( $a, $b ) {
+       return $a - $b;
 }
index 4320d80..f0f55fb 100644 (file)
@@ -10,6 +10,8 @@ class BagOStuffTest extends MediaWikiTestCase {
        /** @var BagOStuff */
        private $cache;
 
+       const TEST_KEY = 'test';
+
        protected function setUp() {
                parent::setUp();
 
@@ -23,7 +25,7 @@ class BagOStuffTest extends MediaWikiTestCase {
                        $this->cache = new HashBagOStuff;
                }
 
-               $this->cache->delete( wfMemcKey( 'test' ) );
+               $this->cache->delete( $this->cache->makeKey( self::TEST_KEY ) );
        }
 
        /**
@@ -63,42 +65,43 @@ class BagOStuffTest extends MediaWikiTestCase {
        /**
         * @covers BagOStuff::merge
         * @covers BagOStuff::mergeViaLock
+        * @covers BagOStuff::mergeViaCas
         */
        public function testMerge() {
-               $key = wfMemcKey( 'test' );
-
-               $usleep = 0;
-
-               /**
-                * Callback method: append "merged" to whatever is in cache.
-                *
-                * @param BagOStuff $cache
-                * @param string $key
-                * @param int $existingValue
-                * @use int $usleep
-                * @return int
-                */
-               $callback = function ( BagOStuff $cache, $key, $existingValue ) use ( &$usleep ) {
-                       // let's pretend this is an expensive callback to test concurrent merge attempts
-                       usleep( $usleep );
-
-                       if ( $existingValue === false ) {
-                               return 'merged';
-                       }
+               $calls = 0;
+               $key = $this->cache->makeKey( self::TEST_KEY );
+               $callback = function ( BagOStuff $cache, $key, $oldVal ) use ( &$calls ) {
+                       ++$calls;
 
-                       return $existingValue . 'merged';
+                       return ( $oldVal === false ) ? 'merged' : $oldVal . 'merged';
                };
 
                // merge on non-existing value
-               $merged = $this->cache->merge( $key, $callback, 0 );
+               $merged = $this->cache->merge( $key, $callback, 5 );
                $this->assertTrue( $merged );
-               $this->assertEquals( $this->cache->get( $key ), 'merged' );
+               $this->assertEquals( 'merged', $this->cache->get( $key ) );
 
                // merge on existing value
-               $merged = $this->cache->merge( $key, $callback, 0 );
+               $merged = $this->cache->merge( $key, $callback, 5 );
                $this->assertTrue( $merged );
-               $this->assertEquals( $this->cache->get( $key ), 'mergedmerged' );
+               $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
@@ -111,33 +114,39 @@ class BagOStuffTest extends MediaWikiTestCase {
                $fork &= !$this->cache instanceof EmptyBagOStuff;
                $fork &= !$this->cache instanceof MultiWriteBagOStuff;
                if ( $fork ) {
-                       // callback should take awhile now so that we can test concurrent merge attempts
-                       $pid = pcntl_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 ) {
-                               // can't fork, ignore this test...
-                       } elseif ( $pid ) {
-                               // wait a little, making sure that the child process is calling merge
-                               usleep( 3000 );
-
-                               // attempt a merge - this should fail
-                               $merged = $this->cache->merge( $key, $callback, 0, 1 );
-
-                               // 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
-                               usleep( 3000 );
-                               $this->assertEquals( $this->cache->get( $key ), 'mergedmergedmerged' );
-                       } else {
-                               $this->cache->merge( $key, $callback, 0, 1 );
-
-                               // Note: I'm not even going to check if the merge worked, I'll
-                               // compare values in the parent process to test if this merge worked.
-                               // I'm just going to exit this child process, since I don't want the
-                               // child to output any test results (would be rather confusing to
-                               // have test output twice)
-                               exit;
+                               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' );
+               } else {
+                       $this->markTestSkipped( 'No pcntl methods available' );
                }
        }
 
@@ -145,10 +154,10 @@ class BagOStuffTest extends MediaWikiTestCase {
         * @covers BagOStuff::changeTTL
         */
        public function testChangeTTL() {
-               $key = wfMemcKey( 'test' );
+               $key = $this->cache->makeKey( self::TEST_KEY );
                $value = 'meow';
 
-               $this->cache->add( $key, $value );
+               $this->cache->add( $key, $value, 5 );
                $this->assertTrue( $this->cache->changeTTL( $key, 5 ) );
                $this->assertEquals( $this->cache->get( $key ), $value );
                $this->cache->delete( $key );
@@ -159,8 +168,8 @@ class BagOStuffTest extends MediaWikiTestCase {
         * @covers BagOStuff::add
         */
        public function testAdd() {
-               $key = wfMemcKey( 'test' );
-               $this->assertTrue( $this->cache->add( $key, 'test' ) );
+               $key = $this->cache->makeKey( self::TEST_KEY );
+               $this->assertTrue( $this->cache->add( $key, 'test', 5 ) );
        }
 
        /**
@@ -169,16 +178,18 @@ class BagOStuffTest extends MediaWikiTestCase {
        public function testGet() {
                $value = [ 'this' => 'is', 'a' => 'test' ];
 
-               $key = wfMemcKey( 'test' );
-               $this->cache->add( $key, $value );
+               $key = $this->cache->makeKey( self::TEST_KEY );
+               $this->cache->add( $key, $value, 5 );
                $this->assertEquals( $this->cache->get( $key ), $value );
        }
 
        /**
+        * @covers BagOStuff::get
+        * @covers BagOStuff::set
         * @covers BagOStuff::getWithSetCallback
         */
        public function testGetWithSetCallback() {
-               $key = wfMemcKey( 'test' );
+               $key = $this->cache->makeKey( self::TEST_KEY );
                $value = $this->cache->getWithSetCallback(
                        $key,
                        30,
@@ -195,8 +206,8 @@ class BagOStuffTest extends MediaWikiTestCase {
         * @covers BagOStuff::incr
         */
        public function testIncr() {
-               $key = wfMemcKey( 'test' );
-               $this->cache->add( $key, 0 );
+               $key = $this->cache->makeKey( self::TEST_KEY );
+               $this->cache->add( $key, 0, 5 );
                $this->cache->incr( $key );
                $expectedValue = 1;
                $actualValue = $this->cache->get( $key );
@@ -207,7 +218,7 @@ class BagOStuffTest extends MediaWikiTestCase {
         * @covers BagOStuff::incrWithInit
         */
        public function testIncrWithInit() {
-               $key = wfMemcKey( 'test' );
+               $key = $this->cache->makeKey( self::TEST_KEY );
                $val = $this->cache->incrWithInit( $key, 0, 1, 3 );
                $this->assertEquals( 3, $val, "Correct init value" );
 
@@ -224,18 +235,24 @@ class BagOStuffTest extends MediaWikiTestCase {
                $value3 = [ 'testing a key that may be encoded when sent to cache backend' ];
                $value4 = [ 'another test where chars in key will be encoded' ];
 
-               $key1 = wfMemcKey( 'test1' );
-               $key2 = wfMemcKey( 'test2' );
+               $key1 = $this->cache->makeKey( 'test-1' );
+               $key2 = $this->cache->makeKey( 'test-2' );
                // internally, MemcachedBagOStuffs will encode to will-%25-encode
-               $key3 = wfMemcKey( 'will-%-encode' );
-               $key4 = wfMemcKey(
+               $key3 = $this->cache->makeKey( 'will-%-encode' );
+               $key4 = $this->cache->makeKey(
                        'flowdb:flow_ref:wiki:by-source:v3:Parser\'s_"broken"_+_(page)_&_grill:testwiki:1:4.7'
                );
 
-               $this->cache->add( $key1, $value1 );
-               $this->cache->add( $key2, $value2 );
-               $this->cache->add( $key3, $value3 );
-               $this->cache->add( $key4, $value4 );
+               // cleanup
+               $this->cache->delete( $key1 );
+               $this->cache->delete( $key2 );
+               $this->cache->delete( $key3 );
+               $this->cache->delete( $key4 );
+
+               $this->cache->add( $key1, $value1, 5 );
+               $this->cache->add( $key2, $value2, 5 );
+               $this->cache->add( $key3, $value3, 5 );
+               $this->cache->add( $key4, $value4, 5 );
 
                $this->assertEquals(
                        [ $key1 => $value1, $key2 => $value2, $key3 => $value3, $key4 => $value4 ],
@@ -253,7 +270,7 @@ class BagOStuffTest extends MediaWikiTestCase {
         * @covers BagOStuff::getScopedLock
         */
        public function testGetScopedLock() {
-               $key = wfMemcKey( 'test' );
+               $key = $this->cache->makeKey( self::TEST_KEY );
                $value1 = $this->cache->getScopedLock( $key, 0 );
                $value2 = $this->cache->getScopedLock( $key, 0 );
 
@@ -297,4 +314,21 @@ class BagOStuffTest extends MediaWikiTestCase {
 
                DeferredUpdates::doUpdates();
        }
+
+       /**
+        * @covers BagOStuff::lock()
+        * @covers BagOStuff::unlock()
+        */
+       public function testLocking() {
+               $key = 'test';
+               $this->assertTrue( $this->cache->lock( $key ) );
+               $this->assertFalse( $this->cache->lock( $key ) );
+               $this->assertTrue( $this->cache->unlock( $key ) );
+
+               $key2 = 'test2';
+               $this->assertTrue( $this->cache->lock( $key2, 5, 5, 'rclass' ) );
+               $this->assertTrue( $this->cache->lock( $key2, 5, 5, 'rclass' ) );
+               $this->assertTrue( $this->cache->unlock( $key2 ) );
+               $this->assertTrue( $this->cache->unlock( $key2 ) );
+       }
 }
index 4a9f6cc..8a95ae7 100644 (file)
@@ -137,4 +137,13 @@ class MultiWriteBagOStuffTest extends MediaWikiTestCase {
 
                $this->assertSame( 'special', $cache->makeGlobalKey( 'a', 'b' ) );
        }
+
+       public function testDuplicateStoreAdd() {
+               $bag = new HashBagOStuff();
+               $cache = new MultiWriteBagOStuff( [
+                       'caches' => [ $bag, $bag ],
+               ] );
+
+               $this->assertTrue( $cache->add( 'key', 1, 30 ) );
+       }
 }
index 078b7b3..662bb96 100644 (file)
@@ -21,7 +21,7 @@ class WANObjectCacheTest extends PHPUnit\Framework\TestCase {
        use MediaWikiCoversValidator;
        use PHPUnit4And6Compat;
 
-       /** @var TimeAdjustableWANObjectCache */
+       /** @var WANObjectCache */
        private $cache;
        /** @var BagOStuff */
        private $internalCache;
@@ -29,8 +29,8 @@ class WANObjectCacheTest extends PHPUnit\Framework\TestCase {
        protected function setUp() {
                parent::setUp();
 
-               $this->cache = new TimeAdjustableWANObjectCache( [
-                       'cache' => new TimeAdjustableHashBagOStuff(),
+               $this->cache = new WANObjectCache( [
+                       'cache' => new HashBagOStuff(),
                        'pool' => 'testcache-hash',
                        'relayer' => new EventRelayerNull( [] )
                ] );
@@ -224,10 +224,11 @@ class WANObjectCacheTest extends PHPUnit\Framework\TestCase {
                $this->assertEquals( $value, $v, "Value returned" );
                $this->assertEquals( 0, $wasSet, "Value not regenerated" );
 
-               $priorTime = microtime( true ); // reference time
-               $cache->setTime( $priorTime );
+               $mockWallClock = microtime( true );
+               $priorTime = $mockWallClock; // reference time
+               $cache->setMockTime( $mockWallClock );
 
-               $cache->addTime( 1 );
+               $mockWallClock += 1;
 
                $wasSet = 0;
                $v = $cache->getWithSetCallback(
@@ -242,8 +243,8 @@ class WANObjectCacheTest extends PHPUnit\Framework\TestCase {
                $t2 = $cache->getCheckKeyTime( $cKey2 );
                $this->assertGreaterThanOrEqual( $priorTime, $t2, 'Check keys generated on miss' );
 
-               $priorTime = $cache->addTime( 0.01 );
-
+               $mockWallClock += 0.01;
+               $priorTime = $mockWallClock; // reference time
                $wasSet = 0;
                $v = $cache->getWithSetCallback(
                        $key, 30, $func, [ 'checkKeys' => [ $cKey1, $cKey2 ] ] + $extOpts
@@ -284,7 +285,8 @@ class WANObjectCacheTest extends PHPUnit\Framework\TestCase {
                        return 'xxx' . $wasSet;
                };
 
-               $now = microtime( true ); // reference time
+               $mockWallClock = microtime( true );
+               $priorTime = $mockWallClock; // reference time
 
                $wasSet = 0;
                $key = wfRandomString();
@@ -294,7 +296,7 @@ class WANObjectCacheTest extends PHPUnit\Framework\TestCase {
                $this->assertEquals( false, $oldValReceived, "Callback got no stale value" );
                $this->assertEquals( null, $oldAsOfReceived, "Callback got no stale value" );
 
-               $cache->addTime( 40 );
+               $mockWallClock += 40;
                $v = $cache->getWithSetCallback(
                        $key, 30, $checkFunc, [ 'staleTTL' => 50 ] + $extOpts );
                $this->assertEquals( 'xxx2', $v, "Value still returned after expired" );
@@ -302,7 +304,7 @@ class WANObjectCacheTest extends PHPUnit\Framework\TestCase {
                $this->assertEquals( 'xxx1', $oldValReceived, "Callback got stale value" );
                $this->assertNotEquals( null, $oldAsOfReceived, "Callback got stale value" );
 
-               $cache->addTime( 260 );
+               $mockWallClock += 260;
                $v = $cache->getWithSetCallback(
                        $key, 30, $checkFunc, [ 'staleTTL' => 50 ] + $extOpts );
                $this->assertEquals( 'xxx3', $v, "Value still returned after expired" );
@@ -310,12 +312,12 @@ class WANObjectCacheTest extends PHPUnit\Framework\TestCase {
                $this->assertEquals( false, $oldValReceived, "Callback got no stale value" );
                $this->assertEquals( null, $oldAsOfReceived, "Callback got no stale value" );
 
+               $mockWallClock = ( $priorTime - $cache::HOLDOFF_TTL - 1 );
                $wasSet = 0;
                $key = wfRandomString();
                $checkKey = $cache->makeKey( 'template', 'X' );
-               $cache->setTime( $now - $cache::HOLDOFF_TTL - 1 );
                $cache->touchCheckKey( $checkKey ); // init check key
-               $cache->setTime( $now );
+               $mockWallClock = $priorTime;
                $v = $cache->getWithSetCallback(
                        $key,
                        $cache::TTL_INDEFINITE,
@@ -327,7 +329,7 @@ class WANObjectCacheTest extends PHPUnit\Framework\TestCase {
                $this->assertEquals( false, $oldValReceived, "Callback got no stale value" );
                $this->assertEquals( null, $oldAsOfReceived, "Callback got no stale value" );
 
-               $cache->addTime( $cache::TTL_HOUR ); // some time passes
+               $mockWallClock += $cache::TTL_HOUR; // some time passes
                $v = $cache->getWithSetCallback(
                        $key,
                        $cache::TTL_INDEFINITE,
@@ -338,7 +340,7 @@ class WANObjectCacheTest extends PHPUnit\Framework\TestCase {
                $this->assertEquals( 1, $wasSet, "Cached value returned" );
 
                $cache->touchCheckKey( $checkKey ); // make key stale
-               $cache->addTime( 0.01 ); // ~1 week left of grace (barely stale to avoid refreshes)
+               $mockWallClock += 0.01; // ~1 week left of grace (barely stale to avoid refreshes)
 
                $v = $cache->getWithSetCallback(
                        $key,
@@ -350,8 +352,7 @@ class WANObjectCacheTest extends PHPUnit\Framework\TestCase {
                $this->assertEquals( 1, $wasSet, "Value still returned after expired (in grace)" );
 
                // Change of refresh increase to unity as staleness approaches graceTTL
-
-               $cache->addTime( $cache::TTL_WEEK ); // 8 days of being stale
+               $mockWallClock += $cache::TTL_WEEK; // 8 days of being stale
                $v = $cache->getWithSetCallback(
                        $key,
                        $cache::TTL_INDEFINITE,
@@ -408,17 +409,17 @@ class WANObjectCacheTest extends PHPUnit\Framework\TestCase {
                        $asycList[] = $callback;
                };
                $cache = new NearExpiringWANObjectCache( [
-                       'cache'        => new TimeAdjustableHashBagOStuff(),
+                       'cache'        => new HashBagOStuff(),
                        'pool'         => 'empty',
                        'asyncHandler' => $asyncHandler
                ] );
 
-               $now = microtime( true ); // reference time
-               $cache->setTime( $now );
+               $mockWallClock = microtime( true );
+               $priorTime = $mockWallClock; // reference time
+               $cache->setMockTime( $mockWallClock );
 
                $wasSet = 0;
                $key = wfRandomString();
-               $checkKey = wfRandomString();
                $opts = [ 'lowTTL' => 100 ];
                $v = $cache->getWithSetCallback( $key, 300, $func, $opts );
                $this->assertEquals( $value, $v, "Value returned" );
@@ -427,7 +428,7 @@ class WANObjectCacheTest extends PHPUnit\Framework\TestCase {
                $this->assertEquals( 1, $wasSet, "Cached value used" );
                $this->assertEquals( $v, $value, "Value cached" );
 
-               $cache->setTime( $now + 250 );
+               $mockWallClock += 250;
                $v = $cache->getWithSetCallback( $key, 300, $func, $opts );
                $this->assertEquals( $value, $v, "Value returned" );
                $this->assertEquals( 1, $wasSet, "Stale value used" );
@@ -441,11 +442,12 @@ class WANObjectCacheTest extends PHPUnit\Framework\TestCase {
                $this->assertEquals( $value, $v, "New value stored" );
 
                $cache = new PopularityRefreshingWANObjectCache( [
-                       'cache'   => new TimeAdjustableHashBagOStuff(),
+                       'cache'   => new HashBagOStuff(),
                        'pool'    => 'empty'
                ] );
 
-               $cache->setTime( $now );
+               $mockWallClock = $priorTime;
+               $cache->setMockTime( $mockWallClock );
 
                $wasSet = 0;
                $key = wfRandomString();
@@ -453,18 +455,22 @@ class WANObjectCacheTest extends PHPUnit\Framework\TestCase {
                $v = $cache->getWithSetCallback( $key, 60, $func, $opts );
                $this->assertEquals( $value, $v, "Value returned" );
                $this->assertEquals( 1, $wasSet, "Value calculated" );
-               $cache->setTime( $now + 30 );
+
+               $mockWallClock += 30;
+
                $v = $cache->getWithSetCallback( $key, 60, $func, $opts );
                $this->assertEquals( 1, $wasSet, "Value cached" );
 
+               $mockWallClock = $priorTime;
                $wasSet = 0;
                $key = wfRandomString();
                $opts = [ 'hotTTR' => 10 ];
-               $cache->setTime( $now );
                $v = $cache->getWithSetCallback( $key, 60, $func, $opts );
                $this->assertEquals( $value, $v, "Value returned" );
                $this->assertEquals( 1, $wasSet, "Value calculated" );
-               $cache->setTime( $now + 30 );
+
+               $mockWallClock += 30;
+
                $v = $cache->getWithSetCallback( $key, 60, $func, $opts );
                $this->assertEquals( $value, $v, "Value returned" );
                $this->assertEquals( 2, $wasSet, "Value re-calculated" );
@@ -538,10 +544,11 @@ class WANObjectCacheTest extends PHPUnit\Framework\TestCase {
                $this->assertEquals( 1, $wasSet, "Value not regenerated" );
                $this->assertEquals( 0, $cache->getWarmupKeyMisses(), "Keys warmed in process cache" );
 
-               $priorTime = microtime( true ); // reference time
-               $cache->setTime( $priorTime );
+               $mockWallClock = microtime( true );
+               $priorTime = $mockWallClock; // reference time
+               $cache->setMockTime( $mockWallClock );
 
-               $cache->addTime( 1 );
+               $mockWallClock += 1;
 
                $wasSet = 0;
                $keyedIds = new ArrayIterator( [ $keyB => 'efef' ] );
@@ -557,7 +564,8 @@ class WANObjectCacheTest extends PHPUnit\Framework\TestCase {
                $t2 = $cache->getCheckKeyTime( $cKey2 );
                $this->assertGreaterThanOrEqual( $priorTime, $t2, 'Check keys generated on miss' );
 
-               $priorTime = $cache->addTime( 0.01 );
+               $mockWallClock += 0.01;
+               $priorTime = $mockWallClock;
                $value = "@43636$";
                $wasSet = 0;
                $keyedIds = new ArrayIterator( [ $keyC => 43636 ] );
@@ -707,10 +715,11 @@ class WANObjectCacheTest extends PHPUnit\Framework\TestCase {
                $this->assertEquals( 1, $wasSet, "Value not regenerated" );
                $this->assertEquals( 0, $cache->getWarmupKeyMisses(), "Keys warmed in process cache" );
 
-               $priorTime = microtime( true ); // reference time
-               $cache->setTime( $priorTime );
+               $mockWallClock = microtime( true );
+               $priorTime = $mockWallClock; // reference time
+               $cache->setMockTime( $mockWallClock );
 
-               $cache->addTime( 1 );
+               $mockWallClock += 1;
 
                $wasSet = 0;
                $keyedIds = new ArrayIterator( [ $keyB => 'efef' ] );
@@ -724,7 +733,8 @@ class WANObjectCacheTest extends PHPUnit\Framework\TestCase {
                $t2 = $cache->getCheckKeyTime( $cKey2 );
                $this->assertGreaterThanOrEqual( $priorTime, $t2, 'Check keys generated on miss' );
 
-               $priorTime = $cache->addTime( 0.01 );
+               $mockWallClock += 0.01;
+               $priorTime = $mockWallClock;
                $value = "@43636$";
                $wasSet = 0;
                $keyedIds = new ArrayIterator( [ $keyC => 43636 ] );
@@ -959,10 +969,11 @@ class WANObjectCacheTest extends PHPUnit\Framework\TestCase {
                $cKey1 = wfRandomString();
                $cKey2 = wfRandomString();
 
-               $priorTime = microtime( true ); // reference time
-               $cache->setTime( $priorTime );
+               $mockWallClock = microtime( true );
+               $priorTime = $mockWallClock; // reference time
+               $cache->setMockTime( $mockWallClock );
 
-               $cache->addTime( 1 );
+               $mockWallClock += 1;
 
                $curTTLs = [];
                $this->assertEquals(
@@ -978,7 +989,7 @@ class WANObjectCacheTest extends PHPUnit\Framework\TestCase {
                $this->assertLessThanOrEqual( 0, $curTTLs[$key1], 'Key 1 has current TTL <= 0' );
                $this->assertLessThanOrEqual( 0, $curTTLs[$key2], 'Key 2 has current TTL <= 0' );
 
-               $cache->addTime( 1 );
+               $mockWallClock += 1;
 
                $curTTLs = [];
                $this->assertEquals(
@@ -1005,7 +1016,8 @@ class WANObjectCacheTest extends PHPUnit\Framework\TestCase {
                $value1 = wfRandomString();
                $value2 = wfRandomString();
 
-               $cache->setTime( microtime( true ) );
+               $mockWallClock = microtime( true );
+               $cache->setMockTime( $mockWallClock );
 
                // Fake initial check key to be set in the past. Otherwise we'd have to sleep for
                // several seconds during the test to assert the behaviour.
@@ -1013,7 +1025,7 @@ class WANObjectCacheTest extends PHPUnit\Framework\TestCase {
                        $cache->touchCheckKey( $checkKey, WANObjectCache::HOLDOFF_NONE );
                }
 
-               $cache->addTime( 0.100 );
+               $mockWallClock += 0.100;
 
                $cache->set( 'key1', $value1, 10 );
                $cache->set( 'key2', $value2, 10 );
@@ -1035,7 +1047,7 @@ class WANObjectCacheTest extends PHPUnit\Framework\TestCase {
                $this->assertGreaterThanOrEqual( 9.5, $curTTLs['key2'], 'Initial ttls' );
                $this->assertLessThanOrEqual( 10.5, $curTTLs['key2'], 'Initial ttls' );
 
-               $cache->addTime( 0.100 );
+               $mockWallClock += 0.100;
                $cache->touchCheckKey( $check1 );
 
                $curTTLs = [];
@@ -1292,15 +1304,16 @@ class WANObjectCacheTest extends PHPUnit\Framework\TestCase {
                $cache = $this->cache;
                $key = wfRandomString();
 
-               $priorTime = microtime( true ); // reference time
-               $cache->setTime( $priorTime );
+               $mockWallClock = microtime( true );
+               $priorTime = $mockWallClock; // reference time
+               $cache->setMockTime( $mockWallClock );
 
-               $newTime = $cache->addTime( 0.100 );
+               $mockWallClock += 0.100;
                $t0 = $cache->getCheckKeyTime( $key );
                $this->assertGreaterThanOrEqual( $priorTime, $t0, 'Check key auto-created' );
 
-               $priorTime = $newTime;
-               $newTime = $cache->addTime( 0.100 );
+               $priorTime = $mockWallClock;
+               $mockWallClock += 0.100;
                $cache->touchCheckKey( $key );
                $t1 = $cache->getCheckKeyTime( $key );
                $this->assertGreaterThanOrEqual( $priorTime, $t1, 'Check key created' );
@@ -1308,7 +1321,7 @@ class WANObjectCacheTest extends PHPUnit\Framework\TestCase {
                $t2 = $cache->getCheckKeyTime( $key );
                $this->assertEquals( $t1, $t2, 'Check key time did not change' );
 
-               $cache->addTime( 0.100 );
+               $mockWallClock += 0.100;
                $cache->touchCheckKey( $key );
                $t3 = $cache->getCheckKeyTime( $key );
                $this->assertGreaterThan( $t2, $t3, 'Check key time increased' );
@@ -1316,7 +1329,7 @@ class WANObjectCacheTest extends PHPUnit\Framework\TestCase {
                $t4 = $cache->getCheckKeyTime( $key );
                $this->assertEquals( $t3, $t4, 'Check key time did not change' );
 
-               $cache->addTime( 0.100 );
+               $mockWallClock += 0.100;
                $cache->resetCheckKey( $key );
                $t5 = $cache->getCheckKeyTime( $key );
                $this->assertGreaterThan( $t4, $t5, 'Check key time increased' );
@@ -1683,43 +1696,7 @@ class WANObjectCacheTest extends PHPUnit\Framework\TestCase {
        }
 }
 
-class TimeAdjustableHashBagOStuff extends HashBagOStuff {
-       private $timeOverride = 0;
-
-       public function setTime( $time ) {
-               $this->timeOverride = $time;
-       }
-
-       protected function getCurrentTime() {
-               return $this->timeOverride ?: parent::getCurrentTime();
-       }
-}
-
-class TimeAdjustableWANObjectCache extends WANObjectCache {
-       private $timeOverride = 0;
-
-       public function setTime( $time ) {
-               $this->timeOverride = $time;
-               if ( $this->cache instanceof TimeAdjustableHashBagOStuff ) {
-                       $this->cache->setTime( $time );
-               }
-       }
-
-       public function addTime( $time ) {
-               $this->timeOverride += $time;
-               if ( $this->cache instanceof TimeAdjustableHashBagOStuff ) {
-                       $this->cache->setTime( $this->timeOverride );
-               }
-
-               return $this->timeOverride;
-       }
-
-       protected function getCurrentTime() {
-               return $this->timeOverride ?: parent::getCurrentTime();
-       }
-}
-
-class NearExpiringWANObjectCache extends TimeAdjustableWANObjectCache {
+class NearExpiringWANObjectCache extends WANObjectCache {
        const CLOCK_SKEW = 1;
 
        protected function worthRefreshExpiring( $curTTL, $lowTTL ) {
@@ -1727,7 +1704,7 @@ class NearExpiringWANObjectCache extends TimeAdjustableWANObjectCache {
        }
 }
 
-class PopularityRefreshingWANObjectCache extends TimeAdjustableWANObjectCache {
+class PopularityRefreshingWANObjectCache extends WANObjectCache {
        protected function worthRefreshPopular( $asOf, $ageNew, $timeTillRefresh, $now ) {
                return ( ( $now - $asOf ) > $timeTillRefresh );
        }
index c3cddc6..e130b23 100644 (file)
@@ -12,6 +12,7 @@ use Wikimedia\Rdbms\ResultWrapper;
  */
 class DBConnRefTest extends PHPUnit\Framework\TestCase {
 
+       use MediaWikiCoversValidator;
        use PHPUnit4And6Compat;
 
        /**
@@ -106,18 +107,9 @@ class DBConnRefTest extends PHPUnit\Framework\TestCase {
                new DBConnRef( $lb, 17 ); // bad constructor argument
        }
 
-       public function testGetWikiID() {
-               $lb = $this->getMock( ILoadBalancer::class );
-
-               // getWikiID is optimized to not create a connection
-               $lb->expects( $this->never() )
-                       ->method( 'getConnection' );
-
-               $ref = new DBConnRef( $lb, [ DB_REPLICA, [], 'dummy', 0 ] );
-
-               $this->assertSame( 'dummy', $ref->getWikiID() );
-       }
-
+       /**
+        * @covers Wikimedia\Rdbms\DBConnRef::getDomainId
+        */
        public function testGetDomainID() {
                $lb = $this->getMock( ILoadBalancer::class );
 
index 93192d0..a86a1c9 100644 (file)
@@ -79,12 +79,12 @@ class DatabaseMysqlBaseTest extends PHPUnit\Framework\TestCase {
 
                        // unicode chars
                        [
-                               self::createUnicodeString( '`\u0001a\uFFFFb`' ),
-                               self::createUnicodeString( '\u0001a\uFFFFb' )
+                               "`\u{0001}a\u{FFFF}b`",
+                               "\u{0001}a\u{FFFF}b"
                        ],
                        [
-                               self::createUnicodeString( '`\u0001\uFFFF`' ),
-                               self::createUnicodeString( '\u0001\u0000\uFFFF\u0000' )
+                               "`\u{0001}\u{FFFF}`",
+                               "\u{0001}\u{0000}\u{FFFF}\u{0000}"
                        ],
                        [ '`☃`', '☃' ],
                        [ '`メインページ`', 'メインページ' ],
@@ -97,10 +97,6 @@ class DatabaseMysqlBaseTest extends PHPUnit\Framework\TestCase {
                ];
        }
 
-       private static function createUnicodeString( $str ) {
-               return json_decode( '"' . $str . '"' );
-       }
-
        private function getMockForViews() {
                $db = $this->getMockBuilder( DatabaseMysqli::class )
                        ->disableOriginalConstructor()
index b434396..0cb35b4 100644 (file)
@@ -53,10 +53,10 @@ class DatabaseSQLTest extends PHPUnit\Framework\TestCase {
                $this->database->select(
                        $sql['tables'],
                        $sql['fields'],
-                       isset( $sql['conds'] ) ? $sql['conds'] : [],
+                       $sql['conds'] ?? [],
                        __METHOD__,
-                       isset( $sql['options'] ) ? $sql['options'] : [],
-                       isset( $sql['join_conds'] ) ? $sql['join_conds'] : []
+                       $sql['options'] ?? [],
+                       $sql['join_conds'] ?? []
                );
                $this->assertLastSql( $sqlText );
        }
@@ -256,6 +256,58 @@ class DatabaseSQLTest extends PHPUnit\Framework\TestCase {
                ];
        }
 
+       /**
+        * @dataProvider provideLockForUpdate
+        * @covers Wikimedia\Rdbms\Database::lockForUpdate
+        */
+       public function testLockForUpdate( $sql, $sqlText ) {
+               $this->database->startAtomic( __METHOD__ );
+               $this->database->lockForUpdate(
+                       $sql['tables'],
+                       $sql['conds'] ?? [],
+                       __METHOD__,
+                       $sql['options'] ?? [],
+                       $sql['join_conds'] ?? []
+               );
+               $this->database->endAtomic( __METHOD__ );
+
+               $this->assertLastSql( "BEGIN; $sqlText; COMMIT" );
+       }
+
+       public static function provideLockForUpdate() {
+               return [
+                       [
+                               [
+                                       'tables' => [ 'table' ],
+                                       'conds' => [ 'field' => [ 1, 2, 3, 4 ] ],
+                               ],
+                               "SELECT COUNT(*) AS rowcount FROM " .
+                               "(SELECT 1 FROM table WHERE field IN ('1','2','3','4')    " .
+                               "FOR UPDATE) tmp_count"
+                       ],
+                       [
+                               [
+                                       'tables' => [ 'table', 't2' => 'table2' ],
+                                       'conds' => [ 'field' => 'text' ],
+                                       'options' => [ 'LIMIT' => 1, 'ORDER BY' => 'field' ],
+                                       'join_conds' => [ 't2' => [
+                                               'LEFT JOIN', 'tid = t2.id'
+                                       ] ],
+                               ],
+                               "SELECT COUNT(*) AS rowcount FROM " .
+                               "(SELECT 1 FROM table LEFT JOIN table2 t2 ON ((tid = t2.id)) " .
+                               "WHERE field = 'text' ORDER BY field LIMIT 1   FOR UPDATE) tmp_count"
+                       ],
+                       [
+                               [
+                                       'tables' => 'table',
+                               ],
+                               "SELECT COUNT(*) AS rowcount FROM " .
+                               "(SELECT 1 FROM table      FOR UPDATE) tmp_count"
+                       ],
+               ];
+       }
+
        /**
         * @covers Wikimedia\Rdbms\Subquery
         * @dataProvider provideSelectRowCount
@@ -266,10 +318,10 @@ class DatabaseSQLTest extends PHPUnit\Framework\TestCase {
                $this->database->selectRowCount(
                        $sql['tables'],
                        $sql['field'],
-                       isset( $sql['conds'] ) ? $sql['conds'] : [],
+                       $sql['conds'] ?? [],
                        __METHOD__,
-                       isset( $sql['options'] ) ? $sql['options'] : [],
-                       isset( $sql['join_conds'] ) ? $sql['join_conds'] : []
+                       $sql['options'] ?? [],
+                       $sql['join_conds'] ?? []
                );
                $this->assertLastSql( $sqlText );
        }
@@ -363,7 +415,7 @@ class DatabaseSQLTest extends PHPUnit\Framework\TestCase {
                        $sql['values'],
                        $sql['conds'],
                        __METHOD__,
-                       isset( $sql['options'] ) ? $sql['options'] : []
+                       $sql['options'] ?? []
                );
                $this->assertLastSql( $sqlText );
        }
@@ -531,7 +583,7 @@ class DatabaseSQLTest extends PHPUnit\Framework\TestCase {
                        $sql['table'],
                        $sql['rows'],
                        __METHOD__,
-                       isset( $sql['options'] ) ? $sql['options'] : []
+                       $sql['options'] ?? []
                );
                $this->assertLastSql( $sqlText );
        }
@@ -587,9 +639,9 @@ class DatabaseSQLTest extends PHPUnit\Framework\TestCase {
                        $sql['varMap'],
                        $sql['conds'],
                        __METHOD__,
-                       isset( $sql['insertOptions'] ) ? $sql['insertOptions'] : [],
-                       isset( $sql['selectOptions'] ) ? $sql['selectOptions'] : [],
-                       isset( $sql['selectJoinConds'] ) ? $sql['selectJoinConds'] : []
+                       $sql['insertOptions'] ?? [],
+                       $sql['selectOptions'] ?? [],
+                       $sql['selectJoinConds'] ?? []
                );
                $this->assertLastSql( $sqlTextNative );
 
@@ -603,9 +655,9 @@ class DatabaseSQLTest extends PHPUnit\Framework\TestCase {
                        $sql['varMap'],
                        $sql['conds'],
                        __METHOD__,
-                       isset( $sql['insertOptions'] ) ? $sql['insertOptions'] : [],
-                       isset( $sql['selectOptions'] ) ? $sql['selectOptions'] : [],
-                       isset( $sql['selectJoinConds'] ) ? $sql['selectJoinConds'] : []
+                       $sql['insertOptions'] ?? [],
+                       $sql['selectOptions'] ?? [],
+                       $sql['selectJoinConds'] ?? []
                );
                $this->assertLastSqlDb( implode( '; ', [ $sqlSelect, 'BEGIN', $sqlInsert, 'COMMIT' ] ), $dbWeb );
        }
@@ -1012,10 +1064,10 @@ class DatabaseSQLTest extends PHPUnit\Framework\TestCase {
                        $params['table'],
                        $params['vars'],
                        $params['permute_conds'],
-                       isset( $params['extra_conds'] ) ? $params['extra_conds'] : '',
+                       $params['extra_conds'] ?? '',
                        'FNAME',
-                       isset( $params['options'] ) ? $params['options'] : [],
-                       isset( $params['join_conds'] ) ? $params['join_conds'] : []
+                       $params['options'] ?? [],
+                       $params['join_conds'] ?? []
                ) );
                $this->assertEquals( $expect, $sql );
        }
@@ -1893,15 +1945,31 @@ class DatabaseSQLTest extends PHPUnit\Framework\TestCase {
 
                $this->database->setFlag( Database::DBO_TRX );
 
-               // Implicit transaction gets silently rolled back
+               // Implicit transaction does not get silently rolled back
                $this->database->begin( __METHOD__, Database::TRANSACTION_INTERNAL );
                call_user_func( $doError );
-               $this->database->delete( 'x', [ 'field' => 1 ], __METHOD__ );
-               $this->database->commit( __METHOD__, Database::FLUSHING_INTERNAL );
-               // phpcs:ignore
-               $this->assertLastSql( 'BEGIN; DELETE FROM error WHERE 1; ROLLBACK; BEGIN; DELETE FROM x WHERE field = \'1\'; COMMIT' );
+               try {
+                       $this->database->delete( 'x', [ 'field' => 1 ], __METHOD__ );
+                       $this->fail( 'Expected exception not thrown' );
+               } catch ( DBTransactionError $e ) {
+                       $this->assertEquals(
+                               'Cannot execute query from ' . __METHOD__ . ' while transaction status is ERROR.',
+                               $e->getMessage()
+                       );
+               }
+               try {
+                       $this->database->commit( __METHOD__, Database::FLUSHING_INTERNAL );
+                       $this->fail( 'Expected exception not thrown' );
+               } catch ( DBTransactionError $e ) {
+                       $this->assertEquals(
+                               'Cannot execute query from ' . __METHOD__ . ' while transaction status is ERROR.',
+                               $e->getMessage()
+                       );
+               }
+               $this->database->rollback( __METHOD__, Database::FLUSHING_INTERNAL );
+               $this->assertLastSql( 'BEGIN; DELETE FROM error WHERE 1; ROLLBACK' );
 
-               // ... unless there were prior writes
+               // Likewise if there were prior writes
                $this->database->begin( __METHOD__, Database::TRANSACTION_INTERNAL );
                $this->database->delete( 'x', [ 'field' => 1 ], __METHOD__ );
                call_user_func( $doError );
index 3f0dae6..8f4aae3 100644 (file)
@@ -260,6 +260,16 @@ class DatabaseTest extends PHPUnit\Framework\TestCase {
 
                $lbFactory->commitMasterChanges( __METHOD__ );
                $this->assertFalse( $called, 'Not called in next round commit' );
+
+               $db->setFlag( DBO_TRX );
+               try {
+                       $db->onTransactionCommitOrIdle( function () {
+                               throw new RuntimeException( 'test' );
+                       } );
+                       $this->fail( "Exception not thrown" );
+               } catch ( RuntimeException $e ) {
+                       $this->assertTrue( $db->getFlag( DBO_TRX ) );
+               }
        }
 
        /**
@@ -430,6 +440,7 @@ class DatabaseTest extends PHPUnit\Framework\TestCase {
                        'numFields', 'numRows',
                        'open',
                        'strencode',
+                       'tableExists'
                ];
                $db = $this->getMockBuilder( Database::class )
                        ->disableOriginalConstructor()
diff --git a/tests/phpunit/includes/libs/xmp/XMPTest.php b/tests/phpunit/includes/libs/xmp/XMPTest.php
deleted file mode 100644 (file)
index 73fd471..0000000
+++ /dev/null
@@ -1,227 +0,0 @@
-<?php
-
-/**
- * @group Media
- * @covers XMPReader
- */
-class XMPTest extends PHPUnit\Framework\TestCase {
-
-       use MediaWikiCoversValidator;
-
-       protected function setUp() {
-               parent::setUp();
-               # Requires libxml to do XMP parsing
-               if ( !extension_loaded( 'exif' ) ) {
-                       $this->markTestSkipped( "PHP extension 'exif' is not loaded, skipping." );
-               }
-       }
-
-       /**
-        * Put XMP in, compare what comes out...
-        *
-        * @param string $xmp The actual xml data.
-        * @param array $expected Expected result of parsing the xmp.
-        * @param string $info Short sentence on what's being tested.
-        *
-        * @throws Exception
-        * @dataProvider provideXMPParse
-        *
-        * @covers XMPReader::parse
-        */
-       public function testXMPParse( $xmp, $expected, $info ) {
-               if ( !is_string( $xmp ) || !is_array( $expected ) ) {
-                       throw new Exception( "Invalid data provided to " . __METHOD__ );
-               }
-               $reader = new XMPReader;
-               $reader->parse( $xmp );
-               $this->assertEquals( $expected, $reader->getResults(), $info, 0.0000000001 );
-       }
-
-       public static function provideXMPParse() {
-               $xmpPath = __DIR__ . '/../../../data/xmp/';
-               $data = [];
-
-               // $xmpFiles format: array of arrays with first arg file base name,
-               // with the actual file having .xmp on the end for the xmp
-               // and .result.php on the end for a php file containing the result
-               // array. Second argument is some info on what's being tested.
-               $xmpFiles = [
-                       [ '1', 'parseType=Resource test' ],
-                       [ '2', 'Structure with mixed attribute and element props' ],
-                       [ '3', 'Extra qualifiers (that should be ignored)' ],
-                       [ '3-invalid', 'Test ignoring qualifiers that look like normal props' ],
-                       [ '4', 'Flash as qualifier' ],
-                       [ '5', 'Flash as qualifier 2' ],
-                       [ '6', 'Multiple rdf:Description' ],
-                       [ '7', 'Generic test of several property types' ],
-                       [ 'flash', 'Test of Flash property' ],
-                       [ 'invalid-child-not-struct', 'Test child props not in struct or ignored' ],
-                       [ 'no-recognized-props', 'Test namespace and no recognized props' ],
-                       [ 'no-namespace', 'Test non-namespaced attributes are ignored' ],
-                       [ 'bag-for-seq', "Allow bag's instead of seq's. (T29105)" ],
-                       [ 'utf16BE', 'UTF-16BE encoding' ],
-                       [ 'utf16LE', 'UTF-16LE encoding' ],
-                       [ 'utf32BE', 'UTF-32BE encoding' ],
-                       [ 'utf32LE', 'UTF-32LE encoding' ],
-                       [ 'xmpExt', 'Extended XMP missing second part' ],
-                       [ 'gps', 'Handling of exif GPS parameters in XMP' ],
-               ];
-
-               $xmpFiles[] = [ 'doctype-included', 'XMP includes doctype' ];
-
-               foreach ( $xmpFiles as $file ) {
-                       $xmp = file_get_contents( $xmpPath . $file[0] . '.xmp' );
-                       // I'm not sure if this is the best way to handle getting the
-                       // result array, but it seems kind of big to put directly in the test
-                       // file.
-                       $result = null;
-                       include $xmpPath . $file[0] . '.result.php';
-                       $data[] = [ $xmp, $result, '[' . $file[0] . '.xmp] ' . $file[1] ];
-               }
-
-               return $data;
-       }
-
-       /** Test ExtendedXMP block support. (Used when the XMP has to be split
-        * over multiple jpeg segments, due to 64k size limit on jpeg segments.
-        *
-        * @todo This is based on what the standard says. Need to find a real
-        * world example file to double check the support for this is right.
-        *
-        * @covers XMPReader::parseExtended
-        */
-       public function testExtendedXMP() {
-               $xmpPath = __DIR__ . '/../../../data/xmp/';
-               $standardXMP = file_get_contents( $xmpPath . 'xmpExt.xmp' );
-               $extendedXMP = file_get_contents( $xmpPath . 'xmpExt2.xmp' );
-
-               $md5sum = '28C74E0AC2D796886759006FBE2E57B7'; // of xmpExt2.xmp
-               $length = pack( 'N', strlen( $extendedXMP ) );
-               $offset = pack( 'N', 0 );
-               $extendedPacket = $md5sum . $length . $offset . $extendedXMP;
-
-               $reader = new XMPReader();
-               $reader->parse( $standardXMP );
-               $reader->parseExtended( $extendedPacket );
-               $actual = $reader->getResults();
-
-               $expected = [
-                       'xmp-exif' => [
-                               'DigitalZoomRatio' => '0/10',
-                               'Flash' => 9,
-                               'FNumber' => '2/10',
-                       ]
-               ];
-
-               $this->assertEquals( $expected, $actual );
-       }
-
-       /**
-        * This test has an extended XMP block with a wrong guid (md5sum)
-        * and thus should only return the StandardXMP, not the ExtendedXMP.
-        *
-        * @covers XMPReader::parseExtended
-        */
-       public function testExtendedXMPWithWrongGUID() {
-               $xmpPath = __DIR__ . '/../../../data/xmp/';
-               $standardXMP = file_get_contents( $xmpPath . 'xmpExt.xmp' );
-               $extendedXMP = file_get_contents( $xmpPath . 'xmpExt2.xmp' );
-
-               $md5sum = '28C74E0AC2D796886759006FBE2E57B9'; // Note last digit.
-               $length = pack( 'N', strlen( $extendedXMP ) );
-               $offset = pack( 'N', 0 );
-               $extendedPacket = $md5sum . $length . $offset . $extendedXMP;
-
-               $reader = new XMPReader();
-               $reader->parse( $standardXMP );
-               $reader->parseExtended( $extendedPacket );
-               $actual = $reader->getResults();
-
-               $expected = [
-                       'xmp-exif' => [
-                               'DigitalZoomRatio' => '0/10',
-                               'Flash' => 9,
-                       ]
-               ];
-
-               $this->assertEquals( $expected, $actual );
-       }
-
-       /**
-        * Have a high offset to simulate a missing packet,
-        * which should cause it to ignore the ExtendedXMP packet.
-        *
-        * @covers XMPReader::parseExtended
-        */
-       public function testExtendedXMPMissingPacket() {
-               $xmpPath = __DIR__ . '/../../../data/xmp/';
-               $standardXMP = file_get_contents( $xmpPath . 'xmpExt.xmp' );
-               $extendedXMP = file_get_contents( $xmpPath . 'xmpExt2.xmp' );
-
-               $md5sum = '28C74E0AC2D796886759006FBE2E57B7'; // of xmpExt2.xmp
-               $length = pack( 'N', strlen( $extendedXMP ) );
-               $offset = pack( 'N', 2048 );
-               $extendedPacket = $md5sum . $length . $offset . $extendedXMP;
-
-               $reader = new XMPReader();
-               $reader->parse( $standardXMP );
-               $reader->parseExtended( $extendedPacket );
-               $actual = $reader->getResults();
-
-               $expected = [
-                       'xmp-exif' => [
-                               'DigitalZoomRatio' => '0/10',
-                               'Flash' => 9,
-                       ]
-               ];
-
-               $this->assertEquals( $expected, $actual );
-       }
-
-       /**
-        * Test for multi-section, hostile XML
-        * @covers XMPReader::checkParseSafety
-        */
-       public function testCheckParseSafety() {
-               // Test for detection
-               $xmpPath = __DIR__ . '/../../../data/xmp/';
-               $file = fopen( $xmpPath . 'doctype-included.xmp', 'rb' );
-               $valid = false;
-               $reader = new XMPReader();
-               do {
-                       $chunk = fread( $file, 10 );
-                       $valid = $reader->parse( $chunk, feof( $file ) );
-               } while ( !feof( $file ) );
-               $this->assertFalse( $valid, 'Check that doctype is detected in fragmented XML' );
-               $this->assertEquals(
-                       [],
-                       $reader->getResults(),
-                       'Check that doctype is detected in fragmented XML'
-               );
-               fclose( $file );
-               unset( $reader );
-
-               // Test for false positives
-               $file = fopen( $xmpPath . 'doctype-not-included.xmp', 'rb' );
-               $valid = false;
-               $reader = new XMPReader();
-               do {
-                       $chunk = fread( $file, 10 );
-                       $valid = $reader->parse( $chunk, feof( $file ) );
-               } while ( !feof( $file ) );
-               $this->assertTrue(
-                       $valid,
-                       'Check for false-positive detecting doctype in fragmented XML'
-               );
-               $this->assertEquals(
-                       [
-                               'xmp-exif' => [
-                                       'DigitalZoomRatio' => '0/10',
-                                       'Flash' => '9'
-                               ]
-                       ],
-                       $reader->getResults(),
-                       'Check that doctype is detected in fragmented XML'
-               );
-       }
-}
diff --git a/tests/phpunit/includes/libs/xmp/XMPValidateTest.php b/tests/phpunit/includes/libs/xmp/XMPValidateTest.php
deleted file mode 100644 (file)
index 746f68a..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-<?php
-
-use Psr\Log\NullLogger;
-
-/**
- * @group Media
- */
-class XMPValidateTest extends PHPUnit\Framework\TestCase {
-
-       use MediaWikiCoversValidator;
-
-       /**
-        * @dataProvider provideDates
-        * @covers XMPValidate::validateDate
-        */
-       public function testValidateDate( $value, $expected ) {
-               // The method should modify $value.
-               $validate = new XMPValidate( new NullLogger() );
-               $validate->validateDate( [], $value, true );
-               $this->assertEquals( $expected, $value );
-       }
-
-       public static function provideDates() {
-               /* For reference valid date formats are:
-                * YYYY
-                * YYYY-MM
-                * YYYY-MM-DD
-                * YYYY-MM-DDThh:mmTZD
-                * YYYY-MM-DDThh:mm:ssTZD
-                * YYYY-MM-DDThh:mm:ss.sTZD
-                * (Time zone is optional)
-                */
-               return [
-                       [ '1992', '1992' ],
-                       [ '1992-04', '1992:04' ],
-                       [ '1992-02-01', '1992:02:01' ],
-                       [ '2011-09-29', '2011:09:29' ],
-                       [ '1982-12-15T20:12', '1982:12:15 20:12' ],
-                       [ '1982-12-15T20:12Z', '1982:12:15 20:12' ],
-                       [ '1982-12-15T20:12+02:30', '1982:12:15 22:42' ],
-                       [ '1982-12-15T01:12-02:30', '1982:12:14 22:42' ],
-                       [ '1982-12-15T20:12:11', '1982:12:15 20:12:11' ],
-                       [ '1982-12-15T20:12:11Z', '1982:12:15 20:12:11' ],
-                       [ '1982-12-15T20:12:11+01:10', '1982:12:15 21:22:11' ],
-                       [ '2045-12-15T20:12:11', '2045:12:15 20:12:11' ],
-                       [ '1867-06-01T15:00:00', '1867:06:01 15:00:00' ],
-                       /* some invalid ones */
-                       [ '2001--12', null ],
-                       [ '2001-5-12', null ],
-                       [ '2001-5-12TZ', null ],
-                       [ '2001-05-12T15', null ],
-                       [ '2001-12T15:13', null ],
-               ];
-       }
-}
index 6d096c2..c758ba6 100644 (file)
@@ -131,6 +131,11 @@ class LinkRendererTest extends MediaWikiLangTestCase {
                        . '(page does not exist)"><script>evil()</script></a>',
                        $linkRenderer->makeLink( $foobar, new HtmlArmor( '<script>evil()</script>' ) )
                );
+
+               $this->assertEquals(
+                       '<a href="#fragment">fragment</a>',
+                       $linkRenderer->makeLink( Title::newFromText( '#fragment' ) )
+               );
        }
 
        public function testGetLinkClasses() {
index 786d761..883af71 100644 (file)
@@ -33,19 +33,19 @@ abstract class LogFormatterTestCase extends MediaWikiLangTestCase {
                        // no log_id because no insert in database
                        'log_type' => $data['type'],
                        'log_action' => $data['action'],
-                       'log_timestamp' => isset( $data['timestamp'] ) ? $data['timestamp'] : wfTimestampNow(),
-                       'log_user' => isset( $data['user'] ) ? $data['user'] : 0,
-                       'log_user_text' => isset( $data['user_text'] ) ? $data['user_text'] : 'User',
-                       'log_actor' => isset( $data['actor'] ) ? $data['actor'] : 0,
-                       'log_namespace' => isset( $data['namespace'] ) ? $data['namespace'] : NS_MAIN,
-                       'log_title' => isset( $data['title'] ) ? $data['title'] : 'Main_Page',
-                       'log_page' => isset( $data['page'] ) ? $data['page'] : 0,
-                       'log_comment_text' => isset( $data['comment'] ) ? $data['comment'] : '',
+                       'log_timestamp' => $data['timestamp'] ?? wfTimestampNow(),
+                       'log_user' => $data['user'] ?? 0,
+                       'log_user_text' => $data['user_text'] ?? 'User',
+                       'log_actor' => $data['actor'] ?? 0,
+                       'log_namespace' => $data['namespace'] ?? NS_MAIN,
+                       'log_title' => $data['title'] ?? 'Main_Page',
+                       'log_page' => $data['page'] ?? 0,
+                       'log_comment_text' => $data['comment'] ?? '',
                        'log_comment_data' => null,
                        'log_params' => $legacy
                                ? LogPage::makeParamBlob( $data['params'] )
                                : LogEntryBase::makeParamBlob( $data['params'] ),
-                       'log_deleted' => isset( $data['deleted'] ) ? $data['deleted'] : 0,
+                       'log_deleted' => $data['deleted'] ?? 0,
                ];
        }
 
index 826957e..4b3ba07 100644 (file)
@@ -44,13 +44,6 @@ class IPTCTest extends MediaWikiTestCase {
         * @covers IPTC::parse
         */
        public function testIPTCParseForcedUTFButInvalid() {
-               if ( version_compare( PHP_VERSION, '5.5.26', '<' )
-                       || ( version_compare( PHP_VERSION, '5.6.0', '>' )
-                               && version_compare( PHP_VERSION, '5.6.10', '<' )
-                       )
-               ) {
-                       $this->markTestSkipped( 'Test fails on pre-PHP 5.5.25. See T124574/T39665 for details.' );
-               }
                $iptcData = "Photoshop 3.0\08BIM\4\4\0\0\0\0\0\x11\x1c\x02\x19\x00\x04\xC3\xC3\xC3\xB8"
                        . "\x1c\x01\x5A\x00\x03\x1B\x25\x47";
                $res = IPTC::parse( $iptcData );
index a4e8056..7a536df 100644 (file)
@@ -70,7 +70,7 @@ abstract class MediaWikiMediaTestCase extends MediaWikiTestCase {
         *
         * File must be in the path returned by getFilePath()
         * @param string $name File name
-        * @param string $type MIME type [optional]
+        * @param string|null $type MIME type [optional]
         * @return UnregisteredLocalFile
         */
        protected function dataFile( $name, $type = null ) {
diff --git a/tests/phpunit/includes/page/PageArchiveMcrTest.php b/tests/phpunit/includes/page/PageArchiveMcrTest.php
new file mode 100644 (file)
index 0000000..d2a8016
--- /dev/null
@@ -0,0 +1,85 @@
+<?php
+use MediaWiki\MediaWikiServices;
+use MediaWiki\Tests\Storage\McrSchemaOverride;
+
+/**
+ * Test class for page archiving, using the new MCR schema.
+ *
+ * @group ContentHandler
+ * @group Database
+ * ^--- important, causes temporary tables to be used instead of the real database
+ *
+ * @group medium
+ * ^--- important, causes tests not to fail with timeout
+ */
+class PageArchiveMcrTest extends PageArchiveTestBase {
+
+       use McrSchemaOverride;
+
+       /**
+        * @covers PageArchive::listRevisions
+        */
+       public function testListRevisions_slots() {
+               $revisions = $this->archivedPage->listRevisions();
+
+               $revisionStore = MediaWikiServices::getInstance()->getInstance()->getRevisionStore();
+               $slotsQuery = $revisionStore->getSlotsQueryInfo( [ 'content' ] );
+
+               foreach ( $revisions as $row ) {
+                       $this->assertSelect(
+                               $slotsQuery['tables'],
+                               'count(*)',
+                               [ 'slot_revision_id' => $row->ar_rev_id ],
+                               [ [ 1 ] ],
+                               [],
+                               $slotsQuery['joins']
+                       );
+               }
+       }
+
+       protected function getExpectedArchiveRows() {
+               return [
+                       [
+                               'ar_minor_edit' => '0',
+                               'ar_user' => '0',
+                               'ar_user_text' => $this->ipEditor,
+                               'ar_actor' => null,
+                               'ar_len' => '11',
+                               'ar_deleted' => '0',
+                               'ar_rev_id' => strval( $this->ipRev->getId() ),
+                               'ar_timestamp' => $this->db->timestamp( $this->ipRev->getTimestamp() ),
+                               'ar_sha1' => '0qdrpxl537ivfnx4gcpnzz0285yxryy',
+                               'ar_page_id' => strval( $this->ipRev->getPageId() ),
+                               'ar_comment_text' => 'just a test',
+                               'ar_comment_data' => null,
+                               'ar_comment_cid' => null,
+                               'ts_tags' => null,
+                               'ar_id' => '2',
+                               'ar_namespace' => '0',
+                               'ar_title' => 'PageArchiveTest_thePage',
+                               'ar_parent_id' => strval( $this->ipRev->getParentId() ),
+                       ],
+                       [
+                               'ar_minor_edit' => '0',
+                               'ar_user' => (string)$this->getTestUser()->getUser()->getId(),
+                               'ar_user_text' => $this->getTestUser()->getUser()->getName(),
+                               'ar_actor' => null,
+                               'ar_len' => '7',
+                               'ar_deleted' => '0',
+                               'ar_rev_id' => strval( $this->firstRev->getId() ),
+                               'ar_timestamp' => $this->db->timestamp( $this->firstRev->getTimestamp() ),
+                               'ar_sha1' => 'pr0s8e18148pxhgjfa0gjrvpy8fiyxc',
+                               'ar_page_id' => strval( $this->firstRev->getPageId() ),
+                               'ar_comment_text' => 'testing',
+                               'ar_comment_data' => null,
+                               'ar_comment_cid' => null,
+                               'ts_tags' => null,
+                               'ar_id' => '1',
+                               'ar_namespace' => '0',
+                               'ar_title' => 'PageArchiveTest_thePage',
+                               'ar_parent_id' => '0',
+                       ],
+               ];
+       }
+
+}
diff --git a/tests/phpunit/includes/page/PageArchivePreMcrTest.php b/tests/phpunit/includes/page/PageArchivePreMcrTest.php
new file mode 100644 (file)
index 0000000..6757e78
--- /dev/null
@@ -0,0 +1,96 @@
+<?php
+use MediaWiki\MediaWikiServices;
+use MediaWiki\Storage\SqlBlobStore;
+use MediaWiki\Tests\Storage\PreMcrSchemaOverride;
+
+/**
+ * Test class for page archiving, using the pre-MCR schema.
+ *
+ * @group ContentHandler
+ * @group Database
+ * ^--- important, causes temporary tables to be used instead of the real database
+ *
+ * @group medium
+ * ^--- important, causes tests not to fail with timeout
+ */
+class PageArchivePreMcrTest extends PageArchiveTestBase {
+
+       use PreMcrSchemaOverride;
+
+       /**
+        * @covers PageArchive::getTextFromRow
+        */
+       public function testGetTextFromRow() {
+               $this->hideDeprecated( PageArchive::class . '::getTextFromRow' );
+
+               /** @var SqlBlobStore $blobStore */
+               $blobStore = MediaWikiServices::getInstance()->getBlobStore();
+
+               $textId = $blobStore->getTextIdFromAddress(
+                       $this->firstRev->getSlot( 'main' )->getAddress()
+               );
+
+               $row = (object)[ 'ar_text_id' => $textId ];
+               $text = $this->archivedPage->getTextFromRow( $row );
+               $this->assertSame( 'testing', $text );
+       }
+
+       protected function getExpectedArchiveRows() {
+               /** @var SqlBlobStore $blobStore */
+               $blobStore = MediaWikiServices::getInstance()->getBlobStore();
+
+               return [
+                       [
+                               'ar_minor_edit' => '0',
+                               'ar_user' => '0',
+                               'ar_user_text' => $this->ipEditor,
+                               'ar_actor' => null,
+                               'ar_len' => '11',
+                               'ar_deleted' => '0',
+                               'ar_rev_id' => strval( $this->ipRev->getId() ),
+                               'ar_timestamp' => $this->db->timestamp( $this->ipRev->getTimestamp() ),
+                               'ar_sha1' => '0qdrpxl537ivfnx4gcpnzz0285yxryy',
+                               'ar_page_id' => strval( $this->ipRev->getPageId() ),
+                               'ar_comment_text' => 'just a test',
+                               'ar_comment_data' => null,
+                               'ar_comment_cid' => null,
+                               'ar_content_format' => null,
+                               'ar_content_model' => null,
+                               'ts_tags' => null,
+                               'ar_id' => '2',
+                               'ar_namespace' => '0',
+                               'ar_title' => 'PageArchiveTest_thePage',
+                               'ar_text_id' => (string)$blobStore->getTextIdFromAddress(
+                                       $this->ipRev->getSlot( 'main' )->getAddress()
+                               ),
+                               'ar_parent_id' => strval( $this->ipRev->getParentId() ),
+                       ],
+                       [
+                               'ar_minor_edit' => '0',
+                               'ar_user' => (string)$this->getTestUser()->getUser()->getId(),
+                               'ar_user_text' => $this->getTestUser()->getUser()->getName(),
+                               'ar_actor' => null,
+                               'ar_len' => '7',
+                               'ar_deleted' => '0',
+                               'ar_rev_id' => strval( $this->firstRev->getId() ),
+                               'ar_timestamp' => $this->db->timestamp( $this->firstRev->getTimestamp() ),
+                               'ar_sha1' => 'pr0s8e18148pxhgjfa0gjrvpy8fiyxc',
+                               'ar_page_id' => strval( $this->firstRev->getPageId() ),
+                               'ar_comment_text' => 'testing',
+                               'ar_comment_data' => null,
+                               'ar_comment_cid' => null,
+                               'ar_content_format' => null,
+                               'ar_content_model' => null,
+                               'ts_tags' => null,
+                               'ar_id' => '1',
+                               'ar_namespace' => '0',
+                               'ar_title' => 'PageArchiveTest_thePage',
+                               'ar_text_id' => (string)$blobStore->getTextIdFromAddress(
+                                       $this->firstRev->getSlot( 'main' )->getAddress()
+                               ),
+                               'ar_parent_id' => '0',
+                       ],
+               ];
+       }
+
+}
diff --git a/tests/phpunit/includes/page/PageArchiveTestBase.php b/tests/phpunit/includes/page/PageArchiveTestBase.php
new file mode 100644 (file)
index 0000000..27e5861
--- /dev/null
@@ -0,0 +1,369 @@
+<?php
+use MediaWiki\MediaWikiServices;
+use MediaWiki\Storage\RevisionRecord;
+
+/**
+ * Base class for tests of PageArchive against different database schemas.
+ */
+abstract class PageArchiveTestBase extends MediaWikiTestCase {
+
+       /**
+        * @var int
+        */
+       protected $pageId;
+
+       /**
+        * @var PageArchive $archivedPage
+        */
+       protected $archivedPage;
+
+       /**
+        * A logged out user who edited the page before it was archived.
+        * @var string $ipEditor
+        */
+       protected $ipEditor;
+
+       /**
+        * Revision of the first (initial) edit
+        * @var RevisionRecord
+        */
+       protected $firstRev;
+
+       /**
+        * Revision of the IP edit (the second edit)
+        * @var RevisionRecord
+        */
+       protected $ipRev;
+
+       function __construct( $name = null, array $data = [], $dataName = '' ) {
+               parent::__construct( $name, $data, $dataName );
+
+               $this->tablesUsed = array_merge(
+                       $this->tablesUsed,
+                       [
+                               'page',
+                               'revision',
+                               'ip_changes',
+                               'text',
+                               'archive',
+                               'recentchanges',
+                               'logging',
+                               'page_props',
+                       ]
+               );
+       }
+
+       protected function addCoreDBData() {
+               // Blank out to avoid failures when schema overrides imposed by subclasses
+               // affect revision storage.
+       }
+
+       /**
+        * @return int
+        */
+       abstract protected function getMcrMigrationStage();
+
+       /**
+        * @return string[]
+        */
+       abstract protected function getMcrTablesToReset();
+
+       /**
+        * @return bool
+        */
+       protected function getContentHandlerUseDB() {
+               return true;
+       }
+
+       protected function setUp() {
+               parent::setUp();
+
+               $this->tablesUsed += $this->getMcrTablesToReset();
+
+               $this->setMwGlobals( 'wgCommentTableSchemaMigrationStage', MIGRATION_OLD );
+               $this->setMwGlobals( 'wgActorTableSchemaMigrationStage', MIGRATION_OLD );
+               $this->setMwGlobals( 'wgContentHandlerUseDB', $this->getContentHandlerUseDB() );
+               $this->setMwGlobals(
+                       'wgMultiContentRevisionSchemaMigrationStage',
+                       $this->getMcrMigrationStage()
+               );
+               $this->overrideMwServices();
+
+               // First create our dummy page
+               $page = Title::newFromText( 'PageArchiveTest_thePage' );
+               $page = new WikiPage( $page );
+               $content = ContentHandler::makeContent(
+                       'testing',
+                       $page->getTitle(),
+                       CONTENT_MODEL_WIKITEXT
+               );
+
+               $user = $this->getTestUser()->getUser();
+               $page->doEditContent( $content, 'testing', EDIT_NEW, false, $user );
+
+               $this->pageId = $page->getId();
+               $this->firstRev = $page->getRevision()->getRevisionRecord();
+
+               // Insert IP revision
+               $this->ipEditor = '2001:db8::1';
+
+               $revisionStore = MediaWikiServices::getInstance()->getRevisionStore();
+
+               $ipTimestamp = wfTimestamp(
+                       TS_MW,
+                       wfTimestamp( TS_UNIX, $this->firstRev->getTimestamp() ) + 1
+               );
+
+               $rev = $revisionStore->newMutableRevisionFromArray( [
+                       'text' => 'Lorem Ipsum',
+                       'comment' => 'just a test',
+                       'page' => $page->getId(),
+                       'user_text' => $this->ipEditor,
+                       'timestamp' => $ipTimestamp,
+               ] );
+
+               $dbw = wfGetDB( DB_MASTER );
+               $this->ipRev = $revisionStore->insertRevisionOn( $rev, $dbw );
+
+               // Delete the page
+               $page->doDeleteArticleReal( 'Just a test deletion' );
+
+               $this->archivedPage = new PageArchive( $page->getTitle() );
+       }
+
+       /**
+        * @covers PageArchive::undelete
+        * @covers PageArchive::undeleteRevisions
+        */
+       public function testUndeleteRevisions() {
+               // TODO: MCR: Test undeletion with multiple slots. Check that slots remain untouched.
+
+               // First make sure old revisions are archived
+               $dbr = wfGetDB( DB_REPLICA );
+               $arQuery = Revision::getArchiveQueryInfo();
+               $row = $dbr->selectRow(
+                       $arQuery['tables'],
+                       $arQuery['fields'],
+                       [ 'ar_rev_id' => $this->ipRev->getId() ],
+                       __METHOD__,
+                       [],
+                       $arQuery['joins']
+               );
+               $this->assertEquals( $this->ipEditor, $row->ar_user_text );
+
+               // Should not be in revision
+               $row = $dbr->selectRow( 'revision', '1', [ 'rev_id' => $this->ipRev->getId() ] );
+               $this->assertFalse( $row );
+
+               // Should not be in ip_changes
+               $row = $dbr->selectRow( 'ip_changes', '1', [ 'ipc_rev_id' => $this->ipRev->getId() ] );
+               $this->assertFalse( $row );
+
+               // Restore the page
+               $this->archivedPage->undelete( [] );
+
+               // Should be back in revision
+               $revQuery = Revision::getQueryInfo();
+               $row = $dbr->selectRow(
+                       $revQuery['tables'],
+                       $revQuery['fields'],
+                       [ 'rev_id' => $this->ipRev->getId() ],
+                       __METHOD__,
+                       [],
+                       $revQuery['joins']
+               );
+               $this->assertNotFalse( $row, 'row exists in revision table' );
+               $this->assertEquals( $this->ipEditor, $row->rev_user_text );
+
+               // Should be back in ip_changes
+               $row = $dbr->selectRow( 'ip_changes', [ 'ipc_hex' ], [ 'ipc_rev_id' => $this->ipRev->getId() ] );
+               $this->assertNotFalse( $row, 'row exists in ip_changes table' );
+               $this->assertEquals( IP::toHex( $this->ipEditor ), $row->ipc_hex );
+       }
+
+       abstract protected function getExpectedArchiveRows();
+
+       /**
+        * @covers PageArchive::listRevisions
+        */
+       public function testListRevisions() {
+               $revisions = $this->archivedPage->listRevisions();
+               $this->assertEquals( 2, $revisions->numRows() );
+
+               // Get the rows as arrays
+               $row0 = (array)$revisions->current();
+               $row1 = (array)$revisions->next();
+
+               $expectedRows = $this->getExpectedArchiveRows();
+
+               $this->assertEquals(
+                       $expectedRows[0],
+                       $row0
+               );
+               $this->assertEquals(
+                       $expectedRows[1],
+                       $row1
+               );
+       }
+
+       /**
+        * @covers PageArchive::listPagesBySearch
+        */
+       public function testListPagesBySearch() {
+               $pages = PageArchive::listPagesBySearch( 'PageArchiveTest_thePage' );
+               $this->assertSame( 1, $pages->numRows() );
+
+               $page = (array)$pages->current();
+
+               $this->assertSame(
+                       [
+                               'ar_namespace' => '0',
+                               'ar_title' => 'PageArchiveTest_thePage',
+                               'count' => '2',
+                       ],
+                       $page
+               );
+       }
+
+       /**
+        * @covers PageArchive::listPagesBySearch
+        */
+       public function testListPagesByPrefix() {
+               $pages = PageArchive::listPagesByPrefix( 'PageArchiveTest' );
+               $this->assertSame( 1, $pages->numRows() );
+
+               $page = (array)$pages->current();
+
+               $this->assertSame(
+                       [
+                               'ar_namespace' => '0',
+                               'ar_title' => 'PageArchiveTest_thePage',
+                               'count' => '2',
+                       ],
+                       $page
+               );
+       }
+
+       public function provideGetTextFromRowThrowsInvalidArgumentException() {
+               yield 'missing ar_text_id field' => [ [] ];
+               yield 'ar_text_id is null' => [ [ 'ar_text_id' => null ] ];
+               yield 'ar_text_id is zero' => [ [ 'ar_text_id' => 0 ] ];
+               yield 'ar_text_id is "0"' => [ [ 'ar_text_id' => '0' ] ];
+       }
+
+       /**
+        * @dataProvider provideGetTextFromRowThrowsInvalidArgumentException
+        * @covers PageArchive::getTextFromRow
+        */
+       public function testGetTextFromRowThrowsInvalidArgumentException( array $row ) {
+               $this->hideDeprecated( PageArchive::class . '::getTextFromRow' );
+               $this->setExpectedException( InvalidArgumentException::class );
+
+               $this->archivedPage->getTextFromRow( (object)$row );
+       }
+
+       /**
+        * @covers PageArchive::getLastRevisionText
+        */
+       public function testGetLastRevisionText() {
+               $this->hideDeprecated( PageArchive::class . '::getLastRevisionText' );
+
+               $text = $this->archivedPage->getLastRevisionText();
+               $this->assertSame( 'Lorem Ipsum', $text );
+       }
+
+       /**
+        * @covers PageArchive::getLastRevisionId
+        */
+       public function testGetLastRevisionId() {
+               $id = $this->archivedPage->getLastRevisionId();
+               $this->assertSame( $this->ipRev->getId(), $id );
+       }
+
+       /**
+        * @covers PageArchive::isDeleted
+        */
+       public function testIsDeleted() {
+               $this->assertTrue( $this->archivedPage->isDeleted() );
+       }
+
+       /**
+        * @covers PageArchive::getRevision
+        */
+       public function testGetRevision() {
+               $rev = $this->archivedPage->getRevision( $this->ipRev->getTimestamp() );
+               $this->assertNotNull( $rev );
+               $this->assertSame( $this->pageId, $rev->getPage() );
+
+               $rev = $this->archivedPage->getRevision( '22991212115555' );
+               $this->assertNull( $rev );
+       }
+
+       /**
+        * @covers PageArchive::getRevision
+        */
+       public function testGetArchivedRevision() {
+               $rev = $this->archivedPage->getArchivedRevision( $this->ipRev->getId() );
+               $this->assertNotNull( $rev );
+               $this->assertSame( $this->ipRev->getTimestamp(), $rev->getTimestamp() );
+               $this->assertSame( $this->pageId, $rev->getPage() );
+
+               $rev = $this->archivedPage->getArchivedRevision( 632546 );
+               $this->assertNull( $rev );
+       }
+
+       /**
+        * @covers PageArchive::getPreviousRevision
+        */
+       public function testGetPreviousRevision() {
+               $rev = $this->archivedPage->getPreviousRevision( $this->ipRev->getTimestamp() );
+               $this->assertNotNull( $rev );
+               $this->assertSame( $this->firstRev->getId(), $rev->getId() );
+
+               $rev = $this->archivedPage->getPreviousRevision( $this->firstRev->getTimestamp() );
+               $this->assertNull( $rev );
+
+               // Re-create our dummy page
+               $title = Title::newFromText( 'PageArchiveTest_thePage' );
+               $page = new WikiPage( $title );
+               $content = ContentHandler::makeContent(
+                       'testing again',
+                       $page->getTitle(),
+                       CONTENT_MODEL_WIKITEXT
+               );
+
+               $user = $this->getTestUser()->getUser();
+               $status = $page->doEditContent( $content, 'testing', EDIT_NEW, false, $user );
+
+               /** @var Revision $newRev */
+               $newRev = $status->value['revision'];
+
+               // force the revision timestamp
+               $newTimestamp = wfTimestamp(
+                       TS_MW,
+                       wfTimestamp( TS_UNIX, $this->ipRev->getTimestamp() ) + 1
+               );
+
+               $this->db->update(
+                       'revision',
+                       [ 'rev_timestamp' => $this->db->timestamp( $newTimestamp ) ],
+                       [ 'rev_id' => $newRev->getId() ]
+               );
+
+               // check that we don't get the existing revision too soon.
+               $rev = $this->archivedPage->getPreviousRevision( $newTimestamp );
+               $this->assertNotNull( $rev );
+               $this->assertSame( $this->ipRev->getId(), $rev->getId() );
+
+               // check that we do get the existing revision when appropriate.
+               $afterNewTimestamp = wfTimestamp(
+                       TS_MW,
+                       wfTimestamp( TS_UNIX, $newTimestamp ) + 1
+               );
+
+               $rev = $this->archivedPage->getPreviousRevision( $afterNewTimestamp );
+               $this->assertNotNull( $rev );
+               $this->assertSame( $newRev->getId(), $rev->getId() );
+       }
+
+}
diff --git a/tests/phpunit/includes/page/WikiPageContentHandlerDbTest.php b/tests/phpunit/includes/page/WikiPageContentHandlerDbTest.php
deleted file mode 100644 (file)
index 2d7d6cc..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-<?php
-
-/**
- * @group ContentHandler
- * @group Database
- * @group medium
- */
-class WikiPageContentHandlerDbTest extends WikiPageDbTestBase {
-
-       protected function getContentHandlerUseDB() {
-               return true;
-       }
-
-       /**
-        * @covers WikiPage::getContentModel
-        */
-       public function testGetContentModel() {
-               $page = $this->createPage(
-                       __METHOD__,
-                       "some text",
-                       CONTENT_MODEL_JAVASCRIPT
-               );
-
-               $page = new WikiPage( $page->getTitle() );
-               $this->assertEquals( CONTENT_MODEL_JAVASCRIPT, $page->getContentModel() );
-       }
-
-       /**
-        * @covers WikiPage::getContentHandler
-        */
-       public function testGetContentHandler() {
-               $page = $this->createPage(
-                       __METHOD__,
-                       "some text",
-                       CONTENT_MODEL_JAVASCRIPT
-               );
-
-               $page = new WikiPage( $page->getTitle() );
-               $this->assertEquals( JavaScriptContentHandler::class, get_class( $page->getContentHandler() ) );
-       }
-
-}
index 40c4e1e..aaaa73b 100644 (file)
@@ -1,5 +1,12 @@
 <?php
 
+use MediaWiki\MediaWikiServices;
+use MediaWiki\Storage\RevisionSlotsUpdate;
+use Wikimedia\TestingAccessWrapper;
+
+/**
+ * @covers WikiPage
+ */
 abstract class WikiPageDbTestBase extends MediaWikiLangTestCase {
 
        private $pagesToDelete;
@@ -30,10 +37,33 @@ abstract class WikiPageDbTestBase extends MediaWikiLangTestCase {
                                'iwlinks' ] );
        }
 
+       protected function addCoreDBData() {
+               // Blank out. This would fail with a modified schema, and we don't need it.
+       }
+
+       /**
+        * @return int
+        */
+       abstract protected function getMcrMigrationStage();
+
+       /**
+        * @return string[]
+        */
+       abstract protected function getMcrTablesToReset();
+
        protected function setUp() {
                parent::setUp();
+
+               $this->tablesUsed += $this->getMcrTablesToReset();
+
                $this->setMwGlobals( 'wgContentHandlerUseDB', $this->getContentHandlerUseDB() );
+               $this->setMwGlobals(
+                       'wgMultiContentRevisionSchemaMigrationStage',
+                       $this->getMcrMigrationStage()
+               );
                $this->pagesToDelete = [];
+
+               $this->overrideMwServices();
        }
 
        protected function tearDown() {
@@ -74,31 +104,144 @@ abstract class WikiPageDbTestBase extends MediaWikiLangTestCase {
        /**
         * @param string|Title|WikiPage $page
         * @param string $text
-        * @param int $model
+        * @param int|null $model
         *
         * @return WikiPage
         */
-       protected function createPage( $page, $text, $model = null ) {
+       protected function createPage( $page, $text, $model = null, $user = null ) {
                if ( is_string( $page ) || $page instanceof Title ) {
                        $page = $this->newPage( $page, $model );
                }
 
                $content = ContentHandler::makeContent( $text, $page->getTitle(), $model );
-               $page->doEditContent( $content, "testing", EDIT_NEW );
+               $page->doEditContent( $content, "testing", EDIT_NEW, false, $user );
 
                return $page;
        }
 
        /**
-        * @covers WikiPage::doEditContent
-        * @covers WikiPage::doModify
-        * @covers WikiPage::doCreate
+        * @covers WikiPage::prepareContentForEdit
+        */
+       public function testPrepareContentForEdit() {
+               $user = $this->getTestUser()->getUser();
+               $sysop = $this->getTestUser( [ 'sysop' ] )->getUser();
+
+               $page = $this->createPage( __METHOD__, __METHOD__, null, $user );
+               $title = $page->getTitle();
+
+               $content = ContentHandler::makeContent(
+                       "[[Lorem ipsum]] dolor sit amet, consetetur sadipscing elitr, sed diam "
+                       . " nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat.",
+                       $title,
+                       CONTENT_MODEL_WIKITEXT
+               );
+               $content2 = ContentHandler::makeContent(
+                       "At vero eos et accusam et justo duo [[dolores]] et ea rebum. "
+                       . "Stet clita kasd [[gubergren]], no sea takimata sanctus est. ~~~~",
+                       $title,
+                       CONTENT_MODEL_WIKITEXT
+               );
+
+               $edit = $page->prepareContentForEdit( $content, null, $user, null, false );
+
+               $this->assertInstanceOf(
+                       ParserOptions::class,
+                       $edit->popts,
+                       "pops"
+               );
+               $this->assertContains( '</a>', $edit->output->getText(), "output" );
+               $this->assertContains(
+                       'consetetur sadipscing elitr',
+                       $edit->output->getText(),
+                       "output"
+               );
+
+               $this->assertTrue( $content->equals( $edit->newContent ), "newContent field" );
+               $this->assertTrue( $content->equals( $edit->pstContent ), "pstContent field" );
+               $this->assertSame( $edit->output, $edit->output, "output field" );
+               $this->assertSame( $edit->popts, $edit->popts, "popts field" );
+               $this->assertSame( null, $edit->revid, "revid field" );
+
+               // Re-using the prepared info if possible
+               $sameEdit = $page->prepareContentForEdit( $content, null, $user, null, false );
+               $this->assertEquals( $edit, $sameEdit, 'equivalent PreparedEdit' );
+               $this->assertSame( $edit->pstContent, $sameEdit->pstContent, 're-use output' );
+               $this->assertSame( $edit->output, $sameEdit->output, 're-use output' );
+
+               // Not re-using the same PreparedEdit if not possible
+               $rev = $page->getRevision();
+               $edit2 = $page->prepareContentForEdit( $content2, null, $user, null, false );
+               $this->assertNotEquals( $edit, $edit2 );
+               $this->assertContains( 'At vero eos', $edit2->pstContent->serialize(), "content" );
+
+               // Check pre-safe transform
+               $this->assertContains( '[[gubergren]]', $edit2->pstContent->serialize() );
+               $this->assertNotContains( '~~~~', $edit2->pstContent->serialize() );
+
+               $edit3 = $page->prepareContentForEdit( $content2, null, $sysop, null, false );
+               $this->assertNotEquals( $edit2, $edit3 );
+
+               // TODO: test with passing revision, then same without revision.
+       }
+
+       /**
         * @covers WikiPage::doEditUpdates
         */
+       public function testDoEditUpdates() {
+               $user = $this->getTestUser()->getUser();
+
+               // NOTE: if site stats get out of whack and drop below 0,
+               // that causes a DB error during tear-down. So bump the
+               // numbers high enough to not drop below 0.
+               $siteStatsUpdate = SiteStatsUpdate::factory(
+                       [ 'edits' => 1000, 'articles' => 1000, 'pages' => 1000 ]
+               );
+               $siteStatsUpdate->doUpdate();
+
+               $page = $this->createPage( __METHOD__, __METHOD__ );
+
+               $revision = new Revision(
+                       [
+                               'id' => 9989,
+                               'page' => $page->getId(),
+                               'title' => $page->getTitle(),
+                               'comment' => __METHOD__,
+                               'minor_edit' => true,
+                               'text' => __METHOD__ . ' [[|foo]][[bar]]', // PST turns [[|foo]] into [[foo]]
+                               'user' => $user->getId(),
+                               'user_text' => $user->getName(),
+                               'timestamp' => '20170707040404',
+                               'content_model' => CONTENT_MODEL_WIKITEXT,
+                               'content_format' => CONTENT_FORMAT_WIKITEXT,
+                       ]
+               );
+
+               $page->doEditUpdates( $revision, $user );
+
+               // TODO: test various options; needs temporary hooks
+
+               $dbr = wfGetDB( DB_REPLICA );
+               $res = $dbr->select( 'pagelinks', '*', [ 'pl_from' => $page->getId() ] );
+               $n = $res->numRows();
+               $res->free();
+
+               $this->assertEquals( 1, $n, 'pagelinks should contain only one link if PST was not applied' );
+       }
+
+       /**
+        * @covers WikiPage::doEditContent
+        * @covers WikiPage::prepareContentForEdit
+        */
        public function testDoEditContent() {
+               $this->setMwGlobals( 'wgPageCreationLog', true );
+
                $page = $this->newPage( __METHOD__ );
                $title = $page->getTitle();
 
+               $user1 = $this->getTestUser()->getUser();
+               // Use the confirmed group for user2 to make sure the user is different
+               $user2 = $this->getTestUser( [ 'confirmed' ] )->getUser();
+
                $content = ContentHandler::makeContent(
                        "[[Lorem ipsum]] dolor sit amet, consetetur sadipscing elitr, sed diam "
                                . " nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat.",
@@ -106,15 +249,41 @@ abstract class WikiPageDbTestBase extends MediaWikiLangTestCase {
                        CONTENT_MODEL_WIKITEXT
                );
 
-               $page->doEditContent( $content, "[[testing]] 1" );
+               $preparedEditBefore = $page->prepareContentForEdit( $content, null, $user1 );
+
+               $status = $page->doEditContent( $content, "[[testing]] 1", EDIT_NEW, false, $user1 );
+
+               $this->assertTrue( $status->isOK(), 'OK' );
+               $this->assertTrue( $status->value['new'], 'new' );
+               $this->assertNotNull( $status->value['revision'], 'revision' );
+               $this->assertSame( $status->value['revision']->getId(), $page->getRevision()->getId() );
+               $this->assertSame( $status->value['revision']->getSha1(), $page->getRevision()->getSha1() );
+               $this->assertTrue( $status->value['revision']->getContent()->equals( $content ), 'equals' );
+
+               $rev = $page->getRevision();
+               $preparedEditAfter = $page->prepareContentForEdit( $content, $rev, $user1 );
+
+               $this->assertNotNull( $rev->getRecentChange() );
+               $this->assertSame( $rev->getId(), (int)$rev->getRecentChange()->getAttribute( 'rc_this_oldid' ) );
+
+               // make sure that cached ParserOutput gets re-used throughout
+               $this->assertSame( $preparedEditBefore->output, $preparedEditAfter->output );
+
+               $id = $page->getId();
+
+               // Test page creation logging
+               $this->assertSelect(
+                       'logging',
+                       [ 'log_type', 'log_action' ],
+                       [ 'log_page' => $id ],
+                       [ [ 'create', 'create' ] ]
+               );
 
                $this->assertTrue( $title->getArticleID() > 0, "Title object should have new page id" );
-               $this->assertTrue( $page->getId() > 0, "WikiPage should have new page id" );
+               $this->assertTrue( $id > 0, "WikiPage should have new page id" );
                $this->assertTrue( $title->exists(), "Title object should indicate that the page now exists" );
                $this->assertTrue( $page->exists(), "WikiPage object should indicate that the page now exists" );
 
-               $id = $page->getId();
-
                # ------------------------
                $dbr = wfGetDB( DB_REPLICA );
                $res = $dbr->select( 'pagelinks', '*', [ 'pl_from' => $id ] );
@@ -129,21 +298,47 @@ abstract class WikiPageDbTestBase extends MediaWikiLangTestCase {
                $retrieved = $page->getContent();
                $this->assertTrue( $content->equals( $retrieved ), 'retrieved content doesn\'t equal original' );
 
+               # ------------------------
+               $page = new WikiPage( $title );
+
+               // try null edit, with a different user
+               $status = $page->doEditContent( $content, 'This changes nothing', EDIT_UPDATE, false, $user2 );
+               $this->assertTrue( $status->isOK(), 'OK' );
+               $this->assertFalse( $status->value['new'], 'new' );
+               $this->assertNull( $status->value['revision'], 'revision' );
+               $this->assertNotNull( $page->getRevision() );
+               $this->assertTrue( $page->getRevision()->getContent()->equals( $content ), 'equals' );
+
                # ------------------------
                $content = ContentHandler::makeContent(
                        "At vero eos et accusam et justo duo [[dolores]] et ea rebum. "
-                               . "Stet clita kasd [[gubergren]], no sea takimata sanctus est.",
+                               . "Stet clita kasd [[gubergren]], no sea takimata sanctus est. ~~~~",
                        $title,
                        CONTENT_MODEL_WIKITEXT
                );
 
-               $page->doEditContent( $content, "testing 2" );
+               $status = $page->doEditContent( $content, "testing 2", EDIT_UPDATE );
+               $this->assertTrue( $status->isOK(), 'OK' );
+               $this->assertFalse( $status->value['new'], 'new' );
+               $this->assertNotNull( $status->value['revision'], 'revision' );
+               $this->assertSame( $status->value['revision']->getId(), $page->getRevision()->getId() );
+               $this->assertSame( $status->value['revision']->getSha1(), $page->getRevision()->getSha1() );
+               $this->assertFalse(
+                       $status->value['revision']->getContent()->equals( $content ),
+                       'not equals (PST must substitute signature)'
+               );
+
+               $rev = $page->getRevision();
+               $this->assertNotNull( $rev->getRecentChange() );
+               $this->assertSame( $rev->getId(), (int)$rev->getRecentChange()->getAttribute( 'rc_this_oldid' ) );
 
                # ------------------------
                $page = new WikiPage( $title );
 
                $retrieved = $page->getContent();
-               $this->assertTrue( $content->equals( $retrieved ), 'retrieved content doesn\'t equal original' );
+               $newText = $retrieved->serialize();
+               $this->assertContains( '[[gubergren]]', $newText, 'New text must replace old text.' );
+               $this->assertNotContains( '~~~~', $newText, 'PST must substitute signature.' );
 
                # ------------------------
                $dbr = wfGetDB( DB_REPLICA );
@@ -154,6 +349,26 @@ abstract class WikiPageDbTestBase extends MediaWikiLangTestCase {
                $this->assertEquals( 2, $n, 'pagelinks should contain two links from the page' );
        }
 
+       /**
+        * @covers WikiPage::doEditContent
+        */
+       public function testDoEditContent_twice() {
+               $title = Title::newFromText( __METHOD__ );
+               $page = WikiPage::factory( $title );
+               $content = ContentHandler::makeContent( '$1 van $2', $title );
+
+               // Make sure we can do the exact same save twice.
+               // This tests checks that internal caches are reset as appropriate.
+               $status1 = $page->doEditContent( $content, __METHOD__ );
+               $status2 = $page->doEditContent( $content, __METHOD__ );
+
+               $this->assertTrue( $status1->isOK(), 'OK' );
+               $this->assertTrue( $status2->isOK(), 'OK' );
+
+               $this->assertTrue( isset( $status1->value['revision'] ), 'OK' );
+               $this->assertFalse( isset( $status2->value['revision'] ), 'OK' );
+       }
+
        /**
         * Undeletion is covered in PageArchiveTest::testUndeleteRevisions()
         * TODO: Revision deletion
@@ -841,6 +1056,10 @@ more stuff
                // Use the confirmed group for user2 to make sure the user is different
                $user2 = $this->getTestUser( [ 'confirmed' ] )->getUser();
 
+               // make sure we can test autopatrolling
+               $this->setMwGlobals( 'wgUseRCPatrol', true );
+
+               // TODO: MCR: test rollback of multiple slots!
                $page = $this->newPage( __METHOD__ );
 
                // Make some edits
@@ -896,57 +1115,22 @@ more stuff
                $this->assertEquals( $rev2->getSha1(), $page->getRevision()->getSha1(),
                        "rollback did not revert to the correct revision" );
                $this->assertEquals( "one\n\ntwo", $page->getContent()->getNativeData() );
-       }
-
-       /**
-        * @covers WikiPage::doRollback
-        * @covers WikiPage::commitRollback
-        */
-       public function testDoRollback_simple() {
-               $admin = $this->getTestSysop()->getUser();
-
-               $text = "one";
-               $page = $this->newPage( __METHOD__ );
-               $page->doEditContent(
-                       ContentHandler::makeContent( $text, $page->getTitle(), CONTENT_MODEL_WIKITEXT ),
-                       "section one",
-                       EDIT_NEW,
-                       false,
-                       $admin
-               );
-               $rev1 = $page->getRevision();
 
-               $user1 = $this->getTestUser()->getUser();
-               $text .= "\n\ntwo";
-               $page = new WikiPage( $page->getTitle() );
-               $page->doEditContent(
-                       ContentHandler::makeContent( $text, $page->getTitle(), CONTENT_MODEL_WIKITEXT ),
-                       "adding section two",
-                       0,
-                       false,
-                       $user1
+               $rc = MediaWikiServices::getInstance()->getRevisionStore()->getRecentChange(
+                       $page->getRevision()->getRevisionRecord()
                );
 
-               # now, try the rollback
-               $token = $admin->getEditToken( 'rollback' );
-               $errors = $page->doRollback(
-                       $user1->getName(),
-                       "testing revert",
-                       $token,
-                       false,
-                       $details,
-                       $admin
+               $this->assertNotNull( $rc, 'RecentChanges entry' );
+               $this->assertEquals(
+                       RecentChange::PRC_AUTOPATROLLED,
+                       $rc->getAttribute( 'rc_patrolled' ),
+                       'rc_patrolled'
                );
 
-               if ( $errors ) {
-                       $this->fail( "Rollback failed:\n" . print_r( $errors, true )
-                               . ";\n" . print_r( $details, true ) );
-               }
-
-               $page = new WikiPage( $page->getTitle() );
-               $this->assertEquals( $rev1->getSha1(), $page->getRevision()->getSha1(),
-                       "rollback did not revert to the correct revision" );
-               $this->assertEquals( "one", $page->getContent()->getNativeData() );
+               // TODO: MCR: assert origin once we write slot data
+               // $mainSlot = $page->getRevision()->getRevisionRecord()->getSlot( 'main' );
+               // $this->assertTrue( $mainSlot->isInherited(), 'isInherited' );
+               // $this->assertSame( $rev2->getId(), $mainSlot->getOrigin(), 'getOrigin' );
        }
 
        /**
@@ -1210,6 +1394,44 @@ more stuff
                $this->assertEquals( WikiPage::class, get_class( $page ) );
        }
 
+       /**
+        * @covers WikiPage::loadPageData
+        * @covers WikiPage::wasLoadedFrom
+        */
+       public function testLoadPageData() {
+               $title = Title::makeTitle( NS_MAIN, 'SomePage' );
+               $page = WikiPage::factory( $title );
+
+               $this->assertFalse( $page->wasLoadedFrom( IDBAccessObject::READ_NORMAL ) );
+               $this->assertFalse( $page->wasLoadedFrom( IDBAccessObject::READ_LATEST ) );
+               $this->assertFalse( $page->wasLoadedFrom( IDBAccessObject::READ_LOCKING ) );
+               $this->assertFalse( $page->wasLoadedFrom( IDBAccessObject::READ_EXCLUSIVE ) );
+
+               $page->loadPageData( IDBAccessObject::READ_NORMAL );
+               $this->assertTrue( $page->wasLoadedFrom( IDBAccessObject::READ_NORMAL ) );
+               $this->assertFalse( $page->wasLoadedFrom( IDBAccessObject::READ_LATEST ) );
+               $this->assertFalse( $page->wasLoadedFrom( IDBAccessObject::READ_LOCKING ) );
+               $this->assertFalse( $page->wasLoadedFrom( IDBAccessObject::READ_EXCLUSIVE ) );
+
+               $page->loadPageData( IDBAccessObject::READ_LATEST );
+               $this->assertTrue( $page->wasLoadedFrom( IDBAccessObject::READ_NORMAL ) );
+               $this->assertTrue( $page->wasLoadedFrom( IDBAccessObject::READ_LATEST ) );
+               $this->assertFalse( $page->wasLoadedFrom( IDBAccessObject::READ_LOCKING ) );
+               $this->assertFalse( $page->wasLoadedFrom( IDBAccessObject::READ_EXCLUSIVE ) );
+
+               $page->loadPageData( IDBAccessObject::READ_LOCKING );
+               $this->assertTrue( $page->wasLoadedFrom( IDBAccessObject::READ_NORMAL ) );
+               $this->assertTrue( $page->wasLoadedFrom( IDBAccessObject::READ_LATEST ) );
+               $this->assertTrue( $page->wasLoadedFrom( IDBAccessObject::READ_LOCKING ) );
+               $this->assertFalse( $page->wasLoadedFrom( IDBAccessObject::READ_EXCLUSIVE ) );
+
+               $page->loadPageData( IDBAccessObject::READ_EXCLUSIVE );
+               $this->assertTrue( $page->wasLoadedFrom( IDBAccessObject::READ_NORMAL ) );
+               $this->assertTrue( $page->wasLoadedFrom( IDBAccessObject::READ_LATEST ) );
+               $this->assertTrue( $page->wasLoadedFrom( IDBAccessObject::READ_LOCKING ) );
+               $this->assertTrue( $page->wasLoadedFrom( IDBAccessObject::READ_EXCLUSIVE ) );
+       }
+
        /**
         * @dataProvider provideCommentMigrationOnDeletion
         *
@@ -2066,4 +2288,106 @@ more stuff
                );
        }
 
+       /**
+        * @covers WikiPage::newPageUpdater
+        * @covers WikiPage::getDerivedDataUpdater
+        */
+       public function testNewPageUpdater() {
+               $user = $this->getTestUser()->getUser();
+               $page = $this->newPage( __METHOD__, __METHOD__ );
+
+               /** @var Content $content */
+               $content = $this->getMockBuilder( WikitextContent::class )
+                       ->setConstructorArgs( [ 'Hello World' ] )
+                       ->setMethods( [ 'getParserOutput' ] )
+                       ->getMock();
+               $content->expects( $this->once() )
+                       ->method( 'getParserOutput' )
+                       ->willReturn( new ParserOutput( 'HTML' ) );
+
+               $preparedEditBefore = $page->prepareContentForEdit( $content, null, $user );
+
+               // provide context, so the cache can be kept in place
+               $slotsUpdate = new revisionSlotsUpdate();
+               $slotsUpdate->modifyContent( 'main', $content );
+
+               $updater = $page->newPageUpdater( $user, $slotsUpdate );
+               $updater->setContent( 'main', $content );
+               $revision = $updater->saveRevision(
+                       CommentStoreComment::newUnsavedComment( 'test' ),
+                       EDIT_NEW
+               );
+
+               $preparedEditAfter = $page->prepareContentForEdit( $content, $revision, $user );
+
+               $this->assertSame( $revision->getId(), $page->getLatest() );
+
+               // Parsed output must remain cached throughout.
+               $this->assertSame( $preparedEditBefore->output, $preparedEditAfter->output );
+       }
+
+       /**
+        * @covers WikiPage::newPageUpdater
+        * @covers WikiPage::getDerivedDataUpdater
+        */
+       public function testGetDerivedDataUpdater() {
+               $admin = $this->getTestSysop()->getUser();
+
+               /** @var object $page */
+               $page = $this->createPage( __METHOD__, __METHOD__ );
+               $page = TestingAccessWrapper::newFromObject( $page );
+
+               $revision = $page->getRevision()->getRevisionRecord();
+               $user = $revision->getUser();
+
+               $slotsUpdate = new RevisionSlotsUpdate();
+               $slotsUpdate->modifyContent( 'main', new WikitextContent( 'Hello World' ) );
+
+               // get a virgin updater
+               $updater1 = $page->getDerivedDataUpdater( $user );
+               $this->assertFalse( $updater1->isUpdatePrepared() );
+
+               $updater1->prepareUpdate( $revision );
+
+               // Re-use updater with same revision or content, even if base changed
+               $this->assertSame( $updater1, $page->getDerivedDataUpdater( $user, $revision ) );
+
+               $slotsUpdate = RevisionSlotsUpdate::newFromContent(
+                       [ 'main' => $revision->getContent( 'main' ) ]
+               );
+               $this->assertSame( $updater1, $page->getDerivedDataUpdater( $user, null, $slotsUpdate ) );
+
+               // Don't re-use for edit if base revision ID changed
+               $this->assertNotSame(
+                       $updater1,
+                       $page->getDerivedDataUpdater( $user, null, $slotsUpdate, true )
+               );
+
+               // Don't re-use with different user
+               $updater2a = $page->getDerivedDataUpdater( $admin, null, $slotsUpdate );
+               $updater2a->prepareContent( $admin, $slotsUpdate, false );
+
+               $updater2b = $page->getDerivedDataUpdater( $user, null, $slotsUpdate );
+               $updater2b->prepareContent( $user, $slotsUpdate, false );
+               $this->assertNotSame( $updater2a, $updater2b );
+
+               // Don't re-use with different content
+               $updater3 = $page->getDerivedDataUpdater( $admin, null, $slotsUpdate );
+               $updater3->prepareUpdate( $revision );
+               $this->assertNotSame( $updater2b, $updater3 );
+
+               // Don't re-use if no context given
+               $updater4 = $page->getDerivedDataUpdater( $admin );
+               $updater4->prepareUpdate( $revision );
+               $this->assertNotSame( $updater3, $updater4 );
+
+               // Don't re-use if AGAIN no context given
+               $updater5 = $page->getDerivedDataUpdater( $admin );
+               $this->assertNotSame( $updater4, $updater5 );
+
+               // Don't re-use cached "virgin" unprepared updater
+               $updater6 = $page->getDerivedDataUpdater( $admin, $revision );
+               $this->assertNotSame( $updater5, $updater6 );
+       }
+
 }
diff --git a/tests/phpunit/includes/page/WikiPageMcrDbTest.php b/tests/phpunit/includes/page/WikiPageMcrDbTest.php
new file mode 100644 (file)
index 0000000..02567f8
--- /dev/null
@@ -0,0 +1,28 @@
+<?php
+
+use MediaWiki\Tests\Storage\McrSchemaOverride;
+
+/**
+ * Tests WikiPage against the MCR DB schema after schema migration.
+ *
+ * @covers WikiPage
+ *
+ * @group WikiPage
+ * @group Storage
+ * @group ContentHandler
+ * @group Database
+ * @group medium
+ */
+class WikiPageMcrDbTest extends WikiPageDbTestBase {
+
+       use McrSchemaOverride;
+
+       public function setUp() {
+               parent::setUp();
+       }
+
+       protected function getContentHandlerUseDB() {
+               return true;
+       }
+
+}
diff --git a/tests/phpunit/includes/page/WikiPageMcrReadNewDbTest.php b/tests/phpunit/includes/page/WikiPageMcrReadNewDbTest.php
new file mode 100644 (file)
index 0000000..9e2ff09
--- /dev/null
@@ -0,0 +1,23 @@
+<?php
+use MediaWiki\Tests\Storage\McrReadNewSchemaOverride;
+
+/**
+ * Tests WikiPage against the intermediate MCR DB schema for use during schema migration.
+ *
+ * @covers WikiPage
+ *
+ * @group WikiPage
+ * @group Storage
+ * @group ContentHandler
+ * @group Database
+ * @group medium
+ */
+class WikiPageMcrReadNewDbTest extends WikiPageDbTestBase {
+
+       use McrReadNewSchemaOverride;
+
+       protected function getContentHandlerUseDB() {
+               return true;
+       }
+
+}
diff --git a/tests/phpunit/includes/page/WikiPageMcrWriteBothDbTest.php b/tests/phpunit/includes/page/WikiPageMcrWriteBothDbTest.php
new file mode 100644 (file)
index 0000000..78bbfa7
--- /dev/null
@@ -0,0 +1,23 @@
+<?php
+use MediaWiki\Tests\Storage\McrWriteBothSchemaOverride;
+
+/**
+ * Tests WikiPage against the intermediate MCR DB schema for use during schema migration.
+ *
+ * @covers WikiPage
+ *
+ * @group WikiPage
+ * @group Storage
+ * @group ContentHandler
+ * @group Database
+ * @group medium
+ */
+class WikiPageMcrWriteBothDbTest extends WikiPageDbTestBase {
+
+       use McrWriteBothSchemaOverride;
+
+       protected function getContentHandlerUseDB() {
+               return true;
+       }
+
+}
diff --git a/tests/phpunit/includes/page/WikiPageNoContentHandlerDbTest.php b/tests/phpunit/includes/page/WikiPageNoContentHandlerDbTest.php
deleted file mode 100644 (file)
index a6ce185..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-<?php
-
-/**
- * @group ContentHandler
- * @group Database
- * @group medium
- */
-class WikiPageNoContentHandlerDbTest extends WikiPageDbTestBase {
-
-       protected function getContentHandlerUseDB() {
-               return false;
-       }
-
-}
diff --git a/tests/phpunit/includes/page/WikiPageNoContentModelDbTest.php b/tests/phpunit/includes/page/WikiPageNoContentModelDbTest.php
new file mode 100644 (file)
index 0000000..7c9c657
--- /dev/null
@@ -0,0 +1,23 @@
+<?php
+use MediaWiki\Tests\Storage\PreMcrSchemaOverride;
+
+/**
+ * Tests WikiPage against the pre-MCR, pre ContentHandler DB schema.
+ *
+ * @covers WikiPage
+ *
+ * @group WikiPage
+ * @group Storage
+ * @group ContentHandler
+ * @group Database
+ * @group medium
+ */
+class WikiPageNoContentModelDbTest extends WikiPageDbTestBase {
+
+       use PreMcrSchemaOverride;
+
+       protected function getContentHandlerUseDB() {
+               return false;
+       }
+
+}
diff --git a/tests/phpunit/includes/page/WikiPagePreMcrDbTest.php b/tests/phpunit/includes/page/WikiPagePreMcrDbTest.php
new file mode 100644 (file)
index 0000000..3e7c8fa
--- /dev/null
@@ -0,0 +1,51 @@
+<?php
+use MediaWiki\Tests\Storage\PreMcrSchemaOverride;
+
+/**
+ * Tests WikiPage against the pre-MCR DB schema.
+ *
+ * @covers WikiPage
+ *
+ * @group WikiPage
+ * @group Storage
+ * @group ContentHandler
+ * @group Database
+ * @group medium
+ */
+class WikiPagePreMcrDbTest extends WikiPageDbTestBase {
+
+       use PreMcrSchemaOverride;
+
+       protected function getContentHandlerUseDB() {
+               return true;
+       }
+
+       /**
+        * @covers WikiPage::getContentModel
+        */
+       public function testGetContentModel() {
+               $page = $this->createPage(
+                       __METHOD__,
+                       "some text",
+                       CONTENT_MODEL_JAVASCRIPT
+               );
+
+               $page = new WikiPage( $page->getTitle() );
+               $this->assertEquals( CONTENT_MODEL_JAVASCRIPT, $page->getContentModel() );
+       }
+
+       /**
+        * @covers WikiPage::getContentHandler
+        */
+       public function testGetContentHandler() {
+               $page = $this->createPage(
+                       __METHOD__,
+                       "some text",
+                       CONTENT_MODEL_JAVASCRIPT
+               );
+
+               $page = new WikiPage( $page->getTitle() );
+               $this->assertEquals( JavaScriptContentHandler::class, get_class( $page->getContentHandler() ) );
+       }
+
+}
index 86b496e..02a4a25 100644 (file)
@@ -38,10 +38,7 @@ class MagicVariableTest extends MediaWikiTestCase {
                parent::setUp();
 
                $contLang = Language::factory( 'en' );
-               $this->setMwGlobals( [
-                       'wgLanguageCode' => 'en',
-                       'wgContLang' => $contLang,
-               ] );
+               $this->setContentLang( $contLang );
 
                $this->testParser = new Parser();
                $this->testParser->Options( ParserOptions::newFromUserAndLang( new User, $contLang ) );
index 8c61b03..29f1c8c 100644 (file)
@@ -42,6 +42,68 @@ class ParserOptionsTest extends MediaWikiTestCase {
                parent::tearDown();
        }
 
+       public function testNewCanonical() {
+               $wgUser = $this->getMutableTestUser()->getUser();
+               $wgLang = Language::factory( 'fr' );
+               $wgContLang = Language::factory( 'qqx' );
+
+               $this->setContentLang( $wgContLang );
+               $this->setMwGlobals( [
+                       'wgUser' => $wgUser,
+                       'wgLang' => $wgLang,
+               ] );
+
+               $user = $this->getMutableTestUser()->getUser();
+               $lang = Language::factory( 'de' );
+               $lang2 = Language::factory( 'bug' );
+               $context = new DerivativeContext( RequestContext::getMain() );
+               $context->setUser( $user );
+               $context->setLanguage( $lang );
+
+               // No parameters picks up $wgUser and $wgLang
+               $popt = ParserOptions::newCanonical();
+               $this->assertSame( $wgUser, $popt->getUser() );
+               $this->assertSame( $wgLang, $popt->getUserLangObj() );
+
+               // Just a user uses $wgLang
+               $popt = ParserOptions::newCanonical( $user );
+               $this->assertSame( $user, $popt->getUser() );
+               $this->assertSame( $wgLang, $popt->getUserLangObj() );
+
+               // Just a language uses $wgUser
+               $popt = ParserOptions::newCanonical( null, $lang );
+               $this->assertSame( $wgUser, $popt->getUser() );
+               $this->assertSame( $lang, $popt->getUserLangObj() );
+
+               // Passing both works
+               $popt = ParserOptions::newCanonical( $user, $lang );
+               $this->assertSame( $user, $popt->getUser() );
+               $this->assertSame( $lang, $popt->getUserLangObj() );
+
+               // Passing 'canonical' uses an anon and $wgContLang, and ignores
+               // any passed $userLang
+               $popt = ParserOptions::newCanonical( 'canonical' );
+               $this->assertTrue( $popt->getUser()->isAnon() );
+               $this->assertSame( $wgContLang, $popt->getUserLangObj() );
+               $popt = ParserOptions::newCanonical( 'canonical', $lang2 );
+               $this->assertSame( $wgContLang, $popt->getUserLangObj() );
+
+               // Passing an IContextSource uses the user and lang from it, and ignores
+               // any passed $userLang
+               $popt = ParserOptions::newCanonical( $context );
+               $this->assertSame( $user, $popt->getUser() );
+               $this->assertSame( $lang, $popt->getUserLangObj() );
+               $popt = ParserOptions::newCanonical( $context, $lang2 );
+               $this->assertSame( $lang, $popt->getUserLangObj() );
+
+               // Passing something else raises an exception
+               try {
+                       $popt = ParserOptions::newCanonical( 'bogus' );
+                       $this->fail( 'Excpected exception not thrown' );
+               } catch ( InvalidArgumentException $ex ) {
+               }
+       }
+
        /**
         * @dataProvider provideIsSafeToCache
         * @param bool $expect Expected value
index 62ab44c..296691d 100644 (file)
@@ -66,7 +66,7 @@ class DefaultPreferencesFactoryTest extends MediaWikiTestCase {
        public function testGetForm() {
                $testUser = $this->getTestUser();
                $form = $this->getPreferencesFactory()->getForm( $testUser->getUser(), $this->context );
-               $this->assertInstanceOf( PreferencesForm::class, $form );
+               $this->assertInstanceOf( PreferencesFormLegacy::class, $form );
                $this->assertCount( 5, $form->getPreferenceSections() );
        }
 
@@ -164,8 +164,9 @@ class DefaultPreferencesFactoryTest extends MediaWikiTestCase {
                        }
                );
 
+               /** @var DefaultPreferencesFactory $factory */
                $factory = TestingAccessWrapper::newFromObject( $this->getPreferencesFactory() );
-               $factory->saveFormData( $newOptions, $form );
+               $factory->saveFormData( $newOptions, $form, [] );
        }
 
        /**
diff --git a/tests/phpunit/includes/preferences/FiltersTest.php b/tests/phpunit/includes/preferences/FiltersTest.php
new file mode 100644 (file)
index 0000000..60b01b8
--- /dev/null
@@ -0,0 +1,141 @@
+<?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\Preferences\IntvalFilter;
+use MediaWiki\Preferences\MultiUsernameFilter;
+use MediaWiki\Preferences\TimezoneFilter;
+
+/**
+ * @group Preferences
+ */
+class FiltersTest extends MediaWikiTestCase {
+       /**
+        * @covers MediaWiki\Preferences\IntvalFilter::filterFromForm()
+        * @covers MediaWiki\Preferences\IntvalFilter::filterForForm()
+        */
+       public function testIntvalFilter() {
+               $filter = new IntvalFilter();
+               self::assertSame( 0, $filter->filterFromForm( '0' ) );
+               self::assertSame( 3, $filter->filterFromForm( '3' ) );
+               self::assertSame( '123', $filter->filterForForm( '123' ) );
+       }
+
+       /**
+        * @covers       MediaWiki\Preferences\TimezoneFilter::filterFromForm()
+        * @dataProvider provideTimezoneFilter
+        *
+        * @param string $input
+        * @param string $expected
+        */
+       public function testTimezoneFilter( $input, $expected ) {
+               $filter = new TimezoneFilter();
+               $result = $filter->filterFromForm( $input );
+               self::assertEquals( $expected, $result );
+       }
+
+       public function provideTimezoneFilter() {
+               return [
+                       [ 'ZoneInfo', 'Offset|0' ],
+                       [ 'ZoneInfo|bogus', 'Offset|0' ],
+                       [ 'System', 'System' ],
+                       [ '2:30', 'Offset|150' ],
+               ];
+       }
+
+       /**
+        * @covers MediaWiki\Preferences\MultiUsernameFilter::filterFromForm()
+        * @dataProvider provideMultiUsernameFilterFrom
+        *
+        * @param string $input
+        * @param string|null $expected
+        */
+       public function testMultiUsernameFilterFrom( $input, $expected ) {
+               $filter = $this->makeMultiUsernameFilter();
+               $result = $filter->filterFromForm( $input );
+               self::assertSame( $expected, $result );
+       }
+
+       public function provideMultiUsernameFilterFrom() {
+               return [
+                       [ '', null ],
+                       [ "\n\n\n", null ],
+                       [ 'Foo', '1' ],
+                       [ "\n\n\nFoo\nBar\n", "1\n2" ],
+                       [ "Baz\nInvalid\nFoo", "3\n1" ],
+                       [ "Invalid", null ],
+                       [ "Invalid\n\n\nInvalid\n", null ],
+               ];
+       }
+
+       /**
+        * @covers MediaWiki\Preferences\MultiUsernameFilter::filterForForm()
+        * @dataProvider provideMultiUsernameFilterFor
+        *
+        * @param string $input
+        * @param string $expected
+        */
+       public function testMultiUsernameFilterFor( $input, $expected ) {
+               $filter = $this->makeMultiUsernameFilter();
+               $result = $filter->filterForForm( $input );
+               self::assertSame( $expected, $result );
+       }
+
+       public function provideMultiUsernameFilterFor() {
+               return [
+                       [ '', '' ],
+                       [ "\n", '' ],
+                       [ '1', 'Foo' ],
+                       [ "\n1\n\n2\377\n", "Foo\nBar" ],
+                       [ "666\n667", '' ],
+               ];
+       }
+
+       private function makeMultiUsernameFilter() {
+               $userMapping = [
+                       'Foo' => 1,
+                       'Bar' => 2,
+                       'Baz' => 3,
+               ];
+               $flipped = array_flip( $userMapping );
+               $idLookup = self::getMockBuilder( CentralIdLookup::class )
+                       ->disableOriginalConstructor()
+                       ->setMethods( [ 'centralIdsFromNames', 'namesFromCentralIds' ] )
+                       ->getMockForAbstractClass();
+
+               $idLookup->method( 'centralIdsFromNames' )
+                       ->will( self::returnCallback( function ( $names ) use ( $userMapping ) {
+                               $ids = [];
+                               foreach ( $names as $name ) {
+                                       $ids[] = $userMapping[$name] ?? null;
+                               }
+                               return array_filter( $ids, 'is_numeric' );
+                       } ) );
+               $idLookup->method( 'namesFromCentralIds' )
+                       ->will( self::returnCallback( function ( $ids ) use ( $flipped ) {
+                               $names = [];
+                               foreach ( $ids as $id ) {
+                                       $names[] = $flipped[$id] ?? null;
+                               }
+                               return array_filter( $names, 'is_string' );
+                       } ) );
+
+               return new MultiUsernameFilter( $idLookup );
+       }
+}
index 355f4ef..46c697f 100644 (file)
@@ -52,6 +52,10 @@ class ExtensionJsonValidatorTest extends MediaWikiTestCase {
                                'notjson.txt',
                                'notjson.txt is not valid JSON'
                        ],
+                       [
+                               'duplicate_keys.json',
+                               'Duplicate key: name'
+                       ],
                        [
                                'no_manifest_version.json',
                                'no_manifest_version.json does not have manifest_version set.'
index 67bc088..7120a91 100644 (file)
@@ -51,6 +51,37 @@ class ExtensionRegistryTest extends MediaWikiTestCase {
                $registry->loadFromQueue();
        }
 
+       public function testLoadFromQueue() {
+               $registry = new ExtensionRegistry();
+               $registry->queue( "{$this->dataDir}/good.json" );
+               $registry->loadFromQueue();
+               $this->assertArrayHasKey( 'FooBar', $registry->getAllThings() );
+               $this->assertTrue( $registry->isLoaded( 'FooBar' ) );
+               $this->assertSame( [ 'test' ], $registry->getAttribute( 'FooBarAttr' ) );
+               $this->assertSame( [], $registry->getAttribute( 'NotLoadedAttr' ) );
+       }
+
+       /**
+        * @expectedException PHPUnit_Framework_Error
+        */
+       public function testReadFromQueue_nonexistent() {
+               $registry = new ExtensionRegistry();
+               $registry->readFromQueue( [
+                       __DIR__ . '/doesnotexist.json' => 1
+               ] );
+       }
+
+       public function testReadFromQueueInitializeAutoloaderWithPsr4Namespaces() {
+               $registry = new ExtensionRegistry();
+               $registry->readFromQueue( [
+                       "{$this->dataDir}/autoload_namespaces.json" => 1
+               ] );
+               $this->assertTrue(
+                       class_exists( 'Test\\MediaWiki\\AutoLoader\\TestFooBar' ),
+                       "Registry initializes Autoloader from AutoloadNamespaces"
+               );
+       }
+
        /**
         * @dataProvider provideExportExtractedDataGlobals
         */
index 35d4ea0..b668a9a 100644 (file)
@@ -17,8 +17,7 @@ class VersionCheckerTest extends PHPUnit\Framework\TestCase {
                        'FakeExtension' => [
                                'MediaWiki' => $constraint,
                        ],
-               ] )
-               );
+               ] ) );
        }
 
        public static function provideCheck() {
@@ -50,8 +49,7 @@ class VersionCheckerTest extends PHPUnit\Framework\TestCase {
         */
        public function testType( $given, $expected ) {
                $checker = new VersionChecker( '1.0.0' );
-               $checker
-                       ->setLoadedExtensionsAndSkins( [
+               $checker->setLoadedExtensionsAndSkins( [
                                'FakeDependency' => [
                                        'version' => '1.0.0',
                                ],
@@ -59,8 +57,7 @@ class VersionCheckerTest extends PHPUnit\Framework\TestCase {
                        ] );
                $this->assertEquals( $expected, $checker->checkArray( [
                        'FakeExtension' => $given,
-               ] )
-               );
+               ] ) );
        }
 
        public static function provideType() {
@@ -69,22 +66,22 @@ class VersionCheckerTest extends PHPUnit\Framework\TestCase {
                        [
                                [
                                        'extensions' => [
-                                               'FakeDependency' => '1.0.0'
-                                       ]
+                                               'FakeDependency' => '1.0.0',
+                                       ],
                                ],
-                               []
+                               [],
                        ],
                        [
                                [
-                                       'MediaWiki' => '1.0.0'
+                                       'MediaWiki' => '1.0.0',
                                ],
-                               []
+                               [],
                        ],
                        [
                                [
                                        'extensions' => [
-                                               'NoVersionGiven' => '*'
-                                       ]
+                                               'NoVersionGiven' => '*',
+                                       ],
                                ],
                                [],
                        ],
@@ -92,39 +89,59 @@ class VersionCheckerTest extends PHPUnit\Framework\TestCase {
                                [
                                        'extensions' => [
                                                'NoVersionGiven' => '1.0',
-                                       ]
+                                       ],
+                               ],
+                               [
+                                       [
+                                               'incompatible' => 'FakeExtension',
+                                               'type' => 'incompatible-extensions',
+                                               'msg' => 'NoVersionGiven does not expose its version, but FakeExtension requires: 1.0.',
+                                       ],
                                ],
-                               [ [
-                                       'incompatible' => 'FakeExtension',
-                                       'type' => 'incompatible-extensions',
-                                       'msg' => 'NoVersionGiven does not expose its version, but FakeExtension requires: 1.0.'
-                               ] ],
                        ],
                        [
                                [
                                        'extensions' => [
                                                'Missing' => '*',
-                                       ]
+                                       ],
+                               ],
+                               [
+                                       [
+                                               'missing' => 'Missing',
+                                               'type' => 'missing-extensions',
+                                               'msg' => 'FakeExtension requires Missing to be installed.',
+                                       ],
                                ],
-                               [ [
-                                       'missing' => 'Missing',
-                                       'type' => 'missing-extensions',
-                                       'msg' => 'FakeExtension requires Missing to be installed.',
-                               ] ],
                        ],
                        [
                                [
                                        'extensions' => [
                                                'FakeDependency' => '2.0.0',
-                                       ]
-                               ],
-                               [ [
-                                       'incompatible' => 'FakeExtension',
-                                       'type' => 'incompatible-extensions',
-                                       // phpcs:ignore Generic.Files.LineLength.TooLong
-                                       'msg' => 'FakeExtension is not compatible with the current installed version of FakeDependency (1.0.0), it requires: 2.0.0.'
-                               ] ],
-                       ]
+                                       ],
+                               ],
+                               [
+                                       [
+                                               'incompatible' => 'FakeExtension',
+                                               'type' => 'incompatible-extensions',
+                                               // phpcs:ignore Generic.Files.LineLength.TooLong
+                                               'msg' => 'FakeExtension is not compatible with the current installed version of FakeDependency (1.0.0), it requires: 2.0.0.',
+                                       ],
+                               ],
+                       ],
+                       [
+                               [
+                                       'skins' => [
+                                               'FakeSkin' => '*',
+                                       ],
+                               ],
+                               [
+                                       [
+                                               'missing' => 'FakeSkin',
+                                               'type' => 'missing-skins',
+                                               'msg' => 'FakeExtension requires FakeSkin to be installed.',
+                                       ],
+                               ],
+                       ],
                ];
        }
 
@@ -134,29 +151,26 @@ class VersionCheckerTest extends PHPUnit\Framework\TestCase {
         */
        public function testInvalidConstraint() {
                $checker = new VersionChecker( '1.0.0' );
-               $checker
-                       ->setLoadedExtensionsAndSkins( [
+               $checker->setLoadedExtensionsAndSkins( [
                                'FakeDependency' => [
                                        'version' => 'not really valid',
                                ],
                        ] );
-               $this->assertEquals(
-                       [ [
+               $this->assertEquals( [
+                       [
                                'type' => 'invalid-version',
-                               'msg' => "FakeDependency does not have a valid version string."
-                       ] ],
-                       $checker->checkArray( [
-                               'FakeExtension' => [
-                                       'extensions' => [
-                                               'FakeDependency' => '1.24.3',
-                                       ],
+                               'msg' => "FakeDependency does not have a valid version string.",
+                       ],
+               ], $checker->checkArray( [
+                       'FakeExtension' => [
+                               'extensions' => [
+                                       'FakeDependency' => '1.24.3',
                                ],
-                       ] )
-               );
+                       ],
+               ] ) );
 
                $checker = new VersionChecker( '1.0.0' );
-               $checker
-                       ->setLoadedExtensionsAndSkins( [
+               $checker->setLoadedExtensionsAndSkins( [
                                'FakeDependency' => [
                                        'version' => '1.24.3',
                                ],
@@ -166,7 +180,28 @@ class VersionCheckerTest extends PHPUnit\Framework\TestCase {
                $checker->checkArray( [
                        'FakeExtension' => [
                                'FakeDependency' => 'not really valid',
-                       ]
+                       ],
                ] );
        }
+
+       /**
+        * T197478
+        */
+       public function testInvalidDependency() {
+               $checker = new VersionChecker( '1.0.0' );
+               $this->setExpectedException( UnexpectedValueException::class,
+                       'Dependency type skin unknown in FakeExtension' );
+               $this->assertEquals( [
+                       [
+                               'type' => 'invalid-version',
+                               'msg' => 'FakeDependency does not have a valid version string.',
+                       ],
+               ], $checker->checkArray( [
+                       'FakeExtension' => [
+                               'skin' => [
+                                       'FakeSkin' => '*',
+                               ],
+                       ],
+               ] ) );
+       }
 }
index 4d98773..58e6d7d 100644 (file)
@@ -26,8 +26,12 @@ class MessageBlobStoreTest extends PHPUnit\Framework\TestCase {
                $this->wanCache->expects( $this->any() )
                        ->method( 'makePurgeValue' )
                        ->will( $this->returnCallback( function ( $timestamp, $holdoff ) {
-                               // Disable holdoff as it messes with testing
-                               return WANObjectCache::PURGE_VAL_PREFIX . (float)$timestamp . ':0';
+                               // 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';
                        } ) );
        }
 
@@ -103,11 +107,6 @@ class MessageBlobStoreTest extends PHPUnit\Framework\TestCase {
                $this->assertEquals( '{"foo":"Example"}', $blob, 'Generated blob' );
        }
 
-       /**
-        * Seems to fail sometimes (T176097).
-        *
-        * @group Broken
-        */
        public function testGetBlobCached() {
                $module = $this->makeModule( [ 'example' ] );
                $rl = new ResourceLoader();
@@ -202,12 +201,16 @@ class MessageBlobStoreTest extends PHPUnit\Framework\TestCase {
                        ->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' );
 
                $blob = $blobStore->getBlob( $module, 'en' );
                $this->assertEquals( '{"example":"First"}', $blob, 'Cache-hit' );
 
+               $now += 1;
                $blobStore->clear();
 
                $blob = $blobStore->getBlob( $module, 'en' );
index 9b03c5c..7cd6983 100644 (file)
@@ -176,7 +176,7 @@ class ResourceLoaderClientHtmlTest extends PHPUnit\Framework\TestCase {
                                        'test.user',
                                ],
                        ],
-                       'styledeprecations' => [
+                       'styleDeprecations' => [
                                Xml::encodeJsCall(
                                        'mw.log.warn',
                                        [ 'This page is using the deprecated ResourceLoader module "test.styles.deprecated".
@@ -228,7 +228,6 @@ Deprecation message.' ]
                        . 'mw.loader.implement("test.private@{blankVer}",function($,jQuery,require,module){},{"css":[]});'
                        . 'mw.loader.load(["test"]);'
                        . 'mw.loader.load("/w/load.php?debug=false\u0026lang=nl\u0026modules=test.scripts\u0026only=scripts\u0026skin=fallback");'
-                       . 'mw.log.warn("This page is using the deprecated ResourceLoader module \"test.styles.deprecated\".\nDeprecation message.");'
                        . '});</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"
                        . '<style>.private{}</style>' . "\n"
@@ -304,18 +303,23 @@ Deprecation message.' ]
                $context = self::makeContext();
                $context->getResourceLoader()->register( self::makeSampleModules() );
 
-               $client = new ResourceLoaderClientHtml( $context );
+               $client = new ResourceLoaderClientHtml( $context, [ 'nonce' => false ] );
                $client->setConfig( [ 'key' => 'value' ] );
                $client->setModules( [
                        'test',
                        'test.private.bottom',
                ] );
+               $client->setModuleStyles( [
+                       'test.styles.deprecated',
+               ] );
                $client->setModuleScripts( [
                        'test.scripts',
                ] );
-
-               $expected = '';
-               $expected = self::expandVariables( $expected );
+               // phpcs:disable Generic.Files.LineLength
+               $expected = '<script>(window.RLQ=window.RLQ||[]).push(function(){'
+                       . 'mw.log.warn("This page is using the deprecated ResourceLoader module \"test.styles.deprecated\".\nDeprecation message.");'
+                       . '});</script>';
+               // phpcs:enable
 
                $this->assertEquals( $expected, $client->getBodyHtml() );
        }
index e82bab7..71966b7 100644 (file)
@@ -140,6 +140,8 @@ class ResourceLoaderFileModuleTest extends ResourceLoaderTestCase {
 
        /**
         * @covers ResourceLoaderFileModule::getScript
+        * @covers ResourceLoaderFileModule::getScriptFiles
+        * @covers ResourceLoaderFileModule::readScriptFiles
         */
        public function testGetScript() {
                $module = new ResourceLoaderFileModule( [
@@ -220,6 +222,8 @@ class ResourceLoaderFileModuleTest extends ResourceLoaderTestCase {
         *
         * @covers ResourceLoaderFileModule::getStyles
         * @covers ResourceLoaderFileModule::getStyleFiles
+        * @covers ResourceLoaderFileModule::readStyleFiles
+        * @covers ResourceLoaderFileModule::readStyleFile
         */
        public function testMixedCssAnnotations() {
                $basePath = __DIR__ . '/../../data/css';
@@ -334,6 +338,7 @@ class ResourceLoaderFileModuleTest extends ResourceLoaderTestCase {
 
        /**
         * @covers ResourceLoaderFileModule::getDefinitionSummary
+        * @covers ResourceLoaderFileModule::getFileHashes
         */
        public function testGetVersionHash() {
                $context = $this->getResourceLoaderContext();
index c917882..c925339 100644 (file)
@@ -4,8 +4,6 @@ class ResourceLoaderModuleTest extends ResourceLoaderTestCase {
 
        /**
         * @covers ResourceLoaderModule::getVersionHash
-        * @covers ResourceLoaderModule::getModifiedTime
-        * @covers ResourceLoaderModule::getModifiedHash
         */
        public function testGetVersionHash() {
                $context = $this->getResourceLoaderContext();
@@ -66,6 +64,19 @@ class ResourceLoaderModuleTest extends ResourceLoaderTestCase {
                );
        }
 
+       /**
+        * @covers ResourceLoaderModule::getVersionHash
+        */
+       public function testGetVersionHash_parentDefinition() {
+               $context = $this->getResourceLoaderContext();
+               $module = $this->getMockBuilder( ResourceLoaderModule::class )
+                       ->setMethods( [ 'getDefinitionSummary' ] )->getMock();
+               $module->method( 'getDefinitionSummary' )->willReturn( [ 'a' => 'summary' ] );
+
+               $this->setExpectedException( LogicException::class, 'must call parent' );
+               $module->getVersionHash( $context );
+       }
+
        /**
         * @covers ResourceLoaderModule::validateScriptFile
         */
index ca4fb34..86956f2 100644 (file)
@@ -463,7 +463,7 @@ mw.loader.register( [
                        $this->setMwGlobals( 'wgResourceLoaderSources', $case['sources'] );
                }
 
-               $extraQuery = isset( $case['extraQuery'] ) ? $case['extraQuery'] : [];
+               $extraQuery = $case['extraQuery'] ?? [];
                $context = $this->getResourceLoaderContext( $extraQuery );
                $rl = $context->getResourceLoader();
                $rl->register( $case['modules'] );
@@ -561,4 +561,77 @@ mw.loader.register( [
                );
        }
 
+       /**
+        * @covers ResourceLoaderStartupModule::getDefinitionSummary
+        */
+       public function testGetVersionHash_varyConfig() {
+               $context = $this->getResourceLoaderContext();
+
+               $this->setMwGlobals( 'wgArticlePath', '/w1' );
+               $module = new ResourceLoaderStartupModule();
+               $version1 = $module->getVersionHash( $context );
+               $module = new ResourceLoaderStartupModule();
+               $version2 = $module->getVersionHash( $context );
+               $this->setMwGlobals( 'wgArticlePath', '/w3' );
+               $module = new ResourceLoaderStartupModule();
+               $version3 = $module->getVersionHash( $context );
+
+               $this->assertEquals(
+                       $version1,
+                       $version2,
+                       'Deterministic version hash'
+               );
+
+               $this->assertNotEquals(
+                       $version1,
+                       $version3,
+                       'Config change impacts version hash'
+               );
+       }
+
+       /**
+        * @covers ResourceLoaderStartupModule::getAllModuleHashes
+        * @covers ResourceLoaderStartupModule::getDefinitionSummary
+        */
+       public function testGetVersionHash_varyModule() {
+               $context1 = $this->getResourceLoaderContext();
+               $rl1 = $context1->getResourceLoader();
+               $rl1->register( [
+                       'test.a' => new ResourceLoaderTestModule(),
+                       'test.b' => new ResourceLoaderTestModule(),
+               ] );
+               $module = new ResourceLoaderStartupModule();
+               $version1 = $module->getVersionHash( $context1 );
+
+               $context2 = $this->getResourceLoaderContext();
+               $rl2 = $context2->getResourceLoader();
+               $rl2->register( [
+                       'test.b' => new ResourceLoaderTestModule(),
+                       'test.c' => new ResourceLoaderTestModule(),
+               ] );
+               $module = new ResourceLoaderStartupModule();
+               $version2 = $module->getVersionHash( $context2 );
+
+               $context3 = $this->getResourceLoaderContext();
+               $rl3 = $context3->getResourceLoader();
+               $rl3->register( [
+                       'test.a' => new ResourceLoaderTestModule(),
+                       'test.b' => new ResourceLoaderTestModule( [ 'script' => 'different' ] ),
+               ] );
+               $module = new ResourceLoaderStartupModule();
+               $version3 = $module->getVersionHash( $context3 );
+
+               $this->assertEquals(
+                       $version1,
+                       $version2,
+                       'Module name is insignificant'
+               );
+
+               $this->assertNotEquals(
+                       $version1,
+                       $version3,
+                       'Hash change of any module impacts startup hash'
+               );
+       }
+
 }
index 95006aa..c15eb2c 100644 (file)
@@ -8,7 +8,6 @@ class ResourceLoaderTest extends ResourceLoaderTestCase {
                parent::setUp();
 
                $this->setMwGlobals( [
-                       'wgResourceLoaderLESSImportPaths' => [],
                        'wgResourceLoaderLESSVars' => [
                                'foo'  => '2px',
                                'Foo' => '#eeeeee',
@@ -267,7 +266,7 @@ class ResourceLoaderTest extends ResourceLoaderTestCase {
         */
        public function testLessImportDirs() {
                $rl = new EmptyResourceLoader();
-               $lc = $rl->getLessCompiler();
+               $lc = $rl->getLessCompiler( $rl->getLessVars() );
                $basePath = dirname( dirname( __DIR__ ) ) . '/data/less';
                $lc->SetImportDirs( [
                         "$basePath/common" => '',
@@ -596,11 +595,11 @@ mw.example();
                }
        }
 
-       protected function getFailFerryMock() {
+       protected function getFailFerryMock( $getter = 'getScript' ) {
                $mock = $this->getMockBuilder( ResourceLoaderTestModule::class )
-                       ->setMethods( [ 'getScript' ] )
+                       ->setMethods( [ $getter ] )
                        ->getMock();
-               $mock->method( 'getScript' )->will( $this->throwException(
+               $mock->method( $getter )->will( $this->throwException(
                        new Exception( 'Ferry not found' )
                ) );
                return $mock;
@@ -614,6 +613,14 @@ mw.example();
                return $mock;
        }
 
+       protected function getSimpleStyleModuleMock( $styles = '' ) {
+               $mock = $this->getMockBuilder( ResourceLoaderTestModule::class )
+                       ->setMethods( [ 'getStyles' ] )
+                       ->getMock();
+               $mock->method( 'getStyles' )->willReturn( [ '' => $styles ] );
+               return $mock;
+       }
+
        /**
         * @covers ResourceLoader::getCombinedVersion
         */
@@ -729,6 +736,21 @@ mw.example();
                $this->assertEquals( $expected, $response, $message ?: 'Response' );
        }
 
+       /**
+        * @covers ResourceLoader::makeModuleResponse
+        */
+       public function testMakeModuleResponseEmpty() {
+               $rl = new EmptyResourceLoader();
+               $context = $this->getResourceLoaderContext(
+                       [ 'modules' => '', 'only' => 'scripts' ],
+                       $rl
+               );
+
+               $response = $rl->makeModuleResponse( $context, [] );
+               $this->assertSame( [], $rl->getErrors(), 'Errors' );
+               $this->assertRegExp( '/^\/\*.+no modules were requested.+\*\/$/ms', $response );
+       }
+
        /**
         * Verify that when building module content in a load.php response,
         * an exception from one module will not break script output from
@@ -770,6 +792,43 @@ mw.example();
                );
        }
 
+       /**
+        * Verify that exceptions in PHP for one module will not break others
+        * (stylesheet response).
+        *
+        * @covers ResourceLoader::makeModuleResponse
+        */
+       public function testMakeModuleResponseErrorCSS() {
+               $modules = [
+                       'foo' => self::getSimpleStyleModuleMock( '.foo{}' ),
+                       'ferry' => self::getFailFerryMock( 'getStyles' ),
+                       'bar' => self::getSimpleStyleModuleMock( '.bar{}' ),
+               ];
+               $rl = new EmptyResourceLoader();
+               $rl->register( $modules );
+               $context = $this->getResourceLoaderContext(
+                       [
+                               'modules' => 'foo|ferry|bar',
+                               'only' => 'styles',
+                               'debug' => 'false',
+                       ],
+                       $rl
+               );
+
+               // Disable log from makeModuleResponse via outputErrorAndLog
+               $this->setLogger( 'exception', new Psr\Log\NullLogger() );
+
+               $response = $rl->makeModuleResponse( $context, $modules );
+               $errors = $rl->getErrors();
+
+               $this->assertCount( 2, $errors );
+               $this->assertRegExp( '/Ferry not found/', $errors[0] );
+               $this->assertRegExp( '/Problem.+"ferry":\s*"error"/ms', $errors[1] );
+               $this->assertEquals(
+                       '.foo{}.bar{}',
+                       $response
+               );
+       }
        /**
         * Verify that when building the startup module response,
         * an exception from one module class will not break the entire
@@ -903,7 +962,7 @@ mw.example();
        /**
         * @covers ResourceLoader::respond
         */
-       public function testRespond() {
+       public function testRespondEmpty() {
                $rl = $this->getMockBuilder( EmptyResourceLoader::class )
                        ->setMethods( [
                                'tryRespondNotModified',
@@ -919,6 +978,66 @@ mw.example();
                $rl->respond( $context );
        }
 
+       /**
+        * @covers ResourceLoader::respond
+        */
+       public function testRespondSimple() {
+               $module = new ResourceLoaderTestModule( [ 'script' => 'foo();' ] );
+               $rl = $this->getMockBuilder( EmptyResourceLoader::class )
+                       ->setMethods( [
+                               'measureResponseTime',
+                               'tryRespondNotModified',
+                               'sendResponseHeaders',
+                               'makeModuleResponse',
+                       ] )
+                       ->getMock();
+               $rl->register( 'test', $module );
+               $context = $this->getResourceLoaderContext(
+                       [ 'modules' => 'test', 'only' => null ],
+                       $rl
+               );
+
+               $rl->expects( $this->once() )->method( 'makeModuleResponse' )
+                       ->with( $context, [ 'test' => $module ] )
+                       ->willReturn( 'implement_foo;' );
+               $this->expectOutputRegex( '/^implement_foo;/' );
+
+               $rl->respond( $context );
+       }
+
+       /**
+        * @covers ResourceLoader::respond
+        */
+       public function testRespondInternalFailures() {
+               $module = new ResourceLoaderTestModule( [ 'script' => 'foo();' ] );
+               $rl = $this->getMockBuilder( EmptyResourceLoader::class )
+                       ->setMethods( [
+                               'measureResponseTime',
+                               'preloadModuleInfo',
+                               'getCombinedVersion',
+                               'tryRespondNotModified',
+                               'makeModuleResponse',
+                               'sendResponseHeaders',
+                       ] )
+                       ->getMock();
+               $rl->register( 'test', $module );
+               $context = $this->getResourceLoaderContext( [ 'modules' => 'test' ], $rl );
+               // Disable logging from outputErrorAndLog
+               $this->setLogger( 'exception', new Psr\Log\NullLogger() );
+
+               $rl->expects( $this->once() )->method( 'preloadModuleInfo' )
+                       ->willThrowException( new Exception( 'Preload error' ) );
+               $rl->expects( $this->once() )->method( 'getCombinedVersion' )
+                       ->willThrowException( new Exception( 'Version error' ) );
+               $rl->expects( $this->once() )->method( 'makeModuleResponse' )
+                       ->with( $context, [ 'test' => $module ] )
+                       ->willReturn( 'foo;' );
+               // Internal errors should be caught and logged without affecting module output
+               $this->expectOutputRegex( '/^\/\*.+Preload error.+Version error.+\*\/.*foo;/ms' );
+
+               $rl->respond( $context );
+       }
+
        /**
         * @covers ResourceLoader::measureResponseTime
         */
index 3f59295..83df61a 100644 (file)
@@ -45,6 +45,9 @@ class SearchEnginePrefixTest extends MediaWikiLangTestCase {
                $this->insertPage( 'Talk:Example' );
 
                $this->insertPage( 'User:Example' );
+               $this->insertPage( 'Barcelona' );
+               $this->insertPage( 'Barbara' );
+               $this->insertPage( 'External' );
        }
 
        protected function setUp() {
@@ -238,7 +241,7 @@ class SearchEnginePrefixTest extends MediaWikiLangTestCase {
                                ],
                        ] ],
                        [ [
-                               'Exact match not on top (T72958)',
+                               'Exact match not in first result should be moved to the first result (T72958)',
                                'provision' => [
                                        'Barcelona',
                                        'Bar',
@@ -252,7 +255,7 @@ class SearchEnginePrefixTest extends MediaWikiLangTestCase {
                                ],
                        ] ],
                        [ [
-                               'Exact match missing (T72958)',
+                               'Exact match missing from results should be added as first result (T72958)',
                                'provision' => [
                                        'Barcelona',
                                        'Barbara',
@@ -266,7 +269,7 @@ class SearchEnginePrefixTest extends MediaWikiLangTestCase {
                                ],
                        ] ],
                        [ [
-                               'Exact match missing and not existing',
+                               'Exact match missing and not existing pages should be dropped',
                                'provision' => [
                                        'Exile',
                                        'Exist',
@@ -274,8 +277,6 @@ class SearchEnginePrefixTest extends MediaWikiLangTestCase {
                                ],
                                'query' => 'Ex',
                                'results' => [
-                                       'Exile',
-                                       'Exist',
                                        'External',
                                ],
                        ] ],
@@ -329,6 +330,21 @@ class SearchEnginePrefixTest extends MediaWikiLangTestCase {
                                        'Redirect test',
                                ],
                        ] ],
+                       [ [
+                               "Extra results must not be returned",
+                               'provision' => [
+                                       'Example',
+                                       'Example Bar',
+                                       'Example Foo',
+                                       'Example Foo/Bar'
+                               ],
+                               'query' => 'foo',
+                               'results' => [
+                                       'Example',
+                                       'Example Bar',
+                                       'Example Foo',
+                               ],
+                       ] ],
                ];
        }
 
@@ -337,16 +353,7 @@ class SearchEnginePrefixTest extends MediaWikiLangTestCase {
         * @covers PrefixSearch::searchBackend
         */
        public function testSearchBackend( array $case ) {
-               $search = $stub = $this->getMockBuilder( SearchEngine::class )
-                       ->setMethods( [ 'completionSearchBackend' ] )->getMock();
-
-               $return = SearchSuggestionSet::fromStrings( $case['provision'] );
-
-               $search->expects( $this->any() )
-                       ->method( 'completionSearchBackend' )
-                       ->will( $this->returnValue( $return ) );
-
-               $search->setLimitOffset( 3 );
+               $search = $this->mockSearchWithResults( $case['provision'] );
                $results = $search->completionSearch( $case['query'] );
 
                $results = $results->map( function ( SearchSuggestion $s ) {
@@ -359,4 +366,43 @@ class SearchEnginePrefixTest extends MediaWikiLangTestCase {
                        $case[0]
                );
        }
+
+       public function paginationProvider() {
+               $res = [ 'Example', 'Example Bar', 'Example Foo', 'Example Foo/Bar' ];
+               return [
+                       'With less than requested results no pagination' => [
+                               false, array_slice( $res, 0, 2 ),
+                       ],
+                       'With same as requested results no pagination' => [
+                               false, array_slice( $res, 0, 3 ),
+                       ],
+                       'With extra result returned offer pagination' => [
+                               true, $res,
+                       ],
+               ];
+       }
+
+       /**
+        * @dataProvider paginationProvider
+        */
+       public function testPagination( $hasMoreResults, $provision ) {
+               $search = $this->mockSearchWithResults( $provision );
+               $results = $search->completionSearch( 'irrelevant' );
+
+               $this->assertEquals( $hasMoreResults, $results->hasMoreResults() );
+       }
+
+       private function mockSearchWithResults( $titleStrings, $limit = 3 ) {
+               $search = $stub = $this->getMockBuilder( SearchEngine::class )
+                       ->setMethods( [ 'completionSearchBackend' ] )->getMock();
+
+               $return = SearchSuggestionSet::fromStrings( $titleStrings );
+
+               $search->expects( $this->any() )
+                       ->method( 'completionSearchBackend' )
+                       ->will( $this->returnValue( $return ) );
+
+               $search->setLimitOffset( $limit );
+               return $search;
+       }
 }
index e807776..2b27571 100644 (file)
@@ -84,10 +84,8 @@ class SearchEngineTest extends MediaWikiLangTestCase {
                $this->assertTrue( is_object( $results ) );
 
                $matches = [];
-               $row = $results->next();
-               while ( $row ) {
+               foreach ( $results as $row ) {
                        $matches[] = $row->getTitle()->getPrefixedText();
-                       $row = $results->next();
                }
                $results->free();
                # Search is not guaranteed to return results in a certain order;
@@ -173,7 +171,7 @@ class SearchEngineTest extends MediaWikiLangTestCase {
        public function testPhraseSearchHighlight() {
                $phrase = "smithee is one who smiths";
                $res = $this->search->searchText( "\"$phrase\"" );
-               $match = $res->next();
+               $match = $res->getIterator()->current();
                $snippet = "A <span class='searchmatch'>" . $phrase . "</span>";
                $this->assertStringStartsWith( $snippet,
                        $match->getTextSnippet( $res->termMatches() ),
@@ -277,7 +275,7 @@ class SearchEngineTest extends MediaWikiLangTestCase {
                $this->mergeMwGlobalArrayValue( 'wgHooks',
                        [ 'SearchResultsAugment' => [ [ $this, 'addAugmentors' ] ] ] );
                $this->search->augmentSearchResults( $resultSet );
-               for ( $result = $resultSet->next(); $result; $result = $resultSet->next() ) {
+               foreach ( $resultSet as $result ) {
                        $id = $result->getTitle()->getArticleID();
                        $augmentData = "Result:$id:" . $result->getTitle()->getText();
                        $augmentData2 = "Result2:$id:" . $result->getTitle()->getText();
@@ -292,11 +290,10 @@ class SearchEngineTest extends MediaWikiLangTestCase {
                        ->method( 'augmentAll' )
                        ->willReturnCallback( function ( SearchResultSet $resultSet ) {
                                $data = [];
-                               for ( $result = $resultSet->next(); $result; $result = $resultSet->next() ) {
+                               foreach ( $resultSet as $result ) {
                                        $id = $result->getTitle()->getArticleID();
                                        $data[$id] = "Result:$id:" . $result->getTitle()->getText();
                                }
-                               $resultSet->rewind();
                                return $data;
                        } );
                $setAugmentors['testSet'] = $setAugmentor;
@@ -310,4 +307,153 @@ class SearchEngineTest extends MediaWikiLangTestCase {
                        } );
                $rowAugmentors['testRow'] = $rowAugmentor;
        }
+
+       public function testFiltersMissing() {
+               $availableResults = [];
+               foreach ( range( 0, 11 ) as $i ) {
+                       $title = "Search_Result_$i";
+                       $availableResults[] = $title;
+                       // pages not created must be filtered
+                       if ( $i % 2 == 0 ) {
+                               $this->editSearchResultPage( $title );
+                       }
+               }
+               MockCompletionSearchEngine::addMockResults( 'foo', $availableResults );
+
+               $engine = new MockCompletionSearchEngine();
+               $engine->setLimitOffset( 10, 0 );
+               $results = $engine->completionSearch( 'foo' );
+               $this->assertEquals( 5, $results->getSize() );
+               $this->assertTrue( $results->hasMoreResults() );
+
+               $engine->setLimitOffset( 10, 10 );
+               $results = $engine->completionSearch( 'foo' );
+               $this->assertEquals( 1, $results->getSize() );
+               $this->assertFalse( $results->hasMoreResults() );
+       }
+
+       private function editSearchResultPage( $title ) {
+               $page = WikiPage::factory( Title::newFromText( $title ) );
+               $page->doEditContent(
+                       new WikitextContent( 'UTContent' ),
+                       'UTPageSummary',
+                       EDIT_NEW | EDIT_SUPPRESS_RC
+               );
+       }
+
+       public function provideDataForParseNamespacePrefix() {
+               return [
+                       'noop' => [
+                               [
+                                       'query' => 'foo',
+                               ],
+                               false
+                       ],
+                       'empty' => [
+                               [
+                                       'query' => '',
+                               ],
+                               false,
+                       ],
+                       'namespace prefix' => [
+                               [
+                                       'query' => 'help:test',
+                               ],
+                               [ 'test', [ NS_HELP ] ],
+                       ],
+                       'accented namespace prefix with hook' => [
+                               [
+                                       'query' => 'hélp:test',
+                                       'withHook' => true,
+                               ],
+                               [ 'test', [ NS_HELP ] ],
+                       ],
+                       'accented namespace prefix without hook' => [
+                               [
+                                       'query' => 'hélp:test',
+                                       'withHook' => false,
+                               ],
+                               false,
+                       ],
+                       'all with all keyword allowed' => [
+                               [
+                                       'query' => 'all:test',
+                                       'withAll' => true,
+                               ],
+                               [ 'test', null ],
+                       ],
+                       'all with all keyword disallowed' => [
+                               [
+                                       'query' => 'all:test',
+                                       'withAll' => false,
+                               ],
+                               false
+                       ],
+                       'ns only' => [
+                               [
+                                       'query' => 'help:',
+                               ],
+                               [ '', [ NS_HELP ] ]
+                       ],
+                       'all only' => [
+                               [
+                                       'query' => 'all:',
+                                       'withAll' => true,
+                               ],
+                               [ '', null ]
+                       ],
+                       'all wins over namespace when first' => [
+                               [
+                                       'query' => 'all:help:test',
+                                       'withAll' => true,
+                               ],
+                               [ 'help:test', null ]
+                       ],
+                       'ns wins over all when first' => [
+                               [
+                                       'query' => 'help:all:test',
+                                       'withAll' => true,
+                               ],
+                               [ 'all:test', [ NS_HELP ] ]
+                       ],
+               ];
+       }
+
+       /**
+        * @dataProvider provideDataForParseNamespacePrefix
+        * @param array $params
+        * @param  array|false $expected
+        * @throws FatalError
+        * @throws MWException
+        */
+       public function testParseNamespacePrefix( array $params, $expected ) {
+               $this->setTemporaryHook( 'PrefixSearchExtractNamespace', function ( &$namespaces, &$query ) {
+                       if ( strpos( $query, 'hélp:' ) === 0 ) {
+                               $namespaces = [ NS_HELP ];
+                               $query = substr( $query, strlen( 'hélp:' ) );
+                       }
+                       return false;
+               } );
+               $testSet = [];
+               if ( isset( $params['withAll'] ) && isset( $params['withHook'] ) ) {
+                       $testSet[] = $params;
+               } elseif ( isset( $params['withAll'] ) ) {
+                       $testSet[] = $params + [ 'withHook' => true ];
+                       $testSet[] = $params + [ 'withHook' => false ];
+               } elseif ( isset( $params['withHook'] ) ) {
+                       $testSet[] = $params + [ 'withAll' => true ];
+                       $testSet[] = $params + [ 'withAll' => false ];
+               } else {
+                       $testSet[] = $params + [ 'withAll' => true, 'withHook' => true ];
+                       $testSet[] = $params + [ 'withAll' => true, 'withHook' => false ];
+                       $testSet[] = $params + [ 'withAll' => false, 'withHook' => false ];
+                       $testSet[] = $params + [ 'withAll' => true, 'withHook' => false ];
+               }
+
+               foreach ( $testSet as $test ) {
+                       $actual = SearchEngine::parseNamespacePrefixes( $test['query'],
+                               $test['withAll'], $test['withHook'] );
+                       $this->assertEquals( $expected, $actual, 'with params: ' . print_r( $test, true ) );
+               }
+       }
 }
diff --git a/tests/phpunit/includes/search/SearchNearMatchResultSetTest.php b/tests/phpunit/includes/search/SearchNearMatchResultSetTest.php
new file mode 100644 (file)
index 0000000..67493c4
--- /dev/null
@@ -0,0 +1,15 @@
+<?php
+
+class SearchNearMatchResultSetTest extends PHPUnit\Framework\TestCase {
+       /**
+        * @covers SearchNearMatchResultSet::__construct
+        * @covers SearchNearMatchResultSet::numRows
+        */
+       public function testNumRows() {
+               $resultSet = new SearchNearMatchResultSet( null );
+               $this->assertEquals( 0, $resultSet->numRows() );
+
+               $resultSet = new SearchNearMatchResultSet( Title::newMainPage() );
+               $this->assertEquals( 1, $resultSet->numRows() );
+       }
+}
diff --git a/tests/phpunit/includes/search/SearchResultSetTest.php b/tests/phpunit/includes/search/SearchResultSetTest.php
new file mode 100644 (file)
index 0000000..26a0672
--- /dev/null
@@ -0,0 +1,61 @@
+<?php
+
+class SearchResultSetTest extends MediaWikiTestCase {
+       /**
+        * @covers SearchResultSet::getIterator
+        * @covers SearchResultSet::next
+        * @covers SearchResultSet::rewind
+        */
+       public function testIterate() {
+               $result = SearchResult::newFromTitle( Title::newMainPage() );
+               $resultSet = new MockSearchResultSet( [ $result ] );
+               $this->assertEquals( 1, $resultSet->numRows() );
+               $count = 0;
+               foreach ( $resultSet as $iterResult ) {
+                       $this->assertEquals( $result, $iterResult );
+                       $count++;
+               }
+               $this->assertEquals( 1, $count );
+
+               $this->hideDeprecated( 'SearchResultSet::rewind' );
+               $this->hideDeprecated( 'SearchResultSet::next' );
+               $resultSet->rewind();
+               $count = 0;
+               while ( false !== ( $iterResult = $resultSet->next() ) ) {
+                       $this->assertEquals( $result, $iterResult );
+                       $count++;
+               }
+               $this->assertEquals( 1, $count );
+       }
+
+       /**
+        * @covers SearchResultSet::augmentResult
+        * @covers SearchResultSet::setAugmentedData
+        */
+       public function testDelayedResultAugment() {
+               $result = SearchResult::newFromTitle( Title::newMainPage() );
+               $resultSet = new MockSearchResultSet( [ $result ] );
+               $resultSet->augmentResult( $result );
+               $this->assertEquals( [], $result->getExtensionData() );
+               $resultSet->setAugmentedData( 'foo', [
+                       $result->getTitle()->getArticleID() => 'bar'
+               ] );
+               $this->assertEquals( [ 'foo' => 'bar' ], $result->getExtensionData() );
+       }
+
+       /**
+        * @covers SearchResultSet::shrink
+        * @covers SearchResultSet::count
+        * @covers SearchResultSet::hasMoreResults
+        */
+       public function testHasMoreResults() {
+               $result = SearchResult::newFromTitle( Title::newMainPage() );
+               $resultSet = new MockSearchResultSet( array_fill( 0, 3, $result ) );
+               $this->assertEquals( 3, count( $resultSet ) );
+               $this->assertFalse( $resultSet->hasMoreResults() );
+               $resultSet->shrink( 3 );
+               $this->assertFalse( $resultSet->hasMoreResults() );
+               $resultSet->shrink( 2 );
+               $this->assertTrue( $resultSet->hasMoreResults() );
+       }
+}
diff --git a/tests/phpunit/includes/search/SearchResultTest.php b/tests/phpunit/includes/search/SearchResultTest.php
new file mode 100644 (file)
index 0000000..0e1e24c
--- /dev/null
@@ -0,0 +1,38 @@
+<?php
+
+class SearchResultTest extends MediawikiTestCase {
+       /**
+        * @covers SearchResult::getExtensionData
+        * @covers SearchResult::setExtensionData
+        */
+       public function testExtensionData() {
+               $result = SearchResult::newFromTitle( Title::newMainPage() );
+               $this->assertEquals( [], $result->getExtensionData(), 'starts empty' );
+
+               $data = [ 'hello' => 'world' ];
+               $result->setExtensionData( function () use ( &$data ) {
+                       return $data;
+               } );
+               $this->assertEquals( $data, $result->getExtensionData(), 'can set extension data' );
+               $data['this'] = 'that';
+               $this->assertEquals( $data, $result->getExtensionData(), 'refetches from callback' );
+       }
+
+       /**
+        * @covers SearchResult::getExtensionData
+        * @covers SearchResult::setExtensionData
+        */
+       public function testExtensionDataArrayBC() {
+               $result = SearchResult::newFromTitle( Title::newMainPage() );
+               $data = [ 'hello' => 'world' ];
+               $this->hideDeprecated( 'SearchResult::setExtensionData with array argument' );
+               $this->assertEquals( [], $result->getExtensionData(), 'starts empty' );
+               $result->setExtensionData( $data );
+               $this->assertEquals( $data, $result->getExtensionData(), 'can set extension data' );
+               $data['this'] = 'that';
+               $this->assertNotEquals( $data, $result->getExtensionData(), 'shouldnt hold any reference' );
+
+               $result->setExtensionData( $data );
+               $this->assertEquals( $data, $result->getExtensionData(), 'can replace extension data' );
+       }
+}
index a760908..aca88aa 100644 (file)
@@ -186,9 +186,26 @@ class ServiceContainerTest extends PHPUnit\Framework\TestCase {
 
                $services->applyWiring( $wiring );
 
+               $services->addServiceManipulator( 'Foo', function ( $service ) {
+                       return $service . '+X';
+               } );
+
+               $services->addServiceManipulator( 'Car', function ( $service ) {
+                       return $service . '+X';
+               } );
+
                $newServices = $this->newServiceContainer();
 
-               // define a service before importing, so we can later check that
+               // create a service with manipulator
+               $newServices->defineService( 'Foo', function () {
+                       return 'Foo!';
+               } );
+
+               $newServices->addServiceManipulator( 'Foo', function ( $service ) {
+                       return $service . '+Y';
+               } );
+
+               // create a service before importing, so we can later check that
                // existing service instances survive importWiring()
                $newServices->defineService( 'Car', function () {
                        return 'Car!';
@@ -207,7 +224,7 @@ class ServiceContainerTest extends PHPUnit\Framework\TestCase {
                $newServices->importWiring( $services, [ 'Bar' ] );
 
                $this->assertNotContains( 'Bar', $newServices->getServiceNames(), 'Skip `Bar` service' );
-               $this->assertSame( 'Foo!', $newServices->getService( 'Foo' ) );
+               $this->assertSame( 'Foo!+Y+X', $newServices->getService( 'Foo' ) );
 
                // import all wiring, but preserve existing service instance
                $newServices->importWiring( $services );
@@ -326,6 +343,73 @@ class ServiceContainerTest extends PHPUnit\Framework\TestCase {
                } );
        }
 
+       public function testAddServiceManipulator() {
+               $services = $this->newServiceContainer( [ 'Foo' ] );
+
+               $theService1 = new stdClass();
+               $theService2 = new stdClass();
+               $name = 'TestService92834576';
+
+               $services->defineService(
+                       $name,
+                       function ( $actualLocator, $extra ) use ( $services, $theService1 ) {
+                               PHPUnit_Framework_Assert::assertSame( $services, $actualLocator );
+                               PHPUnit_Framework_Assert::assertSame( 'Foo', $extra );
+                               return $theService1;
+                       }
+               );
+
+               $services->addServiceManipulator(
+                       $name,
+                       function (
+                               $theService, $actualLocator, $extra
+                       ) use (
+                               $services, $theService1, $theService2
+                       ) {
+                               PHPUnit_Framework_Assert::assertSame( $theService1, $theService );
+                               PHPUnit_Framework_Assert::assertSame( $services, $actualLocator );
+                               PHPUnit_Framework_Assert::assertSame( 'Foo', $extra );
+                               return $theService2;
+                       }
+               );
+
+               // force instantiation, check result
+               $this->assertSame( $theService2, $services->getService( $name ) );
+       }
+
+       public function testAddServiceManipulator_fail_undefined() {
+               $services = $this->newServiceContainer();
+
+               $theService = new stdClass();
+               $name = 'TestService92834576';
+
+               $this->setExpectedException( MediaWiki\Services\NoSuchServiceException::class );
+
+               $services->addServiceManipulator( $name, function () use ( $theService ) {
+                       return $theService;
+               } );
+       }
+
+       public function testAddServiceManipulator_fail_in_use() {
+               $services = $this->newServiceContainer( [ 'Foo' ] );
+
+               $theService = new stdClass();
+               $name = 'TestService92834576';
+
+               $services->defineService( $name, function () use ( $theService ) {
+                       return $theService;
+               } );
+
+               // create the service, so it can no longer be redefined
+               $services->getService( $name );
+
+               $this->setExpectedException( MediaWiki\Services\CannotReplaceActiveServiceException::class );
+
+               $services->addServiceManipulator( $name, function () {
+                       return 'Foo';
+               } );
+       }
+
        public function testDisableService() {
                $services = $this->newServiceContainer( [ 'Foo' ] );
 
index c1df365..33bc29f 100644 (file)
@@ -519,7 +519,7 @@ class CookieSessionProviderTest extends MediaWikiTestCase {
 
                $normalExpiry = $config->get( 'CookieExpiration' );
                $extendedExpiry = $config->get( 'ExtendedLoginCookieExpiration' );
-               $extendedExpiry = (int)( $extendedExpiry === null ? 0 : $extendedExpiry );
+               $extendedExpiry = (int)( $extendedExpiry ?? 0 );
                $expect = [
                        'MySessionName' => [
                                'value' => (string)$sessionId,
@@ -540,7 +540,7 @@ class CookieSessionProviderTest extends MediaWikiTestCase {
                        'forceHTTPS' => [
                                'value' => $secure ? 'true' : '',
                                'secure' => false,
-                               'expire' => $secure ? $remember ? $defaults['expire'] : 0 : -31536000,
+                               'expire' => $secure ? ( $remember ? $defaults['expire'] : 0 ) : -31536000,
                        ] + $defaults,
                ];
                foreach ( $expect as $key => $value ) {
index 28fc04a..b001eb9 100644 (file)
@@ -126,7 +126,7 @@ class PHPSessionHandlerTest extends MediaWikiTestCase {
                $wrap = TestingAccessWrapper::newFromObject( $rProp->getValue() );
                $reset[] = new \Wikimedia\ScopedCallback(
                        [ $wrap, 'setEnableFlags' ],
-                       [ $wrap->enable ? $wrap->warn ? 'warn' : 'enable' : 'disable' ]
+                       [ $wrap->enable ? ( $wrap->warn ? 'warn' : 'enable' ) : 'disable' ]
                );
                $wrap->setEnableFlags( 'warn' );
 
index f84d435..a74056d 100644 (file)
@@ -358,7 +358,7 @@ class SessionTest extends MediaWikiTestCase {
                $logger->clearBuffer();
 
                // Unserializable data
-               $iv = \MWCryptRand::generate( 16, true );
+               $iv = random_bytes( 16 );
                list( $encKey, $hmacKey ) = TestingAccessWrapper::newFromObject( $session )->getSecretKeys();
                $ciphertext = openssl_encrypt( 'foobar', 'aes-256-ctr', $encKey, OPENSSL_RAW_DATA, $iv );
                $sealed = base64_encode( $iv ) . '.' . base64_encode( $ciphertext );
index 5db1ad0..ef8fb4e 100644 (file)
@@ -78,9 +78,9 @@ class TestUtils {
        /**
         * If you need a Session for testing but don't want to create a backend to
         * construct one, use this.
-        * @param object $backend Object to serve as the SessionBackend
+        * @param object|null $backend Object to serve as the SessionBackend
         * @param int $index
-        * @param LoggerInterface $logger
+        * @param LoggerInterface|null $logger
         * @return Session
         */
        public static function getDummySession( $backend = null, $index = -1, $logger = null ) {
index 8b8ba0c..d84fcd7 100644 (file)
@@ -101,7 +101,7 @@ abstract class AbstractChangesListSpecialPageTestCase extends MediaWikiTestCase
                $output->method( 'redirect' )->willReturnCallback(
                        function ( $url ) use ( &$redirectQuery, &$redirected ) {
                                $urlParts = wfParseUrl( $url );
-                               $query = isset( $urlParts[ 'query' ] ) ? $urlParts[ 'query' ] : '';
+                               $query = $urlParts[ 'query' ] ?? '';
                                parse_str( $query, $redirectQuery );
                                $redirected = true;
                        }
index 9ac546d..784fed0 100644 (file)
@@ -105,7 +105,7 @@ class SpecialPageFactoryTest extends MediaWikiTestCase {
         * @covers SpecialPageFactory::resolveAlias
         */
        public function testResolveAlias() {
-               $this->setMwGlobals( 'wgContLang', Language::factory( 'de' ) );
+               $this->setContentLang( 'de' );
                SpecialPageFactory::resetList();
 
                list( $name, $param ) = SpecialPageFactory::resolveAlias( 'Spezialseiten/Foo' );
@@ -117,7 +117,7 @@ class SpecialPageFactoryTest extends MediaWikiTestCase {
         * @covers SpecialPageFactory::getLocalNameFor
         */
        public function testGetLocalNameFor() {
-               $this->setMwGlobals( 'wgContLang', Language::factory( 'de' ) );
+               $this->setContentLang( 'de' );
                SpecialPageFactory::resetList();
 
                $name = SpecialPageFactory::getLocalNameFor( 'Specialpages', 'Foo' );
@@ -128,7 +128,7 @@ class SpecialPageFactoryTest extends MediaWikiTestCase {
         * @covers SpecialPageFactory::getTitleForAlias
         */
        public function testGetTitleForAlias() {
-               $this->setMwGlobals( 'wgContLang', Language::factory( 'de' ) );
+               $this->setContentLang( 'de' );
                SpecialPageFactory::resetList();
 
                $title = SpecialPageFactory::getTitleForAlias( 'Specialpages/Foo' );
@@ -145,7 +145,7 @@ class SpecialPageFactoryTest extends MediaWikiTestCase {
                global $wgContLang;
                $lang = clone $wgContLang;
                $lang->mExtendedSpecialPageAliases = $aliasesList;
-               $this->setMwGlobals( 'wgContLang', $lang );
+               $this->setContentLang( $lang );
                $this->setMwGlobals( 'wgSpecialPages',
                        array_combine( array_keys( $aliasesList ), array_keys( $aliasesList ) )
                );
index 2ad3972..2eddb01 100644 (file)
@@ -12,9 +12,9 @@ class SpecialPageTest extends MediaWikiTestCase {
        protected function setUp() {
                parent::setUp();
 
+               $this->setContentLang( 'en' );
                $this->setMwGlobals( [
                        'wgScript' => '/index.php',
-                       'wgContLang' => Language::factory( 'en' )
                ] );
        }
 
index e0d059f..879acfe 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
 /**
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
  * @author Addshore
  *
  * @covers SpecialBlankpage
index e7cfca7..9572e30 100644 (file)
@@ -73,6 +73,9 @@ class SpecialPageExecutor {
 
                $this->setEditTokenFromUser( $context );
 
+               // Make sure the skin context is correctly set https://phabricator.wikimedia.org/T200771
+               $context->getSkin()->setContext( $context );
+
                return $context;
        }
 
index 274a23c..4809e1b 100644 (file)
@@ -5,7 +5,7 @@
  *
  * @since 1.26
  *
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
  * @author Jeroen De Dauw < jeroendedauw@gmail.com >
  * @author Daniel Kinzler
  * @author Addshore
index bdfbb62..cd6cd3b 100644 (file)
@@ -43,6 +43,10 @@ class SpecialPreferencesTest extends MediaWikiTestCase {
                        ]
                        ) );
 
+               # Needs to return something
+               $user->method( 'getOptions' )
+                       ->willReturn( [] );
+
                # Forge a request to call the special page
                $context = new RequestContext();
                $context->setRequest( new FauxRequest() );
index f0a5726..196321c 100644 (file)
@@ -262,8 +262,8 @@ class SpecialSearchTestMockResultSet extends SearchResultSet {
                $this->containedSyntax = $containedSyntax;
        }
 
-       public function numRows() {
-               return count( $this->results );
+       public function expandResults() {
+               return $this->results;
        }
 
        public function getTotalHits() {
index f799b11..236c5c4 100644 (file)
@@ -5,7 +5,7 @@
  *
  * @since 1.30
  *
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
  */
 class SpecialShortpagesTest extends MediaWikiTestCase {
 
index c272551..e1b98ec 100644 (file)
@@ -104,13 +104,6 @@ class MediaWikiTitleCodecTest extends MediaWikiTestCase {
                        // names ending in "a" to be female.
                        [ NS_USER, 'Lisa_Müller', '', '', 'de', 'Benutzerin:Lisa Müller' ],
                        [ NS_MAIN, 'FooBar', '', 'remotetestiw', 'en', 'remotetestiw:FooBar' ],
-                       // Strip soft hyphen and Unicode directional formatting characters
-                       [ NS_MAIN, "Foo\xC2\xAD\xD8\x9C\xE2\x80\x8E\xE2\x80\x8F\xE2\x80\xAA\xE2\x80\xAB" .
-                               "\xE2\x80\xAC\xE2\x80\xAD\xE2\x80\xAE\xE2\x81\xA6\xE2\x81\xA7" .
-                               "\xE2\x81\xA8\xE2\x81\xA9bar", '', '', 'en',
-                               "Foo\xC2\xAD\xD8\x9C\xE2\x80\x8E\xE2\x80\x8F\xE2\x80\xAA\xE2\x80\xAB" .
-                               "\xE2\x80\xAC\xE2\x80\xAD\xE2\x80\xAE\xE2\x81\xA6\xE2\x81\xA7" .
-                               "\xE2\x81\xA8\xE2\x81\xA9bar", 'Foobar' ],
                ];
        }
 
index d711bac..71e52e8 100644 (file)
@@ -29,9 +29,8 @@ class NaiveImportTitleFactoryTest extends MediaWikiTestCase {
        protected function setUp() {
                parent::setUp();
 
+               $this->setContentLang( 'en' );
                $this->setMwGlobals( [
-                       'wgLanguageCode' => 'en',
-                       'wgContLang' => Language::factory( 'en' ),
                        'wgExtraNamespaces' => [ 100 => 'Portal' ],
                ] );
        }
index 9b6ac93..ae87276 100644 (file)
@@ -29,10 +29,7 @@ class NamespaceImportTitleFactoryTest extends MediaWikiTestCase {
        protected function setUp() {
                parent::setUp();
 
-               $this->setMwGlobals( [
-                       'wgLanguageCode' => 'en',
-                       'wgContLang' => Language::factory( 'en' ),
-               ] );
+               $this->setContentLang( 'en' );
        }
 
        public function basicProvider() {
index 008cf5d..7422bdb 100644 (file)
@@ -29,9 +29,8 @@ class SubpageImportTitleFactoryTest extends MediaWikiTestCase {
        protected function setUp() {
                parent::setUp();
 
+               $this->setContentLang( 'en' );
                $this->setMwGlobals( [
-                       'wgLanguageCode' => 'en',
-                       'wgContLang' => Language::factory( 'en' ),
                        'wgNamespacesWithSubpages' => [ 0 => false, 2 => true ],
                ] );
        }
index 3541091..a80262e 100644 (file)
@@ -562,7 +562,7 @@ class UploadBaseTest extends MediaWikiTestCase {
        public function testCheckXMLEncodingMissmatch( $fileContents, $evil ) {
                $filename = $this->getNewTempFile();
                file_put_contents( $filename, $fileContents );
-               $this->assertSame( UploadBase::checkXMLEncodingMissmatch( $filename ), $evil );
+               $this->assertSame( $evil, UploadBase::checkXMLEncodingMissmatch( $filename ) );
        }
 
        public function provideCheckXMLEncodingMissmatch() {
index 1f578ab..4978b72 100644 (file)
@@ -168,6 +168,7 @@ class PasswordResetTest extends MediaWikiTestCase {
                $performingUser = $this->getMockBuilder( User::class )->getMock();
                $performingUser->expects( $this->any() )->method( 'getRequest' )->willReturn( $request );
                $performingUser->expects( $this->any() )->method( 'isAllowed' )->willReturn( true );
+               $performingUser->expects( $this->any() )->method( 'getName' )->willReturn( 'Performer' );
 
                $targetUser1 = $this->getMockBuilder( User::class )->getMock();
                $targetUser2 = $this->getMockBuilder( User::class )->getMock();
index e819d35..169a7c5 100644 (file)
@@ -4,6 +4,7 @@ define( 'NS_UNITTEST', 5600 );
 define( 'NS_UNITTEST_TALK', 5601 );
 
 use MediaWiki\MediaWikiServices;
+use MediaWiki\User\UserIdentityValue;
 use Wikimedia\TestingAccessWrapper;
 
 /**
@@ -234,36 +235,6 @@ class UserTest extends MediaWikiTestCase {
                ];
        }
 
-       /**
-        * Test, if for all rights a right- message exist,
-        * which is used on Special:ListGroupRights as help text
-        * Extensions and core
-        *
-        * @coversNothing
-        */
-       public function testAllRightsWithMessage() {
-               // Getting all user rights, for core: User::$mCoreRights, for extensions: $wgAvailableRights
-               $allRights = User::getAllRights();
-               $allMessageKeys = Language::getMessageKeysFor( 'en' );
-
-               $rightsWithMessage = [];
-               foreach ( $allMessageKeys as $message ) {
-                       // === 0: must be at beginning of string (position 0)
-                       if ( strpos( $message, 'right-' ) === 0 ) {
-                               $rightsWithMessage[] = substr( $message, strlen( 'right-' ) );
-                       }
-               }
-
-               sort( $allRights );
-               sort( $rightsWithMessage );
-
-               $this->assertEquals(
-                       $allRights,
-                       $rightsWithMessage,
-                       'Each user rights (core/extensions) has a corresponding right- message.'
-               );
-       }
-
        /**
         * Test User::editCount
         * @group medium
@@ -1149,6 +1120,40 @@ class UserTest extends MediaWikiTestCase {
                }
        }
 
+       /**
+        * @covers User::newFromIdentity
+        */
+       public function testNewFromIdentity() {
+               // Registered user
+               $user = $this->getTestUser()->getUser();
+
+               $this->assertSame( $user, User::newFromIdentity( $user ) );
+
+               // ID only
+               $identity = new UserIdentityValue( $user->getId(), '', 0 );
+               $result = User::newFromIdentity( $identity );
+               $this->assertInstanceOf( User::class, $result );
+               $this->assertSame( $user->getId(), $result->getId(), 'ID' );
+               $this->assertSame( $user->getName(), $result->getName(), 'Name' );
+               $this->assertSame( $user->getActorId(), $result->getActorId(), 'Actor' );
+
+               // Name only
+               $identity = new UserIdentityValue( 0, $user->getName(), 0 );
+               $result = User::newFromIdentity( $identity );
+               $this->assertInstanceOf( User::class, $result );
+               $this->assertSame( $user->getId(), $result->getId(), 'ID' );
+               $this->assertSame( $user->getName(), $result->getName(), 'Name' );
+               $this->assertSame( $user->getActorId(), $result->getActorId(), 'Actor' );
+
+               // Actor only
+               $identity = new UserIdentityValue( 0, '', $user->getActorId() );
+               $result = User::newFromIdentity( $identity );
+               $this->assertInstanceOf( User::class, $result );
+               $this->assertSame( $user->getId(), $result->getId(), 'ID' );
+               $this->assertSame( $user->getName(), $result->getName(), 'Name' );
+               $this->assertSame( $user->getActorId(), $result->getActorId(), 'Actor' );
+       }
+
        /**
         * @covers User::getBlockedStatus
         * @covers User::getBlock
@@ -1199,4 +1204,113 @@ class UserTest extends MediaWikiTestCase {
                $this->assertFalse( $user->isBlockedFrom( $ut ) );
        }
 
+       /**
+        * Block cookie should be set for IP Blocks if
+        * wgCookieSetOnIpBlock is set to true
+        */
+       public function testIpBlockCookieSet() {
+               $this->setMwGlobals( [
+                       'wgCookieSetOnIpBlock' => true,
+                       'wgCookiePrefix' => 'wiki',
+                       'wgSecretKey' => MWCryptRand::generateHex( 64, true ),
+               ] );
+
+               // setup block
+               $block = new Block( [
+                       'expiry' => wfTimestamp( TS_MW, wfTimestamp() + ( 5 * 60 * 60 ) ),
+               ] );
+               $block->setTarget( '1.2.3.4' );
+               $block->setBlocker( $this->getTestSysop()->getUser() );
+               $block->insert();
+
+               // setup request
+               $request = new FauxRequest();
+               $request->setIP( '1.2.3.4' );
+
+               // get user
+               $user = User::newFromSession( $request );
+               $user->trackBlockWithCookie();
+
+               // test cookie was set
+               $cookies = $request->response()->getCookies();
+               $this->assertArrayHasKey( 'wikiBlockID', $cookies );
+
+               // clean up
+               $block->delete();
+       }
+
+       /**
+        * Block cookie should NOT be set when wgCookieSetOnIpBlock
+        * is disabled
+        */
+       public function testIpBlockCookieNotSet() {
+               $this->setMwGlobals( [
+                       'wgCookieSetOnIpBlock' => false,
+                       'wgCookiePrefix' => 'wiki',
+                       'wgSecretKey' => MWCryptRand::generateHex( 64, true ),
+               ] );
+
+               // setup block
+               $block = new Block( [
+                       'expiry' => wfTimestamp( TS_MW, wfTimestamp() + ( 5 * 60 * 60 ) ),
+               ] );
+               $block->setTarget( '1.2.3.4' );
+               $block->setBlocker( $this->getTestSysop()->getUser() );
+               $block->insert();
+
+               // setup request
+               $request = new FauxRequest();
+               $request->setIP( '1.2.3.4' );
+
+               // get user
+               $user = User::newFromSession( $request );
+               $user->trackBlockWithCookie();
+
+               // test cookie was not set
+               $cookies = $request->response()->getCookies();
+               $this->assertArrayNotHasKey( 'wikiBlockID', $cookies );
+
+               // clean up
+               $block->delete();
+       }
+
+       /**
+        * When an ip user is blocked and then they log in, cookie block
+        * should be invalid and the cookie removed.
+        */
+       public function testIpBlockCookieIgnoredWhenUserLoggedIn() {
+               $this->setMwGlobals( [
+                       'wgAutoblockExpiry' => 8000,
+                       'wgCookieSetOnIpBlock' => true,
+                       'wgCookiePrefix' => 'wiki',
+                       'wgSecretKey' => MWCryptRand::generateHex( 64, true ),
+               ] );
+
+               // setup block
+               $block = new Block( [
+                       'expiry' => wfTimestamp( TS_MW, wfTimestamp() + ( 40 * 60 * 60 ) ),
+               ] );
+               $block->setTarget( '1.2.3.4' );
+               $block->setBlocker( $this->getTestSysop()->getUser() );
+               $block->insert();
+
+               // setup request
+               $request = new FauxRequest();
+               $request->setIP( '1.2.3.4' );
+               $request->getSession()->setUser( $this->getTestUser()->getUser() );
+               $request->setCookie( 'BlockID', $block->getCookieValue() );
+
+               // setup user
+               $user = User::newFromSession( $request );
+
+               // logged in users should be inmune to cookie block of type ip/range
+               $this->assertFalse( $user->isBlocked() );
+
+               // cookie is being cleared
+               $cookies = $request->response()->getCookies();
+               $this->assertEquals( '', $cookies['wikiBlockID']['value'] );
+
+               // clean up
+               $block->delete();
+       }
 }
index 82ab7de..c97bdaf 100644 (file)
@@ -9,9 +9,9 @@ class LanguageConverterTest extends MediaWikiLangTestCase {
        protected function setUp() {
                parent::setUp();
 
+               $this->setContentLang( 'tg' );
+
                $this->setMwGlobals( [
-                       'wgContLang' => Language::factory( 'tg' ),
-                       'wgLanguageCode' => 'tg',
                        'wgDefaultLanguageVariant' => false,
                        'wgRequest' => new FauxRequest( [] ),
                        'wgUser' => new User,
index 050ed83..35bb1f0 100644 (file)
@@ -1029,6 +1029,13 @@ class LanguageTest extends LanguageClassesTestCase {
                                '2555',
                                'Thai year'
                        ],
+                       [
+                               'xkY',
+                               '19410101090705',
+                               '2484',
+                               '2484',
+                               'Thai year'
+                       ],
                        [
                                'xoY',
                                '20120102090705',
@@ -1110,27 +1117,27 @@ class LanguageTest extends LanguageClassesTestCase {
                                "1 gigabyte"
                        ],
                        [
-                               pow( 1024, 4 ),
+                               1024 ** 4,
                                "1 TB",
                                "1 terabyte"
                        ],
                        [
-                               pow( 1024, 5 ),
+                               1024 ** 5,
                                "1 PB",
                                "1 petabyte"
                        ],
                        [
-                               pow( 1024, 6 ),
+                               1024 ** 6,
                                "1 EB",
                                "1,024 exabyte"
                        ],
                        [
-                               pow( 1024, 7 ),
+                               1024 ** 7,
                                "1 ZB",
                                "1 zetabyte"
                        ],
                        [
-                               pow( 1024, 8 ),
+                               1024 ** 8,
                                "1 YB",
                                "1 yottabyte"
                        ],
@@ -1173,37 +1180,37 @@ class LanguageTest extends LanguageClassesTestCase {
                                "1 megabit per second"
                        ],
                        [
-                               pow( 10, 9 ),
+                               10 ** 9,
                                "1 Gbps",
                                "1 gigabit per second"
                        ],
                        [
-                               pow( 10, 12 ),
+                               10 ** 12,
                                "1 Tbps",
                                "1 terabit per second"
                        ],
                        [
-                               pow( 10, 15 ),
+                               10 ** 15,
                                "1 Pbps",
                                "1 petabit per second"
                        ],
                        [
-                               pow( 10, 18 ),
+                               10 ** 18,
                                "1 Ebps",
                                "1 exabit per second"
                        ],
                        [
-                               pow( 10, 21 ),
+                               10 ** 21,
                                "1 Zbps",
                                "1 zetabit per second"
                        ],
                        [
-                               pow( 10, 24 ),
+                               10 ** 24,
                                "1 Ybps",
                                "1 yottabit per second"
                        ],
                        [
-                               pow( 10, 27 ),
+                               10 ** 27,
                                "1,000 Ybps",
                                "1,000 yottabits per second"
                        ],
@@ -1593,9 +1600,9 @@ class LanguageTest extends LanguageClassesTestCase {
         * @covers Language::embedBidi()
         */
        public function testEmbedBidi() {
-               $lre = "\xE2\x80\xAA"; // U+202A LEFT-TO-RIGHT EMBEDDING
-               $rle = "\xE2\x80\xAB"; // U+202B RIGHT-TO-LEFT EMBEDDING
-               $pdf = "\xE2\x80\xAC"; // U+202C POP DIRECTIONAL FORMATTING
+               $lre = "\u{202A}"; // U+202A LEFT-TO-RIGHT EMBEDDING
+               $rle = "\u{202B}"; // U+202B RIGHT-TO-LEFT EMBEDDING
+               $pdf = "\u{202C}"; // U+202C POP DIRECTIONAL FORMATTING
                $lang = $this->getLang();
                $this->assertEquals(
                        '123',
index 0bb6a4d..d406c88 100644 (file)
@@ -7,12 +7,14 @@
  * @group SpecialPageAliases
  * @group SystemTest
  * @group medium
+ * @todo This should be a structure test
  *
  * @author Katie Filbert < aude.wiki@gmail.com >
  */
 class SpecialPageAliasTest extends MediaWikiTestCase {
 
        /**
+        * @coversNothing
         * @dataProvider validSpecialPageAliasesProvider
         */
        public function testValidSpecialPageAliases( $code, $specialPageAliases ) {
index 11c1097..84a4c46 100644 (file)
  */
 class LanguageCrhTest extends LanguageClassesTestCase {
        /**
-        * @dataProvider provideAutoConvertToAllVariants
+        * @dataProvider provideAutoConvertToAllVariantsByWord
         * @covers Language::autoConvertToAllVariants
+        *
+        * Test individual words and test minimal contextual transforms
+        * by creating test strings "<cyrillic> <latin>" and
+        * "<latin> <cyrillic>" and then converting to all variants.
         */
-       public function testAutoConvertToAllVariants( $result, $value ) {
+       public function testAutoConvertToAllVariantsByWord( $cyrl, $lat ) {
+               $value = $lat;
+               $result = [
+                       'crh'      => $value,
+                       'crh-cyrl' => $cyrl,
+                       'crh-latn' => $lat,
+                       ];
+               $this->assertEquals( $result, $this->getLang()->autoConvertToAllVariants( $value ) );
+
+               $value = $cyrl;
+               $result = [
+                       'crh'      => $value,
+                       'crh-cyrl' => $cyrl,
+                       'crh-latn' => $lat,
+                       ];
+               $this->assertEquals( $result, $this->getLang()->autoConvertToAllVariants( $value ) );
+
+               $value = $cyrl . ' ' . $lat;
+               $result = [
+                       'crh'      => $value,
+                       'crh-cyrl' => $cyrl . ' ' . $cyrl,
+                       'crh-latn' => $lat . ' ' . $lat,
+                       ];
+               $this->assertEquals( $result, $this->getLang()->autoConvertToAllVariants( $value ) );
+
+               $value = $lat . ' ' . $cyrl;
+               $result = [
+                       'crh'      => $value,
+                       'crh-cyrl' => $cyrl . ' ' . $cyrl,
+                       'crh-latn' => $lat . ' ' . $lat,
+                       ];
                $this->assertEquals( $result, $this->getLang()->autoConvertToAllVariants( $value ) );
        }
 
-       public static function provideAutoConvertToAllVariants() {
+       public static function provideAutoConvertToAllVariantsByWord() {
+               return [
+                       // general words, covering more of the alphabet
+                       [ 'рузгярнынъ', 'ruzgârnıñ' ], [ 'Париж', 'Parij' ], [ 'чёкюч', 'çöküç' ],
+                       [ 'элифбени', 'elifbeni' ], [ 'полициясы', 'politsiyası' ], [ 'хусусында', 'hususında' ],
+                       [ 'акъшамларны', 'aqşamlarnı' ], [ 'опькеленюв', 'öpkelenüv' ],
+                       [ 'кулюмсиреди', 'külümsiredi' ], [ 'айтмайджагъым', 'aytmaycağım' ],
+                       [ 'козьяшсыз', 'közyaşsız' ],
+
+                       // exception words
+                       [ 'инструменталь', 'instrumental' ], [ 'гургуль', 'gürgül' ], [ 'тюшюнмемек', 'tüşünmemek' ],
+
+                       // specific problem words
+                       [ 'куню', 'künü' ], [ 'сюргюнлиги', 'sürgünligi' ], [ 'озю', 'özü' ], [ 'этти', 'etti' ],
+                       [ 'эсас', 'esas' ], [ 'дёрт', 'dört' ], [ 'кельди', 'keldi' ], [ 'км²', 'km²' ],
+                       [ 'юзь', 'yüz' ], [ 'АКъШ', 'AQŞ' ], [ 'ШСДжБнен', 'ŞSCBnen' ], [ 'июль', 'iyül' ],
+                       [ 'ишгъаль', 'işğal' ], [ 'ишгъальджилерине', 'işğalcilerine' ], [ 'район', 'rayon' ],
+                       [ 'районынынъ', 'rayonınıñ' ], [ 'Ногъай', 'Noğay' ], [ 'Юрьтю', 'Yürtü' ],
+                       [ 'ватандан', 'vatandan' ], [ 'ком-кок', 'köm-kök' ], [ 'АКЪКЪЫ', 'AQQI' ],
+                       [ 'ДАГЪГЪА', 'DAĞĞA' ], [ '13-юнджи', '13-ünci' ], [ 'ДЖУРЬМЕК', 'CÜRMEK' ],
+                       [ 'джумлеси', 'cümlesi' ], [ 'ильи', 'ilyi' ], [ 'Ильи', 'İlyi' ], [ 'бруцел', 'brutsel' ],
+                       [ 'коцюб', 'kotsüb' ], [ 'плацен', 'platsen' ], [ 'эпицентр', 'epitsentr' ],
+
+                       // -tsin- words
+                       [ 'кетсин', 'ketsin' ], [ 'кирлетсин', 'kirletsin' ], [ 'этсин', 'etsin' ],
+                       [ 'етсин', 'yetsin' ], [ 'этсинлерми', 'etsinlermi' ], [ 'принцини', 'printsini' ],
+                       [ 'медицина', 'meditsina' ], [ 'Щетсин', 'Şçetsin' ], [ 'Щекоцины', 'Şçekotsinı' ],
+
+                       // regex pattern words
+                       [ 'коюнден', 'köyünden' ], [ 'аньге', 'ange' ],
+
+                       // multi part words
+                       [ 'эки юз', 'eki yüz' ],
+
+                       // affix patterns
+                       [ 'койнинъ', 'köyniñ' ], [ 'Авджыкойде', 'Avcıköyde' ], [ 'экваториаль', 'ekvatorial' ],
+                       [ 'Джанкой', 'Canköy' ], [ 'усть', 'üst' ], [ 'роль', 'rol' ], [ 'буюк', 'büyük' ],
+                       [ 'джонк', 'cönk' ],
+
+                       // Roman numerals vs Initials, part 1 - Roman numeral initials without spaces
+                       [ 'А.Б.Дж.Д.М. Къадырова XII', 'A.B.C.D.M. Qadırova XII' ],
+                       // Roman numerals vs Initials, part 2 - Roman numeral initials with spaces
+                       [ 'Г. Х. Ы. В. X. Л. Меметов III',  'G. H. I. V. X. L. Memetov III' ],
+
+                       // ALL CAPS, made up acronyms
+                       [ 'НЪАБ', 'ÑAB' ], [ 'КЪЫДЖ', 'QIC' ], [ 'ГЪУК', 'ĞUK' ], [ 'ДЖОТ', 'COT' ], [ 'ДЖА', 'CA' ],
+               ];
+       }
+
+       /**
+        * @dataProvider provideAutoConvertToAllVariantsByString
+        * @covers Language::autoConvertToAllVariants
+        *
+        * Run tests that require some context (like Roman numerals) or with
+        * many-to-one mappings, or other asymmetric results (like smart quotes)
+        */
+       public function testAutoConvertToAllVariantsByString( $result, $value ) {
+               $this->assertEquals( $result, $this->getLang()->autoConvertToAllVariants( $value ) );
+       }
+
+       public static function provideAutoConvertToAllVariantsByString() {
                return [
-                       [ // general words, covering more of the alphabet
-                               [
-                                       'crh'      => 'рузгярнынъ ruzgârnıñ Париж Parij',
-                                       'crh-cyrl' => 'рузгярнынъ рузгярнынъ Париж Париж',
-                                       'crh-latn' => 'ruzgârnıñ ruzgârnıñ Parij Parij',
-                               ],
-                               'рузгярнынъ ruzgârnıñ Париж Parij'
-                       ],
-                       [ // general words, covering more of the alphabet
-                               [
-                                       'crh'      => 'чёкюч çöküç элифбени elifbeni полициясы politsiyası',
-                                       'crh-cyrl' => 'чёкюч чёкюч элифбени элифбени полициясы полициясы',
-                                       'crh-latn' => 'çöküç çöküç elifbeni elifbeni politsiyası politsiyası',
-                               ],
-                               'чёкюч çöküç элифбени elifbeni полициясы politsiyası'
-                       ],
-                       [ // general words, covering more of the alphabet
-                               [
-                                       'crh'      => 'хусусында hususında акъшамларны aqşamlarnı опькеленюв öpkelenüv',
-                                       'crh-cyrl' => 'хусусында хусусында акъшамларны акъшамларны опькеленюв опькеленюв',
-                                       'crh-latn' => 'hususında hususında aqşamlarnı aqşamlarnı öpkelenüv öpkelenüv',
-                               ],
-                               'хусусында hususında акъшамларны aqşamlarnı опькеленюв öpkelenüv'
-                       ],
-                       [ // general words, covering more of the alphabet
-                               [
-                                       'crh'      => 'кулюмсиреди külümsiredi айтмайджагъым aytmaycağım козьяшсыз közyaşsız',
-                                       'crh-cyrl' => 'кулюмсиреди кулюмсиреди айтмайджагъым айтмайджагъым козьяшсыз козьяшсыз',
-                                       'crh-latn' => 'külümsiredi külümsiredi aytmaycağım aytmaycağım közyaşsız közyaşsız',
-                               ],
-                               'кулюмсиреди külümsiredi айтмайджагъым aytmaycağım козьяшсыз közyaşsız'
-                       ],
-                       [ // exception words
-                               [
-                                       'crh'      => 'инструменталь instrumental гургуль gürgül тюшюнмемек tüşünmemek',
-                                       'crh-cyrl' => 'инструменталь инструменталь гургуль гургуль тюшюнмемек тюшюнмемек',
-                                       'crh-latn' => 'instrumental instrumental gürgül gürgül tüşünmemek tüşünmemek',
-                               ],
-                               'инструменталь instrumental гургуль gürgül тюшюнмемек tüşünmemek'
-                       ],
-                       [ // recent problem words, part 1
-                               [
-                                       'crh'      => 'künü куню sürgünligi сюргюнлиги özü озю etti этти esas эсас dört дёрт',
-                                       'crh-cyrl' => 'куню куню сюргюнлиги сюргюнлиги озю озю этти этти эсас эсас дёрт дёрт',
-                                       'crh-latn' => 'künü künü sürgünligi sürgünligi özü özü etti etti esas esas dört dört',
-                               ],
-                               'künü куню sürgünligi сюргюнлиги özü озю etti этти esas эсас dört дёрт'
-                       ],
-                       [ // recent problem words, part 2
-                               [
-                                       'crh'      => 'keldi кельди km² км² yüz юзь AQŞ АКъШ ŞSCBnen ШСДжБнен iyül июль',
-                                       'crh-cyrl' => 'кельди кельди км² км² юзь юзь АКъШ АКъШ ШСДжБнен ШСДжБнен июль июль',
-                                       'crh-latn' => 'keldi keldi km² km² yüz yüz AQŞ AQŞ ŞSCBnen ŞSCBnen iyül iyül',
-                               ],
-                               'keldi кельди km² км² yüz юзь AQŞ АКъШ ŞSCBnen ШСДжБнен iyül июль'
-                       ],
-                       [ // recent problem words, part 3
-                               [
-                                       'crh'      => 'işğal ишгъаль işğalcilerine ишгъальджилерине rayon район üst усть',
-                                       'crh-cyrl' => 'ишгъаль ишгъаль ишгъальджилерине ишгъальджилерине район район усть усть',
-                                       'crh-latn' => 'işğal işğal işğalcilerine işğalcilerine rayon rayon üst üst',
-                               ],
-                               'işğal ишгъаль işğalcilerine ишгъальджилерине rayon район üst усть'
-                       ],
-                       [ // recent problem words, part 4
-                               [
-                                       'crh'      => 'rayonınıñ районынынъ Noğay Ногъай Yürtü Юрьтю vatandan ватандан',
-                                       'crh-cyrl' => 'районынынъ районынынъ Ногъай Ногъай Юрьтю Юрьтю ватандан ватандан',
-                                       'crh-latn' => 'rayonınıñ rayonınıñ Noğay Noğay Yürtü Yürtü vatandan vatandan',
-                               ],
-                               'rayonınıñ районынынъ Noğay Ногъай Yürtü Юрьтю vatandan ватандан'
-                       ],
-                       [ // recent problem words, part 5
-                               [
-                                       'crh'      => 'ком-кок köm-kök rol роль AQQI АКЪКЪЫ DAĞĞA ДАГЪГЪА 13-ünci 13-юнджи',
-                                       'crh-cyrl' => 'ком-кок ком-кок роль роль АКЪКЪЫ АКЪКЪЫ ДАГЪГЪА ДАГЪГЪА 13-юнджи 13-юнджи',
-                                       'crh-latn' => 'köm-kök köm-kök rol rol AQQI AQQI DAĞĞA DAĞĞA 13-ünci 13-ünci',
-                               ],
-                               'ком-кок köm-kök rol роль AQQI АКЪКЪЫ DAĞĞA ДАГЪГЪА 13-ünci 13-юнджи'
-                       ],
-                       [ // recent problem words, part 6
-                               [
-                                       'crh'      => 'ДЖУРЬМЕК CÜRMEK кетсин ketsin джумлеси cümlesi ильи ilyi Ильи İlyi',
-                                       'crh-cyrl' => 'ДЖУРЬМЕК ДЖУРЬМЕК кетсин кетсин джумлеси джумлеси ильи ильи Ильи Ильи',
-                                       'crh-latn' => 'CÜRMEK CÜRMEK ketsin ketsin cümlesi cümlesi ilyi ilyi İlyi İlyi',
-                               ],
-                               'ДЖУРЬМЕК CÜRMEK кетсин ketsin джумлеси cümlesi ильи ilyi Ильи İlyi'
-                       ],
-                       [ // recent problem words, part 7
-                               [
-                                       'crh'      => 'бруцел brutsel коцюб kotsüb плацен platsen эпицентр epitsentr',
-                                       'crh-cyrl' => 'бруцел бруцел коцюб коцюб плацен плацен эпицентр эпицентр',
-                                       'crh-latn' => 'brutsel brutsel kotsüb kotsüb platsen platsen epitsentr epitsentr',
-                               ],
-                               'бруцел brutsel коцюб kotsüb плацен platsen эпицентр epitsentr'
-                       ],
-                       [ // regex pattern words
-                               [
-                                       'crh'      => 'köyünden коюнден ange аньге',
-                                       'crh-cyrl' => 'коюнден коюнден аньге аньге',
-                                       'crh-latn' => 'köyünden köyünden ange ange',
-                               ],
-                               'köyünden коюнден ange аньге'
-                       ],
-                       [ // multi part words
-                               [
-                                       'crh'      => 'эки юз eki yüz',
-                                       'crh-cyrl' => 'эки юз эки юз',
-                                       'crh-latn' => 'eki yüz eki yüz',
-                               ],
-                               'эки юз eki yüz'
-                       ],
-                       [ // affix patterns
-                               [
-                                       'crh'      => 'köyniñ койнинъ Avcıköyde Авджыкойде ekvatorial экваториаль Canköy Джанкой',
-                                       'crh-cyrl' => 'койнинъ койнинъ Авджыкойде Авджыкойде экваториаль экваториаль Джанкой Джанкой',
-                                       'crh-latn' => 'köyniñ köyniñ Avcıköyde Avcıköyde ekvatorial ekvatorial Canköy Canköy',
-                               ],
-                               'köyniñ койнинъ Avcıköyde Авджыкойде ekvatorial экваториаль Canköy Джанкой'
-                       ],
                        [ // Roman numerals and quotes, esp. single-letter Roman numerals at the end of a string
                                [
                                        'crh'      => 'VI,VII IX “dört” «дёрт» XI XII I V X L C D M',
@@ -144,30 +118,6 @@ class LanguageCrhTest extends LanguageClassesTestCase {
                                ],
                                'VI,VII IX “dört” «дёрт» XI XII I V X L C D M'
                        ],
-                       [ // Roman numerals vs Initials, part 1 - Roman numeral initials without spaces
-                               [
-                                       'crh'      => 'A.B.C.D.M. Qadırova XII, А.Б.Дж.Д.М. Къадырова XII',
-                                       'crh-cyrl' => 'А.Б.Дж.Д.М. Къадырова XII, А.Б.Дж.Д.М. Къадырова XII',
-                                       'crh-latn' => 'A.B.C.D.M. Qadırova XII, A.B.C.D.M. Qadırova XII',
-                               ],
-                               'A.B.C.D.M. Qadırova XII, А.Б.Дж.Д.М. Къадырова XII'
-                       ],
-                       [ // Roman numerals vs Initials, part 2 - Roman numeral initials with spaces
-                               [
-                                       'crh'      => 'G. H. I. V. X. L. Memetov III, Г. Х. Ы. В. X. Л. Меметов III',
-                                       'crh-cyrl' => 'Г. Х. Ы. В. X. Л. Меметов III, Г. Х. Ы. В. X. Л. Меметов III',
-                                       'crh-latn' => 'G. H. I. V. X. L. Memetov III, G. H. I. V. X. L. Memetov III',
-                               ],
-                               'G. H. I. V. X. L. Memetov III, Г. Х. Ы. В. X. Л. Меметов III'
-                       ],
-                       [ // ALL CAPS, made up acronyms
-                               [
-                                       'crh'      => 'ÑAB QIC ĞUK COT НЪАБ КЪЫДЖ ГЪУК ДЖОТ CA ДЖА',
-                                       'crh-cyrl' => 'НЪАБ КЪЫДЖ ГЪУК ДЖОТ НЪАБ КЪЫДЖ ГЪУК ДЖОТ ДЖА ДЖА',
-                                       'crh-latn' => 'ÑAB QIC ĞUK COT ÑAB QIC ĞUK COT CA CA',
-                               ],
-                               'ÑAB QIC ĞUK COT НЪАБ КЪЫДЖ ГЪУК ДЖОТ CA ДЖА'
-                       ],
                        [ // Many-to-one mappings: many Cyrillic to one Latin
                                [
                                        'crh'      => 'шофер шофёр şoför корбекул корьбекул корьбекуль körbekül',
index 51a1ed6..000b50f 100644 (file)
@@ -3,7 +3,6 @@
 namespace MediaWiki\Tests\Maintenance;
 
 use DumpBackup;
-use Language;
 use Title;
 use WikiExporter;
 use WikiPage;
@@ -30,10 +29,7 @@ class BackupDumperPageTest extends DumpTestCase {
 
        function addDBData() {
                // be sure, titles created here using english namespace names
-               $this->setMwGlobals( [
-                       'wgLanguageCode' => 'en',
-                       'wgContLang' => Language::factory( 'en' ),
-               ] );
+               $this->setContentLang( 'en' );
 
                $this->tablesUsed[] = 'page';
                $this->tablesUsed[] = 'revision';
index c141817..19e93de 100644 (file)
@@ -27,6 +27,7 @@ class DeleteAutoPatrolLogsTest extends MaintenanceBaseTestCase {
        }
 
        private function insertLoggingData() {
+               $dbw = wfGetDB( DB_MASTER );
                $logs = [];
 
                // Manual patrolling
@@ -35,7 +36,9 @@ class DeleteAutoPatrolLogsTest extends MaintenanceBaseTestCase {
                        'log_action' => 'patrol',
                        'log_user' => 7251,
                        'log_params' => '',
-                       'log_timestamp' => 20041223210426
+                       'log_timestamp' => $dbw->timestamp( '20041223210426' ),
+                       'log_namespace' => NS_MAIN,
+                       'log_title' => 'DeleteAutoPatrolLogs',
                ];
 
                // Autopatrol #1
@@ -44,7 +47,9 @@ class DeleteAutoPatrolLogsTest extends MaintenanceBaseTestCase {
                        'log_action' => 'autopatrol',
                        'log_user' => 7252,
                        'log_params' => '',
-                       'log_timestamp' => 20051223210426
+                       'log_timestamp' => $dbw->timestamp( '20051223210426' ),
+                       'log_namespace' => NS_MAIN,
+                       'log_title' => 'DeleteAutoPatrolLogs',
                ];
 
                // Block
@@ -53,7 +58,9 @@ class DeleteAutoPatrolLogsTest extends MaintenanceBaseTestCase {
                        'log_action' => 'block',
                        'log_user' => 7253,
                        'log_params' => '',
-                       'log_timestamp' => 20061223210426
+                       'log_timestamp' => $dbw->timestamp( '20061223210426' ),
+                       'log_namespace' => NS_MAIN,
+                       'log_title' => 'DeleteAutoPatrolLogs',
                ];
 
                // Very old/ invalid patrol
@@ -62,7 +69,9 @@ class DeleteAutoPatrolLogsTest extends MaintenanceBaseTestCase {
                        'log_action' => 'patrol',
                        'log_user' => 7253,
                        'log_params' => 'nanana',
-                       'log_timestamp' => 20061223210426
+                       'log_timestamp' => $dbw->timestamp( '20061223210426' ),
+                       'log_namespace' => NS_MAIN,
+                       'log_title' => 'DeleteAutoPatrolLogs',
                ];
 
                // Autopatrol #2
@@ -71,7 +80,9 @@ class DeleteAutoPatrolLogsTest extends MaintenanceBaseTestCase {
                        'log_action' => 'autopatrol',
                        'log_user' => 7254,
                        'log_params' => '',
-                       'log_timestamp' => 20071223210426
+                       'log_timestamp' => $dbw->timestamp( '20071223210426' ),
+                       'log_namespace' => NS_MAIN,
+                       'log_title' => 'DeleteAutoPatrolLogs',
                ];
 
                // Autopatrol #3 old way
@@ -80,7 +91,9 @@ class DeleteAutoPatrolLogsTest extends MaintenanceBaseTestCase {
                        'log_action' => 'patrol',
                        'log_user' => 7255,
                        'log_params' => serialize( [ '6::auto' => true ] ),
-                       'log_timestamp' => 20081223210426
+                       'log_timestamp' => $dbw->timestamp( '20081223210426' ),
+                       'log_namespace' => NS_MAIN,
+                       'log_title' => 'DeleteAutoPatrolLogs',
                ];
 
                // Manual patrol #2 old way
@@ -89,10 +102,34 @@ class DeleteAutoPatrolLogsTest extends MaintenanceBaseTestCase {
                        'log_action' => 'patrol',
                        'log_user' => 7256,
                        'log_params' => serialize( [ '6::auto' => false ] ),
-                       'log_timestamp' => 20091223210426
+                       'log_timestamp' => $dbw->timestamp( '20091223210426' ),
+                       'log_namespace' => NS_MAIN,
+                       'log_title' => 'DeleteAutoPatrolLogs',
                ];
 
-               wfGetDB( DB_MASTER )->insert( 'logging', $logs );
+               // Autopatrol #4 very old way
+               $logs[] = [
+                       'log_type' => 'patrol',
+                       'log_action' => 'patrol',
+                       'log_user' => 7257,
+                       'log_params' => "9227851\n0\n1",
+                       'log_timestamp' => $dbw->timestamp( '20081223210426' ),
+                       'log_namespace' => NS_MAIN,
+                       'log_title' => 'DeleteAutoPatrolLogs',
+               ];
+
+               // Manual patrol #3 very old way
+               $logs[] = [
+                       'log_type' => 'patrol',
+                       'log_action' => 'patrol',
+                       'log_user' => 7258,
+                       'log_params' => "9227851\n0\n0",
+                       'log_timestamp' => $dbw->timestamp( '20091223210426' ),
+                       'log_namespace' => NS_MAIN,
+                       'log_title' => 'DeleteAutoPatrolLogs',
+               ];
+
+               $dbw->insert( 'logging', $logs );
        }
 
        public function runProvider() {
@@ -132,6 +169,16 @@ class DeleteAutoPatrolLogsTest extends MaintenanceBaseTestCase {
                                'log_action' => 'patrol',
                                'log_user' => '7256',
                        ],
+                       (object)[
+                               'log_type' => 'patrol',
+                               'log_action' => 'patrol',
+                               'log_user' => '7257',
+                       ],
+                       (object)[
+                               'log_type' => 'patrol',
+                               'log_action' => 'patrol',
+                               'log_user' => '7258',
+                       ],
                ];
 
                $cases = [
@@ -146,6 +193,8 @@ class DeleteAutoPatrolLogsTest extends MaintenanceBaseTestCase {
                                        $allRows[3],
                                        $allRows[5],
                                        $allRows[6],
+                                       $allRows[7],
+                                       $allRows[8],
                                ],
                                [ '--sleep', '0', '-q' ]
                        ],
@@ -157,6 +206,8 @@ class DeleteAutoPatrolLogsTest extends MaintenanceBaseTestCase {
                                        $allRows[4],
                                        $allRows[5],
                                        $allRows[6],
+                                       $allRows[7],
+                                       $allRows[8],
                                ],
                                [ '--sleep', '0', '--before', '20060123210426', '-q' ]
                        ],
@@ -168,6 +219,7 @@ class DeleteAutoPatrolLogsTest extends MaintenanceBaseTestCase {
                                        $allRows[3],
                                        $allRows[4],
                                        $allRows[6],
+                                       $allRows[8],
                                ],
                                [ '--sleep', '0', '--check-old', '-q' ]
                        ],
diff --git a/tests/phpunit/maintenance/populateChangeTagDefTest.php b/tests/phpunit/maintenance/populateChangeTagDefTest.php
new file mode 100644 (file)
index 0000000..719b46b
--- /dev/null
@@ -0,0 +1,286 @@
+<?php
+
+namespace MediaWiki\Tests\Maintenance;
+
+use PopulateChangeTagDef;
+
+/**
+ * @group Database
+ * @covers PopulateChangeTagDef
+ */
+class PopulateChangeTagDefTest extends MaintenanceBaseTestCase {
+
+       public function getMaintenanceClass() {
+               return PopulateChangeTagDef::class;
+       }
+
+       public function setUp() {
+               parent::setUp();
+               $this->tablesUsed = [ 'change_tag', 'change_tag_def' ];
+
+               $this->cleanChangeTagTables();
+               $this->insertChangeTagData();
+       }
+
+       private function cleanChangeTagTables() {
+               wfGetDB( DB_MASTER )->delete( 'change_tag', '*' );
+               wfGetDB( DB_MASTER )->delete( 'change_tag_def', '*' );
+       }
+
+       private function insertChangeTagData() {
+               $changeTags = [];
+
+               $changeTags[] = [
+                       'ct_rc_id' => 1234,
+                       'ct_tag' => 'One Tag',
+               ];
+
+               $changeTags[] = [
+                       'ct_rc_id' => 1235,
+                       'ct_tag' => 'Two Tags',
+               ];
+
+               $changeTags[] = [
+                       'ct_log_id' => 1236,
+                       'ct_tag' => 'Two Tags',
+               ];
+
+               $changeTags[] = [
+                       'ct_rev_id' => 1237,
+                       'ct_tag' => 'Three Tags',
+               ];
+
+               $changeTags[] = [
+                       'ct_rc_id' => 1238,
+                       'ct_tag' => 'Three Tags',
+               ];
+
+               $changeTags[] = [
+                       'ct_log_id' => 1239,
+                       'ct_tag' => 'Three Tags',
+               ];
+
+               wfGetDB( DB_MASTER )->insert( 'change_tag', $changeTags );
+       }
+
+       public function testRun() {
+               $this->setMwGlobals( 'wgChangeTagsSchemaMigrationStage', MIGRATION_WRITE_BOTH );
+               $this->maintenance->loadWithArgv( [ '--sleep', '0' ] );
+
+               $this->maintenance->execute();
+
+               $changeTagDefRows = [
+                       (object)[
+                               'ctd_name' => 'One Tag',
+                               'ctd_count' => 1,
+                       ],
+                       (object)[
+                               'ctd_name' => 'Two Tags',
+                               'ctd_count' => 2,
+                       ],
+                       (object)[
+                               'ctd_name' => 'Three Tags',
+                               'ctd_count' => 3,
+                       ],
+               ];
+
+               $actualChangeTagDefs = wfGetDB( DB_REPLICA )->select(
+                       [ 'change_tag_def' ],
+                       [ 'ctd_name', 'ctd_count' ],
+                       [],
+                       __METHOD__,
+                       [ 'ORDER BY' => 'ctd_count' ]
+               );
+
+               $this->assertEquals( $changeTagDefRows, iterator_to_array( $actualChangeTagDefs, false ) );
+
+               // Check if change_tag is also backpopulated
+               $actualChangeTags = wfGetDB( DB_REPLICA )->select(
+                       [ 'change_tag', 'change_tag_def' ],
+                       [ 'ct_tag', 'ct_tag_id', 'ctd_count' ],
+                       [],
+                       __METHOD__,
+                       [],
+                       [ 'change_tag_def' => [ 'LEFT JOIN', 'ct_tag_id=ctd_id' ] ]
+               );
+               $mapping = [
+                       'One Tag' => 1,
+                       'Two Tags' => 2,
+                       'Three Tags' => 3
+               ];
+               foreach ( $actualChangeTags as $row ) {
+                       $this->assertNotNull( $row->ct_tag_id );
+                       $this->assertEquals( $row->ctd_count, $mapping[$row->ct_tag] );
+               }
+       }
+
+       public function testRunUpdateHitCountMigrationNew() {
+               $this->setMwGlobals( 'wgChangeTagsSchemaMigrationStage', MIGRATION_NEW );
+               $changeTagDefBadRows = [
+                       [
+                               'ctd_name' => 'One Tag',
+                               'ctd_user_defined' => 0,
+                               'ctd_count' => 50,
+                       ],
+                       [
+                               'ctd_name' => 'Two Tags',
+                               'ctd_user_defined' => 0,
+                               'ctd_count' => 4,
+                       ],
+                       [
+                               'ctd_name' => 'Three Tags',
+                               'ctd_user_defined' => 0,
+                               'ctd_count' => 3,
+                       ],
+               ];
+               wfGetDB( DB_MASTER )->insert(
+                       'change_tag_def',
+                       $changeTagDefBadRows
+               );
+
+               $mapping = [
+                       'One Tag' => 1,
+                       'Two Tags' => 2,
+                       'Three Tags' => 3
+               ];
+               foreach ( $mapping as $tagName => $tagId ) {
+                       wfGetDB( DB_MASTER )->update(
+                               'change_tag',
+                               [ 'ct_tag_id' => $tagId ],
+                               [ 'ct_tag' => $tagName ]
+                       );
+               }
+
+               $this->maintenance->loadWithArgv( [ '--sleep', '0' ] );
+
+               $this->maintenance->execute();
+
+               $changeTagDefRows = [
+                       (object)[
+                               'ctd_name' => 'One Tag',
+                               'ctd_count' => 1,
+                       ],
+                       (object)[
+                               'ctd_name' => 'Two Tags',
+                               'ctd_count' => 2,
+                       ],
+                       (object)[
+                               'ctd_name' => 'Three Tags',
+                               'ctd_count' => 3,
+                       ],
+               ];
+
+               $actualChangeTagDefs = wfGetDB( DB_REPLICA )->select(
+                       [ 'change_tag_def' ],
+                       [ 'ctd_name', 'ctd_count' ],
+                       [],
+                       __METHOD__,
+                       [ 'ORDER BY' => 'ctd_count' ]
+               );
+
+               $this->assertEquals( $changeTagDefRows, iterator_to_array( $actualChangeTagDefs, false ) );
+       }
+
+       public function testRunUpdateHitCountMigrationWriteBoth() {
+               $this->setMwGlobals( 'wgChangeTagsSchemaMigrationStage', MIGRATION_WRITE_BOTH );
+               $changeTagDefBadRows = [
+                       [
+                               'ctd_name' => 'One Tag',
+                               'ctd_user_defined' => 0,
+                               'ctd_count' => 50,
+                       ],
+                       [
+                               'ctd_name' => 'Two Tags',
+                               'ctd_user_defined' => 0,
+                               'ctd_count' => 4,
+                       ],
+                       [
+                               'ctd_name' => 'Three Tags',
+                               'ctd_user_defined' => 0,
+                               'ctd_count' => 3,
+                       ],
+               ];
+               wfGetDB( DB_MASTER )->insert(
+                       'change_tag_def',
+                       $changeTagDefBadRows
+               );
+
+               $this->maintenance->loadWithArgv( [ '--sleep', '0' ] );
+
+               $this->maintenance->execute();
+
+               $changeTagDefRows = [
+                       (object)[
+                               'ctd_name' => 'One Tag',
+                               'ctd_count' => 1,
+                       ],
+                       (object)[
+                               'ctd_name' => 'Two Tags',
+                               'ctd_count' => 2,
+                       ],
+                       (object)[
+                               'ctd_name' => 'Three Tags',
+                               'ctd_count' => 3,
+                       ],
+               ];
+
+               $actualChangeTagDefs = wfGetDB( DB_REPLICA )->select(
+                       [ 'change_tag_def' ],
+                       [ 'ctd_name', 'ctd_count' ],
+                       [],
+                       __METHOD__,
+                       [ 'ORDER BY' => 'ctd_count' ]
+               );
+
+               $this->assertEquals( $changeTagDefRows, iterator_to_array( $actualChangeTagDefs, false ) );
+       }
+
+       public function testDryRunMigrationNew() {
+               $this->setMwGlobals( 'wgChangeTagsSchemaMigrationStage', MIGRATION_NEW );
+               $this->maintenance->loadWithArgv( [ '--dry-run', '--sleep', '0' ] );
+
+               $this->maintenance->execute();
+
+               $actualChangeTagDefs = wfGetDB( DB_REPLICA )->select(
+                       [ 'change_tag_def' ],
+                       [ 'ctd_id', 'ctd_name' ]
+               );
+
+               $this->assertEquals( [], iterator_to_array( $actualChangeTagDefs, false ) );
+
+               $actualChangeTags = wfGetDB( DB_REPLICA )->select(
+                       [ 'change_tag' ],
+                       [ 'ct_tag_id', 'ct_tag' ]
+               );
+
+               foreach ( $actualChangeTags as $row ) {
+                       $this->assertNull( $row->ct_tag_id );
+                       $this->assertNotNull( $row->ct_tag );
+               }
+       }
+
+       public function testDryRunMigrationWriteBoth() {
+               $this->setMwGlobals( 'wgChangeTagsSchemaMigrationStage', MIGRATION_WRITE_BOTH );
+               $this->maintenance->loadWithArgv( [ '--dry-run', '--sleep', '0' ] );
+
+               $this->maintenance->execute();
+
+               $actualChangeTagDefs = wfGetDB( DB_REPLICA )->select(
+                       [ 'change_tag_def' ],
+                       [ 'ctd_id', 'ctd_name' ]
+               );
+
+               $this->assertEquals( [], iterator_to_array( $actualChangeTagDefs, false ) );
+
+               $actualChangeTags = wfGetDB( DB_REPLICA )->select(
+                       [ 'change_tag' ],
+                       [ 'ct_tag_id', 'ct_tag' ]
+               );
+
+               foreach ( $actualChangeTags as $row ) {
+                       $this->assertNull( $row->ct_tag_id );
+                       $this->assertNotNull( $row->ct_tag );
+               }
+       }
+
+}
index 143a419..4d35930 100644 (file)
@@ -37,7 +37,7 @@ class MockMessageLocalizer implements MessageLocalizer {
                $args = func_get_args();
 
                /** @var Message $message */
-               $message = call_user_func_array( 'wfMessage', $args );
+               $message = wfMessage( ...$args );
 
                if ( $this->languageCode !== null ) {
                        $message->inLanguage( $this->languageCode );
index e8259d3..6bc7c44 100644 (file)
@@ -94,7 +94,7 @@ class DummyContentForTesting extends AbstractContent {
 
        /**
         * @param Title $title
-        * @param int $revId Unused.
+        * @param int|null $revId Unused.
         * @param null|ParserOptions $options
         * @param bool $generateHtml Whether to generate Html (default: true). If false, the result
         *  of calling getText() on the ParserOutput object returned by this method is undefined.
index b71577c..f203907 100644 (file)
@@ -10,7 +10,7 @@ class DummyContentHandlerForTesting extends ContentHandler {
         * @see ContentHandler::serializeContent
         *
         * @param Content $content
-        * @param string $format
+        * @param string|null $format
         *
         * @return string
         */
@@ -22,7 +22,7 @@ class DummyContentHandlerForTesting extends ContentHandler {
         * @see ContentHandler::unserializeContent
         *
         * @param string $blob
-        * @param string $format Unused.
+        * @param string|null $format Unused.
         *
         * @return Content
         */
index 91bb186..e65f522 100644 (file)
@@ -92,7 +92,7 @@ class DummyNonTextContent extends AbstractContent {
 
        /**
         * @param Title $title
-        * @param int $revId Unused.
+        * @param int|null $revId Unused.
         * @param null|ParserOptions $options
         * @param bool $generateHtml Whether to generate Html (default: true). If false, the result
         *  of calling getText() on the ParserOutput object returned by this method is undefined.
index 9d91d4a..3294953 100644 (file)
@@ -10,7 +10,7 @@ class DummyNonTextContentHandler extends DummyContentHandlerForTesting {
         * @see ContentHandler::serializeContent
         *
         * @param Content $content
-        * @param string $format
+        * @param string|null $format
         *
         * @return string
         */
@@ -22,7 +22,7 @@ class DummyNonTextContentHandler extends DummyContentHandlerForTesting {
         * @see ContentHandler::unserializeContent
         *
         * @param string $blob
-        * @param string $format Unused.
+        * @param string|null $format Unused.
         *
         * @return Content
         */
index 720547a..4a462c0 100644 (file)
@@ -29,7 +29,7 @@ class DummySerializeErrorContentHandler extends DummyContentHandlerForTesting {
         * @see ContentHandler::unserializeContent
         *
         * @param string $blob
-        * @param string $format
+        * @param string|null $format
         *
         * @return Content
         */
diff --git a/tests/phpunit/mocks/search/MockCompletionSearchEngine.php b/tests/phpunit/mocks/search/MockCompletionSearchEngine.php
new file mode 100644 (file)
index 0000000..13d16df
--- /dev/null
@@ -0,0 +1,43 @@
+<?php
+
+/**
+ * SearchEngine implementation for returning mocked completion search results.
+ */
+class MockCompletionSearchEngine extends SearchEngine {
+       /** @var string[][] */
+       private static $results = [];
+
+       /**
+        * Reset any mocked results
+        */
+       public static function clearMockResults() {
+               self::$results = [];
+       }
+
+       /**
+        * Allows returning arbitrary lists of titles for completion search.
+        * Provided results will be sliced based on offset/limit of query.
+        *
+        * For results to exit the search engine they must pass Title::isKnown.
+        * Injecting into link cache is not enough, as LinkBatch will mark them
+        * bad, they need to be injected into the DB.
+        *
+        * @param string $query Search term as seen in completionSearchBackend
+        * @param string[] $result List of titles to respond to query with
+        */
+       public static function addMockResults( $query, array $result ) {
+               // Leading : ensures we don't treat another : as a namespace separator
+               $normalized = mb_strtolower( Title::newFromText( ":$query" )->getText() );
+               self::$results[$normalized] = $result;
+       }
+
+       public function completionSearchBackend( $search ) {
+               $search = mb_strtolower( $search );
+               if ( !isset( self::$results[$search] ) ) {
+                       return SearchSuggestionSet::emptySuggestionSet();
+               }
+               $results = array_slice( self::$results[$search], $this->offset, $this->limit );
+
+               return SearchSuggestionSet::fromStrings( $results );
+       }
+}
diff --git a/tests/phpunit/mocks/search/MockSearchEngine.php b/tests/phpunit/mocks/search/MockSearchEngine.php
new file mode 100644 (file)
index 0000000..2b7ea47
--- /dev/null
@@ -0,0 +1,45 @@
+<?php
+
+use MediaWiki\MediaWikiServices;
+
+class MockSearchEngine extends SearchEngine {
+       /** @var SearchResult[][] */
+       private static $results = [];
+       /** @var SearchResultSet[][] */
+       private static $interwikiResults = [];
+
+       public static function clearMockResults() {
+               self::$results = [];
+               self::$interwikiResults = [];
+       }
+
+       /**
+        * @param string $query The query searched for *after* initial
+        *  transformations have been applied.
+        * @param SearchResult[] $results The results to return for $query
+        */
+       public static function addMockResults( $query, array $results ) {
+               self::$results[$query] = $results;
+               $lc = MediaWikiServices::getInstance()->getLinkCache();
+               foreach ( $results as $result ) {
+                       // TODO: better page ids? Does it matter?
+                       $lc->addGoodLinkObj( mt_rand(), $result->getTitle() );
+               }
+       }
+
+       /**
+        * @param SearchResultSet[][] $interwikiResults
+        */
+       public static function setMockInterwikiResults( array $interwikiResults ) {
+               self::$interwikiResults = $interwikiResults;
+       }
+
+       protected function doSearchText( $term ) {
+               if ( isset( self::$results[ $term ] ) ) {
+                       $results = array_slice( self::$results[ $term ], $this->offset, $this->limit );
+               } else {
+                       $results = [];
+               }
+               return new MockSearchResultSet( $results, self::$interwikiResults );
+       }
+}
diff --git a/tests/phpunit/mocks/search/MockSearchResult.php b/tests/phpunit/mocks/search/MockSearchResult.php
new file mode 100644 (file)
index 0000000..d92d39a
--- /dev/null
@@ -0,0 +1,32 @@
+<?php
+
+class MockSearchResult extends SearchResult {
+       private $isMissingRevision = false;
+       private $isBrokenTitle = false;
+
+       public function isMissingRevision() {
+               return $this->isMissingRevision;
+       }
+       public function setMissingRevision( $isMissingRevision ) {
+               $this->isMissingRevision = $isMissingRevision;
+               return $this;
+       }
+
+       public function isBrokenTitle() {
+               return $this->isBrokenTitle;
+       }
+
+       public function setBrokenTitle( $isBrokenTitle ) {
+               $this->isBrokenTitle = $isBrokenTitle;
+               return $this;
+       }
+
+       public function getInterwikiPrefix() {
+               return $this->interwikiPrefix;
+       }
+
+       public function setInterwikiPrefix( $interwikiPrefix ) {
+               $this->interwikiPrefix = $interwikiPrefix;
+               return $this;
+       }
+}
diff --git a/tests/phpunit/mocks/search/MockSearchResultSet.php b/tests/phpunit/mocks/search/MockSearchResultSet.php
new file mode 100644 (file)
index 0000000..20e2a9f
--- /dev/null
@@ -0,0 +1,37 @@
+<?php
+
+class MockSearchResultSet extends SearchResultSet {
+       /*
+        * @var SearchResultSet[][] Map from result type to list of results for
+        *  that type.
+        */
+       private $interwikiResults;
+
+       /**
+        * @param SearchResult[] $results
+        * @param SearchResultSet[][] $interwikiResults Map from result type
+        *  to list of results for that type.
+        */
+       public function __construct( array $results, array $interwikiResults = [] ) {
+               parent::__construct( false, false );
+               $this->results = $results;
+               $this->interwikiResults = $interwikiResults;
+       }
+
+       public function numRows() {
+               return count( $this->results );
+       }
+
+       public function hasInterwikiResults( $type = self::SECONDARY_RESULTS ) {
+               return isset( $this->interwikiResults[$type] ) &&
+                       count( $this->interwikiResults[$type] ) > 0;
+       }
+
+       public function getInterwikiResults( $type = self::SECONDARY_RESULTS ) {
+               if ( $this->hasInterwikiResults( $type ) ) {
+                       return $this->interwikiResults[$type];
+               } else {
+                       return null;
+               }
+       }
+}
diff --git a/tests/phpunit/structure/AutoLoaderStructureTest.php b/tests/phpunit/structure/AutoLoaderStructureTest.php
new file mode 100644 (file)
index 0000000..2800d02
--- /dev/null
@@ -0,0 +1,193 @@
+<?php
+
+/**
+ * @coversNothing
+ */
+class AutoLoaderStructureTest extends MediaWikiTestCase {
+       /**
+        * Assert that there were no classes loaded that are not registered with the AutoLoader.
+        *
+        * For example foo.php having class Foo and class Bar but only registering Foo.
+        * This is important because we should not be relying on Foo being used before Bar.
+        */
+       public function testAutoLoadConfig() {
+               $results = self::checkAutoLoadConf();
+
+               $this->assertEquals(
+                       $results['expected'],
+                       $results['actual']
+               );
+       }
+
+       public function providePSR4Completeness() {
+               foreach ( AutoLoader::$psr4Namespaces as $prefix => $dir ) {
+                       foreach ( $this->recurseFiles( $dir ) as $file ) {
+                               yield [ $prefix, $dir, $file ];
+                       }
+               }
+       }
+
+       private function recurseFiles( $dir ) {
+               return ( new File_Iterator_Facade() )->getFilesAsArray( $dir, [ '.php' ] );
+       }
+
+       /**
+        * @dataProvider providePSR4Completeness
+        */
+       public function testPSR4Completeness( $prefix, $dir, $file ) {
+               global $wgAutoloadLocalClasses, $wgAutoloadClasses;
+               $contents = file_get_contents( $file );
+               list( $classesInFile, $aliasesInFile ) = self::parseFile( $contents );
+               $classes = array_keys( $classesInFile );
+               if ( $classes ) {
+                       $this->assertCount( 1, $classes,
+                               "Only one class per file in PSR-4 autoloaded classes ($file)" );
+
+                       // Check that the expected class name (based on the filename) is the
+                       // same as the one we found.
+                       // Strip directory prefix from front of filename, and .php extension
+                       $abbrFileName = substr( substr( $file, strlen( $dir ) ), 0, -4 );
+                       $expectedClassName = $prefix . str_replace( '/', '\\', $abbrFileName );
+
+                       $this->assertSame(
+                               $expectedClassName,
+                               $classes[0],
+                               "Class not autoloaded properly"
+                       );
+
+               } else {
+                       // Dummy assertion so this test isn't marked in risky
+                       // if the file has no classes nor aliases in it
+                       $this->assertCount( 0, $classes );
+               }
+
+               if ( $aliasesInFile ) {
+                       $otherClasses = $wgAutoloadLocalClasses + $wgAutoloadClasses;
+                       foreach ( $aliasesInFile as $alias => $class ) {
+                               $this->assertArrayHasKey( $alias, $otherClasses,
+                                       'Alias must be in the classmap autoloader'
+                               );
+                       }
+               }
+       }
+
+       private static function parseFile( $contents ) {
+               // We could use token_get_all() here, but this is faster
+               // Note: Keep in sync with ClassCollector
+               $matches = [];
+               preg_match_all( '/
+                               ^ [\t ]* (?:
+                                       (?:final\s+)? (?:abstract\s+)? (?:class|interface|trait) \s+
+                                       (?P<class> [a-zA-Z0-9_]+)
+                               |
+                                       class_alias \s* \( \s*
+                                               ([\'"]) (?P<original> [^\'"]+) \g{-2} \s* , \s*
+                                               ([\'"]) (?P<alias> [^\'"]+ ) \g{-2} \s*
+                                       \) \s* ;
+                               |
+                                       class_alias \s* \( \s*
+                                               (?P<originalStatic> [a-zA-Z0-9_]+)::class \s* , \s*
+                                               ([\'"]) (?P<aliasString> [^\'"]+ ) \g{-2} \s*
+                                       \) \s* ;
+                               )
+                       /imx', $contents, $matches, PREG_SET_ORDER );
+
+               $namespaceMatch = [];
+               preg_match( '/
+                               ^ [\t ]*
+                                       namespace \s+
+                                               ([a-zA-Z0-9_]+(\\\\[a-zA-Z0-9_]+)*)
+                                       \s* ;
+                       /imx', $contents, $namespaceMatch );
+               $fileNamespace = $namespaceMatch ? $namespaceMatch[1] . '\\' : '';
+
+               $classesInFile = [];
+               $aliasesInFile = [];
+
+               foreach ( $matches as $match ) {
+                       if ( !empty( $match['class'] ) ) {
+                               // 'class Foo {}'
+                               $class = $fileNamespace . $match['class'];
+                               $classesInFile[$class] = true;
+                       } else {
+                               if ( !empty( $match['original'] ) ) {
+                                       // 'class_alias( "Foo", "Bar" );'
+                                       $aliasesInFile[$match['alias']] = $match['original'];
+                               } else {
+                                       // 'class_alias( Foo::class, "Bar" );'
+                                       $aliasesInFile[$match['aliasString']] = $fileNamespace . $match['originalStatic'];
+                               }
+                       }
+               }
+
+               return [ $classesInFile, $aliasesInFile ];
+       }
+
+       protected static function checkAutoLoadConf() {
+               global $wgAutoloadLocalClasses, $wgAutoloadClasses, $IP;
+
+               // wgAutoloadLocalClasses has precedence, just like in includes/AutoLoader.php
+               $expected = $wgAutoloadLocalClasses + $wgAutoloadClasses;
+               $actual = [];
+
+               $files = array_unique( $expected );
+
+               foreach ( $files as $class => $file ) {
+                       // Only prefix $IP if it doesn't have it already.
+                       // Generally local classes don't have it, and those from extensions and test suites do.
+                       if ( substr( $file, 0, 1 ) != '/' && substr( $file, 1, 1 ) != ':' ) {
+                               $filePath = "$IP/$file";
+                       } else {
+                               $filePath = $file;
+                       }
+
+                       if ( !file_exists( $filePath ) ) {
+                               $actual[$class] = "[file '$filePath' does not exist]";
+                               continue;
+                       }
+
+                       Wikimedia\suppressWarnings();
+                       $contents = file_get_contents( $filePath );
+                       Wikimedia\restoreWarnings();
+
+                       if ( $contents === false ) {
+                               $actual[$class] = "[couldn't read file '$filePath']";
+                               continue;
+                       }
+
+                       list( $classesInFile, $aliasesInFile ) = self::parseFile( $contents );
+
+                       foreach ( $classesInFile as $className => $ignore ) {
+                               $actual[$className] = $file;
+                       }
+
+                       // Only accept aliases for classes in the same file, because for correct
+                       // behavior, all aliases for a class must be set up when the class is loaded
+                       // (see <https://bugs.php.net/bug.php?id=61422>).
+                       foreach ( $aliasesInFile as $alias => $class ) {
+                               if ( isset( $classesInFile[$class] ) ) {
+                                       $actual[$alias] = $file;
+                               } else {
+                                       $actual[$alias] = "[original class not in $file]";
+                               }
+                       }
+               }
+
+               return [
+                       'expected' => $expected,
+                       'actual' => $actual,
+               ];
+       }
+
+       public function testAutoloadOrder() {
+               $path = realpath( __DIR__ . '/../../..' );
+               $oldAutoload = file_get_contents( $path . '/autoload.php' );
+               $generator = new AutoloadGenerator( $path, 'local' );
+               $generator->setExcludePaths( array_values( AutoLoader::getAutoloadNamespaces() ) );
+               $generator->initMediaWikiDefault();
+               $newAutoload = $generator->getAutoload( 'maintenance/generateLocalAutoload.php' );
+
+               $this->assertEquals( $oldAutoload, $newAutoload, 'autoload.php does not match' .
+                       ' output of generateLocalAutoload.php script.' );
+       }
+}
diff --git a/tests/phpunit/structure/AutoLoaderTest.php b/tests/phpunit/structure/AutoLoaderTest.php
deleted file mode 100644 (file)
index 217232e..0000000
+++ /dev/null
@@ -1,171 +0,0 @@
-<?php
-
-class AutoLoaderTest extends MediaWikiTestCase {
-       protected function setUp() {
-               parent::setUp();
-
-               // Fancy dance to trigger a rebuild of AutoLoader::$autoloadLocalClassesLower
-               $this->mergeMwGlobalArrayValue( 'wgAutoloadLocalClasses', [
-                       'TestAutoloadedLocalClass' =>
-                               __DIR__ . '/../data/autoloader/TestAutoloadedLocalClass.php',
-                       'TestAutoloadedCamlClass' =>
-                               __DIR__ . '/../data/autoloader/TestAutoloadedCamlClass.php',
-                       'TestAutoloadedSerializedClass' =>
-                               __DIR__ . '/../data/autoloader/TestAutoloadedSerializedClass.php',
-               ] );
-               AutoLoader::resetAutoloadLocalClassesLower();
-
-               $this->mergeMwGlobalArrayValue( 'wgAutoloadClasses', [
-                       'TestAutoloadedClass' => __DIR__ . '/../data/autoloader/TestAutoloadedClass.php',
-               ] );
-       }
-
-       /**
-        * Assert that there were no classes loaded that are not registered with the AutoLoader.
-        *
-        * For example foo.php having class Foo and class Bar but only registering Foo.
-        * This is important because we should not be relying on Foo being used before Bar.
-        */
-       public function testAutoLoadConfig() {
-               $results = self::checkAutoLoadConf();
-
-               $this->assertEquals(
-                       $results['expected'],
-                       $results['actual']
-               );
-       }
-
-       protected static function checkAutoLoadConf() {
-               global $wgAutoloadLocalClasses, $wgAutoloadClasses, $IP;
-
-               // wgAutoloadLocalClasses has precedence, just like in includes/AutoLoader.php
-               $expected = $wgAutoloadLocalClasses + $wgAutoloadClasses;
-               $actual = [];
-
-               $files = array_unique( $expected );
-
-               foreach ( $files as $class => $file ) {
-                       // Only prefix $IP if it doesn't have it already.
-                       // Generally local classes don't have it, and those from extensions and test suites do.
-                       if ( substr( $file, 0, 1 ) != '/' && substr( $file, 1, 1 ) != ':' ) {
-                               $filePath = "$IP/$file";
-                       } else {
-                               $filePath = $file;
-                       }
-
-                       if ( !file_exists( $filePath ) ) {
-                               $actual[$class] = "[file '$filePath' does not exist]";
-                               continue;
-                       }
-
-                       Wikimedia\suppressWarnings();
-                       $contents = file_get_contents( $filePath );
-                       Wikimedia\restoreWarnings();
-
-                       if ( $contents === false ) {
-                               $actual[$class] = "[couldn't read file '$filePath']";
-                               continue;
-                       }
-
-                       // We could use token_get_all() here, but this is faster
-                       // Note: Keep in sync with ClassCollector
-                       $matches = [];
-                       preg_match_all( '/
-                               ^ [\t ]* (?:
-                                       (?:final\s+)? (?:abstract\s+)? (?:class|interface|trait) \s+
-                                       (?P<class> [a-zA-Z0-9_]+)
-                               |
-                                       class_alias \s* \( \s*
-                                               ([\'"]) (?P<original> [^\'"]+) \g{-2} \s* , \s*
-                                               ([\'"]) (?P<alias> [^\'"]+ ) \g{-2} \s*
-                                       \) \s* ;
-                               |
-                                       class_alias \s* \( \s*
-                                               (?P<originalStatic> [a-zA-Z0-9_]+)::class \s* , \s*
-                                               ([\'"]) (?P<aliasString> [^\'"]+ ) \g{-2} \s*
-                                       \) \s* ;
-                               )
-                       /imx', $contents, $matches, PREG_SET_ORDER );
-
-                       $namespaceMatch = [];
-                       preg_match( '/
-                               ^ [\t ]*
-                                       namespace \s+
-                                               ([a-zA-Z0-9_]+(\\\\[a-zA-Z0-9_]+)*)
-                                       \s* ;
-                       /imx', $contents, $namespaceMatch );
-                       $fileNamespace = $namespaceMatch ? $namespaceMatch[1] . '\\' : '';
-
-                       $classesInFile = [];
-                       $aliasesInFile = [];
-
-                       foreach ( $matches as $match ) {
-                               if ( !empty( $match['class'] ) ) {
-                                       // 'class Foo {}'
-                                       $class = $fileNamespace . $match['class'];
-                                       $actual[$class] = $file;
-                                       $classesInFile[$class] = true;
-                               } else {
-                                       if ( !empty( $match['original'] ) ) {
-                                               // 'class_alias( "Foo", "Bar" );'
-                                               $aliasesInFile[$match['alias']] = $match['original'];
-                                       } else {
-                                               // 'class_alias( Foo::class, "Bar" );'
-                                               $aliasesInFile[$match['aliasString']] = $fileNamespace . $match['originalStatic'];
-                                       }
-                               }
-                       }
-
-                       // Only accept aliases for classes in the same file, because for correct
-                       // behavior, all aliases for a class must be set up when the class is loaded
-                       // (see <https://bugs.php.net/bug.php?id=61422>).
-                       foreach ( $aliasesInFile as $alias => $class ) {
-                               if ( isset( $classesInFile[$class] ) ) {
-                                       $actual[$alias] = $file;
-                               } else {
-                                       $actual[$alias] = "[original class not in $file]";
-                               }
-                       }
-               }
-
-               return [
-                       'expected' => $expected,
-                       'actual' => $actual,
-               ];
-       }
-
-       function testCoreClass() {
-               $this->assertTrue( class_exists( 'TestAutoloadedLocalClass' ) );
-       }
-
-       function testExtensionClass() {
-               $this->assertTrue( class_exists( 'TestAutoloadedClass' ) );
-       }
-
-       function testWrongCaseClass() {
-               $this->setMwGlobals( 'wgAutoloadAttemptLowercase', true );
-
-               $this->assertTrue( class_exists( 'testautoLoadedcamlCLASS' ) );
-       }
-
-       function testWrongCaseSerializedClass() {
-               $this->setMwGlobals( 'wgAutoloadAttemptLowercase', true );
-
-               $dummyCereal = 'O:29:"testautoloadedserializedclass":0:{}';
-               $uncerealized = unserialize( $dummyCereal );
-               $this->assertFalse( $uncerealized instanceof __PHP_Incomplete_Class,
-                       "unserialize() can load classes case-insensitively." );
-       }
-
-       function testAutoloadOrder() {
-               $path = realpath( __DIR__ . '/../../..' );
-               $oldAutoload = file_get_contents( $path . '/autoload.php' );
-               $generator = new AutoloadGenerator( $path, 'local' );
-               $generator->setExcludePaths( array_values( AutoLoader::getAutoloadNamespaces() ) );
-               $generator->initMediaWikiDefault();
-               $newAutoload = $generator->getAutoload( 'maintenance/generateLocalAutoload.php' );
-
-               $this->assertEquals( $oldAutoload, $newAutoload, 'autoload.php does not match' .
-                       ' output of generateLocalAutoload.php script.' );
-       }
-}
index 6c2ff02..a7d947e 100644 (file)
@@ -35,6 +35,9 @@ class AvailableRightsTest extends PHPUnit\Framework\TestCase {
                return $rights;
        }
 
+       /**
+        * @coversNothing
+        */
        public function testAvailableRights() {
                $missingRights = array_diff(
                        $this->getAllVisibleRights(),
@@ -50,4 +53,36 @@ class AvailableRightsTest extends PHPUnit\Framework\TestCase {
                        'https://www.mediawiki.org/wiki/Manual:User_rights#Adding_new_rights'
                );
        }
+
+       /**
+        * Test, if for all rights a right- message exist,
+        * which is used on Special:ListGroupRights as help text
+        * Extensions and core
+        *
+        * @coversNothing
+        */
+       public function testAllRightsWithMessage() {
+               // Getting all user rights, for core: User::$mCoreRights, for extensions: $wgAvailableRights
+               $allRights = User::getAllRights();
+               $allMessageKeys = Language::getMessageKeysFor( 'en' );
+
+               $rightsWithMessage = [];
+               foreach ( $allMessageKeys as $message ) {
+                       // === 0: must be at beginning of string (position 0)
+                       if ( strpos( $message, 'right-' ) === 0 ) {
+                               $rightsWithMessage[] = substr( $message, strlen( 'right-' ) );
+                       }
+               }
+
+               $missing = array_diff(
+                       $allRights,
+                       $rightsWithMessage
+               );
+
+               $this->assertEquals(
+                       [],
+                       $missing,
+                       'Each user rights (core/extensions) has a corresponding right- message.'
+               );
+       }
 }
index c8bcd60..c75a9d0 100644 (file)
@@ -32,6 +32,7 @@ class ContentHandlerSanityTest extends MediaWikiTestCase {
        }
 
        /**
+        * @coversNothing
         * @dataProvider provideHandlers
         * @param ContentHandler $handler
         */
index 60c97cc..dea8f5a 100644 (file)
@@ -19,6 +19,8 @@
 /**
  * Validates all loaded extensions and skins using the ExtensionRegistry
  * against the extension.json schema in the docs/ folder.
+ *
+ * @coversNothing
  */
 class ExtensionJsonValidationTest extends PHPUnit\Framework\TestCase {
 
index 62ddace..8a08181 100644 (file)
@@ -11,6 +11,7 @@
  * @copyright © 2012, Niklas Laxström
  * @copyright © 2012, Santhosh Thottingal
  * @copyright © 2012, Timo Tijhof
+ * @coversNothing
  */
 class ResourcesTest extends MediaWikiTestCase {
 
@@ -44,24 +45,23 @@ class ResourcesTest extends MediaWikiTestCase {
        }
 
        /**
-        * Verify that nothing explicitly depends on base modules, or other raw modules.
+        * Verify that nothing explicitly depends on raw modules (such as "query").
         *
         * Depending on them is unsupported as they are not registered client-side by the startup module.
         *
-        * TODO Modules can dynamically choose dependencies based on context. This method does not
+        * @todo Modules can dynamically choose dependencies based on context. This method does not
         * test such dependencies. The same goes for testMissingDependencies() and
         * testUnsatisfiableDependencies().
         */
        public function testIllegalDependencies() {
                $data = self::getAllModules();
 
-               $illegalDeps = ResourceLoaderStartUpModule::getStartupModules();
+               $illegalDeps = [];
                foreach ( $data['modules'] as $moduleName => $module ) {
                        if ( $module->isRaw() ) {
                                $illegalDeps[] = $moduleName;
                        }
                }
-               $illegalDeps = array_unique( $illegalDeps );
 
                /** @var ResourceLoaderModule $module */
                foreach ( $data['modules'] as $moduleName => $module ) {
diff --git a/tests/phpunit/structure/SpecialPageFatalTest.php b/tests/phpunit/structure/SpecialPageFatalTest.php
new file mode 100644 (file)
index 0000000..abf1cdd
--- /dev/null
@@ -0,0 +1,50 @@
+<?php
+
+/**
+ * Test that runs against all registered special pages to make sure that regular
+ * execution of the special page does not cause a fatal error.
+ *
+ * UTSysop is used to run as much of the special page code as possible without
+ * actually knowing the details of the special page.
+ *
+ * @since 1.32
+ * @author Addshore
+ */
+class SpecialPageFatalTest extends MediaWikiTestCase {
+
+       public static function setUpBeforeClass() {
+               parent::setUpBeforeClass();
+               SpecialPageFactory::resetList();
+       }
+
+       public static function tearDownAfterClass() {
+               SpecialPageFactory::resetList();
+               parent::tearDownAfterClass();
+       }
+
+       public function provideSpecialPages() {
+               $specialPages = [];
+               foreach ( SpecialPageFactory::getNames() as $name ) {
+                       $specialPages[$name] = [ SpecialPageFactory::getPage( $name ) ];
+               }
+               return $specialPages;
+       }
+
+       /**
+        * @dataProvider provideSpecialPages
+        */
+       public function testSpecialPageDoesNotFatal( SpecialPage $page ) {
+               $executor = new SpecialPageExecutor();
+               $user = User::newFromName( 'UTSysop' );
+
+               try {
+                       $executor->executeSpecialPage( $page, '', null, null, $user );
+               } catch ( Exception $e ) {
+                       // Exceptions are allowed
+               }
+
+               // If the page fataled phpunit will have already died
+               $this->addToAssertionCount( 1 );
+       }
+
+}
index 4df791e..82302b1 100644 (file)
@@ -9,6 +9,7 @@ class StructureTest extends MediaWikiTestCase {
         * Verify all files that appear to be tests have file names ending in
         * Test.  If the file names do not end in Test, they will not be run.
         * @group medium
+        * @coversNothing
         */
        public function testUnitTestFileNamesEndWithTest() {
                if ( wfIsWindows() ) {
index e8256ef..e125b8a 100644 (file)
@@ -55,6 +55,9 @@
                        <file>suites/ExtensionsParserTestSuite.php</file>
                        <file>suites/LessTestSuite.php</file>
                </testsuite>
+               <testsuite name="documentation">
+                       <directory>documentation</directory>
+               </testsuite>
        </testsuites>
        <groups>
                <exclude>
index 02934fa..7d1d331 100644 (file)
@@ -45,6 +45,9 @@ class ExtensionsTestSuite extends PHPUnit_Framework_TestSuite {
  * when no extensions with tests are used.
  */
 class DummyExtensionsTest extends MediaWikiTestCase {
+       /**
+        * @coversNothing
+        */
        public function testNothing() {
                $this->assertTrue( true );
        }
index 07b18f5..1ea5853 100644 (file)
@@ -17,6 +17,8 @@ class ParserTestTopLevelSuite extends PHPUnit_Framework_TestSuite {
        /** @var ScopedCallback */
        private $ptTeardownScope;
 
+       private $oldTablePrefix = '';
+
        /**
         * @defgroup filtering_constants Filtering constants
         *
@@ -29,7 +31,7 @@ class ParserTestTopLevelSuite extends PHPUnit_Framework_TestSuite {
        /** Include non core files as set in $wgParserTestFiles */
        const NO_CORE = 2;
        /** Include anything set via $wgParserTestFiles */
-       const WITH_ALL = 3; # CORE_ONLY | NO_CORE
+       const WITH_ALL = self::CORE_ONLY | self::NO_CORE;
 
        /** @} */
 
@@ -137,7 +139,9 @@ class ParserTestTopLevelSuite extends PHPUnit_Framework_TestSuite {
                $type = $db->getType();
                $prefix = $type === 'oracle' ?
                        MediaWikiTestCase::ORA_DB_PREFIX : MediaWikiTestCase::DB_PREFIX;
+               $this->oldTablePrefix = $db->tablePrefix();
                MediaWikiTestCase::setupTestDB( $db, $prefix );
+               CloneDatabase::changePrefix( $prefix );
                $teardown = $this->ptRunner->setDatabase( $db );
                $teardown = $this->ptRunner->setupUploads( $teardown );
                $this->ptTeardownScope = $teardown;
@@ -148,6 +152,7 @@ class ParserTestTopLevelSuite extends PHPUnit_Framework_TestSuite {
                if ( $this->ptTeardownScope ) {
                        ScopedCallback::consume( $this->ptTeardownScope );
                }
+               CloneDatabase::changePrefix( $this->oldTablePrefix );
        }
 
        /**
index d794d13..aebd0bf 100644 (file)
@@ -11,6 +11,13 @@ class MediaWikiTestCaseSchema1Test extends MediaWikiTestCase {
 
        public static $hasRun = false;
 
+       public function setUp() {
+               parent::setUp();
+               if ( $this->db->getType() == 'postgres' ) {
+                       $this->markTestSkipped( __CLASS__ . ' does not support postgres' );
+               }
+       }
+
        public function getSchemaOverrides( IMaintainableDatabase $db ) {
                return [
                        'create' => [ 'MediaWikiTestCaseTestTable', 'imagelinks' ],
index 5464dc4..c0673a1 100644 (file)
  */
 class MediaWikiTestCaseSchema2Test extends MediaWikiTestCase {
 
+       public function setUp() {
+               parent::setUp();
+               if ( $this->db->getType() == 'postgres' ) {
+                       $this->markTestSkipped( __CLASS__ . ' does not support postgres' );
+               }
+       }
+
        public function testMediaWikiTestCaseSchemaTestOrder() {
                // The first test must have run before this one
                $this->assertTrue( MediaWikiTestCaseSchema1Test::$hasRun );
index b3a46f4..e6d2511 100644 (file)
@@ -1,5 +1,9 @@
 {
-       "extends": "../../.eslintrc.json",
+       "extends": [
+               "../../.eslintrc.json",
+               "plugin:qunit/recommended",
+               "plugin:qunit/two"
+       ],
        "env": {
                "qunit": true
        },
@@ -9,6 +13,12 @@
        "rules": {
                "operator-linebreak": 0,
                "quote-props": [ "error", "as-needed" ],
-               "valid-jsdoc": 0
-       }
+               "valid-jsdoc": 0,
+               "qunit/no-assert-equal": "error",
+               "qunit/no-early-return": "error",
+               "qunit/no-negated-ok": "error",
+               "qunit/require-expect": 0,
+               "qunit/resolve-async": 0
+       },
+       "plugins": [ "qunit" ]
 }
index 1922de5..3b511c2 100644 (file)
@@ -70,6 +70,7 @@ return [
                        'tests/qunit/suites/resources/mediawiki/mediawiki.template.test.js',
                        'tests/qunit/suites/resources/mediawiki/mediawiki.template.mustache.test.js',
                        'tests/qunit/suites/resources/mediawiki/mediawiki.test.js',
+                       'tests/qunit/suites/resources/mediawiki/mediawiki.base.test.js',
                        'tests/qunit/suites/resources/mediawiki/mediawiki.loader.test.js',
                        'tests/qunit/suites/resources/mediawiki/mediawiki.html.test.js',
                        'tests/qunit/suites/resources/mediawiki/mediawiki.inspect.test.js',
@@ -95,6 +96,8 @@ return [
                        'tests/qunit/suites/resources/mediawiki.rcfilters/dm.SavedQueryItemModel.test.js',
                        'tests/qunit/suites/resources/mediawiki.rcfilters/dm.SavedQueriesModel.test.js',
                        'tests/qunit/suites/resources/mediawiki.rcfilters/UriProcessor.test.js',
+                       'tests/qunit/suites/resources/mediawiki.widgets/' .
+                               'MediaSearch/mediawiki.widgets.APIResultsQueue.test.js',
                        'tests/qunit/suites/resources/mediawiki/mediawiki.language.test.js',
                        'tests/qunit/suites/resources/mediawiki/mediawiki.cldr.test.js',
                        'tests/qunit/suites/resources/mediawiki/mediawiki.cookie.test.js',
@@ -137,6 +140,7 @@ return [
                        'mediawiki.experiments',
                        'mediawiki.inspect',
                        'mediawiki.visibleTimeout',
+                       'mediawiki.widgets.MediaSearch',
                        'test.mediawiki.qunit.testrunner',
                ],
        ]
index e4f87f8..a85e41a 100644 (file)
@@ -22,7 +22,7 @@
                        QUnit.stop();
                        getMwLanguage( test.lang, function ( langClass ) {
                                var parser = new mw.jqueryMsg.Parser( { language: langClass } );
-                               assert.equal(
+                               assert.strictEqual(
                                        parser.parse( test.key, test.args ).html(),
                                        test.result,
                                        test.name
index e37f67d..db96fd5 100644 (file)
@@ -44,9 +44,9 @@ function cssfilter( $val ) {
 $params = array_map( 'cssfilter', $_GET );
 
 // Defaults
-$selector = isset( $params['selector'] ) ? $params['selector'] : '.mw-test-example';
-$property = isset( $params['prop'] ) ? $params['prop'] : 'float';
-$value = isset( $params['val'] ) ? $params['val'] : 'right';
+$selector = $params['selector'] ?? '.mw-test-example';
+$property = $params['prop'] ?? 'float';
+$value = $params['val'] ?? 'right';
 $wait = isset( $params['wait'] ) ? (int)$params['wait'] : 0; // seconds
 
 sleep( $wait );
index 06c146c..d8972ab 100644 (file)
@@ -40,7 +40,7 @@
         * Configuration
         */
 
-       // For each test() that is asynchronous, allow this time to pass before
+       // For each test that is asynchronous, allow this time to pass before
        // killing the test and assuming timeout failure.
        QUnit.config.testTimeout = 60 * 1000;
 
        }() );
 
        /**
-        * Reset mw.config and others to a fresh copy of the live config for each test(),
+        * Reset mw.config and others to a fresh copy of the live config for each test,
         * and restore it back to the live one afterwards.
         *
         * @param {Object} [localEnv]
        } ) );
 
        QUnit.test( 'Setup', function ( assert ) {
-               assert.equal( mw.html.escape( 'foo' ), 'mocked', 'setup() callback was ran.' );
-               assert.equal( mw.config.get( 'testVar' ), 'foo', 'config object applied' );
-               assert.equal( mw.messages.get( 'testMsg' ), 'Foo.', 'messages object applied' );
+               assert.strictEqual( mw.html.escape( 'foo' ), 'mocked', 'setup() callback was ran.' );
+               assert.strictEqual( mw.config.get( 'testVar' ), 'foo', 'config object applied' );
+               assert.strictEqual( mw.messages.get( 'testMsg' ), 'Foo.', 'messages object applied' );
 
                mw.config.set( 'testVar', 'bar' );
                mw.messages.set( 'testMsg', 'Bar.' );
        } );
 
        QUnit.test( 'Teardown', function ( assert ) {
-               assert.equal( mw.config.get( 'testVar' ), 'foo', 'config object restored and re-applied after test()' );
-               assert.equal( mw.messages.get( 'testMsg' ), 'Foo.', 'messages object restored and re-applied after test()' );
+               assert.strictEqual( mw.config.get( 'testVar' ), 'foo', 'config object restored and re-applied after test()' );
+               assert.strictEqual( mw.messages.get( 'testMsg' ), 'Foo.', 'messages object restored and re-applied after test()' );
        } );
 
        QUnit.test( 'Loader status', function ( assert ) {
        QUnit.module( 'testrunner-after', QUnit.newMwEnvironment() );
 
        QUnit.test( 'Teardown', function ( assert ) {
-               assert.equal( mw.html.escape( '<' ), '&lt;', 'teardown() callback was ran.' );
-               assert.equal( mw.config.get( 'testVar' ), null, 'config object restored to live in next module()' );
-               assert.equal( mw.messages.get( 'testMsg' ), null, 'messages object restored to live in next module()' );
+               assert.strictEqual( mw.html.escape( '<' ), '&lt;', 'teardown() callback was ran.' );
+               assert.strictEqual( mw.config.get( 'testVar' ), null, 'config object restored to live in next module()' );
+               assert.strictEqual( mw.messages.get( 'testMsg' ), null, 'messages object restored to live in next module()' );
        } );
 
        QUnit.module( 'testrunner-each', {
                mw.html = null;
        } );
        QUnit.test( 'afterEach', function ( assert ) {
-               assert.equal( mw.html.escape( '<' ), '&lt;', 'afterEach() ran' );
+               assert.strictEqual( mw.html.escape( '<' ), '&lt;', 'afterEach() ran' );
        } );
 
        QUnit.module( 'testrunner-each-compat', {
+               // eslint-disable-next-line qunit/no-setup-teardown
                setup: function () {
                        this.mwHtmlLive = mw.html;
                },
+               // eslint-disable-next-line qunit/no-setup-teardown
                teardown: function () {
                        mw.html = this.mwHtmlLive;
                }
                mw.html = null;
        } );
        QUnit.test( 'teardown', function ( assert ) {
-               assert.equal( mw.html.escape( '<' ), '&lt;', 'teardown() ran' );
+               assert.strictEqual( mw.html.escape( '<' ), '&lt;', 'teardown() ran' );
        } );
 
        // Regression test for 'this.sandbox undefined' error, fixed by
index e4b6157..c064275 100644 (file)
@@ -51,7 +51,7 @@
        QUnit.test( 'getAccessKeyPrefix', function ( assert ) {
                var i;
                for ( i = 0; i < getAccessKeyPrefixTestData.length; i++ ) {
-                       assert.equal( $.fn.updateTooltipAccessKeys.getAccessKeyPrefix( {
+                       assert.strictEqual( $.fn.updateTooltipAccessKeys.getAccessKeyPrefix( {
                                userAgent: getAccessKeyPrefixTestData[ i ][ 0 ],
                                platform: getAccessKeyPrefixTestData[ i ][ 1 ]
                        } ), getAccessKeyPrefixTestData[ i ][ 2 ], 'Correct prefix for ' + getAccessKeyPrefixTestData[ i ][ 0 ] );
@@ -75,7 +75,7 @@
                        $input = $( makeInput( oldTitle ) );
                        $( '#qunit-fixture' ).append( $input );
                        newTitle = $input.updateTooltipAccessKeys().prop( 'title' );
-                       assert.equal( newTitle, 'Title', 'title="' + oldTitle + '"' );
+                       assert.strictEqual( newTitle, 'Title', 'title="' + oldTitle + '"' );
                }
        } );
 
@@ -87,7 +87,7 @@
                        $input = $( makeInput( oldTitle, 'a' ) );
                        $( '#qunit-fixture' ).append( $input );
                        newTitle = $input.updateTooltipAccessKeys().prop( 'title' );
-                       assert.equal( newTitle, 'Title [test-a]', 'title="' + oldTitle + '"' );
+                       assert.strictEqual( newTitle, 'Title [test-a]', 'title="' + oldTitle + '"' );
                }
                $.fn.updateTooltipAccessKeys.setTestMode( false );
        } );
                $label = $( '#qunit-fixture label' );
                $input = $( '#qunit-fixture input' );
                $input.updateTooltipAccessKeys();
-               assert.equal( $input.prop( 'title' ), '', 'No title attribute added to input element.' );
-               assert.equal( $label.prop( 'title' ), 'Title [test-a]', 'title updated for associated label element.' );
+               assert.strictEqual( $input.prop( 'title' ), '', 'No title attribute added to input element.' );
+               assert.strictEqual( $label.prop( 'title' ), 'Title [test-a]', 'title updated for associated label element.' );
                $.fn.updateTooltipAccessKeys.setTestMode( false );
        } );
 
                $label = $( '#qunit-fixture label' );
                $input = $( '#qunit-fixture input' );
                $input.updateTooltipAccessKeys();
-               assert.equal( $input.prop( 'title' ), '', 'No title attribute added to input element.' );
-               assert.equal( $label.prop( 'title' ), 'Title [test-a]', 'title updated for associated label element.' );
+               assert.strictEqual( $input.prop( 'title' ), '', 'No title attribute added to input element.' );
+               assert.strictEqual( $label.prop( 'title' ), 'Title [test-a]', 'title updated for associated label element.' );
                $.fn.updateTooltipAccessKeys.setTestMode( false );
        } );
 
index d6208e9..bd6e7b2 100644 (file)
@@ -55,9 +55,9 @@
        QUnit.test( 'getColorBrightness', function ( assert ) {
                var a, b;
                a = $.colorUtil.getColorBrightness( 'red', +0.1 );
-               assert.equal( a, 'rgb(255,50,50)', 'Start with named color "red", brighten 10%' );
+               assert.strictEqual( a, 'rgb(255,50,50)', 'Start with named color "red", brighten 10%' );
 
                b = $.colorUtil.getColorBrightness( 'rgb(200,50,50)', -0.2 );
-               assert.equal( b, 'rgb(118,29,29)', 'Start with rgb string "rgb(200,50,50)", darken 20%' );
+               assert.strictEqual( b, 'rgb(118,29,29)', 'Start with rgb string "rgb(200,50,50)", darken 20%' );
        } );
 }( jQuery ) );
index 6a265eb..3f17ca5 100644 (file)
@@ -3,36 +3,36 @@
 
        QUnit.test( 'devicePixelRatio', function ( assert ) {
                var devicePixelRatio = $.devicePixelRatio();
-               assert.equal( typeof devicePixelRatio, 'number', '$.devicePixelRatio() returns a number' );
+               assert.strictEqual( typeof devicePixelRatio, 'number', '$.devicePixelRatio() returns a number' );
        } );
 
        QUnit.test( 'bracketedDevicePixelRatio', function ( assert ) {
                var ratio = $.bracketedDevicePixelRatio();
-               assert.equal( typeof ratio, 'number', '$.bracketedDevicePixelRatio() returns a number' );
+               assert.strictEqual( typeof ratio, 'number', '$.bracketedDevicePixelRatio() returns a number' );
        } );
 
        QUnit.test( 'bracketDevicePixelRatio', function ( assert ) {
-               assert.equal( $.bracketDevicePixelRatio( 0.75 ), 1, '0.75 gives 1' );
-               assert.equal( $.bracketDevicePixelRatio( 1 ), 1, '1 gives 1' );
-               assert.equal( $.bracketDevicePixelRatio( 1.25 ), 1.5, '1.25 gives 1.5' );
-               assert.equal( $.bracketDevicePixelRatio( 1.5 ), 1.5, '1.5 gives 1.5' );
-               assert.equal( $.bracketDevicePixelRatio( 1.75 ), 2, '1.75 gives 2' );
-               assert.equal( $.bracketDevicePixelRatio( 2 ), 2, '2 gives 2' );
-               assert.equal( $.bracketDevicePixelRatio( 2.5 ), 2, '2.5 gives 2' );
-               assert.equal( $.bracketDevicePixelRatio( 3 ), 2, '3 gives 2' );
+               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.equal( $.matchSrcSet( 1, srcset ), null, '1.0 gives no match' );
-               assert.equal( $.matchSrcSet( 1.5, srcset ), 'onefive.png', '1.5 gives match' );
-               assert.equal( $.matchSrcSet( 2, srcset ), 'two.png', '2 gives match' );
+               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.equal( $.matchSrcSet( 1.25, srcset ), null, '1.25 gives no match' );
-               assert.equal( $.matchSrcSet( 1.75, srcset ), 'onefive.png', '1.75 gives match to 1.5' );
-               assert.equal( $.matchSrcSet( 2.25, srcset ), 'two.png', '2.25 gives match to 2' );
+               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' );
        } );
 }( jQuery ) );
index 277ba3f..0e34e34 100644 (file)
 
                cases.forEach( function ( item ) {
                        $fixture = $( '<p>' ).text( item.text ).highlightText( item.highlight );
-                       assert.equal(
+                       assert.strictEqual(
                                $fixture.html(),
                                // Re-parse to normalize
                                $( '<p>' ).html( item.expected ).html(),
index 7117d1f..9d4f8dd 100644 (file)
@@ -55,7 +55,7 @@
                        // Simulate pressing keys for each of the sample characters
                        addChars( opt.$input, opt.sample );
 
-                       assert.equal(
+                       assert.strictEqual(
                                opt.$input.val(),
                                opt.expected,
                                'New value matches the expected string'
index d3f6533..df29ee6 100644 (file)
@@ -50,8 +50,8 @@
                        $content = $collapsible.find( '.mw-collapsible-content' ),
                        $toggle = $collapsible.find( '.mw-collapsible-toggle' );
 
-               assert.equal( $content.length, 1, 'content is present' );
-               assert.equal( $content.find( $toggle ).length, 0, 'toggle is not a descendant of content' );
+               assert.strictEqual( $content.length, 1, 'content is present' );
+               assert.strictEqual( $content.find( $toggle ).length, 0, 'toggle is not a descendant of content' );
 
                assert.assertTrue( $content.is( ':visible' ), 'content is visible' );
 
@@ -80,7 +80,7 @@
                        $contentRow = $collapsible.find( 'tr:last' ),
                        $toggle = $headerRow.find( 'td:last .mw-collapsible-toggle' );
 
-               assert.equal( $toggle.length, 1, 'toggle is added to last cell of first row' );
+               assert.strictEqual( $toggle.length, 1, 'toggle is added to last cell of first row' );
 
                assert.assertTrue( $headerRow.is( ':visible' ), 'headerRow is visible' );
                assert.assertTrue( $contentRow.is( ':visible' ), 'contentRow is visible' );
                        $contentRow = $collapsible.find( 'tr:last' ),
                        $toggle = $caption.find( '.mw-collapsible-toggle' );
 
-               assert.equal( $toggle.length, 1, 'toggle is added to the end of the caption' );
+               assert.strictEqual( $toggle.length, 1, 'toggle is added to the end of the caption' );
 
                assert.assertTrue( $caption.is( ':visible' ), 'caption is visible' );
                assert.assertTrue( $headerRow.is( ':visible' ), 'headerRow is visible' );
                        $contentItem = $collapsible.find( 'li:last' ),
                        $toggle = $toggleItem.find( '.mw-collapsible-toggle' );
 
-               assert.equal( $toggle.length, 1, 'toggle is present, added inside new zeroth list item' );
+               assert.strictEqual( $toggle.length, 1, 'toggle is present, added inside new zeroth list item' );
 
                assert.assertTrue( $toggleItem.is( ':visible' ), 'toggleItem is visible' );
                assert.assertTrue( $contentItem.is( ':visible' ), 'contentItem is visible' );
                        '<div>' + loremIpsum + '</div>'
                );
 
-               assert.equal( $collapsible.data( 'mw-made-collapsible' ), true, 'mw-made-collapsible data present' );
+               assert.strictEqual( $collapsible.data( 'mw-made-collapsible' ), true, 'mw-made-collapsible data present' );
        } );
 
        QUnit.test( 'mw-collapsible added when missing', function ( assert ) {
                        ),
                        $toggleText = $collapsible.find( '.mw-collapsible-text' );
 
-               assert.equal( $toggleText.text(), 'Collapse me!', 'data-collapsetext is respected' );
+               assert.strictEqual( $toggleText.text(), 'Collapse me!', 'data-collapsetext is respected' );
 
                $collapsible.on( 'afterCollapse.mw-collapsible', function () {
-                       assert.equal( $toggleText.text(), 'Expand me!', 'data-expandtext is respected' );
+                       assert.strictEqual( $toggleText.text(), 'Expand me!', 'data-expandtext is respected' );
                } );
 
                $collapsible.find( '.mw-collapsible-toggle' ).trigger( 'click' );
                        ),
                        $toggleText = $collapsible.find( '.mw-collapsible-text' );
 
-               assert.equal( $toggleText.text(), 'Collapse me!', 'options.collapseText is respected' );
+               assert.strictEqual( $toggleText.text(), 'Collapse me!', 'options.collapseText is respected' );
 
                $collapsible.on( 'afterCollapse.mw-collapsible', function () {
-                       assert.equal( $toggleText.text(), 'Expand me!', 'options.expandText is respected' );
+                       assert.strictEqual( $toggleText.text(), 'Expand me!', 'options.expandText is respected' );
                } );
 
                $collapsible.find( '.mw-collapsible-toggle' ).trigger( 'click' );
                        ),
                        $toggleText = $collapsible.find( '.mw-collapsible-text' );
 
-               assert.equal( $toggleText.text(), 'Toggle', 'predefined text remains' );
+               assert.strictEqual( $toggleText.text(), 'Toggle', 'predefined text remains' );
 
                $collapsible.on( 'afterCollapse.mw-collapsible', function () {
-                       assert.equal( $toggleText.text(), 'Show', 'predefined text is toggled' );
+                       assert.strictEqual( $toggleText.text(), 'Show', 'predefined text is toggled' );
 
                        $collapsible.on( 'afterExpand.mw-collapsible', function () {
-                               assert.equal( $toggleText.text(), 'Hide', 'predefined text is toggled back' );
+                               assert.strictEqual( $toggleText.text(), 'Hide', 'predefined text is toggled back' );
                        } );
 
                        $collapsible.find( '.mw-collapsible-toggle' ).trigger( 'click' );
index 495ce74..69a5cec 100644 (file)
                );
                $table.data( 'tablesorter' ).sort( [] );
 
-               assert.equal(
+               assert.strictEqual(
                        $table.find( 'th.headerSortUp' ).length + $table.find( 'th.headerSortDown' ).length,
                        0,
                        'No sort specific sort classes addign to header cells'
                );
 
-               assert.equal(
+               assert.strictEqual(
                        $table.find( 'th' ).first().attr( 'title' ),
                        mw.msg( 'sort-ascending' ),
                        'First header cell has default title'
                );
 
-               assert.equal(
+               assert.strictEqual(
                        $table.find( 'th' ).first().attr( 'title' ),
                        $table.find( 'th' ).last().attr( 'title' ),
                        'Both header cells\' titles match'
                $cell = $table.find( 'tr:eq(0) > th:eq(0)' );
                $table.find( 'tr:eq(0) > th:eq(1)' ).click();
 
-               assert.equal(
+               assert.strictEqual(
                        $cell.hasClass( 'headerSortUp' ) || $cell.hasClass( 'headerSortDown' ),
                        false,
                        'after sort: no class headerSortUp or headerSortDown'
                );
 
-               assert.equal(
+               assert.strictEqual(
                        $cell.attr( 'title' ),
                        undefined,
                        'after sort: no title tag added'
 
                $table.tablesorter();
 
-               assert.equal(
+               assert.strictEqual(
                        $table.find( 'tr:eq(2) td:eq(1)' ).prop( 'rowSpan' ),
                        3,
                        'Rowspan not exploded'
                $table.tablesorter();
                $table.find( '.headerSort:eq(0)' ).click();
 
-               assert.equal(
+               assert.strictEqual(
                        $table.data( 'tablesorter' ).config.parsers[ 0 ].id,
                        'number',
                        'Correctly detected column content skipping sortbottom'
                );
                $table.tablesorter();
 
-               assert.equal(
+               assert.strictEqual(
                        $table.children().get( 0 ).nodeName,
                        'CAPTION',
                        'First element after <thead> must be <caption> (T34047)'
                );
                $table.tablesorter();
 
-               assert.equal(
+               assert.strictEqual(
                        $table.find( '> thead:eq(0) > tr > th.headerSort' ).length,
                        1,
                        'Child tables inside a headercell should not interfere with sortable headers (T34888)'
                );
-               assert.equal(
+               assert.strictEqual(
                        $( '#mw-bug-32888-2' ).find( 'th.headerSort' ).length,
                        0,
                        'The headers of child tables inside a headercell should not be sortable themselves (T34888)'
                );
                $table.tablesorter().find( '.headerSort:eq(0)' ).click();
 
-               assert.equal(
+               assert.strictEqual(
                        $table.find( 'td' ).first().text(),
                        '1',
                        'Applied correct sorting order'
                );
                $table.tablesorter().find( '.headerSort:eq(0)' ).click();
 
-               assert.equal(
+               assert.strictEqual(
                        $table.find( 'td' ).text(),
                        'CDEFCCA',
                        'Applied correct sorting order'
                );
                $table.tablesorter().find( '.headerSort:eq(0)' ).click();
 
-               assert.equal(
+               assert.strictEqual(
                        $table.find( 'td' ).text(),
                        '4517',
                        'Applied correct sorting order'
                );
                $table.tablesorter();
 
-               assert.equal(
+               assert.strictEqual(
                        $table.find( '#A1' ).attr( 'class' ),
                        'headerSort',
                        'The first column of the first row should be sortable'
                );
-               assert.equal(
+               assert.strictEqual(
                        $table.find( '#B2b' ).attr( 'class' ),
                        'headerSort',
                        'The th element of the 2nd row of the 2nd column should be sortable'
                );
-               assert.equal(
+               assert.strictEqual(
                        $table.find( '#C2b' ).attr( 'class' ),
                        'headerSort',
                        'The th element of the 2nd row of the 3rd column should be sortable'
                );
                $table.tablesorter();
 
-               assert.equal(
+               assert.strictEqual(
                        $table.find( '#A1' ).attr( 'class' ),
                        'headerSort',
                        'The first column of the first row should be sortable'
                );
-               assert.equal(
+               assert.strictEqual(
                        $table.find( '#B2b' ).attr( 'class' ),
                        'headerSort',
                        'The th element of the 2nd row of the 2nd column should be sortable'
                                '</table>'
                );
                $table.tablesorter();
-               assert.equal( $table.find( '#A2' ).data( 'headerIndex' ),
+               assert.strictEqual( $table.find( '#A2' ).data( 'headerIndex' ),
                        undefined,
                        'A2 should not be a sort header'
                );
-               assert.equal( $table.find( '#C1' ).data( 'headerIndex' ),
+               assert.strictEqual( $table.find( '#C1' ).data( 'headerIndex' ),
                        2,
                        'C1 should be a sort header'
                );
                                '</table>'
                );
                $table.tablesorter();
-               assert.equal( $table.find( '#C2' ).data( 'headerIndex' ),
+               assert.strictEqual( $table.find( '#C2' ).data( 'headerIndex' ),
                        2,
                        'C2 should be a sort header'
                );
-               assert.equal( $table.find( '#C1' ).data( 'headerIndex' ),
+               assert.strictEqual( $table.find( '#C1' ).data( 'headerIndex' ),
                        undefined,
                        'C1 should not be a sort header'
                );
                                '</tbody></table>' );
 
                        $table.tablesorter();
-                       assert.equal( $table.find( 'tr:eq(1) th:eq(1)' ).data( 'headerIndex' ),
+                       assert.strictEqual( $table.find( 'tr:eq(1) th:eq(1)' ).data( 'headerIndex' ),
                                2,
                                'Incorrect index of sort header'
                        );
 
                parsers = $table.data( 'tablesorter' ).config.parsers;
 
-               assert.equal(
+               assert.strictEqual(
                        parsers.length,
                        2,
                        'detectParserForColumn() detect 2 parsers'
                );
 
-               assert.equal(
+               assert.strictEqual(
                        parsers[ 1 ].id,
                        'number',
                        'detectParserForColumn() detect parser.id "number" for second column'
                );
 
-               assert.equal(
+               assert.strictEqual(
                        parsers[ 1 ].format( $table.find( 'tbody > tr > td:eq(1)' ).text() ),
                        -Infinity,
                        'empty cell is sorted as number -Infinity'
                );
 
                parsers = $table.data( 'tablesorter' ).config.parsers;
-               assert.equal(
+               assert.strictEqual(
                        parsers[ 1 ].id,
                        'number',
                        'detectParserForColumn() detect parser.id "number" for second column'
                );
 
                parsers = $table.data( 'tablesorter' ).config.parsers;
-               assert.equal(
+               assert.strictEqual(
                        parsers[ 0 ].id,
                        'number',
                        'detectParserForColumn() detect parser.id "number"'
index 32cda7e..d598586 100644 (file)
 
                        text = $textarea.textSelection( 'getContents' ).replace( /\r\n/g, '\n' );
 
-                       assert.equal( text, opt.after.text, 'Checking full text after encapsulation' );
+                       assert.strictEqual( text, opt.after.text, 'Checking full text after encapsulation' );
 
                        if ( opt.after.selected !== null ) {
                                selected = $textarea.textSelection( 'getSelection' );
-                               assert.equal( selected, opt.after.selected, 'Checking selected text after encapsulation.' );
+                               assert.strictEqual( selected, opt.after.selected, 'Checking selected text after encapsulation.' );
                        }
 
                } );
 
                        function among( actual, expected, message ) {
                                if ( Array.isArray( expected ) ) {
-                                       assert.ok( expected.indexOf( actual ) !== -1, message + ' (got ' + actual + '; expected one of ' + expected.join( ', ' ) + ')' );
+                                       assert.strictEqual( expected.indexOf( actual ) !== -1, true, message + ' (got ' + actual + '; expected one of ' + expected.join( ', ' ) + ')' );
                                } else {
-                                       assert.equal( actual, expected, message );
+                                       assert.strictEqual( actual, expected, message );
                                }
                        }
 
index 50fa6d1..fdf90dd 100644 (file)
@@ -30,7 +30,7 @@
                        '{"batchcomplete":true}'
                ] );
                return new mw.Api().isCategory( '' ).then( function ( response ) {
-                       assert.equal( response, false );
+                       assert.strictEqual( response, false );
                } );
        } );
 
@@ -41,7 +41,7 @@
                        '{"batchcomplete":true,"query":{"normalized":[{"fromencoded":false,"from":"#","to":""}]}}'
                ] );
                return new mw.Api().isCategory( '#' ).then( function ( response ) {
-                       assert.equal( response, false );
+                       assert.strictEqual( response, false );
                } );
        } );
 
@@ -52,7 +52,7 @@
                        '{"batchcomplete":true,"query":{"interwiki":[{"title":"mw:","iw":"mw"}]}}'
                ] );
                return new mw.Api().isCategory( 'mw:' ).then( function ( response ) {
-                       assert.equal( response, false );
+                       assert.strictEqual( response, false );
                } );
        } );
 
@@ -63,7 +63,7 @@
                        '{"batchcomplete":true,"query":{"pages":[{"title":"|","invalidreason":"The requested page title contains invalid characters: \\"|\\".","invalid":true}]}}'
                ] );
                return new mw.Api().isCategory( '|' ).then( function ( response ) {
-                       assert.equal( response, false );
+                       assert.strictEqual( response, false );
                } );
        } );
 
@@ -74,7 +74,7 @@
                        '{"batchcomplete":true}'
                ] );
                return new mw.Api().getCategories( '' ).then( function ( response ) {
-                       assert.equal( response, false );
+                       assert.strictEqual( response, false );
                } );
        } );
 
@@ -85,7 +85,7 @@
                        '{"batchcomplete":true,"query":{"normalized":[{"fromencoded":false,"from":"#","to":""}]}}'
                ] );
                return new mw.Api().getCategories( '#' ).then( function ( response ) {
-                       assert.equal( response, false );
+                       assert.strictEqual( response, false );
                } );
        } );
 
@@ -96,7 +96,7 @@
                        '{"batchcomplete":true,"query":{"interwiki":[{"title":"mw:","iw":"mw"}]}}'
                ] );
                return new mw.Api().getCategories( 'mw:' ).then( function ( response ) {
-                       assert.equal( response, false );
+                       assert.strictEqual( response, false );
                } );
        } );
 
                        '{"batchcomplete":true,"query":{"pages":[{"title":"|","invalidreason":"The requested page title contains invalid characters: \\"|\\".","invalid":true}]}}'
                ] );
                return new mw.Api().getCategories( '|' ).then( function ( response ) {
-                       assert.equal( response, false );
+                       assert.strictEqual( response, false );
                } );
        } );
 
index 4ce7c5d..ff5cb2c 100644 (file)
@@ -43,7 +43,7 @@
                                return revision.content.replace( 'Sand', 'Box' );
                        } )
                        .then( function ( edit ) {
-                               assert.equal( edit.newrevid, 13 );
+                               assert.strictEqual( edit.newrevid, 13 );
                        } );
        } );
 
@@ -84,7 +84,7 @@
                                return revision.content.replace( 'Sand', 'Box' );
                        } )
                        .then( function ( edit ) {
-                               assert.equal( edit.newrevid, 13 );
+                               assert.strictEqual( edit.newrevid, 13 );
                        } );
        } );
 
                                return $.Deferred().resolve( revision.content.replace( 'Async', 'Promise' ) );
                        } )
                        .then( function ( edit ) {
-                               assert.equal( edit.newrevid, 23 );
+                               assert.strictEqual( edit.newrevid, 23 );
                        } );
        } );
 
                                return { text: 'Content', summary: 'Sum' };
                        } )
                        .then( function ( edit ) {
-                               assert.equal( edit.newrevid, 33 );
+                               assert.strictEqual( edit.newrevid, 33 );
                        } );
        } );
 
                        .then( function () {
                                return $.Deferred().reject( 'Unexpected success' );
                        }, function ( reason ) {
-                               assert.equal( reason, 'invalidtitle' );
+                               assert.strictEqual( reason, 'invalidtitle' );
                        } );
        } );
 
                return new mw.Api()
                        .create( 'Sandbox', { summary: 'Load sand particles.' }, 'Sand.' )
                        .then( function ( page ) {
-                               assert.equal( page.newrevid, 41 );
+                               assert.strictEqual( page.newrevid, 41 );
                        } );
        } );
 
index 74da009..5673227 100644 (file)
@@ -13,7 +13,7 @@
                ] );
 
                return new mw.Api().parse( '\'\'\'Hello world\'\'\'' ).done( function ( html ) {
-                       assert.equal( html, '<p><b>Hello world</b></p>', 'Parse wikitext by string' );
+                       assert.strictEqual( html, '<p><b>Hello world</b></p>', 'Parse wikitext by string' );
                } );
        } );
 
@@ -28,7 +28,7 @@
                                return '\'\'\'Hello world\'\'\'';
                        }
                } ).done( function ( html ) {
-                       assert.equal( html, '<p><b>Hello world</b></p>', 'Parse wikitext by toString object' );
+                       assert.strictEqual( html, '<p><b>Hello world</b></p>', 'Parse wikitext by toString object' );
                } );
        } );
 
@@ -39,7 +39,7 @@
                ] );
 
                return new mw.Api().parse( new mw.Title( 'Earth' ) ).done( function ( html ) {
-                       assert.equal( html, '<p><b>Earth</b> is a planet.</p>', 'Parse page by Title object' );
+                       assert.strictEqual( html, '<p><b>Earth</b> is a planet.</p>', 'Parse page by Title object' );
                } );
        } );
 }( mediaWiki ) );
index 7431b29..5ae0e94 100644 (file)
@@ -59,7 +59,7 @@
 
                api.get( { action: 'doesntexist' } )
                        .fail( function ( errorCode ) {
-                               assert.equal( errorCode, 'unknown_action', 'API error should reject the deferred' );
+                               assert.strictEqual( errorCode, 'unknown_action', 'API error should reject the deferred' );
                        } )
                        .always( assert.async() );
        } );
@@ -73,7 +73,7 @@
 
                api.get( { action: 'doesntexist' } )
                        .fail( function ( errorCode ) {
-                               assert.equal( errorCode, 'unknown_action', 'API error should reject the deferred' );
+                               assert.strictEqual( errorCode, 'unknown_action', 'API error should reject the deferred' );
                        } )
                        .always( assert.async() );
        } );
 
                this.server.respond( function ( request ) {
                        if ( window.FormData ) {
-                               assert.ok( !request.url.match( /action=/ ), 'Request has no query string' );
+                               assert.notOk( request.url.match( /action=/ ), 'Request has no query string' );
                                assert.ok( request.requestBody instanceof FormData, 'Request uses FormData body' );
                        } else {
-                               assert.ok( !request.url.match( /action=test/ ), 'Request has no query string' );
-                               assert.equal( request.requestBody, 'action=test&format=json', 'Request uses query string body' );
+                               assert.notOk( request.url.match( /action=test/ ), 'Request has no query string' );
+                               assert.strictEqual( request.requestBody, 'action=test&format=json', 'Request uses query string body' );
                        }
                        request.respond( 200, { 'Content-Type': 'application/json' }, '[]' );
                } );
@@ -99,7 +99,7 @@
                var api = new mw.Api();
 
                this.server.respond( function ( request ) {
-                       assert.equal( match( request.url, /test=([^&]+)/ ), 'foo%7Cbar%7Cbaz', 'Pipe-separated value was submitted' );
+                       assert.strictEqual( match( request.url, /test=([^&]+)/ ), 'foo%7Cbar%7Cbaz', 'Pipe-separated value was submitted' );
                        request.respond( 200, { 'Content-Type': 'application/json' }, '[]' );
                } );
 
                var api = new mw.Api();
 
                this.server.respond( function ( request ) {
-                       assert.equal( match( request.url, /test=([^&]+)/ ), 'Foo%7CBar', 'Pipe-separated value was submitted' );
+                       assert.strictEqual( match( request.url, /test=([^&]+)/ ), 'Foo%7CBar', 'Pipe-separated value was submitted' );
                        request.respond( 200, { 'Content-Type': 'application/json' }, '[]' );
                } );
 
                var api = new mw.Api();
 
                this.server.respond( function ( request ) {
-                       assert.equal( match( request.url, /test=([^&]+)/ ), 'true%7Cfalse%7C%7C%7C0%7C1%2E2', 'Pipe-separated value was submitted' );
+                       assert.strictEqual( match( request.url, /test=([^&]+)/ ), 'true%7Cfalse%7C%7C%7C0%7C1%2E2', 'Pipe-separated value was submitted' );
                        request.respond( 200, { 'Content-Type': 'application/json' }, '[]' );
                } );
 
                var api = new mw.Api();
 
                this.server.respond( function ( request ) {
-                       assert.ok( !request.url.match( /foo/ ), 'foo query parameter is not present' );
+                       assert.notOk( request.url.match( /foo/ ), 'foo query parameter is not present' );
                        assert.ok( request.url.match( /bar=true/ ), 'bar query parameter is present with value true' );
                        request.respond( 200, { 'Content-Type': 'application/json' }, '[]' );
                } );
                        .then( function ( token ) {
                                assert.ok( token.length, 'Got a token' );
                        }, function ( err ) {
-                               assert.equal( '', err, 'API error' );
+                               assert.strictEqual( err, '', 'API error' );
                        } )
                        .then( function () {
-                               assert.equal( test.server.requests.length, 0, 'Requests made' );
+                               assert.strictEqual( test.server.requests.length, 0, 'Requests made' );
                        } );
        } );
 
                // be added to user.tokens, use a fake one instead.
                api.getToken( 'testuncached' )
                        .done( function ( token ) {
-                               assert.equal( token, 'good', 'The token' );
+                               assert.strictEqual( token, 'good', 'The token' );
                        } )
                        .fail( function ( err ) {
-                               assert.equal( err, '', 'API error' );
+                               assert.strictEqual( err, '', 'API error' );
                        } )
                        .always( firstDone );
 
                api.getToken( 'testuncached' )
                        .done( function ( token ) {
-                               assert.equal( token, 'good', 'The cached token' );
+                               assert.strictEqual( token, 'good', 'The cached token' );
                        } )
                        .fail( function ( err ) {
-                               assert.equal( err, '', 'API error' );
+                               assert.strictEqual( err, '', 'API error' );
                        } )
                        .always( secondDone );
 
-               assert.equal( this.server.requests.length, 1, 'Requests made' );
+               assert.strictEqual( this.server.requests.length, 1, 'Requests made' );
        } );
 
        QUnit.test( 'getToken() - error', function ( assert ) {
                // Don't cache error (T67268)
                return api.getToken( 'testerror' )
                        .catch( function ( err ) {
-                               assert.equal( err, 'bite-me', 'Expected error' );
+                               assert.strictEqual( err, 'bite-me', 'Expected error' );
 
                                return api.getToken( 'testerror' );
                        } )
                        .then( function ( token ) {
-                               assert.equal( token, 'good', 'The token' );
+                               assert.strictEqual( token, 'good', 'The token' );
                        } );
        } );
 
                return api.getToken( 'testnoquery' )
                        .then( function () { assert.fail( 'Expected response missing a query to be rejected' ); } )
                        .catch( function ( err, rsp ) {
-                               assert.equal( err, 'query-missing', 'Expected no query error code' );
+                               assert.strictEqual( err, 'query-missing', 'Expected no query error code' );
                                assert.deepEqual( rsp, serverRsp );
                        } );
        } );
                // Get a token of a type that is in the legacy map.
                return api.getToken( 'email' )
                        .done( function ( token ) {
-                               assert.equal( token, 'csrfgood', 'Token' );
+                               assert.strictEqual( token, 'csrfgood', 'Token' );
                        } )
                        .fail( function ( err ) {
-                               assert.equal( err, '', 'API error' );
+                               assert.strictEqual( err, '', 'API error' );
                        } )
                        .always( function () {
-                               assert.equal( test.server.requests.length, 1, 'Requests made' );
+                               assert.strictEqual( test.server.requests.length, 1, 'Requests made' );
                        } );
        } );
 
                                return api.getToken( 'testbad' );
                        } )
                        .then( function ( token ) {
-                               assert.equal( token, 'good', 'The token' );
-                               assert.equal( test.server.requests.length, 2, 'Requests made' );
+                               assert.strictEqual( token, 'good', 'The token' );
+                               assert.strictEqual( test.server.requests.length, 2, 'Requests made' );
                        } );
 
        } );
                                return api.getToken( 'options' );
                        } )
                        .then( function ( token ) {
-                               assert.equal( token, 'goodlegacy', 'The token' );
-                               assert.equal( test.server.requests.length, 2, 'Request made' );
+                               assert.strictEqual( token, 'goodlegacy', 'The token' );
+                               assert.strictEqual( test.server.requests.length, 2, 'Request made' );
                        } );
 
        } );
                        .then( function () {
                                return $.Deferred().reject( 'Unexpected success' );
                        }, function ( errorCode ) {
-                               assert.equal( errorCode, 'assertuserfailed', 'getToken fails assert' );
+                               assert.strictEqual( errorCode, 'assertuserfailed', 'getToken fails assert' );
                                return $.Deferred().resolve();
                        } )
                        .then( function () {
-                               assert.equal( test.server.requests.length, 1, 'Requests made' );
+                               assert.strictEqual( test.server.requests.length, 1, 'Requests made' );
                        } );
        } );
 
                                }
                        }
                ).then( function () {
-                       assert.equal( test.server.requests[ 0 ].requestHeaders[ 'X-Foo' ], 'Bar', 'Header sent' );
+                       assert.strictEqual( test.server.requests[ 0 ].requestHeaders[ 'X-Foo' ], 'Bar', 'Header sent' );
 
                        return api.postWithToken( 'csrf',
                                { action: 'example' },
                                }
                        );
                } ).then( function ( data ) {
-                       assert.equal( data.example, 'quux' );
+                       assert.strictEqual( data.example, 'quux' );
 
-                       assert.equal( test.server.requests.length, 2, 'Request made' );
+                       assert.strictEqual( test.server.requests.length, 2, 'Request made' );
                } );
        } );
 
        } );
 
        QUnit.module( 'mediawiki.api (2)', {
-               setup: function () {
+               beforeEach: function () {
                        var self = this,
                                requests = this.requests = [];
                        this.api = new mw.Api();
                        b: 2
                } );
                this.api.abort();
-               assert.ok( this.requests.length === 2, 'Check both requests triggered' );
+               assert.strictEqual( this.requests.length, 2, 'Check both requests triggered' );
                this.requests.forEach( function ( request, i ) {
                        assert.ok( request.abort.calledOnce, 'abort request number ' + i );
                } );
index 8641469..649bf03 100644 (file)
@@ -17,7 +17,7 @@
                } );
 
                return new mw.Api().watch( 'Foo' ).done( function ( item ) {
-                       assert.equal( item.title, 'Foo' );
+                       assert.strictEqual( item.title, 'Foo' );
                } );
        } );
 
@@ -34,7 +34,7 @@
                } );
 
                return new mw.Api().watch( [ 'Foo' ] ).done( function ( items ) {
-                       assert.equal( items[ 0 ].title, 'Foo' );
+                       assert.strictEqual( items[ 0 ].title, 'Foo' );
                } );
        } );
 
@@ -52,8 +52,8 @@
                } );
 
                return new mw.Api().watch( [ 'Foo', 'Bar' ] ).done( function ( items ) {
-                       assert.equal( items[ 0 ].title, 'Foo' );
-                       assert.equal( items[ 1 ].title, 'Bar' );
+                       assert.strictEqual( items[ 0 ].title, 'Foo' );
+                       assert.strictEqual( items[ 1 ].title, 'Bar' );
                } );
        } );
 
index 872f4dd..79a1b26 100644 (file)
        QUnit.test( 'getVersion', function ( assert ) {
                var uriProcessor = new mw.rcfilters.UriProcessor( new mw.rcfilters.dm.FiltersViewModel() );
 
-               assert.ok(
+               assert.strictEqual(
                        uriProcessor.getVersion( { param1: 'foo', urlversion: '2' } ),
                        2,
                        'Retrieving the version from the URI query'
                );
 
-               assert.ok(
+               assert.strictEqual(
                        uriProcessor.getVersion( { param1: 'foo' } ),
                        1,
                        'Getting version 1 if no version is specified'
                uriProcessor = new mw.rcfilters.UriProcessor( filtersModel );
 
                cases.forEach( function ( testCase ) {
-                       assert.equal(
+                       assert.strictEqual(
                                uriProcessor.isNewState( testCase.states.curr, testCase.states.new ),
                                testCase.result,
                                testCase.message
                uriProcessor = new mw.rcfilters.UriProcessor( filtersModel );
 
                cases.forEach( function ( testCase ) {
-                       assert.equal(
+                       assert.strictEqual(
                                uriProcessor.doesQueryContainRecognizedParams( testCase.query ),
                                testCase.result,
                                testCase.message
                                }
                        );
 
-                       assert.equal(
+                       assert.strictEqual(
                                uriProcessor._normalizeTargetInUri(
                                        new mw.Uri( testCase.input )
                                ).toString(),
index 18a2c9c..03ef387 100644 (file)
@@ -8,12 +8,12 @@
                        group2 = new mw.rcfilters.dm.FilterGroup( 'group2' );
 
                item = new mw.rcfilters.dm.FilterItem( 'filter1', group1 );
-               assert.equal(
+               assert.strictEqual(
                        item.getName(),
                        'group1__filter1',
                        'Filter name is retained.'
                );
-               assert.equal(
+               assert.strictEqual(
                        item.getGroupName(),
                        'group1',
                        'Group name is retained.'
                                description: 'test description'
                        }
                );
-               assert.equal(
+               assert.strictEqual(
                        item.getLabel(),
                        'test label',
                        'Label information is retained.'
                );
-               assert.equal(
+               assert.strictEqual(
                        item.getLabel(),
                        'test label',
                        'Description information is retained.'
                                selected: true
                        }
                );
-               assert.equal(
+               assert.strictEqual(
                        item.isSelected(),
                        true,
                        'Item can be selected in the config.'
                );
                item.toggleSelected( true );
-               assert.equal(
+               assert.strictEqual(
                        item.isSelected(),
                        true,
                        'Item can toggle its selected state.'
                        [ 'sub1', 'sub2', 'sub3' ],
                        'Subset information is retained.'
                );
-               assert.equal(
+               assert.strictEqual(
                        item.existsInSubset( 'sub1' ),
                        true,
                        'Specific item exists in subset.'
                );
-               assert.equal(
+               assert.strictEqual(
                        item.existsInSubset( 'sub10' ),
                        false,
                        'Specific item does not exists in subset.'
                );
-               assert.equal(
+               assert.strictEqual(
                        item.isIncluded(),
                        false,
                        'Initial state of "included" is false.'
                );
 
                item.toggleIncluded( true );
-               assert.equal(
+               assert.strictEqual(
                        item.isIncluded(),
                        true,
                        'Item toggles its included state.'
                        },
                        'Conflict information is retained.'
                );
-               assert.equal(
+               assert.strictEqual(
                        item.existsInConflicts( new mw.rcfilters.dm.FilterItem( 'conflict1', group2 ) ),
                        true,
                        'Specific item exists in conflicts.'
                );
-               assert.equal(
+               assert.strictEqual(
                        item.existsInConflicts( new mw.rcfilters.dm.FilterItem( 'conflict10', group1 ) ),
                        false,
                        'Specific item does not exists in conflicts.'
                );
-               assert.equal(
+               assert.strictEqual(
                        item.isConflicted(),
                        false,
                        'Initial state of "conflicted" is false.'
                );
 
                item.toggleConflicted( true );
-               assert.equal(
+               assert.strictEqual(
                        item.isConflicted(),
                        true,
                        'Item toggles its conflicted state.'
 
                // Fully covered
                item = new mw.rcfilters.dm.FilterItem( 'filter1', group1 );
-               assert.equal(
+               assert.strictEqual(
                        item.isFullyCovered(),
                        false,
                        'Initial state of "full coverage" is false.'
                );
                item.toggleFullyCovered( true );
-               assert.equal(
+               assert.strictEqual(
                        item.isFullyCovered(),
                        true,
                        'Item toggles its fully coverage state.'
 
                item.setValue( '1' );
 
-               assert.equal( item.getValue(), true, 'Value is coerced to boolean' );
+               assert.strictEqual( item.getValue(), true, 'Value is coerced to boolean' );
        } );
 
        QUnit.test( 'get/set any value', function ( assert ) {
 
                item.setValue( '1' );
 
-               assert.equal( item.getValue(), '1', 'Value is kept as-is' );
+               assert.strictEqual( item.getValue(), '1', 'Value is kept as-is' );
        } );
 }( mediaWiki ) );
index 2b42b5a..45d591d 100644 (file)
 
                model.initializeFilters( definition );
 
-               assert.ok(
-                       !model.isHighlightEnabled(),
+               assert.strictEqual(
+                       model.isHighlightEnabled(),
+                       false,
                        'Initially, highlight is disabled.'
                );
 
                model.toggleHighlight( true );
-               assert.ok(
+               assert.strictEqual(
                        model.isHighlightEnabled(),
+                       true,
                        'Highlight is enabled on toggle.'
                );
 
                        'Highlighted items are highlighted.'
                );
 
-               assert.equal(
+               assert.strictEqual(
                        model.getItemByName( 'group1__filter1' ).getHighlightColor(),
                        'color1',
                        'Item highlight color is set.'
                );
 
                model.setHighlightColor( 'group1__filter1', 'color1changed' );
-               assert.equal(
+               assert.strictEqual(
                        model.getItemByName( 'group1__filter1' ).getHighlightColor(),
                        'color1changed',
                        'Item highlight color is changed on setHighlightColor.'
                model.initializeFilters( shortFilterDefinition, null );
 
                model.emptyAllFilters();
-               assert.ok( model.areVisibleFiltersEmpty() );
+               assert.strictEqual( model.areVisibleFiltersEmpty(), true );
 
                model.toggleFiltersSelected( {
                        group3__filter5: true // sticky
                } );
-               assert.ok( model.areVisibleFiltersEmpty() );
+               assert.strictEqual( model.areVisibleFiltersEmpty(), true );
 
                model.toggleFiltersSelected( {
                        group1__filter1: true
                } );
-               assert.notOk( model.areVisibleFiltersEmpty() );
+               assert.strictEqual( model.areVisibleFiltersEmpty(), false );
        } );
 }( mediaWiki, jQuery ) );
index ed054bd..92e5f2e 100644 (file)
                                testCase.msg + ' (itemState)'
                        );
 
-                       assert.equal(
+                       assert.strictEqual(
                                item.isDefault(),
                                testCase.result.isDefault,
                                testCase.msg + ' (isDefault)'
                        );
 
                        if ( testCase.result.id !== undefined ) {
-                               assert.equal(
+                               assert.strictEqual(
                                        item.getID(),
                                        testCase.result.id,
                                        testCase.msg + ' (item ID)'
                );
                item1 = queriesModel.getItemByID( id1 );
 
-               assert.equal(
+               assert.strictEqual(
                        item1.getID(),
                        id1,
                        'Item created and its data retained successfully'
index 181e992..5e35c18 100644 (file)
                        $.extend( true, {}, itemData )
                );
 
-               assert.equal(
+               assert.strictEqual(
                        model.getID(),
                        'randomID',
                        'Item ID is retained'
                );
 
-               assert.equal(
+               assert.strictEqual(
                        model.getLabel(),
                        'Some label',
                        'Item label is retained'
@@ -41,8 +41,9 @@
                        'Item data is retained'
                );
 
-               assert.ok(
-                       !model.isDefault(),
+               assert.strictEqual(
+                       model.isDefault(),
+                       false,
                        'Item default state is retained.'
                );
        } );
                        $.extend( true, {}, itemData )
                );
 
-               assert.ok(
-                       !model.isDefault(),
+               assert.strictEqual(
+                       model.isDefault(),
+                       false,
                        'Default state represented when item initialized with default:false.'
                );
 
                model.toggleDefault( true );
-               assert.ok(
+               assert.strictEqual(
                        model.isDefault(),
+                       true,
                        'Default state toggles to true successfully'
                );
 
                model.toggleDefault( false );
-               assert.ok(
-                       !model.isDefault(),
+               assert.strictEqual(
+                       model.isDefault(),
+                       false,
                        'Default state toggles to false successfully'
                );
 
@@ -81,8 +85,9 @@
                        { default: true }
                );
 
-               assert.ok(
+               assert.strictEqual(
                        model.isDefault(),
+                       true,
                        'Default state represented when item initialized with default:true.'
                );
        } );
diff --git a/tests/qunit/suites/resources/mediawiki.widgets/MediaSearch/mediawiki.widgets.APIResultsQueue.test.js b/tests/qunit/suites/resources/mediawiki.widgets/MediaSearch/mediawiki.widgets.APIResultsQueue.test.js
new file mode 100644 (file)
index 0000000..a343aa5
--- /dev/null
@@ -0,0 +1,197 @@
+/*!
+ * VisualEditor DataModel ResourceQueue tests.
+ *
+ * @copyright 2011-2018 VisualEditor Team and others; see http://ve.mit-license.org
+ */
+
+QUnit.module( 'mediawiki.widgets.APIResultsQueue' );
+
+( function ( $, mw ) {
+       var itemCounter, FullResourceProvider, EmptyResourceProvider, SingleResultResourceProvider;
+
+       itemCounter = 0;
+       FullResourceProvider = function ( config ) {
+               this.timer = null;
+               this.responseDelay = 1;
+               // Inheritance
+               FullResourceProvider.super.call( this, '', config );
+       };
+       EmptyResourceProvider = function ( config ) {
+               this.timer = null;
+               this.responseDelay = 1;
+               // Inheritance
+               EmptyResourceProvider.super.call( this, '', config );
+       };
+       SingleResultResourceProvider = function ( config ) {
+               this.timer = null;
+               this.responseDelay = 1;
+               // Inheritance
+               SingleResultResourceProvider.super.call( this, '', config );
+       };
+
+       OO.inheritClass( FullResourceProvider, mw.widgets.APIResultsProvider );
+       OO.inheritClass( EmptyResourceProvider, mw.widgets.APIResultsProvider );
+       OO.inheritClass( SingleResultResourceProvider, mw.widgets.APIResultsProvider );
+
+       FullResourceProvider.prototype.getResults = function ( howMany ) {
+               var i, timer,
+                       result = [],
+                       deferred = $.Deferred();
+
+               for ( i = itemCounter; i < itemCounter + howMany; i++ ) {
+                       result.push( 'result ' + ( i + 1 ) );
+               }
+               itemCounter = i;
+
+               timer = setTimeout(
+                       function () {
+                               // Always resolve with some values
+                               deferred.resolve( result );
+                       },
+                       this.responseDelay );
+
+               return deferred.promise( { abort: function () { clearTimeout( timer ); } } );
+       };
+
+       EmptyResourceProvider.prototype.getResults = function () {
+               var provider = this,
+                       deferred = $.Deferred(),
+                       timer = setTimeout(
+                               function () {
+                                       provider.toggleDepleted( true );
+                                       // Always resolve with empty value
+                                       deferred.resolve( [] );
+                               },
+                               this.responseDelay );
+
+               return deferred.promise( { abort: function () { clearTimeout( timer ); } } );
+       };
+
+       SingleResultResourceProvider.prototype.getResults = function ( howMany ) {
+               var timer,
+                       provider = this,
+                       deferred = $.Deferred();
+
+               timer = setTimeout(
+                       function () {
+                               provider.toggleDepleted( howMany > 1 );
+                               // Always resolve with one value
+                               deferred.resolve( [ 'one result (' + ( itemCounter++ + 1 ) + ')' ] );
+                       },
+                       this.responseDelay );
+
+               return deferred.promise( { abort: function () { clearTimeout( timer ); } } );
+       };
+
+       /* Tests */
+
+       QUnit.test( 'Query providers', function ( assert ) {
+               var done = assert.async(),
+                       providers = [
+                               new FullResourceProvider(),
+                               new EmptyResourceProvider(),
+                               new SingleResultResourceProvider()
+                       ],
+                       queue = new mw.widgets.APIResultsQueue( {
+                               threshold: 2
+                       } );
+
+               assert.expect( 15 );
+
+               // Add providers to queue
+               queue.setProviders( providers );
+
+               // Set parameters and fetch
+               queue.setParams( { foo: 'bar' } );
+
+               queue.get( 10 )
+                       .then( function ( data ) {
+                               // Check that we received all requested results
+                               assert.strictEqual( data.length, 10, 'Query 1: Results received.' );
+                               // We've asked for 10 items + 2 threshold from all providers.
+                               // Provider 1 returned 12 results
+                               // Provider 2 returned 0 results
+                               // Provider 3 returned 1 results
+                               // Overall 13 results. 10 were retrieved. 3 left in queue.
+                               assert.strictEqual( queue.getQueueSize(), 3, 'Query 1: Remaining queue size.' );
+
+                               // Check if sources are depleted
+                               assert.strictEqual( providers[ 0 ].isDepleted(), false, 'Query 1: Full provider not depleted.' );
+                               assert.strictEqual( providers[ 1 ].isDepleted(), true, 'Query 1: Empty provider is depleted.' );
+                               assert.strictEqual( providers[ 2 ].isDepleted(), true, 'Query 1: Single result provider is depleted.' );
+
+                               // Ask for more results
+                               return queue.get( 10 );
+                       } )
+                       .then( function ( data1 ) {
+                               // This time, only provider 1 was queried, because the other
+                               // two were marked as depleted.
+                               // * We asked for 10 items
+                               // * There are currently 3 items in the queue
+                               // * The queue queried provider #1 for 12 items
+                               // * The queue returned 10 results as requested
+                               // * 5 results are now left in the queue.
+                               assert.strictEqual( data1.length, 10, 'Query 1: Second set of results received.' );
+                               assert.strictEqual( queue.getQueueSize(), 5, 'Query 1: Remaining queue size.' );
+
+                               // Change the query
+                               queue.setParams( { foo: 'baz' } );
+                               // Check if sources are depleted
+                               assert.strictEqual( providers[ 0 ].isDepleted(), false, 'Query 2: Full provider not depleted.' );
+                               assert.strictEqual( providers[ 1 ].isDepleted(), false, 'Query 2: Empty provider not depleted.' );
+                               assert.strictEqual( providers[ 2 ].isDepleted(), false, 'Query 2: Single result provider not depleted.' );
+
+                               return queue.get( 10 );
+                       } )
+                       .then( function ( data2 ) {
+                               // This should be the same as the very first result
+                               assert.strictEqual( data2.length, 10, 'Query 2: Results received.' );
+                               assert.strictEqual( queue.getQueueSize(), 3, 'Query 2: Remaining queue size.' );
+                               // Check if sources are depleted
+                               assert.strictEqual( providers[ 0 ].isDepleted(), false, 'Query 2: Full provider not depleted.' );
+                               assert.strictEqual( providers[ 1 ].isDepleted(), true, 'Query 2: Empty provider is not depleted.' );
+                               assert.strictEqual( providers[ 2 ].isDepleted(), true, 'Query 2: Single result provider is not depleted.' );
+                       } )
+                       // Finish the async test
+                       .then( done );
+       } );
+
+       QUnit.test( 'Abort providers', function ( assert ) {
+               var done = assert.async(),
+                       completed = false,
+                       biggerQueue = new mw.widgets.APIResultsQueue( {
+                               threshold: 5
+                       } ),
+                       providers = [
+                               new FullResourceProvider(),
+                               new EmptyResourceProvider(),
+                               new SingleResultResourceProvider()
+                       ];
+
+               assert.expect( 1 );
+
+               // Make the delay higher
+               providers.forEach( function ( provider ) { provider.responseDelay = 3; } );
+
+               // Add providers to queue
+               biggerQueue.setProviders( providers );
+
+               biggerQueue.setParams( { foo: 'bar' } );
+               biggerQueue.get( 100 )
+                       .always( function () {
+                               // This should only run if the promise wasn't aborted
+                               completed = true;
+                       } );
+
+               // Make the delay higher
+               providers.forEach( function ( provider ) { provider.responseDelay = 5; } );
+
+               biggerQueue.setParams( { foo: 'baz' } );
+               biggerQueue.get( 10 )
+                       .then( function () {
+                               assert.strictEqual( completed, false, 'Provider promises aborted.' );
+                       } )
+                       // Finish the async test
+                       .then( done );
+       } );
+}( jQuery, mediaWiki ) );
index 4e15cf0..485bac0 100644 (file)
@@ -32,7 +32,7 @@
                        assert.propEqual( str.match( new RegExp( mw.RegExp.escape( str ) ) ), [ str ], 'Match ' + str );
                } );
 
-               assert.equal( mw.RegExp.escape( normal ), normal, 'Alphanumerals are left alone' );
+               assert.strictEqual( mw.RegExp.escape( normal ), normal, 'Alphanumerals are left alone' );
        } );
 
 }( mediaWiki ) );
index ae3ebbf..61b8f34 100644 (file)
                        x = '*',
                        space = '   ';
 
-               assert.equal( byteLength( azLc ), 26, 'Lowercase a-z' );
-               assert.equal( byteLength( azUc ), 26, 'Uppercase A-Z' );
-               assert.equal( byteLength( num ), 10, 'Numbers 0-9' );
-               assert.equal( byteLength( x ), 1, 'An asterisk' );
-               assert.equal( byteLength( space ), 3, '3 spaces' );
+               assert.strictEqual( byteLength( azLc ), 26, 'Lowercase a-z' );
+               assert.strictEqual( byteLength( azUc ), 26, 'Uppercase A-Z' );
+               assert.strictEqual( byteLength( num ), 10, 'Numbers 0-9' );
+               assert.strictEqual( byteLength( x ), 1, 'An asterisk' );
+               assert.strictEqual( byteLength( space ), 3, '3 spaces' );
 
        } );
 
index e2eea94..0898afd 100644 (file)
@@ -40,7 +40,7 @@
                QUnit.test( opt.description, function ( assert ) {
                        var res = trimByteLength( opt.initial, opt.sample, opt.limit, opt.fn );
 
-                       assert.equal(
+                       assert.strictEqual(
                                res.newVal,
                                opt.expected,
                                'New value matches the expected string'
index e8db4e1..8d67b4b 100644 (file)
        QUnit.test( 'newFromText', function ( assert ) {
                var i;
                for ( i = 0; i < cases.valid.length; i++ ) {
-                       assert.equal(
+                       assert.strictEqual(
                                $.type( mw.Title.newFromText( cases.valid[ i ] ) ),
                                'object',
                                cases.valid[ i ]
                        );
                }
                for ( i = 0; i < cases.invalid.length; i++ ) {
-                       assert.equal(
+                       assert.strictEqual(
                                $.type( mw.Title.newFromText( cases.invalid[ i ] ) ),
                                'null',
                                cases.invalid[ i ]
                var title;
                title = new mw.Title( 'File:Foo_bar.JPG' );
 
-               assert.equal( title.getNamespaceId(), 6 );
-               assert.equal( title.getNamespacePrefix(), 'File:' );
-               assert.equal( title.getName(), 'Foo_bar' );
-               assert.equal( title.getNameText(), 'Foo bar' );
-               assert.equal( title.getExtension(), 'JPG' );
-               assert.equal( title.getDotExtension(), '.JPG' );
-               assert.equal( title.getMain(), 'Foo_bar.JPG' );
-               assert.equal( title.getMainText(), 'Foo bar.JPG' );
-               assert.equal( title.getPrefixedDb(), 'File:Foo_bar.JPG' );
-               assert.equal( title.getPrefixedText(), 'File:Foo bar.JPG' );
+               assert.strictEqual( title.getNamespaceId(), 6 );
+               assert.strictEqual( title.getNamespacePrefix(), 'File:' );
+               assert.strictEqual( title.getName(), 'Foo_bar' );
+               assert.strictEqual( title.getNameText(), 'Foo bar' );
+               assert.strictEqual( title.getExtension(), 'JPG' );
+               assert.strictEqual( title.getDotExtension(), '.JPG' );
+               assert.strictEqual( title.getMain(), 'Foo_bar.JPG' );
+               assert.strictEqual( title.getMainText(), 'Foo bar.JPG' );
+               assert.strictEqual( title.getPrefixedDb(), 'File:Foo_bar.JPG' );
+               assert.strictEqual( title.getPrefixedText(), 'File:Foo bar.JPG' );
 
                title = new mw.Title( 'Foo#bar' );
-               assert.equal( title.getPrefixedText(), 'Foo' );
-               assert.equal( title.getFragment(), 'bar' );
+               assert.strictEqual( title.getPrefixedText(), 'Foo' );
+               assert.strictEqual( title.getFragment(), 'bar' );
 
                title = new mw.Title( '.foo' );
-               assert.equal( title.getPrefixedText(), '.foo' );
-               assert.equal( title.getName(), '' );
-               assert.equal( title.getNameText(), '' );
-               assert.equal( title.getExtension(), 'foo' );
-               assert.equal( title.getDotExtension(), '.foo' );
-               assert.equal( title.getMain(), '.foo' );
-               assert.equal( title.getMainText(), '.foo' );
-               assert.equal( title.getPrefixedDb(), '.foo' );
-               assert.equal( title.getPrefixedText(), '.foo' );
+               assert.strictEqual( title.getPrefixedText(), '.foo' );
+               assert.strictEqual( title.getName(), '' );
+               assert.strictEqual( title.getNameText(), '' );
+               assert.strictEqual( title.getExtension(), 'foo' );
+               assert.strictEqual( title.getDotExtension(), '.foo' );
+               assert.strictEqual( title.getMain(), '.foo' );
+               assert.strictEqual( title.getMainText(), '.foo' );
+               assert.strictEqual( title.getPrefixedDb(), '.foo' );
+               assert.strictEqual( title.getPrefixedText(), '.foo' );
        } );
 
        QUnit.test( 'Transformation', function ( assert ) {
                var title;
 
                title = new mw.Title( 'File:quux pif.jpg' );
-               assert.equal( title.getNameText(), 'Quux pif', 'First character of title' );
+               assert.strictEqual( title.getNameText(), 'Quux pif', 'First character of title' );
 
                title = new mw.Title( 'File:Glarg_foo_glang.jpg' );
-               assert.equal( title.getNameText(), 'Glarg foo glang', 'Underscores' );
+               assert.strictEqual( title.getNameText(), 'Glarg foo glang', 'Underscores' );
 
                title = new mw.Title( 'User:ABC.DEF' );
-               assert.equal( title.toText(), 'User:ABC.DEF', 'Round trip text' );
-               assert.equal( title.getNamespaceId(), 2, 'Parse canonical namespace prefix' );
+               assert.strictEqual( title.toText(), 'User:ABC.DEF', 'Round trip text' );
+               assert.strictEqual( title.getNamespaceId(), 2, 'Parse canonical namespace prefix' );
 
                title = new mw.Title( 'Image:quux pix.jpg' );
-               assert.equal( title.getNamespacePrefix(), 'File:', 'Transform alias to canonical namespace' );
+               assert.strictEqual( title.getNamespacePrefix(), 'File:', 'Transform alias to canonical namespace' );
 
                title = new mw.Title( 'uSEr:hAshAr' );
-               assert.equal( title.toText(), 'User:HAshAr' );
-               assert.equal( title.getNamespaceId(), 2, 'Case-insensitive namespace prefix' );
+               assert.strictEqual( title.toText(), 'User:HAshAr' );
+               assert.strictEqual( title.getNamespaceId(), 2, 'Case-insensitive namespace prefix' );
 
                title = new mw.Title( 'Foo \u00A0\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u2028\u2029\u202F\u205F\u3000 bar' );
-               assert.equal( title.getMain(), 'Foo_bar', 'Merge multiple types of whitespace/underscores into a single underscore' );
+               assert.strictEqual( title.getMain(), 'Foo_bar', 'Merge multiple types of whitespace/underscores into a single underscore' );
 
-               title = new mw.Title( 'Foo\u00AD\u061C\u200E\u200F\u202A\u202B\u202C\u202D\u202E\u2066\u2067\u2068\u2069bar' );
-               assert.equal( title.getMain(), 'Foobar', 'Strip soft hyphen and Unicode directional formatting characters' );
+               title = new mw.Title( 'Foo\u200E\u200F\u202A\u202B\u202C\u202D\u202Ebar' );
+               assert.strictEqual( title.getMain(), 'Foobar', 'Strip Unicode bidi override characters' );
 
                // Regression test: Previously it would only detect an extension if there is no space after it
                title = new mw.Title( 'Example.js  ' );
-               assert.equal( title.getExtension(), 'js', 'Space after an extension is stripped' );
+               assert.strictEqual( title.getExtension(), 'js', 'Space after an extension is stripped' );
 
                title = new mw.Title( 'Example#foo' );
-               assert.equal( title.getFragment(), 'foo', 'Fragment' );
+               assert.strictEqual( title.getFragment(), 'foo', 'Fragment' );
 
                title = new mw.Title( 'Example#_foo_bar baz_' );
-               assert.equal( title.getFragment(), ' foo bar baz', 'Fragment' );
+               assert.strictEqual( title.getFragment(), ' foo bar baz', 'Fragment' );
        } );
 
        QUnit.test( 'Namespace detection and conversion', function ( assert ) {
                var title;
 
                title = new mw.Title( 'File:User:Example' );
-               assert.equal( title.getNamespaceId(), 6, 'Titles can contain namespace prefixes, which are otherwise ignored' );
+               assert.strictEqual( title.getNamespaceId(), 6, 'Titles can contain namespace prefixes, which are otherwise ignored' );
 
                title = new mw.Title( 'Example', 6 );
-               assert.equal( title.getNamespaceId(), 6, 'Default namespace passed is used' );
+               assert.strictEqual( title.getNamespaceId(), 6, 'Default namespace passed is used' );
 
                title = new mw.Title( 'User:Example', 6 );
-               assert.equal( title.getNamespaceId(), 2, 'Included namespace prefix overrides the given default' );
+               assert.strictEqual( title.getNamespaceId(), 2, 'Included namespace prefix overrides the given default' );
 
                title = new mw.Title( ':Example', 6 );
-               assert.equal( title.getNamespaceId(), 0, 'Colon forces main namespace' );
+               assert.strictEqual( title.getNamespaceId(), 0, 'Colon forces main namespace' );
 
                title = new mw.Title( 'something.PDF', 6 );
-               assert.equal( title.toString(), 'File:Something.PDF' );
+               assert.strictEqual( title.toString(), 'File:Something.PDF' );
 
                title = new mw.Title( 'NeilK', 3 );
-               assert.equal( title.toString(), 'User_talk:NeilK' );
-               assert.equal( title.toText(), 'User talk:NeilK' );
+               assert.strictEqual( title.toString(), 'User_talk:NeilK' );
+               assert.strictEqual( title.toText(), 'User talk:NeilK' );
 
                title = new mw.Title( 'Frobisher', 100 );
-               assert.equal( title.toString(), 'Penguins:Frobisher' );
+               assert.strictEqual( title.toString(), 'Penguins:Frobisher' );
 
                title = new mw.Title( 'antarctic_waterfowl:flightless_yet_cute.jpg' );
-               assert.equal( title.toString(), 'Penguins:Flightless_yet_cute.jpg' );
+               assert.strictEqual( title.toString(), 'Penguins:Flightless_yet_cute.jpg' );
 
                title = new mw.Title( 'Penguins:flightless_yet_cute.jpg' );
-               assert.equal( title.toString(), 'Penguins:Flightless_yet_cute.jpg' );
+               assert.strictEqual( title.toString(), 'Penguins:Flightless_yet_cute.jpg' );
        } );
 
        QUnit.test( 'Throw error on invalid title', function ( assert ) {
                mw.config.set( 'wgCaseSensitiveNamespaces', [] );
 
                title = new mw.Title( 'article' );
-               assert.equal( title.toString(), 'Article', 'Default config: No sensitive namespaces by default. First-letter becomes uppercase' );
+               assert.strictEqual( title.toString(), 'Article', 'Default config: No sensitive namespaces by default. First-letter becomes uppercase' );
 
                title = new mw.Title( 'ß' );
-               assert.equal( title.toString(), 'ß', 'Uppercasing matches PHP behaviour (ß -> ß, not SS)' );
+               assert.strictEqual( title.toString(), 'ß', 'Uppercasing matches PHP behaviour (ß -> ß, not SS)' );
 
                title = new mw.Title( 'dž (digraph)' );
-               assert.equal( title.toString(), 'Dž_(digraph)', 'Uppercasing matches PHP behaviour (dž -> Dž, not DŽ)' );
+               assert.strictEqual( title.toString(), 'Dž_(digraph)', 'Uppercasing matches PHP behaviour (dž -> Dž, not DŽ)' );
 
                // $wgCapitalLinks = false;
                mw.config.set( 'wgCaseSensitiveNamespaces', [ 0, -2, 1, 4, 5, 6, 7, 10, 11, 12, 13, 14, 15 ] );
 
                title = new mw.Title( 'article' );
-               assert.equal( title.toString(), 'article', '$wgCapitalLinks=false: Article namespace is sensitive, first-letter case stays lowercase' );
+               assert.strictEqual( title.toString(), 'article', '$wgCapitalLinks=false: Article namespace is sensitive, first-letter case stays lowercase' );
 
                title = new mw.Title( 'john', 2 );
-               assert.equal( title.toString(), 'User:John', '$wgCapitalLinks=false: User namespace is insensitive, first-letter becomes uppercase' );
+               assert.strictEqual( title.toString(), 'User:John', '$wgCapitalLinks=false: User namespace is insensitive, first-letter becomes uppercase' );
        } );
 
        QUnit.test( 'toString / toText', function ( assert ) {
                var title = new mw.Title( 'Some random page' );
 
-               assert.equal( title.toString(), title.getPrefixedDb() );
-               assert.equal( title.toText(), title.getPrefixedText() );
+               assert.strictEqual( title.toString(), title.getPrefixedDb() );
+               assert.strictEqual( title.toText(), title.getPrefixedText() );
        } );
 
        QUnit.test( 'getExtension', function ( assert ) {
                function extTest( pagename, ext, description ) {
                        var title = new mw.Title( pagename );
-                       assert.equal( title.getExtension(), ext, description || pagename );
+                       assert.strictEqual( title.getExtension(), ext, description || pagename );
                }
 
                extTest( 'MediaWiki:Vector.js', 'js' );
                } );
 
                title = new mw.Title( 'Foobar' );
-               assert.equal( title.getUrl(), '/wiki/Foobar', 'Basic functionality, getUrl uses mw.util.getUrl' );
-               assert.equal( title.getUrl( { action: 'edit' } ), '/w/index.php?title=Foobar&action=edit', 'Basic functionality, \'params\' parameter' );
+               assert.strictEqual( title.getUrl(), '/wiki/Foobar', 'Basic functionality, getUrl uses mw.util.getUrl' );
+               assert.strictEqual( title.getUrl( { action: 'edit' } ), '/w/index.php?title=Foobar&action=edit', 'Basic functionality, \'params\' parameter' );
 
                title = new mw.Title( 'John Doe', 3 );
-               assert.equal( title.getUrl(), '/wiki/User_talk:John_Doe', 'Escaping in title and namespace for urls' );
+               assert.strictEqual( title.getUrl(), '/wiki/User_talk:John_Doe', 'Escaping in title and namespace for urls' );
 
                title = new mw.Title( 'John Cena#And_His_Name_Is', 3 );
-               assert.equal( title.getUrl( { meme: true } ), '/w/index.php?title=User_talk:John_Cena&meme=true#And_His_Name_Is', 'title with fragment and query parameter' );
+               assert.strictEqual( title.getUrl( { meme: true } ), '/w/index.php?title=User_talk:John_Cena&meme=true#And_His_Name_Is', 'title with fragment and query parameter' );
        } );
 
        QUnit.test( 'newFromImg', function ( assert ) {
                                prefix = '[' + thisCase.typeOfUrl + ' URL] ';
 
                                assert.notStrictEqual( title, null, prefix + 'Parses successfully' );
-                               assert.equal( title.getNameText(), thisCase.nameText, prefix + 'Filename matches original' );
-                               assert.equal( title.getPrefixedText(), thisCase.prefixedText, prefix + 'File page title matches original' );
-                               assert.equal( title.getNamespaceId(), 6, prefix + 'Namespace ID matches File namespace' );
+                               assert.strictEqual( title.getNameText(), thisCase.nameText, prefix + 'Filename matches original' );
+                               assert.strictEqual( title.getPrefixedText(), thisCase.prefixedText, prefix + 'File page title matches original' );
+                               assert.strictEqual( title.getNamespaceId(), 6, prefix + 'Namespace ID matches File namespace' );
                        } else {
                                assert.strictEqual( title, null, thisCase.typeOfUrl + ', should not produce an mw.Title object' );
                        }
                        thisCase = cases[ i ];
 
                        title = mw.Title.newFromText( thisCase.text );
-                       assert.equal( title.getRelativeText( thisCase.relativeTo ), thisCase.expectedResult );
+                       assert.strictEqual( title.getRelativeText( thisCase.relativeTo ), thisCase.expectedResult );
                }
        } );
 
                        extension = mw.Title.normalizeExtension( thisCase.extension );
 
                        prefix = '[' + thisCase.description + '] ';
-                       assert.equal( extension, thisCase.expected, prefix + 'Extension as expected' );
+                       assert.strictEqual( extension, thisCase.expected, prefix + 'Extension as expected' );
                }
        } );
 
                                prefix = '[' + thisCase.description + '] ';
 
                                assert.notStrictEqual( title, null, prefix + 'Parses successfully' );
-                               assert.equal( title.toText(), thisCase.expected, prefix + 'Title as expected' );
+                               assert.strictEqual( title.toText(), thisCase.expected, prefix + 'Title as expected' );
                        } else {
                                assert.strictEqual( title, null, thisCase.description + ', should not produce an mw.Title object' );
                        }
                                },
                                {
                                        fileName: 'BI\u200EDI.jpg',
-                                       typeOfName: 'Name containing Unicode directional formatting characters',
+                                       typeOfName: 'Name containing BIDI overrides',
                                        nameText: 'BIDI',
                                        prefixedText: 'File:BIDI.jpg'
                                },
                                prefix = '[' + thisCase.typeOfName + '] ';
 
                                assert.notStrictEqual( title, null, prefix + 'Parses successfully' );
-                               assert.equal( title.getNameText(), thisCase.nameText, prefix + 'Filename matches original' );
-                               assert.equal( title.getPrefixedText(), thisCase.prefixedText, prefix + 'File page title matches original' );
-                               assert.equal( title.getNamespaceId(), 6, prefix + 'Namespace ID matches File namespace' );
+                               assert.strictEqual( title.getNameText(), thisCase.nameText, prefix + 'Filename matches original' );
+                               assert.strictEqual( title.getPrefixedText(), thisCase.prefixedText, prefix + 'File page title matches original' );
+                               assert.strictEqual( title.getNamespaceId(), 6, prefix + 'Namespace ID matches File namespace' );
                        } else {
                                assert.strictEqual( title, null, thisCase.typeOfName + ', should not produce an mw.Title object' );
                        }
index 918c923..eece8c0 100644 (file)
                uri = new mw.Uri( 'example.com/bar/baz', {
                        strictMode: false
                } );
-               assert.equal( uri.toString(), 'http://example.com/bar/baz', 'normalize URI without protocol or // in loose mode' );
+               assert.strictEqual( uri.toString(), 'http://example.com/bar/baz', 'normalize URI without protocol or // in loose mode' );
 
                uri = new mw.Uri( 'http://example.com/index.php?key=key&hasOwnProperty=hasOwnProperty&constructor=constructor&watch=watch' );
                assert.deepEqual(
                        host: 'www.foo.local',
                        path: '/this'
                } );
-               assert.equal( uri.toString(), 'http://www.foo.local/this', 'Basic properties' );
+               assert.strictEqual( uri.toString(), 'http://www.foo.local/this', 'Basic properties' );
 
                uri = new mw.Uri( {
                        protocol: 'http',
                        query: { hi: 'there' },
                        fragment: 'blah'
                } );
-               assert.equal( uri.toString(), 'http://www.foo.local/this?hi=there#blah', 'More complex properties' );
+               assert.strictEqual( uri.toString(), 'http://www.foo.local/this?hi=there#blah', 'More complex properties' );
 
                assert.throws(
                        function () {
                MyUri = mw.UriRelative( testuri );
 
                uri = new MyUri();
-               assert.equal( uri.toString(), testuri, 'no arguments' );
+               assert.strictEqual( uri.toString(), testuri, 'no arguments' );
 
                uri = new MyUri( undefined );
-               assert.equal( uri.toString(), testuri, 'undefined' );
+               assert.strictEqual( uri.toString(), testuri, 'undefined' );
 
                uri = new MyUri( null );
-               assert.equal( uri.toString(), testuri, 'null' );
+               assert.strictEqual( uri.toString(), testuri, 'null' );
 
                uri = new MyUri( '' );
-               assert.equal( uri.toString(), testuri, 'empty string' );
+               assert.strictEqual( uri.toString(), testuri, 'empty string' );
 
                uri = new MyUri( null, { overrideKeys: true } );
                assert.deepEqual( uri.query, { a: '2' }, 'null, with options' );
 
                uri = uriBase.clone();
                uri.fragment = 'frag';
-               assert.equal( uri.toString(), 'http://en.wiki.local/w/api.php#frag', 'add a fragment' );
+               assert.strictEqual( uri.toString(), 'http://en.wiki.local/w/api.php#frag', 'add a fragment' );
                uri.fragment = 'café';
-               assert.equal( uri.toString(), 'http://en.wiki.local/w/api.php#caf%C3%A9', 'fragment is url-encoded' );
+               assert.strictEqual( uri.toString(), 'http://en.wiki.local/w/api.php#caf%C3%A9', 'fragment is url-encoded' );
 
                uri = uriBase.clone();
                uri.host = 'fr.wiki.local';
                uri.port = '8080';
-               assert.equal( uri.toString(), 'http://fr.wiki.local:8080/w/api.php', 'change host and port' );
+               assert.strictEqual( uri.toString(), 'http://fr.wiki.local:8080/w/api.php', 'change host and port' );
 
                uri = uriBase.clone();
                uri.query.foo = 'bar';
-               assert.equal( uri.toString(), 'http://en.wiki.local/w/api.php?foo=bar', 'add query arguments' );
+               assert.strictEqual( uri.toString(), 'http://en.wiki.local/w/api.php?foo=bar', 'add query arguments' );
 
                delete uri.query.foo;
-               assert.equal( uri.toString(), 'http://en.wiki.local/w/api.php', 'delete query arguments' );
+               assert.strictEqual( uri.toString(), 'http://en.wiki.local/w/api.php', 'delete query arguments' );
 
                uri = uriBase.clone();
                uri.query.foo = 'bar';
-               assert.equal( uri.toString(), 'http://en.wiki.local/w/api.php?foo=bar', 'extend query arguments' );
+               assert.strictEqual( uri.toString(), 'http://en.wiki.local/w/api.php?foo=bar', 'extend query arguments' );
                uri.extend( {
                        foo: 'quux',
                        pif: 'paf'
                } );
-               assert.ok( uri.toString().indexOf( 'foo=quux' ) >= 0, 'extend query arguments' );
-               assert.ok( uri.toString().indexOf( 'foo=bar' ) === -1, 'extend query arguments' );
-               assert.ok( uri.toString().indexOf( 'pif=paf' ) >= 0, 'extend query arguments' );
+               assert.strictEqual( uri.toString().indexOf( 'foo=quux' ) !== -1, true, 'extend query arguments' );
+               assert.strictEqual( uri.toString().indexOf( 'foo=bar' ) !== -1, false, 'extend query arguments' );
+               assert.strictEqual( uri.toString().indexOf( 'pif=paf' ) !== -1, true, 'extend query arguments' );
        } );
 
        QUnit.test( '.getQueryString()', function ( assert ) {
                );
 
                uri = new mw.Uri( 'https://example.com/mw/index.php?title=Sandbox/7&other=Sandbox/7&foo' );
-               assert.equal(
+               assert.strictEqual(
                        uri.getQueryString(),
                        'title=Sandbox/7&other=Sandbox%2F7&foo',
                        'title parameter is escaped the wiki-way'
                clone = original.clone();
 
                assert.deepEqual( clone, original, 'clone has equivalent properties' );
-               assert.equal( original.toString(), clone.toString(), 'toString matches original' );
+               assert.strictEqual( original.toString(), clone.toString(), 'toString matches original' );
 
                assert.notStrictEqual( clone, original, 'clone is a different object when compared by reference' );
 
 
                // Verify parts and total length instead of entire string because order
                // of iteration can vary.
-               assert.ok( uri.toString().indexOf( 'm=bar' ), 'toString preserves other values' );
-               assert.ok( uri.toString().indexOf( 'n=x&n=y&n=z' ), 'toString parameter includes all values of an array query parameter' );
-               assert.equal( uri.toString().length, 'http://www.example.com/dir/?m=bar&n=x&n=y&n=z'.length, 'toString matches expected string' );
+               assert.strictEqual( uri.toString().indexOf( 'm=bar' ) !== -1, true, 'toString preserves other values' );
+               assert.strictEqual( uri.toString().indexOf( 'n=x&n=y&n=z' ) !== -1, true, 'toString parameter includes all values of an array query parameter' );
+               assert.strictEqual( uri.toString().length, 'http://www.example.com/dir/?m=bar&n=x&n=y&n=z'.length, 'toString matches expected string' );
 
                uri = new mw.Uri( 'http://www.example.com/dir/?m=foo&m=bar&n=1', {
                        overrideKeys: false
 
                // Verify parts and total length instead of entire string because order
                // of iteration can vary.
-               assert.ok( uri.toString().indexOf( 'm=foo&m=bar' ) >= 0, 'toString preserves other values' );
-               assert.ok( uri.toString().indexOf( 'n=x&n=y&n=z' ) >= 0, 'toString parameter includes all values of an array query parameter' );
-               assert.equal( uri.toString().length, 'http://www.example.com/dir/?m=foo&m=bar&n=x&n=y&n=z'.length, 'toString matches expected string' );
+               assert.strictEqual( uri.toString().indexOf( 'm=foo&m=bar' ) !== -1, true, 'toString preserves other values' );
+               assert.strictEqual( uri.toString().indexOf( 'n=x&n=y&n=z' ) !== -1, true, 'toString parameter includes all values of an array query parameter' );
+               assert.strictEqual( uri.toString().length, 'http://www.example.com/dir/?m=foo&m=bar&n=x&n=y&n=z'.length, 'toString matches expected string' );
 
                // Remove query values
                uri.query.m.splice( 0, 1 );
                delete uri.query.n;
 
-               assert.equal( uri.toString(), 'http://www.example.com/dir/?m=bar', 'deletion properties' );
+               assert.strictEqual( uri.toString(), 'http://www.example.com/dir/?m=bar', 'deletion properties' );
 
                // Remove more query values, leaving an empty array
                uri.query.m.splice( 0, 1 );
-               assert.equal( uri.toString(), 'http://www.example.com/dir/', 'empty array value is ommitted' );
+               assert.strictEqual( uri.toString(), 'http://www.example.com/dir/', 'empty array value is ommitted' );
        } );
 
        QUnit.test( 'Variable defaultUri', function ( assert ) {
                        'basic object properties'
                );
 
-               assert.equal( uri.getUserInfo(), 'auth', 'user info' );
+               assert.strictEqual( uri.getUserInfo(), 'auth', 'user info' );
 
-               assert.equal( uri.getAuthority(), 'auth@www.example.com:81', 'authority equal to auth@hostport' );
+               assert.strictEqual( uri.getAuthority(), 'auth@www.example.com:81', 'authority equal to auth@hostport' );
 
-               assert.equal( uri.getHostPort(), 'www.example.com:81', 'hostport equal to host:port' );
+               assert.strictEqual( uri.getHostPort(), 'www.example.com:81', 'hostport equal to host:port' );
 
                queryString = uri.getQueryString();
-               assert.ok( queryString.indexOf( 'q1=0' ) >= 0, 'query param with numbers' );
-               assert.ok( queryString.indexOf( 'test1' ) >= 0, 'query param with null value is included' );
-               assert.ok( queryString.indexOf( 'test1=' ) === -1, 'query param with null value does not generate equals sign' );
-               assert.ok( queryString.indexOf( 'test2=value+%28escaped%29' ) >= 0, 'query param is url escaped' );
+               assert.strictEqual( queryString.indexOf( 'q1=0' ) !== -1, true, 'query param with numbers' );
+               assert.strictEqual( queryString.indexOf( 'test1' ) !== -1, true, 'query param with null value is included' );
+               assert.strictEqual( queryString.indexOf( 'test1=' ) !== -1, false, 'query param with null value does not generate equals sign' );
+               assert.strictEqual( queryString.indexOf( 'test2=value+%28escaped%29' ) !== -1, true, 'query param is url escaped' );
 
                relativePath = uri.getRelativePath();
                assert.ok( relativePath.indexOf( uri.path ) >= 0, 'path in relative path' );
                UriRel = mw.UriRelative( 'glork://en.wiki.local/foo.php' );
 
                uri = new UriRel( '//en.wiki.local/w/api.php' );
-               assert.equal( uri.protocol, 'glork', 'create protocol-relative URLs with same protocol as document' );
+               assert.strictEqual( uri.protocol, 'glork', 'create protocol-relative URLs with same protocol as document' );
 
                uri = new UriRel( '/foo.com' );
-               assert.equal( uri.toString(), 'glork://en.wiki.local/foo.com', 'handle absolute paths by supplying protocol and host from document in loose mode' );
+               assert.strictEqual( uri.toString(), 'glork://en.wiki.local/foo.com', 'handle absolute paths by supplying protocol and host from document in loose mode' );
 
                uri = new UriRel( 'http:/foo.com' );
-               assert.equal( uri.toString(), 'http://en.wiki.local/foo.com', 'handle absolute paths by supplying host from document in loose mode' );
+               assert.strictEqual( uri.toString(), 'http://en.wiki.local/foo.com', 'handle absolute paths by supplying host from document in loose mode' );
 
                uri = new UriRel( '/foo.com', true );
-               assert.equal( uri.toString(), 'glork://en.wiki.local/foo.com', 'handle absolute paths by supplying protocol and host from document in strict mode' );
+               assert.strictEqual( uri.toString(), 'glork://en.wiki.local/foo.com', 'handle absolute paths by supplying protocol and host from document in strict mode' );
 
                uri = new UriRel( 'http:/foo.com', true );
-               assert.equal( uri.toString(), 'http://en.wiki.local/foo.com', 'handle absolute paths by supplying host from document in strict mode' );
+               assert.strictEqual( uri.toString(), 'http://en.wiki.local/foo.com', 'handle absolute paths by supplying host from document in strict mode' );
        } );
 
        QUnit.test( 'T37658', function ( assert ) {
                UriClass = mw.UriRelative( testProtocol + testServer + '/some/path/index.html' );
                uri = new UriClass( testPath );
                href = uri.toString();
-               assert.equal( href, testProtocol + testServer + testPath, 'Root-relative URL gets host & protocol supplied' );
+               assert.strictEqual( href, testProtocol + testServer + testPath, 'Root-relative URL gets host & protocol supplied' );
 
                UriClass = mw.UriRelative( testProtocol + testServer + ':' + testPort + '/some/path.php' );
                uri = new UriClass( testPath );
                href = uri.toString();
-               assert.equal( href, testProtocol + testServer + ':' + testPort + testPath, 'Root-relative URL gets host, protocol, and port supplied' );
+               assert.strictEqual( href, testProtocol + testServer + ':' + testPort + testPath, 'Root-relative URL gets host, protocol, and port supplied' );
        } );
 }( mediaWiki ) );
diff --git a/tests/qunit/suites/resources/mediawiki/mediawiki.base.test.js b/tests/qunit/suites/resources/mediawiki/mediawiki.base.test.js
new file mode 100644 (file)
index 0000000..c415953
--- /dev/null
@@ -0,0 +1,126 @@
+( function ( mw ) {
+       QUnit.module( 'mediawiki.base' );
+
+       QUnit.test( 'mw.hook - basic', function ( assert ) {
+               var q = [];
+               mw.hook( 'test.hook.basic' ).add( function () {
+                       q.push( 'basic' );
+               } );
+
+               mw.hook( 'test.hook.basic' ).fire();
+               assert.deepEqual( q, [ 'basic' ], 'Callback' );
+       } );
+
+       QUnit.test( 'mw.hook - name', function ( assert ) {
+               var q = [];
+               mw.hook( 'hasOwnProperty' ).add( function () {
+                       q.push( 'prototype' );
+               } );
+
+               mw.hook( 'hasOwnProperty' ).fire();
+               assert.deepEqual( q, [ 'prototype' ], 'Callback' );
+       } );
+
+       QUnit.test( 'mw.hook - data', function ( assert ) {
+               var q;
+
+               mw.hook( 'test.hook.data' ).add( function ( data1, data2 ) {
+                       q = [ data1, data2 ];
+               } );
+               mw.hook( 'test.hook.data' ).fire( 'example', [ 'two' ] );
+
+               assert.deepEqual( q,
+                       [
+                               'example',
+                               [ 'two' ]
+                       ],
+                       'Data containing a string and an array'
+               );
+       } );
+
+       QUnit.test( 'mw.hook - chainable', function ( assert ) {
+               var hook, add, fire, q = [];
+
+               hook = mw.hook( 'test.hook.chainable' );
+               assert.strictEqual( hook.add(), hook, 'hook.add is chainable' );
+               assert.strictEqual( hook.remove(), hook, 'hook.remove is chainable' );
+               assert.strictEqual( hook.fire(), hook, 'hook.fire is chainable' );
+
+               hook = mw.hook( 'test.hook.detach' );
+               add = hook.add;
+               fire = hook.fire;
+               add( function ( x, y ) {
+                       q.push( x, y );
+               } );
+               fire( 'x', 'y' );
+               assert.deepEqual( q, [ 'x', 'y' ], 'Contextless firing with data' );
+       } );
+
+       QUnit.test( 'mw.hook - memory before', function ( assert ) {
+               var q;
+
+               q = [];
+               mw.hook( 'test.hook.fireBefore' ).fire().add( function () {
+                       q.push( 'X' );
+               } );
+               assert.deepEqual( q, [ 'X' ], 'Remember previous firing for newly added handler' );
+
+               q = [];
+               mw.hook( 'test.hook.fireTwiceBefore' ).fire( 'Y1' ).fire( 'Y2' ).add( function ( data ) {
+                       q.push( data );
+               } );
+               assert.deepEqual( q, [ 'Y2' ], 'Remember only the most recent firing' );
+       } );
+
+       QUnit.test( 'mw.hook - memory before and after', function ( assert ) {
+               var q1 = [], q2 = [];
+               mw.hook( 'test.hook.many' )
+                       .add( function ( chr ) {
+                               q1.push( chr );
+                       } )
+                       .fire( 'x' ).fire( 'y' ).fire( 'z' )
+                       .add( function ( chr ) {
+                               q2.push( chr );
+                       } );
+
+               assert.deepEqual( q1, [ 'x', 'y', 'z' ], 'Multiple fires after callback addition' );
+               assert.deepEqual( q2, [ 'z' ], 'Last fire applied to new handler' );
+       } );
+
+       QUnit.test( 'mw.hook - data variadic', function ( assert ) {
+               var q = [];
+               function callback( chr ) {
+                       q.push( chr );
+               }
+
+               mw.hook( 'test.hook.variadic' )
+                       .add(
+                               callback,
+                               callback,
+                               function ( chr ) {
+                                       q.push( chr );
+                               },
+                               callback
+                       )
+                       .fire( 'x' )
+                       .remove(
+                               function () {
+                                       'not-added';
+                               },
+                               callback
+                       )
+                       .fire( 'y' )
+                       .remove( callback )
+                       .fire( 'z' );
+
+               assert.deepEqual(
+                       q,
+                       [ 'x', 'x', 'x', 'x', 'y', 'z' ],
+                       '"add" and "remove" support variadic arguments. ' +
+                               '"add" does not filter unique. ' +
+                               '"remove" removes all equal by reference. ' +
+                               '"remove" is silent if the function is not found'
+               );
+       } );
+
+}( mediaWiki ) );
index 4170897..17eaa7e 100644 (file)
@@ -65,7 +65,7 @@
                QUnit.test( 'Plural Test for ' + langCode, function ( assert ) {
                        var i;
                        for ( i = 0; i < tests.length; i++ ) {
-                               assert.equal(
+                               assert.strictEqual(
                                        mw.language.convertPlural( tests[ i ][ 0 ], tests[ i ][ 1 ] ),
                                        tests[ i ][ 2 ],
                                        tests[ i ][ 3 ]
index 177c358..c2abc08 100644 (file)
@@ -21,7 +21,7 @@
                var experiment = createExperiment(),
                        token = '123457890';
 
-               assert.equal(
+               assert.strictEqual(
                        getBucket( experiment, token ),
                        getBucket( experiment, token ),
                        'It returns the same bucket for the same experiment-token pair.'
@@ -33,9 +33,9 @@
                        A: 0.314159265359
                };
 
-               assert.equal(
-                       'A',
+               assert.strictEqual(
                        getBucket( experiment, token ),
+                       'A',
                        'It returns the bucket if only one is defined.'
                );
 
@@ -43,9 +43,9 @@
                experiment = createExperiment();
                experiment.enabled = false;
 
-               assert.equal(
-                       'control',
+               assert.strictEqual(
                        getBucket( experiment, token ),
+                       'control',
                        'It returns "control" if the experiment is disabled.'
                );
 
@@ -53,9 +53,9 @@
                experiment = createExperiment();
                experiment.buckets = {};
 
-               assert.equal(
-                       'control',
+               assert.strictEqual(
                        getBucket( experiment, token ),
+                       'control',
                        'It returns "control" if the experiment doesn\'t have any buckets.'
                );
        } );
index 16f8cf3..91afec3 100644 (file)
@@ -10,7 +10,7 @@
                        'throw a TypeError if argument is not a string'
                );
 
-               assert.equal(
+               assert.strictEqual(
                        mw.html.escape( '<mw awesome="awesome" value=\'test\' />' ),
                        '&lt;mw awesome=&quot;awesome&quot; value=&#039;test&#039; /&gt;',
                        'Escape special characters to html entities'
@@ -18,7 +18,7 @@
        } );
 
        QUnit.test( 'element()', function ( assert ) {
-               assert.equal(
+               assert.strictEqual(
                        mw.html.element(),
                        '<undefined/>',
                        'return valid html even without arguments'
        } );
 
        QUnit.test( 'element( tagName )', function ( assert ) {
-               assert.equal( mw.html.element( 'div' ), '<div/>', 'DIV' );
+               assert.strictEqual( mw.html.element( 'div' ), '<div/>', 'DIV' );
        } );
 
        QUnit.test( 'element( tagName, attrs )', function ( assert ) {
-               assert.equal( mw.html.element( 'div', {} ), '<div/>', 'DIV' );
+               assert.strictEqual( mw.html.element( 'div', {} ), '<div/>', 'DIV' );
 
-               assert.equal(
+               assert.strictEqual(
                        mw.html.element(
                                'div', {
                                        id: 'foobar'
 
        QUnit.test( 'element( tagName, attrs, content )', function ( assert ) {
 
-               assert.equal( mw.html.element( 'div', {}, '' ), '<div></div>', 'DIV with empty attributes and content' );
+               assert.strictEqual( mw.html.element( 'div', {}, '' ), '<div></div>', 'DIV with empty attributes and content' );
 
-               assert.equal( mw.html.element( 'p', {}, 12 ), '<p>12</p>', 'numbers as content cast to strings' );
+               assert.strictEqual( mw.html.element( 'p', {}, 12 ), '<p>12</p>', 'numbers as content cast to strings' );
 
-               assert.equal( mw.html.element( 'p', { title: 12 }, '' ), '<p title="12"></p>', 'number as attribute value' );
+               assert.strictEqual( mw.html.element( 'p', { title: 12 }, '' ), '<p title="12"></p>', 'number as attribute value' );
 
-               assert.equal(
+               assert.strictEqual(
                        mw.html.element(
                                'div',
                                {},
@@ -63,7 +63,7 @@
                        'unescaped content with mw.html.Raw'
                );
 
-               assert.equal(
+               assert.strictEqual(
                        mw.html.element(
                                'option',
                                {
@@ -75,7 +75,7 @@
                        'boolean true attribute value'
                );
 
-               assert.equal(
+               assert.strictEqual(
                        mw.html.element(
                                'option',
                                {
                        'boolean false attribute value'
                );
 
-               assert.equal(
+               assert.strictEqual(
                        mw.html.element( 'div', null, 'a' ),
                        '<div>a</div>',
                        'Skip attributes with null' );
 
-               assert.equal(
+               assert.strictEqual(
                        mw.html.element( 'a', {
                                href: 'http://mediawiki.org/w/index.php?title=RL&action=history'
                        }, 'a' ),
index 1f7a5ec..3d3eedd 100644 (file)
@@ -9,7 +9,7 @@
                );
 
                return mw.loader.using( 'test.inspect.script' ).then( function () {
-                       assert.equal(
+                       assert.strictEqual(
                                mw.inspect.getModuleSize( 'test.inspect.script' ),
                                // name, script function
                                43,
@@ -26,7 +26,7 @@
                );
 
                return mw.loader.using( 'test.inspect.both' ).then( function () {
-                       assert.equal(
+                       assert.strictEqual(
                                mw.inspect.getModuleSize( 'test.inspect.both' ),
                                // name, script function, styles object
                                64,
@@ -44,7 +44,7 @@
                );
 
                return mw.loader.using( 'test.inspect.scriptmsg' ).then( function () {
-                       assert.equal(
+                       assert.strictEqual(
                                mw.inspect.getModuleSize( 'test.inspect.scriptmsg' ),
                                // name, script function, empty styles object, messages object
                                74,
@@ -63,7 +63,7 @@
                );
 
                return mw.loader.using( 'test.inspect.all' ).then( function () {
-                       assert.equal(
+                       assert.strictEqual(
                                mw.inspect.getModuleSize( 'test.inspect.all' ),
                                // name, script function, styles object, messages object, templates object
                                126,
index 71362fd..50fd581 100644 (file)
@@ -7,8 +7,8 @@
 
        // When the expected result is the same in both modes
        function assertBothModes( assert, parserArguments, expectedResult, assertMessage ) {
-               assert.equal( formatText.apply( null, parserArguments ), expectedResult, assertMessage + ' when format is \'text\'' );
-               assert.equal( formatParse.apply( null, parserArguments ), expectedResult, assertMessage + ' when format is \'parse\'' );
+               assert.strictEqual( formatText.apply( null, parserArguments ), expectedResult, assertMessage + ' when format is \'text\'' );
+               assert.strictEqual( formatParse.apply( null, parserArguments ), expectedResult, assertMessage + ' when format is \'parse\'' );
        }
 
        QUnit.module( 'mediawiki.jqueryMsg', QUnit.newMwEnvironment( {
                                        skin: mw.config.get( 'skin' ),
                                        lang: langCode,
                                        debug: mw.config.get( 'debug' ),
-                                       modules: [
-                                               'mediawiki.language.data',
-                                               'mediawiki.language'
-                                       ].join( '|' ),
+                                       modules: 'mediawiki.language',
                                        only: 'scripts'
                                },
                                dataType: 'script',
        QUnit.test( 'Replace', function ( assert ) {
                mw.messages.set( 'simple', 'Foo $1 baz $2' );
 
-               assert.equal( formatParse( 'simple' ), 'Foo $1 baz $2', 'Replacements with no substitutes' );
-               assert.equal( formatParse( 'simple', 'bar' ), 'Foo bar baz $2', 'Replacements with less substitutes' );
-               assert.equal( formatParse( 'simple', 'bar', 'quux' ), 'Foo bar baz quux', 'Replacements with all substitutes' );
+               assert.strictEqual( formatParse( 'simple' ), 'Foo $1 baz $2', 'Replacements with no substitutes' );
+               assert.strictEqual( formatParse( 'simple', 'bar' ), 'Foo bar baz $2', 'Replacements with less substitutes' );
+               assert.strictEqual( formatParse( 'simple', 'bar', 'quux' ), 'Foo bar baz quux', 'Replacements with all substitutes' );
 
                mw.messages.set( 'plain-input', '<foo foo="foo">x$1y&lt;</foo>z' );
 
-               assert.equal(
+               assert.strictEqual(
                        formatParse( 'plain-input', 'bar' ),
                        '&lt;foo foo="foo"&gt;xbary&amp;lt;&lt;/foo&gt;z',
                        'Input is not considered html'
 
                mw.messages.set( 'plain-replace', 'Foo $1' );
 
-               assert.equal(
+               assert.strictEqual(
                        formatParse( 'plain-replace', '<bar bar="bar">&gt;</bar>' ),
                        'Foo &lt;bar bar="bar"&gt;&amp;gt;&lt;/bar&gt;',
                        'Replacement is not considered html'
 
                mw.messages.set( 'object-replace', 'Foo $1' );
 
-               assert.equal(
+               assert.strictEqual(
                        formatParse( 'object-replace', $( '<div class="bar">&gt;</div>' ) ),
                        'Foo <div class="bar">&gt;</div>',
                        'jQuery objects are preserved as raw html'
                );
 
-               assert.equal(
+               assert.strictEqual(
                        formatParse( 'object-replace', $( '<div class="bar">&gt;</div>' ).get( 0 ) ),
                        'Foo <div class="bar">&gt;</div>',
                        'HTMLElement objects are preserved as raw html'
                );
 
-               assert.equal(
+               assert.strictEqual(
                        formatParse( 'object-replace', $( '<div class="bar">&gt;</div>' ).toArray() ),
                        'Foo <div class="bar">&gt;</div>',
                        'HTMLElement[] arrays are preserved as raw html'
                );
 
-               assert.equal(
+               assert.strictEqual(
                        formatParse( 'external-link-replace', 'http://example.org/?x=y&z' ),
                        'Foo <a href="http://example.org/?x=y&amp;z">bar</a>',
                        'Href is not double-escaped in wikilink function'
                );
-               assert.equal(
+               assert.strictEqual(
                        formatParse( 'external-link-plural', 1, 'http://example.org' ),
                        'Foo is <a href="http://example.org">one</a> things.',
                        'Link is expanded inside plural and is not escaped html'
                );
-               assert.equal(
+               assert.strictEqual(
                        formatParse( 'external-link-plural', 2, 'http://example.org' ),
                        'Foo <a href="http://example.org">two</a> things.',
                        'Link is expanded inside an explicit plural form and is not escaped html'
                );
-               assert.equal(
+               assert.strictEqual(
                        formatParse( 'external-link-plural', 3 ),
                        'Foo three things.',
                        'A simple explicit plural form co-existing with complex explicit plural forms'
                );
-               assert.equal(
+               assert.strictEqual(
                        formatParse( 'external-link-plural', 4, 'http://example.org' ),
                        'Foo a=b things.',
                        'Only first equal sign is used as delimiter for explicit plural form. Repeated equal signs does not create issue'
                );
-               assert.equal(
+               assert.strictEqual(
                        formatParse( 'external-link-plural', 6, 'http://example.org' ),
                        'Foo are <a href="http://example.org">some</a> things.',
                        'Plural fallback to the "other" plural form'
                );
-               assert.equal(
+               assert.strictEqual(
                        formatParse( 'plural-only-explicit-forms', 2 ),
                        'It is a double room.',
                        'Plural with explicit forms alone.'
        } );
 
        QUnit.test( 'Plural', function ( assert ) {
-               assert.equal( formatParse( 'plural-msg', 0 ), 'Found 0 items', 'Plural test for english with zero as count' );
-               assert.equal( formatParse( 'plural-msg', 1 ), 'Found 1 item', 'Singular test for english' );
-               assert.equal( formatParse( 'plural-msg', 2 ), 'Found 2 items', 'Plural test for english' );
-               assert.equal( formatParse( 'plural-msg-explicit-forms-nested', 6 ), 'Found 6 results', 'Plural message with explicit plural forms' );
-               assert.equal( formatParse( 'plural-msg-explicit-forms-nested', 0 ), 'Found no results in Wiki', 'Plural message with explicit plural forms, with nested {{SITENAME}}' );
-               assert.equal( formatParse( 'plural-msg-explicit-forms-nested', 1 ), 'Found 1 result', 'Plural message with explicit plural forms with placeholder nested' );
-               assert.equal( formatParse( 'plural-empty-explicit-form', 0 ), 'There is me.' );
-               assert.equal( formatParse( 'plural-empty-explicit-form', 1 ), 'There is me and other people.' );
-               assert.equal( formatParse( 'plural-empty-explicit-form', 2 ), 'There is me and other people.' );
+               assert.strictEqual( formatParse( 'plural-msg', 0 ), 'Found 0 items', 'Plural test for english with zero as count' );
+               assert.strictEqual( formatParse( 'plural-msg', 1 ), 'Found 1 item', 'Singular test for english' );
+               assert.strictEqual( formatParse( 'plural-msg', 2 ), 'Found 2 items', 'Plural test for english' );
+               assert.strictEqual( formatParse( 'plural-msg-explicit-forms-nested', 6 ), 'Found 6 results', 'Plural message with explicit plural forms' );
+               assert.strictEqual( formatParse( 'plural-msg-explicit-forms-nested', 0 ), 'Found no results in Wiki', 'Plural message with explicit plural forms, with nested {{SITENAME}}' );
+               assert.strictEqual( formatParse( 'plural-msg-explicit-forms-nested', 1 ), 'Found 1 result', 'Plural message with explicit plural forms with placeholder nested' );
+               assert.strictEqual( formatParse( 'plural-empty-explicit-form', 0 ), 'There is me.' );
+               assert.strictEqual( formatParse( 'plural-empty-explicit-form', 1 ), 'There is me and other people.' );
+               assert.strictEqual( formatParse( 'plural-empty-explicit-form', 2 ), 'There is me and other people.' );
        } );
 
        QUnit.test( 'Gender', function ( assert ) {
                // TODO: These tests should be for mw.msg once mw.msg integrated with mw.jqueryMsg
                // TODO: English may not be the best language for these tests. Use a language like Arabic or Russian
                mw.user.options.set( 'gender', 'male' );
-               assert.equal(
+               assert.strictEqual(
                        formatParse( 'gender-msg', 'Bob', 'male' ),
                        'Bob: blue',
                        'Masculine from string "male"'
                );
-               assert.equal(
+               assert.strictEqual(
                        formatParse( 'gender-msg', 'Bob', mw.user ),
                        'Bob: blue',
                        'Masculine from mw.user object'
                );
-               assert.equal(
+               assert.strictEqual(
                        formatParse( 'gender-msg-currentuser' ),
                        'blue',
                        'Masculine for current user'
                );
 
                mw.user.options.set( 'gender', 'female' );
-               assert.equal(
+               assert.strictEqual(
                        formatParse( 'gender-msg', 'Alice', 'female' ),
                        'Alice: pink',
                        'Feminine from string "female"' );
-               assert.equal(
+               assert.strictEqual(
                        formatParse( 'gender-msg', 'Alice', mw.user ),
                        'Alice: pink',
                        'Feminine from mw.user object'
                );
-               assert.equal(
+               assert.strictEqual(
                        formatParse( 'gender-msg-currentuser' ),
                        'pink',
                        'Feminine for current user'
                );
 
                mw.user.options.set( 'gender', 'unknown' );
-               assert.equal(
+               assert.strictEqual(
                        formatParse( 'gender-msg', 'Foo', mw.user ),
                        'Foo: green',
                        'Neutral from mw.user object' );
-               assert.equal(
+               assert.strictEqual(
                        formatParse( 'gender-msg', 'User' ),
                        'User: green',
                        'Neutral when no parameter given' );
-               assert.equal(
+               assert.strictEqual(
                        formatParse( 'gender-msg', 'User', 'unknown' ),
                        'User: green',
                        'Neutral from string "unknown"'
                );
-               assert.equal(
+               assert.strictEqual(
                        formatParse( 'gender-msg-currentuser' ),
                        'green',
                        'Neutral for current user'
 
                mw.messages.set( 'gender-msg-one-form', '{{GENDER:$1|User}}: $2 {{PLURAL:$2|edit|edits}}' );
 
-               assert.equal(
+               assert.strictEqual(
                        formatParse( 'gender-msg-one-form', 'male', 10 ),
                        'User: 10 edits',
                        'Gender neutral and plural form'
                );
-               assert.equal(
+               assert.strictEqual(
                        formatParse( 'gender-msg-one-form', 'female', 1 ),
                        'User: 1 edit',
                        'Gender neutral and singular form'
                );
 
                mw.messages.set( 'gender-msg-lowercase', '{{gender:$1|he|she}} is awesome' );
-               assert.equal(
+               assert.strictEqual(
                        formatParse( 'gender-msg-lowercase', 'male' ),
                        'he is awesome',
                        'Gender masculine'
                );
-               assert.equal(
+               assert.strictEqual(
                        formatParse( 'gender-msg-lowercase', 'female' ),
                        'she is awesome',
                        'Gender feminine'
                );
 
                mw.messages.set( 'gender-msg-wrong', '{{gender}} test' );
-               assert.equal(
+               assert.strictEqual(
                        formatParse( 'gender-msg-wrong', 'female' ),
                        ' test',
                        'Invalid syntax should result in {{gender}} simply being stripped away'
 
        QUnit.test( 'Case changing', function ( assert ) {
                mw.messages.set( 'to-lowercase', '{{lc:thIS hAS MEsSed uP CapItaliZatiON}}' );
-               assert.equal( formatParse( 'to-lowercase' ), 'this has messed up capitalization', 'To lowercase' );
+               assert.strictEqual( formatParse( 'to-lowercase' ), 'this has messed up capitalization', 'To lowercase' );
 
                mw.messages.set( 'to-caps', '{{uc:thIS hAS MEsSed uP CapItaliZatiON}}' );
-               assert.equal( formatParse( 'to-caps' ), 'THIS HAS MESSED UP CAPITALIZATION', 'To caps' );
+               assert.strictEqual( formatParse( 'to-caps' ), 'THIS HAS MESSED UP CAPITALIZATION', 'To caps' );
 
                mw.messages.set( 'uc-to-lcfirst', '{{lcfirst:THis hAS MEsSed uP CapItaliZatiON}}' );
                mw.messages.set( 'lc-to-lcfirst', '{{lcfirst:thIS hAS MEsSed uP CapItaliZatiON}}' );
-               assert.equal( formatParse( 'uc-to-lcfirst' ), 'tHis hAS MEsSed uP CapItaliZatiON', 'Lcfirst caps' );
-               assert.equal( formatParse( 'lc-to-lcfirst' ), 'thIS hAS MEsSed uP CapItaliZatiON', 'Lcfirst lowercase' );
+               assert.strictEqual( formatParse( 'uc-to-lcfirst' ), 'tHis hAS MEsSed uP CapItaliZatiON', 'Lcfirst caps' );
+               assert.strictEqual( formatParse( 'lc-to-lcfirst' ), 'thIS hAS MEsSed uP CapItaliZatiON', 'Lcfirst lowercase' );
 
                mw.messages.set( 'uc-to-ucfirst', '{{ucfirst:THis hAS MEsSed uP CapItaliZatiON}}' );
                mw.messages.set( 'lc-to-ucfirst', '{{ucfirst:thIS hAS MEsSed uP CapItaliZatiON}}' );
-               assert.equal( formatParse( 'uc-to-ucfirst' ), 'THis hAS MEsSed uP CapItaliZatiON', 'Ucfirst caps' );
-               assert.equal( formatParse( 'lc-to-ucfirst' ), 'ThIS hAS MEsSed uP CapItaliZatiON', 'Ucfirst lowercase' );
+               assert.strictEqual( formatParse( 'uc-to-ucfirst' ), 'THis hAS MEsSed uP CapItaliZatiON', 'Ucfirst caps' );
+               assert.strictEqual( formatParse( 'lc-to-ucfirst' ), 'ThIS hAS MEsSed uP CapItaliZatiON', 'Ucfirst lowercase' );
 
                mw.messages.set( 'mixed-to-sentence', '{{ucfirst:{{lc:thIS hAS MEsSed uP CapItaliZatiON}}}}' );
-               assert.equal( formatParse( 'mixed-to-sentence' ), 'This has messed up capitalization', 'To sentence case' );
+               assert.strictEqual( formatParse( 'mixed-to-sentence' ), 'This has messed up capitalization', 'To sentence case' );
                mw.messages.set( 'all-caps-except-first', '{{lcfirst:{{uc:thIS hAS MEsSed uP CapItaliZatiON}}}}' );
-               assert.equal( formatParse( 'all-caps-except-first' ), 'tHIS HAS MESSED UP CAPITALIZATION', 'To opposite sentence case' );
+               assert.strictEqual( formatParse( 'all-caps-except-first' ), 'tHIS HAS MESSED UP CAPITALIZATION', 'To opposite sentence case' );
        } );
 
        QUnit.test( 'Grammar', function ( assert ) {
-               assert.equal( formatParse( 'grammar-msg' ), 'Przeszukaj Wiki', 'Grammar Test with sitename' );
+               assert.strictEqual( formatParse( 'grammar-msg' ), 'Przeszukaj Wiki', 'Grammar Test with sitename' );
 
                mw.messages.set( 'grammar-msg-wrong-syntax', 'Przeszukaj {{GRAMMAR:grammar_case_xyz}}' );
-               assert.equal( formatParse( 'grammar-msg-wrong-syntax' ), 'Przeszukaj ', 'Grammar Test with wrong grammar template syntax' );
+               assert.strictEqual( formatParse( 'grammar-msg-wrong-syntax' ), 'Przeszukaj ', 'Grammar Test with wrong grammar template syntax' );
        } );
 
        QUnit.test( 'Match PHP parser', function ( assert ) {
                                                var parser;
                                                mw.config.set( 'wgUserLanguage', test.lang );
                                                parser = new mw.jqueryMsg.Parser( { language: langClass } );
-                                               assert.equal(
+                                               assert.strictEqual(
                                                        parser.parse( test.key, test.args ).html(),
                                                        test.result,
                                                        test.name
                mw.messages.set( 'reverse-pipe-trick', '[[|Tampa, Florida]]' );
                mw.messages.set( 'empty-link', '[[]]' );
                this.suppressWarnings();
-               assert.equal(
+               assert.strictEqual(
                        formatParse( 'pipe-trick' ),
                        '[[Tampa, Florida|]]',
                        'Pipe trick should not be parsed.'
                );
-               assert.equal(
+               assert.strictEqual(
                        formatParse( 'reverse-pipe-trick' ),
                        '[[|Tampa, Florida]]',
                        'Reverse pipe trick should not be parsed.'
                );
-               assert.equal(
+               assert.strictEqual(
                        formatParse( 'empty-link' ),
                        '[[]]',
                        'Empty link should not be parsed.'
                // Test non-{{ wikitext, where behavior differs
 
                // Wikilink
-               assert.equal(
+               assert.strictEqual(
                        formatText( 'jquerymsg-test-statistics-users' ),
                        mw.messages.get( 'jquerymsg-test-statistics-users' ),
                        'Internal link message unchanged when format is \'text\''
                );
 
                // External link
-               assert.equal(
+               assert.strictEqual(
                        formatText( 'jquerymsg-test-version-entrypoints-index-php' ),
                        mw.messages.get( 'jquerymsg-test-version-entrypoints-index-php' ),
                        'External link message unchanged when format is \'text\''
                );
 
                // External link with parameter
-               assert.equal(
+               assert.strictEqual(
                        formatText( 'external-link-replace', 'http://example.com' ),
                        'Foo [http://example.com bar]',
                        'External link message only substitutes parameter when format is \'text\''
                        'Link with nested message'
                );
 
-               assert.equal(
+               assert.strictEqual(
                        formatParse( 'see-portal-url' ),
                        'Project:Community portal is an important community page.',
                        'Nested message'
 
                mw.messages.set( 'uses-missing-int', '{{int:doesnt-exist}}' );
 
-               assert.equal(
+               assert.strictEqual(
                        formatParse( 'uses-missing-int' ),
                        '⧼doesnt-exist⧽',
                        'int: where nested message does not exist'
 
        QUnit.test( 'Ns', function ( assert ) {
                mw.messages.set( 'ns-template-talk', '{{ns:Template talk}}' );
-               assert.equal(
+               assert.strictEqual(
                        formatParse( 'ns-template-talk' ),
                        'Dyskusja szablonu',
                        'ns: returns localised namespace when used with a canonical namespace name'
                );
 
                mw.messages.set( 'ns-10', '{{ns:10}}' );
-               assert.equal(
+               assert.strictEqual(
                        formatParse( 'ns-10' ),
                        'Szablon',
                        'ns: returns localised namespace when used with a namespace number'
                );
 
                mw.messages.set( 'ns-unknown', '{{ns:doesnt-exist}}' );
-               assert.equal(
+               assert.strictEqual(
                        formatParse( 'ns-unknown' ),
                        '',
                        'ns: returns empty string for unknown namespace name'
                );
 
                mw.messages.set( 'ns-in-a-link', '[[{{ns:template}}:Foo]]' );
-               assert.equal(
+               assert.strictEqual(
                        formatParse( 'ns-in-a-link' ),
                        '<a title="Szablon:Foo" href="/wiki/Szablon:Foo">Szablon:Foo</a>',
                        'ns: works when used inside a wikilink'
                {
                        lang: 'ar',
                        number: '٩٨٧٦٥٤٣٢١٫٦٥٤٣٢١',
-                       result: 987654321,
+                       result: '987654321',
                        integer: true,
                        description: 'formatnum test for Arabic, with decimal separator, reverse'
                },
                {
                        lang: 'ar',
                        number: '-١٢٫٨٩',
-                       result: -12,
+                       result: '-12',
                        integer: true,
                        description: 'formatnum test for Arabic, negative number, reverse'
                },
                                getMwLanguage( test.lang )
                                        .then( function ( langClass ) {
                                                var parser;
+                                               // The unit tests perform hot-reloading of mw.language (in hacky way).
+                                               // For the languages/*.js script files to work, they need to statically
+                                               // access mw.language.getData() for the "current" language.
+                                               mw.language = langClass;
                                                mw.config.set( 'wgUserLanguage', test.lang );
                                                parser = new mw.jqueryMsg.Parser( { language: langClass } );
-                                               assert.equal(
+                                               assert.strictEqual(
                                                        parser.parse( test.integer ? 'formatnum-msg-int' : 'formatnum-msg',
                                                                [ test.number ] ).html(),
                                                        test.result,
                        'Italics with link inside in parse mode'
                );
 
-               assert.equal(
+               assert.strictEqual(
                        formatText( 'jquerymsg-italics-with-link' ),
                        mw.messages.get( 'jquerymsg-italics-with-link' ),
                        'Italics with link unchanged in text mode'
                        'Tag outside whitelist escaped in parse mode'
                );
 
-               assert.equal(
+               assert.strictEqual(
                        formatText( 'jquerymsg-script-msg' ),
                        mw.messages.get( 'jquerymsg-script-msg' ),
                        'Tag outside whitelist unchanged in text mode'
 
                // Intentionally not using htmlEqual for the quote tests
                mw.messages.set( 'jquerymsg-double-quotes-preserved', '<i id="double">Double</i>' );
-               assert.equal(
+               assert.strictEqual(
                        formatParse( 'jquerymsg-double-quotes-preserved' ),
                        mw.messages.get( 'jquerymsg-double-quotes-preserved' ),
                        'Attributes with double quotes are preserved as such'
                );
 
                mw.messages.set( 'jquerymsg-single-quotes-normalized-to-double', '<i id=\'single\'>Single</i>' );
-               assert.equal(
+               assert.strictEqual(
                        formatParse( 'jquerymsg-single-quotes-normalized-to-double' ),
                        '<i id="single">Single</i>',
                        'Attributes with single quotes are normalized to double'
 
        QUnit.test( 'Nowiki', function ( assert ) {
                mw.messages.set( 'jquerymsg-nowiki-link', 'Foo <nowiki>[[bar]]</nowiki> baz.' );
-               assert.equal(
+               assert.strictEqual(
                        formatParse( 'jquerymsg-nowiki-link' ),
                        'Foo [[bar]] baz.',
                        'Link inside nowiki is not parsed'
                );
 
                mw.messages.set( 'jquerymsg-nowiki-htmltag', 'Foo <nowiki><b>bar</b></nowiki> baz.' );
-               assert.equal(
+               assert.strictEqual(
                        formatParse( 'jquerymsg-nowiki-htmltag' ),
                        'Foo &lt;b&gt;bar&lt;/b&gt; baz.',
                        'HTML inside nowiki is not parsed and escaped'
                );
 
                mw.messages.set( 'jquerymsg-nowiki-template', 'Foo <nowiki>{{bar}}</nowiki> baz.' );
-               assert.equal(
+               assert.strictEqual(
                        formatParse( 'jquerymsg-nowiki-template' ),
                        'Foo {{bar}} baz.',
                        'Template inside nowiki is not parsed and does not cause a parse error'
                this.suppressWarnings();
                logSpy = this.sandbox.spy( mw.log, 'warn' );
 
-               assert.equal(
+               assert.strictEqual(
                        formatParse( 'invalid-wikitext' ),
                        '&lt;b&gt;{{FAIL}}&lt;/b&gt;',
                        'Invalid wikitext: \'parse\' format'
                );
 
-               assert.equal(
+               assert.strictEqual(
                        formatText( 'invalid-wikitext' ),
                        '<b>{{FAIL}}</b>',
                        'Invalid wikitext: \'text\' format'
                );
 
-               assert.equal( logSpy.callCount, 2, 'mw.log.warn calls' );
+               assert.strictEqual( logSpy.callCount, 2, 'mw.log.warn calls' );
        } );
 
        QUnit.test( 'Integration', function ( assert ) {
                expected = '<b><a title="Bold" href="/wiki/Bold">Bold</a>!</b>';
                mw.messages.set( 'integration-test', '<b>[[Bold]]!</b>' );
 
-               assert.equal(
+               assert.strictEqual(
                        mw.message( 'integration-test' ).parse(),
                        expected,
                        'mw.message().parse() works correctly'
                );
 
-               assert.equal(
+               assert.strictEqual(
                        $( '<span>' ).msg( 'integration-test' ).html(),
                        expected,
                        'jQuery plugin $.fn.msg() works correctly'
                        $( '<a>' ).attr( 'href', 'http://example.com/' )
                );
                msg.parse(); // Not a no-op
-               assert.equal(
+               assert.strictEqual(
                        msg.parse(),
                        '<a href="http://example.com/">Link</a>',
                        'Calling .parse() multiple times does not duplicate link contents'
index b0b2e7a..54d4285 100644 (file)
@@ -20,7 +20,7 @@
        // Not that we need this. ;)
        // This fails on IE 6-8
        // Works on IE 9, Firefox 6, Chrome 14
-       QUnit.test( 'Keyword workaround: "if" as variable name using Unicode escapes', function ( assert ) {
+       ...( 'Keyword workaround: "if" as variable name using Unicode escapes', function ( assert ) {
                var orig = "another token";
                \u0069\u0066 = orig;
                assert.deepEqual( \u0069\u0066, orig, '\\u0069\\u0066' );
@@ -31,7 +31,7 @@
        // Not that we need this. ;)
        // This fails on IE 6-9
        // Works on Firefox 6, Chrome 14
-       QUnit.test( 'Keyword workaround: "if" as member variable name using Unicode escapes', function ( assert ) {
+       ...( 'Keyword workaround: "if" as member variable name using Unicode escapes', function ( assert ) {
                var orig = "another token";
                var foo = {};
                foo.\u0069\u0066 = orig;
                        expected = repeat( '\n', n ) + 'some text';
 
                        $textarea = $( '<textarea>\n' + expected + '</textarea>' );
-                       assert.equal( $textarea.val(), expected, 'Expecting ' + n + ' newlines (HTML contained ' + ( n + 1 ) + ')' );
+                       assert.strictEqual( $textarea.val(), expected, 'Expecting ' + n + ' newlines (HTML contained ' + ( n + 1 ) + ')' );
 
                        $textarea = $( '<textarea>' ).val( expected );
-                       assert.equal( $textarea.val(), expected, 'Expecting ' + n + ' newlines (from DOM set with ' + n + ')' );
+                       assert.strictEqual( $textarea.val(), expected, 'Expecting ' + n + ' newlines (from DOM set with ' + n + ')' );
                }
        } );
 }( jQuery ) );
index e4db771..9ea3c11 100644 (file)
 
        QUnit.test( 'mw.language getData and setData', function ( assert ) {
                mw.language.setData( 'en', 'testkey', 'testvalue' );
-               assert.equal( mw.language.getData( 'en', 'testkey' ), 'testvalue', 'Getter setter test for mw.language' );
-               assert.equal( mw.language.getData( 'en', 'invalidkey' ), undefined, 'Getter setter test for mw.language with invalid key' );
+               assert.strictEqual( mw.language.getData( 'en', 'testkey' ), 'testvalue', 'Getter setter test for mw.language' );
+               assert.strictEqual( mw.language.getData( 'en', 'invalidkey' ), null, 'Getter setter test for mw.language with invalid key' );
+               assert.strictEqual( mw.language.getData( 'xx', 'invalidLang' ), undefined, 'Getter setter test for mw.language with invalid lang' );
                mw.language.setData( 'en-us', 'testkey', 'testvalue' );
-               assert.equal( mw.language.getData( 'en-US', 'testkey' ), 'testvalue', 'Case insensitive test for mw.language' );
+               assert.strictEqual( mw.language.getData( 'en-US', 'testkey' ), 'testvalue', 'Case insensitive test for mw.language' );
        } );
 
        QUnit.test( 'mw.language.commafy test', function ( assert ) {
 
                mw.config.set( 'wgUserLanguage', 'en' );
                // Number grouping patterns are as per http://cldr.unicode.org/translation/number-patterns
-               assert.equal( mw.language.commafy( 1234.567, '###0.#####' ), '1234.567', 'Pattern with no digit grouping separator defined' );
-               assert.equal( mw.language.commafy( 123456789.567, '###0.#####' ), '123456789.567', 'Pattern with no digit grouping separator defined, bigger decimal part' );
-               assert.equal( mw.language.commafy( 0.567, '###0.#####' ), '0.567', 'Decimal part 0' );
-               assert.equal( mw.language.commafy( '.567', '###0.#####' ), '0.567', 'Decimal part missing. replace with zero' );
-               assert.equal( mw.language.commafy( 1234, '##,#0.#####' ), '12,34', 'Pattern with no fractional part' );
-               assert.equal( mw.language.commafy( -1234.567, '###0.#####' ), '-1234.567', 'Negative number' );
-               assert.equal( mw.language.commafy( -1234.567, '#,###.00' ), '-1,234.56', 'Fractional part bigger than pattern.' );
-               assert.equal( mw.language.commafy( 123456789.567, '###,##0.00' ), '123,456,789.56', 'Decimal part as group of 3' );
-               assert.equal( mw.language.commafy( 123456789.567, '###,###,#0.00' ), '1,234,567,89.56', 'Decimal part as group of 3 and last one 2' );
+               assert.strictEqual( mw.language.commafy( 1234.567, '###0.#####' ), '1234.567', 'Pattern with no digit grouping separator defined' );
+               assert.strictEqual( mw.language.commafy( 123456789.567, '###0.#####' ), '123456789.567', 'Pattern with no digit grouping separator defined, bigger decimal part' );
+               assert.strictEqual( mw.language.commafy( 0.567, '###0.#####' ), '0.567', 'Decimal part 0' );
+               assert.strictEqual( mw.language.commafy( '.567', '###0.#####' ), '0.567', 'Decimal part missing. replace with zero' );
+               assert.strictEqual( mw.language.commafy( 1234, '##,#0.#####' ), '12,34', 'Pattern with no fractional part' );
+               assert.strictEqual( mw.language.commafy( -1234.567, '###0.#####' ), '-1234.567', 'Negative number' );
+               assert.strictEqual( mw.language.commafy( -1234.567, '#,###.00' ), '-1,234.56', 'Fractional part bigger than pattern.' );
+               assert.strictEqual( mw.language.commafy( 123456789.567, '###,##0.00' ), '123,456,789.56', 'Decimal part as group of 3' );
+               assert.strictEqual( mw.language.commafy( 123456789.567, '###,###,#0.00' ), '1,234,567,89.56', 'Decimal part as group of 3 and last one 2' );
        } );
 
        QUnit.test( 'mw.language.convertNumber', function ( assert ) {
                mw.config.set( 'wgUserLanguage', 'en' );
                mw.config.set( 'wgTranslateNumerals', true );
 
-               assert.equal( mw.language.convertNumber( 180 ), '180', 'formatting 3-digit' );
-               assert.equal( mw.language.convertNumber( 1800 ), '1.800', 'formatting 4-digit' );
-               assert.equal( mw.language.convertNumber( 18000 ), '18.000', 'formatting 5-digit' );
+               assert.strictEqual( mw.language.convertNumber( 180 ), '180', 'formatting 3-digit' );
+               assert.strictEqual( mw.language.convertNumber( 1800 ), '1.800', 'formatting 4-digit' );
+               assert.strictEqual( mw.language.convertNumber( 18000 ), '18.000', 'formatting 5-digit' );
 
-               assert.equal( mw.language.convertNumber( '1.800', true ), '1800', 'unformatting' );
+               assert.strictEqual( mw.language.convertNumber( '1.800', true ), 1800, 'unformatting' );
 
                mw.language.setData( 'en', 'minimumGroupingDigits', 2 );
-               assert.equal( mw.language.convertNumber( 180 ), '180', 'formatting 3-digit with minimumGroupingDigits=2' );
-               assert.equal( mw.language.convertNumber( 1800 ), '1800', 'formatting 4-digit with minimumGroupingDigits=2' );
-               assert.equal( mw.language.convertNumber( 18000 ), '18.000', 'formatting 5-digit with minimumGroupingDigits=2' );
+               assert.strictEqual( mw.language.convertNumber( 180 ), '180', 'formatting 3-digit with minimumGroupingDigits=2' );
+               assert.strictEqual( mw.language.convertNumber( 1800 ), '1800', 'formatting 4-digit with minimumGroupingDigits=2' );
+               assert.strictEqual( mw.language.convertNumber( 18000 ), '18.000', 'formatting 5-digit with minimumGroupingDigits=2' );
        } );
 
        QUnit.test( 'mw.language.convertNumber - digitTransformTable', function ( assert ) {
                        2: '२'
                } );
 
-               assert.equal( mw.language.convertNumber( 1200 ), '१.२००', 'format' );
-               assert.equal( mw.language.convertNumber( '१.२००', true ), '1200', 'unformat from digit transform' );
-               assert.equal( mw.language.convertNumber( '1.200', true ), '1200', 'unformat plain' );
+               assert.strictEqual( mw.language.convertNumber( 1200 ), '१.२००', 'format' );
+               assert.strictEqual( mw.language.convertNumber( '१.२००', true ), 1200, 'unformat from digit transform' );
+               assert.strictEqual( mw.language.convertNumber( '1.200', true ), 1200, 'unformat plain' );
 
                mw.config.set( 'wgTranslateNumerals', false );
 
-               assert.equal( mw.language.convertNumber( 1200 ), '1.200', 'format (digit transform disabled)' );
-               assert.equal( mw.language.convertNumber( '१.२००', true ), '1200', 'unformat from digit transform (when disabled)' );
-               assert.equal( mw.language.convertNumber( '1.200', true ), '1200', 'unformat plain (digit transform disabled)' );
+               assert.strictEqual( mw.language.convertNumber( 1200 ), '1.200', 'format (digit transform disabled)' );
+               assert.strictEqual( mw.language.convertNumber( '१.२००', true ), 1200, 'unformat from digit transform (when disabled)' );
+               assert.strictEqual( mw.language.convertNumber( '1.200', true ), 1200, 'unformat plain (digit transform disabled)' );
        } );
 
        function grammarTest( langCode, test ) {
@@ -96,7 +97,7 @@
                QUnit.test( 'Grammar test for lang=' + langCode, function ( assert ) {
                        var i;
                        for ( i = 0; i < test.length; i++ ) {
-                               assert.equal(
+                               assert.strictEqual(
                                        mw.language.convertGrammar( test[ i ].word, test[ i ].grammarForm ),
                                        test[ i ].expected,
                                        test[ i ].description
        } );
 
        QUnit.test( 'List to text test', function ( assert ) {
-               assert.equal( mw.language.listToText( [] ), '', 'Blank list' );
-               assert.equal( mw.language.listToText( [ 'a' ] ), 'a', 'Single item' );
-               assert.equal( mw.language.listToText( [ 'a', 'b' ] ), 'a and b', 'Two items' );
-               assert.equal( mw.language.listToText( [ 'a', 'b', 'c' ] ), 'a, b and c', 'More than two items' );
+               assert.strictEqual( mw.language.listToText( [] ), '', 'Blank list' );
+               assert.strictEqual( mw.language.listToText( [ 'a' ] ), 'a', 'Single item' );
+               assert.strictEqual( mw.language.listToText( [ 'a', 'b' ] ), 'a and b', 'Two items' );
+               assert.strictEqual( mw.language.listToText( [ 'a', 'b', 'c' ] ), 'a, b and c', 'More than two items' );
        } );
 
        bcp47Tests = [
                bcp47Tests.forEach( function ( data ) {
                        var input = data[ 0 ],
                                expected = data[ 1 ];
-                       assert.equal( mw.language.bcp47( input ), expected );
+                       assert.strictEqual( mw.language.bcp47( input ), expected );
                } );
        } );
 }( mediaWiki, jQuery ) );
index 42bc0a7..de593d5 100644 (file)
@@ -28,7 +28,7 @@
        );
 
        /**
-        * The sync style load test (for @import). This is, in a way, also an open bug for
+        * The sync style load test, for @import. This is, in a way, also an open bug for
         * ResourceLoader ("execute js after styles are loaded"), but browsers don't offer a
         * way to get a callback from when a stylesheet is loaded (that is, including any
         * `@import` rules inside). To work around this, we'll have a little time loop to check
@@ -49,6 +49,7 @@
                        $element.css( 'height' );
                        // eslint-disable-next-line no-unused-expressions
                        el.innerHTML;
+                       // eslint-disable-next-line no-self-assign
                        el.className = el.className;
                        // eslint-disable-next-line no-unused-expressions
                        document.documentElement.clientHeight;
@@ -60,7 +61,7 @@
                        var styleTestSince = new Date().getTime() - styleTestStart;
                        // If it is passing or if we timed out, run the real test and stop the loop
                        if ( isCssImportApplied() || styleTestSince > styleTestTimeout ) {
-                               assert.equal( $element.css( prop ), val,
+                               assert.strictEqual( $element.css( prop ), val,
                                        'style "' + prop + ': ' + val + '" from url is applied (after ' + styleTestSince + 'ms)'
                                );
 
                mw.loader.implement(
                        'test.implement.a',
                        function () {
-                               assert.equal(
+                               assert.strictEqual(
                                        $element.css( 'float' ),
                                        'right',
                                        'style is applied'
                mw.loader.implement(
                        'test.implement.c',
                        function () {
-                               assert.equal(
+                               assert.strictEqual(
                                        $element.css( 'float' ),
                                        'right',
                                        'style is applied'
                mw.loader.implement(
                        'test.implement.order',
                        function () {
-                               assert.equal( mw.loader.getState( 'test.implement.order' ), 'executing', 'state during script execution' );
-                               assert.equal( mw.msg( 'test-foobar' ), 'Hello Foobar, $1!', 'messages load before script execution' );
+                               assert.strictEqual( mw.loader.getState( 'test.implement.order' ), 'executing', 'state during script execution' );
+                               assert.strictEqual( mw.msg( 'test-foobar' ), 'Hello Foobar, $1!', 'messages load before script execution' );
                        },
                        {},
                        {
                );
 
                return mw.loader.using( 'test.implement.order' ).then( function () {
-                       assert.equal( mw.loader.getState( 'test.implement.order' ), 'ready', 'final success state' );
+                       assert.strictEqual( mw.loader.getState( 'test.implement.order' ), 'ready', 'final success state' );
                } );
        } );
 
                                $element = $( '<div class="mw-test-implement-import">Foo bar</div>' ).appendTo( '#qunit-fixture' );
 
                                assertStyleAsync( assert, $element, 'float', 'right', function () {
-                                       assert.equal( $element.css( 'text-align' ), 'center',
+                                       assert.strictEqual( $element.css( 'text-align' ), 'center',
                                                'CSS styles after the @import rule are working'
                                        );
 
                mw.loader.implement(
                        'test.implement.e',
                        function () {
-                               assert.equal(
+                               assert.strictEqual(
                                        $element.css( 'float' ),
                                        'right',
                                        'Depending module\'s style is applied'
                mw.loader.implement(
                        'test.implement.e2',
                        function () {
-                               assert.equal(
+                               assert.strictEqual(
                                        $element2.css( 'float' ),
                                        'left',
                                        'Dependency\'s style is applied'
                ] );
 
                function verifyModuleStates() {
-                       assert.equal( mw.loader.getState( 'testMissing' ), 'missing', 'Module "testMissing" state' );
-                       assert.equal( mw.loader.getState( 'testUsesMissing' ), 'error', 'Module "testUsesMissing" state' );
-                       assert.equal( mw.loader.getState( 'testUsesNestedMissing' ), 'error', 'Module "testUsesNestedMissing" state' );
+                       assert.strictEqual( mw.loader.getState( 'testMissing' ), 'missing', 'Module "testMissing" state' );
+                       assert.strictEqual( mw.loader.getState( 'testUsesMissing' ), 'error', 'Module "testUsesMissing" state' );
+                       assert.strictEqual( mw.loader.getState( 'testUsesNestedMissing' ), 'error', 'Module "testUsesNestedMissing" state' );
                }
 
                mw.loader.using( [ 'testUsesNestedMissing' ],
 
                return mw.loader.using( [ 'testUsesSkippable' ] ).then(
                        function () {
-                               assert.equal( mw.loader.getState( 'testSkipped' ), 'ready', 'Skipped module' );
-                               assert.equal( mw.loader.getState( 'testNotSkipped' ), 'ready', 'Regular module' );
-                               assert.equal( mw.loader.getState( 'testUsesSkippable' ), 'ready', 'Regular module with skippable dependency' );
+                               assert.strictEqual( mw.loader.getState( 'testSkipped' ), 'ready', 'Skipped module' );
+                               assert.strictEqual( mw.loader.getState( 'testNotSkipped' ), 'ready', 'Regular module' );
+                               assert.strictEqual( mw.loader.getState( 'testUsesSkippable' ), 'ready', 'Regular module with skippable dependency' );
                        },
                        function ( e, badmodules ) {
                                // Should not fail and QUnit would already catch this,
                );
                // Ensure a protocol-relative URL for this test
                target = target.replace( /https?:/, '' );
-               assert.equal( target.slice( 0, 2 ), '//', 'URL is protocol-relative' );
+               assert.strictEqual( target.slice( 0, 2 ), '//', 'URL is protocol-relative' );
 
                mw.loader.testCallback = function () {
                        // Ensure once, delete now
 
                // URL to the callback script
                target = QUnit.fixurl( mw.config.get( 'wgScriptPath' ) + '/tests/qunit/data/mwLoaderTestCallback.js' );
-               assert.equal( target.slice( 0, 1 ), '/', 'URL is relative to document root' );
+               assert.strictEqual( target.slice( 0, 1 ), '/', 'URL is relative to document root' );
 
                mw.loader.testCallback = function () {
                        // Ensure once, delete now
                        try {
                                assert.strictEqual( cb.later(), 'Defined.', 'require works asynchrously in debug mode' );
                        } catch ( e ) {
-                               assert.equal( null, String( e ), 'require works asynchrously in debug mode' );
+                               assert.strictEqual( String( e ), null, 'require works asynchrously in debug mode' );
                        }
                } );
        } );
index cb583e7..ab1d55e 100644 (file)
@@ -1,7 +1,7 @@
 ( function ( mw ) {
 
        QUnit.module( 'mediawiki.template.mustache', {
-               setup: function () {
+               beforeEach: function () {
                        // Stub register some templates
                        this.sandbox.stub( mw.templates, 'get' ).returns( {
                                'test_greeting.mustache': '<div>{{foo}}{{>suffix}}</div>',
index a282325..31f4782 100644 (file)
@@ -1,7 +1,7 @@
 ( function ( mw ) {
 
        QUnit.module( 'mediawiki.template', {
-               setup: function () {
+               beforeEach: function () {
                        var abcCompiler = {
                                compile: function () {
                                        return 'abc default compiler';
index 75dc665..83e695f 100644 (file)
        } );
 
        QUnit.test( 'mw.format', function ( assert ) {
-               assert.equal(
+               assert.strictEqual(
                        mw.format( 'Format $1 $2', 'foo', 'bar' ),
                        'Format foo bar',
                        'Simple parameters'
                );
-               assert.equal(
+               assert.strictEqual(
                        mw.format( 'Format $1 $2' ),
                        'Format $1 $2',
                        'Missing parameters'
@@ -65,8 +65,8 @@
        } );
 
        QUnit.test( 'mw.now', function ( assert ) {
-               assert.equal( typeof mw.now(), 'number', 'Return a number' );
-               assert.equal(
+               assert.strictEqual( typeof mw.now(), 'number', 'Return a number' );
+               assert.strictEqual(
                        String( Math.round( mw.now() ) ).length,
                        String( +new Date() ).length,
                        'Match size of current timestamp'
@@ -86,7 +86,7 @@
                // Single get and set
 
                assert.strictEqual( conf.set( 'foo', 'Bar' ), true, 'Map.set returns boolean true if a value was set for a valid key string' );
-               assert.equal( conf.get( 'foo' ), 'Bar', 'Map.get returns a single value value correctly' );
+               assert.strictEqual( conf.get( 'foo' ), 'Bar', 'Map.get returns a single value value correctly' );
 
                assert.strictEqual( conf.get( 'example' ), null, 'Map.get returns null if selection was a string and the key was not found' );
                assert.strictEqual( conf.get( 'example', arry ), arry, 'Map.get returns fallback by reference if the key was not found' );
                assert.strictEqual( conf.set( 'undef' ), false, 'Map.set requires explicit value (no undefined default)' );
 
                assert.strictEqual( conf.set( 'undef', undefined ), true, 'Map.set allows setting value to `undefined`' );
-               assert.equal( conf.get( 'undef', 'fallback' ), undefined, 'Map.get supports retreiving value of `undefined`' );
+               assert.strictEqual( conf.get( 'undef', 'fallback' ), undefined, 'Map.get supports retreiving value of `undefined`' );
 
                assert.strictEqual( conf.set( funky, 'Funky' ), false, 'Map.set returns boolean false if key was invalid (Function)' );
                assert.strictEqual( conf.set( arry, 'Arry' ), false, 'Map.set returns boolean false if key was invalid (Array)' );
                // Interacting with globals
                conf.set( 'globalMapChecker', 'Hi' );
 
-               assert.ok( ( 'globalMapChecker' in window ) === false, 'Map does not its store values in the window object by default' );
+               assert.strictEqual( 'globalMapChecker' in window, false, 'Map does not its store values in the window object by default' );
 
                globalConf = new mw.Map( true );
                globalConf.set( 'anotherGlobalMapChecker', 'Hello' );
 
                assert.ok( 'anotherGlobalMapChecker' in window, 'global Map stores its values in the window object' );
 
-               assert.equal( globalConf.get( 'anotherGlobalMapChecker' ), 'Hello', 'get value from global Map via get()' );
+               assert.strictEqual( globalConf.get( 'anotherGlobalMapChecker' ), 'Hello', 'get value from global Map via get()' );
                this.suppressWarnings();
-               assert.equal( window.anotherGlobalMapChecker, 'Hello', 'get value from global Map via window object' );
+               assert.strictEqual( window.anotherGlobalMapChecker, 'Hello', 'get value from global Map via window object' );
                this.restoreWarnings();
 
                // Change value via global Map
                globalConf.set( 'anotherGlobalMapChecker', 'Again' );
-               assert.equal( globalConf.get( 'anotherGlobalMapChecker' ), 'Again', 'Change in global Map reflected via get()' );
+               assert.strictEqual( globalConf.get( 'anotherGlobalMapChecker' ), 'Again', 'Change in global Map reflected via get()' );
                this.suppressWarnings();
-               assert.equal( window.anotherGlobalMapChecker, 'Again', 'Change in global Map reflected window object' );
+               assert.strictEqual( window.anotherGlobalMapChecker, 'Again', 'Change in global Map reflected window object' );
                this.restoreWarnings();
 
                // Change value via window object
                this.suppressWarnings();
                window.anotherGlobalMapChecker = 'World';
-               assert.equal( window.anotherGlobalMapChecker, 'World', 'Change in window object works' );
+               assert.strictEqual( window.anotherGlobalMapChecker, 'World', 'Change in window object works' );
                this.restoreWarnings();
-               assert.equal( globalConf.get( 'anotherGlobalMapChecker' ), 'Again', 'Change in window object not reflected in global Map' );
+               assert.strictEqual( globalConf.get( 'anotherGlobalMapChecker' ), 'Again', 'Change in window object not reflected in global Map' );
 
                // Whitelist this global variable for QUnit's 'noglobal' mode
                if ( QUnit.config.noglobals ) {
 
                        for ( i = 0; i < len; i++ ) {
                                format = formats[ i ];
-                               assert.equal( mw.message.apply( null, messageArguments )[ format ](), expectedResult, assertMessage + ' when format is ' + format );
+                               assert.strictEqual( mw.message.apply( null, messageArguments )[ format ](), expectedResult, assertMessage + ' when format is ' + format );
                        }
                }
 
                hello = mw.message( 'hello' );
 
                // https://phabricator.wikimedia.org/T46459
-               assert.equal( hello.format, 'text', 'Message property "format" defaults to "text"' );
+               assert.strictEqual( hello.format, 'text', 'Message property "format" defaults to "text"' );
 
                assert.strictEqual( hello.map, mw.messages, 'Message property "map" defaults to the global instance in mw.messages' );
-               assert.equal( hello.key, 'hello', 'Message property "key" (currect key)' );
+               assert.strictEqual( hello.key, 'hello', 'Message property "key" (currect key)' );
                assert.deepEqual( hello.parameters, [], 'Message property "parameters" defaults to an empty array' );
 
                // TODO
                assert.ok( hello.params, 'Message prototype "params"' );
 
                hello.format = 'plain';
-               assert.equal( hello.toString(), 'Hello <b>awesome</b> world', 'Message.toString returns the message as a string with the current "format"' );
+               assert.strictEqual( hello.toString(), 'Hello <b>awesome</b> world', 'Message.toString returns the message as a string with the current "format"' );
 
-               assert.equal( hello.escaped(), 'Hello &lt;b&gt;awesome&lt;/b&gt; world', 'Message.escaped returns the escaped message' );
-               assert.equal( hello.format, 'escaped', 'Message.escaped correctly updated the "format" property' );
+               assert.strictEqual( hello.escaped(), 'Hello &lt;b&gt;awesome&lt;/b&gt; world', 'Message.escaped returns the escaped message' );
+               assert.strictEqual( hello.format, 'escaped', 'Message.escaped correctly updated the "format" property' );
 
                assert.ok( mw.messages.set( 'multiple-curly-brace', '"{{SITENAME}}" is the home of {{int:other-message}}' ), 'mw.messages.set: Register' );
                assertMultipleFormats( [ 'multiple-curly-brace' ], [ 'text', 'parse' ], '"' + siteName + '" is the home of Other Message', 'Curly brace format works correctly' );
-               assert.equal( mw.message( 'multiple-curly-brace' ).plain(), mw.messages.get( 'multiple-curly-brace' ), 'Plain format works correctly for curly brace message' );
-               assert.equal( mw.message( 'multiple-curly-brace' ).escaped(), mw.html.escape( '"' + siteName + '" is the home of Other Message' ), 'Escaped format works correctly for curly brace message' );
+               assert.strictEqual( mw.message( 'multiple-curly-brace' ).plain(), mw.messages.get( 'multiple-curly-brace' ), 'Plain format works correctly for curly brace message' );
+               assert.strictEqual( mw.message( 'multiple-curly-brace' ).escaped(), mw.html.escape( '"' + siteName + '" is the home of Other Message' ), 'Escaped format works correctly for curly brace message' );
 
                assert.ok( mw.messages.set( 'multiple-square-brackets-and-ampersand', 'Visit the [[Project:Community portal|community portal]] & [[Project:Help desk|help desk]]' ), 'mw.messages.set: Register' );
                assertMultipleFormats( [ 'multiple-square-brackets-and-ampersand' ], [ 'plain', 'text' ], mw.messages.get( 'multiple-square-brackets-and-ampersand' ), 'Square bracket message is not processed' );
-               assert.equal( mw.message( 'multiple-square-brackets-and-ampersand' ).escaped(), 'Visit the [[Project:Community portal|community portal]] &amp; [[Project:Help desk|help desk]]', 'Escaped format works correctly for square bracket message' );
+               assert.strictEqual( mw.message( 'multiple-square-brackets-and-ampersand' ).escaped(), 'Visit the [[Project:Community portal|community portal]] &amp; [[Project:Help desk|help desk]]', 'Escaped format works correctly for square bracket message' );
                assert.htmlEqual( mw.message( 'multiple-square-brackets-and-ampersand' ).parse(), 'Visit the ' +
                        '<a title="Project:Community portal" href="/wiki/Project:Community_portal">community portal</a>' +
                        ' &amp; <a title="Project:Help desk" href="/wiki/Project:Help_desk">help desk</a>', 'Internal links work with parse' );
                assert.htmlEqual( mw.message( 'mediawiki-test-version-entrypoints-index-php' ).parse(), '<a href="https://www.mediawiki.org/wiki/Manual:index.php">index.php</a>', 'External link works correctly in parse mode' );
 
                assertMultipleFormats( [ 'external-link-replace', 'http://example.org/?x=y&z' ], [ 'plain', 'text' ], 'Foo [http://example.org/?x=y&z bar]', 'Parameters are substituted but external link is not processed' );
-               assert.equal( mw.message( 'external-link-replace', 'http://example.org/?x=y&z' ).escaped(), 'Foo [http://example.org/?x=y&amp;z bar]', 'In escaped mode, parameters are substituted and ampersand is escaped, but external link is not processed' );
+               assert.strictEqual( mw.message( 'external-link-replace', 'http://example.org/?x=y&z' ).escaped(), 'Foo [http://example.org/?x=y&amp;z bar]', 'In escaped mode, parameters are substituted and ampersand is escaped, but external link is not processed' );
                assert.htmlEqual( mw.message( 'external-link-replace', 'http://example.org/?x=y&z' ).parse(), 'Foo <a href="http://example.org/?x=y&amp;z">bar</a>', 'External link with replacement works in parse mode without double-escaping' );
 
                hello.parse();
-               assert.equal( hello.format, 'parse', 'Message.parse correctly updated the "format" property' );
+               assert.strictEqual( hello.format, 'parse', 'Message.parse correctly updated the "format" property' );
 
                hello.plain();
-               assert.equal( hello.format, 'plain', 'Message.plain correctly updated the "format" property' );
+               assert.strictEqual( hello.format, 'plain', 'Message.plain correctly updated the "format" property' );
 
                hello.text();
-               assert.equal( hello.format, 'text', 'Message.text correctly updated the "format" property' );
+               assert.strictEqual( hello.format, 'text', 'Message.text correctly updated the "format" property' );
 
                assert.strictEqual( hello.exists(), true, 'Message.exists returns true for existing messages' );
 
 
                assert.ok( mw.messages.set( 'plural-test-msg', 'There {{PLURAL:$1|is|are}} $1 {{PLURAL:$1|result|results}}' ), 'mw.messages.set: Register' );
                assertMultipleFormats( [ 'plural-test-msg', 6 ], [ 'text', 'parse', 'escaped' ], 'There are 6 results', 'plural get resolved' );
-               assert.equal( mw.message( 'plural-test-msg', 6 ).plain(), 'There {{PLURAL:6|is|are}} 6 {{PLURAL:6|result|results}}', 'Parameter is substituted but plural is not resolved in plain' );
+               assert.strictEqual( mw.message( 'plural-test-msg', 6 ).plain(), 'There {{PLURAL:6|is|are}} 6 {{PLURAL:6|result|results}}', 'Parameter is substituted but plural is not resolved in plain' );
 
                assert.ok( mw.messages.set( 'plural-test-msg-explicit', 'There {{plural:$1|is one car|are $1 cars|0=are no cars|12=are a dozen cars}}' ), 'mw.messages.set: Register message with explicit plural forms' );
                assertMultipleFormats( [ 'plural-test-msg-explicit', 12 ], [ 'text', 'parse', 'escaped' ], 'There are a dozen cars', 'explicit plural get resolved' );
 
                assertMultipleFormats( [ 'mediawiki-test-pagetriage-del-talk-page-notify-summary', specialCharactersPageName ], [ 'plain', 'text' ], 'Notifying author of deletion nomination for [[' + specialCharactersPageName + ']]', 'Double square brackets with one parameter' );
 
-               assert.equal( mw.message( 'mediawiki-test-pagetriage-del-talk-page-notify-summary', specialCharactersPageName ).escaped(), 'Notifying author of deletion nomination for [[' + mw.html.escape( specialCharactersPageName ) + ']]', 'Double square brackets with one parameter, when escaped' );
+               assert.strictEqual( mw.message( 'mediawiki-test-pagetriage-del-talk-page-notify-summary', specialCharactersPageName ).escaped(), 'Notifying author of deletion nomination for [[' + mw.html.escape( specialCharactersPageName ) + ']]', 'Double square brackets with one parameter, when escaped' );
 
                assert.ok( mw.messages.set( 'mediawiki-test-categorytree-collapse-bullet', '[<b>−</b>]' ), 'mw.messages.set: Register' );
-               assert.equal( mw.message( 'mediawiki-test-categorytree-collapse-bullet' ).plain(), mw.messages.get( 'mediawiki-test-categorytree-collapse-bullet' ), 'Single square brackets unchanged in plain mode' );
+               assert.strictEqual( mw.message( 'mediawiki-test-categorytree-collapse-bullet' ).plain(), mw.messages.get( 'mediawiki-test-categorytree-collapse-bullet' ), 'Single square brackets unchanged in plain mode' );
 
                assert.ok( mw.messages.set( 'mediawiki-test-wikieditor-toolbar-help-content-signature-result', '<a href=\'#\' title=\'{{#special:mypage}}\'>Username</a> (<a href=\'#\' title=\'{{#special:mytalk}}\'>talk</a>)' ), 'mw.messages.set: Register' );
-               assert.equal( mw.message( 'mediawiki-test-wikieditor-toolbar-help-content-signature-result' ).plain(), mw.messages.get( 'mediawiki-test-wikieditor-toolbar-help-content-signature-result' ), 'HTML message with curly braces is not changed in plain mode' );
+               assert.strictEqual( mw.message( 'mediawiki-test-wikieditor-toolbar-help-content-signature-result' ).plain(), mw.messages.get( 'mediawiki-test-wikieditor-toolbar-help-content-signature-result' ), 'HTML message with curly braces is not changed in plain mode' );
 
                assertMultipleFormats( [ 'gender-plural-msg', 'male', 1 ], [ 'text', 'parse', 'escaped' ], 'he is awesome', 'Gender and plural are resolved' );
-               assert.equal( mw.message( 'gender-plural-msg', 'male', 1 ).plain(), '{{GENDER:male|he|she|they}} {{PLURAL:1|is|are}} awesome', 'Parameters are substituted, but gender and plural are not resolved in plain mode' );
+               assert.strictEqual( mw.message( 'gender-plural-msg', 'male', 1 ).plain(), '{{GENDER:male|he|she|they}} {{PLURAL:1|is|are}} awesome', 'Parameters are substituted, but gender and plural are not resolved in plain mode' );
 
-               assert.equal( mw.message( 'grammar-msg' ).plain(), mw.messages.get( 'grammar-msg' ), 'Grammar is not resolved in plain mode' );
+               assert.strictEqual( mw.message( 'grammar-msg' ).plain(), mw.messages.get( 'grammar-msg' ), 'Grammar is not resolved in plain mode' );
                assertMultipleFormats( [ 'grammar-msg' ], [ 'text', 'parse' ], 'Przeszukaj ' + siteName, 'Grammar is resolved' );
-               assert.equal( mw.message( 'grammar-msg' ).escaped(), 'Przeszukaj ' + siteName, 'Grammar is resolved in escaped mode' );
+               assert.strictEqual( mw.message( 'grammar-msg' ).escaped(), 'Przeszukaj ' + siteName, 'Grammar is resolved in escaped mode' );
 
                assertMultipleFormats( [ 'formatnum-msg', '987654321.654321' ], [ 'text', 'parse', 'escaped' ], '987,654,321.654', 'formatnum is resolved' );
-               assert.equal( mw.message( 'formatnum-msg' ).plain(), mw.messages.get( 'formatnum-msg' ), 'formatnum is not resolved in plain mode' );
+               assert.strictEqual( mw.message( 'formatnum-msg' ).plain(), mw.messages.get( 'formatnum-msg' ), 'formatnum is not resolved in plain mode' );
 
                assertMultipleFormats( [ 'int-msg' ], [ 'text', 'parse', 'escaped' ], 'Some Other Message', 'int is resolved' );
-               assert.equal( mw.message( 'int-msg' ).plain(), mw.messages.get( 'int-msg' ), 'int is not resolved in plain mode' );
+               assert.strictEqual( mw.message( 'int-msg' ).plain(), mw.messages.get( 'int-msg' ), 'int is not resolved in plain mode' );
 
                assert.ok( mw.messages.set( 'mediawiki-italics-msg', '<i>Very</i> important' ), 'mw.messages.set: Register' );
                assertMultipleFormats( [ 'mediawiki-italics-msg' ], [ 'plain', 'text', 'parse' ], mw.messages.get( 'mediawiki-italics-msg' ), 'Simple italics unchanged' );
 
        QUnit.test( 'mw.msg', function ( assert ) {
                assert.ok( mw.messages.set( 'hello', 'Hello <b>awesome</b> world' ), 'mw.messages.set: Register' );
-               assert.equal( mw.msg( 'hello' ), 'Hello <b>awesome</b> world', 'Gets message with default options (existing message)' );
-               assert.equal( mw.msg( 'goodbye' ), '⧼goodbye⧽', 'Gets message with default options (nonexistent message)' );
+               assert.strictEqual( mw.msg( 'hello' ), 'Hello <b>awesome</b> world', 'Gets message with default options (existing message)' );
+               assert.strictEqual( mw.msg( 'goodbye' ), '⧼goodbye⧽', 'Gets message with default options (nonexistent message)' );
 
                assert.ok( mw.messages.set( 'plural-item', 'Found $1 {{PLURAL:$1|item|items}}' ), 'mw.messages.set: Register' );
-               assert.equal( mw.msg( 'plural-item', 5 ), 'Found 5 items', 'Apply plural for count 5' );
-               assert.equal( mw.msg( 'plural-item', 0 ), 'Found 0 items', 'Apply plural for count 0' );
-               assert.equal( mw.msg( 'plural-item', 1 ), 'Found 1 item', 'Apply plural for count 1' );
+               assert.strictEqual( mw.msg( 'plural-item', 5 ), 'Found 5 items', 'Apply plural for count 5' );
+               assert.strictEqual( mw.msg( 'plural-item', 0 ), 'Found 0 items', 'Apply plural for count 0' );
+               assert.strictEqual( mw.msg( 'plural-item', 1 ), 'Found 1 item', 'Apply plural for count 1' );
 
-               assert.equal( mw.msg( 'mediawiki-test-pagetriage-del-talk-page-notify-summary', specialCharactersPageName ), 'Notifying author of deletion nomination for [[' + specialCharactersPageName + ']]', 'Double square brackets in mw.msg one parameter' );
+               assert.strictEqual( mw.msg( 'mediawiki-test-pagetriage-del-talk-page-notify-summary', specialCharactersPageName ), 'Notifying author of deletion nomination for [[' + specialCharactersPageName + ']]', 'Double square brackets in mw.msg one parameter' );
 
-               assert.equal( mw.msg( 'gender-plural-msg', 'male', 1 ), 'he is awesome', 'Gender test for male, plural count 1' );
-               assert.equal( mw.msg( 'gender-plural-msg', 'female', '1' ), 'she is awesome', 'Gender test for female, plural count 1' );
-               assert.equal( mw.msg( 'gender-plural-msg', 'unknown', 10 ), 'they are awesome', 'Gender test for neutral, plural count 10' );
+               assert.strictEqual( mw.msg( 'gender-plural-msg', 'male', 1 ), 'he is awesome', 'Gender test for male, plural count 1' );
+               assert.strictEqual( mw.msg( 'gender-plural-msg', 'female', '1' ), 'she is awesome', 'Gender test for female, plural count 1' );
+               assert.strictEqual( mw.msg( 'gender-plural-msg', 'unknown', 10 ), 'they are awesome', 'Gender test for neutral, plural count 10' );
 
-               assert.equal( mw.msg( 'grammar-msg' ), 'Przeszukaj ' + siteName, 'Grammar is resolved' );
+               assert.strictEqual( mw.msg( 'grammar-msg' ), 'Przeszukaj ' + siteName, 'Grammar is resolved' );
 
-               assert.equal( mw.msg( 'formatnum-msg', '987654321.654321' ), '987,654,321.654', 'formatnum is resolved' );
+               assert.strictEqual( mw.msg( 'formatnum-msg', '987654321.654321' ), '987,654,321.654', 'formatnum is resolved' );
 
-               assert.equal( mw.msg( 'int-msg' ), 'Some Other Message', 'int is resolved' );
+               assert.strictEqual( mw.msg( 'int-msg' ), 'Some Other Message', 'int is resolved' );
        } );
-
-       QUnit.test( 'mw.hook', function ( assert ) {
-               var hook, add, fire, chars, callback;
-
-               mw.hook( 'test.hook.unfired' ).add( function () {
-                       assert.ok( false, 'Unfired hook' );
-               } );
-
-               mw.hook( 'test.hook.basic' ).add( function () {
-                       assert.ok( true, 'Basic callback' );
-               } );
-               mw.hook( 'test.hook.basic' ).fire();
-
-               mw.hook( 'hasOwnProperty' ).add( function () {
-                       assert.ok( true, 'hook with name of predefined method' );
-               } );
-               mw.hook( 'hasOwnProperty' ).fire();
-
-               mw.hook( 'test.hook.data' ).add( function ( data1, data2 ) {
-                       assert.equal( data1, 'example', 'Fire with data (string param)' );
-                       assert.deepEqual( data2, [ 'two' ], 'Fire with data (array param)' );
-               } );
-               mw.hook( 'test.hook.data' ).fire( 'example', [ 'two' ] );
-
-               hook = mw.hook( 'test.hook.chainable' );
-               assert.strictEqual( hook.add(), hook, 'hook.add is chainable' );
-               assert.strictEqual( hook.remove(), hook, 'hook.remove is chainable' );
-               assert.strictEqual( hook.fire(), hook, 'hook.fire is chainable' );
-
-               hook = mw.hook( 'test.hook.detach' );
-               add = hook.add;
-               fire = hook.fire;
-               add( function ( x, y ) {
-                       assert.deepEqual( [ x, y ], [ 'x', 'y' ], 'Detached (contextless) with data' );
-               } );
-               fire( 'x', 'y' );
-
-               mw.hook( 'test.hook.fireBefore' ).fire().add( function () {
-                       assert.ok( true, 'Invoke handler right away if it was fired before' );
-               } );
-
-               mw.hook( 'test.hook.fireTwiceBefore' ).fire().fire().add( function () {
-                       assert.ok( true, 'Invoke handler right away if it was fired before (only last one)' );
-               } );
-
-               chars = [];
-
-               mw.hook( 'test.hook.many' )
-                       .add( function ( chr ) {
-                               chars.push( chr );
-                       } )
-                       .fire( 'x' ).fire( 'y' ).fire( 'z' )
-                       .add( function ( chr ) {
-                               assert.equal( chr, 'z', 'Adding callback later invokes right away with last data' );
-                       } );
-
-               assert.deepEqual( chars, [ 'x', 'y', 'z' ], 'Multiple callbacks with multiple fires' );
-
-               chars = [];
-               callback = function ( chr ) {
-                       chars.push( chr );
-               };
-
-               mw.hook( 'test.hook.variadic' )
-                       .add(
-                               callback,
-                               callback,
-                               function ( chr ) {
-                                       chars.push( chr );
-                               },
-                               callback
-                       )
-                       .fire( 'x' )
-                       .remove(
-                               function () {
-                                       'not-added';
-                               },
-                               callback
-                       )
-                       .fire( 'y' )
-                       .remove( callback )
-                       .fire( 'z' );
-
-               assert.deepEqual(
-                       chars,
-                       [ 'x', 'x', 'x', 'x', 'y', 'z' ],
-                       '"add" and "remove" support variadic arguments. ' +
-                               '"add" does not filter unique. ' +
-                               '"remove" removes all equal by reference. ' +
-                               '"remove" is silent if the function is not found'
-               );
-       } );
-
 }( mediaWiki ) );
index 814a207..8a5e68a 100644 (file)
                mw.config.set( 'wgUserName', 'John' );
                mw.config.set( 'wgUserId', 123 );
 
-               assert.equal( mw.user.getName(), 'John', 'getName()' );
+               assert.strictEqual( mw.user.getName(), 'John', 'getName()' );
                assert.strictEqual( mw.user.isAnon(), false, 'isAnon()' );
                assert.strictEqual( mw.user.getId(), 123, 'getId()' );
 
-               assert.equal( mw.user.id(), 'John', 'user.id()' );
+               assert.strictEqual( mw.user.id(), 'John', 'user.id()' );
        } );
 
        QUnit.test( 'getUserInfo', function ( assert ) {
@@ -68,9 +68,9 @@
                var result, result2;
 
                result = mw.user.generateRandomSessionId();
-               assert.equal( typeof result, 'string', 'type' );
-               assert.equal( $.trim( result ), result, 'no whitespace at beginning or end' );
-               assert.equal( result.length, 16, 'size' );
+               assert.strictEqual( typeof result, 'string', 'type' );
+               assert.strictEqual( $.trim( result ), result, 'no whitespace at beginning or end' );
+               assert.strictEqual( result.length, 16, 'size' );
 
                result2 = mw.user.generateRandomSessionId();
                assert.notEqual( result, result2, 'different when called multiple times' );
@@ -89,9 +89,9 @@
                }
 
                result = mw.user.generateRandomSessionId();
-               assert.equal( typeof result, 'string', 'type' );
-               assert.equal( $.trim( result ), result, 'no whitespace at beginning or end' );
-               assert.equal( result.length, 16, 'size' );
+               assert.strictEqual( typeof result, 'string', 'type' );
+               assert.strictEqual( $.trim( result ), result, 'no whitespace at beginning or end' );
+               assert.strictEqual( result.length, 16, 'size' );
 
                result2 = mw.user.generateRandomSessionId();
                assert.notEqual( result, result2, 'different when called multiple times' );
        QUnit.test( 'stickyRandomId', function ( assert ) {
                var result = mw.user.stickyRandomId(),
                        result2 = mw.user.stickyRandomId();
-               assert.equal( typeof result, 'string', 'type' );
+               assert.strictEqual( typeof result, 'string', 'type' );
                assert.strictEqual( /^[a-f0-9]{16}$/.test( result ), true, '16 HEX symbols string' );
-               assert.equal( result2, result, 'sticky' );
+               assert.strictEqual( result2, result, 'sticky' );
        } );
 
        QUnit.test( 'sessionId', function ( assert ) {
                var result = mw.user.sessionId(),
                        result2 = mw.user.sessionId();
-               assert.equal( typeof result, 'string', 'type' );
-               assert.equal( $.trim( result ), result, 'no leading or trailing whitespace' );
-               assert.equal( result2, result, 'retained' );
+               assert.strictEqual( typeof result, 'string', 'type' );
+               assert.strictEqual( $.trim( result ), result, 'no leading or trailing whitespace' );
+               assert.strictEqual( result2, result, 'retained' );
        } );
 }( mediaWiki, jQuery ) );
index f776d41..272b147 100644 (file)
@@ -89,7 +89,7 @@
        } ) );
 
        QUnit.test( 'rawurlencode', function ( assert ) {
-               assert.equal( util.rawurlencode( 'Test:A & B/Here' ), 'Test%3AA%20%26%20B%2FHere' );
+               assert.strictEqual( util.rawurlencode( 'Test:A & B/Here' ), 'Test%3AA%20%26%20B%2FHere' );
        } );
 
        QUnit.test( 'escapeIdForAttribute', function ( assert ) {
                ].forEach( function ( testCase ) {
                        mw.config.set( 'wgFragmentMode', testCase[ 0 ] );
 
-                       assert.equal( util.escapeIdForAttribute( testCase[ 1 ] ), testCase[ 2 ] );
+                       assert.strictEqual( util.escapeIdForAttribute( testCase[ 1 ] ), testCase[ 2 ] );
                } );
        } );
 
                ].forEach( function ( testCase ) {
                        mw.config.set( 'wgFragmentMode', testCase[ 0 ] );
 
-                       assert.equal( util.escapeIdForLink( testCase[ 1 ] ), testCase[ 2 ] );
+                       assert.strictEqual( util.escapeIdForLink( testCase[ 1 ] ), testCase[ 2 ] );
                } );
        } );
 
        QUnit.test( 'wikiUrlencode', function ( assert ) {
-               assert.equal( util.wikiUrlencode( 'Test:A & B/Here' ), 'Test:A_%26_B/Here' );
+               assert.strictEqual( util.wikiUrlencode( 'Test:A & B/Here' ), 'Test:A_%26_B/Here' );
                // See also wfUrlencodeTest.php#provideURLS
                $.each( {
                        '+': '%2B',
                        '<>': '%3C%3E',
                        '\'': '%27'
                }, function ( input, output ) {
-                       assert.equal( util.wikiUrlencode( input ), output );
+                       assert.strictEqual( util.wikiUrlencode( input ), output );
                } );
        } );
 
                } );
 
                href = util.getUrl( 'Sandbox' );
-               assert.equal( href, '/wiki/Sandbox', 'simple title' );
+               assert.strictEqual( href, '/wiki/Sandbox', 'simple title' );
 
                href = util.getUrl( 'Foo:Sandbox? 5+5=10! (test)/sub ' );
-               assert.equal( href, '/wiki/Foo:Sandbox%3F_5%2B5%3D10!_(test)/sub_', 'complex title' );
+               assert.strictEqual( href, '/wiki/Foo:Sandbox%3F_5%2B5%3D10!_(test)/sub_', 'complex title' );
 
                // T149767
                href = util.getUrl( 'My$$test$$$$$title' );
-               assert.equal( href, '/wiki/My$$test$$$$$title', 'title with multiple consecutive dollar signs' );
+               assert.strictEqual( href, '/wiki/My$$test$$$$$title', 'title with multiple consecutive dollar signs' );
 
                href = util.getUrl();
-               assert.equal( href, '/wiki/Foobar', 'default title' );
+               assert.strictEqual( href, '/wiki/Foobar', 'default title' );
 
                href = util.getUrl( null, { action: 'edit' } );
-               assert.equal( href, '/w/index.php?title=Foobar&action=edit', 'default title with query string' );
+               assert.strictEqual( href, '/w/index.php?title=Foobar&action=edit', 'default title with query string' );
 
                href = util.getUrl( 'Sandbox', { action: 'edit' } );
-               assert.equal( href, '/w/index.php?title=Sandbox&action=edit', 'simple title with query string' );
+               assert.strictEqual( href, '/w/index.php?title=Sandbox&action=edit', 'simple title with query string' );
 
                // Test fragments
                href = util.getUrl( 'Foo:Sandbox#Fragment', { action: 'edit' } );
-               assert.equal( href, '/w/index.php?title=Foo:Sandbox&action=edit#Fragment', 'namespaced title with query string and fragment' );
+               assert.strictEqual( href, '/w/index.php?title=Foo:Sandbox&action=edit#Fragment', 'namespaced title with query string and fragment' );
 
                href = util.getUrl( 'Sandbox#', { action: 'edit' } );
-               assert.equal( href, '/w/index.php?title=Sandbox&action=edit', 'title with query string and empty fragment' );
+               assert.strictEqual( href, '/w/index.php?title=Sandbox&action=edit', 'title with query string and empty fragment' );
 
                href = util.getUrl( 'Sandbox', {} );
-               assert.equal( href, '/wiki/Sandbox', 'title with empty query string' );
+               assert.strictEqual( href, '/wiki/Sandbox', 'title with empty query string' );
 
                href = util.getUrl( '#Fragment' );
-               assert.equal( href, '/wiki/#Fragment', 'empty title with fragment' );
+               assert.strictEqual( href, '/wiki/#Fragment', 'empty title with fragment' );
 
                href = util.getUrl( '#Fragment', { action: 'edit' } );
-               assert.equal( href, '/w/index.php?action=edit#Fragment', 'empty title with query string and fragment' );
+               assert.strictEqual( href, '/w/index.php?action=edit#Fragment', 'empty title with query string and fragment' );
 
                mw.config.set( 'wgFragmentMode', [ 'legacy' ] );
                href = util.getUrl( 'Foo:Sandbox \xC4#Fragment \xC4', { action: 'edit' } );
-               assert.equal( href, '/w/index.php?title=Foo:Sandbox_%C3%84&action=edit#Fragment_.C3.84', 'title with query string, fragment, and special characters' );
+               assert.strictEqual( href, '/w/index.php?title=Foo:Sandbox_%C3%84&action=edit#Fragment_.C3.84', 'title with query string, fragment, and special characters' );
 
                mw.config.set( 'wgFragmentMode', [ 'html5' ] );
                href = util.getUrl( 'Foo:Sandbox \xC4#Fragment \xC4', { action: 'edit' } );
-               assert.equal( href, '/w/index.php?title=Foo:Sandbox_%C3%84&action=edit#Fragment_Ä', 'title with query string, fragment, and special characters' );
+               assert.strictEqual( href, '/w/index.php?title=Foo:Sandbox_%C3%84&action=edit#Fragment_Ä', 'title with query string, fragment, and special characters' );
 
                href = util.getUrl( 'Foo:%23#Fragment', { action: 'edit' } );
-               assert.equal( href, '/w/index.php?title=Foo:%2523&action=edit#Fragment', 'title containing %23 (#), fragment, and a query string' );
+               assert.strictEqual( href, '/w/index.php?title=Foo:%2523&action=edit#Fragment', 'title containing %23 (#), fragment, and a query string' );
 
                mw.config.set( 'wgFragmentMode', [ 'legacy' ] );
                href = util.getUrl( '#+&=:;@$-_.!*/[]<>\'§', { action: 'edit' } );
-               assert.equal( href, '/w/index.php?action=edit#.2B.26.3D:.3B.40.24-_..21.2A.2F.5B.5D.3C.3E.27.C2.A7', 'fragment with various characters' );
+               assert.strictEqual( href, '/w/index.php?action=edit#.2B.26.3D:.3B.40.24-_..21.2A.2F.5B.5D.3C.3E.27.C2.A7', 'fragment with various characters' );
 
                mw.config.set( 'wgFragmentMode', [ 'html5' ] );
                href = util.getUrl( '#+&=:;@$-_.!*/[]<>\'§', { action: 'edit' } );
-               assert.equal( href, '/w/index.php?action=edit#+&=:;@$-_.!*/[]<>\'§', 'fragment with various characters' );
+               assert.strictEqual( href, '/w/index.php?action=edit#+&=:;@$-_.!*/[]<>\'§', 'fragment with various characters' );
        } );
 
        QUnit.test( 'wikiScript', function ( assert ) {
                        wgScriptPath: '/w'
                } );
 
-               assert.equal( util.wikiScript(), mw.config.get( 'wgScript' ),
+               assert.strictEqual( util.wikiScript(), mw.config.get( 'wgScript' ),
                        'wikiScript() returns wgScript'
                );
-               assert.equal( util.wikiScript( 'index' ), mw.config.get( 'wgScript' ),
+               assert.strictEqual( util.wikiScript( 'index' ), mw.config.get( 'wgScript' ),
                        'wikiScript( index ) returns wgScript'
                );
-               assert.equal( util.wikiScript( 'load' ), mw.config.get( 'wgLoadScript' ),
+               assert.strictEqual( util.wikiScript( 'load' ), mw.config.get( 'wgLoadScript' ),
                        'wikiScript( load ) returns wgLoadScript'
                );
-               assert.equal( util.wikiScript( 'api' ), '/w/api.php', 'API path' );
+               assert.strictEqual( util.wikiScript( 'api' ), '/w/api.php', 'API path' );
        } );
 
        QUnit.test( 'addCSS', function ( assert ) {
                $el = $( '<div>' ).attr( 'id', 'mw-addcsstest' ).appendTo( '#qunit-fixture' );
 
                style = util.addCSS( '#mw-addcsstest { visibility: hidden; }' );
-               assert.equal( typeof style, 'object', 'addCSS returned an object' );
+               assert.strictEqual( typeof style, 'object', 'addCSS returned an object' );
                assert.strictEqual( style.disabled, false, 'property "disabled" is available and set to false' );
 
-               assert.equal( $el.css( 'visibility' ), 'hidden', 'Added style properties are in effect' );
+               assert.strictEqual( $el.css( 'visibility' ), 'hidden', 'Added style properties are in effect' );
 
                // Clean up
                $( style.ownerNode ).remove();
                var url;
 
                url = 'http://example.org/?foo=wrong&foo=right#&foo=bad';
-               assert.equal( util.getParamValue( 'foo', url ), 'right', 'Use latest one, ignore hash' );
+               assert.strictEqual( util.getParamValue( 'foo', url ), 'right', 'Use latest one, ignore hash' );
                assert.strictEqual( util.getParamValue( 'bar', url ), null, 'Return null when not found' );
 
                url = 'http://example.org/#&foo=bad';
                        'Validate attributes of anchor tag in created element'
                );
 
-               assert.equal( $tbMW.closest( '.portlet' ).attr( 'id' ), 'p-test-tb', 'Link was inserted within correct portlet' );
+               assert.strictEqual( $tbMW.closest( '.portlet' ).attr( 'id' ), 'p-test-tb', 'Link was inserted within correct portlet' );
                assert.strictEqual( $tbMW.next()[ 0 ], tbRL, 'Link is in the correct position (nextnode as Node object)' );
 
                cuQuux = util.addPortletLink( 'p-test-custom', '#', 'Quux', null, 'Example [shift-x]', 'q' );
                $cuQuux = $( cuQuux );
 
-               assert.equal( $cuQuux.find( 'a' ).attr( 'title' ), 'Example [test-q]', 'Existing accesskey is stripped and updated' );
+               assert.strictEqual( $cuQuux.find( 'a' ).attr( 'title' ), 'Example [test-q]', 'Existing accesskey is stripped and updated' );
 
-               assert.equal(
+               assert.strictEqual(
                        $( '#p-test-custom #c-barmenu ul li' ).length,
                        1,
                        'addPortletLink did not add the item to all <ul> elements in the portlet (T37082)'
                tbRLDMnonexistentid = util.addPortletLink( 'p-test-tb', '//mediawiki.org/wiki/RL/DM',
                        'Default modules', 't-rldm-nonexistent', 'List of all default modules ', 'd', '#t-rl-nonexistent' );
 
-               assert.equal( tbRLDMnonexistentid, $( '#p-test-tb li:last' )[ 0 ], 'Fallback to adding at the end (nextnode non-matching CSS selector)' );
+               assert.strictEqual( tbRLDMnonexistentid, $( '#p-test-tb li:last' )[ 0 ], 'Fallback to adding at the end (nextnode non-matching CSS selector)' );
 
                // test case - empty jquery object as next node
                tbRLDMemptyjquery = util.addPortletLink( 'p-test-tb', '//mediawiki.org/wiki/RL/DM',
                        'Default modules', 't-rldm-empty-jquery', 'List of all default modules ', 'd', $( '#t-rl-nonexistent' ) );
 
-               assert.equal( tbRLDMemptyjquery, $( '#p-test-tb li:last' )[ 0 ], 'Fallback to adding at the end (nextnode as empty jQuery object)' );
+               assert.strictEqual( tbRLDMemptyjquery, $( '#p-test-tb li:last' )[ 0 ], 'Fallback to adding at the end (nextnode as empty jQuery object)' );
        } );
 
        QUnit.test( 'validateEmail', function ( assert ) {
diff --git a/tests/selenium/pageobjects/recentchanges.page.js b/tests/selenium/pageobjects/recentchanges.page.js
new file mode 100644 (file)
index 0000000..edecc91
--- /dev/null
@@ -0,0 +1,13 @@
+const Page = require( 'wdio-mediawiki/Page' );
+
+class RecentChangesPage extends Page {
+       get changesList() { return browser.element( '.mw-changeslist' ); }
+       get titles() { return this.changesList.$$( '.mw-changeslist-title' ); }
+
+       open() {
+               super.openTitle( 'Special:RecentChanges' );
+       }
+
+}
+
+module.exports = new RecentChangesPage();
diff --git a/tests/selenium/pageobjects/watchable.page.js b/tests/selenium/pageobjects/watchable.page.js
new file mode 100644 (file)
index 0000000..896b2f4
--- /dev/null
@@ -0,0 +1,13 @@
+const Page = require( 'wdio-mediawiki/Page' );
+
+class WatchablePage extends Page {
+
+       get confirmWatch() { return browser.element( '#mw-content-text button[type="submit"]' ); }
+
+       watch( title ) {
+               super.openTitle( title, { action: 'watch' } );
+               this.confirmWatch.click();
+       }
+}
+
+module.exports = new WatchablePage();
diff --git a/tests/selenium/pageobjects/watchlist.page.js b/tests/selenium/pageobjects/watchlist.page.js
new file mode 100644 (file)
index 0000000..58a003f
--- /dev/null
@@ -0,0 +1,15 @@
+const Page = require( 'wdio-mediawiki/Page' );
+
+class WatchlistPage extends Page {
+       get titles() {
+               return browser.element( '.mw-changeslist' )
+                       .$$( '.mw-changeslist-line .mw-title' );
+       }
+
+       open() {
+               super.openTitle( 'Special:Watchlist' );
+       }
+
+}
+
+module.exports = new WatchlistPage();
index 4a5c254..f6bb944 100755 (executable)
@@ -3,10 +3,13 @@ set -euo pipefail
 # Check the command before running in background so
 # that it can actually fail and have a descriptive error
 hash chromedriver
-chromedriver --url-base=/wd/hub --port=4444 &
+chromedriver --url-base=wd/hub --port=4444 &
+CHROME_DRIVER_PID=$!
+echo chromedriver running with PID $CHROME_DRIVER_PID
 # Make sure it is killed to prevent file descriptors leak
 function kill_chromedriver() {
-    killall chromedriver > /dev/null
+    # Use kill instead of killall to increase chances of this working on Windows
+    kill $CHROME_DRIVER_PID > /dev/null
 }
 trap kill_chromedriver EXIT
 npm run selenium-test
index a1fd480..032cbf0 100644 (file)
@@ -4,16 +4,13 @@ const assert = require( 'assert' ),
        RestorePage = require( '../pageobjects/restore.page' ),
        EditPage = require( '../pageobjects/edit.page' ),
        HistoryPage = require( '../pageobjects/history.page' ),
-       UserLoginPage = require( '../pageobjects/userlogin.page' );
+       UserLoginPage = require( '../pageobjects/userlogin.page' ),
+       Util = require( 'wdio-mediawiki/Util' );
 
 describe( 'Page', function () {
        var content,
                name;
 
-       function getTestString() {
-               return Math.random().toString() + '-öäü-♠♣♥♦';
-       }
-
        before( function () {
                // disable VisualEditor welcome dialog
                UserLoginPage.open();
@@ -22,8 +19,8 @@ describe( 'Page', function () {
 
        beforeEach( function () {
                browser.deleteCookie();
-               content = getTestString();
-               name = getTestString();
+               content = Util.getTestString( 'beforeEach-content-' );
+               name = Util.getTestString( 'BeforeEach-name-' );
        } );
 
        it( 'should be creatable', function () {
@@ -31,12 +28,12 @@ describe( 'Page', function () {
                EditPage.edit( name, content );
 
                // check
-               assert.equal( EditPage.heading.getText(), name );
-               assert.equal( EditPage.displayedContent.getText(), content );
+               assert.strictEqual( EditPage.heading.getText(), name );
+               assert.strictEqual( EditPage.displayedContent.getText(), content );
        } );
 
        it( 'should be re-creatable', function () {
-               let initialContent = getTestString();
+               let initialContent = Util.getTestString( 'initialContent-' );
 
                // create
                browser.call( function () {
@@ -52,8 +49,8 @@ describe( 'Page', function () {
                EditPage.edit( name, content );
 
                // check
-               assert.equal( EditPage.heading.getText(), name );
-               assert.equal( EditPage.displayedContent.getText(), content );
+               assert.strictEqual( EditPage.heading.getText(), name );
+               assert.strictEqual( EditPage.displayedContent.getText(), content );
        } );
 
        it( 'should be editable', function () {
@@ -63,11 +60,12 @@ describe( 'Page', function () {
                } );
 
                // edit
-               EditPage.edit( name, content );
+               let editContent = Util.getTestString( 'editContent-' );
+               EditPage.edit( name, editContent );
 
                // check
-               assert.equal( EditPage.heading.getText(), name );
-               assert.equal( EditPage.displayedContent.getText(), content );
+               assert.strictEqual( EditPage.heading.getText(), name );
+               assert.strictEqual( EditPage.displayedContent.getText(), editContent );
        } );
 
        it( 'should have history', function () {
@@ -78,7 +76,7 @@ describe( 'Page', function () {
 
                // check
                HistoryPage.open( name );
-               assert.equal( HistoryPage.comment.getText(), `(Created page with "${content}")` );
+               assert.strictEqual( HistoryPage.comment.getText(), `(Created page with "${content}")` );
        } );
 
        it( 'should be deletable', function () {
@@ -94,7 +92,7 @@ describe( 'Page', function () {
                DeletePage.delete( name, content + '-deletereason' );
 
                // check
-               assert.equal(
+               assert.strictEqual(
                        DeletePage.displayedContent.getText(),
                        '"' + name + '" has been deleted. See deletion log for a record of recent deletions.\nReturn to Main Page.'
                );
@@ -118,6 +116,6 @@ describe( 'Page', function () {
                RestorePage.restore( name, content + '-restorereason' );
 
                // check
-               assert.equal( RestorePage.displayedContent.getText(), name + ' has been restored\nConsult the deletion log for a record of recent deletions and restorations.' );
+               assert.strictEqual( RestorePage.displayedContent.getText(), name + ' has been restored\nConsult the deletion log for a record of recent deletions and restorations.' );
        } );
 } );
diff --git a/tests/selenium/specs/specialrecentchanges.js b/tests/selenium/specs/specialrecentchanges.js
new file mode 100644 (file)
index 0000000..4328d3f
--- /dev/null
@@ -0,0 +1,25 @@
+const assert = require( 'assert' ),
+       EditPage = require( '../pageobjects/edit.page' ),
+       RecentChangesPage = require( '../pageobjects/recentchanges.page' ),
+       Util = require( 'wdio-mediawiki/Util' );
+
+describe( 'Special:RecentChanges', function () {
+       let content,
+               name;
+
+       beforeEach( function () {
+               browser.deleteCookie();
+               content = Util.getTestString();
+               name = Util.getTestString();
+       } );
+
+       // Skip due to failures on many repos (T199644)
+       it.skip( 'shows page creation', function () {
+               EditPage.edit( name, content );
+
+               RecentChangesPage.open();
+
+               assert.strictEqual( RecentChangesPage.titles[ 0 ].getText(), name );
+       } );
+
+} );
diff --git a/tests/selenium/specs/specialwatchlist.js b/tests/selenium/specs/specialwatchlist.js
new file mode 100644 (file)
index 0000000..de36b90
--- /dev/null
@@ -0,0 +1,41 @@
+const assert = require( 'assert' ),
+       Api = require( 'wdio-mediawiki/Api' ),
+       WatchlistPage = require( '../pageobjects/watchlist.page' ),
+       WatchablePage = require( '../pageobjects/watchable.page' ),
+       LoginPage = require( 'wdio-mediawiki/LoginPage' ),
+       Util = require( 'wdio-mediawiki/Util' );
+
+describe( 'Special:Watchlist', function () {
+       let username, password;
+
+       before( function () {
+               username = Util.getTestString( 'user-' );
+               password = Util.getTestString( 'password-' );
+
+               browser.call( function () {
+                       return Api.createAccount( username, password );
+               } );
+       } );
+
+       beforeEach( function () {
+               browser.deleteCookie();
+               LoginPage.login( username, password );
+       } );
+
+       it( 'should show page with new edit', function () {
+               const title = Util.getTestString( 'Title-' );
+
+               browser.call( function () {
+                       return Api.edit( title, Util.getTestString() ); // create
+               } );
+               WatchablePage.watch( title );
+               browser.call( function () {
+                       return Api.edit( title, Util.getTestString() ); // edit
+               } );
+
+               WatchlistPage.open();
+
+               assert.strictEqual( WatchlistPage.titles[ 0 ].getText(), title );
+       } );
+
+} );
index 10bf05d..4884ded 100644 (file)
@@ -2,7 +2,8 @@ const assert = require( 'assert' ),
        CreateAccountPage = require( '../pageobjects/createaccount.page' ),
        PreferencesPage = require( '../pageobjects/preferences.page' ),
        UserLoginPage = require( 'wdio-mediawiki/LoginPage' ),
-       Api = require( 'wdio-mediawiki/Api' );
+       Api = require( 'wdio-mediawiki/Api' ),
+       Util = require( 'wdio-mediawiki/Util' );
 
 describe( 'User', function () {
        var password,
@@ -16,8 +17,8 @@ describe( 'User', function () {
 
        beforeEach( function () {
                browser.deleteCookie();
-               username = `User-${Math.random().toString()}`;
-               password = Math.random().toString();
+               username = Util.getTestString( 'User-' );
+               password = Util.getTestString();
        } );
 
        it( 'should be able to create account', function () {
@@ -25,7 +26,7 @@ describe( 'User', function () {
                CreateAccountPage.createAccount( username, password );
 
                // check
-               assert.equal( CreateAccountPage.heading.getText(), `Welcome, ${username}!` );
+               assert.strictEqual( CreateAccountPage.heading.getText(), `Welcome, ${username}!` );
        } );
 
        it( 'should be able to log in', function () {
@@ -38,11 +39,12 @@ describe( 'User', function () {
                UserLoginPage.login( username, password );
 
                // check
-               assert.equal( UserLoginPage.userPage.getText(), username );
+               assert.strictEqual( UserLoginPage.userPage.getText(), username );
        } );
 
-       it( 'should be able to change preferences', function () {
-               var realName = Math.random().toString();
+       // Disabled due to flakiness (T199446)
+       it.skip( 'should be able to change preferences', function () {
+               var realName = Util.getTestString();
 
                // create
                browser.call( function () {
@@ -56,6 +58,6 @@ describe( 'User', function () {
                PreferencesPage.changeRealName( realName );
 
                // check
-               assert.equal( PreferencesPage.realName.getValue(), realName );
+               assert.strictEqual( PreferencesPage.realName.getValue(), realName );
        } );
 } );
index bfce387..50e940f 100644 (file)
@@ -1,6 +1,10 @@
 # Notable changes
 
-## [Unreleased]
+## v0.2.0
+
+* Util: Added getTestString().
+
+## v0.1.0
 
 * Api: Added initial version.
 * Page: Added initial version.
diff --git a/tests/selenium/wdio-mediawiki/Util.js b/tests/selenium/wdio-mediawiki/Util.js
new file mode 100644 (file)
index 0000000..247c958
--- /dev/null
@@ -0,0 +1,5 @@
+module.exports = {
+       getTestString( prefix = '' ) {
+               return prefix + Math.random().toString() + '-Iñtërnâtiônàlizætiøn';
+       }
+};
index be7ed33..56ea045 100644 (file)
@@ -1,6 +1,6 @@
 {
   "name": "wdio-mediawiki",
-  "version": "0.1.0",
+  "version": "0.2.0",
   "description": "WebdriverIO plugin for testing a MediaWiki site.",
   "homepage": "https://gerrit.wikimedia.org/g/mediawiki/core/+/master/tests/selenium/wdio-mediawiki/",
   "license": "MIT",
index f84ae90..8cb46d4 100644 (file)
@@ -6,6 +6,6 @@ describe( 'BlankPage', function () {
                BlankPage.open();
 
                // check
-               assert.equal( BlankPage.heading.getText(), 'Blank page' );
+               assert.strictEqual( BlankPage.heading.getText(), 'Blank page' );
        } );
 } );
index f785d36..8b47dff 100644 (file)
@@ -46,6 +46,7 @@ exports.config = {
                relPath( './tests/selenium/specs/**/*.js' ),
                relPath( './extensions/*/tests/selenium/specs/**/*.js' ),
                relPath( './extensions/VisualEditor/modules/ve-mw/tests/selenium/specs/**/*.js' ),
+               relPath( './extensions/Wikibase/repo/tests/selenium/specs/**/*.js' ),
                relPath( './skins/*/tests/selenium/specs/**/*.js' )
        ],
        // Patterns to exclude
index a3c9d84..cc74c89 100644 (file)
--- a/thumb.php
+++ b/thumb.php
@@ -94,7 +94,7 @@ function wfStreamThumb( array $params ) {
 
        $headers = []; // HTTP headers to send
 
-       $fileName = isset( $params['f'] ) ? $params['f'] : '';
+       $fileName = $params['f'] ?? '';
 
        // Backwards compatibility parameters
        if ( isset( $params['w'] ) ) {
@@ -244,7 +244,7 @@ function wfStreamThumb( array $params ) {
                }
        }
 
-       $rel404 = isset( $params['rel404'] ) ? $params['rel404'] : null;
+       $rel404 = $params['rel404'] ?? null;
        unset( $params['r'] ); // ignore 'r' because we unconditionally pass File::RENDER
        unset( $params['f'] ); // We're done with 'f' parameter.
        unset( $params['rel404'] ); // moved to $rel404
@@ -626,7 +626,7 @@ function wfThumbErrorText( $status, $msgText ) {
  *
  * @param int $status
  * @param string $msgHtml HTML
- * @param string $msgText Short error description, for internal logging. Defaults to $msgHtml.
+ * @param string|null $msgText Short error description, for internal logging. Defaults to $msgHtml.
  *   Only used for HTTP 500 errors.
  * @param array $context Error context, for internal logging. Only used for HTTP 500 errors.
  * @return void
@@ -648,7 +648,7 @@ function wfThumbError( $status, $msgHtml, $msgText = null, $context = [] ) {
        if ( $wgShowHostnames ) {
                header( 'X-MW-Thumbnail-Renderer: ' . wfHostname() );
                $url = htmlspecialchars(
-                       isset( $_SERVER['REQUEST_URI'] ) ? $_SERVER['REQUEST_URI'] : '',
+                       $_SERVER['REQUEST_URI'] ?? '',
                        ENT_NOQUOTES
                );
                $hostname = htmlspecialchars( wfHostname(), ENT_NOQUOTES );